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..cf17e056adb611 100644 --- a/be/src/vec/functions/function_date_or_datetime_computation.cpp +++ b/be/src/vec/functions/function_date_or_datetime_computation.cpp @@ -93,6 +93,9 @@ using FunctionMicroSecToDateTime = TimestampToDateTime; using FunctionMilliSecToDateTime = TimestampToDateTime; using FunctionSecToDateTime = TimestampToDateTime; +using FunctionDatetimeLastDay_DateTime = FunctionDateOrDateTimeComputation>; +using FunctionDatetimeLastDay_Date = FunctionDateOrDateTimeComputation>; + void register_function_date_time_computation(SimpleFunctionFactory& factory) { factory.register_function(); factory.register_function(); @@ -135,6 +138,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/be/src/vec/functions/function_date_or_datetime_computation_v2.cpp b/be/src/vec/functions/function_date_or_datetime_computation_v2.cpp index ec9560456c131a..2fceb98d662715 100644 --- a/be/src/vec/functions/function_date_or_datetime_computation_v2.cpp +++ b/be/src/vec/functions/function_date_or_datetime_computation_v2.cpp @@ -25,7 +25,7 @@ using FunctionAddSecondsV2 = FunctionDateOrDateTimeComputation>; using FunctionAddHoursV2 = FunctionDateOrDateTimeComputation>; using FunctionAddDaysV2 = FunctionDateOrDateTimeComputation>; -using FunctionAddWeeksV2 = FunctionDateOrDateTimeComputation>; +using FunctionAddsV2 = FunctionDateOrDateTimeComputation>; using FunctionAddMonthsV2 = FunctionDateOrDateTimeComputation>; using FunctionAddQuartersV2 = FunctionDateOrDateTimeComputation>; using FunctionAddYearsV2 = FunctionDateOrDateTimeComputation>; @@ -34,7 +34,7 @@ using FunctionSubSecondsV2 = FunctionDateOrDateTimeComputation>; using FunctionSubHoursV2 = FunctionDateOrDateTimeComputation>; using FunctionSubDaysV2 = FunctionDateOrDateTimeComputation>; -using FunctionSubWeeksV2 = FunctionDateOrDateTimeComputation>; +using FunctionSubsV2 = FunctionDateOrDateTimeComputation>; using FunctionSubMonthsV2 = FunctionDateOrDateTimeComputation>; using FunctionSubQuartersV2 = FunctionDateOrDateTimeComputation>; @@ -112,6 +112,18 @@ using FunctionDatetimeV2ToYearWeekTwoArgs = FunctionDateOrDateTimeComputation>; using FunctionDatetimeV2ToWeekTwoArgs = FunctionDateOrDateTimeComputation>; +using FunctionDatetimeV2LastDay_DateTimeV2 = + FunctionDateOrDateTimeComputation>; +using FunctionDatetimeV2LastDay_DateV2 = + FunctionDateOrDateTimeComputation>; +using FunctionDatetimeV2NextDay_DateTimeV2 = + FunctionDateOrDateTimeComputation>; +using FunctionDatetimeV2NextDay_DateV2 = + FunctionDateOrDateTimeComputation>; +using FunctionDatetimeV2PreviousDay_DateTimeV2 = + FunctionDateOrDateTimeComputation>; +using FunctionDatetimeV2PreviousDay_DateV2 = + FunctionDateOrDateTimeComputation>; void register_function_date_time_computation_v2(SimpleFunctionFactory& factory) { factory.register_function(); @@ -179,6 +191,13 @@ void register_function_date_time_computation_v2(SimpleFunctionFactory& factory) factory.register_function(); factory.register_function(); factory.register_function(); + factory.register_function(); + factory.register_function(); + factory.register_function(); + factory.register_function(); + factory.register_function(); + factory.register_function(); + } } // namespace doris::vectorized 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..43fca8c2ae486e 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 @@ -34,12 +34,16 @@ import java.util.List; /** - * ScalarFunction 'last_day'. This class is generated by GenerateFunction. + * ScalarFunction 'last_day'. This class is not 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,13 +62,76 @@ 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 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..d021658a4683f1 --- /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 not 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..7b727a14fca32a --- /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 not 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; + } +} diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java index 0601b3b558d882..db4654665e56d6 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java @@ -644,7 +644,9 @@ void testDateTypeDateTimeArithmeticFunctions() { "'2002-06-30'", "'1997-06-30'", "'2000-07-28'", "'1999-06-04'", "'2000-01-30'", "'1999-12-01'", "1999", "4", "12", "6", "31", "365", "31", - "'1999-12-31'", "'1999-12-27'", "'1999-12-31'" + "'1999-12-31'", "'1999-12-27'", + "'1999-12-31'", "'1999-12-31'", "'2000-01-02'", + "'1999-12-31'", "'1999-12-31'", "'1999-12-31'" }; int answerIdx = 0; @@ -670,7 +672,13 @@ void testDateTypeDateTimeArithmeticFunctions() { Assertions.assertEquals(DateTimeExtractAndTransform.dateFormat(dateLiteral, format).toSql(), answer[answerIdx++]); Assertions.assertEquals(DateTimeExtractAndTransform.toMonday(dateLiteral).toSql(), answer[answerIdx++]); - Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral).toSql(), answer[answerIdx]); + + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("day")).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("week")).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("month")).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("quarter")).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("year")).toSql(), answer[answerIdx]); } @Test @@ -685,7 +693,9 @@ void testDateTimeTypeDateTimeArithmeticFunctions() { "'2000-01-02 05:59:59'", "'1999-12-30 17:59:59'", "'2000-01-01 00:29:59'", "'1999-12-31 23:29:59'", "'2000-01-01 00:00:29'", "'1999-12-31 23:59:29'", "1999", "4", "12", "6", "31", "365", "31", "23", "59", "59", - "'1999-12-31'", "'1999-12-27'", "'1999-12-31'", "'1999-12-31'", "730484", "'1999-12-31'" + "'1999-12-31'", "'1999-12-27'", "'1999-12-31'", "730484", "'1999-12-31'", + "'1999-12-31'", "'1999-12-31'", "'2000-01-02'", + "'1999-12-31'", "'1999-12-31'", "'1999-12-31'" }; int answerIdx = 0; @@ -722,10 +732,16 @@ void testDateTimeTypeDateTimeArithmeticFunctions() { Assertions.assertEquals(DateTimeExtractAndTransform.dateFormat(dateLiteral, format).toSql(), answer[answerIdx++]); Assertions.assertEquals(DateTimeExtractAndTransform.toMonday(dateLiteral).toSql(), answer[answerIdx++]); - Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral).toSql(), answer[answerIdx++]); Assertions.assertEquals(DateTimeExtractAndTransform.toDate(dateLiteral).toSql(), answer[answerIdx++]); Assertions.assertEquals(DateTimeExtractAndTransform.toDays(dateLiteral).toSql(), answer[answerIdx++]); - Assertions.assertEquals(DateTimeExtractAndTransform.date(dateLiteral).toSql(), answer[answerIdx]); + Assertions.assertEquals(DateTimeExtractAndTransform.date(dateLiteral).toSql(), answer[answerIdx++]); + + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("day")).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("week")).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("month")).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("quarter")).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("year")).toSql(), answer[answerIdx]); } @Test @@ -738,7 +754,10 @@ void testDateV2TypeDateTimeArithmeticFunctions() { "'2000-01-30'", "'1999-12-01'", "'2029-12-31'", "'1969-12-31'", "'2002-06-30'", "'1997-06-30'", "'2000-01-30'", "'1999-12-01'", "1999", "4", "12", "6", "31", "365", "31", - "'1999-12-31'", "'1999-12-27'", "'1999-12-31'" + "'1999-12-31'", "'1999-12-27'", + "'1999-12-31'", "'1999-12-31'", "'2000-01-02'", + "'1999-12-31'", "'1999-12-31'", "'1999-12-31'", + "'2000-01-01'", "'1999-12-30'" }; int answerIdx = 0; @@ -762,7 +781,16 @@ void testDateV2TypeDateTimeArithmeticFunctions() { Assertions.assertEquals(DateTimeExtractAndTransform.dateFormat(dateLiteral, format).toSql(), answer[answerIdx++]); Assertions.assertEquals(DateTimeExtractAndTransform.toMonday(dateLiteral).toSql(), answer[answerIdx++]); - Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral).toSql(), answer[answerIdx]); + + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("day")).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("week")).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("month")).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("quarter")).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("year")).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.nextDay(dateLiteral).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.previousDay(dateLiteral).toSql(), answer[answerIdx]); + } @Test @@ -793,8 +821,12 @@ void testDateTimeV2TypeDateTimeArithmeticFunctions() { "'1999-12-31 23:59:59.000030'", "'1999-12-31 23:59:58.999970'", "'1999-12-31 23:59:59.030000'", "'1999-12-31 23:59:58.970000'", "1999", "4", "12", "6", "31", "365", "31", "23", "59", "59", - "'1999-12-31'", "'1999-12-27'", "'1999-12-31'", "'1999-12-31'", "730484", "'1999-12-31'", - "'1999-12-31'" + "'1999-12-31'", "'1999-12-27'", "'1999-12-31'", "730484", "'1999-12-31'", + "'1999-12-31'", + "'2000-01-01'", "'1999-12-30'", "'1999-12-31'", + "'1999-12-31'", "'2000-01-02'", "'1999-12-31'", + "'1999-12-31'", "'1999-12-31'" + }; int answerIdx = 0; @@ -839,12 +871,20 @@ void testDateTimeV2TypeDateTimeArithmeticFunctions() { Assertions.assertEquals(DateTimeExtractAndTransform.dateFormat(dateLiteral, format).toSql(), answer[answerIdx++]); Assertions.assertEquals(DateTimeExtractAndTransform.toMonday(dateLiteral).toSql(), answer[answerIdx++]); - Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral).toSql(), answer[answerIdx++]); Assertions.assertEquals(DateTimeExtractAndTransform.toDate(dateLiteral).toSql(), answer[answerIdx++]); Assertions.assertEquals(DateTimeExtractAndTransform.toDays(dateLiteral).toSql(), answer[answerIdx++]); Assertions.assertEquals(DateTimeExtractAndTransform.date(dateLiteral).toSql(), answer[answerIdx++]); - Assertions.assertEquals(DateTimeExtractAndTransform.dateV2(dateLiteral).toSql(), answer[answerIdx]); + Assertions.assertEquals(DateTimeExtractAndTransform.dateV2(dateLiteral).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.nextDay(dateLiteral).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.previousDay(dateLiteral).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("day")).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("week")).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("month")).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("quarter")).toSql(), answer[answerIdx++]); + Assertions.assertEquals(DateTimeExtractAndTransform.lastDay(dateLiteral, new VarcharLiteral("year")).toSql(), answer[answerIdx]); + Assertions.assertEquals("'2021 52 2021 52'", DateTimeExtractAndTransform.dateFormat( new DateTimeLiteral("2022-01-01 00:12:42"), new VarcharLiteral("%x %v %X %V")).toSql());