Hacks for the order clauses specific to Oracle
# File lib/arel/visitors/oracle.rb, line 66
66: def order_hacks o
67: return o if o.orders.empty?
68: return o unless o.cores.any? do |core|
69: core.projections.any? do |projection|
70: /DISTINCT.*FIRST_VALUE/ === projection
71: end
72: end
73: # Previous version with join and split broke ORDER BY clause
74: # if it contained functions with several arguments (separated by ',').
75: #
76: # orders = o.orders.map { |x| visit x }.join(', ').split(',')
77: orders = o.orders.map do |x|
78: string = visit x
79: if string.include?(',')
80: split_order_string(string)
81: else
82: string
83: end
84: end.flatten
85: o.orders = []
86: orders.each_with_index do |order, i|
87: o.orders <<
88: Nodes::SqlLiteral.new("alias_#{i}__#{' DESC' if /\bdesc$/i === order}")
89: end
90: o
91: end
Split string by commas but count opening and closing brackets and ignore commas inside brackets.
# File lib/arel/visitors/oracle.rb, line 95
95: def split_order_string(string)
96: array = []
97: i = 0
98: string.split(',').each do |part|
99: if array[i]
100: array[i] << ',' << part
101: else
102: # to ensure that array[i] will be String and not Arel::Nodes::SqlLiteral
103: array[i] = '' << part
104: end
105: i += 1 if array[i].count('(') == array[i].count(')')
106: end
107: array
108: end
# File lib/arel/visitors/oracle.rb, line 60
60: def visit_Arel_Nodes_Offset o
61: "raw_rnum_ > #{visit o.value}"
62: end
# File lib/arel/visitors/oracle.rb, line 6
6: def visit_Arel_Nodes_SelectStatement o
7: o = order_hacks(o)
8:
9: # if need to select first records without ORDER BY and GROUP BY and without DISTINCT
10: # then can use simple ROWNUM in WHERE clause
11: if o.limit && o.orders.empty? && !o.offset && o.cores.first.projections.first !~ /^DISTINCT /
12: o.cores.last.wheres.push Nodes::LessThanOrEqual.new(
13: Nodes::SqlLiteral.new('ROWNUM'), o.limit
14: )
15: o.limit = nil
16: return super
17: end
18:
19: if o.limit && o.offset
20: o = o.dup
21: limit = o.limit.to_i
22: offset = o.offset
23: o.limit = nil
24: o.offset = nil
25: sql = super(o)
26: return SELECT * FROM ( SELECT raw_sql_.*, rownum raw_rnum_ FROM (#{sql}) raw_sql_ WHERE rownum <= #{offset.value.to_i + limit} ) WHERE #{visit offset}
27: end
28:
29: if o.limit
30: o = o.dup
31: limit = o.limit
32: o.limit = nil
33: return "SELECT * FROM (#{super(o)}) WHERE ROWNUM <= #{limit}"
34: end
35:
36: if o.offset
37: o = o.dup
38: offset = o.offset
39: o.offset = nil
40: sql = super(o)
41: return SELECT * FROM ( SELECT raw_sql_.*, rownum raw_rnum_ FROM (#{sql}) raw_sql_ ) WHERE #{visit offset}
42: end
43:
44: super
45: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.