123456789_123456789_123456789_123456789_123456789_

Class: Arel::Visitors::ToSql

Do not use. This class is for internal use only.
Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Subclasses:
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, Visitor
Instance Chain:
self, Visitor
Inherits: Arel::Visitors::Visitor
Defined in: activerecord/lib/arel/visitors/to_sql.rb

Constant Summary

Class Method Summary

Instance Attribute Summary

Visitor - Inherited

Instance Method Summary

Visitor - Inherited

Constructor Details

.new(connection) ⇒ ToSql

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 12

def initialize(connection)
  super()
  @connection = connection
end

Instance Method Details

#aggregate(name, o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 983

def aggregate(name, o, collector)
  collector << "#{name}("
  if o.distinct
    collector << "DISTINCT "
  end
  collector = inject_join(o.expressions, collector, ", ") << ")"
  if o.alias
    collector << " AS "
    visit o.alias, collector
  else
    collector
  end
end

#bind_block (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 759

def bind_block; BIND_BLOCK; end

#build_subselect(key, o) (private)

FIXME: we should probably have a 2-pass visitor for this

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 946

def build_subselect(key, o)
  stmt             = Nodes::SelectStatement.new
  core             = stmt.cores.first
  core.froms       = o.relation
  core.wheres      = o.wheres
  core.projections = [key]
  core.groups      = o.groups unless o.groups.empty?
  core.havings     = o.havings unless o.havings.empty?
  stmt.limit       = o.limit
  stmt.offset      = o.offset
  stmt.orders      = o.orders
  stmt
end

#collect_ctes(children, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 1010

def collect_ctes(children, collector)
  children.each_with_index do |child, i|
    collector << ", " unless i == 0
    visit child.to_cte, collector
  end

  collector
end

#collect_nodes_for(nodes, collector, spacer, connector = ", ") (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 176

def collect_nodes_for(nodes, collector, spacer, connector = ", ")
  unless nodes.empty?
    collector << spacer
    inject_join nodes, collector, connector
  end
end

#collect_optimizer_hints(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 890

def collect_optimizer_hints(o, collector)
  maybe_visit o.optimizer_hints, collector
end

#compile(node, collector = Arel::Collectors::SQLString.new)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 17

def compile(node, collector = Arel::Collectors::SQLString.new)
  accept(node, collector).value
end

#has_group_by_and_having?(o) ⇒ Boolean (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 920

def has_group_by_and_having?(o)
  !o.groups.empty? && !o.havings.empty?
end

#has_join_sources?(o) ⇒ Boolean (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 912

def has_join_sources?(o)
  o.relation.is_a?(Nodes::JoinSource) && !o.relation.right.empty?
end

#has_limit_or_offset_or_orders?(o) ⇒ Boolean (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 916

def has_limit_or_offset_or_orders?(o)
  o.limit || o.offset || !o.orders.empty?
end

#infix_value(o, collector, value) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 960

def infix_value(o, collector, value)
  collector = visit o.left, collector
  collector << value
  visit o.right, collector
end

#infix_value_with_paren(o, collector, value, suppress_parens = false) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 966

def infix_value_with_paren(o, collector, value, suppress_parens = false)
  collector << "( " unless suppress_parens
  collector = if o.left.class == o.class
    infix_value_with_paren(o.left, collector, value, true)
  else
    visit o.left, collector
  end
  collector << value
  collector = if o.right.class == o.class
    infix_value_with_paren(o.right, collector, value, true)
  else
    visit o.right, collector
  end
  collector << " )" unless suppress_parens
  collector
end

#inject_join(list, collector, join_str) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 900

def inject_join(list, collector, join_str)
  list.each_with_index do |x, i|
    collector << join_str unless i == 0
    collector = visit(x, collector)
  end
  collector
end

#is_distinct_from(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 997

def is_distinct_from(o, collector)
  collector << "CASE WHEN "
  collector = visit o.left, collector
  collector << " = "
  collector = visit o.right, collector
  collector << " OR ("
  collector = visit o.left, collector
  collector << " IS NULL AND "
  collector = visit o.right, collector
  collector << " IS NULL)"
  collector << " THEN 0 ELSE 1 END"
end

#maybe_visit(thing, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 894

def maybe_visit(thing, collector)
  return collector unless thing
  collector << " "
  visit thing, collector
end

#prepare_delete_statement(o) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 943

alias :prepare_delete_statement :prepare_update_statement

#prepare_update_statement(o) (private) Also known as: #prepare_delete_statement

The default strategy for an UPDATE with joins is to use a subquery. This doesnā€™t work on MySQL (even when aliasing the tables), but MySQL allows using JOIN directly in an UPDATE statement, so in the MySQL visitor we redefine this to do that.

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 927

def prepare_update_statement(o)
  if o.key && (has_limit_or_offset_or_orders?(o) || has_join_sources?(o))
    stmt = o.clone
    stmt.limit = nil
    stmt.offset = nil
    stmt.orders = []
    columns = Arel::Nodes::Grouping.new(o.key)
    stmt.wheres = [Nodes::In.new(columns, [build_subselect(o.key, o)])]
    stmt.relation = o.relation.left if has_join_sources?(o)
    stmt.groups = o.groups unless o.groups.empty?
    stmt.havings = o.havings unless o.havings.empty?
    stmt
  else
    o
  end
end

#quote(value) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 870

def quote(value)
  return value if Arel::Nodes::SqlLiteral === value
  @connection.quote value
end

#quote_column_name(name) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 880

def quote_column_name(name)
  return name if Arel::Nodes::SqlLiteral === name
  @connection.quote_column_name(name)
end

#quote_table_name(name) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 875

def quote_table_name(name)
  return name if Arel::Nodes::SqlLiteral === name
  @connection.quote_table_name(name)
end

#sanitize_as_sql_comment(value) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 885

def sanitize_as_sql_comment(value)
  return value if Arel::Nodes::SqlLiteral === value
  @connection.sanitize_as_sql_comment(value)
end

#unboundable?(value) ⇒ Boolean (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 908

def unboundable?(value)
  value.respond_to?(:unboundable?) && value.unboundable?
end

#unsupported(o, collector) (private) Also known as: #visit_ActiveSupport_Multibyte_Chars, #visit_ActiveSupport_StringInquirer, #visit_BigDecimal, #visit_Class, #visit_Date, #visit_DateTime, #visit_FalseClass, #visit_Float, #visit_Hash, #visit_NilClass, #visit_String, #visit_Symbol, #visit_Time, #visit_TrueClass

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 831

def unsupported(o, collector)
  raise UnsupportedVisitError.new(o)
end

#visit_ActiveModel_Attribute(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 761

def visit_ActiveModel_Attribute(o, collector)
  collector.add_bind(o, &bind_block)
end

#visit_ActiveSupport_Multibyte_Chars(o, collector) (private)

Alias for #unsupported.

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 835

alias :visit_ActiveSupport_Multibyte_Chars :unsupported

#visit_ActiveSupport_StringInquirer(o, collector) (private)

Alias for #unsupported.

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 836

alias :visit_ActiveSupport_StringInquirer  :unsupported

#visit_Arel_Attributes_Attribute(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 751

def visit_Arel_Attributes_Attribute(o, collector)
  join_name = o.relation.table_alias || o.relation.name
  collector << quote_table_name(join_name) << "." << quote_column_name(o.name)
end

#visit_Arel_Nodes_And(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 616

def visit_Arel_Nodes_And(o, collector)
  inject_join o.children, collector, " AND "
end

#visit_Arel_Nodes_As(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 698

def visit_Arel_Nodes_As(o, collector)
  collector = visit o.left, collector
  collector << " AS "
  visit o.right, collector
end

#visit_Arel_Nodes_Ascending(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 360

def visit_Arel_Nodes_Ascending(o, collector)
  visit(o.expr, collector) << " ASC"
end

#visit_Arel_Nodes_Assignment(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 635

def visit_Arel_Nodes_Assignment(o, collector)
  case o.right
  when Arel::Nodes::Node, Arel::Attributes::Attribute, ActiveModel::Attribute
    collector = visit o.left, collector
    collector << " = "
    visit o.right, collector
  else
    collector = visit o.left, collector
    collector << " = "
    collector << quote(o.right).to_s
  end
end

#visit_Arel_Nodes_Avg(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 417

def visit_Arel_Nodes_Avg(o, collector)
  aggregate "AVG", o, collector
end

#visit_Arel_Nodes_Between(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 427

def visit_Arel_Nodes_Between(o, collector)
  collector = visit o.left, collector
  collector << " BETWEEN "
  visit o.right, collector
end

#visit_Arel_Nodes_Bin(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 183

def visit_Arel_Nodes_Bin(o, collector)
  visit o.expr, collector
end

#visit_Arel_Nodes_BindParam(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 765

def visit_Arel_Nodes_BindParam(o, collector)
  collector.add_bind(o.value, &bind_block)
end

#visit_Arel_Nodes_BoundSqlLiteral(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 774

def visit_Arel_Nodes_BoundSqlLiteral(o, collector)
  bind_index = 0

  new_bind = lambda do |value|
    if Arel.arel_node?(value)
      visit value, collector
    elsif value.is_a?(Array)
      if value.empty?
        collector << @connection.quote(nil)
      else
        if value.none? { |v| Arel.arel_node?(v) }
          collector.add_binds(value.map { |v| @connection.cast_bound_value(v) }, &bind_block)
        else
          value.each_with_index do |v, i|
            collector << ", " unless i == 0
            if Arel.arel_node?(v)
              visit v, collector
            else
              collector.add_bind(@connection.cast_bound_value(v), &bind_block)
            end
          end
        end
      end
    else
      collector.add_bind(@connection.cast_bound_value(value), &bind_block)
    end
  end

  if o.positional_binds
    o.sql_with_placeholders.scan(/\?|([^?]+)/) do
      if $1
        collector << $1
      else
        value = o.positional_binds[bind_index]
        bind_index += 1

        new_bind.call(value)
      end
    end
  else
    o.sql_with_placeholders.scan(/:(?<!::)([a-zA-Z]\w*)|([^:]+|.)/) do
      if $2
        collector << $2
      else
        value = o.named_binds[$1.to_sym]
        new_bind.call(value)
      end
    end
  end

  collector
end

#visit_Arel_Nodes_Case(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 704

def visit_Arel_Nodes_Case(o, collector)
  collector << "CASE "
  if o.case
    visit o.case, collector
    collector << " "
  end
  o.conditions.each do |condition|
    visit condition, collector
    collector << " "
  end
  if o.default
    visit o.default, collector
    collector << " "
  end
  collector << "END"
end

#visit_Arel_Nodes_Casted(o, collector) (private) Also known as: #visit_Arel_Nodes_Quoted

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 84

def visit_Arel_Nodes_Casted(o, collector)
  collector << quote(o.value_for_database).to_s
end

#visit_Arel_Nodes_Comment(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 172

def visit_Arel_Nodes_Comment(o, collector)
  collector << o.values.map { |v| "/* #{sanitize_as_sql_comment(v)} */" }.join(" ")
end

#visit_Arel_Nodes_Count(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 401

def visit_Arel_Nodes_Count(o, collector)
  aggregate "COUNT", o, collector
end

#visit_Arel_Nodes_Cte(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 737

def visit_Arel_Nodes_Cte(o, collector)
  collector << quote_table_name(o.name)
  collector << " AS "

  case o.materialized
  when true
    collector << "MATERIALIZED "
  when false
    collector << "NOT MATERIALIZED "
  end

  visit o.relation, collector
end

#visit_Arel_Nodes_CurrentRow(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 293

def visit_Arel_Nodes_CurrentRow(o, collector)
  collector << "CURRENT ROW"
end

#visit_Arel_Nodes_DeleteStatement(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 22

def visit_Arel_Nodes_DeleteStatement(o, collector)
  o = prepare_delete_statement(o)

  if has_join_sources?(o)
    collector << "DELETE "
    visit o.relation.left, collector
    collector << " FROM "
  else
    collector << "DELETE FROM "
  end
  collector = visit o.relation, collector

  collect_nodes_for o.wheres, collector, " WHERE ", " AND "
  collect_nodes_for o.orders, collector, " ORDER BY "
  maybe_visit o.limit, collector
end

#visit_Arel_Nodes_Descending(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 364

def visit_Arel_Nodes_Descending(o, collector)
  visit(o.expr, collector) << " DESC"
end

#visit_Arel_Nodes_Distinct(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 187

def visit_Arel_Nodes_Distinct(o, collector)
  collector << "DISTINCT"
end

#visit_Arel_Nodes_DistinctOn(o, collector) (private)

Raises:

  • (NotImplementedError)
[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 191

def visit_Arel_Nodes_DistinctOn(o, collector)
  raise NotImplementedError, "DISTINCT ON not implemented for this db"
end

#visit_Arel_Nodes_DoesNotMatch(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 493

def visit_Arel_Nodes_DoesNotMatch(o, collector)
  collector = visit o.left, collector
  collector << " NOT LIKE "
  collector = visit o.right, collector
  if o.escape
    collector << " ESCAPE "
    visit o.escape, collector
  else
    collector
  end
end

#visit_Arel_Nodes_Else(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 728

def visit_Arel_Nodes_Else(o, collector)
  collector << "ELSE "
  visit o.expr, collector
end

#visit_Arel_Nodes_Equality(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 648

def visit_Arel_Nodes_Equality(o, collector)
  right = o.right

  return collector << "1=0" if unboundable?(right)

  collector = visit o.left, collector

  if right.nil?
    collector << " IS NULL"
  else
    collector << " = "
    visit right, collector
  end
end

#visit_Arel_Nodes_Except(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 218

def visit_Arel_Nodes_Except(o, collector)
  collector << "( "
  infix_value(o, collector, " EXCEPT ") << " )"
end

#visit_Arel_Nodes_Exists(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 73

def visit_Arel_Nodes_Exists(o, collector)
  collector << "EXISTS ("
  collector = visit(o.expressions, collector) << ")"
  if o.alias
    collector << " AS "
    visit o.alias, collector
  else
    collector
  end
end

#visit_Arel_Nodes_Extract(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 396

def visit_Arel_Nodes_Extract(o, collector)
  collector << "EXTRACT(#{o.field.to_s.upcase} FROM "
  visit(o.expr, collector) << ")"
end

#visit_Arel_Nodes_False(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 93

def visit_Arel_Nodes_False(o, collector)
  collector << "FALSE"
end

#visit_Arel_Nodes_Filter(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 248

def visit_Arel_Nodes_Filter(o, collector)
  visit o.left, collector
  collector << " FILTER (WHERE "
  visit o.right, collector
  collector << ")"
end

#visit_Arel_Nodes_Following(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 283

def visit_Arel_Nodes_Following(o, collector)
  collector = if o.expr
    visit o.expr, collector
  else
    collector << "UNBOUNDED"
  end

  collector << " FOLLOWING"
end

#visit_Arel_Nodes_Fragments(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 866

def visit_Arel_Nodes_Fragments(o, collector)
  inject_join o.values, collector, " "
end

#visit_Arel_Nodes_FullOuterJoin(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 528

def visit_Arel_Nodes_FullOuterJoin(o, collector)
  collector << "FULL OUTER JOIN "
  collector = visit o.left, collector
  collector << " "
  visit o.right, collector
end

#visit_Arel_Nodes_GreaterThan(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 445

def visit_Arel_Nodes_GreaterThan(o, collector)
  case unboundable?(o.right)
  when 1
    return collector << "1=0"
  when -1
    return collector << "1=1"
  end
  collector = visit o.left, collector
  collector << " > "
  visit o.right, collector
end

#visit_Arel_Nodes_GreaterThanOrEqual(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 433

def visit_Arel_Nodes_GreaterThanOrEqual(o, collector)
  case unboundable?(o.right)
  when 1
    return collector << "1=0"
  when -1
    return collector << "1=1"
  end
  collector = visit o.left, collector
  collector << " >= "
  visit o.right, collector
end

#visit_Arel_Nodes_Group(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 379

def visit_Arel_Nodes_Group(o, collector)
  visit o.expr, collector
end

#visit_Arel_Nodes_Grouping(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 324

def visit_Arel_Nodes_Grouping(o, collector)
  if o.expr.is_a? Nodes::Grouping
    visit(o.expr, collector)
  else
    collector << "("
    visit(o.expr, collector) << ")"
  end
end

#visit_Arel_Nodes_HomogeneousIn(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 333

def visit_Arel_Nodes_HomogeneousIn(o, collector)
  collector.preparable = false

  visit o.left, collector

  if o.type == :in
    collector << " IN ("
  else
    collector << " NOT IN ("
  end

  values = o.casted_values

  if values.empty?
    collector << @connection.quote(nil)
  else
    collector.add_binds(values, o.proc_for_binds, &bind_block)
  end

  collector << ")"
end

#visit_Arel_Nodes_In(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 584

def visit_Arel_Nodes_In(o, collector)
  collector.preparable = false
  attr, values = o.left, o.right

  if Array === values
    unless values.empty?
      values.delete_if { |value| unboundable?(value) }
    end

    return collector << "1=0" if values.empty?
  end

  visit(attr, collector) << " IN ("
  visit(values, collector) << ")"
end

#visit_Arel_Nodes_InfixOperation(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 850

def visit_Arel_Nodes_InfixOperation(o, collector)
  collector = visit o.left, collector
  collector << " #{o.operator} "
  visit o.right, collector
end

#visit_Arel_Nodes_InnerJoin(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 549

def visit_Arel_Nodes_InnerJoin(o, collector)
  collector << "INNER JOIN "
  collector = visit o.left, collector
  if o.right
    collector << " "
    visit(o.right, collector)
  else
    collector
  end
end

#visit_Arel_Nodes_InsertStatement(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 51

def visit_Arel_Nodes_InsertStatement(o, collector)
  collector << "INSERT INTO "
  collector = visit o.relation, collector

  unless o.columns.empty?
    collector << " ("
    o.columns.each_with_index do |x, i|
      collector << ", " unless i == 0
      collector << quote_column_name(x.name)
    end
    collector << ")"
  end

  if o.values
    maybe_visit o.values, collector
  elsif o.select
    maybe_visit o.select, collector
  else
    collector
  end
end

#visit_Arel_Nodes_Intersect(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 213

def visit_Arel_Nodes_Intersect(o, collector)
  collector << "( "
  infix_value(o, collector, " INTERSECT ") << " )"
end

#visit_Arel_Nodes_IsDistinctFrom(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 673

def visit_Arel_Nodes_IsDistinctFrom(o, collector)
  if o.right.nil?
    collector = visit o.left, collector
    collector << " IS NOT NULL"
  else
    collector = is_distinct_from(o, collector)
    collector << " = 1"
  end
end

#visit_Arel_Nodes_IsNotDistinctFrom(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 663

def visit_Arel_Nodes_IsNotDistinctFrom(o, collector)
  if o.right.nil?
    collector = visit o.left, collector
    collector << " IS NULL"
  else
    collector = is_distinct_from(o, collector)
    collector << " = 0"
  end
end

#visit_Arel_Nodes_JoinSource(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 505

def visit_Arel_Nodes_JoinSource(o, collector)
  if o.left
    collector = visit o.left, collector
  end
  if o.right.any?
    collector << " " if o.left
    collector = inject_join o.right, collector, " "
  end
  collector
end

#visit_Arel_Nodes_LessThan(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 469

def visit_Arel_Nodes_LessThan(o, collector)
  case unboundable?(o.right)
  when 1
    return collector << "1=1"
  when -1
    return collector << "1=0"
  end
  collector = visit o.left, collector
  collector << " < "
  visit o.right, collector
end

#visit_Arel_Nodes_LessThanOrEqual(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 457

def visit_Arel_Nodes_LessThanOrEqual(o, collector)
  case unboundable?(o.right)
  when 1
    return collector << "1=1"
  when -1
    return collector << "1=0"
  end
  collector = visit o.left, collector
  collector << " <= "
  visit o.right, collector
end

#visit_Arel_Nodes_Limit(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 315

def visit_Arel_Nodes_Limit(o, collector)
  collector << "LIMIT "
  visit o.expr, collector
end

#visit_Arel_Nodes_Lock(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 320

def visit_Arel_Nodes_Lock(o, collector)
  visit o.expr, collector
end

#visit_Arel_Nodes_Matches(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 481

def visit_Arel_Nodes_Matches(o, collector)
  collector = visit o.left, collector
  collector << " LIKE "
  collector = visit o.right, collector
  if o.escape
    collector << " ESCAPE "
    visit o.escape, collector
  else
    collector
  end
end

#visit_Arel_Nodes_Max(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 409

def visit_Arel_Nodes_Max(o, collector)
  aggregate "MAX", o, collector
end

#visit_Arel_Nodes_Min(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 413

def visit_Arel_Nodes_Min(o, collector)
  aggregate "MIN", o, collector
end

#visit_Arel_Nodes_NamedFunction(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 383

def visit_Arel_Nodes_NamedFunction(o, collector)
  collector << o.name
  collector << "("
  collector << "DISTINCT " if o.distinct
  collector = inject_join(o.expressions, collector, ", ") << ")"
  if o.alias
    collector << " AS "
    visit o.alias, collector
  else
    collector
  end
end

#visit_Arel_Nodes_NamedWindow(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 223

def visit_Arel_Nodes_NamedWindow(o, collector)
  collector << quote_column_name(o.name)
  collector << " AS "
  visit_Arel_Nodes_Window o, collector
end

#visit_Arel_Nodes_Not(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 565

def visit_Arel_Nodes_Not(o, collector)
  collector << "NOT ("
  visit(o.expr, collector) << ")"
end

#visit_Arel_Nodes_NotEqual(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 683

def visit_Arel_Nodes_NotEqual(o, collector)
  right = o.right

  return collector << "1=1" if unboundable?(right)

  collector = visit o.left, collector

  if right.nil?
    collector << " IS NOT NULL"
  else
    collector << " != "
    visit right, collector
  end
end

#visit_Arel_Nodes_NotIn(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 600

def visit_Arel_Nodes_NotIn(o, collector)
  collector.preparable = false
  attr, values = o.left, o.right

  if Array === values
    unless values.empty?
      values.delete_if { |value| unboundable?(value) }
    end

    return collector << "1=1" if values.empty?
  end

  visit(attr, collector) << " NOT IN ("
  visit(values, collector) << ")"
end

#visit_Arel_Nodes_NotRegexp(o, collector) (private)

Raises:

  • (NotImplementedError)
[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 520

def visit_Arel_Nodes_NotRegexp(o, collector)
  raise NotImplementedError, "!~ not implemented for this db"
end

#visit_Arel_Nodes_NullsFirst(o, collector) (private)

NullsFirst is available on all but MySQL, where it is redefined.

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 369

def visit_Arel_Nodes_NullsFirst(o, collector)
  visit o.expr, collector
  collector << " NULLS FIRST"
end

#visit_Arel_Nodes_NullsLast(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 374

def visit_Arel_Nodes_NullsLast(o, collector)
  visit o.expr, collector
  collector << " NULLS LAST"
end

#visit_Arel_Nodes_Offset(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 310

def visit_Arel_Nodes_Offset(o, collector)
  collector << "OFFSET "
  visit o.expr, collector
end

#visit_Arel_Nodes_On(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 560

def visit_Arel_Nodes_On(o, collector)
  collector << "ON "
  visit o.expr, collector
end

#visit_Arel_Nodes_OptimizerHints(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 167

def visit_Arel_Nodes_OptimizerHints(o, collector)
  hints = o.expr.map { |v| sanitize_as_sql_comment(v) }.join(" ")
  collector << "/*+ #{hints} */"
end

#visit_Arel_Nodes_Or(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 620

def visit_Arel_Nodes_Or(o, collector)
  stack = [o.right, o.left]

  while o = stack.pop
    if o.is_a?(Arel::Nodes::Or)
      stack.push o.right, o.left
    else
      visit o, collector
      collector << " OR " unless stack.empty?
    end
  end

  collector
end

#visit_Arel_Nodes_OuterJoin(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 535

def visit_Arel_Nodes_OuterJoin(o, collector)
  collector << "LEFT OUTER JOIN "
  collector = visit o.left, collector
  collector << " "
  visit o.right, collector
end

#visit_Arel_Nodes_Over(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 297

def visit_Arel_Nodes_Over(o, collector)
  case o.right
  when nil
    visit(o.left, collector) << " OVER ()"
  when Arel::Nodes::SqlLiteral
    infix_value o, collector, " OVER "
  when String, Symbol
    visit(o.left, collector) << " OVER #{quote_column_name o.right.to_s}"
  else
    infix_value o, collector, " OVER "
  end
end

#visit_Arel_Nodes_Preceding(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 273

def visit_Arel_Nodes_Preceding(o, collector)
  collector = if o.expr
    visit o.expr, collector
  else
    collector << "UNBOUNDED"
  end

  collector << " PRECEDING"
end

#visit_Arel_Nodes_Quoted(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 87

alias :visit_Arel_Nodes_Quoted :visit_Arel_Nodes_Casted

#visit_Arel_Nodes_Range(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 264

def visit_Arel_Nodes_Range(o, collector)
  if o.expr
    collector << "RANGE "
    visit o.expr, collector
  else
    collector << "RANGE"
  end
end

#visit_Arel_Nodes_Regexp(o, collector) (private)

Raises:

  • (NotImplementedError)
[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 516

def visit_Arel_Nodes_Regexp(o, collector)
  raise NotImplementedError, "~ not implemented for this db"
end

#visit_Arel_Nodes_RightOuterJoin(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 542

def visit_Arel_Nodes_RightOuterJoin(o, collector)
  collector << "RIGHT OUTER JOIN "
  collector = visit o.left, collector
  collector << " "
  visit o.right, collector
end

#visit_Arel_Nodes_Rows(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 255

def visit_Arel_Nodes_Rows(o, collector)
  if o.expr
    collector << "ROWS "
    visit o.expr, collector
  else
    collector << "ROWS"
  end
end

#visit_Arel_Nodes_SelectCore(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 146

def visit_Arel_Nodes_SelectCore(o, collector)
  collector << "SELECT"

  collector = collect_optimizer_hints(o, collector)
  collector = maybe_visit o.set_quantifier, collector

  collect_nodes_for o.projections, collector, " "

  if o.source && !o.source.empty?
    collector << " FROM "
    collector = visit o.source, collector
  end

  collect_nodes_for o.wheres, collector, " WHERE ", " AND "
  collect_nodes_for o.groups, collector, " GROUP BY "
  collect_nodes_for o.havings, collector, " HAVING ", " AND "
  collect_nodes_for o.windows, collector, " WINDOW "

  maybe_visit o.comment, collector
end

#visit_Arel_Nodes_SelectOptions(o, collector) (private)

The Oracle enhanced adapter uses this private method, see github.com/rsim/oracle-enhanced/issues/2186

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 140

def visit_Arel_Nodes_SelectOptions(o, collector)
  collector = maybe_visit o.limit, collector
  collector = maybe_visit o.offset, collector
  maybe_visit o.lock, collector
end

#visit_Arel_Nodes_SelectStatement(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 117

def visit_Arel_Nodes_SelectStatement(o, collector)
  if o.with
    collector = visit o.with, collector
    collector << " "
  end

  collector = o.cores.inject(collector) { |c, x|
    visit_Arel_Nodes_SelectCore(x, c)
  }

  unless o.orders.empty?
    collector << " ORDER BY "
    o.orders.each_with_index do |x, i|
      collector << ", " unless i == 0
      collector = visit(x, collector)
    end
  end

  visit_Arel_Nodes_SelectOptions(o, collector)
end

#visit_Arel_Nodes_SqlLiteral(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 769

def visit_Arel_Nodes_SqlLiteral(o, collector)
  collector.preparable = false
  collector << o.to_s
end

#visit_Arel_Nodes_StringJoin(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 524

def visit_Arel_Nodes_StringJoin(o, collector)
  visit o.left, collector
end

#visit_Arel_Nodes_Sum(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 405

def visit_Arel_Nodes_Sum(o, collector)
  aggregate "SUM", o, collector
end

#visit_Arel_Nodes_TableAlias(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 421

def visit_Arel_Nodes_TableAlias(o, collector)
  collector = visit o.relation, collector
  collector << " "
  collector << quote_table_name(o.name)
end

#visit_Arel_Nodes_True(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 89

def visit_Arel_Nodes_True(o, collector)
  collector << "TRUE"
end

#visit_Arel_Nodes_UnaryOperation(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 856

def visit_Arel_Nodes_UnaryOperation(o, collector)
  collector << " #{o.operator} "
  visit o.expr, collector
end

#visit_Arel_Nodes_Union(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 205

def visit_Arel_Nodes_Union(o, collector)
  infix_value_with_paren(o, collector, " UNION ")
end

#visit_Arel_Nodes_UnionAll(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 209

def visit_Arel_Nodes_UnionAll(o, collector)
  infix_value_with_paren(o, collector, " UNION ALL ")
end

#visit_Arel_Nodes_UnqualifiedColumn(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 733

def visit_Arel_Nodes_UnqualifiedColumn(o, collector)
  collector << quote_column_name(o.name)
end

#visit_Arel_Nodes_UpdateStatement(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 39

def visit_Arel_Nodes_UpdateStatement(o, collector)
  o = prepare_update_statement(o)

  collector << "UPDATE "
  collector = visit o.relation, collector
  collect_nodes_for o.values, collector, " SET "

  collect_nodes_for o.wheres, collector, " WHERE ", " AND "
  collect_nodes_for o.orders, collector, " ORDER BY "
  maybe_visit o.limit, collector
end

#visit_Arel_Nodes_ValuesList(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 97

def visit_Arel_Nodes_ValuesList(o, collector)
  collector << "VALUES "

  o.rows.each_with_index do |row, i|
    collector << ", " unless i == 0
    collector << "("
    row.each_with_index do |value, k|
      collector << ", " unless k == 0
      case value
      when Nodes::SqlLiteral, Nodes::BindParam, ActiveModel::Attribute
        collector = visit(value, collector)
      else
        collector << quote(value).to_s
      end
    end
    collector << ")"
  end
  collector
end

#visit_Arel_Nodes_When(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 721

def visit_Arel_Nodes_When(o, collector)
  collector << "WHEN "
  visit o.left, collector
  collector << " THEN "
  visit o.right, collector
end

#visit_Arel_Nodes_Window(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 229

def visit_Arel_Nodes_Window(o, collector)
  collector << "("

  collect_nodes_for o.partitions, collector, "PARTITION BY "

  if o.orders.any?
    collector << " " if o.partitions.any?
    collector << "ORDER BY "
    collector = inject_join o.orders, collector, ", "
  end

  if o.framing
    collector << " " if o.partitions.any? || o.orders.any?
    collector = visit o.framing, collector
  end

  collector << ")"
end

#visit_Arel_Nodes_With(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 195

def visit_Arel_Nodes_With(o, collector)
  collector << "WITH "
  collect_ctes(o.children, collector)
end

#visit_Arel_Nodes_WithRecursive(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 200

def visit_Arel_Nodes_WithRecursive(o, collector)
  collector << "WITH RECURSIVE "
  collect_ctes(o.children, collector)
end

#visit_Arel_SelectManager(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 355

def visit_Arel_SelectManager(o, collector)
  collector << "("
  visit(o.ast, collector) << ")"
end

#visit_Arel_Table(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 570

def visit_Arel_Table(o, collector)
  if Arel::Nodes::Node === o.name
    visit o.name, collector
  else
    collector << quote_table_name(o.name)
  end

  if o.table_alias
    collector << " " << quote_table_name(o.table_alias)
  end

  collector
end

#visit_Array(o, collector) (private) Also known as: #visit_Set

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 861

def visit_Array(o, collector)
  inject_join o, collector, ", "
end

#visit_BigDecimal(o, collector) (private)

Alias for #unsupported.

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 837

alias :visit_BigDecimal                    :unsupported

#visit_Class(o, collector) (private)

Alias for #unsupported.

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 838

alias :visit_Class                         :unsupported

#visit_Date(o, collector) (private)

Alias for #unsupported.

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 839

alias :visit_Date                          :unsupported

#visit_DateTime(o, collector) (private)

Alias for #unsupported.

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 840

alias :visit_DateTime                      :unsupported

#visit_FalseClass(o, collector) (private)

Alias for #unsupported.

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 841

alias :visit_FalseClass                    :unsupported

#visit_Float(o, collector) (private)

Alias for #unsupported.

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 842

alias :visit_Float                         :unsupported

#visit_Hash(o, collector) (private)

Alias for #unsupported.

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 843

alias :visit_Hash                          :unsupported

#visit_Integer(o, collector) (private)

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 827

def visit_Integer(o, collector)
  collector << o.to_s
end

#visit_NilClass(o, collector) (private)

Alias for #unsupported.

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 844

alias :visit_NilClass                      :unsupported

#visit_Set(o, collector) (private)

Alias for #visit_Array.

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 864

alias :visit_Set :visit_Array

#visit_String(o, collector) (private)

Alias for #unsupported.

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 845

alias :visit_String                        :unsupported

#visit_Symbol(o, collector) (private)

Alias for #unsupported.

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 846

alias :visit_Symbol                        :unsupported

#visit_Time(o, collector) (private)

Alias for #unsupported.

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 847

alias :visit_Time                          :unsupported

#visit_TrueClass(o, collector) (private)

Alias for #unsupported.

[ GitHub ]

  
# File 'activerecord/lib/arel/visitors/to_sql.rb', line 848

alias :visit_TrueClass                     :unsupported