1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Merge pull request #35441 from kamipo/allow_from_with_index_hint

Relax table name detection in `from` to allow any extension like INDEX hint
This commit is contained in:
Ryuta Kamizono 2019-03-01 23:25:01 +09:00 committed by GitHub
commit 6568d7da63
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 12 deletions

View file

@ -1091,14 +1091,17 @@ module ActiveRecord
field = klass.attribute_alias(field) if klass.attribute_alias?(field)
from = from_clause.name || from_clause.value
if klass.columns_hash.key?(field) &&
(!from || from == table.name || from == connection.quote_table_name(table.name))
if klass.columns_hash.key?(field) && (!from || table_name_matches?(from))
arel_attribute(field)
else
yield
end
end
def table_name_matches?(from)
/(?:\A|(?<!FROM)\s)(?:\b#{table.name}\b|#{connection.quote_table_name(table.name)})(?!\.)/i.match?(from.to_s)
end
def reverse_sql_order(order_query)
if order_query.empty?
return [arel_attribute(primary_key).desc] if primary_key

View file

@ -182,27 +182,27 @@ class RelationTest < ActiveRecord::TestCase
end
end
def test_select_with_original_table_name_in_from
def test_select_with_from_includes_original_table_name
relation = Comment.joins(:post).select(:id).order(:id)
subquery = Comment.from(Comment.table_name).joins(:post).select(:id).order(:id)
subquery = Comment.from("#{Comment.table_name} /*! USE INDEX (PRIMARY) */").joins(:post).select(:id).order(:id)
assert_equal relation.map(&:id), subquery.map(&:id)
end
def test_pluck_with_original_table_name_in_from
def test_pluck_with_from_includes_original_table_name
relation = Comment.joins(:post).order(:id)
subquery = Comment.from(Comment.table_name).joins(:post).order(:id)
subquery = Comment.from("#{Comment.table_name} /*! USE INDEX (PRIMARY) */").joins(:post).order(:id)
assert_equal relation.pluck(:id), subquery.pluck(:id)
end
def test_select_with_quoted_original_table_name_in_from
def test_select_with_from_includes_quoted_original_table_name
relation = Comment.joins(:post).select(:id).order(:id)
subquery = Comment.from(Comment.quoted_table_name).joins(:post).select(:id).order(:id)
subquery = Comment.from("#{Comment.quoted_table_name} /*! USE INDEX (PRIMARY) */").joins(:post).select(:id).order(:id)
assert_equal relation.map(&:id), subquery.map(&:id)
end
def test_pluck_with_quoted_original_table_name_in_from
def test_pluck_with_from_includes_quoted_original_table_name
relation = Comment.joins(:post).order(:id)
subquery = Comment.from(Comment.quoted_table_name).joins(:post).order(:id)
subquery = Comment.from("#{Comment.quoted_table_name} /*! USE INDEX (PRIMARY) */").joins(:post).order(:id)
assert_equal relation.pluck(:id), subquery.pluck(:id)
end
@ -221,13 +221,25 @@ class RelationTest < ActiveRecord::TestCase
def test_select_with_subquery_in_from_does_not_use_original_table_name
relation = Comment.group(:type).select("COUNT(post_id) AS post_count, type")
subquery = Comment.from(relation).select("type", "post_count")
subquery = Comment.from(relation, "grouped_#{Comment.table_name}").select("type", "post_count")
assert_equal(relation.map(&:post_count).sort, subquery.map(&:post_count).sort)
end
def test_group_with_subquery_in_from_does_not_use_original_table_name
relation = Comment.group(:type).select("COUNT(post_id) AS post_count,type")
subquery = Comment.from(relation).group("type").average("post_count")
subquery = Comment.from(relation, "grouped_#{Comment.table_name}").group("type").average("post_count")
assert_equal(relation.map(&:post_count).sort, subquery.values.sort)
end
def test_select_with_subquery_string_in_from_does_not_use_original_table_name
relation = Comment.group(:type).select("COUNT(post_id) AS post_count, type")
subquery = Comment.from("(#{relation.to_sql}) #{Comment.table_name}_grouped").select("type", "post_count")
assert_equal(relation.map(&:post_count).sort, subquery.map(&:post_count).sort)
end
def test_group_with_subquery_string_in_from_does_not_use_original_table_name
relation = Comment.group(:type).select("COUNT(post_id) AS post_count,type")
subquery = Comment.from("(#{relation.to_sql}) #{Comment.table_name}_grouped").group("type").average("post_count")
assert_equal(relation.map(&:post_count).sort, subquery.values.sort)
end