Skip to content

Commit 01a5b36

Browse files
github-actions[bot]morrySnowCopilot
authored
branch-4.1: [fix](fe) Fix Type.exceedsMaxNestingDepth skipping MAP keyType recursion #63201 (#63213)
Cherry-picked from #63201 Co-authored-by: morrySnow <zhangwenxin@selectdb.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 4da4d13 commit 01a5b36

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

  • fe
    • fe-common/src/main/java/org/apache/doris/catalog
    • fe-core/src/test/java/org/apache/doris/catalog

fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,9 @@ private boolean exceedsMaxNestingDepth(int d) {
797797
return itemType.exceedsMaxNestingDepth(d + 1);
798798
} else if (isMapType()) {
799799
MapType mapType = (MapType) this;
800+
if (mapType.getKeyType().exceedsMaxNestingDepth(d + 1)) {
801+
return true;
802+
}
800803
return mapType.getValueType().exceedsMaxNestingDepth(d + 1);
801804
} else {
802805
Preconditions.checkState(isScalarType() || isAggStateType());

fe/fe-core/src/test/java/org/apache/doris/catalog/TypeTest.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,46 @@ public void testDecimalPrecisionGroupsIgnorePrecision() {
185185
Assert.assertFalse(Type.matchExactType(d20s1, d38s1, false));
186186
}
187187

188+
// ===================== exceedsMaxNestingDepth =====================
189+
190+
/**
191+
* Builds a MAP<MAP<...<MAP<STRING, STRING>>...>, STRING> with the given number of outer MAP wrappers.
192+
* This tests the keyType recursion path of exceedsMaxNestingDepth().
193+
*/
194+
private static Type buildMapKeyNestedType(int depth) {
195+
// innermost: MAP<STRING, STRING> counts as depth 1 (from the caller's perspective we start at d=0)
196+
Type current = new MapType(Type.STRING, Type.STRING, true, true);
197+
for (int i = 1; i < depth; i++) {
198+
current = new MapType(current, Type.STRING, true, true);
199+
}
200+
return current;
201+
}
202+
203+
@Test
204+
public void testMapKeyPathNestingWithinLimit() {
205+
// MAP < MAP < ... STRING ...>, STRING > with total nesting == MAX_NESTING_DEPTH should be allowed
206+
Type t = buildMapKeyNestedType(Type.MAX_NESTING_DEPTH);
207+
Assert.assertFalse(t.exceedsMaxNestingDepth());
208+
}
209+
210+
@Test
211+
public void testMapKeyPathDeepNestingDetected() {
212+
// Nesting depth of MAX_NESTING_DEPTH + 1 via keyType path must be rejected
213+
Type t = buildMapKeyNestedType(Type.MAX_NESTING_DEPTH + 1);
214+
Assert.assertTrue(t.exceedsMaxNestingDepth());
215+
}
216+
217+
@Test
218+
public void testMapValuePathDeepNestingDetected() {
219+
// Existing valueType path should still be detected (regression guard).
220+
// Need MAX_NESTING_DEPTH + 1 wraps so the innermost reaches d = MAX_NESTING_DEPTH + 1.
221+
Type current = Type.STRING;
222+
for (int i = 0; i <= Type.MAX_NESTING_DEPTH; i++) {
223+
current = new MapType(Type.STRING, current, true, true);
224+
}
225+
Assert.assertTrue(current.exceedsMaxNestingDepth());
226+
}
227+
188228
@Test
189229
public void testDatetimeV2ScaleMatching() {
190230
ScalarType dtv2s3 = ScalarType.createDatetimeV2Type(3);

0 commit comments

Comments
 (0)