Class: Arel::Visitors::ToSql

Inherits:
Visitor
  • Object
show all
Defined in:
lib/arel/visitors/to_sql.rb

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:[email protected]<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:[email protected]<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.

' 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 Visitor

#accept

Constructor Details

#initialize(connection) ⇒ ToSql

:nodoc:


56
57
58
59
60
61
# File 'lib/arel/visitors/to_sql.rb', line 56

def initialize connection
  @connection     = connection
  @schema_cache   = connection.schema_cache
  @quoted_tables  = {}
  @quoted_columns = {}
end