Skip to content

Commit

Permalink
[enhance](nerieds) month, day, hour, minute, second, day_of_year, day…
Browse files Browse the repository at this point in the history
…_of_month, week_of_year implement monotonic (#45928)
  • Loading branch information
feiniaofeiafei authored Jan 3, 2025
1 parent 7380005 commit 9bbf679
Show file tree
Hide file tree
Showing 25 changed files with 736 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,7 @@ private EvaluateRangeResult computeMonotonicFunctionRange(EvaluateRangeResult re
if (!checkFoldConstantValueIsValid(lowerValue, upperValue)) {
return result;
}

if (!func.isPositive()) {
Expression temp = lowerValue;
lowerValue = upperValue;
Expand Down Expand Up @@ -865,10 +866,7 @@ private boolean checkFoldConstantValueIsValid(Expression lowerValue, Expression
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -31,7 +34,7 @@
/**
* 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;
Expand Down Expand Up @@ -117,4 +120,28 @@ public boolean equals(Object o) {
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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,20 @@
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;
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.
Expand All @@ -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.
*/
Expand Down Expand Up @@ -87,11 +82,11 @@ public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
@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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
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;
Expand All @@ -37,7 +40,7 @@
* 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),
Expand Down Expand Up @@ -70,4 +73,28 @@ public List<FunctionSignature> getSignatures() {
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
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;
Expand All @@ -37,7 +40,7 @@
* 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),
Expand Down Expand Up @@ -70,4 +73,27 @@ public List<FunctionSignature> getSignatures() {
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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;
Expand All @@ -35,7 +36,8 @@
* 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));
Expand All @@ -59,4 +61,9 @@ public List<FunctionSignature> getSignatures() {
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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;
Expand All @@ -35,7 +36,8 @@
* 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));
Expand All @@ -59,4 +61,9 @@ public List<FunctionSignature> getSignatures() {
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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;
Expand All @@ -35,7 +36,8 @@
* 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));
Expand All @@ -59,4 +61,9 @@ public List<FunctionSignature> getSignatures() {
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);
}
}
Loading

0 comments on commit 9bbf679

Please sign in to comment.