diff options
-rw-r--r-- | Manifest.txt | 1 | ||||
-rw-r--r-- | README.markdown | 4 | ||||
-rw-r--r-- | arel.gemspec | 2 | ||||
-rw-r--r-- | lib/arel.rb | 1 | ||||
-rw-r--r-- | lib/arel/attributes/attribute.rb | 7 | ||||
-rw-r--r-- | lib/arel/expression.rb | 1 | ||||
-rw-r--r-- | lib/arel/factory_methods.rb | 6 | ||||
-rw-r--r-- | lib/arel/nodes.rb | 4 | ||||
-rw-r--r-- | lib/arel/nodes/select_core.rb | 17 | ||||
-rw-r--r-- | lib/arel/nodes/sql_literal.rb | 1 | ||||
-rw-r--r-- | lib/arel/nodes/terminal.rb | 6 | ||||
-rw-r--r-- | lib/arel/nodes/unary.rb | 1 | ||||
-rw-r--r-- | lib/arel/order_predications.rb | 13 | ||||
-rw-r--r-- | lib/arel/predications.rb | 24 | ||||
-rw-r--r-- | lib/arel/visitors/postgresql.rb | 27 | ||||
-rw-r--r-- | lib/arel/visitors/to_sql.rb | 13 | ||||
-rw-r--r-- | test/nodes/test_select_core.rb | 37 | ||||
-rw-r--r-- | test/test_attributes.rb | 8 | ||||
-rw-r--r-- | test/test_factory_methods.rb | 7 | ||||
-rw-r--r-- | test/test_select_manager.rb | 39 | ||||
-rw-r--r-- | test/visitors/test_oracle.rb | 4 | ||||
-rw-r--r-- | test/visitors/test_postgres.rb | 11 | ||||
-rw-r--r-- | test/visitors/test_to_sql.rb | 11 |
23 files changed, 171 insertions, 74 deletions
diff --git a/Manifest.txt b/Manifest.txt index f5fd7d7a80..1a448d7e8e 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -42,6 +42,7 @@ lib/arel/nodes/update_statement.rb lib/arel/nodes/values.rb lib/arel/nodes/with.rb lib/arel/predications.rb +lib/arel/order_predications.rb lib/arel/relation.rb lib/arel/select_manager.rb lib/arel/sql/engine.rb diff --git a/README.markdown b/README.markdown index eaefe2d694..eb6426b1ec 100644 --- a/README.markdown +++ b/README.markdown @@ -26,8 +26,8 @@ Generating a query with ARel is simple. For example, in order to produce you construct a table relation and convert it to sql: users = Arel::Table.new(:users) - users.project(Arel.sql('*')) - users.to_sql + query = users.project(Arel.sql('*')) + query.to_sql ### More Sophisticated Queries diff --git a/arel.gemspec b/arel.gemspec index 58cb8f61fb..8539f0ab4a 100644 --- a/arel.gemspec +++ b/arel.gemspec @@ -10,7 +10,7 @@ Gem::Specification.new do |s| s.description = %q{Arel is a Relational Algebra for Ruby. It 1) simplifies the generation complex of SQL queries and it 2) adapts to various RDBMS systems. It is intended to be a framework framework; that is, you can build your own ORM with it, focusing on innovative object and collection modeling as opposed to database 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", "History.txt", "MIT-LICENSE.txt", "Manifest.txt", "README.markdown", "Rakefile", "arel.gemspec", "lib/arel.rb", "lib/arel/attributes.rb", "lib/arel/attributes/attribute.rb", "lib/arel/compatibility/wheres.rb", "lib/arel/crud.rb", "lib/arel/delete_manager.rb", "lib/arel/deprecated.rb", "lib/arel/expression.rb", "lib/arel/expressions.rb", "lib/arel/factory_methods.rb", "lib/arel/insert_manager.rb", "lib/arel/nodes.rb", "lib/arel/nodes/and.rb", "lib/arel/nodes/binary.rb", "lib/arel/nodes/count.rb", "lib/arel/nodes/delete_statement.rb", "lib/arel/nodes/equality.rb", "lib/arel/nodes/function.rb", "lib/arel/nodes/in.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/ordering.rb", "lib/arel/nodes/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/unary.rb", "lib/arel/nodes/unqualified_column.rb", "lib/arel/nodes/update_statement.rb", "lib/arel/nodes/values.rb", "lib/arel/nodes/with.rb", "lib/arel/predications.rb", "lib/arel/relation.rb", "lib/arel/select_manager.rb", "lib/arel/sql/engine.rb", "lib/arel/sql_literal.rb", "lib/arel/table.rb", "lib/arel/tree_manager.rb", "lib/arel/update_manager.rb", "lib/arel/visitors.rb", "lib/arel/visitors/depth_first.rb", "lib/arel/visitors/dot.rb", "lib/arel/visitors/join_sql.rb", "lib/arel/visitors/mssql.rb", "lib/arel/visitors/mysql.rb", "lib/arel/visitors/oracle.rb", "lib/arel/visitors/order_clauses.rb", "lib/arel/visitors/postgresql.rb", "lib/arel/visitors/sqlite.rb", "lib/arel/visitors/to_sql.rb", "lib/arel/visitors/visitor.rb", "lib/arel/visitors/where_sql.rb", "test/attributes/test_attribute.rb", "test/helper.rb", "test/nodes/test_as.rb", "test/nodes/test_count.rb", "test/nodes/test_delete_statement.rb", "test/nodes/test_equality.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_select_core.rb", "test/nodes/test_select_statement.rb", "test/nodes/test_sql_literal.rb", "test/nodes/test_sum.rb", "test/nodes/test_update_statement.rb", "test/support/fake_record.rb", "test/test_activerecord_compat.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_depth_first.rb", "test/visitors/test_dot.rb", "test/visitors/test_join_sql.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", "History.txt", "MIT-LICENSE.txt", "Manifest.txt", "README.markdown", "Rakefile", "arel.gemspec", "lib/arel.rb", "lib/arel/attributes.rb", "lib/arel/attributes/attribute.rb", "lib/arel/compatibility/wheres.rb", "lib/arel/crud.rb", "lib/arel/delete_manager.rb", "lib/arel/deprecated.rb", "lib/arel/expression.rb", "lib/arel/expressions.rb", "lib/arel/factory_methods.rb", "lib/arel/insert_manager.rb", "lib/arel/nodes.rb", "lib/arel/nodes/and.rb", "lib/arel/nodes/binary.rb", "lib/arel/nodes/count.rb", "lib/arel/nodes/delete_statement.rb", "lib/arel/nodes/equality.rb", "lib/arel/nodes/function.rb", "lib/arel/nodes/in.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/ordering.rb", "lib/arel/nodes/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/unary.rb", "lib/arel/nodes/unqualified_column.rb", "lib/arel/nodes/update_statement.rb", "lib/arel/nodes/values.rb", "lib/arel/nodes/with.rb", "lib/arel/order_predications.rb", "lib/arel/predications.rb", "lib/arel/relation.rb", "lib/arel/select_manager.rb", "lib/arel/sql/engine.rb", "lib/arel/sql_literal.rb", "lib/arel/table.rb", "lib/arel/tree_manager.rb", "lib/arel/update_manager.rb", "lib/arel/visitors.rb", "lib/arel/visitors/depth_first.rb", "lib/arel/visitors/dot.rb", "lib/arel/visitors/join_sql.rb", "lib/arel/visitors/mssql.rb", "lib/arel/visitors/mysql.rb", "lib/arel/visitors/oracle.rb", "lib/arel/visitors/order_clauses.rb", "lib/arel/visitors/postgresql.rb", "lib/arel/visitors/sqlite.rb", "lib/arel/visitors/to_sql.rb", "lib/arel/visitors/visitor.rb", "lib/arel/visitors/where_sql.rb", "test/attributes/test_attribute.rb", "test/helper.rb", "test/nodes/test_as.rb", "test/nodes/test_count.rb", "test/nodes/test_delete_statement.rb", "test/nodes/test_equality.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_select_core.rb", "test/nodes/test_select_statement.rb", "test/nodes/test_sql_literal.rb", "test/nodes/test_sum.rb", "test/nodes/test_update_statement.rb", "test/support/fake_record.rb", "test/test_activerecord_compat.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_depth_first.rb", "test/visitors/test_dot.rb", "test/visitors/test_join_sql.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 = %q{http://github.com/rails/arel} s.rdoc_options = ["--main", "README.markdown"] s.require_paths = ["lib"] diff --git a/lib/arel.rb b/lib/arel.rb index de429f532e..bc599514e2 100644 --- a/lib/arel.rb +++ b/lib/arel.rb @@ -4,6 +4,7 @@ require 'arel/factory_methods' require 'arel/expressions' require 'arel/predications' require 'arel/math' +require 'arel/order_predications' require 'arel/table' require 'arel/attributes' require 'arel/compatibility/wheres' diff --git a/lib/arel/attributes/attribute.rb b/lib/arel/attributes/attribute.rb index 5aea87ac43..b9fd8da67e 100644 --- a/lib/arel/attributes/attribute.rb +++ b/lib/arel/attributes/attribute.rb @@ -3,7 +3,14 @@ module Arel class Attribute < Struct.new :relation, :name include Arel::Expressions include Arel::Predications + include Arel::OrderPredications include Arel::Math + + ### + # Create a node for lowering this attribute + def lower + relation.lower self + end end class String < Attribute; end diff --git a/lib/arel/expression.rb b/lib/arel/expression.rb index eb2c21bfd3..3884d6ede6 100644 --- a/lib/arel/expression.rb +++ b/lib/arel/expression.rb @@ -1,4 +1,5 @@ module Arel module Expression + include Arel::OrderPredications end end diff --git a/lib/arel/factory_methods.rb b/lib/arel/factory_methods.rb index 2ced1f8971..9fd0878ada 100644 --- a/lib/arel/factory_methods.rb +++ b/lib/arel/factory_methods.rb @@ -25,5 +25,11 @@ module Arel def grouping expr Nodes::Grouping.new expr end + + ### + # Create a LOWER() function + def lower column + Nodes::NamedFunction.new 'LOWER', [column] + end end end diff --git a/lib/arel/nodes.rb b/lib/arel/nodes.rb index cf2aeb2ddc..9576930a54 100644 --- a/lib/arel/nodes.rb +++ b/lib/arel/nodes.rb @@ -5,6 +5,10 @@ require 'arel/nodes/select_core' require 'arel/nodes/insert_statement' require 'arel/nodes/update_statement' +# terminal + +require 'arel/nodes/terminal' + # unary require 'arel/nodes/unary' require 'arel/nodes/unqualified_column' diff --git a/lib/arel/nodes/select_core.rb b/lib/arel/nodes/select_core.rb index 7f577e0a05..bee0a5930c 100644 --- a/lib/arel/nodes/select_core.rb +++ b/lib/arel/nodes/select_core.rb @@ -2,15 +2,18 @@ module Arel module Nodes class SelectCore < Arel::Nodes::Node attr_accessor :top, :projections, :wheres, :groups - attr_accessor :having, :source + attr_accessor :having, :source, :set_quantifier def initialize - @source = JoinSource.new nil - @top = nil - @projections = [] - @wheres = [] - @groups = [] - @having = nil + @source = JoinSource.new nil + @top = nil + + # http://savage.net.au/SQL/sql-92.bnf.html#set%20quantifier + @set_quantifier = nil + @projections = [] + @wheres = [] + @groups = [] + @having = nil end def from diff --git a/lib/arel/nodes/sql_literal.rb b/lib/arel/nodes/sql_literal.rb index c76a16daf1..ad0bb00484 100644 --- a/lib/arel/nodes/sql_literal.rb +++ b/lib/arel/nodes/sql_literal.rb @@ -3,6 +3,7 @@ module Arel class SqlLiteral < String include Arel::Expressions include Arel::Predications + include Arel::OrderPredications end end end diff --git a/lib/arel/nodes/terminal.rb b/lib/arel/nodes/terminal.rb new file mode 100644 index 0000000000..c6b4f4e1e2 --- /dev/null +++ b/lib/arel/nodes/terminal.rb @@ -0,0 +1,6 @@ +module Arel + module Nodes + class Distinct < Arel::Nodes::Node + end + end +end diff --git a/lib/arel/nodes/unary.rb b/lib/arel/nodes/unary.rb index 1c834913fa..5c4add4792 100644 --- a/lib/arel/nodes/unary.rb +++ b/lib/arel/nodes/unary.rb @@ -20,6 +20,7 @@ module Arel On Top Lock + DistinctOn }.each do |name| const_set(name, Class.new(Unary)) end diff --git a/lib/arel/order_predications.rb b/lib/arel/order_predications.rb new file mode 100644 index 0000000000..af163c9454 --- /dev/null +++ b/lib/arel/order_predications.rb @@ -0,0 +1,13 @@ +module Arel + module OrderPredications + + def asc + Nodes::Ordering.new self, :asc + end + + def desc + Nodes::Ordering.new self, :desc + end + + end +end diff --git a/lib/arel/predications.rb b/lib/arel/predications.rb index 75c4c75855..08cbf16d9d 100644 --- a/lib/arel/predications.rb +++ b/lib/arel/predications.rb @@ -1,5 +1,6 @@ module Arel module Predications + def as other Nodes::As.new self, Nodes::SqlLiteral.new(other) end @@ -152,32 +153,17 @@ module Arel grouping_all :lteq, others end - def asc - Nodes::Ordering.new self, :asc - end - - def desc - Nodes::Ordering.new self, :desc - end - private def grouping_any method_id, others - others = others.dup - first = send method_id, others.shift - - Nodes::Grouping.new others.inject(first) { |memo,expr| - Nodes::Or.new(memo, send(method_id, expr)) + nodes = others.map {|expr| send(method_id, expr)} + Nodes::Grouping.new nodes.inject { |memo,node| + Nodes::Or.new(memo, node) } end def grouping_all method_id, others - others = others.dup - first = send method_id, others.shift - - Nodes::Grouping.new others.inject(first) { |memo,expr| - Nodes::And.new([memo, send(method_id, expr)]) - } + Nodes::Grouping.new Nodes::And.new(others.map {|expr| send(method_id, expr)}) end end end diff --git a/lib/arel/visitors/postgresql.rb b/lib/arel/visitors/postgresql.rb index c423dc6fc6..377a65a216 100644 --- a/lib/arel/visitors/postgresql.rb +++ b/lib/arel/visitors/postgresql.rb @@ -6,25 +6,6 @@ module Arel visit o.expr end - def visit_Arel_Nodes_SelectStatement o - if !o.orders.empty? && using_distinct_on?(o) - subquery = o.dup - subquery.orders = [] - subquery.limit = nil - subquery.offset = nil - - sql = super(subquery) - [ - "SELECT * FROM (#{sql}) AS id_list", - "ORDER BY #{aliased_orders(o.orders).join(', ')}", - (visit(o.limit) if o.limit), - (visit(o.offset) if o.offset), - ].compact.join ' ' - else - super - end - end - def visit_Arel_Nodes_Matches o "#{visit o.left} ILIKE #{visit o.right}" end @@ -33,12 +14,8 @@ module Arel "#{visit o.left} NOT ILIKE #{visit o.right}" end - def using_distinct_on?(o) - o.cores.any? do |core| - core.projections.any? do |projection| - /DISTINCT ON/ === projection - end - end + def visit_Arel_Nodes_DistinctOn o + "DISTINCT ON ( #{visit o.expr} )" end def aliased_orders orders diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb index 061e46a436..73319364d5 100644 --- a/lib/arel/visitors/to_sql.rb +++ b/lib/arel/visitors/to_sql.rb @@ -125,8 +125,9 @@ key on UpdateManager using UpdateManager#key= [ "SELECT", (visit(o.top) if o.top), - "#{o.projections.map { |x| visit x }.join ', '}", - visit(o.source), + (visit(o.set_quantifier) if o.set_quantifier), + ("#{o.projections.map { |x| visit x }.join ', '}" unless o.projections.empty?), + (visit(o.source) if 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), @@ -137,6 +138,14 @@ key on UpdateManager using UpdateManager#key= visit o.expr end + def visit_Arel_Nodes_Distinct o + 'DISTINCT' + end + + def visit_Arel_Nodes_DistinctOn o + raise NotImplementedError, 'DISTINCT ON not implemented for this db' + end + def visit_Arel_Nodes_With o "WITH #{o.children.map { |x| visit x }.join(', ')}" end diff --git a/test/nodes/test_select_core.rb b/test/nodes/test_select_core.rb index 884d86e21f..47f85aee8a 100644 --- a/test/nodes/test_select_core.rb +++ b/test/nodes/test_select_core.rb @@ -1,22 +1,31 @@ require 'helper' -describe Arel::Nodes::SelectCore do - describe "#clone" do - it "clones froms, projections and wheres" do - core = Arel::Nodes::SelectCore.new - core.froms = %w[a b c] - core.projections = %w[d e f] - core.wheres = %w[g h i] +module Arel + module Nodes + class TestSelectCore < MiniTest::Unit::TestCase + def test_clone + core = Arel::Nodes::SelectCore.new + core.froms = %w[a b c] + core.projections = %w[d e f] + core.wheres = %w[g h i] - dolly = core.clone + dolly = core.clone - dolly.froms.must_equal core.froms - dolly.projections.must_equal core.projections - dolly.wheres.must_equal core.wheres + dolly.froms.must_equal core.froms + dolly.projections.must_equal core.projections + dolly.wheres.must_equal core.wheres - dolly.froms.wont_be_same_as core.froms - dolly.projections.wont_be_same_as core.projections - dolly.wheres.wont_be_same_as core.wheres + dolly.froms.wont_be_same_as core.froms + dolly.projections.wont_be_same_as core.projections + dolly.wheres.wont_be_same_as core.wheres + end + + def test_set_quantifier + core = Arel::Nodes::SelectCore.new + core.set_quantifier = Arel::Nodes::Distinct.new + viz = Arel::Visitors::ToSql.new Table.engine + assert_match 'DISTINCT', viz.accept(core) + end end end end diff --git a/test/test_attributes.rb b/test/test_attributes.rb index 3654e78314..010d708859 100644 --- a/test/test_attributes.rb +++ b/test/test_attributes.rb @@ -2,6 +2,14 @@ require 'helper' module Arel describe 'Attributes' do + it 'responds to lower' do + relation = Table.new(:users) + attribute = relation[:foo] + node = attribute.lower + assert_equal 'LOWER', node.name + assert_equal [attribute], node.expressions + end + describe 'for' do it 'deals with unknown column types' do column = Struct.new(:type).new :crazy diff --git a/test/test_factory_methods.rb b/test/test_factory_methods.rb index 6506d3c472..50f77c3175 100644 --- a/test/test_factory_methods.rb +++ b/test/test_factory_methods.rb @@ -22,6 +22,13 @@ module Arel assert_instance_of Nodes::On, on assert_equal :one, on.expr end + + def test_lower + lower = @factory.lower :one + assert_instance_of Nodes::NamedFunction, lower + assert_equal 'LOWER', lower.name + assert_equal [:one], lower.expressions + end end end end diff --git a/test/test_select_manager.rb b/test/test_select_manager.rb index 955d8e8d3a..29d317e16a 100644 --- a/test/test_select_manager.rb +++ b/test/test_select_manager.rb @@ -54,7 +54,7 @@ module Arel def test_join_sources manager = Arel::SelectManager.new Table.engine manager.join_sources << Arel::Nodes::StringJoin.new('foo') - assert_equal "SELECT FROM 'foo'", manager.to_sql + assert_equal "SELECT FROM 'foo'", manager.to_sql end describe 'backwards compatibility' do @@ -105,6 +105,18 @@ module Arel as = manager.as('foo') assert_kind_of Arel::Nodes::SqlLiteral, as.right end + + it 'can make a subselect' do + manager = Arel::SelectManager.new Table.engine + manager.project Arel.star + manager.from Arel.sql('zomg') + as = manager.as(Arel.sql('foo')) + + manager = Arel::SelectManager.new Table.engine + manager.project Arel.sql('name') + manager.from as + manager.to_sql.must_be_like "SELECT name FROM (SELECT * FROM zomg ) foo" + end end describe 'from' do @@ -204,7 +216,7 @@ module Arel table = Table.new :users, :engine => Table.engine, :as => 'foo' mgr = table.from table mgr.skip 10 - mgr.to_sql.must_be_like %{ SELECT FROM "users" "foo" OFFSET 10 } + mgr.to_sql.must_be_like %{ SELECT FROM "users" foo OFFSET 10 } end end @@ -472,6 +484,29 @@ module Arel manager = Arel::SelectManager.new Table.engine manager.order(table[:id]).must_equal manager end + + it 'has order attributes' do + table = Table.new :users + manager = Arel::SelectManager.new Table.engine + manager.project SqlLiteral.new '*' + manager.from table + manager.order table[:id].desc + manager.to_sql.must_be_like %{ + SELECT * FROM "users" ORDER BY "users"."id" DESC + } + end + + it 'has order attributes for expressions' do + table = Table.new :users + manager = Arel::SelectManager.new Table.engine + manager.project SqlLiteral.new '*' + manager.from table + manager.order table[:id].count.desc + manager.to_sql.must_be_like %{ + SELECT * FROM "users" ORDER BY COUNT("users"."id") DESC + } + end + end describe 'on' do diff --git a/test/visitors/test_oracle.rb b/test/visitors/test_oracle.rb index 87b94409e3..eaf68013a7 100644 --- a/test/visitors/test_oracle.rb +++ b/test/visitors/test_oracle.rb @@ -101,7 +101,7 @@ module Arel sql.must_be_like %{ SELECT * FROM ( SELECT raw_sql_.*, rownum raw_rnum_ - FROM (SELECT ) raw_sql_ + FROM (SELECT) raw_sql_ WHERE rownum <= 20 ) WHERE raw_rnum_ > 10 @@ -126,7 +126,7 @@ module Arel sql.must_be_like %{ SELECT * FROM ( SELECT raw_sql_.*, rownum raw_rnum_ - FROM (SELECT ) raw_sql_ + FROM (SELECT) raw_sql_ ) WHERE raw_rnum_ > 10 } diff --git a/test/visitors/test_postgres.rb b/test/visitors/test_postgres.rb index 74446c23ba..446eae0c4a 100644 --- a/test/visitors/test_postgres.rb +++ b/test/visitors/test_postgres.rb @@ -32,6 +32,17 @@ module Arel assert_equal 1, sql.scan(/LIMIT/).length, 'should have one limit' end + it 'should support DISTINCT ON' do + core = Arel::Nodes::SelectCore.new + core.set_quantifier = Arel::Nodes::DistinctOn.new(Arel.sql('aaron')) + assert_match 'DISTINCT ON ( aaron )', @visitor.accept(core) + end + + it 'should support DISTINCT' do + core = Arel::Nodes::SelectCore.new + core.set_quantifier = Arel::Nodes::Distinct.new + assert_equal 'SELECT DISTINCT', @visitor.accept(core) + end end end end diff --git a/test/visitors/test_to_sql.rb b/test/visitors/test_to_sql.rb index 25ff7be3e2..1d5f89280b 100644 --- a/test/visitors/test_to_sql.rb +++ b/test/visitors/test_to_sql.rb @@ -299,6 +299,17 @@ module Arel } end end + + describe 'distinct on' do + it 'raises not implemented error' do + core = Arel::Nodes::SelectCore.new + core.set_quantifier = Arel::Nodes::DistinctOn.new(Arel.sql('aaron')) + + assert_raises(NotImplementedError) do + @visitor.accept(core) + end + end + end end end end |