1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-29 13:56:47 +03:00

Don't use SGML empty tags

For DocBook XML compatibility, don't use SGML empty tags (</>) anymore,
replace by the full tag name.  Add a warning option to catch future
occurrences.

Alexander Lakhin, Jürgen Purtz
This commit is contained in:
Peter Eisentraut 2017-10-08 21:44:17 -04:00
parent 6ecabead4b
commit c29c578908
337 changed files with 31636 additions and 31635 deletions

View File

@ -66,10 +66,11 @@ ALLSGML := $(wildcard $(srcdir)/*.sgml $(srcdir)/ref/*.sgml) $(GENERATED_SGML)
# Enable some extra warnings # Enable some extra warnings
# -wfully-tagged needed to throw a warning on missing tags # -wfully-tagged needed to throw a warning on missing tags
# for older tool chains, 2007-08-31 # for older tool chains, 2007-08-31
override SPFLAGS += -wall -wno-unused-param -wno-empty -wfully-tagged override SPFLAGS += -wall -wno-unused-param -wfully-tagged
# Additional warnings for XML compatibility. The conditional is meant # Additional warnings for XML compatibility. The conditional is meant
# to detect whether we are using OpenSP rather than the ancient # to detect whether we are using OpenSP rather than the ancient
# original SP. # original SP.
override SPFLAGS += -wempty
ifneq (,$(filter o%,$(notdir $(OSX)))) ifneq (,$(filter o%,$(notdir $(OSX))))
override SPFLAGS += -wdata-delim -winstance-ignore-ms -winstance-include-ms -winstance-param-entity override SPFLAGS += -wdata-delim -winstance-ignore-ms -winstance-include-ms -winstance-param-entity
endif endif

View File

@ -4,8 +4,8 @@
<title>Acronyms</title> <title>Acronyms</title>
<para> <para>
This is a list of acronyms commonly used in the <productname>PostgreSQL</> This is a list of acronyms commonly used in the <productname>PostgreSQL</productname>
documentation and in discussions about <productname>PostgreSQL</>. documentation and in discussions about <productname>PostgreSQL</productname>.
<variablelist> <variablelist>
@ -153,7 +153,7 @@
<ulink <ulink
url="http://en.wikipedia.org/wiki/Data_Definition_Language">Data url="http://en.wikipedia.org/wiki/Data_Definition_Language">Data
Definition Language</ulink>, SQL commands such as <command>CREATE Definition Language</ulink>, SQL commands such as <command>CREATE
TABLE</>, <command>ALTER USER</> TABLE</command>, <command>ALTER USER</command>
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -164,8 +164,8 @@
<para> <para>
<ulink <ulink
url="http://en.wikipedia.org/wiki/Data_Manipulation_Language">Data url="http://en.wikipedia.org/wiki/Data_Manipulation_Language">Data
Manipulation Language</ulink>, SQL commands such as <command>INSERT</>, Manipulation Language</ulink>, SQL commands such as <command>INSERT</command>,
<command>UPDATE</>, <command>DELETE</> <command>UPDATE</command>, <command>DELETE</command>
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -281,7 +281,7 @@
<listitem> <listitem>
<para> <para>
<link linkend="config-setting">Grand Unified Configuration</link>, <link linkend="config-setting">Grand Unified Configuration</link>,
the <productname>PostgreSQL</> subsystem that handles server configuration the <productname>PostgreSQL</productname> subsystem that handles server configuration
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -384,7 +384,7 @@
<term><acronym>LSN</acronym></term> <term><acronym>LSN</acronym></term>
<listitem> <listitem>
<para> <para>
Log Sequence Number, see <link linkend="datatype-pg-lsn"><type>pg_lsn</></link> Log Sequence Number, see <link linkend="datatype-pg-lsn"><type>pg_lsn</type></link>
and <link linkend="wal-internals">WAL Internals</link>. and <link linkend="wal-internals">WAL Internals</link>.
</para> </para>
</listitem> </listitem>
@ -486,7 +486,7 @@
<term><acronym>PGSQL</acronym></term> <term><acronym>PGSQL</acronym></term>
<listitem> <listitem>
<para> <para>
<link linkend="postgres"><productname>PostgreSQL</></link> <link linkend="postgres"><productname>PostgreSQL</productname></link>
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -495,7 +495,7 @@
<term><acronym>PGXS</acronym></term> <term><acronym>PGXS</acronym></term>
<listitem> <listitem>
<para> <para>
<link linkend="extend-pgxs"><productname>PostgreSQL</> Extension System</link> <link linkend="extend-pgxs"><productname>PostgreSQL</productname> Extension System</link>
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -8,8 +8,8 @@
</indexterm> </indexterm>
<para> <para>
<filename>adminpack</> provides a number of support functions which <filename>adminpack</filename> provides a number of support functions which
<application>pgAdmin</> and other administration and management tools can <application>pgAdmin</application> and other administration and management tools can
use to provide additional functionality, such as remote management use to provide additional functionality, such as remote management
of server log files. of server log files.
Use of all these functions is restricted to superusers. Use of all these functions is restricted to superusers.
@ -25,7 +25,7 @@
</para> </para>
<table id="functions-adminpack-table"> <table id="functions-adminpack-table">
<title><filename>adminpack</> Functions</title> <title><filename>adminpack</filename> Functions</title>
<tgroup cols="3"> <tgroup cols="3">
<thead> <thead>
<row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry> <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry>
@ -58,7 +58,7 @@
<entry><function>pg_catalog.pg_logdir_ls()</function></entry> <entry><function>pg_catalog.pg_logdir_ls()</function></entry>
<entry><type>setof record</type></entry> <entry><type>setof record</type></entry>
<entry> <entry>
List the log files in the <varname>log_directory</> directory List the log files in the <varname>log_directory</varname> directory
</entry> </entry>
</row> </row>
</tbody> </tbody>
@ -69,9 +69,9 @@
<primary>pg_file_write</primary> <primary>pg_file_write</primary>
</indexterm> </indexterm>
<para> <para>
<function>pg_file_write</> writes the specified <parameter>data</> into <function>pg_file_write</function> writes the specified <parameter>data</parameter> into
the file named by <parameter>filename</>. If <parameter>append</> is the file named by <parameter>filename</parameter>. If <parameter>append</parameter> is
false, the file must not already exist. If <parameter>append</> is true, false, the file must not already exist. If <parameter>append</parameter> is true,
the file can already exist, and will be appended to if so. the file can already exist, and will be appended to if so.
Returns the number of bytes written. Returns the number of bytes written.
</para> </para>
@ -80,15 +80,15 @@
<primary>pg_file_rename</primary> <primary>pg_file_rename</primary>
</indexterm> </indexterm>
<para> <para>
<function>pg_file_rename</> renames a file. If <parameter>archivename</> <function>pg_file_rename</function> renames a file. If <parameter>archivename</parameter>
is omitted or NULL, it simply renames <parameter>oldname</> is omitted or NULL, it simply renames <parameter>oldname</parameter>
to <parameter>newname</> (which must not already exist). to <parameter>newname</parameter> (which must not already exist).
If <parameter>archivename</> is provided, it first If <parameter>archivename</parameter> is provided, it first
renames <parameter>newname</> to <parameter>archivename</> (which must renames <parameter>newname</parameter> to <parameter>archivename</parameter> (which must
not already exist), and then renames <parameter>oldname</> not already exist), and then renames <parameter>oldname</parameter>
to <parameter>newname</>. In event of failure of the second rename step, to <parameter>newname</parameter>. In event of failure of the second rename step,
it will try to rename <parameter>archivename</> back it will try to rename <parameter>archivename</parameter> back
to <parameter>newname</> before reporting the error. to <parameter>newname</parameter> before reporting the error.
Returns true on success, false if the source file(s) are not present or Returns true on success, false if the source file(s) are not present or
not writable; other cases throw errors. not writable; other cases throw errors.
</para> </para>
@ -97,19 +97,19 @@
<primary>pg_file_unlink</primary> <primary>pg_file_unlink</primary>
</indexterm> </indexterm>
<para> <para>
<function>pg_file_unlink</> removes the specified file. <function>pg_file_unlink</function> removes the specified file.
Returns true on success, false if the specified file is not present Returns true on success, false if the specified file is not present
or the <function>unlink()</> call fails; other cases throw errors. or the <function>unlink()</function> call fails; other cases throw errors.
</para> </para>
<indexterm> <indexterm>
<primary>pg_logdir_ls</primary> <primary>pg_logdir_ls</primary>
</indexterm> </indexterm>
<para> <para>
<function>pg_logdir_ls</> returns the start timestamps and path <function>pg_logdir_ls</function> returns the start timestamps and path
names of all the log files in the <xref linkend="guc-log-directory"> names of all the log files in the <xref linkend="guc-log-directory">
directory. The <xref linkend="guc-log-filename"> parameter must have its directory. The <xref linkend="guc-log-filename"> parameter must have its
default setting (<literal>postgresql-%Y-%m-%d_%H%M%S.log</>) to use this default setting (<literal>postgresql-%Y-%m-%d_%H%M%S.log</literal>) to use this
function. function.
</para> </para>
@ -119,12 +119,12 @@
and should not be used in new applications; instead use those shown and should not be used in new applications; instead use those shown
in <xref linkend="functions-admin-signal-table"> in <xref linkend="functions-admin-signal-table">
and <xref linkend="functions-admin-genfile-table">. These functions are and <xref linkend="functions-admin-genfile-table">. These functions are
provided in <filename>adminpack</> only for compatibility with old provided in <filename>adminpack</filename> only for compatibility with old
versions of <application>pgAdmin</>. versions of <application>pgAdmin</application>.
</para> </para>
<table id="functions-adminpack-deprecated-table"> <table id="functions-adminpack-deprecated-table">
<title>Deprecated <filename>adminpack</> Functions</title> <title>Deprecated <filename>adminpack</filename> Functions</title>
<tgroup cols="3"> <tgroup cols="3">
<thead> <thead>
<row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry> <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry>
@ -136,22 +136,22 @@
<entry><function>pg_catalog.pg_file_read(filename text, offset bigint, nbytes bigint)</function></entry> <entry><function>pg_catalog.pg_file_read(filename text, offset bigint, nbytes bigint)</function></entry>
<entry><type>text</type></entry> <entry><type>text</type></entry>
<entry> <entry>
Alternate name for <function>pg_read_file()</> Alternate name for <function>pg_read_file()</function>
</entry> </entry>
</row> </row>
<row> <row>
<entry><function>pg_catalog.pg_file_length(filename text)</function></entry> <entry><function>pg_catalog.pg_file_length(filename text)</function></entry>
<entry><type>bigint</type></entry> <entry><type>bigint</type></entry>
<entry> <entry>
Same as <structfield>size</> column returned Same as <structfield>size</structfield> column returned
by <function>pg_stat_file()</> by <function>pg_stat_file()</function>
</entry> </entry>
</row> </row>
<row> <row>
<entry><function>pg_catalog.pg_logfile_rotate()</function></entry> <entry><function>pg_catalog.pg_logfile_rotate()</function></entry>
<entry><type>integer</type></entry> <entry><type>integer</type></entry>
<entry> <entry>
Alternate name for <function>pg_rotate_logfile()</>, but note that it Alternate name for <function>pg_rotate_logfile()</function>, but note that it
returns integer 0 or 1 rather than <type>boolean</type> returns integer 0 or 1 rather than <type>boolean</type>
</entry> </entry>
</row> </row>

View File

@ -145,7 +145,7 @@ DETAIL: Key (city)=(Berkeley) is not present in table "cities".
</indexterm> </indexterm>
<para> <para>
<firstterm>Transactions</> are a fundamental concept of all database <firstterm>Transactions</firstterm> are a fundamental concept of all database
systems. The essential point of a transaction is that it bundles systems. The essential point of a transaction is that it bundles
multiple steps into a single, all-or-nothing operation. The intermediate multiple steps into a single, all-or-nothing operation. The intermediate
states between the steps are not visible to other concurrent transactions, states between the steps are not visible to other concurrent transactions,
@ -182,8 +182,8 @@ UPDATE branches SET balance = balance + 100.00
remain a happy customer if she was debited without Bob being credited. remain a happy customer if she was debited without Bob being credited.
We need a guarantee that if something goes wrong partway through the We need a guarantee that if something goes wrong partway through the
operation, none of the steps executed so far will take effect. Grouping operation, none of the steps executed so far will take effect. Grouping
the updates into a <firstterm>transaction</> gives us this guarantee. the updates into a <firstterm>transaction</firstterm> gives us this guarantee.
A transaction is said to be <firstterm>atomic</>: from the point of A transaction is said to be <firstterm>atomic</firstterm>: from the point of
view of other transactions, it either happens completely or not at all. view of other transactions, it either happens completely or not at all.
</para> </para>
@ -216,9 +216,9 @@ UPDATE branches SET balance = balance + 100.00
</para> </para>
<para> <para>
In <productname>PostgreSQL</>, a transaction is set up by surrounding In <productname>PostgreSQL</productname>, a transaction is set up by surrounding
the SQL commands of the transaction with the SQL commands of the transaction with
<command>BEGIN</> and <command>COMMIT</> commands. So our banking <command>BEGIN</command> and <command>COMMIT</command> commands. So our banking
transaction would actually look like: transaction would actually look like:
<programlisting> <programlisting>
@ -233,23 +233,23 @@ COMMIT;
<para> <para>
If, partway through the transaction, we decide we do not want to If, partway through the transaction, we decide we do not want to
commit (perhaps we just noticed that Alice's balance went negative), commit (perhaps we just noticed that Alice's balance went negative),
we can issue the command <command>ROLLBACK</> instead of we can issue the command <command>ROLLBACK</command> instead of
<command>COMMIT</>, and all our updates so far will be canceled. <command>COMMIT</command>, and all our updates so far will be canceled.
</para> </para>
<para> <para>
<productname>PostgreSQL</> actually treats every SQL statement as being <productname>PostgreSQL</productname> actually treats every SQL statement as being
executed within a transaction. If you do not issue a <command>BEGIN</> executed within a transaction. If you do not issue a <command>BEGIN</command>
command, command,
then each individual statement has an implicit <command>BEGIN</> and then each individual statement has an implicit <command>BEGIN</command> and
(if successful) <command>COMMIT</> wrapped around it. A group of (if successful) <command>COMMIT</command> wrapped around it. A group of
statements surrounded by <command>BEGIN</> and <command>COMMIT</> statements surrounded by <command>BEGIN</command> and <command>COMMIT</command>
is sometimes called a <firstterm>transaction block</>. is sometimes called a <firstterm>transaction block</firstterm>.
</para> </para>
<note> <note>
<para> <para>
Some client libraries issue <command>BEGIN</> and <command>COMMIT</> Some client libraries issue <command>BEGIN</command> and <command>COMMIT</command>
commands automatically, so that you might get the effect of transaction commands automatically, so that you might get the effect of transaction
blocks without asking. Check the documentation for the interface blocks without asking. Check the documentation for the interface
you are using. you are using.
@ -258,11 +258,11 @@ COMMIT;
<para> <para>
It's possible to control the statements in a transaction in a more It's possible to control the statements in a transaction in a more
granular fashion through the use of <firstterm>savepoints</>. Savepoints granular fashion through the use of <firstterm>savepoints</firstterm>. Savepoints
allow you to selectively discard parts of the transaction, while allow you to selectively discard parts of the transaction, while
committing the rest. After defining a savepoint with committing the rest. After defining a savepoint with
<command>SAVEPOINT</>, you can if needed roll back to the savepoint <command>SAVEPOINT</command>, you can if needed roll back to the savepoint
with <command>ROLLBACK TO</>. All the transaction's database changes with <command>ROLLBACK TO</command>. All the transaction's database changes
between defining the savepoint and rolling back to it are discarded, but between defining the savepoint and rolling back to it are discarded, but
changes earlier than the savepoint are kept. changes earlier than the savepoint are kept.
</para> </para>
@ -308,7 +308,7 @@ COMMIT;
<para> <para>
This example is, of course, oversimplified, but there's a lot of control This example is, of course, oversimplified, but there's a lot of control
possible in a transaction block through the use of savepoints. possible in a transaction block through the use of savepoints.
Moreover, <command>ROLLBACK TO</> is the only way to regain control of a Moreover, <command>ROLLBACK TO</command> is the only way to regain control of a
transaction block that was put in aborted state by the transaction block that was put in aborted state by the
system due to an error, short of rolling it back completely and starting system due to an error, short of rolling it back completely and starting
again. again.
@ -325,7 +325,7 @@ COMMIT;
</indexterm> </indexterm>
<para> <para>
A <firstterm>window function</> performs a calculation across a set of A <firstterm>window function</firstterm> performs a calculation across a set of
table rows that are somehow related to the current row. This is comparable table rows that are somehow related to the current row. This is comparable
to the type of calculation that can be done with an aggregate function. to the type of calculation that can be done with an aggregate function.
However, window functions do not cause rows to become grouped into a single However, window functions do not cause rows to become grouped into a single
@ -360,31 +360,31 @@ SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM emps
</screen> </screen>
The first three output columns come directly from the table The first three output columns come directly from the table
<structname>empsalary</>, and there is one output row for each row in the <structname>empsalary</structname>, and there is one output row for each row in the
table. The fourth column represents an average taken across all the table table. The fourth column represents an average taken across all the table
rows that have the same <structfield>depname</> value as the current row. rows that have the same <structfield>depname</structfield> value as the current row.
(This actually is the same function as the non-window <function>avg</> (This actually is the same function as the non-window <function>avg</function>
aggregate, but the <literal>OVER</> clause causes it to be aggregate, but the <literal>OVER</literal> clause causes it to be
treated as a window function and computed across the window frame.) treated as a window function and computed across the window frame.)
</para> </para>
<para> <para>
A window function call always contains an <literal>OVER</> clause A window function call always contains an <literal>OVER</literal> clause
directly following the window function's name and argument(s). This is what directly following the window function's name and argument(s). This is what
syntactically distinguishes it from a normal function or non-window syntactically distinguishes it from a normal function or non-window
aggregate. The <literal>OVER</> clause determines exactly how the aggregate. The <literal>OVER</literal> clause determines exactly how the
rows of the query are split up for processing by the window function. rows of the query are split up for processing by the window function.
The <literal>PARTITION BY</> clause within <literal>OVER</> The <literal>PARTITION BY</literal> clause within <literal>OVER</literal>
divides the rows into groups, or partitions, that share the same divides the rows into groups, or partitions, that share the same
values of the <literal>PARTITION BY</> expression(s). For each row, values of the <literal>PARTITION BY</literal> expression(s). For each row,
the window function is computed across the rows that fall into the the window function is computed across the rows that fall into the
same partition as the current row. same partition as the current row.
</para> </para>
<para> <para>
You can also control the order in which rows are processed by You can also control the order in which rows are processed by
window functions using <literal>ORDER BY</> within <literal>OVER</>. window functions using <literal>ORDER BY</literal> within <literal>OVER</literal>.
(The window <literal>ORDER BY</> does not even have to match the (The window <literal>ORDER BY</literal> does not even have to match the
order in which the rows are output.) Here is an example: order in which the rows are output.) Here is an example:
<programlisting> <programlisting>
@ -409,39 +409,39 @@ FROM empsalary;
(10 rows) (10 rows)
</screen> </screen>
As shown here, the <function>rank</> function produces a numerical rank As shown here, the <function>rank</function> function produces a numerical rank
for each distinct <literal>ORDER BY</> value in the current row's for each distinct <literal>ORDER BY</literal> value in the current row's
partition, using the order defined by the <literal>ORDER BY</> clause. partition, using the order defined by the <literal>ORDER BY</literal> clause.
<function>rank</> needs no explicit parameter, because its behavior <function>rank</function> needs no explicit parameter, because its behavior
is entirely determined by the <literal>OVER</> clause. is entirely determined by the <literal>OVER</literal> clause.
</para> </para>
<para> <para>
The rows considered by a window function are those of the <quote>virtual The rows considered by a window function are those of the <quote>virtual
table</> produced by the query's <literal>FROM</> clause as filtered by its table</quote> produced by the query's <literal>FROM</literal> clause as filtered by its
<literal>WHERE</>, <literal>GROUP BY</>, and <literal>HAVING</> clauses <literal>WHERE</literal>, <literal>GROUP BY</literal>, and <literal>HAVING</literal> clauses
if any. For example, a row removed because it does not meet the if any. For example, a row removed because it does not meet the
<literal>WHERE</> condition is not seen by any window function. <literal>WHERE</literal> condition is not seen by any window function.
A query can contain multiple window functions that slice up the data A query can contain multiple window functions that slice up the data
in different ways using different <literal>OVER</> clauses, but in different ways using different <literal>OVER</literal> clauses, but
they all act on the same collection of rows defined by this virtual table. they all act on the same collection of rows defined by this virtual table.
</para> </para>
<para> <para>
We already saw that <literal>ORDER BY</> can be omitted if the ordering We already saw that <literal>ORDER BY</literal> can be omitted if the ordering
of rows is not important. It is also possible to omit <literal>PARTITION of rows is not important. It is also possible to omit <literal>PARTITION
BY</>, in which case there is a single partition containing all rows. BY</literal>, in which case there is a single partition containing all rows.
</para> </para>
<para> <para>
There is another important concept associated with window functions: There is another important concept associated with window functions:
for each row, there is a set of rows within its partition called its for each row, there is a set of rows within its partition called its
<firstterm>window frame</>. Some window functions act only <firstterm>window frame</firstterm>. Some window functions act only
on the rows of the window frame, rather than of the whole partition. on the rows of the window frame, rather than of the whole partition.
By default, if <literal>ORDER BY</> is supplied then the frame consists of By default, if <literal>ORDER BY</literal> is supplied then the frame consists of
all rows from the start of the partition up through the current row, plus all rows from the start of the partition up through the current row, plus
any following rows that are equal to the current row according to the any following rows that are equal to the current row according to the
<literal>ORDER BY</> clause. When <literal>ORDER BY</> is omitted the <literal>ORDER BY</literal> clause. When <literal>ORDER BY</literal> is omitted the
default frame consists of all rows in the partition. default frame consists of all rows in the partition.
<footnote> <footnote>
<para> <para>
@ -450,7 +450,7 @@ FROM empsalary;
<xref linkend="syntax-window-functions"> for details. <xref linkend="syntax-window-functions"> for details.
</para> </para>
</footnote> </footnote>
Here is an example using <function>sum</>: Here is an example using <function>sum</function>:
</para> </para>
<programlisting> <programlisting>
@ -474,11 +474,11 @@ SELECT salary, sum(salary) OVER () FROM empsalary;
</screen> </screen>
<para> <para>
Above, since there is no <literal>ORDER BY</> in the <literal>OVER</> Above, since there is no <literal>ORDER BY</literal> in the <literal>OVER</literal>
clause, the window frame is the same as the partition, which for lack of clause, the window frame is the same as the partition, which for lack of
<literal>PARTITION BY</> is the whole table; in other words each sum is <literal>PARTITION BY</literal> is the whole table; in other words each sum is
taken over the whole table and so we get the same result for each output taken over the whole table and so we get the same result for each output
row. But if we add an <literal>ORDER BY</> clause, we get very different row. But if we add an <literal>ORDER BY</literal> clause, we get very different
results: results:
</para> </para>
@ -510,8 +510,8 @@ SELECT salary, sum(salary) OVER (ORDER BY salary) FROM empsalary;
<para> <para>
Window functions are permitted only in the <literal>SELECT</literal> list Window functions are permitted only in the <literal>SELECT</literal> list
and the <literal>ORDER BY</> clause of the query. They are forbidden and the <literal>ORDER BY</literal> clause of the query. They are forbidden
elsewhere, such as in <literal>GROUP BY</>, <literal>HAVING</> elsewhere, such as in <literal>GROUP BY</literal>, <literal>HAVING</literal>
and <literal>WHERE</literal> clauses. This is because they logically and <literal>WHERE</literal> clauses. This is because they logically
execute after the processing of those clauses. Also, window functions execute after the processing of those clauses. Also, window functions
execute after non-window aggregate functions. This means it is valid to execute after non-window aggregate functions. This means it is valid to
@ -534,15 +534,15 @@ WHERE pos &lt; 3;
</programlisting> </programlisting>
The above query only shows the rows from the inner query having The above query only shows the rows from the inner query having
<literal>rank</> less than 3. <literal>rank</literal> less than 3.
</para> </para>
<para> <para>
When a query involves multiple window functions, it is possible to write When a query involves multiple window functions, it is possible to write
out each one with a separate <literal>OVER</> clause, but this is out each one with a separate <literal>OVER</literal> clause, but this is
duplicative and error-prone if the same windowing behavior is wanted duplicative and error-prone if the same windowing behavior is wanted
for several functions. Instead, each windowing behavior can be named for several functions. Instead, each windowing behavior can be named
in a <literal>WINDOW</> clause and then referenced in <literal>OVER</>. in a <literal>WINDOW</literal> clause and then referenced in <literal>OVER</literal>.
For example: For example:
<programlisting> <programlisting>
@ -623,13 +623,13 @@ CREATE TABLE capitals (
<para> <para>
In this case, a row of <classname>capitals</classname> In this case, a row of <classname>capitals</classname>
<firstterm>inherits</firstterm> all columns (<structfield>name</>, <firstterm>inherits</firstterm> all columns (<structfield>name</structfield>,
<structfield>population</>, and <structfield>altitude</>) from its <structfield>population</structfield>, and <structfield>altitude</structfield>) from its
<firstterm>parent</firstterm>, <classname>cities</classname>. The <firstterm>parent</firstterm>, <classname>cities</classname>. The
type of the column <structfield>name</structfield> is type of the column <structfield>name</structfield> is
<type>text</type>, a native <productname>PostgreSQL</productname> <type>text</type>, a native <productname>PostgreSQL</productname>
type for variable length character strings. State capitals have type for variable length character strings. State capitals have
an extra column, <structfield>state</>, that shows their state. In an extra column, <structfield>state</structfield>, that shows their state. In
<productname>PostgreSQL</productname>, a table can inherit from <productname>PostgreSQL</productname>, a table can inherit from
zero or more other tables. zero or more other tables.
</para> </para>

View File

@ -8,19 +8,19 @@
</indexterm> </indexterm>
<para> <para>
The <filename>amcheck</> module provides functions that allow you to The <filename>amcheck</filename> module provides functions that allow you to
verify the logical consistency of the structure of indexes. If the verify the logical consistency of the structure of indexes. If the
structure appears to be valid, no error is raised. structure appears to be valid, no error is raised.
</para> </para>
<para> <para>
The functions verify various <emphasis>invariants</> in the The functions verify various <emphasis>invariants</emphasis> in the
structure of the representation of particular indexes. The structure of the representation of particular indexes. The
correctness of the access method functions behind index scans and correctness of the access method functions behind index scans and
other important operations relies on these invariants always other important operations relies on these invariants always
holding. For example, certain functions verify, among other things, holding. For example, certain functions verify, among other things,
that all B-Tree pages have items in <quote>logical</> order (e.g., that all B-Tree pages have items in <quote>logical</quote> order (e.g.,
for B-Tree indexes on <type>text</>, index tuples should be in for B-Tree indexes on <type>text</type>, index tuples should be in
collated lexical order). If that particular invariant somehow fails collated lexical order). If that particular invariant somehow fails
to hold, we can expect binary searches on the affected page to to hold, we can expect binary searches on the affected page to
incorrectly guide index scans, resulting in wrong answers to SQL incorrectly guide index scans, resulting in wrong answers to SQL
@ -35,7 +35,7 @@
functions. functions.
</para> </para>
<para> <para>
<filename>amcheck</> functions may be used only by superusers. <filename>amcheck</filename> functions may be used only by superusers.
</para> </para>
<sect2> <sect2>
@ -82,7 +82,7 @@ ORDER BY c.relpages DESC LIMIT 10;
(10 rows) (10 rows)
</screen> </screen>
This example shows a session that performs verification of every This example shows a session that performs verification of every
catalog index in the database <quote>test</>. Details of just catalog index in the database <quote>test</quote>. Details of just
the 10 largest indexes verified are displayed. Since no error the 10 largest indexes verified are displayed. Since no error
is raised, all indexes tested appear to be logically consistent. is raised, all indexes tested appear to be logically consistent.
Naturally, this query could easily be changed to call Naturally, this query could easily be changed to call
@ -90,10 +90,10 @@ ORDER BY c.relpages DESC LIMIT 10;
database where verification is supported. database where verification is supported.
</para> </para>
<para> <para>
<function>bt_index_check</function> acquires an <literal>AccessShareLock</> <function>bt_index_check</function> acquires an <literal>AccessShareLock</literal>
on the target index and the heap relation it belongs to. This lock mode on the target index and the heap relation it belongs to. This lock mode
is the same lock mode acquired on relations by simple is the same lock mode acquired on relations by simple
<literal>SELECT</> statements. <literal>SELECT</literal> statements.
<function>bt_index_check</function> does not verify invariants <function>bt_index_check</function> does not verify invariants
that span child/parent relationships, nor does it verify that that span child/parent relationships, nor does it verify that
the target index is consistent with its heap relation. When a the target index is consistent with its heap relation. When a
@ -132,13 +132,13 @@ ORDER BY c.relpages DESC LIMIT 10;
logical inconsistency or other problem. logical inconsistency or other problem.
</para> </para>
<para> <para>
A <literal>ShareLock</> is required on the target index by A <literal>ShareLock</literal> is required on the target index by
<function>bt_index_parent_check</function> (a <function>bt_index_parent_check</function> (a
<literal>ShareLock</> is also acquired on the heap relation). <literal>ShareLock</literal> is also acquired on the heap relation).
These locks prevent concurrent data modification from These locks prevent concurrent data modification from
<command>INSERT</>, <command>UPDATE</>, and <command>DELETE</> <command>INSERT</command>, <command>UPDATE</command>, and <command>DELETE</command>
commands. The locks also prevent the underlying relation from commands. The locks also prevent the underlying relation from
being concurrently processed by <command>VACUUM</>, as well as being concurrently processed by <command>VACUUM</command>, as well as
all other utility commands. Note that the function holds locks all other utility commands. Note that the function holds locks
only while running, not for the entire transaction. only while running, not for the entire transaction.
</para> </para>
@ -159,13 +159,13 @@ ORDER BY c.relpages DESC LIMIT 10;
</sect2> </sect2>
<sect2> <sect2>
<title>Using <filename>amcheck</> effectively</title> <title>Using <filename>amcheck</filename> effectively</title>
<para> <para>
<filename>amcheck</> can be effective at detecting various types of <filename>amcheck</filename> can be effective at detecting various types of
failure modes that <link failure modes that <link
linkend="app-initdb-data-checksums"><application>data page linkend="app-initdb-data-checksums"><application>data page
checksums</></link> will always fail to catch. These include: checksums</application></link> will always fail to catch. These include:
<itemizedlist> <itemizedlist>
<listitem> <listitem>
@ -176,13 +176,13 @@ ORDER BY c.relpages DESC LIMIT 10;
<para> <para>
This includes issues caused by the comparison rules of operating This includes issues caused by the comparison rules of operating
system collations changing. Comparisons of datums of a collatable system collations changing. Comparisons of datums of a collatable
type like <type>text</> must be immutable (just as all type like <type>text</type> must be immutable (just as all
comparisons used for B-Tree index scans must be immutable), which comparisons used for B-Tree index scans must be immutable), which
implies that operating system collation rules must never change. implies that operating system collation rules must never change.
Though rare, updates to operating system collation rules can Though rare, updates to operating system collation rules can
cause these issues. More commonly, an inconsistency in the cause these issues. More commonly, an inconsistency in the
collation order between a master server and a standby server is collation order between a master server and a standby server is
implicated, possibly because the <emphasis>major</> operating implicated, possibly because the <emphasis>major</emphasis> operating
system version in use is inconsistent. Such inconsistencies will system version in use is inconsistent. Such inconsistencies will
generally only arise on standby servers, and so can generally generally only arise on standby servers, and so can generally
only be detected on standby servers. only be detected on standby servers.
@ -190,25 +190,25 @@ ORDER BY c.relpages DESC LIMIT 10;
<para> <para>
If a problem like this arises, it may not affect each individual If a problem like this arises, it may not affect each individual
index that is ordered using an affected collation, simply because index that is ordered using an affected collation, simply because
<emphasis>indexed</> values might happen to have the same <emphasis>indexed</emphasis> values might happen to have the same
absolute ordering regardless of the behavioral inconsistency. See absolute ordering regardless of the behavioral inconsistency. See
<xref linkend="locale"> and <xref linkend="collation"> for <xref linkend="locale"> and <xref linkend="collation"> for
further details about how <productname>PostgreSQL</> uses further details about how <productname>PostgreSQL</productname> uses
operating system locales and collations. operating system locales and collations.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
Corruption caused by hypothetical undiscovered bugs in the Corruption caused by hypothetical undiscovered bugs in the
underlying <productname>PostgreSQL</> access method code or sort underlying <productname>PostgreSQL</productname> access method code or sort
code. code.
</para> </para>
<para> <para>
Automatic verification of the structural integrity of indexes Automatic verification of the structural integrity of indexes
plays a role in the general testing of new or proposed plays a role in the general testing of new or proposed
<productname>PostgreSQL</> features that could plausibly allow a <productname>PostgreSQL</productname> features that could plausibly allow a
logical inconsistency to be introduced. One obvious testing logical inconsistency to be introduced. One obvious testing
strategy is to call <filename>amcheck</> functions continuously strategy is to call <filename>amcheck</filename> functions continuously
when running the standard regression tests. See <xref when running the standard regression tests. See <xref
linkend="regress-run"> for details on running the tests. linkend="regress-run"> for details on running the tests.
</para> </para>
@ -219,12 +219,12 @@ ORDER BY c.relpages DESC LIMIT 10;
simply not be enabled. simply not be enabled.
</para> </para>
<para> <para>
Note that <filename>amcheck</> examines a page as represented in some Note that <filename>amcheck</filename> examines a page as represented in some
shared memory buffer at the time of verification if there is only a shared memory buffer at the time of verification if there is only a
shared buffer hit when accessing the block. Consequently, shared buffer hit when accessing the block. Consequently,
<filename>amcheck</> does not necessarily examine data read from the <filename>amcheck</filename> does not necessarily examine data read from the
file system at the time of verification. Note that when checksums are file system at the time of verification. Note that when checksums are
enabled, <filename>amcheck</> may raise an error due to a checksum enabled, <filename>amcheck</filename> may raise an error due to a checksum
failure when a corrupt block is read into a buffer. failure when a corrupt block is read into a buffer.
</para> </para>
</listitem> </listitem>
@ -234,7 +234,7 @@ ORDER BY c.relpages DESC LIMIT 10;
and operating system. and operating system.
</para> </para>
<para> <para>
<productname>PostgreSQL</> does not protect against correctable <productname>PostgreSQL</productname> does not protect against correctable
memory errors and it is assumed you will operate using RAM that memory errors and it is assumed you will operate using RAM that
uses industry standard Error Correcting Codes (ECC) or better uses industry standard Error Correcting Codes (ECC) or better
protection. However, ECC memory is typically only immune to protection. However, ECC memory is typically only immune to
@ -244,7 +244,7 @@ ORDER BY c.relpages DESC LIMIT 10;
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
In general, <filename>amcheck</> can only prove the presence of In general, <filename>amcheck</filename> can only prove the presence of
corruption; it cannot prove its absence. corruption; it cannot prove its absence.
</para> </para>
@ -252,19 +252,19 @@ ORDER BY c.relpages DESC LIMIT 10;
<sect2> <sect2>
<title>Repairing corruption</title> <title>Repairing corruption</title>
<para> <para>
No error concerning corruption raised by <filename>amcheck</> should No error concerning corruption raised by <filename>amcheck</filename> should
ever be a false positive. In practice, <filename>amcheck</> is more ever be a false positive. In practice, <filename>amcheck</filename> is more
likely to find software bugs than problems with hardware. likely to find software bugs than problems with hardware.
<filename>amcheck</> raises errors in the event of conditions that, <filename>amcheck</filename> raises errors in the event of conditions that,
by definition, should never happen, and so careful analysis of by definition, should never happen, and so careful analysis of
<filename>amcheck</> errors is often required. <filename>amcheck</filename> errors is often required.
</para> </para>
<para> <para>
There is no general method of repairing problems that There is no general method of repairing problems that
<filename>amcheck</> detects. An explanation for the root cause of <filename>amcheck</filename> detects. An explanation for the root cause of
an invariant violation should be sought. <xref an invariant violation should be sought. <xref
linkend="pageinspect"> may play a useful role in diagnosing linkend="pageinspect"> may play a useful role in diagnosing
corruption that <filename>amcheck</> detects. A <command>REINDEX</> corruption that <filename>amcheck</filename> detects. A <command>REINDEX</command>
may not be effective in repairing corruption. may not be effective in repairing corruption.
</para> </para>

View File

@ -118,7 +118,7 @@
<para> <para>
<productname>PostgreSQL</productname> is implemented using a <productname>PostgreSQL</productname> is implemented using a
simple <quote>process per user</> client/server model. In this model simple <quote>process per user</quote> client/server model. In this model
there is one <firstterm>client process</firstterm> connected to there is one <firstterm>client process</firstterm> connected to
exactly one <firstterm>server process</firstterm>. As we do not exactly one <firstterm>server process</firstterm>. As we do not
know ahead of time how many connections will be made, we have to know ahead of time how many connections will be made, we have to
@ -137,9 +137,9 @@
The client process can be any program that understands the The client process can be any program that understands the
<productname>PostgreSQL</productname> protocol described in <productname>PostgreSQL</productname> protocol described in
<xref linkend="protocol">. Many clients are based on the <xref linkend="protocol">. Many clients are based on the
C-language library <application>libpq</>, but several independent C-language library <application>libpq</application>, but several independent
implementations of the protocol exist, such as the Java implementations of the protocol exist, such as the Java
<application>JDBC</> driver. <application>JDBC</application> driver.
</para> </para>
<para> <para>
@ -184,8 +184,8 @@
text) for valid syntax. If the syntax is correct a text) for valid syntax. If the syntax is correct a
<firstterm>parse tree</firstterm> is built up and handed back; <firstterm>parse tree</firstterm> is built up and handed back;
otherwise an error is returned. The parser and lexer are otherwise an error is returned. The parser and lexer are
implemented using the well-known Unix tools <application>bison</> implemented using the well-known Unix tools <application>bison</application>
and <application>flex</>. and <application>flex</application>.
</para> </para>
<para> <para>
@ -251,7 +251,7 @@
back by the parser as input and does the semantic interpretation needed back by the parser as input and does the semantic interpretation needed
to understand which tables, functions, and operators are referenced by to understand which tables, functions, and operators are referenced by
the query. The data structure that is built to represent this the query. The data structure that is built to represent this
information is called the <firstterm>query tree</>. information is called the <firstterm>query tree</firstterm>.
</para> </para>
<para> <para>
@ -259,10 +259,10 @@
system catalog lookups can only be done within a transaction, and we system catalog lookups can only be done within a transaction, and we
do not wish to start a transaction immediately upon receiving a query do not wish to start a transaction immediately upon receiving a query
string. The raw parsing stage is sufficient to identify the transaction string. The raw parsing stage is sufficient to identify the transaction
control commands (<command>BEGIN</>, <command>ROLLBACK</>, etc), and control commands (<command>BEGIN</command>, <command>ROLLBACK</command>, etc), and
these can then be correctly executed without any further analysis. these can then be correctly executed without any further analysis.
Once we know that we are dealing with an actual query (such as Once we know that we are dealing with an actual query (such as
<command>SELECT</> or <command>UPDATE</>), it is okay to <command>SELECT</command> or <command>UPDATE</command>), it is okay to
start a transaction if we're not already in one. Only then can the start a transaction if we're not already in one. Only then can the
transformation process be invoked. transformation process be invoked.
</para> </para>
@ -270,10 +270,10 @@
<para> <para>
The query tree created by the transformation process is structurally The query tree created by the transformation process is structurally
similar to the raw parse tree in most places, but it has many differences similar to the raw parse tree in most places, but it has many differences
in detail. For example, a <structname>FuncCall</> node in the in detail. For example, a <structname>FuncCall</structname> node in the
parse tree represents something that looks syntactically like a function parse tree represents something that looks syntactically like a function
call. This might be transformed to either a <structname>FuncExpr</> call. This might be transformed to either a <structname>FuncExpr</structname>
or <structname>Aggref</> node depending on whether the referenced or <structname>Aggref</structname> node depending on whether the referenced
name turns out to be an ordinary function or an aggregate function. name turns out to be an ordinary function or an aggregate function.
Also, information about the actual data types of columns and expression Also, information about the actual data types of columns and expression
results is added to the query tree. results is added to the query tree.
@ -354,10 +354,10 @@
<para> <para>
The planner's search procedure actually works with data structures The planner's search procedure actually works with data structures
called <firstterm>paths</>, which are simply cut-down representations of called <firstterm>paths</firstterm>, which are simply cut-down representations of
plans containing only as much information as the planner needs to make plans containing only as much information as the planner needs to make
its decisions. After the cheapest path is determined, a full-fledged its decisions. After the cheapest path is determined, a full-fledged
<firstterm>plan tree</> is built to pass to the executor. This represents <firstterm>plan tree</firstterm> is built to pass to the executor. This represents
the desired execution plan in sufficient detail for the executor to run it. the desired execution plan in sufficient detail for the executor to run it.
In the rest of this section we'll ignore the distinction between paths In the rest of this section we'll ignore the distinction between paths
and plans. and plans.
@ -378,12 +378,12 @@
<literal>relation.attribute OPR constant</literal>. If <literal>relation.attribute OPR constant</literal>. If
<literal>relation.attribute</literal> happens to match the key of the B-tree <literal>relation.attribute</literal> happens to match the key of the B-tree
index and <literal>OPR</literal> is one of the operators listed in index and <literal>OPR</literal> is one of the operators listed in
the index's <firstterm>operator class</>, another plan is created using the index's <firstterm>operator class</firstterm>, another plan is created using
the B-tree index to scan the relation. If there are further indexes the B-tree index to scan the relation. If there are further indexes
present and the restrictions in the query happen to match a key of an present and the restrictions in the query happen to match a key of an
index, further plans will be considered. Index scan plans are also index, further plans will be considered. Index scan plans are also
generated for indexes that have a sort ordering that can match the generated for indexes that have a sort ordering that can match the
query's <literal>ORDER BY</> clause (if any), or a sort ordering that query's <literal>ORDER BY</literal> clause (if any), or a sort ordering that
might be useful for merge joining (see below). might be useful for merge joining (see below).
</para> </para>
@ -462,9 +462,9 @@
the base relations, plus nested-loop, merge, or hash join nodes as the base relations, plus nested-loop, merge, or hash join nodes as
needed, plus any auxiliary steps needed, such as sort nodes or needed, plus any auxiliary steps needed, such as sort nodes or
aggregate-function calculation nodes. Most of these plan node aggregate-function calculation nodes. Most of these plan node
types have the additional ability to do <firstterm>selection</> types have the additional ability to do <firstterm>selection</firstterm>
(discarding rows that do not meet a specified Boolean condition) (discarding rows that do not meet a specified Boolean condition)
and <firstterm>projection</> (computation of a derived column set and <firstterm>projection</firstterm> (computation of a derived column set
based on given column values, that is, evaluation of scalar based on given column values, that is, evaluation of scalar
expressions where needed). One of the responsibilities of the expressions where needed). One of the responsibilities of the
planner is to attach selection conditions from the planner is to attach selection conditions from the
@ -496,7 +496,7 @@
subplan) is, let's say, a subplan) is, let's say, a
<literal>Sort</literal> node and again recursion is needed to obtain <literal>Sort</literal> node and again recursion is needed to obtain
an input row. The child node of the <literal>Sort</literal> might an input row. The child node of the <literal>Sort</literal> might
be a <literal>SeqScan</> node, representing actual reading of a table. be a <literal>SeqScan</literal> node, representing actual reading of a table.
Execution of this node causes the executor to fetch a row from the Execution of this node causes the executor to fetch a row from the
table and return it up to the calling node. The <literal>Sort</literal> table and return it up to the calling node. The <literal>Sort</literal>
node will repeatedly call its child to obtain all the rows to be sorted. node will repeatedly call its child to obtain all the rows to be sorted.
@ -529,24 +529,24 @@
<para> <para>
The executor mechanism is used to evaluate all four basic SQL query types: The executor mechanism is used to evaluate all four basic SQL query types:
<command>SELECT</>, <command>INSERT</>, <command>UPDATE</>, and <command>SELECT</command>, <command>INSERT</command>, <command>UPDATE</command>, and
<command>DELETE</>. For <command>SELECT</>, the top-level executor <command>DELETE</command>. For <command>SELECT</command>, the top-level executor
code only needs to send each row returned by the query plan tree off code only needs to send each row returned by the query plan tree off
to the client. For <command>INSERT</>, each returned row is inserted to the client. For <command>INSERT</command>, each returned row is inserted
into the target table specified for the <command>INSERT</>. This is into the target table specified for the <command>INSERT</command>. This is
done in a special top-level plan node called <literal>ModifyTable</>. done in a special top-level plan node called <literal>ModifyTable</literal>.
(A simple (A simple
<command>INSERT ... VALUES</> command creates a trivial plan tree <command>INSERT ... VALUES</command> command creates a trivial plan tree
consisting of a single <literal>Result</> node, which computes just one consisting of a single <literal>Result</literal> node, which computes just one
result row, and <literal>ModifyTable</> above it to perform the insertion. result row, and <literal>ModifyTable</literal> above it to perform the insertion.
But <command>INSERT ... SELECT</> can demand the full power But <command>INSERT ... SELECT</command> can demand the full power
of the executor mechanism.) For <command>UPDATE</>, the planner arranges of the executor mechanism.) For <command>UPDATE</command>, the planner arranges
that each computed row includes all the updated column values, plus that each computed row includes all the updated column values, plus
the <firstterm>TID</> (tuple ID, or row ID) of the original target row; the <firstterm>TID</firstterm> (tuple ID, or row ID) of the original target row;
this data is fed into a <literal>ModifyTable</> node, which uses the this data is fed into a <literal>ModifyTable</literal> node, which uses the
information to create a new updated row and mark the old row deleted. information to create a new updated row and mark the old row deleted.
For <command>DELETE</>, the only column that is actually returned by the For <command>DELETE</command>, the only column that is actually returned by the
plan is the TID, and the <literal>ModifyTable</> node simply uses the TID plan is the TID, and the <literal>ModifyTable</literal> node simply uses the TID
to visit each target row and mark it deleted. to visit each target row and mark it deleted.
</para> </para>

View File

@ -32,7 +32,7 @@ CREATE TABLE sal_emp (
); );
</programlisting> </programlisting>
As shown, an array data type is named by appending square brackets As shown, an array data type is named by appending square brackets
(<literal>[]</>) to the data type name of the array elements. The (<literal>[]</literal>) to the data type name of the array elements. The
above command will create a table named above command will create a table named
<structname>sal_emp</structname> with a column of type <structname>sal_emp</structname> with a column of type
<type>text</type> (<structfield>name</structfield>), a <type>text</type> (<structfield>name</structfield>), a
@ -69,7 +69,7 @@ CREATE TABLE tictactoe (
<para> <para>
An alternative syntax, which conforms to the SQL standard by using An alternative syntax, which conforms to the SQL standard by using
the keyword <literal>ARRAY</>, can be used for one-dimensional arrays. the keyword <literal>ARRAY</literal>, can be used for one-dimensional arrays.
<structfield>pay_by_quarter</structfield> could have been defined <structfield>pay_by_quarter</structfield> could have been defined
as: as:
<programlisting> <programlisting>
@ -79,7 +79,7 @@ CREATE TABLE tictactoe (
<programlisting> <programlisting>
pay_by_quarter integer ARRAY, pay_by_quarter integer ARRAY,
</programlisting> </programlisting>
As before, however, <productname>PostgreSQL</> does not enforce the As before, however, <productname>PostgreSQL</productname> does not enforce the
size restriction in any case. size restriction in any case.
</para> </para>
</sect2> </sect2>
@ -107,8 +107,8 @@ CREATE TABLE tictactoe (
for the type, as recorded in its <literal>pg_type</literal> entry. for the type, as recorded in its <literal>pg_type</literal> entry.
Among the standard data types provided in the Among the standard data types provided in the
<productname>PostgreSQL</productname> distribution, all use a comma <productname>PostgreSQL</productname> distribution, all use a comma
(<literal>,</>), except for type <type>box</> which uses a semicolon (<literal>,</literal>), except for type <type>box</type> which uses a semicolon
(<literal>;</>). Each <replaceable>val</replaceable> is (<literal>;</literal>). Each <replaceable>val</replaceable> is
either a constant of the array element type, or a subarray. An example either a constant of the array element type, or a subarray. An example
of an array constant is: of an array constant is:
<programlisting> <programlisting>
@ -119,10 +119,10 @@ CREATE TABLE tictactoe (
</para> </para>
<para> <para>
To set an element of an array constant to NULL, write <literal>NULL</> To set an element of an array constant to NULL, write <literal>NULL</literal>
for the element value. (Any upper- or lower-case variant of for the element value. (Any upper- or lower-case variant of
<literal>NULL</> will do.) If you want an actual string value <literal>NULL</literal> will do.) If you want an actual string value
<quote>NULL</>, you must put double quotes around it. <quote>NULL</quote>, you must put double quotes around it.
</para> </para>
<para> <para>
@ -176,7 +176,7 @@ ERROR: multidimensional arrays must have array expressions with matching dimens
</para> </para>
<para> <para>
The <literal>ARRAY</> constructor syntax can also be used: The <literal>ARRAY</literal> constructor syntax can also be used:
<programlisting> <programlisting>
INSERT INTO sal_emp INSERT INTO sal_emp
VALUES ('Bill', VALUES ('Bill',
@ -190,7 +190,7 @@ INSERT INTO sal_emp
</programlisting> </programlisting>
Notice that the array elements are ordinary SQL constants or Notice that the array elements are ordinary SQL constants or
expressions; for instance, string literals are single quoted, instead of expressions; for instance, string literals are single quoted, instead of
double quoted as they would be in an array literal. The <literal>ARRAY</> double quoted as they would be in an array literal. The <literal>ARRAY</literal>
constructor syntax is discussed in more detail in constructor syntax is discussed in more detail in
<xref linkend="sql-syntax-array-constructors">. <xref linkend="sql-syntax-array-constructors">.
</para> </para>
@ -222,8 +222,8 @@ SELECT name FROM sal_emp WHERE pay_by_quarter[1] &lt;&gt; pay_by_quarter[2];
The array subscript numbers are written within square brackets. The array subscript numbers are written within square brackets.
By default <productname>PostgreSQL</productname> uses a By default <productname>PostgreSQL</productname> uses a
one-based numbering convention for arrays, that is, one-based numbering convention for arrays, that is,
an array of <replaceable>n</> elements starts with <literal>array[1]</literal> and an array of <replaceable>n</replaceable> elements starts with <literal>array[1]</literal> and
ends with <literal>array[<replaceable>n</>]</literal>. ends with <literal>array[<replaceable>n</replaceable>]</literal>.
</para> </para>
<para> <para>
@ -259,8 +259,8 @@ SELECT schedule[1:2][1:1] FROM sal_emp WHERE name = 'Bill';
If any dimension is written as a slice, i.e., contains a colon, then all If any dimension is written as a slice, i.e., contains a colon, then all
dimensions are treated as slices. Any dimension that has only a single dimensions are treated as slices. Any dimension that has only a single
number (no colon) is treated as being from 1 number (no colon) is treated as being from 1
to the number specified. For example, <literal>[2]</> is treated as to the number specified. For example, <literal>[2]</literal> is treated as
<literal>[1:2]</>, as in this example: <literal>[1:2]</literal>, as in this example:
<programlisting> <programlisting>
SELECT schedule[1:2][2] FROM sal_emp WHERE name = 'Bill'; SELECT schedule[1:2][2] FROM sal_emp WHERE name = 'Bill';
@ -272,7 +272,7 @@ SELECT schedule[1:2][2] FROM sal_emp WHERE name = 'Bill';
</programlisting> </programlisting>
To avoid confusion with the non-slice case, it's best to use slice syntax To avoid confusion with the non-slice case, it's best to use slice syntax
for all dimensions, e.g., <literal>[1:2][1:1]</>, not <literal>[2][1:1]</>. for all dimensions, e.g., <literal>[1:2][1:1]</literal>, not <literal>[2][1:1]</literal>.
</para> </para>
<para> <para>
@ -302,9 +302,9 @@ SELECT schedule[:][1:1] FROM sal_emp WHERE name = 'Bill';
An array subscript expression will return null if either the array itself or An array subscript expression will return null if either the array itself or
any of the subscript expressions are null. Also, null is returned if a any of the subscript expressions are null. Also, null is returned if a
subscript is outside the array bounds (this case does not raise an error). subscript is outside the array bounds (this case does not raise an error).
For example, if <literal>schedule</> For example, if <literal>schedule</literal>
currently has the dimensions <literal>[1:3][1:2]</> then referencing currently has the dimensions <literal>[1:3][1:2]</literal> then referencing
<literal>schedule[3][3]</> yields NULL. Similarly, an array reference <literal>schedule[3][3]</literal> yields NULL. Similarly, an array reference
with the wrong number of subscripts yields a null rather than an error. with the wrong number of subscripts yields a null rather than an error.
</para> </para>
@ -423,16 +423,16 @@ UPDATE sal_emp SET pay_by_quarter[1:2] = '{27000,27000}'
A stored array value can be enlarged by assigning to elements not already A stored array value can be enlarged by assigning to elements not already
present. Any positions between those previously present and the newly present. Any positions between those previously present and the newly
assigned elements will be filled with nulls. For example, if array assigned elements will be filled with nulls. For example, if array
<literal>myarray</> currently has 4 elements, it will have six <literal>myarray</literal> currently has 4 elements, it will have six
elements after an update that assigns to <literal>myarray[6]</>; elements after an update that assigns to <literal>myarray[6]</literal>;
<literal>myarray[5]</> will contain null. <literal>myarray[5]</literal> will contain null.
Currently, enlargement in this fashion is only allowed for one-dimensional Currently, enlargement in this fashion is only allowed for one-dimensional
arrays, not multidimensional arrays. arrays, not multidimensional arrays.
</para> </para>
<para> <para>
Subscripted assignment allows creation of arrays that do not use one-based Subscripted assignment allows creation of arrays that do not use one-based
subscripts. For example one might assign to <literal>myarray[-2:7]</> to subscripts. For example one might assign to <literal>myarray[-2:7]</literal> to
create an array with subscript values from -2 to 7. create an array with subscript values from -2 to 7.
</para> </para>
@ -457,8 +457,8 @@ SELECT ARRAY[5,6] || ARRAY[[1,2],[3,4]];
<para> <para>
The concatenation operator allows a single element to be pushed onto the The concatenation operator allows a single element to be pushed onto the
beginning or end of a one-dimensional array. It also accepts two beginning or end of a one-dimensional array. It also accepts two
<replaceable>N</>-dimensional arrays, or an <replaceable>N</>-dimensional <replaceable>N</replaceable>-dimensional arrays, or an <replaceable>N</replaceable>-dimensional
and an <replaceable>N+1</>-dimensional array. and an <replaceable>N+1</replaceable>-dimensional array.
</para> </para>
<para> <para>
@ -501,10 +501,10 @@ SELECT array_dims(ARRAY[[1,2],[3,4]] || ARRAY[[5,6],[7,8],[9,0]]);
</para> </para>
<para> <para>
When an <replaceable>N</>-dimensional array is pushed onto the beginning When an <replaceable>N</replaceable>-dimensional array is pushed onto the beginning
or end of an <replaceable>N+1</>-dimensional array, the result is or end of an <replaceable>N+1</replaceable>-dimensional array, the result is
analogous to the element-array case above. Each <replaceable>N</>-dimensional analogous to the element-array case above. Each <replaceable>N</replaceable>-dimensional
sub-array is essentially an element of the <replaceable>N+1</>-dimensional sub-array is essentially an element of the <replaceable>N+1</replaceable>-dimensional
array's outer dimension. For example: array's outer dimension. For example:
<programlisting> <programlisting>
SELECT array_dims(ARRAY[1,2] || ARRAY[[3,4],[5,6]]); SELECT array_dims(ARRAY[1,2] || ARRAY[[3,4],[5,6]]);
@ -587,9 +587,9 @@ SELECT array_append(ARRAY[1, 2], NULL); -- this might have been meant
The heuristic it uses to resolve the constant's type is to assume it's of The heuristic it uses to resolve the constant's type is to assume it's of
the same type as the operator's other input &mdash; in this case, the same type as the operator's other input &mdash; in this case,
integer array. So the concatenation operator is presumed to integer array. So the concatenation operator is presumed to
represent <function>array_cat</>, not <function>array_append</>. When represent <function>array_cat</function>, not <function>array_append</function>. When
that's the wrong choice, it could be fixed by casting the constant to the that's the wrong choice, it could be fixed by casting the constant to the
array's element type; but explicit use of <function>array_append</> might array's element type; but explicit use of <function>array_append</function> might
be a preferable solution. be a preferable solution.
</para> </para>
</sect2> </sect2>
@ -633,7 +633,7 @@ SELECT * FROM sal_emp WHERE 10000 = ALL (pay_by_quarter);
</para> </para>
<para> <para>
Alternatively, the <function>generate_subscripts</> function can be used. Alternatively, the <function>generate_subscripts</function> function can be used.
For example: For example:
<programlisting> <programlisting>
@ -648,7 +648,7 @@ SELECT * FROM
</para> </para>
<para> <para>
You can also search an array using the <literal>&amp;&amp;</> operator, You can also search an array using the <literal>&amp;&amp;</literal> operator,
which checks whether the left operand overlaps with the right operand. which checks whether the left operand overlaps with the right operand.
For instance: For instance:
@ -662,8 +662,8 @@ SELECT * FROM sal_emp WHERE pay_by_quarter &amp;&amp; ARRAY[10000];
</para> </para>
<para> <para>
You can also search for specific values in an array using the <function>array_position</> You can also search for specific values in an array using the <function>array_position</function>
and <function>array_positions</> functions. The former returns the subscript of and <function>array_positions</function> functions. The former returns the subscript of
the first occurrence of a value in an array; the latter returns an array with the the first occurrence of a value in an array; the latter returns an array with the
subscripts of all occurrences of the value in the array. For example: subscripts of all occurrences of the value in the array. For example:
@ -703,13 +703,13 @@ SELECT array_positions(ARRAY[1, 4, 3, 1, 3, 4, 2, 1], 1);
The external text representation of an array value consists of items that The external text representation of an array value consists of items that
are interpreted according to the I/O conversion rules for the array's are interpreted according to the I/O conversion rules for the array's
element type, plus decoration that indicates the array structure. element type, plus decoration that indicates the array structure.
The decoration consists of curly braces (<literal>{</> and <literal>}</>) The decoration consists of curly braces (<literal>{</literal> and <literal>}</literal>)
around the array value plus delimiter characters between adjacent items. around the array value plus delimiter characters between adjacent items.
The delimiter character is usually a comma (<literal>,</>) but can be The delimiter character is usually a comma (<literal>,</literal>) but can be
something else: it is determined by the <literal>typdelim</> setting something else: it is determined by the <literal>typdelim</literal> setting
for the array's element type. Among the standard data types provided for the array's element type. Among the standard data types provided
in the <productname>PostgreSQL</productname> distribution, all use a comma, in the <productname>PostgreSQL</productname> distribution, all use a comma,
except for type <type>box</>, which uses a semicolon (<literal>;</>). except for type <type>box</type>, which uses a semicolon (<literal>;</literal>).
In a multidimensional array, each dimension (row, plane, In a multidimensional array, each dimension (row, plane,
cube, etc.) gets its own level of curly braces, and delimiters cube, etc.) gets its own level of curly braces, and delimiters
must be written between adjacent curly-braced entities of the same level. must be written between adjacent curly-braced entities of the same level.
@ -719,7 +719,7 @@ SELECT array_positions(ARRAY[1, 4, 3, 1, 3, 4, 2, 1], 1);
The array output routine will put double quotes around element values The array output routine will put double quotes around element values
if they are empty strings, contain curly braces, delimiter characters, if they are empty strings, contain curly braces, delimiter characters,
double quotes, backslashes, or white space, or match the word double quotes, backslashes, or white space, or match the word
<literal>NULL</>. Double quotes and backslashes <literal>NULL</literal>. Double quotes and backslashes
embedded in element values will be backslash-escaped. For numeric embedded in element values will be backslash-escaped. For numeric
data types it is safe to assume that double quotes will never appear, but data types it is safe to assume that double quotes will never appear, but
for textual data types one should be prepared to cope with either the presence for textual data types one should be prepared to cope with either the presence
@ -731,10 +731,10 @@ SELECT array_positions(ARRAY[1, 4, 3, 1, 3, 4, 2, 1], 1);
set to one. To represent arrays with other lower bounds, the array set to one. To represent arrays with other lower bounds, the array
subscript ranges can be specified explicitly before writing the subscript ranges can be specified explicitly before writing the
array contents. array contents.
This decoration consists of square brackets (<literal>[]</>) This decoration consists of square brackets (<literal>[]</literal>)
around each array dimension's lower and upper bounds, with around each array dimension's lower and upper bounds, with
a colon (<literal>:</>) delimiter character in between. The a colon (<literal>:</literal>) delimiter character in between. The
array dimension decoration is followed by an equal sign (<literal>=</>). array dimension decoration is followed by an equal sign (<literal>=</literal>).
For example: For example:
<programlisting> <programlisting>
SELECT f1[1][-2][3] AS e1, f1[1][-1][5] AS e2 SELECT f1[1][-2][3] AS e1, f1[1][-1][5] AS e2
@ -750,23 +750,23 @@ SELECT f1[1][-2][3] AS e1, f1[1][-1][5] AS e2
</para> </para>
<para> <para>
If the value written for an element is <literal>NULL</> (in any case If the value written for an element is <literal>NULL</literal> (in any case
variant), the element is taken to be NULL. The presence of any quotes variant), the element is taken to be NULL. The presence of any quotes
or backslashes disables this and allows the literal string value or backslashes disables this and allows the literal string value
<quote>NULL</> to be entered. Also, for backward compatibility with <quote>NULL</quote> to be entered. Also, for backward compatibility with
pre-8.2 versions of <productname>PostgreSQL</>, the <xref pre-8.2 versions of <productname>PostgreSQL</productname>, the <xref
linkend="guc-array-nulls"> configuration parameter can be turned linkend="guc-array-nulls"> configuration parameter can be turned
<literal>off</> to suppress recognition of <literal>NULL</> as a NULL. <literal>off</literal> to suppress recognition of <literal>NULL</literal> as a NULL.
</para> </para>
<para> <para>
As shown previously, when writing an array value you can use double As shown previously, when writing an array value you can use double
quotes around any individual array element. You <emphasis>must</> do so quotes around any individual array element. You <emphasis>must</emphasis> do so
if the element value would otherwise confuse the array-value parser. if the element value would otherwise confuse the array-value parser.
For example, elements containing curly braces, commas (or the data type's For example, elements containing curly braces, commas (or the data type's
delimiter character), double quotes, backslashes, or leading or trailing delimiter character), double quotes, backslashes, or leading or trailing
whitespace must be double-quoted. Empty strings and strings matching the whitespace must be double-quoted. Empty strings and strings matching the
word <literal>NULL</> must be quoted, too. To put a double quote or word <literal>NULL</literal> must be quoted, too. To put a double quote or
backslash in a quoted array element value, use escape string syntax backslash in a quoted array element value, use escape string syntax
and precede it with a backslash. Alternatively, you can avoid quotes and use and precede it with a backslash. Alternatively, you can avoid quotes and use
backslash-escaping to protect all data characters that would otherwise backslash-escaping to protect all data characters that would otherwise
@ -785,17 +785,17 @@ SELECT f1[1][-2][3] AS e1, f1[1][-1][5] AS e2
<para> <para>
Remember that what you write in an SQL command will first be interpreted Remember that what you write in an SQL command will first be interpreted
as a string literal, and then as an array. This doubles the number of as a string literal, and then as an array. This doubles the number of
backslashes you need. For example, to insert a <type>text</> array backslashes you need. For example, to insert a <type>text</type> array
value containing a backslash and a double quote, you'd need to write: value containing a backslash and a double quote, you'd need to write:
<programlisting> <programlisting>
INSERT ... VALUES (E'{"\\\\","\\""}'); INSERT ... VALUES (E'{"\\\\","\\""}');
</programlisting> </programlisting>
The escape string processor removes one level of backslashes, so that The escape string processor removes one level of backslashes, so that
what arrives at the array-value parser looks like <literal>{"\\","\""}</>. what arrives at the array-value parser looks like <literal>{"\\","\""}</literal>.
In turn, the strings fed to the <type>text</> data type's input routine In turn, the strings fed to the <type>text</type> data type's input routine
become <literal>\</> and <literal>"</> respectively. (If we were working become <literal>\</literal> and <literal>"</literal> respectively. (If we were working
with a data type whose input routine also treated backslashes specially, with a data type whose input routine also treated backslashes specially,
<type>bytea</> for example, we might need as many as eight backslashes <type>bytea</type> for example, we might need as many as eight backslashes
in the command to get one backslash into the stored array element.) in the command to get one backslash into the stored array element.)
Dollar quoting (see <xref linkend="sql-syntax-dollar-quoting">) can be Dollar quoting (see <xref linkend="sql-syntax-dollar-quoting">) can be
used to avoid the need to double backslashes. used to avoid the need to double backslashes.
@ -804,10 +804,10 @@ INSERT ... VALUES (E'{"\\\\","\\""}');
<tip> <tip>
<para> <para>
The <literal>ARRAY</> constructor syntax (see The <literal>ARRAY</literal> constructor syntax (see
<xref linkend="sql-syntax-array-constructors">) is often easier to work <xref linkend="sql-syntax-array-constructors">) is often easier to work
with than the array-literal syntax when writing array values in SQL with than the array-literal syntax when writing array values in SQL
commands. In <literal>ARRAY</>, individual element values are written the commands. In <literal>ARRAY</literal>, individual element values are written the
same way they would be written when not members of an array. same way they would be written when not members of an array.
</para> </para>
</tip> </tip>

View File

@ -18,7 +18,7 @@
<para> <para>
In order to function, this module must be loaded via In order to function, this module must be loaded via
<xref linkend="guc-shared-preload-libraries"> in <filename>postgresql.conf</>. <xref linkend="guc-shared-preload-libraries"> in <filename>postgresql.conf</filename>.
</para> </para>
<sect2> <sect2>
@ -29,7 +29,7 @@
<term> <term>
<varname>auth_delay.milliseconds</varname> (<type>int</type>) <varname>auth_delay.milliseconds</varname> (<type>int</type>)
<indexterm> <indexterm>
<primary><varname>auth_delay.milliseconds</> configuration parameter</primary> <primary><varname>auth_delay.milliseconds</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
@ -42,7 +42,7 @@
</variablelist> </variablelist>
<para> <para>
These parameters must be set in <filename>postgresql.conf</>. These parameters must be set in <filename>postgresql.conf</filename>.
Typical usage might be: Typical usage might be:
</para> </para>

View File

@ -24,10 +24,10 @@ LOAD 'auto_explain';
</programlisting> </programlisting>
(You must be superuser to do that.) More typical usage is to preload (You must be superuser to do that.) More typical usage is to preload
it into some or all sessions by including <literal>auto_explain</> in it into some or all sessions by including <literal>auto_explain</literal> in
<xref linkend="guc-session-preload-libraries"> or <xref linkend="guc-session-preload-libraries"> or
<xref linkend="guc-shared-preload-libraries"> in <xref linkend="guc-shared-preload-libraries"> in
<filename>postgresql.conf</>. Then you can track unexpectedly slow queries <filename>postgresql.conf</filename>. Then you can track unexpectedly slow queries
no matter when they happen. Of course there is a price in overhead for no matter when they happen. Of course there is a price in overhead for
that. that.
</para> </para>
@ -47,7 +47,7 @@ LOAD 'auto_explain';
<term> <term>
<varname>auto_explain.log_min_duration</varname> (<type>integer</type>) <varname>auto_explain.log_min_duration</varname> (<type>integer</type>)
<indexterm> <indexterm>
<primary><varname>auto_explain.log_min_duration</> configuration parameter</primary> <primary><varname>auto_explain.log_min_duration</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
@ -66,13 +66,13 @@ LOAD 'auto_explain';
<term> <term>
<varname>auto_explain.log_analyze</varname> (<type>boolean</type>) <varname>auto_explain.log_analyze</varname> (<type>boolean</type>)
<indexterm> <indexterm>
<primary><varname>auto_explain.log_analyze</> configuration parameter</primary> <primary><varname>auto_explain.log_analyze</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
<varname>auto_explain.log_analyze</varname> causes <command>EXPLAIN ANALYZE</> <varname>auto_explain.log_analyze</varname> causes <command>EXPLAIN ANALYZE</command>
output, rather than just <command>EXPLAIN</> output, to be printed output, rather than just <command>EXPLAIN</command> output, to be printed
when an execution plan is logged. This parameter is off by default. when an execution plan is logged. This parameter is off by default.
Only superusers can change this setting. Only superusers can change this setting.
</para> </para>
@ -92,14 +92,14 @@ LOAD 'auto_explain';
<term> <term>
<varname>auto_explain.log_buffers</varname> (<type>boolean</type>) <varname>auto_explain.log_buffers</varname> (<type>boolean</type>)
<indexterm> <indexterm>
<primary><varname>auto_explain.log_buffers</> configuration parameter</primary> <primary><varname>auto_explain.log_buffers</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
<varname>auto_explain.log_buffers</varname> controls whether buffer <varname>auto_explain.log_buffers</varname> controls whether buffer
usage statistics are printed when an execution plan is logged; it's usage statistics are printed when an execution plan is logged; it's
equivalent to the <literal>BUFFERS</> option of <command>EXPLAIN</>. equivalent to the <literal>BUFFERS</literal> option of <command>EXPLAIN</command>.
This parameter has no effect This parameter has no effect
unless <varname>auto_explain.log_analyze</varname> is enabled. unless <varname>auto_explain.log_analyze</varname> is enabled.
This parameter is off by default. This parameter is off by default.
@ -112,14 +112,14 @@ LOAD 'auto_explain';
<term> <term>
<varname>auto_explain.log_timing</varname> (<type>boolean</type>) <varname>auto_explain.log_timing</varname> (<type>boolean</type>)
<indexterm> <indexterm>
<primary><varname>auto_explain.log_timing</> configuration parameter</primary> <primary><varname>auto_explain.log_timing</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
<varname>auto_explain.log_timing</varname> controls whether per-node <varname>auto_explain.log_timing</varname> controls whether per-node
timing information is printed when an execution plan is logged; it's timing information is printed when an execution plan is logged; it's
equivalent to the <literal>TIMING</> option of <command>EXPLAIN</>. equivalent to the <literal>TIMING</literal> option of <command>EXPLAIN</command>.
The overhead of repeatedly reading the system clock can slow down The overhead of repeatedly reading the system clock can slow down
queries significantly on some systems, so it may be useful to set this queries significantly on some systems, so it may be useful to set this
parameter to off when only actual row counts, and not exact times, are parameter to off when only actual row counts, and not exact times, are
@ -136,7 +136,7 @@ LOAD 'auto_explain';
<term> <term>
<varname>auto_explain.log_triggers</varname> (<type>boolean</type>) <varname>auto_explain.log_triggers</varname> (<type>boolean</type>)
<indexterm> <indexterm>
<primary><varname>auto_explain.log_triggers</> configuration parameter</primary> <primary><varname>auto_explain.log_triggers</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
@ -155,14 +155,14 @@ LOAD 'auto_explain';
<term> <term>
<varname>auto_explain.log_verbose</varname> (<type>boolean</type>) <varname>auto_explain.log_verbose</varname> (<type>boolean</type>)
<indexterm> <indexterm>
<primary><varname>auto_explain.log_verbose</> configuration parameter</primary> <primary><varname>auto_explain.log_verbose</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
<varname>auto_explain.log_verbose</varname> controls whether verbose <varname>auto_explain.log_verbose</varname> controls whether verbose
details are printed when an execution plan is logged; it's details are printed when an execution plan is logged; it's
equivalent to the <literal>VERBOSE</> option of <command>EXPLAIN</>. equivalent to the <literal>VERBOSE</literal> option of <command>EXPLAIN</command>.
This parameter is off by default. This parameter is off by default.
Only superusers can change this setting. Only superusers can change this setting.
</para> </para>
@ -173,13 +173,13 @@ LOAD 'auto_explain';
<term> <term>
<varname>auto_explain.log_format</varname> (<type>enum</type>) <varname>auto_explain.log_format</varname> (<type>enum</type>)
<indexterm> <indexterm>
<primary><varname>auto_explain.log_format</> configuration parameter</primary> <primary><varname>auto_explain.log_format</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
<varname>auto_explain.log_format</varname> selects the <varname>auto_explain.log_format</varname> selects the
<command>EXPLAIN</> output format to be used. <command>EXPLAIN</command> output format to be used.
The allowed values are <literal>text</literal>, <literal>xml</literal>, The allowed values are <literal>text</literal>, <literal>xml</literal>,
<literal>json</literal>, and <literal>yaml</literal>. The default is text. <literal>json</literal>, and <literal>yaml</literal>. The default is text.
Only superusers can change this setting. Only superusers can change this setting.
@ -191,7 +191,7 @@ LOAD 'auto_explain';
<term> <term>
<varname>auto_explain.log_nested_statements</varname> (<type>boolean</type>) <varname>auto_explain.log_nested_statements</varname> (<type>boolean</type>)
<indexterm> <indexterm>
<primary><varname>auto_explain.log_nested_statements</> configuration parameter</primary> <primary><varname>auto_explain.log_nested_statements</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
@ -208,7 +208,7 @@ LOAD 'auto_explain';
<term> <term>
<varname>auto_explain.sample_rate</varname> (<type>real</type>) <varname>auto_explain.sample_rate</varname> (<type>real</type>)
<indexterm> <indexterm>
<primary><varname>auto_explain.sample_rate</> configuration parameter</primary> <primary><varname>auto_explain.sample_rate</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
@ -224,7 +224,7 @@ LOAD 'auto_explain';
<para> <para>
In ordinary usage, these parameters are set In ordinary usage, these parameters are set
in <filename>postgresql.conf</>, although superusers can alter them in <filename>postgresql.conf</filename>, although superusers can alter them
on-the-fly within their own sessions. on-the-fly within their own sessions.
Typical usage might be: Typical usage might be:
</para> </para>

File diff suppressed because it is too large Load Diff

View File

@ -11,17 +11,17 @@
PostgreSQL can be extended to run user-supplied code in separate processes. PostgreSQL can be extended to run user-supplied code in separate processes.
Such processes are started, stopped and monitored by <command>postgres</command>, Such processes are started, stopped and monitored by <command>postgres</command>,
which permits them to have a lifetime closely linked to the server's status. which permits them to have a lifetime closely linked to the server's status.
These processes have the option to attach to <productname>PostgreSQL</>'s These processes have the option to attach to <productname>PostgreSQL</productname>'s
shared memory area and to connect to databases internally; they can also run shared memory area and to connect to databases internally; they can also run
multiple transactions serially, just like a regular client-connected server multiple transactions serially, just like a regular client-connected server
process. Also, by linking to <application>libpq</> they can connect to the process. Also, by linking to <application>libpq</application> they can connect to the
server and behave like a regular client application. server and behave like a regular client application.
</para> </para>
<warning> <warning>
<para> <para>
There are considerable robustness and security risks in using background There are considerable robustness and security risks in using background
worker processes because, being written in the <literal>C</> language, worker processes because, being written in the <literal>C</literal> language,
they have unrestricted access to data. Administrators wishing to enable they have unrestricted access to data. Administrators wishing to enable
modules that include background worker process should exercise extreme modules that include background worker process should exercise extreme
caution. Only carefully audited modules should be permitted to run caution. Only carefully audited modules should be permitted to run
@ -31,15 +31,15 @@
<para> <para>
Background workers can be initialized at the time that Background workers can be initialized at the time that
<productname>PostgreSQL</> is started by including the module name in <productname>PostgreSQL</productname> is started by including the module name in
<varname>shared_preload_libraries</>. A module wishing to run a background <varname>shared_preload_libraries</varname>. A module wishing to run a background
worker can register it by calling worker can register it by calling
<function>RegisterBackgroundWorker(<type>BackgroundWorker *worker</type>)</function> <function>RegisterBackgroundWorker(<type>BackgroundWorker *worker</type>)</function>
from its <function>_PG_init()</>. Background workers can also be started from its <function>_PG_init()</function>. Background workers can also be started
after the system is up and running by calling the function after the system is up and running by calling the function
<function>RegisterDynamicBackgroundWorker(<type>BackgroundWorker <function>RegisterDynamicBackgroundWorker(<type>BackgroundWorker
*worker, BackgroundWorkerHandle **handle</type>)</function>. Unlike *worker, BackgroundWorkerHandle **handle</type>)</function>. Unlike
<function>RegisterBackgroundWorker</>, which can only be called from within <function>RegisterBackgroundWorker</function>, which can only be called from within
the postmaster, <function>RegisterDynamicBackgroundWorker</function> must be the postmaster, <function>RegisterDynamicBackgroundWorker</function> must be
called from a regular backend. called from a regular backend.
</para> </para>
@ -65,7 +65,7 @@ typedef struct BackgroundWorker
</para> </para>
<para> <para>
<structfield>bgw_name</> and <structfield>bgw_type</structfield> are <structfield>bgw_name</structfield> and <structfield>bgw_type</structfield> are
strings to be used in log messages, process listings and similar contexts. strings to be used in log messages, process listings and similar contexts.
<structfield>bgw_type</structfield> should be the same for all background <structfield>bgw_type</structfield> should be the same for all background
workers of the same type, so that it is possible to group such workers in a workers of the same type, so that it is possible to group such workers in a
@ -76,7 +76,7 @@ typedef struct BackgroundWorker
</para> </para>
<para> <para>
<structfield>bgw_flags</> is a bitwise-or'd bit mask indicating the <structfield>bgw_flags</structfield> is a bitwise-or'd bit mask indicating the
capabilities that the module wants. Possible values are: capabilities that the module wants. Possible values are:
<variablelist> <variablelist>
@ -114,14 +114,14 @@ typedef struct BackgroundWorker
<para> <para>
<structfield>bgw_start_time</structfield> is the server state during which <structfield>bgw_start_time</structfield> is the server state during which
<command>postgres</> should start the process; it can be one of <command>postgres</command> should start the process; it can be one of
<literal>BgWorkerStart_PostmasterStart</> (start as soon as <literal>BgWorkerStart_PostmasterStart</literal> (start as soon as
<command>postgres</> itself has finished its own initialization; processes <command>postgres</command> itself has finished its own initialization; processes
requesting this are not eligible for database connections), requesting this are not eligible for database connections),
<literal>BgWorkerStart_ConsistentState</> (start as soon as a consistent state <literal>BgWorkerStart_ConsistentState</literal> (start as soon as a consistent state
has been reached in a hot standby, allowing processes to connect to has been reached in a hot standby, allowing processes to connect to
databases and run read-only queries), and databases and run read-only queries), and
<literal>BgWorkerStart_RecoveryFinished</> (start as soon as the system has <literal>BgWorkerStart_RecoveryFinished</literal> (start as soon as the system has
entered normal read-write state). Note the last two values are equivalent entered normal read-write state). Note the last two values are equivalent
in a server that's not a hot standby. Note that this setting only indicates in a server that's not a hot standby. Note that this setting only indicates
when the processes are to be started; they do not stop when a different state when the processes are to be started; they do not stop when a different state
@ -152,9 +152,9 @@ typedef struct BackgroundWorker
</para> </para>
<para> <para>
<structfield>bgw_main_arg</structfield> is the <type>Datum</> argument <structfield>bgw_main_arg</structfield> is the <type>Datum</type> argument
to the background worker main function. This main function should take a to the background worker main function. This main function should take a
single argument of type <type>Datum</> and return <type>void</>. single argument of type <type>Datum</type> and return <type>void</type>.
<structfield>bgw_main_arg</structfield> will be passed as the argument. <structfield>bgw_main_arg</structfield> will be passed as the argument.
In addition, the global variable <literal>MyBgworkerEntry</literal> In addition, the global variable <literal>MyBgworkerEntry</literal>
points to a copy of the <structname>BackgroundWorker</structname> structure points to a copy of the <structname>BackgroundWorker</structname> structure
@ -165,39 +165,39 @@ typedef struct BackgroundWorker
<para> <para>
On Windows (and anywhere else where <literal>EXEC_BACKEND</literal> is On Windows (and anywhere else where <literal>EXEC_BACKEND</literal> is
defined) or in dynamic background workers it is not safe to pass a defined) or in dynamic background workers it is not safe to pass a
<type>Datum</> by reference, only by value. If an argument is required, it <type>Datum</type> by reference, only by value. If an argument is required, it
is safest to pass an int32 or other small value and use that as an index is safest to pass an int32 or other small value and use that as an index
into an array allocated in shared memory. If a value like a <type>cstring</> into an array allocated in shared memory. If a value like a <type>cstring</type>
or <type>text</type> is passed then the pointer won't be valid from the or <type>text</type> is passed then the pointer won't be valid from the
new background worker process. new background worker process.
</para> </para>
<para> <para>
<structfield>bgw_extra</structfield> can contain extra data to be passed <structfield>bgw_extra</structfield> can contain extra data to be passed
to the background worker. Unlike <structfield>bgw_main_arg</>, this data to the background worker. Unlike <structfield>bgw_main_arg</structfield>, this data
is not passed as an argument to the worker's main function, but it can be is not passed as an argument to the worker's main function, but it can be
accessed via <literal>MyBgworkerEntry</literal>, as discussed above. accessed via <literal>MyBgworkerEntry</literal>, as discussed above.
</para> </para>
<para> <para>
<structfield>bgw_notify_pid</structfield> is the PID of a PostgreSQL <structfield>bgw_notify_pid</structfield> is the PID of a PostgreSQL
backend process to which the postmaster should send <literal>SIGUSR1</> backend process to which the postmaster should send <literal>SIGUSR1</literal>
when the process is started or exits. It should be 0 for workers registered when the process is started or exits. It should be 0 for workers registered
at postmaster startup time, or when the backend registering the worker does at postmaster startup time, or when the backend registering the worker does
not wish to wait for the worker to start up. Otherwise, it should be not wish to wait for the worker to start up. Otherwise, it should be
initialized to <literal>MyProcPid</>. initialized to <literal>MyProcPid</literal>.
</para> </para>
<para>Once running, the process can connect to a database by calling <para>Once running, the process can connect to a database by calling
<function>BackgroundWorkerInitializeConnection(<parameter>char *dbname</parameter>, <parameter>char *username</parameter>)</function> or <function>BackgroundWorkerInitializeConnection(<parameter>char *dbname</parameter>, <parameter>char *username</parameter>)</function> or
<function>BackgroundWorkerInitializeConnectionByOid(<parameter>Oid dboid</parameter>, <parameter>Oid useroid</parameter>)</function>. <function>BackgroundWorkerInitializeConnectionByOid(<parameter>Oid dboid</parameter>, <parameter>Oid useroid</parameter>)</function>.
This allows the process to run transactions and queries using the This allows the process to run transactions and queries using the
<literal>SPI</literal> interface. If <varname>dbname</> is NULL or <literal>SPI</literal> interface. If <varname>dbname</varname> is NULL or
<varname>dboid</> is <literal>InvalidOid</>, the session is not connected <varname>dboid</varname> is <literal>InvalidOid</literal>, the session is not connected
to any particular database, but shared catalogs can be accessed. to any particular database, but shared catalogs can be accessed.
If <varname>username</> is NULL or <varname>useroid</> is If <varname>username</varname> is NULL or <varname>useroid</varname> is
<literal>InvalidOid</>, the process will run as the superuser created <literal>InvalidOid</literal>, the process will run as the superuser created
during <command>initdb</>. during <command>initdb</command>.
A background worker can only call one of these two functions, and only A background worker can only call one of these two functions, and only
once. It is not possible to switch databases. once. It is not possible to switch databases.
</para> </para>
@ -207,24 +207,24 @@ typedef struct BackgroundWorker
background worker's main function, and must be unblocked by it; this is to background worker's main function, and must be unblocked by it; this is to
allow the process to customize its signal handlers, if necessary. allow the process to customize its signal handlers, if necessary.
Signals can be unblocked in the new process by calling Signals can be unblocked in the new process by calling
<function>BackgroundWorkerUnblockSignals</> and blocked by calling <function>BackgroundWorkerUnblockSignals</function> and blocked by calling
<function>BackgroundWorkerBlockSignals</>. <function>BackgroundWorkerBlockSignals</function>.
</para> </para>
<para> <para>
If <structfield>bgw_restart_time</structfield> for a background worker is If <structfield>bgw_restart_time</structfield> for a background worker is
configured as <literal>BGW_NEVER_RESTART</>, or if it exits with an exit configured as <literal>BGW_NEVER_RESTART</literal>, or if it exits with an exit
code of 0 or is terminated by <function>TerminateBackgroundWorker</>, code of 0 or is terminated by <function>TerminateBackgroundWorker</function>,
it will be automatically unregistered by the postmaster on exit. it will be automatically unregistered by the postmaster on exit.
Otherwise, it will be restarted after the time period configured via Otherwise, it will be restarted after the time period configured via
<structfield>bgw_restart_time</>, or immediately if the postmaster <structfield>bgw_restart_time</structfield>, or immediately if the postmaster
reinitializes the cluster due to a backend failure. Backends which need reinitializes the cluster due to a backend failure. Backends which need
to suspend execution only temporarily should use an interruptible sleep to suspend execution only temporarily should use an interruptible sleep
rather than exiting; this can be achieved by calling rather than exiting; this can be achieved by calling
<function>WaitLatch()</function>. Make sure the <function>WaitLatch()</function>. Make sure the
<literal>WL_POSTMASTER_DEATH</> flag is set when calling that function, and <literal>WL_POSTMASTER_DEATH</literal> flag is set when calling that function, and
verify the return code for a prompt exit in the emergency case that verify the return code for a prompt exit in the emergency case that
<command>postgres</> itself has terminated. <command>postgres</command> itself has terminated.
</para> </para>
<para> <para>
@ -238,29 +238,29 @@ typedef struct BackgroundWorker
opaque handle that can subsequently be passed to opaque handle that can subsequently be passed to
<function>GetBackgroundWorkerPid(<parameter>BackgroundWorkerHandle *</parameter>, <parameter>pid_t *</parameter>)</function> or <function>GetBackgroundWorkerPid(<parameter>BackgroundWorkerHandle *</parameter>, <parameter>pid_t *</parameter>)</function> or
<function>TerminateBackgroundWorker(<parameter>BackgroundWorkerHandle *</parameter>)</function>. <function>TerminateBackgroundWorker(<parameter>BackgroundWorkerHandle *</parameter>)</function>.
<function>GetBackgroundWorkerPid</> can be used to poll the status of the <function>GetBackgroundWorkerPid</function> can be used to poll the status of the
worker: a return value of <literal>BGWH_NOT_YET_STARTED</> indicates that worker: a return value of <literal>BGWH_NOT_YET_STARTED</literal> indicates that
the worker has not yet been started by the postmaster; the worker has not yet been started by the postmaster;
<literal>BGWH_STOPPED</literal> indicates that it has been started but is <literal>BGWH_STOPPED</literal> indicates that it has been started but is
no longer running; and <literal>BGWH_STARTED</literal> indicates that it is no longer running; and <literal>BGWH_STARTED</literal> indicates that it is
currently running. In this last case, the PID will also be returned via the currently running. In this last case, the PID will also be returned via the
second argument. second argument.
<function>TerminateBackgroundWorker</> causes the postmaster to send <function>TerminateBackgroundWorker</function> causes the postmaster to send
<literal>SIGTERM</> to the worker if it is running, and to unregister it <literal>SIGTERM</literal> to the worker if it is running, and to unregister it
as soon as it is not. as soon as it is not.
</para> </para>
<para> <para>
In some cases, a process which registers a background worker may wish to In some cases, a process which registers a background worker may wish to
wait for the worker to start up. This can be accomplished by initializing wait for the worker to start up. This can be accomplished by initializing
<structfield>bgw_notify_pid</structfield> to <literal>MyProcPid</> and <structfield>bgw_notify_pid</structfield> to <literal>MyProcPid</literal> and
then passing the <type>BackgroundWorkerHandle *</type> obtained at then passing the <type>BackgroundWorkerHandle *</type> obtained at
registration time to registration time to
<function>WaitForBackgroundWorkerStartup(<parameter>BackgroundWorkerHandle <function>WaitForBackgroundWorkerStartup(<parameter>BackgroundWorkerHandle
*handle</parameter>, <parameter>pid_t *</parameter>)</function> function. *handle</parameter>, <parameter>pid_t *</parameter>)</function> function.
This function will block until the postmaster has attempted to start the This function will block until the postmaster has attempted to start the
background worker, or until the postmaster dies. If the background runner background worker, or until the postmaster dies. If the background runner
is running, the return value will <literal>BGWH_STARTED</>, and is running, the return value will <literal>BGWH_STARTED</literal>, and
the PID will be written to the provided address. Otherwise, the return the PID will be written to the provided address. Otherwise, the return
value will be <literal>BGWH_STOPPED</literal> or value will be <literal>BGWH_STOPPED</literal> or
<literal>BGWH_POSTMASTER_DIED</literal>. <literal>BGWH_POSTMASTER_DIED</literal>.
@ -279,7 +279,7 @@ typedef struct BackgroundWorker
</para> </para>
<para> <para>
The <filename>src/test/modules/worker_spi</> module The <filename>src/test/modules/worker_spi</filename> module
contains a working example, contains a working example,
which demonstrates some useful techniques. which demonstrates some useful techniques.
</para> </para>

View File

@ -171,7 +171,7 @@ ssimkovi@ag.or.at
<abstract> <abstract>
<para> <para>
Discusses SQL history and syntax, and describes the addition of Discusses SQL history and syntax, and describes the addition of
<literal>INTERSECT</> and <literal>EXCEPT</> constructs into <literal>INTERSECT</literal> and <literal>EXCEPT</literal> constructs into
<productname>PostgreSQL</productname>. Prepared as a Master's <productname>PostgreSQL</productname>. Prepared as a Master's
Thesis with the support of O. Univ. Prof. Dr. Georg Gottlob and Thesis with the support of O. Univ. Prof. Dr. Georg Gottlob and
Univ. Ass. Mag. Katrin Seyr at Vienna University of Technology. Univ. Ass. Mag. Katrin Seyr at Vienna University of Technology.

View File

@ -21,7 +21,7 @@
input file used by <application>initdb</application> is created as input file used by <application>initdb</application> is created as
part of building and installing <productname>PostgreSQL</productname> part of building and installing <productname>PostgreSQL</productname>
by a program named <filename>genbki.pl</filename>, which reads some by a program named <filename>genbki.pl</filename>, which reads some
specially formatted C header files in the <filename>src/include/catalog/</> specially formatted C header files in the <filename>src/include/catalog/</filename>
directory of the source tree. The created <acronym>BKI</acronym> file directory of the source tree. The created <acronym>BKI</acronym> file
is called <filename>postgres.bki</filename> and is is called <filename>postgres.bki</filename> and is
normally installed in the normally installed in the
@ -67,13 +67,13 @@
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term> <term>
<literal>create</> <literal>create</literal>
<replaceable class="parameter">tablename</replaceable> <replaceable class="parameter">tablename</replaceable>
<replaceable class="parameter">tableoid</replaceable> <replaceable class="parameter">tableoid</replaceable>
<optional><literal>bootstrap</></optional> <optional><literal>bootstrap</literal></optional>
<optional><literal>shared_relation</></optional> <optional><literal>shared_relation</literal></optional>
<optional><literal>without_oids</></optional> <optional><literal>without_oids</literal></optional>
<optional><literal>rowtype_oid</> <replaceable>oid</></optional> <optional><literal>rowtype_oid</literal> <replaceable>oid</replaceable></optional>
(<replaceable class="parameter">name1</replaceable> = (<replaceable class="parameter">name1</replaceable> =
<replaceable class="parameter">type1</replaceable> <replaceable class="parameter">type1</replaceable>
<optional>FORCE NOT NULL | FORCE NULL </optional> <optional>, <optional>FORCE NOT NULL | FORCE NULL </optional> <optional>,
@ -93,7 +93,7 @@
<para> <para>
The following column types are supported directly by The following column types are supported directly by
<filename>bootstrap.c</>: <type>bool</type>, <filename>bootstrap.c</filename>: <type>bool</type>,
<type>bytea</type>, <type>char</type> (1 byte), <type>bytea</type>, <type>char</type> (1 byte),
<type>name</type>, <type>int2</type>, <type>name</type>, <type>int2</type>,
<type>int4</type>, <type>regproc</type>, <type>regclass</type>, <type>int4</type>, <type>regproc</type>, <type>regclass</type>,
@ -104,31 +104,31 @@
<type>_oid</type> (array), <type>_char</type> (array), <type>_oid</type> (array), <type>_char</type> (array),
<type>_aclitem</type> (array). Although it is possible to create <type>_aclitem</type> (array). Although it is possible to create
tables containing columns of other types, this cannot be done until tables containing columns of other types, this cannot be done until
after <structname>pg_type</> has been created and filled with after <structname>pg_type</structname> has been created and filled with
appropriate entries. (That effectively means that only these appropriate entries. (That effectively means that only these
column types can be used in bootstrapped tables, but non-bootstrap column types can be used in bootstrapped tables, but non-bootstrap
catalogs can contain any built-in type.) catalogs can contain any built-in type.)
</para> </para>
<para> <para>
When <literal>bootstrap</> is specified, When <literal>bootstrap</literal> is specified,
the table will only be created on disk; nothing is entered into the table will only be created on disk; nothing is entered into
<structname>pg_class</structname>, <structname>pg_class</structname>,
<structname>pg_attribute</structname>, etc, for it. Thus the <structname>pg_attribute</structname>, etc, for it. Thus the
table will not be accessible by ordinary SQL operations until table will not be accessible by ordinary SQL operations until
such entries are made the hard way (with <literal>insert</> such entries are made the hard way (with <literal>insert</literal>
commands). This option is used for creating commands). This option is used for creating
<structname>pg_class</structname> etc themselves. <structname>pg_class</structname> etc themselves.
</para> </para>
<para> <para>
The table is created as shared if <literal>shared_relation</> is The table is created as shared if <literal>shared_relation</literal> is
specified. specified.
It will have OIDs unless <literal>without_oids</> is specified. It will have OIDs unless <literal>without_oids</literal> is specified.
The table's row type OID (<structname>pg_type</> OID) can optionally The table's row type OID (<structname>pg_type</structname> OID) can optionally
be specified via the <literal>rowtype_oid</> clause; if not specified, be specified via the <literal>rowtype_oid</literal> clause; if not specified,
an OID is automatically generated for it. (The <literal>rowtype_oid</> an OID is automatically generated for it. (The <literal>rowtype_oid</literal>
clause is useless if <literal>bootstrap</> is specified, but it can be clause is useless if <literal>bootstrap</literal> is specified, but it can be
provided anyway for documentation.) provided anyway for documentation.)
</para> </para>
</listitem> </listitem>
@ -136,7 +136,7 @@
<varlistentry> <varlistentry>
<term> <term>
<literal>open</> <replaceable class="parameter">tablename</replaceable> <literal>open</literal> <replaceable class="parameter">tablename</replaceable>
</term> </term>
<listitem> <listitem>
@ -150,7 +150,7 @@
<varlistentry> <varlistentry>
<term> <term>
<literal>close</> <optional><replaceable class="parameter">tablename</replaceable></optional> <literal>close</literal> <optional><replaceable class="parameter">tablename</replaceable></optional>
</term> </term>
<listitem> <listitem>
@ -163,7 +163,7 @@
<varlistentry> <varlistentry>
<term> <term>
<literal>insert</> <optional><literal>OID =</> <replaceable class="parameter">oid_value</replaceable></optional> <literal>(</> <replaceable class="parameter">value1</replaceable> <replaceable class="parameter">value2</replaceable> ... <literal>)</> <literal>insert</literal> <optional><literal>OID =</literal> <replaceable class="parameter">oid_value</replaceable></optional> <literal>(</literal> <replaceable class="parameter">value1</replaceable> <replaceable class="parameter">value2</replaceable> ... <literal>)</literal>
</term> </term>
<listitem> <listitem>
@ -188,14 +188,14 @@
<varlistentry> <varlistentry>
<term> <term>
<literal>declare</> <optional><literal>unique</></optional> <literal>declare</literal> <optional><literal>unique</literal></optional>
<literal>index</> <replaceable class="parameter">indexname</replaceable> <literal>index</literal> <replaceable class="parameter">indexname</replaceable>
<replaceable class="parameter">indexoid</replaceable> <replaceable class="parameter">indexoid</replaceable>
<literal>on</> <replaceable class="parameter">tablename</replaceable> <literal>on</literal> <replaceable class="parameter">tablename</replaceable>
<literal>using</> <replaceable class="parameter">amname</replaceable> <literal>using</literal> <replaceable class="parameter">amname</replaceable>
<literal>(</> <replaceable class="parameter">opclass1</replaceable> <literal>(</literal> <replaceable class="parameter">opclass1</replaceable>
<replaceable class="parameter">name1</replaceable> <replaceable class="parameter">name1</replaceable>
<optional>, ...</optional> <literal>)</> <optional>, ...</optional> <literal>)</literal>
</term> </term>
<listitem> <listitem>
@ -220,10 +220,10 @@
<varlistentry> <varlistentry>
<term> <term>
<literal>declare toast</> <literal>declare toast</literal>
<replaceable class="parameter">toasttableoid</replaceable> <replaceable class="parameter">toasttableoid</replaceable>
<replaceable class="parameter">toastindexoid</replaceable> <replaceable class="parameter">toastindexoid</replaceable>
<literal>on</> <replaceable class="parameter">tablename</replaceable> <literal>on</literal> <replaceable class="parameter">tablename</replaceable>
</term> </term>
<listitem> <listitem>
@ -234,14 +234,14 @@
<replaceable class="parameter">toasttableoid</replaceable> <replaceable class="parameter">toasttableoid</replaceable>
and its index is assigned OID and its index is assigned OID
<replaceable class="parameter">toastindexoid</replaceable>. <replaceable class="parameter">toastindexoid</replaceable>.
As with <literal>declare index</>, filling of the index As with <literal>declare index</literal>, filling of the index
is postponed. is postponed.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>build indices</></term> <term><literal>build indices</literal></term>
<listitem> <listitem>
<para> <para>
@ -257,17 +257,17 @@
<title>Structure of the Bootstrap <acronym>BKI</acronym> File</title> <title>Structure of the Bootstrap <acronym>BKI</acronym> File</title>
<para> <para>
The <literal>open</> command cannot be used until the tables it uses The <literal>open</literal> command cannot be used until the tables it uses
exist and have entries for the table that is to be opened. exist and have entries for the table that is to be opened.
(These minimum tables are <structname>pg_class</>, (These minimum tables are <structname>pg_class</structname>,
<structname>pg_attribute</>, <structname>pg_proc</>, and <structname>pg_attribute</structname>, <structname>pg_proc</structname>, and
<structname>pg_type</>.) To allow those tables themselves to be filled, <structname>pg_type</structname>.) To allow those tables themselves to be filled,
<literal>create</> with the <literal>bootstrap</> option implicitly opens <literal>create</literal> with the <literal>bootstrap</literal> option implicitly opens
the created table for data insertion. the created table for data insertion.
</para> </para>
<para> <para>
Also, the <literal>declare index</> and <literal>declare toast</> Also, the <literal>declare index</literal> and <literal>declare toast</literal>
commands cannot be used until the system catalogs they need have been commands cannot be used until the system catalogs they need have been
created and filled in. created and filled in.
</para> </para>
@ -278,17 +278,17 @@
<orderedlist> <orderedlist>
<listitem> <listitem>
<para> <para>
<literal>create bootstrap</> one of the critical tables <literal>create bootstrap</literal> one of the critical tables
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<literal>insert</> data describing at least the critical tables <literal>insert</literal> data describing at least the critical tables
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<literal>close</> <literal>close</literal>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
@ -298,22 +298,22 @@
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<literal>create</> (without <literal>bootstrap</>) a noncritical table <literal>create</literal> (without <literal>bootstrap</literal>) a noncritical table
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<literal>open</> <literal>open</literal>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<literal>insert</> desired data <literal>insert</literal> desired data
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<literal>close</> <literal>close</literal>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
@ -328,7 +328,7 @@
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<literal>build indices</> <literal>build indices</literal>
</para> </para>
</listitem> </listitem>
</orderedlist> </orderedlist>

View File

@ -8,7 +8,7 @@
</indexterm> </indexterm>
<para> <para>
<literal>bloom</> provides an index access method based on <literal>bloom</literal> provides an index access method based on
<ulink url="http://en.wikipedia.org/wiki/Bloom_filter">Bloom filters</ulink>. <ulink url="http://en.wikipedia.org/wiki/Bloom_filter">Bloom filters</ulink>.
</para> </para>
@ -42,29 +42,29 @@
<title>Parameters</title> <title>Parameters</title>
<para> <para>
A <literal>bloom</> index accepts the following parameters in its A <literal>bloom</literal> index accepts the following parameters in its
<literal>WITH</> clause: <literal>WITH</literal> clause:
</para> </para>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><literal>length</></term> <term><literal>length</literal></term>
<listitem> <listitem>
<para> <para>
Length of each signature (index entry) in bits. The default Length of each signature (index entry) in bits. The default
is <literal>80</> bits and maximum is <literal>4096</>. is <literal>80</literal> bits and maximum is <literal>4096</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><literal>col1 &mdash; col32</></term> <term><literal>col1 &mdash; col32</literal></term>
<listitem> <listitem>
<para> <para>
Number of bits generated for each index column. Each parameter's name Number of bits generated for each index column. Each parameter's name
refers to the number of the index column that it controls. The default refers to the number of the index column that it controls. The default
is <literal>2</> bits and maximum is <literal>4095</>. Parameters for is <literal>2</literal> bits and maximum is <literal>4095</literal>. Parameters for
index columns not actually used are ignored. index columns not actually used are ignored.
</para> </para>
</listitem> </listitem>
@ -87,8 +87,8 @@ CREATE INDEX bloomidx ON tbloom USING bloom (i1,i2,i3)
<para> <para>
The index is created with a signature length of 80 bits, with attributes The index is created with a signature length of 80 bits, with attributes
i1 and i2 mapped to 2 bits, and attribute i3 mapped to 4 bits. We could i1 and i2 mapped to 2 bits, and attribute i3 mapped to 4 bits. We could
have omitted the <literal>length</>, <literal>col1</>, have omitted the <literal>length</literal>, <literal>col1</literal>,
and <literal>col2</> specifications since those have the default values. and <literal>col2</literal> specifications since those have the default values.
</para> </para>
<para> <para>
@ -175,7 +175,7 @@ CREATE INDEX
Note the relatively large number of false positives: 2439 rows were Note the relatively large number of false positives: 2439 rows were
selected to be visited in the heap, but none actually matched the selected to be visited in the heap, but none actually matched the
query. We could reduce that by specifying a larger signature length. query. We could reduce that by specifying a larger signature length.
In this example, creating the index with <literal>length=200</> In this example, creating the index with <literal>length=200</literal>
reduced the number of false positives to 55; but it doubled the index size reduced the number of false positives to 55; but it doubled the index size
(to 306 MB) and ended up being slower for this query (125 ms overall). (to 306 MB) and ended up being slower for this query (125 ms overall).
</para> </para>
@ -213,7 +213,7 @@ CREATE INDEX
<para> <para>
An operator class for bloom indexes requires only a hash function for the An operator class for bloom indexes requires only a hash function for the
indexed data type and an equality operator for searching. This example indexed data type and an equality operator for searching. This example
shows the operator class definition for the <type>text</> data type: shows the operator class definition for the <type>text</type> data type:
</para> </para>
<programlisting> <programlisting>
@ -230,7 +230,7 @@ DEFAULT FOR TYPE text USING bloom AS
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
Only operator classes for <type>int4</> and <type>text</> are Only operator classes for <type>int4</type> and <type>text</type> are
included with the module. included with the module.
</para> </para>
</listitem> </listitem>

View File

@ -16,7 +16,7 @@
<acronym>BRIN</acronym> is designed for handling very large tables <acronym>BRIN</acronym> is designed for handling very large tables
in which certain columns have some natural correlation with their in which certain columns have some natural correlation with their
physical location within the table. physical location within the table.
A <firstterm>block range</> is a group of pages that are physically A <firstterm>block range</firstterm> is a group of pages that are physically
adjacent in the table; for each block range, some summary info is stored adjacent in the table; for each block range, some summary info is stored
by the index. by the index.
For example, a table storing a store's sale orders might have For example, a table storing a store's sale orders might have
@ -29,7 +29,7 @@
<para> <para>
<acronym>BRIN</acronym> indexes can satisfy queries via regular bitmap <acronym>BRIN</acronym> indexes can satisfy queries via regular bitmap
index scans, and will return all tuples in all pages within each range if index scans, and will return all tuples in all pages within each range if
the summary info stored by the index is <firstterm>consistent</> with the the summary info stored by the index is <firstterm>consistent</firstterm> with the
query conditions. query conditions.
The query executor is in charge of rechecking these tuples and discarding The query executor is in charge of rechecking these tuples and discarding
those that do not match the query conditions &mdash; in other words, these those that do not match the query conditions &mdash; in other words, these
@ -51,9 +51,9 @@
<para> <para>
The size of the block range is determined at index creation time by The size of the block range is determined at index creation time by
the <literal>pages_per_range</> storage parameter. The number of index the <literal>pages_per_range</literal> storage parameter. The number of index
entries will be equal to the size of the relation in pages divided by entries will be equal to the size of the relation in pages divided by
the selected value for <literal>pages_per_range</>. Therefore, the smaller the selected value for <literal>pages_per_range</literal>. Therefore, the smaller
the number, the larger the index becomes (because of the need to the number, the larger the index becomes (because of the need to
store more index entries), but at the same time the summary data stored can store more index entries), but at the same time the summary data stored can
be more precise and more data blocks can be skipped during an index scan. be more precise and more data blocks can be skipped during an index scan.
@ -99,9 +99,9 @@
</para> </para>
<para> <para>
The <firstterm>minmax</> The <firstterm>minmax</firstterm>
operator classes store the minimum and the maximum values appearing operator classes store the minimum and the maximum values appearing
in the indexed column within the range. The <firstterm>inclusion</> in the indexed column within the range. The <firstterm>inclusion</firstterm>
operator classes store a value which includes the values in the indexed operator classes store a value which includes the values in the indexed
column within the range. column within the range.
</para> </para>
@ -162,21 +162,21 @@
</entry> </entry>
</row> </row>
<row> <row>
<entry><literal>box_inclusion_ops</></entry> <entry><literal>box_inclusion_ops</literal></entry>
<entry><type>box</type></entry> <entry><type>box</type></entry>
<entry> <entry>
<literal>&lt;&lt;</> <literal>&lt;&lt;</literal>
<literal>&amp;&lt;</> <literal>&amp;&lt;</literal>
<literal>&amp;&amp;</> <literal>&amp;&amp;</literal>
<literal>&amp;&gt;</> <literal>&amp;&gt;</literal>
<literal>&gt;&gt;</> <literal>&gt;&gt;</literal>
<literal>~=</> <literal>~=</literal>
<literal>@&gt;</> <literal>@&gt;</literal>
<literal>&lt;@</> <literal>&lt;@</literal>
<literal>&amp;&lt;|</> <literal>&amp;&lt;|</literal>
<literal>&lt;&lt;|</> <literal>&lt;&lt;|</literal>
<literal>|&gt;&gt;</literal> <literal>|&gt;&gt;</literal>
<literal>|&amp;&gt;</> <literal>|&amp;&gt;</literal>
</entry> </entry>
</row> </row>
<row> <row>
@ -249,11 +249,11 @@
<entry><literal>network_inclusion_ops</literal></entry> <entry><literal>network_inclusion_ops</literal></entry>
<entry><type>inet</type></entry> <entry><type>inet</type></entry>
<entry> <entry>
<literal>&amp;&amp;</> <literal>&amp;&amp;</literal>
<literal>&gt;&gt;=</> <literal>&gt;&gt;=</literal>
<literal>&lt;&lt;=</literal> <literal>&lt;&lt;=</literal>
<literal>=</literal> <literal>=</literal>
<literal>&gt;&gt;</> <literal>&gt;&gt;</literal>
<literal>&lt;&lt;</literal> <literal>&lt;&lt;</literal>
</entry> </entry>
</row> </row>
@ -346,18 +346,18 @@
</entry> </entry>
</row> </row>
<row> <row>
<entry><literal>range_inclusion_ops</></entry> <entry><literal>range_inclusion_ops</literal></entry>
<entry><type>any range type</type></entry> <entry><type>any range type</type></entry>
<entry> <entry>
<literal>&lt;&lt;</> <literal>&lt;&lt;</literal>
<literal>&amp;&lt;</> <literal>&amp;&lt;</literal>
<literal>&amp;&amp;</> <literal>&amp;&amp;</literal>
<literal>&amp;&gt;</> <literal>&amp;&gt;</literal>
<literal>&gt;&gt;</> <literal>&gt;&gt;</literal>
<literal>@&gt;</> <literal>@&gt;</literal>
<literal>&lt;@</> <literal>&lt;@</literal>
<literal>-|-</> <literal>-|-</literal>
<literal>=</> <literal>=</literal>
<literal>&lt;</literal> <literal>&lt;</literal>
<literal>&lt;=</literal> <literal>&lt;=</literal>
<literal>=</literal> <literal>=</literal>
@ -505,11 +505,11 @@
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><function>BrinOpcInfo *opcInfo(Oid type_oid)</></term> <term><function>BrinOpcInfo *opcInfo(Oid type_oid)</function></term>
<listitem> <listitem>
<para> <para>
Returns internal information about the indexed columns' summary data. Returns internal information about the indexed columns' summary data.
The return value must point to a palloc'd <structname>BrinOpcInfo</>, The return value must point to a palloc'd <structname>BrinOpcInfo</structname>,
which has this definition: which has this definition:
<programlisting> <programlisting>
typedef struct BrinOpcInfo typedef struct BrinOpcInfo
@ -524,7 +524,7 @@ typedef struct BrinOpcInfo
TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER]; TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER];
} BrinOpcInfo; } BrinOpcInfo;
</programlisting> </programlisting>
<structname>BrinOpcInfo</>.<structfield>oi_opaque</> can be used by the <structname>BrinOpcInfo</structname>.<structfield>oi_opaque</structfield> can be used by the
operator class routines to pass information between support procedures operator class routines to pass information between support procedures
during an index scan. during an index scan.
</para> </para>
@ -797,8 +797,8 @@ typedef struct BrinOpcInfo
It should accept two arguments with the same data type as the operator class, It should accept two arguments with the same data type as the operator class,
and return the union of them. The inclusion operator class can store union and return the union of them. The inclusion operator class can store union
values with different data types if it is defined with the values with different data types if it is defined with the
<literal>STORAGE</> parameter. The return value of the union <literal>STORAGE</literal> parameter. The return value of the union
function should match the <literal>STORAGE</> data type. function should match the <literal>STORAGE</literal> data type.
</para> </para>
<para> <para>
@ -823,11 +823,11 @@ typedef struct BrinOpcInfo
on another operator strategy as shown in on another operator strategy as shown in
<xref linkend="brin-extensibility-inclusion-table">, or the same <xref linkend="brin-extensibility-inclusion-table">, or the same
operator strategy as themselves. They require the dependency operator strategy as themselves. They require the dependency
operator to be defined with the <literal>STORAGE</> data type as the operator to be defined with the <literal>STORAGE</literal> data type as the
left-hand-side argument and the other supported data type to be the left-hand-side argument and the other supported data type to be the
right-hand-side argument of the supported operator. See right-hand-side argument of the supported operator. See
<literal>float4_minmax_ops</> as an example of minmax, and <literal>float4_minmax_ops</literal> as an example of minmax, and
<literal>box_inclusion_ops</> as an example of inclusion. <literal>box_inclusion_ops</literal> as an example of inclusion.
</para> </para>
</sect1> </sect1>
</chapter> </chapter>

View File

@ -8,16 +8,16 @@
</indexterm> </indexterm>
<para> <para>
<filename>btree_gin</> provides sample GIN operator classes that <filename>btree_gin</filename> provides sample GIN operator classes that
implement B-tree equivalent behavior for the data types implement B-tree equivalent behavior for the data types
<type>int2</>, <type>int4</>, <type>int8</>, <type>float4</>, <type>int2</type>, <type>int4</type>, <type>int8</type>, <type>float4</type>,
<type>float8</>, <type>timestamp with time zone</>, <type>float8</type>, <type>timestamp with time zone</type>,
<type>timestamp without time zone</>, <type>time with time zone</>, <type>timestamp without time zone</type>, <type>time with time zone</type>,
<type>time without time zone</>, <type>date</>, <type>interval</>, <type>time without time zone</type>, <type>date</type>, <type>interval</type>,
<type>oid</>, <type>money</>, <type>"char"</>, <type>oid</type>, <type>money</type>, <type>"char"</type>,
<type>varchar</>, <type>text</>, <type>bytea</>, <type>bit</>, <type>varchar</type>, <type>text</type>, <type>bytea</type>, <type>bit</type>,
<type>varbit</>, <type>macaddr</>, <type>macaddr8</>, <type>inet</>, <type>varbit</type>, <type>macaddr</type>, <type>macaddr8</type>, <type>inet</type>,
<type>cidr</>, and all <type>enum</> types. <type>cidr</type>, and all <type>enum</type> types.
</para> </para>
<para> <para>

View File

@ -8,16 +8,16 @@
</indexterm> </indexterm>
<para> <para>
<filename>btree_gist</> provides GiST index operator classes that <filename>btree_gist</filename> provides GiST index operator classes that
implement B-tree equivalent behavior for the data types implement B-tree equivalent behavior for the data types
<type>int2</>, <type>int4</>, <type>int8</>, <type>float4</>, <type>int2</type>, <type>int4</type>, <type>int8</type>, <type>float4</type>,
<type>float8</>, <type>numeric</>, <type>timestamp with time zone</>, <type>float8</type>, <type>numeric</type>, <type>timestamp with time zone</type>,
<type>timestamp without time zone</>, <type>time with time zone</>, <type>timestamp without time zone</type>, <type>time with time zone</type>,
<type>time without time zone</>, <type>date</>, <type>interval</>, <type>time without time zone</type>, <type>date</type>, <type>interval</type>,
<type>oid</>, <type>money</>, <type>char</>, <type>oid</type>, <type>money</type>, <type>char</type>,
<type>varchar</>, <type>text</>, <type>bytea</>, <type>bit</>, <type>varchar</type>, <type>text</type>, <type>bytea</type>, <type>bit</type>,
<type>varbit</>, <type>macaddr</>, <type>macaddr8</>, <type>inet</>, <type>varbit</type>, <type>macaddr</type>, <type>macaddr8</type>, <type>inet</type>,
<type>cidr</>, <type>uuid</>, and all <type>enum</> types. <type>cidr</type>, <type>uuid</type>, and all <type>enum</type> types.
</para> </para>
<para> <para>
@ -33,7 +33,7 @@
</para> </para>
<para> <para>
In addition to the typical B-tree search operators, <filename>btree_gist</> In addition to the typical B-tree search operators, <filename>btree_gist</filename>
also provides index support for <literal>&lt;&gt;</literal> (<quote>not also provides index support for <literal>&lt;&gt;</literal> (<quote>not
equals</quote>). This may be useful in combination with an equals</quote>). This may be useful in combination with an
<link linkend="SQL-CREATETABLE-EXCLUDE">exclusion constraint</link>, <link linkend="SQL-CREATETABLE-EXCLUDE">exclusion constraint</link>,
@ -42,14 +42,14 @@
<para> <para>
Also, for data types for which there is a natural distance metric, Also, for data types for which there is a natural distance metric,
<filename>btree_gist</> defines a distance operator <literal>&lt;-&gt;</>, <filename>btree_gist</filename> defines a distance operator <literal>&lt;-&gt;</literal>,
and provides GiST index support for nearest-neighbor searches using and provides GiST index support for nearest-neighbor searches using
this operator. Distance operators are provided for this operator. Distance operators are provided for
<type>int2</>, <type>int4</>, <type>int8</>, <type>float4</>, <type>int2</type>, <type>int4</type>, <type>int8</type>, <type>float4</type>,
<type>float8</>, <type>timestamp with time zone</>, <type>float8</type>, <type>timestamp with time zone</type>,
<type>timestamp without time zone</>, <type>timestamp without time zone</type>,
<type>time without time zone</>, <type>date</>, <type>interval</>, <type>time without time zone</type>, <type>date</type>, <type>interval</type>,
<type>oid</>, and <type>money</>. <type>oid</type>, and <type>money</type>.
</para> </para>
<sect2> <sect2>

File diff suppressed because it is too large Load Diff

View File

@ -35,12 +35,12 @@
<sect1 id="locale"> <sect1 id="locale">
<title>Locale Support</title> <title>Locale Support</title>
<indexterm zone="locale"><primary>locale</></> <indexterm zone="locale"><primary>locale</primary></indexterm>
<para> <para>
<firstterm>Locale</> support refers to an application respecting <firstterm>Locale</firstterm> support refers to an application respecting
cultural preferences regarding alphabets, sorting, number cultural preferences regarding alphabets, sorting, number
formatting, etc. <productname>PostgreSQL</> uses the standard ISO formatting, etc. <productname>PostgreSQL</productname> uses the standard ISO
C and <acronym>POSIX</acronym> locale facilities provided by the server operating C and <acronym>POSIX</acronym> locale facilities provided by the server operating
system. For additional information refer to the documentation of your system. For additional information refer to the documentation of your
system. system.
@ -67,14 +67,14 @@ initdb --locale=sv_SE
<para> <para>
This example for Unix systems sets the locale to Swedish This example for Unix systems sets the locale to Swedish
(<literal>sv</>) as spoken (<literal>sv</literal>) as spoken
in Sweden (<literal>SE</>). Other possibilities might include in Sweden (<literal>SE</literal>). Other possibilities might include
<literal>en_US</> (U.S. English) and <literal>fr_CA</> (French <literal>en_US</literal> (U.S. English) and <literal>fr_CA</literal> (French
Canadian). If more than one character set can be used for a Canadian). If more than one character set can be used for a
locale then the specifications can take the form locale then the specifications can take the form
<replaceable>language_territory.codeset</>. For example, <replaceable>language_territory.codeset</replaceable>. For example,
<literal>fr_BE.UTF-8</> represents the French language (fr) as <literal>fr_BE.UTF-8</literal> represents the French language (fr) as
spoken in Belgium (BE), with a <acronym>UTF-8</> character set spoken in Belgium (BE), with a <acronym>UTF-8</acronym> character set
encoding. encoding.
</para> </para>
@ -82,9 +82,9 @@ initdb --locale=sv_SE
What locales are available on your What locales are available on your
system under what names depends on what was provided by the operating system under what names depends on what was provided by the operating
system vendor and what was installed. On most Unix systems, the command system vendor and what was installed. On most Unix systems, the command
<literal>locale -a</> will provide a list of available locales. <literal>locale -a</literal> will provide a list of available locales.
Windows uses more verbose locale names, such as <literal>German_Germany</> Windows uses more verbose locale names, such as <literal>German_Germany</literal>
or <literal>Swedish_Sweden.1252</>, but the principles are the same. or <literal>Swedish_Sweden.1252</literal>, but the principles are the same.
</para> </para>
<para> <para>
@ -97,28 +97,28 @@ initdb --locale=sv_SE
<tgroup cols="2"> <tgroup cols="2">
<tbody> <tbody>
<row> <row>
<entry><envar>LC_COLLATE</></> <entry><envar>LC_COLLATE</envar></entry>
<entry>String sort order</> <entry>String sort order</entry>
</row> </row>
<row> <row>
<entry><envar>LC_CTYPE</></> <entry><envar>LC_CTYPE</envar></entry>
<entry>Character classification (What is a letter? Its upper-case equivalent?)</> <entry>Character classification (What is a letter? Its upper-case equivalent?)</entry>
</row> </row>
<row> <row>
<entry><envar>LC_MESSAGES</></> <entry><envar>LC_MESSAGES</envar></entry>
<entry>Language of messages</> <entry>Language of messages</entry>
</row> </row>
<row> <row>
<entry><envar>LC_MONETARY</></> <entry><envar>LC_MONETARY</envar></entry>
<entry>Formatting of currency amounts</> <entry>Formatting of currency amounts</entry>
</row> </row>
<row> <row>
<entry><envar>LC_NUMERIC</></> <entry><envar>LC_NUMERIC</envar></entry>
<entry>Formatting of numbers</> <entry>Formatting of numbers</entry>
</row> </row>
<row> <row>
<entry><envar>LC_TIME</></> <entry><envar>LC_TIME</envar></entry>
<entry>Formatting of dates and times</> <entry>Formatting of dates and times</entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
@ -133,8 +133,8 @@ initdb --locale=sv_SE
<para> <para>
If you want the system to behave as if it had no locale support, If you want the system to behave as if it had no locale support,
use the special locale name <literal>C</>, or equivalently use the special locale name <literal>C</literal>, or equivalently
<literal>POSIX</>. <literal>POSIX</literal>.
</para> </para>
<para> <para>
@ -192,14 +192,14 @@ initdb --locale=sv_SE
settings for the purpose of setting the language of messages. If settings for the purpose of setting the language of messages. If
in doubt, please refer to the documentation of your operating in doubt, please refer to the documentation of your operating
system, in particular the documentation about system, in particular the documentation about
<application>gettext</>. <application>gettext</application>.
</para> </para>
</note> </note>
<para> <para>
To enable messages to be translated to the user's preferred language, To enable messages to be translated to the user's preferred language,
<acronym>NLS</acronym> must have been selected at build time <acronym>NLS</acronym> must have been selected at build time
(<literal>configure --enable-nls</>). All other locale support is (<literal>configure --enable-nls</literal>). All other locale support is
built in automatically. built in automatically.
</para> </para>
</sect2> </sect2>
@ -213,63 +213,63 @@ initdb --locale=sv_SE
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
Sort order in queries using <literal>ORDER BY</> or the standard Sort order in queries using <literal>ORDER BY</literal> or the standard
comparison operators on textual data comparison operators on textual data
<indexterm><primary>ORDER BY</><secondary>and locales</></indexterm> <indexterm><primary>ORDER BY</primary><secondary>and locales</secondary></indexterm>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
The <function>upper</>, <function>lower</>, and <function>initcap</> The <function>upper</function>, <function>lower</function>, and <function>initcap</function>
functions functions
<indexterm><primary>upper</><secondary>and locales</></indexterm> <indexterm><primary>upper</primary><secondary>and locales</secondary></indexterm>
<indexterm><primary>lower</><secondary>and locales</></indexterm> <indexterm><primary>lower</primary><secondary>and locales</secondary></indexterm>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
Pattern matching operators (<literal>LIKE</>, <literal>SIMILAR TO</>, Pattern matching operators (<literal>LIKE</literal>, <literal>SIMILAR TO</literal>,
and POSIX-style regular expressions); locales affect both case and POSIX-style regular expressions); locales affect both case
insensitive matching and the classification of characters by insensitive matching and the classification of characters by
character-class regular expressions character-class regular expressions
<indexterm><primary>LIKE</><secondary>and locales</></indexterm> <indexterm><primary>LIKE</primary><secondary>and locales</secondary></indexterm>
<indexterm><primary>regular expressions</><secondary>and locales</></indexterm> <indexterm><primary>regular expressions</primary><secondary>and locales</secondary></indexterm>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
The <function>to_char</> family of functions The <function>to_char</function> family of functions
<indexterm><primary>to_char</><secondary>and locales</></indexterm> <indexterm><primary>to_char</primary><secondary>and locales</secondary></indexterm>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
The ability to use indexes with <literal>LIKE</> clauses The ability to use indexes with <literal>LIKE</literal> clauses
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</para> </para>
<para> <para>
The drawback of using locales other than <literal>C</> or The drawback of using locales other than <literal>C</literal> or
<literal>POSIX</> in <productname>PostgreSQL</> is its performance <literal>POSIX</literal> in <productname>PostgreSQL</productname> is its performance
impact. It slows character handling and prevents ordinary indexes impact. It slows character handling and prevents ordinary indexes
from being used by <literal>LIKE</>. For this reason use locales from being used by <literal>LIKE</literal>. For this reason use locales
only if you actually need them. only if you actually need them.
</para> </para>
<para> <para>
As a workaround to allow <productname>PostgreSQL</> to use indexes As a workaround to allow <productname>PostgreSQL</productname> to use indexes
with <literal>LIKE</> clauses under a non-C locale, several custom with <literal>LIKE</literal> clauses under a non-C locale, several custom
operator classes exist. These allow the creation of an index that operator classes exist. These allow the creation of an index that
performs a strict character-by-character comparison, ignoring performs a strict character-by-character comparison, ignoring
locale comparison rules. Refer to <xref linkend="indexes-opclass"> locale comparison rules. Refer to <xref linkend="indexes-opclass">
for more information. Another approach is to create indexes using for more information. Another approach is to create indexes using
the <literal>C</> collation, as discussed in the <literal>C</literal> collation, as discussed in
<xref linkend="collation">. <xref linkend="collation">.
</para> </para>
</sect2> </sect2>
@ -286,20 +286,20 @@ initdb --locale=sv_SE
</para> </para>
<para> <para>
Check that <productname>PostgreSQL</> is actually using the locale Check that <productname>PostgreSQL</productname> is actually using the locale
that you think it is. The <envar>LC_COLLATE</> and <envar>LC_CTYPE</> that you think it is. The <envar>LC_COLLATE</envar> and <envar>LC_CTYPE</envar>
settings are determined when a database is created, and cannot be settings are determined when a database is created, and cannot be
changed except by creating a new database. Other locale changed except by creating a new database. Other locale
settings including <envar>LC_MESSAGES</> and <envar>LC_MONETARY</> settings including <envar>LC_MESSAGES</envar> and <envar>LC_MONETARY</envar>
are initially determined by the environment the server is started are initially determined by the environment the server is started
in, but can be changed on-the-fly. You can check the active locale in, but can be changed on-the-fly. You can check the active locale
settings using the <command>SHOW</> command. settings using the <command>SHOW</command> command.
</para> </para>
<para> <para>
The directory <filename>src/test/locale</> in the source The directory <filename>src/test/locale</filename> in the source
distribution contains a test suite for distribution contains a test suite for
<productname>PostgreSQL</>'s locale support. <productname>PostgreSQL</productname>'s locale support.
</para> </para>
<para> <para>
@ -313,7 +313,7 @@ initdb --locale=sv_SE
<para> <para>
Maintaining catalogs of message translations requires the on-going Maintaining catalogs of message translations requires the on-going
efforts of many volunteers that want to see efforts of many volunteers that want to see
<productname>PostgreSQL</> speak their preferred language well. <productname>PostgreSQL</productname> speak their preferred language well.
If messages in your language are currently not available or not fully If messages in your language are currently not available or not fully
translated, your assistance would be appreciated. If you want to translated, your assistance would be appreciated. If you want to
help, refer to <xref linkend="nls"> or write to the developers' help, refer to <xref linkend="nls"> or write to the developers'
@ -326,7 +326,7 @@ initdb --locale=sv_SE
<sect1 id="collation"> <sect1 id="collation">
<title>Collation Support</title> <title>Collation Support</title>
<indexterm zone="collation"><primary>collation</></> <indexterm zone="collation"><primary>collation</primary></indexterm>
<para> <para>
The collation feature allows specifying the sort order and character The collation feature allows specifying the sort order and character
@ -370,9 +370,9 @@ initdb --locale=sv_SE
function or operator call is derived from the arguments, as described function or operator call is derived from the arguments, as described
below. In addition to comparison operators, collations are taken into below. In addition to comparison operators, collations are taken into
account by functions that convert between lower and upper case account by functions that convert between lower and upper case
letters, such as <function>lower</>, <function>upper</>, and letters, such as <function>lower</function>, <function>upper</function>, and
<function>initcap</>; by pattern matching operators; and by <function>initcap</function>; by pattern matching operators; and by
<function>to_char</> and related functions. <function>to_char</function> and related functions.
</para> </para>
<para> <para>
@ -452,7 +452,7 @@ SELECT a &lt; ('foo' COLLATE "fr_FR") FROM test1;
SELECT a &lt; b FROM test1; SELECT a &lt; b FROM test1;
</programlisting> </programlisting>
the parser cannot determine which collation to apply, since the the parser cannot determine which collation to apply, since the
<structfield>a</> and <structfield>b</> columns have conflicting <structfield>a</structfield> and <structfield>b</structfield> columns have conflicting
implicit collations. Since the <literal>&lt;</literal> operator implicit collations. Since the <literal>&lt;</literal> operator
does need to know which collation to use, this will result in an does need to know which collation to use, this will result in an
error. The error can be resolved by attaching an explicit collation error. The error can be resolved by attaching an explicit collation
@ -468,7 +468,7 @@ SELECT a COLLATE "de_DE" &lt; b FROM test1;
<programlisting> <programlisting>
SELECT a || b FROM test1; SELECT a || b FROM test1;
</programlisting> </programlisting>
does not result in an error, because the <literal>||</> operator does not result in an error, because the <literal>||</literal> operator
does not care about collations: its result is the same regardless does not care about collations: its result is the same regardless
of the collation. of the collation.
</para> </para>
@ -486,8 +486,8 @@ SELECT * FROM test1 ORDER BY a || 'foo';
<programlisting> <programlisting>
SELECT * FROM test1 ORDER BY a || b; SELECT * FROM test1 ORDER BY a || b;
</programlisting> </programlisting>
results in an error, because even though the <literal>||</> operator results in an error, because even though the <literal>||</literal> operator
doesn't need to know a collation, the <literal>ORDER BY</> clause does. doesn't need to know a collation, the <literal>ORDER BY</literal> clause does.
As before, the conflict can be resolved with an explicit collation As before, the conflict can be resolved with an explicit collation
specifier: specifier:
<programlisting> <programlisting>
@ -508,7 +508,7 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
operating system C library. These are the locales that most tools operating system C library. These are the locales that most tools
provided by the operating system use. Another provider provided by the operating system use. Another provider
is <literal>icu</literal>, which uses the external is <literal>icu</literal>, which uses the external
ICU<indexterm><primary>ICU</></> library. ICU locales can only be ICU<indexterm><primary>ICU</primary></indexterm> library. ICU locales can only be
used if support for ICU was configured when PostgreSQL was built. used if support for ICU was configured when PostgreSQL was built.
</para> </para>
@ -541,14 +541,14 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
<title>Standard Collations</title> <title>Standard Collations</title>
<para> <para>
On all platforms, the collations named <literal>default</>, On all platforms, the collations named <literal>default</literal>,
<literal>C</>, and <literal>POSIX</> are available. Additional <literal>C</literal>, and <literal>POSIX</literal> are available. Additional
collations may be available depending on operating system support. collations may be available depending on operating system support.
The <literal>default</> collation selects the <symbol>LC_COLLATE</symbol> The <literal>default</literal> collation selects the <symbol>LC_COLLATE</symbol>
and <symbol>LC_CTYPE</symbol> values specified at database creation time. and <symbol>LC_CTYPE</symbol> values specified at database creation time.
The <literal>C</> and <literal>POSIX</> collations both specify The <literal>C</literal> and <literal>POSIX</literal> collations both specify
<quote>traditional C</> behavior, in which only the ASCII letters <quote>traditional C</quote> behavior, in which only the ASCII letters
<quote><literal>A</></quote> through <quote><literal>Z</></quote> <quote><literal>A</literal></quote> through <quote><literal>Z</literal></quote>
are treated as letters, and sorting is done strictly by character are treated as letters, and sorting is done strictly by character
code byte values. code byte values.
</para> </para>
@ -565,7 +565,7 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
<para> <para>
If the operating system provides support for using multiple locales If the operating system provides support for using multiple locales
within a single program (<function>newlocale</> and related functions), within a single program (<function>newlocale</function> and related functions),
or if support for ICU is configured, or if support for ICU is configured,
then when a database cluster is initialized, <command>initdb</command> then when a database cluster is initialized, <command>initdb</command>
populates the system catalog <literal>pg_collation</literal> with populates the system catalog <literal>pg_collation</literal> with
@ -618,8 +618,8 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
within a given database even though it would not be unique globally. within a given database even though it would not be unique globally.
Use of the stripped collation names is recommended, since it will Use of the stripped collation names is recommended, since it will
make one less thing you need to change if you decide to change to make one less thing you need to change if you decide to change to
another database encoding. Note however that the <literal>default</>, another database encoding. Note however that the <literal>default</literal>,
<literal>C</>, and <literal>POSIX</> collations can be used regardless of <literal>C</literal>, and <literal>POSIX</literal> collations can be used regardless of
the database encoding. the database encoding.
</para> </para>
@ -630,7 +630,7 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
<programlisting> <programlisting>
SELECT a COLLATE "C" &lt; b COLLATE "POSIX" FROM test1; SELECT a COLLATE "C" &lt; b COLLATE "POSIX" FROM test1;
</programlisting> </programlisting>
will draw an error even though the <literal>C</> and <literal>POSIX</> will draw an error even though the <literal>C</literal> and <literal>POSIX</literal>
collations have identical behaviors. Mixing stripped and non-stripped collations have identical behaviors. Mixing stripped and non-stripped
collation names is therefore not recommended. collation names is therefore not recommended.
</para> </para>
@ -691,7 +691,7 @@ SELECT a COLLATE "C" &lt; b COLLATE "POSIX" FROM test1;
database encoding is one of these, ICU collation entries database encoding is one of these, ICU collation entries
in <literal>pg_collation</literal> are ignored. Attempting to use one in <literal>pg_collation</literal> are ignored. Attempting to use one
will draw an error along the lines of <quote>collation "de-x-icu" for will draw an error along the lines of <quote>collation "de-x-icu" for
encoding "WIN874" does not exist</>. encoding "WIN874" does not exist</quote>.
</para> </para>
</sect4> </sect4>
</sect3> </sect3>
@ -889,30 +889,30 @@ CREATE COLLATION french FROM "fr-x-icu";
<sect1 id="multibyte"> <sect1 id="multibyte">
<title>Character Set Support</title> <title>Character Set Support</title>
<indexterm zone="multibyte"><primary>character set</></> <indexterm zone="multibyte"><primary>character set</primary></indexterm>
<para> <para>
The character set support in <productname>PostgreSQL</productname> The character set support in <productname>PostgreSQL</productname>
allows you to store text in a variety of character sets (also called allows you to store text in a variety of character sets (also called
encodings), including encodings), including
single-byte character sets such as the ISO 8859 series and single-byte character sets such as the ISO 8859 series and
multiple-byte character sets such as <acronym>EUC</> (Extended Unix multiple-byte character sets such as <acronym>EUC</acronym> (Extended Unix
Code), UTF-8, and Mule internal code. All supported character sets Code), UTF-8, and Mule internal code. All supported character sets
can be used transparently by clients, but a few are not supported can be used transparently by clients, but a few are not supported
for use within the server (that is, as a server-side encoding). for use within the server (that is, as a server-side encoding).
The default character set is selected while The default character set is selected while
initializing your <productname>PostgreSQL</productname> database initializing your <productname>PostgreSQL</productname> database
cluster using <command>initdb</>. It can be overridden when you cluster using <command>initdb</command>. It can be overridden when you
create a database, so you can have multiple create a database, so you can have multiple
databases each with a different character set. databases each with a different character set.
</para> </para>
<para> <para>
An important restriction, however, is that each database's character set An important restriction, however, is that each database's character set
must be compatible with the database's <envar>LC_CTYPE</> (character must be compatible with the database's <envar>LC_CTYPE</envar> (character
classification) and <envar>LC_COLLATE</> (string sort order) locale classification) and <envar>LC_COLLATE</envar> (string sort order) locale
settings. For <literal>C</> or settings. For <literal>C</literal> or
<literal>POSIX</> locale, any character set is allowed, but for other <literal>POSIX</literal> locale, any character set is allowed, but for other
libc-provided locales there is only one character set that will work libc-provided locales there is only one character set that will work
correctly. correctly.
(On Windows, however, UTF-8 encoding can be used with any locale.) (On Windows, however, UTF-8 encoding can be used with any locale.)
@ -954,7 +954,7 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>No</entry> <entry>No</entry>
<entry>No</entry> <entry>No</entry>
<entry>1-2</entry> <entry>1-2</entry>
<entry><literal>WIN950</>, <literal>Windows950</></entry> <entry><literal>WIN950</literal>, <literal>Windows950</literal></entry>
</row> </row>
<row> <row>
<entry><literal>EUC_CN</literal></entry> <entry><literal>EUC_CN</literal></entry>
@ -1017,11 +1017,11 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>No</entry> <entry>No</entry>
<entry>No</entry> <entry>No</entry>
<entry>1-2</entry> <entry>1-2</entry>
<entry><literal>WIN936</>, <literal>Windows936</></entry> <entry><literal>WIN936</literal>, <literal>Windows936</literal></entry>
</row> </row>
<row> <row>
<entry><literal>ISO_8859_5</literal></entry> <entry><literal>ISO_8859_5</literal></entry>
<entry>ISO 8859-5, <acronym>ECMA</> 113</entry> <entry>ISO 8859-5, <acronym>ECMA</acronym> 113</entry>
<entry>Latin/Cyrillic</entry> <entry>Latin/Cyrillic</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
@ -1030,7 +1030,7 @@ CREATE COLLATION french FROM "fr-x-icu";
</row> </row>
<row> <row>
<entry><literal>ISO_8859_6</literal></entry> <entry><literal>ISO_8859_6</literal></entry>
<entry>ISO 8859-6, <acronym>ECMA</> 114</entry> <entry>ISO 8859-6, <acronym>ECMA</acronym> 114</entry>
<entry>Latin/Arabic</entry> <entry>Latin/Arabic</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
@ -1039,7 +1039,7 @@ CREATE COLLATION french FROM "fr-x-icu";
</row> </row>
<row> <row>
<entry><literal>ISO_8859_7</literal></entry> <entry><literal>ISO_8859_7</literal></entry>
<entry>ISO 8859-7, <acronym>ECMA</> 118</entry> <entry>ISO 8859-7, <acronym>ECMA</acronym> 118</entry>
<entry>Latin/Greek</entry> <entry>Latin/Greek</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
@ -1048,7 +1048,7 @@ CREATE COLLATION french FROM "fr-x-icu";
</row> </row>
<row> <row>
<entry><literal>ISO_8859_8</literal></entry> <entry><literal>ISO_8859_8</literal></entry>
<entry>ISO 8859-8, <acronym>ECMA</> 121</entry> <entry>ISO 8859-8, <acronym>ECMA</acronym> 121</entry>
<entry>Latin/Hebrew</entry> <entry>Latin/Hebrew</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
@ -1057,7 +1057,7 @@ CREATE COLLATION french FROM "fr-x-icu";
</row> </row>
<row> <row>
<entry><literal>JOHAB</literal></entry> <entry><literal>JOHAB</literal></entry>
<entry><acronym>JOHAB</></entry> <entry><acronym>JOHAB</acronym></entry>
<entry>Korean (Hangul)</entry> <entry>Korean (Hangul)</entry>
<entry>No</entry> <entry>No</entry>
<entry>No</entry> <entry>No</entry>
@ -1071,7 +1071,7 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>1</entry> <entry>1</entry>
<entry><literal>KOI8</></entry> <entry><literal>KOI8</literal></entry>
</row> </row>
<row> <row>
<entry><literal>KOI8U</literal></entry> <entry><literal>KOI8U</literal></entry>
@ -1084,57 +1084,57 @@ CREATE COLLATION french FROM "fr-x-icu";
</row> </row>
<row> <row>
<entry><literal>LATIN1</literal></entry> <entry><literal>LATIN1</literal></entry>
<entry>ISO 8859-1, <acronym>ECMA</> 94</entry> <entry>ISO 8859-1, <acronym>ECMA</acronym> 94</entry>
<entry>Western European</entry> <entry>Western European</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>1</entry> <entry>1</entry>
<entry><literal>ISO88591</></entry> <entry><literal>ISO88591</literal></entry>
</row> </row>
<row> <row>
<entry><literal>LATIN2</literal></entry> <entry><literal>LATIN2</literal></entry>
<entry>ISO 8859-2, <acronym>ECMA</> 94</entry> <entry>ISO 8859-2, <acronym>ECMA</acronym> 94</entry>
<entry>Central European</entry> <entry>Central European</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>1</entry> <entry>1</entry>
<entry><literal>ISO88592</></entry> <entry><literal>ISO88592</literal></entry>
</row> </row>
<row> <row>
<entry><literal>LATIN3</literal></entry> <entry><literal>LATIN3</literal></entry>
<entry>ISO 8859-3, <acronym>ECMA</> 94</entry> <entry>ISO 8859-3, <acronym>ECMA</acronym> 94</entry>
<entry>South European</entry> <entry>South European</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>1</entry> <entry>1</entry>
<entry><literal>ISO88593</></entry> <entry><literal>ISO88593</literal></entry>
</row> </row>
<row> <row>
<entry><literal>LATIN4</literal></entry> <entry><literal>LATIN4</literal></entry>
<entry>ISO 8859-4, <acronym>ECMA</> 94</entry> <entry>ISO 8859-4, <acronym>ECMA</acronym> 94</entry>
<entry>North European</entry> <entry>North European</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>1</entry> <entry>1</entry>
<entry><literal>ISO88594</></entry> <entry><literal>ISO88594</literal></entry>
</row> </row>
<row> <row>
<entry><literal>LATIN5</literal></entry> <entry><literal>LATIN5</literal></entry>
<entry>ISO 8859-9, <acronym>ECMA</> 128</entry> <entry>ISO 8859-9, <acronym>ECMA</acronym> 128</entry>
<entry>Turkish</entry> <entry>Turkish</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>1</entry> <entry>1</entry>
<entry><literal>ISO88599</></entry> <entry><literal>ISO88599</literal></entry>
</row> </row>
<row> <row>
<entry><literal>LATIN6</literal></entry> <entry><literal>LATIN6</literal></entry>
<entry>ISO 8859-10, <acronym>ECMA</> 144</entry> <entry>ISO 8859-10, <acronym>ECMA</acronym> 144</entry>
<entry>Nordic</entry> <entry>Nordic</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>1</entry> <entry>1</entry>
<entry><literal>ISO885910</></entry> <entry><literal>ISO885910</literal></entry>
</row> </row>
<row> <row>
<entry><literal>LATIN7</literal></entry> <entry><literal>LATIN7</literal></entry>
@ -1143,7 +1143,7 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>1</entry> <entry>1</entry>
<entry><literal>ISO885913</></entry> <entry><literal>ISO885913</literal></entry>
</row> </row>
<row> <row>
<entry><literal>LATIN8</literal></entry> <entry><literal>LATIN8</literal></entry>
@ -1152,7 +1152,7 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>1</entry> <entry>1</entry>
<entry><literal>ISO885914</></entry> <entry><literal>ISO885914</literal></entry>
</row> </row>
<row> <row>
<entry><literal>LATIN9</literal></entry> <entry><literal>LATIN9</literal></entry>
@ -1161,16 +1161,16 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>1</entry> <entry>1</entry>
<entry><literal>ISO885915</></entry> <entry><literal>ISO885915</literal></entry>
</row> </row>
<row> <row>
<entry><literal>LATIN10</literal></entry> <entry><literal>LATIN10</literal></entry>
<entry>ISO 8859-16, <acronym>ASRO</> SR 14111</entry> <entry>ISO 8859-16, <acronym>ASRO</acronym> SR 14111</entry>
<entry>Romanian</entry> <entry>Romanian</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>No</entry> <entry>No</entry>
<entry>1</entry> <entry>1</entry>
<entry><literal>ISO885916</></entry> <entry><literal>ISO885916</literal></entry>
</row> </row>
<row> <row>
<entry><literal>MULE_INTERNAL</literal></entry> <entry><literal>MULE_INTERNAL</literal></entry>
@ -1188,7 +1188,7 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>No</entry> <entry>No</entry>
<entry>No</entry> <entry>No</entry>
<entry>1-2</entry> <entry>1-2</entry>
<entry><literal>Mskanji</>, <literal>ShiftJIS</>, <literal>WIN932</>, <literal>Windows932</></entry> <entry><literal>Mskanji</literal>, <literal>ShiftJIS</literal>, <literal>WIN932</literal>, <literal>Windows932</literal></entry>
</row> </row>
<row> <row>
<entry><literal>SHIFT_JIS_2004</literal></entry> <entry><literal>SHIFT_JIS_2004</literal></entry>
@ -1202,7 +1202,7 @@ CREATE COLLATION french FROM "fr-x-icu";
<row> <row>
<entry><literal>SQL_ASCII</literal></entry> <entry><literal>SQL_ASCII</literal></entry>
<entry>unspecified (see text)</entry> <entry>unspecified (see text)</entry>
<entry><emphasis>any</></entry> <entry><emphasis>any</emphasis></entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>No</entry> <entry>No</entry>
<entry>1</entry> <entry>1</entry>
@ -1215,16 +1215,16 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>No</entry> <entry>No</entry>
<entry>No</entry> <entry>No</entry>
<entry>1-2</entry> <entry>1-2</entry>
<entry><literal>WIN949</>, <literal>Windows949</></entry> <entry><literal>WIN949</literal>, <literal>Windows949</literal></entry>
</row> </row>
<row> <row>
<entry><literal>UTF8</literal></entry> <entry><literal>UTF8</literal></entry>
<entry>Unicode, 8-bit</entry> <entry>Unicode, 8-bit</entry>
<entry><emphasis>all</></entry> <entry><emphasis>all</emphasis></entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>1-4</entry> <entry>1-4</entry>
<entry><literal>Unicode</></entry> <entry><literal>Unicode</literal></entry>
</row> </row>
<row> <row>
<entry><literal>WIN866</literal></entry> <entry><literal>WIN866</literal></entry>
@ -1233,7 +1233,7 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>1</entry> <entry>1</entry>
<entry><literal>ALT</></entry> <entry><literal>ALT</literal></entry>
</row> </row>
<row> <row>
<entry><literal>WIN874</literal></entry> <entry><literal>WIN874</literal></entry>
@ -1260,7 +1260,7 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>1</entry> <entry>1</entry>
<entry><literal>WIN</></entry> <entry><literal>WIN</literal></entry>
</row> </row>
<row> <row>
<entry><literal>WIN1252</literal></entry> <entry><literal>WIN1252</literal></entry>
@ -1323,30 +1323,30 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
<entry>1</entry> <entry>1</entry>
<entry><literal>ABC</>, <literal>TCVN</>, <literal>TCVN5712</>, <literal>VSCII</></entry> <entry><literal>ABC</literal>, <literal>TCVN</literal>, <literal>TCVN5712</literal>, <literal>VSCII</literal></entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
</table> </table>
<para> <para>
Not all client <acronym>API</>s support all the listed character sets. For example, the Not all client <acronym>API</acronym>s support all the listed character sets. For example, the
<productname>PostgreSQL</> <productname>PostgreSQL</productname>
JDBC driver does not support <literal>MULE_INTERNAL</>, <literal>LATIN6</>, JDBC driver does not support <literal>MULE_INTERNAL</literal>, <literal>LATIN6</literal>,
<literal>LATIN8</>, and <literal>LATIN10</>. <literal>LATIN8</literal>, and <literal>LATIN10</literal>.
</para> </para>
<para> <para>
The <literal>SQL_ASCII</> setting behaves considerably differently The <literal>SQL_ASCII</literal> setting behaves considerably differently
from the other settings. When the server character set is from the other settings. When the server character set is
<literal>SQL_ASCII</>, the server interprets byte values 0-127 <literal>SQL_ASCII</literal>, the server interprets byte values 0-127
according to the ASCII standard, while byte values 128-255 are taken according to the ASCII standard, while byte values 128-255 are taken
as uninterpreted characters. No encoding conversion will be done when as uninterpreted characters. No encoding conversion will be done when
the setting is <literal>SQL_ASCII</>. Thus, this setting is not so the setting is <literal>SQL_ASCII</literal>. Thus, this setting is not so
much a declaration that a specific encoding is in use, as a declaration much a declaration that a specific encoding is in use, as a declaration
of ignorance about the encoding. In most cases, if you are of ignorance about the encoding. In most cases, if you are
working with any non-ASCII data, it is unwise to use the working with any non-ASCII data, it is unwise to use the
<literal>SQL_ASCII</> setting because <literal>SQL_ASCII</literal> setting because
<productname>PostgreSQL</productname> will be unable to help you by <productname>PostgreSQL</productname> will be unable to help you by
converting or validating non-ASCII characters. converting or validating non-ASCII characters.
</para> </para>
@ -1356,7 +1356,7 @@ CREATE COLLATION french FROM "fr-x-icu";
<title>Setting the Character Set</title> <title>Setting the Character Set</title>
<para> <para>
<command>initdb</> defines the default character set (encoding) <command>initdb</command> defines the default character set (encoding)
for a <productname>PostgreSQL</productname> cluster. For example, for a <productname>PostgreSQL</productname> cluster. For example,
<screen> <screen>
@ -1367,8 +1367,8 @@ initdb -E EUC_JP
<literal>EUC_JP</literal> (Extended Unix Code for Japanese). You <literal>EUC_JP</literal> (Extended Unix Code for Japanese). You
can use <option>--encoding</option> instead of can use <option>--encoding</option> instead of
<option>-E</option> if you prefer longer option strings. <option>-E</option> if you prefer longer option strings.
If no <option>-E</> or <option>--encoding</option> option is If no <option>-E</option> or <option>--encoding</option> option is
given, <command>initdb</> attempts to determine the appropriate given, <command>initdb</command> attempts to determine the appropriate
encoding to use based on the specified or default locale. encoding to use based on the specified or default locale.
</para> </para>
@ -1388,7 +1388,7 @@ createdb -E EUC_KR -T template0 --lc-collate=ko_KR.euckr --lc-ctype=ko_KR.euckr
CREATE DATABASE korean WITH ENCODING 'EUC_KR' LC_COLLATE='ko_KR.euckr' LC_CTYPE='ko_KR.euckr' TEMPLATE=template0; CREATE DATABASE korean WITH ENCODING 'EUC_KR' LC_COLLATE='ko_KR.euckr' LC_CTYPE='ko_KR.euckr' TEMPLATE=template0;
</programlisting> </programlisting>
Notice that the above commands specify copying the <literal>template0</> Notice that the above commands specify copying the <literal>template0</literal>
database. When copying any other database, the encoding and locale database. When copying any other database, the encoding and locale
settings cannot be changed from those of the source database, because settings cannot be changed from those of the source database, because
that might result in corrupt data. For more information see that might result in corrupt data. For more information see
@ -1420,7 +1420,7 @@ $ <userinput>psql -l</userinput>
<important> <important>
<para> <para>
On most modern operating systems, <productname>PostgreSQL</productname> On most modern operating systems, <productname>PostgreSQL</productname>
can determine which character set is implied by the <envar>LC_CTYPE</> can determine which character set is implied by the <envar>LC_CTYPE</envar>
setting, and it will enforce that only the matching database encoding is setting, and it will enforce that only the matching database encoding is
used. On older systems it is your responsibility to ensure that you use used. On older systems it is your responsibility to ensure that you use
the encoding expected by the locale you have selected. A mistake in the encoding expected by the locale you have selected. A mistake in
@ -1430,9 +1430,9 @@ $ <userinput>psql -l</userinput>
<para> <para>
<productname>PostgreSQL</productname> will allow superusers to create <productname>PostgreSQL</productname> will allow superusers to create
databases with <literal>SQL_ASCII</> encoding even when databases with <literal>SQL_ASCII</literal> encoding even when
<envar>LC_CTYPE</> is not <literal>C</> or <literal>POSIX</>. As noted <envar>LC_CTYPE</envar> is not <literal>C</literal> or <literal>POSIX</literal>. As noted
above, <literal>SQL_ASCII</> does not enforce that the data stored in above, <literal>SQL_ASCII</literal> does not enforce that the data stored in
the database has any particular encoding, and so this choice poses risks the database has any particular encoding, and so this choice poses risks
of locale-dependent misbehavior. Using this combination of settings is of locale-dependent misbehavior. Using this combination of settings is
deprecated and may someday be forbidden altogether. deprecated and may someday be forbidden altogether.
@ -1447,7 +1447,7 @@ $ <userinput>psql -l</userinput>
<productname>PostgreSQL</productname> supports automatic <productname>PostgreSQL</productname> supports automatic
character set conversion between server and client for certain character set conversion between server and client for certain
character set combinations. The conversion information is stored in the character set combinations. The conversion information is stored in the
<literal>pg_conversion</> system catalog. <productname>PostgreSQL</> <literal>pg_conversion</literal> system catalog. <productname>PostgreSQL</productname>
comes with some predefined conversions, as shown in <xref comes with some predefined conversions, as shown in <xref
linkend="multibyte-translation-table">. You can create a new linkend="multibyte-translation-table">. You can create a new
conversion using the SQL command <command>CREATE CONVERSION</command>. conversion using the SQL command <command>CREATE CONVERSION</command>.
@ -1763,7 +1763,7 @@ $ <userinput>psql -l</userinput>
<listitem> <listitem>
<para> <para>
<application>libpq</> (<xref linkend="libpq-control">) has functions to control the client encoding. <application>libpq</application> (<xref linkend="libpq-control">) has functions to control the client encoding.
</para> </para>
</listitem> </listitem>
@ -1774,14 +1774,14 @@ $ <userinput>psql -l</userinput>
Setting the client encoding can be done with this SQL command: Setting the client encoding can be done with this SQL command:
<programlisting> <programlisting>
SET CLIENT_ENCODING TO '<replaceable>value</>'; SET CLIENT_ENCODING TO '<replaceable>value</replaceable>';
</programlisting> </programlisting>
Also you can use the standard SQL syntax <literal>SET NAMES</literal> Also you can use the standard SQL syntax <literal>SET NAMES</literal>
for this purpose: for this purpose:
<programlisting> <programlisting>
SET NAMES '<replaceable>value</>'; SET NAMES '<replaceable>value</replaceable>';
</programlisting> </programlisting>
To query the current client encoding: To query the current client encoding:
@ -1813,7 +1813,7 @@ RESET client_encoding;
<para> <para>
Using the configuration variable <xref Using the configuration variable <xref
linkend="guc-client-encoding">. If the linkend="guc-client-encoding">. If the
<varname>client_encoding</> variable is set, that client <varname>client_encoding</varname> variable is set, that client
encoding is automatically selected when a connection to the encoding is automatically selected when a connection to the
server is made. (This can subsequently be overridden using any server is made. (This can subsequently be overridden using any
of the other methods mentioned above.) of the other methods mentioned above.)
@ -1832,9 +1832,9 @@ RESET client_encoding;
</para> </para>
<para> <para>
If the client character set is defined as <literal>SQL_ASCII</>, If the client character set is defined as <literal>SQL_ASCII</literal>,
encoding conversion is disabled, regardless of the server's character encoding conversion is disabled, regardless of the server's character
set. Just as for the server, use of <literal>SQL_ASCII</> is unwise set. Just as for the server, use of <literal>SQL_ASCII</literal> is unwise
unless you are working with all-ASCII data. unless you are working with all-ASCII data.
</para> </para>
</sect2> </sect2>

View File

@ -8,10 +8,10 @@
</indexterm> </indexterm>
<para> <para>
The <filename>citext</> module provides a case-insensitive The <filename>citext</filename> module provides a case-insensitive
character string type, <type>citext</>. Essentially, it internally calls character string type, <type>citext</type>. Essentially, it internally calls
<function>lower</> when comparing values. Otherwise, it behaves almost <function>lower</function> when comparing values. Otherwise, it behaves almost
exactly like <type>text</>. exactly like <type>text</type>.
</para> </para>
<sect2> <sect2>
@ -19,7 +19,7 @@
<para> <para>
The standard approach to doing case-insensitive matches The standard approach to doing case-insensitive matches
in <productname>PostgreSQL</> has been to use the <function>lower</> in <productname>PostgreSQL</productname> has been to use the <function>lower</function>
function when comparing values, for example function when comparing values, for example
<programlisting> <programlisting>
@ -35,19 +35,19 @@ SELECT * FROM tab WHERE lower(col) = LOWER(?);
<listitem> <listitem>
<para> <para>
It makes your SQL statements verbose, and you always have to remember to It makes your SQL statements verbose, and you always have to remember to
use <function>lower</> on both the column and the query value. use <function>lower</function> on both the column and the query value.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
It won't use an index, unless you create a functional index using It won't use an index, unless you create a functional index using
<function>lower</>. <function>lower</function>.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
If you declare a column as <literal>UNIQUE</> or <literal>PRIMARY If you declare a column as <literal>UNIQUE</literal> or <literal>PRIMARY
KEY</>, the implicitly generated index is case-sensitive. So it's KEY</literal>, the implicitly generated index is case-sensitive. So it's
useless for case-insensitive searches, and it won't enforce useless for case-insensitive searches, and it won't enforce
uniqueness case-insensitively. uniqueness case-insensitively.
</para> </para>
@ -55,13 +55,13 @@ SELECT * FROM tab WHERE lower(col) = LOWER(?);
</itemizedlist> </itemizedlist>
<para> <para>
The <type>citext</> data type allows you to eliminate calls The <type>citext</type> data type allows you to eliminate calls
to <function>lower</> in SQL queries, and allows a primary key to to <function>lower</function> in SQL queries, and allows a primary key to
be case-insensitive. <type>citext</> is locale-aware, just be case-insensitive. <type>citext</type> is locale-aware, just
like <type>text</>, which means that the matching of upper case and like <type>text</type>, which means that the matching of upper case and
lower case characters is dependent on the rules of lower case characters is dependent on the rules of
the database's <literal>LC_CTYPE</> setting. Again, this behavior is the database's <literal>LC_CTYPE</literal> setting. Again, this behavior is
identical to the use of <function>lower</> in queries. But because it's identical to the use of <function>lower</function> in queries. But because it's
done transparently by the data type, you don't have to remember to do done transparently by the data type, you don't have to remember to do
anything special in your queries. anything special in your queries.
</para> </para>
@ -89,9 +89,9 @@ INSERT INTO users VALUES ( 'Bj&oslash;rn', md5(random()::text) );
SELECT * FROM users WHERE nick = 'Larry'; SELECT * FROM users WHERE nick = 'Larry';
</programlisting> </programlisting>
The <command>SELECT</> statement will return one tuple, even though The <command>SELECT</command> statement will return one tuple, even though
the <structfield>nick</> column was set to <literal>larry</> and the query the <structfield>nick</structfield> column was set to <literal>larry</literal> and the query
was for <literal>Larry</>. was for <literal>Larry</literal>.
</para> </para>
</sect2> </sect2>
@ -99,82 +99,82 @@ SELECT * FROM users WHERE nick = 'Larry';
<title>String Comparison Behavior</title> <title>String Comparison Behavior</title>
<para> <para>
<type>citext</> performs comparisons by converting each string to lower <type>citext</type> performs comparisons by converting each string to lower
case (as though <function>lower</> were called) and then comparing the case (as though <function>lower</function> were called) and then comparing the
results normally. Thus, for example, two strings are considered equal results normally. Thus, for example, two strings are considered equal
if <function>lower</> would produce identical results for them. if <function>lower</function> would produce identical results for them.
</para> </para>
<para> <para>
In order to emulate a case-insensitive collation as closely as possible, In order to emulate a case-insensitive collation as closely as possible,
there are <type>citext</>-specific versions of a number of string-processing there are <type>citext</type>-specific versions of a number of string-processing
operators and functions. So, for example, the regular expression operators and functions. So, for example, the regular expression
operators <literal>~</> and <literal>~*</> exhibit the same behavior when operators <literal>~</literal> and <literal>~*</literal> exhibit the same behavior when
applied to <type>citext</>: they both match case-insensitively. applied to <type>citext</type>: they both match case-insensitively.
The same is true The same is true
for <literal>!~</> and <literal>!~*</>, as well as for the for <literal>!~</literal> and <literal>!~*</literal>, as well as for the
<literal>LIKE</> operators <literal>~~</> and <literal>~~*</>, and <literal>LIKE</literal> operators <literal>~~</literal> and <literal>~~*</literal>, and
<literal>!~~</> and <literal>!~~*</>. If you'd like to match <literal>!~~</literal> and <literal>!~~*</literal>. If you'd like to match
case-sensitively, you can cast the operator's arguments to <type>text</>. case-sensitively, you can cast the operator's arguments to <type>text</type>.
</para> </para>
<para> <para>
Similarly, all of the following functions perform matching Similarly, all of the following functions perform matching
case-insensitively if their arguments are <type>citext</>: case-insensitively if their arguments are <type>citext</type>:
</para> </para>
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
<function>regexp_match()</> <function>regexp_match()</function>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<function>regexp_matches()</> <function>regexp_matches()</function>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<function>regexp_replace()</> <function>regexp_replace()</function>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<function>regexp_split_to_array()</> <function>regexp_split_to_array()</function>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<function>regexp_split_to_table()</> <function>regexp_split_to_table()</function>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<function>replace()</> <function>replace()</function>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<function>split_part()</> <function>split_part()</function>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<function>strpos()</> <function>strpos()</function>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<function>translate()</> <function>translate()</function>
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
<para> <para>
For the regexp functions, if you want to match case-sensitively, you can For the regexp functions, if you want to match case-sensitively, you can
specify the <quote>c</> flag to force a case-sensitive match. Otherwise, specify the <quote>c</quote> flag to force a case-sensitive match. Otherwise,
you must cast to <type>text</> before using one of these functions if you must cast to <type>text</type> before using one of these functions if
you want case-sensitive behavior. you want case-sensitive behavior.
</para> </para>
@ -186,13 +186,13 @@ SELECT * FROM users WHERE nick = 'Larry';
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
<type>citext</>'s case-folding behavior depends on <type>citext</type>'s case-folding behavior depends on
the <literal>LC_CTYPE</> setting of your database. How it compares the <literal>LC_CTYPE</literal> setting of your database. How it compares
values is therefore determined when the database is created. values is therefore determined when the database is created.
It is not truly It is not truly
case-insensitive in the terms defined by the Unicode standard. case-insensitive in the terms defined by the Unicode standard.
Effectively, what this means is that, as long as you're happy with your Effectively, what this means is that, as long as you're happy with your
collation, you should be happy with <type>citext</>'s comparisons. But collation, you should be happy with <type>citext</type>'s comparisons. But
if you have data in different languages stored in your database, users if you have data in different languages stored in your database, users
of one language may find their query results are not as expected if the of one language may find their query results are not as expected if the
collation is for another language. collation is for another language.
@ -201,38 +201,38 @@ SELECT * FROM users WHERE nick = 'Larry';
<listitem> <listitem>
<para> <para>
As of <productname>PostgreSQL</> 9.1, you can attach a As of <productname>PostgreSQL</productname> 9.1, you can attach a
<literal>COLLATE</> specification to <type>citext</> columns or data <literal>COLLATE</literal> specification to <type>citext</type> columns or data
values. Currently, <type>citext</> operators will honor a non-default values. Currently, <type>citext</type> operators will honor a non-default
<literal>COLLATE</> specification while comparing case-folded strings, <literal>COLLATE</literal> specification while comparing case-folded strings,
but the initial folding to lower case is always done according to the but the initial folding to lower case is always done according to the
database's <literal>LC_CTYPE</> setting (that is, as though database's <literal>LC_CTYPE</literal> setting (that is, as though
<literal>COLLATE "default"</> were given). This may be changed in a <literal>COLLATE "default"</literal> were given). This may be changed in a
future release so that both steps follow the input <literal>COLLATE</> future release so that both steps follow the input <literal>COLLATE</literal>
specification. specification.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<type>citext</> is not as efficient as <type>text</> because the <type>citext</type> is not as efficient as <type>text</type> because the
operator functions and the B-tree comparison functions must make copies operator functions and the B-tree comparison functions must make copies
of the data and convert it to lower case for comparisons. It is, of the data and convert it to lower case for comparisons. It is,
however, slightly more efficient than using <function>lower</> to get however, slightly more efficient than using <function>lower</function> to get
case-insensitive matching. case-insensitive matching.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<type>citext</> doesn't help much if you need data to compare <type>citext</type> doesn't help much if you need data to compare
case-sensitively in some contexts and case-insensitively in other case-sensitively in some contexts and case-insensitively in other
contexts. The standard answer is to use the <type>text</> type and contexts. The standard answer is to use the <type>text</type> type and
manually use the <function>lower</> function when you need to compare manually use the <function>lower</function> function when you need to compare
case-insensitively; this works all right if case-insensitive comparison case-insensitively; this works all right if case-insensitive comparison
is needed only infrequently. If you need case-insensitive behavior most is needed only infrequently. If you need case-insensitive behavior most
of the time and case-sensitive infrequently, consider storing the data of the time and case-sensitive infrequently, consider storing the data
as <type>citext</> and explicitly casting the column to <type>text</> as <type>citext</type> and explicitly casting the column to <type>text</type>
when you want case-sensitive comparison. In either situation, you will when you want case-sensitive comparison. In either situation, you will
need two indexes if you want both types of searches to be fast. need two indexes if you want both types of searches to be fast.
</para> </para>
@ -240,9 +240,9 @@ SELECT * FROM users WHERE nick = 'Larry';
<listitem> <listitem>
<para> <para>
The schema containing the <type>citext</> operators must be The schema containing the <type>citext</type> operators must be
in the current <varname>search_path</> (typically <literal>public</>); in the current <varname>search_path</varname> (typically <literal>public</literal>);
if it is not, the normal case-sensitive <type>text</> operators if it is not, the normal case-sensitive <type>text</type> operators
will be invoked instead. will be invoked instead.
</para> </para>
</listitem> </listitem>
@ -257,7 +257,7 @@ SELECT * FROM users WHERE nick = 'Larry';
</para> </para>
<para> <para>
Inspired by the original <type>citext</> module by Donald Fraser. Inspired by the original <type>citext</type> module by Donald Fraser.
</para> </para>
</sect2> </sect2>

View File

@ -21,9 +21,9 @@
<para> <para>
As explained in <xref linkend="user-manag">, As explained in <xref linkend="user-manag">,
<productname>PostgreSQL</productname> actually does privilege <productname>PostgreSQL</productname> actually does privilege
management in terms of <quote>roles</>. In this chapter, we management in terms of <quote>roles</quote>. In this chapter, we
consistently use <firstterm>database user</> to mean <quote>role with the consistently use <firstterm>database user</firstterm> to mean <quote>role with the
<literal>LOGIN</> privilege</quote>. <literal>LOGIN</literal> privilege</quote>.
</para> </para>
</note> </note>
@ -66,7 +66,7 @@
which traditionally is named which traditionally is named
<filename>pg_hba.conf</filename> and is stored in the database <filename>pg_hba.conf</filename> and is stored in the database
cluster's data directory. cluster's data directory.
(<acronym>HBA</> stands for host-based authentication.) A default (<acronym>HBA</acronym> stands for host-based authentication.) A default
<filename>pg_hba.conf</filename> file is installed when the data <filename>pg_hba.conf</filename> file is installed when the data
directory is initialized by <command>initdb</command>. It is directory is initialized by <command>initdb</command>. It is
possible to place the authentication configuration file elsewhere, possible to place the authentication configuration file elsewhere,
@ -82,7 +82,7 @@
up of a number of fields which are separated by spaces and/or tabs. up of a number of fields which are separated by spaces and/or tabs.
Fields can contain white space if the field value is double-quoted. Fields can contain white space if the field value is double-quoted.
Quoting one of the keywords in a database, user, or address field (e.g., Quoting one of the keywords in a database, user, or address field (e.g.,
<literal>all</> or <literal>replication</>) makes the word lose its special <literal>all</literal> or <literal>replication</literal>) makes the word lose its special
meaning, and just match a database, user, or host with that name. meaning, and just match a database, user, or host with that name.
</para> </para>
@ -92,8 +92,8 @@
and the authentication method to be used for connections matching and the authentication method to be used for connections matching
these parameters. The first record with a matching connection type, these parameters. The first record with a matching connection type,
client address, requested database, and user name is used to perform client address, requested database, and user name is used to perform
authentication. There is no <quote>fall-through</> or authentication. There is no <quote>fall-through</quote> or
<quote>backup</>: if one record is chosen and the authentication <quote>backup</quote>: if one record is chosen and the authentication
fails, subsequent records are not considered. If no record matches, fails, subsequent records are not considered. If no record matches,
access is denied. access is denied.
</para> </para>
@ -138,7 +138,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
the server is started with an appropriate value for the the server is started with an appropriate value for the
<xref linkend="guc-listen-addresses"> configuration parameter, <xref linkend="guc-listen-addresses"> configuration parameter,
since the default behavior is to listen for TCP/IP connections since the default behavior is to listen for TCP/IP connections
only on the local loopback address <literal>localhost</>. only on the local loopback address <literal>localhost</literal>.
</para> </para>
</note> </note>
</listitem> </listitem>
@ -169,7 +169,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<term><literal>hostnossl</literal></term> <term><literal>hostnossl</literal></term>
<listitem> <listitem>
<para> <para>
This record type has the opposite behavior of <literal>hostssl</>; This record type has the opposite behavior of <literal>hostssl</literal>;
it only matches connection attempts made over it only matches connection attempts made over
TCP/IP that do not use <acronym>SSL</acronym>. TCP/IP that do not use <acronym>SSL</acronym>.
</para> </para>
@ -182,24 +182,24 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<para> <para>
Specifies which database name(s) this record matches. The value Specifies which database name(s) this record matches. The value
<literal>all</literal> specifies that it matches all databases. <literal>all</literal> specifies that it matches all databases.
The value <literal>sameuser</> specifies that the record The value <literal>sameuser</literal> specifies that the record
matches if the requested database has the same name as the matches if the requested database has the same name as the
requested user. The value <literal>samerole</> specifies that requested user. The value <literal>samerole</literal> specifies that
the requested user must be a member of the role with the same the requested user must be a member of the role with the same
name as the requested database. (<literal>samegroup</> is an name as the requested database. (<literal>samegroup</literal> is an
obsolete but still accepted spelling of <literal>samerole</>.) obsolete but still accepted spelling of <literal>samerole</literal>.)
Superusers are not considered to be members of a role for the Superusers are not considered to be members of a role for the
purposes of <literal>samerole</> unless they are explicitly purposes of <literal>samerole</literal> unless they are explicitly
members of the role, directly or indirectly, and not just by members of the role, directly or indirectly, and not just by
virtue of being a superuser. virtue of being a superuser.
The value <literal>replication</> specifies that the record The value <literal>replication</literal> specifies that the record
matches if a physical replication connection is requested (note that matches if a physical replication connection is requested (note that
replication connections do not specify any particular database). replication connections do not specify any particular database).
Otherwise, this is the name of Otherwise, this is the name of
a specific <productname>PostgreSQL</productname> database. a specific <productname>PostgreSQL</productname> database.
Multiple database names can be supplied by separating them with Multiple database names can be supplied by separating them with
commas. A separate file containing database names can be specified by commas. A separate file containing database names can be specified by
preceding the file name with <literal>@</>. preceding the file name with <literal>@</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -211,18 +211,18 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
Specifies which database user name(s) this record Specifies which database user name(s) this record
matches. The value <literal>all</literal> specifies that it matches. The value <literal>all</literal> specifies that it
matches all users. Otherwise, this is either the name of a specific matches all users. Otherwise, this is either the name of a specific
database user, or a group name preceded by <literal>+</>. database user, or a group name preceded by <literal>+</literal>.
(Recall that there is no real distinction between users and groups (Recall that there is no real distinction between users and groups
in <productname>PostgreSQL</>; a <literal>+</> mark really means in <productname>PostgreSQL</productname>; a <literal>+</literal> mark really means
<quote>match any of the roles that are directly or indirectly members <quote>match any of the roles that are directly or indirectly members
of this role</>, while a name without a <literal>+</> mark matches of this role</quote>, while a name without a <literal>+</literal> mark matches
only that specific role.) For this purpose, a superuser is only only that specific role.) For this purpose, a superuser is only
considered to be a member of a role if they are explicitly a member considered to be a member of a role if they are explicitly a member
of the role, directly or indirectly, and not just by virtue of of the role, directly or indirectly, and not just by virtue of
being a superuser. being a superuser.
Multiple user names can be supplied by separating them with commas. Multiple user names can be supplied by separating them with commas.
A separate file containing user names can be specified by preceding the A separate file containing user names can be specified by preceding the
file name with <literal>@</>. file name with <literal>@</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -239,7 +239,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<para> <para>
An IP address range is specified using standard numeric notation An IP address range is specified using standard numeric notation
for the range's starting address, then a slash (<literal>/</literal>) for the range's starting address, then a slash (<literal>/</literal>)
and a <acronym>CIDR</> mask length. The mask and a <acronym>CIDR</acronym> mask length. The mask
length indicates the number of high-order bits of the client length indicates the number of high-order bits of the client
IP address that must match. Bits to the right of this should IP address that must match. Bits to the right of this should
be zero in the given IP address. be zero in the given IP address.
@ -317,7 +317,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<para> <para>
This field only applies to <literal>host</literal>, This field only applies to <literal>host</literal>,
<literal>hostssl</literal>, and <literal>hostnossl</> records. <literal>hostssl</literal>, and <literal>hostnossl</literal> records.
</para> </para>
<note> <note>
@ -360,17 +360,17 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<listitem> <listitem>
<para> <para>
These two fields can be used as an alternative to the These two fields can be used as an alternative to the
<replaceable>IP-address</><literal>/</><replaceable>mask-length</> <replaceable>IP-address</replaceable><literal>/</literal><replaceable>mask-length</replaceable>
notation. Instead of notation. Instead of
specifying the mask length, the actual mask is specified in a specifying the mask length, the actual mask is specified in a
separate column. For example, <literal>255.0.0.0</> represents an IPv4 separate column. For example, <literal>255.0.0.0</literal> represents an IPv4
CIDR mask length of 8, and <literal>255.255.255.255</> represents a CIDR mask length of 8, and <literal>255.255.255.255</literal> represents a
CIDR mask length of 32. CIDR mask length of 32.
</para> </para>
<para> <para>
These fields only apply to <literal>host</literal>, These fields only apply to <literal>host</literal>,
<literal>hostssl</literal>, and <literal>hostnossl</> records. <literal>hostssl</literal>, and <literal>hostnossl</literal> records.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -385,7 +385,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><literal>trust</></term> <term><literal>trust</literal></term>
<listitem> <listitem>
<para> <para>
Allow the connection unconditionally. This method Allow the connection unconditionally. This method
@ -399,12 +399,12 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>reject</></term> <term><literal>reject</literal></term>
<listitem> <listitem>
<para> <para>
Reject the connection unconditionally. This is useful for Reject the connection unconditionally. This is useful for
<quote>filtering out</> certain hosts from a group, for example a <quote>filtering out</quote> certain hosts from a group, for example a
<literal>reject</> line could block a specific host from connecting, <literal>reject</literal> line could block a specific host from connecting,
while a later line allows the remaining hosts in a specific while a later line allows the remaining hosts in a specific
network to connect. network to connect.
</para> </para>
@ -412,7 +412,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>scram-sha-256</></term> <term><literal>scram-sha-256</literal></term>
<listitem> <listitem>
<para> <para>
Perform SCRAM-SHA-256 authentication to verify the user's Perform SCRAM-SHA-256 authentication to verify the user's
@ -422,7 +422,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>md5</></term> <term><literal>md5</literal></term>
<listitem> <listitem>
<para> <para>
Perform SCRAM-SHA-256 or MD5 authentication to verify the Perform SCRAM-SHA-256 or MD5 authentication to verify the
@ -433,7 +433,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>password</></term> <term><literal>password</literal></term>
<listitem> <listitem>
<para> <para>
Require the client to supply an unencrypted password for Require the client to supply an unencrypted password for
@ -446,7 +446,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>gss</></term> <term><literal>gss</literal></term>
<listitem> <listitem>
<para> <para>
Use GSSAPI to authenticate the user. This is only Use GSSAPI to authenticate the user. This is only
@ -457,7 +457,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>sspi</></term> <term><literal>sspi</literal></term>
<listitem> <listitem>
<para> <para>
Use SSPI to authenticate the user. This is only Use SSPI to authenticate the user. This is only
@ -468,7 +468,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>ident</></term> <term><literal>ident</literal></term>
<listitem> <listitem>
<para> <para>
Obtain the operating system user name of the client Obtain the operating system user name of the client
@ -483,7 +483,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>peer</></term> <term><literal>peer</literal></term>
<listitem> <listitem>
<para> <para>
Obtain the client's operating system user name from the operating Obtain the client's operating system user name from the operating
@ -495,17 +495,17 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>ldap</></term> <term><literal>ldap</literal></term>
<listitem> <listitem>
<para> <para>
Authenticate using an <acronym>LDAP</> server. See <xref Authenticate using an <acronym>LDAP</acronym> server. See <xref
linkend="auth-ldap"> for details. linkend="auth-ldap"> for details.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>radius</></term> <term><literal>radius</literal></term>
<listitem> <listitem>
<para> <para>
Authenticate using a RADIUS server. See <xref Authenticate using a RADIUS server. See <xref
@ -515,7 +515,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>cert</></term> <term><literal>cert</literal></term>
<listitem> <listitem>
<para> <para>
Authenticate using SSL client certificates. See Authenticate using SSL client certificates. See
@ -525,7 +525,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>pam</></term> <term><literal>pam</literal></term>
<listitem> <listitem>
<para> <para>
Authenticate using the Pluggable Authentication Modules Authenticate using the Pluggable Authentication Modules
@ -536,7 +536,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>bsd</></term> <term><literal>bsd</literal></term>
<listitem> <listitem>
<para> <para>
Authenticate using the BSD Authentication service provided by the Authenticate using the BSD Authentication service provided by the
@ -554,17 +554,17 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<term><replaceable>auth-options</replaceable></term> <term><replaceable>auth-options</replaceable></term>
<listitem> <listitem>
<para> <para>
After the <replaceable>auth-method</> field, there can be field(s) of After the <replaceable>auth-method</replaceable> field, there can be field(s) of
the form <replaceable>name</><literal>=</><replaceable>value</> that the form <replaceable>name</replaceable><literal>=</literal><replaceable>value</replaceable> that
specify options for the authentication method. Details about which specify options for the authentication method. Details about which
options are available for which authentication methods appear below. options are available for which authentication methods appear below.
</para> </para>
<para> <para>
In addition to the method-specific options listed below, there is one In addition to the method-specific options listed below, there is one
method-independent authentication option <literal>clientcert</>, which method-independent authentication option <literal>clientcert</literal>, which
can be specified in any <literal>hostssl</> record. When set can be specified in any <literal>hostssl</literal> record. When set
to <literal>1</>, this option requires the client to present a valid to <literal>1</literal>, this option requires the client to present a valid
(trusted) SSL certificate, in addition to the other requirements of the (trusted) SSL certificate, in addition to the other requirements of the
authentication method. authentication method.
</para> </para>
@ -574,11 +574,11 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</para> </para>
<para> <para>
Files included by <literal>@</> constructs are read as lists of names, Files included by <literal>@</literal> constructs are read as lists of names,
which can be separated by either whitespace or commas. Comments are which can be separated by either whitespace or commas. Comments are
introduced by <literal>#</literal>, just as in introduced by <literal>#</literal>, just as in
<filename>pg_hba.conf</filename>, and nested <literal>@</> constructs are <filename>pg_hba.conf</filename>, and nested <literal>@</literal> constructs are
allowed. Unless the file name following <literal>@</> is an absolute allowed. Unless the file name following <literal>@</literal> is an absolute
path, it is taken to be relative to the directory containing the path, it is taken to be relative to the directory containing the
referencing file. referencing file.
</para> </para>
@ -589,10 +589,10 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
significant. Typically, earlier records will have tight connection significant. Typically, earlier records will have tight connection
match parameters and weaker authentication methods, while later match parameters and weaker authentication methods, while later
records will have looser match parameters and stronger authentication records will have looser match parameters and stronger authentication
methods. For example, one might wish to use <literal>trust</> methods. For example, one might wish to use <literal>trust</literal>
authentication for local TCP/IP connections but require a password for authentication for local TCP/IP connections but require a password for
remote TCP/IP connections. In this case a record specifying remote TCP/IP connections. In this case a record specifying
<literal>trust</> authentication for connections from 127.0.0.1 would <literal>trust</literal> authentication for connections from 127.0.0.1 would
appear before a record specifying password authentication for a wider appear before a record specifying password authentication for a wider
range of allowed client IP addresses. range of allowed client IP addresses.
</para> </para>
@ -603,7 +603,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<systemitem>SIGHUP</systemitem><indexterm><primary>SIGHUP</primary></indexterm> <systemitem>SIGHUP</systemitem><indexterm><primary>SIGHUP</primary></indexterm>
signal. If you edit the file on an signal. If you edit the file on an
active system, you will need to signal the postmaster active system, you will need to signal the postmaster
(using <literal>pg_ctl reload</> or <literal>kill -HUP</>) to make it (using <literal>pg_ctl reload</literal> or <literal>kill -HUP</literal>) to make it
re-read the file. re-read the file.
</para> </para>
@ -618,7 +618,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<para> <para>
The system view The system view
<link linkend="view-pg-hba-file-rules"><structname>pg_hba_file_rules</structname></link> <link linkend="view-pg-hba-file-rules"><structname>pg_hba_file_rules</structname></link>
can be helpful for pre-testing changes to the <filename>pg_hba.conf</> can be helpful for pre-testing changes to the <filename>pg_hba.conf</filename>
file, or for diagnosing problems if loading of the file did not have the file, or for diagnosing problems if loading of the file did not have the
desired effects. Rows in the view with desired effects. Rows in the view with
non-null <structfield>error</structfield> fields indicate problems in the non-null <structfield>error</structfield> fields indicate problems in the
@ -629,9 +629,9 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<para> <para>
To connect to a particular database, a user must not only pass the To connect to a particular database, a user must not only pass the
<filename>pg_hba.conf</filename> checks, but must have the <filename>pg_hba.conf</filename> checks, but must have the
<literal>CONNECT</> privilege for the database. If you wish to <literal>CONNECT</literal> privilege for the database. If you wish to
restrict which users can connect to which databases, it's usually restrict which users can connect to which databases, it's usually
easier to control this by granting/revoking <literal>CONNECT</> privilege easier to control this by granting/revoking <literal>CONNECT</literal> privilege
than to put the rules in <filename>pg_hba.conf</filename> entries. than to put the rules in <filename>pg_hba.conf</filename> entries.
</para> </para>
</tip> </tip>
@ -760,21 +760,21 @@ local db1,db2,@demodbs all md5
<para> <para>
User name maps are defined in the ident map file, which by default is named User name maps are defined in the ident map file, which by default is named
<filename>pg_ident.conf</><indexterm><primary>pg_ident.conf</primary></indexterm> <filename>pg_ident.conf</filename><indexterm><primary>pg_ident.conf</primary></indexterm>
and is stored in the and is stored in the
cluster's data directory. (It is possible to place the map file cluster's data directory. (It is possible to place the map file
elsewhere, however; see the <xref linkend="guc-ident-file"> elsewhere, however; see the <xref linkend="guc-ident-file">
configuration parameter.) configuration parameter.)
The ident map file contains lines of the general form: The ident map file contains lines of the general form:
<synopsis> <synopsis>
<replaceable>map-name</> <replaceable>system-username</> <replaceable>database-username</> <replaceable>map-name</replaceable> <replaceable>system-username</replaceable> <replaceable>database-username</replaceable>
</synopsis> </synopsis>
Comments and whitespace are handled in the same way as in Comments and whitespace are handled in the same way as in
<filename>pg_hba.conf</>. The <filename>pg_hba.conf</filename>. The
<replaceable>map-name</> is an arbitrary name that will be used to <replaceable>map-name</replaceable> is an arbitrary name that will be used to
refer to this mapping in <filename>pg_hba.conf</filename>. The other refer to this mapping in <filename>pg_hba.conf</filename>. The other
two fields specify an operating system user name and a matching two fields specify an operating system user name and a matching
database user name. The same <replaceable>map-name</> can be database user name. The same <replaceable>map-name</replaceable> can be
used repeatedly to specify multiple user-mappings within a single map. used repeatedly to specify multiple user-mappings within a single map.
</para> </para>
<para> <para>
@ -788,13 +788,13 @@ local db1,db2,@demodbs all md5
user has requested to connect as. user has requested to connect as.
</para> </para>
<para> <para>
If the <replaceable>system-username</> field starts with a slash (<literal>/</>), If the <replaceable>system-username</replaceable> field starts with a slash (<literal>/</literal>),
the remainder of the field is treated as a regular expression. the remainder of the field is treated as a regular expression.
(See <xref linkend="posix-syntax-details"> for details of (See <xref linkend="posix-syntax-details"> for details of
<productname>PostgreSQL</>'s regular expression syntax.) The regular <productname>PostgreSQL</productname>'s regular expression syntax.) The regular
expression can include a single capture, or parenthesized subexpression, expression can include a single capture, or parenthesized subexpression,
which can then be referenced in the <replaceable>database-username</> which can then be referenced in the <replaceable>database-username</replaceable>
field as <literal>\1</> (backslash-one). This allows the mapping of field as <literal>\1</literal> (backslash-one). This allows the mapping of
multiple user names in a single line, which is particularly useful for multiple user names in a single line, which is particularly useful for
simple syntax substitutions. For example, these entries simple syntax substitutions. For example, these entries
<programlisting> <programlisting>
@ -802,14 +802,14 @@ mymap /^(.*)@mydomain\.com$ \1
mymap /^(.*)@otherdomain\.com$ guest mymap /^(.*)@otherdomain\.com$ guest
</programlisting> </programlisting>
will remove the domain part for users with system user names that end with will remove the domain part for users with system user names that end with
<literal>@mydomain.com</>, and allow any user whose system name ends with <literal>@mydomain.com</literal>, and allow any user whose system name ends with
<literal>@otherdomain.com</> to log in as <literal>guest</>. <literal>@otherdomain.com</literal> to log in as <literal>guest</literal>.
</para> </para>
<tip> <tip>
<para> <para>
Keep in mind that by default, a regular expression can match just part of Keep in mind that by default, a regular expression can match just part of
a string. It's usually wise to use <literal>^</> and <literal>$</>, as a string. It's usually wise to use <literal>^</literal> and <literal>$</literal>, as
shown in the above example, to force the match to be to the entire shown in the above example, to force the match to be to the entire
system user name. system user name.
</para> </para>
@ -821,28 +821,28 @@ mymap /^(.*)@otherdomain\.com$ guest
<systemitem>SIGHUP</systemitem><indexterm><primary>SIGHUP</primary></indexterm> <systemitem>SIGHUP</systemitem><indexterm><primary>SIGHUP</primary></indexterm>
signal. If you edit the file on an signal. If you edit the file on an
active system, you will need to signal the postmaster active system, you will need to signal the postmaster
(using <literal>pg_ctl reload</> or <literal>kill -HUP</>) to make it (using <literal>pg_ctl reload</literal> or <literal>kill -HUP</literal>) to make it
re-read the file. re-read the file.
</para> </para>
<para> <para>
A <filename>pg_ident.conf</filename> file that could be used in A <filename>pg_ident.conf</filename> file that could be used in
conjunction with the <filename>pg_hba.conf</> file in <xref conjunction with the <filename>pg_hba.conf</filename> file in <xref
linkend="example-pg-hba.conf"> is shown in <xref linkend="example-pg-hba.conf"> is shown in <xref
linkend="example-pg-ident.conf">. In this example, anyone linkend="example-pg-ident.conf">. In this example, anyone
logged in to a machine on the 192.168 network that does not have the logged in to a machine on the 192.168 network that does not have the
operating system user name <literal>bryanh</>, <literal>ann</>, or operating system user name <literal>bryanh</literal>, <literal>ann</literal>, or
<literal>robert</> would not be granted access. Unix user <literal>robert</literal> would not be granted access. Unix user
<literal>robert</> would only be allowed access when he tries to <literal>robert</literal> would only be allowed access when he tries to
connect as <productname>PostgreSQL</> user <literal>bob</>, not connect as <productname>PostgreSQL</productname> user <literal>bob</literal>, not
as <literal>robert</> or anyone else. <literal>ann</> would as <literal>robert</literal> or anyone else. <literal>ann</literal> would
only be allowed to connect as <literal>ann</>. User only be allowed to connect as <literal>ann</literal>. User
<literal>bryanh</> would be allowed to connect as either <literal>bryanh</literal> would be allowed to connect as either
<literal>bryanh</> or as <literal>guest1</>. <literal>bryanh</literal> or as <literal>guest1</literal>.
</para> </para>
<example id="example-pg-ident.conf"> <example id="example-pg-ident.conf">
<title>An Example <filename>pg_ident.conf</> File</title> <title>An Example <filename>pg_ident.conf</filename> File</title>
<programlisting> <programlisting>
# MAPNAME SYSTEM-USERNAME PG-USERNAME # MAPNAME SYSTEM-USERNAME PG-USERNAME
@ -866,21 +866,21 @@ omicron bryanh guest1
<title>Trust Authentication</title> <title>Trust Authentication</title>
<para> <para>
When <literal>trust</> authentication is specified, When <literal>trust</literal> authentication is specified,
<productname>PostgreSQL</productname> assumes that anyone who can <productname>PostgreSQL</productname> assumes that anyone who can
connect to the server is authorized to access the database with connect to the server is authorized to access the database with
whatever database user name they specify (even superuser names). whatever database user name they specify (even superuser names).
Of course, restrictions made in the <literal>database</> and Of course, restrictions made in the <literal>database</literal> and
<literal>user</> columns still apply. <literal>user</literal> columns still apply.
This method should only be used when there is adequate This method should only be used when there is adequate
operating-system-level protection on connections to the server. operating-system-level protection on connections to the server.
</para> </para>
<para> <para>
<literal>trust</> authentication is appropriate and very <literal>trust</literal> authentication is appropriate and very
convenient for local connections on a single-user workstation. It convenient for local connections on a single-user workstation. It
is usually <emphasis>not</> appropriate by itself on a multiuser is usually <emphasis>not</emphasis> appropriate by itself on a multiuser
machine. However, you might be able to use <literal>trust</> even machine. However, you might be able to use <literal>trust</literal> even
on a multiuser machine, if you restrict access to the server's on a multiuser machine, if you restrict access to the server's
Unix-domain socket file using file-system permissions. To do this, set the Unix-domain socket file using file-system permissions. To do this, set the
<varname>unix_socket_permissions</varname> (and possibly <varname>unix_socket_permissions</varname> (and possibly
@ -895,17 +895,17 @@ omicron bryanh guest1
Setting file-system permissions only helps for Unix-socket connections. Setting file-system permissions only helps for Unix-socket connections.
Local TCP/IP connections are not restricted by file-system permissions. Local TCP/IP connections are not restricted by file-system permissions.
Therefore, if you want to use file-system permissions for local security, Therefore, if you want to use file-system permissions for local security,
remove the <literal>host ... 127.0.0.1 ...</> line from remove the <literal>host ... 127.0.0.1 ...</literal> line from
<filename>pg_hba.conf</>, or change it to a <filename>pg_hba.conf</filename>, or change it to a
non-<literal>trust</> authentication method. non-<literal>trust</literal> authentication method.
</para> </para>
<para> <para>
<literal>trust</> authentication is only suitable for TCP/IP connections <literal>trust</literal> authentication is only suitable for TCP/IP connections
if you trust every user on every machine that is allowed to connect if you trust every user on every machine that is allowed to connect
to the server by the <filename>pg_hba.conf</> lines that specify to the server by the <filename>pg_hba.conf</filename> lines that specify
<literal>trust</>. It is seldom reasonable to use <literal>trust</> <literal>trust</literal>. It is seldom reasonable to use <literal>trust</literal>
for any TCP/IP connections other than those from <systemitem>localhost</> (127.0.0.1). for any TCP/IP connections other than those from <systemitem>localhost</systemitem> (127.0.0.1).
</para> </para>
</sect2> </sect2>
@ -914,10 +914,10 @@ omicron bryanh guest1
<title>Password Authentication</title> <title>Password Authentication</title>
<indexterm> <indexterm>
<primary>MD5</> <primary>MD5</primary>
</indexterm> </indexterm>
<indexterm> <indexterm>
<primary>SCRAM</> <primary>SCRAM</primary>
</indexterm> </indexterm>
<indexterm> <indexterm>
<primary>password</primary> <primary>password</primary>
@ -936,7 +936,7 @@ omicron bryanh guest1
<term><literal>scram-sha-256</literal></term> <term><literal>scram-sha-256</literal></term>
<listitem> <listitem>
<para> <para>
The method <literal>scram-sha-256</> performs SCRAM-SHA-256 The method <literal>scram-sha-256</literal> performs SCRAM-SHA-256
authentication, as described in authentication, as described in
<ulink url="https://tools.ietf.org/html/rfc7677">RFC 7677</ulink>. It <ulink url="https://tools.ietf.org/html/rfc7677">RFC 7677</ulink>. It
is a challenge-response scheme that prevents password sniffing on is a challenge-response scheme that prevents password sniffing on
@ -955,7 +955,7 @@ omicron bryanh guest1
<term><literal>md5</literal></term> <term><literal>md5</literal></term>
<listitem> <listitem>
<para> <para>
The method <literal>md5</> uses a custom less secure challenge-response The method <literal>md5</literal> uses a custom less secure challenge-response
mechanism. It prevents password sniffing and avoids storing passwords mechanism. It prevents password sniffing and avoids storing passwords
on the server in plain text but provides no protection if an attacker on the server in plain text but provides no protection if an attacker
manages to steal the password hash from the server. Also, the MD5 hash manages to steal the password hash from the server. Also, the MD5 hash
@ -982,10 +982,10 @@ omicron bryanh guest1
<term><literal>password</literal></term> <term><literal>password</literal></term>
<listitem> <listitem>
<para> <para>
The method <literal>password</> sends the password in clear-text and is The method <literal>password</literal> sends the password in clear-text and is
therefore vulnerable to password <quote>sniffing</> attacks. It should therefore vulnerable to password <quote>sniffing</quote> attacks. It should
always be avoided if possible. If the connection is protected by SSL always be avoided if possible. If the connection is protected by SSL
encryption then <literal>password</> can be used safely, though. encryption then <literal>password</literal> can be used safely, though.
(Though SSL certificate authentication might be a better choice if one (Though SSL certificate authentication might be a better choice if one
is depending on using SSL). is depending on using SSL).
</para> </para>
@ -996,7 +996,7 @@ omicron bryanh guest1
<para> <para>
<productname>PostgreSQL</productname> database passwords are <productname>PostgreSQL</productname> database passwords are
separate from operating system user passwords. The password for separate from operating system user passwords. The password for
each database user is stored in the <literal>pg_authid</> system each database user is stored in the <literal>pg_authid</literal> system
catalog. Passwords can be managed with the SQL commands catalog. Passwords can be managed with the SQL commands
<xref linkend="sql-createuser"> and <xref linkend="sql-createuser"> and
<xref linkend="sql-alterrole">, <xref linkend="sql-alterrole">,
@ -1060,7 +1060,7 @@ omicron bryanh guest1
</para> </para>
<para> <para>
GSSAPI support has to be enabled when <productname>PostgreSQL</> is built; GSSAPI support has to be enabled when <productname>PostgreSQL</productname> is built;
see <xref linkend="installation"> for more information. see <xref linkend="installation"> for more information.
</para> </para>
@ -1068,13 +1068,13 @@ omicron bryanh guest1
When <productname>GSSAPI</productname> uses When <productname>GSSAPI</productname> uses
<productname>Kerberos</productname>, it uses a standard principal <productname>Kerberos</productname>, it uses a standard principal
in the format in the format
<literal><replaceable>servicename</>/<replaceable>hostname</>@<replaceable>realm</></literal>. <literal><replaceable>servicename</replaceable>/<replaceable>hostname</replaceable>@<replaceable>realm</replaceable></literal>.
The PostgreSQL server will accept any principal that is included in the keytab used by The PostgreSQL server will accept any principal that is included in the keytab used by
the server, but care needs to be taken to specify the correct principal details when the server, but care needs to be taken to specify the correct principal details when
making the connection from the client using the <literal>krbsrvname</> connection parameter. (See making the connection from the client using the <literal>krbsrvname</literal> connection parameter. (See
also <xref linkend="libpq-paramkeywords">.) The installation default can be also <xref linkend="libpq-paramkeywords">.) The installation default can be
changed from the default <literal>postgres</literal> at build time using changed from the default <literal>postgres</literal> at build time using
<literal>./configure --with-krb-srvnam=</><replaceable>whatever</>. <literal>./configure --with-krb-srvnam=</literal><replaceable>whatever</replaceable>.
In most environments, In most environments,
this parameter never needs to be changed. this parameter never needs to be changed.
Some Kerberos implementations might require a different service name, Some Kerberos implementations might require a different service name,
@ -1082,31 +1082,31 @@ omicron bryanh guest1
to be in upper case (<literal>POSTGRES</literal>). to be in upper case (<literal>POSTGRES</literal>).
</para> </para>
<para> <para>
<replaceable>hostname</> is the fully qualified host name of the <replaceable>hostname</replaceable> is the fully qualified host name of the
server machine. The service principal's realm is the preferred realm server machine. The service principal's realm is the preferred realm
of the server machine. of the server machine.
</para> </para>
<para> <para>
Client principals can be mapped to different <productname>PostgreSQL</> Client principals can be mapped to different <productname>PostgreSQL</productname>
database user names with <filename>pg_ident.conf</>. For example, database user names with <filename>pg_ident.conf</filename>. For example,
<literal>pgusername@realm</> could be mapped to just <literal>pgusername</>. <literal>pgusername@realm</literal> could be mapped to just <literal>pgusername</literal>.
Alternatively, you can use the full <literal>username@realm</> principal as Alternatively, you can use the full <literal>username@realm</literal> principal as
the role name in <productname>PostgreSQL</> without any mapping. the role name in <productname>PostgreSQL</productname> without any mapping.
</para> </para>
<para> <para>
<productname>PostgreSQL</> also supports a parameter to strip the realm from <productname>PostgreSQL</productname> also supports a parameter to strip the realm from
the principal. This method is supported for backwards compatibility and is the principal. This method is supported for backwards compatibility and is
strongly discouraged as it is then impossible to distinguish different users strongly discouraged as it is then impossible to distinguish different users
with the same user name but coming from different realms. To enable this, with the same user name but coming from different realms. To enable this,
set <literal>include_realm</> to 0. For simple single-realm set <literal>include_realm</literal> to 0. For simple single-realm
installations, doing that combined with setting the installations, doing that combined with setting the
<literal>krb_realm</> parameter (which checks that the principal's realm <literal>krb_realm</literal> parameter (which checks that the principal's realm
matches exactly what is in the <literal>krb_realm</literal> parameter) matches exactly what is in the <literal>krb_realm</literal> parameter)
is still secure; but this is a is still secure; but this is a
less capable approach compared to specifying an explicit mapping in less capable approach compared to specifying an explicit mapping in
<filename>pg_ident.conf</>. <filename>pg_ident.conf</filename>.
</para> </para>
<para> <para>
@ -1116,8 +1116,8 @@ omicron bryanh guest1
of the key file is specified by the <xref of the key file is specified by the <xref
linkend="guc-krb-server-keyfile"> configuration linkend="guc-krb-server-keyfile"> configuration
parameter. The default is parameter. The default is
<filename>/usr/local/pgsql/etc/krb5.keytab</> (or whatever <filename>/usr/local/pgsql/etc/krb5.keytab</filename> (or whatever
directory was specified as <varname>sysconfdir</> at build time). directory was specified as <varname>sysconfdir</varname> at build time).
For security reasons, it is recommended to use a separate keytab For security reasons, it is recommended to use a separate keytab
just for the <productname>PostgreSQL</productname> server rather just for the <productname>PostgreSQL</productname> server rather
than opening up permissions on the system keytab file. than opening up permissions on the system keytab file.
@ -1127,17 +1127,17 @@ omicron bryanh guest1
Kerberos documentation for details. The following example is Kerberos documentation for details. The following example is
for MIT-compatible Kerberos 5 implementations: for MIT-compatible Kerberos 5 implementations:
<screen> <screen>
<prompt>kadmin% </><userinput>ank -randkey postgres/server.my.domain.org</> <prompt>kadmin% </prompt><userinput>ank -randkey postgres/server.my.domain.org</userinput>
<prompt>kadmin% </><userinput>ktadd -k krb5.keytab postgres/server.my.domain.org</> <prompt>kadmin% </prompt><userinput>ktadd -k krb5.keytab postgres/server.my.domain.org</userinput>
</screen> </screen>
</para> </para>
<para> <para>
When connecting to the database make sure you have a ticket for a When connecting to the database make sure you have a ticket for a
principal matching the requested database user name. For example, for principal matching the requested database user name. For example, for
database user name <literal>fred</>, principal database user name <literal>fred</literal>, principal
<literal>fred@EXAMPLE.COM</> would be able to connect. To also allow <literal>fred@EXAMPLE.COM</literal> would be able to connect. To also allow
principal <literal>fred/users.example.com@EXAMPLE.COM</>, use a user name principal <literal>fred/users.example.com@EXAMPLE.COM</literal>, use a user name
map, as described in <xref linkend="auth-username-maps">. map, as described in <xref linkend="auth-username-maps">.
</para> </para>
@ -1155,8 +1155,8 @@ omicron bryanh guest1
in multi-realm environments unless <literal>krb_realm</literal> is in multi-realm environments unless <literal>krb_realm</literal> is
also used. It is recommended to also used. It is recommended to
leave <literal>include_realm</literal> set to the default (1) and to leave <literal>include_realm</literal> set to the default (1) and to
provide an explicit mapping in <filename>pg_ident.conf</> to convert provide an explicit mapping in <filename>pg_ident.conf</filename> to convert
principal names to <productname>PostgreSQL</> user names. principal names to <productname>PostgreSQL</productname> user names.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1236,8 +1236,8 @@ omicron bryanh guest1
in multi-realm environments unless <literal>krb_realm</literal> is in multi-realm environments unless <literal>krb_realm</literal> is
also used. It is recommended to also used. It is recommended to
leave <literal>include_realm</literal> set to the default (1) and to leave <literal>include_realm</literal> set to the default (1) and to
provide an explicit mapping in <filename>pg_ident.conf</> to convert provide an explicit mapping in <filename>pg_ident.conf</filename> to convert
principal names to <productname>PostgreSQL</> user names. principal names to <productname>PostgreSQL</productname> user names.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1270,9 +1270,9 @@ omicron bryanh guest1
By default, these two names are identical for new user accounts. By default, these two names are identical for new user accounts.
</para> </para>
<para> <para>
Note that <application>libpq</> uses the SAM-compatible name if no Note that <application>libpq</application> uses the SAM-compatible name if no
explicit user name is specified. If you use explicit user name is specified. If you use
<application>libpq</> or a driver based on it, you should <application>libpq</application> or a driver based on it, you should
leave this option disabled or explicitly specify user name in the leave this option disabled or explicitly specify user name in the
connection string. connection string.
</para> </para>
@ -1357,8 +1357,8 @@ omicron bryanh guest1
is to answer questions like <quote>What user initiated the is to answer questions like <quote>What user initiated the
connection that goes out of your port <replaceable>X</replaceable> connection that goes out of your port <replaceable>X</replaceable>
and connects to my port <replaceable>Y</replaceable>?</quote>. and connects to my port <replaceable>Y</replaceable>?</quote>.
Since <productname>PostgreSQL</> knows both <replaceable>X</> and Since <productname>PostgreSQL</productname> knows both <replaceable>X</replaceable> and
<replaceable>Y</> when a physical connection is established, it <replaceable>Y</replaceable> when a physical connection is established, it
can interrogate the ident server on the host of the connecting can interrogate the ident server on the host of the connecting
client and can theoretically determine the operating system user client and can theoretically determine the operating system user
for any given connection. for any given connection.
@ -1386,9 +1386,9 @@ omicron bryanh guest1
<para> <para>
Some ident servers have a nonstandard option that causes the returned Some ident servers have a nonstandard option that causes the returned
user name to be encrypted, using a key that only the originating user name to be encrypted, using a key that only the originating
machine's administrator knows. This option <emphasis>must not</> be machine's administrator knows. This option <emphasis>must not</emphasis> be
used when using the ident server with <productname>PostgreSQL</>, used when using the ident server with <productname>PostgreSQL</productname>,
since <productname>PostgreSQL</> does not have any way to decrypt the since <productname>PostgreSQL</productname> does not have any way to decrypt the
returned string to determine the actual user name. returned string to determine the actual user name.
</para> </para>
</sect2> </sect2>
@ -1424,11 +1424,11 @@ omicron bryanh guest1
<para> <para>
Peer authentication is only available on operating systems providing Peer authentication is only available on operating systems providing
the <function>getpeereid()</> function, the <symbol>SO_PEERCRED</symbol> the <function>getpeereid()</function> function, the <symbol>SO_PEERCRED</symbol>
socket parameter, or similar mechanisms. Currently that includes socket parameter, or similar mechanisms. Currently that includes
<systemitem class="osname">Linux</>, <systemitem class="osname">Linux</systemitem>,
most flavors of <systemitem class="osname">BSD</> including most flavors of <systemitem class="osname">BSD</systemitem> including
<systemitem class="osname">macOS</>, <systemitem class="osname">macOS</systemitem>,
and <systemitem class="osname">Solaris</systemitem>. and <systemitem class="osname">Solaris</systemitem>.
</para> </para>
@ -1454,23 +1454,23 @@ omicron bryanh guest1
LDAP authentication can operate in two modes. In the first mode, LDAP authentication can operate in two modes. In the first mode,
which we will call the simple bind mode, which we will call the simple bind mode,
the server will bind to the distinguished name constructed as the server will bind to the distinguished name constructed as
<replaceable>prefix</> <replaceable>username</> <replaceable>suffix</>. <replaceable>prefix</replaceable> <replaceable>username</replaceable> <replaceable>suffix</replaceable>.
Typically, the <replaceable>prefix</> parameter is used to specify Typically, the <replaceable>prefix</replaceable> parameter is used to specify
<literal>cn=</>, or <replaceable>DOMAIN</><literal>\</> in an Active <literal>cn=</literal>, or <replaceable>DOMAIN</replaceable><literal>\</literal> in an Active
Directory environment. <replaceable>suffix</> is used to specify the Directory environment. <replaceable>suffix</replaceable> is used to specify the
remaining part of the DN in a non-Active Directory environment. remaining part of the DN in a non-Active Directory environment.
</para> </para>
<para> <para>
In the second mode, which we will call the search+bind mode, In the second mode, which we will call the search+bind mode,
the server first binds to the LDAP directory with the server first binds to the LDAP directory with
a fixed user name and password, specified with <replaceable>ldapbinddn</> a fixed user name and password, specified with <replaceable>ldapbinddn</replaceable>
and <replaceable>ldapbindpasswd</>, and performs a search for the user trying and <replaceable>ldapbindpasswd</replaceable>, and performs a search for the user trying
to log in to the database. If no user and password is configured, an to log in to the database. If no user and password is configured, an
anonymous bind will be attempted to the directory. The search will be anonymous bind will be attempted to the directory. The search will be
performed over the subtree at <replaceable>ldapbasedn</>, and will try to performed over the subtree at <replaceable>ldapbasedn</replaceable>, and will try to
do an exact match of the attribute specified in do an exact match of the attribute specified in
<replaceable>ldapsearchattribute</>. <replaceable>ldapsearchattribute</replaceable>.
Once the user has been found in Once the user has been found in
this search, the server disconnects and re-binds to the directory as this search, the server disconnects and re-binds to the directory as
this user, using the password specified by the client, to verify that the this user, using the password specified by the client, to verify that the
@ -1572,7 +1572,7 @@ omicron bryanh guest1
<para> <para>
Attribute to match against the user name in the search when doing Attribute to match against the user name in the search when doing
search+bind authentication. If no attribute is specified, the search+bind authentication. If no attribute is specified, the
<literal>uid</> attribute will be used. <literal>uid</literal> attribute will be used.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1719,11 +1719,11 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse
When using RADIUS authentication, an Access Request message will be sent When using RADIUS authentication, an Access Request message will be sent
to the configured RADIUS server. This request will be of type to the configured RADIUS server. This request will be of type
<literal>Authenticate Only</literal>, and include parameters for <literal>Authenticate Only</literal>, and include parameters for
<literal>user name</>, <literal>password</> (encrypted) and <literal>user name</literal>, <literal>password</literal> (encrypted) and
<literal>NAS Identifier</>. The request will be encrypted using <literal>NAS Identifier</literal>. The request will be encrypted using
a secret shared with the server. The RADIUS server will respond to a secret shared with the server. The RADIUS server will respond to
this server with either <literal>Access Accept</> or this server with either <literal>Access Accept</literal> or
<literal>Access Reject</>. There is no support for RADIUS accounting. <literal>Access Reject</literal>. There is no support for RADIUS accounting.
</para> </para>
<para> <para>
@ -1762,8 +1762,8 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse
<note> <note>
<para> <para>
The encryption vector used will only be cryptographically The encryption vector used will only be cryptographically
strong if <productname>PostgreSQL</> is built with support for strong if <productname>PostgreSQL</productname> is built with support for
<productname>OpenSSL</>. In other cases, the transmission to the <productname>OpenSSL</productname>. In other cases, the transmission to the
RADIUS server should only be considered obfuscated, not secured, and RADIUS server should only be considered obfuscated, not secured, and
external security measures should be applied if necessary. external security measures should be applied if necessary.
</para> </para>
@ -1777,7 +1777,7 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse
<listitem> <listitem>
<para> <para>
The port number on the RADIUS servers to connect to. If no port The port number on the RADIUS servers to connect to. If no port
is specified, the default port <literal>1812</> will be used. is specified, the default port <literal>1812</literal> will be used.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1786,12 +1786,12 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse
<term><literal>radiusidentifiers</literal></term> <term><literal>radiusidentifiers</literal></term>
<listitem> <listitem>
<para> <para>
The string used as <literal>NAS Identifier</> in the RADIUS The string used as <literal>NAS Identifier</literal> in the RADIUS
requests. This parameter can be used as a second parameter requests. This parameter can be used as a second parameter
identifying for example which database user the user is attempting identifying for example which database user the user is attempting
to authenticate as, which can be used for policy matching on to authenticate as, which can be used for policy matching on
the RADIUS server. If no identifier is specified, the default the RADIUS server. If no identifier is specified, the default
<literal>postgresql</> will be used. <literal>postgresql</literal> will be used.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1836,11 +1836,11 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse
</para> </para>
<para> <para>
In a <filename>pg_hba.conf</> record specifying certificate In a <filename>pg_hba.conf</filename> record specifying certificate
authentication, the authentication option <literal>clientcert</> is authentication, the authentication option <literal>clientcert</literal> is
assumed to be <literal>1</>, and it cannot be turned off since a client assumed to be <literal>1</literal>, and it cannot be turned off since a client
certificate is necessary for this method. What the <literal>cert</> certificate is necessary for this method. What the <literal>cert</literal>
method adds to the basic <literal>clientcert</> certificate validity test method adds to the basic <literal>clientcert</literal> certificate validity test
is a check that the <literal>cn</literal> attribute matches the database is a check that the <literal>cn</literal> attribute matches the database
user name. user name.
</para> </para>
@ -1863,7 +1863,7 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse
exist in the database before PAM can be used for authentication. For more exist in the database before PAM can be used for authentication. For more
information about PAM, please read the information about PAM, please read the
<ulink url="http://www.kernel.org/pub/linux/libs/pam/"> <ulink url="http://www.kernel.org/pub/linux/libs/pam/">
<productname>Linux-PAM</> Page</ulink>. <productname>Linux-PAM</productname> Page</ulink>.
</para> </para>
<para> <para>
@ -1896,7 +1896,7 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse
<note> <note>
<para> <para>
If PAM is set up to read <filename>/etc/shadow</>, authentication If PAM is set up to read <filename>/etc/shadow</filename>, authentication
will fail because the PostgreSQL server is started by a non-root will fail because the PostgreSQL server is started by a non-root
user. However, this is not an issue when PAM is configured to use user. However, this is not an issue when PAM is configured to use
LDAP or other authentication methods. LDAP or other authentication methods.
@ -1922,11 +1922,11 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse
</para> </para>
<para> <para>
BSD Authentication in <productname>PostgreSQL</> uses BSD Authentication in <productname>PostgreSQL</productname> uses
the <literal>auth-postgresql</literal> login type and authenticates with the <literal>auth-postgresql</literal> login type and authenticates with
the <literal>postgresql</literal> login class if that's defined the <literal>postgresql</literal> login class if that's defined
in <filename>login.conf</filename>. By default that login class does not in <filename>login.conf</filename>. By default that login class does not
exist, and <productname>PostgreSQL</> will use the default login class. exist, and <productname>PostgreSQL</productname> will use the default login class.
</para> </para>
<note> <note>

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@
</indexterm> </indexterm>
<para> <para>
The <application>spi</> module provides several workable examples The <application>spi</application> module provides several workable examples
of using SPI and triggers. While these functions are of some value in of using SPI and triggers. While these functions are of some value in
their own right, they are even more useful as examples to modify for their own right, they are even more useful as examples to modify for
your own purposes. The functions are general enough to be used your own purposes. The functions are general enough to be used
@ -26,15 +26,15 @@
<title>refint &mdash; Functions for Implementing Referential Integrity</title> <title>refint &mdash; Functions for Implementing Referential Integrity</title>
<para> <para>
<function>check_primary_key()</> and <function>check_primary_key()</function> and
<function>check_foreign_key()</> are used to check foreign key constraints. <function>check_foreign_key()</function> are used to check foreign key constraints.
(This functionality is long since superseded by the built-in foreign (This functionality is long since superseded by the built-in foreign
key mechanism, of course, but the module is still useful as an example.) key mechanism, of course, but the module is still useful as an example.)
</para> </para>
<para> <para>
<function>check_primary_key()</> checks the referencing table. <function>check_primary_key()</function> checks the referencing table.
To use, create a <literal>BEFORE INSERT OR UPDATE</> trigger using this To use, create a <literal>BEFORE INSERT OR UPDATE</literal> trigger using this
function on a table referencing another table. Specify as the trigger function on a table referencing another table. Specify as the trigger
arguments: the referencing table's column name(s) which form the foreign arguments: the referencing table's column name(s) which form the foreign
key, the referenced table name, and the column names in the referenced table key, the referenced table name, and the column names in the referenced table
@ -43,14 +43,14 @@
</para> </para>
<para> <para>
<function>check_foreign_key()</> checks the referenced table. <function>check_foreign_key()</function> checks the referenced table.
To use, create a <literal>BEFORE DELETE OR UPDATE</> trigger using this To use, create a <literal>BEFORE DELETE OR UPDATE</literal> trigger using this
function on a table referenced by other table(s). Specify as the trigger function on a table referenced by other table(s). Specify as the trigger
arguments: the number of referencing tables for which the function has to arguments: the number of referencing tables for which the function has to
perform checking, the action if a referencing key is found perform checking, the action if a referencing key is found
(<literal>cascade</> &mdash; to delete the referencing row, (<literal>cascade</literal> &mdash; to delete the referencing row,
<literal>restrict</> &mdash; to abort transaction if referencing keys <literal>restrict</literal> &mdash; to abort transaction if referencing keys
exist, <literal>setnull</> &mdash; to set referencing key fields to null), exist, <literal>setnull</literal> &mdash; to set referencing key fields to null),
the triggered table's column names which form the primary/unique key, then the triggered table's column names which form the primary/unique key, then
the referencing table name and column names (repeated for as many the referencing table name and column names (repeated for as many
referencing tables as were specified by first argument). Note that the referencing tables as were specified by first argument). Note that the
@ -59,7 +59,7 @@
</para> </para>
<para> <para>
There are examples in <filename>refint.example</>. There are examples in <filename>refint.example</filename>.
</para> </para>
</sect2> </sect2>
@ -67,10 +67,10 @@
<title>timetravel &mdash; Functions for Implementing Time Travel</title> <title>timetravel &mdash; Functions for Implementing Time Travel</title>
<para> <para>
Long ago, <productname>PostgreSQL</> had a built-in time travel feature Long ago, <productname>PostgreSQL</productname> had a built-in time travel feature
that kept the insert and delete times for each tuple. This can be that kept the insert and delete times for each tuple. This can be
emulated using these functions. To use these functions, emulated using these functions. To use these functions,
you must add to a table two columns of <type>abstime</> type to store you must add to a table two columns of <type>abstime</type> type to store
the date when a tuple was inserted (start_date) and changed/deleted the date when a tuple was inserted (start_date) and changed/deleted
(stop_date): (stop_date):
@ -89,7 +89,7 @@ CREATE TABLE mytab (
<para> <para>
When a new row is inserted, start_date should normally be set to When a new row is inserted, start_date should normally be set to
current time, and stop_date to <literal>infinity</>. The trigger current time, and stop_date to <literal>infinity</literal>. The trigger
will automatically substitute these values if the inserted data will automatically substitute these values if the inserted data
contains nulls in these columns. Generally, inserting explicit contains nulls in these columns. Generally, inserting explicit
non-null data in these columns should only be done when re-loading non-null data in these columns should only be done when re-loading
@ -97,7 +97,7 @@ CREATE TABLE mytab (
</para> </para>
<para> <para>
Tuples with stop_date equal to <literal>infinity</> are <quote>valid Tuples with stop_date equal to <literal>infinity</literal> are <quote>valid
now</quote>, and can be modified. Tuples with a finite stop_date cannot now</quote>, and can be modified. Tuples with a finite stop_date cannot
be modified anymore &mdash; the trigger will prevent it. (If you need be modified anymore &mdash; the trigger will prevent it. (If you need
to do that, you can turn off time travel as shown below.) to do that, you can turn off time travel as shown below.)
@ -107,7 +107,7 @@ CREATE TABLE mytab (
For a modifiable row, on update only the stop_date in the tuple being For a modifiable row, on update only the stop_date in the tuple being
updated will be changed (to current time) and a new tuple with the modified updated will be changed (to current time) and a new tuple with the modified
data will be inserted. Start_date in this new tuple will be set to current data will be inserted. Start_date in this new tuple will be set to current
time and stop_date to <literal>infinity</>. time and stop_date to <literal>infinity</literal>.
</para> </para>
<para> <para>
@ -117,29 +117,29 @@ CREATE TABLE mytab (
<para> <para>
To query for tuples <quote>valid now</quote>, include To query for tuples <quote>valid now</quote>, include
<literal>stop_date = 'infinity'</> in the query's WHERE condition. <literal>stop_date = 'infinity'</literal> in the query's WHERE condition.
(You might wish to incorporate that in a view.) Similarly, you can (You might wish to incorporate that in a view.) Similarly, you can
query for tuples valid at any past time with suitable conditions on query for tuples valid at any past time with suitable conditions on
start_date and stop_date. start_date and stop_date.
</para> </para>
<para> <para>
<function>timetravel()</> is the general trigger function that supports <function>timetravel()</function> is the general trigger function that supports
this behavior. Create a <literal>BEFORE INSERT OR UPDATE OR DELETE</> this behavior. Create a <literal>BEFORE INSERT OR UPDATE OR DELETE</literal>
trigger using this function on each time-traveled table. Specify two trigger using this function on each time-traveled table. Specify two
trigger arguments: the actual trigger arguments: the actual
names of the start_date and stop_date columns. names of the start_date and stop_date columns.
Optionally, you can specify one to three more arguments, which must refer Optionally, you can specify one to three more arguments, which must refer
to columns of type <type>text</>. The trigger will store the name of to columns of type <type>text</type>. The trigger will store the name of
the current user into the first of these columns during INSERT, the the current user into the first of these columns during INSERT, the
second column during UPDATE, and the third during DELETE. second column during UPDATE, and the third during DELETE.
</para> </para>
<para> <para>
<function>set_timetravel()</> allows you to turn time-travel on or off for <function>set_timetravel()</function> allows you to turn time-travel on or off for
a table. a table.
<literal>set_timetravel('mytab', 1)</> will turn TT ON for table <literal>mytab</>. <literal>set_timetravel('mytab', 1)</literal> will turn TT ON for table <literal>mytab</literal>.
<literal>set_timetravel('mytab', 0)</> will turn TT OFF for table <literal>mytab</>. <literal>set_timetravel('mytab', 0)</literal> will turn TT OFF for table <literal>mytab</literal>.
In both cases the old status is reported. While TT is off, you can modify In both cases the old status is reported. While TT is off, you can modify
the start_date and stop_date columns freely. Note that the on/off status the start_date and stop_date columns freely. Note that the on/off status
is local to the current database session &mdash; fresh sessions will is local to the current database session &mdash; fresh sessions will
@ -147,12 +147,12 @@ CREATE TABLE mytab (
</para> </para>
<para> <para>
<function>get_timetravel()</> returns the TT state for a table without <function>get_timetravel()</function> returns the TT state for a table without
changing it. changing it.
</para> </para>
<para> <para>
There is an example in <filename>timetravel.example</>. There is an example in <filename>timetravel.example</filename>.
</para> </para>
</sect2> </sect2>
@ -160,17 +160,17 @@ CREATE TABLE mytab (
<title>autoinc &mdash; Functions for Autoincrementing Fields</title> <title>autoinc &mdash; Functions for Autoincrementing Fields</title>
<para> <para>
<function>autoinc()</> is a trigger that stores the next value of <function>autoinc()</function> is a trigger that stores the next value of
a sequence into an integer field. This has some overlap with the a sequence into an integer field. This has some overlap with the
built-in <quote>serial column</> feature, but it is not the same: built-in <quote>serial column</quote> feature, but it is not the same:
<function>autoinc()</> will override attempts to substitute a <function>autoinc()</function> will override attempts to substitute a
different field value during inserts, and optionally it can be different field value during inserts, and optionally it can be
used to increment the field during updates, too. used to increment the field during updates, too.
</para> </para>
<para> <para>
To use, create a <literal>BEFORE INSERT</> (or optionally <literal>BEFORE To use, create a <literal>BEFORE INSERT</literal> (or optionally <literal>BEFORE
INSERT OR UPDATE</>) trigger using this function. Specify two INSERT OR UPDATE</literal>) trigger using this function. Specify two
trigger arguments: the name of the integer column to be modified, trigger arguments: the name of the integer column to be modified,
and the name of the sequence object that will supply values. and the name of the sequence object that will supply values.
(Actually, you can specify any number of pairs of such names, if (Actually, you can specify any number of pairs of such names, if
@ -178,7 +178,7 @@ CREATE TABLE mytab (
</para> </para>
<para> <para>
There is an example in <filename>autoinc.example</>. There is an example in <filename>autoinc.example</filename>.
</para> </para>
</sect2> </sect2>
@ -187,19 +187,19 @@ CREATE TABLE mytab (
<title>insert_username &mdash; Functions for Tracking Who Changed a Table</title> <title>insert_username &mdash; Functions for Tracking Who Changed a Table</title>
<para> <para>
<function>insert_username()</> is a trigger that stores the current <function>insert_username()</function> is a trigger that stores the current
user's name into a text field. This can be useful for tracking user's name into a text field. This can be useful for tracking
who last modified a particular row within a table. who last modified a particular row within a table.
</para> </para>
<para> <para>
To use, create a <literal>BEFORE INSERT</> and/or <literal>UPDATE</> To use, create a <literal>BEFORE INSERT</literal> and/or <literal>UPDATE</literal>
trigger using this function. Specify a single trigger trigger using this function. Specify a single trigger
argument: the name of the text column to be modified. argument: the name of the text column to be modified.
</para> </para>
<para> <para>
There is an example in <filename>insert_username.example</>. There is an example in <filename>insert_username.example</filename>.
</para> </para>
</sect2> </sect2>
@ -208,21 +208,21 @@ CREATE TABLE mytab (
<title>moddatetime &mdash; Functions for Tracking Last Modification Time</title> <title>moddatetime &mdash; Functions for Tracking Last Modification Time</title>
<para> <para>
<function>moddatetime()</> is a trigger that stores the current <function>moddatetime()</function> is a trigger that stores the current
time into a <type>timestamp</> field. This can be useful for tracking time into a <type>timestamp</type> field. This can be useful for tracking
the last modification time of a particular row within a table. the last modification time of a particular row within a table.
</para> </para>
<para> <para>
To use, create a <literal>BEFORE UPDATE</> To use, create a <literal>BEFORE UPDATE</literal>
trigger using this function. Specify a single trigger trigger using this function. Specify a single trigger
argument: the name of the column to be modified. argument: the name of the column to be modified.
The column must be of type <type>timestamp</> or <type>timestamp with The column must be of type <type>timestamp</type> or <type>timestamp with
time zone</>. time zone</type>.
</para> </para>
<para> <para>
There is an example in <filename>moddatetime.example</>. There is an example in <filename>moddatetime.example</filename>.
</para> </para>
</sect2> </sect2>

View File

@ -6,7 +6,7 @@
<para> <para>
This appendix and the next one contain information regarding the modules that This appendix and the next one contain information regarding the modules that
can be found in the <literal>contrib</literal> directory of the can be found in the <literal>contrib</literal> directory of the
<productname>PostgreSQL</> distribution. <productname>PostgreSQL</productname> distribution.
These include porting tools, analysis utilities, These include porting tools, analysis utilities,
and plug-in features that are not part of the core PostgreSQL system, and plug-in features that are not part of the core PostgreSQL system,
mainly because they address a limited audience or are too experimental mainly because they address a limited audience or are too experimental
@ -41,54 +41,54 @@
<screen> <screen>
<userinput>make installcheck</userinput> <userinput>make installcheck</userinput>
</screen> </screen>
once you have a <productname>PostgreSQL</> server running. once you have a <productname>PostgreSQL</productname> server running.
</para> </para>
<para> <para>
If you are using a pre-packaged version of <productname>PostgreSQL</>, If you are using a pre-packaged version of <productname>PostgreSQL</productname>,
these modules are typically made available as a separate subpackage, these modules are typically made available as a separate subpackage,
such as <literal>postgresql-contrib</>. such as <literal>postgresql-contrib</literal>.
</para> </para>
<para> <para>
Many modules supply new user-defined functions, operators, or types. Many modules supply new user-defined functions, operators, or types.
To make use of one of these modules, after you have installed the code To make use of one of these modules, after you have installed the code
you need to register the new SQL objects in the database system. you need to register the new SQL objects in the database system.
In <productname>PostgreSQL</> 9.1 and later, this is done by executing In <productname>PostgreSQL</productname> 9.1 and later, this is done by executing
a <xref linkend="sql-createextension"> command. In a fresh database, a <xref linkend="sql-createextension"> command. In a fresh database,
you can simply do you can simply do
<programlisting> <programlisting>
CREATE EXTENSION <replaceable>module_name</>; CREATE EXTENSION <replaceable>module_name</replaceable>;
</programlisting> </programlisting>
This command must be run by a database superuser. This registers the This command must be run by a database superuser. This registers the
new SQL objects in the current database only, so you need to run this new SQL objects in the current database only, so you need to run this
command in each database that you want command in each database that you want
the module's facilities to be available in. Alternatively, run it in the module's facilities to be available in. Alternatively, run it in
database <literal>template1</> so that the extension will be copied into database <literal>template1</literal> so that the extension will be copied into
subsequently-created databases by default. subsequently-created databases by default.
</para> </para>
<para> <para>
Many modules allow you to install their objects in a schema of your Many modules allow you to install their objects in a schema of your
choice. To do that, add <literal>SCHEMA choice. To do that, add <literal>SCHEMA
<replaceable>schema_name</></literal> to the <command>CREATE EXTENSION</> <replaceable>schema_name</replaceable></literal> to the <command>CREATE EXTENSION</command>
command. By default, the objects will be placed in your current creation command. By default, the objects will be placed in your current creation
target schema, typically <literal>public</>. target schema, typically <literal>public</literal>.
</para> </para>
<para> <para>
If your database was brought forward by dump and reload from a pre-9.1 If your database was brought forward by dump and reload from a pre-9.1
version of <productname>PostgreSQL</>, and you had been using the pre-9.1 version of <productname>PostgreSQL</productname>, and you had been using the pre-9.1
version of the module in it, you should instead do version of the module in it, you should instead do
<programlisting> <programlisting>
CREATE EXTENSION <replaceable>module_name</> FROM unpackaged; CREATE EXTENSION <replaceable>module_name</replaceable> FROM unpackaged;
</programlisting> </programlisting>
This will update the pre-9.1 objects of the module into a proper This will update the pre-9.1 objects of the module into a proper
<firstterm>extension</> object. Future updates to the module will be <firstterm>extension</firstterm> object. Future updates to the module will be
managed by <xref linkend="sql-alterextension">. managed by <xref linkend="sql-alterextension">.
For more information about extension updates, see For more information about extension updates, see
<xref linkend="extend-extensions">. <xref linkend="extend-extensions">.
@ -163,7 +163,7 @@ pages.
<para> <para>
This appendix and the previous one contain information regarding the modules that This appendix and the previous one contain information regarding the modules that
can be found in the <literal>contrib</literal> directory of the can be found in the <literal>contrib</literal> directory of the
<productname>PostgreSQL</> distribution. See <xref linkend="contrib"> for <productname>PostgreSQL</productname> distribution. See <xref linkend="contrib"> for
more information about the <literal>contrib</literal> section in general and more information about the <literal>contrib</literal> section in general and
server extensions and plug-ins found in <literal>contrib</literal> server extensions and plug-ins found in <literal>contrib</literal>
specifically. specifically.

View File

@ -8,7 +8,7 @@
</indexterm> </indexterm>
<para> <para>
This module implements a data type <type>cube</> for This module implements a data type <type>cube</type> for
representing multidimensional cubes. representing multidimensional cubes.
</para> </para>
@ -17,8 +17,8 @@
<para> <para>
<xref linkend="cube-repr-table"> shows the valid external <xref linkend="cube-repr-table"> shows the valid external
representations for the <type>cube</> representations for the <type>cube</type>
type. <replaceable>x</>, <replaceable>y</>, etc. denote type. <replaceable>x</replaceable>, <replaceable>y</replaceable>, etc. denote
floating-point numbers. floating-point numbers.
</para> </para>
@ -34,43 +34,43 @@
<tbody> <tbody>
<row> <row>
<entry><literal><replaceable>x</></literal></entry> <entry><literal><replaceable>x</replaceable></literal></entry>
<entry>A one-dimensional point <entry>A one-dimensional point
(or, zero-length one-dimensional interval) (or, zero-length one-dimensional interval)
</entry> </entry>
</row> </row>
<row> <row>
<entry><literal>(<replaceable>x</>)</literal></entry> <entry><literal>(<replaceable>x</replaceable>)</literal></entry>
<entry>Same as above</entry> <entry>Same as above</entry>
</row> </row>
<row> <row>
<entry><literal><replaceable>x1</>,<replaceable>x2</>,...,<replaceable>xn</></literal></entry> <entry><literal><replaceable>x1</replaceable>,<replaceable>x2</replaceable>,...,<replaceable>xn</replaceable></literal></entry>
<entry>A point in n-dimensional space, represented internally as a <entry>A point in n-dimensional space, represented internally as a
zero-volume cube zero-volume cube
</entry> </entry>
</row> </row>
<row> <row>
<entry><literal>(<replaceable>x1</>,<replaceable>x2</>,...,<replaceable>xn</>)</literal></entry> <entry><literal>(<replaceable>x1</replaceable>,<replaceable>x2</replaceable>,...,<replaceable>xn</replaceable>)</literal></entry>
<entry>Same as above</entry> <entry>Same as above</entry>
</row> </row>
<row> <row>
<entry><literal>(<replaceable>x</>),(<replaceable>y</>)</literal></entry> <entry><literal>(<replaceable>x</replaceable>),(<replaceable>y</replaceable>)</literal></entry>
<entry>A one-dimensional interval starting at <replaceable>x</> and ending at <replaceable>y</> or vice versa; the <entry>A one-dimensional interval starting at <replaceable>x</replaceable> and ending at <replaceable>y</replaceable> or vice versa; the
order does not matter order does not matter
</entry> </entry>
</row> </row>
<row> <row>
<entry><literal>[(<replaceable>x</>),(<replaceable>y</>)]</literal></entry> <entry><literal>[(<replaceable>x</replaceable>),(<replaceable>y</replaceable>)]</literal></entry>
<entry>Same as above</entry> <entry>Same as above</entry>
</row> </row>
<row> <row>
<entry><literal>(<replaceable>x1</>,...,<replaceable>xn</>),(<replaceable>y1</>,...,<replaceable>yn</>)</literal></entry> <entry><literal>(<replaceable>x1</replaceable>,...,<replaceable>xn</replaceable>),(<replaceable>y1</replaceable>,...,<replaceable>yn</replaceable>)</literal></entry>
<entry>An n-dimensional cube represented by a pair of its diagonally <entry>An n-dimensional cube represented by a pair of its diagonally
opposite corners opposite corners
</entry> </entry>
</row> </row>
<row> <row>
<entry><literal>[(<replaceable>x1</>,...,<replaceable>xn</>),(<replaceable>y1</>,...,<replaceable>yn</>)]</literal></entry> <entry><literal>[(<replaceable>x1</replaceable>,...,<replaceable>xn</replaceable>),(<replaceable>y1</replaceable>,...,<replaceable>yn</replaceable>)]</literal></entry>
<entry>Same as above</entry> <entry>Same as above</entry>
</row> </row>
</tbody> </tbody>
@ -79,17 +79,17 @@
<para> <para>
It does not matter which order the opposite corners of a cube are It does not matter which order the opposite corners of a cube are
entered in. The <type>cube</> functions entered in. The <type>cube</type> functions
automatically swap values if needed to create a uniform automatically swap values if needed to create a uniform
<quote>lower left &mdash; upper right</> internal representation. <quote>lower left &mdash; upper right</quote> internal representation.
When the corners coincide, <type>cube</> stores only one corner When the corners coincide, <type>cube</type> stores only one corner
along with an <quote>is point</> flag to avoid wasting space. along with an <quote>is point</quote> flag to avoid wasting space.
</para> </para>
<para> <para>
White space is ignored on input, so White space is ignored on input, so
<literal>[(<replaceable>x</>),(<replaceable>y</>)]</literal> is the same as <literal>[(<replaceable>x</replaceable>),(<replaceable>y</replaceable>)]</literal> is the same as
<literal>[ ( <replaceable>x</> ), ( <replaceable>y</> ) ]</literal>. <literal>[ ( <replaceable>x</replaceable> ), ( <replaceable>y</replaceable> ) ]</literal>.
</para> </para>
</sect2> </sect2>
@ -107,7 +107,7 @@
<para> <para>
<xref linkend="cube-operators-table"> shows the operators provided for <xref linkend="cube-operators-table"> shows the operators provided for
type <type>cube</>. type <type>cube</type>.
</para> </para>
<table id="cube-operators-table"> <table id="cube-operators-table">
@ -123,91 +123,91 @@
<tbody> <tbody>
<row> <row>
<entry><literal>a = b</></entry> <entry><literal>a = b</literal></entry>
<entry><type>boolean</></entry> <entry><type>boolean</type></entry>
<entry>The cubes a and b are identical.</entry> <entry>The cubes a and b are identical.</entry>
</row> </row>
<row> <row>
<entry><literal>a &amp;&amp; b</></entry> <entry><literal>a &amp;&amp; b</literal></entry>
<entry><type>boolean</></entry> <entry><type>boolean</type></entry>
<entry>The cubes a and b overlap.</entry> <entry>The cubes a and b overlap.</entry>
</row> </row>
<row> <row>
<entry><literal>a @&gt; b</></entry> <entry><literal>a @&gt; b</literal></entry>
<entry><type>boolean</></entry> <entry><type>boolean</type></entry>
<entry>The cube a contains the cube b.</entry> <entry>The cube a contains the cube b.</entry>
</row> </row>
<row> <row>
<entry><literal>a &lt;@ b</></entry> <entry><literal>a &lt;@ b</literal></entry>
<entry><type>boolean</></entry> <entry><type>boolean</type></entry>
<entry>The cube a is contained in the cube b.</entry> <entry>The cube a is contained in the cube b.</entry>
</row> </row>
<row> <row>
<entry><literal>a &lt; b</></entry> <entry><literal>a &lt; b</literal></entry>
<entry><type>boolean</></entry> <entry><type>boolean</type></entry>
<entry>The cube a is less than the cube b.</entry> <entry>The cube a is less than the cube b.</entry>
</row> </row>
<row> <row>
<entry><literal>a &lt;= b</></entry> <entry><literal>a &lt;= b</literal></entry>
<entry><type>boolean</></entry> <entry><type>boolean</type></entry>
<entry>The cube a is less than or equal to the cube b.</entry> <entry>The cube a is less than or equal to the cube b.</entry>
</row> </row>
<row> <row>
<entry><literal>a &gt; b</></entry> <entry><literal>a &gt; b</literal></entry>
<entry><type>boolean</></entry> <entry><type>boolean</type></entry>
<entry>The cube a is greater than the cube b.</entry> <entry>The cube a is greater than the cube b.</entry>
</row> </row>
<row> <row>
<entry><literal>a &gt;= b</></entry> <entry><literal>a &gt;= b</literal></entry>
<entry><type>boolean</></entry> <entry><type>boolean</type></entry>
<entry>The cube a is greater than or equal to the cube b.</entry> <entry>The cube a is greater than or equal to the cube b.</entry>
</row> </row>
<row> <row>
<entry><literal>a &lt;&gt; b</></entry> <entry><literal>a &lt;&gt; b</literal></entry>
<entry><type>boolean</></entry> <entry><type>boolean</type></entry>
<entry>The cube a is not equal to the cube b.</entry> <entry>The cube a is not equal to the cube b.</entry>
</row> </row>
<row> <row>
<entry><literal>a -&gt; n</></entry> <entry><literal>a -&gt; n</literal></entry>
<entry><type>float8</></entry> <entry><type>float8</type></entry>
<entry>Get <replaceable>n</>-th coordinate of cube (counting from 1).</entry> <entry>Get <replaceable>n</replaceable>-th coordinate of cube (counting from 1).</entry>
</row> </row>
<row> <row>
<entry><literal>a ~&gt; n</></entry> <entry><literal>a ~&gt; n</literal></entry>
<entry><type>float8</></entry> <entry><type>float8</type></entry>
<entry> <entry>
Get <replaceable>n</>-th coordinate in <quote>normalized</> cube Get <replaceable>n</replaceable>-th coordinate in <quote>normalized</quote> cube
representation, in which the coordinates have been rearranged into representation, in which the coordinates have been rearranged into
the form <quote>lower left &mdash; upper right</>; that is, the the form <quote>lower left &mdash; upper right</quote>; that is, the
smaller endpoint along each dimension appears first. smaller endpoint along each dimension appears first.
</entry> </entry>
</row> </row>
<row> <row>
<entry><literal>a &lt;-&gt; b</></entry> <entry><literal>a &lt;-&gt; b</literal></entry>
<entry><type>float8</></entry> <entry><type>float8</type></entry>
<entry>Euclidean distance between a and b.</entry> <entry>Euclidean distance between a and b.</entry>
</row> </row>
<row> <row>
<entry><literal>a &lt;#&gt; b</></entry> <entry><literal>a &lt;#&gt; b</literal></entry>
<entry><type>float8</></entry> <entry><type>float8</type></entry>
<entry>Taxicab (L-1 metric) distance between a and b.</entry> <entry>Taxicab (L-1 metric) distance between a and b.</entry>
</row> </row>
<row> <row>
<entry><literal>a &lt;=&gt; b</></entry> <entry><literal>a &lt;=&gt; b</literal></entry>
<entry><type>float8</></entry> <entry><type>float8</type></entry>
<entry>Chebyshev (L-inf metric) distance between a and b.</entry> <entry>Chebyshev (L-inf metric) distance between a and b.</entry>
</row> </row>
@ -216,35 +216,35 @@
</table> </table>
<para> <para>
(Before PostgreSQL 8.2, the containment operators <literal>@&gt;</> and <literal>&lt;@</> were (Before PostgreSQL 8.2, the containment operators <literal>@&gt;</literal> and <literal>&lt;@</literal> were
respectively called <literal>@</> and <literal>~</>. These names are still available, but are respectively called <literal>@</literal> and <literal>~</literal>. These names are still available, but are
deprecated and will eventually be retired. Notice that the old names deprecated and will eventually be retired. Notice that the old names
are reversed from the convention formerly followed by the core geometric are reversed from the convention formerly followed by the core geometric
data types!) data types!)
</para> </para>
<para> <para>
The scalar ordering operators (<literal>&lt;</>, <literal>&gt;=</>, etc) The scalar ordering operators (<literal>&lt;</literal>, <literal>&gt;=</literal>, etc)
do not make a lot of sense for any practical purpose but sorting. These do not make a lot of sense for any practical purpose but sorting. These
operators first compare the first coordinates, and if those are equal, operators first compare the first coordinates, and if those are equal,
compare the second coordinates, etc. They exist mainly to support the compare the second coordinates, etc. They exist mainly to support the
b-tree index operator class for <type>cube</>, which can be useful for b-tree index operator class for <type>cube</type>, which can be useful for
example if you would like a UNIQUE constraint on a <type>cube</> column. example if you would like a UNIQUE constraint on a <type>cube</type> column.
</para> </para>
<para> <para>
The <filename>cube</> module also provides a GiST index operator class for The <filename>cube</filename> module also provides a GiST index operator class for
<type>cube</> values. <type>cube</type> values.
A <type>cube</> GiST index can be used to search for values using the A <type>cube</type> GiST index can be used to search for values using the
<literal>=</>, <literal>&amp;&amp;</>, <literal>@&gt;</>, and <literal>=</literal>, <literal>&amp;&amp;</literal>, <literal>@&gt;</literal>, and
<literal>&lt;@</> operators in <literal>WHERE</> clauses. <literal>&lt;@</literal> operators in <literal>WHERE</literal> clauses.
</para> </para>
<para> <para>
In addition, a <type>cube</> GiST index can be used to find nearest In addition, a <type>cube</type> GiST index can be used to find nearest
neighbors using the metric operators neighbors using the metric operators
<literal>&lt;-&gt;</>, <literal>&lt;#&gt;</>, and <literal>&lt;-&gt;</literal>, <literal>&lt;#&gt;</literal>, and
<literal>&lt;=&gt;</> in <literal>ORDER BY</> clauses. <literal>&lt;=&gt;</literal> in <literal>ORDER BY</literal> clauses.
For example, the nearest neighbor of the 3-D point (0.5, 0.5, 0.5) For example, the nearest neighbor of the 3-D point (0.5, 0.5, 0.5)
could be found efficiently with: could be found efficiently with:
<programlisting> <programlisting>
@ -253,7 +253,7 @@ SELECT c FROM test ORDER BY c &lt;-&gt; cube(array[0.5,0.5,0.5]) LIMIT 1;
</para> </para>
<para> <para>
The <literal>~&gt;</> operator can also be used in this way to The <literal>~&gt;</literal> operator can also be used in this way to
efficiently retrieve the first few values sorted by a selected coordinate. efficiently retrieve the first few values sorted by a selected coordinate.
For example, to get the first few cubes ordered by the first coordinate For example, to get the first few cubes ordered by the first coordinate
(lower left corner) ascending one could use the following query: (lower left corner) ascending one could use the following query:
@ -365,7 +365,7 @@ SELECT c FROM test ORDER BY c ~&gt; 3 DESC LIMIT 5;
<row> <row>
<entry><literal>cube_ll_coord(cube, integer)</literal></entry> <entry><literal>cube_ll_coord(cube, integer)</literal></entry>
<entry><type>float8</type></entry> <entry><type>float8</type></entry>
<entry>Returns the <replaceable>n</>-th coordinate value for the lower <entry>Returns the <replaceable>n</replaceable>-th coordinate value for the lower
left corner of the cube. left corner of the cube.
</entry> </entry>
<entry> <entry>
@ -376,7 +376,7 @@ SELECT c FROM test ORDER BY c ~&gt; 3 DESC LIMIT 5;
<row> <row>
<entry><literal>cube_ur_coord(cube, integer)</literal></entry> <entry><literal>cube_ur_coord(cube, integer)</literal></entry>
<entry><type>float8</type></entry> <entry><type>float8</type></entry>
<entry>Returns the <replaceable>n</>-th coordinate value for the <entry>Returns the <replaceable>n</replaceable>-th coordinate value for the
upper right corner of the cube. upper right corner of the cube.
</entry> </entry>
<entry> <entry>
@ -412,9 +412,9 @@ SELECT c FROM test ORDER BY c ~&gt; 3 DESC LIMIT 5;
desired. desired.
</entry> </entry>
<entry> <entry>
<literal>cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[2]) == '(3),(7)'</> <literal>cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[2]) == '(3),(7)'</literal>
<literal>cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]) == <literal>cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]) ==
'(5,3,1,1),(8,7,6,6)'</> '(5,3,1,1),(8,7,6,6)'</literal>
</entry> </entry>
</row> </row>
@ -440,24 +440,24 @@ SELECT c FROM test ORDER BY c ~&gt; 3 DESC LIMIT 5;
<entry><literal>cube_enlarge(c cube, r double, n integer)</literal></entry> <entry><literal>cube_enlarge(c cube, r double, n integer)</literal></entry>
<entry><type>cube</type></entry> <entry><type>cube</type></entry>
<entry>Increases the size of the cube by the specified <entry>Increases the size of the cube by the specified
radius <replaceable>r</> in at least <replaceable>n</> dimensions. radius <replaceable>r</replaceable> in at least <replaceable>n</replaceable> dimensions.
If the radius is negative the cube is shrunk instead. If the radius is negative the cube is shrunk instead.
All defined dimensions are changed by the radius <replaceable>r</>. All defined dimensions are changed by the radius <replaceable>r</replaceable>.
Lower-left coordinates are decreased by <replaceable>r</> and Lower-left coordinates are decreased by <replaceable>r</replaceable> and
upper-right coordinates are increased by <replaceable>r</>. If a upper-right coordinates are increased by <replaceable>r</replaceable>. If a
lower-left coordinate is increased to more than the corresponding lower-left coordinate is increased to more than the corresponding
upper-right coordinate (this can only happen when <replaceable>r</> upper-right coordinate (this can only happen when <replaceable>r</replaceable>
&lt; 0) than both coordinates are set to their average. &lt; 0) than both coordinates are set to their average.
If <replaceable>n</> is greater than the number of defined dimensions If <replaceable>n</replaceable> is greater than the number of defined dimensions
and the cube is being enlarged (<replaceable>r</> &gt; 0), then extra and the cube is being enlarged (<replaceable>r</replaceable> &gt; 0), then extra
dimensions are added to make <replaceable>n</> altogether; dimensions are added to make <replaceable>n</replaceable> altogether;
0 is used as the initial value for the extra coordinates. 0 is used as the initial value for the extra coordinates.
This function is useful for creating bounding boxes around a point for This function is useful for creating bounding boxes around a point for
searching for nearby points. searching for nearby points.
</entry> </entry>
<entry> <entry>
<literal>cube_enlarge('(1,2),(3,4)', 0.5, 3) == <literal>cube_enlarge('(1,2),(3,4)', 0.5, 3) ==
'(0.5,1.5,-0.5),(3.5,4.5,0.5)'</> '(0.5,1.5,-0.5),(3.5,4.5,0.5)'</literal>
</entry> </entry>
</row> </row>
</tbody> </tbody>
@ -523,13 +523,13 @@ t
<title>Notes</title> <title>Notes</title>
<para> <para>
For examples of usage, see the regression test <filename>sql/cube.sql</>. For examples of usage, see the regression test <filename>sql/cube.sql</filename>.
</para> </para>
<para> <para>
To make it harder for people to break things, there To make it harder for people to break things, there
is a limit of 100 on the number of dimensions of cubes. This is set is a limit of 100 on the number of dimensions of cubes. This is set
in <filename>cubedata.h</> if you need something bigger. in <filename>cubedata.h</filename> if you need something bigger.
</para> </para>
</sect2> </sect2>

View File

@ -9,9 +9,9 @@
</indexterm> </indexterm>
<para> <para>
<productname>PostgreSQL</> supports a set of experimental facilities which <productname>PostgreSQL</productname> supports a set of experimental facilities which
are intended to allow extension modules to add new scan types to the system. are intended to allow extension modules to add new scan types to the system.
Unlike a <link linkend="fdwhandler">foreign data wrapper</>, which is only Unlike a <link linkend="fdwhandler">foreign data wrapper</link>, which is only
responsible for knowing how to scan its own foreign tables, a custom scan responsible for knowing how to scan its own foreign tables, a custom scan
provider can provide an alternative method of scanning any relation in the provider can provide an alternative method of scanning any relation in the
system. Typically, the motivation for writing a custom scan provider will system. Typically, the motivation for writing a custom scan provider will
@ -51,9 +51,9 @@ extern PGDLLIMPORT set_rel_pathlist_hook_type set_rel_pathlist_hook;
<para> <para>
Although this hook function can be used to examine, modify, or remove Although this hook function can be used to examine, modify, or remove
paths generated by the core system, a custom scan provider will typically paths generated by the core system, a custom scan provider will typically
confine itself to generating <structname>CustomPath</> objects and adding confine itself to generating <structname>CustomPath</structname> objects and adding
them to <literal>rel</> using <function>add_path</>. The custom scan them to <literal>rel</literal> using <function>add_path</function>. The custom scan
provider is responsible for initializing the <structname>CustomPath</> provider is responsible for initializing the <structname>CustomPath</structname>
object, which is declared like this: object, which is declared like this:
<programlisting> <programlisting>
typedef struct CustomPath typedef struct CustomPath
@ -68,22 +68,22 @@ typedef struct CustomPath
</para> </para>
<para> <para>
<structfield>path</> must be initialized as for any other path, including <structfield>path</structfield> must be initialized as for any other path, including
the row-count estimate, start and total cost, and sort ordering provided the row-count estimate, start and total cost, and sort ordering provided
by this path. <structfield>flags</> is a bit mask, which should include by this path. <structfield>flags</structfield> is a bit mask, which should include
<literal>CUSTOMPATH_SUPPORT_BACKWARD_SCAN</> if the custom path can support <literal>CUSTOMPATH_SUPPORT_BACKWARD_SCAN</literal> if the custom path can support
a backward scan and <literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</> if it a backward scan and <literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</literal> if it
can support mark and restore. Both capabilities are optional. can support mark and restore. Both capabilities are optional.
An optional <structfield>custom_paths</> is a list of <structname>Path</> An optional <structfield>custom_paths</structfield> is a list of <structname>Path</structname>
nodes used by this custom-path node; these will be transformed into nodes used by this custom-path node; these will be transformed into
<structname>Plan</> nodes by planner. <structname>Plan</structname> nodes by planner.
<structfield>custom_private</> can be used to store the custom path's <structfield>custom_private</structfield> can be used to store the custom path's
private data. Private data should be stored in a form that can be handled private data. Private data should be stored in a form that can be handled
by <literal>nodeToString</>, so that debugging routines that attempt to by <literal>nodeToString</literal>, so that debugging routines that attempt to
print the custom path will work as designed. <structfield>methods</> must print the custom path will work as designed. <structfield>methods</structfield> must
point to a (usually statically allocated) object implementing the required point to a (usually statically allocated) object implementing the required
custom path methods, of which there is currently only one. The custom path methods, of which there is currently only one. The
<structfield>LibraryName</> and <structfield>SymbolName</> fields must also <structfield>LibraryName</structfield> and <structfield>SymbolName</structfield> fields must also
be initialized so that the dynamic loader can resolve them to locate the be initialized so that the dynamic loader can resolve them to locate the
method table. method table.
</para> </para>
@ -93,7 +93,7 @@ typedef struct CustomPath
relations, such a path must produce the same output as would normally be relations, such a path must produce the same output as would normally be
produced by the join it replaces. To do this, the join provider should produced by the join it replaces. To do this, the join provider should
set the following hook, and then within the hook function, set the following hook, and then within the hook function,
create <structname>CustomPath</> path(s) for the join relation. create <structname>CustomPath</structname> path(s) for the join relation.
<programlisting> <programlisting>
typedef void (*set_join_pathlist_hook_type) (PlannerInfo *root, typedef void (*set_join_pathlist_hook_type) (PlannerInfo *root,
RelOptInfo *joinrel, RelOptInfo *joinrel,
@ -122,7 +122,7 @@ Plan *(*PlanCustomPath) (PlannerInfo *root,
List *custom_plans); List *custom_plans);
</programlisting> </programlisting>
Convert a custom path to a finished plan. The return value will generally Convert a custom path to a finished plan. The return value will generally
be a <literal>CustomScan</> object, which the callback must allocate and be a <literal>CustomScan</literal> object, which the callback must allocate and
initialize. See <xref linkend="custom-scan-plan"> for more details. initialize. See <xref linkend="custom-scan-plan"> for more details.
</para> </para>
</sect2> </sect2>
@ -150,45 +150,45 @@ typedef struct CustomScan
</para> </para>
<para> <para>
<structfield>scan</> must be initialized as for any other scan, including <structfield>scan</structfield> must be initialized as for any other scan, including
estimated costs, target lists, qualifications, and so on. estimated costs, target lists, qualifications, and so on.
<structfield>flags</> is a bit mask with the same meaning as in <structfield>flags</structfield> is a bit mask with the same meaning as in
<structname>CustomPath</>. <structname>CustomPath</structname>.
<structfield>custom_plans</> can be used to store child <structfield>custom_plans</structfield> can be used to store child
<structname>Plan</> nodes. <structname>Plan</structname> nodes.
<structfield>custom_exprs</> should be used to <structfield>custom_exprs</structfield> should be used to
store expression trees that will need to be fixed up by store expression trees that will need to be fixed up by
<filename>setrefs.c</> and <filename>subselect.c</>, while <filename>setrefs.c</filename> and <filename>subselect.c</filename>, while
<structfield>custom_private</> should be used to store other private data <structfield>custom_private</structfield> should be used to store other private data
that is only used by the custom scan provider itself. that is only used by the custom scan provider itself.
<structfield>custom_scan_tlist</> can be NIL when scanning a base <structfield>custom_scan_tlist</structfield> can be NIL when scanning a base
relation, indicating that the custom scan returns scan tuples that match relation, indicating that the custom scan returns scan tuples that match
the base relation's row type. Otherwise it is a target list describing the base relation's row type. Otherwise it is a target list describing
the actual scan tuples. <structfield>custom_scan_tlist</> must be the actual scan tuples. <structfield>custom_scan_tlist</structfield> must be
provided for joins, and could be provided for scans if the custom scan provided for joins, and could be provided for scans if the custom scan
provider can compute some non-Var expressions. provider can compute some non-Var expressions.
<structfield>custom_relids</> is set by the core code to the set of <structfield>custom_relids</structfield> is set by the core code to the set of
relations (range table indexes) that this scan node handles; except when relations (range table indexes) that this scan node handles; except when
this scan is replacing a join, it will have only one member. this scan is replacing a join, it will have only one member.
<structfield>methods</> must point to a (usually statically allocated) <structfield>methods</structfield> must point to a (usually statically allocated)
object implementing the required custom scan methods, which are further object implementing the required custom scan methods, which are further
detailed below. detailed below.
</para> </para>
<para> <para>
When a <structname>CustomScan</> scans a single relation, When a <structname>CustomScan</structname> scans a single relation,
<structfield>scan.scanrelid</> must be the range table index of the table <structfield>scan.scanrelid</structfield> must be the range table index of the table
to be scanned. When it replaces a join, <structfield>scan.scanrelid</> to be scanned. When it replaces a join, <structfield>scan.scanrelid</structfield>
should be zero. should be zero.
</para> </para>
<para> <para>
Plan trees must be able to be duplicated using <function>copyObject</>, Plan trees must be able to be duplicated using <function>copyObject</function>,
so all the data stored within the <quote>custom</> fields must consist of so all the data stored within the <quote>custom</quote> fields must consist of
nodes that that function can handle. Furthermore, custom scan providers nodes that that function can handle. Furthermore, custom scan providers
cannot substitute a larger structure that embeds cannot substitute a larger structure that embeds
a <structname>CustomScan</> for the structure itself, as would be possible a <structname>CustomScan</structname> for the structure itself, as would be possible
for a <structname>CustomPath</> or <structname>CustomScanState</>. for a <structname>CustomPath</structname> or <structname>CustomScanState</structname>.
</para> </para>
<sect2 id="custom-scan-plan-callbacks"> <sect2 id="custom-scan-plan-callbacks">
@ -197,14 +197,14 @@ typedef struct CustomScan
<programlisting> <programlisting>
Node *(*CreateCustomScanState) (CustomScan *cscan); Node *(*CreateCustomScanState) (CustomScan *cscan);
</programlisting> </programlisting>
Allocate a <structname>CustomScanState</> for this Allocate a <structname>CustomScanState</structname> for this
<structname>CustomScan</>. The actual allocation will often be larger than <structname>CustomScan</structname>. The actual allocation will often be larger than
required for an ordinary <structname>CustomScanState</>, because many required for an ordinary <structname>CustomScanState</structname>, because many
providers will wish to embed that as the first field of a larger structure. providers will wish to embed that as the first field of a larger structure.
The value returned must have the node tag and <structfield>methods</> The value returned must have the node tag and <structfield>methods</structfield>
set appropriately, but other fields should be left as zeroes at this set appropriately, but other fields should be left as zeroes at this
stage; after <function>ExecInitCustomScan</> performs basic initialization, stage; after <function>ExecInitCustomScan</function> performs basic initialization,
the <function>BeginCustomScan</> callback will be invoked to give the the <function>BeginCustomScan</function> callback will be invoked to give the
custom scan provider a chance to do whatever else is needed. custom scan provider a chance to do whatever else is needed.
</para> </para>
</sect2> </sect2>
@ -214,8 +214,8 @@ Node *(*CreateCustomScanState) (CustomScan *cscan);
<title>Executing Custom Scans</title> <title>Executing Custom Scans</title>
<para> <para>
When a <structfield>CustomScan</> is executed, its execution state is When a <structfield>CustomScan</structfield> is executed, its execution state is
represented by a <structfield>CustomScanState</>, which is declared as represented by a <structfield>CustomScanState</structfield>, which is declared as
follows: follows:
<programlisting> <programlisting>
typedef struct CustomScanState typedef struct CustomScanState
@ -228,15 +228,15 @@ typedef struct CustomScanState
</para> </para>
<para> <para>
<structfield>ss</> is initialized as for any other scan state, <structfield>ss</structfield> is initialized as for any other scan state,
except that if the scan is for a join rather than a base relation, except that if the scan is for a join rather than a base relation,
<literal>ss.ss_currentRelation</> is left NULL. <literal>ss.ss_currentRelation</literal> is left NULL.
<structfield>flags</> is a bit mask with the same meaning as in <structfield>flags</structfield> is a bit mask with the same meaning as in
<structname>CustomPath</> and <structname>CustomScan</>. <structname>CustomPath</structname> and <structname>CustomScan</structname>.
<structfield>methods</> must point to a (usually statically allocated) <structfield>methods</structfield> must point to a (usually statically allocated)
object implementing the required custom scan state methods, which are object implementing the required custom scan state methods, which are
further detailed below. Typically, a <structname>CustomScanState</>, which further detailed below. Typically, a <structname>CustomScanState</structname>, which
need not support <function>copyObject</>, will actually be a larger need not support <function>copyObject</function>, will actually be a larger
structure embedding the above as its first member. structure embedding the above as its first member.
</para> </para>
@ -249,8 +249,8 @@ void (*BeginCustomScan) (CustomScanState *node,
EState *estate, EState *estate,
int eflags); int eflags);
</programlisting> </programlisting>
Complete initialization of the supplied <structname>CustomScanState</>. Complete initialization of the supplied <structname>CustomScanState</structname>.
Standard fields have been initialized by <function>ExecInitCustomScan</>, Standard fields have been initialized by <function>ExecInitCustomScan</function>,
but any private fields should be initialized here. but any private fields should be initialized here.
</para> </para>
@ -259,16 +259,16 @@ void (*BeginCustomScan) (CustomScanState *node,
TupleTableSlot *(*ExecCustomScan) (CustomScanState *node); TupleTableSlot *(*ExecCustomScan) (CustomScanState *node);
</programlisting> </programlisting>
Fetch the next scan tuple. If any tuples remain, it should fill Fetch the next scan tuple. If any tuples remain, it should fill
<literal>ps_ResultTupleSlot</> with the next tuple in the current scan <literal>ps_ResultTupleSlot</literal> with the next tuple in the current scan
direction, and then return the tuple slot. If not, direction, and then return the tuple slot. If not,
<literal>NULL</> or an empty slot should be returned. <literal>NULL</literal> or an empty slot should be returned.
</para> </para>
<para> <para>
<programlisting> <programlisting>
void (*EndCustomScan) (CustomScanState *node); void (*EndCustomScan) (CustomScanState *node);
</programlisting> </programlisting>
Clean up any private data associated with the <literal>CustomScanState</>. Clean up any private data associated with the <literal>CustomScanState</literal>.
This method is required, but it does not need to do anything if there is This method is required, but it does not need to do anything if there is
no associated data or it will be cleaned up automatically. no associated data or it will be cleaned up automatically.
</para> </para>
@ -286,9 +286,9 @@ void (*ReScanCustomScan) (CustomScanState *node);
void (*MarkPosCustomScan) (CustomScanState *node); void (*MarkPosCustomScan) (CustomScanState *node);
</programlisting> </programlisting>
Save the current scan position so that it can subsequently be restored Save the current scan position so that it can subsequently be restored
by the <function>RestrPosCustomScan</> callback. This callback is by the <function>RestrPosCustomScan</function> callback. This callback is
optional, and need only be supplied if the optional, and need only be supplied if the
<literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</> flag is set. <literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</literal> flag is set.
</para> </para>
<para> <para>
@ -296,9 +296,9 @@ void (*MarkPosCustomScan) (CustomScanState *node);
void (*RestrPosCustomScan) (CustomScanState *node); void (*RestrPosCustomScan) (CustomScanState *node);
</programlisting> </programlisting>
Restore the previous scan position as saved by the Restore the previous scan position as saved by the
<function>MarkPosCustomScan</> callback. This callback is optional, <function>MarkPosCustomScan</function> callback. This callback is optional,
and need only be supplied if the and need only be supplied if the
<literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</> flag is set. <literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</literal> flag is set.
</para> </para>
<para> <para>
@ -320,8 +320,8 @@ void (*InitializeDSMCustomScan) (CustomScanState *node,
void *coordinate); void *coordinate);
</programlisting> </programlisting>
Initialize the dynamic shared memory that will be required for parallel Initialize the dynamic shared memory that will be required for parallel
operation. <literal>coordinate</> points to a shared memory area of operation. <literal>coordinate</literal> points to a shared memory area of
size equal to the return value of <function>EstimateDSMCustomScan</>. size equal to the return value of <function>EstimateDSMCustomScan</function>.
This callback is optional, and need only be supplied if this custom This callback is optional, and need only be supplied if this custom
scan provider supports parallel execution. scan provider supports parallel execution.
</para> </para>
@ -337,9 +337,9 @@ void (*ReInitializeDSMCustomScan) (CustomScanState *node,
This callback is optional, and need only be supplied if this custom This callback is optional, and need only be supplied if this custom
scan provider supports parallel execution. scan provider supports parallel execution.
Recommended practice is that this callback reset only shared state, Recommended practice is that this callback reset only shared state,
while the <function>ReScanCustomScan</> callback resets only local while the <function>ReScanCustomScan</function> callback resets only local
state. Currently, this callback will be called state. Currently, this callback will be called
before <function>ReScanCustomScan</>, but it's best not to rely on before <function>ReScanCustomScan</function>, but it's best not to rely on
that ordering. that ordering.
</para> </para>
@ -350,7 +350,7 @@ void (*InitializeWorkerCustomScan) (CustomScanState *node,
void *coordinate); void *coordinate);
</programlisting> </programlisting>
Initialize a parallel worker's local state based on the shared state Initialize a parallel worker's local state based on the shared state
set up by the leader during <function>InitializeDSMCustomScan</>. set up by the leader during <function>InitializeDSMCustomScan</function>.
This callback is optional, and need only be supplied if this custom This callback is optional, and need only be supplied if this custom
scan provider supports parallel execution. scan provider supports parallel execution.
</para> </para>
@ -361,7 +361,7 @@ void (*ShutdownCustomScan) (CustomScanState *node);
</programlisting> </programlisting>
Release resources when it is anticipated the node will not be executed Release resources when it is anticipated the node will not be executed
to completion. This is not called in all cases; sometimes, to completion. This is not called in all cases; sometimes,
<literal>EndCustomScan</> may be called without this function having <literal>EndCustomScan</literal> may be called without this function having
been called first. Since the DSM segment used by parallel query is been called first. Since the DSM segment used by parallel query is
destroyed just after this callback is invoked, custom scan providers that destroyed just after this callback is invoked, custom scan providers that
wish to take some action before the DSM segment goes away should implement wish to take some action before the DSM segment goes away should implement
@ -374,9 +374,9 @@ void (*ExplainCustomScan) (CustomScanState *node,
List *ancestors, List *ancestors,
ExplainState *es); ExplainState *es);
</programlisting> </programlisting>
Output additional information for <command>EXPLAIN</> of a custom-scan Output additional information for <command>EXPLAIN</command> of a custom-scan
plan node. This callback is optional. Common data stored in the plan node. This callback is optional. Common data stored in the
<structname>ScanState</>, such as the target list and scan relation, will <structname>ScanState</structname>, such as the target list and scan relation, will
be shown even without this callback, but the callback allows the display be shown even without this callback, but the callback allows the display
of additional, private state. of additional, private state.
</para> </para>

File diff suppressed because it is too large Load Diff

View File

@ -37,18 +37,18 @@
<substeps> <substeps>
<step> <step>
<para> <para>
If the numeric token contains a colon (<literal>:</>), this is If the numeric token contains a colon (<literal>:</literal>), this is
a time string. Include all subsequent digits and colons. a time string. Include all subsequent digits and colons.
</para> </para>
</step> </step>
<step> <step>
<para> <para>
If the numeric token contains a dash (<literal>-</>), slash If the numeric token contains a dash (<literal>-</literal>), slash
(<literal>/</>), or two or more dots (<literal>.</>), this is (<literal>/</literal>), or two or more dots (<literal>.</literal>), this is
a date string which might have a text month. If a date token has a date string which might have a text month. If a date token has
already been seen, it is instead interpreted as a time zone already been seen, it is instead interpreted as a time zone
name (e.g., <literal>America/New_York</>). name (e.g., <literal>America/New_York</literal>).
</para> </para>
</step> </step>
@ -63,8 +63,8 @@
<step> <step>
<para> <para>
If the token starts with a plus (<literal>+</>) or minus If the token starts with a plus (<literal>+</literal>) or minus
(<literal>-</>), then it is either a numeric time zone or a special (<literal>-</literal>), then it is either a numeric time zone or a special
field. field.
</para> </para>
</step> </step>
@ -114,7 +114,7 @@
and if no other date fields have been previously read, then interpret and if no other date fields have been previously read, then interpret
as a <quote>concatenated date</quote> (e.g., as a <quote>concatenated date</quote> (e.g.,
<literal>19990118</literal> or <literal>990118</literal>). <literal>19990118</literal> or <literal>990118</literal>).
The interpretation is <literal>YYYYMMDD</> or <literal>YYMMDD</>. The interpretation is <literal>YYYYMMDD</literal> or <literal>YYMMDD</literal>.
</para> </para>
</step> </step>
@ -128,7 +128,7 @@
<step> <step>
<para> <para>
If four or six digits and a year has already been read, then If four or six digits and a year has already been read, then
interpret as a time (<literal>HHMM</> or <literal>HHMMSS</>). interpret as a time (<literal>HHMM</literal> or <literal>HHMMSS</literal>).
</para> </para>
</step> </step>
@ -143,7 +143,7 @@
<step> <step>
<para> <para>
Otherwise the date field ordering is assumed to follow the Otherwise the date field ordering is assumed to follow the
<varname>DateStyle</> setting: mm-dd-yy, dd-mm-yy, or yy-mm-dd. <varname>DateStyle</varname> setting: mm-dd-yy, dd-mm-yy, or yy-mm-dd.
Throw an error if a month or day field is found to be out of range. Throw an error if a month or day field is found to be out of range.
</para> </para>
</step> </step>
@ -167,7 +167,7 @@
<tip> <tip>
<para> <para>
Gregorian years AD 1-99 can be entered by using 4 digits with leading Gregorian years AD 1-99 can be entered by using 4 digits with leading
zeros (e.g., <literal>0099</> is AD 99). zeros (e.g., <literal>0099</literal> is AD 99).
</para> </para>
</tip> </tip>
</para> </para>
@ -317,7 +317,7 @@
<entry>Ignored</entry> <entry>Ignored</entry>
</row> </row>
<row> <row>
<entry><literal>JULIAN</>, <literal>JD</>, <literal>J</></entry> <entry><literal>JULIAN</literal>, <literal>JD</literal>, <literal>J</literal></entry>
<entry>Next field is Julian Date</entry> <entry>Next field is Julian Date</entry>
</row> </row>
<row> <row>
@ -354,23 +354,23 @@
can be altered by any database user, the possible values for it can be altered by any database user, the possible values for it
are under the control of the database administrator &mdash; they are under the control of the database administrator &mdash; they
are in fact names of configuration files stored in are in fact names of configuration files stored in
<filename>.../share/timezonesets/</> of the installation directory. <filename>.../share/timezonesets/</filename> of the installation directory.
By adding or altering files in that directory, the administrator By adding or altering files in that directory, the administrator
can set local policy for timezone abbreviations. can set local policy for timezone abbreviations.
</para> </para>
<para> <para>
<varname>timezone_abbreviations</> can be set to any file name <varname>timezone_abbreviations</varname> can be set to any file name
found in <filename>.../share/timezonesets/</>, if the file's name found in <filename>.../share/timezonesets/</filename>, if the file's name
is entirely alphabetic. (The prohibition against non-alphabetic is entirely alphabetic. (The prohibition against non-alphabetic
characters in <varname>timezone_abbreviations</> prevents reading characters in <varname>timezone_abbreviations</varname> prevents reading
files outside the intended directory, as well as reading editor files outside the intended directory, as well as reading editor
backup files and other extraneous files.) backup files and other extraneous files.)
</para> </para>
<para> <para>
A timezone abbreviation file can contain blank lines and comments A timezone abbreviation file can contain blank lines and comments
beginning with <literal>#</>. Non-comment lines must have one of beginning with <literal>#</literal>. Non-comment lines must have one of
these formats: these formats:
<synopsis> <synopsis>
@ -388,12 +388,12 @@
the equivalent offset in seconds from UTC, positive being east from the equivalent offset in seconds from UTC, positive being east from
Greenwich and negative being west. For example, -18000 would be five Greenwich and negative being west. For example, -18000 would be five
hours west of Greenwich, or North American east coast standard time. hours west of Greenwich, or North American east coast standard time.
<literal>D</> indicates that the zone name represents local <literal>D</literal> indicates that the zone name represents local
daylight-savings time rather than standard time. daylight-savings time rather than standard time.
</para> </para>
<para> <para>
Alternatively, a <replaceable>time_zone_name</> can be given, referencing Alternatively, a <replaceable>time_zone_name</replaceable> can be given, referencing
a zone name defined in the IANA timezone database. The zone's definition a zone name defined in the IANA timezone database. The zone's definition
is consulted to see whether the abbreviation is or has been in use in is consulted to see whether the abbreviation is or has been in use in
that zone, and if so, the appropriate meaning is used &mdash; that is, that zone, and if so, the appropriate meaning is used &mdash; that is,
@ -417,34 +417,34 @@
</tip> </tip>
<para> <para>
The <literal>@INCLUDE</> syntax allows inclusion of another file in the The <literal>@INCLUDE</literal> syntax allows inclusion of another file in the
<filename>.../share/timezonesets/</> directory. Inclusion can be nested, <filename>.../share/timezonesets/</filename> directory. Inclusion can be nested,
to a limited depth. to a limited depth.
</para> </para>
<para> <para>
The <literal>@OVERRIDE</> syntax indicates that subsequent entries in the The <literal>@OVERRIDE</literal> syntax indicates that subsequent entries in the
file can override previous entries (typically, entries obtained from file can override previous entries (typically, entries obtained from
included files). Without this, conflicting definitions of the same included files). Without this, conflicting definitions of the same
timezone abbreviation are considered an error. timezone abbreviation are considered an error.
</para> </para>
<para> <para>
In an unmodified installation, the file <filename>Default</> contains In an unmodified installation, the file <filename>Default</filename> contains
all the non-conflicting time zone abbreviations for most of the world. all the non-conflicting time zone abbreviations for most of the world.
Additional files <filename>Australia</> and <filename>India</> are Additional files <filename>Australia</filename> and <filename>India</filename> are
provided for those regions: these files first include the provided for those regions: these files first include the
<literal>Default</> file and then add or modify abbreviations as needed. <literal>Default</literal> file and then add or modify abbreviations as needed.
</para> </para>
<para> <para>
For reference purposes, a standard installation also contains files For reference purposes, a standard installation also contains files
<filename>Africa.txt</>, <filename>America.txt</>, etc, containing <filename>Africa.txt</filename>, <filename>America.txt</filename>, etc, containing
information about every time zone abbreviation known to be in use information about every time zone abbreviation known to be in use
according to the IANA timezone database. The zone name according to the IANA timezone database. The zone name
definitions found in these files can be copied and pasted into a custom definitions found in these files can be copied and pasted into a custom
configuration file as needed. Note that these files cannot be directly configuration file as needed. Note that these files cannot be directly
referenced as <varname>timezone_abbreviations</> settings, because of referenced as <varname>timezone_abbreviations</varname> settings, because of
the dot embedded in their names. the dot embedded in their names.
</para> </para>
@ -460,16 +460,16 @@
<para> <para>
Time zone abbreviations defined in the configuration file override Time zone abbreviations defined in the configuration file override
non-timezone meanings built into <productname>PostgreSQL</productname>. non-timezone meanings built into <productname>PostgreSQL</productname>.
For example, the <filename>Australia</> configuration file defines For example, the <filename>Australia</filename> configuration file defines
<literal>SAT</> (for South Australian Standard Time). When this <literal>SAT</literal> (for South Australian Standard Time). When this
file is active, <literal>SAT</> will not be recognized as an abbreviation file is active, <literal>SAT</literal> will not be recognized as an abbreviation
for Saturday. for Saturday.
</para> </para>
</caution> </caution>
<caution> <caution>
<para> <para>
If you modify files in <filename>.../share/timezonesets/</>, If you modify files in <filename>.../share/timezonesets/</filename>,
it is up to you to make backups &mdash; a normal database dump it is up to you to make backups &mdash; a normal database dump
will not include this directory. will not include this directory.
</para> </para>
@ -492,10 +492,10 @@
<quote>datetime literal</quote>, the <quote>datetime <quote>datetime literal</quote>, the <quote>datetime
values</quote> are constrained by the natural rules for dates and values</quote> are constrained by the natural rules for dates and
times according to the Gregorian calendar</quote>. times according to the Gregorian calendar</quote>.
<productname>PostgreSQL</> follows the SQL <productname>PostgreSQL</productname> follows the SQL
standard's lead by counting dates exclusively in the Gregorian standard's lead by counting dates exclusively in the Gregorian
calendar, even for years before that calendar was in use. calendar, even for years before that calendar was in use.
This rule is known as the <firstterm>proleptic Gregorian calendar</>. This rule is known as the <firstterm>proleptic Gregorian calendar</firstterm>.
</para> </para>
<para> <para>
@ -569,7 +569,7 @@ $ <userinput>cal 9 1752</userinput>
dominions, not other places. dominions, not other places.
Since it would be difficult and confusing to try to track the actual Since it would be difficult and confusing to try to track the actual
calendars that were in use in various places at various times, calendars that were in use in various places at various times,
<productname>PostgreSQL</> does not try, but rather follows the Gregorian <productname>PostgreSQL</productname> does not try, but rather follows the Gregorian
calendar rules for all dates, even though this method is not historically calendar rules for all dates, even though this method is not historically
accurate. accurate.
</para> </para>
@ -597,7 +597,7 @@ $ <userinput>cal 9 1752</userinput>
and probably takes its name from Scaliger's father, and probably takes its name from Scaliger's father,
the Italian scholar Julius Caesar Scaliger (1484-1558). the Italian scholar Julius Caesar Scaliger (1484-1558).
In the Julian Date system, each day has a sequential number, starting In the Julian Date system, each day has a sequential number, starting
from JD 0 (which is sometimes called <emphasis>the</> Julian Date). from JD 0 (which is sometimes called <emphasis>the</emphasis> Julian Date).
JD 0 corresponds to 1 January 4713 BC in the Julian calendar, or JD 0 corresponds to 1 January 4713 BC in the Julian calendar, or
24 November 4714 BC in the Gregorian calendar. Julian Date counting 24 November 4714 BC in the Gregorian calendar. Julian Date counting
is most often used by astronomers for labeling their nightly observations, is most often used by astronomers for labeling their nightly observations,
@ -607,10 +607,10 @@ $ <userinput>cal 9 1752</userinput>
</para> </para>
<para> <para>
Although <productname>PostgreSQL</> supports Julian Date notation for Although <productname>PostgreSQL</productname> supports Julian Date notation for
input and output of dates (and also uses Julian dates for some internal input and output of dates (and also uses Julian dates for some internal
datetime calculations), it does not observe the nicety of having dates datetime calculations), it does not observe the nicety of having dates
run from noon to noon. <productname>PostgreSQL</> treats a Julian Date run from noon to noon. <productname>PostgreSQL</productname> treats a Julian Date
as running from midnight to midnight. as running from midnight to midnight.
</para> </para>

View File

@ -8,8 +8,8 @@
</indexterm> </indexterm>
<para> <para>
<filename>dblink</> is a module that supports connections to <filename>dblink</filename> is a module that supports connections to
other <productname>PostgreSQL</> databases from within a database other <productname>PostgreSQL</productname> databases from within a database
session. session.
</para> </para>
@ -44,9 +44,9 @@ dblink_connect(text connname, text connstr) returns text
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink_connect()</> establishes a connection to a remote <function>dblink_connect()</function> establishes a connection to a remote
<productname>PostgreSQL</> database. The server and database to <productname>PostgreSQL</productname> database. The server and database to
be contacted are identified through a standard <application>libpq</> be contacted are identified through a standard <application>libpq</application>
connection string. Optionally, a name can be assigned to the connection string. Optionally, a name can be assigned to the
connection. Multiple named connections can be open at once, but connection. Multiple named connections can be open at once, but
only one unnamed connection is permitted at a time. The connection only one unnamed connection is permitted at a time. The connection
@ -81,9 +81,9 @@ dblink_connect(text connname, text connstr) returns text
<varlistentry> <varlistentry>
<term><parameter>connstr</parameter></term> <term><parameter>connstr</parameter></term>
<listitem> <listitem>
<para><application>libpq</>-style connection info string, for example <para><application>libpq</application>-style connection info string, for example
<literal>hostaddr=127.0.0.1 port=5432 dbname=mydb user=postgres <literal>hostaddr=127.0.0.1 port=5432 dbname=mydb user=postgres
password=mypasswd</>. password=mypasswd</literal>.
For details see <xref linkend="libpq-connstring">. For details see <xref linkend="libpq-connstring">.
Alternatively, the name of a foreign server. Alternatively, the name of a foreign server.
</para> </para>
@ -96,7 +96,7 @@ dblink_connect(text connname, text connstr) returns text
<title>Return Value</title> <title>Return Value</title>
<para> <para>
Returns status, which is always <literal>OK</> (since any error Returns status, which is always <literal>OK</literal> (since any error
causes the function to throw an error instead of returning). causes the function to throw an error instead of returning).
</para> </para>
</refsect1> </refsect1>
@ -105,15 +105,15 @@ dblink_connect(text connname, text connstr) returns text
<title>Notes</title> <title>Notes</title>
<para> <para>
Only superusers may use <function>dblink_connect</> to create Only superusers may use <function>dblink_connect</function> to create
non-password-authenticated connections. If non-superusers need this non-password-authenticated connections. If non-superusers need this
capability, use <function>dblink_connect_u</> instead. capability, use <function>dblink_connect_u</function> instead.
</para> </para>
<para> <para>
It is unwise to choose connection names that contain equal signs, It is unwise to choose connection names that contain equal signs,
as this opens a risk of confusion with connection info strings as this opens a risk of confusion with connection info strings
in other <filename>dblink</> functions. in other <filename>dblink</filename> functions.
</para> </para>
</refsect1> </refsect1>
@ -208,8 +208,8 @@ dblink_connect_u(text connname, text connstr) returns text
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink_connect_u()</> is identical to <function>dblink_connect_u()</function> is identical to
<function>dblink_connect()</>, except that it will allow non-superusers <function>dblink_connect()</function>, except that it will allow non-superusers
to connect using any authentication method. to connect using any authentication method.
</para> </para>
@ -217,24 +217,24 @@ dblink_connect_u(text connname, text connstr) returns text
If the remote server selects an authentication method that does not If the remote server selects an authentication method that does not
involve a password, then impersonation and subsequent escalation of involve a password, then impersonation and subsequent escalation of
privileges can occur, because the session will appear to have privileges can occur, because the session will appear to have
originated from the user as which the local <productname>PostgreSQL</> originated from the user as which the local <productname>PostgreSQL</productname>
server runs. Also, even if the remote server does demand a password, server runs. Also, even if the remote server does demand a password,
it is possible for the password to be supplied from the server it is possible for the password to be supplied from the server
environment, such as a <filename>~/.pgpass</> file belonging to the environment, such as a <filename>~/.pgpass</filename> file belonging to the
server's user. This opens not only a risk of impersonation, but the server's user. This opens not only a risk of impersonation, but the
possibility of exposing a password to an untrustworthy remote server. possibility of exposing a password to an untrustworthy remote server.
Therefore, <function>dblink_connect_u()</> is initially Therefore, <function>dblink_connect_u()</function> is initially
installed with all privileges revoked from <literal>PUBLIC</>, installed with all privileges revoked from <literal>PUBLIC</literal>,
making it un-callable except by superusers. In some situations making it un-callable except by superusers. In some situations
it may be appropriate to grant <literal>EXECUTE</> permission for it may be appropriate to grant <literal>EXECUTE</literal> permission for
<function>dblink_connect_u()</> to specific users who are considered <function>dblink_connect_u()</function> to specific users who are considered
trustworthy, but this should be done with care. It is also recommended trustworthy, but this should be done with care. It is also recommended
that any <filename>~/.pgpass</> file belonging to the server's user that any <filename>~/.pgpass</filename> file belonging to the server's user
<emphasis>not</> contain any records specifying a wildcard host name. <emphasis>not</emphasis> contain any records specifying a wildcard host name.
</para> </para>
<para> <para>
For further details see <function>dblink_connect()</>. For further details see <function>dblink_connect()</function>.
</para> </para>
</refsect1> </refsect1>
</refentry> </refentry>
@ -265,8 +265,8 @@ dblink_disconnect(text connname) returns text
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink_disconnect()</> closes a connection previously opened <function>dblink_disconnect()</function> closes a connection previously opened
by <function>dblink_connect()</>. The form with no arguments closes by <function>dblink_connect()</function>. The form with no arguments closes
an unnamed connection. an unnamed connection.
</para> </para>
</refsect1> </refsect1>
@ -290,7 +290,7 @@ dblink_disconnect(text connname) returns text
<title>Return Value</title> <title>Return Value</title>
<para> <para>
Returns status, which is always <literal>OK</> (since any error Returns status, which is always <literal>OK</literal> (since any error
causes the function to throw an error instead of returning). causes the function to throw an error instead of returning).
</para> </para>
</refsect1> </refsect1>
@ -341,15 +341,15 @@ dblink(text sql [, bool fail_on_error]) returns setof record
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink</> executes a query (usually a <command>SELECT</>, <function>dblink</function> executes a query (usually a <command>SELECT</command>,
but it can be any SQL statement that returns rows) in a remote database. but it can be any SQL statement that returns rows) in a remote database.
</para> </para>
<para> <para>
When two <type>text</> arguments are given, the first one is first When two <type>text</type> arguments are given, the first one is first
looked up as a persistent connection's name; if found, the command looked up as a persistent connection's name; if found, the command
is executed on that connection. If not found, the first argument is executed on that connection. If not found, the first argument
is treated as a connection info string as for <function>dblink_connect</>, is treated as a connection info string as for <function>dblink_connect</function>,
and the indicated connection is made just for the duration of this command. and the indicated connection is made just for the duration of this command.
</para> </para>
</refsect1> </refsect1>
@ -373,7 +373,7 @@ dblink(text sql [, bool fail_on_error]) returns setof record
<listitem> <listitem>
<para> <para>
A connection info string, as previously described for A connection info string, as previously described for
<function>dblink_connect</>. <function>dblink_connect</function>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -383,7 +383,7 @@ dblink(text sql [, bool fail_on_error]) returns setof record
<listitem> <listitem>
<para> <para>
The SQL query that you wish to execute in the remote database, The SQL query that you wish to execute in the remote database,
for example <literal>select * from foo</>. for example <literal>select * from foo</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -407,11 +407,11 @@ dblink(text sql [, bool fail_on_error]) returns setof record
<para> <para>
The function returns the row(s) produced by the query. Since The function returns the row(s) produced by the query. Since
<function>dblink</> can be used with any query, it is declared <function>dblink</function> can be used with any query, it is declared
to return <type>record</>, rather than specifying any particular to return <type>record</type>, rather than specifying any particular
set of columns. This means that you must specify the expected set of columns. This means that you must specify the expected
set of columns in the calling query &mdash; otherwise set of columns in the calling query &mdash; otherwise
<productname>PostgreSQL</> would not know what to expect. <productname>PostgreSQL</productname> would not know what to expect.
Here is an example: Here is an example:
<programlisting> <programlisting>
@ -421,20 +421,20 @@ SELECT *
WHERE proname LIKE 'bytea%'; WHERE proname LIKE 'bytea%';
</programlisting> </programlisting>
The <quote>alias</> part of the <literal>FROM</> clause must The <quote>alias</quote> part of the <literal>FROM</literal> clause must
specify the column names and types that the function will return. specify the column names and types that the function will return.
(Specifying column names in an alias is actually standard SQL (Specifying column names in an alias is actually standard SQL
syntax, but specifying column types is a <productname>PostgreSQL</> syntax, but specifying column types is a <productname>PostgreSQL</productname>
extension.) This allows the system to understand what extension.) This allows the system to understand what
<literal>*</> should expand to, and what <structname>proname</> <literal>*</literal> should expand to, and what <structname>proname</structname>
in the <literal>WHERE</> clause refers to, in advance of trying in the <literal>WHERE</literal> clause refers to, in advance of trying
to execute the function. At run time, an error will be thrown to execute the function. At run time, an error will be thrown
if the actual query result from the remote database does not if the actual query result from the remote database does not
have the same number of columns shown in the <literal>FROM</> clause. have the same number of columns shown in the <literal>FROM</literal> clause.
The column names need not match, however, and <function>dblink</> The column names need not match, however, and <function>dblink</function>
does not insist on exact type matches either. It will succeed does not insist on exact type matches either. It will succeed
so long as the returned data strings are valid input for the so long as the returned data strings are valid input for the
column type declared in the <literal>FROM</> clause. column type declared in the <literal>FROM</literal> clause.
</para> </para>
</refsect1> </refsect1>
@ -442,7 +442,7 @@ SELECT *
<title>Notes</title> <title>Notes</title>
<para> <para>
A convenient way to use <function>dblink</> with predetermined A convenient way to use <function>dblink</function> with predetermined
queries is to create a view. queries is to create a view.
This allows the column type information to be buried in the view, This allows the column type information to be buried in the view,
instead of having to spell it out in every query. For example, instead of having to spell it out in every query. For example,
@ -559,15 +559,15 @@ dblink_exec(text sql [, bool fail_on_error]) returns text
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink_exec</> executes a command (that is, any SQL statement <function>dblink_exec</function> executes a command (that is, any SQL statement
that doesn't return rows) in a remote database. that doesn't return rows) in a remote database.
</para> </para>
<para> <para>
When two <type>text</> arguments are given, the first one is first When two <type>text</type> arguments are given, the first one is first
looked up as a persistent connection's name; if found, the command looked up as a persistent connection's name; if found, the command
is executed on that connection. If not found, the first argument is executed on that connection. If not found, the first argument
is treated as a connection info string as for <function>dblink_connect</>, is treated as a connection info string as for <function>dblink_connect</function>,
and the indicated connection is made just for the duration of this command. and the indicated connection is made just for the duration of this command.
</para> </para>
</refsect1> </refsect1>
@ -591,7 +591,7 @@ dblink_exec(text sql [, bool fail_on_error]) returns text
<listitem> <listitem>
<para> <para>
A connection info string, as previously described for A connection info string, as previously described for
<function>dblink_connect</>. <function>dblink_connect</function>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -602,7 +602,7 @@ dblink_exec(text sql [, bool fail_on_error]) returns text
<para> <para>
The SQL command that you wish to execute in the remote database, The SQL command that you wish to execute in the remote database,
for example for example
<literal>insert into foo values(0,'a','{"a0","b0","c0"}')</>. <literal>insert into foo values(0,'a','{"a0","b0","c0"}')</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -614,7 +614,7 @@ dblink_exec(text sql [, bool fail_on_error]) returns text
If true (the default when omitted) then an error thrown on the If true (the default when omitted) then an error thrown on the
remote side of the connection causes an error to also be thrown remote side of the connection causes an error to also be thrown
locally. If false, the remote error is locally reported as a NOTICE, locally. If false, the remote error is locally reported as a NOTICE,
and the function's return value is set to <literal>ERROR</>. and the function's return value is set to <literal>ERROR</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -625,7 +625,7 @@ dblink_exec(text sql [, bool fail_on_error]) returns text
<title>Return Value</title> <title>Return Value</title>
<para> <para>
Returns status, either the command's status string or <literal>ERROR</>. Returns status, either the command's status string or <literal>ERROR</literal>.
</para> </para>
</refsect1> </refsect1>
@ -695,9 +695,9 @@ dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) ret
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink_open()</> opens a cursor in a remote database. <function>dblink_open()</function> opens a cursor in a remote database.
The cursor can subsequently be manipulated with The cursor can subsequently be manipulated with
<function>dblink_fetch()</> and <function>dblink_close()</>. <function>dblink_fetch()</function> and <function>dblink_close()</function>.
</para> </para>
</refsect1> </refsect1>
@ -728,8 +728,8 @@ dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) ret
<term><parameter>sql</parameter></term> <term><parameter>sql</parameter></term>
<listitem> <listitem>
<para> <para>
The <command>SELECT</> statement that you wish to execute in the remote The <command>SELECT</command> statement that you wish to execute in the remote
database, for example <literal>select * from pg_class</>. database, for example <literal>select * from pg_class</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -741,7 +741,7 @@ dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) ret
If true (the default when omitted) then an error thrown on the If true (the default when omitted) then an error thrown on the
remote side of the connection causes an error to also be thrown remote side of the connection causes an error to also be thrown
locally. If false, the remote error is locally reported as a NOTICE, locally. If false, the remote error is locally reported as a NOTICE,
and the function's return value is set to <literal>ERROR</>. and the function's return value is set to <literal>ERROR</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -752,7 +752,7 @@ dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) ret
<title>Return Value</title> <title>Return Value</title>
<para> <para>
Returns status, either <literal>OK</> or <literal>ERROR</>. Returns status, either <literal>OK</literal> or <literal>ERROR</literal>.
</para> </para>
</refsect1> </refsect1>
@ -761,16 +761,16 @@ dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) ret
<para> <para>
Since a cursor can only persist within a transaction, Since a cursor can only persist within a transaction,
<function>dblink_open</> starts an explicit transaction block <function>dblink_open</function> starts an explicit transaction block
(<command>BEGIN</>) on the remote side, if the remote side was (<command>BEGIN</command>) on the remote side, if the remote side was
not already within a transaction. This transaction will be not already within a transaction. This transaction will be
closed again when the matching <function>dblink_close</> is closed again when the matching <function>dblink_close</function> is
executed. Note that if executed. Note that if
you use <function>dblink_exec</> to change data between you use <function>dblink_exec</function> to change data between
<function>dblink_open</> and <function>dblink_close</>, <function>dblink_open</function> and <function>dblink_close</function>,
and then an error occurs or you use <function>dblink_disconnect</> before and then an error occurs or you use <function>dblink_disconnect</function> before
<function>dblink_close</>, your change <emphasis>will be <function>dblink_close</function>, your change <emphasis>will be
lost</> because the transaction will be aborted. lost</emphasis> because the transaction will be aborted.
</para> </para>
</refsect1> </refsect1>
@ -819,8 +819,8 @@ dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error])
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink_fetch</> fetches rows from a cursor previously <function>dblink_fetch</function> fetches rows from a cursor previously
established by <function>dblink_open</>. established by <function>dblink_open</function>.
</para> </para>
</refsect1> </refsect1>
@ -851,7 +851,7 @@ dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error])
<term><parameter>howmany</parameter></term> <term><parameter>howmany</parameter></term>
<listitem> <listitem>
<para> <para>
The maximum number of rows to retrieve. The next <parameter>howmany</> The maximum number of rows to retrieve. The next <parameter>howmany</parameter>
rows are fetched, starting at the current cursor position, moving rows are fetched, starting at the current cursor position, moving
forward. Once the cursor has reached its end, no more rows are produced. forward. Once the cursor has reached its end, no more rows are produced.
</para> </para>
@ -878,7 +878,7 @@ dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error])
<para> <para>
The function returns the row(s) fetched from the cursor. To use this The function returns the row(s) fetched from the cursor. To use this
function, you will need to specify the expected set of columns, function, you will need to specify the expected set of columns,
as previously discussed for <function>dblink</>. as previously discussed for <function>dblink</function>.
</para> </para>
</refsect1> </refsect1>
@ -887,11 +887,11 @@ dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error])
<para> <para>
On a mismatch between the number of return columns specified in the On a mismatch between the number of return columns specified in the
<literal>FROM</> clause, and the actual number of columns returned by the <literal>FROM</literal> clause, and the actual number of columns returned by the
remote cursor, an error will be thrown. In this event, the remote cursor remote cursor, an error will be thrown. In this event, the remote cursor
is still advanced by as many rows as it would have been if the error had is still advanced by as many rows as it would have been if the error had
not occurred. The same is true for any other error occurring in the local not occurred. The same is true for any other error occurring in the local
query after the remote <command>FETCH</> has been done. query after the remote <command>FETCH</command> has been done.
</para> </para>
</refsect1> </refsect1>
@ -972,8 +972,8 @@ dblink_close(text connname, text cursorname [, bool fail_on_error]) returns text
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink_close</> closes a cursor previously opened with <function>dblink_close</function> closes a cursor previously opened with
<function>dblink_open</>. <function>dblink_open</function>.
</para> </para>
</refsect1> </refsect1>
@ -1007,7 +1007,7 @@ dblink_close(text connname, text cursorname [, bool fail_on_error]) returns text
If true (the default when omitted) then an error thrown on the If true (the default when omitted) then an error thrown on the
remote side of the connection causes an error to also be thrown remote side of the connection causes an error to also be thrown
locally. If false, the remote error is locally reported as a NOTICE, locally. If false, the remote error is locally reported as a NOTICE,
and the function's return value is set to <literal>ERROR</>. and the function's return value is set to <literal>ERROR</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1018,7 +1018,7 @@ dblink_close(text connname, text cursorname [, bool fail_on_error]) returns text
<title>Return Value</title> <title>Return Value</title>
<para> <para>
Returns status, either <literal>OK</> or <literal>ERROR</>. Returns status, either <literal>OK</literal> or <literal>ERROR</literal>.
</para> </para>
</refsect1> </refsect1>
@ -1026,9 +1026,9 @@ dblink_close(text connname, text cursorname [, bool fail_on_error]) returns text
<title>Notes</title> <title>Notes</title>
<para> <para>
If <function>dblink_open</> started an explicit transaction block, If <function>dblink_open</function> started an explicit transaction block,
and this is the last remaining open cursor in this connection, and this is the last remaining open cursor in this connection,
<function>dblink_close</> will issue the matching <command>COMMIT</>. <function>dblink_close</function> will issue the matching <command>COMMIT</command>.
</para> </para>
</refsect1> </refsect1>
@ -1082,8 +1082,8 @@ dblink_get_connections() returns text[]
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink_get_connections</> returns an array of the names <function>dblink_get_connections</function> returns an array of the names
of all open named <filename>dblink</> connections. of all open named <filename>dblink</filename> connections.
</para> </para>
</refsect1> </refsect1>
@ -1127,7 +1127,7 @@ dblink_error_message(text connname) returns text
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink_error_message</> fetches the most recent remote <function>dblink_error_message</function> fetches the most recent remote
error message for a given connection. error message for a given connection.
</para> </para>
</refsect1> </refsect1>
@ -1190,7 +1190,7 @@ dblink_send_query(text connname, text sql) returns int
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink_send_query</> sends a query to be executed <function>dblink_send_query</function> sends a query to be executed
asynchronously, that is, without immediately waiting for the result. asynchronously, that is, without immediately waiting for the result.
There must not be an async query already in progress on the There must not be an async query already in progress on the
connection. connection.
@ -1198,10 +1198,10 @@ dblink_send_query(text connname, text sql) returns int
<para> <para>
After successfully dispatching an async query, completion status After successfully dispatching an async query, completion status
can be checked with <function>dblink_is_busy</>, and the results can be checked with <function>dblink_is_busy</function>, and the results
are ultimately collected with <function>dblink_get_result</>. are ultimately collected with <function>dblink_get_result</function>.
It is also possible to attempt to cancel an active async query It is also possible to attempt to cancel an active async query
using <function>dblink_cancel_query</>. using <function>dblink_cancel_query</function>.
</para> </para>
</refsect1> </refsect1>
@ -1223,7 +1223,7 @@ dblink_send_query(text connname, text sql) returns int
<listitem> <listitem>
<para> <para>
The SQL statement that you wish to execute in the remote database, The SQL statement that you wish to execute in the remote database,
for example <literal>select * from pg_class</>. for example <literal>select * from pg_class</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1272,7 +1272,7 @@ dblink_is_busy(text connname) returns int
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink_is_busy</> tests whether an async query is in progress. <function>dblink_is_busy</function> tests whether an async query is in progress.
</para> </para>
</refsect1> </refsect1>
@ -1297,7 +1297,7 @@ dblink_is_busy(text connname) returns int
<para> <para>
Returns 1 if connection is busy, 0 if it is not busy. Returns 1 if connection is busy, 0 if it is not busy.
If this function returns 0, it is guaranteed that If this function returns 0, it is guaranteed that
<function>dblink_get_result</> will not block. <function>dblink_get_result</function> will not block.
</para> </para>
</refsect1> </refsect1>
@ -1336,10 +1336,10 @@ dblink_get_notify(text connname) returns setof (notify_name text, be_pid int, ex
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink_get_notify</> retrieves notifications on either <function>dblink_get_notify</function> retrieves notifications on either
the unnamed connection, or on a named connection if specified. the unnamed connection, or on a named connection if specified.
To receive notifications via dblink, <function>LISTEN</> must To receive notifications via dblink, <function>LISTEN</function> must
first be issued, using <function>dblink_exec</>. first be issued, using <function>dblink_exec</function>.
For details see <xref linkend="sql-listen"> and <xref linkend="sql-notify">. For details see <xref linkend="sql-listen"> and <xref linkend="sql-notify">.
</para> </para>
@ -1417,9 +1417,9 @@ dblink_get_result(text connname [, bool fail_on_error]) returns setof record
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink_get_result</> collects the results of an <function>dblink_get_result</function> collects the results of an
asynchronous query previously sent with <function>dblink_send_query</>. asynchronous query previously sent with <function>dblink_send_query</function>.
If the query is not already completed, <function>dblink_get_result</> If the query is not already completed, <function>dblink_get_result</function>
will wait until it is. will wait until it is.
</para> </para>
</refsect1> </refsect1>
@ -1458,14 +1458,14 @@ dblink_get_result(text connname [, bool fail_on_error]) returns setof record
For an async query (that is, a SQL statement returning rows), For an async query (that is, a SQL statement returning rows),
the function returns the row(s) produced by the query. To use this the function returns the row(s) produced by the query. To use this
function, you will need to specify the expected set of columns, function, you will need to specify the expected set of columns,
as previously discussed for <function>dblink</>. as previously discussed for <function>dblink</function>.
</para> </para>
<para> <para>
For an async command (that is, a SQL statement not returning rows), For an async command (that is, a SQL statement not returning rows),
the function returns a single row with a single text column containing the function returns a single row with a single text column containing
the command's status string. It is still necessary to specify that the command's status string. It is still necessary to specify that
the result will have a single text column in the calling <literal>FROM</> the result will have a single text column in the calling <literal>FROM</literal>
clause. clause.
</para> </para>
</refsect1> </refsect1>
@ -1474,22 +1474,22 @@ dblink_get_result(text connname [, bool fail_on_error]) returns setof record
<title>Notes</title> <title>Notes</title>
<para> <para>
This function <emphasis>must</> be called if This function <emphasis>must</emphasis> be called if
<function>dblink_send_query</> returned 1. <function>dblink_send_query</function> returned 1.
It must be called once for each query It must be called once for each query
sent, and one additional time to obtain an empty set result, sent, and one additional time to obtain an empty set result,
before the connection can be used again. before the connection can be used again.
</para> </para>
<para> <para>
When using <function>dblink_send_query</> and When using <function>dblink_send_query</function> and
<function>dblink_get_result</>, <application>dblink</> fetches the entire <function>dblink_get_result</function>, <application>dblink</application> fetches the entire
remote query result before returning any of it to the local query remote query result before returning any of it to the local query
processor. If the query returns a large number of rows, this can result processor. If the query returns a large number of rows, this can result
in transient memory bloat in the local session. It may be better to open in transient memory bloat in the local session. It may be better to open
such a query as a cursor with <function>dblink_open</> and then fetch a such a query as a cursor with <function>dblink_open</function> and then fetch a
manageable number of rows at a time. Alternatively, use plain manageable number of rows at a time. Alternatively, use plain
<function>dblink()</>, which avoids memory bloat by spooling large result <function>dblink()</function>, which avoids memory bloat by spooling large result
sets to disk. sets to disk.
</para> </para>
</refsect1> </refsect1>
@ -1581,13 +1581,13 @@ dblink_cancel_query(text connname) returns text
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink_cancel_query</> attempts to cancel any query that <function>dblink_cancel_query</function> attempts to cancel any query that
is in progress on the named connection. Note that this is not is in progress on the named connection. Note that this is not
certain to succeed (since, for example, the remote query might certain to succeed (since, for example, the remote query might
already have finished). A cancel request simply improves the already have finished). A cancel request simply improves the
odds that the query will fail soon. You must still complete the odds that the query will fail soon. You must still complete the
normal query protocol, for example by calling normal query protocol, for example by calling
<function>dblink_get_result</>. <function>dblink_get_result</function>.
</para> </para>
</refsect1> </refsect1>
@ -1610,7 +1610,7 @@ dblink_cancel_query(text connname) returns text
<title>Return Value</title> <title>Return Value</title>
<para> <para>
Returns <literal>OK</> if the cancel request has been sent, or Returns <literal>OK</literal> if the cancel request has been sent, or
the text of an error message on failure. the text of an error message on failure.
</para> </para>
</refsect1> </refsect1>
@ -1651,7 +1651,7 @@ dblink_get_pkey(text relname) returns setof dblink_pkey_results
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink_get_pkey</> provides information about the primary <function>dblink_get_pkey</function> provides information about the primary
key of a relation in the local database. This is sometimes useful key of a relation in the local database. This is sometimes useful
in generating queries to be sent to remote databases. in generating queries to be sent to remote databases.
</para> </para>
@ -1665,10 +1665,10 @@ dblink_get_pkey(text relname) returns setof dblink_pkey_results
<term><parameter>relname</parameter></term> <term><parameter>relname</parameter></term>
<listitem> <listitem>
<para> <para>
Name of a local relation, for example <literal>foo</> or Name of a local relation, for example <literal>foo</literal> or
<literal>myschema.mytab</>. Include double quotes if the <literal>myschema.mytab</literal>. Include double quotes if the
name is mixed-case or contains special characters, for name is mixed-case or contains special characters, for
example <literal>"FooBar"</>; without quotes, the string example <literal>"FooBar"</literal>; without quotes, the string
will be folded to lower case. will be folded to lower case.
</para> </para>
</listitem> </listitem>
@ -1687,7 +1687,7 @@ dblink_get_pkey(text relname) returns setof dblink_pkey_results
CREATE TYPE dblink_pkey_results AS (position int, colname text); CREATE TYPE dblink_pkey_results AS (position int, colname text);
</programlisting> </programlisting>
The <literal>position</> column simply runs from 1 to <replaceable>N</>; The <literal>position</literal> column simply runs from 1 to <replaceable>N</replaceable>;
it is the number of the field within the primary key, not the number it is the number of the field within the primary key, not the number
within the table's columns. within the table's columns.
</para> </para>
@ -1748,10 +1748,10 @@ dblink_build_sql_insert(text relname,
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink_build_sql_insert</> can be useful in doing selective <function>dblink_build_sql_insert</function> can be useful in doing selective
replication of a local table to a remote database. It selects a row replication of a local table to a remote database. It selects a row
from the local table based on primary key, and then builds a SQL from the local table based on primary key, and then builds a SQL
<command>INSERT</> command that will duplicate that row, but with <command>INSERT</command> command that will duplicate that row, but with
the primary key values replaced by the values in the last argument. the primary key values replaced by the values in the last argument.
(To make an exact copy of the row, just specify the same values for (To make an exact copy of the row, just specify the same values for
the last two arguments.) the last two arguments.)
@ -1766,10 +1766,10 @@ dblink_build_sql_insert(text relname,
<term><parameter>relname</parameter></term> <term><parameter>relname</parameter></term>
<listitem> <listitem>
<para> <para>
Name of a local relation, for example <literal>foo</> or Name of a local relation, for example <literal>foo</literal> or
<literal>myschema.mytab</>. Include double quotes if the <literal>myschema.mytab</literal>. Include double quotes if the
name is mixed-case or contains special characters, for name is mixed-case or contains special characters, for
example <literal>"FooBar"</>; without quotes, the string example <literal>"FooBar"</literal>; without quotes, the string
will be folded to lower case. will be folded to lower case.
</para> </para>
</listitem> </listitem>
@ -1780,7 +1780,7 @@ dblink_build_sql_insert(text relname,
<listitem> <listitem>
<para> <para>
Attribute numbers (1-based) of the primary key fields, Attribute numbers (1-based) of the primary key fields,
for example <literal>1 2</>. for example <literal>1 2</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1811,7 +1811,7 @@ dblink_build_sql_insert(text relname,
<listitem> <listitem>
<para> <para>
Values of the primary key fields to be placed in the resulting Values of the primary key fields to be placed in the resulting
<command>INSERT</> command. Each field is represented in text form. <command>INSERT</command> command. Each field is represented in text form.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1828,10 +1828,10 @@ dblink_build_sql_insert(text relname,
<title>Notes</title> <title>Notes</title>
<para> <para>
As of <productname>PostgreSQL</> 9.0, the attribute numbers in As of <productname>PostgreSQL</productname> 9.0, the attribute numbers in
<parameter>primary_key_attnums</parameter> are interpreted as logical <parameter>primary_key_attnums</parameter> are interpreted as logical
column numbers, corresponding to the column's position in column numbers, corresponding to the column's position in
<literal>SELECT * FROM relname</>. Previous versions interpreted the <literal>SELECT * FROM relname</literal>. Previous versions interpreted the
numbers as physical column positions. There is a difference if any numbers as physical column positions. There is a difference if any
column(s) to the left of the indicated column have been dropped during column(s) to the left of the indicated column have been dropped during
the lifetime of the table. the lifetime of the table.
@ -1881,9 +1881,9 @@ dblink_build_sql_delete(text relname,
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink_build_sql_delete</> can be useful in doing selective <function>dblink_build_sql_delete</function> can be useful in doing selective
replication of a local table to a remote database. It builds a SQL replication of a local table to a remote database. It builds a SQL
<command>DELETE</> command that will delete the row with the given <command>DELETE</command> command that will delete the row with the given
primary key values. primary key values.
</para> </para>
</refsect1> </refsect1>
@ -1896,10 +1896,10 @@ dblink_build_sql_delete(text relname,
<term><parameter>relname</parameter></term> <term><parameter>relname</parameter></term>
<listitem> <listitem>
<para> <para>
Name of a local relation, for example <literal>foo</> or Name of a local relation, for example <literal>foo</literal> or
<literal>myschema.mytab</>. Include double quotes if the <literal>myschema.mytab</literal>. Include double quotes if the
name is mixed-case or contains special characters, for name is mixed-case or contains special characters, for
example <literal>"FooBar"</>; without quotes, the string example <literal>"FooBar"</literal>; without quotes, the string
will be folded to lower case. will be folded to lower case.
</para> </para>
</listitem> </listitem>
@ -1910,7 +1910,7 @@ dblink_build_sql_delete(text relname,
<listitem> <listitem>
<para> <para>
Attribute numbers (1-based) of the primary key fields, Attribute numbers (1-based) of the primary key fields,
for example <literal>1 2</>. for example <literal>1 2</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1929,7 +1929,7 @@ dblink_build_sql_delete(text relname,
<listitem> <listitem>
<para> <para>
Values of the primary key fields to be used in the resulting Values of the primary key fields to be used in the resulting
<command>DELETE</> command. Each field is represented in text form. <command>DELETE</command> command. Each field is represented in text form.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1946,10 +1946,10 @@ dblink_build_sql_delete(text relname,
<title>Notes</title> <title>Notes</title>
<para> <para>
As of <productname>PostgreSQL</> 9.0, the attribute numbers in As of <productname>PostgreSQL</productname> 9.0, the attribute numbers in
<parameter>primary_key_attnums</parameter> are interpreted as logical <parameter>primary_key_attnums</parameter> are interpreted as logical
column numbers, corresponding to the column's position in column numbers, corresponding to the column's position in
<literal>SELECT * FROM relname</>. Previous versions interpreted the <literal>SELECT * FROM relname</literal>. Previous versions interpreted the
numbers as physical column positions. There is a difference if any numbers as physical column positions. There is a difference if any
column(s) to the left of the indicated column have been dropped during column(s) to the left of the indicated column have been dropped during
the lifetime of the table. the lifetime of the table.
@ -2000,15 +2000,15 @@ dblink_build_sql_update(text relname,
<title>Description</title> <title>Description</title>
<para> <para>
<function>dblink_build_sql_update</> can be useful in doing selective <function>dblink_build_sql_update</function> can be useful in doing selective
replication of a local table to a remote database. It selects a row replication of a local table to a remote database. It selects a row
from the local table based on primary key, and then builds a SQL from the local table based on primary key, and then builds a SQL
<command>UPDATE</> command that will duplicate that row, but with <command>UPDATE</command> command that will duplicate that row, but with
the primary key values replaced by the values in the last argument. the primary key values replaced by the values in the last argument.
(To make an exact copy of the row, just specify the same values for (To make an exact copy of the row, just specify the same values for
the last two arguments.) The <command>UPDATE</> command always assigns the last two arguments.) The <command>UPDATE</command> command always assigns
all fields of the row &mdash; the main difference between this and all fields of the row &mdash; the main difference between this and
<function>dblink_build_sql_insert</> is that it's assumed that <function>dblink_build_sql_insert</function> is that it's assumed that
the target row already exists in the remote table. the target row already exists in the remote table.
</para> </para>
</refsect1> </refsect1>
@ -2021,10 +2021,10 @@ dblink_build_sql_update(text relname,
<term><parameter>relname</parameter></term> <term><parameter>relname</parameter></term>
<listitem> <listitem>
<para> <para>
Name of a local relation, for example <literal>foo</> or Name of a local relation, for example <literal>foo</literal> or
<literal>myschema.mytab</>. Include double quotes if the <literal>myschema.mytab</literal>. Include double quotes if the
name is mixed-case or contains special characters, for name is mixed-case or contains special characters, for
example <literal>"FooBar"</>; without quotes, the string example <literal>"FooBar"</literal>; without quotes, the string
will be folded to lower case. will be folded to lower case.
</para> </para>
</listitem> </listitem>
@ -2035,7 +2035,7 @@ dblink_build_sql_update(text relname,
<listitem> <listitem>
<para> <para>
Attribute numbers (1-based) of the primary key fields, Attribute numbers (1-based) of the primary key fields,
for example <literal>1 2</>. for example <literal>1 2</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -2066,7 +2066,7 @@ dblink_build_sql_update(text relname,
<listitem> <listitem>
<para> <para>
Values of the primary key fields to be placed in the resulting Values of the primary key fields to be placed in the resulting
<command>UPDATE</> command. Each field is represented in text form. <command>UPDATE</command> command. Each field is represented in text form.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -2083,10 +2083,10 @@ dblink_build_sql_update(text relname,
<title>Notes</title> <title>Notes</title>
<para> <para>
As of <productname>PostgreSQL</> 9.0, the attribute numbers in As of <productname>PostgreSQL</productname> 9.0, the attribute numbers in
<parameter>primary_key_attnums</parameter> are interpreted as logical <parameter>primary_key_attnums</parameter> are interpreted as logical
column numbers, corresponding to the column's position in column numbers, corresponding to the column's position in
<literal>SELECT * FROM relname</>. Previous versions interpreted the <literal>SELECT * FROM relname</literal>. Previous versions interpreted the
numbers as physical column positions. There is a difference if any numbers as physical column positions. There is a difference if any
column(s) to the left of the indicated column have been dropped during column(s) to the left of the indicated column have been dropped during
the lifetime of the table. the lifetime of the table.

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@
C, they must be compiled and linked in a special way to produce a C, they must be compiled and linked in a special way to produce a
file that can be dynamically loaded by the server. To be precise, a file that can be dynamically loaded by the server. To be precise, a
<firstterm>shared library</firstterm> needs to be <firstterm>shared library</firstterm> needs to be
created.<indexterm><primary>shared library</></indexterm> created.<indexterm><primary>shared library</primary></indexterm>
</para> </para>
@ -30,7 +30,7 @@
executables: first the source files are compiled into object files, executables: first the source files are compiled into object files,
then the object files are linked together. The object files need to then the object files are linked together. The object files need to
be created as <firstterm>position-independent code</firstterm> be created as <firstterm>position-independent code</firstterm>
(<acronym>PIC</acronym>),<indexterm><primary>PIC</></> which (<acronym>PIC</acronym>),<indexterm><primary>PIC</primary></indexterm> which
conceptually means that they can be placed at an arbitrary location conceptually means that they can be placed at an arbitrary location
in memory when they are loaded by the executable. (Object files in memory when they are loaded by the executable. (Object files
intended for executables are usually not compiled that way.) The intended for executables are usually not compiled that way.) The
@ -57,8 +57,8 @@
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term> <term>
<systemitem class="osname">FreeBSD</> <systemitem class="osname">FreeBSD</systemitem>
<indexterm><primary>FreeBSD</><secondary>shared library</></> <indexterm><primary>FreeBSD</primary><secondary>shared library</secondary></indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
@ -70,15 +70,15 @@ gcc -fPIC -c foo.c
gcc -shared -o foo.so foo.o gcc -shared -o foo.so foo.o
</programlisting> </programlisting>
This is applicable as of version 3.0 of This is applicable as of version 3.0 of
<systemitem class="osname">FreeBSD</>. <systemitem class="osname">FreeBSD</systemitem>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<systemitem class="osname">HP-UX</> <systemitem class="osname">HP-UX</systemitem>
<indexterm><primary>HP-UX</><secondary>shared library</></> <indexterm><primary>HP-UX</primary><secondary>shared library</secondary></indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
@ -97,7 +97,7 @@ gcc -fPIC -c foo.c
<programlisting> <programlisting>
ld -b -o foo.sl foo.o ld -b -o foo.sl foo.o
</programlisting> </programlisting>
<systemitem class="osname">HP-UX</> uses the extension <systemitem class="osname">HP-UX</systemitem> uses the extension
<filename>.sl</filename> for shared libraries, unlike most other <filename>.sl</filename> for shared libraries, unlike most other
systems. systems.
</para> </para>
@ -106,8 +106,8 @@ ld -b -o foo.sl foo.o
<varlistentry> <varlistentry>
<term> <term>
<systemitem class="osname">Linux</> <systemitem class="osname">Linux</systemitem>
<indexterm><primary>Linux</><secondary>shared library</></> <indexterm><primary>Linux</primary><secondary>shared library</secondary></indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
@ -125,8 +125,8 @@ cc -shared -o foo.so foo.o
<varlistentry> <varlistentry>
<term> <term>
<systemitem class="osname">macOS</> <systemitem class="osname">macOS</systemitem>
<indexterm><primary>macOS</><secondary>shared library</></> <indexterm><primary>macOS</primary><secondary>shared library</secondary></indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
@ -141,8 +141,8 @@ cc -bundle -flat_namespace -undefined suppress -o foo.so foo.o
<varlistentry> <varlistentry>
<term> <term>
<systemitem class="osname">NetBSD</> <systemitem class="osname">NetBSD</systemitem>
<indexterm><primary>NetBSD</><secondary>shared library</></> <indexterm><primary>NetBSD</primary><secondary>shared library</secondary></indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
@ -161,8 +161,8 @@ gcc -shared -o foo.so foo.o
<varlistentry> <varlistentry>
<term> <term>
<systemitem class="osname">OpenBSD</> <systemitem class="osname">OpenBSD</systemitem>
<indexterm><primary>OpenBSD</><secondary>shared library</></> <indexterm><primary>OpenBSD</primary><secondary>shared library</secondary></indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
@ -179,17 +179,17 @@ ld -Bshareable -o foo.so foo.o
<varlistentry> <varlistentry>
<term> <term>
<systemitem class="osname">Solaris</> <systemitem class="osname">Solaris</systemitem>
<indexterm><primary>Solaris</><secondary>shared library</></> <indexterm><primary>Solaris</primary><secondary>shared library</secondary></indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
The compiler flag to create <acronym>PIC</acronym> is The compiler flag to create <acronym>PIC</acronym> is
<option>-KPIC</option> with the Sun compiler and <option>-KPIC</option> with the Sun compiler and
<option>-fPIC</option> with <application>GCC</>. To <option>-fPIC</option> with <application>GCC</application>. To
link shared libraries, the compiler option is link shared libraries, the compiler option is
<option>-G</option> with either compiler or alternatively <option>-G</option> with either compiler or alternatively
<option>-shared</option> with <application>GCC</>. <option>-shared</option> with <application>GCC</application>.
<programlisting> <programlisting>
cc -KPIC -c foo.c cc -KPIC -c foo.c
cc -G -o foo.so foo.o cc -G -o foo.so foo.o

View File

@ -8,7 +8,7 @@
</indexterm> </indexterm>
<para> <para>
<filename>dict_int</> is an example of an add-on dictionary template <filename>dict_int</filename> is an example of an add-on dictionary template
for full-text search. The motivation for this example dictionary is to for full-text search. The motivation for this example dictionary is to
control the indexing of integers (signed and unsigned), allowing such control the indexing of integers (signed and unsigned), allowing such
numbers to be indexed while preventing excessive growth in the number of numbers to be indexed while preventing excessive growth in the number of
@ -25,17 +25,17 @@
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
The <literal>maxlen</> parameter specifies the maximum number of The <literal>maxlen</literal> parameter specifies the maximum number of
digits allowed in an integer word. The default value is 6. digits allowed in an integer word. The default value is 6.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
The <literal>rejectlong</> parameter specifies whether an overlength The <literal>rejectlong</literal> parameter specifies whether an overlength
integer should be truncated or ignored. If <literal>rejectlong</> is integer should be truncated or ignored. If <literal>rejectlong</literal> is
<literal>false</> (the default), the dictionary returns the first <literal>false</literal> (the default), the dictionary returns the first
<literal>maxlen</> digits of the integer. If <literal>rejectlong</> is <literal>maxlen</literal> digits of the integer. If <literal>rejectlong</literal> is
<literal>true</>, the dictionary treats an overlength integer as a stop <literal>true</literal>, the dictionary treats an overlength integer as a stop
word, so that it will not be indexed. Note that this also means that word, so that it will not be indexed. Note that this also means that
such an integer cannot be searched for. such an integer cannot be searched for.
</para> </para>
@ -47,8 +47,8 @@
<title>Usage</title> <title>Usage</title>
<para> <para>
Installing the <literal>dict_int</> extension creates a text search Installing the <literal>dict_int</literal> extension creates a text search
template <literal>intdict_template</> and a dictionary <literal>intdict</> template <literal>intdict_template</literal> and a dictionary <literal>intdict</literal>
based on it, with the default parameters. You can alter the based on it, with the default parameters. You can alter the
parameters, for example parameters, for example

View File

@ -8,7 +8,7 @@
</indexterm> </indexterm>
<para> <para>
<filename>dict_xsyn</> (Extended Synonym Dictionary) is an example of an <filename>dict_xsyn</filename> (Extended Synonym Dictionary) is an example of an
add-on dictionary template for full-text search. This dictionary type add-on dictionary template for full-text search. This dictionary type
replaces words with groups of their synonyms, and so makes it possible to replaces words with groups of their synonyms, and so makes it possible to
search for a word using any of its synonyms. search for a word using any of its synonyms.
@ -18,41 +18,41 @@
<title>Configuration</title> <title>Configuration</title>
<para> <para>
A <literal>dict_xsyn</> dictionary accepts the following options: A <literal>dict_xsyn</literal> dictionary accepts the following options:
</para> </para>
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
<literal>matchorig</> controls whether the original word is accepted by <literal>matchorig</literal> controls whether the original word is accepted by
the dictionary. Default is <literal>true</>. the dictionary. Default is <literal>true</literal>.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<literal>matchsynonyms</> controls whether the synonyms are <literal>matchsynonyms</literal> controls whether the synonyms are
accepted by the dictionary. Default is <literal>false</>. accepted by the dictionary. Default is <literal>false</literal>.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<literal>keeporig</> controls whether the original word is included in <literal>keeporig</literal> controls whether the original word is included in
the dictionary's output. Default is <literal>true</>. the dictionary's output. Default is <literal>true</literal>.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<literal>keepsynonyms</> controls whether the synonyms are included in <literal>keepsynonyms</literal> controls whether the synonyms are included in
the dictionary's output. Default is <literal>true</>. the dictionary's output. Default is <literal>true</literal>.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<literal>rules</> is the base name of the file containing the list of <literal>rules</literal> is the base name of the file containing the list of
synonyms. This file must be stored in synonyms. This file must be stored in
<filename>$SHAREDIR/tsearch_data/</> (where <literal>$SHAREDIR</> means <filename>$SHAREDIR/tsearch_data/</filename> (where <literal>$SHAREDIR</literal> means
the <productname>PostgreSQL</> installation's shared-data directory). the <productname>PostgreSQL</productname> installation's shared-data directory).
Its name must end in <literal>.rules</> (which is not to be included in Its name must end in <literal>.rules</literal> (which is not to be included in
the <literal>rules</> parameter). the <literal>rules</literal> parameter).
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
@ -71,15 +71,15 @@ word syn1 syn2 syn3
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
The sharp (<literal>#</>) sign is a comment delimiter. It may appear at The sharp (<literal>#</literal>) sign is a comment delimiter. It may appear at
any position in a line. The rest of the line will be skipped. any position in a line. The rest of the line will be skipped.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
<para> <para>
Look at <filename>xsyn_sample.rules</>, which is installed in Look at <filename>xsyn_sample.rules</filename>, which is installed in
<filename>$SHAREDIR/tsearch_data/</>, for an example. <filename>$SHAREDIR/tsearch_data/</filename>, for an example.
</para> </para>
</sect2> </sect2>
@ -87,8 +87,8 @@ word syn1 syn2 syn3
<title>Usage</title> <title>Usage</title>
<para> <para>
Installing the <literal>dict_xsyn</> extension creates a text search Installing the <literal>dict_xsyn</literal> extension creates a text search
template <literal>xsyn_template</> and a dictionary <literal>xsyn</> template <literal>xsyn_template</literal> and a dictionary <literal>xsyn</literal>
based on it, with default parameters. You can alter the based on it, with default parameters. You can alter the
parameters, for example parameters, for example

View File

@ -5,7 +5,7 @@
<para> <para>
This chapter discusses how to monitor the disk usage of a This chapter discusses how to monitor the disk usage of a
<productname>PostgreSQL</> database system. <productname>PostgreSQL</productname> database system.
</para> </para>
<sect1 id="disk-usage"> <sect1 id="disk-usage">
@ -18,10 +18,10 @@
<para> <para>
Each table has a primary heap disk file where most of the data is Each table has a primary heap disk file where most of the data is
stored. If the table has any columns with potentially-wide values, stored. If the table has any columns with potentially-wide values,
there also might be a <acronym>TOAST</> file associated with the table, there also might be a <acronym>TOAST</acronym> file associated with the table,
which is used to store values too wide to fit comfortably in the main which is used to store values too wide to fit comfortably in the main
table (see <xref linkend="storage-toast">). There will be one valid index table (see <xref linkend="storage-toast">). There will be one valid index
on the <acronym>TOAST</> table, if present. There also might be indexes on the <acronym>TOAST</acronym> table, if present. There also might be indexes
associated with the base table. Each table and index is stored in a associated with the base table. Each table and index is stored in a
separate disk file &mdash; possibly more than one file, if the file would separate disk file &mdash; possibly more than one file, if the file would
exceed one gigabyte. Naming conventions for these files are described exceed one gigabyte. Naming conventions for these files are described
@ -39,7 +39,7 @@
</para> </para>
<para> <para>
Using <application>psql</> on a recently vacuumed or analyzed database, Using <application>psql</application> on a recently vacuumed or analyzed database,
you can issue queries to see the disk usage of any table: you can issue queries to see the disk usage of any table:
<programlisting> <programlisting>
SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer'; SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer';
@ -49,14 +49,14 @@ SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'custom
base/16384/16806 | 60 base/16384/16806 | 60
(1 row) (1 row)
</programlisting> </programlisting>
Each page is typically 8 kilobytes. (Remember, <structfield>relpages</> Each page is typically 8 kilobytes. (Remember, <structfield>relpages</structfield>
is only updated by <command>VACUUM</>, <command>ANALYZE</>, and is only updated by <command>VACUUM</command>, <command>ANALYZE</command>, and
a few DDL commands such as <command>CREATE INDEX</>.) The file path name a few DDL commands such as <command>CREATE INDEX</command>.) The file path name
is of interest if you want to examine the table's disk file directly. is of interest if you want to examine the table's disk file directly.
</para> </para>
<para> <para>
To show the space used by <acronym>TOAST</> tables, use a query To show the space used by <acronym>TOAST</acronym> tables, use a query
like the following: like the following:
<programlisting> <programlisting>
SELECT relname, relpages SELECT relname, relpages

View File

@ -285,42 +285,42 @@ DELETE FROM products;
<para> <para>
Sometimes it is useful to obtain data from modified rows while they are Sometimes it is useful to obtain data from modified rows while they are
being manipulated. The <command>INSERT</>, <command>UPDATE</>, being manipulated. The <command>INSERT</command>, <command>UPDATE</command>,
and <command>DELETE</> commands all have an and <command>DELETE</command> commands all have an
optional <literal>RETURNING</> clause that supports this. Use optional <literal>RETURNING</literal> clause that supports this. Use
of <literal>RETURNING</> avoids performing an extra database query to of <literal>RETURNING</literal> avoids performing an extra database query to
collect the data, and is especially valuable when it would otherwise be collect the data, and is especially valuable when it would otherwise be
difficult to identify the modified rows reliably. difficult to identify the modified rows reliably.
</para> </para>
<para> <para>
The allowed contents of a <literal>RETURNING</> clause are the same as The allowed contents of a <literal>RETURNING</literal> clause are the same as
a <command>SELECT</> command's output list a <command>SELECT</command> command's output list
(see <xref linkend="queries-select-lists">). It can contain column (see <xref linkend="queries-select-lists">). It can contain column
names of the command's target table, or value expressions using those names of the command's target table, or value expressions using those
columns. A common shorthand is <literal>RETURNING *</>, which selects columns. A common shorthand is <literal>RETURNING *</literal>, which selects
all columns of the target table in order. all columns of the target table in order.
</para> </para>
<para> <para>
In an <command>INSERT</>, the data available to <literal>RETURNING</> is In an <command>INSERT</command>, the data available to <literal>RETURNING</literal> is
the row as it was inserted. This is not so useful in trivial inserts, the row as it was inserted. This is not so useful in trivial inserts,
since it would just repeat the data provided by the client. But it can since it would just repeat the data provided by the client. But it can
be very handy when relying on computed default values. For example, be very handy when relying on computed default values. For example,
when using a <link linkend="datatype-serial"><type>serial</></link> when using a <link linkend="datatype-serial"><type>serial</type></link>
column to provide unique identifiers, <literal>RETURNING</> can return column to provide unique identifiers, <literal>RETURNING</literal> can return
the ID assigned to a new row: the ID assigned to a new row:
<programlisting> <programlisting>
CREATE TABLE users (firstname text, lastname text, id serial primary key); CREATE TABLE users (firstname text, lastname text, id serial primary key);
INSERT INTO users (firstname, lastname) VALUES ('Joe', 'Cool') RETURNING id; INSERT INTO users (firstname, lastname) VALUES ('Joe', 'Cool') RETURNING id;
</programlisting> </programlisting>
The <literal>RETURNING</> clause is also very useful The <literal>RETURNING</literal> clause is also very useful
with <literal>INSERT ... SELECT</>. with <literal>INSERT ... SELECT</literal>.
</para> </para>
<para> <para>
In an <command>UPDATE</>, the data available to <literal>RETURNING</> is In an <command>UPDATE</command>, the data available to <literal>RETURNING</literal> is
the new content of the modified row. For example: the new content of the modified row. For example:
<programlisting> <programlisting>
UPDATE products SET price = price * 1.10 UPDATE products SET price = price * 1.10
@ -330,7 +330,7 @@ UPDATE products SET price = price * 1.10
</para> </para>
<para> <para>
In a <command>DELETE</>, the data available to <literal>RETURNING</> is In a <command>DELETE</command>, the data available to <literal>RETURNING</literal> is
the content of the deleted row. For example: the content of the deleted row. For example:
<programlisting> <programlisting>
DELETE FROM products DELETE FROM products
@ -341,9 +341,9 @@ DELETE FROM products
<para> <para>
If there are triggers (<xref linkend="triggers">) on the target table, If there are triggers (<xref linkend="triggers">) on the target table,
the data available to <literal>RETURNING</> is the row as modified by the data available to <literal>RETURNING</literal> is the row as modified by
the triggers. Thus, inspecting columns computed by triggers is another the triggers. Thus, inspecting columns computed by triggers is another
common use-case for <literal>RETURNING</>. common use-case for <literal>RETURNING</literal>.
</para> </para>
</sect1> </sect1>

View File

@ -449,7 +449,7 @@ checking for fop... fop
<para> <para>
To produce HTML documentation with the stylesheet used on <ulink To produce HTML documentation with the stylesheet used on <ulink
url="https://www.postgresql.org/docs/current">postgresql.org</> instead of the url="https://www.postgresql.org/docs/current">postgresql.org</ulink> instead of the
default simple style use: default simple style use:
<screen> <screen>
<prompt>doc/src/sgml$ </prompt><userinput>make STYLE=website html</userinput> <prompt>doc/src/sgml$ </prompt><userinput>make STYLE=website html</userinput>

View File

@ -8,18 +8,18 @@
</indexterm> </indexterm>
<para> <para>
The <filename>earthdistance</> module provides two different approaches to The <filename>earthdistance</filename> module provides two different approaches to
calculating great circle distances on the surface of the Earth. The one calculating great circle distances on the surface of the Earth. The one
described first depends on the <filename>cube</> module (which described first depends on the <filename>cube</filename> module (which
<emphasis>must</> be installed before <filename>earthdistance</> can be <emphasis>must</emphasis> be installed before <filename>earthdistance</filename> can be
installed). The second one is based on the built-in <type>point</> data type, installed). The second one is based on the built-in <type>point</type> data type,
using longitude and latitude for the coordinates. using longitude and latitude for the coordinates.
</para> </para>
<para> <para>
In this module, the Earth is assumed to be perfectly spherical. In this module, the Earth is assumed to be perfectly spherical.
(If that's too inaccurate for you, you might want to look at the (If that's too inaccurate for you, you might want to look at the
<application><ulink url="http://postgis.net/">PostGIS</ulink></> <application><ulink url="http://postgis.net/">PostGIS</ulink></application>
project.) project.)
</para> </para>
@ -29,13 +29,13 @@
<para> <para>
Data is stored in cubes that are points (both corners are the same) using 3 Data is stored in cubes that are points (both corners are the same) using 3
coordinates representing the x, y, and z distance from the center of the coordinates representing the x, y, and z distance from the center of the
Earth. A domain <type>earth</> over <type>cube</> is provided, which Earth. A domain <type>earth</type> over <type>cube</type> is provided, which
includes constraint checks that the value meets these restrictions and includes constraint checks that the value meets these restrictions and
is reasonably close to the actual surface of the Earth. is reasonably close to the actual surface of the Earth.
</para> </para>
<para> <para>
The radius of the Earth is obtained from the <function>earth()</> The radius of the Earth is obtained from the <function>earth()</function>
function. It is given in meters. But by changing this one function you can function. It is given in meters. But by changing this one function you can
change the module to use some other units, or to use a different value of change the module to use some other units, or to use a different value of
the radius that you feel is more appropriate. the radius that you feel is more appropriate.
@ -43,8 +43,8 @@
<para> <para>
This package has applications to astronomical databases as well. This package has applications to astronomical databases as well.
Astronomers will probably want to change <function>earth()</> to return a Astronomers will probably want to change <function>earth()</function> to return a
radius of <literal>180/pi()</> so that distances are in degrees. radius of <literal>180/pi()</literal> so that distances are in degrees.
</para> </para>
<para> <para>
@ -123,11 +123,11 @@
<entry><function>earth_box(earth, float8)</function><indexterm><primary>earth_box</primary></indexterm></entry> <entry><function>earth_box(earth, float8)</function><indexterm><primary>earth_box</primary></indexterm></entry>
<entry><type>cube</type></entry> <entry><type>cube</type></entry>
<entry>Returns a box suitable for an indexed search using the cube <entry>Returns a box suitable for an indexed search using the cube
<literal>@&gt;</> <literal>@&gt;</literal>
operator for points within a given great circle distance of a location. operator for points within a given great circle distance of a location.
Some points in this box are further than the specified great circle Some points in this box are further than the specified great circle
distance from the location, so a second check using distance from the location, so a second check using
<function>earth_distance</> should be included in the query. <function>earth_distance</function> should be included in the query.
</entry> </entry>
</row> </row>
</tbody> </tbody>
@ -141,7 +141,7 @@
<para> <para>
The second part of the module relies on representing Earth locations as The second part of the module relies on representing Earth locations as
values of type <type>point</>, in which the first component is taken to values of type <type>point</type>, in which the first component is taken to
represent longitude in degrees, and the second component is taken to represent longitude in degrees, and the second component is taken to
represent latitude in degrees. Points are taken as (longitude, latitude) represent latitude in degrees. Points are taken as (longitude, latitude)
and not vice versa because longitude is closer to the intuitive idea of and not vice versa because longitude is closer to the intuitive idea of
@ -165,7 +165,7 @@
</thead> </thead>
<tbody> <tbody>
<row> <row>
<entry><type>point</> <literal>&lt;@&gt;</literal> <type>point</></entry> <entry><type>point</type> <literal>&lt;@&gt;</literal> <type>point</type></entry>
<entry><type>float8</type></entry> <entry><type>float8</type></entry>
<entry>Gives the distance in statute miles between <entry>Gives the distance in statute miles between
two points on the Earth's surface. two points on the Earth's surface.
@ -176,15 +176,15 @@
</table> </table>
<para> <para>
Note that unlike the <type>cube</>-based part of the module, units Note that unlike the <type>cube</type>-based part of the module, units
are hardwired here: changing the <function>earth()</> function will are hardwired here: changing the <function>earth()</function> function will
not affect the results of this operator. not affect the results of this operator.
</para> </para>
<para> <para>
One disadvantage of the longitude/latitude representation is that One disadvantage of the longitude/latitude representation is that
you need to be careful about the edge conditions near the poles you need to be careful about the edge conditions near the poles
and near +/- 180 degrees of longitude. The <type>cube</>-based and near +/- 180 degrees of longitude. The <type>cube</type>-based
representation avoids these discontinuities. representation avoids these discontinuities.
</para> </para>

File diff suppressed because it is too large Load Diff

View File

@ -11,13 +11,13 @@
<para> <para>
All messages emitted by the <productname>PostgreSQL</productname> All messages emitted by the <productname>PostgreSQL</productname>
server are assigned five-character error codes that follow the SQL server are assigned five-character error codes that follow the SQL
standard's conventions for <quote>SQLSTATE</> codes. Applications standard's conventions for <quote>SQLSTATE</quote> codes. Applications
that need to know which error condition has occurred should usually that need to know which error condition has occurred should usually
test the error code, rather than looking at the textual error test the error code, rather than looking at the textual error
message. The error codes are less likely to change across message. The error codes are less likely to change across
<productname>PostgreSQL</> releases, and also are not subject to <productname>PostgreSQL</productname> releases, and also are not subject to
change due to localization of error messages. Note that some, but change due to localization of error messages. Note that some, but
not all, of the error codes produced by <productname>PostgreSQL</> not all, of the error codes produced by <productname>PostgreSQL</productname>
are defined by the SQL standard; some additional error codes for are defined by the SQL standard; some additional error codes for
conditions not defined by the standard have been invented or conditions not defined by the standard have been invented or
borrowed from other databases. borrowed from other databases.
@ -36,16 +36,16 @@
<productname>PostgreSQL</productname> &version;. (Some are not actually <productname>PostgreSQL</productname> &version;. (Some are not actually
used at present, but are defined by the SQL standard.) used at present, but are defined by the SQL standard.)
The error classes are also shown. For each error class there is a The error classes are also shown. For each error class there is a
<quote>standard</> error code having the last three characters <quote>standard</quote> error code having the last three characters
<literal>000</>. This code is used only for error conditions that fall <literal>000</literal>. This code is used only for error conditions that fall
within the class but do not have any more-specific code assigned. within the class but do not have any more-specific code assigned.
</para> </para>
<para> <para>
The symbol shown in the column <quote>Condition Name</quote> is The symbol shown in the column <quote>Condition Name</quote> is
the condition name to use in <application>PL/pgSQL</>. Condition the condition name to use in <application>PL/pgSQL</application>. Condition
names can be written in either upper or lower case. (Note that names can be written in either upper or lower case. (Note that
<application>PL/pgSQL</> does not recognize warning, as opposed to error, <application>PL/pgSQL</application> does not recognize warning, as opposed to error,
condition names; those are classes 00, 01, and 02.) condition names; those are classes 00, 01, and 02.)
</para> </para>
@ -53,10 +53,10 @@
For some types of errors, the server reports the name of a database object For some types of errors, the server reports the name of a database object
(a table, table column, data type, or constraint) associated with the error; (a table, table column, data type, or constraint) associated with the error;
for example, the name of the unique constraint that caused a for example, the name of the unique constraint that caused a
<symbol>unique_violation</> error. Such names are supplied in separate <symbol>unique_violation</symbol> error. Such names are supplied in separate
fields of the error report message so that applications need not try to fields of the error report message so that applications need not try to
extract them from the possibly-localized human-readable text of the message. extract them from the possibly-localized human-readable text of the message.
As of <productname>PostgreSQL</> 9.3, complete coverage for this feature As of <productname>PostgreSQL</productname> 9.3, complete coverage for this feature
exists only for errors in SQLSTATE class 23 (integrity constraint exists only for errors in SQLSTATE class 23 (integrity constraint
violation), but this is likely to be expanded in future. violation), but this is likely to be expanded in future.
</para> </para>

View File

@ -9,7 +9,7 @@
<para> <para>
To supplement the trigger mechanism discussed in <xref linkend="triggers">, To supplement the trigger mechanism discussed in <xref linkend="triggers">,
<productname>PostgreSQL</> also provides event triggers. Unlike regular <productname>PostgreSQL</productname> also provides event triggers. Unlike regular
triggers, which are attached to a single table and capture only DML events, triggers, which are attached to a single table and capture only DML events,
event triggers are global to a particular database and are capable of event triggers are global to a particular database and are capable of
capturing DDL events. capturing DDL events.
@ -28,67 +28,67 @@
An event trigger fires whenever the event with which it is associated An event trigger fires whenever the event with which it is associated
occurs in the database in which it is defined. Currently, the only occurs in the database in which it is defined. Currently, the only
supported events are supported events are
<literal>ddl_command_start</>, <literal>ddl_command_start</literal>,
<literal>ddl_command_end</>, <literal>ddl_command_end</literal>,
<literal>table_rewrite</> <literal>table_rewrite</literal>
and <literal>sql_drop</>. and <literal>sql_drop</literal>.
Support for additional events may be added in future releases. Support for additional events may be added in future releases.
</para> </para>
<para> <para>
The <literal>ddl_command_start</> event occurs just before the The <literal>ddl_command_start</literal> event occurs just before the
execution of a <literal>CREATE</>, <literal>ALTER</>, <literal>DROP</>, execution of a <literal>CREATE</literal>, <literal>ALTER</literal>, <literal>DROP</literal>,
<literal>SECURITY LABEL</>, <literal>SECURITY LABEL</literal>,
<literal>COMMENT</>, <literal>GRANT</> or <literal>REVOKE</> <literal>COMMENT</literal>, <literal>GRANT</literal> or <literal>REVOKE</literal>
command. No check whether the affected object exists or doesn't exist is command. No check whether the affected object exists or doesn't exist is
performed before the event trigger fires. performed before the event trigger fires.
As an exception, however, this event does not occur for As an exception, however, this event does not occur for
DDL commands targeting shared objects &mdash; databases, roles, and tablespaces DDL commands targeting shared objects &mdash; databases, roles, and tablespaces
&mdash; or for commands targeting event triggers themselves. The event trigger &mdash; or for commands targeting event triggers themselves. The event trigger
mechanism does not support these object types. mechanism does not support these object types.
<literal>ddl_command_start</> also occurs just before the execution of a <literal>ddl_command_start</literal> also occurs just before the execution of a
<literal>SELECT INTO</literal> command, since this is equivalent to <literal>SELECT INTO</literal> command, since this is equivalent to
<literal>CREATE TABLE AS</literal>. <literal>CREATE TABLE AS</literal>.
</para> </para>
<para> <para>
The <literal>ddl_command_end</> event occurs just after the execution of The <literal>ddl_command_end</literal> event occurs just after the execution of
this same set of commands. To obtain more details on the <acronym>DDL</> this same set of commands. To obtain more details on the <acronym>DDL</acronym>
operations that took place, use the set-returning function operations that took place, use the set-returning function
<literal>pg_event_trigger_ddl_commands()</> from the <literal>pg_event_trigger_ddl_commands()</literal> from the
<literal>ddl_command_end</> event trigger code (see <literal>ddl_command_end</literal> event trigger code (see
<xref linkend="functions-event-triggers">). Note that the trigger fires <xref linkend="functions-event-triggers">). Note that the trigger fires
after the actions have taken place (but before the transaction commits), after the actions have taken place (but before the transaction commits),
and thus the system catalogs can be read as already changed. and thus the system catalogs can be read as already changed.
</para> </para>
<para> <para>
The <literal>sql_drop</> event occurs just before the The <literal>sql_drop</literal> event occurs just before the
<literal>ddl_command_end</> event trigger for any operation that drops <literal>ddl_command_end</literal> event trigger for any operation that drops
database objects. To list the objects that have been dropped, use the database objects. To list the objects that have been dropped, use the
set-returning function <literal>pg_event_trigger_dropped_objects()</> from the set-returning function <literal>pg_event_trigger_dropped_objects()</literal> from the
<literal>sql_drop</> event trigger code (see <literal>sql_drop</literal> event trigger code (see
<xref linkend="functions-event-triggers">). Note that <xref linkend="functions-event-triggers">). Note that
the trigger is executed after the objects have been deleted from the the trigger is executed after the objects have been deleted from the
system catalogs, so it's not possible to look them up anymore. system catalogs, so it's not possible to look them up anymore.
</para> </para>
<para> <para>
The <literal>table_rewrite</> event occurs just before a table is The <literal>table_rewrite</literal> event occurs just before a table is
rewritten by some actions of the commands <literal>ALTER TABLE</> and rewritten by some actions of the commands <literal>ALTER TABLE</literal> and
<literal>ALTER TYPE</>. While other <literal>ALTER TYPE</literal>. While other
control statements are available to rewrite a table, control statements are available to rewrite a table,
like <literal>CLUSTER</literal> and <literal>VACUUM</literal>, like <literal>CLUSTER</literal> and <literal>VACUUM</literal>,
the <literal>table_rewrite</> event is not triggered by them. the <literal>table_rewrite</literal> event is not triggered by them.
</para> </para>
<para> <para>
Event triggers (like other functions) cannot be executed in an aborted Event triggers (like other functions) cannot be executed in an aborted
transaction. Thus, if a DDL command fails with an error, any associated transaction. Thus, if a DDL command fails with an error, any associated
<literal>ddl_command_end</> triggers will not be executed. Conversely, <literal>ddl_command_end</literal> triggers will not be executed. Conversely,
if a <literal>ddl_command_start</> trigger fails with an error, no if a <literal>ddl_command_start</literal> trigger fails with an error, no
further event triggers will fire, and no attempt will be made to execute further event triggers will fire, and no attempt will be made to execute
the command itself. Similarly, if a <literal>ddl_command_end</> trigger the command itself. Similarly, if a <literal>ddl_command_end</literal> trigger
fails with an error, the effects of the DDL statement will be rolled fails with an error, the effects of the DDL statement will be rolled
back, just as they would be in any other case where the containing back, just as they would be in any other case where the containing
transaction aborts. transaction aborts.
@ -879,14 +879,14 @@
</para> </para>
<para> <para>
Event trigger functions must use the <quote>version 1</> function Event trigger functions must use the <quote>version 1</quote> function
manager interface. manager interface.
</para> </para>
<para> <para>
When a function is called by the event trigger manager, it is not passed When a function is called by the event trigger manager, it is not passed
any normal arguments, but it is passed a <quote>context</> pointer any normal arguments, but it is passed a <quote>context</quote> pointer
pointing to a <structname>EventTriggerData</> structure. C functions can pointing to a <structname>EventTriggerData</structname> structure. C functions can
check whether they were called from the event trigger manager or not by check whether they were called from the event trigger manager or not by
executing the macro: executing the macro:
<programlisting> <programlisting>
@ -897,10 +897,10 @@ CALLED_AS_EVENT_TRIGGER(fcinfo)
((fcinfo)-&gt;context != NULL &amp;&amp; IsA((fcinfo)-&gt;context, EventTriggerData)) ((fcinfo)-&gt;context != NULL &amp;&amp; IsA((fcinfo)-&gt;context, EventTriggerData))
</programlisting> </programlisting>
If this returns true, then it is safe to cast If this returns true, then it is safe to cast
<literal>fcinfo-&gt;context</> to type <literal>EventTriggerData <literal>fcinfo-&gt;context</literal> to type <literal>EventTriggerData
*</literal> and make use of the pointed-to *</literal> and make use of the pointed-to
<structname>EventTriggerData</> structure. The function must <structname>EventTriggerData</structname> structure. The function must
<emphasis>not</emphasis> alter the <structname>EventTriggerData</> <emphasis>not</emphasis> alter the <structname>EventTriggerData</structname>
structure or any of the data it points to. structure or any of the data it points to.
</para> </para>
@ -922,7 +922,7 @@ typedef struct EventTriggerData
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><structfield>type</></term> <term><structfield>type</structfield></term>
<listitem> <listitem>
<para> <para>
Always <literal>T_EventTriggerData</literal>. Always <literal>T_EventTriggerData</literal>.
@ -931,7 +931,7 @@ typedef struct EventTriggerData
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><structfield>event</></term> <term><structfield>event</structfield></term>
<listitem> <listitem>
<para> <para>
Describes the event for which the function is called, one of Describes the event for which the function is called, one of
@ -944,7 +944,7 @@ typedef struct EventTriggerData
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><structfield>parsetree</></term> <term><structfield>parsetree</structfield></term>
<listitem> <listitem>
<para> <para>
A pointer to the parse tree of the command. Check the PostgreSQL A pointer to the parse tree of the command. Check the PostgreSQL
@ -955,7 +955,7 @@ typedef struct EventTriggerData
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><structfield>tag</></term> <term><structfield>tag</structfield></term>
<listitem> <listitem>
<para> <para>
The command tag associated with the event for which the event trigger The command tag associated with the event for which the event trigger
@ -967,8 +967,8 @@ typedef struct EventTriggerData
</para> </para>
<para> <para>
An event trigger function must return a <symbol>NULL</> pointer An event trigger function must return a <symbol>NULL</symbol> pointer
(<emphasis>not</> an SQL null value, that is, do not (<emphasis>not</emphasis> an SQL null value, that is, do not
set <parameter>isNull</parameter> true). set <parameter>isNull</parameter> true).
</para> </para>
</sect1> </sect1>
@ -983,7 +983,7 @@ typedef struct EventTriggerData
</para> </para>
<para> <para>
The function <function>noddl</> raises an exception each time it is called. The function <function>noddl</function> raises an exception each time it is called.
The event trigger definition associated the function with The event trigger definition associated the function with
the <literal>ddl_command_start</literal> event. The effect is that all DDL the <literal>ddl_command_start</literal> event. The effect is that all DDL
commands (with the exceptions mentioned commands (with the exceptions mentioned
@ -1068,7 +1068,7 @@ COMMIT;
<title>A Table Rewrite Event Trigger Example</title> <title>A Table Rewrite Event Trigger Example</title>
<para> <para>
Thanks to the <literal>table_rewrite</> event, it is possible to implement Thanks to the <literal>table_rewrite</literal> event, it is possible to implement
a table rewriting policy only allowing the rewrite in maintenance windows. a table rewriting policy only allowing the rewrite in maintenance windows.
</para> </para>

View File

@ -116,7 +116,7 @@
<para> <para>
Base types are those, like <type>int4</type>, that are Base types are those, like <type>int4</type>, that are
implemented below the level of the <acronym>SQL</> language implemented below the level of the <acronym>SQL</acronym> language
(typically in a low-level language such as C). They generally (typically in a low-level language such as C). They generally
correspond to what are often known as abstract data types. correspond to what are often known as abstract data types.
<productname>PostgreSQL</productname> can only operate on such <productname>PostgreSQL</productname> can only operate on such
@ -136,11 +136,11 @@
Composite types, or row types, are created whenever the user Composite types, or row types, are created whenever the user
creates a table. It is also possible to use <xref creates a table. It is also possible to use <xref
linkend="sql-createtype"> to linkend="sql-createtype"> to
define a <quote>stand-alone</> composite type with no associated define a <quote>stand-alone</quote> composite type with no associated
table. A composite type is simply a list of types with table. A composite type is simply a list of types with
associated field names. A value of a composite type is a row or associated field names. A value of a composite type is a row or
record of field values. The user can access the component fields record of field values. The user can access the component fields
from <acronym>SQL</> queries. Refer to <xref linkend="rowtypes"> from <acronym>SQL</acronym> queries. Refer to <xref linkend="rowtypes">
for more information on composite types. for more information on composite types.
</para> </para>
</sect2> </sect2>
@ -156,7 +156,7 @@
</para> </para>
<para> <para>
Domains can be created using the <acronym>SQL</> command Domains can be created using the <acronym>SQL</acronym> command
<xref linkend="sql-createdomain">. <xref linkend="sql-createdomain">.
Their creation and use is not discussed in this chapter. Their creation and use is not discussed in this chapter.
</para> </para>
@ -166,7 +166,7 @@
<title>Pseudo-Types</title> <title>Pseudo-Types</title>
<para> <para>
There are a few <quote>pseudo-types</> for special purposes. There are a few <quote>pseudo-types</quote> for special purposes.
Pseudo-types cannot appear as columns of tables or attributes of Pseudo-types cannot appear as columns of tables or attributes of
composite types, but they can be used to declare the argument and composite types, but they can be used to declare the argument and
result types of functions. This provides a mechanism within the result types of functions. This provides a mechanism within the
@ -198,12 +198,12 @@
</indexterm> </indexterm>
<para> <para>
Five pseudo-types of special interest are <type>anyelement</>, Five pseudo-types of special interest are <type>anyelement</type>,
<type>anyarray</>, <type>anynonarray</>, <type>anyenum</>, <type>anyarray</type>, <type>anynonarray</type>, <type>anyenum</type>,
and <type>anyrange</>, and <type>anyrange</type>,
which are collectively called <firstterm>polymorphic types</>. which are collectively called <firstterm>polymorphic types</firstterm>.
Any function declared using these types is said to be Any function declared using these types is said to be
a <firstterm>polymorphic function</>. A polymorphic function can a <firstterm>polymorphic function</firstterm>. A polymorphic function can
operate on many different data types, with the specific data type(s) operate on many different data types, with the specific data type(s)
being determined by the data types actually passed to it in a particular being determined by the data types actually passed to it in a particular
call. call.
@ -228,10 +228,10 @@
and others declared <type>anyelement</type>, the actual range type in and others declared <type>anyelement</type>, the actual range type in
the <type>anyrange</type> positions must be a range whose subtype is the <type>anyrange</type> positions must be a range whose subtype is
the same type appearing in the <type>anyelement</type> positions. the same type appearing in the <type>anyelement</type> positions.
<type>anynonarray</> is treated exactly the same as <type>anyelement</>, <type>anynonarray</type> is treated exactly the same as <type>anyelement</type>,
but adds the additional constraint that the actual type must not be but adds the additional constraint that the actual type must not be
an array type. an array type.
<type>anyenum</> is treated exactly the same as <type>anyelement</>, <type>anyenum</type> is treated exactly the same as <type>anyelement</type>,
but adds the additional constraint that the actual type must but adds the additional constraint that the actual type must
be an enum type. be an enum type.
</para> </para>
@ -240,7 +240,7 @@
Thus, when more than one argument position is declared with a polymorphic Thus, when more than one argument position is declared with a polymorphic
type, the net effect is that only certain combinations of actual argument type, the net effect is that only certain combinations of actual argument
types are allowed. For example, a function declared as types are allowed. For example, a function declared as
<literal>equal(anyelement, anyelement)</> will take any two input values, <literal>equal(anyelement, anyelement)</literal> will take any two input values,
so long as they are of the same data type. so long as they are of the same data type.
</para> </para>
@ -251,19 +251,19 @@
result type for that call. For example, if there were not already result type for that call. For example, if there were not already
an array subscripting mechanism, one could define a function that an array subscripting mechanism, one could define a function that
implements subscripting as <literal>subscript(anyarray, integer) implements subscripting as <literal>subscript(anyarray, integer)
returns anyelement</>. This declaration constrains the actual first returns anyelement</literal>. This declaration constrains the actual first
argument to be an array type, and allows the parser to infer the correct argument to be an array type, and allows the parser to infer the correct
result type from the actual first argument's type. Another example result type from the actual first argument's type. Another example
is that a function declared as <literal>f(anyarray) returns anyenum</> is that a function declared as <literal>f(anyarray) returns anyenum</literal>
will only accept arrays of enum types. will only accept arrays of enum types.
</para> </para>
<para> <para>
Note that <type>anynonarray</> and <type>anyenum</> do not represent Note that <type>anynonarray</type> and <type>anyenum</type> do not represent
separate type variables; they are the same type as separate type variables; they are the same type as
<type>anyelement</type>, just with an additional constraint. For <type>anyelement</type>, just with an additional constraint. For
example, declaring a function as <literal>f(anyelement, anyenum)</> example, declaring a function as <literal>f(anyelement, anyenum)</literal>
is equivalent to declaring it as <literal>f(anyenum, anyenum)</>: is equivalent to declaring it as <literal>f(anyenum, anyenum)</literal>:
both actual arguments have to be the same enum type. both actual arguments have to be the same enum type.
</para> </para>
@ -271,10 +271,10 @@
A variadic function (one taking a variable number of arguments, as in A variadic function (one taking a variable number of arguments, as in
<xref linkend="xfunc-sql-variadic-functions">) can be <xref linkend="xfunc-sql-variadic-functions">) can be
polymorphic: this is accomplished by declaring its last parameter as polymorphic: this is accomplished by declaring its last parameter as
<literal>VARIADIC</> <type>anyarray</>. For purposes of argument <literal>VARIADIC</literal> <type>anyarray</type>. For purposes of argument
matching and determining the actual result type, such a function behaves matching and determining the actual result type, such a function behaves
the same as if you had written the appropriate number of the same as if you had written the appropriate number of
<type>anynonarray</> parameters. <type>anynonarray</type> parameters.
</para> </para>
</sect2> </sect2>
</sect1> </sect1>
@ -294,15 +294,15 @@
</indexterm> </indexterm>
<para> <para>
A useful extension to <productname>PostgreSQL</> typically includes A useful extension to <productname>PostgreSQL</productname> typically includes
multiple SQL objects; for example, a new data type will require new multiple SQL objects; for example, a new data type will require new
functions, new operators, and probably new index operator classes. functions, new operators, and probably new index operator classes.
It is helpful to collect all these objects into a single package It is helpful to collect all these objects into a single package
to simplify database management. <productname>PostgreSQL</> calls to simplify database management. <productname>PostgreSQL</productname> calls
such a package an <firstterm>extension</>. To define an extension, such a package an <firstterm>extension</firstterm>. To define an extension,
you need at least a <firstterm>script file</> that contains the you need at least a <firstterm>script file</firstterm> that contains the
<acronym>SQL</> commands to create the extension's objects, and a <acronym>SQL</acronym> commands to create the extension's objects, and a
<firstterm>control file</> that specifies a few basic properties <firstterm>control file</firstterm> that specifies a few basic properties
of the extension itself. If the extension includes C code, there of the extension itself. If the extension includes C code, there
will typically also be a shared library file into which the C code will typically also be a shared library file into which the C code
has been built. Once you have these files, a simple has been built. Once you have these files, a simple
@ -312,14 +312,14 @@
<para> <para>
The main advantage of using an extension, rather than just running the The main advantage of using an extension, rather than just running the
<acronym>SQL</> script to load a bunch of <quote>loose</> objects <acronym>SQL</acronym> script to load a bunch of <quote>loose</quote> objects
into your database, is that <productname>PostgreSQL</> will then into your database, is that <productname>PostgreSQL</productname> will then
understand that the objects of the extension go together. You can understand that the objects of the extension go together. You can
drop all the objects with a single <xref linkend="sql-dropextension"> drop all the objects with a single <xref linkend="sql-dropextension">
command (no need to maintain a separate <quote>uninstall</> script). command (no need to maintain a separate <quote>uninstall</quote> script).
Even more useful, <application>pg_dump</> knows that it should not Even more useful, <application>pg_dump</application> knows that it should not
dump the individual member objects of the extension &mdash; it will dump the individual member objects of the extension &mdash; it will
just include a <command>CREATE EXTENSION</> command in dumps, instead. just include a <command>CREATE EXTENSION</command> command in dumps, instead.
This vastly simplifies migration to a new version of the extension This vastly simplifies migration to a new version of the extension
that might contain more or different objects than the old version. that might contain more or different objects than the old version.
Note however that you must have the extension's control, script, and Note however that you must have the extension's control, script, and
@ -327,12 +327,12 @@
</para> </para>
<para> <para>
<productname>PostgreSQL</> will not let you drop an individual object <productname>PostgreSQL</productname> will not let you drop an individual object
contained in an extension, except by dropping the whole extension. contained in an extension, except by dropping the whole extension.
Also, while you can change the definition of an extension member object Also, while you can change the definition of an extension member object
(for example, via <command>CREATE OR REPLACE FUNCTION</command> for a (for example, via <command>CREATE OR REPLACE FUNCTION</command> for a
function), bear in mind that the modified definition will not be dumped function), bear in mind that the modified definition will not be dumped
by <application>pg_dump</>. Such a change is usually only sensible if by <application>pg_dump</application>. Such a change is usually only sensible if
you concurrently make the same change in the extension's script file. you concurrently make the same change in the extension's script file.
(But there are special provisions for tables containing configuration (But there are special provisions for tables containing configuration
data; see <xref linkend="extend-extensions-config-tables">.) data; see <xref linkend="extend-extensions-config-tables">.)
@ -346,19 +346,19 @@
statements. The final set of privileges for each object (if any are set) statements. The final set of privileges for each object (if any are set)
will be stored in the will be stored in the
<link linkend="catalog-pg-init-privs"><structname>pg_init_privs</structname></link> <link linkend="catalog-pg-init-privs"><structname>pg_init_privs</structname></link>
system catalog. When <application>pg_dump</> is used, the system catalog. When <application>pg_dump</application> is used, the
<command>CREATE EXTENSION</> command will be included in the dump, followed <command>CREATE EXTENSION</command> command will be included in the dump, followed
by the set of <command>GRANT</command> and <command>REVOKE</command> by the set of <command>GRANT</command> and <command>REVOKE</command>
statements necessary to set the privileges on the objects to what they were statements necessary to set the privileges on the objects to what they were
at the time the dump was taken. at the time the dump was taken.
</para> </para>
<para> <para>
<productname>PostgreSQL</> does not currently support extension scripts <productname>PostgreSQL</productname> does not currently support extension scripts
issuing <command>CREATE POLICY</command> or <command>SECURITY LABEL</command> issuing <command>CREATE POLICY</command> or <command>SECURITY LABEL</command>
statements. These are expected to be set after the extension has been statements. These are expected to be set after the extension has been
created. All RLS policies and security labels on extension objects will be created. All RLS policies and security labels on extension objects will be
included in dumps created by <application>pg_dump</>. included in dumps created by <application>pg_dump</application>.
</para> </para>
<para> <para>
@ -366,8 +366,8 @@
scripts that adjust the definitions of the SQL objects contained in an scripts that adjust the definitions of the SQL objects contained in an
extension. For example, if version 1.1 of an extension adds one function extension. For example, if version 1.1 of an extension adds one function
and changes the body of another function compared to 1.0, the extension and changes the body of another function compared to 1.0, the extension
author can provide an <firstterm>update script</> that makes just those author can provide an <firstterm>update script</firstterm> that makes just those
two changes. The <command>ALTER EXTENSION UPDATE</> command can then two changes. The <command>ALTER EXTENSION UPDATE</command> command can then
be used to apply these changes and track which version of the extension be used to apply these changes and track which version of the extension
is actually installed in a given database. is actually installed in a given database.
</para> </para>
@ -384,7 +384,7 @@
considered members of the extension. considered members of the extension.
Another important point is that schemas can belong to extensions, but not Another important point is that schemas can belong to extensions, but not
vice versa: an extension as such has an unqualified name and does not vice versa: an extension as such has an unqualified name and does not
exist <quote>within</> any schema. The extension's member objects, exist <quote>within</quote> any schema. The extension's member objects,
however, will belong to schemas whenever appropriate for their object however, will belong to schemas whenever appropriate for their object
types. It may or may not be appropriate for an extension to own the types. It may or may not be appropriate for an extension to own the
schema(s) its member objects are within. schema(s) its member objects are within.
@ -409,23 +409,23 @@
<para> <para>
The <xref linkend="sql-createextension"> command relies on a control The <xref linkend="sql-createextension"> command relies on a control
file for each extension, which must be named the same as the extension file for each extension, which must be named the same as the extension
with a suffix of <literal>.control</>, and must be placed in the with a suffix of <literal>.control</literal>, and must be placed in the
installation's <literal>SHAREDIR/extension</literal> directory. There installation's <literal>SHAREDIR/extension</literal> directory. There
must also be at least one <acronym>SQL</> script file, which follows the must also be at least one <acronym>SQL</acronym> script file, which follows the
naming pattern naming pattern
<literal><replaceable>extension</>--<replaceable>version</>.sql</literal> <literal><replaceable>extension</replaceable>--<replaceable>version</replaceable>.sql</literal>
(for example, <literal>foo--1.0.sql</> for version <literal>1.0</> of (for example, <literal>foo--1.0.sql</literal> for version <literal>1.0</literal> of
extension <literal>foo</>). By default, the script file(s) are also extension <literal>foo</literal>). By default, the script file(s) are also
placed in the <literal>SHAREDIR/extension</literal> directory; but the placed in the <literal>SHAREDIR/extension</literal> directory; but the
control file can specify a different directory for the script file(s). control file can specify a different directory for the script file(s).
</para> </para>
<para> <para>
The file format for an extension control file is the same as for the The file format for an extension control file is the same as for the
<filename>postgresql.conf</> file, namely a list of <filename>postgresql.conf</filename> file, namely a list of
<replaceable>parameter_name</> <literal>=</> <replaceable>value</> <replaceable>parameter_name</replaceable> <literal>=</literal> <replaceable>value</replaceable>
assignments, one per line. Blank lines and comments introduced by assignments, one per line. Blank lines and comments introduced by
<literal>#</> are allowed. Be sure to quote any value that is not <literal>#</literal> are allowed. Be sure to quote any value that is not
a single word or number. a single word or number.
</para> </para>
@ -438,11 +438,11 @@
<term><varname>directory</varname> (<type>string</type>)</term> <term><varname>directory</varname> (<type>string</type>)</term>
<listitem> <listitem>
<para> <para>
The directory containing the extension's <acronym>SQL</> script The directory containing the extension's <acronym>SQL</acronym> script
file(s). Unless an absolute path is given, the name is relative to file(s). Unless an absolute path is given, the name is relative to
the installation's <literal>SHAREDIR</literal> directory. The the installation's <literal>SHAREDIR</literal> directory. The
default behavior is equivalent to specifying default behavior is equivalent to specifying
<literal>directory = 'extension'</>. <literal>directory = 'extension'</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -452,9 +452,9 @@
<listitem> <listitem>
<para> <para>
The default version of the extension (the one that will be installed The default version of the extension (the one that will be installed
if no version is specified in <command>CREATE EXTENSION</>). Although if no version is specified in <command>CREATE EXTENSION</command>). Although
this can be omitted, that will result in <command>CREATE EXTENSION</> this can be omitted, that will result in <command>CREATE EXTENSION</command>
failing if no <literal>VERSION</> option appears, so you generally failing if no <literal>VERSION</literal> option appears, so you generally
don't want to do that. don't want to do that.
</para> </para>
</listitem> </listitem>
@ -489,11 +489,11 @@
<listitem> <listitem>
<para> <para>
The value of this parameter will be substituted for each occurrence The value of this parameter will be substituted for each occurrence
of <literal>MODULE_PATHNAME</> in the script file(s). If it is not of <literal>MODULE_PATHNAME</literal> in the script file(s). If it is not
set, no substitution is made. Typically, this is set to set, no substitution is made. Typically, this is set to
<literal>$libdir/<replaceable>shared_library_name</></literal> and <literal>$libdir/<replaceable>shared_library_name</replaceable></literal> and
then <literal>MODULE_PATHNAME</> is used in <command>CREATE then <literal>MODULE_PATHNAME</literal> is used in <command>CREATE
FUNCTION</> commands for C-language functions, so that the script FUNCTION</command> commands for C-language functions, so that the script
files do not need to hard-wire the name of the shared library. files do not need to hard-wire the name of the shared library.
</para> </para>
</listitem> </listitem>
@ -514,9 +514,9 @@
<term><varname>superuser</varname> (<type>boolean</type>)</term> <term><varname>superuser</varname> (<type>boolean</type>)</term>
<listitem> <listitem>
<para> <para>
If this parameter is <literal>true</> (which is the default), If this parameter is <literal>true</literal> (which is the default),
only superusers can create the extension or update it to a new only superusers can create the extension or update it to a new
version. If it is set to <literal>false</>, just the privileges version. If it is set to <literal>false</literal>, just the privileges
required to execute the commands in the installation or update script required to execute the commands in the installation or update script
are required. are required.
</para> </para>
@ -527,9 +527,9 @@
<term><varname>relocatable</varname> (<type>boolean</type>)</term> <term><varname>relocatable</varname> (<type>boolean</type>)</term>
<listitem> <listitem>
<para> <para>
An extension is <firstterm>relocatable</> if it is possible to move An extension is <firstterm>relocatable</firstterm> if it is possible to move
its contained objects into a different schema after initial creation its contained objects into a different schema after initial creation
of the extension. The default is <literal>false</>, i.e. the of the extension. The default is <literal>false</literal>, i.e. the
extension is not relocatable. extension is not relocatable.
See <xref linkend="extend-extensions-relocation"> for more information. See <xref linkend="extend-extensions-relocation"> for more information.
</para> </para>
@ -553,45 +553,45 @@
<para> <para>
In addition to the primary control file In addition to the primary control file
<literal><replaceable>extension</>.control</literal>, <literal><replaceable>extension</replaceable>.control</literal>,
an extension can have secondary control files named in the style an extension can have secondary control files named in the style
<literal><replaceable>extension</>--<replaceable>version</>.control</literal>. <literal><replaceable>extension</replaceable>--<replaceable>version</replaceable>.control</literal>.
If supplied, these must be located in the script file directory. If supplied, these must be located in the script file directory.
Secondary control files follow the same format as the primary control Secondary control files follow the same format as the primary control
file. Any parameters set in a secondary control file override the file. Any parameters set in a secondary control file override the
primary control file when installing or updating to that version of primary control file when installing or updating to that version of
the extension. However, the parameters <varname>directory</> and the extension. However, the parameters <varname>directory</varname> and
<varname>default_version</> cannot be set in a secondary control file. <varname>default_version</varname> cannot be set in a secondary control file.
</para> </para>
<para> <para>
An extension's <acronym>SQL</> script files can contain any SQL commands, An extension's <acronym>SQL</acronym> script files can contain any SQL commands,
except for transaction control commands (<command>BEGIN</>, except for transaction control commands (<command>BEGIN</command>,
<command>COMMIT</>, etc) and commands that cannot be executed inside a <command>COMMIT</command>, etc) and commands that cannot be executed inside a
transaction block (such as <command>VACUUM</>). This is because the transaction block (such as <command>VACUUM</command>). This is because the
script files are implicitly executed within a transaction block. script files are implicitly executed within a transaction block.
</para> </para>
<para> <para>
An extension's <acronym>SQL</> script files can also contain lines An extension's <acronym>SQL</acronym> script files can also contain lines
beginning with <literal>\echo</>, which will be ignored (treated as beginning with <literal>\echo</literal>, which will be ignored (treated as
comments) by the extension mechanism. This provision is commonly used comments) by the extension mechanism. This provision is commonly used
to throw an error if the script file is fed to <application>psql</> to throw an error if the script file is fed to <application>psql</application>
rather than being loaded via <command>CREATE EXTENSION</> (see example rather than being loaded via <command>CREATE EXTENSION</command> (see example
script in <xref linkend="extend-extensions-example">). script in <xref linkend="extend-extensions-example">).
Without that, users might accidentally load the Without that, users might accidentally load the
extension's contents as <quote>loose</> objects rather than as an extension's contents as <quote>loose</quote> objects rather than as an
extension, a state of affairs that's a bit tedious to recover from. extension, a state of affairs that's a bit tedious to recover from.
</para> </para>
<para> <para>
While the script files can contain any characters allowed by the specified While the script files can contain any characters allowed by the specified
encoding, control files should contain only plain ASCII, because there encoding, control files should contain only plain ASCII, because there
is no way for <productname>PostgreSQL</> to know what encoding a is no way for <productname>PostgreSQL</productname> to know what encoding a
control file is in. In practice this is only an issue if you want to control file is in. In practice this is only an issue if you want to
use non-ASCII characters in the extension's comment. Recommended use non-ASCII characters in the extension's comment. Recommended
practice in that case is to not use the control file <varname>comment</> practice in that case is to not use the control file <varname>comment</varname>
parameter, but instead use <command>COMMENT ON EXTENSION</> parameter, but instead use <command>COMMENT ON EXTENSION</command>
within a script file to set the comment. within a script file to set the comment.
</para> </para>
@ -611,14 +611,14 @@
<para> <para>
A fully relocatable extension can be moved into another schema A fully relocatable extension can be moved into another schema
at any time, even after it's been loaded into a database. at any time, even after it's been loaded into a database.
This is done with the <command>ALTER EXTENSION SET SCHEMA</> This is done with the <command>ALTER EXTENSION SET SCHEMA</command>
command, which automatically renames all the member objects into command, which automatically renames all the member objects into
the new schema. Normally, this is only possible if the extension the new schema. Normally, this is only possible if the extension
contains no internal assumptions about what schema any of its contains no internal assumptions about what schema any of its
objects are in. Also, the extension's objects must all be in one objects are in. Also, the extension's objects must all be in one
schema to begin with (ignoring objects that do not belong to any schema to begin with (ignoring objects that do not belong to any
schema, such as procedural languages). Mark a fully relocatable schema, such as procedural languages). Mark a fully relocatable
extension by setting <literal>relocatable = true</> in its control extension by setting <literal>relocatable = true</literal> in its control
file. file.
</para> </para>
</listitem> </listitem>
@ -628,26 +628,26 @@
An extension might be relocatable during installation but not An extension might be relocatable during installation but not
afterwards. This is typically the case if the extension's script afterwards. This is typically the case if the extension's script
file needs to reference the target schema explicitly, for example file needs to reference the target schema explicitly, for example
in setting <literal>search_path</> properties for SQL functions. in setting <literal>search_path</literal> properties for SQL functions.
For such an extension, set <literal>relocatable = false</> in its For such an extension, set <literal>relocatable = false</literal> in its
control file, and use <literal>@extschema@</> to refer to the target control file, and use <literal>@extschema@</literal> to refer to the target
schema in the script file. All occurrences of this string will be schema in the script file. All occurrences of this string will be
replaced by the actual target schema's name before the script is replaced by the actual target schema's name before the script is
executed. The user can set the target schema using the executed. The user can set the target schema using the
<literal>SCHEMA</> option of <command>CREATE EXTENSION</>. <literal>SCHEMA</literal> option of <command>CREATE EXTENSION</command>.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
If the extension does not support relocation at all, set If the extension does not support relocation at all, set
<literal>relocatable = false</> in its control file, and also set <literal>relocatable = false</literal> in its control file, and also set
<literal>schema</> to the name of the intended target schema. This <literal>schema</literal> to the name of the intended target schema. This
will prevent use of the <literal>SCHEMA</> option of <command>CREATE will prevent use of the <literal>SCHEMA</literal> option of <command>CREATE
EXTENSION</>, unless it specifies the same schema named in the control EXTENSION</command>, unless it specifies the same schema named in the control
file. This choice is typically necessary if the extension contains file. This choice is typically necessary if the extension contains
internal assumptions about schema names that can't be replaced by internal assumptions about schema names that can't be replaced by
uses of <literal>@extschema@</>. The <literal>@extschema@</> uses of <literal>@extschema@</literal>. The <literal>@extschema@</literal>
substitution mechanism is available in this case too, although it is substitution mechanism is available in this case too, although it is
of limited use since the schema name is determined by the control file. of limited use since the schema name is determined by the control file.
</para> </para>
@ -657,23 +657,23 @@
<para> <para>
In all cases, the script file will be executed with In all cases, the script file will be executed with
<xref linkend="guc-search-path"> initially set to point to the target <xref linkend="guc-search-path"> initially set to point to the target
schema; that is, <command>CREATE EXTENSION</> does the equivalent of schema; that is, <command>CREATE EXTENSION</command> does the equivalent of
this: this:
<programlisting> <programlisting>
SET LOCAL search_path TO @extschema@; SET LOCAL search_path TO @extschema@;
</programlisting> </programlisting>
This allows the objects created by the script file to go into the target This allows the objects created by the script file to go into the target
schema. The script file can change <varname>search_path</> if it wishes, schema. The script file can change <varname>search_path</varname> if it wishes,
but that is generally undesirable. <varname>search_path</> is restored but that is generally undesirable. <varname>search_path</varname> is restored
to its previous setting upon completion of <command>CREATE EXTENSION</>. to its previous setting upon completion of <command>CREATE EXTENSION</command>.
</para> </para>
<para> <para>
The target schema is determined by the <varname>schema</> parameter in The target schema is determined by the <varname>schema</varname> parameter in
the control file if that is given, otherwise by the <literal>SCHEMA</> the control file if that is given, otherwise by the <literal>SCHEMA</literal>
option of <command>CREATE EXTENSION</> if that is given, otherwise the option of <command>CREATE EXTENSION</command> if that is given, otherwise the
current default object creation schema (the first one in the caller's current default object creation schema (the first one in the caller's
<varname>search_path</>). When the control file <varname>schema</> <varname>search_path</varname>). When the control file <varname>schema</varname>
parameter is used, the target schema will be created if it doesn't parameter is used, the target schema will be created if it doesn't
already exist, but in the other two cases it must already exist. already exist, but in the other two cases it must already exist.
</para> </para>
@ -681,7 +681,7 @@ SET LOCAL search_path TO @extschema@;
<para> <para>
If any prerequisite extensions are listed in <varname>requires</varname> If any prerequisite extensions are listed in <varname>requires</varname>
in the control file, their target schemas are appended to the initial in the control file, their target schemas are appended to the initial
setting of <varname>search_path</>. This allows their objects to be setting of <varname>search_path</varname>. This allows their objects to be
visible to the new extension's script file. visible to the new extension's script file.
</para> </para>
@ -690,7 +690,7 @@ SET LOCAL search_path TO @extschema@;
multiple schemas, it is usually desirable to place all the objects meant multiple schemas, it is usually desirable to place all the objects meant
for external use into a single schema, which is considered the extension's for external use into a single schema, which is considered the extension's
target schema. Such an arrangement works conveniently with the default target schema. Such an arrangement works conveniently with the default
setting of <varname>search_path</> during creation of dependent setting of <varname>search_path</varname> during creation of dependent
extensions. extensions.
</para> </para>
</sect2> </sect2>
@ -703,7 +703,7 @@ SET LOCAL search_path TO @extschema@;
might be added or changed by the user after installation of the might be added or changed by the user after installation of the
extension. Ordinarily, if a table is part of an extension, neither extension. Ordinarily, if a table is part of an extension, neither
the table's definition nor its content will be dumped by the table's definition nor its content will be dumped by
<application>pg_dump</>. But that behavior is undesirable for a <application>pg_dump</application>. But that behavior is undesirable for a
configuration table; any data changes made by the user need to be configuration table; any data changes made by the user need to be
included in dumps, or the extension will behave differently after a dump included in dumps, or the extension will behave differently after a dump
and reload. and reload.
@ -716,9 +716,9 @@ SET LOCAL search_path TO @extschema@;
<para> <para>
To solve this problem, an extension's script file can mark a table To solve this problem, an extension's script file can mark a table
or a sequence it has created as a configuration relation, which will or a sequence it has created as a configuration relation, which will
cause <application>pg_dump</> to include the table's or the sequence's cause <application>pg_dump</application> to include the table's or the sequence's
contents (not its definition) in dumps. To do that, call the function contents (not its definition) in dumps. To do that, call the function
<function>pg_extension_config_dump(regclass, text)</> after creating the <function>pg_extension_config_dump(regclass, text)</function> after creating the
table or the sequence, for example table or the sequence, for example
<programlisting> <programlisting>
CREATE TABLE my_config (key text, value text); CREATE TABLE my_config (key text, value text);
@ -728,30 +728,30 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', '');
SELECT pg_catalog.pg_extension_config_dump('my_config_seq', ''); SELECT pg_catalog.pg_extension_config_dump('my_config_seq', '');
</programlisting> </programlisting>
Any number of tables or sequences can be marked this way. Sequences Any number of tables or sequences can be marked this way. Sequences
associated with <type>serial</> or <type>bigserial</> columns can associated with <type>serial</type> or <type>bigserial</type> columns can
be marked as well. be marked as well.
</para> </para>
<para> <para>
When the second argument of <function>pg_extension_config_dump</> is When the second argument of <function>pg_extension_config_dump</function> is
an empty string, the entire contents of the table are dumped by an empty string, the entire contents of the table are dumped by
<application>pg_dump</>. This is usually only correct if the table <application>pg_dump</application>. This is usually only correct if the table
is initially empty as created by the extension script. If there is is initially empty as created by the extension script. If there is
a mixture of initial data and user-provided data in the table, a mixture of initial data and user-provided data in the table,
the second argument of <function>pg_extension_config_dump</> provides the second argument of <function>pg_extension_config_dump</function> provides
a <literal>WHERE</> condition that selects the data to be dumped. a <literal>WHERE</literal> condition that selects the data to be dumped.
For example, you might do For example, you might do
<programlisting> <programlisting>
CREATE TABLE my_config (key text, value text, standard_entry boolean); CREATE TABLE my_config (key text, value text, standard_entry boolean);
SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entry'); SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entry');
</programlisting> </programlisting>
and then make sure that <structfield>standard_entry</> is true only and then make sure that <structfield>standard_entry</structfield> is true only
in the rows created by the extension's script. in the rows created by the extension's script.
</para> </para>
<para> <para>
For sequences, the second argument of <function>pg_extension_config_dump</> For sequences, the second argument of <function>pg_extension_config_dump</function>
has no effect. has no effect.
</para> </para>
@ -763,10 +763,10 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr
<para> <para>
You can alter the filter condition associated with a configuration table You can alter the filter condition associated with a configuration table
by calling <function>pg_extension_config_dump</> again. (This would by calling <function>pg_extension_config_dump</function> again. (This would
typically be useful in an extension update script.) The only way to mark typically be useful in an extension update script.) The only way to mark
a table as no longer a configuration table is to dissociate it from the a table as no longer a configuration table is to dissociate it from the
extension with <command>ALTER EXTENSION ... DROP TABLE</>. extension with <command>ALTER EXTENSION ... DROP TABLE</command>.
</para> </para>
<para> <para>
@ -781,7 +781,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr
</para> </para>
<para> <para>
Sequences associated with <type>serial</> or <type>bigserial</> columns Sequences associated with <type>serial</type> or <type>bigserial</type> columns
need to be directly marked to dump their state. Marking their parent need to be directly marked to dump their state. Marking their parent
relation is not enough for this purpose. relation is not enough for this purpose.
</para> </para>
@ -797,20 +797,20 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr
each released version of the extension's installation script. each released version of the extension's installation script.
In addition, if you want users to be able to update their databases In addition, if you want users to be able to update their databases
dynamically from one version to the next, you should provide dynamically from one version to the next, you should provide
<firstterm>update scripts</> that make the necessary changes to go from <firstterm>update scripts</firstterm> that make the necessary changes to go from
one version to the next. Update scripts have names following the pattern one version to the next. Update scripts have names following the pattern
<literal><replaceable>extension</>--<replaceable>oldversion</>--<replaceable>newversion</>.sql</literal> <literal><replaceable>extension</replaceable>--<replaceable>oldversion</replaceable>--<replaceable>newversion</replaceable>.sql</literal>
(for example, <literal>foo--1.0--1.1.sql</> contains the commands to modify (for example, <literal>foo--1.0--1.1.sql</literal> contains the commands to modify
version <literal>1.0</> of extension <literal>foo</> into version version <literal>1.0</literal> of extension <literal>foo</literal> into version
<literal>1.1</>). <literal>1.1</literal>).
</para> </para>
<para> <para>
Given that a suitable update script is available, the command Given that a suitable update script is available, the command
<command>ALTER EXTENSION UPDATE</> will update an installed extension <command>ALTER EXTENSION UPDATE</command> will update an installed extension
to the specified new version. The update script is run in the same to the specified new version. The update script is run in the same
environment that <command>CREATE EXTENSION</> provides for installation environment that <command>CREATE EXTENSION</command> provides for installation
scripts: in particular, <varname>search_path</> is set up in the same scripts: in particular, <varname>search_path</varname> is set up in the same
way, and any new objects created by the script are automatically added way, and any new objects created by the script are automatically added
to the extension. Also, if the script chooses to drop extension member to the extension. Also, if the script chooses to drop extension member
objects, they are automatically dissociated from the extension. objects, they are automatically dissociated from the extension.
@ -824,56 +824,56 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr
<para> <para>
The update mechanism can be used to solve an important special case: The update mechanism can be used to solve an important special case:
converting a <quote>loose</> collection of objects into an extension. converting a <quote>loose</quote> collection of objects into an extension.
Before the extension mechanism was added to Before the extension mechanism was added to
<productname>PostgreSQL</productname> (in 9.1), many people wrote <productname>PostgreSQL</productname> (in 9.1), many people wrote
extension modules that simply created assorted unpackaged objects. extension modules that simply created assorted unpackaged objects.
Given an existing database containing such objects, how can we convert Given an existing database containing such objects, how can we convert
the objects into a properly packaged extension? Dropping them and then the objects into a properly packaged extension? Dropping them and then
doing a plain <command>CREATE EXTENSION</> is one way, but it's not doing a plain <command>CREATE EXTENSION</command> is one way, but it's not
desirable if the objects have dependencies (for example, if there are desirable if the objects have dependencies (for example, if there are
table columns of a data type created by the extension). The way to fix table columns of a data type created by the extension). The way to fix
this situation is to create an empty extension, then use <command>ALTER this situation is to create an empty extension, then use <command>ALTER
EXTENSION ADD</> to attach each pre-existing object to the extension, EXTENSION ADD</command> to attach each pre-existing object to the extension,
then finally create any new objects that are in the current extension then finally create any new objects that are in the current extension
version but were not in the unpackaged release. <command>CREATE version but were not in the unpackaged release. <command>CREATE
EXTENSION</> supports this case with its <literal>FROM</> <replaceable EXTENSION</command> supports this case with its <literal>FROM</literal> <replaceable
class="parameter">old_version</> option, which causes it to not run the class="parameter">old_version</replaceable> option, which causes it to not run the
normal installation script for the target version, but instead the update normal installation script for the target version, but instead the update
script named script named
<literal><replaceable>extension</>--<replaceable>old_version</>--<replaceable>target_version</>.sql</literal>. <literal><replaceable>extension</replaceable>--<replaceable>old_version</replaceable>--<replaceable>target_version</replaceable>.sql</literal>.
The choice of the dummy version name to use as <replaceable The choice of the dummy version name to use as <replaceable
class="parameter">old_version</> is up to the extension author, though class="parameter">old_version</replaceable> is up to the extension author, though
<literal>unpackaged</> is a common convention. If you have multiple <literal>unpackaged</literal> is a common convention. If you have multiple
prior versions you need to be able to update into extension style, use prior versions you need to be able to update into extension style, use
multiple dummy version names to identify them. multiple dummy version names to identify them.
</para> </para>
<para> <para>
<command>ALTER EXTENSION</> is able to execute sequences of update <command>ALTER EXTENSION</command> is able to execute sequences of update
script files to achieve a requested update. For example, if only script files to achieve a requested update. For example, if only
<literal>foo--1.0--1.1.sql</> and <literal>foo--1.1--2.0.sql</> are <literal>foo--1.0--1.1.sql</literal> and <literal>foo--1.1--2.0.sql</literal> are
available, <command>ALTER EXTENSION</> will apply them in sequence if an available, <command>ALTER EXTENSION</command> will apply them in sequence if an
update to version <literal>2.0</> is requested when <literal>1.0</> is update to version <literal>2.0</literal> is requested when <literal>1.0</literal> is
currently installed. currently installed.
</para> </para>
<para> <para>
<productname>PostgreSQL</> doesn't assume anything about the properties <productname>PostgreSQL</productname> doesn't assume anything about the properties
of version names: for example, it does not know whether <literal>1.1</> of version names: for example, it does not know whether <literal>1.1</literal>
follows <literal>1.0</>. It just matches up the available version names follows <literal>1.0</literal>. It just matches up the available version names
and follows the path that requires applying the fewest update scripts. and follows the path that requires applying the fewest update scripts.
(A version name can actually be any string that doesn't contain (A version name can actually be any string that doesn't contain
<literal>--</> or leading or trailing <literal>-</>.) <literal>--</literal> or leading or trailing <literal>-</literal>.)
</para> </para>
<para> <para>
Sometimes it is useful to provide <quote>downgrade</> scripts, for Sometimes it is useful to provide <quote>downgrade</quote> scripts, for
example <literal>foo--1.1--1.0.sql</> to allow reverting the changes example <literal>foo--1.1--1.0.sql</literal> to allow reverting the changes
associated with version <literal>1.1</>. If you do that, be careful associated with version <literal>1.1</literal>. If you do that, be careful
of the possibility that a downgrade script might unexpectedly of the possibility that a downgrade script might unexpectedly
get applied because it yields a shorter path. The risky case is where get applied because it yields a shorter path. The risky case is where
there is a <quote>fast path</> update script that jumps ahead several there is a <quote>fast path</quote> update script that jumps ahead several
versions as well as a downgrade script to the fast path's start point. versions as well as a downgrade script to the fast path's start point.
It might take fewer steps to apply the downgrade and then the fast It might take fewer steps to apply the downgrade and then the fast
path than to move ahead one version at a time. If the downgrade script path than to move ahead one version at a time. If the downgrade script
@ -883,14 +883,14 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr
<para> <para>
To check for unexpected update paths, use this command: To check for unexpected update paths, use this command:
<programlisting> <programlisting>
SELECT * FROM pg_extension_update_paths('<replaceable>extension_name</>'); SELECT * FROM pg_extension_update_paths('<replaceable>extension_name</replaceable>');
</programlisting> </programlisting>
This shows each pair of distinct known version names for the specified This shows each pair of distinct known version names for the specified
extension, together with the update path sequence that would be taken to extension, together with the update path sequence that would be taken to
get from the source version to the target version, or <literal>NULL</> if get from the source version to the target version, or <literal>NULL</literal> if
there is no available update path. The path is shown in textual form there is no available update path. The path is shown in textual form
with <literal>--</> separators. You can use with <literal>--</literal> separators. You can use
<literal>regexp_split_to_array(path,'--')</> if you prefer an array <literal>regexp_split_to_array(path,'--')</literal> if you prefer an array
format. format.
</para> </para>
</sect2> </sect2>
@ -901,24 +901,24 @@ SELECT * FROM pg_extension_update_paths('<replaceable>extension_name</>');
<para> <para>
An extension that has been around for awhile will probably exist in An extension that has been around for awhile will probably exist in
several versions, for which the author will need to write update scripts. several versions, for which the author will need to write update scripts.
For example, if you have released a <literal>foo</> extension in For example, if you have released a <literal>foo</literal> extension in
versions <literal>1.0</>, <literal>1.1</>, and <literal>1.2</>, there versions <literal>1.0</literal>, <literal>1.1</literal>, and <literal>1.2</literal>, there
should be update scripts <filename>foo--1.0--1.1.sql</> should be update scripts <filename>foo--1.0--1.1.sql</filename>
and <filename>foo--1.1--1.2.sql</>. and <filename>foo--1.1--1.2.sql</filename>.
Before <productname>PostgreSQL</> 10, it was necessary to also create Before <productname>PostgreSQL</productname> 10, it was necessary to also create
new script files <filename>foo--1.1.sql</> and <filename>foo--1.2.sql</> new script files <filename>foo--1.1.sql</filename> and <filename>foo--1.2.sql</filename>
that directly build the newer extension versions, or else the newer that directly build the newer extension versions, or else the newer
versions could not be installed directly, only by versions could not be installed directly, only by
installing <literal>1.0</> and then updating. That was tedious and installing <literal>1.0</literal> and then updating. That was tedious and
duplicative, but now it's unnecessary, because <command>CREATE duplicative, but now it's unnecessary, because <command>CREATE
EXTENSION</> can follow update chains automatically. EXTENSION</command> can follow update chains automatically.
For example, if only the script For example, if only the script
files <filename>foo--1.0.sql</>, <filename>foo--1.0--1.1.sql</>, files <filename>foo--1.0.sql</filename>, <filename>foo--1.0--1.1.sql</filename>,
and <filename>foo--1.1--1.2.sql</> are available then a request to and <filename>foo--1.1--1.2.sql</filename> are available then a request to
install version <literal>1.2</> is honored by running those three install version <literal>1.2</literal> is honored by running those three
scripts in sequence. The processing is the same as if you'd first scripts in sequence. The processing is the same as if you'd first
installed <literal>1.0</> and then updated to <literal>1.2</>. installed <literal>1.0</literal> and then updated to <literal>1.2</literal>.
(As with <command>ALTER EXTENSION UPDATE</>, if multiple pathways are (As with <command>ALTER EXTENSION UPDATE</command>, if multiple pathways are
available then the shortest is preferred.) Arranging an extension's available then the shortest is preferred.) Arranging an extension's
script files in this style can reduce the amount of maintenance effort script files in this style can reduce the amount of maintenance effort
needed to produce small updates. needed to produce small updates.
@ -929,10 +929,10 @@ SELECT * FROM pg_extension_update_paths('<replaceable>extension_name</>');
maintained in this style, keep in mind that each version needs a control maintained in this style, keep in mind that each version needs a control
file even if it has no stand-alone installation script, as that control file even if it has no stand-alone installation script, as that control
file will determine how the implicit update to that version is performed. file will determine how the implicit update to that version is performed.
For example, if <filename>foo--1.0.control</> specifies <literal>requires For example, if <filename>foo--1.0.control</filename> specifies <literal>requires
= 'bar'</> but <literal>foo</>'s other control files do not, the = 'bar'</literal> but <literal>foo</literal>'s other control files do not, the
extension's dependency on <literal>bar</> will be dropped when updating extension's dependency on <literal>bar</literal> will be dropped when updating
from <literal>1.0</> to another version. from <literal>1.0</literal> to another version.
</para> </para>
</sect2> </sect2>
@ -940,14 +940,14 @@ SELECT * FROM pg_extension_update_paths('<replaceable>extension_name</>');
<title>Extension Example</title> <title>Extension Example</title>
<para> <para>
Here is a complete example of an <acronym>SQL</>-only Here is a complete example of an <acronym>SQL</acronym>-only
extension, a two-element composite type that can store any type of value extension, a two-element composite type that can store any type of value
in its slots, which are named <quote>k</> and <quote>v</>. Non-text in its slots, which are named <quote>k</quote> and <quote>v</quote>. Non-text
values are automatically coerced to text for storage. values are automatically coerced to text for storage.
</para> </para>
<para> <para>
The script file <filename>pair--1.0.sql</> looks like this: The script file <filename>pair--1.0.sql</filename> looks like this:
<programlisting><![CDATA[ <programlisting><![CDATA[
-- complain if script is sourced in psql, rather than via CREATE EXTENSION -- complain if script is sourced in psql, rather than via CREATE EXTENSION
@ -976,7 +976,7 @@ CREATE OPERATOR ~> (LEFTARG = text, RIGHTARG = text, PROCEDURE = pair);
</para> </para>
<para> <para>
The control file <filename>pair.control</> looks like this: The control file <filename>pair.control</filename> looks like this:
<programlisting> <programlisting>
# pair extension # pair extension
@ -988,7 +988,7 @@ relocatable = true
<para> <para>
While you hardly need a makefile to install these two files into the While you hardly need a makefile to install these two files into the
correct directory, you could use a <filename>Makefile</> containing this: correct directory, you could use a <filename>Makefile</filename> containing this:
<programlisting> <programlisting>
EXTENSION = pair EXTENSION = pair
@ -1000,9 +1000,9 @@ include $(PGXS)
</programlisting> </programlisting>
This makefile relies on <acronym>PGXS</acronym>, which is described This makefile relies on <acronym>PGXS</acronym>, which is described
in <xref linkend="extend-pgxs">. The command <literal>make install</> in <xref linkend="extend-pgxs">. The command <literal>make install</literal>
will install the control and script files into the correct will install the control and script files into the correct
directory as reported by <application>pg_config</>. directory as reported by <application>pg_config</application>.
</para> </para>
<para> <para>
@ -1022,16 +1022,16 @@ include $(PGXS)
<para> <para>
If you are thinking about distributing your If you are thinking about distributing your
<productname>PostgreSQL</> extension modules, setting up a <productname>PostgreSQL</productname> extension modules, setting up a
portable build system for them can be fairly difficult. Therefore portable build system for them can be fairly difficult. Therefore
the <productname>PostgreSQL</> installation provides a build the <productname>PostgreSQL</productname> installation provides a build
infrastructure for extensions, called <acronym>PGXS</acronym>, so infrastructure for extensions, called <acronym>PGXS</acronym>, so
that simple extension modules can be built simply against an that simple extension modules can be built simply against an
already installed server. <acronym>PGXS</acronym> is mainly intended already installed server. <acronym>PGXS</acronym> is mainly intended
for extensions that include C code, although it can be used for for extensions that include C code, although it can be used for
pure-SQL extensions too. Note that <acronym>PGXS</acronym> is not pure-SQL extensions too. Note that <acronym>PGXS</acronym> is not
intended to be a universal build system framework that can be used intended to be a universal build system framework that can be used
to build any software interfacing to <productname>PostgreSQL</>; to build any software interfacing to <productname>PostgreSQL</productname>;
it simply automates common build rules for simple server extension it simply automates common build rules for simple server extension
modules. For more complicated packages, you might need to write your modules. For more complicated packages, you might need to write your
own build system. own build system.
@ -1115,7 +1115,7 @@ include $(PGXS)
<term><varname>MODULEDIR</varname></term> <term><varname>MODULEDIR</varname></term>
<listitem> <listitem>
<para> <para>
subdirectory of <literal><replaceable>prefix</>/share</literal> subdirectory of <literal><replaceable>prefix</replaceable>/share</literal>
into which DATA and DOCS files should be installed into which DATA and DOCS files should be installed
(if not set, default is <literal>extension</literal> if (if not set, default is <literal>extension</literal> if
<varname>EXTENSION</varname> is set, <varname>EXTENSION</varname> is set,
@ -1198,7 +1198,7 @@ include $(PGXS)
<term><varname>REGRESS_OPTS</varname></term> <term><varname>REGRESS_OPTS</varname></term>
<listitem> <listitem>
<para> <para>
additional switches to pass to <application>pg_regress</> additional switches to pass to <application>pg_regress</application>
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1252,10 +1252,10 @@ include $(PGXS)
<term><varname>PG_CONFIG</varname></term> <term><varname>PG_CONFIG</varname></term>
<listitem> <listitem>
<para> <para>
path to <application>pg_config</> program for the path to <application>pg_config</application> program for the
<productname>PostgreSQL</productname> installation to build against <productname>PostgreSQL</productname> installation to build against
(typically just <literal>pg_config</> to use the first one in your (typically just <literal>pg_config</literal> to use the first one in your
<varname>PATH</>) <varname>PATH</varname>)
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1270,7 +1270,7 @@ include $(PGXS)
compiled and installed for the compiled and installed for the
<productname>PostgreSQL</productname> installation that <productname>PostgreSQL</productname> installation that
corresponds to the first <command>pg_config</command> program corresponds to the first <command>pg_config</command> program
found in your <varname>PATH</>. You can use a different installation by found in your <varname>PATH</varname>. You can use a different installation by
setting <varname>PG_CONFIG</varname> to point to its setting <varname>PG_CONFIG</varname> to point to its
<command>pg_config</command> program, either within the makefile <command>pg_config</command> program, either within the makefile
or on the <literal>make</literal> command line. or on the <literal>make</literal> command line.
@ -1293,7 +1293,7 @@ make -f /path/to/extension/source/tree/Makefile install
<para> <para>
Alternatively, you can set up a directory for a VPATH build in a similar Alternatively, you can set up a directory for a VPATH build in a similar
way to how it is done for the core code. One way to do this is using the way to how it is done for the core code. One way to do this is using the
core script <filename>config/prep_buildtree</>. Once this has been done core script <filename>config/prep_buildtree</filename>. Once this has been done
you can build by setting the <literal>make</literal> variable you can build by setting the <literal>make</literal> variable
<varname>VPATH</varname> like this: <varname>VPATH</varname> like this:
<programlisting> <programlisting>
@ -1304,18 +1304,18 @@ make VPATH=/path/to/extension/source/tree install
</para> </para>
<para> <para>
The scripts listed in the <varname>REGRESS</> variable are used for The scripts listed in the <varname>REGRESS</varname> variable are used for
regression testing of your module, which can be invoked by <literal>make regression testing of your module, which can be invoked by <literal>make
installcheck</literal> after doing <literal>make install</>. For this to installcheck</literal> after doing <literal>make install</literal>. For this to
work you must have a running <productname>PostgreSQL</productname> server. work you must have a running <productname>PostgreSQL</productname> server.
The script files listed in <varname>REGRESS</> must appear in a The script files listed in <varname>REGRESS</varname> must appear in a
subdirectory named <literal>sql/</literal> in your extension's directory. subdirectory named <literal>sql/</literal> in your extension's directory.
These files must have extension <literal>.sql</literal>, which must not be These files must have extension <literal>.sql</literal>, which must not be
included in the <varname>REGRESS</varname> list in the makefile. For each included in the <varname>REGRESS</varname> list in the makefile. For each
test there should also be a file containing the expected output in a test there should also be a file containing the expected output in a
subdirectory named <literal>expected/</literal>, with the same stem and subdirectory named <literal>expected/</literal>, with the same stem and
extension <literal>.out</literal>. <literal>make installcheck</literal> extension <literal>.out</literal>. <literal>make installcheck</literal>
executes each test script with <application>psql</>, and compares the executes each test script with <application>psql</application>, and compares the
resulting output to the matching expected file. Any differences will be resulting output to the matching expected file. Any differences will be
written to the file <literal>regression.diffs</literal> in <command>diff written to the file <literal>regression.diffs</literal> in <command>diff
-c</command> format. Note that trying to run a test that is missing its -c</command> format. Note that trying to run a test that is missing its

View File

@ -42,7 +42,7 @@
All other language interfaces are external projects and are distributed All other language interfaces are external projects and are distributed
separately. <xref linkend="language-interface-table"> includes a list of separately. <xref linkend="language-interface-table"> includes a list of
some of these projects. Note that some of these packages might not be some of these projects. Note that some of these packages might not be
released under the same license as <productname>PostgreSQL</>. For more released under the same license as <productname>PostgreSQL</productname>. For more
information on each language interface, including licensing terms, refer to information on each language interface, including licensing terms, refer to
its website and documentation. its website and documentation.
</para> </para>
@ -145,8 +145,8 @@
<para> <para>
There are several administration tools available for There are several administration tools available for
<productname>PostgreSQL</>. The most popular is <productname>PostgreSQL</productname>. The most popular is
<application><ulink url="http://www.pgadmin.org/">pgAdmin III</ulink></>, <application><ulink url="http://www.pgadmin.org/">pgAdmin III</ulink></application>,
and there are several commercially available ones as well. and there are several commercially available ones as well.
</para> </para>
</sect1> </sect1>
@ -172,7 +172,7 @@
and maintained outside the core <productname>PostgreSQL</productname> and maintained outside the core <productname>PostgreSQL</productname>
distribution. <xref linkend="pl-language-table"> lists some of these distribution. <xref linkend="pl-language-table"> lists some of these
packages. Note that some of these projects might not be released under the same packages. Note that some of these projects might not be released under the same
license as <productname>PostgreSQL</>. For more information on each license as <productname>PostgreSQL</productname>. For more information on each
procedural language, including licensing information, refer to its website procedural language, including licensing information, refer to its website
and documentation. and documentation.
</para> </para>
@ -233,17 +233,17 @@
</indexterm> </indexterm>
<para> <para>
<productname>PostgreSQL</> is designed to be easily extensible. For <productname>PostgreSQL</productname> is designed to be easily extensible. For
this reason, extensions loaded into the database can function this reason, extensions loaded into the database can function
just like features that are built in. The just like features that are built in. The
<filename>contrib/</> directory shipped with the source code <filename>contrib/</filename> directory shipped with the source code
contains several extensions, which are described in contains several extensions, which are described in
<xref linkend="contrib">. Other extensions are developed <xref linkend="contrib">. Other extensions are developed
independently, like <application><ulink independently, like <application><ulink
url="http://postgis.net/">PostGIS</ulink></>. Even url="http://postgis.net/">PostGIS</ulink></application>. Even
<productname>PostgreSQL</> replication solutions can be developed <productname>PostgreSQL</productname> replication solutions can be developed
externally. For example, <application> <ulink externally. For example, <application> <ulink
url="http://www.slony.info">Slony-I</ulink></> is a popular url="http://www.slony.info">Slony-I</ulink></application> is a popular
master/standby replication solution that is developed independently master/standby replication solution that is developed independently
from the core project. from the core project.
</para> </para>

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
</indexterm> </indexterm>
<para> <para>
The <filename>file_fdw</> module provides the foreign-data wrapper The <filename>file_fdw</filename> module provides the foreign-data wrapper
<function>file_fdw</function>, which can be used to access data <function>file_fdw</function>, which can be used to access data
files in the server's file system, or to execute programs on the server files in the server's file system, or to execute programs on the server
and read their output. The data file or program output must be in a format and read their output. The data file or program output must be in a format
@ -41,7 +41,7 @@
<listitem> <listitem>
<para> <para>
Specifies the command to be executed. The standard output of this Specifies the command to be executed. The standard output of this
command will be read as though <command>COPY FROM PROGRAM</> were used. command will be read as though <command>COPY FROM PROGRAM</command> were used.
Either <literal>program</literal> or <literal>filename</literal> must be Either <literal>program</literal> or <literal>filename</literal> must be
specified, but not both. specified, but not both.
</para> </para>
@ -54,7 +54,7 @@
<listitem> <listitem>
<para> <para>
Specifies the data format, Specifies the data format,
the same as <command>COPY</>'s <literal>FORMAT</literal> option. the same as <command>COPY</command>'s <literal>FORMAT</literal> option.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -65,7 +65,7 @@
<listitem> <listitem>
<para> <para>
Specifies whether the data has a header line, Specifies whether the data has a header line,
the same as <command>COPY</>'s <literal>HEADER</literal> option. the same as <command>COPY</command>'s <literal>HEADER</literal> option.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -76,7 +76,7 @@
<listitem> <listitem>
<para> <para>
Specifies the data delimiter character, Specifies the data delimiter character,
the same as <command>COPY</>'s <literal>DELIMITER</literal> option. the same as <command>COPY</command>'s <literal>DELIMITER</literal> option.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -87,7 +87,7 @@
<listitem> <listitem>
<para> <para>
Specifies the data quote character, Specifies the data quote character,
the same as <command>COPY</>'s <literal>QUOTE</literal> option. the same as <command>COPY</command>'s <literal>QUOTE</literal> option.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -98,7 +98,7 @@
<listitem> <listitem>
<para> <para>
Specifies the data escape character, Specifies the data escape character,
the same as <command>COPY</>'s <literal>ESCAPE</literal> option. the same as <command>COPY</command>'s <literal>ESCAPE</literal> option.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -109,7 +109,7 @@
<listitem> <listitem>
<para> <para>
Specifies the data null string, Specifies the data null string,
the same as <command>COPY</>'s <literal>NULL</literal> option. the same as <command>COPY</command>'s <literal>NULL</literal> option.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -120,7 +120,7 @@
<listitem> <listitem>
<para> <para>
Specifies the data encoding, Specifies the data encoding,
the same as <command>COPY</>'s <literal>ENCODING</literal> option. the same as <command>COPY</command>'s <literal>ENCODING</literal> option.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -128,10 +128,10 @@
</variablelist> </variablelist>
<para> <para>
Note that while <command>COPY</> allows options such as <literal>HEADER</> Note that while <command>COPY</command> allows options such as <literal>HEADER</literal>
to be specified without a corresponding value, the foreign table option to be specified without a corresponding value, the foreign table option
syntax requires a value to be present in all cases. To activate syntax requires a value to be present in all cases. To activate
<command>COPY</> options typically written without a value, you can pass <command>COPY</command> options typically written without a value, you can pass
the value TRUE, since all such options are Booleans. the value TRUE, since all such options are Booleans.
</para> </para>
@ -150,7 +150,7 @@
This is a Boolean option. If true, it specifies that values of the This is a Boolean option. If true, it specifies that values of the
column should not be matched against the null string (that is, the column should not be matched against the null string (that is, the
table-level <literal>null</literal> option). This has the same effect table-level <literal>null</literal> option). This has the same effect
as listing the column in <command>COPY</>'s as listing the column in <command>COPY</command>'s
<literal>FORCE_NOT_NULL</literal> option. <literal>FORCE_NOT_NULL</literal> option.
</para> </para>
</listitem> </listitem>
@ -162,11 +162,11 @@
<listitem> <listitem>
<para> <para>
This is a Boolean option. If true, it specifies that values of the This is a Boolean option. If true, it specifies that values of the
column which match the null string are returned as <literal>NULL</> column which match the null string are returned as <literal>NULL</literal>
even if the value is quoted. Without this option, only unquoted even if the value is quoted. Without this option, only unquoted
values matching the null string are returned as <literal>NULL</>. values matching the null string are returned as <literal>NULL</literal>.
This has the same effect as listing the column in This has the same effect as listing the column in
<command>COPY</>'s <literal>FORCE_NULL</literal> option. <command>COPY</command>'s <literal>FORCE_NULL</literal> option.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -174,14 +174,14 @@
</variablelist> </variablelist>
<para> <para>
<command>COPY</>'s <literal>OIDS</literal> and <command>COPY</command>'s <literal>OIDS</literal> and
<literal>FORCE_QUOTE</literal> options are currently not supported by <literal>FORCE_QUOTE</literal> options are currently not supported by
<literal>file_fdw</>. <literal>file_fdw</literal>.
</para> </para>
<para> <para>
These options can only be specified for a foreign table or its columns, not These options can only be specified for a foreign table or its columns, not
in the options of the <literal>file_fdw</> foreign-data wrapper, nor in the in the options of the <literal>file_fdw</literal> foreign-data wrapper, nor in the
options of a server or user mapping using the wrapper. options of a server or user mapping using the wrapper.
</para> </para>
@ -193,7 +193,7 @@
</para> </para>
<para> <para>
When specifying the <literal>program</> option, keep in mind that the option When specifying the <literal>program</literal> option, keep in mind that the option
string is executed by the shell. If you need to pass any arguments to the string is executed by the shell. If you need to pass any arguments to the
command that come from an untrusted source, you must be careful to strip or command that come from an untrusted source, you must be careful to strip or
escape any characters that might have special meaning to the shell. escape any characters that might have special meaning to the shell.
@ -202,9 +202,9 @@
</para> </para>
<para> <para>
For a foreign table using <literal>file_fdw</>, <command>EXPLAIN</> shows For a foreign table using <literal>file_fdw</literal>, <command>EXPLAIN</command> shows
the name of the file to be read or program to be run. the name of the file to be read or program to be run.
For a file, unless <literal>COSTS OFF</> is For a file, unless <literal>COSTS OFF</literal> is
specified, the file size (in bytes) is shown as well. specified, the file size (in bytes) is shown as well.
</para> </para>
@ -212,10 +212,10 @@
<title id="csvlog-fdw">Create a Foreign Table for PostgreSQL CSV Logs</title> <title id="csvlog-fdw">Create a Foreign Table for PostgreSQL CSV Logs</title>
<para> <para>
One of the obvious uses for <literal>file_fdw</> is to make One of the obvious uses for <literal>file_fdw</literal> is to make
the PostgreSQL activity log available as a table for querying. To the PostgreSQL activity log available as a table for querying. To
do this, first you must be logging to a CSV file, which here we do this, first you must be logging to a CSV file, which here we
will call <literal>pglog.csv</>. First, install <literal>file_fdw</> will call <literal>pglog.csv</literal>. First, install <literal>file_fdw</literal>
as an extension: as an extension:
</para> </para>
@ -233,7 +233,7 @@ CREATE SERVER pglog FOREIGN DATA WRAPPER file_fdw;
<para> <para>
Now you are ready to create the foreign data table. Using the Now you are ready to create the foreign data table. Using the
<command>CREATE FOREIGN TABLE</> command, you will need to define <command>CREATE FOREIGN TABLE</command> command, you will need to define
the columns for the table, the CSV file name, and its format: the columns for the table, the CSV file name, and its format:
<programlisting> <programlisting>

File diff suppressed because it is too large Load Diff

View File

@ -8,14 +8,14 @@
</indexterm> </indexterm>
<para> <para>
The <filename>fuzzystrmatch</> module provides several The <filename>fuzzystrmatch</filename> module provides several
functions to determine similarities and distance between strings. functions to determine similarities and distance between strings.
</para> </para>
<caution> <caution>
<para> <para>
At present, the <function>soundex</>, <function>metaphone</>, At present, the <function>soundex</function>, <function>metaphone</function>,
<function>dmetaphone</>, and <function>dmetaphone_alt</> functions do <function>dmetaphone</function>, and <function>dmetaphone_alt</function> functions do
not work well with multibyte encodings (such as UTF-8). not work well with multibyte encodings (such as UTF-8).
</para> </para>
</caution> </caution>
@ -31,7 +31,7 @@
</para> </para>
<para> <para>
The <filename>fuzzystrmatch</> module provides two functions The <filename>fuzzystrmatch</filename> module provides two functions
for working with Soundex codes: for working with Soundex codes:
</para> </para>
@ -49,12 +49,12 @@ difference(text, text) returns int
</synopsis> </synopsis>
<para> <para>
The <function>soundex</> function converts a string to its Soundex code. The <function>soundex</function> function converts a string to its Soundex code.
The <function>difference</> function converts two strings to their Soundex The <function>difference</function> function converts two strings to their Soundex
codes and then reports the number of matching code positions. Since codes and then reports the number of matching code positions. Since
Soundex codes have four characters, the result ranges from zero to four, Soundex codes have four characters, the result ranges from zero to four,
with zero being no match and four being an exact match. (Thus, the with zero being no match and four being an exact match. (Thus, the
function is misnamed &mdash; <function>similarity</> would have been function is misnamed &mdash; <function>similarity</function> would have been
a better name.) a better name.)
</para> </para>
@ -115,10 +115,10 @@ levenshtein_less_equal(text source, text target, int max_d) returns int
<para> <para>
<function>levenshtein_less_equal</function> is an accelerated version of the <function>levenshtein_less_equal</function> is an accelerated version of the
Levenshtein function for use when only small distances are of interest. Levenshtein function for use when only small distances are of interest.
If the actual distance is less than or equal to <literal>max_d</>, If the actual distance is less than or equal to <literal>max_d</literal>,
then <function>levenshtein_less_equal</function> returns the correct then <function>levenshtein_less_equal</function> returns the correct
distance; otherwise it returns some value greater than <literal>max_d</>. distance; otherwise it returns some value greater than <literal>max_d</literal>.
If <literal>max_d</> is negative then the behavior is the same as If <literal>max_d</literal> is negative then the behavior is the same as
<function>levenshtein</function>. <function>levenshtein</function>.
</para> </para>
@ -198,9 +198,9 @@ test=# SELECT metaphone('GUMBO', 4);
<title>Double Metaphone</title> <title>Double Metaphone</title>
<para> <para>
The Double Metaphone system computes two <quote>sounds like</> strings The Double Metaphone system computes two <quote>sounds like</quote> strings
for a given input string &mdash; a <quote>primary</> and an for a given input string &mdash; a <quote>primary</quote> and an
<quote>alternate</>. In most cases they are the same, but for non-English <quote>alternate</quote>. In most cases they are the same, but for non-English
names especially they can be a bit different, depending on pronunciation. names especially they can be a bit different, depending on pronunciation.
These functions compute the primary and alternate codes: These functions compute the primary and alternate codes:
</para> </para>

View File

@ -30,12 +30,12 @@ while (<$errcodes>)
s/-/&mdash;/; s/-/&mdash;/;
# Wrap PostgreSQL in <productname/> # Wrap PostgreSQL in <productname/>
s/PostgreSQL/<productname>PostgreSQL<\/>/g; s/PostgreSQL/<productname>PostgreSQL<\/productname>/g;
print "\n\n"; print "\n\n";
print "<row>\n"; print "<row>\n";
print "<entry spanname=\"span12\">"; print "<entry spanname=\"span12\">";
print "<emphasis role=\"bold\">$_</></entry>\n"; print "<emphasis role=\"bold\">$_</emphasis></entry>\n";
print "</row>\n"; print "</row>\n";
next; next;

View File

@ -13,8 +13,8 @@
<para> <para>
The API for constructing generic WAL records is defined in The API for constructing generic WAL records is defined in
<filename>access/generic_xlog.h</> and implemented <filename>access/generic_xlog.h</filename> and implemented
in <filename>access/transam/generic_xlog.c</>. in <filename>access/transam/generic_xlog.c</filename>.
</para> </para>
<para> <para>
@ -24,24 +24,24 @@
<orderedlist> <orderedlist>
<listitem> <listitem>
<para> <para>
<function>state = GenericXLogStart(relation)</> &mdash; start <function>state = GenericXLogStart(relation)</function> &mdash; start
construction of a generic WAL record for the given relation. construction of a generic WAL record for the given relation.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<function>page = GenericXLogRegisterBuffer(state, buffer, flags)</> <function>page = GenericXLogRegisterBuffer(state, buffer, flags)</function>
&mdash; register a buffer to be modified within the current generic WAL &mdash; register a buffer to be modified within the current generic WAL
record. This function returns a pointer to a temporary copy of the record. This function returns a pointer to a temporary copy of the
buffer's page, where modifications should be made. (Do not modify the buffer's page, where modifications should be made. (Do not modify the
buffer's contents directly.) The third argument is a bit mask of flags buffer's contents directly.) The third argument is a bit mask of flags
applicable to the operation. Currently the only such flag is applicable to the operation. Currently the only such flag is
<literal>GENERIC_XLOG_FULL_IMAGE</>, which indicates that a full-page <literal>GENERIC_XLOG_FULL_IMAGE</literal>, which indicates that a full-page
image rather than a delta update should be included in the WAL record. image rather than a delta update should be included in the WAL record.
Typically this flag would be set if the page is new or has been Typically this flag would be set if the page is new or has been
rewritten completely. rewritten completely.
<function>GenericXLogRegisterBuffer</> can be repeated if the <function>GenericXLogRegisterBuffer</function> can be repeated if the
WAL-logged action needs to modify multiple pages. WAL-logged action needs to modify multiple pages.
</para> </para>
</listitem> </listitem>
@ -54,7 +54,7 @@
<listitem> <listitem>
<para> <para>
<function>GenericXLogFinish(state)</> &mdash; apply the changes to <function>GenericXLogFinish(state)</function> &mdash; apply the changes to
the buffers and emit the generic WAL record. the buffers and emit the generic WAL record.
</para> </para>
</listitem> </listitem>
@ -63,7 +63,7 @@
<para> <para>
WAL record construction can be canceled between any of the above steps by WAL record construction can be canceled between any of the above steps by
calling <function>GenericXLogAbort(state)</>. This will discard all calling <function>GenericXLogAbort(state)</function>. This will discard all
changes to the page image copies. changes to the page image copies.
</para> </para>
@ -75,13 +75,13 @@
<listitem> <listitem>
<para> <para>
No direct modifications of buffers are allowed! All modifications must No direct modifications of buffers are allowed! All modifications must
be done in copies acquired from <function>GenericXLogRegisterBuffer()</>. be done in copies acquired from <function>GenericXLogRegisterBuffer()</function>.
In other words, code that makes generic WAL records should never call In other words, code that makes generic WAL records should never call
<function>BufferGetPage()</> for itself. However, it remains the <function>BufferGetPage()</function> for itself. However, it remains the
caller's responsibility to pin/unpin and lock/unlock the buffers at caller's responsibility to pin/unpin and lock/unlock the buffers at
appropriate times. Exclusive lock must be held on each target buffer appropriate times. Exclusive lock must be held on each target buffer
from before <function>GenericXLogRegisterBuffer()</> until after from before <function>GenericXLogRegisterBuffer()</function> until after
<function>GenericXLogFinish()</>. <function>GenericXLogFinish()</function>.
</para> </para>
</listitem> </listitem>
@ -97,7 +97,7 @@
<listitem> <listitem>
<para> <para>
The maximum number of buffers that can be registered for a generic WAL The maximum number of buffers that can be registered for a generic WAL
record is <literal>MAX_GENERIC_XLOG_PAGES</>. An error will be thrown record is <literal>MAX_GENERIC_XLOG_PAGES</literal>. An error will be thrown
if this limit is exceeded. if this limit is exceeded.
</para> </para>
</listitem> </listitem>
@ -106,26 +106,26 @@
<para> <para>
Generic WAL assumes that the pages to be modified have standard Generic WAL assumes that the pages to be modified have standard
layout, and in particular that there is no useful data between layout, and in particular that there is no useful data between
<structfield>pd_lower</> and <structfield>pd_upper</>. <structfield>pd_lower</structfield> and <structfield>pd_upper</structfield>.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
Since you are modifying copies of buffer Since you are modifying copies of buffer
pages, <function>GenericXLogStart()</> does not start a critical pages, <function>GenericXLogStart()</function> does not start a critical
section. Thus, you can safely do memory allocation, error throwing, section. Thus, you can safely do memory allocation, error throwing,
etc. between <function>GenericXLogStart()</> and etc. between <function>GenericXLogStart()</function> and
<function>GenericXLogFinish()</>. The only actual critical section is <function>GenericXLogFinish()</function>. The only actual critical section is
present inside <function>GenericXLogFinish()</>. There is no need to present inside <function>GenericXLogFinish()</function>. There is no need to
worry about calling <function>GenericXLogAbort()</> during an error worry about calling <function>GenericXLogAbort()</function> during an error
exit, either. exit, either.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<function>GenericXLogFinish()</> takes care of marking buffers dirty <function>GenericXLogFinish()</function> takes care of marking buffers dirty
and setting their LSNs. You do not need to do this explicitly. and setting their LSNs. You do not need to do this explicitly.
</para> </para>
</listitem> </listitem>
@ -148,7 +148,7 @@
<listitem> <listitem>
<para> <para>
If <literal>GENERIC_XLOG_FULL_IMAGE</> is not specified for a If <literal>GENERIC_XLOG_FULL_IMAGE</literal> is not specified for a
registered buffer, the generic WAL record contains a delta between registered buffer, the generic WAL record contains a delta between
the old and the new page images. This delta is based on byte-by-byte the old and the new page images. This delta is based on byte-by-byte
comparison. This is not very compact for the case of moving data comparison. This is not very compact for the case of moving data

View File

@ -88,7 +88,7 @@
</para> </para>
<para> <para>
According to the <systemitem class="resource">comp.ai.genetic</> <acronym>FAQ</acronym> it cannot be stressed too According to the <systemitem class="resource">comp.ai.genetic</systemitem> <acronym>FAQ</acronym> it cannot be stressed too
strongly that a <acronym>GA</acronym> is not a pure random search for a solution to a strongly that a <acronym>GA</acronym> is not a pure random search for a solution to a
problem. A <acronym>GA</acronym> uses stochastic processes, but the result is distinctly problem. A <acronym>GA</acronym> uses stochastic processes, but the result is distinctly
non-random (better than random). non-random (better than random).
@ -222,7 +222,7 @@
are considered; and all the initially-determined relation scan plans are considered; and all the initially-determined relation scan plans
are available. The estimated cost is the cheapest of these are available. The estimated cost is the cheapest of these
possibilities.) Join sequences with lower estimated cost are considered possibilities.) Join sequences with lower estimated cost are considered
<quote>more fit</> than those with higher cost. The genetic algorithm <quote>more fit</quote> than those with higher cost. The genetic algorithm
discards the least fit candidates. Then new candidates are generated discards the least fit candidates. Then new candidates are generated
by combining genes of more-fit candidates &mdash; that is, by using by combining genes of more-fit candidates &mdash; that is, by using
randomly-chosen portions of known low-cost join sequences to create randomly-chosen portions of known low-cost join sequences to create
@ -235,20 +235,20 @@
<para> <para>
This process is inherently nondeterministic, because of the randomized This process is inherently nondeterministic, because of the randomized
choices made during both the initial population selection and subsequent choices made during both the initial population selection and subsequent
<quote>mutation</> of the best candidates. To avoid surprising changes <quote>mutation</quote> of the best candidates. To avoid surprising changes
of the selected plan, each run of the GEQO algorithm restarts its of the selected plan, each run of the GEQO algorithm restarts its
random number generator with the current <xref linkend="guc-geqo-seed"> random number generator with the current <xref linkend="guc-geqo-seed">
parameter setting. As long as <varname>geqo_seed</> and the other parameter setting. As long as <varname>geqo_seed</varname> and the other
GEQO parameters are kept fixed, the same plan will be generated for a GEQO parameters are kept fixed, the same plan will be generated for a
given query (and other planner inputs such as statistics). To experiment given query (and other planner inputs such as statistics). To experiment
with different search paths, try changing <varname>geqo_seed</>. with different search paths, try changing <varname>geqo_seed</varname>.
</para> </para>
</sect2> </sect2>
<sect2 id="geqo-future"> <sect2 id="geqo-future">
<title>Future Implementation Tasks for <title>Future Implementation Tasks for
<productname>PostgreSQL</> <acronym>GEQO</acronym></title> <productname>PostgreSQL</productname> <acronym>GEQO</acronym></title>
<para> <para>
Work is still needed to improve the genetic algorithm parameter Work is still needed to improve the genetic algorithm parameter

View File

@ -21,15 +21,15 @@
</para> </para>
<para> <para>
We use the word <firstterm>item</> to refer to a composite value that We use the word <firstterm>item</firstterm> to refer to a composite value that
is to be indexed, and the word <firstterm>key</> to refer to an element is to be indexed, and the word <firstterm>key</firstterm> to refer to an element
value. <acronym>GIN</acronym> always stores and searches for keys, value. <acronym>GIN</acronym> always stores and searches for keys,
not item values per se. not item values per se.
</para> </para>
<para> <para>
A <acronym>GIN</acronym> index stores a set of (key, posting list) pairs, A <acronym>GIN</acronym> index stores a set of (key, posting list) pairs,
where a <firstterm>posting list</> is a set of row IDs in which the key where a <firstterm>posting list</firstterm> is a set of row IDs in which the key
occurs. The same row ID can appear in multiple posting lists, since occurs. The same row ID can appear in multiple posting lists, since
an item can contain more than one key. Each key value is stored only an item can contain more than one key. Each key value is stored only
once, so a <acronym>GIN</acronym> index is very compact for cases once, so a <acronym>GIN</acronym> index is very compact for cases
@ -66,7 +66,7 @@
<title>Built-in Operator Classes</title> <title>Built-in Operator Classes</title>
<para> <para>
The core <productname>PostgreSQL</> distribution The core <productname>PostgreSQL</productname> distribution
includes the <acronym>GIN</acronym> operator classes shown in includes the <acronym>GIN</acronym> operator classes shown in
<xref linkend="gin-builtin-opclasses-table">. <xref linkend="gin-builtin-opclasses-table">.
(Some of the optional modules described in <xref linkend="contrib"> (Some of the optional modules described in <xref linkend="contrib">
@ -85,38 +85,38 @@
</thead> </thead>
<tbody> <tbody>
<row> <row>
<entry><literal>array_ops</></entry> <entry><literal>array_ops</literal></entry>
<entry><type>anyarray</></entry> <entry><type>anyarray</type></entry>
<entry> <entry>
<literal>&amp;&amp;</> <literal>&amp;&amp;</literal>
<literal>&lt;@</> <literal>&lt;@</literal>
<literal>=</> <literal>=</literal>
<literal>@&gt;</> <literal>@&gt;</literal>
</entry> </entry>
</row> </row>
<row> <row>
<entry><literal>jsonb_ops</></entry> <entry><literal>jsonb_ops</literal></entry>
<entry><type>jsonb</></entry> <entry><type>jsonb</type></entry>
<entry> <entry>
<literal>?</> <literal>?</literal>
<literal>?&amp;</> <literal>?&amp;</literal>
<literal>?|</> <literal>?|</literal>
<literal>@&gt;</> <literal>@&gt;</literal>
</entry> </entry>
</row> </row>
<row> <row>
<entry><literal>jsonb_path_ops</></entry> <entry><literal>jsonb_path_ops</literal></entry>
<entry><type>jsonb</></entry> <entry><type>jsonb</type></entry>
<entry> <entry>
<literal>@&gt;</> <literal>@&gt;</literal>
</entry> </entry>
</row> </row>
<row> <row>
<entry><literal>tsvector_ops</></entry> <entry><literal>tsvector_ops</literal></entry>
<entry><type>tsvector</></entry> <entry><type>tsvector</type></entry>
<entry> <entry>
<literal>@@</> <literal>@@</literal>
<literal>@@@</> <literal>@@@</literal>
</entry> </entry>
</row> </row>
</tbody> </tbody>
@ -124,8 +124,8 @@
</table> </table>
<para> <para>
Of the two operator classes for type <type>jsonb</>, <literal>jsonb_ops</> Of the two operator classes for type <type>jsonb</type>, <literal>jsonb_ops</literal>
is the default. <literal>jsonb_path_ops</> supports fewer operators but is the default. <literal>jsonb_path_ops</literal> supports fewer operators but
offers better performance for those operators. offers better performance for those operators.
See <xref linkend="json-indexing"> for details. See <xref linkend="json-indexing"> for details.
</para> </para>
@ -157,15 +157,15 @@
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><function>Datum *extractValue(Datum itemValue, int32 *nkeys, <term><function>Datum *extractValue(Datum itemValue, int32 *nkeys,
bool **nullFlags)</></term> bool **nullFlags)</function></term>
<listitem> <listitem>
<para> <para>
Returns a palloc'd array of keys given an item to be indexed. The Returns a palloc'd array of keys given an item to be indexed. The
number of returned keys must be stored into <literal>*nkeys</>. number of returned keys must be stored into <literal>*nkeys</literal>.
If any of the keys can be null, also palloc an array of If any of the keys can be null, also palloc an array of
<literal>*nkeys</> <type>bool</type> fields, store its address at <literal>*nkeys</literal> <type>bool</type> fields, store its address at
<literal>*nullFlags</>, and set these null flags as needed. <literal>*nullFlags</literal>, and set these null flags as needed.
<literal>*nullFlags</> can be left <symbol>NULL</symbol> (its initial value) <literal>*nullFlags</literal> can be left <symbol>NULL</symbol> (its initial value)
if all keys are non-null. if all keys are non-null.
The return value can be <symbol>NULL</symbol> if the item contains no keys. The return value can be <symbol>NULL</symbol> if the item contains no keys.
</para> </para>
@ -175,40 +175,40 @@
<varlistentry> <varlistentry>
<term><function>Datum *extractQuery(Datum query, int32 *nkeys, <term><function>Datum *extractQuery(Datum query, int32 *nkeys,
StrategyNumber n, bool **pmatch, Pointer **extra_data, StrategyNumber n, bool **pmatch, Pointer **extra_data,
bool **nullFlags, int32 *searchMode)</></term> bool **nullFlags, int32 *searchMode)</function></term>
<listitem> <listitem>
<para> <para>
Returns a palloc'd array of keys given a value to be queried; that is, Returns a palloc'd array of keys given a value to be queried; that is,
<literal>query</> is the value on the right-hand side of an <literal>query</literal> is the value on the right-hand side of an
indexable operator whose left-hand side is the indexed column. indexable operator whose left-hand side is the indexed column.
<literal>n</> is the strategy number of the operator within the <literal>n</literal> is the strategy number of the operator within the
operator class (see <xref linkend="xindex-strategies">). operator class (see <xref linkend="xindex-strategies">).
Often, <function>extractQuery</> will need Often, <function>extractQuery</function> will need
to consult <literal>n</> to determine the data type of to consult <literal>n</literal> to determine the data type of
<literal>query</> and the method it should use to extract key values. <literal>query</literal> and the method it should use to extract key values.
The number of returned keys must be stored into <literal>*nkeys</>. The number of returned keys must be stored into <literal>*nkeys</literal>.
If any of the keys can be null, also palloc an array of If any of the keys can be null, also palloc an array of
<literal>*nkeys</> <type>bool</type> fields, store its address at <literal>*nkeys</literal> <type>bool</type> fields, store its address at
<literal>*nullFlags</>, and set these null flags as needed. <literal>*nullFlags</literal>, and set these null flags as needed.
<literal>*nullFlags</> can be left <symbol>NULL</symbol> (its initial value) <literal>*nullFlags</literal> can be left <symbol>NULL</symbol> (its initial value)
if all keys are non-null. if all keys are non-null.
The return value can be <symbol>NULL</symbol> if the <literal>query</> contains no keys. The return value can be <symbol>NULL</symbol> if the <literal>query</literal> contains no keys.
</para> </para>
<para> <para>
<literal>searchMode</> is an output argument that allows <literal>searchMode</literal> is an output argument that allows
<function>extractQuery</> to specify details about how the search <function>extractQuery</function> to specify details about how the search
will be done. will be done.
If <literal>*searchMode</> is set to If <literal>*searchMode</literal> is set to
<literal>GIN_SEARCH_MODE_DEFAULT</> (which is the value it is <literal>GIN_SEARCH_MODE_DEFAULT</literal> (which is the value it is
initialized to before call), only items that match at least one of initialized to before call), only items that match at least one of
the returned keys are considered candidate matches. the returned keys are considered candidate matches.
If <literal>*searchMode</> is set to If <literal>*searchMode</literal> is set to
<literal>GIN_SEARCH_MODE_INCLUDE_EMPTY</>, then in addition to items <literal>GIN_SEARCH_MODE_INCLUDE_EMPTY</literal>, then in addition to items
containing at least one matching key, items that contain no keys at containing at least one matching key, items that contain no keys at
all are considered candidate matches. (This mode is useful for all are considered candidate matches. (This mode is useful for
implementing is-subset-of operators, for example.) implementing is-subset-of operators, for example.)
If <literal>*searchMode</> is set to <literal>GIN_SEARCH_MODE_ALL</>, If <literal>*searchMode</literal> is set to <literal>GIN_SEARCH_MODE_ALL</literal>,
then all non-null items in the index are considered candidate then all non-null items in the index are considered candidate
matches, whether they match any of the returned keys or not. (This matches, whether they match any of the returned keys or not. (This
mode is much slower than the other two choices, since it requires mode is much slower than the other two choices, since it requires
@ -217,33 +217,33 @@
in most cases is probably not a good candidate for a GIN operator in most cases is probably not a good candidate for a GIN operator
class.) class.)
The symbols to use for setting this mode are defined in The symbols to use for setting this mode are defined in
<filename>access/gin.h</>. <filename>access/gin.h</filename>.
</para> </para>
<para> <para>
<literal>pmatch</> is an output argument for use when partial match <literal>pmatch</literal> is an output argument for use when partial match
is supported. To use it, <function>extractQuery</> must allocate is supported. To use it, <function>extractQuery</function> must allocate
an array of <literal>*nkeys</> booleans and store its address at an array of <literal>*nkeys</literal> booleans and store its address at
<literal>*pmatch</>. Each element of the array should be set to TRUE <literal>*pmatch</literal>. Each element of the array should be set to TRUE
if the corresponding key requires partial match, FALSE if not. if the corresponding key requires partial match, FALSE if not.
If <literal>*pmatch</> is set to <symbol>NULL</symbol> then GIN assumes partial match If <literal>*pmatch</literal> is set to <symbol>NULL</symbol> then GIN assumes partial match
is not required. The variable is initialized to <symbol>NULL</symbol> before call, is not required. The variable is initialized to <symbol>NULL</symbol> before call,
so this argument can simply be ignored by operator classes that do so this argument can simply be ignored by operator classes that do
not support partial match. not support partial match.
</para> </para>
<para> <para>
<literal>extra_data</> is an output argument that allows <literal>extra_data</literal> is an output argument that allows
<function>extractQuery</> to pass additional data to the <function>extractQuery</function> to pass additional data to the
<function>consistent</> and <function>comparePartial</> methods. <function>consistent</function> and <function>comparePartial</function> methods.
To use it, <function>extractQuery</> must allocate To use it, <function>extractQuery</function> must allocate
an array of <literal>*nkeys</> pointers and store its address at an array of <literal>*nkeys</literal> pointers and store its address at
<literal>*extra_data</>, then store whatever it wants to into the <literal>*extra_data</literal>, then store whatever it wants to into the
individual pointers. The variable is initialized to <symbol>NULL</symbol> before individual pointers. The variable is initialized to <symbol>NULL</symbol> before
call, so this argument can simply be ignored by operator classes that call, so this argument can simply be ignored by operator classes that
do not require extra data. If <literal>*extra_data</> is set, the do not require extra data. If <literal>*extra_data</literal> is set, the
whole array is passed to the <function>consistent</> method, and whole array is passed to the <function>consistent</function> method, and
the appropriate element to the <function>comparePartial</> method. the appropriate element to the <function>comparePartial</function> method.
</para> </para>
</listitem> </listitem>
@ -251,10 +251,10 @@
</variablelist> </variablelist>
An operator class must also provide a function to check if an indexed item An operator class must also provide a function to check if an indexed item
matches the query. It comes in two flavors, a boolean <function>consistent</> matches the query. It comes in two flavors, a boolean <function>consistent</function>
function, and a ternary <function>triConsistent</> function. function, and a ternary <function>triConsistent</function> function.
<function>triConsistent</> covers the functionality of both, so providing <function>triConsistent</function> covers the functionality of both, so providing
<function>triConsistent</> alone is sufficient. However, if the boolean <function>triConsistent</function> alone is sufficient. However, if the boolean
variant is significantly cheaper to calculate, it can be advantageous to variant is significantly cheaper to calculate, it can be advantageous to
provide both. If only the boolean variant is provided, some optimizations provide both. If only the boolean variant is provided, some optimizations
that depend on refuting index items before fetching all the keys are that depend on refuting index items before fetching all the keys are
@ -264,48 +264,48 @@
<varlistentry> <varlistentry>
<term><function>bool consistent(bool check[], StrategyNumber n, Datum query, <term><function>bool consistent(bool check[], StrategyNumber n, Datum query,
int32 nkeys, Pointer extra_data[], bool *recheck, int32 nkeys, Pointer extra_data[], bool *recheck,
Datum queryKeys[], bool nullFlags[])</></term> Datum queryKeys[], bool nullFlags[])</function></term>
<listitem> <listitem>
<para> <para>
Returns TRUE if an indexed item satisfies the query operator with Returns TRUE if an indexed item satisfies the query operator with
strategy number <literal>n</> (or might satisfy it, if the recheck strategy number <literal>n</literal> (or might satisfy it, if the recheck
indication is returned). This function does not have direct access indication is returned). This function does not have direct access
to the indexed item's value, since <acronym>GIN</acronym> does not to the indexed item's value, since <acronym>GIN</acronym> does not
store items explicitly. Rather, what is available is knowledge store items explicitly. Rather, what is available is knowledge
about which key values extracted from the query appear in a given about which key values extracted from the query appear in a given
indexed item. The <literal>check</> array has length indexed item. The <literal>check</literal> array has length
<literal>nkeys</>, which is the same as the number of keys previously <literal>nkeys</literal>, which is the same as the number of keys previously
returned by <function>extractQuery</> for this <literal>query</> datum. returned by <function>extractQuery</function> for this <literal>query</literal> datum.
Each element of the Each element of the
<literal>check</> array is TRUE if the indexed item contains the <literal>check</literal> array is TRUE if the indexed item contains the
corresponding query key, i.e., if (check[i] == TRUE) the i-th key of the corresponding query key, i.e., if (check[i] == TRUE) the i-th key of the
<function>extractQuery</> result array is present in the indexed item. <function>extractQuery</function> result array is present in the indexed item.
The original <literal>query</> datum is The original <literal>query</literal> datum is
passed in case the <function>consistent</> method needs to consult it, passed in case the <function>consistent</function> method needs to consult it,
and so are the <literal>queryKeys[]</> and <literal>nullFlags[]</> and so are the <literal>queryKeys[]</literal> and <literal>nullFlags[]</literal>
arrays previously returned by <function>extractQuery</>. arrays previously returned by <function>extractQuery</function>.
<literal>extra_data</> is the extra-data array returned by <literal>extra_data</literal> is the extra-data array returned by
<function>extractQuery</>, or <symbol>NULL</symbol> if none. <function>extractQuery</function>, or <symbol>NULL</symbol> if none.
</para> </para>
<para> <para>
When <function>extractQuery</> returns a null key in When <function>extractQuery</function> returns a null key in
<literal>queryKeys[]</>, the corresponding <literal>check[]</> element <literal>queryKeys[]</literal>, the corresponding <literal>check[]</literal> element
is TRUE if the indexed item contains a null key; that is, the is TRUE if the indexed item contains a null key; that is, the
semantics of <literal>check[]</> are like <literal>IS NOT DISTINCT semantics of <literal>check[]</literal> are like <literal>IS NOT DISTINCT
FROM</>. The <function>consistent</> function can examine the FROM</literal>. The <function>consistent</function> function can examine the
corresponding <literal>nullFlags[]</> element if it needs to tell corresponding <literal>nullFlags[]</literal> element if it needs to tell
the difference between a regular value match and a null match. the difference between a regular value match and a null match.
</para> </para>
<para> <para>
On success, <literal>*recheck</> should be set to TRUE if the heap On success, <literal>*recheck</literal> should be set to TRUE if the heap
tuple needs to be rechecked against the query operator, or FALSE if tuple needs to be rechecked against the query operator, or FALSE if
the index test is exact. That is, a FALSE return value guarantees the index test is exact. That is, a FALSE return value guarantees
that the heap tuple does not match the query; a TRUE return value with that the heap tuple does not match the query; a TRUE return value with
<literal>*recheck</> set to FALSE guarantees that the heap tuple does <literal>*recheck</literal> set to FALSE guarantees that the heap tuple does
match the query; and a TRUE return value with match the query; and a TRUE return value with
<literal>*recheck</> set to TRUE means that the heap tuple might match <literal>*recheck</literal> set to TRUE means that the heap tuple might match
the query, so it needs to be fetched and rechecked by evaluating the the query, so it needs to be fetched and rechecked by evaluating the
query operator directly against the originally indexed item. query operator directly against the originally indexed item.
</para> </para>
@ -315,30 +315,30 @@
<varlistentry> <varlistentry>
<term><function>GinTernaryValue triConsistent(GinTernaryValue check[], StrategyNumber n, Datum query, <term><function>GinTernaryValue triConsistent(GinTernaryValue check[], StrategyNumber n, Datum query,
int32 nkeys, Pointer extra_data[], int32 nkeys, Pointer extra_data[],
Datum queryKeys[], bool nullFlags[])</></term> Datum queryKeys[], bool nullFlags[])</function></term>
<listitem> <listitem>
<para> <para>
<function>triConsistent</> is similar to <function>consistent</>, <function>triConsistent</function> is similar to <function>consistent</function>,
but instead of booleans in the <literal>check</> vector, there are but instead of booleans in the <literal>check</literal> vector, there are
three possible values for each three possible values for each
key: <literal>GIN_TRUE</>, <literal>GIN_FALSE</> and key: <literal>GIN_TRUE</literal>, <literal>GIN_FALSE</literal> and
<literal>GIN_MAYBE</>. <literal>GIN_FALSE</> and <literal>GIN_TRUE</> <literal>GIN_MAYBE</literal>. <literal>GIN_FALSE</literal> and <literal>GIN_TRUE</literal>
have the same meaning as regular boolean values, while have the same meaning as regular boolean values, while
<literal>GIN_MAYBE</> means that the presence of that key is not known. <literal>GIN_MAYBE</literal> means that the presence of that key is not known.
When <literal>GIN_MAYBE</> values are present, the function should only When <literal>GIN_MAYBE</literal> values are present, the function should only
return <literal>GIN_TRUE</> if the item certainly matches whether or return <literal>GIN_TRUE</literal> if the item certainly matches whether or
not the index item contains the corresponding query keys. Likewise, the not the index item contains the corresponding query keys. Likewise, the
function must return <literal>GIN_FALSE</> only if the item certainly function must return <literal>GIN_FALSE</literal> only if the item certainly
does not match, whether or not it contains the <literal>GIN_MAYBE</> does not match, whether or not it contains the <literal>GIN_MAYBE</literal>
keys. If the result depends on the <literal>GIN_MAYBE</> entries, i.e., keys. If the result depends on the <literal>GIN_MAYBE</literal> entries, i.e.,
the match cannot be confirmed or refuted based on the known query keys, the match cannot be confirmed or refuted based on the known query keys,
the function must return <literal>GIN_MAYBE</>. the function must return <literal>GIN_MAYBE</literal>.
</para> </para>
<para> <para>
When there are no <literal>GIN_MAYBE</> values in the <literal>check</> When there are no <literal>GIN_MAYBE</literal> values in the <literal>check</literal>
vector, a <literal>GIN_MAYBE</> return value is the equivalent of vector, a <literal>GIN_MAYBE</literal> return value is the equivalent of
setting the <literal>recheck</> flag in the setting the <literal>recheck</literal> flag in the
boolean <function>consistent</> function. boolean <function>consistent</function> function.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -352,7 +352,7 @@
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><function>int compare(Datum a, Datum b)</></term> <term><function>int compare(Datum a, Datum b)</function></term>
<listitem> <listitem>
<para> <para>
Compares two keys (not indexed items!) and returns an integer less than Compares two keys (not indexed items!) and returns an integer less than
@ -364,13 +364,13 @@
</varlistentry> </varlistentry>
</variablelist> </variablelist>
Alternatively, if the operator class does not provide a <function>compare</> Alternatively, if the operator class does not provide a <function>compare</function>
method, GIN will look up the default btree operator class for the index method, GIN will look up the default btree operator class for the index
key data type, and use its comparison function. It is recommended to key data type, and use its comparison function. It is recommended to
specify the comparison function in a GIN operator class that is meant for specify the comparison function in a GIN operator class that is meant for
just one data type, as looking up the btree operator class costs a few just one data type, as looking up the btree operator class costs a few
cycles. However, polymorphic GIN operator classes (such cycles. However, polymorphic GIN operator classes (such
as <literal>array_ops</>) typically cannot specify a single comparison as <literal>array_ops</literal>) typically cannot specify a single comparison
function. function.
</para> </para>
@ -381,7 +381,7 @@
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><function>int comparePartial(Datum partial_key, Datum key, StrategyNumber n, <term><function>int comparePartial(Datum partial_key, Datum key, StrategyNumber n,
Pointer extra_data)</></term> Pointer extra_data)</function></term>
<listitem> <listitem>
<para> <para>
Compare a partial-match query key to an index key. Returns an integer Compare a partial-match query key to an index key. Returns an integer
@ -389,11 +389,11 @@
does not match the query, but the index scan should continue; zero does not match the query, but the index scan should continue; zero
means that the index key does match the query; greater than zero means that the index key does match the query; greater than zero
indicates that the index scan should stop because no more matches indicates that the index scan should stop because no more matches
are possible. The strategy number <literal>n</> of the operator are possible. The strategy number <literal>n</literal> of the operator
that generated the partial match query is provided, in case its that generated the partial match query is provided, in case its
semantics are needed to determine when to end the scan. Also, semantics are needed to determine when to end the scan. Also,
<literal>extra_data</> is the corresponding element of the extra-data <literal>extra_data</literal> is the corresponding element of the extra-data
array made by <function>extractQuery</>, or <symbol>NULL</symbol> if none. array made by <function>extractQuery</function>, or <symbol>NULL</symbol> if none.
Null keys are never passed to this function. Null keys are never passed to this function.
</para> </para>
</listitem> </listitem>
@ -402,25 +402,25 @@
</para> </para>
<para> <para>
To support <quote>partial match</> queries, an operator class must To support <quote>partial match</quote> queries, an operator class must
provide the <function>comparePartial</> method, and its provide the <function>comparePartial</function> method, and its
<function>extractQuery</> method must set the <literal>pmatch</> <function>extractQuery</function> method must set the <literal>pmatch</literal>
parameter when a partial-match query is encountered. See parameter when a partial-match query is encountered. See
<xref linkend="gin-partial-match"> for details. <xref linkend="gin-partial-match"> for details.
</para> </para>
<para> <para>
The actual data types of the various <literal>Datum</> values mentioned The actual data types of the various <literal>Datum</literal> values mentioned
above vary depending on the operator class. The item values passed to above vary depending on the operator class. The item values passed to
<function>extractValue</> are always of the operator class's input type, and <function>extractValue</function> are always of the operator class's input type, and
all key values must be of the class's <literal>STORAGE</> type. The type of all key values must be of the class's <literal>STORAGE</literal> type. The type of
the <literal>query</> argument passed to <function>extractQuery</>, the <literal>query</literal> argument passed to <function>extractQuery</function>,
<function>consistent</> and <function>triConsistent</> is whatever is the <function>consistent</function> and <function>triConsistent</function> is whatever is the
right-hand input type of the class member operator identified by the right-hand input type of the class member operator identified by the
strategy number. This need not be the same as the indexed type, so long as strategy number. This need not be the same as the indexed type, so long as
key values of the correct type can be extracted from it. However, it is key values of the correct type can be extracted from it. However, it is
recommended that the SQL declarations of these three support functions use recommended that the SQL declarations of these three support functions use
the opclass's indexed data type for the <literal>query</> argument, even the opclass's indexed data type for the <literal>query</literal> argument, even
though the actual type might be something else depending on the operator. though the actual type might be something else depending on the operator.
</para> </para>
@ -434,8 +434,8 @@
constructed over keys, where each key is an element of one or more indexed constructed over keys, where each key is an element of one or more indexed
items (a member of an array, for example) and where each tuple in a leaf items (a member of an array, for example) and where each tuple in a leaf
page contains either a pointer to a B-tree of heap pointers (a page contains either a pointer to a B-tree of heap pointers (a
<quote>posting tree</>), or a simple list of heap pointers (a <quote>posting <quote>posting tree</quote>), or a simple list of heap pointers (a <quote>posting
list</>) when the list is small enough to fit into a single index tuple along list</quote>) when the list is small enough to fit into a single index tuple along
with the key value. with the key value.
</para> </para>
@ -443,7 +443,7 @@
As of <productname>PostgreSQL</productname> 9.1, null key values can be As of <productname>PostgreSQL</productname> 9.1, null key values can be
included in the index. Also, placeholder nulls are included in the index included in the index. Also, placeholder nulls are included in the index
for indexed items that are null or contain no keys according to for indexed items that are null or contain no keys according to
<function>extractValue</>. This allows searches that should find empty <function>extractValue</function>. This allows searches that should find empty
items to do so. items to do so.
</para> </para>
@ -461,7 +461,7 @@
intrinsic nature of inverted indexes: inserting or updating one heap row intrinsic nature of inverted indexes: inserting or updating one heap row
can cause many inserts into the index (one for each key extracted can cause many inserts into the index (one for each key extracted
from the indexed item). As of <productname>PostgreSQL</productname> 8.4, from the indexed item). As of <productname>PostgreSQL</productname> 8.4,
<acronym>GIN</> is capable of postponing much of this work by inserting <acronym>GIN</acronym> is capable of postponing much of this work by inserting
new tuples into a temporary, unsorted list of pending entries. new tuples into a temporary, unsorted list of pending entries.
When the table is vacuumed or autoanalyzed, or when When the table is vacuumed or autoanalyzed, or when
<function>gin_clean_pending_list</function> function is called, or if the <function>gin_clean_pending_list</function> function is called, or if the
@ -479,7 +479,7 @@
of pending entries in addition to searching the regular index, and so of pending entries in addition to searching the regular index, and so
a large list of pending entries will slow searches significantly. a large list of pending entries will slow searches significantly.
Another disadvantage is that, while most updates are fast, an update Another disadvantage is that, while most updates are fast, an update
that causes the pending list to become <quote>too large</> will incur an that causes the pending list to become <quote>too large</quote> will incur an
immediate cleanup cycle and thus be much slower than other updates. immediate cleanup cycle and thus be much slower than other updates.
Proper use of autovacuum can minimize both of these problems. Proper use of autovacuum can minimize both of these problems.
</para> </para>
@ -497,15 +497,15 @@
<title>Partial Match Algorithm</title> <title>Partial Match Algorithm</title>
<para> <para>
GIN can support <quote>partial match</> queries, in which the query GIN can support <quote>partial match</quote> queries, in which the query
does not determine an exact match for one or more keys, but the possible does not determine an exact match for one or more keys, but the possible
matches fall within a reasonably narrow range of key values (within the matches fall within a reasonably narrow range of key values (within the
key sorting order determined by the <function>compare</> support method). key sorting order determined by the <function>compare</function> support method).
The <function>extractQuery</> method, instead of returning a key value The <function>extractQuery</function> method, instead of returning a key value
to be matched exactly, returns a key value that is the lower bound of to be matched exactly, returns a key value that is the lower bound of
the range to be searched, and sets the <literal>pmatch</> flag true. the range to be searched, and sets the <literal>pmatch</literal> flag true.
The key range is then scanned using the <function>comparePartial</> The key range is then scanned using the <function>comparePartial</function>
method. <function>comparePartial</> must return zero for a matching method. <function>comparePartial</function> must return zero for a matching
index key, less than zero for a non-match that is still within the range index key, less than zero for a non-match that is still within the range
to be searched, or greater than zero if the index key is past the range to be searched, or greater than zero if the index key is past the range
that could match. that could match.
@ -542,7 +542,7 @@
<listitem> <listitem>
<para> <para>
Build time for a <acronym>GIN</acronym> index is very sensitive to Build time for a <acronym>GIN</acronym> index is very sensitive to
the <varname>maintenance_work_mem</> setting; it doesn't pay to the <varname>maintenance_work_mem</varname> setting; it doesn't pay to
skimp on work memory during index creation. skimp on work memory during index creation.
</para> </para>
</listitem> </listitem>
@ -553,18 +553,18 @@
<listitem> <listitem>
<para> <para>
During a series of insertions into an existing <acronym>GIN</acronym> During a series of insertions into an existing <acronym>GIN</acronym>
index that has <literal>fastupdate</> enabled, the system will clean up index that has <literal>fastupdate</literal> enabled, the system will clean up
the pending-entry list whenever the list grows larger than the pending-entry list whenever the list grows larger than
<varname>gin_pending_list_limit</>. To avoid fluctuations in observed <varname>gin_pending_list_limit</varname>. To avoid fluctuations in observed
response time, it's desirable to have pending-list cleanup occur in the response time, it's desirable to have pending-list cleanup occur in the
background (i.e., via autovacuum). Foreground cleanup operations background (i.e., via autovacuum). Foreground cleanup operations
can be avoided by increasing <varname>gin_pending_list_limit</> can be avoided by increasing <varname>gin_pending_list_limit</varname>
or making autovacuum more aggressive. or making autovacuum more aggressive.
However, enlarging the threshold of the cleanup operation means that However, enlarging the threshold of the cleanup operation means that
if a foreground cleanup does occur, it will take even longer. if a foreground cleanup does occur, it will take even longer.
</para> </para>
<para> <para>
<varname>gin_pending_list_limit</> can be overridden for individual <varname>gin_pending_list_limit</varname> can be overridden for individual
GIN indexes by changing storage parameters, and which allows each GIN indexes by changing storage parameters, and which allows each
GIN index to have its own cleanup threshold. GIN index to have its own cleanup threshold.
For example, it's possible to increase the threshold only for the GIN For example, it's possible to increase the threshold only for the GIN
@ -616,7 +616,7 @@
<para> <para>
<acronym>GIN</acronym> assumes that indexable operators are strict. This <acronym>GIN</acronym> assumes that indexable operators are strict. This
means that <function>extractValue</> will not be called at all on a null means that <function>extractValue</function> will not be called at all on a null
item value (instead, a placeholder index entry is created automatically), item value (instead, a placeholder index entry is created automatically),
and <function>extractQuery</function> will not be called on a null query and <function>extractQuery</function> will not be called on a null query
value either (instead, the query is presumed to be unsatisfiable). Note value either (instead, the query is presumed to be unsatisfiable). Note
@ -629,36 +629,36 @@
<title>Examples</title> <title>Examples</title>
<para> <para>
The core <productname>PostgreSQL</> distribution The core <productname>PostgreSQL</productname> distribution
includes the <acronym>GIN</acronym> operator classes previously shown in includes the <acronym>GIN</acronym> operator classes previously shown in
<xref linkend="gin-builtin-opclasses-table">. <xref linkend="gin-builtin-opclasses-table">.
The following <filename>contrib</> modules also contain The following <filename>contrib</filename> modules also contain
<acronym>GIN</acronym> operator classes: <acronym>GIN</acronym> operator classes:
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><filename>btree_gin</></term> <term><filename>btree_gin</filename></term>
<listitem> <listitem>
<para>B-tree equivalent functionality for several data types</para> <para>B-tree equivalent functionality for several data types</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><filename>hstore</></term> <term><filename>hstore</filename></term>
<listitem> <listitem>
<para>Module for storing (key, value) pairs</para> <para>Module for storing (key, value) pairs</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><filename>intarray</></term> <term><filename>intarray</filename></term>
<listitem> <listitem>
<para>Enhanced support for <type>int[]</type></para> <para>Enhanced support for <type>int[]</type></para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><filename>pg_trgm</></term> <term><filename>pg_trgm</filename></term>
<listitem> <listitem>
<para>Text similarity using trigram matching</para> <para>Text similarity using trigram matching</para>
</listitem> </listitem>

View File

@ -44,7 +44,7 @@
<title>Built-in Operator Classes</title> <title>Built-in Operator Classes</title>
<para> <para>
The core <productname>PostgreSQL</> distribution The core <productname>PostgreSQL</productname> distribution
includes the <acronym>GiST</acronym> operator classes shown in includes the <acronym>GiST</acronym> operator classes shown in
<xref linkend="gist-builtin-opclasses-table">. <xref linkend="gist-builtin-opclasses-table">.
(Some of the optional modules described in <xref linkend="contrib"> (Some of the optional modules described in <xref linkend="contrib">
@ -64,142 +64,142 @@
</thead> </thead>
<tbody> <tbody>
<row> <row>
<entry><literal>box_ops</></entry> <entry><literal>box_ops</literal></entry>
<entry><type>box</></entry> <entry><type>box</type></entry>
<entry> <entry>
<literal>&amp;&amp;</> <literal>&amp;&amp;</literal>
<literal>&amp;&gt;</> <literal>&amp;&gt;</literal>
<literal>&amp;&lt;</> <literal>&amp;&lt;</literal>
<literal>&amp;&lt;|</> <literal>&amp;&lt;|</literal>
<literal>&gt;&gt;</> <literal>&gt;&gt;</literal>
<literal>&lt;&lt;</> <literal>&lt;&lt;</literal>
<literal>&lt;&lt;|</> <literal>&lt;&lt;|</literal>
<literal>&lt;@</> <literal>&lt;@</literal>
<literal>@&gt;</> <literal>@&gt;</literal>
<literal>@</> <literal>@</literal>
<literal>|&amp;&gt;</> <literal>|&amp;&gt;</literal>
<literal>|&gt;&gt;</> <literal>|&gt;&gt;</literal>
<literal>~</> <literal>~</literal>
<literal>~=</> <literal>~=</literal>
</entry> </entry>
<entry> <entry>
</entry> </entry>
</row> </row>
<row> <row>
<entry><literal>circle_ops</></entry> <entry><literal>circle_ops</literal></entry>
<entry><type>circle</></entry> <entry><type>circle</type></entry>
<entry> <entry>
<literal>&amp;&amp;</> <literal>&amp;&amp;</literal>
<literal>&amp;&gt;</> <literal>&amp;&gt;</literal>
<literal>&amp;&lt;</> <literal>&amp;&lt;</literal>
<literal>&amp;&lt;|</> <literal>&amp;&lt;|</literal>
<literal>&gt;&gt;</> <literal>&gt;&gt;</literal>
<literal>&lt;&lt;</> <literal>&lt;&lt;</literal>
<literal>&lt;&lt;|</> <literal>&lt;&lt;|</literal>
<literal>&lt;@</> <literal>&lt;@</literal>
<literal>@&gt;</> <literal>@&gt;</literal>
<literal>@</> <literal>@</literal>
<literal>|&amp;&gt;</> <literal>|&amp;&gt;</literal>
<literal>|&gt;&gt;</> <literal>|&gt;&gt;</literal>
<literal>~</> <literal>~</literal>
<literal>~=</> <literal>~=</literal>
</entry> </entry>
<entry> <entry>
<literal>&lt;-&gt;</> <literal>&lt;-&gt;</literal>
</entry> </entry>
</row> </row>
<row> <row>
<entry><literal>inet_ops</></entry> <entry><literal>inet_ops</literal></entry>
<entry><type>inet</>, <type>cidr</></entry> <entry><type>inet</type>, <type>cidr</type></entry>
<entry> <entry>
<literal>&amp;&amp;</> <literal>&amp;&amp;</literal>
<literal>&gt;&gt;</> <literal>&gt;&gt;</literal>
<literal>&gt;&gt;=</> <literal>&gt;&gt;=</literal>
<literal>&gt;</> <literal>&gt;</literal>
<literal>&gt;=</> <literal>&gt;=</literal>
<literal>&lt;&gt;</> <literal>&lt;&gt;</literal>
<literal>&lt;&lt;</> <literal>&lt;&lt;</literal>
<literal>&lt;&lt;=</> <literal>&lt;&lt;=</literal>
<literal>&lt;</> <literal>&lt;</literal>
<literal>&lt;=</> <literal>&lt;=</literal>
<literal>=</> <literal>=</literal>
</entry> </entry>
<entry> <entry>
</entry> </entry>
</row> </row>
<row> <row>
<entry><literal>point_ops</></entry> <entry><literal>point_ops</literal></entry>
<entry><type>point</></entry> <entry><type>point</type></entry>
<entry> <entry>
<literal>&gt;&gt;</> <literal>&gt;&gt;</literal>
<literal>&gt;^</> <literal>&gt;^</literal>
<literal>&lt;&lt;</> <literal>&lt;&lt;</literal>
<literal>&lt;@</> <literal>&lt;@</literal>
<literal>&lt;@</> <literal>&lt;@</literal>
<literal>&lt;@</> <literal>&lt;@</literal>
<literal>&lt;^</> <literal>&lt;^</literal>
<literal>~=</> <literal>~=</literal>
</entry> </entry>
<entry> <entry>
<literal>&lt;-&gt;</> <literal>&lt;-&gt;</literal>
</entry> </entry>
</row> </row>
<row> <row>
<entry><literal>poly_ops</></entry> <entry><literal>poly_ops</literal></entry>
<entry><type>polygon</></entry> <entry><type>polygon</type></entry>
<entry> <entry>
<literal>&amp;&amp;</> <literal>&amp;&amp;</literal>
<literal>&amp;&gt;</> <literal>&amp;&gt;</literal>
<literal>&amp;&lt;</> <literal>&amp;&lt;</literal>
<literal>&amp;&lt;|</> <literal>&amp;&lt;|</literal>
<literal>&gt;&gt;</> <literal>&gt;&gt;</literal>
<literal>&lt;&lt;</> <literal>&lt;&lt;</literal>
<literal>&lt;&lt;|</> <literal>&lt;&lt;|</literal>
<literal>&lt;@</> <literal>&lt;@</literal>
<literal>@&gt;</> <literal>@&gt;</literal>
<literal>@</> <literal>@</literal>
<literal>|&amp;&gt;</> <literal>|&amp;&gt;</literal>
<literal>|&gt;&gt;</> <literal>|&gt;&gt;</literal>
<literal>~</> <literal>~</literal>
<literal>~=</> <literal>~=</literal>
</entry> </entry>
<entry> <entry>
<literal>&lt;-&gt;</> <literal>&lt;-&gt;</literal>
</entry> </entry>
</row> </row>
<row> <row>
<entry><literal>range_ops</></entry> <entry><literal>range_ops</literal></entry>
<entry>any range type</entry> <entry>any range type</entry>
<entry> <entry>
<literal>&amp;&amp;</> <literal>&amp;&amp;</literal>
<literal>&amp;&gt;</> <literal>&amp;&gt;</literal>
<literal>&amp;&lt;</> <literal>&amp;&lt;</literal>
<literal>&gt;&gt;</> <literal>&gt;&gt;</literal>
<literal>&lt;&lt;</> <literal>&lt;&lt;</literal>
<literal>&lt;@</> <literal>&lt;@</literal>
<literal>-|-</> <literal>-|-</literal>
<literal>=</> <literal>=</literal>
<literal>@&gt;</> <literal>@&gt;</literal>
<literal>@&gt;</> <literal>@&gt;</literal>
</entry> </entry>
<entry> <entry>
</entry> </entry>
</row> </row>
<row> <row>
<entry><literal>tsquery_ops</></entry> <entry><literal>tsquery_ops</literal></entry>
<entry><type>tsquery</></entry> <entry><type>tsquery</type></entry>
<entry> <entry>
<literal>&lt;@</> <literal>&lt;@</literal>
<literal>@&gt;</> <literal>@&gt;</literal>
</entry> </entry>
<entry> <entry>
</entry> </entry>
</row> </row>
<row> <row>
<entry><literal>tsvector_ops</></entry> <entry><literal>tsvector_ops</literal></entry>
<entry><type>tsvector</></entry> <entry><type>tsvector</type></entry>
<entry> <entry>
<literal>@@</> <literal>@@</literal>
</entry> </entry>
<entry> <entry>
</entry> </entry>
@ -209,9 +209,9 @@
</table> </table>
<para> <para>
For historical reasons, the <literal>inet_ops</> operator class is For historical reasons, the <literal>inet_ops</literal> operator class is
not the default class for types <type>inet</> and <type>cidr</>. not the default class for types <type>inet</type> and <type>cidr</type>.
To use it, mention the class name in <command>CREATE INDEX</>, To use it, mention the class name in <command>CREATE INDEX</command>,
for example for example
<programlisting> <programlisting>
CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops);
@ -270,53 +270,53 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops);
There are five methods that an index operator class for There are five methods that an index operator class for
<acronym>GiST</acronym> must provide, and four that are optional. <acronym>GiST</acronym> must provide, and four that are optional.
Correctness of the index is ensured Correctness of the index is ensured
by proper implementation of the <function>same</>, <function>consistent</> by proper implementation of the <function>same</function>, <function>consistent</function>
and <function>union</> methods, while efficiency (size and speed) of the and <function>union</function> methods, while efficiency (size and speed) of the
index will depend on the <function>penalty</> and <function>picksplit</> index will depend on the <function>penalty</function> and <function>picksplit</function>
methods. methods.
Two optional methods are <function>compress</> and Two optional methods are <function>compress</function> and
<function>decompress</>, which allow an index to have internal tree data of <function>decompress</function>, which allow an index to have internal tree data of
a different type than the data it indexes. The leaves are to be of the a different type than the data it indexes. The leaves are to be of the
indexed data type, while the other tree nodes can be of any C struct (but indexed data type, while the other tree nodes can be of any C struct (but
you still have to follow <productname>PostgreSQL</> data type rules here, you still have to follow <productname>PostgreSQL</productname> data type rules here,
see about <literal>varlena</> for variable sized data). If the tree's see about <literal>varlena</literal> for variable sized data). If the tree's
internal data type exists at the SQL level, the <literal>STORAGE</> option internal data type exists at the SQL level, the <literal>STORAGE</literal> option
of the <command>CREATE OPERATOR CLASS</> command can be used. of the <command>CREATE OPERATOR CLASS</command> command can be used.
The optional eighth method is <function>distance</>, which is needed The optional eighth method is <function>distance</function>, which is needed
if the operator class wishes to support ordered scans (nearest-neighbor if the operator class wishes to support ordered scans (nearest-neighbor
searches). The optional ninth method <function>fetch</> is needed if the searches). The optional ninth method <function>fetch</function> is needed if the
operator class wishes to support index-only scans, except when the operator class wishes to support index-only scans, except when the
<function>compress</> method is omitted. <function>compress</function> method is omitted.
</para> </para>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><function>consistent</></term> <term><function>consistent</function></term>
<listitem> <listitem>
<para> <para>
Given an index entry <literal>p</> and a query value <literal>q</>, Given an index entry <literal>p</literal> and a query value <literal>q</literal>,
this function determines whether the index entry is this function determines whether the index entry is
<quote>consistent</> with the query; that is, could the predicate <quote>consistent</quote> with the query; that is, could the predicate
<quote><replaceable>indexed_column</> <quote><replaceable>indexed_column</replaceable>
<replaceable>indexable_operator</> <literal>q</></quote> be true for <replaceable>indexable_operator</replaceable> <literal>q</literal></quote> be true for
any row represented by the index entry? For a leaf index entry this is any row represented by the index entry? For a leaf index entry this is
equivalent to testing the indexable condition, while for an internal equivalent to testing the indexable condition, while for an internal
tree node this determines whether it is necessary to scan the subtree tree node this determines whether it is necessary to scan the subtree
of the index represented by the tree node. When the result is of the index represented by the tree node. When the result is
<literal>true</>, a <literal>recheck</> flag must also be returned. <literal>true</literal>, a <literal>recheck</literal> flag must also be returned.
This indicates whether the predicate is certainly true or only possibly This indicates whether the predicate is certainly true or only possibly
true. If <literal>recheck</> = <literal>false</> then the index has true. If <literal>recheck</literal> = <literal>false</literal> then the index has
tested the predicate condition exactly, whereas if <literal>recheck</> tested the predicate condition exactly, whereas if <literal>recheck</literal>
= <literal>true</> the row is only a candidate match. In that case the = <literal>true</literal> the row is only a candidate match. In that case the
system will automatically evaluate the system will automatically evaluate the
<replaceable>indexable_operator</> against the actual row value to see <replaceable>indexable_operator</replaceable> against the actual row value to see
if it is really a match. This convention allows if it is really a match. This convention allows
<acronym>GiST</acronym> to support both lossless and lossy index <acronym>GiST</acronym> to support both lossless and lossy index
structures. structures.
</para> </para>
<para> <para>
The <acronym>SQL</> declaration of the function must look like this: The <acronym>SQL</acronym> declaration of the function must look like this:
<programlisting> <programlisting>
CREATE OR REPLACE FUNCTION my_consistent(internal, data_type, smallint, oid, internal) CREATE OR REPLACE FUNCTION my_consistent(internal, data_type, smallint, oid, internal)
@ -356,23 +356,23 @@ my_consistent(PG_FUNCTION_ARGS)
} }
</programlisting> </programlisting>
Here, <varname>key</> is an element in the index and <varname>query</> Here, <varname>key</varname> is an element in the index and <varname>query</varname>
the value being looked up in the index. The <literal>StrategyNumber</> the value being looked up in the index. The <literal>StrategyNumber</literal>
parameter indicates which operator of your operator class is being parameter indicates which operator of your operator class is being
applied &mdash; it matches one of the operator numbers in the applied &mdash; it matches one of the operator numbers in the
<command>CREATE OPERATOR CLASS</> command. <command>CREATE OPERATOR CLASS</command> command.
</para> </para>
<para> <para>
Depending on which operators you have included in the class, the data Depending on which operators you have included in the class, the data
type of <varname>query</> could vary with the operator, since it will type of <varname>query</varname> could vary with the operator, since it will
be whatever type is on the righthand side of the operator, which might be whatever type is on the righthand side of the operator, which might
be different from the indexed data type appearing on the lefthand side. be different from the indexed data type appearing on the lefthand side.
(The above code skeleton assumes that only one type is possible; if (The above code skeleton assumes that only one type is possible; if
not, fetching the <varname>query</> argument value would have to depend not, fetching the <varname>query</varname> argument value would have to depend
on the operator.) It is recommended that the SQL declaration of on the operator.) It is recommended that the SQL declaration of
the <function>consistent</> function use the opclass's indexed data the <function>consistent</function> function use the opclass's indexed data
type for the <varname>query</> argument, even though the actual type type for the <varname>query</varname> argument, even though the actual type
might be something else depending on the operator. might be something else depending on the operator.
</para> </para>
@ -380,7 +380,7 @@ my_consistent(PG_FUNCTION_ARGS)
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><function>union</></term> <term><function>union</function></term>
<listitem> <listitem>
<para> <para>
This method consolidates information in the tree. Given a set of This method consolidates information in the tree. Given a set of
@ -389,7 +389,7 @@ my_consistent(PG_FUNCTION_ARGS)
</para> </para>
<para> <para>
The <acronym>SQL</> declaration of the function must look like this: The <acronym>SQL</acronym> declaration of the function must look like this:
<programlisting> <programlisting>
CREATE OR REPLACE FUNCTION my_union(internal, internal) CREATE OR REPLACE FUNCTION my_union(internal, internal)
@ -439,44 +439,44 @@ my_union(PG_FUNCTION_ARGS)
<para> <para>
As you can see, in this skeleton we're dealing with a data type As you can see, in this skeleton we're dealing with a data type
where <literal>union(X, Y, Z) = union(union(X, Y), Z)</>. It's easy where <literal>union(X, Y, Z) = union(union(X, Y), Z)</literal>. It's easy
enough to support data types where this is not the case, by enough to support data types where this is not the case, by
implementing the proper union algorithm in this implementing the proper union algorithm in this
<acronym>GiST</> support method. <acronym>GiST</acronym> support method.
</para> </para>
<para> <para>
The result of the <function>union</> function must be a value of the The result of the <function>union</function> function must be a value of the
index's storage type, whatever that is (it might or might not be index's storage type, whatever that is (it might or might not be
different from the indexed column's type). The <function>union</> different from the indexed column's type). The <function>union</function>
function should return a pointer to newly <function>palloc()</>ed function should return a pointer to newly <function>palloc()</function>ed
memory. You can't just return the input value as-is, even if there is memory. You can't just return the input value as-is, even if there is
no type change. no type change.
</para> </para>
<para> <para>
As shown above, the <function>union</> function's As shown above, the <function>union</function> function's
first <type>internal</> argument is actually first <type>internal</type> argument is actually
a <structname>GistEntryVector</> pointer. The second argument is a a <structname>GistEntryVector</structname> pointer. The second argument is a
pointer to an integer variable, which can be ignored. (It used to be pointer to an integer variable, which can be ignored. (It used to be
required that the <function>union</> function store the size of its required that the <function>union</function> function store the size of its
result value into that variable, but this is no longer necessary.) result value into that variable, but this is no longer necessary.)
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><function>compress</></term> <term><function>compress</function></term>
<listitem> <listitem>
<para> <para>
Converts a data item into a format suitable for physical storage in Converts a data item into a format suitable for physical storage in
an index page. an index page.
If the <function>compress</> method is omitted, data items are stored If the <function>compress</function> method is omitted, data items are stored
in the index without modification. in the index without modification.
</para> </para>
<para> <para>
The <acronym>SQL</> declaration of the function must look like this: The <acronym>SQL</acronym> declaration of the function must look like this:
<programlisting> <programlisting>
CREATE OR REPLACE FUNCTION my_compress(internal) CREATE OR REPLACE FUNCTION my_compress(internal)
@ -519,7 +519,7 @@ my_compress(PG_FUNCTION_ARGS)
</para> </para>
<para> <para>
You have to adapt <replaceable>compressed_data_type</> to the specific You have to adapt <replaceable>compressed_data_type</replaceable> to the specific
type you're converting to in order to compress your leaf nodes, of type you're converting to in order to compress your leaf nodes, of
course. course.
</para> </para>
@ -527,24 +527,24 @@ my_compress(PG_FUNCTION_ARGS)
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><function>decompress</></term> <term><function>decompress</function></term>
<listitem> <listitem>
<para> <para>
Converts the stored representation of a data item into a format that Converts the stored representation of a data item into a format that
can be manipulated by the other GiST methods in the operator class. can be manipulated by the other GiST methods in the operator class.
If the <function>decompress</> method is omitted, it is assumed that If the <function>decompress</function> method is omitted, it is assumed that
the other GiST methods can work directly on the stored data format. the other GiST methods can work directly on the stored data format.
(<function>decompress</> is not necessarily the reverse of (<function>decompress</function> is not necessarily the reverse of
the <function>compress</function> method; in particular, the <function>compress</function> method; in particular,
if <function>compress</function> is lossy then it's impossible if <function>compress</function> is lossy then it's impossible
for <function>decompress</> to exactly reconstruct the original for <function>decompress</function> to exactly reconstruct the original
data. <function>decompress</> is not necessarily equivalent data. <function>decompress</function> is not necessarily equivalent
to <function>fetch</>, either, since the other GiST methods might not to <function>fetch</function>, either, since the other GiST methods might not
require full reconstruction of the data.) require full reconstruction of the data.)
</para> </para>
<para> <para>
The <acronym>SQL</> declaration of the function must look like this: The <acronym>SQL</acronym> declaration of the function must look like this:
<programlisting> <programlisting>
CREATE OR REPLACE FUNCTION my_decompress(internal) CREATE OR REPLACE FUNCTION my_decompress(internal)
@ -573,7 +573,7 @@ my_decompress(PG_FUNCTION_ARGS)
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><function>penalty</></term> <term><function>penalty</function></term>
<listitem> <listitem>
<para> <para>
Returns a value indicating the <quote>cost</quote> of inserting the new Returns a value indicating the <quote>cost</quote> of inserting the new
@ -584,7 +584,7 @@ my_decompress(PG_FUNCTION_ARGS)
</para> </para>
<para> <para>
The <acronym>SQL</> declaration of the function must look like this: The <acronym>SQL</acronym> declaration of the function must look like this:
<programlisting> <programlisting>
CREATE OR REPLACE FUNCTION my_penalty(internal, internal, internal) CREATE OR REPLACE FUNCTION my_penalty(internal, internal, internal)
@ -612,15 +612,15 @@ my_penalty(PG_FUNCTION_ARGS)
} }
</programlisting> </programlisting>
For historical reasons, the <function>penalty</> function doesn't For historical reasons, the <function>penalty</function> function doesn't
just return a <type>float</> result; instead it has to store the value just return a <type>float</type> result; instead it has to store the value
at the location indicated by the third argument. The return at the location indicated by the third argument. The return
value per se is ignored, though it's conventional to pass back the value per se is ignored, though it's conventional to pass back the
address of that argument. address of that argument.
</para> </para>
<para> <para>
The <function>penalty</> function is crucial to good performance of The <function>penalty</function> function is crucial to good performance of
the index. It'll get used at insertion time to determine which branch the index. It'll get used at insertion time to determine which branch
to follow when choosing where to add the new entry in the tree. At to follow when choosing where to add the new entry in the tree. At
query time, the more balanced the index, the quicker the lookup. query time, the more balanced the index, the quicker the lookup.
@ -629,7 +629,7 @@ my_penalty(PG_FUNCTION_ARGS)
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><function>picksplit</></term> <term><function>picksplit</function></term>
<listitem> <listitem>
<para> <para>
When an index page split is necessary, this function decides which When an index page split is necessary, this function decides which
@ -638,7 +638,7 @@ my_penalty(PG_FUNCTION_ARGS)
</para> </para>
<para> <para>
The <acronym>SQL</> declaration of the function must look like this: The <acronym>SQL</acronym> declaration of the function must look like this:
<programlisting> <programlisting>
CREATE OR REPLACE FUNCTION my_picksplit(internal, internal) CREATE OR REPLACE FUNCTION my_picksplit(internal, internal)
@ -725,33 +725,33 @@ my_picksplit(PG_FUNCTION_ARGS)
} }
</programlisting> </programlisting>
Notice that the <function>picksplit</> function's result is delivered Notice that the <function>picksplit</function> function's result is delivered
by modifying the passed-in <structname>v</> structure. The return by modifying the passed-in <structname>v</structname> structure. The return
value per se is ignored, though it's conventional to pass back the value per se is ignored, though it's conventional to pass back the
address of <structname>v</>. address of <structname>v</structname>.
</para> </para>
<para> <para>
Like <function>penalty</>, the <function>picksplit</> function Like <function>penalty</function>, the <function>picksplit</function> function
is crucial to good performance of the index. Designing suitable is crucial to good performance of the index. Designing suitable
<function>penalty</> and <function>picksplit</> implementations <function>penalty</function> and <function>picksplit</function> implementations
is where the challenge of implementing well-performing is where the challenge of implementing well-performing
<acronym>GiST</> indexes lies. <acronym>GiST</acronym> indexes lies.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><function>same</></term> <term><function>same</function></term>
<listitem> <listitem>
<para> <para>
Returns true if two index entries are identical, false otherwise. Returns true if two index entries are identical, false otherwise.
(An <quote>index entry</> is a value of the index's storage type, (An <quote>index entry</quote> is a value of the index's storage type,
not necessarily the original indexed column's type.) not necessarily the original indexed column's type.)
</para> </para>
<para> <para>
The <acronym>SQL</> declaration of the function must look like this: The <acronym>SQL</acronym> declaration of the function must look like this:
<programlisting> <programlisting>
CREATE OR REPLACE FUNCTION my_same(storage_type, storage_type, internal) CREATE OR REPLACE FUNCTION my_same(storage_type, storage_type, internal)
@ -777,7 +777,7 @@ my_same(PG_FUNCTION_ARGS)
} }
</programlisting> </programlisting>
For historical reasons, the <function>same</> function doesn't For historical reasons, the <function>same</function> function doesn't
just return a Boolean result; instead it has to store the flag just return a Boolean result; instead it has to store the flag
at the location indicated by the third argument. The return at the location indicated by the third argument. The return
value per se is ignored, though it's conventional to pass back the value per se is ignored, though it's conventional to pass back the
@ -787,15 +787,15 @@ my_same(PG_FUNCTION_ARGS)
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><function>distance</></term> <term><function>distance</function></term>
<listitem> <listitem>
<para> <para>
Given an index entry <literal>p</> and a query value <literal>q</>, Given an index entry <literal>p</literal> and a query value <literal>q</literal>,
this function determines the index entry's this function determines the index entry's
<quote>distance</> from the query value. This function must be <quote>distance</quote> from the query value. This function must be
supplied if the operator class contains any ordering operators. supplied if the operator class contains any ordering operators.
A query using the ordering operator will be implemented by returning A query using the ordering operator will be implemented by returning
index entries with the smallest <quote>distance</> values first, index entries with the smallest <quote>distance</quote> values first,
so the results must be consistent with the operator's semantics. so the results must be consistent with the operator's semantics.
For a leaf index entry the result just represents the distance to For a leaf index entry the result just represents the distance to
the index entry; for an internal tree node, the result must be the the index entry; for an internal tree node, the result must be the
@ -803,7 +803,7 @@ my_same(PG_FUNCTION_ARGS)
</para> </para>
<para> <para>
The <acronym>SQL</> declaration of the function must look like this: The <acronym>SQL</acronym> declaration of the function must look like this:
<programlisting> <programlisting>
CREATE OR REPLACE FUNCTION my_distance(internal, data_type, smallint, oid, internal) CREATE OR REPLACE FUNCTION my_distance(internal, data_type, smallint, oid, internal)
@ -836,8 +836,8 @@ my_distance(PG_FUNCTION_ARGS)
} }
</programlisting> </programlisting>
The arguments to the <function>distance</> function are identical to The arguments to the <function>distance</function> function are identical to
the arguments of the <function>consistent</> function. the arguments of the <function>consistent</function> function.
</para> </para>
<para> <para>
@ -847,31 +847,31 @@ my_distance(PG_FUNCTION_ARGS)
geometric applications. For an internal tree node, the distance geometric applications. For an internal tree node, the distance
returned must not be greater than the distance to any of the child returned must not be greater than the distance to any of the child
nodes. If the returned distance is not exact, the function must set nodes. If the returned distance is not exact, the function must set
<literal>*recheck</> to true. (This is not necessary for internal tree <literal>*recheck</literal> to true. (This is not necessary for internal tree
nodes; for them, the calculation is always assumed to be inexact.) In nodes; for them, the calculation is always assumed to be inexact.) In
this case the executor will calculate the accurate distance after this case the executor will calculate the accurate distance after
fetching the tuple from the heap, and reorder the tuples if necessary. fetching the tuple from the heap, and reorder the tuples if necessary.
</para> </para>
<para> <para>
If the distance function returns <literal>*recheck = true</> for any If the distance function returns <literal>*recheck = true</literal> for any
leaf node, the original ordering operator's return type must leaf node, the original ordering operator's return type must
be <type>float8</> or <type>float4</>, and the distance function's be <type>float8</type> or <type>float4</type>, and the distance function's
result values must be comparable to those of the original ordering result values must be comparable to those of the original ordering
operator, since the executor will sort using both distance function operator, since the executor will sort using both distance function
results and recalculated ordering-operator results. Otherwise, the results and recalculated ordering-operator results. Otherwise, the
distance function's result values can be any finite <type>float8</> distance function's result values can be any finite <type>float8</type>
values, so long as the relative order of the result values matches the values, so long as the relative order of the result values matches the
order returned by the ordering operator. (Infinity and minus infinity order returned by the ordering operator. (Infinity and minus infinity
are used internally to handle cases such as nulls, so it is not are used internally to handle cases such as nulls, so it is not
recommended that <function>distance</> functions return these values.) recommended that <function>distance</function> functions return these values.)
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><function>fetch</></term> <term><function>fetch</function></term>
<listitem> <listitem>
<para> <para>
Converts the compressed index representation of a data item into the Converts the compressed index representation of a data item into the
@ -880,7 +880,7 @@ my_distance(PG_FUNCTION_ARGS)
</para> </para>
<para> <para>
The <acronym>SQL</> declaration of the function must look like this: The <acronym>SQL</acronym> declaration of the function must look like this:
<programlisting> <programlisting>
CREATE OR REPLACE FUNCTION my_fetch(internal) CREATE OR REPLACE FUNCTION my_fetch(internal)
@ -889,14 +889,14 @@ AS 'MODULE_PATHNAME'
LANGUAGE C STRICT; LANGUAGE C STRICT;
</programlisting> </programlisting>
The argument is a pointer to a <structname>GISTENTRY</> struct. On The argument is a pointer to a <structname>GISTENTRY</structname> struct. On
entry, its <structfield>key</> field contains a non-NULL leaf datum in entry, its <structfield>key</structfield> field contains a non-NULL leaf datum in
compressed form. The return value is another <structname>GISTENTRY</> compressed form. The return value is another <structname>GISTENTRY</structname>
struct, whose <structfield>key</> field contains the same datum in its struct, whose <structfield>key</structfield> field contains the same datum in its
original, uncompressed form. If the opclass's compress function does original, uncompressed form. If the opclass's compress function does
nothing for leaf entries, the <function>fetch</> method can return the nothing for leaf entries, the <function>fetch</function> method can return the
argument as-is. Or, if the opclass does not have a compress function, argument as-is. Or, if the opclass does not have a compress function,
the <function>fetch</> method can be omitted as well, since it would the <function>fetch</function> method can be omitted as well, since it would
necessarily be a no-op. necessarily be a no-op.
</para> </para>
@ -933,7 +933,7 @@ my_fetch(PG_FUNCTION_ARGS)
<para> <para>
If the compress method is lossy for leaf entries, the operator class If the compress method is lossy for leaf entries, the operator class
cannot support index-only scans, and must not define cannot support index-only scans, and must not define
a <function>fetch</> function. a <function>fetch</function> function.
</para> </para>
</listitem> </listitem>
@ -942,15 +942,15 @@ my_fetch(PG_FUNCTION_ARGS)
<para> <para>
All the GiST support methods are normally called in short-lived memory All the GiST support methods are normally called in short-lived memory
contexts; that is, <varname>CurrentMemoryContext</> will get reset after contexts; that is, <varname>CurrentMemoryContext</varname> will get reset after
each tuple is processed. It is therefore not very important to worry about each tuple is processed. It is therefore not very important to worry about
pfree'ing everything you palloc. However, in some cases it's useful for a pfree'ing everything you palloc. However, in some cases it's useful for a
support method to cache data across repeated calls. To do that, allocate support method to cache data across repeated calls. To do that, allocate
the longer-lived data in <literal>fcinfo-&gt;flinfo-&gt;fn_mcxt</>, and the longer-lived data in <literal>fcinfo-&gt;flinfo-&gt;fn_mcxt</literal>, and
keep a pointer to it in <literal>fcinfo-&gt;flinfo-&gt;fn_extra</>. Such keep a pointer to it in <literal>fcinfo-&gt;flinfo-&gt;fn_extra</literal>. Such
data will survive for the life of the index operation (e.g., a single GiST data will survive for the life of the index operation (e.g., a single GiST
index scan, index build, or index tuple insertion). Be careful to pfree index scan, index build, or index tuple insertion). Be careful to pfree
the previous value when replacing a <literal>fn_extra</> value, or the leak the previous value when replacing a <literal>fn_extra</literal> value, or the leak
will accumulate for the duration of the operation. will accumulate for the duration of the operation.
</para> </para>
@ -974,7 +974,7 @@ my_fetch(PG_FUNCTION_ARGS)
</para> </para>
<para> <para>
However, buffering index build needs to call the <function>penalty</> However, buffering index build needs to call the <function>penalty</function>
function more often, which consumes some extra CPU resources. Also, the function more often, which consumes some extra CPU resources. Also, the
buffers used in the buffering build need temporary disk space, up to buffers used in the buffering build need temporary disk space, up to
the size of the resulting index. Buffering can also influence the quality the size of the resulting index. Buffering can also influence the quality
@ -1002,57 +1002,57 @@ my_fetch(PG_FUNCTION_ARGS)
The <productname>PostgreSQL</productname> source distribution includes The <productname>PostgreSQL</productname> source distribution includes
several examples of index methods implemented using several examples of index methods implemented using
<acronym>GiST</acronym>. The core system currently provides text search <acronym>GiST</acronym>. The core system currently provides text search
support (indexing for <type>tsvector</> and <type>tsquery</>) as well as support (indexing for <type>tsvector</type> and <type>tsquery</type>) as well as
R-Tree equivalent functionality for some of the built-in geometric data types R-Tree equivalent functionality for some of the built-in geometric data types
(see <filename>src/backend/access/gist/gistproc.c</>). The following (see <filename>src/backend/access/gist/gistproc.c</filename>). The following
<filename>contrib</> modules also contain <acronym>GiST</acronym> <filename>contrib</filename> modules also contain <acronym>GiST</acronym>
operator classes: operator classes:
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><filename>btree_gist</></term> <term><filename>btree_gist</filename></term>
<listitem> <listitem>
<para>B-tree equivalent functionality for several data types</para> <para>B-tree equivalent functionality for several data types</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><filename>cube</></term> <term><filename>cube</filename></term>
<listitem> <listitem>
<para>Indexing for multidimensional cubes</para> <para>Indexing for multidimensional cubes</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><filename>hstore</></term> <term><filename>hstore</filename></term>
<listitem> <listitem>
<para>Module for storing (key, value) pairs</para> <para>Module for storing (key, value) pairs</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><filename>intarray</></term> <term><filename>intarray</filename></term>
<listitem> <listitem>
<para>RD-Tree for one-dimensional array of int4 values</para> <para>RD-Tree for one-dimensional array of int4 values</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><filename>ltree</></term> <term><filename>ltree</filename></term>
<listitem> <listitem>
<para>Indexing for tree-like structures</para> <para>Indexing for tree-like structures</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><filename>pg_trgm</></term> <term><filename>pg_trgm</filename></term>
<listitem> <listitem>
<para>Text similarity using trigram matching</para> <para>Text similarity using trigram matching</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><filename>seg</></term> <term><filename>seg</filename></term>
<listitem> <listitem>
<para>Indexing for <quote>float ranges</quote></para> <para>Indexing for <quote>float ranges</quote></para>
</listitem> </listitem>

File diff suppressed because it is too large Load Diff

View File

@ -132,7 +132,7 @@
(<application>psql</application>) was provided for interactive (<application>psql</application>) was provided for interactive
SQL queries, which used <acronym>GNU</acronym> SQL queries, which used <acronym>GNU</acronym>
<application>Readline</application>. This largely superseded <application>Readline</application>. This largely superseded
the old <application>monitor</> program. the old <application>monitor</application> program.
</para> </para>
</listitem> </listitem>
@ -215,7 +215,7 @@
</para> </para>
<para> <para>
Details about what has happened in <productname>PostgreSQL</> since Details about what has happened in <productname>PostgreSQL</productname> since
then can be found in <xref linkend="release">. then can be found in <xref linkend="release">.
</para> </para>
</sect2> </sect2>

View File

@ -8,21 +8,21 @@
</indexterm> </indexterm>
<para> <para>
This module implements the <type>hstore</> data type for storing sets of This module implements the <type>hstore</type> data type for storing sets of
key/value pairs within a single <productname>PostgreSQL</> value. key/value pairs within a single <productname>PostgreSQL</productname> value.
This can be useful in various scenarios, such as rows with many attributes This can be useful in various scenarios, such as rows with many attributes
that are rarely examined, or semi-structured data. Keys and values are that are rarely examined, or semi-structured data. Keys and values are
simply text strings. simply text strings.
</para> </para>
<sect2> <sect2>
<title><type>hstore</> External Representation</title> <title><type>hstore</type> External Representation</title>
<para> <para>
The text representation of an <type>hstore</>, used for input and output, The text representation of an <type>hstore</type>, used for input and output,
includes zero or more <replaceable>key</> <literal>=&gt;</> includes zero or more <replaceable>key</replaceable> <literal>=&gt;</literal>
<replaceable>value</> pairs separated by commas. Some examples: <replaceable>value</replaceable> pairs separated by commas. Some examples:
<synopsis> <synopsis>
k =&gt; v k =&gt; v
@ -31,15 +31,15 @@ foo =&gt; bar, baz =&gt; whatever
</synopsis> </synopsis>
The order of the pairs is not significant (and may not be reproduced on The order of the pairs is not significant (and may not be reproduced on
output). Whitespace between pairs or around the <literal>=&gt;</> sign is output). Whitespace between pairs or around the <literal>=&gt;</literal> sign is
ignored. Double-quote keys and values that include whitespace, commas, ignored. Double-quote keys and values that include whitespace, commas,
<literal>=</>s or <literal>&gt;</>s. To include a double quote or a <literal>=</literal>s or <literal>&gt;</literal>s. To include a double quote or a
backslash in a key or value, escape it with a backslash. backslash in a key or value, escape it with a backslash.
</para> </para>
<para> <para>
Each key in an <type>hstore</> is unique. If you declare an <type>hstore</> Each key in an <type>hstore</type> is unique. If you declare an <type>hstore</type>
with duplicate keys, only one will be stored in the <type>hstore</> and with duplicate keys, only one will be stored in the <type>hstore</type> and
there is no guarantee as to which will be kept: there is no guarantee as to which will be kept:
<programlisting> <programlisting>
@ -51,24 +51,24 @@ SELECT 'a=&gt;1,a=&gt;2'::hstore;
</para> </para>
<para> <para>
A value (but not a key) can be an SQL <literal>NULL</>. For example: A value (but not a key) can be an SQL <literal>NULL</literal>. For example:
<programlisting> <programlisting>
key =&gt; NULL key =&gt; NULL
</programlisting> </programlisting>
The <literal>NULL</> keyword is case-insensitive. Double-quote the The <literal>NULL</literal> keyword is case-insensitive. Double-quote the
<literal>NULL</> to treat it as the ordinary string <quote>NULL</quote>. <literal>NULL</literal> to treat it as the ordinary string <quote>NULL</quote>.
</para> </para>
<note> <note>
<para> <para>
Keep in mind that the <type>hstore</> text format, when used for input, Keep in mind that the <type>hstore</type> text format, when used for input,
applies <emphasis>before</> any required quoting or escaping. If you are applies <emphasis>before</emphasis> any required quoting or escaping. If you are
passing an <type>hstore</> literal via a parameter, then no additional passing an <type>hstore</type> literal via a parameter, then no additional
processing is needed. But if you're passing it as a quoted literal processing is needed. But if you're passing it as a quoted literal
constant, then any single-quote characters and (depending on the setting of constant, then any single-quote characters and (depending on the setting of
the <varname>standard_conforming_strings</> configuration parameter) the <varname>standard_conforming_strings</varname> configuration parameter)
backslash characters need to be escaped correctly. See backslash characters need to be escaped correctly. See
<xref linkend="sql-syntax-strings"> for more on the handling of string <xref linkend="sql-syntax-strings"> for more on the handling of string
constants. constants.
@ -83,7 +83,7 @@ key =&gt; NULL
</sect2> </sect2>
<sect2> <sect2>
<title><type>hstore</> Operators and Functions</title> <title><type>hstore</type> Operators and Functions</title>
<para> <para>
The operators provided by the <literal>hstore</literal> module are The operators provided by the <literal>hstore</literal> module are
@ -92,7 +92,7 @@ key =&gt; NULL
</para> </para>
<table id="hstore-op-table"> <table id="hstore-op-table">
<title><type>hstore</> Operators</title> <title><type>hstore</type> Operators</title>
<tgroup cols="4"> <tgroup cols="4">
<thead> <thead>
@ -106,99 +106,99 @@ key =&gt; NULL
<tbody> <tbody>
<row> <row>
<entry><type>hstore</> <literal>-&gt;</> <type>text</></entry> <entry><type>hstore</type> <literal>-&gt;</literal> <type>text</type></entry>
<entry>get value for key (<literal>NULL</> if not present)</entry> <entry>get value for key (<literal>NULL</literal> if not present)</entry>
<entry><literal>'a=&gt;x, b=&gt;y'::hstore -&gt; 'a'</literal></entry> <entry><literal>'a=&gt;x, b=&gt;y'::hstore -&gt; 'a'</literal></entry>
<entry><literal>x</literal></entry> <entry><literal>x</literal></entry>
</row> </row>
<row> <row>
<entry><type>hstore</> <literal>-&gt;</> <type>text[]</></entry> <entry><type>hstore</type> <literal>-&gt;</literal> <type>text[]</type></entry>
<entry>get values for keys (<literal>NULL</> if not present)</entry> <entry>get values for keys (<literal>NULL</literal> if not present)</entry>
<entry><literal>'a=&gt;x, b=&gt;y, c=&gt;z'::hstore -&gt; ARRAY['c','a']</literal></entry> <entry><literal>'a=&gt;x, b=&gt;y, c=&gt;z'::hstore -&gt; ARRAY['c','a']</literal></entry>
<entry><literal>{"z","x"}</literal></entry> <entry><literal>{"z","x"}</literal></entry>
</row> </row>
<row> <row>
<entry><type>hstore</> <literal>||</> <type>hstore</></entry> <entry><type>hstore</type> <literal>||</literal> <type>hstore</type></entry>
<entry>concatenate <type>hstore</>s</entry> <entry>concatenate <type>hstore</type>s</entry>
<entry><literal>'a=&gt;b, c=&gt;d'::hstore || 'c=&gt;x, d=&gt;q'::hstore</literal></entry> <entry><literal>'a=&gt;b, c=&gt;d'::hstore || 'c=&gt;x, d=&gt;q'::hstore</literal></entry>
<entry><literal>"a"=&gt;"b", "c"=&gt;"x", "d"=&gt;"q"</literal></entry> <entry><literal>"a"=&gt;"b", "c"=&gt;"x", "d"=&gt;"q"</literal></entry>
</row> </row>
<row> <row>
<entry><type>hstore</> <literal>?</> <type>text</></entry> <entry><type>hstore</type> <literal>?</literal> <type>text</type></entry>
<entry>does <type>hstore</> contain key?</entry> <entry>does <type>hstore</type> contain key?</entry>
<entry><literal>'a=&gt;1'::hstore ? 'a'</literal></entry> <entry><literal>'a=&gt;1'::hstore ? 'a'</literal></entry>
<entry><literal>t</literal></entry> <entry><literal>t</literal></entry>
</row> </row>
<row> <row>
<entry><type>hstore</> <literal>?&amp;</> <type>text[]</></entry> <entry><type>hstore</type> <literal>?&amp;</literal> <type>text[]</type></entry>
<entry>does <type>hstore</> contain all specified keys?</entry> <entry>does <type>hstore</type> contain all specified keys?</entry>
<entry><literal>'a=&gt;1,b=&gt;2'::hstore ?&amp; ARRAY['a','b']</literal></entry> <entry><literal>'a=&gt;1,b=&gt;2'::hstore ?&amp; ARRAY['a','b']</literal></entry>
<entry><literal>t</literal></entry> <entry><literal>t</literal></entry>
</row> </row>
<row> <row>
<entry><type>hstore</> <literal>?|</> <type>text[]</></entry> <entry><type>hstore</type> <literal>?|</literal> <type>text[]</type></entry>
<entry>does <type>hstore</> contain any of the specified keys?</entry> <entry>does <type>hstore</type> contain any of the specified keys?</entry>
<entry><literal>'a=&gt;1,b=&gt;2'::hstore ?| ARRAY['b','c']</literal></entry> <entry><literal>'a=&gt;1,b=&gt;2'::hstore ?| ARRAY['b','c']</literal></entry>
<entry><literal>t</literal></entry> <entry><literal>t</literal></entry>
</row> </row>
<row> <row>
<entry><type>hstore</> <literal>@&gt;</> <type>hstore</></entry> <entry><type>hstore</type> <literal>@&gt;</literal> <type>hstore</type></entry>
<entry>does left operand contain right?</entry> <entry>does left operand contain right?</entry>
<entry><literal>'a=&gt;b, b=&gt;1, c=&gt;NULL'::hstore @&gt; 'b=&gt;1'</literal></entry> <entry><literal>'a=&gt;b, b=&gt;1, c=&gt;NULL'::hstore @&gt; 'b=&gt;1'</literal></entry>
<entry><literal>t</literal></entry> <entry><literal>t</literal></entry>
</row> </row>
<row> <row>
<entry><type>hstore</> <literal>&lt;@</> <type>hstore</></entry> <entry><type>hstore</type> <literal>&lt;@</literal> <type>hstore</type></entry>
<entry>is left operand contained in right?</entry> <entry>is left operand contained in right?</entry>
<entry><literal>'a=&gt;c'::hstore &lt;@ 'a=&gt;b, b=&gt;1, c=&gt;NULL'</literal></entry> <entry><literal>'a=&gt;c'::hstore &lt;@ 'a=&gt;b, b=&gt;1, c=&gt;NULL'</literal></entry>
<entry><literal>f</literal></entry> <entry><literal>f</literal></entry>
</row> </row>
<row> <row>
<entry><type>hstore</> <literal>-</> <type>text</></entry> <entry><type>hstore</type> <literal>-</literal> <type>text</type></entry>
<entry>delete key from left operand</entry> <entry>delete key from left operand</entry>
<entry><literal>'a=&gt;1, b=&gt;2, c=&gt;3'::hstore - 'b'::text</literal></entry> <entry><literal>'a=&gt;1, b=&gt;2, c=&gt;3'::hstore - 'b'::text</literal></entry>
<entry><literal>"a"=&gt;"1", "c"=&gt;"3"</literal></entry> <entry><literal>"a"=&gt;"1", "c"=&gt;"3"</literal></entry>
</row> </row>
<row> <row>
<entry><type>hstore</> <literal>-</> <type>text[]</></entry> <entry><type>hstore</type> <literal>-</literal> <type>text[]</type></entry>
<entry>delete keys from left operand</entry> <entry>delete keys from left operand</entry>
<entry><literal>'a=&gt;1, b=&gt;2, c=&gt;3'::hstore - ARRAY['a','b']</literal></entry> <entry><literal>'a=&gt;1, b=&gt;2, c=&gt;3'::hstore - ARRAY['a','b']</literal></entry>
<entry><literal>"c"=&gt;"3"</literal></entry> <entry><literal>"c"=&gt;"3"</literal></entry>
</row> </row>
<row> <row>
<entry><type>hstore</> <literal>-</> <type>hstore</></entry> <entry><type>hstore</type> <literal>-</literal> <type>hstore</type></entry>
<entry>delete matching pairs from left operand</entry> <entry>delete matching pairs from left operand</entry>
<entry><literal>'a=&gt;1, b=&gt;2, c=&gt;3'::hstore - 'a=&gt;4, b=&gt;2'::hstore</literal></entry> <entry><literal>'a=&gt;1, b=&gt;2, c=&gt;3'::hstore - 'a=&gt;4, b=&gt;2'::hstore</literal></entry>
<entry><literal>"a"=&gt;"1", "c"=&gt;"3"</literal></entry> <entry><literal>"a"=&gt;"1", "c"=&gt;"3"</literal></entry>
</row> </row>
<row> <row>
<entry><type>record</> <literal>#=</> <type>hstore</></entry> <entry><type>record</type> <literal>#=</literal> <type>hstore</type></entry>
<entry>replace fields in <type>record</> with matching values from <type>hstore</></entry> <entry>replace fields in <type>record</type> with matching values from <type>hstore</type></entry>
<entry>see Examples section</entry> <entry>see Examples section</entry>
<entry></entry> <entry></entry>
</row> </row>
<row> <row>
<entry><literal>%%</> <type>hstore</></entry> <entry><literal>%%</literal> <type>hstore</type></entry>
<entry>convert <type>hstore</> to array of alternating keys and values</entry> <entry>convert <type>hstore</type> to array of alternating keys and values</entry>
<entry><literal>%% 'a=&gt;foo, b=&gt;bar'::hstore</literal></entry> <entry><literal>%% 'a=&gt;foo, b=&gt;bar'::hstore</literal></entry>
<entry><literal>{a,foo,b,bar}</literal></entry> <entry><literal>{a,foo,b,bar}</literal></entry>
</row> </row>
<row> <row>
<entry><literal>%#</> <type>hstore</></entry> <entry><literal>%#</literal> <type>hstore</type></entry>
<entry>convert <type>hstore</> to two-dimensional key/value array</entry> <entry>convert <type>hstore</type> to two-dimensional key/value array</entry>
<entry><literal>%# 'a=&gt;foo, b=&gt;bar'::hstore</literal></entry> <entry><literal>%# 'a=&gt;foo, b=&gt;bar'::hstore</literal></entry>
<entry><literal>{{a,foo},{b,bar}}</literal></entry> <entry><literal>{{a,foo},{b,bar}}</literal></entry>
</row> </row>
@ -209,8 +209,8 @@ key =&gt; NULL
<note> <note>
<para> <para>
Prior to PostgreSQL 8.2, the containment operators <literal>@&gt;</> Prior to PostgreSQL 8.2, the containment operators <literal>@&gt;</literal>
and <literal>&lt;@</> were called <literal>@</> and <literal>~</>, and <literal>&lt;@</literal> were called <literal>@</literal> and <literal>~</literal>,
respectively. These names are still available, but are deprecated and will respectively. These names are still available, but are deprecated and will
eventually be removed. Notice that the old names are reversed from the eventually be removed. Notice that the old names are reversed from the
convention formerly followed by the core geometric data types! convention formerly followed by the core geometric data types!
@ -218,7 +218,7 @@ key =&gt; NULL
</note> </note>
<table id="hstore-func-table"> <table id="hstore-func-table">
<title><type>hstore</> Functions</title> <title><type>hstore</type> Functions</title>
<tgroup cols="5"> <tgroup cols="5">
<thead> <thead>
@ -235,7 +235,7 @@ key =&gt; NULL
<row> <row>
<entry><function>hstore(record)</function><indexterm><primary>hstore</primary></indexterm></entry> <entry><function>hstore(record)</function><indexterm><primary>hstore</primary></indexterm></entry>
<entry><type>hstore</type></entry> <entry><type>hstore</type></entry>
<entry>construct an <type>hstore</> from a record or row</entry> <entry>construct an <type>hstore</type> from a record or row</entry>
<entry><literal>hstore(ROW(1,2))</literal></entry> <entry><literal>hstore(ROW(1,2))</literal></entry>
<entry><literal>f1=&gt;1,f2=&gt;2</literal></entry> <entry><literal>f1=&gt;1,f2=&gt;2</literal></entry>
</row> </row>
@ -243,7 +243,7 @@ key =&gt; NULL
<row> <row>
<entry><function>hstore(text[])</function></entry> <entry><function>hstore(text[])</function></entry>
<entry><type>hstore</type></entry> <entry><type>hstore</type></entry>
<entry>construct an <type>hstore</> from an array, which may be either <entry>construct an <type>hstore</type> from an array, which may be either
a key/value array, or a two-dimensional array</entry> a key/value array, or a two-dimensional array</entry>
<entry><literal>hstore(ARRAY['a','1','b','2']) || hstore(ARRAY[['c','3'],['d','4']])</literal></entry> <entry><literal>hstore(ARRAY['a','1','b','2']) || hstore(ARRAY[['c','3'],['d','4']])</literal></entry>
<entry><literal>a=&gt;1, b=&gt;2, c=&gt;3, d=&gt;4</literal></entry> <entry><literal>a=&gt;1, b=&gt;2, c=&gt;3, d=&gt;4</literal></entry>
@ -252,7 +252,7 @@ key =&gt; NULL
<row> <row>
<entry><function>hstore(text[], text[])</function></entry> <entry><function>hstore(text[], text[])</function></entry>
<entry><type>hstore</type></entry> <entry><type>hstore</type></entry>
<entry>construct an <type>hstore</> from separate key and value arrays</entry> <entry>construct an <type>hstore</type> from separate key and value arrays</entry>
<entry><literal>hstore(ARRAY['a','b'], ARRAY['1','2'])</literal></entry> <entry><literal>hstore(ARRAY['a','b'], ARRAY['1','2'])</literal></entry>
<entry><literal>"a"=&gt;"1","b"=&gt;"2"</literal></entry> <entry><literal>"a"=&gt;"1","b"=&gt;"2"</literal></entry>
</row> </row>
@ -260,7 +260,7 @@ key =&gt; NULL
<row> <row>
<entry><function>hstore(text, text)</function></entry> <entry><function>hstore(text, text)</function></entry>
<entry><type>hstore</type></entry> <entry><type>hstore</type></entry>
<entry>make single-item <type>hstore</></entry> <entry>make single-item <type>hstore</type></entry>
<entry><literal>hstore('a', 'b')</literal></entry> <entry><literal>hstore('a', 'b')</literal></entry>
<entry><literal>"a"=&gt;"b"</literal></entry> <entry><literal>"a"=&gt;"b"</literal></entry>
</row> </row>
@ -268,7 +268,7 @@ key =&gt; NULL
<row> <row>
<entry><function>akeys(hstore)</function><indexterm><primary>akeys</primary></indexterm></entry> <entry><function>akeys(hstore)</function><indexterm><primary>akeys</primary></indexterm></entry>
<entry><type>text[]</type></entry> <entry><type>text[]</type></entry>
<entry>get <type>hstore</>'s keys as an array</entry> <entry>get <type>hstore</type>'s keys as an array</entry>
<entry><literal>akeys('a=&gt;1,b=&gt;2')</literal></entry> <entry><literal>akeys('a=&gt;1,b=&gt;2')</literal></entry>
<entry><literal>{a,b}</literal></entry> <entry><literal>{a,b}</literal></entry>
</row> </row>
@ -276,7 +276,7 @@ key =&gt; NULL
<row> <row>
<entry><function>skeys(hstore)</function><indexterm><primary>skeys</primary></indexterm></entry> <entry><function>skeys(hstore)</function><indexterm><primary>skeys</primary></indexterm></entry>
<entry><type>setof text</type></entry> <entry><type>setof text</type></entry>
<entry>get <type>hstore</>'s keys as a set</entry> <entry>get <type>hstore</type>'s keys as a set</entry>
<entry><literal>skeys('a=&gt;1,b=&gt;2')</literal></entry> <entry><literal>skeys('a=&gt;1,b=&gt;2')</literal></entry>
<entry> <entry>
<programlisting> <programlisting>
@ -288,7 +288,7 @@ b
<row> <row>
<entry><function>avals(hstore)</function><indexterm><primary>avals</primary></indexterm></entry> <entry><function>avals(hstore)</function><indexterm><primary>avals</primary></indexterm></entry>
<entry><type>text[]</type></entry> <entry><type>text[]</type></entry>
<entry>get <type>hstore</>'s values as an array</entry> <entry>get <type>hstore</type>'s values as an array</entry>
<entry><literal>avals('a=&gt;1,b=&gt;2')</literal></entry> <entry><literal>avals('a=&gt;1,b=&gt;2')</literal></entry>
<entry><literal>{1,2}</literal></entry> <entry><literal>{1,2}</literal></entry>
</row> </row>
@ -296,7 +296,7 @@ b
<row> <row>
<entry><function>svals(hstore)</function><indexterm><primary>svals</primary></indexterm></entry> <entry><function>svals(hstore)</function><indexterm><primary>svals</primary></indexterm></entry>
<entry><type>setof text</type></entry> <entry><type>setof text</type></entry>
<entry>get <type>hstore</>'s values as a set</entry> <entry>get <type>hstore</type>'s values as a set</entry>
<entry><literal>svals('a=&gt;1,b=&gt;2')</literal></entry> <entry><literal>svals('a=&gt;1,b=&gt;2')</literal></entry>
<entry> <entry>
<programlisting> <programlisting>
@ -308,7 +308,7 @@ b
<row> <row>
<entry><function>hstore_to_array(hstore)</function><indexterm><primary>hstore_to_array</primary></indexterm></entry> <entry><function>hstore_to_array(hstore)</function><indexterm><primary>hstore_to_array</primary></indexterm></entry>
<entry><type>text[]</type></entry> <entry><type>text[]</type></entry>
<entry>get <type>hstore</>'s keys and values as an array of alternating <entry>get <type>hstore</type>'s keys and values as an array of alternating
keys and values</entry> keys and values</entry>
<entry><literal>hstore_to_array('a=&gt;1,b=&gt;2')</literal></entry> <entry><literal>hstore_to_array('a=&gt;1,b=&gt;2')</literal></entry>
<entry><literal>{a,1,b,2}</literal></entry> <entry><literal>{a,1,b,2}</literal></entry>
@ -317,7 +317,7 @@ b
<row> <row>
<entry><function>hstore_to_matrix(hstore)</function><indexterm><primary>hstore_to_matrix</primary></indexterm></entry> <entry><function>hstore_to_matrix(hstore)</function><indexterm><primary>hstore_to_matrix</primary></indexterm></entry>
<entry><type>text[]</type></entry> <entry><type>text[]</type></entry>
<entry>get <type>hstore</>'s keys and values as a two-dimensional array</entry> <entry>get <type>hstore</type>'s keys and values as a two-dimensional array</entry>
<entry><literal>hstore_to_matrix('a=&gt;1,b=&gt;2')</literal></entry> <entry><literal>hstore_to_matrix('a=&gt;1,b=&gt;2')</literal></entry>
<entry><literal>{{a,1},{b,2}}</literal></entry> <entry><literal>{{a,1},{b,2}}</literal></entry>
</row> </row>
@ -359,7 +359,7 @@ b
<row> <row>
<entry><function>slice(hstore, text[])</function><indexterm><primary>slice</primary></indexterm></entry> <entry><function>slice(hstore, text[])</function><indexterm><primary>slice</primary></indexterm></entry>
<entry><type>hstore</type></entry> <entry><type>hstore</type></entry>
<entry>extract a subset of an <type>hstore</></entry> <entry>extract a subset of an <type>hstore</type></entry>
<entry><literal>slice('a=&gt;1,b=&gt;2,c=&gt;3'::hstore, ARRAY['b','c','x'])</literal></entry> <entry><literal>slice('a=&gt;1,b=&gt;2,c=&gt;3'::hstore, ARRAY['b','c','x'])</literal></entry>
<entry><literal>"b"=&gt;"2", "c"=&gt;"3"</literal></entry> <entry><literal>"b"=&gt;"2", "c"=&gt;"3"</literal></entry>
</row> </row>
@ -367,7 +367,7 @@ b
<row> <row>
<entry><function>each(hstore)</function><indexterm><primary>each</primary></indexterm></entry> <entry><function>each(hstore)</function><indexterm><primary>each</primary></indexterm></entry>
<entry><type>setof(key text, value text)</type></entry> <entry><type>setof(key text, value text)</type></entry>
<entry>get <type>hstore</>'s keys and values as a set</entry> <entry>get <type>hstore</type>'s keys and values as a set</entry>
<entry><literal>select * from each('a=&gt;1,b=&gt;2')</literal></entry> <entry><literal>select * from each('a=&gt;1,b=&gt;2')</literal></entry>
<entry> <entry>
<programlisting> <programlisting>
@ -381,7 +381,7 @@ b
<row> <row>
<entry><function>exist(hstore,text)</function><indexterm><primary>exist</primary></indexterm></entry> <entry><function>exist(hstore,text)</function><indexterm><primary>exist</primary></indexterm></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>does <type>hstore</> contain key?</entry> <entry>does <type>hstore</type> contain key?</entry>
<entry><literal>exist('a=&gt;1','a')</literal></entry> <entry><literal>exist('a=&gt;1','a')</literal></entry>
<entry><literal>t</literal></entry> <entry><literal>t</literal></entry>
</row> </row>
@ -389,7 +389,7 @@ b
<row> <row>
<entry><function>defined(hstore,text)</function><indexterm><primary>defined</primary></indexterm></entry> <entry><function>defined(hstore,text)</function><indexterm><primary>defined</primary></indexterm></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>does <type>hstore</> contain non-<literal>NULL</> value for key?</entry> <entry>does <type>hstore</type> contain non-<literal>NULL</literal> value for key?</entry>
<entry><literal>defined('a=&gt;NULL','a')</literal></entry> <entry><literal>defined('a=&gt;NULL','a')</literal></entry>
<entry><literal>f</literal></entry> <entry><literal>f</literal></entry>
</row> </row>
@ -421,7 +421,7 @@ b
<row> <row>
<entry><function>populate_record(record,hstore)</function><indexterm><primary>populate_record</primary></indexterm></entry> <entry><function>populate_record(record,hstore)</function><indexterm><primary>populate_record</primary></indexterm></entry>
<entry><type>record</type></entry> <entry><type>record</type></entry>
<entry>replace fields in <type>record</> with matching values from <type>hstore</></entry> <entry>replace fields in <type>record</type> with matching values from <type>hstore</type></entry>
<entry>see Examples section</entry> <entry>see Examples section</entry>
<entry></entry> <entry></entry>
</row> </row>
@ -442,7 +442,7 @@ b
<note> <note>
<para> <para>
The function <function>populate_record</function> is actually declared The function <function>populate_record</function> is actually declared
with <type>anyelement</>, not <type>record</>, as its first argument, with <type>anyelement</type>, not <type>record</type>, as its first argument,
but it will reject non-record types with a run-time error. but it will reject non-record types with a run-time error.
</para> </para>
</note> </note>
@ -452,8 +452,8 @@ b
<title>Indexes</title> <title>Indexes</title>
<para> <para>
<type>hstore</> has GiST and GIN index support for the <literal>@&gt;</>, <type>hstore</type> has GiST and GIN index support for the <literal>@&gt;</literal>,
<literal>?</>, <literal>?&amp;</> and <literal>?|</> operators. For example: <literal>?</literal>, <literal>?&amp;</literal> and <literal>?|</literal> operators. For example:
</para> </para>
<programlisting> <programlisting>
CREATE INDEX hidx ON testhstore USING GIST (h); CREATE INDEX hidx ON testhstore USING GIST (h);
@ -462,12 +462,12 @@ CREATE INDEX hidx ON testhstore USING GIN (h);
</programlisting> </programlisting>
<para> <para>
<type>hstore</> also supports <type>btree</> or <type>hash</> indexes for <type>hstore</type> also supports <type>btree</type> or <type>hash</type> indexes for
the <literal>=</> operator. This allows <type>hstore</> columns to be the <literal>=</literal> operator. This allows <type>hstore</type> columns to be
declared <literal>UNIQUE</>, or to be used in <literal>GROUP BY</>, declared <literal>UNIQUE</literal>, or to be used in <literal>GROUP BY</literal>,
<literal>ORDER BY</> or <literal>DISTINCT</> expressions. The sort ordering <literal>ORDER BY</literal> or <literal>DISTINCT</literal> expressions. The sort ordering
for <type>hstore</> values is not particularly useful, but these indexes for <type>hstore</type> values is not particularly useful, but these indexes
may be useful for equivalence lookups. Create indexes for <literal>=</> may be useful for equivalence lookups. Create indexes for <literal>=</literal>
comparisons as follows: comparisons as follows:
</para> </para>
<programlisting> <programlisting>
@ -495,7 +495,7 @@ UPDATE tab SET h = delete(h, 'k1');
</para> </para>
<para> <para>
Convert a <type>record</> to an <type>hstore</>: Convert a <type>record</type> to an <type>hstore</type>:
<programlisting> <programlisting>
CREATE TABLE test (col1 integer, col2 text, col3 text); CREATE TABLE test (col1 integer, col2 text, col3 text);
INSERT INTO test VALUES (123, 'foo', 'bar'); INSERT INTO test VALUES (123, 'foo', 'bar');
@ -509,7 +509,7 @@ SELECT hstore(t) FROM test AS t;
</para> </para>
<para> <para>
Convert an <type>hstore</> to a predefined <type>record</> type: Convert an <type>hstore</type> to a predefined <type>record</type> type:
<programlisting> <programlisting>
CREATE TABLE test (col1 integer, col2 text, col3 text); CREATE TABLE test (col1 integer, col2 text, col3 text);
@ -523,7 +523,7 @@ SELECT * FROM populate_record(null::test,
</para> </para>
<para> <para>
Modify an existing record using the values from an <type>hstore</>: Modify an existing record using the values from an <type>hstore</type>:
<programlisting> <programlisting>
CREATE TABLE test (col1 integer, col2 text, col3 text); CREATE TABLE test (col1 integer, col2 text, col3 text);
INSERT INTO test VALUES (123, 'foo', 'bar'); INSERT INTO test VALUES (123, 'foo', 'bar');
@ -541,7 +541,7 @@ SELECT (r).* FROM (SELECT t #= '"col3"=&gt;"baz"' AS r FROM test t) s;
<title>Statistics</title> <title>Statistics</title>
<para> <para>
The <type>hstore</> type, because of its intrinsic liberality, could The <type>hstore</type> type, because of its intrinsic liberality, could
contain a lot of different keys. Checking for valid keys is the task of the contain a lot of different keys. Checking for valid keys is the task of the
application. The following examples demonstrate several techniques for application. The following examples demonstrate several techniques for
checking keys and obtaining statistics. checking keys and obtaining statistics.
@ -588,7 +588,7 @@ SELECT key, count(*) FROM
<title>Compatibility</title> <title>Compatibility</title>
<para> <para>
As of PostgreSQL 9.0, <type>hstore</> uses a different internal As of PostgreSQL 9.0, <type>hstore</type> uses a different internal
representation than previous versions. This presents no obstacle for representation than previous versions. This presents no obstacle for
dump/restore upgrades since the text representation (used in the dump) is dump/restore upgrades since the text representation (used in the dump) is
unchanged. unchanged.
@ -599,7 +599,7 @@ SELECT key, count(*) FROM
having the new code recognize old-format data. This will entail a slight having the new code recognize old-format data. This will entail a slight
performance penalty when processing data that has not yet been modified by performance penalty when processing data that has not yet been modified by
the new code. It is possible to force an upgrade of all values in a table the new code. It is possible to force an upgrade of all values in a table
column by doing an <literal>UPDATE</> statement as follows: column by doing an <literal>UPDATE</literal> statement as follows:
<programlisting> <programlisting>
UPDATE tablename SET hstorecol = hstorecol || ''; UPDATE tablename SET hstorecol = hstorecol || '';
</programlisting> </programlisting>
@ -610,7 +610,7 @@ UPDATE tablename SET hstorecol = hstorecol || '';
<programlisting> <programlisting>
ALTER TABLE tablename ALTER hstorecol TYPE hstore USING hstorecol || ''; ALTER TABLE tablename ALTER hstorecol TYPE hstore USING hstorecol || '';
</programlisting> </programlisting>
The <command>ALTER TABLE</> method requires an exclusive lock on the table, The <command>ALTER TABLE</command> method requires an exclusive lock on the table,
but does not result in bloating the table with old row versions. but does not result in bloating the table with old row versions.
</para> </para>

File diff suppressed because it is too large Load Diff

View File

@ -147,14 +147,14 @@ CREATE INDEX test1_id_index ON test1 (id);
</simplelist> </simplelist>
Constructs equivalent to combinations of these operators, such as Constructs equivalent to combinations of these operators, such as
<literal>BETWEEN</> and <literal>IN</>, can also be implemented with <literal>BETWEEN</literal> and <literal>IN</literal>, can also be implemented with
a B-tree index search. Also, an <literal>IS NULL</> or <literal>IS NOT a B-tree index search. Also, an <literal>IS NULL</literal> or <literal>IS NOT
NULL</> condition on an index column can be used with a B-tree index. NULL</literal> condition on an index column can be used with a B-tree index.
</para> </para>
<para> <para>
The optimizer can also use a B-tree index for queries involving the The optimizer can also use a B-tree index for queries involving the
pattern matching operators <literal>LIKE</> and <literal>~</literal> pattern matching operators <literal>LIKE</literal> and <literal>~</literal>
<emphasis>if</emphasis> the pattern is a constant and is anchored to <emphasis>if</emphasis> the pattern is a constant and is anchored to
the beginning of the string &mdash; for example, <literal>col LIKE the beginning of the string &mdash; for example, <literal>col LIKE
'foo%'</literal> or <literal>col ~ '^foo'</literal>, but not 'foo%'</literal> or <literal>col ~ '^foo'</literal>, but not
@ -206,7 +206,7 @@ CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable>
within which many different indexing strategies can be implemented. within which many different indexing strategies can be implemented.
Accordingly, the particular operators with which a GiST index can be Accordingly, the particular operators with which a GiST index can be
used vary depending on the indexing strategy (the <firstterm>operator used vary depending on the indexing strategy (the <firstterm>operator
class</>). As an example, the standard distribution of class</firstterm>). As an example, the standard distribution of
<productname>PostgreSQL</productname> includes GiST operator classes <productname>PostgreSQL</productname> includes GiST operator classes
for several two-dimensional geometric data types, which support indexed for several two-dimensional geometric data types, which support indexed
queries using these operators: queries using these operators:
@ -231,12 +231,12 @@ CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable>
The GiST operator classes included in the standard distribution are The GiST operator classes included in the standard distribution are
documented in <xref linkend="gist-builtin-opclasses-table">. documented in <xref linkend="gist-builtin-opclasses-table">.
Many other GiST operator Many other GiST operator
classes are available in the <literal>contrib</> collection or as separate classes are available in the <literal>contrib</literal> collection or as separate
projects. For more information see <xref linkend="GiST">. projects. For more information see <xref linkend="GiST">.
</para> </para>
<para> <para>
GiST indexes are also capable of optimizing <quote>nearest-neighbor</> GiST indexes are also capable of optimizing <quote>nearest-neighbor</quote>
searches, such as searches, such as
<programlisting><![CDATA[ <programlisting><![CDATA[
SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10;
@ -245,7 +245,7 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10;
which finds the ten places closest to a given target point. The ability which finds the ten places closest to a given target point. The ability
to do this is again dependent on the particular operator class being used. to do this is again dependent on the particular operator class being used.
In <xref linkend="gist-builtin-opclasses-table">, operators that can be In <xref linkend="gist-builtin-opclasses-table">, operators that can be
used in this way are listed in the column <quote>Ordering Operators</>. used in this way are listed in the column <quote>Ordering Operators</quote>.
</para> </para>
<para> <para>
@ -290,7 +290,7 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10;
<primary>GIN</primary> <primary>GIN</primary>
<see>index</see> <see>index</see>
</indexterm> </indexterm>
GIN indexes are <quote>inverted indexes</> which are appropriate for GIN indexes are <quote>inverted indexes</quote> which are appropriate for
data values that contain multiple component values, such as arrays. An data values that contain multiple component values, such as arrays. An
inverted index contains a separate entry for each component value, and inverted index contains a separate entry for each component value, and
can efficiently handle queries that test for the presence of specific can efficiently handle queries that test for the presence of specific
@ -318,7 +318,7 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10;
The GIN operator classes included in the standard distribution are The GIN operator classes included in the standard distribution are
documented in <xref linkend="gin-builtin-opclasses-table">. documented in <xref linkend="gin-builtin-opclasses-table">.
Many other GIN operator Many other GIN operator
classes are available in the <literal>contrib</> collection or as separate classes are available in the <literal>contrib</literal> collection or as separate
projects. For more information see <xref linkend="GIN">. projects. For more information see <xref linkend="GIN">.
</para> </para>
@ -407,13 +407,13 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor);
are checked in the index, so they save visits to the table proper, but are checked in the index, so they save visits to the table proper, but
they do not reduce the portion of the index that has to be scanned. they do not reduce the portion of the index that has to be scanned.
For example, given an index on <literal>(a, b, c)</literal> and a For example, given an index on <literal>(a, b, c)</literal> and a
query condition <literal>WHERE a = 5 AND b &gt;= 42 AND c &lt; 77</>, query condition <literal>WHERE a = 5 AND b &gt;= 42 AND c &lt; 77</literal>,
the index would have to be scanned from the first entry with the index would have to be scanned from the first entry with
<literal>a</> = 5 and <literal>b</> = 42 up through the last entry with <literal>a</literal> = 5 and <literal>b</literal> = 42 up through the last entry with
<literal>a</> = 5. Index entries with <literal>c</> &gt;= 77 would be <literal>a</literal> = 5. Index entries with <literal>c</literal> &gt;= 77 would be
skipped, but they'd still have to be scanned through. skipped, but they'd still have to be scanned through.
This index could in principle be used for queries that have constraints This index could in principle be used for queries that have constraints
on <literal>b</> and/or <literal>c</> with no constraint on <literal>a</> on <literal>b</literal> and/or <literal>c</literal> with no constraint on <literal>a</literal>
&mdash; but the entire index would have to be scanned, so in most cases &mdash; but the entire index would have to be scanned, so in most cases
the planner would prefer a sequential table scan over using the index. the planner would prefer a sequential table scan over using the index.
</para> </para>
@ -462,17 +462,17 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor);
<sect1 id="indexes-ordering"> <sect1 id="indexes-ordering">
<title>Indexes and <literal>ORDER BY</></title> <title>Indexes and <literal>ORDER BY</literal></title>
<indexterm zone="indexes-ordering"> <indexterm zone="indexes-ordering">
<primary>index</primary> <primary>index</primary>
<secondary>and <literal>ORDER BY</></secondary> <secondary>and <literal>ORDER BY</literal></secondary>
</indexterm> </indexterm>
<para> <para>
In addition to simply finding the rows to be returned by a query, In addition to simply finding the rows to be returned by a query,
an index may be able to deliver them in a specific sorted order. an index may be able to deliver them in a specific sorted order.
This allows a query's <literal>ORDER BY</> specification to be honored This allows a query's <literal>ORDER BY</literal> specification to be honored
without a separate sorting step. Of the index types currently without a separate sorting step. Of the index types currently
supported by <productname>PostgreSQL</productname>, only B-tree supported by <productname>PostgreSQL</productname>, only B-tree
can produce sorted output &mdash; the other index types return can produce sorted output &mdash; the other index types return
@ -480,7 +480,7 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor);
</para> </para>
<para> <para>
The planner will consider satisfying an <literal>ORDER BY</> specification The planner will consider satisfying an <literal>ORDER BY</literal> specification
either by scanning an available index that matches the specification, either by scanning an available index that matches the specification,
or by scanning the table in physical order and doing an explicit or by scanning the table in physical order and doing an explicit
sort. For a query that requires scanning a large fraction of the sort. For a query that requires scanning a large fraction of the
@ -488,50 +488,50 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor);
because it requires because it requires
less disk I/O due to following a sequential access pattern. Indexes are less disk I/O due to following a sequential access pattern. Indexes are
more useful when only a few rows need be fetched. An important more useful when only a few rows need be fetched. An important
special case is <literal>ORDER BY</> in combination with special case is <literal>ORDER BY</literal> in combination with
<literal>LIMIT</> <replaceable>n</>: an explicit sort will have to process <literal>LIMIT</literal> <replaceable>n</replaceable>: an explicit sort will have to process
all the data to identify the first <replaceable>n</> rows, but if there is all the data to identify the first <replaceable>n</replaceable> rows, but if there is
an index matching the <literal>ORDER BY</>, the first <replaceable>n</> an index matching the <literal>ORDER BY</literal>, the first <replaceable>n</replaceable>
rows can be retrieved directly, without scanning the remainder at all. rows can be retrieved directly, without scanning the remainder at all.
</para> </para>
<para> <para>
By default, B-tree indexes store their entries in ascending order By default, B-tree indexes store their entries in ascending order
with nulls last. This means that a forward scan of an index on with nulls last. This means that a forward scan of an index on
column <literal>x</> produces output satisfying <literal>ORDER BY x</> column <literal>x</literal> produces output satisfying <literal>ORDER BY x</literal>
(or more verbosely, <literal>ORDER BY x ASC NULLS LAST</>). The (or more verbosely, <literal>ORDER BY x ASC NULLS LAST</literal>). The
index can also be scanned backward, producing output satisfying index can also be scanned backward, producing output satisfying
<literal>ORDER BY x DESC</> <literal>ORDER BY x DESC</literal>
(or more verbosely, <literal>ORDER BY x DESC NULLS FIRST</>, since (or more verbosely, <literal>ORDER BY x DESC NULLS FIRST</literal>, since
<literal>NULLS FIRST</> is the default for <literal>ORDER BY DESC</>). <literal>NULLS FIRST</literal> is the default for <literal>ORDER BY DESC</literal>).
</para> </para>
<para> <para>
You can adjust the ordering of a B-tree index by including the You can adjust the ordering of a B-tree index by including the
options <literal>ASC</>, <literal>DESC</>, <literal>NULLS FIRST</>, options <literal>ASC</literal>, <literal>DESC</literal>, <literal>NULLS FIRST</literal>,
and/or <literal>NULLS LAST</> when creating the index; for example: and/or <literal>NULLS LAST</literal> when creating the index; for example:
<programlisting> <programlisting>
CREATE INDEX test2_info_nulls_low ON test2 (info NULLS FIRST); CREATE INDEX test2_info_nulls_low ON test2 (info NULLS FIRST);
CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST);
</programlisting> </programlisting>
An index stored in ascending order with nulls first can satisfy An index stored in ascending order with nulls first can satisfy
either <literal>ORDER BY x ASC NULLS FIRST</> or either <literal>ORDER BY x ASC NULLS FIRST</literal> or
<literal>ORDER BY x DESC NULLS LAST</> depending on which direction <literal>ORDER BY x DESC NULLS LAST</literal> depending on which direction
it is scanned in. it is scanned in.
</para> </para>
<para> <para>
You might wonder why bother providing all four options, when two You might wonder why bother providing all four options, when two
options together with the possibility of backward scan would cover options together with the possibility of backward scan would cover
all the variants of <literal>ORDER BY</>. In single-column indexes all the variants of <literal>ORDER BY</literal>. In single-column indexes
the options are indeed redundant, but in multicolumn indexes they can be the options are indeed redundant, but in multicolumn indexes they can be
useful. Consider a two-column index on <literal>(x, y)</>: this can useful. Consider a two-column index on <literal>(x, y)</literal>: this can
satisfy <literal>ORDER BY x, y</> if we scan forward, or satisfy <literal>ORDER BY x, y</literal> if we scan forward, or
<literal>ORDER BY x DESC, y DESC</> if we scan backward. <literal>ORDER BY x DESC, y DESC</literal> if we scan backward.
But it might be that the application frequently needs to use But it might be that the application frequently needs to use
<literal>ORDER BY x ASC, y DESC</>. There is no way to get that <literal>ORDER BY x ASC, y DESC</literal>. There is no way to get that
ordering from a plain index, but it is possible if the index is defined ordering from a plain index, but it is possible if the index is defined
as <literal>(x ASC, y DESC)</> or <literal>(x DESC, y ASC)</>. as <literal>(x ASC, y DESC)</literal> or <literal>(x DESC, y ASC)</literal>.
</para> </para>
<para> <para>
@ -559,38 +559,38 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST);
<para> <para>
A single index scan can only use query clauses that use the index's A single index scan can only use query clauses that use the index's
columns with operators of its operator class and are joined with columns with operators of its operator class and are joined with
<literal>AND</>. For example, given an index on <literal>(a, b)</literal> <literal>AND</literal>. For example, given an index on <literal>(a, b)</literal>
a query condition like <literal>WHERE a = 5 AND b = 6</> could a query condition like <literal>WHERE a = 5 AND b = 6</literal> could
use the index, but a query like <literal>WHERE a = 5 OR b = 6</> could not use the index, but a query like <literal>WHERE a = 5 OR b = 6</literal> could not
directly use the index. directly use the index.
</para> </para>
<para> <para>
Fortunately, Fortunately,
<productname>PostgreSQL</> has the ability to combine multiple indexes <productname>PostgreSQL</productname> has the ability to combine multiple indexes
(including multiple uses of the same index) to handle cases that cannot (including multiple uses of the same index) to handle cases that cannot
be implemented by single index scans. The system can form <literal>AND</> be implemented by single index scans. The system can form <literal>AND</literal>
and <literal>OR</> conditions across several index scans. For example, and <literal>OR</literal> conditions across several index scans. For example,
a query like <literal>WHERE x = 42 OR x = 47 OR x = 53 OR x = 99</> a query like <literal>WHERE x = 42 OR x = 47 OR x = 53 OR x = 99</literal>
could be broken down into four separate scans of an index on <literal>x</>, could be broken down into four separate scans of an index on <literal>x</literal>,
each scan using one of the query clauses. The results of these scans are each scan using one of the query clauses. The results of these scans are
then ORed together to produce the result. Another example is that if we then ORed together to produce the result. Another example is that if we
have separate indexes on <literal>x</> and <literal>y</>, one possible have separate indexes on <literal>x</literal> and <literal>y</literal>, one possible
implementation of a query like <literal>WHERE x = 5 AND y = 6</> is to implementation of a query like <literal>WHERE x = 5 AND y = 6</literal> is to
use each index with the appropriate query clause and then AND together use each index with the appropriate query clause and then AND together
the index results to identify the result rows. the index results to identify the result rows.
</para> </para>
<para> <para>
To combine multiple indexes, the system scans each needed index and To combine multiple indexes, the system scans each needed index and
prepares a <firstterm>bitmap</> in memory giving the locations of prepares a <firstterm>bitmap</firstterm> in memory giving the locations of
table rows that are reported as matching that index's conditions. table rows that are reported as matching that index's conditions.
The bitmaps are then ANDed and ORed together as needed by the query. The bitmaps are then ANDed and ORed together as needed by the query.
Finally, the actual table rows are visited and returned. The table rows Finally, the actual table rows are visited and returned. The table rows
are visited in physical order, because that is how the bitmap is laid are visited in physical order, because that is how the bitmap is laid
out; this means that any ordering of the original indexes is lost, and out; this means that any ordering of the original indexes is lost, and
so a separate sort step will be needed if the query has an <literal>ORDER so a separate sort step will be needed if the query has an <literal>ORDER
BY</> clause. For this reason, and because each additional index scan BY</literal> clause. For this reason, and because each additional index scan
adds extra time, the planner will sometimes choose to use a simple index adds extra time, the planner will sometimes choose to use a simple index
scan even though additional indexes are available that could have been scan even though additional indexes are available that could have been
used as well. used as well.
@ -603,19 +603,19 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST);
indexes are best, but sometimes it's better to create separate indexes indexes are best, but sometimes it's better to create separate indexes
and rely on the index-combination feature. For example, if your and rely on the index-combination feature. For example, if your
workload includes a mix of queries that sometimes involve only column workload includes a mix of queries that sometimes involve only column
<literal>x</>, sometimes only column <literal>y</>, and sometimes both <literal>x</literal>, sometimes only column <literal>y</literal>, and sometimes both
columns, you might choose to create two separate indexes on columns, you might choose to create two separate indexes on
<literal>x</> and <literal>y</>, relying on index combination to <literal>x</literal> and <literal>y</literal>, relying on index combination to
process the queries that use both columns. You could also create a process the queries that use both columns. You could also create a
multicolumn index on <literal>(x, y)</>. This index would typically be multicolumn index on <literal>(x, y)</literal>. This index would typically be
more efficient than index combination for queries involving both more efficient than index combination for queries involving both
columns, but as discussed in <xref linkend="indexes-multicolumn">, it columns, but as discussed in <xref linkend="indexes-multicolumn">, it
would be almost useless for queries involving only <literal>y</>, so it would be almost useless for queries involving only <literal>y</literal>, so it
should not be the only index. A combination of the multicolumn index should not be the only index. A combination of the multicolumn index
and a separate index on <literal>y</> would serve reasonably well. For and a separate index on <literal>y</literal> would serve reasonably well. For
queries involving only <literal>x</>, the multicolumn index could be queries involving only <literal>x</literal>, the multicolumn index could be
used, though it would be larger and hence slower than an index on used, though it would be larger and hence slower than an index on
<literal>x</> alone. The last alternative is to create all three <literal>x</literal> alone. The last alternative is to create all three
indexes, but this is probably only reasonable if the table is searched indexes, but this is probably only reasonable if the table is searched
much more often than it is updated and all three types of query are much more often than it is updated and all three types of query are
common. If one of the types of query is much less common than the common. If one of the types of query is much less common than the
@ -698,9 +698,9 @@ CREATE INDEX test1_lower_col1_idx ON test1 (lower(col1));
</para> </para>
<para> <para>
If we were to declare this index <literal>UNIQUE</>, it would prevent If we were to declare this index <literal>UNIQUE</literal>, it would prevent
creation of rows whose <literal>col1</> values differ only in case, creation of rows whose <literal>col1</literal> values differ only in case,
as well as rows whose <literal>col1</> values are actually identical. as well as rows whose <literal>col1</literal> values are actually identical.
Thus, indexes on expressions can be used to enforce constraints that Thus, indexes on expressions can be used to enforce constraints that
are not definable as simple unique constraints. are not definable as simple unique constraints.
</para> </para>
@ -717,7 +717,7 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name));
</para> </para>
<para> <para>
The syntax of the <command>CREATE INDEX</> command normally requires The syntax of the <command>CREATE INDEX</command> command normally requires
writing parentheses around index expressions, as shown in the second writing parentheses around index expressions, as shown in the second
example. The parentheses can be omitted when the expression is just example. The parentheses can be omitted when the expression is just
a function call, as in the first example. a function call, as in the first example.
@ -727,9 +727,9 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name));
Index expressions are relatively expensive to maintain, because the Index expressions are relatively expensive to maintain, because the
derived expression(s) must be computed for each row upon insertion derived expression(s) must be computed for each row upon insertion
and whenever it is updated. However, the index expressions are and whenever it is updated. However, the index expressions are
<emphasis>not</> recomputed during an indexed search, since they are <emphasis>not</emphasis> recomputed during an indexed search, since they are
already stored in the index. In both examples above, the system already stored in the index. In both examples above, the system
sees the query as just <literal>WHERE indexedcolumn = 'constant'</> sees the query as just <literal>WHERE indexedcolumn = 'constant'</literal>
and so the speed of the search is equivalent to any other simple index and so the speed of the search is equivalent to any other simple index
query. Thus, indexes on expressions are useful when retrieval speed query. Thus, indexes on expressions are useful when retrieval speed
is more important than insertion and update speed. is more important than insertion and update speed.
@ -856,12 +856,12 @@ CREATE INDEX orders_unbilled_index ON orders (order_nr)
SELECT * FROM orders WHERE billed is not true AND order_nr &lt; 10000; SELECT * FROM orders WHERE billed is not true AND order_nr &lt; 10000;
</programlisting> </programlisting>
However, the index can also be used in queries that do not involve However, the index can also be used in queries that do not involve
<structfield>order_nr</> at all, e.g.: <structfield>order_nr</structfield> at all, e.g.:
<programlisting> <programlisting>
SELECT * FROM orders WHERE billed is not true AND amount &gt; 5000.00; SELECT * FROM orders WHERE billed is not true AND amount &gt; 5000.00;
</programlisting> </programlisting>
This is not as efficient as a partial index on the This is not as efficient as a partial index on the
<structfield>amount</> column would be, since the system has to <structfield>amount</structfield> column would be, since the system has to
scan the entire index. Yet, if there are relatively few unbilled scan the entire index. Yet, if there are relatively few unbilled
orders, using this partial index just to find the unbilled orders orders, using this partial index just to find the unbilled orders
could be a win. could be a win.
@ -886,7 +886,7 @@ SELECT * FROM orders WHERE order_nr = 3501;
predicate must match the conditions used in the queries that predicate must match the conditions used in the queries that
are supposed to benefit from the index. To be precise, a partial are supposed to benefit from the index. To be precise, a partial
index can be used in a query only if the system can recognize that index can be used in a query only if the system can recognize that
the <literal>WHERE</> condition of the query mathematically implies the <literal>WHERE</literal> condition of the query mathematically implies
the predicate of the index. the predicate of the index.
<productname>PostgreSQL</productname> does not have a sophisticated <productname>PostgreSQL</productname> does not have a sophisticated
theorem prover that can recognize mathematically equivalent theorem prover that can recognize mathematically equivalent
@ -896,7 +896,7 @@ SELECT * FROM orders WHERE order_nr = 3501;
The system can recognize simple inequality implications, for example The system can recognize simple inequality implications, for example
<quote>x &lt; 1</quote> implies <quote>x &lt; 2</quote>; otherwise <quote>x &lt; 1</quote> implies <quote>x &lt; 2</quote>; otherwise
the predicate condition must exactly match part of the query's the predicate condition must exactly match part of the query's
<literal>WHERE</> condition <literal>WHERE</literal> condition
or the index will not be recognized as usable. Matching takes or the index will not be recognized as usable. Matching takes
place at query planning time, not at run time. As a result, place at query planning time, not at run time. As a result,
parameterized query clauses do not work with a partial index. For parameterized query clauses do not work with a partial index. For
@ -919,9 +919,9 @@ SELECT * FROM orders WHERE order_nr = 3501;
<para> <para>
Suppose that we have a table describing test outcomes. We wish Suppose that we have a table describing test outcomes. We wish
to ensure that there is only one <quote>successful</> entry for to ensure that there is only one <quote>successful</quote> entry for
a given subject and target combination, but there might be any number of a given subject and target combination, but there might be any number of
<quote>unsuccessful</> entries. Here is one way to do it: <quote>unsuccessful</quote> entries. Here is one way to do it:
<programlisting> <programlisting>
CREATE TABLE tests ( CREATE TABLE tests (
subject text, subject text,
@ -944,7 +944,7 @@ CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target)
distributions might cause the system to use an index when it really distributions might cause the system to use an index when it really
should not. In that case the index can be set up so that it is not should not. In that case the index can be set up so that it is not
available for the offending query. Normally, available for the offending query. Normally,
<productname>PostgreSQL</> makes reasonable choices about index <productname>PostgreSQL</productname> makes reasonable choices about index
usage (e.g., it avoids them when retrieving common values, so the usage (e.g., it avoids them when retrieving common values, so the
earlier example really only saves index size, it is not required to earlier example really only saves index size, it is not required to
avoid index usage), and grossly incorrect plan choices are cause avoid index usage), and grossly incorrect plan choices are cause
@ -956,7 +956,7 @@ CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target)
know at least as much as the query planner knows, in particular you know at least as much as the query planner knows, in particular you
know when an index might be profitable. Forming this knowledge know when an index might be profitable. Forming this knowledge
requires experience and understanding of how indexes in requires experience and understanding of how indexes in
<productname>PostgreSQL</> work. In most cases, the advantage of a <productname>PostgreSQL</productname> work. In most cases, the advantage of a
partial index over a regular index will be minimal. partial index over a regular index will be minimal.
</para> </para>
@ -998,8 +998,8 @@ CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable>
the proper class when making an index. The operator class determines the proper class when making an index. The operator class determines
the basic sort ordering (which can then be modified by adding sort options the basic sort ordering (which can then be modified by adding sort options
<literal>COLLATE</literal>, <literal>COLLATE</literal>,
<literal>ASC</>/<literal>DESC</> and/or <literal>ASC</literal>/<literal>DESC</literal> and/or
<literal>NULLS FIRST</>/<literal>NULLS LAST</>). <literal>NULLS FIRST</literal>/<literal>NULLS LAST</literal>).
</para> </para>
<para> <para>
@ -1025,8 +1025,8 @@ CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable>
CREATE INDEX test_index ON test_table (col varchar_pattern_ops); CREATE INDEX test_index ON test_table (col varchar_pattern_ops);
</programlisting> </programlisting>
Note that you should also create an index with the default operator Note that you should also create an index with the default operator
class if you want queries involving ordinary <literal>&lt;</>, class if you want queries involving ordinary <literal>&lt;</literal>,
<literal>&lt;=</>, <literal>&gt;</>, or <literal>&gt;=</> comparisons <literal>&lt;=</literal>, <literal>&gt;</literal>, or <literal>&gt;=</literal> comparisons
to use an index. Such queries cannot use the to use an index. Such queries cannot use the
<literal><replaceable>xxx</replaceable>_pattern_ops</literal> <literal><replaceable>xxx</replaceable>_pattern_ops</literal>
operator classes. (Ordinary equality comparisons can use these operator classes. (Ordinary equality comparisons can use these
@ -1057,7 +1057,7 @@ SELECT am.amname AS index_method,
<para> <para>
An operator class is actually just a subset of a larger structure called an An operator class is actually just a subset of a larger structure called an
<firstterm>operator family</>. In cases where several data types have <firstterm>operator family</firstterm>. In cases where several data types have
similar behaviors, it is frequently useful to define cross-data-type similar behaviors, it is frequently useful to define cross-data-type
operators and allow these to work with indexes. To do this, the operator operators and allow these to work with indexes. To do this, the operator
classes for each of the types must be grouped into the same operator classes for each of the types must be grouped into the same operator
@ -1147,13 +1147,13 @@ CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y");
</indexterm> </indexterm>
<para> <para>
All indexes in <productname>PostgreSQL</> are <firstterm>secondary</> All indexes in <productname>PostgreSQL</productname> are <firstterm>secondary</firstterm>
indexes, meaning that each index is stored separately from the table's indexes, meaning that each index is stored separately from the table's
main data area (which is called the table's <firstterm>heap</> main data area (which is called the table's <firstterm>heap</firstterm>
in <productname>PostgreSQL</> terminology). This means that in an in <productname>PostgreSQL</productname> terminology). This means that in an
ordinary index scan, each row retrieval requires fetching data from both ordinary index scan, each row retrieval requires fetching data from both
the index and the heap. Furthermore, while the index entries that match a the index and the heap. Furthermore, while the index entries that match a
given indexable <literal>WHERE</> condition are usually close together in given indexable <literal>WHERE</literal> condition are usually close together in
the index, the table rows they reference might be anywhere in the heap. the index, the table rows they reference might be anywhere in the heap.
The heap-access portion of an index scan thus involves a lot of random The heap-access portion of an index scan thus involves a lot of random
access into the heap, which can be slow, particularly on traditional access into the heap, which can be slow, particularly on traditional
@ -1163,8 +1163,8 @@ CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y");
</para> </para>
<para> <para>
To solve this performance problem, <productname>PostgreSQL</> To solve this performance problem, <productname>PostgreSQL</productname>
supports <firstterm>index-only scans</>, which can answer queries from an supports <firstterm>index-only scans</firstterm>, which can answer queries from an
index alone without any heap access. The basic idea is to return values index alone without any heap access. The basic idea is to return values
directly out of each index entry instead of consulting the associated heap directly out of each index entry instead of consulting the associated heap
entry. There are two fundamental restrictions on when this method can be entry. There are two fundamental restrictions on when this method can be
@ -1187,8 +1187,8 @@ CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y");
<listitem> <listitem>
<para> <para>
The query must reference only columns stored in the index. For The query must reference only columns stored in the index. For
example, given an index on columns <literal>x</> and <literal>y</> of a example, given an index on columns <literal>x</literal> and <literal>y</literal> of a
table that also has a column <literal>z</>, these queries could use table that also has a column <literal>z</literal>, these queries could use
index-only scans: index-only scans:
<programlisting> <programlisting>
SELECT x, y FROM tab WHERE x = 'key'; SELECT x, y FROM tab WHERE x = 'key';
@ -1210,17 +1210,17 @@ SELECT x FROM tab WHERE x = 'key' AND z &lt; 42;
If these two fundamental requirements are met, then all the data values If these two fundamental requirements are met, then all the data values
required by the query are available from the index, so an index-only scan required by the query are available from the index, so an index-only scan
is physically possible. But there is an additional requirement for any is physically possible. But there is an additional requirement for any
table scan in <productname>PostgreSQL</>: it must verify that each table scan in <productname>PostgreSQL</productname>: it must verify that each
retrieved row be <quote>visible</> to the query's MVCC snapshot, as retrieved row be <quote>visible</quote> to the query's MVCC snapshot, as
discussed in <xref linkend="mvcc">. Visibility information is not stored discussed in <xref linkend="mvcc">. Visibility information is not stored
in index entries, only in heap entries; so at first glance it would seem in index entries, only in heap entries; so at first glance it would seem
that every row retrieval would require a heap access anyway. And this is that every row retrieval would require a heap access anyway. And this is
indeed the case, if the table row has been modified recently. However, indeed the case, if the table row has been modified recently. However,
for seldom-changing data there is a way around this for seldom-changing data there is a way around this
problem. <productname>PostgreSQL</> tracks, for each page in a table's problem. <productname>PostgreSQL</productname> tracks, for each page in a table's
heap, whether all rows stored in that page are old enough to be visible to heap, whether all rows stored in that page are old enough to be visible to
all current and future transactions. This information is stored in a bit all current and future transactions. This information is stored in a bit
in the table's <firstterm>visibility map</>. An index-only scan, after in the table's <firstterm>visibility map</firstterm>. An index-only scan, after
finding a candidate index entry, checks the visibility map bit for the finding a candidate index entry, checks the visibility map bit for the
corresponding heap page. If it's set, the row is known visible and so the corresponding heap page. If it's set, the row is known visible and so the
data can be returned with no further work. If it's not set, the heap data can be returned with no further work. If it's not set, the heap
@ -1243,48 +1243,48 @@ SELECT x FROM tab WHERE x = 'key' AND z &lt; 42;
<para> <para>
To make effective use of the index-only scan feature, you might choose to To make effective use of the index-only scan feature, you might choose to
create indexes in which only the leading columns are meant to create indexes in which only the leading columns are meant to
match <literal>WHERE</> clauses, while the trailing columns match <literal>WHERE</literal> clauses, while the trailing columns
hold <quote>payload</> data to be returned by a query. For example, if hold <quote>payload</quote> data to be returned by a query. For example, if
you commonly run queries like you commonly run queries like
<programlisting> <programlisting>
SELECT y FROM tab WHERE x = 'key'; SELECT y FROM tab WHERE x = 'key';
</programlisting> </programlisting>
the traditional approach to speeding up such queries would be to create an the traditional approach to speeding up such queries would be to create an
index on <literal>x</> only. However, an index on <literal>(x, y)</> index on <literal>x</literal> only. However, an index on <literal>(x, y)</literal>
would offer the possibility of implementing this query as an index-only would offer the possibility of implementing this query as an index-only
scan. As previously discussed, such an index would be larger and hence scan. As previously discussed, such an index would be larger and hence
more expensive than an index on <literal>x</> alone, so this is attractive more expensive than an index on <literal>x</literal> alone, so this is attractive
only if the table is known to be mostly static. Note it's important that only if the table is known to be mostly static. Note it's important that
the index be declared on <literal>(x, y)</> not <literal>(y, x)</>, as for the index be declared on <literal>(x, y)</literal> not <literal>(y, x)</literal>, as for
most index types (particularly B-trees) searches that do not constrain the most index types (particularly B-trees) searches that do not constrain the
leading index columns are not very efficient. leading index columns are not very efficient.
</para> </para>
<para> <para>
In principle, index-only scans can be used with expression indexes. In principle, index-only scans can be used with expression indexes.
For example, given an index on <literal>f(x)</> where <literal>x</> is a For example, given an index on <literal>f(x)</literal> where <literal>x</literal> is a
table column, it should be possible to execute table column, it should be possible to execute
<programlisting> <programlisting>
SELECT f(x) FROM tab WHERE f(x) &lt; 1; SELECT f(x) FROM tab WHERE f(x) &lt; 1;
</programlisting> </programlisting>
as an index-only scan; and this is very attractive if <literal>f()</> is as an index-only scan; and this is very attractive if <literal>f()</literal> is
an expensive-to-compute function. However, <productname>PostgreSQL</>'s an expensive-to-compute function. However, <productname>PostgreSQL</productname>'s
planner is currently not very smart about such cases. It considers a planner is currently not very smart about such cases. It considers a
query to be potentially executable by index-only scan only when query to be potentially executable by index-only scan only when
all <emphasis>columns</> needed by the query are available from the index. all <emphasis>columns</emphasis> needed by the query are available from the index.
In this example, <literal>x</> is not needed except in the In this example, <literal>x</literal> is not needed except in the
context <literal>f(x)</>, but the planner does not notice that and context <literal>f(x)</literal>, but the planner does not notice that and
concludes that an index-only scan is not possible. If an index-only scan concludes that an index-only scan is not possible. If an index-only scan
seems sufficiently worthwhile, this can be worked around by declaring the seems sufficiently worthwhile, this can be worked around by declaring the
index to be on <literal>(f(x), x)</>, where the second column is not index to be on <literal>(f(x), x)</literal>, where the second column is not
expected to be used in practice but is just there to convince the planner expected to be used in practice but is just there to convince the planner
that an index-only scan is possible. An additional caveat, if the goal is that an index-only scan is possible. An additional caveat, if the goal is
to avoid recalculating <literal>f(x)</>, is that the planner won't to avoid recalculating <literal>f(x)</literal>, is that the planner won't
necessarily match uses of <literal>f(x)</> that aren't in necessarily match uses of <literal>f(x)</literal> that aren't in
indexable <literal>WHERE</> clauses to the index column. It will usually indexable <literal>WHERE</literal> clauses to the index column. It will usually
get this right in simple queries such as shown above, but not in queries get this right in simple queries such as shown above, but not in queries
that involve joins. These deficiencies may be remedied in future versions that involve joins. These deficiencies may be remedied in future versions
of <productname>PostgreSQL</>. of <productname>PostgreSQL</productname>.
</para> </para>
<para> <para>
@ -1299,13 +1299,13 @@ CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target)
<programlisting> <programlisting>
SELECT target FROM tests WHERE subject = 'some-subject' AND success; SELECT target FROM tests WHERE subject = 'some-subject' AND success;
</programlisting> </programlisting>
But there's a problem: the <literal>WHERE</> clause refers But there's a problem: the <literal>WHERE</literal> clause refers
to <literal>success</> which is not available as a result column of the to <literal>success</literal> which is not available as a result column of the
index. Nonetheless, an index-only scan is possible because the plan does index. Nonetheless, an index-only scan is possible because the plan does
not need to recheck that part of the <literal>WHERE</> clause at run time: not need to recheck that part of the <literal>WHERE</literal> clause at run time:
all entries found in the index necessarily have <literal>success = true</> all entries found in the index necessarily have <literal>success = true</literal>
so this need not be explicitly checked in the so this need not be explicitly checked in the
plan. <productname>PostgreSQL</> versions 9.6 and later will recognize plan. <productname>PostgreSQL</productname> versions 9.6 and later will recognize
such cases and allow index-only scans to be generated, but older versions such cases and allow index-only scans to be generated, but older versions
will not. will not.
</para> </para>
@ -1321,7 +1321,7 @@ SELECT target FROM tests WHERE subject = 'some-subject' AND success;
</indexterm> </indexterm>
<para> <para>
Although indexes in <productname>PostgreSQL</> do not need Although indexes in <productname>PostgreSQL</productname> do not need
maintenance or tuning, it is still important to check maintenance or tuning, it is still important to check
which indexes are actually used by the real-life query workload. which indexes are actually used by the real-life query workload.
Examining index usage for an individual query is done with the Examining index usage for an individual query is done with the
@ -1388,8 +1388,8 @@ SELECT target FROM tests WHERE subject = 'some-subject' AND success;
their use. There are run-time parameters that can turn off their use. There are run-time parameters that can turn off
various plan types (see <xref linkend="runtime-config-query-enable">). various plan types (see <xref linkend="runtime-config-query-enable">).
For instance, turning off sequential scans For instance, turning off sequential scans
(<varname>enable_seqscan</>) and nested-loop joins (<varname>enable_seqscan</varname>) and nested-loop joins
(<varname>enable_nestloop</>), which are the most basic plans, (<varname>enable_nestloop</varname>), which are the most basic plans,
will force the system to use a different plan. If the system will force the system to use a different plan. If the system
still chooses a sequential scan or nested-loop join then there is still chooses a sequential scan or nested-loop join then there is
probably a more fundamental reason why the index is not being probably a more fundamental reason why the index is not being
@ -1428,7 +1428,7 @@ SELECT target FROM tests WHERE subject = 'some-subject' AND success;
If you do not succeed in adjusting the costs to be more If you do not succeed in adjusting the costs to be more
appropriate, then you might have to resort to forcing index usage appropriate, then you might have to resort to forcing index usage
explicitly. You might also want to contact the explicitly. You might also want to contact the
<productname>PostgreSQL</> developers to examine the issue. <productname>PostgreSQL</productname> developers to examine the issue.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>

View File

@ -15,9 +15,9 @@
<para> <para>
The <productname>PostgreSQL</productname> <ulink The <productname>PostgreSQL</productname> <ulink
url="https://wiki.postgresql.org">wiki</ulink> contains the project's <ulink url="https://wiki.postgresql.org">wiki</ulink> contains the project's <ulink
url="https://wiki.postgresql.org/wiki/Frequently_Asked_Questions">FAQ</> url="https://wiki.postgresql.org/wiki/Frequently_Asked_Questions">FAQ</ulink>
(Frequently Asked Questions) list, <ulink (Frequently Asked Questions) list, <ulink
url="https://wiki.postgresql.org/wiki/Todo">TODO</> list, and url="https://wiki.postgresql.org/wiki/Todo">TODO</ulink> list, and
detailed information about many more topics. detailed information about many more topics.
</para> </para>
</listitem> </listitem>
@ -42,7 +42,7 @@
<para> <para>
The mailing lists are a good place to have your questions The mailing lists are a good place to have your questions
answered, to share experiences with other users, and to contact answered, to share experiences with other users, and to contact
the developers. Consult the <productname>PostgreSQL</> web site the developers. Consult the <productname>PostgreSQL</productname> web site
for details. for details.
</para> </para>
</listitem> </listitem>

File diff suppressed because it is too large Load Diff

View File

@ -84,13 +84,13 @@
<productname>Microsoft Windows SDK</productname> version 6.0a to 8.1 or <productname>Microsoft Windows SDK</productname> version 6.0a to 8.1 or
<productname>Visual Studio 2008</productname> and above. Compilation <productname>Visual Studio 2008</productname> and above. Compilation
is supported down to <productname>Windows XP</productname> and is supported down to <productname>Windows XP</productname> and
<productname>Windows Server 2003</> when building with <productname>Windows Server 2003</productname> when building with
<productname>Visual Studio 2005</> to <productname>Visual Studio 2005</productname> to
<productname>Visual Studio 2013</productname>. Building with <productname>Visual Studio 2013</productname>. Building with
<productname>Visual Studio 2015</productname> is supported down to <productname>Visual Studio 2015</productname> is supported down to
<productname>Windows Vista</> and <productname>Windows Server 2008</>. <productname>Windows Vista</productname> and <productname>Windows Server 2008</productname>.
Building with <productname>Visual Studio 2017</productname> is supported Building with <productname>Visual Studio 2017</productname> is supported
down to <productname>Windows 7 SP1</> and <productname>Windows Server 2008 R2 SP1</>. down to <productname>Windows 7 SP1</productname> and <productname>Windows Server 2008 R2 SP1</productname>.
</para> </para>
<para> <para>
@ -163,7 +163,7 @@ $ENV{MSBFLAGS}="/m";
<productname>Microsoft Windows SDK</productname> it <productname>Microsoft Windows SDK</productname> it
is recommended that you upgrade to the latest version (currently is recommended that you upgrade to the latest version (currently
version 7.1), available for download from version 7.1), available for download from
<ulink url="https://www.microsoft.com/download"></>. <ulink url="https://www.microsoft.com/download"></ulink>.
</para> </para>
<para> <para>
You must always include the You must always include the
@ -182,7 +182,7 @@ $ENV{MSBFLAGS}="/m";
ActiveState Perl is required to run the build generation scripts. MinGW ActiveState Perl is required to run the build generation scripts. MinGW
or Cygwin Perl will not work. It must also be present in the PATH. or Cygwin Perl will not work. It must also be present in the PATH.
Binaries can be downloaded from Binaries can be downloaded from
<ulink url="http://www.activestate.com"></> <ulink url="http://www.activestate.com"></ulink>
(Note: version 5.8.3 or later is required, (Note: version 5.8.3 or later is required,
the free Standard Distribution is sufficient). the free Standard Distribution is sufficient).
</para></listitem> </para></listitem>
@ -219,7 +219,7 @@ $ENV{MSBFLAGS}="/m";
<para> <para>
Both <productname>Bison</productname> and <productname>Flex</productname> Both <productname>Bison</productname> and <productname>Flex</productname>
are included in the <productname>msys</productname> tool suite, available are included in the <productname>msys</productname> tool suite, available
from <ulink url="http://www.mingw.org/wiki/MSYS"></> as part of the from <ulink url="http://www.mingw.org/wiki/MSYS"></ulink> as part of the
<productname>MinGW</productname> compiler suite. <productname>MinGW</productname> compiler suite.
</para> </para>
@ -259,7 +259,7 @@ $ENV{MSBFLAGS}="/m";
<term><productname>Diff</productname></term> <term><productname>Diff</productname></term>
<listitem><para> <listitem><para>
Diff is required to run the regression tests, and can be downloaded Diff is required to run the regression tests, and can be downloaded
from <ulink url="http://gnuwin32.sourceforge.net"></>. from <ulink url="http://gnuwin32.sourceforge.net"></ulink>.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
@ -267,7 +267,7 @@ $ENV{MSBFLAGS}="/m";
<term><productname>Gettext</productname></term> <term><productname>Gettext</productname></term>
<listitem><para> <listitem><para>
Gettext is required to build with NLS support, and can be downloaded Gettext is required to build with NLS support, and can be downloaded
from <ulink url="http://gnuwin32.sourceforge.net"></>. Note that binaries, from <ulink url="http://gnuwin32.sourceforge.net"></ulink>. Note that binaries,
dependencies and developer files are all needed. dependencies and developer files are all needed.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
@ -277,7 +277,7 @@ $ENV{MSBFLAGS}="/m";
<listitem><para> <listitem><para>
Required for GSSAPI authentication support. MIT Kerberos can be Required for GSSAPI authentication support. MIT Kerberos can be
downloaded from downloaded from
<ulink url="http://web.mit.edu/Kerberos/dist/index.html"></>. <ulink url="http://web.mit.edu/Kerberos/dist/index.html"></ulink>.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
@ -286,8 +286,8 @@ $ENV{MSBFLAGS}="/m";
<productname>libxslt</productname></term> <productname>libxslt</productname></term>
<listitem><para> <listitem><para>
Required for XML support. Binaries can be downloaded from Required for XML support. Binaries can be downloaded from
<ulink url="http://zlatkovic.com/pub/libxml"></> or source from <ulink url="http://zlatkovic.com/pub/libxml"></ulink> or source from
<ulink url="http://xmlsoft.org"></>. Note that libxml2 requires iconv, <ulink url="http://xmlsoft.org"></ulink>. Note that libxml2 requires iconv,
which is available from the same download location. which is available from the same download location.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
@ -296,8 +296,8 @@ $ENV{MSBFLAGS}="/m";
<term><productname>openssl</productname></term> <term><productname>openssl</productname></term>
<listitem><para> <listitem><para>
Required for SSL support. Binaries can be downloaded from Required for SSL support. Binaries can be downloaded from
<ulink url="http://www.slproweb.com/products/Win32OpenSSL.html"></> <ulink url="http://www.slproweb.com/products/Win32OpenSSL.html"></ulink>
or source from <ulink url="http://www.openssl.org"></>. or source from <ulink url="http://www.openssl.org"></ulink>.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
@ -306,7 +306,7 @@ $ENV{MSBFLAGS}="/m";
<listitem><para> <listitem><para>
Required for UUID-OSSP support (contrib only). Source can be Required for UUID-OSSP support (contrib only). Source can be
downloaded from downloaded from
<ulink url="http://www.ossp.org/pkg/lib/uuid/"></>. <ulink url="http://www.ossp.org/pkg/lib/uuid/"></ulink>.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
@ -314,7 +314,7 @@ $ENV{MSBFLAGS}="/m";
<term><productname>Python</productname></term> <term><productname>Python</productname></term>
<listitem><para> <listitem><para>
Required for building <application>PL/Python</application>. Binaries can Required for building <application>PL/Python</application>. Binaries can
be downloaded from <ulink url="http://www.python.org"></>. be downloaded from <ulink url="http://www.python.org"></ulink>.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
@ -323,7 +323,7 @@ $ENV{MSBFLAGS}="/m";
<listitem><para> <listitem><para>
Required for compression support in <application>pg_dump</application> Required for compression support in <application>pg_dump</application>
and <application>pg_restore</application>. Binaries can be downloaded and <application>pg_restore</application>. Binaries can be downloaded
from <ulink url="http://www.zlib.net"></>. from <ulink url="http://www.zlib.net"></ulink>.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
@ -347,8 +347,8 @@ $ENV{MSBFLAGS}="/m";
</para> </para>
<para> <para>
To use a server-side third party library such as <productname>python</> or To use a server-side third party library such as <productname>python</productname> or
<productname>openssl</>, this library <emphasis>must</emphasis> also be <productname>openssl</productname>, this library <emphasis>must</emphasis> also be
64-bit. There is no support for loading a 32-bit library in a 64-bit 64-bit. There is no support for loading a 32-bit library in a 64-bit
server. Several of the third party libraries that PostgreSQL supports may server. Several of the third party libraries that PostgreSQL supports may
only be available in 32-bit versions, in which case they cannot be used with only be available in 32-bit versions, in which case they cannot be used with
@ -462,20 +462,20 @@ $ENV{CONFIG}="Debug";
<para> <para>
Running the regression tests on client programs, with Running the regression tests on client programs, with
<command>vcregress bincheck</>, or on recovery tests, with <command>vcregress bincheck</command>, or on recovery tests, with
<command>vcregress recoverycheck</>, requires an additional Perl module <command>vcregress recoverycheck</command>, requires an additional Perl module
to be installed: to be installed:
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><productname>IPC::Run</productname></term> <term><productname>IPC::Run</productname></term>
<listitem><para> <listitem><para>
As of this writing, <literal>IPC::Run</> is not included in the As of this writing, <literal>IPC::Run</literal> is not included in the
ActiveState Perl installation, nor in the ActiveState Perl Package ActiveState Perl installation, nor in the ActiveState Perl Package
Manager (PPM) library. To install, download the Manager (PPM) library. To install, download the
<filename>IPC-Run-&lt;version&gt;.tar.gz</> source archive from CPAN, <filename>IPC-Run-&lt;version&gt;.tar.gz</filename> source archive from CPAN,
at <ulink url="http://search.cpan.org/dist/IPC-Run/"></>, and at <ulink url="http://search.cpan.org/dist/IPC-Run/"></ulink>, and
uncompress. Edit the <filename>buildenv.pl</> file, and add a PERL5LIB uncompress. Edit the <filename>buildenv.pl</filename> file, and add a PERL5LIB
variable to point to the <filename>lib</> subdirectory from the variable to point to the <filename>lib</filename> subdirectory from the
extracted archive. For example: extracted archive. For example:
<programlisting> <programlisting>
$ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib'; $ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib';
@ -498,7 +498,7 @@ $ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib';
<term>OpenJade 1.3.1-2</term> <term>OpenJade 1.3.1-2</term>
<listitem><para> <listitem><para>
Download from Download from
<ulink url="http://sourceforge.net/projects/openjade/files/openjade/1.3.1/openjade-1_3_1-2-bin.zip/download"></> <ulink url="http://sourceforge.net/projects/openjade/files/openjade/1.3.1/openjade-1_3_1-2-bin.zip/download"></ulink>
and uncompress in the subdirectory <filename>openjade-1.3.1</filename>. and uncompress in the subdirectory <filename>openjade-1.3.1</filename>.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
@ -507,7 +507,7 @@ $ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib';
<term>DocBook DTD 4.2</term> <term>DocBook DTD 4.2</term>
<listitem><para> <listitem><para>
Download from Download from
<ulink url="http://www.oasis-open.org/docbook/sgml/4.2/docbook-4.2.zip"></> <ulink url="http://www.oasis-open.org/docbook/sgml/4.2/docbook-4.2.zip"></ulink>
and uncompress in the subdirectory <filename>docbook</filename>. and uncompress in the subdirectory <filename>docbook</filename>.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
@ -516,7 +516,7 @@ $ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib';
<term>ISO character entities</term> <term>ISO character entities</term>
<listitem><para> <listitem><para>
Download from Download from
<ulink url="http://www.oasis-open.org/cover/ISOEnts.zip"></> and <ulink url="http://www.oasis-open.org/cover/ISOEnts.zip"></ulink> and
uncompress in the subdirectory <filename>docbook</filename>. uncompress in the subdirectory <filename>docbook</filename>.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>

File diff suppressed because it is too large Load Diff

View File

@ -28,10 +28,10 @@
<para> <para>
The aggregator is an aggregate function The aggregator is an aggregate function
<function>int_array_aggregate(integer)</> <function>int_array_aggregate(integer)</function>
that produces an integer array that produces an integer array
containing exactly the integers it is fed. containing exactly the integers it is fed.
This is a wrapper around <function>array_agg</>, This is a wrapper around <function>array_agg</function>,
which does the same thing for any array type. which does the same thing for any array type.
</para> </para>
@ -41,10 +41,10 @@
<para> <para>
The enumerator is a function The enumerator is a function
<function>int_array_enum(integer[])</> <function>int_array_enum(integer[])</function>
that returns <type>setof integer</>. It is essentially the reverse that returns <type>setof integer</type>. It is essentially the reverse
operation of the aggregator: given an array of integers, expand it operation of the aggregator: given an array of integers, expand it
into a set of rows. This is a wrapper around <function>unnest</>, into a set of rows. This is a wrapper around <function>unnest</function>,
which does the same thing for any array type. which does the same thing for any array type.
</para> </para>
@ -67,7 +67,7 @@ CREATE TABLE one_to_many(left INT REFERENCES left, right INT REFERENCES right);
<programlisting> <programlisting>
SELECT right.* from right JOIN one_to_many ON (right.id = one_to_many.right) SELECT right.* from right JOIN one_to_many ON (right.id = one_to_many.right)
WHERE one_to_many.left = <replaceable>item</>; WHERE one_to_many.left = <replaceable>item</replaceable>;
</programlisting> </programlisting>
This will return all the items in the right hand table for an entry This will return all the items in the right hand table for an entry
@ -76,7 +76,7 @@ SELECT right.* from right JOIN one_to_many ON (right.id = one_to_many.right)
<para> <para>
Now, this methodology can be cumbersome with a very large number of Now, this methodology can be cumbersome with a very large number of
entries in the <structname>one_to_many</> table. Often, entries in the <structname>one_to_many</structname> table. Often,
a join like this would result in an index scan a join like this would result in an index scan
and a fetch for each right hand entry in the table for a particular and a fetch for each right hand entry in the table for a particular
left hand entry. If you have a very dynamic system, there is not much you left hand entry. If you have a very dynamic system, there is not much you
@ -95,30 +95,30 @@ CREATE TABLE summary AS
the array; that's why there is an array enumerator. You can do the array; that's why there is an array enumerator. You can do
<programlisting> <programlisting>
SELECT left, int_array_enum(right) FROM summary WHERE left = <replaceable>item</>; SELECT left, int_array_enum(right) FROM summary WHERE left = <replaceable>item</replaceable>;
</programlisting> </programlisting>
The above query using <function>int_array_enum</> produces the same results The above query using <function>int_array_enum</function> produces the same results
as as
<programlisting> <programlisting>
SELECT left, right FROM one_to_many WHERE left = <replaceable>item</>; SELECT left, right FROM one_to_many WHERE left = <replaceable>item</replaceable>;
</programlisting> </programlisting>
The difference is that the query against the summary table has to get The difference is that the query against the summary table has to get
only one row from the table, whereas the direct query against only one row from the table, whereas the direct query against
<structname>one_to_many</> must index scan and fetch a row for each entry. <structname>one_to_many</structname> must index scan and fetch a row for each entry.
</para> </para>
<para> <para>
On one system, an <command>EXPLAIN</> showed a query with a cost of 8488 was On one system, an <command>EXPLAIN</command> showed a query with a cost of 8488 was
reduced to a cost of 329. The original query was a join involving the reduced to a cost of 329. The original query was a join involving the
<structname>one_to_many</> table, which was replaced by: <structname>one_to_many</structname> table, which was replaced by:
<programlisting> <programlisting>
SELECT right, count(right) FROM SELECT right, count(right) FROM
( SELECT left, int_array_enum(right) AS right ( SELECT left, int_array_enum(right) AS right
FROM summary JOIN (SELECT left FROM left_table WHERE left = <replaceable>item</>) AS lefts FROM summary JOIN (SELECT left FROM left_table WHERE left = <replaceable>item</replaceable>) AS lefts
ON (summary.left = lefts.left) ON (summary.left = lefts.left)
) AS list ) AS list
GROUP BY right GROUP BY right

View File

@ -8,7 +8,7 @@
</indexterm> </indexterm>
<para> <para>
The <filename>intarray</> module provides a number of useful functions The <filename>intarray</filename> module provides a number of useful functions
and operators for manipulating null-free arrays of integers. and operators for manipulating null-free arrays of integers.
There is also support for indexed searches using some of the operators. There is also support for indexed searches using some of the operators.
</para> </para>
@ -25,7 +25,7 @@
</para> </para>
<sect2> <sect2>
<title><filename>intarray</> Functions and Operators</title> <title><filename>intarray</filename> Functions and Operators</title>
<para> <para>
The functions provided by the <filename>intarray</filename> module The functions provided by the <filename>intarray</filename> module
@ -34,7 +34,7 @@
</para> </para>
<table id="intarray-func-table"> <table id="intarray-func-table">
<title><filename>intarray</> Functions</title> <title><filename>intarray</filename> Functions</title>
<tgroup cols="5"> <tgroup cols="5">
<thead> <thead>
@ -59,7 +59,7 @@
<row> <row>
<entry><function>sort(int[], text dir)</function><indexterm><primary>sort</primary></indexterm></entry> <entry><function>sort(int[], text dir)</function><indexterm><primary>sort</primary></indexterm></entry>
<entry><type>int[]</type></entry> <entry><type>int[]</type></entry>
<entry>sort array &mdash; <parameter>dir</> must be <literal>asc</> or <literal>desc</></entry> <entry>sort array &mdash; <parameter>dir</parameter> must be <literal>asc</literal> or <literal>desc</literal></entry>
<entry><literal>sort('{1,2,3}'::int[], 'desc')</literal></entry> <entry><literal>sort('{1,2,3}'::int[], 'desc')</literal></entry>
<entry><literal>{3,2,1}</literal></entry> <entry><literal>{3,2,1}</literal></entry>
</row> </row>
@ -99,7 +99,7 @@
<row> <row>
<entry><function>idx(int[], int item)</function><indexterm><primary>idx</primary></indexterm></entry> <entry><function>idx(int[], int item)</function><indexterm><primary>idx</primary></indexterm></entry>
<entry><type>int</type></entry> <entry><type>int</type></entry>
<entry>index of first element matching <parameter>item</> (0 if none)</entry> <entry>index of first element matching <parameter>item</parameter> (0 if none)</entry>
<entry><literal>idx(array[11,22,33,22,11], 22)</literal></entry> <entry><literal>idx(array[11,22,33,22,11], 22)</literal></entry>
<entry><literal>2</literal></entry> <entry><literal>2</literal></entry>
</row> </row>
@ -107,7 +107,7 @@
<row> <row>
<entry><function>subarray(int[], int start, int len)</function><indexterm><primary>subarray</primary></indexterm></entry> <entry><function>subarray(int[], int start, int len)</function><indexterm><primary>subarray</primary></indexterm></entry>
<entry><type>int[]</type></entry> <entry><type>int[]</type></entry>
<entry>portion of array starting at position <parameter>start</>, <parameter>len</> elements</entry> <entry>portion of array starting at position <parameter>start</parameter>, <parameter>len</parameter> elements</entry>
<entry><literal>subarray('{1,2,3,2,1}'::int[], 2, 3)</literal></entry> <entry><literal>subarray('{1,2,3,2,1}'::int[], 2, 3)</literal></entry>
<entry><literal>{2,3,2}</literal></entry> <entry><literal>{2,3,2}</literal></entry>
</row> </row>
@ -115,7 +115,7 @@
<row> <row>
<entry><function>subarray(int[], int start)</function></entry> <entry><function>subarray(int[], int start)</function></entry>
<entry><type>int[]</type></entry> <entry><type>int[]</type></entry>
<entry>portion of array starting at position <parameter>start</></entry> <entry>portion of array starting at position <parameter>start</parameter></entry>
<entry><literal>subarray('{1,2,3,2,1}'::int[], 2)</literal></entry> <entry><literal>subarray('{1,2,3,2,1}'::int[], 2)</literal></entry>
<entry><literal>{2,3,2,1}</literal></entry> <entry><literal>{2,3,2,1}</literal></entry>
</row> </row>
@ -133,7 +133,7 @@
</table> </table>
<table id="intarray-op-table"> <table id="intarray-op-table">
<title><filename>intarray</> Operators</title> <title><filename>intarray</filename> Operators</title>
<tgroup cols="3"> <tgroup cols="3">
<thead> <thead>
@ -148,17 +148,17 @@
<row> <row>
<entry><literal>int[] &amp;&amp; int[]</literal></entry> <entry><literal>int[] &amp;&amp; int[]</literal></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>overlap &mdash; <literal>true</> if arrays have at least one common element</entry> <entry>overlap &mdash; <literal>true</literal> if arrays have at least one common element</entry>
</row> </row>
<row> <row>
<entry><literal>int[] @&gt; int[]</literal></entry> <entry><literal>int[] @&gt; int[]</literal></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>contains &mdash; <literal>true</> if left array contains right array</entry> <entry>contains &mdash; <literal>true</literal> if left array contains right array</entry>
</row> </row>
<row> <row>
<entry><literal>int[] &lt;@ int[]</literal></entry> <entry><literal>int[] &lt;@ int[]</literal></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>contained &mdash; <literal>true</> if left array is contained in right array</entry> <entry>contained &mdash; <literal>true</literal> if left array is contained in right array</entry>
</row> </row>
<row> <row>
<entry><literal># int[]</literal></entry> <entry><literal># int[]</literal></entry>
@ -168,7 +168,7 @@
<row> <row>
<entry><literal>int[] # int</literal></entry> <entry><literal>int[] # int</literal></entry>
<entry><type>int</type></entry> <entry><type>int</type></entry>
<entry>index (same as <function>idx</> function)</entry> <entry>index (same as <function>idx</function> function)</entry>
</row> </row>
<row> <row>
<entry><literal>int[] + int</literal></entry> <entry><literal>int[] + int</literal></entry>
@ -208,28 +208,28 @@
<row> <row>
<entry><literal>int[] @@ query_int</literal></entry> <entry><literal>int[] @@ query_int</literal></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry><literal>true</> if array satisfies query (see below)</entry> <entry><literal>true</literal> if array satisfies query (see below)</entry>
</row> </row>
<row> <row>
<entry><literal>query_int ~~ int[]</literal></entry> <entry><literal>query_int ~~ int[]</literal></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry><literal>true</> if array satisfies query (commutator of <literal>@@</>)</entry> <entry><literal>true</literal> if array satisfies query (commutator of <literal>@@</literal>)</entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
</table> </table>
<para> <para>
(Before PostgreSQL 8.2, the containment operators <literal>@&gt;</> and (Before PostgreSQL 8.2, the containment operators <literal>@&gt;</literal> and
<literal>&lt;@</> were respectively called <literal>@</> and <literal>~</>. <literal>&lt;@</literal> were respectively called <literal>@</literal> and <literal>~</literal>.
These names are still available, but are deprecated and will eventually be These names are still available, but are deprecated and will eventually be
retired. Notice that the old names are reversed from the convention retired. Notice that the old names are reversed from the convention
formerly followed by the core geometric data types!) formerly followed by the core geometric data types!)
</para> </para>
<para> <para>
The operators <literal>&amp;&amp;</>, <literal>@&gt;</> and The operators <literal>&amp;&amp;</literal>, <literal>@&gt;</literal> and
<literal>&lt;@</> are equivalent to <productname>PostgreSQL</>'s built-in <literal>&lt;@</literal> are equivalent to <productname>PostgreSQL</productname>'s built-in
operators of the same names, except that they work only on integer arrays operators of the same names, except that they work only on integer arrays
that do not contain nulls, while the built-in operators work for any array that do not contain nulls, while the built-in operators work for any array
type. This restriction makes them faster than the built-in operators type. This restriction makes them faster than the built-in operators
@ -237,14 +237,14 @@
</para> </para>
<para> <para>
The <literal>@@</> and <literal>~~</> operators test whether an array The <literal>@@</literal> and <literal>~~</literal> operators test whether an array
satisfies a <firstterm>query</>, which is expressed as a value of a satisfies a <firstterm>query</firstterm>, which is expressed as a value of a
specialized data type <type>query_int</>. A <firstterm>query</> specialized data type <type>query_int</type>. A <firstterm>query</firstterm>
consists of integer values that are checked against the elements of consists of integer values that are checked against the elements of
the array, possibly combined using the operators <literal>&amp;</> the array, possibly combined using the operators <literal>&amp;</literal>
(AND), <literal>|</> (OR), and <literal>!</> (NOT). Parentheses (AND), <literal>|</literal> (OR), and <literal>!</literal> (NOT). Parentheses
can be used as needed. For example, can be used as needed. For example,
the query <literal>1&amp;(2|3)</> matches arrays that contain 1 the query <literal>1&amp;(2|3)</literal> matches arrays that contain 1
and also contain either 2 or 3. and also contain either 2 or 3.
</para> </para>
</sect2> </sect2>
@ -253,16 +253,16 @@
<title>Index Support</title> <title>Index Support</title>
<para> <para>
<filename>intarray</> provides index support for the <filename>intarray</filename> provides index support for the
<literal>&amp;&amp;</>, <literal>@&gt;</>, <literal>&lt;@</>, <literal>&amp;&amp;</literal>, <literal>@&gt;</literal>, <literal>&lt;@</literal>,
and <literal>@@</> operators, as well as regular array equality. and <literal>@@</literal> operators, as well as regular array equality.
</para> </para>
<para> <para>
Two GiST index operator classes are provided: Two GiST index operator classes are provided:
<literal>gist__int_ops</> (used by default) is suitable for <literal>gist__int_ops</literal> (used by default) is suitable for
small- to medium-size data sets, while small- to medium-size data sets, while
<literal>gist__intbig_ops</> uses a larger signature and is more <literal>gist__intbig_ops</literal> uses a larger signature and is more
suitable for indexing large data sets (i.e., columns containing suitable for indexing large data sets (i.e., columns containing
a large number of distinct array values). a large number of distinct array values).
The implementation uses an RD-tree data structure with The implementation uses an RD-tree data structure with
@ -271,7 +271,7 @@
<para> <para>
There is also a non-default GIN operator class There is also a non-default GIN operator class
<literal>gin__int_ops</> supporting the same operators. <literal>gin__int_ops</literal> supporting the same operators.
</para> </para>
<para> <para>
@ -284,7 +284,7 @@
<title>Example</title> <title>Example</title>
<programlisting> <programlisting>
-- a message can be in one or more <quote>sections</> -- a message can be in one or more <quote>sections</quote>
CREATE TABLE message (mid INT PRIMARY KEY, sections INT[], ...); CREATE TABLE message (mid INT PRIMARY KEY, sections INT[], ...);
-- create specialized index -- create specialized index
@ -305,9 +305,9 @@ SELECT message.mid FROM message WHERE message.sections @@ '1&amp;2'::query_int;
<title>Benchmark</title> <title>Benchmark</title>
<para> <para>
The source directory <filename>contrib/intarray/bench</> contains a The source directory <filename>contrib/intarray/bench</filename> contains a
benchmark test suite, which can be run against an installed benchmark test suite, which can be run against an installed
<productname>PostgreSQL</> server. (It also requires <filename>DBD::Pg</> <productname>PostgreSQL</productname> server. (It also requires <filename>DBD::Pg</filename>
to be installed.) To run: to be installed.) To run:
</para> </para>
@ -320,7 +320,7 @@ psql -c "CREATE EXTENSION intarray" TEST
</programlisting> </programlisting>
<para> <para>
The <filename>bench.pl</> script has numerous options, which The <filename>bench.pl</filename> script has numerous options, which
are displayed when it is run without any arguments. are displayed when it is run without any arguments.
</para> </para>
</sect2> </sect2>

View File

@ -32,7 +32,7 @@
<xref linkend="sql"> documents the <acronym>SQL</acronym> query <xref linkend="sql"> documents the <acronym>SQL</acronym> query
language environment, including data types and functions, as well language environment, including data types and functions, as well
as user-level performance tuning. Every as user-level performance tuning. Every
<productname>PostgreSQL</> user should read this. <productname>PostgreSQL</productname> user should read this.
</para> </para>
</listitem> </listitem>
@ -75,7 +75,7 @@
<listitem> <listitem>
<para> <para>
<xref linkend="internals"> contains assorted information that might be of <xref linkend="internals"> contains assorted information that might be of
use to <productname>PostgreSQL</> developers. use to <productname>PostgreSQL</productname> developers.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>

View File

@ -123,7 +123,7 @@
</listitem> </listitem>
<listitem> <listitem>
<para>UPC numbers are a subset of the EAN13 numbers (they are basically <para>UPC numbers are a subset of the EAN13 numbers (they are basically
EAN13 without the first <literal>0</> digit).</para> EAN13 without the first <literal>0</literal> digit).</para>
</listitem> </listitem>
<listitem> <listitem>
<para>All UPC, ISBN, ISMN and ISSN numbers can be represented as EAN13 <para>All UPC, ISBN, ISMN and ISSN numbers can be represented as EAN13
@ -139,7 +139,7 @@
</para> </para>
<para> <para>
The <type>ISBN</>, <type>ISMN</>, and <type>ISSN</> types will display the The <type>ISBN</type>, <type>ISMN</type>, and <type>ISSN</type> types will display the
short version of the number (ISxN 10) whenever it's possible, and will show short version of the number (ISxN 10) whenever it's possible, and will show
ISxN 13 format for numbers that do not fit in the short version. ISxN 13 format for numbers that do not fit in the short version.
The <type>EAN13</type>, <type>ISBN13</type>, <type>ISMN13</type> and The <type>EAN13</type>, <type>ISBN13</type>, <type>ISMN13</type> and
@ -152,7 +152,7 @@
<title>Casts</title> <title>Casts</title>
<para> <para>
The <filename>isn</> module provides the following pairs of type casts: The <filename>isn</filename> module provides the following pairs of type casts:
</para> </para>
<itemizedlist> <itemizedlist>
@ -209,7 +209,7 @@
</itemizedlist> </itemizedlist>
<para> <para>
When casting from <type>EAN13</> to another type, there is a run-time When casting from <type>EAN13</type> to another type, there is a run-time
check that the value is within the domain of the other type, and an error check that the value is within the domain of the other type, and an error
is thrown if not. The other casts are simply relabelings that will is thrown if not. The other casts are simply relabelings that will
always succeed. always succeed.
@ -220,15 +220,15 @@
<title>Functions and Operators</title> <title>Functions and Operators</title>
<para> <para>
The <filename>isn</> module provides the standard comparison operators, The <filename>isn</filename> module provides the standard comparison operators,
plus B-tree and hash indexing support for all these data types. In plus B-tree and hash indexing support for all these data types. In
addition there are several specialized functions; shown in <xref linkend="isn-functions">. addition there are several specialized functions; shown in <xref linkend="isn-functions">.
In this table, In this table,
<type>isn</> means any one of the module's data types. <type>isn</type> means any one of the module's data types.
</para> </para>
<table id="isn-functions"> <table id="isn-functions">
<title><filename>isn</> Functions</title> <title><filename>isn</filename> Functions</title>
<tgroup cols="3"> <tgroup cols="3">
<thead> <thead>
<row> <row>
@ -285,21 +285,21 @@
<para> <para>
When you insert invalid numbers in a table using the weak mode, the number When you insert invalid numbers in a table using the weak mode, the number
will be inserted with the corrected check digit, but it will be displayed will be inserted with the corrected check digit, but it will be displayed
with an exclamation mark (<literal>!</>) at the end, for example with an exclamation mark (<literal>!</literal>) at the end, for example
<literal>0-11-000322-5!</>. This invalid marker can be checked with <literal>0-11-000322-5!</literal>. This invalid marker can be checked with
the <function>is_valid</> function and cleared with the the <function>is_valid</function> function and cleared with the
<function>make_valid</> function. <function>make_valid</function> function.
</para> </para>
<para> <para>
You can also force the insertion of invalid numbers even when not in the You can also force the insertion of invalid numbers even when not in the
weak mode, by appending the <literal>!</> character at the end of the weak mode, by appending the <literal>!</literal> character at the end of the
number. number.
</para> </para>
<para> <para>
Another special feature is that during input, you can write Another special feature is that during input, you can write
<literal>?</> in place of the check digit, and the correct check digit <literal>?</literal> in place of the check digit, and the correct check digit
will be inserted automatically. will be inserted automatically.
</para> </para>
</sect2> </sect2>
@ -384,7 +384,7 @@ SELECT isbn13(id) FROM test;
<para> <para>
This module was inspired by Garrett A. Wollman's This module was inspired by Garrett A. Wollman's
<filename>isbn_issn</> code. <filename>isbn_issn</filename> code.
</para> </para>
</sect2> </sect2>

View File

@ -1,7 +1,7 @@
<!-- doc/src/sgml/json.sgml --> <!-- doc/src/sgml/json.sgml -->
<sect1 id="datatype-json"> <sect1 id="datatype-json">
<title><acronym>JSON</> Types</title> <title><acronym>JSON</acronym> Types</title>
<indexterm zone="datatype-json"> <indexterm zone="datatype-json">
<primary>JSON</primary> <primary>JSON</primary>
@ -22,25 +22,25 @@
</para> </para>
<para> <para>
There are two JSON data types: <type>json</> and <type>jsonb</>. There are two JSON data types: <type>json</type> and <type>jsonb</type>.
They accept <emphasis>almost</> identical sets of values as They accept <emphasis>almost</emphasis> identical sets of values as
input. The major practical difference is one of efficiency. The input. The major practical difference is one of efficiency. The
<type>json</> data type stores an exact copy of the input text, <type>json</type> data type stores an exact copy of the input text,
which processing functions must reparse on each execution; while which processing functions must reparse on each execution; while
<type>jsonb</> data is stored in a decomposed binary format that <type>jsonb</type> data is stored in a decomposed binary format that
makes it slightly slower to input due to added conversion makes it slightly slower to input due to added conversion
overhead, but significantly faster to process, since no reparsing overhead, but significantly faster to process, since no reparsing
is needed. <type>jsonb</> also supports indexing, which can be a is needed. <type>jsonb</type> also supports indexing, which can be a
significant advantage. significant advantage.
</para> </para>
<para> <para>
Because the <type>json</> type stores an exact copy of the input text, it Because the <type>json</type> type stores an exact copy of the input text, it
will preserve semantically-insignificant white space between tokens, as will preserve semantically-insignificant white space between tokens, as
well as the order of keys within JSON objects. Also, if a JSON object well as the order of keys within JSON objects. Also, if a JSON object
within the value contains the same key more than once, all the key/value within the value contains the same key more than once, all the key/value
pairs are kept. (The processing functions consider the last value as the pairs are kept. (The processing functions consider the last value as the
operative one.) By contrast, <type>jsonb</> does not preserve white operative one.) By contrast, <type>jsonb</type> does not preserve white
space, does not preserve the order of object keys, and does not keep space, does not preserve the order of object keys, and does not keep
duplicate object keys. If duplicate keys are specified in the input, duplicate object keys. If duplicate keys are specified in the input,
only the last value is kept. only the last value is kept.
@ -48,7 +48,7 @@
<para> <para>
In general, most applications should prefer to store JSON data as In general, most applications should prefer to store JSON data as
<type>jsonb</>, unless there are quite specialized needs, such as <type>jsonb</type>, unless there are quite specialized needs, such as
legacy assumptions about ordering of object keys. legacy assumptions about ordering of object keys.
</para> </para>
@ -64,15 +64,15 @@
<para> <para>
RFC 7159 permits JSON strings to contain Unicode escape sequences RFC 7159 permits JSON strings to contain Unicode escape sequences
denoted by <literal>\u<replaceable>XXXX</></literal>. In the input denoted by <literal>\u<replaceable>XXXX</replaceable></literal>. In the input
function for the <type>json</> type, Unicode escapes are allowed function for the <type>json</type> type, Unicode escapes are allowed
regardless of the database encoding, and are checked only for syntactic regardless of the database encoding, and are checked only for syntactic
correctness (that is, that four hex digits follow <literal>\u</>). correctness (that is, that four hex digits follow <literal>\u</literal>).
However, the input function for <type>jsonb</> is stricter: it disallows However, the input function for <type>jsonb</type> is stricter: it disallows
Unicode escapes for non-ASCII characters (those above <literal>U+007F</>) Unicode escapes for non-ASCII characters (those above <literal>U+007F</literal>)
unless the database encoding is UTF8. The <type>jsonb</> type also unless the database encoding is UTF8. The <type>jsonb</type> type also
rejects <literal>\u0000</> (because that cannot be represented in rejects <literal>\u0000</literal> (because that cannot be represented in
<productname>PostgreSQL</productname>'s <type>text</> type), and it insists <productname>PostgreSQL</productname>'s <type>text</type> type), and it insists
that any use of Unicode surrogate pairs to designate characters outside that any use of Unicode surrogate pairs to designate characters outside
the Unicode Basic Multilingual Plane be correct. Valid Unicode escapes the Unicode Basic Multilingual Plane be correct. Valid Unicode escapes
are converted to the equivalent ASCII or UTF8 character for storage; are converted to the equivalent ASCII or UTF8 character for storage;
@ -84,8 +84,8 @@
Many of the JSON processing functions described Many of the JSON processing functions described
in <xref linkend="functions-json"> will convert Unicode escapes to in <xref linkend="functions-json"> will convert Unicode escapes to
regular characters, and will therefore throw the same types of errors regular characters, and will therefore throw the same types of errors
just described even if their input is of type <type>json</> just described even if their input is of type <type>json</type>
not <type>jsonb</>. The fact that the <type>json</> input function does not <type>jsonb</type>. The fact that the <type>json</type> input function does
not make these checks may be considered a historical artifact, although not make these checks may be considered a historical artifact, although
it does allow for simple storage (without processing) of JSON Unicode it does allow for simple storage (without processing) of JSON Unicode
escapes in a non-UTF8 database encoding. In general, it is best to escapes in a non-UTF8 database encoding. In general, it is best to
@ -95,22 +95,22 @@
</note> </note>
<para> <para>
When converting textual JSON input into <type>jsonb</>, the primitive When converting textual JSON input into <type>jsonb</type>, the primitive
types described by <acronym>RFC</> 7159 are effectively mapped onto types described by <acronym>RFC</acronym> 7159 are effectively mapped onto
native <productname>PostgreSQL</productname> types, as shown native <productname>PostgreSQL</productname> types, as shown
in <xref linkend="json-type-mapping-table">. in <xref linkend="json-type-mapping-table">.
Therefore, there are some minor additional constraints on what Therefore, there are some minor additional constraints on what
constitutes valid <type>jsonb</type> data that do not apply to constitutes valid <type>jsonb</type> data that do not apply to
the <type>json</type> type, nor to JSON in the abstract, corresponding the <type>json</type> type, nor to JSON in the abstract, corresponding
to limits on what can be represented by the underlying data type. to limits on what can be represented by the underlying data type.
Notably, <type>jsonb</> will reject numbers that are outside the Notably, <type>jsonb</type> will reject numbers that are outside the
range of the <productname>PostgreSQL</productname> <type>numeric</> data range of the <productname>PostgreSQL</productname> <type>numeric</type> data
type, while <type>json</> will not. Such implementation-defined type, while <type>json</type> will not. Such implementation-defined
restrictions are permitted by <acronym>RFC</> 7159. However, in restrictions are permitted by <acronym>RFC</acronym> 7159. However, in
practice such problems are far more likely to occur in other practice such problems are far more likely to occur in other
implementations, as it is common to represent JSON's <type>number</> implementations, as it is common to represent JSON's <type>number</type>
primitive type as IEEE 754 double precision floating point primitive type as IEEE 754 double precision floating point
(which <acronym>RFC</> 7159 explicitly anticipates and allows for). (which <acronym>RFC</acronym> 7159 explicitly anticipates and allows for).
When using JSON as an interchange format with such systems, the danger When using JSON as an interchange format with such systems, the danger
of losing numeric precision compared to data originally stored of losing numeric precision compared to data originally stored
by <productname>PostgreSQL</productname> should be considered. by <productname>PostgreSQL</productname> should be considered.
@ -134,23 +134,23 @@
</thead> </thead>
<tbody> <tbody>
<row> <row>
<entry><type>string</></entry> <entry><type>string</type></entry>
<entry><type>text</></entry> <entry><type>text</type></entry>
<entry><literal>\u0000</> is disallowed, as are non-ASCII Unicode <entry><literal>\u0000</literal> is disallowed, as are non-ASCII Unicode
escapes if database encoding is not UTF8</entry> escapes if database encoding is not UTF8</entry>
</row> </row>
<row> <row>
<entry><type>number</></entry> <entry><type>number</type></entry>
<entry><type>numeric</></entry> <entry><type>numeric</type></entry>
<entry><literal>NaN</literal> and <literal>infinity</literal> values are disallowed</entry> <entry><literal>NaN</literal> and <literal>infinity</literal> values are disallowed</entry>
</row> </row>
<row> <row>
<entry><type>boolean</></entry> <entry><type>boolean</type></entry>
<entry><type>boolean</></entry> <entry><type>boolean</type></entry>
<entry>Only lowercase <literal>true</literal> and <literal>false</literal> spellings are accepted</entry> <entry>Only lowercase <literal>true</literal> and <literal>false</literal> spellings are accepted</entry>
</row> </row>
<row> <row>
<entry><type>null</></entry> <entry><type>null</type></entry>
<entry>(none)</entry> <entry>(none)</entry>
<entry>SQL <literal>NULL</literal> is a different concept</entry> <entry>SQL <literal>NULL</literal> is a different concept</entry>
</row> </row>
@ -162,10 +162,10 @@
<title>JSON Input and Output Syntax</title> <title>JSON Input and Output Syntax</title>
<para> <para>
The input/output syntax for the JSON data types is as specified in The input/output syntax for the JSON data types is as specified in
<acronym>RFC</> 7159. <acronym>RFC</acronym> 7159.
</para> </para>
<para> <para>
The following are all valid <type>json</> (or <type>jsonb</>) expressions: The following are all valid <type>json</type> (or <type>jsonb</type>) expressions:
<programlisting> <programlisting>
-- Simple scalar/primitive value -- Simple scalar/primitive value
-- Primitive values can be numbers, quoted strings, true, false, or null -- Primitive values can be numbers, quoted strings, true, false, or null
@ -185,8 +185,8 @@ SELECT '{"foo": [true, "bar"], "tags": {"a": 1, "b": null}}'::json;
<para> <para>
As previously stated, when a JSON value is input and then printed without As previously stated, when a JSON value is input and then printed without
any additional processing, <type>json</> outputs the same text that was any additional processing, <type>json</type> outputs the same text that was
input, while <type>jsonb</> does not preserve semantically-insignificant input, while <type>jsonb</type> does not preserve semantically-insignificant
details such as whitespace. For example, note the differences here: details such as whitespace. For example, note the differences here:
<programlisting> <programlisting>
SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::json; SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::json;
@ -202,9 +202,9 @@ SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::jsonb;
(1 row) (1 row)
</programlisting> </programlisting>
One semantically-insignificant detail worth noting is that One semantically-insignificant detail worth noting is that
in <type>jsonb</>, numbers will be printed according to the behavior of the in <type>jsonb</type>, numbers will be printed according to the behavior of the
underlying <type>numeric</> type. In practice this means that numbers underlying <type>numeric</type> type. In practice this means that numbers
entered with <literal>E</> notation will be printed without it, for entered with <literal>E</literal> notation will be printed without it, for
example: example:
<programlisting> <programlisting>
SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb; SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb;
@ -213,7 +213,7 @@ SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb;
{"reading": 1.230e-5} | {"reading": 0.00001230} {"reading": 1.230e-5} | {"reading": 0.00001230}
(1 row) (1 row)
</programlisting> </programlisting>
However, <type>jsonb</> will preserve trailing fractional zeroes, as seen However, <type>jsonb</type> will preserve trailing fractional zeroes, as seen
in this example, even though those are semantically insignificant for in this example, even though those are semantically insignificant for
purposes such as equality checks. purposes such as equality checks.
</para> </para>
@ -231,7 +231,7 @@ SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb;
have a somewhat fixed structure. The structure is typically have a somewhat fixed structure. The structure is typically
unenforced (though enforcing some business rules declaratively is unenforced (though enforcing some business rules declaratively is
possible), but having a predictable structure makes it easier to write possible), but having a predictable structure makes it easier to write
queries that usefully summarize a set of <quote>documents</> (datums) queries that usefully summarize a set of <quote>documents</quote> (datums)
in a table. in a table.
</para> </para>
<para> <para>
@ -249,7 +249,7 @@ SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb;
</sect2> </sect2>
<sect2 id="json-containment"> <sect2 id="json-containment">
<title><type>jsonb</> Containment and Existence</title> <title><type>jsonb</type> Containment and Existence</title>
<indexterm> <indexterm>
<primary>jsonb</primary> <primary>jsonb</primary>
<secondary>containment</secondary> <secondary>containment</secondary>
@ -259,10 +259,10 @@ SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb;
<secondary>existence</secondary> <secondary>existence</secondary>
</indexterm> </indexterm>
<para> <para>
Testing <firstterm>containment</> is an important capability of Testing <firstterm>containment</firstterm> is an important capability of
<type>jsonb</>. There is no parallel set of facilities for the <type>jsonb</type>. There is no parallel set of facilities for the
<type>json</> type. Containment tests whether <type>json</type> type. Containment tests whether
one <type>jsonb</> document has contained within it another one. one <type>jsonb</type> document has contained within it another one.
These examples return true except as noted: These examples return true except as noted:
</para> </para>
<programlisting> <programlisting>
@ -282,7 +282,7 @@ SELECT '[1, 2, 3]'::jsonb @&gt; '[1, 2, 2]'::jsonb;
-- within the object on the left side: -- within the object on the left side:
SELECT '{"product": "PostgreSQL", "version": 9.4, "jsonb": true}'::jsonb @&gt; '{"version": 9.4}'::jsonb; SELECT '{"product": "PostgreSQL", "version": 9.4, "jsonb": true}'::jsonb @&gt; '{"version": 9.4}'::jsonb;
-- The array on the right side is <emphasis>not</> considered contained within the -- The array on the right side is <emphasis>not</emphasis> considered contained within the
-- array on the left, even though a similar array is nested within it: -- array on the left, even though a similar array is nested within it:
SELECT '[1, 2, [1, 3]]'::jsonb @&gt; '[1, 3]'::jsonb; -- yields false SELECT '[1, 2, [1, 3]]'::jsonb @&gt; '[1, 3]'::jsonb; -- yields false
@ -319,10 +319,10 @@ SELECT '"bar"'::jsonb @&gt; '["bar"]'::jsonb; -- yields false
</programlisting> </programlisting>
<para> <para>
<type>jsonb</> also has an <firstterm>existence</> operator, which is <type>jsonb</type> also has an <firstterm>existence</firstterm> operator, which is
a variation on the theme of containment: it tests whether a string a variation on the theme of containment: it tests whether a string
(given as a <type>text</> value) appears as an object key or array (given as a <type>text</type> value) appears as an object key or array
element at the top level of the <type>jsonb</> value. element at the top level of the <type>jsonb</type> value.
These examples return true except as noted: These examples return true except as noted:
</para> </para>
<programlisting> <programlisting>
@ -353,11 +353,11 @@ SELECT '"foo"'::jsonb ? 'foo';
<para> <para>
Because JSON containment is nested, an appropriate query can skip Because JSON containment is nested, an appropriate query can skip
explicit selection of sub-objects. As an example, suppose that we have explicit selection of sub-objects. As an example, suppose that we have
a <structfield>doc</> column containing objects at the top level, with a <structfield>doc</structfield> column containing objects at the top level, with
most objects containing <literal>tags</> fields that contain arrays of most objects containing <literal>tags</literal> fields that contain arrays of
sub-objects. This query finds entries in which sub-objects containing sub-objects. This query finds entries in which sub-objects containing
both <literal>"term":"paris"</> and <literal>"term":"food"</> appear, both <literal>"term":"paris"</literal> and <literal>"term":"food"</literal> appear,
while ignoring any such keys outside the <literal>tags</> array: while ignoring any such keys outside the <literal>tags</literal> array:
<programlisting> <programlisting>
SELECT doc-&gt;'site_name' FROM websites SELECT doc-&gt;'site_name' FROM websites
WHERE doc @&gt; '{"tags":[{"term":"paris"}, {"term":"food"}]}'; WHERE doc @&gt; '{"tags":[{"term":"paris"}, {"term":"food"}]}';
@ -385,7 +385,7 @@ SELECT doc-&gt;'site_name' FROM websites
</sect2> </sect2>
<sect2 id="json-indexing"> <sect2 id="json-indexing">
<title><type>jsonb</> Indexing</title> <title><type>jsonb</type> Indexing</title>
<indexterm> <indexterm>
<primary>jsonb</primary> <primary>jsonb</primary>
<secondary>indexes on</secondary> <secondary>indexes on</secondary>
@ -394,23 +394,23 @@ SELECT doc-&gt;'site_name' FROM websites
<para> <para>
GIN indexes can be used to efficiently search for GIN indexes can be used to efficiently search for
keys or key/value pairs occurring within a large number of keys or key/value pairs occurring within a large number of
<type>jsonb</> documents (datums). <type>jsonb</type> documents (datums).
Two GIN <quote>operator classes</> are provided, offering different Two GIN <quote>operator classes</quote> are provided, offering different
performance and flexibility trade-offs. performance and flexibility trade-offs.
</para> </para>
<para> <para>
The default GIN operator class for <type>jsonb</> supports queries with The default GIN operator class for <type>jsonb</type> supports queries with
top-level key-exists operators <literal>?</>, <literal>?&amp;</> top-level key-exists operators <literal>?</literal>, <literal>?&amp;</literal>
and <literal>?|</> operators and path/value-exists operator and <literal>?|</literal> operators and path/value-exists operator
<literal>@&gt;</>. <literal>@&gt;</literal>.
(For details of the semantics that these operators (For details of the semantics that these operators
implement, see <xref linkend="functions-jsonb-op-table">.) implement, see <xref linkend="functions-jsonb-op-table">.)
An example of creating an index with this operator class is: An example of creating an index with this operator class is:
<programlisting> <programlisting>
CREATE INDEX idxgin ON api USING GIN (jdoc); CREATE INDEX idxgin ON api USING GIN (jdoc);
</programlisting> </programlisting>
The non-default GIN operator class <literal>jsonb_path_ops</> The non-default GIN operator class <literal>jsonb_path_ops</literal>
supports indexing the <literal>@&gt;</> operator only. supports indexing the <literal>@&gt;</literal> operator only.
An example of creating an index with this operator class is: An example of creating an index with this operator class is:
<programlisting> <programlisting>
CREATE INDEX idxginp ON api USING GIN (jdoc jsonb_path_ops); CREATE INDEX idxginp ON api USING GIN (jdoc jsonb_path_ops);
@ -438,8 +438,8 @@ CREATE INDEX idxginp ON api USING GIN (jdoc jsonb_path_ops);
] ]
} }
</programlisting> </programlisting>
We store these documents in a table named <structname>api</>, We store these documents in a table named <structname>api</structname>,
in a <type>jsonb</> column named <structfield>jdoc</>. in a <type>jsonb</type> column named <structfield>jdoc</structfield>.
If a GIN index is created on this column, If a GIN index is created on this column,
queries like the following can make use of the index: queries like the following can make use of the index:
<programlisting> <programlisting>
@ -447,23 +447,23 @@ CREATE INDEX idxginp ON api USING GIN (jdoc jsonb_path_ops);
SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc @&gt; '{"company": "Magnafone"}'; SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc @&gt; '{"company": "Magnafone"}';
</programlisting> </programlisting>
However, the index could not be used for queries like the However, the index could not be used for queries like the
following, because though the operator <literal>?</> is indexable, following, because though the operator <literal>?</literal> is indexable,
it is not applied directly to the indexed column <structfield>jdoc</>: it is not applied directly to the indexed column <structfield>jdoc</structfield>:
<programlisting> <programlisting>
-- Find documents in which the key "tags" contains key or array element "qui" -- Find documents in which the key "tags" contains key or array element "qui"
SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc -&gt; 'tags' ? 'qui'; SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc -&gt; 'tags' ? 'qui';
</programlisting> </programlisting>
Still, with appropriate use of expression indexes, the above Still, with appropriate use of expression indexes, the above
query can use an index. If querying for particular items within query can use an index. If querying for particular items within
the <literal>"tags"</> key is common, defining an index like this the <literal>"tags"</literal> key is common, defining an index like this
may be worthwhile: may be worthwhile:
<programlisting> <programlisting>
CREATE INDEX idxgintags ON api USING GIN ((jdoc -&gt; 'tags')); CREATE INDEX idxgintags ON api USING GIN ((jdoc -&gt; 'tags'));
</programlisting> </programlisting>
Now, the <literal>WHERE</> clause <literal>jdoc -&gt; 'tags' ? 'qui'</> Now, the <literal>WHERE</literal> clause <literal>jdoc -&gt; 'tags' ? 'qui'</literal>
will be recognized as an application of the indexable will be recognized as an application of the indexable
operator <literal>?</> to the indexed operator <literal>?</literal> to the indexed
expression <literal>jdoc -&gt; 'tags'</>. expression <literal>jdoc -&gt; 'tags'</literal>.
(More information on expression indexes can be found in <xref (More information on expression indexes can be found in <xref
linkend="indexes-expressional">.) linkend="indexes-expressional">.)
</para> </para>
@ -473,11 +473,11 @@ CREATE INDEX idxgintags ON api USING GIN ((jdoc -&gt; 'tags'));
-- Find documents in which the key "tags" contains array element "qui" -- Find documents in which the key "tags" contains array element "qui"
SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc @&gt; '{"tags": ["qui"]}'; SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc @&gt; '{"tags": ["qui"]}';
</programlisting> </programlisting>
A simple GIN index on the <structfield>jdoc</> column can support this A simple GIN index on the <structfield>jdoc</structfield> column can support this
query. But note that such an index will store copies of every key and query. But note that such an index will store copies of every key and
value in the <structfield>jdoc</> column, whereas the expression index value in the <structfield>jdoc</structfield> column, whereas the expression index
of the previous example stores only data found under of the previous example stores only data found under
the <literal>tags</> key. While the simple-index approach is far more the <literal>tags</literal> key. While the simple-index approach is far more
flexible (since it supports queries about any key), targeted expression flexible (since it supports queries about any key), targeted expression
indexes are likely to be smaller and faster to search than a simple indexes are likely to be smaller and faster to search than a simple
index. index.
@ -485,7 +485,7 @@ SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc @&gt; '{"tags": ["qu
<para> <para>
Although the <literal>jsonb_path_ops</literal> operator class supports Although the <literal>jsonb_path_ops</literal> operator class supports
only queries with the <literal>@&gt;</> operator, it has notable only queries with the <literal>@&gt;</literal> operator, it has notable
performance advantages over the default operator performance advantages over the default operator
class <literal>jsonb_ops</literal>. A <literal>jsonb_path_ops</literal> class <literal>jsonb_ops</literal>. A <literal>jsonb_path_ops</literal>
index is usually much smaller than a <literal>jsonb_ops</literal> index is usually much smaller than a <literal>jsonb_ops</literal>
@ -503,7 +503,7 @@ SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc @&gt; '{"tags": ["qu
data. data.
<footnote> <footnote>
<para> <para>
For this purpose, the term <quote>value</> includes array elements, For this purpose, the term <quote>value</quote> includes array elements,
though JSON terminology sometimes considers array elements distinct though JSON terminology sometimes considers array elements distinct
from values within objects. from values within objects.
</para> </para>
@ -511,13 +511,13 @@ SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc @&gt; '{"tags": ["qu
Basically, each <literal>jsonb_path_ops</literal> index item is Basically, each <literal>jsonb_path_ops</literal> index item is
a hash of the value and the key(s) leading to it; for example to index a hash of the value and the key(s) leading to it; for example to index
<literal>{"foo": {"bar": "baz"}}</literal>, a single index item would <literal>{"foo": {"bar": "baz"}}</literal>, a single index item would
be created incorporating all three of <literal>foo</>, <literal>bar</>, be created incorporating all three of <literal>foo</literal>, <literal>bar</literal>,
and <literal>baz</> into the hash value. Thus a containment query and <literal>baz</literal> into the hash value. Thus a containment query
looking for this structure would result in an extremely specific index looking for this structure would result in an extremely specific index
search; but there is no way at all to find out whether <literal>foo</> search; but there is no way at all to find out whether <literal>foo</literal>
appears as a key. On the other hand, a <literal>jsonb_ops</literal> appears as a key. On the other hand, a <literal>jsonb_ops</literal>
index would create three index items representing <literal>foo</>, index would create three index items representing <literal>foo</literal>,
<literal>bar</>, and <literal>baz</> separately; then to do the <literal>bar</literal>, and <literal>baz</literal> separately; then to do the
containment query, it would look for rows containing all three of containment query, it would look for rows containing all three of
these items. While GIN indexes can perform such an AND search fairly these items. While GIN indexes can perform such an AND search fairly
efficiently, it will still be less specific and slower than the efficiently, it will still be less specific and slower than the
@ -531,15 +531,15 @@ SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc @&gt; '{"tags": ["qu
that it produces no index entries for JSON structures not containing that it produces no index entries for JSON structures not containing
any values, such as <literal>{"a": {}}</literal>. If a search for any values, such as <literal>{"a": {}}</literal>. If a search for
documents containing such a structure is requested, it will require a documents containing such a structure is requested, it will require a
full-index scan, which is quite slow. <literal>jsonb_path_ops</> is full-index scan, which is quite slow. <literal>jsonb_path_ops</literal> is
therefore ill-suited for applications that often perform such searches. therefore ill-suited for applications that often perform such searches.
</para> </para>
<para> <para>
<type>jsonb</> also supports <literal>btree</> and <literal>hash</> <type>jsonb</type> also supports <literal>btree</literal> and <literal>hash</literal>
indexes. These are usually useful only if it's important to check indexes. These are usually useful only if it's important to check
equality of complete JSON documents. equality of complete JSON documents.
The <literal>btree</> ordering for <type>jsonb</> datums is seldom The <literal>btree</literal> ordering for <type>jsonb</type> datums is seldom
of great interest, but for completeness it is: of great interest, but for completeness it is:
<synopsis> <synopsis>
<replaceable>Object</replaceable> > <replaceable>Array</replaceable> > <replaceable>Boolean</replaceable> > <replaceable>Number</replaceable> > <replaceable>String</replaceable> > <replaceable>Null</replaceable> <replaceable>Object</replaceable> > <replaceable>Array</replaceable> > <replaceable>Boolean</replaceable> > <replaceable>Number</replaceable> > <replaceable>String</replaceable> > <replaceable>Null</replaceable>

File diff suppressed because it is too large Load Diff

View File

@ -8,9 +8,9 @@
</indexterm> </indexterm>
<para> <para>
The <filename>lo</> module provides support for managing Large Objects The <filename>lo</filename> module provides support for managing Large Objects
(also called LOs or BLOBs). This includes a data type <type>lo</> (also called LOs or BLOBs). This includes a data type <type>lo</type>
and a trigger <function>lo_manage</>. and a trigger <function>lo_manage</function>.
</para> </para>
<sect2> <sect2>
@ -24,7 +24,7 @@
</para> </para>
<para> <para>
As <productname>PostgreSQL</> stands, this doesn't occur. Large objects As <productname>PostgreSQL</productname> stands, this doesn't occur. Large objects
are treated as objects in their own right; a table entry can reference a are treated as objects in their own right; a table entry can reference a
large object by OID, but there can be multiple table entries referencing large object by OID, but there can be multiple table entries referencing
the same large object OID, so the system doesn't delete the large object the same large object OID, so the system doesn't delete the large object
@ -32,30 +32,30 @@
</para> </para>
<para> <para>
Now this is fine for <productname>PostgreSQL</>-specific applications, but Now this is fine for <productname>PostgreSQL</productname>-specific applications, but
standard code using JDBC or ODBC won't delete the objects, resulting in standard code using JDBC or ODBC won't delete the objects, resulting in
orphan objects &mdash; objects that are not referenced by anything, and orphan objects &mdash; objects that are not referenced by anything, and
simply occupy disk space. simply occupy disk space.
</para> </para>
<para> <para>
The <filename>lo</> module allows fixing this by attaching a trigger The <filename>lo</filename> module allows fixing this by attaching a trigger
to tables that contain LO reference columns. The trigger essentially just to tables that contain LO reference columns. The trigger essentially just
does a <function>lo_unlink</> whenever you delete or modify a value does a <function>lo_unlink</function> whenever you delete or modify a value
referencing a large object. When you use this trigger, you are assuming referencing a large object. When you use this trigger, you are assuming
that there is only one database reference to any large object that is that there is only one database reference to any large object that is
referenced in a trigger-controlled column! referenced in a trigger-controlled column!
</para> </para>
<para> <para>
The module also provides a data type <type>lo</>, which is really just The module also provides a data type <type>lo</type>, which is really just
a domain of the <type>oid</> type. This is useful for differentiating a domain of the <type>oid</type> type. This is useful for differentiating
database columns that hold large object references from those that are database columns that hold large object references from those that are
OIDs of other things. You don't have to use the <type>lo</> type to OIDs of other things. You don't have to use the <type>lo</type> type to
use the trigger, but it may be convenient to use it to keep track of which use the trigger, but it may be convenient to use it to keep track of which
columns in your database represent large objects that you are managing with columns in your database represent large objects that you are managing with
the trigger. It is also rumored that the ODBC driver gets confused if you the trigger. It is also rumored that the ODBC driver gets confused if you
don't use <type>lo</> for BLOB columns. don't use <type>lo</type> for BLOB columns.
</para> </para>
</sect2> </sect2>
@ -75,11 +75,11 @@ CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image
<para> <para>
For each column that will contain unique references to large objects, For each column that will contain unique references to large objects,
create a <literal>BEFORE UPDATE OR DELETE</> trigger, and give the column create a <literal>BEFORE UPDATE OR DELETE</literal> trigger, and give the column
name as the sole trigger argument. You can also restrict the trigger name as the sole trigger argument. You can also restrict the trigger
to only execute on updates to the column by using <literal>BEFORE UPDATE to only execute on updates to the column by using <literal>BEFORE UPDATE
OF</literal> <replaceable class="parameter">column_name</replaceable>. OF</literal> <replaceable class="parameter">column_name</replaceable>.
If you need multiple <type>lo</> If you need multiple <type>lo</type>
columns in the same table, create a separate trigger for each one, columns in the same table, create a separate trigger for each one,
remembering to give a different name to each trigger on the same table. remembering to give a different name to each trigger on the same table.
</para> </para>
@ -93,18 +93,18 @@ CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image
<para> <para>
Dropping a table will still orphan any objects it contains, as the trigger Dropping a table will still orphan any objects it contains, as the trigger
is not executed. You can avoid this by preceding the <command>DROP is not executed. You can avoid this by preceding the <command>DROP
TABLE</> with <command>DELETE FROM <replaceable>table</></command>. TABLE</command> with <command>DELETE FROM <replaceable>table</replaceable></command>.
</para> </para>
<para> <para>
<command>TRUNCATE</> has the same hazard. <command>TRUNCATE</command> has the same hazard.
</para> </para>
<para> <para>
If you already have, or suspect you have, orphaned large objects, see the If you already have, or suspect you have, orphaned large objects, see the
<xref linkend="vacuumlo"> module to help <xref linkend="vacuumlo"> module to help
you clean them up. It's a good idea to run <application>vacuumlo</> you clean them up. It's a good idea to run <application>vacuumlo</application>
occasionally as a back-stop to the <function>lo_manage</> trigger. occasionally as a back-stop to the <function>lo_manage</function> trigger.
</para> </para>
</listitem> </listitem>

View File

@ -3,11 +3,11 @@
<chapter id="largeObjects"> <chapter id="largeObjects">
<title>Large Objects</title> <title>Large Objects</title>
<indexterm zone="largeobjects"><primary>large object</></> <indexterm zone="largeobjects"><primary>large object</primary></indexterm>
<indexterm><primary>BLOB</><see>large object</></> <indexterm><primary>BLOB</primary><see>large object</see></indexterm>
<para> <para>
<productname>PostgreSQL</productname> has a <firstterm>large object</> <productname>PostgreSQL</productname> has a <firstterm>large object</firstterm>
facility, which provides stream-style access to user data that is stored facility, which provides stream-style access to user data that is stored
in a special large-object structure. Streaming access is useful in a special large-object structure. Streaming access is useful
when working with data values that are too large to manipulate when working with data values that are too large to manipulate
@ -76,12 +76,12 @@
of 1000000 bytes worth of storage; only of chunks covering the range of of 1000000 bytes worth of storage; only of chunks covering the range of
data bytes actually written. A read operation will, however, read out data bytes actually written. A read operation will, however, read out
zeroes for any unallocated locations preceding the last existing chunk. zeroes for any unallocated locations preceding the last existing chunk.
This corresponds to the common behavior of <quote>sparsely allocated</> This corresponds to the common behavior of <quote>sparsely allocated</quote>
files in <acronym>Unix</acronym> file systems. files in <acronym>Unix</acronym> file systems.
</para> </para>
<para> <para>
As of <productname>PostgreSQL</> 9.0, large objects have an owner As of <productname>PostgreSQL</productname> 9.0, large objects have an owner
and a set of access permissions, which can be managed using and a set of access permissions, which can be managed using
<xref linkend="sql-grant"> and <xref linkend="sql-grant"> and
<xref linkend="sql-revoke">. <xref linkend="sql-revoke">.
@ -101,7 +101,7 @@
<para> <para>
This section describes the facilities that This section describes the facilities that
<productname>PostgreSQL</productname>'s <application>libpq</> <productname>PostgreSQL</productname>'s <application>libpq</application>
client interface library provides for accessing large objects. client interface library provides for accessing large objects.
The <productname>PostgreSQL</productname> large object interface is The <productname>PostgreSQL</productname> large object interface is
modeled after the <acronym>Unix</acronym> file-system interface, with modeled after the <acronym>Unix</acronym> file-system interface, with
@ -121,7 +121,7 @@
If an error occurs while executing any one of these functions, the If an error occurs while executing any one of these functions, the
function will return an otherwise-impossible value, typically 0 or -1. function will return an otherwise-impossible value, typically 0 or -1.
A message describing the error is stored in the connection object and A message describing the error is stored in the connection object and
can be retrieved with <function>PQerrorMessage</>. can be retrieved with <function>PQerrorMessage</function>.
</para> </para>
<para> <para>
@ -134,7 +134,7 @@
<title>Creating a Large Object</title> <title>Creating a Large Object</title>
<para> <para>
<indexterm><primary>lo_creat</></> <indexterm><primary>lo_creat</primary></indexterm>
The function The function
<synopsis> <synopsis>
Oid lo_creat(PGconn *conn, int mode); Oid lo_creat(PGconn *conn, int mode);
@ -147,7 +147,7 @@ Oid lo_creat(PGconn *conn, int mode);
ignored as of <productname>PostgreSQL</productname> 8.1; however, for ignored as of <productname>PostgreSQL</productname> 8.1; however, for
backward compatibility with earlier releases it is best to backward compatibility with earlier releases it is best to
set it to <symbol>INV_READ</symbol>, <symbol>INV_WRITE</symbol>, set it to <symbol>INV_READ</symbol>, <symbol>INV_WRITE</symbol>,
or <symbol>INV_READ</symbol> <literal>|</> <symbol>INV_WRITE</symbol>. or <symbol>INV_READ</symbol> <literal>|</literal> <symbol>INV_WRITE</symbol>.
(These symbolic constants are defined (These symbolic constants are defined
in the header file <filename>libpq/libpq-fs.h</filename>.) in the header file <filename>libpq/libpq-fs.h</filename>.)
</para> </para>
@ -160,7 +160,7 @@ inv_oid = lo_creat(conn, INV_READ|INV_WRITE);
</para> </para>
<para> <para>
<indexterm><primary>lo_create</></> <indexterm><primary>lo_create</primary></indexterm>
The function The function
<synopsis> <synopsis>
Oid lo_create(PGconn *conn, Oid lobjId); Oid lo_create(PGconn *conn, Oid lobjId);
@ -169,14 +169,14 @@ Oid lo_create(PGconn *conn, Oid lobjId);
specified by <replaceable class="parameter">lobjId</replaceable>; specified by <replaceable class="parameter">lobjId</replaceable>;
if so, failure occurs if that OID is already in use for some large if so, failure occurs if that OID is already in use for some large
object. If <replaceable class="parameter">lobjId</replaceable> object. If <replaceable class="parameter">lobjId</replaceable>
is <symbol>InvalidOid</symbol> (zero) then <function>lo_create</> assigns an unused is <symbol>InvalidOid</symbol> (zero) then <function>lo_create</function> assigns an unused
OID (this is the same behavior as <function>lo_creat</>). OID (this is the same behavior as <function>lo_creat</function>).
The return value is the OID that was assigned to the new large object, The return value is the OID that was assigned to the new large object,
or <symbol>InvalidOid</symbol> (zero) on failure. or <symbol>InvalidOid</symbol> (zero) on failure.
</para> </para>
<para> <para>
<function>lo_create</> is new as of <productname>PostgreSQL</productname> <function>lo_create</function> is new as of <productname>PostgreSQL</productname>
8.1; if this function is run against an older server version, it will 8.1; if this function is run against an older server version, it will
fail and return <symbol>InvalidOid</symbol>. fail and return <symbol>InvalidOid</symbol>.
</para> </para>
@ -193,7 +193,7 @@ inv_oid = lo_create(conn, desired_oid);
<title>Importing a Large Object</title> <title>Importing a Large Object</title>
<para> <para>
<indexterm><primary>lo_import</></> <indexterm><primary>lo_import</primary></indexterm>
To import an operating system file as a large object, call To import an operating system file as a large object, call
<synopsis> <synopsis>
Oid lo_import(PGconn *conn, const char *filename); Oid lo_import(PGconn *conn, const char *filename);
@ -209,7 +209,7 @@ Oid lo_import(PGconn *conn, const char *filename);
</para> </para>
<para> <para>
<indexterm><primary>lo_import_with_oid</></> <indexterm><primary>lo_import_with_oid</primary></indexterm>
The function The function
<synopsis> <synopsis>
Oid lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId); Oid lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId);
@ -218,14 +218,14 @@ Oid lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId);
specified by <replaceable class="parameter">lobjId</replaceable>; specified by <replaceable class="parameter">lobjId</replaceable>;
if so, failure occurs if that OID is already in use for some large if so, failure occurs if that OID is already in use for some large
object. If <replaceable class="parameter">lobjId</replaceable> object. If <replaceable class="parameter">lobjId</replaceable>
is <symbol>InvalidOid</symbol> (zero) then <function>lo_import_with_oid</> assigns an unused is <symbol>InvalidOid</symbol> (zero) then <function>lo_import_with_oid</function> assigns an unused
OID (this is the same behavior as <function>lo_import</>). OID (this is the same behavior as <function>lo_import</function>).
The return value is the OID that was assigned to the new large object, The return value is the OID that was assigned to the new large object,
or <symbol>InvalidOid</symbol> (zero) on failure. or <symbol>InvalidOid</symbol> (zero) on failure.
</para> </para>
<para> <para>
<function>lo_import_with_oid</> is new as of <productname>PostgreSQL</productname> <function>lo_import_with_oid</function> is new as of <productname>PostgreSQL</productname>
8.4 and uses <function>lo_create</function> internally which is new in 8.1; if this function is run against 8.0 or before, it will 8.4 and uses <function>lo_create</function> internally which is new in 8.1; if this function is run against 8.0 or before, it will
fail and return <symbol>InvalidOid</symbol>. fail and return <symbol>InvalidOid</symbol>.
</para> </para>
@ -235,7 +235,7 @@ Oid lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId);
<title>Exporting a Large Object</title> <title>Exporting a Large Object</title>
<para> <para>
<indexterm><primary>lo_export</></> <indexterm><primary>lo_export</primary></indexterm>
To export a large object To export a large object
into an operating system file, call into an operating system file, call
<synopsis> <synopsis>
@ -253,14 +253,14 @@ int lo_export(PGconn *conn, Oid lobjId, const char *filename);
<title>Opening an Existing Large Object</title> <title>Opening an Existing Large Object</title>
<para> <para>
<indexterm><primary>lo_open</></> <indexterm><primary>lo_open</primary></indexterm>
To open an existing large object for reading or writing, call To open an existing large object for reading or writing, call
<synopsis> <synopsis>
int lo_open(PGconn *conn, Oid lobjId, int mode); int lo_open(PGconn *conn, Oid lobjId, int mode);
</synopsis> </synopsis>
The <parameter>lobjId</parameter> argument specifies the OID of the large The <parameter>lobjId</parameter> argument specifies the OID of the large
object to open. The <parameter>mode</parameter> bits control whether the object to open. The <parameter>mode</parameter> bits control whether the
object is opened for reading (<symbol>INV_READ</>), writing object is opened for reading (<symbol>INV_READ</symbol>), writing
(<symbol>INV_WRITE</symbol>), or both. (<symbol>INV_WRITE</symbol>), or both.
(These symbolic constants are defined (These symbolic constants are defined
in the header file <filename>libpq/libpq-fs.h</filename>.) in the header file <filename>libpq/libpq-fs.h</filename>.)
@ -277,19 +277,19 @@ int lo_open(PGconn *conn, Oid lobjId, int mode);
<para> <para>
The server currently does not distinguish between modes The server currently does not distinguish between modes
<symbol>INV_WRITE</symbol> and <symbol>INV_READ</> <literal>|</> <symbol>INV_WRITE</symbol> and <symbol>INV_READ</symbol> <literal>|</literal>
<symbol>INV_WRITE</symbol>: you are allowed to read from the descriptor <symbol>INV_WRITE</symbol>: you are allowed to read from the descriptor
in either case. However there is a significant difference between in either case. However there is a significant difference between
these modes and <symbol>INV_READ</> alone: with <symbol>INV_READ</> these modes and <symbol>INV_READ</symbol> alone: with <symbol>INV_READ</symbol>
you cannot write on the descriptor, and the data read from it will you cannot write on the descriptor, and the data read from it will
reflect the contents of the large object at the time of the transaction reflect the contents of the large object at the time of the transaction
snapshot that was active when <function>lo_open</> was executed, snapshot that was active when <function>lo_open</function> was executed,
regardless of later writes by this or other transactions. Reading regardless of later writes by this or other transactions. Reading
from a descriptor opened with <symbol>INV_WRITE</symbol> returns from a descriptor opened with <symbol>INV_WRITE</symbol> returns
data that reflects all writes of other committed transactions as well data that reflects all writes of other committed transactions as well
as writes of the current transaction. This is similar to the behavior as writes of the current transaction. This is similar to the behavior
of <literal>REPEATABLE READ</> versus <literal>READ COMMITTED</> transaction of <literal>REPEATABLE READ</literal> versus <literal>READ COMMITTED</literal> transaction
modes for ordinary SQL <command>SELECT</> commands. modes for ordinary SQL <command>SELECT</command> commands.
</para> </para>
<para> <para>
@ -304,14 +304,14 @@ inv_fd = lo_open(conn, inv_oid, INV_READ|INV_WRITE);
<title>Writing Data to a Large Object</title> <title>Writing Data to a Large Object</title>
<para> <para>
<indexterm><primary>lo_write</></> <indexterm><primary>lo_write</primary></indexterm>
The function The function
<synopsis> <synopsis>
int lo_write(PGconn *conn, int fd, const char *buf, size_t len); int lo_write(PGconn *conn, int fd, const char *buf, size_t len);
</synopsis> </synopsis>
writes <parameter>len</parameter> bytes from <parameter>buf</parameter> writes <parameter>len</parameter> bytes from <parameter>buf</parameter>
(which must be of size <parameter>len</parameter>) to large object (which must be of size <parameter>len</parameter>) to large object
descriptor <parameter>fd</>. The <parameter>fd</parameter> argument must descriptor <parameter>fd</parameter>. The <parameter>fd</parameter> argument must
have been returned by a previous <function>lo_open</function>. The have been returned by a previous <function>lo_open</function>. The
number of bytes actually written is returned (in the current number of bytes actually written is returned (in the current
implementation, this will always equal <parameter>len</parameter> unless implementation, this will always equal <parameter>len</parameter> unless
@ -320,8 +320,8 @@ int lo_write(PGconn *conn, int fd, const char *buf, size_t len);
<para> <para>
Although the <parameter>len</parameter> parameter is declared as Although the <parameter>len</parameter> parameter is declared as
<type>size_t</>, this function will reject length values larger than <type>size_t</type>, this function will reject length values larger than
<literal>INT_MAX</>. In practice, it's best to transfer data in chunks <literal>INT_MAX</literal>. In practice, it's best to transfer data in chunks
of at most a few megabytes anyway. of at most a few megabytes anyway.
</para> </para>
</sect2> </sect2>
@ -330,7 +330,7 @@ int lo_write(PGconn *conn, int fd, const char *buf, size_t len);
<title>Reading Data from a Large Object</title> <title>Reading Data from a Large Object</title>
<para> <para>
<indexterm><primary>lo_read</></> <indexterm><primary>lo_read</primary></indexterm>
The function The function
<synopsis> <synopsis>
int lo_read(PGconn *conn, int fd, char *buf, size_t len); int lo_read(PGconn *conn, int fd, char *buf, size_t len);
@ -347,8 +347,8 @@ int lo_read(PGconn *conn, int fd, char *buf, size_t len);
<para> <para>
Although the <parameter>len</parameter> parameter is declared as Although the <parameter>len</parameter> parameter is declared as
<type>size_t</>, this function will reject length values larger than <type>size_t</type>, this function will reject length values larger than
<literal>INT_MAX</>. In practice, it's best to transfer data in chunks <literal>INT_MAX</literal>. In practice, it's best to transfer data in chunks
of at most a few megabytes anyway. of at most a few megabytes anyway.
</para> </para>
</sect2> </sect2>
@ -357,7 +357,7 @@ int lo_read(PGconn *conn, int fd, char *buf, size_t len);
<title>Seeking in a Large Object</title> <title>Seeking in a Large Object</title>
<para> <para>
<indexterm><primary>lo_lseek</></> <indexterm><primary>lo_lseek</primary></indexterm>
To change the current read or write location associated with a To change the current read or write location associated with a
large object descriptor, call large object descriptor, call
<synopsis> <synopsis>
@ -365,16 +365,16 @@ int lo_lseek(PGconn *conn, int fd, int offset, int whence);
</synopsis> </synopsis>
This function moves the This function moves the
current location pointer for the large object descriptor identified by current location pointer for the large object descriptor identified by
<parameter>fd</> to the new location specified by <parameter>fd</parameter> to the new location specified by
<parameter>offset</>. The valid values for <parameter>whence</> <parameter>offset</parameter>. The valid values for <parameter>whence</parameter>
are <symbol>SEEK_SET</> (seek from object start), are <symbol>SEEK_SET</symbol> (seek from object start),
<symbol>SEEK_CUR</> (seek from current position), and <symbol>SEEK_CUR</symbol> (seek from current position), and
<symbol>SEEK_END</> (seek from object end). The return value is <symbol>SEEK_END</symbol> (seek from object end). The return value is
the new location pointer, or -1 on error. the new location pointer, or -1 on error.
</para> </para>
<para> <para>
<indexterm><primary>lo_lseek64</></> <indexterm><primary>lo_lseek64</primary></indexterm>
When dealing with large objects that might exceed 2GB in size, When dealing with large objects that might exceed 2GB in size,
instead use instead use
<synopsis> <synopsis>
@ -382,14 +382,14 @@ pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence);
</synopsis> </synopsis>
This function has the same behavior This function has the same behavior
as <function>lo_lseek</function>, but it can accept an as <function>lo_lseek</function>, but it can accept an
<parameter>offset</> larger than 2GB and/or deliver a result larger <parameter>offset</parameter> larger than 2GB and/or deliver a result larger
than 2GB. than 2GB.
Note that <function>lo_lseek</function> will fail if the new location Note that <function>lo_lseek</function> will fail if the new location
pointer would be greater than 2GB. pointer would be greater than 2GB.
</para> </para>
<para> <para>
<function>lo_lseek64</> is new as of <productname>PostgreSQL</productname> <function>lo_lseek64</function> is new as of <productname>PostgreSQL</productname>
9.3. If this function is run against an older server version, it will 9.3. If this function is run against an older server version, it will
fail and return -1. fail and return -1.
</para> </para>
@ -400,7 +400,7 @@ pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence);
<title>Obtaining the Seek Position of a Large Object</title> <title>Obtaining the Seek Position of a Large Object</title>
<para> <para>
<indexterm><primary>lo_tell</></> <indexterm><primary>lo_tell</primary></indexterm>
To obtain the current read or write location of a large object descriptor, To obtain the current read or write location of a large object descriptor,
call call
<synopsis> <synopsis>
@ -410,7 +410,7 @@ int lo_tell(PGconn *conn, int fd);
</para> </para>
<para> <para>
<indexterm><primary>lo_tell64</></> <indexterm><primary>lo_tell64</primary></indexterm>
When dealing with large objects that might exceed 2GB in size, When dealing with large objects that might exceed 2GB in size,
instead use instead use
<synopsis> <synopsis>
@ -424,7 +424,7 @@ pg_int64 lo_tell64(PGconn *conn, int fd);
</para> </para>
<para> <para>
<function>lo_tell64</> is new as of <productname>PostgreSQL</productname> <function>lo_tell64</function> is new as of <productname>PostgreSQL</productname>
9.3. If this function is run against an older server version, it will 9.3. If this function is run against an older server version, it will
fail and return -1. fail and return -1.
</para> </para>
@ -434,15 +434,15 @@ pg_int64 lo_tell64(PGconn *conn, int fd);
<title>Truncating a Large Object</title> <title>Truncating a Large Object</title>
<para> <para>
<indexterm><primary>lo_truncate</></> <indexterm><primary>lo_truncate</primary></indexterm>
To truncate a large object to a given length, call To truncate a large object to a given length, call
<synopsis> <synopsis>
int lo_truncate(PGcon *conn, int fd, size_t len); int lo_truncate(PGcon *conn, int fd, size_t len);
</synopsis> </synopsis>
This function truncates the large object This function truncates the large object
descriptor <parameter>fd</> to length <parameter>len</>. The descriptor <parameter>fd</parameter> to length <parameter>len</parameter>. The
<parameter>fd</parameter> argument must have been returned by a <parameter>fd</parameter> argument must have been returned by a
previous <function>lo_open</function>. If <parameter>len</> is previous <function>lo_open</function>. If <parameter>len</parameter> is
greater than the large object's current length, the large object greater than the large object's current length, the large object
is extended to the specified length with null bytes ('\0'). is extended to the specified length with null bytes ('\0').
On success, <function>lo_truncate</function> returns On success, <function>lo_truncate</function> returns
@ -456,12 +456,12 @@ int lo_truncate(PGcon *conn, int fd, size_t len);
<para> <para>
Although the <parameter>len</parameter> parameter is declared as Although the <parameter>len</parameter> parameter is declared as
<type>size_t</>, <function>lo_truncate</function> will reject length <type>size_t</type>, <function>lo_truncate</function> will reject length
values larger than <literal>INT_MAX</>. values larger than <literal>INT_MAX</literal>.
</para> </para>
<para> <para>
<indexterm><primary>lo_truncate64</></> <indexterm><primary>lo_truncate64</primary></indexterm>
When dealing with large objects that might exceed 2GB in size, When dealing with large objects that might exceed 2GB in size,
instead use instead use
<synopsis> <synopsis>
@ -469,17 +469,17 @@ int lo_truncate64(PGcon *conn, int fd, pg_int64 len);
</synopsis> </synopsis>
This function has the same This function has the same
behavior as <function>lo_truncate</function>, but it can accept a behavior as <function>lo_truncate</function>, but it can accept a
<parameter>len</> value exceeding 2GB. <parameter>len</parameter> value exceeding 2GB.
</para> </para>
<para> <para>
<function>lo_truncate</> is new as of <productname>PostgreSQL</productname> <function>lo_truncate</function> is new as of <productname>PostgreSQL</productname>
8.3; if this function is run against an older server version, it will 8.3; if this function is run against an older server version, it will
fail and return -1. fail and return -1.
</para> </para>
<para> <para>
<function>lo_truncate64</> is new as of <productname>PostgreSQL</productname> <function>lo_truncate64</function> is new as of <productname>PostgreSQL</productname>
9.3; if this function is run against an older server version, it will 9.3; if this function is run against an older server version, it will
fail and return -1. fail and return -1.
</para> </para>
@ -489,12 +489,12 @@ int lo_truncate64(PGcon *conn, int fd, pg_int64 len);
<title>Closing a Large Object Descriptor</title> <title>Closing a Large Object Descriptor</title>
<para> <para>
<indexterm><primary>lo_close</></> <indexterm><primary>lo_close</primary></indexterm>
A large object descriptor can be closed by calling A large object descriptor can be closed by calling
<synopsis> <synopsis>
int lo_close(PGconn *conn, int fd); int lo_close(PGconn *conn, int fd);
</synopsis> </synopsis>
where <parameter>fd</> is a where <parameter>fd</parameter> is a
large object descriptor returned by <function>lo_open</function>. large object descriptor returned by <function>lo_open</function>.
On success, <function>lo_close</function> returns zero. On On success, <function>lo_close</function> returns zero. On
error, the return value is -1. error, the return value is -1.
@ -510,7 +510,7 @@ int lo_close(PGconn *conn, int fd);
<title>Removing a Large Object</title> <title>Removing a Large Object</title>
<para> <para>
<indexterm><primary>lo_unlink</></> <indexterm><primary>lo_unlink</primary></indexterm>
To remove a large object from the database, call To remove a large object from the database, call
<synopsis> <synopsis>
int lo_unlink(PGconn *conn, Oid lobjId); int lo_unlink(PGconn *conn, Oid lobjId);
@ -554,7 +554,7 @@ int lo_unlink(PGconn *conn, Oid lobjId);
<entry><type>oid</type></entry> <entry><type>oid</type></entry>
<entry> <entry>
Create a large object and store data there, returning its OID. Create a large object and store data there, returning its OID.
Pass <literal>0</> to have the system choose an OID. Pass <literal>0</literal> to have the system choose an OID.
</entry> </entry>
<entry><literal>lo_from_bytea(0, E'\\xffffff00')</literal></entry> <entry><literal>lo_from_bytea(0, E'\\xffffff00')</literal></entry>
<entry><literal>24528</literal></entry> <entry><literal>24528</literal></entry>
@ -599,11 +599,11 @@ int lo_unlink(PGconn *conn, Oid lobjId);
client-side functions described earlier; indeed, for the most part the client-side functions described earlier; indeed, for the most part the
client-side functions are simply interfaces to the equivalent server-side client-side functions are simply interfaces to the equivalent server-side
functions. The ones just as convenient to call via SQL commands are functions. The ones just as convenient to call via SQL commands are
<function>lo_creat</function><indexterm><primary>lo_creat</></>, <function>lo_creat</function><indexterm><primary>lo_creat</primary></indexterm>,
<function>lo_create</function>, <function>lo_create</function>,
<function>lo_unlink</function><indexterm><primary>lo_unlink</></>, <function>lo_unlink</function><indexterm><primary>lo_unlink</primary></indexterm>,
<function>lo_import</function><indexterm><primary>lo_import</></>, and <function>lo_import</function><indexterm><primary>lo_import</primary></indexterm>, and
<function>lo_export</function><indexterm><primary>lo_export</></>. <function>lo_export</function><indexterm><primary>lo_export</primary></indexterm>.
Here are examples of their use: Here are examples of their use:
<programlisting> <programlisting>
@ -645,7 +645,7 @@ SELECT lo_export(image.raster, '/tmp/motd') FROM image
<function>lo_write</function> is also available via server-side calls, <function>lo_write</function> is also available via server-side calls,
but the names of the server-side functions differ from the client side but the names of the server-side functions differ from the client side
interfaces in that they do not contain underscores. You must call interfaces in that they do not contain underscores. You must call
these functions as <function>loread</> and <function>lowrite</>. these functions as <function>loread</function> and <function>lowrite</function>.
</para> </para>
</sect1> </sect1>
@ -656,7 +656,7 @@ SELECT lo_export(image.raster, '/tmp/motd') FROM image
<para> <para>
<xref linkend="lo-example"> is a sample program which shows how the large object <xref linkend="lo-example"> is a sample program which shows how the large object
interface interface
in <application>libpq</> can be used. Parts of the program are in <application>libpq</application> can be used. Parts of the program are
commented out but are left in the source for the reader's commented out but are left in the source for the reader's
benefit. This program can also be found in benefit. This program can also be found in
<filename>src/test/examples/testlo.c</filename> in the source distribution. <filename>src/test/examples/testlo.c</filename> in the source distribution.

View File

@ -156,13 +156,13 @@ postgres=# SELECT pg_drop_replication_slot('regression_slot');
<programlisting> <programlisting>
$ pg_recvlogical -d postgres --slot test --create-slot $ pg_recvlogical -d postgres --slot test --create-slot
$ pg_recvlogical -d postgres --slot test --start -f - $ pg_recvlogical -d postgres --slot test --start -f -
<keycombo action="simul"><keycap>Control</><keycap>Z</></> <keycombo action="simul"><keycap>Control</keycap><keycap>Z</keycap></keycombo>
$ psql -d postgres -c "INSERT INTO data(data) VALUES('4');" $ psql -d postgres -c "INSERT INTO data(data) VALUES('4');"
$ fg $ fg
BEGIN 693 BEGIN 693
table public.data: INSERT: id[integer]:4 data[text]:'4' table public.data: INSERT: id[integer]:4 data[text]:'4'
COMMIT 693 COMMIT 693
<keycombo action="simul"><keycap>Control</><keycap>C</></> <keycombo action="simul"><keycap>Control</keycap><keycap>C</keycap></keycombo>
$ pg_recvlogical -d postgres --slot test --drop-slot $ pg_recvlogical -d postgres --slot test --drop-slot
</programlisting> </programlisting>
</sect1> </sect1>
@ -286,7 +286,7 @@ $ pg_recvlogical -d postgres --slot test --drop-slot
<para> <para>
Creation of a snapshot is not always possible. In particular, it will Creation of a snapshot is not always possible. In particular, it will
fail when connected to a hot standby. Applications that do not require fail when connected to a hot standby. Applications that do not require
snapshot export may suppress it with the <literal>NOEXPORT_SNAPSHOT</> snapshot export may suppress it with the <literal>NOEXPORT_SNAPSHOT</literal>
option. option.
</para> </para>
</sect2> </sect2>
@ -303,7 +303,7 @@ $ pg_recvlogical -d postgres --slot test --drop-slot
</listitem> </listitem>
<listitem> <listitem>
<para><literal>DROP_REPLICATION_SLOT <replaceable>slot_name</replaceable></literal> <optional> <literal>WAIT</> </></para> <para><literal>DROP_REPLICATION_SLOT <replaceable>slot_name</replaceable></literal> <optional> <literal>WAIT</literal> </optional></para>
</listitem> </listitem>
<listitem> <listitem>
@ -426,12 +426,12 @@ CREATE TABLE another_catalog_table(data text) WITH (user_catalog_table = true);
data in a data type that can contain arbitrary data (e.g., <type>bytea</type>) is data in a data type that can contain arbitrary data (e.g., <type>bytea</type>) is
cumbersome. If the output plugin only outputs textual data in the cumbersome. If the output plugin only outputs textual data in the
server's encoding, it can declare that by server's encoding, it can declare that by
setting <literal>OutputPluginOptions.output_type</> setting <literal>OutputPluginOptions.output_type</literal>
to <literal>OUTPUT_PLUGIN_TEXTUAL_OUTPUT</> instead to <literal>OUTPUT_PLUGIN_TEXTUAL_OUTPUT</literal> instead
of <literal>OUTPUT_PLUGIN_BINARY_OUTPUT</> in of <literal>OUTPUT_PLUGIN_BINARY_OUTPUT</literal> in
the <link linkend="logicaldecoding-output-plugin-startup">startup the <link linkend="logicaldecoding-output-plugin-startup">startup
callback</>. In that case, all the data has to be in the server's encoding callback</link>. In that case, all the data has to be in the server's encoding
so that a <type>text</> datum can contain it. This is checked in assertion-enabled so that a <type>text</type> datum can contain it. This is checked in assertion-enabled
builds. builds.
</para> </para>
</sect2> </sect2>

View File

@ -8,7 +8,7 @@
</indexterm> </indexterm>
<para> <para>
This module implements a data type <type>ltree</> for representing This module implements a data type <type>ltree</type> for representing
labels of data stored in a hierarchical tree-like structure. labels of data stored in a hierarchical tree-like structure.
Extensive facilities for searching through label trees are provided. Extensive facilities for searching through label trees are provided.
</para> </para>
@ -19,17 +19,17 @@
<para> <para>
A <firstterm>label</firstterm> is a sequence of alphanumeric characters A <firstterm>label</firstterm> is a sequence of alphanumeric characters
and underscores (for example, in C locale the characters and underscores (for example, in C locale the characters
<literal>A-Za-z0-9_</> are allowed). Labels must be less than 256 bytes <literal>A-Za-z0-9_</literal> are allowed). Labels must be less than 256 bytes
long. long.
</para> </para>
<para> <para>
Examples: <literal>42</>, <literal>Personal_Services</> Examples: <literal>42</literal>, <literal>Personal_Services</literal>
</para> </para>
<para> <para>
A <firstterm>label path</firstterm> is a sequence of zero or more A <firstterm>label path</firstterm> is a sequence of zero or more
labels separated by dots, for example <literal>L1.L2.L3</>, representing labels separated by dots, for example <literal>L1.L2.L3</literal>, representing
a path from the root of a hierarchical tree to a particular node. The a path from the root of a hierarchical tree to a particular node. The
length of a label path must be less than 65kB, but keeping it under 2kB is length of a label path must be less than 65kB, but keeping it under 2kB is
preferable. In practice this is not a major limitation; for example, preferable. In practice this is not a major limitation; for example,
@ -42,7 +42,7 @@
</para> </para>
<para> <para>
The <filename>ltree</> module provides several data types: The <filename>ltree</filename> module provides several data types:
</para> </para>
<itemizedlist> <itemizedlist>
@ -55,13 +55,13 @@
<listitem> <listitem>
<para> <para>
<type>lquery</type> represents a regular-expression-like pattern <type>lquery</type> represents a regular-expression-like pattern
for matching <type>ltree</> values. A simple word matches that for matching <type>ltree</type> values. A simple word matches that
label within a path. A star symbol (<literal>*</>) matches zero label within a path. A star symbol (<literal>*</literal>) matches zero
or more labels. For example: or more labels. For example:
<synopsis> <synopsis>
foo <lineannotation>Match the exact label path <literal>foo</></lineannotation> foo <lineannotation>Match the exact label path <literal>foo</literal></lineannotation>
*.foo.* <lineannotation>Match any label path containing the label <literal>foo</></lineannotation> *.foo.* <lineannotation>Match any label path containing the label <literal>foo</literal></lineannotation>
*.foo <lineannotation>Match any label path whose last label is <literal>foo</></lineannotation> *.foo <lineannotation>Match any label path whose last label is <literal>foo</literal></lineannotation>
</synopsis> </synopsis>
</para> </para>
@ -69,34 +69,34 @@ foo <lineannotation>Match the exact label path <literal>foo</></lineanno
Star symbols can also be quantified to restrict how many labels Star symbols can also be quantified to restrict how many labels
they can match: they can match:
<synopsis> <synopsis>
*{<replaceable>n</>} <lineannotation>Match exactly <replaceable>n</> labels</lineannotation> *{<replaceable>n</replaceable>} <lineannotation>Match exactly <replaceable>n</replaceable> labels</lineannotation>
*{<replaceable>n</>,} <lineannotation>Match at least <replaceable>n</> labels</lineannotation> *{<replaceable>n</replaceable>,} <lineannotation>Match at least <replaceable>n</replaceable> labels</lineannotation>
*{<replaceable>n</>,<replaceable>m</>} <lineannotation>Match at least <replaceable>n</> but not more than <replaceable>m</> labels</lineannotation> *{<replaceable>n</replaceable>,<replaceable>m</replaceable>} <lineannotation>Match at least <replaceable>n</replaceable> but not more than <replaceable>m</replaceable> labels</lineannotation>
*{,<replaceable>m</>} <lineannotation>Match at most <replaceable>m</> labels &mdash; same as </lineannotation> *{0,<replaceable>m</>} *{,<replaceable>m</replaceable>} <lineannotation>Match at most <replaceable>m</replaceable> labels &mdash; same as </lineannotation> *{0,<replaceable>m</replaceable>}
</synopsis> </synopsis>
</para> </para>
<para> <para>
There are several modifiers that can be put at the end of a non-star There are several modifiers that can be put at the end of a non-star
label in <type>lquery</> to make it match more than just the exact match: label in <type>lquery</type> to make it match more than just the exact match:
<synopsis> <synopsis>
@ <lineannotation>Match case-insensitively, for example <literal>a@</> matches <literal>A</></lineannotation> @ <lineannotation>Match case-insensitively, for example <literal>a@</literal> matches <literal>A</literal></lineannotation>
* <lineannotation>Match any label with this prefix, for example <literal>foo*</> matches <literal>foobar</></lineannotation> * <lineannotation>Match any label with this prefix, for example <literal>foo*</literal> matches <literal>foobar</literal></lineannotation>
% <lineannotation>Match initial underscore-separated words</lineannotation> % <lineannotation>Match initial underscore-separated words</lineannotation>
</synopsis> </synopsis>
The behavior of <literal>%</> is a bit complicated. It tries to match The behavior of <literal>%</literal> is a bit complicated. It tries to match
words rather than the entire label. For example words rather than the entire label. For example
<literal>foo_bar%</> matches <literal>foo_bar_baz</> but not <literal>foo_bar%</literal> matches <literal>foo_bar_baz</literal> but not
<literal>foo_barbaz</>. If combined with <literal>*</>, prefix <literal>foo_barbaz</literal>. If combined with <literal>*</literal>, prefix
matching applies to each word separately, for example matching applies to each word separately, for example
<literal>foo_bar%*</> matches <literal>foo1_bar2_baz</> but <literal>foo_bar%*</literal> matches <literal>foo1_bar2_baz</literal> but
not <literal>foo1_br2_baz</>. not <literal>foo1_br2_baz</literal>.
</para> </para>
<para> <para>
Also, you can write several possibly-modified labels separated with Also, you can write several possibly-modified labels separated with
<literal>|</> (OR) to match any of those labels, and you can put <literal>|</literal> (OR) to match any of those labels, and you can put
<literal>!</> (NOT) at the start to match any label that doesn't <literal>!</literal> (NOT) at the start to match any label that doesn't
match any of the alternatives. match any of the alternatives.
</para> </para>
@ -141,14 +141,14 @@ a. b. c. d. e.
<listitem> <listitem>
<para><type>ltxtquery</type> represents a full-text-search-like <para><type>ltxtquery</type> represents a full-text-search-like
pattern for matching <type>ltree</> values. An pattern for matching <type>ltree</type> values. An
<type>ltxtquery</type> value contains words, possibly with the <type>ltxtquery</type> value contains words, possibly with the
modifiers <literal>@</>, <literal>*</>, <literal>%</> at the end; modifiers <literal>@</literal>, <literal>*</literal>, <literal>%</literal> at the end;
the modifiers have the same meanings as in <type>lquery</>. the modifiers have the same meanings as in <type>lquery</type>.
Words can be combined with <literal>&amp;</> (AND), Words can be combined with <literal>&amp;</literal> (AND),
<literal>|</> (OR), <literal>!</> (NOT), and parentheses. <literal>|</literal> (OR), <literal>!</literal> (NOT), and parentheses.
The key difference from The key difference from
<type>lquery</> is that <type>ltxtquery</type> matches words without <type>lquery</type> is that <type>ltxtquery</type> matches words without
regard to their position in the label path. regard to their position in the label path.
</para> </para>
@ -161,7 +161,7 @@ Europe &amp; Russia*@ &amp; !Transportation
any label beginning with <literal>Russia</literal> (case-insensitive), any label beginning with <literal>Russia</literal> (case-insensitive),
but not paths containing the label <literal>Transportation</literal>. but not paths containing the label <literal>Transportation</literal>.
The location of these words within the path is not important. The location of these words within the path is not important.
Also, when <literal>%</> is used, the word can be matched to any Also, when <literal>%</literal> is used, the word can be matched to any
underscore-separated word within a label, regardless of position. underscore-separated word within a label, regardless of position.
</para> </para>
</listitem> </listitem>
@ -169,8 +169,8 @@ Europe &amp; Russia*@ &amp; !Transportation
</itemizedlist> </itemizedlist>
<para> <para>
Note: <type>ltxtquery</> allows whitespace between symbols, but Note: <type>ltxtquery</type> allows whitespace between symbols, but
<type>ltree</> and <type>lquery</> do not. <type>ltree</type> and <type>lquery</type> do not.
</para> </para>
</sect2> </sect2>
@ -178,16 +178,16 @@ Europe &amp; Russia*@ &amp; !Transportation
<title>Operators and Functions</title> <title>Operators and Functions</title>
<para> <para>
Type <type>ltree</> has the usual comparison operators Type <type>ltree</type> has the usual comparison operators
<literal>=</>, <literal>&lt;&gt;</literal>, <literal>=</literal>, <literal>&lt;&gt;</literal>,
<literal>&lt;</>, <literal>&gt;</>, <literal>&lt;=</>, <literal>&gt;=</>. <literal>&lt;</literal>, <literal>&gt;</literal>, <literal>&lt;=</literal>, <literal>&gt;=</literal>.
Comparison sorts in the order of a tree traversal, with the children Comparison sorts in the order of a tree traversal, with the children
of a node sorted by label text. In addition, the specialized of a node sorted by label text. In addition, the specialized
operators shown in <xref linkend="ltree-op-table"> are available. operators shown in <xref linkend="ltree-op-table"> are available.
</para> </para>
<table id="ltree-op-table"> <table id="ltree-op-table">
<title><type>ltree</> Operators</title> <title><type>ltree</type> Operators</title>
<tgroup cols="3"> <tgroup cols="3">
<thead> <thead>
@ -200,153 +200,153 @@ Europe &amp; Russia*@ &amp; !Transportation
<tbody> <tbody>
<row> <row>
<entry><type>ltree</> <literal>@&gt;</> <type>ltree</></entry> <entry><type>ltree</type> <literal>@&gt;</literal> <type>ltree</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>is left argument an ancestor of right (or equal)?</entry> <entry>is left argument an ancestor of right (or equal)?</entry>
</row> </row>
<row> <row>
<entry><type>ltree</> <literal>&lt;@</> <type>ltree</></entry> <entry><type>ltree</type> <literal>&lt;@</literal> <type>ltree</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>is left argument a descendant of right (or equal)?</entry> <entry>is left argument a descendant of right (or equal)?</entry>
</row> </row>
<row> <row>
<entry><type>ltree</> <literal>~</> <type>lquery</></entry> <entry><type>ltree</type> <literal>~</literal> <type>lquery</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>does <type>ltree</> match <type>lquery</>?</entry> <entry>does <type>ltree</type> match <type>lquery</type>?</entry>
</row> </row>
<row> <row>
<entry><type>lquery</> <literal>~</> <type>ltree</></entry> <entry><type>lquery</type> <literal>~</literal> <type>ltree</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>does <type>ltree</> match <type>lquery</>?</entry> <entry>does <type>ltree</type> match <type>lquery</type>?</entry>
</row> </row>
<row> <row>
<entry><type>ltree</> <literal>?</> <type>lquery[]</></entry> <entry><type>ltree</type> <literal>?</literal> <type>lquery[]</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>does <type>ltree</> match any <type>lquery</> in array?</entry> <entry>does <type>ltree</type> match any <type>lquery</type> in array?</entry>
</row> </row>
<row> <row>
<entry><type>lquery[]</> <literal>?</> <type>ltree</></entry> <entry><type>lquery[]</type> <literal>?</literal> <type>ltree</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>does <type>ltree</> match any <type>lquery</> in array?</entry> <entry>does <type>ltree</type> match any <type>lquery</type> in array?</entry>
</row> </row>
<row> <row>
<entry><type>ltree</> <literal>@</> <type>ltxtquery</></entry> <entry><type>ltree</type> <literal>@</literal> <type>ltxtquery</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>does <type>ltree</> match <type>ltxtquery</>?</entry> <entry>does <type>ltree</type> match <type>ltxtquery</type>?</entry>
</row> </row>
<row> <row>
<entry><type>ltxtquery</> <literal>@</> <type>ltree</></entry> <entry><type>ltxtquery</type> <literal>@</literal> <type>ltree</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>does <type>ltree</> match <type>ltxtquery</>?</entry> <entry>does <type>ltree</type> match <type>ltxtquery</type>?</entry>
</row> </row>
<row> <row>
<entry><type>ltree</> <literal>||</> <type>ltree</></entry> <entry><type>ltree</type> <literal>||</literal> <type>ltree</type></entry>
<entry><type>ltree</type></entry> <entry><type>ltree</type></entry>
<entry>concatenate <type>ltree</> paths</entry> <entry>concatenate <type>ltree</type> paths</entry>
</row> </row>
<row> <row>
<entry><type>ltree</> <literal>||</> <type>text</></entry> <entry><type>ltree</type> <literal>||</literal> <type>text</type></entry>
<entry><type>ltree</type></entry> <entry><type>ltree</type></entry>
<entry>convert text to <type>ltree</> and concatenate</entry> <entry>convert text to <type>ltree</type> and concatenate</entry>
</row> </row>
<row> <row>
<entry><type>text</> <literal>||</> <type>ltree</></entry> <entry><type>text</type> <literal>||</literal> <type>ltree</type></entry>
<entry><type>ltree</type></entry> <entry><type>ltree</type></entry>
<entry>convert text to <type>ltree</> and concatenate</entry> <entry>convert text to <type>ltree</type> and concatenate</entry>
</row> </row>
<row> <row>
<entry><type>ltree[]</> <literal>@&gt;</> <type>ltree</></entry> <entry><type>ltree[]</type> <literal>@&gt;</literal> <type>ltree</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>does array contain an ancestor of <type>ltree</>?</entry> <entry>does array contain an ancestor of <type>ltree</type>?</entry>
</row> </row>
<row> <row>
<entry><type>ltree</> <literal>&lt;@</> <type>ltree[]</></entry> <entry><type>ltree</type> <literal>&lt;@</literal> <type>ltree[]</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>does array contain an ancestor of <type>ltree</>?</entry> <entry>does array contain an ancestor of <type>ltree</type>?</entry>
</row> </row>
<row> <row>
<entry><type>ltree[]</> <literal>&lt;@</> <type>ltree</></entry> <entry><type>ltree[]</type> <literal>&lt;@</literal> <type>ltree</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>does array contain a descendant of <type>ltree</>?</entry> <entry>does array contain a descendant of <type>ltree</type>?</entry>
</row> </row>
<row> <row>
<entry><type>ltree</> <literal>@&gt;</> <type>ltree[]</></entry> <entry><type>ltree</type> <literal>@&gt;</literal> <type>ltree[]</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>does array contain a descendant of <type>ltree</>?</entry> <entry>does array contain a descendant of <type>ltree</type>?</entry>
</row> </row>
<row> <row>
<entry><type>ltree[]</> <literal>~</> <type>lquery</></entry> <entry><type>ltree[]</type> <literal>~</literal> <type>lquery</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>does array contain any path matching <type>lquery</>?</entry> <entry>does array contain any path matching <type>lquery</type>?</entry>
</row> </row>
<row> <row>
<entry><type>lquery</> <literal>~</> <type>ltree[]</></entry> <entry><type>lquery</type> <literal>~</literal> <type>ltree[]</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>does array contain any path matching <type>lquery</>?</entry> <entry>does array contain any path matching <type>lquery</type>?</entry>
</row> </row>
<row> <row>
<entry><type>ltree[]</> <literal>?</> <type>lquery[]</></entry> <entry><type>ltree[]</type> <literal>?</literal> <type>lquery[]</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>does <type>ltree</> array contain any path matching any <type>lquery</>?</entry> <entry>does <type>ltree</type> array contain any path matching any <type>lquery</type>?</entry>
</row> </row>
<row> <row>
<entry><type>lquery[]</> <literal>?</> <type>ltree[]</></entry> <entry><type>lquery[]</type> <literal>?</literal> <type>ltree[]</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>does <type>ltree</> array contain any path matching any <type>lquery</>?</entry> <entry>does <type>ltree</type> array contain any path matching any <type>lquery</type>?</entry>
</row> </row>
<row> <row>
<entry><type>ltree[]</> <literal>@</> <type>ltxtquery</></entry> <entry><type>ltree[]</type> <literal>@</literal> <type>ltxtquery</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>does array contain any path matching <type>ltxtquery</>?</entry> <entry>does array contain any path matching <type>ltxtquery</type>?</entry>
</row> </row>
<row> <row>
<entry><type>ltxtquery</> <literal>@</> <type>ltree[]</></entry> <entry><type>ltxtquery</type> <literal>@</literal> <type>ltree[]</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>does array contain any path matching <type>ltxtquery</>?</entry> <entry>does array contain any path matching <type>ltxtquery</type>?</entry>
</row> </row>
<row> <row>
<entry><type>ltree[]</> <literal>?@&gt;</> <type>ltree</></entry> <entry><type>ltree[]</type> <literal>?@&gt;</literal> <type>ltree</type></entry>
<entry><type>ltree</type></entry> <entry><type>ltree</type></entry>
<entry>first array entry that is an ancestor of <type>ltree</>; NULL if none</entry> <entry>first array entry that is an ancestor of <type>ltree</type>; NULL if none</entry>
</row> </row>
<row> <row>
<entry><type>ltree[]</> <literal>?&lt;@</> <type>ltree</></entry> <entry><type>ltree[]</type> <literal>?&lt;@</literal> <type>ltree</type></entry>
<entry><type>ltree</type></entry> <entry><type>ltree</type></entry>
<entry>first array entry that is a descendant of <type>ltree</>; NULL if none</entry> <entry>first array entry that is a descendant of <type>ltree</type>; NULL if none</entry>
</row> </row>
<row> <row>
<entry><type>ltree[]</> <literal>?~</> <type>lquery</></entry> <entry><type>ltree[]</type> <literal>?~</literal> <type>lquery</type></entry>
<entry><type>ltree</type></entry> <entry><type>ltree</type></entry>
<entry>first array entry that matches <type>lquery</>; NULL if none</entry> <entry>first array entry that matches <type>lquery</type>; NULL if none</entry>
</row> </row>
<row> <row>
<entry><type>ltree[]</> <literal>?@</> <type>ltxtquery</></entry> <entry><type>ltree[]</type> <literal>?@</literal> <type>ltxtquery</type></entry>
<entry><type>ltree</type></entry> <entry><type>ltree</type></entry>
<entry>first array entry that matches <type>ltxtquery</>; NULL if none</entry> <entry>first array entry that matches <type>ltxtquery</type>; NULL if none</entry>
</row> </row>
</tbody> </tbody>
@ -356,7 +356,7 @@ Europe &amp; Russia*@ &amp; !Transportation
<para> <para>
The operators <literal>&lt;@</literal>, <literal>@&gt;</literal>, The operators <literal>&lt;@</literal>, <literal>@&gt;</literal>,
<literal>@</literal> and <literal>~</literal> have analogues <literal>@</literal> and <literal>~</literal> have analogues
<literal>^&lt;@</>, <literal>^@&gt;</>, <literal>^@</>, <literal>^&lt;@</literal>, <literal>^@&gt;</literal>, <literal>^@</literal>,
<literal>^~</literal>, which are the same except they do not use <literal>^~</literal>, which are the same except they do not use
indexes. These are useful only for testing purposes. indexes. These are useful only for testing purposes.
</para> </para>
@ -366,7 +366,7 @@ Europe &amp; Russia*@ &amp; !Transportation
</para> </para>
<table id="ltree-func-table"> <table id="ltree-func-table">
<title><type>ltree</> Functions</title> <title><type>ltree</type> Functions</title>
<tgroup cols="5"> <tgroup cols="5">
<thead> <thead>
@ -383,8 +383,8 @@ Europe &amp; Russia*@ &amp; !Transportation
<row> <row>
<entry><function>subltree(ltree, int start, int end)</function><indexterm><primary>subltree</primary></indexterm></entry> <entry><function>subltree(ltree, int start, int end)</function><indexterm><primary>subltree</primary></indexterm></entry>
<entry><type>ltree</type></entry> <entry><type>ltree</type></entry>
<entry>subpath of <type>ltree</> from position <parameter>start</> to <entry>subpath of <type>ltree</type> from position <parameter>start</parameter> to
position <parameter>end</>-1 (counting from 0)</entry> position <parameter>end</parameter>-1 (counting from 0)</entry>
<entry><literal>subltree('Top.Child1.Child2',1,2)</literal></entry> <entry><literal>subltree('Top.Child1.Child2',1,2)</literal></entry>
<entry><literal>Child1</literal></entry> <entry><literal>Child1</literal></entry>
</row> </row>
@ -392,10 +392,10 @@ Europe &amp; Russia*@ &amp; !Transportation
<row> <row>
<entry><function>subpath(ltree, int offset, int len)</function><indexterm><primary>subpath</primary></indexterm></entry> <entry><function>subpath(ltree, int offset, int len)</function><indexterm><primary>subpath</primary></indexterm></entry>
<entry><type>ltree</type></entry> <entry><type>ltree</type></entry>
<entry>subpath of <type>ltree</> starting at position <entry>subpath of <type>ltree</type> starting at position
<parameter>offset</>, length <parameter>len</>. <parameter>offset</parameter>, length <parameter>len</parameter>.
If <parameter>offset</> is negative, subpath starts that far from the If <parameter>offset</parameter> is negative, subpath starts that far from the
end of the path. If <parameter>len</> is negative, leaves that many end of the path. If <parameter>len</parameter> is negative, leaves that many
labels off the end of the path.</entry> labels off the end of the path.</entry>
<entry><literal>subpath('Top.Child1.Child2',0,2)</literal></entry> <entry><literal>subpath('Top.Child1.Child2',0,2)</literal></entry>
<entry><literal>Top.Child1</literal></entry> <entry><literal>Top.Child1</literal></entry>
@ -404,9 +404,9 @@ Europe &amp; Russia*@ &amp; !Transportation
<row> <row>
<entry><function>subpath(ltree, int offset)</function></entry> <entry><function>subpath(ltree, int offset)</function></entry>
<entry><type>ltree</type></entry> <entry><type>ltree</type></entry>
<entry>subpath of <type>ltree</> starting at position <entry>subpath of <type>ltree</type> starting at position
<parameter>offset</>, extending to end of path. <parameter>offset</parameter>, extending to end of path.
If <parameter>offset</> is negative, subpath starts that far from the If <parameter>offset</parameter> is negative, subpath starts that far from the
end of the path.</entry> end of the path.</entry>
<entry><literal>subpath('Top.Child1.Child2',1)</literal></entry> <entry><literal>subpath('Top.Child1.Child2',1)</literal></entry>
<entry><literal>Child1.Child2</literal></entry> <entry><literal>Child1.Child2</literal></entry>
@ -423,8 +423,8 @@ Europe &amp; Russia*@ &amp; !Transportation
<row> <row>
<entry><function>index(ltree a, ltree b)</function><indexterm><primary>index</primary></indexterm></entry> <entry><function>index(ltree a, ltree b)</function><indexterm><primary>index</primary></indexterm></entry>
<entry><type>integer</type></entry> <entry><type>integer</type></entry>
<entry>position of first occurrence of <parameter>b</> in <entry>position of first occurrence of <parameter>b</parameter> in
<parameter>a</>; -1 if not found</entry> <parameter>a</parameter>; -1 if not found</entry>
<entry><literal>index('0.1.2.3.5.4.5.6.8.5.6.8','5.6')</literal></entry> <entry><literal>index('0.1.2.3.5.4.5.6.8.5.6.8','5.6')</literal></entry>
<entry><literal>6</literal></entry> <entry><literal>6</literal></entry>
</row> </row>
@ -432,9 +432,9 @@ Europe &amp; Russia*@ &amp; !Transportation
<row> <row>
<entry><function>index(ltree a, ltree b, int offset)</function></entry> <entry><function>index(ltree a, ltree b, int offset)</function></entry>
<entry><type>integer</type></entry> <entry><type>integer</type></entry>
<entry>position of first occurrence of <parameter>b</> in <entry>position of first occurrence of <parameter>b</parameter> in
<parameter>a</>, searching starting at <parameter>offset</>; <parameter>a</parameter>, searching starting at <parameter>offset</parameter>;
negative <parameter>offset</> means start <parameter>-offset</> negative <parameter>offset</parameter> means start <parameter>-offset</parameter>
labels from the end of the path</entry> labels from the end of the path</entry>
<entry><literal>index('0.1.2.3.5.4.5.6.8.5.6.8','5.6',-4)</literal></entry> <entry><literal>index('0.1.2.3.5.4.5.6.8.5.6.8','5.6',-4)</literal></entry>
<entry><literal>9</literal></entry> <entry><literal>9</literal></entry>
@ -443,7 +443,7 @@ Europe &amp; Russia*@ &amp; !Transportation
<row> <row>
<entry><function>text2ltree(text)</function><indexterm><primary>text2ltree</primary></indexterm></entry> <entry><function>text2ltree(text)</function><indexterm><primary>text2ltree</primary></indexterm></entry>
<entry><type>ltree</type></entry> <entry><type>ltree</type></entry>
<entry>cast <type>text</> to <type>ltree</></entry> <entry>cast <type>text</type> to <type>ltree</type></entry>
<entry><literal></literal></entry> <entry><literal></literal></entry>
<entry><literal></literal></entry> <entry><literal></literal></entry>
</row> </row>
@ -451,7 +451,7 @@ Europe &amp; Russia*@ &amp; !Transportation
<row> <row>
<entry><function>ltree2text(ltree)</function><indexterm><primary>ltree2text</primary></indexterm></entry> <entry><function>ltree2text(ltree)</function><indexterm><primary>ltree2text</primary></indexterm></entry>
<entry><type>text</type></entry> <entry><type>text</type></entry>
<entry>cast <type>ltree</> to <type>text</></entry> <entry>cast <type>ltree</type> to <type>text</type></entry>
<entry><literal></literal></entry> <entry><literal></literal></entry>
<entry><literal></literal></entry> <entry><literal></literal></entry>
</row> </row>
@ -481,25 +481,25 @@ Europe &amp; Russia*@ &amp; !Transportation
<sect2> <sect2>
<title>Indexes</title> <title>Indexes</title>
<para> <para>
<filename>ltree</> supports several types of indexes that can speed <filename>ltree</filename> supports several types of indexes that can speed
up the indicated operators: up the indicated operators:
</para> </para>
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
B-tree index over <type>ltree</>: B-tree index over <type>ltree</type>:
<literal>&lt;</>, <literal>&lt;=</>, <literal>=</>, <literal>&lt;</literal>, <literal>&lt;=</literal>, <literal>=</literal>,
<literal>&gt;=</>, <literal>&gt;</literal> <literal>&gt;=</literal>, <literal>&gt;</literal>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
GiST index over <type>ltree</>: GiST index over <type>ltree</type>:
<literal>&lt;</>, <literal>&lt;=</>, <literal>=</>, <literal>&lt;</literal>, <literal>&lt;=</literal>, <literal>=</literal>,
<literal>&gt;=</>, <literal>&gt;</>, <literal>&gt;=</literal>, <literal>&gt;</literal>,
<literal>@&gt;</>, <literal>&lt;@</>, <literal>@&gt;</literal>, <literal>&lt;@</literal>,
<literal>@</>, <literal>~</>, <literal>?</literal> <literal>@</literal>, <literal>~</literal>, <literal>?</literal>
</para> </para>
<para> <para>
Example of creating such an index: Example of creating such an index:
@ -510,9 +510,9 @@ CREATE INDEX path_gist_idx ON test USING GIST (path);
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
GiST index over <type>ltree[]</>: GiST index over <type>ltree[]</type>:
<literal>ltree[] &lt;@ ltree</>, <literal>ltree @&gt; ltree[]</>, <literal>ltree[] &lt;@ ltree</literal>, <literal>ltree @&gt; ltree[]</literal>,
<literal>@</>, <literal>~</>, <literal>?</literal> <literal>@</literal>, <literal>~</literal>, <literal>?</literal>
</para> </para>
<para> <para>
Example of creating such an index: Example of creating such an index:
@ -532,7 +532,7 @@ CREATE INDEX path_gist_idx ON test USING GIST (array_path);
<para> <para>
This example uses the following data (also available in file This example uses the following data (also available in file
<filename>contrib/ltree/ltreetest.sql</> in the source distribution): <filename>contrib/ltree/ltreetest.sql</filename> in the source distribution):
</para> </para>
<programlisting> <programlisting>
@ -555,7 +555,7 @@ CREATE INDEX path_idx ON test USING BTREE (path);
</programlisting> </programlisting>
<para> <para>
Now, we have a table <structname>test</> populated with data describing Now, we have a table <structname>test</structname> populated with data describing
the hierarchy shown below: the hierarchy shown below:
</para> </para>

View File

@ -12,12 +12,12 @@
</indexterm> </indexterm>
<para> <para>
<productname>PostgreSQL</>, like any database software, requires that certain tasks <productname>PostgreSQL</productname>, like any database software, requires that certain tasks
be performed regularly to achieve optimum performance. The tasks be performed regularly to achieve optimum performance. The tasks
discussed here are <emphasis>required</emphasis>, but they discussed here are <emphasis>required</emphasis>, but they
are repetitive in nature and can easily be automated using standard are repetitive in nature and can easily be automated using standard
tools such as <application>cron</application> scripts or tools such as <application>cron</application> scripts or
Windows' <application>Task Scheduler</>. It is the database Windows' <application>Task Scheduler</application>. It is the database
administrator's responsibility to set up appropriate scripts, and to administrator's responsibility to set up appropriate scripts, and to
check that they execute successfully. check that they execute successfully.
</para> </para>
@ -32,7 +32,7 @@
</para> </para>
<para> <para>
The other main category of maintenance task is periodic <quote>vacuuming</> The other main category of maintenance task is periodic <quote>vacuuming</quote>
of the database. This activity is discussed in of the database. This activity is discussed in
<xref linkend="routine-vacuuming">. Closely related to this is updating <xref linkend="routine-vacuuming">. Closely related to this is updating
the statistics that will be used by the query planner, as discussed in the statistics that will be used by the query planner, as discussed in
@ -46,9 +46,9 @@
<para> <para>
<ulink <ulink
url="http://bucardo.org/wiki/Check_postgres"><application>check_postgres</></ulink> url="http://bucardo.org/wiki/Check_postgres"><application>check_postgres</application></ulink>
is available for monitoring database health and reporting unusual is available for monitoring database health and reporting unusual
conditions. <application>check_postgres</> integrates with conditions. <application>check_postgres</application> integrates with
Nagios and MRTG, but can be run standalone too. Nagios and MRTG, but can be run standalone too.
</para> </para>
@ -68,15 +68,15 @@
<para> <para>
<productname>PostgreSQL</productname> databases require periodic <productname>PostgreSQL</productname> databases require periodic
maintenance known as <firstterm>vacuuming</>. For many installations, it maintenance known as <firstterm>vacuuming</firstterm>. For many installations, it
is sufficient to let vacuuming be performed by the <firstterm>autovacuum is sufficient to let vacuuming be performed by the <firstterm>autovacuum
daemon</>, which is described in <xref linkend="autovacuum">. You might daemon</firstterm>, which is described in <xref linkend="autovacuum">. You might
need to adjust the autovacuuming parameters described there to obtain best need to adjust the autovacuuming parameters described there to obtain best
results for your situation. Some database administrators will want to results for your situation. Some database administrators will want to
supplement or replace the daemon's activities with manually-managed supplement or replace the daemon's activities with manually-managed
<command>VACUUM</> commands, which typically are executed according to a <command>VACUUM</command> commands, which typically are executed according to a
schedule by <application>cron</application> or <application>Task schedule by <application>cron</application> or <application>Task
Scheduler</> scripts. To set up manually-managed vacuuming properly, Scheduler</application> scripts. To set up manually-managed vacuuming properly,
it is essential to understand the issues discussed in the next few it is essential to understand the issues discussed in the next few
subsections. Administrators who rely on autovacuuming may still wish subsections. Administrators who rely on autovacuuming may still wish
to skim this material to help them understand and adjust autovacuuming. to skim this material to help them understand and adjust autovacuuming.
@ -109,30 +109,30 @@
<listitem> <listitem>
<simpara>To protect against loss of very old data due to <simpara>To protect against loss of very old data due to
<firstterm>transaction ID wraparound</> or <firstterm>transaction ID wraparound</firstterm> or
<firstterm>multixact ID wraparound</>.</simpara> <firstterm>multixact ID wraparound</firstterm>.</simpara>
</listitem> </listitem>
</orderedlist> </orderedlist>
Each of these reasons dictates performing <command>VACUUM</> operations Each of these reasons dictates performing <command>VACUUM</command> operations
of varying frequency and scope, as explained in the following subsections. of varying frequency and scope, as explained in the following subsections.
</para> </para>
<para> <para>
There are two variants of <command>VACUUM</>: standard <command>VACUUM</> There are two variants of <command>VACUUM</command>: standard <command>VACUUM</command>
and <command>VACUUM FULL</>. <command>VACUUM FULL</> can reclaim more and <command>VACUUM FULL</command>. <command>VACUUM FULL</command> can reclaim more
disk space but runs much more slowly. Also, disk space but runs much more slowly. Also,
the standard form of <command>VACUUM</> can run in parallel with production the standard form of <command>VACUUM</command> can run in parallel with production
database operations. (Commands such as <command>SELECT</command>, database operations. (Commands such as <command>SELECT</command>,
<command>INSERT</command>, <command>UPDATE</command>, and <command>INSERT</command>, <command>UPDATE</command>, and
<command>DELETE</command> will continue to function normally, though you <command>DELETE</command> will continue to function normally, though you
will not be able to modify the definition of a table with commands such as will not be able to modify the definition of a table with commands such as
<command>ALTER TABLE</command> while it is being vacuumed.) <command>ALTER TABLE</command> while it is being vacuumed.)
<command>VACUUM FULL</> requires exclusive lock on the table it is <command>VACUUM FULL</command> requires exclusive lock on the table it is
working on, and therefore cannot be done in parallel with other use working on, and therefore cannot be done in parallel with other use
of the table. Generally, therefore, of the table. Generally, therefore,
administrators should strive to use standard <command>VACUUM</> and administrators should strive to use standard <command>VACUUM</command> and
avoid <command>VACUUM FULL</>. avoid <command>VACUUM FULL</command>.
</para> </para>
<para> <para>
@ -153,15 +153,15 @@
<para> <para>
In <productname>PostgreSQL</productname>, an In <productname>PostgreSQL</productname>, an
<command>UPDATE</> or <command>DELETE</> of a row does not <command>UPDATE</command> or <command>DELETE</command> of a row does not
immediately remove the old version of the row. immediately remove the old version of the row.
This approach is necessary to gain the benefits of multiversion This approach is necessary to gain the benefits of multiversion
concurrency control (<acronym>MVCC</>, see <xref linkend="mvcc">): the row version concurrency control (<acronym>MVCC</acronym>, see <xref linkend="mvcc">): the row version
must not be deleted while it is still potentially visible to other must not be deleted while it is still potentially visible to other
transactions. But eventually, an outdated or deleted row version is no transactions. But eventually, an outdated or deleted row version is no
longer of interest to any transaction. The space it occupies must then be longer of interest to any transaction. The space it occupies must then be
reclaimed for reuse by new rows, to avoid unbounded growth of disk reclaimed for reuse by new rows, to avoid unbounded growth of disk
space requirements. This is done by running <command>VACUUM</>. space requirements. This is done by running <command>VACUUM</command>.
</para> </para>
<para> <para>
@ -170,7 +170,7 @@
future reuse. However, it will not return the space to the operating future reuse. However, it will not return the space to the operating
system, except in the special case where one or more pages at the system, except in the special case where one or more pages at the
end of a table become entirely free and an exclusive table lock can be end of a table become entirely free and an exclusive table lock can be
easily obtained. In contrast, <command>VACUUM FULL</> actively compacts easily obtained. In contrast, <command>VACUUM FULL</command> actively compacts
tables by writing a complete new version of the table file with no dead tables by writing a complete new version of the table file with no dead
space. This minimizes the size of the table, but can take a long time. space. This minimizes the size of the table, but can take a long time.
It also requires extra disk space for the new copy of the table, until It also requires extra disk space for the new copy of the table, until
@ -178,18 +178,18 @@
</para> </para>
<para> <para>
The usual goal of routine vacuuming is to do standard <command>VACUUM</>s The usual goal of routine vacuuming is to do standard <command>VACUUM</command>s
often enough to avoid needing <command>VACUUM FULL</>. The often enough to avoid needing <command>VACUUM FULL</command>. The
autovacuum daemon attempts to work this way, and in fact will autovacuum daemon attempts to work this way, and in fact will
never issue <command>VACUUM FULL</>. In this approach, the idea never issue <command>VACUUM FULL</command>. In this approach, the idea
is not to keep tables at their minimum size, but to maintain steady-state is not to keep tables at their minimum size, but to maintain steady-state
usage of disk space: each table occupies space equivalent to its usage of disk space: each table occupies space equivalent to its
minimum size plus however much space gets used up between vacuumings. minimum size plus however much space gets used up between vacuumings.
Although <command>VACUUM FULL</> can be used to shrink a table back Although <command>VACUUM FULL</command> can be used to shrink a table back
to its minimum size and return the disk space to the operating system, to its minimum size and return the disk space to the operating system,
there is not much point in this if the table will just grow again in the there is not much point in this if the table will just grow again in the
future. Thus, moderately-frequent standard <command>VACUUM</> runs are a future. Thus, moderately-frequent standard <command>VACUUM</command> runs are a
better approach than infrequent <command>VACUUM FULL</> runs for better approach than infrequent <command>VACUUM FULL</command> runs for
maintaining heavily-updated tables. maintaining heavily-updated tables.
</para> </para>
@ -198,20 +198,20 @@
doing all the work at night when load is low. doing all the work at night when load is low.
The difficulty with doing vacuuming according to a fixed schedule The difficulty with doing vacuuming according to a fixed schedule
is that if a table has an unexpected spike in update activity, it may is that if a table has an unexpected spike in update activity, it may
get bloated to the point that <command>VACUUM FULL</> is really necessary get bloated to the point that <command>VACUUM FULL</command> is really necessary
to reclaim space. Using the autovacuum daemon alleviates this problem, to reclaim space. Using the autovacuum daemon alleviates this problem,
since the daemon schedules vacuuming dynamically in response to update since the daemon schedules vacuuming dynamically in response to update
activity. It is unwise to disable the daemon completely unless you activity. It is unwise to disable the daemon completely unless you
have an extremely predictable workload. One possible compromise is have an extremely predictable workload. One possible compromise is
to set the daemon's parameters so that it will only react to unusually to set the daemon's parameters so that it will only react to unusually
heavy update activity, thus keeping things from getting out of hand, heavy update activity, thus keeping things from getting out of hand,
while scheduled <command>VACUUM</>s are expected to do the bulk of the while scheduled <command>VACUUM</command>s are expected to do the bulk of the
work when the load is typical. work when the load is typical.
</para> </para>
<para> <para>
For those not using autovacuum, a typical approach is to schedule a For those not using autovacuum, a typical approach is to schedule a
database-wide <command>VACUUM</> once a day during a low-usage period, database-wide <command>VACUUM</command> once a day during a low-usage period,
supplemented by more frequent vacuuming of heavily-updated tables as supplemented by more frequent vacuuming of heavily-updated tables as
necessary. (Some installations with extremely high update rates vacuum necessary. (Some installations with extremely high update rates vacuum
their busiest tables as often as once every few minutes.) If you have their busiest tables as often as once every few minutes.) If you have
@ -222,11 +222,11 @@
<tip> <tip>
<para> <para>
Plain <command>VACUUM</> may not be satisfactory when Plain <command>VACUUM</command> may not be satisfactory when
a table contains large numbers of dead row versions as a result of a table contains large numbers of dead row versions as a result of
massive update or delete activity. If you have such a table and massive update or delete activity. If you have such a table and
you need to reclaim the excess disk space it occupies, you will need you need to reclaim the excess disk space it occupies, you will need
to use <command>VACUUM FULL</>, or alternatively to use <command>VACUUM FULL</command>, or alternatively
<xref linkend="sql-cluster"> <xref linkend="sql-cluster">
or one of the table-rewriting variants of or one of the table-rewriting variants of
<xref linkend="sql-altertable">. <xref linkend="sql-altertable">.
@ -271,19 +271,19 @@
generate good plans for queries. These statistics are gathered by generate good plans for queries. These statistics are gathered by
the <xref linkend="sql-analyze"> command, the <xref linkend="sql-analyze"> command,
which can be invoked by itself or which can be invoked by itself or
as an optional step in <command>VACUUM</>. It is important to have as an optional step in <command>VACUUM</command>. It is important to have
reasonably accurate statistics, otherwise poor choices of plans might reasonably accurate statistics, otherwise poor choices of plans might
degrade database performance. degrade database performance.
</para> </para>
<para> <para>
The autovacuum daemon, if enabled, will automatically issue The autovacuum daemon, if enabled, will automatically issue
<command>ANALYZE</> commands whenever the content of a table has <command>ANALYZE</command> commands whenever the content of a table has
changed sufficiently. However, administrators might prefer to rely changed sufficiently. However, administrators might prefer to rely
on manually-scheduled <command>ANALYZE</> operations, particularly on manually-scheduled <command>ANALYZE</command> operations, particularly
if it is known that update activity on a table will not affect the if it is known that update activity on a table will not affect the
statistics of <quote>interesting</> columns. The daemon schedules statistics of <quote>interesting</quote> columns. The daemon schedules
<command>ANALYZE</> strictly as a function of the number of rows <command>ANALYZE</command> strictly as a function of the number of rows
inserted or updated; it has no knowledge of whether that will lead inserted or updated; it has no knowledge of whether that will lead
to meaningful statistical changes. to meaningful statistical changes.
</para> </para>
@ -305,24 +305,24 @@
</para> </para>
<para> <para>
It is possible to run <command>ANALYZE</> on specific tables and even It is possible to run <command>ANALYZE</command> on specific tables and even
just specific columns of a table, so the flexibility exists to update some just specific columns of a table, so the flexibility exists to update some
statistics more frequently than others if your application requires it. statistics more frequently than others if your application requires it.
In practice, however, it is usually best to just analyze the entire In practice, however, it is usually best to just analyze the entire
database, because it is a fast operation. <command>ANALYZE</> uses a database, because it is a fast operation. <command>ANALYZE</command> uses a
statistically random sampling of the rows of a table rather than reading statistically random sampling of the rows of a table rather than reading
every single row. every single row.
</para> </para>
<tip> <tip>
<para> <para>
Although per-column tweaking of <command>ANALYZE</> frequency might not be Although per-column tweaking of <command>ANALYZE</command> frequency might not be
very productive, you might find it worthwhile to do per-column very productive, you might find it worthwhile to do per-column
adjustment of the level of detail of the statistics collected by adjustment of the level of detail of the statistics collected by
<command>ANALYZE</>. Columns that are heavily used in <literal>WHERE</> <command>ANALYZE</command>. Columns that are heavily used in <literal>WHERE</literal>
clauses and have highly irregular data distributions might require a clauses and have highly irregular data distributions might require a
finer-grain data histogram than other columns. See <command>ALTER TABLE finer-grain data histogram than other columns. See <command>ALTER TABLE
SET STATISTICS</>, or change the database-wide default using the <xref SET STATISTICS</command>, or change the database-wide default using the <xref
linkend="guc-default-statistics-target"> configuration parameter. linkend="guc-default-statistics-target"> configuration parameter.
</para> </para>
@ -337,11 +337,11 @@
<tip> <tip>
<para> <para>
The autovacuum daemon does not issue <command>ANALYZE</> commands for The autovacuum daemon does not issue <command>ANALYZE</command> commands for
foreign tables, since it has no means of determining how often that foreign tables, since it has no means of determining how often that
might be useful. If your queries require statistics on foreign tables might be useful. If your queries require statistics on foreign tables
for proper planning, it's a good idea to run manually-managed for proper planning, it's a good idea to run manually-managed
<command>ANALYZE</> commands on those tables on a suitable schedule. <command>ANALYZE</command> commands on those tables on a suitable schedule.
</para> </para>
</tip> </tip>
</sect2> </sect2>
@ -350,7 +350,7 @@
<title>Updating The Visibility Map</title> <title>Updating The Visibility Map</title>
<para> <para>
Vacuum maintains a <link linkend="storage-vm">visibility map</> for each Vacuum maintains a <link linkend="storage-vm">visibility map</link> for each
table to keep track of which pages contain only tuples that are known to be table to keep track of which pages contain only tuples that are known to be
visible to all active transactions (and all future transactions, until the visible to all active transactions (and all future transactions, until the
page is again modified). This has two purposes. First, vacuum page is again modified). This has two purposes. First, vacuum
@ -366,7 +366,7 @@
matching index entry, to check whether it should be seen by the current matching index entry, to check whether it should be seen by the current
transaction. transaction.
An <link linkend="indexes-index-only-scans"><firstterm>index-only An <link linkend="indexes-index-only-scans"><firstterm>index-only
scan</></link>, on the other hand, checks the visibility map first. scan</firstterm></link>, on the other hand, checks the visibility map first.
If it's known that all tuples on the page are If it's known that all tuples on the page are
visible, the heap fetch can be skipped. This is most useful on visible, the heap fetch can be skipped. This is most useful on
large data sets where the visibility map can prevent disk accesses. large data sets where the visibility map can prevent disk accesses.
@ -391,13 +391,13 @@
<para> <para>
<productname>PostgreSQL</productname>'s <productname>PostgreSQL</productname>'s
<link linkend="mvcc-intro">MVCC</link> transaction semantics <link linkend="mvcc-intro">MVCC</link> transaction semantics
depend on being able to compare transaction ID (<acronym>XID</>) depend on being able to compare transaction ID (<acronym>XID</acronym>)
numbers: a row version with an insertion XID greater than the current numbers: a row version with an insertion XID greater than the current
transaction's XID is <quote>in the future</> and should not be visible transaction's XID is <quote>in the future</quote> and should not be visible
to the current transaction. But since transaction IDs have limited size to the current transaction. But since transaction IDs have limited size
(32 bits) a cluster that runs for a long time (more (32 bits) a cluster that runs for a long time (more
than 4 billion transactions) would suffer <firstterm>transaction ID than 4 billion transactions) would suffer <firstterm>transaction ID
wraparound</>: the XID counter wraps around to zero, and all of a sudden wraparound</firstterm>: the XID counter wraps around to zero, and all of a sudden
transactions that were in the past appear to be in the future &mdash; which transactions that were in the past appear to be in the future &mdash; which
means their output become invisible. In short, catastrophic data loss. means their output become invisible. In short, catastrophic data loss.
(Actually the data is still there, but that's cold comfort if you cannot (Actually the data is still there, but that's cold comfort if you cannot
@ -407,47 +407,47 @@
<para> <para>
The reason that periodic vacuuming solves the problem is that The reason that periodic vacuuming solves the problem is that
<command>VACUUM</> will mark rows as <emphasis>frozen</>, indicating that <command>VACUUM</command> will mark rows as <emphasis>frozen</emphasis>, indicating that
they were inserted by a transaction that committed sufficiently far in they were inserted by a transaction that committed sufficiently far in
the past that the effects of the inserting transaction are certain to be the past that the effects of the inserting transaction are certain to be
visible to all current and future transactions. visible to all current and future transactions.
Normal XIDs are Normal XIDs are
compared using modulo-2<superscript>32</> arithmetic. This means compared using modulo-2<superscript>32</superscript> arithmetic. This means
that for every normal XID, there are two billion XIDs that are that for every normal XID, there are two billion XIDs that are
<quote>older</> and two billion that are <quote>newer</>; another <quote>older</quote> and two billion that are <quote>newer</quote>; another
way to say it is that the normal XID space is circular with no way to say it is that the normal XID space is circular with no
endpoint. Therefore, once a row version has been created with a particular endpoint. Therefore, once a row version has been created with a particular
normal XID, the row version will appear to be <quote>in the past</> for normal XID, the row version will appear to be <quote>in the past</quote> for
the next two billion transactions, no matter which normal XID we are the next two billion transactions, no matter which normal XID we are
talking about. If the row version still exists after more than two billion talking about. If the row version still exists after more than two billion
transactions, it will suddenly appear to be in the future. To transactions, it will suddenly appear to be in the future. To
prevent this, <productname>PostgreSQL</> reserves a special XID, prevent this, <productname>PostgreSQL</productname> reserves a special XID,
<literal>FrozenTransactionId</>, which does not follow the normal XID <literal>FrozenTransactionId</literal>, which does not follow the normal XID
comparison rules and is always considered older comparison rules and is always considered older
than every normal XID. than every normal XID.
Frozen row versions are treated as if the inserting XID were Frozen row versions are treated as if the inserting XID were
<literal>FrozenTransactionId</>, so that they will appear to be <literal>FrozenTransactionId</literal>, so that they will appear to be
<quote>in the past</> to all normal transactions regardless of wraparound <quote>in the past</quote> to all normal transactions regardless of wraparound
issues, and so such row versions will be valid until deleted, no matter issues, and so such row versions will be valid until deleted, no matter
how long that is. how long that is.
</para> </para>
<note> <note>
<para> <para>
In <productname>PostgreSQL</> versions before 9.4, freezing was In <productname>PostgreSQL</productname> versions before 9.4, freezing was
implemented by actually replacing a row's insertion XID implemented by actually replacing a row's insertion XID
with <literal>FrozenTransactionId</>, which was visible in the with <literal>FrozenTransactionId</literal>, which was visible in the
row's <structname>xmin</> system column. Newer versions just set a flag row's <structname>xmin</structname> system column. Newer versions just set a flag
bit, preserving the row's original <structname>xmin</> for possible bit, preserving the row's original <structname>xmin</structname> for possible
forensic use. However, rows with <structname>xmin</> equal forensic use. However, rows with <structname>xmin</structname> equal
to <literal>FrozenTransactionId</> (2) may still be found to <literal>FrozenTransactionId</literal> (2) may still be found
in databases <application>pg_upgrade</>'d from pre-9.4 versions. in databases <application>pg_upgrade</application>'d from pre-9.4 versions.
</para> </para>
<para> <para>
Also, system catalogs may contain rows with <structname>xmin</> equal Also, system catalogs may contain rows with <structname>xmin</structname> equal
to <literal>BootstrapTransactionId</> (1), indicating that they were to <literal>BootstrapTransactionId</literal> (1), indicating that they were
inserted during the first phase of <application>initdb</>. inserted during the first phase of <application>initdb</application>.
Like <literal>FrozenTransactionId</>, this special XID is treated as Like <literal>FrozenTransactionId</literal>, this special XID is treated as
older than every normal XID. older than every normal XID.
</para> </para>
</note> </note>
@ -463,26 +463,26 @@
</para> </para>
<para> <para>
<command>VACUUM</> uses the <link linkend="storage-vm">visibility map</> <command>VACUUM</command> uses the <link linkend="storage-vm">visibility map</link>
to determine which pages of a table must be scanned. Normally, it to determine which pages of a table must be scanned. Normally, it
will skip pages that don't have any dead row versions even if those pages will skip pages that don't have any dead row versions even if those pages
might still have row versions with old XID values. Therefore, normal might still have row versions with old XID values. Therefore, normal
<command>VACUUM</>s won't always freeze every old row version in the table. <command>VACUUM</command>s won't always freeze every old row version in the table.
Periodically, <command>VACUUM</> will perform an <firstterm>aggressive Periodically, <command>VACUUM</command> will perform an <firstterm>aggressive
vacuum</>, skipping only those pages which contain neither dead rows nor vacuum</firstterm>, skipping only those pages which contain neither dead rows nor
any unfrozen XID or MXID values. any unfrozen XID or MXID values.
<xref linkend="guc-vacuum-freeze-table-age"> <xref linkend="guc-vacuum-freeze-table-age">
controls when <command>VACUUM</> does that: all-visible but not all-frozen controls when <command>VACUUM</command> does that: all-visible but not all-frozen
pages are scanned if the number of transactions that have passed since the pages are scanned if the number of transactions that have passed since the
last such scan is greater than <varname>vacuum_freeze_table_age</> minus last such scan is greater than <varname>vacuum_freeze_table_age</varname> minus
<varname>vacuum_freeze_min_age</>. Setting <varname>vacuum_freeze_min_age</varname>. Setting
<varname>vacuum_freeze_table_age</> to 0 forces <command>VACUUM</> to <varname>vacuum_freeze_table_age</varname> to 0 forces <command>VACUUM</command> to
use this more aggressive strategy for all scans. use this more aggressive strategy for all scans.
</para> </para>
<para> <para>
The maximum time that a table can go unvacuumed is two billion The maximum time that a table can go unvacuumed is two billion
transactions minus the <varname>vacuum_freeze_min_age</> value at transactions minus the <varname>vacuum_freeze_min_age</varname> value at
the time of the last aggressive vacuum. If it were to go the time of the last aggressive vacuum. If it were to go
unvacuumed for longer than unvacuumed for longer than
that, data loss could result. To ensure that this does not happen, that, data loss could result. To ensure that this does not happen,
@ -495,29 +495,29 @@
<para> <para>
This implies that if a table is not otherwise vacuumed, This implies that if a table is not otherwise vacuumed,
autovacuum will be invoked on it approximately once every autovacuum will be invoked on it approximately once every
<varname>autovacuum_freeze_max_age</> minus <varname>autovacuum_freeze_max_age</varname> minus
<varname>vacuum_freeze_min_age</> transactions. <varname>vacuum_freeze_min_age</varname> transactions.
For tables that are regularly vacuumed for space reclamation purposes, For tables that are regularly vacuumed for space reclamation purposes,
this is of little importance. However, for static tables this is of little importance. However, for static tables
(including tables that receive inserts, but no updates or deletes), (including tables that receive inserts, but no updates or deletes),
there is no need to vacuum for space reclamation, so it can there is no need to vacuum for space reclamation, so it can
be useful to try to maximize the interval between forced autovacuums be useful to try to maximize the interval between forced autovacuums
on very large static tables. Obviously one can do this either by on very large static tables. Obviously one can do this either by
increasing <varname>autovacuum_freeze_max_age</> or decreasing increasing <varname>autovacuum_freeze_max_age</varname> or decreasing
<varname>vacuum_freeze_min_age</>. <varname>vacuum_freeze_min_age</varname>.
</para> </para>
<para> <para>
The effective maximum for <varname>vacuum_freeze_table_age</> is 0.95 * The effective maximum for <varname>vacuum_freeze_table_age</varname> is 0.95 *
<varname>autovacuum_freeze_max_age</>; a setting higher than that will be <varname>autovacuum_freeze_max_age</varname>; a setting higher than that will be
capped to the maximum. A value higher than capped to the maximum. A value higher than
<varname>autovacuum_freeze_max_age</> wouldn't make sense because an <varname>autovacuum_freeze_max_age</varname> wouldn't make sense because an
anti-wraparound autovacuum would be triggered at that point anyway, and anti-wraparound autovacuum would be triggered at that point anyway, and
the 0.95 multiplier leaves some breathing room to run a manual the 0.95 multiplier leaves some breathing room to run a manual
<command>VACUUM</> before that happens. As a rule of thumb, <command>VACUUM</command> before that happens. As a rule of thumb,
<command>vacuum_freeze_table_age</> should be set to a value somewhat <command>vacuum_freeze_table_age</command> should be set to a value somewhat
below <varname>autovacuum_freeze_max_age</>, leaving enough gap so that below <varname>autovacuum_freeze_max_age</varname>, leaving enough gap so that
a regularly scheduled <command>VACUUM</> or an autovacuum triggered by a regularly scheduled <command>VACUUM</command> or an autovacuum triggered by
normal delete and update activity is run in that window. Setting it too normal delete and update activity is run in that window. Setting it too
close could lead to anti-wraparound autovacuums, even though the table close could lead to anti-wraparound autovacuums, even though the table
was recently vacuumed to reclaim space, whereas lower values lead to more was recently vacuumed to reclaim space, whereas lower values lead to more
@ -525,29 +525,29 @@
</para> </para>
<para> <para>
The sole disadvantage of increasing <varname>autovacuum_freeze_max_age</> The sole disadvantage of increasing <varname>autovacuum_freeze_max_age</varname>
(and <varname>vacuum_freeze_table_age</> along with it) is that (and <varname>vacuum_freeze_table_age</varname> along with it) is that
the <filename>pg_xact</> and <filename>pg_commit_ts</filename> the <filename>pg_xact</filename> and <filename>pg_commit_ts</filename>
subdirectories of the database cluster will take more space, because it subdirectories of the database cluster will take more space, because it
must store the commit status and (if <varname>track_commit_timestamp</> is must store the commit status and (if <varname>track_commit_timestamp</varname> is
enabled) timestamp of all transactions back to enabled) timestamp of all transactions back to
the <varname>autovacuum_freeze_max_age</> horizon. The commit status uses the <varname>autovacuum_freeze_max_age</varname> horizon. The commit status uses
two bits per transaction, so if two bits per transaction, so if
<varname>autovacuum_freeze_max_age</> is set to its maximum allowed value <varname>autovacuum_freeze_max_age</varname> is set to its maximum allowed value
of two billion, <filename>pg_xact</> can be expected to grow to about half of two billion, <filename>pg_xact</filename> can be expected to grow to about half
a gigabyte and <filename>pg_commit_ts</filename> to about 20GB. If this a gigabyte and <filename>pg_commit_ts</filename> to about 20GB. If this
is trivial compared to your total database size, is trivial compared to your total database size,
setting <varname>autovacuum_freeze_max_age</> to its maximum allowed value setting <varname>autovacuum_freeze_max_age</varname> to its maximum allowed value
is recommended. Otherwise, set it depending on what you are willing to is recommended. Otherwise, set it depending on what you are willing to
allow for <filename>pg_xact</> and <filename>pg_commit_ts</> storage. allow for <filename>pg_xact</filename> and <filename>pg_commit_ts</filename> storage.
(The default, 200 million transactions, translates to about 50MB (The default, 200 million transactions, translates to about 50MB
of <filename>pg_xact</> storage and about 2GB of <filename>pg_commit_ts</> of <filename>pg_xact</filename> storage and about 2GB of <filename>pg_commit_ts</filename>
storage.) storage.)
</para> </para>
<para> <para>
One disadvantage of decreasing <varname>vacuum_freeze_min_age</> is that One disadvantage of decreasing <varname>vacuum_freeze_min_age</varname> is that
it might cause <command>VACUUM</> to do useless work: freezing a row it might cause <command>VACUUM</command> to do useless work: freezing a row
version is a waste of time if the row is modified version is a waste of time if the row is modified
soon thereafter (causing it to acquire a new XID). So the setting should soon thereafter (causing it to acquire a new XID). So the setting should
be large enough that rows are not frozen until they are unlikely to change be large enough that rows are not frozen until they are unlikely to change
@ -556,18 +556,18 @@
<para> <para>
To track the age of the oldest unfrozen XIDs in a database, To track the age of the oldest unfrozen XIDs in a database,
<command>VACUUM</> stores XID <command>VACUUM</command> stores XID
statistics in the system tables <structname>pg_class</> and statistics in the system tables <structname>pg_class</structname> and
<structname>pg_database</>. In particular, <structname>pg_database</structname>. In particular,
the <structfield>relfrozenxid</> column of a table's the <structfield>relfrozenxid</structfield> column of a table's
<structname>pg_class</> row contains the freeze cutoff XID that was used <structname>pg_class</structname> row contains the freeze cutoff XID that was used
by the last aggressive <command>VACUUM</> for that table. All rows by the last aggressive <command>VACUUM</command> for that table. All rows
inserted by transactions with XIDs older than this cutoff XID are inserted by transactions with XIDs older than this cutoff XID are
guaranteed to have been frozen. Similarly, guaranteed to have been frozen. Similarly,
the <structfield>datfrozenxid</> column of a database's the <structfield>datfrozenxid</structfield> column of a database's
<structname>pg_database</> row is a lower bound on the unfrozen XIDs <structname>pg_database</structname> row is a lower bound on the unfrozen XIDs
appearing in that database &mdash; it is just the minimum of the appearing in that database &mdash; it is just the minimum of the
per-table <structfield>relfrozenxid</> values within the database. per-table <structfield>relfrozenxid</structfield> values within the database.
A convenient way to A convenient way to
examine this information is to execute queries such as: examine this information is to execute queries such as:
@ -581,27 +581,27 @@ WHERE c.relkind IN ('r', 'm');
SELECT datname, age(datfrozenxid) FROM pg_database; SELECT datname, age(datfrozenxid) FROM pg_database;
</programlisting> </programlisting>
The <literal>age</> column measures the number of transactions from the The <literal>age</literal> column measures the number of transactions from the
cutoff XID to the current transaction's XID. cutoff XID to the current transaction's XID.
</para> </para>
<para> <para>
<command>VACUUM</> normally only scans pages that have been modified <command>VACUUM</command> normally only scans pages that have been modified
since the last vacuum, but <structfield>relfrozenxid</> can only be since the last vacuum, but <structfield>relfrozenxid</structfield> can only be
advanced when every page of the table advanced when every page of the table
that might contain unfrozen XIDs is scanned. This happens when that might contain unfrozen XIDs is scanned. This happens when
<structfield>relfrozenxid</> is more than <structfield>relfrozenxid</structfield> is more than
<varname>vacuum_freeze_table_age</> transactions old, when <varname>vacuum_freeze_table_age</varname> transactions old, when
<command>VACUUM</>'s <literal>FREEZE</> option is used, or when all <command>VACUUM</command>'s <literal>FREEZE</literal> option is used, or when all
pages that are not already all-frozen happen to pages that are not already all-frozen happen to
require vacuuming to remove dead row versions. When <command>VACUUM</> require vacuuming to remove dead row versions. When <command>VACUUM</command>
scans every page in the table that is not already all-frozen, it should scans every page in the table that is not already all-frozen, it should
set <literal>age(relfrozenxid)</> to a value just a little more than the set <literal>age(relfrozenxid)</literal> to a value just a little more than the
<varname>vacuum_freeze_min_age</> setting <varname>vacuum_freeze_min_age</varname> setting
that was used (more by the number of transactions started since the that was used (more by the number of transactions started since the
<command>VACUUM</> started). If no <structfield>relfrozenxid</>-advancing <command>VACUUM</command> started). If no <structfield>relfrozenxid</structfield>-advancing
<command>VACUUM</> is issued on the table until <command>VACUUM</command> is issued on the table until
<varname>autovacuum_freeze_max_age</> is reached, an autovacuum will soon <varname>autovacuum_freeze_max_age</varname> is reached, an autovacuum will soon
be forced for the table. be forced for the table.
</para> </para>
@ -616,10 +616,10 @@ WARNING: database "mydb" must be vacuumed within 177009986 transactions
HINT: To avoid a database shutdown, execute a database-wide VACUUM in "mydb". HINT: To avoid a database shutdown, execute a database-wide VACUUM in "mydb".
</programlisting> </programlisting>
(A manual <command>VACUUM</> should fix the problem, as suggested by the (A manual <command>VACUUM</command> should fix the problem, as suggested by the
hint; but note that the <command>VACUUM</> must be performed by a hint; but note that the <command>VACUUM</command> must be performed by a
superuser, else it will fail to process system catalogs and thus not superuser, else it will fail to process system catalogs and thus not
be able to advance the database's <structfield>datfrozenxid</>.) be able to advance the database's <structfield>datfrozenxid</structfield>.)
If these warnings are If these warnings are
ignored, the system will shut down and refuse to start any new ignored, the system will shut down and refuse to start any new
transactions once there are fewer than 1 million transactions left transactions once there are fewer than 1 million transactions left
@ -632,10 +632,10 @@ HINT: Stop the postmaster and vacuum that database in single-user mode.
The 1-million-transaction safety margin exists to let the The 1-million-transaction safety margin exists to let the
administrator recover without data loss, by manually executing the administrator recover without data loss, by manually executing the
required <command>VACUUM</> commands. However, since the system will not required <command>VACUUM</command> commands. However, since the system will not
execute commands once it has gone into the safety shutdown mode, execute commands once it has gone into the safety shutdown mode,
the only way to do this is to stop the server and start the server in single-user the only way to do this is to stop the server and start the server in single-user
mode to execute <command>VACUUM</>. The shutdown mode is not enforced mode to execute <command>VACUUM</command>. The shutdown mode is not enforced
in single-user mode. See the <xref linkend="app-postgres"> reference in single-user mode. See the <xref linkend="app-postgres"> reference
page for details about using single-user mode. page for details about using single-user mode.
</para> </para>
@ -653,15 +653,15 @@ HINT: Stop the postmaster and vacuum that database in single-user mode.
</indexterm> </indexterm>
<para> <para>
<firstterm>Multixact IDs</> are used to support row locking by <firstterm>Multixact IDs</firstterm> are used to support row locking by
multiple transactions. Since there is only limited space in a tuple multiple transactions. Since there is only limited space in a tuple
header to store lock information, that information is encoded as header to store lock information, that information is encoded as
a <quote>multiple transaction ID</>, or multixact ID for short, a <quote>multiple transaction ID</quote>, or multixact ID for short,
whenever there is more than one transaction concurrently locking a whenever there is more than one transaction concurrently locking a
row. Information about which transaction IDs are included in any row. Information about which transaction IDs are included in any
particular multixact ID is stored separately in particular multixact ID is stored separately in
the <filename>pg_multixact</> subdirectory, and only the multixact ID the <filename>pg_multixact</filename> subdirectory, and only the multixact ID
appears in the <structfield>xmax</> field in the tuple header. appears in the <structfield>xmax</structfield> field in the tuple header.
Like transaction IDs, multixact IDs are implemented as a Like transaction IDs, multixact IDs are implemented as a
32-bit counter and corresponding storage, all of which requires 32-bit counter and corresponding storage, all of which requires
careful aging management, storage cleanup, and wraparound handling. careful aging management, storage cleanup, and wraparound handling.
@ -671,23 +671,23 @@ HINT: Stop the postmaster and vacuum that database in single-user mode.
</para> </para>
<para> <para>
Whenever <command>VACUUM</> scans any part of a table, it will replace Whenever <command>VACUUM</command> scans any part of a table, it will replace
any multixact ID it encounters which is older than any multixact ID it encounters which is older than
<xref linkend="guc-vacuum-multixact-freeze-min-age"> <xref linkend="guc-vacuum-multixact-freeze-min-age">
by a different value, which can be the zero value, a single by a different value, which can be the zero value, a single
transaction ID, or a newer multixact ID. For each table, transaction ID, or a newer multixact ID. For each table,
<structname>pg_class</>.<structfield>relminmxid</> stores the oldest <structname>pg_class</structname>.<structfield>relminmxid</structfield> stores the oldest
possible multixact ID still appearing in any tuple of that table. possible multixact ID still appearing in any tuple of that table.
If this value is older than If this value is older than
<xref linkend="guc-vacuum-multixact-freeze-table-age">, an aggressive <xref linkend="guc-vacuum-multixact-freeze-table-age">, an aggressive
vacuum is forced. As discussed in the previous section, an aggressive vacuum is forced. As discussed in the previous section, an aggressive
vacuum means that only those pages which are known to be all-frozen will vacuum means that only those pages which are known to be all-frozen will
be skipped. <function>mxid_age()</> can be used on be skipped. <function>mxid_age()</function> can be used on
<structname>pg_class</>.<structfield>relminmxid</> to find its age. <structname>pg_class</structname>.<structfield>relminmxid</structfield> to find its age.
</para> </para>
<para> <para>
Aggressive <command>VACUUM</> scans, regardless of Aggressive <command>VACUUM</command> scans, regardless of
what causes them, enable advancing the value for that table. what causes them, enable advancing the value for that table.
Eventually, as all tables in all databases are scanned and their Eventually, as all tables in all databases are scanned and their
oldest multixact values are advanced, on-disk storage for older oldest multixact values are advanced, on-disk storage for older
@ -729,21 +729,21 @@ HINT: Stop the postmaster and vacuum that database in single-user mode.
</para> </para>
<para> <para>
The <quote>autovacuum daemon</> actually consists of multiple processes. The <quote>autovacuum daemon</quote> actually consists of multiple processes.
There is a persistent daemon process, called the There is a persistent daemon process, called the
<firstterm>autovacuum launcher</firstterm>, which is in charge of starting <firstterm>autovacuum launcher</firstterm>, which is in charge of starting
<firstterm>autovacuum worker</firstterm> processes for all databases. The <firstterm>autovacuum worker</firstterm> processes for all databases. The
launcher will distribute the work across time, attempting to start one launcher will distribute the work across time, attempting to start one
worker within each database every <xref linkend="guc-autovacuum-naptime"> worker within each database every <xref linkend="guc-autovacuum-naptime">
seconds. (Therefore, if the installation has <replaceable>N</> databases, seconds. (Therefore, if the installation has <replaceable>N</replaceable> databases,
a new worker will be launched every a new worker will be launched every
<varname>autovacuum_naptime</>/<replaceable>N</> seconds.) <varname>autovacuum_naptime</varname>/<replaceable>N</replaceable> seconds.)
A maximum of <xref linkend="guc-autovacuum-max-workers"> worker processes A maximum of <xref linkend="guc-autovacuum-max-workers"> worker processes
are allowed to run at the same time. If there are more than are allowed to run at the same time. If there are more than
<varname>autovacuum_max_workers</> databases to be processed, <varname>autovacuum_max_workers</varname> databases to be processed,
the next database will be processed as soon as the first worker finishes. the next database will be processed as soon as the first worker finishes.
Each worker process will check each table within its database and Each worker process will check each table within its database and
execute <command>VACUUM</> and/or <command>ANALYZE</> as needed. execute <command>VACUUM</command> and/or <command>ANALYZE</command> as needed.
<xref linkend="guc-log-autovacuum-min-duration"> can be set to monitor <xref linkend="guc-log-autovacuum-min-duration"> can be set to monitor
autovacuum workers' activity. autovacuum workers' activity.
</para> </para>
@ -761,7 +761,7 @@ HINT: Stop the postmaster and vacuum that database in single-user mode.
</para> </para>
<para> <para>
Tables whose <structfield>relfrozenxid</> value is more than Tables whose <structfield>relfrozenxid</structfield> value is more than
<xref linkend="guc-autovacuum-freeze-max-age"> transactions old are always <xref linkend="guc-autovacuum-freeze-max-age"> transactions old are always
vacuumed (this also applies to those tables whose freeze max age has vacuumed (this also applies to those tables whose freeze max age has
been modified via storage parameters; see below). Otherwise, if the been modified via storage parameters; see below). Otherwise, if the
@ -781,10 +781,10 @@ vacuum threshold = vacuum base threshold + vacuum scale factor * number of tuple
collector; it is a semi-accurate count updated by each collector; it is a semi-accurate count updated by each
<command>UPDATE</command> and <command>DELETE</command> operation. (It <command>UPDATE</command> and <command>DELETE</command> operation. (It
is only semi-accurate because some information might be lost under heavy is only semi-accurate because some information might be lost under heavy
load.) If the <structfield>relfrozenxid</> value of the table is more load.) If the <structfield>relfrozenxid</structfield> value of the table is more
than <varname>vacuum_freeze_table_age</> transactions old, an aggressive than <varname>vacuum_freeze_table_age</varname> transactions old, an aggressive
vacuum is performed to freeze old tuples and advance vacuum is performed to freeze old tuples and advance
<structfield>relfrozenxid</>; otherwise, only pages that have been modified <structfield>relfrozenxid</structfield>; otherwise, only pages that have been modified
since the last vacuum are scanned. since the last vacuum are scanned.
</para> </para>
@ -821,8 +821,8 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu
<quote>balanced</quote> among all the running workers, so that the <quote>balanced</quote> among all the running workers, so that the
total I/O impact on the system is the same regardless of the number total I/O impact on the system is the same regardless of the number
of workers actually running. However, any workers processing tables whose of workers actually running. However, any workers processing tables whose
per-table <literal>autovacuum_vacuum_cost_delay</> or per-table <literal>autovacuum_vacuum_cost_delay</literal> or
<literal>autovacuum_vacuum_cost_limit</> storage parameters have been set <literal>autovacuum_vacuum_cost_limit</literal> storage parameters have been set
are not considered in the balancing algorithm. are not considered in the balancing algorithm.
</para> </para>
</sect2> </sect2>
@ -872,7 +872,7 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu
But since the command requires an exclusive table lock, it is But since the command requires an exclusive table lock, it is
often preferable to execute an index rebuild with a sequence of often preferable to execute an index rebuild with a sequence of
creation and replacement steps. Index types that support creation and replacement steps. Index types that support
<xref linkend="sql-createindex"> with the <literal>CONCURRENTLY</> <xref linkend="sql-createindex"> with the <literal>CONCURRENTLY</literal>
option can instead be recreated that way. If that is successful and the option can instead be recreated that way. If that is successful and the
resulting index is valid, the original index can then be replaced by resulting index is valid, the original index can then be replaced by
the newly built one using a combination of <xref linkend="sql-alterindex"> the newly built one using a combination of <xref linkend="sql-alterindex">
@ -896,17 +896,17 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu
<para> <para>
It is a good idea to save the database server's log output It is a good idea to save the database server's log output
somewhere, rather than just discarding it via <filename>/dev/null</>. somewhere, rather than just discarding it via <filename>/dev/null</filename>.
The log output is invaluable when diagnosing The log output is invaluable when diagnosing
problems. However, the log output tends to be voluminous problems. However, the log output tends to be voluminous
(especially at higher debug levels) so you won't want to save it (especially at higher debug levels) so you won't want to save it
indefinitely. You need to <emphasis>rotate</> the log files so that indefinitely. You need to <emphasis>rotate</emphasis> the log files so that
new log files are started and old ones removed after a reasonable new log files are started and old ones removed after a reasonable
period of time. period of time.
</para> </para>
<para> <para>
If you simply direct the <systemitem>stderr</> of If you simply direct the <systemitem>stderr</systemitem> of
<command>postgres</command> into a <command>postgres</command> into a
file, you will have log output, but file, you will have log output, but
the only way to truncate the log file is to stop and restart the only way to truncate the log file is to stop and restart
@ -917,13 +917,13 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu
<para> <para>
A better approach is to send the server's A better approach is to send the server's
<systemitem>stderr</> output to some type of log rotation program. <systemitem>stderr</systemitem> output to some type of log rotation program.
There is a built-in log rotation facility, which you can use by There is a built-in log rotation facility, which you can use by
setting the configuration parameter <varname>logging_collector</> to setting the configuration parameter <varname>logging_collector</varname> to
<literal>true</> in <filename>postgresql.conf</>. The control <literal>true</literal> in <filename>postgresql.conf</filename>. The control
parameters for this program are described in <xref parameters for this program are described in <xref
linkend="runtime-config-logging-where">. You can also use this approach linkend="runtime-config-logging-where">. You can also use this approach
to capture the log data in machine readable <acronym>CSV</> to capture the log data in machine readable <acronym>CSV</acronym>
(comma-separated values) format. (comma-separated values) format.
</para> </para>
@ -934,10 +934,10 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu
tool included in the <productname>Apache</productname> distribution tool included in the <productname>Apache</productname> distribution
can be used with <productname>PostgreSQL</productname>. To do this, can be used with <productname>PostgreSQL</productname>. To do this,
just pipe the server's just pipe the server's
<systemitem>stderr</> output to the desired program. <systemitem>stderr</systemitem> output to the desired program.
If you start the server with If you start the server with
<command>pg_ctl</>, then <systemitem>stderr</> <command>pg_ctl</command>, then <systemitem>stderr</systemitem>
is already redirected to <systemitem>stdout</>, so you just need a is already redirected to <systemitem>stdout</systemitem>, so you just need a
pipe command, for example: pipe command, for example:
<programlisting> <programlisting>
@ -947,12 +947,12 @@ pg_ctl start | rotatelogs /var/log/pgsql_log 86400
<para> <para>
Another production-grade approach to managing log output is to Another production-grade approach to managing log output is to
send it to <application>syslog</> and let send it to <application>syslog</application> and let
<application>syslog</> deal with file rotation. To do this, set the <application>syslog</application> deal with file rotation. To do this, set the
configuration parameter <varname>log_destination</> to <literal>syslog</> configuration parameter <varname>log_destination</varname> to <literal>syslog</literal>
(to log to <application>syslog</> only) in (to log to <application>syslog</application> only) in
<filename>postgresql.conf</>. Then you can send a <literal>SIGHUP</literal> <filename>postgresql.conf</filename>. Then you can send a <literal>SIGHUP</literal>
signal to the <application>syslog</> daemon whenever you want to force it signal to the <application>syslog</application> daemon whenever you want to force it
to start writing a new log file. If you want to automate log to start writing a new log file. If you want to automate log
rotation, the <application>logrotate</application> program can be rotation, the <application>logrotate</application> program can be
configured to work with log files from configured to work with log files from
@ -960,12 +960,12 @@ pg_ctl start | rotatelogs /var/log/pgsql_log 86400
</para> </para>
<para> <para>
On many systems, however, <application>syslog</> is not very reliable, On many systems, however, <application>syslog</application> is not very reliable,
particularly with large log messages; it might truncate or drop messages particularly with large log messages; it might truncate or drop messages
just when you need them the most. Also, on <productname>Linux</>, just when you need them the most. Also, on <productname>Linux</productname>,
<application>syslog</> will flush each message to disk, yielding poor <application>syslog</application> will flush each message to disk, yielding poor
performance. (You can use a <quote><literal>-</></> at the start of the file name performance. (You can use a <quote><literal>-</literal></quote> at the start of the file name
in the <application>syslog</> configuration file to disable syncing.) in the <application>syslog</application> configuration file to disable syncing.)
</para> </para>
<para> <para>

View File

@ -3,7 +3,7 @@
<chapter id="managing-databases"> <chapter id="managing-databases">
<title>Managing Databases</title> <title>Managing Databases</title>
<indexterm zone="managing-databases"><primary>database</></> <indexterm zone="managing-databases"><primary>database</primary></indexterm>
<para> <para>
Every instance of a running <productname>PostgreSQL</productname> Every instance of a running <productname>PostgreSQL</productname>
@ -26,7 +26,7 @@
(<quote>database objects</quote>). Generally, every database (<quote>database objects</quote>). Generally, every database
object (tables, functions, etc.) belongs to one and only one object (tables, functions, etc.) belongs to one and only one
database. (However there are a few system catalogs, for example database. (However there are a few system catalogs, for example
<literal>pg_database</>, that belong to a whole cluster and <literal>pg_database</literal>, that belong to a whole cluster and
are accessible from each database within the cluster.) More are accessible from each database within the cluster.) More
accurately, a database is a collection of schemas and the schemas accurately, a database is a collection of schemas and the schemas
contain the tables, functions, etc. So the full hierarchy is: contain the tables, functions, etc. So the full hierarchy is:
@ -41,7 +41,7 @@
connection. However, an application is not restricted in the number of connection. However, an application is not restricted in the number of
connections it opens to the same or other databases. Databases are connections it opens to the same or other databases. Databases are
physically separated and access control is managed at the physically separated and access control is managed at the
connection level. If one <productname>PostgreSQL</> server connection level. If one <productname>PostgreSQL</productname> server
instance is to house projects or users that should be separate and instance is to house projects or users that should be separate and
for the most part unaware of each other, it is therefore for the most part unaware of each other, it is therefore
recommended to put them into separate databases. If the projects recommended to put them into separate databases. If the projects
@ -53,23 +53,23 @@
</para> </para>
<para> <para>
Databases are created with the <command>CREATE DATABASE</> command Databases are created with the <command>CREATE DATABASE</command> command
(see <xref linkend="manage-ag-createdb">) and destroyed with the (see <xref linkend="manage-ag-createdb">) and destroyed with the
<command>DROP DATABASE</> command <command>DROP DATABASE</command> command
(see <xref linkend="manage-ag-dropdb">). (see <xref linkend="manage-ag-dropdb">).
To determine the set of existing databases, examine the To determine the set of existing databases, examine the
<structname>pg_database</> system catalog, for example <structname>pg_database</structname> system catalog, for example
<synopsis> <synopsis>
SELECT datname FROM pg_database; SELECT datname FROM pg_database;
</synopsis> </synopsis>
The <xref linkend="app-psql"> program's <literal>\l</> meta-command The <xref linkend="app-psql"> program's <literal>\l</literal> meta-command
and <option>-l</> command-line option are also useful for listing the and <option>-l</option> command-line option are also useful for listing the
existing databases. existing databases.
</para> </para>
<note> <note>
<para> <para>
The <acronym>SQL</> standard calls databases <quote>catalogs</>, but there The <acronym>SQL</acronym> standard calls databases <quote>catalogs</quote>, but there
is no difference in practice. is no difference in practice.
</para> </para>
</note> </note>
@ -78,10 +78,10 @@ SELECT datname FROM pg_database;
<sect1 id="manage-ag-createdb"> <sect1 id="manage-ag-createdb">
<title>Creating a Database</title> <title>Creating a Database</title>
<indexterm><primary>CREATE DATABASE</></> <indexterm><primary>CREATE DATABASE</primary></indexterm>
<para> <para>
In order to create a database, the <productname>PostgreSQL</> In order to create a database, the <productname>PostgreSQL</productname>
server must be up and running (see <xref server must be up and running (see <xref
linkend="server-start">). linkend="server-start">).
</para> </para>
@ -90,9 +90,9 @@ SELECT datname FROM pg_database;
Databases are created with the SQL command Databases are created with the SQL command
<xref linkend="sql-createdatabase">: <xref linkend="sql-createdatabase">:
<synopsis> <synopsis>
CREATE DATABASE <replaceable>name</>; CREATE DATABASE <replaceable>name</replaceable>;
</synopsis> </synopsis>
where <replaceable>name</> follows the usual rules for where <replaceable>name</replaceable> follows the usual rules for
<acronym>SQL</acronym> identifiers. The current role automatically <acronym>SQL</acronym> identifiers. The current role automatically
becomes the owner of the new database. It is the privilege of the becomes the owner of the new database. It is the privilege of the
owner of a database to remove it later (which also removes all owner of a database to remove it later (which also removes all
@ -107,25 +107,25 @@ CREATE DATABASE <replaceable>name</>;
<para> <para>
Since you need to be connected to the database server in order to Since you need to be connected to the database server in order to
execute the <command>CREATE DATABASE</command> command, the execute the <command>CREATE DATABASE</command> command, the
question remains how the <emphasis>first</> database at any given question remains how the <emphasis>first</emphasis> database at any given
site can be created. The first database is always created by the site can be created. The first database is always created by the
<command>initdb</> command when the data storage area is <command>initdb</command> command when the data storage area is
initialized. (See <xref linkend="creating-cluster">.) This initialized. (See <xref linkend="creating-cluster">.) This
database is called database is called
<literal>postgres</>.<indexterm><primary>postgres</></> So to <literal>postgres</literal>.<indexterm><primary>postgres</primary></indexterm> So to
create the first <quote>ordinary</> database you can connect to create the first <quote>ordinary</quote> database you can connect to
<literal>postgres</>. <literal>postgres</literal>.
</para> </para>
<para> <para>
A second database, A second database,
<literal>template1</literal>,<indexterm><primary>template1</></> <literal>template1</literal>,<indexterm><primary>template1</primary></indexterm>
is also created during database cluster initialization. Whenever a is also created during database cluster initialization. Whenever a
new database is created within the new database is created within the
cluster, <literal>template1</literal> is essentially cloned. cluster, <literal>template1</literal> is essentially cloned.
This means that any changes you make in <literal>template1</> are This means that any changes you make in <literal>template1</literal> are
propagated to all subsequently created databases. Because of this, propagated to all subsequently created databases. Because of this,
avoid creating objects in <literal>template1</> unless you want them avoid creating objects in <literal>template1</literal> unless you want them
propagated to every newly created database. More details propagated to every newly created database. More details
appear in <xref linkend="manage-ag-templatedbs">. appear in <xref linkend="manage-ag-templatedbs">.
</para> </para>
@ -133,17 +133,17 @@ CREATE DATABASE <replaceable>name</>;
<para> <para>
As a convenience, there is a program you can As a convenience, there is a program you can
execute from the shell to create new databases, execute from the shell to create new databases,
<command>createdb</>.<indexterm><primary>createdb</></> <command>createdb</command>.<indexterm><primary>createdb</primary></indexterm>
<synopsis> <synopsis>
createdb <replaceable class="parameter">dbname</replaceable> createdb <replaceable class="parameter">dbname</replaceable>
</synopsis> </synopsis>
<command>createdb</> does no magic. It connects to the <literal>postgres</> <command>createdb</command> does no magic. It connects to the <literal>postgres</literal>
database and issues the <command>CREATE DATABASE</> command, database and issues the <command>CREATE DATABASE</command> command,
exactly as described above. exactly as described above.
The <xref linkend="app-createdb"> reference page contains the invocation The <xref linkend="app-createdb"> reference page contains the invocation
details. Note that <command>createdb</> without any arguments will create details. Note that <command>createdb</command> without any arguments will create
a database with the current user name. a database with the current user name.
</para> </para>
@ -160,11 +160,11 @@ createdb <replaceable class="parameter">dbname</replaceable>
configure and manage it themselves. To achieve that, use one of the configure and manage it themselves. To achieve that, use one of the
following commands: following commands:
<programlisting> <programlisting>
CREATE DATABASE <replaceable>dbname</> OWNER <replaceable>rolename</>; CREATE DATABASE <replaceable>dbname</replaceable> OWNER <replaceable>rolename</replaceable>;
</programlisting> </programlisting>
from the SQL environment, or: from the SQL environment, or:
<programlisting> <programlisting>
createdb -O <replaceable>rolename</> <replaceable>dbname</> createdb -O <replaceable>rolename</replaceable> <replaceable>dbname</replaceable>
</programlisting> </programlisting>
from the shell. from the shell.
Only the superuser is allowed to create a database for Only the superuser is allowed to create a database for
@ -176,55 +176,55 @@ createdb -O <replaceable>rolename</> <replaceable>dbname</>
<title>Template Databases</title> <title>Template Databases</title>
<para> <para>
<command>CREATE DATABASE</> actually works by copying an existing <command>CREATE DATABASE</command> actually works by copying an existing
database. By default, it copies the standard system database named database. By default, it copies the standard system database named
<literal>template1</>.<indexterm><primary>template1</></> Thus that <literal>template1</literal>.<indexterm><primary>template1</primary></indexterm> Thus that
database is the <quote>template</> from which new databases are database is the <quote>template</quote> from which new databases are
made. If you add objects to <literal>template1</>, these objects made. If you add objects to <literal>template1</literal>, these objects
will be copied into subsequently created user databases. This will be copied into subsequently created user databases. This
behavior allows site-local modifications to the standard set of behavior allows site-local modifications to the standard set of
objects in databases. For example, if you install the procedural objects in databases. For example, if you install the procedural
language <application>PL/Perl</> in <literal>template1</>, it will language <application>PL/Perl</application> in <literal>template1</literal>, it will
automatically be available in user databases without any extra automatically be available in user databases without any extra
action being taken when those databases are created. action being taken when those databases are created.
</para> </para>
<para> <para>
There is a second standard system database named There is a second standard system database named
<literal>template0</>.<indexterm><primary>template0</></> This <literal>template0</literal>.<indexterm><primary>template0</primary></indexterm> This
database contains the same data as the initial contents of database contains the same data as the initial contents of
<literal>template1</>, that is, only the standard objects <literal>template1</literal>, that is, only the standard objects
predefined by your version of predefined by your version of
<productname>PostgreSQL</productname>. <literal>template0</> <productname>PostgreSQL</productname>. <literal>template0</literal>
should never be changed after the database cluster has been should never be changed after the database cluster has been
initialized. By instructing initialized. By instructing
<command>CREATE DATABASE</> to copy <literal>template0</> instead <command>CREATE DATABASE</command> to copy <literal>template0</literal> instead
of <literal>template1</>, you can create a <quote>virgin</> user of <literal>template1</literal>, you can create a <quote>virgin</quote> user
database that contains none of the site-local additions in database that contains none of the site-local additions in
<literal>template1</>. This is particularly handy when restoring a <literal>template1</literal>. This is particularly handy when restoring a
<literal>pg_dump</> dump: the dump script should be restored in a <literal>pg_dump</literal> dump: the dump script should be restored in a
virgin database to ensure that one recreates the correct contents virgin database to ensure that one recreates the correct contents
of the dumped database, without conflicting with objects that of the dumped database, without conflicting with objects that
might have been added to <literal>template1</> later on. might have been added to <literal>template1</literal> later on.
</para> </para>
<para> <para>
Another common reason for copying <literal>template0</> instead Another common reason for copying <literal>template0</literal> instead
of <literal>template1</> is that new encoding and locale settings of <literal>template1</literal> is that new encoding and locale settings
can be specified when copying <literal>template0</>, whereas a copy can be specified when copying <literal>template0</literal>, whereas a copy
of <literal>template1</> must use the same settings it does. of <literal>template1</literal> must use the same settings it does.
This is because <literal>template1</> might contain encoding-specific This is because <literal>template1</literal> might contain encoding-specific
or locale-specific data, while <literal>template0</> is known not to. or locale-specific data, while <literal>template0</literal> is known not to.
</para> </para>
<para> <para>
To create a database by copying <literal>template0</literal>, use: To create a database by copying <literal>template0</literal>, use:
<programlisting> <programlisting>
CREATE DATABASE <replaceable>dbname</> TEMPLATE template0; CREATE DATABASE <replaceable>dbname</replaceable> TEMPLATE template0;
</programlisting> </programlisting>
from the SQL environment, or: from the SQL environment, or:
<programlisting> <programlisting>
createdb -T template0 <replaceable>dbname</> createdb -T template0 <replaceable>dbname</replaceable>
</programlisting> </programlisting>
from the shell. from the shell.
</para> </para>
@ -232,49 +232,49 @@ createdb -T template0 <replaceable>dbname</>
<para> <para>
It is possible to create additional template databases, and indeed It is possible to create additional template databases, and indeed
one can copy any database in a cluster by specifying its name one can copy any database in a cluster by specifying its name
as the template for <command>CREATE DATABASE</>. It is important to as the template for <command>CREATE DATABASE</command>. It is important to
understand, however, that this is not (yet) intended as understand, however, that this is not (yet) intended as
a general-purpose <quote><command>COPY DATABASE</command></quote> facility. a general-purpose <quote><command>COPY DATABASE</command></quote> facility.
The principal limitation is that no other sessions can be connected to The principal limitation is that no other sessions can be connected to
the source database while it is being copied. <command>CREATE the source database while it is being copied. <command>CREATE
DATABASE</> will fail if any other connection exists when it starts; DATABASE</command> will fail if any other connection exists when it starts;
during the copy operation, new connections to the source database during the copy operation, new connections to the source database
are prevented. are prevented.
</para> </para>
<para> <para>
Two useful flags exist in <literal>pg_database</literal><indexterm><primary>pg_database</></> for each Two useful flags exist in <literal>pg_database</literal><indexterm><primary>pg_database</primary></indexterm> for each
database: the columns <literal>datistemplate</literal> and database: the columns <literal>datistemplate</literal> and
<literal>datallowconn</literal>. <literal>datistemplate</literal> <literal>datallowconn</literal>. <literal>datistemplate</literal>
can be set to indicate that a database is intended as a template for can be set to indicate that a database is intended as a template for
<command>CREATE DATABASE</>. If this flag is set, the database can be <command>CREATE DATABASE</command>. If this flag is set, the database can be
cloned by any user with <literal>CREATEDB</> privileges; if it is not set, cloned by any user with <literal>CREATEDB</literal> privileges; if it is not set,
only superusers and the owner of the database can clone it. only superusers and the owner of the database can clone it.
If <literal>datallowconn</literal> is false, then no new connections If <literal>datallowconn</literal> is false, then no new connections
to that database will be allowed (but existing sessions are not terminated to that database will be allowed (but existing sessions are not terminated
simply by setting the flag false). The <literal>template0</literal> simply by setting the flag false). The <literal>template0</literal>
database is normally marked <literal>datallowconn = false</> to prevent its modification. database is normally marked <literal>datallowconn = false</literal> to prevent its modification.
Both <literal>template0</literal> and <literal>template1</literal> Both <literal>template0</literal> and <literal>template1</literal>
should always be marked with <literal>datistemplate = true</>. should always be marked with <literal>datistemplate = true</literal>.
</para> </para>
<note> <note>
<para> <para>
<literal>template1</> and <literal>template0</> do not have any special <literal>template1</literal> and <literal>template0</literal> do not have any special
status beyond the fact that the name <literal>template1</> is the default status beyond the fact that the name <literal>template1</literal> is the default
source database name for <command>CREATE DATABASE</>. source database name for <command>CREATE DATABASE</command>.
For example, one could drop <literal>template1</> and recreate it from For example, one could drop <literal>template1</literal> and recreate it from
<literal>template0</> without any ill effects. This course of action <literal>template0</literal> without any ill effects. This course of action
might be advisable if one has carelessly added a bunch of junk in might be advisable if one has carelessly added a bunch of junk in
<literal>template1</>. (To delete <literal>template1</literal>, <literal>template1</literal>. (To delete <literal>template1</literal>,
it must have <literal>pg_database.datistemplate = false</>.) it must have <literal>pg_database.datistemplate = false</literal>.)
</para> </para>
<para> <para>
The <literal>postgres</> database is also created when a database The <literal>postgres</literal> database is also created when a database
cluster is initialized. This database is meant as a default database for cluster is initialized. This database is meant as a default database for
users and applications to connect to. It is simply a copy of users and applications to connect to. It is simply a copy of
<literal>template1</> and can be dropped and recreated if necessary. <literal>template1</literal> and can be dropped and recreated if necessary.
</para> </para>
</note> </note>
</sect1> </sect1>
@ -284,7 +284,7 @@ createdb -T template0 <replaceable>dbname</>
<para> <para>
Recall from <xref linkend="runtime-config"> that the Recall from <xref linkend="runtime-config"> that the
<productname>PostgreSQL</> server provides a large number of <productname>PostgreSQL</productname> server provides a large number of
run-time configuration variables. You can set database-specific run-time configuration variables. You can set database-specific
default values for many of these settings. default values for many of these settings.
</para> </para>
@ -305,8 +305,8 @@ ALTER DATABASE mydb SET geqo TO off;
session started. session started.
Note that users can still alter this setting during their sessions; it Note that users can still alter this setting during their sessions; it
will only be the default. To undo any such setting, use will only be the default. To undo any such setting, use
<literal>ALTER DATABASE <replaceable>dbname</> RESET <literal>ALTER DATABASE <replaceable>dbname</replaceable> RESET
<replaceable>varname</></literal>. <replaceable>varname</replaceable></literal>.
</para> </para>
</sect1> </sect1>
@ -315,9 +315,9 @@ ALTER DATABASE mydb SET geqo TO off;
<para> <para>
Databases are destroyed with the command Databases are destroyed with the command
<xref linkend="sql-dropdatabase">:<indexterm><primary>DROP DATABASE</></> <xref linkend="sql-dropdatabase">:<indexterm><primary>DROP DATABASE</primary></indexterm>
<synopsis> <synopsis>
DROP DATABASE <replaceable>name</>; DROP DATABASE <replaceable>name</replaceable>;
</synopsis> </synopsis>
Only the owner of the database, or Only the owner of the database, or
a superuser, can drop a database. Dropping a database removes all objects a superuser, can drop a database. Dropping a database removes all objects
@ -329,19 +329,19 @@ DROP DATABASE <replaceable>name</>;
<para> <para>
You cannot execute the <command>DROP DATABASE</command> command You cannot execute the <command>DROP DATABASE</command> command
while connected to the victim database. You can, however, be while connected to the victim database. You can, however, be
connected to any other database, including the <literal>template1</> connected to any other database, including the <literal>template1</literal>
database. database.
<literal>template1</> would be the only option for dropping the last user database of a <literal>template1</literal> would be the only option for dropping the last user database of a
given cluster. given cluster.
</para> </para>
<para> <para>
For convenience, there is also a shell program to drop For convenience, there is also a shell program to drop
databases, <xref linkend="app-dropdb">:<indexterm><primary>dropdb</></> databases, <xref linkend="app-dropdb">:<indexterm><primary>dropdb</primary></indexterm>
<synopsis> <synopsis>
dropdb <replaceable class="parameter">dbname</replaceable> dropdb <replaceable class="parameter">dbname</replaceable>
</synopsis> </synopsis>
(Unlike <command>createdb</>, it is not the default action to drop (Unlike <command>createdb</command>, it is not the default action to drop
the database with the current user name.) the database with the current user name.)
</para> </para>
</sect1> </sect1>
@ -354,7 +354,7 @@ dropdb <replaceable class="parameter">dbname</replaceable>
</indexterm> </indexterm>
<para> <para>
Tablespaces in <productname>PostgreSQL</> allow database administrators to Tablespaces in <productname>PostgreSQL</productname> allow database administrators to
define locations in the file system where the files representing define locations in the file system where the files representing
database objects can be stored. Once created, a tablespace can be referred database objects can be stored. Once created, a tablespace can be referred
to by name when creating database objects. to by name when creating database objects.
@ -362,7 +362,7 @@ dropdb <replaceable class="parameter">dbname</replaceable>
<para> <para>
By using tablespaces, an administrator can control the disk layout By using tablespaces, an administrator can control the disk layout
of a <productname>PostgreSQL</> installation. This is useful in at of a <productname>PostgreSQL</productname> installation. This is useful in at
least two ways. First, if the partition or volume on which the least two ways. First, if the partition or volume on which the
cluster was initialized runs out of space and cannot be extended, cluster was initialized runs out of space and cannot be extended,
a tablespace can be created on a different partition and used a tablespace can be created on a different partition and used
@ -397,12 +397,12 @@ dropdb <replaceable class="parameter">dbname</replaceable>
<para> <para>
To define a tablespace, use the <xref To define a tablespace, use the <xref
linkend="sql-createtablespace"> linkend="sql-createtablespace">
command, for example:<indexterm><primary>CREATE TABLESPACE</></>: command, for example:<indexterm><primary>CREATE TABLESPACE</primary></indexterm>:
<programlisting> <programlisting>
CREATE TABLESPACE fastspace LOCATION '/ssd1/postgresql/data'; CREATE TABLESPACE fastspace LOCATION '/ssd1/postgresql/data';
</programlisting> </programlisting>
The location must be an existing, empty directory that is owned by The location must be an existing, empty directory that is owned by
the <productname>PostgreSQL</> operating system user. All objects subsequently the <productname>PostgreSQL</productname> operating system user. All objects subsequently
created within the tablespace will be stored in files underneath this created within the tablespace will be stored in files underneath this
directory. The location must not be on removable or transient storage, directory. The location must not be on removable or transient storage,
as the cluster might fail to function if the tablespace is missing as the cluster might fail to function if the tablespace is missing
@ -414,7 +414,7 @@ CREATE TABLESPACE fastspace LOCATION '/ssd1/postgresql/data';
There is usually not much point in making more than one There is usually not much point in making more than one
tablespace per logical file system, since you cannot control the location tablespace per logical file system, since you cannot control the location
of individual files within a logical file system. However, of individual files within a logical file system. However,
<productname>PostgreSQL</> does not enforce any such limitation, and <productname>PostgreSQL</productname> does not enforce any such limitation, and
indeed it is not directly aware of the file system boundaries on your indeed it is not directly aware of the file system boundaries on your
system. It just stores files in the directories you tell it to use. system. It just stores files in the directories you tell it to use.
</para> </para>
@ -423,15 +423,15 @@ CREATE TABLESPACE fastspace LOCATION '/ssd1/postgresql/data';
<para> <para>
Creation of the tablespace itself must be done as a database superuser, Creation of the tablespace itself must be done as a database superuser,
but after that you can allow ordinary database users to use it. but after that you can allow ordinary database users to use it.
To do that, grant them the <literal>CREATE</> privilege on it. To do that, grant them the <literal>CREATE</literal> privilege on it.
</para> </para>
<para> <para>
Tables, indexes, and entire databases can be assigned to Tables, indexes, and entire databases can be assigned to
particular tablespaces. To do so, a user with the <literal>CREATE</> particular tablespaces. To do so, a user with the <literal>CREATE</literal>
privilege on a given tablespace must pass the tablespace name as a privilege on a given tablespace must pass the tablespace name as a
parameter to the relevant command. For example, the following creates parameter to the relevant command. For example, the following creates
a table in the tablespace <literal>space1</>: a table in the tablespace <literal>space1</literal>:
<programlisting> <programlisting>
CREATE TABLE foo(i int) TABLESPACE space1; CREATE TABLE foo(i int) TABLESPACE space1;
</programlisting> </programlisting>
@ -443,9 +443,9 @@ CREATE TABLE foo(i int) TABLESPACE space1;
SET default_tablespace = space1; SET default_tablespace = space1;
CREATE TABLE foo(i int); CREATE TABLE foo(i int);
</programlisting> </programlisting>
When <varname>default_tablespace</> is set to anything but an empty When <varname>default_tablespace</varname> is set to anything but an empty
string, it supplies an implicit <literal>TABLESPACE</> clause for string, it supplies an implicit <literal>TABLESPACE</literal> clause for
<command>CREATE TABLE</> and <command>CREATE INDEX</> commands that <command>CREATE TABLE</command> and <command>CREATE INDEX</command> commands that
do not have an explicit one. do not have an explicit one.
</para> </para>
@ -463,9 +463,9 @@ CREATE TABLE foo(i int);
The tablespace associated with a database is used to store the system The tablespace associated with a database is used to store the system
catalogs of that database. Furthermore, it is the default tablespace catalogs of that database. Furthermore, it is the default tablespace
used for tables, indexes, and temporary files created within the database, used for tables, indexes, and temporary files created within the database,
if no <literal>TABLESPACE</> clause is given and no other selection is if no <literal>TABLESPACE</literal> clause is given and no other selection is
specified by <varname>default_tablespace</> or specified by <varname>default_tablespace</varname> or
<varname>temp_tablespaces</> (as appropriate). <varname>temp_tablespaces</varname> (as appropriate).
If a database is created without specifying a tablespace for it, If a database is created without specifying a tablespace for it,
it uses the same tablespace as the template database it is copied from. it uses the same tablespace as the template database it is copied from.
</para> </para>
@ -473,12 +473,12 @@ CREATE TABLE foo(i int);
<para> <para>
Two tablespaces are automatically created when the database cluster Two tablespaces are automatically created when the database cluster
is initialized. The is initialized. The
<literal>pg_global</> tablespace is used for shared system catalogs. The <literal>pg_global</literal> tablespace is used for shared system catalogs. The
<literal>pg_default</> tablespace is the default tablespace of the <literal>pg_default</literal> tablespace is the default tablespace of the
<literal>template1</> and <literal>template0</> databases (and, therefore, <literal>template1</literal> and <literal>template0</literal> databases (and, therefore,
will be the default tablespace for other databases as well, unless will be the default tablespace for other databases as well, unless
overridden by a <literal>TABLESPACE</> clause in <command>CREATE overridden by a <literal>TABLESPACE</literal> clause in <command>CREATE
DATABASE</>). DATABASE</command>).
</para> </para>
<para> <para>
@ -501,25 +501,25 @@ CREATE TABLE foo(i int);
<synopsis> <synopsis>
SELECT spcname FROM pg_tablespace; SELECT spcname FROM pg_tablespace;
</synopsis> </synopsis>
The <xref linkend="app-psql"> program's <literal>\db</> meta-command The <xref linkend="app-psql"> program's <literal>\db</literal> meta-command
is also useful for listing the existing tablespaces. is also useful for listing the existing tablespaces.
</para> </para>
<para> <para>
<productname>PostgreSQL</> makes use of symbolic links <productname>PostgreSQL</productname> makes use of symbolic links
to simplify the implementation of tablespaces. This to simplify the implementation of tablespaces. This
means that tablespaces can be used <emphasis>only</> on systems means that tablespaces can be used <emphasis>only</emphasis> on systems
that support symbolic links. that support symbolic links.
</para> </para>
<para> <para>
The directory <filename>$PGDATA/pg_tblspc</> contains symbolic links that The directory <filename>$PGDATA/pg_tblspc</filename> contains symbolic links that
point to each of the non-built-in tablespaces defined in the cluster. point to each of the non-built-in tablespaces defined in the cluster.
Although not recommended, it is possible to adjust the tablespace Although not recommended, it is possible to adjust the tablespace
layout by hand by redefining these links. Under no circumstances perform layout by hand by redefining these links. Under no circumstances perform
this operation while the server is running. Note that in PostgreSQL 9.1 this operation while the server is running. Note that in PostgreSQL 9.1
and earlier you will also need to update the <structname>pg_tablespace</> and earlier you will also need to update the <structname>pg_tablespace</structname>
catalog with the new locations. (If you do not, <literal>pg_dump</> will catalog with the new locations. (If you do not, <literal>pg_dump</literal> will
continue to output the old tablespace locations.) continue to output the old tablespace locations.)
</para> </para>

File diff suppressed because it is too large Load Diff

View File

@ -279,7 +279,7 @@
The table also shows that PostgreSQL's Repeatable Read implementation The table also shows that PostgreSQL's Repeatable Read implementation
does not allow phantom reads. Stricter behavior is permitted by the does not allow phantom reads. Stricter behavior is permitted by the
SQL standard: the four isolation levels only define which phenomena SQL standard: the four isolation levels only define which phenomena
must not happen, not which phenomena <emphasis>must</> happen. must not happen, not which phenomena <emphasis>must</emphasis> happen.
The behavior of the available isolation levels is detailed in the The behavior of the available isolation levels is detailed in the
following subsections. following subsections.
</para> </para>
@ -317,7 +317,7 @@
<firstterm>Read Committed</firstterm> is the default isolation <firstterm>Read Committed</firstterm> is the default isolation
level in <productname>PostgreSQL</productname>. When a transaction level in <productname>PostgreSQL</productname>. When a transaction
uses this isolation level, a <command>SELECT</command> query uses this isolation level, a <command>SELECT</command> query
(without a <literal>FOR UPDATE/SHARE</> clause) sees only data (without a <literal>FOR UPDATE/SHARE</literal> clause) sees only data
committed before the query began; it never sees either uncommitted committed before the query began; it never sees either uncommitted
data or changes committed during query execution by concurrent data or changes committed during query execution by concurrent
transactions. In effect, a <command>SELECT</command> query sees transactions. In effect, a <command>SELECT</command> query sees
@ -345,7 +345,7 @@
updating the originally found row. If the first updater commits, the updating the originally found row. If the first updater commits, the
second updater will ignore the row if the first updater deleted it, second updater will ignore the row if the first updater deleted it,
otherwise it will attempt to apply its operation to the updated version of otherwise it will attempt to apply its operation to the updated version of
the row. The search condition of the command (the <literal>WHERE</> clause) is the row. The search condition of the command (the <literal>WHERE</literal> clause) is
re-evaluated to see if the updated version of the row still matches the re-evaluated to see if the updated version of the row still matches the
search condition. If so, the second updater proceeds with its operation search condition. If so, the second updater proceeds with its operation
using the updated version of the row. In the case of using the updated version of the row. In the case of
@ -355,19 +355,19 @@
</para> </para>
<para> <para>
<command>INSERT</command> with an <literal>ON CONFLICT DO UPDATE</> clause <command>INSERT</command> with an <literal>ON CONFLICT DO UPDATE</literal> clause
behaves similarly. In Read Committed mode, each row proposed for insertion behaves similarly. In Read Committed mode, each row proposed for insertion
will either insert or update. Unless there are unrelated errors, one of will either insert or update. Unless there are unrelated errors, one of
those two outcomes is guaranteed. If a conflict originates in another those two outcomes is guaranteed. If a conflict originates in another
transaction whose effects are not yet visible to the <command>INSERT transaction whose effects are not yet visible to the <command>INSERT
</command>, the <command>UPDATE</command> clause will affect that row, </command>, the <command>UPDATE</command> clause will affect that row,
even though possibly <emphasis>no</> version of that row is even though possibly <emphasis>no</emphasis> version of that row is
conventionally visible to the command. conventionally visible to the command.
</para> </para>
<para> <para>
<command>INSERT</command> with an <literal>ON CONFLICT DO <command>INSERT</command> with an <literal>ON CONFLICT DO
NOTHING</> clause may have insertion not proceed for a row due to NOTHING</literal> clause may have insertion not proceed for a row due to
the outcome of another transaction whose effects are not visible the outcome of another transaction whose effects are not visible
to the <command>INSERT</command> snapshot. Again, this is only to the <command>INSERT</command> snapshot. Again, this is only
the case in Read Committed mode. the case in Read Committed mode.
@ -416,10 +416,10 @@ COMMIT;
The <command>DELETE</command> will have no effect even though The <command>DELETE</command> will have no effect even though
there is a <literal>website.hits = 10</literal> row before and there is a <literal>website.hits = 10</literal> row before and
after the <command>UPDATE</command>. This occurs because the after the <command>UPDATE</command>. This occurs because the
pre-update row value <literal>9</> is skipped, and when the pre-update row value <literal>9</literal> is skipped, and when the
<command>UPDATE</command> completes and <command>DELETE</command> <command>UPDATE</command> completes and <command>DELETE</command>
obtains a lock, the new row value is no longer <literal>10</> but obtains a lock, the new row value is no longer <literal>10</literal> but
<literal>11</>, which no longer matches the criteria. <literal>11</literal>, which no longer matches the criteria.
</para> </para>
<para> <para>
@ -427,7 +427,7 @@ COMMIT;
that includes all transactions committed up to that instant, that includes all transactions committed up to that instant,
subsequent commands in the same transaction will see the effects subsequent commands in the same transaction will see the effects
of the committed concurrent transaction in any case. The point of the committed concurrent transaction in any case. The point
at issue above is whether or not a <emphasis>single</> command at issue above is whether or not a <emphasis>single</emphasis> command
sees an absolutely consistent view of the database. sees an absolutely consistent view of the database.
</para> </para>
@ -472,9 +472,9 @@ COMMIT;
This level is different from Read Committed in that a query in a This level is different from Read Committed in that a query in a
repeatable read transaction sees a snapshot as of the start of the repeatable read transaction sees a snapshot as of the start of the
first non-transaction-control statement in the first non-transaction-control statement in the
<emphasis>transaction</>, not as of the start <emphasis>transaction</emphasis>, not as of the start
of the current statement within the transaction. Thus, successive of the current statement within the transaction. Thus, successive
<command>SELECT</command> commands within a <emphasis>single</> <command>SELECT</command> commands within a <emphasis>single</emphasis>
transaction see the same data, i.e., they do not see changes made by transaction see the same data, i.e., they do not see changes made by
other transactions that committed after their own transaction started. other transactions that committed after their own transaction started.
</para> </para>
@ -587,7 +587,7 @@ ERROR: could not serialize access due to concurrent update
<para> <para>
As an example, As an example,
consider a table <structname>mytab</>, initially containing: consider a table <structname>mytab</structname>, initially containing:
<screen> <screen>
class | value class | value
-------+------- -------+-------
@ -600,14 +600,14 @@ ERROR: could not serialize access due to concurrent update
<screen> <screen>
SELECT SUM(value) FROM mytab WHERE class = 1; SELECT SUM(value) FROM mytab WHERE class = 1;
</screen> </screen>
and then inserts the result (30) as the <structfield>value</> in a and then inserts the result (30) as the <structfield>value</structfield> in a
new row with <structfield>class</><literal> = 2</>. Concurrently, serializable new row with <structfield>class</structfield><literal> = 2</literal>. Concurrently, serializable
transaction B computes: transaction B computes:
<screen> <screen>
SELECT SUM(value) FROM mytab WHERE class = 2; SELECT SUM(value) FROM mytab WHERE class = 2;
</screen> </screen>
and obtains the result 300, which it inserts in a new row with and obtains the result 300, which it inserts in a new row with
<structfield>class</><literal> = 1</>. Then both transactions try to commit. <structfield>class</structfield><literal> = 1</literal>. Then both transactions try to commit.
If either transaction were running at the Repeatable Read isolation level, If either transaction were running at the Repeatable Read isolation level,
both would be allowed to commit; but since there is no serial order of execution both would be allowed to commit; but since there is no serial order of execution
consistent with the result, using Serializable transactions will allow one consistent with the result, using Serializable transactions will allow one
@ -639,11 +639,11 @@ ERROR: could not serialize access due to read/write dependencies among transact
<para> <para>
To guarantee true serializability <productname>PostgreSQL</productname> To guarantee true serializability <productname>PostgreSQL</productname>
uses <firstterm>predicate locking</>, which means that it keeps locks uses <firstterm>predicate locking</firstterm>, which means that it keeps locks
which allow it to determine when a write would have had an impact on which allow it to determine when a write would have had an impact on
the result of a previous read from a concurrent transaction, had it run the result of a previous read from a concurrent transaction, had it run
first. In <productname>PostgreSQL</productname> these locks do not first. In <productname>PostgreSQL</productname> these locks do not
cause any blocking and therefore can <emphasis>not</> play any part in cause any blocking and therefore can <emphasis>not</emphasis> play any part in
causing a deadlock. They are used to identify and flag dependencies causing a deadlock. They are used to identify and flag dependencies
among concurrent Serializable transactions which in certain combinations among concurrent Serializable transactions which in certain combinations
can lead to serialization anomalies. In contrast, a Read Committed or can lead to serialization anomalies. In contrast, a Read Committed or
@ -659,20 +659,20 @@ ERROR: could not serialize access due to read/write dependencies among transact
other database systems, are based on data actually accessed by a other database systems, are based on data actually accessed by a
transaction. These will show up in the transaction. These will show up in the
<link linkend="view-pg-locks"><structname>pg_locks</structname></link> <link linkend="view-pg-locks"><structname>pg_locks</structname></link>
system view with a <literal>mode</> of <literal>SIReadLock</>. The system view with a <literal>mode</literal> of <literal>SIReadLock</literal>. The
particular locks particular locks
acquired during execution of a query will depend on the plan used by acquired during execution of a query will depend on the plan used by
the query, and multiple finer-grained locks (e.g., tuple locks) may be the query, and multiple finer-grained locks (e.g., tuple locks) may be
combined into fewer coarser-grained locks (e.g., page locks) during the combined into fewer coarser-grained locks (e.g., page locks) during the
course of the transaction to prevent exhaustion of the memory used to course of the transaction to prevent exhaustion of the memory used to
track the locks. A <literal>READ ONLY</> transaction may be able to track the locks. A <literal>READ ONLY</literal> transaction may be able to
release its SIRead locks before completion, if it detects that no release its SIRead locks before completion, if it detects that no
conflicts can still occur which could lead to a serialization anomaly. conflicts can still occur which could lead to a serialization anomaly.
In fact, <literal>READ ONLY</> transactions will often be able to In fact, <literal>READ ONLY</literal> transactions will often be able to
establish that fact at startup and avoid taking any predicate locks. establish that fact at startup and avoid taking any predicate locks.
If you explicitly request a <literal>SERIALIZABLE READ ONLY DEFERRABLE</> If you explicitly request a <literal>SERIALIZABLE READ ONLY DEFERRABLE</literal>
transaction, it will block until it can establish this fact. (This is transaction, it will block until it can establish this fact. (This is
the <emphasis>only</> case where Serializable transactions block but the <emphasis>only</emphasis> case where Serializable transactions block but
Repeatable Read transactions don't.) On the other hand, SIRead locks Repeatable Read transactions don't.) On the other hand, SIRead locks
often need to be kept past transaction commit, until overlapping read often need to be kept past transaction commit, until overlapping read
write transactions complete. write transactions complete.
@ -695,13 +695,13 @@ ERROR: could not serialize access due to read/write dependencies among transact
anomalies. The monitoring of read/write dependencies has a cost, as does anomalies. The monitoring of read/write dependencies has a cost, as does
the restart of transactions which are terminated with a serialization the restart of transactions which are terminated with a serialization
failure, but balanced against the cost and blocking involved in use of failure, but balanced against the cost and blocking involved in use of
explicit locks and <literal>SELECT FOR UPDATE</> or <literal>SELECT FOR explicit locks and <literal>SELECT FOR UPDATE</literal> or <literal>SELECT FOR
SHARE</>, Serializable transactions are the best performance choice SHARE</literal>, Serializable transactions are the best performance choice
for some environments. for some environments.
</para> </para>
<para> <para>
While <productname>PostgreSQL</>'s Serializable transaction isolation While <productname>PostgreSQL</productname>'s Serializable transaction isolation
level only allows concurrent transactions to commit if it can prove there level only allows concurrent transactions to commit if it can prove there
is a serial order of execution that would produce the same effect, it is a serial order of execution that would produce the same effect, it
doesn't always prevent errors from being raised that would not occur in doesn't always prevent errors from being raised that would not occur in
@ -709,7 +709,7 @@ ERROR: could not serialize access due to read/write dependencies among transact
constraint violations caused by conflicts with overlapping Serializable constraint violations caused by conflicts with overlapping Serializable
transactions even after explicitly checking that the key isn't present transactions even after explicitly checking that the key isn't present
before attempting to insert it. This can be avoided by making sure before attempting to insert it. This can be avoided by making sure
that <emphasis>all</> Serializable transactions that insert potentially that <emphasis>all</emphasis> Serializable transactions that insert potentially
conflicting keys explicitly check if they can do so first. For example, conflicting keys explicitly check if they can do so first. For example,
imagine an application that asks the user for a new key and then checks imagine an application that asks the user for a new key and then checks
that it doesn't exist already by trying to select it first, or generates that it doesn't exist already by trying to select it first, or generates
@ -727,7 +727,7 @@ ERROR: could not serialize access due to read/write dependencies among transact
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
Declare transactions as <literal>READ ONLY</> when possible. Declare transactions as <literal>READ ONLY</literal> when possible.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
@ -754,8 +754,8 @@ ERROR: could not serialize access due to read/write dependencies among transact
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
Eliminate explicit locks, <literal>SELECT FOR UPDATE</>, and Eliminate explicit locks, <literal>SELECT FOR UPDATE</literal>, and
<literal>SELECT FOR SHARE</> where no longer needed due to the <literal>SELECT FOR SHARE</literal> where no longer needed due to the
protections automatically provided by Serializable transactions. protections automatically provided by Serializable transactions.
</para> </para>
</listitem> </listitem>
@ -801,7 +801,7 @@ ERROR: could not serialize access due to read/write dependencies among transact
most <productname>PostgreSQL</productname> commands automatically most <productname>PostgreSQL</productname> commands automatically
acquire locks of appropriate modes to ensure that referenced acquire locks of appropriate modes to ensure that referenced
tables are not dropped or modified in incompatible ways while the tables are not dropped or modified in incompatible ways while the
command executes. (For example, <command>TRUNCATE</> cannot safely be command executes. (For example, <command>TRUNCATE</command> cannot safely be
executed concurrently with other operations on the same table, so it executed concurrently with other operations on the same table, so it
obtains an exclusive lock on the table to enforce that.) obtains an exclusive lock on the table to enforce that.)
</para> </para>
@ -860,7 +860,7 @@ ERROR: could not serialize access due to read/write dependencies among transact
<para> <para>
The <command>SELECT</command> command acquires a lock of this mode on The <command>SELECT</command> command acquires a lock of this mode on
referenced tables. In general, any query that only <emphasis>reads</> a table referenced tables. In general, any query that only <emphasis>reads</emphasis> a table
and does not modify it will acquire this lock mode. and does not modify it will acquire this lock mode.
</para> </para>
</listitem> </listitem>
@ -904,7 +904,7 @@ ERROR: could not serialize access due to read/write dependencies among transact
acquire this lock mode on the target table (in addition to acquire this lock mode on the target table (in addition to
<literal>ACCESS SHARE</literal> locks on any other referenced <literal>ACCESS SHARE</literal> locks on any other referenced
tables). In general, this lock mode will be acquired by any tables). In general, this lock mode will be acquired by any
command that <emphasis>modifies data</> in a table. command that <emphasis>modifies data</emphasis> in a table.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -920,13 +920,13 @@ ERROR: could not serialize access due to read/write dependencies among transact
EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
<literal>ACCESS EXCLUSIVE</literal> lock modes. <literal>ACCESS EXCLUSIVE</literal> lock modes.
This mode protects a table against This mode protects a table against
concurrent schema changes and <command>VACUUM</> runs. concurrent schema changes and <command>VACUUM</command> runs.
</para> </para>
<para> <para>
Acquired by <command>VACUUM</command> (without <option>FULL</option>), Acquired by <command>VACUUM</command> (without <option>FULL</option>),
<command>ANALYZE</>, <command>CREATE INDEX CONCURRENTLY</>, <command>ANALYZE</command>, <command>CREATE INDEX CONCURRENTLY</command>,
<command>CREATE STATISTICS</> and <command>CREATE STATISTICS</command> and
<command>ALTER TABLE VALIDATE</command> and other <command>ALTER TABLE VALIDATE</command> and other
<command>ALTER TABLE</command> variants (for full details see <command>ALTER TABLE</command> variants (for full details see
<xref linkend="SQL-ALTERTABLE">). <xref linkend="SQL-ALTERTABLE">).
@ -1016,12 +1016,12 @@ ERROR: could not serialize access due to read/write dependencies among transact
</para> </para>
<para> <para>
Acquired by the <command>DROP TABLE</>, Acquired by the <command>DROP TABLE</command>,
<command>TRUNCATE</command>, <command>REINDEX</command>, <command>TRUNCATE</command>, <command>REINDEX</command>,
<command>CLUSTER</command>, <command>VACUUM FULL</command>, <command>CLUSTER</command>, <command>VACUUM FULL</command>,
and <command>REFRESH MATERIALIZED VIEW</command> (without and <command>REFRESH MATERIALIZED VIEW</command> (without
<option>CONCURRENTLY</option>) <option>CONCURRENTLY</option>)
commands. Many forms of <command>ALTER TABLE</> also acquire commands. Many forms of <command>ALTER TABLE</command> also acquire
a lock at this level. This is also the default lock mode for a lock at this level. This is also the default lock mode for
<command>LOCK TABLE</command> statements that do not specify <command>LOCK TABLE</command> statements that do not specify
a mode explicitly. a mode explicitly.
@ -1042,9 +1042,9 @@ ERROR: could not serialize access due to read/write dependencies among transact
Once acquired, a lock is normally held till end of transaction. But if a Once acquired, a lock is normally held till end of transaction. But if a
lock is acquired after establishing a savepoint, the lock is released lock is acquired after establishing a savepoint, the lock is released
immediately if the savepoint is rolled back to. This is consistent with immediately if the savepoint is rolled back to. This is consistent with
the principle that <command>ROLLBACK</> cancels all effects of the the principle that <command>ROLLBACK</command> cancels all effects of the
commands since the savepoint. The same holds for locks acquired within a commands since the savepoint. The same holds for locks acquired within a
<application>PL/pgSQL</> exception block: an error escape from the block <application>PL/pgSQL</application> exception block: an error escape from the block
releases locks acquired within it. releases locks acquired within it.
</para> </para>
@ -1204,17 +1204,17 @@ ERROR: could not serialize access due to read/write dependencies among transact
concurrent transaction that has run any of those commands on the concurrent transaction that has run any of those commands on the
same row, same row,
and will then lock and return the updated row (or no row, if the and will then lock and return the updated row (or no row, if the
row was deleted). Within a <literal>REPEATABLE READ</> or row was deleted). Within a <literal>REPEATABLE READ</literal> or
<literal>SERIALIZABLE</> transaction, <literal>SERIALIZABLE</literal> transaction,
however, an error will be thrown if a row to be locked has changed however, an error will be thrown if a row to be locked has changed
since the transaction started. For further discussion see since the transaction started. For further discussion see
<xref linkend="applevel-consistency">. <xref linkend="applevel-consistency">.
</para> </para>
<para> <para>
The <literal>FOR UPDATE</> lock mode The <literal>FOR UPDATE</literal> lock mode
is also acquired by any <command>DELETE</> on a row, and also by an is also acquired by any <command>DELETE</command> on a row, and also by an
<command>UPDATE</> that modifies the values on certain columns. Currently, <command>UPDATE</command> that modifies the values on certain columns. Currently,
the set of columns considered for the <command>UPDATE</> case are those that the set of columns considered for the <command>UPDATE</command> case are those that
have a unique index on them that can be used in a foreign key (so partial have a unique index on them that can be used in a foreign key (so partial
indexes and expressional indexes are not considered), but this may change indexes and expressional indexes are not considered), but this may change
in the future. in the future.
@ -1228,11 +1228,11 @@ ERROR: could not serialize access due to read/write dependencies among transact
</term> </term>
<listitem> <listitem>
<para> <para>
Behaves similarly to <literal>FOR UPDATE</>, except that the lock Behaves similarly to <literal>FOR UPDATE</literal>, except that the lock
acquired is weaker: this lock will not block acquired is weaker: this lock will not block
<literal>SELECT FOR KEY SHARE</> commands that attempt to acquire <literal>SELECT FOR KEY SHARE</literal> commands that attempt to acquire
a lock on the same rows. This lock mode is also acquired by any a lock on the same rows. This lock mode is also acquired by any
<command>UPDATE</> that does not acquire a <literal>FOR UPDATE</> lock. <command>UPDATE</command> that does not acquire a <literal>FOR UPDATE</literal> lock.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1243,12 +1243,12 @@ ERROR: could not serialize access due to read/write dependencies among transact
</term> </term>
<listitem> <listitem>
<para> <para>
Behaves similarly to <literal>FOR NO KEY UPDATE</>, except that it Behaves similarly to <literal>FOR NO KEY UPDATE</literal>, except that it
acquires a shared lock rather than exclusive lock on each retrieved acquires a shared lock rather than exclusive lock on each retrieved
row. A shared lock blocks other transactions from performing row. A shared lock blocks other transactions from performing
<command>UPDATE</command>, <command>DELETE</command>, <command>UPDATE</command>, <command>DELETE</command>,
<command>SELECT FOR UPDATE</command> or <command>SELECT FOR UPDATE</command> or
<command>SELECT FOR NO KEY UPDATE</> on these rows, but it does not <command>SELECT FOR NO KEY UPDATE</command> on these rows, but it does not
prevent them from performing <command>SELECT FOR SHARE</command> or prevent them from performing <command>SELECT FOR SHARE</command> or
<command>SELECT FOR KEY SHARE</command>. <command>SELECT FOR KEY SHARE</command>.
</para> </para>
@ -1262,13 +1262,13 @@ ERROR: could not serialize access due to read/write dependencies among transact
<listitem> <listitem>
<para> <para>
Behaves similarly to <literal>FOR SHARE</literal>, except that the Behaves similarly to <literal>FOR SHARE</literal>, except that the
lock is weaker: <literal>SELECT FOR UPDATE</> is blocked, but not lock is weaker: <literal>SELECT FOR UPDATE</literal> is blocked, but not
<literal>SELECT FOR NO KEY UPDATE</>. A key-shared lock blocks <literal>SELECT FOR NO KEY UPDATE</literal>. A key-shared lock blocks
other transactions from performing <command>DELETE</command> or other transactions from performing <command>DELETE</command> or
any <command>UPDATE</command> that changes the key values, but not any <command>UPDATE</command> that changes the key values, but not
other <command>UPDATE</>, and neither does it prevent other <command>UPDATE</command>, and neither does it prevent
<command>SELECT FOR NO KEY UPDATE</>, <command>SELECT FOR SHARE</>, <command>SELECT FOR NO KEY UPDATE</command>, <command>SELECT FOR SHARE</command>,
or <command>SELECT FOR KEY SHARE</>. or <command>SELECT FOR KEY SHARE</command>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1357,7 +1357,7 @@ ERROR: could not serialize access due to read/write dependencies among transact
<para> <para>
The use of explicit locking can increase the likelihood of The use of explicit locking can increase the likelihood of
<firstterm>deadlocks</>, wherein two (or more) transactions each <firstterm>deadlocks</firstterm>, wherein two (or more) transactions each
hold locks that the other wants. For example, if transaction 1 hold locks that the other wants. For example, if transaction 1
acquires an exclusive lock on table A and then tries to acquire acquires an exclusive lock on table A and then tries to acquire
an exclusive lock on table B, while transaction 2 has already an exclusive lock on table B, while transaction 2 has already
@ -1447,12 +1447,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
<para> <para>
<productname>PostgreSQL</productname> provides a means for <productname>PostgreSQL</productname> provides a means for
creating locks that have application-defined meanings. These are creating locks that have application-defined meanings. These are
called <firstterm>advisory locks</>, because the system does not called <firstterm>advisory locks</firstterm>, because the system does not
enforce their use &mdash; it is up to the application to use them enforce their use &mdash; it is up to the application to use them
correctly. Advisory locks can be useful for locking strategies correctly. Advisory locks can be useful for locking strategies
that are an awkward fit for the MVCC model. that are an awkward fit for the MVCC model.
For example, a common use of advisory locks is to emulate pessimistic For example, a common use of advisory locks is to emulate pessimistic
locking strategies typical of so-called <quote>flat file</> data locking strategies typical of so-called <quote>flat file</quote> data
management systems. management systems.
While a flag stored in a table could be used for the same purpose, While a flag stored in a table could be used for the same purpose,
advisory locks are faster, avoid table bloat, and are automatically advisory locks are faster, avoid table bloat, and are automatically
@ -1506,7 +1506,7 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
<para> <para>
In certain cases using advisory locking methods, especially in queries In certain cases using advisory locking methods, especially in queries
involving explicit ordering and <literal>LIMIT</> clauses, care must be involving explicit ordering and <literal>LIMIT</literal> clauses, care must be
taken to control the locks acquired because of the order in which SQL taken to control the locks acquired because of the order in which SQL
expressions are evaluated. For example: expressions are evaluated. For example:
<screen> <screen>
@ -1518,7 +1518,7 @@ SELECT pg_advisory_lock(q.id) FROM
) q; -- ok ) q; -- ok
</screen> </screen>
In the above queries, the second form is dangerous because the In the above queries, the second form is dangerous because the
<literal>LIMIT</> is not guaranteed to be applied before the locking <literal>LIMIT</literal> is not guaranteed to be applied before the locking
function is executed. This might cause some locks to be acquired function is executed. This might cause some locks to be acquired
that the application was not expecting, and hence would fail to release that the application was not expecting, and hence would fail to release
(until it ends the session). (until it ends the session).
@ -1590,7 +1590,7 @@ SELECT pg_advisory_lock(q.id) FROM
for application programmers if the application software goes through a for application programmers if the application software goes through a
framework which automatically retries transactions which are rolled framework which automatically retries transactions which are rolled
back with a serialization failure. It may be a good idea to set back with a serialization failure. It may be a good idea to set
<literal>default_transaction_isolation</> to <literal>serializable</>. <literal>default_transaction_isolation</literal> to <literal>serializable</literal>.
It would also be wise to take some action to ensure that no other It would also be wise to take some action to ensure that no other
transaction isolation level is used, either inadvertently or to transaction isolation level is used, either inadvertently or to
subvert integrity checks, through checks of the transaction isolation subvert integrity checks, through checks of the transaction isolation
@ -1660,7 +1660,7 @@ SELECT pg_advisory_lock(q.id) FROM
includes some but not all post-transaction-start changes. In such cases includes some but not all post-transaction-start changes. In such cases
a careful person might wish to lock all tables needed for the check, a careful person might wish to lock all tables needed for the check,
in order to get an indisputable picture of current reality. A in order to get an indisputable picture of current reality. A
<literal>SHARE</> mode (or higher) lock guarantees that there are no <literal>SHARE</literal> mode (or higher) lock guarantees that there are no
uncommitted changes in the locked table, other than those of the current uncommitted changes in the locked table, other than those of the current
transaction. transaction.
</para> </para>
@ -1675,8 +1675,8 @@ SELECT pg_advisory_lock(q.id) FROM
transaction predates obtaining the lock, it might predate some now-committed transaction predates obtaining the lock, it might predate some now-committed
changes in the table. A repeatable read transaction's snapshot is actually changes in the table. A repeatable read transaction's snapshot is actually
frozen at the start of its first query or data-modification command frozen at the start of its first query or data-modification command
(<literal>SELECT</>, <literal>INSERT</>, (<literal>SELECT</literal>, <literal>INSERT</literal>,
<literal>UPDATE</>, or <literal>DELETE</>), so <literal>UPDATE</literal>, or <literal>DELETE</literal>), so
it is possible to obtain locks explicitly before the snapshot is it is possible to obtain locks explicitly before the snapshot is
frozen. frozen.
</para> </para>

View File

@ -7,12 +7,12 @@
<title>For the Translator</title> <title>For the Translator</title>
<para> <para>
<productname>PostgreSQL</> <productname>PostgreSQL</productname>
programs (server and client) can issue their messages in programs (server and client) can issue their messages in
your favorite language &mdash; if the messages have been translated. your favorite language &mdash; if the messages have been translated.
Creating and maintaining translated message sets needs the help of Creating and maintaining translated message sets needs the help of
people who speak their own language well and want to contribute to people who speak their own language well and want to contribute to
the <productname>PostgreSQL</> effort. You do not have to be a the <productname>PostgreSQL</productname> effort. You do not have to be a
programmer at all programmer at all
to do this. This section explains how to help. to do this. This section explains how to help.
</para> </para>
@ -170,8 +170,8 @@ make init-po
This will create a file This will create a file
<filename><replaceable>progname</replaceable>.pot</filename>. <filename><replaceable>progname</replaceable>.pot</filename>.
(<filename>.pot</filename> to distinguish it from PO files that (<filename>.pot</filename> to distinguish it from PO files that
are <quote>in production</quote>. The <literal>T</> stands for are <quote>in production</quote>. The <literal>T</literal> stands for
<quote>template</>.) <quote>template</quote>.)
Copy this file to Copy this file to
<filename><replaceable>language</replaceable>.po</filename> and <filename><replaceable>language</replaceable>.po</filename> and
edit it. To make it known that the new language is available, edit it. To make it known that the new language is available,
@ -234,7 +234,7 @@ make update-po
<listitem> <listitem>
<para> <para>
If the original is a <function>printf</> format string, the translation If the original is a <function>printf</function> format string, the translation
also needs to be. The translation also needs to have the same also needs to be. The translation also needs to have the same
format specifiers in the same order. Sometimes the natural format specifiers in the same order. Sometimes the natural
rules of the language make this impossible or at least awkward. rules of the language make this impossible or at least awkward.
@ -301,7 +301,7 @@ msgstr "Die Datei %2$s hat %1$u Zeichen."
<para> <para>
This section describes how to implement native language support in a This section describes how to implement native language support in a
program or library that is part of the program or library that is part of the
<productname>PostgreSQL</> distribution. <productname>PostgreSQL</productname> distribution.
Currently, it only applies to C programs. Currently, it only applies to C programs.
</para> </para>
@ -447,7 +447,7 @@ fprintf(stderr, gettext("panic level %d\n"), lvl);
printf("Files were %s.\n", flag ? "copied" : "removed"); printf("Files were %s.\n", flag ? "copied" : "removed");
</programlisting> </programlisting>
The word order within the sentence might be different in other The word order within the sentence might be different in other
languages. Also, even if you remember to call <function>gettext()</> on languages. Also, even if you remember to call <function>gettext()</function> on
each fragment, the fragments might not translate well separately. It's each fragment, the fragments might not translate well separately. It's
better to duplicate a little code so that each message to be better to duplicate a little code so that each message to be
translated is a coherent whole. Only numbers, file names, and translated is a coherent whole. Only numbers, file names, and
@ -481,7 +481,7 @@ printf("number of copied files: %d", n);
<para> <para>
If you really want to construct a properly pluralized message, If you really want to construct a properly pluralized message,
there is support for this, but it's a bit awkward. When generating there is support for this, but it's a bit awkward. When generating
a primary or detail error message in <function>ereport()</>, you can a primary or detail error message in <function>ereport()</function>, you can
write something like this: write something like this:
<programlisting> <programlisting>
errmsg_plural("copied %d file", errmsg_plural("copied %d file",
@ -496,17 +496,17 @@ errmsg_plural("copied %d file",
are formatted per the format string as usual. (Normally, the are formatted per the format string as usual. (Normally, the
pluralization control value will also be one of the values to be pluralization control value will also be one of the values to be
formatted, so it has to be written twice.) In English it only formatted, so it has to be written twice.) In English it only
matters whether <replaceable>n</> is 1 or not 1, but in other matters whether <replaceable>n</replaceable> is 1 or not 1, but in other
languages there can be many different plural forms. The translator languages there can be many different plural forms. The translator
sees the two English forms as a group and has the opportunity to sees the two English forms as a group and has the opportunity to
supply multiple substitute strings, with the appropriate one being supply multiple substitute strings, with the appropriate one being
selected based on the run-time value of <replaceable>n</>. selected based on the run-time value of <replaceable>n</replaceable>.
</para> </para>
<para> <para>
If you need to pluralize a message that isn't going directly to an If you need to pluralize a message that isn't going directly to an
<function>errmsg</> or <function>errdetail</> report, you have to use <function>errmsg</function> or <function>errdetail</function> report, you have to use
the underlying function <function>ngettext</>. See the gettext the underlying function <function>ngettext</function>. See the gettext
documentation. documentation.
</para> </para>
</listitem> </listitem>

View File

@ -7,17 +7,17 @@
The following conventions are used in the synopsis of a command: The following conventions are used in the synopsis of a command:
brackets (<literal>[</literal> and <literal>]</literal>) indicate brackets (<literal>[</literal> and <literal>]</literal>) indicate
optional parts. (In the synopsis of a Tcl command, question marks optional parts. (In the synopsis of a Tcl command, question marks
(<literal>?</>) are used instead, as is usual in Tcl.) Braces (<literal>?</literal>) are used instead, as is usual in Tcl.) Braces
(<literal>{</literal> and <literal>}</literal>) and vertical lines (<literal>{</literal> and <literal>}</literal>) and vertical lines
(<literal>|</literal>) indicate that you must choose one (<literal>|</literal>) indicate that you must choose one
alternative. Dots (<literal>...</>) mean that the preceding element alternative. Dots (<literal>...</literal>) mean that the preceding element
can be repeated. can be repeated.
</para> </para>
<para> <para>
Where it enhances the clarity, SQL commands are preceded by the Where it enhances the clarity, SQL commands are preceded by the
prompt <literal>=&gt;</>, and shell commands are preceded by the prompt <literal>=&gt;</literal>, and shell commands are preceded by the
prompt <literal>$</>. Normally, prompts are not shown, though. prompt <literal>$</literal>. Normally, prompts are not shown, though.
</para> </para>
<para> <para>

View File

@ -27,7 +27,7 @@
<title>Description</title> <title>Description</title>
<para> <para>
<application>oid2name</> is a utility program that helps administrators to <application>oid2name</application> is a utility program that helps administrators to
examine the file structure used by PostgreSQL. To make use of it, you need examine the file structure used by PostgreSQL. To make use of it, you need
to be familiar with the database file structure, which is described in to be familiar with the database file structure, which is described in
<xref linkend="storage">. <xref linkend="storage">.
@ -35,7 +35,7 @@
<note> <note>
<para> <para>
The name <quote>oid2name</> is historical, and is actually rather The name <quote>oid2name</quote> is historical, and is actually rather
misleading, since most of the time when you use it, you will really misleading, since most of the time when you use it, you will really
be concerned with tables' filenode numbers (which are the file names be concerned with tables' filenode numbers (which are the file names
visible in the database directories). Be sure you understand the visible in the database directories). Be sure you understand the
@ -60,8 +60,8 @@
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><option>-f</option> <replaceable>filenode</></term> <term><option>-f</option> <replaceable>filenode</replaceable></term>
<listitem><para>show info for table with filenode <replaceable>filenode</></para></listitem> <listitem><para>show info for table with filenode <replaceable>filenode</replaceable></para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -70,8 +70,8 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>-o</option> <replaceable>oid</></term> <term><option>-o</option> <replaceable>oid</replaceable></term>
<listitem><para>show info for table with OID <replaceable>oid</></para></listitem> <listitem><para>show info for table with OID <replaceable>oid</replaceable></para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -93,13 +93,13 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>-t</option> <replaceable>tablename_pattern</></term> <term><option>-t</option> <replaceable>tablename_pattern</replaceable></term>
<listitem><para>show info for table(s) matching <replaceable>tablename_pattern</></para></listitem> <listitem><para>show info for table(s) matching <replaceable>tablename_pattern</replaceable></para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>-V</></term> <term><option>-V</option></term>
<term><option>--version</></term> <term><option>--version</option></term>
<listitem> <listitem>
<para> <para>
Print the <application>oid2name</application> version and exit. Print the <application>oid2name</application> version and exit.
@ -115,8 +115,8 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>-?</></term> <term><option>-?</option></term>
<term><option>--help</></term> <term><option>--help</option></term>
<listitem> <listitem>
<para> <para>
Show help about <application>oid2name</application> command line Show help about <application>oid2name</application> command line
@ -133,27 +133,27 @@
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><option>-d</option> <replaceable>database</></term> <term><option>-d</option> <replaceable>database</replaceable></term>
<listitem><para>database to connect to</para></listitem> <listitem><para>database to connect to</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>-H</option> <replaceable>host</></term> <term><option>-H</option> <replaceable>host</replaceable></term>
<listitem><para>database server's host</para></listitem> <listitem><para>database server's host</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>-p</option> <replaceable>port</></term> <term><option>-p</option> <replaceable>port</replaceable></term>
<listitem><para>database server's port</para></listitem> <listitem><para>database server's port</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>-U</option> <replaceable>username</></term> <term><option>-U</option> <replaceable>username</replaceable></term>
<listitem><para>user name to connect as</para></listitem> <listitem><para>user name to connect as</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>-P</option> <replaceable>password</></term> <term><option>-P</option> <replaceable>password</replaceable></term>
<listitem><para>password (deprecated &mdash; putting this on the command line <listitem><para>password (deprecated &mdash; putting this on the command line
is a security hazard)</para></listitem> is a security hazard)</para></listitem>
</varlistentry> </varlistentry>
@ -163,27 +163,27 @@
<para> <para>
To display specific tables, select which tables to show by To display specific tables, select which tables to show by
using <option>-o</>, <option>-f</> and/or <option>-t</>. using <option>-o</option>, <option>-f</option> and/or <option>-t</option>.
<option>-o</> takes an OID, <option>-o</option> takes an OID,
<option>-f</> takes a filenode, <option>-f</option> takes a filenode,
and <option>-t</> takes a table name (actually, it's a <literal>LIKE</> and <option>-t</option> takes a table name (actually, it's a <literal>LIKE</literal>
pattern, so you can use things like <literal>foo%</>). pattern, so you can use things like <literal>foo%</literal>).
You can use as many You can use as many
of these options as you like, and the listing will include all objects of these options as you like, and the listing will include all objects
matched by any of the options. But note that these options can only matched by any of the options. But note that these options can only
show objects in the database given by <option>-d</>. show objects in the database given by <option>-d</option>.
</para> </para>
<para> <para>
If you don't give any of <option>-o</>, <option>-f</> or <option>-t</>, If you don't give any of <option>-o</option>, <option>-f</option> or <option>-t</option>,
but do give <option>-d</>, it will list all tables in the database but do give <option>-d</option>, it will list all tables in the database
named by <option>-d</>. In this mode, the <option>-S</> and named by <option>-d</option>. In this mode, the <option>-S</option> and
<option>-i</> options control what gets listed. <option>-i</option> options control what gets listed.
</para> </para>
<para> <para>
If you don't give <option>-d</> either, it will show a listing of database If you don't give <option>-d</option> either, it will show a listing of database
OIDs. Alternatively you can give <option>-s</> to get a tablespace OIDs. Alternatively you can give <option>-s</option> to get a tablespace
listing. listing.
</para> </para>
</refsect1> </refsect1>
@ -192,7 +192,7 @@
<title>Notes</title> <title>Notes</title>
<para> <para>
<application>oid2name</> requires a running database server with <application>oid2name</application> requires a running database server with
non-corrupt system catalogs. It is therefore of only limited use non-corrupt system catalogs. It is therefore of only limited use
for recovering from catastrophic database corruption situations. for recovering from catastrophic database corruption situations.
</para> </para>

View File

@ -8,7 +8,7 @@
</indexterm> </indexterm>
<para> <para>
The <filename>pageinspect</> module provides functions that allow you to The <filename>pageinspect</filename> module provides functions that allow you to
inspect the contents of database pages at a low level, which is useful for inspect the contents of database pages at a low level, which is useful for
debugging purposes. All of these functions may be used only by superusers. debugging purposes. All of these functions may be used only by superusers.
</para> </para>
@ -28,7 +28,7 @@
<listitem> <listitem>
<para> <para>
<function>get_raw_page</function> reads the specified block of the named <function>get_raw_page</function> reads the specified block of the named
relation and returns a copy as a <type>bytea</> value. This allows a relation and returns a copy as a <type>bytea</type> value. This allows a
single time-consistent copy of the block to be obtained. single time-consistent copy of the block to be obtained.
<replaceable>fork</replaceable> should be <literal>'main'</literal> for <replaceable>fork</replaceable> should be <literal>'main'</literal> for
the main data fork, <literal>'fsm'</literal> for the free space map, the main data fork, <literal>'fsm'</literal> for the free space map,
@ -63,7 +63,7 @@
<listitem> <listitem>
<para> <para>
<function>page_header</function> shows fields that are common to all <function>page_header</function> shows fields that are common to all
<productname>PostgreSQL</> heap and index pages. <productname>PostgreSQL</productname> heap and index pages.
</para> </para>
<para> <para>
@ -76,8 +76,8 @@ test=# SELECT * FROM page_header(get_raw_page('pg_class', 0));
0/24A1B50 | 0 | 1 | 232 | 368 | 8192 | 8192 | 4 | 0 0/24A1B50 | 0 | 1 | 232 | 368 | 8192 | 8192 | 4 | 0
</screen> </screen>
The returned columns correspond to the fields in the The returned columns correspond to the fields in the
<structname>PageHeaderData</> struct. <structname>PageHeaderData</structname> struct.
See <filename>src/include/storage/bufpage.h</> for details. See <filename>src/include/storage/bufpage.h</filename> for details.
</para> </para>
<para> <para>
@ -147,8 +147,8 @@ test=# SELECT page_checksum(get_raw_page('pg_class', 0), 0);
<screen> <screen>
test=# SELECT * FROM heap_page_items(get_raw_page('pg_class', 0)); test=# SELECT * FROM heap_page_items(get_raw_page('pg_class', 0));
</screen> </screen>
See <filename>src/include/storage/itemid.h</> and See <filename>src/include/storage/itemid.h</filename> and
<filename>src/include/access/htup_details.h</> for explanations of the fields <filename>src/include/access/htup_details.h</filename> for explanations of the fields
returned. returned.
</para> </para>
</listitem> </listitem>
@ -221,7 +221,7 @@ test=# SELECT * FROM heap_page_item_attrs(get_raw_page('pg_class', 0), 'pg_class
next slot to be returned from the page, is also printed. next slot to be returned from the page, is also printed.
</para> </para>
<para> <para>
See <filename>src/backend/storage/freespace/README</> for more See <filename>src/backend/storage/freespace/README</filename> for more
information on the structure of an FSM page. information on the structure of an FSM page.
</para> </para>
</listitem> </listitem>
@ -315,21 +315,21 @@ test=# SELECT * FROM bt_page_items('pg_cast_oid_index', 1);
7 | (0,7) | 12 | f | f | 29 27 00 00 7 | (0,7) | 12 | f | f | 29 27 00 00
8 | (0,8) | 12 | f | f | 2a 27 00 00 8 | (0,8) | 12 | f | f | 2a 27 00 00
</screen> </screen>
In a B-tree leaf page, <structfield>ctid</> points to a heap tuple. In a B-tree leaf page, <structfield>ctid</structfield> points to a heap tuple.
In an internal page, the block number part of <structfield>ctid</> In an internal page, the block number part of <structfield>ctid</structfield>
points to another page in the index itself, while the offset part points to another page in the index itself, while the offset part
(the second number) is ignored and is usually 1. (the second number) is ignored and is usually 1.
</para> </para>
<para> <para>
Note that the first item on any non-rightmost page (any page with Note that the first item on any non-rightmost page (any page with
a non-zero value in the <structfield>btpo_next</> field) is the a non-zero value in the <structfield>btpo_next</structfield> field) is the
page's <quote>high key</quote>, meaning its <structfield>data</> page's <quote>high key</quote>, meaning its <structfield>data</structfield>
serves as an upper bound on all items appearing on the page, while serves as an upper bound on all items appearing on the page, while
its <structfield>ctid</> field is meaningless. Also, on non-leaf its <structfield>ctid</structfield> field is meaningless. Also, on non-leaf
pages, the first real data item (the first item that is not a high pages, the first real data item (the first item that is not a high
key) is a <quote>minus infinity</quote> item, with no actual value key) is a <quote>minus infinity</quote> item, with no actual value
in its <structfield>data</> field. Such an item does have a valid in its <structfield>data</structfield> field. Such an item does have a valid
downlink in its <structfield>ctid</> field, however. downlink in its <structfield>ctid</structfield> field, however.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -345,7 +345,7 @@ test=# SELECT * FROM bt_page_items('pg_cast_oid_index', 1);
<listitem> <listitem>
<para> <para>
It is also possible to pass a page to <function>bt_page_items</function> It is also possible to pass a page to <function>bt_page_items</function>
as a <type>bytea</> value. A page image obtained as a <type>bytea</type> value. A page image obtained
with <function>get_raw_page</function> should be passed as argument. So with <function>get_raw_page</function> should be passed as argument. So
the last example could also be rewritten like this: the last example could also be rewritten like this:
<screen> <screen>
@ -470,8 +470,8 @@ test=# SELECT * FROM brin_page_items(get_raw_page('brinidx', 5),
139 | 8 | 2 | f | f | f | {177 .. 264} 139 | 8 | 2 | f | f | f | {177 .. 264}
</screen> </screen>
The returned columns correspond to the fields in the The returned columns correspond to the fields in the
<structname>BrinMemTuple</> and <structname>BrinValues</> structs. <structname>BrinMemTuple</structname> and <structname>BrinValues</structname> structs.
See <filename>src/include/access/brin_tuple.h</> for details. See <filename>src/include/access/brin_tuple.h</filename> for details.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -8,7 +8,7 @@
</indexterm> </indexterm>
<para> <para>
<productname>PostgreSQL</> can devise query plans which can leverage <productname>PostgreSQL</productname> can devise query plans which can leverage
multiple CPUs in order to answer queries faster. This feature is known multiple CPUs in order to answer queries faster. This feature is known
as parallel query. Many queries cannot benefit from parallel query, either as parallel query. Many queries cannot benefit from parallel query, either
due to limitations of the current implementation or because there is no due to limitations of the current implementation or because there is no
@ -47,18 +47,18 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
In all cases, the <literal>Gather</literal> or In all cases, the <literal>Gather</literal> or
<literal>Gather Merge</literal> node will have exactly one <literal>Gather Merge</literal> node will have exactly one
child plan, which is the portion of the plan that will be executed in child plan, which is the portion of the plan that will be executed in
parallel. If the <literal>Gather</> or <literal>Gather Merge</> node is parallel. If the <literal>Gather</literal> or <literal>Gather Merge</literal> node is
at the very top of the plan tree, then the entire query will execute in at the very top of the plan tree, then the entire query will execute in
parallel. If it is somewhere else in the plan tree, then only the portion parallel. If it is somewhere else in the plan tree, then only the portion
of the plan below it will run in parallel. In the example above, the of the plan below it will run in parallel. In the example above, the
query accesses only one table, so there is only one plan node other than query accesses only one table, so there is only one plan node other than
the <literal>Gather</> node itself; since that plan node is a child of the the <literal>Gather</literal> node itself; since that plan node is a child of the
<literal>Gather</> node, it will run in parallel. <literal>Gather</literal> node, it will run in parallel.
</para> </para>
<para> <para>
<link linkend="using-explain">Using EXPLAIN</>, you can see the number of <link linkend="using-explain">Using EXPLAIN</link>, you can see the number of
workers chosen by the planner. When the <literal>Gather</> node is reached workers chosen by the planner. When the <literal>Gather</literal> node is reached
during query execution, the process which is implementing the user's during query execution, the process which is implementing the user's
session will request a number of <link linkend="bgworker">background session will request a number of <link linkend="bgworker">background
worker processes</link> equal to the number worker processes</link> equal to the number
@ -72,7 +72,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
no workers at all. The optimal plan may depend on the number of workers no workers at all. The optimal plan may depend on the number of workers
that are available, so this can result in poor query performance. If this that are available, so this can result in poor query performance. If this
occurrence is frequent, consider increasing occurrence is frequent, consider increasing
<varname>max_worker_processes</> and <varname>max_parallel_workers</> <varname>max_worker_processes</varname> and <varname>max_parallel_workers</varname>
so that more workers can be run simultaneously or alternatively reducing so that more workers can be run simultaneously or alternatively reducing
<varname>max_parallel_workers_per_gather</varname> so that the planner <varname>max_parallel_workers_per_gather</varname> so that the planner
requests fewer workers. requests fewer workers.
@ -96,10 +96,10 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
<para> <para>
When the node at the top of the parallel portion of the plan is When the node at the top of the parallel portion of the plan is
<literal>Gather Merge</> rather than <literal>Gather</>, it indicates that <literal>Gather Merge</literal> rather than <literal>Gather</literal>, it indicates that
each process executing the parallel portion of the plan is producing each process executing the parallel portion of the plan is producing
tuples in sorted order, and that the leader is performing an tuples in sorted order, and that the leader is performing an
order-preserving merge. In contrast, <literal>Gather</> reads tuples order-preserving merge. In contrast, <literal>Gather</literal> reads tuples
from the workers in whatever order is convenient, destroying any sort from the workers in whatever order is convenient, destroying any sort
order that may have existed. order that may have existed.
</para> </para>
@ -128,7 +128,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
<listitem> <listitem>
<para> <para>
<xref linkend="guc-dynamic-shared-memory-type"> must be set to a <xref linkend="guc-dynamic-shared-memory-type"> must be set to a
value other than <literal>none</>. Parallel query requires dynamic value other than <literal>none</literal>. Parallel query requires dynamic
shared memory in order to pass data between cooperating processes. shared memory in order to pass data between cooperating processes.
</para> </para>
</listitem> </listitem>
@ -152,8 +152,8 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
The query writes any data or locks any database rows. If a query The query writes any data or locks any database rows. If a query
contains a data-modifying operation either at the top level or within contains a data-modifying operation either at the top level or within
a CTE, no parallel plans for that query will be generated. As an a CTE, no parallel plans for that query will be generated. As an
exception, the commands <literal>CREATE TABLE</>, <literal>SELECT exception, the commands <literal>CREATE TABLE</literal>, <literal>SELECT
INTO</>, and <literal>CREATE MATERIALIZED VIEW</> which create a new INTO</literal>, and <literal>CREATE MATERIALIZED VIEW</literal> which create a new
table and populate it can use a parallel plan. table and populate it can use a parallel plan.
</para> </para>
</listitem> </listitem>
@ -205,8 +205,8 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
Even when parallel query plan is generated for a particular query, there Even when parallel query plan is generated for a particular query, there
are several circumstances under which it will be impossible to execute are several circumstances under which it will be impossible to execute
that plan in parallel at execution time. If this occurs, the leader that plan in parallel at execution time. If this occurs, the leader
will execute the portion of the plan below the <literal>Gather</> will execute the portion of the plan below the <literal>Gather</literal>
node entirely by itself, almost as if the <literal>Gather</> node were node entirely by itself, almost as if the <literal>Gather</literal> node were
not present. This will happen if any of the following conditions are met: not present. This will happen if any of the following conditions are met:
</para> </para>
@ -264,7 +264,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
copy of the output result set, so the query would not run any faster copy of the output result set, so the query would not run any faster
than normal but would produce incorrect results. Instead, the parallel than normal but would produce incorrect results. Instead, the parallel
portion of the plan must be what is known internally to the query portion of the plan must be what is known internally to the query
optimizer as a <firstterm>partial plan</>; that is, it must be constructed optimizer as a <firstterm>partial plan</firstterm>; that is, it must be constructed
so that each process which executes the plan will generate only a so that each process which executes the plan will generate only a
subset of the output rows in such a way that each required output row subset of the output rows in such a way that each required output row
is guaranteed to be generated by exactly one of the cooperating processes. is guaranteed to be generated by exactly one of the cooperating processes.
@ -281,14 +281,14 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
In a <emphasis>parallel sequential scan</>, the table's blocks will In a <emphasis>parallel sequential scan</emphasis>, the table's blocks will
be divided among the cooperating processes. Blocks are handed out one be divided among the cooperating processes. Blocks are handed out one
at a time, so that access to the table remains sequential. at a time, so that access to the table remains sequential.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
In a <emphasis>parallel bitmap heap scan</>, one process is chosen In a <emphasis>parallel bitmap heap scan</emphasis>, one process is chosen
as the leader. That process performs a scan of one or more indexes as the leader. That process performs a scan of one or more indexes
and builds a bitmap indicating which table blocks need to be visited. and builds a bitmap indicating which table blocks need to be visited.
These blocks are then divided among the cooperating processes as in These blocks are then divided among the cooperating processes as in
@ -298,8 +298,8 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
In a <emphasis>parallel index scan</> or <emphasis>parallel index-only In a <emphasis>parallel index scan</emphasis> or <emphasis>parallel index-only
scan</>, the cooperating processes take turns reading data from the scan</emphasis>, the cooperating processes take turns reading data from the
index. Currently, parallel index scans are supported only for index. Currently, parallel index scans are supported only for
btree indexes. Each process will claim a single index block and will btree indexes. Each process will claim a single index block and will
scan and return all tuples referenced by that block; other process can scan and return all tuples referenced by that block; other process can
@ -345,25 +345,25 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
<sect2 id="parallel-aggregation"> <sect2 id="parallel-aggregation">
<title>Parallel Aggregation</title> <title>Parallel Aggregation</title>
<para> <para>
<productname>PostgreSQL</> supports parallel aggregation by aggregating in <productname>PostgreSQL</productname> supports parallel aggregation by aggregating in
two stages. First, each process participating in the parallel portion of two stages. First, each process participating in the parallel portion of
the query performs an aggregation step, producing a partial result for the query performs an aggregation step, producing a partial result for
each group of which that process is aware. This is reflected in the plan each group of which that process is aware. This is reflected in the plan
as a <literal>Partial Aggregate</> node. Second, the partial results are as a <literal>Partial Aggregate</literal> node. Second, the partial results are
transferred to the leader via <literal>Gather</> or <literal>Gather transferred to the leader via <literal>Gather</literal> or <literal>Gather
Merge</>. Finally, the leader re-aggregates the results across all Merge</literal>. Finally, the leader re-aggregates the results across all
workers in order to produce the final result. This is reflected in the workers in order to produce the final result. This is reflected in the
plan as a <literal>Finalize Aggregate</> node. plan as a <literal>Finalize Aggregate</literal> node.
</para> </para>
<para> <para>
Because the <literal>Finalize Aggregate</> node runs on the leader Because the <literal>Finalize Aggregate</literal> node runs on the leader
process, queries which produce a relatively large number of groups in process, queries which produce a relatively large number of groups in
comparison to the number of input rows will appear less favorable to the comparison to the number of input rows will appear less favorable to the
query planner. For example, in the worst-case scenario the number of query planner. For example, in the worst-case scenario the number of
groups seen by the <literal>Finalize Aggregate</> node could be as many as groups seen by the <literal>Finalize Aggregate</literal> node could be as many as
the number of input rows which were seen by all worker processes in the the number of input rows which were seen by all worker processes in the
<literal>Partial Aggregate</> stage. For such cases, there is clearly <literal>Partial Aggregate</literal> stage. For such cases, there is clearly
going to be no performance benefit to using parallel aggregation. The going to be no performance benefit to using parallel aggregation. The
query planner takes this into account during the planning process and is query planner takes this into account during the planning process and is
unlikely to choose parallel aggregate in this scenario. unlikely to choose parallel aggregate in this scenario.
@ -371,14 +371,14 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
<para> <para>
Parallel aggregation is not supported in all situations. Each aggregate Parallel aggregation is not supported in all situations. Each aggregate
must be <link linkend="parallel-safety">safe</> for parallelism and must must be <link linkend="parallel-safety">safe</link> for parallelism and must
have a combine function. If the aggregate has a transition state of type have a combine function. If the aggregate has a transition state of type
<literal>internal</>, it must have serialization and deserialization <literal>internal</literal>, it must have serialization and deserialization
functions. See <xref linkend="sql-createaggregate"> for more details. functions. See <xref linkend="sql-createaggregate"> for more details.
Parallel aggregation is not supported if any aggregate function call Parallel aggregation is not supported if any aggregate function call
contains <literal>DISTINCT</> or <literal>ORDER BY</> clause and is also contains <literal>DISTINCT</literal> or <literal>ORDER BY</literal> clause and is also
not supported for ordered set aggregates or when the query involves not supported for ordered set aggregates or when the query involves
<literal>GROUPING SETS</>. It can only be used when all joins involved in <literal>GROUPING SETS</literal>. It can only be used when all joins involved in
the query are also part of the parallel portion of the plan. the query are also part of the parallel portion of the plan.
</para> </para>
@ -417,13 +417,13 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
<para> <para>
The planner classifies operations involved in a query as either The planner classifies operations involved in a query as either
<firstterm>parallel safe</>, <firstterm>parallel restricted</>, <firstterm>parallel safe</firstterm>, <firstterm>parallel restricted</firstterm>,
or <firstterm>parallel unsafe</>. A parallel safe operation is one which or <firstterm>parallel unsafe</firstterm>. A parallel safe operation is one which
does not conflict with the use of parallel query. A parallel restricted does not conflict with the use of parallel query. A parallel restricted
operation is one which cannot be performed in a parallel worker, but which operation is one which cannot be performed in a parallel worker, but which
can be performed in the leader while parallel query is in use. Therefore, can be performed in the leader while parallel query is in use. Therefore,
parallel restricted operations can never occur below a <literal>Gather</> parallel restricted operations can never occur below a <literal>Gather</literal>
or <literal>Gather Merge</> node, but can occur elsewhere in a plan which or <literal>Gather Merge</literal> node, but can occur elsewhere in a plan which
contains such a node. A parallel unsafe operation is one which cannot contains such a node. A parallel unsafe operation is one which cannot
be performed while parallel query is in use, not even in the leader. be performed while parallel query is in use, not even in the leader.
When a query contains anything which is parallel unsafe, parallel query When a query contains anything which is parallel unsafe, parallel query
@ -450,13 +450,13 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
<listitem> <listitem>
<para> <para>
Scans of foreign tables, unless the foreign data wrapper has Scans of foreign tables, unless the foreign data wrapper has
an <literal>IsForeignScanParallelSafe</> API which indicates otherwise. an <literal>IsForeignScanParallelSafe</literal> API which indicates otherwise.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
Access to an <literal>InitPlan</> or correlated <literal>SubPlan</>. Access to an <literal>InitPlan</literal> or correlated <literal>SubPlan</literal>.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
@ -475,23 +475,23 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
be parallel unsafe unless otherwise marked. When using be parallel unsafe unless otherwise marked. When using
<xref linkend="sql-createfunction"> or <xref linkend="sql-createfunction"> or
<xref linkend="sql-alterfunction">, markings can be set by specifying <xref linkend="sql-alterfunction">, markings can be set by specifying
<literal>PARALLEL SAFE</>, <literal>PARALLEL RESTRICTED</>, or <literal>PARALLEL SAFE</literal>, <literal>PARALLEL RESTRICTED</literal>, or
<literal>PARALLEL UNSAFE</> as appropriate. When using <literal>PARALLEL UNSAFE</literal> as appropriate. When using
<xref linkend="sql-createaggregate">, the <xref linkend="sql-createaggregate">, the
<literal>PARALLEL</> option can be specified with <literal>SAFE</>, <literal>PARALLEL</literal> option can be specified with <literal>SAFE</literal>,
<literal>RESTRICTED</>, or <literal>UNSAFE</> as the corresponding value. <literal>RESTRICTED</literal>, or <literal>UNSAFE</literal> as the corresponding value.
</para> </para>
<para> <para>
Functions and aggregates must be marked <literal>PARALLEL UNSAFE</> if Functions and aggregates must be marked <literal>PARALLEL UNSAFE</literal> if
they write to the database, access sequences, change the transaction state they write to the database, access sequences, change the transaction state
even temporarily (e.g. a PL/pgSQL function which establishes an even temporarily (e.g. a PL/pgSQL function which establishes an
<literal>EXCEPTION</> block to catch errors), or make persistent changes to <literal>EXCEPTION</literal> block to catch errors), or make persistent changes to
settings. Similarly, functions must be marked <literal>PARALLEL settings. Similarly, functions must be marked <literal>PARALLEL
RESTRICTED</> if they access temporary tables, client connection state, RESTRICTED</literal> if they access temporary tables, client connection state,
cursors, prepared statements, or miscellaneous backend-local state which cursors, prepared statements, or miscellaneous backend-local state which
the system cannot synchronize across workers. For example, the system cannot synchronize across workers. For example,
<literal>setseed</> and <literal>random</> are parallel restricted for <literal>setseed</literal> and <literal>random</literal> are parallel restricted for
this last reason. this last reason.
</para> </para>
@ -503,7 +503,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
mislabeled, since there is no way for the system to protect itself against mislabeled, since there is no way for the system to protect itself against
arbitrary C code, but in most likely cases the result will be no worse than arbitrary C code, but in most likely cases the result will be no worse than
for any other function. If in doubt, it is probably best to label functions for any other function. If in doubt, it is probably best to label functions
as <literal>UNSAFE</>. as <literal>UNSAFE</literal>.
</para> </para>
<para> <para>
@ -519,13 +519,13 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
<para> <para>
Note that the query planner does not consider deferring the evaluation of Note that the query planner does not consider deferring the evaluation of
parallel-restricted functions or aggregates involved in the query in parallel-restricted functions or aggregates involved in the query in
order to obtain a superior plan. So, for example, if a <literal>WHERE</> order to obtain a superior plan. So, for example, if a <literal>WHERE</literal>
clause applied to a particular table is parallel restricted, the query clause applied to a particular table is parallel restricted, the query
planner will not consider performing a scan of that table in the parallel planner will not consider performing a scan of that table in the parallel
portion of a plan. In some cases, it would be portion of a plan. In some cases, it would be
possible (and perhaps even efficient) to include the scan of that table in possible (and perhaps even efficient) to include the scan of that table in
the parallel portion of the query and defer the evaluation of the the parallel portion of the query and defer the evaluation of the
<literal>WHERE</> clause so that it happens above the <literal>Gather</> <literal>WHERE</literal> clause so that it happens above the <literal>Gather</literal>
node. However, the planner does not do this. node. However, the planner does not do this.
</para> </para>

View File

@ -30,7 +30,7 @@
plan</firstterm> for each query it receives. Choosing the right plan</firstterm> for each query it receives. Choosing the right
plan to match the query structure and the properties of the data plan to match the query structure and the properties of the data
is absolutely critical for good performance, so the system includes is absolutely critical for good performance, so the system includes
a complex <firstterm>planner</> that tries to choose good plans. a complex <firstterm>planner</firstterm> that tries to choose good plans.
You can use the <xref linkend="sql-explain"> command You can use the <xref linkend="sql-explain"> command
to see what query plan the planner creates for any query. to see what query plan the planner creates for any query.
Plan-reading is an art that requires some experience to master, Plan-reading is an art that requires some experience to master,
@ -39,17 +39,17 @@
<para> <para>
Examples in this section are drawn from the regression test database Examples in this section are drawn from the regression test database
after doing a <command>VACUUM ANALYZE</>, using 9.3 development sources. after doing a <command>VACUUM ANALYZE</command>, using 9.3 development sources.
You should be able to get similar results if you try the examples You should be able to get similar results if you try the examples
yourself, but your estimated costs and row counts might vary slightly yourself, but your estimated costs and row counts might vary slightly
because <command>ANALYZE</>'s statistics are random samples rather because <command>ANALYZE</command>'s statistics are random samples rather
than exact, and because costs are inherently somewhat platform-dependent. than exact, and because costs are inherently somewhat platform-dependent.
</para> </para>
<para> <para>
The examples use <command>EXPLAIN</>'s default <quote>text</> output The examples use <command>EXPLAIN</command>'s default <quote>text</quote> output
format, which is compact and convenient for humans to read. format, which is compact and convenient for humans to read.
If you want to feed <command>EXPLAIN</>'s output to a program for further If you want to feed <command>EXPLAIN</command>'s output to a program for further
analysis, you should use one of its machine-readable output formats analysis, you should use one of its machine-readable output formats
(XML, JSON, or YAML) instead. (XML, JSON, or YAML) instead.
</para> </para>
@ -58,12 +58,12 @@
<title><command>EXPLAIN</command> Basics</title> <title><command>EXPLAIN</command> Basics</title>
<para> <para>
The structure of a query plan is a tree of <firstterm>plan nodes</>. The structure of a query plan is a tree of <firstterm>plan nodes</firstterm>.
Nodes at the bottom level of the tree are scan nodes: they return raw rows Nodes at the bottom level of the tree are scan nodes: they return raw rows
from a table. There are different types of scan nodes for different from a table. There are different types of scan nodes for different
table access methods: sequential scans, index scans, and bitmap index table access methods: sequential scans, index scans, and bitmap index
scans. There are also non-table row sources, such as <literal>VALUES</> scans. There are also non-table row sources, such as <literal>VALUES</literal>
clauses and set-returning functions in <literal>FROM</>, which have their clauses and set-returning functions in <literal>FROM</literal>, which have their
own scan node types. own scan node types.
If the query requires joining, aggregation, sorting, or other If the query requires joining, aggregation, sorting, or other
operations on the raw rows, then there will be additional nodes operations on the raw rows, then there will be additional nodes
@ -93,7 +93,7 @@ EXPLAIN SELECT * FROM tenk1;
</para> </para>
<para> <para>
Since this query has no <literal>WHERE</> clause, it must scan all the Since this query has no <literal>WHERE</literal> clause, it must scan all the
rows of the table, so the planner has chosen to use a simple sequential rows of the table, so the planner has chosen to use a simple sequential
scan plan. The numbers that are quoted in parentheses are (left scan plan. The numbers that are quoted in parentheses are (left
to right): to right):
@ -111,7 +111,7 @@ EXPLAIN SELECT * FROM tenk1;
Estimated total cost. This is stated on the assumption that the plan Estimated total cost. This is stated on the assumption that the plan
node is run to completion, i.e., all available rows are retrieved. node is run to completion, i.e., all available rows are retrieved.
In practice a node's parent node might stop short of reading all In practice a node's parent node might stop short of reading all
available rows (see the <literal>LIMIT</> example below). available rows (see the <literal>LIMIT</literal> example below).
</para> </para>
</listitem> </listitem>
@ -135,7 +135,7 @@ EXPLAIN SELECT * FROM tenk1;
cost parameters (see <xref linkend="runtime-config-query-constants">). cost parameters (see <xref linkend="runtime-config-query-constants">).
Traditional practice is to measure the costs in units of disk page Traditional practice is to measure the costs in units of disk page
fetches; that is, <xref linkend="guc-seq-page-cost"> is conventionally fetches; that is, <xref linkend="guc-seq-page-cost"> is conventionally
set to <literal>1.0</> and the other cost parameters are set relative set to <literal>1.0</literal> and the other cost parameters are set relative
to that. The examples in this section are run with the default cost to that. The examples in this section are run with the default cost
parameters. parameters.
</para> </para>
@ -152,11 +152,11 @@ EXPLAIN SELECT * FROM tenk1;
</para> </para>
<para> <para>
The <literal>rows</> value is a little tricky because it is The <literal>rows</literal> value is a little tricky because it is
not the number of rows processed or scanned by the not the number of rows processed or scanned by the
plan node, but rather the number emitted by the node. This is often plan node, but rather the number emitted by the node. This is often
less than the number scanned, as a result of filtering by any less than the number scanned, as a result of filtering by any
<literal>WHERE</>-clause conditions that are being applied at the node. <literal>WHERE</literal>-clause conditions that are being applied at the node.
Ideally the top-level rows estimate will approximate the number of rows Ideally the top-level rows estimate will approximate the number of rows
actually returned, updated, or deleted by the query. actually returned, updated, or deleted by the query.
</para> </para>
@ -184,12 +184,12 @@ SELECT relpages, reltuples FROM pg_class WHERE relname = 'tenk1';
pages and 10000 rows. The estimated cost is computed as (disk pages read * pages and 10000 rows. The estimated cost is computed as (disk pages read *
<xref linkend="guc-seq-page-cost">) + (rows scanned * <xref linkend="guc-seq-page-cost">) + (rows scanned *
<xref linkend="guc-cpu-tuple-cost">). By default, <xref linkend="guc-cpu-tuple-cost">). By default,
<varname>seq_page_cost</> is 1.0 and <varname>cpu_tuple_cost</> is 0.01, <varname>seq_page_cost</varname> is 1.0 and <varname>cpu_tuple_cost</varname> is 0.01,
so the estimated cost is (358 * 1.0) + (10000 * 0.01) = 458. so the estimated cost is (358 * 1.0) + (10000 * 0.01) = 458.
</para> </para>
<para> <para>
Now let's modify the query to add a <literal>WHERE</> condition: Now let's modify the query to add a <literal>WHERE</literal> condition:
<screen> <screen>
EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 7000; EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 7000;
@ -200,21 +200,21 @@ EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 7000;
Filter: (unique1 &lt; 7000) Filter: (unique1 &lt; 7000)
</screen> </screen>
Notice that the <command>EXPLAIN</> output shows the <literal>WHERE</> Notice that the <command>EXPLAIN</command> output shows the <literal>WHERE</literal>
clause being applied as a <quote>filter</> condition attached to the Seq clause being applied as a <quote>filter</quote> condition attached to the Seq
Scan plan node. This means that Scan plan node. This means that
the plan node checks the condition for each row it scans, and outputs the plan node checks the condition for each row it scans, and outputs
only the ones that pass the condition. only the ones that pass the condition.
The estimate of output rows has been reduced because of the The estimate of output rows has been reduced because of the
<literal>WHERE</> clause. <literal>WHERE</literal> clause.
However, the scan will still have to visit all 10000 rows, so the cost However, the scan will still have to visit all 10000 rows, so the cost
hasn't decreased; in fact it has gone up a bit (by 10000 * <xref hasn't decreased; in fact it has gone up a bit (by 10000 * <xref
linkend="guc-cpu-operator-cost">, to be exact) to reflect the extra CPU linkend="guc-cpu-operator-cost">, to be exact) to reflect the extra CPU
time spent checking the <literal>WHERE</> condition. time spent checking the <literal>WHERE</literal> condition.
</para> </para>
<para> <para>
The actual number of rows this query would select is 7000, but the <literal>rows</> The actual number of rows this query would select is 7000, but the <literal>rows</literal>
estimate is only approximate. If you try to duplicate this experiment, estimate is only approximate. If you try to duplicate this experiment,
you will probably get a slightly different estimate; moreover, it can you will probably get a slightly different estimate; moreover, it can
change after each <command>ANALYZE</command> command, because the change after each <command>ANALYZE</command> command, because the
@ -245,12 +245,12 @@ EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 100;
scan. (The reason for using two plan levels is that the upper plan scan. (The reason for using two plan levels is that the upper plan
node sorts the row locations identified by the index into physical order node sorts the row locations identified by the index into physical order
before reading them, to minimize the cost of separate fetches. before reading them, to minimize the cost of separate fetches.
The <quote>bitmap</> mentioned in the node names is the mechanism that The <quote>bitmap</quote> mentioned in the node names is the mechanism that
does the sorting.) does the sorting.)
</para> </para>
<para> <para>
Now let's add another condition to the <literal>WHERE</> clause: Now let's add another condition to the <literal>WHERE</literal> clause:
<screen> <screen>
EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND stringu1 = 'xxx'; EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND stringu1 = 'xxx';
@ -266,15 +266,15 @@ EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND stringu1 = 'xxx';
The added condition <literal>stringu1 = 'xxx'</literal> reduces the The added condition <literal>stringu1 = 'xxx'</literal> reduces the
output row count estimate, but not the cost because we still have to visit output row count estimate, but not the cost because we still have to visit
the same set of rows. Notice that the <literal>stringu1</> clause the same set of rows. Notice that the <literal>stringu1</literal> clause
cannot be applied as an index condition, since this index is only on cannot be applied as an index condition, since this index is only on
the <literal>unique1</> column. Instead it is applied as a filter on the <literal>unique1</literal> column. Instead it is applied as a filter on
the rows retrieved by the index. Thus the cost has actually gone up the rows retrieved by the index. Thus the cost has actually gone up
slightly to reflect this extra checking. slightly to reflect this extra checking.
</para> </para>
<para> <para>
In some cases the planner will prefer a <quote>simple</> index scan plan: In some cases the planner will prefer a <quote>simple</quote> index scan plan:
<screen> <screen>
EXPLAIN SELECT * FROM tenk1 WHERE unique1 = 42; EXPLAIN SELECT * FROM tenk1 WHERE unique1 = 42;
@ -289,14 +289,14 @@ EXPLAIN SELECT * FROM tenk1 WHERE unique1 = 42;
makes them even more expensive to read, but there are so few that the makes them even more expensive to read, but there are so few that the
extra cost of sorting the row locations is not worth it. You'll most extra cost of sorting the row locations is not worth it. You'll most
often see this plan type for queries that fetch just a single row. It's often see this plan type for queries that fetch just a single row. It's
also often used for queries that have an <literal>ORDER BY</> condition also often used for queries that have an <literal>ORDER BY</literal> condition
that matches the index order, because then no extra sorting step is needed that matches the index order, because then no extra sorting step is needed
to satisfy the <literal>ORDER BY</>. to satisfy the <literal>ORDER BY</literal>.
</para> </para>
<para> <para>
If there are separate indexes on several of the columns referenced If there are separate indexes on several of the columns referenced
in <literal>WHERE</>, the planner might choose to use an AND or OR in <literal>WHERE</literal>, the planner might choose to use an AND or OR
combination of the indexes: combination of the indexes:
<screen> <screen>
@ -320,7 +320,7 @@ EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000;
</para> </para>
<para> <para>
Here is an example showing the effects of <literal>LIMIT</>: Here is an example showing the effects of <literal>LIMIT</literal>:
<screen> <screen>
EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000 LIMIT 2; EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000 LIMIT 2;
@ -335,7 +335,7 @@ EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000 LIMIT 2
</para> </para>
<para> <para>
This is the same query as above, but we added a <literal>LIMIT</> so that This is the same query as above, but we added a <literal>LIMIT</literal> so that
not all the rows need be retrieved, and the planner changed its mind about not all the rows need be retrieved, and the planner changed its mind about
what to do. Notice that the total cost and row count of the Index Scan what to do. Notice that the total cost and row count of the Index Scan
node are shown as if it were run to completion. However, the Limit node node are shown as if it were run to completion. However, the Limit node
@ -370,23 +370,23 @@ WHERE t1.unique1 &lt; 10 AND t1.unique2 = t2.unique2;
<para> <para>
In this plan, we have a nested-loop join node with two table scans as In this plan, we have a nested-loop join node with two table scans as
inputs, or children. The indentation of the node summary lines reflects inputs, or children. The indentation of the node summary lines reflects
the plan tree structure. The join's first, or <quote>outer</>, child the plan tree structure. The join's first, or <quote>outer</quote>, child
is a bitmap scan similar to those we saw before. Its cost and row count is a bitmap scan similar to those we saw before. Its cost and row count
are the same as we'd get from <literal>SELECT ... WHERE unique1 &lt; 10</> are the same as we'd get from <literal>SELECT ... WHERE unique1 &lt; 10</literal>
because we are because we are
applying the <literal>WHERE</> clause <literal>unique1 &lt; 10</literal> applying the <literal>WHERE</literal> clause <literal>unique1 &lt; 10</literal>
at that node. at that node.
The <literal>t1.unique2 = t2.unique2</literal> clause is not relevant yet, The <literal>t1.unique2 = t2.unique2</literal> clause is not relevant yet,
so it doesn't affect the row count of the outer scan. The nested-loop so it doesn't affect the row count of the outer scan. The nested-loop
join node will run its second, join node will run its second,
or <quote>inner</> child once for each row obtained from the outer child. or <quote>inner</quote> child once for each row obtained from the outer child.
Column values from the current outer row can be plugged into the inner Column values from the current outer row can be plugged into the inner
scan; here, the <literal>t1.unique2</> value from the outer row is available, scan; here, the <literal>t1.unique2</literal> value from the outer row is available,
so we get a plan and costs similar to what we saw above for a simple so we get a plan and costs similar to what we saw above for a simple
<literal>SELECT ... WHERE t2.unique2 = <replaceable>constant</></> case. <literal>SELECT ... WHERE t2.unique2 = <replaceable>constant</replaceable></literal> case.
(The estimated cost is actually a bit lower than what was seen above, (The estimated cost is actually a bit lower than what was seen above,
as a result of caching that's expected to occur during the repeated as a result of caching that's expected to occur during the repeated
index scans on <literal>t2</>.) The index scans on <literal>t2</literal>.) The
costs of the loop node are then set on the basis of the cost of the outer costs of the loop node are then set on the basis of the cost of the outer
scan, plus one repetition of the inner scan for each outer row (10 * 7.87, scan, plus one repetition of the inner scan for each outer row (10 * 7.87,
here), plus a little CPU time for join processing. here), plus a little CPU time for join processing.
@ -395,7 +395,7 @@ WHERE t1.unique1 &lt; 10 AND t1.unique2 = t2.unique2;
<para> <para>
In this example the join's output row count is the same as the product In this example the join's output row count is the same as the product
of the two scans' row counts, but that's not true in all cases because of the two scans' row counts, but that's not true in all cases because
there can be additional <literal>WHERE</> clauses that mention both tables there can be additional <literal>WHERE</literal> clauses that mention both tables
and so can only be applied at the join point, not to either input scan. and so can only be applied at the join point, not to either input scan.
Here's an example: Here's an example:
@ -418,15 +418,15 @@ WHERE t1.unique1 &lt; 10 AND t2.unique2 &lt; 10 AND t1.hundred &lt; t2.hundred;
</screen> </screen>
The condition <literal>t1.hundred &lt; t2.hundred</literal> can't be The condition <literal>t1.hundred &lt; t2.hundred</literal> can't be
tested in the <literal>tenk2_unique2</> index, so it's applied at the tested in the <literal>tenk2_unique2</literal> index, so it's applied at the
join node. This reduces the estimated output row count of the join node, join node. This reduces the estimated output row count of the join node,
but does not change either input scan. but does not change either input scan.
</para> </para>
<para> <para>
Notice that here the planner has chosen to <quote>materialize</> the inner Notice that here the planner has chosen to <quote>materialize</quote> the inner
relation of the join, by putting a Materialize plan node atop it. This relation of the join, by putting a Materialize plan node atop it. This
means that the <literal>t2</> index scan will be done just once, even means that the <literal>t2</literal> index scan will be done just once, even
though the nested-loop join node needs to read that data ten times, once though the nested-loop join node needs to read that data ten times, once
for each row from the outer relation. The Materialize node saves the data for each row from the outer relation. The Materialize node saves the data
in memory as it's read, and then returns the data from memory on each in memory as it's read, and then returns the data from memory on each
@ -435,8 +435,8 @@ WHERE t1.unique1 &lt; 10 AND t2.unique2 &lt; 10 AND t1.hundred &lt; t2.hundred;
<para> <para>
When dealing with outer joins, you might see join plan nodes with both When dealing with outer joins, you might see join plan nodes with both
<quote>Join Filter</> and plain <quote>Filter</> conditions attached. <quote>Join Filter</quote> and plain <quote>Filter</quote> conditions attached.
Join Filter conditions come from the outer join's <literal>ON</> clause, Join Filter conditions come from the outer join's <literal>ON</literal> clause,
so a row that fails the Join Filter condition could still get emitted as so a row that fails the Join Filter condition could still get emitted as
a null-extended row. But a plain Filter condition is applied after the a null-extended row. But a plain Filter condition is applied after the
outer-join rules and so acts to remove rows unconditionally. In an inner outer-join rules and so acts to remove rows unconditionally. In an inner
@ -470,7 +470,7 @@ WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2;
table are entered into an in-memory hash table, after which the other table are entered into an in-memory hash table, after which the other
table is scanned and the hash table is probed for matches to each row. table is scanned and the hash table is probed for matches to each row.
Again note how the indentation reflects the plan structure: the bitmap Again note how the indentation reflects the plan structure: the bitmap
scan on <literal>tenk1</> is the input to the Hash node, which constructs scan on <literal>tenk1</literal> is the input to the Hash node, which constructs
the hash table. That's then returned to the Hash Join node, which reads the hash table. That's then returned to the Hash Join node, which reads
rows from its outer child plan and searches the hash table for each one. rows from its outer child plan and searches the hash table for each one.
</para> </para>
@ -497,9 +497,9 @@ WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2;
<para> <para>
Merge join requires its input data to be sorted on the join keys. In this Merge join requires its input data to be sorted on the join keys. In this
plan the <literal>tenk1</> data is sorted by using an index scan to visit plan the <literal>tenk1</literal> data is sorted by using an index scan to visit
the rows in the correct order, but a sequential scan and sort is preferred the rows in the correct order, but a sequential scan and sort is preferred
for <literal>onek</>, because there are many more rows to be visited in for <literal>onek</literal>, because there are many more rows to be visited in
that table. that table.
(Sequential-scan-and-sort frequently beats an index scan for sorting many rows, (Sequential-scan-and-sort frequently beats an index scan for sorting many rows,
because of the nonsequential disk access required by the index scan.) because of the nonsequential disk access required by the index scan.)
@ -512,7 +512,7 @@ WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2;
(This is a crude tool, but useful. See (This is a crude tool, but useful. See
also <xref linkend="explicit-joins">.) also <xref linkend="explicit-joins">.)
For example, if we're unconvinced that sequential-scan-and-sort is the best way to For example, if we're unconvinced that sequential-scan-and-sort is the best way to
deal with table <literal>onek</> in the previous example, we could try deal with table <literal>onek</literal> in the previous example, we could try
<screen> <screen>
SET enable_sort = off; SET enable_sort = off;
@ -530,10 +530,10 @@ WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2;
-&gt; Index Scan using onek_unique2 on onek t2 (cost=0.28..224.79 rows=1000 width=244) -&gt; Index Scan using onek_unique2 on onek t2 (cost=0.28..224.79 rows=1000 width=244)
</screen> </screen>
which shows that the planner thinks that sorting <literal>onek</> by which shows that the planner thinks that sorting <literal>onek</literal> by
index-scanning is about 12% more expensive than sequential-scan-and-sort. index-scanning is about 12% more expensive than sequential-scan-and-sort.
Of course, the next question is whether it's right about that. Of course, the next question is whether it's right about that.
We can investigate that using <command>EXPLAIN ANALYZE</>, as discussed We can investigate that using <command>EXPLAIN ANALYZE</command>, as discussed
below. below.
</para> </para>
@ -544,8 +544,8 @@ WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2;
<para> <para>
It is possible to check the accuracy of the planner's estimates It is possible to check the accuracy of the planner's estimates
by using <command>EXPLAIN</>'s <literal>ANALYZE</> option. With this by using <command>EXPLAIN</command>'s <literal>ANALYZE</literal> option. With this
option, <command>EXPLAIN</> actually executes the query, and then displays option, <command>EXPLAIN</command> actually executes the query, and then displays
the true row counts and true run time accumulated within each plan node, the true row counts and true run time accumulated within each plan node,
along with the same estimates that a plain <command>EXPLAIN</command> along with the same estimates that a plain <command>EXPLAIN</command>
shows. For example, we might get a result like this: shows. For example, we might get a result like this:
@ -569,7 +569,7 @@ WHERE t1.unique1 &lt; 10 AND t1.unique2 = t2.unique2;
</screen> </screen>
Note that the <quote>actual time</quote> values are in milliseconds of Note that the <quote>actual time</quote> values are in milliseconds of
real time, whereas the <literal>cost</> estimates are expressed in real time, whereas the <literal>cost</literal> estimates are expressed in
arbitrary units; so they are unlikely to match up. arbitrary units; so they are unlikely to match up.
The thing that's usually most important to look for is whether the The thing that's usually most important to look for is whether the
estimated row counts are reasonably close to reality. In this example estimated row counts are reasonably close to reality. In this example
@ -580,17 +580,17 @@ WHERE t1.unique1 &lt; 10 AND t1.unique2 = t2.unique2;
In some query plans, it is possible for a subplan node to be executed more In some query plans, it is possible for a subplan node to be executed more
than once. For example, the inner index scan will be executed once per than once. For example, the inner index scan will be executed once per
outer row in the above nested-loop plan. In such cases, the outer row in the above nested-loop plan. In such cases, the
<literal>loops</> value reports the <literal>loops</literal> value reports the
total number of executions of the node, and the actual time and rows total number of executions of the node, and the actual time and rows
values shown are averages per-execution. This is done to make the numbers values shown are averages per-execution. This is done to make the numbers
comparable with the way that the cost estimates are shown. Multiply by comparable with the way that the cost estimates are shown. Multiply by
the <literal>loops</> value to get the total time actually spent in the <literal>loops</literal> value to get the total time actually spent in
the node. In the above example, we spent a total of 0.220 milliseconds the node. In the above example, we spent a total of 0.220 milliseconds
executing the index scans on <literal>tenk2</>. executing the index scans on <literal>tenk2</literal>.
</para> </para>
<para> <para>
In some cases <command>EXPLAIN ANALYZE</> shows additional execution In some cases <command>EXPLAIN ANALYZE</command> shows additional execution
statistics beyond the plan node execution times and row counts. statistics beyond the plan node execution times and row counts.
For example, Sort and Hash nodes provide extra information: For example, Sort and Hash nodes provide extra information:
@ -642,13 +642,13 @@ EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE ten &lt; 7;
</screen> </screen>
These counts can be particularly valuable for filter conditions applied at These counts can be particularly valuable for filter conditions applied at
join nodes. The <quote>Rows Removed</> line only appears when at least join nodes. The <quote>Rows Removed</quote> line only appears when at least
one scanned row, or potential join pair in the case of a join node, one scanned row, or potential join pair in the case of a join node,
is rejected by the filter condition. is rejected by the filter condition.
</para> </para>
<para> <para>
A case similar to filter conditions occurs with <quote>lossy</> A case similar to filter conditions occurs with <quote>lossy</quote>
index scans. For example, consider this search for polygons containing a index scans. For example, consider this search for polygons containing a
specific point: specific point:
@ -685,14 +685,14 @@ EXPLAIN ANALYZE SELECT * FROM polygon_tbl WHERE f1 @&gt; polygon '(0.5,2.0)';
Here we can see that the index returned one candidate row, which was Here we can see that the index returned one candidate row, which was
then rejected by a recheck of the index condition. This happens because a then rejected by a recheck of the index condition. This happens because a
GiST index is <quote>lossy</> for polygon containment tests: it actually GiST index is <quote>lossy</quote> for polygon containment tests: it actually
returns the rows with polygons that overlap the target, and then we have returns the rows with polygons that overlap the target, and then we have
to do the exact containment test on those rows. to do the exact containment test on those rows.
</para> </para>
<para> <para>
<command>EXPLAIN</> has a <literal>BUFFERS</> option that can be used with <command>EXPLAIN</command> has a <literal>BUFFERS</literal> option that can be used with
<literal>ANALYZE</> to get even more run time statistics: <literal>ANALYZE</literal> to get even more run time statistics:
<screen> <screen>
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000; EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000;
@ -714,7 +714,7 @@ EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique
Execution time: 0.423 ms Execution time: 0.423 ms
</screen> </screen>
The numbers provided by <literal>BUFFERS</> help to identify which parts The numbers provided by <literal>BUFFERS</literal> help to identify which parts
of the query are the most I/O-intensive. of the query are the most I/O-intensive.
</para> </para>
@ -722,7 +722,7 @@ EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique
Keep in mind that because <command>EXPLAIN ANALYZE</command> actually Keep in mind that because <command>EXPLAIN ANALYZE</command> actually
runs the query, any side-effects will happen as usual, even though runs the query, any side-effects will happen as usual, even though
whatever results the query might output are discarded in favor of whatever results the query might output are discarded in favor of
printing the <command>EXPLAIN</> data. If you want to analyze a printing the <command>EXPLAIN</command> data. If you want to analyze a
data-modifying query without changing your tables, you can data-modifying query without changing your tables, you can
roll the command back afterwards, for example: roll the command back afterwards, for example:
@ -746,8 +746,8 @@ ROLLBACK;
</para> </para>
<para> <para>
As seen in this example, when the query is an <command>INSERT</>, As seen in this example, when the query is an <command>INSERT</command>,
<command>UPDATE</>, or <command>DELETE</> command, the actual work of <command>UPDATE</command>, or <command>DELETE</command> command, the actual work of
applying the table changes is done by a top-level Insert, Update, applying the table changes is done by a top-level Insert, Update,
or Delete plan node. The plan nodes underneath this node perform or Delete plan node. The plan nodes underneath this node perform
the work of locating the old rows and/or computing the new data. the work of locating the old rows and/or computing the new data.
@ -762,7 +762,7 @@ ROLLBACK;
</para> </para>
<para> <para>
When an <command>UPDATE</> or <command>DELETE</> command affects an When an <command>UPDATE</command> or <command>DELETE</command> command affects an
inheritance hierarchy, the output might look like this: inheritance hierarchy, the output might look like this:
<screen> <screen>
@ -789,7 +789,7 @@ EXPLAIN UPDATE parent SET f2 = f2 + 1 WHERE f1 = 101;
scanning subplans, one per table. For clarity, the Update node is scanning subplans, one per table. For clarity, the Update node is
annotated to show the specific target tables that will be updated, in the annotated to show the specific target tables that will be updated, in the
same order as the corresponding subplans. (These annotations are new as same order as the corresponding subplans. (These annotations are new as
of <productname>PostgreSQL</> 9.5; in prior versions the reader had to of <productname>PostgreSQL</productname> 9.5; in prior versions the reader had to
intuit the target tables by inspecting the subplans.) intuit the target tables by inspecting the subplans.)
</para> </para>
@ -804,12 +804,12 @@ EXPLAIN UPDATE parent SET f2 = f2 + 1 WHERE f1 = 101;
ANALYZE</command> includes executor start-up and shut-down time, as well ANALYZE</command> includes executor start-up and shut-down time, as well
as the time to run any triggers that are fired, but it does not include as the time to run any triggers that are fired, but it does not include
parsing, rewriting, or planning time. parsing, rewriting, or planning time.
Time spent executing <literal>BEFORE</> triggers, if any, is included in Time spent executing <literal>BEFORE</literal> triggers, if any, is included in
the time for the related Insert, Update, or Delete node; but time the time for the related Insert, Update, or Delete node; but time
spent executing <literal>AFTER</> triggers is not counted there because spent executing <literal>AFTER</literal> triggers is not counted there because
<literal>AFTER</> triggers are fired after completion of the whole plan. <literal>AFTER</literal> triggers are fired after completion of the whole plan.
The total time spent in each trigger The total time spent in each trigger
(either <literal>BEFORE</> or <literal>AFTER</>) is also shown separately. (either <literal>BEFORE</literal> or <literal>AFTER</literal>) is also shown separately.
Note that deferred constraint triggers will not be executed Note that deferred constraint triggers will not be executed
until end of transaction and are thus not considered at all by until end of transaction and are thus not considered at all by
<command>EXPLAIN ANALYZE</command>. <command>EXPLAIN ANALYZE</command>.
@ -827,13 +827,13 @@ EXPLAIN UPDATE parent SET f2 = f2 + 1 WHERE f1 = 101;
network transmission costs and I/O conversion costs are not included. network transmission costs and I/O conversion costs are not included.
Second, the measurement overhead added by <command>EXPLAIN Second, the measurement overhead added by <command>EXPLAIN
ANALYZE</command> can be significant, especially on machines with slow ANALYZE</command> can be significant, especially on machines with slow
<function>gettimeofday()</> operating-system calls. You can use the <function>gettimeofday()</function> operating-system calls. You can use the
<xref linkend="pgtesttiming"> tool to measure the overhead of timing <xref linkend="pgtesttiming"> tool to measure the overhead of timing
on your system. on your system.
</para> </para>
<para> <para>
<command>EXPLAIN</> results should not be extrapolated to situations <command>EXPLAIN</command> results should not be extrapolated to situations
much different from the one you are actually testing; for example, much different from the one you are actually testing; for example,
results on a toy-sized table cannot be assumed to apply to large tables. results on a toy-sized table cannot be assumed to apply to large tables.
The planner's cost estimates are not linear and so it might choose The planner's cost estimates are not linear and so it might choose
@ -843,14 +843,14 @@ EXPLAIN UPDATE parent SET f2 = f2 + 1 WHERE f1 = 101;
The planner realizes that it's going to take one disk page read to The planner realizes that it's going to take one disk page read to
process the table in any case, so there's no value in expending additional process the table in any case, so there's no value in expending additional
page reads to look at an index. (We saw this happening in the page reads to look at an index. (We saw this happening in the
<literal>polygon_tbl</> example above.) <literal>polygon_tbl</literal> example above.)
</para> </para>
<para> <para>
There are cases in which the actual and estimated values won't match up There are cases in which the actual and estimated values won't match up
well, but nothing is really wrong. One such case occurs when well, but nothing is really wrong. One such case occurs when
plan node execution is stopped short by a <literal>LIMIT</> or similar plan node execution is stopped short by a <literal>LIMIT</literal> or similar
effect. For example, in the <literal>LIMIT</> query we used before, effect. For example, in the <literal>LIMIT</literal> query we used before,
<screen> <screen>
EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000 LIMIT 2; EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000 LIMIT 2;
@ -880,10 +880,10 @@ EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000
and the next key value in the one input is greater than the last key value and the next key value in the one input is greater than the last key value
of the other input; in such a case there can be no more matches and so no of the other input; in such a case there can be no more matches and so no
need to scan the rest of the first input. This results in not reading all need to scan the rest of the first input. This results in not reading all
of one child, with results like those mentioned for <literal>LIMIT</>. of one child, with results like those mentioned for <literal>LIMIT</literal>.
Also, if the outer (first) child contains rows with duplicate key values, Also, if the outer (first) child contains rows with duplicate key values,
the inner (second) child is backed up and rescanned for the portion of its the inner (second) child is backed up and rescanned for the portion of its
rows matching that key value. <command>EXPLAIN ANALYZE</> counts these rows matching that key value. <command>EXPLAIN ANALYZE</command> counts these
repeated emissions of the same inner rows as if they were real additional repeated emissions of the same inner rows as if they were real additional
rows. When there are many outer duplicates, the reported actual row count rows. When there are many outer duplicates, the reported actual row count
for the inner child plan node can be significantly larger than the number for the inner child plan node can be significantly larger than the number
@ -948,9 +948,9 @@ WHERE relname LIKE 'tenk1%';
For efficiency reasons, <structfield>reltuples</structfield> For efficiency reasons, <structfield>reltuples</structfield>
and <structfield>relpages</structfield> are not updated on-the-fly, and <structfield>relpages</structfield> are not updated on-the-fly,
and so they usually contain somewhat out-of-date values. and so they usually contain somewhat out-of-date values.
They are updated by <command>VACUUM</>, <command>ANALYZE</>, and a They are updated by <command>VACUUM</command>, <command>ANALYZE</command>, and a
few DDL commands such as <command>CREATE INDEX</>. A <command>VACUUM</> few DDL commands such as <command>CREATE INDEX</command>. A <command>VACUUM</command>
or <command>ANALYZE</> operation that does not scan the entire table or <command>ANALYZE</command> operation that does not scan the entire table
(which is commonly the case) will incrementally update the (which is commonly the case) will incrementally update the
<structfield>reltuples</structfield> count on the basis of the part <structfield>reltuples</structfield> count on the basis of the part
of the table it did scan, resulting in an approximate value. of the table it did scan, resulting in an approximate value.
@ -966,16 +966,16 @@ WHERE relname LIKE 'tenk1%';
<para> <para>
Most queries retrieve only a fraction of the rows in a table, due Most queries retrieve only a fraction of the rows in a table, due
to <literal>WHERE</> clauses that restrict the rows to be to <literal>WHERE</literal> clauses that restrict the rows to be
examined. The planner thus needs to make an estimate of the examined. The planner thus needs to make an estimate of the
<firstterm>selectivity</> of <literal>WHERE</> clauses, that is, <firstterm>selectivity</firstterm> of <literal>WHERE</literal> clauses, that is,
the fraction of rows that match each condition in the the fraction of rows that match each condition in the
<literal>WHERE</> clause. The information used for this task is <literal>WHERE</literal> clause. The information used for this task is
stored in the stored in the
<link linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link> <link linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link>
system catalog. Entries in <structname>pg_statistic</structname> system catalog. Entries in <structname>pg_statistic</structname>
are updated by the <command>ANALYZE</> and <command>VACUUM are updated by the <command>ANALYZE</command> and <command>VACUUM
ANALYZE</> commands, and are always approximate even when freshly ANALYZE</command> commands, and are always approximate even when freshly
updated. updated.
</para> </para>
@ -1020,17 +1020,17 @@ WHERE tablename = 'road';
Note that two rows are displayed for the same column, one corresponding Note that two rows are displayed for the same column, one corresponding
to the complete inheritance hierarchy starting at the to the complete inheritance hierarchy starting at the
<literal>road</literal> table (<literal>inherited</>=<literal>t</>), <literal>road</literal> table (<literal>inherited</literal>=<literal>t</literal>),
and another one including only the <literal>road</literal> table itself and another one including only the <literal>road</literal> table itself
(<literal>inherited</>=<literal>f</>). (<literal>inherited</literal>=<literal>f</literal>).
</para> </para>
<para> <para>
The amount of information stored in <structname>pg_statistic</structname> The amount of information stored in <structname>pg_statistic</structname>
by <command>ANALYZE</>, in particular the maximum number of entries in the by <command>ANALYZE</command>, in particular the maximum number of entries in the
<structfield>most_common_vals</> and <structfield>histogram_bounds</> <structfield>most_common_vals</structfield> and <structfield>histogram_bounds</structfield>
arrays for each column, can be set on a arrays for each column, can be set on a
column-by-column basis using the <command>ALTER TABLE SET STATISTICS</> column-by-column basis using the <command>ALTER TABLE SET STATISTICS</command>
command, or globally by setting the command, or globally by setting the
<xref linkend="guc-default-statistics-target"> configuration variable. <xref linkend="guc-default-statistics-target"> configuration variable.
The default limit is presently 100 entries. Raising the limit The default limit is presently 100 entries. Raising the limit
@ -1072,7 +1072,7 @@ WHERE tablename = 'road';
an assumption that does not hold when column values are correlated. an assumption that does not hold when column values are correlated.
Regular statistics, because of their per-individual-column nature, Regular statistics, because of their per-individual-column nature,
cannot capture any knowledge about cross-column correlation. cannot capture any knowledge about cross-column correlation.
However, <productname>PostgreSQL</> has the ability to compute However, <productname>PostgreSQL</productname> has the ability to compute
<firstterm>multivariate statistics</firstterm>, which can capture <firstterm>multivariate statistics</firstterm>, which can capture
such information. such information.
</para> </para>
@ -1081,7 +1081,7 @@ WHERE tablename = 'road';
Because the number of possible column combinations is very large, Because the number of possible column combinations is very large,
it's impractical to compute multivariate statistics automatically. it's impractical to compute multivariate statistics automatically.
Instead, <firstterm>extended statistics objects</firstterm>, more often Instead, <firstterm>extended statistics objects</firstterm>, more often
called just <firstterm>statistics objects</>, can be created to instruct called just <firstterm>statistics objects</firstterm>, can be created to instruct
the server to obtain statistics across interesting sets of columns. the server to obtain statistics across interesting sets of columns.
</para> </para>
@ -1116,12 +1116,12 @@ WHERE tablename = 'road';
<para> <para>
The simplest kind of extended statistics tracks <firstterm>functional The simplest kind of extended statistics tracks <firstterm>functional
dependencies</>, a concept used in definitions of database normal forms. dependencies</firstterm>, a concept used in definitions of database normal forms.
We say that column <structfield>b</> is functionally dependent on We say that column <structfield>b</structfield> is functionally dependent on
column <structfield>a</> if knowledge of the value of column <structfield>a</structfield> if knowledge of the value of
<structfield>a</> is sufficient to determine the value <structfield>a</structfield> is sufficient to determine the value
of <structfield>b</>, that is there are no two rows having the same value of <structfield>b</structfield>, that is there are no two rows having the same value
of <structfield>a</> but different values of <structfield>b</>. of <structfield>a</structfield> but different values of <structfield>b</structfield>.
In a fully normalized database, functional dependencies should exist In a fully normalized database, functional dependencies should exist
only on primary keys and superkeys. However, in practice many data sets only on primary keys and superkeys. However, in practice many data sets
are not fully normalized for various reasons; intentional are not fully normalized for various reasons; intentional
@ -1142,15 +1142,15 @@ WHERE tablename = 'road';
</para> </para>
<para> <para>
To inform the planner about functional dependencies, <command>ANALYZE</> To inform the planner about functional dependencies, <command>ANALYZE</command>
can collect measurements of cross-column dependency. Assessing the can collect measurements of cross-column dependency. Assessing the
degree of dependency between all sets of columns would be prohibitively degree of dependency between all sets of columns would be prohibitively
expensive, so data collection is limited to those groups of columns expensive, so data collection is limited to those groups of columns
appearing together in a statistics object defined with appearing together in a statistics object defined with
the <literal>dependencies</> option. It is advisable to create the <literal>dependencies</literal> option. It is advisable to create
<literal>dependencies</> statistics only for column groups that are <literal>dependencies</literal> statistics only for column groups that are
strongly correlated, to avoid unnecessary overhead in both strongly correlated, to avoid unnecessary overhead in both
<command>ANALYZE</> and later query planning. <command>ANALYZE</command> and later query planning.
</para> </para>
<para> <para>
@ -1189,7 +1189,7 @@ SELECT stxname, stxkeys, stxdependencies
simple equality conditions that compare columns to constant values. simple equality conditions that compare columns to constant values.
They are not used to improve estimates for equality conditions They are not used to improve estimates for equality conditions
comparing two columns or comparing a column to an expression, nor for comparing two columns or comparing a column to an expression, nor for
range clauses, <literal>LIKE</> or any other type of condition. range clauses, <literal>LIKE</literal> or any other type of condition.
</para> </para>
<para> <para>
@ -1200,7 +1200,7 @@ SELECT stxname, stxkeys, stxdependencies
<programlisting> <programlisting>
SELECT * FROM zipcodes WHERE city = 'San Francisco' AND zip = '94105'; SELECT * FROM zipcodes WHERE city = 'San Francisco' AND zip = '94105';
</programlisting> </programlisting>
the planner will disregard the <structfield>city</> clause as not the planner will disregard the <structfield>city</structfield> clause as not
changing the selectivity, which is correct. However, it will make changing the selectivity, which is correct. However, it will make
the same assumption about the same assumption about
<programlisting> <programlisting>
@ -1233,11 +1233,11 @@ SELECT * FROM zipcodes WHERE city = 'San Francisco' AND zip = '90210';
</para> </para>
<para> <para>
To improve such estimates, <command>ANALYZE</> can collect n-distinct To improve such estimates, <command>ANALYZE</command> can collect n-distinct
statistics for groups of columns. As before, it's impractical to do statistics for groups of columns. As before, it's impractical to do
this for every possible column grouping, so data is collected only for this for every possible column grouping, so data is collected only for
those groups of columns appearing together in a statistics object those groups of columns appearing together in a statistics object
defined with the <literal>ndistinct</> option. Data will be collected defined with the <literal>ndistinct</literal> option. Data will be collected
for each possible combination of two or more columns from the set of for each possible combination of two or more columns from the set of
listed columns. listed columns.
</para> </para>
@ -1267,17 +1267,17 @@ nd | {"1, 2": 33178, "1, 5": 33178, "2, 5": 27435, "1, 2, 5": 33178}
</para> </para>
<para> <para>
It's advisable to create <literal>ndistinct</> statistics objects only It's advisable to create <literal>ndistinct</literal> statistics objects only
on combinations of columns that are actually used for grouping, and on combinations of columns that are actually used for grouping, and
for which misestimation of the number of groups is resulting in bad for which misestimation of the number of groups is resulting in bad
plans. Otherwise, the <command>ANALYZE</> cycles are just wasted. plans. Otherwise, the <command>ANALYZE</command> cycles are just wasted.
</para> </para>
</sect3> </sect3>
</sect2> </sect2>
</sect1> </sect1>
<sect1 id="explicit-joins"> <sect1 id="explicit-joins">
<title>Controlling the Planner with Explicit <literal>JOIN</> Clauses</title> <title>Controlling the Planner with Explicit <literal>JOIN</literal> Clauses</title>
<indexterm zone="explicit-joins"> <indexterm zone="explicit-joins">
<primary>join</primary> <primary>join</primary>
@ -1286,7 +1286,7 @@ nd | {"1, 2": 33178, "1, 5": 33178, "2, 5": 27435, "1, 2, 5": 33178}
<para> <para>
It is possible It is possible
to control the query planner to some extent by using the explicit <literal>JOIN</> to control the query planner to some extent by using the explicit <literal>JOIN</literal>
syntax. To see why this matters, we first need some background. syntax. To see why this matters, we first need some background.
</para> </para>
@ -1297,13 +1297,13 @@ SELECT * FROM a, b, c WHERE a.id = b.id AND b.ref = c.id;
</programlisting> </programlisting>
the planner is free to join the given tables in any order. For the planner is free to join the given tables in any order. For
example, it could generate a query plan that joins A to B, using example, it could generate a query plan that joins A to B, using
the <literal>WHERE</> condition <literal>a.id = b.id</>, and then the <literal>WHERE</literal> condition <literal>a.id = b.id</literal>, and then
joins C to this joined table, using the other <literal>WHERE</> joins C to this joined table, using the other <literal>WHERE</literal>
condition. Or it could join B to C and then join A to that result. condition. Or it could join B to C and then join A to that result.
Or it could join A to C and then join them with B &mdash; but that Or it could join A to C and then join them with B &mdash; but that
would be inefficient, since the full Cartesian product of A and C would be inefficient, since the full Cartesian product of A and C
would have to be formed, there being no applicable condition in the would have to be formed, there being no applicable condition in the
<literal>WHERE</> clause to allow optimization of the join. (All <literal>WHERE</literal> clause to allow optimization of the join. (All
joins in the <productname>PostgreSQL</productname> executor happen joins in the <productname>PostgreSQL</productname> executor happen
between two input tables, so it's necessary to build up the result between two input tables, so it's necessary to build up the result
in one or another of these fashions.) The important point is that in one or another of these fashions.) The important point is that
@ -1347,30 +1347,30 @@ SELECT * FROM a LEFT JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);
SELECT * FROM a LEFT JOIN b ON (a.bid = b.id) LEFT JOIN c ON (a.cid = c.id); SELECT * FROM a LEFT JOIN b ON (a.bid = b.id) LEFT JOIN c ON (a.cid = c.id);
</programlisting> </programlisting>
it is valid to join A to either B or C first. Currently, only it is valid to join A to either B or C first. Currently, only
<literal>FULL JOIN</> completely constrains the join order. Most <literal>FULL JOIN</literal> completely constrains the join order. Most
practical cases involving <literal>LEFT JOIN</> or <literal>RIGHT JOIN</> practical cases involving <literal>LEFT JOIN</literal> or <literal>RIGHT JOIN</literal>
can be rearranged to some extent. can be rearranged to some extent.
</para> </para>
<para> <para>
Explicit inner join syntax (<literal>INNER JOIN</>, <literal>CROSS Explicit inner join syntax (<literal>INNER JOIN</literal>, <literal>CROSS
JOIN</>, or unadorned <literal>JOIN</>) is semantically the same as JOIN</literal>, or unadorned <literal>JOIN</literal>) is semantically the same as
listing the input relations in <literal>FROM</>, so it does not listing the input relations in <literal>FROM</literal>, so it does not
constrain the join order. constrain the join order.
</para> </para>
<para> <para>
Even though most kinds of <literal>JOIN</> don't completely constrain Even though most kinds of <literal>JOIN</literal> don't completely constrain
the join order, it is possible to instruct the the join order, it is possible to instruct the
<productname>PostgreSQL</productname> query planner to treat all <productname>PostgreSQL</productname> query planner to treat all
<literal>JOIN</> clauses as constraining the join order anyway. <literal>JOIN</literal> clauses as constraining the join order anyway.
For example, these three queries are logically equivalent: For example, these three queries are logically equivalent:
<programlisting> <programlisting>
SELECT * FROM a, b, c WHERE a.id = b.id AND b.ref = c.id; SELECT * FROM a, b, c WHERE a.id = b.id AND b.ref = c.id;
SELECT * FROM a CROSS JOIN b CROSS JOIN c WHERE a.id = b.id AND b.ref = c.id; SELECT * FROM a CROSS JOIN b CROSS JOIN c WHERE a.id = b.id AND b.ref = c.id;
SELECT * FROM a JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id); SELECT * FROM a JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);
</programlisting> </programlisting>
But if we tell the planner to honor the <literal>JOIN</> order, But if we tell the planner to honor the <literal>JOIN</literal> order,
the second and third take less time to plan than the first. This effect the second and third take less time to plan than the first. This effect
is not worth worrying about for only three tables, but it can be a is not worth worrying about for only three tables, but it can be a
lifesaver with many tables. lifesaver with many tables.
@ -1378,19 +1378,19 @@ SELECT * FROM a JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);
<para> <para>
To force the planner to follow the join order laid out by explicit To force the planner to follow the join order laid out by explicit
<literal>JOIN</>s, <literal>JOIN</literal>s,
set the <xref linkend="guc-join-collapse-limit"> run-time parameter to 1. set the <xref linkend="guc-join-collapse-limit"> run-time parameter to 1.
(Other possible values are discussed below.) (Other possible values are discussed below.)
</para> </para>
<para> <para>
You do not need to constrain the join order completely in order to You do not need to constrain the join order completely in order to
cut search time, because it's OK to use <literal>JOIN</> operators cut search time, because it's OK to use <literal>JOIN</literal> operators
within items of a plain <literal>FROM</> list. For example, consider: within items of a plain <literal>FROM</literal> list. For example, consider:
<programlisting> <programlisting>
SELECT * FROM a CROSS JOIN b, c, d, e WHERE ...; SELECT * FROM a CROSS JOIN b, c, d, e WHERE ...;
</programlisting> </programlisting>
With <varname>join_collapse_limit</> = 1, this With <varname>join_collapse_limit</varname> = 1, this
forces the planner to join A to B before joining them to other tables, forces the planner to join A to B before joining them to other tables,
but doesn't constrain its choices otherwise. In this example, the but doesn't constrain its choices otherwise. In this example, the
number of possible join orders is reduced by a factor of 5. number of possible join orders is reduced by a factor of 5.
@ -1400,7 +1400,7 @@ SELECT * FROM a CROSS JOIN b, c, d, e WHERE ...;
Constraining the planner's search in this way is a useful technique Constraining the planner's search in this way is a useful technique
both for reducing planning time and for directing the planner to a both for reducing planning time and for directing the planner to a
good query plan. If the planner chooses a bad join order by default, good query plan. If the planner chooses a bad join order by default,
you can force it to choose a better order via <literal>JOIN</> syntax you can force it to choose a better order via <literal>JOIN</literal> syntax
&mdash; assuming that you know of a better order, that is. Experimentation &mdash; assuming that you know of a better order, that is. Experimentation
is recommended. is recommended.
</para> </para>
@ -1415,22 +1415,22 @@ FROM x, y,
WHERE somethingelse; WHERE somethingelse;
</programlisting> </programlisting>
This situation might arise from use of a view that contains a join; This situation might arise from use of a view that contains a join;
the view's <literal>SELECT</> rule will be inserted in place of the view the view's <literal>SELECT</literal> rule will be inserted in place of the view
reference, yielding a query much like the above. Normally, the planner reference, yielding a query much like the above. Normally, the planner
will try to collapse the subquery into the parent, yielding: will try to collapse the subquery into the parent, yielding:
<programlisting> <programlisting>
SELECT * FROM x, y, a, b, c WHERE something AND somethingelse; SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
</programlisting> </programlisting>
This usually results in a better plan than planning the subquery This usually results in a better plan than planning the subquery
separately. (For example, the outer <literal>WHERE</> conditions might be such that separately. (For example, the outer <literal>WHERE</literal> conditions might be such that
joining X to A first eliminates many rows of A, thus avoiding the need to joining X to A first eliminates many rows of A, thus avoiding the need to
form the full logical output of the subquery.) But at the same time, form the full logical output of the subquery.) But at the same time,
we have increased the planning time; here, we have a five-way join we have increased the planning time; here, we have a five-way join
problem replacing two separate three-way join problems. Because of the problem replacing two separate three-way join problems. Because of the
exponential growth of the number of possibilities, this makes a big exponential growth of the number of possibilities, this makes a big
difference. The planner tries to avoid getting stuck in huge join search difference. The planner tries to avoid getting stuck in huge join search
problems by not collapsing a subquery if more than <varname>from_collapse_limit</> problems by not collapsing a subquery if more than <varname>from_collapse_limit</varname>
<literal>FROM</> items would result in the parent <literal>FROM</literal> items would result in the parent
query. You can trade off planning time against quality of plan by query. You can trade off planning time against quality of plan by
adjusting this run-time parameter up or down. adjusting this run-time parameter up or down.
</para> </para>
@ -1439,11 +1439,11 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
<xref linkend="guc-from-collapse-limit"> and <xref <xref linkend="guc-from-collapse-limit"> and <xref
linkend="guc-join-collapse-limit"> linkend="guc-join-collapse-limit">
are similarly named because they do almost the same thing: one controls are similarly named because they do almost the same thing: one controls
when the planner will <quote>flatten out</> subqueries, and the when the planner will <quote>flatten out</quote> subqueries, and the
other controls when it will flatten out explicit joins. Typically other controls when it will flatten out explicit joins. Typically
you would either set <varname>join_collapse_limit</> equal to you would either set <varname>join_collapse_limit</varname> equal to
<varname>from_collapse_limit</> (so that explicit joins and subqueries <varname>from_collapse_limit</varname> (so that explicit joins and subqueries
act similarly) or set <varname>join_collapse_limit</> to 1 (if you want act similarly) or set <varname>join_collapse_limit</varname> to 1 (if you want
to control join order with explicit joins). But you might set them to control join order with explicit joins). But you might set them
differently if you are trying to fine-tune the trade-off between planning differently if you are trying to fine-tune the trade-off between planning
time and run time. time and run time.
@ -1468,7 +1468,7 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
</indexterm> </indexterm>
<para> <para>
When using multiple <command>INSERT</>s, turn off autocommit and just do When using multiple <command>INSERT</command>s, turn off autocommit and just do
one commit at the end. (In plain one commit at the end. (In plain
SQL, this means issuing <command>BEGIN</command> at the start and SQL, this means issuing <command>BEGIN</command> at the start and
<command>COMMIT</command> at the end. Some client libraries might <command>COMMIT</command> at the end. Some client libraries might
@ -1505,14 +1505,14 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
<command>EXECUTE</command> as many times as required. This avoids <command>EXECUTE</command> as many times as required. This avoids
some of the overhead of repeatedly parsing and planning some of the overhead of repeatedly parsing and planning
<command>INSERT</command>. Different interfaces provide this facility <command>INSERT</command>. Different interfaces provide this facility
in different ways; look for <quote>prepared statements</> in the interface in different ways; look for <quote>prepared statements</quote> in the interface
documentation. documentation.
</para> </para>
<para> <para>
Note that loading a large number of rows using Note that loading a large number of rows using
<command>COPY</command> is almost always faster than using <command>COPY</command> is almost always faster than using
<command>INSERT</command>, even if <command>PREPARE</> is used and <command>INSERT</command>, even if <command>PREPARE</command> is used and
multiple insertions are batched into a single transaction. multiple insertions are batched into a single transaction.
</para> </para>
@ -1523,7 +1523,7 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
needs to be written, because in case of an error, the files needs to be written, because in case of an error, the files
containing the newly loaded data will be removed anyway. containing the newly loaded data will be removed anyway.
However, this consideration only applies when However, this consideration only applies when
<xref linkend="guc-wal-level"> is <literal>minimal</> as all commands <xref linkend="guc-wal-level"> is <literal>minimal</literal> as all commands
must write WAL otherwise. must write WAL otherwise.
</para> </para>
@ -1557,7 +1557,7 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
<para> <para>
Just as with indexes, a foreign key constraint can be checked Just as with indexes, a foreign key constraint can be checked
<quote>in bulk</> more efficiently than row-by-row. So it might be <quote>in bulk</quote> more efficiently than row-by-row. So it might be
useful to drop foreign key constraints, load data, and re-create useful to drop foreign key constraints, load data, and re-create
the constraints. Again, there is a trade-off between data load the constraints. Again, there is a trade-off between data load
speed and loss of error checking while the constraint is missing. speed and loss of error checking while the constraint is missing.
@ -1570,7 +1570,7 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
the row's foreign key constraint). Loading many millions of rows can the row's foreign key constraint). Loading many millions of rows can
cause the trigger event queue to overflow available memory, leading to cause the trigger event queue to overflow available memory, leading to
intolerable swapping or even outright failure of the command. Therefore intolerable swapping or even outright failure of the command. Therefore
it may be <emphasis>necessary</>, not just desirable, to drop and re-apply it may be <emphasis>necessary</emphasis>, not just desirable, to drop and re-apply
foreign keys when loading large amounts of data. If temporarily removing foreign keys when loading large amounts of data. If temporarily removing
the constraint isn't acceptable, the only other recourse may be to split the constraint isn't acceptable, the only other recourse may be to split
up the load operation into smaller transactions. up the load operation into smaller transactions.
@ -1584,8 +1584,8 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
Temporarily increasing the <xref linkend="guc-maintenance-work-mem"> Temporarily increasing the <xref linkend="guc-maintenance-work-mem">
configuration variable when loading large amounts of data can configuration variable when loading large amounts of data can
lead to improved performance. This will help to speed up <command>CREATE lead to improved performance. This will help to speed up <command>CREATE
INDEX</> commands and <command>ALTER TABLE ADD FOREIGN KEY</> commands. INDEX</command> commands and <command>ALTER TABLE ADD FOREIGN KEY</command> commands.
It won't do much for <command>COPY</> itself, so this advice is It won't do much for <command>COPY</command> itself, so this advice is
only useful when you are using one or both of the above techniques. only useful when you are using one or both of the above techniques.
</para> </para>
</sect2> </sect2>
@ -1617,8 +1617,8 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
new base backup after the load has completed than to process a large new base backup after the load has completed than to process a large
amount of incremental WAL data. To prevent incremental WAL logging amount of incremental WAL data. To prevent incremental WAL logging
while loading, disable archiving and streaming replication, by setting while loading, disable archiving and streaming replication, by setting
<xref linkend="guc-wal-level"> to <literal>minimal</>, <xref linkend="guc-wal-level"> to <literal>minimal</literal>,
<xref linkend="guc-archive-mode"> to <literal>off</>, and <xref linkend="guc-archive-mode"> to <literal>off</literal>, and
<xref linkend="guc-max-wal-senders"> to zero. <xref linkend="guc-max-wal-senders"> to zero.
But note that changing these settings requires a server restart. But note that changing these settings requires a server restart.
</para> </para>
@ -1628,8 +1628,8 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
process the WAL data, process the WAL data,
doing this will actually make certain commands faster, because they doing this will actually make certain commands faster, because they
are designed not to write WAL at all if <varname>wal_level</varname> are designed not to write WAL at all if <varname>wal_level</varname>
is <literal>minimal</>. (They can guarantee crash safety more cheaply is <literal>minimal</literal>. (They can guarantee crash safety more cheaply
by doing an <function>fsync</> at the end than by writing WAL.) by doing an <function>fsync</function> at the end than by writing WAL.)
This applies to the following commands: This applies to the following commands:
<itemizedlist> <itemizedlist>
<listitem> <listitem>
@ -1683,21 +1683,21 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
</sect2> </sect2>
<sect2 id="populate-pg-dump"> <sect2 id="populate-pg-dump">
<title>Some Notes About <application>pg_dump</></title> <title>Some Notes About <application>pg_dump</application></title>
<para> <para>
Dump scripts generated by <application>pg_dump</> automatically apply Dump scripts generated by <application>pg_dump</application> automatically apply
several, but not all, of the above guidelines. To reload a several, but not all, of the above guidelines. To reload a
<application>pg_dump</> dump as quickly as possible, you need to <application>pg_dump</application> dump as quickly as possible, you need to
do a few extra things manually. (Note that these points apply while do a few extra things manually. (Note that these points apply while
<emphasis>restoring</> a dump, not while <emphasis>creating</> it. <emphasis>restoring</emphasis> a dump, not while <emphasis>creating</emphasis> it.
The same points apply whether loading a text dump with The same points apply whether loading a text dump with
<application>psql</> or using <application>pg_restore</> to load <application>psql</application> or using <application>pg_restore</application> to load
from a <application>pg_dump</> archive file.) from a <application>pg_dump</application> archive file.)
</para> </para>
<para> <para>
By default, <application>pg_dump</> uses <command>COPY</>, and when By default, <application>pg_dump</application> uses <command>COPY</command>, and when
it is generating a complete schema-and-data dump, it is careful to it is generating a complete schema-and-data dump, it is careful to
load data before creating indexes and foreign keys. So in this case load data before creating indexes and foreign keys. So in this case
several guidelines are handled automatically. What is left several guidelines are handled automatically. What is left
@ -1713,10 +1713,10 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
<listitem> <listitem>
<para> <para>
If using WAL archiving or streaming replication, consider disabling If using WAL archiving or streaming replication, consider disabling
them during the restore. To do that, set <varname>archive_mode</> them during the restore. To do that, set <varname>archive_mode</varname>
to <literal>off</>, to <literal>off</literal>,
<varname>wal_level</varname> to <literal>minimal</>, and <varname>wal_level</varname> to <literal>minimal</literal>, and
<varname>max_wal_senders</> to zero before loading the dump. <varname>max_wal_senders</varname> to zero before loading the dump.
Afterwards, set them back to the right values and take a fresh Afterwards, set them back to the right values and take a fresh
base backup. base backup.
</para> </para>
@ -1724,49 +1724,49 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
<listitem> <listitem>
<para> <para>
Experiment with the parallel dump and restore modes of both Experiment with the parallel dump and restore modes of both
<application>pg_dump</> and <application>pg_restore</> and find the <application>pg_dump</application> and <application>pg_restore</application> and find the
optimal number of concurrent jobs to use. Dumping and restoring in optimal number of concurrent jobs to use. Dumping and restoring in
parallel by means of the <option>-j</> option should give you a parallel by means of the <option>-j</option> option should give you a
significantly higher performance over the serial mode. significantly higher performance over the serial mode.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
Consider whether the whole dump should be restored as a single Consider whether the whole dump should be restored as a single
transaction. To do that, pass the <option>-1</> or transaction. To do that, pass the <option>-1</option> or
<option>--single-transaction</> command-line option to <option>--single-transaction</option> command-line option to
<application>psql</> or <application>pg_restore</>. When using this <application>psql</application> or <application>pg_restore</application>. When using this
mode, even the smallest of errors will rollback the entire restore, mode, even the smallest of errors will rollback the entire restore,
possibly discarding many hours of processing. Depending on how possibly discarding many hours of processing. Depending on how
interrelated the data is, that might seem preferable to manual cleanup, interrelated the data is, that might seem preferable to manual cleanup,
or not. <command>COPY</> commands will run fastest if you use a single or not. <command>COPY</command> commands will run fastest if you use a single
transaction and have WAL archiving turned off. transaction and have WAL archiving turned off.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
If multiple CPUs are available in the database server, consider using If multiple CPUs are available in the database server, consider using
<application>pg_restore</>'s <option>--jobs</> option. This <application>pg_restore</application>'s <option>--jobs</option> option. This
allows concurrent data loading and index creation. allows concurrent data loading and index creation.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
Run <command>ANALYZE</> afterwards. Run <command>ANALYZE</command> afterwards.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</para> </para>
<para> <para>
A data-only dump will still use <command>COPY</>, but it does not A data-only dump will still use <command>COPY</command>, but it does not
drop or recreate indexes, and it does not normally touch foreign drop or recreate indexes, and it does not normally touch foreign
keys. keys.
<footnote> <footnote>
<para> <para>
You can get the effect of disabling foreign keys by using You can get the effect of disabling foreign keys by using
the <option>--disable-triggers</> option &mdash; but realize that the <option>--disable-triggers</option> option &mdash; but realize that
that eliminates, rather than just postpones, foreign key that eliminates, rather than just postpones, foreign key
validation, and so it is possible to insert bad data if you use it. validation, and so it is possible to insert bad data if you use it.
</para> </para>
@ -1778,7 +1778,7 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
while loading the data, but don't bother increasing while loading the data, but don't bother increasing
<varname>maintenance_work_mem</varname>; rather, you'd do that while <varname>maintenance_work_mem</varname>; rather, you'd do that while
manually recreating indexes and foreign keys afterwards. manually recreating indexes and foreign keys afterwards.
And don't forget to <command>ANALYZE</> when you're done; see And don't forget to <command>ANALYZE</command> when you're done; see
<xref linkend="vacuum-for-statistics"> <xref linkend="vacuum-for-statistics">
and <xref linkend="autovacuum"> for more information. and <xref linkend="autovacuum"> for more information.
</para> </para>
@ -1808,7 +1808,7 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
<listitem> <listitem>
<para> <para>
Place the database cluster's data directory in a memory-backed Place the database cluster's data directory in a memory-backed
file system (i.e. <acronym>RAM</> disk). This eliminates all file system (i.e. <acronym>RAM</acronym> disk). This eliminates all
database disk I/O, but limits data storage to the amount of database disk I/O, but limits data storage to the amount of
available memory (and perhaps swap). available memory (and perhaps swap).
</para> </para>
@ -1826,7 +1826,7 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
Turn off <xref linkend="guc-synchronous-commit">; there might be no Turn off <xref linkend="guc-synchronous-commit">; there might be no
need to force <acronym>WAL</acronym> writes to disk on every need to force <acronym>WAL</acronym> writes to disk on every
commit. This setting does risk transaction loss (though not data commit. This setting does risk transaction loss (though not data
corruption) in case of a crash of the <emphasis>database</>. corruption) in case of a crash of the <emphasis>database</emphasis>.
</para> </para>
</listitem> </listitem>
@ -1842,7 +1842,7 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
Increase <xref linkend="guc-max-wal-size"> and <xref Increase <xref linkend="guc-max-wal-size"> and <xref
linkend="guc-checkpoint-timeout">; this reduces the frequency linkend="guc-checkpoint-timeout">; this reduces the frequency
of checkpoints, but increases the storage requirements of of checkpoints, but increases the storage requirements of
<filename>/pg_wal</>. <filename>/pg_wal</filename>.
</para> </para>
</listitem> </listitem>

View File

@ -37,7 +37,7 @@
</para> </para>
<table id="pgbuffercache-columns"> <table id="pgbuffercache-columns">
<title><structname>pg_buffercache</> Columns</title> <title><structname>pg_buffercache</structname> Columns</title>
<tgroup cols="4"> <tgroup cols="4">
<thead> <thead>
@ -54,7 +54,7 @@
<entry><structfield>bufferid</structfield></entry> <entry><structfield>bufferid</structfield></entry>
<entry><type>integer</type></entry> <entry><type>integer</type></entry>
<entry></entry> <entry></entry>
<entry>ID, in the range 1..<varname>shared_buffers</></entry> <entry>ID, in the range 1..<varname>shared_buffers</varname></entry>
</row> </row>
<row> <row>
@ -83,7 +83,7 @@
<entry><type>smallint</type></entry> <entry><type>smallint</type></entry>
<entry></entry> <entry></entry>
<entry>Fork number within the relation; see <entry>Fork number within the relation; see
<filename>include/common/relpath.h</></entry> <filename>include/common/relpath.h</filename></entry>
</row> </row>
<row> <row>
@ -120,22 +120,22 @@
<para> <para>
There is one row for each buffer in the shared cache. Unused buffers are There is one row for each buffer in the shared cache. Unused buffers are
shown with all fields null except <structfield>bufferid</>. Shared system shown with all fields null except <structfield>bufferid</structfield>. Shared system
catalogs are shown as belonging to database zero. catalogs are shown as belonging to database zero.
</para> </para>
<para> <para>
Because the cache is shared by all the databases, there will normally be Because the cache is shared by all the databases, there will normally be
pages from relations not belonging to the current database. This means pages from relations not belonging to the current database. This means
that there may not be matching join rows in <structname>pg_class</> for that there may not be matching join rows in <structname>pg_class</structname> for
some rows, or that there could even be incorrect joins. If you are some rows, or that there could even be incorrect joins. If you are
trying to join against <structname>pg_class</>, it's a good idea to trying to join against <structname>pg_class</structname>, it's a good idea to
restrict the join to rows having <structfield>reldatabase</> equal to restrict the join to rows having <structfield>reldatabase</structfield> equal to
the current database's OID or zero. the current database's OID or zero.
</para> </para>
<para> <para>
When the <structname>pg_buffercache</> view is accessed, internal buffer When the <structname>pg_buffercache</structname> view is accessed, internal buffer
manager locks are taken for long enough to copy all the buffer state manager locks are taken for long enough to copy all the buffer state
data that the view will display. data that the view will display.
This ensures that the view produces a consistent set of results, while not This ensures that the view produces a consistent set of results, while not

View File

@ -13,8 +13,8 @@
</indexterm> </indexterm>
<para> <para>
The <filename>pgcrypto</> module provides cryptographic functions for The <filename>pgcrypto</filename> module provides cryptographic functions for
<productname>PostgreSQL</>. <productname>PostgreSQL</productname>.
</para> </para>
<sect2> <sect2>
@ -33,19 +33,19 @@ digest(data bytea, type text) returns bytea
</synopsis> </synopsis>
<para> <para>
Computes a binary hash of the given <parameter>data</>. Computes a binary hash of the given <parameter>data</parameter>.
<parameter>type</> is the algorithm to use. <parameter>type</parameter> is the algorithm to use.
Standard algorithms are <literal>md5</literal>, <literal>sha1</literal>, Standard algorithms are <literal>md5</literal>, <literal>sha1</literal>,
<literal>sha224</literal>, <literal>sha256</literal>, <literal>sha224</literal>, <literal>sha256</literal>,
<literal>sha384</literal> and <literal>sha512</literal>. <literal>sha384</literal> and <literal>sha512</literal>.
If <filename>pgcrypto</> was built with If <filename>pgcrypto</filename> was built with
OpenSSL, more algorithms are available, as detailed in OpenSSL, more algorithms are available, as detailed in
<xref linkend="pgcrypto-with-without-openssl">. <xref linkend="pgcrypto-with-without-openssl">.
</para> </para>
<para> <para>
If you want the digest as a hexadecimal string, use If you want the digest as a hexadecimal string, use
<function>encode()</> on the result. For example: <function>encode()</function> on the result. For example:
<programlisting> <programlisting>
CREATE OR REPLACE FUNCTION sha1(bytea) returns text AS $$ CREATE OR REPLACE FUNCTION sha1(bytea) returns text AS $$
SELECT encode(digest($1, 'sha1'), 'hex') SELECT encode(digest($1, 'sha1'), 'hex')
@ -67,12 +67,12 @@ hmac(data bytea, key text, type text) returns bytea
</synopsis> </synopsis>
<para> <para>
Calculates hashed MAC for <parameter>data</> with key <parameter>key</>. Calculates hashed MAC for <parameter>data</parameter> with key <parameter>key</parameter>.
<parameter>type</> is the same as in <function>digest()</>. <parameter>type</parameter> is the same as in <function>digest()</function>.
</para> </para>
<para> <para>
This is similar to <function>digest()</> but the hash can only be This is similar to <function>digest()</function> but the hash can only be
recalculated knowing the key. This prevents the scenario of someone recalculated knowing the key. This prevents the scenario of someone
altering data and also changing the hash to match. altering data and also changing the hash to match.
</para> </para>
@ -88,14 +88,14 @@ hmac(data bytea, key text, type text) returns bytea
<title>Password Hashing Functions</title> <title>Password Hashing Functions</title>
<para> <para>
The functions <function>crypt()</> and <function>gen_salt()</> The functions <function>crypt()</function> and <function>gen_salt()</function>
are specifically designed for hashing passwords. are specifically designed for hashing passwords.
<function>crypt()</> does the hashing and <function>gen_salt()</> <function>crypt()</function> does the hashing and <function>gen_salt()</function>
prepares algorithm parameters for it. prepares algorithm parameters for it.
</para> </para>
<para> <para>
The algorithms in <function>crypt()</> differ from the usual The algorithms in <function>crypt()</function> differ from the usual
MD5 or SHA1 hashing algorithms in the following respects: MD5 or SHA1 hashing algorithms in the following respects:
</para> </para>
@ -108,7 +108,7 @@ hmac(data bytea, key text, type text) returns bytea
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
They use a random value, called the <firstterm>salt</>, so that users They use a random value, called the <firstterm>salt</firstterm>, so that users
having the same password will have different encrypted passwords. having the same password will have different encrypted passwords.
This is also an additional defense against reversing the algorithm. This is also an additional defense against reversing the algorithm.
</para> </para>
@ -134,7 +134,7 @@ hmac(data bytea, key text, type text) returns bytea
</para> </para>
<table id="pgcrypto-crypt-algorithms"> <table id="pgcrypto-crypt-algorithms">
<title>Supported Algorithms for <function>crypt()</></title> <title>Supported Algorithms for <function>crypt()</function></title>
<tgroup cols="6"> <tgroup cols="6">
<thead> <thead>
<row> <row>
@ -148,7 +148,7 @@ hmac(data bytea, key text, type text) returns bytea
</thead> </thead>
<tbody> <tbody>
<row> <row>
<entry><literal>bf</></entry> <entry><literal>bf</literal></entry>
<entry>72</entry> <entry>72</entry>
<entry>yes</entry> <entry>yes</entry>
<entry>128</entry> <entry>128</entry>
@ -156,7 +156,7 @@ hmac(data bytea, key text, type text) returns bytea
<entry>Blowfish-based, variant 2a</entry> <entry>Blowfish-based, variant 2a</entry>
</row> </row>
<row> <row>
<entry><literal>md5</></entry> <entry><literal>md5</literal></entry>
<entry>unlimited</entry> <entry>unlimited</entry>
<entry>no</entry> <entry>no</entry>
<entry>48</entry> <entry>48</entry>
@ -164,7 +164,7 @@ hmac(data bytea, key text, type text) returns bytea
<entry>MD5-based crypt</entry> <entry>MD5-based crypt</entry>
</row> </row>
<row> <row>
<entry><literal>xdes</></entry> <entry><literal>xdes</literal></entry>
<entry>8</entry> <entry>8</entry>
<entry>yes</entry> <entry>yes</entry>
<entry>24</entry> <entry>24</entry>
@ -172,7 +172,7 @@ hmac(data bytea, key text, type text) returns bytea
<entry>Extended DES</entry> <entry>Extended DES</entry>
</row> </row>
<row> <row>
<entry><literal>des</></entry> <entry><literal>des</literal></entry>
<entry>8</entry> <entry>8</entry>
<entry>no</entry> <entry>no</entry>
<entry>12</entry> <entry>12</entry>
@ -184,7 +184,7 @@ hmac(data bytea, key text, type text) returns bytea
</table> </table>
<sect3> <sect3>
<title><function>crypt()</></title> <title><function>crypt()</function></title>
<indexterm> <indexterm>
<primary>crypt</primary> <primary>crypt</primary>
@ -195,10 +195,10 @@ crypt(password text, salt text) returns text
</synopsis> </synopsis>
<para> <para>
Calculates a crypt(3)-style hash of <parameter>password</>. Calculates a crypt(3)-style hash of <parameter>password</parameter>.
When storing a new password, you need to use When storing a new password, you need to use
<function>gen_salt()</> to generate a new <parameter>salt</> value. <function>gen_salt()</function> to generate a new <parameter>salt</parameter> value.
To check a password, pass the stored hash value as <parameter>salt</>, To check a password, pass the stored hash value as <parameter>salt</parameter>,
and test whether the result matches the stored value. and test whether the result matches the stored value.
</para> </para>
<para> <para>
@ -212,12 +212,12 @@ UPDATE ... SET pswhash = crypt('new password', gen_salt('md5'));
<programlisting> <programlisting>
SELECT (pswhash = crypt('entered password', pswhash)) AS pswmatch FROM ... ; SELECT (pswhash = crypt('entered password', pswhash)) AS pswmatch FROM ... ;
</programlisting> </programlisting>
This returns <literal>true</> if the entered password is correct. This returns <literal>true</literal> if the entered password is correct.
</para> </para>
</sect3> </sect3>
<sect3> <sect3>
<title><function>gen_salt()</></title> <title><function>gen_salt()</function></title>
<indexterm> <indexterm>
<primary>gen_salt</primary> <primary>gen_salt</primary>
@ -228,30 +228,30 @@ gen_salt(type text [, iter_count integer ]) returns text
</synopsis> </synopsis>
<para> <para>
Generates a new random salt string for use in <function>crypt()</>. Generates a new random salt string for use in <function>crypt()</function>.
The salt string also tells <function>crypt()</> which algorithm to use. The salt string also tells <function>crypt()</function> which algorithm to use.
</para> </para>
<para> <para>
The <parameter>type</> parameter specifies the hashing algorithm. The <parameter>type</parameter> parameter specifies the hashing algorithm.
The accepted types are: <literal>des</literal>, <literal>xdes</literal>, The accepted types are: <literal>des</literal>, <literal>xdes</literal>,
<literal>md5</literal> and <literal>bf</literal>. <literal>md5</literal> and <literal>bf</literal>.
</para> </para>
<para> <para>
The <parameter>iter_count</> parameter lets the user specify the iteration The <parameter>iter_count</parameter> parameter lets the user specify the iteration
count, for algorithms that have one. count, for algorithms that have one.
The higher the count, the more time it takes to hash The higher the count, the more time it takes to hash
the password and therefore the more time to break it. Although with the password and therefore the more time to break it. Although with
too high a count the time to calculate a hash may be several years too high a count the time to calculate a hash may be several years
&mdash; which is somewhat impractical. If the <parameter>iter_count</> &mdash; which is somewhat impractical. If the <parameter>iter_count</parameter>
parameter is omitted, the default iteration count is used. parameter is omitted, the default iteration count is used.
Allowed values for <parameter>iter_count</> depend on the algorithm and Allowed values for <parameter>iter_count</parameter> depend on the algorithm and
are shown in <xref linkend="pgcrypto-icfc-table">. are shown in <xref linkend="pgcrypto-icfc-table">.
</para> </para>
<table id="pgcrypto-icfc-table"> <table id="pgcrypto-icfc-table">
<title>Iteration Counts for <function>crypt()</></title> <title>Iteration Counts for <function>crypt()</function></title>
<tgroup cols="4"> <tgroup cols="4">
<thead> <thead>
<row> <row>
@ -263,13 +263,13 @@ gen_salt(type text [, iter_count integer ]) returns text
</thead> </thead>
<tbody> <tbody>
<row> <row>
<entry><literal>xdes</></entry> <entry><literal>xdes</literal></entry>
<entry>725</entry> <entry>725</entry>
<entry>1</entry> <entry>1</entry>
<entry>16777215</entry> <entry>16777215</entry>
</row> </row>
<row> <row>
<entry><literal>bf</></entry> <entry><literal>bf</literal></entry>
<entry>6</entry> <entry>6</entry>
<entry>4</entry> <entry>4</entry>
<entry>31</entry> <entry>31</entry>
@ -310,63 +310,63 @@ gen_salt(type text [, iter_count integer ]) returns text
<row> <row>
<entry>Algorithm</entry> <entry>Algorithm</entry>
<entry>Hashes/sec</entry> <entry>Hashes/sec</entry>
<entry>For <literal>[a-z]</></entry> <entry>For <literal>[a-z]</literal></entry>
<entry>For <literal>[A-Za-z0-9]</></entry> <entry>For <literal>[A-Za-z0-9]</literal></entry>
<entry>Duration relative to <literal>md5 hash</></entry> <entry>Duration relative to <literal>md5 hash</literal></entry>
</row> </row>
</thead> </thead>
<tbody> <tbody>
<row> <row>
<entry><literal>crypt-bf/8</></entry> <entry><literal>crypt-bf/8</literal></entry>
<entry>1792</entry> <entry>1792</entry>
<entry>4 years</entry> <entry>4 years</entry>
<entry>3927 years</entry> <entry>3927 years</entry>
<entry>100k</entry> <entry>100k</entry>
</row> </row>
<row> <row>
<entry><literal>crypt-bf/7</></entry> <entry><literal>crypt-bf/7</literal></entry>
<entry>3648</entry> <entry>3648</entry>
<entry>2 years</entry> <entry>2 years</entry>
<entry>1929 years</entry> <entry>1929 years</entry>
<entry>50k</entry> <entry>50k</entry>
</row> </row>
<row> <row>
<entry><literal>crypt-bf/6</></entry> <entry><literal>crypt-bf/6</literal></entry>
<entry>7168</entry> <entry>7168</entry>
<entry>1 year</entry> <entry>1 year</entry>
<entry>982 years</entry> <entry>982 years</entry>
<entry>25k</entry> <entry>25k</entry>
</row> </row>
<row> <row>
<entry><literal>crypt-bf/5</></entry> <entry><literal>crypt-bf/5</literal></entry>
<entry>13504</entry> <entry>13504</entry>
<entry>188 days</entry> <entry>188 days</entry>
<entry>521 years</entry> <entry>521 years</entry>
<entry>12.5k</entry> <entry>12.5k</entry>
</row> </row>
<row> <row>
<entry><literal>crypt-md5</></entry> <entry><literal>crypt-md5</literal></entry>
<entry>171584</entry> <entry>171584</entry>
<entry>15 days</entry> <entry>15 days</entry>
<entry>41 years</entry> <entry>41 years</entry>
<entry>1k</entry> <entry>1k</entry>
</row> </row>
<row> <row>
<entry><literal>crypt-des</></entry> <entry><literal>crypt-des</literal></entry>
<entry>23221568</entry> <entry>23221568</entry>
<entry>157.5 minutes</entry> <entry>157.5 minutes</entry>
<entry>108 days</entry> <entry>108 days</entry>
<entry>7</entry> <entry>7</entry>
</row> </row>
<row> <row>
<entry><literal>sha1</></entry> <entry><literal>sha1</literal></entry>
<entry>37774272</entry> <entry>37774272</entry>
<entry>90 minutes</entry> <entry>90 minutes</entry>
<entry>68 days</entry> <entry>68 days</entry>
<entry>4</entry> <entry>4</entry>
</row> </row>
<row> <row>
<entry><literal>md5</> (hash)</entry> <entry><literal>md5</literal> (hash)</entry>
<entry>150085504</entry> <entry>150085504</entry>
<entry>22.5 minutes</entry> <entry>22.5 minutes</entry>
<entry>17 days</entry> <entry>17 days</entry>
@ -388,18 +388,18 @@ gen_salt(type text [, iter_count integer ]) returns text
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<literal>crypt-des</> and <literal>crypt-md5</> algorithm numbers are <literal>crypt-des</literal> and <literal>crypt-md5</literal> algorithm numbers are
taken from John the Ripper v1.6.38 <literal>-test</> output. taken from John the Ripper v1.6.38 <literal>-test</literal> output.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<literal>md5 hash</> numbers are from mdcrack 1.2. <literal>md5 hash</literal> numbers are from mdcrack 1.2.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<literal>sha1</> numbers are from lcrack-20031130-beta. <literal>sha1</literal> numbers are from lcrack-20031130-beta.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
@ -407,10 +407,10 @@ gen_salt(type text [, iter_count integer ]) returns text
<literal>crypt-bf</literal> numbers are taken using a simple program that <literal>crypt-bf</literal> numbers are taken using a simple program that
loops over 1000 8-character passwords. That way I can show the speed loops over 1000 8-character passwords. That way I can show the speed
with different numbers of iterations. For reference: <literal>john with different numbers of iterations. For reference: <literal>john
-test</literal> shows 13506 loops/sec for <literal>crypt-bf/5</>. -test</literal> shows 13506 loops/sec for <literal>crypt-bf/5</literal>.
(The very small (The very small
difference in results is in accordance with the fact that the difference in results is in accordance with the fact that the
<literal>crypt-bf</literal> implementation in <filename>pgcrypto</> <literal>crypt-bf</literal> implementation in <filename>pgcrypto</filename>
is the same one used in John the Ripper.) is the same one used in John the Ripper.)
</para> </para>
</listitem> </listitem>
@ -436,7 +436,7 @@ gen_salt(type text [, iter_count integer ]) returns text
</para> </para>
<para> <para>
An encrypted PGP message consists of 2 parts, or <firstterm>packets</>: An encrypted PGP message consists of 2 parts, or <firstterm>packets</firstterm>:
</para> </para>
<itemizedlist> <itemizedlist>
<listitem> <listitem>
@ -459,7 +459,7 @@ gen_salt(type text [, iter_count integer ]) returns text
<listitem> <listitem>
<para> <para>
The given password is hashed using a String2Key (S2K) algorithm. This is The given password is hashed using a String2Key (S2K) algorithm. This is
rather similar to <function>crypt()</> algorithms &mdash; purposefully rather similar to <function>crypt()</function> algorithms &mdash; purposefully
slow and with random salt &mdash; but it produces a full-length binary slow and with random salt &mdash; but it produces a full-length binary
key. key.
</para> </para>
@ -540,8 +540,8 @@ pgp_sym_encrypt(data text, psw text [, options text ]) returns bytea
pgp_sym_encrypt_bytea(data bytea, psw text [, options text ]) returns bytea pgp_sym_encrypt_bytea(data bytea, psw text [, options text ]) returns bytea
</synopsis> </synopsis>
<para> <para>
Encrypt <parameter>data</> with a symmetric PGP key <parameter>psw</>. Encrypt <parameter>data</parameter> with a symmetric PGP key <parameter>psw</parameter>.
The <parameter>options</> parameter can contain option settings, The <parameter>options</parameter> parameter can contain option settings,
as described below. as described below.
</para> </para>
</sect3> </sect3>
@ -565,12 +565,12 @@ pgp_sym_decrypt_bytea(msg bytea, psw text [, options text ]) returns bytea
Decrypt a symmetric-key-encrypted PGP message. Decrypt a symmetric-key-encrypted PGP message.
</para> </para>
<para> <para>
Decrypting <type>bytea</> data with <function>pgp_sym_decrypt</> is disallowed. Decrypting <type>bytea</type> data with <function>pgp_sym_decrypt</function> is disallowed.
This is to avoid outputting invalid character data. Decrypting This is to avoid outputting invalid character data. Decrypting
originally textual data with <function>pgp_sym_decrypt_bytea</> is fine. originally textual data with <function>pgp_sym_decrypt_bytea</function> is fine.
</para> </para>
<para> <para>
The <parameter>options</> parameter can contain option settings, The <parameter>options</parameter> parameter can contain option settings,
as described below. as described below.
</para> </para>
</sect3> </sect3>
@ -591,11 +591,11 @@ pgp_pub_encrypt(data text, key bytea [, options text ]) returns bytea
pgp_pub_encrypt_bytea(data bytea, key bytea [, options text ]) returns bytea pgp_pub_encrypt_bytea(data bytea, key bytea [, options text ]) returns bytea
</synopsis> </synopsis>
<para> <para>
Encrypt <parameter>data</> with a public PGP key <parameter>key</>. Encrypt <parameter>data</parameter> with a public PGP key <parameter>key</parameter>.
Giving this function a secret key will produce an error. Giving this function a secret key will produce an error.
</para> </para>
<para> <para>
The <parameter>options</> parameter can contain option settings, The <parameter>options</parameter> parameter can contain option settings,
as described below. as described below.
</para> </para>
</sect3> </sect3>
@ -616,19 +616,19 @@ pgp_pub_decrypt(msg bytea, key bytea [, psw text [, options text ]]) returns tex
pgp_pub_decrypt_bytea(msg bytea, key bytea [, psw text [, options text ]]) returns bytea pgp_pub_decrypt_bytea(msg bytea, key bytea [, psw text [, options text ]]) returns bytea
</synopsis> </synopsis>
<para> <para>
Decrypt a public-key-encrypted message. <parameter>key</> must be the Decrypt a public-key-encrypted message. <parameter>key</parameter> must be the
secret key corresponding to the public key that was used to encrypt. secret key corresponding to the public key that was used to encrypt.
If the secret key is password-protected, you must give the password in If the secret key is password-protected, you must give the password in
<parameter>psw</>. If there is no password, but you want to specify <parameter>psw</parameter>. If there is no password, but you want to specify
options, you need to give an empty password. options, you need to give an empty password.
</para> </para>
<para> <para>
Decrypting <type>bytea</> data with <function>pgp_pub_decrypt</> is disallowed. Decrypting <type>bytea</type> data with <function>pgp_pub_decrypt</function> is disallowed.
This is to avoid outputting invalid character data. Decrypting This is to avoid outputting invalid character data. Decrypting
originally textual data with <function>pgp_pub_decrypt_bytea</> is fine. originally textual data with <function>pgp_pub_decrypt_bytea</function> is fine.
</para> </para>
<para> <para>
The <parameter>options</> parameter can contain option settings, The <parameter>options</parameter> parameter can contain option settings,
as described below. as described below.
</para> </para>
</sect3> </sect3>
@ -644,7 +644,7 @@ pgp_pub_decrypt_bytea(msg bytea, key bytea [, psw text [, options text ]]) retur
pgp_key_id(bytea) returns text pgp_key_id(bytea) returns text
</synopsis> </synopsis>
<para> <para>
<function>pgp_key_id</> extracts the key ID of a PGP public or secret key. <function>pgp_key_id</function> extracts the key ID of a PGP public or secret key.
Or it gives the key ID that was used for encrypting the data, if given Or it gives the key ID that was used for encrypting the data, if given
an encrypted message. an encrypted message.
</para> </para>
@ -654,7 +654,7 @@ pgp_key_id(bytea) returns text
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
<literal>SYMKEY</> <literal>SYMKEY</literal>
</para> </para>
<para> <para>
The message is encrypted with a symmetric key. The message is encrypted with a symmetric key.
@ -662,12 +662,12 @@ pgp_key_id(bytea) returns text
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<literal>ANYKEY</> <literal>ANYKEY</literal>
</para> </para>
<para> <para>
The message is public-key encrypted, but the key ID has been removed. The message is public-key encrypted, but the key ID has been removed.
That means you will need to try all your secret keys on it to see That means you will need to try all your secret keys on it to see
which one decrypts it. <filename>pgcrypto</> itself does not produce which one decrypts it. <filename>pgcrypto</filename> itself does not produce
such messages. such messages.
</para> </para>
</listitem> </listitem>
@ -675,7 +675,7 @@ pgp_key_id(bytea) returns text
<para> <para>
Note that different keys may have the same ID. This is rare but a normal Note that different keys may have the same ID. This is rare but a normal
event. The client application should then try to decrypt with each one, event. The client application should then try to decrypt with each one,
to see which fits &mdash; like handling <literal>ANYKEY</>. to see which fits &mdash; like handling <literal>ANYKEY</literal>.
</para> </para>
</sect3> </sect3>
@ -700,8 +700,8 @@ dearmor(data text) returns bytea
</para> </para>
<para> <para>
If the <parameter>keys</> and <parameter>values</> arrays are specified, If the <parameter>keys</parameter> and <parameter>values</parameter> arrays are specified,
an <firstterm>armor header</> is added to the armored format for each an <firstterm>armor header</firstterm> is added to the armored format for each
key/value pair. Both arrays must be single-dimensional, and they must key/value pair. Both arrays must be single-dimensional, and they must
be of the same length. The keys and values cannot contain any non-ASCII be of the same length. The keys and values cannot contain any non-ASCII
characters. characters.
@ -719,8 +719,8 @@ dearmor(data text) returns bytea
pgp_armor_headers(data text, key out text, value out text) returns setof record pgp_armor_headers(data text, key out text, value out text) returns setof record
</synopsis> </synopsis>
<para> <para>
<function>pgp_armor_headers()</> extracts the armor headers from <function>pgp_armor_headers()</function> extracts the armor headers from
<parameter>data</>. The return value is a set of rows with two columns, <parameter>data</parameter>. The return value is a set of rows with two columns,
key and value. If the keys or values contain any non-ASCII characters, key and value. If the keys or values contain any non-ASCII characters,
they are treated as UTF-8. they are treated as UTF-8.
</para> </para>
@ -924,7 +924,7 @@ gpg --gen-key
</programlisting> </programlisting>
</para> </para>
<para> <para>
The preferred key type is <quote>DSA and Elgamal</>. The preferred key type is <quote>DSA and Elgamal</quote>.
</para> </para>
<para> <para>
For RSA encryption you must create either DSA or RSA sign-only key For RSA encryption you must create either DSA or RSA sign-only key
@ -950,7 +950,7 @@ gpg -a --export-secret-keys KEYID > secret.key
</programlisting> </programlisting>
</para> </para>
<para> <para>
You need to use <function>dearmor()</> on these keys before giving them to You need to use <function>dearmor()</function> on these keys before giving them to
the PGP functions. Or if you can handle binary data, you can drop the PGP functions. Or if you can handle binary data, you can drop
<literal>-a</literal> from the command. <literal>-a</literal> from the command.
</para> </para>
@ -982,7 +982,7 @@ gpg -a --export-secret-keys KEYID > secret.key
<para> <para>
No support for several subkeys. This may seem like a problem, as this No support for several subkeys. This may seem like a problem, as this
is common practice. On the other hand, you should not use your regular is common practice. On the other hand, you should not use your regular
GPG/PGP keys with <filename>pgcrypto</>, but create new ones, GPG/PGP keys with <filename>pgcrypto</filename>, but create new ones,
as the usage scenario is rather different. as the usage scenario is rather different.
</para> </para>
</listitem> </listitem>
@ -1056,15 +1056,15 @@ decrypt_iv(data bytea, key bytea, iv bytea, type text) returns bytea
<parameter>type</parameter> string is: <parameter>type</parameter> string is:
<synopsis> <synopsis>
<replaceable>algorithm</> <optional> <literal>-</> <replaceable>mode</> </optional> <optional> <literal>/pad:</> <replaceable>padding</> </optional> <replaceable>algorithm</replaceable> <optional> <literal>-</literal> <replaceable>mode</replaceable> </optional> <optional> <literal>/pad:</literal> <replaceable>padding</replaceable> </optional>
</synopsis> </synopsis>
where <replaceable>algorithm</> is one of: where <replaceable>algorithm</replaceable> is one of:
<itemizedlist> <itemizedlist>
<listitem><para><literal>bf</literal> &mdash; Blowfish</para></listitem> <listitem><para><literal>bf</literal> &mdash; Blowfish</para></listitem>
<listitem><para><literal>aes</literal> &mdash; AES (Rijndael-128)</para></listitem> <listitem><para><literal>aes</literal> &mdash; AES (Rijndael-128)</para></listitem>
</itemizedlist> </itemizedlist>
and <replaceable>mode</> is one of: and <replaceable>mode</replaceable> is one of:
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
@ -1078,7 +1078,7 @@ decrypt_iv(data bytea, key bytea, iv bytea, type text) returns bytea
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
and <replaceable>padding</> is one of: and <replaceable>padding</replaceable> is one of:
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
@ -1100,8 +1100,8 @@ encrypt(data, 'fooz', 'bf-cbc/pad:pkcs')
</programlisting> </programlisting>
</para> </para>
<para> <para>
In <function>encrypt_iv</> and <function>decrypt_iv</>, the In <function>encrypt_iv</function> and <function>decrypt_iv</function>, the
<parameter>iv</> parameter is the initial value for the CBC mode; <parameter>iv</parameter> parameter is the initial value for the CBC mode;
it is ignored for ECB. it is ignored for ECB.
It is clipped or padded with zeroes if not exactly block size. It is clipped or padded with zeroes if not exactly block size.
It defaults to all zeroes in the functions without this parameter. It defaults to all zeroes in the functions without this parameter.
@ -1119,7 +1119,7 @@ encrypt(data, 'fooz', 'bf-cbc/pad:pkcs')
gen_random_bytes(count integer) returns bytea gen_random_bytes(count integer) returns bytea
</synopsis> </synopsis>
<para> <para>
Returns <parameter>count</> cryptographically strong random bytes. Returns <parameter>count</parameter> cryptographically strong random bytes.
At most 1024 bytes can be extracted at a time. This is to avoid At most 1024 bytes can be extracted at a time. This is to avoid
draining the randomness generator pool. draining the randomness generator pool.
</para> </para>
@ -1143,7 +1143,7 @@ gen_random_uuid() returns uuid
<title>Configuration</title> <title>Configuration</title>
<para> <para>
<filename>pgcrypto</> configures itself according to the findings of the <filename>pgcrypto</filename> configures itself according to the findings of the
main PostgreSQL <literal>configure</literal> script. The options that main PostgreSQL <literal>configure</literal> script. The options that
affect it are <literal>--with-zlib</literal> and affect it are <literal>--with-zlib</literal> and
<literal>--with-openssl</literal>. <literal>--with-openssl</literal>.
@ -1253,9 +1253,9 @@ gen_random_uuid() returns uuid
<title>Security Limitations</title> <title>Security Limitations</title>
<para> <para>
All <filename>pgcrypto</> functions run inside the database server. All <filename>pgcrypto</filename> functions run inside the database server.
That means that all That means that all
the data and passwords move between <filename>pgcrypto</> and client the data and passwords move between <filename>pgcrypto</filename> and client
applications in clear text. Thus you must: applications in clear text. Thus you must:
</para> </para>
@ -1276,7 +1276,7 @@ gen_random_uuid() returns uuid
The implementation does not resist The implementation does not resist
<ulink url="http://en.wikipedia.org/wiki/Side-channel_attack">side-channel <ulink url="http://en.wikipedia.org/wiki/Side-channel_attack">side-channel
attacks</ulink>. For example, the time required for attacks</ulink>. For example, the time required for
a <filename>pgcrypto</> decryption function to complete varies among a <filename>pgcrypto</filename> decryption function to complete varies among
ciphertexts of a given size. ciphertexts of a given size.
</para> </para>
</sect3> </sect3>
@ -1342,7 +1342,7 @@ gen_random_uuid() returns uuid
</listitem> </listitem>
<listitem> <listitem>
<para><ulink url="http://jlcooke.ca/random/"></ulink></para> <para><ulink url="http://jlcooke.ca/random/"></ulink></para>
<para>Jean-Luc Cooke Fortuna-based <filename>/dev/random</> driver for Linux.</para> <para>Jean-Luc Cooke Fortuna-based <filename>/dev/random</filename> driver for Linux.</para>
</listitem> </listitem>
<listitem> <listitem>
<para><ulink url="http://kodu.ut.ee/~lipmaa/crypto/"></ulink></para> <para><ulink url="http://kodu.ut.ee/~lipmaa/crypto/"></ulink></para>

View File

@ -8,7 +8,7 @@
</indexterm> </indexterm>
<para> <para>
The <filename>pg_freespacemap</> module provides a means for examining the The <filename>pg_freespacemap</filename> module provides a means for examining the
free space map (FSM). It provides a function called free space map (FSM). It provides a function called
<function>pg_freespace</function>, or two overloaded functions, to be <function>pg_freespace</function>, or two overloaded functions, to be
precise. The functions show the value recorded in the free space map for precise. The functions show the value recorded in the free space map for
@ -36,7 +36,7 @@
<listitem> <listitem>
<para> <para>
Returns the amount of free space on the page of the relation, specified Returns the amount of free space on the page of the relation, specified
by <literal>blkno</>, according to the FSM. by <literal>blkno</literal>, according to the FSM.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -50,7 +50,7 @@
<listitem> <listitem>
<para> <para>
Displays the amount of free space on each page of the relation, Displays the amount of free space on each page of the relation,
according to the FSM. A set of <literal>(blkno bigint, avail int2)</> according to the FSM. A set of <literal>(blkno bigint, avail int2)</literal>
tuples is returned, one tuple for each page in the relation. tuples is returned, one tuple for each page in the relation.
</para> </para>
</listitem> </listitem>
@ -59,7 +59,7 @@
<para> <para>
The values stored in the free space map are not exact. They're rounded The values stored in the free space map are not exact. They're rounded
to precision of 1/256th of <symbol>BLCKSZ</> (32 bytes with default <symbol>BLCKSZ</>), and to precision of 1/256th of <symbol>BLCKSZ</symbol> (32 bytes with default <symbol>BLCKSZ</symbol>), and
they're not kept fully up-to-date as tuples are inserted and updated. they're not kept fully up-to-date as tuples are inserted and updated.
</para> </para>

View File

@ -11,11 +11,11 @@
The <filename>pg_prewarm</filename> module provides a convenient way The <filename>pg_prewarm</filename> module provides a convenient way
to load relation data into either the operating system buffer cache to load relation data into either the operating system buffer cache
or the <productname>PostgreSQL</productname> buffer cache. Prewarming or the <productname>PostgreSQL</productname> buffer cache. Prewarming
can be performed manually using the <filename>pg_prewarm</> function, can be performed manually using the <filename>pg_prewarm</filename> function,
or can be performed automatically by including <literal>pg_prewarm</> in or can be performed automatically by including <literal>pg_prewarm</literal> in
<xref linkend="guc-shared-preload-libraries">. In the latter case, the <xref linkend="guc-shared-preload-libraries">. In the latter case, the
system will run a background worker which periodically records the contents system will run a background worker which periodically records the contents
of shared buffers in a file called <filename>autoprewarm.blocks</> and of shared buffers in a file called <filename>autoprewarm.blocks</filename> and
will, using 2 background workers, reload those same blocks after a restart. will, using 2 background workers, reload those same blocks after a restart.
</para> </para>
@ -77,10 +77,10 @@ autoprewarm_dump_now() RETURNS int8
</synopsis> </synopsis>
<para> <para>
Update <filename>autoprewarm.blocks</> immediately. This may be useful Update <filename>autoprewarm.blocks</filename> immediately. This may be useful
if the autoprewarm worker is not running but you anticipate running it if the autoprewarm worker is not running but you anticipate running it
after the next restart. The return value is the number of records written after the next restart. The return value is the number of records written
to <filename>autoprewarm.blocks</>. to <filename>autoprewarm.blocks</filename>.
</para> </para>
</sect2> </sect2>
@ -92,7 +92,7 @@ autoprewarm_dump_now() RETURNS int8
<term> <term>
<varname>pg_prewarm.autoprewarm</varname> (<type>boolean</type>) <varname>pg_prewarm.autoprewarm</varname> (<type>boolean</type>)
<indexterm> <indexterm>
<primary><varname>pg_prewarm.autoprewarm</> configuration parameter</primary> <primary><varname>pg_prewarm.autoprewarm</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
@ -109,12 +109,12 @@ autoprewarm_dump_now() RETURNS int8
<term> <term>
<varname>pg_prewarm.autoprewarm_interval</varname> (<type>int</type>) <varname>pg_prewarm.autoprewarm_interval</varname> (<type>int</type>)
<indexterm> <indexterm>
<primary><varname>pg_prewarm.autoprewarm_interval</> configuration parameter</primary> <primary><varname>pg_prewarm.autoprewarm_interval</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
This is the interval between updates to <literal>autoprewarm.blocks</>. This is the interval between updates to <literal>autoprewarm.blocks</literal>.
The default is 300 seconds. If set to 0, the file will not be The default is 300 seconds. If set to 0, the file will not be
dumped at regular intervals, but only when the server is shut down. dumped at regular intervals, but only when the server is shut down.
</para> </para>

View File

@ -37,7 +37,7 @@ pgrowlocks(text) returns setof record
</para> </para>
<table id="pgrowlocks-columns"> <table id="pgrowlocks-columns">
<title><function>pgrowlocks</> Output Columns</title> <title><function>pgrowlocks</function> Output Columns</title>
<tgroup cols="3"> <tgroup cols="3">
<thead> <thead>
@ -73,9 +73,9 @@ pgrowlocks(text) returns setof record
<entry><structfield>lock_type</structfield></entry> <entry><structfield>lock_type</structfield></entry>
<entry><type>text[]</type></entry> <entry><type>text[]</type></entry>
<entry>Lock mode of lockers (more than one if multitransaction), <entry>Lock mode of lockers (more than one if multitransaction),
an array of <literal>Key Share</>, <literal>Share</>, an array of <literal>Key Share</literal>, <literal>Share</literal>,
<literal>For No Key Update</>, <literal>No Key Update</>, <literal>For No Key Update</literal>, <literal>No Key Update</literal>,
<literal>For Update</>, <literal>Update</>.</entry> <literal>For Update</literal>, <literal>Update</literal>.</entry>
</row> </row>
<row> <row>
@ -89,7 +89,7 @@ pgrowlocks(text) returns setof record
</table> </table>
<para> <para>
<function>pgrowlocks</function> takes <literal>AccessShareLock</> for the <function>pgrowlocks</function> takes <literal>AccessShareLock</literal> for the
target table and reads each row one by one to collect the row locking target table and reads each row one by one to collect the row locking
information. This is not very speedy for a large table. Note that: information. This is not very speedy for a large table. Note that:
</para> </para>

View File

@ -31,14 +31,14 @@
<title>Description</title> <title>Description</title>
<para> <para>
<application>pg_standby</> supports creation of a <quote>warm standby</> <application>pg_standby</application> supports creation of a <quote>warm standby</quote>
database server. It is designed to be a production-ready program, as well database server. It is designed to be a production-ready program, as well
as a customizable template should you require specific modifications. as a customizable template should you require specific modifications.
</para> </para>
<para> <para>
<application>pg_standby</> is designed to be a waiting <application>pg_standby</application> is designed to be a waiting
<varname>restore_command</>, which is needed to turn a standard <varname>restore_command</varname>, which is needed to turn a standard
archive recovery into a warm standby operation. Other archive recovery into a warm standby operation. Other
configuration is required as well, all of which is described in the main configuration is required as well, all of which is described in the main
server manual (see <xref linkend="warm-standby">). server manual (see <xref linkend="warm-standby">).
@ -46,33 +46,33 @@
<para> <para>
To configure a standby To configure a standby
server to use <application>pg_standby</>, put this into its server to use <application>pg_standby</application>, put this into its
<filename>recovery.conf</filename> configuration file: <filename>recovery.conf</filename> configuration file:
<programlisting> <programlisting>
restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r' restore_command = 'pg_standby <replaceable>archiveDir</replaceable> %f %p %r'
</programlisting> </programlisting>
where <replaceable>archiveDir</> is the directory from which WAL segment where <replaceable>archiveDir</replaceable> is the directory from which WAL segment
files should be restored. files should be restored.
</para> </para>
<para> <para>
If <replaceable>restartwalfile</> is specified, normally by using the If <replaceable>restartwalfile</replaceable> is specified, normally by using the
<literal>%r</literal> macro, then all WAL files logically preceding this <literal>%r</literal> macro, then all WAL files logically preceding this
file will be removed from <replaceable>archivelocation</>. This minimizes file will be removed from <replaceable>archivelocation</replaceable>. This minimizes
the number of files that need to be retained, while preserving the number of files that need to be retained, while preserving
crash-restart capability. Use of this parameter is appropriate if the crash-restart capability. Use of this parameter is appropriate if the
<replaceable>archivelocation</> is a transient staging area for this <replaceable>archivelocation</replaceable> is a transient staging area for this
particular standby server, but <emphasis>not</> when the particular standby server, but <emphasis>not</emphasis> when the
<replaceable>archivelocation</> is intended as a long-term WAL archive area. <replaceable>archivelocation</replaceable> is intended as a long-term WAL archive area.
</para> </para>
<para> <para>
<application>pg_standby</application> assumes that <application>pg_standby</application> assumes that
<replaceable>archivelocation</> is a directory readable by the <replaceable>archivelocation</replaceable> is a directory readable by the
server-owning user. If <replaceable>restartwalfile</> (or <literal>-k</>) server-owning user. If <replaceable>restartwalfile</replaceable> (or <literal>-k</literal>)
is specified, is specified,
the <replaceable>archivelocation</> directory must be writable too. the <replaceable>archivelocation</replaceable> directory must be writable too.
</para> </para>
<para> <para>
There are two ways to fail over to a <quote>warm standby</> database server There are two ways to fail over to a <quote>warm standby</quote> database server
when the master server fails: when the master server fails:
<variablelist> <variablelist>
@ -85,7 +85,7 @@ restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r'
the standby server has fallen behind, but if there is a lot of the standby server has fallen behind, but if there is a lot of
unapplied WAL it can be a long time before the standby server becomes unapplied WAL it can be a long time before the standby server becomes
ready. To trigger a smart failover, create a trigger file containing ready. To trigger a smart failover, create a trigger file containing
the word <literal>smart</>, or just create it and leave it empty. the word <literal>smart</literal>, or just create it and leave it empty.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -96,8 +96,8 @@ restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r'
In fast failover, the server is brought up immediately. Any WAL files In fast failover, the server is brought up immediately. Any WAL files
in the archive that have not yet been applied will be ignored, and in the archive that have not yet been applied will be ignored, and
all transactions in those files are lost. To trigger a fast failover, all transactions in those files are lost. To trigger a fast failover,
create a trigger file and write the word <literal>fast</> into it. create a trigger file and write the word <literal>fast</literal> into it.
<application>pg_standby</> can also be configured to execute a fast <application>pg_standby</application> can also be configured to execute a fast
failover automatically if no new WAL file appears within a defined failover automatically if no new WAL file appears within a defined
interval. interval.
</para> </para>
@ -120,7 +120,7 @@ restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r'
<term><option>-c</option></term> <term><option>-c</option></term>
<listitem> <listitem>
<para> <para>
Use <literal>cp</> or <literal>copy</> command to restore WAL files Use <literal>cp</literal> or <literal>copy</literal> command to restore WAL files
from archive. This is the only supported behavior so this option is useless. from archive. This is the only supported behavior so this option is useless.
</para> </para>
</listitem> </listitem>
@ -130,7 +130,7 @@ restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r'
<term><option>-d</option></term> <term><option>-d</option></term>
<listitem> <listitem>
<para> <para>
Print lots of debug logging output on <filename>stderr</>. Print lots of debug logging output on <filename>stderr</filename>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -147,8 +147,8 @@ restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r'
<replaceable>restartwalfile</replaceable> is specified, since that <replaceable>restartwalfile</replaceable> is specified, since that
specification method is more accurate in determining the correct specification method is more accurate in determining the correct
archive cut-off point. archive cut-off point.
Use of this parameter is <emphasis>deprecated</> as of Use of this parameter is <emphasis>deprecated</emphasis> as of
<productname>PostgreSQL</> 8.3; it is safer and more efficient to <productname>PostgreSQL</productname> 8.3; it is safer and more efficient to
specify a <replaceable>restartwalfile</replaceable> parameter. A too specify a <replaceable>restartwalfile</replaceable> parameter. A too
small setting could result in removal of files that are still needed small setting could result in removal of files that are still needed
for a restart of the standby server, while a too large setting wastes for a restart of the standby server, while a too large setting wastes
@ -158,12 +158,12 @@ restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r'
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>-r</option> <replaceable>maxretries</></term> <term><option>-r</option> <replaceable>maxretries</replaceable></term>
<listitem> <listitem>
<para> <para>
Set the maximum number of times to retry the copy command if Set the maximum number of times to retry the copy command if
it fails (default 3). After each failure, we wait for it fails (default 3). After each failure, we wait for
<replaceable>sleeptime</> * <replaceable>num_retries</> <replaceable>sleeptime</replaceable> * <replaceable>num_retries</replaceable>
so that the wait time increases progressively. So by default, so that the wait time increases progressively. So by default,
we will wait 5 secs, 10 secs, then 15 secs before reporting we will wait 5 secs, 10 secs, then 15 secs before reporting
the failure back to the standby server. This will be the failure back to the standby server. This will be
@ -174,7 +174,7 @@ restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r'
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>-s</option> <replaceable>sleeptime</></term> <term><option>-s</option> <replaceable>sleeptime</replaceable></term>
<listitem> <listitem>
<para> <para>
Set the number of seconds (up to 60, default 5) to sleep between Set the number of seconds (up to 60, default 5) to sleep between
@ -186,21 +186,21 @@ restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r'
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>-t</option> <replaceable>triggerfile</></term> <term><option>-t</option> <replaceable>triggerfile</replaceable></term>
<listitem> <listitem>
<para> <para>
Specify a trigger file whose presence should cause failover. Specify a trigger file whose presence should cause failover.
It is recommended that you use a structured file name to It is recommended that you use a structured file name to
avoid confusion as to which server is being triggered avoid confusion as to which server is being triggered
when multiple servers exist on the same system; for example when multiple servers exist on the same system; for example
<filename>/tmp/pgsql.trigger.5432</>. <filename>/tmp/pgsql.trigger.5432</filename>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>-V</></term> <term><option>-V</option></term>
<term><option>--version</></term> <term><option>--version</option></term>
<listitem> <listitem>
<para> <para>
Print the <application>pg_standby</application> version and exit. Print the <application>pg_standby</application> version and exit.
@ -209,7 +209,7 @@ restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r'
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>-w</option> <replaceable>maxwaittime</></term> <term><option>-w</option> <replaceable>maxwaittime</replaceable></term>
<listitem> <listitem>
<para> <para>
Set the maximum number of seconds to wait for the next WAL file, Set the maximum number of seconds to wait for the next WAL file,
@ -222,8 +222,8 @@ restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r'
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>-?</></term> <term><option>-?</option></term>
<term><option>--help</></term> <term><option>--help</option></term>
<listitem> <listitem>
<para> <para>
Show help about <application>pg_standby</application> command line Show help about <application>pg_standby</application> command line
@ -241,18 +241,18 @@ restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r'
<para> <para>
<application>pg_standby</application> is designed to work with <application>pg_standby</application> is designed to work with
<productname>PostgreSQL</> 8.2 and later. <productname>PostgreSQL</productname> 8.2 and later.
</para> </para>
<para> <para>
<productname>PostgreSQL</> 8.3 provides the <literal>%r</literal> macro, <productname>PostgreSQL</productname> 8.3 provides the <literal>%r</literal> macro,
which is designed to let <application>pg_standby</application> know the which is designed to let <application>pg_standby</application> know the
last file it needs to keep. With <productname>PostgreSQL</> 8.2, the last file it needs to keep. With <productname>PostgreSQL</productname> 8.2, the
<literal>-k</literal> option must be used if archive cleanup is <literal>-k</literal> option must be used if archive cleanup is
required. This option remains available in 8.3, but its use is deprecated. required. This option remains available in 8.3, but its use is deprecated.
</para> </para>
<para> <para>
<productname>PostgreSQL</> 8.4 provides the <productname>PostgreSQL</productname> 8.4 provides the
<varname>recovery_end_command</> option. Without this option <varname>recovery_end_command</varname> option. Without this option
a leftover trigger file can be hazardous. a leftover trigger file can be hazardous.
</para> </para>
@ -276,13 +276,13 @@ restore_command = 'pg_standby -d -s 2 -t /tmp/pgsql.trigger.5442 .../archive %f
recovery_end_command = 'rm -f /tmp/pgsql.trigger.5442' recovery_end_command = 'rm -f /tmp/pgsql.trigger.5442'
</programlisting> </programlisting>
where the archive directory is physically located on the standby server, where the archive directory is physically located on the standby server,
so that the <varname>archive_command</> is accessing it across NFS, so that the <varname>archive_command</varname> is accessing it across NFS,
but the files are local to the standby (enabling use of <literal>ln</>). but the files are local to the standby (enabling use of <literal>ln</literal>).
This will: This will:
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
produce debugging output in <filename>standby.log</> produce debugging output in <filename>standby.log</filename>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
@ -293,7 +293,7 @@ recovery_end_command = 'rm -f /tmp/pgsql.trigger.5442'
<listitem> <listitem>
<para> <para>
stop waiting only when a trigger file called stop waiting only when a trigger file called
<filename>/tmp/pgsql.trigger.5442</> appears, <filename>/tmp/pgsql.trigger.5442</filename> appears,
and perform failover according to its content and perform failover according to its content
</para> </para>
</listitem> </listitem>
@ -320,18 +320,18 @@ restore_command = 'pg_standby -d -s 5 -t C:\pgsql.trigger.5442 ...\archive %f %p
recovery_end_command = 'del C:\pgsql.trigger.5442' recovery_end_command = 'del C:\pgsql.trigger.5442'
</programlisting> </programlisting>
Note that backslashes need to be doubled in the Note that backslashes need to be doubled in the
<varname>archive_command</>, but <emphasis>not</emphasis> in the <varname>archive_command</varname>, but <emphasis>not</emphasis> in the
<varname>restore_command</> or <varname>recovery_end_command</>. <varname>restore_command</varname> or <varname>recovery_end_command</varname>.
This will: This will:
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
use the <literal>copy</> command to restore WAL files from archive use the <literal>copy</literal> command to restore WAL files from archive
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
produce debugging output in <filename>standby.log</> produce debugging output in <filename>standby.log</filename>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
@ -342,7 +342,7 @@ recovery_end_command = 'del C:\pgsql.trigger.5442'
<listitem> <listitem>
<para> <para>
stop waiting only when a trigger file called stop waiting only when a trigger file called
<filename>C:\pgsql.trigger.5442</> appears, <filename>C:\pgsql.trigger.5442</filename> appears,
and perform failover according to its content and perform failover according to its content
</para> </para>
</listitem> </listitem>
@ -360,16 +360,16 @@ recovery_end_command = 'del C:\pgsql.trigger.5442'
</para> </para>
<para> <para>
The <literal>copy</> command on Windows sets the final file size The <literal>copy</literal> command on Windows sets the final file size
before the file is completely copied, which would ordinarily confuse before the file is completely copied, which would ordinarily confuse
<application>pg_standby</application>. Therefore <application>pg_standby</application>. Therefore
<application>pg_standby</application> waits <replaceable>sleeptime</> <application>pg_standby</application> waits <replaceable>sleeptime</replaceable>
seconds once it sees the proper file size. GNUWin32's <literal>cp</> seconds once it sees the proper file size. GNUWin32's <literal>cp</literal>
sets the file size only after the file copy is complete. sets the file size only after the file copy is complete.
</para> </para>
<para> <para>
Since the Windows example uses <literal>copy</> at both ends, either Since the Windows example uses <literal>copy</literal> at both ends, either
or both servers might be accessing the archive directory across the or both servers might be accessing the archive directory across the
network. network.
</para> </para>

View File

@ -13,20 +13,20 @@
</para> </para>
<para> <para>
The module must be loaded by adding <literal>pg_stat_statements</> to The module must be loaded by adding <literal>pg_stat_statements</literal> to
<xref linkend="guc-shared-preload-libraries"> in <xref linkend="guc-shared-preload-libraries"> in
<filename>postgresql.conf</>, because it requires additional shared memory. <filename>postgresql.conf</filename>, because it requires additional shared memory.
This means that a server restart is needed to add or remove the module. This means that a server restart is needed to add or remove the module.
</para> </para>
<para> <para>
When <filename>pg_stat_statements</filename> is loaded, it tracks When <filename>pg_stat_statements</filename> is loaded, it tracks
statistics across all databases of the server. To access and manipulate statistics across all databases of the server. To access and manipulate
these statistics, the module provides a view, <structname>pg_stat_statements</>, these statistics, the module provides a view, <structname>pg_stat_statements</structname>,
and the utility functions <function>pg_stat_statements_reset</> and and the utility functions <function>pg_stat_statements_reset</function> and
<function>pg_stat_statements</>. These are not available globally but <function>pg_stat_statements</function>. These are not available globally but
can be enabled for a specific database with can be enabled for a specific database with
<command>CREATE EXTENSION pg_stat_statements</>. <command>CREATE EXTENSION pg_stat_statements</command>.
</para> </para>
<sect2> <sect2>
@ -34,7 +34,7 @@
<para> <para>
The statistics gathered by the module are made available via a The statistics gathered by the module are made available via a
view named <structname>pg_stat_statements</>. This view view named <structname>pg_stat_statements</structname>. This view
contains one row for each distinct database ID, user ID and query contains one row for each distinct database ID, user ID and query
ID (up to the maximum number of distinct statements that the module ID (up to the maximum number of distinct statements that the module
can track). The columns of the view are shown in can track). The columns of the view are shown in
@ -42,7 +42,7 @@
</para> </para>
<table id="pgstatstatements-columns"> <table id="pgstatstatements-columns">
<title><structname>pg_stat_statements</> Columns</title> <title><structname>pg_stat_statements</structname> Columns</title>
<tgroup cols="4"> <tgroup cols="4">
<thead> <thead>
@ -234,9 +234,9 @@
</para> </para>
<para> <para>
Plannable queries (that is, <command>SELECT</>, <command>INSERT</>, Plannable queries (that is, <command>SELECT</command>, <command>INSERT</command>,
<command>UPDATE</>, and <command>DELETE</>) are combined into a single <command>UPDATE</command>, and <command>DELETE</command>) are combined into a single
<structname>pg_stat_statements</> entry whenever they have identical query <structname>pg_stat_statements</structname> entry whenever they have identical query
structures according to an internal hash calculation. Typically, two structures according to an internal hash calculation. Typically, two
queries will be considered the same for this purpose if they are queries will be considered the same for this purpose if they are
semantically equivalent except for the values of literal constants semantically equivalent except for the values of literal constants
@ -247,16 +247,16 @@
<para> <para>
When a constant's value has been ignored for purposes of matching the query When a constant's value has been ignored for purposes of matching the query
to other queries, the constant is replaced by a parameter symbol, such to other queries, the constant is replaced by a parameter symbol, such
as <literal>$1</literal>, in the <structname>pg_stat_statements</> as <literal>$1</literal>, in the <structname>pg_stat_statements</structname>
display. display.
The rest of the query text is that of the first query that had the The rest of the query text is that of the first query that had the
particular <structfield>queryid</> hash value associated with the particular <structfield>queryid</structfield> hash value associated with the
<structname>pg_stat_statements</> entry. <structname>pg_stat_statements</structname> entry.
</para> </para>
<para> <para>
In some cases, queries with visibly different texts might get merged into a In some cases, queries with visibly different texts might get merged into a
single <structname>pg_stat_statements</> entry. Normally this will happen single <structname>pg_stat_statements</structname> entry. Normally this will happen
only for semantically equivalent queries, but there is a small chance of only for semantically equivalent queries, but there is a small chance of
hash collisions causing unrelated queries to be merged into one entry. hash collisions causing unrelated queries to be merged into one entry.
(This cannot happen for queries belonging to different users or databases, (This cannot happen for queries belonging to different users or databases,
@ -264,41 +264,41 @@
</para> </para>
<para> <para>
Since the <structfield>queryid</> hash value is computed on the Since the <structfield>queryid</structfield> hash value is computed on the
post-parse-analysis representation of the queries, the opposite is post-parse-analysis representation of the queries, the opposite is
also possible: queries with identical texts might appear as also possible: queries with identical texts might appear as
separate entries, if they have different meanings as a result of separate entries, if they have different meanings as a result of
factors such as different <varname>search_path</> settings. factors such as different <varname>search_path</varname> settings.
</para> </para>
<para> <para>
Consumers of <structname>pg_stat_statements</> may wish to use Consumers of <structname>pg_stat_statements</structname> may wish to use
<structfield>queryid</> (perhaps in combination with <structfield>queryid</structfield> (perhaps in combination with
<structfield>dbid</> and <structfield>userid</>) as a more stable <structfield>dbid</structfield> and <structfield>userid</structfield>) as a more stable
and reliable identifier for each entry than its query text. and reliable identifier for each entry than its query text.
However, it is important to understand that there are only limited However, it is important to understand that there are only limited
guarantees around the stability of the <structfield>queryid</> hash guarantees around the stability of the <structfield>queryid</structfield> hash
value. Since the identifier is derived from the value. Since the identifier is derived from the
post-parse-analysis tree, its value is a function of, among other post-parse-analysis tree, its value is a function of, among other
things, the internal object identifiers appearing in this representation. things, the internal object identifiers appearing in this representation.
This has some counterintuitive implications. For example, This has some counterintuitive implications. For example,
<filename>pg_stat_statements</> will consider two apparently-identical <filename>pg_stat_statements</filename> will consider two apparently-identical
queries to be distinct, if they reference a table that was dropped queries to be distinct, if they reference a table that was dropped
and recreated between the executions of the two queries. and recreated between the executions of the two queries.
The hashing process is also sensitive to differences in The hashing process is also sensitive to differences in
machine architecture and other facets of the platform. machine architecture and other facets of the platform.
Furthermore, it is not safe to assume that <structfield>queryid</> Furthermore, it is not safe to assume that <structfield>queryid</structfield>
will be stable across major versions of <productname>PostgreSQL</>. will be stable across major versions of <productname>PostgreSQL</productname>.
</para> </para>
<para> <para>
As a rule of thumb, <structfield>queryid</> values can be assumed to be As a rule of thumb, <structfield>queryid</structfield> values can be assumed to be
stable and comparable only so long as the underlying server version and stable and comparable only so long as the underlying server version and
catalog metadata details stay exactly the same. Two servers catalog metadata details stay exactly the same. Two servers
participating in replication based on physical WAL replay can be expected participating in replication based on physical WAL replay can be expected
to have identical <structfield>queryid</> values for the same query. to have identical <structfield>queryid</structfield> values for the same query.
However, logical replication schemes do not promise to keep replicas However, logical replication schemes do not promise to keep replicas
identical in all relevant details, so <structfield>queryid</> will identical in all relevant details, so <structfield>queryid</structfield> will
not be a useful identifier for accumulating costs across a set of logical not be a useful identifier for accumulating costs across a set of logical
replicas. If in doubt, direct testing is recommended. replicas. If in doubt, direct testing is recommended.
</para> </para>
@ -306,13 +306,13 @@
<para> <para>
The parameter symbols used to replace constants in The parameter symbols used to replace constants in
representative query texts start from the next number after the representative query texts start from the next number after the
highest <literal>$</><replaceable>n</> parameter in the original query highest <literal>$</literal><replaceable>n</replaceable> parameter in the original query
text, or <literal>$1</> if there was none. It's worth noting that in text, or <literal>$1</literal> if there was none. It's worth noting that in
some cases there may be hidden parameter symbols that affect this some cases there may be hidden parameter symbols that affect this
numbering. For example, <application>PL/pgSQL</> uses hidden parameter numbering. For example, <application>PL/pgSQL</application> uses hidden parameter
symbols to insert values of function local variables into queries, so that symbols to insert values of function local variables into queries, so that
a <application>PL/pgSQL</> statement like <literal>SELECT i + 1 INTO j</> a <application>PL/pgSQL</application> statement like <literal>SELECT i + 1 INTO j</literal>
would have representative text like <literal>SELECT i + $2</>. would have representative text like <literal>SELECT i + $2</literal>.
</para> </para>
<para> <para>
@ -320,11 +320,11 @@
not consume shared memory. Therefore, even very lengthy query texts can not consume shared memory. Therefore, even very lengthy query texts can
be stored successfully. However, if many long query texts are be stored successfully. However, if many long query texts are
accumulated, the external file might grow unmanageably large. As a accumulated, the external file might grow unmanageably large. As a
recovery method if that happens, <filename>pg_stat_statements</> may recovery method if that happens, <filename>pg_stat_statements</filename> may
choose to discard the query texts, whereupon all existing entries in choose to discard the query texts, whereupon all existing entries in
the <structname>pg_stat_statements</> view will show the <structname>pg_stat_statements</structname> view will show
null <structfield>query</> fields, though the statistics associated with null <structfield>query</structfield> fields, though the statistics associated with
each <structfield>queryid</> are preserved. If this happens, consider each <structfield>queryid</structfield> are preserved. If this happens, consider
reducing <varname>pg_stat_statements.max</varname> to prevent reducing <varname>pg_stat_statements.max</varname> to prevent
recurrences. recurrences.
</para> </para>
@ -345,7 +345,7 @@
<listitem> <listitem>
<para> <para>
<function>pg_stat_statements_reset</function> discards all statistics <function>pg_stat_statements_reset</function> discards all statistics
gathered so far by <filename>pg_stat_statements</>. gathered so far by <filename>pg_stat_statements</filename>.
By default, this function can only be executed by superusers. By default, this function can only be executed by superusers.
</para> </para>
</listitem> </listitem>
@ -363,17 +363,17 @@
<listitem> <listitem>
<para> <para>
The <structname>pg_stat_statements</structname> view is defined in The <structname>pg_stat_statements</structname> view is defined in
terms of a function also named <function>pg_stat_statements</>. terms of a function also named <function>pg_stat_statements</function>.
It is possible for clients to call It is possible for clients to call
the <function>pg_stat_statements</function> function directly, and by the <function>pg_stat_statements</function> function directly, and by
specifying <literal>showtext := false</literal> have query text be specifying <literal>showtext := false</literal> have query text be
omitted (that is, the <literal>OUT</literal> argument that corresponds omitted (that is, the <literal>OUT</literal> argument that corresponds
to the view's <structfield>query</> column will return nulls). This to the view's <structfield>query</structfield> column will return nulls). This
feature is intended to support external tools that might wish to avoid feature is intended to support external tools that might wish to avoid
the overhead of repeatedly retrieving query texts of indeterminate the overhead of repeatedly retrieving query texts of indeterminate
length. Such tools can instead cache the first query text observed length. Such tools can instead cache the first query text observed
for each entry themselves, since that is for each entry themselves, since that is
all <filename>pg_stat_statements</> itself does, and then retrieve all <filename>pg_stat_statements</filename> itself does, and then retrieve
query texts only as needed. Since the server stores query texts in a query texts only as needed. Since the server stores query texts in a
file, this approach may reduce physical I/O for repeated examination file, this approach may reduce physical I/O for repeated examination
of the <structname>pg_stat_statements</structname> data. of the <structname>pg_stat_statements</structname> data.
@ -396,7 +396,7 @@
<para> <para>
<varname>pg_stat_statements.max</varname> is the maximum number of <varname>pg_stat_statements.max</varname> is the maximum number of
statements tracked by the module (i.e., the maximum number of rows statements tracked by the module (i.e., the maximum number of rows
in the <structname>pg_stat_statements</> view). If more distinct in the <structname>pg_stat_statements</structname> view). If more distinct
statements than that are observed, information about the least-executed statements than that are observed, information about the least-executed
statements is discarded. statements is discarded.
The default value is 5000. The default value is 5000.
@ -414,11 +414,11 @@
<para> <para>
<varname>pg_stat_statements.track</varname> controls which statements <varname>pg_stat_statements.track</varname> controls which statements
are counted by the module. are counted by the module.
Specify <literal>top</> to track top-level statements (those issued Specify <literal>top</literal> to track top-level statements (those issued
directly by clients), <literal>all</> to also track nested statements directly by clients), <literal>all</literal> to also track nested statements
(such as statements invoked within functions), or <literal>none</> to (such as statements invoked within functions), or <literal>none</literal> to
disable statement statistics collection. disable statement statistics collection.
The default value is <literal>top</>. The default value is <literal>top</literal>.
Only superusers can change this setting. Only superusers can change this setting.
</para> </para>
</listitem> </listitem>
@ -433,9 +433,9 @@
<para> <para>
<varname>pg_stat_statements.track_utility</varname> controls whether <varname>pg_stat_statements.track_utility</varname> controls whether
utility commands are tracked by the module. Utility commands are utility commands are tracked by the module. Utility commands are
all those other than <command>SELECT</>, <command>INSERT</>, all those other than <command>SELECT</command>, <command>INSERT</command>,
<command>UPDATE</> and <command>DELETE</>. <command>UPDATE</command> and <command>DELETE</command>.
The default value is <literal>on</>. The default value is <literal>on</literal>.
Only superusers can change this setting. Only superusers can change this setting.
</para> </para>
</listitem> </listitem>
@ -450,10 +450,10 @@
<para> <para>
<varname>pg_stat_statements.save</varname> specifies whether to <varname>pg_stat_statements.save</varname> specifies whether to
save statement statistics across server shutdowns. save statement statistics across server shutdowns.
If it is <literal>off</> then statistics are not saved at If it is <literal>off</literal> then statistics are not saved at
shutdown nor reloaded at server start. shutdown nor reloaded at server start.
The default value is <literal>on</>. The default value is <literal>on</literal>.
This parameter can only be set in the <filename>postgresql.conf</> This parameter can only be set in the <filename>postgresql.conf</filename>
file or on the server command line. file or on the server command line.
</para> </para>
</listitem> </listitem>
@ -464,11 +464,11 @@
The module requires additional shared memory proportional to The module requires additional shared memory proportional to
<varname>pg_stat_statements.max</varname>. Note that this <varname>pg_stat_statements.max</varname>. Note that this
memory is consumed whenever the module is loaded, even if memory is consumed whenever the module is loaded, even if
<varname>pg_stat_statements.track</> is set to <literal>none</>. <varname>pg_stat_statements.track</varname> is set to <literal>none</literal>.
</para> </para>
<para> <para>
These parameters must be set in <filename>postgresql.conf</>. These parameters must be set in <filename>postgresql.conf</filename>.
Typical usage might be: Typical usage might be:
<programlisting> <programlisting>

View File

@ -30,13 +30,13 @@
<indexterm> <indexterm>
<primary>pgstattuple</primary> <primary>pgstattuple</primary>
</indexterm> </indexterm>
<function>pgstattuple(regclass) returns record</> <function>pgstattuple(regclass) returns record</function>
</term> </term>
<listitem> <listitem>
<para> <para>
<function>pgstattuple</function> returns a relation's physical length, <function>pgstattuple</function> returns a relation's physical length,
percentage of <quote>dead</> tuples, and other info. This may help users percentage of <quote>dead</quote> tuples, and other info. This may help users
to determine whether vacuum is necessary or not. The argument is the to determine whether vacuum is necessary or not. The argument is the
target relation's name (optionally schema-qualified) or OID. target relation's name (optionally schema-qualified) or OID.
For example: For example:
@ -135,15 +135,15 @@ free_percent | 1.95
</para> </para>
<para> <para>
<function>pgstattuple</function> judges a tuple is <quote>dead</> if <function>pgstattuple</function> judges a tuple is <quote>dead</quote> if
<function>HeapTupleSatisfiesDirty</> returns false. <function>HeapTupleSatisfiesDirty</function> returns false.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<function>pgstattuple(text) returns record</> <function>pgstattuple(text) returns record</function>
</term> </term>
<listitem> <listitem>
@ -161,7 +161,7 @@ free_percent | 1.95
<indexterm> <indexterm>
<primary>pgstatindex</primary> <primary>pgstatindex</primary>
</indexterm> </indexterm>
<function>pgstatindex(regclass) returns record</> <function>pgstatindex(regclass) returns record</function>
</term> </term>
<listitem> <listitem>
@ -225,7 +225,7 @@ leaf_fragmentation | 0
<row> <row>
<entry><structfield>internal_pages</structfield></entry> <entry><structfield>internal_pages</structfield></entry>
<entry><type>bigint</type></entry> <entry><type>bigint</type></entry>
<entry>Number of <quote>internal</> (upper-level) pages</entry> <entry>Number of <quote>internal</quote> (upper-level) pages</entry>
</row> </row>
<row> <row>
@ -264,14 +264,14 @@ leaf_fragmentation | 0
</para> </para>
<para> <para>
The reported <literal>index_size</> will normally correspond to one more The reported <literal>index_size</literal> will normally correspond to one more
page than is accounted for by <literal>internal_pages + leaf_pages + page than is accounted for by <literal>internal_pages + leaf_pages +
empty_pages + deleted_pages</literal>, because it also includes the empty_pages + deleted_pages</literal>, because it also includes the
index's metapage. index's metapage.
</para> </para>
<para> <para>
As with <function>pgstattuple</>, the results are accumulated As with <function>pgstattuple</function>, the results are accumulated
page-by-page, and should not be expected to represent an page-by-page, and should not be expected to represent an
instantaneous snapshot of the whole index. instantaneous snapshot of the whole index.
</para> </para>
@ -280,7 +280,7 @@ leaf_fragmentation | 0
<varlistentry> <varlistentry>
<term> <term>
<function>pgstatindex(text) returns record</> <function>pgstatindex(text) returns record</function>
</term> </term>
<listitem> <listitem>
@ -298,7 +298,7 @@ leaf_fragmentation | 0
<indexterm> <indexterm>
<primary>pgstatginindex</primary> <primary>pgstatginindex</primary>
</indexterm> </indexterm>
<function>pgstatginindex(regclass) returns record</> <function>pgstatginindex(regclass) returns record</function>
</term> </term>
<listitem> <listitem>
@ -358,7 +358,7 @@ pending_tuples | 0
<indexterm> <indexterm>
<primary>pgstathashindex</primary> <primary>pgstathashindex</primary>
</indexterm> </indexterm>
<function>pgstathashindex(regclass) returns record</> <function>pgstathashindex(regclass) returns record</function>
</term> </term>
<listitem> <listitem>
@ -453,7 +453,7 @@ free_percent | 61.8005949100872
<indexterm> <indexterm>
<primary>pg_relpages</primary> <primary>pg_relpages</primary>
</indexterm> </indexterm>
<function>pg_relpages(regclass) returns bigint</> <function>pg_relpages(regclass) returns bigint</function>
</term> </term>
<listitem> <listitem>
@ -466,7 +466,7 @@ free_percent | 61.8005949100872
<varlistentry> <varlistentry>
<term> <term>
<function>pg_relpages(text) returns bigint</> <function>pg_relpages(text) returns bigint</function>
</term> </term>
<listitem> <listitem>
@ -484,7 +484,7 @@ free_percent | 61.8005949100872
<indexterm> <indexterm>
<primary>pgstattuple_approx</primary> <primary>pgstattuple_approx</primary>
</indexterm> </indexterm>
<function>pgstattuple_approx(regclass) returns record</> <function>pgstattuple_approx(regclass) returns record</function>
</term> </term>
<listitem> <listitem>

View File

@ -111,7 +111,7 @@
<entry><function>show_limit()</function><indexterm><primary>show_limit</primary></indexterm></entry> <entry><function>show_limit()</function><indexterm><primary>show_limit</primary></indexterm></entry>
<entry><type>real</type></entry> <entry><type>real</type></entry>
<entry> <entry>
Returns the current similarity threshold used by the <literal>%</> Returns the current similarity threshold used by the <literal>%</literal>
operator. This sets the minimum similarity between operator. This sets the minimum similarity between
two words for them to be considered similar enough to two words for them to be considered similar enough to
be misspellings of each other, for example be misspellings of each other, for example
@ -122,7 +122,7 @@
<entry><function>set_limit(real)</function><indexterm><primary>set_limit</primary></indexterm></entry> <entry><function>set_limit(real)</function><indexterm><primary>set_limit</primary></indexterm></entry>
<entry><type>real</type></entry> <entry><type>real</type></entry>
<entry> <entry>
Sets the current similarity threshold that is used by the <literal>%</> Sets the current similarity threshold that is used by the <literal>%</literal>
operator. The threshold must be between 0 and 1 (default is 0.3). operator. The threshold must be between 0 and 1 (default is 0.3).
Returns the same value passed in (<emphasis>deprecated</emphasis>). Returns the same value passed in (<emphasis>deprecated</emphasis>).
</entry> </entry>
@ -144,56 +144,56 @@
<tbody> <tbody>
<row> <row>
<entry><type>text</> <literal>%</literal> <type>text</></entry> <entry><type>text</type> <literal>%</literal> <type>text</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry> <entry>
Returns <literal>true</> if its arguments have a similarity that is Returns <literal>true</literal> if its arguments have a similarity that is
greater than the current similarity threshold set by greater than the current similarity threshold set by
<varname>pg_trgm.similarity_threshold</>. <varname>pg_trgm.similarity_threshold</varname>.
</entry> </entry>
</row> </row>
<row> <row>
<entry><type>text</> <literal>&lt;%</literal> <type>text</></entry> <entry><type>text</type> <literal>&lt;%</literal> <type>text</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry> <entry>
Returns <literal>true</> if its first argument has the similar word in Returns <literal>true</literal> if its first argument has the similar word in
the second argument and they have a similarity that is greater than the the second argument and they have a similarity that is greater than the
current word similarity threshold set by current word similarity threshold set by
<varname>pg_trgm.word_similarity_threshold</> parameter. <varname>pg_trgm.word_similarity_threshold</varname> parameter.
</entry> </entry>
</row> </row>
<row> <row>
<entry><type>text</> <literal>%&gt;</literal> <type>text</></entry> <entry><type>text</type> <literal>%&gt;</literal> <type>text</type></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry> <entry>
Commutator of the <literal>&lt;%</> operator. Commutator of the <literal>&lt;%</literal> operator.
</entry> </entry>
</row> </row>
<row> <row>
<entry><type>text</> <literal>&lt;-&gt;</literal> <type>text</></entry> <entry><type>text</type> <literal>&lt;-&gt;</literal> <type>text</type></entry>
<entry><type>real</type></entry> <entry><type>real</type></entry>
<entry> <entry>
Returns the <quote>distance</> between the arguments, that is Returns the <quote>distance</quote> between the arguments, that is
one minus the <function>similarity()</> value. one minus the <function>similarity()</function> value.
</entry> </entry>
</row> </row>
<row> <row>
<entry> <entry>
<type>text</> <literal>&lt;&lt;-&gt;</literal> <type>text</> <type>text</type> <literal>&lt;&lt;-&gt;</literal> <type>text</type>
</entry> </entry>
<entry><type>real</type></entry> <entry><type>real</type></entry>
<entry> <entry>
Returns the <quote>distance</> between the arguments, that is Returns the <quote>distance</quote> between the arguments, that is
one minus the <function>word_similarity()</> value. one minus the <function>word_similarity()</function> value.
</entry> </entry>
</row> </row>
<row> <row>
<entry> <entry>
<type>text</> <literal>&lt;-&gt;&gt;</literal> <type>text</> <type>text</type> <literal>&lt;-&gt;&gt;</literal> <type>text</type>
</entry> </entry>
<entry><type>real</type></entry> <entry><type>real</type></entry>
<entry> <entry>
Commutator of the <literal>&lt;&lt;-&gt;</> operator. Commutator of the <literal>&lt;&lt;-&gt;</literal> operator.
</entry> </entry>
</row> </row>
</tbody> </tbody>
@ -207,31 +207,31 @@
<variablelist> <variablelist>
<varlistentry id="guc-pgtrgm-similarity-threshold" xreflabel="pg_trgm.similarity_threshold"> <varlistentry id="guc-pgtrgm-similarity-threshold" xreflabel="pg_trgm.similarity_threshold">
<term> <term>
<varname>pg_trgm.similarity_threshold</> (<type>real</type>) <varname>pg_trgm.similarity_threshold</varname> (<type>real</type>)
<indexterm> <indexterm>
<primary><varname>pg_trgm.similarity_threshold</> configuration parameter</primary> <primary><varname>pg_trgm.similarity_threshold</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
Sets the current similarity threshold that is used by the <literal>%</> Sets the current similarity threshold that is used by the <literal>%</literal>
operator. The threshold must be between 0 and 1 (default is 0.3). operator. The threshold must be between 0 and 1 (default is 0.3).
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry id="guc-pgtrgm-word-similarity-threshold" xreflabel="pg_trgm.word_similarity_threshold"> <varlistentry id="guc-pgtrgm-word-similarity-threshold" xreflabel="pg_trgm.word_similarity_threshold">
<term> <term>
<varname>pg_trgm.word_similarity_threshold</> (<type>real</type>) <varname>pg_trgm.word_similarity_threshold</varname> (<type>real</type>)
<indexterm> <indexterm>
<primary> <primary>
<varname>pg_trgm.word_similarity_threshold</> configuration parameter <varname>pg_trgm.word_similarity_threshold</varname> configuration parameter
</primary> </primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
Sets the current word similarity threshold that is used by Sets the current word similarity threshold that is used by
<literal>&lt;%</> and <literal>%&gt;</> operators. The threshold <literal>&lt;%</literal> and <literal>%&gt;</literal> operators. The threshold
must be between 0 and 1 (default is 0.6). must be between 0 and 1 (default is 0.6).
</para> </para>
</listitem> </listitem>
@ -247,8 +247,8 @@
operator classes that allow you to create an index over a text column for operator classes that allow you to create an index over a text column for
the purpose of very fast similarity searches. These index types support the purpose of very fast similarity searches. These index types support
the above-described similarity operators, and additionally support the above-described similarity operators, and additionally support
trigram-based index searches for <literal>LIKE</>, <literal>ILIKE</>, trigram-based index searches for <literal>LIKE</literal>, <literal>ILIKE</literal>,
<literal>~</> and <literal>~*</> queries. (These indexes do not <literal>~</literal> and <literal>~*</literal> queries. (These indexes do not
support equality nor simple comparison operators, so you may need a support equality nor simple comparison operators, so you may need a
regular B-tree index too.) regular B-tree index too.)
</para> </para>
@ -267,16 +267,16 @@ CREATE INDEX trgm_idx ON test_trgm USING GIN (t gin_trgm_ops);
</para> </para>
<para> <para>
At this point, you will have an index on the <structfield>t</> column that At this point, you will have an index on the <structfield>t</structfield> column that
you can use for similarity searching. A typical query is you can use for similarity searching. A typical query is
<programlisting> <programlisting>
SELECT t, similarity(t, '<replaceable>word</>') AS sml SELECT t, similarity(t, '<replaceable>word</replaceable>') AS sml
FROM test_trgm FROM test_trgm
WHERE t % '<replaceable>word</>' WHERE t % '<replaceable>word</replaceable>'
ORDER BY sml DESC, t; ORDER BY sml DESC, t;
</programlisting> </programlisting>
This will return all values in the text column that are sufficiently This will return all values in the text column that are sufficiently
similar to <replaceable>word</>, sorted from best match to worst. The similar to <replaceable>word</replaceable>, sorted from best match to worst. The
index will be used to make this a fast operation even over very large data index will be used to make this a fast operation even over very large data
sets. sets.
</para> </para>
@ -284,7 +284,7 @@ SELECT t, similarity(t, '<replaceable>word</>') AS sml
<para> <para>
A variant of the above query is A variant of the above query is
<programlisting> <programlisting>
SELECT t, t &lt;-&gt; '<replaceable>word</>' AS dist SELECT t, t &lt;-&gt; '<replaceable>word</replaceable>' AS dist
FROM test_trgm FROM test_trgm
ORDER BY dist LIMIT 10; ORDER BY dist LIMIT 10;
</programlisting> </programlisting>
@ -294,16 +294,16 @@ SELECT t, t &lt;-&gt; '<replaceable>word</>' AS dist
</para> </para>
<para> <para>
Also you can use an index on the <structfield>t</> column for word Also you can use an index on the <structfield>t</structfield> column for word
similarity. For example: similarity. For example:
<programlisting> <programlisting>
SELECT t, word_similarity('<replaceable>word</>', t) AS sml SELECT t, word_similarity('<replaceable>word</replaceable>', t) AS sml
FROM test_trgm FROM test_trgm
WHERE '<replaceable>word</>' &lt;% t WHERE '<replaceable>word</replaceable>' &lt;% t
ORDER BY sml DESC, t; ORDER BY sml DESC, t;
</programlisting> </programlisting>
This will return all values in the text column that have a word This will return all values in the text column that have a word
which sufficiently similar to <replaceable>word</>, sorted from best which sufficiently similar to <replaceable>word</replaceable>, sorted from best
match to worst. The index will be used to make this a fast operation match to worst. The index will be used to make this a fast operation
even over very large data sets. even over very large data sets.
</para> </para>
@ -311,7 +311,7 @@ SELECT t, word_similarity('<replaceable>word</>', t) AS sml
<para> <para>
A variant of the above query is A variant of the above query is
<programlisting> <programlisting>
SELECT t, '<replaceable>word</>' &lt;&lt;-&gt; t AS dist SELECT t, '<replaceable>word</replaceable>' &lt;&lt;-&gt; t AS dist
FROM test_trgm FROM test_trgm
ORDER BY dist LIMIT 10; ORDER BY dist LIMIT 10;
</programlisting> </programlisting>
@ -321,8 +321,8 @@ SELECT t, '<replaceable>word</>' &lt;&lt;-&gt; t AS dist
<para> <para>
Beginning in <productname>PostgreSQL</> 9.1, these index types also support Beginning in <productname>PostgreSQL</productname> 9.1, these index types also support
index searches for <literal>LIKE</> and <literal>ILIKE</>, for example index searches for <literal>LIKE</literal> and <literal>ILIKE</literal>, for example
<programlisting> <programlisting>
SELECT * FROM test_trgm WHERE t LIKE '%foo%bar'; SELECT * FROM test_trgm WHERE t LIKE '%foo%bar';
</programlisting> </programlisting>
@ -333,9 +333,9 @@ SELECT * FROM test_trgm WHERE t LIKE '%foo%bar';
</para> </para>
<para> <para>
Beginning in <productname>PostgreSQL</> 9.3, these index types also support Beginning in <productname>PostgreSQL</productname> 9.3, these index types also support
index searches for regular-expression matches index searches for regular-expression matches
(<literal>~</> and <literal>~*</> operators), for example (<literal>~</literal> and <literal>~*</literal> operators), for example
<programlisting> <programlisting>
SELECT * FROM test_trgm WHERE t ~ '(foo|bar)'; SELECT * FROM test_trgm WHERE t ~ '(foo|bar)';
</programlisting> </programlisting>
@ -347,7 +347,7 @@ SELECT * FROM test_trgm WHERE t ~ '(foo|bar)';
</para> </para>
<para> <para>
For both <literal>LIKE</> and regular-expression searches, keep in mind For both <literal>LIKE</literal> and regular-expression searches, keep in mind
that a pattern with no extractable trigrams will degenerate to a full-index that a pattern with no extractable trigrams will degenerate to a full-index
scan. scan.
</para> </para>
@ -377,9 +377,9 @@ CREATE TABLE words AS SELECT word FROM
ts_stat('SELECT to_tsvector(''simple'', bodytext) FROM documents'); ts_stat('SELECT to_tsvector(''simple'', bodytext) FROM documents');
</programlisting> </programlisting>
where <structname>documents</> is a table that has a text field where <structname>documents</structname> is a table that has a text field
<structfield>bodytext</> that we wish to search. The reason for using <structfield>bodytext</structfield> that we wish to search. The reason for using
the <literal>simple</> configuration with the <function>to_tsvector</> the <literal>simple</literal> configuration with the <function>to_tsvector</function>
function, instead of using a language-specific configuration, function, instead of using a language-specific configuration,
is that we want a list of the original (unstemmed) words. is that we want a list of the original (unstemmed) words.
</para> </para>
@ -399,7 +399,7 @@ CREATE INDEX words_idx ON words USING GIN (word gin_trgm_ops);
<note> <note>
<para> <para>
Since the <structname>words</> table has been generated as a separate, Since the <structname>words</structname> table has been generated as a separate,
static table, it will need to be periodically regenerated so that static table, it will need to be periodically regenerated so that
it remains reasonably up-to-date with the document collection. it remains reasonably up-to-date with the document collection.
Keeping it exactly current is usually unnecessary. Keeping it exactly current is usually unnecessary.

View File

@ -8,7 +8,7 @@
</indexterm> </indexterm>
<para> <para>
The <filename>pg_visibility</> module provides a means for examining the The <filename>pg_visibility</filename> module provides a means for examining the
visibility map (VM) and page-level visibility information of a table. visibility map (VM) and page-level visibility information of a table.
It also provides functions to check the integrity of a visibility map and to It also provides functions to check the integrity of a visibility map and to
force it to be rebuilt. force it to be rebuilt.
@ -28,13 +28,13 @@
These two bits will normally agree, but the page's all-visible bit can These two bits will normally agree, but the page's all-visible bit can
sometimes be set while the visibility map bit is clear after a crash sometimes be set while the visibility map bit is clear after a crash
recovery. The reported values can also disagree because of a change that recovery. The reported values can also disagree because of a change that
occurs after <literal>pg_visibility</> examines the visibility map and occurs after <literal>pg_visibility</literal> examines the visibility map and
before it examines the data page. Any event that causes data corruption before it examines the data page. Any event that causes data corruption
can also cause these bits to disagree. can also cause these bits to disagree.
</para> </para>
<para> <para>
Functions that display information about <literal>PD_ALL_VISIBLE</> bits Functions that display information about <literal>PD_ALL_VISIBLE</literal> bits
are much more costly than those that only consult the visibility map, are much more costly than those that only consult the visibility map,
because they must read the relation's data blocks rather than only the because they must read the relation's data blocks rather than only the
(much smaller) visibility map. Functions that check the relation's (much smaller) visibility map. Functions that check the relation's
@ -61,7 +61,7 @@
<para> <para>
Returns the all-visible and all-frozen bits in the visibility map for Returns the all-visible and all-frozen bits in the visibility map for
the given block of the given relation, plus the the given block of the given relation, plus the
<literal>PD_ALL_VISIBLE</> bit of that block. <literal>PD_ALL_VISIBLE</literal> bit of that block.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -82,7 +82,7 @@
<listitem> <listitem>
<para> <para>
Returns the all-visible and all-frozen bits in the visibility map for Returns the all-visible and all-frozen bits in the visibility map for
each block of the given relation, plus the <literal>PD_ALL_VISIBLE</> each block of the given relation, plus the <literal>PD_ALL_VISIBLE</literal>
bit of each block. bit of each block.
</para> </para>
</listitem> </listitem>
@ -130,7 +130,7 @@
<para> <para>
Truncates the visibility map for the given relation. This function is Truncates the visibility map for the given relation. This function is
useful if you believe that the visibility map for the relation is useful if you believe that the visibility map for the relation is
corrupt and wish to force rebuilding it. The first <command>VACUUM</> corrupt and wish to force rebuilding it. The first <command>VACUUM</command>
executed on the given relation after this function is executed will scan executed on the given relation after this function is executed will scan
every page in the relation and rebuild the visibility map. (Until that every page in the relation and rebuild the visibility map. (Until that
is done, queries will treat the visibility map as containing all zeroes.) is done, queries will treat the visibility map as containing all zeroes.)

View File

@ -28,13 +28,13 @@
</indexterm> </indexterm>
<para> <para>
The examples shown below use tables in the <productname>PostgreSQL</> The examples shown below use tables in the <productname>PostgreSQL</productname>
regression test database. regression test database.
The outputs shown are taken from version 8.3. The outputs shown are taken from version 8.3.
The behavior of earlier (or later) versions might vary. The behavior of earlier (or later) versions might vary.
Note also that since <command>ANALYZE</> uses random sampling Note also that since <command>ANALYZE</command> uses random sampling
while producing statistics, the results will change slightly after while producing statistics, the results will change slightly after
any new <command>ANALYZE</>. any new <command>ANALYZE</command>.
</para> </para>
<para> <para>
@ -61,8 +61,8 @@ SELECT relpages, reltuples FROM pg_class WHERE relname = 'tenk1';
358 | 10000 358 | 10000
</programlisting> </programlisting>
These numbers are current as of the last <command>VACUUM</> or These numbers are current as of the last <command>VACUUM</command> or
<command>ANALYZE</> on the table. The planner then fetches the <command>ANALYZE</command> on the table. The planner then fetches the
actual current number of pages in the table (this is a cheap operation, actual current number of pages in the table (this is a cheap operation,
not requiring a table scan). If that is different from not requiring a table scan). If that is different from
<structfield>relpages</structfield> then <structfield>relpages</structfield> then
@ -150,7 +150,7 @@ EXPLAIN SELECT * FROM tenk1 WHERE stringu1 = 'CRAAAA';
and looks up the selectivity function for <literal>=</literal>, which is and looks up the selectivity function for <literal>=</literal>, which is
<function>eqsel</function>. For equality estimation the histogram is <function>eqsel</function>. For equality estimation the histogram is
not useful; instead the list of <firstterm>most not useful; instead the list of <firstterm>most
common values</> (<acronym>MCV</acronym>s) is used to determine the common values</firstterm> (<acronym>MCV</acronym>s) is used to determine the
selectivity. Let's have a look at the MCVs, with some additional columns selectivity. Let's have a look at the MCVs, with some additional columns
that will be useful later: that will be useful later:
@ -165,7 +165,7 @@ most_common_freqs | {0.00333333,0.003,0.003,0.003,0.003,0.003,0.003,0.003,0.003,
</programlisting> </programlisting>
Since <literal>CRAAAA</> appears in the list of MCVs, the selectivity is Since <literal>CRAAAA</literal> appears in the list of MCVs, the selectivity is
merely the corresponding entry in the list of most common frequencies merely the corresponding entry in the list of most common frequencies
(<acronym>MCF</acronym>s): (<acronym>MCF</acronym>s):
@ -225,18 +225,18 @@ rows = 10000 * 0.0014559
</para> </para>
<para> <para>
The previous example with <literal>unique1 &lt; 1000</> was an The previous example with <literal>unique1 &lt; 1000</literal> was an
oversimplification of what <function>scalarltsel</function> really does; oversimplification of what <function>scalarltsel</function> really does;
now that we have seen an example of the use of MCVs, we can fill in some now that we have seen an example of the use of MCVs, we can fill in some
more detail. The example was correct as far as it went, because since more detail. The example was correct as far as it went, because since
<structfield>unique1</> is a unique column it has no MCVs (obviously, no <structfield>unique1</structfield> is a unique column it has no MCVs (obviously, no
value is any more common than any other value). For a non-unique value is any more common than any other value). For a non-unique
column, there will normally be both a histogram and an MCV list, and column, there will normally be both a histogram and an MCV list, and
<emphasis>the histogram does not include the portion of the column <emphasis>the histogram does not include the portion of the column
population represented by the MCVs</>. We do things this way because population represented by the MCVs</emphasis>. We do things this way because
it allows more precise estimation. In this situation it allows more precise estimation. In this situation
<function>scalarltsel</function> directly applies the condition (e.g., <function>scalarltsel</function> directly applies the condition (e.g.,
<quote>&lt; 1000</>) to each value of the MCV list, and adds up the <quote>&lt; 1000</quote>) to each value of the MCV list, and adds up the
frequencies of the MCVs for which the condition is true. This gives frequencies of the MCVs for which the condition is true. This gives
an exact estimate of the selectivity within the portion of the table an exact estimate of the selectivity within the portion of the table
that is MCVs. The histogram is then used in the same way as above that is MCVs. The histogram is then used in the same way as above
@ -253,7 +253,7 @@ EXPLAIN SELECT * FROM tenk1 WHERE stringu1 &lt; 'IAAAAA';
Filter: (stringu1 &lt; 'IAAAAA'::name) Filter: (stringu1 &lt; 'IAAAAA'::name)
</programlisting> </programlisting>
We already saw the MCV information for <structfield>stringu1</>, We already saw the MCV information for <structfield>stringu1</structfield>,
and here is its histogram: and here is its histogram:
<programlisting> <programlisting>
@ -266,7 +266,7 @@ WHERE tablename='tenk1' AND attname='stringu1';
</programlisting> </programlisting>
Checking the MCV list, we find that the condition <literal>stringu1 &lt; Checking the MCV list, we find that the condition <literal>stringu1 &lt;
'IAAAAA'</> is satisfied by the first six entries and not the last four, 'IAAAAA'</literal> is satisfied by the first six entries and not the last four,
so the selectivity within the MCV part of the population is so the selectivity within the MCV part of the population is
<programlisting> <programlisting>
@ -279,11 +279,11 @@ selectivity = sum(relevant mvfs)
population represented by MCVs is 0.03033333, and therefore the population represented by MCVs is 0.03033333, and therefore the
fraction represented by the histogram is 0.96966667 (again, there fraction represented by the histogram is 0.96966667 (again, there
are no nulls, else we'd have to exclude them here). We can see are no nulls, else we'd have to exclude them here). We can see
that the value <literal>IAAAAA</> falls nearly at the end of the that the value <literal>IAAAAA</literal> falls nearly at the end of the
third histogram bucket. Using some rather cheesy assumptions third histogram bucket. Using some rather cheesy assumptions
about the frequency of different characters, the planner arrives about the frequency of different characters, the planner arrives
at the estimate 0.298387 for the portion of the histogram population at the estimate 0.298387 for the portion of the histogram population
that is less than <literal>IAAAAA</>. We then combine the estimates that is less than <literal>IAAAAA</literal>. We then combine the estimates
for the MCV and non-MCV populations: for the MCV and non-MCV populations:
<programlisting> <programlisting>
@ -372,7 +372,7 @@ rows = 10000 * 0.005035
= 50 (rounding off) = 50 (rounding off)
</programlisting> </programlisting>
The restriction for the join is <literal>t2.unique2 = t1.unique2</>. The restriction for the join is <literal>t2.unique2 = t1.unique2</literal>.
The operator is just The operator is just
our familiar <literal>=</literal>, however the selectivity function is our familiar <literal>=</literal>, however the selectivity function is
obtained from the <structfield>oprjoin</structfield> column of obtained from the <structfield>oprjoin</structfield> column of
@ -424,12 +424,12 @@ rows = (outer_cardinality * inner_cardinality) * selectivity
</para> </para>
<para> <para>
Notice that we showed <literal>inner_cardinality</> as 10000, that is, Notice that we showed <literal>inner_cardinality</literal> as 10000, that is,
the unmodified size of <structname>tenk2</>. It might appear from the unmodified size of <structname>tenk2</structname>. It might appear from
inspection of the <command>EXPLAIN</> output that the estimate of inspection of the <command>EXPLAIN</command> output that the estimate of
join rows comes from 50 * 1, that is, the number of outer rows times join rows comes from 50 * 1, that is, the number of outer rows times
the estimated number of rows obtained by each inner index scan on the estimated number of rows obtained by each inner index scan on
<structname>tenk2</>. But this is not the case: the join relation size <structname>tenk2</structname>. But this is not the case: the join relation size
is estimated before any particular join plan has been considered. If is estimated before any particular join plan has been considered. If
everything is working well then the two ways of estimating the join everything is working well then the two ways of estimating the join
size will produce about the same answer, but due to round-off error and size will produce about the same answer, but due to round-off error and
@ -438,7 +438,7 @@ rows = (outer_cardinality * inner_cardinality) * selectivity
<para> <para>
For those interested in further details, estimation of the size of For those interested in further details, estimation of the size of
a table (before any <literal>WHERE</> clauses) is done in a table (before any <literal>WHERE</literal> clauses) is done in
<filename>src/backend/optimizer/util/plancat.c</filename>. The generic <filename>src/backend/optimizer/util/plancat.c</filename>. The generic
logic for clause selectivities is in logic for clause selectivities is in
<filename>src/backend/optimizer/path/clausesel.c</filename>. The <filename>src/backend/optimizer/path/clausesel.c</filename>. The
@ -485,8 +485,8 @@ SELECT relpages, reltuples FROM pg_class WHERE relname = 't';
</para> </para>
<para> <para>
The following example shows the result of estimating a <literal>WHERE</> The following example shows the result of estimating a <literal>WHERE</literal>
condition on the <structfield>a</> column: condition on the <structfield>a</structfield> column:
<programlisting> <programlisting>
EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1; EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1;
@ -501,9 +501,9 @@ EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1;
of this clause to be 1%. By comparing this estimate and the actual of this clause to be 1%. By comparing this estimate and the actual
number of rows, we see that the estimate is very accurate number of rows, we see that the estimate is very accurate
(in fact exact, as the table is very small). Changing the (in fact exact, as the table is very small). Changing the
<literal>WHERE</> condition to use the <structfield>b</> column, an <literal>WHERE</literal> condition to use the <structfield>b</structfield> column, an
identical plan is generated. But observe what happens if we apply the same identical plan is generated. But observe what happens if we apply the same
condition on both columns, combining them with <literal>AND</>: condition on both columns, combining them with <literal>AND</literal>:
<programlisting> <programlisting>
EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1; EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
@ -524,7 +524,7 @@ EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
<para> <para>
This problem can be fixed by creating a statistics object that This problem can be fixed by creating a statistics object that
directs <command>ANALYZE</> to calculate functional-dependency directs <command>ANALYZE</command> to calculate functional-dependency
multivariate statistics on the two columns: multivariate statistics on the two columns:
<programlisting> <programlisting>

View File

@ -35,7 +35,7 @@
<para> <para>
The call handler is called in the same way as any other function: The call handler is called in the same way as any other function:
It receives a pointer to a It receives a pointer to a
<structname>FunctionCallInfoData</structname> <type>struct</> containing <structname>FunctionCallInfoData</structname> <type>struct</type> containing
argument values and information about the called function, and it argument values and information about the called function, and it
is expected to return a <type>Datum</type> result (and possibly is expected to return a <type>Datum</type> result (and possibly
set the <structfield>isnull</structfield> field of the set the <structfield>isnull</structfield> field of the
@ -54,7 +54,7 @@
<para> <para>
It's up to the call handler to fetch the entry of the function from the It's up to the call handler to fetch the entry of the function from the
<classname>pg_proc</classname> system catalog and to analyze the argument <classname>pg_proc</classname> system catalog and to analyze the argument
and return types of the called function. The <literal>AS</> clause from the and return types of the called function. The <literal>AS</literal> clause from the
<command>CREATE FUNCTION</command> command for the function will be found <command>CREATE FUNCTION</command> command for the function will be found
in the <literal>prosrc</literal> column of the in the <literal>prosrc</literal> column of the
<classname>pg_proc</classname> row. This is commonly source <classname>pg_proc</classname> row. This is commonly source
@ -68,9 +68,9 @@
A call handler can avoid repeated lookups of information about the A call handler can avoid repeated lookups of information about the
called function by using the called function by using the
<structfield>flinfo-&gt;fn_extra</structfield> field. This will <structfield>flinfo-&gt;fn_extra</structfield> field. This will
initially be <symbol>NULL</>, but can be set by the call handler to point at initially be <symbol>NULL</symbol>, but can be set by the call handler to point at
information about the called function. On subsequent calls, if information about the called function. On subsequent calls, if
<structfield>flinfo-&gt;fn_extra</structfield> is already non-<symbol>NULL</> <structfield>flinfo-&gt;fn_extra</structfield> is already non-<symbol>NULL</symbol>
then it can be used and the information lookup step skipped. The then it can be used and the information lookup step skipped. The
call handler must make sure that call handler must make sure that
<structfield>flinfo-&gt;fn_extra</structfield> is made to point at <structfield>flinfo-&gt;fn_extra</structfield> is made to point at
@ -90,7 +90,7 @@
are passed in the usual way, but the are passed in the usual way, but the
<structname>FunctionCallInfoData</structname>'s <structname>FunctionCallInfoData</structname>'s
<structfield>context</structfield> field points at a <structfield>context</structfield> field points at a
<structname>TriggerData</structname> structure, rather than being <symbol>NULL</> <structname>TriggerData</structname> structure, rather than being <symbol>NULL</symbol>
as it is in a plain function call. A language handler should as it is in a plain function call. A language handler should
provide mechanisms for procedural-language functions to get at the trigger provide mechanisms for procedural-language functions to get at the trigger
information. information.
@ -170,21 +170,21 @@ CREATE LANGUAGE plsample
<para> <para>
If a validator is provided by a procedural language, it If a validator is provided by a procedural language, it
must be declared as a function taking a single parameter of type must be declared as a function taking a single parameter of type
<type>oid</>. The validator's result is ignored, so it is customarily <type>oid</type>. The validator's result is ignored, so it is customarily
declared to return <type>void</>. The validator will be called at declared to return <type>void</type>. The validator will be called at
the end of a <command>CREATE FUNCTION</> command that has created the end of a <command>CREATE FUNCTION</command> command that has created
or updated a function written in the procedural language. or updated a function written in the procedural language.
The passed-in OID is the OID of the function's <classname>pg_proc</> The passed-in OID is the OID of the function's <classname>pg_proc</classname>
row. The validator must fetch this row in the usual way, and do row. The validator must fetch this row in the usual way, and do
whatever checking is appropriate. whatever checking is appropriate.
First, call <function>CheckFunctionValidatorAccess()</> to diagnose First, call <function>CheckFunctionValidatorAccess()</function> to diagnose
explicit calls to the validator that the user could not achieve through explicit calls to the validator that the user could not achieve through
<command>CREATE FUNCTION</>. Typical checks then include verifying <command>CREATE FUNCTION</command>. Typical checks then include verifying
that the function's argument and result types are supported by the that the function's argument and result types are supported by the
language, and that the function's body is syntactically correct language, and that the function's body is syntactically correct
in the language. If the validator finds the function to be okay, in the language. If the validator finds the function to be okay,
it should just return. If it finds an error, it should report that it should just return. If it finds an error, it should report that
via the normal <function>ereport()</> error reporting mechanism. via the normal <function>ereport()</function> error reporting mechanism.
Throwing an error will force a transaction rollback and thus prevent Throwing an error will force a transaction rollback and thus prevent
the incorrect function definition from being committed. the incorrect function definition from being committed.
</para> </para>
@ -195,40 +195,40 @@ CREATE LANGUAGE plsample
any expensive or context-sensitive checking should be skipped. If the any expensive or context-sensitive checking should be skipped. If the
language provides for code execution at compilation time, the validator language provides for code execution at compilation time, the validator
must suppress checks that would induce such execution. In particular, must suppress checks that would induce such execution. In particular,
this parameter is turned off by <application>pg_dump</> so that it can this parameter is turned off by <application>pg_dump</application> so that it can
load procedural language functions without worrying about side effects or load procedural language functions without worrying about side effects or
dependencies of the function bodies on other database objects. dependencies of the function bodies on other database objects.
(Because of this requirement, the call handler should avoid (Because of this requirement, the call handler should avoid
assuming that the validator has fully checked the function. The point assuming that the validator has fully checked the function. The point
of having a validator is not to let the call handler omit checks, but of having a validator is not to let the call handler omit checks, but
to notify the user immediately if there are obvious errors in a to notify the user immediately if there are obvious errors in a
<command>CREATE FUNCTION</> command.) <command>CREATE FUNCTION</command> command.)
While the choice of exactly what to check is mostly left to the While the choice of exactly what to check is mostly left to the
discretion of the validator function, note that the core discretion of the validator function, note that the core
<command>CREATE FUNCTION</> code only executes <literal>SET</> clauses <command>CREATE FUNCTION</command> code only executes <literal>SET</literal> clauses
attached to a function when <varname>check_function_bodies</> is on. attached to a function when <varname>check_function_bodies</varname> is on.
Therefore, checks whose results might be affected by GUC parameters Therefore, checks whose results might be affected by GUC parameters
definitely should be skipped when <varname>check_function_bodies</> is definitely should be skipped when <varname>check_function_bodies</varname> is
off, to avoid false failures when reloading a dump. off, to avoid false failures when reloading a dump.
</para> </para>
<para> <para>
If an inline handler is provided by a procedural language, it If an inline handler is provided by a procedural language, it
must be declared as a function taking a single parameter of type must be declared as a function taking a single parameter of type
<type>internal</>. The inline handler's result is ignored, so it is <type>internal</type>. The inline handler's result is ignored, so it is
customarily declared to return <type>void</>. The inline handler customarily declared to return <type>void</type>. The inline handler
will be called when a <command>DO</> statement is executed specifying will be called when a <command>DO</command> statement is executed specifying
the procedural language. The parameter actually passed is a pointer the procedural language. The parameter actually passed is a pointer
to an <structname>InlineCodeBlock</> struct, which contains information to an <structname>InlineCodeBlock</structname> struct, which contains information
about the <command>DO</> statement's parameters, in particular the about the <command>DO</command> statement's parameters, in particular the
text of the anonymous code block to be executed. The inline handler text of the anonymous code block to be executed. The inline handler
should execute this code and return. should execute this code and return.
</para> </para>
<para> <para>
It's recommended that you wrap all these function declarations, It's recommended that you wrap all these function declarations,
as well as the <command>CREATE LANGUAGE</> command itself, into as well as the <command>CREATE LANGUAGE</command> command itself, into
an <firstterm>extension</> so that a simple <command>CREATE EXTENSION</> an <firstterm>extension</firstterm> so that a simple <command>CREATE EXTENSION</command>
command is sufficient to install the language. See command is sufficient to install the language. See
<xref linkend="extend-extensions"> for information about writing <xref linkend="extend-extensions"> for information about writing
extensions. extensions.
@ -237,7 +237,7 @@ CREATE LANGUAGE plsample
<para> <para>
The procedural languages included in the standard distribution The procedural languages included in the standard distribution
are good references when trying to write your own language handler. are good references when trying to write your own language handler.
Look into the <filename>src/pl</> subdirectory of the source tree. Look into the <filename>src/pl</filename> subdirectory of the source tree.
The <xref linkend="sql-createlanguage"> The <xref linkend="sql-createlanguage">
reference page also has some useful details. reference page also has some useful details.
</para> </para>

View File

@ -27,12 +27,12 @@
<para> <para>
To install PL/Perl in a particular database, use To install PL/Perl in a particular database, use
<literal>CREATE EXTENSION plperl</>. <literal>CREATE EXTENSION plperl</literal>.
</para> </para>
<tip> <tip>
<para> <para>
If a language is installed into <literal>template1</>, all subsequently If a language is installed into <literal>template1</literal>, all subsequently
created databases will have the language installed automatically. created databases will have the language installed automatically.
</para> </para>
</tip> </tip>
@ -90,8 +90,8 @@ $$ LANGUAGE plperl;
subroutines which you call via a coderef. For more information, see the subroutines which you call via a coderef. For more information, see the
entries for <literal>Variable "%s" will not stay shared</literal> and entries for <literal>Variable "%s" will not stay shared</literal> and
<literal>Variable "%s" is not available</literal> in the <literal>Variable "%s" is not available</literal> in the
<citerefentry><refentrytitle>perldiag</></citerefentry> man page, or <citerefentry><refentrytitle>perldiag</refentrytitle></citerefentry> man page, or
search the Internet for <quote>perl nested named subroutine</>. search the Internet for <quote>perl nested named subroutine</quote>.
</para> </para>
</note> </note>
@ -100,16 +100,16 @@ $$ LANGUAGE plperl;
the function body to be written as a string constant. It is usually the function body to be written as a string constant. It is usually
most convenient to use dollar quoting (see <xref most convenient to use dollar quoting (see <xref
linkend="sql-syntax-dollar-quoting">) for the string constant. linkend="sql-syntax-dollar-quoting">) for the string constant.
If you choose to use escape string syntax <literal>E''</>, If you choose to use escape string syntax <literal>E''</literal>,
you must double any single quote marks (<literal>'</>) and backslashes you must double any single quote marks (<literal>'</literal>) and backslashes
(<literal>\</>) used in the body of the function (<literal>\</literal>) used in the body of the function
(see <xref linkend="sql-syntax-strings">). (see <xref linkend="sql-syntax-strings">).
</para> </para>
<para> <para>
Arguments and results are handled as in any other Perl subroutine: Arguments and results are handled as in any other Perl subroutine:
arguments are passed in <varname>@_</varname>, and a result value arguments are passed in <varname>@_</varname>, and a result value
is returned with <literal>return</> or as the last expression is returned with <literal>return</literal> or as the last expression
evaluated in the function. evaluated in the function.
</para> </para>
@ -134,12 +134,12 @@ $$ LANGUAGE plperl;
</note> </note>
<para> <para>
If an SQL null value<indexterm><primary>null value</><secondary If an SQL null value<indexterm><primary>null value</primary><secondary
sortas="PL/Perl">in PL/Perl</></indexterm> is passed to a function, sortas="PL/Perl">in PL/Perl</secondary></indexterm> is passed to a function,
the argument value will appear as <quote>undefined</> in Perl. The the argument value will appear as <quote>undefined</quote> in Perl. The
above function definition will not behave very nicely with null above function definition will not behave very nicely with null
inputs (in fact, it will act as though they are zeroes). We could inputs (in fact, it will act as though they are zeroes). We could
add <literal>STRICT</> to the function definition to make add <literal>STRICT</literal> to the function definition to make
<productname>PostgreSQL</productname> do something more reasonable: <productname>PostgreSQL</productname> do something more reasonable:
if a null value is passed, the function will not be called at all, if a null value is passed, the function will not be called at all,
but will just return a null result automatically. Alternatively, but will just return a null result automatically. Alternatively,
@ -174,14 +174,14 @@ $$ LANGUAGE plperl;
other cases the argument will need to be converted into a form that is other cases the argument will need to be converted into a form that is
more usable in Perl. For example, the <function>decode_bytea</function> more usable in Perl. For example, the <function>decode_bytea</function>
function can be used to convert an argument of function can be used to convert an argument of
type <type>bytea</> into unescaped binary. type <type>bytea</type> into unescaped binary.
</para> </para>
<para> <para>
Similarly, values passed back to <productname>PostgreSQL</productname> Similarly, values passed back to <productname>PostgreSQL</productname>
must be in the external text representation format. For example, the must be in the external text representation format. For example, the
<function>encode_bytea</function> function can be used to <function>encode_bytea</function> function can be used to
escape binary data for a return value of type <type>bytea</>. escape binary data for a return value of type <type>bytea</type>.
</para> </para>
<para> <para>
@ -330,10 +330,10 @@ SELECT * FROM perl_set();
</para> </para>
<para> <para>
If you wish to use the <literal>strict</> pragma with your code you If you wish to use the <literal>strict</literal> pragma with your code you
have a few options. For temporary global use you can <command>SET</> have a few options. For temporary global use you can <command>SET</command>
<literal>plperl.use_strict</literal> to true. <literal>plperl.use_strict</literal> to true.
This will affect subsequent compilations of <application>PL/Perl</> This will affect subsequent compilations of <application>PL/Perl</application>
functions, but not functions already compiled in the current session. functions, but not functions already compiled in the current session.
For permanent global use you can set <literal>plperl.use_strict</literal> For permanent global use you can set <literal>plperl.use_strict</literal>
to true in the <filename>postgresql.conf</filename> file. to true in the <filename>postgresql.conf</filename> file.
@ -348,7 +348,7 @@ use strict;
</para> </para>
<para> <para>
The <literal>feature</> pragma is also available to <function>use</> if your Perl is version 5.10.0 or higher. The <literal>feature</literal> pragma is also available to <function>use</function> if your Perl is version 5.10.0 or higher.
</para> </para>
</sect1> </sect1>
@ -380,7 +380,7 @@ use strict;
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term> <term>
<literal><function>spi_exec_query</>(<replaceable>query</replaceable> [, <replaceable>max-rows</replaceable>])</literal> <literal><function>spi_exec_query</function>(<replaceable>query</replaceable> [, <replaceable>max-rows</replaceable>])</literal>
<indexterm> <indexterm>
<primary>spi_exec_query</primary> <primary>spi_exec_query</primary>
<secondary>in PL/Perl</secondary> <secondary>in PL/Perl</secondary>
@ -524,13 +524,13 @@ SELECT * from lotsa_md5(500);
</para> </para>
<para> <para>
Normally, <function>spi_fetchrow</> should be repeated until it Normally, <function>spi_fetchrow</function> should be repeated until it
returns <literal>undef</literal>, indicating that there are no more returns <literal>undef</literal>, indicating that there are no more
rows to read. The cursor returned by <literal>spi_query</literal> rows to read. The cursor returned by <literal>spi_query</literal>
is automatically freed when is automatically freed when
<function>spi_fetchrow</> returns <literal>undef</literal>. <function>spi_fetchrow</function> returns <literal>undef</literal>.
If you do not wish to read all the rows, instead call If you do not wish to read all the rows, instead call
<function>spi_cursor_close</> to free the cursor. <function>spi_cursor_close</function> to free the cursor.
Failure to do so will result in memory leaks. Failure to do so will result in memory leaks.
</para> </para>
@ -675,13 +675,13 @@ SELECT release_hosts_query();
<listitem> <listitem>
<para> <para>
Emit a log or error message. Possible levels are Emit a log or error message. Possible levels are
<literal>DEBUG</>, <literal>LOG</>, <literal>INFO</>, <literal>DEBUG</literal>, <literal>LOG</literal>, <literal>INFO</literal>,
<literal>NOTICE</>, <literal>WARNING</>, and <literal>ERROR</>. <literal>NOTICE</literal>, <literal>WARNING</literal>, and <literal>ERROR</literal>.
<literal>ERROR</> <literal>ERROR</literal>
raises an error condition; if this is not trapped by the surrounding raises an error condition; if this is not trapped by the surrounding
Perl code, the error propagates out to the calling query, causing Perl code, the error propagates out to the calling query, causing
the current transaction or subtransaction to be aborted. This the current transaction or subtransaction to be aborted. This
is effectively the same as the Perl <literal>die</> command. is effectively the same as the Perl <literal>die</literal> command.
The other levels only generate messages of different The other levels only generate messages of different
priority levels. priority levels.
Whether messages of a particular priority are reported to the client, Whether messages of a particular priority are reported to the client,
@ -706,8 +706,8 @@ SELECT release_hosts_query();
<para> <para>
Return the given string suitably quoted to be used as a string literal in an SQL Return the given string suitably quoted to be used as a string literal in an SQL
statement string. Embedded single-quotes and backslashes are properly doubled. statement string. Embedded single-quotes and backslashes are properly doubled.
Note that <function>quote_literal</> returns undef on undef input; if the argument Note that <function>quote_literal</function> returns undef on undef input; if the argument
might be undef, <function>quote_nullable</> is often more suitable. might be undef, <function>quote_nullable</function> is often more suitable.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -849,7 +849,7 @@ SELECT release_hosts_query();
Returns a true value if the content of the given string looks like a Returns a true value if the content of the given string looks like a
number, according to Perl, returns false otherwise. number, according to Perl, returns false otherwise.
Returns undef if the argument is undef. Leading and trailing space is Returns undef if the argument is undef. Leading and trailing space is
ignored. <literal>Inf</> and <literal>Infinity</> are regarded as numbers. ignored. <literal>Inf</literal> and <literal>Infinity</literal> are regarded as numbers.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -865,8 +865,8 @@ SELECT release_hosts_query();
<listitem> <listitem>
<para> <para>
Returns a true value if the given argument may be treated as an Returns a true value if the given argument may be treated as an
array reference, that is, if ref of the argument is <literal>ARRAY</> or array reference, that is, if ref of the argument is <literal>ARRAY</literal> or
<literal>PostgreSQL::InServer::ARRAY</>. Returns false otherwise. <literal>PostgreSQL::InServer::ARRAY</literal>. Returns false otherwise.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -941,11 +941,11 @@ $$ LANGUAGE plperl;
PL/Perl functions will share the same value of <varname>%_SHARED</varname> PL/Perl functions will share the same value of <varname>%_SHARED</varname>
if and only if they are executed by the same SQL role. In an application if and only if they are executed by the same SQL role. In an application
wherein a single session executes code under multiple SQL roles (via wherein a single session executes code under multiple SQL roles (via
<literal>SECURITY DEFINER</> functions, use of <command>SET ROLE</>, etc) <literal>SECURITY DEFINER</literal> functions, use of <command>SET ROLE</command>, etc)
you may need to take explicit steps to ensure that PL/Perl functions can you may need to take explicit steps to ensure that PL/Perl functions can
share data via <varname>%_SHARED</varname>. To do that, make sure that share data via <varname>%_SHARED</varname>. To do that, make sure that
functions that should communicate are owned by the same user, and mark functions that should communicate are owned by the same user, and mark
them <literal>SECURITY DEFINER</>. You must of course take care that them <literal>SECURITY DEFINER</literal>. You must of course take care that
such functions can't be used to do anything unintended. such functions can't be used to do anything unintended.
</para> </para>
</sect1> </sect1>
@ -959,8 +959,8 @@ $$ LANGUAGE plperl;
</indexterm> </indexterm>
<para> <para>
Normally, PL/Perl is installed as a <quote>trusted</> programming Normally, PL/Perl is installed as a <quote>trusted</quote> programming
language named <literal>plperl</>. In this setup, certain Perl language named <literal>plperl</literal>. In this setup, certain Perl
operations are disabled to preserve security. In general, the operations are disabled to preserve security. In general, the
operations that are restricted are those that interact with the operations that are restricted are those that interact with the
environment. This includes file handle operations, environment. This includes file handle operations,
@ -993,15 +993,15 @@ $$ LANGUAGE plperl;
Sometimes it is desirable to write Perl functions that are not Sometimes it is desirable to write Perl functions that are not
restricted. For example, one might want a Perl function that sends restricted. For example, one might want a Perl function that sends
mail. To handle these cases, PL/Perl can also be installed as an mail. To handle these cases, PL/Perl can also be installed as an
<quote>untrusted</> language (usually called <quote>untrusted</quote> language (usually called
<application>PL/PerlU</application><indexterm><primary>PL/PerlU</></indexterm>). <application>PL/PerlU</application><indexterm><primary>PL/PerlU</primary></indexterm>).
In this case the full Perl language is available. When installing the In this case the full Perl language is available. When installing the
language, the language name <literal>plperlu</literal> will select language, the language name <literal>plperlu</literal> will select
the untrusted PL/Perl variant. the untrusted PL/Perl variant.
</para> </para>
<para> <para>
The writer of a <application>PL/PerlU</> function must take care that the function The writer of a <application>PL/PerlU</application> function must take care that the function
cannot be used to do anything unwanted, since it will be able to do cannot be used to do anything unwanted, since it will be able to do
anything that could be done by a user logged in as the database anything that could be done by a user logged in as the database
administrator. Note that the database system allows only database administrator. Note that the database system allows only database
@ -1010,25 +1010,25 @@ $$ LANGUAGE plperl;
<para> <para>
If the above function was created by a superuser using the language If the above function was created by a superuser using the language
<literal>plperlu</>, execution would succeed. <literal>plperlu</literal>, execution would succeed.
</para> </para>
<para> <para>
In the same way, anonymous code blocks written in Perl can use In the same way, anonymous code blocks written in Perl can use
restricted operations if the language is specified as restricted operations if the language is specified as
<literal>plperlu</> rather than <literal>plperl</>, but the caller <literal>plperlu</literal> rather than <literal>plperl</literal>, but the caller
must be a superuser. must be a superuser.
</para> </para>
<note> <note>
<para> <para>
While <application>PL/Perl</> functions run in a separate Perl While <application>PL/Perl</application> functions run in a separate Perl
interpreter for each SQL role, all <application>PL/PerlU</> functions interpreter for each SQL role, all <application>PL/PerlU</application> functions
executed in a given session run in a single Perl interpreter (which is executed in a given session run in a single Perl interpreter (which is
not any of the ones used for <application>PL/Perl</> functions). not any of the ones used for <application>PL/Perl</application> functions).
This allows <application>PL/PerlU</> functions to share data freely, This allows <application>PL/PerlU</application> functions to share data freely,
but no communication can occur between <application>PL/Perl</> and but no communication can occur between <application>PL/Perl</application> and
<application>PL/PerlU</> functions. <application>PL/PerlU</application> functions.
</para> </para>
</note> </note>
@ -1036,14 +1036,14 @@ $$ LANGUAGE plperl;
<para> <para>
Perl cannot support multiple interpreters within one process unless Perl cannot support multiple interpreters within one process unless
it was built with the appropriate flags, namely either it was built with the appropriate flags, namely either
<literal>usemultiplicity</> or <literal>useithreads</>. <literal>usemultiplicity</literal> or <literal>useithreads</literal>.
(<literal>usemultiplicity</> is preferred unless you actually need (<literal>usemultiplicity</literal> is preferred unless you actually need
to use threads. For more details, see the to use threads. For more details, see the
<citerefentry><refentrytitle>perlembed</></citerefentry> man page.) <citerefentry><refentrytitle>perlembed</refentrytitle></citerefentry> man page.)
If <application>PL/Perl</> is used with a copy of Perl that was not built If <application>PL/Perl</application> is used with a copy of Perl that was not built
this way, then it is only possible to have one Perl interpreter per this way, then it is only possible to have one Perl interpreter per
session, and so any one session can only execute either session, and so any one session can only execute either
<application>PL/PerlU</> functions, or <application>PL/Perl</> functions <application>PL/PerlU</application> functions, or <application>PL/Perl</application> functions
that are all called by the same SQL role. that are all called by the same SQL role.
</para> </para>
</note> </note>
@ -1056,7 +1056,7 @@ $$ LANGUAGE plperl;
<para> <para>
PL/Perl can be used to write trigger functions. In a trigger function, PL/Perl can be used to write trigger functions. In a trigger function,
the hash reference <varname>$_TD</varname> contains information about the the hash reference <varname>$_TD</varname> contains information about the
current trigger event. <varname>$_TD</> is a global variable, current trigger event. <varname>$_TD</varname> is a global variable,
which gets a separate local value for each invocation of the trigger. which gets a separate local value for each invocation of the trigger.
The fields of the <varname>$_TD</varname> hash reference are: The fields of the <varname>$_TD</varname> hash reference are:
@ -1092,8 +1092,8 @@ $$ LANGUAGE plperl;
<term><literal>$_TD-&gt;{event}</literal></term> <term><literal>$_TD-&gt;{event}</literal></term>
<listitem> <listitem>
<para> <para>
Trigger event: <literal>INSERT</>, <literal>UPDATE</>, Trigger event: <literal>INSERT</literal>, <literal>UPDATE</literal>,
<literal>DELETE</>, <literal>TRUNCATE</>, or <literal>UNKNOWN</> <literal>DELETE</literal>, <literal>TRUNCATE</literal>, or <literal>UNKNOWN</literal>
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1244,7 +1244,7 @@ CREATE TRIGGER test_valid_id_trig
<para> <para>
PL/Perl can be used to write event trigger functions. In an event trigger PL/Perl can be used to write event trigger functions. In an event trigger
function, the hash reference <varname>$_TD</varname> contains information function, the hash reference <varname>$_TD</varname> contains information
about the current trigger event. <varname>$_TD</> is a global variable, about the current trigger event. <varname>$_TD</varname> is a global variable,
which gets a separate local value for each invocation of the trigger. The which gets a separate local value for each invocation of the trigger. The
fields of the <varname>$_TD</varname> hash reference are: fields of the <varname>$_TD</varname> hash reference are:
@ -1295,7 +1295,7 @@ CREATE EVENT TRIGGER perl_a_snitch
<title>Configuration</title> <title>Configuration</title>
<para> <para>
This section lists configuration parameters that affect <application>PL/Perl</>. This section lists configuration parameters that affect <application>PL/Perl</application>.
</para> </para>
<variablelist> <variablelist>
@ -1304,14 +1304,14 @@ CREATE EVENT TRIGGER perl_a_snitch
<term> <term>
<varname>plperl.on_init</varname> (<type>string</type>) <varname>plperl.on_init</varname> (<type>string</type>)
<indexterm> <indexterm>
<primary><varname>plperl.on_init</> configuration parameter</primary> <primary><varname>plperl.on_init</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
Specifies Perl code to be executed when a Perl interpreter is first Specifies Perl code to be executed when a Perl interpreter is first
initialized, before it is specialized for use by <literal>plperl</> or initialized, before it is specialized for use by <literal>plperl</literal> or
<literal>plperlu</>. <literal>plperlu</literal>.
The SPI functions are not available when this code is executed. The SPI functions are not available when this code is executed.
If the code fails with an error it will abort the initialization of If the code fails with an error it will abort the initialization of
the interpreter and propagate out to the calling query, causing the the interpreter and propagate out to the calling query, causing the
@ -1319,7 +1319,7 @@ CREATE EVENT TRIGGER perl_a_snitch
</para> </para>
<para> <para>
The Perl code is limited to a single string. Longer code can be placed The Perl code is limited to a single string. Longer code can be placed
into a module and loaded by the <literal>on_init</> string. into a module and loaded by the <literal>on_init</literal> string.
Examples: Examples:
<programlisting> <programlisting>
plperl.on_init = 'require "plperlinit.pl"' plperl.on_init = 'require "plperlinit.pl"'
@ -1327,8 +1327,8 @@ plperl.on_init = 'use lib "/my/app"; use MyApp::PgInit;'
</programlisting> </programlisting>
</para> </para>
<para> <para>
Any modules loaded by <literal>plperl.on_init</>, either directly or Any modules loaded by <literal>plperl.on_init</literal>, either directly or
indirectly, will be available for use by <literal>plperl</>. This may indirectly, will be available for use by <literal>plperl</literal>. This may
create a security risk. To see what modules have been loaded you can use: create a security risk. To see what modules have been loaded you can use:
<programlisting> <programlisting>
DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl; DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl;
@ -1339,14 +1339,14 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl;
included in <xref linkend="guc-shared-preload-libraries">, in which included in <xref linkend="guc-shared-preload-libraries">, in which
case extra consideration should be given to the risk of destabilizing case extra consideration should be given to the risk of destabilizing
the postmaster. The principal reason for making use of this feature the postmaster. The principal reason for making use of this feature
is that Perl modules loaded by <literal>plperl.on_init</> need be is that Perl modules loaded by <literal>plperl.on_init</literal> need be
loaded only at postmaster start, and will be instantly available loaded only at postmaster start, and will be instantly available
without loading overhead in individual database sessions. However, without loading overhead in individual database sessions. However,
keep in mind that the overhead is avoided only for the first Perl keep in mind that the overhead is avoided only for the first Perl
interpreter used by a database session &mdash; either PL/PerlU, or interpreter used by a database session &mdash; either PL/PerlU, or
PL/Perl for the first SQL role that calls a PL/Perl function. Any PL/Perl for the first SQL role that calls a PL/Perl function. Any
additional Perl interpreters created in a database session will have additional Perl interpreters created in a database session will have
to execute <literal>plperl.on_init</> afresh. Also, on Windows there to execute <literal>plperl.on_init</literal> afresh. Also, on Windows there
will be no savings whatsoever from preloading, since the Perl will be no savings whatsoever from preloading, since the Perl
interpreter created in the postmaster process does not propagate to interpreter created in the postmaster process does not propagate to
child processes. child processes.
@ -1361,27 +1361,27 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl;
<term> <term>
<varname>plperl.on_plperl_init</varname> (<type>string</type>) <varname>plperl.on_plperl_init</varname> (<type>string</type>)
<indexterm> <indexterm>
<primary><varname>plperl.on_plperl_init</> configuration parameter</primary> <primary><varname>plperl.on_plperl_init</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<term> <term>
<varname>plperl.on_plperlu_init</varname> (<type>string</type>) <varname>plperl.on_plperlu_init</varname> (<type>string</type>)
<indexterm> <indexterm>
<primary><varname>plperl.on_plperlu_init</> configuration parameter</primary> <primary><varname>plperl.on_plperlu_init</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
These parameters specify Perl code to be executed when a Perl These parameters specify Perl code to be executed when a Perl
interpreter is specialized for <literal>plperl</> or interpreter is specialized for <literal>plperl</literal> or
<literal>plperlu</> respectively. This will happen when a PL/Perl or <literal>plperlu</literal> respectively. This will happen when a PL/Perl or
PL/PerlU function is first executed in a database session, or when PL/PerlU function is first executed in a database session, or when
an additional interpreter has to be created because the other language an additional interpreter has to be created because the other language
is called or a PL/Perl function is called by a new SQL role. This is called or a PL/Perl function is called by a new SQL role. This
follows any initialization done by <literal>plperl.on_init</>. follows any initialization done by <literal>plperl.on_init</literal>.
The SPI functions are not available when this code is executed. The SPI functions are not available when this code is executed.
The Perl code in <literal>plperl.on_plperl_init</> is executed after The Perl code in <literal>plperl.on_plperl_init</literal> is executed after
<quote>locking down</> the interpreter, and thus it can only perform <quote>locking down</quote> the interpreter, and thus it can only perform
trusted operations. trusted operations.
</para> </para>
<para> <para>
@ -1404,13 +1404,13 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl;
<term> <term>
<varname>plperl.use_strict</varname> (<type>boolean</type>) <varname>plperl.use_strict</varname> (<type>boolean</type>)
<indexterm> <indexterm>
<primary><varname>plperl.use_strict</> configuration parameter</primary> <primary><varname>plperl.use_strict</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
When set true subsequent compilations of PL/Perl functions will have When set true subsequent compilations of PL/Perl functions will have
the <literal>strict</> pragma enabled. This parameter does not affect the <literal>strict</literal> pragma enabled. This parameter does not affect
functions already compiled in the current session. functions already compiled in the current session.
</para> </para>
</listitem> </listitem>
@ -1459,7 +1459,7 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl;
<listitem> <listitem>
<para> <para>
When a session ends normally, not due to a fatal error, any When a session ends normally, not due to a fatal error, any
<literal>END</> blocks that have been defined are executed. <literal>END</literal> blocks that have been defined are executed.
Currently no other actions are performed. Specifically, Currently no other actions are performed. Specifically,
file handles are not automatically flushed and objects are file handles are not automatically flushed and objects are
not automatically destroyed. not automatically destroyed.

File diff suppressed because it is too large Load Diff

View File

@ -3,8 +3,8 @@
<chapter id="plpython"> <chapter id="plpython">
<title>PL/Python - Python Procedural Language</title> <title>PL/Python - Python Procedural Language</title>
<indexterm zone="plpython"><primary>PL/Python</></> <indexterm zone="plpython"><primary>PL/Python</primary></indexterm>
<indexterm zone="plpython"><primary>Python</></> <indexterm zone="plpython"><primary>Python</primary></indexterm>
<para> <para>
The <application>PL/Python</application> procedural language allows The <application>PL/Python</application> procedural language allows
@ -14,22 +14,22 @@
<para> <para>
To install PL/Python in a particular database, use To install PL/Python in a particular database, use
<literal>CREATE EXTENSION plpythonu</> (but <literal>CREATE EXTENSION plpythonu</literal> (but
see also <xref linkend="plpython-python23">). see also <xref linkend="plpython-python23">).
</para> </para>
<tip> <tip>
<para> <para>
If a language is installed into <literal>template1</>, all subsequently If a language is installed into <literal>template1</literal>, all subsequently
created databases will have the language installed automatically. created databases will have the language installed automatically.
</para> </para>
</tip> </tip>
<para> <para>
PL/Python is only available as an <quote>untrusted</> language, meaning PL/Python is only available as an <quote>untrusted</quote> language, meaning
it does not offer any way of restricting what users can do in it and it does not offer any way of restricting what users can do in it and
is therefore named <literal>plpythonu</>. A trusted is therefore named <literal>plpythonu</literal>. A trusted
variant <literal>plpython</> might become available in the future variant <literal>plpython</literal> might become available in the future
if a secure execution mechanism is developed in Python. The if a secure execution mechanism is developed in Python. The
writer of a function in untrusted PL/Python must take care that the writer of a function in untrusted PL/Python must take care that the
function cannot be used to do anything unwanted, since it will be function cannot be used to do anything unwanted, since it will be
@ -383,8 +383,8 @@ $$ LANGUAGE plpythonu;
For all other PostgreSQL return types, the return value is converted For all other PostgreSQL return types, the return value is converted
to a string using the Python built-in <literal>str</literal>, and the to a string using the Python built-in <literal>str</literal>, and the
result is passed to the input function of the PostgreSQL data type. result is passed to the input function of the PostgreSQL data type.
(If the Python value is a <type>float</>, it is converted using (If the Python value is a <type>float</type>, it is converted using
the <literal>repr</> built-in instead of <literal>str</literal>, to the <literal>repr</literal> built-in instead of <literal>str</literal>, to
avoid loss of precision.) avoid loss of precision.)
</para> </para>
@ -756,8 +756,8 @@ SELECT * FROM multiout_simple_setof(3);
data between function calls. This variable is private static data. data between function calls. This variable is private static data.
The global dictionary <varname>GD</varname> is public data, The global dictionary <varname>GD</varname> is public data,
available to all Python functions within a session. Use with available to all Python functions within a session. Use with
care.<indexterm><primary>global data</> care.<indexterm><primary>global data</primary>
<secondary>in PL/Python</></indexterm> <secondary>in PL/Python</secondary></indexterm>
</para> </para>
<para> <para>
@ -800,38 +800,38 @@ $$ LANGUAGE plpythonu;
<literal>TD</literal> contains trigger-related values: <literal>TD</literal> contains trigger-related values:
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><literal>TD["event"]</></term> <term><literal>TD["event"]</literal></term>
<listitem> <listitem>
<para> <para>
contains the event as a string: contains the event as a string:
<literal>INSERT</>, <literal>UPDATE</>, <literal>INSERT</literal>, <literal>UPDATE</literal>,
<literal>DELETE</>, or <literal>TRUNCATE</>. <literal>DELETE</literal>, or <literal>TRUNCATE</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>TD["when"]</></term> <term><literal>TD["when"]</literal></term>
<listitem> <listitem>
<para> <para>
contains one of <literal>BEFORE</>, <literal>AFTER</>, or contains one of <literal>BEFORE</literal>, <literal>AFTER</literal>, or
<literal>INSTEAD OF</>. <literal>INSTEAD OF</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>TD["level"]</></term> <term><literal>TD["level"]</literal></term>
<listitem> <listitem>
<para> <para>
contains <literal>ROW</> or <literal>STATEMENT</>. contains <literal>ROW</literal> or <literal>STATEMENT</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>TD["new"]</></term> <term><literal>TD["new"]</literal></term>
<term><literal>TD["old"]</></term> <term><literal>TD["old"]</literal></term>
<listitem> <listitem>
<para> <para>
For a row-level trigger, one or both of these fields contain For a row-level trigger, one or both of these fields contain
@ -841,7 +841,7 @@ $$ LANGUAGE plpythonu;
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>TD["name"]</></term> <term><literal>TD["name"]</literal></term>
<listitem> <listitem>
<para> <para>
contains the trigger name. contains the trigger name.
@ -850,7 +850,7 @@ $$ LANGUAGE plpythonu;
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>TD["table_name"]</></term> <term><literal>TD["table_name"]</literal></term>
<listitem> <listitem>
<para> <para>
contains the name of the table on which the trigger occurred. contains the name of the table on which the trigger occurred.
@ -859,7 +859,7 @@ $$ LANGUAGE plpythonu;
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>TD["table_schema"]</></term> <term><literal>TD["table_schema"]</literal></term>
<listitem> <listitem>
<para> <para>
contains the schema of the table on which the trigger occurred. contains the schema of the table on which the trigger occurred.
@ -868,7 +868,7 @@ $$ LANGUAGE plpythonu;
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>TD["relid"]</></term> <term><literal>TD["relid"]</literal></term>
<listitem> <listitem>
<para> <para>
contains the OID of the table on which the trigger occurred. contains the OID of the table on which the trigger occurred.
@ -877,12 +877,12 @@ $$ LANGUAGE plpythonu;
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>TD["args"]</></term> <term><literal>TD["args"]</literal></term>
<listitem> <listitem>
<para> <para>
If the <command>CREATE TRIGGER</> command If the <command>CREATE TRIGGER</command> command
included arguments, they are available in <literal>TD["args"][0]</> to included arguments, they are available in <literal>TD["args"][0]</literal> to
<literal>TD["args"][<replaceable>n</>-1]</>. <literal>TD["args"][<replaceable>n</replaceable>-1]</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -890,14 +890,14 @@ $$ LANGUAGE plpythonu;
</para> </para>
<para> <para>
If <literal>TD["when"]</literal> is <literal>BEFORE</> or If <literal>TD["when"]</literal> is <literal>BEFORE</literal> or
<literal>INSTEAD OF</> and <literal>INSTEAD OF</literal> and
<literal>TD["level"]</literal> is <literal>ROW</>, you can <literal>TD["level"]</literal> is <literal>ROW</literal>, you can
return <literal>None</literal> or <literal>"OK"</literal> from the return <literal>None</literal> or <literal>"OK"</literal> from the
Python function to indicate the row is unmodified, Python function to indicate the row is unmodified,
<literal>"SKIP"</> to abort the event, or if <literal>TD["event"]</> <literal>"SKIP"</literal> to abort the event, or if <literal>TD["event"]</literal>
is <command>INSERT</> or <command>UPDATE</> you can return is <command>INSERT</command> or <command>UPDATE</command> you can return
<literal>"MODIFY"</> to indicate you've modified the new row. <literal>"MODIFY"</literal> to indicate you've modified the new row.
Otherwise the return value is ignored. Otherwise the return value is ignored.
</para> </para>
</sect1> </sect1>
@ -1023,7 +1023,7 @@ foo = rv[i]["my_column"]
<term><literal>plpy.<function>execute</function>(<replaceable>plan</replaceable> [, <replaceable>arguments</replaceable> [, <replaceable>max-rows</replaceable>]])</literal></term> <term><literal>plpy.<function>execute</function>(<replaceable>plan</replaceable> [, <replaceable>arguments</replaceable> [, <replaceable>max-rows</replaceable>]])</literal></term>
<listitem> <listitem>
<para> <para>
<indexterm><primary>preparing a query</><secondary>in PL/Python</></indexterm> <indexterm><primary>preparing a query</primary><secondary>in PL/Python</secondary></indexterm>
<function>plpy.prepare</function> prepares the execution plan for a <function>plpy.prepare</function> prepares the execution plan for a
query. It is called with a query string and a list of parameter types, query. It is called with a query string and a list of parameter types,
if you have parameter references in the query. For example: if you have parameter references in the query. For example:
@ -1371,22 +1371,22 @@ $$ LANGUAGE plpythonu;
<para> <para>
The <literal>plpy</literal> module also provides the functions The <literal>plpy</literal> module also provides the functions
<simplelist> <simplelist>
<member><literal>plpy.debug(<replaceable>msg, **kwargs</>)</literal></member> <member><literal>plpy.debug(<replaceable>msg, **kwargs</replaceable>)</literal></member>
<member><literal>plpy.log(<replaceable>msg, **kwargs</>)</literal></member> <member><literal>plpy.log(<replaceable>msg, **kwargs</replaceable>)</literal></member>
<member><literal>plpy.info(<replaceable>msg, **kwargs</>)</literal></member> <member><literal>plpy.info(<replaceable>msg, **kwargs</replaceable>)</literal></member>
<member><literal>plpy.notice(<replaceable>msg, **kwargs</>)</literal></member> <member><literal>plpy.notice(<replaceable>msg, **kwargs</replaceable>)</literal></member>
<member><literal>plpy.warning(<replaceable>msg, **kwargs</>)</literal></member> <member><literal>plpy.warning(<replaceable>msg, **kwargs</replaceable>)</literal></member>
<member><literal>plpy.error(<replaceable>msg, **kwargs</>)</literal></member> <member><literal>plpy.error(<replaceable>msg, **kwargs</replaceable>)</literal></member>
<member><literal>plpy.fatal(<replaceable>msg, **kwargs</>)</literal></member> <member><literal>plpy.fatal(<replaceable>msg, **kwargs</replaceable>)</literal></member>
</simplelist> </simplelist>
<indexterm><primary>elog</><secondary>in PL/Python</></indexterm> <indexterm><primary>elog</primary><secondary>in PL/Python</secondary></indexterm>
<function>plpy.error</function> and <function>plpy.fatal</function> <function>plpy.error</function> and <function>plpy.fatal</function>
actually raise a Python exception which, if uncaught, propagates out to actually raise a Python exception which, if uncaught, propagates out to
the calling query, causing the current transaction or subtransaction to the calling query, causing the current transaction or subtransaction to
be aborted. <literal>raise plpy.Error(<replaceable>msg</>)</literal> and be aborted. <literal>raise plpy.Error(<replaceable>msg</replaceable>)</literal> and
<literal>raise plpy.Fatal(<replaceable>msg</>)</literal> are <literal>raise plpy.Fatal(<replaceable>msg</replaceable>)</literal> are
equivalent to calling <literal>plpy.error(<replaceable>msg</>)</literal> and equivalent to calling <literal>plpy.error(<replaceable>msg</replaceable>)</literal> and
<literal>plpy.fatal(<replaceable>msg</>)</literal>, respectively but <literal>plpy.fatal(<replaceable>msg</replaceable>)</literal>, respectively but
the <literal>raise</literal> form does not allow passing keyword arguments. the <literal>raise</literal> form does not allow passing keyword arguments.
The other functions only generate messages of different priority levels. The other functions only generate messages of different priority levels.
Whether messages of a particular priority are reported to the client, Whether messages of a particular priority are reported to the client,
@ -1397,7 +1397,7 @@ $$ LANGUAGE plpythonu;
</para> </para>
<para> <para>
The <replaceable>msg</> argument is given as a positional argument. For The <replaceable>msg</replaceable> argument is given as a positional argument. For
backward compatibility, more than one positional argument can be given. In backward compatibility, more than one positional argument can be given. In
that case, the string representation of the tuple of positional arguments that case, the string representation of the tuple of positional arguments
becomes the message reported to the client. becomes the message reported to the client.
@ -1438,9 +1438,9 @@ PL/Python function "raise_custom_exception"
<para> <para>
Another set of utility functions are Another set of utility functions are
<literal>plpy.quote_literal(<replaceable>string</>)</literal>, <literal>plpy.quote_literal(<replaceable>string</replaceable>)</literal>,
<literal>plpy.quote_nullable(<replaceable>string</>)</literal>, and <literal>plpy.quote_nullable(<replaceable>string</replaceable>)</literal>, and
<literal>plpy.quote_ident(<replaceable>string</>)</literal>. They <literal>plpy.quote_ident(<replaceable>string</replaceable>)</literal>. They
are equivalent to the built-in quoting functions described in <xref are equivalent to the built-in quoting functions described in <xref
linkend="functions-string">. They are useful when constructing linkend="functions-string">. They are useful when constructing
ad-hoc queries. A PL/Python equivalent of dynamic SQL from <xref ad-hoc queries. A PL/Python equivalent of dynamic SQL from <xref

View File

@ -35,7 +35,7 @@
everything is executed from within the safety of the context of a everything is executed from within the safety of the context of a
Tcl interpreter. In addition to the limited command set of safe Tcl interpreter. In addition to the limited command set of safe
Tcl, only a few commands are available to access the database via Tcl, only a few commands are available to access the database via
SPI and to raise messages via <function>elog()</>. PL/Tcl SPI and to raise messages via <function>elog()</function>. PL/Tcl
provides no way to access internals of the database server or to provides no way to access internals of the database server or to
gain OS-level access under the permissions of the gain OS-level access under the permissions of the
<productname>PostgreSQL</productname> server process, as a C <productname>PostgreSQL</productname> server process, as a C
@ -50,23 +50,23 @@
<para> <para>
Sometimes it is desirable to write Tcl functions that are not restricted Sometimes it is desirable to write Tcl functions that are not restricted
to safe Tcl. For example, one might want a Tcl function that sends to safe Tcl. For example, one might want a Tcl function that sends
email. To handle these cases, there is a variant of <application>PL/Tcl</> called <literal>PL/TclU</> email. To handle these cases, there is a variant of <application>PL/Tcl</application> called <literal>PL/TclU</literal>
(for untrusted Tcl). This is exactly the same language except that a full (for untrusted Tcl). This is exactly the same language except that a full
Tcl interpreter is used. <emphasis>If <application>PL/TclU</> is used, it must be Tcl interpreter is used. <emphasis>If <application>PL/TclU</application> is used, it must be
installed as an untrusted procedural language</emphasis> so that only installed as an untrusted procedural language</emphasis> so that only
database superusers can create functions in it. The writer of a <application>PL/TclU</> database superusers can create functions in it. The writer of a <application>PL/TclU</application>
function must take care that the function cannot be used to do anything function must take care that the function cannot be used to do anything
unwanted, since it will be able to do anything that could be done by unwanted, since it will be able to do anything that could be done by
a user logged in as the database administrator. a user logged in as the database administrator.
</para> </para>
<para> <para>
The shared object code for the <application>PL/Tcl</> and The shared object code for the <application>PL/Tcl</application> and
<application>PL/TclU</> call handlers is automatically built and <application>PL/TclU</application> call handlers is automatically built and
installed in the <productname>PostgreSQL</productname> library installed in the <productname>PostgreSQL</productname> library
directory if Tcl support is specified in the configuration step of directory if Tcl support is specified in the configuration step of
the installation procedure. To install <application>PL/Tcl</> the installation procedure. To install <application>PL/Tcl</application>
and/or <application>PL/TclU</> in a particular database, use the and/or <application>PL/TclU</application> in a particular database, use the
<command>CREATE EXTENSION</> command, for example <command>CREATE EXTENSION</command> command, for example
<literal>CREATE EXTENSION pltcl</literal> or <literal>CREATE EXTENSION pltcl</literal> or
<literal>CREATE EXTENSION pltclu</literal>. <literal>CREATE EXTENSION pltclu</literal>.
</para> </para>
@ -78,7 +78,7 @@
<title>PL/Tcl Functions and Arguments</title> <title>PL/Tcl Functions and Arguments</title>
<para> <para>
To create a function in the <application>PL/Tcl</> language, use To create a function in the <application>PL/Tcl</application> language, use
the standard <xref linkend="sql-createfunction"> syntax: the standard <xref linkend="sql-createfunction"> syntax:
<programlisting> <programlisting>
@ -87,8 +87,8 @@ CREATE FUNCTION <replaceable>funcname</replaceable> (<replaceable>argument-types
$$ LANGUAGE pltcl; $$ LANGUAGE pltcl;
</programlisting> </programlisting>
<application>PL/TclU</> is the same, except that the language has to be specified as <application>PL/TclU</application> is the same, except that the language has to be specified as
<literal>pltclu</>. <literal>pltclu</literal>.
</para> </para>
<para> <para>
@ -111,7 +111,7 @@ CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
$$ LANGUAGE pltcl STRICT; $$ LANGUAGE pltcl STRICT;
</programlisting> </programlisting>
Note the clause <literal>STRICT</>, which saves us from Note the clause <literal>STRICT</literal>, which saves us from
having to think about null input values: if a null value is passed, the having to think about null input values: if a null value is passed, the
function will not be called at all, but will just return a null function will not be called at all, but will just return a null
result automatically. result automatically.
@ -122,7 +122,7 @@ $$ LANGUAGE pltcl STRICT;
if the actual value of an argument is null, the corresponding if the actual value of an argument is null, the corresponding
<literal>$<replaceable>n</replaceable></literal> variable will be set to an empty string. <literal>$<replaceable>n</replaceable></literal> variable will be set to an empty string.
To detect whether a particular argument is null, use the function To detect whether a particular argument is null, use the function
<literal>argisnull</>. For example, suppose that we wanted <function>tcl_max</function> <literal>argisnull</literal>. For example, suppose that we wanted <function>tcl_max</function>
with one null and one nonnull argument to return the nonnull with one null and one nonnull argument to return the nonnull
argument, rather than null: argument, rather than null:
@ -188,7 +188,7 @@ $$ LANGUAGE pltcl;
<tip> <tip>
<para> <para>
The result list can be made from an array representation of the The result list can be made from an array representation of the
desired tuple with the <literal>array get</> Tcl command. For example: desired tuple with the <literal>array get</literal> Tcl command. For example:
<programlisting> <programlisting>
CREATE FUNCTION raise_pay(employee, delta int) RETURNS employee AS $$ CREATE FUNCTION raise_pay(employee, delta int) RETURNS employee AS $$
@ -233,8 +233,8 @@ $$ LANGUAGE pltcl;
<para> <para>
The argument values supplied to a PL/Tcl function's code are simply The argument values supplied to a PL/Tcl function's code are simply
the input arguments converted to text form (just as if they had been the input arguments converted to text form (just as if they had been
displayed by a <command>SELECT</> statement). Conversely, the displayed by a <command>SELECT</command> statement). Conversely, the
<literal>return</> and <literal>return_next</> commands will accept <literal>return</literal> and <literal>return_next</literal> commands will accept
any string that is acceptable input format for the function's declared any string that is acceptable input format for the function's declared
result type, or for the specified column of a composite result type. result type, or for the specified column of a composite result type.
</para> </para>
@ -262,14 +262,14 @@ $$ LANGUAGE pltcl;
role in a separate Tcl interpreter for that role. This prevents role in a separate Tcl interpreter for that role. This prevents
accidental or malicious interference by one user with the behavior of accidental or malicious interference by one user with the behavior of
another user's PL/Tcl functions. Each such interpreter will have its own another user's PL/Tcl functions. Each such interpreter will have its own
values for any <quote>global</> Tcl variables. Thus, two PL/Tcl values for any <quote>global</quote> Tcl variables. Thus, two PL/Tcl
functions will share the same global variables if and only if they are functions will share the same global variables if and only if they are
executed by the same SQL role. In an application wherein a single executed by the same SQL role. In an application wherein a single
session executes code under multiple SQL roles (via <literal>SECURITY session executes code under multiple SQL roles (via <literal>SECURITY
DEFINER</> functions, use of <command>SET ROLE</>, etc) you may need to DEFINER</literal> functions, use of <command>SET ROLE</command>, etc) you may need to
take explicit steps to ensure that PL/Tcl functions can share data. To take explicit steps to ensure that PL/Tcl functions can share data. To
do that, make sure that functions that should communicate are owned by do that, make sure that functions that should communicate are owned by
the same user, and mark them <literal>SECURITY DEFINER</>. You must of the same user, and mark them <literal>SECURITY DEFINER</literal>. You must of
course take care that such functions can't be used to do anything course take care that such functions can't be used to do anything
unintended. unintended.
</para> </para>
@ -286,19 +286,19 @@ $$ LANGUAGE pltcl;
<para> <para>
To help protect PL/Tcl functions from unintentionally interfering To help protect PL/Tcl functions from unintentionally interfering
with each other, a global with each other, a global
array is made available to each function via the <function>upvar</> array is made available to each function via the <function>upvar</function>
command. The global name of this variable is the function's internal command. The global name of this variable is the function's internal
name, and the local name is <literal>GD</>. It is recommended that name, and the local name is <literal>GD</literal>. It is recommended that
<literal>GD</> be used <literal>GD</literal> be used
for persistent private data of a function. Use regular Tcl global for persistent private data of a function. Use regular Tcl global
variables only for values that you specifically intend to be shared among variables only for values that you specifically intend to be shared among
multiple functions. (Note that the <literal>GD</> arrays are only multiple functions. (Note that the <literal>GD</literal> arrays are only
global within a particular interpreter, so they do not bypass the global within a particular interpreter, so they do not bypass the
security restrictions mentioned above.) security restrictions mentioned above.)
</para> </para>
<para> <para>
An example of using <literal>GD</> appears in the An example of using <literal>GD</literal> appears in the
<function>spi_execp</function> example below. <function>spi_execp</function> example below.
</para> </para>
</sect1> </sect1>
@ -320,28 +320,28 @@ $$ LANGUAGE pltcl;
causes an error to be raised. Otherwise, the return value of <function>spi_exec</function> causes an error to be raised. Otherwise, the return value of <function>spi_exec</function>
is the number of rows processed (selected, inserted, updated, or is the number of rows processed (selected, inserted, updated, or
deleted) by the command, or zero if the command is a utility deleted) by the command, or zero if the command is a utility
statement. In addition, if the command is a <command>SELECT</> statement, the statement. In addition, if the command is a <command>SELECT</command> statement, the
values of the selected columns are placed in Tcl variables as values of the selected columns are placed in Tcl variables as
described below. described below.
</para> </para>
<para> <para>
The optional <literal>-count</> value tells The optional <literal>-count</literal> value tells
<function>spi_exec</function> the maximum number of rows <function>spi_exec</function> the maximum number of rows
to process in the command. The effect of this is comparable to to process in the command. The effect of this is comparable to
setting up a query as a cursor and then saying <literal>FETCH <replaceable>n</></>. setting up a query as a cursor and then saying <literal>FETCH <replaceable>n</replaceable></literal>.
</para> </para>
<para> <para>
If the command is a <command>SELECT</> statement, the values of the If the command is a <command>SELECT</command> statement, the values of the
result columns are placed into Tcl variables named after the columns. result columns are placed into Tcl variables named after the columns.
If the <literal>-array</> option is given, the column values are If the <literal>-array</literal> option is given, the column values are
instead stored into elements of the named associative array, with the instead stored into elements of the named associative array, with the
column names used as array indexes. In addition, the current row column names used as array indexes. In addition, the current row
number within the result (counting from zero) is stored into the array number within the result (counting from zero) is stored into the array
element named <quote><literal>.tupno</></quote>, unless that name is element named <quote><literal>.tupno</literal></quote>, unless that name is
in use as a column name in the result. in use as a column name in the result.
</para> </para>
<para> <para>
If the command is a <command>SELECT</> statement and no <replaceable>loop-body</> If the command is a <command>SELECT</command> statement and no <replaceable>loop-body</replaceable>
script is given, then only the first row of results are stored into script is given, then only the first row of results are stored into
Tcl variables or array elements; remaining rows, if any, are ignored. Tcl variables or array elements; remaining rows, if any, are ignored.
No storing occurs if the query returns no rows. (This case can be No storing occurs if the query returns no rows. (This case can be
@ -350,14 +350,14 @@ $$ LANGUAGE pltcl;
<programlisting> <programlisting>
spi_exec "SELECT count(*) AS cnt FROM pg_proc" spi_exec "SELECT count(*) AS cnt FROM pg_proc"
</programlisting> </programlisting>
will set the Tcl variable <literal>$cnt</> to the number of rows in will set the Tcl variable <literal>$cnt</literal> to the number of rows in
the <structname>pg_proc</> system catalog. the <structname>pg_proc</structname> system catalog.
</para> </para>
<para> <para>
If the optional <replaceable>loop-body</> argument is given, it is If the optional <replaceable>loop-body</replaceable> argument is given, it is
a piece of Tcl script that is executed once for each row in the a piece of Tcl script that is executed once for each row in the
query result. (<replaceable>loop-body</> is ignored if the given query result. (<replaceable>loop-body</replaceable> is ignored if the given
command is not a <command>SELECT</>.) command is not a <command>SELECT</command>.)
The values of the current row's columns The values of the current row's columns
are stored into Tcl variables or array elements before each iteration. are stored into Tcl variables or array elements before each iteration.
For example: For example:
@ -366,14 +366,14 @@ spi_exec -array C "SELECT * FROM pg_class" {
elog DEBUG "have table $C(relname)" elog DEBUG "have table $C(relname)"
} }
</programlisting> </programlisting>
will print a log message for every row of <literal>pg_class</>. This will print a log message for every row of <literal>pg_class</literal>. This
feature works similarly to other Tcl looping constructs; in feature works similarly to other Tcl looping constructs; in
particular <literal>continue</> and <literal>break</> work in the particular <literal>continue</literal> and <literal>break</literal> work in the
usual way inside the loop body. usual way inside the loop body.
</para> </para>
<para> <para>
If a column of a query result is null, the target If a column of a query result is null, the target
variable for it is <quote>unset</> rather than being set. variable for it is <quote>unset</quote> rather than being set.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -384,8 +384,8 @@ spi_exec -array C "SELECT * FROM pg_class" {
<para> <para>
Prepares and saves a query plan for later execution. The Prepares and saves a query plan for later execution. The
saved plan will be retained for the life of the current saved plan will be retained for the life of the current
session.<indexterm><primary>preparing a query</> session.<indexterm><primary>preparing a query</primary>
<secondary>in PL/Tcl</></> <secondary>in PL/Tcl</secondary></indexterm>
</para> </para>
<para> <para>
The query can use parameters, that is, placeholders for The query can use parameters, that is, placeholders for
@ -405,29 +405,29 @@ spi_exec -array C "SELECT * FROM pg_class" {
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal><function>spi_execp</> <optional role="tcl">-count <replaceable>n</replaceable></optional> <optional role="tcl">-array <replaceable>name</replaceable></optional> <optional role="tcl">-nulls <replaceable>string</replaceable></optional> <replaceable>queryid</replaceable> <optional role="tcl"><replaceable>value-list</replaceable></optional> <optional role="tcl"><replaceable>loop-body</replaceable></optional></literal></term> <term><literal><function>spi_execp</function> <optional role="tcl">-count <replaceable>n</replaceable></optional> <optional role="tcl">-array <replaceable>name</replaceable></optional> <optional role="tcl">-nulls <replaceable>string</replaceable></optional> <replaceable>queryid</replaceable> <optional role="tcl"><replaceable>value-list</replaceable></optional> <optional role="tcl"><replaceable>loop-body</replaceable></optional></literal></term>
<listitem> <listitem>
<para> <para>
Executes a query previously prepared with <function>spi_prepare</>. Executes a query previously prepared with <function>spi_prepare</function>.
<replaceable>queryid</replaceable> is the ID returned by <replaceable>queryid</replaceable> is the ID returned by
<function>spi_prepare</>. If the query references parameters, <function>spi_prepare</function>. If the query references parameters,
a <replaceable>value-list</replaceable> must be supplied. This a <replaceable>value-list</replaceable> must be supplied. This
is a Tcl list of actual values for the parameters. The list must be is a Tcl list of actual values for the parameters. The list must be
the same length as the parameter type list previously given to the same length as the parameter type list previously given to
<function>spi_prepare</>. Omit <replaceable>value-list</replaceable> <function>spi_prepare</function>. Omit <replaceable>value-list</replaceable>
if the query has no parameters. if the query has no parameters.
</para> </para>
<para> <para>
The optional value for <literal>-nulls</> is a string of spaces and The optional value for <literal>-nulls</literal> is a string of spaces and
<literal>'n'</> characters telling <function>spi_execp</function> <literal>'n'</literal> characters telling <function>spi_execp</function>
which of the parameters are null values. If given, it must have exactly the which of the parameters are null values. If given, it must have exactly the
same length as the <replaceable>value-list</replaceable>. If it same length as the <replaceable>value-list</replaceable>. If it
is not given, all the parameter values are nonnull. is not given, all the parameter values are nonnull.
</para> </para>
<para> <para>
Except for the way in which the query and its parameters are specified, Except for the way in which the query and its parameters are specified,
<function>spi_execp</> works just like <function>spi_exec</>. <function>spi_execp</function> works just like <function>spi_exec</function>.
The <literal>-count</>, <literal>-array</>, and The <literal>-count</literal>, <literal>-array</literal>, and
<replaceable>loop-body</replaceable> options are the same, <replaceable>loop-body</replaceable> options are the same,
and so is the result value. and so is the result value.
</para> </para>
@ -448,9 +448,9 @@ $$ LANGUAGE pltcl;
</programlisting> </programlisting>
We need backslashes inside the query string given to We need backslashes inside the query string given to
<function>spi_prepare</> to ensure that the <function>spi_prepare</function> to ensure that the
<literal>$<replaceable>n</replaceable></> markers will be passed <literal>$<replaceable>n</replaceable></literal> markers will be passed
through to <function>spi_prepare</> as-is, and not replaced by Tcl through to <function>spi_prepare</function> as-is, and not replaced by Tcl
variable substitution. variable substitution.
</para> </para>
@ -459,7 +459,7 @@ $$ LANGUAGE pltcl;
<varlistentry> <varlistentry>
<term> <term>
<function>spi_lastoid</> <function>spi_lastoid</function>
<indexterm> <indexterm>
<primary>spi_lastoid</primary> <primary>spi_lastoid</primary>
<secondary>in PL/Tcl</secondary> <secondary>in PL/Tcl</secondary>
@ -468,8 +468,8 @@ $$ LANGUAGE pltcl;
<listitem> <listitem>
<para> <para>
Returns the OID of the row inserted by the last Returns the OID of the row inserted by the last
<function>spi_exec</> or <function>spi_execp</>, if the <function>spi_exec</function> or <function>spi_execp</function>, if the
command was a single-row <command>INSERT</> and the modified command was a single-row <command>INSERT</command> and the modified
table contained OIDs. (If not, you get zero.) table contained OIDs. (If not, you get zero.)
</para> </para>
</listitem> </listitem>
@ -490,7 +490,7 @@ $$ LANGUAGE pltcl;
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><function>quote</> <replaceable>string</replaceable></term> <term><function>quote</function> <replaceable>string</replaceable></term>
<listitem> <listitem>
<para> <para>
Doubles all occurrences of single quote and backslash characters Doubles all occurrences of single quote and backslash characters
@ -504,7 +504,7 @@ $$ LANGUAGE pltcl;
"SELECT '$val' AS ret" "SELECT '$val' AS ret"
</programlisting> </programlisting>
where the Tcl variable <literal>val</> actually contains where the Tcl variable <literal>val</literal> actually contains
<literal>doesn't</literal>. This would result <literal>doesn't</literal>. This would result
in the final command string: in the final command string:
@ -536,7 +536,7 @@ SELECT 'doesn''t' AS ret
<varlistentry> <varlistentry>
<term> <term>
<function>elog</> <replaceable>level</replaceable> <replaceable>msg</replaceable> <function>elog</function> <replaceable>level</replaceable> <replaceable>msg</replaceable>
<indexterm> <indexterm>
<primary>elog</primary> <primary>elog</primary>
<secondary>in PL/Tcl</secondary> <secondary>in PL/Tcl</secondary>
@ -545,14 +545,14 @@ SELECT 'doesn''t' AS ret
<listitem> <listitem>
<para> <para>
Emits a log or error message. Possible levels are Emits a log or error message. Possible levels are
<literal>DEBUG</>, <literal>LOG</>, <literal>INFO</>, <literal>DEBUG</literal>, <literal>LOG</literal>, <literal>INFO</literal>,
<literal>NOTICE</>, <literal>WARNING</>, <literal>ERROR</>, and <literal>NOTICE</literal>, <literal>WARNING</literal>, <literal>ERROR</literal>, and
<literal>FATAL</>. <literal>ERROR</> <literal>FATAL</literal>. <literal>ERROR</literal>
raises an error condition; if this is not trapped by the surrounding raises an error condition; if this is not trapped by the surrounding
Tcl code, the error propagates out to the calling query, causing Tcl code, the error propagates out to the calling query, causing
the current transaction or subtransaction to be aborted. This the current transaction or subtransaction to be aborted. This
is effectively the same as the Tcl <literal>error</> command. is effectively the same as the Tcl <literal>error</literal> command.
<literal>FATAL</> aborts the transaction and causes the current <literal>FATAL</literal> aborts the transaction and causes the current
session to shut down. (There is probably no good reason to use session to shut down. (There is probably no good reason to use
this error level in PL/Tcl functions, but it's provided for this error level in PL/Tcl functions, but it's provided for
completeness.) The other levels only generate messages of different completeness.) The other levels only generate messages of different
@ -585,7 +585,7 @@ SELECT 'doesn''t' AS ret
Trigger procedures can be written in PL/Tcl. Trigger procedures can be written in PL/Tcl.
<productname>PostgreSQL</productname> requires that a procedure that is to be called <productname>PostgreSQL</productname> requires that a procedure that is to be called
as a trigger must be declared as a function with no arguments as a trigger must be declared as a function with no arguments
and a return type of <literal>trigger</>. and a return type of <literal>trigger</literal>.
</para> </para>
<para> <para>
The information from the trigger manager is passed to the procedure body The information from the trigger manager is passed to the procedure body
@ -637,8 +637,8 @@ SELECT 'doesn''t' AS ret
<listitem> <listitem>
<para> <para>
A Tcl list of the table column names, prefixed with an empty list A Tcl list of the table column names, prefixed with an empty list
element. So looking up a column name in the list with <application>Tcl</>'s element. So looking up a column name in the list with <application>Tcl</application>'s
<function>lsearch</> command returns the element's number starting <function>lsearch</function> command returns the element's number starting
with 1 for the first column, the same way the columns are customarily with 1 for the first column, the same way the columns are customarily
numbered in <productname>PostgreSQL</productname>. (Empty list numbered in <productname>PostgreSQL</productname>. (Empty list
elements also appear in the positions of columns that have been elements also appear in the positions of columns that have been
@ -652,8 +652,8 @@ SELECT 'doesn''t' AS ret
<term><varname>$TG_when</varname></term> <term><varname>$TG_when</varname></term>
<listitem> <listitem>
<para> <para>
The string <literal>BEFORE</>, <literal>AFTER</>, or The string <literal>BEFORE</literal>, <literal>AFTER</literal>, or
<literal>INSTEAD OF</>, depending on the type of trigger event. <literal>INSTEAD OF</literal>, depending on the type of trigger event.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -662,7 +662,7 @@ SELECT 'doesn''t' AS ret
<term><varname>$TG_level</varname></term> <term><varname>$TG_level</varname></term>
<listitem> <listitem>
<para> <para>
The string <literal>ROW</> or <literal>STATEMENT</> depending on the The string <literal>ROW</literal> or <literal>STATEMENT</literal> depending on the
type of trigger event. type of trigger event.
</para> </para>
</listitem> </listitem>
@ -672,8 +672,8 @@ SELECT 'doesn''t' AS ret
<term><varname>$TG_op</varname></term> <term><varname>$TG_op</varname></term>
<listitem> <listitem>
<para> <para>
The string <literal>INSERT</>, <literal>UPDATE</>, The string <literal>INSERT</literal>, <literal>UPDATE</literal>,
<literal>DELETE</>, or <literal>TRUNCATE</> depending on the type of <literal>DELETE</literal>, or <literal>TRUNCATE</literal> depending on the type of
trigger event. trigger event.
</para> </para>
</listitem> </listitem>
@ -684,8 +684,8 @@ SELECT 'doesn''t' AS ret
<listitem> <listitem>
<para> <para>
An associative array containing the values of the new table An associative array containing the values of the new table
row for <command>INSERT</> or <command>UPDATE</> actions, or row for <command>INSERT</command> or <command>UPDATE</command> actions, or
empty for <command>DELETE</>. The array is indexed by column empty for <command>DELETE</command>. The array is indexed by column
name. Columns that are null will not appear in the array. name. Columns that are null will not appear in the array.
This is not set for statement-level triggers. This is not set for statement-level triggers.
</para> </para>
@ -697,8 +697,8 @@ SELECT 'doesn''t' AS ret
<listitem> <listitem>
<para> <para>
An associative array containing the values of the old table An associative array containing the values of the old table
row for <command>UPDATE</> or <command>DELETE</> actions, or row for <command>UPDATE</command> or <command>DELETE</command> actions, or
empty for <command>INSERT</>. The array is indexed by column empty for <command>INSERT</command>. The array is indexed by column
name. Columns that are null will not appear in the array. name. Columns that are null will not appear in the array.
This is not set for statement-level triggers. This is not set for statement-level triggers.
</para> </para>
@ -721,32 +721,32 @@ SELECT 'doesn''t' AS ret
<para> <para>
The return value from a trigger procedure can be one of the strings The return value from a trigger procedure can be one of the strings
<literal>OK</> or <literal>SKIP</>, or a list of column name/value pairs. <literal>OK</literal> or <literal>SKIP</literal>, or a list of column name/value pairs.
If the return value is <literal>OK</>, If the return value is <literal>OK</literal>,
the operation (<command>INSERT</>/<command>UPDATE</>/<command>DELETE</>) the operation (<command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command>)
that fired the trigger will proceed that fired the trigger will proceed
normally. <literal>SKIP</> tells the trigger manager to silently suppress normally. <literal>SKIP</literal> tells the trigger manager to silently suppress
the operation for this row. If a list is returned, it tells PL/Tcl to the operation for this row. If a list is returned, it tells PL/Tcl to
return a modified row to the trigger manager; the contents of the return a modified row to the trigger manager; the contents of the
modified row are specified by the column names and values in the list. modified row are specified by the column names and values in the list.
Any columns not mentioned in the list are set to null. Any columns not mentioned in the list are set to null.
Returning a modified row is only meaningful Returning a modified row is only meaningful
for row-level <literal>BEFORE</> <command>INSERT</> or <command>UPDATE</> for row-level <literal>BEFORE</literal> <command>INSERT</command> or <command>UPDATE</command>
triggers, for which the modified row will be inserted instead of the one triggers, for which the modified row will be inserted instead of the one
given in <varname>$NEW</>; or for row-level <literal>INSTEAD OF</> given in <varname>$NEW</varname>; or for row-level <literal>INSTEAD OF</literal>
<command>INSERT</> or <command>UPDATE</> triggers where the returned row <command>INSERT</command> or <command>UPDATE</command> triggers where the returned row
is used as the source data for <command>INSERT RETURNING</> or is used as the source data for <command>INSERT RETURNING</command> or
<command>UPDATE RETURNING</> clauses. <command>UPDATE RETURNING</command> clauses.
In row-level <literal>BEFORE</> <command>DELETE</> or <literal>INSTEAD In row-level <literal>BEFORE</literal> <command>DELETE</command> or <literal>INSTEAD
OF</> <command>DELETE</> triggers, returning a modified row has the same OF</literal> <command>DELETE</command> triggers, returning a modified row has the same
effect as returning <literal>OK</>, that is the operation proceeds. effect as returning <literal>OK</literal>, that is the operation proceeds.
The trigger return value is ignored for all other types of triggers. The trigger return value is ignored for all other types of triggers.
</para> </para>
<tip> <tip>
<para> <para>
The result list can be made from an array representation of the The result list can be made from an array representation of the
modified tuple with the <literal>array get</> Tcl command. modified tuple with the <literal>array get</literal> Tcl command.
</para> </para>
</tip> </tip>
@ -797,7 +797,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab
Event trigger procedures can be written in PL/Tcl. Event trigger procedures can be written in PL/Tcl.
<productname>PostgreSQL</productname> requires that a procedure that is <productname>PostgreSQL</productname> requires that a procedure that is
to be called as an event trigger must be declared as a function with no to be called as an event trigger must be declared as a function with no
arguments and a return type of <literal>event_trigger</>. arguments and a return type of <literal>event_trigger</literal>.
</para> </para>
<para> <para>
The information from the trigger manager is passed to the procedure body The information from the trigger manager is passed to the procedure body
@ -885,17 +885,17 @@ CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE PROCEDURE tclsnit
word is <literal>POSTGRES</literal>, the second word is the PostgreSQL word is <literal>POSTGRES</literal>, the second word is the PostgreSQL
version number, and additional words are field name/value pairs version number, and additional words are field name/value pairs
providing detailed information about the error. providing detailed information about the error.
Fields <varname>SQLSTATE</>, <varname>condition</>, Fields <varname>SQLSTATE</varname>, <varname>condition</varname>,
and <varname>message</> are always supplied and <varname>message</varname> are always supplied
(the first two represent the error code and condition name as shown (the first two represent the error code and condition name as shown
in <xref linkend="errcodes-appendix">). in <xref linkend="errcodes-appendix">).
Fields that may be present include Fields that may be present include
<varname>detail</>, <varname>hint</>, <varname>context</>, <varname>detail</varname>, <varname>hint</varname>, <varname>context</varname>,
<varname>schema</>, <varname>table</>, <varname>column</>, <varname>schema</varname>, <varname>table</varname>, <varname>column</varname>,
<varname>datatype</>, <varname>constraint</>, <varname>datatype</varname>, <varname>constraint</varname>,
<varname>statement</>, <varname>cursor_position</>, <varname>statement</varname>, <varname>cursor_position</varname>,
<varname>filename</>, <varname>lineno</>, and <varname>filename</varname>, <varname>lineno</varname>, and
<varname>funcname</>. <varname>funcname</varname>.
</para> </para>
<para> <para>
@ -1006,7 +1006,7 @@ $$ LANGUAGE pltcl;
<para> <para>
This section lists configuration parameters that This section lists configuration parameters that
affect <application>PL/Tcl</>. affect <application>PL/Tcl</application>.
</para> </para>
<variablelist> <variablelist>
@ -1015,7 +1015,7 @@ $$ LANGUAGE pltcl;
<term> <term>
<varname>pltcl.start_proc</varname> (<type>string</type>) <varname>pltcl.start_proc</varname> (<type>string</type>)
<indexterm> <indexterm>
<primary><varname>pltcl.start_proc</> configuration parameter</primary> <primary><varname>pltcl.start_proc</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
@ -1031,8 +1031,8 @@ $$ LANGUAGE pltcl;
</para> </para>
<para> <para>
The referenced function must be written in the <literal>pltcl</> The referenced function must be written in the <literal>pltcl</literal>
language, and must not be marked <literal>SECURITY DEFINER</>. language, and must not be marked <literal>SECURITY DEFINER</literal>.
(These restrictions ensure that it runs in the interpreter it's (These restrictions ensure that it runs in the interpreter it's
supposed to initialize.) The current user must have permission to supposed to initialize.) The current user must have permission to
call it, too. call it, too.
@ -1060,14 +1060,14 @@ $$ LANGUAGE pltcl;
<term> <term>
<varname>pltclu.start_proc</varname> (<type>string</type>) <varname>pltclu.start_proc</varname> (<type>string</type>)
<indexterm> <indexterm>
<primary><varname>pltclu.start_proc</> configuration parameter</primary> <primary><varname>pltclu.start_proc</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
<para> <para>
This parameter is exactly like <varname>pltcl.start_proc</varname>, This parameter is exactly like <varname>pltcl.start_proc</varname>,
except that it applies to PL/TclU. The referenced function must except that it applies to PL/TclU. The referenced function must
be written in the <literal>pltclu</> language. be written in the <literal>pltclu</literal> language.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1084,7 +1084,7 @@ $$ LANGUAGE pltcl;
differ. Tcl, however, requires all procedure names to be distinct. differ. Tcl, however, requires all procedure names to be distinct.
PL/Tcl deals with this by making the internal Tcl procedure names contain PL/Tcl deals with this by making the internal Tcl procedure names contain
the object the object
ID of the function from the system table <structname>pg_proc</> as part of their name. Thus, ID of the function from the system table <structname>pg_proc</structname> as part of their name. Thus,
<productname>PostgreSQL</productname> functions with the same name <productname>PostgreSQL</productname> functions with the same name
and different argument types will be different Tcl procedures, too. This and different argument types will be different Tcl procedures, too. This
is not normally a concern for a PL/Tcl programmer, but it might be visible is not normally a concern for a PL/Tcl programmer, but it might be visible

View File

@ -8,7 +8,7 @@
</indexterm> </indexterm>
<para> <para>
The <filename>postgres_fdw</> module provides the foreign-data wrapper The <filename>postgres_fdw</filename> module provides the foreign-data wrapper
<literal>postgres_fdw</literal>, which can be used to access data <literal>postgres_fdw</literal>, which can be used to access data
stored in external <productname>PostgreSQL</productname> servers. stored in external <productname>PostgreSQL</productname> servers.
</para> </para>
@ -16,17 +16,17 @@
<para> <para>
The functionality provided by this module overlaps substantially The functionality provided by this module overlaps substantially
with the functionality of the older <xref linkend="dblink"> module. with the functionality of the older <xref linkend="dblink"> module.
But <filename>postgres_fdw</> provides more transparent and But <filename>postgres_fdw</filename> provides more transparent and
standards-compliant syntax for accessing remote tables, and can give standards-compliant syntax for accessing remote tables, and can give
better performance in many cases. better performance in many cases.
</para> </para>
<para> <para>
To prepare for remote access using <filename>postgres_fdw</>: To prepare for remote access using <filename>postgres_fdw</filename>:
<orderedlist spacing="compact"> <orderedlist spacing="compact">
<listitem> <listitem>
<para> <para>
Install the <filename>postgres_fdw</> extension using <xref Install the <filename>postgres_fdw</filename> extension using <xref
linkend="sql-createextension">. linkend="sql-createextension">.
</para> </para>
</listitem> </listitem>
@ -61,17 +61,17 @@
</para> </para>
<para> <para>
Now you need only <command>SELECT</> from a foreign table to access Now you need only <command>SELECT</command> from a foreign table to access
the data stored in its underlying remote table. You can also modify the data stored in its underlying remote table. You can also modify
the remote table using <command>INSERT</>, <command>UPDATE</>, or the remote table using <command>INSERT</command>, <command>UPDATE</command>, or
<command>DELETE</>. (Of course, the remote user you have specified <command>DELETE</command>. (Of course, the remote user you have specified
in your user mapping must have privileges to do these things.) in your user mapping must have privileges to do these things.)
</para> </para>
<para> <para>
Note that <filename>postgres_fdw</> currently lacks support for Note that <filename>postgres_fdw</filename> currently lacks support for
<command>INSERT</command> statements with an <literal>ON CONFLICT DO <command>INSERT</command> statements with an <literal>ON CONFLICT DO
UPDATE</> clause. However, the <literal>ON CONFLICT DO NOTHING</> UPDATE</literal> clause. However, the <literal>ON CONFLICT DO NOTHING</literal>
clause is supported, provided a unique index inference specification clause is supported, provided a unique index inference specification
is omitted. is omitted.
</para> </para>
@ -79,10 +79,10 @@
<para> <para>
It is generally recommended that the columns of a foreign table be declared It is generally recommended that the columns of a foreign table be declared
with exactly the same data types, and collations if applicable, as the with exactly the same data types, and collations if applicable, as the
referenced columns of the remote table. Although <filename>postgres_fdw</> referenced columns of the remote table. Although <filename>postgres_fdw</filename>
is currently rather forgiving about performing data type conversions at is currently rather forgiving about performing data type conversions at
need, surprising semantic anomalies may arise when types or collations do need, surprising semantic anomalies may arise when types or collations do
not match, due to the remote server interpreting <literal>WHERE</> clauses not match, due to the remote server interpreting <literal>WHERE</literal> clauses
slightly differently from the local server. slightly differently from the local server.
</para> </para>
@ -99,8 +99,8 @@
<title>Connection Options</title> <title>Connection Options</title>
<para> <para>
A foreign server using the <filename>postgres_fdw</> foreign data wrapper A foreign server using the <filename>postgres_fdw</filename> foreign data wrapper
can have the same options that <application>libpq</> accepts in can have the same options that <application>libpq</application> accepts in
connection strings, as described in <xref linkend="libpq-paramkeywords">, connection strings, as described in <xref linkend="libpq-paramkeywords">,
except that these options are not allowed: except that these options are not allowed:
@ -113,14 +113,14 @@
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<literal>client_encoding</> (this is automatically set from the local <literal>client_encoding</literal> (this is automatically set from the local
server encoding) server encoding)
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<literal>fallback_application_name</> (always set to <literal>fallback_application_name</literal> (always set to
<literal>postgres_fdw</>) <literal>postgres_fdw</literal>)
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
@ -186,14 +186,14 @@
<title>Cost Estimation Options</title> <title>Cost Estimation Options</title>
<para> <para>
<filename>postgres_fdw</> retrieves remote data by executing queries <filename>postgres_fdw</filename> retrieves remote data by executing queries
against remote servers, so ideally the estimated cost of scanning a against remote servers, so ideally the estimated cost of scanning a
foreign table should be whatever it costs to be done on the remote foreign table should be whatever it costs to be done on the remote
server, plus some overhead for communication. The most reliable way to server, plus some overhead for communication. The most reliable way to
get such an estimate is to ask the remote server and then add something get such an estimate is to ask the remote server and then add something
for overhead &mdash; but for simple queries, it may not be worth the cost for overhead &mdash; but for simple queries, it may not be worth the cost
of an additional remote query to get a cost estimate. of an additional remote query to get a cost estimate.
So <filename>postgres_fdw</> provides the following options to control So <filename>postgres_fdw</filename> provides the following options to control
how cost estimation is done: how cost estimation is done:
</para> </para>
@ -204,7 +204,7 @@
<listitem> <listitem>
<para> <para>
This option, which can be specified for a foreign table or a foreign This option, which can be specified for a foreign table or a foreign
server, controls whether <filename>postgres_fdw</> issues remote server, controls whether <filename>postgres_fdw</filename> issues remote
<command>EXPLAIN</command> commands to obtain cost estimates. <command>EXPLAIN</command> commands to obtain cost estimates.
A setting for a foreign table overrides any setting for its server, A setting for a foreign table overrides any setting for its server,
but only for that table. but only for that table.
@ -245,11 +245,11 @@
<para> <para>
When <literal>use_remote_estimate</literal> is true, When <literal>use_remote_estimate</literal> is true,
<filename>postgres_fdw</> obtains row count and cost estimates from the <filename>postgres_fdw</filename> obtains row count and cost estimates from the
remote server and then adds <literal>fdw_startup_cost</literal> and remote server and then adds <literal>fdw_startup_cost</literal> and
<literal>fdw_tuple_cost</literal> to the cost estimates. When <literal>fdw_tuple_cost</literal> to the cost estimates. When
<literal>use_remote_estimate</literal> is false, <literal>use_remote_estimate</literal> is false,
<filename>postgres_fdw</> performs local row count and cost estimation <filename>postgres_fdw</filename> performs local row count and cost estimation
and then adds <literal>fdw_startup_cost</literal> and and then adds <literal>fdw_startup_cost</literal> and
<literal>fdw_tuple_cost</literal> to the cost estimates. This local <literal>fdw_tuple_cost</literal> to the cost estimates. This local
estimation is unlikely to be very accurate unless local copies of the estimation is unlikely to be very accurate unless local copies of the
@ -268,12 +268,12 @@
<title>Remote Execution Options</title> <title>Remote Execution Options</title>
<para> <para>
By default, only <literal>WHERE</> clauses using built-in operators and By default, only <literal>WHERE</literal> clauses using built-in operators and
functions will be considered for execution on the remote server. Clauses functions will be considered for execution on the remote server. Clauses
involving non-built-in functions are checked locally after rows are involving non-built-in functions are checked locally after rows are
fetched. If such functions are available on the remote server and can be fetched. If such functions are available on the remote server and can be
relied on to produce the same results as they do locally, performance can relied on to produce the same results as they do locally, performance can
be improved by sending such <literal>WHERE</> clauses for remote be improved by sending such <literal>WHERE</literal> clauses for remote
execution. This behavior can be controlled using the following option: execution. This behavior can be controlled using the following option:
</para> </para>
@ -284,7 +284,7 @@
<listitem> <listitem>
<para> <para>
This option is a comma-separated list of names This option is a comma-separated list of names
of <productname>PostgreSQL</> extensions that are installed, in of <productname>PostgreSQL</productname> extensions that are installed, in
compatible versions, on both the local and remote servers. Functions compatible versions, on both the local and remote servers. Functions
and operators that are immutable and belong to a listed extension will and operators that are immutable and belong to a listed extension will
be considered shippable to the remote server. be considered shippable to the remote server.
@ -293,7 +293,7 @@
<para> <para>
When using the <literal>extensions</literal> option, <emphasis>it is the When using the <literal>extensions</literal> option, <emphasis>it is the
user's responsibility</> that the listed extensions exist and behave user's responsibility</emphasis> that the listed extensions exist and behave
identically on both the local and remote servers. Otherwise, remote identically on both the local and remote servers. Otherwise, remote
queries may fail or behave unexpectedly. queries may fail or behave unexpectedly.
</para> </para>
@ -304,11 +304,11 @@
<term><literal>fetch_size</literal></term> <term><literal>fetch_size</literal></term>
<listitem> <listitem>
<para> <para>
This option specifies the number of rows <filename>postgres_fdw</> This option specifies the number of rows <filename>postgres_fdw</filename>
should get in each fetch operation. It can be specified for a foreign should get in each fetch operation. It can be specified for a foreign
table or a foreign server. The option specified on a table overrides table or a foreign server. The option specified on a table overrides
an option specified for the server. an option specified for the server.
The default is <literal>100</>. The default is <literal>100</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -321,7 +321,7 @@
<title>Updatability Options</title> <title>Updatability Options</title>
<para> <para>
By default all foreign tables using <filename>postgres_fdw</> are assumed By default all foreign tables using <filename>postgres_fdw</filename> are assumed
to be updatable. This may be overridden using the following option: to be updatable. This may be overridden using the following option:
</para> </para>
@ -331,20 +331,20 @@
<term><literal>updatable</literal></term> <term><literal>updatable</literal></term>
<listitem> <listitem>
<para> <para>
This option controls whether <filename>postgres_fdw</> allows foreign This option controls whether <filename>postgres_fdw</filename> allows foreign
tables to be modified using <command>INSERT</>, <command>UPDATE</> and tables to be modified using <command>INSERT</command>, <command>UPDATE</command> and
<command>DELETE</> commands. It can be specified for a foreign table <command>DELETE</command> commands. It can be specified for a foreign table
or a foreign server. A table-level option overrides a server-level or a foreign server. A table-level option overrides a server-level
option. option.
The default is <literal>true</>. The default is <literal>true</literal>.
</para> </para>
<para> <para>
Of course, if the remote table is not in fact updatable, an error Of course, if the remote table is not in fact updatable, an error
would occur anyway. Use of this option primarily allows the error to would occur anyway. Use of this option primarily allows the error to
be thrown locally without querying the remote server. Note however be thrown locally without querying the remote server. Note however
that the <literal>information_schema</> views will report a that the <literal>information_schema</literal> views will report a
<filename>postgres_fdw</> foreign table to be updatable (or not) <filename>postgres_fdw</filename> foreign table to be updatable (or not)
according to the setting of this option, without any check of the according to the setting of this option, without any check of the
remote server. remote server.
</para> </para>
@ -358,7 +358,7 @@
<title>Importing Options</title> <title>Importing Options</title>
<para> <para>
<filename>postgres_fdw</> is able to import foreign table definitions <filename>postgres_fdw</filename> is able to import foreign table definitions
using <xref linkend="sql-importforeignschema">. This command creates using <xref linkend="sql-importforeignschema">. This command creates
foreign table definitions on the local server that match tables or foreign table definitions on the local server that match tables or
views present on the remote server. If the remote tables to be imported views present on the remote server. If the remote tables to be imported
@ -368,7 +368,7 @@
<para> <para>
Importing behavior can be customized with the following options Importing behavior can be customized with the following options
(given in the <command>IMPORT FOREIGN SCHEMA</> command): (given in the <command>IMPORT FOREIGN SCHEMA</command> command):
</para> </para>
<variablelist> <variablelist>
@ -376,9 +376,9 @@
<term><literal>import_collate</literal></term> <term><literal>import_collate</literal></term>
<listitem> <listitem>
<para> <para>
This option controls whether column <literal>COLLATE</> options This option controls whether column <literal>COLLATE</literal> options
are included in the definitions of foreign tables imported are included in the definitions of foreign tables imported
from a foreign server. The default is <literal>true</>. You might from a foreign server. The default is <literal>true</literal>. You might
need to turn this off if the remote server has a different set of need to turn this off if the remote server has a different set of
collation names than the local server does, which is likely to be the collation names than the local server does, which is likely to be the
case if it's running on a different operating system. case if it's running on a different operating system.
@ -389,13 +389,13 @@
<term><literal>import_default</literal></term> <term><literal>import_default</literal></term>
<listitem> <listitem>
<para> <para>
This option controls whether column <literal>DEFAULT</> expressions This option controls whether column <literal>DEFAULT</literal> expressions
are included in the definitions of foreign tables imported are included in the definitions of foreign tables imported
from a foreign server. The default is <literal>false</>. If you from a foreign server. The default is <literal>false</literal>. If you
enable this option, be wary of defaults that might get computed enable this option, be wary of defaults that might get computed
differently on the local server than they would be on the remote differently on the local server than they would be on the remote
server; <function>nextval()</> is a common source of problems. server; <function>nextval()</function> is a common source of problems.
The <command>IMPORT</> will fail altogether if an imported default The <command>IMPORT</command> will fail altogether if an imported default
expression uses a function or operator that does not exist locally. expression uses a function or operator that does not exist locally.
</para> </para>
</listitem> </listitem>
@ -404,25 +404,25 @@
<term><literal>import_not_null</literal></term> <term><literal>import_not_null</literal></term>
<listitem> <listitem>
<para> <para>
This option controls whether column <literal>NOT NULL</> This option controls whether column <literal>NOT NULL</literal>
constraints are included in the definitions of foreign tables imported constraints are included in the definitions of foreign tables imported
from a foreign server. The default is <literal>true</>. from a foreign server. The default is <literal>true</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
<para> <para>
Note that constraints other than <literal>NOT NULL</> will never be Note that constraints other than <literal>NOT NULL</literal> will never be
imported from the remote tables. Although <productname>PostgreSQL</> imported from the remote tables. Although <productname>PostgreSQL</productname>
does support <literal>CHECK</> constraints on foreign tables, there is no does support <literal>CHECK</literal> constraints on foreign tables, there is no
provision for importing them automatically, because of the risk that a provision for importing them automatically, because of the risk that a
constraint expression could evaluate differently on the local and remote constraint expression could evaluate differently on the local and remote
servers. Any such inconsistency in the behavior of a <literal>CHECK</> servers. Any such inconsistency in the behavior of a <literal>CHECK</literal>
constraint could lead to hard-to-detect errors in query optimization. constraint could lead to hard-to-detect errors in query optimization.
So if you wish to import <literal>CHECK</> constraints, you must do so So if you wish to import <literal>CHECK</literal> constraints, you must do so
manually, and you should verify the semantics of each one carefully. manually, and you should verify the semantics of each one carefully.
For more detail about the treatment of <literal>CHECK</> constraints on For more detail about the treatment of <literal>CHECK</literal> constraints on
foreign tables, see <xref linkend="sql-createforeigntable">. foreign tables, see <xref linkend="sql-createforeigntable">.
</para> </para>
@ -464,18 +464,18 @@
</para> </para>
<para> <para>
The remote transaction uses <literal>SERIALIZABLE</> The remote transaction uses <literal>SERIALIZABLE</literal>
isolation level when the local transaction has <literal>SERIALIZABLE</> isolation level when the local transaction has <literal>SERIALIZABLE</literal>
isolation level; otherwise it uses <literal>REPEATABLE READ</> isolation level; otherwise it uses <literal>REPEATABLE READ</literal>
isolation level. This choice ensures that if a query performs multiple isolation level. This choice ensures that if a query performs multiple
table scans on the remote server, it will get snapshot-consistent results table scans on the remote server, it will get snapshot-consistent results
for all the scans. A consequence is that successive queries within a for all the scans. A consequence is that successive queries within a
single transaction will see the same data from the remote server, even if single transaction will see the same data from the remote server, even if
concurrent updates are occurring on the remote server due to other concurrent updates are occurring on the remote server due to other
activities. That behavior would be expected anyway if the local activities. That behavior would be expected anyway if the local
transaction uses <literal>SERIALIZABLE</> or <literal>REPEATABLE READ</> transaction uses <literal>SERIALIZABLE</literal> or <literal>REPEATABLE READ</literal>
isolation level, but it might be surprising for a <literal>READ isolation level, but it might be surprising for a <literal>READ
COMMITTED</> local transaction. A future COMMITTED</literal> local transaction. A future
<productname>PostgreSQL</productname> release might modify these rules. <productname>PostgreSQL</productname> release might modify these rules.
</para> </para>
</sect2> </sect2>
@ -484,42 +484,42 @@
<title>Remote Query Optimization</title> <title>Remote Query Optimization</title>
<para> <para>
<filename>postgres_fdw</> attempts to optimize remote queries to reduce <filename>postgres_fdw</filename> attempts to optimize remote queries to reduce
the amount of data transferred from foreign servers. This is done by the amount of data transferred from foreign servers. This is done by
sending query <literal>WHERE</> clauses to the remote server for sending query <literal>WHERE</literal> clauses to the remote server for
execution, and by not retrieving table columns that are not needed for execution, and by not retrieving table columns that are not needed for
the current query. To reduce the risk of misexecution of queries, the current query. To reduce the risk of misexecution of queries,
<literal>WHERE</> clauses are not sent to the remote server unless they use <literal>WHERE</literal> clauses are not sent to the remote server unless they use
only data types, operators, and functions that are built-in or belong to an only data types, operators, and functions that are built-in or belong to an
extension that's listed in the foreign server's <literal>extensions</> extension that's listed in the foreign server's <literal>extensions</literal>
option. Operators and functions in such clauses must option. Operators and functions in such clauses must
be <literal>IMMUTABLE</> as well. be <literal>IMMUTABLE</literal> as well.
For an <command>UPDATE</> or <command>DELETE</> query, For an <command>UPDATE</command> or <command>DELETE</command> query,
<filename>postgres_fdw</> attempts to optimize the query execution by <filename>postgres_fdw</filename> attempts to optimize the query execution by
sending the whole query to the remote server if there are no query sending the whole query to the remote server if there are no query
<literal>WHERE</> clauses that cannot be sent to the remote server, <literal>WHERE</literal> clauses that cannot be sent to the remote server,
no local joins for the query, no row-level local <literal>BEFORE</> or no local joins for the query, no row-level local <literal>BEFORE</literal> or
<literal>AFTER</> triggers on the target table, and no <literal>AFTER</literal> triggers on the target table, and no
<literal>CHECK OPTION</> constraints from parent views. <literal>CHECK OPTION</literal> constraints from parent views.
In <command>UPDATE</>, In <command>UPDATE</command>,
expressions to assign to target columns must use only built-in data types, expressions to assign to target columns must use only built-in data types,
<literal>IMMUTABLE</> operators, or <literal>IMMUTABLE</> functions, <literal>IMMUTABLE</literal> operators, or <literal>IMMUTABLE</literal> functions,
to reduce the risk of misexecution of the query. to reduce the risk of misexecution of the query.
</para> </para>
<para> <para>
When <filename>postgres_fdw</> encounters a join between foreign tables on When <filename>postgres_fdw</filename> encounters a join between foreign tables on
the same foreign server, it sends the entire join to the foreign server, the same foreign server, it sends the entire join to the foreign server,
unless for some reason it believes that it will be more efficient to fetch unless for some reason it believes that it will be more efficient to fetch
rows from each table individually, or unless the table references involved rows from each table individually, or unless the table references involved
are subject to different user mappings. While sending the <literal>JOIN</> are subject to different user mappings. While sending the <literal>JOIN</literal>
clauses, it takes the same precautions as mentioned above for the clauses, it takes the same precautions as mentioned above for the
<literal>WHERE</> clauses. <literal>WHERE</literal> clauses.
</para> </para>
<para> <para>
The query that is actually sent to the remote server for execution can The query that is actually sent to the remote server for execution can
be examined using <command>EXPLAIN VERBOSE</>. be examined using <command>EXPLAIN VERBOSE</command>.
</para> </para>
</sect2> </sect2>
@ -527,55 +527,55 @@
<title>Remote Query Execution Environment</title> <title>Remote Query Execution Environment</title>
<para> <para>
In the remote sessions opened by <filename>postgres_fdw</>, In the remote sessions opened by <filename>postgres_fdw</filename>,
the <xref linkend="guc-search-path"> parameter is set to the <xref linkend="guc-search-path"> parameter is set to
just <literal>pg_catalog</>, so that only built-in objects are visible just <literal>pg_catalog</literal>, so that only built-in objects are visible
without schema qualification. This is not an issue for queries without schema qualification. This is not an issue for queries
generated by <filename>postgres_fdw</> itself, because it always generated by <filename>postgres_fdw</filename> itself, because it always
supplies such qualification. However, this can pose a hazard for supplies such qualification. However, this can pose a hazard for
functions that are executed on the remote server via triggers or rules functions that are executed on the remote server via triggers or rules
on remote tables. For example, if a remote table is actually a view, on remote tables. For example, if a remote table is actually a view,
any functions used in that view will be executed with the restricted any functions used in that view will be executed with the restricted
search path. It is recommended to schema-qualify all names in such search path. It is recommended to schema-qualify all names in such
functions, or else attach <literal>SET search_path</> options functions, or else attach <literal>SET search_path</literal> options
(see <xref linkend="sql-createfunction">) to such functions (see <xref linkend="sql-createfunction">) to such functions
to establish their expected search path environment. to establish their expected search path environment.
</para> </para>
<para> <para>
<filename>postgres_fdw</> likewise establishes remote session settings <filename>postgres_fdw</filename> likewise establishes remote session settings
for various parameters: for various parameters:
<itemizedlist spacing="compact"> <itemizedlist spacing="compact">
<listitem> <listitem>
<para> <para>
<xref linkend="guc-timezone"> is set to <literal>UTC</> <xref linkend="guc-timezone"> is set to <literal>UTC</literal>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<xref linkend="guc-datestyle"> is set to <literal>ISO</> <xref linkend="guc-datestyle"> is set to <literal>ISO</literal>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<xref linkend="guc-intervalstyle"> is set to <literal>postgres</> <xref linkend="guc-intervalstyle"> is set to <literal>postgres</literal>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<xref linkend="guc-extra-float-digits"> is set to <literal>3</> for remote <xref linkend="guc-extra-float-digits"> is set to <literal>3</literal> for remote
servers 9.0 and newer and is set to <literal>2</> for older versions servers 9.0 and newer and is set to <literal>2</literal> for older versions
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
These are less likely to be problematic than <varname>search_path</>, but These are less likely to be problematic than <varname>search_path</varname>, but
can be handled with function <literal>SET</> options if the need arises. can be handled with function <literal>SET</literal> options if the need arises.
</para> </para>
<para> <para>
It is <emphasis>not</> recommended that you override this behavior by It is <emphasis>not</emphasis> recommended that you override this behavior by
changing the session-level settings of these parameters; that is likely changing the session-level settings of these parameters; that is likely
to cause <filename>postgres_fdw</> to malfunction. to cause <filename>postgres_fdw</filename> to malfunction.
</para> </para>
</sect2> </sect2>
@ -583,19 +583,19 @@
<title>Cross-Version Compatibility</title> <title>Cross-Version Compatibility</title>
<para> <para>
<filename>postgres_fdw</> can be used with remote servers dating back <filename>postgres_fdw</filename> can be used with remote servers dating back
to <productname>PostgreSQL</> 8.3. Read-only capability is available to <productname>PostgreSQL</productname> 8.3. Read-only capability is available
back to 8.1. A limitation however is that <filename>postgres_fdw</> back to 8.1. A limitation however is that <filename>postgres_fdw</filename>
generally assumes that immutable built-in functions and operators are generally assumes that immutable built-in functions and operators are
safe to send to the remote server for execution, if they appear in a safe to send to the remote server for execution, if they appear in a
<literal>WHERE</> clause for a foreign table. Thus, a built-in <literal>WHERE</literal> clause for a foreign table. Thus, a built-in
function that was added since the remote server's release might be sent function that was added since the remote server's release might be sent
to it for execution, resulting in <quote>function does not exist</> or to it for execution, resulting in <quote>function does not exist</quote> or
a similar error. This type of failure can be worked around by a similar error. This type of failure can be worked around by
rewriting the query, for example by embedding the foreign table rewriting the query, for example by embedding the foreign table
reference in a sub-<literal>SELECT</> with <literal>OFFSET 0</> as an reference in a sub-<literal>SELECT</literal> with <literal>OFFSET 0</literal> as an
optimization fence, and placing the problematic function or operator optimization fence, and placing the problematic function or operator
outside the sub-<literal>SELECT</>. outside the sub-<literal>SELECT</literal>.
</para> </para>
</sect2> </sect2>
@ -604,7 +604,7 @@
<para> <para>
Here is an example of creating a foreign table with Here is an example of creating a foreign table with
<literal>postgres_fdw</>. First install the extension: <literal>postgres_fdw</literal>. First install the extension:
</para> </para>
<programlisting> <programlisting>
@ -613,7 +613,7 @@ CREATE EXTENSION postgres_fdw;
<para> <para>
Then create a foreign server using <xref linkend="sql-createserver">. Then create a foreign server using <xref linkend="sql-createserver">.
In this example we wish to connect to a <productname>PostgreSQL</> server In this example we wish to connect to a <productname>PostgreSQL</productname> server
on host <literal>192.83.123.89</literal> listening on on host <literal>192.83.123.89</literal> listening on
port <literal>5432</literal>. The database to which the connection is made port <literal>5432</literal>. The database to which the connection is made
is named <literal>foreign_db</literal> on the remote server: is named <literal>foreign_db</literal> on the remote server:
@ -640,9 +640,9 @@ CREATE USER MAPPING FOR local_user
<para> <para>
Now it is possible to create a foreign table with Now it is possible to create a foreign table with
<xref linkend="sql-createforeigntable">. In this example we <xref linkend="sql-createforeigntable">. In this example we
wish to access the table named <structname>some_schema.some_table</> wish to access the table named <structname>some_schema.some_table</structname>
on the remote server. The local name for it will on the remote server. The local name for it will
be <structname>foreign_table</>: be <structname>foreign_table</structname>:
<programlisting> <programlisting>
CREATE FOREIGN TABLE foreign_table ( CREATE FOREIGN TABLE foreign_table (
@ -654,8 +654,8 @@ CREATE FOREIGN TABLE foreign_table (
</programlisting> </programlisting>
It's essential that the data types and other properties of the columns It's essential that the data types and other properties of the columns
declared in <command>CREATE FOREIGN TABLE</> match the actual remote table. declared in <command>CREATE FOREIGN TABLE</command> match the actual remote table.
Column names must match as well, unless you attach <literal>column_name</> Column names must match as well, unless you attach <literal>column_name</literal>
options to the individual columns to show how they are named in the remote options to the individual columns to show how they are named in the remote
table. table.
In many cases, use of <xref linkend="sql-importforeignschema"> is In many cases, use of <xref linkend="sql-importforeignschema"> is

View File

@ -85,11 +85,11 @@
<para> <para>
Readers of this part should know how to connect to a Readers of this part should know how to connect to a
<productname>PostgreSQL</> database and issue <productname>PostgreSQL</productname> database and issue
<acronym>SQL</acronym> commands. Readers that are unfamiliar with <acronym>SQL</acronym> commands. Readers that are unfamiliar with
these issues are encouraged to read <xref linkend="tutorial"> these issues are encouraged to read <xref linkend="tutorial">
first. <acronym>SQL</acronym> commands are typically entered first. <acronym>SQL</acronym> commands are typically entered
using the <productname>PostgreSQL</> interactive terminal using the <productname>PostgreSQL</productname> interactive terminal
<application>psql</application>, but other programs that have <application>psql</application>, but other programs that have
similar functionality can be used as well. similar functionality can be used as well.
</para> </para>
@ -116,10 +116,10 @@
<partintro> <partintro>
<para> <para>
This part covers topics that are of interest to a This part covers topics that are of interest to a
<productname>PostgreSQL</> database administrator. This includes <productname>PostgreSQL</productname> database administrator. This includes
installation of the software, set up and configuration of the installation of the software, set up and configuration of the
server, management of users and databases, and maintenance tasks. server, management of users and databases, and maintenance tasks.
Anyone who runs a <productname>PostgreSQL</> server, even for Anyone who runs a <productname>PostgreSQL</productname> server, even for
personal use, but especially in production, should be familiar personal use, but especially in production, should be familiar
with the topics covered in this part. with the topics covered in this part.
</para> </para>
@ -139,7 +139,7 @@
up their own server can begin their exploration with this part. up their own server can begin their exploration with this part.
The rest of this part is about tuning and management; that material The rest of this part is about tuning and management; that material
assumes that the reader is familiar with the general use of assumes that the reader is familiar with the general use of
the <productname>PostgreSQL</> database system. Readers are the <productname>PostgreSQL</productname> database system. Readers are
encouraged to look at <xref linkend="tutorial"> and <xref encouraged to look at <xref linkend="tutorial"> and <xref
linkend="sql"> for additional information. linkend="sql"> for additional information.
</para> </para>
@ -171,7 +171,7 @@
<partintro> <partintro>
<para> <para>
This part describes the client programming interfaces distributed This part describes the client programming interfaces distributed
with <productname>PostgreSQL</>. Each of these chapters can be with <productname>PostgreSQL</productname>. Each of these chapters can be
read independently. Note that there are many other programming read independently. Note that there are many other programming
interfaces for client programs that are distributed separately and interfaces for client programs that are distributed separately and
contain their own documentation (<xref linkend="external-projects"> contain their own documentation (<xref linkend="external-projects">
@ -197,7 +197,7 @@
This part is about extending the server functionality with This part is about extending the server functionality with
user-defined functions, data types, triggers, etc. These are user-defined functions, data types, triggers, etc. These are
advanced topics which should probably be approached only after all advanced topics which should probably be approached only after all
the other user documentation about <productname>PostgreSQL</> has the other user documentation about <productname>PostgreSQL</productname> has
been understood. Later chapters in this part describe the server-side been understood. Later chapters in this part describe the server-side
programming languages available in the programming languages available in the
<productname>PostgreSQL</productname> distribution as well as <productname>PostgreSQL</productname> distribution as well as
@ -234,7 +234,7 @@
<partintro> <partintro>
<para> <para>
This part contains assorted information that might be of use to This part contains assorted information that might be of use to
<productname>PostgreSQL</> developers. <productname>PostgreSQL</productname> developers.
</para> </para>
</partintro> </partintro>

View File

@ -145,7 +145,7 @@
</para> </para>
<para> <para>
If your application uses some other client interface, such as <application>PHP</>, then If your application uses some other client interface, such as <application>PHP</application>, then
please try to isolate the offending queries. We will probably not set up a please try to isolate the offending queries. We will probably not set up a
web server to reproduce your problem. In any case remember to provide web server to reproduce your problem. In any case remember to provide
the exact input files; do not guess that the problem happens for the exact input files; do not guess that the problem happens for
@ -167,10 +167,10 @@
<note> <note>
<para> <para>
If you are reporting an error message, please obtain the most verbose If you are reporting an error message, please obtain the most verbose
form of the message. In <application>psql</>, say <literal>\set form of the message. In <application>psql</application>, say <literal>\set
VERBOSITY verbose</> beforehand. If you are extracting the message VERBOSITY verbose</literal> beforehand. If you are extracting the message
from the server log, set the run-time parameter from the server log, set the run-time parameter
<xref linkend="guc-log-error-verbosity"> to <literal>verbose</> so that all <xref linkend="guc-log-error-verbosity"> to <literal>verbose</literal> so that all
details are logged. details are logged.
</para> </para>
</note> </note>
@ -236,9 +236,9 @@
If your version is older than &version; we will almost certainly If your version is older than &version; we will almost certainly
tell you to upgrade. There are many bug fixes and improvements tell you to upgrade. There are many bug fixes and improvements
in each new release, so it is quite possible that a bug you have in each new release, so it is quite possible that a bug you have
encountered in an older release of <productname>PostgreSQL</> encountered in an older release of <productname>PostgreSQL</productname>
has already been fixed. We can only provide limited support for has already been fixed. We can only provide limited support for
sites using older releases of <productname>PostgreSQL</>; if you sites using older releases of <productname>PostgreSQL</productname>; if you
require more than we can provide, consider acquiring a require more than we can provide, consider acquiring a
commercial support contract. commercial support contract.
</para> </para>
@ -283,8 +283,8 @@
are specifically talking about the backend process, mention that, do not are specifically talking about the backend process, mention that, do not
just say <quote>PostgreSQL crashes</quote>. A crash of a single just say <quote>PostgreSQL crashes</quote>. A crash of a single
backend process is quite different from crash of the parent backend process is quite different from crash of the parent
<quote>postgres</> process; please don't say <quote>the server <quote>postgres</quote> process; please don't say <quote>the server
crashed</> when you mean a single backend process went down, nor vice versa. crashed</quote> when you mean a single backend process went down, nor vice versa.
Also, client programs such as the interactive frontend <quote><application>psql</application></quote> Also, client programs such as the interactive frontend <quote><application>psql</application></quote>
are completely separate from the backend. Please try to be specific are completely separate from the backend. Please try to be specific
about whether the problem is on the client or server side. about whether the problem is on the client or server side.
@ -356,10 +356,10 @@
subscribed to a list to be allowed to post on it. (You need not be subscribed to a list to be allowed to post on it. (You need not be
subscribed to use the bug-report web form, however.) subscribed to use the bug-report web form, however.)
If you would like to send mail but do not want to receive list traffic, If you would like to send mail but do not want to receive list traffic,
you can subscribe and set your subscription option to <literal>nomail</>. you can subscribe and set your subscription option to <literal>nomail</literal>.
For more information send mail to For more information send mail to
<email>majordomo@postgresql.org</email> <email>majordomo@postgresql.org</email>
with the single word <literal>help</> in the body of the message. with the single word <literal>help</literal> in the body of the message.
</para> </para>
</note> </note>
</sect2> </sect2>

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More