Avoid dangling-pointer problem with partitionwise joins under GEQO.
authorTom Lane <[email protected]>
Fri, 23 Feb 2024 20:21:53 +0000 (15:21 -0500)
committerTom Lane <[email protected]>
Fri, 23 Feb 2024 20:21:53 +0000 (15:21 -0500)
build_child_join_sjinfo creates a derived SpecialJoinInfo in
the short-lived GEQO context, but afterwards the semi_rhs_exprs
from that may be used in a UniquePath for a child base relation.
This breaks the expectation that all base-relation-level structures
are in the planning-lifespan context, leading to use of a dangling
pointer with probable ensuing crash later on in create_unique_plan.
To fix, copy the expression trees when making a UniquePath.

Per bug #18360 from Alexander Lakhin.  This has been broken since
partitionwise joins were added, so back-patch to all supported
branches.

Discussion: https://postgr.es/m/18360-a23caf3157f34e62@postgresql.org

src/backend/optimizer/util/pathnode.c

index b3902b003290ba1265204309cba9f91c1eab8528..6f79b2e3fe7ba97924edb9d7d46bcd9ab3de4960 100644 (file)
@@ -1707,8 +1707,13 @@ create_unique_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath,
    pathnode->path.pathkeys = NIL;
 
    pathnode->subpath = subpath;
-   pathnode->in_operators = sjinfo->semi_operators;
-   pathnode->uniq_exprs = sjinfo->semi_rhs_exprs;
+
+   /*
+    * Under GEQO, the sjinfo might be short-lived, so we'd better make copies
+    * of data structures we extract from it.
+    */
+   pathnode->in_operators = copyObject(sjinfo->semi_operators);
+   pathnode->uniq_exprs = copyObject(sjinfo->semi_rhs_exprs);
 
    /*
     * If the input is a relation and it has a unique index that proves the