-
Notifications
You must be signed in to change notification settings - Fork 2.5k
[CALCITE-7337] Add age function (enabled in PostgreSQL library) #4712
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
base: main
Are you sure you want to change the base?
Conversation
|
Postgresql -> PostgreSQL |
done, thanks |
e84cd34 to
7b827d7
Compare
7b827d7 to
4add80f
Compare
| } | ||
|
|
||
| /** SQL {@code AGE(timestamp1, timestamp2)} function. */ | ||
| private static String age(long timestamp1, long timestamp2) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please take a look at this code and see if it meets your requirements. I tested it locally, and it passed your test cases. The current code implementation seems somewhat unclear.
public static String age(long timestamp1, long timestamp2) {
ZonedDateTime zdt1 = Instant.ofEpochMilli(timestamp1)
.atZone(ZoneOffset.UTC);
ZonedDateTime zdt2 = Instant.ofEpochMilli(timestamp2)
.atZone(ZoneOffset.UTC);
Period period = Period.between(zdt2.toLocalDate(), zdt1.toLocalDate());
Duration duration = Duration.between(zdt2, zdt1);
int years = period.getYears();
int months = period.getMonths();
int days = period.getDays();
long totalSeconds = duration.getSeconds();
long hours = (totalSeconds / 3600) % 24;
long minutes = (totalSeconds / 60) % 60;
long seconds = totalSeconds % 60;
long millis = duration.toMillis() % 1000;
return String.format(Locale.ROOT,
"%d years %d mons %d days %d hours %d mins %.1f secs",
years, months, days, hours, minutes, seconds + millis / 1000.0
);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ZonedDateTime zdt1 = Instant.ofEpochMilli(timestamp1)
.atZone(ZoneOffset.UTC);
ZonedDateTime zdt2 = Instant.ofEpochMilli(timestamp2)
.atZone(ZoneOffset.UTC);Period period = Period.between(zdt2.toLocalDate(), zdt1.toLocalDate()); Duration duration = Duration.between(zdt2, zdt1); int years = period.getYears(); int months = period.getMonths(); int days = period.getDays(); long totalSeconds = duration.getSeconds(); long hours = (totalSeconds / 3600) % 24; long minutes = (totalSeconds / 60) % 60; long seconds = totalSeconds % 60; long millis = duration.toMillis() % 1000;
Thank you very much for your suggestion. The above code is being executed
SELECT AGE(timestamp '2023-12-25 00:00:00', timestamp '2020-01-01 23:59:59') FROM (VALUES (1)) t, Returned 3 years 11 mons 24 days 0 hours 0 mins 1.0 secs, but pgSQL returned
3 years 11 mons 23 days 0 hours 0 mins 1.0 secs, This test case did not pass, and one more thing is that String.form seems to be prohibited from use. The code I submitted for the first time did not pass the detection because of its use
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you're right. I think we can just add the test cases I mentioned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you're right. I think we can just add the test cases I mentioned.
Thank you for your reminder. We have added new test cases
| checkSqlResult("postgresql", | ||
| "SELECT AGE(timestamp '2023-12-25 00:00:00', timestamp '2020-01-01 23:59:59') FROM (VALUES (1)) t", | ||
| "EXPR$0=3 years 11 mons 23 days 0 hours 0 mins 1.0 secs\n"); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should add another test case.
checkSqlResult("postgresql",
"SELECT AGE(timestamp '2023-12-25 00:00:00.101', timestamp '2020-01-01 23:59:59.202') FROM (VALUES (1)) t",
"EXPR$0=3 years 11 mons 23 days 0 hours 0 mins 0.9 secs\n");
|
It was my oversight; I noticed that the results from pgsql are inconsistent with what you provided. The results you provided resemble the format of duckdb. please see pgsql result. current pr: pgsql: |
|
I used multiple clients to verify this issue again and found that |
I will change the logic of this part later. Thank you for your reminder to make this logic more rigorous |
1 similar comment
I will change the logic of this part later. Thank you for your reminder to make this logic more rigorous |
|
Because previously closed two related PR, some comments were lost (we can check if some of the changes can be moved to jira or this pr, so that others can understand what you had done, just a suggestion). |



jira:https://issues.apache.org/jira/projects/CALCITE/issues/CALCITE-7337
we can refer postgresql document about Position:
https://www.postgresql.org/docs/current/functions-datetime.html
link: #4689 / #4703