aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Prater & Fire-Dragon-DoL <francesco.belladonna@gmail.com>2013-07-31 01:08:22 +0200
committerStephen Prater <me@stephenprater.com>2014-03-30 22:59:16 -0500
commit4cb02380116b102142f85d92b7923c11882f94c7 (patch)
tree3cfb5968941e8979ebdfe12c2884398b65f7c8b6
parentdbe1f8b29a80bf07aa5df624f68b9de869c1f248 (diff)
downloadrails-4cb02380116b102142f85d92b7923c11882f94c7.tar.gz
rails-4cb02380116b102142f85d92b7923c11882f94c7.tar.bz2
rails-4cb02380116b102142f85d92b7923c11882f94c7.zip
Added right and full outer joins
-rw-r--r--lib/arel/nodes.rb2
-rw-r--r--lib/arel/nodes/full_outer_join.rb6
-rw-r--r--lib/arel/nodes/right_outer_join.rb6
-rw-r--r--lib/arel/visitors/depth_first.rb2
-rw-r--r--lib/arel/visitors/dot.rb4
-rw-r--r--lib/arel/visitors/to_sql.rb8
-rw-r--r--test/test_select_manager.rb16
-rw-r--r--test/test_table.rb14
-rw-r--r--test/visitors/test_depth_first.rb12
-rw-r--r--test/visitors/test_join_sql.rb26
10 files changed, 95 insertions, 1 deletions
diff --git a/lib/arel/nodes.rb b/lib/arel/nodes.rb
index 6ce1ed7dba..a68e327983 100644
--- a/lib/arel/nodes.rb
+++ b/lib/arel/nodes.rb
@@ -45,8 +45,10 @@ require 'arel/nodes/named_function'
require 'arel/nodes/window'
# joins
+require 'arel/nodes/full_outer_join'
require 'arel/nodes/inner_join'
require 'arel/nodes/outer_join'
+require 'arel/nodes/right_outer_join'
require 'arel/nodes/string_join'
require 'arel/nodes/sql_literal'
diff --git a/lib/arel/nodes/full_outer_join.rb b/lib/arel/nodes/full_outer_join.rb
new file mode 100644
index 0000000000..708f161c9a
--- /dev/null
+++ b/lib/arel/nodes/full_outer_join.rb
@@ -0,0 +1,6 @@
+module Arel
+ module Nodes
+ class FullOuterJoin < Arel::Nodes::Join
+ end
+ end
+end
diff --git a/lib/arel/nodes/right_outer_join.rb b/lib/arel/nodes/right_outer_join.rb
new file mode 100644
index 0000000000..ea1ddb7d52
--- /dev/null
+++ b/lib/arel/nodes/right_outer_join.rb
@@ -0,0 +1,6 @@
+module Arel
+ module Nodes
+ class RightOuterJoin < Arel::Nodes::Join
+ end
+ end
+end
diff --git a/lib/arel/visitors/depth_first.rb b/lib/arel/visitors/depth_first.rb
index 1770ab21d5..7043e5d527 100644
--- a/lib/arel/visitors/depth_first.rb
+++ b/lib/arel/visitors/depth_first.rb
@@ -67,6 +67,7 @@ module Arel
alias :visit_Arel_Nodes_DeleteStatement :binary
alias :visit_Arel_Nodes_DoesNotMatch :binary
alias :visit_Arel_Nodes_Equality :binary
+ alias :visit_Arel_Nodes_FullOuterJoin :binary
alias :visit_Arel_Nodes_GreaterThan :binary
alias :visit_Arel_Nodes_GreaterThanOrEqual :binary
alias :visit_Arel_Nodes_In :binary
@@ -80,6 +81,7 @@ module Arel
alias :visit_Arel_Nodes_NotIn :binary
alias :visit_Arel_Nodes_Or :binary
alias :visit_Arel_Nodes_OuterJoin :binary
+ alias :visit_Arel_Nodes_RightOuterJoin :binary
alias :visit_Arel_Nodes_TableAlias :binary
alias :visit_Arel_Nodes_Values :binary
diff --git a/lib/arel/visitors/dot.rb b/lib/arel/visitors/dot.rb
index b2fa6bfbd5..99f4c467d2 100644
--- a/lib/arel/visitors/dot.rb
+++ b/lib/arel/visitors/dot.rb
@@ -54,7 +54,9 @@ module Arel
visit_edge o, "left"
visit_edge o, "right"
end
- alias :visit_Arel_Nodes_OuterJoin :visit_Arel_Nodes_InnerJoin
+ alias :visit_Arel_Nodes_FullOuterJoin :visit_Arel_Nodes_InnerJoin
+ alias :visit_Arel_Nodes_OuterJoin :visit_Arel_Nodes_InnerJoin
+ alias :visit_Arel_Nodes_RightOuterJoin :visit_Arel_Nodes_InnerJoin
def visit_Arel_Nodes_DeleteStatement o
visit_edge o, "relation"
diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb
index 0c2e649995..84a88e1899 100644
--- a/lib/arel/visitors/to_sql.rb
+++ b/lib/arel/visitors/to_sql.rb
@@ -446,10 +446,18 @@ module Arel
visit o.left
end
+ def visit_Arel_Nodes_FullOuterJoin o
+ "FULL OUTER JOIN #{visit o.left} #{visit o.right}"
+ end
+
def visit_Arel_Nodes_OuterJoin o
"LEFT OUTER JOIN #{visit o.left} #{visit o.right}"
end
+ def visit_Arel_Nodes_RightOuterJoin o
+ "RIGHT OUTER JOIN #{visit o.left} #{visit o.right}"
+ end
+
def visit_Arel_Nodes_InnerJoin o
s = "INNER JOIN #{visit o.left}"
if o.right
diff --git a/test/test_select_manager.rb b/test/test_select_manager.rb
index 7f025f7a02..a0981476fe 100644
--- a/test/test_select_manager.rb
+++ b/test/test_select_manager.rb
@@ -519,12 +519,28 @@ module Arel
it 'should create join nodes with a klass' do
relation = Arel::SelectManager.new Table.engine
+ join = relation.create_join 'foo', 'bar', Arel::Nodes::FullOuterJoin
+ assert_kind_of Arel::Nodes::FullOuterJoin, join
+ assert_equal 'foo', join.left
+ assert_equal 'bar', join.right
+ end
+
+ it 'should create join nodes with a klass' do
+ relation = Arel::SelectManager.new Table.engine
join = relation.create_join 'foo', 'bar', Arel::Nodes::OuterJoin
assert_kind_of Arel::Nodes::OuterJoin, join
assert_equal 'foo', join.left
assert_equal 'bar', join.right
end
+ it 'should create join nodes with a klass' do
+ relation = Arel::SelectManager.new Table.engine
+ join = relation.create_join 'foo', 'bar', Arel::Nodes::RightOuterJoin
+ assert_kind_of Arel::Nodes::RightOuterJoin, join
+ assert_equal 'foo', join.left
+ assert_equal 'bar', join.right
+ end
+
describe 'join' do
it 'responds to join' do
left = Table.new :users
diff --git a/test/test_table.rb b/test/test_table.rb
index 431a919de1..b4c2a65fcd 100644
--- a/test/test_table.rb
+++ b/test/test_table.rb
@@ -20,12 +20,26 @@ module Arel
end
it 'should create join nodes with a klass' do
+ join = @relation.create_join 'foo', 'bar', Arel::Nodes::FullOuterJoin
+ assert_kind_of Arel::Nodes::FullOuterJoin, join
+ assert_equal 'foo', join.left
+ assert_equal 'bar', join.right
+ end
+
+ it 'should create join nodes with a klass' do
join = @relation.create_join 'foo', 'bar', Arel::Nodes::OuterJoin
assert_kind_of Arel::Nodes::OuterJoin, join
assert_equal 'foo', join.left
assert_equal 'bar', join.right
end
+ it 'should create join nodes with a klass' do
+ join = @relation.create_join 'foo', 'bar', Arel::Nodes::RightOuterJoin
+ assert_kind_of Arel::Nodes::RightOuterJoin, join
+ assert_equal 'foo', join.left
+ assert_equal 'bar', join.right
+ end
+
it 'should return an insert manager' do
im = @relation.compile_insert 'VALUES(NULL)'
assert_kind_of Arel::InsertManager, im
diff --git a/test/visitors/test_depth_first.rb b/test/visitors/test_depth_first.rb
index cbaa780dae..baa8f64184 100644
--- a/test/visitors/test_depth_first.rb
+++ b/test/visitors/test_depth_first.rb
@@ -81,12 +81,24 @@ module Arel
assert_equal [:a, :b, join], @collector.calls
end
+ def test_full_outer_join
+ join = Nodes::FullOuterJoin.new :a, :b
+ @visitor.accept join
+ assert_equal [:a, :b, join], @collector.calls
+ end
+
def test_outer_join
join = Nodes::OuterJoin.new :a, :b
@visitor.accept join
assert_equal [:a, :b, join], @collector.calls
end
+ def test_right_outer_join
+ join = Nodes::RightOuterJoin.new :a, :b
+ @visitor.accept join
+ assert_equal [:a, :b, join], @collector.calls
+ end
+
[
Arel::Nodes::Assignment,
Arel::Nodes::Between,
diff --git a/test/visitors/test_join_sql.rb b/test/visitors/test_join_sql.rb
index ea71c05d79..34378dafe7 100644
--- a/test/visitors/test_join_sql.rb
+++ b/test/visitors/test_join_sql.rb
@@ -25,6 +25,19 @@ module Arel
end
end
+ describe 'FULL outer join' do
+ it 'should visit left if left is a join' do
+ t = Table.new :users
+ sm = t.select_manager
+ sm.join(t, Nodes::FullOuterJoin).on(t[:id]).join(
+ t, Nodes::FullOuterJoin).on(t[:id])
+ sm.join_sql.must_be_like %{
+ FULL OUTER JOIN "users" ON "users"."id"
+ FULL OUTER JOIN "users" ON "users"."id"
+ }
+ end
+ end
+
describe 'outer join' do
it 'should visit left if left is a join' do
t = Table.new :users
@@ -37,6 +50,19 @@ module Arel
}
end
end
+
+ describe 'right outer join' do
+ it 'should visit left if left is a join' do
+ t = Table.new :users
+ sm = t.select_manager
+ sm.join(t, Nodes::RightOuterJoin).on(t[:id]).join(
+ t, Nodes::RightOuterJoin).on(t[:id])
+ sm.join_sql.must_be_like %{
+ RIGHT OUTER JOIN "users" ON "users"."id"
+ RIGHT OUTER JOIN "users" ON "users"."id"
+ }
+ end
+ end
end
end
end