1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

fix one more time order_hacks method for Oracle

correctly split order string by commas ignoring commas which separate function arguments
This commit is contained in:
Raimonds Simanovskis 2010-11-16 12:45:29 +02:00
parent ee30881b5a
commit 237e580c49
2 changed files with 29 additions and 8 deletions

View file

@ -70,19 +70,14 @@ module Arel
/DISTINCT.*FIRST_VALUE/ === projection /DISTINCT.*FIRST_VALUE/ === projection
end end
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 ','). # 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 { |x| visit x }.join(', ').split(',')
orders = o.orders.map do |x| orders = o.orders.map do |x|
string = visit x string = visit x
# if there is function call if string.include?(',')
if string.include?('(') split_order_string(string)
string
# if no function call then comma splits several ORDER BY columns
elsif string.include?(',')
string.split(',')
else else
string string
end end
@ -94,6 +89,20 @@ module Arel
end end
o o
end 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 end
end end

View file

@ -43,6 +43,18 @@ module Arel
} }
end 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 'Nodes::SelectStatement' do
describe 'limit' do describe 'limit' do
it 'adds a rownum clause' do it 'adds a rownum clause' do