mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03:00
Don't use SGML empty tags
For DocBook XML compatibility, don't use SGML empty tags (</>) anymore, replace by the full tag name. Add a warning option to catch future occurrences. Alexander Lakhin, Jürgen Purtz
This commit is contained in:
parent
6ecabead4b
commit
c29c578908
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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 < 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>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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] <> 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 — 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>&&</> operator,
|
||||
You can also search an array using the <literal>&&</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 && 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>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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
@ -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>
|
||||
|
@ -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.
|
||||
|
@ -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>
|
||||
|
@ -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 — col32</></term>
|
||||
<term><literal>col1 — 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>
|
||||
|
@ -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 — 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><<</>
|
||||
<literal>&<</>
|
||||
<literal>&&</>
|
||||
<literal>&></>
|
||||
<literal>>></>
|
||||
<literal>~=</>
|
||||
<literal>@></>
|
||||
<literal><@</>
|
||||
<literal>&<|</>
|
||||
<literal><<|</>
|
||||
<literal><<</literal>
|
||||
<literal>&<</literal>
|
||||
<literal>&&</literal>
|
||||
<literal>&></literal>
|
||||
<literal>>></literal>
|
||||
<literal>~=</literal>
|
||||
<literal>@></literal>
|
||||
<literal><@</literal>
|
||||
<literal>&<|</literal>
|
||||
<literal><<|</literal>
|
||||
<literal>|>></literal>
|
||||
<literal>|&></>
|
||||
<literal>|&></literal>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
@ -249,11 +249,11 @@
|
||||
<entry><literal>network_inclusion_ops</literal></entry>
|
||||
<entry><type>inet</type></entry>
|
||||
<entry>
|
||||
<literal>&&</>
|
||||
<literal>>>=</>
|
||||
<literal>&&</literal>
|
||||
<literal>>>=</literal>
|
||||
<literal><<=</literal>
|
||||
<literal>=</literal>
|
||||
<literal>>></>
|
||||
<literal>>></literal>
|
||||
<literal><<</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><<</>
|
||||
<literal>&<</>
|
||||
<literal>&&</>
|
||||
<literal>&></>
|
||||
<literal>>></>
|
||||
<literal>@></>
|
||||
<literal><@</>
|
||||
<literal>-|-</>
|
||||
<literal>=</>
|
||||
<literal><<</literal>
|
||||
<literal>&<</literal>
|
||||
<literal>&&</literal>
|
||||
<literal>&></literal>
|
||||
<literal>>></literal>
|
||||
<literal>@></literal>
|
||||
<literal><@</literal>
|
||||
<literal>-|-</literal>
|
||||
<literal>=</literal>
|
||||
<literal><</literal>
|
||||
<literal><=</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>
|
||||
|
@ -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>
|
||||
|
@ -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><></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><-></>,
|
||||
<filename>btree_gist</filename> defines a distance operator <literal><-></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
@ -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 < ('foo' COLLATE "fr_FR") FROM test1;
|
||||
SELECT a < 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><</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" < 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" < 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" < 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>
|
||||
|
@ -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ø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>
|
||||
|
@ -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
@ -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 — 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</> — to delete the referencing row,
|
||||
<literal>restrict</> — to abort transaction if referencing keys
|
||||
exist, <literal>setnull</> — to set referencing key fields to null),
|
||||
(<literal>cascade</literal> — to delete the referencing row,
|
||||
<literal>restrict</literal> — to abort transaction if referencing keys
|
||||
exist, <literal>setnull</literal> — 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 — 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 — 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 — 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 — 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 — 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 — 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>
|
||||
|
@ -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.
|
||||
|
@ -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 — 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 — 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 && b</></entry>
|
||||
<entry><type>boolean</></entry>
|
||||
<entry><literal>a && b</literal></entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>The cubes a and b overlap.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>a @> b</></entry>
|
||||
<entry><type>boolean</></entry>
|
||||
<entry><literal>a @> b</literal></entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>The cube a contains the cube b.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>a <@ b</></entry>
|
||||
<entry><type>boolean</></entry>
|
||||
<entry><literal>a <@ b</literal></entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>The cube a is contained in the cube b.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>a < b</></entry>
|
||||
<entry><type>boolean</></entry>
|
||||
<entry><literal>a < b</literal></entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>The cube a is less than the cube b.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>a <= b</></entry>
|
||||
<entry><type>boolean</></entry>
|
||||
<entry><literal>a <= 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 > b</></entry>
|
||||
<entry><type>boolean</></entry>
|
||||
<entry><literal>a > b</literal></entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>The cube a is greater than the cube b.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>a >= b</></entry>
|
||||
<entry><type>boolean</></entry>
|
||||
<entry><literal>a >= 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 <> b</></entry>
|
||||
<entry><type>boolean</></entry>
|
||||
<entry><literal>a <> 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 -> n</></entry>
|
||||
<entry><type>float8</></entry>
|
||||
<entry>Get <replaceable>n</>-th coordinate of cube (counting from 1).</entry>
|
||||
<entry><literal>a -> 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 ~> n</></entry>
|
||||
<entry><type>float8</></entry>
|
||||
<entry><literal>a ~> 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 — upper right</>; that is, the
|
||||
the form <quote>lower left — upper right</quote>; that is, the
|
||||
smaller endpoint along each dimension appears first.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>a <-> b</></entry>
|
||||
<entry><type>float8</></entry>
|
||||
<entry><literal>a <-> b</literal></entry>
|
||||
<entry><type>float8</type></entry>
|
||||
<entry>Euclidean distance between a and b.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>a <#> b</></entry>
|
||||
<entry><type>float8</></entry>
|
||||
<entry><literal>a <#> b</literal></entry>
|
||||
<entry><type>float8</type></entry>
|
||||
<entry>Taxicab (L-1 metric) distance between a and b.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>a <=> b</></entry>
|
||||
<entry><type>float8</></entry>
|
||||
<entry><literal>a <=> 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>@></> and <literal><@</> were
|
||||
respectively called <literal>@</> and <literal>~</>. These names are still available, but are
|
||||
(Before PostgreSQL 8.2, the containment operators <literal>@></literal> and <literal><@</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><</>, <literal>>=</>, etc)
|
||||
The scalar ordering operators (<literal><</literal>, <literal>>=</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>&&</>, <literal>@></>, and
|
||||
<literal><@</> 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>&&</literal>, <literal>@></literal>, and
|
||||
<literal><@</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><-></>, <literal><#></>, and
|
||||
<literal><=></> in <literal>ORDER BY</> clauses.
|
||||
<literal><-></literal>, <literal><#></literal>, and
|
||||
<literal><=></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 <-> cube(array[0.5,0.5,0.5]) LIMIT 1;
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <literal>~></> operator can also be used in this way to
|
||||
The <literal>~></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 ~> 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 ~> 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 ~> 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 ~> 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>
|
||||
< 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</> > 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> > 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>
|
||||
|
||||
|
@ -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
@ -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 — 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 — 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 — 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>
|
||||
|
||||
|
@ -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 — 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 — 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
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 — 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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>@></>
|
||||
<literal>@></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><@></literal> <type>point</></entry>
|
||||
<entry><type>point</type> <literal><@></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
@ -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>
|
||||
|
@ -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 — databases, roles, and tablespaces
|
||||
— 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)->context != NULL && IsA((fcinfo)->context, EventTriggerData))
|
||||
</programlisting>
|
||||
If this returns true, then it is safe to cast
|
||||
<literal>fcinfo->context</> to type <literal>EventTriggerData
|
||||
<literal>fcinfo->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>
|
||||
|
||||
|
@ -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 — 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
|
||||
|
@ -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
@ -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
@ -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 — <function>similarity</> would have been
|
||||
function is misnamed — <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 — 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 — 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>
|
||||
|
@ -30,12 +30,12 @@ while (<$errcodes>)
|
||||
s/-/—/;
|
||||
|
||||
# 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;
|
||||
|
@ -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)</> — start
|
||||
<function>state = GenericXLogStart(relation)</function> — 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>
|
||||
— 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)</> — apply the changes to
|
||||
<function>GenericXLogFinish(state)</function> — 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
|
||||
|
@ -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 — 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
|
||||
|
@ -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>&&</>
|
||||
<literal><@</>
|
||||
<literal>=</>
|
||||
<literal>@></>
|
||||
<literal>&&</literal>
|
||||
<literal><@</literal>
|
||||
<literal>=</literal>
|
||||
<literal>@></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>?&</>
|
||||
<literal>?|</>
|
||||
<literal>@></>
|
||||
<literal>?</literal>
|
||||
<literal>?&</literal>
|
||||
<literal>?|</literal>
|
||||
<literal>@></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>@></>
|
||||
<literal>@></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>
|
||||
|
@ -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>&&</>
|
||||
<literal>&></>
|
||||
<literal>&<</>
|
||||
<literal>&<|</>
|
||||
<literal>>></>
|
||||
<literal><<</>
|
||||
<literal><<|</>
|
||||
<literal><@</>
|
||||
<literal>@></>
|
||||
<literal>@</>
|
||||
<literal>|&></>
|
||||
<literal>|>></>
|
||||
<literal>~</>
|
||||
<literal>~=</>
|
||||
<literal>&&</literal>
|
||||
<literal>&></literal>
|
||||
<literal>&<</literal>
|
||||
<literal>&<|</literal>
|
||||
<literal>>></literal>
|
||||
<literal><<</literal>
|
||||
<literal><<|</literal>
|
||||
<literal><@</literal>
|
||||
<literal>@></literal>
|
||||
<literal>@</literal>
|
||||
<literal>|&></literal>
|
||||
<literal>|>></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>&&</>
|
||||
<literal>&></>
|
||||
<literal>&<</>
|
||||
<literal>&<|</>
|
||||
<literal>>></>
|
||||
<literal><<</>
|
||||
<literal><<|</>
|
||||
<literal><@</>
|
||||
<literal>@></>
|
||||
<literal>@</>
|
||||
<literal>|&></>
|
||||
<literal>|>></>
|
||||
<literal>~</>
|
||||
<literal>~=</>
|
||||
<literal>&&</literal>
|
||||
<literal>&></literal>
|
||||
<literal>&<</literal>
|
||||
<literal>&<|</literal>
|
||||
<literal>>></literal>
|
||||
<literal><<</literal>
|
||||
<literal><<|</literal>
|
||||
<literal><@</literal>
|
||||
<literal>@></literal>
|
||||
<literal>@</literal>
|
||||
<literal>|&></literal>
|
||||
<literal>|>></literal>
|
||||
<literal>~</literal>
|
||||
<literal>~=</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
<literal><-></>
|
||||
<literal><-></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>&&</>
|
||||
<literal>>></>
|
||||
<literal>>>=</>
|
||||
<literal>></>
|
||||
<literal>>=</>
|
||||
<literal><></>
|
||||
<literal><<</>
|
||||
<literal><<=</>
|
||||
<literal><</>
|
||||
<literal><=</>
|
||||
<literal>=</>
|
||||
<literal>&&</literal>
|
||||
<literal>>></literal>
|
||||
<literal>>>=</literal>
|
||||
<literal>></literal>
|
||||
<literal>>=</literal>
|
||||
<literal><></literal>
|
||||
<literal><<</literal>
|
||||
<literal><<=</literal>
|
||||
<literal><</literal>
|
||||
<literal><=</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>>></>
|
||||
<literal>>^</>
|
||||
<literal><<</>
|
||||
<literal><@</>
|
||||
<literal><@</>
|
||||
<literal><@</>
|
||||
<literal><^</>
|
||||
<literal>~=</>
|
||||
<literal>>></literal>
|
||||
<literal>>^</literal>
|
||||
<literal><<</literal>
|
||||
<literal><@</literal>
|
||||
<literal><@</literal>
|
||||
<literal><@</literal>
|
||||
<literal><^</literal>
|
||||
<literal>~=</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
<literal><-></>
|
||||
<literal><-></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>&&</>
|
||||
<literal>&></>
|
||||
<literal>&<</>
|
||||
<literal>&<|</>
|
||||
<literal>>></>
|
||||
<literal><<</>
|
||||
<literal><<|</>
|
||||
<literal><@</>
|
||||
<literal>@></>
|
||||
<literal>@</>
|
||||
<literal>|&></>
|
||||
<literal>|>></>
|
||||
<literal>~</>
|
||||
<literal>~=</>
|
||||
<literal>&&</literal>
|
||||
<literal>&></literal>
|
||||
<literal>&<</literal>
|
||||
<literal>&<|</literal>
|
||||
<literal>>></literal>
|
||||
<literal><<</literal>
|
||||
<literal><<|</literal>
|
||||
<literal><@</literal>
|
||||
<literal>@></literal>
|
||||
<literal>@</literal>
|
||||
<literal>|&></literal>
|
||||
<literal>|>></literal>
|
||||
<literal>~</literal>
|
||||
<literal>~=</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
<literal><-></>
|
||||
<literal><-></literal>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>range_ops</></entry>
|
||||
<entry><literal>range_ops</literal></entry>
|
||||
<entry>any range type</entry>
|
||||
<entry>
|
||||
<literal>&&</>
|
||||
<literal>&></>
|
||||
<literal>&<</>
|
||||
<literal>>></>
|
||||
<literal><<</>
|
||||
<literal><@</>
|
||||
<literal>-|-</>
|
||||
<literal>=</>
|
||||
<literal>@></>
|
||||
<literal>@></>
|
||||
<literal>&&</literal>
|
||||
<literal>&></literal>
|
||||
<literal>&<</literal>
|
||||
<literal>>></literal>
|
||||
<literal><<</literal>
|
||||
<literal><@</literal>
|
||||
<literal>-|-</literal>
|
||||
<literal>=</literal>
|
||||
<literal>@></literal>
|
||||
<literal>@></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><@</>
|
||||
<literal>@></>
|
||||
<literal><@</literal>
|
||||
<literal>@></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 — 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->flinfo->fn_mcxt</>, and
|
||||
keep a pointer to it in <literal>fcinfo->flinfo->fn_extra</>. Such
|
||||
the longer-lived data in <literal>fcinfo->flinfo->fn_mcxt</literal>, and
|
||||
keep a pointer to it in <literal>fcinfo->flinfo->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
@ -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>
|
||||
|
@ -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>=></>
|
||||
<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>=></literal>
|
||||
<replaceable>value</replaceable> pairs separated by commas. Some examples:
|
||||
|
||||
<synopsis>
|
||||
k => v
|
||||
@ -31,15 +31,15 @@ foo => bar, baz => whatever
|
||||
</synopsis>
|
||||
|
||||
The order of the pairs is not significant (and may not be reproduced on
|
||||
output). Whitespace between pairs or around the <literal>=></> sign is
|
||||
output). Whitespace between pairs or around the <literal>=></literal> sign is
|
||||
ignored. Double-quote keys and values that include whitespace, commas,
|
||||
<literal>=</>s or <literal>></>s. To include a double quote or a
|
||||
<literal>=</literal>s or <literal>></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=>1,a=>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 => 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 => 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 => 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 => NULL
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><type>hstore</> <literal>-></> <type>text</></entry>
|
||||
<entry>get value for key (<literal>NULL</> if not present)</entry>
|
||||
<entry><type>hstore</type> <literal>-></literal> <type>text</type></entry>
|
||||
<entry>get value for key (<literal>NULL</literal> if not present)</entry>
|
||||
<entry><literal>'a=>x, b=>y'::hstore -> 'a'</literal></entry>
|
||||
<entry><literal>x</literal></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><type>hstore</> <literal>-></> <type>text[]</></entry>
|
||||
<entry>get values for keys (<literal>NULL</> if not present)</entry>
|
||||
<entry><type>hstore</type> <literal>-></literal> <type>text[]</type></entry>
|
||||
<entry>get values for keys (<literal>NULL</literal> if not present)</entry>
|
||||
<entry><literal>'a=>x, b=>y, c=>z'::hstore -> 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=>b, c=>d'::hstore || 'c=>x, d=>q'::hstore</literal></entry>
|
||||
<entry><literal>"a"=>"b", "c"=>"x", "d"=>"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=>1'::hstore ? 'a'</literal></entry>
|
||||
<entry><literal>t</literal></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><type>hstore</> <literal>?&</> <type>text[]</></entry>
|
||||
<entry>does <type>hstore</> contain all specified keys?</entry>
|
||||
<entry><type>hstore</type> <literal>?&</literal> <type>text[]</type></entry>
|
||||
<entry>does <type>hstore</type> contain all specified keys?</entry>
|
||||
<entry><literal>'a=>1,b=>2'::hstore ?& 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=>1,b=>2'::hstore ?| ARRAY['b','c']</literal></entry>
|
||||
<entry><literal>t</literal></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><type>hstore</> <literal>@></> <type>hstore</></entry>
|
||||
<entry><type>hstore</type> <literal>@></literal> <type>hstore</type></entry>
|
||||
<entry>does left operand contain right?</entry>
|
||||
<entry><literal>'a=>b, b=>1, c=>NULL'::hstore @> 'b=>1'</literal></entry>
|
||||
<entry><literal>t</literal></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><type>hstore</> <literal><@</> <type>hstore</></entry>
|
||||
<entry><type>hstore</type> <literal><@</literal> <type>hstore</type></entry>
|
||||
<entry>is left operand contained in right?</entry>
|
||||
<entry><literal>'a=>c'::hstore <@ 'a=>b, b=>1, c=>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=>1, b=>2, c=>3'::hstore - 'b'::text</literal></entry>
|
||||
<entry><literal>"a"=>"1", "c"=>"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=>1, b=>2, c=>3'::hstore - ARRAY['a','b']</literal></entry>
|
||||
<entry><literal>"c"=>"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=>1, b=>2, c=>3'::hstore - 'a=>4, b=>2'::hstore</literal></entry>
|
||||
<entry><literal>"a"=>"1", "c"=>"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=>foo, b=>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=>foo, b=>bar'::hstore</literal></entry>
|
||||
<entry><literal>{{a,foo},{b,bar}}</literal></entry>
|
||||
</row>
|
||||
@ -209,8 +209,8 @@ key => NULL
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Prior to PostgreSQL 8.2, the containment operators <literal>@></>
|
||||
and <literal><@</> were called <literal>@</> and <literal>~</>,
|
||||
Prior to PostgreSQL 8.2, the containment operators <literal>@></literal>
|
||||
and <literal><@</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 => 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 => 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=>1,f2=>2</literal></entry>
|
||||
</row>
|
||||
@ -243,7 +243,7 @@ key => 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=>1, b=>2, c=>3, d=>4</literal></entry>
|
||||
@ -252,7 +252,7 @@ key => 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"=>"1","b"=>"2"</literal></entry>
|
||||
</row>
|
||||
@ -260,7 +260,7 @@ key => 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"=>"b"</literal></entry>
|
||||
</row>
|
||||
@ -268,7 +268,7 @@ key => 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=>1,b=>2')</literal></entry>
|
||||
<entry><literal>{a,b}</literal></entry>
|
||||
</row>
|
||||
@ -276,7 +276,7 @@ key => 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=>1,b=>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=>1,b=>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=>1,b=>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=>1,b=>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=>1,b=>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=>1,b=>2,c=>3'::hstore, ARRAY['b','c','x'])</literal></entry>
|
||||
<entry><literal>"b"=>"2", "c"=>"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=>1,b=>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=>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=>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>@></>,
|
||||
<literal>?</>, <literal>?&</> and <literal>?|</> operators. For example:
|
||||
<type>hstore</type> has GiST and GIN index support for the <literal>@></literal>,
|
||||
<literal>?</literal>, <literal>?&</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"=>"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
@ -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 — 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 >= 42 AND c < 77</>,
|
||||
query condition <literal>WHERE a = 5 AND b >= 42 AND c < 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</> >= 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> >= 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>
|
||||
— 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 — 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 < 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 > 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 < 1</quote> implies <quote>x < 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><</>,
|
||||
<literal><=</>, <literal>></>, or <literal>>=</> comparisons
|
||||
class if you want queries involving ordinary <literal><</literal>,
|
||||
<literal><=</literal>, <literal>></literal>, or <literal>>=</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 < 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 < 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) < 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>
|
||||
|
@ -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
@ -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-<version>.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-<version>.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
@ -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
|
||||
|
@ -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 — <parameter>dir</> must be <literal>asc</> or <literal>desc</></entry>
|
||||
<entry>sort array — <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[] && int[]</literal></entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>overlap — <literal>true</> if arrays have at least one common element</entry>
|
||||
<entry>overlap — <literal>true</literal> if arrays have at least one common element</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>int[] @> int[]</literal></entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>contains — <literal>true</> if left array contains right array</entry>
|
||||
<entry>contains — <literal>true</literal> if left array contains right array</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>int[] <@ int[]</literal></entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>contained — <literal>true</> if left array is contained in right array</entry>
|
||||
<entry>contained — <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>@></> and
|
||||
<literal><@</> were respectively called <literal>@</> and <literal>~</>.
|
||||
(Before PostgreSQL 8.2, the containment operators <literal>@></literal> and
|
||||
<literal><@</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>&&</>, <literal>@></> and
|
||||
<literal><@</> are equivalent to <productname>PostgreSQL</>'s built-in
|
||||
The operators <literal>&&</literal>, <literal>@></literal> and
|
||||
<literal><@</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>&</>
|
||||
(AND), <literal>|</> (OR), and <literal>!</> (NOT). Parentheses
|
||||
the array, possibly combined using the operators <literal>&</literal>
|
||||
(AND), <literal>|</literal> (OR), and <literal>!</literal> (NOT). Parentheses
|
||||
can be used as needed. For example,
|
||||
the query <literal>1&(2|3)</> matches arrays that contain 1
|
||||
the query <literal>1&(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>&&</>, <literal>@></>, <literal><@</>,
|
||||
and <literal>@@</> operators, as well as regular array equality.
|
||||
<filename>intarray</filename> provides index support for the
|
||||
<literal>&&</literal>, <literal>@></literal>, <literal><@</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&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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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 @> '[1, 2, 2]'::jsonb;
|
||||
-- within the object on the left side:
|
||||
SELECT '{"product": "PostgreSQL", "version": 9.4, "jsonb": true}'::jsonb @> '{"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 @> '[1, 3]'::jsonb; -- yields false
|
||||
|
||||
@ -319,10 +319,10 @@ SELECT '"bar"'::jsonb @> '["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->'site_name' FROM websites
|
||||
WHERE doc @> '{"tags":[{"term":"paris"}, {"term":"food"}]}';
|
||||
@ -385,7 +385,7 @@ SELECT doc->'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->'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>?&</>
|
||||
and <literal>?|</> operators and path/value-exists operator
|
||||
<literal>@></>.
|
||||
The default GIN operator class for <type>jsonb</type> supports queries with
|
||||
top-level key-exists operators <literal>?</literal>, <literal>?&</literal>
|
||||
and <literal>?|</literal> operators and path/value-exists operator
|
||||
<literal>@></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>@></> operator only.
|
||||
The non-default GIN operator class <literal>jsonb_path_ops</literal>
|
||||
supports indexing the <literal>@></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->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"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->'guid', jdoc->'name' FROM api WHERE jdoc -> '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 -> 'tags'));
|
||||
</programlisting>
|
||||
Now, the <literal>WHERE</> clause <literal>jdoc -> 'tags' ? 'qui'</>
|
||||
Now, the <literal>WHERE</literal> clause <literal>jdoc -> 'tags' ? 'qui'</literal>
|
||||
will be recognized as an application of the indexable
|
||||
operator <literal>?</> to the indexed
|
||||
expression <literal>jdoc -> 'tags'</>.
|
||||
operator <literal>?</literal> to the indexed
|
||||
expression <literal>jdoc -> '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 -> 'tags'));
|
||||
-- Find documents in which the key "tags" contains array element "qui"
|
||||
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"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->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qu
|
||||
|
||||
<para>
|
||||
Although the <literal>jsonb_path_ops</literal> operator class supports
|
||||
only queries with the <literal>@></> operator, it has notable
|
||||
only queries with the <literal>@></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->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"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->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"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->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"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
@ -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 — 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>
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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>
|
||||
|
@ -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 — 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 — 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>&</> (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>&</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 & Russia*@ & !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 & Russia*@ & !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 & Russia*@ & !Transportation
|
||||
<title>Operators and Functions</title>
|
||||
|
||||
<para>
|
||||
Type <type>ltree</> has the usual comparison operators
|
||||
<literal>=</>, <literal><></literal>,
|
||||
<literal><</>, <literal>></>, <literal><=</>, <literal>>=</>.
|
||||
Type <type>ltree</type> has the usual comparison operators
|
||||
<literal>=</literal>, <literal><></literal>,
|
||||
<literal><</literal>, <literal>></literal>, <literal><=</literal>, <literal>>=</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 & Russia*@ & !Transportation
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><type>ltree</> <literal>@></> <type>ltree</></entry>
|
||||
<entry><type>ltree</type> <literal>@></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><@</> <type>ltree</></entry>
|
||||
<entry><type>ltree</type> <literal><@</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>@></> <type>ltree</></entry>
|
||||
<entry><type>ltree[]</type> <literal>@></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><@</> <type>ltree[]</></entry>
|
||||
<entry><type>ltree</type> <literal><@</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><@</> <type>ltree</></entry>
|
||||
<entry><type>ltree[]</type> <literal><@</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>ltree[]</></entry>
|
||||
<entry><type>ltree</type> <literal>@></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>?@></> <type>ltree</></entry>
|
||||
<entry><type>ltree[]</type> <literal>?@></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>?<@</> <type>ltree</></entry>
|
||||
<entry><type>ltree[]</type> <literal>?<@</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 & Russia*@ & !Transportation
|
||||
<para>
|
||||
The operators <literal><@</literal>, <literal>@></literal>,
|
||||
<literal>@</literal> and <literal>~</literal> have analogues
|
||||
<literal>^<@</>, <literal>^@></>, <literal>^@</>,
|
||||
<literal>^<@</literal>, <literal>^@></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 & Russia*@ & !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 & Russia*@ & !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 & Russia*@ & !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 & Russia*@ & !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 & Russia*@ & !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 & Russia*@ & !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 & Russia*@ & !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 & Russia*@ & !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 & Russia*@ & !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><</>, <literal><=</>, <literal>=</>,
|
||||
<literal>>=</>, <literal>></literal>
|
||||
B-tree index over <type>ltree</type>:
|
||||
<literal><</literal>, <literal><=</literal>, <literal>=</literal>,
|
||||
<literal>>=</literal>, <literal>></literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
GiST index over <type>ltree</>:
|
||||
<literal><</>, <literal><=</>, <literal>=</>,
|
||||
<literal>>=</>, <literal>></>,
|
||||
<literal>@></>, <literal><@</>,
|
||||
<literal>@</>, <literal>~</>, <literal>?</literal>
|
||||
GiST index over <type>ltree</type>:
|
||||
<literal><</literal>, <literal><=</literal>, <literal>=</literal>,
|
||||
<literal>>=</literal>, <literal>></literal>,
|
||||
<literal>@></literal>, <literal><@</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[] <@ ltree</>, <literal>ltree @> ltree[]</>,
|
||||
<literal>@</>, <literal>~</>, <literal>?</literal>
|
||||
GiST index over <type>ltree[]</type>:
|
||||
<literal>ltree[] <@ ltree</literal>, <literal>ltree @> 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>
|
||||
|
||||
|
@ -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 — 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 — 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>
|
||||
|
@ -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
@ -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 — 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>
|
||||
|
@ -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 — 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>
|
||||
|
@ -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>=></>, and shell commands are preceded by the
|
||||
prompt <literal>$</>. Normally, prompts are not shown, though.
|
||||
prompt <literal>=></literal>, and shell commands are preceded by the
|
||||
prompt <literal>$</literal>. Normally, prompts are not shown, though.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -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 — 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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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 < 7000;
|
||||
@ -200,21 +200,21 @@ EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 7000;
|
||||
Filter: (unique1 < 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 < 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 < 100 AND stringu1 = 'xxx';
|
||||
@ -266,15 +266,15 @@ EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 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 < 100 AND unique2 > 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 < 100 AND unique2 > 9000 LIMIT 2;
|
||||
@ -335,7 +335,7 @@ EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 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 < 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 < 10</>
|
||||
are the same as we'd get from <literal>SELECT ... WHERE unique1 < 10</literal>
|
||||
because we are
|
||||
applying the <literal>WHERE</> clause <literal>unique1 < 10</literal>
|
||||
applying the <literal>WHERE</literal> clause <literal>unique1 < 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 < 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 < 10 AND t2.unique2 < 10 AND t1.hundred < t2.hundred;
|
||||
</screen>
|
||||
|
||||
The condition <literal>t1.hundred < 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 < 10 AND t2.unique2 < 10 AND t1.hundred < 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 < 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 < 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 < 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 < 100 AND t1.unique2 = t2.unique2;
|
||||
-> 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 < 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 < 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 < 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 < 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 @> 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 < 100 AND unique2 > 9000;
|
||||
@ -714,7 +714,7 @@ EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM tenk1 WHERE unique1 < 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 < 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 < 100 AND unique2 > 9000 LIMIT 2;
|
||||
@ -880,10 +880,10 @@ EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 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 — 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
|
||||
— 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 — but realize that
|
||||
the <option>--disable-triggers</option> option — 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>
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
— which is somewhat impractical. If the <parameter>iter_count</>
|
||||
— 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 — purposefully
|
||||
rather similar to <function>crypt()</function> algorithms — purposefully
|
||||
slow and with random salt — 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 — like handling <literal>ANYKEY</>.
|
||||
to see which fits — 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> — Blowfish</para></listitem>
|
||||
<listitem><para><literal>aes</literal> — 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>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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><%</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 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>%></literal> <type>text</></entry>
|
||||
<entry><type>text</type> <literal>%></literal> <type>text</type></entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>
|
||||
Commutator of the <literal><%</> operator.
|
||||
Commutator of the <literal><%</literal> operator.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><type>text</> <literal><-></literal> <type>text</></entry>
|
||||
<entry><type>text</type> <literal><-></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><<-></literal> <type>text</>
|
||||
<type>text</type> <literal><<-></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><->></literal> <type>text</>
|
||||
<type>text</type> <literal><->></literal> <type>text</type>
|
||||
</entry>
|
||||
<entry><type>real</type></entry>
|
||||
<entry>
|
||||
Commutator of the <literal><<-></> operator.
|
||||
Commutator of the <literal><<-></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><%</> and <literal>%></> operators. The threshold
|
||||
<literal><%</literal> and <literal>%></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 <-> '<replaceable>word</>' AS dist
|
||||
SELECT t, t <-> '<replaceable>word</replaceable>' AS dist
|
||||
FROM test_trgm
|
||||
ORDER BY dist LIMIT 10;
|
||||
</programlisting>
|
||||
@ -294,16 +294,16 @@ SELECT t, t <-> '<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</>' <% t
|
||||
WHERE '<replaceable>word</replaceable>' <% 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</>' <<-> t AS dist
|
||||
SELECT t, '<replaceable>word</replaceable>' <<-> t AS dist
|
||||
FROM test_trgm
|
||||
ORDER BY dist LIMIT 10;
|
||||
</programlisting>
|
||||
@ -321,8 +321,8 @@ SELECT t, '<replaceable>word</>' <<-> 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.
|
||||
|
@ -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.)
|
||||
|
@ -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 < 1000</> was an
|
||||
The previous example with <literal>unique1 < 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>< 1000</>) to each value of the MCV list, and adds up the
|
||||
<quote>< 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 < 'IAAAAA';
|
||||
Filter: (stringu1 < '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 <
|
||||
'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>
|
||||
|
@ -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->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->fn_extra</structfield> is already non-<symbol>NULL</>
|
||||
<structfield>flinfo->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->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>
|
||||
|
@ -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->{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 — 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
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 — 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
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user