From e072ce7f686bfa2552c04494ddb48a7df3f08f7f Mon Sep 17 00:00:00 2001 From: seawinde <149132972+seawinde@users.noreply.github.com> Date: Fri, 30 Aug 2024 07:51:42 +0800 Subject: [PATCH] [fix](nereids) Remove Nondeterministic to avoid ambiguity when decide a expression is nondeterministic or not (#39801) (#40130) ## Proposed changes commitId: 2b715a7e pr: https://github.com/apache/doris/pull/39801 --- .../doris/common/NereidsSqlCacheManager.java | 5 ++-- .../rules/analysis/ExpressionAnalyzer.java | 7 +++-- .../nereids/trees/expressions/Expression.java | 3 +-- .../functions/ExpressionTrait.java | 26 +++++++------------ .../functions/scalar/ConnectionId.java | 8 ++++-- .../functions/scalar/CurrentDate.java | 8 ++++-- .../functions/scalar/CurrentTime.java | 8 ++++-- .../functions/scalar/CurrentUser.java | 8 ++++-- .../functions/scalar/Database.java | 8 ++++-- .../expressions/functions/scalar/Now.java | 8 ++++-- .../expressions/functions/scalar/Random.java | 8 ++++-- .../expressions/functions/scalar/User.java | 8 ++++-- .../functions/scalar/UtcTimestamp.java | 8 ++++-- .../expressions/functions/scalar/Uuid.java | 8 ++++-- .../functions/scalar/UuidNumeric.java | 8 ++++-- .../functions/table/TableValuedFunction.java | 8 ++++-- .../rules/analysis/GenerateFunction.java | 4 --- .../trees/expressions/ExpressionTest.java | 26 +++++++++++++++++++ .../nereids/trees/plans/PlanVisitorTest.java | 16 ++++++++++++ 19 files changed, 130 insertions(+), 53 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/common/NereidsSqlCacheManager.java b/fe/fe-core/src/main/java/org/apache/doris/common/NereidsSqlCacheManager.java index 77f1d929dd..33a33007dc 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/common/NereidsSqlCacheManager.java +++ b/fe/fe-core/src/main/java/org/apache/doris/common/NereidsSqlCacheManager.java @@ -46,7 +46,7 @@ import org.apache.doris.nereids.rules.expression.ExpressionRewriteContext; import org.apache.doris.nereids.rules.expression.rules.FoldConstantRuleOnFE; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.Variable; -import org.apache.doris.nereids.trees.expressions.functions.Nondeterministic; +import org.apache.doris.nereids.trees.expressions.functions.ExpressionTrait; import org.apache.doris.nereids.trees.plans.Plan; import org.apache.doris.nereids.trees.plans.RelationId; import org.apache.doris.nereids.trees.plans.logical.LogicalEmptyRelation; @@ -400,7 +400,8 @@ public class NereidsSqlCacheManager { Variable currentVariable = currentVariables.get(i); Variable cachedVariable = cachedUsedVariables.get(i); if (!Objects.equals(currentVariable, cachedVariable) - || cachedVariable.getRealExpression().anyMatch(Nondeterministic.class::isInstance)) { + || cachedVariable.getRealExpression().anyMatch( + expr -> !((ExpressionTrait) expr).isDeterministic())) { return true; } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/ExpressionAnalyzer.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/ExpressionAnalyzer.java index 91b5bf671c..8624ba205c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/ExpressionAnalyzer.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/ExpressionAnalyzer.java @@ -65,7 +65,6 @@ import org.apache.doris.nereids.trees.expressions.Variable; import org.apache.doris.nereids.trees.expressions.WhenClause; import org.apache.doris.nereids.trees.expressions.functions.BoundFunction; import org.apache.doris.nereids.trees.expressions.functions.FunctionBuilder; -import org.apache.doris.nereids.trees.expressions.functions.Nondeterministic; import org.apache.doris.nereids.trees.expressions.functions.agg.Count; import org.apache.doris.nereids.trees.expressions.functions.scalar.ElementAt; import org.apache.doris.nereids.trees.expressions.functions.scalar.Lambda; @@ -177,11 +176,11 @@ public class ExpressionAnalyzer extends SubExprAnalyzer sqlCacheContext = Optional.empty(); if (wantToParseSqlFromSqlCache) { StatementContext statementContext = context.cascadesContext.getStatementContext(); - if (buildResult.second instanceof Nondeterministic) { + if (!buildResult.second.isDeterministic()) { hasNondeterministic = true; } sqlCacheContext = statementContext.getSqlCacheContext(); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java index e355cd204c..5bb8355477 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java @@ -25,7 +25,6 @@ import org.apache.doris.nereids.exceptions.AnalysisException; import org.apache.doris.nereids.trees.AbstractTreeNode; import org.apache.doris.nereids.trees.expressions.ArrayItemReference.ArrayItemSlot; import org.apache.doris.nereids.trees.expressions.functions.ExpressionTrait; -import org.apache.doris.nereids.trees.expressions.functions.Nondeterministic; import org.apache.doris.nereids.trees.expressions.functions.agg.AggregateFunction; import org.apache.doris.nereids.trees.expressions.functions.scalar.Lambda; import org.apache.doris.nereids.trees.expressions.literal.Literal; @@ -350,7 +349,7 @@ public abstract class Expression extends AbstractTreeNode implements if (this instanceof LeafExpression) { return this instanceof Literal; } else { - return !(this instanceof Nondeterministic) && ExpressionUtils.allMatch(children(), Expression::isConstant); + return this.isDeterministic() && ExpressionUtils.allMatch(children(), Expression::isConstant); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ExpressionTrait.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ExpressionTrait.java index 2e69a5ecd1..daaab359e8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ExpressionTrait.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ExpressionTrait.java @@ -26,7 +26,6 @@ import org.apache.doris.nereids.types.DataType; import com.google.common.collect.ImmutableList; import java.util.List; -import java.util.Optional; /** * ExpressionTrait. @@ -79,23 +78,16 @@ public interface ExpressionTrait extends TreeNode { } /** - * Identify the expression is deterministic or not + * Identify the expression itself is deterministic or not, default true */ default boolean isDeterministic() { - boolean isDeterministic = true; - List children = this.children(); - if (children.isEmpty()) { - return isDeterministic; - } - for (Expression child : children) { - Optional nonDeterministic = - child.collectFirst(expressionTreeNode -> expressionTreeNode instanceof ExpressionTrait - && !((ExpressionTrait) expressionTreeNode).isDeterministic()); - if (nonDeterministic.isPresent()) { - isDeterministic = false; - break; - } - } - return isDeterministic; + return true; + } + + /** + * Identify the expression is containing deterministic expr or not + */ + default boolean containsNondeterministic() { + return anyMatch(expr -> !((ExpressionTrait) expr).isDeterministic()); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ConnectionId.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ConnectionId.java index 6f17e247c4..145e516255 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ConnectionId.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ConnectionId.java @@ -20,7 +20,6 @@ package org.apache.doris.nereids.trees.expressions.functions.scalar; import org.apache.doris.catalog.FunctionSignature; import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable; import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; -import org.apache.doris.nereids.trees.expressions.functions.Nondeterministic; import org.apache.doris.nereids.trees.expressions.shape.LeafExpression; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.BigIntType; @@ -33,7 +32,7 @@ import java.util.List; * ScalarFunction 'ConnectionId'. */ public class ConnectionId extends ScalarFunction - implements LeafExpression, ExplicitlyCastableSignature, AlwaysNotNullable, Nondeterministic { + implements LeafExpression, ExplicitlyCastableSignature, AlwaysNotNullable { public static final List SIGNATURES = ImmutableList.of( FunctionSignature.ret(BigIntType.INSTANCE).args() @@ -52,4 +51,9 @@ public class ConnectionId extends ScalarFunction public R accept(ExpressionVisitor visitor, C context) { return visitor.visitConnectionId(this, context); } + + @Override + public boolean isDeterministic() { + return false; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentDate.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentDate.java index bca7ffd05c..04d42932ac 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentDate.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentDate.java @@ -20,7 +20,6 @@ package org.apache.doris.nereids.trees.expressions.functions.scalar; import org.apache.doris.catalog.FunctionSignature; import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable; import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; -import org.apache.doris.nereids.trees.expressions.functions.Nondeterministic; import org.apache.doris.nereids.trees.expressions.shape.LeafExpression; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.DateType; @@ -33,7 +32,7 @@ import java.util.List; * ScalarFunction 'current_date'. This class is generated by GenerateFunction. */ public class CurrentDate extends ScalarFunction - implements LeafExpression, ExplicitlyCastableSignature, Nondeterministic, AlwaysNotNullable { + implements LeafExpression, ExplicitlyCastableSignature, AlwaysNotNullable { public static final List SIGNATURES = ImmutableList.of( FunctionSignature.ret(DateType.INSTANCE).args() @@ -55,4 +54,9 @@ public class CurrentDate extends ScalarFunction public R accept(ExpressionVisitor visitor, C context) { return visitor.visitCurrentDate(this, context); } + + @Override + public boolean isDeterministic() { + return false; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentTime.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentTime.java index 2e09c36d85..a748078eb4 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentTime.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentTime.java @@ -20,7 +20,6 @@ package org.apache.doris.nereids.trees.expressions.functions.scalar; import org.apache.doris.catalog.FunctionSignature; import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable; import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; -import org.apache.doris.nereids.trees.expressions.functions.Nondeterministic; import org.apache.doris.nereids.trees.expressions.shape.LeafExpression; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.TimeType; @@ -33,7 +32,7 @@ import java.util.List; * ScalarFunction 'current_time'. This class is generated by GenerateFunction. */ public class CurrentTime extends ScalarFunction - implements LeafExpression, ExplicitlyCastableSignature, Nondeterministic, AlwaysNotNullable { + implements LeafExpression, ExplicitlyCastableSignature, AlwaysNotNullable { public static final List SIGNATURES = ImmutableList.of( FunctionSignature.ret(TimeType.INSTANCE).args() @@ -55,4 +54,9 @@ public class CurrentTime extends ScalarFunction public R accept(ExpressionVisitor visitor, C context) { return visitor.visitCurrentTime(this, context); } + + @Override + public boolean isDeterministic() { + return false; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentUser.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentUser.java index 5f00e37471..081037f5c1 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentUser.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentUser.java @@ -20,7 +20,6 @@ package org.apache.doris.nereids.trees.expressions.functions.scalar; import org.apache.doris.catalog.FunctionSignature; import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable; import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; -import org.apache.doris.nereids.trees.expressions.functions.Nondeterministic; import org.apache.doris.nereids.trees.expressions.shape.LeafExpression; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.StringType; @@ -33,7 +32,7 @@ import java.util.List; * ScalarFunction 'CurrentUser'. */ public class CurrentUser extends ScalarFunction - implements LeafExpression, ExplicitlyCastableSignature, AlwaysNotNullable, Nondeterministic { + implements LeafExpression, ExplicitlyCastableSignature, AlwaysNotNullable { public static final List SIGNATURES = ImmutableList.of( FunctionSignature.ret(StringType.INSTANCE).args() @@ -52,4 +51,9 @@ public class CurrentUser extends ScalarFunction public R accept(ExpressionVisitor visitor, C context) { return visitor.visitCurrentUser(this, context); } + + @Override + public boolean isDeterministic() { + return false; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Database.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Database.java index c213fc6bc5..888eb9ccb6 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Database.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Database.java @@ -20,7 +20,6 @@ package org.apache.doris.nereids.trees.expressions.functions.scalar; import org.apache.doris.catalog.FunctionSignature; import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable; import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; -import org.apache.doris.nereids.trees.expressions.functions.Nondeterministic; import org.apache.doris.nereids.trees.expressions.shape.LeafExpression; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.VarcharType; @@ -33,7 +32,7 @@ import java.util.List; * ScalarFunction 'database'. */ public class Database extends ScalarFunction - implements LeafExpression, ExplicitlyCastableSignature, AlwaysNotNullable, Nondeterministic { + implements LeafExpression, ExplicitlyCastableSignature, AlwaysNotNullable { public static final List SIGNATURES = ImmutableList.of( FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args() @@ -52,4 +51,9 @@ public class Database extends ScalarFunction public R accept(ExpressionVisitor visitor, C context) { return visitor.visitDatabase(this, context); } + + @Override + public boolean isDeterministic() { + return false; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Now.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Now.java index 90b1f77a37..1befaa6d29 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Now.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Now.java @@ -21,7 +21,6 @@ import org.apache.doris.catalog.FunctionSignature; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.functions.DateTimeWithPrecision; import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; -import org.apache.doris.nereids.trees.expressions.functions.Nondeterministic; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.DateTimeType; import org.apache.doris.nereids.types.DateTimeV2Type; @@ -35,7 +34,7 @@ import java.util.List; /** * ScalarFunction 'now'. This class is generated by GenerateFunction. */ -public class Now extends DateTimeWithPrecision implements ExplicitlyCastableSignature, Nondeterministic { +public class Now extends DateTimeWithPrecision implements ExplicitlyCastableSignature { public static final List SIGNATURES = ImmutableList.of( FunctionSignature.ret(DateTimeType.INSTANCE).args(), @@ -91,4 +90,9 @@ public class Now extends DateTimeWithPrecision implements ExplicitlyCastableSign public R accept(ExpressionVisitor visitor, C context) { return visitor.visitNow(this, context); } + + @Override + public boolean isDeterministic() { + return false; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Random.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Random.java index 5045d85c91..4c658414aa 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Random.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Random.java @@ -21,7 +21,6 @@ import org.apache.doris.catalog.FunctionSignature; import org.apache.doris.nereids.exceptions.AnalysisException; 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.Nondeterministic; import org.apache.doris.nereids.trees.expressions.literal.Literal; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.BigIntType; @@ -36,7 +35,7 @@ import java.util.List; * ScalarFunction 'random'. This class is generated by GenerateFunction. */ public class Random extends ScalarFunction - implements ExplicitlyCastableSignature, Nondeterministic { + implements ExplicitlyCastableSignature { public static final List SIGNATURES = ImmutableList.of( FunctionSignature.ret(DoubleType.INSTANCE).args(), @@ -119,4 +118,9 @@ public class Random extends ScalarFunction public R accept(ExpressionVisitor visitor, C context) { return visitor.visitRandom(this, context); } + + @Override + public boolean isDeterministic() { + return false; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/User.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/User.java index 6cf547f8ab..e56d12e80b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/User.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/User.java @@ -20,7 +20,6 @@ package org.apache.doris.nereids.trees.expressions.functions.scalar; import org.apache.doris.catalog.FunctionSignature; import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable; import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; -import org.apache.doris.nereids.trees.expressions.functions.Nondeterministic; import org.apache.doris.nereids.trees.expressions.shape.LeafExpression; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.VarcharType; @@ -33,7 +32,7 @@ import java.util.List; * ScalarFunction 'User'. */ public class User extends ScalarFunction - implements LeafExpression, ExplicitlyCastableSignature, AlwaysNotNullable, Nondeterministic { + implements LeafExpression, ExplicitlyCastableSignature, AlwaysNotNullable { public static final List SIGNATURES = ImmutableList.of( FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args() @@ -52,4 +51,9 @@ public class User extends ScalarFunction public R accept(ExpressionVisitor visitor, C context) { return visitor.visitUser(this, context); } + + @Override + public boolean isDeterministic() { + return false; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/UtcTimestamp.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/UtcTimestamp.java index 2a775223cc..67b4b4bc94 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/UtcTimestamp.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/UtcTimestamp.java @@ -20,7 +20,6 @@ package org.apache.doris.nereids.trees.expressions.functions.scalar; import org.apache.doris.catalog.FunctionSignature; import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable; import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; -import org.apache.doris.nereids.trees.expressions.functions.Nondeterministic; import org.apache.doris.nereids.trees.expressions.shape.LeafExpression; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.DateTimeType; @@ -33,7 +32,7 @@ import java.util.List; * ScalarFunction 'utc_timestamp'. This class is generated by GenerateFunction. */ public class UtcTimestamp extends ScalarFunction - implements LeafExpression, ExplicitlyCastableSignature, Nondeterministic, AlwaysNotNullable { + implements LeafExpression, ExplicitlyCastableSignature, AlwaysNotNullable { public static final List SIGNATURES = ImmutableList.of( FunctionSignature.ret(DateTimeType.INSTANCE).args() @@ -55,4 +54,9 @@ public class UtcTimestamp extends ScalarFunction public R accept(ExpressionVisitor visitor, C context) { return visitor.visitUtcTimestamp(this, context); } + + @Override + public boolean isDeterministic() { + return false; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Uuid.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Uuid.java index 8949290783..1df3121969 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Uuid.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Uuid.java @@ -20,7 +20,6 @@ package org.apache.doris.nereids.trees.expressions.functions.scalar; import org.apache.doris.catalog.FunctionSignature; import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable; import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; -import org.apache.doris.nereids.trees.expressions.functions.Nondeterministic; import org.apache.doris.nereids.trees.expressions.shape.LeafExpression; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.VarcharType; @@ -33,7 +32,7 @@ import java.util.List; * ScalarFunction 'uuid'. This class is generated by GenerateFunction. */ public class Uuid extends ScalarFunction - implements LeafExpression, ExplicitlyCastableSignature, Nondeterministic, AlwaysNotNullable { + implements LeafExpression, ExplicitlyCastableSignature, AlwaysNotNullable { public static final List SIGNATURES = ImmutableList.of( FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args() @@ -60,4 +59,9 @@ public class Uuid extends ScalarFunction public List getSignatures() { return SIGNATURES; } + + @Override + public boolean isDeterministic() { + return false; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/UuidNumeric.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/UuidNumeric.java index bbbd2e81a9..141d64bb41 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/UuidNumeric.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/UuidNumeric.java @@ -20,7 +20,6 @@ package org.apache.doris.nereids.trees.expressions.functions.scalar; import org.apache.doris.catalog.FunctionSignature; import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable; import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; -import org.apache.doris.nereids.trees.expressions.functions.Nondeterministic; import org.apache.doris.nereids.trees.expressions.shape.LeafExpression; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.LargeIntType; @@ -33,7 +32,7 @@ import java.util.List; * ScalarFunction 'uuid_numeric'. This class is generated by GenerateFunction. */ public class UuidNumeric extends ScalarFunction - implements LeafExpression, ExplicitlyCastableSignature, Nondeterministic, AlwaysNotNullable { + implements LeafExpression, ExplicitlyCastableSignature, AlwaysNotNullable { public static final List SIGNATURES = ImmutableList.of( FunctionSignature.ret(LargeIntType.INSTANCE).args() @@ -60,4 +59,9 @@ public class UuidNumeric extends ScalarFunction public List getSignatures() { return SIGNATURES; } + + @Override + public boolean isDeterministic() { + return false; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/table/TableValuedFunction.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/table/TableValuedFunction.java index 1b619a400d..706277fd30 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/table/TableValuedFunction.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/table/TableValuedFunction.java @@ -27,7 +27,6 @@ import org.apache.doris.nereids.trees.expressions.Properties; import org.apache.doris.nereids.trees.expressions.Slot; import org.apache.doris.nereids.trees.expressions.functions.BoundFunction; import org.apache.doris.nereids.trees.expressions.functions.CustomSignature; -import org.apache.doris.nereids.trees.expressions.functions.Nondeterministic; 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; @@ -47,7 +46,7 @@ import java.util.stream.Collectors; /** TableValuedFunction */ public abstract class TableValuedFunction extends BoundFunction - implements UnaryExpression, CustomSignature, Nondeterministic { + implements UnaryExpression, CustomSignature { protected final Supplier catalogFunctionCache = Suppliers.memoize(this::toCatalogFunction); protected final Supplier tableCache = Suppliers.memoize(() -> { @@ -141,4 +140,9 @@ public abstract class TableValuedFunction extends BoundFunction public String toString() { return toSql(); } + + @Override + public boolean isDeterministic() { + return false; + } } diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/GenerateFunction.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/GenerateFunction.java index 514062b679..2d010df4c5 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/GenerateFunction.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/GenerateFunction.java @@ -44,7 +44,6 @@ import org.apache.doris.nereids.trees.expressions.functions.DecimalWiderPrecisio import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; import org.apache.doris.nereids.trees.expressions.functions.IdenticalSignature; import org.apache.doris.nereids.trees.expressions.functions.ImplicitlyCastableSignature; -import org.apache.doris.nereids.trees.expressions.functions.Nondeterministic; import org.apache.doris.nereids.trees.expressions.functions.NullOrIdenticalSignature; import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable; import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral; @@ -739,9 +738,6 @@ public class GenerateFunction { interfaces.add(arityExpressionType); } interfaces.add(getComputeSignatureInterface(functionName)); - if (functionSet.isNondeterministicFunction(functionName)) { - interfaces.add(Nondeterministic.class); - } Function function = functions.get(0); if (!customNullableFunctions.contains(functionName)) { diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionTest.java index d673cfa9a0..cb43efb0b3 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionTest.java @@ -17,8 +17,13 @@ package org.apache.doris.nereids.trees.expressions; +import org.apache.doris.nereids.trees.expressions.functions.scalar.CurrentDate; +import org.apache.doris.nereids.trees.expressions.functions.scalar.DaysAdd; +import org.apache.doris.nereids.trees.expressions.functions.scalar.UnixTimestamp; +import org.apache.doris.nereids.trees.expressions.literal.DateLiteral; import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral; import org.apache.doris.nereids.trees.expressions.literal.StringLiteral; +import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral; import org.apache.doris.nereids.types.IntegerType; import org.junit.jupiter.api.Assertions; @@ -40,4 +45,25 @@ public class ExpressionTest { Assertions.assertFalse( new Add(new SlotReference("a", IntegerType.INSTANCE), new IntegerLiteral(1)).isConstant()); } + + @Test + public void testContainsNondeterministic() { + Assertions.assertTrue(new DaysAdd(new CurrentDate(), new IntegerLiteral(2)).containsNondeterministic()); + Assertions.assertTrue(new DaysAdd( + new UnixTimestamp( + new CurrentDate(), + new VarcharLiteral("%Y-%m-%d %H:%i-%s")), new IntegerLiteral(2)) + .containsNondeterministic()); + Assertions.assertTrue(new DaysAdd( + new UnixTimestamp(new CurrentDate()), new IntegerLiteral(2)).containsNondeterministic()); + + Assertions.assertFalse(new DaysAdd( + new UnixTimestamp( + new DateLiteral("2024-01-01"), + new VarcharLiteral("%Y-%m-%d %H:%i-%s")), new IntegerLiteral(2)) + .containsNondeterministic()); + Assertions.assertTrue(new DaysAdd( + new UnixTimestamp(), new IntegerLiteral(2)).containsNondeterministic()); + + } } diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/PlanVisitorTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/PlanVisitorTest.java index 0a2fcdc40d..256406781a 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/PlanVisitorTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/PlanVisitorTest.java @@ -281,6 +281,22 @@ public class PlanVisitorTest extends TestWithFeService { }); } + @Test + public void testContainsNondeterministic() { + PlanChecker.from(connectContext) + .checkExplain("SELECT * FROM table1 " + + "LEFT SEMI JOIN table2 ON table1.c1 = table2.c1 " + + "WHERE table1.c1 IN (SELECT c1 FROM table2) OR date_add(current_date(), INTERVAL 2 DAY) < '2023-01-01'", + nereidsPlanner -> { + // Check nondeterministic collect + List nondeterministicFunctionSet = + MaterializedViewUtils.extractNondeterministicFunction( + nereidsPlanner.getAnalyzedPlan()); + Assertions.assertEquals(1, nondeterministicFunctionSet.size()); + Assertions.assertTrue(nondeterministicFunctionSet.get(0) instanceof CurrentDate); + }); + } + @Test public void testUnixTimestampWithArgsFunction() { PlanChecker.from(connectContext)