aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Manifest.txt1
-rw-r--r--README.markdown21
-rw-r--r--arel.gemspec23
-rw-r--r--lib/arel.rb2
-rw-r--r--lib/arel/collectors/plain_string.rb18
-rw-r--r--lib/arel/collectors/sql_string.rb17
-rw-r--r--lib/arel/expressions.rb9
-rw-r--r--lib/arel/nodes.rb2
-rw-r--r--lib/arel/nodes/and.rb6
-rw-r--r--lib/arel/nodes/window.rb27
-rw-r--r--lib/arel/predications.rb40
-rw-r--r--lib/arel/select_manager.rb2
-rw-r--r--lib/arel/table.rb2
-rw-r--r--lib/arel/tree_manager.rb4
-rw-r--r--lib/arel/visitors/bind_substitute.rb2
-rw-r--r--lib/arel/visitors/dot.rb6
-rw-r--r--lib/arel/visitors/to_sql.rb17
-rw-r--r--test/attributes/test_attribute.rb30
-rw-r--r--test/collectors/test_bind_collector.rb2
-rw-r--r--test/nodes/test_infix_operation.rb2
-rw-r--r--test/nodes/test_window.rb12
-rw-r--r--test/test_insert_manager.rb11
-rw-r--r--test/test_select_manager.rb160
-rw-r--r--test/visitors/test_dot.rb8
-rw-r--r--test/visitors/test_to_sql.rb5
25 files changed, 273 insertions, 156 deletions
diff --git a/Manifest.txt b/Manifest.txt
index 3892cd3b2a..32e1dd43a6 100644
--- a/Manifest.txt
+++ b/Manifest.txt
@@ -13,6 +13,7 @@ lib/arel/alias_predication.rb
lib/arel/attributes.rb
lib/arel/attributes/attribute.rb
lib/arel/collectors/bind.rb
+lib/arel/collectors/plain_string.rb
lib/arel/collectors/sql_string.rb
lib/arel/compatibility/wheres.rb
lib/arel/crud.rb
diff --git a/README.markdown b/README.markdown
index 75b0b3ee0b..1776330da8 100644
--- a/README.markdown
+++ b/README.markdown
@@ -120,10 +120,10 @@ Aggregate functions `AVG`, `SUM`, `COUNT`, `MIN`, `MAX`, `HAVING`:
```ruby
photos.group(photos[:user_id]).having(photos[:id].count.gt(5)) # => SELECT FROM photos GROUP BY photos.user_id HAVING COUNT(photos.id) > 5
-users.project(users[:age].sum) # => SELECT SUM(users.age) AS sum_id FROM users
-users.project(users[:age].average) # => SELECT AVG(users.age) AS avg_id FROM users
-users.project(users[:age].maximum) # => SELECT MAX(users.age) AS max_id FROM users
-users.project(users[:age].minimum) # => SELECT MIN(users.age) AS min_id FROM users
+users.project(users[:age].sum) # => SELECT SUM(users.age) FROM users
+users.project(users[:age].average) # => SELECT AVG(users.age) FROM users
+users.project(users[:age].maximum) # => SELECT MAX(users.age) FROM users
+users.project(users[:age].minimum) # => SELECT MIN(users.age) FROM users
users.project(users[:age].count) # => SELECT COUNT(users.age) FROM users
```
@@ -160,7 +160,7 @@ products.
#### Complex Joins
-Where Arel really shines in its ability to handle complex joins and aggregations. As a first example, let's consider an "adjacency list", a tree represented in a table. Suppose we have a table `comments`, representing a threaded discussion:
+Where Arel really shines is in its ability to handle complex joins and aggregations. As a first example, let's consider an "adjacency list", a tree represented in a table. Suppose we have a table `comments`, representing a threaded discussion:
```ruby
comments = Arel::Table.new(:comments)
@@ -172,16 +172,17 @@ And this table has the following attributes:
# [:id, :body, :parent_id]
```
-The `parent_id` column is a foreign key from the `comments` table to itself. Now, joining a table to itself requires aliasing in SQL. In fact, you may alias in Arel as well:
+The `parent_id` column is a foreign key from the `comments` table to itself.
+Joining a table to itself requires aliasing in SQL. This aliasing can be handled from Arel as below:
```ruby
replies = comments.alias
comments_with_replies = \
- comments.join(replies).on(replies[:parent_id].eq(comments[:id]))
-# => SELECT * FROM comments INNER JOIN comments AS comments_2 WHERE comments_2.parent_id = comments.id
+ comments.join(replies).on(replies[:parent_id].eq(comments[:id])).where(comments[:id].eq(1))
+# => SELECT * FROM comments INNER JOIN comments AS comments_2 WHERE comments_2.parent_id = comments.id AND comments.id = 1
```
-This will return the first comment's reply's body.
+This will return the reply for the first comment.
[Common Table Expresssions(CTE)](https://en.wikipedia.org/wiki/Common_table_expressions#Common_table_expression) support via:
@@ -200,7 +201,7 @@ users.
project(users[:id], cte_table[:click].sum).
with(composed_cte)
-# => WITH cte_table AS (SELECT FROM photos WHERE photos.created_at > '2014-05-02') SELECT users.id, SUM(cte_table.click) AS sum_id FROM users INNER JOIN cte_table ON users.id = cte_table.user_id
+# => WITH cte_table AS (SELECT FROM photos WHERE photos.created_at > '2014-05-02') SELECT users.id, SUM(cte_table.click) FROM users INNER JOIN cte_table ON users.id = cte_table.user_id
```
When your query is too complex for `Arel`, you can use `Arel::SqlLiteral`:
diff --git a/arel.gemspec b/arel.gemspec
index e6fe10a4bf..832eb12f49 100644
--- a/arel.gemspec
+++ b/arel.gemspec
@@ -1,22 +1,21 @@
# -*- encoding: utf-8 -*-
-# stub: arel 6.0.0.20140505020427 ruby lib
+# stub: arel 6.0.0.beta1.20140817224534 ruby lib
Gem::Specification.new do |s|
s.name = "arel"
- s.version = "6.0.0.20140505020427"
+ s.version = "6.0.0.beta1.20140817224534"
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib"]
s.authors = ["Aaron Patterson", "Bryan Helmkamp", "Emilio Tagua", "Nick Kallen"]
- s.date = "2014-05-05"
+ s.date = "2014-08-18"
s.description = "Arel Really Exasperates Logicians\n\nArel is a SQL AST manager for Ruby. It\n\n1. Simplifies the generation of complex SQL queries\n2. Adapts to various RDBMSes\n\nIt is intended to be a framework framework; that is, you can build your own ORM\nwith it, focusing on innovative object and collection modeling as opposed to\ndatabase compatibility and query generation."
s.email = ["aaron@tenderlovemaking.com", "bryan@brynary.com", "miloops@gmail.com", "nick@example.org"]
s.extra_rdoc_files = ["History.txt", "MIT-LICENSE.txt", "Manifest.txt", "README.markdown"]
- s.files = [".autotest", ".gemtest", ".travis.yml", "Gemfile", "History.txt", "MIT-LICENSE.txt", "Manifest.txt", "README.markdown", "Rakefile", "arel.gemspec", "lib/arel.rb", "lib/arel/alias_predication.rb", "lib/arel/attributes.rb", "lib/arel/attributes/attribute.rb", "lib/arel/collectors/bind.rb", "lib/arel/collectors/sql_string.rb", "lib/arel/compatibility/wheres.rb", "lib/arel/crud.rb", "lib/arel/delete_manager.rb", "lib/arel/expressions.rb", "lib/arel/factory_methods.rb", "lib/arel/insert_manager.rb", "lib/arel/math.rb", "lib/arel/nodes.rb", "lib/arel/nodes/and.rb", "lib/arel/nodes/ascending.rb", "lib/arel/nodes/binary.rb", "lib/arel/nodes/count.rb", "lib/arel/nodes/delete_statement.rb", "lib/arel/nodes/descending.rb", "lib/arel/nodes/equality.rb", "lib/arel/nodes/extract.rb", "lib/arel/nodes/false.rb", "lib/arel/nodes/full_outer_join.rb", "lib/arel/nodes/function.rb", "lib/arel/nodes/grouping.rb", "lib/arel/nodes/in.rb", "lib/arel/nodes/infix_operation.rb", "lib/arel/nodes/inner_join.rb", "lib/arel/nodes/insert_statement.rb", "lib/arel/nodes/join_source.rb", "lib/arel/nodes/named_function.rb", "lib/arel/nodes/node.rb", "lib/arel/nodes/outer_join.rb", "lib/arel/nodes/over.rb", "lib/arel/nodes/right_outer_join.rb", "lib/arel/nodes/select_core.rb", "lib/arel/nodes/select_statement.rb", "lib/arel/nodes/sql_literal.rb", "lib/arel/nodes/string_join.rb", "lib/arel/nodes/table_alias.rb", "lib/arel/nodes/terminal.rb", "lib/arel/nodes/true.rb", "lib/arel/nodes/unary.rb", "lib/arel/nodes/unqualified_column.rb", "lib/arel/nodes/update_statement.rb", "lib/arel/nodes/values.rb", "lib/arel/nodes/window.rb", "lib/arel/nodes/with.rb", "lib/arel/order_predications.rb", "lib/arel/predications.rb", "lib/arel/select_manager.rb", "lib/arel/table.rb", "lib/arel/tree_manager.rb", "lib/arel/update_manager.rb", "lib/arel/visitors.rb", "lib/arel/visitors/bind_substitute.rb", "lib/arel/visitors/bind_visitor.rb", "lib/arel/visitors/depth_first.rb", "lib/arel/visitors/dot.rb", "lib/arel/visitors/ibm_db.rb", "lib/arel/visitors/informix.rb", "lib/arel/visitors/mssql.rb", "lib/arel/visitors/mysql.rb", "lib/arel/visitors/oracle.rb", "lib/arel/visitors/postgresql.rb", "lib/arel/visitors/reduce.rb", "lib/arel/visitors/sqlite.rb", "lib/arel/visitors/to_sql.rb", "lib/arel/visitors/visitor.rb", "lib/arel/visitors/where_sql.rb", "lib/arel/window_predications.rb", "test/attributes/test_attribute.rb", "test/collectors/test_bind_collector.rb", "test/collectors/test_sql_string.rb", "test/helper.rb", "test/nodes/test_and.rb", "test/nodes/test_as.rb", "test/nodes/test_ascending.rb", "test/nodes/test_bin.rb", "test/nodes/test_count.rb", "test/nodes/test_delete_statement.rb", "test/nodes/test_descending.rb", "test/nodes/test_distinct.rb", "test/nodes/test_equality.rb", "test/nodes/test_extract.rb", "test/nodes/test_false.rb", "test/nodes/test_grouping.rb", "test/nodes/test_infix_operation.rb", "test/nodes/test_insert_statement.rb", "test/nodes/test_named_function.rb", "test/nodes/test_node.rb", "test/nodes/test_not.rb", "test/nodes/test_or.rb", "test/nodes/test_over.rb", "test/nodes/test_select_core.rb", "test/nodes/test_select_statement.rb", "test/nodes/test_sql_literal.rb", "test/nodes/test_sum.rb", "test/nodes/test_table_alias.rb", "test/nodes/test_true.rb", "test/nodes/test_update_statement.rb", "test/nodes/test_window.rb", "test/support/fake_record.rb", "test/test_attributes.rb", "test/test_crud.rb", "test/test_delete_manager.rb", "test/test_factory_methods.rb", "test/test_insert_manager.rb", "test/test_select_manager.rb", "test/test_table.rb", "test/test_update_manager.rb", "test/visitors/test_bind_visitor.rb", "test/visitors/test_depth_first.rb", "test/visitors/test_dispatch_contamination.rb", "test/visitors/test_dot.rb", "test/visitors/test_ibm_db.rb", "test/visitors/test_informix.rb", "test/visitors/test_mssql.rb", "test/visitors/test_mysql.rb", "test/visitors/test_oracle.rb", "test/visitors/test_postgres.rb", "test/visitors/test_sqlite.rb", "test/visitors/test_to_sql.rb"]
+ s.files = [".autotest", ".gemtest", ".travis.yml", "Gemfile", "History.txt", "MIT-LICENSE.txt", "Manifest.txt", "README.markdown", "Rakefile", "arel.gemspec", "lib/arel.rb", "lib/arel/alias_predication.rb", "lib/arel/attributes.rb", "lib/arel/attributes/attribute.rb", "lib/arel/collectors/bind.rb", "lib/arel/collectors/plain_string.rb", "lib/arel/collectors/sql_string.rb", "lib/arel/compatibility/wheres.rb", "lib/arel/crud.rb", "lib/arel/delete_manager.rb", "lib/arel/expressions.rb", "lib/arel/factory_methods.rb", "lib/arel/insert_manager.rb", "lib/arel/math.rb", "lib/arel/nodes.rb", "lib/arel/nodes/and.rb", "lib/arel/nodes/ascending.rb", "lib/arel/nodes/binary.rb", "lib/arel/nodes/count.rb", "lib/arel/nodes/delete_statement.rb", "lib/arel/nodes/descending.rb", "lib/arel/nodes/equality.rb", "lib/arel/nodes/extract.rb", "lib/arel/nodes/false.rb", "lib/arel/nodes/full_outer_join.rb", "lib/arel/nodes/function.rb", "lib/arel/nodes/grouping.rb", "lib/arel/nodes/in.rb", "lib/arel/nodes/infix_operation.rb", "lib/arel/nodes/inner_join.rb", "lib/arel/nodes/insert_statement.rb", "lib/arel/nodes/join_source.rb", "lib/arel/nodes/named_function.rb", "lib/arel/nodes/node.rb", "lib/arel/nodes/outer_join.rb", "lib/arel/nodes/over.rb", "lib/arel/nodes/right_outer_join.rb", "lib/arel/nodes/select_core.rb", "lib/arel/nodes/select_statement.rb", "lib/arel/nodes/sql_literal.rb", "lib/arel/nodes/string_join.rb", "lib/arel/nodes/table_alias.rb", "lib/arel/nodes/terminal.rb", "lib/arel/nodes/true.rb", "lib/arel/nodes/unary.rb", "lib/arel/nodes/unqualified_column.rb", "lib/arel/nodes/update_statement.rb", "lib/arel/nodes/values.rb", "lib/arel/nodes/window.rb", "lib/arel/nodes/with.rb", "lib/arel/order_predications.rb", "lib/arel/predications.rb", "lib/arel/select_manager.rb", "lib/arel/table.rb", "lib/arel/tree_manager.rb", "lib/arel/update_manager.rb", "lib/arel/visitors.rb", "lib/arel/visitors/bind_substitute.rb", "lib/arel/visitors/bind_visitor.rb", "lib/arel/visitors/depth_first.rb", "lib/arel/visitors/dot.rb", "lib/arel/visitors/ibm_db.rb", "lib/arel/visitors/informix.rb", "lib/arel/visitors/mssql.rb", "lib/arel/visitors/mysql.rb", "lib/arel/visitors/oracle.rb", "lib/arel/visitors/postgresql.rb", "lib/arel/visitors/reduce.rb", "lib/arel/visitors/sqlite.rb", "lib/arel/visitors/to_sql.rb", "lib/arel/visitors/visitor.rb", "lib/arel/visitors/where_sql.rb", "lib/arel/window_predications.rb", "test/attributes/test_attribute.rb", "test/collectors/test_bind_collector.rb", "test/collectors/test_sql_string.rb", "test/helper.rb", "test/nodes/test_and.rb", "test/nodes/test_as.rb", "test/nodes/test_ascending.rb", "test/nodes/test_bin.rb", "test/nodes/test_count.rb", "test/nodes/test_delete_statement.rb", "test/nodes/test_descending.rb", "test/nodes/test_distinct.rb", "test/nodes/test_equality.rb", "test/nodes/test_extract.rb", "test/nodes/test_false.rb", "test/nodes/test_grouping.rb", "test/nodes/test_infix_operation.rb", "test/nodes/test_insert_statement.rb", "test/nodes/test_named_function.rb", "test/nodes/test_node.rb", "test/nodes/test_not.rb", "test/nodes/test_or.rb", "test/nodes/test_over.rb", "test/nodes/test_select_core.rb", "test/nodes/test_select_statement.rb", "test/nodes/test_sql_literal.rb", "test/nodes/test_sum.rb", "test/nodes/test_table_alias.rb", "test/nodes/test_true.rb", "test/nodes/test_update_statement.rb", "test/nodes/test_window.rb", "test/support/fake_record.rb", "test/test_attributes.rb", "test/test_crud.rb", "test/test_delete_manager.rb", "test/test_factory_methods.rb", "test/test_insert_manager.rb", "test/test_select_manager.rb", "test/test_table.rb", "test/test_update_manager.rb", "test/visitors/test_bind_visitor.rb", "test/visitors/test_depth_first.rb", "test/visitors/test_dispatch_contamination.rb", "test/visitors/test_dot.rb", "test/visitors/test_ibm_db.rb", "test/visitors/test_informix.rb", "test/visitors/test_mssql.rb", "test/visitors/test_mysql.rb", "test/visitors/test_oracle.rb", "test/visitors/test_postgres.rb", "test/visitors/test_sqlite.rb", "test/visitors/test_to_sql.rb"]
s.homepage = "http://github.com/rails/arel"
s.licenses = ["MIT"]
s.rdoc_options = ["--main", "README.markdown"]
- s.rubyforge_project = "arel"
s.rubygems_version = "2.2.2"
s.summary = "Arel Really Exasperates Logicians Arel is a SQL AST manager for Ruby"
s.test_files = ["test/attributes/test_attribute.rb", "test/collectors/test_bind_collector.rb", "test/collectors/test_sql_string.rb", "test/nodes/test_and.rb", "test/nodes/test_as.rb", "test/nodes/test_ascending.rb", "test/nodes/test_bin.rb", "test/nodes/test_count.rb", "test/nodes/test_delete_statement.rb", "test/nodes/test_descending.rb", "test/nodes/test_distinct.rb", "test/nodes/test_equality.rb", "test/nodes/test_extract.rb", "test/nodes/test_false.rb", "test/nodes/test_grouping.rb", "test/nodes/test_infix_operation.rb", "test/nodes/test_insert_statement.rb", "test/nodes/test_named_function.rb", "test/nodes/test_node.rb", "test/nodes/test_not.rb", "test/nodes/test_or.rb", "test/nodes/test_over.rb", "test/nodes/test_select_core.rb", "test/nodes/test_select_statement.rb", "test/nodes/test_sql_literal.rb", "test/nodes/test_sum.rb", "test/nodes/test_table_alias.rb", "test/nodes/test_true.rb", "test/nodes/test_update_statement.rb", "test/nodes/test_window.rb", "test/test_attributes.rb", "test/test_crud.rb", "test/test_delete_manager.rb", "test/test_factory_methods.rb", "test/test_insert_manager.rb", "test/test_select_manager.rb", "test/test_table.rb", "test/test_update_manager.rb", "test/visitors/test_bind_visitor.rb", "test/visitors/test_depth_first.rb", "test/visitors/test_dispatch_contamination.rb", "test/visitors/test_dot.rb", "test/visitors/test_ibm_db.rb", "test/visitors/test_informix.rb", "test/visitors/test_mssql.rb", "test/visitors/test_mysql.rb", "test/visitors/test_oracle.rb", "test/visitors/test_postgres.rb", "test/visitors/test_sqlite.rb", "test/visitors/test_to_sql.rb"]
@@ -25,17 +24,17 @@ Gem::Specification.new do |s|
s.specification_version = 4
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
- s.add_development_dependency(%q<minitest>, ["~> 5.3"])
+ s.add_development_dependency(%q<minitest>, ["~> 5.4"])
s.add_development_dependency(%q<rdoc>, ["~> 4.0"])
- s.add_development_dependency(%q<hoe>, ["~> 3.6"])
+ s.add_development_dependency(%q<hoe>, ["~> 3.12"])
else
- s.add_dependency(%q<minitest>, ["~> 5.3"])
+ s.add_dependency(%q<minitest>, ["~> 5.4"])
s.add_dependency(%q<rdoc>, ["~> 4.0"])
- s.add_dependency(%q<hoe>, ["~> 3.6"])
+ s.add_dependency(%q<hoe>, ["~> 3.12"])
end
else
- s.add_dependency(%q<minitest>, ["~> 5.3"])
+ s.add_dependency(%q<minitest>, ["~> 5.4"])
s.add_dependency(%q<rdoc>, ["~> 4.0"])
- s.add_dependency(%q<hoe>, ["~> 3.6"])
+ s.add_dependency(%q<hoe>, ["~> 3.12"])
end
end
diff --git a/lib/arel.rb b/lib/arel.rb
index 1e3c51a254..80677953df 100644
--- a/lib/arel.rb
+++ b/lib/arel.rb
@@ -21,7 +21,7 @@ require 'arel/delete_manager'
require 'arel/nodes'
module Arel
- VERSION = '6.0.0'
+ VERSION = '6.0.0.beta1'
def self.sql raw_sql
Arel::Nodes::SqlLiteral.new raw_sql
diff --git a/lib/arel/collectors/plain_string.rb b/lib/arel/collectors/plain_string.rb
new file mode 100644
index 0000000000..2505bc376e
--- /dev/null
+++ b/lib/arel/collectors/plain_string.rb
@@ -0,0 +1,18 @@
+module Arel
+ module Collectors
+ class PlainString
+ def initialize
+ @str = ''
+ end
+
+ def value
+ @str
+ end
+
+ def << str
+ @str << str
+ self
+ end
+ end
+ end
+end
diff --git a/lib/arel/collectors/sql_string.rb b/lib/arel/collectors/sql_string.rb
index 45001bb507..8ca89ca7bd 100644
--- a/lib/arel/collectors/sql_string.rb
+++ b/lib/arel/collectors/sql_string.rb
@@ -1,21 +1,10 @@
# encoding: utf-8
+require 'arel/collectors/plain_string'
+
module Arel
module Collectors
- class SQLString
- def initialize
- @str = ''
- end
-
- def value
- @str
- end
-
- def << str
- @str << str
- self
- end
-
+ class SQLString < PlainString
def add_bind bind
self << bind.to_s
self
diff --git a/lib/arel/expressions.rb b/lib/arel/expressions.rb
index fa18f15b67..d40268c292 100644
--- a/lib/arel/expressions.rb
+++ b/lib/arel/expressions.rb
@@ -5,23 +5,24 @@ module Arel
end
def sum
- Nodes::Sum.new [self], Nodes::SqlLiteral.new('sum_id')
+ Nodes::Sum.new [self]
end
def maximum
- Nodes::Max.new [self], Nodes::SqlLiteral.new('max_id')
+ Nodes::Max.new [self]
end
def minimum
- Nodes::Min.new [self], Nodes::SqlLiteral.new('min_id')
+ Nodes::Min.new [self]
end
def average
- Nodes::Avg.new [self], Nodes::SqlLiteral.new('avg_id')
+ Nodes::Avg.new [self]
end
def extract field
Nodes::Extract.new [self], field
end
+
end
end
diff --git a/lib/arel/nodes.rb b/lib/arel/nodes.rb
index a68e327983..c6bde8c3cc 100644
--- a/lib/arel/nodes.rb
+++ b/lib/arel/nodes.rb
@@ -78,7 +78,7 @@ module Arel
def self.build_quoted other, attribute = nil
case other
- when Arel::Nodes::Node, Arel::Attributes::Attribute, Arel::Nodes::SelectStatement, Arel::Table, Arel::Nodes::BindParam
+ when Arel::Nodes::Node, Arel::Attributes::Attribute, Arel::Table, Arel::Nodes::BindParam, Arel::SelectManager
other
else
case attribute
diff --git a/lib/arel/nodes/and.rb b/lib/arel/nodes/and.rb
index 62e8ef6f11..8e1afda709 100644
--- a/lib/arel/nodes/and.rb
+++ b/lib/arel/nodes/and.rb
@@ -3,12 +3,8 @@ module Arel
class And < Arel::Nodes::Node
attr_reader :children
- def initialize children, right = nil
+ def initialize children
super()
- unless Array === children
- warn "(#{caller.first}) AND nodes should be created with a list"
- children = [children, right]
- end
@children = children
end
diff --git a/lib/arel/nodes/window.rb b/lib/arel/nodes/window.rb
index 60259e8c05..fee8eeff7a 100644
--- a/lib/arel/nodes/window.rb
+++ b/lib/arel/nodes/window.rb
@@ -1,10 +1,12 @@
module Arel
module Nodes
class Window < Arel::Nodes::Node
- attr_accessor :orders, :framing
+ attr_accessor :orders, :framing, :partitions
def initialize
@orders = []
+ @partitions = []
+ @framing = nil
end
def order *expr
@@ -15,16 +17,32 @@ module Arel
self
end
+ def partition *expr
+ # FIXME: We SHOULD NOT be converting these to SqlLiteral automatically
+ @partitions.concat expr.map { |x|
+ String === x || Symbol === x ? Nodes::SqlLiteral.new(x.to_s) : x
+ }
+ self
+ end
+
def frame(expr)
@framing = expr
end
def rows(expr = nil)
- frame(Rows.new(expr))
+ if @framing
+ Rows.new(expr)
+ else
+ frame(Rows.new(expr))
+ end
end
def range(expr = nil)
- frame(Range.new(expr))
+ if @framing
+ Range.new(expr)
+ else
+ frame(Range.new(expr))
+ end
end
def initialize_copy other
@@ -39,7 +57,8 @@ module Arel
def eql? other
self.class == other.class &&
self.orders == other.orders &&
- self.framing == other.framing
+ self.framing == other.framing &&
+ self.partitions == other.partitions
end
alias :== :eql?
end
diff --git a/lib/arel/predications.rb b/lib/arel/predications.rb
index 2ef4837548..78cd87d430 100644
--- a/lib/arel/predications.rb
+++ b/lib/arel/predications.rb
@@ -29,14 +29,16 @@ module Arel
when Arel::SelectManager
Arel::Nodes::In.new(self, other.ast)
when Range
- if other.begin == -Float::INFINITY && other.end == Float::INFINITY
- Nodes::NotIn.new self, []
+ if other.begin == -Float::INFINITY
+ if other.end == Float::INFINITY
+ Nodes::NotIn.new self, []
+ elsif other.exclude_end?
+ Nodes::LessThan.new(self, Nodes.build_quoted(other.end, self))
+ else
+ Nodes::LessThanOrEqual.new(self, Nodes.build_quoted(other.end, self))
+ end
elsif other.end == Float::INFINITY
Nodes::GreaterThanOrEqual.new(self, Nodes.build_quoted(other.begin, self))
- elsif other.begin == -Float::INFINITY && other.exclude_end?
- Nodes::LessThan.new(self, Nodes.build_quoted(other.end, self))
- elsif other.begin == -Float::INFINITY
- Nodes::LessThanOrEqual.new(self, Nodes.build_quoted(other.end, self))
elsif other.exclude_end?
left = Nodes::GreaterThanOrEqual.new(self, Nodes.build_quoted(other.begin, self))
right = Nodes::LessThan.new(self, Nodes.build_quoted(other.end, self))
@@ -64,21 +66,23 @@ module Arel
when Arel::SelectManager
Arel::Nodes::NotIn.new(self, other.ast)
when Range
- if other.begin == -Float::INFINITY && other.end == Float::INFINITY
- Nodes::In.new self, []
- elsif other.end == Float::INFINITY
+ if other.begin == -Float::INFINITY # The range begins with negative infinity
+ if other.end == Float::INFINITY
+ Nodes::In.new self, [] # The range is infinite, so return an empty range
+ elsif other.exclude_end?
+ Nodes::GreaterThanOrEqual.new(self, Nodes.build_quoted(other.end, self))
+ else
+ Nodes::GreaterThan.new(self, Nodes.build_quoted(other.end, self))
+ end
+ elsif other.end == Float::INFINITY
Nodes::LessThan.new(self, Nodes.build_quoted(other.begin, self))
- elsif other.begin == -Float::INFINITY && other.exclude_end?
- Nodes::GreaterThanOrEqual.new(self, Nodes.build_quoted(other.end, self))
- elsif other.begin == -Float::INFINITY
- Nodes::GreaterThan.new(self, Nodes.build_quoted(other.end, self))
- elsif other.exclude_end?
- left = Nodes::LessThan.new(self, Nodes.build_quoted(other.begin, self))
- right = Nodes::GreaterThanOrEqual.new(self, Nodes.build_quoted(other.end, self))
- Nodes::Or.new left, right
else
left = Nodes::LessThan.new(self, Nodes.build_quoted(other.begin, self))
- right = Nodes::GreaterThan.new(self, Nodes.build_quoted(other.end, self))
+ if other.exclude_end?
+ right = Nodes::GreaterThanOrEqual.new(self, Nodes.build_quoted(other.end, self))
+ else
+ right = Nodes::GreaterThan.new(self, Nodes.build_quoted(other.end, self))
+ end
Nodes::Or.new left, right
end
when Array
diff --git a/lib/arel/select_manager.rb b/lib/arel/select_manager.rb
index f1dde6403a..4a652f2c9c 100644
--- a/lib/arel/select_manager.rb
+++ b/lib/arel/select_manager.rb
@@ -106,7 +106,7 @@ module Arel
case relation
when String, Nodes::SqlLiteral
- raise if relation.blank?
+ raise if relation.empty?
klass = Nodes::StringJoin
end
diff --git a/lib/arel/table.rb b/lib/arel/table.rb
index 545e73e3ae..01d4561ff1 100644
--- a/lib/arel/table.rb
+++ b/lib/arel/table.rb
@@ -57,7 +57,7 @@ primary_key (#{caller.first}) is deprecated and will be removed in Arel 4.0.0
case relation
when String, Nodes::SqlLiteral
- raise if relation.blank?
+ raise if relation.empty?
klass = Nodes::StringJoin
end
diff --git a/lib/arel/tree_manager.rb b/lib/arel/tree_manager.rb
index 87887800d0..8bff97af78 100644
--- a/lib/arel/tree_manager.rb
+++ b/lib/arel/tree_manager.rb
@@ -15,7 +15,9 @@ module Arel
end
def to_dot
- Visitors::Dot.new.accept @ast
+ collector = Arel::Collectors::PlainString.new
+ collector = Visitors::Dot.new.accept @ast, collector
+ collector.value
end
def visitor
diff --git a/lib/arel/visitors/bind_substitute.rb b/lib/arel/visitors/bind_substitute.rb
index 0503a9c986..ce0fb5c924 100644
--- a/lib/arel/visitors/bind_substitute.rb
+++ b/lib/arel/visitors/bind_substitute.rb
@@ -1,7 +1,7 @@
module Arel
module Visitors
class BindSubstitute
- def initialize delegte
+ def initialize delegate
@delegate = delegate
end
end
diff --git a/lib/arel/visitors/dot.rb b/lib/arel/visitors/dot.rb
index ba35223ac9..f0cefeabd7 100644
--- a/lib/arel/visitors/dot.rb
+++ b/lib/arel/visitors/dot.rb
@@ -22,9 +22,9 @@ module Arel
@seen = {}
end
- def accept object
+ def accept object, collector
visit object
- to_dot
+ collector << to_dot
end
private
@@ -82,12 +82,14 @@ module Arel
alias :visit_Arel_Nodes_Range :unary
def window o
+ visit_edge o, "partitions"
visit_edge o, "orders"
visit_edge o, "framing"
end
alias :visit_Arel_Nodes_Window :window
def named_window o
+ visit_edge o, "partitions"
visit_edge o, "orders"
visit_edge o, "framing"
visit_edge o, "name"
diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb
index 264521f4c6..ae1b7930af 100644
--- a/lib/arel/visitors/to_sql.rb
+++ b/lib/arel/visitors/to_sql.rb
@@ -103,9 +103,7 @@ module Arel
collector << "UPDATE "
collector = visit o.relation, collector
- values = false
unless o.values.empty?
- values = true
collector << " SET "
collector = inject_join o.values, collector, ", "
end
@@ -300,8 +298,9 @@ module Arel
raise NotImplementedError, 'DISTINCT ON not implemented for this db'
end
- def visit_Arel_Nodes_With o
- "WITH #{o.children.map { |x| visit x }.join(', ')}"
+ def visit_Arel_Nodes_With o, collector
+ collector << "WITH "
+ inject_join o.children, collector, ', '
end
def visit_Arel_Nodes_WithRecursive o, collector
@@ -337,12 +336,20 @@ module Arel
def visit_Arel_Nodes_Window o, collector
collector << "("
+
+ if o.partitions.any?
+ collector << "PARTITION BY "
+ collector = inject_join o.partitions, collector, ", "
+ end
+
if o.orders.any?
+ collector << ' ' if o.partitions.any?
collector << "ORDER BY "
collector = inject_join o.orders, collector, ", "
end
if o.framing
+ collector << ' ' if o.partitions.any? or o.orders.any?
collector = visit o.framing, collector
end
@@ -719,7 +726,7 @@ module Arel
quote(o, column_for(a))
end
- def unsupported o
+ def unsupported o, collector
raise "unsupported: #{o.class.name}"
end
diff --git a/test/attributes/test_attribute.rb b/test/attributes/test_attribute.rb
index e53b32d0ac..dd2d9d343e 100644
--- a/test/attributes/test_attribute.rb
+++ b/test/attributes/test_attribute.rb
@@ -66,7 +66,7 @@ module Arel
relation[:id].gt(10).must_be_kind_of Nodes::GreaterThan
end
- it 'should generate >= in sql' do
+ it 'should generate > in sql' do
relation = Table.new(:users)
mgr = relation.project relation[:id]
mgr.where relation[:id].gt(10)
@@ -74,6 +74,17 @@ module Arel
SELECT "users"."id" FROM "users" WHERE "users"."id" > 10
}
end
+
+ it 'should handle comparing with a subquery' do
+ users = Table.new(:users)
+
+ avg = users.project(users[:karma].average)
+ mgr = users.project(Arel.star).where(users[:karma].gt(avg))
+
+ mgr.to_sql.must_be_like %{
+ SELECT * FROM "users" WHERE "users"."karma" > (SELECT AVG("users"."karma") FROM "users")
+ }
+ end
end
describe '#gt_any' do
@@ -258,12 +269,11 @@ module Arel
relation[:id].average.must_be_kind_of Nodes::Avg
end
- # FIXME: backwards compat. Is this really necessary?
- it 'should set the alias to "avg_id"' do
+ it 'should generate the proper SQL' do
relation = Table.new(:users)
mgr = relation.project relation[:id].average
mgr.to_sql.must_be_like %{
- SELECT AVG("users"."id") AS avg_id
+ SELECT AVG("users"."id")
FROM "users"
}
end
@@ -275,12 +285,11 @@ module Arel
relation[:id].maximum.must_be_kind_of Nodes::Max
end
- # FIXME: backwards compat. Is this really necessary?
- it 'should set the alias to "max_id"' do
+ it 'should generate the proper SQL' do
relation = Table.new(:users)
mgr = relation.project relation[:id].maximum
mgr.to_sql.must_be_like %{
- SELECT MAX("users"."id") AS max_id
+ SELECT MAX("users"."id")
FROM "users"
}
end
@@ -299,12 +308,11 @@ module Arel
relation[:id].sum.must_be_kind_of Nodes::Sum
end
- # FIXME: backwards compat. Is this really necessary?
- it 'should set the alias to "sum_id"' do
+ it 'should generate the proper SQL' do
relation = Table.new(:users)
mgr = relation.project relation[:id].sum
mgr.to_sql.must_be_like %{
- SELECT SUM("users"."id") AS sum_id
+ SELECT SUM("users"."id")
FROM "users"
}
end
@@ -550,8 +558,6 @@ module Arel
end
describe '#not_in' do
- it 'can be constructed with a list' do
- end
it 'should return a NotIn node' do
attribute = Attribute.new nil, nil
diff --git a/test/collectors/test_bind_collector.rb b/test/collectors/test_bind_collector.rb
index 036d8f05fe..60532f061c 100644
--- a/test/collectors/test_bind_collector.rb
+++ b/test/collectors/test_bind_collector.rb
@@ -49,7 +49,7 @@ module Arel
offsets = values.map.with_index { |v,i|
[v,i]
- }.find_all { |(v,i)| Nodes::BindParam === v }.map(&:last)
+ }.find_all { |(v,_)| Nodes::BindParam === v }.map(&:last)
list = collector.substitute_binds ["hello", "world"]
assert_equal "hello", list[offsets[0]]
diff --git a/test/nodes/test_infix_operation.rb b/test/nodes/test_infix_operation.rb
index bec226e395..40616024e5 100644
--- a/test/nodes/test_infix_operation.rb
+++ b/test/nodes/test_infix_operation.rb
@@ -18,7 +18,7 @@ module Arel
assert_equal 'zomg', aliaz.right
end
- def test_opertaion_ordering
+ def test_operation_ordering
operation = InfixOperation.new :+, 1, 2
ordering = operation.desc
assert_kind_of Descending, ordering
diff --git a/test/nodes/test_window.rb b/test/nodes/test_window.rb
index f09d16e441..9ec42be59f 100644
--- a/test/nodes/test_window.rb
+++ b/test/nodes/test_window.rb
@@ -7,9 +7,11 @@ module Arel
it 'is equal with equal ivars' do
window1 = Window.new
window1.orders = [1, 2]
+ window1.partitions = [1]
window1.frame 3
window2 = Window.new
window2.orders = [1, 2]
+ window2.partitions = [1]
window2.frame 3
array = [window1, window2]
assert_equal 1, array.uniq.size
@@ -18,9 +20,11 @@ module Arel
it 'is not equal with different ivars' do
window1 = Window.new
window1.orders = [1, 2]
+ window1.partitions = [1]
window1.frame 3
window2 = Window.new
window2.orders = [1, 2]
+ window1.partitions = [1]
window2.frame 4
array = [window1, window2]
assert_equal 2, array.uniq.size
@@ -33,9 +37,11 @@ module Arel
it 'is equal with equal ivars' do
window1 = NamedWindow.new 'foo'
window1.orders = [1, 2]
+ window1.partitions = [1]
window1.frame 3
window2 = NamedWindow.new 'foo'
window2.orders = [1, 2]
+ window2.partitions = [1]
window2.frame 3
array = [window1, window2]
assert_equal 1, array.uniq.size
@@ -44,9 +50,11 @@ module Arel
it 'is not equal with different ivars' do
window1 = NamedWindow.new 'foo'
window1.orders = [1, 2]
+ window1.partitions = [1]
window1.frame 3
window2 = NamedWindow.new 'bar'
window2.orders = [1, 2]
+ window2.partitions = [1]
window2.frame 3
array = [window1, window2]
assert_equal 2, array.uniq.size
@@ -68,6 +76,4 @@ module Arel
end
end
end
-end
-
-
+end \ No newline at end of file
diff --git a/test/test_insert_manager.rb b/test/test_insert_manager.rb
index 4e82ca34c0..9cfd01262b 100644
--- a/test/test_insert_manager.rb
+++ b/test/test_insert_manager.rb
@@ -78,14 +78,19 @@ module Arel
}
end
- it 'takes an empty list' do
+ it 'noop for empty list' do
+ table = Table.new(:users)
manager = Arel::InsertManager.new Table.engine
+ manager.insert [[table[:id], 1]]
manager.insert []
+ manager.to_sql.must_be_like %{
+ INSERT INTO "users" ("id") VALUES (1)
+ }
end
end
describe 'into' do
- it 'takes an engine' do
+ it 'takes a Table and chains' do
manager = Arel::InsertManager.new Table.engine
manager.into(Table.new(:users)).must_equal manager
end
@@ -126,7 +131,7 @@ module Arel
end
describe "combo" do
- it "puts shit together" do
+ it "combines columns and values list in order" do
table = Table.new :users
manager = Arel::InsertManager.new Table.engine
manager.into table
diff --git a/test/test_select_manager.rb b/test/test_select_manager.rb
index 09608ea71e..3380bbec6f 100644
--- a/test/test_select_manager.rb
+++ b/test/test_select_manager.rb
@@ -140,7 +140,7 @@ module Arel
mgr.to_sql.must_be_like %{ SELECT FROM "users" INNER JOIN "users" "users_2" ON omg }
end
- it 'converts to sqlliterals' do
+ it 'converts to sqlliterals with multiple items' do
table = Table.new :users
right = table.alias
mgr = table.from table
@@ -152,7 +152,7 @@ module Arel
describe 'clone' do
it 'creates new cores' do
- table = Table.new :users, :engine => Table.engine, :as => 'foo'
+ table = Table.new :users, :as => 'foo'
mgr = table.from table
m2 = mgr.clone
m2.project "foo"
@@ -160,7 +160,7 @@ module Arel
end
it 'makes updates to the correct copy' do
- table = Table.new :users, :engine => Table.engine, :as => 'foo'
+ table = Table.new :users, :as => 'foo'
mgr = table.from table
m2 = mgr.clone
m3 = m2.clone
@@ -172,7 +172,7 @@ module Arel
describe 'initialize' do
it 'uses alias in sql' do
- table = Table.new :users, :engine => Table.engine, :as => 'foo'
+ table = Table.new :users, :as => 'foo'
mgr = table.from table
mgr.skip 10
mgr.to_sql.must_be_like %{ SELECT FROM "users" "foo" OFFSET 10 }
@@ -330,6 +330,20 @@ module Arel
end
describe 'with' do
+ it 'should support basic WITH' do
+ users = Table.new(:users)
+ users_top = Table.new(:users_top)
+ comments = Table.new(:comments)
+
+ top = users.project(users[:id]).where(users[:karma].gt(100))
+ users_as = Arel::Nodes::As.new(users_top, top)
+ select_manager = comments.project(Arel.star).with(users_as)
+ .where(comments[:author_id].in(users_top.project(users_top[:id])))
+
+ select_manager.to_sql.must_be_like %{
+ WITH "users_top" AS (SELECT "users"."id" FROM "users" WHERE "users"."karma" > 100) SELECT * FROM "comments" WHERE "comments"."author_id" IN (SELECT "users_top"."id" FROM "users_top")
+ }
+ end
it "should support WITH RECURSIVE" do
comments = Table.new(:comments)
@@ -368,8 +382,7 @@ module Arel
it 'should return the ast' do
table = Table.new :users
mgr = table.from table
- ast = mgr.ast
- assert ast
+ assert mgr.ast
end
it 'should allow orders to work when the ast is grepped' do
@@ -518,7 +531,7 @@ module Arel
assert_equal 'bar', join.right
end
- it 'should create join nodes with a klass' do
+ it 'should create join nodes with a full outer join klass' do
relation = Arel::SelectManager.new Table.engine
join = relation.create_join 'foo', 'bar', Arel::Nodes::FullOuterJoin
assert_kind_of Arel::Nodes::FullOuterJoin, join
@@ -526,7 +539,7 @@ module Arel
assert_equal 'bar', join.right
end
- it 'should create join nodes with a klass' do
+ it 'should create join nodes with a outer join klass' do
relation = Arel::SelectManager.new Table.engine
join = relation.create_join 'foo', 'bar', Arel::Nodes::OuterJoin
assert_kind_of Arel::Nodes::OuterJoin, join
@@ -534,7 +547,7 @@ module Arel
assert_equal 'bar', join.right
end
- it 'should create join nodes with a klass' do
+ it 'should create join nodes with a right outer join klass' do
relation = Arel::SelectManager.new Table.engine
join = relation.create_join 'foo', 'bar', Arel::Nodes::RightOuterJoin
assert_kind_of Arel::Nodes::RightOuterJoin, join
@@ -602,7 +615,8 @@ module Arel
end
describe 'joins' do
- it 'returns join sql' do
+
+ it 'returns inner join sql' do
table = Table.new :users
aliaz = table.alias
manager = Arel::SelectManager.new Table.engine
@@ -637,6 +651,22 @@ module Arel
}
end
+ it "joins itself" do
+ left = Table.new :users
+ right = left.alias
+ predicate = left[:id].eq(right[:id])
+
+ mgr = left.join(right)
+ mgr.project Nodes::SqlLiteral.new('*')
+ mgr.on(predicate).must_equal mgr
+
+ mgr.to_sql.must_be_like %{
+ SELECT * FROM "users"
+ INNER JOIN "users" "users_2"
+ ON "users"."id" = "users_2"."id"
+ }
+ end
+
it 'returns string join sql' do
manager = Arel::SelectManager.new Table.engine
manager.from Nodes::StringJoin.new(Nodes.build_quoted('hello'))
@@ -702,6 +732,47 @@ module Arel
}
end
+ it 'takes an order with multiple columns' do
+ table = Table.new :users
+ manager = Arel::SelectManager.new Table.engine
+ manager.from table
+ manager.window('a_window').order(table['foo'].asc, table['bar'].desc)
+ manager.to_sql.must_be_like %{
+ SELECT FROM "users" WINDOW "a_window" AS (ORDER BY "users"."foo" ASC, "users"."bar" DESC)
+ }
+ end
+
+ it 'takes a partition' do
+ table = Table.new :users
+ manager = Arel::SelectManager.new Table.engine
+ manager.from table
+ manager.window('a_window').partition(table['bar'])
+ manager.to_sql.must_be_like %{
+ SELECT FROM "users" WINDOW "a_window" AS (PARTITION BY "users"."bar")
+ }
+ end
+
+ it 'takes a partition and an order' do
+ table = Table.new :users
+ manager = Arel::SelectManager.new Table.engine
+ manager.from table
+ manager.window('a_window').partition(table['foo']).order(table['foo'].asc)
+ manager.to_sql.must_be_like %{
+ SELECT FROM "users" WINDOW "a_window" AS (PARTITION BY "users"."foo"
+ ORDER BY "users"."foo" ASC)
+ }
+ end
+
+ it 'takes a partition with multiple columns' do
+ table = Table.new :users
+ manager = Arel::SelectManager.new Table.engine
+ manager.from table
+ manager.window('a_window').partition(table['bar'], table['baz'])
+ manager.to_sql.must_be_like %{
+ SELECT FROM "users" WINDOW "a_window" AS (PARTITION BY "users"."bar", "users"."baz")
+ }
+ end
+
it 'takes a rows frame, unbounded preceding' do
table = Table.new :users
manager = Arel::SelectManager.new Table.engine
@@ -878,6 +949,27 @@ module Arel
end
describe 'update' do
+
+ it 'creates an update statement' do
+ table = Table.new :users
+ manager = Arel::SelectManager.new Table.engine
+ manager.from table
+ stmt = manager.compile_update({table[:id] => 1}, Arel::Attributes::Attribute.new(table, 'id'))
+
+ stmt.to_sql.must_be_like %{
+ UPDATE "users" SET "id" = 1
+ }
+ end
+
+ it 'takes a string' do
+ table = Table.new :users
+ manager = Arel::SelectManager.new Table.engine
+ manager.from table
+ stmt = manager.compile_update(Nodes::SqlLiteral.new('foo = bar'), Arel::Attributes::Attribute.new(table, 'id'))
+
+ stmt.to_sql.must_be_like %{ UPDATE "users" SET foo = bar }
+ end
+
it 'copies limits' do
table = Table.new :users
manager = Arel::SelectManager.new Table.engine
@@ -906,15 +998,6 @@ module Arel
}
end
- it 'takes a string' do
- table = Table.new :users
- manager = Arel::SelectManager.new Table.engine
- manager.from table
- stmt = manager.compile_update(Nodes::SqlLiteral.new('foo = bar'), Arel::Attributes::Attribute.new(table, 'id'))
-
- stmt.to_sql.must_be_like %{ UPDATE "users" SET foo = bar }
- end
-
it 'copies where clauses' do
table = Table.new :users
manager = Arel::SelectManager.new Table.engine
@@ -940,19 +1023,15 @@ module Arel
}
end
- it 'executes an update statement' do
- table = Table.new :users
- manager = Arel::SelectManager.new Table.engine
- manager.from table
- stmt = manager.compile_update({table[:id] => 1}, Arel::Attributes::Attribute.new(table, 'id'))
-
- stmt.to_sql.must_be_like %{
- UPDATE "users" SET "id" = 1
- }
- end
end
describe 'project' do
+ it "takes sql literals" do
+ manager = Arel::SelectManager.new Table.engine
+ manager.project Nodes::SqlLiteral.new '*'
+ manager.to_sql.must_be_like %{ SELECT * }
+ end
+
it 'takes multiple args' do
manager = Arel::SelectManager.new Table.engine
manager.project Nodes::SqlLiteral.new('foo'),
@@ -966,11 +1045,6 @@ module Arel
manager.to_sql.must_be_like %{ SELECT * }
end
- it "takes sql literals" do
- manager = Arel::SelectManager.new Table.engine
- manager.project Nodes::SqlLiteral.new '*'
- manager.to_sql.must_be_like %{ SELECT * }
- end
end
describe 'projections' do
@@ -1042,24 +1116,6 @@ module Arel
end
end
- describe "join" do
- it "joins itself" do
- left = Table.new :users
- right = left.alias
- predicate = left[:id].eq(right[:id])
-
- mgr = left.join(right)
- mgr.project Nodes::SqlLiteral.new('*')
- mgr.on(predicate).must_equal mgr
-
- mgr.to_sql.must_be_like %{
- SELECT * FROM "users"
- INNER JOIN "users" "users_2"
- ON "users"."id" = "users_2"."id"
- }
- end
- end
-
describe 'from' do
it "makes sql" do
table = Table.new :users
diff --git a/test/visitors/test_dot.rb b/test/visitors/test_dot.rb
index ee7fc7886c..7763350f5c 100644
--- a/test/visitors/test_dot.rb
+++ b/test/visitors/test_dot.rb
@@ -17,13 +17,13 @@ module Arel
].each do |klass|
define_method("test_#{klass.name.gsub('::', '_')}") do
op = klass.new(:a, "z")
- @visitor.accept op
+ @visitor.accept op, Collectors::PlainString.new
end
end
def test_named_function
func = Nodes::NamedFunction.new 'omg', 'omg'
- @visitor.accept func
+ @visitor.accept func, Collectors::PlainString.new
end
# unary ops
@@ -41,7 +41,7 @@ module Arel
].each do |klass|
define_method("test_#{klass.name.gsub('::', '_')}") do
op = klass.new(:a)
- @visitor.accept op
+ @visitor.accept op, Collectors::PlainString.new
end
end
@@ -68,7 +68,7 @@ module Arel
].each do |klass|
define_method("test_#{klass.name.gsub('::', '_')}") do
binary = klass.new(:a, :b)
- @visitor.accept binary
+ @visitor.accept binary, Collectors::PlainString.new
end
end
end
diff --git a/test/visitors/test_to_sql.rb b/test/visitors/test_to_sql.rb
index 738bbe9626..c03d89cfef 100644
--- a/test/visitors/test_to_sql.rb
+++ b/test/visitors/test_to_sql.rb
@@ -254,6 +254,11 @@ module Arel
compile(Nodes.build_quoted(nil)).must_be_like "NULL"
end
+ it "unsupported input should not raise ArgumentError" do
+ error = assert_raises(RuntimeError) { compile(nil) }
+ assert_match(/\Aunsupported/, error.message)
+ end
+
it "should visit_Arel_SelectManager, which is a subquery" do
mgr = Table.new(:foo).project(:bar)
compile(mgr).must_be_like '(SELECT bar FROM "foo")'