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. --- doc/src/sgml/ref/create_type.sgml | 52 ++++++++++++++++++++++++++++----------- doc/src/sgml/xtypes.sgml | 21 +++++++++------- 2 files changed, 49 insertions(+), 24 deletions(-) (limited to 'doc/src') diff --git a/doc/src/sgml/ref/create_type.sgml b/doc/src/sgml/ref/create_type.sgml index a39c244c6c7..9382395182a 100644 --- a/doc/src/sgml/ref/create_type.sgml +++ b/doc/src/sgml/ref/create_type.sgml @@ -1,5 +1,5 @@ @@ -37,6 +37,8 @@ CREATE TYPE name ( [ , ELEMENT = element ] [ , DELIMITER = delimiter ] ) + +CREATE TYPE name @@ -142,17 +144,16 @@ CREATE TYPE name ( You should at this point be wondering how the input and output functions - can be declared to have results or arguments of the new type, when they have - to be created before the new type can be created. The answer is that the - input function must be created first, then the output function (and - the binary I/O functions if wanted), and finally the data type. - PostgreSQL will first see the name of the new - data type as the return type of the input function. It will create a - shell type, which is simply a placeholder entry in - the system catalog, and link the input function definition to the shell - type. Similarly the other functions will be linked to the (now already - existing) shell type. Finally, CREATE TYPE replaces the - shell entry with a complete type definition, and the new type can be used. + can be declared to have results or arguments of the new type, when they + have to be created before the new type can be created. The answer is that + the type should first be defined as a shell type, which is a + placeholder type that has no properties except a name and an owner. This + is done by issuing the command CREATE TYPE + name, with no additional parameters. Then the + I/O functions can be defined referencing the shell type. Finally, + CREATE TYPE with a full definition replaces the shell entry + with a complete, valid type definition, after which the new type can be + used normally. @@ -457,17 +458,33 @@ CREATE TYPE name ( while converting it to or from external form. + + Before PostgreSQL version 8.2, the syntax + CREATE TYPE name did not exist. + The way to create a new base type was to create its input function first. + In this approach, PostgreSQL will first see + the name of the new data type as the return type of the input function. + The shell type is implicitly created in this situation, and then it + can be referenced in the definitions of the remaining I/O functions. + This approach still works, but is deprecated and may be disallowed in + some future release. Also, to avoid accidentally cluttering + the catalogs with shell types as a result of simple typos in function + definitions, a shell type will only be made this way when the input + function is written in C. + + In PostgreSQL versions before 7.3, it - was customary to avoid creating a shell type by replacing the + was customary to avoid creating a shell type at all, by replacing the functions' forward references to the type name with the placeholder pseudotype opaque. The cstring arguments and results also had to be declared as opaque before 7.3. To support loading of old dump files, CREATE TYPE will - accept functions declared using opaque, but it will issue - a notice and change the function's declaration to use the correct + accept I/O functions declared using opaque, but it will issue + a notice and change the function declarations to use the correct types. + @@ -489,6 +506,11 @@ $$ LANGUAGE SQL; This example creates the base data type box and then uses the type in a table definition: +CREATE TYPE box; + +CREATE FUNCTION my_box_in_function(cstring) RETURNS box AS ... ; +CREATE FUNCTION my_box_out_function(box) RETURNS cstring AS ... ; + CREATE TYPE box ( INTERNALLENGTH = 16, INPUT = my_box_in_function, diff --git a/doc/src/sgml/xtypes.sgml b/doc/src/sgml/xtypes.sgml index 22d11a6300b..95723360e70 100644 --- a/doc/src/sgml/xtypes.sgml +++ b/doc/src/sgml/xtypes.sgml @@ -1,5 +1,5 @@ @@ -168,8 +168,16 @@ complex_send(PG_FUNCTION_ARGS) - To define the complex type, we need to create the - user-defined I/O functions before creating the type: + Once we have written the I/O functions and compiled them into a shared + library, we can define the complex type in SQL. + First we declare it as a shell type: + + +CREATE TYPE complex; + + + This serves as a placeholder that allows us to reference the type while + defining its I/O functions. Now we can define the I/O functions: CREATE FUNCTION complex_in(cstring) @@ -192,15 +200,10 @@ CREATE FUNCTION complex_send(complex) AS 'filename' LANGUAGE C IMMUTABLE STRICT; - - Notice that the declarations of the input and output functions must - reference the not-yet-defined type. This is allowed, but will draw - warning messages that may be ignored. The input function must - appear first. - Finally, we can declare the data type: + Finally, we can provide the full definition of the data type: CREATE TYPE complex ( internallength = 16, -- cgit v1.2.3