mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Avoid extra BindParam
allocation to generate placeholder in queries
In the Active Record usage, a `BindParam` object always has an attribute object as the value. A `BindParam` object is used to call `add_bind` to generate placeholder if `prepared_statements: true`. Since Arel is a part of Active Record now, I think that we can regard an `ActiveModel::Attribute` object as boundable without wrapping it by a `BindParam` to avoid extra `BindParam` allocation.
This commit is contained in:
parent
a8c462d37c
commit
64ca6f608e
7 changed files with 15 additions and 20 deletions
|
@ -368,7 +368,7 @@ module ActiveRecord
|
||||||
if values.empty?
|
if values.empty?
|
||||||
im.insert(connection.empty_insert_statement_value(primary_key))
|
im.insert(connection.empty_insert_statement_value(primary_key))
|
||||||
else
|
else
|
||||||
im.insert(_substitute_values(values))
|
im.insert(values.transform_keys { |name| arel_table[name] })
|
||||||
end
|
end
|
||||||
|
|
||||||
connection.insert(im, "#{self} Create", primary_key || false, primary_key_value)
|
connection.insert(im, "#{self} Create", primary_key || false, primary_key_value)
|
||||||
|
@ -386,7 +386,7 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
um = Arel::UpdateManager.new(arel_table)
|
um = Arel::UpdateManager.new(arel_table)
|
||||||
um.set(_substitute_values(values))
|
um.set(values.transform_keys { |name| arel_table[name] })
|
||||||
um.wheres = constraints
|
um.wheres = constraints
|
||||||
|
|
||||||
connection.update(um, "#{self} Update")
|
connection.update(um, "#{self} Update")
|
||||||
|
@ -425,12 +425,6 @@ module ActiveRecord
|
||||||
def discriminate_class_for_record(record)
|
def discriminate_class_for_record(record)
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
def _substitute_values(values)
|
|
||||||
values.map do |name, value|
|
|
||||||
[ arel_table[name], Arel::Nodes::BindParam.new(value) ]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns true if this object hasn't been saved yet -- that is, a record
|
# Returns true if this object hasn't been saved yet -- that is, a record
|
||||||
|
|
|
@ -65,8 +65,7 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_bind_attribute(column_name, value)
|
def build_bind_attribute(column_name, value)
|
||||||
attr = Relation::QueryAttribute.new(column_name, value, table.type(column_name))
|
Relation::QueryAttribute.new(column_name, value, table.type(column_name))
|
||||||
Arel::Nodes::BindParam.new(attr)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def resolve_arel_attribute(table_name, column_name, &block)
|
def resolve_arel_attribute(table_name, column_name, &block)
|
||||||
|
|
|
@ -1263,8 +1263,7 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_cast_value(name, value)
|
def build_cast_value(name, value)
|
||||||
cast_value = ActiveModel::Attribute.with_cast_value(name, value, Type.default_value)
|
ActiveModel::Attribute.with_cast_value(name, value, Type.default_value)
|
||||||
Arel::Nodes::BindParam.new(cast_value)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_from
|
def build_from
|
||||||
|
|
|
@ -224,11 +224,10 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def extract_node_value(node)
|
def extract_node_value(node)
|
||||||
case node
|
if node.respond_to?(:value_before_type_cast)
|
||||||
when Array
|
|
||||||
node.map { |v| extract_node_value(v) }
|
|
||||||
when Arel::Nodes::BindParam, Arel::Nodes::Casted, Arel::Nodes::Quoted
|
|
||||||
node.value_before_type_cast
|
node.value_before_type_cast
|
||||||
|
elsif Array === node
|
||||||
|
node.map { |v| extract_node_value(v) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -47,7 +47,7 @@ module Arel # :nodoc: all
|
||||||
|
|
||||||
def self.build_quoted(other, attribute = nil)
|
def self.build_quoted(other, attribute = nil)
|
||||||
case other
|
case other
|
||||||
when Arel::Nodes::Node, Arel::Attributes::Attribute, Arel::Table, Arel::SelectManager, Arel::Nodes::SqlLiteral
|
when Arel::Nodes::Node, Arel::Attributes::Attribute, Arel::Table, Arel::SelectManager, Arel::Nodes::SqlLiteral, ActiveModel::Attribute
|
||||||
other
|
other
|
||||||
else
|
else
|
||||||
case attribute
|
case attribute
|
||||||
|
|
|
@ -52,7 +52,7 @@ module Arel # :nodoc: all
|
||||||
else
|
else
|
||||||
left = quoted_node(other.begin)
|
left = quoted_node(other.begin)
|
||||||
right = quoted_node(other.end)
|
right = quoted_node(other.end)
|
||||||
Nodes::Between.new(self, left.and(right))
|
Nodes::Between.new(self, Nodes::And.new([left, right]))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ module Arel # :nodoc: all
|
||||||
row.each_with_index do |value, k|
|
row.each_with_index do |value, k|
|
||||||
collector << ", " unless k == 0
|
collector << ", " unless k == 0
|
||||||
case value
|
case value
|
||||||
when Nodes::SqlLiteral, Nodes::BindParam
|
when Nodes::SqlLiteral, Nodes::BindParam, ActiveModel::Attribute
|
||||||
collector = visit(value, collector)
|
collector = visit(value, collector)
|
||||||
else
|
else
|
||||||
collector << quote(value).to_s
|
collector << quote(value).to_s
|
||||||
|
@ -585,7 +585,7 @@ module Arel # :nodoc: all
|
||||||
|
|
||||||
def visit_Arel_Nodes_Assignment(o, collector)
|
def visit_Arel_Nodes_Assignment(o, collector)
|
||||||
case o.right
|
case o.right
|
||||||
when Arel::Nodes::Node, Arel::Attributes::Attribute
|
when Arel::Nodes::Node, Arel::Attributes::Attribute, ActiveModel::Attribute
|
||||||
collector = visit o.left, collector
|
collector = visit o.left, collector
|
||||||
collector << " = "
|
collector << " = "
|
||||||
visit o.right, collector
|
visit o.right, collector
|
||||||
|
@ -695,6 +695,10 @@ module Arel # :nodoc: all
|
||||||
|
|
||||||
def bind_block; BIND_BLOCK; end
|
def bind_block; BIND_BLOCK; end
|
||||||
|
|
||||||
|
def visit_ActiveModel_Attribute(o, collector)
|
||||||
|
collector.add_bind(o, &bind_block)
|
||||||
|
end
|
||||||
|
|
||||||
def visit_Arel_Nodes_BindParam(o, collector)
|
def visit_Arel_Nodes_BindParam(o, collector)
|
||||||
collector.add_bind(o.value, &bind_block)
|
collector.add_bind(o.value, &bind_block)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue