diff options
Diffstat (limited to 'doc/src')
-rw-r--r-- | doc/src/sgml/catalogs.sgml | 38 | ||||
-rw-r--r-- | doc/src/sgml/ref/create_type.sgml | 76 |
2 files changed, 90 insertions, 24 deletions
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index 79069ddfabe..62711ee83ff 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -8742,24 +8742,36 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l <row> <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>typsubscript</structfield> <type>regproc</type> + (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>) + </para> + <para> + Subscripting handler function's OID, or zero if this type doesn't + support subscripting. Types that are <quote>true</quote> array + types have <structfield>typsubscript</structfield> + = <function>array_subscript_handler</function>, but other types may + have other handler functions to implement specialized subscripting + behavior. + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> <structfield>typelem</structfield> <type>oid</type> (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>) </para> <para> If <structfield>typelem</structfield> is not 0 then it - identifies another row in <structname>pg_type</structname>. - The current type can then be subscripted like an array yielding - values of type <structfield>typelem</structfield>. A - <quote>true</quote> array type is variable length - (<structfield>typlen</structfield> = -1), - but some fixed-length (<structfield>typlen</structfield> > 0) types - also have nonzero <structfield>typelem</structfield>, for example - <type>name</type> and <type>point</type>. - If a fixed-length type has a <structfield>typelem</structfield> then - its internal representation must be some number of values of the - <structfield>typelem</structfield> data type with no other data. - Variable-length array types have a header defined by the array - subroutines. + identifies another row in <structname>pg_type</structname>, + defining the type yielded by subscripting. This should be 0 + if <structfield>typsubscript</structfield> is 0. However, it can + be 0 when <structfield>typsubscript</structfield> isn't 0, if the + handler doesn't need <structfield>typelem</structfield> to + determine the subscripting result type. + Note that a <structfield>typelem</structfield> dependency is + considered to imply physical containment of the element type in + this type; so DDL changes on the element type might be restricted + by the presence of this type. </para></entry> </row> diff --git a/doc/src/sgml/ref/create_type.sgml b/doc/src/sgml/ref/create_type.sgml index 970b517db9f..d909ee0d33b 100644 --- a/doc/src/sgml/ref/create_type.sgml +++ b/doc/src/sgml/ref/create_type.sgml @@ -43,6 +43,7 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> ( [ , TYPMOD_IN = <replaceable class="parameter">type_modifier_input_function</replaceable> ] [ , TYPMOD_OUT = <replaceable class="parameter">type_modifier_output_function</replaceable> ] [ , ANALYZE = <replaceable class="parameter">analyze_function</replaceable> ] + [ , SUBSCRIPT = <replaceable class="parameter">subscript_function</replaceable> ] [ , INTERNALLENGTH = { <replaceable class="parameter">internallength</replaceable> | VARIABLE } ] [ , PASSEDBYVALUE ] [ , ALIGNMENT = <replaceable class="parameter">alignment</replaceable> ] @@ -196,8 +197,9 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> <replaceable class="parameter">receive_function</replaceable>, <replaceable class="parameter">send_function</replaceable>, <replaceable class="parameter">type_modifier_input_function</replaceable>, - <replaceable class="parameter">type_modifier_output_function</replaceable> and - <replaceable class="parameter">analyze_function</replaceable> + <replaceable class="parameter">type_modifier_output_function</replaceable>, + <replaceable class="parameter">analyze_function</replaceable>, and + <replaceable class="parameter">subscript_function</replaceable> are optional. Generally these functions have to be coded in C or another low-level language. </para> @@ -319,6 +321,26 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> </para> <para> + The optional <replaceable class="parameter">subscript_function</replaceable> + allows the data type to be subscripted in SQL commands. Specifying this + function does not cause the type to be considered a <quote>true</quote> + array type; for example, it will not be a candidate for the result type + of <literal>ARRAY[]</literal> constructs. But if subscripting a value + of the type is a natural notation for extracting data from it, then + a <replaceable class="parameter">subscript_function</replaceable> can + be written to define what that means. The subscript function must be + declared to take a single argument of type <type>internal</type>, and + return an <type>internal</type> result, which is a pointer to a struct + of methods (functions) that implement subscripting. + The detailed API for subscript functions appears + in <filename>src/include/nodes/subscripting.h</filename>; + it may also be useful to read the array implementation + in <filename>src/backend/utils/adt/arraysubs.c</filename>. + Additional information appears in + <xref linkend="sql-createtype-array"/> below. + </para> + + <para> While the details of the new type's internal representation are only known to the I/O functions and other functions you create to work with the type, there are several properties of the internal representation @@ -428,11 +450,12 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> </para> <para> - To indicate that a type is an array, specify the type of the array + To indicate that a type is a fixed-length array type, + specify the type of the array elements using the <literal>ELEMENT</literal> key word. For example, to define an array of 4-byte integers (<type>int4</type>), specify - <literal>ELEMENT = int4</literal>. More details about array types - appear below. + <literal>ELEMENT = int4</literal>. For more details, + see <xref linkend="sql-createtype-array"/> below. </para> <para> @@ -456,7 +479,7 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> </para> </refsect2> - <refsect2> + <refsect2 id="sql-createtype-array" xreflabel="Array Types"> <title>Array Types</title> <para> @@ -469,14 +492,16 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> repeated until a non-colliding name is found.) This implicitly-created array type is variable length and uses the built-in input and output functions <literal>array_in</literal> and - <literal>array_out</literal>. The array type tracks any changes in its + <literal>array_out</literal>. Furthermore, this type is what the system + uses for constructs such as <literal>ARRAY[]</literal> over the + user-defined type. The array type tracks any changes in its element type's owner or schema, and is dropped if the element type is. </para> <para> You might reasonably ask why there is an <option>ELEMENT</option> option, if the system makes the correct array type automatically. - The only case where it's useful to use <option>ELEMENT</option> is when you are + The main case where it's useful to use <option>ELEMENT</option> is when you are making a fixed-length type that happens to be internally an array of a number of identical things, and you want to allow these things to be accessed directly by subscripting, in addition to whatever operations you plan @@ -485,13 +510,32 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> using <literal>point[0]</literal> and <literal>point[1]</literal>. Note that this facility only works for fixed-length types whose internal form - is exactly a sequence of identical fixed-length fields. A subscriptable - variable-length type must have the generalized internal representation - used by <literal>array_in</literal> and <literal>array_out</literal>. + is exactly a sequence of identical fixed-length fields. For historical reasons (i.e., this is clearly wrong but it's far too late to change it), subscripting of fixed-length array types starts from zero, rather than from one as for variable-length arrays. </para> + + <para> + Specifying the <option>SUBSCRIPT</option> option allows a data type to + be subscripted, even though the system does not otherwise regard it as + an array type. The behavior just described for fixed-length arrays is + actually implemented by the <option>SUBSCRIPT</option> handler + function <function>raw_array_subscript_handler</function>, which is + used automatically if you specify <option>ELEMENT</option> for a + fixed-length type without also writing <option>SUBSCRIPT</option>. + </para> + + <para> + When specifying a custom <option>SUBSCRIPT</option> function, it is + not necessary to specify <option>ELEMENT</option> unless + the <option>SUBSCRIPT</option> handler function needs to + consult <structfield>typelem</structfield> to find out what to return. + Be aware that specifying <option>ELEMENT</option> causes the system to + assume that the new type contains, or is somehow physically dependent on, + the element type; thus for example changing properties of the element + type won't be allowed if there are any columns of the dependent type. + </para> </refsect2> </refsect1> @@ -655,6 +699,16 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> </varlistentry> <varlistentry> + <term><replaceable class="parameter">subscript_function</replaceable></term> + <listitem> + <para> + The name of a function that defines what subscripting a value of the + data type does. + </para> + </listitem> + </varlistentry> + + <varlistentry> <term><replaceable class="parameter">internallength</replaceable></term> <listitem> <para> |