aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml8
-rw-r--r--History.txt6
-rw-r--r--lib/arel.rb2
-rw-r--r--lib/arel/nodes/unary.rb8
-rw-r--r--lib/arel/visitors/depth_first.rb5
-rw-r--r--lib/arel/visitors/dot.rb5
-rw-r--r--lib/arel/visitors/oracle12.rb12
-rw-r--r--lib/arel/visitors/postgresql.rb36
-rw-r--r--lib/arel/visitors/to_sql.rb7
-rw-r--r--test/visitors/test_oracle12.rb22
-rw-r--r--test/visitors/test_postgres.rb78
-rw-r--r--test/visitors/test_to_sql.rb2
12 files changed, 174 insertions, 17 deletions
diff --git a/.travis.yml b/.travis.yml
index 31d4b9ed3a..363f53f6ce 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,16 +9,20 @@ env:
- JRUBY_OPTS='--dev -J-Xmx1024M'
rvm:
- rbx-2
+ - jruby-9.0.5.0
- jruby-head
- 2.0.0
- 2.1
- - 2.2.4
- - 2.3.0
+ - 2.2.5
+ - 2.3.1
- ruby-head
matrix:
fast_finish: true
allow_failures:
+ - rvm: jruby-9.0.5.0
+ - rvm: jruby-head
- rvm: ruby-head
+ - rvm: jruby-head
bundler_args: --jobs 3 --retry 3
notifications:
email: false
diff --git a/History.txt b/History.txt
index 9d4cd32461..07cb9024fd 100644
--- a/History.txt
+++ b/History.txt
@@ -1,3 +1,9 @@
+=== 7.0.1 / unreleased
+
+* Enhancements
+
+ * Support Ruby 2.4 unified Integer class
+
=== 7.0.0 / 2015-12-17
* Enhancements
diff --git a/lib/arel.rb b/lib/arel.rb
index f32929e70f..2bd56372ef 100644
--- a/lib/arel.rb
+++ b/lib/arel.rb
@@ -21,7 +21,7 @@ require 'arel/delete_manager'
require 'arel/nodes'
module Arel
- VERSION = '7.0.0'
+ VERSION = '7.0.1.pre'
def self.sql raw_sql
Arel::Nodes::SqlLiteral.new raw_sql
diff --git a/lib/arel/nodes/unary.rb b/lib/arel/nodes/unary.rb
index a0062ff5be..50946980b4 100644
--- a/lib/arel/nodes/unary.rb
+++ b/lib/arel/nodes/unary.rb
@@ -22,15 +22,19 @@ module Arel
%w{
Bin
+ Cube
+ DistinctOn
Group
+ GroupingElement
+ GroupingSet
Limit
+ Lock
Not
Offset
On
Ordering
+ RollUp
Top
- Lock
- DistinctOn
}.each do |name|
const_set(name, Class.new(Unary))
end
diff --git a/lib/arel/visitors/depth_first.rb b/lib/arel/visitors/depth_first.rb
index fb21fb1e70..80b3c3c346 100644
--- a/lib/arel/visitors/depth_first.rb
+++ b/lib/arel/visitors/depth_first.rb
@@ -18,6 +18,10 @@ module Arel
end
alias :visit_Arel_Nodes_Else :unary
alias :visit_Arel_Nodes_Group :unary
+ alias :visit_Arel_Nodes_Cube :unary
+ alias :visit_Arel_Nodes_RollUp :unary
+ alias :visit_Arel_Nodes_GroupingSet :unary
+ alias :visit_Arel_Nodes_GroupingElement :unary
alias :visit_Arel_Nodes_Grouping :unary
alias :visit_Arel_Nodes_Having :unary
alias :visit_Arel_Nodes_Limit :unary
@@ -137,6 +141,7 @@ module Arel
alias :visit_FalseClass :terminal
alias :visit_Fixnum :terminal
alias :visit_Float :terminal
+ alias :visit_Integer :terminal
alias :visit_NilClass :terminal
alias :visit_String :terminal
alias :visit_Symbol :terminal
diff --git a/lib/arel/visitors/dot.rb b/lib/arel/visitors/dot.rb
index da75423523..ca8d2b0bd0 100644
--- a/lib/arel/visitors/dot.rb
+++ b/lib/arel/visitors/dot.rb
@@ -69,6 +69,10 @@ module Arel
visit_edge o, "expr"
end
alias :visit_Arel_Nodes_Group :unary
+ alias :visit_Arel_Nodes_Cube :unary
+ alias :visit_Arel_Nodes_RollUp :unary
+ alias :visit_Arel_Nodes_GroupingSet :unary
+ alias :visit_Arel_Nodes_GroupingElement :unary
alias :visit_Arel_Nodes_Grouping :unary
alias :visit_Arel_Nodes_Having :unary
alias :visit_Arel_Nodes_Limit :unary
@@ -201,6 +205,7 @@ module Arel
alias :visit_TrueClass :visit_String
alias :visit_FalseClass :visit_String
alias :visit_Arel_Nodes_BindParam :visit_String
+ alias :visit_Integer :visit_String
alias :visit_Fixnum :visit_String
alias :visit_BigDecimal :visit_String
alias :visit_Float :visit_String
diff --git a/lib/arel/visitors/oracle12.rb b/lib/arel/visitors/oracle12.rb
index 4a42343c9b..9b722e8c0c 100644
--- a/lib/arel/visitors/oracle12.rb
+++ b/lib/arel/visitors/oracle12.rb
@@ -6,10 +6,12 @@ module Arel
def visit_Arel_Nodes_SelectStatement o, collector
# Oracle does not allow LIMIT clause with select for update
if o.limit && o.lock
- o = o.dup
- o.limit = []
+ raise ArgumentError, <<-MSG
+ 'Combination of limit and lock is not supported.
+ because generated SQL statements
+ `SELECT FOR UPDATE and FETCH FIRST n ROWS` generates ORA-02014.`
+ MSG
end
-
super
end
@@ -48,6 +50,10 @@ module Arel
super
end
+
+ def visit_Arel_Nodes_BindParam o, collector
+ collector.add_bind(o) { |i| ":a#{i}" }
+ end
end
end
end
diff --git a/lib/arel/visitors/postgresql.rb b/lib/arel/visitors/postgresql.rb
index 1ef0261bdd..ef0f0ea2ef 100644
--- a/lib/arel/visitors/postgresql.rb
+++ b/lib/arel/visitors/postgresql.rb
@@ -1,6 +1,10 @@
module Arel
module Visitors
class PostgreSQL < Arel::Visitors::ToSql
+ CUBE = 'CUBE'
+ ROLLUP = 'ROLLUP'
+ GROUPING_SET = 'GROUPING SET'
+
private
def visit_Arel_Nodes_Matches o, collector
@@ -43,6 +47,38 @@ module Arel
def visit_Arel_Nodes_BindParam o, collector
collector.add_bind(o) { |i| "$#{i}" }
end
+
+ def visit_Arel_Nodes_GroupingElement o, collector
+ collector << "( "
+ visit(o.expr, collector) << " )"
+ end
+
+ def visit_Arel_Nodes_Cube o, collector
+ collector << CUBE
+ grouping_array_or_grouping_element o, collector
+ end
+
+ def visit_Arel_Nodes_RollUp o, collector
+ collector << ROLLUP
+ grouping_array_or_grouping_element o, collector
+ end
+
+ def visit_Arel_Nodes_GroupingSet o, collector
+ collector << GROUPING_SET
+ grouping_array_or_grouping_element o, collector
+ end
+
+ # Utilized by GroupingSet, Cube & RollUp visitors to
+ # handle grouping aggregation semantics
+ def grouping_array_or_grouping_element o, collector
+ if o.expr.is_a? Array
+ collector << "( "
+ visit o.expr, collector
+ collector << " )"
+ else
+ visit o.expr, collector
+ end
+ end
end
end
end
diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb
index 1435f3e21d..5429bf4ee8 100644
--- a/lib/arel/visitors/to_sql.rb
+++ b/lib/arel/visitors/to_sql.rb
@@ -329,13 +329,13 @@ module Arel
end
if o.orders.any?
- collector << ' ' if o.partitions.any?
+ collector << SPACE 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 << SPACE if o.partitions.any? or o.orders.any?
collector = visit o.framing, collector
end
@@ -544,7 +544,7 @@ module Arel
collector = visit o.left, collector
end
if o.right.any?
- collector << " " if o.left
+ collector << SPACE if o.left
collector = inject_join o.right, collector, ' '
end
collector
@@ -742,6 +742,7 @@ module Arel
alias :visit_Arel_Nodes_SqlLiteral :literal
alias :visit_Bignum :literal
alias :visit_Fixnum :literal
+ alias :visit_Integer :literal
def quoted o, a
if a && a.able_to_type_cast?
diff --git a/test/visitors/test_oracle12.rb b/test/visitors/test_oracle12.rb
index df0f01b30b..5dac2994cf 100644
--- a/test/visitors/test_oracle12.rb
+++ b/test/visitors/test_oracle12.rb
@@ -2,9 +2,10 @@ require 'helper'
module Arel
module Visitors
- describe 'the oracle visitor' do
+ describe 'the oracle12 visitor' do
before do
- @visitor = Oracle12.new Table.engine.connection_pool
+ @visitor = Oracle12.new Table.engine.connection
+ @table = Table.new(:users)
end
def compile node
@@ -29,12 +30,13 @@ module Arel
end
describe 'locking' do
- it 'removes limit when locking' do
+ it 'generates ArgumentError if limit and lock are used' do
stmt = Nodes::SelectStatement.new
stmt.limit = Nodes::Limit.new(10)
stmt.lock = Nodes::Lock.new(Arel.sql('FOR UPDATE'))
- sql = compile(stmt)
- sql.must_be_like "SELECT FOR UPDATE"
+ assert_raises ArgumentError do
+ sql = compile(stmt)
+ end
end
it 'defaults to FOR UPDATE when locking' do
@@ -42,6 +44,16 @@ module Arel
compile(node).must_be_like "FOR UPDATE"
end
end
+
+ describe "Nodes::BindParam" do
+ it "increments each bind param" do
+ query = @table[:name].eq(Arel::Nodes::BindParam.new)
+ .and(@table[:id].eq(Arel::Nodes::BindParam.new))
+ compile(query).must_be_like %{
+ "users"."name" = :a1 AND "users"."id" = :a2
+ }
+ end
+ end
end
end
end
diff --git a/test/visitors/test_postgres.rb b/test/visitors/test_postgres.rb
index 4b7dbe367f..f97b734b7d 100644
--- a/test/visitors/test_postgres.rb
+++ b/test/visitors/test_postgres.rb
@@ -182,6 +182,84 @@ module Arel
}
end
end
+
+ describe "Nodes::Cube" do
+ it "should know how to visit with array arguments" do
+ node = Arel::Nodes::Cube.new([@table[:name], @table[:bool]])
+ compile(node).must_be_like %{
+ CUBE( "users"."name", "users"."bool" )
+ }
+ end
+
+ it "should know how to visit with CubeDimension Argument" do
+ dimensions = Arel::Nodes::GroupingElement.new([@table[:name], @table[:bool]])
+ node = Arel::Nodes::Cube.new(dimensions)
+ compile(node).must_be_like %{
+ CUBE( "users"."name", "users"."bool" )
+ }
+ end
+
+ it "should know how to generate paranthesis when supplied with many Dimensions" do
+ dim1 = Arel::Nodes::GroupingElement.new(@table[:name])
+ dim2 = Arel::Nodes::GroupingElement.new([@table[:bool], @table[:created_at]])
+ node = Arel::Nodes::Cube.new([dim1, dim2])
+ compile(node).must_be_like %{
+ CUBE( ( "users"."name" ), ( "users"."bool", "users"."created_at" ) )
+ }
+ end
+ end
+
+ describe "Nodes::GroupingSet" do
+ it "should know how to visit with array arguments" do
+ node = Arel::Nodes::GroupingSet.new([@table[:name], @table[:bool]])
+ compile(node).must_be_like %{
+ GROUPING SET( "users"."name", "users"."bool" )
+ }
+ end
+
+ it "should know how to visit with CubeDimension Argument" do
+ group = Arel::Nodes::GroupingElement.new([@table[:name], @table[:bool]])
+ node = Arel::Nodes::GroupingSet.new(group)
+ compile(node).must_be_like %{
+ GROUPING SET( "users"."name", "users"."bool" )
+ }
+ end
+
+ it "should know how to generate paranthesis when supplied with many Dimensions" do
+ group1 = Arel::Nodes::GroupingElement.new(@table[:name])
+ group2 = Arel::Nodes::GroupingElement.new([@table[:bool], @table[:created_at]])
+ node = Arel::Nodes::GroupingSet.new([group1, group2])
+ compile(node).must_be_like %{
+ GROUPING SET( ( "users"."name" ), ( "users"."bool", "users"."created_at" ) )
+ }
+ end
+ end
+
+ describe "Nodes::RollUp" do
+ it "should know how to visit with array arguments" do
+ node = Arel::Nodes::RollUp.new([@table[:name], @table[:bool]])
+ compile(node).must_be_like %{
+ ROLLUP( "users"."name", "users"."bool" )
+ }
+ end
+
+ it "should know how to visit with CubeDimension Argument" do
+ group = Arel::Nodes::GroupingElement.new([@table[:name], @table[:bool]])
+ node = Arel::Nodes::RollUp.new(group)
+ compile(node).must_be_like %{
+ ROLLUP( "users"."name", "users"."bool" )
+ }
+ end
+
+ it "should know how to generate paranthesis when supplied with many Dimensions" do
+ group1 = Arel::Nodes::GroupingElement.new(@table[:name])
+ group2 = Arel::Nodes::GroupingElement.new([@table[:bool], @table[:created_at]])
+ node = Arel::Nodes::RollUp.new([group1, group2])
+ compile(node).must_be_like %{
+ ROLLUP( ( "users"."name" ), ( "users"."bool", "users"."created_at" ) )
+ }
+ end
+ end
end
end
end
diff --git a/test/visitors/test_to_sql.rb b/test/visitors/test_to_sql.rb
index 6da86c2dee..6833d4e8f5 100644
--- a/test/visitors/test_to_sql.rb
+++ b/test/visitors/test_to_sql.rb
@@ -695,7 +695,7 @@ module Arel
it 'supports #when with two arguments and no #then' do
node = Arel::Nodes::Case.new @table[:name]
- { foo: 1, bar: 0 }.reduce(node) { |node, pair| node.when *pair }
+ { foo: 1, bar: 0 }.reduce(node) { |_node, pair| _node.when(*pair) }
compile(node).must_be_like %{
CASE "users"."name" WHEN 'foo' THEN 1 WHEN 'bar' THEN 0 END