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

Merge pull request #481 from lautis/lateral

Lateral expressions for PostgreSQL
......@@ -10,7 +10,7 @@ def initialize
@source = JoinSource.new nil
@top = nil
# http://savage.net.au/SQL/sql-92.bnf.html#set%20quantifier
# https://ronsavage.github.io/SQL/sql-92.bnf.html#set%20quantifier
@set_quantifier = nil
@projections = []
@wheres = []
......
......@@ -28,6 +28,7 @@ def eql? other
Group
GroupingElement
GroupingSet
Lateral
Limit
Lock
Not
......
......@@ -202,6 +202,11 @@ def except other
end
alias :minus :except
def lateral table_name = nil
base = table_name.nil? ? ast : as(table_name)
Nodes::Lateral.new(base)
end
def with *subqueries
if subqueries.first.is_a? Symbol
node_class = Nodes.const_get("With#{subqueries.shift.to_s.capitalize}")
......
......@@ -25,6 +25,7 @@ def unary o
alias :visit_Arel_Nodes_GroupingElement :unary
alias :visit_Arel_Nodes_Grouping :unary
alias :visit_Arel_Nodes_Having :unary
alias :visit_Arel_Nodes_Lateral :unary
alias :visit_Arel_Nodes_Limit :unary
alias :visit_Arel_Nodes_Not :unary
alias :visit_Arel_Nodes_Offset :unary
......
......@@ -5,6 +5,7 @@ class PostgreSQL < Arel::Visitors::ToSql
CUBE = 'CUBE'
ROLLUP = 'ROLLUP'
GROUPING_SET = 'GROUPING SET'
LATERAL = 'LATERAL'
private
......@@ -69,6 +70,23 @@ def visit_Arel_Nodes_GroupingSet o, collector
grouping_array_or_grouping_element o, collector
end
def visit_Arel_Nodes_Lateral o, collector
collector << LATERAL
collector << SPACE
grouping_parentheses o, collector
end
# Used by Lateral visitor to enclose select queries in parentheses
def grouping_parentheses o, collector
if o.expr.is_a? Nodes::SelectStatement
collector << "("
visit o.expr, collector
collector << ")"
else
visit o.expr, collector
end
end
# Utilized by GroupingSet, Cube & RollUp visitors to
# handle grouping aggregation semantics
def grouping_array_or_grouping_element o, collector
......
......@@ -51,6 +51,20 @@ def compile node
assert_equal 'SELECT DISTINCT', compile(core)
end
it 'encloses LATERAL queries in parens' do
subquery = @table.project(:id).where(@table[:name].matches('foo%'))
compile(subquery.lateral).must_be_like %{
LATERAL (SELECT id FROM "users" WHERE "users"."name" ILIKE 'foo%')
}
end
it 'produces LATERAL queries with alias' do
subquery = @table.project(:id).where(@table[:name].matches('foo%'))
compile(subquery.lateral('bar')).must_be_like %{
LATERAL (SELECT id FROM "users" WHERE "users"."name" ILIKE 'foo%') bar
}
end
describe "Nodes::Matches" do
it "should know how to visit" do
node = @table[:name].matches('foo%')
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册