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 09a22aaf3bb [fix](variable) Track user variables in SQL cache during
binding (#67787)
09a22aaf3bb is described below
commit 09a22aaf3bbe5628d42616f828f98d52253f48e9
Author: morrySnow <[email protected]>
AuthorDate: Fri Sep 11 13:29:08 2026 +0800
[fix](variable) Track user variables in SQL cache during binding (#67787)
### What problem does this PR solve?
Related PR: #62524
Problem Summary:
User-variable dependencies were registered in the SQL cache context only
by the late `ReplaceVariableByLiteral` rewrite. Function binding unwraps
a direct `Variable` argument to its real expression before that rewrite,
so expressions such as `ABS(@v)` lost the variable dependency. After
`@v` changed, the same SQL could therefore reuse a stale
`PhysicalSqlCache` result and return the old value.
This PR records the complete variable dependency while binding
`UnboundVariable`, then directly returns its real expression. It removes
the now-redundant `VariableToLiteral` / `ReplaceVariableByLiteral` path
and the `ExpressionTrait` variable special case. It also moves the
generated-column variable check to the parsed expression so variables
inside functions remain rejected.
---
.../doris/nereids/jobs/executor/Analyzer.java | 12 ---
.../nereids/rules/analysis/ExpressionAnalyzer.java | 7 +-
.../nereids/rules/analysis/VariableToLiteral.java | 40 ----------
.../rules/expression/ExpressionRuleType.java | 1 -
.../expression/rules/ReplaceVariableByLiteral.java | 53 -------------
.../expressions/functions/ExpressionTrait.java | 29 +-------
.../trees/plans/commands/info/CreateTableInfo.java | 8 +-
.../apache/doris/nereids/util/ExpressionUtils.java | 8 +-
.../rules/analysis/UserVariableAnalysisTest.java | 28 +++++++
.../expressions/functions/ExpressionTraitTest.java | 86 ----------------------
.../fault_tolerance_nereids.groovy | 12 ++-
.../query_p0/cache/parse_sql_from_sql_cache.groovy | 23 ++++++
12 files changed, 75 insertions(+), 232 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/executor/Analyzer.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/executor/Analyzer.java
index 8e4dc6c63e1..db6ed38ac41 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/executor/Analyzer.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/executor/Analyzer.java
@@ -52,7 +52,6 @@ import
org.apache.doris.nereids.rules.analysis.ProjectWithDistinctToAggregate;
import org.apache.doris.nereids.rules.analysis.QualifyToFilter;
import org.apache.doris.nereids.rules.analysis.ReplaceExpressionByChildOutput;
import org.apache.doris.nereids.rules.analysis.SubqueryToApply;
-import org.apache.doris.nereids.rules.analysis.VariableToLiteral;
import org.apache.doris.nereids.rules.rewrite.AdjustNullable;
import org.apache.doris.nereids.rules.rewrite.MergeFilters;
import org.apache.doris.nereids.rules.rewrite.SimplifyAggGroupBy;
@@ -168,17 +167,6 @@ public class Analyzer extends AbstractBatchJobExecutor {
// LogicalProject for normalize. This rule depends on
FillUpMissingSlots to fill up slots.
new NormalizeRepeat()
),
- // consider sql with user defined var @t_zone
- // set @t_zone='GMT';
- // SELECT
- // DATE_FORMAT(convert_tz(dt, time_zone, @t_zone),'%Y-%m-%d')
day
- // FROM
- // t
- // GROUP BY
- // 1;
- // @t_zone must be replaced as 'GMT' before
EliminateGroupByConstant and NormalizeAggregate rule.
- // So need run VariableToLiteral rule before the two rules.
- topDown(new VariableToLiteral()),
// run CheckSearchUsage before CheckAnalysis to detect search() in
GROUP BY before it gets optimized
bottomUp(new CheckSearchUsage()),
// run CheckAnalysis before EliminateGroupByConstant in order to
report error message correctly like bellow
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 ebace17bca2..f8fd0910ae1 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
@@ -225,7 +225,12 @@ public class ExpressionAnalyzer extends
SubExprAnalyzer<ExpressionRewriteContext
*
********************************************************************************************
*/
@Override
public Expression visitUnboundVariable(UnboundVariable unboundVariable,
ExpressionRewriteContext context) {
- return resolveUnboundVariable(unboundVariable);
+ Variable variable = resolveUnboundVariable(unboundVariable);
+ if (wantToParseSqlFromSqlCache) {
+ getCascadesContext().getStatementContext().getSqlCacheContext()
+ .ifPresent(sqlCacheContext ->
sqlCacheContext.addUsedVariable(variable));
+ }
+ return variable.getRealExpression();
}
/** resolveUnboundVariable */
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/VariableToLiteral.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/VariableToLiteral.java
deleted file mode 100644
index 3f9be8ed677..00000000000
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/VariableToLiteral.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// 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.rules.analysis;
-
-import org.apache.doris.nereids.rules.expression.ExpressionRewrite;
-import org.apache.doris.nereids.rules.expression.ExpressionRewriteContext;
-import org.apache.doris.nereids.rules.expression.ExpressionRewriteRule;
-import org.apache.doris.nereids.rules.expression.ExpressionRuleExecutor;
-import
org.apache.doris.nereids.rules.expression.rules.ReplaceVariableByLiteral;
-
-import com.google.common.collect.ImmutableList;
-
-import java.util.List;
-
-/**
- * replace Variable To Literal
- */
-public class VariableToLiteral extends ExpressionRewrite {
- public static final List<ExpressionRewriteRule<ExpressionRewriteContext>>
NORMALIZE_REWRITE_RULES =
- ImmutableList.of(bottomUp(ReplaceVariableByLiteral.INSTANCE));
-
- public VariableToLiteral() {
- super(new ExpressionRuleExecutor(NORMALIZE_REWRITE_RULES));
- }
-}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionRuleType.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionRuleType.java
index a3409004ca7..7d4494da26a 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionRuleType.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionRuleType.java
@@ -50,7 +50,6 @@ public enum ExpressionRuleType {
NORMALIZE_BINARY_PREDICATES,
NULL_SAFE_EQUAL_TO_EQUAL,
PUSH_INTO_CASE_WHEN_BRANCH,
- REPLACE_VARIABLE_BY_LITERAL,
SIMPLIFY_ARITHMETIC_COMPARISON,
SIMPLIFY_ARITHMETIC,
SIMPLIFY_CAST,
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/ReplaceVariableByLiteral.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/ReplaceVariableByLiteral.java
deleted file mode 100644
index e800bf790c5..00000000000
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/ReplaceVariableByLiteral.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// 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.rules.expression.rules;
-
-import org.apache.doris.nereids.SqlCacheContext;
-import org.apache.doris.nereids.StatementContext;
-import org.apache.doris.nereids.rules.expression.ExpressionPatternMatcher;
-import org.apache.doris.nereids.rules.expression.ExpressionPatternRuleFactory;
-import org.apache.doris.nereids.rules.expression.ExpressionRuleType;
-import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.Variable;
-
-import com.google.common.collect.ImmutableList;
-
-import java.util.List;
-import java.util.Optional;
-
-/**
- * replace varaible to real expression
- */
-public class ReplaceVariableByLiteral implements ExpressionPatternRuleFactory {
- public static ReplaceVariableByLiteral INSTANCE = new
ReplaceVariableByLiteral();
-
- @Override
- public List<ExpressionPatternMatcher<? extends Expression>> buildRules() {
- return ImmutableList.of(
- matchesType(Variable.class).thenApply(ctx -> {
- StatementContext statementContext =
ctx.cascadesContext.getStatementContext();
- Variable variable = ctx.expr;
- Optional<SqlCacheContext> sqlCacheContext =
statementContext.getSqlCacheContext();
- if (sqlCacheContext.isPresent()) {
- sqlCacheContext.get().addUsedVariable(variable);
- }
- return variable.getRealExpression();
- }).toRule(ExpressionRuleType.REPLACE_VARIABLE_BY_LITERAL)
- );
- }
-}
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 f382964bcaf..8740a200cd7 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
@@ -21,7 +21,6 @@ import org.apache.doris.nereids.annotation.Developing;
import org.apache.doris.nereids.exceptions.UnboundException;
import org.apache.doris.nereids.trees.TreeNode;
import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.Variable;
import org.apache.doris.nereids.trees.expressions.VolatileExpression;
import org.apache.doris.nereids.types.DataType;
@@ -52,38 +51,14 @@ public interface ExpressionTrait extends
TreeNode<Expression> {
* getArguments.
*/
default List<Expression> getArguments() {
- boolean hasVariableArg = false;
- for (Expression arg : children()) {
- if (arg instanceof Variable) {
- hasVariableArg = true;
- break;
- }
- }
- if (hasVariableArg) {
- ImmutableList.Builder<Expression> arguments =
ImmutableList.builder();
- for (Expression arg : children()) {
- if (arg instanceof Variable) {
- arguments.add(((Variable) arg).getRealExpression());
- } else {
- arguments.add(arg);
- }
- }
- return arguments.build();
- } else {
- return children();
- }
+ return children();
}
/**
* getArgument.
*/
default Expression getArgument(int index) {
- Expression arg = child(index);
- if (arg instanceof Variable) {
- return ((Variable) arg).getRealExpression();
- } else {
- return arg;
- }
+ return child(index);
}
default List<DataType> getArgumentsTypes() {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableInfo.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableInfo.java
index ac39d7256a7..69357d6f39a 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableInfo.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableInfo.java
@@ -56,6 +56,7 @@ import org.apache.doris.nereids.CascadesContext;
import org.apache.doris.nereids.analyzer.Scope;
import org.apache.doris.nereids.analyzer.UnboundFunction;
import org.apache.doris.nereids.analyzer.UnboundSlot;
+import org.apache.doris.nereids.analyzer.UnboundVariable;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.glue.translator.ExpressionTranslator;
import org.apache.doris.nereids.glue.translator.PlanTranslatorContext;
@@ -66,7 +67,6 @@ import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.SlotReference;
import org.apache.doris.nereids.trees.expressions.SubqueryExpr;
-import org.apache.doris.nereids.trees.expressions.Variable;
import org.apache.doris.nereids.trees.expressions.functions.BoundFunction;
import org.apache.doris.nereids.trees.expressions.functions.Udf;
import
org.apache.doris.nereids.trees.expressions.functions.scalar.GroupingScalarFunction;
@@ -1209,6 +1209,8 @@ public class CreateTableInfo {
throw new AnalysisException("Generated column does not support
subquery.");
} else if (e instanceof Lambda) {
throw new AnalysisException("Generated column does not support
lambda.");
+ } else if (e instanceof UnboundVariable) {
+ throw new AnalysisException("Generated column expression
cannot contain variable.");
}
});
}
@@ -1216,9 +1218,7 @@ public class CreateTableInfo {
void checkExpressionInGeneratedColumn(Expression expr, ColumnDefinition
column,
Map<String, ColumnDefinition> nameToColumnDefinition) {
expr.foreach(e -> {
- if (e instanceof Variable) {
- throw new AnalysisException("Generated column expression
cannot contain variable.");
- } else if (e instanceof Slot &&
nameToColumnDefinition.containsKey(((Slot) e).getName())) {
+ if (e instanceof Slot &&
nameToColumnDefinition.containsKey(((Slot) e).getName())) {
ColumnDefinition columnDefinition =
nameToColumnDefinition.get(((Slot) e).getName());
if (columnDefinition.getAutoIncInitValue() != -1) {
throw new AnalysisException(
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/ExpressionUtils.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/ExpressionUtils.java
index 984b74372fb..00f5caa8364 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/ExpressionUtils.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/ExpressionUtils.java
@@ -29,11 +29,8 @@ import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.properties.DataTrait;
import org.apache.doris.nereids.properties.PhysicalProperties;
import org.apache.doris.nereids.rules.analysis.ExpressionAnalyzer;
-import org.apache.doris.nereids.rules.expression.ExpressionRewrite;
import org.apache.doris.nereids.rules.expression.ExpressionRewriteContext;
-import org.apache.doris.nereids.rules.expression.ExpressionRuleExecutor;
import org.apache.doris.nereids.rules.expression.rules.FoldConstantRule;
-import
org.apache.doris.nereids.rules.expression.rules.ReplaceVariableByLiteral;
import
org.apache.doris.nereids.rules.expression.rules.TrySimplifyPredicateWithMarkJoinSlot;
import org.apache.doris.nereids.trees.SuperClassId;
import org.apache.doris.nereids.trees.TreeNode;
@@ -1504,10 +1501,7 @@ public class ExpressionUtils {
throw new UserException(expression + " must be constant value");
}
ExpressionRewriteContext context = new
ExpressionRewriteContext(cascadesContext);
- ExpressionRuleExecutor executor = new
ExpressionRuleExecutor(ImmutableList.of(
-
ExpressionRewrite.bottomUp(ReplaceVariableByLiteral.INSTANCE)));
- Expression rewrittenExpression = executor.rewrite(analyzedExpr,
context);
- Expression foldExpression =
FoldConstantRule.evaluate(rewrittenExpression, context);
+ Expression foldExpression = FoldConstantRule.evaluate(analyzedExpr,
context);
if (foldExpression instanceof Literal) {
return (Literal) foldExpression;
} else {
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/UserVariableAnalysisTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/UserVariableAnalysisTest.java
index 3ba8bcf22ab..688569121ad 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/UserVariableAnalysisTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/UserVariableAnalysisTest.java
@@ -22,6 +22,12 @@ import org.apache.doris.analysis.IntLiteral;
import org.apache.doris.analysis.LargeIntLiteral;
import org.apache.doris.analysis.TimeStampNsLiteral;
import org.apache.doris.catalog.ScalarType;
+import org.apache.doris.nereids.CascadesContext;
+import org.apache.doris.nereids.analyzer.Scope;
+import org.apache.doris.nereids.analyzer.UnboundVariable;
+import org.apache.doris.nereids.analyzer.UnboundVariable.VariableType;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.Variable;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
import org.apache.doris.nereids.trees.expressions.literal.TimestampTzLiteral;
import org.apache.doris.nereids.types.BigIntType;
@@ -34,9 +40,12 @@ import org.apache.doris.nereids.types.TinyIntType;
import org.apache.doris.nereids.util.MemoTestUtils;
import org.apache.doris.qe.ConnectContext;
+import com.google.common.collect.ImmutableList;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import java.util.List;
+
/** Tests for user variable handling in expression analysis. */
public class UserVariableAnalysisTest {
@@ -84,4 +93,23 @@ public class UserVariableAnalysisTest {
Assertions.assertEquals(TimeStampNsType.INSTANCE,
literal.getDataType());
Assertions.assertEquals("2024-02-29 12:34:56.123456789",
literal.getStringValue());
}
+
+ @Test
+ public void
testBindUserVariableToRealExpressionAndRecordSqlCacheDependency() {
+ ConnectContext ctx = MemoTestUtils.createConnectContext();
+ ctx.setUserVar("v", new IntLiteral(42));
+ CascadesContext cascadesContext =
MemoTestUtils.createCascadesContext(ctx, "select @v");
+ ExpressionAnalyzer analyzer = new ExpressionAnalyzer(null, new
Scope(ImmutableList.of()),
+ cascadesContext, false, false);
+
+ Expression analyzed = analyzer.analyze(new UnboundVariable("v",
VariableType.USER));
+
+ Assertions.assertInstanceOf(Literal.class, analyzed);
+ List<Variable> usedVariables =
cascadesContext.getStatementContext().getSqlCacheContext()
+ .orElseThrow().getUsedVariables();
+ Assertions.assertEquals(1, usedVariables.size());
+ Assertions.assertEquals("v", usedVariables.get(0).getName());
+ Assertions.assertEquals(VariableType.USER,
usedVariables.get(0).getType());
+ Assertions.assertEquals(analyzed,
usedVariables.get(0).getRealExpression());
+ }
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/ExpressionTraitTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/ExpressionTraitTest.java
deleted file mode 100644
index 03a36c2c927..00000000000
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/ExpressionTraitTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-// 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.analyzer.UnboundVariable.VariableType;
-import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.Variable;
-import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
-import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
-import org.apache.doris.nereids.types.DataType;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-import java.util.List;
-
-/**
- * Tests for ExpressionTrait behaviors when children are `Variable`.
- */
-public class ExpressionTraitTest {
-
- static class DummyFunction extends Expression {
- protected DummyFunction(List<Expression> children) {
- super(children);
- }
-
- protected DummyFunction(Expression... children) {
- super(children);
- }
-
- @Override
- public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
- return null;
- }
-
- @Override
- public Expression withChildren(List<Expression> children) {
- return new DummyFunction(children);
- }
-
- @Override
- protected String computeToSql() {
- return "dummy";
- }
-
- @Override
- public boolean nullable() {
- return false;
- }
- }
-
- @Test
- public void testVariable() {
- IntegerLiteral lit = new IntegerLiteral(42);
- Variable var = new Variable("v", VariableType.USER, lit);
-
- DummyFunction func = new DummyFunction(var);
-
- List<Expression> args = func.getArguments();
- Assertions.assertEquals(1, args.size());
- Assertions.assertEquals(lit, args.get(0));
-
- Assertions.assertEquals(lit, func.getArgument(0));
-
- List<DataType> types = func.getArgumentsTypes();
- Assertions.assertEquals(1, types.size());
- Assertions.assertEquals(lit.getDataType(), types.get(0));
-
- Assertions.assertEquals(lit.getDataType(), func.getArgumentType(0));
- }
-}
diff --git
a/regression-test/suites/ddl_p0/test_create_table_generated_column/fault_tolerance_nereids.groovy
b/regression-test/suites/ddl_p0/test_create_table_generated_column/fault_tolerance_nereids.groovy
index 02409621bdc..62d73edb653 100644
---
a/regression-test/suites/ddl_p0/test_create_table_generated_column/fault_tolerance_nereids.groovy
+++
b/regression-test/suites/ddl_p0/test_create_table_generated_column/fault_tolerance_nereids.groovy
@@ -68,6 +68,16 @@ suite("test_generated_column_fault_tolerance_nereids") {
exception "Generated column expression cannot contain variable."
}
+ // Variables are resolved to literals during binding, so generated columns
must reject them before binding.
+ test {
+ sql """
+ create table test_gen_col_var_in_function(a int, c int generated
always as (abs(@myvar)) not null)
+ DISTRIBUTED BY HASH(a)
+ PROPERTIES("replication_num" = "1");
+ """
+ exception "Generated column expression cannot contain variable."
+ }
+
test {
sql """
create table test_gen_col_auto_increment(a bigint not null
auto_increment, b int, c int as (a*b))
@@ -200,4 +210,4 @@ suite("test_generated_column_fault_tolerance_nereids") {
}
-}
\ No newline at end of file
+}
diff --git
a/regression-test/suites/query_p0/cache/parse_sql_from_sql_cache.groovy
b/regression-test/suites/query_p0/cache/parse_sql_from_sql_cache.groovy
index c12ccf50273..c90b755a48c 100644
--- a/regression-test/suites/query_p0/cache/parse_sql_from_sql_cache.groovy
+++ b/regression-test/suites/query_p0/cache/parse_sql_from_sql_cache.groovy
@@ -633,6 +633,29 @@ suite("parse_sql_from_sql_cache") {
def result1 = sql "select @custom_variable from
test_use_plan_cache17 where id = 1 and value = 1"
assertTrue(result1.size() == 1 &&
result1[0][0].toString().toInteger() == 10)
+ def functionVariableSql = "select
abs(@custom_variable_in_function) " +
+ "from test_use_plan_cache17 where id = 1 and
value = 1"
+ sql "set @custom_variable_in_function=-10"
+ assertNoCache functionVariableSql
+ def functionResult = sql functionVariableSql
+ assertTrue(functionResult.size() == 1
+ && functionResult[0][0].toString().toInteger()
== 10)
+ assertHasCache functionVariableSql
+
+ sql "set @custom_variable_in_function=-20"
+ assertNoCache functionVariableSql
+ functionResult = sql functionVariableSql
+ assertTrue(functionResult.size() == 1
+ && functionResult[0][0].toString().toInteger()
== 20)
+ assertHasCache functionVariableSql
+
+ // switch back to the original value and reuse its
value-aware cache
+ sql "set @custom_variable_in_function=-10"
+ assertHasCache functionVariableSql
+ functionResult = sql functionVariableSql
+ assertTrue(functionResult.size() == 1
+ && functionResult[0][0].toString().toInteger()
== 10)
+
sql "set @custom_variable2=1"
assertNoCache "select * from test_use_plan_cache17
where id = @custom_variable2 and value = 1"
def res = sql "select * from test_use_plan_cache17
where id = @custom_variable2 and value = 1"
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]