Don't skip some columns in column_types
on Postgres
Fixes https://github.com/rails/rails/issues/41651, by partially reverting https://github.com/rails/rails/pull/39097 I ran the same benchmark as https://github.com/rails/rails/pull/39097 and it seems like this change does not cause a perf regression. ```ruby require "bundler/inline" gemfile(true) do source "https://rubygems.org" git_source(:github) { |repo| "https://github.com/#{repo}.git" } gem "rails", path: "/Users/alex/code/rails" # github: "rails/rails", branch: "main" gem "sqlite3" gem "benchmark-ips" end require "active_record" ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:") ActiveRecord::Schema.define do create_table :active_storage_blobs do |t| t.string :key, null: false t.string :filename, null: false t.string :content_type t.text :metadata t.string :service_name, null: false t.bigint :byte_size, null: false t.string :checksum, null: false t.datetime :created_at, null: false t.index [ :key ], unique: true end end class ActiveStorageBlob < ActiveRecord::Base end Benchmark.ips do |x| x.report("find_by") { ActiveStorageBlob.find_by(id: 1) } end ``` This branch: ``` Warming up -------------------------------------- find_by 1.940k i/100ms Calculating ------------------------------------- find_by 17.928k (± 4.8%) i/s - 91.180k in 5.098301s ``` Main: ``` Warming up -------------------------------------- find_by 1.912k i/100ms Calculating ------------------------------------- find_by 17.961k (± 4.8%) i/s - 89.864k in 5.015252s ```
This commit is contained in:
parent
0b5c7210af
commit
587522e696
@ -55,11 +55,7 @@ def exec_query(sql, name = "SQL", binds = [], prepare: false, async: false) # :n
|
||||
fields.each_with_index do |fname, i|
|
||||
ftype = result.ftype i
|
||||
fmod = result.fmod i
|
||||
case type = get_oid_type(ftype, fmod, fname)
|
||||
when Type::Integer, Type::Float, OID::Decimal, Type::String, Type::DateTime, Type::Boolean
|
||||
# skip if a column has already been type casted by pg decoders
|
||||
else types[fname] = type
|
||||
end
|
||||
types[fname] = get_oid_type(ftype, fmod, fname)
|
||||
end
|
||||
build_result(columns: fields, rows: result.values, column_types: types)
|
||||
end
|
||||
|
@ -1442,6 +1442,13 @@ def cast(value)
|
||||
assert_equal "t.lo", topic.author_name
|
||||
end
|
||||
|
||||
if current_adapter?(:PostgreSQLAdapter)
|
||||
def test_column_types_on_queries_on_postgresql
|
||||
result = ActiveRecord::Base.connection.exec_query("SELECT 1 AS test")
|
||||
assert_equal ActiveModel::Type::Integer, result.column_types["test"].class
|
||||
end
|
||||
end
|
||||
|
||||
def test_typecasting_aliases
|
||||
assert_equal 10, Topic.select("10 as tenderlove").first.tenderlove
|
||||
end
|
||||
|
@ -993,11 +993,24 @@ def test_pluck_functions_with_alias
|
||||
end
|
||||
|
||||
def test_pluck_functions_without_alias
|
||||
assert_equal [
|
||||
[1, "The First Topic"], [2, "The Second Topic of the day"],
|
||||
[3, "The Third Topic of the day"], [4, "The Fourth Topic of the day"],
|
||||
[5, "The Fifth Topic of the day"]
|
||||
], Topic.order(:id).pluck(
|
||||
expected = if current_adapter?(:PostgreSQLAdapter)
|
||||
# Postgres returns the same name for each column in the given query, so each column is named "coalesce"
|
||||
# As a result Rails cannot accurately type cast each value.
|
||||
# To work around this, you should use aliases in your select statement (see test_pluck_functions_with_alias).
|
||||
[
|
||||
["1", "The First Topic"], ["2", "The Second Topic of the day"],
|
||||
["3", "The Third Topic of the day"], ["4", "The Fourth Topic of the day"],
|
||||
["5", "The Fifth Topic of the day"]
|
||||
]
|
||||
else
|
||||
[
|
||||
[1, "The First Topic"], [2, "The Second Topic of the day"],
|
||||
[3, "The Third Topic of the day"], [4, "The Fourth Topic of the day"],
|
||||
[5, "The Fifth Topic of the day"]
|
||||
]
|
||||
end
|
||||
|
||||
assert_equal expected, Topic.order(:id).pluck(
|
||||
Arel.sql("COALESCE(id, 0)"),
|
||||
Arel.sql("COALESCE(title, 'untitled')")
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user