I wrote:
> Indeed. Curiously, the in_operators list, which I thought was
> parallel to that, seems fine. Anyway, something's being careless
> about which context it creates that data structure in. Shouldn't
> be too hard to fix.
The problem seems to arise from build_child_join_sjinfo(), which
makes a translated version of the semi_rhs_exprs that is later
propagated into a UniquePath for a base relation. This breaks
GEQO's intention that base-relation structs will be long-lived
while only join-relation data is short-lived. (in_operators
is not modified so the original long-lived list is used for that,
explaining why it's not trashed at the same time.)
The simplest fix is as attached: just do a quick copyObject
in create_unique_path. That's rather ugly, but create_unique_path
is already taking explicit responsibility for the context that the
Path is built in, so it doesn't quite exceed my threshold of pain.
(The alternative of making build_child_join_sjinfo force its output
to be long-lived doesn't look good: that gets invoked quite a few
times during a GEQO cycle.) I chose to make it copy the in_operators
list as well, even though that's not minimally necessary to fix
the bug --- it would look odd if we didn't, and the copy is pretty
cheap since it's only a short integer list.
regards, tom lane
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index b3902b0032..6f79b2e3fe 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -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