Skip to content

Commit

Permalink
Merge pull request #51497 from bensheldon/preparable-in
Browse files Browse the repository at this point in the history
Allow `IN` with subselect to be preparable
  • Loading branch information
matthewd committed Apr 5, 2024
2 parents 83a1cff + 2182419 commit dbb5c4a
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
6 changes: 4 additions & 2 deletions activerecord/lib/arel/visitors/to_sql.rb
Expand Up @@ -586,10 +586,11 @@ def visit_Arel_Table(o, collector)
end

def visit_Arel_Nodes_In(o, collector)
collector.preparable = false
attr, values = o.left, o.right

if Array === values
collector.preparable = false

unless values.empty?
values.delete_if { |value| unboundable?(value) }
end
Expand All @@ -602,10 +603,11 @@ def visit_Arel_Nodes_In(o, collector)
end

def visit_Arel_Nodes_NotIn(o, collector)
collector.preparable = false
attr, values = o.left, o.right

if Array === values
collector.preparable = false

unless values.empty?
values.delete_if { |value| unboundable?(value) }
end
Expand Down
36 changes: 36 additions & 0 deletions activerecord/test/cases/arel/visitors/to_sql_test.rb
Expand Up @@ -520,6 +520,24 @@ def dispatch
"users"."id" IN (SELECT id FROM "users" WHERE "users"."name" = 'Aaron')
}
end

it "is not preparable when an array" do
node = @attr.in [1, 2, 3]

collector = Collectors::SQLString.new.tap { |c| c.preparable = true }
@visitor.accept(node, collector)
_(collector.preparable).must_equal false
end

it "is preparable when a subselect" do
table = Table.new(:users)
subquery = table.project(table[:id]).where(table[:name].eq("Aaron"))
node = @attr.in subquery

collector = Collectors::SQLString.new.tap { |c| c.preparable = true }
@visitor.accept(node, collector)
_(collector.preparable).must_equal true
end
end

describe "Nodes::InfixOperation" do
Expand Down Expand Up @@ -682,6 +700,24 @@ def dispatch
"users"."id" NOT IN (SELECT id FROM "users" WHERE "users"."name" = 'Aaron')
}
end

it "is not preparable when an array" do
node = @attr.not_in [1, 2, 3]

collector = Collectors::SQLString.new.tap { |c| c.preparable = true }
@visitor.accept(node, collector)
_(collector.preparable).must_equal false
end

it "is preparable when a subselect" do
table = Table.new(:users)
subquery = table.project(table[:id]).where(table[:name].eq("Aaron"))
node = @attr.not_in subquery

collector = Collectors::SQLString.new.tap { |c| c.preparable = true }
@visitor.accept(node, collector)
_(collector.preparable).must_equal true
end
end

describe "Constants" do
Expand Down

0 comments on commit dbb5c4a

Please sign in to comment.