1
0
mirror of https://github.com/postgres/postgres.git synced 2026-10-23 13:29:09 +03:00

Clear more substructure of a dead relation during join removal.

The tablesample and securityQuals subtrees of a RangeTblEntry can
include Vars, which will cause trouble if they point at a removed
rel and are visited during later processing.  Hence, clear those
fields during join removal, as we already do for the subquery field.
remove_useless_outer_joins got this right for securityQuals but
not tablesample, while remove_self_join_rel missed doing it for
securityQuals.  (It escapes trouble for tablesample only because we
made a policy decision to never touch sampled relations for SJE.)

Oversight in 2ebf25e7d.  Back-patch to v16, like that commit
(but the SJE issue only goes as far back as v18).

Author: shihao zhong <zhong950419@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAGRkXqSOAT1yop44B8jwacL_91rxK=QuoU8Of3NLMb9NgAO2NA@mail.gmail.com
Backpatch-through: 16
This commit is contained in:
Tom Lane
2026-10-14 15:37:28 -04:00
parent 49103c3cd6
commit 91b1872ff2

View File

@@ -151,13 +151,15 @@ remove_useless_outer_joins(PlannerInfo *root)
* As in pull_up_simple_subquery, discard no-longer-needed subqueries.
* This is not just an optimization, but is necessary to prevent
* subsequent processing from descending into stale subtrees and
* seeing inconsistent data. Likewise discard any securityQuals of
* the removed rel. (Although simple_rte_array[] will be rebuilt
* shortly, we can still use it to find the RTE in the parse tree.)
* seeing inconsistent data. For the same reason, discard any
* tablesample and securityQuals subtrees of the removed rel.
* (Although simple_rte_array[] will be rebuilt shortly, we can still
* use it to find the RTE in the parse tree.)
*/
rte = root->simple_rte_array[innerrelid];
if (rte->rtekind == RTE_SUBQUERY)
rte->subquery = NULL;
rte->tablesample = NULL;
rte->securityQuals = NIL;
/*
@@ -1269,6 +1271,13 @@ remove_self_join_rel(PlannerInfo *root,
ChangeVarNodes((Node *) root->append_rel_list, toRemove->relid,
toKeep->relid, 0);
/*
* As in remove_useless_outer_joins, discard the securityQuals of the
* removed rel, so that later passes don't visit them. We know the kept
* rel has the same quals. (tablesample is already known NULL.)
*/
root->simple_rte_array[toRemove->relid]->securityQuals = NIL;
/* Clean up the quals that the substitution has messed with */
fixup_selfjoin_jointree(root, (Node *) root->parse->jointree,
toKeep->relid,