diff options
Diffstat (limited to 'src/backend')
| -rw-r--r-- | src/backend/catalog/heap.c | 4 | ||||
| -rw-r--r-- | src/backend/catalog/pg_type.c | 30 | ||||
| -rw-r--r-- | src/backend/commands/typecmds.c | 280 | ||||
| -rw-r--r-- | src/backend/utils/adt/arrayfuncs.c | 30 | ||||
| -rw-r--r-- | src/backend/utils/adt/pseudotypes.c | 24 |
5 files changed, 267 insertions, 101 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 5a6ec98e1b..ea70765d43 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.242 2003/04/29 22:13:08 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.243 2003/05/08 22:19:56 tgl Exp $ * * * INTERFACE ROUTINES @@ -675,6 +675,8 @@ AddNewRelationType(const char *typeName, ',', /* default array delimiter */ F_RECORD_IN, /* input procedure */ F_RECORD_OUT, /* output procedure */ + F_RECORD_RECV, /* receive procedure */ + F_RECORD_SEND, /* send procedure */ InvalidOid, /* array element type - irrelevant */ InvalidOid, /* domain base type - irrelevant */ NULL, /* default type value - none */ diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c index 66b6788eee..90ad20f2d5 100644 --- a/src/backend/catalog/pg_type.c +++ b/src/backend/catalog/pg_type.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.86 2003/01/08 21:40:39 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.87 2003/05/08 22:19:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -84,6 +84,8 @@ TypeShellMake(const char *typeName, Oid typeNamespace) values[i++] = ObjectIdGetDatum(InvalidOid); /* typelem */ values[i++] = ObjectIdGetDatum(InvalidOid); /* typinput */ values[i++] = ObjectIdGetDatum(InvalidOid); /* typoutput */ + values[i++] = ObjectIdGetDatum(InvalidOid); /* typreceive */ + values[i++] = ObjectIdGetDatum(InvalidOid); /* typsend */ values[i++] = CharGetDatum('i'); /* typalign */ values[i++] = CharGetDatum('p'); /* typstorage */ values[i++] = BoolGetDatum(false); /* typnotnull */ @@ -117,6 +119,8 @@ TypeShellMake(const char *typeName, Oid typeNamespace) InvalidOid, InvalidOid, InvalidOid, + InvalidOid, + InvalidOid, NULL, false); @@ -151,6 +155,8 @@ TypeCreate(const char *typeName, char typDelim, Oid inputProcedure, Oid outputProcedure, + Oid receiveProcedure, + Oid sendProcedure, Oid elementType, Oid baseType, const char *defaultTypeValue, /* human readable rep */ @@ -222,6 +228,8 @@ TypeCreate(const char *typeName, values[i++] = ObjectIdGetDatum(elementType); /* typelem */ values[i++] = ObjectIdGetDatum(inputProcedure); /* typinput */ values[i++] = ObjectIdGetDatum(outputProcedure); /* typoutput */ + values[i++] = ObjectIdGetDatum(receiveProcedure); /* typreceive */ + values[i++] = ObjectIdGetDatum(sendProcedure); /* typsend */ values[i++] = CharGetDatum(alignment); /* typalign */ values[i++] = CharGetDatum(storage); /* typstorage */ values[i++] = BoolGetDatum(typeNotNull); /* typnotnull */ @@ -314,6 +322,8 @@ TypeCreate(const char *typeName, relationKind, inputProcedure, outputProcedure, + receiveProcedure, + sendProcedure, elementType, baseType, (defaultTypeBin ? @@ -345,6 +355,8 @@ GenerateTypeDependencies(Oid typeNamespace, char relationKind, /* ditto */ Oid inputProcedure, Oid outputProcedure, + Oid receiveProcedure, + Oid sendProcedure, Oid elementType, Oid baseType, Node *defaultExpr, @@ -388,6 +400,22 @@ GenerateTypeDependencies(Oid typeNamespace, recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } + if (OidIsValid(receiveProcedure)) + { + referenced.classId = RelOid_pg_proc; + referenced.objectId = receiveProcedure; + referenced.objectSubId = 0; + recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + } + + if (OidIsValid(sendProcedure)) + { + referenced.classId = RelOid_pg_proc; + referenced.objectId = sendProcedure; + referenced.objectSubId = 0; + recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + } + /* * If the type is a rowtype for a relation, mark it as internally * dependent on the relation, *unless* it is a stand-alone diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 0523878f2a..f7bf3d3ee8 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, diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c index 9fee8516b8..f713fda7d5 100644 --- a/src/backend/utils/adt/arrayfuncs.c +++ b/src/backend/utils/adt/arrayfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.87 2003/04/08 23:20:02 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.88 2003/05/08 22:19:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -752,6 +752,34 @@ array_out(PG_FUNCTION_ARGS) PG_RETURN_CSTRING(retval); } +/*--------------------------------------------------------------------- + * array_recv : + * converts an array from the external binary format to + * its internal format. + * return value : + * the internal representation of the input array + *-------------------------------------------------------------------- + */ +Datum +array_recv(PG_FUNCTION_ARGS) +{ + elog(ERROR, "array_recv: not implemented yet"); + return 0; +} + +/*------------------------------------------------------------------------- + * array_send : + * takes the internal representation of an array and returns a bytea + * containing the array in its external binary format. + *------------------------------------------------------------------------- + */ +Datum +array_send(PG_FUNCTION_ARGS) +{ + elog(ERROR, "array_send: not implemented yet"); + return 0; +} + /*------------------------------------------------------------------------- * array_length_coerce : * Apply the element type's length-coercion routine to each element diff --git a/src/backend/utils/adt/pseudotypes.c b/src/backend/utils/adt/pseudotypes.c index 8d7b77202c..59b3185918 100644 --- a/src/backend/utils/adt/pseudotypes.c +++ b/src/backend/utils/adt/pseudotypes.c @@ -16,7 +16,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/pseudotypes.c,v 1.5 2003/04/08 23:20:02 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/pseudotypes.c,v 1.6 2003/05/08 22:19:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -48,6 +48,28 @@ record_out(PG_FUNCTION_ARGS) PG_RETURN_VOID(); /* keep compiler quiet */ } +/* + * record_recv - binary input routine for pseudo-type RECORD. + */ +Datum +record_recv(PG_FUNCTION_ARGS) +{ + elog(ERROR, "Cannot accept a constant of type %s", "RECORD"); + + PG_RETURN_VOID(); /* keep compiler quiet */ +} + +/* + * record_send - binary output routine for pseudo-type RECORD. + */ +Datum +record_send(PG_FUNCTION_ARGS) +{ + elog(ERROR, "Cannot display a value of type %s", "RECORD"); + + PG_RETURN_VOID(); /* keep compiler quiet */ +} + /* * cstring_in - input routine for pseudo-type CSTRING. |
