From 1fca6b69011bfd11ceb915ca5e7f2ee22da555d2 Mon Sep 17 00:00:00 2001 From: cat-with-cat Date: Tue, 17 Dec 2024 17:43:14 +0800 Subject: [PATCH] The draft of the test code has not been implemented1 --- .../function_date_or_datetime_computation.cpp | 2 + .../function_date_or_datetime_computation.h | 17 ++++ .../executable/NumericArithmetic.java | 3 + .../expressions/functions/scalar/LastDay.java | 81 +++++++++++++++++-- .../expressions/functions/scalar/NextDay.java | 81 +++++++++++++++++++ .../functions/scalar/PreviousDay.java | 81 +++++++++++++++++++ 6 files changed, 258 insertions(+), 7 deletions(-) create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/NextDay.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/PreviousDay.java 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 f6bf806ad46c1d..e8c909165ec327 100644 --- a/be/src/vec/functions/function_date_or_datetime_computation.cpp +++ b/be/src/vec/functions/function_date_or_datetime_computation.cpp @@ -135,6 +135,8 @@ void register_function_date_time_computation(SimpleFunctionFactory& factory) { factory.register_function(); factory.register_function(); factory.register_function(); + factory.register_function(); + factory.register_function(); // alias factory.register_alias("days_add", "date_add"); 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 ac18965749eb8e..c84b92cc94eb71 100644 --- a/be/src/vec/functions/function_date_or_datetime_computation.h +++ b/be/src/vec/functions/function_date_or_datetime_computation.h @@ -1050,6 +1050,22 @@ struct Sec { static constexpr auto name = "from_second"; static constexpr Int64 ratio = 1; }; +struct NextDayImpl { + static constexpr auto name = "next_day"; + static constexpr int64_t day_seconds = 86400; + template + static void calculate(const DateType& date, DateType& result) { + result = date + day_seconds; + } +}; +struct PreviousDayImpl { + static constexpr auto name = "previous_day"; + static constexpr int64_t day_seconds = 86400; + template + static void calculate(const DateType& date, DateType& result) { + result = date - day_seconds; + } +}; template struct TimestampToDateTime : IFunction { using ReturnType = DataTypeDateTimeV2; @@ -1090,6 +1106,7 @@ struct TimestampToDateTime : IFunction { if (dt.is_valid_date()) [[likely]] { dt.set_microsecond((value % Impl::ratio) * ratio_to_micro); + Impl::calculate(dt, dt); } else { null_map[i] = true; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/NumericArithmetic.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/NumericArithmetic.java index 325e676fc046a0..4d2d4c2bcbf2c9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/NumericArithmetic.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/NumericArithmetic.java @@ -34,6 +34,8 @@ import org.apache.doris.nereids.trees.expressions.literal.StringLiteral; import org.apache.doris.nereids.trees.expressions.literal.TinyIntLiteral; import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral; +import org.apache.doris.nereids.types.DateV2Type; +import org.apache.doris.nereids.types.DateTimeV2Type; import org.apache.doris.nereids.types.DecimalV3Type; import java.math.BigDecimal; @@ -1154,4 +1156,5 @@ public static Expression truncate(DecimalV3Literal first, IntegerLiteral second) } } + } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/LastDay.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/LastDay.java index bd3783abd9a963..1f91558e1b12ea 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/LastDay.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/LastDay.java @@ -37,9 +37,13 @@ * ScalarFunction 'last_day'. This class is generated by GenerateFunction. */ public class LastDay extends ScalarFunction - implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args { + implements ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args { public static final List SIGNATURES = ImmutableList.of( + FunctionSignature.ret(DateV2Type.INSTANCE).args(DateV2Type.INSTANCE, StringType.INSTANCE), + FunctionSignature.ret(DateV2Type.INSTANCE).args(DateTimeV2Type.SYSTEM_DEFAULT, StringType.INSTANCE), + FunctionSignature.ret(DateType.INSTANCE).args(DateType.INSTANCE, StringType.INSTANCE), + FunctionSignature.ret(DateType.INSTANCE).args(DateTimeType.INSTANCE, StringType.INSTANCE), FunctionSignature.ret(DateV2Type.INSTANCE).args(DateV2Type.INSTANCE), FunctionSignature.ret(DateV2Type.INSTANCE).args(DateTimeV2Type.SYSTEM_DEFAULT), FunctionSignature.ret(DateType.INSTANCE).args(DateType.INSTANCE), @@ -47,10 +51,10 @@ public class LastDay extends ScalarFunction ); /** - * constructor with 1 argument. + * constructor with 2 argument. */ - public LastDay(Expression arg) { - super("last_day", arg); + public LastDay(Expression arg, Expression timeUnit) { + super("last_day", arg, timeUnit); } /** @@ -58,15 +62,78 @@ public LastDay(Expression arg) { */ @Override public LastDay withChildren(List children) { - Preconditions.checkArgument(children.size() == 1); - return new LastDay(children.get(0)); + Preconditions.checkArgument(children.size() == 1 || children.size() == 2); + if (children.size() == 1) { + return new LastDay(children.get(0), null); + } else { + return new LastDay(children.get(0), children.get(1)); + } } @Override public R accept(ExpressionVisitor visitor, C context) { - return visitor.visitLastDay(this, context); + if (getChildren().size() == 2) { + Expression timeUnit = getChildren().get(1); + String unit = timeUnit.toString(); + switch (unit.toLowerCase()) { + case "day": + return calculateLastDayOfDay(visitor, context); + case "week": + return calculateLastDayOfWeek(visitor, context); + case "quarter": + return calculateLastDayOfQuarter(visitor, context); + case "year": + return calculateLastDayOfYear(visitor, context); + case "month": + return calculateLastDayOfMonth(visitor, context); + } + } else { + + return calculateLastDayOfMonth(visitor, context); + } + } + + private R calculateLastDayOfDay(ExpressionVisitor visitor, C context) { + LocalDate currentDate = toJavaDateType().toLocalDate(); + return (R) new DateLiteral(currentDate.getYear(), currentDate.getMonthValue(), currentDate.getDayOfMonth()); + } + + private R calculateLastDayOfWeek(ExpressionVisitor visitor, C context) { + LocalDate currentDate = toJavaDateType().toLocalDate(); + int dayOfWeek = currentDate.getDayOfWeek().getValue(); + LocalDate lastDayOfWeek = currentDate.plusDays(7 - dayOfWeek); + return (R) new DateLiteral(lastDayOfWeek.getYear(), lastDayOfWeek.getMonthValue(), lastDayOfWeek.getDayOfMonth()); } + private R calculateLastDayOfMonth(ExpressionVisitor visitor, C context) { + LocalDate currentDate = toJavaDateType().toLocalDate(); + LocalDate lastDayOfMonth = currentDate.withDayOfMonth(currentDate.lengthOfMonth()); + return (R) new DateLiteral(lastDayOfMonth.getYear(), lastDayOfMonth.getMonthValue(), lastDayOfMonth.getDayOfMonth()); + } + + private R calculateLastDayOfQuarter(ExpressionVisitor visitor, C context) { + LocalDate currentDate = toJavaDateType().toLocalDate(); + int month = currentDate.getMonthValue(); + int lastMonthOfQuarter = ((month - 1) / 3 + 1) * 3; + LocalDate lastDayOfQuarter; + if (lastMonthOfQuarter == 3) { + lastDayOfQuarter = LocalDate.of(currentDate.getYear(), 3, 31); + } else if (lastMonthOfQuarter == 6) { + lastDayOfQuarter = LocalDate.of(currentDate.getYear(), 6, 30); + } else if (lastMonthOfQuarter == 9) { + lastDayOfQuarter = LocalDate.of(currentDate.getYear(), 9, 30); + } else { + lastDayOfQuarter = LocalDate.of(currentDate.getYear(), 12, 31); + } + return (R) new DateLiteral(lastDayOfQuarter.getYear(), lastDayOfQuarter.getMonthValue(), lastDayOfQuarter.getDayOfMonth()); + } + + private R calculateLastDayOfYear(ExpressionVisitor visitor, C context) { + LocalDate currentDate = toJavaDateType().toLocalDate(); + LocalDate lastDayOfYear = LocalDate.of(currentDate.getYear(), 12, 31); + return (R) new DateLiteral(lastDayOfYear.getYear(), lastDayOfYear.getMonthValue(), lastDayOfYear.getDayOfMonth()); + } + @Override public List getSignatures() { return SIGNATURES; 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 00000000000000..5b1c852e7aa2e9 --- /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.UnaryExpression; +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 com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; + +import java.time.LocalDate; +import java.util.List; + +/** + * ScalarFunction 'next_day'. This class is generated by GenerateFunction. + */ +public class NextDay extends ScalarFunction + implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args { + + public static final List SIGNATURES = ImmutableList.of( + FunctionSignature.ret(DateV2Type.INSTANCE).args(DateV2Type.INSTANCE), + FunctionSignature.ret(DateV2Type.INSTANCE).args(DateTimeV2Type.SYSTEM_DEFAULT), + FunctionSignature.ret(DateType.INSTANCE).args(DateType.INSTANCE), + FunctionSignature.ret(DateType.INSTANCE).args(DateTimeType.INSTANCE) + ); + + /** + * Constructor with 1 argument. + */ + public NextDay(Expression arg) { + super("next_day", arg); + } + + /** + * withChildren. + */ + @Override + public NextDay withChildren(List children) { + Preconditions.checkArgument(children.size() == 1); + return new NextDay(children.get(0)); + } + + @Override + public R accept(ExpressionVisitor visitor, C context) { + return calculateNextDay(visitor, context); + } + + private R calculateNextDay(ExpressionVisitor visitor, C context) { + LocalDate currentDate = toJavaDateType().toLocalDate(); + LocalDate nextDay = currentDate.plusDays(1); + return (R) new DateLiteral(nextDay.getYear(), nextDay.getMonthValue(), nextDay.getDayOfMonth()); + } + + @Override + public List getSignatures() { + return SIGNATURES; + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/PreviousDay.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/PreviousDay.java new file mode 100644 index 00000000000000..f33b88f3a40156 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/PreviousDay.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.UnaryExpression; +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 com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; + +import java.time.LocalDate; +import java.util.List; + +/** + * ScalarFunction 'previous_day'. This class is generated by GenerateFunction. + */ +public class PreviousDay extends ScalarFunction + implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args { + + public static final List SIGNATURES = ImmutableList.of( + FunctionSignature.ret(DateV2Type.INSTANCE).args(DateV2Type.INSTANCE), + FunctionSignature.ret(DateV2Type.INSTANCE).args(DateTimeV2Type.SYSTEM_DEFAULT), + FunctionSignature.ret(DateType.INSTANCE).args(DateType.INSTANCE), + FunctionSignature.ret(DateType.INSTANCE).args(DateTimeType.INSTANCE) + ); + + /** + * Constructor with 1 argument. + */ + public PreviousDay(Expression arg) { + super("previous_day", arg); + } + + /** + * withChildren. + */ + @Override + public PreviousDay withChildren(List children) { + Preconditions.checkArgument(children.size() == 1); + return new PreviousDay(children.get(0)); + } + + @Override + public R accept(ExpressionVisitor visitor, C context) { + return calculatePreviousDay(visitor, context); + } + + private R calculatePreviousDay(ExpressionVisitor visitor, C context) { + LocalDate currentDate = toJavaDateType().toLocalDate(); + LocalDate previousDay = currentDate.minusDays(1); + return (R) new DateLiteral(previousDay.getYear(), previousDay.getMonthValue(), previousDay.getDayOfMonth()); + } + + @Override + public List getSignatures() { + return SIGNATURES; + } +}