Skip to content

[fix](fe) Fix Type.exceedsMaxNestingDepth skipping MAP keyType recursion#63201

Merged
morrySnow merged 1 commit into
apache:masterfrom
morrySnow:doris-25592-map-keytype-nesting-depth
May 13, 2026
Merged

[fix](fe) Fix Type.exceedsMaxNestingDepth skipping MAP keyType recursion#63201
morrySnow merged 1 commit into
apache:masterfrom
morrySnow:doris-25592-map-keytype-nesting-depth

Conversation

@morrySnow
Copy link
Copy Markdown
Contributor

@morrySnow morrySnow commented May 13, 2026

Summary

Type.exceedsMaxNestingDepth in the MAP branch only recursed into valueType and silently skipped keyType. A user could construct arbitrarily deep types via the MAP key path, bypassing the 9-layer nesting limit.

What problem does this PR solve?

Problem Summary:

// Before fix — MAP branch:
} else if (isMapType()) {
    MapType mapType = (MapType) this;
    return mapType.getValueType().exceedsMaxNestingDepth(d + 1);  // keyType never checked
}

ARRAY and STRUCT branches recursed correctly; only MAP missed the keyType path.

Fix

} else if (isMapType()) {
    MapType mapType = (MapType) this;
    if (mapType.getKeyType().exceedsMaxNestingDepth(d + 1)) {
        return true;
    }
    return mapType.getValueType().exceedsMaxNestingDepth(d + 1);
}

Tests

Three new FE unit tests added to TypeTest:

  • testMapKeyPathNestingWithinLimitMAX_NESTING_DEPTH levels via keyType → allowed (assertFalse)
  • testMapKeyPathDeepNestingDetectedMAX_NESTING_DEPTH + 1 levels via keyType → rejected (assertTrue)
  • testMapValuePathDeepNestingDetected — regression guard: valueType path still detected (assertTrue)

All 11 tests in TypeTest pass.

Release note

Fix MAP key-type nesting-depth check bypass: deeply-nested MAP key types are now correctly rejected with "Type exceeds the maximum nesting depth".

Check List (For Author)

  • Test: FE Unit Test
  • Behavior changed: Yes — MAP types with deep nesting via keyType path are now rejected as intended by the spec.
  • Does this need documentation: No

### What problem does this PR solve?

Issue Number: close #DORIS-25592

Problem Summary: `Type.exceedsMaxNestingDepth` in the MAP branch only
recursed into `valueType` and silently skipped `keyType`. A user could
construct arbitrarily deep types via the MAP key path, bypassing the
9-layer nesting limit.

### Release note

Fix MAP key-type nesting-depth check bypass: deeply-nested MAP key types
are now correctly rejected with "Type exceeds the maximum nesting depth".

### Check List (For Author)

- Test: FE Unit Test — TypeTest#testMapKeyPathDeepNestingDetected (new),
  TypeTest#testMapKeyPathNestingWithinLimit (new),
  TypeTest#testMapValuePathDeepNestingDetected (new, regression guard)
- Behavior changed: Yes — MAP types with deep nesting via keyType path
  are now rejected as intended by the spec.
- Does this need documentation: No

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@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?

@morrySnow
Copy link
Copy Markdown
Contributor Author

run buildall

@morrySnow
Copy link
Copy Markdown
Contributor Author

/review

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Review result: no blocking issues found.

Critical checkpoint conclusions:

  • Goal and coverage: The PR fixes Type.exceedsMaxNestingDepth() so MAP key types are traversed, closing the key-path bypass. The new tests cover within-limit MAP key nesting, over-limit MAP key nesting, and the existing MAP value path.
  • Scope and clarity: The production change is minimal and focused: one additional recursive check before the existing value-type recursion.
  • Concurrency and lifecycle: Not applicable; this is pure immutable type validation logic with no shared mutable state, locks, threads, or lifecycle changes.
  • Configuration and compatibility: No new configs, protocol fields, storage formats, persisted metadata, or rolling-upgrade compatibility concerns.
  • Parallel code paths: ARRAY, STRUCT, and MAP value recursion remain intact; the missing MAP key recursion is now aligned with the other complex-type paths.
  • Error handling: Existing caller behavior is preserved; validateDataType() still raises the same maximum nesting-depth error when exceedsMaxNestingDepth() returns true.
  • Tests: mvn checkstyle:check -pl fe-core passed. Focused unit test execution was attempted; mvn test -pl fe-core -Dtest=org.apache.doris.catalog.TypeTest failed because fe-foundation was absent locally, mvn test -pl fe-core -am -Dtest=org.apache.doris.catalog.TypeTest failed because upstream modules had no matching tests, and rerunning with -DfailIfNoTests=false progressed further but failed because thirdparty/installed/bin/thrift is missing in this runner.
  • Observability: Not needed for this validation helper change.
  • Transactions/persistence/data visibility: Not applicable.
  • Performance: The added key recursion is bounded by MAX_NESTING_DEPTH and only runs during type validation; no hot-path performance concern found.

User focus: no additional user-provided review focus was present.

@hello-stephen
Copy link
Copy Markdown
Contributor

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

------ Round 1 ----------------------------------
orders	Doris	NULL	NULL	0	0	0	NULL	0	NULL	NULL	2023-12-26 18:27:23	2023-12-26 18:42:55	NULL	utf-8	NULL	NULL	
============================================
q1	17662	3814	3814	3814
q2	q3	10716	901	609	609
q4	4655	459	344	344
q5	7456	1367	1141	1141
q6	191	171	144	144
q7	909	946	780	780
q8	9314	1435	1324	1324
q9	5594	5421	5324	5324
q10	6235	2083	1815	1815
q11	468	274	266	266
q12	624	427	301	301
q13	18087	3404	2737	2737
q14	290	287	259	259
q15	q16	897	879	790	790
q17	923	1090	748	748
q18	6385	5663	5525	5525
q19	1168	1218	1117	1117
q20	522	416	268	268
q21	4645	2405	1976	1976
q22	475	426	335	335
Total cold run time: 97216 ms
Total hot run time: 29617 ms

----- Round 2, with runtime_filter_mode=off -----
orders	Doris	NULL	NULL	150000000	42	6422171781	NULL	22778155	NULL	NULL	2023-12-26 18:27:23	2023-12-26 18:42:55	NULL	utf-8	NULL	NULL	
============================================
q1	4851	4677	4799	4677
q2	q3	4655	4823	4223	4223
q4	2124	2195	1392	1392
q5	4987	5009	5249	5009
q6	195	168	133	133
q7	2086	1835	1635	1635
q8	3351	3089	3161	3089
q9	8471	8461	8427	8427
q10	4476	4504	4247	4247
q11	605	416	400	400
q12	705	758	527	527
q13	3346	3662	2945	2945
q14	294	317	276	276
q15	q16	788	787	683	683
q17	1511	1295	1310	1295
q18	7919	7016	7160	7016
q19	1166	1176	1172	1172
q20	2207	2242	1953	1953
q21	6201	5523	5118	5118
q22	549	521	416	416
Total cold run time: 60487 ms
Total hot run time: 54633 ms

@hello-stephen
Copy link
Copy Markdown
Contributor

TPC-DS: Total hot run time: 171971 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 df8c20a828aa39a274216af6fdf19a28a0c3bb33, data reload: false

query5	4300	694	535	535
query6	329	237	210	210
query7	4255	587	312	312
query8	330	241	231	231
query9	8820	4082	4054	4054
query10	465	342	310	310
query11	5734	2397	2240	2240
query12	179	134	137	134
query13	1311	628	442	442
query14	6235	5375	5116	5116
query14_1	4440	4458	4410	4410
query15	212	208	186	186
query16	1016	476	456	456
query17	1154	798	665	665
query18	2743	511	369	369
query19	246	225	170	170
query20	157	139	138	138
query21	228	153	126	126
query22	13769	14027	14532	14027
query23	17172	16610	16445	16445
query23_1	16409	16240	16267	16240
query24	7560	1720	1357	1357
query24_1	1370	1358	1367	1358
query25	564	472	415	415
query26	1316	322	171	171
query27	2652	577	331	331
query28	4364	1975	1956	1956
query29	1014	641	531	531
query30	297	235	196	196
query31	1105	1078	955	955
query32	85	71	69	69
query33	520	347	297	297
query34	1173	1146	646	646
query35	768	781	671	671
query36	1317	1297	1085	1085
query37	146	102	85	85
query38	3239	3136	3071	3071
query39	926	935	913	913
query39_1	865	876	876	876
query40	233	153	136	136
query41	65	62	60	60
query42	108	108	112	108
query43	322	324	287	287
query44	
query45	212	201	189	189
query46	1082	1178	718	718
query47	2252	2303	2169	2169
query48	400	426	288	288
query49	630	537	431	431
query50	708	292	234	234
query51	4328	4300	4249	4249
query52	107	109	97	97
query53	258	279	209	209
query54	311	274	251	251
query55	95	93	89	89
query56	335	308	312	308
query57	1426	1363	1298	1298
query58	295	271	262	262
query59	1611	1702	1469	1469
query60	330	333	336	333
query61	159	147	157	147
query62	679	616	573	573
query63	236	202	214	202
query64	2366	804	665	665
query65	
query66	1708	517	390	390
query67	30182	30127	30002	30002
query68	
query69	462	353	303	303
query70	1009	1009	1011	1009
query71	315	275	276	275
query72	2968	2695	2459	2459
query73	874	772	406	406
query74	5115	4915	4753	4753
query75	2772	2664	2356	2356
query76	2319	1153	805	805
query77	426	433	357	357
query78	13080	12918	12449	12449
query79	1509	1010	712	712
query80	1368	575	509	509
query81	530	289	248	248
query82	995	158	132	132
query83	350	291	246	246
query84	266	139	109	109
query85	913	494	440	440
query86	460	352	334	334
query87	3465	3412	3243	3243
query88	3549	2672	2682	2672
query89	439	376	341	341
query90	1950	194	190	190
query91	183	166	138	138
query92	79	77	72	72
query93	1123	966	564	564
query94	707	328	302	302
query95	668	379	345	345
query96	1054	795	344	344
query97	2687	2691	2551	2551
query98	242	234	222	222
query99	1103	1123	969	969
Total cold run time: 254948 ms
Total hot run time: 171971 ms

@hello-stephen
Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage `` 🎉
Increment coverage report
Complete coverage report

@hello-stephen
Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 0.00% (0/188) 🎉
Increment coverage report
Complete coverage report

@github-actions github-actions Bot added the approved Indicates a PR has been approved by one committer. label May 13, 2026
@github-actions
Copy link
Copy Markdown
Contributor

PR approved by at least one committer and no changes requested.

@github-actions
Copy link
Copy Markdown
Contributor

PR approved by anyone and no changes requested.

@morrySnow morrySnow merged commit a8216b5 into apache:master May 13, 2026
35 checks passed
@morrySnow morrySnow deleted the doris-25592-map-keytype-nesting-depth branch May 13, 2026 08:38
github-actions Bot pushed a commit that referenced this pull request May 13, 2026
…ion (#63201)

## Summary

`Type.exceedsMaxNestingDepth` in the MAP branch only recursed into
`valueType` and silently skipped `keyType`. A user could construct
arbitrarily deep types via the MAP key path, bypassing the 9-layer
nesting limit.

### What problem does this PR solve?

Problem Summary:

```java
// Before fix — MAP branch:
} else if (isMapType()) {
    MapType mapType = (MapType) this;
    return mapType.getValueType().exceedsMaxNestingDepth(d + 1);  // keyType never checked
}
```

ARRAY and STRUCT branches recursed correctly; only MAP missed the
keyType path.

### Fix

```java
} else if (isMapType()) {
    MapType mapType = (MapType) this;
    if (mapType.getKeyType().exceedsMaxNestingDepth(d + 1)) {
        return true;
    }
    return mapType.getValueType().exceedsMaxNestingDepth(d + 1);
}
```

### Tests

Three new FE unit tests added to `TypeTest`:

- `testMapKeyPathNestingWithinLimit` — `MAX_NESTING_DEPTH` levels via
keyType → allowed (assertFalse)
- `testMapKeyPathDeepNestingDetected` — `MAX_NESTING_DEPTH + 1` levels
via keyType → rejected (assertTrue)
- `testMapValuePathDeepNestingDetected` — regression guard: valueType
path still detected (assertTrue)

All 11 tests in `TypeTest` pass.

### Release note

Fix MAP key-type nesting-depth check bypass: deeply-nested MAP key types
are now correctly rejected with "Type exceeds the maximum nesting
depth".

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
github-actions Bot pushed a commit that referenced this pull request May 13, 2026
…ion (#63201)

## Summary

`Type.exceedsMaxNestingDepth` in the MAP branch only recursed into
`valueType` and silently skipped `keyType`. A user could construct
arbitrarily deep types via the MAP key path, bypassing the 9-layer
nesting limit.

### What problem does this PR solve?

Problem Summary:

```java
// Before fix — MAP branch:
} else if (isMapType()) {
    MapType mapType = (MapType) this;
    return mapType.getValueType().exceedsMaxNestingDepth(d + 1);  // keyType never checked
}
```

ARRAY and STRUCT branches recursed correctly; only MAP missed the
keyType path.

### Fix

```java
} else if (isMapType()) {
    MapType mapType = (MapType) this;
    if (mapType.getKeyType().exceedsMaxNestingDepth(d + 1)) {
        return true;
    }
    return mapType.getValueType().exceedsMaxNestingDepth(d + 1);
}
```

### Tests

Three new FE unit tests added to `TypeTest`:

- `testMapKeyPathNestingWithinLimit` — `MAX_NESTING_DEPTH` levels via
keyType → allowed (assertFalse)
- `testMapKeyPathDeepNestingDetected` — `MAX_NESTING_DEPTH + 1` levels
via keyType → rejected (assertTrue)
- `testMapValuePathDeepNestingDetected` — regression guard: valueType
path still detected (assertTrue)

All 11 tests in `TypeTest` pass.

### Release note

Fix MAP key-type nesting-depth check bypass: deeply-nested MAP key types
are now correctly rejected with "Type exceeds the maximum nesting
depth".

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
morningman pushed a commit that referenced this pull request May 16, 2026
…yType recursion #63201 (#63212)

Cherry-picked from #63201

Co-authored-by: morrySnow <zhangwenxin@selectdb.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by one committer. dev/4.0.6-merged dev/4.1.x reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants