[analytics-engine] PPL date/time/timestamp fixes — format, overloads, span types, invalid literals#22045
Conversation
PR Reviewer Guide 🔍(Review updated until commit 28279be)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to 643892c Explore these optional code suggestions:
Previous suggestionsSuggestions up to commit c5b4995
Suggestions up to commit 28279be
Suggestions up to commit 5bf9be5
Suggestions up to commit 196a140
Suggestions up to commit 243f8fa
|
4026e1d to
510c16d
Compare
|
Persistent review updated to latest commit 510c16d |
510c16d to
b6c3cfb
Compare
|
Persistent review updated to latest commit b6c3cfb |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #22045 +/- ##
============================================
+ Coverage 73.36% 73.38% +0.02%
- Complexity 75504 75556 +52
============================================
Files 6038 6038
Lines 342954 342954
Branches 49340 49340
============================================
+ Hits 251592 251668 +76
+ Misses 71303 71280 -23
+ Partials 20059 20006 -53 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
b6c3cfb to
243f8fa
Compare
|
Persistent review updated to latest commit 243f8fa |
243f8fa to
196a140
Compare
|
Persistent review updated to latest commit 196a140 |
196a140 to
5bf9be5
Compare
|
❌ Gradle check result for 5bf9be5: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
expani
left a comment
There was a problem hiding this comment.
Thanks for taking this up @vinaykpud
Most of my comments are around making the code short which could be follow-ups.
Just have a couple of things that seems odd specially the QTF test fix
7fb66f0 to
28279be
Compare
|
Persistent review updated to latest commit 28279be |
|
❌ Gradle check result for 28279be: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
28279be to
c5b4995
Compare
|
❌ Gradle check result for c5b4995: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
|
Thanks @expani , replied to the comments |
|
❌ Gradle check result for 643892c: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
643892c to
38c286a
Compare
|
❌ Gradle check result for 38c286a: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
- ArrowValues: scalar + list temporal cells use space separator; time renders as HH:mm:ss[.frac] (no 1970-01-01 prefix); nanos preserved. - ArrowValues: post-process ISO-T VarChar cells from native CAST -> space. - CastToVarcharRewriter (new): boolean -> varchar emits TRUE/FALSE. - ListAggregateMultiTypeIT: assertions updated for new format. Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com>
… TIME - week() / week_of_year() default to mode 0 (Sunday-start) instead of ISO. - str_to_date %b parses Jan/Feb/.../Dec to month number. - date_format adds %c (month), %U %u %V %v (week numbers), %P (lowercase AM/PM). - unix_timestamp accepts numeric YYYYMMDDhhmmss literal. - convert_tz returns NULL on out-of-range tz instead of throwing. - cast(<datetime-string> AS TIME) strips date prefix and keeps the time portion. Adds os_week and os_strftime Rust UDFs (rust/src/udf/) wired through OsWeekAdapter and the existing format / parse paths. Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com>
Pre-isthmus CastTemporalLiteralValidator and per-adapter validation surface malformed string literals as IllegalArgumentException with the typed message "<type>:<value> in unsupported format, please use '<pattern>'", replacing the opaque Arrow Parser error / StreamException at HTTP 500. Covers: - CAST(<lit> AS DATE/TIME/TIMESTAMP) and TIMESTAMPADD/DIFF string args (CastTemporalLiteralValidator RexShuttle). - DATE / TIME / DATE_FORMAT / TIME_FORMAT / DATE_PART unit-aware operands (per-adapter validation). - HOUR(<bad-time>) and STR_TO_DATE with out-of-range month/day (was silent HTTP 200 with wrong row). DATETIME(<invalid>) folds to NULL TIMESTAMP at plan time per legacy SQL DATETIME-of-invalid semantics. Shared parsing routes through DatetimeLiteralValidator so accept-set and format-hint message stay in one place. Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com>
Adds the substrait-bind paths for ten function overloads that previously failed isthmus lowering with "Unable to convert call <fn>(<sig>)": - DATETIME(string, tz): plan-time fold for all-literal input (NULL on bad value/tz); column-input rewrites to convert_tz with the source offset stripped. tz bounds tightened to MySQL DATETIME range [-13:59, +14:00]. - now(fsp) / sysdate(fsp): drop FSP arg before mapping to DataFusion's niladic now(). - DATE_ADD / DATE_SUB(TIME, interval) and TIMESTAMPADD(unit, n, TIME): anchor TIME to today UTC, then DATETIME_PLUS with the unit interval. - TIMESTAMPADD standalone: new adapter lowering to DATETIME_PLUS so the call binds without a substrait sig for TIMESTAMPADD itself. - TIMESTAMPDIFF standalone: (to_unixtime(t2) - to_unixtime(t1)) scaled by the out-unit factor; MONTH/QUARTER/YEAR use 30/90/365-day approximations matching legacy SQL plugin. - DATE_PART(unit, TIME) and DATE_PART(unit, bare-time-string): today-UTC anchor so the (string, precision_timestamp<P>) sig binds. - FROM_UNIXTIME(epoch, format): compose date_format around the 1-arg UDF. - SPAN(timestamp, N, 'M'|'q'|'y'): rewrite calendar-unit spans to date_bin with a fixed 1970-01-01 origin. - CONVERT_TZ invalid timestamp literal: plan-time fold to typed NULL. - microsecond(): single CAST to TIMESTAMP(6) so the µs fraction survives date_part (no intermediate TIMESTAMP cast that would clip to ms). Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com>
OpenSearchSchemaBuilder reads each date / date_nanos field's `format` mapping and routes date-only formats to DateOnlyType, time-only formats to TimeOnlyType (new UDT markers). Format detection in DateFormatClassifier mirrors the SQL plugin's OpenSearchDateType (named-format allow-lists + custom-pattern symbol scan). The UDT markers are TIMESTAMP-backed BasicSqlType subclasses — substrait wire stays Timestamp(ms) so DateParquetField is unchanged. Only the user-visible schema label flips. Result: - span(<date-typed>, …) returns a date column (not widened to timestamp). - span(<time-typed>, …) returns a time column. - Bucket values render as YYYY-MM-DD / HH:mm:ss (no 00:00:00 suffix, no 1970-01-01 prefix). Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com>
Lifted from fix/ai-substrait-call-unlowerable (PR 22014): - TIMESTAMP(<date col>, <time col>): 2-arg combine via from_unixtime(to_unixtime(date) + to_unixtime(time)). - HOUR / MINUTE / SECOND / MICROSECOND on a TIME literal: fold to BIGINT at plan time so the call doesn't need a precision_time substrait sig. PR 22014's other capabilities are already covered (or superseded) by the preceding clusters: TimestampAddAdapter and DatetimeAdapter 2-arg fold by B, TimestampDiffAdapter literal fold by B, FromUnixtimeAdapter 2-arg by B, ConvertTzAdapter all-literal fold by F (cleaner reconciliation). Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com>
Adds testTimeLiteralCastToDateRejected to CastTemporalLiteralValidatorTests. The rejection path itself was added in cluster C; this is the missing direct test for the time-string-to-DATE case. The two capabilities originally scoped under "cluster G" are landed elsewhere: - CAST cross-type permissiveness — already covered by cluster C's plan-time validators; only this test was missing. - span() over date_add-derived expr — landed as a sql/api fix on the fix/ai/cluster-g2-datetime-udt-normalize branch (DatetimeUdtNormalizeRule re-aligns RexInputRefs after child UDT normalization). Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com>
End-to-end IT covering query shapes fixed by the cluster-all branch: clusters D, F, C, B, A, plus the cherry-pick from PR 22014. Shapes sourced from tests/parquet/a-date-time-failed/ and tests/parquet/assertion-error-deep-dive/ topic folders. Each test method exercises one shape that was failing pre-fix and passes post-fix. Out of scope (deferred): - Timechart depth-15 planner guard - @timestamp:string schema regression in bin/auto-date-histogram - list() time-only stringification (sandbox-side fix needed) - chart timestamp-format and percentile algorithm shapes Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com>
These tests pass when sql/fix/ai/cluster-all (commits 3a172a743 cluster A and 2eebeddc cluster D) is installed; without those commits they fail with substrait schema mismatches or unbound function-call lowerings. Marking @AwaitsFix so the sandbox PR can merge before sql. Once sql PR is merged, this commit should be reverted. - DatetimeCoverageIT: 14 methods (cluster A span tests, cluster B/E/F two-arg DATETIME, microsecond preservation, format token spec, etc.) - DateTimeScalarFunctionsIT.testDateAddMillisecondIntervalOnTimestampColumn - TimestampFunctionIT.testShapeCTimeLiteralFoldsWithTodayUtc - TimestampFunctionIT.testTimeEqualsDateDoesNotCrash - TwoShardCommandIT.testReduceCorrectnessAcrossTwoShards Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com>
Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com>
38c286a to
50d8bd6
Compare
…s→9) The UDT branch in OpenSearchSchemaBuilder.buildLeafType bypassed the precision switch added by opensearch-project#22049, so a date_nanos field with a date-only or time-only mapping format produced TIMESTAMP(0). The schema/parquet-read mismatch surfaced on multi-shard sort as RowConverter "Timestamp(ms) got Timestamp(ns)". Thread the source-type precision through DateOnlyType / TimeOnlyType constructors and append it to the digest so canonicalization keeps date-precision-3 and date_nanos-precision-9 distinct (without the digest change, type-factory caching collapses them). Tests: 5 unit assertions in OpenSearchSchemaBuilderTests pinning the precision contract for plain TIMESTAMP, DateOnlyType, and TimeOnlyType paths over both date and date_nanos sources, plus DateNanosUDTPrecisionIT exercising the 2-shard sort regression end-to-end. Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com>
50d8bd6 to
55994fb
Compare
|
❌ Gradle check result for 55994fb: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com> # Conflicts: # sandbox/plugins/analytics-backend-datafusion/rust/src/udf/os_strftime.rs # sandbox/plugins/analytics-backend-datafusion/src/main/java/org/opensearch/be/datafusion/ConvertTzAdapter.java # sandbox/plugins/analytics-backend-datafusion/src/main/java/org/opensearch/be/datafusion/DataFusionAnalyticsBackendPlugin.java # sandbox/plugins/analytics-backend-datafusion/src/main/java/org/opensearch/be/datafusion/DatePartAdapters.java # sandbox/plugins/analytics-backend-datafusion/src/main/java/org/opensearch/be/datafusion/MicrosecondAdapter.java # sandbox/plugins/analytics-backend-datafusion/src/main/java/org/opensearch/be/datafusion/TimestampAddAdapter.java # sandbox/plugins/analytics-backend-datafusion/src/main/java/org/opensearch/be/datafusion/TimestampDiffAdapter.java
2346ecf to
9d24d5c
Compare
|
❌ Gradle check result for 9d24d5c: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
… span types, invalid literals (opensearch-project#22045) * datetime stringify uses space, time has no epoch prefix - ArrowValues: scalar + list temporal cells use space separator; time renders as HH:mm:ss[.frac] (no 1970-01-01 prefix); nanos preserved. - ArrowValues: post-process ISO-T VarChar cells from native CAST -> space. - CastToVarcharRewriter (new): boolean -> varchar emits TRUE/FALSE. - ListAggregateMultiTypeIT: assertions updated for new format. Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com> * PPL date function gap fixes: week modes, format tokens, tz NULL, cast TIME - week() / week_of_year() default to mode 0 (Sunday-start) instead of ISO. - str_to_date %b parses Jan/Feb/.../Dec to month number. - date_format adds %c (month), %U %u %V %v (week numbers), %P (lowercase AM/PM). - unix_timestamp accepts numeric YYYYMMDDhhmmss literal. - convert_tz returns NULL on out-of-range tz instead of throwing. - cast(<datetime-string> AS TIME) strips date prefix and keeps the time portion. Adds os_week and os_strftime Rust UDFs (rust/src/udf/) wired through OsWeekAdapter and the existing format / parse paths. Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com> * PPL invalid date literals reject with typed format-hint message Pre-isthmus CastTemporalLiteralValidator and per-adapter validation surface malformed string literals as IllegalArgumentException with the typed message "<type>:<value> in unsupported format, please use '<pattern>'", replacing the opaque Arrow Parser error / StreamException at HTTP 500. Covers: - CAST(<lit> AS DATE/TIME/TIMESTAMP) and TIMESTAMPADD/DIFF string args (CastTemporalLiteralValidator RexShuttle). - DATE / TIME / DATE_FORMAT / TIME_FORMAT / DATE_PART unit-aware operands (per-adapter validation). - HOUR(<bad-time>) and STR_TO_DATE with out-of-range month/day (was silent HTTP 200 with wrong row). DATETIME(<invalid>) folds to NULL TIMESTAMP at plan time per legacy SQL DATETIME-of-invalid semantics. Shared parsing routes through DatetimeLiteralValidator so accept-set and format-hint message stay in one place. Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com> * Add missing PPL date function overloads Adds the substrait-bind paths for ten function overloads that previously failed isthmus lowering with "Unable to convert call <fn>(<sig>)": - DATETIME(string, tz): plan-time fold for all-literal input (NULL on bad value/tz); column-input rewrites to convert_tz with the source offset stripped. tz bounds tightened to MySQL DATETIME range [-13:59, +14:00]. - now(fsp) / sysdate(fsp): drop FSP arg before mapping to DataFusion's niladic now(). - DATE_ADD / DATE_SUB(TIME, interval) and TIMESTAMPADD(unit, n, TIME): anchor TIME to today UTC, then DATETIME_PLUS with the unit interval. - TIMESTAMPADD standalone: new adapter lowering to DATETIME_PLUS so the call binds without a substrait sig for TIMESTAMPADD itself. - TIMESTAMPDIFF standalone: (to_unixtime(t2) - to_unixtime(t1)) scaled by the out-unit factor; MONTH/QUARTER/YEAR use 30/90/365-day approximations matching legacy SQL plugin. - DATE_PART(unit, TIME) and DATE_PART(unit, bare-time-string): today-UTC anchor so the (string, precision_timestamp<P>) sig binds. - FROM_UNIXTIME(epoch, format): compose date_format around the 1-arg UDF. - SPAN(timestamp, N, 'M'|'q'|'y'): rewrite calendar-unit spans to date_bin with a fixed 1970-01-01 origin. - CONVERT_TZ invalid timestamp literal: plan-time fold to typed NULL. - microsecond(): single CAST to TIMESTAMP(6) so the µs fraction survives date_part (no intermediate TIMESTAMP cast that would clip to ms). Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com> * PPL span(date) and span(time) preserve column type OpenSearchSchemaBuilder reads each date / date_nanos field's `format` mapping and routes date-only formats to DateOnlyType, time-only formats to TimeOnlyType (new UDT markers). Format detection in DateFormatClassifier mirrors the SQL plugin's OpenSearchDateType (named-format allow-lists + custom-pattern symbol scan). The UDT markers are TIMESTAMP-backed BasicSqlType subclasses — substrait wire stays Timestamp(ms) so DateParquetField is unchanged. Only the user-visible schema label flips. Result: - span(<date-typed>, …) returns a date column (not widened to timestamp). - span(<time-typed>, …) returns a time column. - Bucket values render as YYYY-MM-DD / HH:mm:ss (no 00:00:00 suffix, no 1970-01-01 prefix). Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com> * PPL TIMESTAMP(date, time) combine and HOUR-of-TIME-literal fold Lifted from fix/ai-substrait-call-unlowerable (PR 22014): - TIMESTAMP(<date col>, <time col>): 2-arg combine via from_unixtime(to_unixtime(date) + to_unixtime(time)). - HOUR / MINUTE / SECOND / MICROSECOND on a TIME literal: fold to BIGINT at plan time so the call doesn't need a precision_time substrait sig. PR 22014's other capabilities are already covered (or superseded) by the preceding clusters: TimestampAddAdapter and DatetimeAdapter 2-arg fold by B, TimestampDiffAdapter literal fold by B, FromUnixtimeAdapter 2-arg by B, ConvertTzAdapter all-literal fold by F (cleaner reconciliation). Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com> * test(sandbox): backfill CAST(time-string AS DATE) rejection test Adds testTimeLiteralCastToDateRejected to CastTemporalLiteralValidatorTests. The rejection path itself was added in cluster C; this is the missing direct test for the time-string-to-DATE case. The two capabilities originally scoped under "cluster G" are landed elsewhere: - CAST cross-type permissiveness — already covered by cluster C's plan-time validators; only this test was missing. - span() over date_add-derived expr — landed as a sql/api fix on the fix/ai/cluster-g2-datetime-udt-normalize branch (DatetimeUdtNormalizeRule re-aligns RexInputRefs after child UDT normalization). Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com> * test(sandbox): add DatetimeCoverageIT for cluster-all regression gate End-to-end IT covering query shapes fixed by the cluster-all branch: clusters D, F, C, B, A, plus the cherry-pick from PR 22014. Shapes sourced from tests/parquet/a-date-time-failed/ and tests/parquet/assertion-error-deep-dive/ topic folders. Each test method exercises one shape that was failing pre-fix and passes post-fix. Out of scope (deferred): - Timechart depth-15 planner guard - @timestamp:string schema regression in bin/auto-date-histogram - list() time-only stringification (sandbox-side fix needed) - chart timestamp-format and percentile algorithm shapes Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com> * test(sandbox): @AwaitsFix on tests that require sql cluster A/D These tests pass when sql/fix/ai/cluster-all (commits 3a172a743 cluster A and 2eebeddc cluster D) is installed; without those commits they fail with substrait schema mismatches or unbound function-call lowerings. Marking @AwaitsFix so the sandbox PR can merge before sql. Once sql PR is merged, this commit should be reverted. - DatetimeCoverageIT: 14 methods (cluster A span tests, cluster B/E/F two-arg DATETIME, microsecond preservation, format token spec, etc.) - DateTimeScalarFunctionsIT.testDateAddMillisecondIntervalOnTimestampColumn - TimestampFunctionIT.testShapeCTimeLiteralFoldsWithTodayUtc - TimestampFunctionIT.testTimeEqualsDateDoesNotCrash - TwoShardCommandIT.testReduceCorrectnessAcrossTwoShards Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com> * PR comments Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com> * DateOnly/TimeOnly UDTs carry source-type precision (date→3, date_nanos→9) The UDT branch in OpenSearchSchemaBuilder.buildLeafType bypassed the precision switch added by opensearch-project#22049, so a date_nanos field with a date-only or time-only mapping format produced TIMESTAMP(0). The schema/parquet-read mismatch surfaced on multi-shard sort as RowConverter "Timestamp(ms) got Timestamp(ns)". Thread the source-type precision through DateOnlyType / TimeOnlyType constructors and append it to the digest so canonicalization keeps date-precision-3 and date_nanos-precision-9 distinct (without the digest change, type-factory caching collapses them). Tests: 5 unit assertions in OpenSearchSchemaBuilderTests pinning the precision contract for plain TIMESTAMP, DateOnlyType, and TimeOnlyType paths over both date and date_nanos sources, plus DateNanosUDTPrecisionIT exercising the 2-shard sort regression end-to-end. Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com> --------- Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com>
Summary
Fixes a batch of PPL date/time/timestamp gaps on the analytics-engine (parquet-primary) path: format rendering, missing function overloads, invalid-literal error surface, span() column type preservation, and sub-second precision preservation.
Pairs with opensearch-project/sql#5521. Tests that depend on the sql siblings are gated with
@AwaitsFixand listed at the bottom of this description.Commits
datetime stringify uses space, time has no epoch prefixyyyy-MM-dd HH:mm:ss(space separator instead of ISO-T).HH:mm:ss(no1970-01-01epoch prefix).cast(boolean AS varchar)rewrites to upper-caseTRUE/FALSEto match PPL semantics.PPL date function gap fixes: week modes, format tokens, tz NULL, cast TIMEWEEK()/WEEK_OF_YEAR()default to mode 0 (Sunday-start, MySQL semantics) instead of ISO.STR_TO_DATEparses%b(Jan/Feb/.../Dec) abbreviations.DATE_FORMATadds%c %U %u %V %v %Ptokens.UNIX_TIMESTAMPaccepts numericYYYYMMDDhhmmssliterals.CONVERT_TZreturns NULL on out-of-range tz instead of throwing.CAST(<datetime-string> AS TIME)strips the date prefix.os_week(8-mode MySQLWEEK) andos_strftime(shared parse / render engine forDATE_FORMATandSTR_TO_DATE).PPL invalid date literals reject with typed format-hint messageIllegalArgumentExceptionwith the typed message"<type>:<value> in unsupported format, please use '<pattern>'", replacing the opaque Arrow Parser error / 500 StreamException.CAST(<lit> AS DATE/TIME/TIMESTAMP),TIMESTAMPADD/DIFFstring args, DATE/TIME/DATE_FORMAT/TIME_FORMAT/DATE_PART operands, and silent-success cases (HOUR('99:99:99'),STR_TO_DATEout-of-range month/day).DATETIME(<invalid>)folds to NULL TIMESTAMP at plan time.Add missing PPL date function overloadsTen function overloads that previously failed isthmus lowering with "Unable to convert call ..." now bind:
DATETIME(string, tz)— plan-time fold for literals; column input rewrites toconvert_tz.now(fsp)/sysdate(fsp)— drops the FSP argument.DATE_ADD(TIME, interval)andDATE_SUB(TIME, interval)— anchors TIME to today UTC.TIMESTAMPADDstandalone — lowers toDATETIME_PLUS+ interval.TIMESTAMPDIFFstandalone —to_unixtimedelta with unit scaling.DATE_PART(unit, TIME)— today-UTC anchor on TIME operands.FROM_UNIXTIME(epoch, format)— composesdate_formataround 1-arg UDF.SPAN(timestamp, N, 'M' | 'q' | 'y')— calendar-unitdate_binrewrite.CONVERT_TZinvalid timestamp literal — folds to typed NULL.microsecond()— single CAST toTIMESTAMP(6)so the µs fraction survivesdate_part.PPL span(date) and span(time) preserve column typeDateOnlyType/TimeOnlyTypeUDT markers in the schema builder.date/date_nanosfield with a date-only or time-onlyformatmapping now surfaces with the right user-visible label.span(<date col>, …)returns a date-typed bucket column (not widened to timestamp);span(<time col>, …)returns a time-typed bucket.Timestamp(ms)— only the schema label changes.PPL TIMESTAMP(date, time) combine and HOUR-of-TIME-literal foldTwo capabilities lifted from #22014:
TIMESTAMP(<date col>, <time col>)2-arg combine viafrom_unixtime(to_unixtime(date) + to_unixtime(time)).HOUR / MINUTE / SECOND / MICROSECONDon a TIME literal folds toBIGINTat plan time (avoids theprecision_timesubstrait gap).test(sandbox): backfill CAST(time-string AS DATE) rejection testCastTemporalLiteralValidatorTests.test(sandbox): add DatetimeCoverageIT for cluster-all regression gatetest(sandbox): @AwaitsFix on tests that require sql cluster A/D@AwaitsFixbecause they depend on the sql/core siblings (cluster A schema label + cluster D list-element formatter).fix(sandbox): DateOnly/TimeOnly UDTs carry source-type precision (date→3, date_nanos→9)#22049 added sub-second precision (
date→3,date_nanos→9) on the plain-TIMESTAMP path. TheDateOnlyType/TimeOnlyTypeUDT branch short-circuited before that switch, so adate_nanosfield with a date-only or time-onlyformatproducedTIMESTAMP(0)and broke multi-shard sort. Mirror the same precision selection on the UDT factories.Query shapes fixed
Format / output rendering
Function overloads — previously failed with
Unable to convert call ...Format tokens — date_format / str_to_date
Mode / range corrections
date_nanos sub-second precision (multi-shard sort)
Span column type preservation
Invalid literal rejection
Tests gated
@AwaitsFixuntil sql PR mergesThe following pass when the sql/core sibling PR is installed; without it they fail with substrait schema mismatches or unbound function-call lowerings.
DatetimeCoverageIT— 14 methods (cluster A span tests, cluster B 2-arg DATETIME, cluster E µs preservation, cluster F format/cast/maketime, max-time / max-timestamp boundaries).DateTimeScalarFunctionsIT.testDateAddMillisecondIntervalOnTimestampColumnTimestampFunctionIT.testShapeCTimeLiteralFoldsWithTodayUtcTimestampFunctionIT.testTimeEqualsDateDoesNotCrashTwoShardCommandIT.testReduceCorrectnessAcrossTwoShardsSites are searchable via
grep -rn "pull/<TBD>" sandbox/qa/and will be unmuted in a follow-up commit once the sql PR merges.