From 3d5ddc0b3cea3d7c8366ee1bdee108af0492da52 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 3 Nov 2001 21:42:47 +0000 Subject: [PATCH] Clean up wrong, misleading, or obsolete documentation about array types, particularly in the CREATE TYPE reference page. Fix some other errors in the CREATE TYPE page, too. --- doc/src/sgml/array.sgml | 11 +- doc/src/sgml/catalogs.sgml | 31 +++-- doc/src/sgml/ref/create_type.sgml | 180 ++++++++++++++++++------------ doc/src/sgml/ref/drop_type.sgml | 6 +- 4 files changed, 139 insertions(+), 89 deletions(-) diff --git a/doc/src/sgml/array.sgml b/doc/src/sgml/array.sgml index 4f57f2f0e2..a6ea373d2a 100644 --- a/doc/src/sgml/array.sgml +++ b/doc/src/sgml/array.sgml @@ -1,4 +1,4 @@ - + Arrays @@ -23,15 +23,15 @@ CREATE TABLE sal_emp ( sal_emp with a text string (name), a one-dimensional array of type integer (pay_by_quarter), - which shall represent the employee's salary by quarter, and a + which represents the employee's salary by quarter, and a two-dimensional array of text (schedule), which represents the employee's weekly schedule. - Now we do some INSERTs; note that when appending - to an array, we enclose the values within braces and separate them + Now we do some INSERTs. Observe that to write an array + value, we enclose the element values within braces and separate them by commas. If you know C, this is not unlike the syntax for initializing structures. @@ -200,8 +200,7 @@ SELECT * FROM sal_emp WHERE pay_by_quarter[1] = 10000 OR However, this quickly becomes tedious for large arrays, and is not helpful if the size of the array is unknown. Although it is not part of the primary PostgreSQL distribution, - in the contributions directory, there is an extension to - PostgreSQL that defines new functions and + there is an extension available that defines new functions and operators for iterating over array values. Using this, the above query could be: diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index b5e7fffe8e..7903112ec9 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -1,6 +1,6 @@ @@ -420,7 +420,9 @@ int4 - Number of dimensions, if the column is an array; otherwise 0. + Number of dimensions, if the column is an array type; otherwise 0. + (Presently, the number of dimensions of an array is not enforced, + so any nonzero value effectively means it's an array.) @@ -1064,7 +1066,7 @@ int2vector pg_attribute.attnum - This is an vector (array) of up to + This is a vector (array) of up to INDEX_MAX_KEYS values that indicate which table columns this index pertains to. For example a value of 1 3 would mean that the first and the third @@ -2336,7 +2338,9 @@ typdelim char - Character that separates two values of this type when parsing array input + Character that separates two values of this type when parsing + array input. Note that the delimiter is associated with the array + element datatype, not the array datatype. @@ -2360,14 +2364,17 @@ If typelem is not 0 then it identifies another row in pg_type. The current type can then be subscripted like an array yielding - values of type typelem. A non-zero - typelem does not guarantee this type - to be a real array type; some ordinary - fixed-length types can also be subscripted (e.g., - oidvector). Variable-length types can - not be turned into pseudo-arrays like - that. Hence, the way to determine whether a type is a - true array type is typelem != 0 and typlen < 0. + values of type typelem. A + true array type is variable length + (typlen = -1), + but some fixed-length (typlen > 0) types + also have nonzero typelem, for example + name and oidvector. + If a fixed-length type has a typelem then + its internal representation must be N values of the + typelem datatype with no other data. + Variable-length array types have a header defined by the array + subroutines. diff --git a/doc/src/sgml/ref/create_type.sgml b/doc/src/sgml/ref/create_type.sgml index 319a4824e6..0ae5a560b4 100644 --- a/doc/src/sgml/ref/create_type.sgml +++ b/doc/src/sgml/ref/create_type.sgml @@ -1,5 +1,5 @@ @@ -27,7 +27,7 @@ CREATE TYPE typename ( INPUT = internallength | VARIABLE } [ , EXTERNALLENGTH = { externallength | VARIABLE } ] - [ , DEFAULT = "default" ] + [ , DEFAULT = default ] [ , ELEMENT = element ] [ , DELIMITER = delimiter ] [ , SEND = send_function ] [ , RECEIVE = receive_function ] [ , PASSEDBYVALUE ] @@ -113,7 +113,8 @@ CREATE TYPE typename ( INPUT = delimiter - The delimiter character for the array elements. + The delimiter character to be used between values in arrays made + of this type. @@ -219,82 +220,101 @@ CREATE CREATE TYPE requires the registration of two functions - (using create function) before defining the type. The + (using CREATE FUNCTION) before defining the type. The representation of a new base type is determined by input_function, which converts the type's external representation to an internal representation usable by the operators and functions defined for the type. Naturally, output_function - performs the reverse transformation. Both - the input and output functions must be declared to take - one or two arguments of type opaque. + performs the reverse transformation. The input function may be + declared as taking one argument of type opaque, + or as taking three arguments of types + opaque, OID, int4. + (The first argument is the input text as a C string, the second + argument is the element type in case this is an array type, + and the third is the typmod of the destination column, if known.) + The output function may be + declared as taking one argument of type opaque, + or as taking two arguments of types + opaque, OID. + (The first argument is actually of the datatype itself, but since the + output function must be declared first, it's easier to declare it as + accepting type opaque. The second argument is again + the array element type for array types.) New base data types can be fixed length, in which case internallength is a - positive integer, or variable length, - in which case PostgreSQL assumes that the new type has the - same format - as the PostgreSQL-supplied data type, text. - To indicate that a type is variable length, set + positive integer, or variable length, indicated by setting internallength - to . - The external representation is similarly specified using the + to . (Internally, this is represented + by setting typlen to -1.) The internal representation of all + variable-length types must start with an integer giving the total + length of this value of the type. + + + + The external representation length is similarly specified using the externallength - keyword. + keyword. (This value is not presently used, and is typically omitted, + letting it default to .) - To indicate that a type is an array and to indicate that a - type has array elements, indicate the type of the array - element using the element keyword. For example, to define + To indicate that a type is an array, + specify the type of the array + elements using the - To indicate the delimiter to be used on arrays of this - type, delimiter - can be + To indicate the delimiter to be used between values in the external + representation of arrays of this type, delimiter can be set to a specific character. The default delimiter is the comma - (","). + (','). Note that the delimiter is associated + with the array element type, not the array type itself. - A default value is optionally available in case a user - wants some specific bit pattern to mean data not present. - Specify the default with the DEFAULT keyword. - How does the user specify that bit pattern and associate - it with the fact that the data is not present> + A default value may be specified, in case a user wants columns of the + datatype to default to something other than NULL. + Specify the default with the keyword. + (Such a default may be overridden by an explicit + clause attached to a particular column.) The optional arguments send_function and receive_function - are used when the application program requesting PostgreSQL - services resides on a different machine. In this case, - the machine on which PostgreSQL runs may use a format for the data - type different from that used on the remote machine. - In this case it is appropriate to convert data items to a - standard form when sending from the server to the client - and converting from the standard format to the machine - specific format when the server receives the data from the - client. If these functions are not specified, then it is - assumed that the internal format of the type is acceptable - on all relevant machine architectures. For example, single - characters do not have to be converted if passed from - a Sun-4 to a DECstation, but many other types do. + are not currently used, and are usually omitted (allowing them + to default to the + output_function and + input_function + respectively). These functions may someday be resurrected for use + in specifying machine-independent binary representations. - The optional flag, , indicates that operators - and functions which use this data type should be passed an - argument by value rather than by reference. Note that you + The optional flag, , indicates that + values of this data type are passed + by value rather than by reference. Note that you may not pass by value types whose internal representation is - more than four bytes. + longer than the width of the Datum type (four bytes on + most machines, eight bytes on a few). + + + + The alignment keyword + specifies the storage alignment required for the datatype. The + allowed values equate to alignment on 1, 2, 4, or 8 byte boundaries. + Note that variable-length types must have an alignment of at least + 4, since they necessarily contain an int4 as their first component. @@ -315,19 +335,40 @@ CREATE extended and external items.) - - For new base types, a user can define operators, functions - and aggregates using the appropriate facilities described - in this section. - - Array Types + - Two generalized built-in functions, array_in and - array_out, exist for quick creation of variable-length - array types. These functions operate on arrays of any - existing PostgreSQL type. + Whenever a user-defined datatype is created, + PostgreSQL automatically creates an + associated array type, whose name consists of the base type's + name prepended with an underscore. The parser understands this + naming convention, and translates requests for columns of type + foo[] into requests for type _foo. + The implicitly-created array type is variable length and uses the + built-in input and output functions array_in and + array_out. + + + + You might reasonably ask why is there an + The only case where it's useful to use @@ -336,41 +377,42 @@ CREATE Notes - Type names cannot begin with the underscore character - (_) and can only be 31 - characters long. This is because PostgreSQL silently creates an - array type for each base type with a name consisting of the base - type's name prepended with an underscore. + User-defined type names cannot begin with the underscore character + (_) and can only be 30 + characters long (or in general NAMEDATALEN-2, rather than + the NAMEDATALEN-1 characters allowed for other names). + Type names beginning with underscore are + reserved for internally-created array type names. Examples - This command creates the box data type and then uses the + This example creates the box data type and then uses the type in a table definition: -CREATE TYPE box (INTERNALLENGTH = 8, +CREATE TYPE box (INTERNALLENGTH = 16, INPUT = my_procedure_1, OUTPUT = my_procedure_2); CREATE TABLE myboxes (id INT4, description box); - This command creates a variable length array type with - integer elements: - + If box's internal structure were an array of four + float4s, we might instead say -CREATE TYPE int4array (INPUT = array_in, OUTPUT = array_out, - INTERNALLENGTH = VARIABLE, ELEMENT = int4); -CREATE TABLE myarrays (id int4, numbers int4array); +CREATE TYPE box (INTERNALLENGTH = 16, + INPUT = my_procedure_1, OUTPUT = my_procedure_2, + ELEMENT = float4); + which would allow a box value's component floats to be accessed + by subscripting. Otherwise the type behaves the same as before. - This command creates a large object type and uses it in + This example creates a large object type and uses it in a table definition: - CREATE TYPE bigobj (INPUT = lo_filein, OUTPUT = lo_fileout, INTERNALLENGTH = VARIABLE); diff --git a/doc/src/sgml/ref/drop_type.sgml b/doc/src/sgml/ref/drop_type.sgml index 174119ffc8..8bf9a8f382 100644 --- a/doc/src/sgml/ref/drop_type.sgml +++ b/doc/src/sgml/ref/drop_type.sgml @@ -1,5 +1,5 @@ @@ -105,7 +105,9 @@ ERROR: RemoveType: type 'typename' It is the user's responsibility to remove any operators, functions, aggregates, access methods, subtypes, and tables that - use a deleted type. + use a deleted type. However, the associated array datatype + (which was automatically created by CREATE TYPE) + will be removed automatically. -- GitLab