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
# -wfully-tagged needed to throw a warning on missing tags
# 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
# to detect whether we are using OpenSP rather than the ancient
# original SP.
override SPFLAGS += -wempty
ifneq (,$(filter o%,$(notdir $(OSX))))
override SPFLAGS += -wdata-delim -winstance-ignore-ms -winstance-include-ms -winstance-param-entity
endif

View File

@ -4,8 +4,8 @@
<title>Acronyms</title>
<para>
This is a list of acronyms commonly used in the <productname>PostgreSQL</>
documentation and in discussions about <productname>PostgreSQL</>.
This is a list of acronyms commonly used in the <productname>PostgreSQL</productname>
documentation and in discussions about <productname>PostgreSQL</productname>.
<variablelist>
@ -153,7 +153,7 @@
<ulink
url="http://en.wikipedia.org/wiki/Data_Definition_Language">Data
Definition Language</ulink>, SQL commands such as <command>CREATE
TABLE</>, <command>ALTER USER</>
TABLE</command>, <command>ALTER USER</command>
</para>
</listitem>
</varlistentry>
@ -164,8 +164,8 @@
<para>
<ulink
url="http://en.wikipedia.org/wiki/Data_Manipulation_Language">Data
Manipulation Language</ulink>, SQL commands such as <command>INSERT</>,
<command>UPDATE</>, <command>DELETE</>
Manipulation Language</ulink>, SQL commands such as <command>INSERT</command>,
<command>UPDATE</command>, <command>DELETE</command>
</para>
</listitem>
</varlistentry>
@ -281,7 +281,7 @@
<listitem>
<para>
<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>
</listitem>
</varlistentry>
@ -384,7 +384,7 @@
<term><acronym>LSN</acronym></term>
<listitem>
<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>.
</para>
</listitem>
@ -486,7 +486,7 @@
<term><acronym>PGSQL</acronym></term>
<listitem>
<para>
<link linkend="postgres"><productname>PostgreSQL</></link>
<link linkend="postgres"><productname>PostgreSQL</productname></link>
</para>
</listitem>
</varlistentry>
@ -495,7 +495,7 @@
<term><acronym>PGXS</acronym></term>
<listitem>
<para>
<link linkend="extend-pgxs"><productname>PostgreSQL</> Extension System</link>
<link linkend="extend-pgxs"><productname>PostgreSQL</productname> Extension System</link>
</para>
</listitem>
</varlistentry>

View File

@ -8,8 +8,8 @@
</indexterm>
<para>
<filename>adminpack</> provides a number of support functions which
<application>pgAdmin</> and other administration and management tools can
<filename>adminpack</filename> provides a number of support functions which
<application>pgAdmin</application> and other administration and management tools can
use to provide additional functionality, such as remote management
of server log files.
Use of all these functions is restricted to superusers.
@ -25,7 +25,7 @@
</para>
<table id="functions-adminpack-table">
<title><filename>adminpack</> Functions</title>
<title><filename>adminpack</filename> Functions</title>
<tgroup cols="3">
<thead>
<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><type>setof record</type></entry>
<entry>
List the log files in the <varname>log_directory</> directory
List the log files in the <varname>log_directory</varname> directory
</entry>
</row>
</tbody>
@ -69,9 +69,9 @@
<primary>pg_file_write</primary>
</indexterm>
<para>
<function>pg_file_write</> writes the specified <parameter>data</> into
the file named by <parameter>filename</>. If <parameter>append</> is
false, the file must not already exist. If <parameter>append</> is true,
<function>pg_file_write</function> writes the specified <parameter>data</parameter> into
the file named by <parameter>filename</parameter>. If <parameter>append</parameter> is
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.
Returns the number of bytes written.
</para>
@ -80,15 +80,15 @@
<primary>pg_file_rename</primary>
</indexterm>
<para>
<function>pg_file_rename</> renames a file. If <parameter>archivename</>
is omitted or NULL, it simply renames <parameter>oldname</>
to <parameter>newname</> (which must not already exist).
If <parameter>archivename</> is provided, it first
renames <parameter>newname</> to <parameter>archivename</> (which must
not already exist), and then renames <parameter>oldname</>
to <parameter>newname</>. In event of failure of the second rename step,
it will try to rename <parameter>archivename</> back
to <parameter>newname</> before reporting the error.
<function>pg_file_rename</function> renames a file. If <parameter>archivename</parameter>
is omitted or NULL, it simply renames <parameter>oldname</parameter>
to <parameter>newname</parameter> (which must not already exist).
If <parameter>archivename</parameter> is provided, it first
renames <parameter>newname</parameter> to <parameter>archivename</parameter> (which must
not already exist), and then renames <parameter>oldname</parameter>
to <parameter>newname</parameter>. In event of failure of the second rename step,
it will try to rename <parameter>archivename</parameter> back
to <parameter>newname</parameter> before reporting the error.
Returns true on success, false if the source file(s) are not present or
not writable; other cases throw errors.
</para>
@ -97,19 +97,19 @@
<primary>pg_file_unlink</primary>
</indexterm>
<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
or the <function>unlink()</> call fails; other cases throw errors.
or the <function>unlink()</function> call fails; other cases throw errors.
</para>
<indexterm>
<primary>pg_logdir_ls</primary>
</indexterm>
<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">
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.
</para>
@ -119,12 +119,12 @@
and should not be used in new applications; instead use those shown
in <xref linkend="functions-admin-signal-table">
and <xref linkend="functions-admin-genfile-table">. These functions are
provided in <filename>adminpack</> only for compatibility with old
versions of <application>pgAdmin</>.
provided in <filename>adminpack</filename> only for compatibility with old
versions of <application>pgAdmin</application>.
</para>
<table id="functions-adminpack-deprecated-table">
<title>Deprecated <filename>adminpack</> Functions</title>
<title>Deprecated <filename>adminpack</filename> Functions</title>
<tgroup cols="3">
<thead>
<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><type>text</type></entry>
<entry>
Alternate name for <function>pg_read_file()</>
Alternate name for <function>pg_read_file()</function>
</entry>
</row>
<row>
<entry><function>pg_catalog.pg_file_length(filename text)</function></entry>
<entry><type>bigint</type></entry>
<entry>
Same as <structfield>size</> column returned
by <function>pg_stat_file()</>
Same as <structfield>size</structfield> column returned
by <function>pg_stat_file()</function>
</entry>
</row>
<row>
<entry><function>pg_catalog.pg_logfile_rotate()</function></entry>
<entry><type>integer</type></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>
</entry>
</row>

View File

@ -145,7 +145,7 @@ DETAIL: Key (city)=(Berkeley) is not present in table "cities".
</indexterm>
<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
multiple steps into a single, all-or-nothing operation. The intermediate
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.
We need a guarantee that if something goes wrong partway through the
operation, none of the steps executed so far will take effect. Grouping
the updates into a <firstterm>transaction</> gives us this guarantee.
A transaction is said to be <firstterm>atomic</>: from the point of
the updates into a <firstterm>transaction</firstterm> gives us this guarantee.
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.
</para>
@ -216,9 +216,9 @@ UPDATE branches SET balance = balance + 100.00
</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
<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:
<programlisting>
@ -233,23 +233,23 @@ COMMIT;
<para>
If, partway through the transaction, we decide we do not want to
commit (perhaps we just noticed that Alice's balance went negative),
we can issue the command <command>ROLLBACK</> instead of
<command>COMMIT</>, and all our updates so far will be canceled.
we can issue the command <command>ROLLBACK</command> instead of
<command>COMMIT</command>, and all our updates so far will be canceled.
</para>
<para>
<productname>PostgreSQL</> actually treats every SQL statement as being
executed within a transaction. If you do not issue a <command>BEGIN</>
<productname>PostgreSQL</productname> actually treats every SQL statement as being
executed within a transaction. If you do not issue a <command>BEGIN</command>
command,
then each individual statement has an implicit <command>BEGIN</> and
(if successful) <command>COMMIT</> wrapped around it. A group of
statements surrounded by <command>BEGIN</> and <command>COMMIT</>
is sometimes called a <firstterm>transaction block</>.
then each individual statement has an implicit <command>BEGIN</command> and
(if successful) <command>COMMIT</command> wrapped around it. A group of
statements surrounded by <command>BEGIN</command> and <command>COMMIT</command>
is sometimes called a <firstterm>transaction block</firstterm>.
</para>
<note>
<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
blocks without asking. Check the documentation for the interface
you are using.
@ -258,11 +258,11 @@ COMMIT;
<para>
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
committing the rest. After defining a savepoint with
<command>SAVEPOINT</>, you can if needed roll back to the savepoint
with <command>ROLLBACK TO</>. All the transaction's database changes
<command>SAVEPOINT</command>, you can if needed roll back to the savepoint
with <command>ROLLBACK TO</command>. All the transaction's database changes
between defining the savepoint and rolling back to it are discarded, but
changes earlier than the savepoint are kept.
</para>
@ -308,7 +308,7 @@ COMMIT;
<para>
This example is, of course, oversimplified, but there's a lot of control
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
system due to an error, short of rolling it back completely and starting
again.
@ -325,7 +325,7 @@ COMMIT;
</indexterm>
<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
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
@ -360,31 +360,31 @@ SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM emps
</screen>
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
rows that have the same <structfield>depname</> value as the current row.
(This actually is the same function as the non-window <function>avg</>
aggregate, but the <literal>OVER</> clause causes it to be
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</function>
aggregate, but the <literal>OVER</literal> clause causes it to be
treated as a window function and computed across the window frame.)
</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
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.
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
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
same partition as the current row.
</para>
<para>
You can also control the order in which rows are processed by
window functions using <literal>ORDER BY</> within <literal>OVER</>.
(The window <literal>ORDER BY</> does not even have to match the
window functions using <literal>ORDER BY</literal> within <literal>OVER</literal>.
(The window <literal>ORDER BY</literal> does not even have to match the
order in which the rows are output.) Here is an example:
<programlisting>
@ -409,39 +409,39 @@ FROM empsalary;
(10 rows)
</screen>
As shown here, the <function>rank</> function produces a numerical rank
for each distinct <literal>ORDER BY</> value in the current row's
partition, using the order defined by the <literal>ORDER BY</> clause.
<function>rank</> needs no explicit parameter, because its behavior
is entirely determined by the <literal>OVER</> clause.
As shown here, the <function>rank</function> function produces a numerical rank
for each distinct <literal>ORDER BY</literal> value in the current row's
partition, using the order defined by the <literal>ORDER BY</literal> clause.
<function>rank</function> needs no explicit parameter, because its behavior
is entirely determined by the <literal>OVER</literal> clause.
</para>
<para>
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
<literal>WHERE</>, <literal>GROUP BY</>, and <literal>HAVING</> clauses
table</quote> produced by the query's <literal>FROM</literal> clause as filtered by its
<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
<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
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.
</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
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>
There is another important concept associated with window functions:
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.
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
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.
<footnote>
<para>
@ -450,7 +450,7 @@ FROM empsalary;
<xref linkend="syntax-window-functions"> for details.
</para>
</footnote>
Here is an example using <function>sum</>:
Here is an example using <function>sum</function>:
</para>
<programlisting>
@ -474,11 +474,11 @@ SELECT salary, sum(salary) OVER () FROM empsalary;
</screen>
<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
<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
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:
</para>
@ -510,8 +510,8 @@ SELECT salary, sum(salary) OVER (ORDER BY salary) FROM empsalary;
<para>
Window functions are permitted only in the <literal>SELECT</literal> list
and the <literal>ORDER BY</> clause of the query. They are forbidden
elsewhere, such as in <literal>GROUP BY</>, <literal>HAVING</>
and the <literal>ORDER BY</literal> clause of the query. They are forbidden
elsewhere, such as in <literal>GROUP BY</literal>, <literal>HAVING</literal>
and <literal>WHERE</literal> clauses. This is because they logically
execute after the processing of those clauses. Also, window functions
execute after non-window aggregate functions. This means it is valid to
@ -534,15 +534,15 @@ WHERE pos &lt; 3;
</programlisting>
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>
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
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:
<programlisting>
@ -623,13 +623,13 @@ CREATE TABLE capitals (
<para>
In this case, a row of <classname>capitals</classname>
<firstterm>inherits</firstterm> all columns (<structfield>name</>,
<structfield>population</>, and <structfield>altitude</>) from its
<firstterm>inherits</firstterm> all columns (<structfield>name</structfield>,
<structfield>population</structfield>, and <structfield>altitude</structfield>) from its
<firstterm>parent</firstterm>, <classname>cities</classname>. The
type of the column <structfield>name</structfield> is
<type>text</type>, a native <productname>PostgreSQL</productname>
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
zero or more other tables.
</para>

View File

@ -8,19 +8,19 @@
</indexterm>
<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
structure appears to be valid, no error is raised.
</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
correctness of the access method functions behind index scans and
other important operations relies on these invariants always
holding. For example, certain functions verify, among other things,
that all B-Tree pages have items in <quote>logical</> order (e.g.,
for B-Tree indexes on <type>text</>, index tuples should be in
that all B-Tree pages have items in <quote>logical</quote> order (e.g.,
for B-Tree indexes on <type>text</type>, index tuples should be in
collated lexical order). If that particular invariant somehow fails
to hold, we can expect binary searches on the affected page to
incorrectly guide index scans, resulting in wrong answers to SQL
@ -35,7 +35,7 @@
functions.
</para>
<para>
<filename>amcheck</> functions may be used only by superusers.
<filename>amcheck</filename> functions may be used only by superusers.
</para>
<sect2>
@ -82,7 +82,7 @@ ORDER BY c.relpages DESC LIMIT 10;
(10 rows)
</screen>
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
is raised, all indexes tested appear to be logically consistent.
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.
</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
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
that span child/parent relationships, nor does it verify that
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.
</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
<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
<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
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
only while running, not for the entire transaction.
</para>
@ -159,13 +159,13 @@ ORDER BY c.relpages DESC LIMIT 10;
</sect2>
<sect2>
<title>Using <filename>amcheck</> effectively</title>
<title>Using <filename>amcheck</filename> effectively</title>
<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
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>
<listitem>
@ -176,13 +176,13 @@ ORDER BY c.relpages DESC LIMIT 10;
<para>
This includes issues caused by the comparison rules of operating
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
implies that operating system collation rules must never change.
Though rare, updates to operating system collation rules can
cause these issues. More commonly, an inconsistency in the
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
generally only arise on standby servers, and so can generally
only be detected on standby servers.
@ -190,25 +190,25 @@ ORDER BY c.relpages DESC LIMIT 10;
<para>
If a problem like this arises, it may not affect each individual
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
<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.
</para>
</listitem>
<listitem>
<para>
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.
</para>
<para>
Automatic verification of the structural integrity of indexes
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
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
linkend="regress-run"> for details on running the tests.
</para>
@ -219,12 +219,12 @@ ORDER BY c.relpages DESC LIMIT 10;
simply not be enabled.
</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 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
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.
</para>
</listitem>
@ -234,7 +234,7 @@ ORDER BY c.relpages DESC LIMIT 10;
and operating system.
</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
uses industry standard Error Correcting Codes (ECC) or better
protection. However, ECC memory is typically only immune to
@ -244,7 +244,7 @@ ORDER BY c.relpages DESC LIMIT 10;
</para>
</listitem>
</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.
</para>
@ -252,19 +252,19 @@ ORDER BY c.relpages DESC LIMIT 10;
<sect2>
<title>Repairing corruption</title>
<para>
No error concerning corruption raised by <filename>amcheck</> should
ever be a false positive. In practice, <filename>amcheck</> is more
No error concerning corruption raised by <filename>amcheck</filename> should
ever be a false positive. In practice, <filename>amcheck</filename> is more
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
<filename>amcheck</> errors is often required.
<filename>amcheck</filename> errors is often required.
</para>
<para>
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
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.
</para>

View File

@ -118,7 +118,7 @@
<para>
<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
exactly one <firstterm>server process</firstterm>. As we do not
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
<productname>PostgreSQL</productname> protocol described in
<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
<application>JDBC</> driver.
<application>JDBC</application> driver.
</para>
<para>
@ -184,8 +184,8 @@
text) for valid syntax. If the syntax is correct a
<firstterm>parse tree</firstterm> is built up and handed back;
otherwise an error is returned. The parser and lexer are
implemented using the well-known Unix tools <application>bison</>
and <application>flex</>.
implemented using the well-known Unix tools <application>bison</application>
and <application>flex</application>.
</para>
<para>
@ -251,7 +251,7 @@
back by the parser as input and does the semantic interpretation needed
to understand which tables, functions, and operators are referenced by
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>
@ -259,10 +259,10 @@
system catalog lookups can only be done within a transaction, and we
do not wish to start a transaction immediately upon receiving a query
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.
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
transformation process be invoked.
</para>
@ -270,10 +270,10 @@
<para>
The query tree created by the transformation process is structurally
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
call. This might be transformed to either a <structname>FuncExpr</>
or <structname>Aggref</> node depending on whether the referenced
call. This might be transformed to either a <structname>FuncExpr</structname>
or <structname>Aggref</structname> node depending on whether the referenced
name turns out to be an ordinary function or an aggregate function.
Also, information about the actual data types of columns and expression
results is added to the query tree.
@ -354,10 +354,10 @@
<para>
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
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.
In the rest of this section we'll ignore the distinction between paths
and plans.
@ -378,12 +378,12 @@
<literal>relation.attribute OPR constant</literal>. If
<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
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
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
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).
</para>
@ -462,9 +462,9 @@
the base relations, plus nested-loop, merge, or hash join nodes as
needed, plus any auxiliary steps needed, such as sort nodes or
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)
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
expressions where needed). One of the responsibilities of the
planner is to attach selection conditions from the
@ -496,7 +496,7 @@
subplan) is, let's say, a
<literal>Sort</literal> node and again recursion is needed to obtain
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
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.
@ -529,24 +529,24 @@
<para>
The executor mechanism is used to evaluate all four basic SQL query types:
<command>SELECT</>, <command>INSERT</>, <command>UPDATE</>, and
<command>DELETE</>. For <command>SELECT</>, the top-level executor
<command>SELECT</command>, <command>INSERT</command>, <command>UPDATE</command>, and
<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
to the client. For <command>INSERT</>, each returned row is inserted
into the target table specified for the <command>INSERT</>. This is
done in a special top-level plan node called <literal>ModifyTable</>.
to the client. For <command>INSERT</command>, each returned row is inserted
into the target table specified for the <command>INSERT</command>. This is
done in a special top-level plan node called <literal>ModifyTable</literal>.
(A simple
<command>INSERT ... VALUES</> command creates a trivial plan tree
consisting of a single <literal>Result</> node, which computes just one
result row, and <literal>ModifyTable</> above it to perform the insertion.
But <command>INSERT ... SELECT</> can demand the full power
of the executor mechanism.) For <command>UPDATE</>, the planner arranges
<command>INSERT ... VALUES</command> command creates a trivial plan tree
consisting of a single <literal>Result</literal> node, which computes just one
result row, and <literal>ModifyTable</literal> above it to perform the insertion.
But <command>INSERT ... SELECT</command> can demand the full power
of the executor mechanism.) For <command>UPDATE</command>, the planner arranges
that each computed row includes all the updated column values, plus
the <firstterm>TID</> (tuple ID, or row ID) of the original target row;
this data is fed into a <literal>ModifyTable</> node, which uses the
the <firstterm>TID</firstterm> (tuple ID, or row ID) of the original target row;
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.
For <command>DELETE</>, the only column that is actually returned by the
plan is the TID, and the <literal>ModifyTable</> node simply uses the TID
For <command>DELETE</command>, the only column that is actually returned by the
plan is the TID, and the <literal>ModifyTable</literal> node simply uses the TID
to visit each target row and mark it deleted.
</para>

View File

@ -32,7 +32,7 @@ CREATE TABLE sal_emp (
);
</programlisting>
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
<structname>sal_emp</structname> with a column of type
<type>text</type> (<structfield>name</structfield>), a
@ -69,7 +69,7 @@ CREATE TABLE tictactoe (
<para>
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
as:
<programlisting>
@ -79,7 +79,7 @@ CREATE TABLE tictactoe (
<programlisting>
pay_by_quarter integer ARRAY,
</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.
</para>
</sect2>
@ -107,8 +107,8 @@ CREATE TABLE tictactoe (
for the type, as recorded in its <literal>pg_type</literal> entry.
Among the standard data types provided in the
<productname>PostgreSQL</productname> distribution, all use a comma
(<literal>,</>), except for type <type>box</> which uses a semicolon
(<literal>;</>). Each <replaceable>val</replaceable> is
(<literal>,</literal>), except for type <type>box</type> which uses a semicolon
(<literal>;</literal>). Each <replaceable>val</replaceable> is
either a constant of the array element type, or a subarray. An example
of an array constant is:
<programlisting>
@ -119,10 +119,10 @@ CREATE TABLE tictactoe (
</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
<literal>NULL</> will do.) If you want an actual string value
<quote>NULL</>, you must put double quotes around it.
<literal>NULL</literal> will do.) If you want an actual string value
<quote>NULL</quote>, you must put double quotes around it.
</para>
<para>
@ -176,7 +176,7 @@ ERROR: multidimensional arrays must have array expressions with matching dimens
</para>
<para>
The <literal>ARRAY</> constructor syntax can also be used:
The <literal>ARRAY</literal> constructor syntax can also be used:
<programlisting>
INSERT INTO sal_emp
VALUES ('Bill',
@ -190,7 +190,7 @@ INSERT INTO sal_emp
</programlisting>
Notice that the array elements are ordinary SQL constants or
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
<xref linkend="sql-syntax-array-constructors">.
</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.
By default <productname>PostgreSQL</productname> uses a
one-based numbering convention for arrays, that is,
an array of <replaceable>n</> elements starts with <literal>array[1]</literal> and
ends with <literal>array[<replaceable>n</>]</literal>.
an array of <replaceable>n</replaceable> elements starts with <literal>array[1]</literal> and
ends with <literal>array[<replaceable>n</replaceable>]</literal>.
</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
dimensions are treated as slices. Any dimension that has only a single
number (no colon) is treated as being from 1
to the number specified. For example, <literal>[2]</> is treated as
<literal>[1:2]</>, as in this example:
to the number specified. For example, <literal>[2]</literal> is treated as
<literal>[1:2]</literal>, as in this example:
<programlisting>
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>
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>
@ -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
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).
For example, if <literal>schedule</>
currently has the dimensions <literal>[1:3][1:2]</> then referencing
<literal>schedule[3][3]</> yields NULL. Similarly, an array reference
For example, if <literal>schedule</literal>
currently has the dimensions <literal>[1:3][1:2]</literal> then referencing
<literal>schedule[3][3]</literal> yields NULL. Similarly, an array reference
with the wrong number of subscripts yields a null rather than an error.
</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
present. Any positions between those previously present and the newly
assigned elements will be filled with nulls. For example, if array
<literal>myarray</> currently has 4 elements, it will have six
elements after an update that assigns to <literal>myarray[6]</>;
<literal>myarray[5]</> will contain null.
<literal>myarray</literal> currently has 4 elements, it will have six
elements after an update that assigns to <literal>myarray[6]</literal>;
<literal>myarray[5]</literal> will contain null.
Currently, enlargement in this fashion is only allowed for one-dimensional
arrays, not multidimensional arrays.
</para>
<para>
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.
</para>
@ -457,8 +457,8 @@ SELECT ARRAY[5,6] || ARRAY[[1,2],[3,4]];
<para>
The concatenation operator allows a single element to be pushed onto the
beginning or end of a one-dimensional array. It also accepts two
<replaceable>N</>-dimensional arrays, or an <replaceable>N</>-dimensional
and an <replaceable>N+1</>-dimensional array.
<replaceable>N</replaceable>-dimensional arrays, or an <replaceable>N</replaceable>-dimensional
and an <replaceable>N+1</replaceable>-dimensional array.
</para>
<para>
@ -501,10 +501,10 @@ SELECT array_dims(ARRAY[[1,2],[3,4]] || ARRAY[[5,6],[7,8],[9,0]]);
</para>
<para>
When an <replaceable>N</>-dimensional array is pushed onto the beginning
or end of an <replaceable>N+1</>-dimensional array, the result is
analogous to the element-array case above. Each <replaceable>N</>-dimensional
sub-array is essentially an element of the <replaceable>N+1</>-dimensional
When an <replaceable>N</replaceable>-dimensional array is pushed onto the beginning
or end of an <replaceable>N+1</replaceable>-dimensional array, the result is
analogous to the element-array case above. Each <replaceable>N</replaceable>-dimensional
sub-array is essentially an element of the <replaceable>N+1</replaceable>-dimensional
array's outer dimension. For example:
<programlisting>
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 same type as the operator's other input &mdash; in this case,
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
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.
</para>
</sect2>
@ -633,7 +633,7 @@ SELECT * FROM sal_emp WHERE 10000 = ALL (pay_by_quarter);
</para>
<para>
Alternatively, the <function>generate_subscripts</> function can be used.
Alternatively, the <function>generate_subscripts</function> function can be used.
For example:
<programlisting>
@ -648,7 +648,7 @@ SELECT * FROM
</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.
For instance:
@ -662,8 +662,8 @@ SELECT * FROM sal_emp WHERE pay_by_quarter &amp;&amp; ARRAY[10000];
</para>
<para>
You can also search for specific values in an array using the <function>array_position</>
and <function>array_positions</> functions. The former returns the subscript of
You can also search for specific values in an array using the <function>array_position</function>
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
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
are interpreted according to the I/O conversion rules for the array's
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.
The delimiter character is usually a comma (<literal>,</>) but can be
something else: it is determined by the <literal>typdelim</> setting
The delimiter character is usually a comma (<literal>,</literal>) but can be
something else: it is determined by the <literal>typdelim</literal> setting
for the array's element type. Among the standard data types provided
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,
cube, etc.) gets its own level of curly braces, and delimiters
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
if they are empty strings, contain curly braces, delimiter characters,
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
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
@ -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
subscript ranges can be specified explicitly before writing the
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
a colon (<literal>:</>) delimiter character in between. The
array dimension decoration is followed by an equal sign (<literal>=</>).
a colon (<literal>:</literal>) delimiter character in between. The
array dimension decoration is followed by an equal sign (<literal>=</literal>).
For example:
<programlisting>
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>
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
or backslashes disables this and allows the literal string value
<quote>NULL</> to be entered. Also, for backward compatibility with
pre-8.2 versions of <productname>PostgreSQL</>, the <xref
<quote>NULL</quote> to be entered. Also, for backward compatibility with
pre-8.2 versions of <productname>PostgreSQL</productname>, the <xref
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>
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.
For example, elements containing curly braces, commas (or the data type's
delimiter character), double quotes, backslashes, or leading or trailing
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
and precede it with a backslash. Alternatively, you can avoid quotes and use
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>
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
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:
<programlisting>
INSERT ... VALUES (E'{"\\\\","\\""}');
</programlisting>
The escape string processor removes one level of backslashes, so that
what arrives at the array-value parser looks like <literal>{"\\","\""}</>.
In turn, the strings fed to the <type>text</> data type's input routine
become <literal>\</> and <literal>"</> respectively. (If we were working
what arrives at the array-value parser looks like <literal>{"\\","\""}</literal>.
In turn, the strings fed to the <type>text</type> data type's input routine
become <literal>\</literal> and <literal>"</literal> respectively. (If we were working
with a data type whose input routine also treated backslashes specially,
<type>bytea</> for example, we might need as many as eight backslashes
<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.)
Dollar quoting (see <xref linkend="sql-syntax-dollar-quoting">) can be
used to avoid the need to double backslashes.
@ -804,10 +804,10 @@ INSERT ... VALUES (E'{"\\\\","\\""}');
<tip>
<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
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.
</para>
</tip>

View File

@ -18,7 +18,7 @@
<para>
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>
<sect2>
@ -29,7 +29,7 @@
<term>
<varname>auth_delay.milliseconds</varname> (<type>int</type>)
<indexterm>
<primary><varname>auth_delay.milliseconds</> configuration parameter</primary>
<primary><varname>auth_delay.milliseconds</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
@ -42,7 +42,7 @@
</variablelist>
<para>
These parameters must be set in <filename>postgresql.conf</>.
These parameters must be set in <filename>postgresql.conf</filename>.
Typical usage might be:
</para>

View File

@ -24,10 +24,10 @@ LOAD 'auto_explain';
</programlisting>
(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-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
that.
</para>
@ -47,7 +47,7 @@ LOAD 'auto_explain';
<term>
<varname>auto_explain.log_min_duration</varname> (<type>integer</type>)
<indexterm>
<primary><varname>auto_explain.log_min_duration</> configuration parameter</primary>
<primary><varname>auto_explain.log_min_duration</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
@ -66,13 +66,13 @@ LOAD 'auto_explain';
<term>
<varname>auto_explain.log_analyze</varname> (<type>boolean</type>)
<indexterm>
<primary><varname>auto_explain.log_analyze</> configuration parameter</primary>
<primary><varname>auto_explain.log_analyze</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<para>
<varname>auto_explain.log_analyze</varname> causes <command>EXPLAIN ANALYZE</>
output, rather than just <command>EXPLAIN</> output, to be printed
<varname>auto_explain.log_analyze</varname> causes <command>EXPLAIN ANALYZE</command>
output, rather than just <command>EXPLAIN</command> output, to be printed
when an execution plan is logged. This parameter is off by default.
Only superusers can change this setting.
</para>
@ -92,14 +92,14 @@ LOAD 'auto_explain';
<term>
<varname>auto_explain.log_buffers</varname> (<type>boolean</type>)
<indexterm>
<primary><varname>auto_explain.log_buffers</> configuration parameter</primary>
<primary><varname>auto_explain.log_buffers</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<para>
<varname>auto_explain.log_buffers</varname> controls whether buffer
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
unless <varname>auto_explain.log_analyze</varname> is enabled.
This parameter is off by default.
@ -112,14 +112,14 @@ LOAD 'auto_explain';
<term>
<varname>auto_explain.log_timing</varname> (<type>boolean</type>)
<indexterm>
<primary><varname>auto_explain.log_timing</> configuration parameter</primary>
<primary><varname>auto_explain.log_timing</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<para>
<varname>auto_explain.log_timing</varname> controls whether per-node
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
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
@ -136,7 +136,7 @@ LOAD 'auto_explain';
<term>
<varname>auto_explain.log_triggers</varname> (<type>boolean</type>)
<indexterm>
<primary><varname>auto_explain.log_triggers</> configuration parameter</primary>
<primary><varname>auto_explain.log_triggers</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
@ -155,14 +155,14 @@ LOAD 'auto_explain';
<term>
<varname>auto_explain.log_verbose</varname> (<type>boolean</type>)
<indexterm>
<primary><varname>auto_explain.log_verbose</> configuration parameter</primary>
<primary><varname>auto_explain.log_verbose</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<para>
<varname>auto_explain.log_verbose</varname> controls whether verbose
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.
Only superusers can change this setting.
</para>
@ -173,13 +173,13 @@ LOAD 'auto_explain';
<term>
<varname>auto_explain.log_format</varname> (<type>enum</type>)
<indexterm>
<primary><varname>auto_explain.log_format</> configuration parameter</primary>
<primary><varname>auto_explain.log_format</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<para>
<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>,
<literal>json</literal>, and <literal>yaml</literal>. The default is text.
Only superusers can change this setting.
@ -191,7 +191,7 @@ LOAD 'auto_explain';
<term>
<varname>auto_explain.log_nested_statements</varname> (<type>boolean</type>)
<indexterm>
<primary><varname>auto_explain.log_nested_statements</> configuration parameter</primary>
<primary><varname>auto_explain.log_nested_statements</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
@ -208,7 +208,7 @@ LOAD 'auto_explain';
<term>
<varname>auto_explain.sample_rate</varname> (<type>real</type>)
<indexterm>
<primary><varname>auto_explain.sample_rate</> configuration parameter</primary>
<primary><varname>auto_explain.sample_rate</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
@ -224,7 +224,7 @@ LOAD 'auto_explain';
<para>
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.
Typical usage might be:
</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.
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.
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
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.
</para>
<warning>
<para>
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
modules that include background worker process should exercise extreme
caution. Only carefully audited modules should be permitted to run
@ -31,15 +31,15 @@
<para>
Background workers can be initialized at the time that
<productname>PostgreSQL</> is started by including the module name in
<varname>shared_preload_libraries</>. A module wishing to run a background
<productname>PostgreSQL</productname> is started by including the module name in
<varname>shared_preload_libraries</varname>. A module wishing to run a background
worker can register it by calling
<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
<function>RegisterDynamicBackgroundWorker(<type>BackgroundWorker
*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
called from a regular backend.
</para>
@ -65,7 +65,7 @@ typedef struct BackgroundWorker
</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.
<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
@ -76,7 +76,7 @@ typedef struct BackgroundWorker
</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:
<variablelist>
@ -114,14 +114,14 @@ typedef struct BackgroundWorker
<para>
<structfield>bgw_start_time</structfield> is the server state during which
<command>postgres</> should start the process; it can be one of
<literal>BgWorkerStart_PostmasterStart</> (start as soon as
<command>postgres</> itself has finished its own initialization; processes
<command>postgres</command> should start the process; it can be one of
<literal>BgWorkerStart_PostmasterStart</literal> (start as soon as
<command>postgres</command> itself has finished its own initialization; processes
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
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
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
@ -152,9 +152,9 @@ typedef struct BackgroundWorker
</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
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.
In addition, the global variable <literal>MyBgworkerEntry</literal>
points to a copy of the <structname>BackgroundWorker</structname> structure
@ -165,39 +165,39 @@ typedef struct BackgroundWorker
<para>
On Windows (and anywhere else where <literal>EXEC_BACKEND</literal> is
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
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
new background worker process.
</para>
<para>
<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
accessed via <literal>MyBgworkerEntry</literal>, as discussed above.
</para>
<para>
<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
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
initialized to <literal>MyProcPid</>.
initialized to <literal>MyProcPid</literal>.
</para>
<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>BackgroundWorkerInitializeConnectionByOid(<parameter>Oid dboid</parameter>, <parameter>Oid useroid</parameter>)</function>.
This allows the process to run transactions and queries using the
<literal>SPI</literal> interface. If <varname>dbname</> is NULL or
<varname>dboid</> is <literal>InvalidOid</>, the session is not connected
<literal>SPI</literal> interface. If <varname>dbname</varname> is NULL or
<varname>dboid</varname> is <literal>InvalidOid</literal>, the session is not connected
to any particular database, but shared catalogs can be accessed.
If <varname>username</> is NULL or <varname>useroid</> is
<literal>InvalidOid</>, the process will run as the superuser created
during <command>initdb</>.
If <varname>username</varname> is NULL or <varname>useroid</varname> is
<literal>InvalidOid</literal>, the process will run as the superuser created
during <command>initdb</command>.
A background worker can only call one of these two functions, and only
once. It is not possible to switch databases.
</para>
@ -207,24 +207,24 @@ typedef struct BackgroundWorker
background worker's main function, and must be unblocked by it; this is to
allow the process to customize its signal handlers, if necessary.
Signals can be unblocked in the new process by calling
<function>BackgroundWorkerUnblockSignals</> and blocked by calling
<function>BackgroundWorkerBlockSignals</>.
<function>BackgroundWorkerUnblockSignals</function> and blocked by calling
<function>BackgroundWorkerBlockSignals</function>.
</para>
<para>
If <structfield>bgw_restart_time</structfield> for a background worker is
configured as <literal>BGW_NEVER_RESTART</>, or if it exits with an exit
code of 0 or is terminated by <function>TerminateBackgroundWorker</>,
configured as <literal>BGW_NEVER_RESTART</literal>, or if it exits with an exit
code of 0 or is terminated by <function>TerminateBackgroundWorker</function>,
it will be automatically unregistered by the postmaster on exit.
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
to suspend execution only temporarily should use an interruptible sleep
rather than exiting; this can be achieved by calling
<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
<command>postgres</> itself has terminated.
<command>postgres</command> itself has terminated.
</para>
<para>
@ -238,29 +238,29 @@ typedef struct BackgroundWorker
opaque handle that can subsequently be passed to
<function>GetBackgroundWorkerPid(<parameter>BackgroundWorkerHandle *</parameter>, <parameter>pid_t *</parameter>)</function> or
<function>TerminateBackgroundWorker(<parameter>BackgroundWorkerHandle *</parameter>)</function>.
<function>GetBackgroundWorkerPid</> can be used to poll the status of the
worker: a return value of <literal>BGWH_NOT_YET_STARTED</> indicates that
<function>GetBackgroundWorkerPid</function> can be used to poll the status of the
worker: a return value of <literal>BGWH_NOT_YET_STARTED</literal> indicates that
the worker has not yet been started by the postmaster;
<literal>BGWH_STOPPED</literal> indicates that it has been started but 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
second argument.
<function>TerminateBackgroundWorker</> causes the postmaster to send
<literal>SIGTERM</> to the worker if it is running, and to unregister it
<function>TerminateBackgroundWorker</function> causes the postmaster to send
<literal>SIGTERM</literal> to the worker if it is running, and to unregister it
as soon as it is not.
</para>
<para>
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
<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
registration time to
<function>WaitForBackgroundWorkerStartup(<parameter>BackgroundWorkerHandle
*handle</parameter>, <parameter>pid_t *</parameter>)</function> function.
This function will block until the postmaster has attempted to start the
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
value will be <literal>BGWH_STOPPED</literal> or
<literal>BGWH_POSTMASTER_DIED</literal>.
@ -279,7 +279,7 @@ typedef struct BackgroundWorker
</para>
<para>
The <filename>src/test/modules/worker_spi</> module
The <filename>src/test/modules/worker_spi</filename> module
contains a working example,
which demonstrates some useful techniques.
</para>

View File

@ -171,7 +171,7 @@ ssimkovi@ag.or.at
<abstract>
<para>
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
Thesis with the support of O. Univ. Prof. Dr. Georg Gottlob and
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
part of building and installing <productname>PostgreSQL</productname>
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
is called <filename>postgres.bki</filename> and is
normally installed in the
@ -67,13 +67,13 @@
<variablelist>
<varlistentry>
<term>
<literal>create</>
<literal>create</literal>
<replaceable class="parameter">tablename</replaceable>
<replaceable class="parameter">tableoid</replaceable>
<optional><literal>bootstrap</></optional>
<optional><literal>shared_relation</></optional>
<optional><literal>without_oids</></optional>
<optional><literal>rowtype_oid</> <replaceable>oid</></optional>
<optional><literal>bootstrap</literal></optional>
<optional><literal>shared_relation</literal></optional>
<optional><literal>without_oids</literal></optional>
<optional><literal>rowtype_oid</literal> <replaceable>oid</replaceable></optional>
(<replaceable class="parameter">name1</replaceable> =
<replaceable class="parameter">type1</replaceable>
<optional>FORCE NOT NULL | FORCE NULL </optional> <optional>,
@ -93,7 +93,7 @@
<para>
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>name</type>, <type>int2</type>,
<type>int4</type>, <type>regproc</type>, <type>regclass</type>,
@ -104,31 +104,31 @@
<type>_oid</type> (array), <type>_char</type> (array),
<type>_aclitem</type> (array). Although it is possible to create
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
column types can be used in bootstrapped tables, but non-bootstrap
catalogs can contain any built-in type.)
</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
<structname>pg_class</structname>,
<structname>pg_attribute</structname>, etc, for it. Thus the
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
<structname>pg_class</structname> etc themselves.
</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.
It will have OIDs unless <literal>without_oids</> is specified.
The table's row type OID (<structname>pg_type</> OID) can optionally
be specified via the <literal>rowtype_oid</> clause; if not specified,
an OID is automatically generated for it. (The <literal>rowtype_oid</>
clause is useless if <literal>bootstrap</> is specified, but it can be
It will have OIDs unless <literal>without_oids</literal> is specified.
The table's row type OID (<structname>pg_type</structname> OID) can optionally
be specified via the <literal>rowtype_oid</literal> clause; if not specified,
an OID is automatically generated for it. (The <literal>rowtype_oid</literal>
clause is useless if <literal>bootstrap</literal> is specified, but it can be
provided anyway for documentation.)
</para>
</listitem>
@ -136,7 +136,7 @@
<varlistentry>
<term>
<literal>open</> <replaceable class="parameter">tablename</replaceable>
<literal>open</literal> <replaceable class="parameter">tablename</replaceable>
</term>
<listitem>
@ -150,7 +150,7 @@
<varlistentry>
<term>
<literal>close</> <optional><replaceable class="parameter">tablename</replaceable></optional>
<literal>close</literal> <optional><replaceable class="parameter">tablename</replaceable></optional>
</term>
<listitem>
@ -163,7 +163,7 @@
<varlistentry>
<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>
<listitem>
@ -188,14 +188,14 @@
<varlistentry>
<term>
<literal>declare</> <optional><literal>unique</></optional>
<literal>index</> <replaceable class="parameter">indexname</replaceable>
<literal>declare</literal> <optional><literal>unique</literal></optional>
<literal>index</literal> <replaceable class="parameter">indexname</replaceable>
<replaceable class="parameter">indexoid</replaceable>
<literal>on</> <replaceable class="parameter">tablename</replaceable>
<literal>using</> <replaceable class="parameter">amname</replaceable>
<literal>(</> <replaceable class="parameter">opclass1</replaceable>
<literal>on</literal> <replaceable class="parameter">tablename</replaceable>
<literal>using</literal> <replaceable class="parameter">amname</replaceable>
<literal>(</literal> <replaceable class="parameter">opclass1</replaceable>
<replaceable class="parameter">name1</replaceable>
<optional>, ...</optional> <literal>)</>
<optional>, ...</optional> <literal>)</literal>
</term>
<listitem>
@ -220,10 +220,10 @@
<varlistentry>
<term>
<literal>declare toast</>
<literal>declare toast</literal>
<replaceable class="parameter">toasttableoid</replaceable>
<replaceable class="parameter">toastindexoid</replaceable>
<literal>on</> <replaceable class="parameter">tablename</replaceable>
<literal>on</literal> <replaceable class="parameter">tablename</replaceable>
</term>
<listitem>
@ -234,14 +234,14 @@
<replaceable class="parameter">toasttableoid</replaceable>
and its index is assigned OID
<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.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>build indices</></term>
<term><literal>build indices</literal></term>
<listitem>
<para>
@ -257,17 +257,17 @@
<title>Structure of the Bootstrap <acronym>BKI</acronym> File</title>
<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.
(These minimum tables are <structname>pg_class</>,
<structname>pg_attribute</>, <structname>pg_proc</>, and
<structname>pg_type</>.) To allow those tables themselves to be filled,
<literal>create</> with the <literal>bootstrap</> option implicitly opens
(These minimum tables are <structname>pg_class</structname>,
<structname>pg_attribute</structname>, <structname>pg_proc</structname>, and
<structname>pg_type</structname>.) To allow those tables themselves to be filled,
<literal>create</literal> with the <literal>bootstrap</literal> option implicitly opens
the created table for data insertion.
</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
created and filled in.
</para>
@ -278,17 +278,17 @@
<orderedlist>
<listitem>
<para>
<literal>create bootstrap</> one of the critical tables
<literal>create bootstrap</literal> one of the critical tables
</para>
</listitem>
<listitem>
<para>
<literal>insert</> data describing at least the critical tables
<literal>insert</literal> data describing at least the critical tables
</para>
</listitem>
<listitem>
<para>
<literal>close</>
<literal>close</literal>
</para>
</listitem>
<listitem>
@ -298,22 +298,22 @@
</listitem>
<listitem>
<para>
<literal>create</> (without <literal>bootstrap</>) a noncritical table
<literal>create</literal> (without <literal>bootstrap</literal>) a noncritical table
</para>
</listitem>
<listitem>
<para>
<literal>open</>
<literal>open</literal>
</para>
</listitem>
<listitem>
<para>
<literal>insert</> desired data
<literal>insert</literal> desired data
</para>
</listitem>
<listitem>
<para>
<literal>close</>
<literal>close</literal>
</para>
</listitem>
<listitem>
@ -328,7 +328,7 @@
</listitem>
<listitem>
<para>
<literal>build indices</>
<literal>build indices</literal>
</para>
</listitem>
</orderedlist>

View File

@ -8,7 +8,7 @@
</indexterm>
<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>.
</para>
@ -42,29 +42,29 @@
<title>Parameters</title>
<para>
A <literal>bloom</> index accepts the following parameters in its
<literal>WITH</> clause:
A <literal>bloom</literal> index accepts the following parameters in its
<literal>WITH</literal> clause:
</para>
<variablelist>
<varlistentry>
<term><literal>length</></term>
<term><literal>length</literal></term>
<listitem>
<para>
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>
</listitem>
</varlistentry>
</variablelist>
<variablelist>
<varlistentry>
<term><literal>col1 &mdash; col32</></term>
<term><literal>col1 &mdash; col32</literal></term>
<listitem>
<para>
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
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.
</para>
</listitem>
@ -87,8 +87,8 @@ CREATE INDEX bloomidx ON tbloom USING bloom (i1,i2,i3)
<para>
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
have omitted the <literal>length</>, <literal>col1</>,
and <literal>col2</> specifications since those have the default values.
have omitted the <literal>length</literal>, <literal>col1</literal>,
and <literal>col2</literal> specifications since those have the default values.
</para>
<para>
@ -175,7 +175,7 @@ CREATE INDEX
Note the relatively large number of false positives: 2439 rows were
selected to be visited in the heap, but none actually matched the
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
(to 306 MB) and ended up being slower for this query (125 ms overall).
</para>
@ -213,7 +213,7 @@ CREATE INDEX
<para>
An operator class for bloom indexes requires only a hash function for the
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>
<programlisting>
@ -230,7 +230,7 @@ DEFAULT FOR TYPE text USING bloom AS
<itemizedlist>
<listitem>
<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.
</para>
</listitem>

View File

@ -16,7 +16,7 @@
<acronym>BRIN</acronym> is designed for handling very large tables
in which certain columns have some natural correlation with their
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
by the index.
For example, a table storing a store's sale orders might have
@ -29,7 +29,7 @@
<para>
<acronym>BRIN</acronym> indexes can satisfy queries via regular bitmap
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.
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
@ -51,9 +51,9 @@
<para>
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
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
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.
@ -99,9 +99,9 @@
</para>
<para>
The <firstterm>minmax</>
The <firstterm>minmax</firstterm>
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
column within the range.
</para>
@ -162,21 +162,21 @@
</entry>
</row>
<row>
<entry><literal>box_inclusion_ops</></entry>
<entry><literal>box_inclusion_ops</literal></entry>
<entry><type>box</type></entry>
<entry>
<literal>&lt;&lt;</>
<literal>&amp;&lt;</>
<literal>&amp;&amp;</>
<literal>&amp;&gt;</>
<literal>&gt;&gt;</>
<literal>~=</>
<literal>@&gt;</>
<literal>&lt;@</>
<literal>&amp;&lt;|</>
<literal>&lt;&lt;|</>
<literal>&lt;&lt;</literal>
<literal>&amp;&lt;</literal>
<literal>&amp;&amp;</literal>
<literal>&amp;&gt;</literal>
<literal>&gt;&gt;</literal>
<literal>~=</literal>
<literal>@&gt;</literal>
<literal>&lt;@</literal>
<literal>&amp;&lt;|</literal>
<literal>&lt;&lt;|</literal>
<literal>|&gt;&gt;</literal>
<literal>|&amp;&gt;</>
<literal>|&amp;&gt;</literal>
</entry>
</row>
<row>
@ -249,11 +249,11 @@
<entry><literal>network_inclusion_ops</literal></entry>
<entry><type>inet</type></entry>
<entry>
<literal>&amp;&amp;</>
<literal>&gt;&gt;=</>
<literal>&amp;&amp;</literal>
<literal>&gt;&gt;=</literal>
<literal>&lt;&lt;=</literal>
<literal>=</literal>
<literal>&gt;&gt;</>
<literal>&gt;&gt;</literal>
<literal>&lt;&lt;</literal>
</entry>
</row>
@ -346,18 +346,18 @@
</entry>
</row>
<row>
<entry><literal>range_inclusion_ops</></entry>
<entry><literal>range_inclusion_ops</literal></entry>
<entry><type>any range type</type></entry>
<entry>
<literal>&lt;&lt;</>
<literal>&amp;&lt;</>
<literal>&amp;&amp;</>
<literal>&amp;&gt;</>
<literal>&gt;&gt;</>
<literal>@&gt;</>
<literal>&lt;@</>
<literal>-|-</>
<literal>=</>
<literal>&lt;&lt;</literal>
<literal>&amp;&lt;</literal>
<literal>&amp;&amp;</literal>
<literal>&amp;&gt;</literal>
<literal>&gt;&gt;</literal>
<literal>@&gt;</literal>
<literal>&lt;@</literal>
<literal>-|-</literal>
<literal>=</literal>
<literal>&lt;</literal>
<literal>&lt;=</literal>
<literal>=</literal>
@ -505,11 +505,11 @@
<variablelist>
<varlistentry>
<term><function>BrinOpcInfo *opcInfo(Oid type_oid)</></term>
<term><function>BrinOpcInfo *opcInfo(Oid type_oid)</function></term>
<listitem>
<para>
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:
<programlisting>
typedef struct BrinOpcInfo
@ -524,7 +524,7 @@ typedef struct BrinOpcInfo
TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER];
} BrinOpcInfo;
</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
during an index scan.
</para>
@ -797,8 +797,8 @@ typedef struct BrinOpcInfo
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
values with different data types if it is defined with the
<literal>STORAGE</> parameter. The return value of the union
function should match the <literal>STORAGE</> data type.
<literal>STORAGE</literal> parameter. The return value of the union
function should match the <literal>STORAGE</literal> data type.
</para>
<para>
@ -823,11 +823,11 @@ typedef struct BrinOpcInfo
on another operator strategy as shown in
<xref linkend="brin-extensibility-inclusion-table">, or the same
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
right-hand-side argument of the supported operator. See
<literal>float4_minmax_ops</> as an example of minmax, and
<literal>box_inclusion_ops</> as an example of inclusion.
<literal>float4_minmax_ops</literal> as an example of minmax, and
<literal>box_inclusion_ops</literal> as an example of inclusion.
</para>
</sect1>
</chapter>

View File

@ -8,16 +8,16 @@
</indexterm>
<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
<type>int2</>, <type>int4</>, <type>int8</>, <type>float4</>,
<type>float8</>, <type>timestamp with time zone</>,
<type>timestamp without time zone</>, <type>time with time zone</>,
<type>time without time zone</>, <type>date</>, <type>interval</>,
<type>oid</>, <type>money</>, <type>"char"</>,
<type>varchar</>, <type>text</>, <type>bytea</>, <type>bit</>,
<type>varbit</>, <type>macaddr</>, <type>macaddr8</>, <type>inet</>,
<type>cidr</>, and all <type>enum</> types.
<type>int2</type>, <type>int4</type>, <type>int8</type>, <type>float4</type>,
<type>float8</type>, <type>timestamp with time zone</type>,
<type>timestamp without time zone</type>, <type>time with time zone</type>,
<type>time without time zone</type>, <type>date</type>, <type>interval</type>,
<type>oid</type>, <type>money</type>, <type>"char"</type>,
<type>varchar</type>, <type>text</type>, <type>bytea</type>, <type>bit</type>,
<type>varbit</type>, <type>macaddr</type>, <type>macaddr8</type>, <type>inet</type>,
<type>cidr</type>, and all <type>enum</type> types.
</para>
<para>

View File

@ -8,16 +8,16 @@
</indexterm>
<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
<type>int2</>, <type>int4</>, <type>int8</>, <type>float4</>,
<type>float8</>, <type>numeric</>, <type>timestamp with time zone</>,
<type>timestamp without time zone</>, <type>time with time zone</>,
<type>time without time zone</>, <type>date</>, <type>interval</>,
<type>oid</>, <type>money</>, <type>char</>,
<type>varchar</>, <type>text</>, <type>bytea</>, <type>bit</>,
<type>varbit</>, <type>macaddr</>, <type>macaddr8</>, <type>inet</>,
<type>cidr</>, <type>uuid</>, and all <type>enum</> types.
<type>int2</type>, <type>int4</type>, <type>int8</type>, <type>float4</type>,
<type>float8</type>, <type>numeric</type>, <type>timestamp with time zone</type>,
<type>timestamp without time zone</type>, <type>time with time zone</type>,
<type>time without time zone</type>, <type>date</type>, <type>interval</type>,
<type>oid</type>, <type>money</type>, <type>char</type>,
<type>varchar</type>, <type>text</type>, <type>bytea</type>, <type>bit</type>,
<type>varbit</type>, <type>macaddr</type>, <type>macaddr8</type>, <type>inet</type>,
<type>cidr</type>, <type>uuid</type>, and all <type>enum</type> types.
</para>
<para>
@ -33,7 +33,7 @@
</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
equals</quote>). This may be useful in combination with an
<link linkend="SQL-CREATETABLE-EXCLUDE">exclusion constraint</link>,
@ -42,14 +42,14 @@
<para>
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
this operator. Distance operators are provided for
<type>int2</>, <type>int4</>, <type>int8</>, <type>float4</>,
<type>float8</>, <type>timestamp with time zone</>,
<type>timestamp without time zone</>,
<type>time without time zone</>, <type>date</>, <type>interval</>,
<type>oid</>, and <type>money</>.
<type>int2</type>, <type>int4</type>, <type>int8</type>, <type>float4</type>,
<type>float8</type>, <type>timestamp with time zone</type>,
<type>timestamp without time zone</type>,
<type>time without time zone</type>, <type>date</type>, <type>interval</type>,
<type>oid</type>, and <type>money</type>.
</para>
<sect2>

File diff suppressed because it is too large Load Diff

View File

@ -35,12 +35,12 @@
<sect1 id="locale">
<title>Locale Support</title>
<indexterm zone="locale"><primary>locale</></>
<indexterm zone="locale"><primary>locale</primary></indexterm>
<para>
<firstterm>Locale</> support refers to an application respecting
<firstterm>Locale</firstterm> support refers to an application respecting
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
system. For additional information refer to the documentation of your
system.
@ -67,14 +67,14 @@ initdb --locale=sv_SE
<para>
This example for Unix systems sets the locale to Swedish
(<literal>sv</>) as spoken
in Sweden (<literal>SE</>). Other possibilities might include
<literal>en_US</> (U.S. English) and <literal>fr_CA</> (French
(<literal>sv</literal>) as spoken
in Sweden (<literal>SE</literal>). Other possibilities might include
<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
locale then the specifications can take the form
<replaceable>language_territory.codeset</>. For example,
<literal>fr_BE.UTF-8</> represents the French language (fr) as
spoken in Belgium (BE), with a <acronym>UTF-8</> character set
<replaceable>language_territory.codeset</replaceable>. For example,
<literal>fr_BE.UTF-8</literal> represents the French language (fr) as
spoken in Belgium (BE), with a <acronym>UTF-8</acronym> character set
encoding.
</para>
@ -82,9 +82,9 @@ initdb --locale=sv_SE
What locales are available on your
system under what names depends on what was provided by the operating
system vendor and what was installed. On most Unix systems, the command
<literal>locale -a</> will provide a list of available locales.
Windows uses more verbose locale names, such as <literal>German_Germany</>
or <literal>Swedish_Sweden.1252</>, but the principles are the same.
<literal>locale -a</literal> will provide a list of available locales.
Windows uses more verbose locale names, such as <literal>German_Germany</literal>
or <literal>Swedish_Sweden.1252</literal>, but the principles are the same.
</para>
<para>
@ -97,28 +97,28 @@ initdb --locale=sv_SE
<tgroup cols="2">
<tbody>
<row>
<entry><envar>LC_COLLATE</></>
<entry>String sort order</>
<entry><envar>LC_COLLATE</envar></entry>
<entry>String sort order</entry>
</row>
<row>
<entry><envar>LC_CTYPE</></>
<entry>Character classification (What is a letter? Its upper-case equivalent?)</>
<entry><envar>LC_CTYPE</envar></entry>
<entry>Character classification (What is a letter? Its upper-case equivalent?)</entry>
</row>
<row>
<entry><envar>LC_MESSAGES</></>
<entry>Language of messages</>
<entry><envar>LC_MESSAGES</envar></entry>
<entry>Language of messages</entry>
</row>
<row>
<entry><envar>LC_MONETARY</></>
<entry>Formatting of currency amounts</>
<entry><envar>LC_MONETARY</envar></entry>
<entry>Formatting of currency amounts</entry>
</row>
<row>
<entry><envar>LC_NUMERIC</></>
<entry>Formatting of numbers</>
<entry><envar>LC_NUMERIC</envar></entry>
<entry>Formatting of numbers</entry>
</row>
<row>
<entry><envar>LC_TIME</></>
<entry>Formatting of dates and times</>
<entry><envar>LC_TIME</envar></entry>
<entry>Formatting of dates and times</entry>
</row>
</tbody>
</tgroup>
@ -133,8 +133,8 @@ initdb --locale=sv_SE
<para>
If you want the system to behave as if it had no locale support,
use the special locale name <literal>C</>, or equivalently
<literal>POSIX</>.
use the special locale name <literal>C</literal>, or equivalently
<literal>POSIX</literal>.
</para>
<para>
@ -192,14 +192,14 @@ initdb --locale=sv_SE
settings for the purpose of setting the language of messages. If
in doubt, please refer to the documentation of your operating
system, in particular the documentation about
<application>gettext</>.
<application>gettext</application>.
</para>
</note>
<para>
To enable messages to be translated to the user's preferred language,
<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.
</para>
</sect2>
@ -213,63 +213,63 @@ initdb --locale=sv_SE
<itemizedlist>
<listitem>
<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
<indexterm><primary>ORDER BY</><secondary>and locales</></indexterm>
<indexterm><primary>ORDER BY</primary><secondary>and locales</secondary></indexterm>
</para>
</listitem>
<listitem>
<para>
The <function>upper</>, <function>lower</>, and <function>initcap</>
The <function>upper</function>, <function>lower</function>, and <function>initcap</function>
functions
<indexterm><primary>upper</><secondary>and locales</></indexterm>
<indexterm><primary>lower</><secondary>and locales</></indexterm>
<indexterm><primary>upper</primary><secondary>and locales</secondary></indexterm>
<indexterm><primary>lower</primary><secondary>and locales</secondary></indexterm>
</para>
</listitem>
<listitem>
<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
insensitive matching and the classification of characters by
character-class regular expressions
<indexterm><primary>LIKE</><secondary>and locales</></indexterm>
<indexterm><primary>regular expressions</><secondary>and locales</></indexterm>
<indexterm><primary>LIKE</primary><secondary>and locales</secondary></indexterm>
<indexterm><primary>regular expressions</primary><secondary>and locales</secondary></indexterm>
</para>
</listitem>
<listitem>
<para>
The <function>to_char</> family of functions
<indexterm><primary>to_char</><secondary>and locales</></indexterm>
The <function>to_char</function> family of functions
<indexterm><primary>to_char</primary><secondary>and locales</secondary></indexterm>
</para>
</listitem>
<listitem>
<para>
The ability to use indexes with <literal>LIKE</> clauses
The ability to use indexes with <literal>LIKE</literal> clauses
</para>
</listitem>
</itemizedlist>
</para>
<para>
The drawback of using locales other than <literal>C</> or
<literal>POSIX</> in <productname>PostgreSQL</> is its performance
The drawback of using locales other than <literal>C</literal> or
<literal>POSIX</literal> in <productname>PostgreSQL</productname> is its performance
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.
</para>
<para>
As a workaround to allow <productname>PostgreSQL</> to use indexes
with <literal>LIKE</> clauses under a non-C locale, several custom
As a workaround to allow <productname>PostgreSQL</productname> to use indexes
with <literal>LIKE</literal> clauses under a non-C locale, several custom
operator classes exist. These allow the creation of an index that
performs a strict character-by-character comparison, ignoring
locale comparison rules. Refer to <xref linkend="indexes-opclass">
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">.
</para>
</sect2>
@ -286,20 +286,20 @@ initdb --locale=sv_SE
</para>
<para>
Check that <productname>PostgreSQL</> is actually using the locale
that you think it is. The <envar>LC_COLLATE</> and <envar>LC_CTYPE</>
Check that <productname>PostgreSQL</productname> is actually using the locale
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
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
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>
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
<productname>PostgreSQL</>'s locale support.
<productname>PostgreSQL</productname>'s locale support.
</para>
<para>
@ -313,7 +313,7 @@ initdb --locale=sv_SE
<para>
Maintaining catalogs of message translations requires the on-going
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
translated, your assistance would be appreciated. If you want to
help, refer to <xref linkend="nls"> or write to the developers'
@ -326,7 +326,7 @@ initdb --locale=sv_SE
<sect1 id="collation">
<title>Collation Support</title>
<indexterm zone="collation"><primary>collation</></>
<indexterm zone="collation"><primary>collation</primary></indexterm>
<para>
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
below. In addition to comparison operators, collations are taken into
account by functions that convert between lower and upper case
letters, such as <function>lower</>, <function>upper</>, and
<function>initcap</>; by pattern matching operators; and by
<function>to_char</> and related functions.
letters, such as <function>lower</function>, <function>upper</function>, and
<function>initcap</function>; by pattern matching operators; and by
<function>to_char</function> and related functions.
</para>
<para>
@ -452,7 +452,7 @@ SELECT a &lt; ('foo' COLLATE "fr_FR") FROM test1;
SELECT a &lt; b FROM test1;
</programlisting>
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
does need to know which collation to use, this will result in an
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>
SELECT a || b FROM test1;
</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
of the collation.
</para>
@ -486,8 +486,8 @@ SELECT * FROM test1 ORDER BY a || 'foo';
<programlisting>
SELECT * FROM test1 ORDER BY a || b;
</programlisting>
results in an error, because even though the <literal>||</> operator
doesn't need to know a collation, the <literal>ORDER BY</> clause does.
results in an error, because even though the <literal>||</literal> operator
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
specifier:
<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
provided by the operating system use. Another provider
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.
</para>
@ -541,14 +541,14 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
<title>Standard Collations</title>
<para>
On all platforms, the collations named <literal>default</>,
<literal>C</>, and <literal>POSIX</> are available. Additional
On all platforms, the collations named <literal>default</literal>,
<literal>C</literal>, and <literal>POSIX</literal> are available. Additional
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.
The <literal>C</> and <literal>POSIX</> collations both specify
<quote>traditional C</> behavior, in which only the ASCII letters
<quote><literal>A</></quote> through <quote><literal>Z</></quote>
The <literal>C</literal> and <literal>POSIX</literal> collations both specify
<quote>traditional C</quote> behavior, in which only the ASCII letters
<quote><literal>A</literal></quote> through <quote><literal>Z</literal></quote>
are treated as letters, and sorting is done strictly by character
code byte values.
</para>
@ -565,7 +565,7 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
<para>
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,
then when a database cluster is initialized, <command>initdb</command>
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.
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
another database encoding. Note however that the <literal>default</>,
<literal>C</>, and <literal>POSIX</> collations can be used regardless of
another database encoding. Note however that the <literal>default</literal>,
<literal>C</literal>, and <literal>POSIX</literal> collations can be used regardless of
the database encoding.
</para>
@ -630,7 +630,7 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
<programlisting>
SELECT a COLLATE "C" &lt; b COLLATE "POSIX" FROM test1;
</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
collation names is therefore not recommended.
</para>
@ -691,7 +691,7 @@ SELECT a COLLATE "C" &lt; b COLLATE "POSIX" FROM test1;
database encoding is one of these, ICU collation entries
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
encoding "WIN874" does not exist</>.
encoding "WIN874" does not exist</quote>.
</para>
</sect4>
</sect3>
@ -889,30 +889,30 @@ CREATE COLLATION french FROM "fr-x-icu";
<sect1 id="multibyte">
<title>Character Set Support</title>
<indexterm zone="multibyte"><primary>character set</></>
<indexterm zone="multibyte"><primary>character set</primary></indexterm>
<para>
The character set support in <productname>PostgreSQL</productname>
allows you to store text in a variety of character sets (also called
encodings), including
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
can be used transparently by clients, but a few are not supported
for use within the server (that is, as a server-side encoding).
The default character set is selected while
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
databases each with a different character set.
</para>
<para>
An important restriction, however, is that each database's character set
must be compatible with the database's <envar>LC_CTYPE</> (character
classification) and <envar>LC_COLLATE</> (string sort order) locale
settings. For <literal>C</> or
<literal>POSIX</> locale, any character set is allowed, but for other
must be compatible with the database's <envar>LC_CTYPE</envar> (character
classification) and <envar>LC_COLLATE</envar> (string sort order) locale
settings. For <literal>C</literal> or
<literal>POSIX</literal> locale, any character set is allowed, but for other
libc-provided locales there is only one character set that will work
correctly.
(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>1-2</entry>
<entry><literal>WIN950</>, <literal>Windows950</></entry>
<entry><literal>WIN950</literal>, <literal>Windows950</literal></entry>
</row>
<row>
<entry><literal>EUC_CN</literal></entry>
@ -1017,11 +1017,11 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>No</entry>
<entry>No</entry>
<entry>1-2</entry>
<entry><literal>WIN936</>, <literal>Windows936</></entry>
<entry><literal>WIN936</literal>, <literal>Windows936</literal></entry>
</row>
<row>
<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>Yes</entry>
<entry>Yes</entry>
@ -1030,7 +1030,7 @@ CREATE COLLATION french FROM "fr-x-icu";
</row>
<row>
<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>Yes</entry>
<entry>Yes</entry>
@ -1039,7 +1039,7 @@ CREATE COLLATION french FROM "fr-x-icu";
</row>
<row>
<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>Yes</entry>
<entry>Yes</entry>
@ -1048,7 +1048,7 @@ CREATE COLLATION french FROM "fr-x-icu";
</row>
<row>
<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>Yes</entry>
<entry>Yes</entry>
@ -1057,7 +1057,7 @@ CREATE COLLATION french FROM "fr-x-icu";
</row>
<row>
<entry><literal>JOHAB</literal></entry>
<entry><acronym>JOHAB</></entry>
<entry><acronym>JOHAB</acronym></entry>
<entry>Korean (Hangul)</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>1</entry>
<entry><literal>KOI8</></entry>
<entry><literal>KOI8</literal></entry>
</row>
<row>
<entry><literal>KOI8U</literal></entry>
@ -1084,57 +1084,57 @@ CREATE COLLATION french FROM "fr-x-icu";
</row>
<row>
<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>Yes</entry>
<entry>Yes</entry>
<entry>1</entry>
<entry><literal>ISO88591</></entry>
<entry><literal>ISO88591</literal></entry>
</row>
<row>
<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>Yes</entry>
<entry>Yes</entry>
<entry>1</entry>
<entry><literal>ISO88592</></entry>
<entry><literal>ISO88592</literal></entry>
</row>
<row>
<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>Yes</entry>
<entry>Yes</entry>
<entry>1</entry>
<entry><literal>ISO88593</></entry>
<entry><literal>ISO88593</literal></entry>
</row>
<row>
<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>Yes</entry>
<entry>Yes</entry>
<entry>1</entry>
<entry><literal>ISO88594</></entry>
<entry><literal>ISO88594</literal></entry>
</row>
<row>
<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>Yes</entry>
<entry>Yes</entry>
<entry>1</entry>
<entry><literal>ISO88599</></entry>
<entry><literal>ISO88599</literal></entry>
</row>
<row>
<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>Yes</entry>
<entry>Yes</entry>
<entry>1</entry>
<entry><literal>ISO885910</></entry>
<entry><literal>ISO885910</literal></entry>
</row>
<row>
<entry><literal>LATIN7</literal></entry>
@ -1143,7 +1143,7 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>Yes</entry>
<entry>Yes</entry>
<entry>1</entry>
<entry><literal>ISO885913</></entry>
<entry><literal>ISO885913</literal></entry>
</row>
<row>
<entry><literal>LATIN8</literal></entry>
@ -1152,7 +1152,7 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>Yes</entry>
<entry>Yes</entry>
<entry>1</entry>
<entry><literal>ISO885914</></entry>
<entry><literal>ISO885914</literal></entry>
</row>
<row>
<entry><literal>LATIN9</literal></entry>
@ -1161,16 +1161,16 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>Yes</entry>
<entry>Yes</entry>
<entry>1</entry>
<entry><literal>ISO885915</></entry>
<entry><literal>ISO885915</literal></entry>
</row>
<row>
<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>Yes</entry>
<entry>No</entry>
<entry>1</entry>
<entry><literal>ISO885916</></entry>
<entry><literal>ISO885916</literal></entry>
</row>
<row>
<entry><literal>MULE_INTERNAL</literal></entry>
@ -1188,7 +1188,7 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>No</entry>
<entry>No</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>
<entry><literal>SHIFT_JIS_2004</literal></entry>
@ -1202,7 +1202,7 @@ CREATE COLLATION french FROM "fr-x-icu";
<row>
<entry><literal>SQL_ASCII</literal></entry>
<entry>unspecified (see text)</entry>
<entry><emphasis>any</></entry>
<entry><emphasis>any</emphasis></entry>
<entry>Yes</entry>
<entry>No</entry>
<entry>1</entry>
@ -1215,16 +1215,16 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>No</entry>
<entry>No</entry>
<entry>1-2</entry>
<entry><literal>WIN949</>, <literal>Windows949</></entry>
<entry><literal>WIN949</literal>, <literal>Windows949</literal></entry>
</row>
<row>
<entry><literal>UTF8</literal></entry>
<entry>Unicode, 8-bit</entry>
<entry><emphasis>all</></entry>
<entry><emphasis>all</emphasis></entry>
<entry>Yes</entry>
<entry>Yes</entry>
<entry>1-4</entry>
<entry><literal>Unicode</></entry>
<entry><literal>Unicode</literal></entry>
</row>
<row>
<entry><literal>WIN866</literal></entry>
@ -1233,7 +1233,7 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>Yes</entry>
<entry>Yes</entry>
<entry>1</entry>
<entry><literal>ALT</></entry>
<entry><literal>ALT</literal></entry>
</row>
<row>
<entry><literal>WIN874</literal></entry>
@ -1260,7 +1260,7 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>Yes</entry>
<entry>Yes</entry>
<entry>1</entry>
<entry><literal>WIN</></entry>
<entry><literal>WIN</literal></entry>
</row>
<row>
<entry><literal>WIN1252</literal></entry>
@ -1323,30 +1323,30 @@ CREATE COLLATION french FROM "fr-x-icu";
<entry>Yes</entry>
<entry>Yes</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>
</tbody>
</tgroup>
</table>
<para>
Not all client <acronym>API</>s support all the listed character sets. For example, the
<productname>PostgreSQL</>
JDBC driver does not support <literal>MULE_INTERNAL</>, <literal>LATIN6</>,
<literal>LATIN8</>, and <literal>LATIN10</>.
Not all client <acronym>API</acronym>s support all the listed character sets. For example, the
<productname>PostgreSQL</productname>
JDBC driver does not support <literal>MULE_INTERNAL</literal>, <literal>LATIN6</literal>,
<literal>LATIN8</literal>, and <literal>LATIN10</literal>.
</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
<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
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
of ignorance about the encoding. In most cases, if you are
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
converting or validating non-ASCII characters.
</para>
@ -1356,7 +1356,7 @@ CREATE COLLATION french FROM "fr-x-icu";
<title>Setting the Character Set</title>
<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,
<screen>
@ -1367,8 +1367,8 @@ initdb -E EUC_JP
<literal>EUC_JP</literal> (Extended Unix Code for Japanese). You
can use <option>--encoding</option> instead of
<option>-E</option> if you prefer longer option strings.
If no <option>-E</> or <option>--encoding</option> option is
given, <command>initdb</> attempts to determine the appropriate
If no <option>-E</option> or <option>--encoding</option> option is
given, <command>initdb</command> attempts to determine the appropriate
encoding to use based on the specified or default locale.
</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;
</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
settings cannot be changed from those of the source database, because
that might result in corrupt data. For more information see
@ -1420,7 +1420,7 @@ $ <userinput>psql -l</userinput>
<important>
<para>
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
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
@ -1430,9 +1430,9 @@ $ <userinput>psql -l</userinput>
<para>
<productname>PostgreSQL</productname> will allow superusers to create
databases with <literal>SQL_ASCII</> encoding even when
<envar>LC_CTYPE</> is not <literal>C</> or <literal>POSIX</>. As noted
above, <literal>SQL_ASCII</> does not enforce that the data stored in
databases with <literal>SQL_ASCII</literal> encoding even when
<envar>LC_CTYPE</envar> is not <literal>C</literal> or <literal>POSIX</literal>. As noted
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
of locale-dependent misbehavior. Using this combination of settings is
deprecated and may someday be forbidden altogether.
@ -1447,7 +1447,7 @@ $ <userinput>psql -l</userinput>
<productname>PostgreSQL</productname> supports automatic
character set conversion between server and client for certain
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
linkend="multibyte-translation-table">. You can create a new
conversion using the SQL command <command>CREATE CONVERSION</command>.
@ -1763,7 +1763,7 @@ $ <userinput>psql -l</userinput>
<listitem>
<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>
</listitem>
@ -1774,14 +1774,14 @@ $ <userinput>psql -l</userinput>
Setting the client encoding can be done with this SQL command:
<programlisting>
SET CLIENT_ENCODING TO '<replaceable>value</>';
SET CLIENT_ENCODING TO '<replaceable>value</replaceable>';
</programlisting>
Also you can use the standard SQL syntax <literal>SET NAMES</literal>
for this purpose:
<programlisting>
SET NAMES '<replaceable>value</>';
SET NAMES '<replaceable>value</replaceable>';
</programlisting>
To query the current client encoding:
@ -1813,7 +1813,7 @@ RESET client_encoding;
<para>
Using the configuration variable <xref
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
server is made. (This can subsequently be overridden using any
of the other methods mentioned above.)
@ -1832,9 +1832,9 @@ RESET client_encoding;
</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
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.
</para>
</sect2>

View File

@ -8,10 +8,10 @@
</indexterm>
<para>
The <filename>citext</> module provides a case-insensitive
character string type, <type>citext</>. Essentially, it internally calls
<function>lower</> when comparing values. Otherwise, it behaves almost
exactly like <type>text</>.
The <filename>citext</filename> module provides a case-insensitive
character string type, <type>citext</type>. Essentially, it internally calls
<function>lower</function> when comparing values. Otherwise, it behaves almost
exactly like <type>text</type>.
</para>
<sect2>
@ -19,7 +19,7 @@
<para>
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
<programlisting>
@ -35,19 +35,19 @@ SELECT * FROM tab WHERE lower(col) = LOWER(?);
<listitem>
<para>
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>
</listitem>
<listitem>
<para>
It won't use an index, unless you create a functional index using
<function>lower</>.
<function>lower</function>.
</para>
</listitem>
<listitem>
<para>
If you declare a column as <literal>UNIQUE</> or <literal>PRIMARY
KEY</>, the implicitly generated index is case-sensitive. So it's
If you declare a column as <literal>UNIQUE</literal> or <literal>PRIMARY
KEY</literal>, the implicitly generated index is case-sensitive. So it's
useless for case-insensitive searches, and it won't enforce
uniqueness case-insensitively.
</para>
@ -55,13 +55,13 @@ SELECT * FROM tab WHERE lower(col) = LOWER(?);
</itemizedlist>
<para>
The <type>citext</> data type allows you to eliminate calls
to <function>lower</> in SQL queries, and allows a primary key to
be case-insensitive. <type>citext</> is locale-aware, just
like <type>text</>, which means that the matching of upper case and
The <type>citext</type> data type allows you to eliminate calls
to <function>lower</function> in SQL queries, and allows a primary key to
be case-insensitive. <type>citext</type> is locale-aware, just
like <type>text</type>, which means that the matching of upper case and
lower case characters is dependent on the rules of
the database's <literal>LC_CTYPE</> setting. Again, this behavior is
identical to the use of <function>lower</> in queries. But because it's
the database's <literal>LC_CTYPE</literal> setting. Again, this behavior is
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
anything special in your queries.
</para>
@ -89,9 +89,9 @@ INSERT INTO users VALUES ( 'Bj&oslash;rn', md5(random()::text) );
SELECT * FROM users WHERE nick = 'Larry';
</programlisting>
The <command>SELECT</> statement will return one tuple, even though
the <structfield>nick</> column was set to <literal>larry</> and the query
was for <literal>Larry</>.
The <command>SELECT</command> statement will return one tuple, even though
the <structfield>nick</structfield> column was set to <literal>larry</literal> and the query
was for <literal>Larry</literal>.
</para>
</sect2>
@ -99,82 +99,82 @@ SELECT * FROM users WHERE nick = 'Larry';
<title>String Comparison Behavior</title>
<para>
<type>citext</> performs comparisons by converting each string to lower
case (as though <function>lower</> were called) and then comparing the
<type>citext</type> performs comparisons by converting each string to lower
case (as though <function>lower</function> were called) and then comparing the
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>
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 <literal>~</> and <literal>~*</> exhibit the same behavior when
applied to <type>citext</>: they both match case-insensitively.
operators <literal>~</literal> and <literal>~*</literal> exhibit the same behavior when
applied to <type>citext</type>: they both match case-insensitively.
The same is true
for <literal>!~</> and <literal>!~*</>, as well as for the
<literal>LIKE</> operators <literal>~~</> and <literal>~~*</>, and
<literal>!~~</> and <literal>!~~*</>. If you'd like to match
case-sensitively, you can cast the operator's arguments to <type>text</>.
for <literal>!~</literal> and <literal>!~*</literal>, as well as for the
<literal>LIKE</literal> operators <literal>~~</literal> and <literal>~~*</literal>, and
<literal>!~~</literal> and <literal>!~~*</literal>. If you'd like to match
case-sensitively, you can cast the operator's arguments to <type>text</type>.
</para>
<para>
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>
<itemizedlist>
<listitem>
<para>
<function>regexp_match()</>
<function>regexp_match()</function>
</para>
</listitem>
<listitem>
<para>
<function>regexp_matches()</>
<function>regexp_matches()</function>
</para>
</listitem>
<listitem>
<para>
<function>regexp_replace()</>
<function>regexp_replace()</function>
</para>
</listitem>
<listitem>
<para>
<function>regexp_split_to_array()</>
<function>regexp_split_to_array()</function>
</para>
</listitem>
<listitem>
<para>
<function>regexp_split_to_table()</>
<function>regexp_split_to_table()</function>
</para>
</listitem>
<listitem>
<para>
<function>replace()</>
<function>replace()</function>
</para>
</listitem>
<listitem>
<para>
<function>split_part()</>
<function>split_part()</function>
</para>
</listitem>
<listitem>
<para>
<function>strpos()</>
<function>strpos()</function>
</para>
</listitem>
<listitem>
<para>
<function>translate()</>
<function>translate()</function>
</para>
</listitem>
</itemizedlist>
<para>
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,
you must cast to <type>text</> before using one of these functions if
specify the <quote>c</quote> flag to force a case-sensitive match. Otherwise,
you must cast to <type>text</type> before using one of these functions if
you want case-sensitive behavior.
</para>
@ -186,13 +186,13 @@ SELECT * FROM users WHERE nick = 'Larry';
<itemizedlist>
<listitem>
<para>
<type>citext</>'s case-folding behavior depends on
the <literal>LC_CTYPE</> setting of your database. How it compares
<type>citext</type>'s case-folding behavior depends on
the <literal>LC_CTYPE</literal> setting of your database. How it compares
values is therefore determined when the database is created.
It is not truly
case-insensitive in the terms defined by the Unicode standard.
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
of one language may find their query results are not as expected if the
collation is for another language.
@ -201,38 +201,38 @@ SELECT * FROM users WHERE nick = 'Larry';
<listitem>
<para>
As of <productname>PostgreSQL</> 9.1, you can attach a
<literal>COLLATE</> specification to <type>citext</> columns or data
values. Currently, <type>citext</> operators will honor a non-default
<literal>COLLATE</> specification while comparing case-folded strings,
As of <productname>PostgreSQL</productname> 9.1, you can attach a
<literal>COLLATE</literal> specification to <type>citext</type> columns or data
values. Currently, <type>citext</type> operators will honor a non-default
<literal>COLLATE</literal> specification while comparing case-folded strings,
but the initial folding to lower case is always done according to the
database's <literal>LC_CTYPE</> setting (that is, as though
<literal>COLLATE "default"</> were given). This may be changed in a
future release so that both steps follow the input <literal>COLLATE</>
database's <literal>LC_CTYPE</literal> setting (that is, as though
<literal>COLLATE "default"</literal> were given). This may be changed in a
future release so that both steps follow the input <literal>COLLATE</literal>
specification.
</para>
</listitem>
<listitem>
<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
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.
</para>
</listitem>
<listitem>
<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
contexts. The standard answer is to use the <type>text</> type and
manually use the <function>lower</> function when you need to compare
contexts. The standard answer is to use the <type>text</type> type and
manually use the <function>lower</function> function when you need to compare
case-insensitively; this works all right if case-insensitive comparison
is needed only infrequently. If you need case-insensitive behavior most
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
need two indexes if you want both types of searches to be fast.
</para>
@ -240,9 +240,9 @@ SELECT * FROM users WHERE nick = 'Larry';
<listitem>
<para>
The schema containing the <type>citext</> operators must be
in the current <varname>search_path</> (typically <literal>public</>);
if it is not, the normal case-sensitive <type>text</> operators
The schema containing the <type>citext</type> operators must be
in the current <varname>search_path</varname> (typically <literal>public</literal>);
if it is not, the normal case-sensitive <type>text</type> operators
will be invoked instead.
</para>
</listitem>
@ -257,7 +257,7 @@ SELECT * FROM users WHERE nick = 'Larry';
</para>
<para>
Inspired by the original <type>citext</> module by Donald Fraser.
Inspired by the original <type>citext</type> module by Donald Fraser.
</para>
</sect2>

View File

@ -21,9 +21,9 @@
<para>
As explained in <xref linkend="user-manag">,
<productname>PostgreSQL</productname> actually does privilege
management in terms of <quote>roles</>. In this chapter, we
consistently use <firstterm>database user</> to mean <quote>role with the
<literal>LOGIN</> privilege</quote>.
management in terms of <quote>roles</quote>. In this chapter, we
consistently use <firstterm>database user</firstterm> to mean <quote>role with the
<literal>LOGIN</literal> privilege</quote>.
</para>
</note>
@ -66,7 +66,7 @@
which traditionally is named
<filename>pg_hba.conf</filename> and is stored in the database
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
directory is initialized by <command>initdb</command>. It is
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.
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.,
<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.
</para>
@ -92,8 +92,8 @@
and the authentication method to be used for connections matching
these parameters. The first record with a matching connection type,
client address, requested database, and user name is used to perform
authentication. There is no <quote>fall-through</> or
<quote>backup</>: if one record is chosen and the authentication
authentication. There is no <quote>fall-through</quote> or
<quote>backup</quote>: if one record is chosen and the authentication
fails, subsequent records are not considered. If no record matches,
access is denied.
</para>
@ -138,7 +138,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
the server is started with an appropriate value for the
<xref linkend="guc-listen-addresses"> configuration parameter,
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>
</note>
</listitem>
@ -169,7 +169,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<term><literal>hostnossl</literal></term>
<listitem>
<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
TCP/IP that do not use <acronym>SSL</acronym>.
</para>
@ -182,24 +182,24 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<para>
Specifies which database name(s) this record matches. The value
<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
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
name as the requested database. (<literal>samegroup</> is an
obsolete but still accepted spelling of <literal>samerole</>.)
name as the requested database. (<literal>samegroup</literal> is an
obsolete but still accepted spelling of <literal>samerole</literal>.)
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
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
replication connections do not specify any particular database).
Otherwise, this is the name of
a specific <productname>PostgreSQL</productname> database.
Multiple database names can be supplied by separating them with
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>
</listitem>
</varlistentry>
@ -211,18 +211,18 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
Specifies which database user name(s) this record
matches. The value <literal>all</literal> specifies that it
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
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
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
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
being a superuser.
Multiple user names can be supplied by separating them with commas.
A separate file containing user names can be specified by preceding the
file name with <literal>@</>.
file name with <literal>@</literal>.
</para>
</listitem>
</varlistentry>
@ -239,7 +239,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<para>
An IP address range is specified using standard numeric notation
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
IP address that must match. Bits to the right of this should
be zero in the given IP address.
@ -317,7 +317,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<para>
This field only applies to <literal>host</literal>,
<literal>hostssl</literal>, and <literal>hostnossl</> records.
<literal>hostssl</literal>, and <literal>hostnossl</literal> records.
</para>
<note>
@ -360,17 +360,17 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<listitem>
<para>
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
specifying the mask length, the actual mask is specified in a
separate column. For example, <literal>255.0.0.0</> represents an IPv4
CIDR mask length of 8, and <literal>255.255.255.255</> represents a
separate column. For example, <literal>255.0.0.0</literal> represents an IPv4
CIDR mask length of 8, and <literal>255.255.255.255</literal> represents a
CIDR mask length of 32.
</para>
<para>
These fields only apply to <literal>host</literal>,
<literal>hostssl</literal>, and <literal>hostnossl</> records.
<literal>hostssl</literal>, and <literal>hostnossl</literal> records.
</para>
</listitem>
</varlistentry>
@ -385,7 +385,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<variablelist>
<varlistentry>
<term><literal>trust</></term>
<term><literal>trust</literal></term>
<listitem>
<para>
Allow the connection unconditionally. This method
@ -399,12 +399,12 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry>
<varlistentry>
<term><literal>reject</></term>
<term><literal>reject</literal></term>
<listitem>
<para>
Reject the connection unconditionally. This is useful for
<quote>filtering out</> certain hosts from a group, for example a
<literal>reject</> line could block a specific host from connecting,
<quote>filtering out</quote> certain hosts from a group, for example a
<literal>reject</literal> line could block a specific host from connecting,
while a later line allows the remaining hosts in a specific
network to connect.
</para>
@ -412,7 +412,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry>
<varlistentry>
<term><literal>scram-sha-256</></term>
<term><literal>scram-sha-256</literal></term>
<listitem>
<para>
Perform SCRAM-SHA-256 authentication to verify the user's
@ -422,7 +422,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry>
<varlistentry>
<term><literal>md5</></term>
<term><literal>md5</literal></term>
<listitem>
<para>
Perform SCRAM-SHA-256 or MD5 authentication to verify the
@ -433,7 +433,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry>
<varlistentry>
<term><literal>password</></term>
<term><literal>password</literal></term>
<listitem>
<para>
Require the client to supply an unencrypted password for
@ -446,7 +446,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry>
<varlistentry>
<term><literal>gss</></term>
<term><literal>gss</literal></term>
<listitem>
<para>
Use GSSAPI to authenticate the user. This is only
@ -457,7 +457,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry>
<varlistentry>
<term><literal>sspi</></term>
<term><literal>sspi</literal></term>
<listitem>
<para>
Use SSPI to authenticate the user. This is only
@ -468,7 +468,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry>
<varlistentry>
<term><literal>ident</></term>
<term><literal>ident</literal></term>
<listitem>
<para>
Obtain the operating system user name of the client
@ -483,7 +483,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry>
<varlistentry>
<term><literal>peer</></term>
<term><literal>peer</literal></term>
<listitem>
<para>
Obtain the client's operating system user name from the operating
@ -495,17 +495,17 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry>
<varlistentry>
<term><literal>ldap</></term>
<term><literal>ldap</literal></term>
<listitem>
<para>
Authenticate using an <acronym>LDAP</> server. See <xref
Authenticate using an <acronym>LDAP</acronym> server. See <xref
linkend="auth-ldap"> for details.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>radius</></term>
<term><literal>radius</literal></term>
<listitem>
<para>
Authenticate using a RADIUS server. See <xref
@ -515,7 +515,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry>
<varlistentry>
<term><literal>cert</></term>
<term><literal>cert</literal></term>
<listitem>
<para>
Authenticate using SSL client certificates. See
@ -525,7 +525,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry>
<varlistentry>
<term><literal>pam</></term>
<term><literal>pam</literal></term>
<listitem>
<para>
Authenticate using the Pluggable Authentication Modules
@ -536,7 +536,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry>
<varlistentry>
<term><literal>bsd</></term>
<term><literal>bsd</literal></term>
<listitem>
<para>
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>
<listitem>
<para>
After the <replaceable>auth-method</> field, there can be field(s) of
the form <replaceable>name</><literal>=</><replaceable>value</> that
After the <replaceable>auth-method</replaceable> field, there can be field(s) of
the form <replaceable>name</replaceable><literal>=</literal><replaceable>value</replaceable> that
specify options for the authentication method. Details about which
options are available for which authentication methods appear below.
</para>
<para>
In addition to the method-specific options listed below, there is one
method-independent authentication option <literal>clientcert</>, which
can be specified in any <literal>hostssl</> record. When set
to <literal>1</>, this option requires the client to present a valid
method-independent authentication option <literal>clientcert</literal>, which
can be specified in any <literal>hostssl</literal> record. When set
to <literal>1</literal>, this option requires the client to present a valid
(trusted) SSL certificate, in addition to the other requirements of the
authentication method.
</para>
@ -574,11 +574,11 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</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
introduced by <literal>#</literal>, just as in
<filename>pg_hba.conf</filename>, and nested <literal>@</> constructs are
allowed. Unless the file name following <literal>@</> is an absolute
<filename>pg_hba.conf</filename>, and nested <literal>@</literal> constructs are
allowed. Unless the file name following <literal>@</literal> is an absolute
path, it is taken to be relative to the directory containing the
referencing file.
</para>
@ -589,10 +589,10 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
significant. Typically, earlier records will have tight connection
match parameters and weaker authentication methods, while later
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
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
range of allowed client IP addresses.
</para>
@ -603,7 +603,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<systemitem>SIGHUP</systemitem><indexterm><primary>SIGHUP</primary></indexterm>
signal. If you edit the file on an
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.
</para>
@ -618,7 +618,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<para>
The system view
<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
desired effects. Rows in the view with
non-null <structfield>error</structfield> fields indicate problems in the
@ -629,9 +629,9 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
<para>
To connect to a particular database, a user must not only pass 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
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.
</para>
</tip>
@ -760,21 +760,21 @@ local db1,db2,@demodbs all md5
<para>
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
cluster's data directory. (It is possible to place the map file
elsewhere, however; see the <xref linkend="guc-ident-file">
configuration parameter.)
The ident map file contains lines of the general form:
<synopsis>
<replaceable>map-name</> <replaceable>system-username</> <replaceable>database-username</>
<replaceable>map-name</replaceable> <replaceable>system-username</replaceable> <replaceable>database-username</replaceable>
</synopsis>
Comments and whitespace are handled in the same way as in
<filename>pg_hba.conf</>. The
<replaceable>map-name</> is an arbitrary name that will be used to
<filename>pg_hba.conf</filename>. The
<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
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.
</para>
<para>
@ -788,13 +788,13 @@ local db1,db2,@demodbs all md5
user has requested to connect as.
</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.
(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,
which can then be referenced in the <replaceable>database-username</>
field as <literal>\1</> (backslash-one). This allows the mapping of
which can then be referenced in the <replaceable>database-username</replaceable>
field as <literal>\1</literal> (backslash-one). This allows the mapping of
multiple user names in a single line, which is particularly useful for
simple syntax substitutions. For example, these entries
<programlisting>
@ -802,14 +802,14 @@ mymap /^(.*)@mydomain\.com$ \1
mymap /^(.*)@otherdomain\.com$ guest
</programlisting>
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>@otherdomain.com</> to log in as <literal>guest</>.
<literal>@mydomain.com</literal>, and allow any user whose system name ends with
<literal>@otherdomain.com</literal> to log in as <literal>guest</literal>.
</para>
<tip>
<para>
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
system user name.
</para>
@ -821,28 +821,28 @@ mymap /^(.*)@otherdomain\.com$ guest
<systemitem>SIGHUP</systemitem><indexterm><primary>SIGHUP</primary></indexterm>
signal. If you edit the file on an
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.
</para>
<para>
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-ident.conf">. In this example, anyone
logged in to a machine on the 192.168 network that does not have the
operating system user name <literal>bryanh</>, <literal>ann</>, or
<literal>robert</> would not be granted access. Unix user
<literal>robert</> would only be allowed access when he tries to
connect as <productname>PostgreSQL</> user <literal>bob</>, not
as <literal>robert</> or anyone else. <literal>ann</> would
only be allowed to connect as <literal>ann</>. User
<literal>bryanh</> would be allowed to connect as either
<literal>bryanh</> or as <literal>guest1</>.
operating system user name <literal>bryanh</literal>, <literal>ann</literal>, or
<literal>robert</literal> would not be granted access. Unix user
<literal>robert</literal> would only be allowed access when he tries to
connect as <productname>PostgreSQL</productname> user <literal>bob</literal>, not
as <literal>robert</literal> or anyone else. <literal>ann</literal> would
only be allowed to connect as <literal>ann</literal>. User
<literal>bryanh</literal> would be allowed to connect as either
<literal>bryanh</literal> or as <literal>guest1</literal>.
</para>
<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>
# MAPNAME SYSTEM-USERNAME PG-USERNAME
@ -866,21 +866,21 @@ omicron bryanh guest1
<title>Trust Authentication</title>
<para>
When <literal>trust</> authentication is specified,
When <literal>trust</literal> authentication is specified,
<productname>PostgreSQL</productname> assumes that anyone who can
connect to the server is authorized to access the database with
whatever database user name they specify (even superuser names).
Of course, restrictions made in the <literal>database</> and
<literal>user</> columns still apply.
Of course, restrictions made in the <literal>database</literal> and
<literal>user</literal> columns still apply.
This method should only be used when there is adequate
operating-system-level protection on connections to the server.
</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
is usually <emphasis>not</> appropriate by itself on a multiuser
machine. However, you might be able to use <literal>trust</> even
is usually <emphasis>not</emphasis> appropriate by itself on a multiuser
machine. However, you might be able to use <literal>trust</literal> even
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
<varname>unix_socket_permissions</varname> (and possibly
@ -895,17 +895,17 @@ omicron bryanh guest1
Setting file-system permissions only helps for Unix-socket connections.
Local TCP/IP connections are not restricted by file-system permissions.
Therefore, if you want to use file-system permissions for local security,
remove the <literal>host ... 127.0.0.1 ...</> line from
<filename>pg_hba.conf</>, or change it to a
non-<literal>trust</> authentication method.
remove the <literal>host ... 127.0.0.1 ...</literal> line from
<filename>pg_hba.conf</filename>, or change it to a
non-<literal>trust</literal> authentication method.
</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
to the server by the <filename>pg_hba.conf</> lines that specify
<literal>trust</>. It is seldom reasonable to use <literal>trust</>
for any TCP/IP connections other than those from <systemitem>localhost</> (127.0.0.1).
to the server by the <filename>pg_hba.conf</filename> lines that specify
<literal>trust</literal>. It is seldom reasonable to use <literal>trust</literal>
for any TCP/IP connections other than those from <systemitem>localhost</systemitem> (127.0.0.1).
</para>
</sect2>
@ -914,10 +914,10 @@ omicron bryanh guest1
<title>Password Authentication</title>
<indexterm>
<primary>MD5</>
<primary>MD5</primary>
</indexterm>
<indexterm>
<primary>SCRAM</>
<primary>SCRAM</primary>
</indexterm>
<indexterm>
<primary>password</primary>
@ -936,7 +936,7 @@ omicron bryanh guest1
<term><literal>scram-sha-256</literal></term>
<listitem>
<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
<ulink url="https://tools.ietf.org/html/rfc7677">RFC 7677</ulink>. It
is a challenge-response scheme that prevents password sniffing on
@ -955,7 +955,7 @@ omicron bryanh guest1
<term><literal>md5</literal></term>
<listitem>
<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
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
@ -982,10 +982,10 @@ omicron bryanh guest1
<term><literal>password</literal></term>
<listitem>
<para>
The method <literal>password</> sends the password in clear-text and is
therefore vulnerable to password <quote>sniffing</> attacks. It should
The method <literal>password</literal> sends the password in clear-text and is
therefore vulnerable to password <quote>sniffing</quote> attacks. It should
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
is depending on using SSL).
</para>
@ -996,7 +996,7 @@ omicron bryanh guest1
<para>
<productname>PostgreSQL</productname> database passwords are
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
<xref linkend="sql-createuser"> and
<xref linkend="sql-alterrole">,
@ -1060,7 +1060,7 @@ omicron bryanh guest1
</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.
</para>
@ -1068,13 +1068,13 @@ omicron bryanh guest1
When <productname>GSSAPI</productname> uses
<productname>Kerberos</productname>, it uses a standard principal
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 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
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,
this parameter never needs to be changed.
Some Kerberos implementations might require a different service name,
@ -1082,31 +1082,31 @@ omicron bryanh guest1
to be in upper case (<literal>POSTGRES</literal>).
</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
of the server machine.
</para>
<para>
Client principals can be mapped to different <productname>PostgreSQL</>
database user names with <filename>pg_ident.conf</>. For example,
<literal>pgusername@realm</> could be mapped to just <literal>pgusername</>.
Alternatively, you can use the full <literal>username@realm</> principal as
the role name in <productname>PostgreSQL</> without any mapping.
Client principals can be mapped to different <productname>PostgreSQL</productname>
database user names with <filename>pg_ident.conf</filename>. For example,
<literal>pgusername@realm</literal> could be mapped to just <literal>pgusername</literal>.
Alternatively, you can use the full <literal>username@realm</literal> principal as
the role name in <productname>PostgreSQL</productname> without any mapping.
</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
strongly discouraged as it is then impossible to distinguish different users
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
<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)
is still secure; but this is a
less capable approach compared to specifying an explicit mapping in
<filename>pg_ident.conf</>.
<filename>pg_ident.conf</filename>.
</para>
<para>
@ -1116,8 +1116,8 @@ omicron bryanh guest1
of the key file is specified by the <xref
linkend="guc-krb-server-keyfile"> configuration
parameter. The default is
<filename>/usr/local/pgsql/etc/krb5.keytab</> (or whatever
directory was specified as <varname>sysconfdir</> at build time).
<filename>/usr/local/pgsql/etc/krb5.keytab</filename> (or whatever
directory was specified as <varname>sysconfdir</varname> at build time).
For security reasons, it is recommended to use a separate keytab
just for the <productname>PostgreSQL</productname> server rather
than opening up permissions on the system keytab file.
@ -1127,17 +1127,17 @@ omicron bryanh guest1
Kerberos documentation for details. The following example is
for MIT-compatible Kerberos 5 implementations:
<screen>
<prompt>kadmin% </><userinput>ank -randkey postgres/server.my.domain.org</>
<prompt>kadmin% </><userinput>ktadd -k krb5.keytab postgres/server.my.domain.org</>
<prompt>kadmin% </prompt><userinput>ank -randkey postgres/server.my.domain.org</userinput>
<prompt>kadmin% </prompt><userinput>ktadd -k krb5.keytab postgres/server.my.domain.org</userinput>
</screen>
</para>
<para>
When connecting to the database make sure you have a ticket for a
principal matching the requested database user name. For example, for
database user name <literal>fred</>, principal
<literal>fred@EXAMPLE.COM</> would be able to connect. To also allow
principal <literal>fred/users.example.com@EXAMPLE.COM</>, use a user name
database user name <literal>fred</literal>, principal
<literal>fred@EXAMPLE.COM</literal> would be able to connect. To also allow
principal <literal>fred/users.example.com@EXAMPLE.COM</literal>, use a user name
map, as described in <xref linkend="auth-username-maps">.
</para>
@ -1155,8 +1155,8 @@ omicron bryanh guest1
in multi-realm environments unless <literal>krb_realm</literal> is
also used. It is recommended to
leave <literal>include_realm</literal> set to the default (1) and to
provide an explicit mapping in <filename>pg_ident.conf</> to convert
principal names to <productname>PostgreSQL</> user names.
provide an explicit mapping in <filename>pg_ident.conf</filename> to convert
principal names to <productname>PostgreSQL</productname> user names.
</para>
</listitem>
</varlistentry>
@ -1236,8 +1236,8 @@ omicron bryanh guest1
in multi-realm environments unless <literal>krb_realm</literal> is
also used. It is recommended to
leave <literal>include_realm</literal> set to the default (1) and to
provide an explicit mapping in <filename>pg_ident.conf</> to convert
principal names to <productname>PostgreSQL</> user names.
provide an explicit mapping in <filename>pg_ident.conf</filename> to convert
principal names to <productname>PostgreSQL</productname> user names.
</para>
</listitem>
</varlistentry>
@ -1270,9 +1270,9 @@ omicron bryanh guest1
By default, these two names are identical for new user accounts.
</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
<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
connection string.
</para>
@ -1357,8 +1357,8 @@ omicron bryanh guest1
is to answer questions like <quote>What user initiated the
connection that goes out of your port <replaceable>X</replaceable>
and connects to my port <replaceable>Y</replaceable>?</quote>.
Since <productname>PostgreSQL</> knows both <replaceable>X</> and
<replaceable>Y</> when a physical connection is established, it
Since <productname>PostgreSQL</productname> knows both <replaceable>X</replaceable> and
<replaceable>Y</replaceable> when a physical connection is established, it
can interrogate the ident server on the host of the connecting
client and can theoretically determine the operating system user
for any given connection.
@ -1386,9 +1386,9 @@ omicron bryanh guest1
<para>
Some ident servers have a nonstandard option that causes the returned
user name to be encrypted, using a key that only the originating
machine's administrator knows. This option <emphasis>must not</> be
used when using the ident server with <productname>PostgreSQL</>,
since <productname>PostgreSQL</> does not have any way to decrypt the
machine's administrator knows. This option <emphasis>must not</emphasis> be
used when using the ident server with <productname>PostgreSQL</productname>,
since <productname>PostgreSQL</productname> does not have any way to decrypt the
returned string to determine the actual user name.
</para>
</sect2>
@ -1424,11 +1424,11 @@ omicron bryanh guest1
<para>
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
<systemitem class="osname">Linux</>,
most flavors of <systemitem class="osname">BSD</> including
<systemitem class="osname">macOS</>,
<systemitem class="osname">Linux</systemitem>,
most flavors of <systemitem class="osname">BSD</systemitem> including
<systemitem class="osname">macOS</systemitem>,
and <systemitem class="osname">Solaris</systemitem>.
</para>
@ -1454,23 +1454,23 @@ omicron bryanh guest1
LDAP authentication can operate in two modes. In the first mode,
which we will call the simple bind mode,
the server will bind to the distinguished name constructed as
<replaceable>prefix</> <replaceable>username</> <replaceable>suffix</>.
Typically, the <replaceable>prefix</> parameter is used to specify
<literal>cn=</>, or <replaceable>DOMAIN</><literal>\</> in an Active
Directory environment. <replaceable>suffix</> is used to specify the
<replaceable>prefix</replaceable> <replaceable>username</replaceable> <replaceable>suffix</replaceable>.
Typically, the <replaceable>prefix</replaceable> parameter is used to specify
<literal>cn=</literal>, or <replaceable>DOMAIN</replaceable><literal>\</literal> in an Active
Directory environment. <replaceable>suffix</replaceable> is used to specify the
remaining part of the DN in a non-Active Directory environment.
</para>
<para>
In the second mode, which we will call the search+bind mode,
the server first binds to the LDAP directory with
a fixed user name and password, specified with <replaceable>ldapbinddn</>
and <replaceable>ldapbindpasswd</>, and performs a search for the user trying
a fixed user name and password, specified with <replaceable>ldapbinddn</replaceable>
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
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
<replaceable>ldapsearchattribute</>.
<replaceable>ldapsearchattribute</replaceable>.
Once the user has been found in
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
@ -1572,7 +1572,7 @@ omicron bryanh guest1
<para>
Attribute to match against the user name in the search when doing
search+bind authentication. If no attribute is specified, the
<literal>uid</> attribute will be used.
<literal>uid</literal> attribute will be used.
</para>
</listitem>
</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
to the configured RADIUS server. This request will be of type
<literal>Authenticate Only</literal>, and include parameters for
<literal>user name</>, <literal>password</> (encrypted) and
<literal>NAS Identifier</>. The request will be encrypted using
<literal>user name</literal>, <literal>password</literal> (encrypted) and
<literal>NAS Identifier</literal>. The request will be encrypted using
a secret shared with the server. The RADIUS server will respond to
this server with either <literal>Access Accept</> or
<literal>Access Reject</>. There is no support for RADIUS accounting.
this server with either <literal>Access Accept</literal> or
<literal>Access Reject</literal>. There is no support for RADIUS accounting.
</para>
<para>
@ -1762,8 +1762,8 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse
<note>
<para>
The encryption vector used will only be cryptographically
strong if <productname>PostgreSQL</> is built with support for
<productname>OpenSSL</>. In other cases, the transmission to the
strong if <productname>PostgreSQL</productname> is built with support for
<productname>OpenSSL</productname>. In other cases, the transmission to the
RADIUS server should only be considered obfuscated, not secured, and
external security measures should be applied if necessary.
</para>
@ -1777,7 +1777,7 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse
<listitem>
<para>
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>
</listitem>
</varlistentry>
@ -1786,12 +1786,12 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse
<term><literal>radiusidentifiers</literal></term>
<listitem>
<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
identifying for example which database user the user is attempting
to authenticate as, which can be used for policy matching on
the RADIUS server. If no identifier is specified, the default
<literal>postgresql</> will be used.
<literal>postgresql</literal> will be used.
</para>
</listitem>
</varlistentry>
@ -1836,11 +1836,11 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse
</para>
<para>
In a <filename>pg_hba.conf</> record specifying certificate
authentication, the authentication option <literal>clientcert</> is
assumed to be <literal>1</>, and it cannot be turned off since a client
certificate is necessary for this method. What the <literal>cert</>
method adds to the basic <literal>clientcert</> certificate validity test
In a <filename>pg_hba.conf</filename> record specifying certificate
authentication, the authentication option <literal>clientcert</literal> is
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</literal>
method adds to the basic <literal>clientcert</literal> certificate validity test
is a check that the <literal>cn</literal> attribute matches the database
user name.
</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
information about PAM, please read the
<ulink url="http://www.kernel.org/pub/linux/libs/pam/">
<productname>Linux-PAM</> Page</ulink>.
<productname>Linux-PAM</productname> Page</ulink>.
</para>
<para>
@ -1896,7 +1896,7 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse
<note>
<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
user. However, this is not an issue when PAM is configured to use
LDAP or other authentication methods.
@ -1922,11 +1922,11 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse
</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>postgresql</literal> login class if that's defined
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>
<note>

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@
</indexterm>
<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
their own right, they are even more useful as examples to modify for
your own purposes. The functions are general enough to be used
@ -26,15 +26,15 @@
<title>refint &mdash; Functions for Implementing Referential Integrity</title>
<para>
<function>check_primary_key()</> and
<function>check_foreign_key()</> are used to check foreign key constraints.
<function>check_primary_key()</function> and
<function>check_foreign_key()</function> are used to check foreign key constraints.
(This functionality is long since superseded by the built-in foreign
key mechanism, of course, but the module is still useful as an example.)
</para>
<para>
<function>check_primary_key()</> checks the referencing table.
To use, create a <literal>BEFORE INSERT OR UPDATE</> trigger using this
<function>check_primary_key()</function> checks the referencing table.
To use, create a <literal>BEFORE INSERT OR UPDATE</literal> trigger using this
function on a table referencing another table. Specify as the trigger
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
@ -43,14 +43,14 @@
</para>
<para>
<function>check_foreign_key()</> checks the referenced table.
To use, create a <literal>BEFORE DELETE OR UPDATE</> trigger using this
<function>check_foreign_key()</function> checks the referenced table.
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
arguments: the number of referencing tables for which the function has to
perform checking, the action if a referencing key is found
(<literal>cascade</> &mdash; to delete the referencing row,
<literal>restrict</> &mdash; to abort transaction if referencing keys
exist, <literal>setnull</> &mdash; to set referencing key fields to null),
(<literal>cascade</literal> &mdash; to delete the referencing row,
<literal>restrict</literal> &mdash; to abort transaction if referencing keys
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 referencing table name and column names (repeated for as many
referencing tables as were specified by first argument). Note that the
@ -59,7 +59,7 @@
</para>
<para>
There are examples in <filename>refint.example</>.
There are examples in <filename>refint.example</filename>.
</para>
</sect2>
@ -67,10 +67,10 @@
<title>timetravel &mdash; Functions for Implementing Time Travel</title>
<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
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
(stop_date):
@ -89,7 +89,7 @@ CREATE TABLE mytab (
<para>
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
contains nulls in these columns. Generally, inserting explicit
non-null data in these columns should only be done when re-loading
@ -97,7 +97,7 @@ CREATE TABLE mytab (
</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
be modified anymore &mdash; the trigger will prevent it. (If you need
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
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
time and stop_date to <literal>infinity</>.
time and stop_date to <literal>infinity</literal>.
</para>
<para>
@ -117,29 +117,29 @@ CREATE TABLE mytab (
<para>
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
query for tuples valid at any past time with suitable conditions on
start_date and stop_date.
</para>
<para>
<function>timetravel()</> is the general trigger function that supports
this behavior. Create a <literal>BEFORE INSERT OR UPDATE OR DELETE</>
<function>timetravel()</function> is the general trigger function that supports
this behavior. Create a <literal>BEFORE INSERT OR UPDATE OR DELETE</literal>
trigger using this function on each time-traveled table. Specify two
trigger arguments: the actual
names of the start_date and stop_date columns.
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
second column during UPDATE, and the third during DELETE.
</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.
<literal>set_timetravel('mytab', 1)</> will turn TT ON for table <literal>mytab</>.
<literal>set_timetravel('mytab', 0)</> will turn TT OFF for table <literal>mytab</>.
<literal>set_timetravel('mytab', 1)</literal> will turn TT ON for table <literal>mytab</literal>.
<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
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
@ -147,12 +147,12 @@ CREATE TABLE mytab (
</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.
</para>
<para>
There is an example in <filename>timetravel.example</>.
There is an example in <filename>timetravel.example</filename>.
</para>
</sect2>
@ -160,17 +160,17 @@ CREATE TABLE mytab (
<title>autoinc &mdash; Functions for Autoincrementing Fields</title>
<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
built-in <quote>serial column</> feature, but it is not the same:
<function>autoinc()</> will override attempts to substitute a
built-in <quote>serial column</quote> feature, but it is not the same:
<function>autoinc()</function> will override attempts to substitute a
different field value during inserts, and optionally it can be
used to increment the field during updates, too.
</para>
<para>
To use, create a <literal>BEFORE INSERT</> (or optionally <literal>BEFORE
INSERT OR UPDATE</>) trigger using this function. Specify two
To use, create a <literal>BEFORE INSERT</literal> (or optionally <literal>BEFORE
INSERT OR UPDATE</literal>) trigger using this function. Specify two
trigger arguments: the name of the integer column to be modified,
and the name of the sequence object that will supply values.
(Actually, you can specify any number of pairs of such names, if
@ -178,7 +178,7 @@ CREATE TABLE mytab (
</para>
<para>
There is an example in <filename>autoinc.example</>.
There is an example in <filename>autoinc.example</filename>.
</para>
</sect2>
@ -187,19 +187,19 @@ CREATE TABLE mytab (
<title>insert_username &mdash; Functions for Tracking Who Changed a Table</title>
<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
who last modified a particular row within a table.
</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
argument: the name of the text column to be modified.
</para>
<para>
There is an example in <filename>insert_username.example</>.
There is an example in <filename>insert_username.example</filename>.
</para>
</sect2>
@ -208,21 +208,21 @@ CREATE TABLE mytab (
<title>moddatetime &mdash; Functions for Tracking Last Modification Time</title>
<para>
<function>moddatetime()</> is a trigger that stores the current
time into a <type>timestamp</> field. This can be useful for tracking
<function>moddatetime()</function> is a trigger that stores the current
time into a <type>timestamp</type> field. This can be useful for tracking
the last modification time of a particular row within a table.
</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
argument: the name of the column to be modified.
The column must be of type <type>timestamp</> or <type>timestamp with
time zone</>.
The column must be of type <type>timestamp</type> or <type>timestamp with
time zone</type>.
</para>
<para>
There is an example in <filename>moddatetime.example</>.
There is an example in <filename>moddatetime.example</filename>.
</para>
</sect2>

View File

@ -6,7 +6,7 @@
<para>
This appendix and the next one contain information regarding the modules that
can be found in the <literal>contrib</literal> directory of the
<productname>PostgreSQL</> distribution.
<productname>PostgreSQL</productname> distribution.
These include porting tools, analysis utilities,
and plug-in features that are not part of the core PostgreSQL system,
mainly because they address a limited audience or are too experimental
@ -41,54 +41,54 @@
<screen>
<userinput>make installcheck</userinput>
</screen>
once you have a <productname>PostgreSQL</> server running.
once you have a <productname>PostgreSQL</productname> server running.
</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,
such as <literal>postgresql-contrib</>.
such as <literal>postgresql-contrib</literal>.
</para>
<para>
Many modules supply new user-defined functions, operators, or types.
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.
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,
you can simply do
<programlisting>
CREATE EXTENSION <replaceable>module_name</>;
CREATE EXTENSION <replaceable>module_name</replaceable>;
</programlisting>
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
command in each database that you want
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.
</para>
<para>
Many modules allow you to install their objects in a schema of your
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
target schema, typically <literal>public</>.
target schema, typically <literal>public</literal>.
</para>
<para>
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
<programlisting>
CREATE EXTENSION <replaceable>module_name</> FROM unpackaged;
CREATE EXTENSION <replaceable>module_name</replaceable> FROM unpackaged;
</programlisting>
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">.
For more information about extension updates, see
<xref linkend="extend-extensions">.
@ -163,7 +163,7 @@ pages.
<para>
This appendix and the previous one contain information regarding the modules that
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
server extensions and plug-ins found in <literal>contrib</literal>
specifically.

View File

@ -8,7 +8,7 @@
</indexterm>
<para>
This module implements a data type <type>cube</> for
This module implements a data type <type>cube</type> for
representing multidimensional cubes.
</para>
@ -17,8 +17,8 @@
<para>
<xref linkend="cube-repr-table"> shows the valid external
representations for the <type>cube</>
type. <replaceable>x</>, <replaceable>y</>, etc. denote
representations for the <type>cube</type>
type. <replaceable>x</replaceable>, <replaceable>y</replaceable>, etc. denote
floating-point numbers.
</para>
@ -34,43 +34,43 @@
<tbody>
<row>
<entry><literal><replaceable>x</></literal></entry>
<entry><literal><replaceable>x</replaceable></literal></entry>
<entry>A one-dimensional point
(or, zero-length one-dimensional interval)
</entry>
</row>
<row>
<entry><literal>(<replaceable>x</>)</literal></entry>
<entry><literal>(<replaceable>x</replaceable>)</literal></entry>
<entry>Same as above</entry>
</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
zero-volume cube
</entry>
</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>
</row>
<row>
<entry><literal>(<replaceable>x</>),(<replaceable>y</>)</literal></entry>
<entry>A one-dimensional interval starting at <replaceable>x</> and ending at <replaceable>y</> or vice versa; the
<entry><literal>(<replaceable>x</replaceable>),(<replaceable>y</replaceable>)</literal></entry>
<entry>A one-dimensional interval starting at <replaceable>x</replaceable> and ending at <replaceable>y</replaceable> or vice versa; the
order does not matter
</entry>
</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>
</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
opposite corners
</entry>
</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>
</row>
</tbody>
@ -79,17 +79,17 @@
<para>
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
<quote>lower left &mdash; upper right</> internal representation.
When the corners coincide, <type>cube</> stores only one corner
along with an <quote>is point</> flag to avoid wasting space.
<quote>lower left &mdash; upper right</quote> internal representation.
When the corners coincide, <type>cube</type> stores only one corner
along with an <quote>is point</quote> flag to avoid wasting space.
</para>
<para>
White space is ignored on input, so
<literal>[(<replaceable>x</>),(<replaceable>y</>)]</literal> is the same as
<literal>[ ( <replaceable>x</> ), ( <replaceable>y</> ) ]</literal>.
<literal>[(<replaceable>x</replaceable>),(<replaceable>y</replaceable>)]</literal> is the same as
<literal>[ ( <replaceable>x</replaceable> ), ( <replaceable>y</replaceable> ) ]</literal>.
</para>
</sect2>
@ -107,7 +107,7 @@
<para>
<xref linkend="cube-operators-table"> shows the operators provided for
type <type>cube</>.
type <type>cube</type>.
</para>
<table id="cube-operators-table">
@ -123,91 +123,91 @@
<tbody>
<row>
<entry><literal>a = b</></entry>
<entry><type>boolean</></entry>
<entry><literal>a = b</literal></entry>
<entry><type>boolean</type></entry>
<entry>The cubes a and b are identical.</entry>
</row>
<row>
<entry><literal>a &amp;&amp; b</></entry>
<entry><type>boolean</></entry>
<entry><literal>a &amp;&amp; b</literal></entry>
<entry><type>boolean</type></entry>
<entry>The cubes a and b overlap.</entry>
</row>
<row>
<entry><literal>a @&gt; b</></entry>
<entry><type>boolean</></entry>
<entry><literal>a @&gt; b</literal></entry>
<entry><type>boolean</type></entry>
<entry>The cube a contains the cube b.</entry>
</row>
<row>
<entry><literal>a &lt;@ b</></entry>
<entry><type>boolean</></entry>
<entry><literal>a &lt;@ b</literal></entry>
<entry><type>boolean</type></entry>
<entry>The cube a is contained in the cube b.</entry>
</row>
<row>
<entry><literal>a &lt; b</></entry>
<entry><type>boolean</></entry>
<entry><literal>a &lt; b</literal></entry>
<entry><type>boolean</type></entry>
<entry>The cube a is less than the cube b.</entry>
</row>
<row>
<entry><literal>a &lt;= b</></entry>
<entry><type>boolean</></entry>
<entry><literal>a &lt;= b</literal></entry>
<entry><type>boolean</type></entry>
<entry>The cube a is less than or equal to the cube b.</entry>
</row>
<row>
<entry><literal>a &gt; b</></entry>
<entry><type>boolean</></entry>
<entry><literal>a &gt; b</literal></entry>
<entry><type>boolean</type></entry>
<entry>The cube a is greater than the cube b.</entry>
</row>
<row>
<entry><literal>a &gt;= b</></entry>
<entry><type>boolean</></entry>
<entry><literal>a &gt;= b</literal></entry>
<entry><type>boolean</type></entry>
<entry>The cube a is greater than or equal to the cube b.</entry>
</row>
<row>
<entry><literal>a &lt;&gt; b</></entry>
<entry><type>boolean</></entry>
<entry><literal>a &lt;&gt; b</literal></entry>
<entry><type>boolean</type></entry>
<entry>The cube a is not equal to the cube b.</entry>
</row>
<row>
<entry><literal>a -&gt; n</></entry>
<entry><type>float8</></entry>
<entry>Get <replaceable>n</>-th coordinate of cube (counting from 1).</entry>
<entry><literal>a -&gt; n</literal></entry>
<entry><type>float8</type></entry>
<entry>Get <replaceable>n</replaceable>-th coordinate of cube (counting from 1).</entry>
</row>
<row>
<entry><literal>a ~&gt; n</></entry>
<entry><type>float8</></entry>
<entry><literal>a ~&gt; n</literal></entry>
<entry><type>float8</type></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
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.
</entry>
</row>
<row>
<entry><literal>a &lt;-&gt; b</></entry>
<entry><type>float8</></entry>
<entry><literal>a &lt;-&gt; b</literal></entry>
<entry><type>float8</type></entry>
<entry>Euclidean distance between a and b.</entry>
</row>
<row>
<entry><literal>a &lt;#&gt; b</></entry>
<entry><type>float8</></entry>
<entry><literal>a &lt;#&gt; b</literal></entry>
<entry><type>float8</type></entry>
<entry>Taxicab (L-1 metric) distance between a and b.</entry>
</row>
<row>
<entry><literal>a &lt;=&gt; b</></entry>
<entry><type>float8</></entry>
<entry><literal>a &lt;=&gt; b</literal></entry>
<entry><type>float8</type></entry>
<entry>Chebyshev (L-inf metric) distance between a and b.</entry>
</row>
@ -216,35 +216,35 @@
</table>
<para>
(Before PostgreSQL 8.2, the containment operators <literal>@&gt;</> and <literal>&lt;@</> were
respectively called <literal>@</> and <literal>~</>. These names are still available, but are
(Before PostgreSQL 8.2, the containment operators <literal>@&gt;</literal> and <literal>&lt;@</literal> were
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
are reversed from the convention formerly followed by the core geometric
data types!)
</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
operators first compare the first coordinates, and if those are equal,
compare the second coordinates, etc. They exist mainly to support the
b-tree index operator class for <type>cube</>, which can be useful for
example if you would like a UNIQUE constraint on a <type>cube</> column.
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</type> column.
</para>
<para>
The <filename>cube</> module also provides a GiST index operator class for
<type>cube</> values.
A <type>cube</> GiST index can be used to search for values using the
<literal>=</>, <literal>&amp;&amp;</>, <literal>@&gt;</>, and
<literal>&lt;@</> operators in <literal>WHERE</> clauses.
The <filename>cube</filename> module also provides a GiST index operator class for
<type>cube</type> values.
A <type>cube</type> GiST index can be used to search for values using the
<literal>=</literal>, <literal>&amp;&amp;</literal>, <literal>@&gt;</literal>, and
<literal>&lt;@</literal> operators in <literal>WHERE</literal> clauses.
</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
<literal>&lt;-&gt;</>, <literal>&lt;#&gt;</>, and
<literal>&lt;=&gt;</> in <literal>ORDER BY</> clauses.
<literal>&lt;-&gt;</literal>, <literal>&lt;#&gt;</literal>, and
<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)
could be found efficiently with:
<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>
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.
For example, to get the first few cubes ordered by the first coordinate
(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>
<entry><literal>cube_ll_coord(cube, integer)</literal></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.
</entry>
<entry>
@ -376,7 +376,7 @@ SELECT c FROM test ORDER BY c ~&gt; 3 DESC LIMIT 5;
<row>
<entry><literal>cube_ur_coord(cube, integer)</literal></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.
</entry>
<entry>
@ -412,9 +412,9 @@ SELECT c FROM test ORDER BY c ~&gt; 3 DESC LIMIT 5;
desired.
</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]) ==
'(5,3,1,1),(8,7,6,6)'</>
'(5,3,1,1),(8,7,6,6)'</literal>
</entry>
</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><type>cube</type></entry>
<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.
All defined dimensions are changed by the radius <replaceable>r</>.
Lower-left coordinates are decreased by <replaceable>r</> and
upper-right coordinates are increased by <replaceable>r</>. If a
All defined dimensions are changed by the radius <replaceable>r</replaceable>.
Lower-left coordinates are decreased by <replaceable>r</replaceable> and
upper-right coordinates are increased by <replaceable>r</replaceable>. If a
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.
If <replaceable>n</> is greater than the number of defined dimensions
and the cube is being enlarged (<replaceable>r</> &gt; 0), then extra
dimensions are added to make <replaceable>n</> altogether;
If <replaceable>n</replaceable> is greater than the number of defined dimensions
and the cube is being enlarged (<replaceable>r</replaceable> &gt; 0), then extra
dimensions are added to make <replaceable>n</replaceable> altogether;
0 is used as the initial value for the extra coordinates.
This function is useful for creating bounding boxes around a point for
searching for nearby points.
</entry>
<entry>
<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>
</row>
</tbody>
@ -523,13 +523,13 @@ t
<title>Notes</title>
<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>
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
in <filename>cubedata.h</> if you need something bigger.
in <filename>cubedata.h</filename> if you need something bigger.
</para>
</sect2>

View File

@ -9,9 +9,9 @@
</indexterm>
<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.
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
provider can provide an alternative method of scanning any relation in the
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>
Although this hook function can be used to examine, modify, or remove
paths generated by the core system, a custom scan provider will typically
confine itself to generating <structname>CustomPath</> objects and adding
them to <literal>rel</> using <function>add_path</>. The custom scan
provider is responsible for initializing the <structname>CustomPath</>
confine itself to generating <structname>CustomPath</structname> objects and adding
them to <literal>rel</literal> using <function>add_path</function>. The custom scan
provider is responsible for initializing the <structname>CustomPath</structname>
object, which is declared like this:
<programlisting>
typedef struct CustomPath
@ -68,22 +68,22 @@ typedef struct CustomPath
</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
by this path. <structfield>flags</> is a bit mask, which should include
<literal>CUSTOMPATH_SUPPORT_BACKWARD_SCAN</> if the custom path can support
a backward scan and <literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</> if it
by this path. <structfield>flags</structfield> is a bit mask, which should include
<literal>CUSTOMPATH_SUPPORT_BACKWARD_SCAN</literal> if the custom path can support
a backward scan and <literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</literal> if it
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
<structname>Plan</> nodes by planner.
<structfield>custom_private</> can be used to store the custom path's
<structname>Plan</structname> nodes by planner.
<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
by <literal>nodeToString</>, so that debugging routines that attempt to
print the custom path will work as designed. <structfield>methods</> must
by <literal>nodeToString</literal>, so that debugging routines that attempt to
print the custom path will work as designed. <structfield>methods</structfield> must
point to a (usually statically allocated) object implementing the required
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
method table.
</para>
@ -93,7 +93,7 @@ typedef struct CustomPath
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
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>
typedef void (*set_join_pathlist_hook_type) (PlannerInfo *root,
RelOptInfo *joinrel,
@ -122,7 +122,7 @@ Plan *(*PlanCustomPath) (PlannerInfo *root,
List *custom_plans);
</programlisting>
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.
</para>
</sect2>
@ -150,45 +150,45 @@ typedef struct CustomScan
</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.
<structfield>flags</> is a bit mask with the same meaning as in
<structname>CustomPath</>.
<structfield>custom_plans</> can be used to store child
<structname>Plan</> nodes.
<structfield>custom_exprs</> should be used to
<structfield>flags</structfield> is a bit mask with the same meaning as in
<structname>CustomPath</structname>.
<structfield>custom_plans</structfield> can be used to store child
<structname>Plan</structname> nodes.
<structfield>custom_exprs</structfield> should be used to
store expression trees that will need to be fixed up by
<filename>setrefs.c</> and <filename>subselect.c</>, while
<structfield>custom_private</> should be used to store other private data
<filename>setrefs.c</filename> and <filename>subselect.c</filename>, while
<structfield>custom_private</structfield> should be used to store other private data
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
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
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
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
detailed below.
</para>
<para>
When a <structname>CustomScan</> scans a single relation,
<structfield>scan.scanrelid</> must be the range table index of the table
to be scanned. When it replaces a join, <structfield>scan.scanrelid</>
When a <structname>CustomScan</structname> scans a single relation,
<structfield>scan.scanrelid</structfield> must be the range table index of the table
to be scanned. When it replaces a join, <structfield>scan.scanrelid</structfield>
should be zero.
</para>
<para>
Plan trees must be able to be duplicated using <function>copyObject</>,
so all the data stored within the <quote>custom</> fields must consist of
Plan trees must be able to be duplicated using <function>copyObject</function>,
so all the data stored within the <quote>custom</quote> fields must consist of
nodes that that function can handle. Furthermore, custom scan providers
cannot substitute a larger structure that embeds
a <structname>CustomScan</> for the structure itself, as would be possible
for a <structname>CustomPath</> or <structname>CustomScanState</>.
a <structname>CustomScan</structname> for the structure itself, as would be possible
for a <structname>CustomPath</structname> or <structname>CustomScanState</structname>.
</para>
<sect2 id="custom-scan-plan-callbacks">
@ -197,14 +197,14 @@ typedef struct CustomScan
<programlisting>
Node *(*CreateCustomScanState) (CustomScan *cscan);
</programlisting>
Allocate a <structname>CustomScanState</> for this
<structname>CustomScan</>. The actual allocation will often be larger than
required for an ordinary <structname>CustomScanState</>, because many
Allocate a <structname>CustomScanState</structname> for this
<structname>CustomScan</structname>. The actual allocation will often be larger than
required for an ordinary <structname>CustomScanState</structname>, because many
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
stage; after <function>ExecInitCustomScan</> performs basic initialization,
the <function>BeginCustomScan</> callback will be invoked to give the
stage; after <function>ExecInitCustomScan</function> performs basic initialization,
the <function>BeginCustomScan</function> callback will be invoked to give the
custom scan provider a chance to do whatever else is needed.
</para>
</sect2>
@ -214,8 +214,8 @@ Node *(*CreateCustomScanState) (CustomScan *cscan);
<title>Executing Custom Scans</title>
<para>
When a <structfield>CustomScan</> is executed, its execution state is
represented by a <structfield>CustomScanState</>, which is declared as
When a <structfield>CustomScan</structfield> is executed, its execution state is
represented by a <structfield>CustomScanState</structfield>, which is declared as
follows:
<programlisting>
typedef struct CustomScanState
@ -228,15 +228,15 @@ typedef struct CustomScanState
</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,
<literal>ss.ss_currentRelation</> is left NULL.
<structfield>flags</> is a bit mask with the same meaning as in
<structname>CustomPath</> and <structname>CustomScan</>.
<structfield>methods</> must point to a (usually statically allocated)
<literal>ss.ss_currentRelation</literal> is left NULL.
<structfield>flags</structfield> is a bit mask with the same meaning as in
<structname>CustomPath</structname> and <structname>CustomScan</structname>.
<structfield>methods</structfield> must point to a (usually statically allocated)
object implementing the required custom scan state methods, which are
further detailed below. Typically, a <structname>CustomScanState</>, which
need not support <function>copyObject</>, will actually be a larger
further detailed below. Typically, a <structname>CustomScanState</structname>, which
need not support <function>copyObject</function>, will actually be a larger
structure embedding the above as its first member.
</para>
@ -249,8 +249,8 @@ void (*BeginCustomScan) (CustomScanState *node,
EState *estate,
int eflags);
</programlisting>
Complete initialization of the supplied <structname>CustomScanState</>.
Standard fields have been initialized by <function>ExecInitCustomScan</>,
Complete initialization of the supplied <structname>CustomScanState</structname>.
Standard fields have been initialized by <function>ExecInitCustomScan</function>,
but any private fields should be initialized here.
</para>
@ -259,16 +259,16 @@ void (*BeginCustomScan) (CustomScanState *node,
TupleTableSlot *(*ExecCustomScan) (CustomScanState *node);
</programlisting>
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,
<literal>NULL</> or an empty slot should be returned.
<literal>NULL</literal> or an empty slot should be returned.
</para>
<para>
<programlisting>
void (*EndCustomScan) (CustomScanState *node);
</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
no associated data or it will be cleaned up automatically.
</para>
@ -286,9 +286,9 @@ void (*ReScanCustomScan) (CustomScanState *node);
void (*MarkPosCustomScan) (CustomScanState *node);
</programlisting>
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
<literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</> flag is set.
<literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</literal> flag is set.
</para>
<para>
@ -296,9 +296,9 @@ void (*MarkPosCustomScan) (CustomScanState *node);
void (*RestrPosCustomScan) (CustomScanState *node);
</programlisting>
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
<literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</> flag is set.
<literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</literal> flag is set.
</para>
<para>
@ -320,8 +320,8 @@ void (*InitializeDSMCustomScan) (CustomScanState *node,
void *coordinate);
</programlisting>
Initialize the dynamic shared memory that will be required for parallel
operation. <literal>coordinate</> points to a shared memory area of
size equal to the return value of <function>EstimateDSMCustomScan</>.
operation. <literal>coordinate</literal> points to a shared memory area of
size equal to the return value of <function>EstimateDSMCustomScan</function>.
This callback is optional, and need only be supplied if this custom
scan provider supports parallel execution.
</para>
@ -337,9 +337,9 @@ void (*ReInitializeDSMCustomScan) (CustomScanState *node,
This callback is optional, and need only be supplied if this custom
scan provider supports parallel execution.
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
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.
</para>
@ -350,7 +350,7 @@ void (*InitializeWorkerCustomScan) (CustomScanState *node,
void *coordinate);
</programlisting>
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
scan provider supports parallel execution.
</para>
@ -361,7 +361,7 @@ void (*ShutdownCustomScan) (CustomScanState *node);
</programlisting>
Release resources when it is anticipated the node will not be executed
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
destroyed just after this callback is invoked, custom scan providers that
wish to take some action before the DSM segment goes away should implement
@ -374,9 +374,9 @@ void (*ExplainCustomScan) (CustomScanState *node,
List *ancestors,
ExplainState *es);
</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
<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
of additional, private state.
</para>

File diff suppressed because it is too large Load Diff

View File

@ -37,18 +37,18 @@
<substeps>
<step>
<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.
</para>
</step>
<step>
<para>
If the numeric token contains a dash (<literal>-</>), slash
(<literal>/</>), or two or more dots (<literal>.</>), this is
If the numeric token contains a dash (<literal>-</literal>), slash
(<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
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>
</step>
@ -63,8 +63,8 @@
<step>
<para>
If the token starts with a plus (<literal>+</>) or minus
(<literal>-</>), then it is either a numeric time zone or a special
If the token starts with a plus (<literal>+</literal>) or minus
(<literal>-</literal>), then it is either a numeric time zone or a special
field.
</para>
</step>
@ -114,7 +114,7 @@
and if no other date fields have been previously read, then interpret
as a <quote>concatenated date</quote> (e.g.,
<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>
</step>
@ -128,7 +128,7 @@
<step>
<para>
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>
</step>
@ -143,7 +143,7 @@
<step>
<para>
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.
</para>
</step>
@ -167,7 +167,7 @@
<tip>
<para>
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>
</tip>
</para>
@ -317,7 +317,7 @@
<entry>Ignored</entry>
</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>
</row>
<row>
@ -354,23 +354,23 @@
can be altered by any database user, the possible values for it
are under the control of the database administrator &mdash; they
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
can set local policy for timezone abbreviations.
</para>
<para>
<varname>timezone_abbreviations</> can be set to any file name
found in <filename>.../share/timezonesets/</>, if the file's name
<varname>timezone_abbreviations</varname> can be set to any file name
found in <filename>.../share/timezonesets/</filename>, if the file's name
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
backup files and other extraneous files.)
</para>
<para>
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:
<synopsis>
@ -388,12 +388,12 @@
the equivalent offset in seconds from UTC, positive being east from
Greenwich and negative being west. For example, -18000 would be five
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.
</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
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,
@ -417,34 +417,34 @@
</tip>
<para>
The <literal>@INCLUDE</> syntax allows inclusion of another file in the
<filename>.../share/timezonesets/</> directory. Inclusion can be nested,
The <literal>@INCLUDE</literal> syntax allows inclusion of another file in the
<filename>.../share/timezonesets/</filename> directory. Inclusion can be nested,
to a limited depth.
</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
included files). Without this, conflicting definitions of the same
timezone abbreviation are considered an error.
</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.
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
<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>
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
according to the IANA timezone database. The zone name
definitions found in these files can be copied and pasted into a custom
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.
</para>
@ -460,16 +460,16 @@
<para>
Time zone abbreviations defined in the configuration file override
non-timezone meanings built into <productname>PostgreSQL</productname>.
For example, the <filename>Australia</> configuration file defines
<literal>SAT</> (for South Australian Standard Time). When this
file is active, <literal>SAT</> will not be recognized as an abbreviation
For example, the <filename>Australia</filename> configuration file defines
<literal>SAT</literal> (for South Australian Standard Time). When this
file is active, <literal>SAT</literal> will not be recognized as an abbreviation
for Saturday.
</para>
</caution>
<caution>
<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
will not include this directory.
</para>
@ -492,10 +492,10 @@
<quote>datetime literal</quote>, the <quote>datetime
values</quote> are constrained by the natural rules for dates and
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
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>
@ -569,7 +569,7 @@ $ <userinput>cal 9 1752</userinput>
dominions, not other places.
Since it would be difficult and confusing to try to track the actual
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
accurate.
</para>
@ -597,7 +597,7 @@ $ <userinput>cal 9 1752</userinput>
and probably takes its name from Scaliger's father,
the Italian scholar Julius Caesar Scaliger (1484-1558).
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
24 November 4714 BC in the Gregorian calendar. Julian Date counting
is most often used by astronomers for labeling their nightly observations,
@ -607,10 +607,10 @@ $ <userinput>cal 9 1752</userinput>
</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
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.
</para>

View File

@ -8,8 +8,8 @@
</indexterm>
<para>
<filename>dblink</> is a module that supports connections to
other <productname>PostgreSQL</> databases from within a database
<filename>dblink</filename> is a module that supports connections to
other <productname>PostgreSQL</productname> databases from within a database
session.
</para>
@ -44,9 +44,9 @@ dblink_connect(text connname, text connstr) returns text
<title>Description</title>
<para>
<function>dblink_connect()</> establishes a connection to a remote
<productname>PostgreSQL</> database. The server and database to
be contacted are identified through a standard <application>libpq</>
<function>dblink_connect()</function> establishes a connection to a remote
<productname>PostgreSQL</productname> database. The server and database to
be contacted are identified through a standard <application>libpq</application>
connection string. Optionally, a name can be assigned to the
connection. Multiple named connections can be open at once, but
only one unnamed connection is permitted at a time. The connection
@ -81,9 +81,9 @@ dblink_connect(text connname, text connstr) returns text
<varlistentry>
<term><parameter>connstr</parameter></term>
<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
password=mypasswd</>.
password=mypasswd</literal>.
For details see <xref linkend="libpq-connstring">.
Alternatively, the name of a foreign server.
</para>
@ -96,7 +96,7 @@ dblink_connect(text connname, text connstr) returns text
<title>Return Value</title>
<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).
</para>
</refsect1>
@ -105,15 +105,15 @@ dblink_connect(text connname, text connstr) returns text
<title>Notes</title>
<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
capability, use <function>dblink_connect_u</> instead.
capability, use <function>dblink_connect_u</function> instead.
</para>
<para>
It is unwise to choose connection names that contain equal signs,
as this opens a risk of confusion with connection info strings
in other <filename>dblink</> functions.
in other <filename>dblink</filename> functions.
</para>
</refsect1>
@ -208,8 +208,8 @@ dblink_connect_u(text connname, text connstr) returns text
<title>Description</title>
<para>
<function>dblink_connect_u()</> is identical to
<function>dblink_connect()</>, except that it will allow non-superusers
<function>dblink_connect_u()</function> is identical to
<function>dblink_connect()</function>, except that it will allow non-superusers
to connect using any authentication method.
</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
involve a password, then impersonation and subsequent escalation of
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,
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
possibility of exposing a password to an untrustworthy remote server.
Therefore, <function>dblink_connect_u()</> is initially
installed with all privileges revoked from <literal>PUBLIC</>,
Therefore, <function>dblink_connect_u()</function> is initially
installed with all privileges revoked from <literal>PUBLIC</literal>,
making it un-callable except by superusers. In some situations
it may be appropriate to grant <literal>EXECUTE</> permission for
<function>dblink_connect_u()</> to specific users who are considered
it may be appropriate to grant <literal>EXECUTE</literal> permission for
<function>dblink_connect_u()</function> to specific users who are considered
trustworthy, but this should be done with care. It is also recommended
that any <filename>~/.pgpass</> file belonging to the server's user
<emphasis>not</> contain any records specifying a wildcard host name.
that any <filename>~/.pgpass</filename> file belonging to the server's user
<emphasis>not</emphasis> contain any records specifying a wildcard host name.
</para>
<para>
For further details see <function>dblink_connect()</>.
For further details see <function>dblink_connect()</function>.
</para>
</refsect1>
</refentry>
@ -265,8 +265,8 @@ dblink_disconnect(text connname) returns text
<title>Description</title>
<para>
<function>dblink_disconnect()</> closes a connection previously opened
by <function>dblink_connect()</>. The form with no arguments closes
<function>dblink_disconnect()</function> closes a connection previously opened
by <function>dblink_connect()</function>. The form with no arguments closes
an unnamed connection.
</para>
</refsect1>
@ -290,7 +290,7 @@ dblink_disconnect(text connname) returns text
<title>Return Value</title>
<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).
</para>
</refsect1>
@ -341,15 +341,15 @@ dblink(text sql [, bool fail_on_error]) returns setof record
<title>Description</title>
<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.
</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
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.
</para>
</refsect1>
@ -373,7 +373,7 @@ dblink(text sql [, bool fail_on_error]) returns setof record
<listitem>
<para>
A connection info string, as previously described for
<function>dblink_connect</>.
<function>dblink_connect</function>.
</para>
</listitem>
</varlistentry>
@ -383,7 +383,7 @@ dblink(text sql [, bool fail_on_error]) returns setof record
<listitem>
<para>
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>
</listitem>
</varlistentry>
@ -407,11 +407,11 @@ dblink(text sql [, bool fail_on_error]) returns setof record
<para>
The function returns the row(s) produced by the query. Since
<function>dblink</> can be used with any query, it is declared
to return <type>record</>, rather than specifying any particular
<function>dblink</function> can be used with any query, it is declared
to return <type>record</type>, rather than specifying any particular
set of columns. This means that you must specify the expected
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:
<programlisting>
@ -421,20 +421,20 @@ SELECT *
WHERE proname LIKE 'bytea%';
</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.
(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
<literal>*</> should expand to, and what <structname>proname</>
in the <literal>WHERE</> clause refers to, in advance of trying
<literal>*</literal> should expand to, and what <structname>proname</structname>
in the <literal>WHERE</literal> clause refers to, in advance of trying
to execute the function. At run time, an error will be thrown
if the actual query result from the remote database does not
have the same number of columns shown in the <literal>FROM</> clause.
The column names need not match, however, and <function>dblink</>
have the same number of columns shown in the <literal>FROM</literal> clause.
The column names need not match, however, and <function>dblink</function>
does not insist on exact type matches either. It will succeed
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>
</refsect1>
@ -442,7 +442,7 @@ SELECT *
<title>Notes</title>
<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.
This allows the column type information to be buried in the view,
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>
<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.
</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
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.
</para>
</refsect1>
@ -591,7 +591,7 @@ dblink_exec(text sql [, bool fail_on_error]) returns text
<listitem>
<para>
A connection info string, as previously described for
<function>dblink_connect</>.
<function>dblink_connect</function>.
</para>
</listitem>
</varlistentry>
@ -602,7 +602,7 @@ dblink_exec(text sql [, bool fail_on_error]) returns text
<para>
The SQL command that you wish to execute in the remote database,
for example
<literal>insert into foo values(0,'a','{"a0","b0","c0"}')</>.
<literal>insert into foo values(0,'a','{"a0","b0","c0"}')</literal>.
</para>
</listitem>
</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
remote side of the connection causes an error to also be thrown
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>
</listitem>
</varlistentry>
@ -625,7 +625,7 @@ dblink_exec(text sql [, bool fail_on_error]) returns text
<title>Return Value</title>
<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>
</refsect1>
@ -695,9 +695,9 @@ dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) ret
<title>Description</title>
<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
<function>dblink_fetch()</> and <function>dblink_close()</>.
<function>dblink_fetch()</function> and <function>dblink_close()</function>.
</para>
</refsect1>
@ -728,8 +728,8 @@ dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) ret
<term><parameter>sql</parameter></term>
<listitem>
<para>
The <command>SELECT</> statement that you wish to execute in the remote
database, for example <literal>select * from pg_class</>.
The <command>SELECT</command> statement that you wish to execute in the remote
database, for example <literal>select * from pg_class</literal>.
</para>
</listitem>
</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
remote side of the connection causes an error to also be thrown
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>
</listitem>
</varlistentry>
@ -752,7 +752,7 @@ dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) ret
<title>Return Value</title>
<para>
Returns status, either <literal>OK</> or <literal>ERROR</>.
Returns status, either <literal>OK</literal> or <literal>ERROR</literal>.
</para>
</refsect1>
@ -761,16 +761,16 @@ dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) ret
<para>
Since a cursor can only persist within a transaction,
<function>dblink_open</> starts an explicit transaction block
(<command>BEGIN</>) on the remote side, if the remote side was
<function>dblink_open</function> starts an explicit transaction block
(<command>BEGIN</command>) on the remote side, if the remote side was
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
you use <function>dblink_exec</> to change data between
<function>dblink_open</> and <function>dblink_close</>,
and then an error occurs or you use <function>dblink_disconnect</> before
<function>dblink_close</>, your change <emphasis>will be
lost</> because the transaction will be aborted.
you use <function>dblink_exec</function> to change data between
<function>dblink_open</function> and <function>dblink_close</function>,
and then an error occurs or you use <function>dblink_disconnect</function> before
<function>dblink_close</function>, your change <emphasis>will be
lost</emphasis> because the transaction will be aborted.
</para>
</refsect1>
@ -819,8 +819,8 @@ dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error])
<title>Description</title>
<para>
<function>dblink_fetch</> fetches rows from a cursor previously
established by <function>dblink_open</>.
<function>dblink_fetch</function> fetches rows from a cursor previously
established by <function>dblink_open</function>.
</para>
</refsect1>
@ -851,7 +851,7 @@ dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error])
<term><parameter>howmany</parameter></term>
<listitem>
<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
forward. Once the cursor has reached its end, no more rows are produced.
</para>
@ -878,7 +878,7 @@ dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error])
<para>
The function returns the row(s) fetched from the cursor. To use this
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>
</refsect1>
@ -887,11 +887,11 @@ dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error])
<para>
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
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
query after the remote <command>FETCH</> has been done.
query after the remote <command>FETCH</command> has been done.
</para>
</refsect1>
@ -972,8 +972,8 @@ dblink_close(text connname, text cursorname [, bool fail_on_error]) returns text
<title>Description</title>
<para>
<function>dblink_close</> closes a cursor previously opened with
<function>dblink_open</>.
<function>dblink_close</function> closes a cursor previously opened with
<function>dblink_open</function>.
</para>
</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
remote side of the connection causes an error to also be thrown
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>
</listitem>
</varlistentry>
@ -1018,7 +1018,7 @@ dblink_close(text connname, text cursorname [, bool fail_on_error]) returns text
<title>Return Value</title>
<para>
Returns status, either <literal>OK</> or <literal>ERROR</>.
Returns status, either <literal>OK</literal> or <literal>ERROR</literal>.
</para>
</refsect1>
@ -1026,9 +1026,9 @@ dblink_close(text connname, text cursorname [, bool fail_on_error]) returns text
<title>Notes</title>
<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,
<function>dblink_close</> will issue the matching <command>COMMIT</>.
<function>dblink_close</function> will issue the matching <command>COMMIT</command>.
</para>
</refsect1>
@ -1082,8 +1082,8 @@ dblink_get_connections() returns text[]
<title>Description</title>
<para>
<function>dblink_get_connections</> returns an array of the names
of all open named <filename>dblink</> connections.
<function>dblink_get_connections</function> returns an array of the names
of all open named <filename>dblink</filename> connections.
</para>
</refsect1>
@ -1127,7 +1127,7 @@ dblink_error_message(text connname) returns text
<title>Description</title>
<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.
</para>
</refsect1>
@ -1190,7 +1190,7 @@ dblink_send_query(text connname, text sql) returns int
<title>Description</title>
<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.
There must not be an async query already in progress on the
connection.
@ -1198,10 +1198,10 @@ dblink_send_query(text connname, text sql) returns int
<para>
After successfully dispatching an async query, completion status
can be checked with <function>dblink_is_busy</>, and the results
are ultimately collected with <function>dblink_get_result</>.
can be checked with <function>dblink_is_busy</function>, and the results
are ultimately collected with <function>dblink_get_result</function>.
It is also possible to attempt to cancel an active async query
using <function>dblink_cancel_query</>.
using <function>dblink_cancel_query</function>.
</para>
</refsect1>
@ -1223,7 +1223,7 @@ dblink_send_query(text connname, text sql) returns int
<listitem>
<para>
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>
</listitem>
</varlistentry>
@ -1272,7 +1272,7 @@ dblink_is_busy(text connname) returns int
<title>Description</title>
<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>
</refsect1>
@ -1297,7 +1297,7 @@ dblink_is_busy(text connname) returns int
<para>
Returns 1 if connection is busy, 0 if it is not busy.
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>
</refsect1>
@ -1336,10 +1336,10 @@ dblink_get_notify(text connname) returns setof (notify_name text, be_pid int, ex
<title>Description</title>
<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.
To receive notifications via dblink, <function>LISTEN</> must
first be issued, using <function>dblink_exec</>.
To receive notifications via dblink, <function>LISTEN</function> must
first be issued, using <function>dblink_exec</function>.
For details see <xref linkend="sql-listen"> and <xref linkend="sql-notify">.
</para>
@ -1417,9 +1417,9 @@ dblink_get_result(text connname [, bool fail_on_error]) returns setof record
<title>Description</title>
<para>
<function>dblink_get_result</> collects the results of an
asynchronous query previously sent with <function>dblink_send_query</>.
If the query is not already completed, <function>dblink_get_result</>
<function>dblink_get_result</function> collects the results of an
asynchronous query previously sent with <function>dblink_send_query</function>.
If the query is not already completed, <function>dblink_get_result</function>
will wait until it is.
</para>
</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),
the function returns the row(s) produced by the query. To use this
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>
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 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.
</para>
</refsect1>
@ -1474,22 +1474,22 @@ dblink_get_result(text connname [, bool fail_on_error]) returns setof record
<title>Notes</title>
<para>
This function <emphasis>must</> be called if
<function>dblink_send_query</> returned 1.
This function <emphasis>must</emphasis> be called if
<function>dblink_send_query</function> returned 1.
It must be called once for each query
sent, and one additional time to obtain an empty set result,
before the connection can be used again.
</para>
<para>
When using <function>dblink_send_query</> and
<function>dblink_get_result</>, <application>dblink</> fetches the entire
When using <function>dblink_send_query</function> and
<function>dblink_get_result</function>, <application>dblink</application> fetches the entire
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
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
<function>dblink()</>, which avoids memory bloat by spooling large result
<function>dblink()</function>, which avoids memory bloat by spooling large result
sets to disk.
</para>
</refsect1>
@ -1581,13 +1581,13 @@ dblink_cancel_query(text connname) returns text
<title>Description</title>
<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
certain to succeed (since, for example, the remote query might
already have finished). A cancel request simply improves the
odds that the query will fail soon. You must still complete the
normal query protocol, for example by calling
<function>dblink_get_result</>.
<function>dblink_get_result</function>.
</para>
</refsect1>
@ -1610,7 +1610,7 @@ dblink_cancel_query(text connname) returns text
<title>Return Value</title>
<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.
</para>
</refsect1>
@ -1651,7 +1651,7 @@ dblink_get_pkey(text relname) returns setof dblink_pkey_results
<title>Description</title>
<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
in generating queries to be sent to remote databases.
</para>
@ -1665,10 +1665,10 @@ dblink_get_pkey(text relname) returns setof dblink_pkey_results
<term><parameter>relname</parameter></term>
<listitem>
<para>
Name of a local relation, for example <literal>foo</> or
<literal>myschema.mytab</>. Include double quotes if the
Name of a local relation, for example <literal>foo</literal> or
<literal>myschema.mytab</literal>. Include double quotes if the
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.
</para>
</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);
</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
within the table's columns.
</para>
@ -1748,10 +1748,10 @@ dblink_build_sql_insert(text relname,
<title>Description</title>
<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
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.
(To make an exact copy of the row, just specify the same values for
the last two arguments.)
@ -1766,10 +1766,10 @@ dblink_build_sql_insert(text relname,
<term><parameter>relname</parameter></term>
<listitem>
<para>
Name of a local relation, for example <literal>foo</> or
<literal>myschema.mytab</>. Include double quotes if the
Name of a local relation, for example <literal>foo</literal> or
<literal>myschema.mytab</literal>. Include double quotes if the
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.
</para>
</listitem>
@ -1780,7 +1780,7 @@ dblink_build_sql_insert(text relname,
<listitem>
<para>
Attribute numbers (1-based) of the primary key fields,
for example <literal>1 2</>.
for example <literal>1 2</literal>.
</para>
</listitem>
</varlistentry>
@ -1811,7 +1811,7 @@ dblink_build_sql_insert(text relname,
<listitem>
<para>
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>
</listitem>
</varlistentry>
@ -1828,10 +1828,10 @@ dblink_build_sql_insert(text relname,
<title>Notes</title>
<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
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
column(s) to the left of the indicated column have been dropped during
the lifetime of the table.
@ -1881,9 +1881,9 @@ dblink_build_sql_delete(text relname,
<title>Description</title>
<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
<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.
</para>
</refsect1>
@ -1896,10 +1896,10 @@ dblink_build_sql_delete(text relname,
<term><parameter>relname</parameter></term>
<listitem>
<para>
Name of a local relation, for example <literal>foo</> or
<literal>myschema.mytab</>. Include double quotes if the
Name of a local relation, for example <literal>foo</literal> or
<literal>myschema.mytab</literal>. Include double quotes if the
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.
</para>
</listitem>
@ -1910,7 +1910,7 @@ dblink_build_sql_delete(text relname,
<listitem>
<para>
Attribute numbers (1-based) of the primary key fields,
for example <literal>1 2</>.
for example <literal>1 2</literal>.
</para>
</listitem>
</varlistentry>
@ -1929,7 +1929,7 @@ dblink_build_sql_delete(text relname,
<listitem>
<para>
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>
</listitem>
</varlistentry>
@ -1946,10 +1946,10 @@ dblink_build_sql_delete(text relname,
<title>Notes</title>
<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
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
column(s) to the left of the indicated column have been dropped during
the lifetime of the table.
@ -2000,15 +2000,15 @@ dblink_build_sql_update(text relname,
<title>Description</title>
<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
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.
(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
<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.
</para>
</refsect1>
@ -2021,10 +2021,10 @@ dblink_build_sql_update(text relname,
<term><parameter>relname</parameter></term>
<listitem>
<para>
Name of a local relation, for example <literal>foo</> or
<literal>myschema.mytab</>. Include double quotes if the
Name of a local relation, for example <literal>foo</literal> or
<literal>myschema.mytab</literal>. Include double quotes if the
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.
</para>
</listitem>
@ -2035,7 +2035,7 @@ dblink_build_sql_update(text relname,
<listitem>
<para>
Attribute numbers (1-based) of the primary key fields,
for example <literal>1 2</>.
for example <literal>1 2</literal>.
</para>
</listitem>
</varlistentry>
@ -2066,7 +2066,7 @@ dblink_build_sql_update(text relname,
<listitem>
<para>
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>
</listitem>
</varlistentry>
@ -2083,10 +2083,10 @@ dblink_build_sql_update(text relname,
<title>Notes</title>
<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
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
column(s) to the left of the indicated column have been dropped during
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
file that can be dynamically loaded by the server. To be precise, a
<firstterm>shared library</firstterm> needs to be
created.<indexterm><primary>shared library</></indexterm>
created.<indexterm><primary>shared library</primary></indexterm>
</para>
@ -30,7 +30,7 @@
executables: first the source files are compiled into object files,
then the object files are linked together. The object files need to
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
in memory when they are loaded by the executable. (Object files
intended for executables are usually not compiled that way.) The
@ -57,8 +57,8 @@
<variablelist>
<varlistentry>
<term>
<systemitem class="osname">FreeBSD</>
<indexterm><primary>FreeBSD</><secondary>shared library</></>
<systemitem class="osname">FreeBSD</systemitem>
<indexterm><primary>FreeBSD</primary><secondary>shared library</secondary></indexterm>
</term>
<listitem>
<para>
@ -70,15 +70,15 @@ gcc -fPIC -c foo.c
gcc -shared -o foo.so foo.o
</programlisting>
This is applicable as of version 3.0 of
<systemitem class="osname">FreeBSD</>.
<systemitem class="osname">FreeBSD</systemitem>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<systemitem class="osname">HP-UX</>
<indexterm><primary>HP-UX</><secondary>shared library</></>
<systemitem class="osname">HP-UX</systemitem>
<indexterm><primary>HP-UX</primary><secondary>shared library</secondary></indexterm>
</term>
<listitem>
<para>
@ -97,7 +97,7 @@ gcc -fPIC -c foo.c
<programlisting>
ld -b -o foo.sl foo.o
</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
systems.
</para>
@ -106,8 +106,8 @@ ld -b -o foo.sl foo.o
<varlistentry>
<term>
<systemitem class="osname">Linux</>
<indexterm><primary>Linux</><secondary>shared library</></>
<systemitem class="osname">Linux</systemitem>
<indexterm><primary>Linux</primary><secondary>shared library</secondary></indexterm>
</term>
<listitem>
<para>
@ -125,8 +125,8 @@ cc -shared -o foo.so foo.o
<varlistentry>
<term>
<systemitem class="osname">macOS</>
<indexterm><primary>macOS</><secondary>shared library</></>
<systemitem class="osname">macOS</systemitem>
<indexterm><primary>macOS</primary><secondary>shared library</secondary></indexterm>
</term>
<listitem>
<para>
@ -141,8 +141,8 @@ cc -bundle -flat_namespace -undefined suppress -o foo.so foo.o
<varlistentry>
<term>
<systemitem class="osname">NetBSD</>
<indexterm><primary>NetBSD</><secondary>shared library</></>
<systemitem class="osname">NetBSD</systemitem>
<indexterm><primary>NetBSD</primary><secondary>shared library</secondary></indexterm>
</term>
<listitem>
<para>
@ -161,8 +161,8 @@ gcc -shared -o foo.so foo.o
<varlistentry>
<term>
<systemitem class="osname">OpenBSD</>
<indexterm><primary>OpenBSD</><secondary>shared library</></>
<systemitem class="osname">OpenBSD</systemitem>
<indexterm><primary>OpenBSD</primary><secondary>shared library</secondary></indexterm>
</term>
<listitem>
<para>
@ -179,17 +179,17 @@ ld -Bshareable -o foo.so foo.o
<varlistentry>
<term>
<systemitem class="osname">Solaris</>
<indexterm><primary>Solaris</><secondary>shared library</></>
<systemitem class="osname">Solaris</systemitem>
<indexterm><primary>Solaris</primary><secondary>shared library</secondary></indexterm>
</term>
<listitem>
<para>
The compiler flag to create <acronym>PIC</acronym> is
<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
<option>-G</option> with either compiler or alternatively
<option>-shared</option> with <application>GCC</>.
<option>-shared</option> with <application>GCC</application>.
<programlisting>
cc -KPIC -c foo.c
cc -G -o foo.so foo.o

View File

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

View File

@ -8,7 +8,7 @@
</indexterm>
<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
replaces words with groups of their synonyms, and so makes it possible to
search for a word using any of its synonyms.
@ -18,41 +18,41 @@
<title>Configuration</title>
<para>
A <literal>dict_xsyn</> dictionary accepts the following options:
A <literal>dict_xsyn</literal> dictionary accepts the following options:
</para>
<itemizedlist>
<listitem>
<para>
<literal>matchorig</> controls whether the original word is accepted by
the dictionary. Default is <literal>true</>.
<literal>matchorig</literal> controls whether the original word is accepted by
the dictionary. Default is <literal>true</literal>.
</para>
</listitem>
<listitem>
<para>
<literal>matchsynonyms</> controls whether the synonyms are
accepted by the dictionary. Default is <literal>false</>.
<literal>matchsynonyms</literal> controls whether the synonyms are
accepted by the dictionary. Default is <literal>false</literal>.
</para>
</listitem>
<listitem>
<para>
<literal>keeporig</> controls whether the original word is included in
the dictionary's output. Default is <literal>true</>.
<literal>keeporig</literal> controls whether the original word is included in
the dictionary's output. Default is <literal>true</literal>.
</para>
</listitem>
<listitem>
<para>
<literal>keepsynonyms</> controls whether the synonyms are included in
the dictionary's output. Default is <literal>true</>.
<literal>keepsynonyms</literal> controls whether the synonyms are included in
the dictionary's output. Default is <literal>true</literal>.
</para>
</listitem>
<listitem>
<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
<filename>$SHAREDIR/tsearch_data/</> (where <literal>$SHAREDIR</> means
the <productname>PostgreSQL</> installation's shared-data directory).
Its name must end in <literal>.rules</> (which is not to be included in
the <literal>rules</> parameter).
<filename>$SHAREDIR/tsearch_data/</filename> (where <literal>$SHAREDIR</literal> means
the <productname>PostgreSQL</productname> installation's shared-data directory).
Its name must end in <literal>.rules</literal> (which is not to be included in
the <literal>rules</literal> parameter).
</para>
</listitem>
</itemizedlist>
@ -71,15 +71,15 @@ word syn1 syn2 syn3
</listitem>
<listitem>
<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.
</para>
</listitem>
</itemizedlist>
<para>
Look at <filename>xsyn_sample.rules</>, which is installed in
<filename>$SHAREDIR/tsearch_data/</>, for an example.
Look at <filename>xsyn_sample.rules</filename>, which is installed in
<filename>$SHAREDIR/tsearch_data/</filename>, for an example.
</para>
</sect2>
@ -87,8 +87,8 @@ word syn1 syn2 syn3
<title>Usage</title>
<para>
Installing the <literal>dict_xsyn</> extension creates a text search
template <literal>xsyn_template</> and a dictionary <literal>xsyn</>
Installing the <literal>dict_xsyn</literal> extension creates a text search
template <literal>xsyn_template</literal> and a dictionary <literal>xsyn</literal>
based on it, with default parameters. You can alter the
parameters, for example

View File

@ -5,7 +5,7 @@
<para>
This chapter discusses how to monitor the disk usage of a
<productname>PostgreSQL</> database system.
<productname>PostgreSQL</productname> database system.
</para>
<sect1 id="disk-usage">
@ -18,10 +18,10 @@
<para>
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,
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
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
separate disk file &mdash; possibly more than one file, if the file would
exceed one gigabyte. Naming conventions for these files are described
@ -39,7 +39,7 @@
</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:
<programlisting>
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
(1 row)
</programlisting>
Each page is typically 8 kilobytes. (Remember, <structfield>relpages</>
is only updated by <command>VACUUM</>, <command>ANALYZE</>, and
a few DDL commands such as <command>CREATE INDEX</>.) The file path name
Each page is typically 8 kilobytes. (Remember, <structfield>relpages</structfield>
is only updated by <command>VACUUM</command>, <command>ANALYZE</command>, and
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.
</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:
<programlisting>
SELECT relname, relpages

View File

@ -285,42 +285,42 @@ DELETE FROM products;
<para>
Sometimes it is useful to obtain data from modified rows while they are
being manipulated. The <command>INSERT</>, <command>UPDATE</>,
and <command>DELETE</> commands all have an
optional <literal>RETURNING</> clause that supports this. Use
of <literal>RETURNING</> avoids performing an extra database query to
being manipulated. The <command>INSERT</command>, <command>UPDATE</command>,
and <command>DELETE</command> commands all have an
optional <literal>RETURNING</literal> clause that supports this. Use
of <literal>RETURNING</literal> avoids performing an extra database query to
collect the data, and is especially valuable when it would otherwise be
difficult to identify the modified rows reliably.
</para>
<para>
The allowed contents of a <literal>RETURNING</> clause are the same as
a <command>SELECT</> command's output list
The allowed contents of a <literal>RETURNING</literal> clause are the same as
a <command>SELECT</command> command's output list
(see <xref linkend="queries-select-lists">). It can contain column
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.
</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,
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,
when using a <link linkend="datatype-serial"><type>serial</></link>
column to provide unique identifiers, <literal>RETURNING</> can return
when using a <link linkend="datatype-serial"><type>serial</type></link>
column to provide unique identifiers, <literal>RETURNING</literal> can return
the ID assigned to a new row:
<programlisting>
CREATE TABLE users (firstname text, lastname text, id serial primary key);
INSERT INTO users (firstname, lastname) VALUES ('Joe', 'Cool') RETURNING id;
</programlisting>
The <literal>RETURNING</> clause is also very useful
with <literal>INSERT ... SELECT</>.
The <literal>RETURNING</literal> clause is also very useful
with <literal>INSERT ... SELECT</literal>.
</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:
<programlisting>
UPDATE products SET price = price * 1.10
@ -330,7 +330,7 @@ UPDATE products SET price = price * 1.10
</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:
<programlisting>
DELETE FROM products
@ -341,9 +341,9 @@ DELETE FROM products
<para>
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
common use-case for <literal>RETURNING</>.
common use-case for <literal>RETURNING</literal>.
</para>
</sect1>

View File

@ -449,7 +449,7 @@ checking for fop... fop
<para>
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:
<screen>
<prompt>doc/src/sgml$ </prompt><userinput>make STYLE=website html</userinput>

View File

@ -8,18 +8,18 @@
</indexterm>
<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
described first depends on the <filename>cube</> module (which
<emphasis>must</> be installed before <filename>earthdistance</> can be
installed). The second one is based on the built-in <type>point</> data type,
described first depends on the <filename>cube</filename> module (which
<emphasis>must</emphasis> be installed before <filename>earthdistance</filename> can be
installed). The second one is based on the built-in <type>point</type> data type,
using longitude and latitude for the coordinates.
</para>
<para>
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
<application><ulink url="http://postgis.net/">PostGIS</ulink></>
<application><ulink url="http://postgis.net/">PostGIS</ulink></application>
project.)
</para>
@ -29,13 +29,13 @@
<para>
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
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
is reasonably close to the actual surface of the Earth.
</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
change the module to use some other units, or to use a different value of
the radius that you feel is more appropriate.
@ -43,8 +43,8 @@
<para>
This package has applications to astronomical databases as well.
Astronomers will probably want to change <function>earth()</> to return a
radius of <literal>180/pi()</> so that distances are in degrees.
Astronomers will probably want to change <function>earth()</function> to return a
radius of <literal>180/pi()</literal> so that distances are in degrees.
</para>
<para>
@ -123,11 +123,11 @@
<entry><function>earth_box(earth, float8)</function><indexterm><primary>earth_box</primary></indexterm></entry>
<entry><type>cube</type></entry>
<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.
Some points in this box are further than the specified great circle
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>
</row>
</tbody>
@ -141,7 +141,7 @@
<para>
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 latitude in degrees. Points are taken as (longitude, latitude)
and not vice versa because longitude is closer to the intuitive idea of
@ -165,7 +165,7 @@
</thead>
<tbody>
<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>Gives the distance in statute miles between
two points on the Earth's surface.
@ -176,15 +176,15 @@
</table>
<para>
Note that unlike the <type>cube</>-based part of the module, units
are hardwired here: changing the <function>earth()</> function will
Note that unlike the <type>cube</type>-based part of the module, units
are hardwired here: changing the <function>earth()</function> function will
not affect the results of this operator.
</para>
<para>
One disadvantage of the longitude/latitude representation is that
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.
</para>

File diff suppressed because it is too large Load Diff

View File

@ -11,13 +11,13 @@
<para>
All messages emitted by the <productname>PostgreSQL</productname>
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
test the error code, rather than looking at the textual error
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
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
conditions not defined by the standard have been invented or
borrowed from other databases.
@ -36,16 +36,16 @@
<productname>PostgreSQL</productname> &version;. (Some are not actually
used at present, but are defined by the SQL standard.)
The error classes are also shown. For each error class there is a
<quote>standard</> error code having the last three characters
<literal>000</>. This code is used only for error conditions that fall
<quote>standard</quote> error code having the last three characters
<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.
</para>
<para>
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
<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.)
</para>
@ -53,10 +53,10 @@
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;
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
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
violation), but this is likely to be expanded in future.
</para>

View File

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

View File

@ -116,7 +116,7 @@
<para>
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
correspond to what are often known as abstract data types.
<productname>PostgreSQL</productname> can only operate on such
@ -136,11 +136,11 @@
Composite types, or row types, are created whenever the user
creates a table. It is also possible to use <xref
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
associated field names. A value of a composite type is a row or
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.
</para>
</sect2>
@ -156,7 +156,7 @@
</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">.
Their creation and use is not discussed in this chapter.
</para>
@ -166,7 +166,7 @@
<title>Pseudo-Types</title>
<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
composite types, but they can be used to declare the argument and
result types of functions. This provides a mechanism within the
@ -198,12 +198,12 @@
</indexterm>
<para>
Five pseudo-types of special interest are <type>anyelement</>,
<type>anyarray</>, <type>anynonarray</>, <type>anyenum</>,
and <type>anyrange</>,
which are collectively called <firstterm>polymorphic types</>.
Five pseudo-types of special interest are <type>anyelement</type>,
<type>anyarray</type>, <type>anynonarray</type>, <type>anyenum</type>,
and <type>anyrange</type>,
which are collectively called <firstterm>polymorphic types</firstterm>.
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)
being determined by the data types actually passed to it in a particular
call.
@ -228,10 +228,10 @@
and others declared <type>anyelement</type>, the actual range type in
the <type>anyrange</type> positions must be a range whose subtype is
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
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
be an enum type.
</para>
@ -240,7 +240,7 @@
Thus, when more than one argument position is declared with a polymorphic
type, the net effect is that only certain combinations of actual argument
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.
</para>
@ -251,19 +251,19 @@
result type for that call. For example, if there were not already
an array subscripting mechanism, one could define a function that
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
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.
</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
<type>anyelement</type>, just with an additional constraint. For
example, declaring a function as <literal>f(anyelement, anyenum)</>
is equivalent to declaring it as <literal>f(anyenum, anyenum)</>:
example, declaring a function as <literal>f(anyelement, anyenum)</literal>
is equivalent to declaring it as <literal>f(anyenum, anyenum)</literal>:
both actual arguments have to be the same enum type.
</para>
@ -271,10 +271,10 @@
A variadic function (one taking a variable number of arguments, as in
<xref linkend="xfunc-sql-variadic-functions">) can be
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
the same as if you had written the appropriate number of
<type>anynonarray</> parameters.
<type>anynonarray</type> parameters.
</para>
</sect2>
</sect1>
@ -294,15 +294,15 @@
</indexterm>
<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
functions, new operators, and probably new index operator classes.
It is helpful to collect all these objects into a single package
to simplify database management. <productname>PostgreSQL</> calls
such a package an <firstterm>extension</>. To define an extension,
you need at least a <firstterm>script file</> that contains the
<acronym>SQL</> commands to create the extension's objects, and a
<firstterm>control file</> that specifies a few basic properties
to simplify database management. <productname>PostgreSQL</productname> calls
such a package an <firstterm>extension</firstterm>. To define an extension,
you need at least a <firstterm>script file</firstterm> that contains the
<acronym>SQL</acronym> commands to create the extension's objects, and a
<firstterm>control file</firstterm> that specifies a few basic properties
of the extension itself. If the extension includes C code, there
will typically also be a shared library file into which the C code
has been built. Once you have these files, a simple
@ -312,14 +312,14 @@
<para>
The main advantage of using an extension, rather than just running the
<acronym>SQL</> script to load a bunch of <quote>loose</> objects
into your database, is that <productname>PostgreSQL</> will then
<acronym>SQL</acronym> script to load a bunch of <quote>loose</quote> objects
into your database, is that <productname>PostgreSQL</productname> will then
understand that the objects of the extension go together. You can
drop all the objects with a single <xref linkend="sql-dropextension">
command (no need to maintain a separate <quote>uninstall</> script).
Even more useful, <application>pg_dump</> knows that it should not
command (no need to maintain a separate <quote>uninstall</quote> script).
Even more useful, <application>pg_dump</application> knows that it should not
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
that might contain more or different objects than the old version.
Note however that you must have the extension's control, script, and
@ -327,12 +327,12 @@
</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.
Also, while you can change the definition of an extension member object
(for example, via <command>CREATE OR REPLACE FUNCTION</command> for a
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.
(But there are special provisions for tables containing configuration
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)
will be stored in the
<link linkend="catalog-pg-init-privs"><structname>pg_init_privs</structname></link>
system catalog. When <application>pg_dump</> is used, the
<command>CREATE EXTENSION</> command will be included in the dump, followed
system catalog. When <application>pg_dump</application> is used, the
<command>CREATE EXTENSION</command> command will be included in the dump, followed
by the set of <command>GRANT</command> and <command>REVOKE</command>
statements necessary to set the privileges on the objects to what they were
at the time the dump was taken.
</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>
statements. These are expected to be set after the extension has been
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>
@ -366,8 +366,8 @@
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
and changes the body of another function compared to 1.0, the extension
author can provide an <firstterm>update script</> that makes just those
two changes. The <command>ALTER EXTENSION UPDATE</> command can then
author can provide an <firstterm>update script</firstterm> that makes just those
two changes. The <command>ALTER EXTENSION UPDATE</command> command can then
be used to apply these changes and track which version of the extension
is actually installed in a given database.
</para>
@ -384,7 +384,7 @@
considered members of the extension.
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
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
types. It may or may not be appropriate for an extension to own the
schema(s) its member objects are within.
@ -409,23 +409,23 @@
<para>
The <xref linkend="sql-createextension"> command relies on a control
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
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
<literal><replaceable>extension</>--<replaceable>version</>.sql</literal>
(for example, <literal>foo--1.0.sql</> for version <literal>1.0</> of
extension <literal>foo</>). By default, the script file(s) are also
<literal><replaceable>extension</replaceable>--<replaceable>version</replaceable>.sql</literal>
(for example, <literal>foo--1.0.sql</literal> for version <literal>1.0</literal> of
extension <literal>foo</literal>). By default, the script file(s) are also
placed in the <literal>SHAREDIR/extension</literal> directory; but the
control file can specify a different directory for the script file(s).
</para>
<para>
The file format for an extension control file is the same as for the
<filename>postgresql.conf</> file, namely a list of
<replaceable>parameter_name</> <literal>=</> <replaceable>value</>
<filename>postgresql.conf</filename> file, namely a list of
<replaceable>parameter_name</replaceable> <literal>=</literal> <replaceable>value</replaceable>
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.
</para>
@ -438,11 +438,11 @@
<term><varname>directory</varname> (<type>string</type>)</term>
<listitem>
<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
the installation's <literal>SHAREDIR</literal> directory. The
default behavior is equivalent to specifying
<literal>directory = 'extension'</>.
<literal>directory = 'extension'</literal>.
</para>
</listitem>
</varlistentry>
@ -452,9 +452,9 @@
<listitem>
<para>
The default version of the extension (the one that will be installed
if no version is specified in <command>CREATE EXTENSION</>). Although
this can be omitted, that will result in <command>CREATE EXTENSION</>
failing if no <literal>VERSION</> option appears, so you generally
if no version is specified in <command>CREATE EXTENSION</command>). Although
this can be omitted, that will result in <command>CREATE EXTENSION</command>
failing if no <literal>VERSION</literal> option appears, so you generally
don't want to do that.
</para>
</listitem>
@ -489,11 +489,11 @@
<listitem>
<para>
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
<literal>$libdir/<replaceable>shared_library_name</></literal> and
then <literal>MODULE_PATHNAME</> is used in <command>CREATE
FUNCTION</> commands for C-language functions, so that the script
<literal>$libdir/<replaceable>shared_library_name</replaceable></literal> and
then <literal>MODULE_PATHNAME</literal> is used in <command>CREATE
FUNCTION</command> commands for C-language functions, so that the script
files do not need to hard-wire the name of the shared library.
</para>
</listitem>
@ -514,9 +514,9 @@
<term><varname>superuser</varname> (<type>boolean</type>)</term>
<listitem>
<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
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
are required.
</para>
@ -527,9 +527,9 @@
<term><varname>relocatable</varname> (<type>boolean</type>)</term>
<listitem>
<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
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.
See <xref linkend="extend-extensions-relocation"> for more information.
</para>
@ -553,45 +553,45 @@
<para>
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
<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.
Secondary control files follow the same format as the primary control
file. Any parameters set in a secondary control file override the
primary control file when installing or updating to that version of
the extension. However, the parameters <varname>directory</> and
<varname>default_version</> cannot be set in a secondary control file.
the extension. However, the parameters <varname>directory</varname> and
<varname>default_version</varname> cannot be set in a secondary control file.
</para>
<para>
An extension's <acronym>SQL</> script files can contain any SQL commands,
except for transaction control commands (<command>BEGIN</>,
<command>COMMIT</>, etc) and commands that cannot be executed inside a
transaction block (such as <command>VACUUM</>). This is because the
An extension's <acronym>SQL</acronym> script files can contain any SQL commands,
except for transaction control commands (<command>BEGIN</command>,
<command>COMMIT</command>, etc) and commands that cannot be executed inside a
transaction block (such as <command>VACUUM</command>). This is because the
script files are implicitly executed within a transaction block.
</para>
<para>
An extension's <acronym>SQL</> script files can also contain lines
beginning with <literal>\echo</>, which will be ignored (treated as
An extension's <acronym>SQL</acronym> script files can also contain lines
beginning with <literal>\echo</literal>, which will be ignored (treated as
comments) by the extension mechanism. This provision is commonly used
to throw an error if the script file is fed to <application>psql</>
rather than being loaded via <command>CREATE EXTENSION</> (see example
to throw an error if the script file is fed to <application>psql</application>
rather than being loaded via <command>CREATE EXTENSION</command> (see example
script in <xref linkend="extend-extensions-example">).
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.
</para>
<para>
While the script files can contain any characters allowed by the specified
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
use non-ASCII characters in the extension's comment. Recommended
practice in that case is to not use the control file <varname>comment</>
parameter, but instead use <command>COMMENT ON EXTENSION</>
practice in that case is to not use the control file <varname>comment</varname>
parameter, but instead use <command>COMMENT ON EXTENSION</command>
within a script file to set the comment.
</para>
@ -611,14 +611,14 @@
<para>
A fully relocatable extension can be moved into another schema
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
the new schema. Normally, this is only possible if the extension
contains no internal assumptions about what schema any of its
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, 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.
</para>
</listitem>
@ -628,26 +628,26 @@
An extension might be relocatable during installation but not
afterwards. This is typically the case if the extension's script
file needs to reference the target schema explicitly, for example
in setting <literal>search_path</> properties for SQL functions.
For such an extension, set <literal>relocatable = false</> in its
control file, and use <literal>@extschema@</> to refer to the target
in setting <literal>search_path</literal> properties for SQL functions.
For such an extension, set <literal>relocatable = false</literal> in its
control file, and use <literal>@extschema@</literal> to refer to the target
schema in the script file. All occurrences of this string will be
replaced by the actual target schema's name before the script is
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>
</listitem>
<listitem>
<para>
If the extension does not support relocation at all, set
<literal>relocatable = false</> in its control file, and also set
<literal>schema</> to the name of the intended target schema. This
will prevent use of the <literal>SCHEMA</> option of <command>CREATE
EXTENSION</>, unless it specifies the same schema named in the control
<literal>relocatable = false</literal> in its control file, and also set
<literal>schema</literal> to the name of the intended target schema. This
will prevent use of the <literal>SCHEMA</literal> option of <command>CREATE
EXTENSION</command>, unless it specifies the same schema named in the control
file. This choice is typically necessary if the extension contains
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
of limited use since the schema name is determined by the control file.
</para>
@ -657,23 +657,23 @@
<para>
In all cases, the script file will be executed with
<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:
<programlisting>
SET LOCAL search_path TO @extschema@;
</programlisting>
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,
but that is generally undesirable. <varname>search_path</> is restored
to its previous setting upon completion of <command>CREATE EXTENSION</>.
schema. The script file can change <varname>search_path</varname> if it wishes,
but that is generally undesirable. <varname>search_path</varname> is restored
to its previous setting upon completion of <command>CREATE EXTENSION</command>.
</para>
<para>
The target schema is determined by the <varname>schema</> parameter in
the control file if that is given, otherwise by the <literal>SCHEMA</>
option of <command>CREATE EXTENSION</> if that is given, otherwise the
The target schema is determined by the <varname>schema</varname> parameter in
the control file if that is given, otherwise by the <literal>SCHEMA</literal>
option of <command>CREATE EXTENSION</command> if that is given, otherwise the
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
already exist, but in the other two cases it must already exist.
</para>
@ -681,7 +681,7 @@ SET LOCAL search_path TO @extschema@;
<para>
If any prerequisite extensions are listed in <varname>requires</varname>
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.
</para>
@ -690,7 +690,7 @@ SET LOCAL search_path TO @extschema@;
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
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.
</para>
</sect2>
@ -703,7 +703,7 @@ SET LOCAL search_path TO @extschema@;
might be added or changed by the user after installation of the
extension. Ordinarily, if a table is part of an extension, neither
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
included in dumps, or the extension will behave differently after a dump
and reload.
@ -716,9 +716,9 @@ SET LOCAL search_path TO @extschema@;
<para>
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
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
<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
<programlisting>
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', '');
</programlisting>
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.
</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
<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
a mixture of initial data and user-provided data in the table,
the second argument of <function>pg_extension_config_dump</> provides
a <literal>WHERE</> condition that selects the data to be dumped.
the second argument of <function>pg_extension_config_dump</function> provides
a <literal>WHERE</literal> condition that selects the data to be dumped.
For example, you might do
<programlisting>
CREATE TABLE my_config (key text, value text, standard_entry boolean);
SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entry');
</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.
</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.
</para>
@ -763,10 +763,10 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr
<para>
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
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>
@ -781,7 +781,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr
</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
relation is not enough for this purpose.
</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.
In addition, if you want users to be able to update their databases
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
<literal><replaceable>extension</>--<replaceable>oldversion</>--<replaceable>newversion</>.sql</literal>
(for example, <literal>foo--1.0--1.1.sql</> contains the commands to modify
version <literal>1.0</> of extension <literal>foo</> into version
<literal>1.1</>).
<literal><replaceable>extension</replaceable>--<replaceable>oldversion</replaceable>--<replaceable>newversion</replaceable>.sql</literal>
(for example, <literal>foo--1.0--1.1.sql</literal> contains the commands to modify
version <literal>1.0</literal> of extension <literal>foo</literal> into version
<literal>1.1</literal>).
</para>
<para>
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
environment that <command>CREATE EXTENSION</> provides for installation
scripts: in particular, <varname>search_path</> is set up in the same
environment that <command>CREATE EXTENSION</command> provides for installation
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
to the extension. Also, if the script chooses to drop extension member
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>
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
<productname>PostgreSQL</productname> (in 9.1), many people wrote
extension modules that simply created assorted unpackaged objects.
Given an existing database containing such objects, how can we convert
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
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
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
version but were not in the unpackaged release. <command>CREATE
EXTENSION</> supports this case with its <literal>FROM</> <replaceable
class="parameter">old_version</> option, which causes it to not run the
EXTENSION</command> supports this case with its <literal>FROM</literal> <replaceable
class="parameter">old_version</replaceable> option, which causes it to not run the
normal installation script for the target version, but instead the update
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
class="parameter">old_version</> is up to the extension author, though
<literal>unpackaged</> is a common convention. If you have multiple
class="parameter">old_version</replaceable> is up to the extension author, though
<literal>unpackaged</literal> is a common convention. If you have multiple
prior versions you need to be able to update into extension style, use
multiple dummy version names to identify them.
</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
<literal>foo--1.0--1.1.sql</> and <literal>foo--1.1--2.0.sql</> are
available, <command>ALTER EXTENSION</> will apply them in sequence if an
update to version <literal>2.0</> is requested when <literal>1.0</> is
<literal>foo--1.0--1.1.sql</literal> and <literal>foo--1.1--2.0.sql</literal> are
available, <command>ALTER EXTENSION</command> will apply them in sequence if an
update to version <literal>2.0</literal> is requested when <literal>1.0</literal> is
currently installed.
</para>
<para>
<productname>PostgreSQL</> doesn't assume anything about the properties
of version names: for example, it does not know whether <literal>1.1</>
follows <literal>1.0</>. It just matches up the available version names
<productname>PostgreSQL</productname> doesn't assume anything about the properties
of version names: for example, it does not know whether <literal>1.1</literal>
follows <literal>1.0</literal>. It just matches up the available version names
and follows the path that requires applying the fewest update scripts.
(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>
Sometimes it is useful to provide <quote>downgrade</> scripts, for
example <literal>foo--1.1--1.0.sql</> to allow reverting the changes
associated with version <literal>1.1</>. If you do that, be careful
Sometimes it is useful to provide <quote>downgrade</quote> scripts, for
example <literal>foo--1.1--1.0.sql</literal> to allow reverting the changes
associated with version <literal>1.1</literal>. If you do that, be careful
of the possibility that a downgrade script might unexpectedly
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.
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
@ -883,14 +883,14 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr
<para>
To check for unexpected update paths, use this command:
<programlisting>
SELECT * FROM pg_extension_update_paths('<replaceable>extension_name</>');
SELECT * FROM pg_extension_update_paths('<replaceable>extension_name</replaceable>');
</programlisting>
This shows each pair of distinct known version names for the specified
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
with <literal>--</> separators. You can use
<literal>regexp_split_to_array(path,'--')</> if you prefer an array
with <literal>--</literal> separators. You can use
<literal>regexp_split_to_array(path,'--')</literal> if you prefer an array
format.
</para>
</sect2>
@ -901,24 +901,24 @@ SELECT * FROM pg_extension_update_paths('<replaceable>extension_name</>');
<para>
An extension that has been around for awhile will probably exist in
several versions, for which the author will need to write update scripts.
For example, if you have released a <literal>foo</> extension in
versions <literal>1.0</>, <literal>1.1</>, and <literal>1.2</>, there
should be update scripts <filename>foo--1.0--1.1.sql</>
and <filename>foo--1.1--1.2.sql</>.
Before <productname>PostgreSQL</> 10, it was necessary to also create
new script files <filename>foo--1.1.sql</> and <filename>foo--1.2.sql</>
For example, if you have released a <literal>foo</literal> extension in
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</filename>
and <filename>foo--1.1--1.2.sql</filename>.
Before <productname>PostgreSQL</productname> 10, it was necessary to also create
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
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
EXTENSION</> can follow update chains automatically.
EXTENSION</command> can follow update chains automatically.
For example, if only the script
files <filename>foo--1.0.sql</>, <filename>foo--1.0--1.1.sql</>,
and <filename>foo--1.1--1.2.sql</> are available then a request to
install version <literal>1.2</> is honored by running those three
files <filename>foo--1.0.sql</filename>, <filename>foo--1.0--1.1.sql</filename>,
and <filename>foo--1.1--1.2.sql</filename> are available then a request to
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
installed <literal>1.0</> and then updated to <literal>1.2</>.
(As with <command>ALTER EXTENSION UPDATE</>, if multiple pathways are
installed <literal>1.0</literal> and then updated to <literal>1.2</literal>.
(As with <command>ALTER EXTENSION UPDATE</command>, if multiple pathways are
available then the shortest is preferred.) Arranging an extension's
script files in this style can reduce the amount of maintenance effort
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
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.
For example, if <filename>foo--1.0.control</> specifies <literal>requires
= 'bar'</> but <literal>foo</>'s other control files do not, the
extension's dependency on <literal>bar</> will be dropped when updating
from <literal>1.0</> to another version.
For example, if <filename>foo--1.0.control</filename> specifies <literal>requires
= 'bar'</literal> but <literal>foo</literal>'s other control files do not, the
extension's dependency on <literal>bar</literal> will be dropped when updating
from <literal>1.0</literal> to another version.
</para>
</sect2>
@ -940,14 +940,14 @@ SELECT * FROM pg_extension_update_paths('<replaceable>extension_name</>');
<title>Extension Example</title>
<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
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.
</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[
-- 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>
The control file <filename>pair.control</> looks like this:
The control file <filename>pair.control</filename> looks like this:
<programlisting>
# pair extension
@ -988,7 +988,7 @@ relocatable = true
<para>
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>
EXTENSION = pair
@ -1000,9 +1000,9 @@ include $(PGXS)
</programlisting>
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
directory as reported by <application>pg_config</>.
directory as reported by <application>pg_config</application>.
</para>
<para>
@ -1022,16 +1022,16 @@ include $(PGXS)
<para>
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
the <productname>PostgreSQL</> installation provides a build
the <productname>PostgreSQL</productname> installation provides a build
infrastructure for extensions, called <acronym>PGXS</acronym>, so
that simple extension modules can be built simply against an
already installed server. <acronym>PGXS</acronym> is mainly intended
for extensions that include C code, although it can be used for
pure-SQL extensions too. Note that <acronym>PGXS</acronym> is not
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
modules. For more complicated packages, you might need to write your
own build system.
@ -1115,7 +1115,7 @@ include $(PGXS)
<term><varname>MODULEDIR</varname></term>
<listitem>
<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
(if not set, default is <literal>extension</literal> if
<varname>EXTENSION</varname> is set,
@ -1198,7 +1198,7 @@ include $(PGXS)
<term><varname>REGRESS_OPTS</varname></term>
<listitem>
<para>
additional switches to pass to <application>pg_regress</>
additional switches to pass to <application>pg_regress</application>
</para>
</listitem>
</varlistentry>
@ -1252,10 +1252,10 @@ include $(PGXS)
<term><varname>PG_CONFIG</varname></term>
<listitem>
<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
(typically just <literal>pg_config</> to use the first one in your
<varname>PATH</>)
(typically just <literal>pg_config</literal> to use the first one in your
<varname>PATH</varname>)
</para>
</listitem>
</varlistentry>
@ -1270,7 +1270,7 @@ include $(PGXS)
compiled and installed for the
<productname>PostgreSQL</productname> installation that
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
<command>pg_config</command> program, either within the makefile
or on the <literal>make</literal> command line.
@ -1293,7 +1293,7 @@ make -f /path/to/extension/source/tree/Makefile install
<para>
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
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
<varname>VPATH</varname> like this:
<programlisting>
@ -1304,18 +1304,18 @@ make VPATH=/path/to/extension/source/tree install
</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
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.
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.
These files must have extension <literal>.sql</literal>, which must not be
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
subdirectory named <literal>expected/</literal>, with the same stem and
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
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

View File

@ -42,7 +42,7 @@
All other language interfaces are external projects and are distributed
separately. <xref linkend="language-interface-table"> includes a list of
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
its website and documentation.
</para>
@ -145,8 +145,8 @@
<para>
There are several administration tools available for
<productname>PostgreSQL</>. The most popular is
<application><ulink url="http://www.pgadmin.org/">pgAdmin III</ulink></>,
<productname>PostgreSQL</productname>. The most popular is
<application><ulink url="http://www.pgadmin.org/">pgAdmin III</ulink></application>,
and there are several commercially available ones as well.
</para>
</sect1>
@ -172,7 +172,7 @@
and maintained outside the core <productname>PostgreSQL</productname>
distribution. <xref linkend="pl-language-table"> lists some of these
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
and documentation.
</para>
@ -233,17 +233,17 @@
</indexterm>
<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
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
<xref linkend="contrib">. Other extensions are developed
independently, like <application><ulink
url="http://postgis.net/">PostGIS</ulink></>. Even
<productname>PostgreSQL</> replication solutions can be developed
url="http://postgis.net/">PostGIS</ulink></application>. Even
<productname>PostgreSQL</productname> replication solutions can be developed
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
from the core project.
</para>

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
</indexterm>
<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
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
@ -41,7 +41,7 @@
<listitem>
<para>
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
specified, but not both.
</para>
@ -54,7 +54,7 @@
<listitem>
<para>
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>
</listitem>
</varlistentry>
@ -65,7 +65,7 @@
<listitem>
<para>
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>
</listitem>
</varlistentry>
@ -76,7 +76,7 @@
<listitem>
<para>
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>
</listitem>
</varlistentry>
@ -87,7 +87,7 @@
<listitem>
<para>
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>
</listitem>
</varlistentry>
@ -98,7 +98,7 @@
<listitem>
<para>
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>
</listitem>
</varlistentry>
@ -109,7 +109,7 @@
<listitem>
<para>
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>
</listitem>
</varlistentry>
@ -120,7 +120,7 @@
<listitem>
<para>
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>
</listitem>
</varlistentry>
@ -128,10 +128,10 @@
</variablelist>
<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
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.
</para>
@ -150,7 +150,7 @@
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
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.
</para>
</listitem>
@ -162,11 +162,11 @@
<listitem>
<para>
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
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
<command>COPY</>'s <literal>FORCE_NULL</literal> option.
<command>COPY</command>'s <literal>FORCE_NULL</literal> option.
</para>
</listitem>
</varlistentry>
@ -174,14 +174,14 @@
</variablelist>
<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>file_fdw</>.
<literal>file_fdw</literal>.
</para>
<para>
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.
</para>
@ -193,7 +193,7 @@
</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
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.
@ -202,9 +202,9 @@
</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.
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.
</para>
@ -212,10 +212,10 @@
<title id="csvlog-fdw">Create a Foreign Table for PostgreSQL CSV Logs</title>
<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
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:
</para>
@ -233,7 +233,7 @@ CREATE SERVER pglog FOREIGN DATA WRAPPER file_fdw;
<para>
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:
<programlisting>

File diff suppressed because it is too large Load Diff

View File

@ -8,14 +8,14 @@
</indexterm>
<para>
The <filename>fuzzystrmatch</> module provides several
The <filename>fuzzystrmatch</filename> module provides several
functions to determine similarities and distance between strings.
</para>
<caution>
<para>
At present, the <function>soundex</>, <function>metaphone</>,
<function>dmetaphone</>, and <function>dmetaphone_alt</> functions do
At present, the <function>soundex</function>, <function>metaphone</function>,
<function>dmetaphone</function>, and <function>dmetaphone_alt</function> functions do
not work well with multibyte encodings (such as UTF-8).
</para>
</caution>
@ -31,7 +31,7 @@
</para>
<para>
The <filename>fuzzystrmatch</> module provides two functions
The <filename>fuzzystrmatch</filename> module provides two functions
for working with Soundex codes:
</para>
@ -49,12 +49,12 @@ difference(text, text) returns int
</synopsis>
<para>
The <function>soundex</> function converts a string to its Soundex code.
The <function>difference</> function converts two strings to their Soundex
The <function>soundex</function> function converts a string to its Soundex code.
The <function>difference</function> function converts two strings to their Soundex
codes and then reports the number of matching code positions. Since
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
function is misnamed &mdash; <function>similarity</> would have been
function is misnamed &mdash; <function>similarity</function> would have been
a better name.)
</para>
@ -115,10 +115,10 @@ levenshtein_less_equal(text source, text target, int max_d) returns int
<para>
<function>levenshtein_less_equal</function> is an accelerated version of the
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
distance; otherwise it returns some value greater than <literal>max_d</>.
If <literal>max_d</> is negative then the behavior is the same as
distance; otherwise it returns some value greater than <literal>max_d</literal>.
If <literal>max_d</literal> is negative then the behavior is the same as
<function>levenshtein</function>.
</para>
@ -198,9 +198,9 @@ test=# SELECT metaphone('GUMBO', 4);
<title>Double Metaphone</title>
<para>
The Double Metaphone system computes two <quote>sounds like</> strings
for a given input string &mdash; a <quote>primary</> and an
<quote>alternate</>. In most cases they are the same, but for non-English
The Double Metaphone system computes two <quote>sounds like</quote> strings
for a given input string &mdash; a <quote>primary</quote> and an
<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.
These functions compute the primary and alternate codes:
</para>

View File

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

View File

@ -13,8 +13,8 @@
<para>
The API for constructing generic WAL records is defined in
<filename>access/generic_xlog.h</> and implemented
in <filename>access/transam/generic_xlog.c</>.
<filename>access/generic_xlog.h</filename> and implemented
in <filename>access/transam/generic_xlog.c</filename>.
</para>
<para>
@ -24,24 +24,24 @@
<orderedlist>
<listitem>
<para>
<function>state = GenericXLogStart(relation)</> &mdash; start
<function>state = GenericXLogStart(relation)</function> &mdash; start
construction of a generic WAL record for the given relation.
</para>
</listitem>
<listitem>
<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
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 contents directly.) The third argument is a bit mask of flags
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.
Typically this flag would be set if the page is new or has been
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.
</para>
</listitem>
@ -54,7 +54,7 @@
<listitem>
<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.
</para>
</listitem>
@ -63,7 +63,7 @@
<para>
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.
</para>
@ -75,13 +75,13 @@
<listitem>
<para>
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
<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
appropriate times. Exclusive lock must be held on each target buffer
from before <function>GenericXLogRegisterBuffer()</> until after
<function>GenericXLogFinish()</>.
from before <function>GenericXLogRegisterBuffer()</function> until after
<function>GenericXLogFinish()</function>.
</para>
</listitem>
@ -97,7 +97,7 @@
<listitem>
<para>
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.
</para>
</listitem>
@ -106,26 +106,26 @@
<para>
Generic WAL assumes that the pages to be modified have standard
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>
</listitem>
<listitem>
<para>
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,
etc. between <function>GenericXLogStart()</> and
<function>GenericXLogFinish()</>. The only actual critical section is
present inside <function>GenericXLogFinish()</>. There is no need to
worry about calling <function>GenericXLogAbort()</> during an error
etc. between <function>GenericXLogStart()</function> and
<function>GenericXLogFinish()</function>. The only actual critical section is
present inside <function>GenericXLogFinish()</function>. There is no need to
worry about calling <function>GenericXLogAbort()</function> during an error
exit, either.
</para>
</listitem>
<listitem>
<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.
</para>
</listitem>
@ -148,7 +148,7 @@
<listitem>
<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
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

View File

@ -88,7 +88,7 @@
</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
problem. A <acronym>GA</acronym> uses stochastic processes, but the result is distinctly
non-random (better than random).
@ -222,7 +222,7 @@
are considered; and all the initially-determined relation scan plans
are available. The estimated cost is the cheapest of these
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
by combining genes of more-fit candidates &mdash; that is, by using
randomly-chosen portions of known low-cost join sequences to create
@ -235,20 +235,20 @@
<para>
This process is inherently nondeterministic, because of the randomized
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
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
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>
</sect2>
<sect2 id="geqo-future">
<title>Future Implementation Tasks for
<productname>PostgreSQL</> <acronym>GEQO</acronym></title>
<productname>PostgreSQL</productname> <acronym>GEQO</acronym></title>
<para>
Work is still needed to improve the genetic algorithm parameter

View File

@ -21,15 +21,15 @@
</para>
<para>
We use the word <firstterm>item</> to refer to a composite value that
is to be indexed, and the word <firstterm>key</> to refer to an element
We use the word <firstterm>item</firstterm> to refer to a composite value that
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,
not item values per se.
</para>
<para>
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
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
@ -66,7 +66,7 @@
<title>Built-in Operator Classes</title>
<para>
The core <productname>PostgreSQL</> distribution
The core <productname>PostgreSQL</productname> distribution
includes the <acronym>GIN</acronym> operator classes shown in
<xref linkend="gin-builtin-opclasses-table">.
(Some of the optional modules described in <xref linkend="contrib">
@ -85,38 +85,38 @@
</thead>
<tbody>
<row>
<entry><literal>array_ops</></entry>
<entry><type>anyarray</></entry>
<entry><literal>array_ops</literal></entry>
<entry><type>anyarray</type></entry>
<entry>
<literal>&amp;&amp;</>
<literal>&lt;@</>
<literal>=</>
<literal>@&gt;</>
<literal>&amp;&amp;</literal>
<literal>&lt;@</literal>
<literal>=</literal>
<literal>@&gt;</literal>
</entry>
</row>
<row>
<entry><literal>jsonb_ops</></entry>
<entry><type>jsonb</></entry>
<entry><literal>jsonb_ops</literal></entry>
<entry><type>jsonb</type></entry>
<entry>
<literal>?</>
<literal>?&amp;</>
<literal>?|</>
<literal>@&gt;</>
<literal>?</literal>
<literal>?&amp;</literal>
<literal>?|</literal>
<literal>@&gt;</literal>
</entry>
</row>
<row>
<entry><literal>jsonb_path_ops</></entry>
<entry><type>jsonb</></entry>
<entry><literal>jsonb_path_ops</literal></entry>
<entry><type>jsonb</type></entry>
<entry>
<literal>@&gt;</>
<literal>@&gt;</literal>
</entry>
</row>
<row>
<entry><literal>tsvector_ops</></entry>
<entry><type>tsvector</></entry>
<entry><literal>tsvector_ops</literal></entry>
<entry><type>tsvector</type></entry>
<entry>
<literal>@@</>
<literal>@@@</>
<literal>@@</literal>
<literal>@@@</literal>
</entry>
</row>
</tbody>
@ -124,8 +124,8 @@
</table>
<para>
Of the two operator classes for type <type>jsonb</>, <literal>jsonb_ops</>
is the default. <literal>jsonb_path_ops</> supports fewer operators but
Of the two operator classes for type <type>jsonb</type>, <literal>jsonb_ops</literal>
is the default. <literal>jsonb_path_ops</literal> supports fewer operators but
offers better performance for those operators.
See <xref linkend="json-indexing"> for details.
</para>
@ -157,15 +157,15 @@
<variablelist>
<varlistentry>
<term><function>Datum *extractValue(Datum itemValue, int32 *nkeys,
bool **nullFlags)</></term>
bool **nullFlags)</function></term>
<listitem>
<para>
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
<literal>*nkeys</> <type>bool</type> fields, store its address at
<literal>*nullFlags</>, and set these null flags as needed.
<literal>*nullFlags</> can be left <symbol>NULL</symbol> (its initial value)
<literal>*nkeys</literal> <type>bool</type> fields, store its address at
<literal>*nullFlags</literal>, and set these null flags as needed.
<literal>*nullFlags</literal> can be left <symbol>NULL</symbol> (its initial value)
if all keys are non-null.
The return value can be <symbol>NULL</symbol> if the item contains no keys.
</para>
@ -175,40 +175,40 @@
<varlistentry>
<term><function>Datum *extractQuery(Datum query, int32 *nkeys,
StrategyNumber n, bool **pmatch, Pointer **extra_data,
bool **nullFlags, int32 *searchMode)</></term>
bool **nullFlags, int32 *searchMode)</function></term>
<listitem>
<para>
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.
<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">).
Often, <function>extractQuery</> will need
to consult <literal>n</> to determine the data type of
<literal>query</> and the method it should use to extract key values.
The number of returned keys must be stored into <literal>*nkeys</>.
Often, <function>extractQuery</function> will need
to consult <literal>n</literal> to determine the data type of
<literal>query</literal> and the method it should use to extract key values.
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
<literal>*nkeys</> <type>bool</type> fields, store its address at
<literal>*nullFlags</>, and set these null flags as needed.
<literal>*nullFlags</> can be left <symbol>NULL</symbol> (its initial value)
<literal>*nkeys</literal> <type>bool</type> fields, store its address at
<literal>*nullFlags</literal>, and set these null flags as needed.
<literal>*nullFlags</literal> can be left <symbol>NULL</symbol> (its initial value)
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>
<literal>searchMode</> is an output argument that allows
<function>extractQuery</> to specify details about how the search
<literal>searchMode</literal> is an output argument that allows
<function>extractQuery</function> to specify details about how the search
will be done.
If <literal>*searchMode</> is set to
<literal>GIN_SEARCH_MODE_DEFAULT</> (which is the value it is
If <literal>*searchMode</literal> is set to
<literal>GIN_SEARCH_MODE_DEFAULT</literal> (which is the value it is
initialized to before call), only items that match at least one of
the returned keys are considered candidate matches.
If <literal>*searchMode</> is set to
<literal>GIN_SEARCH_MODE_INCLUDE_EMPTY</>, then in addition to items
If <literal>*searchMode</literal> is set to
<literal>GIN_SEARCH_MODE_INCLUDE_EMPTY</literal>, then in addition to items
containing at least one matching key, items that contain no keys at
all are considered candidate matches. (This mode is useful for
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
matches, whether they match any of the returned keys or not. (This
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
class.)
The symbols to use for setting this mode are defined in
<filename>access/gin.h</>.
<filename>access/gin.h</filename>.
</para>
<para>
<literal>pmatch</> is an output argument for use when partial match
is supported. To use it, <function>extractQuery</> must allocate
an array of <literal>*nkeys</> booleans and store its address at
<literal>*pmatch</>. Each element of the array should be set to TRUE
<literal>pmatch</literal> is an output argument for use when partial match
is supported. To use it, <function>extractQuery</function> must allocate
an array of <literal>*nkeys</literal> booleans and store its address at
<literal>*pmatch</literal>. Each element of the array should be set to TRUE
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,
so this argument can simply be ignored by operator classes that do
not support partial match.
</para>
<para>
<literal>extra_data</> is an output argument that allows
<function>extractQuery</> to pass additional data to the
<function>consistent</> and <function>comparePartial</> methods.
To use it, <function>extractQuery</> must allocate
an array of <literal>*nkeys</> pointers and store its address at
<literal>*extra_data</>, then store whatever it wants to into the
<literal>extra_data</literal> is an output argument that allows
<function>extractQuery</function> to pass additional data to the
<function>consistent</function> and <function>comparePartial</function> methods.
To use it, <function>extractQuery</function> must allocate
an array of <literal>*nkeys</literal> pointers and store its address at
<literal>*extra_data</literal>, then store whatever it wants to into the
individual pointers. The variable is initialized to <symbol>NULL</symbol> before
call, so this argument can simply be ignored by operator classes that
do not require extra data. If <literal>*extra_data</> is set, the
whole array is passed to the <function>consistent</> method, and
the appropriate element to the <function>comparePartial</> method.
do not require extra data. If <literal>*extra_data</literal> is set, the
whole array is passed to the <function>consistent</function> method, and
the appropriate element to the <function>comparePartial</function> method.
</para>
</listitem>
@ -251,10 +251,10 @@
</variablelist>
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</>
function, and a ternary <function>triConsistent</> function.
<function>triConsistent</> covers the functionality of both, so providing
<function>triConsistent</> alone is sufficient. However, if the boolean
matches the query. It comes in two flavors, a boolean <function>consistent</function>
function, and a ternary <function>triConsistent</function> function.
<function>triConsistent</function> covers the functionality of both, so providing
<function>triConsistent</function> alone is sufficient. However, if the boolean
variant is significantly cheaper to calculate, it can be advantageous to
provide both. If only the boolean variant is provided, some optimizations
that depend on refuting index items before fetching all the keys are
@ -264,48 +264,48 @@
<varlistentry>
<term><function>bool consistent(bool check[], StrategyNumber n, Datum query,
int32 nkeys, Pointer extra_data[], bool *recheck,
Datum queryKeys[], bool nullFlags[])</></term>
Datum queryKeys[], bool nullFlags[])</function></term>
<listitem>
<para>
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
to the indexed item's value, since <acronym>GIN</acronym> does not
store items explicitly. Rather, what is available is knowledge
about which key values extracted from the query appear in a given
indexed item. The <literal>check</> array has length
<literal>nkeys</>, which is the same as the number of keys previously
returned by <function>extractQuery</> for this <literal>query</> datum.
indexed item. The <literal>check</literal> array has length
<literal>nkeys</literal>, which is the same as the number of keys previously
returned by <function>extractQuery</function> for this <literal>query</literal> datum.
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
<function>extractQuery</> result array is present in the indexed item.
The original <literal>query</> datum is
passed in case the <function>consistent</> method needs to consult it,
and so are the <literal>queryKeys[]</> and <literal>nullFlags[]</>
arrays previously returned by <function>extractQuery</>.
<literal>extra_data</> is the extra-data array returned by
<function>extractQuery</>, or <symbol>NULL</symbol> if none.
<function>extractQuery</function> result array is present in the indexed item.
The original <literal>query</literal> datum is
passed in case the <function>consistent</function> method needs to consult it,
and so are the <literal>queryKeys[]</literal> and <literal>nullFlags[]</literal>
arrays previously returned by <function>extractQuery</function>.
<literal>extra_data</literal> is the extra-data array returned by
<function>extractQuery</function>, or <symbol>NULL</symbol> if none.
</para>
<para>
When <function>extractQuery</> returns a null key in
<literal>queryKeys[]</>, the corresponding <literal>check[]</> element
When <function>extractQuery</function> returns a null key in
<literal>queryKeys[]</literal>, the corresponding <literal>check[]</literal> element
is TRUE if the indexed item contains a null key; that is, the
semantics of <literal>check[]</> are like <literal>IS NOT DISTINCT
FROM</>. The <function>consistent</> function can examine the
corresponding <literal>nullFlags[]</> element if it needs to tell
semantics of <literal>check[]</literal> are like <literal>IS NOT DISTINCT
FROM</literal>. The <function>consistent</function> function can examine the
corresponding <literal>nullFlags[]</literal> element if it needs to tell
the difference between a regular value match and a null match.
</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
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
<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
<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
query operator directly against the originally indexed item.
</para>
@ -315,30 +315,30 @@
<varlistentry>
<term><function>GinTernaryValue triConsistent(GinTernaryValue check[], StrategyNumber n, Datum query,
int32 nkeys, Pointer extra_data[],
Datum queryKeys[], bool nullFlags[])</></term>
Datum queryKeys[], bool nullFlags[])</function></term>
<listitem>
<para>
<function>triConsistent</> is similar to <function>consistent</>,
but instead of booleans in the <literal>check</> vector, there are
<function>triConsistent</function> is similar to <function>consistent</function>,
but instead of booleans in the <literal>check</literal> vector, there are
three possible values for each
key: <literal>GIN_TRUE</>, <literal>GIN_FALSE</> and
<literal>GIN_MAYBE</>. <literal>GIN_FALSE</> and <literal>GIN_TRUE</>
key: <literal>GIN_TRUE</literal>, <literal>GIN_FALSE</literal> and
<literal>GIN_MAYBE</literal>. <literal>GIN_FALSE</literal> and <literal>GIN_TRUE</literal>
have the same meaning as regular boolean values, while
<literal>GIN_MAYBE</> means that the presence of that key is not known.
When <literal>GIN_MAYBE</> values are present, the function should only
return <literal>GIN_TRUE</> if the item certainly matches whether or
<literal>GIN_MAYBE</literal> means that the presence of that key is not known.
When <literal>GIN_MAYBE</literal> values are present, the function should only
return <literal>GIN_TRUE</literal> if the item certainly matches whether or
not the index item contains the corresponding query keys. Likewise, the
function must return <literal>GIN_FALSE</> only if the item certainly
does not match, whether or not it contains the <literal>GIN_MAYBE</>
keys. If the result depends on the <literal>GIN_MAYBE</> entries, i.e.,
function must return <literal>GIN_FALSE</literal> only if the item certainly
does not match, whether or not it contains the <literal>GIN_MAYBE</literal>
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 function must return <literal>GIN_MAYBE</>.
the function must return <literal>GIN_MAYBE</literal>.
</para>
<para>
When there are no <literal>GIN_MAYBE</> values in the <literal>check</>
vector, a <literal>GIN_MAYBE</> return value is the equivalent of
setting the <literal>recheck</> flag in the
boolean <function>consistent</> function.
When there are no <literal>GIN_MAYBE</literal> values in the <literal>check</literal>
vector, a <literal>GIN_MAYBE</literal> return value is the equivalent of
setting the <literal>recheck</literal> flag in the
boolean <function>consistent</function> function.
</para>
</listitem>
</varlistentry>
@ -352,7 +352,7 @@
<variablelist>
<varlistentry>
<term><function>int compare(Datum a, Datum b)</></term>
<term><function>int compare(Datum a, Datum b)</function></term>
<listitem>
<para>
Compares two keys (not indexed items!) and returns an integer less than
@ -364,13 +364,13 @@
</varlistentry>
</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
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
just one data type, as looking up the btree operator class costs a few
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.
</para>
@ -381,7 +381,7 @@
<variablelist>
<varlistentry>
<term><function>int comparePartial(Datum partial_key, Datum key, StrategyNumber n,
Pointer extra_data)</></term>
Pointer extra_data)</function></term>
<listitem>
<para>
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
means that the index key does match the query; greater than zero
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
semantics are needed to determine when to end the scan. Also,
<literal>extra_data</> is the corresponding element of the extra-data
array made by <function>extractQuery</>, or <symbol>NULL</symbol> if none.
<literal>extra_data</literal> is the corresponding element of the extra-data
array made by <function>extractQuery</function>, or <symbol>NULL</symbol> if none.
Null keys are never passed to this function.
</para>
</listitem>
@ -402,25 +402,25 @@
</para>
<para>
To support <quote>partial match</> queries, an operator class must
provide the <function>comparePartial</> method, and its
<function>extractQuery</> method must set the <literal>pmatch</>
To support <quote>partial match</quote> queries, an operator class must
provide the <function>comparePartial</function> method, and its
<function>extractQuery</function> method must set the <literal>pmatch</literal>
parameter when a partial-match query is encountered. See
<xref linkend="gin-partial-match"> for details.
</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
<function>extractValue</> 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
the <literal>query</> argument passed to <function>extractQuery</>,
<function>consistent</> and <function>triConsistent</> is whatever is the
<function>extractValue</function> are always of the operator class's input type, and
all key values must be of the class's <literal>STORAGE</literal> type. The type of
the <literal>query</literal> argument passed to <function>extractQuery</function>,
<function>consistent</function> and <function>triConsistent</function> is whatever is 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
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
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.
</para>
@ -434,8 +434,8 @@
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
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
list</>) when the list is small enough to fit into a single index tuple along
<quote>posting tree</quote>), or a simple list of heap pointers (a <quote>posting
list</quote>) when the list is small enough to fit into a single index tuple along
with the key value.
</para>
@ -443,7 +443,7 @@
As of <productname>PostgreSQL</productname> 9.1, null key values can be
included in the index. Also, placeholder nulls are included in the index
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.
</para>
@ -461,7 +461,7 @@
intrinsic nature of inverted indexes: inserting or updating one heap row
can cause many inserts into the index (one for each key extracted
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.
When the table is vacuumed or autoanalyzed, or when
<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
a large list of pending entries will slow searches significantly.
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.
Proper use of autovacuum can minimize both of these problems.
</para>
@ -497,15 +497,15 @@
<title>Partial Match Algorithm</title>
<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
matches fall within a reasonably narrow range of key values (within the
key sorting order determined by the <function>compare</> support method).
The <function>extractQuery</> method, instead of returning a key value
key sorting order determined by the <function>compare</function> support method).
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
the range to be searched, and sets the <literal>pmatch</> flag true.
The key range is then scanned using the <function>comparePartial</>
method. <function>comparePartial</> must return zero for a matching
the range to be searched, and sets the <literal>pmatch</literal> flag true.
The key range is then scanned using the <function>comparePartial</function>
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
to be searched, or greater than zero if the index key is past the range
that could match.
@ -542,7 +542,7 @@
<listitem>
<para>
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.
</para>
</listitem>
@ -553,18 +553,18 @@
<listitem>
<para>
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
<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
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.
However, enlarging the threshold of the cleanup operation means that
if a foreground cleanup does occur, it will take even longer.
</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 index to have its own cleanup threshold.
For example, it's possible to increase the threshold only for the GIN
@ -616,7 +616,7 @@
<para>
<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),
and <function>extractQuery</function> will not be called on a null query
value either (instead, the query is presumed to be unsatisfiable). Note
@ -629,36 +629,36 @@
<title>Examples</title>
<para>
The core <productname>PostgreSQL</> distribution
The core <productname>PostgreSQL</productname> distribution
includes the <acronym>GIN</acronym> operator classes previously shown in
<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:
<variablelist>
<varlistentry>
<term><filename>btree_gin</></term>
<term><filename>btree_gin</filename></term>
<listitem>
<para>B-tree equivalent functionality for several data types</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>hstore</></term>
<term><filename>hstore</filename></term>
<listitem>
<para>Module for storing (key, value) pairs</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>intarray</></term>
<term><filename>intarray</filename></term>
<listitem>
<para>Enhanced support for <type>int[]</type></para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>pg_trgm</></term>
<term><filename>pg_trgm</filename></term>
<listitem>
<para>Text similarity using trigram matching</para>
</listitem>

View File

@ -44,7 +44,7 @@
<title>Built-in Operator Classes</title>
<para>
The core <productname>PostgreSQL</> distribution
The core <productname>PostgreSQL</productname> distribution
includes the <acronym>GiST</acronym> operator classes shown in
<xref linkend="gist-builtin-opclasses-table">.
(Some of the optional modules described in <xref linkend="contrib">
@ -64,142 +64,142 @@
</thead>
<tbody>
<row>
<entry><literal>box_ops</></entry>
<entry><type>box</></entry>
<entry><literal>box_ops</literal></entry>
<entry><type>box</type></entry>
<entry>
<literal>&amp;&amp;</>
<literal>&amp;&gt;</>
<literal>&amp;&lt;</>
<literal>&amp;&lt;|</>
<literal>&gt;&gt;</>
<literal>&lt;&lt;</>
<literal>&lt;&lt;|</>
<literal>&lt;@</>
<literal>@&gt;</>
<literal>@</>
<literal>|&amp;&gt;</>
<literal>|&gt;&gt;</>
<literal>~</>
<literal>~=</>
<literal>&amp;&amp;</literal>
<literal>&amp;&gt;</literal>
<literal>&amp;&lt;</literal>
<literal>&amp;&lt;|</literal>
<literal>&gt;&gt;</literal>
<literal>&lt;&lt;</literal>
<literal>&lt;&lt;|</literal>
<literal>&lt;@</literal>
<literal>@&gt;</literal>
<literal>@</literal>
<literal>|&amp;&gt;</literal>
<literal>|&gt;&gt;</literal>
<literal>~</literal>
<literal>~=</literal>
</entry>
<entry>
</entry>
</row>
<row>
<entry><literal>circle_ops</></entry>
<entry><type>circle</></entry>
<entry><literal>circle_ops</literal></entry>
<entry><type>circle</type></entry>
<entry>
<literal>&amp;&amp;</>
<literal>&amp;&gt;</>
<literal>&amp;&lt;</>
<literal>&amp;&lt;|</>
<literal>&gt;&gt;</>
<literal>&lt;&lt;</>
<literal>&lt;&lt;|</>
<literal>&lt;@</>
<literal>@&gt;</>
<literal>@</>
<literal>|&amp;&gt;</>
<literal>|&gt;&gt;</>
<literal>~</>
<literal>~=</>
<literal>&amp;&amp;</literal>
<literal>&amp;&gt;</literal>
<literal>&amp;&lt;</literal>
<literal>&amp;&lt;|</literal>
<literal>&gt;&gt;</literal>
<literal>&lt;&lt;</literal>
<literal>&lt;&lt;|</literal>
<literal>&lt;@</literal>
<literal>@&gt;</literal>
<literal>@</literal>
<literal>|&amp;&gt;</literal>
<literal>|&gt;&gt;</literal>
<literal>~</literal>
<literal>~=</literal>
</entry>
<entry>
<literal>&lt;-&gt;</>
<literal>&lt;-&gt;</literal>
</entry>
</row>
<row>
<entry><literal>inet_ops</></entry>
<entry><type>inet</>, <type>cidr</></entry>
<entry><literal>inet_ops</literal></entry>
<entry><type>inet</type>, <type>cidr</type></entry>
<entry>
<literal>&amp;&amp;</>
<literal>&gt;&gt;</>
<literal>&gt;&gt;=</>
<literal>&gt;</>
<literal>&gt;=</>
<literal>&lt;&gt;</>
<literal>&lt;&lt;</>
<literal>&lt;&lt;=</>
<literal>&lt;</>
<literal>&lt;=</>
<literal>=</>
<literal>&amp;&amp;</literal>
<literal>&gt;&gt;</literal>
<literal>&gt;&gt;=</literal>
<literal>&gt;</literal>
<literal>&gt;=</literal>
<literal>&lt;&gt;</literal>
<literal>&lt;&lt;</literal>
<literal>&lt;&lt;=</literal>
<literal>&lt;</literal>
<literal>&lt;=</literal>
<literal>=</literal>
</entry>
<entry>
</entry>
</row>
<row>
<entry><literal>point_ops</></entry>
<entry><type>point</></entry>
<entry><literal>point_ops</literal></entry>
<entry><type>point</type></entry>
<entry>
<literal>&gt;&gt;</>
<literal>&gt;^</>
<literal>&lt;&lt;</>
<literal>&lt;@</>
<literal>&lt;@</>
<literal>&lt;@</>
<literal>&lt;^</>
<literal>~=</>
<literal>&gt;&gt;</literal>
<literal>&gt;^</literal>
<literal>&lt;&lt;</literal>
<literal>&lt;@</literal>
<literal>&lt;@</literal>
<literal>&lt;@</literal>
<literal>&lt;^</literal>
<literal>~=</literal>
</entry>
<entry>
<literal>&lt;-&gt;</>
<literal>&lt;-&gt;</literal>
</entry>
</row>
<row>
<entry><literal>poly_ops</></entry>
<entry><type>polygon</></entry>
<entry><literal>poly_ops</literal></entry>
<entry><type>polygon</type></entry>
<entry>
<literal>&amp;&amp;</>
<literal>&amp;&gt;</>
<literal>&amp;&lt;</>
<literal>&amp;&lt;|</>
<literal>&gt;&gt;</>
<literal>&lt;&lt;</>
<literal>&lt;&lt;|</>
<literal>&lt;@</>
<literal>@&gt;</>
<literal>@</>
<literal>|&amp;&gt;</>
<literal>|&gt;&gt;</>
<literal>~</>
<literal>~=</>
<literal>&amp;&amp;</literal>
<literal>&amp;&gt;</literal>
<literal>&amp;&lt;</literal>
<literal>&amp;&lt;|</literal>
<literal>&gt;&gt;</literal>
<literal>&lt;&lt;</literal>
<literal>&lt;&lt;|</literal>
<literal>&lt;@</literal>
<literal>@&gt;</literal>
<literal>@</literal>
<literal>|&amp;&gt;</literal>
<literal>|&gt;&gt;</literal>
<literal>~</literal>
<literal>~=</literal>
</entry>
<entry>
<literal>&lt;-&gt;</>
<literal>&lt;-&gt;</literal>
</entry>
</row>
<row>
<entry><literal>range_ops</></entry>
<entry><literal>range_ops</literal></entry>
<entry>any range type</entry>
<entry>
<literal>&amp;&amp;</>
<literal>&amp;&gt;</>
<literal>&amp;&lt;</>
<literal>&gt;&gt;</>
<literal>&lt;&lt;</>
<literal>&lt;@</>
<literal>-|-</>
<literal>=</>
<literal>@&gt;</>
<literal>@&gt;</>
<literal>&amp;&amp;</literal>
<literal>&amp;&gt;</literal>
<literal>&amp;&lt;</literal>
<literal>&gt;&gt;</literal>
<literal>&lt;&lt;</literal>
<literal>&lt;@</literal>
<literal>-|-</literal>
<literal>=</literal>
<literal>@&gt;</literal>
<literal>@&gt;</literal>
</entry>
<entry>
</entry>
</row>
<row>
<entry><literal>tsquery_ops</></entry>
<entry><type>tsquery</></entry>
<entry><literal>tsquery_ops</literal></entry>
<entry><type>tsquery</type></entry>
<entry>
<literal>&lt;@</>
<literal>@&gt;</>
<literal>&lt;@</literal>
<literal>@&gt;</literal>
</entry>
<entry>
</entry>
</row>
<row>
<entry><literal>tsvector_ops</></entry>
<entry><type>tsvector</></entry>
<entry><literal>tsvector_ops</literal></entry>
<entry><type>tsvector</type></entry>
<entry>
<literal>@@</>
<literal>@@</literal>
</entry>
<entry>
</entry>
@ -209,9 +209,9 @@
</table>
<para>
For historical reasons, the <literal>inet_ops</> operator class is
not the default class for types <type>inet</> and <type>cidr</>.
To use it, mention the class name in <command>CREATE INDEX</>,
For historical reasons, the <literal>inet_ops</literal> operator class is
not the default class for types <type>inet</type> and <type>cidr</type>.
To use it, mention the class name in <command>CREATE INDEX</command>,
for example
<programlisting>
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
<acronym>GiST</acronym> must provide, and four that are optional.
Correctness of the index is ensured
by proper implementation of the <function>same</>, <function>consistent</>
and <function>union</> methods, while efficiency (size and speed) of the
index will depend on the <function>penalty</> and <function>picksplit</>
by proper implementation of the <function>same</function>, <function>consistent</function>
and <function>union</function> methods, while efficiency (size and speed) of the
index will depend on the <function>penalty</function> and <function>picksplit</function>
methods.
Two optional methods are <function>compress</> and
<function>decompress</>, which allow an index to have internal tree data of
Two optional methods are <function>compress</function> and
<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
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,
see about <literal>varlena</> for variable sized data). If the tree's
internal data type exists at the SQL level, the <literal>STORAGE</> option
of the <command>CREATE OPERATOR CLASS</> command can be used.
The optional eighth method is <function>distance</>, which is needed
you still have to follow <productname>PostgreSQL</productname> data type rules here,
see about <literal>varlena</literal> for variable sized data). If the tree's
internal data type exists at the SQL level, the <literal>STORAGE</literal> option
of the <command>CREATE OPERATOR CLASS</command> command can be used.
The optional eighth method is <function>distance</function>, which is needed
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
<function>compress</> method is omitted.
<function>compress</function> method is omitted.
</para>
<variablelist>
<varlistentry>
<term><function>consistent</></term>
<term><function>consistent</function></term>
<listitem>
<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
<quote>consistent</> with the query; that is, could the predicate
<quote><replaceable>indexed_column</>
<replaceable>indexable_operator</> <literal>q</></quote> be true for
<quote>consistent</quote> with the query; that is, could the predicate
<quote><replaceable>indexed_column</replaceable>
<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
equivalent to testing the indexable condition, while for an internal
tree node this determines whether it is necessary to scan the subtree
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
true. If <literal>recheck</> = <literal>false</> then the index has
tested the predicate condition exactly, whereas if <literal>recheck</>
= <literal>true</> the row is only a candidate match. In that case the
true. If <literal>recheck</literal> = <literal>false</literal> then the index has
tested the predicate condition exactly, whereas if <literal>recheck</literal>
= <literal>true</literal> the row is only a candidate match. In that case 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
<acronym>GiST</acronym> to support both lossless and lossy index
structures.
</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>
CREATE OR REPLACE FUNCTION my_consistent(internal, data_type, smallint, oid, internal)
@ -356,23 +356,23 @@ my_consistent(PG_FUNCTION_ARGS)
}
</programlisting>
Here, <varname>key</> is an element in the index and <varname>query</>
the value being looked up in the index. The <literal>StrategyNumber</>
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</literal>
parameter indicates which operator of your operator class is being
applied &mdash; it matches one of the operator numbers in the
<command>CREATE OPERATOR CLASS</> command.
<command>CREATE OPERATOR CLASS</command> command.
</para>
<para>
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 different from the indexed data type appearing on the lefthand side.
(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
the <function>consistent</> function use the opclass's indexed data
type for the <varname>query</> argument, even though the actual type
the <function>consistent</function> function use the opclass's indexed data
type for the <varname>query</varname> argument, even though the actual type
might be something else depending on the operator.
</para>
@ -380,7 +380,7 @@ my_consistent(PG_FUNCTION_ARGS)
</varlistentry>
<varlistentry>
<term><function>union</></term>
<term><function>union</function></term>
<listitem>
<para>
This method consolidates information in the tree. Given a set of
@ -389,7 +389,7 @@ my_consistent(PG_FUNCTION_ARGS)
</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>
CREATE OR REPLACE FUNCTION my_union(internal, internal)
@ -439,44 +439,44 @@ my_union(PG_FUNCTION_ARGS)
<para>
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
implementing the proper union algorithm in this
<acronym>GiST</> support method.
<acronym>GiST</acronym> support method.
</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
different from the indexed column's type). The <function>union</>
function should return a pointer to newly <function>palloc()</>ed
different from the indexed column's type). The <function>union</function>
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
no type change.
</para>
<para>
As shown above, the <function>union</> function's
first <type>internal</> argument is actually
a <structname>GistEntryVector</> pointer. The second argument is a
As shown above, the <function>union</function> function's
first <type>internal</type> argument is actually
a <structname>GistEntryVector</structname> pointer. The second argument is a
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.)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><function>compress</></term>
<term><function>compress</function></term>
<listitem>
<para>
Converts a data item into a format suitable for physical storage in
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.
</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>
CREATE OR REPLACE FUNCTION my_compress(internal)
@ -519,7 +519,7 @@ my_compress(PG_FUNCTION_ARGS)
</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
course.
</para>
@ -527,24 +527,24 @@ my_compress(PG_FUNCTION_ARGS)
</varlistentry>
<varlistentry>
<term><function>decompress</></term>
<term><function>decompress</function></term>
<listitem>
<para>
Converts the stored representation of a data item into a format that
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.
(<function>decompress</> is not necessarily the reverse of
(<function>decompress</function> is not necessarily the reverse of
the <function>compress</function> method; in particular,
if <function>compress</function> is lossy then it's impossible
for <function>decompress</> to exactly reconstruct the original
data. <function>decompress</> is not necessarily equivalent
to <function>fetch</>, either, since the other GiST methods might not
for <function>decompress</function> to exactly reconstruct the original
data. <function>decompress</function> is not necessarily equivalent
to <function>fetch</function>, either, since the other GiST methods might not
require full reconstruction of the data.)
</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>
CREATE OR REPLACE FUNCTION my_decompress(internal)
@ -573,7 +573,7 @@ my_decompress(PG_FUNCTION_ARGS)
</varlistentry>
<varlistentry>
<term><function>penalty</></term>
<term><function>penalty</function></term>
<listitem>
<para>
Returns a value indicating the <quote>cost</quote> of inserting the new
@ -584,7 +584,7 @@ my_decompress(PG_FUNCTION_ARGS)
</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>
CREATE OR REPLACE FUNCTION my_penalty(internal, internal, internal)
@ -612,15 +612,15 @@ my_penalty(PG_FUNCTION_ARGS)
}
</programlisting>
For historical reasons, the <function>penalty</> function doesn't
just return a <type>float</> result; instead it has to store the value
For historical reasons, the <function>penalty</function> function doesn't
just return a <type>float</type> result; instead it has to store the value
at the location indicated by the third argument. The return
value per se is ignored, though it's conventional to pass back the
address of that argument.
</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
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.
@ -629,7 +629,7 @@ my_penalty(PG_FUNCTION_ARGS)
</varlistentry>
<varlistentry>
<term><function>picksplit</></term>
<term><function>picksplit</function></term>
<listitem>
<para>
When an index page split is necessary, this function decides which
@ -638,7 +638,7 @@ my_penalty(PG_FUNCTION_ARGS)
</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>
CREATE OR REPLACE FUNCTION my_picksplit(internal, internal)
@ -725,33 +725,33 @@ my_picksplit(PG_FUNCTION_ARGS)
}
</programlisting>
Notice that the <function>picksplit</> function's result is delivered
by modifying the passed-in <structname>v</> structure. The return
Notice that the <function>picksplit</function> function's result is delivered
by modifying the passed-in <structname>v</structname> structure. The return
value per se is ignored, though it's conventional to pass back the
address of <structname>v</>.
address of <structname>v</structname>.
</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
<function>penalty</> and <function>picksplit</> implementations
<function>penalty</function> and <function>picksplit</function> implementations
is where the challenge of implementing well-performing
<acronym>GiST</> indexes lies.
<acronym>GiST</acronym> indexes lies.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><function>same</></term>
<term><function>same</function></term>
<listitem>
<para>
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.)
</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>
CREATE OR REPLACE FUNCTION my_same(storage_type, storage_type, internal)
@ -777,7 +777,7 @@ my_same(PG_FUNCTION_ARGS)
}
</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
at the location indicated by the third argument. The return
value per se is ignored, though it's conventional to pass back the
@ -787,15 +787,15 @@ my_same(PG_FUNCTION_ARGS)
</varlistentry>
<varlistentry>
<term><function>distance</></term>
<term><function>distance</function></term>
<listitem>
<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
<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.
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.
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
@ -803,7 +803,7 @@ my_same(PG_FUNCTION_ARGS)
</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>
CREATE OR REPLACE FUNCTION my_distance(internal, data_type, smallint, oid, internal)
@ -836,8 +836,8 @@ my_distance(PG_FUNCTION_ARGS)
}
</programlisting>
The arguments to the <function>distance</> function are identical to
the arguments of the <function>consistent</> function.
The arguments to the <function>distance</function> function are identical to
the arguments of the <function>consistent</function> function.
</para>
<para>
@ -847,31 +847,31 @@ my_distance(PG_FUNCTION_ARGS)
geometric applications. For an internal tree node, the distance
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
<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
this case the executor will calculate the accurate distance after
fetching the tuple from the heap, and reorder the tuples if necessary.
</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
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
operator, since the executor will sort using both distance function
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
order returned by the ordering operator. (Infinity and minus infinity
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>
</listitem>
</varlistentry>
<varlistentry>
<term><function>fetch</></term>
<term><function>fetch</function></term>
<listitem>
<para>
Converts the compressed index representation of a data item into the
@ -880,7 +880,7 @@ my_distance(PG_FUNCTION_ARGS)
</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>
CREATE OR REPLACE FUNCTION my_fetch(internal)
@ -889,14 +889,14 @@ AS 'MODULE_PATHNAME'
LANGUAGE C STRICT;
</programlisting>
The argument is a pointer to a <structname>GISTENTRY</> struct. On
entry, its <structfield>key</> field contains a non-NULL leaf datum in
compressed form. The return value is another <structname>GISTENTRY</>
struct, whose <structfield>key</> field contains the same datum in its
The argument is a pointer to a <structname>GISTENTRY</structname> struct. On
entry, its <structfield>key</structfield> field contains a non-NULL leaf datum in
compressed form. The return value is another <structname>GISTENTRY</structname>
struct, whose <structfield>key</structfield> field contains the same datum in its
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,
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.
</para>
@ -933,7 +933,7 @@ my_fetch(PG_FUNCTION_ARGS)
<para>
If the compress method is lossy for leaf entries, the operator class
cannot support index-only scans, and must not define
a <function>fetch</> function.
a <function>fetch</function> function.
</para>
</listitem>
@ -942,15 +942,15 @@ my_fetch(PG_FUNCTION_ARGS)
<para>
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
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
the longer-lived data in <literal>fcinfo-&gt;flinfo-&gt;fn_mcxt</>, and
keep a pointer to it in <literal>fcinfo-&gt;flinfo-&gt;fn_extra</>. Such
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</literal>. Such
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
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.
</para>
@ -974,7 +974,7 @@ my_fetch(PG_FUNCTION_ARGS)
</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
buffers used in the buffering build need temporary disk space, up to
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
several examples of index methods implemented using
<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
(see <filename>src/backend/access/gist/gistproc.c</>). The following
<filename>contrib</> modules also contain <acronym>GiST</acronym>
(see <filename>src/backend/access/gist/gistproc.c</filename>). The following
<filename>contrib</filename> modules also contain <acronym>GiST</acronym>
operator classes:
<variablelist>
<varlistentry>
<term><filename>btree_gist</></term>
<term><filename>btree_gist</filename></term>
<listitem>
<para>B-tree equivalent functionality for several data types</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>cube</></term>
<term><filename>cube</filename></term>
<listitem>
<para>Indexing for multidimensional cubes</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>hstore</></term>
<term><filename>hstore</filename></term>
<listitem>
<para>Module for storing (key, value) pairs</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>intarray</></term>
<term><filename>intarray</filename></term>
<listitem>
<para>RD-Tree for one-dimensional array of int4 values</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>ltree</></term>
<term><filename>ltree</filename></term>
<listitem>
<para>Indexing for tree-like structures</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>pg_trgm</></term>
<term><filename>pg_trgm</filename></term>
<listitem>
<para>Text similarity using trigram matching</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>seg</></term>
<term><filename>seg</filename></term>
<listitem>
<para>Indexing for <quote>float ranges</quote></para>
</listitem>

File diff suppressed because it is too large Load Diff

View File

@ -132,7 +132,7 @@
(<application>psql</application>) was provided for interactive
SQL queries, which used <acronym>GNU</acronym>
<application>Readline</application>. This largely superseded
the old <application>monitor</> program.
the old <application>monitor</application> program.
</para>
</listitem>
@ -215,7 +215,7 @@
</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">.
</para>
</sect2>

View File

@ -8,21 +8,21 @@
</indexterm>
<para>
This module implements the <type>hstore</> data type for storing sets of
key/value pairs within a single <productname>PostgreSQL</> value.
This module implements the <type>hstore</type> data type for storing sets of
key/value pairs within a single <productname>PostgreSQL</productname> value.
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
simply text strings.
</para>
<sect2>
<title><type>hstore</> External Representation</title>
<title><type>hstore</type> External Representation</title>
<para>
The text representation of an <type>hstore</>, used for input and output,
includes zero or more <replaceable>key</> <literal>=&gt;</>
<replaceable>value</> pairs separated by commas. Some examples:
The text representation of an <type>hstore</type>, used for input and output,
includes zero or more <replaceable>key</replaceable> <literal>=&gt;</literal>
<replaceable>value</replaceable> pairs separated by commas. Some examples:
<synopsis>
k =&gt; v
@ -31,15 +31,15 @@ foo =&gt; bar, baz =&gt; whatever
</synopsis>
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,
<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.
</para>
<para>
Each key in an <type>hstore</> is unique. If you declare an <type>hstore</>
with duplicate keys, only one will be stored in the <type>hstore</> and
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</type> and
there is no guarantee as to which will be kept:
<programlisting>
@ -51,24 +51,24 @@ SELECT 'a=&gt;1,a=&gt;2'::hstore;
</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>
key =&gt; NULL
</programlisting>
The <literal>NULL</> keyword is case-insensitive. Double-quote the
<literal>NULL</> to treat it as the ordinary string <quote>NULL</quote>.
The <literal>NULL</literal> keyword is case-insensitive. Double-quote the
<literal>NULL</literal> to treat it as the ordinary string <quote>NULL</quote>.
</para>
<note>
<para>
Keep in mind that the <type>hstore</> text format, when used for input,
applies <emphasis>before</> any required quoting or escaping. If you are
passing an <type>hstore</> literal via a parameter, then no additional
Keep in mind that the <type>hstore</type> text format, when used for input,
applies <emphasis>before</emphasis> any required quoting or escaping. If you are
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
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
<xref linkend="sql-syntax-strings"> for more on the handling of string
constants.
@ -83,7 +83,7 @@ key =&gt; NULL
</sect2>
<sect2>
<title><type>hstore</> Operators and Functions</title>
<title><type>hstore</type> Operators and Functions</title>
<para>
The operators provided by the <literal>hstore</literal> module are
@ -92,7 +92,7 @@ key =&gt; NULL
</para>
<table id="hstore-op-table">
<title><type>hstore</> Operators</title>
<title><type>hstore</type> Operators</title>
<tgroup cols="4">
<thead>
@ -106,99 +106,99 @@ key =&gt; NULL
<tbody>
<row>
<entry><type>hstore</> <literal>-&gt;</> <type>text</></entry>
<entry>get value for key (<literal>NULL</> if not present)</entry>
<entry><type>hstore</type> <literal>-&gt;</literal> <type>text</type></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>x</literal></entry>
</row>
<row>
<entry><type>hstore</> <literal>-&gt;</> <type>text[]</></entry>
<entry>get values for keys (<literal>NULL</> if not present)</entry>
<entry><type>hstore</type> <literal>-&gt;</literal> <type>text[]</type></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>{"z","x"}</literal></entry>
</row>
<row>
<entry><type>hstore</> <literal>||</> <type>hstore</></entry>
<entry>concatenate <type>hstore</>s</entry>
<entry><type>hstore</type> <literal>||</literal> <type>hstore</type></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;"x", "d"=&gt;"q"</literal></entry>
</row>
<row>
<entry><type>hstore</> <literal>?</> <type>text</></entry>
<entry>does <type>hstore</> contain key?</entry>
<entry><type>hstore</type> <literal>?</literal> <type>text</type></entry>
<entry>does <type>hstore</type> contain key?</entry>
<entry><literal>'a=&gt;1'::hstore ? 'a'</literal></entry>
<entry><literal>t</literal></entry>
</row>
<row>
<entry><type>hstore</> <literal>?&amp;</> <type>text[]</></entry>
<entry>does <type>hstore</> contain all specified keys?</entry>
<entry><type>hstore</type> <literal>?&amp;</literal> <type>text[]</type></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>t</literal></entry>
</row>
<row>
<entry><type>hstore</> <literal>?|</> <type>text[]</></entry>
<entry>does <type>hstore</> contain any of the specified keys?</entry>
<entry><type>hstore</type> <literal>?|</literal> <type>text[]</type></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>t</literal></entry>
</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><literal>'a=&gt;b, b=&gt;1, c=&gt;NULL'::hstore @&gt; 'b=&gt;1'</literal></entry>
<entry><literal>t</literal></entry>
</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><literal>'a=&gt;c'::hstore &lt;@ 'a=&gt;b, b=&gt;1, c=&gt;NULL'</literal></entry>
<entry><literal>f</literal></entry>
</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><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>
</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><literal>'a=&gt;1, b=&gt;2, c=&gt;3'::hstore - ARRAY['a','b']</literal></entry>
<entry><literal>"c"=&gt;"3"</literal></entry>
</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><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>
</row>
<row>
<entry><type>record</> <literal>#=</> <type>hstore</></entry>
<entry>replace fields in <type>record</> with matching values from <type>hstore</></entry>
<entry><type>record</type> <literal>#=</literal> <type>hstore</type></entry>
<entry>replace fields in <type>record</type> with matching values from <type>hstore</type></entry>
<entry>see Examples section</entry>
<entry></entry>
</row>
<row>
<entry><literal>%%</> <type>hstore</></entry>
<entry>convert <type>hstore</> to array of alternating keys and values</entry>
<entry><literal>%%</literal> <type>hstore</type></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,foo,b,bar}</literal></entry>
</row>
<row>
<entry><literal>%#</> <type>hstore</></entry>
<entry>convert <type>hstore</> to two-dimensional key/value array</entry>
<entry><literal>%#</literal> <type>hstore</type></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,foo},{b,bar}}</literal></entry>
</row>
@ -209,8 +209,8 @@ key =&gt; NULL
<note>
<para>
Prior to PostgreSQL 8.2, the containment operators <literal>@&gt;</>
and <literal>&lt;@</> were called <literal>@</> and <literal>~</>,
Prior to PostgreSQL 8.2, the containment operators <literal>@&gt;</literal>
and <literal>&lt;@</literal> were called <literal>@</literal> and <literal>~</literal>,
respectively. These names are still available, but are deprecated and will
eventually be removed. Notice that the old names are reversed from the
convention formerly followed by the core geometric data types!
@ -218,7 +218,7 @@ key =&gt; NULL
</note>
<table id="hstore-func-table">
<title><type>hstore</> Functions</title>
<title><type>hstore</type> Functions</title>
<tgroup cols="5">
<thead>
@ -235,7 +235,7 @@ key =&gt; NULL
<row>
<entry><function>hstore(record)</function><indexterm><primary>hstore</primary></indexterm></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>f1=&gt;1,f2=&gt;2</literal></entry>
</row>
@ -243,7 +243,7 @@ key =&gt; NULL
<row>
<entry><function>hstore(text[])</function></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>
<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>
@ -252,7 +252,7 @@ key =&gt; NULL
<row>
<entry><function>hstore(text[], text[])</function></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>"a"=&gt;"1","b"=&gt;"2"</literal></entry>
</row>
@ -260,7 +260,7 @@ key =&gt; NULL
<row>
<entry><function>hstore(text, text)</function></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>"a"=&gt;"b"</literal></entry>
</row>
@ -268,7 +268,7 @@ key =&gt; NULL
<row>
<entry><function>akeys(hstore)</function><indexterm><primary>akeys</primary></indexterm></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>{a,b}</literal></entry>
</row>
@ -276,7 +276,7 @@ key =&gt; NULL
<row>
<entry><function>skeys(hstore)</function><indexterm><primary>skeys</primary></indexterm></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>
<programlisting>
@ -288,7 +288,7 @@ b
<row>
<entry><function>avals(hstore)</function><indexterm><primary>avals</primary></indexterm></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>{1,2}</literal></entry>
</row>
@ -296,7 +296,7 @@ b
<row>
<entry><function>svals(hstore)</function><indexterm><primary>svals</primary></indexterm></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>
<programlisting>
@ -308,7 +308,7 @@ b
<row>
<entry><function>hstore_to_array(hstore)</function><indexterm><primary>hstore_to_array</primary></indexterm></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>
<entry><literal>hstore_to_array('a=&gt;1,b=&gt;2')</literal></entry>
<entry><literal>{a,1,b,2}</literal></entry>
@ -317,7 +317,7 @@ b
<row>
<entry><function>hstore_to_matrix(hstore)</function><indexterm><primary>hstore_to_matrix</primary></indexterm></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>{{a,1},{b,2}}</literal></entry>
</row>
@ -359,7 +359,7 @@ b
<row>
<entry><function>slice(hstore, text[])</function><indexterm><primary>slice</primary></indexterm></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>"b"=&gt;"2", "c"=&gt;"3"</literal></entry>
</row>
@ -367,7 +367,7 @@ b
<row>
<entry><function>each(hstore)</function><indexterm><primary>each</primary></indexterm></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>
<programlisting>
@ -381,7 +381,7 @@ b
<row>
<entry><function>exist(hstore,text)</function><indexterm><primary>exist</primary></indexterm></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>t</literal></entry>
</row>
@ -389,7 +389,7 @@ b
<row>
<entry><function>defined(hstore,text)</function><indexterm><primary>defined</primary></indexterm></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>f</literal></entry>
</row>
@ -421,7 +421,7 @@ b
<row>
<entry><function>populate_record(record,hstore)</function><indexterm><primary>populate_record</primary></indexterm></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></entry>
</row>
@ -442,7 +442,7 @@ b
<note>
<para>
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.
</para>
</note>
@ -452,8 +452,8 @@ b
<title>Indexes</title>
<para>
<type>hstore</> has GiST and GIN index support for the <literal>@&gt;</>,
<literal>?</>, <literal>?&amp;</> and <literal>?|</> operators. For example:
<type>hstore</type> has GiST and GIN index support for the <literal>@&gt;</literal>,
<literal>?</literal>, <literal>?&amp;</literal> and <literal>?|</literal> operators. For example:
</para>
<programlisting>
CREATE INDEX hidx ON testhstore USING GIST (h);
@ -462,12 +462,12 @@ CREATE INDEX hidx ON testhstore USING GIN (h);
</programlisting>
<para>
<type>hstore</> also supports <type>btree</> or <type>hash</> indexes for
the <literal>=</> operator. This allows <type>hstore</> columns to be
declared <literal>UNIQUE</>, or to be used in <literal>GROUP BY</>,
<literal>ORDER BY</> or <literal>DISTINCT</> expressions. The sort ordering
for <type>hstore</> values is not particularly useful, but these indexes
may be useful for equivalence lookups. Create indexes for <literal>=</>
<type>hstore</type> also supports <type>btree</type> or <type>hash</type> indexes for
the <literal>=</literal> operator. This allows <type>hstore</type> columns to be
declared <literal>UNIQUE</literal>, or to be used in <literal>GROUP BY</literal>,
<literal>ORDER BY</literal> or <literal>DISTINCT</literal> expressions. The sort ordering
for <type>hstore</type> values is not particularly useful, but these indexes
may be useful for equivalence lookups. Create indexes for <literal>=</literal>
comparisons as follows:
</para>
<programlisting>
@ -495,7 +495,7 @@ UPDATE tab SET h = delete(h, 'k1');
</para>
<para>
Convert a <type>record</> to an <type>hstore</>:
Convert a <type>record</type> to an <type>hstore</type>:
<programlisting>
CREATE TABLE test (col1 integer, col2 text, col3 text);
INSERT INTO test VALUES (123, 'foo', 'bar');
@ -509,7 +509,7 @@ SELECT hstore(t) FROM test AS t;
</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>
CREATE TABLE test (col1 integer, col2 text, col3 text);
@ -523,7 +523,7 @@ SELECT * FROM populate_record(null::test,
</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>
CREATE TABLE test (col1 integer, col2 text, col3 text);
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>
<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
application. The following examples demonstrate several techniques for
checking keys and obtaining statistics.
@ -588,7 +588,7 @@ SELECT key, count(*) FROM
<title>Compatibility</title>
<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
dump/restore upgrades since the text representation (used in the dump) is
unchanged.
@ -599,7 +599,7 @@ SELECT key, count(*) FROM
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
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>
UPDATE tablename SET hstorecol = hstorecol || '';
</programlisting>
@ -610,7 +610,7 @@ UPDATE tablename SET hstorecol = hstorecol || '';
<programlisting>
ALTER TABLE tablename ALTER hstorecol TYPE hstore USING hstorecol || '';
</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.
</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>
Constructs equivalent to combinations of these operators, such as
<literal>BETWEEN</> and <literal>IN</>, can also be implemented with
a B-tree index search. Also, an <literal>IS NULL</> or <literal>IS NOT
NULL</> condition on an index column can be used with a B-tree index.
<literal>BETWEEN</literal> and <literal>IN</literal>, can also be implemented with
a B-tree index search. Also, an <literal>IS NULL</literal> or <literal>IS NOT
NULL</literal> condition on an index column can be used with a B-tree index.
</para>
<para>
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
the beginning of the string &mdash; for example, <literal>col LIKE
'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.
Accordingly, the particular operators with which a GiST index can be
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
for several two-dimensional geometric data types, which support indexed
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
documented in <xref linkend="gist-builtin-opclasses-table">.
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">.
</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
<programlisting><![CDATA[
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
to do this is again dependent on the particular operator class being used.
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>
@ -290,7 +290,7 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10;
<primary>GIN</primary>
<see>index</see>
</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
inverted index contains a separate entry for each component value, and
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
documented in <xref linkend="gin-builtin-opclasses-table">.
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">.
</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
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
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
<literal>a</> = 5 and <literal>b</> = 42 up through the last entry with
<literal>a</> = 5. Index entries with <literal>c</> &gt;= 77 would be
<literal>a</literal> = 5 and <literal>b</literal> = 42 up through the last entry with
<literal>a</literal> = 5. Index entries with <literal>c</literal> &gt;= 77 would be
skipped, but they'd still have to be scanned through.
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
the planner would prefer a sequential table scan over using the index.
</para>
@ -462,17 +462,17 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor);
<sect1 id="indexes-ordering">
<title>Indexes and <literal>ORDER BY</></title>
<title>Indexes and <literal>ORDER BY</literal></title>
<indexterm zone="indexes-ordering">
<primary>index</primary>
<secondary>and <literal>ORDER BY</></secondary>
<secondary>and <literal>ORDER BY</literal></secondary>
</indexterm>
<para>
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.
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
supported by <productname>PostgreSQL</productname>, only B-tree
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>
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,
or by scanning the table in physical order and doing an explicit
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
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
special case is <literal>ORDER BY</> in combination with
<literal>LIMIT</> <replaceable>n</>: an explicit sort will have to process
all the data to identify the first <replaceable>n</> rows, but if there is
an index matching the <literal>ORDER BY</>, the first <replaceable>n</>
special case is <literal>ORDER BY</literal> in combination with
<literal>LIMIT</literal> <replaceable>n</replaceable>: an explicit sort will have to process
all the data to identify the first <replaceable>n</replaceable> rows, but if there is
an index matching the <literal>ORDER BY</literal>, the first <replaceable>n</replaceable>
rows can be retrieved directly, without scanning the remainder at all.
</para>
<para>
By default, B-tree indexes store their entries in ascending order
with nulls last. This means that a forward scan of an index on
column <literal>x</> produces output satisfying <literal>ORDER BY x</>
(or more verbosely, <literal>ORDER BY x ASC NULLS LAST</>). The
column <literal>x</literal> produces output satisfying <literal>ORDER BY x</literal>
(or more verbosely, <literal>ORDER BY x ASC NULLS LAST</literal>). The
index can also be scanned backward, producing output satisfying
<literal>ORDER BY x DESC</>
(or more verbosely, <literal>ORDER BY x DESC NULLS FIRST</>, since
<literal>NULLS FIRST</> is the default for <literal>ORDER BY DESC</>).
<literal>ORDER BY x DESC</literal>
(or more verbosely, <literal>ORDER BY x DESC NULLS FIRST</literal>, since
<literal>NULLS FIRST</literal> is the default for <literal>ORDER BY DESC</literal>).
</para>
<para>
You can adjust the ordering of a B-tree index by including the
options <literal>ASC</>, <literal>DESC</>, <literal>NULLS FIRST</>,
and/or <literal>NULLS LAST</> when creating the index; for example:
options <literal>ASC</literal>, <literal>DESC</literal>, <literal>NULLS FIRST</literal>,
and/or <literal>NULLS LAST</literal> when creating the index; for example:
<programlisting>
CREATE INDEX test2_info_nulls_low ON test2 (info NULLS FIRST);
CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST);
</programlisting>
An index stored in ascending order with nulls first can satisfy
either <literal>ORDER BY x ASC NULLS FIRST</> or
<literal>ORDER BY x DESC NULLS LAST</> depending on which direction
either <literal>ORDER BY x ASC NULLS FIRST</literal> or
<literal>ORDER BY x DESC NULLS LAST</literal> depending on which direction
it is scanned in.
</para>
<para>
You might wonder why bother providing all four options, when two
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
useful. Consider a two-column index on <literal>(x, y)</>: this can
satisfy <literal>ORDER BY x, y</> if we scan forward, or
<literal>ORDER BY x DESC, y DESC</> if we scan backward.
useful. Consider a two-column index on <literal>(x, y)</literal>: this can
satisfy <literal>ORDER BY x, y</literal> if we scan forward, or
<literal>ORDER BY x DESC, y DESC</literal> if we scan backward.
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
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>
@ -559,38 +559,38 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST);
<para>
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
<literal>AND</>. For example, given an index on <literal>(a, b)</literal>
a query condition like <literal>WHERE a = 5 AND b = 6</> could
use the index, but a query like <literal>WHERE a = 5 OR b = 6</> could not
<literal>AND</literal>. For example, given an index on <literal>(a, b)</literal>
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</literal> could not
directly use the index.
</para>
<para>
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
be implemented by single index scans. The system can form <literal>AND</>
and <literal>OR</> conditions across several index scans. For example,
a query like <literal>WHERE x = 42 OR x = 47 OR x = 53 OR x = 99</>
could be broken down into four separate scans of an index on <literal>x</>,
be implemented by single index scans. The system can form <literal>AND</literal>
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</literal>
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
then ORed together to produce the result. Another example is that if we
have separate indexes on <literal>x</> and <literal>y</>, one possible
implementation of a query like <literal>WHERE x = 5 AND y = 6</> is to
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</literal> is to
use each index with the appropriate query clause and then AND together
the index results to identify the result rows.
</para>
<para>
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.
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
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
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
scan even though additional indexes are available that could have been
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
and rely on the index-combination feature. For example, if your
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
<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
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
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
and a separate index on <literal>y</> would serve reasonably well. For
queries involving only <literal>x</>, the multicolumn index could be
and a separate index on <literal>y</literal> would serve reasonably well. For
queries involving only <literal>x</literal>, the multicolumn index could be
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
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
@ -698,9 +698,9 @@ CREATE INDEX test1_lower_col1_idx ON test1 (lower(col1));
</para>
<para>
If we were to declare this index <literal>UNIQUE</>, it would prevent
creation of rows whose <literal>col1</> values differ only in case,
as well as rows whose <literal>col1</> values are actually identical.
If we were to declare this index <literal>UNIQUE</literal>, it would prevent
creation of rows whose <literal>col1</literal> values differ only in case,
as well as rows whose <literal>col1</literal> values are actually identical.
Thus, indexes on expressions can be used to enforce constraints that
are not definable as simple unique constraints.
</para>
@ -717,7 +717,7 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name));
</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
example. The parentheses can be omitted when the expression is just
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
derived expression(s) must be computed for each row upon insertion
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
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
query. Thus, indexes on expressions are useful when retrieval 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;
</programlisting>
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>
SELECT * FROM orders WHERE billed is not true AND amount &gt; 5000.00;
</programlisting>
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
orders, using this partial index just to find the unbilled orders
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
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
the <literal>WHERE</> condition of the query mathematically implies
the <literal>WHERE</literal> condition of the query mathematically implies
the predicate of the index.
<productname>PostgreSQL</productname> does not have a sophisticated
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
<quote>x &lt; 1</quote> implies <quote>x &lt; 2</quote>; otherwise
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
place at query planning time, not at run time. As a result,
parameterized query clauses do not work with a partial index. For
@ -919,9 +919,9 @@ SELECT * FROM orders WHERE order_nr = 3501;
<para>
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
<quote>unsuccessful</> entries. Here is one way to do it:
<quote>unsuccessful</quote> entries. Here is one way to do it:
<programlisting>
CREATE TABLE tests (
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
should not. In that case the index can be set up so that it is not
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
earlier example really only saves index size, it is not required to
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 when an index might be profitable. Forming this knowledge
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.
</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 basic sort ordering (which can then be modified by adding sort options
<literal>COLLATE</literal>,
<literal>ASC</>/<literal>DESC</> and/or
<literal>NULLS FIRST</>/<literal>NULLS LAST</>).
<literal>ASC</literal>/<literal>DESC</literal> and/or
<literal>NULLS FIRST</literal>/<literal>NULLS LAST</literal>).
</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);
</programlisting>
Note that you should also create an index with the default operator
class if you want queries involving ordinary <literal>&lt;</>,
<literal>&lt;=</>, <literal>&gt;</>, or <literal>&gt;=</> comparisons
class if you want queries involving ordinary <literal>&lt;</literal>,
<literal>&lt;=</literal>, <literal>&gt;</literal>, or <literal>&gt;=</literal> comparisons
to use an index. Such queries cannot use the
<literal><replaceable>xxx</replaceable>_pattern_ops</literal>
operator classes. (Ordinary equality comparisons can use these
@ -1057,7 +1057,7 @@ SELECT am.amname AS index_method,
<para>
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
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
@ -1147,13 +1147,13 @@ CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y");
</indexterm>
<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
main data area (which is called the table's <firstterm>heap</>
in <productname>PostgreSQL</> terminology). This means that in an
main data area (which is called the table's <firstterm>heap</firstterm>
in <productname>PostgreSQL</productname> terminology). This means that in an
ordinary index scan, each row retrieval requires fetching data from both
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 heap-access portion of an index scan thus involves a lot of random
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>
To solve this performance problem, <productname>PostgreSQL</>
supports <firstterm>index-only scans</>, which can answer queries from an
To solve this performance problem, <productname>PostgreSQL</productname>
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
directly out of each index entry instead of consulting the associated heap
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>
<para>
The query must reference only columns stored in the index. For
example, given an index on columns <literal>x</> and <literal>y</> of a
table that also has a column <literal>z</>, these queries could use
example, given an index on columns <literal>x</literal> and <literal>y</literal> of a
table that also has a column <literal>z</literal>, these queries could use
index-only scans:
<programlisting>
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
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
table scan in <productname>PostgreSQL</>: it must verify that each
retrieved row be <quote>visible</> to the query's MVCC snapshot, as
table scan in <productname>PostgreSQL</productname>: it must verify that each
retrieved row be <quote>visible</quote> to the query's MVCC snapshot, as
discussed in <xref linkend="mvcc">. Visibility information is not stored
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
indeed the case, if the table row has been modified recently. However,
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
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
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
@ -1243,48 +1243,48 @@ SELECT x FROM tab WHERE x = 'key' AND z &lt; 42;
<para>
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
match <literal>WHERE</> clauses, while the trailing columns
hold <quote>payload</> data to be returned by a query. For example, if
match <literal>WHERE</literal> clauses, while the trailing columns
hold <quote>payload</quote> data to be returned by a query. For example, if
you commonly run queries like
<programlisting>
SELECT y FROM tab WHERE x = 'key';
</programlisting>
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
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
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
leading index columns are not very efficient.
</para>
<para>
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
<programlisting>
SELECT f(x) FROM tab WHERE f(x) &lt; 1;
</programlisting>
as an index-only scan; and this is very attractive if <literal>f()</> is
an expensive-to-compute function. However, <productname>PostgreSQL</>'s
as an index-only scan; and this is very attractive if <literal>f()</literal> is
an expensive-to-compute function. However, <productname>PostgreSQL</productname>'s
planner is currently not very smart about such cases. It considers a
query to be potentially executable by index-only scan only when
all <emphasis>columns</> needed by the query are available from the index.
In this example, <literal>x</> is not needed except in the
context <literal>f(x)</>, but the planner does not notice that and
all <emphasis>columns</emphasis> needed by the query are available from the index.
In this example, <literal>x</literal> is not needed except in the
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
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
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
necessarily match uses of <literal>f(x)</> that aren't in
indexable <literal>WHERE</> clauses to the index column. It will usually
to avoid recalculating <literal>f(x)</literal>, is that the planner won't
necessarily match uses of <literal>f(x)</literal> that aren't in
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
that involve joins. These deficiencies may be remedied in future versions
of <productname>PostgreSQL</>.
of <productname>PostgreSQL</productname>.
</para>
<para>
@ -1299,13 +1299,13 @@ CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target)
<programlisting>
SELECT target FROM tests WHERE subject = 'some-subject' AND success;
</programlisting>
But there's a problem: the <literal>WHERE</> clause refers
to <literal>success</> which is not available as a result column of the
But there's a problem: the <literal>WHERE</literal> clause refers
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
not need to recheck that part of the <literal>WHERE</> clause at run time:
all entries found in the index necessarily have <literal>success = true</>
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</literal>
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
will not.
</para>
@ -1321,7 +1321,7 @@ SELECT target FROM tests WHERE subject = 'some-subject' AND success;
</indexterm>
<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
which indexes are actually used by the real-life query workload.
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
various plan types (see <xref linkend="runtime-config-query-enable">).
For instance, turning off sequential scans
(<varname>enable_seqscan</>) and nested-loop joins
(<varname>enable_nestloop</>), which are the most basic plans,
(<varname>enable_seqscan</varname>) and nested-loop joins
(<varname>enable_nestloop</varname>), which are the most basic plans,
will force the system to use a different plan. If the system
still chooses a sequential scan or nested-loop join then there is
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
appropriate, then you might have to resort to forcing index usage
explicitly. You might also want to contact the
<productname>PostgreSQL</> developers to examine the issue.
<productname>PostgreSQL</productname> developers to examine the issue.
</para>
</listitem>
</itemizedlist>

View File

@ -15,9 +15,9 @@
<para>
The <productname>PostgreSQL</productname> <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
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.
</para>
</listitem>
@ -42,7 +42,7 @@
<para>
The mailing lists are a good place to have your questions
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.
</para>
</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>Visual Studio 2008</productname> and above. Compilation
is supported down to <productname>Windows XP</productname> and
<productname>Windows Server 2003</> when building with
<productname>Visual Studio 2005</> to
<productname>Windows Server 2003</productname> when building with
<productname>Visual Studio 2005</productname> to
<productname>Visual Studio 2013</productname>. Building with
<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
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>
@ -163,7 +163,7 @@ $ENV{MSBFLAGS}="/m";
<productname>Microsoft Windows SDK</productname> it
is recommended that you upgrade to the latest version (currently
version 7.1), available for download from
<ulink url="https://www.microsoft.com/download"></>.
<ulink url="https://www.microsoft.com/download"></ulink>.
</para>
<para>
You must always include the
@ -182,7 +182,7 @@ $ENV{MSBFLAGS}="/m";
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.
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,
the free Standard Distribution is sufficient).
</para></listitem>
@ -219,7 +219,7 @@ $ENV{MSBFLAGS}="/m";
<para>
Both <productname>Bison</productname> and <productname>Flex</productname>
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.
</para>
@ -259,7 +259,7 @@ $ENV{MSBFLAGS}="/m";
<term><productname>Diff</productname></term>
<listitem><para>
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>
</varlistentry>
@ -267,7 +267,7 @@ $ENV{MSBFLAGS}="/m";
<term><productname>Gettext</productname></term>
<listitem><para>
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.
</para></listitem>
</varlistentry>
@ -277,7 +277,7 @@ $ENV{MSBFLAGS}="/m";
<listitem><para>
Required for GSSAPI authentication support. MIT Kerberos can be
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>
</varlistentry>
@ -286,8 +286,8 @@ $ENV{MSBFLAGS}="/m";
<productname>libxslt</productname></term>
<listitem><para>
Required for XML support. Binaries can be downloaded from
<ulink url="http://zlatkovic.com/pub/libxml"></> or source from
<ulink url="http://xmlsoft.org"></>. Note that libxml2 requires iconv,
<ulink url="http://zlatkovic.com/pub/libxml"></ulink> or source from
<ulink url="http://xmlsoft.org"></ulink>. Note that libxml2 requires iconv,
which is available from the same download location.
</para></listitem>
</varlistentry>
@ -296,8 +296,8 @@ $ENV{MSBFLAGS}="/m";
<term><productname>openssl</productname></term>
<listitem><para>
Required for SSL support. Binaries can be downloaded from
<ulink url="http://www.slproweb.com/products/Win32OpenSSL.html"></>
or source from <ulink url="http://www.openssl.org"></>.
<ulink url="http://www.slproweb.com/products/Win32OpenSSL.html"></ulink>
or source from <ulink url="http://www.openssl.org"></ulink>.
</para></listitem>
</varlistentry>
@ -306,7 +306,7 @@ $ENV{MSBFLAGS}="/m";
<listitem><para>
Required for UUID-OSSP support (contrib only). Source can be
downloaded from
<ulink url="http://www.ossp.org/pkg/lib/uuid/"></>.
<ulink url="http://www.ossp.org/pkg/lib/uuid/"></ulink>.
</para></listitem>
</varlistentry>
@ -314,7 +314,7 @@ $ENV{MSBFLAGS}="/m";
<term><productname>Python</productname></term>
<listitem><para>
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>
</varlistentry>
@ -323,7 +323,7 @@ $ENV{MSBFLAGS}="/m";
<listitem><para>
Required for compression support in <application>pg_dump</application>
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>
</varlistentry>
@ -347,8 +347,8 @@ $ENV{MSBFLAGS}="/m";
</para>
<para>
To use a server-side third party library such as <productname>python</> or
<productname>openssl</>, this library <emphasis>must</emphasis> also be
To use a server-side third party library such as <productname>python</productname> or
<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
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
@ -462,20 +462,20 @@ $ENV{CONFIG}="Debug";
<para>
Running the regression tests on client programs, with
<command>vcregress bincheck</>, or on recovery tests, with
<command>vcregress recoverycheck</>, requires an additional Perl module
<command>vcregress bincheck</command>, or on recovery tests, with
<command>vcregress recoverycheck</command>, requires an additional Perl module
to be installed:
<variablelist>
<varlistentry>
<term><productname>IPC::Run</productname></term>
<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
Manager (PPM) library. To install, download the
<filename>IPC-Run-&lt;version&gt;.tar.gz</> source archive from CPAN,
at <ulink url="http://search.cpan.org/dist/IPC-Run/"></>, and
uncompress. Edit the <filename>buildenv.pl</> file, and add a PERL5LIB
variable to point to the <filename>lib</> subdirectory from the
<filename>IPC-Run-&lt;version&gt;.tar.gz</filename> source archive from CPAN,
at <ulink url="http://search.cpan.org/dist/IPC-Run/"></ulink>, and
uncompress. Edit the <filename>buildenv.pl</filename> file, and add a PERL5LIB
variable to point to the <filename>lib</filename> subdirectory from the
extracted archive. For example:
<programlisting>
$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>
<listitem><para>
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>.
</para></listitem>
</varlistentry>
@ -507,7 +507,7 @@ $ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib';
<term>DocBook DTD 4.2</term>
<listitem><para>
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>.
</para></listitem>
</varlistentry>
@ -516,7 +516,7 @@ $ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib';
<term>ISO character entities</term>
<listitem><para>
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>.
</para></listitem>
</varlistentry>

File diff suppressed because it is too large Load Diff

View File

@ -28,10 +28,10 @@
<para>
The aggregator is an aggregate function
<function>int_array_aggregate(integer)</>
<function>int_array_aggregate(integer)</function>
that produces an integer array
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.
</para>
@ -41,10 +41,10 @@
<para>
The enumerator is a function
<function>int_array_enum(integer[])</>
that returns <type>setof integer</>. It is essentially the reverse
<function>int_array_enum(integer[])</function>
that returns <type>setof integer</type>. It is essentially the reverse
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.
</para>
@ -67,7 +67,7 @@ CREATE TABLE one_to_many(left INT REFERENCES left, right INT REFERENCES right);
<programlisting>
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>
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>
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
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
@ -95,30 +95,30 @@ CREATE TABLE summary AS
the array; that's why there is an array enumerator. You can do
<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>
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
<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>
The difference is that the query against the summary table has to get
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>
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
<structname>one_to_many</> table, which was replaced by:
<structname>one_to_many</structname> table, which was replaced by:
<programlisting>
SELECT right, count(right) FROM
( 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)
) AS list
GROUP BY right

View File

@ -8,7 +8,7 @@
</indexterm>
<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.
There is also support for indexed searches using some of the operators.
</para>
@ -25,7 +25,7 @@
</para>
<sect2>
<title><filename>intarray</> Functions and Operators</title>
<title><filename>intarray</filename> Functions and Operators</title>
<para>
The functions provided by the <filename>intarray</filename> module
@ -34,7 +34,7 @@
</para>
<table id="intarray-func-table">
<title><filename>intarray</> Functions</title>
<title><filename>intarray</filename> Functions</title>
<tgroup cols="5">
<thead>
@ -59,7 +59,7 @@
<row>
<entry><function>sort(int[], text dir)</function><indexterm><primary>sort</primary></indexterm></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>{3,2,1}</literal></entry>
</row>
@ -99,7 +99,7 @@
<row>
<entry><function>idx(int[], int item)</function><indexterm><primary>idx</primary></indexterm></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>2</literal></entry>
</row>
@ -107,7 +107,7 @@
<row>
<entry><function>subarray(int[], int start, int len)</function><indexterm><primary>subarray</primary></indexterm></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>{2,3,2}</literal></entry>
</row>
@ -115,7 +115,7 @@
<row>
<entry><function>subarray(int[], int start)</function></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>{2,3,2,1}</literal></entry>
</row>
@ -133,7 +133,7 @@
</table>
<table id="intarray-op-table">
<title><filename>intarray</> Operators</title>
<title><filename>intarray</filename> Operators</title>
<tgroup cols="3">
<thead>
@ -148,17 +148,17 @@
<row>
<entry><literal>int[] &amp;&amp; int[]</literal></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>
<entry><literal>int[] @&gt; int[]</literal></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>
<entry><literal>int[] &lt;@ int[]</literal></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>
<entry><literal># int[]</literal></entry>
@ -168,7 +168,7 @@
<row>
<entry><literal>int[] # int</literal></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>
<entry><literal>int[] + int</literal></entry>
@ -208,28 +208,28 @@
<row>
<entry><literal>int[] @@ query_int</literal></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>
<entry><literal>query_int ~~ int[]</literal></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>
</tbody>
</tgroup>
</table>
<para>
(Before PostgreSQL 8.2, the containment operators <literal>@&gt;</> and
<literal>&lt;@</> were respectively called <literal>@</> and <literal>~</>.
(Before PostgreSQL 8.2, the containment operators <literal>@&gt;</literal> and
<literal>&lt;@</literal> were 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 are reversed from the convention
formerly followed by the core geometric data types!)
</para>
<para>
The operators <literal>&amp;&amp;</>, <literal>@&gt;</> and
<literal>&lt;@</> are equivalent to <productname>PostgreSQL</>'s built-in
The operators <literal>&amp;&amp;</literal>, <literal>@&gt;</literal> and
<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
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
@ -237,14 +237,14 @@
</para>
<para>
The <literal>@@</> and <literal>~~</> operators test whether an array
satisfies a <firstterm>query</>, which is expressed as a value of a
specialized data type <type>query_int</>. A <firstterm>query</>
The <literal>@@</literal> and <literal>~~</literal> operators test whether an array
satisfies a <firstterm>query</firstterm>, which is expressed as a value of a
specialized data type <type>query_int</type>. A <firstterm>query</firstterm>
consists of integer values that are checked against the elements of
the array, possibly combined using the operators <literal>&amp;</>
(AND), <literal>|</> (OR), and <literal>!</> (NOT). Parentheses
the array, possibly combined using the operators <literal>&amp;</literal>
(AND), <literal>|</literal> (OR), and <literal>!</literal> (NOT). Parentheses
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.
</para>
</sect2>
@ -253,16 +253,16 @@
<title>Index Support</title>
<para>
<filename>intarray</> provides index support for the
<literal>&amp;&amp;</>, <literal>@&gt;</>, <literal>&lt;@</>,
and <literal>@@</> operators, as well as regular array equality.
<filename>intarray</filename> provides index support for the
<literal>&amp;&amp;</literal>, <literal>@&gt;</literal>, <literal>&lt;@</literal>,
and <literal>@@</literal> operators, as well as regular array equality.
</para>
<para>
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
<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
a large number of distinct array values).
The implementation uses an RD-tree data structure with
@ -271,7 +271,7 @@
<para>
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>
@ -284,7 +284,7 @@
<title>Example</title>
<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 specialized index
@ -305,9 +305,9 @@ SELECT message.mid FROM message WHERE message.sections @@ '1&amp;2'::query_int;
<title>Benchmark</title>
<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
<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:
</para>
@ -320,7 +320,7 @@ psql -c "CREATE EXTENSION intarray" TEST
</programlisting>
<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.
</para>
</sect2>

View File

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

View File

@ -123,7 +123,7 @@
</listitem>
<listitem>
<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>
<para>All UPC, ISBN, ISMN and ISSN numbers can be represented as EAN13
@ -139,7 +139,7 @@
</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
ISxN 13 format for numbers that do not fit in the short version.
The <type>EAN13</type>, <type>ISBN13</type>, <type>ISMN13</type> and
@ -152,7 +152,7 @@
<title>Casts</title>
<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>
<itemizedlist>
@ -209,7 +209,7 @@
</itemizedlist>
<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
is thrown if not. The other casts are simply relabelings that will
always succeed.
@ -220,15 +220,15 @@
<title>Functions and Operators</title>
<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
addition there are several specialized functions; shown in <xref linkend="isn-functions">.
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>
<table id="isn-functions">
<title><filename>isn</> Functions</title>
<title><filename>isn</filename> Functions</title>
<tgroup cols="3">
<thead>
<row>
@ -285,21 +285,21 @@
<para>
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
with an exclamation mark (<literal>!</>) at the end, for example
<literal>0-11-000322-5!</>. This invalid marker can be checked with
the <function>is_valid</> function and cleared with the
<function>make_valid</> function.
with an exclamation mark (<literal>!</literal>) at the end, for example
<literal>0-11-000322-5!</literal>. This invalid marker can be checked with
the <function>is_valid</function> function and cleared with the
<function>make_valid</function> function.
</para>
<para>
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.
</para>
<para>
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.
</para>
</sect2>
@ -384,7 +384,7 @@ SELECT isbn13(id) FROM test;
<para>
This module was inspired by Garrett A. Wollman's
<filename>isbn_issn</> code.
<filename>isbn_issn</filename> code.
</para>
</sect2>

View File

@ -1,7 +1,7 @@
<!-- doc/src/sgml/json.sgml -->
<sect1 id="datatype-json">
<title><acronym>JSON</> Types</title>
<title><acronym>JSON</acronym> Types</title>
<indexterm zone="datatype-json">
<primary>JSON</primary>
@ -22,25 +22,25 @@
</para>
<para>
There are two JSON data types: <type>json</> and <type>jsonb</>.
They accept <emphasis>almost</> identical sets of values as
There are two JSON data types: <type>json</type> and <type>jsonb</type>.
They accept <emphasis>almost</emphasis> identical sets of values as
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
<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
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.
</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
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
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
duplicate object keys. If duplicate keys are specified in the input,
only the last value is kept.
@ -48,7 +48,7 @@
<para>
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.
</para>
@ -64,15 +64,15 @@
<para>
RFC 7159 permits JSON strings to contain Unicode escape sequences
denoted by <literal>\u<replaceable>XXXX</></literal>. In the input
function for the <type>json</> type, Unicode escapes are allowed
denoted by <literal>\u<replaceable>XXXX</replaceable></literal>. In the input
function for the <type>json</type> type, Unicode escapes are allowed
regardless of the database encoding, and are checked only for syntactic
correctness (that is, that four hex digits follow <literal>\u</>).
However, the input function for <type>jsonb</> is stricter: it disallows
Unicode escapes for non-ASCII characters (those above <literal>U+007F</>)
unless the database encoding is UTF8. The <type>jsonb</> type also
rejects <literal>\u0000</> (because that cannot be represented in
<productname>PostgreSQL</productname>'s <type>text</> type), and it insists
correctness (that is, that four hex digits follow <literal>\u</literal>).
However, the input function for <type>jsonb</type> is stricter: it disallows
Unicode escapes for non-ASCII characters (those above <literal>U+007F</literal>)
unless the database encoding is UTF8. The <type>jsonb</type> type also
rejects <literal>\u0000</literal> (because that cannot be represented in
<productname>PostgreSQL</productname>'s <type>text</type> type), and it insists
that any use of Unicode surrogate pairs to designate characters outside
the Unicode Basic Multilingual Plane be correct. Valid Unicode escapes
are converted to the equivalent ASCII or UTF8 character for storage;
@ -84,8 +84,8 @@
Many of the JSON processing functions described
in <xref linkend="functions-json"> will convert Unicode escapes to
regular characters, and will therefore throw the same types of errors
just described even if their input is of type <type>json</>
not <type>jsonb</>. The fact that the <type>json</> input function does
just described even if their input is of type <type>json</type>
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
it does allow for simple storage (without processing) of JSON Unicode
escapes in a non-UTF8 database encoding. In general, it is best to
@ -95,22 +95,22 @@
</note>
<para>
When converting textual JSON input into <type>jsonb</>, the primitive
types described by <acronym>RFC</> 7159 are effectively mapped onto
When converting textual JSON input into <type>jsonb</type>, the primitive
types described by <acronym>RFC</acronym> 7159 are effectively mapped onto
native <productname>PostgreSQL</productname> types, as shown
in <xref linkend="json-type-mapping-table">.
Therefore, there are some minor additional constraints on what
constitutes valid <type>jsonb</type> data that do not apply to
the <type>json</type> type, nor to JSON in the abstract, corresponding
to limits on what can be represented by the underlying data type.
Notably, <type>jsonb</> will reject numbers that are outside the
range of the <productname>PostgreSQL</productname> <type>numeric</> data
type, while <type>json</> will not. Such implementation-defined
restrictions are permitted by <acronym>RFC</> 7159. However, in
Notably, <type>jsonb</type> will reject numbers that are outside the
range of the <productname>PostgreSQL</productname> <type>numeric</type> data
type, while <type>json</type> will not. Such implementation-defined
restrictions are permitted by <acronym>RFC</acronym> 7159. However, in
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
(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
of losing numeric precision compared to data originally stored
by <productname>PostgreSQL</productname> should be considered.
@ -134,23 +134,23 @@
</thead>
<tbody>
<row>
<entry><type>string</></entry>
<entry><type>text</></entry>
<entry><literal>\u0000</> is disallowed, as are non-ASCII Unicode
<entry><type>string</type></entry>
<entry><type>text</type></entry>
<entry><literal>\u0000</literal> is disallowed, as are non-ASCII Unicode
escapes if database encoding is not UTF8</entry>
</row>
<row>
<entry><type>number</></entry>
<entry><type>numeric</></entry>
<entry><type>number</type></entry>
<entry><type>numeric</type></entry>
<entry><literal>NaN</literal> and <literal>infinity</literal> values are disallowed</entry>
</row>
<row>
<entry><type>boolean</></entry>
<entry><type>boolean</></entry>
<entry><type>boolean</type></entry>
<entry><type>boolean</type></entry>
<entry>Only lowercase <literal>true</literal> and <literal>false</literal> spellings are accepted</entry>
</row>
<row>
<entry><type>null</></entry>
<entry><type>null</type></entry>
<entry>(none)</entry>
<entry>SQL <literal>NULL</literal> is a different concept</entry>
</row>
@ -162,10 +162,10 @@
<title>JSON Input and Output Syntax</title>
<para>
The input/output syntax for the JSON data types is as specified in
<acronym>RFC</> 7159.
<acronym>RFC</acronym> 7159.
</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>
-- Simple scalar/primitive value
-- 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>
As previously stated, when a JSON value is input and then printed without
any additional processing, <type>json</> outputs the same text that was
input, while <type>jsonb</> does not preserve semantically-insignificant
any additional processing, <type>json</type> outputs the same text that was
input, while <type>jsonb</type> does not preserve semantically-insignificant
details such as whitespace. For example, note the differences here:
<programlisting>
SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::json;
@ -202,9 +202,9 @@ SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::jsonb;
(1 row)
</programlisting>
One semantically-insignificant detail worth noting is that
in <type>jsonb</>, numbers will be printed according to the behavior of the
underlying <type>numeric</> type. In practice this means that numbers
entered with <literal>E</> notation will be printed without it, for
in <type>jsonb</type>, numbers will be printed according to the behavior of the
underlying <type>numeric</type> type. In practice this means that numbers
entered with <literal>E</literal> notation will be printed without it, for
example:
<programlisting>
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}
(1 row)
</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
purposes such as equality checks.
</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
unenforced (though enforcing some business rules declaratively is
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.
</para>
<para>
@ -249,7 +249,7 @@ SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb;
</sect2>
<sect2 id="json-containment">
<title><type>jsonb</> Containment and Existence</title>
<title><type>jsonb</type> Containment and Existence</title>
<indexterm>
<primary>jsonb</primary>
<secondary>containment</secondary>
@ -259,10 +259,10 @@ SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb;
<secondary>existence</secondary>
</indexterm>
<para>
Testing <firstterm>containment</> is an important capability of
<type>jsonb</>. There is no parallel set of facilities for the
<type>json</> type. Containment tests whether
one <type>jsonb</> document has contained within it another one.
Testing <firstterm>containment</firstterm> is an important capability of
<type>jsonb</type>. There is no parallel set of facilities for the
<type>json</type> type. Containment tests whether
one <type>jsonb</type> document has contained within it another one.
These examples return true except as noted:
</para>
<programlisting>
@ -282,7 +282,7 @@ SELECT '[1, 2, 3]'::jsonb @&gt; '[1, 2, 2]'::jsonb;
-- within the object on the left side:
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:
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>
<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
(given as a <type>text</> value) appears as an object key or array
element at the top level of the <type>jsonb</> value.
(given as a <type>text</type> value) appears as an object key or array
element at the top level of the <type>jsonb</type> value.
These examples return true except as noted:
</para>
<programlisting>
@ -353,11 +353,11 @@ SELECT '"foo"'::jsonb ? 'foo';
<para>
Because JSON containment is nested, an appropriate query can skip
explicit selection of sub-objects. As an example, suppose that we have
a <structfield>doc</> column containing objects at the top level, with
most objects containing <literal>tags</> fields that contain arrays of
a <structfield>doc</structfield> column containing objects at the top level, with
most objects containing <literal>tags</literal> fields that contain arrays of
sub-objects. This query finds entries in which sub-objects containing
both <literal>"term":"paris"</> and <literal>"term":"food"</> appear,
while ignoring any such keys outside the <literal>tags</> array:
both <literal>"term":"paris"</literal> and <literal>"term":"food"</literal> appear,
while ignoring any such keys outside the <literal>tags</literal> array:
<programlisting>
SELECT doc-&gt;'site_name' FROM websites
WHERE doc @&gt; '{"tags":[{"term":"paris"}, {"term":"food"}]}';
@ -385,7 +385,7 @@ SELECT doc-&gt;'site_name' FROM websites
</sect2>
<sect2 id="json-indexing">
<title><type>jsonb</> Indexing</title>
<title><type>jsonb</type> Indexing</title>
<indexterm>
<primary>jsonb</primary>
<secondary>indexes on</secondary>
@ -394,23 +394,23 @@ SELECT doc-&gt;'site_name' FROM websites
<para>
GIN indexes can be used to efficiently search for
keys or key/value pairs occurring within a large number of
<type>jsonb</> documents (datums).
Two GIN <quote>operator classes</> are provided, offering different
<type>jsonb</type> documents (datums).
Two GIN <quote>operator classes</quote> are provided, offering different
performance and flexibility trade-offs.
</para>
<para>
The default GIN operator class for <type>jsonb</> supports queries with
top-level key-exists operators <literal>?</>, <literal>?&amp;</>
and <literal>?|</> operators and path/value-exists operator
<literal>@&gt;</>.
The default GIN operator class for <type>jsonb</type> supports queries with
top-level key-exists operators <literal>?</literal>, <literal>?&amp;</literal>
and <literal>?|</literal> operators and path/value-exists operator
<literal>@&gt;</literal>.
(For details of the semantics that these operators
implement, see <xref linkend="functions-jsonb-op-table">.)
An example of creating an index with this operator class is:
<programlisting>
CREATE INDEX idxgin ON api USING GIN (jdoc);
</programlisting>
The non-default GIN operator class <literal>jsonb_path_ops</>
supports indexing the <literal>@&gt;</> operator only.
The non-default GIN operator class <literal>jsonb_path_ops</literal>
supports indexing the <literal>@&gt;</literal> operator only.
An example of creating an index with this operator class is:
<programlisting>
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>
We store these documents in a table named <structname>api</>,
in a <type>jsonb</> column named <structfield>jdoc</>.
We store these documents in a table named <structname>api</structname>,
in a <type>jsonb</type> column named <structfield>jdoc</structfield>.
If a GIN index is created on this column,
queries like the following can make use of the index:
<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"}';
</programlisting>
However, the index could not be used for queries like the
following, because though the operator <literal>?</> is indexable,
it is not applied directly to the indexed column <structfield>jdoc</>:
following, because though the operator <literal>?</literal> is indexable,
it is not applied directly to the indexed column <structfield>jdoc</structfield>:
<programlisting>
-- 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';
</programlisting>
Still, with appropriate use of expression indexes, the above
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:
<programlisting>
CREATE INDEX idxgintags ON api USING GIN ((jdoc -&gt; 'tags'));
</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
operator <literal>?</> to the indexed
expression <literal>jdoc -&gt; 'tags'</>.
operator <literal>?</literal> to the indexed
expression <literal>jdoc -&gt; 'tags'</literal>.
(More information on expression indexes can be found in <xref
linkend="indexes-expressional">.)
</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"
SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc @&gt; '{"tags": ["qui"]}';
</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
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
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
indexes are likely to be smaller and faster to search than a simple
index.
@ -485,7 +485,7 @@ SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc @&gt; '{"tags": ["qu
<para>
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
class <literal>jsonb_ops</literal>. A <literal>jsonb_path_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.
<footnote>
<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
from values within objects.
</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
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
be created incorporating all three of <literal>foo</>, <literal>bar</>,
and <literal>baz</> into the hash value. Thus a containment query
be created incorporating all three of <literal>foo</literal>, <literal>bar</literal>,
and <literal>baz</literal> into the hash value. Thus a containment query
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>
index would create three index items representing <literal>foo</>,
<literal>bar</>, and <literal>baz</> separately; then to do the
index would create three index items representing <literal>foo</literal>,
<literal>bar</literal>, and <literal>baz</literal> separately; then to do the
containment query, it would look for rows containing all three of
these items. While GIN indexes can perform such an AND search fairly
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
any values, such as <literal>{"a": {}}</literal>. If a search for
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.
</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
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:
<synopsis>
<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>
<para>
The <filename>lo</> module provides support for managing Large Objects
(also called LOs or BLOBs). This includes a data type <type>lo</>
and a trigger <function>lo_manage</>.
The <filename>lo</filename> module provides support for managing Large Objects
(also called LOs or BLOBs). This includes a data type <type>lo</type>
and a trigger <function>lo_manage</function>.
</para>
<sect2>
@ -24,7 +24,7 @@
</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
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
@ -32,30 +32,30 @@
</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
orphan objects &mdash; objects that are not referenced by anything, and
simply occupy disk space.
</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
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
that there is only one database reference to any large object that is
referenced in a trigger-controlled column!
</para>
<para>
The module also provides a data type <type>lo</>, which is really just
a domain of the <type>oid</> type. This is useful for differentiating
The module also provides a data type <type>lo</type>, which is really just
a domain of the <type>oid</type> type. This is useful for differentiating
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
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
don't use <type>lo</> for BLOB columns.
don't use <type>lo</type> for BLOB columns.
</para>
</sect2>
@ -75,11 +75,11 @@ CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image
<para>
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
to only execute on updates to the column by using <literal>BEFORE UPDATE
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,
remembering to give a different name to each trigger on the same table.
</para>
@ -93,18 +93,18 @@ CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image
<para>
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
TABLE</> with <command>DELETE FROM <replaceable>table</></command>.
TABLE</command> with <command>DELETE FROM <replaceable>table</replaceable></command>.
</para>
<para>
<command>TRUNCATE</> has the same hazard.
<command>TRUNCATE</command> has the same hazard.
</para>
<para>
If you already have, or suspect you have, orphaned large objects, see the
<xref linkend="vacuumlo"> module to help
you clean them up. It's a good idea to run <application>vacuumlo</>
occasionally as a back-stop to the <function>lo_manage</> trigger.
you clean them up. It's a good idea to run <application>vacuumlo</application>
occasionally as a back-stop to the <function>lo_manage</function> trigger.
</para>
</listitem>

View File

@ -3,11 +3,11 @@
<chapter id="largeObjects">
<title>Large Objects</title>
<indexterm zone="largeobjects"><primary>large object</></>
<indexterm><primary>BLOB</><see>large object</></>
<indexterm zone="largeobjects"><primary>large object</primary></indexterm>
<indexterm><primary>BLOB</primary><see>large object</see></indexterm>
<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
in a special large-object structure. Streaming access is useful
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
data bytes actually written. A read operation will, however, read out
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.
</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
<xref linkend="sql-grant"> and
<xref linkend="sql-revoke">.
@ -101,7 +101,7 @@
<para>
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.
The <productname>PostgreSQL</productname> large object interface is
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
function will return an otherwise-impossible value, typically 0 or -1.
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>
@ -134,7 +134,7 @@
<title>Creating a Large Object</title>
<para>
<indexterm><primary>lo_creat</></>
<indexterm><primary>lo_creat</primary></indexterm>
The function
<synopsis>
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
backward compatibility with earlier releases it is best to
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
in the header file <filename>libpq/libpq-fs.h</filename>.)
</para>
@ -160,7 +160,7 @@ inv_oid = lo_creat(conn, INV_READ|INV_WRITE);
</para>
<para>
<indexterm><primary>lo_create</></>
<indexterm><primary>lo_create</primary></indexterm>
The function
<synopsis>
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>;
if so, failure occurs if that OID is already in use for some large
object. If <replaceable class="parameter">lobjId</replaceable>
is <symbol>InvalidOid</symbol> (zero) then <function>lo_create</> assigns an unused
OID (this is the same behavior as <function>lo_creat</>).
is <symbol>InvalidOid</symbol> (zero) then <function>lo_create</function> assigns an unused
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,
or <symbol>InvalidOid</symbol> (zero) on failure.
</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
fail and return <symbol>InvalidOid</symbol>.
</para>
@ -193,7 +193,7 @@ inv_oid = lo_create(conn, desired_oid);
<title>Importing a Large Object</title>
<para>
<indexterm><primary>lo_import</></>
<indexterm><primary>lo_import</primary></indexterm>
To import an operating system file as a large object, call
<synopsis>
Oid lo_import(PGconn *conn, const char *filename);
@ -209,7 +209,7 @@ Oid lo_import(PGconn *conn, const char *filename);
</para>
<para>
<indexterm><primary>lo_import_with_oid</></>
<indexterm><primary>lo_import_with_oid</primary></indexterm>
The function
<synopsis>
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>;
if so, failure occurs if that OID is already in use for some large
object. If <replaceable class="parameter">lobjId</replaceable>
is <symbol>InvalidOid</symbol> (zero) then <function>lo_import_with_oid</> assigns an unused
OID (this is the same behavior as <function>lo_import</>).
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</function>).
The return value is the OID that was assigned to the new large object,
or <symbol>InvalidOid</symbol> (zero) on failure.
</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
fail and return <symbol>InvalidOid</symbol>.
</para>
@ -235,7 +235,7 @@ Oid lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId);
<title>Exporting a Large Object</title>
<para>
<indexterm><primary>lo_export</></>
<indexterm><primary>lo_export</primary></indexterm>
To export a large object
into an operating system file, call
<synopsis>
@ -253,14 +253,14 @@ int lo_export(PGconn *conn, Oid lobjId, const char *filename);
<title>Opening an Existing Large Object</title>
<para>
<indexterm><primary>lo_open</></>
<indexterm><primary>lo_open</primary></indexterm>
To open an existing large object for reading or writing, call
<synopsis>
int lo_open(PGconn *conn, Oid lobjId, int mode);
</synopsis>
The <parameter>lobjId</parameter> argument specifies the OID of the large
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.
(These symbolic constants are defined
in the header file <filename>libpq/libpq-fs.h</filename>.)
@ -277,19 +277,19 @@ int lo_open(PGconn *conn, Oid lobjId, int mode);
<para>
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
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
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
from a descriptor opened with <symbol>INV_WRITE</symbol> returns
data that reflects all writes of other committed transactions as well
as writes of the current transaction. This is similar to the behavior
of <literal>REPEATABLE READ</> versus <literal>READ COMMITTED</> transaction
modes for ordinary SQL <command>SELECT</> commands.
of <literal>REPEATABLE READ</literal> versus <literal>READ COMMITTED</literal> transaction
modes for ordinary SQL <command>SELECT</command> commands.
</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>
<para>
<indexterm><primary>lo_write</></>
<indexterm><primary>lo_write</primary></indexterm>
The function
<synopsis>
int lo_write(PGconn *conn, int fd, const char *buf, size_t len);
</synopsis>
writes <parameter>len</parameter> bytes from <parameter>buf</parameter>
(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
number of bytes actually written is returned (in the current
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>
Although the <parameter>len</parameter> parameter is declared as
<type>size_t</>, this function will reject length values larger than
<literal>INT_MAX</>. In practice, it's best to transfer data in chunks
<type>size_t</type>, this function will reject length values larger than
<literal>INT_MAX</literal>. In practice, it's best to transfer data in chunks
of at most a few megabytes anyway.
</para>
</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>
<para>
<indexterm><primary>lo_read</></>
<indexterm><primary>lo_read</primary></indexterm>
The function
<synopsis>
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>
Although the <parameter>len</parameter> parameter is declared as
<type>size_t</>, this function will reject length values larger than
<literal>INT_MAX</>. In practice, it's best to transfer data in chunks
<type>size_t</type>, this function will reject length values larger than
<literal>INT_MAX</literal>. In practice, it's best to transfer data in chunks
of at most a few megabytes anyway.
</para>
</sect2>
@ -357,7 +357,7 @@ int lo_read(PGconn *conn, int fd, char *buf, size_t len);
<title>Seeking in a Large Object</title>
<para>
<indexterm><primary>lo_lseek</></>
<indexterm><primary>lo_lseek</primary></indexterm>
To change the current read or write location associated with a
large object descriptor, call
<synopsis>
@ -365,16 +365,16 @@ int lo_lseek(PGconn *conn, int fd, int offset, int whence);
</synopsis>
This function moves the
current location pointer for the large object descriptor identified by
<parameter>fd</> to the new location specified by
<parameter>offset</>. The valid values for <parameter>whence</>
are <symbol>SEEK_SET</> (seek from object start),
<symbol>SEEK_CUR</> (seek from current position), and
<symbol>SEEK_END</> (seek from object end). The return value is
<parameter>fd</parameter> to the new location specified by
<parameter>offset</parameter>. The valid values for <parameter>whence</parameter>
are <symbol>SEEK_SET</symbol> (seek from object start),
<symbol>SEEK_CUR</symbol> (seek from current position), and
<symbol>SEEK_END</symbol> (seek from object end). The return value is
the new location pointer, or -1 on error.
</para>
<para>
<indexterm><primary>lo_lseek64</></>
<indexterm><primary>lo_lseek64</primary></indexterm>
When dealing with large objects that might exceed 2GB in size,
instead use
<synopsis>
@ -382,14 +382,14 @@ pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence);
</synopsis>
This function has the same behavior
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.
Note that <function>lo_lseek</function> will fail if the new location
pointer would be greater than 2GB.
</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
fail and return -1.
</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>
<para>
<indexterm><primary>lo_tell</></>
<indexterm><primary>lo_tell</primary></indexterm>
To obtain the current read or write location of a large object descriptor,
call
<synopsis>
@ -410,7 +410,7 @@ int lo_tell(PGconn *conn, int fd);
</para>
<para>
<indexterm><primary>lo_tell64</></>
<indexterm><primary>lo_tell64</primary></indexterm>
When dealing with large objects that might exceed 2GB in size,
instead use
<synopsis>
@ -424,7 +424,7 @@ pg_int64 lo_tell64(PGconn *conn, int fd);
</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
fail and return -1.
</para>
@ -434,15 +434,15 @@ pg_int64 lo_tell64(PGconn *conn, int fd);
<title>Truncating a Large Object</title>
<para>
<indexterm><primary>lo_truncate</></>
<indexterm><primary>lo_truncate</primary></indexterm>
To truncate a large object to a given length, call
<synopsis>
int lo_truncate(PGcon *conn, int fd, size_t len);
</synopsis>
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
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
is extended to the specified length with null bytes ('\0').
On success, <function>lo_truncate</function> returns
@ -456,12 +456,12 @@ int lo_truncate(PGcon *conn, int fd, size_t len);
<para>
Although the <parameter>len</parameter> parameter is declared as
<type>size_t</>, <function>lo_truncate</function> will reject length
values larger than <literal>INT_MAX</>.
<type>size_t</type>, <function>lo_truncate</function> will reject length
values larger than <literal>INT_MAX</literal>.
</para>
<para>
<indexterm><primary>lo_truncate64</></>
<indexterm><primary>lo_truncate64</primary></indexterm>
When dealing with large objects that might exceed 2GB in size,
instead use
<synopsis>
@ -469,17 +469,17 @@ int lo_truncate64(PGcon *conn, int fd, pg_int64 len);
</synopsis>
This function has the same
behavior as <function>lo_truncate</function>, but it can accept a
<parameter>len</> value exceeding 2GB.
<parameter>len</parameter> value exceeding 2GB.
</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
fail and return -1.
</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
fail and return -1.
</para>
@ -489,12 +489,12 @@ int lo_truncate64(PGcon *conn, int fd, pg_int64 len);
<title>Closing a Large Object Descriptor</title>
<para>
<indexterm><primary>lo_close</></>
<indexterm><primary>lo_close</primary></indexterm>
A large object descriptor can be closed by calling
<synopsis>
int lo_close(PGconn *conn, int fd);
</synopsis>
where <parameter>fd</> is a
where <parameter>fd</parameter> is a
large object descriptor returned by <function>lo_open</function>.
On success, <function>lo_close</function> returns zero. On
error, the return value is -1.
@ -510,7 +510,7 @@ int lo_close(PGconn *conn, int fd);
<title>Removing a Large Object</title>
<para>
<indexterm><primary>lo_unlink</></>
<indexterm><primary>lo_unlink</primary></indexterm>
To remove a large object from the database, call
<synopsis>
int lo_unlink(PGconn *conn, Oid lobjId);
@ -554,7 +554,7 @@ int lo_unlink(PGconn *conn, Oid lobjId);
<entry><type>oid</type></entry>
<entry>
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><literal>lo_from_bytea(0, E'\\xffffff00')</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 are simply interfaces to the equivalent server-side
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_unlink</function><indexterm><primary>lo_unlink</></>,
<function>lo_import</function><indexterm><primary>lo_import</></>, and
<function>lo_export</function><indexterm><primary>lo_export</></>.
<function>lo_unlink</function><indexterm><primary>lo_unlink</primary></indexterm>,
<function>lo_import</function><indexterm><primary>lo_import</primary></indexterm>, and
<function>lo_export</function><indexterm><primary>lo_export</primary></indexterm>.
Here are examples of their use:
<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,
but the names of the server-side functions differ from the client side
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>
</sect1>
@ -656,7 +656,7 @@ SELECT lo_export(image.raster, '/tmp/motd') FROM image
<para>
<xref linkend="lo-example"> is a sample program which shows how the large object
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
benefit. This program can also be found in
<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>
$ pg_recvlogical -d postgres --slot test --create-slot
$ 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');"
$ fg
BEGIN 693
table public.data: INSERT: id[integer]:4 data[text]:'4'
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
</programlisting>
</sect1>
@ -286,7 +286,7 @@ $ pg_recvlogical -d postgres --slot test --drop-slot
<para>
Creation of a snapshot is not always possible. In particular, it will
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.
</para>
</sect2>
@ -303,7 +303,7 @@ $ pg_recvlogical -d postgres --slot test --drop-slot
</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>
@ -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
cumbersome. If the output plugin only outputs textual data in the
server's encoding, it can declare that by
setting <literal>OutputPluginOptions.output_type</>
to <literal>OUTPUT_PLUGIN_TEXTUAL_OUTPUT</> instead
of <literal>OUTPUT_PLUGIN_BINARY_OUTPUT</> in
setting <literal>OutputPluginOptions.output_type</literal>
to <literal>OUTPUT_PLUGIN_TEXTUAL_OUTPUT</literal> instead
of <literal>OUTPUT_PLUGIN_BINARY_OUTPUT</literal> in
the <link linkend="logicaldecoding-output-plugin-startup">startup
callback</>. 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
callback</link>. In that case, all the data has to be in the server's encoding
so that a <type>text</type> datum can contain it. This is checked in assertion-enabled
builds.
</para>
</sect2>

View File

@ -8,7 +8,7 @@
</indexterm>
<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.
Extensive facilities for searching through label trees are provided.
</para>
@ -19,17 +19,17 @@
<para>
A <firstterm>label</firstterm> is a sequence of alphanumeric 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.
</para>
<para>
Examples: <literal>42</>, <literal>Personal_Services</>
Examples: <literal>42</literal>, <literal>Personal_Services</literal>
</para>
<para>
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
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,
@ -42,7 +42,7 @@
</para>
<para>
The <filename>ltree</> module provides several data types:
The <filename>ltree</filename> module provides several data types:
</para>
<itemizedlist>
@ -55,13 +55,13 @@
<listitem>
<para>
<type>lquery</type> represents a regular-expression-like pattern
for matching <type>ltree</> values. A simple word matches that
label within a path. A star symbol (<literal>*</>) matches zero
for matching <type>ltree</type> values. A simple word matches that
label within a path. A star symbol (<literal>*</literal>) matches zero
or more labels. For example:
<synopsis>
foo <lineannotation>Match the exact label path <literal>foo</></lineannotation>
*.foo.* <lineannotation>Match any label path containing the label <literal>foo</></lineannotation>
*.foo <lineannotation>Match any label path whose last label is <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</literal></lineannotation>
*.foo <lineannotation>Match any label path whose last label is <literal>foo</literal></lineannotation>
</synopsis>
</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
they can match:
<synopsis>
*{<replaceable>n</>} <lineannotation>Match exactly <replaceable>n</> labels</lineannotation>
*{<replaceable>n</>,} <lineannotation>Match at least <replaceable>n</> labels</lineannotation>
*{<replaceable>n</>,<replaceable>m</>} <lineannotation>Match at least <replaceable>n</> but not more than <replaceable>m</> labels</lineannotation>
*{,<replaceable>m</>} <lineannotation>Match at most <replaceable>m</> labels &mdash; same as </lineannotation> *{0,<replaceable>m</>}
*{<replaceable>n</replaceable>} <lineannotation>Match exactly <replaceable>n</replaceable> labels</lineannotation>
*{<replaceable>n</replaceable>,} <lineannotation>Match at least <replaceable>n</replaceable> 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</replaceable>} <lineannotation>Match at most <replaceable>m</replaceable> labels &mdash; same as </lineannotation> *{0,<replaceable>m</replaceable>}
</synopsis>
</para>
<para>
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>
@ <lineannotation>Match case-insensitively, for example <literal>a@</> matches <literal>A</></lineannotation>
* <lineannotation>Match any label with this prefix, for example <literal>foo*</> matches <literal>foobar</></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*</literal> matches <literal>foobar</literal></lineannotation>
% <lineannotation>Match initial underscore-separated words</lineannotation>
</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
<literal>foo_bar%</> matches <literal>foo_bar_baz</> but not
<literal>foo_barbaz</>. If combined with <literal>*</>, prefix
<literal>foo_bar%</literal> matches <literal>foo_bar_baz</literal> but not
<literal>foo_barbaz</literal>. If combined with <literal>*</literal>, prefix
matching applies to each word separately, for example
<literal>foo_bar%*</> matches <literal>foo1_bar2_baz</> but
not <literal>foo1_br2_baz</>.
<literal>foo_bar%*</literal> matches <literal>foo1_bar2_baz</literal> but
not <literal>foo1_br2_baz</literal>.
</para>
<para>
Also, you can write several possibly-modified labels separated with
<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> (OR) to match any of those labels, and you can put
<literal>!</literal> (NOT) at the start to match any label that doesn't
match any of the alternatives.
</para>
@ -141,14 +141,14 @@ a. b. c. d. e.
<listitem>
<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
modifiers <literal>@</>, <literal>*</>, <literal>%</> at the end;
the modifiers have the same meanings as in <type>lquery</>.
Words can be combined with <literal>&amp;</> (AND),
<literal>|</> (OR), <literal>!</> (NOT), and parentheses.
modifiers <literal>@</literal>, <literal>*</literal>, <literal>%</literal> at the end;
the modifiers have the same meanings as in <type>lquery</type>.
Words can be combined with <literal>&amp;</literal> (AND),
<literal>|</literal> (OR), <literal>!</literal> (NOT), and parentheses.
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.
</para>
@ -161,7 +161,7 @@ Europe &amp; Russia*@ &amp; !Transportation
any label beginning with <literal>Russia</literal> (case-insensitive),
but not paths containing the label <literal>Transportation</literal>.
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.
</para>
</listitem>
@ -169,8 +169,8 @@ Europe &amp; Russia*@ &amp; !Transportation
</itemizedlist>
<para>
Note: <type>ltxtquery</> allows whitespace between symbols, but
<type>ltree</> and <type>lquery</> do not.
Note: <type>ltxtquery</type> allows whitespace between symbols, but
<type>ltree</type> and <type>lquery</type> do not.
</para>
</sect2>
@ -178,16 +178,16 @@ Europe &amp; Russia*@ &amp; !Transportation
<title>Operators and Functions</title>
<para>
Type <type>ltree</> has the usual comparison operators
<literal>=</>, <literal>&lt;&gt;</literal>,
<literal>&lt;</>, <literal>&gt;</>, <literal>&lt;=</>, <literal>&gt;=</>.
Type <type>ltree</type> has the usual comparison operators
<literal>=</literal>, <literal>&lt;&gt;</literal>,
<literal>&lt;</literal>, <literal>&gt;</literal>, <literal>&lt;=</literal>, <literal>&gt;=</literal>.
Comparison sorts in the order of a tree traversal, with the children
of a node sorted by label text. In addition, the specialized
operators shown in <xref linkend="ltree-op-table"> are available.
</para>
<table id="ltree-op-table">
<title><type>ltree</> Operators</title>
<title><type>ltree</type> Operators</title>
<tgroup cols="3">
<thead>
@ -200,153 +200,153 @@ Europe &amp; Russia*@ &amp; !Transportation
<tbody>
<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>is left argument an ancestor of right (or equal)?</entry>
</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>is left argument a descendant of right (or equal)?</entry>
</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>does <type>ltree</> match <type>lquery</>?</entry>
<entry>does <type>ltree</type> match <type>lquery</type>?</entry>
</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>does <type>ltree</> match <type>lquery</>?</entry>
<entry>does <type>ltree</type> match <type>lquery</type>?</entry>
</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>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>
<entry><type>lquery[]</> <literal>?</> <type>ltree</></entry>
<entry><type>lquery[]</type> <literal>?</literal> <type>ltree</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>
<entry><type>ltree</> <literal>@</> <type>ltxtquery</></entry>
<entry><type>ltree</type> <literal>@</literal> <type>ltxtquery</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>
<entry><type>ltxtquery</> <literal>@</> <type>ltree</></entry>
<entry><type>ltxtquery</type> <literal>@</literal> <type>ltree</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>
<entry><type>ltree</> <literal>||</> <type>ltree</></entry>
<entry><type>ltree</type> <literal>||</literal> <type>ltree</type></entry>
<entry><type>ltree</type></entry>
<entry>concatenate <type>ltree</> paths</entry>
<entry>concatenate <type>ltree</type> paths</entry>
</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>convert text to <type>ltree</> and concatenate</entry>
<entry>convert text to <type>ltree</type> and concatenate</entry>
</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>convert text to <type>ltree</> and concatenate</entry>
<entry>convert text to <type>ltree</type> and concatenate</entry>
</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>does array contain an ancestor of <type>ltree</>?</entry>
<entry>does array contain an ancestor of <type>ltree</type>?</entry>
</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>does array contain an ancestor of <type>ltree</>?</entry>
<entry>does array contain an ancestor of <type>ltree</type>?</entry>
</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>does array contain a descendant of <type>ltree</>?</entry>
<entry>does array contain a descendant of <type>ltree</type>?</entry>
</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>does array contain a descendant of <type>ltree</>?</entry>
<entry>does array contain a descendant of <type>ltree</type>?</entry>
</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>does array contain any path matching <type>lquery</>?</entry>
<entry>does array contain any path matching <type>lquery</type>?</entry>
</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>does array contain any path matching <type>lquery</>?</entry>
<entry>does array contain any path matching <type>lquery</type>?</entry>
</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>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>
<entry><type>lquery[]</> <literal>?</> <type>ltree[]</></entry>
<entry><type>lquery[]</type> <literal>?</literal> <type>ltree[]</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>
<entry><type>ltree[]</> <literal>@</> <type>ltxtquery</></entry>
<entry><type>ltree[]</type> <literal>@</literal> <type>ltxtquery</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>
<entry><type>ltxtquery</> <literal>@</> <type>ltree[]</></entry>
<entry><type>ltxtquery</type> <literal>@</literal> <type>ltree[]</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>
<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>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>
<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>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>
<entry><type>ltree[]</> <literal>?~</> <type>lquery</></entry>
<entry><type>ltree[]</type> <literal>?~</literal> <type>lquery</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>
<entry><type>ltree[]</> <literal>?@</> <type>ltxtquery</></entry>
<entry><type>ltree[]</type> <literal>?@</literal> <type>ltxtquery</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>
</tbody>
@ -356,7 +356,7 @@ Europe &amp; Russia*@ &amp; !Transportation
<para>
The operators <literal>&lt;@</literal>, <literal>@&gt;</literal>,
<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
indexes. These are useful only for testing purposes.
</para>
@ -366,7 +366,7 @@ Europe &amp; Russia*@ &amp; !Transportation
</para>
<table id="ltree-func-table">
<title><type>ltree</> Functions</title>
<title><type>ltree</type> Functions</title>
<tgroup cols="5">
<thead>
@ -383,8 +383,8 @@ Europe &amp; Russia*@ &amp; !Transportation
<row>
<entry><function>subltree(ltree, int start, int end)</function><indexterm><primary>subltree</primary></indexterm></entry>
<entry><type>ltree</type></entry>
<entry>subpath of <type>ltree</> from position <parameter>start</> to
position <parameter>end</>-1 (counting from 0)</entry>
<entry>subpath of <type>ltree</type> from position <parameter>start</parameter> to
position <parameter>end</parameter>-1 (counting from 0)</entry>
<entry><literal>subltree('Top.Child1.Child2',1,2)</literal></entry>
<entry><literal>Child1</literal></entry>
</row>
@ -392,10 +392,10 @@ Europe &amp; Russia*@ &amp; !Transportation
<row>
<entry><function>subpath(ltree, int offset, int len)</function><indexterm><primary>subpath</primary></indexterm></entry>
<entry><type>ltree</type></entry>
<entry>subpath of <type>ltree</> starting at position
<parameter>offset</>, length <parameter>len</>.
If <parameter>offset</> is negative, subpath starts that far from the
end of the path. If <parameter>len</> is negative, leaves that many
<entry>subpath of <type>ltree</type> starting at position
<parameter>offset</parameter>, length <parameter>len</parameter>.
If <parameter>offset</parameter> is negative, subpath starts that far from the
end of the path. If <parameter>len</parameter> is negative, leaves that many
labels off the end of the path.</entry>
<entry><literal>subpath('Top.Child1.Child2',0,2)</literal></entry>
<entry><literal>Top.Child1</literal></entry>
@ -404,9 +404,9 @@ Europe &amp; Russia*@ &amp; !Transportation
<row>
<entry><function>subpath(ltree, int offset)</function></entry>
<entry><type>ltree</type></entry>
<entry>subpath of <type>ltree</> starting at position
<parameter>offset</>, extending to end of path.
If <parameter>offset</> is negative, subpath starts that far from the
<entry>subpath of <type>ltree</type> starting at position
<parameter>offset</parameter>, extending to end of path.
If <parameter>offset</parameter> is negative, subpath starts that far from the
end of the path.</entry>
<entry><literal>subpath('Top.Child1.Child2',1)</literal></entry>
<entry><literal>Child1.Child2</literal></entry>
@ -423,8 +423,8 @@ Europe &amp; Russia*@ &amp; !Transportation
<row>
<entry><function>index(ltree a, ltree b)</function><indexterm><primary>index</primary></indexterm></entry>
<entry><type>integer</type></entry>
<entry>position of first occurrence of <parameter>b</> in
<parameter>a</>; -1 if not found</entry>
<entry>position of first occurrence of <parameter>b</parameter> in
<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>6</literal></entry>
</row>
@ -432,9 +432,9 @@ Europe &amp; Russia*@ &amp; !Transportation
<row>
<entry><function>index(ltree a, ltree b, int offset)</function></entry>
<entry><type>integer</type></entry>
<entry>position of first occurrence of <parameter>b</> in
<parameter>a</>, searching starting at <parameter>offset</>;
negative <parameter>offset</> means start <parameter>-offset</>
<entry>position of first occurrence of <parameter>b</parameter> in
<parameter>a</parameter>, searching starting at <parameter>offset</parameter>;
negative <parameter>offset</parameter> means start <parameter>-offset</parameter>
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>9</literal></entry>
@ -443,7 +443,7 @@ Europe &amp; Russia*@ &amp; !Transportation
<row>
<entry><function>text2ltree(text)</function><indexterm><primary>text2ltree</primary></indexterm></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>
</row>
@ -451,7 +451,7 @@ Europe &amp; Russia*@ &amp; !Transportation
<row>
<entry><function>ltree2text(ltree)</function><indexterm><primary>ltree2text</primary></indexterm></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>
</row>
@ -481,25 +481,25 @@ Europe &amp; Russia*@ &amp; !Transportation
<sect2>
<title>Indexes</title>
<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:
</para>
<itemizedlist>
<listitem>
<para>
B-tree index over <type>ltree</>:
<literal>&lt;</>, <literal>&lt;=</>, <literal>=</>,
<literal>&gt;=</>, <literal>&gt;</literal>
B-tree index over <type>ltree</type>:
<literal>&lt;</literal>, <literal>&lt;=</literal>, <literal>=</literal>,
<literal>&gt;=</literal>, <literal>&gt;</literal>
</para>
</listitem>
<listitem>
<para>
GiST index over <type>ltree</>:
<literal>&lt;</>, <literal>&lt;=</>, <literal>=</>,
<literal>&gt;=</>, <literal>&gt;</>,
<literal>@&gt;</>, <literal>&lt;@</>,
<literal>@</>, <literal>~</>, <literal>?</literal>
GiST index over <type>ltree</type>:
<literal>&lt;</literal>, <literal>&lt;=</literal>, <literal>=</literal>,
<literal>&gt;=</literal>, <literal>&gt;</literal>,
<literal>@&gt;</literal>, <literal>&lt;@</literal>,
<literal>@</literal>, <literal>~</literal>, <literal>?</literal>
</para>
<para>
Example of creating such an index:
@ -510,9 +510,9 @@ CREATE INDEX path_gist_idx ON test USING GIST (path);
</listitem>
<listitem>
<para>
GiST index over <type>ltree[]</>:
<literal>ltree[] &lt;@ ltree</>, <literal>ltree @&gt; ltree[]</>,
<literal>@</>, <literal>~</>, <literal>?</literal>
GiST index over <type>ltree[]</type>:
<literal>ltree[] &lt;@ ltree</literal>, <literal>ltree @&gt; ltree[]</literal>,
<literal>@</literal>, <literal>~</literal>, <literal>?</literal>
</para>
<para>
Example of creating such an index:
@ -532,7 +532,7 @@ CREATE INDEX path_gist_idx ON test USING GIST (array_path);
<para>
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>
<programlisting>
@ -555,7 +555,7 @@ CREATE INDEX path_idx ON test USING BTREE (path);
</programlisting>
<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:
</para>

View File

@ -12,12 +12,12 @@
</indexterm>
<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
discussed here are <emphasis>required</emphasis>, but they
are repetitive in nature and can easily be automated using standard
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
check that they execute successfully.
</para>
@ -32,7 +32,7 @@
</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
<xref linkend="routine-vacuuming">. Closely related to this is updating
the statistics that will be used by the query planner, as discussed in
@ -46,9 +46,9 @@
<para>
<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
conditions. <application>check_postgres</> integrates with
conditions. <application>check_postgres</application> integrates with
Nagios and MRTG, but can be run standalone too.
</para>
@ -68,15 +68,15 @@
<para>
<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
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
results for your situation. Some database administrators will want to
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
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
subsections. Administrators who rely on autovacuuming may still wish
to skim this material to help them understand and adjust autovacuuming.
@ -109,30 +109,30 @@
<listitem>
<simpara>To protect against loss of very old data due to
<firstterm>transaction ID wraparound</> or
<firstterm>multixact ID wraparound</>.</simpara>
<firstterm>transaction ID wraparound</firstterm> or
<firstterm>multixact ID wraparound</firstterm>.</simpara>
</listitem>
</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.
</para>
<para>
There are two variants of <command>VACUUM</>: standard <command>VACUUM</>
and <command>VACUUM FULL</>. <command>VACUUM FULL</> can reclaim more
There are two variants of <command>VACUUM</command>: standard <command>VACUUM</command>
and <command>VACUUM FULL</command>. <command>VACUUM FULL</command> can reclaim more
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>,
<command>INSERT</command>, <command>UPDATE</command>, and
<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
<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
of the table. Generally, therefore,
administrators should strive to use standard <command>VACUUM</> and
avoid <command>VACUUM FULL</>.
administrators should strive to use standard <command>VACUUM</command> and
avoid <command>VACUUM FULL</command>.
</para>
<para>
@ -153,15 +153,15 @@
<para>
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.
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
transactions. But eventually, an outdated or deleted row version is no
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
space requirements. This is done by running <command>VACUUM</>.
space requirements. This is done by running <command>VACUUM</command>.
</para>
<para>
@ -170,7 +170,7 @@
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
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
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
@ -178,18 +178,18 @@
</para>
<para>
The usual goal of routine vacuuming is to do standard <command>VACUUM</>s
often enough to avoid needing <command>VACUUM FULL</>. The
The usual goal of routine vacuuming is to do standard <command>VACUUM</command>s
often enough to avoid needing <command>VACUUM FULL</command>. The
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
usage of disk space: each table occupies space equivalent to its
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,
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
better approach than infrequent <command>VACUUM FULL</> runs for
future. Thus, moderately-frequent standard <command>VACUUM</command> runs are a
better approach than infrequent <command>VACUUM FULL</command> runs for
maintaining heavily-updated tables.
</para>
@ -198,20 +198,20 @@
doing all the work at night when load is low.
The difficulty with doing vacuuming according to a fixed schedule
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,
since the daemon schedules vacuuming dynamically in response to update
activity. It is unwise to disable the daemon completely unless you
have an extremely predictable workload. One possible compromise is
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,
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.
</para>
<para>
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
necessary. (Some installations with extremely high update rates vacuum
their busiest tables as often as once every few minutes.) If you have
@ -222,11 +222,11 @@
<tip>
<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
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
to use <command>VACUUM FULL</>, or alternatively
to use <command>VACUUM FULL</command>, or alternatively
<xref linkend="sql-cluster">
or one of the table-rewriting variants of
<xref linkend="sql-altertable">.
@ -271,19 +271,19 @@
generate good plans for queries. These statistics are gathered by
the <xref linkend="sql-analyze"> command,
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
degrade database performance.
</para>
<para>
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
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
statistics of <quote>interesting</> columns. The daemon schedules
<command>ANALYZE</> strictly as a function of the number of rows
statistics of <quote>interesting</quote> columns. The daemon schedules
<command>ANALYZE</command> strictly as a function of the number of rows
inserted or updated; it has no knowledge of whether that will lead
to meaningful statistical changes.
</para>
@ -305,24 +305,24 @@
</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
statistics more frequently than others if your application requires it.
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
every single row.
</para>
<tip>
<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
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
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.
</para>
@ -337,11 +337,11 @@
<tip>
<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
might be useful. If your queries require statistics on foreign tables
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>
</tip>
</sect2>
@ -350,7 +350,7 @@
<title>Updating The Visibility Map</title>
<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
visible to all active transactions (and all future transactions, until the
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
transaction.
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
visible, the heap fetch can be skipped. This is most useful on
large data sets where the visibility map can prevent disk accesses.
@ -391,13 +391,13 @@
<para>
<productname>PostgreSQL</productname>'s
<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
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
(32 bits) a cluster that runs for a long time (more
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
means their output become invisible. In short, catastrophic data loss.
(Actually the data is still there, but that's cold comfort if you cannot
@ -407,47 +407,47 @@
<para>
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
the past that the effects of the inserting transaction are certain to be
visible to all current and future transactions.
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
<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
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
talking about. If the row version still exists after more than two billion
transactions, it will suddenly appear to be in the future. To
prevent this, <productname>PostgreSQL</> reserves a special XID,
<literal>FrozenTransactionId</>, which does not follow the normal XID
prevent this, <productname>PostgreSQL</productname> reserves a special XID,
<literal>FrozenTransactionId</literal>, which does not follow the normal XID
comparison rules and is always considered older
than every normal XID.
Frozen row versions are treated as if the inserting XID were
<literal>FrozenTransactionId</>, so that they will appear to be
<quote>in the past</> to all normal transactions regardless of wraparound
<literal>FrozenTransactionId</literal>, so that they will appear to be
<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
how long that is.
</para>
<note>
<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
with <literal>FrozenTransactionId</>, which was visible in the
row's <structname>xmin</> system column. Newer versions just set a flag
bit, preserving the row's original <structname>xmin</> for possible
forensic use. However, rows with <structname>xmin</> equal
to <literal>FrozenTransactionId</> (2) may still be found
in databases <application>pg_upgrade</>'d from pre-9.4 versions.
with <literal>FrozenTransactionId</literal>, which was visible in the
row's <structname>xmin</structname> system column. Newer versions just set a flag
bit, preserving the row's original <structname>xmin</structname> for possible
forensic use. However, rows with <structname>xmin</structname> equal
to <literal>FrozenTransactionId</literal> (2) may still be found
in databases <application>pg_upgrade</application>'d from pre-9.4 versions.
</para>
<para>
Also, system catalogs may contain rows with <structname>xmin</> equal
to <literal>BootstrapTransactionId</> (1), indicating that they were
inserted during the first phase of <application>initdb</>.
Like <literal>FrozenTransactionId</>, this special XID is treated as
Also, system catalogs may contain rows with <structname>xmin</structname> equal
to <literal>BootstrapTransactionId</literal> (1), indicating that they were
inserted during the first phase of <application>initdb</application>.
Like <literal>FrozenTransactionId</literal>, this special XID is treated as
older than every normal XID.
</para>
</note>
@ -463,26 +463,26 @@
</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
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
<command>VACUUM</>s won't always freeze every old row version in the table.
Periodically, <command>VACUUM</> will perform an <firstterm>aggressive
vacuum</>, skipping only those pages which contain neither dead rows nor
<command>VACUUM</command>s won't always freeze every old row version in the table.
Periodically, <command>VACUUM</command> will perform an <firstterm>aggressive
vacuum</firstterm>, skipping only those pages which contain neither dead rows nor
any unfrozen XID or MXID values.
<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
last such scan is greater than <varname>vacuum_freeze_table_age</> minus
<varname>vacuum_freeze_min_age</>. Setting
<varname>vacuum_freeze_table_age</> to 0 forces <command>VACUUM</> to
last such scan is greater than <varname>vacuum_freeze_table_age</varname> minus
<varname>vacuum_freeze_min_age</varname>. Setting
<varname>vacuum_freeze_table_age</varname> to 0 forces <command>VACUUM</command> to
use this more aggressive strategy for all scans.
</para>
<para>
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
unvacuumed for longer than
that, data loss could result. To ensure that this does not happen,
@ -495,29 +495,29 @@
<para>
This implies that if a table is not otherwise vacuumed,
autovacuum will be invoked on it approximately once every
<varname>autovacuum_freeze_max_age</> minus
<varname>vacuum_freeze_min_age</> transactions.
<varname>autovacuum_freeze_max_age</varname> minus
<varname>vacuum_freeze_min_age</varname> transactions.
For tables that are regularly vacuumed for space reclamation purposes,
this is of little importance. However, for static tables
(including tables that receive inserts, but no updates or deletes),
there is no need to vacuum for space reclamation, so it can
be useful to try to maximize the interval between forced autovacuums
on very large static tables. Obviously one can do this either by
increasing <varname>autovacuum_freeze_max_age</> or decreasing
<varname>vacuum_freeze_min_age</>.
increasing <varname>autovacuum_freeze_max_age</varname> or decreasing
<varname>vacuum_freeze_min_age</varname>.
</para>
<para>
The effective maximum for <varname>vacuum_freeze_table_age</> is 0.95 *
<varname>autovacuum_freeze_max_age</>; a setting higher than that will be
The effective maximum for <varname>vacuum_freeze_table_age</varname> is 0.95 *
<varname>autovacuum_freeze_max_age</varname>; a setting higher than that will be
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
the 0.95 multiplier leaves some breathing room to run a manual
<command>VACUUM</> before that happens. As a rule of thumb,
<command>vacuum_freeze_table_age</> should be set to a value somewhat
below <varname>autovacuum_freeze_max_age</>, leaving enough gap so that
a regularly scheduled <command>VACUUM</> or an autovacuum triggered by
<command>VACUUM</command> before that happens. As a rule of thumb,
<command>vacuum_freeze_table_age</command> should be set to a value somewhat
below <varname>autovacuum_freeze_max_age</varname>, leaving enough gap so that
a regularly scheduled <command>VACUUM</command> or an autovacuum triggered by
normal delete and update activity is run in that window. Setting it too
close could lead to anti-wraparound autovacuums, even though the table
was recently vacuumed to reclaim space, whereas lower values lead to more
@ -525,29 +525,29 @@
</para>
<para>
The sole disadvantage of increasing <varname>autovacuum_freeze_max_age</>
(and <varname>vacuum_freeze_table_age</> along with it) is that
the <filename>pg_xact</> and <filename>pg_commit_ts</filename>
The sole disadvantage of increasing <varname>autovacuum_freeze_max_age</varname>
(and <varname>vacuum_freeze_table_age</varname> along with it) is that
the <filename>pg_xact</filename> and <filename>pg_commit_ts</filename>
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
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
<varname>autovacuum_freeze_max_age</> is set to its maximum allowed value
of two billion, <filename>pg_xact</> can be expected to grow to about half
<varname>autovacuum_freeze_max_age</varname> is set to its maximum allowed value
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
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
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
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.)
</para>
<para>
One disadvantage of decreasing <varname>vacuum_freeze_min_age</> is that
it might cause <command>VACUUM</> to do useless work: freezing a row
One disadvantage of decreasing <varname>vacuum_freeze_min_age</varname> is that
it might cause <command>VACUUM</command> to do useless work: freezing a row
version is a waste of time if the row is modified
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
@ -556,18 +556,18 @@
<para>
To track the age of the oldest unfrozen XIDs in a database,
<command>VACUUM</> stores XID
statistics in the system tables <structname>pg_class</> and
<structname>pg_database</>. In particular,
the <structfield>relfrozenxid</> column of a table's
<structname>pg_class</> row contains the freeze cutoff XID that was used
by the last aggressive <command>VACUUM</> for that table. All rows
<command>VACUUM</command> stores XID
statistics in the system tables <structname>pg_class</structname> and
<structname>pg_database</structname>. In particular,
the <structfield>relfrozenxid</structfield> column of a table's
<structname>pg_class</structname> row contains the freeze cutoff XID that was used
by the last aggressive <command>VACUUM</command> for that table. All rows
inserted by transactions with XIDs older than this cutoff XID are
guaranteed to have been frozen. Similarly,
the <structfield>datfrozenxid</> column of a database's
<structname>pg_database</> row is a lower bound on the unfrozen XIDs
the <structfield>datfrozenxid</structfield> column of a database's
<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
per-table <structfield>relfrozenxid</> values within the database.
per-table <structfield>relfrozenxid</structfield> values within the database.
A convenient way to
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;
</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.
</para>
<para>
<command>VACUUM</> normally only scans pages that have been modified
since the last vacuum, but <structfield>relfrozenxid</> can only be
<command>VACUUM</command> normally only scans pages that have been modified
since the last vacuum, but <structfield>relfrozenxid</structfield> can only be
advanced when every page of the table
that might contain unfrozen XIDs is scanned. This happens when
<structfield>relfrozenxid</> is more than
<varname>vacuum_freeze_table_age</> transactions old, when
<command>VACUUM</>'s <literal>FREEZE</> option is used, or when all
<structfield>relfrozenxid</structfield> is more than
<varname>vacuum_freeze_table_age</varname> transactions old, when
<command>VACUUM</command>'s <literal>FREEZE</literal> option is used, or when all
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
set <literal>age(relfrozenxid)</> to a value just a little more than the
<varname>vacuum_freeze_min_age</> setting
set <literal>age(relfrozenxid)</literal> to a value just a little more than the
<varname>vacuum_freeze_min_age</varname> setting
that was used (more by the number of transactions started since the
<command>VACUUM</> started). If no <structfield>relfrozenxid</>-advancing
<command>VACUUM</> is issued on the table until
<varname>autovacuum_freeze_max_age</> is reached, an autovacuum will soon
<command>VACUUM</command> started). If no <structfield>relfrozenxid</structfield>-advancing
<command>VACUUM</command> is issued on the table until
<varname>autovacuum_freeze_max_age</varname> is reached, an autovacuum will soon
be forced for the table.
</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".
</programlisting>
(A manual <command>VACUUM</> should fix the problem, as suggested by the
hint; but note that the <command>VACUUM</> must be performed by a
(A manual <command>VACUUM</command> should fix the problem, as suggested by the
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
be able to advance the database's <structfield>datfrozenxid</>.)
be able to advance the database's <structfield>datfrozenxid</structfield>.)
If these warnings are
ignored, the system will shut down and refuse to start any new
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
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,
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
page for details about using single-user mode.
</para>
@ -653,15 +653,15 @@ HINT: Stop the postmaster and vacuum that database in single-user mode.
</indexterm>
<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
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
row. Information about which transaction IDs are included in any
particular multixact ID is stored separately in
the <filename>pg_multixact</> subdirectory, and only the multixact ID
appears in the <structfield>xmax</> field in the tuple header.
the <filename>pg_multixact</filename> subdirectory, and only the multixact ID
appears in the <structfield>xmax</structfield> field in the tuple header.
Like transaction IDs, multixact IDs are implemented as a
32-bit counter and corresponding storage, all of which requires
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>
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
<xref linkend="guc-vacuum-multixact-freeze-min-age">
by a different value, which can be the zero value, a single
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.
If this value is older than
<xref linkend="guc-vacuum-multixact-freeze-table-age">, 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
be skipped. <function>mxid_age()</> can be used on
<structname>pg_class</>.<structfield>relminmxid</> to find its age.
be skipped. <function>mxid_age()</function> can be used on
<structname>pg_class</structname>.<structfield>relminmxid</structfield> to find its age.
</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.
Eventually, as all tables in all databases are scanned and their
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>
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
<firstterm>autovacuum launcher</firstterm>, which is in charge of starting
<firstterm>autovacuum worker</firstterm> processes for all databases. The
launcher will distribute the work across time, attempting to start one
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
<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
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.
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
autovacuum workers' activity.
</para>
@ -761,7 +761,7 @@ HINT: Stop the postmaster and vacuum that database in single-user mode.
</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
vacuumed (this also applies to those tables whose freeze max age has
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
<command>UPDATE</command> and <command>DELETE</command> operation. (It
is only semi-accurate because some information might be lost under heavy
load.) If the <structfield>relfrozenxid</> value of the table is more
than <varname>vacuum_freeze_table_age</> transactions old, an aggressive
load.) If the <structfield>relfrozenxid</structfield> value of the table is more
than <varname>vacuum_freeze_table_age</varname> transactions old, an aggressive
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.
</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
total I/O impact on the system is the same regardless of the number
of workers actually running. However, any workers processing tables whose
per-table <literal>autovacuum_vacuum_cost_delay</> or
<literal>autovacuum_vacuum_cost_limit</> storage parameters have been set
per-table <literal>autovacuum_vacuum_cost_delay</literal> or
<literal>autovacuum_vacuum_cost_limit</literal> storage parameters have been set
are not considered in the balancing algorithm.
</para>
</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
often preferable to execute an index rebuild with a sequence of
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
resulting index is valid, the original index can then be replaced by
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>
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
problems. However, the log output tends to be voluminous
(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
period of time.
</para>
<para>
If you simply direct the <systemitem>stderr</> of
If you simply direct the <systemitem>stderr</systemitem> of
<command>postgres</command> into a
file, you will have log output, but
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>
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
setting the configuration parameter <varname>logging_collector</> to
<literal>true</> in <filename>postgresql.conf</>. The control
setting the configuration parameter <varname>logging_collector</varname> to
<literal>true</literal> in <filename>postgresql.conf</filename>. The control
parameters for this program are described in <xref
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.
</para>
@ -934,10 +934,10 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu
tool included in the <productname>Apache</productname> distribution
can be used with <productname>PostgreSQL</productname>. To do this,
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
<command>pg_ctl</>, then <systemitem>stderr</>
is already redirected to <systemitem>stdout</>, so you just need a
<command>pg_ctl</command>, then <systemitem>stderr</systemitem>
is already redirected to <systemitem>stdout</systemitem>, so you just need a
pipe command, for example:
<programlisting>
@ -947,12 +947,12 @@ pg_ctl start | rotatelogs /var/log/pgsql_log 86400
<para>
Another production-grade approach to managing log output is to
send it to <application>syslog</> and let
<application>syslog</> deal with file rotation. To do this, set the
configuration parameter <varname>log_destination</> to <literal>syslog</>
(to log to <application>syslog</> only) in
<filename>postgresql.conf</>. Then you can send a <literal>SIGHUP</literal>
signal to the <application>syslog</> daemon whenever you want to force it
send it to <application>syslog</application> and let
<application>syslog</application> deal with file rotation. To do this, set the
configuration parameter <varname>log_destination</varname> to <literal>syslog</literal>
(to log to <application>syslog</application> only) in
<filename>postgresql.conf</filename>. Then you can send a <literal>SIGHUP</literal>
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
rotation, the <application>logrotate</application> program can be
configured to work with log files from
@ -960,12 +960,12 @@ pg_ctl start | rotatelogs /var/log/pgsql_log 86400
</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
just when you need them the most. Also, on <productname>Linux</>,
<application>syslog</> will flush each message to disk, yielding poor
performance. (You can use a <quote><literal>-</></> at the start of the file name
in the <application>syslog</> configuration file to disable syncing.)
just when you need them the most. Also, on <productname>Linux</productname>,
<application>syslog</application> will flush each message to disk, yielding poor
performance. (You can use a <quote><literal>-</literal></quote> at the start of the file name
in the <application>syslog</application> configuration file to disable syncing.)
</para>
<para>

View File

@ -3,7 +3,7 @@
<chapter id="managing-databases">
<title>Managing Databases</title>
<indexterm zone="managing-databases"><primary>database</></>
<indexterm zone="managing-databases"><primary>database</primary></indexterm>
<para>
Every instance of a running <productname>PostgreSQL</productname>
@ -26,7 +26,7 @@
(<quote>database objects</quote>). Generally, every database
object (tables, functions, etc.) belongs to one and only one
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
accurately, a database is a collection of schemas and the schemas
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
connections it opens to the same or other databases. Databases are
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
for the most part unaware of each other, it is therefore
recommended to put them into separate databases. If the projects
@ -53,23 +53,23 @@
</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
<command>DROP DATABASE</> command
<command>DROP DATABASE</command> command
(see <xref linkend="manage-ag-dropdb">).
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>
SELECT datname FROM pg_database;
</synopsis>
The <xref linkend="app-psql"> program's <literal>\l</> meta-command
and <option>-l</> command-line option are also useful for listing the
The <xref linkend="app-psql"> program's <literal>\l</literal> meta-command
and <option>-l</option> command-line option are also useful for listing the
existing databases.
</para>
<note>
<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.
</para>
</note>
@ -78,10 +78,10 @@ SELECT datname FROM pg_database;
<sect1 id="manage-ag-createdb">
<title>Creating a Database</title>
<indexterm><primary>CREATE DATABASE</></>
<indexterm><primary>CREATE DATABASE</primary></indexterm>
<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
linkend="server-start">).
</para>
@ -90,9 +90,9 @@ SELECT datname FROM pg_database;
Databases are created with the SQL command
<xref linkend="sql-createdatabase">:
<synopsis>
CREATE DATABASE <replaceable>name</>;
CREATE DATABASE <replaceable>name</replaceable>;
</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
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
@ -107,25 +107,25 @@ CREATE DATABASE <replaceable>name</>;
<para>
Since you need to be connected to the database server in order to
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
<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
database is called
<literal>postgres</>.<indexterm><primary>postgres</></> So to
create the first <quote>ordinary</> database you can connect to
<literal>postgres</>.
<literal>postgres</literal>.<indexterm><primary>postgres</primary></indexterm> So to
create the first <quote>ordinary</quote> database you can connect to
<literal>postgres</literal>.
</para>
<para>
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
new database is created within the
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,
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
appear in <xref linkend="manage-ag-templatedbs">.
</para>
@ -133,17 +133,17 @@ CREATE DATABASE <replaceable>name</>;
<para>
As a convenience, there is a program you can
execute from the shell to create new databases,
<command>createdb</>.<indexterm><primary>createdb</></>
<command>createdb</command>.<indexterm><primary>createdb</primary></indexterm>
<synopsis>
createdb <replaceable class="parameter">dbname</replaceable>
</synopsis>
<command>createdb</> does no magic. It connects to the <literal>postgres</>
database and issues the <command>CREATE DATABASE</> command,
<command>createdb</command> does no magic. It connects to the <literal>postgres</literal>
database and issues the <command>CREATE DATABASE</command> command,
exactly as described above.
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.
</para>
@ -160,11 +160,11 @@ createdb <replaceable class="parameter">dbname</replaceable>
configure and manage it themselves. To achieve that, use one of the
following commands:
<programlisting>
CREATE DATABASE <replaceable>dbname</> OWNER <replaceable>rolename</>;
CREATE DATABASE <replaceable>dbname</replaceable> OWNER <replaceable>rolename</replaceable>;
</programlisting>
from the SQL environment, or:
<programlisting>
createdb -O <replaceable>rolename</> <replaceable>dbname</>
createdb -O <replaceable>rolename</replaceable> <replaceable>dbname</replaceable>
</programlisting>
from the shell.
Only the superuser is allowed to create a database for
@ -176,55 +176,55 @@ createdb -O <replaceable>rolename</> <replaceable>dbname</>
<title>Template Databases</title>
<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
<literal>template1</>.<indexterm><primary>template1</></> Thus that
database is the <quote>template</> from which new databases are
made. If you add objects to <literal>template1</>, these objects
<literal>template1</literal>.<indexterm><primary>template1</primary></indexterm> Thus that
database is the <quote>template</quote> from which new databases are
made. If you add objects to <literal>template1</literal>, these objects
will be copied into subsequently created user databases. This
behavior allows site-local modifications to the standard set of
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
action being taken when those databases are created.
</para>
<para>
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
<literal>template1</>, that is, only the standard objects
<literal>template1</literal>, that is, only the standard objects
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
initialized. By instructing
<command>CREATE DATABASE</> to copy <literal>template0</> instead
of <literal>template1</>, you can create a <quote>virgin</> user
<command>CREATE DATABASE</command> to copy <literal>template0</literal> instead
of <literal>template1</literal>, you can create a <quote>virgin</quote> user
database that contains none of the site-local additions in
<literal>template1</>. This is particularly handy when restoring a
<literal>pg_dump</> dump: the dump script should be restored in a
<literal>template1</literal>. This is particularly handy when restoring a
<literal>pg_dump</literal> dump: the dump script should be restored in a
virgin database to ensure that one recreates the correct contents
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>
Another common reason for copying <literal>template0</> instead
of <literal>template1</> is that new encoding and locale settings
can be specified when copying <literal>template0</>, whereas a copy
of <literal>template1</> must use the same settings it does.
This is because <literal>template1</> might contain encoding-specific
or locale-specific data, while <literal>template0</> is known not to.
Another common reason for copying <literal>template0</literal> instead
of <literal>template1</literal> is that new encoding and locale settings
can be specified when copying <literal>template0</literal>, whereas a copy
of <literal>template1</literal> must use the same settings it does.
This is because <literal>template1</literal> might contain encoding-specific
or locale-specific data, while <literal>template0</literal> is known not to.
</para>
<para>
To create a database by copying <literal>template0</literal>, use:
<programlisting>
CREATE DATABASE <replaceable>dbname</> TEMPLATE template0;
CREATE DATABASE <replaceable>dbname</replaceable> TEMPLATE template0;
</programlisting>
from the SQL environment, or:
<programlisting>
createdb -T template0 <replaceable>dbname</>
createdb -T template0 <replaceable>dbname</replaceable>
</programlisting>
from the shell.
</para>
@ -232,49 +232,49 @@ createdb -T template0 <replaceable>dbname</>
<para>
It is possible to create additional template databases, and indeed
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
a general-purpose <quote><command>COPY DATABASE</command></quote> facility.
The principal limitation is that no other sessions can be connected to
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
are prevented.
</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
<literal>datallowconn</literal>. <literal>datistemplate</literal>
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
cloned by any user with <literal>CREATEDB</> privileges; if it is not set,
<command>CREATE DATABASE</command>. If this flag is set, the database can be
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.
If <literal>datallowconn</literal> is false, then no new connections
to that database will be allowed (but existing sessions are not terminated
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>
should always be marked with <literal>datistemplate = true</>.
should always be marked with <literal>datistemplate = true</literal>.
</para>
<note>
<para>
<literal>template1</> and <literal>template0</> do not have any special
status beyond the fact that the name <literal>template1</> is the default
source database name for <command>CREATE DATABASE</>.
For example, one could drop <literal>template1</> and recreate it from
<literal>template0</> without any ill effects. This course of action
<literal>template1</literal> and <literal>template0</literal> do not have any special
status beyond the fact that the name <literal>template1</literal> is the default
source database name for <command>CREATE DATABASE</command>.
For example, one could drop <literal>template1</literal> and recreate it from
<literal>template0</literal> without any ill effects. This course of action
might be advisable if one has carelessly added a bunch of junk in
<literal>template1</>. (To delete <literal>template1</literal>,
it must have <literal>pg_database.datistemplate = false</>.)
<literal>template1</literal>. (To delete <literal>template1</literal>,
it must have <literal>pg_database.datistemplate = false</literal>.)
</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
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>
</note>
</sect1>
@ -284,7 +284,7 @@ createdb -T template0 <replaceable>dbname</>
<para>
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
default values for many of these settings.
</para>
@ -305,8 +305,8 @@ ALTER DATABASE mydb SET geqo TO off;
session started.
Note that users can still alter this setting during their sessions; it
will only be the default. To undo any such setting, use
<literal>ALTER DATABASE <replaceable>dbname</> RESET
<replaceable>varname</></literal>.
<literal>ALTER DATABASE <replaceable>dbname</replaceable> RESET
<replaceable>varname</replaceable></literal>.
</para>
</sect1>
@ -315,9 +315,9 @@ ALTER DATABASE mydb SET geqo TO off;
<para>
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>
DROP DATABASE <replaceable>name</>;
DROP DATABASE <replaceable>name</replaceable>;
</synopsis>
Only the owner of the database, or
a superuser, can drop a database. Dropping a database removes all objects
@ -329,19 +329,19 @@ DROP DATABASE <replaceable>name</>;
<para>
You cannot execute the <command>DROP DATABASE</command> command
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.
<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.
</para>
<para>
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>
dropdb <replaceable class="parameter">dbname</replaceable>
</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.)
</para>
</sect1>
@ -354,7 +354,7 @@ dropdb <replaceable class="parameter">dbname</replaceable>
</indexterm>
<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
database objects can be stored. Once created, a tablespace can be referred
to by name when creating database objects.
@ -362,7 +362,7 @@ dropdb <replaceable class="parameter">dbname</replaceable>
<para>
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
cluster was initialized runs out of space and cannot be extended,
a tablespace can be created on a different partition and used
@ -397,12 +397,12 @@ dropdb <replaceable class="parameter">dbname</replaceable>
<para>
To define a tablespace, use the <xref
linkend="sql-createtablespace">
command, for example:<indexterm><primary>CREATE TABLESPACE</></>:
command, for example:<indexterm><primary>CREATE TABLESPACE</primary></indexterm>:
<programlisting>
CREATE TABLESPACE fastspace LOCATION '/ssd1/postgresql/data';
</programlisting>
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
directory. The location must not be on removable or transient storage,
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
tablespace per logical file system, since you cannot control the location
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
system. It just stores files in the directories you tell it to use.
</para>
@ -423,15 +423,15 @@ CREATE TABLESPACE fastspace LOCATION '/ssd1/postgresql/data';
<para>
Creation of the tablespace itself must be done as a database superuser,
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>
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
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>
CREATE TABLE foo(i int) TABLESPACE space1;
</programlisting>
@ -443,9 +443,9 @@ CREATE TABLE foo(i int) TABLESPACE space1;
SET default_tablespace = space1;
CREATE TABLE foo(i int);
</programlisting>
When <varname>default_tablespace</> is set to anything but an empty
string, it supplies an implicit <literal>TABLESPACE</> clause for
<command>CREATE TABLE</> and <command>CREATE INDEX</> commands that
When <varname>default_tablespace</varname> is set to anything but an empty
string, it supplies an implicit <literal>TABLESPACE</literal> clause for
<command>CREATE TABLE</command> and <command>CREATE INDEX</command> commands that
do not have an explicit one.
</para>
@ -463,9 +463,9 @@ CREATE TABLE foo(i int);
The tablespace associated with a database is used to store the system
catalogs of that database. Furthermore, it is the default tablespace
used for tables, indexes, and temporary files created within the database,
if no <literal>TABLESPACE</> clause is given and no other selection is
specified by <varname>default_tablespace</> or
<varname>temp_tablespaces</> (as appropriate).
if no <literal>TABLESPACE</literal> clause is given and no other selection is
specified by <varname>default_tablespace</varname> or
<varname>temp_tablespaces</varname> (as appropriate).
If a database is created without specifying a tablespace for it,
it uses the same tablespace as the template database it is copied from.
</para>
@ -473,12 +473,12 @@ CREATE TABLE foo(i int);
<para>
Two tablespaces are automatically created when the database cluster
is initialized. The
<literal>pg_global</> tablespace is used for shared system catalogs. The
<literal>pg_default</> tablespace is the default tablespace of the
<literal>template1</> and <literal>template0</> databases (and, therefore,
<literal>pg_global</literal> tablespace is used for shared system catalogs. The
<literal>pg_default</literal> tablespace is the default tablespace of the
<literal>template1</literal> and <literal>template0</literal> databases (and, therefore,
will be the default tablespace for other databases as well, unless
overridden by a <literal>TABLESPACE</> clause in <command>CREATE
DATABASE</>).
overridden by a <literal>TABLESPACE</literal> clause in <command>CREATE
DATABASE</command>).
</para>
<para>
@ -501,25 +501,25 @@ CREATE TABLE foo(i int);
<synopsis>
SELECT spcname FROM pg_tablespace;
</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.
</para>
<para>
<productname>PostgreSQL</> makes use of symbolic links
<productname>PostgreSQL</productname> makes use of symbolic links
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.
</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.
Although not recommended, it is possible to adjust the tablespace
layout by hand by redefining these links. Under no circumstances perform
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</>
catalog with the new locations. (If you do not, <literal>pg_dump</> will
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</literal> will
continue to output the old tablespace locations.)
</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
does not allow phantom reads. Stricter behavior is permitted by the
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
following subsections.
</para>
@ -317,7 +317,7 @@
<firstterm>Read Committed</firstterm> is the default isolation
level in <productname>PostgreSQL</productname>. When a transaction
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
data or changes committed during query execution by concurrent
transactions. In effect, a <command>SELECT</command> query sees
@ -345,7 +345,7 @@
updating the originally found row. If the first updater commits, the
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
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
search condition. If so, the second updater proceeds with its operation
using the updated version of the row. In the case of
@ -355,19 +355,19 @@
</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
will either insert or update. Unless there are unrelated errors, one of
those two outcomes is guaranteed. If a conflict originates in another
transaction whose effects are not yet visible to the <command>INSERT
</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.
</para>
<para>
<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
to the <command>INSERT</command> snapshot. Again, this is only
the case in Read Committed mode.
@ -416,10 +416,10 @@ COMMIT;
The <command>DELETE</command> will have no effect even though
there is a <literal>website.hits = 10</literal> row before and
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>
obtains a lock, the new row value is no longer <literal>10</> but
<literal>11</>, which no longer matches the criteria.
obtains a lock, the new row value is no longer <literal>10</literal> but
<literal>11</literal>, which no longer matches the criteria.
</para>
<para>
@ -427,7 +427,7 @@ COMMIT;
that includes all transactions committed up to that instant,
subsequent commands in the same transaction will see the effects
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.
</para>
@ -472,9 +472,9 @@ COMMIT;
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
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
<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
other transactions that committed after their own transaction started.
</para>
@ -587,7 +587,7 @@ ERROR: could not serialize access due to concurrent update
<para>
As an example,
consider a table <structname>mytab</>, initially containing:
consider a table <structname>mytab</structname>, initially containing:
<screen>
class | value
-------+-------
@ -600,14 +600,14 @@ ERROR: could not serialize access due to concurrent update
<screen>
SELECT SUM(value) FROM mytab WHERE class = 1;
</screen>
and then inserts the result (30) as the <structfield>value</> in a
new row with <structfield>class</><literal> = 2</>. Concurrently, serializable
and then inserts the result (30) as the <structfield>value</structfield> in a
new row with <structfield>class</structfield><literal> = 2</literal>. Concurrently, serializable
transaction B computes:
<screen>
SELECT SUM(value) FROM mytab WHERE class = 2;
</screen>
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,
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
@ -639,11 +639,11 @@ ERROR: could not serialize access due to read/write dependencies among transact
<para>
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
the result of a previous read from a concurrent transaction, had it run
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
among concurrent Serializable transactions which in certain combinations
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
transaction. These will show up in the
<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
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
combined into fewer coarser-grained locks (e.g., page locks) during the
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
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.
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
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
often need to be kept past transaction commit, until overlapping read
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
the restart of transactions which are terminated with a serialization
failure, but balanced against the cost and blocking involved in use of
explicit locks and <literal>SELECT FOR UPDATE</> or <literal>SELECT FOR
SHARE</>, Serializable transactions are the best performance choice
explicit locks and <literal>SELECT FOR UPDATE</literal> or <literal>SELECT FOR
SHARE</literal>, Serializable transactions are the best performance choice
for some environments.
</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
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
@ -709,7 +709,7 @@ ERROR: could not serialize access due to read/write dependencies among transact
constraint violations caused by conflicts with overlapping Serializable
transactions even after explicitly checking that the key isn't present
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,
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
@ -727,7 +727,7 @@ ERROR: could not serialize access due to read/write dependencies among transact
<itemizedlist>
<listitem>
<para>
Declare transactions as <literal>READ ONLY</> when possible.
Declare transactions as <literal>READ ONLY</literal> when possible.
</para>
</listitem>
<listitem>
@ -754,8 +754,8 @@ ERROR: could not serialize access due to read/write dependencies among transact
</listitem>
<listitem>
<para>
Eliminate explicit locks, <literal>SELECT FOR UPDATE</>, and
<literal>SELECT FOR SHARE</> where no longer needed due to the
Eliminate explicit locks, <literal>SELECT FOR UPDATE</literal>, and
<literal>SELECT FOR SHARE</literal> where no longer needed due to the
protections automatically provided by Serializable transactions.
</para>
</listitem>
@ -801,7 +801,7 @@ ERROR: could not serialize access due to read/write dependencies among transact
most <productname>PostgreSQL</productname> commands automatically
acquire locks of appropriate modes to ensure that referenced
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
obtains an exclusive lock on the table to enforce that.)
</para>
@ -860,7 +860,7 @@ ERROR: could not serialize access due to read/write dependencies among transact
<para>
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.
</para>
</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
<literal>ACCESS SHARE</literal> locks on any other referenced
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>
</listitem>
</varlistentry>
@ -920,13 +920,13 @@ ERROR: could not serialize access due to read/write dependencies among transact
EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
<literal>ACCESS EXCLUSIVE</literal> lock modes.
This mode protects a table against
concurrent schema changes and <command>VACUUM</> runs.
concurrent schema changes and <command>VACUUM</command> runs.
</para>
<para>
Acquired by <command>VACUUM</command> (without <option>FULL</option>),
<command>ANALYZE</>, <command>CREATE INDEX CONCURRENTLY</>,
<command>CREATE STATISTICS</> and
<command>ANALYZE</command>, <command>CREATE INDEX CONCURRENTLY</command>,
<command>CREATE STATISTICS</command> and
<command>ALTER TABLE VALIDATE</command> and other
<command>ALTER TABLE</command> variants (for full details see
<xref linkend="SQL-ALTERTABLE">).
@ -1016,12 +1016,12 @@ ERROR: could not serialize access due to read/write dependencies among transact
</para>
<para>
Acquired by the <command>DROP TABLE</>,
Acquired by the <command>DROP TABLE</command>,
<command>TRUNCATE</command>, <command>REINDEX</command>,
<command>CLUSTER</command>, <command>VACUUM FULL</command>,
and <command>REFRESH MATERIALIZED VIEW</command> (without
<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
<command>LOCK TABLE</command> statements that do not specify
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
lock is acquired after establishing a savepoint, the lock is released
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
<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.
</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
same row,
and will then lock and return the updated row (or no row, if the
row was deleted). Within a <literal>REPEATABLE READ</> or
<literal>SERIALIZABLE</> transaction,
row was deleted). Within a <literal>REPEATABLE READ</literal> or
<literal>SERIALIZABLE</literal> transaction,
however, an error will be thrown if a row to be locked has changed
since the transaction started. For further discussion see
<xref linkend="applevel-consistency">.
</para>
<para>
The <literal>FOR UPDATE</> lock mode
is also acquired by any <command>DELETE</> on a row, and also by an
<command>UPDATE</> that modifies the values on certain columns. Currently,
the set of columns considered for the <command>UPDATE</> case are those that
The <literal>FOR UPDATE</literal> lock mode
is also acquired by any <command>DELETE</command> on a row, and also by an
<command>UPDATE</command> that modifies the values on certain columns. Currently,
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
indexes and expressional indexes are not considered), but this may change
in the future.
@ -1228,11 +1228,11 @@ ERROR: could not serialize access due to read/write dependencies among transact
</term>
<listitem>
<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
<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
<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>
</listitem>
</varlistentry>
@ -1243,12 +1243,12 @@ ERROR: could not serialize access due to read/write dependencies among transact
</term>
<listitem>
<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
row. A shared lock blocks other transactions from performing
<command>UPDATE</command>, <command>DELETE</command>,
<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
<command>SELECT FOR KEY SHARE</command>.
</para>
@ -1262,13 +1262,13 @@ ERROR: could not serialize access due to read/write dependencies among transact
<listitem>
<para>
Behaves similarly to <literal>FOR SHARE</literal>, except that the
lock is weaker: <literal>SELECT FOR UPDATE</> is blocked, but not
<literal>SELECT FOR NO KEY UPDATE</>. A key-shared lock blocks
lock is weaker: <literal>SELECT FOR UPDATE</literal> is blocked, but not
<literal>SELECT FOR NO KEY UPDATE</literal>. A key-shared lock blocks
other transactions from performing <command>DELETE</command> or
any <command>UPDATE</command> that changes the key values, but not
other <command>UPDATE</>, and neither does it prevent
<command>SELECT FOR NO KEY UPDATE</>, <command>SELECT FOR SHARE</>,
or <command>SELECT FOR KEY SHARE</>.
other <command>UPDATE</command>, and neither does it prevent
<command>SELECT FOR NO KEY UPDATE</command>, <command>SELECT FOR SHARE</command>,
or <command>SELECT FOR KEY SHARE</command>.
</para>
</listitem>
</varlistentry>
@ -1357,7 +1357,7 @@ ERROR: could not serialize access due to read/write dependencies among transact
<para>
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
acquires an exclusive lock on table A and then tries to acquire
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>
<productname>PostgreSQL</productname> provides a means for
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
correctly. Advisory locks can be useful for locking strategies
that are an awkward fit for the MVCC model.
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.
While a flag stored in a table could be used for the same purpose,
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>
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
expressions are evaluated. For example:
<screen>
@ -1518,7 +1518,7 @@ SELECT pg_advisory_lock(q.id) FROM
) q; -- ok
</screen>
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
that the application was not expecting, and hence would fail to release
(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
framework which automatically retries transactions which are rolled
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
transaction isolation level is used, either inadvertently or to
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
a careful person might wish to lock all tables needed for the check,
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
transaction.
</para>
@ -1675,8 +1675,8 @@ SELECT pg_advisory_lock(q.id) FROM
transaction predates obtaining the lock, it might predate some now-committed
changes in the table. A repeatable read transaction's snapshot is actually
frozen at the start of its first query or data-modification command
(<literal>SELECT</>, <literal>INSERT</>,
<literal>UPDATE</>, or <literal>DELETE</>), so
(<literal>SELECT</literal>, <literal>INSERT</literal>,
<literal>UPDATE</literal>, or <literal>DELETE</literal>), so
it is possible to obtain locks explicitly before the snapshot is
frozen.
</para>

View File

@ -7,12 +7,12 @@
<title>For the Translator</title>
<para>
<productname>PostgreSQL</>
<productname>PostgreSQL</productname>
programs (server and client) can issue their messages in
your favorite language &mdash; if the messages have been translated.
Creating and maintaining translated message sets needs the help of
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
to do this. This section explains how to help.
</para>
@ -170,8 +170,8 @@ make init-po
This will create a file
<filename><replaceable>progname</replaceable>.pot</filename>.
(<filename>.pot</filename> to distinguish it from PO files that
are <quote>in production</quote>. The <literal>T</> stands for
<quote>template</>.)
are <quote>in production</quote>. The <literal>T</literal> stands for
<quote>template</quote>.)
Copy this file to
<filename><replaceable>language</replaceable>.po</filename> and
edit it. To make it known that the new language is available,
@ -234,7 +234,7 @@ make update-po
<listitem>
<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
format specifiers in the same order. Sometimes the natural
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>
This section describes how to implement native language support in a
program or library that is part of the
<productname>PostgreSQL</> distribution.
<productname>PostgreSQL</productname> distribution.
Currently, it only applies to C programs.
</para>
@ -447,7 +447,7 @@ fprintf(stderr, gettext("panic level %d\n"), lvl);
printf("Files were %s.\n", flag ? "copied" : "removed");
</programlisting>
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
better to duplicate a little code so that each message to be
translated is a coherent whole. Only numbers, file names, and
@ -481,7 +481,7 @@ printf("number of copied files: %d", n);
<para>
If you really want to construct a properly pluralized message,
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:
<programlisting>
errmsg_plural("copied %d file",
@ -496,17 +496,17 @@ errmsg_plural("copied %d file",
are formatted per the format string as usual. (Normally, the
pluralization control value will also be one of the values to be
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
sees the two English forms as a group and has the opportunity to
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>
If you need to pluralize a message that isn't going directly to an
<function>errmsg</> or <function>errdetail</> report, you have to use
the underlying function <function>ngettext</>. See the gettext
<function>errmsg</function> or <function>errdetail</function> report, you have to use
the underlying function <function>ngettext</function>. See the gettext
documentation.
</para>
</listitem>

View File

@ -7,17 +7,17 @@
The following conventions are used in the synopsis of a command:
brackets (<literal>[</literal> and <literal>]</literal>) indicate
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>) 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.
</para>
<para>
Where it enhances the clarity, SQL commands are preceded by the
prompt <literal>=&gt;</>, and shell commands are preceded by the
prompt <literal>$</>. Normally, prompts are not shown, though.
prompt <literal>=&gt;</literal>, and shell commands are preceded by the
prompt <literal>$</literal>. Normally, prompts are not shown, though.
</para>
<para>

View File

@ -27,7 +27,7 @@
<title>Description</title>
<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
to be familiar with the database file structure, which is described in
<xref linkend="storage">.
@ -35,7 +35,7 @@
<note>
<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
be concerned with tables' filenode numbers (which are the file names
visible in the database directories). Be sure you understand the
@ -60,8 +60,8 @@
<variablelist>
<varlistentry>
<term><option>-f</option> <replaceable>filenode</></term>
<listitem><para>show info for table with filenode <replaceable>filenode</></para></listitem>
<term><option>-f</option> <replaceable>filenode</replaceable></term>
<listitem><para>show info for table with filenode <replaceable>filenode</replaceable></para></listitem>
</varlistentry>
<varlistentry>
@ -70,8 +70,8 @@
</varlistentry>
<varlistentry>
<term><option>-o</option> <replaceable>oid</></term>
<listitem><para>show info for table with OID <replaceable>oid</></para></listitem>
<term><option>-o</option> <replaceable>oid</replaceable></term>
<listitem><para>show info for table with OID <replaceable>oid</replaceable></para></listitem>
</varlistentry>
<varlistentry>
@ -93,13 +93,13 @@
</varlistentry>
<varlistentry>
<term><option>-t</option> <replaceable>tablename_pattern</></term>
<listitem><para>show info for table(s) matching <replaceable>tablename_pattern</></para></listitem>
<term><option>-t</option> <replaceable>tablename_pattern</replaceable></term>
<listitem><para>show info for table(s) matching <replaceable>tablename_pattern</replaceable></para></listitem>
</varlistentry>
<varlistentry>
<term><option>-V</></term>
<term><option>--version</></term>
<term><option>-V</option></term>
<term><option>--version</option></term>
<listitem>
<para>
Print the <application>oid2name</application> version and exit.
@ -115,8 +115,8 @@
</varlistentry>
<varlistentry>
<term><option>-?</></term>
<term><option>--help</></term>
<term><option>-?</option></term>
<term><option>--help</option></term>
<listitem>
<para>
Show help about <application>oid2name</application> command line
@ -133,27 +133,27 @@
<variablelist>
<varlistentry>
<term><option>-d</option> <replaceable>database</></term>
<term><option>-d</option> <replaceable>database</replaceable></term>
<listitem><para>database to connect to</para></listitem>
</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>
</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>
</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>
</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
is a security hazard)</para></listitem>
</varlistentry>
@ -163,27 +163,27 @@
<para>
To display specific tables, select which tables to show by
using <option>-o</>, <option>-f</> and/or <option>-t</>.
<option>-o</> takes an OID,
<option>-f</> takes a filenode,
and <option>-t</> takes a table name (actually, it's a <literal>LIKE</>
pattern, so you can use things like <literal>foo%</>).
using <option>-o</option>, <option>-f</option> and/or <option>-t</option>.
<option>-o</option> takes an OID,
<option>-f</option> takes a filenode,
and <option>-t</option> takes a table name (actually, it's a <literal>LIKE</literal>
pattern, so you can use things like <literal>foo%</literal>).
You can use as many
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
show objects in the database given by <option>-d</>.
show objects in the database given by <option>-d</option>.
</para>
<para>
If you don't give any of <option>-o</>, <option>-f</> or <option>-t</>,
but do give <option>-d</>, it will list all tables in the database
named by <option>-d</>. In this mode, the <option>-S</> and
<option>-i</> options control what gets listed.
If you don't give any of <option>-o</option>, <option>-f</option> or <option>-t</option>,
but do give <option>-d</option>, it will list all tables in the database
named by <option>-d</option>. In this mode, the <option>-S</option> and
<option>-i</option> options control what gets listed.
</para>
<para>
If you don't give <option>-d</> either, it will show a listing of database
OIDs. Alternatively you can give <option>-s</> to get a tablespace
If you don't give <option>-d</option> either, it will show a listing of database
OIDs. Alternatively you can give <option>-s</option> to get a tablespace
listing.
</para>
</refsect1>
@ -192,7 +192,7 @@
<title>Notes</title>
<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
for recovering from catastrophic database corruption situations.
</para>

View File

@ -8,7 +8,7 @@
</indexterm>
<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
debugging purposes. All of these functions may be used only by superusers.
</para>
@ -28,7 +28,7 @@
<listitem>
<para>
<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.
<replaceable>fork</replaceable> should be <literal>'main'</literal> for
the main data fork, <literal>'fsm'</literal> for the free space map,
@ -63,7 +63,7 @@
<listitem>
<para>
<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>
@ -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
</screen>
The returned columns correspond to the fields in the
<structname>PageHeaderData</> struct.
See <filename>src/include/storage/bufpage.h</> for details.
<structname>PageHeaderData</structname> struct.
See <filename>src/include/storage/bufpage.h</filename> for details.
</para>
<para>
@ -147,8 +147,8 @@ test=# SELECT page_checksum(get_raw_page('pg_class', 0), 0);
<screen>
test=# SELECT * FROM heap_page_items(get_raw_page('pg_class', 0));
</screen>
See <filename>src/include/storage/itemid.h</> and
<filename>src/include/access/htup_details.h</> for explanations of the fields
See <filename>src/include/storage/itemid.h</filename> and
<filename>src/include/access/htup_details.h</filename> for explanations of the fields
returned.
</para>
</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.
</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.
</para>
</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
8 | (0,8) | 12 | f | f | 2a 27 00 00
</screen>
In a B-tree leaf page, <structfield>ctid</> points to a heap tuple.
In an internal page, the block number part of <structfield>ctid</>
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</structfield>
points to another page in the index itself, while the offset part
(the second number) is ignored and is usually 1.
</para>
<para>
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
page's <quote>high key</quote>, meaning its <structfield>data</>
a non-zero value in the <structfield>btpo_next</structfield> field) is the
page's <quote>high key</quote>, meaning its <structfield>data</structfield>
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
key) is a <quote>minus infinity</quote> item, with no actual value
in its <structfield>data</> field. Such an item does have a valid
downlink in its <structfield>ctid</> field, however.
in its <structfield>data</structfield> field. Such an item does have a valid
downlink in its <structfield>ctid</structfield> field, however.
</para>
</listitem>
</varlistentry>
@ -345,7 +345,7 @@ test=# SELECT * FROM bt_page_items('pg_cast_oid_index', 1);
<listitem>
<para>
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
the last example could also be rewritten like this:
<screen>
@ -470,8 +470,8 @@ test=# SELECT * FROM brin_page_items(get_raw_page('brinidx', 5),
139 | 8 | 2 | f | f | f | {177 .. 264}
</screen>
The returned columns correspond to the fields in the
<structname>BrinMemTuple</> and <structname>BrinValues</> structs.
See <filename>src/include/access/brin_tuple.h</> for details.
<structname>BrinMemTuple</structname> and <structname>BrinValues</structname> structs.
See <filename>src/include/access/brin_tuple.h</filename> for details.
</para>
</listitem>
</varlistentry>

View File

@ -8,7 +8,7 @@
</indexterm>
<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
as parallel query. Many queries cannot benefit from parallel query, either
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
<literal>Gather Merge</literal> node will have exactly one
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
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
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
<literal>Gather</> node, it will run in parallel.
the <literal>Gather</literal> node itself; since that plan node is a child of the
<literal>Gather</literal> node, it will run in parallel.
</para>
<para>
<link linkend="using-explain">Using EXPLAIN</>, you can see the number of
workers chosen by the planner. When the <literal>Gather</> node is reached
<link linkend="using-explain">Using EXPLAIN</link>, you can see the number of
workers chosen by the planner. When the <literal>Gather</literal> node is reached
during query execution, the process which is implementing the user's
session will request a number of <link linkend="bgworker">background
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
that are available, so this can result in poor query performance. If this
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
<varname>max_parallel_workers_per_gather</varname> so that the planner
requests fewer workers.
@ -96,10 +96,10 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
<para>
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
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
order that may have existed.
</para>
@ -128,7 +128,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
<listitem>
<para>
<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.
</para>
</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
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
exception, the commands <literal>CREATE TABLE</>, <literal>SELECT
INTO</>, and <literal>CREATE MATERIALIZED VIEW</> which create a new
exception, the commands <literal>CREATE TABLE</literal>, <literal>SELECT
INTO</literal>, and <literal>CREATE MATERIALIZED VIEW</literal> which create a new
table and populate it can use a parallel plan.
</para>
</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
are several circumstances under which it will be impossible to execute
that plan in parallel at execution time. If this occurs, the leader
will execute the portion of the plan below the <literal>Gather</>
node entirely by itself, almost as if the <literal>Gather</> node were
will execute the portion of the plan below the <literal>Gather</literal>
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:
</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
than normal but would produce incorrect results. Instead, the parallel
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
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.
@ -281,14 +281,14 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
<itemizedlist>
<listitem>
<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
at a time, so that access to the table remains sequential.
</para>
</listitem>
<listitem>
<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
and builds a bitmap indicating which table blocks need to be visited.
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>
<para>
In a <emphasis>parallel index scan</> or <emphasis>parallel index-only
scan</>, the cooperating processes take turns reading data from the
In a <emphasis>parallel index scan</emphasis> or <emphasis>parallel index-only
scan</emphasis>, the cooperating processes take turns reading data from the
index. Currently, parallel index scans are supported only for
btree indexes. Each process will claim a single index block and will
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">
<title>Parallel Aggregation</title>
<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
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
as a <literal>Partial Aggregate</> node. Second, the partial results are
transferred to the leader via <literal>Gather</> or <literal>Gather
Merge</>. Finally, the leader re-aggregates the results across all
as a <literal>Partial Aggregate</literal> node. Second, the partial results are
transferred to the leader via <literal>Gather</literal> or <literal>Gather
Merge</literal>. Finally, the leader re-aggregates the results across all
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>
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
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
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
<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
query planner takes this into account during the planning process and is
unlikely to choose parallel aggregate in this scenario.
@ -371,14 +371,14 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
<para>
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
<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.
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
<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.
</para>
@ -417,13 +417,13 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
<para>
The planner classifies operations involved in a query as either
<firstterm>parallel safe</>, <firstterm>parallel restricted</>,
or <firstterm>parallel unsafe</>. A parallel safe operation is one which
<firstterm>parallel safe</firstterm>, <firstterm>parallel restricted</firstterm>,
or <firstterm>parallel unsafe</firstterm>. A parallel safe operation is one which
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
can be performed in the leader while parallel query is in use. Therefore,
parallel restricted operations can never occur below a <literal>Gather</>
or <literal>Gather Merge</> node, but can occur elsewhere in a plan which
parallel restricted operations can never occur below a <literal>Gather</literal>
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
be performed while parallel query is in use, not even in the leader.
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>
<para>
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>
</listitem>
<listitem>
<para>
Access to an <literal>InitPlan</> or correlated <literal>SubPlan</>.
Access to an <literal>InitPlan</literal> or correlated <literal>SubPlan</literal>.
</para>
</listitem>
</itemizedlist>
@ -475,23 +475,23 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
be parallel unsafe unless otherwise marked. When using
<xref linkend="sql-createfunction"> or
<xref linkend="sql-alterfunction">, markings can be set by specifying
<literal>PARALLEL SAFE</>, <literal>PARALLEL RESTRICTED</>, or
<literal>PARALLEL UNSAFE</> as appropriate. When using
<literal>PARALLEL SAFE</literal>, <literal>PARALLEL RESTRICTED</literal>, or
<literal>PARALLEL UNSAFE</literal> as appropriate. When using
<xref linkend="sql-createaggregate">, the
<literal>PARALLEL</> option can be specified with <literal>SAFE</>,
<literal>RESTRICTED</>, or <literal>UNSAFE</> as the corresponding value.
<literal>PARALLEL</literal> option can be specified with <literal>SAFE</literal>,
<literal>RESTRICTED</literal>, or <literal>UNSAFE</literal> as the corresponding value.
</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
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
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
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.
</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
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
as <literal>UNSAFE</>.
as <literal>UNSAFE</literal>.
</para>
<para>
@ -519,13 +519,13 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
<para>
Note that the query planner does not consider deferring the evaluation of
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
planner will not consider performing a scan of that table in the parallel
portion of a plan. In some cases, it would be
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
<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.
</para>

View File

@ -30,7 +30,7 @@
plan</firstterm> for each query it receives. Choosing the right
plan to match the query structure and the properties of the data
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
to see what query plan the planner creates for any query.
Plan-reading is an art that requires some experience to master,
@ -39,17 +39,17 @@
<para>
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
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.
</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.
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
(XML, JSON, or YAML) instead.
</para>
@ -58,12 +58,12 @@
<title><command>EXPLAIN</command> Basics</title>
<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
from a table. There are different types of scan nodes for different
table access methods: sequential scans, index scans, and bitmap index
scans. There are also non-table row sources, such as <literal>VALUES</>
clauses and set-returning functions in <literal>FROM</>, which have their
scans. There are also non-table row sources, such as <literal>VALUES</literal>
clauses and set-returning functions in <literal>FROM</literal>, which have their
own scan node types.
If the query requires joining, aggregation, sorting, or other
operations on the raw rows, then there will be additional nodes
@ -93,7 +93,7 @@ EXPLAIN SELECT * FROM tenk1;
</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
scan plan. The numbers that are quoted in parentheses are (left
to right):
@ -111,7 +111,7 @@ EXPLAIN SELECT * FROM tenk1;
Estimated total cost. This is stated on the assumption that the plan
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
available rows (see the <literal>LIMIT</> example below).
available rows (see the <literal>LIMIT</literal> example below).
</para>
</listitem>
@ -135,7 +135,7 @@ EXPLAIN SELECT * FROM tenk1;
cost parameters (see <xref linkend="runtime-config-query-constants">).
Traditional practice is to measure the costs in units of disk page
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
parameters.
</para>
@ -152,11 +152,11 @@ EXPLAIN SELECT * FROM tenk1;
</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
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
<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
actually returned, updated, or deleted by the query.
</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 *
<xref linkend="guc-seq-page-cost">) + (rows scanned *
<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.
</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>
EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 7000;
@ -200,21 +200,21 @@ EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 7000;
Filter: (unique1 &lt; 7000)
</screen>
Notice that the <command>EXPLAIN</> output shows the <literal>WHERE</>
clause being applied as a <quote>filter</> condition attached to the Seq
Notice that the <command>EXPLAIN</command> output shows the <literal>WHERE</literal>
clause being applied as a <quote>filter</quote> condition attached to the Seq
Scan plan node. This means that
the plan node checks the condition for each row it scans, and outputs
only the ones that pass the condition.
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
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
time spent checking the <literal>WHERE</> condition.
time spent checking the <literal>WHERE</literal> condition.
</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,
you will probably get a slightly different estimate; moreover, it can
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
node sorts the row locations identified by the index into physical order
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.)
</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>
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
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
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
slightly to reflect this extra checking.
</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>
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
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
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
to satisfy the <literal>ORDER BY</>.
to satisfy the <literal>ORDER BY</literal>.
</para>
<para>
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:
<screen>
@ -320,7 +320,7 @@ EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000;
</para>
<para>
Here is an example showing the effects of <literal>LIMIT</>:
Here is an example showing the effects of <literal>LIMIT</literal>:
<screen>
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>
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
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
@ -370,23 +370,23 @@ WHERE t1.unique1 &lt; 10 AND t1.unique2 = t2.unique2;
<para>
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
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
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
applying the <literal>WHERE</> clause <literal>unique1 &lt; 10</literal>
applying the <literal>WHERE</literal> clause <literal>unique1 &lt; 10</literal>
at that node.
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
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
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
<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,
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
scan, plus one repetition of the inner scan for each outer row (10 * 7.87,
here), plus a little CPU time for join processing.
@ -395,7 +395,7 @@ WHERE t1.unique1 &lt; 10 AND t1.unique2 = t2.unique2;
<para>
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
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.
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>
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,
but does not change either input scan.
</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
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
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
@ -435,8 +435,8 @@ WHERE t1.unique1 &lt; 10 AND t2.unique2 &lt; 10 AND t1.hundred &lt; t2.hundred;
<para>
When dealing with outer joins, you might see join plan nodes with both
<quote>Join Filter</> and plain <quote>Filter</> conditions attached.
Join Filter conditions come from the outer join's <literal>ON</> clause,
<quote>Join Filter</quote> and plain <quote>Filter</quote> conditions attached.
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
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
@ -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 is scanned and the hash table is probed for matches to each row.
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
rows from its outer child plan and searches the hash table for each one.
</para>
@ -497,9 +497,9 @@ WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2;
<para>
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
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.
(Sequential-scan-and-sort frequently beats an index scan for sorting many rows,
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
also <xref linkend="explicit-joins">.)
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>
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)
</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.
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.
</para>
@ -544,8 +544,8 @@ WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2;
<para>
It is possible to check the accuracy of the planner's estimates
by using <command>EXPLAIN</>'s <literal>ANALYZE</> option. With this
option, <command>EXPLAIN</> actually executes the query, and then displays
by using <command>EXPLAIN</command>'s <literal>ANALYZE</literal> option. With this
option, <command>EXPLAIN</command> actually executes the query, and then displays
the true row counts and true run time accumulated within each plan node,
along with the same estimates that a plain <command>EXPLAIN</command>
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>
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.
The thing that's usually most important to look for is whether the
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
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
<literal>loops</> value reports the
<literal>loops</literal> value reports the
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
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
executing the index scans on <literal>tenk2</>.
executing the index scans on <literal>tenk2</literal>.
</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.
For example, Sort and Hash nodes provide extra information:
@ -642,13 +642,13 @@ EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE ten &lt; 7;
</screen>
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,
is rejected by the filter condition.
</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
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
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
to do the exact containment test on those rows.
</para>
<para>
<command>EXPLAIN</> has a <literal>BUFFERS</> option that can be used with
<literal>ANALYZE</> to get even more run time statistics:
<command>EXPLAIN</command> has a <literal>BUFFERS</literal> option that can be used with
<literal>ANALYZE</literal> to get even more run time statistics:
<screen>
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
</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.
</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
runs the query, any side-effects will happen as usual, even though
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
roll the command back afterwards, for example:
@ -746,8 +746,8 @@ ROLLBACK;
</para>
<para>
As seen in this example, when the query is an <command>INSERT</>,
<command>UPDATE</>, or <command>DELETE</> command, the actual work of
As seen in this example, when the query is an <command>INSERT</command>,
<command>UPDATE</command>, or <command>DELETE</command> command, the actual work of
applying the table changes is done by a top-level Insert, Update,
or Delete plan node. The plan nodes underneath this node perform
the work of locating the old rows and/or computing the new data.
@ -762,7 +762,7 @@ ROLLBACK;
</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:
<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
annotated to show the specific target tables that will be updated, in the
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.)
</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
as the time to run any triggers that are fired, but it does not include
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
spent executing <literal>AFTER</> triggers is not counted there because
<literal>AFTER</> triggers are fired after completion of the whole plan.
spent executing <literal>AFTER</literal> triggers is not counted there because
<literal>AFTER</literal> triggers are fired after completion of the whole plan.
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
until end of transaction and are thus not considered at all by
<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.
Second, the measurement overhead added by <command>EXPLAIN
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
on your system.
</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,
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
@ -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
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
<literal>polygon_tbl</> example above.)
<literal>polygon_tbl</literal> example above.)
</para>
<para>
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
plan node execution is stopped short by a <literal>LIMIT</> or similar
effect. For example, in the <literal>LIMIT</> query we used before,
plan node execution is stopped short by a <literal>LIMIT</literal> or similar
effect. For example, in the <literal>LIMIT</literal> query we used before,
<screen>
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
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
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,
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
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
@ -948,9 +948,9 @@ WHERE relname LIKE 'tenk1%';
For efficiency reasons, <structfield>reltuples</structfield>
and <structfield>relpages</structfield> are not updated on-the-fly,
and so they usually contain somewhat out-of-date values.
They are updated by <command>VACUUM</>, <command>ANALYZE</>, and a
few DDL commands such as <command>CREATE INDEX</>. A <command>VACUUM</>
or <command>ANALYZE</> operation that does not scan the entire table
They are updated by <command>VACUUM</command>, <command>ANALYZE</command>, and a
few DDL commands such as <command>CREATE INDEX</command>. A <command>VACUUM</command>
or <command>ANALYZE</command> operation that does not scan the entire table
(which is commonly the case) will incrementally update the
<structfield>reltuples</structfield> count on the basis of the part
of the table it did scan, resulting in an approximate value.
@ -966,16 +966,16 @@ WHERE relname LIKE 'tenk1%';
<para>
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
<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
<literal>WHERE</> clause. The information used for this task is
<literal>WHERE</literal> clause. The information used for this task is
stored in the
<link linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link>
system catalog. Entries in <structname>pg_statistic</structname>
are updated by the <command>ANALYZE</> and <command>VACUUM
ANALYZE</> commands, and are always approximate even when freshly
are updated by the <command>ANALYZE</command> and <command>VACUUM
ANALYZE</command> commands, and are always approximate even when freshly
updated.
</para>
@ -1020,17 +1020,17 @@ WHERE tablename = 'road';
Note that two rows are displayed for the same column, one corresponding
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
(<literal>inherited</>=<literal>f</>).
(<literal>inherited</literal>=<literal>f</literal>).
</para>
<para>
The amount of information stored in <structname>pg_statistic</structname>
by <command>ANALYZE</>, in particular the maximum number of entries in the
<structfield>most_common_vals</> and <structfield>histogram_bounds</>
by <command>ANALYZE</command>, in particular the maximum number of entries in the
<structfield>most_common_vals</structfield> and <structfield>histogram_bounds</structfield>
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
<xref linkend="guc-default-statistics-target"> configuration variable.
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.
Regular statistics, because of their per-individual-column nature,
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
such information.
</para>
@ -1081,7 +1081,7 @@ WHERE tablename = 'road';
Because the number of possible column combinations is very large,
it's impractical to compute multivariate statistics automatically.
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.
</para>
@ -1116,12 +1116,12 @@ WHERE tablename = 'road';
<para>
The simplest kind of extended statistics tracks <firstterm>functional
dependencies</>, a concept used in definitions of database normal forms.
We say that column <structfield>b</> is functionally dependent on
column <structfield>a</> if knowledge of the value of
<structfield>a</> is sufficient to determine the value
of <structfield>b</>, that is there are no two rows having the same value
of <structfield>a</> but different values of <structfield>b</>.
dependencies</firstterm>, a concept used in definitions of database normal forms.
We say that column <structfield>b</structfield> is functionally dependent on
column <structfield>a</structfield> if knowledge of the value of
<structfield>a</structfield> is sufficient to determine the value
of <structfield>b</structfield>, that is there are no two rows having the same value
of <structfield>a</structfield> but different values of <structfield>b</structfield>.
In a fully normalized database, functional dependencies should exist
only on primary keys and superkeys. However, in practice many data sets
are not fully normalized for various reasons; intentional
@ -1142,15 +1142,15 @@ WHERE tablename = 'road';
</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
degree of dependency between all sets of columns would be prohibitively
expensive, so data collection is limited to those groups of columns
appearing together in a statistics object defined with
the <literal>dependencies</> option. It is advisable to create
<literal>dependencies</> statistics only for column groups that are
the <literal>dependencies</literal> option. It is advisable to create
<literal>dependencies</literal> statistics only for column groups that are
strongly correlated, to avoid unnecessary overhead in both
<command>ANALYZE</> and later query planning.
<command>ANALYZE</command> and later query planning.
</para>
<para>
@ -1189,7 +1189,7 @@ SELECT stxname, stxkeys, stxdependencies
simple equality conditions that compare columns to constant values.
They are not used to improve estimates for equality conditions
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>
@ -1200,7 +1200,7 @@ SELECT stxname, stxkeys, stxdependencies
<programlisting>
SELECT * FROM zipcodes WHERE city = 'San Francisco' AND zip = '94105';
</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
the same assumption about
<programlisting>
@ -1233,11 +1233,11 @@ SELECT * FROM zipcodes WHERE city = 'San Francisco' AND zip = '90210';
</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
this for every possible column grouping, so data is collected only for
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
listed columns.
</para>
@ -1267,17 +1267,17 @@ nd | {"1, 2": 33178, "1, 5": 33178, "2, 5": 27435, "1, 2, 5": 33178}
</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
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>
</sect3>
</sect2>
</sect1>
<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">
<primary>join</primary>
@ -1286,7 +1286,7 @@ nd | {"1, 2": 33178, "1, 5": 33178, "2, 5": 27435, "1, 2, 5": 33178}
<para>
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.
</para>
@ -1297,13 +1297,13 @@ SELECT * FROM a, b, c WHERE a.id = b.id AND b.ref = c.id;
</programlisting>
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
the <literal>WHERE</> condition <literal>a.id = b.id</>, and then
joins C to this joined table, using the other <literal>WHERE</>
the <literal>WHERE</literal> condition <literal>a.id = b.id</literal>, and then
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.
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 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
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
@ -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);
</programlisting>
it is valid to join A to either B or C first. Currently, only
<literal>FULL JOIN</> completely constrains the join order. Most
practical cases involving <literal>LEFT JOIN</> or <literal>RIGHT JOIN</>
<literal>FULL JOIN</literal> completely constrains the join order. Most
practical cases involving <literal>LEFT JOIN</literal> or <literal>RIGHT JOIN</literal>
can be rearranged to some extent.
</para>
<para>
Explicit inner join syntax (<literal>INNER JOIN</>, <literal>CROSS
JOIN</>, or unadorned <literal>JOIN</>) is semantically the same as
listing the input relations in <literal>FROM</>, so it does not
Explicit inner join syntax (<literal>INNER JOIN</literal>, <literal>CROSS
JOIN</literal>, or unadorned <literal>JOIN</literal>) is semantically the same as
listing the input relations in <literal>FROM</literal>, so it does not
constrain the join order.
</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
<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:
<programlisting>
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 JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);
</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
is not worth worrying about for only three tables, but it can be a
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>
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.
(Other possible values are discussed below.)
</para>
<para>
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
within items of a plain <literal>FROM</> list. For example, consider:
cut search time, because it's OK to use <literal>JOIN</literal> operators
within items of a plain <literal>FROM</literal> list. For example, consider:
<programlisting>
SELECT * FROM a CROSS JOIN b, c, d, e WHERE ...;
</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,
but doesn't constrain its choices otherwise. In this example, the
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
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,
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
is recommended.
</para>
@ -1415,22 +1415,22 @@ FROM x, y,
WHERE somethingelse;
</programlisting>
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
will try to collapse the subquery into the parent, yielding:
<programlisting>
SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
</programlisting>
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
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
problem replacing two separate three-way join problems. Because of the
exponential growth of the number of possibilities, this makes a big
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</>
<literal>FROM</> items would result in the parent
problems by not collapsing a subquery if more than <varname>from_collapse_limit</varname>
<literal>FROM</literal> items would result in the parent
query. You can trade off planning time against quality of plan by
adjusting this run-time parameter up or down.
</para>
@ -1439,11 +1439,11 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
<xref linkend="guc-from-collapse-limit"> and <xref
linkend="guc-join-collapse-limit">
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
you would either set <varname>join_collapse_limit</> equal to
<varname>from_collapse_limit</> (so that explicit joins and subqueries
act similarly) or set <varname>join_collapse_limit</> to 1 (if you want
you would either set <varname>join_collapse_limit</varname> equal to
<varname>from_collapse_limit</varname> (so that explicit joins and subqueries
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
differently if you are trying to fine-tune the trade-off between planning
time and run time.
@ -1468,7 +1468,7 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
</indexterm>
<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
SQL, this means issuing <command>BEGIN</command> at the start and
<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
some of the overhead of repeatedly parsing and planning
<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.
</para>
<para>
Note that loading a large number of rows 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.
</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
containing the newly loaded data will be removed anyway.
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.
</para>
@ -1557,7 +1557,7 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
<para>
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
the constraints. Again, there is a trade-off between data load
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
cause the trigger event queue to overflow available memory, leading to
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
the constraint isn't acceptable, the only other recourse may be to split
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">
configuration variable when loading large amounts of data can
lead to improved performance. This will help to speed up <command>CREATE
INDEX</> commands and <command>ALTER TABLE ADD FOREIGN KEY</> commands.
It won't do much for <command>COPY</> itself, so this advice is
INDEX</command> commands and <command>ALTER TABLE ADD FOREIGN KEY</command> commands.
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.
</para>
</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
amount of incremental WAL data. To prevent incremental WAL logging
while loading, disable archiving and streaming replication, by setting
<xref linkend="guc-wal-level"> to <literal>minimal</>,
<xref linkend="guc-archive-mode"> to <literal>off</>, and
<xref linkend="guc-wal-level"> to <literal>minimal</literal>,
<xref linkend="guc-archive-mode"> to <literal>off</literal>, and
<xref linkend="guc-max-wal-senders"> to zero.
But note that changing these settings requires a server restart.
</para>
@ -1628,8 +1628,8 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
process the WAL data,
doing this will actually make certain commands faster, because they
are designed not to write WAL at all if <varname>wal_level</varname>
is <literal>minimal</>. (They can guarantee crash safety more cheaply
by doing an <function>fsync</> at the end than by writing WAL.)
is <literal>minimal</literal>. (They can guarantee crash safety more cheaply
by doing an <function>fsync</function> at the end than by writing WAL.)
This applies to the following commands:
<itemizedlist>
<listitem>
@ -1683,21 +1683,21 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
</sect2>
<sect2 id="populate-pg-dump">
<title>Some Notes About <application>pg_dump</></title>
<title>Some Notes About <application>pg_dump</application></title>
<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
<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
<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
<application>psql</> or using <application>pg_restore</> to load
from a <application>pg_dump</> archive file.)
<application>psql</application> or using <application>pg_restore</application> to load
from a <application>pg_dump</application> archive file.)
</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
load data before creating indexes and foreign keys. So in this case
several guidelines are handled automatically. What is left
@ -1713,10 +1713,10 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
<listitem>
<para>
If using WAL archiving or streaming replication, consider disabling
them during the restore. To do that, set <varname>archive_mode</>
to <literal>off</>,
<varname>wal_level</varname> to <literal>minimal</>, and
<varname>max_wal_senders</> to zero before loading the dump.
them during the restore. To do that, set <varname>archive_mode</varname>
to <literal>off</literal>,
<varname>wal_level</varname> to <literal>minimal</literal>, and
<varname>max_wal_senders</varname> to zero before loading the dump.
Afterwards, set them back to the right values and take a fresh
base backup.
</para>
@ -1724,49 +1724,49 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
<listitem>
<para>
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
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.
</para>
</listitem>
<listitem>
<para>
Consider whether the whole dump should be restored as a single
transaction. To do that, pass the <option>-1</> or
<option>--single-transaction</> command-line option to
<application>psql</> or <application>pg_restore</>. When using this
transaction. To do that, pass the <option>-1</option> or
<option>--single-transaction</option> command-line option to
<application>psql</application> or <application>pg_restore</application>. When using this
mode, even the smallest of errors will rollback the entire restore,
possibly discarding many hours of processing. Depending on how
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.
</para>
</listitem>
<listitem>
<para>
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.
</para>
</listitem>
<listitem>
<para>
Run <command>ANALYZE</> afterwards.
Run <command>ANALYZE</command> afterwards.
</para>
</listitem>
</itemizedlist>
</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
keys.
<footnote>
<para>
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
validation, and so it is possible to insert bad data if you use it.
</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
<varname>maintenance_work_mem</varname>; rather, you'd do that while
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">
and <xref linkend="autovacuum"> for more information.
</para>
@ -1808,7 +1808,7 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
<listitem>
<para>
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
available memory (and perhaps swap).
</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
need to force <acronym>WAL</acronym> writes to disk on every
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>
</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
linkend="guc-checkpoint-timeout">; this reduces the frequency
of checkpoints, but increases the storage requirements of
<filename>/pg_wal</>.
<filename>/pg_wal</filename>.
</para>
</listitem>

View File

@ -37,7 +37,7 @@
</para>
<table id="pgbuffercache-columns">
<title><structname>pg_buffercache</> Columns</title>
<title><structname>pg_buffercache</structname> Columns</title>
<tgroup cols="4">
<thead>
@ -54,7 +54,7 @@
<entry><structfield>bufferid</structfield></entry>
<entry><type>integer</type></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>
@ -83,7 +83,7 @@
<entry><type>smallint</type></entry>
<entry></entry>
<entry>Fork number within the relation; see
<filename>include/common/relpath.h</></entry>
<filename>include/common/relpath.h</filename></entry>
</row>
<row>
@ -120,22 +120,22 @@
<para>
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.
</para>
<para>
Because the cache is shared by all the databases, there will normally be
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
trying to join against <structname>pg_class</>, it's a good idea to
restrict the join to rows having <structfield>reldatabase</> equal to
trying to join against <structname>pg_class</structname>, it's a good idea to
restrict the join to rows having <structfield>reldatabase</structfield> equal to
the current database's OID or zero.
</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
data that the view will display.
This ensures that the view produces a consistent set of results, while not

View File

@ -13,8 +13,8 @@
</indexterm>
<para>
The <filename>pgcrypto</> module provides cryptographic functions for
<productname>PostgreSQL</>.
The <filename>pgcrypto</filename> module provides cryptographic functions for
<productname>PostgreSQL</productname>.
</para>
<sect2>
@ -33,19 +33,19 @@ digest(data bytea, type text) returns bytea
</synopsis>
<para>
Computes a binary hash of the given <parameter>data</>.
<parameter>type</> is the algorithm to use.
Computes a binary hash of the given <parameter>data</parameter>.
<parameter>type</parameter> is the algorithm to use.
Standard algorithms are <literal>md5</literal>, <literal>sha1</literal>,
<literal>sha224</literal>, <literal>sha256</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
<xref linkend="pgcrypto-with-without-openssl">.
</para>
<para>
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>
CREATE OR REPLACE FUNCTION sha1(bytea) returns text AS $$
SELECT encode(digest($1, 'sha1'), 'hex')
@ -67,12 +67,12 @@ hmac(data bytea, key text, type text) returns bytea
</synopsis>
<para>
Calculates hashed MAC for <parameter>data</> with key <parameter>key</>.
<parameter>type</> is the same as in <function>digest()</>.
Calculates hashed MAC for <parameter>data</parameter> with key <parameter>key</parameter>.
<parameter>type</parameter> is the same as in <function>digest()</function>.
</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
altering data and also changing the hash to match.
</para>
@ -88,14 +88,14 @@ hmac(data bytea, key text, type text) returns bytea
<title>Password Hashing Functions</title>
<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.
<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.
</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:
</para>
@ -108,7 +108,7 @@ hmac(data bytea, key text, type text) returns bytea
</listitem>
<listitem>
<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.
This is also an additional defense against reversing the algorithm.
</para>
@ -134,7 +134,7 @@ hmac(data bytea, key text, type text) returns bytea
</para>
<table id="pgcrypto-crypt-algorithms">
<title>Supported Algorithms for <function>crypt()</></title>
<title>Supported Algorithms for <function>crypt()</function></title>
<tgroup cols="6">
<thead>
<row>
@ -148,7 +148,7 @@ hmac(data bytea, key text, type text) returns bytea
</thead>
<tbody>
<row>
<entry><literal>bf</></entry>
<entry><literal>bf</literal></entry>
<entry>72</entry>
<entry>yes</entry>
<entry>128</entry>
@ -156,7 +156,7 @@ hmac(data bytea, key text, type text) returns bytea
<entry>Blowfish-based, variant 2a</entry>
</row>
<row>
<entry><literal>md5</></entry>
<entry><literal>md5</literal></entry>
<entry>unlimited</entry>
<entry>no</entry>
<entry>48</entry>
@ -164,7 +164,7 @@ hmac(data bytea, key text, type text) returns bytea
<entry>MD5-based crypt</entry>
</row>
<row>
<entry><literal>xdes</></entry>
<entry><literal>xdes</literal></entry>
<entry>8</entry>
<entry>yes</entry>
<entry>24</entry>
@ -172,7 +172,7 @@ hmac(data bytea, key text, type text) returns bytea
<entry>Extended DES</entry>
</row>
<row>
<entry><literal>des</></entry>
<entry><literal>des</literal></entry>
<entry>8</entry>
<entry>no</entry>
<entry>12</entry>
@ -184,7 +184,7 @@ hmac(data bytea, key text, type text) returns bytea
</table>
<sect3>
<title><function>crypt()</></title>
<title><function>crypt()</function></title>
<indexterm>
<primary>crypt</primary>
@ -195,10 +195,10 @@ crypt(password text, salt text) returns text
</synopsis>
<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
<function>gen_salt()</> to generate a new <parameter>salt</> value.
To check a password, pass the stored hash value as <parameter>salt</>,
<function>gen_salt()</function> to generate a new <parameter>salt</parameter> value.
To check a password, pass the stored hash value as <parameter>salt</parameter>,
and test whether the result matches the stored value.
</para>
<para>
@ -212,12 +212,12 @@ UPDATE ... SET pswhash = crypt('new password', gen_salt('md5'));
<programlisting>
SELECT (pswhash = crypt('entered password', pswhash)) AS pswmatch FROM ... ;
</programlisting>
This returns <literal>true</> if the entered password is correct.
This returns <literal>true</literal> if the entered password is correct.
</para>
</sect3>
<sect3>
<title><function>gen_salt()</></title>
<title><function>gen_salt()</function></title>
<indexterm>
<primary>gen_salt</primary>
@ -228,30 +228,30 @@ gen_salt(type text [, iter_count integer ]) returns text
</synopsis>
<para>
Generates a new random salt string for use in <function>crypt()</>.
The salt string also tells <function>crypt()</> which algorithm to use.
Generates a new random salt string for use in <function>crypt()</function>.
The salt string also tells <function>crypt()</function> which algorithm to use.
</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>,
<literal>md5</literal> and <literal>bf</literal>.
</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.
The higher the count, the more time it takes to hash
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
&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.
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">.
</para>
<table id="pgcrypto-icfc-table">
<title>Iteration Counts for <function>crypt()</></title>
<title>Iteration Counts for <function>crypt()</function></title>
<tgroup cols="4">
<thead>
<row>
@ -263,13 +263,13 @@ gen_salt(type text [, iter_count integer ]) returns text
</thead>
<tbody>
<row>
<entry><literal>xdes</></entry>
<entry><literal>xdes</literal></entry>
<entry>725</entry>
<entry>1</entry>
<entry>16777215</entry>
</row>
<row>
<entry><literal>bf</></entry>
<entry><literal>bf</literal></entry>
<entry>6</entry>
<entry>4</entry>
<entry>31</entry>
@ -310,63 +310,63 @@ gen_salt(type text [, iter_count integer ]) returns text
<row>
<entry>Algorithm</entry>
<entry>Hashes/sec</entry>
<entry>For <literal>[a-z]</></entry>
<entry>For <literal>[A-Za-z0-9]</></entry>
<entry>Duration relative to <literal>md5 hash</></entry>
<entry>For <literal>[a-z]</literal></entry>
<entry>For <literal>[A-Za-z0-9]</literal></entry>
<entry>Duration relative to <literal>md5 hash</literal></entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>crypt-bf/8</></entry>
<entry><literal>crypt-bf/8</literal></entry>
<entry>1792</entry>
<entry>4 years</entry>
<entry>3927 years</entry>
<entry>100k</entry>
</row>
<row>
<entry><literal>crypt-bf/7</></entry>
<entry><literal>crypt-bf/7</literal></entry>
<entry>3648</entry>
<entry>2 years</entry>
<entry>1929 years</entry>
<entry>50k</entry>
</row>
<row>
<entry><literal>crypt-bf/6</></entry>
<entry><literal>crypt-bf/6</literal></entry>
<entry>7168</entry>
<entry>1 year</entry>
<entry>982 years</entry>
<entry>25k</entry>
</row>
<row>
<entry><literal>crypt-bf/5</></entry>
<entry><literal>crypt-bf/5</literal></entry>
<entry>13504</entry>
<entry>188 days</entry>
<entry>521 years</entry>
<entry>12.5k</entry>
</row>
<row>
<entry><literal>crypt-md5</></entry>
<entry><literal>crypt-md5</literal></entry>
<entry>171584</entry>
<entry>15 days</entry>
<entry>41 years</entry>
<entry>1k</entry>
</row>
<row>
<entry><literal>crypt-des</></entry>
<entry><literal>crypt-des</literal></entry>
<entry>23221568</entry>
<entry>157.5 minutes</entry>
<entry>108 days</entry>
<entry>7</entry>
</row>
<row>
<entry><literal>sha1</></entry>
<entry><literal>sha1</literal></entry>
<entry>37774272</entry>
<entry>90 minutes</entry>
<entry>68 days</entry>
<entry>4</entry>
</row>
<row>
<entry><literal>md5</> (hash)</entry>
<entry><literal>md5</literal> (hash)</entry>
<entry>150085504</entry>
<entry>22.5 minutes</entry>
<entry>17 days</entry>
@ -388,18 +388,18 @@ gen_salt(type text [, iter_count integer ]) returns text
</listitem>
<listitem>
<para>
<literal>crypt-des</> and <literal>crypt-md5</> algorithm numbers are
taken from John the Ripper v1.6.38 <literal>-test</> output.
<literal>crypt-des</literal> and <literal>crypt-md5</literal> algorithm numbers are
taken from John the Ripper v1.6.38 <literal>-test</literal> output.
</para>
</listitem>
<listitem>
<para>
<literal>md5 hash</> numbers are from mdcrack 1.2.
<literal>md5 hash</literal> numbers are from mdcrack 1.2.
</para>
</listitem>
<listitem>
<para>
<literal>sha1</> numbers are from lcrack-20031130-beta.
<literal>sha1</literal> numbers are from lcrack-20031130-beta.
</para>
</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
loops over 1000 8-character passwords. That way I can show the speed
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
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.)
</para>
</listitem>
@ -436,7 +436,7 @@ gen_salt(type text [, iter_count integer ]) returns text
</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>
<itemizedlist>
<listitem>
@ -459,7 +459,7 @@ gen_salt(type text [, iter_count integer ]) returns text
<listitem>
<para>
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
key.
</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
</synopsis>
<para>
Encrypt <parameter>data</> with a symmetric PGP key <parameter>psw</>.
The <parameter>options</> parameter can contain option settings,
Encrypt <parameter>data</parameter> with a symmetric PGP key <parameter>psw</parameter>.
The <parameter>options</parameter> parameter can contain option settings,
as described below.
</para>
</sect3>
@ -565,12 +565,12 @@ pgp_sym_decrypt_bytea(msg bytea, psw text [, options text ]) returns bytea
Decrypt a symmetric-key-encrypted PGP message.
</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
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>
The <parameter>options</> parameter can contain option settings,
The <parameter>options</parameter> parameter can contain option settings,
as described below.
</para>
</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
</synopsis>
<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.
</para>
<para>
The <parameter>options</> parameter can contain option settings,
The <parameter>options</parameter> parameter can contain option settings,
as described below.
</para>
</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
</synopsis>
<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.
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.
</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
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>
The <parameter>options</> parameter can contain option settings,
The <parameter>options</parameter> parameter can contain option settings,
as described below.
</para>
</sect3>
@ -644,7 +644,7 @@ pgp_pub_decrypt_bytea(msg bytea, key bytea [, psw text [, options text ]]) retur
pgp_key_id(bytea) returns text
</synopsis>
<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
an encrypted message.
</para>
@ -654,7 +654,7 @@ pgp_key_id(bytea) returns text
<itemizedlist>
<listitem>
<para>
<literal>SYMKEY</>
<literal>SYMKEY</literal>
</para>
<para>
The message is encrypted with a symmetric key.
@ -662,12 +662,12 @@ pgp_key_id(bytea) returns text
</listitem>
<listitem>
<para>
<literal>ANYKEY</>
<literal>ANYKEY</literal>
</para>
<para>
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
which one decrypts it. <filename>pgcrypto</> itself does not produce
which one decrypts it. <filename>pgcrypto</filename> itself does not produce
such messages.
</para>
</listitem>
@ -675,7 +675,7 @@ pgp_key_id(bytea) returns text
<para>
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,
to see which fits &mdash; like handling <literal>ANYKEY</>.
to see which fits &mdash; like handling <literal>ANYKEY</literal>.
</para>
</sect3>
@ -700,8 +700,8 @@ dearmor(data text) returns bytea
</para>
<para>
If the <parameter>keys</> and <parameter>values</> arrays are specified,
an <firstterm>armor header</> is added to the armored format for each
If the <parameter>keys</parameter> and <parameter>values</parameter> arrays are specified,
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
be of the same length. The keys and values cannot contain any non-ASCII
characters.
@ -719,8 +719,8 @@ dearmor(data text) returns bytea
pgp_armor_headers(data text, key out text, value out text) returns setof record
</synopsis>
<para>
<function>pgp_armor_headers()</> extracts the armor headers from
<parameter>data</>. The return value is a set of rows with two columns,
<function>pgp_armor_headers()</function> extracts the armor headers from
<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,
they are treated as UTF-8.
</para>
@ -924,7 +924,7 @@ gpg --gen-key
</programlisting>
</para>
<para>
The preferred key type is <quote>DSA and Elgamal</>.
The preferred key type is <quote>DSA and Elgamal</quote>.
</para>
<para>
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>
</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
<literal>-a</literal> from the command.
</para>
@ -982,7 +982,7 @@ gpg -a --export-secret-keys KEYID > secret.key
<para>
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
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.
</para>
</listitem>
@ -1056,15 +1056,15 @@ decrypt_iv(data bytea, key bytea, iv bytea, type text) returns bytea
<parameter>type</parameter> string is:
<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>
where <replaceable>algorithm</> is one of:
where <replaceable>algorithm</replaceable> is one of:
<itemizedlist>
<listitem><para><literal>bf</literal> &mdash; Blowfish</para></listitem>
<listitem><para><literal>aes</literal> &mdash; AES (Rijndael-128)</para></listitem>
</itemizedlist>
and <replaceable>mode</> is one of:
and <replaceable>mode</replaceable> is one of:
<itemizedlist>
<listitem>
<para>
@ -1078,7 +1078,7 @@ decrypt_iv(data bytea, key bytea, iv bytea, type text) returns bytea
</para>
</listitem>
</itemizedlist>
and <replaceable>padding</> is one of:
and <replaceable>padding</replaceable> is one of:
<itemizedlist>
<listitem>
<para>
@ -1100,8 +1100,8 @@ encrypt(data, 'fooz', 'bf-cbc/pad:pkcs')
</programlisting>
</para>
<para>
In <function>encrypt_iv</> and <function>decrypt_iv</>, the
<parameter>iv</> parameter is the initial value for the CBC mode;
In <function>encrypt_iv</function> and <function>decrypt_iv</function>, the
<parameter>iv</parameter> parameter is the initial value for the CBC mode;
it is ignored for ECB.
It is clipped or padded with zeroes if not exactly block size.
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
</synopsis>
<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
draining the randomness generator pool.
</para>
@ -1143,7 +1143,7 @@ gen_random_uuid() returns uuid
<title>Configuration</title>
<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
affect it are <literal>--with-zlib</literal> and
<literal>--with-openssl</literal>.
@ -1253,9 +1253,9 @@ gen_random_uuid() returns uuid
<title>Security Limitations</title>
<para>
All <filename>pgcrypto</> functions run inside the database server.
All <filename>pgcrypto</filename> functions run inside the database server.
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:
</para>
@ -1276,7 +1276,7 @@ gen_random_uuid() returns uuid
The implementation does not resist
<ulink url="http://en.wikipedia.org/wiki/Side-channel_attack">side-channel
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.
</para>
</sect3>
@ -1342,7 +1342,7 @@ gen_random_uuid() returns uuid
</listitem>
<listitem>
<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>
<para><ulink url="http://kodu.ut.ee/~lipmaa/crypto/"></ulink></para>

View File

@ -8,7 +8,7 @@
</indexterm>
<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
<function>pg_freespace</function>, or two overloaded functions, to be
precise. The functions show the value recorded in the free space map for
@ -36,7 +36,7 @@
<listitem>
<para>
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>
</listitem>
</varlistentry>
@ -50,7 +50,7 @@
<listitem>
<para>
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.
</para>
</listitem>
@ -59,7 +59,7 @@
<para>
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.
</para>

View File

@ -11,11 +11,11 @@
The <filename>pg_prewarm</filename> module provides a convenient way
to load relation data into either the operating system buffer cache
or the <productname>PostgreSQL</productname> buffer cache. Prewarming
can be performed manually using the <filename>pg_prewarm</> function,
or can be performed automatically by including <literal>pg_prewarm</> in
can be performed manually using the <filename>pg_prewarm</filename> function,
or can be performed automatically by including <literal>pg_prewarm</literal> in
<xref linkend="guc-shared-preload-libraries">. In the latter case, the
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.
</para>
@ -77,10 +77,10 @@ autoprewarm_dump_now() RETURNS int8
</synopsis>
<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
after the next restart. The return value is the number of records written
to <filename>autoprewarm.blocks</>.
to <filename>autoprewarm.blocks</filename>.
</para>
</sect2>
@ -92,7 +92,7 @@ autoprewarm_dump_now() RETURNS int8
<term>
<varname>pg_prewarm.autoprewarm</varname> (<type>boolean</type>)
<indexterm>
<primary><varname>pg_prewarm.autoprewarm</> configuration parameter</primary>
<primary><varname>pg_prewarm.autoprewarm</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
@ -109,12 +109,12 @@ autoprewarm_dump_now() RETURNS int8
<term>
<varname>pg_prewarm.autoprewarm_interval</varname> (<type>int</type>)
<indexterm>
<primary><varname>pg_prewarm.autoprewarm_interval</> configuration parameter</primary>
<primary><varname>pg_prewarm.autoprewarm_interval</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<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
dumped at regular intervals, but only when the server is shut down.
</para>

View File

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

View File

@ -31,14 +31,14 @@
<title>Description</title>
<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
as a customizable template should you require specific modifications.
</para>
<para>
<application>pg_standby</> is designed to be a waiting
<varname>restore_command</>, which is needed to turn a standard
<application>pg_standby</application> is designed to be a waiting
<varname>restore_command</varname>, which is needed to turn a standard
archive recovery into a warm standby operation. Other
configuration is required as well, all of which is described in the main
server manual (see <xref linkend="warm-standby">).
@ -46,33 +46,33 @@
<para>
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:
<programlisting>
restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r'
restore_command = 'pg_standby <replaceable>archiveDir</replaceable> %f %p %r'
</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.
</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
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
crash-restart capability. Use of this parameter is appropriate if the
<replaceable>archivelocation</> is a transient staging area for this
particular standby server, but <emphasis>not</> when the
<replaceable>archivelocation</> is intended as a long-term WAL archive area.
<replaceable>archivelocation</replaceable> is a transient staging area for this
particular standby server, but <emphasis>not</emphasis> when the
<replaceable>archivelocation</replaceable> is intended as a long-term WAL archive area.
</para>
<para>
<application>pg_standby</application> assumes that
<replaceable>archivelocation</> is a directory readable by the
server-owning user. If <replaceable>restartwalfile</> (or <literal>-k</>)
<replaceable>archivelocation</replaceable> is a directory readable by the
server-owning user. If <replaceable>restartwalfile</replaceable> (or <literal>-k</literal>)
is specified,
the <replaceable>archivelocation</> directory must be writable too.
the <replaceable>archivelocation</replaceable> directory must be writable too.
</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:
<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
unapplied WAL it can be a long time before the standby server becomes
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>
</listitem>
</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 the archive that have not yet been applied will be ignored, and
all transactions in those files are lost. To trigger a fast failover,
create a trigger file and write the word <literal>fast</> into it.
<application>pg_standby</> can also be configured to execute a fast
create a trigger file and write the word <literal>fast</literal> into it.
<application>pg_standby</application> can also be configured to execute a fast
failover automatically if no new WAL file appears within a defined
interval.
</para>
@ -120,7 +120,7 @@ restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r'
<term><option>-c</option></term>
<listitem>
<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.
</para>
</listitem>
@ -130,7 +130,7 @@ restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r'
<term><option>-d</option></term>
<listitem>
<para>
Print lots of debug logging output on <filename>stderr</>.
Print lots of debug logging output on <filename>stderr</filename>.
</para>
</listitem>
</varlistentry>
@ -147,8 +147,8 @@ restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r'
<replaceable>restartwalfile</replaceable> is specified, since that
specification method is more accurate in determining the correct
archive cut-off point.
Use of this parameter is <emphasis>deprecated</> as of
<productname>PostgreSQL</> 8.3; it is safer and more efficient to
Use of this parameter is <emphasis>deprecated</emphasis> as of
<productname>PostgreSQL</productname> 8.3; it is safer and more efficient to
specify a <replaceable>restartwalfile</replaceable> parameter. A too
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
@ -158,12 +158,12 @@ restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r'
</varlistentry>
<varlistentry>
<term><option>-r</option> <replaceable>maxretries</></term>
<term><option>-r</option> <replaceable>maxretries</replaceable></term>
<listitem>
<para>
Set the maximum number of times to retry the copy command if
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,
we will wait 5 secs, 10 secs, then 15 secs before reporting
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>
<term><option>-s</option> <replaceable>sleeptime</></term>
<term><option>-s</option> <replaceable>sleeptime</replaceable></term>
<listitem>
<para>
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>
<term><option>-t</option> <replaceable>triggerfile</></term>
<term><option>-t</option> <replaceable>triggerfile</replaceable></term>
<listitem>
<para>
Specify a trigger file whose presence should cause failover.
It is recommended that you use a structured file name to
avoid confusion as to which server is being triggered
when multiple servers exist on the same system; for example
<filename>/tmp/pgsql.trigger.5432</>.
<filename>/tmp/pgsql.trigger.5432</filename>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-V</></term>
<term><option>--version</></term>
<term><option>-V</option></term>
<term><option>--version</option></term>
<listitem>
<para>
Print the <application>pg_standby</application> version and exit.
@ -209,7 +209,7 @@ restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r'
</varlistentry>
<varlistentry>
<term><option>-w</option> <replaceable>maxwaittime</></term>
<term><option>-w</option> <replaceable>maxwaittime</replaceable></term>
<listitem>
<para>
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>
<term><option>-?</></term>
<term><option>--help</></term>
<term><option>-?</option></term>
<term><option>--help</option></term>
<listitem>
<para>
Show help about <application>pg_standby</application> command line
@ -241,18 +241,18 @@ restore_command = 'pg_standby <replaceable>archiveDir</> %f %p %r'
<para>
<application>pg_standby</application> is designed to work with
<productname>PostgreSQL</> 8.2 and later.
<productname>PostgreSQL</productname> 8.2 and later.
</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
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
required. This option remains available in 8.3, but its use is deprecated.
</para>
<para>
<productname>PostgreSQL</> 8.4 provides the
<varname>recovery_end_command</> option. Without this option
<productname>PostgreSQL</productname> 8.4 provides the
<varname>recovery_end_command</varname> option. Without this option
a leftover trigger file can be hazardous.
</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'
</programlisting>
where the archive directory is physically located on the standby server,
so that the <varname>archive_command</> is accessing it across NFS,
but the files are local to the standby (enabling use of <literal>ln</>).
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</literal>).
This will:
<itemizedlist>
<listitem>
<para>
produce debugging output in <filename>standby.log</>
produce debugging output in <filename>standby.log</filename>
</para>
</listitem>
<listitem>
@ -293,7 +293,7 @@ recovery_end_command = 'rm -f /tmp/pgsql.trigger.5442'
<listitem>
<para>
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
</para>
</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'
</programlisting>
Note that backslashes need to be doubled in the
<varname>archive_command</>, but <emphasis>not</emphasis> in the
<varname>restore_command</> or <varname>recovery_end_command</>.
<varname>archive_command</varname>, but <emphasis>not</emphasis> in the
<varname>restore_command</varname> or <varname>recovery_end_command</varname>.
This will:
<itemizedlist>
<listitem>
<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>
</listitem>
<listitem>
<para>
produce debugging output in <filename>standby.log</>
produce debugging output in <filename>standby.log</filename>
</para>
</listitem>
<listitem>
@ -342,7 +342,7 @@ recovery_end_command = 'del C:\pgsql.trigger.5442'
<listitem>
<para>
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
</para>
</listitem>
@ -360,16 +360,16 @@ recovery_end_command = 'del C:\pgsql.trigger.5442'
</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
<application>pg_standby</application>. Therefore
<application>pg_standby</application> waits <replaceable>sleeptime</>
seconds once it sees the proper file size. GNUWin32's <literal>cp</>
<application>pg_standby</application> waits <replaceable>sleeptime</replaceable>
seconds once it sees the proper file size. GNUWin32's <literal>cp</literal>
sets the file size only after the file copy is complete.
</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
network.
</para>

View File

@ -13,20 +13,20 @@
</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
<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.
</para>
<para>
When <filename>pg_stat_statements</filename> is loaded, it tracks
statistics across all databases of the server. To access and manipulate
these statistics, the module provides a view, <structname>pg_stat_statements</>,
and the utility functions <function>pg_stat_statements_reset</> and
<function>pg_stat_statements</>. These are not available globally but
these statistics, the module provides a view, <structname>pg_stat_statements</structname>,
and the utility functions <function>pg_stat_statements_reset</function> and
<function>pg_stat_statements</function>. These are not available globally but
can be enabled for a specific database with
<command>CREATE EXTENSION pg_stat_statements</>.
<command>CREATE EXTENSION pg_stat_statements</command>.
</para>
<sect2>
@ -34,7 +34,7 @@
<para>
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
ID (up to the maximum number of distinct statements that the module
can track). The columns of the view are shown in
@ -42,7 +42,7 @@
</para>
<table id="pgstatstatements-columns">
<title><structname>pg_stat_statements</> Columns</title>
<title><structname>pg_stat_statements</structname> Columns</title>
<tgroup cols="4">
<thead>
@ -234,9 +234,9 @@
</para>
<para>
Plannable queries (that is, <command>SELECT</>, <command>INSERT</>,
<command>UPDATE</>, and <command>DELETE</>) are combined into a single
<structname>pg_stat_statements</> entry whenever they have identical query
Plannable queries (that is, <command>SELECT</command>, <command>INSERT</command>,
<command>UPDATE</command>, and <command>DELETE</command>) are combined into a single
<structname>pg_stat_statements</structname> entry whenever they have identical query
structures according to an internal hash calculation. Typically, two
queries will be considered the same for this purpose if they are
semantically equivalent except for the values of literal constants
@ -247,16 +247,16 @@
<para>
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
as <literal>$1</literal>, in the <structname>pg_stat_statements</>
as <literal>$1</literal>, in the <structname>pg_stat_statements</structname>
display.
The rest of the query text is that of the first query that had the
particular <structfield>queryid</> hash value associated with the
<structname>pg_stat_statements</> entry.
particular <structfield>queryid</structfield> hash value associated with the
<structname>pg_stat_statements</structname> entry.
</para>
<para>
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
hash collisions causing unrelated queries to be merged into one entry.
(This cannot happen for queries belonging to different users or databases,
@ -264,41 +264,41 @@
</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
also possible: queries with identical texts might appear as
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>
Consumers of <structname>pg_stat_statements</> may wish to use
<structfield>queryid</> (perhaps in combination with
<structfield>dbid</> and <structfield>userid</>) as a more stable
Consumers of <structname>pg_stat_statements</structname> may wish to use
<structfield>queryid</structfield> (perhaps in combination with
<structfield>dbid</structfield> and <structfield>userid</structfield>) as a more stable
and reliable identifier for each entry than its query text.
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
post-parse-analysis tree, its value is a function of, among other
things, the internal object identifiers appearing in this representation.
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
and recreated between the executions of the two queries.
The hashing process is also sensitive to differences in
machine architecture and other facets of the platform.
Furthermore, it is not safe to assume that <structfield>queryid</>
will be stable across major versions of <productname>PostgreSQL</>.
Furthermore, it is not safe to assume that <structfield>queryid</structfield>
will be stable across major versions of <productname>PostgreSQL</productname>.
</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
catalog metadata details stay exactly the same. Two servers
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
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
replicas. If in doubt, direct testing is recommended.
</para>
@ -306,13 +306,13 @@
<para>
The parameter symbols used to replace constants in
representative query texts start from the next number after the
highest <literal>$</><replaceable>n</> parameter in the original query
text, or <literal>$1</> if there was none. It's worth noting that in
highest <literal>$</literal><replaceable>n</replaceable> parameter in the original query
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
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
a <application>PL/pgSQL</> statement like <literal>SELECT i + 1 INTO j</>
would have representative text like <literal>SELECT i + $2</>.
a <application>PL/pgSQL</application> statement like <literal>SELECT i + 1 INTO j</literal>
would have representative text like <literal>SELECT i + $2</literal>.
</para>
<para>
@ -320,11 +320,11 @@
not consume shared memory. Therefore, even very lengthy query texts can
be stored successfully. However, if many long query texts are
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
the <structname>pg_stat_statements</> view will show
null <structfield>query</> fields, though the statistics associated with
each <structfield>queryid</> are preserved. If this happens, consider
the <structname>pg_stat_statements</structname> view will show
null <structfield>query</structfield> fields, though the statistics associated with
each <structfield>queryid</structfield> are preserved. If this happens, consider
reducing <varname>pg_stat_statements.max</varname> to prevent
recurrences.
</para>
@ -345,7 +345,7 @@
<listitem>
<para>
<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.
</para>
</listitem>
@ -363,17 +363,17 @@
<listitem>
<para>
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
the <function>pg_stat_statements</function> function directly, and by
specifying <literal>showtext := false</literal> have query text be
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
the overhead of repeatedly retrieving query texts of indeterminate
length. Such tools can instead cache the first query text observed
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
file, this approach may reduce physical I/O for repeated examination
of the <structname>pg_stat_statements</structname> data.
@ -396,7 +396,7 @@
<para>
<varname>pg_stat_statements.max</varname> is the maximum number of
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 is discarded.
The default value is 5000.
@ -414,11 +414,11 @@
<para>
<varname>pg_stat_statements.track</varname> controls which statements
are counted by the module.
Specify <literal>top</> to track top-level statements (those issued
directly by clients), <literal>all</> to also track nested statements
(such as statements invoked within functions), or <literal>none</> to
Specify <literal>top</literal> to track top-level statements (those issued
directly by clients), <literal>all</literal> to also track nested statements
(such as statements invoked within functions), or <literal>none</literal> to
disable statement statistics collection.
The default value is <literal>top</>.
The default value is <literal>top</literal>.
Only superusers can change this setting.
</para>
</listitem>
@ -433,9 +433,9 @@
<para>
<varname>pg_stat_statements.track_utility</varname> controls whether
utility commands are tracked by the module. Utility commands are
all those other than <command>SELECT</>, <command>INSERT</>,
<command>UPDATE</> and <command>DELETE</>.
The default value is <literal>on</>.
all those other than <command>SELECT</command>, <command>INSERT</command>,
<command>UPDATE</command> and <command>DELETE</command>.
The default value is <literal>on</literal>.
Only superusers can change this setting.
</para>
</listitem>
@ -450,10 +450,10 @@
<para>
<varname>pg_stat_statements.save</varname> specifies whether to
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.
The default value is <literal>on</>.
This parameter can only be set in the <filename>postgresql.conf</>
The default value is <literal>on</literal>.
This parameter can only be set in the <filename>postgresql.conf</filename>
file or on the server command line.
</para>
</listitem>
@ -464,11 +464,11 @@
The module requires additional shared memory proportional to
<varname>pg_stat_statements.max</varname>. Note that this
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>
These parameters must be set in <filename>postgresql.conf</>.
These parameters must be set in <filename>postgresql.conf</filename>.
Typical usage might be:
<programlisting>

View File

@ -30,13 +30,13 @@
<indexterm>
<primary>pgstattuple</primary>
</indexterm>
<function>pgstattuple(regclass) returns record</>
<function>pgstattuple(regclass) returns record</function>
</term>
<listitem>
<para>
<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
target relation's name (optionally schema-qualified) or OID.
For example:
@ -135,15 +135,15 @@ free_percent | 1.95
</para>
<para>
<function>pgstattuple</function> judges a tuple is <quote>dead</> if
<function>HeapTupleSatisfiesDirty</> returns false.
<function>pgstattuple</function> judges a tuple is <quote>dead</quote> if
<function>HeapTupleSatisfiesDirty</function> returns false.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<function>pgstattuple(text) returns record</>
<function>pgstattuple(text) returns record</function>
</term>
<listitem>
@ -161,7 +161,7 @@ free_percent | 1.95
<indexterm>
<primary>pgstatindex</primary>
</indexterm>
<function>pgstatindex(regclass) returns record</>
<function>pgstatindex(regclass) returns record</function>
</term>
<listitem>
@ -225,7 +225,7 @@ leaf_fragmentation | 0
<row>
<entry><structfield>internal_pages</structfield></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>
@ -264,14 +264,14 @@ leaf_fragmentation | 0
</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 +
empty_pages + deleted_pages</literal>, because it also includes the
index's metapage.
</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
instantaneous snapshot of the whole index.
</para>
@ -280,7 +280,7 @@ leaf_fragmentation | 0
<varlistentry>
<term>
<function>pgstatindex(text) returns record</>
<function>pgstatindex(text) returns record</function>
</term>
<listitem>
@ -298,7 +298,7 @@ leaf_fragmentation | 0
<indexterm>
<primary>pgstatginindex</primary>
</indexterm>
<function>pgstatginindex(regclass) returns record</>
<function>pgstatginindex(regclass) returns record</function>
</term>
<listitem>
@ -358,7 +358,7 @@ pending_tuples | 0
<indexterm>
<primary>pgstathashindex</primary>
</indexterm>
<function>pgstathashindex(regclass) returns record</>
<function>pgstathashindex(regclass) returns record</function>
</term>
<listitem>
@ -453,7 +453,7 @@ free_percent | 61.8005949100872
<indexterm>
<primary>pg_relpages</primary>
</indexterm>
<function>pg_relpages(regclass) returns bigint</>
<function>pg_relpages(regclass) returns bigint</function>
</term>
<listitem>
@ -466,7 +466,7 @@ free_percent | 61.8005949100872
<varlistentry>
<term>
<function>pg_relpages(text) returns bigint</>
<function>pg_relpages(text) returns bigint</function>
</term>
<listitem>
@ -484,7 +484,7 @@ free_percent | 61.8005949100872
<indexterm>
<primary>pgstattuple_approx</primary>
</indexterm>
<function>pgstattuple_approx(regclass) returns record</>
<function>pgstattuple_approx(regclass) returns record</function>
</term>
<listitem>

View File

@ -111,7 +111,7 @@
<entry><function>show_limit()</function><indexterm><primary>show_limit</primary></indexterm></entry>
<entry><type>real</type></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
two words for them to be considered similar enough to
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><type>real</type></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).
Returns the same value passed in (<emphasis>deprecated</emphasis>).
</entry>
@ -144,56 +144,56 @@
<tbody>
<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>
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
<varname>pg_trgm.similarity_threshold</>.
<varname>pg_trgm.similarity_threshold</varname>.
</entry>
</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>
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
current word similarity threshold set by
<varname>pg_trgm.word_similarity_threshold</> parameter.
<varname>pg_trgm.word_similarity_threshold</varname> parameter.
</entry>
</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>
Commutator of the <literal>&lt;%</> operator.
Commutator of the <literal>&lt;%</literal> operator.
</entry>
</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>
Returns the <quote>distance</> between the arguments, that is
one minus the <function>similarity()</> value.
Returns the <quote>distance</quote> between the arguments, that is
one minus the <function>similarity()</function> value.
</entry>
</row>
<row>
<entry>
<type>text</> <literal>&lt;&lt;-&gt;</literal> <type>text</>
<type>text</type> <literal>&lt;&lt;-&gt;</literal> <type>text</type>
</entry>
<entry><type>real</type></entry>
<entry>
Returns the <quote>distance</> between the arguments, that is
one minus the <function>word_similarity()</> value.
Returns the <quote>distance</quote> between the arguments, that is
one minus the <function>word_similarity()</function> value.
</entry>
</row>
<row>
<entry>
<type>text</> <literal>&lt;-&gt;&gt;</literal> <type>text</>
<type>text</type> <literal>&lt;-&gt;&gt;</literal> <type>text</type>
</entry>
<entry><type>real</type></entry>
<entry>
Commutator of the <literal>&lt;&lt;-&gt;</> operator.
Commutator of the <literal>&lt;&lt;-&gt;</literal> operator.
</entry>
</row>
</tbody>
@ -207,31 +207,31 @@
<variablelist>
<varlistentry id="guc-pgtrgm-similarity-threshold" xreflabel="pg_trgm.similarity_threshold">
<term>
<varname>pg_trgm.similarity_threshold</> (<type>real</type>)
<varname>pg_trgm.similarity_threshold</varname> (<type>real</type>)
<indexterm>
<primary><varname>pg_trgm.similarity_threshold</> configuration parameter</primary>
<primary><varname>pg_trgm.similarity_threshold</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<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).
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-pgtrgm-word-similarity-threshold" xreflabel="pg_trgm.word_similarity_threshold">
<term>
<varname>pg_trgm.word_similarity_threshold</> (<type>real</type>)
<varname>pg_trgm.word_similarity_threshold</varname> (<type>real</type>)
<indexterm>
<primary>
<varname>pg_trgm.word_similarity_threshold</> configuration parameter
<varname>pg_trgm.word_similarity_threshold</varname> configuration parameter
</primary>
</indexterm>
</term>
<listitem>
<para>
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).
</para>
</listitem>
@ -247,8 +247,8 @@
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 above-described similarity operators, and additionally support
trigram-based index searches for <literal>LIKE</>, <literal>ILIKE</>,
<literal>~</> and <literal>~*</> queries. (These indexes do not
trigram-based index searches for <literal>LIKE</literal>, <literal>ILIKE</literal>,
<literal>~</literal> and <literal>~*</literal> queries. (These indexes do not
support equality nor simple comparison operators, so you may need a
regular B-tree index too.)
</para>
@ -267,16 +267,16 @@ CREATE INDEX trgm_idx ON test_trgm USING GIN (t gin_trgm_ops);
</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
<programlisting>
SELECT t, similarity(t, '<replaceable>word</>') AS sml
SELECT t, similarity(t, '<replaceable>word</replaceable>') AS sml
FROM test_trgm
WHERE t % '<replaceable>word</>'
WHERE t % '<replaceable>word</replaceable>'
ORDER BY sml DESC, t;
</programlisting>
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
sets.
</para>
@ -284,7 +284,7 @@ SELECT t, similarity(t, '<replaceable>word</>') AS sml
<para>
A variant of the above query is
<programlisting>
SELECT t, t &lt;-&gt; '<replaceable>word</>' AS dist
SELECT t, t &lt;-&gt; '<replaceable>word</replaceable>' AS dist
FROM test_trgm
ORDER BY dist LIMIT 10;
</programlisting>
@ -294,16 +294,16 @@ SELECT t, t &lt;-&gt; '<replaceable>word</>' AS dist
</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:
<programlisting>
SELECT t, word_similarity('<replaceable>word</>', t) AS sml
SELECT t, word_similarity('<replaceable>word</replaceable>', t) AS sml
FROM test_trgm
WHERE '<replaceable>word</>' &lt;% t
WHERE '<replaceable>word</replaceable>' &lt;% t
ORDER BY sml DESC, t;
</programlisting>
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
even over very large data sets.
</para>
@ -311,7 +311,7 @@ SELECT t, word_similarity('<replaceable>word</>', t) AS sml
<para>
A variant of the above query is
<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
ORDER BY dist LIMIT 10;
</programlisting>
@ -321,8 +321,8 @@ SELECT t, '<replaceable>word</>' &lt;&lt;-&gt; t AS dist
<para>
Beginning in <productname>PostgreSQL</> 9.1, these index types also support
index searches for <literal>LIKE</> and <literal>ILIKE</>, for example
Beginning in <productname>PostgreSQL</productname> 9.1, these index types also support
index searches for <literal>LIKE</literal> and <literal>ILIKE</literal>, for example
<programlisting>
SELECT * FROM test_trgm WHERE t LIKE '%foo%bar';
</programlisting>
@ -333,9 +333,9 @@ SELECT * FROM test_trgm WHERE t LIKE '%foo%bar';
</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
(<literal>~</> and <literal>~*</> operators), for example
(<literal>~</literal> and <literal>~*</literal> operators), for example
<programlisting>
SELECT * FROM test_trgm WHERE t ~ '(foo|bar)';
</programlisting>
@ -347,7 +347,7 @@ SELECT * FROM test_trgm WHERE t ~ '(foo|bar)';
</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
scan.
</para>
@ -377,9 +377,9 @@ CREATE TABLE words AS SELECT word FROM
ts_stat('SELECT to_tsvector(''simple'', bodytext) FROM documents');
</programlisting>
where <structname>documents</> is a table that has a text field
<structfield>bodytext</> that we wish to search. The reason for using
the <literal>simple</> configuration with the <function>to_tsvector</>
where <structname>documents</structname> is a table that has a text field
<structfield>bodytext</structfield> that we wish to search. The reason for using
the <literal>simple</literal> configuration with the <function>to_tsvector</function>
function, instead of using a language-specific configuration,
is that we want a list of the original (unstemmed) words.
</para>
@ -399,7 +399,7 @@ CREATE INDEX words_idx ON words USING GIN (word gin_trgm_ops);
<note>
<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
it remains reasonably up-to-date with the document collection.
Keeping it exactly current is usually unnecessary.

View File

@ -8,7 +8,7 @@
</indexterm>
<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.
It also provides functions to check the integrity of a visibility map and to
force it to be rebuilt.
@ -28,13 +28,13 @@
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
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
can also cause these bits to disagree.
</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,
because they must read the relation's data blocks rather than only the
(much smaller) visibility map. Functions that check the relation's
@ -61,7 +61,7 @@
<para>
Returns the all-visible and all-frozen bits in the visibility map for
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>
</listitem>
</varlistentry>
@ -82,7 +82,7 @@
<listitem>
<para>
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.
</para>
</listitem>
@ -130,7 +130,7 @@
<para>
Truncates the visibility map for the given relation. This function 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
every page in the relation and rebuild the visibility map. (Until that
is done, queries will treat the visibility map as containing all zeroes.)

View File

@ -28,13 +28,13 @@
</indexterm>
<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.
The outputs shown are taken from version 8.3.
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
any new <command>ANALYZE</>.
any new <command>ANALYZE</command>.
</para>
<para>
@ -61,8 +61,8 @@ SELECT relpages, reltuples FROM pg_class WHERE relname = 'tenk1';
358 | 10000
</programlisting>
These numbers are current as of the last <command>VACUUM</> or
<command>ANALYZE</> on the table. The planner then fetches the
These numbers are current as of the last <command>VACUUM</command> or
<command>ANALYZE</command> on the table. The planner then fetches the
actual current number of pages in the table (this is a cheap operation,
not requiring a table scan). If that is different from
<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
<function>eqsel</function>. For equality estimation the histogram is
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
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>
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
(<acronym>MCF</acronym>s):
@ -225,18 +225,18 @@ rows = 10000 * 0.0014559
</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;
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
<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
column, there will normally be both a histogram and an MCV list, and
<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
<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
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
@ -253,7 +253,7 @@ EXPLAIN SELECT * FROM tenk1 WHERE stringu1 &lt; 'IAAAAA';
Filter: (stringu1 &lt; 'IAAAAA'::name)
</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:
<programlisting>
@ -266,7 +266,7 @@ WHERE tablename='tenk1' AND attname='stringu1';
</programlisting>
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
<programlisting>
@ -279,11 +279,11 @@ selectivity = sum(relevant mvfs)
population represented by MCVs is 0.03033333, and therefore the
fraction represented by the histogram is 0.96966667 (again, there
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
about the frequency of different characters, the planner arrives
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:
<programlisting>
@ -372,7 +372,7 @@ rows = 10000 * 0.005035
= 50 (rounding off)
</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
our familiar <literal>=</literal>, however the selectivity function is
obtained from the <structfield>oprjoin</structfield> column of
@ -424,12 +424,12 @@ rows = (outer_cardinality * inner_cardinality) * selectivity
</para>
<para>
Notice that we showed <literal>inner_cardinality</> as 10000, that is,
the unmodified size of <structname>tenk2</>. It might appear from
inspection of the <command>EXPLAIN</> output that the estimate of
Notice that we showed <literal>inner_cardinality</literal> as 10000, that is,
the unmodified size of <structname>tenk2</structname>. It might appear from
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
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
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
@ -438,7 +438,7 @@ rows = (outer_cardinality * inner_cardinality) * selectivity
<para>
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
logic for clause selectivities is in
<filename>src/backend/optimizer/path/clausesel.c</filename>. The
@ -485,8 +485,8 @@ SELECT relpages, reltuples FROM pg_class WHERE relname = 't';
</para>
<para>
The following example shows the result of estimating a <literal>WHERE</>
condition on the <structfield>a</> column:
The following example shows the result of estimating a <literal>WHERE</literal>
condition on the <structfield>a</structfield> column:
<programlisting>
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
number of rows, we see that the estimate is very accurate
(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
condition on both columns, combining them with <literal>AND</>:
condition on both columns, combining them with <literal>AND</literal>:
<programlisting>
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>
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:
<programlisting>

View File

@ -35,7 +35,7 @@
<para>
The call handler is called in the same way as any other function:
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
is expected to return a <type>Datum</type> result (and possibly
set the <structfield>isnull</structfield> field of the
@ -54,7 +54,7 @@
<para>
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
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
in the <literal>prosrc</literal> column of the
<classname>pg_proc</classname> row. This is commonly source
@ -68,9 +68,9 @@
A call handler can avoid repeated lookups of information about the
called function by using the
<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
<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
call handler must make sure that
<structfield>flinfo-&gt;fn_extra</structfield> is made to point at
@ -90,7 +90,7 @@
are passed in the usual way, but the
<structname>FunctionCallInfoData</structname>'s
<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
provide mechanisms for procedural-language functions to get at the trigger
information.
@ -170,21 +170,21 @@ CREATE LANGUAGE plsample
<para>
If a validator is provided by a procedural language, it
must be declared as a function taking a single parameter of type
<type>oid</>. The validator's result is ignored, so it is customarily
declared to return <type>void</>. The validator will be called at
the end of a <command>CREATE FUNCTION</> command that has created
<type>oid</type>. The validator's result is ignored, so it is customarily
declared to return <type>void</type>. The validator will be called at
the end of a <command>CREATE FUNCTION</command> command that has created
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
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
<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
language, and that the function's body is syntactically correct
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
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
the incorrect function definition from being committed.
</para>
@ -195,40 +195,40 @@ CREATE LANGUAGE plsample
any expensive or context-sensitive checking should be skipped. If the
language provides for code execution at compilation time, the validator
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
dependencies of the function bodies on other database objects.
(Because of this requirement, the call handler should avoid
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
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
discretion of the validator function, note that the core
<command>CREATE FUNCTION</> code only executes <literal>SET</> clauses
attached to a function when <varname>check_function_bodies</> is on.
<command>CREATE FUNCTION</command> code only executes <literal>SET</literal> clauses
attached to a function when <varname>check_function_bodies</varname> is on.
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.
</para>
<para>
If an inline handler is provided by a procedural language, it
must be declared as a function taking a single parameter of type
<type>internal</>. The inline handler's result is ignored, so it is
customarily declared to return <type>void</>. The inline handler
will be called when a <command>DO</> statement is executed specifying
<type>internal</type>. The inline handler's result is ignored, so it is
customarily declared to return <type>void</type>. The inline handler
will be called when a <command>DO</command> statement is executed specifying
the procedural language. The parameter actually passed is a pointer
to an <structname>InlineCodeBlock</> struct, which contains information
about the <command>DO</> statement's parameters, in particular the
to an <structname>InlineCodeBlock</structname> struct, which contains information
about the <command>DO</command> statement's parameters, in particular the
text of the anonymous code block to be executed. The inline handler
should execute this code and return.
</para>
<para>
It's recommended that you wrap all these function declarations,
as well as the <command>CREATE LANGUAGE</> command itself, into
an <firstterm>extension</> so that a simple <command>CREATE EXTENSION</>
as well as the <command>CREATE LANGUAGE</command> command itself, into
an <firstterm>extension</firstterm> so that a simple <command>CREATE EXTENSION</command>
command is sufficient to install the language. See
<xref linkend="extend-extensions"> for information about writing
extensions.
@ -237,7 +237,7 @@ CREATE LANGUAGE plsample
<para>
The procedural languages included in the standard distribution
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">
reference page also has some useful details.
</para>

View File

@ -27,12 +27,12 @@
<para>
To install PL/Perl in a particular database, use
<literal>CREATE EXTENSION plperl</>.
<literal>CREATE EXTENSION plperl</literal>.
</para>
<tip>
<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.
</para>
</tip>
@ -90,8 +90,8 @@ $$ LANGUAGE plperl;
subroutines which you call via a coderef. For more information, see the
entries for <literal>Variable "%s" will not stay shared</literal> and
<literal>Variable "%s" is not available</literal> in the
<citerefentry><refentrytitle>perldiag</></citerefentry> man page, or
search the Internet for <quote>perl nested named subroutine</>.
<citerefentry><refentrytitle>perldiag</refentrytitle></citerefentry> man page, or
search the Internet for <quote>perl nested named subroutine</quote>.
</para>
</note>
@ -100,16 +100,16 @@ $$ LANGUAGE plperl;
the function body to be written as a string constant. It is usually
most convenient to use dollar quoting (see <xref
linkend="sql-syntax-dollar-quoting">) for the string constant.
If you choose to use escape string syntax <literal>E''</>,
you must double any single quote marks (<literal>'</>) and backslashes
(<literal>\</>) used in the body of the function
If you choose to use escape string syntax <literal>E''</literal>,
you must double any single quote marks (<literal>'</literal>) and backslashes
(<literal>\</literal>) used in the body of the function
(see <xref linkend="sql-syntax-strings">).
</para>
<para>
Arguments and results are handled as in any other Perl subroutine:
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.
</para>
@ -134,12 +134,12 @@ $$ LANGUAGE plperl;
</note>
<para>
If an SQL null value<indexterm><primary>null value</><secondary
sortas="PL/Perl">in PL/Perl</></indexterm> is passed to a function,
the argument value will appear as <quote>undefined</> in Perl. The
If an SQL null value<indexterm><primary>null value</primary><secondary
sortas="PL/Perl">in PL/Perl</secondary></indexterm> is passed to a function,
the argument value will appear as <quote>undefined</quote> in Perl. The
above function definition will not behave very nicely with null
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:
if a null value is passed, the function will not be called at all,
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
more usable in Perl. For example, the <function>decode_bytea</function>
function can be used to convert an argument of
type <type>bytea</> into unescaped binary.
type <type>bytea</type> into unescaped binary.
</para>
<para>
Similarly, values passed back to <productname>PostgreSQL</productname>
must be in the external text representation format. For example, the
<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>
@ -330,10 +330,10 @@ SELECT * FROM perl_set();
</para>
<para>
If you wish to use the <literal>strict</> pragma with your code you
have a few options. For temporary global use you can <command>SET</>
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</command>
<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.
For permanent global use you can set <literal>plperl.use_strict</literal>
to true in the <filename>postgresql.conf</filename> file.
@ -348,7 +348,7 @@ use strict;
</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>
</sect1>
@ -380,7 +380,7 @@ use strict;
<variablelist>
<varlistentry>
<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>
<primary>spi_exec_query</primary>
<secondary>in PL/Perl</secondary>
@ -524,13 +524,13 @@ SELECT * from lotsa_md5(500);
</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
rows to read. The cursor returned by <literal>spi_query</literal>
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
<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.
</para>
@ -675,13 +675,13 @@ SELECT release_hosts_query();
<listitem>
<para>
Emit a log or error message. Possible levels are
<literal>DEBUG</>, <literal>LOG</>, <literal>INFO</>,
<literal>NOTICE</>, <literal>WARNING</>, and <literal>ERROR</>.
<literal>ERROR</>
<literal>DEBUG</literal>, <literal>LOG</literal>, <literal>INFO</literal>,
<literal>NOTICE</literal>, <literal>WARNING</literal>, and <literal>ERROR</literal>.
<literal>ERROR</literal>
raises an error condition; if this is not trapped by the surrounding
Perl code, the error propagates out to the calling query, causing
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
priority levels.
Whether messages of a particular priority are reported to the client,
@ -706,8 +706,8 @@ SELECT release_hosts_query();
<para>
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.
Note that <function>quote_literal</> returns undef on undef input; if the argument
might be undef, <function>quote_nullable</> is often more suitable.
Note that <function>quote_literal</function> returns undef on undef input; if the argument
might be undef, <function>quote_nullable</function> is often more suitable.
</para>
</listitem>
</varlistentry>
@ -849,7 +849,7 @@ SELECT release_hosts_query();
Returns a true value if the content of the given string looks like a
number, according to Perl, returns false otherwise.
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>
</listitem>
</varlistentry>
@ -865,8 +865,8 @@ SELECT release_hosts_query();
<listitem>
<para>
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
<literal>PostgreSQL::InServer::ARRAY</>. Returns false otherwise.
array reference, that is, if ref of the argument is <literal>ARRAY</literal> or
<literal>PostgreSQL::InServer::ARRAY</literal>. Returns false otherwise.
</para>
</listitem>
</varlistentry>
@ -941,11 +941,11 @@ $$ LANGUAGE plperl;
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
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
share data via <varname>%_SHARED</varname>. To do that, make sure that
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.
</para>
</sect1>
@ -959,8 +959,8 @@ $$ LANGUAGE plperl;
</indexterm>
<para>
Normally, PL/Perl is installed as a <quote>trusted</> programming
language named <literal>plperl</>. In this setup, certain Perl
Normally, PL/Perl is installed as a <quote>trusted</quote> programming
language named <literal>plperl</literal>. In this setup, certain Perl
operations are disabled to preserve security. In general, the
operations that are restricted are those that interact with the
environment. This includes file handle operations,
@ -993,15 +993,15 @@ $$ LANGUAGE plperl;
Sometimes it is desirable to write Perl functions that are not
restricted. For example, one might want a Perl function that sends
mail. To handle these cases, PL/Perl can also be installed as an
<quote>untrusted</> language (usually called
<application>PL/PerlU</application><indexterm><primary>PL/PerlU</></indexterm>).
<quote>untrusted</quote> language (usually called
<application>PL/PerlU</application><indexterm><primary>PL/PerlU</primary></indexterm>).
In this case the full Perl language is available. When installing the
language, the language name <literal>plperlu</literal> will select
the untrusted PL/Perl variant.
</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
anything that could be done by a user logged in as the database
administrator. Note that the database system allows only database
@ -1010,25 +1010,25 @@ $$ LANGUAGE plperl;
<para>
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>
In the same way, anonymous code blocks written in Perl can use
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.
</para>
<note>
<para>
While <application>PL/Perl</> functions run in a separate Perl
interpreter for each SQL role, all <application>PL/PerlU</> functions
While <application>PL/Perl</application> functions run in a separate Perl
interpreter for each SQL role, all <application>PL/PerlU</application> functions
executed in a given session run in a single Perl interpreter (which is
not any of the ones used for <application>PL/Perl</> functions).
This allows <application>PL/PerlU</> functions to share data freely,
but no communication can occur between <application>PL/Perl</> and
<application>PL/PerlU</> functions.
not any of the ones used for <application>PL/Perl</application> functions).
This allows <application>PL/PerlU</application> functions to share data freely,
but no communication can occur between <application>PL/Perl</application> and
<application>PL/PerlU</application> functions.
</para>
</note>
@ -1036,14 +1036,14 @@ $$ LANGUAGE plperl;
<para>
Perl cannot support multiple interpreters within one process unless
it was built with the appropriate flags, namely either
<literal>usemultiplicity</> or <literal>useithreads</>.
(<literal>usemultiplicity</> is preferred unless you actually need
<literal>usemultiplicity</literal> or <literal>useithreads</literal>.
(<literal>usemultiplicity</literal> is preferred unless you actually need
to use threads. For more details, see the
<citerefentry><refentrytitle>perlembed</></citerefentry> man page.)
If <application>PL/Perl</> is used with a copy of Perl that was not built
<citerefentry><refentrytitle>perlembed</refentrytitle></citerefentry> man page.)
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
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.
</para>
</note>
@ -1056,7 +1056,7 @@ $$ LANGUAGE plperl;
<para>
PL/Perl can be used to write trigger functions. In a trigger function,
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.
The fields of the <varname>$_TD</varname> hash reference are:
@ -1092,8 +1092,8 @@ $$ LANGUAGE plperl;
<term><literal>$_TD-&gt;{event}</literal></term>
<listitem>
<para>
Trigger event: <literal>INSERT</>, <literal>UPDATE</>,
<literal>DELETE</>, <literal>TRUNCATE</>, or <literal>UNKNOWN</>
Trigger event: <literal>INSERT</literal>, <literal>UPDATE</literal>,
<literal>DELETE</literal>, <literal>TRUNCATE</literal>, or <literal>UNKNOWN</literal>
</para>
</listitem>
</varlistentry>
@ -1244,7 +1244,7 @@ CREATE TRIGGER test_valid_id_trig
<para>
PL/Perl can be used to write event trigger functions. In an event trigger
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
fields of the <varname>$_TD</varname> hash reference are:
@ -1295,7 +1295,7 @@ CREATE EVENT TRIGGER perl_a_snitch
<title>Configuration</title>
<para>
This section lists configuration parameters that affect <application>PL/Perl</>.
This section lists configuration parameters that affect <application>PL/Perl</application>.
</para>
<variablelist>
@ -1304,14 +1304,14 @@ CREATE EVENT TRIGGER perl_a_snitch
<term>
<varname>plperl.on_init</varname> (<type>string</type>)
<indexterm>
<primary><varname>plperl.on_init</> configuration parameter</primary>
<primary><varname>plperl.on_init</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<para>
Specifies Perl code to be executed when a Perl interpreter is first
initialized, before it is specialized for use by <literal>plperl</> or
<literal>plperlu</>.
initialized, before it is specialized for use by <literal>plperl</literal> or
<literal>plperlu</literal>.
The SPI functions are not available when this code is executed.
If the code fails with an error it will abort the initialization of
the interpreter and propagate out to the calling query, causing the
@ -1319,7 +1319,7 @@ CREATE EVENT TRIGGER perl_a_snitch
</para>
<para>
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:
<programlisting>
plperl.on_init = 'require "plperlinit.pl"'
@ -1327,8 +1327,8 @@ plperl.on_init = 'use lib "/my/app"; use MyApp::PgInit;'
</programlisting>
</para>
<para>
Any modules loaded by <literal>plperl.on_init</>, either directly or
indirectly, will be available for use by <literal>plperl</>. This may
Any modules loaded by <literal>plperl.on_init</literal>, either directly or
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:
<programlisting>
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
case extra consideration should be given to the risk of destabilizing
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
without loading overhead in individual database sessions. However,
keep in mind that the overhead is avoided only for the first Perl
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
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
interpreter created in the postmaster process does not propagate to
child processes.
@ -1361,27 +1361,27 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl;
<term>
<varname>plperl.on_plperl_init</varname> (<type>string</type>)
<indexterm>
<primary><varname>plperl.on_plperl_init</> configuration parameter</primary>
<primary><varname>plperl.on_plperl_init</varname> configuration parameter</primary>
</indexterm>
</term>
<term>
<varname>plperl.on_plperlu_init</varname> (<type>string</type>)
<indexterm>
<primary><varname>plperl.on_plperlu_init</> configuration parameter</primary>
<primary><varname>plperl.on_plperlu_init</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<para>
These parameters specify Perl code to be executed when a Perl
interpreter is specialized for <literal>plperl</> or
<literal>plperlu</> respectively. This will happen when a PL/Perl or
interpreter is specialized for <literal>plperl</literal> 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
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
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 Perl code in <literal>plperl.on_plperl_init</> is executed after
<quote>locking down</> the interpreter, and thus it can only perform
The Perl code in <literal>plperl.on_plperl_init</literal> is executed after
<quote>locking down</quote> the interpreter, and thus it can only perform
trusted operations.
</para>
<para>
@ -1404,13 +1404,13 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl;
<term>
<varname>plperl.use_strict</varname> (<type>boolean</type>)
<indexterm>
<primary><varname>plperl.use_strict</> configuration parameter</primary>
<primary><varname>plperl.use_strict</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<para>
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.
</para>
</listitem>
@ -1459,7 +1459,7 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl;
<listitem>
<para>
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,
file handles are not automatically flushed and objects are
not automatically destroyed.

File diff suppressed because it is too large Load Diff

View File

@ -3,8 +3,8 @@
<chapter id="plpython">
<title>PL/Python - Python Procedural Language</title>
<indexterm zone="plpython"><primary>PL/Python</></>
<indexterm zone="plpython"><primary>Python</></>
<indexterm zone="plpython"><primary>PL/Python</primary></indexterm>
<indexterm zone="plpython"><primary>Python</primary></indexterm>
<para>
The <application>PL/Python</application> procedural language allows
@ -14,22 +14,22 @@
<para>
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">).
</para>
<tip>
<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.
</para>
</tip>
<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
is therefore named <literal>plpythonu</>. A trusted
variant <literal>plpython</> might become available in the future
is therefore named <literal>plpythonu</literal>. A trusted
variant <literal>plpython</literal> might become available in the future
if a secure execution mechanism is developed in Python. 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
@ -383,8 +383,8 @@ $$ LANGUAGE plpythonu;
For all other PostgreSQL return types, the return value is converted
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.
(If the Python value is a <type>float</>, it is converted using
the <literal>repr</> built-in instead of <literal>str</literal>, to
(If the Python value is a <type>float</type>, it is converted using
the <literal>repr</literal> built-in instead of <literal>str</literal>, to
avoid loss of precision.)
</para>
@ -756,8 +756,8 @@ SELECT * FROM multiout_simple_setof(3);
data between function calls. This variable is private static data.
The global dictionary <varname>GD</varname> is public data,
available to all Python functions within a session. Use with
care.<indexterm><primary>global data</>
<secondary>in PL/Python</></indexterm>
care.<indexterm><primary>global data</primary>
<secondary>in PL/Python</secondary></indexterm>
</para>
<para>
@ -800,38 +800,38 @@ $$ LANGUAGE plpythonu;
<literal>TD</literal> contains trigger-related values:
<variablelist>
<varlistentry>
<term><literal>TD["event"]</></term>
<term><literal>TD["event"]</literal></term>
<listitem>
<para>
contains the event as a string:
<literal>INSERT</>, <literal>UPDATE</>,
<literal>DELETE</>, or <literal>TRUNCATE</>.
<literal>INSERT</literal>, <literal>UPDATE</literal>,
<literal>DELETE</literal>, or <literal>TRUNCATE</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>TD["when"]</></term>
<term><literal>TD["when"]</literal></term>
<listitem>
<para>
contains one of <literal>BEFORE</>, <literal>AFTER</>, or
<literal>INSTEAD OF</>.
contains one of <literal>BEFORE</literal>, <literal>AFTER</literal>, or
<literal>INSTEAD OF</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>TD["level"]</></term>
<term><literal>TD["level"]</literal></term>
<listitem>
<para>
contains <literal>ROW</> or <literal>STATEMENT</>.
contains <literal>ROW</literal> or <literal>STATEMENT</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>TD["new"]</></term>
<term><literal>TD["old"]</></term>
<term><literal>TD["new"]</literal></term>
<term><literal>TD["old"]</literal></term>
<listitem>
<para>
For a row-level trigger, one or both of these fields contain
@ -841,7 +841,7 @@ $$ LANGUAGE plpythonu;
</varlistentry>
<varlistentry>
<term><literal>TD["name"]</></term>
<term><literal>TD["name"]</literal></term>
<listitem>
<para>
contains the trigger name.
@ -850,7 +850,7 @@ $$ LANGUAGE plpythonu;
</varlistentry>
<varlistentry>
<term><literal>TD["table_name"]</></term>
<term><literal>TD["table_name"]</literal></term>
<listitem>
<para>
contains the name of the table on which the trigger occurred.
@ -859,7 +859,7 @@ $$ LANGUAGE plpythonu;
</varlistentry>
<varlistentry>
<term><literal>TD["table_schema"]</></term>
<term><literal>TD["table_schema"]</literal></term>
<listitem>
<para>
contains the schema of the table on which the trigger occurred.
@ -868,7 +868,7 @@ $$ LANGUAGE plpythonu;
</varlistentry>
<varlistentry>
<term><literal>TD["relid"]</></term>
<term><literal>TD["relid"]</literal></term>
<listitem>
<para>
contains the OID of the table on which the trigger occurred.
@ -877,12 +877,12 @@ $$ LANGUAGE plpythonu;
</varlistentry>
<varlistentry>
<term><literal>TD["args"]</></term>
<term><literal>TD["args"]</literal></term>
<listitem>
<para>
If the <command>CREATE TRIGGER</> command
included arguments, they are available in <literal>TD["args"][0]</> to
<literal>TD["args"][<replaceable>n</>-1]</>.
If the <command>CREATE TRIGGER</command> command
included arguments, they are available in <literal>TD["args"][0]</literal> to
<literal>TD["args"][<replaceable>n</replaceable>-1]</literal>.
</para>
</listitem>
</varlistentry>
@ -890,14 +890,14 @@ $$ LANGUAGE plpythonu;
</para>
<para>
If <literal>TD["when"]</literal> is <literal>BEFORE</> or
<literal>INSTEAD OF</> and
<literal>TD["level"]</literal> is <literal>ROW</>, you can
If <literal>TD["when"]</literal> is <literal>BEFORE</literal> or
<literal>INSTEAD OF</literal> and
<literal>TD["level"]</literal> is <literal>ROW</literal>, you can
return <literal>None</literal> or <literal>"OK"</literal> from the
Python function to indicate the row is unmodified,
<literal>"SKIP"</> to abort the event, or if <literal>TD["event"]</>
is <command>INSERT</> or <command>UPDATE</> you can return
<literal>"MODIFY"</> to indicate you've modified the new row.
<literal>"SKIP"</literal> to abort the event, or if <literal>TD["event"]</literal>
is <command>INSERT</command> or <command>UPDATE</command> you can return
<literal>"MODIFY"</literal> to indicate you've modified the new row.
Otherwise the return value is ignored.
</para>
</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>
<listitem>
<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
query. It is called with a query string and a list of parameter types,
if you have parameter references in the query. For example:
@ -1371,22 +1371,22 @@ $$ LANGUAGE plpythonu;
<para>
The <literal>plpy</literal> module also provides the functions
<simplelist>
<member><literal>plpy.debug(<replaceable>msg, **kwargs</>)</literal></member>
<member><literal>plpy.log(<replaceable>msg, **kwargs</>)</literal></member>
<member><literal>plpy.info(<replaceable>msg, **kwargs</>)</literal></member>
<member><literal>plpy.notice(<replaceable>msg, **kwargs</>)</literal></member>
<member><literal>plpy.warning(<replaceable>msg, **kwargs</>)</literal></member>
<member><literal>plpy.error(<replaceable>msg, **kwargs</>)</literal></member>
<member><literal>plpy.fatal(<replaceable>msg, **kwargs</>)</literal></member>
<member><literal>plpy.debug(<replaceable>msg, **kwargs</replaceable>)</literal></member>
<member><literal>plpy.log(<replaceable>msg, **kwargs</replaceable>)</literal></member>
<member><literal>plpy.info(<replaceable>msg, **kwargs</replaceable>)</literal></member>
<member><literal>plpy.notice(<replaceable>msg, **kwargs</replaceable>)</literal></member>
<member><literal>plpy.warning(<replaceable>msg, **kwargs</replaceable>)</literal></member>
<member><literal>plpy.error(<replaceable>msg, **kwargs</replaceable>)</literal></member>
<member><literal>plpy.fatal(<replaceable>msg, **kwargs</replaceable>)</literal></member>
</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>
actually raise a Python exception which, if uncaught, propagates out to
the calling query, causing the current transaction or subtransaction to
be aborted. <literal>raise plpy.Error(<replaceable>msg</>)</literal> and
<literal>raise plpy.Fatal(<replaceable>msg</>)</literal> are
equivalent to calling <literal>plpy.error(<replaceable>msg</>)</literal> and
<literal>plpy.fatal(<replaceable>msg</>)</literal>, respectively but
be aborted. <literal>raise plpy.Error(<replaceable>msg</replaceable>)</literal> and
<literal>raise plpy.Fatal(<replaceable>msg</replaceable>)</literal> are
equivalent to calling <literal>plpy.error(<replaceable>msg</replaceable>)</literal> and
<literal>plpy.fatal(<replaceable>msg</replaceable>)</literal>, respectively but
the <literal>raise</literal> form does not allow passing keyword arguments.
The other functions only generate messages of different priority levels.
Whether messages of a particular priority are reported to the client,
@ -1397,7 +1397,7 @@ $$ LANGUAGE plpythonu;
</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
that case, the string representation of the tuple of positional arguments
becomes the message reported to the client.
@ -1438,9 +1438,9 @@ PL/Python function "raise_custom_exception"
<para>
Another set of utility functions are
<literal>plpy.quote_literal(<replaceable>string</>)</literal>,
<literal>plpy.quote_nullable(<replaceable>string</>)</literal>, and
<literal>plpy.quote_ident(<replaceable>string</>)</literal>. They
<literal>plpy.quote_literal(<replaceable>string</replaceable>)</literal>,
<literal>plpy.quote_nullable(<replaceable>string</replaceable>)</literal>, and
<literal>plpy.quote_ident(<replaceable>string</replaceable>)</literal>. They
are equivalent to the built-in quoting functions described in <xref
linkend="functions-string">. They are useful when constructing
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
Tcl interpreter. In addition to the limited command set of safe
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
gain OS-level access under the permissions of the
<productname>PostgreSQL</productname> server process, as a C
@ -50,23 +50,23 @@
<para>
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
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
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
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
unwanted, since it will be able to do anything that could be done by
a user logged in as the database administrator.
</para>
<para>
The shared object code for the <application>PL/Tcl</> and
<application>PL/TclU</> call handlers is automatically built and
The shared object code for the <application>PL/Tcl</application> and
<application>PL/TclU</application> call handlers is automatically built and
installed in the <productname>PostgreSQL</productname> library
directory if Tcl support is specified in the configuration step of
the installation procedure. To install <application>PL/Tcl</>
and/or <application>PL/TclU</> in a particular database, use the
<command>CREATE EXTENSION</> command, for example
the installation procedure. To install <application>PL/Tcl</application>
and/or <application>PL/TclU</application> in a particular database, use the
<command>CREATE EXTENSION</command> command, for example
<literal>CREATE EXTENSION pltcl</literal> or
<literal>CREATE EXTENSION pltclu</literal>.
</para>
@ -78,7 +78,7 @@
<title>PL/Tcl Functions and Arguments</title>
<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:
<programlisting>
@ -87,8 +87,8 @@ CREATE FUNCTION <replaceable>funcname</replaceable> (<replaceable>argument-types
$$ LANGUAGE pltcl;
</programlisting>
<application>PL/TclU</> is the same, except that the language has to be specified as
<literal>pltclu</>.
<application>PL/TclU</application> is the same, except that the language has to be specified as
<literal>pltclu</literal>.
</para>
<para>
@ -111,7 +111,7 @@ CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
$$ LANGUAGE pltcl STRICT;
</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
function will not be called at all, but will just return a null
result automatically.
@ -122,7 +122,7 @@ $$ LANGUAGE pltcl STRICT;
if the actual value of an argument is null, the corresponding
<literal>$<replaceable>n</replaceable></literal> variable will be set to an empty string.
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
argument, rather than null:
@ -188,7 +188,7 @@ $$ LANGUAGE pltcl;
<tip>
<para>
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>
CREATE FUNCTION raise_pay(employee, delta int) RETURNS employee AS $$
@ -233,8 +233,8 @@ $$ LANGUAGE pltcl;
<para>
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
displayed by a <command>SELECT</> statement). Conversely, the
<literal>return</> and <literal>return_next</> commands will accept
displayed by a <command>SELECT</command> statement). Conversely, the
<literal>return</literal> and <literal>return_next</literal> commands will accept
any string that is acceptable input format for the function's declared
result type, or for the specified column of a composite result type.
</para>
@ -262,14 +262,14 @@ $$ LANGUAGE pltcl;
role in a separate Tcl interpreter for that role. This prevents
accidental or malicious interference by one user with the behavior of
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
executed by the same SQL role. In an application wherein a single
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
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
unintended.
</para>
@ -286,19 +286,19 @@ $$ LANGUAGE pltcl;
<para>
To help protect PL/Tcl functions from unintentionally interfering
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
name, and the local name is <literal>GD</>. It is recommended that
<literal>GD</> be used
name, and the local name is <literal>GD</literal>. It is recommended that
<literal>GD</literal> be used
for persistent private data of a function. Use regular Tcl global
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
security restrictions mentioned above.)
</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.
</para>
</sect1>
@ -320,28 +320,28 @@ $$ LANGUAGE pltcl;
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
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
described below.
</para>
<para>
The optional <literal>-count</> value tells
The optional <literal>-count</literal> value tells
<function>spi_exec</function> the maximum number of rows
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>
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.
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
column names used as array indexes. In addition, the current row
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.
</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
Tcl variables or array elements; remaining rows, if any, are ignored.
No storing occurs if the query returns no rows. (This case can be
@ -350,14 +350,14 @@ $$ LANGUAGE pltcl;
<programlisting>
spi_exec "SELECT count(*) AS cnt FROM pg_proc"
</programlisting>
will set the Tcl variable <literal>$cnt</> to the number of rows in
the <structname>pg_proc</> system catalog.
will set the Tcl variable <literal>$cnt</literal> to the number of rows in
the <structname>pg_proc</structname> system catalog.
</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
query result. (<replaceable>loop-body</> is ignored if the given
command is not a <command>SELECT</>.)
query result. (<replaceable>loop-body</replaceable> is ignored if the given
command is not a <command>SELECT</command>.)
The values of the current row's columns
are stored into Tcl variables or array elements before each iteration.
For example:
@ -366,14 +366,14 @@ spi_exec -array C "SELECT * FROM pg_class" {
elog DEBUG "have table $C(relname)"
}
</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
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.
</para>
<para>
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>
</listitem>
</varlistentry>
@ -384,8 +384,8 @@ spi_exec -array C "SELECT * FROM pg_class" {
<para>
Prepares and saves a query plan for later execution. The
saved plan will be retained for the life of the current
session.<indexterm><primary>preparing a query</>
<secondary>in PL/Tcl</></>
session.<indexterm><primary>preparing a query</primary>
<secondary>in PL/Tcl</secondary></indexterm>
</para>
<para>
The query can use parameters, that is, placeholders for
@ -405,29 +405,29 @@ spi_exec -array C "SELECT * FROM pg_class" {
</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>
<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
<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
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
<function>spi_prepare</>. Omit <replaceable>value-list</replaceable>
<function>spi_prepare</function>. Omit <replaceable>value-list</replaceable>
if the query has no parameters.
</para>
<para>
The optional value for <literal>-nulls</> is a string of spaces and
<literal>'n'</> characters telling <function>spi_execp</function>
The optional value for <literal>-nulls</literal> is a string of spaces and
<literal>'n'</literal> characters telling <function>spi_execp</function>
which of the parameters are null values. If given, it must have exactly the
same length as the <replaceable>value-list</replaceable>. If it
is not given, all the parameter values are nonnull.
</para>
<para>
Except for the way in which the query and its parameters are specified,
<function>spi_execp</> works just like <function>spi_exec</>.
The <literal>-count</>, <literal>-array</>, and
<function>spi_execp</function> works just like <function>spi_exec</function>.
The <literal>-count</literal>, <literal>-array</literal>, and
<replaceable>loop-body</replaceable> options are the same,
and so is the result value.
</para>
@ -448,9 +448,9 @@ $$ LANGUAGE pltcl;
</programlisting>
We need backslashes inside the query string given to
<function>spi_prepare</> to ensure that the
<literal>$<replaceable>n</replaceable></> markers will be passed
through to <function>spi_prepare</> as-is, and not replaced by Tcl
<function>spi_prepare</function> to ensure that the
<literal>$<replaceable>n</replaceable></literal> markers will be passed
through to <function>spi_prepare</function> as-is, and not replaced by Tcl
variable substitution.
</para>
@ -459,7 +459,7 @@ $$ LANGUAGE pltcl;
<varlistentry>
<term>
<function>spi_lastoid</>
<function>spi_lastoid</function>
<indexterm>
<primary>spi_lastoid</primary>
<secondary>in PL/Tcl</secondary>
@ -468,8 +468,8 @@ $$ LANGUAGE pltcl;
<listitem>
<para>
Returns the OID of the row inserted by the last
<function>spi_exec</> or <function>spi_execp</>, if the
command was a single-row <command>INSERT</> and the modified
<function>spi_exec</function> or <function>spi_execp</function>, if the
command was a single-row <command>INSERT</command> and the modified
table contained OIDs. (If not, you get zero.)
</para>
</listitem>
@ -490,7 +490,7 @@ $$ LANGUAGE pltcl;
</varlistentry>
<varlistentry>
<term><function>quote</> <replaceable>string</replaceable></term>
<term><function>quote</function> <replaceable>string</replaceable></term>
<listitem>
<para>
Doubles all occurrences of single quote and backslash characters
@ -504,7 +504,7 @@ $$ LANGUAGE pltcl;
"SELECT '$val' AS ret"
</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
in the final command string:
@ -536,7 +536,7 @@ SELECT 'doesn''t' AS ret
<varlistentry>
<term>
<function>elog</> <replaceable>level</replaceable> <replaceable>msg</replaceable>
<function>elog</function> <replaceable>level</replaceable> <replaceable>msg</replaceable>
<indexterm>
<primary>elog</primary>
<secondary>in PL/Tcl</secondary>
@ -545,14 +545,14 @@ SELECT 'doesn''t' AS ret
<listitem>
<para>
Emits a log or error message. Possible levels are
<literal>DEBUG</>, <literal>LOG</>, <literal>INFO</>,
<literal>NOTICE</>, <literal>WARNING</>, <literal>ERROR</>, and
<literal>FATAL</>. <literal>ERROR</>
<literal>DEBUG</literal>, <literal>LOG</literal>, <literal>INFO</literal>,
<literal>NOTICE</literal>, <literal>WARNING</literal>, <literal>ERROR</literal>, and
<literal>FATAL</literal>. <literal>ERROR</literal>
raises an error condition; if this is not trapped by the surrounding
Tcl code, the error propagates out to the calling query, causing
the current transaction or subtransaction to be aborted. This
is effectively the same as the Tcl <literal>error</> command.
<literal>FATAL</> aborts the transaction and causes the current
is effectively the same as the Tcl <literal>error</literal> command.
<literal>FATAL</literal> aborts the transaction and causes the current
session to shut down. (There is probably no good reason to use
this error level in PL/Tcl functions, but it's provided for
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.
<productname>PostgreSQL</productname> requires that a procedure that is to be called
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>
The information from the trigger manager is passed to the procedure body
@ -637,8 +637,8 @@ SELECT 'doesn''t' AS ret
<listitem>
<para>
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
<function>lsearch</> command returns the element's number starting
element. So looking up a column name in the list with <application>Tcl</application>'s
<function>lsearch</function> command returns the element's number starting
with 1 for the first column, the same way the columns are customarily
numbered in <productname>PostgreSQL</productname>. (Empty list
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>
<listitem>
<para>
The string <literal>BEFORE</>, <literal>AFTER</>, or
<literal>INSTEAD OF</>, depending on the type of trigger event.
The string <literal>BEFORE</literal>, <literal>AFTER</literal>, or
<literal>INSTEAD OF</literal>, depending on the type of trigger event.
</para>
</listitem>
</varlistentry>
@ -662,7 +662,7 @@ SELECT 'doesn''t' AS ret
<term><varname>$TG_level</varname></term>
<listitem>
<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.
</para>
</listitem>
@ -672,8 +672,8 @@ SELECT 'doesn''t' AS ret
<term><varname>$TG_op</varname></term>
<listitem>
<para>
The string <literal>INSERT</>, <literal>UPDATE</>,
<literal>DELETE</>, or <literal>TRUNCATE</> depending on the type of
The string <literal>INSERT</literal>, <literal>UPDATE</literal>,
<literal>DELETE</literal>, or <literal>TRUNCATE</literal> depending on the type of
trigger event.
</para>
</listitem>
@ -684,8 +684,8 @@ SELECT 'doesn''t' AS ret
<listitem>
<para>
An associative array containing the values of the new table
row for <command>INSERT</> or <command>UPDATE</> actions, or
empty for <command>DELETE</>. The array is indexed by column
row for <command>INSERT</command> or <command>UPDATE</command> actions, or
empty for <command>DELETE</command>. The array is indexed by column
name. Columns that are null will not appear in the array.
This is not set for statement-level triggers.
</para>
@ -697,8 +697,8 @@ SELECT 'doesn''t' AS ret
<listitem>
<para>
An associative array containing the values of the old table
row for <command>UPDATE</> or <command>DELETE</> actions, or
empty for <command>INSERT</>. The array is indexed by column
row for <command>UPDATE</command> or <command>DELETE</command> actions, or
empty for <command>INSERT</command>. The array is indexed by column
name. Columns that are null will not appear in the array.
This is not set for statement-level triggers.
</para>
@ -721,32 +721,32 @@ SELECT 'doesn''t' AS ret
<para>
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.
If the return value is <literal>OK</>,
the operation (<command>INSERT</>/<command>UPDATE</>/<command>DELETE</>)
<literal>OK</literal> or <literal>SKIP</literal>, or a list of column name/value pairs.
If the return value is <literal>OK</literal>,
the operation (<command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command>)
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
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.
Any columns not mentioned in the list are set to null.
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
given in <varname>$NEW</>; or for row-level <literal>INSTEAD OF</>
<command>INSERT</> or <command>UPDATE</> triggers where the returned row
is used as the source data for <command>INSERT RETURNING</> or
<command>UPDATE RETURNING</> clauses.
In row-level <literal>BEFORE</> <command>DELETE</> or <literal>INSTEAD
OF</> <command>DELETE</> triggers, returning a modified row has the same
effect as returning <literal>OK</>, that is the operation proceeds.
given in <varname>$NEW</varname>; or for row-level <literal>INSTEAD OF</literal>
<command>INSERT</command> or <command>UPDATE</command> triggers where the returned row
is used as the source data for <command>INSERT RETURNING</command> or
<command>UPDATE RETURNING</command> clauses.
In row-level <literal>BEFORE</literal> <command>DELETE</command> or <literal>INSTEAD
OF</literal> <command>DELETE</command> triggers, returning a modified row has the same
effect as returning <literal>OK</literal>, that is the operation proceeds.
The trigger return value is ignored for all other types of triggers.
</para>
<tip>
<para>
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>
</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.
<productname>PostgreSQL</productname> requires that a procedure that is
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>
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
version number, and additional words are field name/value pairs
providing detailed information about the error.
Fields <varname>SQLSTATE</>, <varname>condition</>,
and <varname>message</> are always supplied
Fields <varname>SQLSTATE</varname>, <varname>condition</varname>,
and <varname>message</varname> are always supplied
(the first two represent the error code and condition name as shown
in <xref linkend="errcodes-appendix">).
Fields that may be present include
<varname>detail</>, <varname>hint</>, <varname>context</>,
<varname>schema</>, <varname>table</>, <varname>column</>,
<varname>datatype</>, <varname>constraint</>,
<varname>statement</>, <varname>cursor_position</>,
<varname>filename</>, <varname>lineno</>, and
<varname>funcname</>.
<varname>detail</varname>, <varname>hint</varname>, <varname>context</varname>,
<varname>schema</varname>, <varname>table</varname>, <varname>column</varname>,
<varname>datatype</varname>, <varname>constraint</varname>,
<varname>statement</varname>, <varname>cursor_position</varname>,
<varname>filename</varname>, <varname>lineno</varname>, and
<varname>funcname</varname>.
</para>
<para>
@ -1006,7 +1006,7 @@ $$ LANGUAGE pltcl;
<para>
This section lists configuration parameters that
affect <application>PL/Tcl</>.
affect <application>PL/Tcl</application>.
</para>
<variablelist>
@ -1015,7 +1015,7 @@ $$ LANGUAGE pltcl;
<term>
<varname>pltcl.start_proc</varname> (<type>string</type>)
<indexterm>
<primary><varname>pltcl.start_proc</> configuration parameter</primary>
<primary><varname>pltcl.start_proc</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
@ -1031,8 +1031,8 @@ $$ LANGUAGE pltcl;
</para>
<para>
The referenced function must be written in the <literal>pltcl</>
language, and must not be marked <literal>SECURITY DEFINER</>.
The referenced function must be written in the <literal>pltcl</literal>
language, and must not be marked <literal>SECURITY DEFINER</literal>.
(These restrictions ensure that it runs in the interpreter it's
supposed to initialize.) The current user must have permission to
call it, too.
@ -1060,14 +1060,14 @@ $$ LANGUAGE pltcl;
<term>
<varname>pltclu.start_proc</varname> (<type>string</type>)
<indexterm>
<primary><varname>pltclu.start_proc</> configuration parameter</primary>
<primary><varname>pltclu.start_proc</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<para>
This parameter is exactly like <varname>pltcl.start_proc</varname>,
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>
</listitem>
</varlistentry>
@ -1084,7 +1084,7 @@ $$ LANGUAGE pltcl;
differ. Tcl, however, requires all procedure names to be distinct.
PL/Tcl deals with this by making the internal Tcl procedure names contain
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
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

View File

@ -8,7 +8,7 @@
</indexterm>
<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
stored in external <productname>PostgreSQL</productname> servers.
</para>
@ -16,17 +16,17 @@
<para>
The functionality provided by this module overlaps substantially
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
better performance in many cases.
</para>
<para>
To prepare for remote access using <filename>postgres_fdw</>:
To prepare for remote access using <filename>postgres_fdw</filename>:
<orderedlist spacing="compact">
<listitem>
<para>
Install the <filename>postgres_fdw</> extension using <xref
Install the <filename>postgres_fdw</filename> extension using <xref
linkend="sql-createextension">.
</para>
</listitem>
@ -61,17 +61,17 @@
</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 remote table using <command>INSERT</>, <command>UPDATE</>, or
<command>DELETE</>. (Of course, the remote user you have specified
the remote table using <command>INSERT</command>, <command>UPDATE</command>, or
<command>DELETE</command>. (Of course, the remote user you have specified
in your user mapping must have privileges to do these things.)
</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
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
is omitted.
</para>
@ -79,10 +79,10 @@
<para>
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
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
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.
</para>
@ -99,8 +99,8 @@
<title>Connection Options</title>
<para>
A foreign server using the <filename>postgres_fdw</> foreign data wrapper
can have the same options that <application>libpq</> accepts in
A foreign server using the <filename>postgres_fdw</filename> foreign data wrapper
can have the same options that <application>libpq</application> accepts in
connection strings, as described in <xref linkend="libpq-paramkeywords">,
except that these options are not allowed:
@ -113,14 +113,14 @@
</listitem>
<listitem>
<para>
<literal>client_encoding</> (this is automatically set from the local
<literal>client_encoding</literal> (this is automatically set from the local
server encoding)
</para>
</listitem>
<listitem>
<para>
<literal>fallback_application_name</> (always set to
<literal>postgres_fdw</>)
<literal>fallback_application_name</literal> (always set to
<literal>postgres_fdw</literal>)
</para>
</listitem>
</itemizedlist>
@ -186,14 +186,14 @@
<title>Cost Estimation Options</title>
<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
foreign table should be whatever it costs to be done on the remote
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
for overhead &mdash; but for simple queries, it may not be worth the cost
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:
</para>
@ -204,7 +204,7 @@
<listitem>
<para>
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.
A setting for a foreign table overrides any setting for its server,
but only for that table.
@ -245,11 +245,11 @@
<para>
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
<literal>fdw_tuple_cost</literal> to the cost estimates. When
<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
<literal>fdw_tuple_cost</literal> to the cost estimates. This local
estimation is unlikely to be very accurate unless local copies of the
@ -268,12 +268,12 @@
<title>Remote Execution Options</title>
<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
involving non-built-in functions are checked locally after rows are
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
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:
</para>
@ -284,7 +284,7 @@
<listitem>
<para>
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
and operators that are immutable and belong to a listed extension will
be considered shippable to the remote server.
@ -293,7 +293,7 @@
<para>
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
queries may fail or behave unexpectedly.
</para>
@ -304,11 +304,11 @@
<term><literal>fetch_size</literal></term>
<listitem>
<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
table or a foreign server. The option specified on a table overrides
an option specified for the server.
The default is <literal>100</>.
The default is <literal>100</literal>.
</para>
</listitem>
</varlistentry>
@ -321,7 +321,7 @@
<title>Updatability Options</title>
<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:
</para>
@ -331,20 +331,20 @@
<term><literal>updatable</literal></term>
<listitem>
<para>
This option controls whether <filename>postgres_fdw</> allows foreign
tables to be modified using <command>INSERT</>, <command>UPDATE</> and
<command>DELETE</> commands. It can be specified for a foreign table
This option controls whether <filename>postgres_fdw</filename> allows foreign
tables to be modified using <command>INSERT</command>, <command>UPDATE</command> and
<command>DELETE</command> commands. It can be specified for a foreign table
or a foreign server. A table-level option overrides a server-level
option.
The default is <literal>true</>.
The default is <literal>true</literal>.
</para>
<para>
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
be thrown locally without querying the remote server. Note however
that the <literal>information_schema</> views will report a
<filename>postgres_fdw</> foreign table to be updatable (or not)
that the <literal>information_schema</literal> views will report a
<filename>postgres_fdw</filename> foreign table to be updatable (or not)
according to the setting of this option, without any check of the
remote server.
</para>
@ -358,7 +358,7 @@
<title>Importing Options</title>
<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
foreign table definitions on the local server that match tables or
views present on the remote server. If the remote tables to be imported
@ -368,7 +368,7 @@
<para>
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>
<variablelist>
@ -376,9 +376,9 @@
<term><literal>import_collate</literal></term>
<listitem>
<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
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
collation names than the local server does, which is likely to be the
case if it's running on a different operating system.
@ -389,13 +389,13 @@
<term><literal>import_default</literal></term>
<listitem>
<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
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
differently on the local server than they would be on the remote
server; <function>nextval()</> is a common source of problems.
The <command>IMPORT</> will fail altogether if an imported default
server; <function>nextval()</function> is a common source of problems.
The <command>IMPORT</command> will fail altogether if an imported default
expression uses a function or operator that does not exist locally.
</para>
</listitem>
@ -404,25 +404,25 @@
<term><literal>import_not_null</literal></term>
<listitem>
<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
from a foreign server. The default is <literal>true</>.
from a foreign server. The default is <literal>true</literal>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
Note that constraints other than <literal>NOT NULL</> will never be
imported from the remote tables. Although <productname>PostgreSQL</>
does support <literal>CHECK</> constraints on foreign tables, there is no
Note that constraints other than <literal>NOT NULL</literal> will never be
imported from the remote tables. Although <productname>PostgreSQL</productname>
does support <literal>CHECK</literal> constraints on foreign tables, there is no
provision for importing them automatically, because of the risk that a
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.
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.
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">.
</para>
@ -464,18 +464,18 @@
</para>
<para>
The remote transaction uses <literal>SERIALIZABLE</>
isolation level when the local transaction has <literal>SERIALIZABLE</>
isolation level; otherwise it uses <literal>REPEATABLE READ</>
The remote transaction uses <literal>SERIALIZABLE</literal>
isolation level when the local transaction has <literal>SERIALIZABLE</literal>
isolation level; otherwise it uses <literal>REPEATABLE READ</literal>
isolation level. This choice ensures that if a query performs multiple
table scans on the remote server, it will get snapshot-consistent results
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
concurrent updates are occurring on the remote server due to other
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
COMMITTED</> local transaction. A future
COMMITTED</literal> local transaction. A future
<productname>PostgreSQL</productname> release might modify these rules.
</para>
</sect2>
@ -484,42 +484,42 @@
<title>Remote Query Optimization</title>
<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
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
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
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
be <literal>IMMUTABLE</> as well.
For an <command>UPDATE</> or <command>DELETE</> query,
<filename>postgres_fdw</> attempts to optimize the query execution by
be <literal>IMMUTABLE</literal> as well.
For an <command>UPDATE</command> or <command>DELETE</command> query,
<filename>postgres_fdw</filename> attempts to optimize the query execution by
sending the whole query to the remote server if there are no query
<literal>WHERE</> clauses that cannot be sent to the remote server,
no local joins for the query, no row-level local <literal>BEFORE</> or
<literal>AFTER</> triggers on the target table, and no
<literal>CHECK OPTION</> constraints from parent views.
In <command>UPDATE</>,
<literal>WHERE</literal> clauses that cannot be sent to the remote server,
no local joins for the query, no row-level local <literal>BEFORE</literal> or
<literal>AFTER</literal> triggers on the target table, and no
<literal>CHECK OPTION</literal> constraints from parent views.
In <command>UPDATE</command>,
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.
</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,
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
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
<literal>WHERE</> clauses.
<literal>WHERE</literal> clauses.
</para>
<para>
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>
</sect2>
@ -527,55 +527,55 @@
<title>Remote Query Execution Environment</title>
<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
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
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
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,
any functions used in that view will be executed with the restricted
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
to establish their expected search path environment.
</para>
<para>
<filename>postgres_fdw</> likewise establishes remote session settings
<filename>postgres_fdw</filename> likewise establishes remote session settings
for various parameters:
<itemizedlist spacing="compact">
<listitem>
<para>
<xref linkend="guc-timezone"> is set to <literal>UTC</>
<xref linkend="guc-timezone"> is set to <literal>UTC</literal>
</para>
</listitem>
<listitem>
<para>
<xref linkend="guc-datestyle"> is set to <literal>ISO</>
<xref linkend="guc-datestyle"> is set to <literal>ISO</literal>
</para>
</listitem>
<listitem>
<para>
<xref linkend="guc-intervalstyle"> is set to <literal>postgres</>
<xref linkend="guc-intervalstyle"> is set to <literal>postgres</literal>
</para>
</listitem>
<listitem>
<para>
<xref linkend="guc-extra-float-digits"> is set to <literal>3</> for remote
servers 9.0 and newer and is set to <literal>2</> for older versions
<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</literal> for older versions
</para>
</listitem>
</itemizedlist>
These are less likely to be problematic than <varname>search_path</>, but
can be handled with function <literal>SET</> options if the need arises.
These are less likely to be problematic than <varname>search_path</varname>, but
can be handled with function <literal>SET</literal> options if the need arises.
</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
to cause <filename>postgres_fdw</> to malfunction.
to cause <filename>postgres_fdw</filename> to malfunction.
</para>
</sect2>
@ -583,19 +583,19 @@
<title>Cross-Version Compatibility</title>
<para>
<filename>postgres_fdw</> can be used with remote servers dating back
to <productname>PostgreSQL</> 8.3. Read-only capability is available
back to 8.1. A limitation however is that <filename>postgres_fdw</>
<filename>postgres_fdw</filename> can be used with remote servers dating back
to <productname>PostgreSQL</productname> 8.3. Read-only capability is available
back to 8.1. A limitation however is that <filename>postgres_fdw</filename>
generally assumes that immutable built-in functions and operators are
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
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
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
outside the sub-<literal>SELECT</>.
outside the sub-<literal>SELECT</literal>.
</para>
</sect2>
@ -604,7 +604,7 @@
<para>
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>
<programlisting>
@ -613,7 +613,7 @@ CREATE EXTENSION postgres_fdw;
<para>
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
port <literal>5432</literal>. The database to which the connection is made
is named <literal>foreign_db</literal> on the remote server:
@ -640,9 +640,9 @@ CREATE USER MAPPING FOR local_user
<para>
Now it is possible to create a foreign table with
<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
be <structname>foreign_table</>:
be <structname>foreign_table</structname>:
<programlisting>
CREATE FOREIGN TABLE foreign_table (
@ -654,8 +654,8 @@ CREATE FOREIGN TABLE foreign_table (
</programlisting>
It's essential that the data types and other properties of the columns
declared in <command>CREATE FOREIGN TABLE</> match the actual remote table.
Column names must match as well, unless you attach <literal>column_name</>
declared in <command>CREATE FOREIGN TABLE</command> match the actual remote table.
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
table.
In many cases, use of <xref linkend="sql-importforeignschema"> is

View File

@ -85,11 +85,11 @@
<para>
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
these issues are encouraged to read <xref linkend="tutorial">
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
similar functionality can be used as well.
</para>
@ -116,10 +116,10 @@
<partintro>
<para>
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
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
with the topics covered in this part.
</para>
@ -139,7 +139,7 @@
up their own server can begin their exploration with this part.
The rest of this part is about tuning and management; that material
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
linkend="sql"> for additional information.
</para>
@ -171,7 +171,7 @@
<partintro>
<para>
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
interfaces for client programs that are distributed separately and
contain their own documentation (<xref linkend="external-projects">
@ -197,7 +197,7 @@
This part is about extending the server functionality with
user-defined functions, data types, triggers, etc. These are
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
programming languages available in the
<productname>PostgreSQL</productname> distribution as well as
@ -234,7 +234,7 @@
<partintro>
<para>
This part contains assorted information that might be of use to
<productname>PostgreSQL</> developers.
<productname>PostgreSQL</productname> developers.
</para>
</partintro>

View File

@ -145,7 +145,7 @@
</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
web server to reproduce your problem. In any case remember to provide
the exact input files; do not guess that the problem happens for
@ -167,10 +167,10 @@
<note>
<para>
If you are reporting an error message, please obtain the most verbose
form of the message. In <application>psql</>, say <literal>\set
VERBOSITY verbose</> beforehand. If you are extracting the message
form of the message. In <application>psql</application>, say <literal>\set
VERBOSITY verbose</literal> beforehand. If you are extracting the message
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.
</para>
</note>
@ -236,9 +236,9 @@
If your version is older than &version; we will almost certainly
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
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
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
commercial support contract.
</para>
@ -283,8 +283,8 @@
are specifically talking about the backend process, mention that, do not
just say <quote>PostgreSQL crashes</quote>. A crash of a single
backend process is quite different from crash of the parent
<quote>postgres</> process; please don't say <quote>the server
crashed</> when you mean a single backend process went down, nor vice versa.
<quote>postgres</quote> process; please don't say <quote>the server
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>
are completely separate from the backend. Please try to be specific
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 use the bug-report web form, however.)
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
<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>
</note>
</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