diff options
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/abstract/quoting.rb | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/database_configurations.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation.rb | 6 | ||||
-rw-r--r-- | activerecord/lib/arel/visitors/ibm_db.rb | 3 | ||||
-rw-r--r-- | activerecord/lib/arel/visitors/informix.rb | 3 | ||||
-rw-r--r-- | activerecord/lib/arel/visitors/mssql.rb | 5 | ||||
-rw-r--r-- | activerecord/lib/arel/visitors/postgresql.rb | 14 | ||||
-rw-r--r-- | activerecord/lib/arel/visitors/to_sql.rb | 105 |
8 files changed, 46 insertions, 96 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb index 9d24d839c1..2877530917 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb @@ -138,6 +138,10 @@ module ActiveRecord "'#{quote_string(value.to_s)}'" end + def sanitize_as_sql_comment(value) # :nodoc: + value.to_s.gsub(%r{ (/ (?: | \g<1>) \*) \+? \s* | \s* (\* (?: | \g<2>) /) }x, "") + end + private def type_casted_binds(binds) if binds.first.is_a?(Array) diff --git a/activerecord/lib/active_record/database_configurations.rb b/activerecord/lib/active_record/database_configurations.rb index a6c702cbbc..4656045fe5 100644 --- a/activerecord/lib/active_record/database_configurations.rb +++ b/activerecord/lib/active_record/database_configurations.rb @@ -106,7 +106,7 @@ module ActiveRecord build_db_config = configs.each_pair.flat_map do |env_name, config| walk_configs(env_name.to_s, "primary", config) - end.compact + end.flatten.compact if url = ENV["DATABASE_URL"] build_url_config(url, build_db_config) diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 37179774fa..6d954a2b2e 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -342,6 +342,8 @@ module ActiveRecord # trigger Active Record callbacks or validations. However, values passed to #update_all will still go through # Active Record's normal type casting and serialization. # + # Note: As Active Record callbacks are not triggered, this method will not automatically update +updated_at+/+updated_on+ columns. + # # ==== Parameters # # * +updates+ - A string, array, or hash representing the SET part of an SQL statement. @@ -416,10 +418,10 @@ module ActiveRecord update_all updates end - # Touches all records in the current relation without instantiating records first with the updated_at/on attributes + # Touches all records in the current relation without instantiating records first with the +updated_at+/+updated_on+ attributes # set to the current time or the time specified. # This method can be passed attribute names and an optional time argument. - # If attribute names are passed, they are updated along with updated_at/on attributes. + # If attribute names are passed, they are updated along with +updated_at+/+updated_on+ attributes. # If no time argument is passed, the current time is used as default. # # === Examples diff --git a/activerecord/lib/arel/visitors/ibm_db.rb b/activerecord/lib/arel/visitors/ibm_db.rb index 0ffc0725f7..5cf958f5f0 100644 --- a/activerecord/lib/arel/visitors/ibm_db.rb +++ b/activerecord/lib/arel/visitors/ibm_db.rb @@ -10,7 +10,8 @@ module Arel # :nodoc: all end def visit_Arel_Nodes_OptimizerHints(o, collector) - collector << "/* <OPTGUIDELINES>#{sanitize_as_sql_comment(o).join}</OPTGUIDELINES> */" + hints = o.expr.map { |v| sanitize_as_sql_comment(v) }.join + collector << "/* <OPTGUIDELINES>#{hints}</OPTGUIDELINES> */" end def visit_Arel_Nodes_Limit(o, collector) diff --git a/activerecord/lib/arel/visitors/informix.rb b/activerecord/lib/arel/visitors/informix.rb index cd43be8858..1a4ad1c8d8 100644 --- a/activerecord/lib/arel/visitors/informix.rb +++ b/activerecord/lib/arel/visitors/informix.rb @@ -43,7 +43,8 @@ module Arel # :nodoc: all end def visit_Arel_Nodes_OptimizerHints(o, collector) - collector << "/*+ #{sanitize_as_sql_comment(o).join(", ")} */" + hints = o.expr.map { |v| sanitize_as_sql_comment(v) }.join(", ") + collector << "/*+ #{hints} */" end def visit_Arel_Nodes_Offset(o, collector) diff --git a/activerecord/lib/arel/visitors/mssql.rb b/activerecord/lib/arel/visitors/mssql.rb index 85815baca2..8475139870 100644 --- a/activerecord/lib/arel/visitors/mssql.rb +++ b/activerecord/lib/arel/visitors/mssql.rb @@ -82,7 +82,8 @@ module Arel # :nodoc: all end def visit_Arel_Nodes_OptimizerHints(o, collector) - collector << "OPTION (#{sanitize_as_sql_comment(o).join(", ")})" + hints = o.expr.map { |v| sanitize_as_sql_comment(v) }.join(", ") + collector << "OPTION (#{hints})" end def get_offset_limit_clause(o) @@ -106,7 +107,7 @@ module Arel # :nodoc: all 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 920776b4dc..8296f1cdc1 100644 --- a/activerecord/lib/arel/visitors/postgresql.rb +++ b/activerecord/lib/arel/visitors/postgresql.rb @@ -3,11 +3,6 @@ module Arel # :nodoc: all module Visitors class PostgreSQL < Arel::Visitors::ToSql - CUBE = "CUBE" - ROLLUP = "ROLLUP" - GROUPING_SETS = "GROUPING SETS" - LATERAL = "LATERAL" - private def visit_Arel_Nodes_Matches(o, collector) @@ -57,23 +52,22 @@ module Arel # :nodoc: all 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 583f920290..1630226085 100644 --- a/activerecord/lib/arel/visitors/to_sql.rb +++ b/activerecord/lib/arel/visitors/to_sql.rb @@ -9,59 +9,6 @@ module Arel # :nodoc: all 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: <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 = " WHERE " # :nodoc: - SPACE = " " # :nodoc: - COMMA = ", " # :nodoc: - GROUP_BY = " GROUP BY " # :nodoc: - ORDER_BY = " ORDER BY " # :nodoc: - WINDOW = " WINDOW " # :nodoc: - AND = " AND " # :nodoc: - - DISTINCT = "DISTINCT" # :nodoc: - def initialize(connection) super() @connection = connection @@ -161,10 +108,10 @@ module Arel # :nodoc: all 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 +119,7 @@ module Arel # :nodoc: all 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 +127,11 @@ module Arel # :nodoc: all } 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,26 +150,27 @@ module Arel # :nodoc: all 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 def visit_Arel_Nodes_OptimizerHints(o, collector) - collector << "/*+ #{sanitize_as_sql_comment(o).join(" ")} */" + hints = o.expr.map { |v| sanitize_as_sql_comment(v) }.join(" ") + collector << "/*+ #{hints} */" 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 +182,7 @@ module Arel # :nodoc: all end def visit_Arel_Nodes_Distinct(o, collector) - collector << DISTINCT + collector << "DISTINCT" end def visit_Arel_Nodes_DistinctOn(o, collector) @@ -243,12 +191,12 @@ module Arel # :nodoc: all 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 +229,13 @@ module Arel # :nodoc: all 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 +440,8 @@ module Arel # :nodoc: all 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 +461,7 @@ module Arel # :nodoc: all 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 +475,7 @@ module Arel # :nodoc: all 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 +483,7 @@ module Arel # :nodoc: all collector << "INNER JOIN " collector = visit o.left, collector if o.right - collector << SPACE + collector << " " visit(o.right, collector) else collector @@ -785,10 +733,9 @@ module Arel # :nodoc: all @connection.quote_column_name(name) end - def sanitize_as_sql_comment(o) - o.expr.map { |v| - v.gsub(%r{ (/ (?: | \g<1>) \*) \+? \s* | \s* (\* (?: | \g<2>) /) }x, "") - } + def sanitize_as_sql_comment(value) + return value if Arel::Nodes::SqlLiteral === value + @connection.sanitize_as_sql_comment(value) end def collect_optimizer_hints(o, collector) |