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

yjhjstz pushed a commit to branch 
yjhjstz/fix/orca-use-after-free-having-decorrelation
in repository https://gitbox.apache.org/repos/asf/cloudberry.git

commit 77d365c6f531abf7106e8ac3a7836712f86afb8a
Author: Jianghua Yang <[email protected]>
AuthorDate: Sat Mar 14 03:50:51 2026 +0800

    ORCA: Fix use-after-free in flatten_join_alias_var_optimizer
    
    Guard pfree/list_free calls with pointer-equality checks to avoid
    freeing live nodes when flatten_join_alias_vars returns the same
    pointer unchanged (e.g., outer-reference Vars with varlevelsup > 0).
    
    The unconditional pfree(havingQual) freed the Var node, whose memory
    was later reused by palloc for a T_List. copyObjectImpl then copied
    the wrong node type into havingQual, causing ORCA to encounter an
    unexpected RangeTblEntry and fall back to the Postgres planner.
    
    Applies the same guard pattern to all six fields: targetList,
    returningList, havingQual, scatterClause, limitOffset, limitCount.
    
    Reported-in: https://github.com/apache/cloudberry/issues/1618
---
 src/backend/optimizer/util/clauses.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/src/backend/optimizer/util/clauses.c 
b/src/backend/optimizer/util/clauses.c
index 2669f2c3017..9085f3876a4 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -5522,35 +5522,40 @@ flatten_join_alias_var_optimizer(Query *query, int 
queryLevel)
        if (NIL != targetList)
        {
                queryNew->targetList = (List *) 
flatten_join_alias_vars(queryNew, (Node *) targetList);
-               list_free(targetList);
+               if (targetList != queryNew->targetList)
+                       list_free(targetList);
        }
 
-       List * returningList = queryNew->returningList;
+       List *returningList = queryNew->returningList;
        if (NIL != returningList)
        {
                queryNew->returningList = (List *) 
flatten_join_alias_vars(queryNew, (Node *) returningList);
-               list_free(returningList);
+               if (returningList != queryNew->returningList)
+                       list_free(returningList);
        }
 
        Node *havingQual = queryNew->havingQual;
        if (NULL != havingQual)
        {
                queryNew->havingQual = flatten_join_alias_vars(queryNew, 
havingQual);
-               pfree(havingQual);
+               if (havingQual != queryNew->havingQual)
+                       pfree(havingQual);
        }
 
        List *scatterClause = queryNew->scatterClause;
        if (NIL != scatterClause)
        {
                queryNew->scatterClause = (List *) 
flatten_join_alias_vars(queryNew, (Node *) scatterClause);
-               list_free(scatterClause);
+               if (scatterClause != queryNew->scatterClause)
+                       list_free(scatterClause);
        }
 
        Node *limitOffset = queryNew->limitOffset;
        if (NULL != limitOffset)
        {
                queryNew->limitOffset = flatten_join_alias_vars(queryNew, 
limitOffset);
-               pfree(limitOffset);
+               if (limitOffset != queryNew->limitOffset)
+                       pfree(limitOffset);
        }
 
        List *windowClause = queryNew->windowClause;
@@ -5577,7 +5582,8 @@ flatten_join_alias_var_optimizer(Query *query, int 
queryLevel)
        if (NULL != limitCount)
        {
                queryNew->limitCount = flatten_join_alias_vars(queryNew, 
limitCount);
-               pfree(limitCount);
+               if (limitCount != queryNew->limitCount)
+                       pfree(limitCount);
        }
 
     return queryNew;


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

Reply via email to