You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by li...@apache.org on 2022/10/12 02:01:17 UTC
[doris] branch master updated: [Vectorized][Function] support date_trunc and countequal function (#13039)
This is an automated email from the ASF dual-hosted git repository.
lihaopeng 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 16999ef02d [Vectorized][Function] support date_trunc and countequal function (#13039)
16999ef02d is described below
commit 16999ef02d6af72f60d81e8bbdfc35a47b4b4b1d
Author: zhangstar333 <87...@users.noreply.github.com>
AuthorDate: Wed Oct 12 10:01:09 2022 +0800
[Vectorized][Function] support date_trunc and countequal function (#13039)
---
.../vec/functions/array/function_array_index.cpp | 4 +
be/src/vec/functions/array/function_array_index.h | 6 +
be/src/vec/functions/function_timestamp.cpp | 105 +++++++++++++-
be/src/vec/runtime/vdatetime_value.cpp | 160 +++++++++++++++++++++
be/src/vec/runtime/vdatetime_value.h | 6 +
be/test/vec/function/function_time_test.cpp | 41 ++++++
.../sql-functions/array-functions/countequal.md | 65 +++++++++
.../date-time-functions/date_trunc.md | 100 +++++++++++++
docs/sidebars.json | 2 +
.../sql-functions/array-functions/countequal.md | 65 +++++++++
.../date-time-functions/date_trunc.md | 95 ++++++++++++
gensrc/script/doris_builtins_functions.py | 24 +++-
12 files changed, 670 insertions(+), 3 deletions(-)
diff --git a/be/src/vec/functions/array/function_array_index.cpp b/be/src/vec/functions/array/function_array_index.cpp
index 0c59b05b77..dec7236963 100644
--- a/be/src/vec/functions/array/function_array_index.cpp
+++ b/be/src/vec/functions/array/function_array_index.cpp
@@ -27,10 +27,14 @@ struct NameArrayContains {
struct NameArrayPosition {
static constexpr auto name = "array_position";
};
+struct NameCountEqual {
+ static constexpr auto name = "countequal";
+};
void register_function_array_index(SimpleFunctionFactory& factory) {
factory.register_function<FunctionArrayIndex<ArrayContainsAction, NameArrayContains>>();
factory.register_function<FunctionArrayIndex<ArrayPositionAction, NameArrayPosition>>();
+ factory.register_function<FunctionArrayIndex<ArrayCountEqual, NameCountEqual>>();
}
} // namespace doris::vectorized
diff --git a/be/src/vec/functions/array/function_array_index.h b/be/src/vec/functions/array/function_array_index.h
index cd17feff8d..be39c4dcb5 100644
--- a/be/src/vec/functions/array/function_array_index.h
+++ b/be/src/vec/functions/array/function_array_index.h
@@ -41,6 +41,12 @@ struct ArrayPositionAction {
static constexpr void apply(ResultType& current, size_t j) noexcept { current = j + 1; }
};
+struct ArrayCountEqual {
+ using ResultType = Int64;
+ static constexpr const bool resume_execution = true;
+ static constexpr void apply(ResultType& current, size_t j) noexcept { ++current; }
+};
+
template <typename ConcreteAction, typename Name>
class FunctionArrayIndex : public IFunction {
public:
diff --git a/be/src/vec/functions/function_timestamp.cpp b/be/src/vec/functions/function_timestamp.cpp
index 3c2f0d5b65..461b317bf6 100644
--- a/be/src/vec/functions/function_timestamp.cpp
+++ b/be/src/vec/functions/function_timestamp.cpp
@@ -33,6 +33,14 @@ namespace doris::vectorized {
struct StrToDate {
static constexpr auto name = "str_to_date";
+ static bool is_variadic() { return false; }
+
+ static DataTypes get_variadic_argument_types() { return {}; }
+
+ static DataTypePtr get_return_type_impl(const DataTypes& arguments) {
+ return make_nullable(std::make_shared<DataTypeDateTime>());
+ }
+
static Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
size_t result, size_t input_rows_count) {
auto null_map = ColumnUInt8::create(input_rows_count, 0);
@@ -122,6 +130,14 @@ struct StrToDate {
struct MakeDateImpl {
static constexpr auto name = "makedate";
+ static bool is_variadic() { return false; }
+
+ static DataTypes get_variadic_argument_types() { return {}; }
+
+ static DataTypePtr get_return_type_impl(const DataTypes& arguments) {
+ return make_nullable(std::make_shared<DataTypeDateTime>());
+ }
+
static Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
size_t result, size_t input_rows_count) {
auto null_map = ColumnUInt8::create(input_rows_count, 0);
@@ -214,6 +230,81 @@ struct MakeDateImpl {
}
};
+template <typename DateValueType, typename ArgType>
+struct DateTrunc {
+ static constexpr auto name = "date_trunc";
+
+ static bool is_variadic() { return true; }
+
+ static DataTypes get_variadic_argument_types() {
+ if constexpr (std::is_same_v<DateValueType, VecDateTimeValue>) {
+ return {std::make_shared<DataTypeDateTime>(), std::make_shared<DataTypeString>()};
+ } else {
+ return {std::make_shared<DataTypeDateTimeV2>(), std::make_shared<DataTypeString>()};
+ }
+ }
+
+ static DataTypePtr get_return_type_impl(const DataTypes& arguments) {
+ if constexpr (std::is_same_v<DateValueType, VecDateTimeValue>) {
+ return make_nullable(std::make_shared<DataTypeDateTime>());
+ } else {
+ return make_nullable(std::make_shared<DataTypeDateTimeV2>());
+ }
+ }
+
+ static Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
+ size_t result, size_t input_rows_count) {
+ DCHECK_EQ(arguments.size(), 2);
+ ColumnPtr argument_columns[2];
+ auto null_map = ColumnUInt8::create(input_rows_count, 0);
+ argument_columns[0] =
+ block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
+ argument_columns[1] =
+ block.get_by_position(arguments[1]).column->convert_to_full_column_if_const();
+ auto datetime_column = static_cast<const ColumnVector<ArgType>*>(argument_columns[0].get());
+ auto str_column = static_cast<const ColumnString*>(argument_columns[1].get());
+ auto& rdata = str_column->get_chars();
+ auto& roffsets = str_column->get_offsets();
+
+ ColumnPtr res = ColumnVector<ArgType>::create();
+ executeImpl(datetime_column->get_data(), rdata, roffsets,
+ static_cast<ColumnVector<ArgType>*>(res->assume_mutable().get())->get_data(),
+ null_map->get_data(), input_rows_count);
+
+ block.get_by_position(result).column =
+ ColumnNullable::create(std::move(res), std::move(null_map));
+ return Status::OK();
+ }
+
+ static void executeImpl(const PaddedPODArray<ArgType>& ldata, const ColumnString::Chars& rdata,
+ const ColumnString::Offsets& roffsets, PaddedPODArray<ArgType>& res,
+ NullMap& null_map, size_t input_rows_count) {
+ res.resize(input_rows_count);
+ for (size_t i = 0; i < input_rows_count; ++i) {
+ auto dt = binary_cast<ArgType, DateValueType>(ldata[i]);
+ const char* str_data = reinterpret_cast<const char*>(&rdata[roffsets[i - 1]]);
+ if (std::strncmp("year", str_data, 4) == 0) {
+ null_map[i] = !dt.template datetime_trunc<YEAR>();
+ } else if (std::strncmp("quarter", str_data, 7) == 0) {
+ null_map[i] = !dt.template datetime_trunc<QUARTER>();
+ } else if (std::strncmp("month", str_data, 5) == 0) {
+ null_map[i] = !dt.template datetime_trunc<MONTH>();
+ } else if (std::strncmp("day", str_data, 3) == 0) {
+ null_map[i] = !dt.template datetime_trunc<DAY>();
+ } else if (std::strncmp("hour", str_data, 4) == 0) {
+ null_map[i] = !dt.template datetime_trunc<HOUR>();
+ } else if (std::strncmp("minute", str_data, 6) == 0) {
+ null_map[i] = !dt.template datetime_trunc<MINUTE>();
+ } else if (std::strncmp("second", str_data, 6) == 0) {
+ null_map[i] = !dt.template datetime_trunc<SECOND>();
+ } else {
+ null_map[i] = 1;
+ }
+ res[i] = binary_cast<DateValueType, ArgType>(dt);
+ }
+ }
+};
+
class FromDays : public IFunction {
public:
static constexpr auto name = "from_days";
@@ -488,8 +579,14 @@ public:
size_t get_number_of_arguments() const override { return 2; }
+ bool is_variadic() const override { return Impl::is_variadic(); }
+
+ DataTypes get_variadic_argument_types_impl() const override {
+ return Impl::get_variadic_argument_types();
+ }
+
DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
- return make_nullable(std::make_shared<DataTypeDateTime>());
+ return Impl::get_return_type_impl(arguments);
}
bool use_default_implementation_for_constants() const override { return true; }
@@ -501,13 +598,17 @@ public:
};
using FunctionStrToDate = FunctionOtherTypesToDateType<StrToDate>;
-
using FunctionMakeDate = FunctionOtherTypesToDateType<MakeDateImpl>;
+using FunctionDateTrunc = FunctionOtherTypesToDateType<DateTrunc<VecDateTimeValue, Int64>>;
+using FunctionDateTruncV2 =
+ FunctionOtherTypesToDateType<DateTrunc<DateV2Value<DateTimeV2ValueType>, UInt64>>;
void register_function_timestamp(SimpleFunctionFactory& factory) {
factory.register_function<FunctionStrToDate>();
factory.register_function<FunctionMakeDate>();
factory.register_function<FromDays>();
+ factory.register_function<FunctionDateTrunc>();
+ factory.register_function<FunctionDateTruncV2>();
factory.register_function<FunctionUnixTimestamp<UnixTimeStampImpl>>();
factory.register_function<FunctionUnixTimestamp<UnixTimeStampDateImpl<DataTypeDate>>>();
diff --git a/be/src/vec/runtime/vdatetime_value.cpp b/be/src/vec/runtime/vdatetime_value.cpp
index 1696e57d89..28ecf960f2 100644
--- a/be/src/vec/runtime/vdatetime_value.cpp
+++ b/be/src/vec/runtime/vdatetime_value.cpp
@@ -1668,6 +1668,67 @@ void VecDateTimeValue::set_time(uint32_t year, uint32_t month, uint32_t day, uin
_second = second;
}
+template <TimeUnit unit>
+bool VecDateTimeValue::datetime_trunc() {
+ if (!is_valid_date()) {
+ return false;
+ }
+ switch (unit) {
+ case SECOND: {
+ break;
+ }
+ case MINUTE: {
+ _second = 0;
+ break;
+ }
+ case HOUR: {
+ _second = 0;
+ _minute = 0;
+ break;
+ }
+ case DAY: {
+ _second = 0;
+ _minute = 0;
+ _hour = 0;
+ break;
+ }
+ case MONTH: {
+ _second = 0;
+ _minute = 0;
+ _hour = 0;
+ _day = 1;
+ break;
+ }
+ case QUARTER: {
+ _second = 0;
+ _minute = 0;
+ _hour = 0;
+ _day = 1;
+ if (_month <= 3) {
+ _month = 1;
+ } else if (_month <= 6) {
+ _month = 4;
+ } else if (_month <= 9) {
+ _month = 7;
+ } else {
+ _month = 10;
+ }
+ break;
+ }
+ case YEAR: {
+ _second = 0;
+ _minute = 0;
+ _hour = 0;
+ _day = 1;
+ _month = 1;
+ break;
+ }
+ default:
+ return false;
+ }
+ return true;
+}
+
template <typename T>
void VecDateTimeValue::create_from_date_v2(DateV2Value<T>& value, TimeType type) {
if constexpr (std::is_same_v<T, DateV2ValueType>) {
@@ -2595,6 +2656,78 @@ bool DateV2Value<T>::date_add_interval(const TimeInterval& interval) {
return true;
}
+template <typename T>
+template <TimeUnit unit>
+bool DateV2Value<T>::datetime_trunc() {
+ if constexpr (is_datetime) {
+ if (!is_valid_date()) {
+ return false;
+ }
+ switch (unit) {
+ case SECOND: {
+ date_v2_value_.microsecond_ = 0;
+ break;
+ }
+ case MINUTE: {
+ date_v2_value_.microsecond_ = 0;
+ date_v2_value_.second_ = 0;
+ break;
+ }
+ case HOUR: {
+ date_v2_value_.microsecond_ = 0;
+ date_v2_value_.second_ = 0;
+ date_v2_value_.minute_ = 0;
+ break;
+ }
+ case DAY: {
+ date_v2_value_.microsecond_ = 0;
+ date_v2_value_.second_ = 0;
+ date_v2_value_.minute_ = 0;
+ date_v2_value_.hour_ = 0;
+ break;
+ }
+ case MONTH: {
+ date_v2_value_.microsecond_ = 0;
+ date_v2_value_.second_ = 0;
+ date_v2_value_.minute_ = 0;
+ date_v2_value_.hour_ = 0;
+ date_v2_value_.day_ = 1;
+ break;
+ }
+ case QUARTER: {
+ date_v2_value_.microsecond_ = 0;
+ date_v2_value_.second_ = 0;
+ date_v2_value_.minute_ = 0;
+ date_v2_value_.hour_ = 0;
+ date_v2_value_.day_ = 1;
+ if (date_v2_value_.month_ <= 3) {
+ date_v2_value_.month_ = 1;
+ } else if (date_v2_value_.month_ <= 6) {
+ date_v2_value_.month_ = 4;
+ } else if (date_v2_value_.month_ <= 9) {
+ date_v2_value_.month_ = 7;
+ } else {
+ date_v2_value_.month_ = 10;
+ }
+ break;
+ }
+ case YEAR: {
+ date_v2_value_.microsecond_ = 0;
+ date_v2_value_.second_ = 0;
+ date_v2_value_.minute_ = 0;
+ date_v2_value_.hour_ = 0;
+ date_v2_value_.day_ = 1;
+ date_v2_value_.month_ = 1;
+ break;
+ }
+ default:
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
template <typename T>
bool DateV2Value<T>::unix_timestamp(int64_t* timestamp, const std::string& timezone) const {
cctz::time_zone ctz;
@@ -3266,4 +3399,31 @@ template bool DateV2Value<DateTimeV2ValueType>::date_add_interval<TimeUnit::QUAR
template bool DateV2Value<DateTimeV2ValueType>::date_add_interval<TimeUnit::WEEK>(
const TimeInterval& interval);
+template bool VecDateTimeValue::datetime_trunc<TimeUnit::SECOND>();
+template bool VecDateTimeValue::datetime_trunc<TimeUnit::MINUTE>();
+template bool VecDateTimeValue::datetime_trunc<TimeUnit::HOUR>();
+template bool VecDateTimeValue::datetime_trunc<TimeUnit::DAY>();
+template bool VecDateTimeValue::datetime_trunc<TimeUnit::MONTH>();
+template bool VecDateTimeValue::datetime_trunc<TimeUnit::YEAR>();
+template bool VecDateTimeValue::datetime_trunc<TimeUnit::QUARTER>();
+template bool VecDateTimeValue::datetime_trunc<TimeUnit::WEEK>();
+
+template bool DateV2Value<DateV2ValueType>::datetime_trunc<TimeUnit::SECOND>();
+template bool DateV2Value<DateV2ValueType>::datetime_trunc<TimeUnit::MINUTE>();
+template bool DateV2Value<DateV2ValueType>::datetime_trunc<TimeUnit::HOUR>();
+template bool DateV2Value<DateV2ValueType>::datetime_trunc<TimeUnit::DAY>();
+template bool DateV2Value<DateV2ValueType>::datetime_trunc<TimeUnit::MONTH>();
+template bool DateV2Value<DateV2ValueType>::datetime_trunc<TimeUnit::YEAR>();
+template bool DateV2Value<DateV2ValueType>::datetime_trunc<TimeUnit::QUARTER>();
+template bool DateV2Value<DateV2ValueType>::datetime_trunc<TimeUnit::WEEK>();
+
+template bool DateV2Value<DateTimeV2ValueType>::datetime_trunc<TimeUnit::SECOND>();
+template bool DateV2Value<DateTimeV2ValueType>::datetime_trunc<TimeUnit::MINUTE>();
+template bool DateV2Value<DateTimeV2ValueType>::datetime_trunc<TimeUnit::HOUR>();
+template bool DateV2Value<DateTimeV2ValueType>::datetime_trunc<TimeUnit::DAY>();
+template bool DateV2Value<DateTimeV2ValueType>::datetime_trunc<TimeUnit::MONTH>();
+template bool DateV2Value<DateTimeV2ValueType>::datetime_trunc<TimeUnit::YEAR>();
+template bool DateV2Value<DateTimeV2ValueType>::datetime_trunc<TimeUnit::QUARTER>();
+template bool DateV2Value<DateTimeV2ValueType>::datetime_trunc<TimeUnit::WEEK>();
+
} // namespace doris::vectorized
diff --git a/be/src/vec/runtime/vdatetime_value.h b/be/src/vec/runtime/vdatetime_value.h
index 7af0c273b1..edf918d5fb 100644
--- a/be/src/vec/runtime/vdatetime_value.h
+++ b/be/src/vec/runtime/vdatetime_value.h
@@ -461,6 +461,9 @@ public:
template <TimeUnit unit>
bool date_add_interval(const TimeInterval& interval);
+ template <TimeUnit unit>
+ bool datetime_trunc(); //datetime trunc, like trunc minute = 0
+
//unix_timestamp is called with a timezone argument,
//it returns seconds of the value of date literal since '1970-01-01 00:00:00' UTC
bool unix_timestamp(int64_t* timestamp, const std::string& timezone) const;
@@ -912,6 +915,9 @@ public:
template <TimeUnit unit>
bool date_add_interval(const TimeInterval& interval);
+ template <TimeUnit unit>
+ bool datetime_trunc(); //datetime trunc, like trunc minute = 0
+
//unix_timestamp is called with a timezone argument,
//it returns seconds of the value of date literal since '1970-01-01 00:00:00' UTC
bool unix_timestamp(int64_t* timestamp, const std::string& timezone) const;
diff --git a/be/test/vec/function/function_time_test.cpp b/be/test/vec/function/function_time_test.cpp
index 4f6a49ba23..18455a4566 100644
--- a/be/test/vec/function/function_time_test.cpp
+++ b/be/test/vec/function/function_time_test.cpp
@@ -1620,6 +1620,47 @@ TEST(VTimestampFunctionsTest, dayname_test) {
}
}
+TEST(VTimestampFunctionsTest, datetrunc_test) {
+ std::string func_name = "date_trunc";
+ {
+ InputTypeSet input_types = {TypeIndex::DateTime, TypeIndex::String};
+
+ DataSet data_set = {{{std::string("2022-10-08 11:44:23"), std::string("second")},
+ str_to_date_time("2022-10-08 11:44:23")},
+ {{std::string("2022-10-08 11:44:23"), std::string("minute")},
+ str_to_date_time("2022-10-08 11:44:00")},
+ {{std::string("2022-10-08 11:44:23"), std::string("hour")},
+ str_to_date_time("2022-10-08 11:00:00")},
+ {{std::string("2022-10-08 11:44:23"), std::string("day")},
+ str_to_date_time("2022-10-08 00:00:00")},
+ {{std::string("2022-10-08 11:44:23"), std::string("month")},
+ str_to_date_time("2022-10-01 00:00:00")},
+ {{std::string("2022-10-08 11:44:23"), std::string("year")},
+ str_to_date_time("2022-01-01 00:00:00")}};
+
+ check_function<DataTypeDateTime, true>(func_name, input_types, data_set);
+ }
+
+ {
+ InputTypeSet input_types = {TypeIndex::DateTimeV2, TypeIndex::String};
+
+ DataSet data_set = {{{std::string("2022-10-08 11:44:23.123"), std::string("second")},
+ str_to_datetime_v2("2022-10-08 11:44:23.000", "%Y-%m-%d %H:%i:%s.%f")},
+ {{std::string("2022-10-08 11:44:23"), std::string("minute")},
+ str_to_datetime_v2("2022-10-08 11:44:00", "%Y-%m-%d %H:%i:%s")},
+ {{std::string("2022-10-08 11:44:23"), std::string("hour")},
+ str_to_datetime_v2("2022-10-08 11:00:00", "%Y-%m-%d %H:%i:%s")},
+ {{std::string("2022-10-08 11:44:23"), std::string("day")},
+ str_to_datetime_v2("2022-10-08 00:00:00", "%Y-%m-%d %H:%i:%s")},
+ {{std::string("2022-10-08 11:44:23"), std::string("month")},
+ str_to_datetime_v2("2022-10-01 00:00:00", "%Y-%m-%d %H:%i:%s")},
+ {{std::string("2022-10-08 11:44:23"), std::string("year")},
+ str_to_datetime_v2("2022-01-01 00:00:00", "%Y-%m-%d %H:%i:%s")}};
+
+ check_function<DataTypeDateTimeV2, true>(func_name, input_types, data_set);
+ }
+}
+
TEST(VTimestampFunctionsTest, hours_add_v2_test) {
std::string func_name = "hours_add";
diff --git a/docs/en/docs/sql-manual/sql-functions/array-functions/countequal.md b/docs/en/docs/sql-manual/sql-functions/array-functions/countequal.md
new file mode 100644
index 0000000000..f743774964
--- /dev/null
+++ b/docs/en/docs/sql-manual/sql-functions/array-functions/countequal.md
@@ -0,0 +1,65 @@
+---
+{
+ "title": "countequal",
+ "language": "en"
+}
+---
+
+<!--
+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.
+-->
+
+## countequal
+
+### description
+
+#### Syntax
+
+`BIGINT countequal(ARRAY<T> arr, T value)`
+
+Returns a number of the `value` in the given array.
+
+```
+num - how many the value number in array;
+0 - if value does not present in the array;
+NULL - when array is NULL or value is NULL.
+```
+
+### notice
+
+`Only supported in vectorized engine`
+
+### example
+
+```
+mysql> set enable_vectorized_engine=true;
+
+mysql> select *, countEqual(c_array,5) from array_test;
++------+-----------------+--------------------------+
+| id | c_array | countequal(`c_array`, 5) |
++------+-----------------+--------------------------+
+| 1 | [1, 2, 3, 4, 5] | 1 |
+| 2 | [6, 7, 8] | 0 |
+| 3 | [] | 0 |
+| 4 | NULL | NULL |
++------+-----------------+--------------------------+
+```
+
+### keywords
+
+ARRAY,COUNTEQUAL,
diff --git a/docs/en/docs/sql-manual/sql-functions/date-time-functions/date_trunc.md b/docs/en/docs/sql-manual/sql-functions/date-time-functions/date_trunc.md
new file mode 100644
index 0000000000..385d43ba70
--- /dev/null
+++ b/docs/en/docs/sql-manual/sql-functions/date-time-functions/date_trunc.md
@@ -0,0 +1,100 @@
+---
+{
+ "title": "date_trunc",
+ "language": "en"
+}
+---
+
+<!--
+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.
+-->
+
+## date_trunc
+### Description
+#### Syntax
+
+`DATETIME DATE_TRUNC(DATETIME datetime,VARCHAR unit)`
+
+
+Truncates datetime in the specified time unit.
+
+datetime is a legal date expression.
+
+unit is the time unit you want to truncate. The optional values are as follows: [`second`,`minute`,`hour`,`day`,`month`,`quarter`,`year`]。
+If unit does not meet the above optional values, the result will return NULL.
+### example
+
+```
+mysql> select date_trunc('2010-12-02 19:28:30', 'second');
++-------------------------------------------------+
+| date_trunc('2010-12-02 19:28:30', 'second') |
++-------------------------------------------------+
+| 2010-12-02 19:28:30 |
++-------------------------------------------------+
+
+mysql> select date_trunc('2010-12-02 19:28:30', 'minute');
++-------------------------------------------------+
+| date_trunc('2010-12-02 19:28:30', 'minute') |
++-------------------------------------------------+
+| 2010-12-02 19:28:00 |
++-------------------------------------------------+
+
+mysql> select date_trunc('2010-12-02 19:28:30', 'hour');
++-------------------------------------------------+
+| date_trunc('2010-12-02 19:28:30', 'hour') |
++-------------------------------------------------+
+| 2010-12-02 19:00:00 |
++-------------------------------------------------+
+
+mysql> select date_trunc('2010-12-02 19:28:30', 'day');
++-------------------------------------------------+
+| date_trunc('2010-12-02 19:28:30', 'day') |
++-------------------------------------------------+
+| 2010-12-02 00:00:00 |
++-------------------------------------------------+
+
+mysql> select date_trunc('2010-12-02 19:28:30', 'week');
++-------------------------------------------------+
+| date_trunc('2010-12-02 19:28:30', 'week') |
++-------------------------------------------------+
+| 2010-11-28 00:00:00 |
++-------------------------------------------------+
+
+mysql> select date_trunc('2010-12-02 19:28:30', 'month');
++-------------------------------------------------+
+| date_trunc('2010-12-02 19:28:30', 'month') |
++-------------------------------------------------+
+| 2010-12-01 00:00:00 |
++-------------------------------------------------+
+
+mysql> select date_trunc('2010-12-02 19:28:30', 'quarter');
++-------------------------------------------------+
+| date_trunc('2010-12-02 19:28:30', 'quarter') |
++-------------------------------------------------+
+| 2010-10-01 00:00:00 |
++-------------------------------------------------+
+
+mysql> select date_trunc('2010-12-02 19:28:30', 'year');
++-------------------------------------------------+
+| date_trunc('2010-12-02 19:28:30', 'year') |
++-------------------------------------------------+
+| 2010-01-01 00:00:00 |
++-------------------------------------------------+
+```
+### keywords
+ DATE_TRUNC,DATE,DATETIME
diff --git a/docs/sidebars.json b/docs/sidebars.json
index 3b423dc338..03e3883ecb 100644
--- a/docs/sidebars.json
+++ b/docs/sidebars.json
@@ -251,6 +251,7 @@
"sql-manual/sql-functions/array-functions/array_intersect",
"sql-manual/sql-functions/array-functions/arrays_overlap",
"sql-manual/sql-functions/array-functions/array_min",
+ "sql-manual/sql-functions/array-functions/countequal",
"sql-manual/sql-functions/array-functions/element_at",
"sql-manual/sql-functions/array-functions/array_avg",
"sql-manual/sql-functions/array-functions/size",
@@ -300,6 +301,7 @@
"sql-manual/sql-functions/date-time-functions/timestampdiff",
"sql-manual/sql-functions/date-time-functions/date_add",
"sql-manual/sql-functions/date-time-functions/date_sub",
+ "sql-manual/sql-functions/date-time-functions/date_trunc",
"sql-manual/sql-functions/date-time-functions/date_format",
"sql-manual/sql-functions/date-time-functions/datediff",
"sql-manual/sql-functions/date-time-functions/minutes_add",
diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/array-functions/countequal.md b/docs/zh-CN/docs/sql-manual/sql-functions/array-functions/countequal.md
new file mode 100644
index 0000000000..761d79881c
--- /dev/null
+++ b/docs/zh-CN/docs/sql-manual/sql-functions/array-functions/countequal.md
@@ -0,0 +1,65 @@
+---
+{
+ "title": "countequal",
+ "language": "zh-CN"
+}
+---
+
+<!--
+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.
+-->
+
+## countequal
+
+### description
+
+#### Syntax
+
+`BIGINT countequal(ARRAY<T> arr, T value)`
+
+判断数组中包含value元素的个数。返回结果如下:
+
+```
+num - value在array中的数量;
+0 - value不存在数组arr中;
+NULL - 如果数组为NULL,或者value为NULL。
+```
+
+### notice
+
+`仅支持向量化引擎中使用`
+
+### example
+
+```
+mysql> set enable_vectorized_engine=true;
+
+mysql> select *, countEqual(c_array,5) from array_test;
++------+-----------------+--------------------------+
+| id | c_array | countequal(`c_array`, 5) |
++------+-----------------+--------------------------+
+| 1 | [1, 2, 3, 4, 5] | 1 |
+| 2 | [6, 7, 8] | 0 |
+| 3 | [] | 0 |
+| 4 | NULL | NULL |
++------+-----------------+--------------------------+
+```
+
+### keywords
+
+ARRAY,COUNTEQUAL
diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/date-time-functions/date_trunc.md b/docs/zh-CN/docs/sql-manual/sql-functions/date-time-functions/date_trunc.md
new file mode 100644
index 0000000000..17753027d7
--- /dev/null
+++ b/docs/zh-CN/docs/sql-manual/sql-functions/date-time-functions/date_trunc.md
@@ -0,0 +1,95 @@
+---
+{
+ "title": "date_trunc",
+ "language": "zh-CN"
+}
+---
+
+<!--
+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.
+-->
+
+## date_trunc
+### description
+#### Syntax
+
+`DATETIME DATE_TRUNC(DATETIME datetime,VARCHAR unit)`
+
+
+将datetime按照指定的时间单位截断。
+
+datetime 参数是合法的日期表达式。
+
+unit 参数是您希望截断的时间间隔,可选的值如下:[`second`,`minute`,`hour`,`day`,`month`,`quarter`,`year`]。
+如果unit 不符合上述可选值,结果将返回NULL。
+### example
+
+```
+mysql> select date_trunc('2010-12-02 19:28:30', 'second');
++-------------------------------------------------+
+| date_trunc('2010-12-02 19:28:30', 'second') |
++-------------------------------------------------+
+| 2010-12-02 19:28:30 |
++-------------------------------------------------+
+
+mysql> select date_trunc('2010-12-02 19:28:30', 'minute');
++-------------------------------------------------+
+| date_trunc('2010-12-02 19:28:30', 'minute') |
++-------------------------------------------------+
+| 2010-12-02 19:28:00 |
++-------------------------------------------------+
+
+mysql> select date_trunc('2010-12-02 19:28:30', 'hour');
++-------------------------------------------------+
+| date_trunc('2010-12-02 19:28:30', 'hour') |
++-------------------------------------------------+
+| 2010-12-02 19:00:00 |
++-------------------------------------------------+
+
+mysql> select date_trunc('2010-12-02 19:28:30', 'day');
++-------------------------------------------------+
+| date_trunc('2010-12-02 19:28:30', 'day') |
++-------------------------------------------------+
+| 2010-12-02 00:00:00 |
++-------------------------------------------------+
+
+mysql> select date_trunc('2010-12-02 19:28:30', 'month');
++-------------------------------------------------+
+| date_trunc('2010-12-02 19:28:30', 'month') |
++-------------------------------------------------+
+| 2010-12-01 00:00:00 |
++-------------------------------------------------+
+
+mysql> select date_trunc('2010-12-02 19:28:30', 'quarter');
++-------------------------------------------------+
+| date_trunc('2010-12-02 19:28:30', 'quarter') |
++-------------------------------------------------+
+| 2010-10-01 00:00:00 |
++-------------------------------------------------+
+
+mysql> select date_trunc('2010-12-02 19:28:30', 'year');
++-------------------------------------------------+
+| date_trunc('2010-12-02 19:28:30', 'year') |
++-------------------------------------------------+
+| 2010-01-01 00:00:00 |
++-------------------------------------------------+
+```
+
+### keywords
+
+ DATE_TRUNC,DATE,TRUNC
diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py
index d2439fdfa6..2070a546ff 100755
--- a/gensrc/script/doris_builtins_functions.py
+++ b/gensrc/script/doris_builtins_functions.py
@@ -166,6 +166,22 @@ visible_functions = [
[['array_contains'], 'BOOLEAN', ['ARRAY_VARCHAR', 'VARCHAR'], '', '', '', 'vec', ''],
[['array_contains'], 'BOOLEAN', ['ARRAY_STRING', 'STRING'], '', '', '', 'vec', ''],
+ [['countequal'], 'BIGINT', ['ARRAY_BOOLEAN', 'BOOLEAN'], '', '', '', 'vec', ''],
+ [['countequal'], 'BIGINT', ['ARRAY_TINYINT', 'TINYINT'], '', '', '', 'vec', ''],
+ [['countequal'], 'BIGINT', ['ARRAY_SMALLINT', 'SMALLINT'], '', '', '', 'vec', ''],
+ [['countequal'], 'BIGINT', ['ARRAY_INT', 'INT'], '', '', '', 'vec', ''],
+ [['countequal'], 'BIGINT', ['ARRAY_BIGINT', 'BIGINT'], '', '', '', 'vec', ''],
+ [['countequal'], 'BIGINT', ['ARRAY_LARGEINT', 'LARGEINT'], '', '', '', 'vec', ''],
+ [['countequal'], 'BIGINT', ['ARRAY_DATETIME', 'DATETIME'], '', '', '', 'vec', ''],
+ [['countequal'], 'BIGINT', ['ARRAY_DATE', 'DATE'], '', '', '', 'vec', ''],
+ [['countequal'], 'BIGINT', ['ARRAY_DATETIMEV2', 'DATETIMEV2'], '', '', '', 'vec', ''],
+ [['countequal'], 'BIGINT', ['ARRAY_DATEV2', 'DATEV2'], '', '', '', 'vec', ''],
+ [['countequal'], 'BIGINT', ['ARRAY_FLOAT', 'FLOAT'], '', '', '', 'vec', ''],
+ [['countequal'], 'BIGINT', ['ARRAY_DOUBLE', 'DOUBLE'], '', '', '', 'vec', ''],
+ [['countequal'], 'BIGINT', ['ARRAY_DECIMALV2', 'DECIMALV2'], '', '', '', 'vec', ''],
+ [['countequal'], 'BIGINT', ['ARRAY_VARCHAR', 'VARCHAR'], '', '', '', 'vec', ''],
+ [['countequal'], 'BIGINT', ['ARRAY_STRING', 'STRING'], '', '', '', 'vec', ''],
+
[['array_position'], 'BIGINT', ['ARRAY_BOOLEAN', 'BOOLEAN'], '', '', '', 'vec', ''],
[['array_position'], 'BIGINT', ['ARRAY_TINYINT', 'TINYINT'], '', '', '', 'vec', ''],
[['array_position'], 'BIGINT', ['ARRAY_SMALLINT', 'SMALLINT'], '', '', '', 'vec', ''],
@@ -466,7 +482,13 @@ visible_functions = [
'_ZN5doris18TimestampFunctions7to_daysEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE',
'', '', 'vec', 'ALWAYS_NULLABLE'],
- [['year'], 'INT', ['DATETIME'],
+ [['date_trunc'], 'DATETIME', ['DATETIME', 'VARCHAR'],
+ '', '', '', 'vec', 'ALWAYS_NULLABLE'],
+
+ [['date_trunc'], 'DATETIMEV2', ['DATETIMEV2', 'VARCHAR'],
+ '', '', '', 'vec', 'ALWAYS_NULLABLE'],
+
+ [['year'], 'INT', ['DATETIME'],
'_ZN5doris18TimestampFunctions4yearEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE',
'', '', 'vec', 'ALWAYS_NULLABLE'],
[['month'], 'INT', ['DATETIME'],
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org