|
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"
|
@@ -153,8 +152,6 @@ static MergeJoin *create_mergejoin_plan(PlannerInfo *root, MergePath *best_path)
|
153 | 152 | static HashJoin *create_hashjoin_plan(PlannerInfo *root, HashPath *best_path);
|
154 | 153 | static Node *replace_nestloop_params(PlannerInfo *root, Node *expr);
|
155 | 154 | static Node *replace_nestloop_params_mutator(Node *node, PlannerInfo *root);
|
156 |
| -static void process_subquery_nestloop_params(PlannerInfo *root, |
157 |
| - List *subplan_params); |
158 | 155 | static List *fix_indexqual_references(PlannerInfo *root, IndexPath *index_path);
|
159 | 156 | static List *fix_indexorderby_references(PlannerInfo *root, IndexPath *index_path);
|
160 | 157 | static Node *fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol);
|
@@ -307,7 +304,7 @@ create_plan(PlannerInfo *root, Path *best_path)
|
307 | 304 | /* plan_params should not be in use in current query level */
|
308 | 305 | Assert(root->plan_params == NIL);
|
309 | 306 |
|
310 |
| - /* Initialize this module's private workspace in PlannerInfo */ |
| 307 | + /* Initialize this module's workspace in PlannerInfo */ |
311 | 308 | root->curOuterRels = NULL;
|
312 | 309 | root->curOuterParams = NIL;
|
313 | 310 |
|
@@ -1464,7 +1461,7 @@ create_gather_plan(PlannerInfo *root, GatherPath *best_path)
|
1464 | 1461 | gather_plan = make_gather(tlist,
|
1465 | 1462 | NIL,
|
1466 | 1463 | best_path->num_workers,
|
1467 |
| - SS_assign_special_param(root), |
| 1464 | + assign_special_exec_param(root), |
1468 | 1465 | best_path->single_copy,
|
1469 | 1466 | subplan);
|
1470 | 1467 |
|
@@ -1500,7 +1497,7 @@ create_gather_merge_plan(PlannerInfo *root, GatherMergePath *best_path)
|
1500 | 1497 | copy_generic_path_info(&gm_plan->plan, &best_path->path);
|
1501 | 1498 |
|
1502 | 1499 | /* Assign the rescan Param. */
|
1503 |
| - gm_plan->rescan_param = SS_assign_special_param(root); |
| 1500 | + gm_plan->rescan_param = assign_special_exec_param(root); |
1504 | 1501 |
|
1505 | 1502 | /* Gather Merge is pointless with no pathkeys; use Gather instead. */
|
1506 | 1503 | Assert(pathkeys != NIL);
|
@@ -3684,9 +3681,6 @@ create_nestloop_plan(PlannerInfo *root,
|
3684 | 3681 | Relids outerrelids;
|
3685 | 3682 | List *nestParams;
|
3686 | 3683 | Relids saveOuterRels = root->curOuterRels;
|
3687 |
| - ListCell *cell; |
3688 |
| - ListCell *prev; |
3689 |
| - ListCell *next; |
3690 | 3684 |
|
3691 | 3685 | /* NestLoop can project, so no need to be picky about child tlists */
|
3692 | 3686 | outer_plan = create_plan_recurse(root, best_path->outerjoinpath, 0);
|
@@ -3730,38 +3724,10 @@ create_nestloop_plan(PlannerInfo *root,
|
3730 | 3724 |
|
3731 | 3725 | /*
|
3732 | 3726 | * Identify any nestloop parameters that should be supplied by this join
|
3733 |
| - * node, and move them from root->curOuterParams to the nestParams list. |
| 3727 | + * node, and remove them from root->curOuterParams. |
3734 | 3728 | */
|
3735 | 3729 | outerrelids = best_path->outerjoinpath->parent->relids;
|
3736 |
| - nestParams = NIL; |
3737 |
| - prev = NULL; |
3738 |
| - for (cell = list_head(root->curOuterParams); cell; cell = next) |
3739 |
| - { |
3740 |
| - NestLoopParam *nlp = (NestLoopParam *) lfirst(cell); |
3741 |
| - |
3742 |
| - next = lnext(cell); |
3743 |
| - if (IsA(nlp->paramval, Var) && |
3744 |
| - bms_is_member(nlp->paramval->varno, outerrelids)) |
3745 |
| - { |
3746 |
| - root->curOuterParams = list_delete_cell(root->curOuterParams, |
3747 |
| - cell, prev); |
3748 |
| - nestParams = lappend(nestParams, nlp); |
3749 |
| - } |
3750 |
| - else if (IsA(nlp->paramval, PlaceHolderVar) && |
3751 |
| - bms_overlap(((PlaceHolderVar *) nlp->paramval)->phrels, |
3752 |
| - outerrelids) && |
3753 |
| - bms_is_subset(find_placeholder_info(root, |
3754 |
| - (PlaceHolderVar *) nlp->paramval, |
3755 |
| - false)->ph_eval_at, |
3756 |
| - outerrelids)) |
3757 |
| - { |
3758 |
| - root->curOuterParams = list_delete_cell(root->curOuterParams, |
3759 |
| - cell, prev); |
3760 |
| - nestParams = lappend(nestParams, nlp); |
3761 |
| - } |
3762 |
| - else |
3763 |
| - prev = cell; |
3764 |
| - } |
| 3730 | + nestParams = identify_current_nestloop_params(root, outerrelids); |
3765 | 3731 |
|
3766 | 3732 | join_plan = make_nestloop(tlist,
|
3767 | 3733 | joinclauses,
|
@@ -4244,42 +4210,18 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root)
|
4244 | 4210 | if (IsA(node, Var))
|
4245 | 4211 | {
|
4246 | 4212 | Var *var = (Var *) node;
|
4247 |
| - Param *param; |
4248 |
| - NestLoopParam *nlp; |
4249 |
| - ListCell *lc; |
4250 | 4213 |
|
4251 | 4214 | /* Upper-level Vars should be long gone at this point */
|
4252 | 4215 | Assert(var->varlevelsup == 0);
|
4253 | 4216 | /* If not to be replaced, we can just return the Var unmodified */
|
4254 | 4217 | if (!bms_is_member(var->varno, root->curOuterRels))
|
4255 | 4218 | return node;
|
4256 |
| - /* Create a Param representing the Var */ |
4257 |
| - param = assign_nestloop_param_var(root, var); |
4258 |
| - /* Is this param already listed in root->curOuterParams? */ |
4259 |
| - foreach(lc, root->curOuterParams) |
4260 |
| - { |
4261 |
| - nlp = (NestLoopParam *) lfirst(lc); |
4262 |
| - if (nlp->paramno == param->paramid) |
4263 |
| - { |
4264 |
| - Assert(equal(var, nlp->paramval)); |
4265 |
| - /* Present, so we can just return the Param */ |
4266 |
| - return (Node *) param; |
4267 |
| - } |
4268 |
| - } |
4269 |
| - /* No, so add it */ |
4270 |
| - nlp = makeNode(NestLoopParam); |
4271 |
| - nlp->paramno = param->paramid; |
4272 |
| - nlp->paramval = var; |
4273 |
| - root->curOuterParams = lappend(root->curOuterParams, nlp); |
4274 |
| - /* And return the replacement Param */ |
4275 |
| - return (Node *) param; |
| 4219 | + /* Replace the Var with a nestloop Param */ |
| 4220 | + return (Node *) replace_nestloop_param_var(root, var); |
4276 | 4221 | }
|
4277 | 4222 | if (IsA(node, PlaceHolderVar))
|
4278 | 4223 | {
|
4279 | 4224 | PlaceHolderVar *phv = (PlaceHolderVar *) node;
|
4280 |
| - Param *param; |
4281 |
| - NestLoopParam *nlp; |
4282 |
| - ListCell *lc; |
4283 | 4225 |
|
4284 | 4226 | /* Upper-level PlaceHolderVars should be long gone at this point */
|
4285 | 4227 | Assert(phv->phlevelsup == 0);
|
@@ -4316,118 +4258,14 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root)
|
4316 | 4258 | root);
|
4317 | 4259 | return (Node *) newphv;
|
4318 | 4260 | }
|
4319 |
| - /* Create a Param representing the PlaceHolderVar */ |
4320 |
| - param = assign_nestloop_param_placeholdervar(root, phv); |
4321 |
| - /* Is this param already listed in root->curOuterParams? */ |
4322 |
| - foreach(lc, root->curOuterParams) |
4323 |
| - { |
4324 |
| - nlp = (NestLoopParam *) lfirst(lc); |
4325 |
| - if (nlp->paramno == param->paramid) |
4326 |
| - { |
4327 |
| - Assert(equal(phv, nlp->paramval)); |
4328 |
| - /* Present, so we can just return the Param */ |
4329 |
| - return (Node *) param; |
4330 |
| - } |
4331 |
| - } |
4332 |
| - /* No, so add it */ |
4333 |
| - nlp = makeNode(NestLoopParam); |
4334 |
| - nlp->paramno = param->paramid; |
4335 |
| - nlp->paramval = (Var *) phv; |
4336 |
| - root->curOuterParams = lappend(root->curOuterParams, nlp); |
4337 |
| - /* And return the replacement Param */ |
4338 |
| - return (Node *) param; |
| 4261 | + /* Replace the PlaceHolderVar with a nestloop Param */ |
| 4262 | + return (Node *) replace_nestloop_param_placeholdervar(root, phv); |
4339 | 4263 | }
|
4340 | 4264 | return expression_tree_mutator(node,
|
4341 | 4265 | replace_nestloop_params_mutator,
|
4342 | 4266 | (void *) root);
|
4343 | 4267 | }
|
4344 | 4268 |
|
4345 |
| -/* |
4346 |
| - * process_subquery_nestloop_params |
4347 |
| - * Handle params of a parameterized subquery that need to be fed |
4348 |
| - * from an outer nestloop. |
4349 |
| - * |
4350 |
| - * Currently, that would be *all* params that a subquery in FROM has demanded |
4351 |
| - * from the current query level, since they must be LATERAL references. |
4352 |
| - * |
4353 |
| - * The subplan's references to the outer variables are already represented |
4354 |
| - * as PARAM_EXEC Params, so we need not modify the subplan here. What we |
4355 |
| - * do need to do is add entries to root->curOuterParams to signal the parent |
4356 |
| - * nestloop plan node that it must provide these values. |
4357 |
| - */ |
4358 |
| -static void |
4359 |
| -process_subquery_nestloop_params(PlannerInfo *root, List *subplan_params) |
4360 |
| -{ |
4361 |
| - ListCell *ppl; |
4362 |
| - |
4363 |
| - foreach(ppl, subplan_params) |
4364 |
| - { |
4365 |
| - PlannerParamItem *pitem = (PlannerParamItem *) lfirst(ppl); |
4366 |
| - |
4367 |
| - if (IsA(pitem->item, Var)) |
4368 |
| - { |
4369 |
| - Var *var = (Var *) pitem->item; |
4370 |
| - NestLoopParam *nlp; |
4371 |
| - ListCell *lc; |
4372 |
| - |
4373 |
| - /* If not from a nestloop outer rel, complain */ |
4374 |
| - if (!bms_is_member(var->varno, root->curOuterRels)) |
4375 |
| - elog(ERROR, "non-LATERAL parameter required by subquery"); |
4376 |
| - /* Is this param already listed in root->curOuterParams? */ |
4377 |
| - foreach(lc, root->curOuterParams) |
4378 |
| - { |
4379 |
| - nlp = (NestLoopParam *) lfirst(lc); |
4380 |
| - if (nlp->paramno == pitem->paramId) |
4381 |
| - { |
4382 |
| - Assert(equal(var, nlp->paramval)); |
4383 |
| - /* Present, so nothing to do */ |
4384 |
| - break; |
4385 |
| - } |
4386 |
| - } |
4387 |
| - if (lc == NULL) |
4388 |
| - { |
4389 |
| - /* No, so add it */ |
4390 |
| - nlp = makeNode(NestLoopParam); |
4391 |
| - nlp->paramno = pitem->paramId; |
4392 |
| - nlp->paramval = copyObject(var); |
4393 |
| - root->curOuterParams = lappend(root->curOuterParams, nlp); |
4394 |
| - } |
4395 |
| - } |
4396 |
| - else if (IsA(pitem->item, PlaceHolderVar)) |
4397 |
| - { |
4398 |
| - PlaceHolderVar *phv = (PlaceHolderVar *) pitem->item; |
4399 |
| - NestLoopParam *nlp; |
4400 |
| - ListCell *lc; |
4401 |
| - |
4402 |
| - /* If not from a nestloop outer rel, complain */ |
4403 |
| - if (!bms_is_subset(find_placeholder_info(root, phv, false)->ph_eval_at, |
4404 |
| - root->curOuterRels)) |
4405 |
| - elog(ERROR, "non-LATERAL parameter required by subquery"); |
4406 |
| - /* Is this param already listed in root->curOuterParams? */ |
4407 |
| - foreach(lc, root->curOuterParams) |
4408 |
| - { |
4409 |
| - nlp = (NestLoopParam *) lfirst(lc); |
4410 |
| - if (nlp->paramno == pitem->paramId) |
4411 |
| - { |
4412 |
| - Assert(equal(phv, nlp->paramval)); |
4413 |
| - /* Present, so nothing to do */ |
4414 |
| - break; |
4415 |
| - } |
4416 |
| - } |
4417 |
| - if (lc == NULL) |
4418 |
| - { |
4419 |
| - /* No, so add it */ |
4420 |
| - nlp = makeNode(NestLoopParam); |
4421 |
| - nlp->paramno = pitem->paramId; |
4422 |
| - nlp->paramval = (Var *) copyObject(phv); |
4423 |
| - root->curOuterParams = lappend(root->curOuterParams, nlp); |
4424 |
| - } |
4425 |
| - } |
4426 |
| - else |
4427 |
| - elog(ERROR, "unexpected type of subquery parameter"); |
4428 |
| - } |
4429 |
| -} |
4430 |
| - |
4431 | 4269 | /*
|
4432 | 4270 | * fix_indexqual_references
|
4433 | 4271 | * Adjust indexqual clauses to the form the executor's indexqual
|
|
0 commit comments