diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 07d1a879b3ff83c31d8ae6903328ca8537671905..57a618faa6fd849efc940d96f09a3ae0894f3b01 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.118 2007/03/26 01:41:57 tgl Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.119 2007/04/02 15:27:02 petere Exp $ --> <chapter Id="runtime-config"> <title>Server Configuration</title> @@ -3591,7 +3591,7 @@ SELECT * FROM parent WHERE key = 2400; <primary><varname>SET XML OPTION</></primary> </indexterm> <indexterm> - <primary><varname>XML option</></primary> + <primary>XML option</primary> </indexterm> <listitem> <para> diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml index 1bf103c8780e21949bbe5c3b9fc96e61c322a10a..9e95f95f011d70c14e22e1853a0a65b7c3af93f2 100644 --- a/doc/src/sgml/datatype.sgml +++ b/doc/src/sgml/datatype.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.192 2007/04/02 03:49:36 tgl Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.193 2007/04/02 15:27:02 petere Exp $ --> <chapter id="datatype"> <title id="datatype-title">Data Types</title> @@ -3190,6 +3190,144 @@ SELECT * FROM test; </sect1> + <sect1 id="datatype-xml"> + <title><acronym>XML</> Type</title> + + <indexterm zone="datatype-xml"> + <primary>XML</primary> + </indexterm> + + <para> + The data type <type>xml</type> can be used to store XML data. Its + advantage over storing XML data in a <type>text</type> field is that it + checks the input values for well-formedness, and there are support + functions to perform type-safe operations on it; see <xref + linkend="functions-xml">. + </para> + + <para> + In particular, the <type>xml</type> type can store well-formed + <quote>documents</quote>, as defined by the XML standard, as well + as <quote>content</quote> fragments, which are defined by the + production <literal>XMLDecl? content</literal> in the XML + standard. Roughly, this means that content fragments can have + more than one top-level element or character node. The expression + <literal><replaceable>xmlvalue</replaceable> IS DOCUMENT</literal> + can be used to evaluate whether a particular <type>xml</type> + value is a full document or only a content fragment. + </para> + + <para> + To produce a value of type <type>xml</type> from character data, + use the function + <function>xmlparse</function>:<indexterm><primary>xmlparse</primary></indexterm> +<synopsis> +XMLPARSE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable>) +</synopsis> + Examples: +<programlisting><![CDATA[ +XMLPARSE (DOCUMENT '<?xml version="1.0"?><book><title>Manual</title><chapter>...</chapter><book>') +XMLPARSE (CONTENT 'abc<foo>bar</bar><bar>foo</foo>') +]]></programlisting> + While this is the only way to convert character strings into XML + values according to the SQL standard, the PostgreSQL-specific + syntaxes: +<programlisting><![CDATA[ +xml '<foo>bar</foo>' +'<foo>bar</foo>'::xml +]]></programlisting> + can also be used. + </para> + + <para> + The <type>xml</type> type does not validate its input values + against a possibly included document type declaration + (DTD).<indexterm><primary>DTD</primary></indexterm> + </para> + + <para> + The inverse operation, producing character string type values from + <type>xml</type>, uses the function + <function>xmlserialize</function>:<indexterm><primary>xmlserialize</primary></indexterm> +<synopsis> +XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <replaceable>type</replaceable> ) +</synopsis> + <replaceable>type</replaceable> can be one of + <type>character</type>, <type>character varying</type>, or + <type>text</type> (or an alias name for those). Again, according + to the SQL standard, this is the only way to convert between type + <type>xml</type> and character types, but PostgreSQL also allows + you to simply cast the value. + </para> + + <para> + When character string values are cast to or from type + <type>xml</type> without going through <type>XMLPARSE</type> or + <type>XMLSERIALIZE</type>, respectively, the choice of + <literal>DOCUMENT</literal> versus <literal>CONTENT</literal> is + determined by the <quote>XML option</quote> + <indexterm><primary>XML option</primary></indexterm> + session configuration parameter, which can be set using the + standard command +<synopsis> +SET XML OPTION { DOCUMENT | CONTENT }; +</synopsis> + or the more PostgreSQL-like syntax +<synopsis> +SET xmloption TO { DOCUMENT | CONTENT }; +</synopsis> + The default is <literal>CONTENT</literal>, so all forms of XML + data are allowed. + </para> + + <para> + Care must be taken when dealing with multiple character encodings + on the client, server, and in the XML data passed through them. + When using the text mode to pass queries to the server and query + results to the client (which is the normal mode), PostgreSQL + converts all character data passed between the client and the + server and vice versa to the character encoding of the respective + end; see <xref linkend="multibyte">. This includes string + representations of XML values, such as in the above examples. + This would ordinarily mean that encoding declarations contained in + XML data might become invalid as the character data is converted + to other encodings while travelling between client and server, + while the embedded encoding declaration is not changed. To cope + with this behavior, an encoding declaration contained in a + character string presented for input to the <type>xml</type> type + is <emphasis>ignored</emphasis>, and the content is always assumed + to be in the current server encoding. Consequently, for correct + processing, such character strings of XML data must be sent off + from the client in the current client encoding. It is the + responsibility of the client to either convert the document to the + current client encoding before sending it off to the server or to + adjust the client encoding appropriately. On output, values of + type <type>xml</type> will not have an encoding declaration, and + clients must assume that the data is in the current client + encoding. + </para> + + <para> + When using the binary mode to pass query parameters to the server + and query results back the the client, no character set conversion + is performed, so the situation is different. In this case, an + encoding declaration in the XML data will be observed, and if it + is absent, the data will be assumed to be in UTF-8 (as required by + the XML standard; note that PostgreSQL does not support UTF-16 at + all). On output, data will have an encoding declaration + specifying the client encoding, unless the client encoding is + UTF-8, in which case it will be omitted. + </para> + + <para> + Needless to say, processing XML data with PostgreSQL will be less + error-prone and more efficient if data encoding, client encoding, + and server encoding are the same. Since XML data is internally + processed in UTF-8, computations will be most efficient if the + server encoding is also UTF-8. + </para> + </sect1> + &array; &rowtypes; @@ -3579,138 +3717,4 @@ SELECT * FROM pg_attribute </sect1> - <sect1 id="datatype-xml"> - <title><acronym>XML</> Type</title> - - <indexterm zone="datatype-xml"> - <primary>XML</primary> - </indexterm> - - <para> - The data type <type>xml</type> can be used to store XML data. Its - advantage over storing XML data in a <type>text</type> field is that it - checks the input values for well-formedness, and there are support - functions to perform type-safe operations on it; see <xref - linkend="functions-xml">. - </para> - - <para> - In particular, the <type>xml</type> type can store well-formed - <quote>documents</quote>, as defined by the XML standard, as well - as <quote>content</quote> fragments, which are defined by the - production <literal>XMLDecl? content</literal> in the XML - standard. Roughly, this means that content fragments can have - more than one top-level element or character node. The expression - <literal><replaceable>xmlvalue</replaceable> IS DOCUMENT</literal> - can be used to evaluate whether a particular <type>xml</type> - value is a full document or only a content fragment. - </para> - - <para> - To produce a value of type <type>xml</type> from character data, - use the function <function>xmlparse</function>: -<synopsis> -XMLPARSE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable>) -</synopsis> - Examples: -<programlisting><![CDATA[ -XMLPARSE (DOCUMENT '<?xml version="1.0"?><book><title>Manual</title><chapter>...</chapter><book>') -XMLPARSE (CONTENT 'abc<foo>bar</bar><bar>foo</foo>') -]]></programlisting> - While this is the only way to convert character strings into XML - values according to the SQL standard, the PostgreSQL-specific - syntaxes: -<programlisting><![CDATA[ -xml '<foo>bar</foo>' -'<foo>bar</foo>'::xml -]]></programlisting> - can also be used. - </para> - - <para> - The <type>xml</type> type does not validate its input values - against a possibly included document type declaration (DTD). - </para> - - <para> - The inverse operation, producing character string type values from - <type>xml</type>, uses the function - <function>xmlserialize</function>: -<synopsis> -XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <replaceable>type</replaceable> ) -</synopsis> - <replaceable>type</replaceable> can be one of - <type>character</type>, <type>character varying</type>, or - <type>text</type> (or an alias name for those). Again, according - to the SQL standard, this is the only way to convert between type - <type>xml</type> and character types, but PostgreSQL also allows - you to simply cast the value. - </para> - - <para> - When character string values are cast to or from type - <type>xml</type> without going through <type>XMLPARSE</type> or - <type>XMLSERIALIZE</type>, respectively, the choice of - <literal>DOCUMENT</literal> versus <literal>CONTENT</literal> is - determined by the <quote>XML option</quote> session configuration - parameter, which can be set using the standard command -<synopsis> -SET XML OPTION { DOCUMENT | CONTENT }; -</synopsis> - or the more PostgreSQL-like syntax -<synopsis> -SET xmloption TO { DOCUMENT | CONTENT }; -</synopsis> - The default is <literal>CONTENT</literal>, so all forms of XML - data are allowed. - </para> - - <para> - Care must be taken when dealing with multiple character encodings - on the client, server, and in the XML data passed through them. - When using the text mode to pass queries to the server and query - results to the client (which is the normal mode), PostgreSQL - converts all character data passed between the client and the - server and vice versa to the character encoding of the respective - end; see <xref linkend="multibyte">. This includes string - representations of XML values, such as in the above examples. - This would ordinarily mean that encoding declarations contained in - XML data might become invalid as the character data is converted - to other encodings while travelling between client and server, - while the embedded encoding declaration is not changed. To cope - with this behavior, an encoding declaration contained in a - character string presented for input to the <type>xml</type> type - is <emphasis>ignored</emphasis>, and the content is always assumed - to be in the current server encoding. Consequently, for correct - processing, such character strings of XML data must be sent off - from the client in the current client encoding. It is the - responsibility of the client to either convert the document to the - current client encoding before sending it off to the server or to - adjust the client encoding appropriately. On output, values of - type <type>xml</type> will not have an encoding declaration, and - clients must assume that the data is in the current client - encoding. - </para> - - <para> - When using the binary mode to pass query parameters to the server - and query results back the the client, no character set conversion - is performed, so the situation is different. In this case, an - encoding declaration in the XML data will be observed, and if it - is absent, the data will be assumed to be in UTF-8 (as required by - the XML standard; note that PostgreSQL does not support UTF-16 at - all). On output, data will have an encoding declaration - specifying the client encoding, unless the client encoding is - UTF-8, in which case it will be omitted. - </para> - - <para> - Needless to say, processing XML data with PostgreSQL will be less - error-prone and more efficient if data encoding, client encoding, - and server encoding are the same. Since XML data is internally - processed in UTF-8, computations will be most efficient if the - server encoding is also UTF-8. - </para> - </sect1> - </chapter> diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 0baf1525944cce736ca069d13beb9f1c62bfddca..cc872d8234f42c7a0e218700c24baeaac24bc0ad 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -1,4 +1,4 @@ -<!-- $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> @@ -7502,4302 +7502,4308 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple </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>