From 00e8d1c3b45c4d592243a54d70c19d673b82fff9 Mon Sep 17 00:00:00 2001 From: LiBinfeng <46676950+LiBinfeng-01@users.noreply.github.com> Date: Wed, 27 Sep 2023 16:57:06 +0800 Subject: [PATCH] [Fix](Planner) disable bitmap type in compare expression (#24792) Problem: be core because of bitmap calculation. Reason: when be check failed, it would core directly. Example: SELECT id_bitmap FROM test_bitmap WHERE id_bitmap IN (NULL) LIMIT 20; Solved: Forbidden this kind of expression in fe when analyze. And also forbid bitmap type comparing in other unsupported expressions. --- .../doris/analysis/BinaryPredicate.java | 2 +- .../org/apache/doris/analysis/CaseExpr.java | 6 ++++ .../java/org/apache/doris/analysis/Expr.java | 11 ++++++ .../apache/doris/analysis/InPredicate.java | 1 + .../apache/doris/planner/QueryPlanTest.java | 2 +- .../datatype_p0/bitmap/test_bitmap_int.out | Bin 315 -> 350 bytes .../datatype_p0/bitmap/test_bitmap_int.groovy | 33 ++++++++++++++++++ 7 files changed, 53 insertions(+), 2 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/BinaryPredicate.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/BinaryPredicate.java index dd9253109e..f892b850bb 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/BinaryPredicate.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/BinaryPredicate.java @@ -474,7 +474,7 @@ public class BinaryPredicate extends Predicate implements Writable { @Override public void analyzeImpl(Analyzer analyzer) throws AnalysisException { super.analyzeImpl(analyzer); - + this.checkIncludeBitmap(); // Ignore placeholder if (getChild(0) instanceof PlaceHolderExpr || getChild(1) instanceof PlaceHolderExpr) { return; diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CaseExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CaseExpr.java index 548ceb1f62..3d3070ec3c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CaseExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CaseExpr.java @@ -192,6 +192,9 @@ public class CaseExpr extends Expr { if (caseExpr instanceof Subquery && !caseExpr.getType().isScalarType()) { throw new AnalysisException("Subquery in case-when must return scala type"); } + if (caseExpr.getType().isBitmapType()) { + throw new AnalysisException("Unsupported bitmap type in expression: " + toSql()); + } whenType = caseExpr.getType(); lastCompatibleWhenExpr = children.get(0); } else { @@ -226,6 +229,9 @@ public class CaseExpr extends Expr { && !((hasCaseExpr() && whenExpr instanceof Subquery || !checkSubquery(whenExpr)))) { throw new AnalysisException("Only support subquery in binary predicate in case statement."); } + if (whenExpr.getType().isBitmapType()) { + throw new AnalysisException("Unsupported bitmap type in expression: " + toSql()); + } // Determine maximum compatible type of the then exprs seen so far. // We will add casts to them at the very end. Expr thenExpr = children.get(i + 1); diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java index b4d550175f..c167fdaa42 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java @@ -1419,6 +1419,17 @@ public abstract class Expr extends TreeNode implements ParseNode, Cloneabl } } + /** + * Checks whether comparing predicates' children include bitmap type. + */ + public void checkIncludeBitmap() throws AnalysisException { + for (int i = 0; i < children.size(); ++i) { + if (children.get(i).getType().isBitmapType()) { + throw new AnalysisException("Unsupported bitmap type in expression: " + toSql()); + } + } + } + public Expr checkTypeCompatibility(Type targetType) throws AnalysisException { if (!targetType.isComplexType() && !targetType.isAggStateType() && targetType.getPrimitiveType() == type.getPrimitiveType()) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/InPredicate.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/InPredicate.java index dcc8c694b5..c110b2e6ea 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/InPredicate.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/InPredicate.java @@ -170,6 +170,7 @@ public class InPredicate extends Predicate { @Override public void analyzeImpl(Analyzer analyzer) throws AnalysisException { super.analyzeImpl(analyzer); + this.checkIncludeBitmap(); if (contains(Subquery.class)) { // An [NOT] IN predicate with a subquery must contain two children, the second diff --git a/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java b/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java index 8bdfb2a1c7..2c0e29b9b6 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java @@ -492,7 +492,7 @@ public class QueryPlanTest extends TestWithFeService { assertSQLPlanOrErrorMsgContains( "select count(*) from test.bitmap_table where id2 = 1;", - "Bitmap type dose not support operand: `id2` = 1" + "Unsupported bitmap type in expression: `id2` = 1" ); } diff --git a/regression-test/data/datatype_p0/bitmap/test_bitmap_int.out b/regression-test/data/datatype_p0/bitmap/test_bitmap_int.out index d8101b77068672f4b423d97ab981a2445383c5f1..3ff7233cef75a5967010703add45a477054e6a8d 100644 GIT binary patch delta 43 ocmdnZbdPC+HKVewu7YB5VUC$eyorLYE*BSqZwlha_;GOo0Q@uxP5=M^ delta 7 Ocmcb|w3}&zH6s8FTLOvz diff --git a/regression-test/suites/datatype_p0/bitmap/test_bitmap_int.groovy b/regression-test/suites/datatype_p0/bitmap/test_bitmap_int.groovy index 8dccfd3b9b..0b0d577d19 100644 --- a/regression-test/suites/datatype_p0/bitmap/test_bitmap_int.groovy +++ b/regression-test/suites/datatype_p0/bitmap/test_bitmap_int.groovy @@ -44,6 +44,39 @@ suite("test_bitmap_int") { sql "DROP TABLE test_int_bitmap" + sql "DROP TABLE IF EXISTS test_bitmap" + sql """CREATE TABLE + `test_bitmap` ( + `id` varchar(16) NOT NULL, + `id_bitmap` bitmap BITMAP_UNION NOT NULL + ) DISTRIBUTED BY HASH (`id`) BUCKETS 1 PROPERTIES ("replication_num" = "1");""" + + test { + sql """SELECT id_bitmap FROM test_bitmap WHERE (id_bitmap NOT IN (NULL) OR (1 = 1)) AND id_bitmap IS NOT NULL LIMIT 20;""" + exception "errCode" + } + + test { + sql """SELECT id_bitmap FROM test_bitmap WHERE id_bitmap IN (NULL) LIMIT 20;""" + exception "errCode" + } + + test { + sql """SELECT id_bitmap FROM test_bitmap WHERE id_bitmap = 1 LIMIT 20;""" + exception "errCode" + } + + test { + sql """SELECT case id_bitmap when 1 then 1 else 0 FROM test_bitmap;""" + exception "errCode" + } + + qt_sql64_4 """SELECT id_bitmap FROM test_bitmap WHERE id_bitmap is null LIMIT 20;""" + + qt_sql64_5 """select case when 1 = 0 then bitmap_from_string('0') else bitmap_from_string('0') end as new_bitmap;""" + + sql "DROP TABLE IF EXISTS test_bitmap" + }