[
https://issues.apache.org/jira/browse/CALCITE-5266?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18110499#comment-18110499
]
Aleksandr Efimov commented on CALCITE-5266:
-------------------------------------------
Checking on main at 1f94e23fa, the millisecond representation CALCITE-5919
points at is now the only place the precision goes. The type, the literal and
the plan all carry it — a row prints as {{13:30:25.575401:TIME(6)}} — and since
CALCITE-7529 landed in 1.43.0, casts between literals carry it too.
Which makes the symptoms filed separately one bug at one boundary. Reduced with
{{PROJECT_REDUCE_EXPRESSIONS}}, with the first line being the example from
CALCITE-5919:
{code}
EXTRACT(MICROSECOND FROM TIME '13:30:25.575401') -> 25575000 (expected
25575401) CALCITE-5919
EXTRACT(MICROSECOND FROM TIME '13:30:25.575') -> 25575000 TIME(6) and
TIME(3) agree
TIMESTAMPADD(MICROSECOND, 1, ...00:00:00.000000) -> unchanged
CALCITE-3530
TIMESTAMPDIFF(MICROSECOND, ...000001, ...000002) -> 0 (expected 1)
CALCITE-3530
TIMESTAMPDIFF(NANOSECOND, 1500-01-01, 2500-01-01) -> -5336492947419103232
CALCITE-3529
{code}
Anything at millisecond granularity or coarser is right: {{EXTRACT(MILLISECOND
...)}} gives 25575 and {{EXTRACT(SECOND ...)}} gives 25. The last line is a
positive span returning a negative number, silently, because nanoseconds
overflow a long.
On the representation itself, CALCITE-5919 already suggests switching
implementation once a type needs more than about 31 bits. Counting the units
each type would actually need puts a number on that criterion:
||type||today||precision 6||precision 9||
|TIME|int, ms of day, 27 bits|needs long, 37 bits|long, 47 bits|
|TIMESTAMP|long ms, +/-292M years|long us, +/-292k years|long ns, 1678..2262
only|
|INTERVAL day-time|long ms, fits to start precision 10|long us, fits to 8|long
ns, fits to 5|
Widening int to long therefore covers TIME all the way to TIME(9), without wide
arithmetic. A representation that cannot be an integral type is needed in
exactly two corners: TIMESTAMP(9) outside 1678..2262, and a day-time interval
whose leading precision is above 5 — Calcite's own limit is
MAX_INTERVAL_START_PRECISION = 10.
On the Avatica side, which this issue already flags as needing its own answer,
the numbers are worth having. Core calls DateTimeUtils 142 times across 23
files, and its public signatures are typed in milliseconds:
{{unixTimeExtract(TimeUnitRange, int time)}}, {{unixTimestampToString(long
timestamp, int precision)}} — where the precision argument only affects
formatting, so a TIMESTAMP(6) rendered from that value can only have zeros
after the third digit. The whole file mentions microseconds or nanoseconds
once. So the representation question reaches a separate release cycle and a
wire protocol with its own compatibility promises, which seems a bigger
constraint than the 31 files in core that assume MILLIS_PER_*.
Two things I cannot settle from the code, and would rather ask than assume:
Is limiting TIMESTAMP(9) to 1678..2262 acceptable? Arrow and pandas both made
that trade for nanosecond timestamps. If it is, an integral runtime unit chosen
from the declared precision covers everything except very wide day-time
intervals, and the wide-arithmetic path shrinks to a corner rather than being
the design.
And should the change go through Avatica's public API, or should core stop
routing high-precision paths through DateTimeUtils and keep its own helpers?
The first coordinates two release cycles; the second duplicates logic but
leaves the wire protocol alone.
I came here from CALCITE-4543, the same root cause on the literal side, and
would rather build on a decision than guess at one.
> Increase precision of TIMESTAMP, INTERVAL types to microseconds, nanoseconds
> ----------------------------------------------------------------------------
>
> Key: CALCITE-5266
> URL: https://issues.apache.org/jira/browse/CALCITE-5266
> Project: Calcite
> Issue Type: Improvement
> Components: core
> Reporter: Dmitry Sysolyatin
> Priority: Major
>
> TIMESTAMP, INTERVAL types can preserve only milliseconds, because internal
> TIMESTAMP representation is Long. But it would be good to extend precision to
> microseconds and nanoseconds.
> I suggest to use standard java.time classes for representing TIMESTAMP and
> INTERVAL type internally:
> # TIMESTAMP type can be represent like java.time.Instant
> # INTERVAL type can be represent like java.time.Period + java.time.Duration
> What do you guys think ?
--
This message was sent by Atlassian Jira
(v8.20.10#820010)