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…
Reference in New Issue