From 8e68d783902b0b47f377efa4a23a04ddeef272a8 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 28 Feb 2006 22:37:27 +0000 Subject: Allow the syntax CREATE TYPE foo, with no parameters, to permit explicit creation of a shell type. This allows a less hacky way of dealing with the mutual dependency between a datatype and its I/O functions: make a shell type, then make the functions, then define the datatype fully. We should fix pg_dump to handle things this way, but this commit just deals with the backend. Martijn van Oosterhout, with some corrections by Tom Lane. --- src/backend/commands/typecmds.c | 49 +++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 17 deletions(-) (limited to 'src/backend/commands/typecmds.c') diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 143695252f4..f8e1a2665cf 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.86 2006/01/13 18:06:45 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.87 2006/02/28 22:37:26 tgl Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -138,6 +138,37 @@ DefineType(List *names, List *parameters) errmsg("type names must be %d characters or less", NAMEDATALEN - 2))); + /* + * Look to see if type already exists (presumably as a shell; if not, + * TypeCreate will complain). If it doesn't, create it as a shell, so + * that the OID is known for use in the I/O function definitions. + */ + typoid = GetSysCacheOid(TYPENAMENSP, + CStringGetDatum(typeName), + ObjectIdGetDatum(typeNamespace), + 0, 0); + if (!OidIsValid(typoid)) + { + typoid = TypeShellMake(typeName, typeNamespace); + /* Make new shell type visible for modification below */ + CommandCounterIncrement(); + + /* + * If the command was a parameterless CREATE TYPE, we're done --- + * creating the shell type was all we're supposed to do. + */ + if (parameters == NIL) + return; + } + else + { + /* Complain if dummy CREATE TYPE and entry already exists */ + if (parameters == NIL) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("type \"%s\" already exists", typeName))); + } + foreach(pl, parameters) { DefElem *defel = (DefElem *) lfirst(pl); @@ -240,22 +271,6 @@ DefineType(List *names, List *parameters) (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("type output function must be specified"))); - /* - * Look to see if type already exists (presumably as a shell; if not, - * TypeCreate will complain). If it doesn't, create it as a shell, so - * that the OID is known for use in the I/O function definitions. - */ - typoid = GetSysCacheOid(TYPENAMENSP, - CStringGetDatum(typeName), - ObjectIdGetDatum(typeNamespace), - 0, 0); - if (!OidIsValid(typoid)) - { - typoid = TypeShellMake(typeName, typeNamespace); - /* Make new shell type visible for modification below */ - CommandCounterIncrement(); - } - /* * Convert I/O proc names to OIDs */ -- cgit v1.2.3