Skip to content

Commit

Permalink
add lower and upper for isMonotonic
Browse files Browse the repository at this point in the history
  • Loading branch information
feiniaofeiafei committed Dec 17, 2024
1 parent ecca5af commit 5bd5f2a
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
import org.apache.doris.nereids.trees.expressions.literal.MaxLiteral;
import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.BooleanType;
import org.apache.doris.nereids.util.ExpressionUtils;
Expand Down Expand Up @@ -800,9 +801,6 @@ private EvaluateRangeResult computeMonotonicFunctionRange(EvaluateRangeResult re
return new EvaluateRangeResult((Expression) func, ImmutableMap.of((Expression) func,
context.rangeMap.get(func)), result.childrenResult);
}
if (!func.isMonotonic()) {
return result;
}
int childIndex = func.getMonotonicFunctionChildIndex();
Expression funcChild = func.child(childIndex);
boolean isNullable = partitionSlotContainsNull.getOrDefault(funcChild, true);
Expand All @@ -819,13 +817,20 @@ private EvaluateRangeResult computeMonotonicFunctionRange(EvaluateRangeResult re
return result;
}
Range<ColumnBound> span = childRange.span();
// null means positive infinity or negative infinity
Literal lower = span.hasLowerBound() ? span.lowerEndpoint().getValue() : null;
Literal upper = span.hasUpperBound() && !(span.upperEndpoint().getValue() instanceof MaxLiteral)
? span.upperEndpoint().getValue() : null;
if (!func.isMonotonic(lower, upper)) {
return result;
}
Expression lowerValue = lower != null ? FoldConstantRuleOnFE.evaluate(func.withConstantArgs(lower),
expressionRewriteContext) : null;
Expression upperValue = upper != null ? FoldConstantRuleOnFE.evaluate(func.withConstantArgs(upper),
expressionRewriteContext) : null;
if (lowerValue instanceof NullLiteral || upperValue instanceof NullLiteral) {
return result;
}
if (!func.isPositive()) {
Expression temp = lowerValue;
lowerValue = upperValue;
Expand All @@ -845,7 +850,7 @@ private EvaluateRangeResult computeMonotonicFunctionRange(EvaluateRangeResult re
if (upperValue instanceof Literal) {
newRange = newRange.withUpperBound((Literal) upperValue);
}
if (!newRange.span().hasLowerBound() && !newRange.span().hasUpperBound()) {
if (newRange.isEmptyRange() || !newRange.span().hasLowerBound() && !newRange.span().hasUpperBound()) {
return result;
}
context.rangeMap.put((Expression) func, newRange);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
/** monotonicity for XX_ADD XX_SUB */
public interface DateAddSubMonotonic extends Monotonic {
@Override
default boolean isMonotonic() {
default boolean isMonotonic(Literal lower, Literal upper) {
return child(1) instanceof Literal;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
/** monotonicity of XX_CEIL and XX_FLOOR */
public interface DateCeilFloorMonotonic extends Monotonic {
@Override
default boolean isMonotonic() {
default boolean isMonotonic(Literal lower, Literal upper) {
switch (arity()) {
case 1:
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
/** monotonicity for XX_DIFF */
public interface DateDiffMonotonic extends Monotonic {
@Override
default boolean isMonotonic() {
default boolean isMonotonic(Literal lower, Literal upper) {
return !(child(0) instanceof Literal) && child(1) instanceof Literal
|| child(0) instanceof Literal && !(child(1) instanceof Literal);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@
package org.apache.doris.nereids.trees.expressions.functions;

import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.literal.Literal;

/** monotonicity of expressions */
public interface Monotonic extends ExpressionTrait {
default boolean isMonotonic() {
default boolean isMonotonic(Literal lower, Literal upper) {
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
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.shape.UnaryExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
Expand All @@ -36,7 +37,7 @@
* ScalarFunction 'from_days'. This class is generated by GenerateFunction.
*/
public class FromDays extends ScalarFunction
implements UnaryExpression, ExplicitlyCastableSignature, AlwaysNullable, PropagateNullLiteral {
implements UnaryExpression, ExplicitlyCastableSignature, AlwaysNullable, PropagateNullLiteral, Monotonic {

public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
FunctionSignature.ret(DateV2Type.INSTANCE).args(IntegerType.INSTANCE)
Expand Down Expand Up @@ -67,4 +68,19 @@ public List<FunctionSignature> getSignatures() {
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
return visitor.visitFromDays(this, context);
}

@Override
public boolean isPositive() {
return true;
}

@Override
public int getMonotonicFunctionChildIndex() {
return 0;
}

@Override
public Expression withConstantArgs(Expression literal) {
return new FromDays(literal);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
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.literal.DateTimeLiteral;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.DataType;
import org.apache.doris.nereids.types.DateTimeType;
Expand All @@ -39,7 +42,9 @@
/**
* ScalarFunction 'unix_timestamp'. This class is generated by GenerateFunction.
*/
public class UnixTimestamp extends ScalarFunction implements ExplicitlyCastableSignature {
public class UnixTimestamp extends ScalarFunction implements ExplicitlyCastableSignature, Monotonic {
private static final DateTimeLiteral MIN = new DateTimeLiteral("1970-01-01 00:00:00");
private static final DateTimeLiteral MAX = new DateTimeLiteral("2038-01-19 03:14:07");

// we got changes when computeSignature
private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
Expand Down Expand Up @@ -145,4 +150,37 @@ public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
public boolean isDeterministic() {
return !this.children.isEmpty();
}

@Override
public boolean isPositive() {
return true;
}

@Override
public int getMonotonicFunctionChildIndex() {
return 0;
}

@Override
public Expression withConstantArgs(Expression literal) {
return new UnixTimestamp(literal);
}

@Override
public boolean isMonotonic(Literal lower, Literal upper) {
if (arity() != 1) {
return false;
}
if (null == lower) {
lower = DateTimeLiteral.MIN_DATETIME;
}
if (null == upper) {
upper = DateTimeLiteral.MAX_DATETIME;
}
if (lower.compareTo(MAX) <= 0 && upper.compareTo(MAX) > 0) {
return false;
} else {
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,10 @@
* date time literal.
*/
public class DateTimeLiteral extends DateLiteral {
public static final DateTimeLiteral MIN_DATETIME = new DateTimeLiteral(0000, 1, 1, 0, 0, 0);
public static final DateTimeLiteral MAX_DATETIME = new DateTimeLiteral(9999, 12, 31, 23, 59, 59);
protected static final int MAX_MICROSECOND = 999999;

private static final DateTimeLiteral MIN_DATETIME = new DateTimeLiteral(0000, 1, 1, 0, 0, 0);
private static final DateTimeLiteral MAX_DATETIME = new DateTimeLiteral(9999, 12, 31, 23, 59, 59);

private static final Logger LOG = LogManager.getLogger(DateTimeLiteral.class);

protected long hour;
Expand Down

0 comments on commit 5bd5f2a

Please sign in to comment.