mirror of https://github.com/postgres/postgres
Some preliminary documentation for composite-type stuff.
This commit is contained in:
parent
7845bfc095
commit
982d005d62
|
@ -1,4 +1,4 @@
|
|||
<!-- $PostgreSQL: pgsql/doc/src/sgml/array.sgml,v 1.34 2003/11/29 19:51:36 pgsql Exp $ -->
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/array.sgml,v 1.35 2004/06/07 04:04:47 tgl Exp $ -->
|
||||
|
||||
<sect1 id="arrays">
|
||||
<title>Arrays</title>
|
||||
|
@ -10,7 +10,8 @@
|
|||
<para>
|
||||
<productname>PostgreSQL</productname> allows columns of a table to be
|
||||
defined as variable-length multidimensional arrays. Arrays of any
|
||||
built-in type or user-defined type can be created.
|
||||
built-in or user-defined base type can be created. (Arrays of
|
||||
composite types or domains are not yet supported, however.)
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!--
|
||||
Documentation of the system catalogs, directed toward PostgreSQL developers
|
||||
$PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.85 2004/04/01 21:28:43 tgl Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.86 2004/06/07 04:04:47 tgl Exp $
|
||||
-->
|
||||
|
||||
<chapter id="catalogs">
|
||||
|
@ -957,8 +957,8 @@
|
|||
The catalog <structname>pg_class</structname> catalogs tables and most
|
||||
everything else that has columns or is otherwise similar to a
|
||||
table. This includes indexes (but see also
|
||||
<structname>pg_index</structname>), sequences, views, and some
|
||||
kinds of special relation; see <structfield>relkind</>.
|
||||
<structname>pg_index</structname>), sequences, views, composite types,
|
||||
and some kinds of special relation; see <structfield>relkind</>.
|
||||
Below, when we mean all of these
|
||||
kinds of objects we speak of <quote>relations</quote>. Not all
|
||||
columns are meaningful for all relation types.
|
||||
|
@ -999,8 +999,8 @@
|
|||
<entry><type>oid</type></entry>
|
||||
<entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry>
|
||||
<entry>
|
||||
The OID of the data type that corresponds to this table, if any
|
||||
(zero for indexes, which have no <structname>pg_type</> entry)
|
||||
The OID of the data type that corresponds to this table's rowtype,
|
||||
if any (zero for indexes, which have no <structname>pg_type</> entry)
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
|
@ -3420,7 +3420,7 @@
|
|||
<entry></entry>
|
||||
<entry>
|
||||
<structfield>typtype</structfield> is <literal>b</literal> for
|
||||
a base type, <literal>c</literal> for a composite type (i.e., a
|
||||
a base type, <literal>c</literal> for a composite type (e.g., a
|
||||
table's row type), <literal>d</literal> for a domain, or
|
||||
<literal>p</literal> for a pseudo-type. See also
|
||||
<structfield>typrelid</structfield> and
|
||||
|
@ -3461,7 +3461,7 @@
|
|||
<structname>pg_class</structname> entry doesn't really represent
|
||||
a table, but it is needed anyway for the type's
|
||||
<structname>pg_attribute</structname> entries to link to.)
|
||||
Zero for base types.
|
||||
Zero for non-composite types.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.144 2004/03/23 02:47:35 neilc Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.145 2004/06/07 04:04:47 tgl Exp $
|
||||
-->
|
||||
|
||||
<chapter id="datatype">
|
||||
|
@ -2879,6 +2879,8 @@ SELECT * FROM test;
|
|||
|
||||
&array;
|
||||
|
||||
&rowtypes;
|
||||
|
||||
<sect1 id="datatype-oid">
|
||||
<title>Object Identifier Types</title>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/extend.sgml,v 1.27 2003/11/29 19:51:37 pgsql Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/extend.sgml,v 1.28 2004/06/07 04:04:47 tgl Exp $
|
||||
-->
|
||||
|
||||
<chapter id="extend">
|
||||
|
@ -151,7 +151,7 @@ $PostgreSQL: pgsql/doc/src/sgml/extend.sgml,v 1.27 2003/11/29 19:51:37 pgsql Exp
|
|||
</para>
|
||||
|
||||
<para>
|
||||
Domains can be created using the <acronym>SQL</> commands
|
||||
Domains can be created using the <acronym>SQL</> command
|
||||
<command>CREATE DOMAIN</command>. Their creation and use is not
|
||||
discussed in this chapter.
|
||||
</para>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!-- $PostgreSQL: pgsql/doc/src/sgml/filelist.sgml,v 1.37 2004/04/20 01:11:49 momjian Exp $ -->
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/filelist.sgml,v 1.38 2004/06/07 04:04:47 tgl Exp $ -->
|
||||
|
||||
<!entity history SYSTEM "history.sgml">
|
||||
<!entity info SYSTEM "info.sgml">
|
||||
|
@ -17,6 +17,7 @@
|
|||
|
||||
<!-- user's guide -->
|
||||
<!entity array SYSTEM "array.sgml">
|
||||
<!entity rowtypes SYSTEM "rowtypes.sgml">
|
||||
<!entity datatype SYSTEM "datatype.sgml">
|
||||
<!entity ddl SYSTEM "ddl.sgml">
|
||||
<!entity dml SYSTEM "dml.sgml">
|
||||
|
|
|
@ -0,0 +1,261 @@
|
|||
<!-- $PostgreSQL: pgsql/doc/src/sgml/rowtypes.sgml,v 2.1 2004/06/07 04:04:47 tgl Exp $ -->
|
||||
|
||||
<sect1 id="rowtypes">
|
||||
<title>Composite Types</title>
|
||||
|
||||
<indexterm>
|
||||
<primary>composite type</primary>
|
||||
</indexterm>
|
||||
|
||||
<indexterm>
|
||||
<primary>row type</primary>
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
A <firstterm>composite type</> describes the structure of a row or record;
|
||||
it is in essence just a list of field names and their datatypes.
|
||||
<productname>PostgreSQL</productname> allows values of composite types to be
|
||||
used in many of the same ways that simple types can be used. For example, a
|
||||
column of a table can be declared to be of a composite type.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>Declaration of Composite Types</title>
|
||||
|
||||
<para>
|
||||
Here are two simple examples of defining composite types:
|
||||
<programlisting>
|
||||
CREATE TYPE complex AS (
|
||||
r double precision,
|
||||
i double precision
|
||||
);
|
||||
|
||||
CREATE TYPE inventory_item AS (
|
||||
name text,
|
||||
supplier_id integer,
|
||||
price numeric
|
||||
);
|
||||
</programlisting>
|
||||
The syntax is comparable to <command>CREATE TABLE</>, except that only
|
||||
field names and types can be specified; no constraints (such as <literal>NOT
|
||||
NULL</>) can presently be included. Note that the <literal>AS</> keyword
|
||||
is essential; without it, the system will think a quite different kind
|
||||
of <command>CREATE TYPE</> command is meant, and you'll get odd syntax
|
||||
errors.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Having defined the types, we can use them to create tables:
|
||||
|
||||
<programlisting>
|
||||
CREATE TABLE on_hand (
|
||||
item inventory_item,
|
||||
count integer
|
||||
);
|
||||
|
||||
INSERT INTO on_hand VALUES (ROW('fuzzy dice', 42, 1.99), 1000);
|
||||
</programlisting>
|
||||
|
||||
or functions:
|
||||
|
||||
<programlisting>
|
||||
CREATE FUNCTION price_extension(inventory_item, integer) RETURNS numeric
|
||||
AS 'SELECT $1.price * $2' LANGUAGE SQL;
|
||||
|
||||
SELECT price_extension(item, 10) FROM on_hand;
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Composite Value Input</title>
|
||||
|
||||
<indexterm>
|
||||
<primary>composite type</primary>
|
||||
<secondary>constant</secondary>
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
To write a composite value as a literal constant, enclose the field
|
||||
values within parentheses and separate them by commas. You may put double
|
||||
quotes around any field value, and must do so if it contains commas or
|
||||
parentheses. (More details appear below.) Thus, the general format of a
|
||||
composite constant is the following:
|
||||
<synopsis>
|
||||
'( <replaceable>val1</replaceable> , <replaceable>val2</replaceable> , ... )'
|
||||
</synopsis>
|
||||
An example is
|
||||
<programlisting>
|
||||
'("fuzzy dice",42,1.99)'
|
||||
</programlisting>
|
||||
which would be a valid value of the <literal>inventory_item</> type
|
||||
defined above. To make a field be NULL, write no characters at all
|
||||
in its position in the list. For example, this constant specifies
|
||||
a NULL third field:
|
||||
<programlisting>
|
||||
'("fuzzy dice",42,)'
|
||||
</programlisting>
|
||||
If you want an empty string rather than NULL, write double quotes:
|
||||
<programlisting>
|
||||
'("",42,)'
|
||||
</programlisting>
|
||||
Here the first field is a non-NULL empty string, the third is NULL.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
(These constants are actually only a special case of
|
||||
the generic type constants discussed in <xref
|
||||
linkend="sql-syntax-constants-generic">. The constant is initially
|
||||
treated as a string and passed to the composite-type input conversion
|
||||
routine. An explicit type specification might be necessary.)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <literal>ROW</literal> expression syntax may also be used to
|
||||
construct composite values. In most cases this is considerably
|
||||
simpler to use than the string-literal syntax, since you don't have
|
||||
to worry about multiple layers of quoting. We already used this
|
||||
method above:
|
||||
<programlisting>
|
||||
ROW('fuzzy dice', 42, 1.99)
|
||||
ROW('', 42, NULL)
|
||||
</programlisting>
|
||||
The ROW keyword is actually optional as long as you have more than one
|
||||
field in the expression, so these can simplify to
|
||||
<programlisting>
|
||||
('fuzzy dice', 42, 1.99)
|
||||
('', 42, NULL)
|
||||
</programlisting>
|
||||
The <literal>ROW</> expression syntax is discussed in more detail in <xref
|
||||
linkend="sql-syntax-row-constructors">.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Accessing Composite Types</title>
|
||||
|
||||
<para>
|
||||
To access a field of a composite column, one writes a dot and the field
|
||||
name, much like selecting a field from a table name. In fact, it's so
|
||||
much like selecting from a table name that you often have to use parentheses
|
||||
to keep from confusing the parser. For example, you might try to select
|
||||
some subfields from our <literal>on_hand</> example table with something
|
||||
like:
|
||||
|
||||
<programlisting>
|
||||
SELECT item.name FROM on_hand WHERE item.price > 9.99;
|
||||
</programlisting>
|
||||
|
||||
This will not work since the name <literal>item</> is taken to be a table
|
||||
name, not a field name, per SQL syntax rules. You must write it like this:
|
||||
|
||||
<programlisting>
|
||||
SELECT (item).name FROM on_hand WHERE (item).price > 9.99;
|
||||
</programlisting>
|
||||
|
||||
or if you need to use the table name as well (for instance in a multi-table
|
||||
query), like this:
|
||||
|
||||
<programlisting>
|
||||
SELECT (on_hand.item).name FROM on_hand WHERE (on_hand.item).price > 9.99;
|
||||
</programlisting>
|
||||
|
||||
Now the parenthesized object is correctly interpreted as a reference to
|
||||
the <literal>item</> column, and then the subfield can be selected from it.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Similar syntactic issues apply whenever you select a field from a composite
|
||||
value. For instance, to select just one field from the result of a function
|
||||
that returns a composite value, you'd need to write something like
|
||||
|
||||
<programlisting>
|
||||
SELECT (my_func(...)).field FROM ...
|
||||
</programlisting>
|
||||
|
||||
Without the extra parentheses, this will provoke a syntax error.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Composite Type Input and Output Syntax</title>
|
||||
|
||||
<para>
|
||||
The external text representation of a composite value consists of items that
|
||||
are interpreted according to the I/O conversion rules for the individual
|
||||
field types, plus decoration that indicates the composite structure.
|
||||
The decoration consists of parentheses (<literal>(</> and <literal>)</>)
|
||||
around the whole value, plus commas (<literal>,</>) between adjacent
|
||||
items. Whitespace outside the parentheses is ignored, but within the
|
||||
parentheses it is considered part of the field value, and may or may not be
|
||||
significant depending on the input conversion rules for the field datatype.
|
||||
For example, in
|
||||
<programlisting>
|
||||
'( 42)'
|
||||
</programlisting>
|
||||
the whitespace will be ignored if the field type is integer, but not if
|
||||
it is text.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
As shown previously, when writing a composite value you may write double
|
||||
quotes around any individual field value.
|
||||
You <emphasis>must</> do so if the field value would otherwise
|
||||
confuse the composite-value parser. In particular, fields containing
|
||||
parentheses, commas, double quotes, or backslashes must be double-quoted.
|
||||
To put a double quote or backslash in a quoted composite field value,
|
||||
precede it with a backslash. (Also, a pair of double quotes within a
|
||||
double-quoted field value is taken to represent a double quote character,
|
||||
analogously to the rules for single quotes in SQL literal strings.)
|
||||
Alternatively, you can use backslash-escaping to protect all data characters
|
||||
that would otherwise be taken as composite syntax.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
A completely empty field value (no characters at all between the commas
|
||||
or parentheses) represents a NULL. To write a value that is an empty
|
||||
string rather than NULL, write <literal>""</>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The composite output routine will put double quotes around field values
|
||||
if they are empty strings or contain parentheses, commas,
|
||||
double quotes, backslashes, or white space. (Doing so for white space
|
||||
is not essential, but aids legibility.) Double quotes and backslashes
|
||||
embedded in field values will be doubled.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Remember that what you write in an SQL command will first be interpreted
|
||||
as a string literal, and then as a composite. This doubles the number of
|
||||
backslashes you need. For example, to insert a <type>text</> field
|
||||
containing a double quote and a backslash in a composite
|
||||
value, you'd need to write
|
||||
<programlisting>
|
||||
INSERT ... VALUES ('("\\"\\\\")');
|
||||
</programlisting>
|
||||
The string-literal processor removes one level of backslashes, so that
|
||||
what arrives at the composite-value parser looks like
|
||||
<literal>("\"\\")</>. In turn, the string
|
||||
fed to the <type>text</> data type's input routine
|
||||
becomes <literal>"\</>. (If we were working
|
||||
with a data type whose input routine also treated backslashes specially,
|
||||
<type>bytea</> for example, we might need as many as eight backslashes
|
||||
in the command to get one backslash into the stored composite field.)
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<tip>
|
||||
<para>
|
||||
The <literal>ROW</> constructor syntax is usually easier to work with
|
||||
than the composite-literal syntax when writing composite values in SQL
|
||||
commands.
|
||||
In <literal>ROW</>, individual field values are written the same way
|
||||
they would be written when not members of a composite.
|
||||
</para>
|
||||
</tip>
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
|
@ -1,5 +1,5 @@
|
|||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/syntax.sgml,v 1.92 2004/05/16 23:22:07 neilc Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/syntax.sgml,v 1.93 2004/06/07 04:04:47 tgl Exp $
|
||||
-->
|
||||
|
||||
<chapter id="sql-syntax">
|
||||
|
@ -1496,18 +1496,24 @@ SELECT ARRAY(SELECT oid FROM pg_proc WHERE proname LIKE 'bytea%');
|
|||
<title>Row Constructors</title>
|
||||
|
||||
<indexterm>
|
||||
<primary>row</primary>
|
||||
<primary>composite type</primary>
|
||||
<secondary>constructor</secondary>
|
||||
</indexterm>
|
||||
|
||||
<indexterm>
|
||||
<primary>row type</primary>
|
||||
<secondary>constructor</secondary>
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
A row constructor is an expression that builds a row value from values
|
||||
A row constructor is an expression that builds a row value (also
|
||||
called a composite value) from values
|
||||
for its member fields. A row constructor consists of the key word
|
||||
<literal>ROW</literal>, a left parenthesis <literal>(</>, zero or more
|
||||
expressions (separated by commas) for the row field values, and finally
|
||||
a right parenthesis <literal>)</>. For example,
|
||||
<programlisting>
|
||||
SELECT myfunc(ROW(1,2.5,'this is a test'));
|
||||
SELECT ROW(1,2.5,'this is a test');
|
||||
</programlisting>
|
||||
The key word <literal>ROW</> is optional when there is more than one
|
||||
expression in the list.
|
||||
|
@ -1549,10 +1555,10 @@ SELECT getf1(CAST(ROW(11,'this is a test',2.5) AS myrowtype));
|
|||
</para>
|
||||
|
||||
<para>
|
||||
Row constructors have only limited uses, other than creating an argument
|
||||
value for a user-defined function that accepts a rowtype parameter, as
|
||||
illustrated above.
|
||||
It is possible to compare two row values or test a row with
|
||||
Row constructors can be used to build composite values to be stored
|
||||
in a composite-type table column, or to be passed to a function that
|
||||
accepts a composite parameter. Also,
|
||||
it is possible to compare two row values or test a row with
|
||||
<literal>IS NULL</> or <literal>IS NOT NULL</>, for example
|
||||
<programlisting>
|
||||
SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same');
|
||||
|
|
Loading…
Reference in New Issue