Skip to content

[feat](inverted-index) Add IK tokenizers to custom analyzers - #67918

Open
airborne12 wants to merge 17 commits into
apache:masterfrom
airborne12:feature/ik-custom-tokenizers
Open

airborne12 wants to merge 17 commits into
apache:masterfrom
airborne12:feature/ik-custom-tokenizers

Conversation

@airborne12

@airborne12 airborne12 commented Sep 13, 2026

Copy link
Copy Markdown
Member

What problem does this PR solve?

Custom inverted-index analyzers could not use IK smart or max-word tokenization with their configured character and token filters. This adds the ik_smart and ik_max_word tokenizer factories and policy validation.

Composed pipelines need source-byte provenance across normalization, splitting, concatenation, trimming, and reset/reuse. Opt-in offset tracking propagates through IK, keyword, standard, ICU normalization, word-delimiter, and pinyin processing. Separate rune end offsets preserve gaps removed by delimiter concatenation.

Review fixes preserve exact saved policy bindings across replay, lifecycle operations, MATCH serialization, provider dispatch, physical reader selection, and scoring-statistics collection. FE matches explicit built-in IK to its default max-word configuration. BE selection keys distinguish mode, lowercase configuration, and effective outer character filters without changing provider names, Thrift, or stored index formats. Encoded configurations cannot collide with arbitrary policy names.

For backend-first upgrades, BE now binds an old FE's normalized analyzer name to the canonical saved policy and accepts a lowercase metadata key only when it resolves to the same policy. Exact metadata remains preferred. The compatibility alias cannot select a differently bound policy or a built-in analyzer with different tokenization.

Named character-filter identities account for transformations absorbed by the resolved tokenizer while preserving meaningful ordered transformations. The two new global-policy suites run in nonConcurrent instead of contributing to concurrent P0 policy-quota exhaustion.

Review fix commits: 4119d0bf2e3, 2558085d88f, 6618a7099cb. Current candidate: 6618a7099cb.

Release note

Add IK smart and max-word tokenizers to custom inverted-index analyzers. Correct composed-tokenizer source offsets, preserve custom-analyzer MATCH bindings during backend-first upgrades, select the matching physical IK configuration, and fix effective duplicate-index identities.

Check List (For Author)

  • Test:
    • Native FE/BE ASAN build passed in the isolated task worktree. BE was rebuilt after the final production change, including the GLIBC 2.17 compatibility gate.
    • Official BE ASAN runner passed 354 tests in 10 related suites on the final source. Earlier focused offset and analyzer runs remain applicable to unchanged code.
    • Official FE runner passed 118 tests in four classes, including real index selection and MATCH-to-Thrift translation; the final repair changes BE only.
    • Discriminating native RED/GREEN tests cover legacy exact reader metadata, normalized index metadata, policy-name collisions, a reserved built-in-name collision, canonical-key precedence, legacy normalizers, scoring selection, and encoded-policy-name collisions.
    • test_ik_custom_analyzer, test_analyzer_identity_semantics, and existing test_ik_analyzer passed together against the final task-owned native ASAN cluster. No expected output changed.
    • Full committed PR English audit passed for 55 source files. Thirty precisely reviewed Chinese input and expected-token literals remain as test data; no descriptive text was exempted.
    • Clang-tidy checked the 13 newly modified C++ files with the matching ASAN compilation database. Four lowercase integer suffix findings were fixed; an exact current-source rerun of that rule passed. The qualified run retains only known diagnostics in unchanged CLucene and Boost headers, with an analysis-only VFS overlay for an unchanged unmatched comment in be/src/core/types.h; repository checks and source are unchanged.
    • Full merged-snapshot clang-format 16 and all FE reactor Checkstyle modules are verified by the shared publication gate before push.
    • Local results are not a claim that fresh full CI or AI review passed. Those runs are requested and evaluated against the published candidate.
  • Behavior changed: Yes. Custom analyzers support IK tokenization; saved policy bindings, physical index selection, source offsets, and effective duplicate-index identities remain consistent across query and DDL paths.
  • Does this need documentation: No new syntax is introduced. Existing analyzer configuration syntax is reused; no documentation changes are included.

Component-level replay, serialization, dispatch, reader selection, scoring selection, and current-version end-to-end regression were validated. A full mixed-version cluster upgrade was not run. Existing IK internal lowercasing behavior is unchanged; the uppercase SQL probe is not treated as proof of a lowercase-disabled runtime fix.

@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?

@airborne12

Copy link
Copy Markdown
Member Author

run buildall

@airborne12

Copy link
Copy Markdown
Member Author

/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 of exact head 1ecadcaebb31e4bdfc8139194e9434eb044cdea1. Requesting changes for 1 P0, 6 P1, and 1 P2 findings.

Critical checkpoint conclusions

  • Goal and proof: The goal is to expose ik_smart and ik_max_word as custom-analyzer tokenizers. The lowercase scalar happy path is wired, but the P0 reset regression and the policy, offset, and phrase failures mean the implementation does not yet satisfy the supported public paths. The added tests prove selected terms only.
  • Scope/focus: The production change is small and focused, but its integration surface is broader than the tests cover. No user-specific focus was provided, so the complete PR was reviewed.
  • Concurrency: Factory and dictionary publication use call_once; all production IK initializers use the same dictionary path, per-tokenizer mode remains local, and loaded tries are read-only. No new race, lock-order, deadlock, or heavy-under-lock issue was found.
  • Lifecycle/static initialization: Dictionary initialization is safe, but tokenizer reset lifecycle is not: CLucene's mandatory reset-before-consume crashes legacy IK indexing and destructively empties custom ARRAY token streams. Reader ownership and retained token storage are otherwise sound on the traced paths.
  • Configuration: No new Doris runtime configuration item is added. Existing dictionary configuration remains restart-only and is used consistently.
  • Compatibility: No wire/storage-format symbol is added, and the documented BE-then-FE rolling sequence covers factory availability. However, previously legal persisted policies named ik_smart/ik_max_word now collide, with FE and BE choosing different meanings.
  • Parallel paths: Scalar custom reuse works, but legacy and ARRAY CLucene paths fail reset; both legacy CLucene and SNII phrase readers mishandle same-position pinyin alternatives, while the query-v2 CLucene path groups them.
  • Conditional logic: No additional unsupported special condition was found. The missing FE validator cases and inconsistent normalization are called out inline.
  • Test coverage: Missing cases include legacy IndexWriter, custom ARRAY, named TOKENIZER policies, mixed-case/noncanonical references, replay collisions, exact offsets, multibyte refill boundaries, and MATCH_PHRASE across storage implementations.
  • Test results: BE/FE tests and a regression suite were added, but their assertions do not cover the failing paths; the regression also violates required golden-output/table-name conventions. Per the review contract, I did not run builds or tests, so all conclusions are static and author/CI claims are not independent execution evidence.
  • Observability: No new metrics or logging are required for this registry exposure; existing exception boundaries are adequate once the correctness defects are fixed. The ARRAY failure is silent data omission and must be corrected rather than observed around.
  • Persistence/transactions: No transaction state machine changes. Existing policy journaling/replay is structurally used, but replayed-name collision semantics are incompatible as noted inline.
  • Data writes: Index construction is materially affected: existing legacy IK writes can crash and custom IK ARRAY values can contribute no terms. No separate rowset/version/MoW issue was introduced.
  • FE-BE variables: No new Thrift field is needed, but existing string-valued policy transport preserves a spelling that FE accepts and BE's exact factory lookup rejects.
  • Performance: No new asymptotic hot-path or material memory-accounting issue was substantiated; repeated dictionary initialization is only a completed call_once check.
  • Other issues: After two full rounds, including separate lifecycle/phrase and dictionary/policy risk passes, all reviewers returned NO_NEW_VALUABLE_FINDINGS. One char-filter candidate was disproven by concrete overrides and is intentionally not submitted.

Please address the eight inline findings before merge.

Comment thread be/src/storage/index/inverted/analyzer/ik/IKTokenizer.cpp Outdated
Comment thread be/src/storage/index/inverted/analyzer/ik/IKTokenizer.cpp
Comment thread be/src/storage/index/inverted/analyzer/ik/IKTokenizer.cpp Outdated
Comment thread regression-test/suites/inverted_index_p0/analyzer/test_ik_custom_analyzer.groovy Outdated
Comment thread regression-test/suites/inverted_index_p0/analyzer/test_ik_custom_analyzer.groovy Outdated
@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17563	3080	3069	3069
q2	2065	249	208	208
q3	10284	883	506	506
q4	4666	248	197	197
q5	7693	568	388	388
q6	135	110	90	90
q7	525	498	389	389
q8	9227	848	923	848
q9	3441	2363	2361	2361
q10	6494	858	712	712
q11	404	197	179	179
q12	622	263	195	195
q13	18120	1540	1168	1168
q14	159	151	138	138
q15	q16	430	390	372	372
q17	1381	862	815	815
q18	3084	2245	2205	2205
q19	1266	866	743	743
q20	369	286	194	194
q21	5650	1641	1825	1641
q22	328	271	236	236
Total cold run time: 93906 ms
Total hot run time: 16654 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3436	3403	3368	3368
q2	506	390	390	390
q3	2206	2267	2175	2175
q4	1187	1160	881	881
q5	2178	2097	2101	2097
q6	167	117	88	88
q7	1024	891	838	838
q8	1591	1413	1413	1413
q9	3108	3093	3076	3076
q10	1857	1801	1617	1617
q11	357	269	252	252
q12	450	427	341	341
q13	1492	1508	1123	1123
q14	177	166	162	162
q15	q16	394	399	352	352
q17	3548	3289	3168	3168
q18	4765	4363	4748	4363
q19	855	783	898	783
q20	1070	966	832	832
q21	3842	3117	3288	3117
q22	414	358	329	329
Total cold run time: 34624 ms
Total hot run time: 30765 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 81543 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 1ecadcaebb31e4bdfc8139194e9434eb044cdea1, data reload: false

query5	4226	416	341	341
query6	380	133	128	128
query7	4960	428	236	236
query8	284	117	114	114
query9	8688	2832	2858	2832
query10	416	228	185	185
query11	5376	1036	916	916
query12	121	70	70	70
query13	1190	452	322	322
query14	6087	2203	2069	2069
query14_1	1981	1954	1952	1952
query15	175	119	114	114
query16	921	366	332	332
query17	803	479	371	371
query18	2321	350	244	244
query19	163	140	115	115
query20	73	72	72	72
query21	207	103	89	89
query22	5339	5305	5359	5305
query23	6774	6243	5948	5948
query23_1	6049	6070	6005	6005
query24	7343	1103	743	743
query24_1	769	769	798	769
query25	425	303	257	257
query26	1243	242	133	133
query27	2769	399	257	257
query28	4707	1475	1491	1475
query29	926	429	359	359
query30	264	156	132	132
query31	830	425	331	331
query32	131	78	80	78
query33	462	227	182	182
query34	1002	840	496	496
query35	406	402	348	348
query36	565	571	525	525
query37	127	86	72	72
query38	1013	850	792	792
query39	496	490	474	474
query39_1	490	452	473	452
query40	201	100	80	80
query41	58	57	58	57
query42	75	75	72	72
query43	244	242	210	210
query44	1007	539	541	539
query45	118	111	100	100
query46	764	860	508	508
query47	768	786	722	722
query48	325	319	238	238
query49	585	253	199	199
query50	775	256	192	192
query51	7998	7966	7989	7966
query52	67	68	60	60
query53	191	196	151	151
query54	218	182	148	148
query55	79	60	54	54
query56	189	160	167	160
query57	687	720	664	664
query58	193	192	170	170
query59	1209	1209	1099	1099
query60	238	195	178	178
query61	118	117	132	117
query62	361	220	184	184
query63	174	138	139	138
query64	2698	678	628	628
query65	1635	1583	1576	1576
query66	1870	278	225	225
query67	9742	9379	9684	9379
query68	2930	1189	768	768
query69	343	231	194	194
query70	672	623	617	617
query71	262	168	158	158
query72	2280	1750	1499	1499
query73	652	636	351	351
query74	1987	1233	1138	1138
query75	1189	1125	982	982
query76	2345	700	513	513
query77	258	274	202	202
query78	3867	3686	3239	3239
query79	2299	841	614	614
query80	1635	330	283	283
query81	485	157	132	132
query82	631	126	103	103
query83	274	212	191	191
query84	301	109	87	87
query85	783	342	281	281
query86	386	181	173	173
query87	1011	970	893	893
query88	2800	2112	2116	2112
query89	280	198	177	177
query90	1982	136	138	136
query91	128	119	97	97
query92	74	74	72	72
query93	1384	1142	717	717
query94	645	239	235	235
query95	539	245	291	245
query96	839	616	285	285
query97	1054	1039	992	992
query98	142	138	138	138
query99	419	354	319	319
Total cold run time: 177364 ms
Total hot run time: 81543 ms

@hello-stephen

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

query1	0.00	0.00	0.01
query2	0.08	0.04	0.03
query3	0.26	0.11	0.10
query4	1.59	0.09	0.10
query5	0.17	0.16	0.15
query6	1.29	0.70	0.67
query7	0.03	0.01	0.00
query8	0.04	0.03	0.03
query9	0.29	0.21	0.21
query10	0.33	0.35	0.34
query11	0.16	0.13	0.13
query12	0.14	0.13	0.12
query13	0.30	0.29	0.30
query14	0.43	0.45	0.44
query15	0.35	0.35	0.35
query16	0.23	0.23	0.22
query17	0.67	0.68	0.67
query18	0.16	0.15	0.15
query19	1.13	1.18	1.17
query20	0.02	0.01	0.01
query21	15.44	0.15	0.12
query22	5.08	0.04	0.04
query23	16.19	0.26	0.10
query24	3.06	0.33	0.26
query25	0.12	0.04	0.04
query26	0.77	0.17	0.12
query27	0.03	0.03	0.03
query28	3.65	0.58	0.29
query29	12.41	3.17	2.57
query30	0.28	0.11	0.14
query31	2.77	0.38	0.17
query32	3.49	0.31	0.24
query33	1.36	1.54	1.37
query34	15.34	2.20	1.76
query35	1.74	1.67	1.72
query36	0.46	0.29	0.29
query37	0.07	0.04	0.03
query38	0.05	0.03	0.03
query39	0.03	0.02	0.03
query40	0.12	0.08	0.07
query41	0.08	0.02	0.03
query42	0.03	0.03	0.02
query43	0.03	0.03	0.03
Total cold run time: 90.27 s
Total hot run time: 14.57 s

airborne12 added a commit to airborne12/apache-doris that referenced this pull request Sep 13, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#67918

Problem Summary:

The initial IK custom-analyzer integration did not fully preserve tokenizer reset semantics, document-relative UTF-8 offsets, case-insensitive built-in resolution, or upgrade compatibility when an existing named policy collides with a new built-in name. Its regression coverage also lacked generated golden output.

Preserve the pending-reader reset contract, advance refill offsets by consumed bytes, rebase pinyin candidates to source-token byte spans, canonicalize built-in names while keeping named policies authoritative, accept IK tokenizer policy types in FE validation, and add focused unit and regression coverage.

### Release note

None

### Check List (For Author)

- Test
    - [x] Regression test
    - [x] Unit Test
    - [x] Manual test
- Behavior changed:
    - [x] No. This corrects edge cases in the feature introduced by the preceding commit.
    - [ ] Yes.
- Does this need documentation?
    - [x] No.
    - [ ] Yes.

Validation:

- `./build.sh --be -j48` (ASAN)
- `./build.sh --fe`
- `./run-be-ut.sh --run --filter='IKTokenizerTest.*' -j48` (21 tests passed)
- `./run-be-ut.sh --run --filter='AnalysisFactoryMgrTest.*:IKTokenizerTest.*:PinyinFilterTest.*:IndexPolicyMgrTest.*' -j48` (80 passed; one pre-existing order-dependent dictionary-initialization test failed, then passed in the isolated IK run)
- `./run-fe-ut.sh --run --filter=org.apache.doris.analysis.invertedindex.AnalyzerIdentityBuilderTest` (6 tests passed)
- `./run-fe-ut.sh --run --filter=org.apache.doris.indexpolicy.PolicyValidatorTests` (20 tests passed)
- `./run-regression-test.sh --run -s test_ik_custom_analyzer -d inverted_index_p0/analyzer` (generated golden and clean comparison passed)
- clang-tidy on all changed C++ lines with the ASAN compilation database; one test translation unit is blocked by the pre-existing unmatched `NOLINTEND` in `be/src/core/types.h`
- C++ format, Checkstyle, build-hygiene, and glibc compatibility checks

The Chinese literals in the tests and regression golden are tokenizer input and expected token data, not code descriptions.
@airborne12

Copy link
Copy Markdown
Member Author

run buildall

@airborne12

Copy link
Copy Markdown
Member Author

/review

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17603	3081	3059	3059
q2	2066	253	218	218
q3	10258	871	528	528
q4	4669	255	212	212
q5	7654	561	385	385
q6	137	114	96	96
q7	539	512	390	390
q8	9255	897	912	897
q9	3446	2421	2398	2398
q10	6508	862	710	710
q11	418	198	186	186
q12	627	269	203	203
q13	18092	1521	1156	1156
q14	166	149	139	139
q15	q16	440	403	374	374
q17	1365	878	752	752
q18	3106	2285	2263	2263
q19	1286	944	734	734
q20	394	291	201	201
q21	5698	1720	1896	1720
q22	340	272	234	234
Total cold run time: 94067 ms
Total hot run time: 16855 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3459	3396	3355	3355
q2	509	394	375	375
q3	2211	2353	2203	2203
q4	1204	1167	898	898
q5	2193	2148	2091	2091
q6	170	120	89	89
q7	1046	910	855	855
q8	1586	1400	1399	1399
q9	3160	3132	3109	3109
q10	1852	1804	1622	1622
q11	354	270	248	248
q12	457	434	355	355
q13	1507	1545	1137	1137
q14	167	176	161	161
q15	q16	399	399	360	360
q17	3542	3346	3194	3194
q18	4823	4422	4735	4422
q19	841	915	866	866
q20	1003	967	832	832
q21	3854	3226	3164	3164
q22	400	344	317	317
Total cold run time: 34737 ms
Total hot run time: 31052 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 82284 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 33dd82008708152608064761581e49b9d1475744, data reload: false

query5	4274	419	358	358
query6	388	166	132	132
query7	4889	434	227	227
query8	302	127	128	127
query9	8718	2934	2950	2934
query10	399	235	213	213
query11	5401	1052	927	927
query12	137	75	71	71
query13	1192	453	327	327
query14	6192	2210	2106	2106
query14_1	1999	1976	1962	1962
query15	181	121	114	114
query16	973	374	378	374
query17	810	457	386	386
query18	2325	312	225	225
query19	155	135	107	107
query20	83	70	71	70
query21	198	99	86	86
query22	5466	5455	5330	5330
query23	6863	6351	5994	5994
query23_1	6127	6005	6068	6005
query24	7237	1074	772	772
query24_1	750	782	778	778
query25	408	279	233	233
query26	1223	224	128	128
query27	2810	423	259	259
query28	4666	1513	1500	1500
query29	929	422	340	340
query30	252	160	131	131
query31	822	402	325	325
query32	125	74	78	74
query33	451	229	172	172
query34	1000	822	474	474
query35	398	395	336	336
query36	572	567	531	531
query37	118	78	70	70
query38	1023	854	824	824
query39	493	498	473	473
query39_1	502	456	445	445
query40	206	88	77	77
query41	53	51	51	51
query42	72	70	72	70
query43	246	239	208	208
query44	1032	539	530	530
query45	108	104	103	103
query46	765	828	539	539
query47	762	769	729	729
query48	304	309	232	232
query49	549	243	189	189
query50	736	265	188	188
query51	8131	8221	8168	8168
query52	67	68	60	60
query53	199	192	148	148
query54	219	154	150	150
query55	71	61	56	56
query56	274	168	168	168
query57	683	678	625	625
query58	203	167	162	162
query59	1205	1247	1113	1113
query60	230	198	185	185
query61	144	108	125	108
query62	349	201	180	180
query63	172	140	141	140
query64	2665	719	660	660
query65	1700	1610	1643	1610
query66	1840	274	212	212
query67	9892	9795	9925	9795
query68	3007	1176	686	686
query69	350	228	199	199
query70	687	636	626	626
query71	259	183	169	169
query72	2340	1683	1480	1480
query73	667	576	328	328
query74	1995	1243	1126	1126
query75	1180	1106	959	959
query76	2376	718	510	510
query77	251	268	214	214
query78	4073	3701	3159	3159
query79	2446	809	546	546
query80	1612	325	266	266
query81	517	159	132	132
query82	646	126	94	94
query83	303	217	190	190
query84	293	108	86	86
query85	834	348	288	288
query86	393	174	169	169
query87	1023	975	893	893
query88	2775	2144	2143	2143
query89	299	197	176	176
query90	1966	135	131	131
query91	133	124	99	99
query92	80	70	71	70
query93	1554	1091	733	733
query94	647	249	231	231
query95	542	263	232	232
query96	759	573	273	273
query97	1043	1091	1068	1068
query98	140	143	133	133
query99	441	348	312	312
Total cold run time: 178783 ms
Total hot run time: 82284 ms

@hello-stephen

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

query1	0.00	0.01	0.00
query2	0.07	0.04	0.04
query3	0.25	0.11	0.10
query4	1.60	0.09	0.10
query5	0.17	0.16	0.16
query6	1.28	0.70	0.71
query7	0.03	0.01	0.00
query8	0.04	0.03	0.03
query9	0.28	0.22	0.21
query10	0.34	0.36	0.36
query11	0.16	0.12	0.12
query12	0.15	0.12	0.13
query13	0.31	0.31	0.32
query14	0.44	0.44	0.45
query15	0.36	0.35	0.36
query16	0.23	0.22	0.22
query17	0.69	0.75	0.70
query18	0.18	0.17	0.17
query19	1.15	1.17	1.13
query20	0.02	0.01	0.01
query21	15.46	0.16	0.11
query22	5.07	0.04	0.04
query23	16.18	0.26	0.10
query24	2.99	0.34	0.28
query25	0.11	0.03	0.03
query26	0.84	0.16	0.13
query27	0.03	0.03	0.03
query28	3.67	0.53	0.28
query29	12.49	3.19	2.59
query30	0.26	0.11	0.12
query31	2.77	0.37	0.18
query32	3.53	0.32	0.23
query33	1.54	1.50	1.51
query34	15.37	2.21	1.82
query35	1.78	1.75	1.73
query36	0.45	0.29	0.29
query37	0.06	0.04	0.04
query38	0.04	0.03	0.03
query39	0.03	0.02	0.02
query40	0.12	0.08	0.07
query41	0.08	0.02	0.03
query42	0.03	0.02	0.02
query43	0.04	0.03	0.03
Total cold run time: 90.69 s
Total hot run time: 14.94 s

@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.

Request changes — static review completed and converged at exact head 33dd82008708152608064761581e49b9d1475744 against base 2573820600eb178150a35710a94fd58b478df96d.

Five distinct P1 findings are attached inline: aggregate BE test-order dependence, locale-dependent IK name normalization, loss of source-byte boundaries after fullwidth normalization, non-canonical built-in filter identities, and unequal identities for direct versus type-only named IK tokenizers.

Critical checkpoint conclusions:

  • Goal and proof: the patch registers both IK modes and adds FE, BE, and regression coverage, but the goal is not safely complete while the combined BE test binary is order-dependent and the offset/identity cases above remain uncovered.
  • Scope: the production change is focused on analyzer registration, reset/offset propagation, policy validation, and identity. All 19 changed files and their upstream/downstream paths were reviewed; no additional user focus was provided.
  • Concurrency: factory registration and dictionary initialization use process-wide call_once; FE policy maps remain lock-protected. No runtime race, lock-order, or deadlock issue was found. The singleton lifecycle does create the accepted cross-test failure.
  • Lifecycle: fresh/reusable custom streams, legacy raw-reader streams, scalar/ARRAY indexing, reader ownership, and repeated reset were traced; the current reset fix preserves ownership and tokenizes once per reader. Global dictionary test state is not isolated.
  • Configuration: no new dynamic or persisted configuration key is introduced; both factories consume the existing dictionary path and keep smart/max-word mode per stream. No runtime configuration propagation gap was found.
  • Compatibility: existing named-policy precedence is aligned across FE replay/identity and BE resolution, and unsupported mixed-version direct use fails explicitly rather than silently reinterpreting metadata. Locale normalization and semantic identity consistency still need the inline fixes.
  • Parallel paths and conditions: tokenizer, token-filter, and char-filter resolution plus both CREATE TABLE and CREATE INDEX identity consumers were checked. The filter and named-wrapper branches are the missing parallel cases reported inline.
  • Tests and results: regression ordering/goldens are structurally deterministic, but negative Unicode/locale/identity coverage is missing. Per review-runner contract I ran no builds or tests. Author-reported validation includes a combined relevant BE run failure followed by an isolated IK pass; live CI currently has formatter, Checkstyle, license, secrets, Cloud UT, and performance passing while BE UT, FE UT, and compile remain pending.
  • Observability: existing exception and logging paths are adequate for this local analyzer feature; no new metric is warranted.
  • Persistence and transactions: policy image/replay, name-map rebuilding, propagation, and drop/reference paths were traced. No EditLog payload, transaction protocol, or storage-format change is introduced.
  • Data writes and crash behavior: index-writer scalar/ARRAY paths were checked; no new transactional atomicity or crash-leak issue was found beyond incorrect offsets and duplicate-index admission.
  • FE/BE variables: no new thrift field or scattered session variable is introduced; existing policy properties carry the component names.
  • Performance and memory: eager IK buffering is pre-existing; retaining two offsets per token adds bounded metadata and no new hot-loop or tracked-allocation regression was substantiated.
  • Other correctness: error propagation and position increments are consistent. All prior threads were treated as hard duplicate fences, every candidate was resolved, and the third round returned NO_NEW_VALUABLE_FINDINGS from all reviewers.

Comment thread be/test/runtime/index_policy/index_policy_mgr_test.cpp Outdated
Comment thread be/src/storage/index/inverted/token_filter/pinyin_filter.cpp
airborne12 added a commit to airborne12/apache-doris that referenced this pull request Sep 13, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#67918

Problem Summary:

The IK analyzer integration could initialize global dictionaries from a factory-resolution test, depend on the JVM default locale, produce distinct identities for equivalent built-in components, and lose original byte boundaries when IK regularization changes UTF-8 width.

Keep the factory-resolution test side-effect free, normalize names with Locale.ROOT, canonicalize all built-in component identities and type-only wrappers, and propagate source rune boundaries through token filters so pinyin offsets remain relative to the original document.

### Release note

None

### Check List (For Author)

- Test
    - [x] Regression test
    - [x] Unit Test
    - [x] Manual test
- Behavior changed:
    - [x] No. This corrects edge cases in the feature introduced by the preceding commits.
    - [ ] Yes.
- Does this need documentation?
    - [x] No.
    - [ ] Yes.

Validation:

- ./build.sh --be -j8 (ASAN)
- ./build.sh --fe -j8
- IKTokenizerTest and PinyinFilterTest (62 tests passed)
- AnalysisFactoryMgrTest, IKTokenizerTest, PinyinFilterTest, and IndexPolicyMgrTest (82 tests passed)
- AnalyzerIdentityBuilderTest and PolicyValidatorTests (29 tests passed)
- clang-format 16 and Checkstyle passed
- clang-tidy found no warnings on analyzable changed lines; one deletion-only test translation unit remains blocked by a pre-existing unmatched NOLINTEND in be/src/core/types.h

The fullwidth literal in the test is tokenizer input data, not a code description.
@airborne12

Copy link
Copy Markdown
Member Author

run buildall

@airborne12

Copy link
Copy Markdown
Member Author

/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 complete at head c5976f7cff0c8aae1f3dc174a377d1446b70c315 after two convergence rounds. Requesting changes for one distinct P1 issue described inline.

Critical checkpoint conclusions:

  • Goal and test approach: The PR wires ik_smart and ik_max_word through FE policy validation, BE factory construction, TOKENIZE/query, index writing, and regression coverage. The implementation goal is coherent, but semantic duplicate detection is incomplete across the legacy and custom IK entry points.
  • Scope and focus: Reviewed all 22 authoritative changed paths and their confirmed callers/consumers. The user supplied no additional focus, so the full PR remained in scope.
  • Concurrency: FE policy-map locking, factory registration, and the process-wide IK dictionary initialization were traced; no distinct new runtime race or lock-order defect was found.
  • Lifecycle and static initialization: Legacy/custom raw and shared readers, reusable scalar streams, ARRAY streams, reset/error recovery, dictionary lifetime, and filter span lifetime were checked. Residual test-order concerns are already covered by an existing thread and were not duplicated.
  • Configuration: No new dynamic-config contract is introduced. Both IK modes use the established dictionary path; configuration normalization issues substantially covered by existing threads were fenced.
  • Compatibility and rolling upgrade: No new persisted or wire schema is added. Policy replay/publication and existing-policy-first name collisions were checked; normal BE-first rollout is required for the new factories, with no separate compatibility defect found.
  • Parallel and special-case paths: Checked smart, implicit-smart, and max-word modes; direct and named/type-only references; CREATE TABLE and ALTER/CREATE INDEX; scalar and ARRAY writes; TOKENIZE, MATCH, and query analysis. The cross-family duplicate gap affects both DDL paths.
  • Conditionals, comments, and similar implementations: Compared legacy IKAnalyzer construction with IKTokenizerFactory, reviewed normalization precedence and related tokenizer/filter factories, and traced source-offset/refill/truncation branches. No additional distinct issue survived the duplicate fences.
  • Tests: Changed BE unit, FE unit, and regression tests cover registration, validation, reset/reuse, refills, offsets, pinyin composition, both IK modes, TOKENIZE, and MATCH. Cross-family duplicate tests are missing and are requested with the inline finding. This reviewer ran no builds or tests because the review contract prohibited execution. The author reports ASAN builds, 82 combined BE tests, 29 FE tests, and the regression case; at submission time BE UT, FE UT, compile, performance, and review checks were still pending in CI.
  • Outputs: The regression golden is ordered/deterministic for the asserted queries and follows cleanup-before-use conventions. No distinct output-contract issue was found.
  • Observability and errors: Existing exceptions/status propagation and relevant logging remain in place; no new silent production failure or observability gap was found outside the identity bug.
  • Persistence and transactions: Index-policy journal/replay/image reconstruction and FE-to-BE publication were traced. No transaction-state, metadata-format, or replay-order defect was found.
  • Writes, atomicity, and crash behavior: Scalar/ARRAY index-writer consumption and reset ordering were reviewed; no new atomicity, partial-write, or crash-recovery issue was found.
  • FE/BE variables and all consumers: No Thrift field is added. FE names and BE factories align for valid direct/named policies, but FE's analyzer identity does not unify the equivalent legacy IK representation, which is the blocking finding.
  • Performance: Source-byte mapping is allocated only for width-changing normalization and the identity work remains DDL-side; no material new performance issue was substantiated.
  • Other: Security review was not requested or implicated. Existing inline issues and replies were treated as hard duplicate fences and were not reposted.

Review status: complete static review; one new blocking finding; exact base/head verified before submission.

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 85.00% (17/20) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 63.28% (29643/46844)
Line Coverage 48.19% (309651/642588)
Region Coverage 43.71% (249283/570269)
Branch Coverage 45.33% (116106/256159)

airborne12 added a commit to airborne12/apache-doris that referenced this pull request Sep 13, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#67918

Problem Summary:

Legacy IK parser indexes and equivalent custom analyzers used different semantic identities, allowing duplicate inverted indexes on one column. Canonicalize unfiltered legacy smart and max-word modes to the corresponding custom analyzer identities while preserving distinct identities for filtered legacy analyzers.

### Release note

None

### Check List (For Author)

- Test
    - [x] Regression test
    - [x] Unit Test

- Behavior changed:
    - [x] Yes. Equivalent legacy and custom IK indexes are now rejected as duplicates.

- Does this need documentation?
    - [x] No.
@airborne12

Copy link
Copy Markdown
Member Author

run buildall

@airborne12

Copy link
Copy Markdown
Member Author

/review

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17561	2984	2958	2958
q2	2065	248	215	215
q3	10280	869	513	513
q4	4663	248	205	205
q5	7676	549	384	384
q6	139	115	93	93
q7	533	508	384	384
q8	9229	927	906	906
q9	3434	2402	2361	2361
q10	6517	857	702	702
q11	405	197	184	184
q12	616	257	197	197
q13	18127	1498	1141	1141
q14	177	150	137	137
q15	q16	436	390	369	369
q17	1326	875	814	814
q18	3043	2197	2234	2197
q19	1118	851	799	799
q20	379	281	205	205
q21	5229	1674	1853	1674
q22	325	265	237	237
Total cold run time: 93278 ms
Total hot run time: 16675 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3337	3278	3269	3269
q2	509	387	372	372
q3	2204	2258	2152	2152
q4	1177	1159	871	871
q5	2157	2073	2086	2073
q6	171	119	85	85
q7	1030	944	834	834
q8	1574	1367	1364	1364
q9	3067	3033	3018	3018
q10	1845	1789	1609	1609
q11	349	266	246	246
q12	446	421	343	343
q13	1467	1533	1141	1141
q14	172	162	154	154
q15	q16	389	392	360	360
q17	3531	3298	3247	3247
q18	4736	4397	4739	4397
q19	863	845	807	807
q20	992	1106	806	806
q21	3699	3047	3145	3047
q22	398	348	338	338
Total cold run time: 34113 ms
Total hot run time: 30533 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 81320 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 0e66fd9522552abd9efa2bb685db6970859b19d1, data reload: false

query5	4270	420	343	343
query6	388	140	126	126
query7	4935	427	229	229
query8	298	126	119	119
query9	8724	2876	2886	2876
query10	411	241	197	197
query11	5395	1052	910	910
query12	123	71	69	69
query13	1192	432	321	321
query14	6059	2216	2098	2098
query14_1	1986	1968	1966	1966
query15	173	121	117	117
query16	889	360	334	334
query17	764	419	331	331
query18	2312	313	227	227
query19	159	132	107	107
query20	74	70	67	67
query21	201	99	85	85
query22	5358	5466	5330	5330
query23	6578	6192	6003	6003
query23_1	6117	6124	5980	5980
query24	7268	1055	742	742
query24_1	758	775	773	773
query25	408	269	229	229
query26	1231	230	122	122
query27	2793	416	246	246
query28	4726	1477	1490	1477
query29	918	408	358	358
query30	250	152	126	126
query31	799	401	321	321
query32	121	68	70	68
query33	447	218	172	172
query34	986	827	480	480
query35	411	402	332	332
query36	565	577	511	511
query37	119	82	67	67
query38	987	851	792	792
query39	495	475	480	475
query39_1	458	449	456	449
query40	200	88	76	76
query41	55	54	52	52
query42	74	69	71	69
query43	237	236	207	207
query44	985	536	544	536
query45	111	107	105	105
query46	785	808	513	513
query47	788	784	709	709
query48	313	301	234	234
query49	541	243	205	205
query50	723	265	194	194
query51	8022	7957	7807	7807
query52	67	67	57	57
query53	192	199	149	149
query54	206	174	138	138
query55	68	58	53	53
query56	197	183	173	173
query57	675	667	658	658
query58	202	170	200	170
query59	1284	1242	1105	1105
query60	234	185	170	170
query61	114	124	127	124
query62	368	205	180	180
query63	167	137	140	137
query64	2753	755	695	695
query65	1619	1566	1650	1566
query66	1897	289	248	248
query67	9845	9525	9466	9466
query68	2740	1201	760	760
query69	337	228	213	213
query70	682	620	627	620
query71	248	176	174	174
query72	2325	1686	1445	1445
query73	643	619	349	349
query74	1553	1232	1140	1140
query75	1172	1100	960	960
query76	2278	699	503	503
query77	242	251	215	215
query78	4058	3645	3246	3246
query79	2849	810	555	555
query80	1605	328	272	272
query81	513	157	134	134
query82	616	140	97	97
query83	271	207	187	187
query84	288	113	89	89
query85	801	337	318	318
query86	472	174	168	168
query87	1003	963	890	890
query88	3026	2093	2098	2093
query89	274	195	173	173
query90	2136	118	133	118
query91	128	119	98	98
query92	88	70	71	70
query93	2245	1060	675	675
query94	644	248	205	205
query95	511	271	222	222
query96	800	608	276	276
query97	1027	1092	1010	1010
query98	177	130	133	130
query99	412	339	310	310
Total cold run time: 178476 ms
Total hot run time: 81320 ms

@hello-stephen

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

query1	0.01	0.00	0.01
query2	0.08	0.03	0.04
query3	0.25	0.12	0.11
query4	1.60	0.11	0.09
query5	0.16	0.15	0.16
query6	1.27	0.70	0.69
query7	0.03	0.01	0.00
query8	0.07	0.04	0.03
query9	0.28	0.21	0.21
query10	0.35	0.34	0.35
query11	0.16	0.11	0.12
query12	0.14	0.12	0.11
query13	0.30	0.31	0.30
query14	0.45	0.44	0.44
query15	0.37	0.35	0.35
query16	0.20	0.23	0.22
query17	0.71	0.68	0.68
query18	0.18	0.17	0.17
query19	1.22	1.20	1.09
query20	0.02	0.01	0.01
query21	15.43	0.17	0.12
query22	5.08	0.05	0.04
query23	16.18	0.26	0.10
query24	3.01	0.33	0.24
query25	0.12	0.03	0.02
query26	0.78	0.16	0.13
query27	0.04	0.03	0.03
query28	3.64	0.56	0.27
query29	12.48	3.13	2.53
query30	0.26	0.11	0.12
query31	2.75	0.38	0.17
query32	3.52	0.32	0.22
query33	1.34	1.49	1.52
query34	15.32	2.16	1.78
query35	1.75	1.76	1.70
query36	0.45	0.30	0.29
query37	0.06	0.04	0.04
query38	0.04	0.04	0.03
query39	0.03	0.02	0.02
query40	0.11	0.07	0.08
query41	0.07	0.03	0.02
query42	0.04	0.02	0.02
query43	0.03	0.03	0.03
Total cold run time: 90.38 s
Total hot run time: 14.6 s

@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 complete at exact head 0e66fd9522552abd9efa2bb685db6970859b19d1 against base 2573820600eb178150a35710a94fd58b478df96d after three bounded convergence rounds. Requesting changes for three P1 findings and one P2 finding attached inline.

Critical checkpoint conclusions

  • Goal and proof: The PR exposes ik_smart and ik_max_word to custom analyzers and covers the ordinary factory, reset, direct-offset, TOKENIZE, MATCH, CREATE, and ALTER paths. The happy path is coherent, but lazy error propagation, semantic identity, transforming-filter offsets, and unconditional resource costs keep the feature from being safely complete.
  • Scope and focus: The production change is generally focused on factory registration, tokenizer lifecycle/offsets, policy validation, and analyzer identity. All 22 authoritative changed files and their relevant callers/consumers were reviewed. No additional user focus was supplied, so the full PR remained in scope.
  • Concurrency: Factory publication and dictionary initialization use the existing process-wide call_once mechanisms; FE policy-map access remains under the existing reentrant lock discipline. No new thread, race, heavy-under-lock operation, inconsistent lock order, or deadlock issue was found.
  • Lifecycle/static initialization: Raw and shared readers, eager and reusable streams, reset-before-consume, EOF behavior, and source-map lifetime were traced. Reset and ownership are sound on supported production paths. The dictionary singleton itself is stable, but its new lazy creation point exposes the uncaught error boundary reported inline; no cross-TU static-order hazard was found.
  • Configuration: No new Doris runtime configuration key is added. Both modes use the established IK dictionary path and per-stream mode. No dynamic-configuration propagation gap was found.
  • Compatibility: No wire or storage-format field changes. Direct/case-variant factories align across FE and BE, and supported BE-before-FE rolling order avoids an old-BE factory gap. Replayed pre-upgrade tokenizer-name collisions are nevertheless misused by the new synthetic legacy identity, as reported inline.
  • Parallel paths: CREATE and ALTER share the faulty identity. TOKENIZE, row-fallback MATCH, and analyzed SEARCH all reach lazy tokenizer creation after their effective CLucene conversion boundary. Scalar/ARRAY writer and VARIANT metadata paths were separately traced; legal FE metadata does not route a custom analyzer into ARRAY ingestion, so that unsupported path is intentionally excluded from the finding.
  • Special conditions: The conditional reset is safe in the traced caller sequences. The legacy-identity guard omits behavior-affecting state, and term-text-only source-map forwarding is not compositional through a supported transforming filter; both are concrete inline findings.
  • Test coverage: Changed tests cover both modes, default legacy/custom duplicate detection in CREATE and ALTER, raw/shared reset contracts, synthetic IndexWriter ARRAY consumption, refill/direct full-width offsets, and deterministic TOKENIZE/MATCH results. Missing cases correspond to the four findings: first-use dictionary failure, legacy lower_case=false, replay-plus-duplicate identity, transforming-filter source offsets, and resource behavior. The residual dictionary test-order concern is already covered by an existing thread and was not reposted.
  • Test results: The regression uses ordered/deterministic output, pre-test drops, hardcoded table names, and expected-error form. Per the review contract, I ran no build or test, so these conclusions are static. Author-reported ASAN builds, combined BE tests, FE tests, and regression execution were treated as author evidence, not independent verification.
  • Observability: Existing dictionary logging is sufficient once failures are converted into Doris errors; no new metric is warranted. Letting a raw CLuceneError escape is an error-contract defect, not an observability substitute.
  • Persistence and transactions: Policy image/replay/name-map rebuilding was traced. No EditLog payload, transaction state machine, failover, or metadata-format change is introduced; replayed-name state is relevant only to the identity finding.
  • Data writes and crash behavior: Analyzer output affects inverted-index term generation, but no rowset/version/MoW, atomicity, partial-write, or crash-recovery defect was found. Direct offset/reset writer paths are sound; the supported transforming-filter chain still publishes incorrect source offsets.
  • FE-BE variables: No new Thrift or session variable is added. Existing string-valued policy properties carry the tokenizer/filter names; ordinary resolution agrees, with the synthetic-identity exception reported inline.
  • Performance and memory: The new source-map detector and enlarged eager token records affect every legacy/custom IK stream even when Pinyin is absent. This definite redundant scan and retained-memory growth is the P2 finding; no separate RTTI or memory-accounting finding was substantiated.
  • Other issues: Existing rendered threads and raw comments were treated as hard duplicate fences. Every candidate was ledgered and adjudicated. The final round narrowed supporting evidence but did not add or remove a finding; the stable four-finding set is complete within the three-round bound. Security review was neither requested nor implicated.

Comment thread be/src/storage/index/inverted/tokenizer/ik/ik_tokenizer_factory.h
Comment thread be/src/storage/index/inverted/token_filter/token_filter.h Outdated
Comment thread be/src/storage/index/inverted/analyzer/ik/IKTokenizer.cpp Outdated
airborne12 added a commit to airborne12/apache-doris that referenced this pull request Sep 13, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#67918

Problem Summary:

Lazy IK dictionary failures could escape the custom analyzer exception boundary, legacy IK identities could collide with behaviorally different or shadowed custom tokenizers, and pinyin offsets lost source-byte provenance after word delimiter processing. Source offset maps were also built even when no downstream filter consumed them.

Translate analyzer construction errors, keep legacy identity matching limited to equivalent built-in IK behavior, and make source-byte provenance opt-in and compositional through token filters. Preserve and rebase provenance for generated word delimiter parts and concatenations.

### Release note

None

### Check List (For Author)

- Test
    - [x] Regression test
    - [x] Unit Test

- Behavior changed:
    - [x] Yes. IK custom analyzers now report Doris analyzer errors, keep distinct identities for non-equivalent legacy settings, and preserve exact source offsets through delimiter and pinyin filters without unconditional mapping work.

- Does this need documentation?
    - [x] No.
@airborne12

Copy link
Copy Markdown
Member Author

run buildall

### What problem does this PR solve?

Related PR: apache#67918

Problem Summary:
The analyzer identity regression used inline assertions for deterministic
MATCH query results. Use ordered qt queries and runner-generated output so
these cases follow the repository's regression conventions. Preserve the
positive full-term matches and the negative keyword-fragment match.

### Release note

None

### Check List (For Author)

- Test:
  - run-regression-test.sh generated the new output (1 suite passed), then
    verified test_analyzer_identity_semantics and test_ik_custom_analyzer
    against this worktree's synchronized FE/BE ASAN output (2 suites passed).
  - The synchronized implementation also passed 137 related BE ASAN tests,
    115 related FE tests, and the full native FE/BE ASAN build.
- Behavior changed: No. This records the existing regression expectations.
- Does this need documentation: No. This is a regression-only change.
@airborne12

Copy link
Copy Markdown
Member Author

run buildall

@airborne12

Copy link
Copy Markdown
Member Author

/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 converged after two complete normal/risk-focused rounds. I am requesting changes for three data-correctness issues: gapped WordDelimiter concatenations corrupt downstream Pinyin offsets; distinct IK configurations share a MATCH selection key; and named character-filter identities ignore transformations absorbed by the downstream IK tokenizer.

Critical checkpoints:

  • Goal, proof, scope, and focus: the cross-cutting implementation is focused on IK custom-analyzer support, policy binding, semantic identity, MATCH dispatch, and source-offset propagation. The changed tests are broad, but their current oracles do not distinguish the three failures below. No additional user focus was specified.
  • Data correctness and FE/BE propagation: the three inline comments trace concrete term/offset or reader-selection failures through the relevant FE, Thrift, and BE paths. Implicit/explicit MATCH, slow analysis, SNII, variant SEARCH, scoring, and classic writer paths were checked where applicable.
  • Concurrency, lifecycle, and static state: FE policy maps remain lock-protected, BE maps remain protected by the existing shared mutex, replay/image/drop restore exact-name state, and token-stream reset paths clear their buffers. No distinct lock-order, stale-state, or initialization issue survived review.
  • Compatibility, configuration, persistence, and transactions: no new wire/storage field or runtime configuration is introduced. Supported BE-first rollout, journal/image reconstruction, policy reconciliation, and transaction/data-write boundaries were checked; residual exact-name lifecycle concerns are already covered by existing threads.
  • Error handling, ownership, nullability, observability, and resources: no new unhandled status/exception boundary, ownership/null path, or observability requirement was found. The remaining ICU dense-edit resource concern is already covered by an existing inline thread.
  • Tests and validation: this review was static only, as required by the review prompt; no build or test was run. Author/CI-reported results are not independent validation. Add discriminating regression/unit oracles for each inline reproduction.

Comment thread be/src/storage/index/inverted/token_filter/word_delimiter_filter.h Outdated
Comment thread fe/fe-core/src/main/java/org/apache/doris/analysis/InvertedIndexUtil.java Outdated
…ings

### What problem does this PR solve?

Related PR: apache#67918

Problem Summary:
Explicit built-in IK requests could select a smart or differently configured
physical index after distinct IK identities were admitted on one column.
Named A-to-a character replacement was not folded through IK's default
lowercasing, and word delimiter concatenation discarded source gaps needed
by downstream pinyin offsets. Encoded selection keys could also collide
with arbitrary legal policy names.

Match built-in IK indexes by effective configuration and carry the existing
mode, lowercase and outer character-filter fields into BE selection keys.
Separate encoded configurations from policy names without changing provider
bindings, Thrift or stored index formats. Canonicalize named character
filters in tokenizer context, and preserve optional per-rune source ends
through concatenation and reset. Run the two new global-policy suites in
the nonConcurrent group to avoid contributing to concurrent quota exhaustion.

### Release note

Fix IK MATCH index selection and effective analyzer duplicate detection,
and preserve pinyin source offsets through word delimiter concatenation.

### Check List (For Author)

- Test
    - [x] Regression test
      Official runner: test_analyzer_identity_semantics and
      test_ik_custom_analyzer passed together; test_ik_analyzer passed
      separately. Expected output was generated by the runner and then
      checked in a normal run on a task-owned ASAN cluster.
    - [x] Unit Test
      Official ASAN BE runner: 178 tests across 12 related suites passed.
      After clang-tidy fixes, all 120 tests in the three affected suites
      passed again. Official FE runner: 118 tests in four classes passed.
      The three review defects and the encoded-name collision have
      discriminating native RED/GREEN evidence.
    - [ ] Manual test
    - [ ] No need to test or manual test. Explain why:

- Additional validation
  Native build.sh --be --fe passed; BE was rebuilt after the final source
  change. Java Checkstyle and build hygiene passed. Clang-tidy checked all
  12 newly changed C++ files and rechecked the three files subsequently
  corrected, with no checks disabled. The run remains qualified by
  pre-existing processCurrentToken size/complexity diagnostics and
  diagnostics in unchanged CLucene and Boost headers. A baseline-only
  unmatched NOLINTEND comment was removed through a temporary VFS overlay,
  not by changing repository code. A controlled baseline source comparison
  confirmed the function's complexity decreased from 75 to 69 and its
  length from 141 to 125 lines. These are not claimed as a clean tidy pass.

- Behavior changed:
    - [ ] No.
    - [x] Yes. Explicit built-in IK uses its matching default configuration;
      distinct physical configurations retain separate selection keys,
      equivalent named character filters are rejected as duplicates, and
      concatenated tokens retain their original source spans.

- Does this need documentation?
    - [x] No. This corrects existing analyzer behavior and test isolation.
    - [ ] Yes.
@airborne12

Copy link
Copy Markdown
Member Author

run buildall

@airborne12

Copy link
Copy Markdown
Member Author

/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 exact-head review found one blocking rolling-upgrade compatibility issue, attached inline.

Checkpoint conclusions:

  • Goal/tests: the IK tokenizer, offset, identity, and current-version reader-selection paths have broad focused coverage, but the old-FE/new-BE request boundary is untested.
  • Focus/minimality: all 49 changed files are relevant to analyzer construction, policy/identity handling, offset provenance, physical selection, or their tests.
  • Concurrency/lifecycle/persistence: FE and BE exact/normalized maps are lock-protected and rebuild/reconcile deterministically; no distinct current-version replay, drop, retry, or failover defect survived review.
  • Configuration/observability: no new operator configuration is introduced; the blocking case is silent apart from the inverted-index downgrade counter and debug logging.
  • Compatibility/parallel paths: legacy and custom analyzers, implicit and explicit MATCH, CLucene/SNII selection, and the documented BE-before-FE upgrade order were traced. Exact reader keys are not compatible with the base FE request shape.
  • Conditions/data flow: mode, lowercase, outer filters, reset/reuse, UTF-8 clipping, deletion/expansion, and FE-to-BE analyzer fields were checked. Other technically valid concerns are already captured by live inline threads and were not reposted.
  • Performance: the blocking case converts an indexed MATCH into per-row analysis on upgraded BEs until FE upgrade.

Validation was static-only as required by the review contract: I did not run builds or tests. The PR body reports successful author-side BE, FE, regression, formatting, and partial clang-tidy validation, but those claims were not independently executed here. Three normal reviews, four targeted risk reviews, and a three-way convergence round completed; all final-round reviewers returned NO_NEW_VALUABLE_FINDINGS beyond the single inline issue.

Comment thread be/src/storage/index/inverted/inverted_index_parser.cpp
@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17593	3954	3835	3835
q2	2278	363	299	299
q3	10054	1377	777	777
q4	4693	481	360	360
q5	7466	845	544	544
q6	177	168	135	135
q7	738	792	579	579
q8	9324	1526	1535	1526
q9	5517	4252	4158	4158
q10	6724	1633	1377	1377
q11	440	276	252	252
q12	646	422	292	292
q13	18072	2589	1987	1987
q14	257	259	236	236
q15	q16	744	721	662	662
q17	1683	1072	1060	1060
q18	6608	5604	5542	5542
q19	1143	1279	1052	1052
q20	495	399	272	272
q21	5406	2568	2276	2276
q22	412	351	291	291
Total cold run time: 100470 ms
Total hot run time: 27512 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4244	4065	4058	4058
q2	749	601	564	564
q3	4517	4914	4357	4357
q4	2232	2292	1466	1466
q5	4196	4087	4094	4087
q6	218	168	126	126
q7	1698	1621	1433	1433
q8	2141	2232	2021	2021
q9	7371	7211	7358	7211
q10	4276	4286	3852	3852
q11	559	394	369	369
q12	716	733	514	514
q13	2447	2788	2173	2173
q14	298	306	282	282
q15	q16	695	716	635	635
q17	7884	7103	7063	7063
q18	11966	11245	11756	11245
q19	1209	1080	1043	1043
q20	2201	2203	1938	1938
q21	5786	4723	4573	4573
q22	536	448	398	398
Total cold run time: 65939 ms
Total hot run time: 59408 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 152795 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 2558085d88f6e815ff6775ce0c341a83fa1baef2, data reload: false

query5	4313	587	448	448
query6	421	177	166	166
query7	4801	517	300	300
query8	329	171	161	161
query9	8782	3926	3902	3902
query10	435	304	248	248
query11	5880	2185	1960	1960
query12	149	96	95	95
query13	1239	573	375	375
query14	6467	4480	4222	4222
query14_1	3994	3974	3961	3961
query15	199	199	182	182
query16	980	473	446	446
query17	910	666	535	535
query18	2420	458	335	335
query19	201	178	143	143
query20	107	101	105	101
query21	222	134	115	115
query22	13009	12933	12788	12788
query23	15428	14514	13859	13859
query23_1	14155	14480	14165	14165
query24	7485	1673	1233	1233
query24_1	1226	1247	1240	1240
query25	560	438	372	372
query26	1280	310	168	168
query27	2692	586	331	331
query28	4582	1952	1956	1952
query29	1057	590	479	479
query30	328	235	201	201
query31	892	754	642	642
query32	155	96	91	91
query33	525	322	252	252
query34	1183	1097	628	628
query35	721	782	640	640
query36	781	782	727	727
query37	154	106	88	88
query38	1834	1777	1699	1699
query39	685	702	658	658
query39_1	653	654	626	626
query40	238	124	105	105
query41	71	70	69	69
query42	93	93	92	92
query43	329	350	301	301
query44	1332	687	701	687
query45	188	181	176	176
query46	1001	1196	709	709
query47	1466	1486	1383	1383
query48	401	410	292	292
query49	581	401	288	288
query50	1017	340	243	243
query51	10409	10319	10054	10054
query52	85	86	73	73
query53	235	260	201	201
query54	240	202	180	180
query55	77	71	67	67
query56	234	224	210	210
query57	1504	1416	1382	1382
query58	238	203	205	203
query59	1967	2047	1837	1837
query60	271	258	220	220
query61	141	139	143	139
query62	391	316	261	261
query63	212	178	175	175
query64	2797	978	837	837
query65	4014	3994	3877	3877
query66	1797	411	317	317
query67	21336	19894	19867	19867
query68	3180	1489	988	988
query69	407	293	259	259
query70	934	928	855	855
query71	294	236	211	211
query72	2853	2442	2101	2101
query73	885	820	414	414
query74	4586	4467	4251	4251
query75	2283	2255	1926	1926
query76	2332	1081	690	690
query77	347	383	287	287
query78	9206	9139	8519	8519
query79	1375	1173	718	718
query80	576	448	358	358
query81	473	278	235	235
query82	636	159	125	125
query83	354	271	243	243
query84	305	145	113	113
query85	809	477	390	390
query86	321	232	229	229
query87	1999	1955	1850	1850
query88	3607	2697	2715	2697
query89	357	281	244	244
query90	1934	176	171	171
query91	164	151	121	121
query92	104	85	85	85
query93	1547	1432	819	819
query94	525	345	306	306
query95	660	451	321	321
query96	1103	734	338	338
query97	2416	2408	2295	2295
query98	194	188	180	180
query99	740	715	609	609
Total cold run time: 241436 ms
Total hot run time: 152795 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 23.85 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit 2558085d88f6e815ff6775ce0c341a83fa1baef2, 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.14	0.14
query5	0.25	0.22	0.22
query6	1.16	0.93	0.91
query7	0.04	0.01	0.01
query8	0.05	0.03	0.04
query9	0.39	0.33	0.33
query10	0.57	0.54	0.59
query11	0.20	0.14	0.14
query12	0.18	0.15	0.15
query13	0.47	0.47	0.46
query14	0.95	0.95	0.94
query15	0.60	0.58	0.57
query16	0.30	0.31	0.32
query17	1.10	1.10	1.07
query18	0.21	0.20	0.20
query19	2.01	1.94	1.91
query20	0.02	0.01	0.01
query21	15.43	0.21	0.13
query22	4.99	0.05	0.06
query23	16.13	0.31	0.12
query24	2.99	0.40	0.31
query25	0.11	0.05	0.04
query26	0.75	0.19	0.15
query27	0.04	0.03	0.03
query28	3.51	0.73	0.34
query29	12.46	4.03	3.21
query30	0.28	0.16	0.15
query31	2.77	0.57	0.30
query32	3.22	0.59	0.49
query33	3.34	3.15	3.17
query34	15.59	3.89	3.30
query35	3.22	3.23	3.18
query36	0.55	0.46	0.42
query37	0.08	0.07	0.06
query38	0.06	0.03	0.04
query39	0.04	0.04	0.04
query40	0.17	0.14	0.14
query41	0.08	0.03	0.03
query42	0.04	0.03	0.03
query43	0.04	0.04	0.03
Total cold run time: 96.37 s
Total hot run time: 23.85 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 77.23% (173/224) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 71.43% (160/224) 🎉
Increment coverage report
Complete coverage report

### What problem does this PR solve?

Older FE versions lowercase analyzer names in MATCH requests and index
properties, while replayed policy names may retain their original spelling.
Exact reader selection can therefore miss an existing inverted index during
a backend-first upgrade.

Resolve the provider and canonical policy name under the same policy lock.
Return a lowercase metadata alias only when it resolves to the same policy
and does not select a builtin analyzer. Prefer the canonical reader key and
use the verified alias only when that key is absent. Forward the binding to
both physical reader selection and similarity-statistics collection.

Cover exact and normalized metadata, legacy normalizers, case-colliding
policies, canonical-key precedence, builtin-name collisions, and scoring.
Initialize the real IK test dictionary explicitly so the selection fixture
does not depend on another test's global dictionary configuration.

Related PR: apache#67918

### Release note

Preserve custom-analyzer MATCH index bindings during backend-first upgrades.

### Check List (For Author)

- Test:
  - Native ASAN BE build passed with the GLIBC 2.17 compatibility gate.
  - Official ASAN BE runner passed 354 tests in 10 related suites.
  - Three discriminating native RED/GREEN cycles cover legacy exact metadata,
    normalized index metadata, and the builtin-name alias collision.
  - Official regression runner passed all three relevant analyzer suites on
    the task-owned native ASAN cluster, without expected-output edits.
  - A full mixed-version cluster upgrade was not run.
- Behavior changed: Yes. MATCH reuses only a compatible canonical or verified
  legacy index, and never substitutes another policy or a builtin analyzer.
- Does this need documentation: No. No new syntax, stored format, wire field,
  or configuration is introduced.
@airborne12

Copy link
Copy Markdown
Member Author

run buildall

@airborne12

Copy link
Copy Markdown
Member Author

/review

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17615	3916	3872	3872
q2	2253	337	300	300
q3	10028	1387	784	784
q4	4678	478	346	346
q5	7465	821	549	549
q6	178	171	135	135
q7	735	784	586	586
q8	9319	1319	1381	1319
q9	5503	4238	4211	4211
q10	6727	1642	1351	1351
q11	436	274	236	236
q12	638	404	292	292
q13	18058	2664	1989	1989
q14	263	257	236	236
q15	q16	739	721	671	671
q17	1730	1141	1034	1034
q18	6522	5608	5550	5550
q19	1254	1290	1012	1012
q20	451	381	254	254
q21	5803	2906	2507	2507
q22	454	366	313	313
Total cold run time: 100849 ms
Total hot run time: 27547 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4580	4520	4461	4461
q2	796	605	551	551
q3	4803	5289	4642	4642
q4	2254	2321	1482	1482
q5	4562	4581	4480	4480
q6	244	186	126	126
q7	1821	1741	1583	1583
q8	2492	2173	1991	1991
q9	7544	7389	6852	6852
q10	4242	4218	3792	3792
q11	519	373	335	335
q12	708	711	495	495
q13	2344	2646	1990	1990
q14	270	287	251	251
q15	q16	656	687	598	598
q17	7298	6745	6658	6658
q18	11871	11104	11781	11104
q19	1109	1005	1014	1005
q20	2214	2204	1938	1938
q21	5434	4437	4653	4437
q22	531	438	429	429
Total cold run time: 66292 ms
Total hot run time: 59200 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 152719 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 6618a7099cb4a347a1e26d492d9144b3b60210b5, data reload: false

query5	4342	576	460	460
query6	424	180	168	168
query7	4825	559	287	287
query8	314	174	161	161
query9	8790	3916	3903	3903
query10	447	307	256	256
query11	5760	2182	1987	1987
query12	150	95	95	95
query13	1245	510	417	417
query14	6552	4527	4178	4178
query14_1	3983	3971	3971	3971
query15	205	196	177	177
query16	991	439	411	411
query17	905	643	517	517
query18	2417	449	328	328
query19	196	188	141	141
query20	103	102	106	102
query21	224	133	116	116
query22	13118	13103	12934	12934
query23	15496	14463	13969	13969
query23_1	14086	13931	13886	13886
query24	7595	1658	1213	1213
query24_1	1240	1235	1220	1220
query25	504	401	345	345
query26	1267	308	168	168
query27	2699	531	341	341
query28	4545	1947	1919	1919
query29	1027	575	448	448
query30	313	235	197	197
query31	868	759	616	616
query32	148	98	95	95
query33	504	310	243	243
query34	1188	1165	618	618
query35	717	771	633	633
query36	800	789	715	715
query37	157	104	87	87
query38	1828	1760	1708	1708
query39	687	660	665	660
query39_1	671	631	634	631
query40	231	117	100	100
query41	67	66	64	64
query42	92	87	92	87
query43	341	344	306	306
query44	1322	672	688	672
query45	193	178	183	178
query46	1062	1166	720	720
query47	1504	1495	1382	1382
query48	408	402	290	290
query49	604	413	303	303
query50	952	346	251	251
query51	10559	10162	10339	10162
query52	87	87	80	80
query53	235	262	180	180
query54	259	221	210	210
query55	77	73	75	73
query56	251	240	232	232
query57	1483	1463	1349	1349
query58	247	223	215	215
query59	1969	2054	1818	1818
query60	303	257	237	237
query61	166	165	164	164
query62	403	328	268	268
query63	224	180	174	174
query64	2815	1119	950	950
query65	4027	3979	3943	3943
query66	1800	438	328	328
query67	19939	20010	19877	19877
query68	3193	1479	893	893
query69	411	298	269	269
query70	966	904	849	849
query71	289	240	218	218
query72	2954	2463	1959	1959
query73	827	761	415	415
query74	4573	4484	4271	4271
query75	2295	2250	1936	1936
query76	2344	1109	705	705
query77	353	398	299	299
query78	9074	9024	8476	8476
query79	1412	1155	715	715
query80	1256	452	347	347
query81	526	279	237	237
query82	693	159	131	131
query83	358	269	239	239
query84	309	142	104	104
query85	880	467	372	372
query86	410	235	226	226
query87	1990	1952	1831	1831
query88	3608	2709	2685	2685
query89	360	278	244	244
query90	1946	180	190	180
query91	166	157	125	125
query92	100	96	92	92
query93	1615	1495	822	822
query94	716	320	309	309
query95	650	369	423	369
query96	1078	741	335	335
query97	2421	2420	2304	2304
query98	204	189	183	183
query99	733	727	617	617
Total cold run time: 241780 ms
Total hot run time: 152719 ms

@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 of exact head 6618a7099cb4a347a1e26d492d9144b3b60210b5 found two distinct blocking issues: lazy custom-IK failures cross classic Status boundaries as the wrong exception type, and analyzer identity still misses a redundant pre-ICU replacement. Existing inline threads were treated as hard duplicate fences.

Critical checkpoint conclusions:

  • Goal and tests: the PR largely implements custom IK tokenizers, source-offset propagation, exact policy binding, and configuration-aware reader selection, with broad FE/BE/regression coverage; the two missing negative cases below prevent completion.
  • Scope and focus: the 57-file change is broad but coherent around analyzer construction, identity, offsets, selection, and compatibility; no unrelated production change was found.
  • Concurrency: FE/BE policy maps are lock-protected and deterministic collision restoration was traced; process-global IK initialization uses call_once. No new deadlock or lock-order issue survived review.
  • Lifecycle: dictionary first-use/failure/reload and reusable token-stream reset were traced. The accepted BE finding is the remaining lifecycle/error-boundary defect.
  • Configuration: no new dynamically mutable server setting is introduced; existing dictionary-path behavior is used.
  • Compatibility: no Thrift field or storage-format change was added. The supported BE-first rolling shape, exact-name aliases, classic/Nereids senders, MATCH, scoring, SEARCH, and variant paths were traced without another distinct issue.
  • Parallel paths: classic and SNII paths were compared; the classic writer/query/scoring boundaries do not match SNII's doris::Exception handling, which is the first finding.
  • Conditions and identity: built-in/custom collision, mode, lowercase, outer-filter, and ordered-filter conditions were reviewed. The reverse char-filter walk loses a valid downstream absorption fact, which is the second finding.
  • Test coverage and results: changed unit and regression tests cover reset/reuse, offsets, exact binding, selection, and upgrade aliases, but do not cover either accepted failure. Review was static-only; I did not build or run tests, and author/CI test claims are not independent validation.
  • Observability: existing policy and dictionary logs are sufficient for the reviewed paths; no additional metric requirement was identified.
  • Persistence, transactions, and writes: journal/image rebuild, FE-to-BE policy reconciliation, dependency checks, and writer call chains were traced. No new transaction or atomicity issue survived beyond the exception escape below.
  • FE/BE variables: all existing TMatchPredicate fields and sender paths were checked; no missing variable propagation was found.
  • Performance: opt-in provenance, compact ICU correction runs, and reader-key lookup were reviewed; no distinct unfenced performance defect remained.
  • Other issues: the final changed-file sweep and two convergence rounds left no unresolved candidate; substantially similar offset and exact-validation concerns were not resubmitted.

ts = filter->create(ts);
}
return std::make_shared<TokenStreamComponents>(tk, ts);
} catch (const CLuceneError& e) {

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.

[P1] Keep lazy IK failures inside the classic Status boundaries

This catch changes a lazy IKTokenizerFactory::create() failure from CLuceneError to doris::Exception, but the classic call sites still catch only CLuceneError. InvertedIndexColumnWriter::new_inverted_index_field() invokes reusableTokenStream() inside a Status method, and FullTextIndexReader::query() invokes get_analyse_result() inside another Status method; with a missing or corrupt IK dictionary, the converted exception now escapes both instead of returning their analyzer error. The added test calls CustomAnalyzer::tokenStream() directly, so it does not cover either boundary. Please preserve the original exception here or teach every classic invocation boundary to convert doris::Exception to a non-OK Status, and add a writer/query failure-path test.

}
identities.addFirst(filter);
// An earlier replacement can change the input of a later filter.
lowercaseIk = false;

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.

[P1] Preserve absorption through a downstream case-folding filter

Clearing lowercaseIk after every nonempty downstream filter still gives different identities to equivalent pipelines. For example, let lower_a={type=char_replace,pattern=A,replacement=a} and fold={type=icu_normalizer} with its default nfkc_cf; {tokenizer=ik_smart,char_filter=fold} and {tokenizer=ik_smart,char_filter=lower_a,fold} emit the same text, positions, and source offsets because nfkc_cf already maps A to a. Walking backward resolves fold, clears the absorption context here, and then retains lower_a, so CREATE/ALTER can admit both indexes. Please propagate the known nfkc_cf case-folding context backward (or canonicalize the composed pipeline) and cover this intervening-filter case.

@hello-stephen

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

query1	0.00	0.00	0.00
query2	0.09	0.05	0.05
query3	0.26	0.14	0.14
query4	1.61	0.14	0.15
query5	0.24	0.22	0.22
query6	1.16	0.92	0.92
query7	0.04	0.00	0.00
query8	0.05	0.04	0.04
query9	0.39	0.33	0.34
query10	0.54	0.54	0.57
query11	0.20	0.15	0.15
query12	0.18	0.15	0.15
query13	0.48	0.45	0.46
query14	1.00	0.97	0.94
query15	0.59	0.59	0.59
query16	0.33	0.33	0.34
query17	1.10	1.10	1.09
query18	0.20	0.21	0.19
query19	2.02	1.92	1.99
query20	0.02	0.01	0.01
query21	15.43	0.19	0.13
query22	5.00	0.05	0.05
query23	16.15	0.31	0.12
query24	2.93	0.41	0.32
query25	0.10	0.06	0.04
query26	0.73	0.21	0.15
query27	0.03	0.05	0.03
query28	3.51	0.82	0.37
query29	12.48	4.02	3.20
query30	0.28	0.16	0.15
query31	2.77	0.56	0.31
query32	3.23	0.58	0.49
query33	3.11	3.33	3.22
query34	15.62	3.90	3.32
query35	3.23	3.25	3.24
query36	0.56	0.45	0.43
query37	0.09	0.07	0.06
query38	0.05	0.03	0.04
query39	0.04	0.03	0.03
query40	0.18	0.15	0.15
query41	0.08	0.03	0.03
query42	0.04	0.04	0.03
query43	0.04	0.03	0.03
Total cold run time: 96.18 s
Total hot run time: 24.13 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 77.23% (173/224) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 92.79% (103/111) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 63.59% (29613/46569)
Line Coverage 48.32% (308477/638467)
Region Coverage 43.93% (248991/566787)
Branch Coverage 45.47% (115740/254518)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 71.43% (160/224) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 92.66% (101/109) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 76.27% (34392/45092)
Line Coverage 61.17% (386087/631185)
Region Coverage 57.57% (325009/564503)
Branch Coverage 58.35% (148061/253729)

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.

3 participants