diff options
author | Raimonds Simanovskis <raimonds.simanovskis@gmail.com> | 2010-11-16 12:45:29 +0200 |
---|---|---|
committer | Raimonds Simanovskis <raimonds.simanovskis@gmail.com> | 2010-11-16 12:45:29 +0200 |
commit | 237e580c4920b2414ef1bb72c14250688b479b9e (patch) | |
tree | 9387b40c4dfd18fae7e6bad97cb4fde2883431f9 | |
parent | ee30881b5aa0a545e6624bd343ae2646061e7107 (diff) | |
download | rails-237e580c4920b2414ef1bb72c14250688b479b9e.tar.gz rails-237e580c4920b2414ef1bb72c14250688b479b9e.tar.bz2 rails-237e580c4920b2414ef1bb72c14250688b479b9e.zip |
fix one more time order_hacks method for Oracle
correctly split order string by commas ignoring commas which separate function arguments
-rw-r--r-- | lib/arel/visitors/oracle.rb | 25 | ||||
-rw-r--r-- | test/visitors/test_oracle.rb | 12 |
2 files changed, 29 insertions, 8 deletions
diff --git a/lib/arel/visitors/oracle.rb b/lib/arel/visitors/oracle.rb index bb6ebd4ab8..00572213e6 100644 --- a/lib/arel/visitors/oracle.rb +++ b/lib/arel/visitors/oracle.rb @@ -70,19 +70,14 @@ module Arel /DISTINCT.*FIRST_VALUE/ === projection end end - # FIXME: previous version with join and split broke ORDER BY clause + # Previous version with join and split broke ORDER BY clause # if it contained functions with several arguments (separated by ','). - # Currently splitting is done only if there is no function calls # # orders = o.orders.map { |x| visit x }.join(', ').split(',') orders = o.orders.map do |x| string = visit x - # if there is function call - if string.include?('(') - string - # if no function call then comma splits several ORDER BY columns - elsif string.include?(',') - string.split(',') + if string.include?(',') + split_order_string(string) else string end @@ -94,6 +89,20 @@ module Arel end o end + + # Split string by commas but count opening and closing brackets + # and ignore commas inside brackets. + def split_order_string(string) + array = [] + i = 0 + string.split(',').each do |part| + array[i] ||= "" + array[i] << part + i += 1 if array[i].count('(') == array[i].count(')') + end + array + end + end end end diff --git a/test/visitors/test_oracle.rb b/test/visitors/test_oracle.rb index d2a73ea8c5..2c9bba15d8 100644 --- a/test/visitors/test_oracle.rb +++ b/test/visitors/test_oracle.rb @@ -43,6 +43,18 @@ module Arel } end + it 'splits orders with commas and function calls' do + # *sigh* + select = "DISTINCT foo.id, FIRST_VALUE(projects.name) OVER (foo) AS alias_0__" + stmt = Nodes::SelectStatement.new + stmt.cores.first.projections << Nodes::SqlLiteral.new(select) + stmt.orders << Nodes::SqlLiteral.new('NVL(LOWER(bar, foo), foo) DESC, UPPER(baz)') + sql = @visitor.accept(stmt) + sql.must_be_like %{ + SELECT #{select} ORDER BY alias_0__ DESC, alias_1__ + } + end + describe 'Nodes::SelectStatement' do describe 'limit' do it 'adds a rownum clause' do |