Skip to content

feat(workflow-core): store a timestamp before 1883 at the wall clock it holds - #9076

Merged
aglinxinyuan merged 2 commits into
apache:mainfrom
kz930:fix/9074-iceberg-old-timestamp
Nov 1, 2026
Merged

aglinxinyuan merged 2 commits into
apache:mainfrom
kz930:fix/9074-iceberg-old-timestamp

Conversation

@kz930

@kz930 kz930 commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

IcebergUtil.toGenericRecord stored a TIMESTAMP field by turning the java.sql.Timestamp into an instant and back into a wall clock in the machine's zone. The two steps follow different zone rules. A Timestamp gives a date before 1900 the zone's standard offset, and java.time reads the instant back with the zone's full history, which is local mean time before 1883. In America/Los_Angeles a stored 1600-06-15 08:30:00 came back as 08:37:02.

The field is now stored as ts.toLocalDateTime, the wall clock the Timestamp holds. fromRecord already reads it back with Timestamp.valueOf, which is its inverse, so a value comes out of result storage as it went in. Timestamps after 1883 are unchanged, since both rules agree there.

Any related issues, documentation, discussions?

Closes #9074.

How was this PR tested?

A test in IcebergUtilSpec sets the default zone to America/Los_Angeles, stores 1600-06-15 08:30:00 and 1677-09-21 00:00:00, and checks that the record holds each wall clock and reads back to the same tuple. The zone is set in the test because UTC has no local mean time, so the old conversion passes there. On the old code the test fails with 1600-06-15T08:37:02 did not equal 1600-06-15T08:30. All 24 tests in the spec pass.

Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Claude Opus 5.5)

🤖 Generated with Claude Code

…t holds

IcebergUtil wrote a Timestamp through an instant. A Timestamp gives a date
before 1900 the zone's standard offset, and java.time reads the instant
back with the zone's local mean time before 1883, so the stored value
moved by the difference. It is now stored as its own wall clock.

Fixes apache#9074

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@github-actions

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • Contributors with relevant context: @aglinxinyuan, @eugenegujing
    You can notify them by mentioning @aglinxinyuan, @eugenegujing in a comment.

@kz930

kz930 commented Oct 22, 2026

Copy link
Copy Markdown
Contributor Author

@carloea2 could you review this one when you have time? It stores a timestamp before 1883 at the wall clock it holds (#9074).

@carloea2 carloea2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified on fresh upstream main with JDK 17. The regression fails with the old conversion, shifting 08:30 to 08:37:02, and passes with this change. All 24 IcebergUtilSpec tests and scalafmtCheckAll pass. Code looks good. Current CI is blocked before tests by the Ampel action allowlist.

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 2 better · 🔴 6 worse · ⚪ 7 noise (<±5%) · 0 without baseline

Compared against main 8fbd4f2 benchmarked on this same runner, so the delta is largely free of cross-runner hardware noise. The "7d avg" column still reflects the gh-pages dashboard. Treat <±5% as noise unless repeated.

Dashboard · Run

config throughput MB/s latency max Δ latest / 7d
🔴 bs=10 sw=10 sl=64 378 0.23 26,021/38,143/38,143 us 🔴 +25.2% / 🔴 +212.0%
🔴 bs=100 sw=10 sl=64 829 0.506 119,342/135,939/135,939 us 🟢 -8.4% / 🔴 +56.0%
⚪ bs=1000 sw=10 sl=64 951 0.58 1,046,196/1,128,602/1,128,602 us ⚪ within ±5% / 🔴 +38.0%
Baseline details

Latest main 8fbd4f2 from same runner

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 378 tuples/sec 423 tuples/sec 1,019 tuples/sec -10.6% -62.9%
bs=10 sw=10 sl=64 MB/s 0.23 MB/s 0.258 MB/s 0.622 MB/s -10.9% -63.0%
bs=10 sw=10 sl=64 p50 26,021 us 20,784 us 10,144 us +25.2% +156.5%
bs=10 sw=10 sl=64 p95 38,143 us 35,643 us 12,225 us +7.0% +212.0%
bs=10 sw=10 sl=64 p99 38,143 us 35,643 us 15,527 us +7.0% +145.7%
bs=100 sw=10 sl=64 throughput 829 tuples/sec 863 tuples/sec 1,371 tuples/sec -3.9% -39.5%
bs=100 sw=10 sl=64 MB/s 0.506 MB/s 0.526 MB/s 0.837 MB/s -3.8% -39.5%
bs=100 sw=10 sl=64 p50 119,342 us 111,520 us 79,910 us +7.0% +49.3%
bs=100 sw=10 sl=64 p95 135,939 us 148,438 us 87,155 us -8.4% +56.0%
bs=100 sw=10 sl=64 p99 135,939 us 148,438 us 106,643 us -8.4% +27.5%
bs=1000 sw=10 sl=64 throughput 951 tuples/sec 946 tuples/sec 1,415 tuples/sec +0.5% -32.8%
bs=1000 sw=10 sl=64 MB/s 0.58 MB/s 0.577 MB/s 0.864 MB/s +0.5% -32.9%
bs=1000 sw=10 sl=64 p50 1,046,196 us 1,048,957 us 780,407 us -0.3% +34.1%
bs=1000 sw=10 sl=64 p95 1,128,602 us 1,176,012 us 817,814 us -4.0% +38.0%
bs=1000 sw=10 sl=64 p99 1,128,602 us 1,176,012 us 848,683 us -4.0% +33.0%
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,529.77,200,128000,378,0.230,26021.02,38142.55,38142.55
1,100,10,64,20,2412.39,2000,1280000,829,0.506,119341.82,135939.44,135939.44
2,1000,10,64,20,21035.67,20000,12800000,951,0.580,1046196.43,1128601.83,1128601.83

@codecov-commenter

codecov-commenter commented Oct 26, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.81%. Comparing base (8fbd4f2) to head (07f82ac).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##               main    #9076   +/-   ##
=========================================
  Coverage     91.81%   91.81%           
- Complexity     5069     5070    +1     
=========================================
  Files          1271     1271           
  Lines         55208    55208           
  Branches       6987     6987           
=========================================
+ Hits          50688    50690    +2     
+ Misses         2800     2799    -1     
+ Partials       1720     1719    -1     
Flag Coverage Δ *Carryforward flag
access-control-service 77.44% <ø> (ø)
agent-service 99.16% <ø> (ø) Carriedforward from 8fbd4f2
amber 85.97% <ø> (+0.01%) ⬆️
computing-unit-managing-service 61.84% <ø> (ø)
config-service 87.50% <ø> (ø)
file-service 81.92% <ø> (ø)
frontend 96.50% <ø> (ø) Carriedforward from 8fbd4f2
notebook-migration-service 83.77% <ø> (ø)
pyamber 98.54% <ø> (ø) Carriedforward from 8fbd4f2
workflow-compiling-service 72.61% <ø> (ø)

*This pull request uses carry forward flags. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@aglinxinyuan aglinxinyuan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@aglinxinyuan
aglinxinyuan added this pull request to the merge queue Nov 1, 2026
Merged via the queue into apache:main with commit 7b8422e Nov 1, 2026
33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Result storage moves a timestamp before 1883 by the zone's local mean time

4 participants