You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The release of Rails 4.2.1 breaks subqueries with columns that match reserved keywords.
Script to reproduce
unlessFile.exist?('Gemfile')File.write('Gemfile',<<-GEMFILE) source 'https://rubygems.org' gem 'rails', '4.2.1' # works with '4.2.0' gem 'mysql2' GEMFILEsystem'bundle'endrequire'bundler'Bundler.setup(:default)require'active_record'require'minitest/autorun'require'logger'# This connection will do for database-independent bug reports.ActiveRecord::Base.establish_connection(adapter: 'mysql2',host: 'localhost',username: 'user',password: 'password',database: 'test')ActiveRecord::Base.logger=Logger.new(STDOUT)ActiveRecord::Schema.definedocreate_table:test,force: truedo |t|
t.integer:descendendclassTest < ActiveRecord::Baseself.table_name=:testdefault_scope{select(:desc)}endclassBugTest < Minitest::Testdeftest_from_escaping_attributesTest.create!(desc: 10)Test.create!(desc: 11)result=Test.from(Test.where(desc: 10),Test.table_name)assert_equal1,result.to_a.sizeendend
Rails 4.2.0
In rails 4.2.0 this will generate a query that looks like this
SELECT`test`.`desc`FROM (SELECT`test`.`desc`FROM`test`WHERE`test`.`desc`=10) test
Notice that the value in the select are properly escaped with backticks and fully qualified with the name of the subquery
Rails 4.2.1
In rails 4.2.1 it will generate a query that looks like this
SELECTdescFROM (SELECT`test`.`desc`FROM`test`WHERE`test`.`desc`=10) test
Notice how both the escaping and the qualifying of the attribute with the name of the subquery is not present. Because the desc column is not escaped this will cause a SQL error
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'desc FROM (SELECT `test`.`desc` FROM `test` WHERE `test`.`desc` = 10) test' at line 1: SELECT desc FROM (SELECT `test`.`desc` FROM `test` WHERE `test`.`desc` = 10) test
Suggested fix
Revert this behaviour back to escaping and fully qualifying the attributes when selecting from a subquery
The text was updated successfully, but these errors were encountered:
That seems like it's probably it. Maybe just making sure the value is quoted, but skipping the full qualification of the column would be a good middle road. AFAIK that should allow both this behaviour and the behaviour discussed in #18743 to continue working
Our general contract in Active Record is that strings are assumed to be
SQL literals, and symbols are assumed to reference a column. If a from
clause is given, we shouldn't include the table name, but we should
still quote the value as if it were a column.
Upon fixing this, the tests were still failing on SQLite. This was
because the column name being returned by the query was `"\"join\""`
instead of `"join"`. This is actually a bug in SQLite that was fixed a
long time ago, but I was using the version of SQLite included by OS X
which has this bug. Since I'm guessing this will be a common case for
contributors, I also added an explicit check with a more helpful error
message.
Fixes#20360
The release of Rails 4.2.1 breaks subqueries with columns that match reserved keywords.
Script to reproduce
Rails 4.2.0
In rails 4.2.0 this will generate a query that looks like this
Notice that the value in the select are properly escaped with backticks and fully qualified with the name of the subquery
Rails 4.2.1
In rails 4.2.1 it will generate a query that looks like this
Notice how both the escaping and the qualifying of the attribute with the name of the subquery is not present. Because the
desc
column is not escaped this will cause a SQL errorSuggested fix
Revert this behaviour back to escaping and fully qualifying the attributes when selecting from a subquery
The text was updated successfully, but these errors were encountered: