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

xuyang 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 ea41d94582 [Improve](complex-type) Support Count(complexType) (#17868)
ea41d94582 is described below

commit ea41d945827dd015b8606ffc5697a9a9a184ea53
Author: amory <[email protected]>
AuthorDate: Thu Mar 30 15:43:32 2023 +0800

    [Improve](complex-type) Support Count(complexType) (#17868)
    
    Support count function for ARRAY/MAP/STRUCT type
---
 .../vec/functions/array/function_array_element.h   | 121 ++++++++++-----------
 .../java/org/apache/doris/catalog/StructType.java  |   9 +-
 .../main/java/org/apache/doris/catalog/Type.java   |   2 +
 .../apache/doris/analysis/FunctionCallExpr.java    |   2 +-
 .../org/apache/doris/analysis/IsNullPredicate.java |  10 +-
 .../java/org/apache/doris/catalog/FunctionSet.java |  21 ++++
 .../IsNullPredicateWithComplexTypeTest.java        |  18 ++-
 regression-test/data/export/test_map_export.out    |   4 +
 .../load/insert/test_array_insert_into_select.out  |   6 +
 .../data/load/insert/test_array_string_insert.out  |   3 +
 .../data/load/insert/test_insert_nested_array.out  |   6 +
 regression-test/data/load/insert/test_map_dml.out  |   7 ++
 .../data/load_p0/broker_load/test_array_load.out   |  18 +++
 .../stream_load/test_map_load_and_compaction.out   |   3 +
 .../stream_load/test_map_load_and_function.out     |   7 +-
 .../data/query_p0/show/test_map_show_create.out    |   3 +
 .../data/query_p0/show/test_struct_show_create.out |   3 +
 .../suites/export/test_map_export.groovy           |   1 +
 .../insert/test_array_insert_into_select.groovy    |   2 +
 .../load/insert/test_array_string_insert.groovy    |   1 +
 .../load/insert/test_insert_nested_array.groovy    |   2 +
 .../suites/load/insert/test_map_dml.groovy         |   2 +
 .../load_p0/broker_load/test_array_load.groovy     |   3 +-
 .../test_map_load_and_compaction.groovy            |   1 +
 .../stream_load/test_map_load_and_function.groovy  |   1 +
 .../query_p0/show/test_map_show_create.groovy      |   1 +
 .../query_p0/show/test_struct_show_create.groovy   |   2 +-
 27 files changed, 174 insertions(+), 85 deletions(-)

diff --git a/be/src/vec/functions/array/function_array_element.h 
b/be/src/vec/functions/array/function_array_element.h
index 094802f886..9b84a274a9 100644
--- a/be/src/vec/functions/array/function_array_element.h
+++ b/be/src/vec/functions/array/function_array_element.h
@@ -43,20 +43,24 @@ public:
 
     bool is_variadic() const override { return false; }
 
+    bool use_default_implementation_for_nulls() const override { return false; 
}
+
     size_t get_number_of_arguments() const override { return 2; }
 
     DataTypePtr get_return_type_impl(const DataTypes& arguments) const 
override {
-        DCHECK(is_array(arguments[0]) || is_map(arguments[0]))
+        DataTypePtr arg_0 = remove_nullable(arguments[0]);
+        DCHECK(is_array(arg_0) || is_map(arg_0))
                 << "first argument for function: " << name
-                << " should be DataTypeArray or DataTypeMap";
-        if (is_array(arguments[0])) {
-            DCHECK(is_integer(arguments[1])) << "second argument for function: 
" << name
-                                             << " should be Integer for array 
element";
+                << " should be DataTypeArray or DataTypeMap, but it is " << 
arg_0->get_name();
+        if (is_array(arg_0)) {
+            DCHECK(is_integer(remove_nullable(arguments[1])))
+                    << "second argument for function: " << name
+                    << " should be Integer for array element";
             return make_nullable(
-                    
check_and_get_data_type<DataTypeArray>(arguments[0].get())->get_nested_type());
-        } else if (is_map(arguments[0])) {
+                    
check_and_get_data_type<DataTypeArray>(arg_0.get())->get_nested_type());
+        } else if (is_map(arg_0)) {
             return make_nullable(
-                    
check_and_get_data_type<DataTypeMap>(arguments[0].get())->get_value_type());
+                    
check_and_get_data_type<DataTypeMap>(arg_0.get())->get_value_type());
         } else {
             LOG(ERROR) << "element_at only support array and map so far.";
             return nullptr;
@@ -83,7 +87,7 @@ public:
         if (args[0].column->is_column_map()) {
             res_column = _execute_map(args, input_rows_count, src_null_map, 
dst_null_map);
         } else {
-            res_column = _execute_non_nullable(args, input_rows_count, 
src_null_map, dst_null_map);
+            res_column = _execute_nullable(args, input_rows_count, 
src_null_map, dst_null_map);
         }
         if (!res_column) {
             return Status::RuntimeError("unsupported types for function {}({}, 
{})", get_name(),
@@ -98,15 +102,9 @@ public:
 private:
     //=========================== map element===========================//
     ColumnPtr _get_mapped_idx(const ColumnArray& column, const 
ColumnWithTypeAndName& argument) {
-        auto right_column = argument.column->convert_to_full_column_if_const();
+        auto right_column = 
make_nullable(argument.column->convert_to_full_column_if_const());
         const ColumnArray::Offsets64& offsets = column.get_offsets();
-        ColumnPtr nested_ptr = nullptr;
-        if (is_column_nullable(column.get_data())) {
-            nested_ptr = reinterpret_cast<const 
ColumnNullable&>(column.get_data())
-                                 .get_nested_column_ptr();
-        } else {
-            nested_ptr = column.get_data_ptr();
-        }
+        ColumnPtr nested_ptr = make_nullable(column.get_data_ptr());
         size_t rows = offsets.size();
         // prepare return data
         auto matched_indices = ColumnVector<Int8>::create();
@@ -245,7 +243,8 @@ private:
         if (rows <= 0) {
             return nullptr;
         }
-
+        if (key_arr->is_nullable()) {
+        }
         ColumnPtr matched_indices = _get_mapped_idx(*key_arr, arguments[1]);
         if (!matched_indices) {
             return nullptr;
@@ -254,12 +253,11 @@ private:
         ColumnWithTypeAndName indices(matched_indices, indices_type, 
"indices");
         ColumnWithTypeAndName data(val_arr, val_type, "value");
         ColumnsWithTypeAndName args = {data, indices};
-        return _execute_non_nullable(args, input_rows_count, src_null_map, 
dst_null_map);
+        return _execute_nullable(args, input_rows_count, src_null_map, 
dst_null_map);
     }
 
-    ColumnPtr _execute_non_nullable(const ColumnsWithTypeAndName& arguments,
-                                    size_t input_rows_count, const UInt8* 
src_null_map,
-                                    UInt8* dst_null_map) {
+    ColumnPtr _execute_nullable(const ColumnsWithTypeAndName& arguments, 
size_t input_rows_count,
+                                const UInt8* src_null_map, UInt8* 
dst_null_map) {
         // check array nested column type and get data
         auto left_column = 
arguments[0].column->convert_to_full_column_if_const();
         const auto& array_column = reinterpret_cast<const 
ColumnArray&>(*left_column);
@@ -277,67 +275,60 @@ private:
         }
 
         ColumnPtr res = nullptr;
+        // because we impl use_default_implementation_for_nulls
+        // we should handle array index column by-self, and array index should 
not be nullable.
+        auto idx_col = remove_nullable(arguments[1].column);
         if (nested_column->is_date_type()) {
-            res = _execute_number<ColumnDate>(offsets, *nested_column, 
src_null_map,
-                                              *arguments[1].column, 
nested_null_map, dst_null_map);
+            res = _execute_number<ColumnDate>(offsets, *nested_column, 
src_null_map, *idx_col,
+                                              nested_null_map, dst_null_map);
         } else if (nested_column->is_datetime_type()) {
-            res = _execute_number<ColumnDateTime>(offsets, *nested_column, 
src_null_map,
-                                                  *arguments[1].column, 
nested_null_map,
-                                                  dst_null_map);
+            res = _execute_number<ColumnDateTime>(offsets, *nested_column, 
src_null_map, *idx_col,
+                                                  nested_null_map, 
dst_null_map);
         } else if (check_column<ColumnDateV2>(nested_column)) {
-            res = _execute_number<ColumnDateV2>(offsets, *nested_column, 
src_null_map,
-                                                *arguments[1].column, 
nested_null_map,
-                                                dst_null_map);
+            res = _execute_number<ColumnDateV2>(offsets, *nested_column, 
src_null_map, *idx_col,
+                                                nested_null_map, dst_null_map);
         } else if (check_column<ColumnDateTimeV2>(nested_column)) {
-            res = _execute_number<ColumnDateTime>(offsets, *nested_column, 
src_null_map,
-                                                  *arguments[1].column, 
nested_null_map,
-                                                  dst_null_map);
+            res = _execute_number<ColumnDateTime>(offsets, *nested_column, 
src_null_map, *idx_col,
+                                                  nested_null_map, 
dst_null_map);
         } else if (check_column<ColumnUInt8>(*nested_column)) {
-            res = _execute_number<ColumnUInt8>(offsets, *nested_column, 
src_null_map,
-                                               *arguments[1].column, 
nested_null_map, dst_null_map);
+            res = _execute_number<ColumnUInt8>(offsets, *nested_column, 
src_null_map, *idx_col,
+                                               nested_null_map, dst_null_map);
         } else if (check_column<ColumnInt8>(*nested_column)) {
-            res = _execute_number<ColumnInt8>(offsets, *nested_column, 
src_null_map,
-                                              *arguments[1].column, 
nested_null_map, dst_null_map);
+            res = _execute_number<ColumnInt8>(offsets, *nested_column, 
src_null_map, *idx_col,
+                                              nested_null_map, dst_null_map);
         } else if (check_column<ColumnInt16>(*nested_column)) {
-            res = _execute_number<ColumnInt16>(offsets, *nested_column, 
src_null_map,
-                                               *arguments[1].column, 
nested_null_map, dst_null_map);
+            res = _execute_number<ColumnInt16>(offsets, *nested_column, 
src_null_map, *idx_col,
+                                               nested_null_map, dst_null_map);
         } else if (check_column<ColumnInt32>(*nested_column)) {
-            res = _execute_number<ColumnInt32>(offsets, *nested_column, 
src_null_map,
-                                               *arguments[1].column, 
nested_null_map, dst_null_map);
+            res = _execute_number<ColumnInt32>(offsets, *nested_column, 
src_null_map, *idx_col,
+                                               nested_null_map, dst_null_map);
         } else if (check_column<ColumnInt64>(*nested_column)) {
-            res = _execute_number<ColumnInt64>(offsets, *nested_column, 
src_null_map,
-                                               *arguments[1].column, 
nested_null_map, dst_null_map);
+            res = _execute_number<ColumnInt64>(offsets, *nested_column, 
src_null_map, *idx_col,
+                                               nested_null_map, dst_null_map);
         } else if (check_column<ColumnInt128>(*nested_column)) {
-            res = _execute_number<ColumnInt128>(offsets, *nested_column, 
src_null_map,
-                                                *arguments[1].column, 
nested_null_map,
-                                                dst_null_map);
+            res = _execute_number<ColumnInt128>(offsets, *nested_column, 
src_null_map, *idx_col,
+                                                nested_null_map, dst_null_map);
         } else if (check_column<ColumnFloat32>(*nested_column)) {
-            res = _execute_number<ColumnFloat32>(offsets, *nested_column, 
src_null_map,
-                                                 *arguments[1].column, 
nested_null_map,
-                                                 dst_null_map);
+            res = _execute_number<ColumnFloat32>(offsets, *nested_column, 
src_null_map, *idx_col,
+                                                 nested_null_map, 
dst_null_map);
         } else if (check_column<ColumnFloat64>(*nested_column)) {
-            res = _execute_number<ColumnFloat64>(offsets, *nested_column, 
src_null_map,
-                                                 *arguments[1].column, 
nested_null_map,
-                                                 dst_null_map);
+            res = _execute_number<ColumnFloat64>(offsets, *nested_column, 
src_null_map, *idx_col,
+                                                 nested_null_map, 
dst_null_map);
         } else if (check_column<ColumnDecimal32>(*nested_column)) {
-            res = _execute_number<ColumnDecimal32>(offsets, *nested_column, 
src_null_map,
-                                                   *arguments[1].column, 
nested_null_map,
-                                                   dst_null_map);
+            res = _execute_number<ColumnDecimal32>(offsets, *nested_column, 
src_null_map, *idx_col,
+                                                   nested_null_map, 
dst_null_map);
         } else if (check_column<ColumnDecimal64>(*nested_column)) {
-            res = _execute_number<ColumnDecimal64>(offsets, *nested_column, 
src_null_map,
-                                                   *arguments[1].column, 
nested_null_map,
-                                                   dst_null_map);
+            res = _execute_number<ColumnDecimal64>(offsets, *nested_column, 
src_null_map, *idx_col,
+                                                   nested_null_map, 
dst_null_map);
         } else if (check_column<ColumnDecimal128I>(*nested_column)) {
             res = _execute_number<ColumnDecimal128I>(offsets, *nested_column, 
src_null_map,
-                                                     *arguments[1].column, 
nested_null_map,
-                                                     dst_null_map);
+                                                     *idx_col, 
nested_null_map, dst_null_map);
         } else if (check_column<ColumnDecimal128>(*nested_column)) {
-            res = _execute_number<ColumnDecimal128>(offsets, *nested_column, 
src_null_map,
-                                                    *arguments[1].column, 
nested_null_map,
-                                                    dst_null_map);
+            res = _execute_number<ColumnDecimal128>(offsets, *nested_column, 
src_null_map, *idx_col,
+                                                    nested_null_map, 
dst_null_map);
         } else if (check_column<ColumnString>(*nested_column)) {
-            res = _execute_string(offsets, *nested_column, src_null_map, 
*arguments[1].column,
-                                  nested_null_map, dst_null_map);
+            res = _execute_string(offsets, *nested_column, src_null_map, 
*idx_col, nested_null_map,
+                                  dst_null_map);
         }
 
         return res;
diff --git 
a/fe/fe-common/src/main/java/org/apache/doris/catalog/StructType.java 
b/fe/fe-common/src/main/java/org/apache/doris/catalog/StructType.java
index fa8624a955..a037b77de9 100644
--- a/fe/fe-common/src/main/java/org/apache/doris/catalog/StructType.java
+++ b/fe/fe-common/src/main/java/org/apache/doris/catalog/StructType.java
@@ -175,11 +175,14 @@ public class StructType extends Type {
         }
 
         StructType other = (StructType) t;
+        // Temp to make NullPredict from fe send to be
+        if (other.getFields().size() == 1 && 
Objects.equals(other.getFields().get(0).name,
+                Type.GENERIC_STRUCT.getFields().get(0).name)) {
+            return true;
+        }
         if (fields.size() != other.getFields().size()) {
-            // Temp to make NullPredict from fe send to be
-            return other.getFields().size() == 1 && 
Objects.equals(other.getFields().get(0).name, "null_pred");
+            return false;
         }
-
         for (int i = 0; i < fields.size(); i++) {
             if (!fields.get(i).matchesField(((StructType) 
t).getFields().get(i))) {
                 return false;
diff --git a/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java 
b/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java
index 8c1f1200b4..5e794b27e0 100644
--- a/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java
+++ b/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java
@@ -107,6 +107,8 @@ public abstract class Type {
     public static final ScalarType ALL = new ScalarType(PrimitiveType.ALL);
     public static final MapType MAP = new MapType();
     public static final ArrayType ARRAY = ArrayType.create();
+    public static final StructType GENERIC_STRUCT = new 
StructType(Lists.newArrayList(
+            new StructField("generic_struct", new 
ScalarType(PrimitiveType.NULL_TYPE))));
     public static final StructType STRUCT = new StructType();
     public static final VariantType VARIANT = new VariantType();
 
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 976722fc21..1edca054dd 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
@@ -699,7 +699,7 @@ public class FunctionCallExpr extends Expr {
             }
 
             for (Expr child : children) {
-                if (child.type.isOnlyMetricType()) {
+                if (child.type.isOnlyMetricType() && 
!child.type.isComplexType()) {
                     throw new AnalysisException(Type.OnlyMetricTypeErrorMsg);
                 }
             }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/IsNullPredicate.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/IsNullPredicate.java
index 64367c56ce..545bfc5185 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/IsNullPredicate.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/IsNullPredicate.java
@@ -24,8 +24,6 @@ import org.apache.doris.catalog.Function;
 import org.apache.doris.catalog.Function.NullableMode;
 import org.apache.doris.catalog.FunctionSet;
 import org.apache.doris.catalog.ScalarFunction;
-import org.apache.doris.catalog.StructField;
-import org.apache.doris.catalog.StructType;
 import org.apache.doris.catalog.Type;
 import org.apache.doris.common.AnalysisException;
 import org.apache.doris.thrift.TExprNode;
@@ -62,7 +60,7 @@ public class IsNullPredicate extends Predicate {
                     isNotNullSymbol, Lists.newArrayList(t), Type.BOOLEAN, 
NullableMode.ALWAYS_NOT_NULLABLE));
 
             // for array type
-            for (Type complexType : Lists.newArrayList(Type.ARRAY, Type.MAP)) {
+            for (Type complexType : Lists.newArrayList(Type.ARRAY, Type.MAP, 
Type.GENERIC_STRUCT)) {
                 
functionSet.addBuiltinBothScalaAndVectorized(ScalarFunction.createBuiltinOperator(IS_NULL,
 isNullSymbol,
                         Lists.newArrayList(complexType), Type.BOOLEAN, 
NullableMode.ALWAYS_NOT_NULLABLE));
 
@@ -71,12 +69,6 @@ public class IsNullPredicate extends Predicate {
                         NullableMode.ALWAYS_NOT_NULLABLE));
             }
 
-            Type nullStruct = new StructType(Lists.newArrayList(new 
StructField("null_pred", Type.NULL)));
-            
functionSet.addBuiltinBothScalaAndVectorized(ScalarFunction.createBuiltinOperator(IS_NULL,
 isNullSymbol,
-                    Lists.newArrayList(nullStruct), Type.BOOLEAN, 
NullableMode.ALWAYS_NOT_NULLABLE));
-
-            
functionSet.addBuiltinBothScalaAndVectorized(ScalarFunction.createBuiltinOperator(IS_NOT_NULL,
-                    isNotNullSymbol, Lists.newArrayList(nullStruct), 
Type.BOOLEAN, NullableMode.ALWAYS_NOT_NULLABLE));
         }
     }
 
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java
index ffb11b6015..6475f3e3ec 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java
@@ -1564,6 +1564,27 @@ public class FunctionSet<T> {
                 prefix + 
"17count_star_removeEPN9doris_udf15FunctionContextEPNS1_9BigIntValE",
                 null, false, true, true, true));
 
+        // count(array/map/struct)
+        for (Type complexType : Lists.newArrayList(Type.ARRAY, Type.MAP, 
Type.GENERIC_STRUCT)) {
+            addBuiltin(AggregateFunction.createBuiltin(FunctionSet.COUNT,
+                    Lists.newArrayList(complexType), Type.BIGINT, Type.BIGINT,
+                    prefix + 
"18init_zero_not_nullIN9doris_udf9BigIntValEEEvPNS2_15FunctionContextEPT_",
+                    prefix + 
"12count_updateEPN9doris_udf15FunctionContextERKNS1_6AnyValEPNS1_9BigIntValE",
+                    prefix + 
"11count_mergeEPN9doris_udf15FunctionContextERKNS1_9BigIntValEPS4_",
+                    null, null,
+                    prefix + 
"12count_removeEPN9doris_udf15FunctionContextERKNS1_6AnyValEPNS1_9BigIntValE",
+                    null, false, true, true, true));
+
+            addBuiltin(AggregateFunction.createBuiltin(FunctionSet.COUNT,
+                    Lists.newArrayList(complexType), Type.BIGINT, Type.BIGINT,
+                    prefix + 
"18init_zero_not_nullIN9doris_udf9BigIntValEEEvPNS2_15FunctionContextEPT_",
+                    prefix + 
"12count_updateEPN9doris_udf15FunctionContextERKNS1_6AnyValEPNS1_9BigIntValE",
+                    prefix + 
"11count_mergeEPN9doris_udf15FunctionContextERKNS1_9BigIntValEPS4_",
+                    null, null,
+                    prefix + 
"12count_removeEPN9doris_udf15FunctionContextERKNS1_6AnyValEPNS1_9BigIntValE",
+                    null, false, true, true, true));
+        }
+
         // windowFunnel
         addBuiltin(AggregateFunction.createBuiltin(FunctionSet.WINDOW_FUNNEL,
                 Lists.newArrayList(Type.BIGINT, Type.STRING, Type.DATETIME, 
Type.BOOLEAN),
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/analysis/IsNullPredicateWithComplexTypeTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/analysis/IsNullPredicateWithComplexTypeTest.java
index c40de1e643..6897b1ec82 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/analysis/IsNullPredicateWithComplexTypeTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/analysis/IsNullPredicateWithComplexTypeTest.java
@@ -20,6 +20,7 @@ package org.apache.doris.analysis;
 import org.apache.doris.common.Config;
 import org.apache.doris.utframe.TestWithFeService;
 
+import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
 public class IsNullPredicateWithComplexTypeTest extends TestWithFeService {
@@ -53,8 +54,19 @@ public class IsNullPredicateWithComplexTypeTest extends 
TestWithFeService {
         String testStructIsNUll = "select * from test.complex where s is null";
         String testMapIsNUll = "select * from test.complex where m is null";
         String testArrayIsNUll = "select * from test.complex where a is null";
-        assertSQLPlanOrErrorMsgContains(testStructIsNUll, "");
-        assertSQLPlanOrErrorMsgContains(testMapIsNUll, "");
-        assertSQLPlanOrErrorMsgContains(testArrayIsNUll, "");
+        Assertions.assertNotNull(getSQLPlanner(testStructIsNUll));
+        Assertions.assertNotNull(getSQLPlanner(testMapIsNUll));
+        Assertions.assertNotNull(getSQLPlanner(testArrayIsNUll));
     }
+
+    @Test
+    public void testCount() throws Exception {
+        String testStructIsNUll = "select count(s) from test.complex";
+        String testMapIsNUll = "select count(m) from test.complex";
+        String testArrayIsNUll = "select count(a) from test.complex";
+        Assertions.assertNotNull(getSQLPlanner(testStructIsNUll));
+        Assertions.assertNotNull(getSQLPlanner(testMapIsNUll));
+        Assertions.assertNotNull(getSQLPlanner(testArrayIsNUll));
+    }
+
 }
diff --git a/regression-test/data/export/test_map_export.out 
b/regression-test/data/export/test_map_export.out
index bf3df19431..9b46ae9dfb 100644
--- a/regression-test/data/export/test_map_export.out
+++ b/regression-test/data/export/test_map_export.out
@@ -5,3 +5,7 @@
 3      {"  33,amory  ":2, " bet ":20, " cler ":26}
 4      {"k3":23, null:20, "k4":null}
 5      {null:null}
+
+-- !select_count --
+4
+
diff --git a/regression-test/data/load/insert/test_array_insert_into_select.out 
b/regression-test/data/load/insert/test_array_insert_into_select.out
index 2dcf990314..594d8881e3 100644
--- a/regression-test/data/load/insert/test_array_insert_into_select.out
+++ b/regression-test/data/load/insert/test_array_insert_into_select.out
@@ -5,9 +5,15 @@
 2      [{"a":"1","b":"2"}]
 3      []
 
+-- !select_string --
+4
+
 -- !select_array --
 0      \N
 1      ['{"a":"1","b":"2","c":"3",}', '{"a":"1","b":"2"}']
 2      \N
 3      []
 
+-- !select_array --
+2
+
diff --git a/regression-test/data/load/insert/test_array_string_insert.out 
b/regression-test/data/load/insert/test_array_string_insert.out
index bec55ae658..4d5875f533 100644
--- a/regression-test/data/load/insert/test_array_string_insert.out
+++ b/regression-test/data/load/insert/test_array_string_insert.out
@@ -5,3 +5,6 @@
 6      \N      ['4']   [[123], [222]]
 7      \N      ['4']   [[12345, NULL], [222]]
 
+-- !select_count --
+1      4       2
+
diff --git a/regression-test/data/load/insert/test_insert_nested_array.out 
b/regression-test/data/load/insert/test_insert_nested_array.out
index e40e3d26c8..0a59a905cf 100644
--- a/regression-test/data/load/insert/test_insert_nested_array.out
+++ b/regression-test/data/load/insert/test_insert_nested_array.out
@@ -13,6 +13,9 @@
 6      [[1, 2, NULL], NULL, [4, NULL, 6], NULL, [NULL, 8, 9]]
 6      [[1, 2, NULL], NULL, [4, NULL, 6], NULL, [NULL, 8, 9]]
 
+-- !select --
+12
+
 -- !select --
 1      []
 1      []
@@ -27,6 +30,9 @@
 6      [[[NULL]], [[1], [2, 3]], [[4, 5, 6], NULL, NULL]]
 6      [[[NULL]], [[1], [2, 3]], [[4, 5, 6], NULL, NULL]]
 
+-- !select --
+12
+
 -- !select --
 1      []      1       []
 1      []      1       []
diff --git a/regression-test/data/load/insert/test_map_dml.out 
b/regression-test/data/load/insert/test_map_dml.out
index 4ce856d254..fd032152a2 100644
--- a/regression-test/data/load/insert/test_map_dml.out
+++ b/regression-test/data/load/insert/test_map_dml.out
@@ -3,5 +3,12 @@
 1      {" amory ":6, "happy":38}
 6      {"amory":6, "is":38, "cl":0}
 
+-- !select_count --
+2
+
 -- !select --
 100    {1:"1", 2:"2", 3:"3"}   {32767:"32767", 32768:"32768", 32769:"32769"}   
[65534, 65535, 65536]   {2022-07-13:1}  {2022-07-13 12:30:00:"2022-07-13 
12:30:00"}     {0.33:33, 0.67:67}
+
+-- !select --
+1      1       1       1       1       1
+
diff --git a/regression-test/data/load_p0/broker_load/test_array_load.out 
b/regression-test/data/load_p0/broker_load/test_array_load.out
index aac06e46ed..89b7f6c012 100644
--- a/regression-test/data/load_p0/broker_load/test_array_load.out
+++ b/regression-test/data/load_p0/broker_load/test_array_load.out
@@ -7,6 +7,9 @@
 5      [NULL, NULL]    [32767, 32768, NULL]    [65534, NULL, 65536]    ['a', 
'b', 'c', 'd', 'e']       ['hello', 'world']      [1991-01-01]    [1991-01-01 
00:00:00]   [0.33, 0.67]    [3.1415926, 0.878787878]        [1, 1.2, 1.3]
 100    [1, 2, 3]       [32767, 32768, 32769]   [65534, 65535, 65536]   ['a', 
'b', 'c'] ['hello', 'world']      [2022-07-13]    [2022-07-13 12:30:00]   
[0.33, 0.67]    [3.1415926, 0.878787878]        [4, 5.5, 6.67]
 
+-- !select_count --
+6      6
+
 -- !select --
 1      [1, 2, 3, 4, 5] [32767, 32768, 32769]   [65534, 65535, 65536]   ['a', 
'b', 'c', 'd', 'e']       ['hello', 'world']      [1991-01-01]    [1991-01-01 
00:00:00]   [0.333333, 0.676767]    [3.1415926, 0.878787878]        [1, 1.2, 
1.3]
 2      [6, 7, 8, 9, 10]        [32767, 32768, 32769]   [65534, 65535, 65536]   
['a', 'b', 'c', 'd', 'e']       ['hello', 'world']      [1991-01-01]    
[1991-01-01 00:00:00]   [0.333333, 0.676767]    [3.1415926, 0.878787878]        
[1, 1.2, 1.3]
@@ -16,6 +19,9 @@
 6      [NULL, NULL, 0, 0]      [32767, 32768, NULL]    [65534, NULL, 65536]    
['a', 'b', 'c', 'd', 'e']       ['hello,,,', 'world][]']        [1991-01-01]    
[1991-01-01 00:00:00]   [0.33, 0.67]    [3.1415926, 0.878787878]        [0, 0]
 100    [1, 2, 3]       [32767, 32768, 32769]   [65534, 65535, 65536]   ['a', 
'b', 'c'] ['hello', 'world']      [2022-07-13]    [2022-07-13 12:30:00]   
[0.33, 0.67]    [3.1415926, 0.878787878]        [4, 5.5, 6.67]
 
+-- !select_count --
+7      7
+
 -- !select --
 1      [1, 2, 3, 4, 5] [32767, 32768, 32769]   [65534, 65535, 65536]   ['a', 
'b', 'c', 'd', 'e']       ['hello', 'world']      [1991-01-01, 1992-02-02, 
1993-03-03]    [1991-01-01 00:00:00]   [0.33, 0.67]    [3.1415926, 0.878787878] 
       [1, 1.2, 1.3]
 2      [1, 2, 3, 4, 5] [32767, 32768, 32769]   [65534, 65535, 65536]   ['a', 
'b', 'c', 'd', 'e']       ['hello', 'world']      [1991-01-01, 1992-02-02, 
1993-03-03]    \N      \N      \N      [1, NULL, 1.3]
@@ -24,6 +30,9 @@
 5      \N      \N      \N      \N      \N      \N      \N      \N      \N      
\N
 100    [1, 2, 3]       [32767, 32768, 32769]   [65534, 65535, 65536]   ['a', 
'b', 'c'] ['hello', 'world']      [2022-07-13]    [2022-07-13 12:30:00]   
[0.33, 0.67]    [3.1415926, 0.878787878]        [4, 5.5, 6.67]
 
+-- !select_count --
+6      3
+
 -- !select --
 1      [1, 2, 3, 4, 5] [32767, 32768, 32769]   [65534, 65535, 65536]   ['a', 
'b', 'c', 'd', 'e']       ['hello', 'world']      [1991-01-01]    [1991-01-01 
00:00:00]   [0.33, 0.67]    [3.1415926, 0.878787878]        [1, 1.2, 1.3]
 2      [6, 7, 8, 9, 10]        [32767, 32768, 32769]   [65534, 65535, 65536]   
['a', 'b', 'c', 'd', 'e']       ['hello', 'world']      [1991-01-01]    
[1991-01-01 00:00:00]   [0.33, 0.67]    [3.1415926, 0.878787878]        [1, 
1.2, 1.3]
@@ -32,6 +41,9 @@
 5      [NULL, NULL]    [32767, 32768, NULL]    [65534, NULL, 65536]    ['a', 
'b', 'c', 'd', 'e']       ['hello', 'world']      [1991-01-01]    [1991-01-01 
00:00:00]   [0.33, 0.67]    [3.1415926, 0.878787878]        [1, 1.2, 1.3]
 100    [1, 2, 3]       [32767, 32768, 32769]   [65534, 65535, 65536]   ['a', 
'b', 'c'] ['hello', 'world']      [2022-07-13]    [2022-07-13 12:30:00]   
[0.33, 0.67]    [3.1415926, 0.878787878]        [4, 5.5, 6.67]
 
+-- !select_count --
+6      6
+
 -- !select --
 1      [1, 2, 3, 4, 5] [32767, 32768, 32769]   [65534, 65535, 65536]   ['a', 
'b', 'c', 'd', 'e']       ['hello', 'world']      [1991-01-01]    [1991-01-01 
00:00:00]   [0.333333, 0.676767]    [3.1415926, 0.878787878]        [1, 1.2, 
1.3]
 2      [6, 7, 8, 9, 10]        [32767, 32768, 32769]   [65534, 65535, 65536]   
['a', 'b', 'c', 'd', 'e']       ['hello', 'world']      [1991-01-01]    
[1991-01-01 00:00:00]   [0.333333, 0.676767]    [3.1415926, 0.878787878]        
[1, 1.2, 1.3]
@@ -41,6 +53,9 @@
 6      [NULL, NULL, 0, 0]      [32767, 32768, NULL]    [65534, NULL, 65536]    
['a', 'b', 'c', 'd', 'e']       ['hello,,,', 'world][]']        [1991-01-01]    
[1991-01-01 00:00:00]   [0.33, 0.67]    [3.1415926, 0.878787878]        [0, 0]
 100    [1, 2, 3]       [32767, 32768, 32769]   [65534, 65535, 65536]   ['a', 
'b', 'c'] ['hello', 'world']      [2022-07-13]    [2022-07-13 12:30:00]   
[0.33, 0.67]    [3.1415926, 0.878787878]        [4, 5.5, 6.67]
 
+-- !select_count --
+7      7
+
 -- !select --
 1      [1, 2, 3, 4, 5] [32767, 32768, 32769]   [65534, 65535, 65536]   ['a', 
'b', 'c', 'd', 'e']       ['hello', 'world']      [1991-01-01, 1992-02-02, 
1993-03-03]    [1991-01-01 00:00:00]   [0.33, 0.67]    [3.1415926, 0.878787878] 
       [1, 1.2, 1.3]
 2      [1, 2, 3, 4, 5] [32767, 32768, 32769]   [65534, 65535, 65536]   ['a', 
'b', 'c', 'd', 'e']       ['hello', 'world']      [1991-01-01, 1992-02-02, 
1993-03-03]    \N      \N      \N      [1, NULL, 1.3]
@@ -49,3 +64,6 @@
 5      \N      \N      \N      \N      \N      \N      \N      \N      \N      
\N
 100    [1, 2, 3]       [32767, 32768, 32769]   [65534, 65535, 65536]   ['a', 
'b', 'c'] ['hello', 'world']      [2022-07-13]    [2022-07-13 12:30:00]   
[0.33, 0.67]    [3.1415926, 0.878787878]        [4, 5.5, 6.67]
 
+-- !select_count --
+6      3
+
diff --git 
a/regression-test/data/load_p0/stream_load/test_map_load_and_compaction.out 
b/regression-test/data/load_p0/stream_load/test_map_load_and_compaction.out
index df2b8a05db..b4348cb553 100644
--- a/regression-test/data/load_p0/stream_load/test_map_load_and_compaction.out
+++ b/regression-test/data/load_p0/stream_load/test_map_load_and_compaction.out
@@ -2,3 +2,6 @@
 -- !select --
 20317
 
+-- !select --
+20317
+
diff --git 
a/regression-test/data/load_p0/stream_load/test_map_load_and_function.out 
b/regression-test/data/load_p0/stream_load/test_map_load_and_function.out
index 70f7d3c7d1..c02d5efe7a 100644
--- a/regression-test/data/load_p0/stream_load/test_map_load_and_function.out
+++ b/regression-test/data/load_p0/stream_load/test_map_load_and_function.out
@@ -305,7 +305,7 @@ k22
 9      {"  1,amy  ":2, " k2 ":90, " k7 ":33}   \N
 10     {}      \N
 11     \N      \N
-12     {"k3":23, null:20, "k4":null}   20
+12     {"k3":23, null:20, "k4":null}   \N
 13     {"null":1}      \N
 15     {"":2, "k2":0}  2
 16     {null:null}     \N
@@ -324,7 +324,7 @@ k22
 9      {"  1,amy  ":2, " k2 ":90, " k7 ":33}   \N
 10     {}      \N
 11     \N      \N
-12     {"k3":23, null:20, "k4":null}   \N
+12     {"k3":23, null:20, "k4":null}   20
 13     {"null":1}      \N
 15     {"":2, "k2":0}  \N
 16     {null:null}     \N
@@ -1047,3 +1047,6 @@ false
 -- !select_m5 --
 1      100     200     \N
 
+-- !select_count --
+1      1       1       1       1
+
diff --git a/regression-test/data/query_p0/show/test_map_show_create.out 
b/regression-test/data/query_p0/show/test_map_show_create.out
index 78b706ca7d..774a1d9020 100644
--- a/regression-test/data/query_p0/show/test_map_show_create.out
+++ b/regression-test/data/query_p0/show/test_map_show_create.out
@@ -2,3 +2,6 @@
 -- !select --
 test_map_show_create   CREATE TABLE `test_map_show_create` (\n  `k1` int(11) 
NULL,\n  `k2` MAP<smallint(6),text> NULL,\n  `k3` MAP<int(11),text> NULL,\n  
`k4` MAP<date,int(11)> NULL,\n  `k5` MAP<datetime,text> NULL,\n  `k6` 
MAP<float,int(11)> NULL\n) ENGINE=OLAP\nDUPLICATE KEY(`k1`)\nCOMMENT 
'OLAP'\nDISTRIBUTED BY HASH(`k1`) BUCKETS 1\nPROPERTIES 
(\n"replication_allocation" = "tag.location.default: 1",\n"in_memory" = 
"false",\n"storage_format" = "V2",\n"light_schema_change" = "true",\n"dis [...]
 
+-- !select --
+1      1       1       1       1
+
diff --git a/regression-test/data/query_p0/show/test_struct_show_create.out 
b/regression-test/data/query_p0/show/test_struct_show_create.out
index e06f2ba5dd..1dd95c010c 100644
--- a/regression-test/data/query_p0/show/test_struct_show_create.out
+++ b/regression-test/data/query_p0/show/test_struct_show_create.out
@@ -1,4 +1,7 @@
 -- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !select_count --
+1      1       1       1       1       1       1       1       1       1
+
 -- !select --
 test_struct_show_create        CREATE TABLE `test_struct_show_create` (\n  
`k1` int(11) NULL,\n  `k2` STRUCT<f1:smallint(6)> NOT NULL,\n  `k3` 
STRUCT<f1:smallint(6),f2:int(11)> NOT NULL,\n  `k4` 
STRUCT<f1:smallint(6),f2:int(11),f3:bigint(20)> NOT NULL,\n  `k5` 
STRUCT<f1:smallint(6),f2:int(11),f3:bigint(20),f4:char(1)> NOT NULL,\n  `k6` 
STRUCT<f1:smallint(6),f2:int(11),f3:bigint(20),f4:char(1),f5:varchar(20)> 
NULL,\n  `k7` 
STRUCT<f1:smallint(6),f2:int(11),f3:bigint(20),f4:char(1),f5:varchar(20), [...]
 
diff --git a/regression-test/suites/export/test_map_export.groovy 
b/regression-test/suites/export/test_map_export.groovy
index a1fa469f43..362e512491 100644
--- a/regression-test/suites/export/test_map_export.groovy
+++ b/regression-test/suites/export/test_map_export.groovy
@@ -75,6 +75,7 @@ suite("test_map_export", "export") {
 
     // check result
     qt_select """ SELECT * FROM ${testTable} ORDER BY id; """
+    qt_select_count """SELECT COUNT(m) FROM ${testTable}"""
 
     def outFilePath = """${context.file.parent}/test_map_export"""
     logger.info("test_map_export the outFilePath=" + outFilePath)
diff --git 
a/regression-test/suites/load/insert/test_array_insert_into_select.groovy 
b/regression-test/suites/load/insert/test_array_insert_into_select.groovy
index f171ae3220..554f188af0 100644
--- a/regression-test/suites/load/insert/test_array_insert_into_select.groovy
+++ b/regression-test/suites/load/insert/test_array_insert_into_select.groovy
@@ -41,6 +41,7 @@ suite("test_array_insert_into_select", "load") {
 
     // check data in tstring
     qt_select_string "SELECT * FROM tstring ORDER BY id"
+    qt_select_string "SELECT count(data) FROM tstring"
 
 
     // create table with array
@@ -62,4 +63,5 @@ suite("test_array_insert_into_select", "load") {
 
     // check data in tarray
     qt_select_array "SELECT * FROM tarray ORDER BY id"
+    qt_select_array "SELECT count(data) FROM tarray"
 }
diff --git a/regression-test/suites/load/insert/test_array_string_insert.groovy 
b/regression-test/suites/load/insert/test_array_string_insert.groovy
index c98f1ac80a..23acc72242 100644
--- a/regression-test/suites/load/insert/test_array_string_insert.groovy
+++ b/regression-test/suites/load/insert/test_array_string_insert.groovy
@@ -73,6 +73,7 @@ suite("test_array_string_insert", "load") {
 
         // select the table and check whether the data is correct
         qt_select "select * from ${testTable} order by k1"
+        qt_select_count "select count(k2), count(k3), count(k4) from 
${testTable}"
     }
     
     test_insert_array_string();
diff --git a/regression-test/suites/load/insert/test_insert_nested_array.groovy 
b/regression-test/suites/load/insert/test_insert_nested_array.groovy
index e3291d7831..2291b6c652 100644
--- a/regression-test/suites/load/insert/test_insert_nested_array.groovy
+++ b/regression-test/suites/load/insert/test_insert_nested_array.groovy
@@ -44,6 +44,7 @@ suite("test_insert_nested_array", "load") {
                 (6, [[1, 2, null], null, [4, null, 6], null, [null, 8, 9]])
         """
         qt_select "select * from ${tableName} order by `key`"
+        qt_select "select count(value) from ${tableName}"
     }
 
     def test_nested_array_3_depths = {
@@ -74,6 +75,7 @@ suite("test_insert_nested_array", "load") {
                 (6, [[[null]], [[1], [2, 3]], [[4, 5, 6], null, null]])
         """
         qt_select "select * from ${tableName} order by `key`"
+        qt_select "select count(value) from ${tableName}"
         qt_select "select * from ${tableName} as t1 right join ${tableName} as 
t2 on t1.`key` = t2.`key` order by t1.`key`"
     }
 
diff --git a/regression-test/suites/load/insert/test_map_dml.groovy 
b/regression-test/suites/load/insert/test_map_dml.groovy
index 438bd0b496..5f626fe833 100644
--- a/regression-test/suites/load/insert/test_map_dml.groovy
+++ b/regression-test/suites/load/insert/test_map_dml.groovy
@@ -95,6 +95,7 @@ suite("test_map_dml", "load") {
 
         // select the table and check whether the data is correct
         qt_select "SELECT * FROM ${testTable} ORDER BY k1"
+        qt_select_count "SELECT COUNT(k1) FROM ${testTable}"
 
     } finally {
         try_sql("DROP TABLE IF EXISTS ${testTable}")
@@ -107,6 +108,7 @@ suite("test_map_dml", "load") {
         create_test_table01.call(testTable)
         // select the table and check whether the data is correct
         qt_select "SELECT * FROM ${testTable01} ORDER BY k1"
+        qt_select "SELECT COUNT(k2), COUNT(k3), COUNT(k4),COUNT(k5),COUNT(k6), 
COUNT(k7) FROM ${testTable01}"
 
     } finally {
         try_sql("DROP TABLE IF EXISTS ${testTable01}")
diff --git a/regression-test/suites/load_p0/broker_load/test_array_load.groovy 
b/regression-test/suites/load_p0/broker_load/test_array_load.groovy
index 9634b29a4e..2697d08db2 100644
--- a/regression-test/suites/load_p0/broker_load/test_array_load.groovy
+++ b/regression-test/suites/load_p0/broker_load/test_array_load.groovy
@@ -191,7 +191,8 @@ suite("test_array_load", "load_p0") {
     def check_data_correct = {table_name ->
         sql "sync"
         // select the table and check whether the data is correct
-        qt_select "select * from ${table_name} order by k1" 
+        qt_select "select * from ${table_name} order by k1"
+        qt_select_count "select count(3), count(k6) from ${table_name}"
     }
 
     try {
diff --git 
a/regression-test/suites/load_p0/stream_load/test_map_load_and_compaction.groovy
 
b/regression-test/suites/load_p0/stream_load/test_map_load_and_compaction.groovy
index ae4778d511..c8b0a98570 100644
--- 
a/regression-test/suites/load_p0/stream_load/test_map_load_and_compaction.groovy
+++ 
b/regression-test/suites/load_p0/stream_load/test_map_load_and_compaction.groovy
@@ -97,6 +97,7 @@ suite("test_map_load_and_compaction", "p0") {
 
         // check result
         qt_select "SELECT count(*) FROM ${testTable};"
+        qt_select "SELECT count(actor) FROM ${testTable};"
 
         // check here 2 rowsets
         
//TabletId,ReplicaId,BackendId,SchemaHash,Version,LstSuccessVersion,LstFailedVersion,LstFailedTime,LocalDataSize,RemoteDataSize,RowCount,State,LstConsistencyCheckTime,CheckVersion,VersionCount,PathHash,MetaUrl,CompactionStatus
diff --git 
a/regression-test/suites/load_p0/stream_load/test_map_load_and_function.groovy 
b/regression-test/suites/load_p0/stream_load/test_map_load_and_function.groovy
index 362be32602..5d0a187d09 100644
--- 
a/regression-test/suites/load_p0/stream_load/test_map_load_and_function.groovy
+++ 
b/regression-test/suites/load_p0/stream_load/test_map_load_and_function.groovy
@@ -183,4 +183,5 @@ suite("test_map_load_and_function", "p0") {
     qt_select_m3 "SELECT id, m3['k1'], m3['k2'], m3['nokey'] FROM ${testTable} 
ORDER BY id"
     qt_select_m4 "SELECT id, m4[100], m4[200], m4[300] FROM ${testTable} ORDER 
BY id"
     qt_select_m5 "SELECT id, m5[10000], m5[20000], m5[30000] FROM ${testTable} 
ORDER BY id"
+    qt_select_count "SELECT COUNT(m1), COUNT(m2), COUNT(m3), COUNT(m4), 
COUNT(m5)  FROM ${testTable}"
 }
diff --git a/regression-test/suites/query_p0/show/test_map_show_create.groovy 
b/regression-test/suites/query_p0/show/test_map_show_create.groovy
index 463cb2babc..01776b7c80 100644
--- a/regression-test/suites/query_p0/show/test_map_show_create.groovy
+++ b/regression-test/suites/query_p0/show/test_map_show_create.groovy
@@ -62,6 +62,7 @@ suite("test_map_show_create", "query") {
         create_test_table.call(testTable)
 
         qt_select "SHOW CREATE TABLE ${testTable}"
+        qt_select "select count(k2), count(k3), count(k4), count(k5), 
count(k6) from ${testTable}"
     } finally {
         try_sql("DROP TABLE IF EXISTS ${testTable}")
     }
diff --git 
a/regression-test/suites/query_p0/show/test_struct_show_create.groovy 
b/regression-test/suites/query_p0/show/test_struct_show_create.groovy
index e73359b663..ae21c4ed45 100644
--- a/regression-test/suites/query_p0/show/test_struct_show_create.groovy
+++ b/regression-test/suites/query_p0/show/test_struct_show_create.groovy
@@ -71,7 +71,7 @@ suite("test_struct_show_create", "query") {
     try {
         sql "DROP TABLE IF EXISTS ${testTable}"
         create_test_table.call(testTable)
-
+        qt_select_count "select count(k2), count(k3), count(k4), count(k5), 
count(6), count(k7), count(k8), count(k9), count(k10), count(11) from 
${testTable}"
         qt_select "show create table ${testTable}"
     } finally {
         try_sql("DROP TABLE IF EXISTS ${testTable}")


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


Reply via email to