This is an automated email from the ASF dual-hosted git repository.
starocean999 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new d80ead89ae1 [fix](fe) Reject JSONB and variant distribution columns
(#63211)
d80ead89ae1 is described below
commit d80ead89ae19a167dc7ad329389bb35abacc6801
Author: Calvin Kirs <[email protected]>
AuthorDate: Fri May 15 15:58:21 2026 +0800
[fix](fe) Reject JSONB and variant distribution columns (#63211)
Problem Summary: Hash distribution column validation missed JSONB and
VARIANT columns, allowing CREATE TABLE statements such as DISTRIBUTED BY
HASH(jsonb_col) even though those types are rejected in key and
partition paths. This change centralizes hash distribution type
validation and reuses it from both catalog and Nereids create-table
paths.
### Release note
Reject JSONB and VARIANT columns as hash distribution columns during
CREATE TABLE analysis.
---
.../doris/analysis/HashDistributionDesc.java | 14 +------
.../apache/doris/catalog/HashDistributionInfo.java | 23 +++++++++++
.../commands/info/DistributionDescriptorTest.java | 48 ++++++++++++++++++++++
.../jsonb_p0/test_jsonb_distribution_column.groovy | 46 +++++++++++++++++++++
.../suites/variant_p0/doc_mode/load.groovy | 2 +-
regression-test/suites/variant_p0/load.groovy | 2 +-
6 files changed, 120 insertions(+), 15 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/analysis/HashDistributionDesc.java
b/fe/fe-core/src/main/java/org/apache/doris/analysis/HashDistributionDesc.java
index 754f036d79f..4509a71440c 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/analysis/HashDistributionDesc.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/analysis/HashDistributionDesc.java
@@ -112,19 +112,7 @@ public class HashDistributionDesc extends DistributionDesc
{
boolean find = false;
for (Column column : columns) {
if (column.getName().equalsIgnoreCase(colName)) {
- if (column.getType().isArrayType()) {
- throw new DdlException("Array Type should not be used
in distribution column["
- + column.getName() + "].");
- } else if (column.getType().isMapType()) {
- throw new DdlException("Map Type should not be used in
distribution column["
- + column.getName() + "].");
- } else if (column.getType().isStructType()) {
- throw new DdlException("Struct Type should not be used
in distribution column["
- + column.getName() + "].");
- } else if (column.getType().isFloatingPointType()) {
- throw new DdlException("Floating point type should not
be used in distribution column["
- + column.getName() + "].");
- }
+
HashDistributionInfo.checkDistributionColumnType(column.getName(),
column.getType());
// distribution info and base columns persist seperately
inside OlapTable, so we need deep copy
// to avoid modify table columns also modify columns
inside distribution info.
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/catalog/HashDistributionInfo.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/HashDistributionInfo.java
index 98ea3acb677..a1f4688cb66 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/catalog/HashDistributionInfo.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/catalog/HashDistributionInfo.java
@@ -19,6 +19,7 @@ package org.apache.doris.catalog;
import org.apache.doris.analysis.DistributionDesc;
import org.apache.doris.analysis.HashDistributionDesc;
+import org.apache.doris.common.DdlException;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
@@ -54,6 +55,28 @@ public class HashDistributionInfo extends DistributionInfo {
return distributionColumns;
}
+ public static void checkDistributionColumnType(String columnName, Type
type) throws DdlException {
+ if (type.isArrayType()) {
+ throw new DdlException("Array Type should not be used in
distribution column[" + columnName + "].");
+ }
+ if (type.isMapType()) {
+ throw new DdlException("Map Type should not be used in
distribution column[" + columnName + "].");
+ }
+ if (type.isStructType()) {
+ throw new DdlException("Struct Type should not be used in
distribution column[" + columnName + "].");
+ }
+ if (type.isJsonbType()) {
+ throw new DdlException("JsonType type should not be used in
distribution column[" + columnName + "].");
+ }
+ if (type.isVariantType()) {
+ throw new DdlException("Variant type should not be used in
distribution column[" + columnName + "].");
+ }
+ if (type.isFloatingPointType()) {
+ throw new DdlException("Floating point type should not be used in
distribution column["
+ + columnName + "].");
+ }
+ }
+
public boolean sameDistributionColumns(HashDistributionInfo other) {
if (distributionColumns.size() != other.distributionColumns.size()) {
return false;
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/info/DistributionDescriptorTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/info/DistributionDescriptorTest.java
index c80b9c4258e..f4c29f4cc91 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/info/DistributionDescriptorTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/info/DistributionDescriptorTest.java
@@ -17,10 +17,16 @@
package org.apache.doris.nereids.trees.plans.commands.info;
+import org.apache.doris.analysis.HashDistributionDesc;
+import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.KeysType;
+import org.apache.doris.catalog.Type;
import org.apache.doris.common.Config;
+import org.apache.doris.common.DdlException;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.types.IntegerType;
+import org.apache.doris.nereids.types.JsonType;
+import org.apache.doris.nereids.types.VariantType;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@@ -113,4 +119,46 @@ public class DistributionDescriptorTest {
() -> desc3.validate(columnMap, KeysType.DUP_KEYS));
Assertions.assertTrue(ex3.getMessage().contains("greater than zero"));
}
+
+ @Test
+ public void testRejectJsonAndVariantTranslatedDistributionColumns() {
+ Map<String, ColumnDefinition> columnMap = Maps.newHashMap();
+ columnMap.put("json_col", new ColumnDefinition("json_col",
JsonType.INSTANCE, false));
+ columnMap.put("variant_col", new ColumnDefinition("variant_col",
VariantType.INSTANCE, false));
+
+ DistributionDescriptor jsonDesc = new DistributionDescriptor(
+ true, false, 1, Lists.newArrayList("json_col"));
+ jsonDesc.validate(columnMap, KeysType.DUP_KEYS);
+ DdlException jsonException =
Assertions.assertThrows(DdlException.class,
+ () -> jsonDesc.translateToCatalogStyle()
+ .toDistributionInfo(Lists.newArrayList(new
Column("json_col", Type.JSONB))));
+ Assertions.assertEquals("JsonType type should not be used in
distribution column[json_col].",
+ jsonException.getDetailMessage());
+
+ DistributionDescriptor variantDesc = new DistributionDescriptor(
+ true, false, 1, Lists.newArrayList("variant_col"));
+ variantDesc.validate(columnMap, KeysType.DUP_KEYS);
+ DdlException variantException =
Assertions.assertThrows(DdlException.class,
+ () -> variantDesc.translateToCatalogStyle()
+ .toDistributionInfo(Lists.newArrayList(new
Column("variant_col", Type.VARIANT))));
+ Assertions.assertEquals("Variant type should not be used in
distribution column[variant_col].",
+ variantException.getDetailMessage());
+ }
+
+ @Test
+ public void testRejectJsonAndVariantCatalogDistributionColumns() {
+ Column jsonColumn = new Column("json_col", Type.JSONB);
+ HashDistributionDesc jsonDesc = new HashDistributionDesc(1,
Lists.newArrayList("json_col"));
+ DdlException jsonException =
Assertions.assertThrows(DdlException.class,
+ () ->
jsonDesc.toDistributionInfo(Lists.newArrayList(jsonColumn)));
+ Assertions.assertEquals("JsonType type should not be used in
distribution column[json_col].",
+ jsonException.getDetailMessage());
+
+ Column variantColumn = new Column("variant_col", Type.VARIANT);
+ HashDistributionDesc variantDesc = new HashDistributionDesc(1,
Lists.newArrayList("variant_col"));
+ DdlException variantException =
Assertions.assertThrows(DdlException.class,
+ () ->
variantDesc.toDistributionInfo(Lists.newArrayList(variantColumn)));
+ Assertions.assertEquals("Variant type should not be used in
distribution column[variant_col].",
+ variantException.getDetailMessage());
+ }
}
diff --git
a/regression-test/suites/jsonb_p0/test_jsonb_distribution_column.groovy
b/regression-test/suites/jsonb_p0/test_jsonb_distribution_column.groovy
new file mode 100644
index 00000000000..e26616e0d40
--- /dev/null
+++ b/regression-test/suites/jsonb_p0/test_jsonb_distribution_column.groovy
@@ -0,0 +1,46 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+suite("test_jsonb_distribution_column", "p0") {
+ sql "DROP TABLE IF EXISTS test_jsonb_distribution_column"
+ test {
+ sql """
+ CREATE TABLE test_jsonb_distribution_column (
+ k INT,
+ c JSONB
+ )
+ DUPLICATE KEY(k)
+ DISTRIBUTED BY HASH(c) BUCKETS 4
+ PROPERTIES("replication_num" = "1")
+ """
+ exception "JsonType type should not be used in distribution column[c]."
+ }
+
+ sql "DROP TABLE IF EXISTS test_variant_distribution_column"
+ test {
+ sql """
+ CREATE TABLE test_variant_distribution_column (
+ k INT,
+ v VARIANT<PROPERTIES("variant_max_subcolumns_count" = "0")>
+ )
+ DUPLICATE KEY(k)
+ DISTRIBUTED BY HASH(v) BUCKETS 4
+ PROPERTIES("replication_num" = "1")
+ """
+ exception "Variant type should not be used in distribution column[v]."
+ }
+}
diff --git a/regression-test/suites/variant_p0/doc_mode/load.groovy
b/regression-test/suites/variant_p0/doc_mode/load.groovy
index 896d2eeccb1..11ab4b8108f 100644
--- a/regression-test/suites/variant_p0/doc_mode/load.groovy
+++ b/regression-test/suites/variant_p0/doc_mode/load.groovy
@@ -412,7 +412,7 @@ suite("regression_test_variant_doc_value", "p0"){
"replication_allocation" = "tag.location.default: 1"
);
"""
- exception("errCode = 2, detailMessage = Hash distribution info
should not contain variant columns")
+ exception("errCode = 2, detailMessage = Variant type should not be
used in distribution column[content].")
}
test {
diff --git a/regression-test/suites/variant_p0/load.groovy
b/regression-test/suites/variant_p0/load.groovy
index c2642bdab2e..f7b7370a52b 100644
--- a/regression-test/suites/variant_p0/load.groovy
+++ b/regression-test/suites/variant_p0/load.groovy
@@ -410,7 +410,7 @@ suite("regression_test_variant", "p0"){
"replication_allocation" = "tag.location.default: 1"
);
"""
- exception("errCode = 2, detailMessage = Hash distribution info
should not contain variant columns")
+ exception("errCode = 2, detailMessage = Variant type should not be
used in distribution column[content].")
}
test {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]