This is an automated email from the ASF dual-hosted git repository.

eldenmoon 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 8db9a80d120 [fix](point-query) Refresh stale prepared short-circuit 
plans (#63920)
8db9a80d120 is described below

commit 8db9a80d120c1b1c581edcbd30d6a82cd634bf81
Author: HonestManXin <[email protected]>
AuthorDate: Mon Jun 1 11:57:48 2026 +0800

    [fix](point-query) Refresh stale prepared short-circuit plans (#63920)
    
    Prepared point queries cache short-circuit planner state and the
    associated StatementContext.
    When a target table is renamed, replaced, or swapped, the cached plan
    may still reference stale
    table metadata and reuse an outdated StatementContext, causing execution
    failures or incorrect
      table access.
    
    This change tracks the table name captured during planning, checks
    dropped/renamed/schema-changed
    tables before reusing the short-circuit context, and reparses the
    prepared SQL to rebuild the
    prepared plan with a fresh StatementContext when the cached context is
    stale. Bound placeholder
    values and MySQL parameter types are preserved across refresh.
    Regression coverage is added for
      rename, replace, and swap scenarios.
---
 .../nereids/trees/expressions/Placeholder.java     |   8 ++
 .../trees/plans/commands/ExecuteCommand.java       | 141 +++++++++++++++++++--
 .../org/apache/doris/planner/OlapScanNode.java     |   6 +
 .../org/apache/doris/qe/MysqlConnectProcessor.java |   2 +-
 .../apache/doris/qe/PreparedStatementContext.java  |  10 +-
 .../apache/doris/qe/ShortCircuitQueryContext.java  |  10 ++
 .../java/org/apache/doris/qe/StmtExecutor.java     |  12 +-
 .../suites/point_query_p0/test_point_query.groovy  | 101 +++++++++++++++
 8 files changed, 273 insertions(+), 17 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Placeholder.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Placeholder.java
index ce92a0e36c8..2806e9a5bdc 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Placeholder.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Placeholder.java
@@ -93,6 +93,14 @@ public class Placeholder extends Expression implements 
LeafExpression {
         return MysqlColType.isUnsigned(mysqlTypeCode);
     }
 
+    public boolean hasMysqlColType() {
+        return mysqlColType.isPresent();
+    }
+
+    public int getMysqlTypeCode() {
+        return mysqlTypeCode;
+    }
+
     public MysqlColType getMysqlColType() {
         return mysqlColType.get();
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ExecuteCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ExecuteCommand.java
index 3d27b52ae21..97fbf9ed3d4 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ExecuteCommand.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ExecuteCommand.java
@@ -18,11 +18,16 @@
 package org.apache.doris.nereids.trees.plans.commands;
 
 import org.apache.doris.analysis.Queriable;
+import org.apache.doris.analysis.StatementBase;
 import org.apache.doris.analysis.StmtType;
+import org.apache.doris.catalog.MysqlColType;
 import org.apache.doris.nereids.StatementContext;
 import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.glue.LogicalPlanAdapter;
+import org.apache.doris.nereids.parser.NereidsParser;
 import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.Placeholder;
+import org.apache.doris.nereids.trees.plans.PlaceholderId;
 import org.apache.doris.nereids.trees.plans.PlanType;
 import 
org.apache.doris.nereids.trees.plans.commands.insert.InsertIntoTableCommand;
 import 
org.apache.doris.nereids.trees.plans.commands.insert.InsertOverwriteTableCommand;
@@ -37,7 +42,13 @@ import org.apache.doris.qe.PreparedStatementContext;
 import org.apache.doris.qe.ShortCircuitQueryContext;
 import org.apache.doris.qe.StmtExecutor;
 
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
@@ -45,6 +56,8 @@ import java.util.stream.Collectors;
  * Prepared Statement
  */
 public class ExecuteCommand extends Command {
+    private static final Logger LOG = 
LogManager.getLogger(ExecuteCommand.class);
+
     private final String stmtName;
     private final PrepareCommand prepareCommand;
     private final StatementContext statementContext;
@@ -67,15 +80,15 @@ public class ExecuteCommand extends Command {
 
     @Override
     public void run(ConnectContext ctx, StmtExecutor executor) throws 
Exception {
-        StatementContext statementContext = ctx.getStatementContext();
-        statementContext.setPrepareStage(false);
-        statementContext.setIsInsert(false);
         PreparedStatementContext preparedStmtCtx = 
ctx.getPreparedStementContext(stmtName);
         if (null == preparedStmtCtx) {
             throw new AnalysisException(
                     "prepare statement " + stmtName + " not found,  maybe 
expired");
         }
         PrepareCommand prepareCommand = preparedStmtCtx.command;
+        StatementContext statementContext = 
preparedStmtCtx.getStatementContext();
+        statementContext.setPrepareStage(false);
+        statementContext.setIsInsert(false);
         LogicalPlan logicalPlan = prepareCommand.getLogicalPlan();
         if (logicalPlan instanceof LogicalSqlCache) {
             throw new AnalysisException("Unsupported sql cache for server 
prepared statement");
@@ -83,18 +96,20 @@ public class ExecuteCommand extends Command {
         if (logicalPlan instanceof InsertIntoTableCommand
                 || logicalPlan instanceof InsertOverwriteTableCommand
                 || logicalPlan instanceof UpdateCommand) {
-            ctx.getStatementContext().setIsInsert(true);
+            statementContext.setIsInsert(true);
         }
-        LogicalPlanAdapter planAdapter = new LogicalPlanAdapter(
-                logicalPlan, executor.getContext().getStatementContext());
+        LogicalPlanAdapter planAdapter = new LogicalPlanAdapter(logicalPlan, 
statementContext);
+        executor.setStatementContext(statementContext);
         executor.setParsedStmt(planAdapter);
-        // If it's not a short circuit query or schema version is 
different(indicates schema changed) or
-        // has nondeterministic functions in statement, then need to do 
reanalyze and plan
-        if (executor.getContext().getStatementContext().isShortCircuitQuery()
-                && preparedStmtCtx.shortCircuitQueryContext.isPresent()
-                && 
preparedStmtCtx.shortCircuitQueryContext.get().tbl.getBaseSchemaVersion()
-                == 
preparedStmtCtx.shortCircuitQueryContext.get().schemaVersion && 
!executor.getContext()
-                .getStatementContext().hasNondeterministic()) {
+        boolean hasShortCircuitContext = 
preparedStmtCtx.shortCircuitQueryContext.isPresent();
+        boolean shortCircuitContextReusable = hasShortCircuitContext
+                && preparedStmtCtx.shortCircuitQueryContext.get().isReusable();
+        // Reuse the cached short-circuit plan only when table metadata is 
unchanged and the statement
+        // has no nondeterministic functions. Otherwise fall back to the 
normal execution path below.
+        if (statementContext.isShortCircuitQuery()
+                && hasShortCircuitContext
+                && shortCircuitContextReusable
+                && !statementContext.hasNondeterministic()) {
             PointQueryExecutor.directExecuteShortCircuitQuery(executor, 
preparedStmtCtx, statementContext);
             return;
         }
@@ -110,8 +125,14 @@ public class ExecuteCommand extends Command {
             }
         }
         // execute real statement
+        if (statementContext.isShortCircuitQuery() && hasShortCircuitContext 
&& !shortCircuitContextReusable) {
+            statementContext = refreshPreparedPlan(preparedStmtCtx, executor, 
prepareCommand, statementContext);
+        } else {
+            statementContext.setShortCircuitQueryContext(null);
+        }
+        // Drop the previously cached short-circuit context: either it was 
reusable and returned
+        // early above, has just been refreshed here, or is stale and we are 
about to re-plan.
         preparedStmtCtx.shortCircuitQueryContext = Optional.empty();
-        statementContext.setShortCircuitQueryContext(null);
         executor.execute();
         if (executor.getContext().getStatementContext().isShortCircuitQuery()) 
{
             // cache short-circuit plan
@@ -121,6 +142,98 @@ public class ExecuteCommand extends Command {
         }
     }
 
+    private StatementContext refreshPreparedPlan(PreparedStatementContext 
preparedStmtCtx, StmtExecutor executor,
+            PrepareCommand currentCommand, StatementContext 
currentStatementContext) {
+        Map<PlaceholderId, Expression> boundPlaceholderValues = new HashMap<>(
+                currentStatementContext.getIdToPlaceholderRealExpr());
+        StatementContext originalStatementContext = 
executor.getContext().getStatementContext();
+        StatementBase originalParsedStmt = executor.getParsedStmt();
+        PrepareCommand originalCommand = preparedStmtCtx.command;
+        StatementContext originalPreparedStatementContext = 
preparedStmtCtx.getStatementContext();
+        boolean refreshed = false;
+        try {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("refresh prepared statement plan for short-circuit 
query, stmtName={}",
+                        currentCommand.getName());
+            }
+            List<StatementBase> reparsedStatements = new 
NereidsParser().parseSQL(
+                    currentCommand.getOriginalStmt().originStmt, 
executor.getContext().getSessionVariable());
+            if (reparsedStatements.size() <= 
currentCommand.getOriginalStmt().idx) {
+                throw new AnalysisException("Nereids parse failed. Parser get 
" + reparsedStatements.size()
+                        + " statements, but we need at least " + 
(currentCommand.getOriginalStmt().idx + 1)
+                        + " statements.");
+            }
+            StatementBase reparsedStmt = 
reparsedStatements.get(currentCommand.getOriginalStmt().idx);
+            if (!(reparsedStmt instanceof LogicalPlanAdapter)) {
+                throw new AnalysisException("Prepared statement must be parsed 
as LogicalPlanAdapter, but get "
+                        + reparsedStmt.getClass().getName());
+            }
+
+            LogicalPlanAdapter reparsedAdapter = (LogicalPlanAdapter) 
reparsedStmt;
+            StatementContext reparsedStatementContext = 
reparsedAdapter.getStatementContext();
+            List<Placeholder> reparsedPlaceholders = 
reparsedStatementContext.getPlaceholders();
+            List<Placeholder> currentPlaceholders = 
currentCommand.getPlaceholders();
+            if (reparsedPlaceholders.size() != currentPlaceholders.size()) {
+                throw new AnalysisException("Prepared statement placeholder 
count changed after reparse, old: "
+                        + currentPlaceholders.size() + ", new: " + 
reparsedPlaceholders.size());
+            }
+
+            reparsedStatementContext.setConnectContext(executor.getContext());
+            
reparsedStatementContext.setOriginStatement(currentCommand.getOriginalStmt());
+            reparsedStatementContext.getIdToPlaceholderRealExpr().clear();
+
+            List<Placeholder> refreshedPlaceholders = new 
ArrayList<>(reparsedPlaceholders.size());
+            for (int i = 0; i < reparsedPlaceholders.size(); i++) {
+                Placeholder oldPlaceholder = currentPlaceholders.get(i);
+                Placeholder refreshedPlaceholder = 
withMysqlType(reparsedPlaceholders.get(i), oldPlaceholder);
+                refreshedPlaceholders.add(refreshedPlaceholder);
+
+                Expression boundValue = 
boundPlaceholderValues.get(oldPlaceholder.getPlaceholderId());
+                if (boundValue != null) {
+                    reparsedStatementContext.getIdToPlaceholderRealExpr().put(
+                            refreshedPlaceholder.getPlaceholderId(), 
boundValue);
+                }
+            }
+            reparsedStatementContext.setPlaceholders(refreshedPlaceholders);
+
+            reparsedAdapter.setOrigStmt(currentCommand.getOriginalStmt());
+            executor.setStatementContext(reparsedStatementContext);
+            executor.setParsedStmt(reparsedAdapter);
+            PrepareCommand refreshedCommand = new 
PrepareCommand(currentCommand.getName(),
+                    reparsedAdapter.getLogicalPlan(), refreshedPlaceholders, 
currentCommand.getOriginalStmt());
+            preparedStmtCtx.command = refreshedCommand;
+            preparedStmtCtx.setStatementContext(reparsedStatementContext);
+            refreshed = true;
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("refreshed prepared statement plan for short-circuit 
query, stmtName={}",
+                        currentCommand.getName());
+            }
+            return reparsedStatementContext;
+        } finally {
+            if (!refreshed) {
+                executor.setStatementContext(originalStatementContext);
+                executor.setParsedStmt(originalParsedStmt);
+                preparedStmtCtx.command = originalCommand;
+                
preparedStmtCtx.setStatementContext(originalPreparedStatementContext);
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("rollback prepared statement plan refresh for 
short-circuit query, stmtName={}",
+                            currentCommand.getName());
+                }
+            }
+        }
+    }
+
+    private Placeholder withMysqlType(Placeholder refreshedPlaceholder, 
Placeholder oldPlaceholder) {
+        if (!oldPlaceholder.hasMysqlColType()) {
+            return refreshedPlaceholder;
+        }
+        int mysqlTypeCode = oldPlaceholder.getMysqlTypeCode() & 
MysqlColType.MYSQL_CODE_MASK;
+        if (oldPlaceholder.isUnsigned()) {
+            mysqlTypeCode |= MysqlColType.UNSIGNED_MASK;
+        }
+        return refreshedPlaceholder.withNewMysqlColType(mysqlTypeCode);
+    }
+
     /**
      * return the sql representation contains real expr instead of placeholders
      */
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/OlapScanNode.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/OlapScanNode.java
index f1d89b63d51..1a44788e33c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/OlapScanNode.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/OlapScanNode.java
@@ -158,6 +158,7 @@ public class OlapScanNode extends ScanNode {
     private boolean isPreAggregation = false;
     private String reasonOfPreAggregation = null;
     private OlapTable olapTable = null;
+    private String tableNameInPlan = null;
     private long totalTabletsNum = 0;
     private long selectedIndexId = -1;
     private Collection<Long> selectedPartitionIds = Lists.newArrayList();
@@ -214,6 +215,7 @@ public class OlapScanNode extends ScanNode {
     public OlapScanNode(PlanNodeId id, TupleDescriptor desc, String 
planNodeName, ScanContext scanContext) {
         super(id, desc, planNodeName, scanContext);
         olapTable = (OlapTable) desc.getTable();
+        tableNameInPlan = olapTable.getName();
         distributionColumnIds = Sets.newTreeSet();
 
         Set<String> distColumnName = getDistributionColumnNames();
@@ -317,6 +319,10 @@ public class OlapScanNode extends ScanNode {
         return olapTable;
     }
 
+    public String getTableNameInPlan() {
+        return tableNameInPlan;
+    }
+
     /**
      * Init OlapScanNode, ONLY used for Nereids. Should NOT use this function 
in anywhere else.
      */
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/qe/MysqlConnectProcessor.java 
b/fe/fe-core/src/main/java/org/apache/doris/qe/MysqlConnectProcessor.java
index 15d1b8baad5..8e2b805b27b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/MysqlConnectProcessor.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/MysqlConnectProcessor.java
@@ -120,7 +120,7 @@ public class MysqlConnectProcessor extends ConnectProcessor 
{
         // null bitmap
         String stmtStr = "";
         try {
-            StatementContext statementContext = prepCtx.statementContext;
+            StatementContext statementContext = prepCtx.getStatementContext();
             if (paramCount > 0) {
                 if (LOG.isDebugEnabled()) {
                     LOG.debug("execute param buf: {}, array: {}", packetBuf, 
getHexStr(packetBuf));
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/qe/PreparedStatementContext.java 
b/fe/fe-core/src/main/java/org/apache/doris/qe/PreparedStatementContext.java
index 0174befee5b..fd1b093ee12 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/PreparedStatementContext.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/PreparedStatementContext.java
@@ -26,7 +26,7 @@ import java.util.Optional;
 public class PreparedStatementContext {
     public PrepareCommand command;
     public ConnectContext ctx;
-    StatementContext statementContext;
+    private StatementContext statementContext;
     public String stmtString;
     public Optional<ShortCircuitQueryContext> shortCircuitQueryContext = 
Optional.empty();
     public Optional<GroupCommitPlanner> groupCommitPlanner = Optional.empty();
@@ -46,6 +46,14 @@ public class PreparedStatementContext {
         return startTime;
     }
 
+    public StatementContext getStatementContext() {
+        return statementContext;
+    }
+
+    public void setStatementContext(StatementContext statementContext) {
+        this.statementContext = statementContext;
+    }
+
     public void setStartTime() {
         startTime = System.currentTimeMillis();
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/qe/ShortCircuitQueryContext.java 
b/fe/fe-core/src/main/java/org/apache/doris/qe/ShortCircuitQueryContext.java
index 1a79bde875a..e9dbc41c967 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/ShortCircuitQueryContext.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/ShortCircuitQueryContext.java
@@ -38,6 +38,7 @@ import org.apache.thrift.TSerializer;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.UUID;
 import java.util.stream.Collectors;
 
@@ -56,6 +57,7 @@ public class ShortCircuitQueryContext {
 
     public final int schemaVersion;
     public final OlapTable tbl;
+    public final String tableName;
 
     public final OlapScanNode scanNode;
     public final Queriable analzyedQuery;
@@ -106,14 +108,22 @@ public class ShortCircuitQueryContext {
         this.cacheID = UUID.randomUUID();
         this.scanNode = olapScanNode;
         this.tbl = this.scanNode.getOlapTable();
+        this.tableName = this.scanNode.getTableNameInPlan();
         this.schemaVersion = this.tbl.getBaseSchemaVersion();
         this.analzyedQuery = analzyedQuery;
     }
 
+    public boolean isReusable() {
+        return !this.tbl.isDropped
+                && this.tbl.getBaseSchemaVersion() == this.schemaVersion
+                && Objects.equals(this.tableName, this.tbl.getName());
+    }
+
     public void sanitize() {
         Preconditions.checkNotNull(serializedDescTable);
         Preconditions.checkNotNull(serializedOutputExpr);
         Preconditions.checkNotNull(cacheID);
         Preconditions.checkNotNull(tbl);
+        Preconditions.checkNotNull(tableName);
     }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java 
b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java
index 3ebd2f69307..fcd16289ce7 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java
@@ -185,7 +185,7 @@ public class StmtExecutor {
 
     private static final Pattern beIpPattern = Pattern.compile("\\[(\\d+):");
     private ConnectContext context;
-    private final StatementContext statementContext;
+    private StatementContext statementContext;
     private MysqlSerializer serializer;
     private OriginStatement originStmt;
     private StatementBase parsedStmt;
@@ -551,6 +551,16 @@ public class StmtExecutor {
         return parsedStmt;
     }
 
+    /**
+     * Replace the executor statement context and synchronize it to the owning 
ConnectContext.
+     */
+    public void setStatementContext(StatementContext statementContext) {
+        this.statementContext = statementContext;
+        this.statementContext.setConnectContext(context);
+        this.statementContext.setOriginStatement(originStmt);
+        this.context.setStatementContext(statementContext);
+    }
+
     public boolean isHandleQueryInFe() {
         return isHandleQueryInFe;
     }
diff --git a/regression-test/suites/point_query_p0/test_point_query.groovy 
b/regression-test/suites/point_query_p0/test_point_query.groovy
index 6bb17da5a09..e76cd14df80 100644
--- a/regression-test/suites/point_query_p0/test_point_query.groovy
+++ b/regression-test/suites/point_query_p0/test_point_query.groovy
@@ -274,6 +274,107 @@ suite("test_point_query") {
             }
         }
 
+        sql "DROP TABLE IF EXISTS ${realDb}.tbl_point_query_meta_change"
+        sql "DROP TABLE IF EXISTS 
${realDb}.tbl_point_query_meta_change_renamed"
+        sql "DROP TABLE IF EXISTS 
${realDb}.tbl_point_query_meta_change_replace"
+        sql "DROP TABLE IF EXISTS ${realDb}.tbl_point_query_meta_change_swap"
+        sql "DROP TABLE IF EXISTS 
${realDb}.tbl_point_query_meta_change_string_key"
+        sql "DROP TABLE IF EXISTS 
${realDb}.tbl_point_query_meta_change_string_key_renamed"
+        def create_meta_change_table = { tbl ->
+            sql """
+                CREATE TABLE ${tbl} (
+                    `k` int NOT NULL,
+                    `v` varchar(30) NULL
+                ) ENGINE=OLAP
+                UNIQUE KEY(`k`)
+                DISTRIBUTED BY HASH(`k`) BUCKETS 1
+                PROPERTIES (
+                    "replication_allocation" = "tag.location.default: 1",
+                    "enable_unique_key_merge_on_write" = "true",
+                    "light_schema_change" = "true",
+                    "store_row_column" = "true"
+                )
+            """
+        }
+        def create_string_key_meta_change_table = { tbl ->
+            sql """
+                CREATE TABLE ${tbl} (
+                    `k` varchar(30) NOT NULL,
+                    `v` varchar(30) NULL
+                ) ENGINE=OLAP
+                UNIQUE KEY(`k`)
+                DISTRIBUTED BY HASH(`k`) BUCKETS 1
+                PROPERTIES (
+                    "replication_allocation" = "tag.location.default: 1",
+                    "enable_unique_key_merge_on_write" = "true",
+                    "light_schema_change" = "true",
+                    "store_row_column" = "true"
+                )
+            """
+        }
+        def get_prepared_value = { stmt, key ->
+            stmt.setInt(1, key)
+            try (ResultSet rs = stmt.executeQuery()) {
+                assertTrue(rs.next())
+                def value = rs.getString(1)
+                assertFalse(rs.next())
+                return value
+            }
+        }
+        def get_prepared_string_key_value = { stmt, key ->
+            stmt.setString(1, key)
+            try (ResultSet rs = stmt.executeQuery()) {
+                assertTrue(rs.next())
+                def value = rs.getString(1)
+                assertFalse(rs.next())
+                return value
+            }
+        }
+        create_meta_change_table("${realDb}.tbl_point_query_meta_change")
+        sql "INSERT INTO ${realDb}.tbl_point_query_meta_change VALUES (1, 
'origin')"
+        connect(user, password, prepare_url) {
+            def stmt = prepareStatement "select /*+ 
SET_VAR(enable_nereids_planner=true) */ v from 
${realDb}.tbl_point_query_meta_change where k = ?"
+            assertEquals(stmt.class, com.mysql.cj.jdbc.ServerPreparedStatement)
+            assertEquals('origin', get_prepared_value(stmt, 1))
+            assertEquals('origin', get_prepared_value(stmt, 1))
+
+            nprep_sql "ALTER TABLE ${realDb}.tbl_point_query_meta_change 
RENAME tbl_point_query_meta_change_renamed"
+            create_meta_change_table("${realDb}.tbl_point_query_meta_change")
+            sql "INSERT INTO ${realDb}.tbl_point_query_meta_change VALUES (1, 
'renamed')"
+            assertEquals('renamed', get_prepared_value(stmt, 1))
+
+            sql "DROP TABLE ${realDb}.tbl_point_query_meta_change"
+            create_meta_change_table("${realDb}.tbl_point_query_meta_change")
+            sql "INSERT INTO ${realDb}.tbl_point_query_meta_change VALUES (1, 
'recreated')"
+            assertEquals('recreated', get_prepared_value(stmt, 1))
+
+            
create_meta_change_table("${realDb}.tbl_point_query_meta_change_replace")
+            sql "INSERT INTO ${realDb}.tbl_point_query_meta_change_replace 
VALUES (1, 'replaced')"
+            sql "ALTER TABLE ${realDb}.tbl_point_query_meta_change REPLACE 
WITH TABLE tbl_point_query_meta_change_replace PROPERTIES('swap' = 'false')"
+            assertEquals('replaced', get_prepared_value(stmt, 1))
+
+            
create_meta_change_table("${realDb}.tbl_point_query_meta_change_swap")
+            sql "INSERT INTO ${realDb}.tbl_point_query_meta_change_swap VALUES 
(1, 'swapped')"
+            sql "ALTER TABLE ${realDb}.tbl_point_query_meta_change REPLACE 
WITH TABLE tbl_point_query_meta_change_swap PROPERTIES('swap' = 'true')"
+            assertEquals('swapped', get_prepared_value(stmt, 1))
+            stmt.close()
+        }
+
+        
create_string_key_meta_change_table("${realDb}.tbl_point_query_meta_change_string_key")
+        sql "INSERT INTO ${realDb}.tbl_point_query_meta_change_string_key 
VALUES ('key1', 'string_origin')"
+        connect(user, password, prepare_url) {
+            def stmt = prepareStatement "select /*+ 
SET_VAR(enable_nereids_planner=true) */ v from 
${realDb}.tbl_point_query_meta_change_string_key where k = ?"
+            assertEquals(stmt.class, com.mysql.cj.jdbc.ServerPreparedStatement)
+            assertEquals('string_origin', get_prepared_string_key_value(stmt, 
'key1'))
+
+            nprep_sql "ALTER TABLE 
${realDb}.tbl_point_query_meta_change_string_key RENAME 
tbl_point_query_meta_change_string_key_renamed"
+            
create_string_key_meta_change_table("${realDb}.tbl_point_query_meta_change_string_key")
+            sql "INSERT INTO ${realDb}.tbl_point_query_meta_change_string_key 
VALUES ('key1', 'string_renamed')"
+            assertEquals('string_renamed', get_prepared_string_key_value(stmt, 
'key1'))
+            assertEquals('string_renamed', get_prepared_string_key_value(stmt, 
'key1'))
+            stmt.close()
+        }
+
         sql """ADMIN SET FRONTEND CONFIG ("enable_lightweight_lookup_request" 
= "true")"""
         try {
             connect(user, password, prepare_url) {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to