1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-18 02:02:55 +03:00

Fixes for ChangeVarNodes_walker()

This commit fixes two bug in ChangeVarNodes_walker() function.

 * When considering RestrictInfo, walk down to its clauses based on the
   presense of relid to be deleted not just in clause_relids but also in
   required_relids.

 * Incrementally adjust num_base_rels based on the change of clause_relids
   instead of recalculating it using clause_relids, which could contain
   outer-join relids.

Reported-by: Richard Guo <guofenglinux@gmail.com>
Discussion: https://postgr.es/m/CAMbWs49PE3CvnV8vrQ0Dr%3DHqgZZmX0tdNbzVNJxqc8yg-8kDQQ%40mail.gmail.com
Author: Andrei Lepikhov <lepihov@gmail.com>
Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com>
This commit is contained in:
Alexander Korotkov
2025-04-29 14:34:44 +03:00
parent 15b1b4dd3f
commit 2260c7f6d9
3 changed files with 46 additions and 6 deletions

View File

@@ -644,14 +644,34 @@ ChangeVarNodes_walker(Node *node, ChangeVarNodes_context *context)
bool clause_relids_is_multiple =
(bms_membership(rinfo->clause_relids) == BMS_MULTIPLE);
if (bms_is_member(context->rt_index, rinfo->clause_relids))
/*
* Recurse down into clauses if the target relation is present in
* clause_relids or required_relids. We must check required_relids
* because the relation not present in clause_relids might still be
* present somewhere in orclause.
*/
if (bms_is_member(context->rt_index, rinfo->clause_relids) ||
bms_is_member(context->rt_index, rinfo->required_relids))
{
Relids new_clause_relids;
expression_tree_walker((Node *) rinfo->clause, ChangeVarNodes_walker, (void *) context);
expression_tree_walker((Node *) rinfo->orclause, ChangeVarNodes_walker, (void *) context);
rinfo->clause_relids =
adjust_relid_set(rinfo->clause_relids, context->rt_index, context->new_index);
rinfo->num_base_rels = bms_num_members(rinfo->clause_relids);
new_clause_relids = adjust_relid_set(rinfo->clause_relids,
context->rt_index,
context->new_index);
/*
* Incrementally adjust num_base_rels based on the change of
* clause_relids, which could contain both base relids and
* outer-join relids. This operation is legal until we remove
* only baserels.
*/
rinfo->num_base_rels -= bms_num_members(rinfo->clause_relids) -
bms_num_members(new_clause_relids);
rinfo->clause_relids = new_clause_relids;
rinfo->left_relids =
adjust_relid_set(rinfo->left_relids, context->rt_index, context->new_index);
rinfo->right_relids =