-<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.373 2007/04/02 03:49:36 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.374 2007/04/02 15:27:02 petere Exp $ -->
<chapter id="functions">
<title>Functions and Operators</title>
</sect1>
- <sect1 id="functions-sequence">
- <title>Sequence Manipulation Functions</title>
-
- <indexterm>
- <primary>sequence</primary>
- </indexterm>
- <indexterm>
- <primary>nextval</primary>
- </indexterm>
- <indexterm>
- <primary>currval</primary>
- </indexterm>
- <indexterm>
- <primary>lastval</primary>
- </indexterm>
- <indexterm>
- <primary>setval</primary>
- </indexterm>
+ <sect1 id="functions-xml">
+ <title>XML Functions</title>
<para>
- This section describes <productname>PostgreSQL</productname>'s functions
- for operating on <firstterm>sequence objects</firstterm>.
- Sequence objects (also called sequence generators or
- just sequences) are special single-row tables created with
- <command>CREATE SEQUENCE</command>. A sequence object is usually used to
- generate unique identifiers for rows of a table. The sequence functions,
- listed in <xref linkend="functions-sequence-table">,
- provide simple, multiuser-safe methods for obtaining successive
- sequence values from sequence objects.
+ The functions and function-like expressions described in this
+ section operate on values of type <type>xml</type>. Check <xref
+ linkend="datatype-xml"> for information about the <type>xml</type>
+ type. The function-like expressions <function>xmlparse</function>
+ and <function>xmlserialize</function> for converting to and from
+ type <type>xml</type> are not repeated here.
</para>
- <table id="functions-sequence-table">
- <title>Sequence Functions</title>
- <tgroup cols="3">
- <thead>
- <row><entry>Function</entry> <entry>Return Type</entry> <entry>Description</entry></row>
- </thead>
-
- <tbody>
- <row>
- <entry><literal><function>currval</function>(<type>regclass</type>)</literal></entry>
- <entry><type>bigint</type></entry>
- <entry>Return value most recently obtained with
- <function>nextval</function> for specified sequence</entry>
- </row>
- <row>
- <entry><literal><function>nextval</function>(<type>regclass</type>)</literal></entry>
- <entry><type>bigint</type></entry>
- <entry>Advance sequence and return new value</entry>
- </row>
- <row>
- <entry><literal><function>setval</function>(<type>regclass</type>, <type>bigint</type>)</literal></entry>
- <entry><type>bigint</type></entry>
- <entry>Set sequence's current value</entry>
- </row>
- <row>
- <entry><literal><function>setval</function>(<type>regclass</type>, <type>bigint</type>, <type>boolean</type>)</literal></entry>
- <entry><type>bigint</type></entry>
- <entry>Set sequence's current value and <literal>is_called</literal> flag</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>
- The sequence to be operated on by a sequence-function call is specified by
- a <type>regclass</> argument, which is just the OID of the sequence in the
- <structname>pg_class</> system catalog. You do not have to look up the
- OID by hand, however, since the <type>regclass</> data type's input
- converter will do the work for you. Just write the sequence name enclosed
- in single quotes, so that it looks like a literal constant. To
- achieve some compatibility with the handling of ordinary
- <acronym>SQL</acronym> names, the string will be converted to lowercase
- unless it contains double quotes around the sequence name. Thus:
-<programlisting>
-nextval('foo') <lineannotation>operates on sequence <literal>foo</literal></>
-nextval('FOO') <lineannotation>operates on sequence <literal>foo</literal></>
-nextval('"Foo"') <lineannotation>operates on sequence <literal>Foo</literal></>
-</programlisting>
- The sequence name can be schema-qualified if necessary:
-<programlisting>
-nextval('myschema.foo') <lineannotation>operates on <literal>myschema.foo</literal></>
-nextval('"myschema".foo') <lineannotation>same as above</lineannotation>
-nextval('foo') <lineannotation>searches search path for <literal>foo</literal></>
-</programlisting>
- See <xref linkend="datatype-oid"> for more information about
- <type>regclass</>.
- </para>
+ <sect2>
+ <title>Producing XML Content</title>
- <note>
<para>
- Before <productname>PostgreSQL</productname> 8.1, the arguments of the
- sequence functions were of type <type>text</>, not <type>regclass</>, and
- the above-described conversion from a text string to an OID value would
- happen at run time during each call. For backwards compatibility, this
- facility still exists, but internally it is now handled as an implicit
- coercion from <type>text</> to <type>regclass</> before the function is
- invoked.
+ A set of functions and function-like expressions are available for
+ producing XML content from SQL data. As such, they are
+ particularly suitable for formatting query results into XML
+ documents for processing in client applications.
</para>
- <para>
- When you write the argument of a sequence function as an unadorned
- literal string, it becomes a constant of type <type>regclass</>.
- Since this is really just an OID, it will track the originally
- identified sequence despite later renaming, schema reassignment,
- etc. This <quote>early binding</> behavior is usually desirable for
- sequence references in column defaults and views. But sometimes you will
- want <quote>late binding</> where the sequence reference is resolved
- at run time. To get late-binding behavior, force the constant to be
- stored as a <type>text</> constant instead of <type>regclass</>:
-<programlisting>
-nextval('foo'::text) <lineannotation><literal>foo</literal> is looked up at runtime</>
-</programlisting>
- Note that late binding was the only behavior supported in
- <productname>PostgreSQL</productname> releases before 8.1, so you
- might need to do this to preserve the semantics of old applications.
- </para>
+ <sect3>
+ <title><literal>xmlcomment</literal></title>
- <para>
- Of course, the argument of a sequence function can be an expression
- as well as a constant. If it is a text expression then the implicit
- coercion will result in a run-time lookup.
- </para>
- </note>
+ <indexterm>
+ <primary>xmlcomment</primary>
+ </indexterm>
- <para>
- The available sequence functions are:
+<synopsis>
+<function>xmlcomment</function>(<replaceable>text</replaceable>)
+</synopsis>
- <variablelist>
- <varlistentry>
- <term><function>nextval</function></term>
- <listitem>
- <para>
- Advance the sequence object to its next value and return that
- value. This is done atomically: even if multiple sessions
- execute <function>nextval</function> concurrently, each will safely receive
- a distinct sequence value.
- </para>
- </listitem>
- </varlistentry>
+ <para>
+ The function <function>xmlcomment</function> creates an XML value
+ containing an XML comment with the specified text as content.
+ The text cannot contain <literal>--</literal> or end with a
+ <literal>-</literal> so that the resulting construct is a valid
+ XML comment. If the argument is null, the result is null.
+ </para>
- <varlistentry>
- <term><function>currval</function></term>
- <listitem>
- <para>
- Return the value most recently obtained by <function>nextval</function>
- for this sequence in the current session. (An error is
- reported if <function>nextval</function> has never been called for this
- sequence in this session.) Notice that because this is returning
- a session-local value, it gives a predictable answer whether or not
- other sessions have executed <function>nextval</function> since the
- current session did.
- </para>
- </listitem>
- </varlistentry>
+ <para>
+ Example:
+<screen><![CDATA[
+SELECT xmlcomment('hello');
- <varlistentry>
- <term><function>lastval</function></term>
- <listitem>
- <para>
- Return the value most recently returned by
- <function>nextval</> in the current session. This function is
- identical to <function>currval</function>, except that instead
- of taking the sequence name as an argument it fetches the
- value of the last sequence that <function>nextval</function>
- was used on in the current session. It is an error to call
- <function>lastval</function> if <function>nextval</function>
- has not yet been called in the current session.
- </para>
- </listitem>
- </varlistentry>
+ xmlcomment
+--------------
+ <!--hello-->
+]]></screen>
+ </para>
+ </sect3>
- <varlistentry>
- <term><function>setval</function></term>
- <listitem>
- <para>
- Reset the sequence object's counter value. The two-parameter
- form sets the sequence's <literal>last_value</literal> field to the specified
- value and sets its <literal>is_called</literal> field to <literal>true</literal>,
- meaning that the next <function>nextval</function> will advance the sequence
- before returning a value. In the three-parameter form,
- <literal>is_called</literal> can be set either <literal>true</literal> or
- <literal>false</literal>. If it's set to <literal>false</literal>,
- the next <function>nextval</function> will return exactly the specified
- value, and sequence advancement commences with the following
- <function>nextval</function>. For example,
+ <sect3>
+ <title><literal>xmlconcat</literal></title>
-<screen>
-SELECT setval('foo', 42); <lineannotation>Next <function>nextval</> will return 43</lineannotation>
-SELECT setval('foo', 42, true); <lineannotation>Same as above</lineannotation>
-SELECT setval('foo', 42, false); <lineannotation>Next <function>nextval</> will return 42</lineannotation>
-</screen>
+ <indexterm>
+ <primary>xmlconcat</primary>
+ </indexterm>
- The result returned by <function>setval</function> is just the value of its
- second argument.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </para>
+ <synopsis>
+ <function>xmlconcat</function>(<replaceable>xml</replaceable><optional>, ...</optional>)
+ </synopsis>
+
+ <para>
+ The function <function>xmlconcat</function> concatenates a list
+ of individual XML values to create a single value containing an
+ XML content fragment. Null values are omitted; the result is
+ only null if there are no nonnull arguments.
+ </para>
- <para>
- If a sequence object has been created with default parameters,
- <function>nextval</function> calls on it will return successive values
- beginning with 1. Other behaviors can be obtained by using
- special parameters in the <xref linkend="sql-createsequence" endterm="sql-createsequence-title"> command;
- see its command reference page for more information.
- </para>
+ <para>
+ Example:
+<screen><![CDATA[
+SELECT xmlconcat('<abc/>', '<bar>foo</bar>');
- <important>
- <para>
- To avoid blocking of concurrent transactions that obtain numbers from the
- same sequence, a <function>nextval</function> operation is never rolled back;
- that is, once a value has been fetched it is considered used, even if the
- transaction that did the <function>nextval</function> later aborts. This means
- that aborted transactions might leave unused <quote>holes</quote> in the
- sequence of assigned values. <function>setval</function> operations are never
- rolled back, either.
- </para>
- </important>
+ xmlconcat
+----------------------
+ <abc/><bar>foo</bar>
+]]></screen>
+ </para>
- </sect1>
+ <para>
+ XML declarations, if present are combined as follows. If all
+ argument values have the same XML version declaration, that
+ version is used in the result, else no version is used. If all
+ argument values have the standalone declaration value
+ <quote>yes</quote>, then that value is used in the result. If
+ all argument values have a standalone declaration value and at
+ least one is <quote>no</quote>, then that is used in the result.
+ Else the result will have no standalone declaration. If the
+ result is determined to require a standalone declaration but no
+ version declaration, a version declaration with version 1.0 will
+ be used because XML requires an XML declaration to contain a
+ version declaration. Encoding declarations are ignored and
+ removed in all cases.
+ </para>
+ <para>
+ Example:
+<screen><![CDATA[
+SELECT xmlconcat('<?xml version="1.1"?><foo/>', '<?xml version="1.1" standalone="no"?><bar/>');
- <sect1 id="functions-conditional">
- <title>Conditional Expressions</title>
+ xmlconcat
+-----------------------------------
+ <?xml version="1.1"?><foo/><bar/>
+]]></screen>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><literal>xmlelement</literal></title>
+
+ <indexterm>
+ <primary>xmlelement</primary>
+ </indexterm>
+
+<synopsis>
+ <function>xmlelement</function>(name <replaceable>name</replaceable> <optional>, xmlattributes(<replaceable>value</replaceable> <optional>AS <replaceable>attname</replaceable></optional> <optional>, ... </optional>)</optional> <optional><replaceable>, content, ...</replaceable></optional>)
+ </synopsis>
+
+ <para>
+ The <function>xmlelement</function> expression produces an XML
+ element with the given name, attributes, and content.
+ </para>
- <indexterm>
- <primary>CASE</primary>
- </indexterm>
+ <para>
+ Examples:
+<screen><![CDATA[
+SELECT xmlelement(name foo);
- <indexterm>
- <primary>conditional expression</primary>
- </indexterm>
+ xmlelement
+------------
+ <foo/>
- <para>
- This section describes the <acronym>SQL</acronym>-compliant conditional expressions
- available in <productname>PostgreSQL</productname>.
- </para>
+SELECT xmlelement(name foo, xmlattributes('xyz' as bar));
- <tip>
- <para>
- If your needs go beyond the capabilities of these conditional
- expressions you might want to consider writing a stored procedure
- in a more expressive programming language.
- </para>
- </tip>
+ xmlelement
+------------------
+ <foo bar="xyz"/>
- <sect2>
- <title><literal>CASE</></title>
+SELECT xmlelement(name foo, xmlattributes(current_date as bar), 'cont', 'ent');
- <para>
- The <acronym>SQL</acronym> <token>CASE</token> expression is a
- generic conditional expression, similar to if/else statements in
- other languages:
+ xmlelement
+-------------------------------------
+ <foo bar="2007-01-26">content</foo>
+]]></screen>
+ </para>
-<synopsis>
-CASE WHEN <replaceable>condition</replaceable> THEN <replaceable>result</replaceable>
- <optional>WHEN ...</optional>
- <optional>ELSE <replaceable>result</replaceable></optional>
-END
-</synopsis>
+ <para>
+ Element and attribute names that are not valid XML names are
+ escaped by replacing the offending characters by the sequence
+ <literal>_x<replaceable>HHHH</replaceable>_</literal>, where
+ <replaceable>HHHH</replaceable> is the character's Unicode
+ codepoint in hexadecimal notation. For example:
+<screen><![CDATA[
+SELECT xmlelement(name "foo$bar", xmlattributes('xyz' as "a&b"));
- <token>CASE</token> clauses can be used wherever
- an expression is valid. <replaceable>condition</replaceable> is an
- expression that returns a <type>boolean</type> result. If the result is true
- then the value of the <token>CASE</token> expression is the
- <replaceable>result</replaceable> that follows the condition. If the result is false any
- subsequent <token>WHEN</token> clauses are searched in the same
- manner. If no <token>WHEN</token>
- <replaceable>condition</replaceable> is true then the value of the
- case expression is the <replaceable>result</replaceable> in the
- <token>ELSE</token> clause. If the <token>ELSE</token> clause is
- omitted and no condition matches, the result is null.
- </para>
+ xmlelement
+----------------------------------
+ <foo_x0024_bar a_x0026_b="xyz"/>
+]]></screen>
+ </para>
- <para>
- An example:
+ <para>
+ An explicit attribute name need not be specified if the attribute
+ value is a column reference, in which case the column's name will
+ be used as attribute name by default. In any other case, the
+ attribute must be given an explicit name. So this example is
+ valid:
<screen>
-SELECT * FROM test;
+CREATE TABLE test (a xml, b xml);
+SELECT xmlelement(name test, xmlattributes(a, b)) FROM test;
+</screen>
+ But these are not:
+<screen>
+SELECT xmlelement(name test, xmlattributes('constant'), a, b) FROM test;
+SELECT xmlelement(name test, xmlattributes(func(a, b))) FROM test;
+</screen>
+ </para>
- a
----
- 1
- 2
- 3
+ <para>
+ Element content, if specified, will be formatted according to
+ data type. If the content is itself of type <type>xml</type>,
+ complex XML documents can be constructed. For example:
+<screen><![CDATA[
+SELECT xmlelement(name foo, xmlattributes('xyz' as bar),
+ xmlelement(name abc),
+ xmlcomment('test'),
+ xmlelement(name xyz));
+ xmlelement
+----------------------------------------------
+ <foo bar="xyz"><abc/><!--test--><xyz/></foo>
+]]></screen>
-SELECT a,
- CASE WHEN a=1 THEN 'one'
- WHEN a=2 THEN 'two'
- ELSE 'other'
- END
- FROM test;
+ Content of other types will be formatted into valid XML character
+ data. This means in particular that the characters <, >,
+ and & will be converted to entities. Binary data (data type
+ <type>bytea</type>) will be represented in base64 or hex
+ encoding, depending on the setting of the configuration parameter
+ <xref linkend="guc-xmlbinary">. The particular behavior for
+ individual data types is expected evolve in order to align the
+ SQL and PostgreSQL data types with the XML Schema specification,
+ at which point a more precise description will appear.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><literal>xmlforest</literal></title>
+
+ <indexterm>
+ <primary>xmlforest</primary>
+ </indexterm>
+
+ <synopsis>
+ <function>xmlforest</function>(<replaceable>content</replaceable> <optional>AS <replaceable>name</replaceable></optional> <optional>, ...</optional>)
+ </synopsis>
+
+ <para>
+ The <function>xmlforest</function> expression produces an XML
+ forest (sequence) of elements using the given names and content.
+ </para>
- a | case
----+-------
- 1 | one
- 2 | two
- 3 | other
-</screen>
- </para>
+ <para>
+ Examples:
+<screen><![CDATA[
+SELECT xmlforest('abc' AS foo, 123 AS bar);
- <para>
- The data types of all the <replaceable>result</replaceable>
- expressions must be convertible to a single output type.
- See <xref linkend="typeconv-union-case"> for more detail.
- </para>
+ xmlforest
+------------------------------
+ <foo>abc</foo><bar>123</bar>
- <para>
- The following <quote>simple</quote> <token>CASE</token> expression is a
- specialized variant of the general form above:
-<synopsis>
-CASE <replaceable>expression</replaceable>
- WHEN <replaceable>value</replaceable> THEN <replaceable>result</replaceable>
- <optional>WHEN ...</optional>
- <optional>ELSE <replaceable>result</replaceable></optional>
-END
-</synopsis>
+SELECT xmlforest(table_name, column_name) FROM information_schema.columns WHERE table_schema = 'pg_catalog';
- The
- <replaceable>expression</replaceable> is computed and compared to
- all the <replaceable>value</replaceable> specifications in the
- <token>WHEN</token> clauses until one is found that is equal. If
- no match is found, the <replaceable>result</replaceable> in the
- <token>ELSE</token> clause (or a null value) is returned. This is similar
- to the <function>switch</function> statement in C.
- </para>
+ xmlforest
+-------------------------------------------------------------------------------------------
+ <table_name>pg_authid</table_name><column_name>rolname</column_name>
+ <table_name>pg_authid</table_name><column_name>rolsuper</column_name>
+ ...
+]]></screen>
- <para>
- The example above can be written using the simple
- <token>CASE</token> syntax:
-<screen>
-SELECT a,
- CASE a WHEN 1 THEN 'one'
- WHEN 2 THEN 'two'
- ELSE 'other'
- END
- FROM test;
+ As seen in the second example, the element name can be omitted if
+ the content value is a column reference, in which case the column
+ name is used by default. Otherwise, a name must be specified.
+ </para>
- a | case
----+-------
- 1 | one
- 2 | two
- 3 | other
-</screen>
- </para>
-
- <para>
- A <token>CASE</token> expression does not evaluate any subexpressions
- that are not needed to determine the result. For example, this is a
- possible way of avoiding a division-by-zero failure:
-<programlisting>
-SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END;
-</programlisting>
- </para>
- </sect2>
-
- <sect2>
- <title><literal>COALESCE</></title>
-
- <indexterm>
- <primary>COALESCE</primary>
- </indexterm>
+ <para>
+ Element names that are not valid XML names are escaped as shown
+ for <function>xmlelement</function> above. Similarly, content
+ data is escaped to make valid XML content, unless it is already
+ of type <type>xml</type>.
+ </para>
- <indexterm>
- <primary>NVL</primary>
- </indexterm>
+ <para>
+ Note that XML forests are not valid XML documents if they consist
+ of more than one element. So it might be useful to wrap
+ <function>xmlforest</function> expressions in
+ <function>xmlelement</function>.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><literal>xmlpi</literal></title>
+
+ <indexterm>
+ <primary>xmlpi</primary>
+ </indexterm>
+
+ <synopsis>
+ <function>xmlpi</function>(name <replaceable>target</replaceable> <optional>, <replaceable>content</replaceable></optional>)
+ </synopsis>
+
+ <para>
+ The <function>xmlpi</function> expression creates an XML
+ processing instruction. The content, if present, must not
+ contain the character sequence <literal>?></literal>.
+ </para>
- <indexterm>
- <primary>IFNULL</primary>
- </indexterm>
+ <para>
+ Example:
+<screen><![CDATA[
+SELECT xmlpi(name php, 'echo "hello world";');
-<synopsis>
-<function>COALESCE</function>(<replaceable>value</replaceable> <optional>, ...</optional>)
-</synopsis>
+ xmlpi
+-----------------------------
+ <?php echo "hello world";?>
+]]></screen>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><literal>xmlroot</literal></title>
+
+ <indexterm>
+ <primary>xmlroot</primary>
+ </indexterm>
+
+ <synopsis>
+ <function>xmlroot</function>(<replaceable>xml</replaceable>, version <replaceable>text</replaceable>|no value <optional>, standalone yes|no|no value</optional>)
+ </synopsis>
+
+ <para>
+ The <function>xmlroot</function> expression alters the properties
+ of the root node of an XML value. If a version is specified,
+ this replaces the value in the version declaration, if a
+ standalone value is specified, this replaces the value in the
+ standalone declaration.
+ </para>
- <para>
- The <function>COALESCE</function> function returns the first of its
- arguments that is not null. Null is returned only if all arguments
- are null. It is often used to substitute a default value for
- null values when data is retrieved for display, for example:
-<programlisting>
-SELECT COALESCE(description, short_description, '(none)') ...
-</programlisting>
- </para>
+ <para>
+<screen><![CDATA[
+SELECT xmlroot(xmlparse(document '<?xml version="1.1"?><content>abc</content>'), version '1.0', standalone yes);
- <para>
- Like a <token>CASE</token> expression, <function>COALESCE</function> will
- not evaluate arguments that are not needed to determine the result;
- that is, arguments to the right of the first non-null argument are
- not evaluated. This SQL-standard function provides capabilities similar
- to <function>NVL</> and <function>IFNULL</>, which are used in some other
- database systems.
- </para>
- </sect2>
+ xmlroot
+----------------------------------------
+ <?xml version="1.0" standalone="yes"?>
+ <content>abc</content>
+]]></screen>
+ </para>
+ </sect3>
- <sect2>
- <title><literal>NULLIF</></title>
+ <sect3>
+ <title>XML Predicates</title>
- <indexterm>
- <primary>NULLIF</primary>
- </indexterm>
+ <indexterm>
+ <primary>IS DOCUMENT</primary>
+ </indexterm>
<synopsis>
-<function>NULLIF</function>(<replaceable>value1</replaceable>, <replaceable>value2</replaceable>)
+<replaceable>xml</replaceable> IS DOCUMENT
</synopsis>
- <para>
- The <function>NULLIF</function> function returns a null value if
- <replaceable>value1</replaceable> and <replaceable>value2</replaceable>
- are equal; otherwise it returns <replaceable>value1</replaceable>.
- This can be used to perform the inverse operation of the
- <function>COALESCE</function> example given above:
-<programlisting>
-SELECT NULLIF(value, '(none)') ...
-</programlisting>
- </para>
- <para>
- If <replaceable>value1</replaceable> is <literal>(none)</>, return a null,
- otherwise return <replaceable>value1</replaceable>.
- </para>
-
+ <para>
+ The expression <literal>IS DOCUMENT</literal> returns true if the
+ argument XML value is a proper XML document, false if it is not
+ (that is, it is a content fragment), or null if the argument is
+ null. See <xref linkend="datatype-xml"> about the difference
+ between documents and content fragments.
+ </para>
+ </sect3>
</sect2>
- <sect2>
- <title><literal>GREATEST</literal> and <literal>LEAST</literal></title>
+ <sect2 id="functions-xml-mapping">
+ <title>Mapping Tables to XML</title>
- <indexterm>
- <primary>GREATEST</primary>
- </indexterm>
- <indexterm>
- <primary>LEAST</primary>
- </indexterm>
+ <indexterm zone="functions-xml-mapping">
+ <primary>XML export</primary>
+ </indexterm>
+ <para>
+ The following functions map the contents of relational tables to
+ XML values. They can be thought of as XML export functionality.
<synopsis>
-<function>GREATEST</function>(<replaceable>value</replaceable> <optional>, ...</optional>)
-</synopsis>
-<synopsis>
-<function>LEAST</function>(<replaceable>value</replaceable> <optional>, ...</optional>)
+table_to_xml(tbl regclass, nulls boolean, tableforest boolean, targetns text)
+query_to_xml(query text, nulls boolean, tableforest boolean, targetns text)
+cursor_to_xml(cursor refcursor, count int, nulls boolean, tableforest boolean, targetns text)
</synopsis>
+ The return type of each function is <type>xml</type>.
+ </para>
<para>
- The <function>GREATEST</> and <function>LEAST</> functions select the
- largest or smallest value from a list of any number of expressions.
- The expressions must all be convertible to a common data type, which
- will be the type of the result
- (see <xref linkend="typeconv-union-case"> for details). NULL values
- in the list are ignored. The result will be NULL only if all the
- expressions evaluate to NULL.
+ <function>table_to_xml</function> maps the content of the named
+ table, passed as parameter <parameter>tbl</parameter>. The
+ <type>regclass</type> accepts strings identifying tables using the
+ usual notation, including optional schema qualifications and
+ double quotes. <function>query_to_xml</function> executes the
+ query whose text is passed as parameter
+ <parameter>query</parameter> and maps the result set.
+ <function>cursor_to_xml</function> fetches the indicated number of
+ rows from the cursor specified by the parameter
+ <parameter>cursor</parameter>. This variant is recommendable if
+ large tables have to be mapped, because the result value is built
+ up in memory by each function.
</para>
<para>
- Note that <function>GREATEST</> and <function>LEAST</> are not in
- the SQL standard, but are a common extension.
- </para>
- </sect2>
- </sect1>
+ If <parameter>tableforest</parameter> is false, then the resulting
+ XML document looks like this:
+<screen><![CDATA[
+<tablename>
+ <row>
+ <columnname1>data</columnname1>
+ <columnname2>data</columnname2>
+ </row>
+ <row>
+ ...
+ </row>
- <sect1 id="functions-array">
- <title>Array Functions and Operators</title>
+ ...
+</tablename>
+]]></screen>
- <para>
- <xref linkend="array-operators-table"> shows the operators
- available for <type>array</type> types.
- </para>
+ If <parameter>tableforest</parameter> is true, the result is an
+ XML content fragment that looks like this:
+<screen><![CDATA[
+<tablename>
+ <columnname1>data</columnname1>
+ <columnname2>data</columnname2>
+</tablename>
- <table id="array-operators-table">
- <title><type>array</type> Operators</title>
- <tgroup cols="4">
- <thead>
- <row>
- <entry>Operator</entry>
- <entry>Description</entry>
- <entry>Example</entry>
- <entry>Result</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry> <literal>=</literal> </entry>
- <entry>equal</entry>
- <entry><literal>ARRAY[1.1,2.1,3.1]::int[] = ARRAY[1,2,3]</literal></entry>
- <entry><literal>t</literal></entry>
- </row>
+<tablename>
+ ...
+</tablename>
- <row>
- <entry> <literal><></literal> </entry>
- <entry>not equal</entry>
- <entry><literal>ARRAY[1,2,3] <> ARRAY[1,2,4]</literal></entry>
- <entry><literal>t</literal></entry>
- </row>
+...
+]]></screen>
- <row>
- <entry> <literal><</literal> </entry>
- <entry>less than</entry>
- <entry><literal>ARRAY[1,2,3] < ARRAY[1,2,4]</literal></entry>
- <entry><literal>t</literal></entry>
- </row>
+ If no table name is avaible, that is, when mapping a query or a
+ cursor, the string <literal>table</literal> is used in the first
+ format, <literal>row</literal> in the second format.
+ </para>
- <row>
- <entry> <literal>></literal> </entry>
- <entry>greater than</entry>
- <entry><literal>ARRAY[1,4,3] > ARRAY[1,2,4]</literal></entry>
- <entry><literal>t</literal></entry>
- </row>
+ <para>
+ The choice between these formats is up to the user. The first
+ format is a proper XML document, which will be important in many
+ applications. The second format tends to be more useful in the
+ <function>cursor_to_xml</function> function if the result values are to be
+ reassembled into one document later on. The functions for
+ producing XML content discussed above, in particular
+ <function>xmlelement</function>, can be used to alter the results
+ to taste.
+ </para>
- <row>
- <entry> <literal><=</literal> </entry>
- <entry>less than or equal</entry>
- <entry><literal>ARRAY[1,2,3] <= ARRAY[1,2,3]</literal></entry>
- <entry><literal>t</literal></entry>
- </row>
+ <para>
+ The data values are mapping in the same way as described for the
+ function <function>xmlelement</function> above.
+ </para>
- <row>
- <entry> <literal>>=</literal> </entry>
- <entry>greater than or equal</entry>
- <entry><literal>ARRAY[1,4,3] >= ARRAY[1,4,3]</literal></entry>
- <entry><literal>t</literal></entry>
- </row>
+ <para>
+ The parameter <parameter>nulls</parameter> determines whether null
+ values should be included in the output. If true, null values in
+ columns are represented as
+<screen><![CDATA[
+<columnname xsi:nil="true"/>
+]]></screen>
+ where <literal>xsi</literal> is the XML namespace prefix for XML
+ Schema Instance. An appropriate namespace declaration will be
+ added to the result value. If false, columns containing null
+ values are simply omitted from the output.
+ </para>
- <row>
- <entry> <literal>@></literal> </entry>
- <entry>contains</entry>
- <entry><literal>ARRAY[1,4,3] @> ARRAY[3,1]</literal></entry>
- <entry><literal>t</literal></entry>
- </row>
+ <para>
+ The parameter <parameter>targetns</parameter> specifies the
+ desired XML namespace of the result. If no particular namespace
+ is wanted, an empty string should be passed.
+ </para>
- <row>
- <entry> <literal><@</literal> </entry>
- <entry>is contained by</entry>
- <entry><literal>ARRAY[2,7] <@ ARRAY[1,7,4,2,6]</literal></entry>
- <entry><literal>t</literal></entry>
- </row>
+ <para>
+ The following functions return XML Schema documents describing the
+ mappings made by the data mappings produced by the corresponding
+ functions above.
+<synopsis>
+table_to_xmlschema(tbl regclass, nulls boolean, tableforest boolean, targetns text)
+query_to_xmlschema(query text, nulls boolean, tableforest boolean, targetns text)
+cursor_to_xmlschema(cursor refcursor, nulls boolean, tableforest boolean, targetns text)
+</synopsis>
+ It is essential that the same parameters are passed in order to
+ obtain matching XML data mappings and XML Schema documents.
+ </para>
- <row>
- <entry> <literal>&&</literal> </entry>
- <entry>overlap (have elements in common)</entry>
- <entry><literal>ARRAY[1,4,3] && ARRAY[2,1]</literal></entry>
- <entry><literal>t</literal></entry>
- </row>
+ <para>
+ The following functions produce XML data mappings and the
+ corresponding XML Schema in one document (or forest), linked
+ together. They can be useful where self-contained and
+ self-describing results are wanted.
+<synopsis>
+table_to_xml_and_xmlschema(tbl regclass, nulls boolean, tableforest boolean, targetns text)
+query_to_xml_and_xmlschema(query text, nulls boolean, tableforest boolean, targetns text)
+</synopsis>
+ </para>
- <row>
- <entry> <literal>||</literal> </entry>
- <entry>array-to-array concatenation</entry>
- <entry><literal>ARRAY[1,2,3] || ARRAY[4,5,6]</literal></entry>
- <entry><literal>{1,2,3,4,5,6}</literal></entry>
- </row>
+ <para>
+ In addition, the following functions are available to produce
+ analogous mappings of entire schemas or the entire current
+ database.
+<synopsis>
+schema_to_xml(schema name, nulls boolean, tableforest boolean, targetns text)
+schema_to_xmlschema(schema name, nulls boolean, tableforest boolean, targetns text)
+schema_to_xml_and_xmlschema(schema name, nulls boolean, tableforest boolean, targetns text)
- <row>
- <entry> <literal>||</literal> </entry>
- <entry>array-to-array concatenation</entry>
- <entry><literal>ARRAY[1,2,3] || ARRAY[[4,5,6],[7,8,9]]</literal></entry>
- <entry><literal>{{1,2,3},{4,5,6},{7,8,9}}</literal></entry>
- </row>
+database_to_xml(nulls boolean, tableforest boolean, targetns text)
+database_to_xmlschema(nulls boolean, tableforest boolean, targetns text)
+database_to_xml_and_xmlschema(nulls boolean, tableforest boolean, targetns text)
+</synopsis>
- <row>
- <entry> <literal>||</literal> </entry>
- <entry>element-to-array concatenation</entry>
- <entry><literal>3 || ARRAY[4,5,6]</literal></entry>
- <entry><literal>{3,4,5,6}</literal></entry>
- </row>
+ Note that these potentially produce a lot of data, which needs to
+ be built up in memory. When requesting content mappings of large
+ schemas or databases, it may be worthwhile to consider mapping the
+ tables separately instead, possibly even through a cursor.
+ </para>
- <row>
- <entry> <literal>||</literal> </entry>
- <entry>array-to-element concatenation</entry>
- <entry><literal>ARRAY[4,5,6] || 7</literal></entry>
- <entry><literal>{4,5,6,7}</literal></entry>
- </row>
- </tbody>
- </tgroup>
- </table>
+ <para>
+ The result of a schema content mapping looks like this:
- <para>
- Array comparisons compare the array contents element-by-element,
- using the default B-Tree comparison function for the element data type.
- In multidimensional arrays the elements are visited in row-major order
- (last subscript varies most rapidly).
- If the contents of two arrays are equal but the dimensionality is
- different, the first difference in the dimensionality information
- determines the sort order. (This is a change from versions of
- <productname>PostgreSQL</> prior to 8.2: older versions would claim
- that two arrays with the same contents were equal, even if the
- number of dimensions or subscript ranges were different.)
- </para>
+<screen><![CDATA[
+<schemaname>
- <para>
- See <xref linkend="arrays"> for more details about array operator
- behavior.
- </para>
+table1-mapping
- <para>
- <xref linkend="array-functions-table"> shows the functions
- available for use with array types. See <xref linkend="arrays">
- for more discussion and examples of the use of these functions.
- </para>
+table2-mapping
- <table id="array-functions-table">
- <title><type>array</type> Functions</title>
- <tgroup cols="5">
- <thead>
- <row>
- <entry>Function</entry>
- <entry>Return Type</entry>
- <entry>Description</entry>
- <entry>Example</entry>
- <entry>Result</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>
- <literal>
- <function>array_append</function>(<type>anyarray</type>, <type>anyelement</type>)
- </literal>
- </entry>
- <entry><type>anyarray</type></entry>
- <entry>append an element to the end of an array</entry>
- <entry><literal>array_append(ARRAY[1,2], 3)</literal></entry>
- <entry><literal>{1,2,3}</literal></entry>
- </row>
- <row>
- <entry>
- <literal>
- <function>array_cat</function>(<type>anyarray</type>, <type>anyarray</type>)
- </literal>
- </entry>
- <entry><type>anyarray</type></entry>
- <entry>concatenate two arrays</entry>
- <entry><literal>array_cat(ARRAY[1,2,3], ARRAY[4,5])</literal></entry>
- <entry><literal>{1,2,3,4,5}</literal></entry>
- </row>
- <row>
- <entry>
- <literal>
- <function>array_dims</function>(<type>anyarray</type>)
- </literal>
- </entry>
- <entry><type>text</type></entry>
- <entry>returns a text representation of array's dimensions</entry>
- <entry><literal>array_dims(ARRAY[[1,2,3], [4,5,6]])</literal></entry>
- <entry><literal>[1:2][1:3]</literal></entry>
- </row>
- <row>
- <entry>
- <literal>
- <function>array_lower</function>(<type>anyarray</type>, <type>int</type>)
- </literal>
- </entry>
- <entry><type>int</type></entry>
- <entry>returns lower bound of the requested array dimension</entry>
- <entry><literal>array_lower('[0:2]={1,2,3}'::int[], 1)</literal></entry>
- <entry><literal>0</literal></entry>
- </row>
- <row>
- <entry>
- <literal>
- <function>array_prepend</function>(<type>anyelement</type>, <type>anyarray</type>)
- </literal>
- </entry>
- <entry><type>anyarray</type></entry>
- <entry>append an element to the beginning of an array</entry>
- <entry><literal>array_prepend(1, ARRAY[2,3])</literal></entry>
- <entry><literal>{1,2,3}</literal></entry>
- </row>
- <row>
- <entry>
- <literal>
- <function>array_to_string</function>(<type>anyarray</type>, <type>text</type>)
- </literal>
- </entry>
- <entry><type>text</type></entry>
- <entry>concatenates array elements using provided delimiter</entry>
- <entry><literal>array_to_string(ARRAY[1, 2, 3], '~^~')</literal></entry>
- <entry><literal>1~^~2~^~3</literal></entry>
- </row>
- <row>
- <entry>
- <literal>
- <function>array_upper</function>(<type>anyarray</type>, <type>int</type>)
- </literal>
- </entry>
- <entry><type>int</type></entry>
- <entry>returns upper bound of the requested array dimension</entry>
- <entry><literal>array_upper(ARRAY[1,2,3,4], 1)</literal></entry>
- <entry><literal>4</literal></entry>
- </row>
- <row>
- <entry>
- <literal>
- <function>string_to_array</function>(<type>text</type>, <type>text</type>)
- </literal>
- </entry>
- <entry><type>text[]</type></entry>
- <entry>splits string into array elements using provided delimiter</entry>
- <entry><literal>string_to_array('xx~^~yy~^~zz', '~^~')</literal></entry>
- <entry><literal>{xx,yy,zz}</literal></entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </sect1>
+...
- <sect1 id="functions-aggregate">
- <title>Aggregate Functions</title>
+</schemaname>]]></screen>
- <indexterm zone="functions-aggregate">
- <primary>aggregate function</primary>
- <secondary>built-in</secondary>
- </indexterm>
+ where the format of a table mapping depends on the
+ <parameter>tableforest</parameter> parameter as explained above.
+ </para>
- <para>
- <firstterm>Aggregate functions</firstterm> compute a single result
- value from a set of input values. The built-in aggregate functions
- are listed in
- <xref linkend="functions-aggregate-table"> and
- <xref linkend="functions-aggregate-statistics-table">.
- The special syntax considerations for aggregate
- functions are explained in <xref linkend="syntax-aggregates">.
- Consult <xref linkend="tutorial-agg"> for additional introductory
- information.
- </para>
+ <para>
+ The result of a database content mapping looks like this:
- <table id="functions-aggregate-table">
- <title>General-Purpose Aggregate Functions</title>
+<screen><![CDATA[
+<dbname>
- <tgroup cols="4">
- <thead>
- <row>
- <entry>Function</entry>
- <entry>Argument Type</entry>
- <entry>Return Type</entry>
- <entry>Description</entry>
- </row>
- </thead>
+<schema1name>
+ ...
+</schema1name>
- <tbody>
- <row>
- <entry>
- <indexterm>
- <primary>average</primary>
- </indexterm>
- <function>avg(<replaceable class="parameter">expression</replaceable>)</function>
- </entry>
- <entry>
- <type>smallint</type>, <type>int</type>,
- <type>bigint</type>, <type>real</type>, <type>double
- precision</type>, <type>numeric</type>, or <type>interval</type>
- </entry>
- <entry>
- <type>numeric</type> for any integer type argument,
- <type>double precision</type> for a floating-point argument,
- otherwise the same as the argument data type
- </entry>
- <entry>the average (arithmetic mean) of all input values</entry>
- </row>
+<schema2name>
+ ...
+</schema2name>
- <row>
- <entry>
- <indexterm>
- <primary>bit_and</primary>
- </indexterm>
- <function>bit_and(<replaceable class="parameter">expression</replaceable>)</function>
- </entry>
- <entry>
- <type>smallint</type>, <type>int</type>, <type>bigint</type>, or
- <type>bit</type>
- </entry>
- <entry>
- same as argument data type
- </entry>
- <entry>the bitwise AND of all non-null input values, or null if none</entry>
- </row>
+...
- <row>
- <entry>
- <indexterm>
- <primary>bit_or</primary>
- </indexterm>
- <function>bit_or(<replaceable class="parameter">expression</replaceable>)</function>
- </entry>
- <entry>
- <type>smallint</type>, <type>int</type>, <type>bigint</type>, or
- <type>bit</type>
- </entry>
- <entry>
- same as argument data type
- </entry>
- <entry>the bitwise OR of all non-null input values, or null if none</entry>
- </row>
+</dbname>]]></screen>
- <row>
- <entry>
- <indexterm>
- <primary>bool_and</primary>
- </indexterm>
- <function>bool_and(<replaceable class="parameter">expression</replaceable>)</function>
- </entry>
- <entry>
- <type>bool</type>
- </entry>
- <entry>
- <type>bool</type>
- </entry>
- <entry>true if all input values are true, otherwise false</entry>
- </row>
+ where the schema mapping is as above.
+ </para>
- <row>
- <entry>
- <indexterm>
- <primary>bool_or</primary>
- </indexterm>
- <function>bool_or(<replaceable class="parameter">expression</replaceable>)</function>
- </entry>
- <entry>
- <type>bool</type>
- </entry>
- <entry>
- <type>bool</type>
- </entry>
- <entry>true if at least one input value is true, otherwise false</entry>
- </row>
+ <para>
+ As an example for using the output produced by these functions,
+ <xref linkend="xslt-xml-html"> shows an XSLT stylesheet that
+ converts the output of
+ <function>table_to_xml_and_xmlschema</function> to an HTML
+ document containing a tabular rendition of the table data. In a
+ similar manner, the result data of these functions can be
+ converted into other XML-based formats.
+ </para>
- <row>
- <entry><function>count(*)</function></entry>
- <entry></entry>
- <entry><type>bigint</type></entry>
- <entry>number of input rows</entry>
- </row>
+ <figure id="xslt-xml-html">
+ <title>XSLT stylesheet for converting SQL/XML output to HTML</title>
+<programlisting><![CDATA[
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns="http://www.w3.org/1999/xhtml"
+>
- <row>
- <entry><function>count(<replaceable class="parameter">expression</replaceable>)</function></entry>
- <entry>any</entry>
- <entry><type>bigint</type></entry>
- <entry>
- number of input rows for which the value of <replaceable
- class="parameter">expression</replaceable> is not null
- </entry>
- </row>
+ <xsl:output method="xml"
+ doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
+ doctype-public="-//W3C/DTD XHTML 1.0 Strict//EN"
+ indent="yes"/>
- <row>
- <entry>
- <indexterm>
- <primary>every</primary>
- </indexterm>
- <function>every(<replaceable class="parameter">expression</replaceable>)</function>
- </entry>
- <entry>
- <type>bool</type>
- </entry>
- <entry>
- <type>bool</type>
- </entry>
- <entry>equivalent to <function>bool_and</function></entry>
- </row>
+ <xsl:template match="/*">
+ <xsl:variable name="schema" select="//xsd:schema"/>
+ <xsl:variable name="tabletypename"
+ select="$schema/xsd:element[@name=name(current())]/@type"/>
+ <xsl:variable name="rowtypename"
+ select="$schema/xsd:complexType[@name=$tabletypename]/xsd:sequence/xsd:element[@name='row']/@type"/>
- <row>
- <entry><function>max(<replaceable class="parameter">expression</replaceable>)</function></entry>
- <entry>any array, numeric, string, or date/time type</entry>
- <entry>same as argument type</entry>
- <entry>
- maximum value of <replaceable
- class="parameter">expression</replaceable> across all input
- values
- </entry>
- </row>
+ <html>
+ <head>
+ <title><xsl:value-of select="name(current())"/></title>
+ </head>
+ <body>
+ <table>
+ <tr>
+ <xsl:for-each select="$schema/xsd:complexType[@name=$rowtypename]/xsd:sequence/xsd:element/@name">
+ <th><xsl:value-of select="."/></th>
+ </xsl:for-each>
+ </tr>
- <row>
- <entry><function>min(<replaceable class="parameter">expression</replaceable>)</function></entry>
- <entry>any array, numeric, string, or date/time type</entry>
- <entry>same as argument type</entry>
- <entry>
- minimum value of <replaceable
- class="parameter">expression</replaceable> across all input
- values
- </entry>
- </row>
+ <xsl:for-each select="row">
+ <tr>
+ <xsl:for-each select="*">
+ <td><xsl:value-of select="."/></td>
+ </xsl:for-each>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+ </xsl:template>
- <row>
- <entry><function>sum(<replaceable class="parameter">expression</replaceable>)</function></entry>
- <entry>
- <type>smallint</type>, <type>int</type>,
- <type>bigint</type>, <type>real</type>, <type>double
- precision</type>, <type>numeric</type>, or
- <type>interval</type>
- </entry>
- <entry>
- <type>bigint</type> for <type>smallint</type> or
- <type>int</type> arguments, <type>numeric</type> for
- <type>bigint</type> arguments, <type>double precision</type>
- for floating-point arguments, otherwise the same as the
- argument data type
- </entry>
- <entry>sum of <replaceable class="parameter">expression</replaceable> across all input values</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>
- It should be noted that except for <function>count</function>,
- these functions return a null value when no rows are selected. In
- particular, <function>sum</function> of no rows returns null, not
- zero as one might expect. The <function>coalesce</function> function can be
- used to substitute zero for null when necessary.
- </para>
+</xsl:stylesheet>
+]]></programlisting>
+ </figure>
+ </sect2>
- <note>
- <indexterm>
- <primary>ANY</primary>
- </indexterm>
- <indexterm>
- <primary>SOME</primary>
- </indexterm>
- <para>
- Boolean aggregates <function>bool_and</function> and
- <function>bool_or</function> correspond to standard SQL aggregates
- <function>every</function> and <function>any</function> or
- <function>some</function>.
- As for <function>any</function> and <function>some</function>,
- it seems that there is an ambiguity built into the standard syntax:
-<programlisting>
-SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...;
-</programlisting>
- Here <function>ANY</function> can be considered both as leading
- to a subquery or as an aggregate if the select expression returns 1 row.
- Thus the standard name cannot be given to these aggregates.
- </para>
- </note>
+ <sect2>
+ <title>Processing XML</title>
- <note>
<para>
- Users accustomed to working with other SQL database management
- systems might be surprised by the performance of the
- <function>count</function> aggregate when it is applied to the
- entire table. A query like:
-<programlisting>
-SELECT count(*) FROM sometable;
-</programlisting>
- will be executed by <productname>PostgreSQL</productname> using a
- sequential scan of the entire table.
+ <acronym>XML</> support is not just the existence of an
+ <type>xml</type> data type, but a variety of features supported by
+ a database system. These capabilities include import/export,
+ indexing, searching, transforming, and <acronym>XML</> to
+ <acronym>SQL</> mapping. <productname>PostgreSQL</> supports some
+ but not all of these <acronym>XML</> capabilities. For an
+ overview of <acronym>XML</> use in databases, see <ulink
+ url="http://www.rpbourret.com/xml/XMLAndDatabases.htm"></>.
</para>
- </note>
+ <variablelist>
+ <varlistentry>
+ <term>Indexing</term>
+ <listitem>
- <para>
- <xref linkend="functions-aggregate-statistics-table"> shows
- aggregate functions typically used in statistical analysis.
- (These are separated out merely to avoid cluttering the listing
- of more-commonly-used aggregates.) Where the description mentions
- <replaceable class="parameter">N</replaceable>, it means the
- number of input rows for which all the input expressions are non-null.
- In all cases, null is returned if the computation is meaningless,
- for example when <replaceable class="parameter">N</replaceable> is zero.
- </para>
+ <para>
+ <filename>contrib/xml2/</> functions can be used in expression
+ indexes to index specific <acronym>XML</> fields. To index the
+ full contents of <acronym>XML</> documents, the full-text
+ indexing tool <filename>contrib/tsearch2/</> can be used. Of
+ course, Tsearch2 indexes have no <acronym>XML</> awareness so
+ additional <filename>contrib/xml2/</> checks should be added to
+ queries.
+ </para>
+ </listitem>
+ </varlistentry>
- <indexterm>
- <primary>statistics</primary>
- </indexterm>
- <indexterm>
- <primary>linear regression</primary>
- </indexterm>
+ <varlistentry>
+ <term>Searching</term>
+ <listitem>
- <table id="functions-aggregate-statistics-table">
- <title>Aggregate Functions for Statistics</title>
+ <para>
+ XPath searches are implemented using <filename>contrib/xml2/</>.
+ It processes <acronym>XML</> text documents and returns results
+ based on the requested query.
+ </para>
+ </listitem>
+ </varlistentry>
- <tgroup cols="4">
- <thead>
- <row>
- <entry>Function</entry>
- <entry>Argument Type</entry>
- <entry>Return Type</entry>
- <entry>Description</entry>
- </row>
- </thead>
+ <varlistentry>
+ <term>Transforming</term>
+ <listitem>
- <tbody>
+ <para>
+ <filename>contrib/xml2/</> supports <acronym>XSLT</> (Extensible
+ Stylesheet Language Transformation).
+ </para>
+ </listitem>
+ </varlistentry>
- <row>
- <entry>
- <indexterm>
- <primary>correlation</primary>
- </indexterm>
- <function>corr(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>correlation coefficient</entry>
- </row>
+ <varlistentry>
+ <term>XML to SQL Mapping</term>
+ <listitem>
- <row>
- <entry>
- <indexterm>
- <primary>covariance</primary>
- <secondary>population</secondary>
- </indexterm>
- <function>covar_pop(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>population covariance</entry>
- </row>
+ <para>
+ This involves converting <acronym>XML</> data to and from
+ relational structures. <productname>PostgreSQL</> has no
+ internal support for such mapping, and relies on external tools
+ to do such conversions.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ </sect1>
- <row>
- <entry>
- <indexterm>
- <primary>covariance</primary>
- <secondary>sample</secondary>
- </indexterm>
- <function>covar_samp(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>sample covariance</entry>
- </row>
- <row>
- <entry>
- <function>regr_avgx(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>average of the independent variable
- (<literal>sum(<replaceable class="parameter">X</replaceable>)/<replaceable class="parameter">N</replaceable></literal>)</entry>
- </row>
+ <sect1 id="functions-sequence">
+ <title>Sequence Manipulation Functions</title>
- <row>
- <entry>
- <function>regr_avgy(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>average of the dependent variable
- (<literal>sum(<replaceable class="parameter">Y</replaceable>)/<replaceable class="parameter">N</replaceable></literal>)</entry>
- </row>
+ <indexterm>
+ <primary>sequence</primary>
+ </indexterm>
+ <indexterm>
+ <primary>nextval</primary>
+ </indexterm>
+ <indexterm>
+ <primary>currval</primary>
+ </indexterm>
+ <indexterm>
+ <primary>lastval</primary>
+ </indexterm>
+ <indexterm>
+ <primary>setval</primary>
+ </indexterm>
- <row>
- <entry>
- <function>regr_count(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>
- <type>bigint</type>
- </entry>
- <entry>number of input rows in which both expressions are nonnull</entry>
- </row>
+ <para>
+ This section describes <productname>PostgreSQL</productname>'s functions
+ for operating on <firstterm>sequence objects</firstterm>.
+ Sequence objects (also called sequence generators or
+ just sequences) are special single-row tables created with
+ <command>CREATE SEQUENCE</command>. A sequence object is usually used to
+ generate unique identifiers for rows of a table. The sequence functions,
+ listed in <xref linkend="functions-sequence-table">,
+ provide simple, multiuser-safe methods for obtaining successive
+ sequence values from sequence objects.
+ </para>
- <row>
- <entry>
- <indexterm>
- <primary>regression intercept</primary>
- </indexterm>
- <function>regr_intercept(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>y-intercept of the least-squares-fit linear equation
- determined by the (<replaceable
- class="parameter">X</replaceable>, <replaceable
- class="parameter">Y</replaceable>) pairs</entry>
- </row>
-
- <row>
- <entry>
- <function>regr_r2(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>square of the correlation coefficient</entry>
- </row>
-
- <row>
- <entry>
- <indexterm>
- <primary>regression slope</primary>
- </indexterm>
- <function>regr_slope(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>slope of the least-squares-fit linear equation determined
- by the (<replaceable class="parameter">X</replaceable>,
- <replaceable class="parameter">Y</replaceable>) pairs</entry>
- </row>
-
- <row>
- <entry>
- <function>regr_sxx(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry><literal>sum(<replaceable
- class="parameter">X</replaceable>^2) - sum(<replaceable
- class="parameter">X</replaceable>)^2/<replaceable
- class="parameter">N</replaceable></literal> (<quote>sum of
- squares</quote> of the independent variable)</entry>
- </row>
-
- <row>
- <entry>
- <function>regr_sxy(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry><literal>sum(<replaceable
- class="parameter">X</replaceable>*<replaceable
- class="parameter">Y</replaceable>) - sum(<replaceable
- class="parameter">X</replaceable>) * sum(<replaceable
- class="parameter">Y</replaceable>)/<replaceable
- class="parameter">N</replaceable></literal> (<quote>sum of
- products</quote> of independent times dependent
- variable)</entry>
- </row>
-
- <row>
- <entry>
- <function>regr_syy(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry>
- <type>double precision</type>
- </entry>
- <entry><literal>sum(<replaceable
- class="parameter">Y</replaceable>^2) - sum(<replaceable
- class="parameter">Y</replaceable>)^2/<replaceable
- class="parameter">N</replaceable></literal> (<quote>sum of
- squares</quote> of the dependent variable)</entry>
- </row>
-
- <row>
- <entry>
- <indexterm>
- <primary>standard deviation</primary>
- </indexterm>
- <function>stddev(<replaceable class="parameter">expression</replaceable>)</function>
- </entry>
- <entry>
- <type>smallint</type>, <type>int</type>,
- <type>bigint</type>, <type>real</type>, <type>double
- precision</type>, or <type>numeric</type>
- </entry>
- <entry>
- <type>double precision</type> for floating-point arguments,
- otherwise <type>numeric</type>
- </entry>
- <entry>historical alias for <function>stddev_samp</function></entry>
- </row>
-
- <row>
- <entry>
- <indexterm>
- <primary>standard deviation</primary>
- <secondary>population</secondary>
- </indexterm>
- <function>stddev_pop(<replaceable class="parameter">expression</replaceable>)</function>
- </entry>
- <entry>
- <type>smallint</type>, <type>int</type>,
- <type>bigint</type>, <type>real</type>, <type>double
- precision</type>, or <type>numeric</type>
- </entry>
- <entry>
- <type>double precision</type> for floating-point arguments,
- otherwise <type>numeric</type>
- </entry>
- <entry>population standard deviation of the input values</entry>
- </row>
-
- <row>
- <entry>
- <indexterm>
- <primary>standard deviation</primary>
- <secondary>sample</secondary>
- </indexterm>
- <function>stddev_samp(<replaceable class="parameter">expression</replaceable>)</function>
- </entry>
- <entry>
- <type>smallint</type>, <type>int</type>,
- <type>bigint</type>, <type>real</type>, <type>double
- precision</type>, or <type>numeric</type>
- </entry>
- <entry>
- <type>double precision</type> for floating-point arguments,
- otherwise <type>numeric</type>
- </entry>
- <entry>sample standard deviation of the input values</entry>
- </row>
-
- <row>
- <entry>
- <indexterm>
- <primary>variance</primary>
- </indexterm>
- <function>variance</function>(<replaceable class="parameter">expression</replaceable>)
- </entry>
- <entry>
- <type>smallint</type>, <type>int</type>,
- <type>bigint</type>, <type>real</type>, <type>double
- precision</type>, or <type>numeric</type>
- </entry>
- <entry>
- <type>double precision</type> for floating-point arguments,
- otherwise <type>numeric</type>
- </entry>
- <entry>historical alias for <function>var_samp</function></entry>
- </row>
-
- <row>
- <entry>
- <indexterm>
- <primary>variance</primary>
- <secondary>population</secondary>
- </indexterm>
- <function>var_pop</function>(<replaceable class="parameter">expression</replaceable>)
- </entry>
- <entry>
- <type>smallint</type>, <type>int</type>,
- <type>bigint</type>, <type>real</type>, <type>double
- precision</type>, or <type>numeric</type>
- </entry>
- <entry>
- <type>double precision</type> for floating-point arguments,
- otherwise <type>numeric</type>
- </entry>
- <entry>population variance of the input values (square of the population standard deviation)</entry>
- </row>
-
- <row>
- <entry>
- <indexterm>
- <primary>variance</primary>
- <secondary>sample</secondary>
- </indexterm>
- <function>var_samp</function>(<replaceable class="parameter">expression</replaceable>)
- </entry>
- <entry>
- <type>smallint</type>, <type>int</type>,
- <type>bigint</type>, <type>real</type>, <type>double
- precision</type>, or <type>numeric</type>
- </entry>
- <entry>
- <type>double precision</type> for floating-point arguments,
- otherwise <type>numeric</type>
- </entry>
- <entry>sample variance of the input values (square of the sample standard deviation)</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- </sect1>
-
-
- <sect1 id="functions-subquery">
- <title>Subquery Expressions</title>
-
- <indexterm>
- <primary>EXISTS</primary>
- </indexterm>
-
- <indexterm>
- <primary>IN</primary>
- </indexterm>
-
- <indexterm>
- <primary>NOT IN</primary>
- </indexterm>
-
- <indexterm>
- <primary>ANY</primary>
- </indexterm>
-
- <indexterm>
- <primary>ALL</primary>
- </indexterm>
-
- <indexterm>
- <primary>SOME</primary>
- </indexterm>
+ <table id="functions-sequence-table">
+ <title>Sequence Functions</title>
+ <tgroup cols="3">
+ <thead>
+ <row><entry>Function</entry> <entry>Return Type</entry> <entry>Description</entry></row>
+ </thead>
- <indexterm>
- <primary>subquery</primary>
- </indexterm>
+ <tbody>
+ <row>
+ <entry><literal><function>currval</function>(<type>regclass</type>)</literal></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Return value most recently obtained with
+ <function>nextval</function> for specified sequence</entry>
+ </row>
+ <row>
+ <entry><literal><function>nextval</function>(<type>regclass</type>)</literal></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Advance sequence and return new value</entry>
+ </row>
+ <row>
+ <entry><literal><function>setval</function>(<type>regclass</type>, <type>bigint</type>)</literal></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Set sequence's current value</entry>
+ </row>
+ <row>
+ <entry><literal><function>setval</function>(<type>regclass</type>, <type>bigint</type>, <type>boolean</type>)</literal></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Set sequence's current value and <literal>is_called</literal> flag</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
<para>
- This section describes the <acronym>SQL</acronym>-compliant subquery
- expressions available in <productname>PostgreSQL</productname>.
- All of the expression forms documented in this section return
- Boolean (true/false) results.
+ The sequence to be operated on by a sequence-function call is specified by
+ a <type>regclass</> argument, which is just the OID of the sequence in the
+ <structname>pg_class</> system catalog. You do not have to look up the
+ OID by hand, however, since the <type>regclass</> data type's input
+ converter will do the work for you. Just write the sequence name enclosed
+ in single quotes, so that it looks like a literal constant. To
+ achieve some compatibility with the handling of ordinary
+ <acronym>SQL</acronym> names, the string will be converted to lowercase
+ unless it contains double quotes around the sequence name. Thus:
+<programlisting>
+nextval('foo') <lineannotation>operates on sequence <literal>foo</literal></>
+nextval('FOO') <lineannotation>operates on sequence <literal>foo</literal></>
+nextval('"Foo"') <lineannotation>operates on sequence <literal>Foo</literal></>
+</programlisting>
+ The sequence name can be schema-qualified if necessary:
+<programlisting>
+nextval('myschema.foo') <lineannotation>operates on <literal>myschema.foo</literal></>
+nextval('"myschema".foo') <lineannotation>same as above</lineannotation>
+nextval('foo') <lineannotation>searches search path for <literal>foo</literal></>
+</programlisting>
+ See <xref linkend="datatype-oid"> for more information about
+ <type>regclass</>.
</para>
- <sect2>
- <title><literal>EXISTS</literal></title>
+ <note>
+ <para>
+ Before <productname>PostgreSQL</productname> 8.1, the arguments of the
+ sequence functions were of type <type>text</>, not <type>regclass</>, and
+ the above-described conversion from a text string to an OID value would
+ happen at run time during each call. For backwards compatibility, this
+ facility still exists, but internally it is now handled as an implicit
+ coercion from <type>text</> to <type>regclass</> before the function is
+ invoked.
+ </para>
-<synopsis>
-EXISTS (<replaceable>subquery</replaceable>)
-</synopsis>
+ <para>
+ When you write the argument of a sequence function as an unadorned
+ literal string, it becomes a constant of type <type>regclass</>.
+ Since this is really just an OID, it will track the originally
+ identified sequence despite later renaming, schema reassignment,
+ etc. This <quote>early binding</> behavior is usually desirable for
+ sequence references in column defaults and views. But sometimes you will
+ want <quote>late binding</> where the sequence reference is resolved
+ at run time. To get late-binding behavior, force the constant to be
+ stored as a <type>text</> constant instead of <type>regclass</>:
+<programlisting>
+nextval('foo'::text) <lineannotation><literal>foo</literal> is looked up at runtime</>
+</programlisting>
+ Note that late binding was the only behavior supported in
+ <productname>PostgreSQL</productname> releases before 8.1, so you
+ might need to do this to preserve the semantics of old applications.
+ </para>
- <para>
- The argument of <token>EXISTS</token> is an arbitrary <command>SELECT</> statement,
- or <firstterm>subquery</firstterm>. The
- subquery is evaluated to determine whether it returns any rows.
- If it returns at least one row, the result of <token>EXISTS</token> is
- <quote>true</>; if the subquery returns no rows, the result of <token>EXISTS</token>
- is <quote>false</>.
- </para>
+ <para>
+ Of course, the argument of a sequence function can be an expression
+ as well as a constant. If it is a text expression then the implicit
+ coercion will result in a run-time lookup.
+ </para>
+ </note>
<para>
- The subquery can refer to variables from the surrounding query,
- which will act as constants during any one evaluation of the subquery.
- </para>
+ The available sequence functions are:
+
+ <variablelist>
+ <varlistentry>
+ <term><function>nextval</function></term>
+ <listitem>
+ <para>
+ Advance the sequence object to its next value and return that
+ value. This is done atomically: even if multiple sessions
+ execute <function>nextval</function> concurrently, each will safely receive
+ a distinct sequence value.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>currval</function></term>
+ <listitem>
+ <para>
+ Return the value most recently obtained by <function>nextval</function>
+ for this sequence in the current session. (An error is
+ reported if <function>nextval</function> has never been called for this
+ sequence in this session.) Notice that because this is returning
+ a session-local value, it gives a predictable answer whether or not
+ other sessions have executed <function>nextval</function> since the
+ current session did.
+ </para>
+ </listitem>
+ </varlistentry>
- <para>
- The subquery will generally only be executed far enough to determine
- whether at least one row is returned, not all the way to completion.
- It is unwise to write a subquery that has any side effects (such as
- calling sequence functions); whether the side effects occur or not
- might be difficult to predict.
- </para>
+ <varlistentry>
+ <term><function>lastval</function></term>
+ <listitem>
+ <para>
+ Return the value most recently returned by
+ <function>nextval</> in the current session. This function is
+ identical to <function>currval</function>, except that instead
+ of taking the sequence name as an argument it fetches the
+ value of the last sequence that <function>nextval</function>
+ was used on in the current session. It is an error to call
+ <function>lastval</function> if <function>nextval</function>
+ has not yet been called in the current session.
+ </para>
+ </listitem>
+ </varlistentry>
- <para>
- Since the result depends only on whether any rows are returned,
- and not on the contents of those rows, the output list of the
- subquery is normally uninteresting. A common coding convention is
- to write all <literal>EXISTS</> tests in the form
- <literal>EXISTS(SELECT 1 WHERE ...)</literal>. There are exceptions to
- this rule however, such as subqueries that use <token>INTERSECT</token>.
- </para>
+ <varlistentry>
+ <term><function>setval</function></term>
+ <listitem>
+ <para>
+ Reset the sequence object's counter value. The two-parameter
+ form sets the sequence's <literal>last_value</literal> field to the specified
+ value and sets its <literal>is_called</literal> field to <literal>true</literal>,
+ meaning that the next <function>nextval</function> will advance the sequence
+ before returning a value. In the three-parameter form,
+ <literal>is_called</literal> can be set either <literal>true</literal> or
+ <literal>false</literal>. If it's set to <literal>false</literal>,
+ the next <function>nextval</function> will return exactly the specified
+ value, and sequence advancement commences with the following
+ <function>nextval</function>. For example,
- <para>
- This simple example is like an inner join on <literal>col2</>, but
- it produces at most one output row for each <literal>tab1</> row,
- even if there are multiple matching <literal>tab2</> rows:
<screen>
-SELECT col1 FROM tab1
- WHERE EXISTS(SELECT 1 FROM tab2 WHERE col2 = tab1.col2);
+SELECT setval('foo', 42); <lineannotation>Next <function>nextval</> will return 43</lineannotation>
+SELECT setval('foo', 42, true); <lineannotation>Same as above</lineannotation>
+SELECT setval('foo', 42, false); <lineannotation>Next <function>nextval</> will return 42</lineannotation>
</screen>
- </para>
- </sect2>
-
- <sect2>
- <title><literal>IN</literal></title>
-
-<synopsis>
-<replaceable>expression</replaceable> IN (<replaceable>subquery</replaceable>)
-</synopsis>
- <para>
- The right-hand side is a parenthesized
- subquery, which must return exactly one column. The left-hand expression
- is evaluated and compared to each row of the subquery result.
- The result of <token>IN</token> is <quote>true</> if any equal subquery row is found.
- The result is <quote>false</> if no equal row is found (including the special
- case where the subquery returns no rows).
+ The result returned by <function>setval</function> is just the value of its
+ second argument.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
</para>
<para>
- Note that if the left-hand expression yields null, or if there are
- no equal right-hand values and at least one right-hand row yields
- null, the result of the <token>IN</token> construct will be null, not false.
- This is in accordance with SQL's normal rules for Boolean combinations
- of null values.
+ If a sequence object has been created with default parameters,
+ <function>nextval</function> calls on it will return successive values
+ beginning with 1. Other behaviors can be obtained by using
+ special parameters in the <xref linkend="sql-createsequence" endterm="sql-createsequence-title"> command;
+ see its command reference page for more information.
</para>
- <para>
- As with <token>EXISTS</token>, it's unwise to assume that the subquery will
- be evaluated completely.
- </para>
+ <important>
+ <para>
+ To avoid blocking of concurrent transactions that obtain numbers from the
+ same sequence, a <function>nextval</function> operation is never rolled back;
+ that is, once a value has been fetched it is considered used, even if the
+ transaction that did the <function>nextval</function> later aborts. This means
+ that aborted transactions might leave unused <quote>holes</quote> in the
+ sequence of assigned values. <function>setval</function> operations are never
+ rolled back, either.
+ </para>
+ </important>
-<synopsis>
-<replaceable>row_constructor</replaceable> IN (<replaceable>subquery</replaceable>)
-</synopsis>
+ </sect1>
- <para>
- The left-hand side of this form of <token>IN</token> is a row constructor,
- as described in <xref linkend="sql-syntax-row-constructors">.
- The right-hand side is a parenthesized
- subquery, which must return exactly as many columns as there are
- expressions in the left-hand row. The left-hand expressions are
- evaluated and compared row-wise to each row of the subquery result.
- The result of <token>IN</token> is <quote>true</> if any equal subquery row is found.
- The result is <quote>false</> if no equal row is found (including the special
- case where the subquery returns no rows).
- </para>
- <para>
- As usual, null values in the rows are combined per
- the normal rules of SQL Boolean expressions. Two rows are considered
- equal if all their corresponding members are non-null and equal; the rows
- are unequal if any corresponding members are non-null and unequal;
- otherwise the result of that row comparison is unknown (null).
- If all the per-row results are either unequal or null, with at least one
- null, then the result of <token>IN</token> is null.
- </para>
- </sect2>
+ <sect1 id="functions-conditional">
+ <title>Conditional Expressions</title>
- <sect2>
- <title><literal>NOT IN</literal></title>
+ <indexterm>
+ <primary>CASE</primary>
+ </indexterm>
-<synopsis>
-<replaceable>expression</replaceable> NOT IN (<replaceable>subquery</replaceable>)
-</synopsis>
+ <indexterm>
+ <primary>conditional expression</primary>
+ </indexterm>
<para>
- The right-hand side is a parenthesized
- subquery, which must return exactly one column. The left-hand expression
- is evaluated and compared to each row of the subquery result.
- The result of <token>NOT IN</token> is <quote>true</> if only unequal subquery rows
- are found (including the special case where the subquery returns no rows).
- The result is <quote>false</> if any equal row is found.
+ This section describes the <acronym>SQL</acronym>-compliant conditional expressions
+ available in <productname>PostgreSQL</productname>.
</para>
- <para>
- Note that if the left-hand expression yields null, or if there are
- no equal right-hand values and at least one right-hand row yields
- null, the result of the <token>NOT IN</token> construct will be null, not true.
- This is in accordance with SQL's normal rules for Boolean combinations
- of null values.
- </para>
+ <tip>
+ <para>
+ If your needs go beyond the capabilities of these conditional
+ expressions you might want to consider writing a stored procedure
+ in a more expressive programming language.
+ </para>
+ </tip>
+
+ <sect2>
+ <title><literal>CASE</></title>
<para>
- As with <token>EXISTS</token>, it's unwise to assume that the subquery will
- be evaluated completely.
- </para>
+ The <acronym>SQL</acronym> <token>CASE</token> expression is a
+ generic conditional expression, similar to if/else statements in
+ other languages:
<synopsis>
-<replaceable>row_constructor</replaceable> NOT IN (<replaceable>subquery</replaceable>)
+CASE WHEN <replaceable>condition</replaceable> THEN <replaceable>result</replaceable>
+ <optional>WHEN ...</optional>
+ <optional>ELSE <replaceable>result</replaceable></optional>
+END
</synopsis>
- <para>
- The left-hand side of this form of <token>NOT IN</token> is a row constructor,
- as described in <xref linkend="sql-syntax-row-constructors">.
- The right-hand side is a parenthesized
- subquery, which must return exactly as many columns as there are
- expressions in the left-hand row. The left-hand expressions are
- evaluated and compared row-wise to each row of the subquery result.
- The result of <token>NOT IN</token> is <quote>true</> if only unequal subquery rows
- are found (including the special case where the subquery returns no rows).
- The result is <quote>false</> if any equal row is found.
- </para>
-
- <para>
- As usual, null values in the rows are combined per
- the normal rules of SQL Boolean expressions. Two rows are considered
- equal if all their corresponding members are non-null and equal; the rows
- are unequal if any corresponding members are non-null and unequal;
- otherwise the result of that row comparison is unknown (null).
- If all the per-row results are either unequal or null, with at least one
- null, then the result of <token>NOT IN</token> is null.
+ <token>CASE</token> clauses can be used wherever
+ an expression is valid. <replaceable>condition</replaceable> is an
+ expression that returns a <type>boolean</type> result. If the result is true
+ then the value of the <token>CASE</token> expression is the
+ <replaceable>result</replaceable> that follows the condition. If the result is false any
+ subsequent <token>WHEN</token> clauses are searched in the same
+ manner. If no <token>WHEN</token>
+ <replaceable>condition</replaceable> is true then the value of the
+ case expression is the <replaceable>result</replaceable> in the
+ <token>ELSE</token> clause. If the <token>ELSE</token> clause is
+ omitted and no condition matches, the result is null.
</para>
- </sect2>
- <sect2>
- <title><literal>ANY</literal>/<literal>SOME</literal></title>
+ <para>
+ An example:
+<screen>
+SELECT * FROM test;
-<synopsis>
-<replaceable>expression</replaceable> <replaceable>operator</replaceable> ANY (<replaceable>subquery</replaceable>)
-<replaceable>expression</replaceable> <replaceable>operator</replaceable> SOME (<replaceable>subquery</replaceable>)
-</synopsis>
+ a
+---
+ 1
+ 2
+ 3
- <para>
- The right-hand side is a parenthesized
- subquery, which must return exactly one column. The left-hand expression
- is evaluated and compared to each row of the subquery result using the
- given <replaceable>operator</replaceable>, which must yield a Boolean
- result.
- The result of <token>ANY</token> is <quote>true</> if any true result is obtained.
- The result is <quote>false</> if no true result is found (including the special
- case where the subquery returns no rows).
- </para>
- <para>
- <token>SOME</token> is a synonym for <token>ANY</token>.
- <token>IN</token> is equivalent to <literal>= ANY</literal>.
- </para>
+SELECT a,
+ CASE WHEN a=1 THEN 'one'
+ WHEN a=2 THEN 'two'
+ ELSE 'other'
+ END
+ FROM test;
- <para>
- Note that if there are no successes and at least one right-hand row yields
- null for the operator's result, the result of the <token>ANY</token> construct
- will be null, not false.
- This is in accordance with SQL's normal rules for Boolean combinations
- of null values.
- </para>
+ a | case
+---+-------
+ 1 | one
+ 2 | two
+ 3 | other
+</screen>
+ </para>
<para>
- As with <token>EXISTS</token>, it's unwise to assume that the subquery will
- be evaluated completely.
+ The data types of all the <replaceable>result</replaceable>
+ expressions must be convertible to a single output type.
+ See <xref linkend="typeconv-union-case"> for more detail.
</para>
+ <para>
+ The following <quote>simple</quote> <token>CASE</token> expression is a
+ specialized variant of the general form above:
+
<synopsis>
-<replaceable>row_constructor</replaceable> <replaceable>operator</> ANY (<replaceable>subquery</replaceable>)
-<replaceable>row_constructor</replaceable> <replaceable>operator</> SOME (<replaceable>subquery</replaceable>)
+CASE <replaceable>expression</replaceable>
+ WHEN <replaceable>value</replaceable> THEN <replaceable>result</replaceable>
+ <optional>WHEN ...</optional>
+ <optional>ELSE <replaceable>result</replaceable></optional>
+END
</synopsis>
- <para>
- The left-hand side of this form of <token>ANY</token> is a row constructor,
- as described in <xref linkend="sql-syntax-row-constructors">.
- The right-hand side is a parenthesized
- subquery, which must return exactly as many columns as there are
- expressions in the left-hand row. The left-hand expressions are
- evaluated and compared row-wise to each row of the subquery result,
- using the given <replaceable>operator</replaceable>.
- The result of <token>ANY</token> is <quote>true</> if the comparison
- returns true for any subquery row.
- The result is <quote>false</> if the comparison returns false for every
- subquery row (including the special case where the subquery returns no
- rows).
- The result is NULL if the comparison does not return true for any row,
- and it returns NULL for at least one row.
+ The
+ <replaceable>expression</replaceable> is computed and compared to
+ all the <replaceable>value</replaceable> specifications in the
+ <token>WHEN</token> clauses until one is found that is equal. If
+ no match is found, the <replaceable>result</replaceable> in the
+ <token>ELSE</token> clause (or a null value) is returned. This is similar
+ to the <function>switch</function> statement in C.
</para>
- <para>
- See <xref linkend="row-wise-comparison"> for details about the meaning
- of a row-wise comparison.
- </para>
+ <para>
+ The example above can be written using the simple
+ <token>CASE</token> syntax:
+<screen>
+SELECT a,
+ CASE a WHEN 1 THEN 'one'
+ WHEN 2 THEN 'two'
+ ELSE 'other'
+ END
+ FROM test;
+
+ a | case
+---+-------
+ 1 | one
+ 2 | two
+ 3 | other
+</screen>
+ </para>
+
+ <para>
+ A <token>CASE</token> expression does not evaluate any subexpressions
+ that are not needed to determine the result. For example, this is a
+ possible way of avoiding a division-by-zero failure:
+<programlisting>
+SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END;
+</programlisting>
+ </para>
</sect2>
<sect2>
- <title><literal>ALL</literal></title>
+ <title><literal>COALESCE</></title>
+
+ <indexterm>
+ <primary>COALESCE</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>NVL</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>IFNULL</primary>
+ </indexterm>
<synopsis>
-<replaceable>expression</replaceable> <replaceable>operator</replaceable> ALL (<replaceable>subquery</replaceable>)
+<function>COALESCE</function>(<replaceable>value</replaceable> <optional>, ...</optional>)
</synopsis>
<para>
- The right-hand side is a parenthesized
- subquery, which must return exactly one column. The left-hand expression
- is evaluated and compared to each row of the subquery result using the
- given <replaceable>operator</replaceable>, which must yield a Boolean
- result.
- The result of <token>ALL</token> is <quote>true</> if all rows yield true
- (including the special case where the subquery returns no rows).
- The result is <quote>false</> if any false result is found.
- The result is NULL if the comparison does not return false for any row,
- and it returns NULL for at least one row.
+ The <function>COALESCE</function> function returns the first of its
+ arguments that is not null. Null is returned only if all arguments
+ are null. It is often used to substitute a default value for
+ null values when data is retrieved for display, for example:
+<programlisting>
+SELECT COALESCE(description, short_description, '(none)') ...
+</programlisting>
</para>
- <para>
- <token>NOT IN</token> is equivalent to <literal><> ALL</literal>.
- </para>
+ <para>
+ Like a <token>CASE</token> expression, <function>COALESCE</function> will
+ not evaluate arguments that are not needed to determine the result;
+ that is, arguments to the right of the first non-null argument are
+ not evaluated. This SQL-standard function provides capabilities similar
+ to <function>NVL</> and <function>IFNULL</>, which are used in some other
+ database systems.
+ </para>
+ </sect2>
- <para>
- As with <token>EXISTS</token>, it's unwise to assume that the subquery will
- be evaluated completely.
- </para>
+ <sect2>
+ <title><literal>NULLIF</></title>
+
+ <indexterm>
+ <primary>NULLIF</primary>
+ </indexterm>
<synopsis>
-<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> ALL (<replaceable>subquery</replaceable>)
+<function>NULLIF</function>(<replaceable>value1</replaceable>, <replaceable>value2</replaceable>)
</synopsis>
<para>
- The left-hand side of this form of <token>ALL</token> is a row constructor,
- as described in <xref linkend="sql-syntax-row-constructors">.
- The right-hand side is a parenthesized
- subquery, which must return exactly as many columns as there are
- expressions in the left-hand row. The left-hand expressions are
- evaluated and compared row-wise to each row of the subquery result,
- using the given <replaceable>operator</replaceable>.
- The result of <token>ALL</token> is <quote>true</> if the comparison
- returns true for all subquery rows (including the special
- case where the subquery returns no rows).
- The result is <quote>false</> if the comparison returns false for any
- subquery row.
- The result is NULL if the comparison does not return false for any
- subquery row, and it returns NULL for at least one row.
+ The <function>NULLIF</function> function returns a null value if
+ <replaceable>value1</replaceable> and <replaceable>value2</replaceable>
+ are equal; otherwise it returns <replaceable>value1</replaceable>.
+ This can be used to perform the inverse operation of the
+ <function>COALESCE</function> example given above:
+<programlisting>
+SELECT NULLIF(value, '(none)') ...
+</programlisting>
</para>
-
<para>
- See <xref linkend="row-wise-comparison"> for details about the meaning
- of a row-wise comparison.
+ If <replaceable>value1</replaceable> is <literal>(none)</>, return a null,
+ otherwise return <replaceable>value1</replaceable>.
</para>
+
</sect2>
<sect2>
- <title>Row-wise Comparison</title>
+ <title><literal>GREATEST</literal> and <literal>LEAST</literal></title>
- <indexterm zone="functions-subquery">
- <primary>comparison</primary>
- <secondary>subquery result row</secondary>
- </indexterm>
+ <indexterm>
+ <primary>GREATEST</primary>
+ </indexterm>
+ <indexterm>
+ <primary>LEAST</primary>
+ </indexterm>
<synopsis>
-<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> (<replaceable>subquery</replaceable>)
+<function>GREATEST</function>(<replaceable>value</replaceable> <optional>, ...</optional>)
+</synopsis>
+<synopsis>
+<function>LEAST</function>(<replaceable>value</replaceable> <optional>, ...</optional>)
</synopsis>
- <para>
- The left-hand side is a row constructor,
- as described in <xref linkend="sql-syntax-row-constructors">.
- The right-hand side is a parenthesized subquery, which must return exactly
- as many columns as there are expressions in the left-hand row. Furthermore,
- the subquery cannot return more than one row. (If it returns zero rows,
- the result is taken to be null.) The left-hand side is evaluated and
- compared row-wise to the single subquery result row.
- </para>
+ <para>
+ The <function>GREATEST</> and <function>LEAST</> functions select the
+ largest or smallest value from a list of any number of expressions.
+ The expressions must all be convertible to a common data type, which
+ will be the type of the result
+ (see <xref linkend="typeconv-union-case"> for details). NULL values
+ in the list are ignored. The result will be NULL only if all the
+ expressions evaluate to NULL.
+ </para>
- <para>
- See <xref linkend="row-wise-comparison"> for details about the meaning
- of a row-wise comparison.
- </para>
+ <para>
+ Note that <function>GREATEST</> and <function>LEAST</> are not in
+ the SQL standard, but are a common extension.
+ </para>
</sect2>
</sect1>
- <sect1 id="functions-comparisons">
- <title>Row and Array Comparisons</title>
+ <sect1 id="functions-array">
+ <title>Array Functions and Operators</title>
- <indexterm>
- <primary>IN</primary>
- </indexterm>
+ <para>
+ <xref linkend="array-operators-table"> shows the operators
+ available for <type>array</type> types.
+ </para>
+
+ <table id="array-operators-table">
+ <title><type>array</type> Operators</title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Operator</entry>
+ <entry>Description</entry>
+ <entry>Example</entry>
+ <entry>Result</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry> <literal>=</literal> </entry>
+ <entry>equal</entry>
+ <entry><literal>ARRAY[1.1,2.1,3.1]::int[] = ARRAY[1,2,3]</literal></entry>
+ <entry><literal>t</literal></entry>
+ </row>
+
+ <row>
+ <entry> <literal><></literal> </entry>
+ <entry>not equal</entry>
+ <entry><literal>ARRAY[1,2,3] <> ARRAY[1,2,4]</literal></entry>
+ <entry><literal>t</literal></entry>
+ </row>
+
+ <row>
+ <entry> <literal><</literal> </entry>
+ <entry>less than</entry>
+ <entry><literal>ARRAY[1,2,3] < ARRAY[1,2,4]</literal></entry>
+ <entry><literal>t</literal></entry>
+ </row>
+
+ <row>
+ <entry> <literal>></literal> </entry>
+ <entry>greater than</entry>
+ <entry><literal>ARRAY[1,4,3] > ARRAY[1,2,4]</literal></entry>
+ <entry><literal>t</literal></entry>
+ </row>
+
+ <row>
+ <entry> <literal><=</literal> </entry>
+ <entry>less than or equal</entry>
+ <entry><literal>ARRAY[1,2,3] <= ARRAY[1,2,3]</literal></entry>
+ <entry><literal>t</literal></entry>
+ </row>
- <indexterm>
- <primary>NOT IN</primary>
- </indexterm>
+ <row>
+ <entry> <literal>>=</literal> </entry>
+ <entry>greater than or equal</entry>
+ <entry><literal>ARRAY[1,4,3] >= ARRAY[1,4,3]</literal></entry>
+ <entry><literal>t</literal></entry>
+ </row>
- <indexterm>
- <primary>ANY</primary>
- </indexterm>
+ <row>
+ <entry> <literal>@></literal> </entry>
+ <entry>contains</entry>
+ <entry><literal>ARRAY[1,4,3] @> ARRAY[3,1]</literal></entry>
+ <entry><literal>t</literal></entry>
+ </row>
- <indexterm>
- <primary>ALL</primary>
- </indexterm>
+ <row>
+ <entry> <literal><@</literal> </entry>
+ <entry>is contained by</entry>
+ <entry><literal>ARRAY[2,7] <@ ARRAY[1,7,4,2,6]</literal></entry>
+ <entry><literal>t</literal></entry>
+ </row>
- <indexterm>
- <primary>SOME</primary>
- </indexterm>
+ <row>
+ <entry> <literal>&&</literal> </entry>
+ <entry>overlap (have elements in common)</entry>
+ <entry><literal>ARRAY[1,4,3] && ARRAY[2,1]</literal></entry>
+ <entry><literal>t</literal></entry>
+ </row>
- <indexterm>
- <primary>row-wise comparison</primary>
- </indexterm>
+ <row>
+ <entry> <literal>||</literal> </entry>
+ <entry>array-to-array concatenation</entry>
+ <entry><literal>ARRAY[1,2,3] || ARRAY[4,5,6]</literal></entry>
+ <entry><literal>{1,2,3,4,5,6}</literal></entry>
+ </row>
- <indexterm>
- <primary>comparison</primary>
- <secondary>row-wise</secondary>
- </indexterm>
+ <row>
+ <entry> <literal>||</literal> </entry>
+ <entry>array-to-array concatenation</entry>
+ <entry><literal>ARRAY[1,2,3] || ARRAY[[4,5,6],[7,8,9]]</literal></entry>
+ <entry><literal>{{1,2,3},{4,5,6},{7,8,9}}</literal></entry>
+ </row>
- <indexterm>
- <primary>IS DISTINCT FROM</primary>
- </indexterm>
+ <row>
+ <entry> <literal>||</literal> </entry>
+ <entry>element-to-array concatenation</entry>
+ <entry><literal>3 || ARRAY[4,5,6]</literal></entry>
+ <entry><literal>{3,4,5,6}</literal></entry>
+ </row>
- <indexterm>
- <primary>IS NOT DISTINCT FROM</primary>
- </indexterm>
+ <row>
+ <entry> <literal>||</literal> </entry>
+ <entry>array-to-element concatenation</entry>
+ <entry><literal>ARRAY[4,5,6] || 7</literal></entry>
+ <entry><literal>{4,5,6,7}</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
<para>
- This section describes several specialized constructs for making
- multiple comparisons between groups of values. These forms are
- syntactically related to the subquery forms of the previous section,
- but do not involve subqueries.
- The forms involving array subexpressions are
- <productname>PostgreSQL</productname> extensions; the rest are
- <acronym>SQL</acronym>-compliant.
- All of the expression forms documented in this section return
- Boolean (true/false) results.
+ Array comparisons compare the array contents element-by-element,
+ using the default B-Tree comparison function for the element data type.
+ In multidimensional arrays the elements are visited in row-major order
+ (last subscript varies most rapidly).
+ If the contents of two arrays are equal but the dimensionality is
+ different, the first difference in the dimensionality information
+ determines the sort order. (This is a change from versions of
+ <productname>PostgreSQL</> prior to 8.2: older versions would claim
+ that two arrays with the same contents were equal, even if the
+ number of dimensions or subscript ranges were different.)
</para>
- <sect2>
- <title><literal>IN</literal></title>
-
-<synopsis>
-<replaceable>expression</replaceable> IN (<replaceable>value</replaceable> <optional>, ...</optional>)
-</synopsis>
-
<para>
- The right-hand side is a parenthesized list
- of scalar expressions. The result is <quote>true</> if the left-hand expression's
- result is equal to any of the right-hand expressions. This is a shorthand
- notation for
-
-<synopsis>
-<replaceable>expression</replaceable> = <replaceable>value1</replaceable>
-OR
-<replaceable>expression</replaceable> = <replaceable>value2</replaceable>
-OR
-...
-</synopsis>
+ See <xref linkend="arrays"> for more details about array operator
+ behavior.
</para>
<para>
- Note that if the left-hand expression yields null, or if there are
- no equal right-hand values and at least one right-hand expression yields
- null, the result of the <token>IN</token> construct will be null, not false.
- This is in accordance with SQL's normal rules for Boolean combinations
- of null values.
+ <xref linkend="array-functions-table"> shows the functions
+ available for use with array types. See <xref linkend="arrays">
+ for more discussion and examples of the use of these functions.
</para>
- </sect2>
-
- <sect2>
- <title><literal>NOT IN</literal></title>
-<synopsis>
-<replaceable>expression</replaceable> NOT IN (<replaceable>value</replaceable> <optional>, ...</optional>)
-</synopsis>
+ <table id="array-functions-table">
+ <title><type>array</type> Functions</title>
+ <tgroup cols="5">
+ <thead>
+ <row>
+ <entry>Function</entry>
+ <entry>Return Type</entry>
+ <entry>Description</entry>
+ <entry>Example</entry>
+ <entry>Result</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>
+ <function>array_append</function>(<type>anyarray</type>, <type>anyelement</type>)
+ </literal>
+ </entry>
+ <entry><type>anyarray</type></entry>
+ <entry>append an element to the end of an array</entry>
+ <entry><literal>array_append(ARRAY[1,2], 3)</literal></entry>
+ <entry><literal>{1,2,3}</literal></entry>
+ </row>
+ <row>
+ <entry>
+ <literal>
+ <function>array_cat</function>(<type>anyarray</type>, <type>anyarray</type>)
+ </literal>
+ </entry>
+ <entry><type>anyarray</type></entry>
+ <entry>concatenate two arrays</entry>
+ <entry><literal>array_cat(ARRAY[1,2,3], ARRAY[4,5])</literal></entry>
+ <entry><literal>{1,2,3,4,5}</literal></entry>
+ </row>
+ <row>
+ <entry>
+ <literal>
+ <function>array_dims</function>(<type>anyarray</type>)
+ </literal>
+ </entry>
+ <entry><type>text</type></entry>
+ <entry>returns a text representation of array's dimensions</entry>
+ <entry><literal>array_dims(ARRAY[[1,2,3], [4,5,6]])</literal></entry>
+ <entry><literal>[1:2][1:3]</literal></entry>
+ </row>
+ <row>
+ <entry>
+ <literal>
+ <function>array_lower</function>(<type>anyarray</type>, <type>int</type>)
+ </literal>
+ </entry>
+ <entry><type>int</type></entry>
+ <entry>returns lower bound of the requested array dimension</entry>
+ <entry><literal>array_lower('[0:2]={1,2,3}'::int[], 1)</literal></entry>
+ <entry><literal>0</literal></entry>
+ </row>
+ <row>
+ <entry>
+ <literal>
+ <function>array_prepend</function>(<type>anyelement</type>, <type>anyarray</type>)
+ </literal>
+ </entry>
+ <entry><type>anyarray</type></entry>
+ <entry>append an element to the beginning of an array</entry>
+ <entry><literal>array_prepend(1, ARRAY[2,3])</literal></entry>
+ <entry><literal>{1,2,3}</literal></entry>
+ </row>
+ <row>
+ <entry>
+ <literal>
+ <function>array_to_string</function>(<type>anyarray</type>, <type>text</type>)
+ </literal>
+ </entry>
+ <entry><type>text</type></entry>
+ <entry>concatenates array elements using provided delimiter</entry>
+ <entry><literal>array_to_string(ARRAY[1, 2, 3], '~^~')</literal></entry>
+ <entry><literal>1~^~2~^~3</literal></entry>
+ </row>
+ <row>
+ <entry>
+ <literal>
+ <function>array_upper</function>(<type>anyarray</type>, <type>int</type>)
+ </literal>
+ </entry>
+ <entry><type>int</type></entry>
+ <entry>returns upper bound of the requested array dimension</entry>
+ <entry><literal>array_upper(ARRAY[1,2,3,4], 1)</literal></entry>
+ <entry><literal>4</literal></entry>
+ </row>
+ <row>
+ <entry>
+ <literal>
+ <function>string_to_array</function>(<type>text</type>, <type>text</type>)
+ </literal>
+ </entry>
+ <entry><type>text[]</type></entry>
+ <entry>splits string into array elements using provided delimiter</entry>
+ <entry><literal>string_to_array('xx~^~yy~^~zz', '~^~')</literal></entry>
+ <entry><literal>{xx,yy,zz}</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
- <para>
- The right-hand side is a parenthesized list
- of scalar expressions. The result is <quote>true</quote> if the left-hand expression's
- result is unequal to all of the right-hand expressions. This is a shorthand
- notation for
+ <sect1 id="functions-aggregate">
+ <title>Aggregate Functions</title>
-<synopsis>
-<replaceable>expression</replaceable> <> <replaceable>value1</replaceable>
-AND
-<replaceable>expression</replaceable> <> <replaceable>value2</replaceable>
-AND
-...
-</synopsis>
- </para>
+ <indexterm zone="functions-aggregate">
+ <primary>aggregate function</primary>
+ <secondary>built-in</secondary>
+ </indexterm>
<para>
- Note that if the left-hand expression yields null, or if there are
- no equal right-hand values and at least one right-hand expression yields
- null, the result of the <token>NOT IN</token> construct will be null, not true
- as one might naively expect.
- This is in accordance with SQL's normal rules for Boolean combinations
- of null values.
+ <firstterm>Aggregate functions</firstterm> compute a single result
+ value from a set of input values. The built-in aggregate functions
+ are listed in
+ <xref linkend="functions-aggregate-table"> and
+ <xref linkend="functions-aggregate-statistics-table">.
+ The special syntax considerations for aggregate
+ functions are explained in <xref linkend="syntax-aggregates">.
+ Consult <xref linkend="tutorial-agg"> for additional introductory
+ information.
</para>
- <tip>
- <para>
- <literal>x NOT IN y</literal> is equivalent to <literal>NOT (x IN y)</literal> in all
- cases. However, null values are much more likely to trip up the novice when
- working with <token>NOT IN</token> than when working with <token>IN</token>.
- It's best to express your condition positively if possible.
- </para>
- </tip>
- </sect2>
+ <table id="functions-aggregate-table">
+ <title>General-Purpose Aggregate Functions</title>
- <sect2>
- <title><literal>ANY</literal>/<literal>SOME</literal> (array)</title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Function</entry>
+ <entry>Argument Type</entry>
+ <entry>Return Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
-<synopsis>
-<replaceable>expression</replaceable> <replaceable>operator</replaceable> ANY (<replaceable>array expression</replaceable>)
-<replaceable>expression</replaceable> <replaceable>operator</replaceable> SOME (<replaceable>array expression</replaceable>)
-</synopsis>
+ <tbody>
+ <row>
+ <entry>
+ <indexterm>
+ <primary>average</primary>
+ </indexterm>
+ <function>avg(<replaceable class="parameter">expression</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>smallint</type>, <type>int</type>,
+ <type>bigint</type>, <type>real</type>, <type>double
+ precision</type>, <type>numeric</type>, or <type>interval</type>
+ </entry>
+ <entry>
+ <type>numeric</type> for any integer type argument,
+ <type>double precision</type> for a floating-point argument,
+ otherwise the same as the argument data type
+ </entry>
+ <entry>the average (arithmetic mean) of all input values</entry>
+ </row>
- <para>
- The right-hand side is a parenthesized expression, which must yield an
- array value.
- The left-hand expression
- is evaluated and compared to each element of the array using the
- given <replaceable>operator</replaceable>, which must yield a Boolean
- result.
- The result of <token>ANY</token> is <quote>true</> if any true result is obtained.
- The result is <quote>false</> if no true result is found (including the special
- case where the array has zero elements).
- </para>
+ <row>
+ <entry>
+ <indexterm>
+ <primary>bit_and</primary>
+ </indexterm>
+ <function>bit_and(<replaceable class="parameter">expression</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>smallint</type>, <type>int</type>, <type>bigint</type>, or
+ <type>bit</type>
+ </entry>
+ <entry>
+ same as argument data type
+ </entry>
+ <entry>the bitwise AND of all non-null input values, or null if none</entry>
+ </row>
- <para>
- If the array expression yields a null array, the result of
- <token>ANY</token> will be null. If the left-hand expression yields null,
- the result of <token>ANY</token> is ordinarily null (though a non-strict
- comparison operator could possibly yield a different result).
- Also, if the right-hand array contains any null elements and no true
- comparison result is obtained, the result of <token>ANY</token>
- will be null, not false (again, assuming a strict comparison operator).
- This is in accordance with SQL's normal rules for Boolean combinations
- of null values.
- </para>
+ <row>
+ <entry>
+ <indexterm>
+ <primary>bit_or</primary>
+ </indexterm>
+ <function>bit_or(<replaceable class="parameter">expression</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>smallint</type>, <type>int</type>, <type>bigint</type>, or
+ <type>bit</type>
+ </entry>
+ <entry>
+ same as argument data type
+ </entry>
+ <entry>the bitwise OR of all non-null input values, or null if none</entry>
+ </row>
- <para>
- <token>SOME</token> is a synonym for <token>ANY</token>.
- </para>
- </sect2>
+ <row>
+ <entry>
+ <indexterm>
+ <primary>bool_and</primary>
+ </indexterm>
+ <function>bool_and(<replaceable class="parameter">expression</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>bool</type>
+ </entry>
+ <entry>
+ <type>bool</type>
+ </entry>
+ <entry>true if all input values are true, otherwise false</entry>
+ </row>
- <sect2>
- <title><literal>ALL</literal> (array)</title>
+ <row>
+ <entry>
+ <indexterm>
+ <primary>bool_or</primary>
+ </indexterm>
+ <function>bool_or(<replaceable class="parameter">expression</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>bool</type>
+ </entry>
+ <entry>
+ <type>bool</type>
+ </entry>
+ <entry>true if at least one input value is true, otherwise false</entry>
+ </row>
-<synopsis>
-<replaceable>expression</replaceable> <replaceable>operator</replaceable> ALL (<replaceable>array expression</replaceable>)
-</synopsis>
+ <row>
+ <entry><function>count(*)</function></entry>
+ <entry></entry>
+ <entry><type>bigint</type></entry>
+ <entry>number of input rows</entry>
+ </row>
- <para>
- The right-hand side is a parenthesized expression, which must yield an
- array value.
- The left-hand expression
- is evaluated and compared to each element of the array using the
- given <replaceable>operator</replaceable>, which must yield a Boolean
- result.
- The result of <token>ALL</token> is <quote>true</> if all comparisons yield true
- (including the special case where the array has zero elements).
- The result is <quote>false</> if any false result is found.
- </para>
+ <row>
+ <entry><function>count(<replaceable class="parameter">expression</replaceable>)</function></entry>
+ <entry>any</entry>
+ <entry><type>bigint</type></entry>
+ <entry>
+ number of input rows for which the value of <replaceable
+ class="parameter">expression</replaceable> is not null
+ </entry>
+ </row>
- <para>
- If the array expression yields a null array, the result of
- <token>ALL</token> will be null. If the left-hand expression yields null,
- the result of <token>ALL</token> is ordinarily null (though a non-strict
- comparison operator could possibly yield a different result).
- Also, if the right-hand array contains any null elements and no false
- comparison result is obtained, the result of <token>ALL</token>
- will be null, not true (again, assuming a strict comparison operator).
- This is in accordance with SQL's normal rules for Boolean combinations
- of null values.
- </para>
- </sect2>
+ <row>
+ <entry>
+ <indexterm>
+ <primary>every</primary>
+ </indexterm>
+ <function>every(<replaceable class="parameter">expression</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>bool</type>
+ </entry>
+ <entry>
+ <type>bool</type>
+ </entry>
+ <entry>equivalent to <function>bool_and</function></entry>
+ </row>
- <sect2 id="row-wise-comparison">
- <title>Row-wise Comparison</title>
+ <row>
+ <entry><function>max(<replaceable class="parameter">expression</replaceable>)</function></entry>
+ <entry>any array, numeric, string, or date/time type</entry>
+ <entry>same as argument type</entry>
+ <entry>
+ maximum value of <replaceable
+ class="parameter">expression</replaceable> across all input
+ values
+ </entry>
+ </row>
-<synopsis>
-<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> <replaceable>row_constructor</replaceable>
-</synopsis>
+ <row>
+ <entry><function>min(<replaceable class="parameter">expression</replaceable>)</function></entry>
+ <entry>any array, numeric, string, or date/time type</entry>
+ <entry>same as argument type</entry>
+ <entry>
+ minimum value of <replaceable
+ class="parameter">expression</replaceable> across all input
+ values
+ </entry>
+ </row>
- <para>
- Each side is a row constructor,
- as described in <xref linkend="sql-syntax-row-constructors">.
- The two row values must have the same number of fields.
- Each side is evaluated and they are compared row-wise. Row comparisons
- are allowed when the <replaceable>operator</replaceable> is
- <literal>=</>,
- <literal><></>,
- <literal><</>,
- <literal><=</>,
- <literal>></> or
- <literal>>=</>,
- or has semantics similar to one of these. (To be specific, an operator
- can be a row comparison operator if it is a member of a B-Tree operator
- class, or is the negator of the <literal>=</> member of a B-Tree operator
- class.)
- </para>
+ <row>
+ <entry><function>sum(<replaceable class="parameter">expression</replaceable>)</function></entry>
+ <entry>
+ <type>smallint</type>, <type>int</type>,
+ <type>bigint</type>, <type>real</type>, <type>double
+ precision</type>, <type>numeric</type>, or
+ <type>interval</type>
+ </entry>
+ <entry>
+ <type>bigint</type> for <type>smallint</type> or
+ <type>int</type> arguments, <type>numeric</type> for
+ <type>bigint</type> arguments, <type>double precision</type>
+ for floating-point arguments, otherwise the same as the
+ argument data type
+ </entry>
+ <entry>sum of <replaceable class="parameter">expression</replaceable> across all input values</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
<para>
- The <literal>=</> and <literal><></> cases work slightly differently
- from the others. Two rows are considered
- equal if all their corresponding members are non-null and equal; the rows
- are unequal if any corresponding members are non-null and unequal;
- otherwise the result of the row comparison is unknown (null).
+ It should be noted that except for <function>count</function>,
+ these functions return a null value when no rows are selected. In
+ particular, <function>sum</function> of no rows returns null, not
+ zero as one might expect. The <function>coalesce</function> function can be
+ used to substitute zero for null when necessary.
</para>
- <para>
- For the <literal><</>, <literal><=</>, <literal>></> and
- <literal>>=</> cases, the row elements are compared left-to-right,
- stopping as soon as an unequal or null pair of elements is found.
- If either of this pair of elements is null, the result of the
- row comparison is unknown (null); otherwise comparison of this pair
- of elements determines the result. For example,
- <literal>ROW(1,2,NULL) < ROW(1,3,0)</>
- yields true, not null, because the third pair of elements are not
- considered.
- </para>
+ <note>
+ <indexterm>
+ <primary>ANY</primary>
+ </indexterm>
+ <indexterm>
+ <primary>SOME</primary>
+ </indexterm>
+ <para>
+ Boolean aggregates <function>bool_and</function> and
+ <function>bool_or</function> correspond to standard SQL aggregates
+ <function>every</function> and <function>any</function> or
+ <function>some</function>.
+ As for <function>any</function> and <function>some</function>,
+ it seems that there is an ambiguity built into the standard syntax:
+<programlisting>
+SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...;
+</programlisting>
+ Here <function>ANY</function> can be considered both as leading
+ to a subquery or as an aggregate if the select expression returns 1 row.
+ Thus the standard name cannot be given to these aggregates.
+ </para>
+ </note>
<note>
<para>
- Prior to <productname>PostgreSQL</productname> 8.2, the
- <literal><</>, <literal><=</>, <literal>></> and <literal>>=</>
- cases were not handled per SQL specification. A comparison like
- <literal>ROW(a,b) < ROW(c,d)</>
- was implemented as
- <literal>a < c AND b < d</>
- whereas the correct behavior is equivalent to
- <literal>a < c OR (a = c AND b < d)</>.
+ Users accustomed to working with other SQL database management
+ systems might be surprised by the performance of the
+ <function>count</function> aggregate when it is applied to the
+ entire table. A query like:
+<programlisting>
+SELECT count(*) FROM sometable;
+</programlisting>
+ will be executed by <productname>PostgreSQL</productname> using a
+ sequential scan of the entire table.
</para>
</note>
-<synopsis>
-<replaceable>row_constructor</replaceable> IS DISTINCT FROM <replaceable>row_constructor</replaceable>
-</synopsis>
<para>
- This construct is similar to a <literal><></literal> row comparison,
- but it does not yield null for null inputs. Instead, any null value is
- considered unequal to (distinct from) any non-null value, and any two
- nulls are considered equal (not distinct). Thus the result will always
- be either true or false, never null.
+ <xref linkend="functions-aggregate-statistics-table"> shows
+ aggregate functions typically used in statistical analysis.
+ (These are separated out merely to avoid cluttering the listing
+ of more-commonly-used aggregates.) Where the description mentions
+ <replaceable class="parameter">N</replaceable>, it means the
+ number of input rows for which all the input expressions are non-null.
+ In all cases, null is returned if the computation is meaningless,
+ for example when <replaceable class="parameter">N</replaceable> is zero.
</para>
-<synopsis>
-<replaceable>row_constructor</replaceable> IS NOT DISTINCT FROM <replaceable>row_constructor</replaceable>
-</synopsis>
+ <indexterm>
+ <primary>statistics</primary>
+ </indexterm>
+ <indexterm>
+ <primary>linear regression</primary>
+ </indexterm>
- <para>
- This construct is similar to a <literal>=</literal> row comparison,
- but it does not yield null for null inputs. Instead, any null value is
- considered unequal to (distinct from) any non-null value, and any two
- nulls are considered equal (not distinct). Thus the result will always
- be either true or false, never null.
- </para>
+ <table id="functions-aggregate-statistics-table">
+ <title>Aggregate Functions for Statistics</title>
+
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Function</entry>
+ <entry>Argument Type</entry>
+ <entry>Return Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+
+ <row>
+ <entry>
+ <indexterm>
+ <primary>correlation</primary>
+ </indexterm>
+ <function>corr(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>correlation coefficient</entry>
+ </row>
+
+ <row>
+ <entry>
+ <indexterm>
+ <primary>covariance</primary>
+ <secondary>population</secondary>
+ </indexterm>
+ <function>covar_pop(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>population covariance</entry>
+ </row>
+
+ <row>
+ <entry>
+ <indexterm>
+ <primary>covariance</primary>
+ <secondary>sample</secondary>
+ </indexterm>
+ <function>covar_samp(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>sample covariance</entry>
+ </row>
+
+ <row>
+ <entry>
+ <function>regr_avgx(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>average of the independent variable
+ (<literal>sum(<replaceable class="parameter">X</replaceable>)/<replaceable class="parameter">N</replaceable></literal>)</entry>
+ </row>
+
+ <row>
+ <entry>
+ <function>regr_avgy(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>average of the dependent variable
+ (<literal>sum(<replaceable class="parameter">Y</replaceable>)/<replaceable class="parameter">N</replaceable></literal>)</entry>
+ </row>
+
+ <row>
+ <entry>
+ <function>regr_count(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>
+ <type>bigint</type>
+ </entry>
+ <entry>number of input rows in which both expressions are nonnull</entry>
+ </row>
+
+ <row>
+ <entry>
+ <indexterm>
+ <primary>regression intercept</primary>
+ </indexterm>
+ <function>regr_intercept(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>y-intercept of the least-squares-fit linear equation
+ determined by the (<replaceable
+ class="parameter">X</replaceable>, <replaceable
+ class="parameter">Y</replaceable>) pairs</entry>
+ </row>
+
+ <row>
+ <entry>
+ <function>regr_r2(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>square of the correlation coefficient</entry>
+ </row>
+
+ <row>
+ <entry>
+ <indexterm>
+ <primary>regression slope</primary>
+ </indexterm>
+ <function>regr_slope(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>slope of the least-squares-fit linear equation determined
+ by the (<replaceable class="parameter">X</replaceable>,
+ <replaceable class="parameter">Y</replaceable>) pairs</entry>
+ </row>
- </sect2>
- </sect1>
+ <row>
+ <entry>
+ <function>regr_sxx(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry><literal>sum(<replaceable
+ class="parameter">X</replaceable>^2) - sum(<replaceable
+ class="parameter">X</replaceable>)^2/<replaceable
+ class="parameter">N</replaceable></literal> (<quote>sum of
+ squares</quote> of the independent variable)</entry>
+ </row>
- <sect1 id="functions-srf">
- <title>Set Returning Functions</title>
+ <row>
+ <entry>
+ <function>regr_sxy(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry><literal>sum(<replaceable
+ class="parameter">X</replaceable>*<replaceable
+ class="parameter">Y</replaceable>) - sum(<replaceable
+ class="parameter">X</replaceable>) * sum(<replaceable
+ class="parameter">Y</replaceable>)/<replaceable
+ class="parameter">N</replaceable></literal> (<quote>sum of
+ products</quote> of independent times dependent
+ variable)</entry>
+ </row>
- <indexterm zone="functions-srf">
- <primary>set returning functions</primary>
- <secondary>functions</secondary>
- </indexterm>
+ <row>
+ <entry>
+ <function>regr_syy(<replaceable class="parameter">Y</replaceable>, <replaceable class="parameter">X</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry>
+ <type>double precision</type>
+ </entry>
+ <entry><literal>sum(<replaceable
+ class="parameter">Y</replaceable>^2) - sum(<replaceable
+ class="parameter">Y</replaceable>)^2/<replaceable
+ class="parameter">N</replaceable></literal> (<quote>sum of
+ squares</quote> of the dependent variable)</entry>
+ </row>
- <indexterm>
- <primary>generate_series</primary>
- </indexterm>
+ <row>
+ <entry>
+ <indexterm>
+ <primary>standard deviation</primary>
+ </indexterm>
+ <function>stddev(<replaceable class="parameter">expression</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>smallint</type>, <type>int</type>,
+ <type>bigint</type>, <type>real</type>, <type>double
+ precision</type>, or <type>numeric</type>
+ </entry>
+ <entry>
+ <type>double precision</type> for floating-point arguments,
+ otherwise <type>numeric</type>
+ </entry>
+ <entry>historical alias for <function>stddev_samp</function></entry>
+ </row>
- <para>
- This section describes functions that possibly return more than one row.
- Currently the only functions in this class are series generating functions,
- as detailed in <xref linkend="functions-srf-series">.
- </para>
+ <row>
+ <entry>
+ <indexterm>
+ <primary>standard deviation</primary>
+ <secondary>population</secondary>
+ </indexterm>
+ <function>stddev_pop(<replaceable class="parameter">expression</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>smallint</type>, <type>int</type>,
+ <type>bigint</type>, <type>real</type>, <type>double
+ precision</type>, or <type>numeric</type>
+ </entry>
+ <entry>
+ <type>double precision</type> for floating-point arguments,
+ otherwise <type>numeric</type>
+ </entry>
+ <entry>population standard deviation of the input values</entry>
+ </row>
- <table id="functions-srf-series">
- <title>Series Generating Functions</title>
- <tgroup cols="4">
- <thead>
<row>
- <entry>Function</entry>
- <entry>Argument Type</entry>
- <entry>Return Type</entry>
- <entry>Description</entry>
+ <entry>
+ <indexterm>
+ <primary>standard deviation</primary>
+ <secondary>sample</secondary>
+ </indexterm>
+ <function>stddev_samp(<replaceable class="parameter">expression</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>smallint</type>, <type>int</type>,
+ <type>bigint</type>, <type>real</type>, <type>double
+ precision</type>, or <type>numeric</type>
+ </entry>
+ <entry>
+ <type>double precision</type> for floating-point arguments,
+ otherwise <type>numeric</type>
+ </entry>
+ <entry>sample standard deviation of the input values</entry>
</row>
- </thead>
- <tbody>
<row>
- <entry><literal><function>generate_series</function>(<parameter>start</parameter>, <parameter>stop</parameter>)</literal></entry>
- <entry><type>int</type> or <type>bigint</type></entry>
- <entry><type>setof int</type> or <type>setof bigint</type> (same as argument type)</entry>
<entry>
- Generate a series of values, from <parameter>start</parameter> to <parameter>stop</parameter>
- with a step size of one
+ <indexterm>
+ <primary>variance</primary>
+ </indexterm>
+ <function>variance</function>(<replaceable class="parameter">expression</replaceable>)
</entry>
+ <entry>
+ <type>smallint</type>, <type>int</type>,
+ <type>bigint</type>, <type>real</type>, <type>double
+ precision</type>, or <type>numeric</type>
+ </entry>
+ <entry>
+ <type>double precision</type> for floating-point arguments,
+ otherwise <type>numeric</type>
+ </entry>
+ <entry>historical alias for <function>var_samp</function></entry>
</row>
<row>
- <entry><literal><function>generate_series</function>(<parameter>start</parameter>, <parameter>stop</parameter>, <parameter>step</parameter>)</literal></entry>
- <entry><type>int</type> or <type>bigint</type></entry>
- <entry><type>setof int</type> or <type>setof bigint</type> (same as argument type)</entry>
<entry>
- Generate a series of values, from <parameter>start</parameter> to <parameter>stop</parameter>
- with a step size of <parameter>step</parameter>
+ <indexterm>
+ <primary>variance</primary>
+ <secondary>population</secondary>
+ </indexterm>
+ <function>var_pop</function>(<replaceable class="parameter">expression</replaceable>)
+ </entry>
+ <entry>
+ <type>smallint</type>, <type>int</type>,
+ <type>bigint</type>, <type>real</type>, <type>double
+ precision</type>, or <type>numeric</type>
+ </entry>
+ <entry>
+ <type>double precision</type> for floating-point arguments,
+ otherwise <type>numeric</type>
</entry>
+ <entry>population variance of the input values (square of the population standard deviation)</entry>
</row>
+ <row>
+ <entry>
+ <indexterm>
+ <primary>variance</primary>
+ <secondary>sample</secondary>
+ </indexterm>
+ <function>var_samp</function>(<replaceable class="parameter">expression</replaceable>)
+ </entry>
+ <entry>
+ <type>smallint</type>, <type>int</type>,
+ <type>bigint</type>, <type>real</type>, <type>double
+ precision</type>, or <type>numeric</type>
+ </entry>
+ <entry>
+ <type>double precision</type> for floating-point arguments,
+ otherwise <type>numeric</type>
+ </entry>
+ <entry>sample variance of the input values (square of the sample standard deviation)</entry>
+ </row>
</tbody>
</tgroup>
- </table>
-
- <para>
- When <parameter>step</parameter> is positive, zero rows are returned if
- <parameter>start</parameter> is greater than <parameter>stop</parameter>.
- Conversely, when <parameter>step</parameter> is negative, zero rows are
- returned if <parameter>start</parameter> is less than <parameter>stop</parameter>.
- Zero rows are also returned for <literal>NULL</literal> inputs. It is an error
- for <parameter>step</parameter> to be zero. Some examples follow:
-<programlisting>
-select * from generate_series(2,4);
- generate_series
------------------
- 2
- 3
- 4
-(3 rows)
-
-select * from generate_series(5,1,-2);
- generate_series
------------------
- 5
- 3
- 1
-(3 rows)
-
-select * from generate_series(4,3);
- generate_series
------------------
-(0 rows)
-
-select current_date + s.a as dates from generate_series(0,14,7) as s(a);
- dates
-------------
- 2004-02-05
- 2004-02-12
- 2004-02-19
-(3 rows)
-</programlisting>
- </para>
- </sect1>
-
- <sect1 id="functions-info">
- <title>System Information Functions</title>
-
- <para>
- <xref linkend="functions-info-session-table"> shows several
- functions that extract session and system information.
- </para>
-
- <table id="functions-info-session-table">
- <title>Session Information Functions</title>
- <tgroup cols="3">
- <thead>
- <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry></row>
- </thead>
-
- <tbody>
- <row>
- <entry><literal><function>current_database</function>()</literal></entry>
- <entry><type>name</type></entry>
- <entry>name of current database</entry>
- </row>
+ </table>
- <row>
- <entry><literal><function>current_schema</function>()</literal></entry>
- <entry><type>name</type></entry>
- <entry>name of current schema</entry>
- </row>
+ </sect1>
- <row>
- <entry><literal><function>current_schemas</function>(<type>boolean</type>)</literal></entry>
- <entry><type>name[]</type></entry>
- <entry>names of schemas in search path optionally including implicit schemas</entry>
- </row>
- <row>
- <entry><literal><function>current_user</function></literal></entry>
- <entry><type>name</type></entry>
- <entry>user name of current execution context</entry>
- </row>
+ <sect1 id="functions-subquery">
+ <title>Subquery Expressions</title>
- <row>
- <entry><literal><function>inet_client_addr</function>()</literal></entry>
- <entry><type>inet</type></entry>
- <entry>address of the remote connection</entry>
- </row>
+ <indexterm>
+ <primary>EXISTS</primary>
+ </indexterm>
- <row>
- <entry><literal><function>inet_client_port</function>()</literal></entry>
- <entry><type>int</type></entry>
- <entry>port of the remote connection</entry>
- </row>
+ <indexterm>
+ <primary>IN</primary>
+ </indexterm>
- <row>
- <entry><literal><function>inet_server_addr</function>()</literal></entry>
- <entry><type>inet</type></entry>
- <entry>address of the local connection</entry>
- </row>
+ <indexterm>
+ <primary>NOT IN</primary>
+ </indexterm>
- <row>
- <entry><literal><function>inet_server_port</function>()</literal></entry>
- <entry><type>int</type></entry>
- <entry>port of the local connection</entry>
- </row>
+ <indexterm>
+ <primary>ANY</primary>
+ </indexterm>
- <row>
- <entry><literal><function>pg_my_temp_schema</function>()</literal></entry>
- <entry><type>oid</type></entry>
- <entry>OID of session's temporary schema, or 0 if none</entry>
- </row>
+ <indexterm>
+ <primary>ALL</primary>
+ </indexterm>
- <row>
- <entry><literal><function>pg_is_other_temp_schema</function>(<type>oid</type>)</literal></entry>
- <entry><type>boolean</type></entry>
- <entry>is schema another session's temporary schema?</entry>
- </row>
+ <indexterm>
+ <primary>SOME</primary>
+ </indexterm>
- <row>
- <entry><literal><function>pg_postmaster_start_time</function>()</literal></entry>
- <entry><type>timestamp with time zone</type></entry>
- <entry>server start time</entry>
- </row>
+ <indexterm>
+ <primary>subquery</primary>
+ </indexterm>
- <row>
- <entry><literal><function>session_user</function></literal></entry>
- <entry><type>name</type></entry>
- <entry>session user name</entry>
- </row>
+ <para>
+ This section describes the <acronym>SQL</acronym>-compliant subquery
+ expressions available in <productname>PostgreSQL</productname>.
+ All of the expression forms documented in this section return
+ Boolean (true/false) results.
+ </para>
- <row>
- <entry><literal><function>user</function></literal></entry>
- <entry><type>name</type></entry>
- <entry>equivalent to <function>current_user</function></entry>
- </row>
+ <sect2>
+ <title><literal>EXISTS</literal></title>
- <row>
- <entry><literal><function>version</function>()</literal></entry>
- <entry><type>text</type></entry>
- <entry><productname>PostgreSQL</> version information</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
+<synopsis>
+EXISTS (<replaceable>subquery</replaceable>)
+</synopsis>
- <indexterm zone="functions-info">
- <primary>user</primary>
- <secondary>current</secondary>
- </indexterm>
+ <para>
+ The argument of <token>EXISTS</token> is an arbitrary <command>SELECT</> statement,
+ or <firstterm>subquery</firstterm>. The
+ subquery is evaluated to determine whether it returns any rows.
+ If it returns at least one row, the result of <token>EXISTS</token> is
+ <quote>true</>; if the subquery returns no rows, the result of <token>EXISTS</token>
+ is <quote>false</>.
+ </para>
- <indexterm zone="functions-info">
- <primary>schema</primary>
- <secondary>current</secondary>
- </indexterm>
+ <para>
+ The subquery can refer to variables from the surrounding query,
+ which will act as constants during any one evaluation of the subquery.
+ </para>
- <indexterm zone="functions-info">
- <primary>search path</primary>
- <secondary>current</secondary>
- </indexterm>
+ <para>
+ The subquery will generally only be executed far enough to determine
+ whether at least one row is returned, not all the way to completion.
+ It is unwise to write a subquery that has any side effects (such as
+ calling sequence functions); whether the side effects occur or not
+ might be difficult to predict.
+ </para>
- <para>
- The <function>session_user</function> is normally the user who initiated
- the current database connection; but superusers can change this setting
- with <xref linkend="sql-set-session-authorization" endterm="sql-set-session-authorization-title">.
- The <function>current_user</function> is the user identifier
- that is applicable for permission checking. Normally, it is equal
- to the session user, but it can be changed with
- <xref linkend="sql-set-role" endterm="sql-set-role-title">.
- It also changes during the execution of
- functions with the attribute <literal>SECURITY DEFINER</literal>.
- In Unix parlance, the session user is the <quote>real user</quote> and
- the current user is the <quote>effective user</quote>.
- </para>
+ <para>
+ Since the result depends only on whether any rows are returned,
+ and not on the contents of those rows, the output list of the
+ subquery is normally uninteresting. A common coding convention is
+ to write all <literal>EXISTS</> tests in the form
+ <literal>EXISTS(SELECT 1 WHERE ...)</literal>. There are exceptions to
+ this rule however, such as subqueries that use <token>INTERSECT</token>.
+ </para>
- <note>
- <para>
- <function>current_user</function>, <function>session_user</function>, and
- <function>user</function> have special syntactic status in <acronym>SQL</acronym>:
- they must be called without trailing parentheses.
- </para>
- </note>
+ <para>
+ This simple example is like an inner join on <literal>col2</>, but
+ it produces at most one output row for each <literal>tab1</> row,
+ even if there are multiple matching <literal>tab2</> rows:
+<screen>
+SELECT col1 FROM tab1
+ WHERE EXISTS(SELECT 1 FROM tab2 WHERE col2 = tab1.col2);
+</screen>
+ </para>
+ </sect2>
- <para>
- <function>current_schema</function> returns the name of the schema that is
- at the front of the search path (or a null value if the search path is
- empty). This is the schema that will be used for any tables or
- other named objects that are created without specifying a target schema.
- <function>current_schemas(boolean)</function> returns an array of the names of all
- schemas presently in the search path. The Boolean option determines whether or not
- implicitly included system schemas such as <literal>pg_catalog</> are included in the search
- path returned.
- </para>
+ <sect2>
+ <title><literal>IN</literal></title>
- <note>
- <para>
- The search path can be altered at run time. The command is:
-<programlisting>
-SET search_path TO <replaceable>schema</> <optional>, <replaceable>schema</>, ...</optional>
-</programlisting>
- </para>
- </note>
+<synopsis>
+<replaceable>expression</replaceable> IN (<replaceable>subquery</replaceable>)
+</synopsis>
- <indexterm zone="functions-info">
- <primary>inet_client_addr</primary>
- </indexterm>
+ <para>
+ The right-hand side is a parenthesized
+ subquery, which must return exactly one column. The left-hand expression
+ is evaluated and compared to each row of the subquery result.
+ The result of <token>IN</token> is <quote>true</> if any equal subquery row is found.
+ The result is <quote>false</> if no equal row is found (including the special
+ case where the subquery returns no rows).
+ </para>
- <indexterm zone="functions-info">
- <primary>inet_client_port</primary>
- </indexterm>
+ <para>
+ Note that if the left-hand expression yields null, or if there are
+ no equal right-hand values and at least one right-hand row yields
+ null, the result of the <token>IN</token> construct will be null, not false.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </para>
- <indexterm zone="functions-info">
- <primary>inet_server_addr</primary>
- </indexterm>
+ <para>
+ As with <token>EXISTS</token>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </para>
- <indexterm zone="functions-info">
- <primary>inet_server_port</primary>
- </indexterm>
+<synopsis>
+<replaceable>row_constructor</replaceable> IN (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The left-hand side of this form of <token>IN</token> is a row constructor,
+ as described in <xref linkend="sql-syntax-row-constructors">.
+ The right-hand side is a parenthesized
+ subquery, which must return exactly as many columns as there are
+ expressions in the left-hand row. The left-hand expressions are
+ evaluated and compared row-wise to each row of the subquery result.
+ The result of <token>IN</token> is <quote>true</> if any equal subquery row is found.
+ The result is <quote>false</> if no equal row is found (including the special
+ case where the subquery returns no rows).
+ </para>
+
+ <para>
+ As usual, null values in the rows are combined per
+ the normal rules of SQL Boolean expressions. Two rows are considered
+ equal if all their corresponding members are non-null and equal; the rows
+ are unequal if any corresponding members are non-null and unequal;
+ otherwise the result of that row comparison is unknown (null).
+ If all the per-row results are either unequal or null, with at least one
+ null, then the result of <token>IN</token> is null.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title><literal>NOT IN</literal></title>
- <para>
- <function>inet_client_addr</function> returns the IP address of the
- current client, and <function>inet_client_port</function> returns the
- port number.
- <function>inet_server_addr</function> returns the IP address on which
- the server accepted the current connection, and
- <function>inet_server_port</function> returns the port number.
- All these functions return NULL if the current connection is via a
- Unix-domain socket.
- </para>
+<synopsis>
+<replaceable>expression</replaceable> NOT IN (<replaceable>subquery</replaceable>)
+</synopsis>
- <indexterm zone="functions-info">
- <primary>pg_my_temp_schema</primary>
- </indexterm>
+ <para>
+ The right-hand side is a parenthesized
+ subquery, which must return exactly one column. The left-hand expression
+ is evaluated and compared to each row of the subquery result.
+ The result of <token>NOT IN</token> is <quote>true</> if only unequal subquery rows
+ are found (including the special case where the subquery returns no rows).
+ The result is <quote>false</> if any equal row is found.
+ </para>
- <indexterm zone="functions-info">
- <primary>pg_is_other_temp_schema</primary>
- </indexterm>
+ <para>
+ Note that if the left-hand expression yields null, or if there are
+ no equal right-hand values and at least one right-hand row yields
+ null, the result of the <token>NOT IN</token> construct will be null, not true.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </para>
- <para>
- <function>pg_my_temp_schema</function> returns the OID of the current
- session's temporary schema, or 0 if it has none (because it has not
- created any temporary tables).
- <function>pg_is_other_temp_schema</function> returns true if the
- given OID is the OID of any other session's temporary schema.
- (This can be useful, for example, to exclude other sessions' temporary
- tables from a catalog display.)
- </para>
+ <para>
+ As with <token>EXISTS</token>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </para>
- <indexterm zone="functions-info">
- <primary>pg_postmaster_start_time</primary>
- </indexterm>
+<synopsis>
+<replaceable>row_constructor</replaceable> NOT IN (<replaceable>subquery</replaceable>)
+</synopsis>
- <para>
- <function>pg_postmaster_start_time</function> returns the
- <type>timestamp with time zone</type> when the
- server started.
- </para>
+ <para>
+ The left-hand side of this form of <token>NOT IN</token> is a row constructor,
+ as described in <xref linkend="sql-syntax-row-constructors">.
+ The right-hand side is a parenthesized
+ subquery, which must return exactly as many columns as there are
+ expressions in the left-hand row. The left-hand expressions are
+ evaluated and compared row-wise to each row of the subquery result.
+ The result of <token>NOT IN</token> is <quote>true</> if only unequal subquery rows
+ are found (including the special case where the subquery returns no rows).
+ The result is <quote>false</> if any equal row is found.
+ </para>
- <indexterm zone="functions-info">
- <primary>version</primary>
- </indexterm>
+ <para>
+ As usual, null values in the rows are combined per
+ the normal rules of SQL Boolean expressions. Two rows are considered
+ equal if all their corresponding members are non-null and equal; the rows
+ are unequal if any corresponding members are non-null and unequal;
+ otherwise the result of that row comparison is unknown (null).
+ If all the per-row results are either unequal or null, with at least one
+ null, then the result of <token>NOT IN</token> is null.
+ </para>
+ </sect2>
- <para>
- <function>version</function> returns a string describing the
- <productname>PostgreSQL</productname> server's version.
- </para>
+ <sect2>
+ <title><literal>ANY</literal>/<literal>SOME</literal></title>
- <indexterm>
- <primary>privilege</primary>
- <secondary>querying</secondary>
- </indexterm>
+<synopsis>
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> ANY (<replaceable>subquery</replaceable>)
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> SOME (<replaceable>subquery</replaceable>)
+</synopsis>
<para>
- <xref linkend="functions-info-access-table"> lists functions that
- allow the user to query object access privileges programmatically.
- See <xref linkend="ddl-priv"> for more information about
- privileges.
+ The right-hand side is a parenthesized
+ subquery, which must return exactly one column. The left-hand expression
+ is evaluated and compared to each row of the subquery result using the
+ given <replaceable>operator</replaceable>, which must yield a Boolean
+ result.
+ The result of <token>ANY</token> is <quote>true</> if any true result is obtained.
+ The result is <quote>false</> if no true result is found (including the special
+ case where the subquery returns no rows).
</para>
- <table id="functions-info-access-table">
- <title>Access Privilege Inquiry Functions</title>
- <tgroup cols="3">
- <thead>
- <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry></row>
- </thead>
+ <para>
+ <token>SOME</token> is a synonym for <token>ANY</token>.
+ <token>IN</token> is equivalent to <literal>= ANY</literal>.
+ </para>
- <tbody>
- <row>
- <entry><literal><function>has_database_privilege</function>(<parameter>user</parameter>,
- <parameter>database</parameter>,
- <parameter>privilege</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>does user have privilege for database</entry>
- </row>
- <row>
- <entry><literal><function>has_database_privilege</function>(<parameter>database</parameter>,
- <parameter>privilege</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>does current user have privilege for database</entry>
- </row>
- <row>
- <entry><literal><function>has_function_privilege</function>(<parameter>user</parameter>,
- <parameter>function</parameter>,
- <parameter>privilege</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>does user have privilege for function</entry>
- </row>
- <row>
- <entry><literal><function>has_function_privilege</function>(<parameter>function</parameter>,
- <parameter>privilege</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>does current user have privilege for function</entry>
- </row>
- <row>
- <entry><literal><function>has_language_privilege</function>(<parameter>user</parameter>,
- <parameter>language</parameter>,
- <parameter>privilege</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>does user have privilege for language</entry>
- </row>
- <row>
- <entry><literal><function>has_language_privilege</function>(<parameter>language</parameter>,
- <parameter>privilege</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>does current user have privilege for language</entry>
- </row>
- <row>
- <entry><literal><function>has_schema_privilege</function>(<parameter>user</parameter>,
- <parameter>schema</parameter>,
- <parameter>privilege</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>does user have privilege for schema</entry>
- </row>
- <row>
- <entry><literal><function>has_schema_privilege</function>(<parameter>schema</parameter>,
- <parameter>privilege</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>does current user have privilege for schema</entry>
- </row>
- <row>
- <entry><literal><function>has_table_privilege</function>(<parameter>user</parameter>,
- <parameter>table</parameter>,
- <parameter>privilege</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>does user have privilege for table</entry>
- </row>
- <row>
- <entry><literal><function>has_table_privilege</function>(<parameter>table</parameter>,
- <parameter>privilege</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>does current user have privilege for table</entry>
- </row>
- <row>
- <entry><literal><function>has_tablespace_privilege</function>(<parameter>user</parameter>,
- <parameter>tablespace</parameter>,
- <parameter>privilege</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>does user have privilege for tablespace</entry>
- </row>
- <row>
- <entry><literal><function>has_tablespace_privilege</function>(<parameter>tablespace</parameter>,
- <parameter>privilege</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>does current user have privilege for tablespace</entry>
- </row>
- <row>
- <entry><literal><function>pg_has_role</function>(<parameter>user</parameter>,
- <parameter>role</parameter>,
- <parameter>privilege</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>does user have privilege for role</entry>
- </row>
- <row>
- <entry><literal><function>pg_has_role</function>(<parameter>role</parameter>,
- <parameter>privilege</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>does current user have privilege for role</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
+ <para>
+ Note that if there are no successes and at least one right-hand row yields
+ null for the operator's result, the result of the <token>ANY</token> construct
+ will be null, not false.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </para>
- <indexterm zone="functions-info">
- <primary>has_database_privilege</primary>
- </indexterm>
- <indexterm zone="functions-info">
- <primary>has_function_privilege</primary>
- </indexterm>
- <indexterm zone="functions-info">
- <primary>has_language_privilege</primary>
- </indexterm>
- <indexterm zone="functions-info">
- <primary>has_schema_privilege</primary>
- </indexterm>
- <indexterm zone="functions-info">
- <primary>has_table_privilege</primary>
- </indexterm>
- <indexterm zone="functions-info">
- <primary>has_tablespace_privilege</primary>
- </indexterm>
- <indexterm zone="functions-info">
- <primary>pg_has_role</primary>
- </indexterm>
+ <para>
+ As with <token>EXISTS</token>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </para>
- <para>
- <function>has_database_privilege</function> checks whether a user
- can access a database in a particular way. The possibilities for its
- arguments are analogous to <function>has_table_privilege</function>.
- The desired access privilege type must evaluate to
- <literal>CREATE</literal>,
- <literal>CONNECT</literal>,
- <literal>TEMPORARY</literal>, or
- <literal>TEMP</literal> (which is equivalent to
- <literal>TEMPORARY</literal>).
- </para>
+<synopsis>
+<replaceable>row_constructor</replaceable> <replaceable>operator</> ANY (<replaceable>subquery</replaceable>)
+<replaceable>row_constructor</replaceable> <replaceable>operator</> SOME (<replaceable>subquery</replaceable>)
+</synopsis>
- <para>
- <function>has_function_privilege</function> checks whether a user
- can access a function in a particular way. The possibilities for its
- arguments are analogous to <function>has_table_privilege</function>.
- When specifying a function by a text string rather than by OID,
- the allowed input is the same as for the <type>regprocedure</> data type
- (see <xref linkend="datatype-oid">).
- The desired access privilege type must evaluate to
- <literal>EXECUTE</literal>.
- An example is:
-<programlisting>
-SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
-</programlisting>
- </para>
+ <para>
+ The left-hand side of this form of <token>ANY</token> is a row constructor,
+ as described in <xref linkend="sql-syntax-row-constructors">.
+ The right-hand side is a parenthesized
+ subquery, which must return exactly as many columns as there are
+ expressions in the left-hand row. The left-hand expressions are
+ evaluated and compared row-wise to each row of the subquery result,
+ using the given <replaceable>operator</replaceable>.
+ The result of <token>ANY</token> is <quote>true</> if the comparison
+ returns true for any subquery row.
+ The result is <quote>false</> if the comparison returns false for every
+ subquery row (including the special case where the subquery returns no
+ rows).
+ The result is NULL if the comparison does not return true for any row,
+ and it returns NULL for at least one row.
+ </para>
- <para>
- <function>has_language_privilege</function> checks whether a user
- can access a procedural language in a particular way. The possibilities
- for its arguments are analogous to <function>has_table_privilege</function>.
- The desired access privilege type must evaluate to
- <literal>USAGE</literal>.
- </para>
+ <para>
+ See <xref linkend="row-wise-comparison"> for details about the meaning
+ of a row-wise comparison.
+ </para>
+ </sect2>
- <para>
- <function>has_schema_privilege</function> checks whether a user
- can access a schema in a particular way. The possibilities for its
- arguments are analogous to <function>has_table_privilege</function>.
- The desired access privilege type must evaluate to
- <literal>CREATE</literal> or
- <literal>USAGE</literal>.
- </para>
+ <sect2>
+ <title><literal>ALL</literal></title>
- <para>
- <function>has_table_privilege</function> checks whether a user
- can access a table in a particular way. The user can be
- specified by name or by OID
- (<literal>pg_authid.oid</literal>), or if the argument is
- omitted
- <function>current_user</function> is assumed. The table can be specified
- by name or by OID. (Thus, there are actually six variants of
- <function>has_table_privilege</function>, which can be distinguished by
- the number and types of their arguments.) When specifying by name,
- the name can be schema-qualified if necessary.
- The desired access privilege type
- is specified by a text string, which must evaluate to one of the
- values <literal>SELECT</literal>, <literal>INSERT</literal>,
- <literal>UPDATE</literal>, <literal>DELETE</literal>,
- <literal>REFERENCES</literal>, or <literal>TRIGGER</literal>.
- (Case of the string is not significant, however.)
- An example is:
-<programlisting>
-SELECT has_table_privilege('myschema.mytable', 'select');
-</programlisting>
- </para>
+<synopsis>
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> ALL (<replaceable>subquery</replaceable>)
+</synopsis>
- <para>
- <function>has_tablespace_privilege</function> checks whether a user
- can access a tablespace in a particular way. The possibilities for its
- arguments are analogous to <function>has_table_privilege</function>.
- The desired access privilege type must evaluate to
- <literal>CREATE</literal>.
- </para>
+ <para>
+ The right-hand side is a parenthesized
+ subquery, which must return exactly one column. The left-hand expression
+ is evaluated and compared to each row of the subquery result using the
+ given <replaceable>operator</replaceable>, which must yield a Boolean
+ result.
+ The result of <token>ALL</token> is <quote>true</> if all rows yield true
+ (including the special case where the subquery returns no rows).
+ The result is <quote>false</> if any false result is found.
+ The result is NULL if the comparison does not return false for any row,
+ and it returns NULL for at least one row.
+ </para>
- <para>
- <function>pg_has_role</function> checks whether a user
- can access a role in a particular way. The possibilities for its
- arguments are analogous to <function>has_table_privilege</function>.
- The desired access privilege type must evaluate to
- <literal>MEMBER</literal> or
- <literal>USAGE</literal>.
- <literal>MEMBER</literal> denotes direct or indirect membership in
- the role (that is, the right to do <command>SET ROLE</>), while
- <literal>USAGE</literal> denotes whether the privileges of the role
- are immediately available without doing <command>SET ROLE</>.
- </para>
+ <para>
+ <token>NOT IN</token> is equivalent to <literal><> ALL</literal>.
+ </para>
<para>
- To test whether a user holds a grant option on the privilege,
- append <literal>WITH GRANT OPTION</literal> to the privilege key
- word; for example <literal>'UPDATE WITH GRANT OPTION'</literal>.
+ As with <token>EXISTS</token>, it's unwise to assume that the subquery will
+ be evaluated completely.
</para>
+<synopsis>
+<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> ALL (<replaceable>subquery</replaceable>)
+</synopsis>
+
<para>
- <xref linkend="functions-info-schema-table"> shows functions that
- determine whether a certain object is <firstterm>visible</> in the
- current schema search path. A table is said to be visible if its
- containing schema is in the search path and no table of the same
- name appears earlier in the search path. This is equivalent to the
- statement that the table can be referenced by name without explicit
- schema qualification. For example, to list the names of all
- visible tables:
-<programlisting>
-SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
-</programlisting>
+ The left-hand side of this form of <token>ALL</token> is a row constructor,
+ as described in <xref linkend="sql-syntax-row-constructors">.
+ The right-hand side is a parenthesized
+ subquery, which must return exactly as many columns as there are
+ expressions in the left-hand row. The left-hand expressions are
+ evaluated and compared row-wise to each row of the subquery result,
+ using the given <replaceable>operator</replaceable>.
+ The result of <token>ALL</token> is <quote>true</> if the comparison
+ returns true for all subquery rows (including the special
+ case where the subquery returns no rows).
+ The result is <quote>false</> if the comparison returns false for any
+ subquery row.
+ The result is NULL if the comparison does not return false for any
+ subquery row, and it returns NULL for at least one row.
</para>
- <table id="functions-info-schema-table">
- <title>Schema Visibility Inquiry Functions</title>
- <tgroup cols="3">
- <thead>
- <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry></row>
- </thead>
+ <para>
+ See <xref linkend="row-wise-comparison"> for details about the meaning
+ of a row-wise comparison.
+ </para>
+ </sect2>
- <tbody>
- <row>
- <entry><literal><function>pg_conversion_is_visible</function>(<parameter>conversion_oid</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>is conversion visible in search path</entry>
- </row>
- <row>
- <entry><literal><function>pg_function_is_visible</function>(<parameter>function_oid</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>is function visible in search path</entry>
- </row>
- <row>
- <entry><literal><function>pg_operator_is_visible</function>(<parameter>operator_oid</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>is operator visible in search path</entry>
- </row>
- <row>
- <entry><literal><function>pg_opclass_is_visible</function>(<parameter>opclass_oid</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>is operator class visible in search path</entry>
- </row>
- <row>
- <entry><literal><function>pg_table_is_visible</function>(<parameter>table_oid</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>is table visible in search path</entry>
- </row>
- <row>
- <entry><literal><function>pg_type_is_visible</function>(<parameter>type_oid</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>is type (or domain) visible in search path</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
+ <sect2>
+ <title>Row-wise Comparison</title>
- <indexterm zone="functions-info">
- <primary>pg_conversion_is_visible</primary>
- </indexterm>
- <indexterm zone="functions-info">
- <primary>pg_function_is_visible</primary>
- </indexterm>
- <indexterm zone="functions-info">
- <primary>pg_operator_is_visible</primary>
- </indexterm>
- <indexterm zone="functions-info">
- <primary>pg_opclass_is_visible</primary>
- </indexterm>
- <indexterm zone="functions-info">
- <primary>pg_table_is_visible</primary>
- </indexterm>
- <indexterm zone="functions-info">
- <primary>pg_type_is_visible</primary>
+ <indexterm zone="functions-subquery">
+ <primary>comparison</primary>
+ <secondary>subquery result row</secondary>
</indexterm>
- <para>
- <function>pg_conversion_is_visible</function>,
- <function>pg_function_is_visible</function>,
- <function>pg_operator_is_visible</function>,
- <function>pg_opclass_is_visible</function>,
- <function>pg_table_is_visible</function>, and
- <function>pg_type_is_visible</function> perform the visibility check for
- conversions, functions, operators, operator classes, tables, and
- types. Note that <function>pg_table_is_visible</function> can also be used
- with views, indexes and sequences; <function>pg_type_is_visible</function>
- can also be used with domains. For functions and operators, an object in
- the search path is visible if there is no object of the same name
- <emphasis>and argument data type(s)</> earlier in the path. For operator
- classes, both name and associated index access method are considered.
- </para>
+<synopsis>
+<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The left-hand side is a row constructor,
+ as described in <xref linkend="sql-syntax-row-constructors">.
+ The right-hand side is a parenthesized subquery, which must return exactly
+ as many columns as there are expressions in the left-hand row. Furthermore,
+ the subquery cannot return more than one row. (If it returns zero rows,
+ the result is taken to be null.) The left-hand side is evaluated and
+ compared row-wise to the single subquery result row.
+ </para>
+
+ <para>
+ See <xref linkend="row-wise-comparison"> for details about the meaning
+ of a row-wise comparison.
+ </para>
+ </sect2>
+ </sect1>
+
- <para>
- All these functions require object OIDs to identify the object to be
- checked. If you want to test an object by name, it is convenient to use
- the OID alias types (<type>regclass</>, <type>regtype</>,
- <type>regprocedure</>, or <type>regoperator</>), for example:
-<programlisting>
-SELECT pg_type_is_visible('myschema.widget'::regtype);
-</programlisting>
- Note that it would not make much sense to test an unqualified name in
- this way — if the name can be recognized at all, it must be visible.
- </para>
+ <sect1 id="functions-comparisons">
+ <title>Row and Array Comparisons</title>
- <indexterm zone="functions-info">
- <primary>format_type</primary>
- </indexterm>
+ <indexterm>
+ <primary>IN</primary>
+ </indexterm>
- <indexterm zone="functions-info">
- <primary>pg_get_viewdef</primary>
- </indexterm>
+ <indexterm>
+ <primary>NOT IN</primary>
+ </indexterm>
- <indexterm zone="functions-info">
- <primary>pg_get_ruledef</primary>
- </indexterm>
+ <indexterm>
+ <primary>ANY</primary>
+ </indexterm>
- <indexterm zone="functions-info">
- <primary>pg_get_indexdef</primary>
- </indexterm>
+ <indexterm>
+ <primary>ALL</primary>
+ </indexterm>
- <indexterm zone="functions-info">
- <primary>pg_get_triggerdef</primary>
- </indexterm>
+ <indexterm>
+ <primary>SOME</primary>
+ </indexterm>
- <indexterm zone="functions-info">
- <primary>pg_get_constraintdef</primary>
- </indexterm>
+ <indexterm>
+ <primary>row-wise comparison</primary>
+ </indexterm>
- <indexterm zone="functions-info">
- <primary>pg_get_expr</primary>
- </indexterm>
+ <indexterm>
+ <primary>comparison</primary>
+ <secondary>row-wise</secondary>
+ </indexterm>
- <indexterm zone="functions-info">
- <primary>pg_get_userbyid</primary>
- </indexterm>
+ <indexterm>
+ <primary>IS DISTINCT FROM</primary>
+ </indexterm>
- <indexterm zone="functions-info">
- <primary>pg_get_serial_sequence</primary>
- </indexterm>
+ <indexterm>
+ <primary>IS NOT DISTINCT FROM</primary>
+ </indexterm>
- <indexterm zone="functions-info">
- <primary>pg_tablespace_databases</primary>
- </indexterm>
+ <para>
+ This section describes several specialized constructs for making
+ multiple comparisons between groups of values. These forms are
+ syntactically related to the subquery forms of the previous section,
+ but do not involve subqueries.
+ The forms involving array subexpressions are
+ <productname>PostgreSQL</productname> extensions; the rest are
+ <acronym>SQL</acronym>-compliant.
+ All of the expression forms documented in this section return
+ Boolean (true/false) results.
+ </para>
+
+ <sect2>
+ <title><literal>IN</literal></title>
+
+<synopsis>
+<replaceable>expression</replaceable> IN (<replaceable>value</replaceable> <optional>, ...</optional>)
+</synopsis>
<para>
- <xref linkend="functions-info-catalog-table"> lists functions that
- extract information from the system catalogs.
+ The right-hand side is a parenthesized list
+ of scalar expressions. The result is <quote>true</> if the left-hand expression's
+ result is equal to any of the right-hand expressions. This is a shorthand
+ notation for
+
+<synopsis>
+<replaceable>expression</replaceable> = <replaceable>value1</replaceable>
+OR
+<replaceable>expression</replaceable> = <replaceable>value2</replaceable>
+OR
+...
+</synopsis>
</para>
- <table id="functions-info-catalog-table">
- <title>System Catalog Information Functions</title>
- <tgroup cols="3">
- <thead>
- <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry></row>
- </thead>
+ <para>
+ Note that if the left-hand expression yields null, or if there are
+ no equal right-hand values and at least one right-hand expression yields
+ null, the result of the <token>IN</token> construct will be null, not false.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </para>
+ </sect2>
- <tbody>
- <row>
- <entry><literal><function>format_type</function>(<parameter>type_oid</parameter>, <parameter>typemod</>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>get SQL name of a data type</entry>
- </row>
- <row>
- <entry><literal><function>pg_get_constraintdef</function>(<parameter>constraint_oid</parameter>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>get definition of a constraint</entry>
- </row>
- <row>
- <entry><literal><function>pg_get_constraintdef</function>(<parameter>constraint_oid</parameter>, <parameter>pretty_bool</>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>get definition of a constraint</entry>
- </row>
- <row>
- <entry><literal><function>pg_get_expr</function>(<parameter>expr_text</parameter>, <parameter>relation_oid</>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>decompile internal form of an expression, assuming that any Vars
- in it refer to the relation indicated by the second parameter</entry>
- </row>
- <row>
- <entry><literal><function>pg_get_expr</function>(<parameter>expr_text</parameter>, <parameter>relation_oid</>, <parameter>pretty_bool</>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>decompile internal form of an expression, assuming that any Vars
- in it refer to the relation indicated by the second parameter</entry>
- </row>
- <row>
- <entry><literal><function>pg_get_indexdef</function>(<parameter>index_oid</parameter>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>get <command>CREATE INDEX</> command for index</entry>
- </row>
- <row>
- <entry><literal><function>pg_get_indexdef</function>(<parameter>index_oid</parameter>, <parameter>column_no</>, <parameter>pretty_bool</>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>get <command>CREATE INDEX</> command for index,
- or definition of just one index column when
- <parameter>column_no</> is not zero</entry>
- </row>
- <row>
- <entry><literal><function>pg_get_ruledef</function>(<parameter>rule_oid</parameter>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>get <command>CREATE RULE</> command for rule</entry>
- </row>
- <row>
- <entry><literal><function>pg_get_ruledef</function>(<parameter>rule_oid</parameter>, <parameter>pretty_bool</>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>get <command>CREATE RULE</> command for rule</entry>
- </row>
- <row>
- <entry><literal><function>pg_get_serial_sequence</function>(<parameter>table_name</parameter>, <parameter>column_name</parameter>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>get name of the sequence that a <type>serial</type> or <type>bigserial</type> column
- uses</entry>
- </row>
- <row>
- <entry><function>pg_get_triggerdef</function>(<parameter>trigger_oid</parameter>)</entry>
- <entry><type>text</type></entry>
- <entry>get <command>CREATE [ CONSTRAINT ] TRIGGER</> command for trigger</entry>
- </row>
- <row>
- <entry><literal><function>pg_get_userbyid</function>(<parameter>roleid</parameter>)</literal></entry>
- <entry><type>name</type></entry>
- <entry>get role name with given ID</entry>
- </row>
- <row>
- <entry><literal><function>pg_get_viewdef</function>(<parameter>view_name</parameter>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>get underlying <command>SELECT</command> command for view (<emphasis>deprecated</emphasis>)</entry>
- </row>
- <row>
- <entry><literal><function>pg_get_viewdef</function>(<parameter>view_name</parameter>, <parameter>pretty_bool</>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>get underlying <command>SELECT</command> command for view (<emphasis>deprecated</emphasis>)</entry>
- </row>
- <row>
- <entry><literal><function>pg_get_viewdef</function>(<parameter>view_oid</parameter>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>get underlying <command>SELECT</command> command for view</entry>
- </row>
- <row>
- <entry><literal><function>pg_get_viewdef</function>(<parameter>view_oid</parameter>, <parameter>pretty_bool</>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>get underlying <command>SELECT</command> command for view</entry>
- </row>
- <row>
- <entry><literal><function>pg_tablespace_databases</function>(<parameter>tablespace_oid</parameter>)</literal></entry>
- <entry><type>setof oid</type></entry>
- <entry>get the set of database OIDs that have objects in the tablespace</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
+ <sect2>
+ <title><literal>NOT IN</literal></title>
+
+<synopsis>
+<replaceable>expression</replaceable> NOT IN (<replaceable>value</replaceable> <optional>, ...</optional>)
+</synopsis>
+
+ <para>
+ The right-hand side is a parenthesized list
+ of scalar expressions. The result is <quote>true</quote> if the left-hand expression's
+ result is unequal to all of the right-hand expressions. This is a shorthand
+ notation for
+
+<synopsis>
+<replaceable>expression</replaceable> <> <replaceable>value1</replaceable>
+AND
+<replaceable>expression</replaceable> <> <replaceable>value2</replaceable>
+AND
+...
+</synopsis>
+ </para>
+
+ <para>
+ Note that if the left-hand expression yields null, or if there are
+ no equal right-hand values and at least one right-hand expression yields
+ null, the result of the <token>NOT IN</token> construct will be null, not true
+ as one might naively expect.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </para>
+ <tip>
<para>
- <function>format_type</function> returns the SQL name of a data type that
- is identified by its type OID and possibly a type modifier. Pass NULL
- for the type modifier if no specific modifier is known.
+ <literal>x NOT IN y</literal> is equivalent to <literal>NOT (x IN y)</literal> in all
+ cases. However, null values are much more likely to trip up the novice when
+ working with <token>NOT IN</token> than when working with <token>IN</token>.
+ It's best to express your condition positively if possible.
</para>
+ </tip>
+ </sect2>
+
+ <sect2>
+ <title><literal>ANY</literal>/<literal>SOME</literal> (array)</title>
+
+<synopsis>
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> ANY (<replaceable>array expression</replaceable>)
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> SOME (<replaceable>array expression</replaceable>)
+</synopsis>
<para>
- <function>pg_get_constraintdef</function>,
- <function>pg_get_indexdef</function>, <function>pg_get_ruledef</function>,
- and <function>pg_get_triggerdef</function>, respectively reconstruct the
- creating command for a constraint, index, rule, or trigger. (Note that this
- is a decompiled reconstruction, not the original text of the command.)
- <function>pg_get_expr</function> decompiles the internal form of an
- individual expression, such as the default value for a column. It can be
- useful when examining the contents of system catalogs.
- <function>pg_get_viewdef</function> reconstructs the <command>SELECT</>
- query that defines a view. Most of these functions come in two variants,
- one of which can optionally <quote>pretty-print</> the result. The
- pretty-printed format is more readable, but the default format is more
- likely to be interpreted the same way by future versions of
- <productname>PostgreSQL</>; avoid using pretty-printed output for dump
- purposes. Passing <literal>false</> for the pretty-print parameter yields
- the same result as the variant that does not have the parameter at all.
+ The right-hand side is a parenthesized expression, which must yield an
+ array value.
+ The left-hand expression
+ is evaluated and compared to each element of the array using the
+ given <replaceable>operator</replaceable>, which must yield a Boolean
+ result.
+ The result of <token>ANY</token> is <quote>true</> if any true result is obtained.
+ The result is <quote>false</> if no true result is found (including the special
+ case where the array has zero elements).
</para>
<para>
- <function>pg_get_serial_sequence</function> returns the name of the
- sequence associated with a column, or NULL if no sequence is associated
- with the column. The first input parameter is a table name with
- optional schema, and the second parameter is a column name. Because
- the first parameter is potentially a schema and table, it is not treated
- as a double-quoted identifier, meaning it is lowercased by default,
- while the second parameter, being just a column name, is treated as
- double-quoted and has its case preserved. The function returns a value
- suitably formatted for passing to the sequence functions (see <xref
- linkend="functions-sequence">). This association can be modified or
- removed with <command>ALTER SEQUENCE OWNED BY</>. (The function
- probably should have been called
- <function>pg_get_owned_sequence</function>; its name reflects the fact
- that it's typically used with <type>serial</> or <type>bigserial</>
- columns.)
+ If the array expression yields a null array, the result of
+ <token>ANY</token> will be null. If the left-hand expression yields null,
+ the result of <token>ANY</token> is ordinarily null (though a non-strict
+ comparison operator could possibly yield a different result).
+ Also, if the right-hand array contains any null elements and no true
+ comparison result is obtained, the result of <token>ANY</token>
+ will be null, not false (again, assuming a strict comparison operator).
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
</para>
<para>
- <function>pg_get_userbyid</function> extracts a role's name given
- its OID.
+ <token>SOME</token> is a synonym for <token>ANY</token>.
</para>
+ </sect2>
+
+ <sect2>
+ <title><literal>ALL</literal> (array)</title>
+
+<synopsis>
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> ALL (<replaceable>array expression</replaceable>)
+</synopsis>
<para>
- <function>pg_tablespace_databases</function> allows a tablespace to be
- examined. It returns the set of OIDs of databases that have objects stored
- in the tablespace. If this function returns any rows, the tablespace is not
- empty and cannot be dropped. To display the specific objects populating the
- tablespace, you will need to connect to the databases identified by
- <function>pg_tablespace_databases</function> and query their
- <structname>pg_class</> catalogs.
+ The right-hand side is a parenthesized expression, which must yield an
+ array value.
+ The left-hand expression
+ is evaluated and compared to each element of the array using the
+ given <replaceable>operator</replaceable>, which must yield a Boolean
+ result.
+ The result of <token>ALL</token> is <quote>true</> if all comparisons yield true
+ (including the special case where the array has zero elements).
+ The result is <quote>false</> if any false result is found.
</para>
- <indexterm zone="functions-info">
- <primary>col_description</primary>
- </indexterm>
+ <para>
+ If the array expression yields a null array, the result of
+ <token>ALL</token> will be null. If the left-hand expression yields null,
+ the result of <token>ALL</token> is ordinarily null (though a non-strict
+ comparison operator could possibly yield a different result).
+ Also, if the right-hand array contains any null elements and no false
+ comparison result is obtained, the result of <token>ALL</token>
+ will be null, not true (again, assuming a strict comparison operator).
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </para>
+ </sect2>
- <indexterm zone="functions-info">
- <primary>obj_description</primary>
- </indexterm>
+ <sect2 id="row-wise-comparison">
+ <title>Row-wise Comparison</title>
- <indexterm zone="functions-info">
- <primary>shobj_description</primary>
- </indexterm>
+<synopsis>
+<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> <replaceable>row_constructor</replaceable>
+</synopsis>
- <indexterm zone="functions-info">
- <primary>comment</primary>
- <secondary sortas="database objects">about database objects</secondary>
- </indexterm>
+ <para>
+ Each side is a row constructor,
+ as described in <xref linkend="sql-syntax-row-constructors">.
+ The two row values must have the same number of fields.
+ Each side is evaluated and they are compared row-wise. Row comparisons
+ are allowed when the <replaceable>operator</replaceable> is
+ <literal>=</>,
+ <literal><></>,
+ <literal><</>,
+ <literal><=</>,
+ <literal>></> or
+ <literal>>=</>,
+ or has semantics similar to one of these. (To be specific, an operator
+ can be a row comparison operator if it is a member of a B-Tree operator
+ class, or is the negator of the <literal>=</> member of a B-Tree operator
+ class.)
+ </para>
+
+ <para>
+ The <literal>=</> and <literal><></> cases work slightly differently
+ from the others. Two rows are considered
+ equal if all their corresponding members are non-null and equal; the rows
+ are unequal if any corresponding members are non-null and unequal;
+ otherwise the result of the row comparison is unknown (null).
+ </para>
+
+ <para>
+ For the <literal><</>, <literal><=</>, <literal>></> and
+ <literal>>=</> cases, the row elements are compared left-to-right,
+ stopping as soon as an unequal or null pair of elements is found.
+ If either of this pair of elements is null, the result of the
+ row comparison is unknown (null); otherwise comparison of this pair
+ of elements determines the result. For example,
+ <literal>ROW(1,2,NULL) < ROW(1,3,0)</>
+ yields true, not null, because the third pair of elements are not
+ considered.
+ </para>
+ <note>
<para>
- The functions shown in <xref linkend="functions-info-comment-table">
- extract comments previously stored with the <xref linkend="sql-comment"
- endterm="sql-comment-title"> command. A null value is returned if no
- comment could be found matching the specified parameters.
+ Prior to <productname>PostgreSQL</productname> 8.2, the
+ <literal><</>, <literal><=</>, <literal>></> and <literal>>=</>
+ cases were not handled per SQL specification. A comparison like
+ <literal>ROW(a,b) < ROW(c,d)</>
+ was implemented as
+ <literal>a < c AND b < d</>
+ whereas the correct behavior is equivalent to
+ <literal>a < c OR (a = c AND b < d)</>.
</para>
+ </note>
- <table id="functions-info-comment-table">
- <title>Comment Information Functions</title>
- <tgroup cols="3">
- <thead>
- <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry></row>
- </thead>
+<synopsis>
+<replaceable>row_constructor</replaceable> IS DISTINCT FROM <replaceable>row_constructor</replaceable>
+</synopsis>
- <tbody>
- <row>
- <entry><literal><function>col_description</function>(<parameter>table_oid</parameter>, <parameter>column_number</parameter>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>get comment for a table column</entry>
- </row>
- <row>
- <entry><literal><function>obj_description</function>(<parameter>object_oid</parameter>, <parameter>catalog_name</parameter>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>get comment for a database object</entry>
- </row>
- <row>
- <entry><literal><function>obj_description</function>(<parameter>object_oid</parameter>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>get comment for a database object (<emphasis>deprecated</emphasis>)</entry>
- </row>
- <row>
- <entry><literal><function>shobj_description</function>(<parameter>object_oid</parameter>, <parameter>catalog_name</parameter>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>get comment for a shared database object</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
+ <para>
+ This construct is similar to a <literal><></literal> row comparison,
+ but it does not yield null for null inputs. Instead, any null value is
+ considered unequal to (distinct from) any non-null value, and any two
+ nulls are considered equal (not distinct). Thus the result will always
+ be either true or false, never null.
+ </para>
- <para>
- <function>col_description</function> returns the comment for a table column,
- which is specified by the OID of its table and its column number.
- <function>obj_description</function> cannot be used for table columns since
- columns do not have OIDs of their own.
- </para>
+<synopsis>
+<replaceable>row_constructor</replaceable> IS NOT DISTINCT FROM <replaceable>row_constructor</replaceable>
+</synopsis>
- <para>
- The two-parameter form of <function>obj_description</function> returns the
- comment for a database object specified by its OID and the name of the
- containing system catalog. For example,
- <literal>obj_description(123456,'pg_class')</literal>
- would retrieve the comment for a table with OID 123456.
- The one-parameter form of <function>obj_description</function> requires only
- the object OID. It is now deprecated since there is no guarantee that
- OIDs are unique across different system catalogs; therefore, the wrong
- comment could be returned.
- </para>
+ <para>
+ This construct is similar to a <literal>=</literal> row comparison,
+ but it does not yield null for null inputs. Instead, any null value is
+ considered unequal to (distinct from) any non-null value, and any two
+ nulls are considered equal (not distinct). Thus the result will always
+ be either true or false, never null.
+ </para>
- <para>
- <function>shobj_description</function> is used just like
- <function>obj_description</function> only that it is used for retrieving
- comments on shared objects. Some system catalogs are global to all
- databases within each cluster and their descriptions are stored globally
- as well.
- </para>
- </sect1>
+ </sect2>
+ </sect1>
+
+ <sect1 id="functions-srf">
+ <title>Set Returning Functions</title>
- <sect1 id="functions-admin">
- <title>System Administration Functions</title>
+ <indexterm zone="functions-srf">
+ <primary>set returning functions</primary>
+ <secondary>functions</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>generate_series</primary>
+ </indexterm>
<para>
- <xref linkend="functions-admin-set-table"> shows the functions
- available to query and alter run-time configuration parameters.
+ This section describes functions that possibly return more than one row.
+ Currently the only functions in this class are series generating functions,
+ as detailed in <xref linkend="functions-srf-series">.
</para>
- <table id="functions-admin-set-table">
- <title>Configuration Settings Functions</title>
- <tgroup cols="3">
- <thead>
- <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry></row>
- </thead>
-
- <tbody>
- <row>
- <entry>
- <literal><function>current_setting</function>(<parameter>setting_name</parameter>)</literal>
- </entry>
- <entry><type>text</type></entry>
- <entry>current value of setting</entry>
- </row>
- <row>
- <entry>
- <literal><function>set_config(<parameter>setting_name</parameter>,
- <parameter>new_value</parameter>,
- <parameter>is_local</parameter>)</function></literal>
- </entry>
- <entry><type>text</type></entry>
- <entry>set parameter and return new value</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
+ <table id="functions-srf-series">
+ <title>Series Generating Functions</title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Function</entry>
+ <entry>Argument Type</entry>
+ <entry>Return Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
- <indexterm zone="functions-admin">
- <primary>SET</primary>
- </indexterm>
+ <tbody>
+ <row>
+ <entry><literal><function>generate_series</function>(<parameter>start</parameter>, <parameter>stop</parameter>)</literal></entry>
+ <entry><type>int</type> or <type>bigint</type></entry>
+ <entry><type>setof int</type> or <type>setof bigint</type> (same as argument type)</entry>
+ <entry>
+ Generate a series of values, from <parameter>start</parameter> to <parameter>stop</parameter>
+ with a step size of one
+ </entry>
+ </row>
- <indexterm zone="functions-admin">
- <primary>SHOW</primary>
- </indexterm>
+ <row>
+ <entry><literal><function>generate_series</function>(<parameter>start</parameter>, <parameter>stop</parameter>, <parameter>step</parameter>)</literal></entry>
+ <entry><type>int</type> or <type>bigint</type></entry>
+ <entry><type>setof int</type> or <type>setof bigint</type> (same as argument type)</entry>
+ <entry>
+ Generate a series of values, from <parameter>start</parameter> to <parameter>stop</parameter>
+ with a step size of <parameter>step</parameter>
+ </entry>
+ </row>
- <indexterm zone="functions-admin">
- <primary>configuration</primary>
- <secondary sortas="server">of the server</secondary>
- <tertiary>functions</tertiary>
- </indexterm>
+ </tbody>
+ </tgroup>
+ </table>
- <para>
- The function <function>current_setting</function> yields the
- current value of the setting <parameter>setting_name</parameter>.
- It corresponds to the <acronym>SQL</acronym> command
- <command>SHOW</command>. An example:
+ <para>
+ When <parameter>step</parameter> is positive, zero rows are returned if
+ <parameter>start</parameter> is greater than <parameter>stop</parameter>.
+ Conversely, when <parameter>step</parameter> is negative, zero rows are
+ returned if <parameter>start</parameter> is less than <parameter>stop</parameter>.
+ Zero rows are also returned for <literal>NULL</literal> inputs. It is an error
+ for <parameter>step</parameter> to be zero. Some examples follow:
<programlisting>
-SELECT current_setting('datestyle');
+select * from generate_series(2,4);
+ generate_series
+-----------------
+ 2
+ 3
+ 4
+(3 rows)
- current_setting
+select * from generate_series(5,1,-2);
+ generate_series
-----------------
- ISO, MDY
-(1 row)
-</programlisting>
- </para>
+ 5
+ 3
+ 1
+(3 rows)
- <para>
- <function>set_config</function> sets the parameter
- <parameter>setting_name</parameter> to
- <parameter>new_value</parameter>. If
- <parameter>is_local</parameter> is <literal>true</literal>, the
- new value will only apply to the current transaction. If you want
- the new value to apply for the current session, use
- <literal>false</literal> instead. The function corresponds to the
- SQL command <command>SET</command>. An example:
-<programlisting>
-SELECT set_config('log_statement_stats', 'off', false);
+select * from generate_series(4,3);
+ generate_series
+-----------------
+(0 rows)
- set_config
+select current_date + s.a as dates from generate_series(0,14,7) as s(a);
+ dates
------------
- off
-(1 row)
+ 2004-02-05
+ 2004-02-12
+ 2004-02-19
+(3 rows)
</programlisting>
- </para>
-
- <indexterm zone="functions-admin">
- <primary>pg_cancel_backend</primary>
- </indexterm>
- <indexterm zone="functions-admin">
- <primary>pg_reload_conf</primary>
- </indexterm>
- <indexterm zone="functions-admin">
- <primary>pg_rotate_logfile</primary>
- </indexterm>
+ </para>
+ </sect1>
- <indexterm zone="functions-admin">
- <primary>signal</primary>
- <secondary sortas="backend">backend processes</secondary>
- </indexterm>
+ <sect1 id="functions-info">
+ <title>System Information Functions</title>
- <para>
- The functions shown in <xref
- linkend="functions-admin-signal-table"> send control signals to
- other server processes. Use of these functions is restricted
- to superusers.
- </para>
+ <para>
+ <xref linkend="functions-info-session-table"> shows several
+ functions that extract session and system information.
+ </para>
- <table id="functions-admin-signal-table">
- <title>Server Signalling Functions</title>
+ <table id="functions-info-session-table">
+ <title>Session Information Functions</title>
<tgroup cols="3">
<thead>
- <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry>
- </row>
+ <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry></row>
</thead>
<tbody>
<row>
- <entry>
- <literal><function>pg_cancel_backend</function>(<parameter>pid</parameter> <type>int</>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>Cancel a backend's current query</entry>
- </row>
- <row>
- <entry>
- <literal><function>pg_reload_conf</function>()</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>Cause server processes to reload their configuration files</entry>
- </row>
- <row>
- <entry>
- <literal><function>pg_rotate_logfile</function>()</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>Rotate server's log file</entry>
+ <entry><literal><function>current_database</function>()</literal></entry>
+ <entry><type>name</type></entry>
+ <entry>name of current database</entry>
</row>
- </tbody>
- </tgroup>
- </table>
-
- <para>
- Each of these functions returns <literal>true</literal> if
- successful and <literal>false</literal> otherwise.
- </para>
-
- <para>
- <function>pg_cancel_backend</> sends a query cancel
- (<systemitem>SIGINT</>) signal to a backend process identified by
- process ID. The process ID of an active backend can be found from
- the <structfield>procpid</structfield> column in the
- <structname>pg_stat_activity</structname> view, or by listing the
- <command>postgres</command> processes on the server with
- <application>ps</>.
- </para>
-
- <para>
- <function>pg_reload_conf</> sends a <systemitem>SIGHUP</> signal
- to the server, causing the configuration files
- to be reloaded by all server processes.
- </para>
-
- <para>
- <function>pg_rotate_logfile</> signals the log-file manager to switch
- to a new output file immediately. This works only when
- <varname>redirect_stderr</> is used for logging, since otherwise there
- is no log-file manager subprocess.
- </para>
- <indexterm zone="functions-admin">
- <primary>pg_start_backup</primary>
- </indexterm>
- <indexterm zone="functions-admin">
- <primary>pg_stop_backup</primary>
- </indexterm>
- <indexterm zone="functions-admin">
- <primary>pg_switch_xlog</primary>
- </indexterm>
- <indexterm zone="functions-admin">
- <primary>pg_current_xlog_location</primary>
- </indexterm>
- <indexterm zone="functions-admin">
- <primary>pg_current_xlog_insert_location</primary>
- </indexterm>
- <indexterm zone="functions-admin">
- <primary>pg_xlogfile_name_offset</primary>
- </indexterm>
- <indexterm zone="functions-admin">
- <primary>pg_xlogfile_name</primary>
- </indexterm>
- <indexterm zone="functions-admin">
- <primary>backup</primary>
- </indexterm>
+ <row>
+ <entry><literal><function>current_schema</function>()</literal></entry>
+ <entry><type>name</type></entry>
+ <entry>name of current schema</entry>
+ </row>
- <para>
- The functions shown in <xref
- linkend="functions-admin-backup-table"> assist in making on-line backups.
- Use of the first three functions is restricted to superusers.
- </para>
+ <row>
+ <entry><literal><function>current_schemas</function>(<type>boolean</type>)</literal></entry>
+ <entry><type>name[]</type></entry>
+ <entry>names of schemas in search path optionally including implicit schemas</entry>
+ </row>
- <table id="functions-admin-backup-table">
- <title>Backup Control Functions</title>
- <tgroup cols="3">
- <thead>
- <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry>
+ <row>
+ <entry><literal><function>current_user</function></literal></entry>
+ <entry><type>name</type></entry>
+ <entry>user name of current execution context</entry>
</row>
- </thead>
- <tbody>
<row>
- <entry>
- <literal><function>pg_start_backup</function>(<parameter>label</> <type>text</>)</literal>
- </entry>
- <entry><type>text</type></entry>
- <entry>Set up for performing on-line backup</entry>
+ <entry><literal><function>inet_client_addr</function>()</literal></entry>
+ <entry><type>inet</type></entry>
+ <entry>address of the remote connection</entry>
</row>
+
<row>
- <entry>
- <literal><function>pg_stop_backup</function>()</literal>
- </entry>
- <entry><type>text</type></entry>
- <entry>Finish performing on-line backup</entry>
+ <entry><literal><function>inet_client_port</function>()</literal></entry>
+ <entry><type>int</type></entry>
+ <entry>port of the remote connection</entry>
</row>
+
<row>
- <entry>
- <literal><function>pg_switch_xlog</function>()</literal>
- </entry>
- <entry><type>text</type></entry>
- <entry>Force switch to a new transaction log file</entry>
+ <entry><literal><function>inet_server_addr</function>()</literal></entry>
+ <entry><type>inet</type></entry>
+ <entry>address of the local connection</entry>
</row>
+
<row>
- <entry>
- <literal><function>pg_current_xlog_location</function>()</literal>
- </entry>
- <entry><type>text</type></entry>
- <entry>Get current transaction log write location</entry>
+ <entry><literal><function>inet_server_port</function>()</literal></entry>
+ <entry><type>int</type></entry>
+ <entry>port of the local connection</entry>
</row>
+
<row>
- <entry>
- <literal><function>pg_current_xlog_insert_location</function>()</literal>
- </entry>
- <entry><type>text</type></entry>
- <entry>Get current transaction log insert location</entry>
+ <entry><literal><function>pg_my_temp_schema</function>()</literal></entry>
+ <entry><type>oid</type></entry>
+ <entry>OID of session's temporary schema, or 0 if none</entry>
</row>
+
<row>
- <entry>
- <literal><function>pg_xlogfile_name_offset</function>(<parameter>location</> <type>text</>)</literal>
- </entry>
- <entry><type>text</>, <type>integer</></entry>
- <entry>Convert transaction log location string to file name and decimal byte offset within file</entry>
+ <entry><literal><function>pg_is_other_temp_schema</function>(<type>oid</type>)</literal></entry>
+ <entry><type>boolean</type></entry>
+ <entry>is schema another session's temporary schema?</entry>
</row>
+
<row>
- <entry>
- <literal><function>pg_xlogfile_name</function>(<parameter>location</> <type>text</>)</literal>
- </entry>
+ <entry><literal><function>pg_postmaster_start_time</function>()</literal></entry>
+ <entry><type>timestamp with time zone</type></entry>
+ <entry>server start time</entry>
+ </row>
+
+ <row>
+ <entry><literal><function>session_user</function></literal></entry>
+ <entry><type>name</type></entry>
+ <entry>session user name</entry>
+ </row>
+
+ <row>
+ <entry><literal><function>user</function></literal></entry>
+ <entry><type>name</type></entry>
+ <entry>equivalent to <function>current_user</function></entry>
+ </row>
+
+ <row>
+ <entry><literal><function>version</function>()</literal></entry>
<entry><type>text</type></entry>
- <entry>Convert transaction log location string to file name</entry>
+ <entry><productname>PostgreSQL</> version information</entry>
</row>
</tbody>
</tgroup>
</table>
- <para>
- <function>pg_start_backup</> accepts a single parameter which is an
- arbitrary user-defined label for the backup. (Typically this would be
- the name under which the backup dump file will be stored.) The function
- writes a backup label file into the database cluster's data directory,
- and then returns the backup's starting transaction log location as text. The user
- need not pay any attention to this result value, but it is provided in
- case it is of use.
-<programlisting>
-postgres=# select pg_start_backup('label_goes_here');
- pg_start_backup
------------------
- 0/D4445B8
-(1 row)
-</programlisting>
- </para>
+ <indexterm zone="functions-info">
+ <primary>user</primary>
+ <secondary>current</secondary>
+ </indexterm>
+
+ <indexterm zone="functions-info">
+ <primary>schema</primary>
+ <secondary>current</secondary>
+ </indexterm>
+
+ <indexterm zone="functions-info">
+ <primary>search path</primary>
+ <secondary>current</secondary>
+ </indexterm>
<para>
- <function>pg_stop_backup</> removes the label file created by
- <function>pg_start_backup</>, and instead creates a backup history file in
- the transaction log archive area. The history file includes the label given to
- <function>pg_start_backup</>, the starting and ending transaction log locations for
- the backup, and the starting and ending times of the backup. The return
- value is the backup's ending transaction log location (which again might be of little
- interest). After noting the ending location, the current transaction log insertion
- point is automatically advanced to the next transaction log file, so that the
- ending transaction log file can be archived immediately to complete the backup.
+ The <function>session_user</function> is normally the user who initiated
+ the current database connection; but superusers can change this setting
+ with <xref linkend="sql-set-session-authorization" endterm="sql-set-session-authorization-title">.
+ The <function>current_user</function> is the user identifier
+ that is applicable for permission checking. Normally, it is equal
+ to the session user, but it can be changed with
+ <xref linkend="sql-set-role" endterm="sql-set-role-title">.
+ It also changes during the execution of
+ functions with the attribute <literal>SECURITY DEFINER</literal>.
+ In Unix parlance, the session user is the <quote>real user</quote> and
+ the current user is the <quote>effective user</quote>.
</para>
+ <note>
+ <para>
+ <function>current_user</function>, <function>session_user</function>, and
+ <function>user</function> have special syntactic status in <acronym>SQL</acronym>:
+ they must be called without trailing parentheses.
+ </para>
+ </note>
+
<para>
- <function>pg_switch_xlog</> moves to the next transaction log file, allowing the
- current file to be archived (assuming you are using continuous archiving).
- The result is the ending transaction log location within the just-completed transaction log file.
- If there has been no transaction log activity since the last transaction log switch,
- <function>pg_switch_xlog</> does nothing and returns the end location
- of the previous transaction log file.
+ <function>current_schema</function> returns the name of the schema that is
+ at the front of the search path (or a null value if the search path is
+ empty). This is the schema that will be used for any tables or
+ other named objects that are created without specifying a target schema.
+ <function>current_schemas(boolean)</function> returns an array of the names of all
+ schemas presently in the search path. The Boolean option determines whether or not
+ implicitly included system schemas such as <literal>pg_catalog</> are included in the search
+ path returned.
</para>
+ <note>
+ <para>
+ The search path can be altered at run time. The command is:
+<programlisting>
+SET search_path TO <replaceable>schema</> <optional>, <replaceable>schema</>, ...</optional>
+</programlisting>
+ </para>
+ </note>
+
+ <indexterm zone="functions-info">
+ <primary>inet_client_addr</primary>
+ </indexterm>
+
+ <indexterm zone="functions-info">
+ <primary>inet_client_port</primary>
+ </indexterm>
+
+ <indexterm zone="functions-info">
+ <primary>inet_server_addr</primary>
+ </indexterm>
+
+ <indexterm zone="functions-info">
+ <primary>inet_server_port</primary>
+ </indexterm>
+
<para>
- <function>pg_current_xlog_location</> displays the current transaction log write
- location in the same format used by the above functions. Similarly
- <function>pg_current_xlog_insert_location</> displays the current transaction log
- insertion point. The insertion point is the <quote>logical</> end of transaction log
- at any instant, while the write location is the end of what has actually
- been written out from the server's internal buffers. The write location
- is the end of what can be examined from outside the server, and is usually
- what you want if you are interested in archiving partially-complete transaction log
- files. The insertion point is made available primarily for server
- debugging purposes. These are both read-only operations and do not
- require superuser permissions.
+ <function>inet_client_addr</function> returns the IP address of the
+ current client, and <function>inet_client_port</function> returns the
+ port number.
+ <function>inet_server_addr</function> returns the IP address on which
+ the server accepted the current connection, and
+ <function>inet_server_port</function> returns the port number.
+ All these functions return NULL if the current connection is via a
+ Unix-domain socket.
</para>
+ <indexterm zone="functions-info">
+ <primary>pg_my_temp_schema</primary>
+ </indexterm>
+
+ <indexterm zone="functions-info">
+ <primary>pg_is_other_temp_schema</primary>
+ </indexterm>
+
<para>
- You can use <function>pg_xlogfile_name_offset</> to extract the
- corresponding transaction log file name and byte offset from the results of any of the
- above functions. For example:
-<programlisting>
-postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup());
- file_name | file_offset
---------------------------+-------------
- 00000001000000000000000D | 4039624
-(1 row)
-</programlisting>
- Similarly, <function>pg_xlogfile_name</> extracts just the transaction log file name.
- When the given transction log location is exactly at an transaction log file boundary, both
- these functions return the name of the preceding transaction log file.
- This is usually the desired behavior for managing transaction log archiving
- behavior, since the preceding file is the last one that currently
- needs to be archived.
+ <function>pg_my_temp_schema</function> returns the OID of the current
+ session's temporary schema, or 0 if it has none (because it has not
+ created any temporary tables).
+ <function>pg_is_other_temp_schema</function> returns true if the
+ given OID is the OID of any other session's temporary schema.
+ (This can be useful, for example, to exclude other sessions' temporary
+ tables from a catalog display.)
</para>
+ <indexterm zone="functions-info">
+ <primary>pg_postmaster_start_time</primary>
+ </indexterm>
+
<para>
- For details about proper usage of these functions, see
- <xref linkend="continuous-archiving">.
+ <function>pg_postmaster_start_time</function> returns the
+ <type>timestamp with time zone</type> when the
+ server started.
</para>
+ <indexterm zone="functions-info">
+ <primary>version</primary>
+ </indexterm>
+
<para>
- The functions shown in <xref linkend="functions-admin-dbsize"> calculate
- the actual disk space usage of database objects.
+ <function>version</function> returns a string describing the
+ <productname>PostgreSQL</productname> server's version.
</para>
- <indexterm zone="functions-admin">
- <primary>pg_column_size</primary>
- </indexterm>
- <indexterm zone="functions-admin">
- <primary>pg_database_size</primary>
- </indexterm>
- <indexterm zone="functions-admin">
- <primary>pg_relation_size</primary>
- </indexterm>
- <indexterm zone="functions-admin">
- <primary>pg_size_pretty</primary>
- </indexterm>
- <indexterm zone="functions-admin">
- <primary>pg_tablespace_size</primary>
- </indexterm>
- <indexterm zone="functions-admin">
- <primary>pg_total_relation_size</primary>
- </indexterm>
+ <indexterm>
+ <primary>privilege</primary>
+ <secondary>querying</secondary>
+ </indexterm>
- <table id="functions-admin-dbsize">
- <title>Database Object Size Functions</title>
+ <para>
+ <xref linkend="functions-info-access-table"> lists functions that
+ allow the user to query object access privileges programmatically.
+ See <xref linkend="ddl-priv"> for more information about
+ privileges.
+ </para>
+
+ <table id="functions-info-access-table">
+ <title>Access Privilege Inquiry Functions</title>
<tgroup cols="3">
<thead>
- <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry>
- </row>
+ <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry></row>
</thead>
<tbody>
<row>
- <entry><function>pg_column_size</function>(<type>any</type>)</entry>
- <entry><type>int</type></entry>
- <entry>Number of bytes used to store a particular value (possibly compressed)</entry>
+ <entry><literal><function>has_database_privilege</function>(<parameter>user</parameter>,
+ <parameter>database</parameter>,
+ <parameter>privilege</parameter>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>does user have privilege for database</entry>
</row>
<row>
- <entry>
- <literal><function>pg_database_size</function>(<type>oid</type>)</literal>
- </entry>
- <entry><type>bigint</type></entry>
- <entry>Disk space used by the database with the specified OID</entry>
+ <entry><literal><function>has_database_privilege</function>(<parameter>database</parameter>,
+ <parameter>privilege</parameter>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>does current user have privilege for database</entry>
</row>
<row>
- <entry>
- <literal><function>pg_database_size</function>(<type>name</type>)</literal>
- </entry>
- <entry><type>bigint</type></entry>
- <entry>Disk space used by the database with the specified name</entry>
+ <entry><literal><function>has_function_privilege</function>(<parameter>user</parameter>,
+ <parameter>function</parameter>,
+ <parameter>privilege</parameter>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>does user have privilege for function</entry>
</row>
<row>
- <entry>
- <literal><function>pg_relation_size</function>(<type>oid</type>)</literal>
- </entry>
- <entry><type>bigint</type></entry>
- <entry>Disk space used by the table or index with the specified OID</entry>
+ <entry><literal><function>has_function_privilege</function>(<parameter>function</parameter>,
+ <parameter>privilege</parameter>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>does current user have privilege for function</entry>
</row>
<row>
- <entry>
- <literal><function>pg_relation_size</function>(<type>text</type>)</literal>
- </entry>
- <entry><type>bigint</type></entry>
- <entry>
- Disk space used by the table or index with the specified name.
- The table name can be qualified with a schema name
+ <entry><literal><function>has_language_privilege</function>(<parameter>user</parameter>,
+ <parameter>language</parameter>,
+ <parameter>privilege</parameter>)</literal>
</entry>
+ <entry><type>boolean</type></entry>
+ <entry>does user have privilege for language</entry>
</row>
<row>
- <entry>
- <literal><function>pg_size_pretty</function>(<type>bigint</type>)</literal>
- </entry>
- <entry><type>text</type></entry>
- <entry>Converts a size in bytes into a human-readable format with size units</entry>
+ <entry><literal><function>has_language_privilege</function>(<parameter>language</parameter>,
+ <parameter>privilege</parameter>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>does current user have privilege for language</entry>
</row>
<row>
- <entry>
- <literal><function>pg_tablespace_size</function>(<type>oid</type>)</literal>
- </entry>
- <entry><type>bigint</type></entry>
- <entry>Disk space used by the tablespace with the specified OID</entry>
+ <entry><literal><function>has_schema_privilege</function>(<parameter>user</parameter>,
+ <parameter>schema</parameter>,
+ <parameter>privilege</parameter>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>does user have privilege for schema</entry>
</row>
<row>
- <entry>
- <literal><function>pg_tablespace_size</function>(<type>name</type>)</literal>
- </entry>
- <entry><type>bigint</type></entry>
- <entry>Disk space used by the tablespace with the specified name</entry>
+ <entry><literal><function>has_schema_privilege</function>(<parameter>schema</parameter>,
+ <parameter>privilege</parameter>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>does current user have privilege for schema</entry>
</row>
<row>
- <entry>
- <literal><function>pg_total_relation_size</function>(<type>oid</type>)</literal>
- </entry>
- <entry><type>bigint</type></entry>
- <entry>
- Total disk space used by the table with the specified OID,
- including indexes and toasted data
+ <entry><literal><function>has_table_privilege</function>(<parameter>user</parameter>,
+ <parameter>table</parameter>,
+ <parameter>privilege</parameter>)</literal>
</entry>
+ <entry><type>boolean</type></entry>
+ <entry>does user have privilege for table</entry>
</row>
<row>
- <entry>
- <literal><function>pg_total_relation_size</function>(<type>text</type>)</literal>
- </entry>
- <entry><type>bigint</type></entry>
- <entry>
- Total disk space used by the table with the specified name,
- including indexes and toasted data. The table name can be
- qualified with a schema name
+ <entry><literal><function>has_table_privilege</function>(<parameter>table</parameter>,
+ <parameter>privilege</parameter>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>does current user have privilege for table</entry>
+ </row>
+ <row>
+ <entry><literal><function>has_tablespace_privilege</function>(<parameter>user</parameter>,
+ <parameter>tablespace</parameter>,
+ <parameter>privilege</parameter>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>does user have privilege for tablespace</entry>
+ </row>
+ <row>
+ <entry><literal><function>has_tablespace_privilege</function>(<parameter>tablespace</parameter>,
+ <parameter>privilege</parameter>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>does current user have privilege for tablespace</entry>
+ </row>
+ <row>
+ <entry><literal><function>pg_has_role</function>(<parameter>user</parameter>,
+ <parameter>role</parameter>,
+ <parameter>privilege</parameter>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>does user have privilege for role</entry>
+ </row>
+ <row>
+ <entry><literal><function>pg_has_role</function>(<parameter>role</parameter>,
+ <parameter>privilege</parameter>)</literal>
</entry>
+ <entry><type>boolean</type></entry>
+ <entry>does current user have privilege for role</entry>
</row>
</tbody>
</tgroup>
</table>
+ <indexterm zone="functions-info">
+ <primary>has_database_privilege</primary>
+ </indexterm>
+ <indexterm zone="functions-info">
+ <primary>has_function_privilege</primary>
+ </indexterm>
+ <indexterm zone="functions-info">
+ <primary>has_language_privilege</primary>
+ </indexterm>
+ <indexterm zone="functions-info">
+ <primary>has_schema_privilege</primary>
+ </indexterm>
+ <indexterm zone="functions-info">
+ <primary>has_table_privilege</primary>
+ </indexterm>
+ <indexterm zone="functions-info">
+ <primary>has_tablespace_privilege</primary>
+ </indexterm>
+ <indexterm zone="functions-info">
+ <primary>pg_has_role</primary>
+ </indexterm>
+
<para>
- <function>pg_column_size</> shows the space used to store any individual
- data value.
+ <function>has_database_privilege</function> checks whether a user
+ can access a database in a particular way. The possibilities for its
+ arguments are analogous to <function>has_table_privilege</function>.
+ The desired access privilege type must evaluate to
+ <literal>CREATE</literal>,
+ <literal>CONNECT</literal>,
+ <literal>TEMPORARY</literal>, or
+ <literal>TEMP</literal> (which is equivalent to
+ <literal>TEMPORARY</literal>).
</para>
<para>
- <function>pg_database_size</function> and <function>pg_tablespace_size</>
- accept the OID or name of a database or tablespace, and return the total
- disk space used therein.
+ <function>has_function_privilege</function> checks whether a user
+ can access a function in a particular way. The possibilities for its
+ arguments are analogous to <function>has_table_privilege</function>.
+ When specifying a function by a text string rather than by OID,
+ the allowed input is the same as for the <type>regprocedure</> data type
+ (see <xref linkend="datatype-oid">).
+ The desired access privilege type must evaluate to
+ <literal>EXECUTE</literal>.
+ An example is:
+<programlisting>
+SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
+</programlisting>
+ </para>
+
+ <para>
+ <function>has_language_privilege</function> checks whether a user
+ can access a procedural language in a particular way. The possibilities
+ for its arguments are analogous to <function>has_table_privilege</function>.
+ The desired access privilege type must evaluate to
+ <literal>USAGE</literal>.
+ </para>
+
+ <para>
+ <function>has_schema_privilege</function> checks whether a user
+ can access a schema in a particular way. The possibilities for its
+ arguments are analogous to <function>has_table_privilege</function>.
+ The desired access privilege type must evaluate to
+ <literal>CREATE</literal> or
+ <literal>USAGE</literal>.
+ </para>
+
+ <para>
+ <function>has_table_privilege</function> checks whether a user
+ can access a table in a particular way. The user can be
+ specified by name or by OID
+ (<literal>pg_authid.oid</literal>), or if the argument is
+ omitted
+ <function>current_user</function> is assumed. The table can be specified
+ by name or by OID. (Thus, there are actually six variants of
+ <function>has_table_privilege</function>, which can be distinguished by
+ the number and types of their arguments.) When specifying by name,
+ the name can be schema-qualified if necessary.
+ The desired access privilege type
+ is specified by a text string, which must evaluate to one of the
+ values <literal>SELECT</literal>, <literal>INSERT</literal>,
+ <literal>UPDATE</literal>, <literal>DELETE</literal>,
+ <literal>REFERENCES</literal>, or <literal>TRIGGER</literal>.
+ (Case of the string is not significant, however.)
+ An example is:
+<programlisting>
+SELECT has_table_privilege('myschema.mytable', 'select');
+</programlisting>
</para>
<para>
- <function>pg_relation_size</> accepts the OID or name of a table, index or
- toast table, and returns the size in bytes.
+ <function>has_tablespace_privilege</function> checks whether a user
+ can access a tablespace in a particular way. The possibilities for its
+ arguments are analogous to <function>has_table_privilege</function>.
+ The desired access privilege type must evaluate to
+ <literal>CREATE</literal>.
</para>
<para>
- <function>pg_size_pretty</> can be used to format the result of one of
- the other functions in a human-readable way, using kB, MB, GB or TB as
- appropriate.
+ <function>pg_has_role</function> checks whether a user
+ can access a role in a particular way. The possibilities for its
+ arguments are analogous to <function>has_table_privilege</function>.
+ The desired access privilege type must evaluate to
+ <literal>MEMBER</literal> or
+ <literal>USAGE</literal>.
+ <literal>MEMBER</literal> denotes direct or indirect membership in
+ the role (that is, the right to do <command>SET ROLE</>), while
+ <literal>USAGE</literal> denotes whether the privileges of the role
+ are immediately available without doing <command>SET ROLE</>.
</para>
- <para>
- <function>pg_total_relation_size</> accepts the OID or name of a
- table or toast table, and returns the size in bytes of the data
- and all associated indexes and toast tables.
- </para>
+ <para>
+ To test whether a user holds a grant option on the privilege,
+ append <literal>WITH GRANT OPTION</literal> to the privilege key
+ word; for example <literal>'UPDATE WITH GRANT OPTION'</literal>.
+ </para>
- <para>
- The functions shown in <xref
- linkend="functions-admin-genfile"> provide native file access to
- files on the machine hosting the server. Only files within the
- database cluster directory and the <varname>log_directory</> can be
- accessed. Use a relative path for files within the cluster directory,
- and a path matching the <varname>log_directory</> configuration setting
- for log files. Use of these functions is restricted to superusers.
- </para>
+ <para>
+ <xref linkend="functions-info-schema-table"> shows functions that
+ determine whether a certain object is <firstterm>visible</> in the
+ current schema search path. A table is said to be visible if its
+ containing schema is in the search path and no table of the same
+ name appears earlier in the search path. This is equivalent to the
+ statement that the table can be referenced by name without explicit
+ schema qualification. For example, to list the names of all
+ visible tables:
+<programlisting>
+SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
+</programlisting>
+ </para>
- <table id="functions-admin-genfile">
- <title>Generic File Access Functions</title>
+ <table id="functions-info-schema-table">
+ <title>Schema Visibility Inquiry Functions</title>
<tgroup cols="3">
<thead>
- <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry>
- </row>
+ <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry></row>
</thead>
<tbody>
<row>
- <entry>
- <literal><function>pg_ls_dir</function>(<parameter>dirname</> <type>text</>)</literal>
+ <entry><literal><function>pg_conversion_is_visible</function>(<parameter>conversion_oid</parameter>)</literal>
</entry>
- <entry><type>setof text</type></entry>
- <entry>List the contents of a directory</entry>
+ <entry><type>boolean</type></entry>
+ <entry>is conversion visible in search path</entry>
</row>
<row>
- <entry>
- <literal><function>pg_read_file</function>(<parameter>filename</> <type>text</>, <parameter>offset</> <type>bigint</>, <parameter>length</> <type>bigint</>)</literal>
+ <entry><literal><function>pg_function_is_visible</function>(<parameter>function_oid</parameter>)</literal>
</entry>
- <entry><type>text</type></entry>
- <entry>Return the contents of a text file</entry>
+ <entry><type>boolean</type></entry>
+ <entry>is function visible in search path</entry>
</row>
<row>
- <entry>
- <literal><function>pg_stat_file</function>(<parameter>filename</> <type>text</>)</literal>
+ <entry><literal><function>pg_operator_is_visible</function>(<parameter>operator_oid</parameter>)</literal>
</entry>
- <entry><type>record</type></entry>
- <entry>Return information about a file</entry>
+ <entry><type>boolean</type></entry>
+ <entry>is operator visible in search path</entry>
+ </row>
+ <row>
+ <entry><literal><function>pg_opclass_is_visible</function>(<parameter>opclass_oid</parameter>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>is operator class visible in search path</entry>
+ </row>
+ <row>
+ <entry><literal><function>pg_table_is_visible</function>(<parameter>table_oid</parameter>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>is table visible in search path</entry>
+ </row>
+ <row>
+ <entry><literal><function>pg_type_is_visible</function>(<parameter>type_oid</parameter>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>is type (or domain) visible in search path</entry>
</row>
</tbody>
</tgroup>
</table>
- <indexterm zone="functions-admin">
- <primary>pg_ls_dir</primary>
+ <indexterm zone="functions-info">
+ <primary>pg_conversion_is_visible</primary>
</indexterm>
- <para>
- <function>pg_ls_dir</> returns all the names in the specified
- directory, except the special entries <quote><literal>.</></> and
- <quote><literal>..</></>.
- </para>
-
- <indexterm zone="functions-admin">
- <primary>pg_read_file</primary>
+ <indexterm zone="functions-info">
+ <primary>pg_function_is_visible</primary>
+ </indexterm>
+ <indexterm zone="functions-info">
+ <primary>pg_operator_is_visible</primary>
+ </indexterm>
+ <indexterm zone="functions-info">
+ <primary>pg_opclass_is_visible</primary>
+ </indexterm>
+ <indexterm zone="functions-info">
+ <primary>pg_table_is_visible</primary>
</indexterm>
+ <indexterm zone="functions-info">
+ <primary>pg_type_is_visible</primary>
+ </indexterm>
+
<para>
- <function>pg_read_file</> returns part of a text file, starting
- at the given <parameter>offset</>, returning at most <parameter>length</>
- bytes (less if the end of file is reached first). If <parameter>offset</>
- is negative, it is relative to the end of the file.
+ <function>pg_conversion_is_visible</function>,
+ <function>pg_function_is_visible</function>,
+ <function>pg_operator_is_visible</function>,
+ <function>pg_opclass_is_visible</function>,
+ <function>pg_table_is_visible</function>, and
+ <function>pg_type_is_visible</function> perform the visibility check for
+ conversions, functions, operators, operator classes, tables, and
+ types. Note that <function>pg_table_is_visible</function> can also be used
+ with views, indexes and sequences; <function>pg_type_is_visible</function>
+ can also be used with domains. For functions and operators, an object in
+ the search path is visible if there is no object of the same name
+ <emphasis>and argument data type(s)</> earlier in the path. For operator
+ classes, both name and associated index access method are considered.
</para>
- <indexterm zone="functions-admin">
- <primary>pg_stat_file</primary>
- </indexterm>
<para>
- <function>pg_stat_file</> returns a record containing the file
- size, last accessed time stamp, last modified time stamp,
- last file status change time stamp (Unix platforms only),
- file creation time stamp (Windows only), and a <type>boolean</type>
- indicating if it is a directory. Typical usages include:
+ All these functions require object OIDs to identify the object to be
+ checked. If you want to test an object by name, it is convenient to use
+ the OID alias types (<type>regclass</>, <type>regtype</>,
+ <type>regprocedure</>, or <type>regoperator</>), for example:
<programlisting>
-SELECT * FROM pg_stat_file('filename');
-SELECT (pg_stat_file('filename')).modification;
+SELECT pg_type_is_visible('myschema.widget'::regtype);
</programlisting>
+ Note that it would not make much sense to test an unqualified name in
+ this way — if the name can be recognized at all, it must be visible.
</para>
- <para>
- The functions shown in <xref linkend="functions-advisory-locks"> manage
- advisory locks. For details about proper usage of these functions, see
- <xref linkend="advisory-locks">.
- </para>
+ <indexterm zone="functions-info">
+ <primary>format_type</primary>
+ </indexterm>
- <table id="functions-advisory-locks">
- <title>Advisory Lock Functions</title>
+ <indexterm zone="functions-info">
+ <primary>pg_get_viewdef</primary>
+ </indexterm>
+
+ <indexterm zone="functions-info">
+ <primary>pg_get_ruledef</primary>
+ </indexterm>
+
+ <indexterm zone="functions-info">
+ <primary>pg_get_indexdef</primary>
+ </indexterm>
+
+ <indexterm zone="functions-info">
+ <primary>pg_get_triggerdef</primary>
+ </indexterm>
+
+ <indexterm zone="functions-info">
+ <primary>pg_get_constraintdef</primary>
+ </indexterm>
+
+ <indexterm zone="functions-info">
+ <primary>pg_get_expr</primary>
+ </indexterm>
+
+ <indexterm zone="functions-info">
+ <primary>pg_get_userbyid</primary>
+ </indexterm>
+
+ <indexterm zone="functions-info">
+ <primary>pg_get_serial_sequence</primary>
+ </indexterm>
+
+ <indexterm zone="functions-info">
+ <primary>pg_tablespace_databases</primary>
+ </indexterm>
+
+ <para>
+ <xref linkend="functions-info-catalog-table"> lists functions that
+ extract information from the system catalogs.
+ </para>
+
+ <table id="functions-info-catalog-table">
+ <title>System Catalog Information Functions</title>
<tgroup cols="3">
<thead>
- <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry>
- </row>
+ <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry></row>
</thead>
<tbody>
<row>
- <entry>
- <literal><function>pg_advisory_lock</function>(<parameter>key</> <type>bigint</>)</literal>
- </entry>
- <entry><type>void</type></entry>
- <entry>Obtain exclusive advisory lock</entry>
+ <entry><literal><function>format_type</function>(<parameter>type_oid</parameter>, <parameter>typemod</>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>get SQL name of a data type</entry>
+ </row>
+ <row>
+ <entry><literal><function>pg_get_constraintdef</function>(<parameter>constraint_oid</parameter>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>get definition of a constraint</entry>
+ </row>
+ <row>
+ <entry><literal><function>pg_get_constraintdef</function>(<parameter>constraint_oid</parameter>, <parameter>pretty_bool</>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>get definition of a constraint</entry>
+ </row>
+ <row>
+ <entry><literal><function>pg_get_expr</function>(<parameter>expr_text</parameter>, <parameter>relation_oid</>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>decompile internal form of an expression, assuming that any Vars
+ in it refer to the relation indicated by the second parameter</entry>
+ </row>
+ <row>
+ <entry><literal><function>pg_get_expr</function>(<parameter>expr_text</parameter>, <parameter>relation_oid</>, <parameter>pretty_bool</>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>decompile internal form of an expression, assuming that any Vars
+ in it refer to the relation indicated by the second parameter</entry>
</row>
<row>
- <entry>
- <literal><function>pg_advisory_lock</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
- </entry>
- <entry><type>void</type></entry>
- <entry>Obtain exclusive advisory lock</entry>
+ <entry><literal><function>pg_get_indexdef</function>(<parameter>index_oid</parameter>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>get <command>CREATE INDEX</> command for index</entry>
</row>
-
<row>
- <entry>
- <literal><function>pg_advisory_lock_shared</function>(<parameter>key</> <type>bigint</>)</literal>
- </entry>
- <entry><type>void</type></entry>
- <entry>Obtain shared advisory lock</entry>
+ <entry><literal><function>pg_get_indexdef</function>(<parameter>index_oid</parameter>, <parameter>column_no</>, <parameter>pretty_bool</>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>get <command>CREATE INDEX</> command for index,
+ or definition of just one index column when
+ <parameter>column_no</> is not zero</entry>
</row>
<row>
- <entry>
- <literal><function>pg_advisory_lock_shared</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
- </entry>
- <entry><type>void</type></entry>
- <entry>Obtain shared advisory lock</entry>
+ <entry><literal><function>pg_get_ruledef</function>(<parameter>rule_oid</parameter>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>get <command>CREATE RULE</> command for rule</entry>
</row>
-
<row>
- <entry>
- <literal><function>pg_try_advisory_lock</function>(<parameter>key</> <type>bigint</>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>Obtain exclusive advisory lock if available</entry>
+ <entry><literal><function>pg_get_ruledef</function>(<parameter>rule_oid</parameter>, <parameter>pretty_bool</>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>get <command>CREATE RULE</> command for rule</entry>
</row>
<row>
- <entry>
- <literal><function>pg_try_advisory_lock</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>Obtain exclusive advisory lock if available</entry>
+ <entry><literal><function>pg_get_serial_sequence</function>(<parameter>table_name</parameter>, <parameter>column_name</parameter>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>get name of the sequence that a <type>serial</type> or <type>bigserial</type> column
+ uses</entry>
</row>
-
<row>
- <entry>
- <literal><function>pg_try_advisory_lock_shared</function>(<parameter>key</> <type>bigint</>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>Obtain shared advisory lock if available</entry>
+ <entry><function>pg_get_triggerdef</function>(<parameter>trigger_oid</parameter>)</entry>
+ <entry><type>text</type></entry>
+ <entry>get <command>CREATE [ CONSTRAINT ] TRIGGER</> command for trigger</entry>
</row>
<row>
- <entry>
- <literal><function>pg_try_advisory_lock_shared</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>Obtain shared advisory lock if available</entry>
+ <entry><literal><function>pg_get_userbyid</function>(<parameter>roleid</parameter>)</literal></entry>
+ <entry><type>name</type></entry>
+ <entry>get role name with given ID</entry>
</row>
-
<row>
- <entry>
- <literal><function>pg_advisory_unlock</function>(<parameter>key</> <type>bigint</>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>Release an exclusive advisory lock</entry>
+ <entry><literal><function>pg_get_viewdef</function>(<parameter>view_name</parameter>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>get underlying <command>SELECT</command> command for view (<emphasis>deprecated</emphasis>)</entry>
</row>
<row>
- <entry>
- <literal><function>pg_advisory_unlock</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>Release an exclusive advisory lock</entry>
+ <entry><literal><function>pg_get_viewdef</function>(<parameter>view_name</parameter>, <parameter>pretty_bool</>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>get underlying <command>SELECT</command> command for view (<emphasis>deprecated</emphasis>)</entry>
</row>
-
<row>
- <entry>
- <literal><function>pg_advisory_unlock_shared</function>(<parameter>key</> <type>bigint</>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>Release a shared advisory lock</entry>
+ <entry><literal><function>pg_get_viewdef</function>(<parameter>view_oid</parameter>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>get underlying <command>SELECT</command> command for view</entry>
</row>
<row>
- <entry>
- <literal><function>pg_advisory_unlock_shared</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>Release a shared advisory lock</entry>
+ <entry><literal><function>pg_get_viewdef</function>(<parameter>view_oid</parameter>, <parameter>pretty_bool</>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>get underlying <command>SELECT</command> command for view</entry>
</row>
-
<row>
- <entry>
- <literal><function>pg_advisory_unlock_all</function>()</literal>
- </entry>
- <entry><type>void</type></entry>
- <entry>Release all advisory locks held by the current session</entry>
+ <entry><literal><function>pg_tablespace_databases</function>(<parameter>tablespace_oid</parameter>)</literal></entry>
+ <entry><type>setof oid</type></entry>
+ <entry>get the set of database OIDs that have objects in the tablespace</entry>
</row>
-
</tbody>
</tgroup>
</table>
- <indexterm zone="functions-admin">
- <primary>pg_advisory_lock</primary>
- </indexterm>
- <para>
- <function>pg_advisory_lock</> locks an application-defined resource,
- which can be identified either by a single 64-bit key value or two
- 32-bit key values (note that these two key spaces do not overlap). If
- another session already holds a lock on the same resource, the
- function will wait until the resource becomes available. The lock
- is exclusive. Multiple lock requests stack, so that if the same resource
- is locked three times it must be also unlocked three times to be
- released for other sessions' use.
- </para>
+ <para>
+ <function>format_type</function> returns the SQL name of a data type that
+ is identified by its type OID and possibly a type modifier. Pass NULL
+ for the type modifier if no specific modifier is known.
+ </para>
- <indexterm zone="functions-admin">
- <primary>pg_advisory_lock_shared</primary>
+ <para>
+ <function>pg_get_constraintdef</function>,
+ <function>pg_get_indexdef</function>, <function>pg_get_ruledef</function>,
+ and <function>pg_get_triggerdef</function>, respectively reconstruct the
+ creating command for a constraint, index, rule, or trigger. (Note that this
+ is a decompiled reconstruction, not the original text of the command.)
+ <function>pg_get_expr</function> decompiles the internal form of an
+ individual expression, such as the default value for a column. It can be
+ useful when examining the contents of system catalogs.
+ <function>pg_get_viewdef</function> reconstructs the <command>SELECT</>
+ query that defines a view. Most of these functions come in two variants,
+ one of which can optionally <quote>pretty-print</> the result. The
+ pretty-printed format is more readable, but the default format is more
+ likely to be interpreted the same way by future versions of
+ <productname>PostgreSQL</>; avoid using pretty-printed output for dump
+ purposes. Passing <literal>false</> for the pretty-print parameter yields
+ the same result as the variant that does not have the parameter at all.
+ </para>
+
+ <para>
+ <function>pg_get_serial_sequence</function> returns the name of the
+ sequence associated with a column, or NULL if no sequence is associated
+ with the column. The first input parameter is a table name with
+ optional schema, and the second parameter is a column name. Because
+ the first parameter is potentially a schema and table, it is not treated
+ as a double-quoted identifier, meaning it is lowercased by default,
+ while the second parameter, being just a column name, is treated as
+ double-quoted and has its case preserved. The function returns a value
+ suitably formatted for passing to the sequence functions (see <xref
+ linkend="functions-sequence">). This association can be modified or
+ removed with <command>ALTER SEQUENCE OWNED BY</>. (The function
+ probably should have been called
+ <function>pg_get_owned_sequence</function>; its name reflects the fact
+ that it's typically used with <type>serial</> or <type>bigserial</>
+ columns.)
+ </para>
+
+ <para>
+ <function>pg_get_userbyid</function> extracts a role's name given
+ its OID.
+ </para>
+
+ <para>
+ <function>pg_tablespace_databases</function> allows a tablespace to be
+ examined. It returns the set of OIDs of databases that have objects stored
+ in the tablespace. If this function returns any rows, the tablespace is not
+ empty and cannot be dropped. To display the specific objects populating the
+ tablespace, you will need to connect to the databases identified by
+ <function>pg_tablespace_databases</function> and query their
+ <structname>pg_class</> catalogs.
+ </para>
+
+ <indexterm zone="functions-info">
+ <primary>col_description</primary>
</indexterm>
- <para>
- <function>pg_advisory_lock_shared</> works the same as
- <function>pg_advisory_lock</>,
- except the lock can be shared with other sessions requesting shared locks.
- Only would-be exclusive lockers are locked out.
- </para>
- <indexterm zone="functions-admin">
- <primary>pg_try_advisory_lock</primary>
+ <indexterm zone="functions-info">
+ <primary>obj_description</primary>
</indexterm>
- <para>
- <function>pg_try_advisory_lock</> is similar to
- <function>pg_advisory_lock</>, except the function will not wait for the
- lock to become available. It will either obtain the lock immediately and
- return <literal>true</>, or return <literal>false</> if the lock cannot be
- acquired now.
- </para>
- <indexterm zone="functions-admin">
- <primary>pg_try_advisory_lock_shared</primary>
+ <indexterm zone="functions-info">
+ <primary>shobj_description</primary>
</indexterm>
- <para>
- <function>pg_try_advisory_lock_shared</> works the same as
- <function>pg_try_advisory_lock</>, except it attempts to acquire
- shared rather than exclusive lock.
- </para>
- <indexterm zone="functions-admin">
- <primary>pg_advisory_unlock</primary>
+ <indexterm zone="functions-info">
+ <primary>comment</primary>
+ <secondary sortas="database objects">about database objects</secondary>
</indexterm>
+
<para>
- <function>pg_advisory_unlock</> will release a previously-acquired
- exclusive advisory lock. It
- will return <literal>true</> if the lock is successfully released.
- If the lock was in fact not held, it will return <literal>false</>,
- and in addition, an SQL warning will be raised by the server.
+ The functions shown in <xref linkend="functions-info-comment-table">
+ extract comments previously stored with the <xref linkend="sql-comment"
+ endterm="sql-comment-title"> command. A null value is returned if no
+ comment could be found matching the specified parameters.
</para>
- <indexterm zone="functions-admin">
- <primary>pg_advisory_unlock_shared</primary>
- </indexterm>
+ <table id="functions-info-comment-table">
+ <title>Comment Information Functions</title>
+ <tgroup cols="3">
+ <thead>
+ <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry></row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal><function>col_description</function>(<parameter>table_oid</parameter>, <parameter>column_number</parameter>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>get comment for a table column</entry>
+ </row>
+ <row>
+ <entry><literal><function>obj_description</function>(<parameter>object_oid</parameter>, <parameter>catalog_name</parameter>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>get comment for a database object</entry>
+ </row>
+ <row>
+ <entry><literal><function>obj_description</function>(<parameter>object_oid</parameter>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>get comment for a database object (<emphasis>deprecated</emphasis>)</entry>
+ </row>
+ <row>
+ <entry><literal><function>shobj_description</function>(<parameter>object_oid</parameter>, <parameter>catalog_name</parameter>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>get comment for a shared database object</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
<para>
- <function>pg_advisory_unlock_shared</> works the same as
- <function>pg_advisory_unlock</>,
- except to release a shared advisory lock.
+ <function>col_description</function> returns the comment for a table column,
+ which is specified by the OID of its table and its column number.
+ <function>obj_description</function> cannot be used for table columns since
+ columns do not have OIDs of their own.
</para>
- <indexterm zone="functions-admin">
- <primary>pg_advisory_unlock_all</primary>
- </indexterm>
<para>
- <function>pg_advisory_unlock_all</> will release all advisory locks
- held by the current session. (This function is implicitly invoked
- at session end, even if the client disconnects ungracefully.)
+ The two-parameter form of <function>obj_description</function> returns the
+ comment for a database object specified by its OID and the name of the
+ containing system catalog. For example,
+ <literal>obj_description(123456,'pg_class')</literal>
+ would retrieve the comment for a table with OID 123456.
+ The one-parameter form of <function>obj_description</function> requires only
+ the object OID. It is now deprecated since there is no guarantee that
+ OIDs are unique across different system catalogs; therefore, the wrong
+ comment could be returned.
</para>
+ <para>
+ <function>shobj_description</function> is used just like
+ <function>obj_description</function> only that it is used for retrieving
+ comments on shared objects. Some system catalogs are global to all
+ databases within each cluster and their descriptions are stored globally
+ as well.
+ </para>
</sect1>
- <sect1 id="functions-xml">
- <title>XML Functions</title>
+ <sect1 id="functions-admin">
+ <title>System Administration Functions</title>
<para>
- The functions and function-like expressions described in this
- section operate on values of type <type>xml</type>. Check <xref
- linkend="datatype-xml"> for information about the <type>xml</type>
- type. The function-like expressions <function>xmlparse</function>
- and <function>xmlserialize</function> for converting to and from
- type <type>xml</type> are not repeated here.
+ <xref linkend="functions-admin-set-table"> shows the functions
+ available to query and alter run-time configuration parameters.
</para>
- <sect2>
- <title>Producing XML Content</title>
-
- <para>
- A set of functions and function-like expressions are available for
- producing XML content from SQL data. As such, they are
- particularly suitable for formatting query results into XML
- documents for processing in client applications.
- </para>
-
- <sect3>
- <title><literal>xmlcomment</literal></title>
-
- <indexterm>
- <primary>xmlcomment</primary>
- </indexterm>
-
-<synopsis>
-<function>xmlcomment</function>(<replaceable>text</replaceable>)
-</synopsis>
-
- <para>
- The function <function>xmlcomment</function> creates an XML value
- containing an XML comment with the specified text as content.
- The text cannot contain <literal>--</literal> or end with a
- <literal>-</literal> so that the resulting construct is a valid
- XML comment. If the argument is null, the result is null.
- </para>
-
- <para>
- Example:
-<screen><![CDATA[
-SELECT xmlcomment('hello');
-
- xmlcomment
---------------
- <!--hello-->
-]]></screen>
- </para>
- </sect3>
-
- <sect3>
- <title><literal>xmlconcat</literal></title>
-
- <indexterm>
- <primary>xmlconcat</primary>
- </indexterm>
-
- <synopsis>
- <function>xmlconcat</function>(<replaceable>xml</replaceable><optional>, ...</optional>)
- </synopsis>
-
- <para>
- The function <function>xmlconcat</function> concatenates a list
- of individual XML values to create a single value containing an
- XML content fragment. Null values are omitted; the result is
- only null if there are no nonnull arguments.
- </para>
-
- <para>
- Example:
-<screen><![CDATA[
-SELECT xmlconcat('<abc/>', '<bar>foo</bar>');
-
- xmlconcat
-----------------------
- <abc/><bar>foo</bar>
-]]></screen>
- </para>
-
- <para>
- XML declarations, if present are combined as follows. If all
- argument values have the same XML version declaration, that
- version is used in the result, else no version is used. If all
- argument values have the standalone declaration value
- <quote>yes</quote>, then that value is used in the result. If
- all argument values have a standalone declaration value and at
- least one is <quote>no</quote>, then that is used in the result.
- Else the result will have no standalone declaration. If the
- result is determined to require a standalone declaration but no
- version declaration, a version declaration with version 1.0 will
- be used because XML requires an XML declaration to contain a
- version declaration. Encoding declarations are ignored and
- removed in all cases.
- </para>
+ <table id="functions-admin-set-table">
+ <title>Configuration Settings Functions</title>
+ <tgroup cols="3">
+ <thead>
+ <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry></row>
+ </thead>
- <para>
- Example:
-<screen><![CDATA[
-SELECT xmlconcat('<?xml version="1.1"?><foo/>', '<?xml version="1.1" standalone="no"?><bar/>');
+ <tbody>
+ <row>
+ <entry>
+ <literal><function>current_setting</function>(<parameter>setting_name</parameter>)</literal>
+ </entry>
+ <entry><type>text</type></entry>
+ <entry>current value of setting</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>set_config(<parameter>setting_name</parameter>,
+ <parameter>new_value</parameter>,
+ <parameter>is_local</parameter>)</function></literal>
+ </entry>
+ <entry><type>text</type></entry>
+ <entry>set parameter and return new value</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
- xmlconcat
------------------------------------
- <?xml version="1.1"?><foo/><bar/>
-]]></screen>
- </para>
- </sect3>
-
- <sect3>
- <title><literal>xmlelement</literal></title>
-
- <indexterm>
- <primary>xmlelement</primary>
+ <indexterm zone="functions-admin">
+ <primary>SET</primary>
</indexterm>
-
-<synopsis>
- <function>xmlelement</function>(name <replaceable>name</replaceable> <optional>, xmlattributes(<replaceable>value</replaceable> <optional>AS <replaceable>attname</replaceable></optional> <optional>, ... </optional>)</optional> <optional><replaceable>, content, ...</replaceable></optional>)
- </synopsis>
-
- <para>
- The <function>xmlelement</function> expression produces an XML
- element with the given name, attributes, and content.
- </para>
-
- <para>
- Examples:
-<screen><![CDATA[
-SELECT xmlelement(name foo);
-
- xmlelement
-------------
- <foo/>
-SELECT xmlelement(name foo, xmlattributes('xyz' as bar));
-
- xmlelement
-------------------
- <foo bar="xyz"/>
-
-SELECT xmlelement(name foo, xmlattributes(current_date as bar), 'cont', 'ent');
+ <indexterm zone="functions-admin">
+ <primary>SHOW</primary>
+ </indexterm>
- xmlelement
--------------------------------------
- <foo bar="2007-01-26">content</foo>
-]]></screen>
- </para>
+ <indexterm zone="functions-admin">
+ <primary>configuration</primary>
+ <secondary sortas="server">of the server</secondary>
+ <tertiary>functions</tertiary>
+ </indexterm>
- <para>
- Element and attribute names that are not valid XML names are
- escaped by replacing the offending characters by the sequence
- <literal>_x<replaceable>HHHH</replaceable>_</literal>, where
- <replaceable>HHHH</replaceable> is the character's Unicode
- codepoint in hexadecimal notation. For example:
-<screen><![CDATA[
-SELECT xmlelement(name "foo$bar", xmlattributes('xyz' as "a&b"));
+ <para>
+ The function <function>current_setting</function> yields the
+ current value of the setting <parameter>setting_name</parameter>.
+ It corresponds to the <acronym>SQL</acronym> command
+ <command>SHOW</command>. An example:
+<programlisting>
+SELECT current_setting('datestyle');
- xmlelement
-----------------------------------
- <foo_x0024_bar a_x0026_b="xyz"/>
-]]></screen>
- </para>
+ current_setting
+-----------------
+ ISO, MDY
+(1 row)
+</programlisting>
+ </para>
- <para>
- An explicit attribute name need not be specified if the attribute
- value is a column reference, in which case the column's name will
- be used as attribute name by default. In any other case, the
- attribute must be given an explicit name. So this example is
- valid:
-<screen>
-CREATE TABLE test (a xml, b xml);
-SELECT xmlelement(name test, xmlattributes(a, b)) FROM test;
-</screen>
- But these are not:
-<screen>
-SELECT xmlelement(name test, xmlattributes('constant'), a, b) FROM test;
-SELECT xmlelement(name test, xmlattributes(func(a, b))) FROM test;
-</screen>
- </para>
+ <para>
+ <function>set_config</function> sets the parameter
+ <parameter>setting_name</parameter> to
+ <parameter>new_value</parameter>. If
+ <parameter>is_local</parameter> is <literal>true</literal>, the
+ new value will only apply to the current transaction. If you want
+ the new value to apply for the current session, use
+ <literal>false</literal> instead. The function corresponds to the
+ SQL command <command>SET</command>. An example:
+<programlisting>
+SELECT set_config('log_statement_stats', 'off', false);
- <para>
- Element content, if specified, will be formatted according to
- data type. If the content is itself of type <type>xml</type>,
- complex XML documents can be constructed. For example:
-<screen><![CDATA[
-SELECT xmlelement(name foo, xmlattributes('xyz' as bar),
- xmlelement(name abc),
- xmlcomment('test'),
- xmlelement(name xyz));
+ set_config
+------------
+ off
+(1 row)
+</programlisting>
+ </para>
- xmlelement
-----------------------------------------------
- <foo bar="xyz"><abc/><!--test--><xyz/></foo>
-]]></screen>
+ <indexterm zone="functions-admin">
+ <primary>pg_cancel_backend</primary>
+ </indexterm>
+ <indexterm zone="functions-admin">
+ <primary>pg_reload_conf</primary>
+ </indexterm>
+ <indexterm zone="functions-admin">
+ <primary>pg_rotate_logfile</primary>
+ </indexterm>
- Content of other types will be formatted into valid XML character
- data. This means in particular that the characters <, >,
- and & will be converted to entities. Binary data (data type
- <type>bytea</type>) will be represented in base64 or hex
- encoding, depending on the setting of the configuration parameter
- <xref linkend="guc-xmlbinary">. The particular behavior for
- individual data types is expected evolve in order to align the
- SQL and PostgreSQL data types with the XML Schema specification,
- at which point a more precise description will appear.
- </para>
- </sect3>
-
- <sect3>
- <title><literal>xmlforest</literal></title>
-
- <indexterm>
- <primary>xmlforest</primary>
+ <indexterm zone="functions-admin">
+ <primary>signal</primary>
+ <secondary sortas="backend">backend processes</secondary>
</indexterm>
-
- <synopsis>
- <function>xmlforest</function>(<replaceable>content</replaceable> <optional>AS <replaceable>name</replaceable></optional> <optional>, ...</optional>)
- </synopsis>
-
- <para>
- The <function>xmlforest</function> expression produces an XML
- forest (sequence) of elements using the given names and content.
- </para>
- <para>
- Examples:
-<screen><![CDATA[
-SELECT xmlforest('abc' AS foo, 123 AS bar);
+ <para>
+ The functions shown in <xref
+ linkend="functions-admin-signal-table"> send control signals to
+ other server processes. Use of these functions is restricted
+ to superusers.
+ </para>
- xmlforest
-------------------------------
- <foo>abc</foo><bar>123</bar>
+ <table id="functions-admin-signal-table">
+ <title>Server Signalling Functions</title>
+ <tgroup cols="3">
+ <thead>
+ <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal><function>pg_cancel_backend</function>(<parameter>pid</parameter> <type>int</>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>Cancel a backend's current query</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_reload_conf</function>()</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>Cause server processes to reload their configuration files</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_rotate_logfile</function>()</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>Rotate server's log file</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
-SELECT xmlforest(table_name, column_name) FROM information_schema.columns WHERE table_schema = 'pg_catalog';
+ <para>
+ Each of these functions returns <literal>true</literal> if
+ successful and <literal>false</literal> otherwise.
+ </para>
- xmlforest
--------------------------------------------------------------------------------------------
- <table_name>pg_authid</table_name><column_name>rolname</column_name>
- <table_name>pg_authid</table_name><column_name>rolsuper</column_name>
- ...
-]]></screen>
+ <para>
+ <function>pg_cancel_backend</> sends a query cancel
+ (<systemitem>SIGINT</>) signal to a backend process identified by
+ process ID. The process ID of an active backend can be found from
+ the <structfield>procpid</structfield> column in the
+ <structname>pg_stat_activity</structname> view, or by listing the
+ <command>postgres</command> processes on the server with
+ <application>ps</>.
+ </para>
- As seen in the second example, the element name can be omitted if
- the content value is a column reference, in which case the column
- name is used by default. Otherwise, a name must be specified.
- </para>
+ <para>
+ <function>pg_reload_conf</> sends a <systemitem>SIGHUP</> signal
+ to the server, causing the configuration files
+ to be reloaded by all server processes.
+ </para>
- <para>
- Element names that are not valid XML names are escaped as shown
- for <function>xmlelement</function> above. Similarly, content
- data is escaped to make valid XML content, unless it is already
- of type <type>xml</type>.
- </para>
+ <para>
+ <function>pg_rotate_logfile</> signals the log-file manager to switch
+ to a new output file immediately. This works only when
+ <varname>redirect_stderr</> is used for logging, since otherwise there
+ is no log-file manager subprocess.
+ </para>
- <para>
- Note that XML forests are not valid XML documents if they consist
- of more than one element. So it might be useful to wrap
- <function>xmlforest</function> expressions in
- <function>xmlelement</function>.
- </para>
- </sect3>
-
- <sect3>
- <title><literal>xmlpi</literal></title>
-
- <indexterm>
- <primary>xmlpi</primary>
+ <indexterm zone="functions-admin">
+ <primary>pg_start_backup</primary>
</indexterm>
-
- <synopsis>
- <function>xmlpi</function>(name <replaceable>target</replaceable> <optional>, <replaceable>content</replaceable></optional>)
- </synopsis>
-
- <para>
- The <function>xmlpi</function> expression creates an XML
- processing instruction. The content, if present, must not
- contain the character sequence <literal>?></literal>.
- </para>
+ <indexterm zone="functions-admin">
+ <primary>pg_stop_backup</primary>
+ </indexterm>
+ <indexterm zone="functions-admin">
+ <primary>pg_switch_xlog</primary>
+ </indexterm>
+ <indexterm zone="functions-admin">
+ <primary>pg_current_xlog_location</primary>
+ </indexterm>
+ <indexterm zone="functions-admin">
+ <primary>pg_current_xlog_insert_location</primary>
+ </indexterm>
+ <indexterm zone="functions-admin">
+ <primary>pg_xlogfile_name_offset</primary>
+ </indexterm>
+ <indexterm zone="functions-admin">
+ <primary>pg_xlogfile_name</primary>
+ </indexterm>
+ <indexterm zone="functions-admin">
+ <primary>backup</primary>
+ </indexterm>
+
+ <para>
+ The functions shown in <xref
+ linkend="functions-admin-backup-table"> assist in making on-line backups.
+ Use of the first three functions is restricted to superusers.
+ </para>
+
+ <table id="functions-admin-backup-table">
+ <title>Backup Control Functions</title>
+ <tgroup cols="3">
+ <thead>
+ <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>
+ <literal><function>pg_start_backup</function>(<parameter>label</> <type>text</>)</literal>
+ </entry>
+ <entry><type>text</type></entry>
+ <entry>Set up for performing on-line backup</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_stop_backup</function>()</literal>
+ </entry>
+ <entry><type>text</type></entry>
+ <entry>Finish performing on-line backup</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_switch_xlog</function>()</literal>
+ </entry>
+ <entry><type>text</type></entry>
+ <entry>Force switch to a new transaction log file</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_current_xlog_location</function>()</literal>
+ </entry>
+ <entry><type>text</type></entry>
+ <entry>Get current transaction log write location</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_current_xlog_insert_location</function>()</literal>
+ </entry>
+ <entry><type>text</type></entry>
+ <entry>Get current transaction log insert location</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_xlogfile_name_offset</function>(<parameter>location</> <type>text</>)</literal>
+ </entry>
+ <entry><type>text</>, <type>integer</></entry>
+ <entry>Convert transaction log location string to file name and decimal byte offset within file</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_xlogfile_name</function>(<parameter>location</> <type>text</>)</literal>
+ </entry>
+ <entry><type>text</type></entry>
+ <entry>Convert transaction log location string to file name</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
- <para>
- Example:
-<screen><![CDATA[
-SELECT xmlpi(name php, 'echo "hello world";');
+ <para>
+ <function>pg_start_backup</> accepts a single parameter which is an
+ arbitrary user-defined label for the backup. (Typically this would be
+ the name under which the backup dump file will be stored.) The function
+ writes a backup label file into the database cluster's data directory,
+ and then returns the backup's starting transaction log location as text. The user
+ need not pay any attention to this result value, but it is provided in
+ case it is of use.
+<programlisting>
+postgres=# select pg_start_backup('label_goes_here');
+ pg_start_backup
+-----------------
+ 0/D4445B8
+(1 row)
+</programlisting>
+ </para>
- xmlpi
------------------------------
- <?php echo "hello world";?>
-]]></screen>
- </para>
- </sect3>
-
- <sect3>
- <title><literal>xmlroot</literal></title>
-
- <indexterm>
- <primary>xmlroot</primary>
- </indexterm>
-
- <synopsis>
- <function>xmlroot</function>(<replaceable>xml</replaceable>, version <replaceable>text</replaceable>|no value <optional>, standalone yes|no|no value</optional>)
- </synopsis>
-
- <para>
- The <function>xmlroot</function> expression alters the properties
- of the root node of an XML value. If a version is specified,
- this replaces the value in the version declaration, if a
- standalone value is specified, this replaces the value in the
- standalone declaration.
- </para>
+ <para>
+ <function>pg_stop_backup</> removes the label file created by
+ <function>pg_start_backup</>, and instead creates a backup history file in
+ the transaction log archive area. The history file includes the label given to
+ <function>pg_start_backup</>, the starting and ending transaction log locations for
+ the backup, and the starting and ending times of the backup. The return
+ value is the backup's ending transaction log location (which again might be of little
+ interest). After noting the ending location, the current transaction log insertion
+ point is automatically advanced to the next transaction log file, so that the
+ ending transaction log file can be archived immediately to complete the backup.
+ </para>
- <para>
-<screen><![CDATA[
-SELECT xmlroot(xmlparse(document '<?xml version="1.1"?><content>abc</content>'), version '1.0', standalone yes);
+ <para>
+ <function>pg_switch_xlog</> moves to the next transaction log file, allowing the
+ current file to be archived (assuming you are using continuous archiving).
+ The result is the ending transaction log location within the just-completed transaction log file.
+ If there has been no transaction log activity since the last transaction log switch,
+ <function>pg_switch_xlog</> does nothing and returns the end location
+ of the previous transaction log file.
+ </para>
- xmlroot
-----------------------------------------
- <?xml version="1.0" standalone="yes"?>
- <content>abc</content>
-]]></screen>
- </para>
- </sect3>
+ <para>
+ <function>pg_current_xlog_location</> displays the current transaction log write
+ location in the same format used by the above functions. Similarly
+ <function>pg_current_xlog_insert_location</> displays the current transaction log
+ insertion point. The insertion point is the <quote>logical</> end of transaction log
+ at any instant, while the write location is the end of what has actually
+ been written out from the server's internal buffers. The write location
+ is the end of what can be examined from outside the server, and is usually
+ what you want if you are interested in archiving partially-complete transaction log
+ files. The insertion point is made available primarily for server
+ debugging purposes. These are both read-only operations and do not
+ require superuser permissions.
+ </para>
- <sect3>
- <title>XML Predicates</title>
+ <para>
+ You can use <function>pg_xlogfile_name_offset</> to extract the
+ corresponding transaction log file name and byte offset from the results of any of the
+ above functions. For example:
+<programlisting>
+postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup());
+ file_name | file_offset
+--------------------------+-------------
+ 00000001000000000000000D | 4039624
+(1 row)
+</programlisting>
+ Similarly, <function>pg_xlogfile_name</> extracts just the transaction log file name.
+ When the given transction log location is exactly at an transaction log file boundary, both
+ these functions return the name of the preceding transaction log file.
+ This is usually the desired behavior for managing transaction log archiving
+ behavior, since the preceding file is the last one that currently
+ needs to be archived.
+ </para>
- <indexterm>
- <primary>IS DOCUMENT</primary>
- </indexterm>
+ <para>
+ For details about proper usage of these functions, see
+ <xref linkend="continuous-archiving">.
+ </para>
-<synopsis>
-<replaceable>xml</replaceable> IS DOCUMENT
-</synopsis>
+ <para>
+ The functions shown in <xref linkend="functions-admin-dbsize"> calculate
+ the actual disk space usage of database objects.
+ </para>
- <para>
- The expression <literal>IS DOCUMENT</literal> returns true if the
- argument XML value is a proper XML document, false if it is not
- (that is, it is a content fragment), or null if the argument is
- null. See <xref linkend="datatype-xml"> about the difference
- between documents and content fragments.
- </para>
- </sect3>
- </sect2>
+ <indexterm zone="functions-admin">
+ <primary>pg_column_size</primary>
+ </indexterm>
+ <indexterm zone="functions-admin">
+ <primary>pg_database_size</primary>
+ </indexterm>
+ <indexterm zone="functions-admin">
+ <primary>pg_relation_size</primary>
+ </indexterm>
+ <indexterm zone="functions-admin">
+ <primary>pg_size_pretty</primary>
+ </indexterm>
+ <indexterm zone="functions-admin">
+ <primary>pg_tablespace_size</primary>
+ </indexterm>
+ <indexterm zone="functions-admin">
+ <primary>pg_total_relation_size</primary>
+ </indexterm>
- <sect2>
- <title>Mapping Tables to XML</title>
+ <table id="functions-admin-dbsize">
+ <title>Database Object Size Functions</title>
+ <tgroup cols="3">
+ <thead>
+ <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry>
+ </row>
+ </thead>
- <para>
- The following functions map the contents of relational tables to
- XML values. They can be thought of as XML export functionality.
-<synopsis>
-table_to_xml(tbl regclass, nulls boolean, tableforest boolean, targetns text)
-query_to_xml(query text, nulls boolean, tableforest boolean, targetns text)
-cursor_to_xml(cursor refcursor, count int, nulls boolean, tableforest boolean, targetns text)
-</synopsis>
- The return type of each function is <type>xml</type>.
+ <tbody>
+ <row>
+ <entry><function>pg_column_size</function>(<type>any</type>)</entry>
+ <entry><type>int</type></entry>
+ <entry>Number of bytes used to store a particular value (possibly compressed)</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_database_size</function>(<type>oid</type>)</literal>
+ </entry>
+ <entry><type>bigint</type></entry>
+ <entry>Disk space used by the database with the specified OID</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_database_size</function>(<type>name</type>)</literal>
+ </entry>
+ <entry><type>bigint</type></entry>
+ <entry>Disk space used by the database with the specified name</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_relation_size</function>(<type>oid</type>)</literal>
+ </entry>
+ <entry><type>bigint</type></entry>
+ <entry>Disk space used by the table or index with the specified OID</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_relation_size</function>(<type>text</type>)</literal>
+ </entry>
+ <entry><type>bigint</type></entry>
+ <entry>
+ Disk space used by the table or index with the specified name.
+ The table name can be qualified with a schema name
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_size_pretty</function>(<type>bigint</type>)</literal>
+ </entry>
+ <entry><type>text</type></entry>
+ <entry>Converts a size in bytes into a human-readable format with size units</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_tablespace_size</function>(<type>oid</type>)</literal>
+ </entry>
+ <entry><type>bigint</type></entry>
+ <entry>Disk space used by the tablespace with the specified OID</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_tablespace_size</function>(<type>name</type>)</literal>
+ </entry>
+ <entry><type>bigint</type></entry>
+ <entry>Disk space used by the tablespace with the specified name</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_total_relation_size</function>(<type>oid</type>)</literal>
+ </entry>
+ <entry><type>bigint</type></entry>
+ <entry>
+ Total disk space used by the table with the specified OID,
+ including indexes and toasted data
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_total_relation_size</function>(<type>text</type>)</literal>
+ </entry>
+ <entry><type>bigint</type></entry>
+ <entry>
+ Total disk space used by the table with the specified name,
+ including indexes and toasted data. The table name can be
+ qualified with a schema name
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <function>pg_column_size</> shows the space used to store any individual
+ data value.
</para>
<para>
- <function>table_to_xml</function> maps the content of the named
- table, passed as parameter <parameter>tbl</parameter>. The
- <type>regclass</type> accepts strings identifying tables using the
- usual notation, including optional schema qualifications and
- double quotes. <function>query_to_xml</function> executes the
- query whose text is passed as parameter
- <parameter>query</parameter> and maps the result set.
- <function>cursor_to_xml</function> fetches the indicated number of
- rows from the cursor specified by the parameter
- <parameter>cursor</parameter>. This variant is recommendable if
- large tables have to be mapped, because the result value is built
- up in memory by each function.
+ <function>pg_database_size</function> and <function>pg_tablespace_size</>
+ accept the OID or name of a database or tablespace, and return the total
+ disk space used therein.
</para>
<para>
- If <parameter>tableforest</parameter> is false, then the resulting
- XML document looks like this:
-<screen><![CDATA[
-<tablename>
- <row>
- <columnname1>data</columnname1>
- <columnname2>data</columnname2>
- </row>
+ <function>pg_relation_size</> accepts the OID or name of a table, index or
+ toast table, and returns the size in bytes.
+ </para>
- <row>
- ...
- </row>
+ <para>
+ <function>pg_size_pretty</> can be used to format the result of one of
+ the other functions in a human-readable way, using kB, MB, GB or TB as
+ appropriate.
+ </para>
- ...
-</tablename>
-]]></screen>
+ <para>
+ <function>pg_total_relation_size</> accepts the OID or name of a
+ table or toast table, and returns the size in bytes of the data
+ and all associated indexes and toast tables.
+ </para>
- If <parameter>tableforest</parameter> is true, the result is an
- XML content fragment that looks like this:
-<screen><![CDATA[
-<tablename>
- <columnname1>data</columnname1>
- <columnname2>data</columnname2>
-</tablename>
+ <para>
+ The functions shown in <xref
+ linkend="functions-admin-genfile"> provide native file access to
+ files on the machine hosting the server. Only files within the
+ database cluster directory and the <varname>log_directory</> can be
+ accessed. Use a relative path for files within the cluster directory,
+ and a path matching the <varname>log_directory</> configuration setting
+ for log files. Use of these functions is restricted to superusers.
+ </para>
-<tablename>
- ...
-</tablename>
+ <table id="functions-admin-genfile">
+ <title>Generic File Access Functions</title>
+ <tgroup cols="3">
+ <thead>
+ <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry>
+ </row>
+ </thead>
-...
-]]></screen>
+ <tbody>
+ <row>
+ <entry>
+ <literal><function>pg_ls_dir</function>(<parameter>dirname</> <type>text</>)</literal>
+ </entry>
+ <entry><type>setof text</type></entry>
+ <entry>List the contents of a directory</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_read_file</function>(<parameter>filename</> <type>text</>, <parameter>offset</> <type>bigint</>, <parameter>length</> <type>bigint</>)</literal>
+ </entry>
+ <entry><type>text</type></entry>
+ <entry>Return the contents of a text file</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_stat_file</function>(<parameter>filename</> <type>text</>)</literal>
+ </entry>
+ <entry><type>record</type></entry>
+ <entry>Return information about a file</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
- If no table name is avaible, that is, when mapping a query or a
- cursor, the string <literal>table</literal> is used in the first
- format, <literal>row</literal> in the second format.
+ <indexterm zone="functions-admin">
+ <primary>pg_ls_dir</primary>
+ </indexterm>
+ <para>
+ <function>pg_ls_dir</> returns all the names in the specified
+ directory, except the special entries <quote><literal>.</></> and
+ <quote><literal>..</></>.
</para>
+ <indexterm zone="functions-admin">
+ <primary>pg_read_file</primary>
+ </indexterm>
<para>
- The choice between these formats is up to the user. The first
- format is a proper XML document, which will be important in many
- applications. The second format tends to be more useful in the
- <function>cursor_to_xml</function> function if the result values are to be
- reassembled into one document later on. The functions for
- producing XML content discussed above, in particular
- <function>xmlelement</function>, can be used to alter the results
- to taste.
+ <function>pg_read_file</> returns part of a text file, starting
+ at the given <parameter>offset</>, returning at most <parameter>length</>
+ bytes (less if the end of file is reached first). If <parameter>offset</>
+ is negative, it is relative to the end of the file.
</para>
+ <indexterm zone="functions-admin">
+ <primary>pg_stat_file</primary>
+ </indexterm>
<para>
- The data values are mapping in the same way as described for the
- function <function>xmlelement</function> above.
+ <function>pg_stat_file</> returns a record containing the file
+ size, last accessed time stamp, last modified time stamp,
+ last file status change time stamp (Unix platforms only),
+ file creation time stamp (Windows only), and a <type>boolean</type>
+ indicating if it is a directory. Typical usages include:
+<programlisting>
+SELECT * FROM pg_stat_file('filename');
+SELECT (pg_stat_file('filename')).modification;
+</programlisting>
</para>
<para>
- The parameter <parameter>nulls</parameter> determines whether null
- values should be included in the output. If true, null values in
- columns are represented as
-<screen><![CDATA[
-<columnname xsi:nil="true"/>
-]]></screen>
- where <literal>xsi</literal> is the XML namespace prefix for XML
- Schema Instance. An appropriate namespace declaration will be
- added to the result value. If false, columns containing null
- values are simply omitted from the output.
+ The functions shown in <xref linkend="functions-advisory-locks"> manage
+ advisory locks. For details about proper usage of these functions, see
+ <xref linkend="advisory-locks">.
</para>
- <para>
- The parameter <parameter>targetns</parameter> specifies the
- desired XML namespace of the result. If no particular namespace
- is wanted, an empty string should be passed.
- </para>
+ <table id="functions-advisory-locks">
+ <title>Advisory Lock Functions</title>
+ <tgroup cols="3">
+ <thead>
+ <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>
+ <literal><function>pg_advisory_lock</function>(<parameter>key</> <type>bigint</>)</literal>
+ </entry>
+ <entry><type>void</type></entry>
+ <entry>Obtain exclusive advisory lock</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_advisory_lock</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
+ </entry>
+ <entry><type>void</type></entry>
+ <entry>Obtain exclusive advisory lock</entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal><function>pg_advisory_lock_shared</function>(<parameter>key</> <type>bigint</>)</literal>
+ </entry>
+ <entry><type>void</type></entry>
+ <entry>Obtain shared advisory lock</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_advisory_lock_shared</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
+ </entry>
+ <entry><type>void</type></entry>
+ <entry>Obtain shared advisory lock</entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal><function>pg_try_advisory_lock</function>(<parameter>key</> <type>bigint</>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>Obtain exclusive advisory lock if available</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_try_advisory_lock</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>Obtain exclusive advisory lock if available</entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal><function>pg_try_advisory_lock_shared</function>(<parameter>key</> <type>bigint</>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>Obtain shared advisory lock if available</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_try_advisory_lock_shared</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>Obtain shared advisory lock if available</entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal><function>pg_advisory_unlock</function>(<parameter>key</> <type>bigint</>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>Release an exclusive advisory lock</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_advisory_unlock</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>Release an exclusive advisory lock</entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal><function>pg_advisory_unlock_shared</function>(<parameter>key</> <type>bigint</>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>Release a shared advisory lock</entry>
+ </row>
+ <row>
+ <entry>
+ <literal><function>pg_advisory_unlock_shared</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>Release a shared advisory lock</entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal><function>pg_advisory_unlock_all</function>()</literal>
+ </entry>
+ <entry><type>void</type></entry>
+ <entry>Release all advisory locks held by the current session</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+ <indexterm zone="functions-admin">
+ <primary>pg_advisory_lock</primary>
+ </indexterm>
<para>
- The following functions return XML Schema documents describing the
- mappings made by the data mappings produced by the corresponding
- functions above.
-<synopsis>
-table_to_xmlschema(tbl regclass, nulls boolean, tableforest boolean, targetns text)
-query_to_xmlschema(query text, nulls boolean, tableforest boolean, targetns text)
-cursor_to_xmlschema(cursor refcursor, nulls boolean, tableforest boolean, targetns text)
-</synopsis>
- It is essential that the same parameters are passed in order to
- obtain matching XML data mappings and XML Schema documents.
+ <function>pg_advisory_lock</> locks an application-defined resource,
+ which can be identified either by a single 64-bit key value or two
+ 32-bit key values (note that these two key spaces do not overlap). If
+ another session already holds a lock on the same resource, the
+ function will wait until the resource becomes available. The lock
+ is exclusive. Multiple lock requests stack, so that if the same resource
+ is locked three times it must be also unlocked three times to be
+ released for other sessions' use.
</para>
+ <indexterm zone="functions-admin">
+ <primary>pg_advisory_lock_shared</primary>
+ </indexterm>
<para>
- The following functions produce XML data mappings and the
- corresponding XML Schema in one document (or forest), linked
- together. They can be useful where self-contained and
- self-describing results are wanted.
-<synopsis>
-table_to_xml_and_xmlschema(tbl regclass, nulls boolean, tableforest boolean, targetns text)
-query_to_xml_and_xmlschema(query text, nulls boolean, tableforest boolean, targetns text)
-</synopsis>
+ <function>pg_advisory_lock_shared</> works the same as
+ <function>pg_advisory_lock</>,
+ except the lock can be shared with other sessions requesting shared locks.
+ Only would-be exclusive lockers are locked out.
</para>
+ <indexterm zone="functions-admin">
+ <primary>pg_try_advisory_lock</primary>
+ </indexterm>
<para>
- In addition, the following functions are available to produce
- analogous mappings of entire schemas or the entire current
- database.
-<synopsis>
-schema_to_xml(schema name, nulls boolean, tableforest boolean, targetns text)
-schema_to_xmlschema(schema name, nulls boolean, tableforest boolean, targetns text)
-schema_to_xml_and_xmlschema(schema name, nulls boolean, tableforest boolean, targetns text)
-
-database_to_xml(nulls boolean, tableforest boolean, targetns text)
-database_to_xmlschema(nulls boolean, tableforest boolean, targetns text)
-database_to_xml_and_xmlschema(nulls boolean, tableforest boolean, targetns text)
-</synopsis>
-
- Note that these potentially produce a lot of data, which needs to
- be built up in memory. When requesting content mappings of large
- schemas or databases, it may be worthwhile to consider mapping the
- tables separately instead, possibly even through a cursor.
+ <function>pg_try_advisory_lock</> is similar to
+ <function>pg_advisory_lock</>, except the function will not wait for the
+ lock to become available. It will either obtain the lock immediately and
+ return <literal>true</>, or return <literal>false</> if the lock cannot be
+ acquired now.
</para>
+ <indexterm zone="functions-admin">
+ <primary>pg_try_advisory_lock_shared</primary>
+ </indexterm>
<para>
- The result of a schema content mapping looks like this:
-
-<screen><![CDATA[
-<schemaname>
-
-table1-mapping
-
-table2-mapping
-
-...
-
-</schemaname>]]></screen>
-
- where the format of a table mapping depends on the
- <parameter>tableforest</parameter> parameter as explained above.
+ <function>pg_try_advisory_lock_shared</> works the same as
+ <function>pg_try_advisory_lock</>, except it attempts to acquire
+ shared rather than exclusive lock.
</para>
+ <indexterm zone="functions-admin">
+ <primary>pg_advisory_unlock</primary>
+ </indexterm>
<para>
- The result of a database content mapping looks like this:
-
-<screen><![CDATA[
-<dbname>
-
-<schema1name>
- ...
-</schema1name>
-
-<schema2name>
- ...
-</schema2name>
-
-...
-
-</dbname>]]></screen>
-
- where the schema mapping is as above.
+ <function>pg_advisory_unlock</> will release a previously-acquired
+ exclusive advisory lock. It
+ will return <literal>true</> if the lock is successfully released.
+ If the lock was in fact not held, it will return <literal>false</>,
+ and in addition, an SQL warning will be raised by the server.
</para>
+ <indexterm zone="functions-admin">
+ <primary>pg_advisory_unlock_shared</primary>
+ </indexterm>
<para>
- As an example for using the output produced by these functions,
- <xref linkend="xslt-xml-html"> shows an XSLT stylesheet that
- converts the output of
- <function>table_to_xml_and_xmlschema</function> to an HTML
- document containing a tabular rendition of the table data. In a
- similar manner, the result data of these functions can be
- converted into other XML-based formats.
+ <function>pg_advisory_unlock_shared</> works the same as
+ <function>pg_advisory_unlock</>,
+ except to release a shared advisory lock.
</para>
- <figure id="xslt-xml-html">
- <title>XSLT stylesheet for converting SQL/XML output to HTML</title>
-<programlisting><![CDATA[
-<?xml version="1.0"?>
-<xsl:stylesheet version="1.0"
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns="http://www.w3.org/1999/xhtml"
->
-
- <xsl:output method="xml"
- doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
- doctype-public="-//W3C/DTD XHTML 1.0 Strict//EN"
- indent="yes"/>
-
- <xsl:template match="/*">
- <xsl:variable name="schema" select="//xsd:schema"/>
- <xsl:variable name="tabletypename"
- select="$schema/xsd:element[@name=name(current())]/@type"/>
- <xsl:variable name="rowtypename"
- select="$schema/xsd:complexType[@name=$tabletypename]/xsd:sequence/xsd:element[@name='row']/@type"/>
-
- <html>
- <head>
- <title><xsl:value-of select="name(current())"/></title>
- </head>
- <body>
- <table>
- <tr>
- <xsl:for-each select="$schema/xsd:complexType[@name=$rowtypename]/xsd:sequence/xsd:element/@name">
- <th><xsl:value-of select="."/></th>
- </xsl:for-each>
- </tr>
-
- <xsl:for-each select="row">
- <tr>
- <xsl:for-each select="*">
- <td><xsl:value-of select="."/></td>
- </xsl:for-each>
- </tr>
- </xsl:for-each>
- </table>
- </body>
- </html>
- </xsl:template>
-
-</xsl:stylesheet>
-]]></programlisting>
- </figure>
- </sect2>
-
- <sect2>
- <title>Processing XML</title>
-
+ <indexterm zone="functions-admin">
+ <primary>pg_advisory_unlock_all</primary>
+ </indexterm>
<para>
- <acronym>XML</> support is not just the existence of an
- <type>xml</type> data type, but a variety of features supported by
- a database system. These capabilities include import/export,
- indexing, searching, transforming, and <acronym>XML</> to
- <acronym>SQL</> mapping. <productname>PostgreSQL</> supports some
- but not all of these <acronym>XML</> capabilities. For an
- overview of <acronym>XML</> use in databases, see <ulink
- url="http://www.rpbourret.com/xml/XMLAndDatabases.htm"></>.
+ <function>pg_advisory_unlock_all</> will release all advisory locks
+ held by the current session. (This function is implicitly invoked
+ at session end, even if the client disconnects ungracefully.)
</para>
- <variablelist>
- <varlistentry>
- <term>Indexing</term>
- <listitem>
-
- <para>
- <filename>contrib/xml2/</> functions can be used in expression
- indexes to index specific <acronym>XML</> fields. To index the
- full contents of <acronym>XML</> documents, the full-text
- indexing tool <filename>contrib/tsearch2/</> can be used. Of
- course, Tsearch2 indexes have no <acronym>XML</> awareness so
- additional <filename>contrib/xml2/</> checks should be added to
- queries.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>Searching</term>
- <listitem>
-
- <para>
- XPath searches are implemented using <filename>contrib/xml2/</>.
- It processes <acronym>XML</> text documents and returns results
- based on the requested query.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>Transforming</term>
- <listitem>
-
- <para>
- <filename>contrib/xml2/</> supports <acronym>XSLT</> (Extensible
- Stylesheet Language Transformation).
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>XML to SQL Mapping</term>
- <listitem>
+ </sect1>
- <para>
- This involves converting <acronym>XML</> data to and from
- relational structures. <productname>PostgreSQL</> has no
- internal support for such mapping, and relies on external tools
- to do such conversions.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </sect2>
- </sect1>
</chapter>