diff options
Diffstat (limited to 'src/backend/commands/functioncmds.c')
-rw-r--r-- | src/backend/commands/functioncmds.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 757869a925a..7747eb1d776 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.47 2004/05/26 04:41:11 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.48 2004/06/16 01:26:42 tgl Exp $ * * DESCRIPTION * These routines take the parse tree and pick out the @@ -809,6 +809,7 @@ CreateCast(CreateCastStmt *stmt) Oid sourcetypeid; Oid targettypeid; Oid funcid; + int nargs; char castcontext; Relation relation; HeapTuple tuple; @@ -831,11 +832,6 @@ CreateCast(CreateCastStmt *stmt) errmsg("target data type %s does not exist", TypeNameToString(stmt->targettype)))); - if (sourcetypeid == targettypeid) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("source data type and target data type are the same"))); - /* No shells, no pseudo-types allowed */ if (!get_typisdefined(sourcetypeid)) ereport(ERROR, @@ -885,14 +881,23 @@ CreateCast(CreateCastStmt *stmt) elog(ERROR, "cache lookup failed for function %u", funcid); procstruct = (Form_pg_proc) GETSTRUCT(tuple); - if (procstruct->pronargs != 1) + nargs = procstruct->pronargs; + if (nargs < 1 || nargs > 3) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("cast function must take one argument"))); + errmsg("cast function must take one to three arguments"))); if (procstruct->proargtypes[0] != sourcetypeid) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("argument of cast function must match source data type"))); + if (nargs > 1 && procstruct->proargtypes[1] != INT4OID) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("second argument of cast function must be type integer"))); + if (nargs > 2 && procstruct->proargtypes[2] != BOOLOID) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("third argument of cast function must be type boolean"))); if (procstruct->prorettype != targettypeid) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), @@ -931,6 +936,7 @@ CreateCast(CreateCastStmt *stmt) /* indicates binary coercibility */ funcid = InvalidOid; + nargs = 0; /* * Must be superuser to create binary-compatible casts, since @@ -957,6 +963,15 @@ CreateCast(CreateCastStmt *stmt) errmsg("source and target data types are not physically compatible"))); } + /* + * Allow source and target types to be same only for length coercion + * functions. We assume a multi-arg function does length coercion. + */ + if (sourcetypeid == targettypeid && nargs < 2) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("source data type and target data type are the same"))); + /* convert CoercionContext enum to char value for castcontext */ switch (stmt->context) { |