Repository navigation
feat: support TIME(p) SQL types #27316
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?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -806,11 +806,20 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> { | |
| )) | ||
| } | ||
| SQLDataType::Date => Ok(DataType::Date32), | ||
| SQLDataType::Time(None, tz_info) => { | ||
| SQLDataType::Time(precision, tz_info) | ||
| if precision.is_none() || [0, 3, 6, 9].contains(&precision.unwrap()) => | ||
| { | ||
| if *tz_info == TimezoneInfo::None | ||
| || *tz_info == TimezoneInfo::WithoutTimeZone | ||
| { | ||
| Ok(DataType::Time64(TimeUnit::Nanosecond)) | ||
| let data_type = match precision { | ||
| Some(0) => DataType::Time32(TimeUnit::Second), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct me if I am wrong but TIME(0), TIME(3) and TIME(6) now give Time32(s), Time32(ms) and Time64(us), but DataFusion has no rule to compare two time values with different units, so these columns cannot be compared, joined or IN-listed against plain TIME values?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe that would be a good follow on to track in a separate ticket |
||
| Some(3) => DataType::Time32(TimeUnit::Millisecond), | ||
| Some(6) => DataType::Time64(TimeUnit::Microsecond), | ||
| None | Some(9) => DataType::Time64(TimeUnit::Nanosecond), | ||
| _ => unreachable!(), | ||
| }; | ||
| Ok(data_type) | ||
| } else { | ||
| // We don't support TIMETZ and TIME WITH TIME ZONE for now | ||
| not_impl_err!("Unsupported SQL type {sql_type}") | ||
|
|
@@ -880,7 +889,7 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> { | |
| | SQLDataType::CharacterLargeObject(_) | ||
| | SQLDataType::CharLargeObject(_) | ||
| | SQLDataType::Timestamp(_, _) | ||
| | SQLDataType::Time(Some(_), _) | ||
| | SQLDataType::Time(_, _) | ||
| | SQLDataType::Dec(_) | ||
| | SQLDataType::BigNumeric(_) | ||
| | SQLDataType::BigDecimal(_) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -749,6 +749,85 @@ select date '1994-01-01' - interval '1' day as date; | |
| ---- | ||
| 1993-12-31 | ||
|
|
||
| # TIME precision selects the Arrow unit; the default remains nanoseconds. | ||
| query TTTTT | ||
| SELECT arrow_typeof(CAST(NULL AS TIME)) AS t, | ||
| arrow_typeof(CAST(NULL AS TIME(0))) AS s, | ||
| arrow_typeof(CAST(NULL AS TIME(3))) AS ms, | ||
| arrow_typeof(CAST(NULL AS TIME(6))) AS us, | ||
| arrow_typeof(CAST(NULL AS TIME(9))) AS ns; | ||
| ---- | ||
| Time64(ns) Time32(s) Time32(ms) Time64(µs) Time64(ns) | ||
|
|
||
| # String casts truncate fractional seconds to the requested precision. | ||
| query DDDD | ||
| SELECT CAST('12:34:56.123456789' AS TIME(0)) AS s, | ||
| CAST('12:34:56.123456789' AS TIME(3)) AS ms, | ||
| CAST('12:34:56.123456789' AS TIME(6)) AS us, | ||
| CAST('12:34:56.123456789' AS TIME(9)) AS ns; | ||
| ---- | ||
| 12:34:56 12:34:56.123 12:34:56.123456 12:34:56.123456789 | ||
|
|
||
| # Column declarations use the same mapping, including WITHOUT TIME ZONE. | ||
| statement ok | ||
| CREATE TABLE times ( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new |
||
| t TIME WITHOUT TIME ZONE, | ||
| s TIME(0) WITHOUT TIME ZONE, | ||
| ms TIME(3) WITHOUT TIME ZONE, | ||
| us TIME(6) WITHOUT TIME ZONE, | ||
| ns TIME(9) WITHOUT TIME ZONE | ||
| ); | ||
|
|
||
| statement ok | ||
| INSERT INTO times VALUES ( | ||
| '12:34:56.123456789', '12:34:56.123456789', '12:34:56.123456789', | ||
| '12:34:56.123456789', '12:34:56.123456789' | ||
| ), (NULL, NULL, NULL, NULL, NULL); | ||
|
|
||
| query DDDDD rowsort | ||
| SELECT * FROM times; | ||
| ---- | ||
| 12:34:56.123456789 12:34:56 12:34:56.123 12:34:56.123456 12:34:56.123456789 | ||
| NULL NULL NULL NULL NULL | ||
|
|
||
| query TTTTT | ||
| SELECT arrow_typeof(t), arrow_typeof(s), arrow_typeof(ms), arrow_typeof(us), arrow_typeof(ns) | ||
| FROM times LIMIT 1; | ||
| ---- | ||
| Time64(ns) Time32(s) Time32(ms) Time64(µs) Time64(ns) | ||
|
|
||
| # Unsupported precisions, including values beyond nanoseconds, remain errors. | ||
| statement error | ||
| SELECT CAST('12:34:56' AS TIME(1)); | ||
| ---- | ||
| DataFusion error: This feature is not implemented: Unsupported SQL type TIME(1) | ||
|
|
||
|
|
||
| statement error | ||
| CREATE TABLE invalid_time (t TIME(12)); | ||
| ---- | ||
| DataFusion error: This feature is not implemented: Unsupported SQL type TIME(12) | ||
|
|
||
|
|
||
| # Arrow time types have no time zone. | ||
| statement error | ||
| SELECT CAST('12:34:56' AS TIME WITH TIME ZONE); | ||
| ---- | ||
| DataFusion error: This feature is not implemented: Unsupported SQL type TIME WITH TIME ZONE | ||
|
|
||
|
|
||
| statement error | ||
| SELECT CAST('12:34:56' AS TIME(6) WITH TIME ZONE); | ||
| ---- | ||
| DataFusion error: This feature is not implemented: Unsupported SQL type TIME(6) WITH TIME ZONE | ||
|
|
||
|
|
||
| statement error | ||
| SELECT CAST('12:34:56' AS TIMETZ(6)); | ||
| ---- | ||
| DataFusion error: This feature is not implemented: Unsupported SQL type TIMETZ(6) | ||
|
|
||
|
|
||
| # cast_string_to_time() | ||
| query DDDD | ||
| select | ||
|
|
||
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.
The precision guard and the precision-to-TimeUnit match, including
_ => unreachable!(), are copied from the TIMESTAMP arm instead of shared.