github-actions[bot] commented on code in PR #67256:
URL: https://github.com/apache/doris/pull/67256#discussion_r3877984253


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/StatementContext.java:
##########
@@ -395,6 +395,53 @@ private StatementContext(ConnectContext connectContext, 
OriginStatement originSt
         }
     }
 
+    /**
+     * Create a fresh StatementContext for the next EXECUTE of a prepared 
statement.
+     *
+     * <p>A prepared statement keeps its StatementContext inside {@code 
PreparedStatementContext}
+     * for the whole lifetime of the connection. Reusing the same object 
across executions makes
+     * its per-statement state (bound tables, CTE maps, statistics, snapshots, 
connector scope,
+     * ...) accumulate and it is only released when the connection closes, 
which can OOM
+     * long-lived connections. Instead of clearing in place, allocate a 
brand-new context per
+     * EXECUTE and copy over only the state that must survive between 
executions, so the previous
+     * context becomes unreachable and is promptly GC'd.
+     *
+     * <p>Carried over:
+     * <ul>
+     *   <li>id generator positions, so ids generated during this execution 
never collide with
+     *       ids already present in the cached analyzed plan from PREPARE;</li>
+     *   <li>the placeholder real expressions bound by this EXECUTE (the 
protocol layer fills
+     *       them on the previous context before this method runs) and the 
placeholder list;</li>
+     *   <li>the placeholder to comparison-slot registry used by the 
short-circuit fast path;</li>
+     *   <li>the short-circuit and nondeterministic flags that gate the 
short-circuit fast path
+     *       before this execution re-plans.</li>
+     * </ul>
+     * Everything else (tables, CTEs, statistics, snapshots, planner 
resources, connector
+     * scope, ...) starts empty/fresh on the new context.
+     */
+    public StatementContext createNextExecuteContext() {
+        // Continue the id generators from the previous context. The cached 
analyzed plan from
+        // PREPARE (and every prior execution) already consumed ids from them, 
so a fresh
+        // generator starting at 0 would collide with those ids during this 
execution's planning.
+        StatementContext next = new StatementContext(connectContext, 
originStatement,
+                exprIdGenerator.getCurrentId());
+        next.objectIdGenerator.resetId(objectIdGenerator.getCurrentId());
+        next.relationIdGenerator.resetId(relationIdGenerator.getCurrentId());
+        next.cteIdGenerator.resetId(cteIdGenerator.getCurrentId());
+        next.talbeIdGenerator.resetId(talbeIdGenerator.getCurrentId());
+        
next.placeHolderIdGenerator.resetId(placeHolderIdGenerator.getCurrentId());
+        // Placeholder bindings of this EXECUTE, and the comparison-slot 
registry used to replace
+        // conjuncts on the cached short-circuit plan without re-planning.
+        next.idToPlaceholderRealExpr.putAll(idToPlaceholderRealExpr);
+        next.idToComparisonSlot.putAll(idToComparisonSlot);
+        next.placeholders = new ArrayList<>(placeholders);
+        // Short-circuit gating flags are computed by the previous execution's 
planning and gate
+        // the fast path of this execution before any re-planning happens.
+        next.isShortCircuitQuery = isShortCircuitQuery;

Review Comment:
   Blocking: the fresh context carries isShortCircuitQuery=true but drops the 
cached ShortCircuitQueryContext. On the second reusable EXECUTE, ExecuteCommand 
enters directExecuteShortCircuitQuery without planning this executor. 
StmtExecutor.executeAndSendResult then sees a null statement-level cache and 
falls back to new ShortCircuitQueryContext(planner, ...); planner is null on 
this direct path, and the constructor immediately dereferences it via 
planner.getDescTable(), so the prepared point query fails with an NPE. Please 
install the already-validated prepared cache on the fresh context before direct 
execution (or preserve it with equivalent invalidation semantics) and cover two 
executions of the fast path.



##########
fe/fe-core/src/main/java/org/apache/doris/qe/PreparedStatementContext.java:
##########
@@ -54,6 +54,23 @@ public void setStatementContext(StatementContext 
statementContext) {
         this.statementContext = statementContext;
     }
 
+    /**
+     * Allocate a fresh StatementContext for this EXECUTE and replace the 
previous one, so the
+     * old context (with the per-statement state accumulated by prior 
executions: bound tables,
+     * CTE maps, statistics, snapshots, ...) becomes unreachable and is 
promptly GC'd.
+     *
+     * <p>A prepared statement lives as long as its connection. Reusing one 
StatementContext
+     * across all executions would keep growing those maps and could OOM 
long-lived connections,
+     * so we create a new object per execution and carry over only the state 
that must survive
+     * (placeholder bindings, comparison slots, id generator positions, 
short-circuit flags).
+     *
+     * @return the fresh StatementContext to use for the current execution
+     */
+    public StatementContext nextStatementContext() {
+        statementContext = statementContext.createNextExecuteContext();

Review Comment:
   Blocking: this assignment discards the outgoing context without closing its 
connector scope. COM_STMT_EXECUTE does not run the ConnectProcessor.handleQuery 
StatementContext.close finally, and ConnectContext.clear only nulls the 
connection reference. Coordinated scans register a query-finish close, but 
connector commands and failures before scan registration have no callback and 
relied on the removed next-execution reset. Repeated executions can therefore 
abandon closeable metadata or an active connector transaction without closeAll; 
GC will not finalize them. Please close/reset the outgoing scope before 
replacing it, and make the wiring test assert that a seeded closeable or 
transaction is finalized.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to