未验证 提交 ca48977f 编写于 作者: A Aaron Patterson 提交者: GitHub

Merge pull request #39246 from alassek/arel-set-operators

Add Arel support for PostgreSQL contains and overlaps operators
......@@ -47,6 +47,18 @@ def initialize(left, right)
end
end
class Contains < InfixOperation
def initialize(left, right)
super("@>", left, right)
end
end
class Overlaps < InfixOperation
def initialize(left, right)
super("&&", left, right)
end
end
class BitwiseAnd < InfixOperation
def initialize(left, right)
super(:&, left, right)
......
......@@ -206,6 +206,14 @@ def concat(other)
Nodes::Concat.new self, other
end
def contains(other)
Arel::Nodes::Contains.new(self, other)
end
def overlaps(other)
Arel::Nodes::Overlaps.new(self, other)
end
private
def grouping_any(method_id, others, *extras)
nodes = others.map { |expr| send(method_id, expr, *extras) }
......
......@@ -92,6 +92,9 @@ def visit_Arel_Nodes_NullsLast(o, collector)
collector << " NULLS LAST"
end
alias :visit_Arel_Nodes_Contains :visit_Arel_Nodes_InfixOperation
alias :visit_Arel_Nodes_Overlaps :visit_Arel_Nodes_InfixOperation
# Used by Lateral visitor to enclose select queries in parentheses
def grouping_parentheses(o, collector)
if o.expr.is_a? Nodes::SelectStatement
......
......@@ -1043,6 +1043,38 @@ class AttributeTest < Arel::Spec
end
end
describe "#contains" do
it "should create a Contains node" do
relation = Table.new(:products)
query = Nodes.build_quoted("{foo,bar}")
_(relation[:tags].contains(query)).must_be_kind_of Nodes::Contains
end
it "should generate @> in sql" do
relation = Table.new(:products)
mgr = relation.project relation[:id]
query = Nodes.build_quoted("{foo,bar}")
mgr.where relation[:tags].contains(query)
_(mgr.to_sql).must_be_like %{ SELECT "products"."id" FROM "products" WHERE "products"."tags" @> '{foo,bar}' }
end
end
describe "#overlaps" do
it "should create an Overlaps node" do
relation = Table.new(:products)
query = Nodes.build_quoted("{foo,bar}")
_(relation[:tags].overlaps(query)).must_be_kind_of Nodes::Overlaps
end
it "should generate && in sql" do
relation = Table.new(:products)
mgr = relation.project relation[:id]
query = Nodes.build_quoted("{foo,bar}")
mgr.where relation[:tags].overlaps(query)
_(mgr.to_sql).must_be_like %{ SELECT "products"."id" FROM "products" WHERE "products"."tags" && '{foo,bar}' }
end
end
describe "equality" do
describe "#to_sql" do
it "should produce sql" do
......
......@@ -331,6 +331,22 @@ def compile(node)
}
end
end
describe "Nodes::InfixOperation" do
it "should handle Contains" do
inner = Nodes.build_quoted('{"foo":"bar"}')
outer = Table.new(:products)[:metadata]
sql = compile Nodes::Contains.new(outer, inner)
_(sql).must_be_like %{ "products"."metadata" @> '{"foo":"bar"}' }
end
it "should handle Overlaps" do
column = Table.new(:products)[:tags]
search = Nodes.build_quoted("{foo,bar,baz}")
sql = compile Nodes::Overlaps.new(column, search)
_(sql).must_be_like %{ "products"."tags" && '{foo,bar,baz}' }
end
end
end
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册