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

morrysnow pushed a commit to branch branch-3.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-3.1 by this push:
     new e3440361b32 branch-3.1: [enhance](array) array_min/max support 
array<string> #51145 (#52640)
e3440361b32 is described below

commit e3440361b324a1423cf4fa4bb0a19f862de35d32
Author: Sun Chenyang <[email protected]>
AuthorDate: Wed Jul 2 18:11:47 2025 +0800

    branch-3.1: [enhance](array) array_min/max support array<string> #51145 
(#52640)
    
    pick from mater #51145
---
 .../functions/array/function_array_aggregation.cpp |  59 +++++++++++-----
 .../expressions/functions/scalar/ArrayAvg.java     |  11 +++
 .../expressions/functions/scalar/ArrayJoin.java    |  11 +++
 .../expressions/functions/scalar/ArrayProduct.java |  11 +++
 .../expressions/functions/scalar/ArraySum.java     |  11 +++
 .../data/function_p0/test_array_agg.out            | Bin 0 -> 338 bytes
 .../data/variant_p0/test_array_function.out        | Bin 0 -> 376 bytes
 .../suites/function_p0/test_array_agg.groovy       |  64 ++++++++++++++++++
 .../suites/variant_p0/test_array_function.groovy   |  74 +++++++++++++++++++++
 9 files changed, 224 insertions(+), 17 deletions(-)

diff --git a/be/src/vec/functions/array/function_array_aggregation.cpp 
b/be/src/vec/functions/array/function_array_aggregation.cpp
index 24d82f7894a..6879d68144c 100644
--- a/be/src/vec/functions/array/function_array_aggregation.cpp
+++ b/be/src/vec/functions/array/function_array_aggregation.cpp
@@ -228,7 +228,8 @@ struct ArrayAggregateImpl {
             execute_type<Date>(res, type, data, offsets) ||
             execute_type<DateTime>(res, type, data, offsets) ||
             execute_type<DateV2>(res, type, data, offsets) ||
-            execute_type<DateTimeV2>(res, type, data, offsets)) {
+            execute_type<DateTimeV2>(res, type, data, offsets) ||
+            execute_type<String>(res, type, data, offsets)) {
             block.replace_by_position(result, std::move(res));
             return Status::OK();
         } else {
@@ -236,29 +237,22 @@ struct ArrayAggregateImpl {
         }
     }
 
-    template <typename Element>
-    static bool execute_type(ColumnPtr& res_ptr, const DataTypePtr& type, 
const IColumn* data,
-                             const ColumnArray::Offsets64& offsets) {
-        using ColVecType = ColumnVectorOrDecimal<Element>;
-        using ResultType = ArrayAggregateResult<Element, operation, 
enable_decimal256>;
-        using ColVecResultType = ColumnVectorOrDecimal<ResultType>;
+    template <typename ColumnType, typename CreateColumnFunc>
+    static bool execute_type_impl(ColumnPtr& res_ptr, const DataTypePtr& type, 
const IColumn* data,
+                                  const ColumnArray::Offsets64& offsets,
+                                  CreateColumnFunc create_column_func) {
         using Function = AggregateFunction<AggregateFunctionImpl<operation, 
enable_decimal256>>;
 
-        const ColVecType* column =
+        const ColumnType* column =
                 data->is_nullable()
-                        ? check_and_get_column<ColVecType>(
+                        ? check_and_get_column<ColumnType>(
                                   static_cast<const 
ColumnNullable*>(data)->get_nested_column())
-                        : check_and_get_column<ColVecType>(&*data);
+                        : check_and_get_column<ColumnType>(&*data);
         if (!column) {
             return false;
         }
 
-        ColumnPtr res_column;
-        if constexpr (IsDecimalNumber<Element>) {
-            res_column = ColVecResultType::create(0, column->get_scale());
-        } else {
-            res_column = ColVecResultType::create();
-        }
+        ColumnPtr res_column = create_column_func(column);
         res_column = make_nullable(res_column);
         
static_cast<ColumnNullable&>(res_column->assume_mutable_ref()).reserve(offsets.size());
 
@@ -282,7 +276,38 @@ struct ArrayAggregateImpl {
         }
         res_ptr = std::move(res_column);
         return true;
-    };
+    }
+
+    template <typename Element>
+    static bool execute_type(ColumnPtr& res_ptr, const DataTypePtr& type, 
const IColumn* data,
+                             const ColumnArray::Offsets64& offsets) {
+        using ColVecType = ColumnVectorOrDecimal<Element>;
+        using ResultType = ArrayAggregateResult<Element, operation, 
enable_decimal256>;
+        using ColVecResultType = ColumnVectorOrDecimal<ResultType>;
+
+        return execute_type_impl<ColVecType>(
+                res_ptr, type, data, offsets, [](const ColVecType* column) -> 
ColumnPtr {
+                    if constexpr (IsDecimalNumber<Element>) {
+                        return ColVecResultType::create(0, 
column->get_scale());
+                    } else {
+                        return ColVecResultType::create();
+                    }
+                });
+    }
+
+    template <>
+    static bool execute_type<String>(ColumnPtr& res_ptr, const DataTypePtr& 
type,
+                                     const IColumn* data, const 
ColumnArray::Offsets64& offsets) {
+        if (operation == AggregateOperation::SUM || operation == 
AggregateOperation::PRODUCT ||
+            operation == AggregateOperation::AVERAGE) {
+            return false;
+        }
+        using ColumnType = ColumnString;
+
+        return execute_type_impl<ColumnType>(
+                res_ptr, type, data, offsets,
+                [](const ColumnType*) -> ColumnPtr { return 
ColumnString::create(); });
+    }
 };
 
 struct NameArrayMin {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArrayAvg.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArrayAvg.java
index e07351f2a5c..ee82c7c2221 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArrayAvg.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArrayAvg.java
@@ -18,6 +18,7 @@
 package org.apache.doris.nereids.trees.expressions.functions.scalar;
 
 import org.apache.doris.catalog.FunctionSignature;
+import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ComputePrecisionForArrayItemAgg;
@@ -27,6 +28,7 @@ import 
org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.ArrayType;
 import org.apache.doris.nereids.types.BigIntType;
 import org.apache.doris.nereids.types.BooleanType;
+import org.apache.doris.nereids.types.DataType;
 import org.apache.doris.nereids.types.DecimalV2Type;
 import org.apache.doris.nereids.types.DecimalV3Type;
 import org.apache.doris.nereids.types.DoubleType;
@@ -96,6 +98,15 @@ public class ArrayAvg extends ScalarFunction implements 
ExplicitlyCastableSignat
     //     return signature;
     // }
 
+    @Override
+    public void checkLegalityBeforeTypeCoercion() {
+        DataType argType = child().getDataType();
+        if (((ArrayType) argType).getItemType().isComplexType()) {
+            throw new AnalysisException(toSql() + " does not support type: "
+                                                + ((ArrayType) 
argType).getItemType().toString());
+        }
+    }
+
     /**
      * withChildren.
      */
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArrayJoin.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArrayJoin.java
index 0da1ab78752..4185e74f755 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArrayJoin.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArrayJoin.java
@@ -18,11 +18,13 @@
 package org.apache.doris.nereids.trees.expressions.functions.scalar;
 
 import org.apache.doris.catalog.FunctionSignature;
+import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.ArrayType;
+import org.apache.doris.nereids.types.DataType;
 import org.apache.doris.nereids.types.StringType;
 import org.apache.doris.nereids.types.VarcharType;
 import org.apache.doris.nereids.types.coercion.AnyDataType;
@@ -60,6 +62,15 @@ public class ArrayJoin extends ScalarFunction
         super("array_join", arg0, arg1, arg2);
     }
 
+    @Override
+    public void checkLegalityBeforeTypeCoercion() {
+        DataType argType = child(0).getDataType();
+        if (((ArrayType) argType).getItemType().isComplexType()) {
+            throw new AnalysisException(toSql() + " does not support type: "
+                                    + ((ArrayType) 
argType).getItemType().toString());
+        }
+    }
+
     /**
      * withChildren.
      */
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArrayProduct.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArrayProduct.java
index ecc4eaac5eb..ad9dda6c66d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArrayProduct.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArrayProduct.java
@@ -18,6 +18,7 @@
 package org.apache.doris.nereids.trees.expressions.functions.scalar;
 
 import org.apache.doris.catalog.FunctionSignature;
+import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ComputePrecisionForArrayItemAgg;
@@ -27,6 +28,7 @@ import 
org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.ArrayType;
 import org.apache.doris.nereids.types.BigIntType;
 import org.apache.doris.nereids.types.BooleanType;
+import org.apache.doris.nereids.types.DataType;
 import org.apache.doris.nereids.types.DecimalV2Type;
 import org.apache.doris.nereids.types.DecimalV3Type;
 import org.apache.doris.nereids.types.DoubleType;
@@ -67,6 +69,15 @@ public class ArrayProduct extends ScalarFunction implements 
ExplicitlyCastableSi
         super("array_product", arg);
     }
 
+    @Override
+    public void checkLegalityBeforeTypeCoercion() {
+        DataType argType = child().getDataType();
+        if (((ArrayType) argType).getItemType().isComplexType()) {
+            throw new AnalysisException(toSql() + " does not support type: "
+                                                    + ((ArrayType) 
argType).getItemType().toString());
+        }
+    }
+
     /**
      * withChildren.
      */
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArraySum.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArraySum.java
index 2a28a4d18bf..8ed41b2368f 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArraySum.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArraySum.java
@@ -18,6 +18,7 @@
 package org.apache.doris.nereids.trees.expressions.functions.scalar;
 
 import org.apache.doris.catalog.FunctionSignature;
+import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ComputePrecisionForArrayItemAgg;
@@ -27,6 +28,7 @@ import 
org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.ArrayType;
 import org.apache.doris.nereids.types.BigIntType;
 import org.apache.doris.nereids.types.BooleanType;
+import org.apache.doris.nereids.types.DataType;
 import org.apache.doris.nereids.types.DecimalV2Type;
 import org.apache.doris.nereids.types.DecimalV3Type;
 import org.apache.doris.nereids.types.DoubleType;
@@ -68,6 +70,15 @@ public class ArraySum extends ScalarFunction implements 
ExplicitlyCastableSignat
         super("array_sum", arg);
     }
 
+    @Override
+    public void checkLegalityBeforeTypeCoercion() {
+        DataType argType = child().getDataType();
+        if (((ArrayType) argType).getItemType().isComplexType()) {
+            throw new AnalysisException(toSql() + " does not support type: "
+                                            + ((ArrayType) 
argType).getItemType().toString());
+        }
+    }
+
     /**
      * withChildren.
      */
diff --git a/regression-test/data/function_p0/test_array_agg.out 
b/regression-test/data/function_p0/test_array_agg.out
new file mode 100644
index 00000000000..4d0eff49821
Binary files /dev/null and 
b/regression-test/data/function_p0/test_array_agg.out differ
diff --git a/regression-test/data/variant_p0/test_array_function.out 
b/regression-test/data/variant_p0/test_array_function.out
new file mode 100644
index 00000000000..80815350a9a
Binary files /dev/null and 
b/regression-test/data/variant_p0/test_array_function.out differ
diff --git a/regression-test/suites/function_p0/test_array_agg.groovy 
b/regression-test/suites/function_p0/test_array_agg.groovy
new file mode 100644
index 00000000000..e89ea83be95
--- /dev/null
+++ b/regression-test/suites/function_p0/test_array_agg.groovy
@@ -0,0 +1,64 @@
+// 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_array_agg", "p0") {
+    sql """ set enable_nereids_planner=true;"""
+    sql """ set enable_fallback_to_original_planner=false;"""
+    def tableName = "array_agg_table"
+    sql """
+        drop table if exists ${tableName};
+    """
+
+    sql """ set enable_decimal256 = true """
+    sql """
+       CREATE TABLE IF NOT EXISTS ${tableName} (
+              `id` INT(11) null COMMENT "",
+              `a` array<INT> null  COMMENT "",
+              `b` array<array<INT>>  null COMMENT "",
+              `s` array<String>  null  COMMENT "",
+              `d` array<decimal(50,18)>  null  COMMENT ""
+            ) ENGINE=OLAP
+            DUPLICATE KEY(`id`)
+            DISTRIBUTED BY HASH(`id`) BUCKETS 1
+            PROPERTIES (
+            "replication_allocation" = "tag.location.default: 1",
+            "storage_format" = "V2"
+    );
+    """
+    sql """
+    insert into ${tableName} values
+    (1,[1,2,3],[[1],[1,2,3],[2]],["ab","123","114514"],[1.1,2.2,3.3]),
+    (2,[20],[[2]],["cd"],[3.3]),
+    (3,[100],[[1]],["efg"],[null,2.2,3.3]),
+    (4,null,[null],null,null),
+    (5,[null,2],[[2],null],[null,'c'],[1,null,3.3]);
+   """
+
+   qt_sql """
+       select array_min(a), array_min(s), array_max(a), array_max(s) from 
${tableName} order by id;
+   """
+
+   qt_sql """
+       select array_join(a, ',', 'replaced'), array_join(s, ',', 'replaced') 
from ${tableName} order by id;
+   """
+
+    qt_sql """ select array_sum(s) from ${tableName} order by id; """
+
+    qt_sql """ select array_avg(s) from ${tableName} order by id; """
+
+    qt_sql """ select array_product(s) from ${tableName} order by id; """
+}
diff --git a/regression-test/suites/variant_p0/test_array_function.groovy 
b/regression-test/suites/variant_p0/test_array_function.groovy
new file mode 100644
index 00000000000..8fa2a513161
--- /dev/null
+++ b/regression-test/suites/variant_p0/test_array_function.groovy
@@ -0,0 +1,74 @@
+// 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_variant_array_function", "p0") {
+    sql """ set enable_nereids_planner=true;"""
+    sql """ set enable_fallback_to_original_planner=false;"""
+    def tableName = "test_variant_array_function"
+    sql """
+        drop table if exists ${tableName};
+    """
+
+    sql """
+       CREATE TABLE IF NOT EXISTS ${tableName} (
+              `id` INT(11) null COMMENT "",
+              `var` variant  null
+            ) ENGINE=OLAP
+            DUPLICATE KEY(`id`)
+            DISTRIBUTED BY HASH(`id`) BUCKETS 1
+            PROPERTIES (
+            "replication_allocation" = "tag.location.default: 1",
+            "storage_format" = "V2"
+    );
+    """
+    sql """
+    insert into ${tableName} values
+    (1, '{"a":[1, 2,3],"b": ["a", "b", "c"], "c": [1.1, 2.2, 3.3]}')
+    """
+
+    sql """
+    insert into ${tableName} values
+    (2, '{"a":[1, 2,3],"b": ["1", "2", "3"], "c": [1.1, 2.2, 3.3]}')
+   """
+
+
+   qt_sql """
+       select array_min(cast(var['a'] as array<int>)), array_min(cast(var['b'] 
as array<string>)), array_max(cast(var['a'] as array<int>)), 
array_max(cast(var['b'] as array<string>)) from ${tableName} order by id;
+   """
+
+    qt_sql """
+        select array_join(cast(var['a'] as array<int>), ',', 'replaced'), 
array_join(cast(var['b'] as array<string>), ',', 'replaced'), 
array_join(cast(var['c'] as array<double>), ',', 'replaced') from ${tableName} 
order by id;
+    """
+
+    qt_sql """
+        select array_sum(cast(var['a'] as array<int>)), 
array_sum(cast(var['c'] as array<double>)) from ${tableName} order by id;
+    """
+
+    qt_sql """
+        select array_avg(cast(var['a'] as array<int>)), 
array_avg(cast(var['c'] as array<double>)) from ${tableName} order by id;
+    """
+    
+    qt_sql """
+        select array_product(cast(var['a'] as array<int>)), 
array_product(cast(var['c'] as array<double>)) from ${tableName} order by id;
+    """
+
+    qt_sql """ select array_sum(cast(var['b'] as array<string>)) from 
${tableName} order by id; """
+
+    qt_sql """ select array_avg(cast(var['b'] as array<string>)) from 
${tableName} order by id; """
+
+    qt_sql """ select array_product(cast(var['b'] as array<string>)) from 
${tableName} order by id; """
+}


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

Reply via email to