<!--
-$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.214 2004/07/12 20:23:47 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.215 2004/08/03 20:32:31 tgl Exp $
PostgreSQL documentation
-->
</sect1>
- <sect1 id="functions-misc">
- <title>Miscellaneous Functions</title>
+ <sect1 id="functions-array">
+ <title>Array Functions and Operators</title>
<para>
- <xref linkend="functions-misc-session-table"> shows several
- functions that extract session and system information.
+ <xref linkend="array-operators-table"> shows the operators
+ available for <type>array</type> types.
</para>
- <table id="functions-misc-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><function>current_database()</function></entry>
- <entry><type>name</type></entry>
- <entry>name of current database</entry>
- </row>
-
- <row>
- <entry><function>current_schema()</function></entry>
- <entry><type>name</type></entry>
- <entry>name of current schema</entry>
- </row>
-
- <row>
- <entry><function>current_schemas(boolean)</function></entry>
- <entry><type>name[]</type></entry>
- <entry>names of schemas in search path optionally including implicit schemas</entry>
- </row>
-
- <row>
- <entry><function>current_user</function></entry>
- <entry><type>name</type></entry>
- <entry>user name of current execution context</entry>
- </row>
-
- <row>
- <entry><function>inet_client_addr()</function></entry>
- <entry><type>inet</type></entry>
- <entry>address of the remote connection</entry>
- </row>
-
- <row>
- <entry><function>inet_client_port()</function></entry>
- <entry><type>int4</type></entry>
- <entry>port of the remote connection</entry>
- </row>
-
- <row>
- <entry><function>inet_server_addr()</function></entry>
- <entry><type>inet</type></entry>
- <entry>address of the local connection</entry>
- </row>
-
- <row>
- <entry><function>inet_server_port()</function></entry>
- <entry><type>int4</type></entry>
- <entry>port of the local connection</entry>
- </row>
-
- <row>
- <entry><function>session_user</function></entry>
- <entry><type>name</type></entry>
- <entry>session user name</entry>
- </row>
-
- <row>
- <entry><function>user</function></entry>
- <entry><type>name</type></entry>
- <entry>equivalent to <function>current_user</function></entry>
- </row>
-
- <row>
- <entry><function>version()</function></entry>
- <entry><type>text</type></entry>
- <entry>PostgreSQL version information</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <indexterm zone="functions-misc">
- <primary>user</primary>
- <secondary>current</secondary>
- </indexterm>
-
- <indexterm zone="functions-misc">
- <primary>schema</primary>
- <secondary>current</secondary>
- </indexterm>
-
- <indexterm zone="functions-misc">
- <primary>search path</primary>
- <secondary>current</secondary>
- </indexterm>
-
- <para>
- The <function>session_user</function> is the user that initiated a
- database connection; it is fixed for the duration of that
- connection. 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 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>
+ <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>
- <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>
+ <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>
- <note>
- <para>
- The search path may be altered at run time. The command is:
-<programlisting>
-SET search_path TO <replaceable>schema</> <optional>, <replaceable>schema</>, ...</optional>
-</programlisting>
- </para>
- </note>
+ <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>
- <indexterm zone="functions-misc">
- <primary>inet_client_addr</primary>
- </indexterm>
+ <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>
- <indexterm zone="functions-misc">
- <primary>inet_client_port</primary>
- </indexterm>
+ <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 zone="functions-misc">
- <primary>inet_server_addr</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 zone="functions-misc">
- <primary>inet_server_port</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>
- <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 connection is via a Unix-domain
- socket.
- </para>
+ <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 zone="functions-misc">
- <primary>version</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>
- <para>
- <function>version()</function> returns a string describing the
- <productname>PostgreSQL</productname> server's version.
- </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>
- <xref linkend="functions-misc-set-table"> shows the functions
- available to query and alter run-time configuration parameters.
+ See <xref linkend="arrays"> for more details about array operator
+ behavior.
</para>
- <table id="functions-misc-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>
+ <xref linkend="array-functions-table"> shows the functions
+ available for use with array types. See <xref linkend="arrays">
+ for more discussion and examples for the use of these functions.
+ </para>
- <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="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_cat</function>
+ (<type>anyarray</type>, <type>anyarray</type>)
+ </literal>
+ </entry>
+ <entry><type>anyarray</type></entry>
+ <entry>
+ concatenate two arrays, returning <literal>NULL</literal>
+ for <literal>NULL</literal> inputs
+ </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_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, returning
+ <literal>NULL</literal> for <literal>NULL</literal> inputs
+ </entry>
+ <entry><literal>array_append(ARRAY[1,2], 3)</literal></entry>
+ <entry><literal>{1,2,3}</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, returning
+ <literal>NULL</literal> for <literal>NULL</literal> inputs
+ </entry>
+ <entry><literal>array_prepend(1, ARRAY[2,3])</literal></entry>
+ <entry><literal>{1,2,3}</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 dimension lower and upper bounds,
+ generating an ERROR for <literal>NULL</literal> inputs
+ </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>integer</type>)
+ </literal>
+ </entry>
+ <entry><type>integer</type></entry>
+ <entry>
+ returns lower bound of the requested array dimension, returning
+ <literal>NULL</literal> for <literal>NULL</literal> inputs
+ </entry>
+ <entry><literal>array_lower(array_prepend(0, ARRAY[1,2,3]), 1)</literal></entry>
+ <entry><literal>0</literal></entry>
+ </row>
+ <row>
+ <entry>
+ <literal>
+ <function>array_upper</function>
+ (<type>anyarray</type>, <type>integer</type>)
+ </literal>
+ </entry>
+ <entry><type>integer</type></entry>
+ <entry>
+ returns upper bound of the requested array dimension, returning
+ <literal>NULL</literal> for <literal>NULL</literal> inputs
+ </entry>
+ <entry><literal>array_upper(ARRAY[1,2,3,4], 1)</literal></entry>
+ <entry><literal>4</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, returning
+ <literal>NULL</literal> for <literal>NULL</literal> inputs
+ </entry>
+ <entry><literal>array_to_string(array[1, 2, 3], '~^~')</literal></entry>
+ <entry><literal>1~^~2~^~3</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, returning
+ <literal>NULL</literal> for <literal>NULL</literal> inputs
+ </entry>
+ <entry><literal>string_to_array( 'xx~^~yy~^~zz', '~^~')</literal></entry>
+ <entry><literal>{xx,yy,zz}</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
- <indexterm zone="functions-misc">
- <primary>SET</primary>
- </indexterm>
+ <sect1 id="functions-aggregate">
+ <title>Aggregate Functions</title>
+
+ <indexterm zone="functions-aggregate">
+ <primary>aggregate function</primary>
+ <secondary>built-in</secondary>
+ </indexterm>
+
+ <para>
+ <firstterm>Aggregate functions</firstterm> compute a single result
+ value from a set of input values. <xref
+ linkend="functions-aggregate-table"> shows the built-in aggregate
+ functions. The special syntax considerations for aggregate
+ functions are explained in <xref linkend="syntax-aggregates">.
+ Consult <xref linkend="tutorial-agg"> for additional introductory
+ information.
+ </para>
+
+ <table id="functions-aggregate-table">
+ <title>Aggregate Functions</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>average</primary>
+ </indexterm>
+ <function>avg(<replaceable class="parameter">expression</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>smallint</type>, <type>integer</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>
+
+ <row>
+ <entry>
+ <indexterm>
+ <primary>bit_and</primary>
+ </indexterm>
+ <function>bit_and(<replaceable class="parameter">expression</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>smallint</type>, <type>integer</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>integer</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>
+
+ <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>
+
+ <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>
+
+ <row>
+ <entry><function>count(*)</function></entry>
+ <entry></entry>
+ <entry><type>bigint</type></entry>
+ <entry>number of input values</entry>
+ </row>
+
+ <row>
+ <entry><function>count(<replaceable class="parameter">expression</replaceable>)</function></entry>
+ <entry>any</entry>
+ <entry><type>bigint</type></entry>
+ <entry>
+ number of input values for which the value of <replaceable
+ class="parameter">expression</replaceable> is not null
+ </entry>
+ </row>
- <indexterm zone="functions-misc">
- <primary>SHOW</primary>
- </indexterm>
+ <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>
- <indexterm zone="functions-misc">
- <primary>configuration</primary>
- <secondary sortas="server">of the server</secondary>
- <tertiary>functions</tertiary>
- </indexterm>
+ <row>
+ <entry><function>max(<replaceable class="parameter">expression</replaceable>)</function></entry>
+ <entry>any 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>
- <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');
+ <row>
+ <entry><function>min(<replaceable class="parameter">expression</replaceable>)</function></entry>
+ <entry>any 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>
- current_setting
------------------
- ISO, MDY
-(1 row)
-</programlisting>
- </para>
+ <row>
+ <entry>
+ <indexterm>
+ <primary>standard deviation</primary>
+ </indexterm>
+ <function>stddev(<replaceable class="parameter">expression</replaceable>)</function>
+ </entry>
+ <entry>
+ <type>smallint</type>, <type>integer</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>
- <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);
+ <row>
+ <entry><function>sum(<replaceable class="parameter">expression</replaceable>)</function></entry>
+ <entry>
+ <type>smallint</type>, <type>integer</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>integer</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>
- set_config
-------------
- off
-(1 row)
-</programlisting>
- </para>
+ <row>
+ <entry>
+ <indexterm>
+ <primary>variance</primary>
+ </indexterm>
+ <function>variance</function>(<replaceable class="parameter">expression</replaceable>)
+ </entry>
+ <entry>
+ <type>smallint</type>, <type>integer</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>
- <indexterm>
- <primary>privilege</primary>
- <secondary>querying</secondary>
- </indexterm>
+ </tbody>
+ </tgroup>
+ </table>
<para>
- <xref linkend="functions-misc-access-table"> lists functions that
- allow the user to query object access privileges programmatically.
- See <xref linkend="ddl-priv"> for more information about
- privileges.
+ 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 <function>coalesce</function> may be
+ used to substitute zero for null when necessary.
</para>
- <table id="functions-misc-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>
-
- <tbody>
- <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_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_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>
- </tbody>
- </tgroup>
- </table>
-
- <indexterm zone="functions-misc">
- <primary>has_table_privilege</primary>
- </indexterm>
- <indexterm zone="functions-misc">
- <primary>has_database_privilege</primary>
- </indexterm>
- <indexterm zone="functions-misc">
- <primary>has_function_privilege</primary>
- </indexterm>
- <indexterm zone="functions-misc">
- <primary>has_language_privilege</primary>
- </indexterm>
- <indexterm zone="functions-misc">
- <primary>has_schema_privilege</primary>
- </indexterm>
- <indexterm zone="functions-misc">
- <primary>has_tablespace_privilege</primary>
- </indexterm>
+ <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>
- <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 ID
- (<literal>pg_user.usesysid</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>RULE</literal>, <literal>REFERENCES</literal>, or
- <literal>TRIGGER</literal>. (Case of the string is not significant, however.)
- An example is:
+ Users accustomed to working with other SQL database management
+ systems may be surprised by the performance characteristics of
+ certain aggregate functions in
+ <productname>PostgreSQL</productname> when the aggregate is
+ applied to the entire table (in other words, no
+ <literal>WHERE</literal> clause is specified). In particular, a
+ query like
<programlisting>
-SELECT has_table_privilege('myschema.mytable', 'select');
+SELECT min(col) FROM sometable;
</programlisting>
+ will be executed by <productname>PostgreSQL</productname> using a
+ sequential scan of the entire table. Other database systems may
+ optimize queries of this form to use an index on the column, if
+ one is available. Similarly, the aggregate functions
+ <function>max()</function> and <function>count()</function> always
+ require a sequential scan if applied to the entire table in
+ <productname>PostgreSQL</productname>.
</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>TEMPORARY</literal>, or
- <literal>TEMP</literal> (which is equivalent to
- <literal>TEMPORARY</literal>).
+ <productname>PostgreSQL</productname> cannot easily implement this
+ optimization because it also allows for user-defined aggregate
+ queries. Since <function>min()</function>,
+ <function>max()</function>, and <function>count()</function> are
+ defined using a generic API for aggregate functions, there is no
+ provision for special-casing the execution of these functions
+ under certain circumstances.
</para>
<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.
- The desired access privilege type must evaluate to
- <literal>EXECUTE</literal>.
- An example is:
+ Fortunately, there is a simple workaround for
+ <function>min()</function> and <function>max()</function>. The
+ query shown below is equivalent to the query above, except that it
+ can take advantage of a B-tree index if there is one present on
+ the column in question.
<programlisting>
-SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
+SELECT col FROM sometable ORDER BY col ASC LIMIT 1;
</programlisting>
+ A similar query (obtained by substituting <literal>DESC</literal>
+ for <literal>ASC</literal> in the query above) can be used in the
+ place of <function>max()</function>).
</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>.
+ Unfortunately, there is no similarly trivial query that can be
+ used to improve the performance of <function>count()</function>
+ when applied to the entire table.
</para>
+ </note>
- <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>
+ </sect1>
- <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>
- To evaluate 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>
+ <sect1 id="functions-subquery">
+ <title>Subquery Expressions</title>
- <para>
- <xref linkend="functions-misc-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>
+ <indexterm>
+ <primary>EXISTS</primary>
+ </indexterm>
- <table id="functions-misc-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>
+ <indexterm>
+ <primary>IN</primary>
+ </indexterm>
- <tbody>
- <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>
- <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_conversion_is_visible</function>(<parameter>conversion_oid</parameter>)</literal>
- </entry>
- <entry><type>boolean</type></entry>
- <entry>is conversion visible in search path</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
+ <indexterm>
+ <primary>NOT IN</primary>
+ </indexterm>
- <indexterm zone="functions-misc">
- <primary>pg_table_is_visible</primary>
- </indexterm>
- <indexterm zone="functions-misc">
- <primary>pg_type_is_visible</primary>
- </indexterm>
- <indexterm zone="functions-misc">
- <primary>pg_function_is_visible</primary>
- </indexterm>
- <indexterm zone="functions-misc">
- <primary>pg_operator_is_visible</primary>
- </indexterm>
- <indexterm zone="functions-misc">
- <primary>pg_opclass_is_visible</primary>
- </indexterm>
- <indexterm zone="functions-misc">
- <primary>pg_conversion_is_visible</primary>
- </indexterm>
+ <indexterm>
+ <primary>ANY</primary>
+ </indexterm>
- <para>
- <function>pg_table_is_visible</function> performs the check for
- tables (or views, or any other kind of <literal>pg_class</> entry).
- <function>pg_type_is_visible</function>,
- <function>pg_function_is_visible</function>,
- <function>pg_operator_is_visible</function>,
- <function>pg_opclass_is_visible</function>, and
- <function>pg_conversion_is_visible</function> perform the same sort of
- visibility check for types (and domains), functions, operators, operator classes
- and conversions, respectively. 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>
+ <primary>ALL</primary>
+ </indexterm>
- <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>
+ <indexterm>
+ <primary>SOME</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>subquery</primary>
+ </indexterm>
+
+ <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>
+
+ <sect2>
+ <title><literal>EXISTS</literal></title>
+
+<synopsis>
+EXISTS ( <replaceable>subquery</replaceable> )
+</synopsis>
+
+ <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-misc">
- <primary>pg_get_viewdef</primary>
- </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-misc">
- <primary>pg_get_ruledef</primary>
- </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
+ may be difficult to predict.
+ </para>
- <indexterm zone="functions-misc">
- <primary>pg_get_indexdef</primary>
- </indexterm>
+ <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>
- <indexterm zone="functions-misc">
- <primary>pg_get_triggerdef</primary>
- </indexterm>
+ <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>
- <indexterm zone="functions-misc">
- <primary>pg_get_constraintdef</primary>
- </indexterm>
+ <sect2>
+ <title><literal>IN</literal></title>
- <indexterm zone="functions-misc">
- <primary>pg_get_expr</primary>
- </indexterm>
+<synopsis>
+<replaceable>expression</replaceable> IN (<replaceable>subquery</replaceable>)
+</synopsis>
- <indexterm zone="functions-misc">
- <primary>pg_get_userbyid</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-misc">
- <primary>pg_get_serial_sequence</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-misc">
- <primary>pg_tablespace_databases</primary>
- </indexterm>
+ <para>
+ As with <token>EXISTS</token>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </para>
+
+<synopsis>
+<replaceable>row_constructor</replaceable> IN (<replaceable>subquery</replaceable>)
+</synopsis>
<para>
- <xref linkend="functions-misc-catalog-table"> lists functions that
- extract information from the system catalogs.
+ 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>
- <table id="functions-misc-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>
+ 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 row results are either unequal or null, with at least one null,
+ then the result of <token>IN</token> is null.
+ </para>
+ </sect2>
- <tbody>
- <row>
- <entry><literal><function>pg_get_viewdef</function>(<parameter>view_name</parameter>)</literal></entry>
- <entry><type>text</type></entry>
- <entry>get <command>CREATE VIEW</> 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 <command>CREATE VIEW</> 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 <command>CREATE VIEW</> 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 <command>CREATE VIEW</> command for view</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_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><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_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_userbyid</function>(<parameter>userid</parameter>)</literal></entry>
- <entry><type>name</type></entry>
- <entry>get user name with given ID</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 serial or bigserial column
- uses</entry>
- </row>
- <row>
- <entry><literal><function>pg_tablespace_databases</function>(<parameter>tablespace_oid</parameter>)</literal></entry>
- <entry><type>setof oid</type></entry>
- <entry>get 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>subquery</replaceable>)
+</synopsis>
<para>
- <function>pg_get_viewdef</function>,
- <function>pg_get_ruledef</function>,
- <function>pg_get_indexdef</function>,
- <function>pg_get_triggerdef</function>, and
- <function>pg_get_constraintdef</function> respectively
- reconstruct the creating command for a view, rule, index, trigger, or
- constraint. (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
- may be useful when examining the contents of system catalogs.
- 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
+ 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>
<para>
- <function>pg_get_userbyid</function>
- extracts a user's name given a user ID number.
- <function>pg_get_serial_sequence</function>
- fetches the name of the sequence associated with a serial or
- bigserial column. The name is suitably formatted
- for passing to the sequence functions (see <xref
- linkend="functions-sequence">).
- NULL is returned if the column does not have a sequence attached.
+ 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>
+ As with <token>EXISTS</token>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </para>
+
+<synopsis>
+<replaceable>row_constructor</replaceable> NOT IN (<replaceable>subquery</replaceable>)
+</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>
- <function>pg_tablespace_databases</function> allows usage examination of a
- tablespace. It will return a set of OIDs of databases that have objects
- stored in the tablespace. If this function returns any row, 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.
+ 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 row results are either unequal or null, with at least one null,
+ then the result of <token>NOT IN</token> is null.
</para>
+ </sect2>
- <indexterm zone="functions-misc">
- <primary>obj_description</primary>
- </indexterm>
+ <sect2>
+ <title><literal>ANY</literal>/<literal>SOME</literal></title>
- <indexterm zone="functions-misc">
- <primary>col_description</primary>
- </indexterm>
+<synopsis>
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> ANY (<replaceable>subquery</replaceable>)
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> SOME (<replaceable>subquery</replaceable>)
+</synopsis>
- <indexterm zone="functions-misc">
- <primary>comment</primary>
- <secondary sortas="database objects">about database objects</secondary>
- </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 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>
- The functions shown in <xref
- linkend="functions-misc-comment-table"> extract comments
- previously stored with the <command>COMMENT</command> command. A
- null value is returned if no comment could be found matching the
- specified parameters.
- </para>
+ <para>
+ <token>SOME</token> is a synonym for <token>ANY</token>.
+ <token>IN</token> is equivalent to <literal>= ANY</literal>.
+ </para>
- <table id="functions-misc-comment-table">
- <title>Comment Information Functions</title>
- <tgroup cols="3">
- <thead>
- <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry></row>
- </thead>
+ <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>
- <tbody>
- <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>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>
- </tbody>
- </tgroup>
- </table>
+ <para>
+ As with <token>EXISTS</token>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </para>
- <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>
+<synopsis>
+<replaceable>row_constructor</replaceable> <replaceable>operator</> ANY (<replaceable>subquery</replaceable>)
+<replaceable>row_constructor</replaceable> <replaceable>operator</> SOME (<replaceable>subquery</replaceable>)
+</synopsis>
- <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>
+ <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>. Presently,
+ only <literal>=</literal> and <literal><></literal> operators are allowed
+ in row-wise <token>ANY</token> constructs.
+ The result of <token>ANY</token> is <quote>true</> if any equal or unequal row is
+ found, respectively.
+ The result is <quote>false</> if no such row is found (including the special
+ case where the subquery returns no rows).
+ </para>
- <indexterm zone="functions-misc">
- <primary>pg_cancel_backend</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 there is at least one null row result, then the result of <token>ANY</token>
+ cannot be false; it will be true or null.
+ </para>
+ </sect2>
- <indexterm zone="functions-misc">
- <primary>pg_terminate_backend</primary>
- </indexterm>
+ <sect2>
+ <title><literal>ALL</literal></title>
- <indexterm zone="functions-misc">
- <primary>signal</primary>
- <secondary sortas="backend">backend processes</secondary>
- </indexterm>
+<synopsis>
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> ALL (<replaceable>subquery</replaceable>)
+</synopsis>
- <para>
- The functions shown in <xref
- linkend="functions-misc-signal-table"> send control signals to
- other server processes. Use of these functions is restricted
- to superusers.
- </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.
+ </para>
- <table id="functions-misc-signal-table">
- <title>Backend Signalling Functions</title>
- <tgroup cols="3">
- <thead>
- <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry>
- </row>
- </thead>
+ <para>
+ <token>NOT IN</token> is equivalent to <literal><> ALL</literal>.
+ </para>
- <tbody>
- <row>
- <entry>
- <literal><function>pg_cancel_backend</function>(<parameter>pid</parameter>)</literal>
- </entry>
- <entry><type>int</type></entry>
- <entry>Cancel a backend's current query</entry>
- </row>
- <row>
- <entry>
- <literal><function>pg_terminate_backend</function>(<parameter>pid</parameter>)</literal>
- </entry>
- <entry><type>int</type></entry>
- <entry>Terminate a backend process</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
+ <para>
+ Note that if there are no failures but at least one right-hand row yields
+ null for the operator's result, the result of the <token>ALL</token> construct
+ will be null, not true.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </para>
- <para>
- These functions return 1 if successful, 0 if not successful.
- The process ID (<literal>pid</literal>) 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 postgres
- processes on the server.
- </para>
- </sect1>
+ <para>
+ As with <token>EXISTS</token>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </para>
- <sect1 id="functions-array">
- <title>Array Functions and Operators</title>
+<synopsis>
+<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> ALL (<replaceable>subquery</replaceable>)
+</synopsis>
<para>
- <xref linkend="array-operators-table"> shows the operators
- available for <type>array</type> types.
+ 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>. Presently,
+ only <literal>=</literal> and <literal><></literal> operators are allowed
+ in row-wise <token>ALL</token> queries.
+ The result of <token>ALL</token> is <quote>true</> if all subquery rows are equal
+ or unequal, respectively (including the special
+ case where the subquery returns no rows).
+ The result is <quote>false</> if any row is found to be unequal or equal,
+ respectively.
</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>
+ <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 there is at least one null row result, then the result of <token>ALL</token>
+ cannot be true; it will be false or null.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Row-wise Comparison</title>
+
+ <indexterm>
+ <primary>comparison</primary>
+ <secondary>of rows</secondary>
+ </indexterm>
+
+<synopsis>
+<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> (<replaceable>subquery</replaceable>)
+</synopsis>
- <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>
+ <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.
+ Presently, only <literal>=</literal> and <literal><></literal> operators are allowed
+ in row-wise comparisons.
+ The result is <quote>true</> if the two rows are equal or unequal, respectively.
+ </para>
- <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>
+ <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 the row comparison is unknown (null).
+ </para>
+ </sect2>
+ </sect1>
- <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>
+ <sect1 id="functions-comparisons">
+ <title>Row and Array Comparisons</title>
- <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>IN</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>NOT IN</primary>
+ </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>ANY</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>ALL</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>
+ <indexterm>
+ <primary>SOME</primary>
+ </indexterm>
<para>
- See <xref linkend="arrays"> for more details about array operator
- behavior.
+ 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>
- <para>
- <xref linkend="array-functions-table"> shows the functions
- available for use with array types. See <xref linkend="arrays">
- for more discussion and examples for the use of these functions.
- </para>
+ <sect2>
+ <title><literal>IN</literal></title>
- <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_cat</function>
- (<type>anyarray</type>, <type>anyarray</type>)
- </literal>
- </entry>
- <entry><type>anyarray</type></entry>
- <entry>
- concatenate two arrays, returning <literal>NULL</literal>
- for <literal>NULL</literal> inputs
- </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_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, returning
- <literal>NULL</literal> for <literal>NULL</literal> inputs
- </entry>
- <entry><literal>array_append(ARRAY[1,2], 3)</literal></entry>
- <entry><literal>{1,2,3}</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, returning
- <literal>NULL</literal> for <literal>NULL</literal> inputs
- </entry>
- <entry><literal>array_prepend(1, ARRAY[2,3])</literal></entry>
- <entry><literal>{1,2,3}</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 dimension lower and upper bounds,
- generating an ERROR for <literal>NULL</literal> inputs
- </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>integer</type>)
- </literal>
- </entry>
- <entry><type>integer</type></entry>
- <entry>
- returns lower bound of the requested array dimension, returning
- <literal>NULL</literal> for <literal>NULL</literal> inputs
- </entry>
- <entry><literal>array_lower(array_prepend(0, ARRAY[1,2,3]), 1)</literal></entry>
- <entry><literal>0</literal></entry>
- </row>
- <row>
- <entry>
- <literal>
- <function>array_upper</function>
- (<type>anyarray</type>, <type>integer</type>)
- </literal>
- </entry>
- <entry><type>integer</type></entry>
- <entry>
- returns upper bound of the requested array dimension, returning
- <literal>NULL</literal> for <literal>NULL</literal> inputs
- </entry>
- <entry><literal>array_upper(ARRAY[1,2,3,4], 1)</literal></entry>
- <entry><literal>4</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, returning
- <literal>NULL</literal> for <literal>NULL</literal> inputs
- </entry>
- <entry><literal>array_to_string(array[1, 2, 3], '~^~')</literal></entry>
- <entry><literal>1~^~2~^~3</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, returning
- <literal>NULL</literal> for <literal>NULL</literal> inputs
- </entry>
- <entry><literal>string_to_array( 'xx~^~yy~^~zz', '~^~')</literal></entry>
- <entry><literal>{xx,yy,zz}</literal></entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </sect1>
+<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
- <sect1 id="functions-aggregate">
- <title>Aggregate Functions</title>
+<synopsis>
+<replaceable>expression</replaceable> = <replaceable>value1</replaceable>
+OR
+<replaceable>expression</replaceable> = <replaceable>value2</replaceable>
+OR
+...
+</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>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>
+
+ <sect2>
+ <title><literal>NOT IN</literal></title>
+
+<synopsis>
+<replaceable>expression</replaceable> NOT IN (<replaceable>value</replaceable><optional>, ...</optional>)
+</synopsis>
<para>
- <firstterm>Aggregate functions</firstterm> compute a single result
- value from a set of input values. <xref
- linkend="functions-aggregate-table"> shows the built-in aggregate
- functions. The special syntax considerations for aggregate
- functions are explained in <xref linkend="syntax-aggregates">.
- Consult <xref linkend="tutorial-agg"> for additional introductory
- information.
+ 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>
- <table id="functions-aggregate-table">
- <title>Aggregate Functions</title>
+ <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>
- <tgroup cols="4">
- <thead>
- <row>
- <entry>Function</entry>
- <entry>Argument Type</entry>
- <entry>Return Type</entry>
- <entry>Description</entry>
- </row>
- </thead>
+ <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>
- <tbody>
- <row>
- <entry>
- <indexterm>
- <primary>average</primary>
- </indexterm>
- <function>avg(<replaceable class="parameter">expression</replaceable>)</function>
- </entry>
- <entry>
- <type>smallint</type>, <type>integer</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>
+ <sect2>
+ <title><literal>ANY</literal>/<literal>SOME</literal> (array)</title>
- <row>
- <entry>
- <indexterm>
- <primary>bit_and</primary>
- </indexterm>
- <function>bit_and(<replaceable class="parameter">expression</replaceable>)</function>
- </entry>
- <entry>
- <type>smallint</type>, <type>integer</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>
+<synopsis>
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> ANY (<replaceable>array expression</replaceable>)
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> SOME (<replaceable>array expression</replaceable>)
+</synopsis>
- <row>
- <entry>
- <indexterm>
- <primary>bit_or</primary>
- </indexterm>
- <function>bit_or(<replaceable class="parameter">expression</replaceable>)</function>
- </entry>
- <entry>
- <type>smallint</type>, <type>integer</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>
+ 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>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>
+ <para>
+ <token>SOME</token> is a synonym for <token>ANY</token>.
+ </para>
+ </sect2>
- <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>
+ <sect2>
+ <title><literal>ALL</literal> (array)</title>
- <row>
- <entry><function>count(*)</function></entry>
- <entry></entry>
- <entry><type>bigint</type></entry>
- <entry>number of input values</entry>
- </row>
+<synopsis>
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> ALL (<replaceable>array expression</replaceable>)
+</synopsis>
- <row>
- <entry><function>count(<replaceable class="parameter">expression</replaceable>)</function></entry>
- <entry>any</entry>
- <entry><type>bigint</type></entry>
- <entry>
- number of input values for which the value of <replaceable
- class="parameter">expression</replaceable> is not null
- </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>
+ </sect2>
+
+ <sect2>
+ <title>Row-wise Comparison</title>
+
+<synopsis>
+<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> <replaceable>row_constructor</replaceable>
+</synopsis>
+
+ <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.
+ Presently, only <literal>=</literal> and <literal><></literal> operators are allowed
+ in row-wise comparisons.
+ The result is <quote>true</> if the two rows are equal or unequal, respectively.
+ </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 the row comparison is unknown (null).
+ </para>
+
+<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.
+ </para>
+
+<synopsis>
+<replaceable>row_constructor</replaceable> IS NULL
+<replaceable>row_constructor</replaceable> IS NOT NULL
+</synopsis>
- <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>
+ <para>
+ These constructs test a row value for null or not null. A row value
+ is considered not null if it has at least one field that is not null.
+ </para>
- <row>
- <entry><function>max(<replaceable class="parameter">expression</replaceable>)</function></entry>
- <entry>any 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>
+ </sect2>
+ </sect1>
- <row>
- <entry><function>min(<replaceable class="parameter">expression</replaceable>)</function></entry>
- <entry>any 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>
+ <sect1 id="functions-srf">
+ <title>Set Returning Functions</title>
+
+ <indexterm zone="functions-srf">
+ <primary>set returning functions</primary>
+ <secondary>functions</secondary>
+ </indexterm>
+
+ <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>
+ <table id="functions-srf-series">
+ <title>Series Generating Functions</title>
+ <tgroup cols="4">
+ <thead>
<row>
- <entry>
- <indexterm>
- <primary>standard deviation</primary>
- </indexterm>
- <function>stddev(<replaceable class="parameter">expression</replaceable>)</function>
- </entry>
- <entry>
- <type>smallint</type>, <type>integer</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>
+ <entry>Function</entry>
+ <entry>Argument Type</entry>
+ <entry>Return Type</entry>
+ <entry>Description</entry>
</row>
+ </thead>
+ <tbody>
<row>
- <entry><function>sum(<replaceable class="parameter">expression</replaceable>)</function></entry>
- <entry>
- <type>smallint</type>, <type>integer</type>,
- <type>bigint</type>, <type>real</type>, <type>double
- precision</type>, <type>numeric</type>, or
- <type>interval</type>
- </entry>
+ <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>
- <type>bigint</type> for <type>smallint</type> or
- <type>integer</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
+ Generate a series of values, from <parameter>start</parameter> to <parameter>stop</parameter>
+ with a step size of one.
</entry>
- <entry>sum of <replaceable class="parameter">expression</replaceable> across all input values</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>
- <indexterm>
- <primary>variance</primary>
- </indexterm>
- <function>variance</function>(<replaceable class="parameter">expression</replaceable>)
- </entry>
- <entry>
- <type>smallint</type>, <type>integer</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>
+ Generate a series of values, from <parameter>start</parameter> to <parameter>stop</parameter>
+ with a step size of <parameter>step</parameter>.
</entry>
- <entry>sample variance of the input values (square of the sample standard deviation)</entry>
</row>
</tbody>
</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 <function>coalesce</function> may be
- used to substitute zero for null when necessary.
- </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:
+ 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 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>
+select * from generate_series(2,4);
+ generate_series
+-----------------
+ 2
+ 3
+ 4
+(3 rows)
- <note>
- <para>
- Users accustomed to working with other SQL database management
- systems may be surprised by the performance characteristics of
- certain aggregate functions in
- <productname>PostgreSQL</productname> when the aggregate is
- applied to the entire table (in other words, no
- <literal>WHERE</literal> clause is specified). In particular, a
- query like
-<programlisting>
-SELECT min(col) FROM sometable;
-</programlisting>
- will be executed by <productname>PostgreSQL</productname> using a
- sequential scan of the entire table. Other database systems may
- optimize queries of this form to use an index on the column, if
- one is available. Similarly, the aggregate functions
- <function>max()</function> and <function>count()</function> always
- require a sequential scan if applied to the entire table in
- <productname>PostgreSQL</productname>.
- </para>
+select * from generate_series(5,1,-2);
+ generate_series
+-----------------
+ 5
+ 3
+ 1
+(3 rows)
- <para>
- <productname>PostgreSQL</productname> cannot easily implement this
- optimization because it also allows for user-defined aggregate
- queries. Since <function>min()</function>,
- <function>max()</function>, and <function>count()</function> are
- defined using a generic API for aggregate functions, there is no
- provision for special-casing the execution of these functions
- under certain circumstances.
- </para>
+select * from generate_series(4,3);
+ generate_series
+-----------------
+(0 rows)
- <para>
- Fortunately, there is a simple workaround for
- <function>min()</function> and <function>max()</function>. The
- query shown below is equivalent to the query above, except that it
- can take advantage of a B-tree index if there is one present on
- the column in question.
-<programlisting>
-SELECT col FROM sometable ORDER BY col ASC LIMIT 1;
+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>
- A similar query (obtained by substituting <literal>DESC</literal>
- for <literal>ASC</literal> in the query above) can be used in the
- place of <function>max()</function>).
- </para>
-
- <para>
- Unfortunately, there is no similarly trivial query that can be
- used to improve the performance of <function>count()</function>
- when applied to the entire table.
- </para>
- </note>
-
+ </para>
</sect1>
+ <sect1 id="functions-info">
+ <title>System Information Functions</title>
- <sect1 id="functions-subquery">
- <title>Subquery Expressions</title>
-
- <indexterm>
- <primary>EXISTS</primary>
- </indexterm>
-
- <indexterm>
- <primary>IN</primary>
- </indexterm>
-
- <indexterm>
- <primary>NOT IN</primary>
- </indexterm>
+ <para>
+ <xref linkend="functions-info-session-table"> shows several
+ functions that extract session and system information.
+ </para>
- <indexterm>
- <primary>ANY</primary>
- </indexterm>
+ <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>
- <indexterm>
- <primary>ALL</primary>
- </indexterm>
+ <tbody>
+ <row>
+ <entry><function>current_database()</function></entry>
+ <entry><type>name</type></entry>
+ <entry>name of current database</entry>
+ </row>
- <indexterm>
- <primary>SOME</primary>
- </indexterm>
+ <row>
+ <entry><function>current_schema()</function></entry>
+ <entry><type>name</type></entry>
+ <entry>name of current schema</entry>
+ </row>
- <indexterm>
- <primary>subquery</primary>
- </indexterm>
+ <row>
+ <entry><function>current_schemas(boolean)</function></entry>
+ <entry><type>name[]</type></entry>
+ <entry>names of schemas in search path optionally including implicit schemas</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><function>current_user</function></entry>
+ <entry><type>name</type></entry>
+ <entry>user name of current execution context</entry>
+ </row>
- <sect2>
- <title><literal>EXISTS</literal></title>
+ <row>
+ <entry><function>inet_client_addr()</function></entry>
+ <entry><type>inet</type></entry>
+ <entry>address of the remote connection</entry>
+ </row>
-<synopsis>
-EXISTS ( <replaceable>subquery</replaceable> )
-</synopsis>
+ <row>
+ <entry><function>inet_client_port()</function></entry>
+ <entry><type>int4</type></entry>
+ <entry>port of the remote connection</entry>
+ </row>
- <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>
+ <row>
+ <entry><function>inet_server_addr()</function></entry>
+ <entry><type>inet</type></entry>
+ <entry>address of the local connection</entry>
+ </row>
- <para>
- The subquery can refer to variables from the surrounding query,
- which will act as constants during any one evaluation of the subquery.
- </para>
+ <row>
+ <entry><function>inet_server_port()</function></entry>
+ <entry><type>int4</type></entry>
+ <entry>port of the local connection</entry>
+ </row>
- <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
- may be difficult to predict.
- </para>
+ <row>
+ <entry><function>session_user</function></entry>
+ <entry><type>name</type></entry>
+ <entry>session user name</entry>
+ </row>
- <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>
+ <row>
+ <entry><function>user</function></entry>
+ <entry><type>name</type></entry>
+ <entry>equivalent to <function>current_user</function></entry>
+ </row>
- <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>
+ <row>
+ <entry><function>version()</function></entry>
+ <entry><type>text</type></entry>
+ <entry>PostgreSQL version information</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
- <sect2>
- <title><literal>IN</literal></title>
+ <indexterm zone="functions-info">
+ <primary>user</primary>
+ <secondary>current</secondary>
+ </indexterm>
-<synopsis>
-<replaceable>expression</replaceable> IN (<replaceable>subquery</replaceable>)
-</synopsis>
+ <indexterm zone="functions-info">
+ <primary>schema</primary>
+ <secondary>current</secondary>
+ </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>search path</primary>
+ <secondary>current</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 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>
+ <para>
+ The <function>session_user</function> is the user that initiated a
+ database connection; it is fixed for the duration of that
+ connection. 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 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>
- As with <token>EXISTS</token>, it's unwise to assume that the subquery will
- be evaluated completely.
- </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>
-<synopsis>
-<replaceable>row_constructor</replaceable> IN (<replaceable>subquery</replaceable>)
-</synopsis>
+ <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>
- <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>
+ <note>
+ <para>
+ The search path may be altered at run time. The command is:
+<programlisting>
+SET search_path TO <replaceable>schema</> <optional>, <replaceable>schema</>, ...</optional>
+</programlisting>
+ </para>
+ </note>
- <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 row results are either unequal or null, with at least one null,
- then the result of <token>IN</token> is null.
- </para>
- </sect2>
+ <indexterm zone="functions-info">
+ <primary>inet_client_addr</primary>
+ </indexterm>
- <sect2>
- <title><literal>NOT IN </literal></title>
+ <indexterm zone="functions-info">
+ <primary>inet_client_port</primary>
+ </indexterm>
-<synopsis>
-<replaceable>expression</replaceable> NOT IN (<replaceable>subquery</replaceable>)
-</synopsis>
+ <indexterm zone="functions-info">
+ <primary>inet_server_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>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>inet_server_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>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>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 connection is via a Unix-domain
+ socket.
+ </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>version</primary>
+ </indexterm>
-<synopsis>
-<replaceable>row_constructor</replaceable> NOT IN (<replaceable>subquery</replaceable>)
-</synopsis>
+ <para>
+ <function>version()</function> returns a string describing the
+ <productname>PostgreSQL</productname> server's version.
+ </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>
+ <primary>privilege</primary>
+ <secondary>querying</secondary>
+ </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 row results are either unequal or null, with at least one null,
- then the result of <token>NOT IN</token> is null.
+ <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>
- </sect2>
- <sect2>
- <title><literal>ANY</literal>/<literal>SOME</literal></title>
+ <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>
-<synopsis>
-<replaceable>expression</replaceable> <replaceable>operator</replaceable> ANY (<replaceable>subquery</replaceable>)
-<replaceable>expression</replaceable> <replaceable>operator</replaceable> SOME (<replaceable>subquery</replaceable>)
-</synopsis>
+ <tbody>
+ <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_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_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>
+ </tbody>
+ </tgroup>
+ </table>
- <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>
+ <indexterm zone="functions-info">
+ <primary>has_table_privilege</primary>
+ </indexterm>
+ <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_tablespace_privilege</primary>
+ </indexterm>
- <para>
- <token>SOME</token> is a synonym for <token>ANY</token>.
- <token>IN</token> is equivalent to <literal>= ANY</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 ID
+ (<literal>pg_user.usesysid</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>RULE</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>
- 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>
+ <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>TEMPORARY</literal>, or
+ <literal>TEMP</literal> (which is equivalent to
+ <literal>TEMPORARY</literal>).
+ </para>
- <para>
- As with <token>EXISTS</token>, it's unwise to assume that the subquery will
- be evaluated completely.
- </para>
+ <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.
+ 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>
-<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_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_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 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>. Presently,
- only <literal>=</literal> and <literal><></literal> operators are allowed
- in row-wise <token>ANY</token> constructs.
- The result of <token>ANY</token> is <quote>true</> if any equal or unequal row is
- found, respectively.
- The result is <quote>false</> if no such row is found (including the special
- case where the subquery returns no rows).
+ To evaluate 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>
- 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 there is at least one null row result, then the result of <token>ANY</token>
- cannot be false; it will be true or null.
+ <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>
- </sect2>
- <sect2>
- <title><literal>ALL</literal></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>
+ </thead>
-<synopsis>
-<replaceable>expression</replaceable> <replaceable>operator</replaceable> ALL (<replaceable>subquery</replaceable>)
-</synopsis>
+ <tbody>
+ <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>
+ <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_conversion_is_visible</function>(<parameter>conversion_oid</parameter>)</literal>
+ </entry>
+ <entry><type>boolean</type></entry>
+ <entry>is conversion visible in search path</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
- <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.
- </para>
+ <indexterm zone="functions-info">
+ <primary>pg_table_is_visible</primary>
+ </indexterm>
+ <indexterm zone="functions-info">
+ <primary>pg_type_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_conversion_is_visible</primary>
+ </indexterm>
- <para>
- <token>NOT IN</token> is equivalent to <literal><> ALL</literal>.
- </para>
+ <para>
+ <function>pg_table_is_visible</function> performs the check for
+ tables (or views, or any other kind of <literal>pg_class</> entry).
+ <function>pg_type_is_visible</function>,
+ <function>pg_function_is_visible</function>,
+ <function>pg_operator_is_visible</function>,
+ <function>pg_opclass_is_visible</function>, and
+ <function>pg_conversion_is_visible</function> perform the same sort of
+ visibility check for types (and domains), functions, operators, operator classes
+ and conversions, respectively. 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>
- <para>
- Note that if there are no failures but at least one right-hand row yields
- null for the operator's result, the result of the <token>ALL</token> construct
- will be null, not true.
- This is in accordance with SQL's normal rules for Boolean combinations
- of null values.
- </para>
+ <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>
- <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_get_viewdef</primary>
+ </indexterm>
-<synopsis>
-<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> ALL (<replaceable>subquery</replaceable>)
-</synopsis>
+ <indexterm zone="functions-info">
+ <primary>pg_get_ruledef</primary>
+ </indexterm>
- <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>. Presently,
- only <literal>=</literal> and <literal><></literal> operators are allowed
- in row-wise <token>ALL</token> queries.
- The result of <token>ALL</token> is <quote>true</> if all subquery rows are equal
- or unequal, respectively (including the special
- case where the subquery returns no rows).
- The result is <quote>false</> if any row is found to be unequal or equal,
- respectively.
- </para>
+ <indexterm zone="functions-info">
+ <primary>pg_get_indexdef</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 there is at least one null row result, then the result of <token>ALL</token>
- cannot be true; it will be false or null.
- </para>
- </sect2>
+ <indexterm zone="functions-info">
+ <primary>pg_get_triggerdef</primary>
+ </indexterm>
- <sect2>
- <title>Row-wise Comparison</title>
+ <indexterm zone="functions-info">
+ <primary>pg_get_constraintdef</primary>
+ </indexterm>
- <indexterm>
- <primary>comparison</primary>
- <secondary>of rows</secondary>
+ <indexterm zone="functions-info">
+ <primary>pg_get_expr</primary>
</indexterm>
-<synopsis>
-<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> (<replaceable>subquery</replaceable>)
-</synopsis>
+ <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>
- 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.
- Presently, only <literal>=</literal> and <literal><></literal> operators are allowed
- in row-wise comparisons.
- The result is <quote>true</> if the two rows are equal or unequal, respectively.
+ <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>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal><function>pg_get_viewdef</function>(<parameter>view_name</parameter>)</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>get <command>CREATE VIEW</> 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 <command>CREATE VIEW</> 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 <command>CREATE VIEW</> 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 <command>CREATE VIEW</> command for view</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_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><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_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_userbyid</function>(<parameter>userid</parameter>)</literal></entry>
+ <entry><type>name</type></entry>
+ <entry>get user name with given ID</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 serial or bigserial column
+ uses</entry>
+ </row>
+ <row>
+ <entry><literal><function>pg_tablespace_databases</function>(<parameter>tablespace_oid</parameter>)</literal></entry>
+ <entry><type>setof oid</type></entry>
+ <entry>get set of database OIDs that have objects in the tablespace</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
<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 the row comparison is unknown (null).
+ <function>pg_get_viewdef</function>,
+ <function>pg_get_ruledef</function>,
+ <function>pg_get_indexdef</function>,
+ <function>pg_get_triggerdef</function>, and
+ <function>pg_get_constraintdef</function> respectively
+ reconstruct the creating command for a view, rule, index, trigger, or
+ constraint. (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
+ may be useful when examining the contents of system catalogs.
+ 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>
- </sect2>
- </sect1>
-
-
- <sect1 id="functions-comparisons">
- <title>Row and Array Comparisons</title>
-
- <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>
<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.
+ <function>pg_get_userbyid</function>
+ extracts a user's name given a user ID number.
+ <function>pg_get_serial_sequence</function>
+ fetches the name of the sequence associated with a serial or
+ bigserial column. The name is suitably formatted
+ for passing to the sequence functions (see <xref
+ linkend="functions-sequence">).
+ NULL is returned if the column does not have a sequence attached.
</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>
+ <function>pg_tablespace_databases</function> allows usage examination of a
+ tablespace. It will return a set of OIDs of databases that have objects
+ stored in the tablespace. If this function returns any row, 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>
- <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>
+ <indexterm zone="functions-info">
+ <primary>obj_description</primary>
+ </indexterm>
- <sect2>
- <title><literal>NOT IN</literal></title>
+ <indexterm zone="functions-info">
+ <primary>col_description</primary>
+ </indexterm>
-<synopsis>
-<replaceable>expression</replaceable> NOT IN (<replaceable>value</replaceable><optional>, ...</optional>)
-</synopsis>
+ <indexterm zone="functions-info">
+ <primary>comment</primary>
+ <secondary sortas="database objects">about database objects</secondary>
+ </indexterm>
- <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
+ <para>
+ The functions shown in <xref
+ linkend="functions-info-comment-table"> extract comments
+ previously stored with the <command>COMMENT</command> command. A
+ null value is returned if no comment could be found matching the
+ specified parameters.
+ </para>
-<synopsis>
-<replaceable>expression</replaceable> <> <replaceable>value1</replaceable>
-AND
-<replaceable>expression</replaceable> <> <replaceable>value2</replaceable>
-AND
-...
-</synopsis>
- </para>
+ <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>
- <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>
+ <tbody>
+ <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>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>
+ </tbody>
+ </tgroup>
+ </table>
- <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>
+ <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>
- <sect2>
- <title><literal>ANY</literal>/<literal>SOME</literal> (array)</title>
+ <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>
+ </sect1>
-<synopsis>
-<replaceable>expression</replaceable> <replaceable>operator</replaceable> ANY (<replaceable>array expression</replaceable>)
-<replaceable>expression</replaceable> <replaceable>operator</replaceable> SOME (<replaceable>array expression</replaceable>)
-</synopsis>
+ <sect1 id="functions-admin">
+ <title>System Administration Functions</title>
<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).
+ <xref linkend="functions-admin-set-table"> shows the functions
+ available to query and alter run-time configuration parameters.
</para>
- <para>
- <token>SOME</token> is a synonym for <token>ANY</token>.
- </para>
- </sect2>
+ <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>
- <sect2>
- <title><literal>ALL</literal> (array)</title>
+ <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>
-<synopsis>
-<replaceable>expression</replaceable> <replaceable>operator</replaceable> ALL (<replaceable>array expression</replaceable>)
-</synopsis>
+ <indexterm zone="functions-admin">
+ <primary>SET</primary>
+ </indexterm>
- <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>
- </sect2>
+ <indexterm zone="functions-admin">
+ <primary>SHOW</primary>
+ </indexterm>
- <sect2>
- <title>Row-wise Comparison</title>
+ <indexterm zone="functions-admin">
+ <primary>configuration</primary>
+ <secondary sortas="server">of the server</secondary>
+ <tertiary>functions</tertiary>
+ </indexterm>
-<synopsis>
-<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> <replaceable>row_constructor</replaceable>
-</synopsis>
+ <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');
- <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.
- Presently, only <literal>=</literal> and <literal><></literal> operators are allowed
- in row-wise comparisons.
- The result is <quote>true</> if the two rows are equal or unequal, respectively.
- </para>
+ current_setting
+-----------------
+ ISO, MDY
+(1 row)
+</programlisting>
+ </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 the row comparison is unknown (null).
- </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);
-<synopsis>
-<replaceable>row_constructor</replaceable> IS DISTINCT FROM <replaceable>row_constructor</replaceable>
-</synopsis>
+ set_config
+------------
+ off
+(1 row)
+</programlisting>
+ </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>
+ <indexterm zone="functions-admin">
+ <primary>pg_cancel_backend</primary>
+ </indexterm>
-<synopsis>
-<replaceable>row_constructor</replaceable> IS NULL
-<replaceable>row_constructor</replaceable> IS NOT NULL
-</synopsis>
+ <indexterm zone="functions-admin">
+ <primary>signal</primary>
+ <secondary sortas="backend">backend processes</secondary>
+ </indexterm>
- <para>
- These constructs test a row value for null or not null. A row value
- is considered not null if it has at least one field that is not null.
- </para>
+ <para>
+ The function shown in <xref
+ linkend="functions-admin-signal-table"> sends control signals to
+ other server processes. Use of this function is restricted
+ to superusers.
+ </para>
- </sect2>
- </sect1>
+ <table id="functions-admin-signal-table">
+ <title>Backend Signalling Functions</title>
+ <tgroup cols="3">
+ <thead>
+ <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry>
+ </row>
+ </thead>
- <sect1 id="functions-srf">
- <title>Set Returning Functions</title>
+ <tbody>
+ <row>
+ <entry>
+ <literal><function>pg_cancel_backend</function>(<parameter>pid</parameter>)</literal>
+ </entry>
+ <entry><type>int</type></entry>
+ <entry>Cancel a backend's current query</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
- <indexterm zone="functions-srf">
- <primary>set returning functions</primary>
- <secondary>functions</secondary>
- </indexterm>
+ <para>
+ This function returns 1 if successful, 0 if not successful.
+ The process ID (<literal>pid</literal>) 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 postgres
+ processes on the server with <application>ps</>.
+ </para>
- <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>
+ <indexterm zone="functions-admin">
+ <primary>pg_start_backup</primary>
+ </indexterm>
- <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>pg_stop_backup</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>backup</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>
+ <para>
+ The functions shown in <xref
+ linkend="functions-admin-backup-table"> assist in making on-line backups.
+ Use of these functions is restricted to superusers.
+ </para>
- </tbody>
- </tgroup>
- </table>
+ <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>
- <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)
+ <tbody>
+ <row>
+ <entry>
+ <literal><function>pg_start_backup</function>(<parameter>label_text</parameter>)</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>
+ </tbody>
+ </tgroup>
+ </table>
-select * from generate_series(5,1,-2);
- generate_series
------------------
- 5
- 3
- 1
-(3 rows)
+ <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 WAL offset as text. (The user
+ need not pay any attention to this result value, but it is provided in
+ case it is of use.)
+ </para>
-select * from generate_series(4,3);
- generate_series
------------------
-(0 rows)
+ <para>
+ <function>pg_stop_backup</> removes the label file created by
+ <function>pg_start_backup</>, and instead creates a backup history file in
+ the WAL archive area. The history file includes the label given to
+ <function>pg_start_backup</>, the starting and ending WAL offsets for
+ the backup, and the starting and ending times of the backup. The return
+ value is the backup's ending WAL offset (which again may be of little
+ interest).
+ </para>
-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>
+ <para>
+ For details about proper usage of these functions, see
+ <xref linkend="backup-online">.
+ </para>
+ </sect1>
</chapter>
<!-- Keep this comment at the end of the file