Class: Arel::Visitors::ToSql

Inherits:
Reduce show all
Defined in:
lib/arel/visitors/to_sql.rb

Direct Known Subclasses

IBM_DB, Informix, MSSQL, MySQL, Oracle, Oracle12, PostgreSQL, SQLite, WhereSql

Constant Summary collapse

WHERE =

This is some roflscale crazy stuff. I’m roflscaling this because building SQL queries is a hotspot. I will explain the roflscale so that others will not rm this code.

In YARV, string literals in a method body will get duped when the byte code is executed. Let’s take a look:

> puts RubyVM::InstructionSequence.new(‘def foo; “bar”; end’).disasm

== disasm: <RubyVM::InstructionSequence:foo@<compiled>>=====
 0000 trace            8
 0002 trace            1
 0004 putstring        "bar"
 0006 trace            16
 0008 leave

The ‘putstring` bytecode will dup the string and push it on the stack. In many cases in our SQL visitor, that string is never mutated, so there is no need to dup the literal.

If we change to a constant lookup, the string will not be duped, and we can reduce the objects in our system:

> puts RubyVM::InstructionSequence.new(‘BAR = “bar”; def foo; BAR; end’).disasm

== disasm: <RubyVM::InstructionSequence:foo@<compiled>>========
0000 trace            8
0002 trace            1
0004 getinlinecache   11, <ic:0>
0007 getconstant      :BAR
0009 setinlinecache   <ic:0>
0011 trace            16
0013 leave

‘getconstant` should be a hash lookup, and no object is duped when the value of the constant is pushed on the stack. Hence the crazy constants below.

‘matches` and `doesNotMatch` operate case-insensitively via Visitor subclasses specialized for specific databases when necessary.

' WHERE '
SPACE =

:nodoc:

' '
COMMA =

:nodoc:

', '
GROUP_BY =

:nodoc:

' GROUP BY '
ORDER_BY =

:nodoc:

' ORDER BY '
WINDOW =

:nodoc:

' WINDOW '
AND =

:nodoc:

' AND '
DISTINCT =

:nodoc:

'DISTINCT'

Instance Method Summary collapse

Methods inherited from Reduce

#accept

Methods inherited from Visitor

#accept

Constructor Details

#initialize(connection) ⇒ ToSql

:nodoc:



68
69
70
71
# File 'lib/arel/visitors/to_sql.rb', line 68

def initialize connection
  super()
  @connection     = connection
end

Instance Method Details

#compile(node, &block) ⇒ Object



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

def compile node, &block
  accept(node, Arel::Collectors::SQLString.new, &block).value
end