aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/optimizer/plan/analyzejoins.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c
index aa725925675..c3fd4a81f8a 100644
--- a/src/backend/optimizer/plan/analyzejoins.c
+++ b/src/backend/optimizer/plan/analyzejoins.c
@@ -390,6 +390,17 @@ remove_rel_from_query(PlannerInfo *root, int relid, SpecialJoinInfo *sjinfo)
{
SpecialJoinInfo *sjinf = (SpecialJoinInfo *) lfirst(l);
+ /*
+ * initsplan.c is fairly cavalier about allowing SpecialJoinInfos'
+ * lefthand/righthand relid sets to be shared with other data
+ * structures. Ensure that we don't modify the original relid sets.
+ * (The commute_xxx sets are always per-SpecialJoinInfo though.)
+ */
+ sjinf->min_lefthand = bms_copy(sjinf->min_lefthand);
+ sjinf->min_righthand = bms_copy(sjinf->min_righthand);
+ sjinf->syn_lefthand = bms_copy(sjinf->syn_lefthand);
+ sjinf->syn_righthand = bms_copy(sjinf->syn_righthand);
+ /* Now remove relid and ojrelid bits from the sets: */
sjinf->min_lefthand = bms_del_member(sjinf->min_lefthand, relid);
sjinf->min_righthand = bms_del_member(sjinf->min_righthand, relid);
sjinf->syn_lefthand = bms_del_member(sjinf->syn_lefthand, relid);
@@ -551,8 +562,11 @@ static void
remove_rel_from_restrictinfo(RestrictInfo *rinfo, int relid, int ojrelid)
{
/*
- * The clause_relids probably aren't shared with anything else, but let's
- * copy them just to be sure.
+ * initsplan.c is fairly cavalier about allowing RestrictInfos to share
+ * relid sets with other RestrictInfos, and SpecialJoinInfos too. Make
+ * sure this RestrictInfo has its own relid sets before we modify them.
+ * (In present usage, clause_relids is probably not shared, but
+ * required_relids could be; let's not assume anything.)
*/
rinfo->clause_relids = bms_copy(rinfo->clause_relids);
rinfo->clause_relids = bms_del_member(rinfo->clause_relids, relid);