|
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" |
@@ -151,8 +150,6 @@ static MergeJoin *create_mergejoin_plan(PlannerInfo *root, MergePath *best_path) |
151 | 150 | static HashJoin *create_hashjoin_plan(PlannerInfo *root, HashPath *best_path); |
152 | 151 | static Node *replace_nestloop_params(PlannerInfo *root, Node *expr); |
153 | 152 | static Node *replace_nestloop_params_mutator(Node *node, PlannerInfo *root); |
154 | | -static void process_subquery_nestloop_params(PlannerInfo *root, |
155 | | - List *subplan_params); |
156 | 153 | static List *fix_indexqual_references(PlannerInfo *root, IndexPath *index_path); |
157 | 154 | static List *fix_indexorderby_references(PlannerInfo *root, IndexPath *index_path); |
158 | 155 | static Node *fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol); |
@@ -310,7 +307,7 @@ create_plan(PlannerInfo *root, Path *best_path) |
310 | 307 | /* plan_params should not be in use in current query level */ |
311 | 308 | Assert(root->plan_params == NIL); |
312 | 309 |
|
313 | | - /* Initialize this module's private workspace in PlannerInfo */ |
| 310 | + /* Initialize this module's workspace in PlannerInfo */ |
314 | 311 | root->curOuterRels = NULL; |
315 | 312 | root->curOuterParams = NIL; |
316 | 313 |
|
@@ -1554,7 +1551,7 @@ create_gather_plan(PlannerInfo *root, GatherPath *best_path) |
1554 | 1551 | gather_plan = make_gather(tlist, |
1555 | 1552 | NIL, |
1556 | 1553 | best_path->num_workers, |
1557 | | - SS_assign_special_param(root), |
| 1554 | + assign_special_exec_param(root), |
1558 | 1555 | best_path->single_copy, |
1559 | 1556 | subplan); |
1560 | 1557 |
|
@@ -1590,7 +1587,7 @@ create_gather_merge_plan(PlannerInfo *root, GatherMergePath *best_path) |
1590 | 1587 | copy_generic_path_info(&gm_plan->plan, &best_path->path); |
1591 | 1588 |
|
1592 | 1589 | /* Assign the rescan Param. */ |
1593 | | - gm_plan->rescan_param = SS_assign_special_param(root); |
| 1590 | + gm_plan->rescan_param = assign_special_exec_param(root); |
1594 | 1591 |
|
1595 | 1592 | /* Gather Merge is pointless with no pathkeys; use Gather instead. */ |
1596 | 1593 | Assert(pathkeys != NIL); |
@@ -3774,9 +3771,6 @@ create_nestloop_plan(PlannerInfo *root, |
3774 | 3771 | Relids outerrelids; |
3775 | 3772 | List *nestParams; |
3776 | 3773 | Relids saveOuterRels = root->curOuterRels; |
3777 | | - ListCell *cell; |
3778 | | - ListCell *prev; |
3779 | | - ListCell *next; |
3780 | 3774 |
|
3781 | 3775 | /* NestLoop can project, so no need to be picky about child tlists */ |
3782 | 3776 | outer_plan = create_plan_recurse(root, best_path->outerjoinpath, 0); |
@@ -3820,38 +3814,10 @@ create_nestloop_plan(PlannerInfo *root, |
3820 | 3814 |
|
3821 | 3815 | /* |
3822 | 3816 | * Identify any nestloop parameters that should be supplied by this join |
3823 | | - * node, and move them from root->curOuterParams to the nestParams list. |
| 3817 | + * node, and remove them from root->curOuterParams. |
3824 | 3818 | */ |
3825 | 3819 | outerrelids = best_path->outerjoinpath->parent->relids; |
3826 | | - nestParams = NIL; |
3827 | | - prev = NULL; |
3828 | | - for (cell = list_head(root->curOuterParams); cell; cell = next) |
3829 | | - { |
3830 | | - NestLoopParam *nlp = (NestLoopParam *) lfirst(cell); |
3831 | | - |
3832 | | - next = lnext(cell); |
3833 | | - if (IsA(nlp->paramval, Var) && |
3834 | | - bms_is_member(nlp->paramval->varno, outerrelids)) |
3835 | | - { |
3836 | | - root->curOuterParams = list_delete_cell(root->curOuterParams, |
3837 | | - cell, prev); |
3838 | | - nestParams = lappend(nestParams, nlp); |
3839 | | - } |
3840 | | - else if (IsA(nlp->paramval, PlaceHolderVar) && |
3841 | | - bms_overlap(((PlaceHolderVar *) nlp->paramval)->phrels, |
3842 | | - outerrelids) && |
3843 | | - bms_is_subset(find_placeholder_info(root, |
3844 | | - (PlaceHolderVar *) nlp->paramval, |
3845 | | - false)->ph_eval_at, |
3846 | | - outerrelids)) |
3847 | | - { |
3848 | | - root->curOuterParams = list_delete_cell(root->curOuterParams, |
3849 | | - cell, prev); |
3850 | | - nestParams = lappend(nestParams, nlp); |
3851 | | - } |
3852 | | - else |
3853 | | - prev = cell; |
3854 | | - } |
| 3820 | + nestParams = identify_current_nestloop_params(root, outerrelids); |
3855 | 3821 |
|
3856 | 3822 | join_plan = make_nestloop(tlist, |
3857 | 3823 | joinclauses, |
@@ -4351,42 +4317,18 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root) |
4351 | 4317 | if (IsA(node, Var)) |
4352 | 4318 | { |
4353 | 4319 | Var *var = (Var *) node; |
4354 | | - Param *param; |
4355 | | - NestLoopParam *nlp; |
4356 | | - ListCell *lc; |
4357 | 4320 |
|
4358 | 4321 | /* Upper-level Vars should be long gone at this point */ |
4359 | 4322 | Assert(var->varlevelsup == 0); |
4360 | 4323 | /* If not to be replaced, we can just return the Var unmodified */ |
4361 | 4324 | if (!bms_is_member(var->varno, root->curOuterRels)) |
4362 | 4325 | return node; |
4363 | | - /* Create a Param representing the Var */ |
4364 | | - param = assign_nestloop_param_var(root, var); |
4365 | | - /* Is this param already listed in root->curOuterParams? */ |
4366 | | - foreach(lc, root->curOuterParams) |
4367 | | - { |
4368 | | - nlp = (NestLoopParam *) lfirst(lc); |
4369 | | - if (nlp->paramno == param->paramid) |
4370 | | - { |
4371 | | - Assert(equal(var, nlp->paramval)); |
4372 | | - /* Present, so we can just return the Param */ |
4373 | | - return (Node *) param; |
4374 | | - } |
4375 | | - } |
4376 | | - /* No, so add it */ |
4377 | | - nlp = makeNode(NestLoopParam); |
4378 | | - nlp->paramno = param->paramid; |
4379 | | - nlp->paramval = var; |
4380 | | - root->curOuterParams = lappend(root->curOuterParams, nlp); |
4381 | | - /* And return the replacement Param */ |
4382 | | - return (Node *) param; |
| 4326 | + /* Replace the Var with a nestloop Param */ |
| 4327 | + return (Node *) replace_nestloop_param_var(root, var); |
4383 | 4328 | } |
4384 | 4329 | if (IsA(node, PlaceHolderVar)) |
4385 | 4330 | { |
4386 | 4331 | PlaceHolderVar *phv = (PlaceHolderVar *) node; |
4387 | | - Param *param; |
4388 | | - NestLoopParam *nlp; |
4389 | | - ListCell *lc; |
4390 | 4332 |
|
4391 | 4333 | /* Upper-level PlaceHolderVars should be long gone at this point */ |
4392 | 4334 | Assert(phv->phlevelsup == 0); |
@@ -4423,118 +4365,14 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root) |
4423 | 4365 | root); |
4424 | 4366 | return (Node *) newphv; |
4425 | 4367 | } |
4426 | | - /* Create a Param representing the PlaceHolderVar */ |
4427 | | - param = assign_nestloop_param_placeholdervar(root, phv); |
4428 | | - /* Is this param already listed in root->curOuterParams? */ |
4429 | | - foreach(lc, root->curOuterParams) |
4430 | | - { |
4431 | | - nlp = (NestLoopParam *) lfirst(lc); |
4432 | | - if (nlp->paramno == param->paramid) |
4433 | | - { |
4434 | | - Assert(equal(phv, nlp->paramval)); |
4435 | | - /* Present, so we can just return the Param */ |
4436 | | - return (Node *) param; |
4437 | | - } |
4438 | | - } |
4439 | | - /* No, so add it */ |
4440 | | - nlp = makeNode(NestLoopParam); |
4441 | | - nlp->paramno = param->paramid; |
4442 | | - nlp->paramval = (Var *) phv; |
4443 | | - root->curOuterParams = lappend(root->curOuterParams, nlp); |
4444 | | - /* And return the replacement Param */ |
4445 | | - return (Node *) param; |
| 4368 | + /* Replace the PlaceHolderVar with a nestloop Param */ |
| 4369 | + return (Node *) replace_nestloop_param_placeholdervar(root, phv); |
4446 | 4370 | } |
4447 | 4371 | return expression_tree_mutator(node, |
4448 | 4372 | replace_nestloop_params_mutator, |
4449 | 4373 | (void *) root); |
4450 | 4374 | } |
4451 | 4375 |
|
4452 | | -/* |
4453 | | - * process_subquery_nestloop_params |
4454 | | - * Handle params of a parameterized subquery that need to be fed |
4455 | | - * from an outer nestloop. |
4456 | | - * |
4457 | | - * Currently, that would be *all* params that a subquery in FROM has demanded |
4458 | | - * from the current query level, since they must be LATERAL references. |
4459 | | - * |
4460 | | - * The subplan's references to the outer variables are already represented |
4461 | | - * as PARAM_EXEC Params, so we need not modify the subplan here. What we |
4462 | | - * do need to do is add entries to root->curOuterParams to signal the parent |
4463 | | - * nestloop plan node that it must provide these values. |
4464 | | - */ |
4465 | | -static void |
4466 | | -process_subquery_nestloop_params(PlannerInfo *root, List *subplan_params) |
4467 | | -{ |
4468 | | - ListCell *ppl; |
4469 | | - |
4470 | | - foreach(ppl, subplan_params) |
4471 | | - { |
4472 | | - PlannerParamItem *pitem = (PlannerParamItem *) lfirst(ppl); |
4473 | | - |
4474 | | - if (IsA(pitem->item, Var)) |
4475 | | - { |
4476 | | - Var *var = (Var *) pitem->item; |
4477 | | - NestLoopParam *nlp; |
4478 | | - ListCell *lc; |
4479 | | - |
4480 | | - /* If not from a nestloop outer rel, complain */ |
4481 | | - if (!bms_is_member(var->varno, root->curOuterRels)) |
4482 | | - elog(ERROR, "non-LATERAL parameter required by subquery"); |
4483 | | - /* Is this param already listed in root->curOuterParams? */ |
4484 | | - foreach(lc, root->curOuterParams) |
4485 | | - { |
4486 | | - nlp = (NestLoopParam *) lfirst(lc); |
4487 | | - if (nlp->paramno == pitem->paramId) |
4488 | | - { |
4489 | | - Assert(equal(var, nlp->paramval)); |
4490 | | - /* Present, so nothing to do */ |
4491 | | - break; |
4492 | | - } |
4493 | | - } |
4494 | | - if (lc == NULL) |
4495 | | - { |
4496 | | - /* No, so add it */ |
4497 | | - nlp = makeNode(NestLoopParam); |
4498 | | - nlp->paramno = pitem->paramId; |
4499 | | - nlp->paramval = copyObject(var); |
4500 | | - root->curOuterParams = lappend(root->curOuterParams, nlp); |
4501 | | - } |
4502 | | - } |
4503 | | - else if (IsA(pitem->item, PlaceHolderVar)) |
4504 | | - { |
4505 | | - PlaceHolderVar *phv = (PlaceHolderVar *) pitem->item; |
4506 | | - NestLoopParam *nlp; |
4507 | | - ListCell *lc; |
4508 | | - |
4509 | | - /* If not from a nestloop outer rel, complain */ |
4510 | | - if (!bms_is_subset(find_placeholder_info(root, phv, false)->ph_eval_at, |
4511 | | - root->curOuterRels)) |
4512 | | - elog(ERROR, "non-LATERAL parameter required by subquery"); |
4513 | | - /* Is this param already listed in root->curOuterParams? */ |
4514 | | - foreach(lc, root->curOuterParams) |
4515 | | - { |
4516 | | - nlp = (NestLoopParam *) lfirst(lc); |
4517 | | - if (nlp->paramno == pitem->paramId) |
4518 | | - { |
4519 | | - Assert(equal(phv, nlp->paramval)); |
4520 | | - /* Present, so nothing to do */ |
4521 | | - break; |
4522 | | - } |
4523 | | - } |
4524 | | - if (lc == NULL) |
4525 | | - { |
4526 | | - /* No, so add it */ |
4527 | | - nlp = makeNode(NestLoopParam); |
4528 | | - nlp->paramno = pitem->paramId; |
4529 | | - nlp->paramval = (Var *) copyObject(phv); |
4530 | | - root->curOuterParams = lappend(root->curOuterParams, nlp); |
4531 | | - } |
4532 | | - } |
4533 | | - else |
4534 | | - elog(ERROR, "unexpected type of subquery parameter"); |
4535 | | - } |
4536 | | -} |
4537 | | - |
4538 | 4376 | /* |
4539 | 4377 | * fix_indexqual_references |
4540 | 4378 | * Adjust indexqual clauses to the form the executor's indexqual |
|
0 commit comments