-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Bad conversion from non-UTC timestamptz with postgres #703
Comments
This is possible to trigger if you use We should be parsing |
ANNOTATION ADDED BY @yuyawk HIM/HERSELF: In this comment s/he misunderstood what this issue mean. See also an advice to him/her It seems that this issue is not reproduced at the current HEAD (perhaps already fixed?). I added the test below to tests/postgres/postgres.rs, set up docker-compose and carried out test that I added: #[sqlx_macros::test]
async fn test_issue_703() -> anyhow::Result<()> {
use sqlx::types::chrono::{DateTime, TimeZone, Utc};
let mut conn = new::<Postgres>().await?;
let date = Utc.ymd(2020, 1, 1).and_hms(1, 1, 1);
sqlx::query("SET TIME ZONE 'Europe/Berlin'")
.fetch_optional(&mut conn)
.await?;
let row: (DateTime<Utc>,) = sqlx::query_as("SELECT $1::timestamptz")
.bind(&date)
.fetch_one(&mut conn)
.await?;
assert_eq!(row.0, date);
Ok(())
} P.S. As well as the original issue, it might be better to use #[sqlx_macros::test]
async fn test_issue_703() -> anyhow::Result<()> {
use sqlx::types::chrono::{DateTime, TimeZone, Utc};
use sqlx_test::pool;
let pool = pool::<Postgres>().await?;
let mut conn = pool.acquire().await?;
let date = Utc.ymd(2020, 1, 1).and_hms(1, 1, 1);
sqlx::query("SET TIME ZONE 'Europe/Berlin'")
.fetch_optional(&mut conn)
.await?;
let row: (DateTime<Utc>,) = sqlx::query_as("SELECT $1::timestamptz")
.bind(&date)
.fetch_one(&mut conn)
.await?;
assert_eq!(row.0, date);
Ok(())
} |
As mentioned this doesn't occur normally because the binary result format is used. I managed to trigger it without editing let row: (DateTime<Utc>,) = sqlx::query_as("SELECT '2020-01-01 01:01:01'::timestamptz")
.fetch_one(&mut conn).await?; But weirdly, if I also do this query before the EDIT: Adding in some more debugging shows that this is still returning a use sqlx::{Row, Executor};
let row = conn.fetch_one("SELECT '2020-01-01 01:01:01+00'::timestamptz").await?;
assert_eq!(row.get::<DateTime<Utc>, _>(0), date); |
@Nemo157 Thank you for your explanation. I totally misunderstood what this issue means. Sorry to trouble you. |
I created a PR to fix this issue, but I'm not so confident about how to convert the output into types with timezone not determined on the application side, i.e. If my understanding is correct:
In my PR, I kept these behaviors unchanged, but in my opinion, it may be natural that these values are determined according to the timezone of the database. |
My PR #1484 is waiting for reviewers to approve it quoted:
|
@abonander Hi. I am currently looking at this problem and interested in reviving PR above or make a new one. There is also problem that I cannot use custom timezones, because decode is implemented only for Utc, Local and FixedOffset. I think something like that would be more appropriate impl<'r, Tz: Timezone> Decode<'r, Postgres> for DateTime<Tz> {
fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> {
...
}
} I'll try to come up with solution if that's ok. |
@Flowneee Happy to pair on this as I am also facing the same problem. There is an associated problem that was fixed for SQLite here My expectations are, if I store a date:
@abonander Can you provide guidance on whether we're on the right track? Also related code that might need to be modified:
|
Note that Postgres does not store timezones. The |
@Nemo157 not sure what you mean, there is a specific type called "timestamp with timezone". Waiting for tests to pass. ![]()
|
Try running |
@Nemo157 Thanks! Just double checked, sad since SQLite does store all of it as text so it can be queried back.. |
|
This comment here is incorrect:
sqlx/sqlx-core/src/postgres/types/chrono/datetime.rs
Lines 79 to 81 in 2e1658e
If you have a connection set to use a non-UTC timezone you will get a response with timestamps in that timezone. After overriding the executor to use
PgValueFormat::Text
for responses and adding some extra debugging code, running the following code:The assertion failed because the timezone on the response was not taken into account
I can't see any way to trigger this behaviour from outside
sqlx-core
since it always uses the binary format for responses, but it seems like a potential footgun to leave around in case this does someday become configurable.The text was updated successfully, but these errors were encountered: