This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.2
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.2 by this push:
new 2c0dfb21ced branch-4.2: [fix](fe) Reject complex types
(ARRAY/MAP/STRUCT) as MAP key types #63621 (#70037)
2c0dfb21ced is described below
commit 2c0dfb21ceddfe341fe3c5675d02bfb0522613cf
Author: morrySnow <[email protected]>
AuthorDate: Tue Nov 3 17:19:06 2026 +0800
branch-4.2: [fix](fe) Reject complex types (ARRAY/MAP/STRUCT) as MAP key
types #63621 (#70037)
picked from master #63621
---
.../org/apache/doris/nereids/types/DataType.java | 7 +++-
.../trees/plans/CreateTableCommandTest.java | 24 ++++++++++++++
.../string_len/test_string_len_complex.out | 7 ----
.../test_complex_disallowed_subtypes.groovy | 33 +++++++++++++++++++
.../string_len/test_string_len_complex.groovy | 38 ----------------------
.../show/test_nested_complex_switch.groovy | 17 ----------
6 files changed, 63 insertions(+), 63 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DataType.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DataType.java
index d3bcd607fc3..782e7462471 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DataType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DataType.java
@@ -949,7 +949,12 @@ public abstract class DataType {
if (catalogType.isMapType()) {
org.apache.doris.catalog.MapType mt =
(org.apache.doris.catalog.MapType) catalogType;
- validateNestedType(catalogType, mt.getKeyType());
+ Type mapKeyType = mt.getKeyType();
+ if (mapKeyType.isComplexType()) {
+ throw new AnalysisException(
+ "MAP key type must be a primitive type but get " +
mapKeyType.toSql());
+ }
+ validateNestedType(catalogType, mapKeyType);
validateNestedType(catalogType, mt.getValueType());
}
if (catalogType.isStructType()) {
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/CreateTableCommandTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/CreateTableCommandTest.java
index 2ec8b39aa57..eb49d9790ae 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/CreateTableCommandTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/CreateTableCommandTest.java
@@ -709,6 +709,30 @@ public class CreateTableCommandTest extends
TestWithFeService {
+ "distributed by hash(k1) buckets 1
properties('replication_num' = '1');"));
}
+ @Test
+ public void testCreateTableWithComplexMapKey() {
+ // MAP<ARRAY<INT>, INT> should be rejected - array key
+ checkThrow(AnalysisException.class, "MAP key type must be a primitive
type",
+ () -> createTable("create table test.test_map_array_key(k1
INT, k2 Map<Array<int>, int>) "
+ + "duplicate key (k1) distributed by hash(k1) buckets
1 "
+ + "properties('replication_num' = '1');"));
+ // MAP<MAP<INT, INT>, INT> should be rejected - map key
+ checkThrow(AnalysisException.class, "MAP key type must be a primitive
type",
+ () -> createTable("create table test.test_map_map_key(k1 INT,
k2 Map<Map<int,int>, int>) "
+ + "duplicate key (k1) distributed by hash(k1) buckets
1 "
+ + "properties('replication_num' = '1');"));
+ // MAP<STRUCT<f1:INT>, INT> should be rejected - struct key
+ checkThrow(AnalysisException.class, "MAP key type must be a primitive
type",
+ () -> createTable("create table test.test_map_struct_key(k1
INT, k2 Map<Struct<f1:int>, int>) "
+ + "duplicate key (k1) distributed by hash(k1) buckets
1 "
+ + "properties('replication_num' = '1');"));
+ // MAP<STRING, ARRAY<INT>> should still be accepted - complex value
type is OK
+ Assertions.assertDoesNotThrow(
+ () -> createTable("create table test.test_map_complex_value(k1
INT, k2 Map<String, Array<int>>) "
+ + "duplicate key (k1) distributed by hash(k1) buckets
1 "
+ + "properties('replication_num' = '1');"));
+ }
+
@Test
public void testCreateTableWithStructType() {
Assertions.assertDoesNotThrow(
diff --git
a/regression-test/data/datatype_p0/nested_types/string_len/test_string_len_complex.out
b/regression-test/data/datatype_p0/nested_types/string_len/test_string_len_complex.out
index acc8e888691..d09fc1f00f6 100644
---
a/regression-test/data/datatype_p0/nested_types/string_len/test_string_len_complex.out
+++
b/regression-test/data/datatype_p0/nested_types/string_len/test_string_len_complex.out
@@ -34,10 +34,3 @@
-- !sql_map_all2 --
--- !sql_map_all3 --
-1 {{"01234567891":"12345678901"}:{"11234567891":"12345678901"},
{"01234567892":"12345678902"}:{"11234567892":"12345678902"}}
-2 {{"01234567891":"22345678901"}:{"11234567891":"22345678901"},
{"01234567892":"22345678902"}:{"11234567892":"22345678902"}}
-3 {{"01234567891":"32345678901"}:{"11234567891":"32345678901"},
{"01234567892":"32345678902"}:{"11234567892":"32345678902"}}
-
--- !sql_map_all4 --
-
diff --git
a/regression-test/suites/datatype_p0/complex_types/test_complex_disallowed_subtypes.groovy
b/regression-test/suites/datatype_p0/complex_types/test_complex_disallowed_subtypes.groovy
index 36d261e9d0a..684c1084f83 100644
---
a/regression-test/suites/datatype_p0/complex_types/test_complex_disallowed_subtypes.groovy
+++
b/regression-test/suites/datatype_p0/complex_types/test_complex_disallowed_subtypes.groovy
@@ -64,6 +64,31 @@ suite("test_complex_disallowed_subtypes") {
exception "unsupported sub-type"
}
+ // ---- DORIS-25583: MAP key must not be a complex type (MAP/ARRAY/STRUCT)
----
+
+ sql "DROP TABLE IF EXISTS t_complex_map_key_1"
+ sql "DROP TABLE IF EXISTS t_complex_map_key_2"
+ sql "DROP TABLE IF EXISTS t_complex_map_key_3"
+ sql "DROP TABLE IF EXISTS t_complex_map_key_valid"
+
+ test {
+ // MAP<ARRAY<INT>, INT>
+ sql "CREATE TABLE t_complex_map_key_1 (k INT, v MAP<ARRAY<INT>,INT>)
DUPLICATE KEY(k) DISTRIBUTED BY HASH(k) BUCKETS 1
PROPERTIES('replication_num'='1')"
+ exception "MAP key type must be a primitive type"
+ }
+
+ test {
+ // MAP<MAP<STRING,INT>, INT>
+ sql "CREATE TABLE t_complex_map_key_2 (k INT, v
MAP<MAP<STRING,INT>,INT>) DUPLICATE KEY(k) DISTRIBUTED BY HASH(k) BUCKETS 1
PROPERTIES('replication_num'='1')"
+ exception "MAP key type must be a primitive type"
+ }
+
+ test {
+ // MAP<STRUCT<a:INT>, INT>
+ sql "CREATE TABLE t_complex_map_key_3 (k INT, v
MAP<STRUCT<a:INT>,INT>) DUPLICATE KEY(k) DISTRIBUTED BY HASH(k) BUCKETS 1
PROPERTIES('replication_num'='1')"
+ exception "MAP key type must be a primitive type"
+ }
+
// ---- valid deep nesting must still be accepted ----
sql """
@@ -73,5 +98,13 @@ suite("test_complex_disallowed_subtypes") {
PROPERTIES('replication_num'='1')
"""
+ sql """
+ CREATE TABLE t_complex_map_key_valid (k INT, v MAP<STRING, ARRAY<INT>>)
+ DUPLICATE KEY(k)
+ DISTRIBUTED BY HASH(k) BUCKETS 1
+ PROPERTIES('replication_num'='1')
+ """
+
sql "DROP TABLE IF EXISTS t_complex_valid"
+ sql "DROP TABLE IF EXISTS t_complex_map_key_valid"
}
diff --git
a/regression-test/suites/datatype_p0/nested_types/string_len/test_string_len_complex.groovy
b/regression-test/suites/datatype_p0/nested_types/string_len/test_string_len_complex.groovy
index 07b63914fa9..1e8ff5e4c46 100644
---
a/regression-test/suites/datatype_p0/nested_types/string_len/test_string_len_complex.groovy
+++
b/regression-test/suites/datatype_p0/nested_types/string_len/test_string_len_complex.groovy
@@ -200,42 +200,4 @@ suite("test_string_len_complex") {
}
qt_sql_map_all2 """ select * from test_string_len_map_one_level order by
id; """
- // test map two level
- def create_table_map_two_level = {
- sql """ DROP TABLE IF EXISTS test_string_len_map_two_level """
- sql """
- CREATE TABLE `test_string_len_map_two_level` (
- `id` int(11),
- `info` map<map<char(11), char(11)>, map<char(11), char(11)>>
- ) PROPERTIES ("replication_num" = "1");
- """
- }
-
- create_table_map_two_level()
- sql """
- set enable_insert_strict = false;
- set enable_strict_cast = false;
- """
- sql """
- insert into test_string_len_map_two_level values (1, {
{'01234567891':'12345678901'}:{'11234567891':'12345678901'},
{'01234567892':'12345678902'}:{'11234567892':'12345678902'} } ),
- (2, { {'01234567891':'22345678901'}:{'11234567891':'22345678901'},
{'01234567892':'22345678902'}:{'11234567892':'22345678902'} } ),
- (3, { {'01234567891':'32345678901'}:{'11234567891':'32345678901'},
{'01234567892':'32345678902x'}:{'11234567892':'32345678902x'} } );
- """
- qt_sql_map_all3 """ select * from test_string_len_map_two_level order by
id; """
-
- create_table_map_two_level()
- sql """
- set enable_insert_strict = true;
- set enable_strict_cast = true;
- """
- test {
- sql """
- insert into test_string_len_map_two_level values (1, {
{'01234567891':'12345678901'}:{'11234567891':'12345678901'},
{'01234567892':'12345678902'}:{'11234567892':'12345678902'} } ),
- (2, { {'01234567891':'22345678901'}:{'11234567891':'22345678901'},
{'01234567892':'22345678902'}:{'11234567892':'22345678902'} } ),
- (3, { {'01234567891':'32345678901'}:{'11234567891':'32345678901'},
{'01234567892':'32345678902x'}:{'11234567892':'32345678902x'} } );
- """
- exception "Insert has filtered data in strict mode"
- }
- qt_sql_map_all4 """ select * from test_string_len_map_two_level order by
id; """
-
}
\ No newline at end of file
diff --git
a/regression-test/suites/query_p0/show/test_nested_complex_switch.groovy
b/regression-test/suites/query_p0/show/test_nested_complex_switch.groovy
index 9b06a00eb42..e0175f3147a 100644
--- a/regression-test/suites/query_p0/show/test_nested_complex_switch.groovy
+++ b/regression-test/suites/query_p0/show/test_nested_complex_switch.groovy
@@ -35,19 +35,6 @@ suite("test_nested_complex_switch", "query") {
"storage_format" = "V2",
"disable_auto_compaction" = "false"
)"""
- def sql_m_a = """CREATE TABLE IF NOT EXISTS ${testTable_m} (
- `k1` INT(11) NULL,
- `k2` MAP<ARRAY<INT>, STRING>
- ) ENGINE=OLAP
- DUPLICATE KEY(`k1`)
- COMMENT 'OLAP'
- DISTRIBUTED BY HASH(`k1`) BUCKETS 1
- PROPERTIES (
- "replication_allocation" = "tag.location.default: 1",
- "in_memory" = "false",
- "storage_format" = "V2",
- "disable_auto_compaction" = "false"
- )"""
def sql_m_m = """CREATE TABLE IF NOT EXISTS ${testTable_m} (
`k1` INT(11) NULL,
@@ -145,10 +132,6 @@ suite("test_nested_complex_switch", "query") {
sql sql_m_s
}
- test {
- sql sql_m_a
- }
-
test {
sql sql_m_m
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]