diff --git a/be/src/vec/CMakeLists.txt b/be/src/vec/CMakeLists.txt index ddc74e8ab5..6c82623816 100644 --- a/be/src/vec/CMakeLists.txt +++ b/be/src/vec/CMakeLists.txt @@ -206,6 +206,7 @@ set(VEC_FILES functions/array/function_array_zip.cpp functions/array/function_array_pushfront.cpp functions/array/function_array_first_index.cpp + functions/array/function_array_cum_sum.cpp functions/function_map.cpp functions/function_struct.cpp exprs/table_function/vexplode_json_array.cpp diff --git a/be/src/vec/functions/array/function_array_cum_sum.cpp b/be/src/vec/functions/array/function_array_cum_sum.cpp new file mode 100644 index 0000000000..4201fe4f27 --- /dev/null +++ b/be/src/vec/functions/array/function_array_cum_sum.cpp @@ -0,0 +1,247 @@ +// 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. +// This file is copied from +// https://github.com/ClickHouse/ClickHouse/blob/master/src/Functions/array/arrayCumSum.cpp +// and modified by Doris + +#include "vec/columns/column.h" +#include "vec/columns/column_array.h" +#include "vec/core/types.h" +#include "vec/data_types/data_type.h" +#include "vec/data_types/data_type_array.h" +#include "vec/data_types/data_type_decimal.h" +#include "vec/data_types/data_type_nullable.h" +#include "vec/data_types/data_type_number.h" +#include "vec/functions/function.h" +#include "vec/functions/simple_function_factory.h" +#include "vec/utils/util.hpp" + +namespace doris::vectorized { + +// array_cum_sum([1, 2, 3, 4, 5]) -> [1, 3, 6, 10, 15] +// array_cum_sum([1, NULL, 3, NULL, 5]) -> [1, NULL, 4, NULL, 9] +class FunctionArrayCumSum : public IFunction { +public: + using NullMapType = PaddedPODArray; + + static constexpr auto name = "array_cum_sum"; + + static FunctionPtr create() { return std::make_shared(); } + + String get_name() const override { return name; } + + bool is_variadic() const override { return false; } + + size_t get_number_of_arguments() const override { return 1; } + + DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { + DCHECK(is_array(arguments[0])) + << "argument for function: " << name << " should be DataTypeArray but it has type " + << arguments[0]->get_name() << "."; + auto nested_type = assert_cast(*(arguments[0])).get_nested_type(); + + auto non_null_nested_type = remove_nullable(nested_type); + auto scale = get_decimal_scale(*non_null_nested_type); + WhichDataType which(non_null_nested_type); + + //return type is promoted to prevent result overflow + //like: input is int32 ---> return type will be int64 + DataTypePtr return_type = nullptr; + + // same cast logic as array_sum + if (which.is_uint8() || which.is_int8() || which.is_uint16() || which.is_int16() || + which.is_uint32() || which.is_int32() || which.is_int64() || which.is_uint64()) { + return_type = std::make_shared(); + } else if (which.is_int128()) { + return_type = std::make_shared(); + } else if (which.is_float32() || which.is_float64()) { + return_type = std::make_shared(); + } else if (which.is_decimal128() && !which.is_decimal128i()) { + // decimalv2 + return_type = std::make_shared>( + DataTypeDecimal::max_precision(), scale); + } else if (which.is_decimal()) { + return_type = std::make_shared>( + DataTypeDecimal::max_precision(), scale); + } + if (return_type) { + return std::make_shared(make_nullable(return_type)); + } else { + LOG(FATAL) << "Function of " << name + << " return type get wrong: and input argument is: " + << arguments[0]->get_name(); + } + + return nullptr; + } + + Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, + const size_t result, size_t input_rows_count) override { + auto src_arg = block.get_by_position(arguments[0]); + ColumnPtr src_column = src_arg.column->convert_to_full_column_if_const(); + + const auto& src_column_array = check_and_get_column(src_column.get()); + if (!src_column_array) { + return Status::RuntimeError( + fmt::format("unsupported types for function {}({})", get_name(), + block.get_by_position(arguments[0]).type->get_name())); + } + + const auto& src_offsets = src_column_array->get_offsets(); + const auto* src_nested_column = &src_column_array->get_data(); + DCHECK(src_nested_column != nullptr); + + // get src nested column + auto src_nested_type = assert_cast(*src_arg.type).get_nested_type(); + + // get null map + const ColumnNullable* src_nested_nullable_col = + check_and_get_column(*src_nested_column); + src_nested_column = src_nested_nullable_col->get_nested_column_ptr(); + const NullMapType& src_null_map = src_nested_nullable_col->get_null_map_column().get_data(); + + ColumnPtr res_nested_ptr; + auto res_val = _execute_by_type(src_nested_type, *src_nested_column, src_offsets, + src_null_map, res_nested_ptr); + if (!res_val) { + return Status::RuntimeError( + fmt::format("execute failed or unsupported types for function {}({})", + get_name(), block.get_by_position(arguments[0]).type->get_name())); + } + + ColumnPtr res_array_ptr = + ColumnArray::create(res_nested_ptr, src_column_array->get_offsets_ptr()); + + block.replace_by_position(result, std::move(res_array_ptr)); + return Status::OK(); + } + +private: + bool _execute_by_type(DataTypePtr src_nested_type, const IColumn& src_column, + const ColumnArray::Offsets64& src_offsets, + const NullMapType& src_null_map, ColumnPtr& res_nested_ptr) { + bool res = false; + WhichDataType which(remove_nullable(src_nested_type)); + if (which.is_uint8()) { + res = _execute_number(src_column, src_offsets, src_null_map, + res_nested_ptr); + } else if (which.is_int8()) { + res = _execute_number(src_column, src_offsets, src_null_map, + res_nested_ptr); + } else if (which.is_int16()) { + res = _execute_number(src_column, src_offsets, src_null_map, + res_nested_ptr); + } else if (which.is_int32()) { + res = _execute_number(src_column, src_offsets, src_null_map, + res_nested_ptr); + } else if (which.is_int64()) { + res = _execute_number(src_column, src_offsets, src_null_map, + res_nested_ptr); + } else if (which.is_int128()) { + res = _execute_number(src_column, src_offsets, src_null_map, + res_nested_ptr); + } else if (which.is_float32()) { + res = _execute_number(src_column, src_offsets, src_null_map, + res_nested_ptr); + } else if (which.is_float64()) { + res = _execute_number(src_column, src_offsets, src_null_map, + res_nested_ptr); + } else if (which.is_decimal32()) { + res = _execute_number(src_column, src_offsets, src_null_map, + res_nested_ptr); + } else if (which.is_decimal64()) { + res = _execute_number(src_column, src_offsets, src_null_map, + res_nested_ptr); + } else if (which.is_decimal128i()) { + res = _execute_number(src_column, src_offsets, src_null_map, + res_nested_ptr); + } else if (which.is_decimal128()) { + res = _execute_number(src_column, src_offsets, src_null_map, + res_nested_ptr); + } + + return res; + } + + template + bool _execute_number(const IColumn& src_column, const ColumnArray::Offsets64& src_offsets, + const NullMapType& src_null_map, ColumnPtr& res_nested_ptr) { + using ColVecType = ColumnVectorOrDecimal; + using ColVecResult = ColumnVectorOrDecimal; + + // 1. get pod array from src + auto src_column_concrete = reinterpret_cast(&src_column); + if (!src_column_concrete) { + return false; + } + + // 2. construct result data + typename ColVecResult::MutablePtr res_nested_mut_ptr = nullptr; + if constexpr (IsDecimalNumber) { + res_nested_mut_ptr = ColVecResult::create(0, src_column_concrete->get_scale()); + } else { + res_nested_mut_ptr = ColVecResult::create(); + } + + // get result data pod array + auto size = src_column.size(); + auto& res_datas = res_nested_mut_ptr->get_data(); + res_datas.resize(size); + + _compute_cum_sum(src_column_concrete->get_data(), src_offsets, + src_null_map, res_datas); + + auto res_null_map_col = ColumnUInt8::create(size, 0); + auto& res_null_map = res_null_map_col->get_data(); + VectorizedUtils::update_null_map(res_null_map, src_null_map); + res_nested_ptr = + ColumnNullable::create(std::move(res_nested_mut_ptr), std::move(res_null_map_col)); + + return true; + } + + template + void _compute_cum_sum(const PaddedPODArray& src_datas, + const ColumnArray::Offsets64& src_offsets, + const NullMapType& src_null_map, PaddedPODArray& res_datas) { + size_t prev_offset = 0; + for (auto cur_offset : src_offsets) { + // [1, null, 2, 3] -> [1, null, 3, 6] + // [null, null, 1, 2, 3] -> [null, null, 1, 3, 6] + Result accumulated {}; + + for (size_t pos = prev_offset; pos < cur_offset; ++pos) { + // skip null value + if (src_null_map[pos]) { + res_datas[pos] = Result {}; + continue; + } + + accumulated += src_datas[pos]; + res_datas[pos] = accumulated; + } + + prev_offset = cur_offset; + } + } +}; + +void register_function_array_cum_sum(SimpleFunctionFactory& factory) { + factory.register_function(); +} + +} // namespace doris::vectorized \ No newline at end of file diff --git a/be/src/vec/functions/array/function_array_register.cpp b/be/src/vec/functions/array/function_array_register.cpp index f25223ccff..9ac2983ef7 100644 --- a/be/src/vec/functions/array/function_array_register.cpp +++ b/be/src/vec/functions/array/function_array_register.cpp @@ -51,6 +51,7 @@ void register_function_array_concat(SimpleFunctionFactory&); void register_function_array_zip(SimpleFunctionFactory&); void register_function_array_pushfront(SimpleFunctionFactory& factory); void register_function_array_first_index(SimpleFunctionFactory& factory); +void register_function_array_cum_sum(SimpleFunctionFactory& factory); void register_function_array(SimpleFunctionFactory& factory) { register_function_array_shuffle(factory); @@ -82,6 +83,7 @@ void register_function_array(SimpleFunctionFactory& factory) { register_function_array_zip(factory); register_function_array_pushfront(factory); register_function_array_first_index(factory); + register_function_array_cum_sum(factory); } } // namespace doris::vectorized diff --git a/docs/en/docs/sql-manual/sql-functions/array-functions/array_cum_sum.md b/docs/en/docs/sql-manual/sql-functions/array-functions/array_cum_sum.md new file mode 100644 index 0000000000..69f7333623 --- /dev/null +++ b/docs/en/docs/sql-manual/sql-functions/array-functions/array_cum_sum.md @@ -0,0 +1,70 @@ +--- +{ + "title": "array_cum_sum", + "language": "en" +} +--- + + + +## array_cum_sum + + + +array_cum_sum + + + +### description + +Get the cumulative sum of an array (`NULL` values are skipped). +If the array contains `NULL` values, then `NULL` is set at the same position in the result array. + +#### Syntax + +```sql +Array array_cum_sum(Array) +``` + +### notice + +`Only supported in vectorized engine` + +### example + +```shell +mysql> create table array_type_table(k1 INT, k2 Array) duplicate key (k1) distributed by hash(k1) buckets 1 properties('replication_num' = '1'); +mysql> insert into array_type_table values (0, []), (1, [NULL]), (2, [1, 2, 3, 4]), (3, [1, NULL, 3, NULL, 5]); +mysql> set enable_vectorized_engine = true; # enable vectorized engine +mysql> select k2, array_cum_sum(k2) from array_type_table; ++-----------------------+-----------------------+ +| k2 | array_cum_sum(`k2`) | ++-----------------------+-----------------------+ +| [] | [] | +| [NULL] | [NULL] | +| [1, 2, 3, 4] | [1, 3, 6, 10] | +| [1, NULL, 3, NULL, 5] | [1, NULL, 4, NULL, 9] | ++-----------------------+-----------------------+ + +4 rows in set +Time: 0.122s +``` + +### keywords + +ARRAY,CUM_SUM,ARRAY_CUM_SUM \ No newline at end of file diff --git a/docs/sidebars.json b/docs/sidebars.json index d278bb7bcb..efe810a61f 100644 --- a/docs/sidebars.json +++ b/docs/sidebars.json @@ -301,6 +301,7 @@ "sql-manual/sql-functions/array-functions/array_concat", "sql-manual/sql-functions/array-functions/array_zip", "sql-manual/sql-functions/array-functions/array_shuffle", + "sql-manual/sql-functions/array-functions/array_cum_sum", "sql-manual/sql-functions/array-functions/array_exists", "sql-manual/sql-functions/array-functions/array_first_index", "sql-manual/sql-functions/array-functions/arrays_overlap", diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/array-functions/array_cum_sum.md b/docs/zh-CN/docs/sql-manual/sql-functions/array-functions/array_cum_sum.md new file mode 100644 index 0000000000..c7ad479943 --- /dev/null +++ b/docs/zh-CN/docs/sql-manual/sql-functions/array-functions/array_cum_sum.md @@ -0,0 +1,69 @@ +--- +{ + "title": "array_cum_sum", + "language": "zh-CN" +} +--- + + + +## array_cum_sum + + + +array_cum_sum + + + +### description + +返回数组的累计和。数组中的`NULL`值会被跳过,并在结果数组的相同位置设置`NULL`。 + +#### Syntax + +```sql +Array array_cum_sum(Array) +``` + +### notice + +`仅支持向量化引擎中使用` + +### example + +```shell +mysql> create table array_type_table(k1 INT, k2 Array) duplicate key (k1) distributed by hash(k1) buckets 1 properties('replication_num' = '1'); +mysql> insert into array_type_table values (0, []), (1, [NULL]), (2, [1, 2, 3, 4]), (3, [1, NULL, 3, NULL, 5]); +mysql> set enable_vectorized_engine = true; # enable vectorized engine +mysql> select k2, array_cum_sum(k2) from array_type_table; ++-----------------------+-----------------------+ +| k2 | array_cum_sum(`k2`) | ++-----------------------+-----------------------+ +| [] | [] | +| [NULL] | [NULL] | +| [1, 2, 3, 4] | [1, 3, 6, 10] | +| [1, NULL, 3, NULL, 5] | [1, NULL, 4, NULL, 9] | ++-----------------------+-----------------------+ + +4 rows in set +Time: 0.122s +``` + +### keywords + +ARRAY,CUM_SUM,ARRAY_CUM_SUM 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 a027944747..6908b64fae 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 @@ -154,6 +154,19 @@ public class FunctionCallExpr extends Expr { return returnType; } }; + java.util.function.BiFunction, Type, Type> arrayDecimal128ArrayRule + = (children, returnType) -> { + Preconditions.checkArgument(children != null && children.size() > 0); + if (children.get(0).getType().isArrayType() && ( + ((ArrayType) children.get(0).getType()).getItemType().isDecimalV3())) { + ArrayType childArrayType = (ArrayType) children.get(0).getType(); + Type itemType = ScalarType.createDecimalV3Type(ScalarType.MAX_DECIMAL128_PRECISION, + ((ScalarType) childArrayType.getItemType()).getScalarScale()); + return ArrayType.create(itemType, childArrayType.getContainsNull()); + } else { + return returnType; + } + }; PRECISION_INFER_RULE = new HashMap<>(); PRECISION_INFER_RULE.put("sum", sumRule); PRECISION_INFER_RULE.put("multi_distinct_sum", sumRule); @@ -192,6 +205,7 @@ public class FunctionCallExpr extends Expr { PRECISION_INFER_RULE.put("array_avg", arrayDecimal128Rule); PRECISION_INFER_RULE.put("array_sum", arrayDecimal128Rule); PRECISION_INFER_RULE.put("array_product", arrayDecimal128Rule); + PRECISION_INFER_RULE.put("array_cum_sum", arrayDecimal128ArrayRule); PRECISION_INFER_RULE.put("round", roundRule); PRECISION_INFER_RULE.put("round_bankers", roundRule); PRECISION_INFER_RULE.put("ceil", roundRule); @@ -1089,6 +1103,7 @@ public class FunctionCallExpr extends Expr { || fnName.getFunction().equalsIgnoreCase("array_product") || fnName.getFunction().equalsIgnoreCase("array_union") || fnName.getFunction().equalsIgnoreCase("array_except") + || fnName.getFunction().equalsIgnoreCase("array_cum_sum") || fnName.getFunction().equalsIgnoreCase("array_intersect") || fnName.getFunction().equalsIgnoreCase("arrays_overlap") || fnName.getFunction().equalsIgnoreCase("array_concat")) { @@ -1554,6 +1569,7 @@ public class FunctionCallExpr extends Expr { || fnName.getFunction().equalsIgnoreCase("array_popback") || fnName.getFunction().equalsIgnoreCase("array_popfront") || fnName.getFunction().equalsIgnoreCase("array_pushfront") + || fnName.getFunction().equalsIgnoreCase("array_cum_sum") || fnName.getFunction().equalsIgnoreCase("reverse") || fnName.getFunction().equalsIgnoreCase("%element_slice%") || fnName.getFunction().equalsIgnoreCase("array_concat") @@ -1628,7 +1644,9 @@ public class FunctionCallExpr extends Expr { fn.setReturnType(Type.MAX_DECIMALV2_TYPE); } - if (this.type.isDecimalV3() || (this.type.isDatetimeV2() + if (this.type.isDecimalV3() || (this.type.isArrayType() + && ((ArrayType) this.type).getItemType().isDecimalV3()) + || (this.type.isDatetimeV2() && !TIME_FUNCTIONS_WITH_PRECISION.contains(fnName.getFunction().toLowerCase()))) { // TODO(gabriel): If type exceeds max precision of DECIMALV3, we should change // it to a double function diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index 0413bcd3b6..a2c839d42f 100644 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -160,6 +160,18 @@ visible_functions = [ [['array_contains'], 'BOOLEAN', ['ARRAY_VARCHAR', 'VARCHAR'], 'ALWAYS_NULLABLE'], [['array_contains'], 'BOOLEAN', ['ARRAY_STRING', 'STRING'], 'ALWAYS_NULLABLE'], + [['array_cum_sum'], 'ARRAY_BIGINT', ['ARRAY_TINYINT'], ''], + [['array_cum_sum'], 'ARRAY_BIGINT', ['ARRAY_SMALLINT'], ''], + [['array_cum_sum'], 'ARRAY_BIGINT', ['ARRAY_INT'], ''], + [['array_cum_sum'], 'ARRAY_BIGINT', ['ARRAY_BIGINT'], ''], + [['array_cum_sum'], 'ARRAY_LARGEINT', ['ARRAY_LARGEINT'], ''], + [['array_cum_sum'], 'ARRAY_DOUBLE', ['ARRAY_FLOAT'], ''], + [['array_cum_sum'], 'ARRAY_DOUBLE', ['ARRAY_DOUBLE'], ''], + [['array_cum_sum'], 'ARRAY_DECIMALV2', ['ARRAY_DECIMALV2'], ''], + [['array_cum_sum'], 'ARRAY_DECIMAL128', ['ARRAY_DECIMAL32'], ''], + [['array_cum_sum'], 'ARRAY_DECIMAL128', ['ARRAY_DECIMAL64'], ''], + [['array_cum_sum'], 'ARRAY_DECIMAL128', ['ARRAY_DECIMAL128'], ''], + [['array_enumerate'], 'ARRAY_BIGINT', ['ARRAY_BOOLEAN'], ''], [['array_enumerate'], 'ARRAY_BIGINT', ['ARRAY_TINYINT'], ''], [['array_enumerate'], 'ARRAY_BIGINT', ['ARRAY_SMALLINT'], ''], diff --git a/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions.out b/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions.out index 228170dea7..40fbcdfa93 100644 --- a/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions.out +++ b/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions.out @@ -1286,6 +1286,28 @@ 8 \N 9 \N +-- !select -- +1 [1, 3, 6] [1, 3] +2 [4] [5] +3 [] \N +4 [1, 3, 6, 10, 15, 19, 22, 24, 25] [] +5 [] \N +6 [1, 3, 6, 10, 15, 19, 22, 24, 25] \N +7 [8, 17, NULL, 27, NULL] \N +8 [1, 3, 6, 9, 13, 17, NULL] [1, 3, 5, 8] +9 [1, 3, 6] [1, 3] + +-- !select -- +1 [111.111, 333.333] [222.222, 555.555] +2 [3333.333, 7777.777] [4444.444, 9999.999] +3 \N \N +4 \N \N +5 \N \N +6 \N \N +7 \N \N +8 \N \N +9 \N \N + -- !select -- \N \N -1 \N diff --git a/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_by_literal.out b/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_by_literal.out index c9806ef1d7..54371b7131 100644 --- a/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_by_literal.out +++ b/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_by_literal.out @@ -827,3 +827,48 @@ _ -- !sql -- [333.333, 111.111, 222.222] +-- !sql -- +[0, 2, 129] + +-- !sql -- +[254, 258, 258] + +-- !sql -- +[1, 3.1, 6.3, 10.6, 16] + +-- !sql -- +[-1, 1, -2, 2, -3] + +-- !sql -- +[-5.23, -1.11, -4.13, -2.13, -1.12] + +-- !sql -- +[1, 3, 6, NULL] + +-- !sql -- +[NULL, 1, NULL, 4, 12, NULL] + +-- !sql -- +[NULL, NULL] + +-- !sql -- +[8] + +-- !sql -- +[1.1] + +-- !sql -- +[NULL] + +-- !sql -- +[] + +-- !sql -- +[12.99, 47.98, 1047.26] + +-- !sql -- +[111.111, 333.333] + +-- !sql -- +[111.9999, 334.0000] + diff --git a/regression-test/data/query_p0/sql_functions/array_functions/test_array_with_scale_type.out b/regression-test/data/query_p0/sql_functions/array_functions/test_array_with_scale_type.out index 53aecd35b2..2232f54770 100644 --- a/regression-test/data/query_p0/sql_functions/array_functions/test_array_with_scale_type.out +++ b/regression-test/data/query_p0/sql_functions/array_functions/test_array_with_scale_type.out @@ -154,3 +154,16 @@ 22.678 [22.678, 33.6789] [22.678, 22.678, 33.6789] 23.678 [23.678, 34.6789] [23.678, 23.678, 34.6789] +-- !select -- +[22, 11] + +-- !select -- +[22.99, 11] + +-- !select -- +[22.99, 10.999] + +-- !select -- +[22.678, 56.3569] +[23.678, 58.3569] + diff --git a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions.groovy b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions.groovy index 34a791b4f2..ed4550076a 100644 --- a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions.groovy +++ b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions.groovy @@ -171,6 +171,9 @@ suite("test_array_functions") { qt_select "SELECT k1, array_zip(k10, k10) FROM ${tableName} ORDER BY k1" qt_select "SELECT k1, array_zip(k11, k11, k11, k11) FROM ${tableName} ORDER BY k1" + qt_select "SELECT k1, array_cum_sum(k2), array_cum_sum(k4) FROM ${tableName} ORDER BY k1" + qt_select "SELECT k1, array_cum_sum(k12), array_cum_sum(k13) FROM ${tableName} ORDER BY k1" + def tableName2 = "tbl_test_array_range" sql """DROP TABLE IF EXISTS ${tableName2}""" sql """ diff --git a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_by_literal.groovy b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_by_literal.groovy index c5efa833d7..a1c7bbd3a6 100644 --- a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_by_literal.groovy +++ b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_by_literal.groovy @@ -335,6 +335,23 @@ suite("test_array_functions_by_literal") { qt_sql "select array_pushfront(array(cast ('2023-03-05 12:23:24.999' as datetimev2(3)),cast ('2023-03-05 15:23:23.997' as datetimev2(3))), cast ('2023-03-08 16:23:54.999' as datetimev2(3)))" qt_sql "select array_pushfront(array(cast (111.111 as decimalv3(6,3)),cast (222.222 as decimalv3(6,3))), cast (333.333 as decimalv3(6,3)))" + // array_cum_sum + qt_sql "select array_cum_sum([0, 2, 127])" + qt_sql "select array_cum_sum([254, 4, 0])" + qt_sql "select array_cum_sum([1.0, 2.1 ,3.2, 4.3, 5.4])" + qt_sql "select array_cum_sum([-1, 2 ,-3, 4, -5])" + qt_sql "select array_cum_sum([-5.23, 4.12, -3.02, 2.00 ,1.01])" + qt_sql "select array_cum_sum([1, 2, 3, null])" + qt_sql "select array_cum_sum([null, 1, null, 3, 8, null])" + qt_sql "select array_cum_sum([null, null])" + qt_sql "select array_cum_sum([8])" + qt_sql "select array_cum_sum([1.1])" + qt_sql "select array_cum_sum([null])" + qt_sql "select array_cum_sum([])" + qt_sql "select array_cum_sum(array(cast (12.99 as decimal(10,3)), cast (34.99 as decimal(10,3)), cast (999.28 as decimal(10,3))))" + qt_sql "select array_cum_sum(array(cast (111.111 as decimalv3(6,3)),cast (222.222 as decimalv3(6,3))))" + qt_sql "select array_cum_sum(array(cast (111.9999 as decimalv3(6,4)),cast (222.0001 as decimalv3(6,4))))" + // abnormal test try { sql "select array_intersect([1, 2, 3, 1, 2, 3], '1[3, 2, 5]')" diff --git a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_with_scale_type.groovy b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_with_scale_type.groovy index 9bc37196d1..ea18080b64 100644 --- a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_with_scale_type.groovy +++ b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_with_scale_type.groovy @@ -90,5 +90,10 @@ suite("test_array_with_scale_type") { qt_select "select array_pushfront(c_array_decimal, cast (25.99 as decimalv3(10,3))) from ${tableName}" qt_select "select c_decimal, c_array_decimal, array_pushfront(c_array_decimal, c_decimal) from ${tableName}" + qt_select "select array_cum_sum(array(cast (22.99 as decimal), cast (-11.99 as decimal)))" + qt_select "select array_cum_sum(array(cast (22.99 as decimal(10,3)), cast (-11.99 as decimal(10,3))))" + qt_select "select array_cum_sum(array(cast (22.99 as decimal(10,6)), cast (-11.991 as decimal(10,6))))" + qt_select "select array_cum_sum(c_array_decimal) from ${tableName}" + sql "DROP TABLE IF EXISTS ${tableName}" } \ No newline at end of file