This is an automated email from the ASF dual-hosted git repository. morrysnow 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 9bbf67975f9 [enhance](nerieds) month, day, hour, minute, second, day_of_year, day_of_month, week_of_year implement monotonic (#45928) 9bbf67975f9 is described below commit 9bbf67975f935b3d4cbe8d5236d4b6d0d6200f77 Author: feiniaofeiafei <moail...@selectdb.com> AuthorDate: Fri Jan 3 14:15:04 2025 +0800 [enhance](nerieds) month, day, hour, minute, second, day_of_year, day_of_month, week_of_year implement monotonic (#45928) --- .../rules/OneRangePartitionEvaluator.java | 8 +- .../doris/nereids/trees/expressions/Cast.java | 29 ++- .../expressions/functions/FromSecondMonotonic.java | 42 ++++ .../expressions/functions/scalar/DateFormat.java | 15 +- .../expressions/functions/scalar/DayOfMonth.java | 29 ++- .../expressions/functions/scalar/DayOfYear.java | 28 ++- .../functions/scalar/FromMicrosecond.java | 9 +- .../functions/scalar/FromMillisecond.java | 9 +- .../expressions/functions/scalar/FromSecond.java | 9 +- .../expressions/functions/scalar/FromUnixtime.java | 38 +++- .../trees/expressions/functions/scalar/Hour.java | 30 ++- .../expressions/functions/scalar/MakeDate.java | 18 +- .../expressions/functions/scalar/Microsecond.java | 37 +++- .../trees/expressions/functions/scalar/Minute.java | 35 +++- .../trees/expressions/functions/scalar/Month.java | 28 ++- .../expressions/functions/scalar/Quarter.java | 28 ++- .../trees/expressions/functions/scalar/Second.java | 36 +++- .../expressions/functions/scalar/WeeksAdd.java | 8 +- .../expressions/functions/scalar/WeeksDiff.java | 13 +- .../expressions/functions/scalar/WeeksSub.java | 8 +- .../expressions/functions/scalar/YearWeek.java | 30 ++- .../org/apache/doris/nereids/util/DateUtils.java | 6 + .../int_as_date_partition_col.groovy | 6 - .../month_quarter_cast_in_prune.groovy | 226 +++++++++++++++++++++ .../test_add_sub_diff_ceil_floor.groovy | 51 +++++ 25 files changed, 736 insertions(+), 40 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/OneRangePartitionEvaluator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/OneRangePartitionEvaluator.java index 90b5af14931..03eba5a2f99 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/OneRangePartitionEvaluator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/OneRangePartitionEvaluator.java @@ -832,6 +832,7 @@ public class OneRangePartitionEvaluator<K> if (!checkFoldConstantValueIsValid(lowerValue, upperValue)) { return result; } + if (!func.isPositive()) { Expression temp = lowerValue; lowerValue = upperValue; @@ -865,10 +866,7 @@ public class OneRangePartitionEvaluator<K> if (lowerValue instanceof NullLiteral || upperValue instanceof NullLiteral) { return false; } - if (lowerValue != null && !(lowerValue instanceof Literal) - || upperValue != null && !(upperValue instanceof Literal)) { - return false; - } - return true; + return (lowerValue == null || lowerValue instanceof Literal) + && (upperValue == null || upperValue instanceof Literal); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Cast.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Cast.java index 20f8079bd9f..0b280af2363 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Cast.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Cast.java @@ -18,9 +18,12 @@ package org.apache.doris.nereids.trees.expressions; import org.apache.doris.nereids.exceptions.UnboundException; +import org.apache.doris.nereids.trees.expressions.functions.Monotonic; +import org.apache.doris.nereids.trees.expressions.literal.Literal; import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.DataType; +import org.apache.doris.nereids.types.coercion.DateLikeType; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -31,7 +34,7 @@ import java.util.Objects; /** * cast function. */ -public class Cast extends Expression implements UnaryExpression { +public class Cast extends Expression implements UnaryExpression, Monotonic { // CAST can be from SQL Query or Type Coercion. private final boolean isExplicitType; @@ -117,4 +120,28 @@ public class Cast extends Expression implements UnaryExpression { public int hashCode() { return Objects.hash(super.hashCode(), targetType); } + + @Override + public boolean isPositive() { + return true; + } + + @Override + public int getMonotonicFunctionChildIndex() { + return 0; + } + + @Override + public Expression withConstantArgs(Expression literal) { + return new Cast(literal, targetType, isExplicitType); + } + + @Override + public boolean isMonotonic(Literal lower, Literal upper) { + // Both upward and downward casting of date types satisfy monotonicity. + if (child().getDataType() instanceof DateLikeType && targetType instanceof DateLikeType) { + return true; + } + return false; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/FromSecondMonotonic.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/FromSecondMonotonic.java new file mode 100644 index 00000000000..96dfa7ac650 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/FromSecondMonotonic.java @@ -0,0 +1,42 @@ +// 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; + +import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral; +import org.apache.doris.nereids.trees.expressions.literal.Literal; + +/** monotonicity for from_{xx}second */ +public interface FromSecondMonotonic extends Monotonic { + @Override + default boolean isMonotonic(Literal lower, Literal upper) { + if (lower instanceof BigIntLiteral) { + return ((BigIntLiteral) lower).getValue() >= 0; + } + return false; + } + + @Override + default boolean isPositive() { + return true; + } + + @Override + default int getMonotonicFunctionChildIndex() { + return 0; + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DateFormat.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DateFormat.java index 997464cf81a..98a9f3e3b19 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DateFormat.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DateFormat.java @@ -24,7 +24,7 @@ import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSi import org.apache.doris.nereids.trees.expressions.functions.Monotonic; import org.apache.doris.nereids.trees.expressions.functions.PropagateNullLiteral; import org.apache.doris.nereids.trees.expressions.literal.Literal; -import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral; +import org.apache.doris.nereids.trees.expressions.literal.StringLikeLiteral; 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; @@ -32,13 +32,12 @@ 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.VarcharType; +import org.apache.doris.nereids.util.DateUtils; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import java.util.List; -import java.util.Set; /** * ScalarFunction 'date_format'. This class is generated by GenerateFunction. @@ -54,10 +53,6 @@ public class DateFormat extends ScalarFunction FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(DateType.INSTANCE, VarcharType.SYSTEM_DEFAULT) ); - private static final Set<String> monoFormat = ImmutableSet.of("yyyyMMdd", "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", - "%Y", "%Y-%m", "%Y-%m-%d", "%Y-%m-%d %H", "%Y-%m-%d %H:%i", "%Y-%m-%d %H:%i:%s", "%Y-%m-%d %H:%i:%S", - "%Y-%m-%d %T", "%Y%m%d", "%Y%m"); - /** * constructor with 2 arguments. */ @@ -87,11 +82,11 @@ public class DateFormat extends ScalarFunction @Override public boolean isMonotonic(Literal lower, Literal upper) { Expression format = child(1); - if (!(format instanceof VarcharLiteral)) { + if (!(format instanceof StringLikeLiteral)) { return false; } - String str = ((VarcharLiteral) format).getValue(); - return monoFormat.contains(str); + String str = ((StringLikeLiteral) format).getValue(); + return DateUtils.monoFormat.contains(str); } @Override diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DayOfMonth.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DayOfMonth.java index a64bff850b7..16ef08a00f0 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DayOfMonth.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DayOfMonth.java @@ -20,7 +20,10 @@ 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.Monotonic; import org.apache.doris.nereids.trees.expressions.functions.PropagateNullableOnDateLikeV2Args; +import org.apache.doris.nereids.trees.expressions.literal.DateLiteral; +import org.apache.doris.nereids.trees.expressions.literal.Literal; 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; @@ -37,7 +40,7 @@ import java.util.List; * ScalarFunction 'dayofmonth'. This class is generated by GenerateFunction. */ public class DayOfMonth extends ScalarFunction - implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args { + implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args, Monotonic { public static final List<FunctionSignature> SIGNATURES = ImmutableList.of( FunctionSignature.ret(TinyIntType.INSTANCE).args(DateV2Type.INSTANCE), @@ -70,4 +73,28 @@ public class DayOfMonth extends ScalarFunction public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { return visitor.visitDayOfMonth(this, context); } + + @Override + public boolean isPositive() { + return true; + } + + @Override + public int getMonotonicFunctionChildIndex() { + return 0; + } + + @Override + public Expression withConstantArgs(Expression literal) { + return new DayOfMonth(literal); + } + + @Override + public boolean isMonotonic(Literal lower, Literal upper) { + if (lower instanceof DateLiteral && upper instanceof DateLiteral) { + return ((DateLiteral) lower).getYear() == ((DateLiteral) upper).getYear() + && ((DateLiteral) lower).getMonth() == ((DateLiteral) upper).getMonth(); + } + return false; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DayOfYear.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DayOfYear.java index a32f64325e1..b76ebc77763 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DayOfYear.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DayOfYear.java @@ -20,7 +20,10 @@ 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.Monotonic; import org.apache.doris.nereids.trees.expressions.functions.PropagateNullableOnDateLikeV2Args; +import org.apache.doris.nereids.trees.expressions.literal.DateLiteral; +import org.apache.doris.nereids.trees.expressions.literal.Literal; 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; @@ -37,7 +40,7 @@ import java.util.List; * ScalarFunction 'dayofyear'. This class is generated by GenerateFunction. */ public class DayOfYear extends ScalarFunction - implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args { + implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args, Monotonic { public static final List<FunctionSignature> SIGNATURES = ImmutableList.of( FunctionSignature.ret(SmallIntType.INSTANCE).args(DateV2Type.INSTANCE), @@ -70,4 +73,27 @@ public class DayOfYear extends ScalarFunction public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { return visitor.visitDayOfYear(this, context); } + + @Override + public boolean isPositive() { + return true; + } + + @Override + public int getMonotonicFunctionChildIndex() { + return 0; + } + + @Override + public Expression withConstantArgs(Expression literal) { + return new DayOfYear(literal); + } + + @Override + public boolean isMonotonic(Literal lower, Literal upper) { + if (lower instanceof DateLiteral && upper instanceof DateLiteral) { + return ((DateLiteral) lower).getYear() == ((DateLiteral) upper).getYear(); + } + return false; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromMicrosecond.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromMicrosecond.java index 32e38858da4..f99f7ca9dbc 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromMicrosecond.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromMicrosecond.java @@ -20,6 +20,7 @@ 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.FromSecondMonotonic; 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; @@ -35,7 +36,8 @@ import java.util.List; * ScalarFunction 'from_microsecond'. */ public class FromMicrosecond extends ScalarFunction - implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args { + implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args, + FromSecondMonotonic { private static final List<FunctionSignature> SIGNATURES = ImmutableList.of( FunctionSignature.ret(DateTimeV2Type.MAX).args(BigIntType.INSTANCE)); @@ -59,4 +61,9 @@ public class FromMicrosecond extends ScalarFunction public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { return visitor.visitScalarFunction(this, context); } + + @Override + public Expression withConstantArgs(Expression literal) { + return new FromMicrosecond(literal); + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromMillisecond.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromMillisecond.java index 658f7444d81..ad0c385bf36 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromMillisecond.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromMillisecond.java @@ -20,6 +20,7 @@ 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.FromSecondMonotonic; 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; @@ -35,7 +36,8 @@ import java.util.List; * ScalarFunction 'from_millisecond'. */ public class FromMillisecond extends ScalarFunction - implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args { + implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args, + FromSecondMonotonic { public static final DateTimeV2Type MillisecondDateTimeV2 = DateTimeV2Type.of(3); private static final List<FunctionSignature> SIGNATURES = ImmutableList.of( FunctionSignature.ret(MillisecondDateTimeV2).args(BigIntType.INSTANCE)); @@ -59,4 +61,9 @@ public class FromMillisecond extends ScalarFunction public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { return visitor.visitScalarFunction(this, context); } + + @Override + public Expression withConstantArgs(Expression literal) { + return new FromMillisecond(literal); + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromSecond.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromSecond.java index 46c550fe78c..fdbbbebf870 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromSecond.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromSecond.java @@ -20,6 +20,7 @@ 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.FromSecondMonotonic; 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; @@ -35,7 +36,8 @@ import java.util.List; * ScalarFunction 'from_second'. */ public class FromSecond extends ScalarFunction - implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args { + implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args, + FromSecondMonotonic { private static final List<FunctionSignature> SIGNATURES = ImmutableList.of( FunctionSignature.ret(DateTimeV2Type.SYSTEM_DEFAULT).args(BigIntType.INSTANCE)); @@ -59,4 +61,9 @@ public class FromSecond extends ScalarFunction public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { return visitor.visitScalarFunction(this, context); } + + @Override + public Expression withConstantArgs(Expression literal) { + return new FromSecond(literal); + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromUnixtime.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromUnixtime.java index 05d5d73e0de..675feb0f355 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromUnixtime.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromUnixtime.java @@ -21,11 +21,15 @@ import org.apache.doris.catalog.FunctionSignature; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable; import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; +import org.apache.doris.nereids.trees.expressions.functions.Monotonic; import org.apache.doris.nereids.trees.expressions.functions.PropagateNullLiteral; +import org.apache.doris.nereids.trees.expressions.literal.Literal; +import org.apache.doris.nereids.trees.expressions.literal.StringLikeLiteral; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.BigIntType; import org.apache.doris.nereids.types.StringType; import org.apache.doris.nereids.types.VarcharType; +import org.apache.doris.nereids.util.DateUtils; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -36,8 +40,7 @@ import java.util.List; * ScalarFunction 'from_unixtime'. This class is generated by GenerateFunction. */ public class FromUnixtime extends ScalarFunction - implements ExplicitlyCastableSignature, AlwaysNullable, PropagateNullLiteral { - + implements ExplicitlyCastableSignature, AlwaysNullable, PropagateNullLiteral, Monotonic { public static final List<FunctionSignature> SIGNATURES = ImmutableList.of( FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(BigIntType.INSTANCE), FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(BigIntType.INSTANCE, VarcharType.SYSTEM_DEFAULT), @@ -81,4 +84,35 @@ public class FromUnixtime extends ScalarFunction public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { return visitor.visitFromUnixtime(this, context); } + + @Override + public boolean isMonotonic(Literal lower, Literal upper) { + if (1 == arity()) { + return true; + } + Expression format = child(1); + if (!(format instanceof StringLikeLiteral)) { + return false; + } + String str = ((StringLikeLiteral) format).getValue(); + return DateUtils.monoFormat.contains(str); + } + + @Override + public boolean isPositive() { + return true; + } + + @Override + public int getMonotonicFunctionChildIndex() { + return 0; + } + + @Override + public Expression withConstantArgs(Expression literal) { + if (1 == arity()) { + return new FromUnixtime(literal); + } + return new FromUnixtime(literal, child(1)); + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Hour.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Hour.java index 60a57ff96be..768ddbbd686 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Hour.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Hour.java @@ -20,7 +20,10 @@ 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.Monotonic; import org.apache.doris.nereids.trees.expressions.functions.PropagateNullableOnDateLikeV2Args; +import org.apache.doris.nereids.trees.expressions.literal.DateLiteral; +import org.apache.doris.nereids.trees.expressions.literal.Literal; 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; @@ -39,7 +42,7 @@ import java.util.List; * ScalarFunction 'hour'. This class is generated by GenerateFunction. */ public class Hour extends ScalarFunction - implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args { + implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args, Monotonic { public static final List<FunctionSignature> SIGNATURES = ImmutableList.of( FunctionSignature.ret(TinyIntType.INSTANCE).args(DateTimeV2Type.SYSTEM_DEFAULT), @@ -72,4 +75,29 @@ public class Hour extends ScalarFunction public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { return visitor.visitHour(this, context); } + + @Override + public boolean isPositive() { + return true; + } + + @Override + public int getMonotonicFunctionChildIndex() { + return 0; + } + + @Override + public Expression withConstantArgs(Expression literal) { + return new Hour(literal); + } + + @Override + public boolean isMonotonic(Literal lower, Literal upper) { + if (lower instanceof DateLiteral && upper instanceof DateLiteral) { + return ((DateLiteral) lower).getYear() == ((DateLiteral) upper).getYear() + && ((DateLiteral) lower).getMonth() == ((DateLiteral) upper).getMonth() + && ((DateLiteral) lower).getDay() == ((DateLiteral) upper).getDay(); + } + return false; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MakeDate.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MakeDate.java index 8b5215251dd..6c217b92f81 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MakeDate.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MakeDate.java @@ -20,7 +20,9 @@ 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.AlwaysNullable; +import org.apache.doris.nereids.trees.expressions.functions.DateDiffMonotonic; import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; +import org.apache.doris.nereids.trees.expressions.literal.Literal; import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.DateType; @@ -35,7 +37,7 @@ import java.util.List; * ScalarFunction 'makedate'. This class is generated by GenerateFunction. */ public class MakeDate extends ScalarFunction - implements BinaryExpression, ExplicitlyCastableSignature, AlwaysNullable { + implements BinaryExpression, ExplicitlyCastableSignature, AlwaysNullable, DateDiffMonotonic { public static final List<FunctionSignature> SIGNATURES = ImmutableList.of( FunctionSignature.ret(DateType.INSTANCE).args(IntegerType.INSTANCE, IntegerType.INSTANCE) @@ -66,4 +68,18 @@ public class MakeDate extends ScalarFunction public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { return visitor.visitMakeDate(this, context); } + + @Override + public boolean isPositive() { + return true; + } + + @Override + public Expression withConstantArgs(Expression literal) { + if (child(1) instanceof Literal) { + return new MakeDate(literal, child(1)); + } else { + return new MakeDate(child(0), literal); + } + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Microsecond.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Microsecond.java index 4e610e21bed..5f5fe3e4fd1 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Microsecond.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Microsecond.java @@ -20,7 +20,11 @@ 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.Monotonic; import org.apache.doris.nereids.trees.expressions.functions.PropagateNullableOnDateLikeV2Args; +import org.apache.doris.nereids.trees.expressions.literal.DateLiteral; +import org.apache.doris.nereids.trees.expressions.literal.DateTimeLiteral; +import org.apache.doris.nereids.trees.expressions.literal.Literal; import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.DateTimeV2Type; @@ -35,7 +39,7 @@ import java.util.List; * ScalarFunction 'microsecond'. This class is generated by GenerateFunction. */ public class Microsecond extends ScalarFunction - implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args { + implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args, Monotonic { public static final List<FunctionSignature> SIGNATURES = ImmutableList.of( FunctionSignature.ret(IntegerType.INSTANCE).args(DateTimeV2Type.SYSTEM_DEFAULT) @@ -66,4 +70,35 @@ public class Microsecond extends ScalarFunction public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { return visitor.visitMicrosecond(this, context); } + + @Override + public boolean isPositive() { + return true; + } + + @Override + public int getMonotonicFunctionChildIndex() { + return 0; + } + + @Override + public Expression withConstantArgs(Expression literal) { + return new Microsecond(literal); + } + + @Override + public boolean isMonotonic(Literal lower, Literal upper) { + if (lower instanceof DateTimeLiteral && upper instanceof DateTimeLiteral) { + DateTimeLiteral lowerDateTime = (DateTimeLiteral) lower; + DateTimeLiteral upperDateTime = (DateTimeLiteral) upper; + return lowerDateTime.getYear() == upperDateTime.getYear() + && lowerDateTime.getMonth() == upperDateTime.getMonth() + && lowerDateTime.getDay() == upperDateTime.getDay() + && lowerDateTime.getHour() == upperDateTime.getHour() + && lowerDateTime.getMinute() == upperDateTime.getMinute() + && lowerDateTime.getSecond() == upperDateTime.getSecond(); + } else { + return lower instanceof DateLiteral && upper instanceof DateLiteral; + } + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Minute.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Minute.java index 790b0378235..9959fafbaad 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Minute.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Minute.java @@ -20,7 +20,11 @@ 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.Monotonic; import org.apache.doris.nereids.trees.expressions.functions.PropagateNullableOnDateLikeV2Args; +import org.apache.doris.nereids.trees.expressions.literal.DateLiteral; +import org.apache.doris.nereids.trees.expressions.literal.DateTimeLiteral; +import org.apache.doris.nereids.trees.expressions.literal.Literal; 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; @@ -38,7 +42,7 @@ import java.util.List; * ScalarFunction 'minute'. This class is generated by GenerateFunction. */ public class Minute extends ScalarFunction - implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args { + implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args, Monotonic { private static final List<FunctionSignature> SIGNATURES = ImmutableList.of( FunctionSignature.ret(TinyIntType.INSTANCE).args(DateTimeV2Type.SYSTEM_DEFAULT), @@ -71,4 +75,33 @@ public class Minute extends ScalarFunction public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { return visitor.visitMinute(this, context); } + + @Override + public boolean isPositive() { + return true; + } + + @Override + public int getMonotonicFunctionChildIndex() { + return 0; + } + + @Override + public Expression withConstantArgs(Expression literal) { + return new Minute(literal); + } + + @Override + public boolean isMonotonic(Literal lower, Literal upper) { + if (lower instanceof DateTimeLiteral && upper instanceof DateTimeLiteral) { + DateTimeLiteral lowerDateTime = (DateTimeLiteral) lower; + DateTimeLiteral upperDateTime = (DateTimeLiteral) upper; + return lowerDateTime.getYear() == upperDateTime.getYear() + && lowerDateTime.getMonth() == upperDateTime.getMonth() + && lowerDateTime.getDay() == upperDateTime.getDay() + && lowerDateTime.getHour() == upperDateTime.getHour(); + } else { + return lower instanceof DateLiteral && upper instanceof DateLiteral; + } + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Month.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Month.java index 9f8d38dc759..bff6cc30a3f 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Month.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Month.java @@ -20,7 +20,10 @@ 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.Monotonic; import org.apache.doris.nereids.trees.expressions.functions.PropagateNullableOnDateLikeV2Args; +import org.apache.doris.nereids.trees.expressions.literal.DateLiteral; +import org.apache.doris.nereids.trees.expressions.literal.Literal; 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; @@ -37,7 +40,7 @@ import java.util.List; * ScalarFunction 'month'. This class is generated by GenerateFunction. */ public class Month extends ScalarFunction - implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args { + implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args, Monotonic { private static final List<FunctionSignature> SIGNATURES = ImmutableList.of( FunctionSignature.ret(TinyIntType.INSTANCE).args(DateV2Type.INSTANCE), @@ -70,4 +73,27 @@ public class Month extends ScalarFunction public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { return visitor.visitMonth(this, context); } + + @Override + public boolean isPositive() { + return true; + } + + @Override + public int getMonotonicFunctionChildIndex() { + return 0; + } + + @Override + public Expression withConstantArgs(Expression literal) { + return new Month(literal); + } + + @Override + public boolean isMonotonic(Literal lower, Literal upper) { + if (lower instanceof DateLiteral && upper instanceof DateLiteral) { + return ((DateLiteral) lower).getYear() == ((DateLiteral) upper).getYear(); + } + return false; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Quarter.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Quarter.java index 3a88b2dbe8f..70135b938ae 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Quarter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Quarter.java @@ -20,7 +20,10 @@ 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.Monotonic; import org.apache.doris.nereids.trees.expressions.functions.PropagateNullableOnDateLikeV2Args; +import org.apache.doris.nereids.trees.expressions.literal.DateLiteral; +import org.apache.doris.nereids.trees.expressions.literal.Literal; 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; @@ -37,7 +40,7 @@ import java.util.List; * ScalarFunction 'quarter'. This class is generated by GenerateFunction. */ public class Quarter extends ScalarFunction - implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args { + implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args, Monotonic { public static final List<FunctionSignature> SIGNATURES = ImmutableList.of( FunctionSignature.ret(TinyIntType.INSTANCE).args(DateTimeType.INSTANCE), @@ -70,4 +73,27 @@ public class Quarter extends ScalarFunction public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { return visitor.visitQuarter(this, context); } + + @Override + public boolean isPositive() { + return true; + } + + @Override + public int getMonotonicFunctionChildIndex() { + return 0; + } + + @Override + public Expression withConstantArgs(Expression literal) { + return new Quarter(literal); + } + + @Override + public boolean isMonotonic(Literal lower, Literal upper) { + if (lower instanceof DateLiteral && upper instanceof DateLiteral) { + return ((DateLiteral) lower).getYear() == ((DateLiteral) upper).getYear(); + } + return false; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Second.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Second.java index 8f36817b4d0..a7dc75be1e9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Second.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Second.java @@ -20,7 +20,11 @@ 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.Monotonic; import org.apache.doris.nereids.trees.expressions.functions.PropagateNullableOnDateLikeV2Args; +import org.apache.doris.nereids.trees.expressions.literal.DateLiteral; +import org.apache.doris.nereids.trees.expressions.literal.DateTimeLiteral; +import org.apache.doris.nereids.trees.expressions.literal.Literal; 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; @@ -38,7 +42,7 @@ import java.util.List; * ScalarFunction 'second'. This class is generated by GenerateFunction. */ public class Second extends ScalarFunction - implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args { + implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args, Monotonic { private static final List<FunctionSignature> SIGNATURES = ImmutableList.of( FunctionSignature.ret(TinyIntType.INSTANCE).args(DateTimeV2Type.SYSTEM_DEFAULT), @@ -71,4 +75,34 @@ public class Second extends ScalarFunction public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { return visitor.visitSecond(this, context); } + + @Override + public boolean isPositive() { + return true; + } + + @Override + public int getMonotonicFunctionChildIndex() { + return 0; + } + + @Override + public Expression withConstantArgs(Expression literal) { + return new Second(literal); + } + + @Override + public boolean isMonotonic(Literal lower, Literal upper) { + if (lower instanceof DateTimeLiteral && upper instanceof DateTimeLiteral) { + DateTimeLiteral lowerDateTime = (DateTimeLiteral) lower; + DateTimeLiteral upperDateTime = (DateTimeLiteral) upper; + return lowerDateTime.getYear() == upperDateTime.getYear() + && lowerDateTime.getMonth() == upperDateTime.getMonth() + && lowerDateTime.getDay() == upperDateTime.getDay() + && lowerDateTime.getHour() == upperDateTime.getHour() + && lowerDateTime.getMinute() == upperDateTime.getMinute(); + } else { + return lower instanceof DateLiteral && upper instanceof DateLiteral; + } + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/WeeksAdd.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/WeeksAdd.java index 938822c1d21..607096f8322 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/WeeksAdd.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/WeeksAdd.java @@ -21,6 +21,7 @@ import org.apache.doris.catalog.FunctionSignature; import org.apache.doris.common.Config; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.functions.ComputeSignatureForDateArithmetic; +import org.apache.doris.nereids.trees.expressions.functions.DateAddSubMonotonic; 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; @@ -41,7 +42,7 @@ import java.util.List; */ public class WeeksAdd extends ScalarFunction implements BinaryExpression, ExplicitlyCastableSignature, - ComputeSignatureForDateArithmetic, PropagateNullableOnDateLikeV2Args { + ComputeSignatureForDateArithmetic, PropagateNullableOnDateLikeV2Args, DateAddSubMonotonic { // When enable_date_conversion is true, we prefer to V2 signature. // This preference follows original planner. refer to ScalarType.getDefaultDateType() @@ -78,4 +79,9 @@ public class WeeksAdd extends ScalarFunction public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { return visitor.visitWeeksAdd(this, context); } + + @Override + public Expression withConstantArgs(Expression literal) { + return new WeeksAdd(literal, child(1)); + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/WeeksDiff.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/WeeksDiff.java index dfacc8137be..3a31e1f56d0 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/WeeksDiff.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/WeeksDiff.java @@ -19,8 +19,10 @@ 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.DateDiffMonotonic; 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.literal.Literal; import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.BigIntType; @@ -37,7 +39,7 @@ import java.util.List; * ScalarFunction 'weeks_diff'. This class is generated by GenerateFunction. */ public class WeeksDiff extends ScalarFunction - implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args { + implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args, DateDiffMonotonic { private static final List<FunctionSignature> SIGNATURES = ImmutableList.of( FunctionSignature.ret(BigIntType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE), @@ -73,4 +75,13 @@ public class WeeksDiff extends ScalarFunction public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { return visitor.visitWeeksDiff(this, context); } + + @Override + public Expression withConstantArgs(Expression literal) { + if (child(1) instanceof Literal) { + return new WeeksDiff(literal, child(1)); + } else { + return new WeeksDiff(child(0), literal); + } + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/WeeksSub.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/WeeksSub.java index 0be7a20d4c6..d088fb4de1c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/WeeksSub.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/WeeksSub.java @@ -21,6 +21,7 @@ import org.apache.doris.catalog.FunctionSignature; import org.apache.doris.common.Config; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.functions.ComputeSignatureForDateArithmetic; +import org.apache.doris.nereids.trees.expressions.functions.DateAddSubMonotonic; 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; @@ -41,7 +42,7 @@ import java.util.List; */ public class WeeksSub extends ScalarFunction implements BinaryExpression, ExplicitlyCastableSignature, - ComputeSignatureForDateArithmetic, PropagateNullableOnDateLikeV2Args { + ComputeSignatureForDateArithmetic, PropagateNullableOnDateLikeV2Args, DateAddSubMonotonic { // When enable_date_conversion is true, we prefer to V2 signature. // This preference follows original planner. refer to ScalarType.getDefaultDateType() @@ -78,4 +79,9 @@ public class WeeksSub extends ScalarFunction public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { return visitor.visitWeeksSub(this, context); } + + @Override + public Expression withConstantArgs(Expression literal) { + return new WeeksSub(literal, child(1)); + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/YearWeek.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/YearWeek.java index 5afc52b2f66..2dba1d9cd31 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/YearWeek.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/YearWeek.java @@ -20,7 +20,9 @@ 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.Monotonic; import org.apache.doris.nereids.trees.expressions.functions.PropagateNullableOnDateLikeV2Args; +import org.apache.doris.nereids.trees.expressions.literal.Literal; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.DateTimeType; import org.apache.doris.nereids.types.DateTimeV2Type; @@ -36,7 +38,7 @@ import java.util.List; * ScalarFunction 'yearweek'. This class is generated by GenerateFunction. */ public class YearWeek extends ScalarFunction - implements ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args { + implements ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args, Monotonic { private static final List<FunctionSignature> SIGNATURES = ImmutableList.of( FunctionSignature.ret(IntegerType.INSTANCE).args(DateV2Type.INSTANCE), @@ -84,4 +86,30 @@ public class YearWeek extends ScalarFunction public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { return visitor.visitYearWeek(this, context); } + + @Override + public boolean isMonotonic(Literal lower, Literal upper) { + if (arity() == 1) { + return true; + } + return child(1) instanceof Literal; + } + + @Override + public boolean isPositive() { + return true; + } + + @Override + public int getMonotonicFunctionChildIndex() { + return 0; + } + + @Override + public Expression withConstantArgs(Expression literal) { + if (arity() == 1) { + return new YearWeek(literal); + } + return new YearWeek(literal, child(1)); + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/DateUtils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/DateUtils.java index 354d78d0271..fdd2fe3a22b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/DateUtils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/DateUtils.java @@ -20,6 +20,8 @@ package org.apache.doris.nereids.util; import org.apache.doris.nereids.exceptions.AnalysisException; import org.apache.doris.qe.ConnectContext; +import com.google.common.collect.ImmutableSet; + import java.time.DayOfWeek; import java.time.LocalDateTime; import java.time.ZoneId; @@ -31,11 +33,15 @@ import java.time.temporal.ChronoField; import java.time.temporal.IsoFields; import java.time.temporal.TemporalAccessor; import java.time.temporal.WeekFields; +import java.util.Set; /** * date util tools. */ public class DateUtils { + public static final Set<String> monoFormat = ImmutableSet.of("yyyyMMdd", "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", + "%Y", "%Y-%m", "%Y-%m-%d", "%Y-%m-%d %H", "%Y-%m-%d %H:%i", "%Y-%m-%d %H:%i:%s", "%Y-%m-%d %H:%i:%S", + "%Y-%m-%d %T", "%Y%m%d", "%Y%m"); private static final WeekFields weekFields = WeekFields.of(DayOfWeek.SUNDAY, 7); /** diff --git a/regression-test/suites/nereids_rules_p0/partition_prune/int_as_date_partition_col.groovy b/regression-test/suites/nereids_rules_p0/partition_prune/int_as_date_partition_col.groovy index 9d4e2a16490..59467e48306 100644 --- a/regression-test/suites/nereids_rules_p0/partition_prune/int_as_date_partition_col.groovy +++ b/regression-test/suites/nereids_rules_p0/partition_prune/int_as_date_partition_col.groovy @@ -80,12 +80,6 @@ suite("int_as_date_partition_col") { contains("partitions=5/6 (p20240101,p20240201,p20240301,p20240401,p20240501)") } - explain { - sql """SELECT count(*) FROM partition_int WHERE - !(date_trunc(dt,'month')<'2024-8-01' and date_trunc(dt,'month')>'2024-6-01' );""" - contains("partitions=5/6 (p20240101,p20240201,p20240301,p20240401,p20240501)") - } - explain { sql """ SELECT count(*) FROM partition_int WHERE diff --git a/regression-test/suites/nereids_rules_p0/partition_prune/month_quarter_cast_in_prune.groovy b/regression-test/suites/nereids_rules_p0/partition_prune/month_quarter_cast_in_prune.groovy new file mode 100644 index 00000000000..f2ac6c85d54 --- /dev/null +++ b/regression-test/suites/nereids_rules_p0/partition_prune/month_quarter_cast_in_prune.groovy @@ -0,0 +1,226 @@ +// 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. + +suite("month_quarter_cast_in_prune") { + sql "drop table if exists test_month;" + sql """create table test_month(a int,dt datetime(3)) + partition by range(dt) ( + partition p1 values less than ('2021-01-01'), + partition p2 values less than ('2021-02-01'), + partition p3 values less than ('2021-03-01'), + partition p4 values less than ('2021-07-01'), + partition p5 values less than ('2022-02-01'), + partition p6 values less than ('2022-02-25'), + partition p7 values less than ('2022-02-26 12:00:00'), + partition p8 values less than ('2022-02-26 12:10:30'), + partition p9 values less than ('2022-02-26 12:10:59'), + partition p10 values less than ('2022-02-26 12:10:59.342'), + partition p11 values less than (MAXVALUE) + ) + distributed by hash(a) + properties("replication_num"="1");""" + + sql """insert into test_month values(1,'2020-01-01'),(1,'2021-01-31'),(1,'2021-02-11'),(1,'2021-03-31'),(1,'2021-07-10'),(1,'2022-02-10'),(1,'2022-02-26'), + (1,'2022-02-26 12:09:00'),(1,'2022-02-26 12:10:01'),(1,'2022-03-03'),(1,'2022-02-26 12:10:41'),(1,'2022-02-26 12:10:59.123');""" + + explain { + sql "select * from test_month where month(dt)<3" + contains("partitions=10/11 (p1,p2,p3,p5,p6,p7,p8,p9,p10,p11)") + }; + explain { + sql "select * from test_month where month(dt)>3" + contains("partitions=4/11 (p1,p4,p5,p11)") + }; + explain { + sql "select * from test_month where quarter(dt)>1" + contains("partitions=4/11 (p1,p4,p5,p11)") + }; + explain { + sql "select * from test_month where day(dt)>27" + contains("partitions=6/11 (p1,p2,p3,p4,p5,p11)") + }; + explain { + sql "select * from test_month where hour(dt)<10" + contains("partitions=8/11 (p1,p2,p3,p4,p5,p6,p7,p11)") + }; + explain { + sql "select * from test_month where second(dt)<20" + contains("partitions=9/11 (p1,p2,p3,p4,p5,p6,p7,p8,p11)") + }; + explain { + sql "select * from test_month where microsecond(dt)>500000" + contains("partitions=10/11 (p1,p2,p3,p4,p5,p6,p7,p8,p9,p11)") + } + explain { + sql "select * from test_month where dayofyear(dt)>150" + contains("partitions=4/11 (p1,p4,p5,p11)") + }; + explain { + sql "select * from test_month where dayofmonth(dt)<25" + contains("partitions=7/11 (p1,p2,p3,p4,p5,p6,p11)") + }; + explain { + sql "select * from test_month where weekofyear(dt)>40" + contains("partitions=11/11 (p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11)") + }; + explain { + sql "select * from test_month where cast(dt as date) > '2022-02-26'" + contains("partitions=5/11 (p7,p8,p9,p10,p11)") + } + + explain { + sql "select * from test_month where month(dt)>3 and dt>'2021-01-02'" + contains("partitions=3/11 (p4,p5,p11)") + } + explain { + sql "select * from test_month where quarter(dt)>1 or cast(dt as date) > '2022-02-26'" + contains("partitions=8/11 (p1,p4,p5,p7,p8,p9,p10,p11)") + } + explain { + sql "select * from test_month where day(dt)>80" + contains("partitions=6/11 (p1,p2,p3,p4,p5,p11)") + } + explain { + sql "select * from test_month where hour(dt)<=100;" + contains("partitions=11/11 (p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11)") + } + explain { + sql "select * from test_month where dayofyear(dt)>150 or dt='2021-02-01'" + contains("partitions=5/11 (p1,p3,p4,p5,p11)") + } + explain { + sql "select * from test_month where dayofyear(dt)>150 or dt!='2021-02-01'" + contains("partitions=11/11 (p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11)") + } + explain { + sql "select * from test_month where dayofmonth(dt)<25 and dt>='2021-07-01'" + contains("partitions=3/11 (p5,p6,p11)") + } + explain { + sql "select * from test_month where dayofmonth(dt)=24" + contains("partitions=7/11 (p1,p2,p3,p4,p5,p6,p11)") + } + + sql "drop table if exists monotonic_function_t" + sql """create table monotonic_function_t (a bigint, dt datetime, d date, c varchar(100)) duplicate key(a) + partition by range(a) ( + partition p1 values less than ("100000"), + partition p2 values less than ("1000000009999"), + partition p3 values less than ("1000000009999999"), + partition p4 values less than MAXVALUE + ) distributed by hash(a) properties("replication_num"="1");""" + sql """INSERT INTO monotonic_function_t values(10000,'1979-01-01','1979-01-01','abc'),(100000009999,'2012-01-01','2012-01-01','abc'),(100000009999999,'2020-01-01','2020-01-01','abc'),(10000000099999999,'2045-01-01','2045-01-01','abc')""" + + explain { + sql """select * from monotonic_function_t where from_second(a) < '2001-09-09 12:33:19' """ + contains("partitions=4/4 (p1,p2,p3,p4)") + } + explain { + sql """select * from monotonic_function_t where from_second(a) > '2001-09-09 12:33:19' """ + contains("partitions=4/4 (p1,p2,p3,p4)") + } + explain { + sql """select * from monotonic_function_t where from_millisecond(a) < '2001-09-09 12:33:19' """ + contains("partitions=4/4 (p1,p2,p3,p4)") + } + explain { + sql """select * from monotonic_function_t where from_millisecond(a) > '2001-09-09 12:33:19' """ + contains("partitions=3/4 (p1,p3,p4)") + } + explain { + sql """select * from monotonic_function_t where from_microsecond(a) < '2000-09-09 12:33:19' """ + contains("partitions=3/4 (p1,p2,p3)") + } + explain { + sql """select * from monotonic_function_t where from_microsecond(a) > '2002-09-09 12:33:19' """ + contains("partitions=2/4 (p1,p4)") + } + + // test makedate + sql "drop table if exists makedate_t" + sql """create table makedate_t(a int, b int) partition by range(a)( + partition p1 values less than ("2"), + partition p2 values less than ("200"), + partition p3 values less than("1000"), + partition p4 values less than ("2100"), + partition p5 values less than ("3500"), + partition p6 values less than("5003"), + partition p7 values less than(MAXVALUE) + ) + distributed by hash(a) properties("replication_num"="1");""" + + sql "insert into makedate_t values(1,2),(100, 9),(500,10),(2000,101),(3000,103),(5000,101),(6000,1)" + + explain { + sql "select * from makedate_t where makedate(a,10)<'2024-01-01'" + contains("partitions=4/7 (p1,p2,p3,p4)") + }; + explain { + sql "select * from makedate_t where makedate(2000,a)>'2024-01-01'" + contains("partitions=2/7 (p1,p7)") + }; + explain { + sql "select * from makedate_t where makedate(2023,a)>'2024-01-01'" + contains("partitions=6/7 (p1,p3,p4,p5,p6,p7)") + }; + explain { + sql "select * from makedate_t where makedate(2023,b)>'2024-01-01'" + contains("partitions=7/7 (p1,p2,p3,p4,p5,p6,p7)") + }; + explain { + sql "select * from makedate_t where makedate(a,b)>'2024-01-01'" + contains("partitions=7/7 (p1,p2,p3,p4,p5,p6,p7)") + }; + + sql "drop table if exists from_unixtime_t;" + sql """create table from_unixtime_t(a bigint, b int) partition by range(a)( + partition p1 values less than ("50000000"), + partition p2 values less than ("990000000"), + partition p3 values less than("2000000000"), + partition p4 values less than ("2500000000"), + partition p5 values less than(MAXVALUE) + ) + distributed by hash(a) properties("replication_num"="1");""" + sql "insert into from_unixtime_t values(1000,10),(50000001,11),(990000001,12),(2000000002,13),(2500000003,14);" + + explain { + sql """select * from from_unixtime_t where from_unixtime(a,"%Y-%m-%d %T") <'2001-05-16 16:00:00'""" + contains("partitions=2/5 (p1,p2)") + } + explain { + sql """select * from from_unixtime_t where from_unixtime(a,"%Y-%m-%d %T") <='2001-05-16 16:00:00'""" + contains("partitions=3/5 (p1,p2,p3)") + } + + explain { + sql """select * from from_unixtime_t where from_unixtime(a,"yyyyMMdd") < '20330518'""" + contains("partitions=3/5 (p1,p2,p3)") + } + explain { + sql """select * from from_unixtime_t where from_unixtime(a,"yyyyMMdd") > '20330518'""" + contains("partitions=3/5 (p1,p4,p5)") + + } + explain { + sql """select * from from_unixtime_t where from_unixtime(a,"%yyyyMMdd") > '20330518'""" + contains("partitions=5/5 (p1,p2,p3,p4,p5)") + } + explain { + sql """select * from from_unixtime_t where from_unixtime(a,"yyyyMMdd %T") <='2001-05-16 16:00:00'""" + contains("partitions=5/5 (p1,p2,p3,p4,p5)") + } +} \ No newline at end of file diff --git a/regression-test/suites/nereids_rules_p0/partition_prune/test_add_sub_diff_ceil_floor.groovy b/regression-test/suites/nereids_rules_p0/partition_prune/test_add_sub_diff_ceil_floor.groovy index bda9dc81af7..eb0be34704f 100644 --- a/regression-test/suites/nereids_rules_p0/partition_prune/test_add_sub_diff_ceil_floor.groovy +++ b/regression-test/suites/nereids_rules_p0/partition_prune/test_add_sub_diff_ceil_floor.groovy @@ -342,6 +342,41 @@ suite("test_add_sub_diff_ceil_floor") { contains("partitions=1/6 (p6)") } + explain { + sql """select * from max_t where weeks_add(dt, 1) >'2018-01-01' """ + contains("partitions=5/6 (p2,p3,p4,p5,p6)") + } + explain { + sql """select * from max_t where weeks_sub(dt, 10) >'2018-01-01' """ + contains("partitions=5/6 (p1,p3,p4,p5,p6)") + } + explain { + sql """select * from max_t where weeks_diff(dt, '2018-01-01') >=10""" + contains("partitions=4/6 (p3,p4,p5,p6)") + } + explain { + sql """select * from max_t where weeks_diff('2018-01-01', dt) <=10""" + contains("partitions=5/6 (p2,p3,p4,p5,p6)") + } + // yearweek + explain { + sql """select * from max_t where yearweek(dt) <201902""" + contains("partitions=4/6 (p1,p2,p3,p4)") + } + explain { + sql """select * from max_t where yearweek(dt,1) <201902""" + contains("partitions=4/6 (p1,p2,p3,p4)") + } + explain { + sql """select * from max_t where yearweek(dt,c) <20190206""" + contains("partitions=6/6 (p1,p2,p3,p4,p5,p6)") + } + + // yearweek + explain { + sql """select * from max_t where yearweek(dt) <20190206""" + contains("partitions=6/6 (p1,p2,p3,p4,p5,p6)") + } // from_days and unix_timestamp explain { sql """select * from max_t where unix_timestamp(dt) > 1547838847 """ @@ -404,4 +439,20 @@ suite("test_add_sub_diff_ceil_floor") { contains("partitions=3/4 (p1,p3,p4)") } + explain { + sql """select * from max_t where year(weeks_add(dt, 1)) >2019""" + contains("partitions=3/6 (p4,p5,p6)") + } + explain { + sql """select * from max_t where month(weeks_add(dt, 1)) >6""" + contains("partitions=6/6 (p1,p2,p3,p4,p5,p6)") + } + explain { + sql """select * from max_t where quarter(weeks_sub(dt, 1)) >3""" + contains("partitions=6/6 (p1,p2,p3,p4,p5,p6)") + } + explain { + sql """select * from max_t where weeks_diff(dt, quarter(weeks_sub(dt, 1))) >'2020-01-01'""" + contains("partitions=6/6 (p1,p2,p3,p4,p5,p6)") + } } \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org