Skip to content

Commit 56e1aab

Browse files
committed
Reconsider mechanism for marking sub-selects that are at top level of
a qualification clause (and hence can get away with being sloppy about distinguishing FALSE from UNKNOWN). We need to know this in subselect.c; marking the subplans in setrefs.c is too late.
1 parent de432ce commit 56e1aab

File tree

4 files changed

+34
-53
lines changed

4 files changed

+34
-53
lines changed

src/backend/optimizer/plan/planner.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.137 2003/01/13 00:29:25 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.138 2003/01/13 18:10:53 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -777,7 +777,7 @@ preprocess_expression(Query *parse, Node *expr, int kind)
777777

778778
/* Expand SubLinks to SubPlans */
779779
if (parse->hasSubLinks)
780-
expr = SS_process_sublinks(expr);
780+
expr = SS_process_sublinks(expr, (kind != EXPRKIND_TARGET));
781781

782782
/* Replace uplevel vars with Param nodes */
783783
if (PlannerQueryLevel > 1)

src/backend/optimizer/plan/setrefs.c

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.87 2003/01/10 21:08:11 tgl Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.88 2003/01/13 18:10:53 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -42,7 +42,6 @@ typedef struct
4242

4343
static void fix_expr_references(Plan *plan, Node *node);
4444
static bool fix_expr_references_walker(Node *node, void *context);
45-
static void mark_qual_expressions(List *quals);
4645
static void set_join_references(Join *join, List *rtable);
4746
static void set_uppernode_references(Plan *plan, Index subvarno);
4847
static Node *join_references_mutator(Node *node,
@@ -89,12 +88,10 @@ set_plan_references(Plan *plan, List *rtable)
8988
case T_SeqScan:
9089
fix_expr_references(plan, (Node *) plan->targetlist);
9190
fix_expr_references(plan, (Node *) plan->qual);
92-
mark_qual_expressions(plan->qual);
9391
break;
9492
case T_IndexScan:
9593
fix_expr_references(plan, (Node *) plan->targetlist);
9694
fix_expr_references(plan, (Node *) plan->qual);
97-
mark_qual_expressions(plan->qual);
9895
fix_expr_references(plan,
9996
(Node *) ((IndexScan *) plan)->indxqual);
10097
fix_expr_references(plan,
@@ -103,7 +100,6 @@ set_plan_references(Plan *plan, List *rtable)
103100
case T_TidScan:
104101
fix_expr_references(plan, (Node *) plan->targetlist);
105102
fix_expr_references(plan, (Node *) plan->qual);
106-
mark_qual_expressions(plan->qual);
107103
fix_expr_references(plan,
108104
(Node *) ((TidScan *) plan)->tideval);
109105
break;
@@ -118,7 +114,6 @@ set_plan_references(Plan *plan, List *rtable)
118114
*/
119115
fix_expr_references(plan, (Node *) plan->targetlist);
120116
fix_expr_references(plan, (Node *) plan->qual);
121-
mark_qual_expressions(plan->qual);
122117

123118
/* Recurse into subplan too */
124119
rte = rt_fetch(((SubqueryScan *) plan)->scan.scanrelid,
@@ -134,7 +129,6 @@ set_plan_references(Plan *plan, List *rtable)
134129

135130
fix_expr_references(plan, (Node *) plan->targetlist);
136131
fix_expr_references(plan, (Node *) plan->qual);
137-
mark_qual_expressions(plan->qual);
138132
rte = rt_fetch(((FunctionScan *) plan)->scan.scanrelid,
139133
rtable);
140134
Assert(rte->rtekind == RTE_FUNCTION);
@@ -145,27 +139,21 @@ set_plan_references(Plan *plan, List *rtable)
145139
set_join_references((Join *) plan, rtable);
146140
fix_expr_references(plan, (Node *) plan->targetlist);
147141
fix_expr_references(plan, (Node *) plan->qual);
148-
mark_qual_expressions(plan->qual);
149142
fix_expr_references(plan, (Node *) ((Join *) plan)->joinqual);
150-
mark_qual_expressions(((Join *) plan)->joinqual);
151143
break;
152144
case T_MergeJoin:
153145
set_join_references((Join *) plan, rtable);
154146
fix_expr_references(plan, (Node *) plan->targetlist);
155147
fix_expr_references(plan, (Node *) plan->qual);
156-
mark_qual_expressions(plan->qual);
157148
fix_expr_references(plan, (Node *) ((Join *) plan)->joinqual);
158-
mark_qual_expressions(((Join *) plan)->joinqual);
159149
fix_expr_references(plan,
160150
(Node *) ((MergeJoin *) plan)->mergeclauses);
161151
break;
162152
case T_HashJoin:
163153
set_join_references((Join *) plan, rtable);
164154
fix_expr_references(plan, (Node *) plan->targetlist);
165155
fix_expr_references(plan, (Node *) plan->qual);
166-
mark_qual_expressions(plan->qual);
167156
fix_expr_references(plan, (Node *) ((Join *) plan)->joinqual);
168-
mark_qual_expressions(((Join *) plan)->joinqual);
169157
fix_expr_references(plan,
170158
(Node *) ((HashJoin *) plan)->hashclauses);
171159
break;
@@ -192,7 +180,6 @@ set_plan_references(Plan *plan, List *rtable)
192180
set_uppernode_references(plan, (Index) 0);
193181
fix_expr_references(plan, (Node *) plan->targetlist);
194182
fix_expr_references(plan, (Node *) plan->qual);
195-
mark_qual_expressions(plan->qual);
196183
break;
197184
case T_Result:
198185

@@ -206,9 +193,7 @@ set_plan_references(Plan *plan, List *rtable)
206193
set_uppernode_references(plan, (Index) OUTER);
207194
fix_expr_references(plan, (Node *) plan->targetlist);
208195
fix_expr_references(plan, (Node *) plan->qual);
209-
mark_qual_expressions(plan->qual);
210196
fix_expr_references(plan, ((Result *) plan)->resconstantqual);
211-
mark_qual_expressions((List *) ((Result *) plan)->resconstantqual);
212197
break;
213198
case T_Append:
214199

@@ -283,28 +268,6 @@ fix_expr_references_walker(Node *node, void *context)
283268
return expression_tree_walker(node, fix_expr_references_walker, context);
284269
}
285270

286-
/*
287-
* mark_qual_expressions
288-
* Do final cleanup on qualifier expressions (not targetlists!)
289-
*
290-
* SubPlans appearing at the top level of a qual expression are marked
291-
* to indicate that they need not distinguish UNKNOWN (null) from FALSE
292-
* results; this can save processing time in some cases.
293-
*/
294-
static void
295-
mark_qual_expressions(List *quals)
296-
{
297-
List *qual;
298-
299-
foreach(qual, quals)
300-
{
301-
Node *node = lfirst(qual);
302-
303-
if (IsA(node, SubPlan))
304-
((SubPlan *) node)->unknownEqFalse = true;
305-
}
306-
}
307-
308271
/*
309272
* set_join_references
310273
* Modifies the target list of a join node to reference its subplans,

src/backend/optimizer/plan/subselect.c

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.65 2003/01/13 00:29:26 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.66 2003/01/13 18:10:53 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -65,7 +65,7 @@ static List *convert_sublink_opers(List *lefthand, List *operOids,
6565
List *targetlist, List **paramIds);
6666
static bool subplan_is_hashable(SubLink *slink, SubPlan *node);
6767
static Node *replace_correlation_vars_mutator(Node *node, void *context);
68-
static Node *process_sublinks_mutator(Node *node, void *context);
68+
static Node *process_sublinks_mutator(Node *node, bool *isTopQual);
6969
static bool finalize_primnode(Node *node, finalize_primnode_results *results);
7070

7171

@@ -159,7 +159,8 @@ generate_new_param(Oid paramtype, int32 paramtypmod)
159159
* Convert a bare SubLink (as created by the parser) into a SubPlan.
160160
*
161161
* We are given the raw SubLink and the already-processed lefthand argument
162-
* list (use this instead of the SubLink's own field).
162+
* list (use this instead of the SubLink's own field). We are also told if
163+
* this expression appears at top level of a WHERE/HAVING qual.
163164
*
164165
* The result is whatever we need to substitute in place of the SubLink
165166
* node in the executable expression. This will be either the SubPlan
@@ -168,7 +169,7 @@ generate_new_param(Oid paramtype, int32 paramtypmod)
168169
* containing InitPlan Param nodes.
169170
*/
170171
static Node *
171-
make_subplan(SubLink *slink, List *lefthand)
172+
make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
172173
{
173174
SubPlan *node = makeNode(SubPlan);
174175
Query *subquery = (Query *) (slink->subselect);
@@ -232,7 +233,8 @@ make_subplan(SubLink *slink, List *lefthand)
232233
node->exprs = NIL;
233234
node->paramIds = NIL;
234235
node->useHashTable = false;
235-
node->unknownEqFalse = false;
236+
/* At top level of a qual, can treat UNKNOWN the same as FALSE */
237+
node->unknownEqFalse = isTopQual;
236238
node->setParam = NIL;
237239
node->parParam = NIL;
238240
node->args = NIL;
@@ -589,17 +591,23 @@ replace_correlation_vars_mutator(Node *node, void *context)
589591

590592
/*
591593
* Expand SubLinks to SubPlans in the given expression.
594+
*
595+
* The isQual argument tells whether or not this expression is a WHERE/HAVING
596+
* qualifier expression. If it is, any sublinks appearing at top level need
597+
* not distinguish FALSE from UNKNOWN return values.
592598
*/
593599
Node *
594-
SS_process_sublinks(Node *expr)
600+
SS_process_sublinks(Node *expr, bool isQual)
595601
{
596-
/* No setup needed for tree walk, so away we go */
597-
return process_sublinks_mutator(expr, NULL);
602+
/* The only context needed is the initial are-we-in-a-qual flag */
603+
return process_sublinks_mutator(expr, &isQual);
598604
}
599605

600606
static Node *
601-
process_sublinks_mutator(Node *node, void *context)
607+
process_sublinks_mutator(Node *node, bool *isTopQual)
602608
{
609+
bool locTopQual;
610+
603611
if (node == NULL)
604612
return NULL;
605613
if (IsA(node, SubLink))
@@ -610,12 +618,13 @@ process_sublinks_mutator(Node *node, void *context)
610618
/*
611619
* First, recursively process the lefthand-side expressions, if any.
612620
*/
621+
locTopQual = false;
613622
lefthand = (List *)
614-
process_sublinks_mutator((Node *) sublink->lefthand, context);
623+
process_sublinks_mutator((Node *) sublink->lefthand, &locTopQual);
615624
/*
616625
* Now build the SubPlan node and make the expr to return.
617626
*/
618-
return make_subplan(sublink, lefthand);
627+
return make_subplan(sublink, lefthand, *isTopQual);
619628
}
620629

621630
/*
@@ -626,9 +635,18 @@ process_sublinks_mutator(Node *node, void *context)
626635
*/
627636
Assert(!is_subplan(node));
628637

638+
/*
639+
* If we recurse down through anything other than a List node, we are
640+
* definitely not at top qual level anymore.
641+
*/
642+
if (IsA(node, List))
643+
locTopQual = *isTopQual;
644+
else
645+
locTopQual = false;
646+
629647
return expression_tree_mutator(node,
630648
process_sublinks_mutator,
631-
context);
649+
(void *) &locTopQual);
632650
}
633651

634652
/*

src/include/optimizer/subselect.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ extern int PlannerPlanId; /* to assign unique ID to subquery plans */
1616

1717
extern List *SS_finalize_plan(Plan *plan, List *rtable);
1818
extern Node *SS_replace_correlation_vars(Node *expr);
19-
extern Node *SS_process_sublinks(Node *expr);
19+
extern Node *SS_process_sublinks(Node *expr, bool isQual);
2020

2121
#endif /* SUBSELECT_H */

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