Ramin Gharib created FLINK-41281:
------------------------------------

             Summary: Allow CAST from a VARIANT timestamp to the other temporal 
types
                 Key: FLINK-41281
                 URL: https://issues.apache.org/jira/browse/FLINK-41281
             Project: Flink
          Issue Type: Improvement
          Components: Table SQL / API
            Reporter: Ramin Gharib
             Fix For: 2.5.0


h3. Problem

A cast from {{VARIANT}} accepts a timestamp only for its own type. A variant 
{{TIMESTAMP_LTZ}} casts to {{TIMESTAMP_LTZ(p)}} and fails for every other 
temporal target. With the session time zone {{Europe/Berlin}} and 
{{v_timestamp_ltz = CAST(TO_TIMESTAMP_LTZ(1704151800123, 3) AS VARIANT)}}, the 
instant {{2024-01-01 23:30:00.123Z}}:

||Query||Today||Proposed||
|{{CAST(v_timestamp_ltz AS TIMESTAMP(3))}}|fails with {{Cannot cast a VARIANT 
TIMESTAMP_LTZ value to TIMESTAMP(3). A VARIANT cast does not change the type of 
the stored value, so cast it to its own type first and then convert with a 
regular cast.}}|{{2024-01-02 00:30:00.123}}|
|{{CAST(v_timestamp_ltz AS DATE)}}|fails with {{VariantTypeException: Expected 
type DATE but got TIMESTAMP_LTZ}}|{{2024-01-02}}|
|{{CAST(v_timestamp_ltz AS TIME(3))}}|fails with {{Cannot cast a VARIANT 
TIMESTAMP_LTZ value to TIME(3). ...}}|{{00:30:00.123}}|

Today a user has to know the stored kind and nest two casts, such as 
{{CAST(CAST(v AS TIMESTAMP_LTZ(3)) AS DATE)}}. A column that mixes 
{{TIMESTAMP}} and {{TIMESTAMP_LTZ}} values needs a chain of {{TRY_CAST}} calls.

h3. Proposal

A stored {{TIMESTAMP}} or {{TIMESTAMP_LTZ}}, including the nanosecond kinds, 
casts to the other temporal types the same way a regular cast from that type 
does, using the session time zone.

||Stored kind||Today||Adds||
|{{TIMESTAMP}}, {{TIMESTAMP_NS}}|{{TIMESTAMP(p)}}|{{TIMESTAMP_LTZ(p)}}, 
{{DATE}}, {{TIME(p)}}|
|{{TIMESTAMP_LTZ}}, {{TIMESTAMP_LTZ_NS}}|{{TIMESTAMP_LTZ(p)}}|{{TIMESTAMP(p)}}, 
{{DATE}}, {{TIME(p)}}|
|{{DATE}}|{{DATE}}|nothing|
|{{TIME}}|{{TIME(p)}}|nothing|

* {{DATE}} and {{TIME}} stay own-type only. Widening them would add something 
the value never had: a time of day, a date, or a zone offset. The regular 
{{TIME}} to {{TIMESTAMP}} cast shows the problem, since it fills in 1970-01-01 
(FLINK-24423).
* A {{DATE}} target that gets any other kind fails with the standard VARIANT 
cast message instead of the raw {{VariantTypeException}}.
* {{VARIANT_GET}} and {{TRY_VARIANT_GET}} follow the same rules.
* Values are read through {{java.time}}, not the millisecond helpers of the 
regular casts, which are wrong before 1970 (see the linked bug).
* The VARIANT section of {{data-types.md}} is updated.

Trade-off: casts to {{DATE}} and {{TIME}} drop part of the timestamp, while the 
numeric rule rejects {{7.2}} to {{INT}}. Cutting off fractional seconds beyond 
the target precision is already allowed, and Spark, Snowflake and Trino apply 
their regular cast rules here.

h3. Tests

* The queries above, for {{TIMESTAMP}} and {{TIMESTAMP_LTZ}} with the micro and 
nanosecond kinds, in two session time zones.
* A value before 1970 to {{DATE}} and {{TIME}}.
* Stored {{DATE}} and {{TIME}} still fail for the other targets, and 
{{TRY_CAST}} returns NULL.




--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to