This project is archived and is in readonly mode.
SQLiteAdapter::select_rows misses columns when column names are ambiguous
Reported by Richard Bunch | May 4th, 2010 @ 01:06 AM
When select_rows is used on a SQLite database and the selected columns include some with the same name in different tables, the last of the columns selected (not necessarily the ambiguous ones) will not appear in the result rows. The bug can be worked around by giving unambiguous aliases to the columns selected. I was using ruby 1.8.7 and rails 2.3.5.
An example follows.
config/schema.rb
ActiveRecord::Schema.define(:version => 20100503193703) do
create_table "dogs", :force => true do |t|
t.string "name"
t.string "color"
t.integer "owner_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "people", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
end
app/models/dog.rb
class Dog < ActiveRecord::Base
belongs_to :person
end
app/models/person.rb
class Person < ActiveRecord::Base
has_many :dog
end
db/seeds.rb
bob = Person.create(:name => 'Bob')
Dog.create(:name => 'Fido', :owner_id => bob.id, :color => 'brown')
app/controllers/home_controller.rb
require 'pp'
class HomeController < ApplicationController
def index
@dog_show = ActiveRecord::Base::connection.select_rows 'SELECT people.name, dogs.name, dogs.color FROM people INNER JOIN dogs ON dogs.owner_id = people.id'
pp @dog_show #=> [["Bob", "Fido"]]
@dog_show = ActiveRecord::Base::connection.select_rows 'SELECT people.name, dogs.name as dogname, dogs.color FROM people INNER JOIN dogs ON dogs.owner_id = people.id'
pp @dog_show #=> [["Bob", "Fido", "brown"]]
end
end
The bug appears to be due to the implementation of select_rows in activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
def select_rows(sql, name = nil)
execute(sql, name).map do |row|
(0...(row.size / 2)).map { |i| row[i] }
end
end
With the ambiguous column names in the example, the value
returned by execute is:
[{"name"=>"Fido", 0=>"Bob", 1=>"Fido", 2=>"brown", "color"=>"brown"}]
Due to the ambiguity, there is no "name"=>"Bob" pair, so the number of columns is not row.size/2 as is assumed.
The following monkey patch seemed to fix the problem, but I have
not tested it properly and it seems that the code could be more
"rubyish".
module ActiveRecord
module ConnectionAdapters
class SQLiteAdapter
def select_rows(sql, name = nil)
rows = execute(sql, name)
pp rows
rows.map do |row|
(0...(row.size / 2)).map { |i| row[i] }
end
end
end
end
end
I have not tested the bug with other databases, but their code for select_rows looks totally different.
Comments and changes to this ticket
-
Neeraj Singh May 4th, 2010 @ 03:50 PM
- Tag set to rails3, sqlite
I have confirmed that it is indeed an issue with SQLite database. It works fine with MySQL.
Will be looking into the difference between how MySQL handles it and how SQLite handles the query.
I did my check on rails3 edge.
-
Santiago Pastorino February 2nd, 2011 @ 04:43 PM
- State changed from new to open
This issue has been automatically marked as stale because it has not been commented on for at least three months.
The resources of the Rails core team are limited, and so we are asking for your help. If you can still reproduce this error on the 3-0-stable branch or on master, please reply with all of the information you have about it and add "[state:open]" to your comment. This will reopen the ticket for review. Likewise, if you feel that this is a very important feature for Rails to include, please reply with your explanation so we can consider it.
Thank you for all your contributions, and we hope you will understand this step to focus our efforts where they are most helpful.
-
Santiago Pastorino February 2nd, 2011 @ 04:43 PM
- State changed from open to stale
-
Richard Bunch February 6th, 2011 @ 09:34 PM
- State changed from stale to open
- Tag changed from rails3, sqlite to bug sqlite
I have tested and this bug is still present with rails 3.0.3, ruby-1.9.2-p136, sqlite 3.7.5, Windows XP. Looking at the latest code on the git browser, it looks like the bug is still in there.
I notice my "monkey patch" is nothing but a copy of the original code with debug printing. I clearly copied the wrong code. It should be:
module ActiveRecord module ConnectionAdapters
class SQLiteAdapter def select_rows(sql, name = nil) execute(sql, name).map do |row| new_row = [] for i in (0...row.size) if row[i] then new_row << row[i] else break end end new_row end end end
end endI think making this change in the original sqlite_adapter.rb should solve the problem. I will try to make a patch, if I have time.
[state:open]
-
Richard Bunch February 6th, 2011 @ 09:35 PM
- Tag changed from bug sqlite to rails3 sqlite bug
-
Richard Bunch February 6th, 2011 @ 09:38 PM
- Tag changed from rails3 sqlite bug to rails3, rails3.0.3, sqlite_adapter
Sorry, my script blocker messed up the tags.
-
rails May 7th, 2011 @ 01:00 AM
- Tag changed from rails3, rails3.0.3, sqlite_adapter to rails3, rails303, sqlite_adapter
This issue has been automatically marked as stale because it has not been commented on for at least three months.
The resources of the Rails core team are limited, and so we are asking for your help. If you can still reproduce this error on the 3-0-stable branch or on master, please reply with all of the information you have about it and add "[state:open]" to your comment. This will reopen the ticket for review. Likewise, if you feel that this is a very important feature for Rails to include, please reply with your explanation so we can consider it.
Thank you for all your contributions, and we hope you will understand this step to focus our efforts where they are most helpful.
-
rails May 7th, 2011 @ 01:00 AM
- State changed from open to stale
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>