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

Allow the construction of a CTE from an Arel::Table

This commit is contained in:
Eric Hayes 2020-05-11 11:03:15 -04:00
parent 57d926a78a
commit 596469d556
3 changed files with 49 additions and 2 deletions

View file

@ -4,6 +4,7 @@ module Arel # :nodoc: all
class Table
include Arel::Crud
include Arel::FactoryMethods
include Arel::AliasPredication
@engine = nil
class << self; attr_accessor :engine; end

View file

@ -192,12 +192,12 @@ module Arel # :nodoc: all
def visit_Arel_Nodes_With(o, collector)
collector << "WITH "
inject_join o.children, collector, ", "
collect_ctes(o.children, collector)
end
def visit_Arel_Nodes_WithRecursive(o, collector)
collector << "WITH RECURSIVE "
inject_join o.children, collector, ", "
collect_ctes(o.children, collector)
end
def visit_Arel_Nodes_Union(o, collector)
@ -874,6 +874,27 @@ module Arel # :nodoc: all
collector << " IS NULL)"
collector << " THEN 0 ELSE 1 END"
end
def collect_ctes(children, collector)
children.each_with_index do |child, i|
collector << ", " unless i == 0
case child
when Arel::Nodes::As
name = child.left.name
relation = child.right
when Arel::Nodes::TableAlias
name = child.name
relation = child.relation
end
collector << quote_table_name(name)
collector << " AS "
visit relation, collector
end
collector
end
end
end
end

View file

@ -708,6 +708,31 @@ module Arel
}
end
end
describe "Nodes::With" do
it "handles table aliases" do
manager = Table.new(:foo).project(Arel.star).from(Arel.sql("expr2"))
expr1 = Table.new(:bar).project(Arel.star).as("expr1")
expr2 = Table.new(:baz).project(Arel.star).as("expr2")
manager.with(expr1, expr2)
_(compile(manager.ast)).must_be_like %{
WITH expr1 AS (SELECT * FROM "bar"), expr2 AS (SELECT * FROM "baz") SELECT * FROM expr2
}
end
end
describe "Nodes::WithRecursive" do
it "handles table aliases" do
manager = Table.new(:foo).project(Arel.star).from(Arel.sql("expr1"))
expr1 = Table.new(:bar).project(Arel.star).as("expr1")
manager.with(:recursive, expr1)
_(compile(manager.ast)).must_be_like %{
WITH RECURSIVE expr1 AS (SELECT * FROM "bar") SELECT * FROM expr1
}
end
end
end
end
end