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
Postgresql date type is not properly typecasted when using direct SQL queries like select_all #51448
Comments
@bogdan Correct me if you think I am wrong but I don't think this is an issue with Rails/Activerecord.
is to extract the date from the database by casting it as date and comparing it with a Date object. I don't think that's the right way to go about it.
Additionally, since
Now if you compare the two dates:
, it should be equal. Let me know if that works for you. |
@bogdan This is not a bug in Rails. It unpacks the result object from the raw underlying connection adapter, but it doesn't convert or interpret types of the results (It does type casting for params/bindings). When trying with the Mysql2 adapter, dates are parsed to a Ruby Date object, because the The PG gems does support mechanism for type casting, but those are never called by You can cast the result by passing it to: |
Ok, so I tried a few tests using require 'pg'
# Replace these with your actual database credentials
dbname = 'rails_test'
user = 'bogdan'
password = nil
host = 'localhost' # or the appropriate host
# Establish a connection to the database
conn = PG.connect(dbname: dbname, user: user, password: password, host: host)
# Execute a query
query = "select cast('2024-01-01' as date)"
puts conn.exec(query).to_a.inspect
query = "select cast('2024-01-01' as timestamp)"
puts conn.exec(query).to_a.inspect
# Close the database connection
conn.close Outputs:
Which means that it doens't perform typecast neither for timestamp nor for date.
If so, who is performing typecast for |
Interesting. I missed this because the typecasting doesn't happen inside of Rails, but Rails does add some decoders to the connection when initializing it. The impact radius is pretty big, just adding date here works, but could break a bunch of stuff downstream. I'll check if it blows up the test suite later. |
at the connection level Fix rails#51448 Type cast columns of type `date` to ruby `Date` when running a raw query through `ActiveRecord::Base.connection.select_all`.
at the connection level Fix rails#51448 Type cast columns of type `date` to ruby `Date` when running a raw query through `ActiveRecord::Base.connection.select_all`.
at the connection level Fix rails#51448 Type cast columns of type `date` to ruby `Date` when running a raw query through `ActiveRecord::Base.connection.select_all`.
@bogdan This is what chatGPT is telling me: The difference in return types from these ActiveRecord queries when casting to
This behavior underscores ActiveRecord's design to map SQL data types to Ruby's data types intuitively. For simple dates, a string is often sufficient and follows Ruby's principle of least surprise. For timestamps, which inherently carry more complexity due to the inclusion of time (and potentially time zone), a more capable object like Ruby's This automatic conversion facilitates easier manipulation and comparison of date and time values within Ruby, adhering to the conventions of the Ruby language and the expectations of developers working within its ecosystem. |
@rebase-master well, @JoeDupuis's answer looks better to me, really happy that human defeated the machine on this tiny case. |
Take that robot! You probably saw that I submitted a PR #51483 for it already, but it could be rejected. Unrelated, but I am a big fan of your datagrid gem. Thank you for writing it 😁 |
at the connection level Fix rails#51448 Type cast columns of type `date` to ruby `Date` when running a raw query through `ActiveRecord::Base.connection.select_all`.
at the connection level Fix rails#51448 Type cast columns of type `date` to ruby `Date` when running a raw query through `ActiveRecord::Base.connection.select_all`.
When using direct SQL query, the date is not properly typecasted on Postgresql:
Notes
2024
as integer.Reproduce
Expected behavior
System configuration
Rails version: 7.1.3
Ruby version: 3.2.2
The text was updated successfully, but these errors were encountered: