Class: Arel::SqlCompiler::OracleCompiler

Inherits:
GenericCompiler show all
Defined in:
lib/arel/engines/sql/compilers/oracle_compiler.rb

Instance Attribute Summary

Attributes inherited from GenericCompiler

#relation

Instance Method Summary collapse

Methods inherited from GenericCompiler

#add_limit_on_delete, #initialize, #insert_sql, #supports_insert_with_returning?, #update_sql

Constructor Details

This class inherits a constructor from Arel::SqlCompiler::GenericCompiler

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Arel::SqlCompiler::GenericCompiler

Instance Method Details

#delete_sqlObject



57
58
59
60
61
62
63
64
# File 'lib/arel/engines/sql/compilers/oracle_compiler.rb', line 57

def delete_sql
  where_clauses_array = wheres.collect(&:to_sql)
  where_clauses_array << "ROWNUM <= #{taken}" unless taken.blank?
  build_query \
    "DELETE",
    "FROM #{table_sql}",
    ("WHERE #{where_clauses_array.join(' AND ')}" unless where_clauses_array.blank? )
end

#select_sqlObject



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/arel/engines/sql/compilers/oracle_compiler.rb', line 5

def select_sql
  where_clauses_array = where_clauses
  if limit_or_offset = !taken.blank? || !skipped.blank?
    # if need to select first records without ORDER BY and GROUP BY
    # then can use simple ROWNUM in WHERE clause
    if skipped.blank? && groupings.blank? && orders.blank?
      where_clauses_array << "ROWNUM <= #{taken}" if !taken.blank? && skipped.blank? && groupings.blank? && orders.blank?
      limit_or_offset = false
    end
  end

  # when limit or offset subquery is used then cannot use FOR UPDATE directly
  # and need to construct separate subquery for primary key
  if use_subquery_for_lock = limit_or_offset && !locked.blank?
    quoted_primary_key = engine.quote_column_name(primary_key)
  end
  select_attributes_string = use_subquery_for_lock ? quoted_primary_key : select_clauses.join(', ')

  # OracleEnhanced adapter workaround when ORDER BY is used with columns not
  # present in DISTINCT columns list
  order_clauses_array = if select_attributes_string =~ /DISTINCT.*FIRST_VALUE/ && !orders.blank?
    order = order_clauses.join(', ').split(',').map { |s| s.strip }.reject(&:blank?)
    order = order.zip((0...order.size).to_a).map { |s,i| "alias_#{i}__ #{'DESC' if s =~ /\bdesc$/i}" }
  else
    order_clauses
  end

  query = build_query \
    "SELECT     #{select_attributes_string}",
    "FROM       #{from_clauses}",
    (joins(self)                                   unless joins(self).blank? ),
    ("WHERE     #{where_clauses_array.join(" AND ")}"    unless where_clauses_array.blank?      ),
    ("GROUP BY  #{group_clauses.join(', ')}"       unless groupings.blank?   ),
    ("HAVING    #{having_clauses.join(', ')}"      unless havings.blank?     ),
    ("ORDER BY  #{order_clauses_array.join(', ')}" unless order_clauses_array.blank? )

  # Use existing method from oracle_enhanced adapter to implement limit and offset using subqueries
  engine.add_limit_offset!(query, :limit => taken, :offset => skipped) if limit_or_offset

  if use_subquery_for_lock
    build_query \
      "SELECT     #{select_clauses.join(', ')}",
      "FROM       #{from_clauses}",
      "WHERE      #{quoted_primary_key} IN (#{query})",
      "#{locked}"
  elsif !locked.blank?
    build_query query, "#{locked}"
  else
    query
  end
end