Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 9fa12dd

Browse files
committed
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 ...
1 parent 314c7b6 commit 9fa12dd

File tree

10 files changed

+50
-47
lines changed

10 files changed

+50
-47
lines changed

src/backend/nodes/copyfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.353 2006/11/05 22:42:08 tgl Exp $
18+
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.354 2006/12/10 22:13:26 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -745,6 +745,7 @@ _copyParam(Param *from)
745745
COPY_SCALAR_FIELD(paramkind);
746746
COPY_SCALAR_FIELD(paramid);
747747
COPY_SCALAR_FIELD(paramtype);
748+
COPY_SCALAR_FIELD(paramtypmod);
748749

749750
return newnode;
750751
}

src/backend/nodes/equalfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* Portions Copyright (c) 1994, Regents of the University of California
1919
*
2020
* IDENTIFICATION
21-
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.287 2006/11/05 22:42:08 tgl Exp $
21+
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.288 2006/12/10 22:13:26 tgl Exp $
2222
*
2323
*-------------------------------------------------------------------------
2424
*/
@@ -147,6 +147,7 @@ _equalParam(Param *a, Param *b)
147147
COMPARE_SCALAR_FIELD(paramkind);
148148
COMPARE_SCALAR_FIELD(paramid);
149149
COMPARE_SCALAR_FIELD(paramtype);
150+
COMPARE_SCALAR_FIELD(paramtypmod);
150151

151152
return true;
152153
}

src/backend/nodes/outfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.285 2006/09/19 22:49:52 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.286 2006/12/10 22:13:26 tgl Exp $
1212
*
1313
* NOTES
1414
* Every node type that can appear in stored rules' parsetrees *must*
@@ -634,6 +634,7 @@ _outParam(StringInfo str, Param *node)
634634
WRITE_ENUM_FIELD(paramkind, ParamKind);
635635
WRITE_INT_FIELD(paramid);
636636
WRITE_OID_FIELD(paramtype);
637+
WRITE_INT_FIELD(paramtypmod);
637638
}
638639

639640
static void

src/backend/nodes/readfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.195 2006/08/12 02:52:04 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.196 2006/12/10 22:13:26 tgl Exp $
1212
*
1313
* NOTES
1414
* Path and Plan nodes do not have any readfuncs support, because we
@@ -337,6 +337,7 @@ _readParam(void)
337337
READ_ENUM_FIELD(paramkind, ParamKind);
338338
READ_INT_FIELD(paramid);
339339
READ_OID_FIELD(paramtype);
340+
READ_INT_FIELD(paramtypmod);
340341

341342
READ_DONE();
342343
}

src/backend/optimizer/plan/subselect.c

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.113 2006/12/06 19:40:01 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.114 2006/12/10 22:13:26 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -75,7 +75,6 @@ typedef struct convert_testexpr_context
7575
{
7676
int rtindex; /* RT index for Vars, or 0 for Params */
7777
List *righthandIds; /* accumulated list of Vars or Param IDs */
78-
List *sub_tlist; /* subselect targetlist (if given) */
7978
} convert_testexpr_context;
8079

8180
typedef struct finalize_primnode_context
@@ -87,8 +86,7 @@ typedef struct finalize_primnode_context
8786

8887
static Node *convert_testexpr(Node *testexpr,
8988
int rtindex,
90-
List **righthandIds,
91-
List *sub_tlist);
89+
List **righthandIds);
9290
static Node *convert_testexpr_mutator(Node *node,
9391
convert_testexpr_context *context);
9492
static bool subplan_is_hashable(SubLink *slink, SubPlan *node);
@@ -166,6 +164,7 @@ replace_outer_var(Var *var)
166164
retval->paramkind = PARAM_EXEC;
167165
retval->paramid = i;
168166
retval->paramtype = var->vartype;
167+
retval->paramtypmod = var->vartypmod;
169168

170169
return retval;
171170
}
@@ -204,6 +203,7 @@ replace_outer_agg(Aggref *agg)
204203
retval->paramkind = PARAM_EXEC;
205204
retval->paramid = i;
206205
retval->paramtype = agg->aggtype;
206+
retval->paramtypmod = -1;
207207

208208
return retval;
209209
}
@@ -212,8 +212,6 @@ replace_outer_agg(Aggref *agg)
212212
* Generate a new Param node that will not conflict with any other.
213213
*
214214
* This is used to allocate PARAM_EXEC slots for subplan outputs.
215-
*
216-
* paramtypmod is currently unused but might be wanted someday.
217215
*/
218216
static Param *
219217
generate_new_param(Oid paramtype, int32 paramtypmod)
@@ -225,6 +223,7 @@ generate_new_param(Oid paramtype, int32 paramtypmod)
225223
retval->paramkind = PARAM_EXEC;
226224
retval->paramid = list_length(PlannerParamList);
227225
retval->paramtype = paramtype;
226+
retval->paramtypmod = paramtypmod;
228227

229228
pitem = (PlannerParamItem *) palloc(sizeof(PlannerParamItem));
230229
pitem->item = (Node *) retval;
@@ -371,7 +370,7 @@ make_subplan(SubLink *slink, Node *testexpr, bool isTopQual)
371370
if (!OidIsValid(arraytype))
372371
elog(ERROR, "could not find array type for datatype %s",
373372
format_type_be(exprType((Node *) te->expr)));
374-
prm = generate_new_param(arraytype, -1);
373+
prm = generate_new_param(arraytype, exprTypmod((Node *) te->expr));
375374
node->setParam = list_make1_int(prm->paramid);
376375
PlannerInitPlan = lappend(PlannerInitPlan, node);
377376
result = (Node *) prm;
@@ -381,8 +380,7 @@ make_subplan(SubLink *slink, Node *testexpr, bool isTopQual)
381380
/* Adjust the Params */
382381
result = convert_testexpr(testexpr,
383382
0,
384-
&node->paramIds,
385-
NIL);
383+
&node->paramIds);
386384
node->setParam = list_copy(node->paramIds);
387385
PlannerInitPlan = lappend(PlannerInitPlan, node);
388386

@@ -399,8 +397,7 @@ make_subplan(SubLink *slink, Node *testexpr, bool isTopQual)
399397
/* Adjust the Params */
400398
node->testexpr = convert_testexpr(testexpr,
401399
0,
402-
&node->paramIds,
403-
NIL);
400+
&node->paramIds);
404401

405402
/*
406403
* 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)
474471
* of the Var nodes are returned in *righthandIds (this is a bit of a type
475472
* cheat, but we can get away with it).
476473
*
477-
* The subquery targetlist need be supplied only if rtindex is not 0.
478-
* We consult it to extract the correct typmods for the created Vars.
479-
* (XXX this is a kluge that could go away if Params carried typmod.)
480-
*
481474
* The given testexpr has already been recursively processed by
482475
* process_sublinks_mutator. Hence it can no longer contain any
483476
* PARAM_SUBLINK Params for lower SubLink nodes; we can safely assume that
@@ -486,15 +479,13 @@ make_subplan(SubLink *slink, Node *testexpr, bool isTopQual)
486479
static Node *
487480
convert_testexpr(Node *testexpr,
488481
int rtindex,
489-
List **righthandIds,
490-
List *sub_tlist)
482+
List **righthandIds)
491483
{
492484
Node *result;
493485
convert_testexpr_context context;
494486

495487
context.rtindex = rtindex;
496488
context.righthandIds = NIL;
497-
context.sub_tlist = sub_tlist;
498489
result = convert_testexpr_mutator(testexpr, &context);
499490
*righthandIds = context.righthandIds;
500491
return result;
@@ -526,23 +517,10 @@ convert_testexpr_mutator(Node *node,
526517
/* Make the Var node representing the subplan's result */
527518
Var *newvar;
528519

529-
/*
530-
* XXX kluge: since Params don't carry typmod, we have to
531-
* look into the subquery targetlist to find out the right
532-
* typmod to assign to the Var.
533-
*/
534-
TargetEntry *ste = get_tle_by_resno(context->sub_tlist,
535-
param->paramid);
536-
537-
if (ste == NULL || ste->resjunk)
538-
elog(ERROR, "subquery output %d not found",
539-
param->paramid);
540-
Assert(param->paramtype == exprType((Node *) ste->expr));
541-
542520
newvar = makeVar(context->rtindex,
543521
param->paramid,
544522
param->paramtype,
545-
exprTypmod((Node *) ste->expr),
523+
param->paramtypmod,
546524
0);
547525

548526
/*
@@ -558,7 +536,8 @@ convert_testexpr_mutator(Node *node,
558536
/* Make the Param node representing the subplan's result */
559537
Param *newparam;
560538

561-
newparam = generate_new_param(param->paramtype, -1);
539+
newparam = generate_new_param(param->paramtype,
540+
param->paramtypmod);
562541
/* Record its ID */
563542
context->righthandIds = lappend_int(context->righthandIds,
564543
newparam->paramid);
@@ -775,8 +754,7 @@ convert_IN_to_join(PlannerInfo *root, SubLink *sublink)
775754
*/
776755
return convert_testexpr(sublink->testexpr,
777756
rtindex,
778-
&ininfo->sub_targetlist,
779-
subselect->targetList);
757+
&ininfo->sub_targetlist);
780758
}
781759

782760
/*

src/backend/parser/parse_agg.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.73 2006/07/27 19:52:05 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.74 2006/12/10 22:13:26 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -394,6 +394,7 @@ build_aggregate_fnexprs(Oid *agg_input_types,
394394
argp->paramkind = PARAM_EXEC;
395395
argp->paramid = -1;
396396
argp->paramtype = agg_state_type;
397+
argp->paramtypmod = -1;
397398

398399
args = list_make1(argp);
399400

@@ -403,6 +404,7 @@ build_aggregate_fnexprs(Oid *agg_input_types,
403404
argp->paramkind = PARAM_EXEC;
404405
argp->paramid = -1;
405406
argp->paramtype = agg_input_types[i];
407+
argp->paramtypmod = -1;
406408
args = lappend(args, argp);
407409
}
408410

@@ -425,6 +427,7 @@ build_aggregate_fnexprs(Oid *agg_input_types,
425427
argp->paramkind = PARAM_EXEC;
426428
argp->paramid = -1;
427429
argp->paramtype = agg_state_type;
430+
argp->paramtypmod = -1;
428431
args = list_make1(argp);
429432

430433
*finalfnexpr = (Expr *) makeFuncExpr(finalfn_oid,

src/backend/parser/parse_coerce.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.146 2006/11/28 12:54:41 petere Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.147 2006/12/10 22:13:26 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -264,6 +264,14 @@ coerce_type(ParseState *pstate, Node *node,
264264
}
265265

266266
param->paramtype = targetTypeId;
267+
/*
268+
* Note: it is tempting here to set the Param's paramtypmod to
269+
* targetTypeMod, but that is probably unwise because we have no
270+
* infrastructure that enforces that the value delivered for a
271+
* Param will match any particular typmod. Leaving it -1 ensures
272+
* that a run-time length check/coercion will occur if needed.
273+
*/
274+
param->paramtypmod = -1;
267275

268276
return (Node *) param;
269277
}

src/backend/parser/parse_expr.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.198 2006/10/04 00:29:55 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.199 2006/12/10 22:13:26 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -572,6 +572,7 @@ transformParamRef(ParseState *pstate, ParamRef *pref)
572572
param->paramkind = PARAM_EXTERN;
573573
param->paramid = paramno;
574574
param->paramtype = toppstate->p_paramtypes[paramno - 1];
575+
param->paramtypmod = -1;
575576

576577
return (Node *) param;
577578
}
@@ -1180,6 +1181,7 @@ transformSubLink(ParseState *pstate, SubLink *sublink)
11801181
param->paramkind = PARAM_SUBLINK;
11811182
param->paramid = tent->resno;
11821183
param->paramtype = exprType((Node *) tent->expr);
1184+
param->paramtypmod = exprTypmod((Node *) tent->expr);
11831185

11841186
right_list = lappend(right_list, param);
11851187
}
@@ -1721,6 +1723,8 @@ exprTypmod(Node *expr)
17211723
}
17221724
}
17231725
break;
1726+
case T_Param:
1727+
return ((Param *) expr)->paramtypmod;
17241728
case T_FuncExpr:
17251729
{
17261730
int32 coercedTypmod;

src/include/catalog/catversion.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
3838
* Portions Copyright (c) 1994, Regents of the University of California
3939
*
40-
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.361 2006/12/06 18:06:47 neilc Exp $
40+
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.362 2006/12/10 22:13:26 tgl Exp $
4141
*
4242
*-------------------------------------------------------------------------
4343
*/
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 200612061
56+
#define CATALOG_VERSION_NO 200612101
5757

5858
#endif

src/include/nodes/primnodes.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
1111
* Portions Copyright (c) 1994, Regents of the University of California
1212
*
13-
* $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.117 2006/10/04 00:30:09 momjian Exp $
13+
* $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.118 2006/12/10 22:13:27 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -113,7 +113,7 @@ typedef struct Var
113113
* table (could also be INNER or OUTER) */
114114
AttrNumber varattno; /* attribute number of this var, or zero for
115115
* all */
116-
Oid vartype; /* pg_type tuple OID for the type of this var */
116+
Oid vartype; /* pg_type OID for the type of this var */
117117
int32 vartypmod; /* pg_attribute typmod value */
118118
Index varlevelsup;
119119

@@ -159,6 +159,11 @@ typedef struct Const
159159
* node's sub-select. The column number is contained in the
160160
* `paramid' field. (This type of Param is converted to
161161
* PARAM_EXEC during planning.)
162+
*
163+
* Note: currently, paramtypmod is valid for PARAM_SUBLINK Params, and for
164+
* PARAM_EXEC Params generated from them; it is always -1 for PARAM_EXTERN
165+
* params, since the APIs that supply values for such parameters don't carry
166+
* any typmod info.
162167
* ----------------
163168
*/
164169
typedef enum ParamKind
@@ -173,7 +178,8 @@ typedef struct Param
173178
Expr xpr;
174179
ParamKind paramkind; /* kind of parameter. See above */
175180
int paramid; /* numeric ID for parameter */
176-
Oid paramtype; /* PG_TYPE OID of parameter's datatype */
181+
Oid paramtype; /* pg_type OID of parameter's datatype */
182+
int32 paramtypmod; /* typmod value, if known */
177183
} Param;
178184

179185
/*

0 commit comments

Comments
 (0)