-
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
The select
method in [ActiveRecord] is producing incorrect results with PostgreSQL.
#52029
Comments
select
method in [ActiveRecord] is producing incorrect results.
select
method in [ActiveRecord] is producing incorrect results.select
method in [ActiveRecord] is producing incorrect results with PostgreSQL.
1.) Rails has no knowledge of the columns being used in your I would close this issue as it has nothing to do with Rails. |
@justinko, the output from the select method is incorrect. It is missing some fields that should be present in the output. PostgreSQL is returning two columns with the field names min and min. However, in Rails, we are ignoring one of these fields. We should ensure that the number of columns fetched in the select query matches the number of columns we handle. FilePart.select('min(part_name), min(part_start_at)').as_json
D, [2024-06-07T13:01:19.214175 #80053] DEBUG -- : FilePart Load (0.9ms) SELECT min(part_name), min(part_start_at) FROM "file_parts"
[{"min"=>"2024-05-31T11:12:00.000Z", "id"=>nil}] |
What would you like to see? [{"min_part_name"=>"2024-05-31T11:12:00.000Z", "min_part_start_at"=>"2024-05-31T11:12:00.000Z", "id"=>nil}] That? |
@justinko IMO It should be consistent with mysql and sqlite. MySQL (ruby) FilePart.select('min(part_name), min(part_start_at)').as_json.first
D, [2024-06-07T17:08:28.850168 #86936] DEBUG -- : FilePart Load (1.7ms) SELECT min(part_name), min(part_start_at) FROM `file_parts`
{"min(part_name)"=>"2024/05/31/11_12.a2b3c4d5.txt", "min(part_start_at)"=>"2024-05-31T11:12:00.000Z", "id"=>nil} Sqlite (ruby) FilePart.select('min(part_name), min(part_start_at)').as_json.first
D, [2024-06-07T17:12:16.720248 #88035] DEBUG -- : FilePart Load (0.1ms) SELECT min(part_name), min(part_start_at) FROM "file_parts"
{"min(part_name)"=>"2024/05/31/11_12.a2b3c4d5.txt", "min(part_start_at)"=>"2024-05-31 11:12:00", "id"=>nil} PostgreSQL (ruby) FilePart.select('min(part_name), min(part_start_at)').as_json.first
D, [2024-06-07T17:13:38.814009 #88447] DEBUG -- : FilePart Load (0.9ms) SELECT min(part_name), min(part_start_at) FROM "file_parts"
{"min"=>"2024-05-31T11:12:00.000Z", "id"=>nil} |
Yes, it would be great if postgres also returned |
This is functioning as intended.
We use the column names as returned by the database. |
@matthewd, we're encountering an issue when parsing a column returned by PostgreSQL in Rails. In the example below, one of the fields is missing. PostgreSQL returns two fields, but when Rails parses it, only one value is taken for fields with the same key, and the other is ignored. This results in a mismatch between the output from PostgreSQL and what Rails select results.
|
.select calls with multiple SQL fragment arguments, using the same function (such as min or max) incorrectly returned values when using PostgreSQL.
Steps to reproduce
Expected behavior
Actual behavior
Research and Findings
internal_exec_query
is responsible for:pg
gem.ActiveRecord::Result
object for the fetched result.rails/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
Lines 65 to 76 in 5dabff4
Fetching the result from the
pg
gem.For example:
In this case, the
pg
gem returns the values for fields as:Build an
ActiveRecord::Result
object for the fetched result.When constructing the
ActiveRecord::Result
object, we utilize the fields as the column names:rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
Lines 1184 to 1188 in 5dabff4
Initialize a model object from
ActiveRecord::Result
:rails/activerecord/lib/active_record/querying.rb
Line 73 in 5dabff4
When creating an object, if two columns have the same key name, the object
min
gets overridden, resulting in an incorrect outcome.Why does the
pg
gem return the same column name for two different fields?pg
gem internally usesPQfname
method from thelibpq
.res: https://github.com/ged/ruby-pg/blob/d072b21852865ecb84e6345df11d68eed50702bb/ext/pg_result.c#L502
OR
The text was updated successfully, but these errors were encountered: