Skip to content

[fix](be) Truncate native ORC timestamps to microseconds - #68024

Open
OIiveirra wants to merge 4 commits into
apache:masterfrom
OIiveirra:fix/jira-doris-29021
Open

OIiveirra wants to merge 4 commits into
apache:masterfrom
OIiveirra:fix/jira-doris-29021

Conversation

@OIiveirra

@OIiveirra OIiveirra commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: None

Related PR: #67904

Problem Summary:

Paimon ORC tables can store timestamp values with nanosecond precision, while Doris exposes timestamps at microsecond precision. The Paimon JNI reader truncates sub-microsecond digits, but the native ORC reader rounded them. For example, 2024-01-02 10:04:05.123456789 was exposed as .123456 by JNI and .123457 by the native reader, causing equality predicates to return inconsistent results.

The existing Paimon predicate conversion keeps TIMESTAMP(7/8/9) comparisons as residual predicates. This change makes the native ORC path use the same truncation semantics as Doris and the JNI reader for row decoding, stripe statistics, and ORC search argument bounds.

Release note

Fix inconsistent timestamp values and predicate results between native ORC and JNI readers for sub-microsecond timestamps.

Check List (For Author)

  • Test
    • Regression test
      • ./run-regression-test.sh --conf /tmp/yuze-regression-full-conf.groovy --run -d external_table_p0/paimon -s paimon_timestamp_types
    • Unit Test
      • ./run-be-ut.sh --run --filter=NewOrcReaderTest.*Timestamp*:NewOrcReaderTest.ReadTimestampNanosecondsTruncatesToMicroseconds
    • Manual test
    • No need to test or manual test
  • Behavior changed:
    • Yes. Native ORC timestamps now truncate sub-microsecond digits consistently with Doris precision and the JNI reader.
    • No.
  • Does this need documentation?
    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

Gabriel39
Gabriel39 previously approved these changes Sep 15, 2026
@OIiveirra
OIiveirra requested a review from Gabriel39 September 15, 2026 15:10
@OIiveirra OIiveirra changed the title [fix](fe) Preserve Paimon high-precision timestamp filters [test](regression) Cover Paimon high-precision timestamp predicates Sep 15, 2026
Gabriel39
Gabriel39 previously approved these changes Sep 16, 2026
@Gabriel39

Copy link
Copy Markdown
Contributor

run buildall

@OIiveirra

Copy link
Copy Markdown
Contributor Author

run external

### What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: Add the generated expected results for the Paimon timestamp predicate regression coverage.

### Release note

None

### Check List (For Author)

- Test: Regression test
    - ./run-regression-test.sh --conf /tmp/yuze-regression-full-conf.groovy --run -d external_table_p0/paimon -s paimon_timestamp_types
- Behavior changed: No
- Does this need documentation: No
@Gabriel39

Copy link
Copy Markdown
Contributor

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor

/review

@github-actions github-actions Bot 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.

Static review completed at exact head bf9a4feea46fbc700446d8238d310fc8ae720aa4. Two review rounds converged with no additional valuable findings after the accepted set.

Blocking findings:

  • The generated ORC oracle accepts duplicate rows from a documented one-row fixture.
  • The oracle also accepts different timestamp values and row sets for identical SQL under JNI versus native ORC scanning.

Critical checkpoint conclusions:

  • Goal and proof: the PR is intended to prove correct high-precision Paimon predicate behavior, but the checked-in ORC results preserve row multiplication and scanner-dependent semantics, so the goal is not yet proven.
  • Scope and clarity: the code change is small and focused; query reuse, hardcoded table names, ordering, and session cleanup are otherwise clear.
  • Concurrency and lifecycle: no production concurrency, locks, static initialization, or new lifecycle is introduced. Existing scanner/time-zone settings are restored in finally.
  • Configuration: no configuration item is added; only existing session variables are toggled.
  • Compatibility: no function symbol, storage format, protocol, or rolling-upgrade behavior changes in this test-only PR.
  • Parallel paths and conditions: precision greater than six is left as a residual predicate; FE pruning, JNI/native routing, and BE residual evaluation were traced. Both readers and formats are invoked, but their ORC results are not semantically equivalent.
  • Test coverage and results: the new queries are deterministic and use generated result blocks, but the new ORC expected results are not correct oracles. A one-row filter must not return two rows, and changing only the scanner must not change SQL semantics.
  • Observability, persistence, transactions, writes, FE-BE variables, memory ownership, and performance: not applicable; no production path is modified.
  • User focus: no additional focus points were provided.

Review status: complete, static-only. Builds and tests were not run because the review runner contract prohibits them.


-- !ts9_eq_orc --
1
1

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.

The fixture and both unfiltered scans contain exactly one id = 1, so accepting two rows here (and for <=/IN) makes this regression preserve an ORC row-multiplication bug. A predicate cannot create a second source row. Please fix the filtered ORC path and regenerate these blocks with exactly one row; do not mask it with DISTINCT, which would prevent the test from detecting the duplication.

-- !c2 --
1 2024-01-02T10:04:05.100 2024-01-02T10:04:05.120 2024-01-02T10:04:05.123 2024-01-02T10:04:05.123400 2024-01-02T10:04:05.123450 2024-01-02T10:04:05.123456 2024-01-02T10:04:05.123456 2024-01-02T10:04:05.123456 2024-01-02T10:04:05.123456 2024-01-02T10:04:05.100 2024-01-02T10:04:05.120 2024-01-02T10:04:05.123 2024-01-02T10:04:05.123400 2024-01-02T10:04:05.123450 2024-01-02T10:04:05.123456 2024-01-02T10:04:05.123456 2024-01-02T10:04:05.123456 2024-01-02T10:04:05.123456

-- !ts9_eq_orc --

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.

The same ORC row is exposed as .123456 under JNI but .123457 under the native reader, so this empty native equality block contradicts the truncation contract used by PaimonPredicateConverter and makes identical SQL return different rows when force_jni_scanner changes. Please establish one precision-reduction contract, align both scanner paths to it, and regenerate the snapshots so they produce the same row set.

### What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: Replace duplicated expected rows with framework-generated results for the Paimon timestamp predicate regression coverage.

### Release note

None

### Check List (For Author)

- Test: Regression test
    - ./run-regression-test.sh --conf /mnt/disk4/zhangyuze/doris-regression-env/regression-conf.groovy --run -d external_table_p0/paimon -s paimon_timestamp_types
- Behavior changed: No
- Does this need documentation: No
### What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: Native ORC timestamp decoding rounded nanoseconds to microseconds while the Paimon JNI path truncated them. This made visible values and timestamp predicate results differ between scanner implementations. Truncate native ORC row values, stripe statistics, and search argument bounds consistently, with unit and Paimon regression coverage.

### Release note

Fix inconsistent timestamp predicate results between native ORC and JNI readers for sub-microsecond values.

### Check List (For Author)

- Test: Regression test / Unit Test
    - ./run-be-ut.sh --run --filter=NewOrcReaderTest.*Timestamp*:NewOrcReaderTest.ReadTimestampNanosecondsTruncatesToMicroseconds
    - ./run-regression-test.sh --conf /tmp/yuze-regression-full-conf.groovy --run -d external_table_p0/paimon -s paimon_timestamp_types
- Behavior changed: Yes, native ORC timestamps now truncate sub-microsecond digits consistently with Doris precision and the JNI reader.
- Does this need documentation: No
@OIiveirra
OIiveirra requested a review from yiguolei as a code owner September 17, 2026 08:29
@OIiveirra OIiveirra changed the title [test](regression) Cover Paimon high-precision timestamp predicates [fix](be) Truncate native ORC timestamps to microseconds Sep 17, 2026
@OIiveirra

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 27644 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit e7dca64b45bc167479ca7f6454b52ed74e195b67, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17737	3955	3904	3904
q2	2277	350	282	282
q3	10000	1416	818	818
q4	4689	481	345	345
q5	7479	826	554	554
q6	173	168	138	138
q7	735	797	588	588
q8	9322	1635	1552	1552
q9	5473	4182	4205	4182
q10	6749	1600	1364	1364
q11	432	270	243	243
q12	631	408	295	295
q13	18065	2628	2011	2011
q14	261	258	238	238
q15	q16	725	723	655	655
q17	1750	1080	952	952
q18	6624	5639	5589	5589
q19	1351	1272	936	936
q20	493	392	267	267
q21	5853	2496	2433	2433
q22	428	352	298	298
Total cold run time: 101247 ms
Total hot run time: 27644 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4239	4219	4180	4180
q2	763	583	585	583
q3	4564	4987	4394	4394
q4	2266	2312	1481	1481
q5	4245	4127	4125	4125
q6	226	171	128	128
q7	1705	1614	1407	1407
q8	2468	2291	2156	2156
q9	7604	7693	7774	7693
q10	4339	4359	4053	4053
q11	588	403	382	382
q12	773	752	516	516
q13	2521	2804	2188	2188
q14	299	314	275	275
q15	q16	700	711	667	667
q17	7723	7293	7241	7241
q18	11957	11071	11834	11071
q19	1173	1071	1066	1066
q20	2223	2217	1971	1971
q21	5890	4806	4970	4806
q22	542	474	407	407
Total cold run time: 66808 ms
Total hot run time: 60790 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 153078 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit e7dca64b45bc167479ca7f6454b52ed74e195b67, data reload: false

query5	4316	592	446	446
query6	447	179	163	163
query7	4890	544	288	288
query8	324	186	182	182
query9	8787	3936	3917	3917
query10	472	305	280	280
query11	5869	2188	1984	1984
query12	161	102	101	101
query13	1251	550	410	410
query14	6512	4556	4222	4222
query14_1	4041	3985	4015	3985
query15	195	191	173	173
query16	999	474	429	429
query17	881	685	508	508
query18	2419	451	311	311
query19	191	179	134	134
query20	103	101	102	101
query21	219	129	114	114
query22	13140	13048	12816	12816
query23	15452	14469	14039	14039
query23_1	14137	14046	14120	14046
query24	7516	1680	1207	1207
query24_1	1220	1246	1200	1200
query25	513	405	335	335
query26	1266	301	158	158
query27	2699	541	336	336
query28	4613	1947	1970	1947
query29	1037	584	459	459
query30	308	232	202	202
query31	895	767	647	647
query32	156	98	96	96
query33	526	329	258	258
query34	1243	1166	649	649
query35	725	752	646	646
query36	794	793	705	705
query37	149	103	90	90
query38	1830	1786	1711	1711
query39	709	675	666	666
query39_1	649	639	654	639
query40	218	123	110	110
query41	73	69	69	69
query42	96	93	89	89
query43	335	351	297	297
query44	1349	685	689	685
query45	188	179	180	179
query46	1009	1137	700	700
query47	1504	1514	1377	1377
query48	395	428	306	306
query49	597	406	296	296
query50	945	348	266	266
query51	10753	10811	10606	10606
query52	89	89	75	75
query53	243	250	182	182
query54	257	215	197	197
query55	82	81	68	68
query56	252	248	233	233
query57	1425	1386	1272	1272
query58	250	205	217	205
query59	1972	2082	1820	1820
query60	323	227	214	214
query61	141	139	137	137
query62	392	313	270	270
query63	217	166	163	163
query64	2827	989	795	795
query65	4080	3969	3938	3938
query66	1818	425	308	308
query67	20399	19997	19628	19628
query68	3345	1539	954	954
query69	402	301	254	254
query70	920	879	862	862
query71	298	229	225	225
query72	2963	2694	2183	2183
query73	855	836	430	430
query74	4598	4452	4263	4263
query75	2300	2278	1927	1927
query76	2387	1084	685	685
query77	350	381	291	291
query78	9032	9065	8439	8439
query79	1203	1149	747	747
query80	511	470	360	360
query81	459	275	244	244
query82	342	163	121	121
query83	340	268	236	236
query84	313	141	107	107
query85	818	445	372	372
query86	325	235	231	231
query87	1982	1975	1836	1836
query88	3593	2661	2674	2661
query89	345	284	241	241
query90	1819	176	179	176
query91	161	149	131	131
query92	100	89	89	89
query93	1422	1366	832	832
query94	524	298	306	298
query95	663	461	328	328
query96	1056	753	325	325
query97	2457	2441	2316	2316
query98	203	184	183	183
query99	736	721	604	604
Total cold run time: 240932 ms
Total hot run time: 153078 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 24.07 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit e7dca64b45bc167479ca7f6454b52ed74e195b67, data reload: false

query1	0.01	0.01	0.01
query2	0.10	0.05	0.04
query3	0.26	0.14	0.13
query4	1.61	0.15	0.14
query5	0.25	0.22	0.23
query6	1.16	0.95	0.93
query7	0.04	0.01	0.00
query8	0.05	0.04	0.03
query9	0.40	0.34	0.36
query10	0.57	0.58	0.55
query11	0.21	0.15	0.14
query12	0.19	0.15	0.15
query13	0.47	0.46	0.46
query14	0.94	0.95	0.93
query15	0.62	0.58	0.59
query16	0.31	0.34	0.35
query17	1.13	1.04	1.10
query18	0.20	0.19	0.20
query19	2.05	1.93	1.89
query20	0.02	0.01	0.02
query21	15.45	0.22	0.14
query22	4.78	0.05	0.05
query23	16.13	0.33	0.13
query24	3.02	0.44	0.32
query25	0.11	0.05	0.05
query26	0.72	0.20	0.16
query27	0.03	0.04	0.04
query28	3.54	0.77	0.35
query29	12.47	3.99	3.21
query30	0.28	0.15	0.16
query31	2.78	0.57	0.30
query32	3.22	0.60	0.50
query33	3.23	3.24	3.27
query34	15.60	3.92	3.30
query35	3.22	3.25	3.24
query36	0.56	0.43	0.42
query37	0.08	0.06	0.06
query38	0.05	0.04	0.04
query39	0.04	0.03	0.03
query40	0.17	0.15	0.14
query41	0.08	0.03	0.02
query42	0.05	0.03	0.03
query43	0.04	0.04	0.03
Total cold run time: 96.24 s
Total hot run time: 24.07 s

@OIiveirra

Copy link
Copy Markdown
Contributor Author

run external

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 63.51% (29570/46562)
Line Coverage 48.24% (307966/638458)
Region Coverage 43.85% (248644/566977)
Branch Coverage 45.39% (115541/254546)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100% (0/0) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 76.27% (34390/45090)
Line Coverage 61.14% (385900/631186)
Region Coverage 57.53% (324852/564704)
Branch Coverage 58.30% (147932/253757)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100% (0/0) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 76.29% (34399/45090)
Line Coverage 61.17% (386115/631186)
Region Coverage 57.58% (325157/564704)
Branch Coverage 58.34% (148054/253757)

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