This is an automated email from the ASF dual-hosted git repository.
zhangstar333 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 d848afbd63d [Enhancement] (doris-future) Support auto partition name
function (#34258)
d848afbd63d is described below
commit d848afbd63dc5359c28db5f5e1af81793b9cc42c
Author: Uniqueyou <[email protected]>
AuthorDate: Mon Aug 5 11:38:13 2024 +0800
[Enhancement] (doris-future) Support auto partition name function (#34258)
## Proposed changes
Issue Number: #34130
---
be/src/vec/functions/function_string.cpp | 1 +
be/src/vec/functions/function_string.h | 215 +++++++++++++++++++++
.../doris/catalog/BuiltinScalarFunctions.java | 2 +
.../functions/scalar/AutoPartitionName.java | 105 ++++++++++
.../expressions/visitor/ScalarFunctionVisitor.java | 5 +
gensrc/script/doris_builtins_functions.py | 2 +
.../data/nereids_function_p0/scalar_function/A.out | 129 +++++++++++++
.../nereids_function_p0/scalar_function/A.groovy | 72 +++++++
8 files changed, 531 insertions(+)
diff --git a/be/src/vec/functions/function_string.cpp
b/be/src/vec/functions/function_string.cpp
index 223d32a5682..30384413d1d 100644
--- a/be/src/vec/functions/function_string.cpp
+++ b/be/src/vec/functions/function_string.cpp
@@ -1010,6 +1010,7 @@ void register_function_string(SimpleFunctionFactory&
factory) {
factory.register_function<FunctionStringLocate>();
factory.register_function<FunctionStringLocatePos>();
factory.register_function<FunctionQuote>();
+ factory.register_function<FunctionAutoPartitionName>();
factory.register_function<FunctionReverseCommon>();
factory.register_function<FunctionUnHex>();
factory.register_function<FunctionToLower>();
diff --git a/be/src/vec/functions/function_string.h
b/be/src/vec/functions/function_string.h
index 22eeb93591f..1c843acb697 100644
--- a/be/src/vec/functions/function_string.h
+++ b/be/src/vec/functions/function_string.h
@@ -26,6 +26,7 @@
#include <array>
#include <boost/iterator/iterator_facade.hpp>
#include <cmath>
+#include <codecvt>
#include <cstddef>
#include <cstdlib>
#include <iomanip>
@@ -33,6 +34,7 @@
#include <memory>
#include <ostream>
#include <random>
+#include <regex>
#include <sstream>
#include <stdexcept>
#include <tuple>
@@ -70,6 +72,7 @@
#include "vec/core/field.h"
#include "vec/core/types.h"
#include "vec/data_types/data_type.h"
+#include "vec/functions/function_binary_arithmetic.h"
#include "vec/functions/round.h"
#include "vec/io/io_helper.h"
#include "vec/utils/template_helpers.hpp"
@@ -387,6 +390,218 @@ private:
}
};
+class FunctionAutoPartitionName : public IFunction {
+public:
+ static constexpr auto name = "auto_partition_name";
+ static FunctionPtr create() { return
std::make_shared<FunctionAutoPartitionName>(); }
+ String get_name() const override { return name; }
+ size_t get_number_of_arguments() const override { return 0; }
+ bool is_variadic() const override { return true; }
+
+ DataTypePtr get_return_type_impl(const DataTypes& arguments) const
override {
+ return std::make_shared<DataTypeString>();
+ }
+
+ Status execute_impl(FunctionContext* context, Block& block, const
ColumnNumbers& arguments,
+ size_t result, size_t input_rows_count) const override
{
+ size_t argument_size = arguments.size();
+ if (argument_size < 2) {
+ return Status::InvalidArgument(
+ "auto_partition_name must contains at least two
arguments");
+ }
+ std::vector<const ColumnString::Chars*> chars_list(argument_size);
+ std::vector<const ColumnString::Offsets*> offsets_list(argument_size);
+ std::vector<bool> is_const_args(argument_size);
+
+ for (int i = 0; i < argument_size; ++i) {
+ const auto& [col, is_const] =
+
unpack_if_const(block.get_by_position(arguments[i]).column);
+
+ const auto* col_str = assert_cast<const ColumnString*>(col.get());
+ chars_list[i] = &col_str->get_chars();
+ offsets_list[i] = &col_str->get_offsets();
+ is_const_args[i] = is_const;
+ }
+ auto res = ColumnString::create();
+ auto& res_data = res->get_chars();
+ auto& res_offset = res->get_offsets();
+ res_offset.resize(input_rows_count);
+
+ const char* partition_type = chars_list[0]->raw_data();
+ // partition type is list|range
+ if (std::strncmp(partition_type, "list", 4) == 0) {
+ return _auto_partition_type_of_list(chars_list, offsets_list,
is_const_args, res_data,
+ res_offset, input_rows_count,
argument_size, block,
+ result, res);
+ } else {
+ return _auto_partition_type_of_range(chars_list, offsets_list,
is_const_args, res_data,
+ res_offset, input_rows_count,
argument_size, block,
+ result, res);
+ }
+ return Status::OK();
+ }
+
+private:
+ std::u16string _string_to_u16string(const std::string& str) const {
+ std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>
convert;
+ return convert.from_bytes(str);
+ }
+
+ std::string _string_to_unicode(const std::u16string& s) const {
+ std::string res_s;
+ res_s.reserve(s.size());
+ if (s.length() > 0 && s[0] == '-') {
+ res_s += '_';
+ }
+ for (int i = 0; i < s.length(); i++) {
+ char ch = s[i];
+ if (std::isalnum(ch)) {
+ res_s += ch;
+ } else {
+ int unicodeValue = _get_code_point_at(s, i);
+ res_s += fmt::format("{:02x}",
static_cast<uint32_t>(unicodeValue));
+ }
+ }
+ return res_s;
+ }
+
+ int _get_code_point_at(const std::u16string& str, std::size_t index) const
{
+ char16_t first = str[index];
+ // [0xD800,0xDBFF] is the scope of the first code unit
+ if ((first >= 0xD800 && first <= 0xDBFF) && (index + 1 < str.size())) {
+ char16_t second = str[index + 1];
+ // [0xDC00,0xDFFF] is the scope of the second code unit
+ if (second >= 0xDC00 && second <= 0xDFFF) {
+ return ((first - 0xD800) << 10) + (second - 0xDC00) + 0x10000;
+ }
+ }
+
+ return first;
+ }
+ Status _auto_partition_type_of_list(std::vector<const
ColumnString::Chars*>& chars_list,
+ std::vector<const
ColumnString::Offsets*>& offsets_list,
+ std::vector<bool>& is_const_args,
auto& res_data,
+ auto& res_offset, size_t
input_rows_count,
+ size_t argument_size, Block& block,
size_t result,
+ auto& res) const {
+ int curr_len = 0;
+ for (int row = 0; row < input_rows_count; row++) {
+ std::string res_p;
+ res_p.reserve(argument_size * 5);
+ res_p += 'p';
+ for (int col = 1; col < argument_size; col++) {
+ const auto& current_offsets = *offsets_list[col];
+ const auto& current_chars = *chars_list[col];
+
+ auto idx = index_check_const(row, is_const_args[col]);
+ int size = current_offsets[idx] - current_offsets[idx - 1];
+ const char* raw_chars =
+ reinterpret_cast<const
char*>(¤t_chars[current_offsets[idx - 1]]);
+
+ // convert string to u16string in order to convert to unicode
strings
+ const std::string raw_str(raw_chars, size);
+ auto u16string = _string_to_u16string(raw_str);
+ res_p += _string_to_unicode(u16string) +
std::to_string(u16string.size());
+ }
+
+ // check the name of length
+ int len = res_p.size();
+ if (len > 50) [[unlikely]] {
+ return Status::InvalidArgument(
+ "The list partition name cannot exceed 50 characters");
+ }
+ curr_len += len;
+ res_data.resize(curr_len);
+ memcpy(&res_data[res_offset[row - 1]], res_p.c_str(), len);
+ res_offset[row] = res_offset[row - 1] + len;
+ }
+ block.get_by_position(result).column = std::move(res);
+ return Status::OK();
+ }
+
+ size_t _copy_date_str_of_len_to_res_data(auto& res_data, auto& res_offset,
+ std::vector<std::string>&
date_str, size_t row,
+ size_t len) const {
+ size_t curr_len = 1;
+ for (int j = 0; j < len; j++) {
+ memcpy(&res_data[res_offset[row - 1]] + curr_len,
date_str[j].c_str(),
+ date_str[j].size());
+ curr_len += date_str[j].size();
+ }
+ return curr_len;
+ }
+
+ Status _auto_partition_type_of_range(std::vector<const
ColumnString::Chars*>& chars_list,
+ std::vector<const
ColumnString::Offsets*>& offsets_list,
+ std::vector<bool>& is_const_args,
auto& res_data,
+ auto& res_offset, size_t
input_rows_count,
+ size_t argument_size, Block& block,
size_t result,
+ auto& res) const {
+ const char* range_type = chars_list[1]->raw_data();
+
+ res_data.resize(15 * input_rows_count);
+ for (int i = 0; i < input_rows_count; i++) {
+ const auto& current_offsets = *offsets_list[2];
+ const auto& current_chars = *chars_list[2];
+
+ auto idx = index_check_const(i, is_const_args[2]);
+ int size = current_offsets[idx] - current_offsets[idx - 1];
+ const char* tmp =
+ reinterpret_cast<const
char*>(¤t_chars[current_offsets[idx - 1]]);
+ std::string to_split_s(tmp, size);
+
+ // check the str if it is date|datetime
+ RE2 date_regex(R"(^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}:\d{2})?$)");
+ if (!RE2::FullMatch(to_split_s, date_regex)) {
+ return Status::InvalidArgument("The range partition only
support DATE|DATETIME");
+ }
+
+ // split date_str from (yyyy-mm-dd hh:mm:ss) to ([yyyy, mm, dd,
hh, mm, ss])
+ std::vector<std::string> date_str(6);
+ date_str[0] = to_split_s.substr(0, 4);
+ for (int i = 5, j = 1; i <= size; i += 3, j++) {
+ date_str[j] = to_split_s.substr(i, 2);
+ }
+ int curr_len = 0;
+
+ res_data[res_offset[i - 1]] = 'p';
+ // raw => 2022-12-12 11:30:20
+ // year => 2022 01 01 00 00 00
+ // month => 2022 12 01 00 00 00
+ // day => 2022 12 12 00 00 00
+ // hour => 2022 12 12 11 00 00
+ // minute => 2022 12 11 30 00
+ // second => 2022 12 12 12 30 20
+
+ if (!strncmp(range_type, "year", 4)) {
+ curr_len += _copy_date_str_of_len_to_res_data(res_data,
res_offset, date_str, i, 1);
+ memcpy(&res_data[res_offset[i - 1]] + curr_len, "0101", 4);
+ curr_len += 4;
+ } else if (!strncmp(range_type, "month", 5)) {
+ curr_len += _copy_date_str_of_len_to_res_data(res_data,
res_offset, date_str, i, 2);
+ memcpy(&res_data[res_offset[i - 1]] + curr_len, "01", 2);
+ curr_len += 2;
+ } else if (!strncmp(range_type, "day", 3)) {
+ curr_len += _copy_date_str_of_len_to_res_data(res_data,
res_offset, date_str, i, 3);
+ } else if (!strncmp(range_type, "hour", 4)) {
+ curr_len += _copy_date_str_of_len_to_res_data(res_data,
res_offset, date_str, i, 4);
+ } else if (!strncmp(range_type, "minute", 6)) {
+ curr_len += _copy_date_str_of_len_to_res_data(res_data,
res_offset, date_str, i, 5);
+ } else if (!strncmp(range_type, "second", 6)) {
+ curr_len += _copy_date_str_of_len_to_res_data(res_data,
res_offset, date_str, i, 6);
+ }
+
+ // fill in zero
+ int zero = 15 - curr_len;
+ std::fill_n(&res_data[res_offset[i - 1]] + curr_len, zero, '0');
+ curr_len += zero;
+ res_offset[i] = res_offset[i - 1] + curr_len;
+ }
+ block.get_by_position(result).column = std::move(res);
+ return Status::OK();
+ }
+};
+
template <typename Impl>
class FunctionSubstring : public IFunction {
public:
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
index b24c86f219f..cc0f8701716 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
@@ -75,6 +75,7 @@ import
org.apache.doris.nereids.trees.expressions.functions.scalar.Ascii;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Asin;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Atan;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Atan2;
+import
org.apache.doris.nereids.trees.expressions.functions.scalar.AutoPartitionName;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Bin;
import org.apache.doris.nereids.trees.expressions.functions.scalar.BitCount;
import org.apache.doris.nereids.trees.expressions.functions.scalar.BitLength;
@@ -528,6 +529,7 @@ public class BuiltinScalarFunctions implements
FunctionHelper {
scalar(Asin.class, "asin"),
scalar(Atan.class, "atan"),
scalar(Atan2.class, "atan2"),
+ scalar(AutoPartitionName.class, "auto_partition_name"),
scalar(Bin.class, "bin"),
scalar(BitCount.class, "bit_count"),
scalar(BitLength.class, "bit_length"),
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/AutoPartitionName.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/AutoPartitionName.java
new file mode 100644
index 00000000000..716cb0a6ee5
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/AutoPartitionName.java
@@ -0,0 +1,105 @@
+// 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.
+
+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.literal.VarcharLiteral;
+import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.StringType;
+import org.apache.doris.nereids.types.VarcharType;
+import org.apache.doris.nereids.util.ExpressionUtils;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+/**
+ * ScalarFunction 'auto_partition_name'. This class is not generated by
+ * GenerateFunction.
+ */
+public class AutoPartitionName extends ScalarFunction
+ implements UnaryExpression, ExplicitlyCastableSignature,
PropagateNullable {
+
+ public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).varArgs(VarcharType.SYSTEM_DEFAULT),
+
FunctionSignature.ret(StringType.INSTANCE).varArgs(StringType.INSTANCE));
+
+ /**
+ * constructor with 2 or 3 arguments.
+ */
+ public AutoPartitionName(Expression arg, Expression... varArgs) {
+ super("auto_partition_name", ExpressionUtils.mergeArguments(arg,
varArgs));
+ }
+
+ /**
+ * withChildren.
+ */
+ @Override
+ public AutoPartitionName withChildren(List<Expression> children) {
+ Preconditions.checkArgument(children.size() >= 2);
+ return new AutoPartitionName(children.get(0),
+ children.subList(1, children.size()).toArray(new
Expression[0]));
+ }
+
+ @Override
+ public void checkLegalityAfterRewrite() {
+ if (arity() < 2) {
+ throw new AnalysisException("function auto_partition_name must
contains at least two arguments");
+ }
+ if (!child(0).isLiteral()) {
+ throw new AnalysisException("auto_partition_name must accept
literal for 1nd argument");
+ }
+ final String partition_type = ((VarcharLiteral)
getArgument(0)).getStringValue().toLowerCase();
+ if (!Lists.newArrayList("range", "list").contains(partition_type)) {
+ throw new AnalysisException("function auto_partition_name must
accept range|list for 1nd argument");
+ } else if (Lists.newArrayList("range").contains(partition_type)) {
+ if (!child(1).isLiteral()) {
+ throw new AnalysisException("auto_partition_name must accept
literal for 2nd argument");
+ } else {
+ final String range_partition_type = ((VarcharLiteral)
getArgument(1)).getStringValue()
+ .toLowerCase();
+ if (arity() != 3) {
+ throw new AnalysisException("range auto_partition_name
must contains three arguments");
+ }
+ if (!Lists.newArrayList("year", "month", "day", "hour",
"minute", "second")
+ .contains(range_partition_type)) {
+ throw new AnalysisException(
+ "range auto_partition_name must accept
year|month|day|hour|minute|second for 2nd argument");
+ }
+ }
+
+ }
+ }
+
+ @Override
+ public List<FunctionSignature> getSignatures() {
+ return SIGNATURES;
+ }
+
+ @Override
+ public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitAutoPartitionName(this, context);
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
index 51ffe642510..5a76d49d567 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
@@ -82,6 +82,7 @@ import
org.apache.doris.nereids.trees.expressions.functions.scalar.Ascii;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Asin;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Atan;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Atan2;
+import
org.apache.doris.nereids.trees.expressions.functions.scalar.AutoPartitionName;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Bin;
import org.apache.doris.nereids.trees.expressions.functions.scalar.BitCount;
import org.apache.doris.nereids.trees.expressions.functions.scalar.BitLength;
@@ -708,6 +709,10 @@ public interface ScalarFunctionVisitor<R, C> {
return visitScalarFunction(atan2, context);
}
+ default R visitAutoPartitionName(AutoPartitionName autoPartitionName, C
context) {
+ return visitScalarFunction(autoPartitionName, context);
+ }
+
default R visitBin(Bin bin, C context) {
return visitScalarFunction(bin, context);
}
diff --git a/gensrc/script/doris_builtins_functions.py
b/gensrc/script/doris_builtins_functions.py
index 7328355ce7a..3a4d1e57781 100644
--- a/gensrc/script/doris_builtins_functions.py
+++ b/gensrc/script/doris_builtins_functions.py
@@ -1626,6 +1626,7 @@ visible_functions = {
[['lower', 'lcase'], 'VARCHAR', ['VARCHAR'], ''],
[['upper', 'ucase'], 'VARCHAR', ['VARCHAR'], ''],
[['quote'], 'VARCHAR', ['VARCHAR'], ''],
+ [['auto_partition_name'], 'VARCHAR', ['VARCHAR', '...'], ''],
[['initcap'], 'VARCHAR', ['VARCHAR'], ''],
[['trim'], 'VARCHAR', ['VARCHAR','VARCHAR'], ''],
[['trim'], 'VARCHAR', ['VARCHAR'], ''],
@@ -1701,6 +1702,7 @@ visible_functions = {
[['ltrim'], 'STRING', ['STRING','STRING'], ''],
[['rtrim'], 'STRING', ['STRING'], ''],
[['rtrim'], 'STRING', ['STRING','STRING'], ''],
+ [['auto_partition_name'], 'STRING', ['STRING', '...'], ''],
[['ascii'], 'INT', ['STRING'], ''],
[['instr'], 'INT', ['STRING', 'STRING'], ''],
[['locate'], 'INT', ['STRING', 'STRING'], ''],
diff --git a/regression-test/data/nereids_function_p0/scalar_function/A.out
b/regression-test/data/nereids_function_p0/scalar_function/A.out
index 20ad9d7fd19..a08da4e70f4 100644
--- a/regression-test/data/nereids_function_p0/scalar_function/A.out
+++ b/regression-test/data/nereids_function_p0/scalar_function/A.out
@@ -469,3 +469,132 @@
0.7378150601204648
0.6947382761967031
+-- !sql_auto_partition_name_list_column_type_mixed --
+pchar11601
+pchar12601
+pchar13601
+
+-- !sql_auto_partition_name_list_column_literal_mixed --
+pstring17hello5
+pstring27hello5
+pstring37hello5
+
+-- !sql_auto_partition_name_list_column --
+pchar116varchar119
+pchar126varchar129
+pchar136varchar139
+
+-- !sql_auto_partition_name_list_literal_empty --
+p0
+
+-- !sql_auto_partition_name_list_literal_mixed --
+p4f60597d21101
+
+-- !sql_auto_partition_name_list_literal_mixed --
+p_2dhello6
+
+-- !sql_auto_partition_name_list_literal_mixed --
+p4023ffe5257e7cworld111112e2e2e2e20
+
+-- !sql_auto_partition_name_range_literal_notnull --
+p20221212000000
+
+-- !sql_auto_partition_name_range_literal_notnull --
+p20221201000000
+
+-- !sql_auto_partition_name_range_literal_notnull --
+p20220101000000
+
+-- !sql_auto_partition_name_range_literal_notnull --
+p20221212190000
+
+-- !sql_auto_partition_name_range_literal_notnull --
+p20221212192000
+
+-- !sql_auto_partition_name_range_literal_notnull --
+p20221212192030
+
+-- !sql_auto_partition_name_range_notnull --
+p20120301000000
+p20120302000000
+p20120303000000
+p20120304000000
+p20120305000000
+p20120306000000
+p20120307000000
+p20120308000000
+p20120309000000
+p20120310000000
+p20120311000000
+p20120312000000
+
+-- !sql_auto_partition_name_range_notnull --
+p20120301000000
+p20120301000000
+p20120301000000
+p20120301000000
+p20120301000000
+p20120301000000
+p20120301000000
+p20120301000000
+p20120301000000
+p20120301000000
+p20120301000000
+p20120301000000
+
+-- !sql_auto_partition_name_range_notnull --
+p20120101000000
+p20120101000000
+p20120101000000
+p20120101000000
+p20120101000000
+p20120101000000
+p20120101000000
+p20120101000000
+p20120101000000
+p20120101000000
+p20120101000000
+p20120101000000
+
+-- !sql_auto_partition_name_range_notnull --
+p20120301000000
+p20120302000000
+p20120303000000
+p20120304000000
+p20120305000000
+p20120306000000
+p20120307000000
+p20120308000000
+p20120309000000
+p20120310000000
+p20120311000000
+p20120312000000
+
+-- !sql_auto_partition_name_range_notnull --
+p20120301000000
+p20120302000000
+p20120303000000
+p20120304000000
+p20120305000000
+p20120306000000
+p20120307000000
+p20120308000000
+p20120309000000
+p20120310000000
+p20120311000000
+p20120312000000
+
+-- !sql_auto_partition_name_range_notnull --
+p20120301000000
+p20120302000000
+p20120303000000
+p20120304000000
+p20120305000000
+p20120306000000
+p20120307000000
+p20120308000000
+p20120309000000
+p20120310000000
+p20120311000000
+p20120312000000
+
diff --git
a/regression-test/suites/nereids_function_p0/scalar_function/A.groovy
b/regression-test/suites/nereids_function_p0/scalar_function/A.groovy
index 4ae51024d34..8ccdd31102e 100644
--- a/regression-test/suites/nereids_function_p0/scalar_function/A.groovy
+++ b/regression-test/suites/nereids_function_p0/scalar_function/A.groovy
@@ -77,4 +77,76 @@ suite("nereids_scalar_fn_A") {
qt_sql_atan_Double_notnull "select atan(kdbl) from fn_test_not_nullable
order by kdbl"
qt_sql_atan2_Double "select atan2(kdbl, kdbl*kdbl) from fn_test order
by kdbl"
qt_sql_atan2_Double_notnull "select atan2(kdbl, kdbl*kdbl) from
fn_test_not_nullable order by kdbl"
+ qt_sql_auto_partition_name_list_column_type_mixed "select
auto_partition_name('list', kchrs1, kbool) from fn_test_not_nullable where id <
3 order by kchrs1"
+ qt_sql_auto_partition_name_list_column_literal_mixed "select
auto_partition_name('list', kstr, 'hello') from fn_test_not_nullable where id <
3 order by kstr"
+ qt_sql_auto_partition_name_list_column "select
auto_partition_name('list', kchrs1, kvchrs1) from fn_test_not_nullable where id
< 3 order by kchrs1"
+ qt_sql_auto_partition_name_list_literal_empty "select
auto_partition_name('list', '')"
+ qt_sql_auto_partition_name_list_literal_mixed "select
auto_partition_name('list', '你好', true, false)"
+ qt_sql_auto_partition_name_list_literal_mixed "select
auto_partition_name('list', '-hello')"
+ qt_sql_auto_partition_name_list_literal_mixed "select
auto_partition_name('list', '@#¥%~|world11111....')"
+ qt_sql_auto_partition_name_range_literal_notnull "select
auto_partition_name('range', 'day', '2022-12-12 19:20:30')"
+ qt_sql_auto_partition_name_range_literal_notnull "select
auto_partition_name('range', 'month', '2022-12-12 19:20:30')"
+ qt_sql_auto_partition_name_range_literal_notnull "select
auto_partition_name('range', 'year', '2022-12-12 19:20:30')"
+ qt_sql_auto_partition_name_range_literal_notnull "select
auto_partition_name('range', 'hour', '2022-12-12 19:20:30')"
+ qt_sql_auto_partition_name_range_literal_notnull "select
auto_partition_name('range', 'minute', '2022-12-12 19:20:30')"
+ qt_sql_auto_partition_name_range_literal_notnull "select
auto_partition_name('range', 'second', '2022-12-12 19:20:30')"
+ qt_sql_auto_partition_name_range_notnull "select
auto_partition_name('range', 'day', kdt) from fn_test_not_nullable order by kdt"
+ qt_sql_auto_partition_name_range_notnull "select
auto_partition_name('range', 'month', kdt) from fn_test_not_nullable order by
kdt"
+ qt_sql_auto_partition_name_range_notnull "select
auto_partition_name('range', 'year', kdt) from fn_test_not_nullable order by
kdt"
+ qt_sql_auto_partition_name_range_notnull "select
auto_partition_name('range', 'hour', kdt) from fn_test_not_nullable order by
kdt"
+ qt_sql_auto_partition_name_range_notnull "select
auto_partition_name('range', 'minute', kdt) from fn_test_not_nullable order by
kdt"
+ qt_sql_auto_partition_name_range_notnull "select
auto_partition_name('range', 'second', kdt) from fn_test_not_nullable order by
kdt"
+
+ test{
+ sql """select auto_partition_name('hello');"""
+ exception "function auto_partition_name must contains at least
two arguments"
+ }
+ test{
+ sql """select auto_partition_name('range', 'day', '123-12-12
19:20:30', '123-12-12 19:20:30');"""
+ exception "range auto_partition_name must contains three
arguments"
+ }
+ test{
+ sql """select auto_partition_name(kdt, 'day', kdt) from
fn_test_not_nullable order by kdt"""
+ exception "auto_partition_name must accept literal for 1nd
argument"
+ }
+ test{
+ sql """select auto_partition_name('range', kdt, kdt) from
fn_test_not_nullable order by kdt"""
+ exception "auto_partition_name must accept literal for 2nd
argument"
+ }
+ test{
+ sql """select auto_partition_name('range', 'second', '')"""
+ exception "The range partition only support DATE|DATETIME"
+ }
+ test{
+ sql """select auto_partition_name('range', 'second', '123-12-12
19:20:30')"""
+ exception "The range partition only support DATE|DATETIME"
+ }
+ test{
+ sql """select auto_partition_name('range', 'second',
'123-12-12')"""
+ exception "The range partition only support DATE|DATETIME"
+ }
+ test{
+ sql """select auto_partition_name('range', 'second',
'2011-12-12 123:12:12')"""
+ exception "The range partition only support DATE|DATETIME"
+ }
+ test{
+ sql """select auto_partition_name('range', 'day', 1);"""
+ exception "The range partition only support DATE|DATETIME"
+ }
+ test{
+ sql """select auto_partition_name('range', 'year', 'hello');"""
+ exception "The range partition only support DATE|DATETIME"
+ }
+ test{
+ sql """select auto_partition_name('ranges', 'year', 'hello');"""
+ exception "function auto_partition_name must accept range|list
for 1nd argument"
+ }
+ test{
+ sql """select auto_partition_name('range', 'years', 'hello');"""
+ exception "range auto_partition_name must accept
year|month|day|hour|minute|second for 2nd argument"
+ }
+ test{
+ sql "select auto_partition_name('list', '你好',
'hello!@#¥%~|world11111....', '世界')"
+ exception "The list partition name cannot exceed 50 characters"
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]