branch-2.1: [fix](sql cache) fix prepare statement with sql cache throw NullPointerException (#48902) (#48977)

cherry pick from #48902
This commit is contained in:
924060929
2025-03-13 14:35:58 +08:00
committed by GitHub
parent 3b4be62a86
commit ea59465ec7
7 changed files with 66 additions and 20 deletions

View File

@ -126,6 +126,13 @@ public class NereidsSqlCacheManager {
* tryAddFeCache
*/
public void tryAddFeSqlCache(ConnectContext connectContext, String sql) {
switch (connectContext.getCommand()) {
case COM_STMT_EXECUTE:
case COM_STMT_PREPARE:
return;
default: { }
}
Optional<SqlCacheContext> sqlCacheContextOpt = connectContext.getStatementContext().getSqlCacheContext();
if (!sqlCacheContextOpt.isPresent()) {
return;
@ -145,6 +152,12 @@ public class NereidsSqlCacheManager {
* tryAddBeCache
*/
public void tryAddBeCache(ConnectContext connectContext, String sql, CacheAnalyzer analyzer) {
switch (connectContext.getCommand()) {
case COM_STMT_EXECUTE:
case COM_STMT_PREPARE:
return;
default: { }
}
Optional<SqlCacheContext> sqlCacheContextOpt = connectContext.getStatementContext().getSqlCacheContext();
if (!sqlCacheContextOpt.isPresent()) {
return;
@ -176,6 +189,12 @@ public class NereidsSqlCacheManager {
* tryParseSql
*/
public Optional<LogicalSqlCache> tryParseSql(ConnectContext connectContext, String sql) {
switch (connectContext.getCommand()) {
case COM_STMT_EXECUTE:
case COM_STMT_PREPARE:
return Optional.empty();
default: { }
}
String key = generateCacheKey(connectContext, normalizeSql(sql.trim()));
SqlCacheContext sqlCacheContext = sqlCaches.getIfPresent(key);
if (sqlCacheContext == null) {

View File

@ -167,7 +167,7 @@ public class StatementContext implements Closeable {
private final Stack<CloseableResource> plannerResources = new Stack<>();
// placeholder params for prepared statement
private List<Placeholder> placeholders;
private List<Placeholder> placeholders = new ArrayList<>();
// all tables in query
private boolean needLockTables = true;

View File

@ -23,6 +23,8 @@ import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.glue.LogicalPlanAdapter;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.plans.PlanType;
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
import org.apache.doris.nereids.trees.plans.logical.LogicalSqlCache;
import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.qe.PointQueryExecutor;
@ -65,9 +67,13 @@ public class ExecuteCommand extends Command {
throw new AnalysisException(
"prepare statement " + stmtName + " not found, maybe expired");
}
PrepareCommand prepareCommand = (PrepareCommand) preparedStmtCtx.command;
LogicalPlanAdapter planAdapter = new LogicalPlanAdapter(prepareCommand.getLogicalPlan(), executor.getContext()
.getStatementContext());
PrepareCommand prepareCommand = preparedStmtCtx.command;
LogicalPlan logicalPlan = prepareCommand.getLogicalPlan();
if (logicalPlan instanceof LogicalSqlCache) {
throw new AnalysisException("Unsupported sql cache for server prepared statement");
}
LogicalPlanAdapter planAdapter = new LogicalPlanAdapter(
logicalPlan, executor.getContext().getStatementContext());
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

View File

@ -396,6 +396,17 @@ public abstract class ConnectProcessor {
private List<StatementBase> parseFromSqlCache(String originStmt) {
StatementContext statementContext = new StatementContext(ctx, new OriginStatement(originStmt, 0));
ctx.setStatementContext(statementContext);
// the mysql protocol has different between COM_QUERY and COM_STMT_EXECUTE,
// the sql cache use the result of COM_QUERY, so we can not provide the
// result of sql cache for COM_STMT_EXECUTE/COM_STMT_PREPARE
switch (ctx.getCommand()) {
case COM_STMT_EXECUTE:
case COM_STMT_PREPARE:
return null;
default: { }
}
try {
Optional<Pair<ExplainOptions, String>> explainPlan = NereidsParser.tryParseExplainPlan(originStmt);
String cacheSqlKey = originStmt;