Skip to content

Commit 5a7d369

Browse files
committed
Fix two separate bugs in setrefs.c. set_subqueryscan_references needs
to copy the whole plan tree before invoking adjust_plan_varnos(); else if there is any multiply-linked substructure, the latter might increment some Var's varno twice. Previously there were some retail copyObject calls inside adjust_plan_varnos, but it seems a lot safer to just dup the whole tree first. Also, set_inner_join_references was trying to avoid work by not recursing if a BitmapHeapScan's bitmapqualorig contained no outer references; which was OK at the time the code was written, I think, but now that create_bitmap_scan_plan removes duplicate clauses from bitmapqualorig it is possible for that field to be NULL while outer references still remain in the qpqual and/or contained indexscan nodes. For safety, always recurse even if the BitmapHeapScan looks to be outer reference free. Per reports from Michael Fuhr and Oleg Bartunov.
1 parent 5824d02 commit 5a7d369

File tree

1 file changed

+32
-40
lines changed

1 file changed

+32
-40
lines changed

src/backend/optimizer/plan/setrefs.c

Lines changed: 32 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.111 2005/06/10 00:28:54 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.112 2005/08/27 18:04:49 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -367,7 +367,12 @@ set_subqueryscan_references(SubqueryScan *plan, List *rtable)
367367
QTW_IGNORE_RT_SUBQUERIES);
368368
rtable = list_concat(rtable, sub_rtable);
369369

370-
result = plan->subplan;
370+
/*
371+
* we have to copy the subplan to make sure there are no duplicately
372+
* linked nodes in it, else adjust_plan_varnos might increment some
373+
* varnos twice
374+
*/
375+
result = copyObject(plan->subplan);
371376

372377
adjust_plan_varnos(result, rtoffset);
373378

@@ -538,10 +543,7 @@ adjust_plan_varnos(Plan *plan, int rtoffset)
538543
* Even though the targetlist won't be used by the executor,
539544
* we fix it up for possible use by EXPLAIN (not to mention
540545
* ease of debugging --- wrong varnos are very confusing).
541-
* We have to make a copy because the tlist is very likely
542-
* shared with lower plan levels.
543546
*/
544-
plan->targetlist = copyObject(plan->targetlist);
545547
adjust_expr_varnos((Node *) plan->targetlist, rtoffset);
546548
Assert(plan->qual == NIL);
547549
break;
@@ -552,7 +554,6 @@ adjust_plan_varnos(Plan *plan, int rtoffset)
552554
* or quals. It does have live expressions for limit/offset,
553555
* however.
554556
*/
555-
plan->targetlist = copyObject(plan->targetlist);
556557
adjust_expr_varnos((Node *) plan->targetlist, rtoffset);
557558
Assert(plan->qual == NIL);
558559
adjust_expr_varnos(((Limit *) plan)->limitOffset, rtoffset);
@@ -569,14 +570,6 @@ adjust_plan_varnos(Plan *plan, int rtoffset)
569570
adjust_expr_varnos(((Result *) plan)->resconstantqual, rtoffset);
570571
break;
571572
case T_Append:
572-
573-
/*
574-
* Append, like Sort et al, doesn't actually evaluate its
575-
* targetlist or check quals, and we haven't bothered to give it
576-
* its own tlist copy. So, copy tlist before fixing. Then
577-
* recurse into child plans.
578-
*/
579-
plan->targetlist = copyObject(plan->targetlist);
580573
adjust_expr_varnos((Node *) plan->targetlist, rtoffset);
581574
Assert(plan->qual == NIL);
582575
foreach(l, ((Append *) plan)->appendplans)
@@ -849,39 +842,38 @@ set_inner_join_references(Plan *inner_plan,
849842
/*
850843
* The inner side is a bitmap scan plan. Fix the top node,
851844
* and recurse to get the lower nodes.
845+
*
846+
* Note: create_bitmap_scan_plan removes clauses from bitmapqualorig
847+
* if they are duplicated in qpqual, so must test these independently.
852848
*/
853849
BitmapHeapScan *innerscan = (BitmapHeapScan *) inner_plan;
850+
Index innerrel = innerscan->scan.scanrelid;
854851
List *bitmapqualorig = innerscan->bitmapqualorig;
855852

856-
/* No work needed if bitmapqual refers only to its own rel... */
853+
/* only refs to outer vars get changed in the inner qual */
857854
if (NumRelids((Node *) bitmapqualorig) > 1)
858-
{
859-
Index innerrel = innerscan->scan.scanrelid;
860-
861-
/* only refs to outer vars get changed in the inner qual */
862855
innerscan->bitmapqualorig = join_references(bitmapqualorig,
863-
rtable,
864-
outer_itlist,
865-
NULL,
866-
innerrel);
867-
868-
/*
869-
* We must fix the inner qpqual too, if it has join
870-
* clauses (this could happen if special operators are
871-
* involved: some indexquals may get rechecked as qpquals).
872-
*/
873-
if (NumRelids((Node *) inner_plan->qual) > 1)
874-
inner_plan->qual = join_references(inner_plan->qual,
875-
rtable,
876-
outer_itlist,
877-
NULL,
878-
innerrel);
856+
rtable,
857+
outer_itlist,
858+
NULL,
859+
innerrel);
879860

880-
/* Now recurse */
881-
set_inner_join_references(inner_plan->lefttree,
882-
rtable,
883-
outer_itlist);
884-
}
861+
/*
862+
* We must fix the inner qpqual too, if it has join
863+
* clauses (this could happen if special operators are
864+
* involved: some indexquals may get rechecked as qpquals).
865+
*/
866+
if (NumRelids((Node *) inner_plan->qual) > 1)
867+
inner_plan->qual = join_references(inner_plan->qual,
868+
rtable,
869+
outer_itlist,
870+
NULL,
871+
innerrel);
872+
873+
/* Now recurse */
874+
set_inner_join_references(inner_plan->lefttree,
875+
rtable,
876+
outer_itlist);
885877
}
886878
else if (IsA(inner_plan, BitmapAnd))
887879
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy