mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
reorder bind parameters when merging relations
This commit is contained in:
parent
d345ed40b5
commit
9675c7da28
3 changed files with 43 additions and 3 deletions
|
@ -97,13 +97,29 @@ module ActiveRecord
|
||||||
def merge_multi_values
|
def merge_multi_values
|
||||||
lhs_wheres = relation.where_values
|
lhs_wheres = relation.where_values
|
||||||
rhs_wheres = values[:where] || []
|
rhs_wheres = values[:where] || []
|
||||||
|
|
||||||
lhs_binds = relation.bind_values
|
lhs_binds = relation.bind_values
|
||||||
rhs_binds = values[:bind] || []
|
rhs_binds = values[:bind] || []
|
||||||
|
|
||||||
removed, kept = partition_overwrites(lhs_wheres, rhs_wheres)
|
removed, kept = partition_overwrites(lhs_wheres, rhs_wheres)
|
||||||
|
|
||||||
relation.where_values = kept + rhs_wheres
|
where_values = kept + rhs_wheres
|
||||||
relation.bind_values = filter_binds(lhs_binds, removed) + rhs_binds
|
bind_values = filter_binds(lhs_binds, removed) + rhs_binds
|
||||||
|
|
||||||
|
conn = relation.klass.connection
|
||||||
|
bviter = bind_values.each.with_index
|
||||||
|
where_values.map! do |node|
|
||||||
|
if Arel::Nodes::Equality === node && Arel::Nodes::BindParam === node.right
|
||||||
|
(column, _), i = bviter.next
|
||||||
|
substitute = conn.substitute_at column, i
|
||||||
|
Arel::Nodes::Equality.new(node.left, substitute)
|
||||||
|
else
|
||||||
|
node
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
relation.where_values = where_values
|
||||||
|
relation.bind_values = bind_values
|
||||||
|
|
||||||
if values[:reordering]
|
if values[:reordering]
|
||||||
# override any order specified in the original relation
|
# override any order specified in the original relation
|
||||||
|
|
|
@ -9,6 +9,9 @@ module ActiveRecord
|
||||||
fixtures :posts, :comments, :authors
|
fixtures :posts, :comments, :authors
|
||||||
|
|
||||||
class FakeKlass < Struct.new(:table_name, :name)
|
class FakeKlass < Struct.new(:table_name, :name)
|
||||||
|
def self.connection
|
||||||
|
Post.connection
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_construction
|
def test_construction
|
||||||
|
@ -204,6 +207,10 @@ module ActiveRecord
|
||||||
def arel_table
|
def arel_table
|
||||||
Post.arel_table
|
Post.arel_table
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def connection
|
||||||
|
Post.connection
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def relation
|
def relation
|
||||||
|
@ -295,7 +302,7 @@ module ActiveRecord
|
||||||
assert_equal({foo: 'bar'}, relation.create_with_value)
|
assert_equal({foo: 'bar'}, relation.create_with_value)
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'merge!' do
|
def test_merge!
|
||||||
assert relation.merge!(where: :foo).equal?(relation)
|
assert relation.merge!(where: :foo).equal?(relation)
|
||||||
assert_equal [:foo], relation.where_values
|
assert_equal [:foo], relation.where_values
|
||||||
end
|
end
|
||||||
|
|
|
@ -1556,4 +1556,21 @@ class RelationTest < ActiveRecord::TestCase
|
||||||
merged = left.merge(right)
|
merged = left.merge(right)
|
||||||
assert_equal binds, merged.bind_values
|
assert_equal binds, merged.bind_values
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_merging_reorders_bind_params
|
||||||
|
post = Post.first
|
||||||
|
id_column = Post.columns_hash['id']
|
||||||
|
title_column = Post.columns_hash['title']
|
||||||
|
|
||||||
|
bv = Post.connection.substitute_at id_column, 0
|
||||||
|
|
||||||
|
right = Post.where(id: bv)
|
||||||
|
right.bind_values += [[id_column, post.id]]
|
||||||
|
|
||||||
|
left = Post.where(title: bv)
|
||||||
|
left.bind_values += [[title_column, post.title]]
|
||||||
|
|
||||||
|
merged = left.merge(right)
|
||||||
|
assert_equal post, merged.first
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue