Ramin Gharib created FLINK-39666:
------------------------------------

             Summary: Fix TO_TIMESTAMP_LTZ multiple edge-case bugs in precision 
handling
                 Key: FLINK-39666
                 URL: https://issues.apache.org/jira/browse/FLINK-39666
             Project: Flink
          Issue Type: Bug
          Components: Table SQL / API, Table SQL / Planner
            Reporter: Ramin Gharib


Follow-up review of FLINK-39244 uncovered five bugs. All are reproducible on 
master at \{{25493ac2a95}}.

h2. 1. \{{toTimestampData(double, int)}} overflows near year 9999

The range check on \{{epoch / 10^precision}} passes, then \{{(long) (epoch * 
10^(9 - precision))}} saturates.

{code:java}
DateTimeUtils.toTimestampData(253402300799.0, 0)
// expected: 9999-12-31T23:59:59Z
// actual:   2262-04-11T23:47:16.854775807Z
{code}

h2. 2. \{{epochToTimestampData}} does not validate precision

Negative precision makes \{{Math.floorDiv}} throw \{{ArithmeticException: / by 
zero}}. Precision > 9 silently returns \{{1970-01-01T00:00:00Z}}. Expected: 
return \{{null}} for precision outside \{{[0, 9]}}.

h2. 3. \{{precisionFromFormat}} only counts trailing \{{'S'}} characters

{code:java}
DateTimeUtils.precisionFromFormat("yyyy-MM-dd HH:mm:ss.SSSSSS X");  // returns 
3, expected 6
DateTimeUtils.precisionFromFormat("yyyy-MM-dd HH:mm:ss.SSSS'Z'");   // returns 
3, expected 4
{code}

The method should detect the \{{S}} run inside the pattern, ignoring quoted 
sections.

h2. 4. \{{ValueLiteralExpression.canRepresentAsLong}} off-by-one

The check ignores the nanos term \{{toEpochValue}} adds. At \{{epochSeconds == 
9223372036}} and precision 9, any \{{nanos > 854_775_807}} overflows and emits 
a wrapped negative literal.

{code:java}
new ValueLiteralExpression(
        Instant.ofEpochSecond(9223372036L, 900_000_000),
        DataTypes.TIMESTAMP_LTZ(9).notNull())
    .asSerializableString(DefaultSqlFactory.INSTANCE);
// expected: TO_TIMESTAMP_LTZ('2262-04-11 23:47:16.900000000', 'yyyy-MM-dd 
HH:mm:ss.SSSSSSSSS', 'UTC')
// actual:   TO_TIMESTAMP_LTZ(-9223372036809551616, 9)
{code}

h2. 5. Non-literal precision bypasses \{{validatePrecision}}

{\{ToTimestampLtzTypeStrategy.validatePrecision}} only fires when the precision 
argument is a literal. For a column-valued precision, validation is skipped and 
the raw row value reaches the runtime, triggering issue 2.

{code:sql}
SELECT TO_TIMESTAMP_LTZ(epoch, prec) FROM t  -- prec = -1 throws, prec = 10 
returns epoch 0
{code}

h2. Test coverage

Failing tests for all five issues exist locally:

* New \{{DateTimeUtilsTest}} and an added case in 
\{{ExpressionTest#testTimestampLtzPrecisionAsSerializableString}} in 
\{{flink-table-common}}.
* Two new \{{TestSetSpec}} blocks in 
\{{TimeFunctionsITCase#toTimestampLtzTestCases}} in \{{flink-table-planner}}.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to