aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2014-03-24 16:26:09 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2014-03-24 16:26:09 -0700
commit93d72131bcc24ccb5536bec672d2dac94f8de651 (patch)
treeb0bddcce28817906b483c8f73c574d350ac844c4 /lib
parent24995298face1d08ffb52f6c1b0374feeb7a380b (diff)
downloadrails-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')
-rw-r--r--lib/arel/nodes.rb32
-rw-r--r--lib/arel/nodes/node.rb2
-rw-r--r--lib/arel/predications.rb8
-rw-r--r--lib/arel/update_manager.rb4
-rw-r--r--lib/arel/visitors/mysql.rb4
-rw-r--r--lib/arel/visitors/to_sql.rb40
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}"