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)