diff options
Diffstat (limited to 'src/backend/commands/typecmds.c')
-rw-r--r-- | src/backend/commands/typecmds.c | 280 |
1 files changed, 183 insertions, 97 deletions
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 0523878f2a7..f7bf3d3ee87 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.34 2003/04/29 22:13:08 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.35 2003/05/08 22:19:56 tgl Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -20,7 +20,7 @@ * NOTES * These things must be defined and committed in the following order: * "create function": - * input/output functions + * input/output, recv/send functions * "create type": * type * "create operator": @@ -73,7 +73,10 @@ typedef struct } RelToCheck; -static Oid findTypeIOFunction(List *procname, Oid typeOid, bool isOutput); +static Oid findTypeInputFunction(List *procname, Oid typeOid); +static Oid findTypeOutputFunction(List *procname, Oid typeOid); +static Oid findTypeReceiveFunction(List *procname, Oid typeOid); +static Oid findTypeSendFunction(List *procname, Oid typeOid); static List *get_rels_with_domain(Oid domainOid, LOCKMODE lockmode); static void domainOwnerCheck(HeapTuple tup, TypeName *typename); static char *domainAddConstraint(Oid domainOid, Oid domainNamespace, @@ -92,17 +95,21 @@ DefineType(List *names, List *parameters) char *typeName; Oid typeNamespace; AclResult aclresult; - int16 internalLength = -1; /* int2 */ + int16 internalLength = -1; /* default: variable-length */ Oid elemType = InvalidOid; List *inputName = NIL; List *outputName = NIL; + List *receiveName = NIL; + List *sendName = NIL; char *defaultValue = NULL; bool byValue = false; char delimiter = DEFAULT_TYPDELIM; char alignment = 'i'; /* default alignment */ - char storage = 'p'; /* default TOAST storage method */ + char storage = 'p'; /* default TOAST storage method */ Oid inputOid; Oid outputOid; + Oid receiveOid = InvalidOid; + Oid sendOid = InvalidOid; char *shadow_type; List *pl; Oid typoid; @@ -137,10 +144,10 @@ DefineType(List *names, List *parameters) inputName = defGetQualifiedName(defel); else if (strcasecmp(defel->defname, "output") == 0) outputName = defGetQualifiedName(defel); - else if (strcasecmp(defel->defname, "send") == 0) - ; /* ignored -- remove after 7.3 */ else if (strcasecmp(defel->defname, "receive") == 0) - ; /* ignored -- remove after 7.3 */ + receiveName = defGetQualifiedName(defel); + else if (strcasecmp(defel->defname, "send") == 0) + sendName = defGetQualifiedName(defel); else if (strcasecmp(defel->defname, "delimiter") == 0) { char *p = defGetString(defel); @@ -236,8 +243,12 @@ DefineType(List *names, List *parameters) /* * Convert I/O proc names to OIDs */ - inputOid = findTypeIOFunction(inputName, typoid, false); - outputOid = findTypeIOFunction(outputName, typoid, true); + inputOid = findTypeInputFunction(inputName, typoid); + outputOid = findTypeOutputFunction(outputName, typoid); + if (receiveName) + receiveOid = findTypeReceiveFunction(receiveName, typoid); + if (sendName) + sendOid = findTypeSendFunction(sendName, typoid); /* * Verify that I/O procs return the expected thing. If we see OPAQUE, @@ -269,6 +280,20 @@ DefineType(List *names, List *parameters) elog(ERROR, "Type output function %s must return cstring", NameListToString(outputName)); } + if (receiveOid) + { + resulttype = get_func_rettype(receiveOid); + if (resulttype != typoid) + elog(ERROR, "Type receive function %s must return %s", + NameListToString(receiveName), typeName); + } + if (sendOid) + { + resulttype = get_func_rettype(sendOid); + if (resulttype != BYTEAOID) + elog(ERROR, "Type send function %s must return bytea", + NameListToString(sendName)); + } /* * now have TypeCreate do all the real work. @@ -284,6 +309,8 @@ DefineType(List *names, List *parameters) delimiter, /* array element delimiter */ inputOid, /* input procedure */ outputOid, /* output procedure */ + receiveOid, /* receive procedure */ + sendOid, /* send procedure */ elemType, /* element type ID */ InvalidOid, /* base type ID (only for domains) */ defaultValue, /* default type value */ @@ -314,6 +341,8 @@ DefineType(List *names, List *parameters) DEFAULT_TYPDELIM, /* array element delimiter */ F_ARRAY_IN, /* input procedure */ F_ARRAY_OUT, /* output procedure */ + F_ARRAY_RECV, /* receive procedure */ + F_ARRAY_SEND, /* send procedure */ typoid, /* element type ID */ InvalidOid, /* base type ID */ NULL, /* never a default type value */ @@ -418,6 +447,8 @@ DefineDomain(CreateDomainStmt *stmt) int16 internalLength; Oid inputProcedure; Oid outputProcedure; + Oid receiveProcedure; + Oid sendProcedure; bool byValue; char delimiter; char alignment; @@ -495,6 +526,8 @@ DefineDomain(CreateDomainStmt *stmt) /* I/O Functions */ inputProcedure = baseType->typinput; outputProcedure = baseType->typoutput; + receiveProcedure = baseType->typreceive; + sendProcedure = baseType->typsend; /* Inherited default value */ datum = SysCacheGetAttr(TYPEOID, typeTup, @@ -628,6 +661,8 @@ DefineDomain(CreateDomainStmt *stmt) delimiter, /* array element delimiter */ inputProcedure, /* input procedure */ outputProcedure, /* output procedure */ + receiveProcedure, /* receive procedure */ + sendProcedure, /* send procedure */ basetypelem, /* element type ID */ basetypeoid, /* base type ID */ defaultValue, /* default type value (text) */ @@ -731,135 +766,184 @@ RemoveDomain(List *names, DropBehavior behavior) /* - * Find a suitable I/O function for a type. + * Find suitable I/O functions for a type. * * typeOid is the type's OID (which will already exist, if only as a shell * type). */ + static Oid -findTypeIOFunction(List *procname, Oid typeOid, bool isOutput) +findTypeInputFunction(List *procname, Oid typeOid) { Oid argList[FUNC_MAX_ARGS]; Oid procOid; - if (isOutput) + /* + * Input functions can take a single argument of type CSTRING, or + * three arguments (string, element OID, typmod). + * + * For backwards compatibility we allow OPAQUE in place of CSTRING; + * if we see this, we issue a NOTICE and fix up the pg_proc entry. + */ + MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); + + argList[0] = CSTRINGOID; + + procOid = LookupFuncName(procname, 1, argList); + if (OidIsValid(procOid)) + return procOid; + + argList[1] = OIDOID; + argList[2] = INT4OID; + + procOid = LookupFuncName(procname, 3, argList); + if (OidIsValid(procOid)) + return procOid; + + /* No luck, try it with OPAQUE */ + MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); + + argList[0] = OPAQUEOID; + + procOid = LookupFuncName(procname, 1, argList); + + if (!OidIsValid(procOid)) + { + argList[1] = OIDOID; + argList[2] = INT4OID; + + procOid = LookupFuncName(procname, 3, argList); + } + + if (OidIsValid(procOid)) { + /* Found, but must complain and fix the pg_proc entry */ + elog(NOTICE, "TypeCreate: changing argument type of function %s " + "from OPAQUE to CSTRING", + NameListToString(procname)); + SetFunctionArgType(procOid, 0, CSTRINGOID); /* - * Output functions can take a single argument of the type, or two - * arguments (data value, element OID). - * - * For backwards compatibility we allow OPAQUE in place of the actual - * type name; if we see this, we issue a NOTICE and fix up the - * pg_proc entry. + * Need CommandCounterIncrement since DefineType will likely + * try to alter the pg_proc tuple again. */ - MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); + CommandCounterIncrement(); - argList[0] = typeOid; + return procOid; + } - procOid = LookupFuncName(procname, 1, argList); - if (OidIsValid(procOid)) - return procOid; + /* Use CSTRING (preferred) in the error message */ + argList[0] = CSTRINGOID; - argList[1] = OIDOID; + func_error("TypeCreate", procname, 1, argList, NULL); - procOid = LookupFuncName(procname, 2, argList); - if (OidIsValid(procOid)) - return procOid; + return InvalidOid; /* keep compiler quiet */ +} - /* No luck, try it with OPAQUE */ - MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); +static Oid +findTypeOutputFunction(List *procname, Oid typeOid) +{ + Oid argList[FUNC_MAX_ARGS]; + Oid procOid; - argList[0] = OPAQUEOID; + /* + * Output functions can take a single argument of the type, or two + * arguments (data value, element OID). + * + * For backwards compatibility we allow OPAQUE in place of the actual + * type name; if we see this, we issue a NOTICE and fix up the + * pg_proc entry. + */ + MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); - procOid = LookupFuncName(procname, 1, argList); + argList[0] = typeOid; - if (!OidIsValid(procOid)) - { - argList[1] = OIDOID; + procOid = LookupFuncName(procname, 1, argList); + if (OidIsValid(procOid)) + return procOid; - procOid = LookupFuncName(procname, 2, argList); - } + argList[1] = OIDOID; - if (OidIsValid(procOid)) - { - /* Found, but must complain and fix the pg_proc entry */ - elog(NOTICE, "TypeCreate: changing argument type of function %s from OPAQUE to %s", - NameListToString(procname), format_type_be(typeOid)); - SetFunctionArgType(procOid, 0, typeOid); - /* - * Need CommandCounterIncrement since DefineType will likely - * try to alter the pg_proc tuple again. - */ - CommandCounterIncrement(); + procOid = LookupFuncName(procname, 2, argList); + if (OidIsValid(procOid)) + return procOid; - return procOid; - } + /* No luck, try it with OPAQUE */ + MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); + + argList[0] = OPAQUEOID; - /* Use type name, not OPAQUE, in the failure message. */ - argList[0] = typeOid; + procOid = LookupFuncName(procname, 1, argList); - func_error("TypeCreate", procname, 1, argList, NULL); + if (!OidIsValid(procOid)) + { + argList[1] = OIDOID; + + procOid = LookupFuncName(procname, 2, argList); } - else + + if (OidIsValid(procOid)) { + /* Found, but must complain and fix the pg_proc entry */ + elog(NOTICE, "TypeCreate: changing argument type of function %s from OPAQUE to %s", + NameListToString(procname), format_type_be(typeOid)); + SetFunctionArgType(procOid, 0, typeOid); /* - * Input functions can take a single argument of type CSTRING, or - * three arguments (string, element OID, typmod). - * - * For backwards compatibility we allow OPAQUE in place of CSTRING; - * if we see this, we issue a NOTICE and fix up the pg_proc entry. + * Need CommandCounterIncrement since DefineType will likely + * try to alter the pg_proc tuple again. */ - MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); + CommandCounterIncrement(); - argList[0] = CSTRINGOID; + return procOid; + } - procOid = LookupFuncName(procname, 1, argList); - if (OidIsValid(procOid)) - return procOid; + /* Use type name, not OPAQUE, in the failure message. */ + argList[0] = typeOid; - argList[1] = OIDOID; - argList[2] = INT4OID; + func_error("TypeCreate", procname, 1, argList, NULL); - procOid = LookupFuncName(procname, 3, argList); - if (OidIsValid(procOid)) - return procOid; + return InvalidOid; /* keep compiler quiet */ +} - /* No luck, try it with OPAQUE */ - MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); +static Oid +findTypeReceiveFunction(List *procname, Oid typeOid) +{ + Oid argList[FUNC_MAX_ARGS]; + Oid procOid; - argList[0] = OPAQUEOID; + /* + * Receive functions take a single argument of type INTERNAL. + */ + MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); - procOid = LookupFuncName(procname, 1, argList); + argList[0] = INTERNALOID; - if (!OidIsValid(procOid)) - { - argList[1] = OIDOID; - argList[2] = INT4OID; + procOid = LookupFuncName(procname, 1, argList); + if (OidIsValid(procOid)) + return procOid; - procOid = LookupFuncName(procname, 3, argList); - } + func_error("TypeCreate", procname, 1, argList, NULL); - if (OidIsValid(procOid)) - { - /* Found, but must complain and fix the pg_proc entry */ - elog(NOTICE, "TypeCreate: changing argument type of function %s " - "from OPAQUE to CSTRING", - NameListToString(procname)); - SetFunctionArgType(procOid, 0, CSTRINGOID); - /* - * Need CommandCounterIncrement since DefineType will likely - * try to alter the pg_proc tuple again. - */ - CommandCounterIncrement(); + return InvalidOid; /* keep compiler quiet */ +} - return procOid; - } +static Oid +findTypeSendFunction(List *procname, Oid typeOid) +{ + Oid argList[FUNC_MAX_ARGS]; + Oid procOid; - /* Use CSTRING (preferred) in the error message */ - argList[0] = CSTRINGOID; + /* + * Send functions take a single argument of the type. + */ + MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); - func_error("TypeCreate", procname, 1, argList, NULL); - } + argList[0] = typeOid; + + procOid = LookupFuncName(procname, 1, argList); + if (OidIsValid(procOid)) + return procOid; + + func_error("TypeCreate", procname, 1, argList, NULL); return InvalidOid; /* keep compiler quiet */ } @@ -1017,6 +1101,8 @@ AlterDomainDefault(List *names, Node *defaultRaw) 0, /* relation kind is n/a */ typTup->typinput, typTup->typoutput, + typTup->typreceive, + typTup->typsend, typTup->typelem, typTup->typbasetype, defaultExpr, |