|
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