|
19 | 19 | #include <limits.h>
|
20 | 20 | #include <math.h>
|
21 | 21 |
|
22 |
| -#include "access/stratnum.h" |
23 | 22 | #include "access/sysattr.h"
|
24 | 23 | #include "catalog/pg_class.h"
|
25 | 24 | #include "foreign/fdwapi.h"
|
|
29 | 28 | #include "nodes/nodeFuncs.h"
|
30 | 29 | #include "optimizer/clauses.h"
|
31 | 30 | #include "optimizer/cost.h"
|
| 31 | +#include "optimizer/paramassign.h" |
32 | 32 | #include "optimizer/paths.h"
|
33 | 33 | #include "optimizer/placeholder.h"
|
34 | 34 | #include "optimizer/plancat.h"
|
35 | 35 | #include "optimizer/planmain.h"
|
36 |
| -#include "optimizer/planner.h" |
37 | 36 | #include "optimizer/predtest.h"
|
38 | 37 | #include "optimizer/restrictinfo.h"
|
39 | 38 | #include "optimizer/subselect.h"
|
@@ -152,8 +151,6 @@ static MergeJoin *create_mergejoin_plan(PlannerInfo *root, MergePath *best_path)
|
152 | 151 | static HashJoin *create_hashjoin_plan(PlannerInfo *root, HashPath *best_path);
|
153 | 152 | static Node *replace_nestloop_params(PlannerInfo *root, Node *expr);
|
154 | 153 | static Node *replace_nestloop_params_mutator(Node *node, PlannerInfo *root);
|
155 |
| -static void process_subquery_nestloop_params(PlannerInfo *root, |
156 |
| - List *subplan_params); |
157 | 154 | static List *fix_indexqual_references(PlannerInfo *root, IndexPath *index_path);
|
158 | 155 | static List *fix_indexorderby_references(PlannerInfo *root, IndexPath *index_path);
|
159 | 156 | static Node *fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol);
|
@@ -312,7 +309,7 @@ create_plan(PlannerInfo *root, Path *best_path)
|
312 | 309 | /* plan_params should not be in use in current query level */
|
313 | 310 | Assert(root->plan_params == NIL);
|
314 | 311 |
|
315 |
| - /* Initialize this module's private workspace in PlannerInfo */ |
| 312 | + /* Initialize this module's workspace in PlannerInfo */ |
316 | 313 | root->curOuterRels = NULL;
|
317 | 314 | root->curOuterParams = NIL;
|
318 | 315 |
|
@@ -1531,7 +1528,7 @@ create_gather_plan(PlannerInfo *root, GatherPath *best_path)
|
1531 | 1528 | gather_plan = make_gather(tlist,
|
1532 | 1529 | NIL,
|
1533 | 1530 | best_path->num_workers,
|
1534 |
| - SS_assign_special_param(root), |
| 1531 | + assign_special_exec_param(root), |
1535 | 1532 | best_path->single_copy,
|
1536 | 1533 | subplan);
|
1537 | 1534 |
|
@@ -1567,7 +1564,7 @@ create_gather_merge_plan(PlannerInfo *root, GatherMergePath *best_path)
|
1567 | 1564 | copy_generic_path_info(&gm_plan->plan, &best_path->path);
|
1568 | 1565 |
|
1569 | 1566 | /* Assign the rescan Param. */
|
1570 |
| - gm_plan->rescan_param = SS_assign_special_param(root); |
| 1567 | + gm_plan->rescan_param = assign_special_exec_param(root); |
1571 | 1568 |
|
1572 | 1569 | /* Gather Merge is pointless with no pathkeys; use Gather instead. */
|
1573 | 1570 | Assert(pathkeys != NIL);
|
@@ -3706,9 +3703,6 @@ create_nestloop_plan(PlannerInfo *root,
|
3706 | 3703 | Relids outerrelids;
|
3707 | 3704 | List *nestParams;
|
3708 | 3705 | Relids saveOuterRels = root->curOuterRels;
|
3709 |
| - ListCell *cell; |
3710 |
| - ListCell *prev; |
3711 |
| - ListCell *next; |
3712 | 3706 |
|
3713 | 3707 | /* NestLoop can project, so no need to be picky about child tlists */
|
3714 | 3708 | outer_plan = create_plan_recurse(root, best_path->outerjoinpath, 0);
|
@@ -3752,38 +3746,10 @@ create_nestloop_plan(PlannerInfo *root,
|
3752 | 3746 |
|
3753 | 3747 | /*
|
3754 | 3748 | * Identify any nestloop parameters that should be supplied by this join
|
3755 |
| - * node, and move them from root->curOuterParams to the nestParams list. |
| 3749 | + * node, and remove them from root->curOuterParams. |
3756 | 3750 | */
|
3757 | 3751 | outerrelids = best_path->outerjoinpath->parent->relids;
|
3758 |
| - nestParams = NIL; |
3759 |
| - prev = NULL; |
3760 |
| - for (cell = list_head(root->curOuterParams); cell; cell = next) |
3761 |
| - { |
3762 |
| - NestLoopParam *nlp = (NestLoopParam *) lfirst(cell); |
3763 |
| - |
3764 |
| - next = lnext(cell); |
3765 |
| - if (IsA(nlp->paramval, Var) && |
3766 |
| - bms_is_member(nlp->paramval->varno, outerrelids)) |
3767 |
| - { |
3768 |
| - root->curOuterParams = list_delete_cell(root->curOuterParams, |
3769 |
| - cell, prev); |
3770 |
| - nestParams = lappend(nestParams, nlp); |
3771 |
| - } |
3772 |
| - else if (IsA(nlp->paramval, PlaceHolderVar) && |
3773 |
| - bms_overlap(((PlaceHolderVar *) nlp->paramval)->phrels, |
3774 |
| - outerrelids) && |
3775 |
| - bms_is_subset(find_placeholder_info(root, |
3776 |
| - (PlaceHolderVar *) nlp->paramval, |
3777 |
| - false)->ph_eval_at, |
3778 |
| - outerrelids)) |
3779 |
| - { |
3780 |
| - root->curOuterParams = list_delete_cell(root->curOuterParams, |
3781 |
| - cell, prev); |
3782 |
| - nestParams = lappend(nestParams, nlp); |
3783 |
| - } |
3784 |
| - else |
3785 |
| - prev = cell; |
3786 |
| - } |
| 3752 | + nestParams = identify_current_nestloop_params(root, outerrelids); |
3787 | 3753 |
|
3788 | 3754 | join_plan = make_nestloop(tlist,
|
3789 | 3755 | joinclauses,
|
@@ -4283,42 +4249,18 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root)
|
4283 | 4249 | if (IsA(node, Var))
|
4284 | 4250 | {
|
4285 | 4251 | Var *var = (Var *) node;
|
4286 |
| - Param *param; |
4287 |
| - NestLoopParam *nlp; |
4288 |
| - ListCell *lc; |
4289 | 4252 |
|
4290 | 4253 | /* Upper-level Vars should be long gone at this point */
|
4291 | 4254 | Assert(var->varlevelsup == 0);
|
4292 | 4255 | /* If not to be replaced, we can just return the Var unmodified */
|
4293 | 4256 | if (!bms_is_member(var->varno, root->curOuterRels))
|
4294 | 4257 | return node;
|
4295 |
| - /* Create a Param representing the Var */ |
4296 |
| - param = assign_nestloop_param_var(root, var); |
4297 |
| - /* Is this param already listed in root->curOuterParams? */ |
4298 |
| - foreach(lc, root->curOuterParams) |
4299 |
| - { |
4300 |
| - nlp = (NestLoopParam *) lfirst(lc); |
4301 |
| - if (nlp->paramno == param->paramid) |
4302 |
| - { |
4303 |
| - Assert(equal(var, nlp->paramval)); |
4304 |
| - /* Present, so we can just return the Param */ |
4305 |
| - return (Node *) param; |
4306 |
| - } |
4307 |
| - } |
4308 |
| - /* No, so add it */ |
4309 |
| - nlp = makeNode(NestLoopParam); |
4310 |
| - nlp->paramno = param->paramid; |
4311 |
| - nlp->paramval = var; |
4312 |
| - root->curOuterParams = lappend(root->curOuterParams, nlp); |
4313 |
| - /* And return the replacement Param */ |
4314 |
| - return (Node *) param; |
| 4258 | + /* Replace the Var with a nestloop Param */ |
| 4259 | + return (Node *) replace_nestloop_param_var(root, var); |
4315 | 4260 | }
|
4316 | 4261 | if (IsA(node, PlaceHolderVar))
|
4317 | 4262 | {
|
4318 | 4263 | PlaceHolderVar *phv = (PlaceHolderVar *) node;
|
4319 |
| - Param *param; |
4320 |
| - NestLoopParam *nlp; |
4321 |
| - ListCell *lc; |
4322 | 4264 |
|
4323 | 4265 | /* Upper-level PlaceHolderVars should be long gone at this point */
|
4324 | 4266 | Assert(phv->phlevelsup == 0);
|
@@ -4355,118 +4297,14 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root)
|
4355 | 4297 | root);
|
4356 | 4298 | return (Node *) newphv;
|
4357 | 4299 | }
|
4358 |
| - /* Create a Param representing the PlaceHolderVar */ |
4359 |
| - param = assign_nestloop_param_placeholdervar(root, phv); |
4360 |
| - /* Is this param already listed in root->curOuterParams? */ |
4361 |
| - foreach(lc, root->curOuterParams) |
4362 |
| - { |
4363 |
| - nlp = (NestLoopParam *) lfirst(lc); |
4364 |
| - if (nlp->paramno == param->paramid) |
4365 |
| - { |
4366 |
| - Assert(equal(phv, nlp->paramval)); |
4367 |
| - /* Present, so we can just return the Param */ |
4368 |
| - return (Node *) param; |
4369 |
| - } |
4370 |
| - } |
4371 |
| - /* No, so add it */ |
4372 |
| - nlp = makeNode(NestLoopParam); |
4373 |
| - nlp->paramno = param->paramid; |
4374 |
| - nlp->paramval = (Var *) phv; |
4375 |
| - root->curOuterParams = lappend(root->curOuterParams, nlp); |
4376 |
| - /* And return the replacement Param */ |
4377 |
| - return (Node *) param; |
| 4300 | + /* Replace the PlaceHolderVar with a nestloop Param */ |
| 4301 | + return (Node *) replace_nestloop_param_placeholdervar(root, phv); |
4378 | 4302 | }
|
4379 | 4303 | return expression_tree_mutator(node,
|
4380 | 4304 | replace_nestloop_params_mutator,
|
4381 | 4305 | (void *) root);
|
4382 | 4306 | }
|
4383 | 4307 |
|
4384 |
| -/* |
4385 |
| - * process_subquery_nestloop_params |
4386 |
| - * Handle params of a parameterized subquery that need to be fed |
4387 |
| - * from an outer nestloop. |
4388 |
| - * |
4389 |
| - * Currently, that would be *all* params that a subquery in FROM has demanded |
4390 |
| - * from the current query level, since they must be LATERAL references. |
4391 |
| - * |
4392 |
| - * The subplan's references to the outer variables are already represented |
4393 |
| - * as PARAM_EXEC Params, so we need not modify the subplan here. What we |
4394 |
| - * do need to do is add entries to root->curOuterParams to signal the parent |
4395 |
| - * nestloop plan node that it must provide these values. |
4396 |
| - */ |
4397 |
| -static void |
4398 |
| -process_subquery_nestloop_params(PlannerInfo *root, List *subplan_params) |
4399 |
| -{ |
4400 |
| - ListCell *ppl; |
4401 |
| - |
4402 |
| - foreach(ppl, subplan_params) |
4403 |
| - { |
4404 |
| - PlannerParamItem *pitem = (PlannerParamItem *) lfirst(ppl); |
4405 |
| - |
4406 |
| - if (IsA(pitem->item, Var)) |
4407 |
| - { |
4408 |
| - Var *var = (Var *) pitem->item; |
4409 |
| - NestLoopParam *nlp; |
4410 |
| - ListCell *lc; |
4411 |
| - |
4412 |
| - /* If not from a nestloop outer rel, complain */ |
4413 |
| - if (!bms_is_member(var->varno, root->curOuterRels)) |
4414 |
| - elog(ERROR, "non-LATERAL parameter required by subquery"); |
4415 |
| - /* Is this param already listed in root->curOuterParams? */ |
4416 |
| - foreach(lc, root->curOuterParams) |
4417 |
| - { |
4418 |
| - nlp = (NestLoopParam *) lfirst(lc); |
4419 |
| - if (nlp->paramno == pitem->paramId) |
4420 |
| - { |
4421 |
| - Assert(equal(var, nlp->paramval)); |
4422 |
| - /* Present, so nothing to do */ |
4423 |
| - break; |
4424 |
| - } |
4425 |
| - } |
4426 |
| - if (lc == NULL) |
4427 |
| - { |
4428 |
| - /* No, so add it */ |
4429 |
| - nlp = makeNode(NestLoopParam); |
4430 |
| - nlp->paramno = pitem->paramId; |
4431 |
| - nlp->paramval = copyObject(var); |
4432 |
| - root->curOuterParams = lappend(root->curOuterParams, nlp); |
4433 |
| - } |
4434 |
| - } |
4435 |
| - else if (IsA(pitem->item, PlaceHolderVar)) |
4436 |
| - { |
4437 |
| - PlaceHolderVar *phv = (PlaceHolderVar *) pitem->item; |
4438 |
| - NestLoopParam *nlp; |
4439 |
| - ListCell *lc; |
4440 |
| - |
4441 |
| - /* If not from a nestloop outer rel, complain */ |
4442 |
| - if (!bms_is_subset(find_placeholder_info(root, phv, false)->ph_eval_at, |
4443 |
| - root->curOuterRels)) |
4444 |
| - elog(ERROR, "non-LATERAL parameter required by subquery"); |
4445 |
| - /* Is this param already listed in root->curOuterParams? */ |
4446 |
| - foreach(lc, root->curOuterParams) |
4447 |
| - { |
4448 |
| - nlp = (NestLoopParam *) lfirst(lc); |
4449 |
| - if (nlp->paramno == pitem->paramId) |
4450 |
| - { |
4451 |
| - Assert(equal(phv, nlp->paramval)); |
4452 |
| - /* Present, so nothing to do */ |
4453 |
| - break; |
4454 |
| - } |
4455 |
| - } |
4456 |
| - if (lc == NULL) |
4457 |
| - { |
4458 |
| - /* No, so add it */ |
4459 |
| - nlp = makeNode(NestLoopParam); |
4460 |
| - nlp->paramno = pitem->paramId; |
4461 |
| - nlp->paramval = (Var *) copyObject(phv); |
4462 |
| - root->curOuterParams = lappend(root->curOuterParams, nlp); |
4463 |
| - } |
4464 |
| - } |
4465 |
| - else |
4466 |
| - elog(ERROR, "unexpected type of subquery parameter"); |
4467 |
| - } |
4468 |
| -} |
4469 |
| - |
4470 | 4308 | /*
|
4471 | 4309 | * fix_indexqual_references
|
4472 | 4310 | * Adjust indexqual clauses to the form the executor's indexqual
|
|
0 commit comments