|
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"
|
@@ -147,8 +146,6 @@ static MergeJoin *create_mergejoin_plan(PlannerInfo *root, MergePath *best_path)
|
147 | 146 | static HashJoin *create_hashjoin_plan(PlannerInfo *root, HashPath *best_path);
|
148 | 147 | static Node *replace_nestloop_params(PlannerInfo *root, Node *expr);
|
149 | 148 | static Node *replace_nestloop_params_mutator(Node *node, PlannerInfo *root);
|
150 |
| -static void process_subquery_nestloop_params(PlannerInfo *root, |
151 |
| - List *subplan_params); |
152 | 149 | static List *fix_indexqual_references(PlannerInfo *root, IndexPath *index_path);
|
153 | 150 | static List *fix_indexorderby_references(PlannerInfo *root, IndexPath *index_path);
|
154 | 151 | static Node *fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol);
|
@@ -295,7 +292,7 @@ create_plan(PlannerInfo *root, Path *best_path)
|
295 | 292 | /* plan_params should not be in use in current query level */
|
296 | 293 | Assert(root->plan_params == NIL);
|
297 | 294 |
|
298 |
| - /* Initialize this module's private workspace in PlannerInfo */ |
| 295 | + /* Initialize this module's workspace in PlannerInfo */ |
299 | 296 | root->curOuterRels = NULL;
|
300 | 297 | root->curOuterParams = NIL;
|
301 | 298 |
|
@@ -3444,9 +3441,6 @@ create_nestloop_plan(PlannerInfo *root,
|
3444 | 3441 | Relids outerrelids;
|
3445 | 3442 | List *nestParams;
|
3446 | 3443 | Relids saveOuterRels = root->curOuterRels;
|
3447 |
| - ListCell *cell; |
3448 |
| - ListCell *prev; |
3449 |
| - ListCell *next; |
3450 | 3444 |
|
3451 | 3445 | /* NestLoop can project, so no need to be picky about child tlists */
|
3452 | 3446 | outer_plan = create_plan_recurse(root, best_path->outerjoinpath, 0);
|
@@ -3490,38 +3484,10 @@ create_nestloop_plan(PlannerInfo *root,
|
3490 | 3484 |
|
3491 | 3485 | /*
|
3492 | 3486 | * Identify any nestloop parameters that should be supplied by this join
|
3493 |
| - * node, and move them from root->curOuterParams to the nestParams list. |
| 3487 | + * node, and remove them from root->curOuterParams. |
3494 | 3488 | */
|
3495 | 3489 | outerrelids = best_path->outerjoinpath->parent->relids;
|
3496 |
| - nestParams = NIL; |
3497 |
| - prev = NULL; |
3498 |
| - for (cell = list_head(root->curOuterParams); cell; cell = next) |
3499 |
| - { |
3500 |
| - NestLoopParam *nlp = (NestLoopParam *) lfirst(cell); |
3501 |
| - |
3502 |
| - next = lnext(cell); |
3503 |
| - if (IsA(nlp->paramval, Var) && |
3504 |
| - bms_is_member(nlp->paramval->varno, outerrelids)) |
3505 |
| - { |
3506 |
| - root->curOuterParams = list_delete_cell(root->curOuterParams, |
3507 |
| - cell, prev); |
3508 |
| - nestParams = lappend(nestParams, nlp); |
3509 |
| - } |
3510 |
| - else if (IsA(nlp->paramval, PlaceHolderVar) && |
3511 |
| - bms_overlap(((PlaceHolderVar *) nlp->paramval)->phrels, |
3512 |
| - outerrelids) && |
3513 |
| - bms_is_subset(find_placeholder_info(root, |
3514 |
| - (PlaceHolderVar *) nlp->paramval, |
3515 |
| - false)->ph_eval_at, |
3516 |
| - outerrelids)) |
3517 |
| - { |
3518 |
| - root->curOuterParams = list_delete_cell(root->curOuterParams, |
3519 |
| - cell, prev); |
3520 |
| - nestParams = lappend(nestParams, nlp); |
3521 |
| - } |
3522 |
| - else |
3523 |
| - prev = cell; |
3524 |
| - } |
| 3490 | + nestParams = identify_current_nestloop_params(root, outerrelids); |
3525 | 3491 |
|
3526 | 3492 | join_plan = make_nestloop(tlist,
|
3527 | 3493 | joinclauses,
|
@@ -4007,42 +3973,18 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root)
|
4007 | 3973 | if (IsA(node, Var))
|
4008 | 3974 | {
|
4009 | 3975 | Var *var = (Var *) node;
|
4010 |
| - Param *param; |
4011 |
| - NestLoopParam *nlp; |
4012 |
| - ListCell *lc; |
4013 | 3976 |
|
4014 | 3977 | /* Upper-level Vars should be long gone at this point */
|
4015 | 3978 | Assert(var->varlevelsup == 0);
|
4016 | 3979 | /* If not to be replaced, we can just return the Var unmodified */
|
4017 | 3980 | if (!bms_is_member(var->varno, root->curOuterRels))
|
4018 | 3981 | return node;
|
4019 |
| - /* Create a Param representing the Var */ |
4020 |
| - param = assign_nestloop_param_var(root, var); |
4021 |
| - /* Is this param already listed in root->curOuterParams? */ |
4022 |
| - foreach(lc, root->curOuterParams) |
4023 |
| - { |
4024 |
| - nlp = (NestLoopParam *) lfirst(lc); |
4025 |
| - if (nlp->paramno == param->paramid) |
4026 |
| - { |
4027 |
| - Assert(equal(var, nlp->paramval)); |
4028 |
| - /* Present, so we can just return the Param */ |
4029 |
| - return (Node *) param; |
4030 |
| - } |
4031 |
| - } |
4032 |
| - /* No, so add it */ |
4033 |
| - nlp = makeNode(NestLoopParam); |
4034 |
| - nlp->paramno = param->paramid; |
4035 |
| - nlp->paramval = var; |
4036 |
| - root->curOuterParams = lappend(root->curOuterParams, nlp); |
4037 |
| - /* And return the replacement Param */ |
4038 |
| - return (Node *) param; |
| 3982 | + /* Replace the Var with a nestloop Param */ |
| 3983 | + return (Node *) replace_nestloop_param_var(root, var); |
4039 | 3984 | }
|
4040 | 3985 | if (IsA(node, PlaceHolderVar))
|
4041 | 3986 | {
|
4042 | 3987 | PlaceHolderVar *phv = (PlaceHolderVar *) node;
|
4043 |
| - Param *param; |
4044 |
| - NestLoopParam *nlp; |
4045 |
| - ListCell *lc; |
4046 | 3988 |
|
4047 | 3989 | /* Upper-level PlaceHolderVars should be long gone at this point */
|
4048 | 3990 | Assert(phv->phlevelsup == 0);
|
@@ -4079,118 +4021,14 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root)
|
4079 | 4021 | root);
|
4080 | 4022 | return (Node *) newphv;
|
4081 | 4023 | }
|
4082 |
| - /* Create a Param representing the PlaceHolderVar */ |
4083 |
| - param = assign_nestloop_param_placeholdervar(root, phv); |
4084 |
| - /* Is this param already listed in root->curOuterParams? */ |
4085 |
| - foreach(lc, root->curOuterParams) |
4086 |
| - { |
4087 |
| - nlp = (NestLoopParam *) lfirst(lc); |
4088 |
| - if (nlp->paramno == param->paramid) |
4089 |
| - { |
4090 |
| - Assert(equal(phv, nlp->paramval)); |
4091 |
| - /* Present, so we can just return the Param */ |
4092 |
| - return (Node *) param; |
4093 |
| - } |
4094 |
| - } |
4095 |
| - /* No, so add it */ |
4096 |
| - nlp = makeNode(NestLoopParam); |
4097 |
| - nlp->paramno = param->paramid; |
4098 |
| - nlp->paramval = (Var *) phv; |
4099 |
| - root->curOuterParams = lappend(root->curOuterParams, nlp); |
4100 |
| - /* And return the replacement Param */ |
4101 |
| - return (Node *) param; |
| 4024 | + /* Replace the PlaceHolderVar with a nestloop Param */ |
| 4025 | + return (Node *) replace_nestloop_param_placeholdervar(root, phv); |
4102 | 4026 | }
|
4103 | 4027 | return expression_tree_mutator(node,
|
4104 | 4028 | replace_nestloop_params_mutator,
|
4105 | 4029 | (void *) root);
|
4106 | 4030 | }
|
4107 | 4031 |
|
4108 |
| -/* |
4109 |
| - * process_subquery_nestloop_params |
4110 |
| - * Handle params of a parameterized subquery that need to be fed |
4111 |
| - * from an outer nestloop. |
4112 |
| - * |
4113 |
| - * Currently, that would be *all* params that a subquery in FROM has demanded |
4114 |
| - * from the current query level, since they must be LATERAL references. |
4115 |
| - * |
4116 |
| - * The subplan's references to the outer variables are already represented |
4117 |
| - * as PARAM_EXEC Params, so we need not modify the subplan here. What we |
4118 |
| - * do need to do is add entries to root->curOuterParams to signal the parent |
4119 |
| - * nestloop plan node that it must provide these values. |
4120 |
| - */ |
4121 |
| -static void |
4122 |
| -process_subquery_nestloop_params(PlannerInfo *root, List *subplan_params) |
4123 |
| -{ |
4124 |
| - ListCell *ppl; |
4125 |
| - |
4126 |
| - foreach(ppl, subplan_params) |
4127 |
| - { |
4128 |
| - PlannerParamItem *pitem = (PlannerParamItem *) lfirst(ppl); |
4129 |
| - |
4130 |
| - if (IsA(pitem->item, Var)) |
4131 |
| - { |
4132 |
| - Var *var = (Var *) pitem->item; |
4133 |
| - NestLoopParam *nlp; |
4134 |
| - ListCell *lc; |
4135 |
| - |
4136 |
| - /* If not from a nestloop outer rel, complain */ |
4137 |
| - if (!bms_is_member(var->varno, root->curOuterRels)) |
4138 |
| - elog(ERROR, "non-LATERAL parameter required by subquery"); |
4139 |
| - /* Is this param already listed in root->curOuterParams? */ |
4140 |
| - foreach(lc, root->curOuterParams) |
4141 |
| - { |
4142 |
| - nlp = (NestLoopParam *) lfirst(lc); |
4143 |
| - if (nlp->paramno == pitem->paramId) |
4144 |
| - { |
4145 |
| - Assert(equal(var, nlp->paramval)); |
4146 |
| - /* Present, so nothing to do */ |
4147 |
| - break; |
4148 |
| - } |
4149 |
| - } |
4150 |
| - if (lc == NULL) |
4151 |
| - { |
4152 |
| - /* No, so add it */ |
4153 |
| - nlp = makeNode(NestLoopParam); |
4154 |
| - nlp->paramno = pitem->paramId; |
4155 |
| - nlp->paramval = copyObject(var); |
4156 |
| - root->curOuterParams = lappend(root->curOuterParams, nlp); |
4157 |
| - } |
4158 |
| - } |
4159 |
| - else if (IsA(pitem->item, PlaceHolderVar)) |
4160 |
| - { |
4161 |
| - PlaceHolderVar *phv = (PlaceHolderVar *) pitem->item; |
4162 |
| - NestLoopParam *nlp; |
4163 |
| - ListCell *lc; |
4164 |
| - |
4165 |
| - /* If not from a nestloop outer rel, complain */ |
4166 |
| - if (!bms_is_subset(find_placeholder_info(root, phv, false)->ph_eval_at, |
4167 |
| - root->curOuterRels)) |
4168 |
| - elog(ERROR, "non-LATERAL parameter required by subquery"); |
4169 |
| - /* Is this param already listed in root->curOuterParams? */ |
4170 |
| - foreach(lc, root->curOuterParams) |
4171 |
| - { |
4172 |
| - nlp = (NestLoopParam *) lfirst(lc); |
4173 |
| - if (nlp->paramno == pitem->paramId) |
4174 |
| - { |
4175 |
| - Assert(equal(phv, nlp->paramval)); |
4176 |
| - /* Present, so nothing to do */ |
4177 |
| - break; |
4178 |
| - } |
4179 |
| - } |
4180 |
| - if (lc == NULL) |
4181 |
| - { |
4182 |
| - /* No, so add it */ |
4183 |
| - nlp = makeNode(NestLoopParam); |
4184 |
| - nlp->paramno = pitem->paramId; |
4185 |
| - nlp->paramval = copyObject(phv); |
4186 |
| - root->curOuterParams = lappend(root->curOuterParams, nlp); |
4187 |
| - } |
4188 |
| - } |
4189 |
| - else |
4190 |
| - elog(ERROR, "unexpected type of subquery parameter"); |
4191 |
| - } |
4192 |
| -} |
4193 |
| - |
4194 | 4032 | /*
|
4195 | 4033 | * fix_indexqual_references
|
4196 | 4034 | * Adjust indexqual clauses to the form the executor's indexqual
|
|
0 commit comments