This is an automated email from the ASF dual-hosted git repository. yiguolei pushed a commit to branch branch-4.2 in repository https://gitbox.apache.org/repos/asf/doris.git
commit 8e79827c98ee7d11acee46cde67d6380ed68162b Author: morrySnow <[email protected]> AuthorDate: Wed Sep 16 23:39:51 2026 +0800 branch-4.1: [fix](variable) Track user variables in SQL cache during binding #67787 (#68069) ### What problem does this PR solve? Related PR: #67787 Problem Summary: Backport the user-variable SQL cache dependency fix to branch-4.1. User variables are now recorded while binding `UnboundVariable`, before function binding unwraps them to their real expressions. This prevents expressions such as `ABS(@v)` from reusing a stale cached result after the variable changes. The obsolete late `VariableToLiteral` / `ReplaceVariableByLiteral` path is removed, and the generated-column variable check is performed on the parsed expression so variables nested inside functions remain rejected. The unit test is adapted to the Java `Optional` API used by branch-4.1. ### Release note None ### Check List (For Author) - Test - [x] Unit Test - [x] Regression test coverage included - Behavior changed: - [x] No. - Does this need documentation? - [x] No. ### Check List (For Reviewer who merge this PR) - [ ] Confirm the release note - [ ] Confirm test cases - [ ] Confirm document - [ ] Add branch pick label --- .../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 | 9 +-- .../rules/analysis/UserVariableAnalysisTest.java | 29 ++++++++ .../expressions/functions/ExpressionTraitTest.java | 86 ---------------------- .../fault_tolerance_nereids.groovy | 12 ++- .../cache/parse_sql_from_sql_cache.groovy | 23 ++++++ 12 files changed, 76 insertions(+), 233 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 358e9faeb06..1f83b242cf8 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 @@ -50,7 +50,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.SemiJoinCommute; @@ -167,17 +166,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 14203c9792e..8a3eade3f20 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 @@ -217,7 +217,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 f311d9a2d48..7fcb6285875 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 35d87e65279..a938729ba52 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 @@ -57,6 +57,7 @@ import org.apache.doris.mysql.privilege.PrivPredicate; import org.apache.doris.nereids.CascadesContext; import org.apache.doris.nereids.analyzer.Scope; 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; @@ -67,7 +68,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; @@ -1276,6 +1276,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."); } }); } @@ -1283,9 +1285,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 1b3f83bdcf6..6ab9695c1ca 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 @@ -28,11 +28,8 @@ import org.apache.doris.nereids.analyzer.UnboundSlot; import org.apache.doris.nereids.exceptions.AnalysisException; 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; @@ -1456,11 +1453,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 2dd8ca07be5..41e549f23d5 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 @@ -21,6 +21,12 @@ import org.apache.doris.analysis.DateLiteral; import org.apache.doris.analysis.IntLiteral; import org.apache.doris.analysis.LargeIntLiteral; 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; @@ -32,9 +38,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 { @@ -70,4 +79,24 @@ public class UserVariableAnalysisTest { Assertions.assertEquals(TimeStampTzType.of(6), literal.getDataType()); Assertions.assertEquals("2024-11-03 05:05:00.123456+00:00", 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(() -> new IllegalStateException("SQL cache context is not initialized")) + .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/nereids_p0/cache/parse_sql_from_sql_cache.groovy b/regression-test/suites/nereids_p0/cache/parse_sql_from_sql_cache.groovy index 477d20dd197..72e07321f73 100644 --- a/regression-test/suites/nereids_p0/cache/parse_sql_from_sql_cache.groovy +++ b/regression-test/suites/nereids_p0/cache/parse_sql_from_sql_cache.groovy @@ -677,6 +677,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]
