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

feature request: a function to extract units in interval #12624

Closed
xiangjinwu opened this issue Oct 4, 2023 · 6 comments
Closed

feature request: a function to extract units in interval #12624

xiangjinwu opened this issue Oct 4, 2023 · 6 comments
Milestone

Comments

@xiangjinwu
Copy link
Contributor

xiangjinwu commented Oct 4, 2023

Currently:

extract(minute from interval '1 hour 1 minute') -> 1
extract(epoch from interval '1 hour 1 minute')/60 -> 61

We want:

new_func('minute', interval '1 hour 1 minute') -> 61

Intervals containing year/month should report an error until the desired behavior is clear. In PostgreSQL:

  • interval '1 year' = interval '31104000 seconds' is t
  • extract(epoch from interval '1 year') is 31557600

Original request:

Is it possible to add to the list date_diff?
Current alternative is taking the epoch and then subtracting by given unit you want:

(EXTRACT(EPOCH FROM date2 - date1) / 86400)::int

Originally posted by @matanper in #8849 (comment)

@github-actions github-actions bot added this to the release-1.3 milestone Oct 4, 2023
@xiangjinwu
Copy link
Contributor Author

xiangjinwu commented Oct 4, 2023

The subtraction returns an interval, from which we can extract the number of days directly. SQL Server does not have the interval data type, and defines a set of functions with the 2 steps fused together.

EXTRACT(day FROM date2 - date1)::int

There are several caveats though, given the complexity of date/time:

  • It returns the number of whole days, truncating the part less than a day. This is different from SQL Server, which checks specified datepart boundaries crossed.
    For example, DATEDIFF(year, '2005-12-31 23:59:59.999999', '2006-01-01 00:00:00.000000') returns 1 but both workarounds above return 0.
    @matanper Could you confirm which definition of diff/subtract is expected in your case?
  • This only works for day but not year/month or hour/minute/....
    • Month: how many months are between 2023-01-31 and 2023-03-01?
      • SQL Server DATETIME returns 2, as explained above.
      • PostgreSQL subtraction (-) returns 29 days, which truncates to 0 months.
      • PostgreSQL age function (not in RisingWave yet) returns 1 mon 1 day.
    • Minute: extract only returns the subfield. extract(minute from interval '1 hour 1 minute') is 1 rather than 61. We still need to extract(epoch) and calculate manually.
  • When the input type is date rather than timestamptz or timestamp, the subtraction returns int rather than interval. So we either need extract(day from date2::timestamp - date1)::int, or simply date2 - date1.
    • Do NOT use timestamptz2::date - timestamptz1::date. The cast is timezone-dependent.

@fuyufjh
Copy link
Member

fuyufjh commented Oct 4, 2023

cc. @matanper

@matanper
Copy link

matanper commented Oct 4, 2023

@xiangjinwu Thanks for the reply.
Right now I'm working with date_diff in Redshift (which is the same as SQL Server), and I'm using only days/hours so I don't have the weird quirks related to month/year.
But I think the more accurate way for me would be to work with intervals and be able to convert it to the given time unit something like extract(minute from interval '1 hour 1 minute') which returns 61

@xiangjinwu xiangjinwu changed the title feature request: support date_diff function feature request: a function to extract units in interval Oct 4, 2023
@xxchan
Copy link
Member

xxchan commented Oct 9, 2023

Would this be a case suitable to be solved by SQL UDF (#10151)?

@fuyufjh fuyufjh modified the milestones: release-1.3, release-1.4 Oct 10, 2023
@fuyufjh fuyufjh assigned KeXiangWang and unassigned KeXiangWang Oct 11, 2023
@fuyufjh
Copy link
Member

fuyufjh commented Oct 11, 2023

Is there any reference from other databases/systems?

@KeXiangWang
Copy link
Contributor

Hi, @matanper. (EXTRACT(EPOCH FROM date2 - date1) / 86400)::int could be a feasible trick for your case, currently. We think it is not a too complicated workaround. Since PostgreSQL does not provide a function for date_diff, and we tend to keep risingwave's syntax consistent with PostgreSQL, we've chosen not to make alterations in this regard.

This is our decision for now. Please keep us informed if you face any further issues. We're open to revisiting this decision if needed.

@KeXiangWang KeXiangWang closed this as not planned Won't fix, can't repro, duplicate, stale Oct 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants