diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2014-03-24 16:26:09 -0700 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2014-03-24 16:26:09 -0700 |
commit | 93d72131bcc24ccb5536bec672d2dac94f8de651 (patch) | |
tree | b0bddcce28817906b483c8f73c574d350ac844c4 /lib/arel | |
parent | 24995298face1d08ffb52f6c1b0374feeb7a380b (diff) | |
download | rails-93d72131bcc24ccb5536bec672d2dac94f8de651.tar.gz rails-93d72131bcc24ccb5536bec672d2dac94f8de651.tar.bz2 rails-93d72131bcc24ccb5536bec672d2dac94f8de651.zip |
add the casting node to the AST at build time
If we add the casting node to the ast at build time, then we can avoid
doing the lookup at visit time.
Diffstat (limited to 'lib/arel')
-rw-r--r-- | lib/arel/nodes.rb | 32 | ||||
-rw-r--r-- | lib/arel/nodes/node.rb | 2 | ||||
-rw-r--r-- | lib/arel/predications.rb | 8 | ||||
-rw-r--r-- | lib/arel/update_manager.rb | 4 | ||||
-rw-r--r-- | lib/arel/visitors/mysql.rb | 4 | ||||
-rw-r--r-- | lib/arel/visitors/to_sql.rb | 40 |
6 files changed, 69 insertions, 21 deletions
diff --git a/lib/arel/nodes.rb b/lib/arel/nodes.rb index 54caea69a1..3642958cf8 100644 --- a/lib/arel/nodes.rb +++ b/lib/arel/nodes.rb @@ -50,3 +50,35 @@ require 'arel/nodes/outer_join' require 'arel/nodes/string_join' require 'arel/nodes/sql_literal' + +module Arel + module Nodes + class Casted < Arel::Nodes::Node # :nodoc: + attr_reader :val, :attribute + def initialize val, attribute + @val = val + @attribute = attribute + super() + end + + def nil?; @val.nil?; end + end + + class Quoted < Arel::Nodes::Unary # :nodoc: + end + + def self.build_quoted other, attribute = nil + case other + when Arel::Nodes::Node, Arel::Attributes::Attribute + other + else + case attribute + when Arel::Attributes::Attribute + Casted.new other, attribute + else + Quoted.new other + end + end + end + end +end diff --git a/lib/arel/nodes/node.rb b/lib/arel/nodes/node.rb index 36e7628612..a3eadf7170 100644 --- a/lib/arel/nodes/node.rb +++ b/lib/arel/nodes/node.rb @@ -51,6 +51,8 @@ module Arel ::Arel::Visitors::DepthFirst.new(block).accept self end + + def cast_reference?; false; end # :nodoc: end end end diff --git a/lib/arel/predications.rb b/lib/arel/predications.rb index c485de07e3..fb98f0a383 100644 --- a/lib/arel/predications.rb +++ b/lib/arel/predications.rb @@ -13,7 +13,7 @@ module Arel end def eq other - Nodes::Equality.new self, other + Nodes::Equality.new self, Nodes.build_quoted(other, self) end def eq_any others @@ -21,7 +21,7 @@ module Arel end def eq_all others - grouping_all :eq, others + grouping_all :eq, others.map { |x| Nodes.build_quoted(x, self) } end def in other @@ -93,7 +93,7 @@ module Arel end def matches other - Nodes::Matches.new self, other + Nodes::Matches.new self, Nodes.build_quoted(other, self) end def matches_any others @@ -105,7 +105,7 @@ module Arel end def does_not_match other - Nodes::DoesNotMatch.new self, other + Nodes::DoesNotMatch.new self, Nodes.build_quoted(other, self) end def does_not_match_any others diff --git a/lib/arel/update_manager.rb b/lib/arel/update_manager.rb index 56e219040c..db8cf05f76 100644 --- a/lib/arel/update_manager.rb +++ b/lib/arel/update_manager.rb @@ -7,12 +7,12 @@ module Arel end def take limit - @ast.limit = Nodes::Limit.new(limit) if limit + @ast.limit = Nodes::Limit.new(Nodes.build_quoted(limit)) if limit self end def key= key - @ast.key = key + @ast.key = Nodes.build_quoted(key) end def key diff --git a/lib/arel/visitors/mysql.rb b/lib/arel/visitors/mysql.rb index 4db5a94019..ec9d91f8ce 100644 --- a/lib/arel/visitors/mysql.rb +++ b/lib/arel/visitors/mysql.rb @@ -32,7 +32,9 @@ module Arel # :'( # http://dev.mysql.com/doc/refman/5.0/en/select.html#id3482214 def visit_Arel_Nodes_SelectStatement o, a - o.limit = Arel::Nodes::Limit.new(18446744073709551615) if o.offset && !o.limit + if o.offset && !o.limit + o.limit = Arel::Nodes::Limit.new(Nodes.build_quoted(18446744073709551615)) + end super end diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb index 236f0354b1..69c82e792a 100644 --- a/lib/arel/visitors/to_sql.rb +++ b/lib/arel/visitors/to_sql.rb @@ -116,6 +116,14 @@ module Arel o.alias ? " AS #{visit o.alias, a}" : ''}" end + def visit_Arel_Nodes_Casted o, a + quoted o.val, o.attribute + end + + def visit_Arel_Nodes_Quoted o, a + quoted o.expr, nil + end + def visit_Arel_Nodes_True o, a "TRUE" end @@ -562,20 +570,24 @@ module Arel quote(o, column_for(a)) end - alias :visit_ActiveSupport_Multibyte_Chars :quoted - alias :visit_ActiveSupport_StringInquirer :quoted - alias :visit_BigDecimal :quoted - alias :visit_Class :quoted - alias :visit_Date :quoted - alias :visit_DateTime :quoted - alias :visit_FalseClass :quoted - alias :visit_Float :quoted - alias :visit_Hash :quoted - alias :visit_NilClass :quoted - alias :visit_String :quoted - alias :visit_Symbol :quoted - alias :visit_Time :quoted - alias :visit_TrueClass :quoted + def unsupported o, a + raise "unsupported: #{o.class.name}" + end + + alias :visit_ActiveSupport_Multibyte_Chars :unsupported + alias :visit_ActiveSupport_StringInquirer :unsupported + alias :visit_BigDecimal :unsupported + alias :visit_Class :unsupported + alias :visit_Date :unsupported + alias :visit_DateTime :unsupported + alias :visit_FalseClass :unsupported + alias :visit_Float :unsupported + alias :visit_Hash :unsupported + alias :visit_NilClass :unsupported + alias :visit_String :unsupported + alias :visit_Symbol :unsupported + alias :visit_Time :unsupported + alias :visit_TrueClass :unsupported def visit_Arel_Nodes_InfixOperation o, a "#{visit o.left, a} #{o.operator} #{visit o.right, a}" |