diff --git a/activerecord/lib/arel/visitors/mssql.rb b/activerecord/lib/arel/visitors/mssql.rb index 85815baca222adfdbef8497779344af8554d43f2..deb87242b75eb2c6c97839da056b7e20913269d9 100644 --- a/activerecord/lib/arel/visitors/mssql.rb +++ b/activerecord/lib/arel/visitors/mssql.rb @@ -106,7 +106,7 @@ def visit_Arel_Nodes_DeleteStatement(o, collector) collector = visit o.relation, collector if o.wheres.any? collector << " WHERE " - inject_join o.wheres, collector, AND + inject_join o.wheres, collector, " AND " else collector end diff --git a/activerecord/lib/arel/visitors/postgresql.rb b/activerecord/lib/arel/visitors/postgresql.rb index 920776b4dc9ede7bfd14d95980fb4e416dd737ce..68ec6c02e2b218444b42ed4e514aabdf27850b5e 100644 --- a/activerecord/lib/arel/visitors/postgresql.rb +++ b/activerecord/lib/arel/visitors/postgresql.rb @@ -57,23 +57,22 @@ def visit_Arel_Nodes_GroupingElement(o, collector) end def visit_Arel_Nodes_Cube(o, collector) - collector << CUBE + collector << "CUBE" grouping_array_or_grouping_element o, collector end def visit_Arel_Nodes_RollUp(o, collector) - collector << ROLLUP + collector << "ROLLUP" grouping_array_or_grouping_element o, collector end def visit_Arel_Nodes_GroupingSet(o, collector) - collector << GROUPING_SETS + collector << "GROUPING SETS" grouping_array_or_grouping_element o, collector end def visit_Arel_Nodes_Lateral(o, collector) - collector << LATERAL - collector << SPACE + collector << "LATERAL " grouping_parentheses o, collector end diff --git a/activerecord/lib/arel/visitors/to_sql.rb b/activerecord/lib/arel/visitors/to_sql.rb index 583f920290abb00d8810f1f75afb97c4afd65d4b..a93a318e0da99f4af489b17fc41d6c58f31ec0a2 100644 --- a/activerecord/lib/arel/visitors/to_sql.rb +++ b/activerecord/lib/arel/visitors/to_sql.rb @@ -9,49 +9,6 @@ def initialize(object) end class ToSql < Arel::Visitors::Visitor - ## - # 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: >===== - # 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: >======== - # 0000 trace 8 - # 0002 trace 1 - # 0004 getinlinecache 11, - # 0007 getconstant :BAR - # 0009 setinlinecache - # 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 = " WHERE " # :nodoc: SPACE = " " # :nodoc: COMMA = ", " # :nodoc: @@ -161,10 +118,10 @@ def visit_Arel_Nodes_ValuesList(o, collector) else collector << quote(value).to_s end - collector << COMMA unless k == row_len + collector << ", " unless k == row_len end collector << ")" - collector << COMMA unless i == len + collector << ", " unless i == len } collector end @@ -172,7 +129,7 @@ def visit_Arel_Nodes_ValuesList(o, collector) def visit_Arel_Nodes_SelectStatement(o, collector) if o.with collector = visit o.with, collector - collector << SPACE + collector << " " end collector = o.cores.inject(collector) { |c, x| @@ -180,11 +137,11 @@ def visit_Arel_Nodes_SelectStatement(o, collector) } unless o.orders.empty? - collector << ORDER_BY + collector << " ORDER BY " len = o.orders.length - 1 o.orders.each_with_index { |x, i| collector = visit(x, collector) - collector << COMMA unless len == i + collector << ", " unless len == i } end @@ -203,17 +160,17 @@ def visit_Arel_Nodes_SelectCore(o, collector) collector = collect_optimizer_hints(o, collector) collector = maybe_visit o.set_quantifier, collector - collect_nodes_for o.projections, collector, SPACE + 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 + 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 " collector end @@ -222,7 +179,7 @@ def visit_Arel_Nodes_OptimizerHints(o, collector) collector << "/*+ #{sanitize_as_sql_comment(o).join(" ")} */" end - def collect_nodes_for(nodes, collector, spacer, connector = COMMA) + def collect_nodes_for(nodes, collector, spacer, connector = ", ") unless nodes.empty? collector << spacer inject_join nodes, collector, connector @@ -234,7 +191,7 @@ def visit_Arel_Nodes_Bin(o, collector) end def visit_Arel_Nodes_Distinct(o, collector) - collector << DISTINCT + collector << "DISTINCT" end def visit_Arel_Nodes_DistinctOn(o, collector) @@ -243,12 +200,12 @@ def visit_Arel_Nodes_DistinctOn(o, collector) def visit_Arel_Nodes_With(o, collector) collector << "WITH " - inject_join o.children, collector, COMMA + inject_join o.children, collector, ", " end def visit_Arel_Nodes_WithRecursive(o, collector) collector << "WITH RECURSIVE " - inject_join o.children, collector, COMMA + inject_join o.children, collector, ", " end def visit_Arel_Nodes_Union(o, collector) @@ -281,13 +238,13 @@ def visit_Arel_Nodes_Window(o, collector) collect_nodes_for o.partitions, collector, "PARTITION BY " if o.orders.any? - collector << SPACE if o.partitions.any? + collector << " " if o.partitions.any? collector << "ORDER BY " collector = inject_join o.orders, collector, ", " end if o.framing - collector << SPACE if o.partitions.any? || o.orders.any? + collector << " " if o.partitions.any? || o.orders.any? collector = visit o.framing, collector end @@ -492,8 +449,8 @@ def visit_Arel_Nodes_JoinSource(o, collector) collector = visit o.left, collector end if o.right.any? - collector << SPACE if o.left - collector = inject_join o.right, collector, SPACE + collector << " " if o.left + collector = inject_join o.right, collector, " " end collector end @@ -513,7 +470,7 @@ def visit_Arel_Nodes_StringJoin(o, collector) def visit_Arel_Nodes_FullOuterJoin(o, collector) collector << "FULL OUTER JOIN " collector = visit o.left, collector - collector << SPACE + collector << " " visit o.right, collector end @@ -527,7 +484,7 @@ def visit_Arel_Nodes_OuterJoin(o, collector) def visit_Arel_Nodes_RightOuterJoin(o, collector) collector << "RIGHT OUTER JOIN " collector = visit o.left, collector - collector << SPACE + collector << " " visit o.right, collector end @@ -535,7 +492,7 @@ def visit_Arel_Nodes_InnerJoin(o, collector) collector << "INNER JOIN " collector = visit o.left, collector if o.right - collector << SPACE + collector << " " visit(o.right, collector) else collector