Skip to content
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

Support for (Pg)Interval with chrono::Duration #237

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

Rudi3
Copy link

@Rudi3 Rudi3 commented Jan 14, 2022

Preparation for
SeaQL/sea-orm#426

Support for

  • std::time::Duration
  • chrono::Duration

I'm not sure if it makes sense to use std::time::Duration without chrono

postgres-types doesn't seem to support ToSql for chrono::Duration - at least it wasn't listed in the docs. So I'm not sure if this is a big deal in postgres.rs

sqlx will panic if a conversion fails; if:

  • Duration is longer than what PgInterval can store
  • Duration contains nanoseconds - too small for PgInterval

@Rudi3 Rudi3 changed the title Prepare Support for PgInterval and chrono:.Duration in sea-orm Support for (Pg)Interval with chrono::Duration Jan 15, 2022
@ikrivosheev
Copy link
Member

@Rudi3 hello, are there any plans to finish?)

@Rudi3
Copy link
Author

Rudi3 commented Apr 22, 2022

@ikrivosheev hello, i have to admit that I forgot about it.
But this was pretty much done except for the uncertainty about ToSql.
Do you think there might be any other problems?

@ikrivosheev
Copy link
Member

@Rudi3 which uncertainty with ToSql? I dont understand

@Rudi3
Copy link
Author

Rudi3 commented Apr 22, 2022

@ikrivosheev src/driver/postgres.rs I decided to throw unimplemented if to_sql is called in the postgres driver.rs because postgres-types doesn't implement ToSql for chrono::Duration - as far as I could tell. I'm not sure if that would lead to any problems. I'll have to check if support was added in the meantime, however.
At a glance, it doesn't seem like it: https://docs.rs/postgres-types/latest/postgres_types/trait.ToSql.html
If this is needed, it might block this for now.

@ikrivosheev
Copy link
Member

Ah... I understood! We can create issue in postgres-types and wait for implantation or implement it yourself.

I will create issue.

@ikrivosheev
Copy link
Member

ikrivosheev commented Apr 22, 2022

Found: sfackler/rust-postgres#60

@billy1624
Copy link
Member

Hey @Rudi3, welcome back!

After second thought, I think we can support time::Duration & chrono::Duration. Just like what we did to all other datetime values.

  • sea-query/src/value.rs

    Lines 51 to 53 in 70cd3dc

    #[cfg(feature = "with-chrono")]
    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
    ChronoDate(Option<Box<NaiveDate>>),
  • sea-query/src/value.rs

    Lines 75 to 77 in 70cd3dc

    #[cfg(feature = "with-time")]
    #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
    TimeDate(Option<Box<time::Date>>),

@Rudi3
Copy link
Author

Rudi3 commented Apr 26, 2022

Hey, @billy1624!
Unfortunately ToSql isn't implemented for time::Duration in postgres-types either.
But I'll see if I can add time::Duration at least in here when I get to it.

@etsea117
Copy link

@Rudi3 any update on this?

@billy1624
Copy link
Member

Hey @Rudi3, I'm sorry for the delay.

Hey, @billy1624! Unfortunately ToSql isn't implemented for time::Duration in postgres-types either. But I'll see if I can add time::Duration at least in here when I get to it.

I think postgres driver implements non of chrono::Duration, time::Duration and std::time::Duration?

We could get this PR merge before moving on to SeaQL/sea-orm#456

@Rudi3
Copy link
Author

Rudi3 commented Sep 22, 2023

Hello, I revised this PR and noticed that to_sql seems be run on a Json value rather than on e.g. chrono::DateTime or chrono::Duration. So it's converted to a string in a previous step. If I got that right, we don't actually need the ToSql Trait for chrono::Duration or time::Duration - but just a conversion to a precise string that is accepted by postgres.

For now, I opted for the ISO8601 duration format that's provided by chrono::Duration. Negative durations are expressed by a minus before the statement like -P3DT4H5M6S. But postgres docs mention that each field should be negative to avoid misinterpretation.

So maybe I should rewrite the formatter to do exactly this. Furthermore, the maximum allowed precision is 6. So should any other digits be rounded/cut off/etc? Also, maybe it's possible to optimize the format to just provide total seconds with up to 6 decimal places - if ISO8601 and postgres allow for this. This would also dodge the multiple field issue related to the sign. Requesting some feedback on this and maybe confirmation of my assumption about the to_sql conversion, please. Thank you!

Edit:
The code in src/backend/query_builder.rs doesn't seem to be called during my tests with time::Duration. I can read and write values without reaching this code - so I'm not sure what it's for and how it should behave.

sea-query-binder/src/sqlx_postgres.rs seems to be doing all the work when writing but I'm not sure if it's sufficient - as the duration is just passed over as far as I can see.

Currently, it appears to be working with time:Duration. chrono:Duration isn't tested yet. Due to the aforementioned problems, I'm not sure if it's safe.

@DevSlashRichie
Copy link

Is there any advancement on this? Is there anything I can help with?

@ccqpein
Copy link

ccqpein commented Jul 6, 2024

Hi guys, is there any update about this PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Triage
Development

Successfully merging this pull request may close these issues.

6 participants