This is an automated email from the ASF dual-hosted git repository.

morningman pushed a commit to branch dev-1.0.1
in repository https://gitbox.apache.org/repos/asf/incubator-doris.git

commit b86f290a7c4c94fcce1dd470b8167a019d763990
Author: HappenLee <[email protected]>
AuthorDate: Fri Apr 8 09:13:56 2022 +0800

    [fix] Disable cast operation of object type (#8882)
    
    Disable cast between string and object type(bitmap, hll, quantile_state)
---
 .../java/org/apache/doris/analysis/CastExpr.java   | 28 +++++++++++--------
 .../apache/doris/analysis/FunctionCallExpr.java    |  4 +--
 .../org/apache/doris/catalog/PrimitiveType.java    |  8 ------
 .../java/org/apache/doris/catalog/ScalarType.java  | 12 ++++++---
 .../main/java/org/apache/doris/catalog/Type.java   |  4 +++
 .../org/apache/doris/planner/QueryPlanTest.java    | 31 +++++++++++++---------
 .../doris/planner/TableFunctionPlanTest.java       |  4 +--
 7 files changed, 52 insertions(+), 39 deletions(-)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java
index 387cf1a77f..3bc9a19831 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java
@@ -134,23 +134,29 @@ public class CastExpr extends Expr {
         return targetTypeDef;
     }
 
+    private static boolean disableRegisterCastingFunction(Type fromType, Type 
toType) {
+        // Disable casting from boolean to decimal or datetime or date
+        if (fromType.isBoolean() &&
+                (toType.equals(Type.DECIMALV2) ||
+                        toType.equals(Type.DATETIME) || 
toType.equals(Type.DATE))) {
+            return true;
+        }
+
+        // Disable casting operation of hll/bitmap/quantile_state
+        if (fromType.isObjectStored() || toType.isObjectStored()) {
+            return true;
+        }
+        // Disable no-op casting
+        return fromType.equals(toType);
+    }
+
     public static void initBuiltins(FunctionSet functionSet) {
         for (Type fromType : Type.getSupportedTypes()) {
             if (fromType.isNull()) {
                 continue;
             }
             for (Type toType : Type.getSupportedTypes()) {
-                if (toType.isNull()) {
-                    continue;
-                }
-                // Disable casting from boolean to decimal or datetime or date
-                if (fromType.isBoolean() &&
-                        (toType.equals(Type.DECIMALV2) ||
-                                toType.equals(Type.DATETIME) || 
toType.equals(Type.DATE))) {
-                    continue;
-                }
-                // Disable no-op casts
-                if (fromType.equals(toType)) {
+                if (toType.isNull() || 
disableRegisterCastingFunction(fromType, toType)) {
                     continue;
                 }
                 String beClass = toType.isDecimalV2() || 
fromType.isDecimalV2() ? "DecimalV2Operators" : "CastFunctions";
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
index a023da2e6c..bc30b9d5f9 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
@@ -89,8 +89,6 @@ public class FunctionCallExpr extends Expr {
 
     private boolean isRewrote = false;
 
-    public static final String UNKNOWN_TABLE_FUNCTION_MSG = "This table 
function not supported now";
-
     public void setIsAnalyticFnCall(boolean v) {
         isAnalyticFnCall = v;
     }
@@ -808,7 +806,7 @@ public class FunctionCallExpr extends Expr {
                 fn = getTableFunction(fnName.getFunction(), childTypes,
                         Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
                 if (fn == null) {
-                    throw new AnalysisException(UNKNOWN_TABLE_FUNCTION_MSG);
+                    throw new 
AnalysisException(getFunctionNotFoundError(argTypes));
                 }
             } else {
                 // now first find function in built-in functions
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/PrimitiveType.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/PrimitiveType.java
index 7def685b5a..d5f65908a9 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/PrimitiveType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/PrimitiveType.java
@@ -247,8 +247,6 @@ public enum PrimitiveType {
         builder.put(VARCHAR, DECIMALV2);
         builder.put(VARCHAR, VARCHAR);
         builder.put(VARCHAR, STRING);
-        builder.put(VARCHAR, HLL);
-        builder.put(VARCHAR, BITMAP);
 
         // Varchar
         builder.put(STRING, BOOLEAN);
@@ -264,8 +262,6 @@ public enum PrimitiveType {
         builder.put(STRING, DECIMALV2);
         builder.put(STRING, VARCHAR);
         builder.put(STRING, STRING);
-        builder.put(STRING, HLL);
-        builder.put(STRING, BITMAP);
 
         // DecimalV2
         builder.put(DECIMALV2, BOOLEAN);
@@ -282,13 +278,9 @@ public enum PrimitiveType {
 
         // HLL
         builder.put(HLL, HLL);
-        builder.put(HLL, VARCHAR);
-        builder.put(HLL, STRING);
 
         // BITMAP
         builder.put(BITMAP, BITMAP);
-        builder.put(BITMAP, VARCHAR);
-        builder.put(BITMAP, STRING);
 
         //TIME
         builder.put(TIME, TIME);
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/ScalarType.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/ScalarType.java
index 714e067699..6809a99eea 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/ScalarType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/ScalarType.java
@@ -541,9 +541,6 @@ public class ScalarType extends Type {
         if (type == PrimitiveType.VARCHAR && scalarType.isStringType()) {
             return true;
         }
-        if (type == PrimitiveType.HLL && scalarType.isStringType()) {
-            return true;
-        }
         if (isDecimalV2() && scalarType.isWildcardDecimal()) {
             Preconditions.checkState(!isWildcardDecimal());
             return true;
@@ -677,6 +674,15 @@ public class ScalarType extends Type {
             return INVALID;
         }
 
+        boolean t1IsBitMap = t1.type == PrimitiveType.BITMAP;
+        boolean t2IsBitMap = t2.type == PrimitiveType.BITMAP;
+        if (t1IsBitMap || t2IsBitMap) {
+            if (t1IsBitMap && t2IsBitMap) {
+                return BITMAP;
+            }
+            return INVALID;
+        }
+
         // for cast all type
         if (t1.type == PrimitiveType.ALL || t2.type == PrimitiveType.ALL) {
             return Type.ALL;
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Type.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Type.java
index efee561e00..438d2d1828 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Type.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Type.java
@@ -209,6 +209,10 @@ public abstract class Type {
         return isScalarType(PrimitiveType.BITMAP);
     }
 
+    public boolean isObjectStored() {
+        return isHllType() || isBitmapType();
+    }
+
     public boolean isScalarType() {
         return this instanceof ScalarType;
     }
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 bfaec003ad..20a5c7c704 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
@@ -476,18 +476,6 @@ public class QueryPlanTest {
         Assert.assertTrue(explainString.contains("OUTPUT EXPRS:`id` | `id2`"));
         Assert.assertTrue(explainString.contains("0:OlapScanNode"));
 
-        queryStr = "explain insert into test.bitmap_table select id, 
to_bitmap(id2) from test.bitmap_table_2;";
-        explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, 
queryStr);
-        Assert.assertTrue(explainString.contains("OLAP TABLE SINK"));
-        Assert.assertTrue(explainString.contains("OUTPUT EXPRS:`id` | 
to_bitmap(CAST(`id2` AS CHARACTER))"));
-        Assert.assertTrue(explainString.contains("0:OlapScanNode"));
-
-        queryStr = "explain insert into test.bitmap_table select id, 
bitmap_hash(id2) from test.bitmap_table_2;";
-        explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, 
queryStr);
-        Assert.assertTrue(explainString.contains("OLAP TABLE SINK"));
-        Assert.assertTrue(explainString.contains("OUTPUT EXPRS:`id` | 
bitmap_hash(CAST(`id2` AS CHARACTER))"));
-        Assert.assertTrue(explainString.contains("0:OlapScanNode"));
-
         queryStr = "explain insert into test.bitmap_table select id, id from 
test.bitmap_table_2;";
         String errorMsg = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, 
queryStr);
         Assert.assertTrue(errorMsg.contains("bitmap column require the 
function return type is BITMAP"));
@@ -615,6 +603,25 @@ public class QueryPlanTest {
         sql = "SHOW VARIABLES LIKE 'lower_case_%'; SHOW VARIABLES LIKE 
'sql_mode'";
         List<StatementBase> stmts = UtFrameUtils.parseAndAnalyzeStmts(sql, 
connectContext);
         Assert.assertEquals(2, stmts.size());
+
+        // disable cast hll/bitmap to string
+        testHLLQueryPlan(
+                "select cast(id2 as varchar) from test.hll_table;",
+                "Invalid type cast of `id2` from HLL to VARCHAR(*)"
+        );
+        testBitmapQueryPlan(
+                "select cast(id2 as varchar) from test.bitmap_table;",
+                "Invalid type cast of `id2` from BITMAP to VARCHAR(*)"
+        );
+        // disable implicit cast hll/bitmap to string
+        testHLLQueryPlan(
+                "select length(id2) from test.hll_table;",
+                "No matching function with signature: length(hll)"
+        );
+        testBitmapQueryPlan(
+                "select length(id2) from test.bitmap_table;",
+                "No matching function with signature: length(bitmap)"
+        );
     }
 
     @Test
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/planner/TableFunctionPlanTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/planner/TableFunctionPlanTest.java
index 58e4c9de86..15d84f7f39 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/planner/TableFunctionPlanTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/planner/TableFunctionPlanTest.java
@@ -184,11 +184,11 @@ public class TableFunctionPlanTest {
     public void errorParam() throws Exception {
         String sql = "explain select k1, e1 from db1.tbl1 lateral view 
explode_split(k2) tmp as e1;";
         String explainString = UtFrameUtils.getSQLPlanOrErrorMsg(ctx, sql);
-        
Assert.assertTrue(explainString.contains(FunctionCallExpr.UNKNOWN_TABLE_FUNCTION_MSG));
+        Assert.assertTrue(explainString.contains("No matching function with 
signature: explode_split(varchar(1))"));
 
         sql = "explain select k1, e1 from db1.tbl1 lateral view 
explode_split(k1) tmp as e1;";
         explainString = UtFrameUtils.getSQLPlanOrErrorMsg(ctx, sql);
-        
Assert.assertTrue(explainString.contains(FunctionCallExpr.UNKNOWN_TABLE_FUNCTION_MSG));
+        Assert.assertTrue(explainString.contains("No matching function with 
signature: explode_split(int(11))"));
     }
 
     /* Case2 table function in where stmt


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to