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 make_interval function #6951

Closed
Tracked by #8282 ...
liukun4515 opened this issue Jul 13, 2023 · 10 comments
Closed
Tracked by #8282 ...

support make_interval function #6951

liukun4515 opened this issue Jul 13, 2023 · 10 comments
Assignees

Comments

@liukun4515
Copy link
Contributor

          Do we have any method to convert or cast the integer type/integer expr with the timeunit to the interval?

@waitingkuo @alamb

I want to implement a app or function like this datetime + integer with timeunit, and the timeunit may be year,month,day.

I can't find the any method to convert the integer with timeunit to the interval, but in the PG which has a function make_interval() https://www.postgresql.org/docs/current/functions-datetime.html can do this.

I just can find a way to resolve the issue by using the concat method.

For example: I have a table like below, and want to convert the b with dayunit to interval

❯ \d test
+---------------+--------------+------------+-------------+-----------+-------------+
| table_catalog | table_schema | table_name | column_name | data_type | is_nullable |
+---------------+--------------+------------+-------------+-----------+-------------+
| datafusion    | public       | test       | a           | Date32    | NO          |
| datafusion    | public       | test       | b           | Int64     | NO          |
+---------------+--------------+------------+-------------+-----------+-------------+
2 rows in set. Query took 0.013 seconds.

Using the concat to get the utf8 expr which can be casted to interval.

❯   select cast(concat(b,' day') as interval), b from test;
+-------------------------------------------------------+---+
| concat(test.b,Utf8(" day"))                           | b |
+-------------------------------------------------------+---+
| 0 years 0 mons 2 days 0 hours 0 mins 0.000000000 secs | 2 |
+-------------------------------------------------------+---+

Originally posted by @liukun4515 in #3148 (comment)

@liukun4515
Copy link
Contributor Author

cc @alamb @waitingkuo please help to add this issue to #3148

@waitingkuo
Copy link
Contributor

@liukun4515
added, thank you

@waitingkuo
Copy link
Contributor

hi @liukun4515

Do you plan to support multiple time unit? for example column a as year, column b as month

@alamb
Copy link
Contributor

alamb commented Jul 13, 2023

I adding the make_interval function seems very reasonable to me.

arrow knows how to parse strings like 5 days 4 minutes so you could build up such a string using concat. However, if you already have the fields and you know what output interval type you want/need doing it with a specific function would likely be much more performant

@Tangruilin
Copy link
Contributor

@alamb Maybe you can assign it to me.

I can help with this issue

@milevin
Copy link

milevin commented Dec 14, 2024

Is anybody working on this? cc: @alamb

I could really use it in the work that I am doing. (Supporting interval multiplication/division by integers; supporting Date32 + integer).

If nobody's on it, I can take a stab

@alamb
Copy link
Contributor

alamb commented Dec 15, 2024

FWIW DataFusion already does support interval syntax (though not make_interval):

> select '2021-01-01'::timestamp + interval '1 year';
+-----------------------------------------------------------------------------------------------------------+
| Utf8("2021-01-01") + IntervalMonthDayNano("IntervalMonthDayNano { months: 12, days: 0, nanoseconds: 0 }") |
+-----------------------------------------------------------------------------------------------------------+
| 2022-01-01T00:00:00                                                                                       |
+-----------------------------------------------------------------------------------------------------------+
1 row(s) fetched.
Elapsed 0.045 seconds.

The cast workaround works ok too

@milevin
Copy link

milevin commented Dec 16, 2024

FWIW DataFusion already does support interval syntax

This is insufficient. Suppose we want to do something like this:

select make_interval(x, 'days') from (select 1 as x)

This wouldn't be representable using the interval syntax.

Why do I want to have it? I want to be able to write this, which works in Postgres:

select x * y as z from (select 5 as x, interval '2' day as y)

My current thinking is to desugar it into this:

select make_interval('month', x * date_part('month', y)) + make_interval('day', x * date_part('day', y)) + make_interval('nanosecond', x * date_part('nanosecond', y)) as z from (select 5 as x, interval '2' day as y)

Does this make sense? It's a little clunky, but that's my current working plan.

If somebody has a better idea, speak now or forever hold.

@findepi
Copy link
Member

findepi commented Dec 17, 2024

There is no reason for interval * integer syntax not to be supported. And once it's supported, not sure we need a new make_interval function.

Therefore I propose we re-purpose this issue to support interval * integer operator.

@alamb
Copy link
Contributor

alamb commented Dec 19, 2024

There is no reason for interval * integer syntax not to be supported. And once it's supported, not sure we need a new make_interval function.

Agreed

Therefore I propose we re-purpose this issue to support interval * integer operator.

I thought it might be clearer if we filed a new ticket with a clear description of the feature, so I did so in:

Thus closing this ticket as not planned. Please reopen or comment if you disagree

@alamb alamb closed this as not planned Won't fix, can't repro, duplicate, stale Dec 19, 2024
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

6 participants