diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 2006-12-10 22:13:27 +0000 |
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 2006-12-10 22:13:27 +0000 |
| commit | 9fa12ddda62549a0e0225220745c3bf89434dab3 (patch) | |
| tree | 691cde987387d3500ec9c5560f19b270beb90da7 /src/backend/optimizer | |
| parent | 314c7b642b14e8a60a411ecce2435edf0072f78a (diff) | |
| download | postgresql-9fa12ddda62549a0e0225220745c3bf89434dab3.tar.gz | |
Add a paramtypmod field to Param nodes. This is dead weight for Params
representing externally-supplied values, since the APIs that carry such
values only specify type not typmod. However, for PARAM_SUBLINK Params
it is handy to carry the typmod of the sublink's output column. This
is a much cleaner solution for the recently reported 'could not find
pathkey item to sort' and 'failed to find unique expression in subplan
tlist' bugs than my original 8.2-compatible patch. Besides, someday we
might want to support typmods for external parameters ...
Diffstat (limited to 'src/backend/optimizer')
| -rw-r--r-- | src/backend/optimizer/plan/subselect.c | 48 |
1 files changed, 13 insertions, 35 deletions
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index 72b986002d..7793d071cd 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.113 2006/12/06 19:40:01 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.114 2006/12/10 22:13:26 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -75,7 +75,6 @@ typedef struct convert_testexpr_context { int rtindex; /* RT index for Vars, or 0 for Params */ List *righthandIds; /* accumulated list of Vars or Param IDs */ - List *sub_tlist; /* subselect targetlist (if given) */ } convert_testexpr_context; typedef struct finalize_primnode_context @@ -87,8 +86,7 @@ typedef struct finalize_primnode_context static Node *convert_testexpr(Node *testexpr, int rtindex, - List **righthandIds, - List *sub_tlist); + List **righthandIds); static Node *convert_testexpr_mutator(Node *node, convert_testexpr_context *context); static bool subplan_is_hashable(SubLink *slink, SubPlan *node); @@ -166,6 +164,7 @@ replace_outer_var(Var *var) retval->paramkind = PARAM_EXEC; retval->paramid = i; retval->paramtype = var->vartype; + retval->paramtypmod = var->vartypmod; return retval; } @@ -204,6 +203,7 @@ replace_outer_agg(Aggref *agg) retval->paramkind = PARAM_EXEC; retval->paramid = i; retval->paramtype = agg->aggtype; + retval->paramtypmod = -1; return retval; } @@ -212,8 +212,6 @@ replace_outer_agg(Aggref *agg) * Generate a new Param node that will not conflict with any other. * * This is used to allocate PARAM_EXEC slots for subplan outputs. - * - * paramtypmod is currently unused but might be wanted someday. */ static Param * generate_new_param(Oid paramtype, int32 paramtypmod) @@ -225,6 +223,7 @@ generate_new_param(Oid paramtype, int32 paramtypmod) retval->paramkind = PARAM_EXEC; retval->paramid = list_length(PlannerParamList); retval->paramtype = paramtype; + retval->paramtypmod = paramtypmod; pitem = (PlannerParamItem *) palloc(sizeof(PlannerParamItem)); pitem->item = (Node *) retval; @@ -371,7 +370,7 @@ make_subplan(SubLink *slink, Node *testexpr, bool isTopQual) if (!OidIsValid(arraytype)) elog(ERROR, "could not find array type for datatype %s", format_type_be(exprType((Node *) te->expr))); - prm = generate_new_param(arraytype, -1); + prm = generate_new_param(arraytype, exprTypmod((Node *) te->expr)); node->setParam = list_make1_int(prm->paramid); PlannerInitPlan = lappend(PlannerInitPlan, node); result = (Node *) prm; @@ -381,8 +380,7 @@ make_subplan(SubLink *slink, Node *testexpr, bool isTopQual) /* Adjust the Params */ result = convert_testexpr(testexpr, 0, - &node->paramIds, - NIL); + &node->paramIds); node->setParam = list_copy(node->paramIds); PlannerInitPlan = lappend(PlannerInitPlan, node); @@ -399,8 +397,7 @@ make_subplan(SubLink *slink, Node *testexpr, bool isTopQual) /* Adjust the Params */ node->testexpr = convert_testexpr(testexpr, 0, - &node->paramIds, - NIL); + &node->paramIds); /* * We can't convert subplans of ALL_SUBLINK or ANY_SUBLINK types to @@ -474,10 +471,6 @@ make_subplan(SubLink *slink, Node *testexpr, bool isTopQual) * of the Var nodes are returned in *righthandIds (this is a bit of a type * cheat, but we can get away with it). * - * The subquery targetlist need be supplied only if rtindex is not 0. - * We consult it to extract the correct typmods for the created Vars. - * (XXX this is a kluge that could go away if Params carried typmod.) - * * The given testexpr has already been recursively processed by * process_sublinks_mutator. Hence it can no longer contain any * PARAM_SUBLINK Params for lower SubLink nodes; we can safely assume that @@ -486,15 +479,13 @@ make_subplan(SubLink *slink, Node *testexpr, bool isTopQual) static Node * convert_testexpr(Node *testexpr, int rtindex, - List **righthandIds, - List *sub_tlist) + List **righthandIds) { Node *result; convert_testexpr_context context; context.rtindex = rtindex; context.righthandIds = NIL; - context.sub_tlist = sub_tlist; result = convert_testexpr_mutator(testexpr, &context); *righthandIds = context.righthandIds; return result; @@ -526,23 +517,10 @@ convert_testexpr_mutator(Node *node, /* Make the Var node representing the subplan's result */ Var *newvar; - /* - * XXX kluge: since Params don't carry typmod, we have to - * look into the subquery targetlist to find out the right - * typmod to assign to the Var. - */ - TargetEntry *ste = get_tle_by_resno(context->sub_tlist, - param->paramid); - - if (ste == NULL || ste->resjunk) - elog(ERROR, "subquery output %d not found", - param->paramid); - Assert(param->paramtype == exprType((Node *) ste->expr)); - newvar = makeVar(context->rtindex, param->paramid, param->paramtype, - exprTypmod((Node *) ste->expr), + param->paramtypmod, 0); /* @@ -558,7 +536,8 @@ convert_testexpr_mutator(Node *node, /* Make the Param node representing the subplan's result */ Param *newparam; - newparam = generate_new_param(param->paramtype, -1); + newparam = generate_new_param(param->paramtype, + param->paramtypmod); /* Record its ID */ context->righthandIds = lappend_int(context->righthandIds, newparam->paramid); @@ -775,8 +754,7 @@ convert_IN_to_join(PlannerInfo *root, SubLink *sublink) */ return convert_testexpr(sublink->testexpr, rtindex, - &ininfo->sub_targetlist, - subselect->targetList); + &ininfo->sub_targetlist); } /* |
