Skip to content

[python] Read row-format TIMESTAMP values in the precision's time unit - #10125

Open
jackylee-ch wants to merge 1 commit into
apache:masterfrom
jackylee-ch:py-row-timestamp-unit
Open

jackylee-ch wants to merge 1 commit into
apache:masterfrom
jackylee-ch:py-row-timestamp-unit

Conversation

@jackylee-ch

Copy link
Copy Markdown
Contributor

Purpose

The row file-format reader returned a TIMESTAMP value in milliseconds for precision ≤ 3 and microseconds for precision > 3. But PyarrowFieldParser.from_paimon_type maps the precision to four Arrow units — 0 → s, 1-3 → ms, 4-6 → us, 7-9 → ns — and _build_table puts the integer into that type without conversion. So only precisions 1-6 agreed:

  • TIMESTAMP(0) (Arrow s): a millisecond integer read as seconds — ×1000, overflowing (a 2020 instant renders as year 52626).
  • TIMESTAMP(7-9) (Arrow ns): a microsecond integer read as nanoseconds — ÷1000 (a 2020 instant renders as 1970).

The reader now returns the value in the unit the precision maps to (seconds / millis / micros / nanos). The wire format (a millis long plus, for precision > 3, a nano_of_milli varint) is unchanged, so this is a read-side fix.

Tests

test_timestamp_precisions round-trips TIMESTAMP(0/3/6/9) and asserts exact values (fails on master: TIMESTAMP(0) overflows, TIMESTAMP(9) reads 1970). test_timestamp_nanos_decoded_from_wire pins the nanosecond formula against a hand-built wire buffer (nano_of_milli=123456), the genuine Java-written case.

@Akash3121

Copy link
Copy Markdown
Contributor

Reviewed the row-format timestamp wire decoding against the Arrow precision mapping and Java timestamp conversion. The seconds, milliseconds, microseconds, and nanoseconds formulas are consistent, including pre-epoch floor semantics and genuine sub-microsecond  nano_of_milli  values. The focused precision and raw-wire tests cover the behavior well.
LGTM.

The row-format reader returned a TIMESTAMP value in milliseconds for precision
<= 3 and microseconds for precision > 3, but PyarrowFieldParser.from_paimon_type
maps the precision to four Arrow units (0 -> s, 1-3 -> ms, 4-6 -> us, 7-9 -> ns)
and the value is placed into that type without conversion. Only precisions 1-6
agreed: a precision-0 value was read as seconds from a millisecond integer
(x1000, overflowing to year 52626), and a precision 7-9 value was read as
nanoseconds from a microsecond integer (/1000).

Return the value in the Arrow unit the precision maps to: seconds for 0, millis
for 1-3, micros for 4-6, nanos for 7-9. The wire format (a millis long plus,
only for precision > 3, a nano_of_milli varint) is unchanged and already written
that way, so this is a read-side fix.
@JingsongLi

JingsongLi commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

Conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants