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.