2828#include "optimizer/optimizer.h"
2929#include "optimizer/pathnode.h"
3030#include "optimizer/paths.h"
31- #include "optimizer/placeholder.h"
3231#include "optimizer/planmain.h"
3332#include "optimizer/restrictinfo.h"
3433#include "rewrite/rewriteManip.h"
@@ -344,6 +343,37 @@ remove_rel_from_query(PlannerInfo *root, RelOptInfo *rel,
344343 sjinfo -> ojrelid );
345344 }
346345
346+ /*
347+ * Remove references to the rel from other baserels' attr_needed arrays.
348+ */
349+ for (rti = 1 ; rti < root -> simple_rel_array_size ; rti ++ )
350+ {
351+ RelOptInfo * otherrel = root -> simple_rel_array [rti ];
352+ int attroff ;
353+
354+ /* there may be empty slots corresponding to non-baserel RTEs */
355+ if (otherrel == NULL )
356+ continue ;
357+
358+ Assert (otherrel -> relid == rti ); /* sanity check on array */
359+
360+ /* no point in processing target rel itself */
361+ if (otherrel == rel )
362+ continue ;
363+
364+ for (attroff = otherrel -> max_attr - otherrel -> min_attr ;
365+ attroff >= 0 ;
366+ attroff -- )
367+ {
368+ otherrel -> attr_needed [attroff ] =
369+ bms_del_member (otherrel -> attr_needed [attroff ], relid );
370+ if (sjinfo != NULL )
371+ otherrel -> attr_needed [attroff ] =
372+ bms_del_member (otherrel -> attr_needed [attroff ],
373+ sjinfo -> ojrelid );
374+ }
375+ }
376+
347377 /*
348378 * Likewise remove references from SpecialJoinInfo data structures.
349379 *
@@ -451,11 +481,13 @@ remove_rel_from_query(PlannerInfo *root, RelOptInfo *rel,
451481 phinfo -> ph_eval_at = adjust_relid_set (phinfo -> ph_eval_at ,
452482 sjinfo -> ojrelid , subst );
453483 Assert (!bms_is_empty (phinfo -> ph_eval_at )); /* checked previously */
454- /* Reduce ph_needed to contain only "relation 0"; see below */
455- if (bms_is_member (0 , phinfo -> ph_needed ))
456- phinfo -> ph_needed = bms_make_singleton (0 );
457- else
458- phinfo -> ph_needed = NULL ;
484+
485+ phinfo -> ph_needed = adjust_relid_set (phinfo -> ph_needed ,
486+ relid , subst );
487+ if (sjinfo != NULL )
488+ phinfo -> ph_needed = adjust_relid_set (phinfo -> ph_needed ,
489+ sjinfo -> ojrelid , subst );
490+ /* ph_needed might or might not become empty */
459491
460492 phinfo -> ph_lateral = adjust_relid_set (phinfo -> ph_lateral , relid , subst );
461493
@@ -490,46 +522,6 @@ remove_rel_from_query(PlannerInfo *root, RelOptInfo *rel,
490522 (sjinfo == NULL || bms_is_member (sjinfo -> ojrelid , ec -> ec_relids )))
491523 remove_rel_from_eclass (ec , sjinfo , relid , subst );
492524 }
493-
494- /*
495- * Finally, we must recompute per-Var attr_needed and per-PlaceHolderVar
496- * ph_needed relid sets. These have to be known accurately, else we may
497- * fail to remove other now-removable outer joins. And our removal of the
498- * join clause(s) for this outer join may mean that Vars that were
499- * formerly needed no longer are. So we have to do this honestly by
500- * repeating the construction of those relid sets. We can cheat to one
501- * small extent: we can avoid re-examining the targetlist and HAVING qual
502- * by preserving "relation 0" bits from the existing relid sets. This is
503- * safe because we'd never remove such references.
504- *
505- * So, start by removing all other bits from attr_needed sets and
506- * lateral_vars lists. (We already did this above for ph_needed.)
507- */
508- for (rti = 1 ; rti < root -> simple_rel_array_size ; rti ++ )
509- {
510- RelOptInfo * otherrel = root -> simple_rel_array [rti ];
511- int attroff ;
512-
513- /* there may be empty slots corresponding to non-baserel RTEs */
514- if (otherrel == NULL )
515- continue ;
516-
517- Assert (otherrel -> relid == rti ); /* sanity check on array */
518-
519- for (attroff = otherrel -> max_attr - otherrel -> min_attr ;
520- attroff >= 0 ;
521- attroff -- )
522- {
523- if (bms_is_member (0 , otherrel -> attr_needed [attroff ]))
524- otherrel -> attr_needed [attroff ] = bms_make_singleton (0 );
525- else
526- otherrel -> attr_needed [attroff ] = NULL ;
527- }
528-
529- if (subst > 0 )
530- ChangeVarNodesExtended ((Node * ) otherrel -> lateral_vars , relid ,
531- subst , 0 , replace_relid_callback );
532- }
533525}
534526
535527/*
@@ -626,7 +618,7 @@ remove_leftjoinrel_from_query(PlannerInfo *root, int relid,
626618 */
627619
628620 /*
629- * Now remove the rel from the baserel array to prevent it from being
621+ * Finally, remove the rel from the baserel array to prevent it from being
630622 * referenced again. (We can't do this earlier because
631623 * remove_join_clause_from_rels will touch it.)
632624 */
@@ -635,15 +627,6 @@ remove_leftjoinrel_from_query(PlannerInfo *root, int relid,
635627
636628 /* And nuke the RelOptInfo, just in case there's another access path */
637629 pfree (rel );
638-
639- /*
640- * Now repeat construction of attr_needed bits coming from all other
641- * sources.
642- */
643- rebuild_placeholder_attr_needed (root );
644- rebuild_joinclause_attr_needed (root );
645- rebuild_eclass_attr_needed (root );
646- rebuild_lateral_attr_needed (root );
647630}
648631
649632/*
@@ -1983,16 +1966,6 @@ remove_self_join_rel(PlannerInfo *root, PlanRowMark *kmark, PlanRowMark *rmark,
19831966
19841967 /* And nuke the RelOptInfo, just in case there's another access path. */
19851968 pfree (toRemove );
1986-
1987-
1988- /*
1989- * Now repeat construction of attr_needed bits coming from all other
1990- * sources.
1991- */
1992- rebuild_placeholder_attr_needed (root );
1993- rebuild_joinclause_attr_needed (root );
1994- rebuild_eclass_attr_needed (root );
1995- rebuild_lateral_attr_needed (root );
19961969}
19971970
19981971/*
0 commit comments