aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/arel.rb7
-rw-r--r--lib/arel/attributes/attribute.rb2
-rw-r--r--lib/arel/crud.rb47
-rw-r--r--lib/arel/factory_methods.rb25
-rw-r--r--lib/arel/nodes.rb62
-rw-r--r--lib/arel/nodes/and.rb19
-rw-r--r--lib/arel/nodes/as.rb6
-rw-r--r--lib/arel/nodes/assignment.rb6
-rw-r--r--lib/arel/nodes/avg.rb6
-rw-r--r--lib/arel/nodes/between.rb6
-rw-r--r--lib/arel/nodes/binary.rb24
-rw-r--r--lib/arel/nodes/does_not_match.rb6
-rw-r--r--lib/arel/nodes/exists.rb7
-rw-r--r--lib/arel/nodes/function.rb10
-rw-r--r--lib/arel/nodes/greater_than.rb6
-rw-r--r--lib/arel/nodes/greater_than_or_equal.rb6
-rw-r--r--lib/arel/nodes/group.rb6
-rw-r--r--lib/arel/nodes/grouping.rb6
-rw-r--r--lib/arel/nodes/having.rb6
-rw-r--r--lib/arel/nodes/join.rb13
-rw-r--r--lib/arel/nodes/join_source.rb14
-rw-r--r--lib/arel/nodes/less_than.rb6
-rw-r--r--lib/arel/nodes/less_than_or_equal.rb6
-rw-r--r--lib/arel/nodes/limit.rb7
-rw-r--r--lib/arel/nodes/matches.rb6
-rw-r--r--lib/arel/nodes/max.rb6
-rw-r--r--lib/arel/nodes/min.rb6
-rw-r--r--lib/arel/nodes/node.rb5
-rw-r--r--lib/arel/nodes/not.rb6
-rw-r--r--lib/arel/nodes/not_equal.rb6
-rw-r--r--lib/arel/nodes/not_in.rb6
-rw-r--r--lib/arel/nodes/offset.rb7
-rw-r--r--lib/arel/nodes/on.rb6
-rw-r--r--lib/arel/nodes/or.rb6
-rw-r--r--lib/arel/nodes/select_core.rb21
-rw-r--r--lib/arel/nodes/select_statement.rb1
-rw-r--r--lib/arel/nodes/string_join.rb6
-rw-r--r--lib/arel/nodes/sum.rb6
-rw-r--r--lib/arel/nodes/table_alias.rb2
-rw-r--r--lib/arel/nodes/top.rb6
-rw-r--r--lib/arel/nodes/unary.rb14
-rw-r--r--lib/arel/nodes/unqualified_column.rb4
-rw-r--r--lib/arel/nodes/update_statement.rb6
-rw-r--r--lib/arel/predications.rb6
-rw-r--r--lib/arel/select_manager.rb91
-rw-r--r--lib/arel/table.rb46
-rw-r--r--lib/arel/tree_manager.rb1
-rw-r--r--lib/arel/update_manager.rb4
-rw-r--r--lib/arel/visitors/depth_first.rb22
-rw-r--r--lib/arel/visitors/dot.rb44
-rw-r--r--lib/arel/visitors/join_sql.rb25
-rw-r--r--lib/arel/visitors/oracle.rb4
-rw-r--r--lib/arel/visitors/to_sql.rb138
53 files changed, 446 insertions, 370 deletions
diff --git a/lib/arel.rb b/lib/arel.rb
index 6c9f51d03a..32fc8d9bc0 100644
--- a/lib/arel.rb
+++ b/lib/arel.rb
@@ -1,4 +1,5 @@
require 'arel/crud'
+require 'arel/factory_methods'
require 'arel/expressions'
require 'arel/predications'
@@ -29,11 +30,15 @@ require 'arel/sql_literal'
####
module Arel
- VERSION = '2.0.6'
+ VERSION = '2.0.7.beta'
def self.sql raw_sql
Arel::Nodes::SqlLiteral.new raw_sql
end
+
+ def self.star
+ sql '*'
+ end
## Convenience Alias
Node = Arel::Nodes::Node
end
diff --git a/lib/arel/attributes/attribute.rb b/lib/arel/attributes/attribute.rb
index 5cbe194b41..9a42e5a4da 100644
--- a/lib/arel/attributes/attribute.rb
+++ b/lib/arel/attributes/attribute.rb
@@ -1,6 +1,6 @@
module Arel
module Attributes
- class Attribute < Struct.new :relation, :name, :column
+ class Attribute < Struct.new :relation, :name
include Arel::Expressions
include Arel::Predications
end
diff --git a/lib/arel/crud.rb b/lib/arel/crud.rb
index 50d6f72773..bedfb8c30c 100644
--- a/lib/arel/crud.rb
+++ b/lib/arel/crud.rb
@@ -2,12 +2,11 @@ module Arel
###
# FIXME hopefully we can remove this
module Crud
- # FIXME: this method should go away
- def update values
+ def compile_update values
um = UpdateManager.new @engine
if Nodes::SqlLiteral === values
- relation = @ctx.froms
+ relation = @ctx.from
else
relation = values.first.first.relation
end
@@ -16,22 +15,54 @@ module Arel
um.take @ast.limit.expr if @ast.limit
um.order(*@ast.orders)
um.wheres = @ctx.wheres
+ um
+ end
+
+ # FIXME: this method should go away
+ def update values
+ if $VERBOSE
+ warn <<-eowarn
+update (#{caller.first}) is deprecated and will be removed in ARel 3.0.0. Please
+switch to `compile_update`
+ eowarn
+ end
+ um = compile_update values
@engine.connection.update um.to_sql, 'AREL'
end
- # FIXME: this method should go away
- def insert values
+ def compile_insert values
im = InsertManager.new @engine
im.insert values
- @engine.connection.insert im.to_sql
+ im
end
- def delete
+ # FIXME: this method should go away
+ def insert values
+ if $VERBOSE
+ warn <<-eowarn
+insert (#{caller.first}) is deprecated and will be removed in ARel 3.0.0. Please
+switch to `compile_insert`
+ eowarn
+ end
+ @engine.connection.insert compile_insert(values).to_sql
+ end
+
+ def compile_delete
dm = DeleteManager.new @engine
dm.wheres = @ctx.wheres
dm.from @ctx.froms
- @engine.connection.delete dm.to_sql, 'AREL'
+ dm
+ end
+
+ def delete
+ if $VERBOSE
+ warn <<-eowarn
+delete (#{caller.first}) is deprecated and will be removed in ARel 3.0.0. Please
+switch to `compile_delete`
+ eowarn
+ end
+ @engine.connection.delete compile_delete.to_sql, 'AREL'
end
end
end
diff --git a/lib/arel/factory_methods.rb b/lib/arel/factory_methods.rb
new file mode 100644
index 0000000000..09b82c0555
--- /dev/null
+++ b/lib/arel/factory_methods.rb
@@ -0,0 +1,25 @@
+module Arel
+ ###
+ # Methods for creating various nodes
+ module FactoryMethods
+ def create_join to, constraint = nil, klass = Nodes::InnerJoin
+ klass.new(to, constraint)
+ end
+
+ def create_string_join to
+ create_join to, nil, Nodes::StringJoin
+ end
+
+ def create_and clauses
+ Nodes::And.new clauses
+ end
+
+ def create_on expr
+ Nodes::On.new expr
+ end
+
+ def grouping expr
+ Nodes::Grouping.new expr
+ end
+ end
+end
diff --git a/lib/arel/nodes.rb b/lib/arel/nodes.rb
index db2f22750a..c43134bb50 100644
--- a/lib/arel/nodes.rb
+++ b/lib/arel/nodes.rb
@@ -1,49 +1,37 @@
+# node
require 'arel/nodes/node'
+require 'arel/nodes/lock'
+require 'arel/nodes/select_statement'
+require 'arel/nodes/select_core'
+require 'arel/nodes/insert_statement'
+require 'arel/nodes/update_statement'
+
+# unary
require 'arel/nodes/unary'
+require 'arel/nodes/unqualified_column'
+
+# binary
require 'arel/nodes/binary'
require 'arel/nodes/equality'
-require 'arel/nodes/between'
-require 'arel/nodes/not_equal'
-require 'arel/nodes/assignment'
-require 'arel/nodes/or'
+require 'arel/nodes/in' # Why is this subclassed from equality?
+require 'arel/nodes/join_source'
+require 'arel/nodes/ordering'
+require 'arel/nodes/delete_statement'
+require 'arel/nodes/table_alias'
+
+# nary
require 'arel/nodes/and'
-require 'arel/nodes/as'
-require 'arel/nodes/not'
-require 'arel/nodes/greater_than'
-require 'arel/nodes/greater_than_or_equal'
-require 'arel/nodes/less_than'
-require 'arel/nodes/less_than_or_equal'
-require 'arel/nodes/matches'
-require 'arel/nodes/does_not_match'
-require 'arel/nodes/in'
-require 'arel/nodes/not_in'
-require 'arel/nodes/ordering'
-require 'arel/nodes/lock'
+# function
+# FIXME: Function + Alias can be rewritten as a Function and Alias node.
+# We should make Function a Unary node and deprecate the use of "aliaz"
require 'arel/nodes/function'
require 'arel/nodes/count'
require 'arel/nodes/values'
-require 'arel/nodes/offset'
-require 'arel/nodes/limit'
-require 'arel/nodes/top'
-require 'arel/nodes/sum'
-require 'arel/nodes/exists'
-require 'arel/nodes/max'
-require 'arel/nodes/min'
-require 'arel/nodes/avg'
-require 'arel/nodes/having'
-require 'arel/nodes/sql_literal'
-require 'arel/nodes/select_core'
-require 'arel/nodes/select_statement'
-require 'arel/nodes/insert_statement'
-require 'arel/nodes/update_statement'
-require 'arel/nodes/delete_statement'
-require 'arel/nodes/unqualified_column'
-require 'arel/nodes/table_alias'
-require 'arel/nodes/join'
-require 'arel/nodes/group'
-require 'arel/nodes/grouping'
+
+# joins
require 'arel/nodes/inner_join'
require 'arel/nodes/outer_join'
require 'arel/nodes/string_join'
-require 'arel/nodes/on'
+
+require 'arel/nodes/sql_literal'
diff --git a/lib/arel/nodes/and.rb b/lib/arel/nodes/and.rb
index 80f420b4f1..b4443c3d27 100644
--- a/lib/arel/nodes/and.rb
+++ b/lib/arel/nodes/and.rb
@@ -1,6 +1,23 @@
module Arel
module Nodes
- class And < Arel::Nodes::Binary
+ class And < Arel::Nodes::Node
+ attr_reader :children
+
+ def initialize children, right = nil
+ unless Array === children
+ warn "(#{caller.first}) AND nodes should be created with a list"
+ children = [children, right]
+ end
+ @children = children
+ end
+
+ def left
+ children.first
+ end
+
+ def right
+ children[1]
+ end
end
end
end
diff --git a/lib/arel/nodes/as.rb b/lib/arel/nodes/as.rb
deleted file mode 100644
index 9009fe12f4..0000000000
--- a/lib/arel/nodes/as.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class As < Arel::Nodes::Binary
- end
- end
-end
diff --git a/lib/arel/nodes/assignment.rb b/lib/arel/nodes/assignment.rb
deleted file mode 100644
index 693bd5afe6..0000000000
--- a/lib/arel/nodes/assignment.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class Assignment < Arel::Nodes::Binary
- end
- end
-end
diff --git a/lib/arel/nodes/avg.rb b/lib/arel/nodes/avg.rb
deleted file mode 100644
index 8fc86fc21e..0000000000
--- a/lib/arel/nodes/avg.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class Avg < Arel::Nodes::Function
- end
- end
-end
diff --git a/lib/arel/nodes/between.rb b/lib/arel/nodes/between.rb
deleted file mode 100644
index 2e7596cdae..0000000000
--- a/lib/arel/nodes/between.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class Between < Arel::Nodes::Binary
- end
- end
-end
diff --git a/lib/arel/nodes/binary.rb b/lib/arel/nodes/binary.rb
index cfa75909c5..0d02554199 100644
--- a/lib/arel/nodes/binary.rb
+++ b/lib/arel/nodes/binary.rb
@@ -7,6 +7,30 @@ module Arel
@left = left
@right = right
end
+
+ def initialize_copy other
+ super
+ @left = @left.clone if @left
+ @right = @right.clone if @right
+ end
+ end
+
+ %w{
+ As
+ Assignment
+ Between
+ DoesNotMatch
+ GreaterThan
+ GreaterThanOrEqual
+ Join
+ LessThan
+ LessThanOrEqual
+ Matches
+ NotEqual
+ NotIn
+ Or
+ }.each do |name|
+ const_set name, Class.new(Binary)
end
end
end
diff --git a/lib/arel/nodes/does_not_match.rb b/lib/arel/nodes/does_not_match.rb
deleted file mode 100644
index 33bdeab005..0000000000
--- a/lib/arel/nodes/does_not_match.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class DoesNotMatch < Arel::Nodes::Binary
- end
- end
-end
diff --git a/lib/arel/nodes/exists.rb b/lib/arel/nodes/exists.rb
deleted file mode 100644
index 18ba8403b4..0000000000
--- a/lib/arel/nodes/exists.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-module Arel
- module Nodes
- class Exists < Arel::Nodes::Function
- alias :select_stmt :expressions
- end
- end
-end
diff --git a/lib/arel/nodes/function.rb b/lib/arel/nodes/function.rb
index 133dd66019..e4e45bff31 100644
--- a/lib/arel/nodes/function.rb
+++ b/lib/arel/nodes/function.rb
@@ -14,5 +14,15 @@ module Arel
self
end
end
+
+ %w{
+ Sum
+ Exists
+ Max
+ Min
+ Avg
+ }.each do |name|
+ const_set(name, Class.new(Function))
+ end
end
end
diff --git a/lib/arel/nodes/greater_than.rb b/lib/arel/nodes/greater_than.rb
deleted file mode 100644
index 2e03cc2e18..0000000000
--- a/lib/arel/nodes/greater_than.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class GreaterThan < Arel::Nodes::Binary
- end
- end
-end
diff --git a/lib/arel/nodes/greater_than_or_equal.rb b/lib/arel/nodes/greater_than_or_equal.rb
deleted file mode 100644
index a8cfaab04e..0000000000
--- a/lib/arel/nodes/greater_than_or_equal.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class GreaterThanOrEqual < Arel::Nodes::Binary
- end
- end
-end
diff --git a/lib/arel/nodes/group.rb b/lib/arel/nodes/group.rb
deleted file mode 100644
index a7fa6f170d..0000000000
--- a/lib/arel/nodes/group.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class Group < Arel::Nodes::Unary
- end
- end
-end
diff --git a/lib/arel/nodes/grouping.rb b/lib/arel/nodes/grouping.rb
deleted file mode 100644
index 18adeae97f..0000000000
--- a/lib/arel/nodes/grouping.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class Grouping < Arel::Nodes::Unary
- end
- end
-end
diff --git a/lib/arel/nodes/having.rb b/lib/arel/nodes/having.rb
deleted file mode 100644
index 6972c58dda..0000000000
--- a/lib/arel/nodes/having.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class Having < Arel::Nodes::Unary
- end
- end
-end
diff --git a/lib/arel/nodes/join.rb b/lib/arel/nodes/join.rb
deleted file mode 100644
index 07f8c98e85..0000000000
--- a/lib/arel/nodes/join.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-module Arel
- module Nodes
- class Join < Arel::Nodes::Node
- attr_accessor :left, :right, :constraint
-
- def initialize left, right, constraint
- @left = left
- @right = right
- @constraint = constraint
- end
- end
- end
-end
diff --git a/lib/arel/nodes/join_source.rb b/lib/arel/nodes/join_source.rb
new file mode 100644
index 0000000000..c57ad0e930
--- /dev/null
+++ b/lib/arel/nodes/join_source.rb
@@ -0,0 +1,14 @@
+module Arel
+ module Nodes
+ ###
+ # Class that represents a join source
+ #
+ # http://www.sqlite.org/syntaxdiagrams.html#join-source
+
+ class JoinSource < Arel::Nodes::Binary
+ def initialize single_source, joinop = []
+ super
+ end
+ end
+ end
+end
diff --git a/lib/arel/nodes/less_than.rb b/lib/arel/nodes/less_than.rb
deleted file mode 100644
index cfaf716c42..0000000000
--- a/lib/arel/nodes/less_than.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class LessThan < Arel::Nodes::Binary
- end
- end
-end
diff --git a/lib/arel/nodes/less_than_or_equal.rb b/lib/arel/nodes/less_than_or_equal.rb
deleted file mode 100644
index 55449d12f1..0000000000
--- a/lib/arel/nodes/less_than_or_equal.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class LessThanOrEqual < Arel::Nodes::Binary
- end
- end
-end
diff --git a/lib/arel/nodes/limit.rb b/lib/arel/nodes/limit.rb
deleted file mode 100644
index 68ea95daf5..0000000000
--- a/lib/arel/nodes/limit.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-module Arel
- module Nodes
- class Limit < Arel::Nodes::Unary
- end
- end
-end
-
diff --git a/lib/arel/nodes/matches.rb b/lib/arel/nodes/matches.rb
deleted file mode 100644
index 5ef8ac8302..0000000000
--- a/lib/arel/nodes/matches.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class Matches < Arel::Nodes::Binary
- end
- end
-end
diff --git a/lib/arel/nodes/max.rb b/lib/arel/nodes/max.rb
deleted file mode 100644
index 5af611b0d6..0000000000
--- a/lib/arel/nodes/max.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class Max < Arel::Nodes::Function
- end
- end
-end
diff --git a/lib/arel/nodes/min.rb b/lib/arel/nodes/min.rb
deleted file mode 100644
index bdc1371858..0000000000
--- a/lib/arel/nodes/min.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class Min < Arel::Nodes::Function
- end
- end
-end
diff --git a/lib/arel/nodes/node.rb b/lib/arel/nodes/node.rb
index 404ad22ece..711fa34b6d 100644
--- a/lib/arel/nodes/node.rb
+++ b/lib/arel/nodes/node.rb
@@ -3,6 +3,9 @@ module Arel
###
# Abstract base class for all AST nodes
class Node
+ include Arel::FactoryMethods
+ include Enumerable
+
###
# Factory method to create a Nodes::Not node that has the recipient of
# the caller as a child.
@@ -20,7 +23,7 @@ module Arel
###
# Factory method to create an Nodes::And node.
def and right
- Nodes::And.new self, right
+ Nodes::And.new [self, right]
end
# FIXME: this method should go away. I don't like people calling
diff --git a/lib/arel/nodes/not.rb b/lib/arel/nodes/not.rb
deleted file mode 100644
index de138435bb..0000000000
--- a/lib/arel/nodes/not.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class Not < Arel::Nodes::Unary
- end
- end
-end
diff --git a/lib/arel/nodes/not_equal.rb b/lib/arel/nodes/not_equal.rb
deleted file mode 100644
index 7f892940cb..0000000000
--- a/lib/arel/nodes/not_equal.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class NotEqual < Arel::Nodes::Binary
- end
- end
-end
diff --git a/lib/arel/nodes/not_in.rb b/lib/arel/nodes/not_in.rb
deleted file mode 100644
index 6c01921a46..0000000000
--- a/lib/arel/nodes/not_in.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class NotIn < Arel::Nodes::Binary
- end
- end
-end
diff --git a/lib/arel/nodes/offset.rb b/lib/arel/nodes/offset.rb
deleted file mode 100644
index d93e46aa1f..0000000000
--- a/lib/arel/nodes/offset.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-module Arel
- module Nodes
- class Offset < Arel::Nodes::Unary
- alias :value :expr
- end
- end
-end
diff --git a/lib/arel/nodes/on.rb b/lib/arel/nodes/on.rb
deleted file mode 100644
index 953d64f9f1..0000000000
--- a/lib/arel/nodes/on.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class On < Arel::Nodes::Unary
- end
- end
-end
diff --git a/lib/arel/nodes/or.rb b/lib/arel/nodes/or.rb
deleted file mode 100644
index bdf7f6d9b3..0000000000
--- a/lib/arel/nodes/or.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class Or < Arel::Nodes::Binary
- end
- end
-end
diff --git a/lib/arel/nodes/select_core.rb b/lib/arel/nodes/select_core.rb
index 501a2aaf7c..7f577e0a05 100644
--- a/lib/arel/nodes/select_core.rb
+++ b/lib/arel/nodes/select_core.rb
@@ -1,24 +1,35 @@
module Arel
module Nodes
class SelectCore < Arel::Nodes::Node
- attr_accessor :top, :froms, :projections, :wheres, :groups
- attr_accessor :having
+ attr_accessor :top, :projections, :wheres, :groups
+ attr_accessor :having, :source
def initialize
+ @source = JoinSource.new nil
@top = nil
- @froms = nil
@projections = []
@wheres = []
@groups = []
@having = nil
end
+ def from
+ @source.left
+ end
+
+ def from= value
+ @source.left = value
+ end
+
+ alias :froms= :from=
+ alias :froms :from
+
def initialize_copy other
super
- @froms = @froms.clone if @froms
+ @source = @source.clone if @source
@projections = @projections.clone
@wheres = @wheres.clone
- @group = @groups.clone
+ @groups = @groups.clone
@having = @having.clone if @having
end
end
diff --git a/lib/arel/nodes/select_statement.rb b/lib/arel/nodes/select_statement.rb
index 6881a66747..c9a0cde4e0 100644
--- a/lib/arel/nodes/select_statement.rb
+++ b/lib/arel/nodes/select_statement.rb
@@ -5,6 +5,7 @@ module Arel
attr_accessor :limit, :orders, :lock, :offset
def initialize cores = [SelectCore.new]
+ #puts caller
@cores = cores
@orders = []
@limit = nil
diff --git a/lib/arel/nodes/string_join.rb b/lib/arel/nodes/string_join.rb
index ea7912f92b..7fb0033c0f 100644
--- a/lib/arel/nodes/string_join.rb
+++ b/lib/arel/nodes/string_join.rb
@@ -1,10 +1,8 @@
module Arel
module Nodes
class StringJoin < Arel::Nodes::Join
- undef :constraint
-
- def initialize left, right
- super(left, right, nil)
+ def initialize left, right = nil
+ super
end
end
end
diff --git a/lib/arel/nodes/sum.rb b/lib/arel/nodes/sum.rb
deleted file mode 100644
index 3e043b7330..0000000000
--- a/lib/arel/nodes/sum.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class Sum < Arel::Nodes::Function
- end
- end
-end
diff --git a/lib/arel/nodes/table_alias.rb b/lib/arel/nodes/table_alias.rb
index 723b025883..4f4d5e29e9 100644
--- a/lib/arel/nodes/table_alias.rb
+++ b/lib/arel/nodes/table_alias.rb
@@ -6,7 +6,7 @@ module Arel
alias :table_alias :name
def [] name
- Attribute.new self, name
+ Attribute.new(self, name)
end
end
end
diff --git a/lib/arel/nodes/top.rb b/lib/arel/nodes/top.rb
deleted file mode 100644
index 56e2e97e8d..0000000000
--- a/lib/arel/nodes/top.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Arel
- module Nodes
- class Top < Arel::Nodes::Unary
- end
- end
-end
diff --git a/lib/arel/nodes/unary.rb b/lib/arel/nodes/unary.rb
index edda89e1f0..e1576b9c99 100644
--- a/lib/arel/nodes/unary.rb
+++ b/lib/arel/nodes/unary.rb
@@ -2,10 +2,24 @@ module Arel
module Nodes
class Unary < Arel::Nodes::Node
attr_accessor :expr
+ alias :value :expr
def initialize expr
@expr = expr
end
end
+
+ %w{
+ Group
+ Grouping
+ Having
+ Limit
+ Not
+ Offset
+ On
+ Top
+ }.each do |name|
+ const_set(name, Class.new(Unary))
+ end
end
end
diff --git a/lib/arel/nodes/unqualified_column.rb b/lib/arel/nodes/unqualified_column.rb
index f7ba653c11..2820dba9d2 100644
--- a/lib/arel/nodes/unqualified_column.rb
+++ b/lib/arel/nodes/unqualified_column.rb
@@ -4,6 +4,10 @@ module Arel
alias :attribute :expr
alias :attribute= :expr=
+ def relation
+ @expr.relation
+ end
+
def column
@expr.column
end
diff --git a/lib/arel/nodes/update_statement.rb b/lib/arel/nodes/update_statement.rb
index 288e9f4676..c08f1b2c5e 100644
--- a/lib/arel/nodes/update_statement.rb
+++ b/lib/arel/nodes/update_statement.rb
@@ -2,13 +2,15 @@ module Arel
module Nodes
class UpdateStatement < Arel::Nodes::Node
attr_accessor :relation, :wheres, :values, :orders, :limit
+ attr_accessor :key
def initialize
@relation = nil
@wheres = []
@values = []
- @orders = []
- @limit = nil
+ @orders = []
+ @limit = nil
+ @key = nil
end
def initialize_copy other
diff --git a/lib/arel/predications.rb b/lib/arel/predications.rb
index 23e68e99f1..58f02a2b53 100644
--- a/lib/arel/predications.rb
+++ b/lib/arel/predications.rb
@@ -36,9 +36,9 @@ module Arel
if other.exclude_end?
left = Nodes::GreaterThanOrEqual.new(self, other.begin)
right = Nodes::LessThan.new(self, other.end)
- Nodes::And.new left, right
+ Nodes::And.new [left, right]
else
- Nodes::Between.new(self, Nodes::And.new(other.begin, other.end))
+ Nodes::Between.new(self, Nodes::And.new([other.begin, other.end]))
end
else
Nodes::In.new self, other
@@ -174,7 +174,7 @@ module Arel
first = send method_id, others.shift
Nodes::Grouping.new others.inject(first) { |memo,expr|
- Nodes::And.new(memo, send(method_id, expr))
+ Nodes::And.new([memo, send(method_id, expr)])
}
end
end
diff --git a/lib/arel/select_manager.rb b/lib/arel/select_manager.rb
index cb656d5340..b4103144fe 100644
--- a/lib/arel/select_manager.rb
+++ b/lib/arel/select_manager.rb
@@ -9,9 +9,10 @@ module Arel
from table
end
- def taken
+ def limit
@ast.limit && @ast.limit.expr
end
+ alias :taken :limit
def constraints
@ctx.wheres
@@ -29,7 +30,9 @@ module Arel
end
def where_clauses
- #warn "where_clauses is deprecated" if $VERBOSE
+ if $VERBOSE
+ warn "(#{caller.first}) where_clauses is deprecated and will be removed in arel 3.0.0 with no replacement"
+ end
to_sql = Visitors::ToSql.new @engine
@ctx.wheres.map { |c| to_sql.accept c }
end
@@ -46,7 +49,7 @@ module Arel
end
def on *exprs
- @ctx.froms.constraint = Nodes::On.new(collapse(exprs))
+ @ctx.source.right.last.right = Nodes::On.new(collapse(exprs))
self
end
@@ -66,35 +69,36 @@ module Arel
# FIXME: this is a hack to support
# test_with_two_tables_in_from_without_getting_double_quoted
# from the AR tests.
- if @ctx.froms
- source = @ctx.froms
- if Nodes::SqlLiteral === table && Nodes::Join === source
- source.left = table
- table = source
- end
+ case table
+ when Nodes::SqlLiteral, Arel::Table
+ @ctx.source.left = table
+ when Nodes::Join
+ @ctx.source.right << table
end
- @ctx.froms = table
self
end
+ def froms
+ @ast.cores.map { |x| x.from }.compact
+ end
+
def join relation, klass = Nodes::InnerJoin
return self unless relation
case relation
when String, Nodes::SqlLiteral
raise if relation.blank?
- from Nodes::StringJoin.new(@ctx.froms, relation)
- else
- from klass.new(@ctx.froms, relation, nil)
+ klass = Nodes::StringJoin
end
- end
- def having expr
- expr = Nodes::SqlLiteral.new(expr) if String === expr
+ @ctx.source.right << create_join(relation, nil, klass)
+ self
+ end
- @ctx.having = Nodes::Having.new(expr)
+ def having *exprs
+ @ctx.having = Nodes::Having.new(collapse(exprs, @ctx.having))
self
end
@@ -137,10 +141,10 @@ module Arel
end
def join_sql
- return nil unless @ctx.froms
+ return nil if @ctx.source.right.empty?
- viz = Visitors::JoinSql.new @engine
- Nodes::SqlLiteral.new viz.accept @ctx
+ sql = @visitor.dup.extend(Visitors::JoinSql).accept @ctx
+ Nodes::SqlLiteral.new sql
end
def order_clauses
@@ -149,9 +153,13 @@ module Arel
}
end
+ def join_sources
+ @ctx.source.right
+ end
+
def joins manager
if $VERBOSE
- warn "joins is deprecated and will be removed in 2.2"
+ warn "joins is deprecated and will be removed in 3.0.0"
warn "please remove your call to joins from #{caller.first}"
end
manager.join_sql
@@ -177,13 +185,22 @@ module Arel
# FIXME: this method should go away
def insert values
- im = InsertManager.new @engine
+ if $VERBOSE
+ warn <<-eowarn
+insert (#{caller.first}) is deprecated and will be removed in ARel 3.0.0. Please
+switch to `compile_insert`
+ eowarn
+ end
+
+ im = compile_insert(values)
table = @ctx.froms
- primary_key_name = (primary_key = table.primary_key) && primary_key.name
+
+ primary_key = table.primary_key
+ primary_key_name = primary_key.name if primary_key
+
# FIXME: in AR tests values sometimes were Array and not Hash therefore is_a?(Hash) check is added
primary_key_value = primary_key && values.is_a?(Hash) && values[primary_key]
im.into table
- im.insert values
# Oracle adapter needs primary key name to generate RETURNING ... INTO ... clause
# for tables which assign primary key value using trigger.
# RETURNING ... INTO ... clause will be added only if primary_key_value is nil
@@ -192,18 +209,22 @@ module Arel
end
private
- def collapse exprs
- return exprs.first if exprs.length == 1
-
- right = exprs.pop
- left = exprs.pop
-
- right = Nodes::SqlLiteral.new(right) if String === right
-
- right = Nodes::And.new left, right
- exprs.reverse.inject(right) { |memo,expr|
- Nodes::And.new(expr, memo)
+ def collapse exprs, existing = nil
+ exprs = exprs.unshift(existing.expr) if existing
+ exprs = exprs.compact.map { |expr|
+ if String === expr
+ # FIXME: Don't do this automatically
+ Arel.sql(expr)
+ else
+ expr
+ end
}
+
+ if exprs.length == 1
+ exprs.first
+ else
+ create_and exprs
+ end
end
end
end
diff --git a/lib/arel/table.rb b/lib/arel/table.rb
index aa23a7d601..d1d1e40e11 100644
--- a/lib/arel/table.rb
+++ b/lib/arel/table.rb
@@ -1,6 +1,7 @@
module Arel
class Table
include Arel::Crud
+ include Arel::FactoryMethods
@engine = nil
class << self; attr_accessor :engine; end
@@ -17,7 +18,6 @@ module Arel
if Hash === engine
@engine = engine[:engine] || Table.engine
- @columns = attributes_for engine[:columns]
# Sometime AR sends an :as parameter to table, to let the table know
# that it is an Alias. We may want to override new, and return a
@@ -27,6 +27,11 @@ module Arel
end
def primary_key
+ if $VERBOSE
+ warn <<-eowarn
+primary_key (#{caller.first}) is deprecated and will be removed in ARel 3.0.0
+ eowarn
+ end
@primary_key ||= begin
primary_key_name = @engine.connection.primary_key(name)
# some tables might be without primary key
@@ -46,7 +51,7 @@ module Arel
def joins manager
if $VERBOSE
- warn "joins is deprecated and will be removed in 2.2"
+ warn "joins is deprecated and will be removed in 3.0.0"
warn "please remove your call to joins from #{caller.first}"
end
nil
@@ -58,10 +63,10 @@ module Arel
case relation
when String, Nodes::SqlLiteral
raise if relation.blank?
- from Nodes::StringJoin.new(self, relation)
- else
- from klass.new(self, relation, nil)
+ klass = Nodes::StringJoin
end
+
+ from(self).join(relation, klass)
end
def group *columns
@@ -93,41 +98,46 @@ module Arel
end
def columns
+ if $VERBOSE
+ warn <<-eowarn
+(#{caller.first}) Arel::Table#columns is deprecated and will be removed in
+Arel 3.0.0 with no replacement. PEW PEW PEW!!!
+ eowarn
+ end
@columns ||=
attributes_for @engine.connection.columns(@name, "#{@name} Columns")
end
def [] name
- return nil unless table_exists?
-
- name = name.to_sym
- columns.find { |column| column.name == name }
+ ::Arel::Attribute.new self, name
end
def select_manager
SelectManager.new(@engine)
end
+ def insert_manager
+ InsertManager.new(@engine)
+ end
+
private
def attributes_for columns
return nil unless columns
columns.map do |column|
- Attributes.for(column).new self, column.name.to_sym, column
+ Attributes.for(column).new self, column.name.to_sym
end
end
- def table_exists?
- @table_exists ||= tables.key?(@name) || engine.connection.table_exists?(name)
- end
-
- def tables
- self.class.table_cache(@engine)
- end
-
@@table_cache = nil
def self.table_cache engine # :nodoc:
+ if $VERBOSE
+ warn <<-eowarn
+(#{caller.first}) Arel::Table.table_cache is deprecated and will be removed in
+Arel 3.0.0 with no replacement. PEW PEW PEW!!!
+ eowarn
+ end
@@table_cache ||= Hash[engine.connection.tables.map { |x| [x,true] }]
end
end
diff --git a/lib/arel/tree_manager.rb b/lib/arel/tree_manager.rb
index 2fa770a0e3..5722baca77 100644
--- a/lib/arel/tree_manager.rb
+++ b/lib/arel/tree_manager.rb
@@ -2,6 +2,7 @@ module Arel
class TreeManager
# FIXME: Remove this.
include Arel::Relation
+ include Arel::FactoryMethods
attr_accessor :visitor
attr_reader :ast, :engine
diff --git a/lib/arel/update_manager.rb b/lib/arel/update_manager.rb
index d92c8b9a03..f13aeb0a8c 100644
--- a/lib/arel/update_manager.rb
+++ b/lib/arel/update_manager.rb
@@ -11,6 +11,10 @@ module Arel
self
end
+ def key= key
+ @ast.key = key
+ end
+
def order *expr
@ast.orders = expr
self
diff --git a/lib/arel/visitors/depth_first.rb b/lib/arel/visitors/depth_first.rb
index 00f18727f0..ed95cad472 100644
--- a/lib/arel/visitors/depth_first.rb
+++ b/lib/arel/visitors/depth_first.rb
@@ -18,9 +18,11 @@ module Arel
alias :visit_Arel_Nodes_Group :unary
alias :visit_Arel_Nodes_Grouping :unary
alias :visit_Arel_Nodes_Having :unary
+ alias :visit_Arel_Nodes_Limit :unary
alias :visit_Arel_Nodes_Not :unary
alias :visit_Arel_Nodes_Offset :unary
alias :visit_Arel_Nodes_On :unary
+ alias :visit_Arel_Nodes_Top :unary
alias :visit_Arel_Nodes_UnqualifiedColumn :unary
def function o
@@ -39,19 +41,15 @@ module Arel
visit o.distinct
end
- def join o
- visit o.left
- visit o.right
- visit o.constraint
+ def nary o
+ o.children.each { |child| visit child }
end
- alias :visit_Arel_Nodes_InnerJoin :join
- alias :visit_Arel_Nodes_OuterJoin :join
+ alias :visit_Arel_Nodes_And :nary
def binary o
visit o.left
visit o.right
end
- alias :visit_Arel_Nodes_And :binary
alias :visit_Arel_Nodes_As :binary
alias :visit_Arel_Nodes_Assignment :binary
alias :visit_Arel_Nodes_Between :binary
@@ -61,6 +59,8 @@ module Arel
alias :visit_Arel_Nodes_GreaterThan :binary
alias :visit_Arel_Nodes_GreaterThanOrEqual :binary
alias :visit_Arel_Nodes_In :binary
+ alias :visit_Arel_Nodes_JoinSource :binary
+ alias :visit_Arel_Nodes_InnerJoin :binary
alias :visit_Arel_Nodes_LessThan :binary
alias :visit_Arel_Nodes_LessThanOrEqual :binary
alias :visit_Arel_Nodes_Matches :binary
@@ -68,10 +68,14 @@ module Arel
alias :visit_Arel_Nodes_NotIn :binary
alias :visit_Arel_Nodes_Or :binary
alias :visit_Arel_Nodes_Ordering :binary
- alias :visit_Arel_Nodes_StringJoin :binary
+ alias :visit_Arel_Nodes_OuterJoin :binary
alias :visit_Arel_Nodes_TableAlias :binary
alias :visit_Arel_Nodes_Values :binary
+ def visit_Arel_Nodes_StringJoin o
+ visit o.left
+ end
+
def visit_Arel_Attribute o
visit o.relation
visit o.name
@@ -118,7 +122,7 @@ module Arel
def visit_Arel_Nodes_SelectCore o
visit o.projections
- visit o.froms
+ visit o.source
visit o.wheres
visit o.groups
visit o.having
diff --git a/lib/arel/visitors/dot.rb b/lib/arel/visitors/dot.rb
index eab5e4afdc..3c4fe12d1f 100644
--- a/lib/arel/visitors/dot.rb
+++ b/lib/arel/visitors/dot.rb
@@ -36,7 +36,6 @@ module Arel
def visit_Arel_Nodes_TableAlias o
visit_edge o, "name"
visit_edge o, "relation"
- visit_edge o, "columns"
end
def visit_Arel_Nodes_Sum o
@@ -57,13 +56,11 @@ module Arel
def visit_Arel_Nodes_StringJoin o
visit_edge o, "left"
- visit_edge o, "right"
end
def visit_Arel_Nodes_InnerJoin o
visit_edge o, "left"
visit_edge o, "right"
- visit_edge o, "constraint"
end
alias :visit_Arel_Nodes_OuterJoin :visit_Arel_Nodes_InnerJoin
@@ -78,9 +75,11 @@ module Arel
alias :visit_Arel_Nodes_Group :unary
alias :visit_Arel_Nodes_Grouping :unary
alias :visit_Arel_Nodes_Having :unary
+ alias :visit_Arel_Nodes_Limit :unary
alias :visit_Arel_Nodes_Not :unary
alias :visit_Arel_Nodes_Offset :unary
alias :visit_Arel_Nodes_On :unary
+ alias :visit_Arel_Nodes_Top :unary
alias :visit_Arel_Nodes_UnqualifiedColumn :unary
def visit_Arel_Nodes_InsertStatement o
@@ -90,7 +89,7 @@ module Arel
end
def visit_Arel_Nodes_SelectCore o
- visit_edge o, "froms"
+ visit_edge o, "source"
visit_edge o, "projections"
visit_edge o, "wheres"
end
@@ -123,23 +122,32 @@ module Arel
alias :visit_Arel_Attributes_Boolean :visit_Arel_Attribute
alias :visit_Arel_Attributes_Attribute :visit_Arel_Attribute
- def visit_Arel_Nodes_Equality o
+ def nary o
+ o.children.each_with_index do |x,i|
+ edge(i) { visit x }
+ end
+ end
+ alias :visit_Arel_Nodes_And :nary
+
+ def binary o
visit_edge o, "left"
visit_edge o, "right"
end
- alias :visit_Arel_Nodes_And :visit_Arel_Nodes_Equality
- alias :visit_Arel_Nodes_Or :visit_Arel_Nodes_Equality
- alias :visit_Arel_Nodes_NotEqual :visit_Arel_Nodes_Equality
- alias :visit_Arel_Nodes_GreaterThan :visit_Arel_Nodes_Equality
- alias :visit_Arel_Nodes_GreaterThanOrEqual :visit_Arel_Nodes_Equality
- alias :visit_Arel_Nodes_Assignment :visit_Arel_Nodes_Equality
- alias :visit_Arel_Nodes_In :visit_Arel_Nodes_Equality
- alias :visit_Arel_Nodes_LessThan :visit_Arel_Nodes_Equality
- alias :visit_Arel_Nodes_LessThanOrEqual :visit_Arel_Nodes_Equality
- alias :visit_Arel_Nodes_Between :visit_Arel_Nodes_Equality
- alias :visit_Arel_Nodes_NotIn :visit_Arel_Nodes_Equality
- alias :visit_Arel_Nodes_DoesNotMatch :visit_Arel_Nodes_Equality
- alias :visit_Arel_Nodes_Matches :visit_Arel_Nodes_Equality
+ alias :visit_Arel_Nodes_As :binary
+ alias :visit_Arel_Nodes_Assignment :binary
+ alias :visit_Arel_Nodes_Between :binary
+ alias :visit_Arel_Nodes_DoesNotMatch :binary
+ alias :visit_Arel_Nodes_Equality :binary
+ alias :visit_Arel_Nodes_GreaterThan :binary
+ alias :visit_Arel_Nodes_GreaterThanOrEqual :binary
+ alias :visit_Arel_Nodes_In :binary
+ alias :visit_Arel_Nodes_JoinSource :binary
+ alias :visit_Arel_Nodes_LessThan :binary
+ alias :visit_Arel_Nodes_LessThanOrEqual :binary
+ alias :visit_Arel_Nodes_Matches :binary
+ alias :visit_Arel_Nodes_NotEqual :binary
+ alias :visit_Arel_Nodes_NotIn :binary
+ alias :visit_Arel_Nodes_Or :binary
def visit_String o
@node_stack.last.fields << o
diff --git a/lib/arel/visitors/join_sql.rb b/lib/arel/visitors/join_sql.rb
index d3fb18d3c6..1cdd7eb5ca 100644
--- a/lib/arel/visitors/join_sql.rb
+++ b/lib/arel/visitors/join_sql.rb
@@ -8,32 +8,11 @@ module Arel
#
# This visitor is used in SelectManager#join_sql and is for backwards
# compatibility with Arel V1.0
- class JoinSql < Arel::Visitors::ToSql
+ module JoinSql
private
def visit_Arel_Nodes_SelectCore o
- [o.froms].grep(Nodes::Join).map { |x| visit x }.join ', '
- end
-
- def visit_Arel_Nodes_StringJoin o
- [
- (visit o.left if Nodes::Join === o.left),
- visit(o.right)
- ].compact.join ' '
- end
-
- def visit_Arel_Nodes_OuterJoin o
- [
- (visit o.left if Nodes::Join === o.left),
- "LEFT OUTER JOIN #{visit o.right} #{visit o.constraint if o.constraint}"
- ].compact.join ' '
- end
-
- def visit_Arel_Nodes_InnerJoin o
- [
- (visit o.left if Nodes::Join === o.left),
- "INNER JOIN #{visit o.right} #{visit o.constraint if o.constraint}"
- ].compact.join ' '
+ o.source.right.map { |j| visit j }.join ' '
end
end
end
diff --git a/lib/arel/visitors/oracle.rb b/lib/arel/visitors/oracle.rb
index 3c8c816feb..aaf0324fd7 100644
--- a/lib/arel/visitors/oracle.rb
+++ b/lib/arel/visitors/oracle.rb
@@ -25,7 +25,7 @@ module Arel
SELECT * FROM (
SELECT raw_sql_.*, rownum raw_rnum_
FROM (#{sql}) raw_sql_
- WHERE rownum <= #{offset.value.to_i + limit}
+ WHERE rownum <= #{offset.expr.to_i + limit}
)
WHERE #{visit offset}
eosql
@@ -58,7 +58,7 @@ module Arel
end
def visit_Arel_Nodes_Offset o
- "raw_rnum_ > #{visit o.value}"
+ "raw_rnum_ > #{visit o.expr}"
end
###
diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb
index 7435e41561..4eae5a9ae5 100644
--- a/lib/arel/visitors/to_sql.rb
+++ b/lib/arel/visitors/to_sql.rb
@@ -7,14 +7,24 @@ module Arel
def initialize engine
@engine = engine
@connection = nil
+ @pool = nil
@last_column = nil
@quoted_tables = {}
@quoted_columns = {}
+ @column_cache = Hash.new { |h,pool|
+ h[pool] = Hash.new { |conn_h,column|
+ conn_h[column] = {}
+ }
+ }
+ @table_exists = Hash.new { |h,pool|
+ h[pool] = {}
+ }
end
def accept object
@last_column = nil
- @engine.connection_pool.with_connection do |conn|
+ @pool = @engine.connection_pool
+ @pool.with_connection do |conn|
@connection = conn
super
end
@@ -32,20 +42,31 @@ module Arel
if o.orders.empty? && o.limit.nil?
wheres = o.wheres
else
+ key = o.key
+ unless key
+ warn(<<-eowarn) if $VERBOSE
+(#{caller.first}) Using UpdateManager without setting UpdateManager#key is
+deprecated and support will be removed in ARel 3.0.0. Please set the primary
+key on UpdateManager using UpdateManager#key=
+eowarn
+ key = o.relation.primary_key
+ end
+
+ wheres = o.wheres
stmt = Nodes::SelectStatement.new
core = stmt.cores.first
core.froms = o.relation
- core.projections = [o.relation.primary_key]
+ core.projections = [key]
stmt.limit = o.limit
stmt.orders = o.orders
- wheres = [Nodes::In.new(o.relation.primary_key, [stmt])]
+ wheres = [Nodes::In.new(key, [stmt])]
end
[
"UPDATE #{visit o.relation}",
("SET #{o.values.map { |value| visit value }.join ', '}" unless o.values.empty?),
- ("WHERE #{wheres.map { |x| visit x }.join ' AND '}" unless wheres.empty?)
+ ("WHERE #{wheres.map { |x| visit x }.join ' AND '}" unless wheres.empty?),
].compact.join ' '
end
@@ -62,13 +83,47 @@ module Arel
end
def visit_Arel_Nodes_Exists o
- "EXISTS (#{visit o.select_stmt})#{
+ "EXISTS (#{visit o.expressions})#{
o.alias ? " AS #{visit o.alias}" : ''}"
end
+ def table_exists? name
+ return true if table_exists.key? name
+
+ @connection.tables.each do |table|
+ table_exists[table] = true
+ end
+
+ table_exists.key? name
+ end
+
+ def table_exists
+ @table_exists[@pool]
+ end
+
+ def column_for attr
+ name = attr.name.to_sym
+ table = attr.relation.name
+
+ return nil unless table_exists? table
+
+ # If we don't have this column cached, get a list of columns and
+ # cache them for this table
+ unless column_cache.key? table
+ columns = @connection.columns(table, "#{table}(#{name}) Columns")
+ column_cache[table] = Hash[columns.map { |c| [c.name.to_sym, c] }]
+ end
+
+ column_cache[table][name]
+ end
+
+ def column_cache
+ @column_cache[@pool]
+ end
+
def visit_Arel_Nodes_Values o
- "VALUES (#{o.expressions.zip(o.columns).map { |value, column|
- quote(value, column && column.column)
+ "VALUES (#{o.expressions.zip(o.columns).map { |value, attr|
+ quote(value, attr && column_for(attr))
}.join ', '})"
end
@@ -87,7 +142,7 @@ module Arel
"SELECT",
(visit(o.top) if o.top),
"#{o.projections.map { |x| visit x }.join ', '}",
- ("FROM #{visit o.froms}" if o.froms),
+ visit(o.source),
("WHERE #{o.wheres.map { |x| visit x }.join ' AND ' }" unless o.wheres.empty?),
("GROUP BY #{o.groups.map { |x| visit x }.join ', ' }" unless o.groups.empty?),
(visit(o.having) if o.having),
@@ -186,16 +241,26 @@ module Arel
"#{visit o.left} NOT LIKE #{visit o.right}"
end
+ def visit_Arel_Nodes_JoinSource o
+ return unless o.left || !o.right.empty?
+
+ [
+ "FROM",
+ (visit(o.left) if o.left),
+ o.right.map { |j| visit j }.join(' ')
+ ].compact.join ' '
+ end
+
def visit_Arel_Nodes_StringJoin o
- "#{visit o.left} #{visit o.right}"
+ visit o.left
end
def visit_Arel_Nodes_OuterJoin o
- "#{visit o.left} LEFT OUTER JOIN #{visit o.right} #{visit o.constraint}"
+ "LEFT OUTER JOIN #{visit o.left} #{visit o.right}"
end
def visit_Arel_Nodes_InnerJoin o
- "#{visit o.left} INNER JOIN #{visit o.right} #{visit o.constraint if o.constraint}"
+ "INNER JOIN #{visit o.left} #{visit o.right if o.right}"
end
def visit_Arel_Nodes_On o
@@ -223,7 +288,7 @@ module Arel
end
def visit_Arel_Nodes_And o
- "#{visit o.left} AND #{visit o.right}"
+ o.children.map { |x| visit x }.join ' AND '
end
def visit_Arel_Nodes_Or o
@@ -231,7 +296,7 @@ module Arel
end
def visit_Arel_Nodes_Assignment o
- right = quote(o.right, o.left.column)
+ right = quote(o.right, column_for(o.left))
"#{visit o.left} = #{right}"
end
@@ -264,7 +329,7 @@ module Arel
end
def visit_Arel_Attributes_Attribute o
- @last_column = o.column
+ @last_column = column_for o
join_name = o.relation.table_alias || o.relation.name
"#{quote_table_name join_name}.#{quote_column_name o.name}"
end
@@ -275,26 +340,29 @@ module Arel
alias :visit_Arel_Attributes_Time :visit_Arel_Attributes_Attribute
alias :visit_Arel_Attributes_Boolean :visit_Arel_Attributes_Attribute
- def visit_Fixnum o; o end
- alias :visit_Arel_Nodes_SqlLiteral :visit_Fixnum
- alias :visit_Arel_SqlLiteral :visit_Fixnum # This is deprecated
- alias :visit_Bignum :visit_Fixnum
-
- def visit_String o; quote(o, @last_column) end
-
- alias :visit_ActiveSupport_Multibyte_Chars :visit_String
- alias :visit_BigDecimal :visit_String
- alias :visit_Date :visit_String
- alias :visit_DateTime :visit_String
- alias :visit_FalseClass :visit_String
- alias :visit_Float :visit_String
- alias :visit_Hash :visit_String
- alias :visit_Symbol :visit_String
- alias :visit_Time :visit_String
- alias :visit_TrueClass :visit_String
- alias :visit_NilClass :visit_String
- alias :visit_ActiveSupport_StringInquirer :visit_String
- alias :visit_Class :visit_String
+ def literal o; o end
+
+ alias :visit_Arel_Nodes_SqlLiteral :literal
+ alias :visit_Arel_SqlLiteral :literal # This is deprecated
+ alias :visit_Bignum :literal
+ alias :visit_Fixnum :literal
+
+ def quoted o; quote(o, @last_column) 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 visit_Array o
o.empty? ? 'NULL' : o.map { |x| visit x }.join(', ')
@@ -309,7 +377,7 @@ module Arel
end
def quote_column_name name
- @quoted_columns[name] ||= @connection.quote_column_name(name)
+ @quoted_columns[name] ||= Arel::Nodes::SqlLiteral === name ? name : @connection.quote_column_name(name)
end
end
end