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

morningman pushed a commit to branch branch-c108335-hive-sql
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-c108335-hive-sql by 
this push:
     new a0ef41eb0ea Impl next day (#49197)
a0ef41eb0ea is described below

commit a0ef41eb0ea2a7d9d0c9c59200dde01f0eb7af93
Author: Socrates <suyit...@selectdb.com>
AuthorDate: Tue Mar 18 16:03:09 2025 +0800

    Impl next day (#49197)
---
 .../function_date_or_datetime_computation.cpp      |  3 +
 .../function_date_or_datetime_computation.h        | 94 ++++++++++++++++++++++
 .../doris/catalog/BuiltinScalarFunctions.java      |  2 +
 .../expressions/functions/scalar/NextDay.java      | 81 +++++++++++++++++++
 .../expressions/visitor/ScalarFunctionVisitor.java |  5 ++
 5 files changed, 185 insertions(+)

diff --git a/be/src/vec/functions/function_date_or_datetime_computation.cpp 
b/be/src/vec/functions/function_date_or_datetime_computation.cpp
index 097176e1c7c..736a6f48539 100644
--- a/be/src/vec/functions/function_date_or_datetime_computation.cpp
+++ b/be/src/vec/functions/function_date_or_datetime_computation.cpp
@@ -127,6 +127,9 @@ void 
register_function_date_time_computation(SimpleFunctionFactory& factory) {
     factory.register_function<FunctionMinutesDiff>();
     factory.register_function<FunctionSecondsDiff>();
 
+    factory.register_function<FunctionNextDay<DateNextDayImpl>>();
+    factory.register_function<FunctionNextDay<DateTimeNextDayImpl>>();
+
     factory.register_function<FunctionToYearWeekTwoArgs>();
     factory.register_function<FunctionToWeekTwoArgs>();
 
diff --git a/be/src/vec/functions/function_date_or_datetime_computation.h 
b/be/src/vec/functions/function_date_or_datetime_computation.h
index 0d71bee6e73..1c99aa5fc1f 100644
--- a/be/src/vec/functions/function_date_or_datetime_computation.h
+++ b/be/src/vec/functions/function_date_or_datetime_computation.h
@@ -1036,4 +1036,98 @@ public:
     }
 };
 
+template <typename FunctionImpl>
+class FunctionNextDay : public IFunction {
+public:
+    static constexpr auto name = "next_day";
+    static FunctionPtr create() { return std::make_shared<FunctionNextDay>(); }
+    String get_name() const override { return name; }
+    size_t get_number_of_arguments() const override { return 2; }
+    DataTypePtr get_return_type_impl(const ColumnsWithTypeAndName& arguments) 
const override {
+        return make_nullable(std::make_shared<typename 
FunctionImpl::ReturnType>());
+    }
+
+    Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
+                        uint32_t result, size_t input_rows_count) const 
override {
+        // TODO: const optimize
+        return FunctionImpl::execute(context, block, arguments, result, 
input_rows_count);
+    }
+};
+
+static int day_of_week(const StringRef& weekday) {
+    static const std::unordered_map<std::string, int> weekday_map = {
+            {"SU", 1}, {"SUN", 1}, {"SUNDAY", 1},   {"MO", 2}, {"MON", 2}, 
{"MONDAY", 2},
+            {"TU", 3}, {"TUE", 3}, {"TUESDAY", 3},  {"WE", 4}, {"WED", 4}, 
{"WEDNESDAY", 4},
+            {"TH", 5}, {"THU", 5}, {"THURSDAY", 5}, {"FR", 6}, {"FRI", 6}, 
{"FRIDAY", 6},
+            {"SA", 7}, {"SAT", 7}, {"SATURDAY", 7},
+    };
+    auto weekday_upper = weekday.to_string();
+    std::transform(weekday_upper.begin(), weekday_upper.end(), 
weekday_upper.begin(), ::toupper);
+    auto it = weekday_map.find(weekday_upper);
+    if (it == weekday_map.end()) {
+        return 0;
+    }
+    return it->second;
+}
+
+struct DateNextDayImpl {
+    using ReturnType = DataTypeDateV2;
+    static Status execute(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
+                          uint32_t result, size_t input_rows_count) {
+        CHECK_EQ(arguments.size(), 2);
+        auto res = ColumnVector<UInt32>::create();
+        const auto* date_col =
+                assert_cast<const 
ColumnDateV2*>(block.get_by_position(arguments[0]).column.get());
+        const auto* week_col =
+                assert_cast<const 
ColumnString*>(block.get_by_position(arguments[1]).column.get());
+        for (int i = 0; i < input_rows_count; ++i) {
+            auto date = date_col->get_element(i);
+            auto week = week_col->get_data_at(i);
+            auto week_day = day_of_week(week);
+            if (week_day == 0) {
+                return Status::InvalidArgument("Invalid weekday: {}", week);
+            } else {
+                auto dtv = binary_cast<UInt32, 
DateV2Value<DateV2ValueType>>(date);
+                auto days_to_add = (week_day - dtv.day_of_week() + 7) % 7;
+                days_to_add = days_to_add == 0 ? 7 : days_to_add;
+                dtv.date_add_interval<TimeUnit::DAY>(
+                        TimeInterval(TimeUnit::DAY, days_to_add, false));
+                res->insert_value(binary_cast<DateV2Value<DateV2ValueType>, 
UInt32>(dtv));
+            }
+        }
+        block.replace_by_position(result, std::move(res));
+        return Status::OK();
+    }
+};
+
+struct DateTimeNextDayImpl {
+    using ReturnType = DataTypeDateTimeV2;
+    static Status execute(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
+                          uint32_t result, size_t input_rows_count) {
+        CHECK_EQ(arguments.size(), 2);
+        auto res = ColumnVector<UInt64>::create();
+        const auto* date_col = assert_cast<const ColumnDateTimeV2*>(
+                block.get_by_position(arguments[0]).column.get());
+        const auto* week_col =
+                assert_cast<const 
ColumnString*>(block.get_by_position(arguments[1]).column.get());
+        for (int i = 0; i < input_rows_count; ++i) {
+            auto date = date_col->get_element(i);
+            auto week = week_col->get_data_at(i);
+            auto week_day = day_of_week(week);
+            if (week_day == 0) {
+                return Status::InvalidArgument("Invalid weekday: {}", week);
+            } else {
+                auto dtv = binary_cast<UInt64, 
DateV2Value<DateTimeV2ValueType>>(date);
+                auto days_to_add = (week_day - dtv.day_of_week() + 7) % 7;
+                days_to_add = days_to_add == 0 ? 7 : days_to_add;
+                dtv.date_add_interval<TimeUnit::DAY>(
+                        TimeInterval(TimeUnit::DAY, days_to_add, false));
+                
res->insert_value(binary_cast<DateV2Value<DateTimeV2ValueType>, UInt64>(dtv));
+            }
+        }
+        block.replace_by_position(result, std::move(res));
+        return Status::OK();
+    }
+};
+
 } // namespace doris::vectorized
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 2f9bccc2706..f31f705dafb 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
@@ -329,6 +329,7 @@ import 
org.apache.doris.nereids.trees.expressions.functions.scalar.MultiSearchAl
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.MurmurHash332;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.MurmurHash364;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Negative;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.NextDay;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.NgramSearch;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.NonNullable;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.NormalCdf;
@@ -825,6 +826,7 @@ public class BuiltinScalarFunctions implements 
FunctionHelper {
             scalar(MurmurHash332.class, "murmur_hash3_32"),
             scalar(MurmurHash364.class, "murmur_hash3_64"),
             scalar(Negative.class, "negative"),
+            scalar(NextDay.class, "next_day"),
             scalar(NonNullable.class, "non_nullable"),
             scalar(NormalCdf.class, "normal_cdf"),
             scalar(NotNullOrEmpty.class, "not_null_or_empty"),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/NextDay.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/NextDay.java
new file mode 100644
index 00000000000..d47035e6d7e
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/NextDay.java
@@ -0,0 +1,81 @@
+// 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.trees.expressions.Expression;
+import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
+import 
org.apache.doris.nereids.trees.expressions.functions.PropagateNullableOnDateLikeV2Args;
+import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.DateTimeType;
+import org.apache.doris.nereids.types.DateTimeV2Type;
+import org.apache.doris.nereids.types.DateType;
+import org.apache.doris.nereids.types.DateV2Type;
+import org.apache.doris.nereids.types.StringType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/**
+ * ScalarFunction 'days_add'.
+ * next_day(expr, dayOfWeek)
+ * - expr: A DATE expression.
+ * - dayOfWeek: A STRING expression identifying a day of the week.
+ * Returns the first DATE that is later than expr and has the same day of the
+ * week as dayOfWeek.
+ * dayOfWeek must be one of the following (case insensitive):
+ * 'SU', 'SUN', 'SUNDAY'
+ * 'MO', 'MON', 'MONDAY'
+ * 'TU', 'TUE', 'TUESDAY'
+ * 'WE', 'WED', 'WEDNESDAY'
+ * 'TH', 'THU', 'THURSDAY'
+ * 'FR', 'FRI', 'FRIDAY'
+ * 'SA', 'SAT', 'SATURDAY'
+ */
+public class NextDay extends ScalarFunction
+        implements BinaryExpression, ExplicitlyCastableSignature, 
PropagateNullableOnDateLikeV2Args {
+    private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            FunctionSignature.ret(DateTimeV2Type.SYSTEM_DEFAULT)
+                    .args(DateTimeV2Type.SYSTEM_DEFAULT, StringType.INSTANCE),
+            
FunctionSignature.ret(DateV2Type.INSTANCE).args(DateV2Type.INSTANCE, 
StringType.INSTANCE),
+            
FunctionSignature.ret(DateTimeType.INSTANCE).args(DateTimeType.INSTANCE, 
StringType.INSTANCE),
+            FunctionSignature.ret(DateType.INSTANCE).args(DateType.INSTANCE, 
StringType.INSTANCE));
+
+    public NextDay(Expression arg0, Expression arg1) {
+        super("next_day", arg0, arg1);
+    }
+
+    @Override
+    public NextDay withChildren(List<Expression> children) {
+        Preconditions.checkArgument(children.size() == 2);
+        return new NextDay(children.get(0), children.get(1));
+    }
+
+    @Override
+    public List<FunctionSignature> getSignatures() {
+        return SIGNATURES;
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitNextDay(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 02fff766d43..e1af90013a1 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
@@ -330,6 +330,7 @@ import 
org.apache.doris.nereids.trees.expressions.functions.scalar.MultiSearchAl
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.MurmurHash332;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.MurmurHash364;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Negative;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.NextDay;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.NgramSearch;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.NormalCdf;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.NotNullOrEmpty;
@@ -1698,6 +1699,10 @@ public interface ScalarFunctionVisitor<R, C> {
         return visitScalarFunction(negative, context);
     }
 
+    default R visitNextDay(NextDay nextDay, C context) {
+        return visitScalarFunction(nextDay, context);
+    }
+
     default R visitNgramSearch(NgramSearch ngramSearch, C context) {
         return visitScalarFunction(ngramSearch, context);
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to