From ed6192c55b8e77b60e4203dc30ae056f222a1499 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 15 Sep 2010 09:26:01 -0700 Subject: [PATCH] adding a grouping node --- lib/arel/nodes.rb | 2 ++ lib/arel/nodes/binary.rb | 10 +--------- lib/arel/nodes/grouping.rb | 21 +++++++++++++++++++++ lib/arel/nodes/node.rb | 20 ++++++++++++++++++++ lib/arel/visitors/to_sql.rb | 4 ++++ spec/arel/nodes/equality_spec.rb | 4 ++-- spec/arel/nodes/or_spec.rb | 8 ++++---- 7 files changed, 54 insertions(+), 15 deletions(-) create mode 100644 lib/arel/nodes/grouping.rb create mode 100644 lib/arel/nodes/node.rb diff --git a/lib/arel/nodes.rb b/lib/arel/nodes.rb index 99a34c3b2b..ac4bba57c2 100644 --- a/lib/arel/nodes.rb +++ b/lib/arel/nodes.rb @@ -1,3 +1,4 @@ +require 'arel/nodes/node' require 'arel/nodes/binary' require 'arel/nodes/equality' require 'arel/nodes/not_equal' @@ -29,6 +30,7 @@ require 'arel/nodes/unqualified_column' require 'arel/nodes/table_alias' require 'arel/nodes/join' require 'arel/nodes/group' +require 'arel/nodes/grouping' require 'arel/nodes/inner_join' require 'arel/nodes/outer_join' require 'arel/nodes/string_join' diff --git a/lib/arel/nodes/binary.rb b/lib/arel/nodes/binary.rb index 3cd9583e79..090468adfa 100644 --- a/lib/arel/nodes/binary.rb +++ b/lib/arel/nodes/binary.rb @@ -1,6 +1,6 @@ module Arel module Nodes - class Binary + class Binary < Arel::Nodes::Node attr_accessor :left, :right def initialize left, right @@ -8,14 +8,6 @@ module Arel @right = right end - def or right - Nodes::Or.new self, right - end - - def and right - Nodes::And.new self, right - end - # FIXME: this method should go away. I don't like people calling # to_sql on non-head nodes. This forces us to walk the AST until we # can find a node that has a "relation" member. diff --git a/lib/arel/nodes/grouping.rb b/lib/arel/nodes/grouping.rb new file mode 100644 index 0000000000..0af1df1f7a --- /dev/null +++ b/lib/arel/nodes/grouping.rb @@ -0,0 +1,21 @@ +module Arel + module Nodes + class Grouping < Arel::Nodes::Node + attr_accessor :expr + + def initialize expression + @expr = expression + end + + # FIXME: this method should go away. I don't like people calling + # to_sql on non-head nodes. This forces us to walk the AST until we + # can find a node that has a "relation" member. + # + # Maybe we should just use `Table.engine`? :'( + def to_sql + viz = Visitors::ToSql.new Table.engine + viz.accept self + end + end + end +end diff --git a/lib/arel/nodes/node.rb b/lib/arel/nodes/node.rb new file mode 100644 index 0000000000..fd5ea410ea --- /dev/null +++ b/lib/arel/nodes/node.rb @@ -0,0 +1,20 @@ +module Arel + module Nodes + ### + # Abstract base class for all AST nodes + class Node + ### + # Factory method to create a Nodes::Grouping node that has an Nodes::Or + # node as a child. + def or right + Nodes::Grouping.new Nodes::Or.new(self, right) + end + + ### + # Factory method to create an Nodes::And node. + def and right + Nodes::And.new self, right + end + end + end +end diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb index 46f70d0f7c..5be95565f3 100644 --- a/lib/arel/visitors/to_sql.rb +++ b/lib/arel/visitors/to_sql.rb @@ -84,6 +84,10 @@ module Arel def visit_Arel_Nodes_Lock o end + def visit_Arel_Nodes_Grouping o + "(#{visit o.expr})" + end + def visit_Arel_Nodes_Group o visit o.expr end diff --git a/spec/arel/nodes/equality_spec.rb b/spec/arel/nodes/equality_spec.rb index d9edc352f3..81eea4d482 100644 --- a/spec/arel/nodes/equality_spec.rb +++ b/spec/arel/nodes/equality_spec.rb @@ -34,8 +34,8 @@ module Arel left = attr.eq(10) right = attr.eq(11) node = left.or right - check node.left.should == left - check node.right.should == right + check node.expr.left.should == left + check node.expr.right.should == right end end diff --git a/spec/arel/nodes/or_spec.rb b/spec/arel/nodes/or_spec.rb index e855b92453..88484ff4f7 100644 --- a/spec/arel/nodes/or_spec.rb +++ b/spec/arel/nodes/or_spec.rb @@ -7,12 +7,12 @@ module Arel left = attr.eq(10) right = attr.eq(11) node = left.or right - check node.left.should == left - check node.right.should == right + check node.expr.left.should == left + check node.expr.right.should == right oror = node.or(right) - check oror.left == node - check oror.right == right + check oror.expr.left == node + check oror.expr.right == right end end end