Repository navigation
Commit 096de8a
Fix timestamp precision (#255)
* Support timestamp-millis and timestamp-micros independently
Timestamp columns surfaced as TIMESTAMP(0) because Avro timestamp logical
types were mapped to TIMESTAMP with unspecified precision, and Calcite's
default RelDataTypeSystem caps datetime precision at 3 (milliseconds), so
micro/nanosecond precision could never survive.
- Add HoptimatorTypeSystem, which raises the datetime precision ceiling from
3 to 9 (matching Flink SQL's TIMESTAMP(0..9)).
- Map Avro timestamp-millis to TIMESTAMP(3) and timestamp-micros to
TIMESTAMP(6) in AvroConverter, and choose the logical type by precision on
the reverse path.
- Route the JDBC planner/validator through HoptimatorTypeSystem via the
Calcite typeSystem connection property, and repoint the standalone type
factories in the Avro conversion path.
- Carry datetime precision through generated DDL in ScriptImplementor (e.g.
TIMESTAMP(6)); a bare TIMESTAMP stays precision-less.
Adds unit coverage (type system, Avro mapping both directions, DDL
rendering), an end-to-end DDL Quidem test, and an integration script case.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Normalize tests onto HoptimatorTypeSystem
Swap RelDataTypeSystem.DEFAULT for HoptimatorTypeSystem.INSTANCE in test type
factories so tests mirror the type system used in production. Raising the
datetime precision ceiling does not affect existing assertions.
HoptimatorTypeSystemTest intentionally keeps RelDataTypeSystem.DEFAULT, since
it asserts the default's clamping behavior as the premise for the custom type
system. The delete-marked planner and catalog modules are left untouched.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Normalize remaining type factories onto HoptimatorTypeSystem
Route the remaining standalone type factories through HoptimatorTypeSystem so
nothing silently falls back to Calcite's default (which caps datetime
precision at 3).
- Main code: the compatibility validators (AvroTableValidator, Backward/
ForwardCompatibilityValidator) and RemoteTable/ArrayTable built row types
via new JavaTypeFactoryImpl() (default type system). With the default,
micro/nanosecond timestamps collapse to TIMESTAMP(3), so the compat
validators could not distinguish millis from micros. They now use
HoptimatorTypeSystem.INSTANCE.
- Tests: normalize the remaining JavaTypeFactoryImpl() and
RelDataTypeSystem.DEFAULT usages (demodb, planner, catalog, jdbc),
adding a test-scoped hoptimator-avro dependency where needed.
HoptimatorTypeSystemTest intentionally still references
RelDataTypeSystem.DEFAULT, since it exists to contrast the default's
clamping behavior against the custom type system.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Preserve JDBC temporal fractional-seconds precision (MySQL)
A JDBC source's temporal columns were mapped using only the SQL type name, so
MySqlTable produced TIMESTAMP(0) for a TIMESTAMP(3)/(6) column — the
fractional-seconds precision JDBC exposes via DECIMAL_DIGITS was dropped at the
JDBC layer. Downstream, the planner's row type showed TIMESTAMP(0) even though
the source carried milli/microsecond precision.
Read DECIMAL_DIGITS for temporal types (TIME/TIMESTAMP and their local-time-zone
variants) and build the column with that precision, so TIMESTAMP(3)/(6) survive.
Adds MySqlTableTest cases for millis/micros/time/no-fraction, and an integration
script (mysql-timestamp-precision.id) with an `events` source table whose
TIMESTAMP(3)/(6) columns are asserted end-to-end via !describe.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Preserve temporal precision across the JDBC federation
HoptimatorJdbcTable derived its row type from the wrapped Calcite JdbcTable,
whose type comes from DatabaseMetaData. That round-trip drops temporal
fractional-seconds precision: CalciteMetaImpl reports a TIMESTAMP's precision in
COLUMN_SIZE while JdbcSchema#getRelDataType reads it from DECIMAL_DIGITS (left
null) and builds the proto type with RelDataTypeSystem.DEFAULT (capped at
millis). The net effect is TIMESTAMP(3)/(6) collapsing to TIMESTAMP(0) in the
planner even when the source carries milli/microsecond precision.
Calcite exposes no usable hook here (getRelDataType is package-private and its
proto is memoized; the THREAD_METADATA/Foo hook is experimental "do not use" and
only lists tables). So prefer the upstream table's own row type — the same
source of truth already used for the Avro key/value schemas — which preserves
precision, falling back to the JDBC-metadata path for non-Calcite upstreams.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Report temporal precision in DECIMAL_DIGITS across the JDBC federation
Replaces the upstream-table bypass with a native Calcite metadata fix. The
precision was being dropped inside Calcite's own JDBC federation: its metadata
producer (CalciteMetaImpl.columns) reports a TIMESTAMP/TIME column's precision
in COLUMN_SIZE and leaves DECIMAL_DIGITS null, but its reader
(JdbcSchema.getRelDataType) reads temporal precision from DECIMAL_DIGITS. So the
two halves disagree and TIMESTAMP(3) surfaces as TIMESTAMP(0).
Fix it the way an external JDBC driver would — populate DECIMAL_DIGITS — via
Calcite's native metaColumnFactory connection property (honored by Driver.
createMeta). HoptimatorMetaColumnFactory mirrors COLUMN_SIZE into DECIMAL_DIGITS
for temporal types, and CalciteDriver sets the property so every adapter
connection reports it. No federation bypass, no metadata round-trip change.
This restores millisecond precision across the federation; precision beyond
millis is still clamped by JdbcSchema.getRelDataType's hardcoded
RelDataTypeSystem.DEFAULT, which no connection knob can override.
Reverts the HoptimatorJdbcTable.getRowType bypass from the previous commit.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Remove flawed timestamp-precision integration scenarios
The mysql-timestamp-precision and kafka ts-precision integration scenarios
asserted micro/nanosecond precision (TIMESTAMP(6)/(9)) surviving a source read,
but that is unattainable through Calcite's JDBC federation: JdbcSchema.
getRelDataType builds its proto type with RelDataTypeSystem.DEFAULT, which caps
datetime precision at milliseconds. So those assertions could never hold
regardless of the metadata fix.
The MySQL scenario additionally depended on MySQL Connector/J reporting
DECIMAL_DIGITS for a TIMESTAMP(3) column, which is a separate, driver-specific
variable from the Calcite-over-Calcite federation fix.
Removes both scenarios and the associated events table. The millisecond fix
remains covered by unit tests (HoptimatorMetaColumnFactoryTest, MySqlTableTest).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix redundant check
* Fix MySQL precision/scale handling + support in quidem
* fix up tests
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent e9ab47c commit 096de8a
76 files changed
Lines changed: 1106 additions & 385 deletions
File tree
- deploy/docker/mysql
- hoptimator-avro/src
- main/java/com/linkedin/hoptimator/avro
- test/java/com/linkedin/hoptimator/avro
- hoptimator-catalog/src
- main/java/com/linkedin/hoptimator/catalog
- builtin
- test/java/com/linkedin/hoptimator/catalog/builtin
- hoptimator-demodb
- src/test/java/com/linkedin/hoptimator/demodb
- hoptimator-jdbc/src
- main/java/com/linkedin/hoptimator/jdbc
- testFixtures/java/com/linkedin/hoptimator/jdbc
- test/java/com/linkedin/hoptimator/jdbc
- schema
- hoptimator-k8s/src/test/java/com/linkedin/hoptimator/k8s
- hoptimator-kafka/src/test
- java/com/linkedin/hoptimator/kafka
- resources
- hoptimator-logical
- src
- main/java/com/linkedin/hoptimator/logical
- test
- java/com/linkedin/hoptimator/logical
- resources
- hoptimator-mysql/src
- main/java/com/linkedin/hoptimator/mysql
- test
- java/com/linkedin/hoptimator/mysql
- resources
- hoptimator-operator/src/test/java/com/linkedin/hoptimator/operator/subscription
- hoptimator-planner
- src/test/java/com/linkedin/hoptimator/planner
- hoptimator-util/src
- main/java/com/linkedin/hoptimator/util
- planner
- test/java/com/linkedin/hoptimator/util
- planner
- hoptimator-venice/src/test
- java/com/linkedin/hoptimator/venice
- resources
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
9 | | - | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
30 | 34 | | |
31 | 35 | | |
32 | 36 | | |
| |||
75 | 79 | | |
76 | 80 | | |
77 | 81 | | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
78 | 86 | | |
79 | | - | |
| 87 | + | |
80 | 88 | | |
81 | 89 | | |
82 | 90 | | |
| |||
101 | 109 | | |
102 | 110 | | |
103 | 111 | | |
104 | | - | |
| 112 | + | |
105 | 113 | | |
106 | 114 | | |
107 | 115 | | |
| |||
118 | 126 | | |
119 | 127 | | |
120 | 128 | | |
121 | | - | |
| 129 | + | |
122 | 130 | | |
123 | 131 | | |
124 | 132 | | |
| |||
289 | 297 | | |
290 | 298 | | |
291 | 299 | | |
292 | | - | |
293 | | - | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
294 | 305 | | |
295 | 306 | | |
296 | 307 | | |
| |||
335 | 346 | | |
336 | 347 | | |
337 | 348 | | |
338 | | - | |
| 349 | + | |
339 | 350 | | |
340 | 351 | | |
341 | 352 | | |
| |||
349 | 360 | | |
350 | 361 | | |
351 | 362 | | |
352 | | - | |
| 363 | + | |
353 | 364 | | |
354 | 365 | | |
355 | 366 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
53 | 53 | | |
54 | 54 | | |
55 | 55 | | |
56 | | - | |
| 56 | + | |
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
0 commit comments