~ubuntu-branches/ubuntu/hardy/postgresql-8.4/hardy-backports

« back to all changes in this revision

Viewing changes to src/backend/optimizer/plan/subselect.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-03-20 12:00:13 UTC
  • Revision ID: james.westby@ubuntu.com-20090320120013-hogj7egc5mjncc5g
Tags: upstream-8.4~0cvs20090328
ImportĀ upstreamĀ versionĀ 8.4~0cvs20090328

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------------------------------------------------------------------------
 
2
 *
 
3
 * subselect.c
 
4
 *        Planning routines for subselects and parameters.
 
5
 *
 
6
 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
 
7
 * Portions Copyright (c) 1994, Regents of the University of California
 
8
 *
 
9
 * IDENTIFICATION
 
10
 *        $PostgreSQL$
 
11
 *
 
12
 *-------------------------------------------------------------------------
 
13
 */
 
14
#include "postgres.h"
 
15
 
 
16
#include "catalog/pg_operator.h"
 
17
#include "catalog/pg_type.h"
 
18
#include "miscadmin.h"
 
19
#include "nodes/makefuncs.h"
 
20
#include "nodes/nodeFuncs.h"
 
21
#include "optimizer/clauses.h"
 
22
#include "optimizer/cost.h"
 
23
#include "optimizer/planmain.h"
 
24
#include "optimizer/planner.h"
 
25
#include "optimizer/prep.h"
 
26
#include "optimizer/subselect.h"
 
27
#include "optimizer/var.h"
 
28
#include "parser/parse_relation.h"
 
29
#include "parser/parsetree.h"
 
30
#include "rewrite/rewriteManip.h"
 
31
#include "utils/builtins.h"
 
32
#include "utils/lsyscache.h"
 
33
#include "utils/syscache.h"
 
34
 
 
35
 
 
36
typedef struct convert_testexpr_context
 
37
{
 
38
        PlannerInfo *root;
 
39
        List       *subst_nodes;        /* Nodes to substitute for Params */
 
40
} convert_testexpr_context;
 
41
 
 
42
typedef struct process_sublinks_context
 
43
{
 
44
        PlannerInfo *root;
 
45
        bool            isTopQual;
 
46
} process_sublinks_context;
 
47
 
 
48
typedef struct finalize_primnode_context
 
49
{
 
50
        PlannerInfo *root;
 
51
        Bitmapset  *paramids;           /* Non-local PARAM_EXEC paramids found */
 
52
} finalize_primnode_context;
 
53
 
 
54
 
 
55
static Node *build_subplan(PlannerInfo *root, Plan *plan, List *rtable,
 
56
                          SubLinkType subLinkType, Node *testexpr,
 
57
                          bool adjust_testexpr, bool unknownEqFalse);
 
58
static List *generate_subquery_params(PlannerInfo *root, List *tlist,
 
59
                                                                          List **paramIds);
 
60
static List *generate_subquery_vars(PlannerInfo *root, List *tlist,
 
61
                                                                        Index varno);
 
62
static Node *convert_testexpr(PlannerInfo *root,
 
63
                                 Node *testexpr,
 
64
                                 List *subst_nodes);
 
65
static Node *convert_testexpr_mutator(Node *node,
 
66
                                                 convert_testexpr_context *context);
 
67
static bool subplan_is_hashable(Plan *plan);
 
68
static bool testexpr_is_hashable(Node *testexpr);
 
69
static bool hash_ok_operator(OpExpr *expr);
 
70
static bool simplify_EXISTS_query(Query *query);
 
71
static Query *convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect,
 
72
                                          Node **testexpr, List **paramIds);
 
73
static Node *replace_correlation_vars_mutator(Node *node, PlannerInfo *root);
 
74
static Node *process_sublinks_mutator(Node *node,
 
75
                                                 process_sublinks_context *context);
 
76
static Bitmapset *finalize_plan(PlannerInfo *root,
 
77
                          Plan *plan,
 
78
                          Bitmapset *valid_params);
 
79
static bool finalize_primnode(Node *node, finalize_primnode_context *context);
 
80
 
 
81
 
 
82
/*
 
83
 * Generate a Param node to replace the given Var,
 
84
 * which is expected to have varlevelsup > 0 (ie, it is not local).
 
85
 */
 
86
static Param *
 
87
replace_outer_var(PlannerInfo *root, Var *var)
 
88
{
 
89
        Param      *retval;
 
90
        ListCell   *ppl;
 
91
        PlannerParamItem *pitem;
 
92
        Index           abslevel;
 
93
        int                     i;
 
94
 
 
95
        Assert(var->varlevelsup > 0 && var->varlevelsup < root->query_level);
 
96
        abslevel = root->query_level - var->varlevelsup;
 
97
 
 
98
        /*
 
99
         * If there's already a paramlist entry for this same Var, just use it.
 
100
         * NOTE: in sufficiently complex querytrees, it is possible for the same
 
101
         * varno/abslevel to refer to different RTEs in different parts of the
 
102
         * parsetree, so that different fields might end up sharing the same Param
 
103
         * number.      As long as we check the vartype/typmod as well, I believe that
 
104
         * this sort of aliasing will cause no trouble.  The correct field should
 
105
         * get stored into the Param slot at execution in each part of the tree.
 
106
         */
 
107
        i = 0;
 
108
        foreach(ppl, root->glob->paramlist)
 
109
        {
 
110
                pitem = (PlannerParamItem *) lfirst(ppl);
 
111
                if (pitem->abslevel == abslevel && IsA(pitem->item, Var))
 
112
                {
 
113
                        Var                *pvar = (Var *) pitem->item;
 
114
 
 
115
                        if (pvar->varno == var->varno &&
 
116
                                pvar->varattno == var->varattno &&
 
117
                                pvar->vartype == var->vartype &&
 
118
                                pvar->vartypmod == var->vartypmod)
 
119
                                break;
 
120
                }
 
121
                i++;
 
122
        }
 
123
 
 
124
        if (!ppl)
 
125
        {
 
126
                /* Nope, so make a new one */
 
127
                var = (Var *) copyObject(var);
 
128
                var->varlevelsup = 0;
 
129
 
 
130
                pitem = makeNode(PlannerParamItem);
 
131
                pitem->item = (Node *) var;
 
132
                pitem->abslevel = abslevel;
 
133
 
 
134
                root->glob->paramlist = lappend(root->glob->paramlist, pitem);
 
135
                /* i is already the correct index for the new item */
 
136
        }
 
137
 
 
138
        retval = makeNode(Param);
 
139
        retval->paramkind = PARAM_EXEC;
 
140
        retval->paramid = i;
 
141
        retval->paramtype = var->vartype;
 
142
        retval->paramtypmod = var->vartypmod;
 
143
        retval->location = -1;
 
144
 
 
145
        return retval;
 
146
}
 
147
 
 
148
/*
 
149
 * Generate a Param node to replace the given Aggref
 
150
 * which is expected to have agglevelsup > 0 (ie, it is not local).
 
151
 */
 
152
static Param *
 
153
replace_outer_agg(PlannerInfo *root, Aggref *agg)
 
154
{
 
155
        Param      *retval;
 
156
        PlannerParamItem *pitem;
 
157
        Index           abslevel;
 
158
        int                     i;
 
159
 
 
160
        Assert(agg->agglevelsup > 0 && agg->agglevelsup < root->query_level);
 
161
        abslevel = root->query_level - agg->agglevelsup;
 
162
 
 
163
        /*
 
164
         * It does not seem worthwhile to try to match duplicate outer aggs. Just
 
165
         * make a new slot every time.
 
166
         */
 
167
        agg = (Aggref *) copyObject(agg);
 
168
        IncrementVarSublevelsUp((Node *) agg, -((int) agg->agglevelsup), 0);
 
169
        Assert(agg->agglevelsup == 0);
 
170
 
 
171
        pitem = makeNode(PlannerParamItem);
 
172
        pitem->item = (Node *) agg;
 
173
        pitem->abslevel = abslevel;
 
174
 
 
175
        root->glob->paramlist = lappend(root->glob->paramlist, pitem);
 
176
        i = list_length(root->glob->paramlist) - 1;
 
177
 
 
178
        retval = makeNode(Param);
 
179
        retval->paramkind = PARAM_EXEC;
 
180
        retval->paramid = i;
 
181
        retval->paramtype = agg->aggtype;
 
182
        retval->paramtypmod = -1;
 
183
        retval->location = -1;
 
184
 
 
185
        return retval;
 
186
}
 
187
 
 
188
/*
 
189
 * Generate a new Param node that will not conflict with any other.
 
190
 *
 
191
 * This is used to allocate PARAM_EXEC slots for subplan outputs.
 
192
 */
 
193
static Param *
 
194
generate_new_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod)
 
195
{
 
196
        Param      *retval;
 
197
        PlannerParamItem *pitem;
 
198
 
 
199
        retval = makeNode(Param);
 
200
        retval->paramkind = PARAM_EXEC;
 
201
        retval->paramid = list_length(root->glob->paramlist);
 
202
        retval->paramtype = paramtype;
 
203
        retval->paramtypmod = paramtypmod;
 
204
        retval->location = -1;
 
205
 
 
206
        pitem = makeNode(PlannerParamItem);
 
207
        pitem->item = (Node *) retval;
 
208
        pitem->abslevel = root->query_level;
 
209
 
 
210
        root->glob->paramlist = lappend(root->glob->paramlist, pitem);
 
211
 
 
212
        return retval;
 
213
}
 
214
 
 
215
/*
 
216
 * Assign a (nonnegative) PARAM_EXEC ID for a recursive query's worktable.
 
217
 */
 
218
int
 
219
SS_assign_worktable_param(PlannerInfo *root)
 
220
{
 
221
        Param      *param;
 
222
 
 
223
        /* We generate a Param of datatype INTERNAL */
 
224
        param = generate_new_param(root, INTERNALOID, -1);
 
225
        /* ... but the caller only cares about its ID */
 
226
        return param->paramid;
 
227
}
 
228
 
 
229
/*
 
230
 * Get the datatype of the first column of the plan's output.
 
231
 *
 
232
 * This is stored for ARRAY_SUBLINK execution and for exprType()/exprTypmod(),
 
233
 * which have no way to get at the plan associated with a SubPlan node.
 
234
 * We really only need the info for EXPR_SUBLINK and ARRAY_SUBLINK subplans,
 
235
 * but for consistency we save it always.
 
236
 */
 
237
static void
 
238
get_first_col_type(Plan *plan, Oid *coltype, int32 *coltypmod)
 
239
{
 
240
        /* In cases such as EXISTS, tlist might be empty; arbitrarily use VOID */
 
241
        if (plan->targetlist)
 
242
        {
 
243
                TargetEntry *tent = (TargetEntry *) linitial(plan->targetlist);
 
244
 
 
245
                Assert(IsA(tent, TargetEntry));
 
246
                if (!tent->resjunk)
 
247
                {
 
248
                        *coltype = exprType((Node *) tent->expr);
 
249
                        *coltypmod = exprTypmod((Node *) tent->expr);
 
250
                        return;
 
251
                }
 
252
        }
 
253
        *coltype = VOIDOID;
 
254
        *coltypmod = -1;
 
255
}
 
256
 
 
257
/*
 
258
 * Convert a SubLink (as created by the parser) into a SubPlan.
 
259
 *
 
260
 * We are given the SubLink's contained query, type, and testexpr.  We are
 
261
 * also told if this expression appears at top level of a WHERE/HAVING qual.
 
262
 *
 
263
 * Note: we assume that the testexpr has been AND/OR flattened (actually,
 
264
 * it's been through eval_const_expressions), but not converted to
 
265
 * implicit-AND form; and any SubLinks in it should already have been
 
266
 * converted to SubPlans.  The subquery is as yet untouched, however.
 
267
 *
 
268
 * The result is whatever we need to substitute in place of the SubLink
 
269
 * node in the executable expression.  This will be either the SubPlan
 
270
 * node (if we have to do the subplan as a subplan), or a Param node
 
271
 * representing the result of an InitPlan, or a row comparison expression
 
272
 * tree containing InitPlan Param nodes.
 
273
 */
 
274
static Node *
 
275
make_subplan(PlannerInfo *root, Query *orig_subquery, SubLinkType subLinkType,
 
276
                         Node *testexpr, bool isTopQual)
 
277
{
 
278
        Query      *subquery;
 
279
        bool            simple_exists = false;
 
280
        double          tuple_fraction;
 
281
        Plan       *plan;
 
282
        PlannerInfo *subroot;
 
283
        Node       *result;
 
284
 
 
285
        /*
 
286
         * Copy the source Query node.  This is a quick and dirty kluge to resolve
 
287
         * the fact that the parser can generate trees with multiple links to the
 
288
         * same sub-Query node, but the planner wants to scribble on the Query.
 
289
         * Try to clean this up when we do querytree redesign...
 
290
         */
 
291
        subquery = (Query *) copyObject(orig_subquery);
 
292
 
 
293
        /*
 
294
         * If it's an EXISTS subplan, we might be able to simplify it.
 
295
         */
 
296
        if (subLinkType == EXISTS_SUBLINK)
 
297
                simple_exists = simplify_EXISTS_query(subquery);
 
298
 
 
299
        /*
 
300
         * For an EXISTS subplan, tell lower-level planner to expect that only the
 
301
         * first tuple will be retrieved.  For ALL and ANY subplans, we will be
 
302
         * able to stop evaluating if the test condition fails or matches, so very
 
303
         * often not all the tuples will be retrieved; for lack of a better idea,
 
304
         * specify 50% retrieval.  For EXPR and ROWCOMPARE subplans, use default
 
305
         * behavior (we're only expecting one row out, anyway).
 
306
         *
 
307
         * NOTE: if you change these numbers, also change cost_subplan() in
 
308
         * path/costsize.c.
 
309
         *
 
310
         * XXX If an ANY subplan is uncorrelated, build_subplan may decide to hash
 
311
         * its output.  In that case it would've been better to specify full
 
312
         * retrieval.  At present, however, we can only check hashability after
 
313
         * we've made the subplan :-(.  (Determining whether it'll fit in work_mem
 
314
         * is the really hard part.)  Therefore, we don't want to be too
 
315
         * optimistic about the percentage of tuples retrieved, for fear of
 
316
         * selecting a plan that's bad for the materialization case.
 
317
         */
 
318
        if (subLinkType == EXISTS_SUBLINK)
 
319
                tuple_fraction = 1.0;   /* just like a LIMIT 1 */
 
320
        else if (subLinkType == ALL_SUBLINK ||
 
321
                         subLinkType == ANY_SUBLINK)
 
322
                tuple_fraction = 0.5;   /* 50% */
 
323
        else
 
324
                tuple_fraction = 0.0;   /* default behavior */
 
325
 
 
326
        /*
 
327
         * Generate the plan for the subquery.
 
328
         */
 
329
        plan = subquery_planner(root->glob, subquery,
 
330
                                                        root,
 
331
                                                        false, tuple_fraction,
 
332
                                                        &subroot);
 
333
 
 
334
        /* And convert to SubPlan or InitPlan format. */
 
335
        result = build_subplan(root, plan, subroot->parse->rtable,
 
336
                                                   subLinkType, testexpr, true, isTopQual);
 
337
 
 
338
        /*
 
339
         * If it's a correlated EXISTS with an unimportant targetlist, we might be
 
340
         * able to transform it to the equivalent of an IN and then implement it
 
341
         * by hashing.  We don't have enough information yet to tell which way
 
342
         * is likely to be better (it depends on the expected number of executions
 
343
         * of the EXISTS qual, and we are much too early in planning the outer
 
344
         * query to be able to guess that).  So we generate both plans, if
 
345
         * possible, and leave it to the executor to decide which to use.
 
346
         */
 
347
        if (simple_exists && IsA(result, SubPlan))
 
348
        {
 
349
                Node       *newtestexpr;
 
350
                List       *paramIds;
 
351
 
 
352
                /* Make a second copy of the original subquery */
 
353
                subquery = (Query *) copyObject(orig_subquery);
 
354
                /* and re-simplify */
 
355
                simple_exists = simplify_EXISTS_query(subquery);
 
356
                Assert(simple_exists);
 
357
                /* See if it can be converted to an ANY query */
 
358
                subquery = convert_EXISTS_to_ANY(root, subquery,
 
359
                                                                                 &newtestexpr, &paramIds);
 
360
                if (subquery)
 
361
                {
 
362
                        /* Generate the plan for the ANY subquery; we'll need all rows */
 
363
                        plan = subquery_planner(root->glob, subquery,
 
364
                                                                        root,
 
365
                                                                        false, 0.0,
 
366
                                                                        &subroot);
 
367
 
 
368
                        /* Now we can check if it'll fit in work_mem */
 
369
                        if (subplan_is_hashable(plan))
 
370
                        {
 
371
                                SubPlan    *hashplan;
 
372
                                AlternativeSubPlan *asplan;
 
373
 
 
374
                                /* OK, convert to SubPlan format. */
 
375
                                hashplan = (SubPlan *) build_subplan(root, plan,
 
376
                                                                                                         subroot->parse->rtable,
 
377
                                                                                                         ANY_SUBLINK, newtestexpr,
 
378
                                                                                                         false, true);
 
379
                                /* Check we got what we expected */
 
380
                                Assert(IsA(hashplan, SubPlan));
 
381
                                Assert(hashplan->parParam == NIL);
 
382
                                Assert(hashplan->useHashTable);
 
383
                                /* build_subplan won't have filled in paramIds */
 
384
                                hashplan->paramIds = paramIds;
 
385
 
 
386
                                /* Leave it to the executor to decide which plan to use */
 
387
                                asplan = makeNode(AlternativeSubPlan);
 
388
                                asplan->subplans = list_make2(result, hashplan);
 
389
                                result = (Node *) asplan;
 
390
                        }
 
391
                }
 
392
        }
 
393
 
 
394
        return result;
 
395
}
 
396
 
 
397
/*
 
398
 * Build a SubPlan node given the raw inputs --- subroutine for make_subplan
 
399
 *
 
400
 * Returns either the SubPlan, or an expression using initplan output Params,
 
401
 * as explained in the comments for make_subplan.
 
402
 */
 
403
static Node *
 
404
build_subplan(PlannerInfo *root, Plan *plan, List *rtable,
 
405
                          SubLinkType subLinkType, Node *testexpr,
 
406
                          bool adjust_testexpr, bool unknownEqFalse)
 
407
{
 
408
        Node       *result;
 
409
        SubPlan    *splan;
 
410
        bool            isInitPlan;
 
411
        Bitmapset  *tmpset;
 
412
        int                     paramid;
 
413
 
 
414
        /*
 
415
         * Initialize the SubPlan node.  Note plan_id isn't set till further down,
 
416
         * likewise the cost fields.
 
417
         */
 
418
        splan = makeNode(SubPlan);
 
419
        splan->subLinkType = subLinkType;
 
420
        splan->testexpr = NULL;
 
421
        splan->paramIds = NIL;
 
422
        get_first_col_type(plan, &splan->firstColType, &splan->firstColTypmod);
 
423
        splan->useHashTable = false;
 
424
        splan->unknownEqFalse = unknownEqFalse;
 
425
        splan->setParam = NIL;
 
426
        splan->parParam = NIL;
 
427
        splan->args = NIL;
 
428
 
 
429
        /*
 
430
         * Make parParam and args lists of param IDs and expressions that current
 
431
         * query level will pass to this child plan.
 
432
         */
 
433
        tmpset = bms_copy(plan->extParam);
 
434
        while ((paramid = bms_first_member(tmpset)) >= 0)
 
435
        {
 
436
                PlannerParamItem *pitem = list_nth(root->glob->paramlist, paramid);
 
437
 
 
438
                if (pitem->abslevel == root->query_level)
 
439
                {
 
440
                        splan->parParam = lappend_int(splan->parParam, paramid);
 
441
                        /*
 
442
                         * The Var or Aggref has already been adjusted to have the correct
 
443
                         * varlevelsup or agglevelsup.  We probably don't even need to
 
444
                         * copy it again, but be safe.
 
445
                         */
 
446
                        splan->args = lappend(splan->args, copyObject(pitem->item));
 
447
                }
 
448
        }
 
449
        bms_free(tmpset);
 
450
 
 
451
        /*
 
452
         * Un-correlated or undirect correlated plans of EXISTS, EXPR, ARRAY, or
 
453
         * ROWCOMPARE types can be used as initPlans.  For EXISTS, EXPR, or ARRAY,
 
454
         * we just produce a Param referring to the result of evaluating the
 
455
         * initPlan.  For ROWCOMPARE, we must modify the testexpr tree to contain
 
456
         * PARAM_EXEC Params instead of the PARAM_SUBLINK Params emitted by the
 
457
         * parser.
 
458
         */
 
459
        if (splan->parParam == NIL && subLinkType == EXISTS_SUBLINK)
 
460
        {
 
461
                Param      *prm;
 
462
 
 
463
                Assert(testexpr == NULL);
 
464
                prm = generate_new_param(root, BOOLOID, -1);
 
465
                splan->setParam = list_make1_int(prm->paramid);
 
466
                isInitPlan = true;
 
467
                result = (Node *) prm;
 
468
        }
 
469
        else if (splan->parParam == NIL && subLinkType == EXPR_SUBLINK)
 
470
        {
 
471
                TargetEntry *te = linitial(plan->targetlist);
 
472
                Param      *prm;
 
473
 
 
474
                Assert(!te->resjunk);
 
475
                Assert(testexpr == NULL);
 
476
                prm = generate_new_param(root,
 
477
                                                                 exprType((Node *) te->expr),
 
478
                                                                 exprTypmod((Node *) te->expr));
 
479
                splan->setParam = list_make1_int(prm->paramid);
 
480
                isInitPlan = true;
 
481
                result = (Node *) prm;
 
482
        }
 
483
        else if (splan->parParam == NIL && subLinkType == ARRAY_SUBLINK)
 
484
        {
 
485
                TargetEntry *te = linitial(plan->targetlist);
 
486
                Oid                     arraytype;
 
487
                Param      *prm;
 
488
 
 
489
                Assert(!te->resjunk);
 
490
                Assert(testexpr == NULL);
 
491
                arraytype = get_array_type(exprType((Node *) te->expr));
 
492
                if (!OidIsValid(arraytype))
 
493
                        elog(ERROR, "could not find array type for datatype %s",
 
494
                                 format_type_be(exprType((Node *) te->expr)));
 
495
                prm = generate_new_param(root,
 
496
                                                                 arraytype,
 
497
                                                                 exprTypmod((Node *) te->expr));
 
498
                splan->setParam = list_make1_int(prm->paramid);
 
499
                isInitPlan = true;
 
500
                result = (Node *) prm;
 
501
        }
 
502
        else if (splan->parParam == NIL && subLinkType == ROWCOMPARE_SUBLINK)
 
503
        {
 
504
                /* Adjust the Params */
 
505
                List       *params;
 
506
 
 
507
                Assert(testexpr != NULL);
 
508
                params = generate_subquery_params(root,
 
509
                                                                                  plan->targetlist,
 
510
                                                                                  &splan->paramIds);
 
511
                result = convert_testexpr(root,
 
512
                                                                  testexpr,
 
513
                                                                  params);
 
514
                splan->setParam = list_copy(splan->paramIds);
 
515
                isInitPlan = true;
 
516
 
 
517
                /*
 
518
                 * The executable expression is returned to become part of the outer
 
519
                 * plan's expression tree; it is not kept in the initplan node.
 
520
                 */
 
521
        }
 
522
        else
 
523
        {
 
524
                /*
 
525
                 * Adjust the Params in the testexpr, unless caller said it's not
 
526
                 * needed.
 
527
                 */
 
528
                if (testexpr && adjust_testexpr)
 
529
                {
 
530
                        List       *params;
 
531
 
 
532
                        params = generate_subquery_params(root,
 
533
                                                                                          plan->targetlist,
 
534
                                                                                          &splan->paramIds);
 
535
                        splan->testexpr = convert_testexpr(root,
 
536
                                                                                           testexpr,
 
537
                                                                                           params);
 
538
                }
 
539
                else
 
540
                        splan->testexpr = testexpr;
 
541
 
 
542
                /*
 
543
                 * We can't convert subplans of ALL_SUBLINK or ANY_SUBLINK types to
 
544
                 * initPlans, even when they are uncorrelated or undirect correlated,
 
545
                 * because we need to scan the output of the subplan for each outer
 
546
                 * tuple.  But if it's a not-direct-correlated IN (= ANY) test, we
 
547
                 * might be able to use a hashtable to avoid comparing all the tuples.
 
548
                 */
 
549
                if (subLinkType == ANY_SUBLINK &&
 
550
                        splan->parParam == NIL &&
 
551
                        subplan_is_hashable(plan) &&
 
552
                        testexpr_is_hashable(splan->testexpr))
 
553
                        splan->useHashTable = true;
 
554
 
 
555
                /*
 
556
                 * Otherwise, we have the option to tack a MATERIAL node onto the top
 
557
                 * of the subplan, to reduce the cost of reading it repeatedly.  This
 
558
                 * is pointless for a direct-correlated subplan, since we'd have to
 
559
                 * recompute its results each time anyway.      For uncorrelated/undirect
 
560
                 * correlated subplans, we add MATERIAL unless the subplan's top plan
 
561
                 * node would materialize its output anyway.
 
562
                 */
 
563
                else if (splan->parParam == NIL)
 
564
                {
 
565
                        bool            use_material;
 
566
 
 
567
                        switch (nodeTag(plan))
 
568
                        {
 
569
                                case T_Material:
 
570
                                case T_FunctionScan:
 
571
                                case T_CteScan:
 
572
                                case T_WorkTableScan:
 
573
                                case T_Sort:
 
574
                                        use_material = false;
 
575
                                        break;
 
576
                                default:
 
577
                                        use_material = true;
 
578
                                        break;
 
579
                        }
 
580
                        if (use_material)
 
581
                                plan = materialize_finished_plan(plan);
 
582
                }
 
583
 
 
584
                result = (Node *) splan;
 
585
                isInitPlan = false;
 
586
        }
 
587
 
 
588
        /*
 
589
         * Add the subplan and its rtable to the global lists.
 
590
         */
 
591
        root->glob->subplans = lappend(root->glob->subplans, plan);
 
592
        root->glob->subrtables = lappend(root->glob->subrtables, rtable);
 
593
        splan->plan_id = list_length(root->glob->subplans);
 
594
 
 
595
        if (isInitPlan)
 
596
                root->init_plans = lappend(root->init_plans, splan);
 
597
 
 
598
        /*
 
599
         * A parameterless subplan (not initplan) should be prepared to handle
 
600
         * REWIND efficiently.  If it has direct parameters then there's no point
 
601
         * since it'll be reset on each scan anyway; and if it's an initplan then
 
602
         * there's no point since it won't get re-run without parameter changes
 
603
         * anyway.      The input of a hashed subplan doesn't need REWIND either.
 
604
         */
 
605
        if (splan->parParam == NIL && !isInitPlan && !splan->useHashTable)
 
606
                root->glob->rewindPlanIDs = bms_add_member(root->glob->rewindPlanIDs,
 
607
                                                                                                   splan->plan_id);
 
608
 
 
609
        /* Lastly, fill in the cost estimates for use later */
 
610
        cost_subplan(root, splan, plan);
 
611
 
 
612
        return result;
 
613
}
 
614
 
 
615
/*
 
616
 * generate_subquery_params: build a list of Params representing the output
 
617
 * columns of a sublink's sub-select, given the sub-select's targetlist.
 
618
 *
 
619
 * We also return an integer list of the paramids of the Params.
 
620
 */
 
621
static List *
 
622
generate_subquery_params(PlannerInfo *root, List *tlist, List **paramIds)
 
623
{
 
624
        List       *result;
 
625
        List       *ids;
 
626
        ListCell   *lc;
 
627
 
 
628
        result = ids = NIL;
 
629
        foreach(lc, tlist)
 
630
        {
 
631
                TargetEntry *tent = (TargetEntry *) lfirst(lc);
 
632
                Param      *param;
 
633
 
 
634
                if (tent->resjunk)
 
635
                        continue;
 
636
 
 
637
                param = generate_new_param(root,
 
638
                                                                   exprType((Node *) tent->expr),
 
639
                                                                   exprTypmod((Node *) tent->expr));
 
640
                result = lappend(result, param);
 
641
                ids = lappend_int(ids, param->paramid);
 
642
        }
 
643
 
 
644
        *paramIds = ids;
 
645
        return result;
 
646
}
 
647
 
 
648
/*
 
649
 * generate_subquery_vars: build a list of Vars representing the output
 
650
 * columns of a sublink's sub-select, given the sub-select's targetlist.
 
651
 * The Vars have the specified varno (RTE index).
 
652
 */
 
653
static List *
 
654
generate_subquery_vars(PlannerInfo *root, List *tlist, Index varno)
 
655
{
 
656
        List       *result;
 
657
        ListCell   *lc;
 
658
 
 
659
        result = NIL;
 
660
        foreach(lc, tlist)
 
661
        {
 
662
                TargetEntry *tent = (TargetEntry *) lfirst(lc);
 
663
                Var                *var;
 
664
 
 
665
                if (tent->resjunk)
 
666
                        continue;
 
667
 
 
668
                var = makeVar(varno,
 
669
                                          tent->resno,
 
670
                                          exprType((Node *) tent->expr),
 
671
                                          exprTypmod((Node *) tent->expr),
 
672
                                          0);
 
673
                result = lappend(result, var);
 
674
        }
 
675
 
 
676
        return result;
 
677
}
 
678
 
 
679
/*
 
680
 * convert_testexpr: convert the testexpr given by the parser into
 
681
 * actually executable form.  This entails replacing PARAM_SUBLINK Params
 
682
 * with Params or Vars representing the results of the sub-select.  The
 
683
 * nodes to be substituted are passed in as the List result from
 
684
 * generate_subquery_params or generate_subquery_vars.
 
685
 *
 
686
 * The given testexpr has already been recursively processed by
 
687
 * process_sublinks_mutator.  Hence it can no longer contain any
 
688
 * PARAM_SUBLINK Params for lower SubLink nodes; we can safely assume that
 
689
 * any we find are for our own level of SubLink.
 
690
 */
 
691
static Node *
 
692
convert_testexpr(PlannerInfo *root,
 
693
                                 Node *testexpr,
 
694
                                 List *subst_nodes)
 
695
{
 
696
        convert_testexpr_context context;
 
697
 
 
698
        context.root = root;
 
699
        context.subst_nodes = subst_nodes;
 
700
        return convert_testexpr_mutator(testexpr, &context);
 
701
}
 
702
 
 
703
static Node *
 
704
convert_testexpr_mutator(Node *node,
 
705
                                                 convert_testexpr_context *context)
 
706
{
 
707
        if (node == NULL)
 
708
                return NULL;
 
709
        if (IsA(node, Param))
 
710
        {
 
711
                Param      *param = (Param *) node;
 
712
 
 
713
                if (param->paramkind == PARAM_SUBLINK)
 
714
                {
 
715
                        if (param->paramid <= 0 ||
 
716
                                param->paramid > list_length(context->subst_nodes))
 
717
                                elog(ERROR, "unexpected PARAM_SUBLINK ID: %d", param->paramid);
 
718
 
 
719
                        /*
 
720
                         * We copy the list item to avoid having doubly-linked
 
721
                         * substructure in the modified parse tree.  This is probably
 
722
                         * unnecessary when it's a Param, but be safe.
 
723
                         */
 
724
                        return (Node *) copyObject(list_nth(context->subst_nodes,
 
725
                                                                                                param->paramid - 1));
 
726
                }
 
727
        }
 
728
        return expression_tree_mutator(node,
 
729
                                                                   convert_testexpr_mutator,
 
730
                                                                   (void *) context);
 
731
}
 
732
 
 
733
/*
 
734
 * subplan_is_hashable: can we implement an ANY subplan by hashing?
 
735
 */
 
736
static bool
 
737
subplan_is_hashable(Plan *plan)
 
738
{
 
739
        double          subquery_size;
 
740
 
 
741
        /*
 
742
         * The estimated size of the subquery result must fit in work_mem. (Note:
 
743
         * we use sizeof(HeapTupleHeaderData) here even though the tuples will
 
744
         * actually be stored as MinimalTuples; this provides some fudge factor
 
745
         * for hashtable overhead.)
 
746
         */
 
747
        subquery_size = plan->plan_rows *
 
748
                (MAXALIGN(plan->plan_width) + MAXALIGN(sizeof(HeapTupleHeaderData)));
 
749
        if (subquery_size > work_mem * 1024L)
 
750
                return false;
 
751
 
 
752
        return true;
 
753
}
 
754
 
 
755
/*
 
756
 * testexpr_is_hashable: is an ANY SubLink's test expression hashable?
 
757
 */
 
758
static bool
 
759
testexpr_is_hashable(Node *testexpr)
 
760
{
 
761
        /*
 
762
         * The testexpr must be a single OpExpr, or an AND-clause containing
 
763
         * only OpExprs.
 
764
         *
 
765
         * The combining operators must be hashable and strict. The need for
 
766
         * hashability is obvious, since we want to use hashing. Without
 
767
         * strictness, behavior in the presence of nulls is too unpredictable.  We
 
768
         * actually must assume even more than plain strictness: they can't yield
 
769
         * NULL for non-null inputs, either (see nodeSubplan.c).  However, hash
 
770
         * indexes and hash joins assume that too.
 
771
         */
 
772
        if (testexpr && IsA(testexpr, OpExpr))
 
773
        {
 
774
                if (hash_ok_operator((OpExpr *) testexpr))
 
775
                        return true;
 
776
        }
 
777
        else if (and_clause(testexpr))
 
778
        {
 
779
                ListCell   *l;
 
780
 
 
781
                foreach(l, ((BoolExpr *) testexpr)->args)
 
782
                {
 
783
                        Node       *andarg = (Node *) lfirst(l);
 
784
 
 
785
                        if (!IsA(andarg, OpExpr))
 
786
                                return false;
 
787
                        if (!hash_ok_operator((OpExpr *) andarg))
 
788
                                return false;
 
789
                }
 
790
                return true;
 
791
        }
 
792
 
 
793
        return false;
 
794
}
 
795
 
 
796
static bool
 
797
hash_ok_operator(OpExpr *expr)
 
798
{
 
799
        Oid                     opid = expr->opno;
 
800
        HeapTuple       tup;
 
801
        Form_pg_operator optup;
 
802
 
 
803
        /* quick out if not a binary operator */
 
804
        if (list_length(expr->args) != 2)
 
805
                return false;
 
806
        /* else must look up the operator properties */
 
807
        tup = SearchSysCache(OPEROID,
 
808
                                                 ObjectIdGetDatum(opid),
 
809
                                                 0, 0, 0);
 
810
        if (!HeapTupleIsValid(tup))
 
811
                elog(ERROR, "cache lookup failed for operator %u", opid);
 
812
        optup = (Form_pg_operator) GETSTRUCT(tup);
 
813
        if (!optup->oprcanhash || !func_strict(optup->oprcode))
 
814
        {
 
815
                ReleaseSysCache(tup);
 
816
                return false;
 
817
        }
 
818
        ReleaseSysCache(tup);
 
819
        return true;
 
820
}
 
821
 
 
822
 
 
823
/*
 
824
 * SS_process_ctes: process a query's WITH list
 
825
 *
 
826
 * We plan each interesting WITH item and convert it to an initplan.
 
827
 * A side effect is to fill in root->cte_plan_ids with a list that
 
828
 * parallels root->parse->cteList and provides the subplan ID for
 
829
 * each CTE's initplan.
 
830
 */
 
831
void
 
832
SS_process_ctes(PlannerInfo *root)
 
833
{
 
834
        ListCell   *lc;
 
835
 
 
836
        Assert(root->cte_plan_ids == NIL);
 
837
 
 
838
        foreach(lc, root->parse->cteList)
 
839
        {
 
840
                CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
 
841
                Query      *subquery;
 
842
                Plan       *plan;
 
843
                PlannerInfo *subroot;
 
844
                SubPlan    *splan;
 
845
                Bitmapset  *tmpset;
 
846
                int                     paramid;
 
847
                Param      *prm;
 
848
 
 
849
                /*
 
850
                 * Ignore CTEs that are not actually referenced anywhere.
 
851
                 */
 
852
                if (cte->cterefcount == 0)
 
853
                {
 
854
                        /* Make a dummy entry in cte_plan_ids */
 
855
                        root->cte_plan_ids = lappend_int(root->cte_plan_ids, -1);
 
856
                        continue;
 
857
                }
 
858
 
 
859
                /*
 
860
                 * Copy the source Query node.  Probably not necessary, but let's
 
861
                 * keep this similar to make_subplan.
 
862
                 */
 
863
                subquery = (Query *) copyObject(cte->ctequery);
 
864
 
 
865
                /*
 
866
                 * Generate the plan for the CTE query.  Always plan for full
 
867
                 * retrieval --- we don't have enough info to predict otherwise.
 
868
                 */
 
869
                plan = subquery_planner(root->glob, subquery,
 
870
                                                                root,
 
871
                                                                cte->cterecursive, 0.0,
 
872
                                                                &subroot);
 
873
 
 
874
                /*
 
875
                 * Make a SubPlan node for it.  This is just enough unlike
 
876
                 * build_subplan that we can't share code.
 
877
                 *
 
878
                 * Note plan_id isn't set till further down, likewise the cost fields.
 
879
                 */
 
880
                splan = makeNode(SubPlan);
 
881
                splan->subLinkType = CTE_SUBLINK;
 
882
                splan->testexpr = NULL;
 
883
                splan->paramIds = NIL;
 
884
                get_first_col_type(plan, &splan->firstColType, &splan->firstColTypmod);
 
885
                splan->useHashTable = false;
 
886
                splan->unknownEqFalse = false;
 
887
                splan->setParam = NIL;
 
888
                splan->parParam = NIL;
 
889
                splan->args = NIL;
 
890
 
 
891
                /*
 
892
                 * Make parParam and args lists of param IDs and expressions that
 
893
                 * current query level will pass to this child plan.  Even though
 
894
                 * this is an initplan, there could be side-references to earlier
 
895
                 * initplan's outputs, specifically their CTE output parameters.
 
896
                 */
 
897
                tmpset = bms_copy(plan->extParam);
 
898
                while ((paramid = bms_first_member(tmpset)) >= 0)
 
899
                {
 
900
                        PlannerParamItem *pitem = list_nth(root->glob->paramlist, paramid);
 
901
 
 
902
                        if (pitem->abslevel == root->query_level)
 
903
                        {
 
904
                                prm = (Param *) pitem->item;
 
905
                                if (!IsA(prm, Param) ||
 
906
                                        prm->paramtype != INTERNALOID)
 
907
                                        elog(ERROR, "bogus local parameter passed to WITH query");
 
908
 
 
909
                                splan->parParam = lappend_int(splan->parParam, paramid);
 
910
                                splan->args = lappend(splan->args, copyObject(prm));
 
911
                        }
 
912
                }
 
913
                bms_free(tmpset);
 
914
 
 
915
                /*
 
916
                 * Assign a param to represent the query output.  We only really
 
917
                 * care about reserving a parameter ID number.
 
918
                 */
 
919
                prm = generate_new_param(root, INTERNALOID, -1);
 
920
                splan->setParam = list_make1_int(prm->paramid);
 
921
 
 
922
                /*
 
923
                 * Add the subplan and its rtable to the global lists.
 
924
                 */
 
925
                root->glob->subplans = lappend(root->glob->subplans, plan);
 
926
                root->glob->subrtables = lappend(root->glob->subrtables,
 
927
                                                                                 subroot->parse->rtable);
 
928
                splan->plan_id = list_length(root->glob->subplans);
 
929
 
 
930
                root->init_plans = lappend(root->init_plans, splan);
 
931
 
 
932
                root->cte_plan_ids = lappend_int(root->cte_plan_ids, splan->plan_id);
 
933
 
 
934
                /* Lastly, fill in the cost estimates for use later */
 
935
                cost_subplan(root, splan, plan);
 
936
        }
 
937
}
 
938
 
 
939
/*
 
940
 * convert_ANY_sublink_to_join: try to convert an ANY SubLink to a join
 
941
 *
 
942
 * The caller has found an ANY SubLink at the top level of one of the query's
 
943
 * qual clauses, but has not checked the properties of the SubLink further.
 
944
 * Decide whether it is appropriate to process this SubLink in join style.
 
945
 * If so, form a JoinExpr and return it.  Return NULL if the SubLink cannot
 
946
 * be converted to a join.
 
947
 *
 
948
 * The only non-obvious input parameter is available_rels: this is the set
 
949
 * of query rels that can safely be referenced in the sublink expression.
 
950
 * (We must restrict this to avoid changing the semantics when a sublink
 
951
 * is present in an outer join's ON qual.)  The conversion must fail if
 
952
 * the converted qual would reference any but these parent-query relids.
 
953
 *
 
954
 * On success, the returned JoinExpr has larg = NULL and rarg = the jointree
 
955
 * item representing the pulled-up subquery.  The caller must set larg to
 
956
 * represent the relation(s) on the lefthand side of the new join, and insert
 
957
 * the JoinExpr into the upper query's jointree at an appropriate place
 
958
 * (typically, where the lefthand relation(s) had been).  Note that the
 
959
 * passed-in SubLink must also be removed from its original position in the
 
960
 * query quals, since the quals of the returned JoinExpr replace it.
 
961
 * (Notionally, we replace the SubLink with a constant TRUE, then elide the
 
962
 * redundant constant from the qual.)
 
963
 *
 
964
 * Side effects of a successful conversion include adding the SubLink's
 
965
 * subselect to the query's rangetable, so that it can be referenced in
 
966
 * the JoinExpr's rarg.
 
967
 */
 
968
JoinExpr *
 
969
convert_ANY_sublink_to_join(PlannerInfo *root, SubLink *sublink,
 
970
                                                        Relids available_rels)
 
971
{
 
972
        JoinExpr   *result;
 
973
        Query      *parse = root->parse;
 
974
        Query      *subselect = (Query *) sublink->subselect;
 
975
        Relids          upper_varnos;
 
976
        int                     rtindex;
 
977
        RangeTblEntry *rte;
 
978
        RangeTblRef *rtr;
 
979
        List       *subquery_vars;
 
980
        Node       *quals;
 
981
 
 
982
        Assert(sublink->subLinkType == ANY_SUBLINK);
 
983
 
 
984
        /*
 
985
         * The sub-select must not refer to any Vars of the parent query. (Vars of
 
986
         * higher levels should be okay, though.)
 
987
         */
 
988
        if (contain_vars_of_level((Node *) subselect, 1))
 
989
                return NULL;
 
990
 
 
991
        /*
 
992
         * The test expression must contain some Vars of the parent query,
 
993
         * else it's not gonna be a join.  (Note that it won't have Vars
 
994
         * referring to the subquery, rather Params.)
 
995
         */
 
996
        upper_varnos = pull_varnos(sublink->testexpr);
 
997
        if (bms_is_empty(upper_varnos))
 
998
                return NULL;
 
999
 
 
1000
        /*
 
1001
         * However, it can't refer to anything outside available_rels.
 
1002
         */
 
1003
        if (!bms_is_subset(upper_varnos, available_rels))
 
1004
                return NULL;
 
1005
 
 
1006
        /*
 
1007
         * The combining operators and left-hand expressions mustn't be volatile.
 
1008
         */
 
1009
        if (contain_volatile_functions(sublink->testexpr))
 
1010
                return NULL;
 
1011
 
 
1012
        /*
 
1013
         * Okay, pull up the sub-select into upper range table.
 
1014
         *
 
1015
         * We rely here on the assumption that the outer query has no references
 
1016
         * to the inner (necessarily true, other than the Vars that we build
 
1017
         * below). Therefore this is a lot easier than what pull_up_subqueries has
 
1018
         * to go through.
 
1019
         */
 
1020
        rte = addRangeTableEntryForSubquery(NULL,
 
1021
                                                                                subselect,
 
1022
                                                                                makeAlias("ANY_subquery", NIL),
 
1023
                                                                                false);
 
1024
        parse->rtable = lappend(parse->rtable, rte);
 
1025
        rtindex = list_length(parse->rtable);
 
1026
 
 
1027
        /*
 
1028
         * Form a RangeTblRef for the pulled-up sub-select.
 
1029
         */
 
1030
        rtr = makeNode(RangeTblRef);
 
1031
        rtr->rtindex = rtindex;
 
1032
 
 
1033
        /*
 
1034
         * Build a list of Vars representing the subselect outputs.
 
1035
         */
 
1036
        subquery_vars = generate_subquery_vars(root,
 
1037
                                                                                   subselect->targetList,
 
1038
                                                                                   rtindex);
 
1039
 
 
1040
        /*
 
1041
         * Build the new join's qual expression, replacing Params with these Vars.
 
1042
         */
 
1043
        quals = convert_testexpr(root, sublink->testexpr, subquery_vars);
 
1044
 
 
1045
        /*
 
1046
         * And finally, build the JoinExpr node.
 
1047
         */
 
1048
        result = makeNode(JoinExpr);
 
1049
        result->jointype = JOIN_SEMI;
 
1050
        result->isNatural = false;
 
1051
        result->larg = NULL;            /* caller must fill this in */
 
1052
        result->rarg = (Node *) rtr;
 
1053
        result->using = NIL;
 
1054
        result->quals = quals;
 
1055
        result->alias = NULL;
 
1056
        result->rtindex = 0;            /* we don't need an RTE for it */
 
1057
 
 
1058
        return result;
 
1059
}
 
1060
 
 
1061
/*
 
1062
 * convert_EXISTS_sublink_to_join: try to convert an EXISTS SubLink to a join
 
1063
 *
 
1064
 * The API of this function is identical to convert_ANY_sublink_to_join's,
 
1065
 * except that we also support the case where the caller has found NOT EXISTS,
 
1066
 * so we need an additional input parameter "under_not".
 
1067
 */
 
1068
JoinExpr *
 
1069
convert_EXISTS_sublink_to_join(PlannerInfo *root, SubLink *sublink,
 
1070
                                                           bool under_not, Relids available_rels)
 
1071
{
 
1072
        JoinExpr   *result;
 
1073
        Query      *parse = root->parse;
 
1074
        Query      *subselect = (Query *) sublink->subselect;
 
1075
        Node       *whereClause;
 
1076
        int                     rtoffset;
 
1077
        int                     varno;
 
1078
        Relids          clause_varnos;
 
1079
        Relids          upper_varnos;
 
1080
 
 
1081
        Assert(sublink->subLinkType == EXISTS_SUBLINK);
 
1082
 
 
1083
        /*
 
1084
         * Copy the subquery so we can modify it safely (see comments in
 
1085
         * make_subplan).
 
1086
         */
 
1087
        subselect = (Query *) copyObject(subselect);
 
1088
 
 
1089
        /*
 
1090
         * See if the subquery can be simplified based on the knowledge that
 
1091
         * it's being used in EXISTS().  If we aren't able to get rid of its
 
1092
         * targetlist, we have to fail, because the pullup operation leaves
 
1093
         * us with noplace to evaluate the targetlist.
 
1094
         */
 
1095
        if (!simplify_EXISTS_query(subselect))
 
1096
                return NULL;
 
1097
 
 
1098
        /*
 
1099
         * The subquery must have a nonempty jointree, else we won't have a join.
 
1100
         */
 
1101
        if (subselect->jointree->fromlist == NIL)
 
1102
                return NULL;
 
1103
 
 
1104
        /*
 
1105
         * Separate out the WHERE clause.  (We could theoretically also remove
 
1106
         * top-level plain JOIN/ON clauses, but it's probably not worth the
 
1107
         * trouble.)
 
1108
         */
 
1109
        whereClause = subselect->jointree->quals;
 
1110
        subselect->jointree->quals = NULL;
 
1111
 
 
1112
        /*
 
1113
         * The rest of the sub-select must not refer to any Vars of the parent
 
1114
         * query.  (Vars of higher levels should be okay, though.)
 
1115
         */
 
1116
        if (contain_vars_of_level((Node *) subselect, 1))
 
1117
                return NULL;
 
1118
 
 
1119
        /*
 
1120
         * On the other hand, the WHERE clause must contain some Vars of the
 
1121
         * parent query, else it's not gonna be a join.
 
1122
         */
 
1123
        if (!contain_vars_of_level(whereClause, 1))
 
1124
                return NULL;
 
1125
 
 
1126
        /*
 
1127
         * We don't risk optimizing if the WHERE clause is volatile, either.
 
1128
         */
 
1129
        if (contain_volatile_functions(whereClause))
 
1130
                return NULL;
 
1131
 
 
1132
        /*
 
1133
         * Prepare to pull up the sub-select into top range table.
 
1134
         *
 
1135
         * We rely here on the assumption that the outer query has no references
 
1136
         * to the inner (necessarily true). Therefore this is a lot easier than
 
1137
         * what pull_up_subqueries has to go through.
 
1138
         *
 
1139
         * In fact, it's even easier than what convert_ANY_sublink_to_join has
 
1140
         * to do.  The machinations of simplify_EXISTS_query ensured that there
 
1141
         * is nothing interesting in the subquery except an rtable and jointree,
 
1142
         * and even the jointree FromExpr no longer has quals.  So we can just
 
1143
         * append the rtable to our own and use the FromExpr in our jointree.
 
1144
         * But first, adjust all level-zero varnos in the subquery to account
 
1145
         * for the rtable merger.
 
1146
         */
 
1147
        rtoffset = list_length(parse->rtable);
 
1148
        OffsetVarNodes((Node *) subselect, rtoffset, 0);
 
1149
        OffsetVarNodes(whereClause, rtoffset, 0);
 
1150
 
 
1151
        /*
 
1152
         * Upper-level vars in subquery will now be one level closer to their
 
1153
         * parent than before; in particular, anything that had been level 1
 
1154
         * becomes level zero.
 
1155
         */
 
1156
        IncrementVarSublevelsUp((Node *) subselect, -1, 1);
 
1157
        IncrementVarSublevelsUp(whereClause, -1, 1);
 
1158
 
 
1159
        /*
 
1160
         * Now that the WHERE clause is adjusted to match the parent query
 
1161
         * environment, we can easily identify all the level-zero rels it uses.
 
1162
         * The ones <= rtoffset belong to the upper query; the ones > rtoffset
 
1163
         * do not.
 
1164
         */
 
1165
        clause_varnos = pull_varnos(whereClause);
 
1166
        upper_varnos = NULL;
 
1167
        while ((varno = bms_first_member(clause_varnos)) >= 0)
 
1168
        {
 
1169
                if (varno <= rtoffset)
 
1170
                        upper_varnos = bms_add_member(upper_varnos, varno);
 
1171
        }
 
1172
        bms_free(clause_varnos);
 
1173
        Assert(!bms_is_empty(upper_varnos));
 
1174
 
 
1175
        /*
 
1176
         * Now that we've got the set of upper-level varnos, we can make the
 
1177
         * last check: only available_rels can be referenced.
 
1178
         */
 
1179
        if (!bms_is_subset(upper_varnos, available_rels))
 
1180
                return NULL;
 
1181
 
 
1182
        /* Now we can attach the modified subquery rtable to the parent */
 
1183
        parse->rtable = list_concat(parse->rtable, subselect->rtable);
 
1184
 
 
1185
        /*
 
1186
         * And finally, build the JoinExpr node.
 
1187
         */
 
1188
        result = makeNode(JoinExpr);
 
1189
        result->jointype = under_not ? JOIN_ANTI : JOIN_SEMI;
 
1190
        result->isNatural = false;
 
1191
        result->larg = NULL;            /* caller must fill this in */
 
1192
        /* flatten out the FromExpr node if it's useless */
 
1193
        if (list_length(subselect->jointree->fromlist) == 1)
 
1194
                result->rarg = (Node *) linitial(subselect->jointree->fromlist);
 
1195
        else
 
1196
                result->rarg = (Node *) subselect->jointree;
 
1197
        result->using = NIL;
 
1198
        result->quals = whereClause;
 
1199
        result->alias = NULL;
 
1200
        result->rtindex = 0;            /* we don't need an RTE for it */
 
1201
 
 
1202
        return result;
 
1203
}
 
1204
 
 
1205
/*
 
1206
 * simplify_EXISTS_query: remove any useless stuff in an EXISTS's subquery
 
1207
 *
 
1208
 * The only thing that matters about an EXISTS query is whether it returns
 
1209
 * zero or more than zero rows.  Therefore, we can remove certain SQL features
 
1210
 * that won't affect that.  The only part that is really likely to matter in
 
1211
 * typical usage is simplifying the targetlist: it's a common habit to write
 
1212
 * "SELECT * FROM" even though there is no need to evaluate any columns.
 
1213
 *
 
1214
 * Note: by suppressing the targetlist we could cause an observable behavioral
 
1215
 * change, namely that any errors that might occur in evaluating the tlist
 
1216
 * won't occur, nor will other side-effects of volatile functions.  This seems
 
1217
 * unlikely to bother anyone in practice.
 
1218
 *
 
1219
 * Returns TRUE if was able to discard the targetlist, else FALSE.
 
1220
 */
 
1221
static bool
 
1222
simplify_EXISTS_query(Query *query)
 
1223
{
 
1224
        /*
 
1225
         * We don't try to simplify at all if the query uses set operations,
 
1226
         * aggregates, HAVING, LIMIT/OFFSET, or FOR UPDATE/SHARE; none of these
 
1227
         * seem likely in normal usage and their possible effects are complex.
 
1228
         */
 
1229
        if (query->commandType != CMD_SELECT ||
 
1230
                query->intoClause ||
 
1231
                query->setOperations ||
 
1232
                query->hasAggs ||
 
1233
                query->hasWindowFuncs ||
 
1234
                query->havingQual ||
 
1235
                query->limitOffset ||
 
1236
                query->limitCount ||
 
1237
                query->rowMarks)
 
1238
                return false;
 
1239
 
 
1240
        /*
 
1241
         * Mustn't throw away the targetlist if it contains set-returning
 
1242
         * functions; those could affect whether zero rows are returned!
 
1243
         */
 
1244
        if (expression_returns_set((Node *) query->targetList))
 
1245
                return false;
 
1246
 
 
1247
        /*
 
1248
         * Otherwise, we can throw away the targetlist, as well as any GROUP,
 
1249
         * WINDOW, DISTINCT, and ORDER BY clauses; none of those clauses will
 
1250
         * change a nonzero-rows result to zero rows or vice versa.  (Furthermore,
 
1251
         * since our parsetree representation of these clauses depends on the
 
1252
         * targetlist, we'd better throw them away if we drop the targetlist.)
 
1253
         */
 
1254
        query->targetList = NIL;
 
1255
        query->groupClause = NIL;
 
1256
        query->windowClause = NIL;
 
1257
        query->distinctClause = NIL;
 
1258
        query->sortClause = NIL;
 
1259
        query->hasDistinctOn = false;
 
1260
 
 
1261
        return true;
 
1262
}
 
1263
 
 
1264
/*
 
1265
 * convert_EXISTS_to_ANY: try to convert EXISTS to a hashable ANY sublink
 
1266
 *
 
1267
 * The subselect is expected to be a fresh copy that we can munge up,
 
1268
 * and to have been successfully passed through simplify_EXISTS_query.
 
1269
 *
 
1270
 * On success, the modified subselect is returned, and we store a suitable
 
1271
 * upper-level test expression at *testexpr, plus a list of the subselect's
 
1272
 * output Params at *paramIds.  (The test expression is already Param-ified
 
1273
 * and hence need not go through convert_testexpr, which is why we have to
 
1274
 * deal with the Param IDs specially.)
 
1275
 *
 
1276
 * On failure, returns NULL.
 
1277
 */
 
1278
static Query *
 
1279
convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect,
 
1280
                                          Node **testexpr, List **paramIds)
 
1281
{
 
1282
        Node       *whereClause;
 
1283
        List       *leftargs,
 
1284
                           *rightargs,
 
1285
                           *opids,
 
1286
                           *newWhere,
 
1287
                           *tlist,
 
1288
                           *testlist,
 
1289
                           *paramids;
 
1290
        ListCell   *lc,
 
1291
                           *rc,
 
1292
                           *oc;
 
1293
        AttrNumber      resno;
 
1294
 
 
1295
        /*
 
1296
         * Query must not require a targetlist, since we have to insert a new one.
 
1297
         * Caller should have dealt with the case already.
 
1298
         */
 
1299
        Assert(subselect->targetList == NIL);
 
1300
 
 
1301
        /*
 
1302
         * Separate out the WHERE clause.  (We could theoretically also remove
 
1303
         * top-level plain JOIN/ON clauses, but it's probably not worth the
 
1304
         * trouble.)
 
1305
         */
 
1306
        whereClause = subselect->jointree->quals;
 
1307
        subselect->jointree->quals = NULL;
 
1308
 
 
1309
        /*
 
1310
         * The rest of the sub-select must not refer to any Vars of the parent
 
1311
         * query.  (Vars of higher levels should be okay, though.)
 
1312
         *
 
1313
         * Note: we need not check for Aggrefs separately because we know the
 
1314
         * sub-select is as yet unoptimized; any uplevel Aggref must therefore
 
1315
         * contain an uplevel Var reference.  This is not the case below ...
 
1316
         */
 
1317
        if (contain_vars_of_level((Node *) subselect, 1))
 
1318
                return NULL;
 
1319
 
 
1320
        /*
 
1321
         * We don't risk optimizing if the WHERE clause is volatile, either.
 
1322
         */
 
1323
        if (contain_volatile_functions(whereClause))
 
1324
                return NULL;
 
1325
 
 
1326
        /*
 
1327
         * Clean up the WHERE clause by doing const-simplification etc on it.
 
1328
         * Aside from simplifying the processing we're about to do, this is
 
1329
         * important for being able to pull chunks of the WHERE clause up into
 
1330
         * the parent query.  Since we are invoked partway through the parent's
 
1331
         * preprocess_expression() work, earlier steps of preprocess_expression()
 
1332
         * wouldn't get applied to the pulled-up stuff unless we do them here.
 
1333
         * For the parts of the WHERE clause that get put back into the child
 
1334
         * query, this work is partially duplicative, but it shouldn't hurt.
 
1335
         *
 
1336
         * Note: we do not run flatten_join_alias_vars.  This is OK because
 
1337
         * any parent aliases were flattened already, and we're not going to
 
1338
         * pull any child Vars (of any description) into the parent.
 
1339
         *
 
1340
         * Note: passing the parent's root to eval_const_expressions is technically
 
1341
         * wrong, but we can get away with it since only the boundParams (if any)
 
1342
         * are used, and those would be the same in a subroot.
 
1343
         */
 
1344
        whereClause = eval_const_expressions(root, whereClause);
 
1345
        whereClause = (Node *) canonicalize_qual((Expr *) whereClause);
 
1346
        whereClause = (Node *) make_ands_implicit((Expr *) whereClause);
 
1347
 
 
1348
        /*
 
1349
         * We now have a flattened implicit-AND list of clauses, which we
 
1350
         * try to break apart into "outervar = innervar" hash clauses.
 
1351
         * Anything that can't be broken apart just goes back into the
 
1352
         * newWhere list.  Note that we aren't trying hard yet to ensure
 
1353
         * that we have only outer or only inner on each side; we'll check
 
1354
         * that if we get to the end.
 
1355
         */
 
1356
        leftargs = rightargs = opids = newWhere = NIL;
 
1357
        foreach(lc, (List *) whereClause)
 
1358
        {
 
1359
                OpExpr     *expr = (OpExpr *) lfirst(lc);
 
1360
 
 
1361
                if (IsA(expr, OpExpr) &&
 
1362
                        hash_ok_operator(expr))
 
1363
                {
 
1364
                        Node   *leftarg = (Node *) linitial(expr->args);
 
1365
                        Node   *rightarg = (Node *) lsecond(expr->args);
 
1366
 
 
1367
                        if (contain_vars_of_level(leftarg, 1))
 
1368
                        {
 
1369
                                leftargs = lappend(leftargs, leftarg);
 
1370
                                rightargs = lappend(rightargs, rightarg);
 
1371
                                opids = lappend_oid(opids, expr->opno);
 
1372
                                continue;
 
1373
                        }
 
1374
                        if (contain_vars_of_level(rightarg, 1))
 
1375
                        {
 
1376
                                /*
 
1377
                                 * We must commute the clause to put the outer var on the
 
1378
                                 * left, because the hashing code in nodeSubplan.c expects
 
1379
                                 * that.  This probably shouldn't ever fail, since hashable
 
1380
                                 * operators ought to have commutators, but be paranoid.
 
1381
                                 */
 
1382
                                expr->opno = get_commutator(expr->opno);
 
1383
                                if (OidIsValid(expr->opno) && hash_ok_operator(expr))
 
1384
                                {
 
1385
                                        leftargs = lappend(leftargs, rightarg);
 
1386
                                        rightargs = lappend(rightargs, leftarg);
 
1387
                                        opids = lappend_oid(opids, expr->opno);
 
1388
                                        continue;
 
1389
                                }
 
1390
                                /* If no commutator, no chance to optimize the WHERE clause */
 
1391
                                return NULL;
 
1392
                        }
 
1393
                }
 
1394
                /* Couldn't handle it as a hash clause */
 
1395
                newWhere = lappend(newWhere, expr);
 
1396
        }
 
1397
 
 
1398
        /*
 
1399
         * If we didn't find anything we could convert, fail.
 
1400
         */
 
1401
        if (leftargs == NIL)
 
1402
                return NULL;
 
1403
 
 
1404
        /*
 
1405
         * There mustn't be any parent Vars or Aggs in the stuff that we intend to
 
1406
         * put back into the child query.  Note: you might think we don't need to
 
1407
         * check for Aggs separately, because an uplevel Agg must contain an
 
1408
         * uplevel Var in its argument.  But it is possible that the uplevel Var
 
1409
         * got optimized away by eval_const_expressions.  Consider
 
1410
         *
 
1411
         * SUM(CASE WHEN false THEN uplevelvar ELSE 0 END)
 
1412
         */
 
1413
        if (contain_vars_of_level((Node *) newWhere, 1) ||
 
1414
                contain_vars_of_level((Node *) rightargs, 1))
 
1415
                return NULL;
 
1416
        if (root->parse->hasAggs &&
 
1417
                (contain_aggs_of_level((Node *) newWhere, 1) ||
 
1418
                 contain_aggs_of_level((Node *) rightargs, 1)))
 
1419
                return NULL;
 
1420
 
 
1421
        /*
 
1422
         * And there can't be any child Vars in the stuff we intend to pull up.
 
1423
         * (Note: we'd need to check for child Aggs too, except we know the
 
1424
         * child has no aggs at all because of simplify_EXISTS_query's check.
 
1425
         * The same goes for window functions.)
 
1426
         */
 
1427
        if (contain_vars_of_level((Node *) leftargs, 0))
 
1428
                return NULL;
 
1429
 
 
1430
        /*
 
1431
         * Also reject sublinks in the stuff we intend to pull up.  (It might be
 
1432
         * possible to support this, but doesn't seem worth the complication.)
 
1433
         */
 
1434
        if (contain_subplans((Node *) leftargs))
 
1435
                return NULL;
 
1436
 
 
1437
        /*
 
1438
         * Okay, adjust the sublevelsup in the stuff we're pulling up.
 
1439
         */
 
1440
        IncrementVarSublevelsUp((Node *) leftargs, -1, 1);
 
1441
 
 
1442
        /*
 
1443
         * Put back any child-level-only WHERE clauses.
 
1444
         */
 
1445
        if (newWhere)
 
1446
                subselect->jointree->quals = (Node *) make_ands_explicit(newWhere);
 
1447
 
 
1448
        /*
 
1449
         * Build a new targetlist for the child that emits the expressions
 
1450
         * we need.  Concurrently, build a testexpr for the parent using
 
1451
         * Params to reference the child outputs.  (Since we generate Params
 
1452
         * directly here, there will be no need to convert the testexpr in
 
1453
         * build_subplan.)
 
1454
         */
 
1455
        tlist = testlist = paramids = NIL;
 
1456
        resno = 1;
 
1457
        /* there's no "for3" so we have to chase one of the lists manually */
 
1458
        oc = list_head(opids);
 
1459
        forboth(lc, leftargs, rc, rightargs)
 
1460
        {
 
1461
                Node       *leftarg = (Node *) lfirst(lc);
 
1462
                Node       *rightarg = (Node *) lfirst(rc);
 
1463
                Oid                     opid = lfirst_oid(oc);
 
1464
                Param      *param;
 
1465
 
 
1466
                oc = lnext(oc);
 
1467
                param = generate_new_param(root,
 
1468
                                                                   exprType(rightarg),
 
1469
                                                                   exprTypmod(rightarg));
 
1470
                tlist = lappend(tlist,
 
1471
                                                makeTargetEntry((Expr *) rightarg,
 
1472
                                                                                resno++,
 
1473
                                                                                NULL,
 
1474
                                                                                false));
 
1475
                testlist = lappend(testlist,
 
1476
                                                   make_opclause(opid, BOOLOID, false,
 
1477
                                                                                 (Expr *) leftarg, (Expr *) param));
 
1478
                paramids = lappend_int(paramids, param->paramid);
 
1479
        }
 
1480
 
 
1481
        /* Put everything where it should go, and we're done */
 
1482
        subselect->targetList = tlist;
 
1483
        *testexpr = (Node *) make_ands_explicit(testlist);
 
1484
        *paramIds = paramids;
 
1485
 
 
1486
        return subselect;
 
1487
}
 
1488
 
 
1489
 
 
1490
/*
 
1491
 * Replace correlation vars (uplevel vars) with Params.
 
1492
 *
 
1493
 * Uplevel aggregates are replaced, too.
 
1494
 *
 
1495
 * Note: it is critical that this runs immediately after SS_process_sublinks.
 
1496
 * Since we do not recurse into the arguments of uplevel aggregates, they will
 
1497
 * get copied to the appropriate subplan args list in the parent query with
 
1498
 * uplevel vars not replaced by Params, but only adjusted in level (see
 
1499
 * replace_outer_agg).  That's exactly what we want for the vars of the parent
 
1500
 * level --- but if an aggregate's argument contains any further-up variables,
 
1501
 * they have to be replaced with Params in their turn.  That will happen when
 
1502
 * the parent level runs SS_replace_correlation_vars.  Therefore it must do
 
1503
 * so after expanding its sublinks to subplans.  And we don't want any steps
 
1504
 * in between, else those steps would never get applied to the aggregate
 
1505
 * argument expressions, either in the parent or the child level.
 
1506
 */
 
1507
Node *
 
1508
SS_replace_correlation_vars(PlannerInfo *root, Node *expr)
 
1509
{
 
1510
        /* No setup needed for tree walk, so away we go */
 
1511
        return replace_correlation_vars_mutator(expr, root);
 
1512
}
 
1513
 
 
1514
static Node *
 
1515
replace_correlation_vars_mutator(Node *node, PlannerInfo *root)
 
1516
{
 
1517
        if (node == NULL)
 
1518
                return NULL;
 
1519
        if (IsA(node, Var))
 
1520
        {
 
1521
                if (((Var *) node)->varlevelsup > 0)
 
1522
                        return (Node *) replace_outer_var(root, (Var *) node);
 
1523
        }
 
1524
        if (IsA(node, Aggref))
 
1525
        {
 
1526
                if (((Aggref *) node)->agglevelsup > 0)
 
1527
                        return (Node *) replace_outer_agg(root, (Aggref *) node);
 
1528
        }
 
1529
        return expression_tree_mutator(node,
 
1530
                                                                   replace_correlation_vars_mutator,
 
1531
                                                                   (void *) root);
 
1532
}
 
1533
 
 
1534
/*
 
1535
 * Expand SubLinks to SubPlans in the given expression.
 
1536
 *
 
1537
 * The isQual argument tells whether or not this expression is a WHERE/HAVING
 
1538
 * qualifier expression.  If it is, any sublinks appearing at top level need
 
1539
 * not distinguish FALSE from UNKNOWN return values.
 
1540
 */
 
1541
Node *
 
1542
SS_process_sublinks(PlannerInfo *root, Node *expr, bool isQual)
 
1543
{
 
1544
        process_sublinks_context context;
 
1545
 
 
1546
        context.root = root;
 
1547
        context.isTopQual = isQual;
 
1548
        return process_sublinks_mutator(expr, &context);
 
1549
}
 
1550
 
 
1551
static Node *
 
1552
process_sublinks_mutator(Node *node, process_sublinks_context *context)
 
1553
{
 
1554
        process_sublinks_context locContext;
 
1555
 
 
1556
        locContext.root = context->root;
 
1557
 
 
1558
        if (node == NULL)
 
1559
                return NULL;
 
1560
        if (IsA(node, SubLink))
 
1561
        {
 
1562
                SubLink    *sublink = (SubLink *) node;
 
1563
                Node       *testexpr;
 
1564
 
 
1565
                /*
 
1566
                 * First, recursively process the lefthand-side expressions, if any.
 
1567
                 * They're not top-level anymore.
 
1568
                 */
 
1569
                locContext.isTopQual = false;
 
1570
                testexpr = process_sublinks_mutator(sublink->testexpr, &locContext);
 
1571
 
 
1572
                /*
 
1573
                 * Now build the SubPlan node and make the expr to return.
 
1574
                 */
 
1575
                return make_subplan(context->root,
 
1576
                                                        (Query *) sublink->subselect,
 
1577
                                                        sublink->subLinkType,
 
1578
                                                        testexpr,
 
1579
                                                        context->isTopQual);
 
1580
        }
 
1581
 
 
1582
        /*
 
1583
         * We should never see a SubPlan expression in the input (since this is
 
1584
         * the very routine that creates 'em to begin with).  We shouldn't find
 
1585
         * ourselves invoked directly on a Query, either.
 
1586
         */
 
1587
        Assert(!IsA(node, SubPlan));
 
1588
        Assert(!IsA(node, AlternativeSubPlan));
 
1589
        Assert(!IsA(node, Query));
 
1590
 
 
1591
        /*
 
1592
         * Because make_subplan() could return an AND or OR clause, we have to
 
1593
         * take steps to preserve AND/OR flatness of a qual.  We assume the input
 
1594
         * has been AND/OR flattened and so we need no recursion here.
 
1595
         *
 
1596
         * (Due to the coding here, we will not get called on the List subnodes of
 
1597
         * an AND; and the input is *not* yet in implicit-AND format.  So no check
 
1598
         * is needed for a bare List.)
 
1599
         *
 
1600
         * Anywhere within the top-level AND/OR clause structure, we can tell
 
1601
         * make_subplan() that NULL and FALSE are interchangeable.  So isTopQual
 
1602
         * propagates down in both cases.  (Note that this is unlike the meaning
 
1603
         * of "top level qual" used in most other places in Postgres.)
 
1604
         */
 
1605
        if (and_clause(node))
 
1606
        {
 
1607
                List       *newargs = NIL;
 
1608
                ListCell   *l;
 
1609
 
 
1610
                /* Still at qual top-level */
 
1611
                locContext.isTopQual = context->isTopQual;
 
1612
 
 
1613
                foreach(l, ((BoolExpr *) node)->args)
 
1614
                {
 
1615
                        Node       *newarg;
 
1616
 
 
1617
                        newarg = process_sublinks_mutator(lfirst(l), &locContext);
 
1618
                        if (and_clause(newarg))
 
1619
                                newargs = list_concat(newargs, ((BoolExpr *) newarg)->args);
 
1620
                        else
 
1621
                                newargs = lappend(newargs, newarg);
 
1622
                }
 
1623
                return (Node *) make_andclause(newargs);
 
1624
        }
 
1625
 
 
1626
        if (or_clause(node))
 
1627
        {
 
1628
                List       *newargs = NIL;
 
1629
                ListCell   *l;
 
1630
 
 
1631
                /* Still at qual top-level */
 
1632
                locContext.isTopQual = context->isTopQual;
 
1633
 
 
1634
                foreach(l, ((BoolExpr *) node)->args)
 
1635
                {
 
1636
                        Node       *newarg;
 
1637
 
 
1638
                        newarg = process_sublinks_mutator(lfirst(l), &locContext);
 
1639
                        if (or_clause(newarg))
 
1640
                                newargs = list_concat(newargs, ((BoolExpr *) newarg)->args);
 
1641
                        else
 
1642
                                newargs = lappend(newargs, newarg);
 
1643
                }
 
1644
                return (Node *) make_orclause(newargs);
 
1645
        }
 
1646
 
 
1647
        /*
 
1648
         * If we recurse down through anything other than an AND or OR node,
 
1649
         * we are definitely not at top qual level anymore.
 
1650
         */
 
1651
        locContext.isTopQual = false;
 
1652
 
 
1653
        return expression_tree_mutator(node,
 
1654
                                                                   process_sublinks_mutator,
 
1655
                                                                   (void *) &locContext);
 
1656
}
 
1657
 
 
1658
/*
 
1659
 * SS_finalize_plan - do final sublink processing for a completed Plan.
 
1660
 *
 
1661
 * This recursively computes the extParam and allParam sets for every Plan
 
1662
 * node in the given plan tree.  It also optionally attaches any previously
 
1663
 * generated InitPlans to the top plan node.  (Any InitPlans should already
 
1664
 * have been put through SS_finalize_plan.)
 
1665
 */
 
1666
void
 
1667
SS_finalize_plan(PlannerInfo *root, Plan *plan, bool attach_initplans)
 
1668
{
 
1669
        Bitmapset  *valid_params,
 
1670
                           *initExtParam,
 
1671
                           *initSetParam;
 
1672
        Cost            initplan_cost;
 
1673
        int                     paramid;
 
1674
        ListCell   *l;
 
1675
 
 
1676
        /*
 
1677
         * Examine any initPlans to determine the set of external params they
 
1678
         * reference, the set of output params they supply, and their total cost.
 
1679
         * We'll use at least some of this info below.  (Note we are assuming that
 
1680
         * finalize_plan doesn't touch the initPlans.)
 
1681
         *
 
1682
         * In the case where attach_initplans is false, we are assuming that the
 
1683
         * existing initPlans are siblings that might supply params needed by the
 
1684
         * current plan.
 
1685
         */
 
1686
        initExtParam = initSetParam = NULL;
 
1687
        initplan_cost = 0;
 
1688
        foreach(l, root->init_plans)
 
1689
        {
 
1690
                SubPlan    *initsubplan = (SubPlan *) lfirst(l);
 
1691
                Plan       *initplan = planner_subplan_get_plan(root, initsubplan);
 
1692
                ListCell   *l2;
 
1693
 
 
1694
                initExtParam = bms_add_members(initExtParam, initplan->extParam);
 
1695
                foreach(l2, initsubplan->setParam)
 
1696
                {
 
1697
                        initSetParam = bms_add_member(initSetParam, lfirst_int(l2));
 
1698
                }
 
1699
                initplan_cost += initsubplan->startup_cost + initsubplan->per_call_cost;
 
1700
        }
 
1701
 
 
1702
        /*
 
1703
         * Now determine the set of params that are validly referenceable in this
 
1704
         * query level; to wit, those available from outer query levels plus the
 
1705
         * output parameters of any initPlans.  (We do not include output
 
1706
         * parameters of regular subplans.  Those should only appear within the
 
1707
         * testexpr of SubPlan nodes, and are taken care of locally within
 
1708
         * finalize_primnode.)
 
1709
         *
 
1710
         * Note: this is a bit overly generous since some parameters of upper
 
1711
         * query levels might belong to query subtrees that don't include this
 
1712
         * query.  However, valid_params is only a debugging crosscheck, so it
 
1713
         * doesn't seem worth expending lots of cycles to try to be exact.
 
1714
         */
 
1715
        valid_params = bms_copy(initSetParam);
 
1716
        paramid = 0;
 
1717
        foreach(l, root->glob->paramlist)
 
1718
        {
 
1719
                PlannerParamItem *pitem = (PlannerParamItem *) lfirst(l);
 
1720
 
 
1721
                if (pitem->abslevel < root->query_level)
 
1722
                {
 
1723
                        /* valid outer-level parameter */
 
1724
                        valid_params = bms_add_member(valid_params, paramid);
 
1725
                }
 
1726
 
 
1727
                paramid++;
 
1728
        }
 
1729
        /* Also include the recursion working table, if any */
 
1730
        if (root->wt_param_id >= 0)
 
1731
                valid_params = bms_add_member(valid_params, root->wt_param_id);
 
1732
 
 
1733
        /*
 
1734
         * Now recurse through plan tree.
 
1735
         */
 
1736
        (void) finalize_plan(root, plan, valid_params);
 
1737
 
 
1738
        bms_free(valid_params);
 
1739
 
 
1740
        /*
 
1741
         * Finally, attach any initPlans to the topmost plan node, and add their
 
1742
         * extParams to the topmost node's, too.  However, any setParams of the
 
1743
         * initPlans should not be present in the topmost node's extParams, only
 
1744
         * in its allParams.  (As of PG 8.1, it's possible that some initPlans
 
1745
         * have extParams that are setParams of other initPlans, so we have to
 
1746
         * take care of this situation explicitly.)
 
1747
         *
 
1748
         * We also add the eval cost of each initPlan to the startup cost of the
 
1749
         * top node.  This is a conservative overestimate, since in fact each
 
1750
         * initPlan might be executed later than plan startup, or even not at all.
 
1751
         */
 
1752
        if (attach_initplans)
 
1753
        {
 
1754
                plan->initPlan = root->init_plans;
 
1755
                root->init_plans = NIL;         /* make sure they're not attached twice */
 
1756
 
 
1757
                /* allParam must include all these params */
 
1758
                plan->allParam = bms_add_members(plan->allParam, initExtParam);
 
1759
                plan->allParam = bms_add_members(plan->allParam, initSetParam);
 
1760
                /* extParam must include any child extParam */
 
1761
                plan->extParam = bms_add_members(plan->extParam, initExtParam);
 
1762
                /* but extParam shouldn't include any setParams */
 
1763
                plan->extParam = bms_del_members(plan->extParam, initSetParam);
 
1764
                /* ensure extParam is exactly NULL if it's empty */
 
1765
                if (bms_is_empty(plan->extParam))
 
1766
                        plan->extParam = NULL;
 
1767
 
 
1768
                plan->startup_cost += initplan_cost;
 
1769
                plan->total_cost += initplan_cost;
 
1770
        }
 
1771
}
 
1772
 
 
1773
/*
 
1774
 * Recursive processing of all nodes in the plan tree
 
1775
 *
 
1776
 * The return value is the computed allParam set for the given Plan node.
 
1777
 * This is just an internal notational convenience.
 
1778
 */
 
1779
static Bitmapset *
 
1780
finalize_plan(PlannerInfo *root, Plan *plan, Bitmapset *valid_params)
 
1781
{
 
1782
        finalize_primnode_context context;
 
1783
 
 
1784
        if (plan == NULL)
 
1785
                return NULL;
 
1786
 
 
1787
        context.root = root;
 
1788
        context.paramids = NULL;        /* initialize set to empty */
 
1789
 
 
1790
        /*
 
1791
         * When we call finalize_primnode, context.paramids sets are automatically
 
1792
         * merged together.  But when recursing to self, we have to do it the hard
 
1793
         * way.  We want the paramids set to include params in subplans as well as
 
1794
         * at this level.
 
1795
         */
 
1796
 
 
1797
        /* Find params in targetlist and qual */
 
1798
        finalize_primnode((Node *) plan->targetlist, &context);
 
1799
        finalize_primnode((Node *) plan->qual, &context);
 
1800
 
 
1801
        /* Check additional node-type-specific fields */
 
1802
        switch (nodeTag(plan))
 
1803
        {
 
1804
                case T_Result:
 
1805
                        finalize_primnode(((Result *) plan)->resconstantqual,
 
1806
                                                          &context);
 
1807
                        break;
 
1808
 
 
1809
                case T_IndexScan:
 
1810
                        finalize_primnode((Node *) ((IndexScan *) plan)->indexqual,
 
1811
                                                          &context);
 
1812
 
 
1813
                        /*
 
1814
                         * we need not look at indexqualorig, since it will have the same
 
1815
                         * param references as indexqual.
 
1816
                         */
 
1817
                        break;
 
1818
 
 
1819
                case T_BitmapIndexScan:
 
1820
                        finalize_primnode((Node *) ((BitmapIndexScan *) plan)->indexqual,
 
1821
                                                          &context);
 
1822
 
 
1823
                        /*
 
1824
                         * we need not look at indexqualorig, since it will have the same
 
1825
                         * param references as indexqual.
 
1826
                         */
 
1827
                        break;
 
1828
 
 
1829
                case T_BitmapHeapScan:
 
1830
                        finalize_primnode((Node *) ((BitmapHeapScan *) plan)->bitmapqualorig,
 
1831
                                                          &context);
 
1832
                        break;
 
1833
 
 
1834
                case T_TidScan:
 
1835
                        finalize_primnode((Node *) ((TidScan *) plan)->tidquals,
 
1836
                                                          &context);
 
1837
                        break;
 
1838
 
 
1839
                case T_SubqueryScan:
 
1840
 
 
1841
                        /*
 
1842
                         * In a SubqueryScan, SS_finalize_plan has already been run on the
 
1843
                         * subplan by the inner invocation of subquery_planner, so there's
 
1844
                         * no need to do it again.      Instead, just pull out the subplan's
 
1845
                         * extParams list, which represents the params it needs from my
 
1846
                         * level and higher levels.
 
1847
                         */
 
1848
                        context.paramids = bms_add_members(context.paramids,
 
1849
                                                                 ((SubqueryScan *) plan)->subplan->extParam);
 
1850
                        break;
 
1851
 
 
1852
                case T_FunctionScan:
 
1853
                        finalize_primnode(((FunctionScan *) plan)->funcexpr,
 
1854
                                                          &context);
 
1855
                        break;
 
1856
 
 
1857
                case T_ValuesScan:
 
1858
                        finalize_primnode((Node *) ((ValuesScan *) plan)->values_lists,
 
1859
                                                          &context);
 
1860
                        break;
 
1861
 
 
1862
                case T_CteScan:
 
1863
                        context.paramids =
 
1864
                                bms_add_member(context.paramids,
 
1865
                                                           ((CteScan *) plan)->cteParam);
 
1866
                        break;
 
1867
 
 
1868
                case T_WorkTableScan:
 
1869
                        context.paramids =
 
1870
                                bms_add_member(context.paramids,
 
1871
                                                           ((WorkTableScan *) plan)->wtParam);
 
1872
                        break;
 
1873
 
 
1874
                case T_Append:
 
1875
                        {
 
1876
                                ListCell   *l;
 
1877
 
 
1878
                                foreach(l, ((Append *) plan)->appendplans)
 
1879
                                {
 
1880
                                        context.paramids =
 
1881
                                                bms_add_members(context.paramids,
 
1882
                                                                                finalize_plan(root,
 
1883
                                                                                                          (Plan *) lfirst(l),
 
1884
                                                                                                          valid_params));
 
1885
                                }
 
1886
                        }
 
1887
                        break;
 
1888
 
 
1889
                case T_BitmapAnd:
 
1890
                        {
 
1891
                                ListCell   *l;
 
1892
 
 
1893
                                foreach(l, ((BitmapAnd *) plan)->bitmapplans)
 
1894
                                {
 
1895
                                        context.paramids =
 
1896
                                                bms_add_members(context.paramids,
 
1897
                                                                                finalize_plan(root,
 
1898
                                                                                                          (Plan *) lfirst(l),
 
1899
                                                                                                          valid_params));
 
1900
                                }
 
1901
                        }
 
1902
                        break;
 
1903
 
 
1904
                case T_BitmapOr:
 
1905
                        {
 
1906
                                ListCell   *l;
 
1907
 
 
1908
                                foreach(l, ((BitmapOr *) plan)->bitmapplans)
 
1909
                                {
 
1910
                                        context.paramids =
 
1911
                                                bms_add_members(context.paramids,
 
1912
                                                                                finalize_plan(root,
 
1913
                                                                                                          (Plan *) lfirst(l),
 
1914
                                                                                                          valid_params));
 
1915
                                }
 
1916
                        }
 
1917
                        break;
 
1918
 
 
1919
                case T_NestLoop:
 
1920
                        finalize_primnode((Node *) ((Join *) plan)->joinqual,
 
1921
                                                          &context);
 
1922
                        break;
 
1923
 
 
1924
                case T_MergeJoin:
 
1925
                        finalize_primnode((Node *) ((Join *) plan)->joinqual,
 
1926
                                                          &context);
 
1927
                        finalize_primnode((Node *) ((MergeJoin *) plan)->mergeclauses,
 
1928
                                                          &context);
 
1929
                        break;
 
1930
 
 
1931
                case T_HashJoin:
 
1932
                        finalize_primnode((Node *) ((Join *) plan)->joinqual,
 
1933
                                                          &context);
 
1934
                        finalize_primnode((Node *) ((HashJoin *) plan)->hashclauses,
 
1935
                                                          &context);
 
1936
                        break;
 
1937
 
 
1938
                case T_Limit:
 
1939
                        finalize_primnode(((Limit *) plan)->limitOffset,
 
1940
                                                          &context);
 
1941
                        finalize_primnode(((Limit *) plan)->limitCount,
 
1942
                                                          &context);
 
1943
                        break;
 
1944
 
 
1945
                case T_RecursiveUnion:
 
1946
                case T_Hash:
 
1947
                case T_Agg:
 
1948
                case T_WindowAgg:
 
1949
                case T_SeqScan:
 
1950
                case T_Material:
 
1951
                case T_Sort:
 
1952
                case T_Unique:
 
1953
                case T_SetOp:
 
1954
                case T_Group:
 
1955
                        break;
 
1956
 
 
1957
                default:
 
1958
                        elog(ERROR, "unrecognized node type: %d",
 
1959
                                 (int) nodeTag(plan));
 
1960
        }
 
1961
 
 
1962
        /* Process left and right child plans, if any */
 
1963
        context.paramids = bms_add_members(context.paramids,
 
1964
                                                                           finalize_plan(root,
 
1965
                                                                                                         plan->lefttree,
 
1966
                                                                                                         valid_params));
 
1967
 
 
1968
        context.paramids = bms_add_members(context.paramids,
 
1969
                                                                           finalize_plan(root,
 
1970
                                                                                                         plan->righttree,
 
1971
                                                                                                         valid_params));
 
1972
 
 
1973
        /*
 
1974
         * RecursiveUnion *generates* its worktable param, so don't bubble that up
 
1975
         */
 
1976
        if (IsA(plan, RecursiveUnion))
 
1977
        {
 
1978
                context.paramids = bms_del_member(context.paramids,
 
1979
                                                                                  ((RecursiveUnion *) plan)->wtParam);
 
1980
        }
 
1981
 
 
1982
        /* Now we have all the paramids */
 
1983
 
 
1984
        if (!bms_is_subset(context.paramids, valid_params))
 
1985
                elog(ERROR, "plan should not reference subplan's variable");
 
1986
 
 
1987
        /*
 
1988
         * Note: by definition, extParam and allParam should have the same value
 
1989
         * in any plan node that doesn't have child initPlans.  We set them
 
1990
         * equal here, and later SS_finalize_plan will update them properly
 
1991
         * in node(s) that it attaches initPlans to.
 
1992
         *
 
1993
         * For speed at execution time, make sure extParam/allParam are actually
 
1994
         * NULL if they are empty sets.
 
1995
         */
 
1996
        if (bms_is_empty(context.paramids))
 
1997
        {
 
1998
                plan->extParam = NULL;
 
1999
                plan->allParam = NULL;
 
2000
        }
 
2001
        else
 
2002
        {
 
2003
                plan->extParam = context.paramids;
 
2004
                plan->allParam = bms_copy(context.paramids);
 
2005
        }
 
2006
 
 
2007
        return plan->allParam;
 
2008
}
 
2009
 
 
2010
/*
 
2011
 * finalize_primnode: add IDs of all PARAM_EXEC params appearing in the given
 
2012
 * expression tree to the result set.
 
2013
 */
 
2014
static bool
 
2015
finalize_primnode(Node *node, finalize_primnode_context *context)
 
2016
{
 
2017
        if (node == NULL)
 
2018
                return false;
 
2019
        if (IsA(node, Param))
 
2020
        {
 
2021
                if (((Param *) node)->paramkind == PARAM_EXEC)
 
2022
                {
 
2023
                        int                     paramid = ((Param *) node)->paramid;
 
2024
 
 
2025
                        context->paramids = bms_add_member(context->paramids, paramid);
 
2026
                }
 
2027
                return false;                   /* no more to do here */
 
2028
        }
 
2029
        if (IsA(node, SubPlan))
 
2030
        {
 
2031
                SubPlan    *subplan = (SubPlan *) node;
 
2032
                Plan       *plan = planner_subplan_get_plan(context->root, subplan);
 
2033
                ListCell   *lc;
 
2034
                Bitmapset  *subparamids;
 
2035
 
 
2036
                /* Recurse into the testexpr, but not into the Plan */
 
2037
                finalize_primnode(subplan->testexpr, context);
 
2038
 
 
2039
                /*
 
2040
                 * Remove any param IDs of output parameters of the subplan that were
 
2041
                 * referenced in the testexpr.  These are not interesting for
 
2042
                 * parameter change signaling since we always re-evaluate the subplan.
 
2043
                 * Note that this wouldn't work too well if there might be uses of the
 
2044
                 * same param IDs elsewhere in the plan, but that can't happen because
 
2045
                 * generate_new_param never tries to merge params.
 
2046
                 */
 
2047
                foreach(lc, subplan->paramIds)
 
2048
                {
 
2049
                        context->paramids = bms_del_member(context->paramids,
 
2050
                                                                                           lfirst_int(lc));
 
2051
                }
 
2052
 
 
2053
                /* Also examine args list */
 
2054
                finalize_primnode((Node *) subplan->args, context);
 
2055
 
 
2056
                /*
 
2057
                 * Add params needed by the subplan to paramids, but excluding those
 
2058
                 * we will pass down to it.
 
2059
                 */
 
2060
                subparamids = bms_copy(plan->extParam);
 
2061
                foreach(lc, subplan->parParam)
 
2062
                {
 
2063
                        subparamids = bms_del_member(subparamids, lfirst_int(lc));
 
2064
                }
 
2065
                context->paramids = bms_join(context->paramids, subparamids);
 
2066
 
 
2067
                return false;                   /* no more to do here */
 
2068
        }
 
2069
        return expression_tree_walker(node, finalize_primnode,
 
2070
                                                                  (void *) context);
 
2071
}
 
2072
 
 
2073
/*
 
2074
 * SS_make_initplan_from_plan - given a plan tree, make it an InitPlan
 
2075
 *
 
2076
 * The plan is expected to return a scalar value of the indicated type.
 
2077
 * We build an EXPR_SUBLINK SubPlan node and put it into the initplan
 
2078
 * list for the current query level.  A Param that represents the initplan's
 
2079
 * output is returned.
 
2080
 *
 
2081
 * We assume the plan hasn't been put through SS_finalize_plan.
 
2082
 */
 
2083
Param *
 
2084
SS_make_initplan_from_plan(PlannerInfo *root, Plan *plan,
 
2085
                                                   Oid resulttype, int32 resulttypmod)
 
2086
{
 
2087
        SubPlan    *node;
 
2088
        Param      *prm;
 
2089
 
 
2090
        /*
 
2091
         * We must run SS_finalize_plan(), since that's normally done before a
 
2092
         * subplan gets put into the initplan list.  Tell it not to attach any
 
2093
         * pre-existing initplans to this one, since they are siblings not
 
2094
         * children of this initplan.  (This is something else that could perhaps
 
2095
         * be cleaner if we did extParam/allParam processing in setrefs.c instead
 
2096
         * of here?  See notes for materialize_finished_plan.)
 
2097
         */
 
2098
 
 
2099
        /*
 
2100
         * Build extParam/allParam sets for plan nodes.
 
2101
         */
 
2102
        SS_finalize_plan(root, plan, false);
 
2103
 
 
2104
        /*
 
2105
         * Add the subplan and its rtable to the global lists.
 
2106
         */
 
2107
        root->glob->subplans = lappend(root->glob->subplans,
 
2108
                                                                   plan);
 
2109
        root->glob->subrtables = lappend(root->glob->subrtables,
 
2110
                                                                         root->parse->rtable);
 
2111
 
 
2112
        /*
 
2113
         * Create a SubPlan node and add it to the outer list of InitPlans.
 
2114
         * Note it has to appear after any other InitPlans it might depend on
 
2115
         * (see comments in ExecReScan).
 
2116
         */
 
2117
        node = makeNode(SubPlan);
 
2118
        node->subLinkType = EXPR_SUBLINK;
 
2119
        get_first_col_type(plan, &node->firstColType, &node->firstColTypmod);
 
2120
        node->plan_id = list_length(root->glob->subplans);
 
2121
 
 
2122
        root->init_plans = lappend(root->init_plans, node);
 
2123
 
 
2124
        /*
 
2125
         * The node can't have any inputs (since it's an initplan), so the
 
2126
         * parParam and args lists remain empty.
 
2127
         */
 
2128
 
 
2129
        cost_subplan(root, node, plan);
 
2130
 
 
2131
        /*
 
2132
         * Make a Param that will be the subplan's output.
 
2133
         */
 
2134
        prm = generate_new_param(root, resulttype, resulttypmod);
 
2135
        node->setParam = list_make1_int(prm->paramid);
 
2136
 
 
2137
        return prm;
 
2138
}