* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.353 2006/11/05 22:42:08 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.354 2006/12/10 22:13:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
COPY_SCALAR_FIELD(paramkind);
COPY_SCALAR_FIELD(paramid);
COPY_SCALAR_FIELD(paramtype);
+ COPY_SCALAR_FIELD(paramtypmod);
return newnode;
}
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.287 2006/11/05 22:42:08 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.288 2006/12/10 22:13:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
COMPARE_SCALAR_FIELD(paramkind);
COMPARE_SCALAR_FIELD(paramid);
COMPARE_SCALAR_FIELD(paramtype);
+ COMPARE_SCALAR_FIELD(paramtypmod);
return true;
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.285 2006/09/19 22:49:52 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.286 2006/12/10 22:13:26 tgl Exp $
*
* NOTES
* Every node type that can appear in stored rules' parsetrees *must*
WRITE_ENUM_FIELD(paramkind, ParamKind);
WRITE_INT_FIELD(paramid);
WRITE_OID_FIELD(paramtype);
+ WRITE_INT_FIELD(paramtypmod);
}
static void
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.195 2006/08/12 02:52:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.196 2006/12/10 22:13:26 tgl Exp $
*
* NOTES
* Path and Plan nodes do not have any readfuncs support, because we
READ_ENUM_FIELD(paramkind, ParamKind);
READ_INT_FIELD(paramid);
READ_OID_FIELD(paramtype);
+ READ_INT_FIELD(paramtypmod);
READ_DONE();
}
* 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 $
*
*-------------------------------------------------------------------------
*/
{
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
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);
retval->paramkind = PARAM_EXEC;
retval->paramid = i;
retval->paramtype = var->vartype;
+ retval->paramtypmod = var->vartypmod;
return retval;
}
retval->paramkind = PARAM_EXEC;
retval->paramid = i;
retval->paramtype = agg->aggtype;
+ retval->paramtypmod = -1;
return retval;
}
* 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)
retval->paramkind = PARAM_EXEC;
retval->paramid = list_length(PlannerParamList);
retval->paramtype = paramtype;
+ retval->paramtypmod = paramtypmod;
pitem = (PlannerParamItem *) palloc(sizeof(PlannerParamItem));
pitem->item = (Node *) retval;
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;
/* Adjust the Params */
result = convert_testexpr(testexpr,
0,
- &node->paramIds,
- NIL);
+ &node->paramIds);
node->setParam = list_copy(node->paramIds);
PlannerInitPlan = lappend(PlannerInitPlan, node);
/* 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
* 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
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;
/* 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);
/*
/* 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);
*/
return convert_testexpr(sublink->testexpr,
rtindex,
- &ininfo->sub_targetlist,
- subselect->targetList);
+ &ininfo->sub_targetlist);
}
/*
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.73 2006/07/27 19:52:05 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.74 2006/12/10 22:13:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
argp->paramkind = PARAM_EXEC;
argp->paramid = -1;
argp->paramtype = agg_state_type;
+ argp->paramtypmod = -1;
args = list_make1(argp);
argp->paramkind = PARAM_EXEC;
argp->paramid = -1;
argp->paramtype = agg_input_types[i];
+ argp->paramtypmod = -1;
args = lappend(args, argp);
}
argp->paramkind = PARAM_EXEC;
argp->paramid = -1;
argp->paramtype = agg_state_type;
+ argp->paramtypmod = -1;
args = list_make1(argp);
*finalfnexpr = (Expr *) makeFuncExpr(finalfn_oid,
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.146 2006/11/28 12:54:41 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.147 2006/12/10 22:13:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
}
param->paramtype = targetTypeId;
+ /*
+ * Note: it is tempting here to set the Param's paramtypmod to
+ * targetTypeMod, but that is probably unwise because we have no
+ * infrastructure that enforces that the value delivered for a
+ * Param will match any particular typmod. Leaving it -1 ensures
+ * that a run-time length check/coercion will occur if needed.
+ */
+ param->paramtypmod = -1;
return (Node *) param;
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.198 2006/10/04 00:29:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.199 2006/12/10 22:13:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
param->paramkind = PARAM_EXTERN;
param->paramid = paramno;
param->paramtype = toppstate->p_paramtypes[paramno - 1];
+ param->paramtypmod = -1;
return (Node *) param;
}
param->paramkind = PARAM_SUBLINK;
param->paramid = tent->resno;
param->paramtype = exprType((Node *) tent->expr);
+ param->paramtypmod = exprTypmod((Node *) tent->expr);
right_list = lappend(right_list, param);
}
}
}
break;
+ case T_Param:
+ return ((Param *) expr)->paramtypmod;
case T_FuncExpr:
{
int32 coercedTypmod;
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.361 2006/12/06 18:06:47 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.362 2006/12/10 22:13:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200612061
+#define CATALOG_VERSION_NO 200612101
#endif
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.117 2006/10/04 00:30:09 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.118 2006/12/10 22:13:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* table (could also be INNER or OUTER) */
AttrNumber varattno; /* attribute number of this var, or zero for
* all */
- Oid vartype; /* pg_type tuple OID for the type of this var */
+ Oid vartype; /* pg_type OID for the type of this var */
int32 vartypmod; /* pg_attribute typmod value */
Index varlevelsup;
* node's sub-select. The column number is contained in the
* `paramid' field. (This type of Param is converted to
* PARAM_EXEC during planning.)
+ *
+ * Note: currently, paramtypmod is valid for PARAM_SUBLINK Params, and for
+ * PARAM_EXEC Params generated from them; it is always -1 for PARAM_EXTERN
+ * params, since the APIs that supply values for such parameters don't carry
+ * any typmod info.
* ----------------
*/
typedef enum ParamKind
Expr xpr;
ParamKind paramkind; /* kind of parameter. See above */
int paramid; /* numeric ID for parameter */
- Oid paramtype; /* PG_TYPE OID of parameter's datatype */
+ Oid paramtype; /* pg_type OID of parameter's datatype */
+ int32 paramtypmod; /* typmod value, if known */
} Param;
/*