-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid coercing all SELECTs with the same column name to the same value #36186
Changes from 1 commit
20f3f0e
cb0dc11
6b57bf9
f4630d8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -34,13 +34,13 @@ module ActiveRecord | |||
class Result | ||||
include Enumerable | ||||
|
||||
attr_reader :columns, :rows, :column_types | ||||
attr_reader :columns, :rows, :types | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see a strong reason to rename the interface/instance variable to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤔 Good callout re: I wouldn't expect the instance variable to be part of this classes interface, though, and I did implement My concern with simply reusing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||
|
||||
def initialize(columns, rows, column_types = {}) | ||||
def initialize(columns, rows, types = []) | ||||
@columns = columns | ||||
@rows = rows | ||||
@hash_rows = nil | ||||
@column_types = column_types | ||||
@types = types | ||||
boblail marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
end | ||||
|
||||
# Returns true if this result set includes the column named +name+ | ||||
|
@@ -110,13 +110,15 @@ def cast_values(type_overrides = {}) # :nodoc: | |||
if columns.one? | ||||
# Separated to avoid allocating an array per row | ||||
|
||||
type = column_type(columns.first, type_overrides) | ||||
type = column_type(columns.first, 0, type_overrides) | ||||
|
||||
rows.map do |(value)| | ||||
type.deserialize(value) | ||||
end | ||||
else | ||||
types = columns.map { |name| column_type(name, type_overrides) } | ||||
types = columns.map.with_index do |name, i| | ||||
column_type(name, i, type_overrides) | ||||
end | ||||
|
||||
rows.map do |values| | ||||
Array.new(values.size) { |i| types[i].deserialize(values[i]) } | ||||
|
@@ -127,14 +129,22 @@ def cast_values(type_overrides = {}) # :nodoc: | |||
def initialize_copy(other) | ||||
@columns = columns.dup | ||||
@rows = rows.dup | ||||
@column_types = column_types.dup | ||||
@hash_rows = nil | ||||
@types = types.dup | ||||
end | ||||
|
||||
def column_types | ||||
if @types.present? | ||||
boblail marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
Hash[@columns.zip(@types)] | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method is sometimes called inside a loop:
The result should be memoised so that it will only be calculated once, as it was before this change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if it's worth roflscaling this a bit, similar to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since @st0012 was suggesting it earlier, I roflscaled this by assigning |
||||
else | ||||
{} | ||||
end | ||||
end | ||||
|
||||
private | ||||
def column_type(name, type_overrides = {}) | ||||
def column_type(name, index, type_overrides = {}) | ||||
type_overrides.fetch(name) do | ||||
column_types.fetch(name, Type.default_value) | ||||
types[index] || Type.default_value | ||||
end | ||||
end | ||||
|
||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this
column_types:
parameter should be renamed totypes:
.The default value is now of the wrong type too:
rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
Line 746 in a3f62cb