2000-03-31 05:27:42 +02:00
|
|
|
<!--
|
2001-01-14 00:58:55 +01:00
|
|
|
$Header: /cvsroot/pgsql/doc/src/sgml/advanced.sgml,v 1.21 2001/01/13 23:58:55 petere Exp $
|
2000-03-31 05:27:42 +02:00
|
|
|
-->
|
|
|
|
|
1999-08-08 06:21:33 +02:00
|
|
|
<chapter id="advanced">
|
|
|
|
<title>Advanced <productname>Postgres</productname> <acronym>SQL</acronym> Features</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Having covered the basics of using
|
2000-03-31 00:22:41 +02:00
|
|
|
<productname>Postgres</productname> <acronym>SQL</acronym> to
|
1999-08-08 06:21:33 +02:00
|
|
|
access your data, we will now discuss those features of
|
|
|
|
<productname>Postgres</productname> that distinguish it from conventional data
|
|
|
|
managers. These features include inheritance, time
|
|
|
|
travel and non-atomic data values (array- and
|
|
|
|
set-valued attributes).
|
|
|
|
Examples in this section can also be found in
|
|
|
|
<filename>advance.sql</filename> in the tutorial directory.
|
|
|
|
(Refer to <xref linkend="QUERY"> for how to use it.)
|
|
|
|
</para>
|
|
|
|
|
2000-09-29 22:21:34 +02:00
|
|
|
<sect1 id="inheritance">
|
1999-08-08 06:21:33 +02:00
|
|
|
<title>Inheritance</title>
|
|
|
|
|
|
|
|
<para>
|
2001-01-14 00:58:55 +01:00
|
|
|
Let's create two tables. The capitals table contains
|
2000-12-22 19:57:50 +01:00
|
|
|
state capitals that are also cities. Naturally, the
|
2001-01-14 00:58:55 +01:00
|
|
|
capitals table should inherit from cities.
|
1999-08-08 06:21:33 +02:00
|
|
|
|
|
|
|
<programlisting>
|
1998-03-01 09:16:16 +01:00
|
|
|
CREATE TABLE cities (
|
|
|
|
name text,
|
2001-01-14 00:58:55 +01:00
|
|
|
population real,
|
1999-08-08 06:21:33 +02:00
|
|
|
altitude int -- (in ft)
|
1998-03-01 09:16:16 +01:00
|
|
|
);
|
|
|
|
|
2001-01-05 07:34:23 +01:00
|
|
|
CREATE TABLE capitals (
|
1999-08-08 06:21:33 +02:00
|
|
|
state char(2)
|
2001-01-05 07:34:23 +01:00
|
|
|
) INHERITS (cities);
|
1999-08-08 06:21:33 +02:00
|
|
|
</programlisting>
|
|
|
|
|
2001-01-14 00:58:55 +01:00
|
|
|
In this case, a row of capitals <firstterm>inherits</firstterm> all
|
|
|
|
columns (name, population, and altitude) from its
|
|
|
|
parent, cities. The type of the column name is
|
1999-08-08 06:21:33 +02:00
|
|
|
<type>text</type>, a native <productname>Postgres</productname>
|
|
|
|
type for variable length
|
2001-01-14 00:58:55 +01:00
|
|
|
ASCII strings. The type of the column population is
|
|
|
|
<type>real</type>, a type for single precision
|
1999-08-08 06:21:33 +02:00
|
|
|
floating point numbers. State capitals have an extra
|
2001-01-14 00:58:55 +01:00
|
|
|
column, state, that shows their state.
|
1999-08-08 06:21:33 +02:00
|
|
|
In <productname>Postgres</productname>,
|
2001-01-14 00:58:55 +01:00
|
|
|
a table can inherit from zero or more other tables,
|
|
|
|
and a query can reference either all rows of a
|
|
|
|
table or all rows of a tables plus all of its
|
1999-08-08 06:21:33 +02:00
|
|
|
descendants.
|
|
|
|
|
|
|
|
<note>
|
|
|
|
<para>
|
|
|
|
The inheritance hierarchy is a directed acyclic graph.
|
|
|
|
</para>
|
|
|
|
</note>
|
2000-06-14 15:12:52 +02:00
|
|
|
</para>
|
1999-08-08 06:21:33 +02:00
|
|
|
|
2000-06-14 15:12:52 +02:00
|
|
|
<para>
|
|
|
|
For example, the following query finds the names of all cities,
|
|
|
|
including state capitals, that are located at an altitude
|
2001-01-05 07:34:23 +01:00
|
|
|
over 500ft:
|
2000-06-09 03:44:34 +02:00
|
|
|
|
2000-06-14 15:12:52 +02:00
|
|
|
<programlisting>
|
2001-01-05 07:34:23 +01:00
|
|
|
SELECT name, altitude
|
|
|
|
FROM cities
|
|
|
|
WHERE altitude > 500;
|
2000-06-14 15:12:52 +02:00
|
|
|
</programlisting>
|
2000-06-09 03:44:34 +02:00
|
|
|
|
2000-06-14 15:12:52 +02:00
|
|
|
which returns:
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2000-06-14 15:12:52 +02:00
|
|
|
<programlisting>
|
1998-03-01 09:16:16 +01:00
|
|
|
+----------+----------+
|
|
|
|
|name | altitude |
|
|
|
|
+----------+----------+
|
|
|
|
|Las Vegas | 2174 |
|
|
|
|
+----------+----------+
|
|
|
|
|Mariposa | 1953 |
|
|
|
|
+----------+----------+
|
2000-06-09 03:44:34 +02:00
|
|
|
|Madison | 845 |
|
|
|
|
+----------+----------+
|
2000-06-14 15:12:52 +02:00
|
|
|
</programlisting>
|
|
|
|
</para>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2000-06-14 15:12:52 +02:00
|
|
|
<para>
|
|
|
|
On the other hand, the following query finds
|
2001-01-05 07:34:23 +01:00
|
|
|
all the cities that are not state capitals and
|
|
|
|
are situated at an altitude of 500ft or higher:
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2000-06-14 15:12:52 +02:00
|
|
|
<programlisting>
|
|
|
|
SELECT name, altitude
|
2000-06-09 03:44:34 +02:00
|
|
|
FROM ONLY cities
|
|
|
|
WHERE altitude > 500;
|
1998-03-01 09:16:16 +01:00
|
|
|
|
|
|
|
+----------+----------+
|
|
|
|
|name | altitude |
|
|
|
|
+----------+----------+
|
|
|
|
|Las Vegas | 2174 |
|
|
|
|
+----------+----------+
|
|
|
|
|Mariposa | 1953 |
|
|
|
|
+----------+----------+
|
2000-06-14 15:12:52 +02:00
|
|
|
</programlisting>
|
|
|
|
</para>
|
2000-06-09 03:44:34 +02:00
|
|
|
|
2000-06-14 15:12:52 +02:00
|
|
|
<para>
|
|
|
|
Here the <quote>ONLY</quote> before cities indicates that the query should
|
2001-01-14 00:58:55 +01:00
|
|
|
be run over only the cities table, and not tables below cities in the
|
2000-06-14 15:12:52 +02:00
|
|
|
inheritance hierarchy. Many of the commands that we
|
|
|
|
have already discussed -- <command>SELECT</command>,
|
|
|
|
<command>UPDATE</command> and <command>DELETE</command> --
|
|
|
|
support this <quote>ONLY</quote> notation.
|
|
|
|
</para>
|
1999-08-08 06:21:33 +02:00
|
|
|
|
2000-06-23 00:31:24 +02:00
|
|
|
<note>
|
|
|
|
<title>Deprecated</title>
|
|
|
|
<para>
|
|
|
|
In previous versions of <productname>Postgres</productname>, the
|
|
|
|
default was not to get access to child tables. This was found to
|
2001-01-05 07:34:23 +01:00
|
|
|
be error prone and is also in violation of SQL99. Under the old
|
2001-01-14 00:58:55 +01:00
|
|
|
syntax, to get the sub-tables you append "*" to the table name.
|
2000-06-23 00:31:24 +02:00
|
|
|
For example
|
|
|
|
<programlisting>
|
2000-06-14 15:12:52 +02:00
|
|
|
SELECT * from cities*;
|
2000-06-23 00:31:24 +02:00
|
|
|
</programlisting>
|
2001-01-05 07:34:23 +01:00
|
|
|
You can still explicitly specify scanning child tables by appending
|
|
|
|
"*", as well as explicitly specify not scanning child tables by
|
|
|
|
writing <quote>ONLY</quote>. But beginning in version 7.1, the default
|
|
|
|
behavior for an undecorated table name is to scan its child tables
|
|
|
|
too, whereas before the default was not to do so. To get the old
|
|
|
|
default behavior, set the configuration option
|
2000-06-23 00:31:24 +02:00
|
|
|
<literal>SQL_Inheritance</literal> to off, e.g.,
|
|
|
|
<programlisting>
|
|
|
|
SET SQL_Inheritance TO OFF;
|
|
|
|
</programlisting>
|
|
|
|
or add a line in your <filename>postgresql.conf</filename> file.
|
|
|
|
</para>
|
|
|
|
</note>
|
1999-08-08 06:21:33 +02:00
|
|
|
</sect1>
|
|
|
|
|
2000-09-29 22:21:34 +02:00
|
|
|
<sect1 id="non-atomic-values">
|
1999-08-08 06:21:33 +02:00
|
|
|
<title>Non-Atomic Values</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
One of the tenets of the relational model is that the
|
2001-01-14 00:58:55 +01:00
|
|
|
columns of a table are atomic.
|
2000-04-07 15:30:58 +02:00
|
|
|
<productname>Postgres</productname> does not
|
2001-01-14 00:58:55 +01:00
|
|
|
have this restriction; columns can themselves contain
|
1999-08-08 06:21:33 +02:00
|
|
|
sub-values that can be accessed from the query
|
2001-01-14 00:58:55 +01:00
|
|
|
language. For example, you can create columns that
|
1999-08-08 06:21:33 +02:00
|
|
|
are arrays of base types.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<sect2>
|
|
|
|
<title>Arrays</title>
|
|
|
|
|
|
|
|
<para>
|
2001-01-14 00:58:55 +01:00
|
|
|
<productname>Postgres</productname> allows columns of a
|
|
|
|
row to be defined
|
1998-03-01 09:16:16 +01:00
|
|
|
as fixed-length or variable-length multi-dimensional
|
|
|
|
arrays. Arrays of any base type or user-defined type
|
|
|
|
can be created. To illustrate their use, we first create a
|
2001-01-14 00:58:55 +01:00
|
|
|
table with arrays of base types.
|
1999-08-08 06:21:33 +02:00
|
|
|
|
|
|
|
<programlisting>
|
1998-03-01 09:16:16 +01:00
|
|
|
CREATE TABLE SAL_EMP (
|
|
|
|
name text,
|
2001-01-14 00:58:55 +01:00
|
|
|
pay_by_quarter integer[],
|
1998-04-26 06:18:06 +02:00
|
|
|
schedule text[][]
|
1998-03-01 09:16:16 +01:00
|
|
|
);
|
1999-08-08 06:21:33 +02:00
|
|
|
</programlisting>
|
|
|
|
</para>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-08-08 06:21:33 +02:00
|
|
|
<para>
|
2001-01-14 00:58:55 +01:00
|
|
|
The above query will create a table named SAL_EMP with
|
1999-08-08 06:21:33 +02:00
|
|
|
a <firstterm>text</firstterm> string (name), a one-dimensional
|
2001-01-14 00:58:55 +01:00
|
|
|
array of <firstterm>integer</firstterm>
|
1998-03-01 09:16:16 +01:00
|
|
|
(pay_by_quarter), which represents the employee's
|
2000-04-07 15:30:58 +02:00
|
|
|
salary by quarter and a two-dimensional array of
|
|
|
|
<firstterm>text</firstterm>
|
1998-03-01 09:16:16 +01:00
|
|
|
(schedule), which represents the employee's weekly
|
2000-12-19 00:39:37 +01:00
|
|
|
schedule. Now we do some <firstterm>INSERT</firstterm>s;
|
2000-04-07 15:30:58 +02:00
|
|
|
note that when
|
1998-03-01 09:16:16 +01:00
|
|
|
appending to an array, we enclose the values within
|
2000-04-07 15:30:58 +02:00
|
|
|
braces and separate them by commas. If you know
|
|
|
|
<firstterm>C</firstterm>,
|
1998-03-01 09:16:16 +01:00
|
|
|
this is not unlike the syntax for initializing structures.
|
1999-08-08 06:21:33 +02:00
|
|
|
|
|
|
|
<programlisting>
|
1998-03-01 09:16:16 +01:00
|
|
|
INSERT INTO SAL_EMP
|
|
|
|
VALUES ('Bill',
|
|
|
|
'{10000, 10000, 10000, 10000}',
|
|
|
|
'{{"meeting", "lunch"}, {}}');
|
|
|
|
|
|
|
|
INSERT INTO SAL_EMP
|
|
|
|
VALUES ('Carol',
|
|
|
|
'{20000, 25000, 25000, 25000}',
|
|
|
|
'{{"talk", "consult"}, {"meeting"}}');
|
1999-08-08 06:21:33 +02:00
|
|
|
</programlisting>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2000-04-07 15:30:58 +02:00
|
|
|
By default, <productname>Postgres</productname> uses the
|
|
|
|
"one-based" numbering
|
1999-08-08 06:21:33 +02:00
|
|
|
convention for arrays -- that is, an array of n elements
|
|
|
|
starts with array[1] and ends with array[n].
|
1998-03-01 09:16:16 +01:00
|
|
|
Now, we can run some queries on SAL_EMP. First, we
|
|
|
|
show how to access a single element of an array at a
|
|
|
|
time. This query retrieves the names of the employees
|
|
|
|
whose pay changed in the second quarter:
|
1999-08-08 06:21:33 +02:00
|
|
|
|
|
|
|
<programlisting>
|
1998-03-01 09:16:16 +01:00
|
|
|
SELECT name
|
|
|
|
FROM SAL_EMP
|
|
|
|
WHERE SAL_EMP.pay_by_quarter[1] <>
|
|
|
|
SAL_EMP.pay_by_quarter[2];
|
|
|
|
|
|
|
|
+------+
|
|
|
|
|name |
|
|
|
|
+------+
|
|
|
|
|Carol |
|
|
|
|
+------+
|
1999-08-08 06:21:33 +02:00
|
|
|
</programlisting>
|
|
|
|
</para>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-08-08 06:21:33 +02:00
|
|
|
<para>
|
1998-03-01 09:16:16 +01:00
|
|
|
This query retrieves the third quarter pay of all
|
|
|
|
employees:
|
|
|
|
|
1999-08-08 06:21:33 +02:00
|
|
|
<programlisting>
|
1998-03-01 09:16:16 +01:00
|
|
|
SELECT SAL_EMP.pay_by_quarter[3] FROM SAL_EMP;
|
|
|
|
|
|
|
|
|
|
|
|
+---------------+
|
|
|
|
|pay_by_quarter |
|
|
|
|
+---------------+
|
|
|
|
|10000 |
|
|
|
|
+---------------+
|
|
|
|
|25000 |
|
|
|
|
+---------------+
|
1999-08-08 06:21:33 +02:00
|
|
|
</programlisting>
|
|
|
|
</para>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-08-08 06:21:33 +02:00
|
|
|
<para>
|
2000-12-19 00:39:37 +01:00
|
|
|
We can also access arbitrary slices of an array (subarrays)
|
|
|
|
by specifying both lower and upper bounds for
|
|
|
|
each subscript. This query retrieves the first item on
|
1998-03-01 09:16:16 +01:00
|
|
|
Bill's schedule for the first two days of the week.
|
1999-08-08 06:21:33 +02:00
|
|
|
|
|
|
|
<programlisting>
|
1998-03-01 09:16:16 +01:00
|
|
|
SELECT SAL_EMP.schedule[1:2][1:1]
|
|
|
|
FROM SAL_EMP
|
|
|
|
WHERE SAL_EMP.name = 'Bill';
|
|
|
|
|
|
|
|
+-------------------+
|
|
|
|
|schedule |
|
|
|
|
+-------------------+
|
|
|
|
|{{"meeting"},{""}} |
|
|
|
|
+-------------------+
|
1999-08-08 06:21:33 +02:00
|
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
</sect1>
|
|
|
|
|
2000-09-29 22:21:34 +02:00
|
|
|
<sect1 id="more-advanced">
|
1999-08-08 06:21:33 +02:00
|
|
|
<title>More Advanced Features</title>
|
|
|
|
|
|
|
|
<para>
|
2000-04-07 15:30:58 +02:00
|
|
|
<productname>Postgres</productname> has many features not touched
|
|
|
|
upon in this
|
1999-08-08 06:21:33 +02:00
|
|
|
tutorial introduction, which has been oriented toward newer users of
|
|
|
|
<acronym>SQL</acronym>.
|
2000-04-07 15:30:58 +02:00
|
|
|
These are discussed in more detail in both the User's and
|
|
|
|
Programmer's Guides.
|
1999-08-08 06:21:33 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
</sect1>
|
2000-04-07 15:30:58 +02:00
|
|
|
|
1999-08-08 06:21:33 +02:00
|
|
|
</chapter>
|
|
|
|
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
|
|
Local variables:
|
2000-03-31 05:27:42 +02:00
|
|
|
mode:sgml
|
1999-08-08 06:21:33 +02:00
|
|
|
sgml-omittag:nil
|
|
|
|
sgml-shorttag:t
|
|
|
|
sgml-minimize-attributes:nil
|
|
|
|
sgml-always-quote-attributes:t
|
|
|
|
sgml-indent-step:1
|
|
|
|
sgml-indent-data:t
|
|
|
|
sgml-parent-document:nil
|
|
|
|
sgml-default-dtd-file:"./reference.ced"
|
|
|
|
sgml-exposed-tags:nil
|
2000-03-31 05:27:42 +02:00
|
|
|
sgml-local-catalogs:("/usr/lib/sgml/catalog")
|
1999-08-08 06:21:33 +02:00
|
|
|
sgml-local-ecat-files:nil
|
|
|
|
End:
|
|
|
|
-->
|