<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/advanced.sgml,v 1.32 2003/02/19 04:06:27 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/advanced.sgml,v 1.33 2003/03/13 01:30:24 petere Exp $
-->
<chapter id="tutorial-advanced">
which returns:
- <screen>
+<screen>
name | altitude
-----------+----------
Las Vegas | 2174
Mariposa | 1953
Madison | 845
(3 rows)
- </screen>
+</screen>
</para>
<para>
-<!-- $Header: /cvsroot/pgsql/doc/src/sgml/array.sgml,v 1.24 2002/11/11 20:14:02 petere Exp $ -->
+<!-- $Header: /cvsroot/pgsql/doc/src/sgml/array.sgml,v 1.25 2003/03/13 01:30:26 petere Exp $ -->
<sect1 id="arrays">
<title>Arrays</title>
<para>
<productname>PostgreSQL</productname> allows columns of a table to be
defined as variable-length multidimensional arrays. Arrays of any
- built-in type or user-defined type can be created. To illustrate
- their use, we create this table:
+ built-in type or user-defined type can be created.
+ </para>
+
+ <sect2>
+ <title>Declaration of Array Types</title>
+
+ <para>
+ To illustrate the use of array types, we create this table:
<programlisting>
CREATE TABLE sal_emp (
name text,
);
</programlisting>
As shown, an array data type is named by appending square brackets
- (<literal>[]</>) to the data type name of the array elements.
- The above command will create a table named
- <structname>sal_emp</structname> with columns including
- a <type>text</type> string (<structfield>name</structfield>),
- a one-dimensional array of type
- <type>integer</type> (<structfield>pay_by_quarter</structfield>),
- which represents the employee's salary by quarter, and a
- two-dimensional array of <type>text</type>
- (<structfield>schedule</structfield>), which represents the
- employee's weekly schedule.
+ (<literal>[]</>) to the data type name of the array elements. The
+ above command will create a table named
+ <structname>sal_emp</structname> with a column of type
+ <type>text</type> (<structfield>name</structfield>), a
+ one-dimensional array of type <type>integer</type>
+ (<structfield>pay_by_quarter</structfield>), which represents the
+ employee's salary by quarter, and a two-dimensional array of
+ <type>text</type> (<structfield>schedule</structfield>), which
+ represents the employee's weekly schedule.
</para>
+ </sect2>
+
+ <sect2>
+ <title>Array Value Input</title>
<para>
- Now we do some <command>INSERT</command>s. Observe that to write an array
+ Now we can show some <command>INSERT</command> statements. To write an array
value, we enclose the element values within curly braces and separate them
by commas. If you know C, this is not unlike the syntax for
initializing structures. (More details appear below.)
-
+
<programlisting>
INSERT INTO sal_emp
VALUES ('Bill',
</programlisting>
</para>
+ <note>
+ <para>
+ A limitation of the present array implementation is that individual
+ elements of an array cannot be SQL null values. The entire array can be set
+ to null, but you can't have an array with some elements null and some
+ not. Fixing this is on the to-do list.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Array Value References</title>
+
<para>
- Now, we can run some queries on <structname>sal_emp</structname>.
+ Now, we can run some queries on the table.
First, we show how to access a single element of an array at a time.
This query retrieves the names of the employees whose pay changed in
the second quarter:
We can also access arbitrary rectangular slices of an array, or
subarrays. An array slice is denoted by writing
<literal><replaceable>lower-bound</replaceable>:<replaceable>upper-bound</replaceable></literal>
- for one or more array dimensions. This query retrieves the first
+ for one or more array dimensions. For example, this query retrieves the first
item on Bill's schedule for the first two days of the week:
<programlisting>
SELECT schedule[1:2][1] FROM sal_emp WHERE name = 'Bill';
</programlisting>
- with the same result. An array subscripting operation is taken to
+ with the same result. An array subscripting operation is always taken to
represent an array slice if any of the subscripts are written in the
form
<literal><replaceable>lower</replaceable>:<replaceable>upper</replaceable></literal>.
array_lower</function> return the upper/lower bound of the
given array dimension, respectively.
</para>
+ </sect2>
+
+ <sect2>
+ <title>Searching in Arrays</title>
<para>
To search for a value in an array, you must check each value of the
- array. This can be done by hand (if you know the size of the array):
+ array. This can be done by hand (if you know the size of the array).
+ For example:
<programlisting>
SELECT * FROM sal_emp WHERE pay_by_quarter[1] = 10000 OR
</programlisting>
However, this quickly becomes tedious for large arrays, and is not
- helpful if the size of the array is unknown. Although it is not part
- of the primary <productname>PostgreSQL</productname> distribution,
+ helpful if the size of the array is unknown. Although it is not built
+ into <productname>PostgreSQL</productname>,
there is an extension available that defines new functions and
operators for iterating over array values. Using this, the above
query could be:
SELECT * FROM sal_emp WHERE pay_by_quarter[1:4] *= 10000;
</programlisting>
- To search the entire array (not just specified columns), you could
+ To search the entire array (not just specified slices), you could
use:
<programlisting>
Tables can obviously be searched easily.
</para>
</tip>
+ </sect2>
- <note>
- <para>
- A limitation of the present array implementation is that individual
- elements of an array cannot be SQL null values. The entire array can be set
- to null, but you can't have an array with some elements null and some
- not. Fixing this is on the to-do list.
- </para>
- </note>
+ <sect2>
+ <title>Array Input and Output Syntax</title>
- <formalpara>
- <title>Array input and output syntax.</title>
<para>
The external representation of an array value consists of items that
are interpreted according to the I/O conversion rules for the array's
is not ignored, however: after skipping leading whitespace, everything
up to the next right brace or delimiter is taken as the item value.
</para>
- </formalpara>
+ </sect2>
+
+ <sect2>
+ <title>Quoting Array Elements</title>
- <formalpara>
- <title>Quoting array elements.</title>
<para>
As shown above, when writing an array value you may write double
quotes around any individual array
Alternatively, you can use backslash-escaping to protect all data characters
that would otherwise be taken as array syntax or ignorable white space.
</para>
- </formalpara>
<para>
The array output routine will put double quotes around element values
<productname>PostgreSQL</productname> releases.)
</para>
- <tip>
+ <note>
<para>
Remember that what you write in an SQL command will first be interpreted
as a string literal, and then as an array. This doubles the number of
<type>bytea</> for example, we might need as many as eight backslashes
in the command to get one backslash into the stored array element.)
</para>
- </tip>
+ </note>
+ </sect2>
</sect1>
-<!-- $Header: /cvsroot/pgsql/doc/src/sgml/charset.sgml,v 2.31 2003/01/19 00:13:28 momjian Exp $ -->
+<!-- $Header: /cvsroot/pgsql/doc/src/sgml/charset.sgml,v 2.32 2003/03/13 01:30:26 petere Exp $ -->
<chapter id="charset">
<title>Localization</>
<command>initdb</command> exactly which locale you want with the
option <option>--locale</option>. For example:
<screen>
-<prompt>$ </><userinput>initdb --locale=sv_SE</>
+initdb --locale=sv_SE
</screen>
</para>
for a <productname>PostgreSQL</productname> installation. For example:
<screen>
-$ <userinput>initdb -E EUC_JP</>
+initdb -E EUC_JP
</screen>
sets the default encoding to <literal>EUC_JP</literal> (Extended Unix Code for Japanese).
You can create a database with a different encoding:
<screen>
-$ <userinput>createdb -E EUC_KR korean</>
+createdb -E EUC_KR korean
</screen>
will create a database named <database>korean</database> with <literal>EUC_KR</literal> encoding.
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/client-auth.sgml,v 1.45 2003/02/13 05:47:46 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/client-auth.sgml,v 1.46 2003/03/13 01:30:26 petere Exp $
-->
<chapter id="client-authentication">
runs. If all the users of a particular server also have accounts on
the server's machine, it makes sense to assign database user names
that match their operating system user names. However, a server that
- accepts remote connections may have many users who have no local
+ accepts remote connections may have many database users who have no local operating system
account, and in such cases there need be no connection between
database user names and OS user names.
</para>
<para>
The general format of the <filename>pg_hba.conf</filename> file is
a set of records, one per line. Blank lines are ignored, as is any
- text after the <quote>#</quote> comment character. A record is made
+ text after the <literal>#</literal> comment character. A record is made
up of a number of fields which are separated by spaces and/or tabs.
Fields can contain white space if the field value is quoted. Records
cannot be continued across lines.
<para>
A record may have one of the three formats
- <synopsis>
+<synopsis>
local <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>authentication-method</replaceable> <optional><replaceable>authentication-option</replaceable></optional>
host <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>authentication-method</replaceable> <optional><replaceable>authentication-option</replaceable></optional>
hostssl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>authentication-method</replaceable> <optional><replaceable>authentication-option</replaceable></optional>
- </synopsis>
+</synopsis>
The meaning of the fields is as follows:
<variablelist>
<term><literal>local</literal></term>
<listitem>
<para>
- This record matches connection attempts using Unix domain
+ This record matches connection attempts using Unix-domain
sockets. Without a record of this type, Unix-domain socket
connections are disallowed
</para>
numerically, not as domain or host names.) Taken together they
specify the client machine IP addresses that this record
matches. The precise logic is that
- <blockquote>
- <informalfigure>
- <programlisting>(<replaceable>actual-IP-address</replaceable> xor <replaceable>IP-address-field</replaceable>) and <replaceable>IP-mask-field</replaceable></programlisting>
- </informalfigure>
- </blockquote>
+<programlisting>
+(<replaceable>actual-IP-address</replaceable> xor <replaceable>IP-address-field</replaceable>) and <replaceable>IP-mask-field</replaceable>
+</programlisting>
must be zero for the record to match. (Of course IP addresses
can be spoofed but this consideration is beyond the scope of
<productname>PostgreSQL</productname>.) If you machine supports
<para>
The connection is allowed unconditionally. This method
allows anyone that can connect to the
- <productname>PostgreSQL</productname> database to login as
+ <productname>PostgreSQL</productname> database server to login as
any <productname>PostgreSQL</productname> user they like,
without the need for a password. See <xref
linkend="auth-trust"> for details.
<term><literal>crypt</></term>
<listitem>
<para>
- Like <literal>md5</literal> method but uses older crypt
+ Like the <literal>md5</literal> method but uses older <function>crypt()</>
encryption, which is needed for pre-7.2 clients.
<literal>md5</literal> is preferred for 7.2 and later clients.
See <xref linkend="auth-password"> for details.
<term><literal>password</></term>
<listitem>
<para>
- Same as "md5", but the password is sent in clear text over the
+ Same as <literal>md5</>, but the password is sent in clear text over the
network. This should not be used on untrusted networks.
See <xref linkend="auth-password"> for details.
</para>
<para>
If you use the map <literal>sameuser</literal>, the user
- names are assumed to be identical. If not, the map name is
+ names are required to be identical. If not, the map name is
looked up in the file <filename>pg_ident.conf</filename>
in the same directory as <filename>pg_hba.conf</filename>.
The connection is accepted if that file contains an
- entry for this map name with the ident-supplied user name
+ entry for this map name with the operating-system user name
and the requested <productname>PostgreSQL</productname> user
name.
</para>
match parameters and weaker authentication methods, while later
records will have looser match parameters and stronger authentication
methods. For example, one might wish to use <literal>trust</>
- authentication for local TCP connections but require a password for
- remote TCP connections. In this case a record specifying
+ authentication for local TCP/IP connections but require a password for
+ remote TCP/IP connections. In this case a record specifying
<literal>trust</> authentication for connections from 127.0.0.1 would
appear before a record specifying password authentication for a wider
range of allowed client IP addresses.
<important>
<para>
- Do not prevent the superuser from accessing the template1
- database. Various utility commands need access to template1.
+ Do not prevent the superuser from accessing the <literal>template1</literal>
+ database. Various utility commands need access to <literal>template1</literal>.
</para>
</important>
<para>
- <indexterm>
- <primary>SIGHUP</primary>
- </indexterm>
The <filename>pg_hba.conf</filename> file is read on start-up and when
- the <application>postmaster</> receives a
- <systemitem>SIGHUP</systemitem> signal. If you edit the file on an
- active system, you will need to signal the <application>postmaster</>
+ the main server process (<command>postmaster</>) receives a
+ <systemitem>SIGHUP</systemitem><indexterm><primary>SIGHUP</primary></indexterm>
+ signal. If you edit the file on an
+ active system, you will need to signal the <command>postmaster</>
(using <literal>pg_ctl reload</> or <literal>kill -HUP</>) to make it
re-read the file.
</para>
<para>
An example of a <filename>pg_hba.conf</filename> file is shown in
- <xref linkend="example-pg-hba.conf">. See below for details on the
+ <xref linkend="example-pg-hba.conf">. See the next section for details on the
different authentication methods.
+ </para>
<example id="example-pg-hba.conf">
<title>An example <filename>pg_hba.conf</filename> file</title>
local db1,db2,@demodbs all md5
</programlisting>
</example>
- </para>
</sect1>
<sect1 id="auth-methods">
<productname>PostgreSQL</productname> assumes that anyone who can
connect to the server is authorized to access the database as
whatever database user he specifies (including the database superuser).
- This method should only be used when there is adequate system-level
- protection on connections to the postmaster port.
+ This method should only be used when there is adequate operating system-level
+ protection on connections to the server.
</para>
<para>
convenient for local connections on a single-user workstation. It
is usually <emphasis>not</> appropriate by itself on a multiuser
machine. However, you may be able to use <literal>trust</> even
- on a multiuser machine, if you restrict access to the postmaster's
- socket file using file-system permissions. To do this, set the
+ on a multiuser machine, if you restrict access to the server's
+ Unix-domain socket file using file-system permissions. To do this, set the
<varname>unix_socket_permissions</varname> (and possibly
<varname>unix_socket_group</varname>) configuration parameters as
described in <xref linkend="runtime-config-general">. Or you
<para>
Setting file-system permissions only helps for Unix-socket connections.
- Local TCP connections are not restricted by it; therefore, if you want
- to use permissions for local security, remove the <literal>host ...
+ Local TCP/IP connections are not restricted by it; therefore, if you want
+ to use file-system permissions for local security, remove the <literal>host ...
127.0.0.1 ...</> line from <filename>pg_hba.conf</>, or change it to a
non-<literal>trust</> authentication method.
</para>
<para>
- <literal>trust</> authentication is only suitable for TCP connections
+ <literal>trust</> authentication is only suitable for TCP/IP connections
if you trust every user on every machine that is allowed to connect
to the server by the <filename>pg_hba.conf</> lines that specify
<literal>trust</>. It is seldom reasonable to use <literal>trust</>
- for any TCP connections other than those from <systemitem>localhost</> (127.0.0.1).
+ for any TCP/IP connections other than those from <systemitem>localhost</> (127.0.0.1).
</para>
</sect2>
</indexterm>
<para>
- Password-based authentication methods include <literal>md5</>,
+ The password-based authentication methods are <literal>md5</>,
<literal>crypt</>, and <literal>password</>. These methods operate
similarly except for the way that the password is sent across the
connection. If you are at all concerned about password
<productname>PostgreSQL</productname> database passwords are
separate from operating system user passwords. The password for
each database user is stored in the <literal>pg_shadow</> system
- catalog table. Passwords can be managed with the query language
+ catalog table. Passwords can be managed with the SQL
commands <command>CREATE USER</command> and <command>ALTER
USER</command>, e.g., <userinput>CREATE USER foo WITH PASSWORD
'secret';</userinput>. By default, that is, if no password has
</para>
<para>
- To restrict the set of users that are allowed to connect to certain
- databases, list the users separated by commas, or in a separate
- file. The file should contain user names separated by commas or one
- user name per line, and be in the same directory as
- <filename>pg_hba.conf</>. Mention the (base) name of the file
- preceded with <literal>@</> in the user column. The
- database column can similarly accept a list of values or
- a file name. You can also specify group names by preceding the group
- name with <literal>+</>.
+ To restrict the set of users that are allowed to connect to
+ certain databases, list the users in the <replaceable>user</>
+ column of <filename>pg_hba.conf</filename>, as explained in the
+ previous section.
</para>
</sect2>
<para>
<productname>PostgreSQL</> operates like a normal Kerberos service.
The name of the service principal is
- <replaceable>servicename/hostname@realm</>, where
+ <literal><replaceable>servicename</>/<replaceable>hostname</>@<replaceable>realm</></literal>, where
<replaceable>servicename</> is <literal>postgres</literal> (unless a
different service name was selected at configure time with
<literal>./configure --with-krb-srvnam=whatever</>).
- <replaceable>hostname</> is the fully qualified domain name of the
+ <replaceable>hostname</> is the fully qualified host name of the
server machine. The service principal's realm is the preferred realm
of the server machine.
</para>
<para>
Client principals must have their <productname>PostgreSQL</> user
name as their first component, for example
- <replaceable>pgusername/otherstuff@realm</>. At present the realm of
+ <literal>pgusername/otherstuff@realm</>. At present the realm of
the client is not checked by <productname>PostgreSQL</>; so if you
have cross-realm authentication enabled, then any principal in any
realm that can communicate with yours will be accepted.
<para>
Make sure that your server key file is readable (and preferably only
readable) by the <productname>PostgreSQL</productname> server
- account (see <xref linkend="postgres-user">). The location of the
- key file is specified with the <varname>krb_server_keyfile</> run
- time configuration parameter. (See also <xref
+ account. (See also <xref linkend="postgres-user">). The location of the
+ key file is specified with the <varname>krb_server_keyfile</> run-time
+ configuration parameter. (See also <xref
linkend="runtime-config">.) The default is <filename>/etc/srvtab</>
if you are using Kerberos 4 and
<filename>FILE:/usr/local/pgsql/etc/krb5.keytab</> (or whichever
<productname>PostgreSQL</productname> checks whether that user is
allowed to connect as the database user he is requesting to connect
as. This is controlled by the ident map argument that follows the
- <literal>ident</> keyword in the <filename>pg_hba.conf</filename>
+ <literal>ident</> key word in the <filename>pg_hba.conf</filename>
file. There is a predefined ident map <literal>sameuser</literal>,
which allows any operating system user to connect as the database
user of the same name (if the latter exists). Other maps must be
</para>
<para>
- <indexterm><primary>pg_ident.conf</primary></indexterm> Ident maps
+ Ident maps
other than <literal>sameuser</literal> are defined in the file
- <filename>pg_ident.conf</filename> in the data directory, which
- contains lines of the general form:
+ <filename>pg_ident.conf</filename><indexterm><primary>pg_ident.conf</primary></indexterm>
+ in the data directory, which contains lines of the general form:
<synopsis>
<replaceable>map-name</> <replaceable>ident-username</> <replaceable>database-username</>
</synopsis>
</para>
<para>
- <indexterm>
- <primary>SIGHUP</primary>
- </indexterm>
The <filename>pg_ident.conf</filename> file is read on start-up and
- when the <application>postmaster</> receives a
- <systemitem>SIGHUP</systemitem> signal. If you edit the file on an
- active system, you will need to signal the <application>postmaster</>
+ when the main server process (<command>postmaster</>) receives a
+ <systemitem>SIGHUP</systemitem><indexterm><primary>SIGHUP</primary></indexterm>
+ signal. If you edit the file on an
+ active system, you will need to signal the <command>postmaster</>
(using <literal>pg_ctl reload</> or <literal>kill -HUP</>) to make it
re-read the file.
</para>
linkend="example-pg-hba.conf"> is shown in <xref
linkend="example-pg-ident.conf">. In this example setup, anyone
logged in to a machine on the 192.168 network that does not have the
- Unix user name <systemitem>bryanh</>, <systemitem>ann</>, or
- <systemitem>robert</> would not be granted access. Unix user
- <systemitem>robert</> would only be allowed access when he tries to
- connect as <productname>PostgreSQL</> user <systemitem>bob</>, not
- as <systemitem>robert</> or anyone else. <systemitem>ann</> would
- only be allowed to connect as <systemitem>ann</>. User
- <systemitem>bryanh</> would be allowed to connect as either
- <systemitem>bryanh</> himself or as <systemitem>guest1</>.
+ Unix user name <literal>bryanh</>, <literal>ann</>, or
+ <literal>robert</> would not be granted access. Unix user
+ <literal>robert</> would only be allowed access when he tries to
+ connect as <productname>PostgreSQL</> user <literal>bob</>, not
+ as <literal>robert</> or anyone else. <literal>ann</> would
+ only be allowed to connect as <literal>ann</>. User
+ <literal>bryanh</> would be allowed to connect as either
+ <literal>bryanh</> himself or as <literal>guest1</>.
</para>
<example id="example-pg-ident.conf">
<title>PAM Authentication</title>
<para>
- This authentication type operates similarly to
- <firstterm>password</firstterm> except that it uses PAM (Pluggable
+ This authentication method operates similarly to
+ <literal>password</literal> except that it uses PAM (Pluggable
Authentication Modules) as the authentication mechanism. The
default PAM service name is <literal>postgresql</literal>. You can
optionally supply you own service name after the <literal>pam</>
- keyword in the file. For more information about PAM, please read
+ key word in the file <filename>pg_hba.conf</filename>. For more information about PAM, please read
the <ulink
url="http://www.kernel.org/pub/linux/libs/pam/"><productname>Linux-PAM</>
Page</ulink> and the <ulink
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.115 2003/02/19 04:06:27 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.116 2003/03/13 01:30:27 petere Exp $
-->
<chapter id="datatype">
</para>
<para>
- <xref linkend="datatype-table"> shows all general-purpose data types
- included in the standard distribution. Most of the alternative names
+ <xref linkend="datatype-table"> shows all built-in general-purpose data types.
+ Most of the alternative names
listed in the
<quote>Aliases</quote> column are the names used internally by
<productname>PostgreSQL</productname> for historical reasons. In
but they are not listed here.
</para>
- <para>
<table id="datatype-table">
<title>Data Types</title>
<tgroup cols="3">
<thead>
<row>
- <entry>Type Name</entry>
+ <entry>Name</entry>
<entry>Aliases</entry>
<entry>Description</entry>
</row>
<row>
<entry><type>box</type></entry>
<entry></entry>
- <entry>rectangular box in 2D plane</entry>
+ <entry>rectangular box in the plane</entry>
</row>
<row>
<row>
<entry><type>circle</type></entry>
<entry></entry>
- <entry>circle in 2D plane</entry>
+ <entry>circle in the plane</entry>
</row>
<row>
<row>
<entry><type>interval(<replaceable>p</replaceable>)</type></entry>
<entry></entry>
- <entry>general-use time span</entry>
+ <entry>time span</entry>
</row>
<row>
<entry><type>line</type></entry>
<entry></entry>
- <entry>infinite line in 2D plane (not implemented)</entry>
+ <entry>infinite line in the plane (not fully implemented)</entry>
</row>
<row>
<entry><type>lseg</type></entry>
<entry></entry>
- <entry>line segment in 2D plane</entry>
+ <entry>line segment in the plane</entry>
</row>
<row>
<row>
<entry><type>path</type></entry>
<entry></entry>
- <entry>open and closed geometric path in 2D plane</entry>
+ <entry>open and closed geometric path in the plane</entry>
</row>
<row>
<entry><type>point</type></entry>
<entry></entry>
- <entry>geometric point in 2D plane</entry>
+ <entry>geometric point in the plane</entry>
</row>
<row>
<entry><type>polygon</type></entry>
<entry></entry>
- <entry>closed geometric path in 2D plane</entry>
+ <entry>closed geometric path in the plane</entry>
</row>
<row>
</tbody>
</tgroup>
</table>
- </para>
<note>
<title>Compatibility</title>
to <productname>PostgreSQL</productname>, such as open and closed
paths, or have several possibilities for formats, such as the date
and time types.
- Most of the input and output functions corresponding to the
- base types (e.g., integers and floating-point numbers) do some
- error-checking.
Some of the input and output functions are not invertible. That is,
- the result of an output function may lose precision when compared to
+ the result of an output function may lose accuracy when compared to
the original input.
</para>
addition and multiplication) do not perform run-time error-checking in the
interests of improving execution speed.
On some systems, for example, the numeric operators for some data types may
- silently underflow or overflow.
+ silently cause underflow or overflow.
</para>
<sect1 id="datatype-numeric">
<tgroup cols="4">
<thead>
<row>
- <entry>Type name</entry>
- <entry>Storage size</entry>
+ <entry>Name</entry>
+ <entry>Storage Size</entry>
<entry>Description</entry>
<entry>Range</entry>
</row>
<row>
<entry><type>smallint</></entry>
<entry>2 bytes</entry>
- <entry>small range fixed-precision</entry>
+ <entry>small-range integer</entry>
<entry>-32768 to +32767</entry>
</row>
<row>
<entry><type>integer</></entry>
<entry>4 bytes</entry>
- <entry>usual choice for fixed-precision</entry>
+ <entry>usual choice for integer</entry>
<entry>-2147483648 to +2147483647</entry>
</row>
<row>
<entry><type>bigint</></entry>
<entry>8 bytes</entry>
- <entry>large range fixed-precision</entry>
+ <entry>large-range integer</entry>
<entry>-9223372036854775808 to 9223372036854775807</entry>
</row>
</para>
<sect2 id="datatype-int">
- <title>The Integer Types</title>
+ <title>Integer Types</title>
<para>
- The types <type>smallint</type>, <type>integer</type>,
+ The types <type>smallint</type>, <type>integer</type>, and
<type>bigint</type> store whole numbers, that is, numbers without
fractional components, of various ranges. Attempts to store
values outside of the allowed range will result in an error.
<title>Arbitrary Precision Numbers</title>
<para>
- The type <type>numeric</type> can store numbers with up to 1,000
+ The type <type>numeric</type> can store numbers with up to 1000
digits of precision and perform calculations exactly. It is
especially recommended for storing monetary amounts and other
quantities where exactness is required. However, the
</sect2>
<sect2 id="datatype-serial">
- <title>The Serial Types</title>
+ <title>Serial Types</title>
<indexterm zone="datatype-serial">
<primary>serial</primary>
</indexterm>
<para>
- The <type>serial</type> data type is not a true type, but merely
+ The data types <type>serial</type> and <type>bigserial</type>
+ are not true types, but merely
a notational convenience for setting up identifier columns
(similar to the <literal>AUTO_INCREMENT</literal> property
supported by some other databases). In the current
not automatic.
</para>
+ <note>
+ <para>
+ Prior to <productname>PostgreSQL</productname> 7.3, <type>serial</type>
+ implied <literal>UNIQUE</literal>. This is no longer automatic. If
+ you wish a serial column to be in a unique constraint or a
+ primary key, it must now be specified, same as with
+ any other data type.
+ </para>
+ </note>
+
<para>
To use a <type>serial</type> column to insert the next value of
the sequence into the table, specify that the <type>serial</type>
<para>
The sequence created by a <type>serial</type> type is
- automatically dropped when the owning column is dropped, and
+ automatically dropped when the owning column is dropped and
cannot be dropped otherwise. (This was not true in
<productname>PostgreSQL</productname> releases before 7.3. Note
that this automatic drop linkage will not occur for a sequence
dependency link.) Furthermore, this dependency between sequence
and column is made only for the <type>serial</> column itself; if
any other columns reference the sequence (perhaps by manually
- calling the <function>nextval()</>) function), they may be broken
+ calling the <function>nextval</>) function), they may be broken
if the sequence is removed. Using <type>serial</> columns in
fashion is considered bad form.
</para>
-
- <note>
- <para>
- Prior to <productname>PostgreSQL</> 7.3, <type>serial</type>
- implied <literal>UNIQUE</literal>. This is no longer automatic.
- If you wish a serial column to be <literal>UNIQUE</literal> or a
- <literal>PRIMARY KEY</literal> it must now be specified, just as
- with any other data type.
- </para>
- </note>
</sect2>
</sect1>
<sect1 id="datatype-money">
- <title>Monetary Type</title>
+ <title>Monetary Types</title>
<note>
- <title>Note</title>
<para>
The <type>money</type> type is deprecated. Use
<type>numeric</type> or <type>decimal</type> instead, in
- combination with the <function>to_char</function> function. The
- money type may become a locale-aware layer over the
- <type>numeric</type> type in a future release.
+ combination with the <function>to_char</function> function.
</para>
</note>
<para>
- The <type>money</type> type stores a currency amount with fixed
- decimal point representation; see <xref
- linkend="datatype-money-table">. The output format is
- locale-specific.
- </para>
-
- <para>
+ The <type>money</type> type stores a currency amount with a fixed
+ fractional precision; see <xref
+ linkend="datatype-money-table">.
Input is accepted in a variety of formats, including integer and
floating-point literals, as well as <quote>typical</quote>
currency formatting, such as <literal>'$1,000.00'</literal>.
- Output is in the latter form.
+ Output is generally in the latter form but depends on the locale.
</para>
<table id="datatype-money-table">
<tgroup cols="4">
<thead>
<row>
- <entry>Type Name</entry>
- <entry>Storage</entry>
+ <entry>Name</entry>
+ <entry>Storage Size</entry>
<entry>Description</entry>
<entry>Range</entry>
</row>
<tgroup cols="2">
<thead>
<row>
- <entry>Type name</entry>
+ <entry>Name</entry>
<entry>Description</entry>
</row>
</thead>
string.
</para>
- <note>
<para>
If one explicitly casts a value to <type>character
varying(<replaceable>n</>)</type> or
raising an error. (This too is required by the
<acronym>SQL</acronym> standard.)
</para>
- </note>
<note>
<para>
</para>
<para>
- In addition, <productname>PostgreSQL</productname> supports the
- more general <type>text</type> type, which stores strings of any
- length. Unlike <type>character varying</type>, <type>text</type>
- does not require an explicit declared upper limit on the size of
- the string. Although the type <type>text</type> is not in the
- <acronym>SQL</acronym> standard, many other RDBMS packages have it
- as well.
+ In addition, <productname>PostgreSQL</productname> provides the
+ <type>text</type> type, which stores strings of any
+ length. Although the type <type>text</type> is not in the
+ <acronym>SQL</acronym> standard, several other SQL database products
+ have it as well.
</para>
<para>
There are two other fixed-length character types in
<productname>PostgreSQL</productname>, shown in <xref
linkend="datatype-character-special-table">. The <type>name</type>
- type exists <emphasis>only</emphasis> for storage of internal
- catalog names and is not intended for use by the general user. Its
+ type exists <emphasis>only</emphasis> for storage of identifiers
+ in the internal system catalogs and is not intended for use by the general user. Its
length is currently defined as 64 bytes (63 usable characters plus
terminator) but should be referenced using the constant
<symbol>NAMEDATALEN</symbol>. The length is set at compile time (and
</para>
<table id="datatype-character-special-table">
- <title>Specialty Character Types</title>
+ <title>Special Character Types</title>
<tgroup cols="3">
<thead>
<row>
- <entry>Type Name</entry>
- <entry>Storage</entry>
+ <entry>Name</entry>
+ <entry>Storage Size</entry>
<entry>Description</entry>
</row>
</thead>
<row>
<entry><type>"char"</type></entry>
<entry>1 byte</entry>
- <entry>single character internal type</entry>
+ <entry>single-character internal type</entry>
</row>
<row>
<entry><type>name</type></entry>
<entry>64 bytes</entry>
- <entry>sixty-three character internal type</entry>
+ <entry>internal type for object names</entry>
</row>
</tbody>
</tgroup>
</sect1>
<sect1 id="datatype-binary">
- <title>Binary Strings</title>
+ <title>Binary Data Types</title>
<para>
The <type>bytea</type> data type allows storage of binary strings;
see <xref linkend="datatype-binary-table">.
</para>
<table id="datatype-binary-table">
- <title>Binary String Types</title>
+ <title>Binary Data Types</title>
<tgroup cols="3">
<thead>
<row>
- <entry>Type Name</entry>
- <entry>Storage</entry>
+ <entry>Name</entry>
+ <entry>Storage Size</entry>
<entry>Description</entry>
</row>
</thead>
<row>
<entry><type>bytea</type></entry>
<entry>4 bytes plus the actual binary string</entry>
- <entry>Variable (not specifically limited)
- length binary string</entry>
+ <entry>variable-length binary string</entry>
</row>
</tbody>
</tgroup>
A binary string is a sequence of octets (or bytes). Binary
strings are distinguished from characters strings by two
characteristics: First, binary strings specifically allow storing
- octets of zero value and other <quote>non-printable</quote>
+ octets of value zero and other <quote>non-printable</quote>
octets. Second, operations on binary strings process the actual
bytes, whereas the encoding and processing of character strings
depends on locale settings.
<row>
<entry>Decimal Octet Value</entry>
<entry>Description</entry>
- <entry>Input Escaped Representation</entry>
+ <entry>Escaped Input Representation</entry>
<entry>Example</entry>
- <entry>Printed Result</entry>
+ <entry>Output Representation</entry>
</row>
</thead>
<para>
Note that the result in each of the examples in <xref linkend="datatype-binary-sqlesc"> was exactly one
octet in length, even though the output representation of the zero
- octet and backslash are more than one character. <type>Bytea</type>
- output octets are also escaped. In general, each
- <quote>non-printable</quote> octet decimal value is converted into
- its equivalent three digit octal value, and preceded by one backslash.
+ octet and backslash are more than one character.
+ </para>
+
+ <para>
+ The reason that you have to write so many backslashes, as shown in
+ <xref linkend="datatype-binary-sqlesc">, is that an input string
+ written as a string literal must pass through two parse phases in
+ the <productname>PostgreSQL</productname> server. The first
+ backslash of each pair is interpreted as an escape character by
+ the string-literal parser and is therefore consumed, leaving the
+ second backslash of the pair. The remaining backslash is then
+ recognized by the <type>bytea</type> input function as starting
+ either a three digit octal value or escaping another backslash.
+ For example, a string literal passed to the server as
+ <literal>'\\001'</literal> becomes <literal>\001</literal> after
+ passing through the string-literal parser. The
+ <literal>\001</literal> is then sent to the <type>bytea</type>
+ input function, where it is converted to a single octet with a
+ decimal value of 1. Note that the apostrophe character is not
+ treated specially by <type>bytea</type>, so it follows the normal
+ rules for string literals. (See also <xref
+ linkend="sql-syntax-strings">.)
+ </para>
+
+ <para>
+ <type>Bytea</type> octets are also escaped in the output. In general, each
+ <quote>non-printable</quote> octet is converted into
+ its equivalent three-digit octal value and preceded by one backslash.
Most <quote>printable</quote> octets are represented by their standard
representation in the client character set. The octet with decimal
- value 92 (backslash) has a special alternate output representation.
+ value 92 (backslash) has a special alternative output representation.
Details are in <xref linkend="datatype-binary-resesc">.
</para>
<row>
<entry>Decimal Octet Value</entry>
<entry>Description</entry>
- <entry>Output Escaped Representation</entry>
+ <entry>Escaped Output Representation</entry>
<entry>Example</entry>
- <entry>Printed Result</entry>
+ <entry>Output Result</entry>
</row>
</thead>
<row>
<entry>0 to 31 and 127 to 255</entry>
<entry><quote>non-printable</quote> octets</entry>
- <entry><literal>\### (octal value)</literal></entry>
+ <entry><literal>\<replaceable>xxx</></literal> (octal value)</entry>
<entry><literal>SELECT '\\001'::bytea;</literal></entry>
<entry><literal>\001</literal></entry>
</row>
</table>
<para>
- To use the <type>bytea</type> escaped octet notation, string
- literals (input strings) must contain two backslashes because they
- must pass through two parsers in the <productname>PostgreSQL</>
- server. The first backslash is interpreted as an escape character
- by the string-literal parser, and therefore is consumed, leaving
- the characters that follow. The remaining backslash is recognized
- by the <type>bytea</type> input function as the prefix of a three
- digit octal value. For example, a string literal passed to the
- backend as <literal>'\\001'</literal> becomes
- <literal>'\001'</literal> after passing through the string-literal
- parser. The <literal>'\001'</literal> is then sent to the
- <type>bytea</type> input function, where it is converted to a
- single octet with a decimal value of 1.
- </para>
-
- <para>
- For a similar reason, a backslash must be input as
- <literal>'\\\\'</literal> (or <literal>'\\134'</literal>). The first
- and third backslashes are interpreted as escape characters by the
- string-literal parser, and therefore are consumed, leaving two
- backslashes in the string passed to the <type>bytea</type> input function,
- which interprets them as representing a single backslash.
- For example, a string literal passed to the
- server as <literal>'\\\\'</literal> becomes <literal>'\\'</literal>
- after passing through the string-literal parser. The
- <literal>'\\'</literal> is then sent to the <type>bytea</type> input
- function, where it is converted to a single octet with a decimal
- value of 92.
- </para>
-
- <para>
- A single quote is a bit different in that it must be input as
- <literal>'\''</literal> (or <literal>'\\047'</literal>),
- <emphasis>not</emphasis> as <literal>'\\''</literal>. This is because,
- while the literal parser interprets the single quote as a special
- character, and will consume the single backslash, the
- <type>bytea</type> input function does <emphasis>not</emphasis>
- recognize a single quote as a special octet. Therefore a string
- literal passed to the backend as <literal>'\''</literal> becomes
- <literal>'''</literal> after passing through the string-literal
- parser. The <literal>'''</literal> is then sent to the
- <type>bytea</type> input function, where it is retains its single
- octet decimal value of 39.
- </para>
-
- <para>
Depending on the front end to <productname>PostgreSQL</> you use,
you may have additional work to do in terms of escaping and
unescaping <type>bytea</type> strings. For example, you may also
have to escape line feeds and carriage returns if your interface
- automatically translates these. Or you may have to double up on
- backslashes if the parser for your language or choice also treats
- them as an escape character.
+ automatically translates these.
</para>
<para>
<tgroup cols="6">
<thead>
<row>
- <entry>Type</entry>
+ <entry>Name</entry>
+ <entry>Storage Size</entry>
<entry>Description</entry>
- <entry>Storage</entry>
- <entry>Earliest</entry>
- <entry>Latest</entry>
+ <entry>Low Value</entry>
+ <entry>High Value</entry>
<entry>Resolution</entry>
</row>
</thead>
<tbody>
<row>
<entry><type>timestamp [ (<replaceable>p</replaceable>) ] [ without time zone ]</type></entry>
- <entry>both date and time</entry>
<entry>8 bytes</entry>
+ <entry>both date and time</entry>
<entry>4713 BC</entry>
<entry>AD 5874897</entry>
<entry>1 microsecond / 14 digits</entry>
</row>
<row>
<entry><type>timestamp [ (<replaceable>p</replaceable>) ] with time zone</type></entry>
- <entry>both date and time</entry>
<entry>8 bytes</entry>
+ <entry>both date and time, with time zone</entry>
<entry>4713 BC</entry>
<entry>AD 5874897</entry>
<entry>1 microsecond / 14 digits</entry>
</row>
<row>
<entry><type>interval [ (<replaceable>p</replaceable>) ]</type></entry>
- <entry>time intervals</entry>
<entry>12 bytes</entry>
+ <entry>time intervals</entry>
<entry>-178000000 years</entry>
<entry>178000000 years</entry>
<entry>1 microsecond</entry>
</row>
<row>
<entry><type>date</type></entry>
- <entry>dates only</entry>
<entry>4 bytes</entry>
+ <entry>dates only</entry>
<entry>4713 BC</entry>
<entry>32767 AD</entry>
<entry>1 day</entry>
</row>
<row>
<entry><type>time [ (<replaceable>p</replaceable>) ] [ without time zone ]</type></entry>
- <entry>times of day only</entry>
<entry>8 bytes</entry>
+ <entry>times of day only</entry>
<entry>00:00:00.00</entry>
<entry>23:59:59.99</entry>
<entry>1 microsecond</entry>
</row>
<row>
<entry><type>time [ (<replaceable>p</replaceable>) ] with time zone</type></entry>
- <entry>times of day only</entry>
<entry>12 bytes</entry>
+ <entry>times of day only, with time zone</entry>
<entry>00:00:00.00+12</entry>
<entry>23:59:59.99-12</entry>
<entry>1 microsecond</entry>
<para>
When <type>timestamp</> values are stored as double precision floating-point
numbers (currently the default), the effective limit of precision
- may be less than 6, since timestamp values are stored as seconds
- since 2000-01-01. Microsecond precision is achieved for dates within
+ may be less than 6. Timestamp values are stored as seconds
+ since 2000-01-01, and microsecond precision is achieved for dates within
a few years of 2000-01-01, but the precision degrades for dates further
away. When timestamps are stored as eight-byte integers (a compile-time
option), microsecond precision is available over the full range of
</para>
</note>
+ <note>
+ <para>
+ Prior to <productname>PostgreSQL</productname> 7.3, writing just
+ <type>timestamp</type> was equivalent to <type>timestamp with
+ time zone</type>. This was changed for SQL compliance.
+ </para>
+ </note>
+
<para>
For the <type>time</type> types, the allowed range of
<replaceable>p</replaceable> is from 0 to 6 when eight-byte integer
</para>
<para>
- Time zones, and time-zone conventions, are influenced by
- political decisions, not just earth geometry. Time zones around the
- world became somewhat standardized during the 1900's,
- but continue to be prone to arbitrary changes.
- <productname>PostgreSQL</productname> uses your operating
- system's underlying features to provide output time-zone
- support, and these systems usually contain information for only
- the time period 1902 through 2038 (corresponding to the full
- range of conventional Unix system time).
- <type>timestamp with time zone</type> and <type>time with time
- zone</type> will use time zone
- information only within that year range, and assume that times
- outside that range are in <acronym>UTC</acronym>.
- </para>
-
- <para>
The type <type>time with time zone</type> is defined by the SQL
standard, but the definition exhibits properties which lead to
questionable usefulness. In most cases, a combination of
<type>date</type>, <type>time</type>, <type>timestamp without time
- zone</type> and <type>timestamp with time zone</type> should
+ zone</type>, and <type>timestamp with time zone</type> should
provide a complete range of date/time functionality required by
any application.
</para>
<para>
Date and time input is accepted in almost any reasonable format, including
- <acronym>ISO 8601</acronym>, <acronym>SQL</acronym>-compatible,
- traditional <productname>PostgreSQL</productname>, and others.
+ ISO 8601, <acronym>SQL</acronym>-compatible,
+ traditional <productname>POSTGRES</productname>, and others.
For some formats, ordering of month and day in date input can be
ambiguous and there is support for specifying the expected
ordering of these fields.
The command
- <literal>SET DateStyle TO 'US'</literal>
- or <literal>SET DateStyle TO 'NonEuropean'</literal>
+ <literal>SET datestyle TO 'US'</literal>
+ or <literal>SET datestyle TO 'NonEuropean'</literal>
specifies the variant <quote>month before day</quote>, the command
- <literal>SET DateStyle TO 'European'</literal> sets the variant
+ <literal>SET datestyle TO 'European'</literal> sets the variant
<quote>day before month</quote>.
</para>
<para>
<productname>PostgreSQL</productname> is more flexible in
- handling date/time than the
+ handling date/time input than the
<acronym>SQL</acronym> standard requires.
See <xref linkend="datetime-appendix">
for the exact parsing rules of date/time input and for the
<replaceable>type</replaceable> [ (<replaceable>p</replaceable>) ] '<replaceable>value</replaceable>'
</synopsis>
where <replaceable>p</replaceable> in the optional precision
- specification is an integer corresponding to the
- number of fractional digits in the seconds field. Precision can
- be specified
- for <type>time</type>, <type>timestamp</type>, and
- <type>interval</type> types.
+ specification is an integer corresponding to the number of
+ fractional digits in the seconds field. Precision can be
+ specified for <type>time</type>, <type>timestamp</type>, and
+ <type>interval</type> types. The allowed values are mentioned
+ above. If no precision is specified in a constant specification,
+ it defaults to the precision of the literal value.
</para>
<sect3>
</row>
<row>
<entry>1/8/1999</entry>
- <entry>U.S.; read as August 1 in European mode</entry>
- </row>
- <row>
- <entry>8/1/1999</entry>
- <entry>European; read as August 1 in U.S. mode</entry>
+ <entry>ambiguous (January 8 in U.S. mode; August 1 in European mode)</entry>
</row>
<row>
<entry>1/18/1999</entry>
- <entry>U.S.; read as January 18 in any mode</entry>
+ <entry>U.S. notation; January 18 in any mode</entry>
</row>
<row>
<entry>19990108</entry>
- <entry>ISO-8601 year, month, day</entry>
+ <entry>ISO-8601; year, month, day</entry>
</row>
<row>
<entry>990108</entry>
- <entry>ISO-8601 year, month, day</entry>
+ <entry>ISO-8601; year, month, day</entry>
</row>
<row>
<entry>1999.008</entry>
</para>
<para>
- Valid input for these types consists of a time of day followed by an
- optional time zone. (See <xref linkend="datatype-datetime-time-table">.)
- The optional precision
- <replaceable>p</replaceable> should be between 0 and 6, and
- defaults to the precision of the input time literal. If a time zone
- is specified in the input for <type>time without time zone</type>,
+ Valid input for these types consists of a time of day followed
+ by an optional time zone. (See <xref
+ linkend="datatype-datetime-time-table">.) If a time zone is
+ specified in the input for <type>time without time zone</type>,
it is silently ignored.
</para>
</sect3>
<sect3>
- <title>Time stamps</title>
+ <title>Time Stamps</title>
<indexterm>
<primary>timestamp</primary>
</indexterm>
<para>
- The time stamp types are <type>timestamp [
- (<replaceable>p</replaceable>) ] without time zone</type> and
- <type>timestamp [ (<replaceable>p</replaceable>) ] with time
- zone</type>. Writing just <type>timestamp</type> is equivalent to
- <type>timestamp without time zone</type>.
- </para>
-
- <note>
- <para>
- Prior to <productname>PostgreSQL</productname> 7.3, writing just
- <type>timestamp</type> was equivalent to <type>timestamp with time
- zone</type>. This was changed for SQL spec compliance.
- </para>
- </note>
-
- <para>
Valid input for the time stamp types consists of a concatenation
of a date and a time, followed by an optional
<literal>AD</literal> or <literal>BC</literal>, followed by an
</para>
<para>
- The optional precision
- <replaceable>p</replaceable> should be between 0 and 6, and
- defaults to the precision of the input <type>timestamp</type> literal.
- </para>
-
- <para>
- For <type>timestamp without time zone</type>, any explicit time
+ For <type>timestamp [without time zone]</type>, any explicit time
zone specified in the input is silently ignored. That is, the
resulting date/time value is derived from the explicit date/time
fields in the input value, and is not adjusted for time zone.
<para>
For <type>timestamp with time zone</type>, the internally stored
- value is always in UTC (GMT). An input value that has an explicit
+ value is always in UTC (Universal
+ Coordinated Time, traditionally known as Greenwich Mean Time,
+ <acronym>GMT</>). An input value that has an explicit
time zone specified is converted to UTC using the appropriate offset
for that time zone. If no time zone is stated in the input string,
then it is assumed to be in the time zone indicated by the system's
- <varname>TimeZone</> parameter, and is converted to UTC using the
- offset for the <varname>TimeZone</> zone.
+ <varname>timezone</> parameter, and is converted to UTC using the
+ offset for the <varname>timezone</> zone.
</para>
<para>
When a <type>timestamp with time
zone</type> value is output, it is always converted from UTC to the
- current <varname>TimeZone</> zone, and displayed as local time in that
+ current <varname>timezone</> zone, and displayed as local time in that
zone. To see the time in another time zone, either change
- <varname>TimeZone</> or use the <literal>AT TIME ZONE</> construct
+ <varname>timezone</> or use the <literal>AT TIME ZONE</> construct
(see <xref linkend="functions-datetime-zoneconvert">).
</para>
Conversions between <type>timestamp without time zone</type> and
<type>timestamp with time zone</type> normally assume that the
<type>timestamp without time zone</type> value should be taken or given
- as <varname>TimeZone</> local time. A different zone reference can
+ as <varname>timezone</> local time. A different zone reference can
be specified for the conversion using <literal>AT TIME ZONE</>.
</para>
<tgroup cols="2">
<thead>
<row>
- <entry>Time Zone</entry>
+ <entry>Example</entry>
<entry>Description</entry>
</row>
</thead>
<type>interval</type> values can be written with the following syntax:
<programlisting>
- Quantity Unit [Quantity Unit...] [Direction]
-@ Quantity Unit [Quantity Unit...] [Direction]
+<optional>@</> <replaceable>quantity</> <replaceable>unit</> <optional><replaceable>quantity</> <replaceable>unit</>...</> <optional><replaceable>direction</></optional>
</programlisting>
- where: <literal>Quantity</literal> is a number (possibly signed),
- <literal>Unit</literal> is <literal>second</literal>,
+ Where: <replaceable>quantity</> is a number (possibly signed);
+ <replaceable>unit</> is <literal>second</literal>,
<literal>minute</literal>, <literal>hour</literal>, <literal>day</literal>,
<literal>week</literal>, <literal>month</literal>, <literal>year</literal>,
<literal>decade</literal>, <literal>century</literal>, <literal>millennium</literal>,
or abbreviations or plurals of these units;
- <literal>Direction</literal> can be <literal>ago</literal> or
+ <replaceable>direction</> can be <literal>ago</literal> or
empty. The at sign (<literal>@</>) is optional noise. The amounts
of different units are implicitly added up with appropriate
sign accounting.
</sect3>
<sect3>
- <title>Special values</title>
+ <title>Special Values</title>
<indexterm>
<primary>time</primary>
are specially represented inside the system and will be displayed
the same way; but the others are simply notational shorthands
that will be converted to ordinary date/time values when read.
+ All of these values are treated as normal constants and need to be
+ written in single quotes.
</para>
<table id="datatype-datetime-special-table">
<tgroup cols="2">
<thead>
<row>
- <entry>Input string</entry>
+ <entry>Input String</entry>
+ <entry>Valid Types</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>epoch</literal></entry>
+ <entry><type>date</type>, <type>timestamp</type></entry>
<entry>1970-01-01 00:00:00+00 (Unix system time zero)</entry>
</row>
<row>
<entry><literal>infinity</literal></entry>
- <entry>later than all other timestamps (not available for
- type <type>date</>)</entry>
+ <entry><type>timestamp</type></entry>
+ <entry>later than all other time stamps</entry>
</row>
<row>
<entry><literal>-infinity</literal></entry>
- <entry>earlier than all other timestamps (not available for
- type <type>date</>)</entry>
+ <entry><type>timestamp</type></entry>
+ <entry>earlier than all other time stamps</entry>
</row>
<row>
<entry><literal>now</literal></entry>
+ <entry><type>date</type>, <type>time</type>, <type>timestamp</type></entry>
<entry>current transaction time</entry>
</row>
<row>
<entry><literal>today</literal></entry>
+ <entry><type>date</type>, <type>timestamp</type></entry>
<entry>midnight today</entry>
</row>
<row>
<entry><literal>tomorrow</literal></entry>
+ <entry><type>date</type>, <type>timestamp</type></entry>
<entry>midnight tomorrow</entry>
</row>
<row>
<entry><literal>yesterday</literal></entry>
+ <entry><type>date</type>, <type>timestamp</type></entry>
<entry>midnight yesterday</entry>
</row>
<row>
<entry><literal>zulu</>, <literal>allballs</>, <literal>z</></entry>
- <entry>00:00:00.00 GMT</entry>
+ <entry><type>time</type></entry>
+ <entry>00:00:00.00 UTC</entry>
</row>
</tbody>
</tgroup>
</indexterm>
<para>
- Output formats can be set to one of the four styles ISO 8601,
- <acronym>SQL</acronym> (Ingres), traditional PostgreSQL, and
- German, using the <command>SET DateStyle</command>. The default
+ The output format of the date/time types can be set to one of the four styles ISO 8601,
+ <acronym>SQL</acronym> (Ingres), traditional POSTGRES, and
+ German, using the <literal>SET datestyle</literal>. The default
is the <acronym>ISO</acronym> format. (The
<acronym>SQL</acronym> standard requires the use of the ISO 8601
format. The name of the <quote>SQL</quote> output format is a
<entry>12/17/1997 07:37:16.00 PST</entry>
</row>
<row>
- <entry>PostgreSQL</entry>
+ <entry>POSTGRES</entry>
<entry>original style</entry>
<entry>Wed Dec 17 07:37:16 1997 PST</entry>
</row>
<row>
<entry>European</entry>
<entry><replaceable>day</replaceable>/<replaceable>month</replaceable>/<replaceable>year</replaceable></entry>
- <entry>17/12/1997 15:37:16.00 MET</entry>
+ <entry>17/12/1997 15:37:16.00 CET</entry>
</row>
<row>
<entry>US</entry>
</table>
<para>
- <type>interval</type> output looks like the input format, except that units like
- <literal>week</literal> or <literal>century</literal> are converted to years and days.
- In ISO mode the output looks like
+ <type>interval</type> output looks like the input format, except
+ that units like <literal>century</literal> or
+ <literal>wek</literal> are converted to years and days and that
+ <literal>ago</literal> is converted to an appropriate sign. In
+ ISO mode the output looks like
<programlisting>
-[ Quantity Units [ ... ] ] [ Days ] Hours:Minutes [ ago ]
+<optional> <replaceable>quantity</> <replaceable>unit</> <optional> ... </> </> <optional> <replaceable>days</> </> <optional> <replaceable>hours</>:<replaceable>minutes</>:<replaceable>sekunden</> </optional>
</programlisting>
</para>
<para>
The date/time styles can be selected by the user using the
- <command>SET DATESTYLE</command> command, the
+ <command>SET datestyle</command> command, the
<varname>datestyle</varname> parameter in the
<filename>postgresql.conf</filename> configuration file, and the
<envar>PGDATESTYLE</envar> environment variable on the server or
<primary>time zones</primary>
</indexterm>
+ <para>
+ Time zones, and time-zone conventions, are influenced by
+ political decisions, not just earth geometry. Time zones around the
+ world became somewhat standardized during the 1900's,
+ but continue to be prone to arbitrary changes.
+ <productname>PostgreSQL</productname> uses your operating
+ system's underlying features to provide output time-zone
+ support, and these systems usually contain information for only
+ the time period 1902 through 2038 (corresponding to the full
+ range of conventional Unix system time).
+ <type>timestamp with time zone</type> and <type>time with time
+ zone</type> will use time zone
+ information only within that year range, and assume that times
+ outside that range are in <acronym>UTC</acronym>.
+ But since time zone support is derived from the underlying operating
+ system time-zone capabilities, it can handle daylight-saving time
+ and other special behavior.
+ </para>
+
<para>
<productname>PostgreSQL</productname> endeavors to be compatible with
the <acronym>SQL</acronym> standard definitions for typical usage.
<listitem>
<para>
- The default time zone is specified as a constant integer offset
- from <acronym>GMT</>/<acronym>UTC</>. It is not possible to adapt to daylight-saving
+ The default time zone is specified as a constant numeric offset
+ from <acronym>UTC</>. It is not possible to adapt to daylight-saving
time when doing date/time arithmetic across
<acronym>DST</acronym> boundaries.
</para>
<productname>PostgreSQL</productname> for legacy applications and
for compatibility with other <acronym>SQL</acronym>
implementations). <productname>PostgreSQL</productname> assumes
- your local time zone for any type containing only date or
- time. Further, time zone support is derived from the underlying
- operating system time-zone capabilities, and hence can handle
- daylight-saving time and other expected behavior.
- </para>
-
- <para>
- <productname>PostgreSQL</productname> obtains time-zone support
- from the underlying operating system for dates between 1902 and
- 2038 (near the typical date limits for Unix-style
- systems). Outside of this range, all dates are assumed to be
- specified and used in Universal Coordinated Time
- (<acronym>UTC</acronym>).
+ your local time zone for any type containing only date or time.
</para>
<para>
All dates and times are stored internally in
- <acronym>UTC</acronym>, traditionally known as Greenwich Mean
- Time (<acronym>GMT</acronym>). Times are converted to local time
- on the database server before being sent to the client frontend,
+ <acronym>UTC</acronym>. Times are converted to local time
+ on the database server before being sent to the client,
hence by default are in the server time zone.
</para>
<listitem>
<para>
The <varname>timezone</varname> configuration parameter can be
- set in <filename>postgresql.conf</>.
+ set in the file <filename>postgresql.conf</>.
</para>
</listitem>
<tgroup cols="4">
<thead>
<row>
- <entry>Geometric Type</entry>
- <entry>Storage</entry>
+ <entry>Name</entry>
+ <entry>Storage Size</entry>
<entry>Representation</entry>
<entry>Description</entry>
</row>
<row>
<entry><type>point</type></entry>
<entry>16 bytes</entry>
+ <entry>Point on the plane</entry>
<entry>(x,y)</entry>
- <entry>Point in space</entry>
</row>
<row>
<entry><type>line</type></entry>
<entry>32 bytes</entry>
- <entry>((x1,y1),(x2,y2))</entry>
<entry>Infinite line (not fully implemented)</entry>
+ <entry>((x1,y1),(x2,y2))</entry>
</row>
<row>
<entry><type>lseg</type></entry>
<entry>32 bytes</entry>
- <entry>((x1,y1),(x2,y2))</entry>
<entry>Finite line segment</entry>
+ <entry>((x1,y1),(x2,y2))</entry>
</row>
<row>
<entry><type>box</type></entry>
<entry>32 bytes</entry>
- <entry>((x1,y1),(x2,y2))</entry>
<entry>Rectangular box</entry>
+ <entry>((x1,y1),(x2,y2))</entry>
</row>
<row>
<entry><type>path</type></entry>
<entry>16+16n bytes</entry>
- <entry>((x1,y1),...)</entry>
<entry>Closed path (similar to polygon)</entry>
+ <entry>((x1,y1),...)</entry>
</row>
<row>
<entry><type>path</type></entry>
<entry>16+16n bytes</entry>
- <entry>[(x1,y1),...]</entry>
<entry>Open path</entry>
+ <entry>[(x1,y1),...]</entry>
</row>
<row>
<entry><type>polygon</type></entry>
<entry>40+16n bytes</entry>
- <entry>((x1,y1),...)</entry>
<entry>Polygon (similar to closed path)</entry>
+ <entry>((x1,y1),...)</entry>
</row>
<row>
<entry><type>circle</type></entry>
<entry>24 bytes</entry>
- <entry><(x,y),r></entry>
- <entry>Circle (center and radius)</entry>
+ <entry>Circle</entry>
+ <entry><(x,y),r> (center and radius)</entry>
</row>
</tbody>
</tgroup>
</para>
<sect2>
- <title>Point</title>
+ <title>Points</title>
<indexterm>
<primary>point</primary>
<para>
Points are the fundamental two-dimensional building block for geometric types.
- <type>point</type> is specified using the following syntax:
+ Values of type <type>point</type> are specified using the following syntax:
<synopsis>
( <replaceable>x</replaceable> , <replaceable>y</replaceable> )
<replaceable>x</replaceable> , <replaceable>y</replaceable>
</synopsis>
- where the arguments are
-
- <variablelist>
- <varlistentry>
- <term><replaceable>x</replaceable></term>
- <listitem>
- <para>
- the x-axis coordinate as a floating-point number
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><replaceable>y</replaceable></term>
- <listitem>
- <para>
- the y-axis coordinate as a floating-point number
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
+ where <replaceable>x</> and <replaceable>y</> are the respective
+ coordinates as floating-point numbers.
</para>
</sect2>
<sect2>
- <title>Line Segment</title>
+ <title>Line Segments</title>
<indexterm>
<primary>line</primary>
<para>
Line segments (<type>lseg</type>) are represented by pairs of points.
- <type>lseg</type> is specified using the following syntax:
+ Values of type <type>lseg</type> are specified using the following syntax:
<synopsis>
( ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ( <replaceable>x2</replaceable> , <replaceable>y2</replaceable> ) )
<replaceable>x1</replaceable> , <replaceable>y1</replaceable> , <replaceable>x2</replaceable> , <replaceable>y2</replaceable>
</synopsis>
- where the arguments are
-
- <variablelist>
- <varlistentry>
- <term>(<replaceable>x1</replaceable>,<replaceable>y1</replaceable>)</term>
- <term>(<replaceable>x2</replaceable>,<replaceable>y2</replaceable>)</term>
- <listitem>
- <para>
- the end points of the line segment
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
+ where
+ <literal>(<replaceable>x1</replaceable>,<replaceable>y1</replaceable>)</literal>
+ and
+ <literal>(<replaceable>x2</replaceable>,<replaceable>y2</replaceable>)</literal>
+ are the end points of the line segment.
</para>
</sect2>
<sect2>
- <title>Box</title>
+ <title>Boxes</title>
<indexterm>
<primary>box (data type)</primary>
<para>
Boxes are represented by pairs of points that are opposite
corners of the box.
- <type>box</type> is specified using the following syntax:
+ Values of type <type>box</type> is specified using the following syntax:
<synopsis>
( ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ( <replaceable>x2</replaceable> , <replaceable>y2</replaceable> ) )
<replaceable>x1</replaceable> , <replaceable>y1</replaceable> , <replaceable>x2</replaceable> , <replaceable>y2</replaceable>
</synopsis>
- where the arguments are
-
- <variablelist>
- <varlistentry>
- <term>(<replaceable>x1</replaceable>,<replaceable>y1</replaceable>)</term>
- <term>(<replaceable>x2</replaceable>,<replaceable>y2</replaceable>)</term>
- <listitem>
- <para>
- opposite corners of the box
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
+ where
+ <literal>(<replaceable>x1</replaceable>,<replaceable>y1</replaceable>)</literal>
+ and
+ <literal>(<replaceable>x2</replaceable>,<replaceable>y2</replaceable>)</literal>
+ are the opposite corners of the box.
</para>
<para>
</sect2>
<sect2>
- <title>Path</title>
+ <title>Paths</title>
<indexterm>
<primary>path (data type)</primary>
Paths are represented by connected sets of points. Paths can be
<firstterm>open</firstterm>, where
the first and last points in the set are not connected, and <firstterm>closed</firstterm>,
- where the first and last point are connected. Functions
- <function>popen(p)</function>
+ where the first and last point are connected. The functions
+ <function>popen(<replaceable>p</>)</function>
and
- <function>pclose(p)</function>
- are supplied to force a path to be open or closed, and functions
- <function>isopen(p)</function>
+ <function>pclose(<replaceable>p</>)</function>
+ are supplied to force a path to be open or closed, and the functions
+ <function>isopen(<replaceable>p</>)</function>
and
- <function>isclosed(p)</function>
- are supplied to test for either type in a query.
+ <function>isclosed(<replaceable>p</>)</function>
+ are supplied to test for either type in an expression.
</para>
<para>
- <type>path</type> is specified using the following syntax:
+ Values of type <type>path</type> are specified using the following syntax:
<synopsis>
( ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ... , ( <replaceable>xn</replaceable> , <replaceable>yn</replaceable> ) )
<replaceable>x1</replaceable> , <replaceable>y1</replaceable> , ... , <replaceable>xn</replaceable> , <replaceable>yn</replaceable>
</synopsis>
- where the arguments are
-
- <variablelist>
- <varlistentry>
- <term>(<replaceable>x</replaceable>,<replaceable>y</replaceable>)</term>
- <listitem>
- <para>
- End points of the line segments comprising the path.
- A leading square bracket (<literal>[</>) indicates an open path, while
- a leading parenthesis (<literal>(</>) indicates a closed path.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
+ where the points are the end points of the line segments
+ comprising the path. Square brackets (<literal>[]</>) indicate
+ an open path, while parentheses (<literal>()</>) indicate a
+ closed path.
</para>
<para>
</sect2>
<sect2>
- <title>Polygon</title>
+ <title>Polygons</title>
<indexterm>
<primary>polygon</primary>
</para>
<para>
- <type>polygon</type> is specified using the following syntax:
+ Values of type <type>polygon</type> are specified using the following syntax:
<synopsis>
( ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ... , ( <replaceable>xn</replaceable> , <replaceable>yn</replaceable> ) )
<replaceable>x1</replaceable> , <replaceable>y1</replaceable> , ... , <replaceable>xn</replaceable> , <replaceable>yn</replaceable>
</synopsis>
- where the arguments are
-
- <variablelist>
- <varlistentry>
- <term>(<replaceable>x</replaceable>,<replaceable>y</replaceable>)</term>
- <listitem>
- <para>
- End points of the line segments comprising the boundary of the
- polygon
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
+ where the points are the end points of the line segments
+ comprising the boundary of the polygon.
</para>
<para>
</sect2>
<sect2>
- <title>Circle</title>
+ <title>Circles</title>
<indexterm>
<primary>circle</primary>
<para>
Circles are represented by a center point and a radius.
- <type>circle</type> is specified using the following syntax:
+ Values of type <type>circle</type> are specified using the following syntax:
<synopsis>
< ( <replaceable>x</replaceable> , <replaceable>y</replaceable> ) , <replaceable>r</replaceable> >
<replaceable>x</replaceable> , <replaceable>y</replaceable> , <replaceable>r</replaceable>
</synopsis>
- where the arguments are
-
- <variablelist>
- <varlistentry>
- <term>(<replaceable>x</replaceable>,<replaceable>y</replaceable>)</term>
- <listitem>
- <para>
- center of the circle
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><replaceable>r</replaceable></term>
- <listitem>
- <para>
- radius of the circle
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
+ where
+ <literal>(<replaceable>x</replaceable>,<replaceable>y</replaceable>)</literal>
+ is the center and <replaceable>r</replaceable> is the radius of the circle.
</para>
<para>
</sect1>
<sect1 id="datatype-net-types">
- <title>Network Address Data Types</title>
+ <title>Network Address Types</title>
<indexterm zone="datatype-net-types">
<primary>network</primary>
</para>
<table tocentry="1" id="datatype-net-types-table">
- <title>Network Address Data Types</title>
- <tgroup cols="4">
+ <title>Network Address Types</title>
+ <tgroup cols="3">
<thead>
<row>
<entry>Name</entry>
- <entry>Storage</entry>
+ <entry>Storage Size</entry>
<entry>Description</entry>
- <entry>Range</entry>
</row>
</thead>
<tbody>
<row>
<entry><type>cidr</type></entry>
<entry>12 bytes</entry>
- <entry>IP networks</entry>
- <entry>valid IPv4 networks</entry>
+ <entry>IPv4 networks</entry>
</row>
<row>
<entry><type>inet</type></entry>
<entry>12 bytes</entry>
- <entry>IP hosts and networks</entry>
- <entry>valid IPv4 hosts or networks</entry>
+ <entry>IPv4 hosts and networks</entry>
</row>
<row>
<entry><type>macaddr</type></entry>
<entry>6 bytes</entry>
<entry>MAC addresses</entry>
- <entry>customary formats</entry>
</row>
</tbody>
<para>
The <type>inet</type> type holds an IP host address, and
optionally the identity of the subnet it is in, all in one field.
- The subnet identity is represented by the number of bits in the
- network part of the address (the <quote>netmask</quote>). If the
- netmask is 32,
- then the value does not indicate a subnet, only a single host.
- Note that if you want to accept networks only, you should use the
+ The subnet identity is represented by stating how many bits of
+ the host address represent the network address (the
+ <quote>netmask</quote>). If the netmask is 32, then the value
+ does not indicate a subnet, only a single host. Note that if you
+ want to accept networks only, you should use the
<type>cidr</type> type rather than <type>inet</type>.
</para>
The <type>cidr</type> type holds an IP network specification.
Input and output formats follow Classless Internet Domain Routing
conventions.
- The format for
- specifying classless networks is <replaceable
+ The format for specifying networks is <replaceable
class="parameter">x.x.x.x/y</> where <replaceable
class="parameter">x.x.x.x</> is the network and <replaceable
class="parameter">y</> is the number of bits in the netmask. If
<replaceable class="parameter">y</> is omitted, it is calculated
- using assumptions from the older classful numbering system, except
+ using assumptions from the older classful network numbering system, except
that it will be at least large enough to include all of the octets
- written in the input.
+ written in the input. It is an error to specify a network address
+ that has bits set to the right of the specified netmask.
</para>
<para>
<tgroup cols="3">
<thead>
<row>
- <entry><type>CIDR</type> Input</entry>
- <entry><type>CIDR</type> Displayed</entry>
- <entry><function>abbrev</function>(<type>CIDR</type>)</entry>
+ <entry><type>cidr</type> Input</entry>
+ <entry><type>cidr</type> Output</entry>
+ <entry><literal><function>abbrev</function>(<type>cidr</type>)</literal></entry>
</row>
</thead>
<tbody>
</sect2>
<sect2 id="datatype-inet-vs-cidr">
- <title><type>inet</type> vs <type>cidr</type></title>
+ <title><type>inet</type> vs. <type>cidr</type></title>
<para>
The essential difference between <type>inet</type> and <type>cidr</type>
data types is that <type>inet</type> accepts values with nonzero bits to
the right of the netmask, whereas <type>cidr</type> does not.
+ </para>
<tip>
<para>
If you do not like the output format for <type>inet</type> or
- <type>cidr</type> values, try the <function>host</>(),
- <function>text</>(), and <function>abbrev</>() functions.
+ <type>cidr</type> values, try the functions <function>host</>,
+ <function>text</>, and <function>abbrev</>.
</para>
</tip>
- </para>
</sect2>
<sect2 id="datatype-macaddr">
<para>
Bit strings are strings of 1's and 0's. They can be used to store
or visualize bit masks. There are two SQL bit types:
- <type>BIT(<replaceable>n</replaceable>)</type> and <type>BIT
- VARYING(<replaceable>n</replaceable>)</type>, where
+ <type>bit(<replaceable>n</replaceable>)</type> and <type>bit
+ varying(<replaceable>n</replaceable>)</type>, where
<replaceable>n</replaceable> is a positive integer.
</para>
<para>
- <type>BIT</type> type data must match the length
+ <type>bit</type> type data must match the length
<replaceable>n</replaceable> exactly; it is an error to attempt to
- store shorter or longer bit strings. <type>BIT VARYING</type> data is
+ store shorter or longer bit strings. <type>bit varying</type> data is
of variable length up to the maximum length
<replaceable>n</replaceable>; longer strings will be rejected.
- Writing <type>BIT</type> without a length is equivalent to
- <literal>BIT(1)</literal>, while <type>BIT VARYING</type> without a length
+ Writing <type>bit</type> without a length is equivalent to
+ <literal>bit(1)</literal>, while <type>bit varying</type> without a length
specification means unlimited length.
</para>
<note>
<para>
If one explicitly casts a bit-string value to
- <type>BIT(<replaceable>n</>)</type>, it will be truncated or
+ <type>bit(<replaceable>n</>)</type>, it will be truncated or
zero-padded on the right to be exactly <replaceable>n</> bits,
without raising an error. Similarly,
if one explicitly casts a bit-string value to
- <type>BIT VARYING(<replaceable>n</>)</type>, it will be truncated
+ <type>bit varying(<replaceable>n</>)</type>, it will be truncated
on the right if it is more than <replaceable>n</> bits.
</para>
</note>
<note>
<para>
- Prior to <productname>PostgreSQL</> 7.2, <type>BIT</type> data
+ Prior to <productname>PostgreSQL</> 7.2, <type>bit</type> data
was always silently truncated or zero-padded on the right, with
or without an explicit cast. This was changed to comply with the
<acronym>SQL</acronym> standard.
</sect1>
+ &array;
+
<sect1 id="datatype-oid">
<title>Object Identifier Types</title>
tables. Also, an OID system column is added to user-created tables
(unless <literal>WITHOUT OIDS</> is specified at table creation time).
Type <type>oid</> represents an object identifier. There are also
- several aliases for <type>oid</>: <type>regproc</>, <type>regprocedure</>,
+ several alias types for <type>oid</>: <type>regproc</>, <type>regprocedure</>,
<type>regoper</>, <type>regoperator</>, <type>regclass</>,
and <type>regtype</>. <xref linkend="datatype-oid-table"> shows an overview.
</para>
</para>
<para>
- The <type>oid</> type itself has few operations beyond comparison
- (which is implemented as unsigned comparison). It can be cast to
+ The <type>oid</> type itself has few operations beyond comparison.
+ It can be cast to
integer, however, and then manipulated using the standard integer
operators. (Beware of possible signed-versus-unsigned confusion
if you do this.)
</para>
<para>
- The <type>oid</> alias types have no operations of their own except
+ The OID alias types have no operations of their own except
for specialized input and output routines. These routines are able
to accept and display symbolic names for system objects, rather than
the raw numeric value that type <type>oid</> would use. The alias
<tgroup cols="4">
<thead>
<row>
- <entry>Type name</entry>
+ <entry>Name</entry>
<entry>References</entry>
<entry>Description</entry>
- <entry>Value example</entry>
+ <entry>Value Example</entry>
</row>
</thead>
<row>
<entry><type>regtype</></entry>
<entry><structname>pg_type</></entry>
- <entry>type name</entry>
+ <entry>data type name</entry>
<entry><literal>integer</></entry>
</row>
</tbody>
</para>
<para>
- OIDs are 32-bit quantities and are assigned from a single cluster-wide
- counter. In a large or long-lived database, it is possible for the
- counter to wrap around. Hence, it is bad practice to assume that OIDs
- are unique, unless you take steps to ensure that they are unique.
- Recommended practice when using OIDs for row identification is to create
- a unique constraint on the OID column of each table for which the OID will
- be used. Never assume that OIDs are unique across tables; use the
- combination of <structfield>tableoid</> and row OID if you need a
- database-wide identifier. (Future releases of
- <productname>PostgreSQL</productname> are likely to use a separate
- OID counter for each table, so that <structfield>tableoid</>
- <emphasis>must</> be included to arrive at a globally unique identifier.)
- </para>
-
- <para>
Another identifier type used by the system is <type>xid</>, or transaction
(abbreviated <abbrev>xact</>) identifier. This is the data type of the system columns
- <structfield>xmin</> and <structfield>xmax</>.
- Transaction identifiers are 32-bit quantities. In a long-lived
- database it is possible for transaction IDs to wrap around. This
- is not a fatal problem given appropriate maintenance procedures;
- see the &cite-admin; for details. However, it is
- unwise to depend on uniqueness of transaction IDs over the long term
- (more than one billion transactions).
+ <structfield>xmin</> and <structfield>xmax</>. Transaction identifiers are 32-bit quantities.
</para>
<para>
A third identifier type used by the system is <type>cid</>, or
command identifier. This is the data type of the system columns
- <structfield>cmin</> and <structfield>cmax</>. Command
- identifiers are also 32-bit quantities. This creates a hard limit
- of 2<superscript>32</> (4 billion) <acronym>SQL</acronym> commands
- within a single transaction. In practice this limit is not a
- problem --- note that the limit is on number of
- <acronym>SQL</acronym> commands, not number of tuples processed.
+ <structfield>cmin</> and <structfield>cmax</>. Command identifiers are also 32-bit quantities.
</para>
<para>
physical location of the tuple within its table.
</para>
+ <para>
+ (The system columns are further explained in <xref
+ linkend="ddl-system-columns">.)
+ </para>
</sect1>
<sect1 id="datatype-pseudo">
<tgroup cols="2">
<thead>
<row>
- <entry>Type name</entry>
+ <entry>Name</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
-
<row>
<entry><type>record</></entry>
- <entry>Identifies a function returning an unspecified row type</entry>
+ <entry>Identifies a function returning an unspecified row type.</entry>
</row>
<row>
<entry><type>any</></entry>
- <entry>Indicates that a function accepts any input data type whatever</entry>
+ <entry>Indicates that a function accepts any input data type whatever.</entry>
</row>
<row>
<entry><type>anyarray</></entry>
- <entry>Indicates that a function accepts any array data type</entry>
+ <entry>Indicates that a function accepts any array data type.</entry>
</row>
<row>
<entry><type>void</></entry>
- <entry>Indicates that a function returns no value</entry>
+ <entry>Indicates that a function returns no value.</entry>
</row>
<row>
<entry><type>trigger</></entry>
- <entry>A trigger function is declared to return <type>trigger</></entry>
+ <entry>A trigger function is declared to return <type>trigger.</></entry>
</row>
<row>
<entry><type>language_handler</></entry>
- <entry>A procedural language call handler is declared to return <type>language_handler</></entry>
+ <entry>A procedural language call handler is declared to return <type>language_handler</>.</entry>
</row>
<row>
<entry><type>cstring</></entry>
- <entry>Indicates that a function accepts or returns a null-terminated C string</entry>
+ <entry>Indicates that a function accepts or returns a null-terminated C string.</entry>
</row>
<row>
<entry><type>internal</></entry>
<entry>Indicates that a function accepts or returns a server-internal
- data type</entry>
+ data type.</entry>
</row>
<row>
<entry><type>opaque</></entry>
- <entry>An obsolete type name that formerly served all the above purposes</entry>
+ <entry>An obsolete type name that formerly served all the above purposes.</entry>
</row>
</tbody>
</tgroup>
</sect1>
- &array;
-
</chapter>
<!-- Keep this comment at the end of the file
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/datetime.sgml,v 2.29 2002/11/11 20:14:02 petere Exp $
-Date/time details
+$Header: /cvsroot/pgsql/doc/src/sgml/datetime.sgml,v 2.30 2003/03/13 01:30:27 petere Exp $
-->
<appendix id="datetime-appendix">
- <title id="datetime-appendix-title">Date/Time Support</title>
+ <title>Date/Time Support</title>
<para>
<productname>PostgreSQL</productname> uses an internal heuristic
<title>Date/Time Input Interpretation</title>
<para>
- The date/time types are all decoded using a common set of routines.
+ The date/time type inputs are all decoded using the following routine.
</para>
<procedure>
- <title>Date/Time Input Interpretation</title>
-
<step>
<para>
Break the input string into tokens and categorize each token as
If the token is numeric only, then it is either a single field
or an ISO 8601 concatenated date (e.g.,
<literal>19990113</literal> for January 13, 1999) or time
- (e.g. <literal>141516</literal> for 14:15:16).
+ (e.g., <literal>141516</literal> for 14:15:16).
</para>
</step>
<para>
If BC has been specified, negate the year and add one for
internal storage. (There is no year zero in the Gregorian
- calendar, so numerically <literal>1BC</literal> becomes year
+ calendar, so numerically 1 BC becomes year
zero.)
</para>
</step>
<step>
<para>
If BC was not specified, and if the year field was two digits in length, then
- adjust the year to 4 digits. If the field was less than 70, then add 2000;
- otherwise, add 1900.
+ adjust the year to four digits. If the field is less than 70, then add 2000,
+ otherwise add 1900.
<tip>
<para>
<para>
The key word <literal>ABSTIME</literal> is ignored for historical
- reasons; in very old releases of
- <productname>PostgreSQL</productname> invalid fields of type <type>abstime</type>
+ reasons: In very old releases of
+ <productname>PostgreSQL</productname>, invalid values of type <type>abstime</type>
were emitted as <literal>Invalid Abstime</literal>. This is no
longer the case however and this key word will likely be dropped in
a future release.
<para>
The table is organized by time zone offset from <acronym>UTC</>,
- rather than alphabetically; this is intended to facilitate
+ rather than alphabetically. This is intended to facilitate
matching local usage with recognized abbreviations for cases where
these might differ.
</para>
<row>
<entry>NZDT</entry>
<entry>+13:00</entry>
- <entry>New Zealand Daylight Time</entry>
+ <entry>New Zealand Daylight-Saving Time</entry>
</row>
<row>
<entry>IDLE</entry>
<row>
<entry>CADT</entry>
<entry>+10:30</entry>
- <entry>Central Australia Daylight Savings Time</entry>
+ <entry>Central Australia Daylight-Saving Time</entry>
</row>
<row>
<entry>SADT</entry>
<entry>+10:30</entry>
- <entry>South Australian Daylight Time</entry>
+ <entry>South Australian Daylight-Saving Time</entry>
</row>
<row>
<entry>AEST</entry>
<row>
<entry>GST</entry>
<entry>+10:00</entry>
- <entry>Guam Standard Time, USSR Zone 9</entry>
+ <entry>Guam Standard Time, Russia zone 9</entry>
</row>
<row>
<entry>LIGT</entry>
<row>
<entry>JST</entry>
<entry>+09:00</entry>
- <entry>Japan Standard Time,USSR Zone 8</entry>
+ <entry>Japan Standard Time, Russia zone 8</entry>
</row>
<row>
<entry>KST</entry>
<row>
<entry>WDT</entry>
<entry>+09:00</entry>
- <entry>West Australian Daylight Time</entry>
+ <entry>West Australian Daylight-Saving Time</entry>
</row>
<row>
<entry>MT</entry>
<row>
<entry>WADT</entry>
<entry>+08:00</entry>
- <entry>West Australian Daylight Time</entry>
+ <entry>West Australian Daylight-Saving Time</entry>
</row>
<row>
<entry>WST</entry>
<row>
<entry>EAST</entry>
<entry>+04:00</entry>
- <entry>Antananarivo Savings Time</entry>
+ <entry>Antananarivo Summer Time</entry>
</row>
<row>
<entry>MUT</entry>
<row>
<entry>EETDST</entry>
<entry>+03:00</entry>
- <entry>Eastern Europe Daylight Savings Time</entry>
+ <entry>Eastern Europe Daylight-Saving Time</entry>
</row>
<row>
<entry>HMT</entry>
<row>
<entry>CEST</entry>
<entry>+02:00</entry>
- <entry>Central European Savings Time</entry>
+ <entry>Central European Summer Time</entry>
</row>
<row>
<entry>CETDST</entry>
<entry>+02:00</entry>
- <entry>Central European Daylight Savings Time</entry>
+ <entry>Central European Daylight-Saving Time</entry>
</row>
<row>
<entry>EET</entry>
<entry>+02:00</entry>
- <entry>Eastern Europe, USSR Zone 1</entry>
+ <entry>Eastern European Time, Russia zone 1</entry>
</row>
<row>
<entry>FWT</entry>
<row>
<entry>MEST</entry>
<entry>+02:00</entry>
- <entry>Middle Europe Summer Time</entry>
+ <entry>Middle European Summer Time</entry>
</row>
<row>
<entry>METDST</entry>
<entry>+02:00</entry>
- <entry>Middle Europe Daylight Time</entry>
+ <entry>Middle Europe Daylight-Saving Time</entry>
</row>
<row>
<entry>SST</entry>
<row>
<entry>MET</entry>
<entry>+01:00</entry>
- <entry>Middle Europe Time</entry>
+ <entry>Middle European Time</entry>
</row>
<row>
<entry>MEWT</entry>
<entry>+01:00</entry>
- <entry>Middle Europe Winter Time</entry>
+ <entry>Middle European Winter Time</entry>
</row>
<row>
<entry>MEZ</entry>
<entry>+01:00</entry>
- <entry>Middle Europe Zone</entry>
+ <entry><foreignphrase>Mitteleuropäische Zeit</></entry>
</row>
<row>
<entry>NOR</entry>
<row>
<entry>WETDST</entry>
<entry>+01:00</entry>
- <entry>Western Europe Daylight Savings Time</entry>
+ <entry>Western European Daylight-Saving Time</entry>
</row>
<row>
<entry>GMT</entry>
- <entry>+00:00</entry>
+ <entry>00:00</entry>
<entry>Greenwich Mean Time</entry>
</row>
<row>
<entry>UT</entry>
- <entry>+00:00</entry>
+ <entry>00:00</entry>
<entry>Universal Time</entry>
</row>
<row>
<entry>UTC</entry>
- <entry>+00:00</entry>
- <entry>Universal Time, Coordinated</entry>
+ <entry>00:00</entry>
+ <entry>Universal Coordinated Time</entry>
</row>
<row>
<entry>Z</entry>
- <entry>+00:00</entry>
+ <entry>00:00</entry>
<entry>Same as UTC</entry>
</row>
<row>
<entry>ZULU</entry>
- <entry>+00:00</entry>
+ <entry>00:00</entry>
<entry>Same as UTC</entry>
</row>
<row>
<entry>WET</entry>
- <entry>+00:00</entry>
- <entry>Western Europe</entry>
+ <entry>00:00</entry>
+ <entry>Western European Time</entry>
</row>
<row>
<entry>WAT</entry>
<row>
<entry>NDT</entry>
<entry>-02:30</entry>
- <entry>Newfoundland Daylight Time</entry>
+ <entry>Newfoundland Daylight-Saving Time</entry>
</row>
<row>
<entry>ADT</entry>
<entry>-03:00</entry>
- <entry>Atlantic Daylight Time</entry>
+ <entry>Atlantic Daylight-Saving Time</entry>
</row>
<row>
<entry>AWT</entry>
<row>
<entry>EDT</entry>
<entry>-04:00</entry>
- <entry>Eastern Daylight Time</entry>
+ <entry>Eastern Daylight-Saving Time</entry>
</row>
<!--
<row>
<row>
<entry>CDT</entry>
<entry>-05:00</entry>
- <entry>Central Daylight Time</entry>
+ <entry>Central Daylight-Saving Time</entry>
</row>
<row>
<entry>EST</entry>
<row>
<entry>MDT</entry>
<entry>-06:00</entry>
- <entry>Mountain Daylight Time</entry>
+ <entry>Mountain Daylight-Saving Time</entry>
</row>
<!--
<row>
<row>
<entry>PDT</entry>
<entry>-07:00</entry>
- <entry>Pacific Daylight Time</entry>
+ <entry>Pacific Daylight-Saving Time</entry>
</row>
<row>
<entry>AKDT</entry>
<entry>-08:00</entry>
- <entry>Alaska Daylight Time</entry>
+ <entry>Alaska Daylight-Saving Time</entry>
</row>
<row>
<entry>PST</entry>
<row>
<entry>YDT</entry>
<entry>-08:00</entry>
- <entry>Yukon Daylight Time</entry>
+ <entry>Yukon Daylight-Saving Time</entry>
</row>
<row>
<entry>AKST</entry>
<row>
<entry>HDT</entry>
<entry>-09:00</entry>
- <entry>Hawaii/Alaska Daylight Time</entry>
+ <entry>Hawaii/Alaska Daylight-Saving Time</entry>
</row>
<row>
<entry>YST</entry>
<row>
<entry>AHST</entry>
<entry>-10:00</entry>
- <entry>Alaska-Hawaii Standard Time</entry>
+ <entry>Alaska/Hawaii Standard Time</entry>
</row>
<row>
<entry>HST</entry>
<para>
There are three naming conflicts between Australian time zone
- names with time zones commonly used in North and South America:
+ names and time zone names commonly used in North and South America:
<literal>ACST</literal>, <literal>CST</literal>, and
<literal>EST</literal>. If the run-time option
- <varname>AUSTRALIAN_TIMEZONES</varname> is set to true then
+ <varname>australian_timezones</varname> is set to true then
<literal>ACST</literal>, <literal>CST</literal>,
<literal>EST</literal>, and <literal>SAT</literal> are interpreted
as Australian time zone names, as shown in <xref
</sect1>
- <sect1 id="units-history">
+ <sect1 id="datetime-units-history">
<title>History of Units</title>
- <note>
- <para>
- Contributed by José Soares (<email>jose@sferacarta.com</email>)
- </para>
- </note>
-
<para>
- The Julian Day was invented by the French scholar
+ The Julian Date was invented by the French scholar
Joseph Justus Scaliger (1540-1609)
and probably takes its name from the Scaliger's father,
the Italian scholar Julius Caesar Scaliger (1484-1558).
Astronomers have used the Julian period to assign a unique number to
- every day since 1 January 4713 BC. This is the so-called Julian Day
+ every day since 1 January 4713 BC. This is the so-called Julian Date
(JD). JD 0 designates the 24 hours from noon UTC on 1 January 4713 BC
to noon UTC on 2 January 4713 BC.
</para>
<para>
- The <quote>Julian Day</quote> is different from the <quote>Julian
- Date</quote>. The Julian date refers to the Julian calendar, which
+ The <quote>Julian Date</quote> is different from the <quote>Julian
+ Calendar</quote>. The Julian calendar
was introduced by Julius Caesar in 45 BC. It was in common use
until the 1582, when countries started changing to the Gregorian
calendar. In the Julian calendar, the tropical year is
-<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ddl.sgml,v 1.12 2003/02/19 04:06:27 momjian Exp $ -->
+<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ddl.sgml,v 1.13 2003/03/13 01:30:28 petere Exp $ -->
<chapter id="ddl">
<title>Data Definition</title>
The object identifier (object ID) of a row. This is a serial
number that is automatically added by
<productname>PostgreSQL</productname> to all table rows (unless
- the table was created <literal>WITHOUT OIDS</literal>, in which
+ the table was created using <literal>WITHOUT OIDS</literal>, in which
case this column is not present). This column is of type
- <literal>oid</literal> (same name as the column); see <xref
+ <type>oid</type> (same name as the column); see <xref
linkend="datatype-oid"> for more information about the type.
</para>
</listitem>
<term><structfield>tableoid</></term>
<listitem>
<para>
- The OID of the table containing this row. This attribute is
+ The OID of the table containing this row. This column is
particularly handy for queries that select from inheritance
hierarchies, since without it, it's difficult to tell which
individual table a row came from. The
<listitem>
<para>
The identity (transaction ID) of the deleting transaction, or
- zero for an undeleted tuple. It is possible for this field to
+ zero for an undeleted tuple. It is possible for this column to
be nonzero in a visible tuple: That usually indicates that the
deleting transaction hasn't committed yet, or that an attempted
deletion was rolled back.
</listitem>
</varlistentry>
</variablelist>
+
+ <para>
+ OIDs are 32-bit quantities and are assigned from a single cluster-wide
+ counter. In a large or long-lived database, it is possible for the
+ counter to wrap around. Hence, it is bad practice to assume that OIDs
+ are unique, unless you take steps to ensure that they are unique.
+ Recommended practice when using OIDs for row identification is to create
+ a unique constraint on the OID column of each table for which the OID will
+ be used. Never assume that OIDs are unique across tables; use the
+ combination of <structfield>tableoid</> and row OID if you need a
+ database-wide identifier. (Future releases of
+ <productname>PostgreSQL</productname> are likely to use a separate
+ OID counter for each table, so that <structfield>tableoid</>
+ <emphasis>must</> be included to arrive at a globally unique identifier.)
+ </para>
+
+ <para>
+ Transaction identifiers are also 32-bit quantities. In a long-lived
+ database it is possible for transaction IDs to wrap around. This
+ is not a fatal problem given appropriate maintenance procedures;
+ see the &cite-admin; for details. However, it is
+ unwise to depend on uniqueness of transaction IDs over the long term
+ (more than one billion transactions).
+ </para>
+
+ <para>
+ Command
+ identifiers are also 32-bit quantities. This creates a hard limit
+ of 2<superscript>32</> (4 billion) <acronym>SQL</acronym> commands
+ within a single transaction. In practice this limit is not a
+ problem --- note that the limit is on number of
+ <acronym>SQL</acronym> commands, not number of tuples processed.
+ </para>
</sect1>
- <sect1>
+ <sect1 id="ddl-default">
<title>Default Values</title>
<para>
data type. For example:
<programlisting>
CREATE TABLE products (
- product_no integer PRIMARY KEY,
+ product_no integer,
name text,
price numeric <emphasis>DEFAULT 9.99</emphasis>
);
REVOKE ALL ON accounts FROM PUBLIC;
</programlisting>
The special privileges of the table owner (i.e., the right to do
- <command>DROP</>, <command>GRANT</>, <command>REVOKE</>, etc)
+ <command>DROP</>, <command>GRANT</>, <command>REVOKE</>, etc.)
are always implicit in being the owner,
and cannot be granted or revoked. But the table owner can choose
to revoke his own ordinary privileges, for example to make a
</indexterm>
<para>
- A <productname>PostgreSQL</productname> database cluster (installation)
+ A <productname>PostgreSQL</productname> database cluster
contains one or more named databases. Users and groups of users are
shared across the entire cluster, but no other data is shared across
databases. Any given client connection to the server can access
no longer true: you may create such a table name if you wish, in
any non-system schema. However, it's best to continue to avoid
such names, to ensure that you won't suffer a conflict if some
- future version defines a system catalog named the same as your
+ future version defines a system table named the same as your
table. (With the default search path, an unqualified reference to
- your table name would be resolved as the system catalog instead.)
- System catalogs will continue to follow the convention of having
+ your table name would be resolved as the system table instead.)
+ System tables will continue to follow the convention of having
names beginning with <literal>pg_</>, so that they will not
conflict with unqualified user-table names so long as users avoid
the <literal>pg_</> prefix.
linkend="ddl-constraints-fk">, with the orders table depending on
it, would result in an error message such as this:
<screen>
-<userinput>DROP TABLE products;</userinput>
+DROP TABLE products;
+
NOTICE: constraint $1 on table orders depends on table products
ERROR: Cannot drop table products because other objects depend on it
Use DROP ... CASCADE to drop the dependent objects too
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ecpg.sgml,v 1.41 2003/01/19 00:13:28 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ecpg.sgml,v 1.42 2003/03/13 01:30:28 petere Exp $
-->
<chapter id="ecpg">
implementation is designed to match this standard as much as
possible, and it is usually possible to port embedded
<acronym>SQL</acronym> programs written for other
- <acronym>RDBMS</acronym> to <productname>PostgreSQL</productname>
+ SQL databases to <productname>PostgreSQL</productname>
with relative ease.
</para>
<itemizedlist>
<listitem>
<simpara>
- <literal><replaceable>userid</replaceable></literal>
+ <literal><replaceable>username</replaceable></literal>
</simpara>
</listitem>
<listitem>
<simpara>
- <literal><replaceable>userid</replaceable>/<replaceable>password</replaceable></literal>
+ <literal><replaceable>username</replaceable>/<replaceable>password</replaceable></literal>
</simpara>
</listitem>
<listitem>
<simpara>
- <literal><replaceable>userid</replaceable> IDENTIFIED BY <replaceable>password</replaceable></literal>
+ <literal><replaceable>username</replaceable> IDENTIFIED BY <replaceable>password</replaceable></literal>
</simpara>
</listitem>
<listitem>
<simpara>
- <literal><replaceable>userid</replaceable> USING <replaceable>password</replaceable></literal>
+ <literal><replaceable>username</replaceable> USING <replaceable>password</replaceable></literal>
</simpara>
</listitem>
</itemizedlist>
- The <replaceable>userid</replaceable> and
- <replaceable>password</replaceable> may be a constant text, a
+ The <replaceable>username</replaceable> and
+ <replaceable>password</replaceable> may be an SQL name, a
character variable, or a character string.
</para>
<para>
To close a connection, use the following statement:
<programlisting>
-EXEC SQL DISCONNECT [<replaceable>connection</replaceable>];
+EXEC SQL DISCONNECT <optional><replaceable>connection</replaceable></optional>;
</programlisting>
The <replaceable>connection</replaceable> can be specified
in the following ways:
other interfaces) via the <option>-t</option> command-line option
to <command>ecpg</command> (see below) or via the <literal>EXEC SQL
SET AUTOCOMMIT TO ON</literal> statement. In autocommit mode, each
- query is automatically committed unless it is inside an explicit
+ command is automatically committed unless it is inside an explicit
transaction block. This mode can be explicitly turned off using
<literal>EXEC SQL SET AUTOCOMMIT TO OFF</literal>.
</para>
<para>
The special types <type>VARCHAR</type> and <type>VARCHAR2</type>
are converted into a named <type>struct</> for every variable. A
- declaration like:
+ declaration like
<programlisting>
VARCHAR var[180];
</programlisting>
- is converted into:
+ is converted into
<programlisting>
struct varchar_var { int len; char arr[180]; } var;
</programlisting>
This structure is suitable for interfacing with SQL datums of type
- <type>VARCHAR</type>.
+ <type>varchar</type>.
</para>
<para>
long sqlerrd[6];
/* 0: empty */
- /* 1: OID of processed tuple if applicable */
+ /* 1: OID of processed row if applicable */
/* 2: number of rows processed in an INSERT, UPDATE */
/* or DELETE statement */
/* 3: empty */
/* 0: set to 'W' if at least one other is 'W' */
/* 1: if 'W' at least one character string */
/* value was truncated when it was */
- /* stored into a host variable. */
+ /* stored into a host variable */
/* 2: empty */
/* 3: empty */
/* 4: empty */
If no error occurred in the last <acronym>SQL</acronym> statement,
<literal>sqlca.sqlcode</literal> will be 0
(<symbol>ECPG_NO_ERROR</>). If <literal>sqlca.sqlcode</literal> is
- less that zero, this is a serious error, like the database
+ less than zero, this is a serious error, like the database
definition does not match the query. If it is greater than zero, it
is a normal error like the table did not contain the requested row.
</para>
<variablelist>
<varlistentry>
- <term><computeroutput>-12, Out of memory in line %d.</computeroutput></term>
+ <term><computeroutput>-12: Out of memory in line %d.</computeroutput></term>
<listitem>
<para>
Should not normally occur. This indicates your virtual memory
This means that the server has returned more arguments than we
have matching variables. Perhaps you have forgotten a couple
of the host variables in the <command>INTO
- :var1,:var2</command> list.
+ :var1, :var2</command> list.
</para>
</listitem>
</varlistentry>
<term><computeroutput>-203 (ECPG_TOO_MANY_MATCHES): Too many matches line %d.</computeroutput></term>
<listitem>
<para>
- This means the query has returned several rows but the
+ This means the query has returned multiple rows but the
variables specified are not arrays. The
<command>SELECT</command> command was not unique.
</para>
</varlistentry>
<varlistentry>
- <term><computeroutput>-242 (ECPG_UNKNOWN_DESCRIPTOR_ITEM): Descriptor %s not found in line %d.</computeroutput></term>
+ <term><computeroutput>-242 (ECPG_UNKNOWN_DESCRIPTOR_ITEM): Unknown descriptor item %s in line %d.</computeroutput></term>
<listitem>
<para>
The descriptor specified was not found. The statement you are trying to use has not been prepared.
</varlistentry>
<varlistentry>
- <term><computeroutput>-400 (ECPG_PGSQL): Postgres error: %s line %d.</computeroutput></term>
+ <term><computeroutput>-400 (ECPG_PGSQL): '%s' in line %d.</computeroutput></term>
<listitem>
<para>
Some <productname>PostgreSQL</productname> error. The message
contains the error message from the
- <productname>PostgreSQL</productname> backend.
+ <productname>PostgreSQL</productname> server.
</para>
</listitem>
</varlistentry>
<term><computeroutput>-401 (ECPG_TRANS): Error in transaction processing line %d.</computeroutput></term>
<listitem>
<para>
- <productname>PostgreSQL</productname> signaled that we cannot
+ The <productname>PostgreSQL</productname> server signaled that we cannot
start, commit, or rollback the transaction.
</para>
</listitem>
<term><computeroutput>-402 (ECPG_CONNECT): Could not connect to database %s in line %d.</computeroutput></term>
<listitem>
<para>
- The connect to the database did not work.
+ The connection attempt to the database did not work.
</para>
</listitem>
</varlistentry>
<programlisting>
#include <<replaceable>filename</replaceable>.h>
</programlisting>
- because the file would not be subject to SQL command preprocessing.
+ because this file would not be subject to SQL command preprocessing.
Naturally, you can continue to use the C
<literal>#include</literal> directive to include other header
files.
<acronym>SQL</acronym> statements you used to special function
calls. After compiling, you must link with a special library that
contains the needed functions. These functions fetch information
- from the arguments, perform the <acronym>SQL</acronym> query using
+ from the arguments, perform the <acronym>SQL</acronym> command using
the <application>libpq</application> interface, and put the result
in the arguments specified for output.
</para>
</para>
<para>
- The preprocessed file can be compiled normally, for example
+ The preprocessed file can be compiled normally, for example:
<programlisting>
cc -c prog1.c
</programlisting>
<function>ECPGdebug(int <replaceable>on</replaceable>, FILE
*<replaceable>stream</replaceable>)</function> turns on debug
logging if called with the first argument non-zero. Debug logging
- is done on <replaceable>stream</replaceable>. Most
- <acronym>SQL</acronym> statement log their arguments and results.
- </para>
-
- <para>
- The most important function, <function>ECPGdo</function>, logs
- all <acronym>SQL</acronym> statements with both the expanded
- string, i.e. the string with all the input variables inserted,
- and the result from the <productname>PostgreSQL</productname>
- server. This can be very useful when searching for errors in your
- <acronym>SQL</acronym> statements.
+ is done on <replaceable>stream</replaceable>. The log contains
+ all <acronym>SQL</acronym> statements with all the input
+ variables inserted, and the results from the
+ <productname>PostgreSQL</productname> server. This can be very
+ useful when searching for errors in your <acronym>SQL</acronym>
+ statements.
</para>
</listitem>
<listitem>
<para>
- <function>ECPGstatus()</function> This method returns true if we
+ <function>ECPGstatus()</function> returns true if you
are connected to a database and false if not.
</para>
</listitem>
</itemizedlist>
</sect1>
- <sect1 id="ecpg-porting">
- <title>Porting From Other <acronym>RDBMS</acronym> Packages</title>
-
- <para>
- The design of <application>ecpg</application> follows the SQL
- standard. Porting from a standard RDBMS should not be a problem.
- Unfortunately there is no such thing as a standard RDBMS. Therefore
- <application>ecpg</application> tries to understand syntax
- extensions as long as they do not create conflicts with the
- standard.
- </para>
-
- <para>
- The following list shows all the known incompatibilities. If you
- find one not listed please notify the developers. Note, however,
- that we list only incompatibilities from a preprocessor of another
- RDBMS to <application>ecpg</application> and not
- <application>ecpg</application> features that these RDBMS do not
- support.
- </para>
-
- <variablelist>
- <varlistentry>
- <term>Syntax of <command>FETCH</command></term>
- <indexterm><primary>FETCH</><secondary>embedded SQL</></indexterm>
-
- <listitem>
- <para>
- The standard syntax for <command>FETCH</command> is:
-<synopsis>
-FETCH <optional><replaceable>direction</></> <optional><replaceable>amount</></> IN|FROM <replaceable>cursor</replaceable>
-</synopsis>
- <indexterm><primary>Oracle</></>
- <productname>Oracle</productname>, however, does not use the
- keywords <literal>IN</literal> or <literal>FROM</literal>. This
- feature cannot be added since it would create parsing conflicts.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </sect1>
-
<sect1 id="ecpg-develop">
- <title>For the Developer</title>
+ <title>Internals</title>
<para>
- This section explain how <application>ecpg</application> works
+ This section explain how <application>ECPG</application> works
internally. This information can occasionally be useful to help
- users understand how to use <application>ecpg</application>.
+ users understand how to use <application>ECPG</application>.
</para>
- <sect2>
- <title>The Preprocessor</title>
-
<para>
The first four lines written by <command>ecpg</command> to the
output are fixed lines. Two are comments and two are include
<para>
When it sees an <command>EXEC SQL</command> statement, it
- intervenes and changes it. The command starts with <command>exec
- sql</command> and ends with <command>;</command>. Everything in
+ intervenes and changes it. The command starts with <command>EXEC
+ SQL</command> and ends with <command>;</command>. Everything in
between is treated as an <acronym>SQL</acronym> statement and
parsed for variable substitution.
</para>
Variable substitution occurs when a symbol starts with a colon
(<literal>:</literal>). The variable with that name is looked up
among the variables that were previously declared within a
- <literal>EXEC SQL DECLARE</> section. Depending on whether the
- variable is being use for input or output, a pointer to the
- variable is output to allow access by the function.
+ <literal>EXEC SQL DECLARE</> section.
+ </para>
+
+ <para>
+ The most important function in the library is
+ <function>ECPGdo</function>, which takes care of executing most
+ commands. It takes a variable number of arguments. This can easily
+ add up to 50 or so arguments, and we hope this will not be a
+ problem on any platform.
+ </para>
+
+ <para>
+ The arguments are:
+
+ <variablelist>
+ <varlistentry>
+ <term>A line number</term>
+ <listitem>
+ <para>
+ This is the line number of the original line; used in error
+ messages only.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>A string</term>
+ <listitem>
+ <para>
+ This is the <acronym>SQL</acronym> command that is to be issued.
+ It is modified by the input variables, i.e., the variables that
+ where not known at compile time but are to be entered in the
+ command. Where the variables should go the string contains
+ <literal>?</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Input variables</term>
+ <listitem>
+ <para>
+ Every input variable causes ten arguments to be created. (See below.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>ECPGt_EOIT</></term>
+ <listitem>
+ <para>
+ An <type>enum</> telling that there are no more input
+ variables.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Output variables</term>
+ <listitem>
+ <para>
+ Every output variable causes ten arguments to be created.
+ (See below.) These variables are filled by the function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>ECPGt_EORT</></term>
+ <listitem>
+ <para>
+ An <type>enum</> telling that there are no more variables.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
</para>
<para>
For every variable that is part of the <acronym>SQL</acronym>
- query, the function gets other arguments:
+ command, the function gets ten arguments:
- <itemizedlist>
+ <orderedlist>
<listitem>
<para>
The type as a special symbol.
<listitem>
<para>
- A pointer to the value of the indicator variable or a pointer
- to the pointer of the indicator variable.
+ A pointer to the indicator variable.
</para>
</listitem>
<listitem>
<para>
- Number of elements in the indicator array (for array fetches).
+ The number of elements in the indicator array (for array fetches).
</para>
</listitem>
array fetches).
</para>
</listitem>
- </itemizedlist>
+ </orderedlist>
</para>
<para>
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
#line 147 "foo.pgc"
</programlisting>
- (The indentation in this manual is added for readability and not
+ (The indentation here is added for readability and not
something the preprocessor does.)
</para>
- </sect2>
-
- <sect2>
- <title>The Library</title>
-
- <para>
- The most important function in the library is
- <function>ECPGdo</function>. It takes a variable number of
- arguments. Hopefully there are no computers that limit the number
- of variables that can be accepted by a
- <function>varargs()</function> function. This can easily add up to
- 50 or so arguments.
- </para>
-
- <para>
- The arguments are:
-
- <variablelist>
- <varlistentry>
- <term>A line number</term>
- <listitem>
- <para>
- This is a line number of the original line; used in error
- messages only.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>A string</term>
- <listitem>
- <para>
- This is the <acronym>SQL</acronym> query that is to be issued.
- It is modified by the input variables, i.e. the variables that
- where not known at compile time but are to be entered in the
- query. Where the variables should go the string contains
- <literal>?</literal>.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>Input variables</term>
- <listitem>
- <para>
- As described in the section about the preprocessor, every
- input variable gets ten arguments.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><parameter>ECPGt_EOIT</></term>
- <listitem>
- <para>
- An <type>enum</> telling that there are no more input
- variables.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>Output variables</term>
- <listitem>
- <para>
- As described in the section about the preprocessor, every
- input variable gets ten arguments. These variables are filled
- by the function.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><parameter>ECPGt_EORT</></term>
- <listitem>
- <para>
- An <type>enum</> telling that there are no more variables.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </para>
- </sect2>
</sect1>
</chapter>
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/features.sgml,v 2.17 2003/01/15 21:55:52 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/features.sgml,v 2.18 2003/03/13 01:30:28 petere Exp $
-->
<appendix id="features">
<para>
The following features defined in <acronym>SQL99</acronym> are not
- implemented in the current release of
+ implemented in this release of
<productname>PostgreSQL</productname>. In a few cases, equivalent
functionality is available.
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.142 2003/03/03 03:31:23 tgl Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.143 2003/03/13 01:30:28 petere Exp $
PostgreSQL documentation
-->
exception of the most trivial arithmetic and comparison operators
and some explicitly marked functions, are not specified by the
<acronym>SQL</acronym>
- standard. Some of this extended functionality is present in other
+ standard. Some of the extended functionality is present in other
<acronym>SQL</acronym> implementations, and in many cases this
functionality is compatible and consistent between various products.
</para>
</indexterm>
<simplelist>
- <member>AND</member>
- <member>OR</member>
- <member>NOT</member>
+ <member><literal>AND</></member>
+ <member><literal>OR</></member>
+ <member><literal>NOT</></member>
</simplelist>
<acronym>SQL</acronym> uses a three-valued Boolean logic where the null value represents
<tgroup cols="4">
<thead>
<row>
- <entry>Name</entry>
+ <entry>Operator</entry>
<entry>Description</entry>
<entry>Example</entry>
<entry>Result</entry>
<row>
<entry> <literal>+</literal> </entry>
<entry>addition</entry>
- <entry>2 + 3</entry>
- <entry>5</entry>
+ <entry><literal>2 + 3</literal></entry>
+ <entry><literal>5</literal></entry>
</row>
<row>
<entry> <literal>-</literal> </entry>
<entry>subtraction</entry>
- <entry>2 - 3</entry>
- <entry>-1</entry>
+ <entry><literal>2 - 3</literal></entry>
+ <entry><literal>-1</literal></entry>
</row>
<row>
<entry> <literal>*</literal> </entry>
<entry>multiplication</entry>
- <entry>2 * 3</entry>
- <entry>6</entry>
+ <entry><literal>2 * 3</literal></entry>
+ <entry><literal>6</literal></entry>
</row>
<row>
<entry> <literal>/</literal> </entry>
<entry>division (integer division truncates results)</entry>
- <entry>4 / 2</entry>
- <entry>2</entry>
+ <entry><literal>4 / 2</literal></entry>
+ <entry><literal>2</literal></entry>
</row>
<row>
<entry> <literal>%</literal> </entry>
<entry>modulo (remainder)</entry>
- <entry>5 % 4</entry>
- <entry>1</entry>
+ <entry><literal>5 % 4</literal></entry>
+ <entry><literal>1</literal></entry>
</row>
<row>
<entry> <literal>^</literal> </entry>
<entry>exponentiation</entry>
- <entry>2.0 ^ 3.0</entry>
- <entry>8</entry>
+ <entry><literal>2.0 ^ 3.0</literal></entry>
+ <entry><literal>8</literal></entry>
</row>
<row>
<entry> <literal>|/</literal> </entry>
<entry>square root</entry>
- <entry>|/ 25.0</entry>
- <entry>5</entry>
+ <entry><literal>|/ 25.0</literal></entry>
+ <entry><literal>5</literal></entry>
</row>
<row>
<entry> <literal>||/</literal> </entry>
<entry>cube root</entry>
- <entry>||/ 27.0</entry>
- <entry>3</entry>
+ <entry><literal>||/ 27.0</literal></entry>
+ <entry><literal>3</literal></entry>
</row>
<row>
<entry> <literal>!</literal> </entry>
<entry>factorial</entry>
- <entry>5 !</entry>
- <entry>120</entry>
+ <entry><literal>5 !</literal></entry>
+ <entry><literal>120</literal></entry>
</row>
<row>
<entry> <literal>!!</literal> </entry>
<entry>factorial (prefix operator)</entry>
- <entry>!! 5</entry>
- <entry>120</entry>
+ <entry><literal>!! 5</literal></entry>
+ <entry><literal>120</literal></entry>
</row>
<row>
<entry> <literal>@</literal> </entry>
<entry>absolute value</entry>
- <entry>@ -5.0</entry>
- <entry>5</entry>
+ <entry><literal>@ -5.0</literal></entry>
+ <entry><literal>5</literal></entry>
</row>
<row>
<entry> <literal>&</literal> </entry>
- <entry>binary AND</entry>
- <entry>91 & 15</entry>
- <entry>11</entry>
+ <entry>bitwise AND</entry>
+ <entry><literal>91 & 15</literal></entry>
+ <entry><literal>11</literal></entry>
</row>
<row>
<entry> <literal>|</literal> </entry>
- <entry>binary OR</entry>
- <entry>32 | 3</entry>
- <entry>35</entry>
+ <entry>bitwise OR</entry>
+ <entry><literal>32 | 3</literal></entry>
+ <entry><literal>35</literal></entry>
</row>
<row>
<entry> <literal>#</literal> </entry>
- <entry>binary XOR</entry>
- <entry>17 # 5</entry>
- <entry>20</entry>
+ <entry>bitwise XOR</entry>
+ <entry><literal>17 # 5</literal></entry>
+ <entry><literal>20</literal></entry>
</row>
<row>
<entry> <literal>~</literal> </entry>
- <entry>binary NOT</entry>
- <entry>~1</entry>
- <entry>-2</entry>
+ <entry>bitwise NOT</entry>
+ <entry><literal>~1</literal></entry>
+ <entry><literal>-2</literal></entry>
</row>
<row>
- <entry> << </entry>
- <entry>binary shift left</entry>
- <entry>1 << 4</entry>
- <entry>16</entry>
+ <entry> <literal><<</literal> </entry>
+ <entry>biwise shift left</entry>
+ <entry><literal>1 << 4</literal></entry>
+ <entry><literal>16</literal></entry>
</row>
<row>
- <entry> >> </entry>
- <entry>binary shift right</entry>
- <entry>8 >> 2</entry>
- <entry>2</entry>
+ <entry> <literal>>></literal> </entry>
+ <entry>bitwise shift right</entry>
+ <entry><literal>8 >> 2</literal></entry>
+ <entry><literal>2</literal></entry>
</row>
</tbody>
</table>
<para>
- The <quote>binary</quote> operators are also available for the bit
- string types <type>BIT</type> and <type>BIT VARYING</type>, as
+ The bitwise operators are also available for the bit
+ string types <type>bit</type> and <type>bit varying</type>, as
shown in <xref linkend="functions-math-bit-table">.
- Bit string arguments to <literal>&</literal>, <literal>|</literal>,
+ Bit string operands of <literal>&</literal>, <literal>|</literal>,
and <literal>#</literal> must be of equal length. When bit
shifting, the original length of the string is preserved, as shown
in the table.
</para>
<table id="functions-math-bit-table">
- <title>Bit String Binary Operators</title>
+ <title>Bit String Bitwise Operators</title>
<tgroup cols="2">
<thead>
<tbody>
<row>
- <entry>B'10001' & B'01101'</entry>
- <entry>00001</entry>
+ <entry><literal>B'10001' & B'01101'</literal></entry>
+ <entry><literal>00001</literal></entry>
</row>
<row>
- <entry>B'10001' | B'01101'</entry>
- <entry>11101</entry>
+ <entry><literal>B'10001' | B'01101'</literal></entry>
+ <entry><literal>11101</literal></entry>
</row>
<row>
- <entry>B'10001' # B'01101'</entry>
- <entry>11110</entry>
+ <entry><literal>B'10001' # B'01101'</literal></entry>
+ <entry><literal>11110</literal></entry>
</row>
<row>
- <entry>~ B'10001'</entry>
- <entry>01110</entry>
+ <entry><literal>~ B'10001'</literal></entry>
+ <entry><literal>01110</literal></entry>
</row>
<row>
- <entry>B'10001' << 3</entry>
- <entry>01000</entry>
+ <entry><literal>B'10001' << 3</literal></entry>
+ <entry><literal>01000</literal></entry>
</row>
<row>
- <entry>B'10001' >> 2</entry>
- <entry>00100</entry>
+ <entry><literal>B'10001' >> 2</literal></entry>
+ <entry><literal>00100</literal></entry>
</row>
</tbody>
</tgroup>
<tbody>
<row>
- <entry><function>abs</function>(<replaceable>x</replaceable>)</entry>
+ <entry><literal><function>abs</>(<replaceable>x</replaceable>)</literal></entry>
<entry>(same as <replaceable>x</>)</entry>
<entry>absolute value</entry>
<entry><literal>abs(-17.4)</literal></entry>
- <entry>17.4</entry>
+ <entry><literal>17.4</literal></entry>
</row>
<row>
- <entry><function>cbrt</function>(<type>dp</type>)</entry>
+ <entry><literal><function>cbrt</function>(<type>dp</type>)</literal></entry>
<entry><type>dp</type></entry>
<entry>cube root</entry>
<entry><literal>cbrt(27.0)</literal></entry>
- <entry>3</entry>
+ <entry><literal>3</literal></entry>
</row>
<row>
- <entry><function>ceil</function>(<type>dp</type> or <type>numeric</type>)</entry>
+ <entry><literal><function>ceil</function>(<type>dp</type> or <type>numeric</type>)</literal></entry>
<entry>(same as input)</entry>
<entry>smallest integer not less than argument</entry>
<entry><literal>ceil(-42.8)</literal></entry>
- <entry>-42</entry>
+ <entry><literal>-42</literal></entry>
</row>
<row>
- <entry><function>degrees</function>(<type>dp</type>)</entry>
+ <entry><literal><function>degrees</function>(<type>dp</type>)</literal></entry>
<entry><type>dp</type></entry>
<entry>radians to degrees</entry>
<entry><literal>degrees(0.5)</literal></entry>
- <entry>28.6478897565412</entry>
+ <entry><literal>28.6478897565412</literal></entry>
</row>
<row>
- <entry><function>exp</function>(<type>dp</type> or <type>numeric</type>)</entry>
+ <entry><literal><function>exp</function>(<type>dp</type> or <type>numeric</type>)</literal></entry>
<entry>(same as input)</entry>
<entry>exponential</entry>
<entry><literal>exp(1.0)</literal></entry>
- <entry>2.71828182845905</entry>
+ <entry><literal>2.71828182845905</literal></entry>
</row>
<row>
- <entry><function>floor</function>(<type>dp</type> or <type>numeric</type>)</entry>
+ <entry><literal><function>floor</function>(<type>dp</type> or <type>numeric</type>)</literal></entry>
<entry>(same as input)</entry>
<entry>largest integer not greater than argument</entry>
<entry><literal>floor(-42.8)</literal></entry>
- <entry>-43</entry>
+ <entry><literal>-43</literal></entry>
</row>
<row>
- <entry><function>ln</function>(<type>dp</type> or <type>numeric</type>)</entry>
+ <entry><literal><function>ln</function>(<type>dp</type> or <type>numeric</type>)</literal></entry>
<entry>(same as input)</entry>
<entry>natural logarithm</entry>
<entry><literal>ln(2.0)</literal></entry>
- <entry>0.693147180559945</entry>
+ <entry><literal>0.693147180559945</literal></entry>
</row>
<row>
- <entry><function>log</function>(<type>dp</type> or <type>numeric</type>)</entry>
+ <entry><literal><function>log</function>(<type>dp</type> or <type>numeric</type>)</literal></entry>
<entry>(same as input)</entry>
<entry>base 10 logarithm</entry>
<entry><literal>log(100.0)</literal></entry>
- <entry>2</entry>
+ <entry><literal>2</literal></entry>
</row>
<row>
- <entry><function>log</function>(<parameter>b</parameter> <type>numeric</type>,
- <parameter>x</parameter> <type>numeric</type>)</entry>
+ <entry><literal><function>log</function>(<parameter>b</parameter> <type>numeric</type>,
+ <parameter>x</parameter> <type>numeric</type>)</literal></entry>
<entry><type>numeric</type></entry>
<entry>logarithm to base <parameter>b</parameter></entry>
<entry><literal>log(2.0, 64.0)</literal></entry>
- <entry>6.0000000000</entry>
+ <entry><literal>6.0000000000</literal></entry>
</row>
<row>
- <entry><function>mod</function>(<parameter>y</parameter>,
- <parameter>x</parameter>)</entry>
+ <entry><literal><function>mod</function>(<parameter>y</parameter>,
+ <parameter>x</parameter>)</literal></entry>
<entry>(same as argument types)</entry>
<entry>remainder of <parameter>y</parameter>/<parameter>x</parameter></entry>
<entry><literal>mod(9,4)</literal></entry>
- <entry>1</entry>
+ <entry><literal>1</literal></entry>
</row>
<row>
- <entry><function>pi</function>()</entry>
+ <entry><literal><function>pi</function>()</literal></entry>
<entry><type>dp</type></entry>
- <entry><quote>Pi</quote> constant</entry>
+ <entry><quote>π</quote> constant</entry>
<entry><literal>pi()</literal></entry>
- <entry>3.14159265358979</entry>
+ <entry><literal>3.14159265358979</literal></entry>
</row>
<row>
- <entry><function>pow</function>(<parameter>x</parameter> <type>dp</type>,
- <parameter>e</parameter> <type>dp</type>)</entry>
+ <entry><literal><function>pow</function>(<parameter>a</parameter> <type>dp</type>,
+ <parameter>b</parameter> <type>dp</type>)</literal></entry>
<entry><type>dp</type></entry>
- <entry>raise a number to exponent <parameter>e</parameter></entry>
+ <entry><parameter>a</> raised to the power of <parameter>b</parameter></entry>
<entry><literal>pow(9.0, 3.0)</literal></entry>
- <entry>729</entry>
+ <entry><literal>729</literal></entry>
</row>
<row>
- <entry><function>pow</function>(<parameter>x</parameter> <type>numeric</type>,
- <parameter>e</parameter> <type>numeric</type>)</entry>
+ <entry><literal><function>pow</function>(<parameter>a</parameter> <type>numeric</type>,
+ <parameter>b</parameter> <type>numeric</type>)</literal></entry>
<entry><type>numeric</type></entry>
- <entry>raise a number to exponent <parameter>e</parameter></entry>
+ <entry><parameter>a</> raised to the power of <parameter>b</parameter></entry>
<entry><literal>pow(9.0, 3.0)</literal></entry>
- <entry>729</entry>
+ <entry><literal>729</literal></entry>
</row>
<row>
- <entry><function>radians</function>(<type>dp</type>)</entry>
+ <entry><literal><function>radians</function>(<type>dp</type>)</literal></entry>
<entry><type>dp</type></entry>
<entry>degrees to radians</entry>
<entry><literal>radians(45.0)</literal></entry>
- <entry>0.785398163397448</entry>
+ <entry><literal>0.785398163397448</literal></entry>
</row>
<row>
- <entry><function>random</function>()</entry>
+ <entry><literal><function>random</function>()</literal></entry>
<entry><type>dp</type></entry>
<entry>random value between 0.0 and 1.0</entry>
<entry><literal>random()</literal></entry>
</row>
<row>
- <entry><function>round</function>(<type>dp</type> or <type>numeric</type>)</entry>
+ <entry><literal><function>round</function>(<type>dp</type> or <type>numeric</type>)</literal></entry>
<entry>(same as input)</entry>
<entry>round to nearest integer</entry>
<entry><literal>round(42.4)</literal></entry>
- <entry>42</entry>
+ <entry><literal>42</literal></entry>
</row>
<row>
- <entry><function>round</function>(<parameter>v</parameter> <type>numeric</type>, <parameter>s</parameter> <type>integer</type>)</entry>
+ <entry><literal><function>round</function>(<parameter>v</parameter> <type>numeric</type>, <parameter>s</parameter> <type>integer</type>)</literal></entry>
<entry><type>numeric</type></entry>
<entry>round to <parameter>s</parameter> decimal places</entry>
<entry><literal>round(42.4382, 2)</literal></entry>
- <entry>42.44</entry>
+ <entry><literal>42.44</literal></entry>
</row>
<row>
- <entry><function>setseed</function>(<type>dp</type>)</entry>
+ <entry><literal><function>setseed</function>(<type>dp</type>)</literal></entry>
<entry><type>int32</type></entry>
- <entry>set seed for subsequent random() calls</entry>
+ <entry>set seed for subsequent <literal>random()</literal> calls</entry>
<entry><literal>setseed(0.54823)</literal></entry>
- <entry>1177314959</entry>
+ <entry><literal>1177314959</literal></entry>
</row>
<row>
- <entry><function>sign</function>(<type>dp</type> or <type>numeric</type>)</entry>
+ <entry><literal><function>sign</function>(<type>dp</type> or <type>numeric</type>)</literal></entry>
<entry>(same as input)</entry>
<entry>sign of the argument (-1, 0, +1)</entry>
<entry><literal>sign(-8.4)</literal></entry>
- <entry>-1</entry>
+ <entry><literal>-1</literal></entry>
</row>
<row>
- <entry><function>sqrt</function>(<type>dp</type> or <type>numeric</type>)</entry>
+ <entry><literal><function>sqrt</function>(<type>dp</type> or <type>numeric</type>)</literal></entry>
<entry>(same as input)</entry>
<entry>square root</entry>
<entry><literal>sqrt(2.0)</literal></entry>
- <entry>1.4142135623731</entry>
+ <entry><literal>1.4142135623731</literal></entry>
</row>
<row>
- <entry><function>trunc</function>(<type>dp</type> or <type>numeric</type>)</entry>
+ <entry><literal><function>trunc</function>(<type>dp</type> or <type>numeric</type>)</literal></entry>
<entry>(same as input)</entry>
<entry>truncate toward zero</entry>
<entry><literal>trunc(42.8)</literal></entry>
- <entry>42</entry>
+ <entry><literal>42</literal></entry>
</row>
<row>
- <entry><function>trunc</function>(<parameter>v</parameter> <type>numeric</type>, <parameter>s</parameter> <type>integer</type>)</entry>
+ <entry><literal><function>trunc</function>(<parameter>v</parameter> <type>numeric</type>, <parameter>s</parameter> <type>integer</type>)</literal></entry>
<entry><type>numeric</type></entry>
<entry>truncate to <parameter>s</parameter> decimal places</entry>
<entry><literal>trunc(42.4382, 2)</literal></entry>
- <entry>42.43</entry>
+ <entry><literal>42.43</literal></entry>
</row>
</tbody>
<tbody>
<row>
- <entry><function>acos</function>(<replaceable>x</replaceable>)</entry>
+ <entry><literal><function>acos</function>(<replaceable>x</replaceable>)</literal></entry>
<entry>inverse cosine</entry>
</row>
<row>
- <entry><function>asin</function>(<replaceable>x</replaceable>)</entry>
+ <entry><literal><function>asin</function>(<replaceable>x</replaceable>)</literal></entry>
<entry>inverse sine</entry>
</row>
<row>
- <entry><function>atan</function>(<replaceable>x</replaceable>)</entry>
+ <entry><literal><function>atan</function>(<replaceable>x</replaceable>)</literal></entry>
<entry>inverse tangent</entry>
</row>
<row>
- <entry><function>atan2</function>(<replaceable>x</replaceable>,
- <replaceable>y</replaceable>)</entry>
+ <entry><literal><function>atan2</function>(<replaceable>x</replaceable>,
+ <replaceable>y</replaceable>)</literal></entry>
<entry>inverse tangent of
- <replaceable>x</replaceable>/<replaceable>y</replaceable></entry>
+ <literal><replaceable>x</replaceable>/<replaceable>y</replaceable></literal></entry>
</row>
<row>
- <entry><function>cos</function>(<replaceable>x</replaceable>)</entry>
+ <entry><literal><function>cos</function>(<replaceable>x</replaceable>)</literal></entry>
<entry>cosine</entry>
</row>
<row>
- <entry><function>cot</function>(<replaceable>x</replaceable>)</entry>
+ <entry><literal><function>cot</function>(<replaceable>x</replaceable>)</literal></entry>
<entry>cotangent</entry>
</row>
<row>
- <entry><function>sin</function>(<replaceable>x</replaceable>)</entry>
+ <entry><literal><function>sin</function>(<replaceable>x</replaceable>)</literal></entry>
<entry>sine</entry>
</row>
<row>
- <entry><function>tan</function>(<replaceable>x</replaceable>)</entry>
+ <entry><literal><function>tan</function>(<replaceable>x</replaceable>)</literal></entry>
<entry>tangent</entry>
</row>
</tbody>
<para>
This section describes functions and operators for examining and
manipulating string values. Strings in this context include values
- of all the types <type>CHARACTER</type>, <type>CHARACTER
- VARYING</type>, and <type>TEXT</type>. Unless otherwise noted, all
+ of all the types <type>character</type>, <type>character
+ varying</type>, and <type>text</type>. Unless otherwise noted, all
of the functions listed below work on all of these types, but be
wary of potential effects of the automatic padding when using the
- <type>CHARACTER</type> type. Generally, the functions described
+ <type>character</type> type. Generally, the functions described
here also work on data of non-string types by converting that data
to a string representation first. Some functions also exist
- natively for bit-string types.
+ natively for the bit-string types.
</para>
<para>
<tbody>
<row>
- <entry> <parameter>string</parameter> <literal>||</literal>
- <parameter>string</parameter> </entry>
+ <entry><literal><parameter>string</parameter> <literal>||</literal>
+ <parameter>string</parameter></literal></entry>
<entry> <type>text</type> </entry>
<entry>
String concatenation
</row>
<row>
- <entry><function>bit_length</function>(<parameter>string</parameter>)</entry>
+ <entry><literal><function>bit_length</function>(<parameter>string</parameter>)</literal></entry>
<entry><type>integer</type></entry>
<entry>Number of bits in string</entry>
<entry><literal>bit_length('jose')</literal></entry>
</row>
<row>
- <entry><function>char_length</function>(<parameter>string</parameter>) or <function>character_length</function>(<parameter>string</parameter>)</entry>
+ <entry><literal><function>char_length</function>(<parameter>string</parameter>)</literal> or <literal><function>character_length</function>(<parameter>string</parameter>)</literal></entry>
<entry><type>integer</type></entry>
<entry>
Number of characters in string
</row>
<row>
- <entry><function>convert</function>(<parameter>string</parameter>
- using <parameter>conversion_name</parameter>)</entry>
+ <entry><literal><function>convert</function>(<parameter>string</parameter>
+ using <parameter>conversion_name</parameter>)</literal></entry>
<entry><type>text</type></entry>
<entry>
Change encoding using specified conversion name. Conversions
</row>
<row>
- <entry><function>lower</function>(<parameter>string</parameter>)</entry>
+ <entry><literal><function>lower</function>(<parameter>string</parameter>)</literal></entry>
<entry><type>text</type></entry>
<entry>Convert string to lower case</entry>
<entry><literal>lower('TOM')</literal></entry>
</row>
<row>
- <entry><function>octet_length</function>(<parameter>string</parameter>)</entry>
+ <entry><literal><function>octet_length</function>(<parameter>string</parameter>)</literal></entry>
<entry><type>integer</type></entry>
<entry>Number of bytes in string</entry>
<entry><literal>octet_length('jose')</literal></entry>
</row>
<row>
- <entry><function>overlay</function>(<parameter>string</parameter> placing <parameter>string</parameter> from <type>integer</type> <optional>for <type>integer</type></optional>)</entry>
+ <entry><literal><function>overlay</function>(<parameter>string</parameter> placing <parameter>string</parameter> from <type>integer</type> <optional>for <type>integer</type></optional>)</literal></entry>
<entry><type>text</type></entry>
<entry>
- Insert substring
+ Replace substring
<indexterm>
<primary>overlay</primary>
</indexterm>
</row>
<row>
- <entry><function>position</function>(<parameter>substring</parameter> in <parameter>string</parameter>)</entry>
+ <entry><literal><function>position</function>(<parameter>substring</parameter> in <parameter>string</parameter>)</literal></entry>
<entry><type>integer</type></entry>
<entry>Location of specified substring</entry>
<entry><literal>position('om' in 'Thomas')</literal></entry>
</row>
<row>
- <entry><function>substring</function>(<parameter>string</parameter> <optional>from <type>integer</type></optional> <optional>for <type>integer</type></optional>)</entry>
+ <entry><literal><function>substring</function>(<parameter>string</parameter> <optional>from <type>integer</type></optional> <optional>for <type>integer</type></optional>)</literal></entry>
<entry><type>text</type></entry>
<entry>
Extract substring
</row>
<row>
- <entry><function>substring</function>(<parameter>string</parameter> from <replaceable>pattern</replaceable>)</entry>
+ <entry><literal><function>substring</function>(<parameter>string</parameter> from <replaceable>pattern</replaceable>)</literal></entry>
<entry><type>text</type></entry>
<entry>
Extract substring matching POSIX regular expression
</row>
<row>
- <entry><function>substring</function>(<parameter>string</parameter> from <replaceable>pattern</replaceable> for <replaceable>escape</replaceable>)</entry>
+ <entry><literal><function>substring</function>(<parameter>string</parameter> from <replaceable>pattern</replaceable> for <replaceable>escape</replaceable>)</literal></entry>
<entry><type>text</type></entry>
<entry>
Extract substring matching <acronym>SQL</acronym> regular
<row>
<entry>
- <function>trim</function>(<optional>leading | trailing | both</optional>
+ <literal><function>trim</function>(<optional>leading | trailing | both</optional>
<optional><parameter>characters</parameter></optional> from
- <parameter>string</parameter>)
+ <parameter>string</parameter>)</literal>
</entry>
<entry><type>text</type></entry>
<entry>
Remove the longest string containing only the
<parameter>characters</parameter> (a space by default) from the
- beginning/end/both ends of the <parameter>string</parameter>
+ start/end/both ends of the <parameter>string</parameter>.
</entry>
<entry><literal>trim(both 'x' from 'xTomxx')</literal></entry>
<entry><literal>Tom</literal></entry>
</row>
<row>
- <entry><function>upper</function>(<parameter>string</parameter>)</entry>
+ <entry><literal><function>upper</function>(<parameter>string</parameter>)</literal></entry>
<entry><type>text</type></entry>
<entry>Convert string to upper case</entry>
<entry><literal>upper('tom')</literal></entry>
<tbody>
<row>
- <entry><function>ascii</function>(<type>text</type>)</entry>
+ <entry><literal><function>ascii</function>(<type>text</type>)</literal></entry>
<entry>integer</entry>
- <entry><acronym>ASCII</acronym> code of the first character of the argument.</entry>
+ <entry><acronym>ASCII</acronym> code of the first character of the argument</entry>
<entry><literal>ascii('x')</literal></entry>
<entry><literal>120</literal></entry>
</row>
<row>
- <entry><function>btrim</function>(<parameter>string</parameter> <type>text</type>, <parameter>trim</parameter> <type>text</type>)</entry>
+ <entry><literal><function>btrim</function>(<parameter>string</parameter> <type>text</type>, <parameter>characters</parameter> <type>text</type>)</literal></entry>
<entry><type>text</type></entry>
<entry>
- Remove (trim) the longest string consisting only of characters
- in <parameter>trim</parameter> from the start and end of
- <parameter>string</parameter>
+ Remove the longest string consisting only of characters
+ in <parameter>characters</parameter> from the start and end of
+ <parameter>string</parameter>.
</entry>
<entry><literal>btrim('xyxtrimyyx','xy')</literal></entry>
<entry><literal>trim</literal></entry>
</row>
<row>
- <entry><function>chr</function>(<type>integer</type>)</entry>
+ <entry><literal><function>chr</function>(<type>integer</type>)</literal></entry>
<entry><type>text</type></entry>
<entry>Character with the given <acronym>ASCII</acronym> code</entry>
<entry><literal>chr(65)</literal></entry>
<row>
<entry>
- <function>convert</function>(<parameter>string</parameter>
+ <literal><function>convert</function>(<parameter>string</parameter>
<type>text</type>,
<optional><parameter>src_encoding</parameter> <type>name</type>,</optional>
- <parameter>dest_encoding</parameter> <type>name</type>)
+ <parameter>dest_encoding</parameter> <type>name</type>)</literal>
</entry>
<entry><type>text</type></entry>
<entry>
encoding is assumed.
</entry>
<entry><literal>convert('text_in_unicode', 'UNICODE', 'LATIN1')</literal></entry>
- <entry><literal>text_in_unicode</literal> represented in ISO 8859-1</entry>
+ <entry><literal>text_in_unicode</literal> represented in ISO 8859-1 encoding</entry>
</row>
<row>
<entry>
- <function>decode</function>(<parameter>string</parameter> <type>text</type>,
- <parameter>type</parameter> <type>text</type>)
+ <literal><function>decode</function>(<parameter>string</parameter> <type>text</type>,
+ <parameter>type</parameter> <type>text</type>)</literal>
</entry>
<entry><type>bytea</type></entry>
<entry>
Decode binary data from <parameter>string</parameter> previously
- encoded with <function>encode()</>. Parameter type is same as in <function>encode()</>.
+ encoded with <function>encode</>. Parameter type is same as in <function>encode</>.
</entry>
<entry><literal>decode('MTIzAAE=', 'base64')</literal></entry>
<entry><literal>123\000\001</literal></entry>
<row>
<entry>
- <function>encode</function>(<parameter>data</parameter> <type>bytea</type>,
- <parameter>type</parameter> <type>text</type>)
+ <literal><function>encode</function>(<parameter>data</parameter> <type>bytea</type>,
+ <parameter>type</parameter> <type>text</type>)</literal>
</entry>
<entry><type>text</type></entry>
<entry>
Encode binary data to <acronym>ASCII</acronym>-only representation. Supported
- types are: base64, hex, escape.
+ types are: <literal>base64</>, <literal>hex</>, <literal>escape</>.
</entry>
<entry><literal>encode('123\\000\\001', 'base64')</literal></entry>
<entry><literal>MTIzAAE=</literal></entry>
</row>
<row>
- <entry><function>initcap</function>(<type>text</type>)</entry>
+ <entry><literal><function>initcap</function>(<type>text</type>)</literal></entry>
<entry><type>text</type></entry>
- <entry>Convert first letter of each word (whitespace separated) to upper case</entry>
+ <entry>Convert first letter of each word (whitespace-separated) to upper case</entry>
<entry><literal>initcap('hi thomas')</literal></entry>
<entry><literal>Hi Thomas</literal></entry>
</row>
<row>
- <entry><function>length</function>(<parameter>string</parameter>)</entry>
+ <entry><literal><function>length</function>(<parameter>string</parameter>)</literal></entry>
<entry><type>integer</type></entry>
<entry>
- Length of string
+ Number of characters in string
<indexterm>
<primary>character strings</primary>
<secondary>length</secondary>
<row>
<entry>
- <function>lpad</function>(<parameter>string</parameter> <type>text</type>,
+ <literal><function>lpad</function>(<parameter>string</parameter> <type>text</type>,
<parameter>length</parameter> <type>integer</type>
- <optional>, <parameter>fill</parameter> <type>text</type></optional>)
+ <optional>, <parameter>fill</parameter> <type>text</type></optional>)</literal>
</entry>
<entry>text</entry>
<entry>
</row>
<row>
- <entry><function>ltrim</function>(<parameter>string</parameter> <type>text</type>, <parameter>text</parameter> <type>text</type>)</entry>
+ <entry><literal><function>ltrim</function>(<parameter>string</parameter> <type>text</type>, <parameter>characters</parameter> <type>text</type>)</literal></entry>
<entry><type>text</type></entry>
<entry>
Remove the longest string containing only characters from
- <parameter>trim</parameter> from the start of the string.
+ <parameter>characters</parameter> from the start of the string.
</entry>
<entry><literal>ltrim('zzzytrim','xyz')</literal></entry>
<entry><literal>trim</literal></entry>
</row>
<row>
- <entry><function>md5</function>(<parameter>string</parameter> <type>text</type>)</entry>
+ <entry><literal><function>md5</function>(<parameter>string</parameter> <type>text</type>)</literal></entry>
<entry><type>text</type></entry>
<entry>
- Calculates the MD5 hash of given string, returning the result in hex.
+ Calculates the MD5 hash of given string, returning the result in hexadecimal.
</entry>
<entry><literal>md5('abc')</literal></entry>
<entry><literal>900150983cd24fb0d6963f7d28e17f72</literal></entry>
</row>
<row>
- <entry><function>pg_client_encoding</function>()</entry>
+ <entry><literal><function>pg_client_encoding</function>()</literal></entry>
<entry><type>name</type></entry>
<entry>
- Current client encoding name.
+ Current client encoding name
</entry>
<entry><literal>pg_client_encoding()</literal></entry>
<entry><literal>SQL_ASCII</literal></entry>
</row>
<row>
- <entry><function>quote_ident</function>(<parameter>string</parameter> text)</entry>
+ <entry><literal><function>quote_ident</function>(<parameter>string</parameter> text)</literal></entry>
<entry><type>text</type></entry>
<entry>
Return the given string suitably quoted to be used as an identifier
- in an <acronym>SQL</acronym> query string.
+ in an <acronym>SQL</acronym> statement string.
Quotes are added only if necessary (i.e., if the string contains
non-identifier characters or would be case-folded).
Embedded quotes are properly doubled.
</row>
<row>
- <entry><function>quote_literal</function>(<parameter>string</parameter> text)</entry>
+ <entry><literal><function>quote_literal</function>(<parameter>string</parameter> text)</literal></entry>
<entry><type>text</type></entry>
<entry>
- Return the given string suitably quoted to be used as a literal
- in an <acronym>SQL</acronym> query string.
+ Return the given string suitably quoted to be used as a string literal
+ in an <acronym>SQL</acronym> statement string.
Embedded quotes and backslashes are properly doubled.
</entry>
<entry><literal>quote_literal('O\'Reilly')</literal></entry>
</row>
<row>
- <entry><function>repeat</function>(<type>text</type>, <type>integer</type>)</entry>
+ <entry><literal><function>repeat</function>(<type>text</type>, <type>integer</type>)</literal></entry>
<entry><type>text</type></entry>
<entry>Repeat text a number of times</entry>
<entry><literal>repeat('Pg', 4)</literal></entry>
</row>
<row>
- <entry><function>replace</function>(<parameter>string</parameter> <type>text</type>,
+ <entry><literal><function>replace</function>(<parameter>string</parameter> <type>text</type>,
<parameter>from</parameter> <type>text</type>,
- <parameter>to</parameter> <type>text</type>)</entry>
+ <parameter>to</parameter> <type>text</type>)</literal></entry>
<entry><type>text</type></entry>
<entry>Replace all occurrences in <parameter>string</parameter> of substring
- <parameter>from</parameter> with substring <parameter>to</parameter>
+ <parameter>from</parameter> with substring <parameter>to</parameter>.
</entry>
<entry><literal>replace('abcdefabcdef', 'cd', 'XX')</literal></entry>
<entry><literal>abXXefabXXef</literal></entry>
<row>
<entry>
- <function>rpad</function>(<parameter>string</parameter> <type>text</type>,
+ <literal><function>rpad</function>(<parameter>string</parameter> <type>text</type>,
<parameter>length</parameter> <type>integer</type>
- <optional>, <parameter>fill</parameter> <type>text</type></optional>)
+ <optional>, <parameter>fill</parameter> <type>text</type></optional>)</literal>
</entry>
<entry><type>text</type></entry>
<entry>
</row>
<row>
- <entry><function>rtrim</function>(<parameter>string</parameter>
- text, <parameter>trim</parameter> text)</entry>
+ <entry><literal><function>rtrim</function>(<parameter>string</parameter>
+ text, <parameter>characters</parameter> text)</literal></entry>
<entry><type>text</type></entry>
<entry>
Remove the longest string containing only characters from
- <parameter>trim</parameter> from the end of the string.
+ <parameter>characters</parameter> from the end of the string.
</entry>
<entry><literal>rtrim('trimxxxx','x')</literal></entry>
<entry><literal>trim</literal></entry>
</row>
<row>
- <entry><function>split_part</function>(<parameter>string</parameter> <type>text</type>,
+ <entry><literal><function>split_part</function>(<parameter>string</parameter> <type>text</type>,
<parameter>delimiter</parameter> <type>text</type>,
- <parameter>column</parameter> <type>integer</type>)</entry>
+ <parameter>field</parameter> <type>integer</type>)</literal></entry>
<entry><type>text</type></entry>
<entry>Split <parameter>string</parameter> on <parameter>delimiter</parameter>
- returning the resulting (one based) <parameter>column</parameter> number.
+ and return the given field (counting from one)
</entry>
<entry><literal>split_part('abc~@~def~@~ghi','~@~',2)</literal></entry>
<entry><literal>def</literal></entry>
</row>
<row>
- <entry><function>strpos</function>(<parameter>string</parameter>, <parameter>substring</parameter>)</entry>
+ <entry><literal><function>strpos</function>(<parameter>string</parameter>, <parameter>substring</parameter>)</literal></entry>
<entry><type>text</type></entry>
<entry>
- Locate specified substring (same as
+ Location of specified substring (same as
<literal>position(<parameter>substring</parameter> in
<parameter>string</parameter>)</literal>, but note the reversed
argument order)
</row>
<row>
- <entry><function>substr</function>(<parameter>string</parameter>, <parameter>from</parameter> <optional>, <parameter>count</parameter></optional>)</entry>
+ <entry><literal><function>substr</function>(<parameter>string</parameter>, <parameter>from</parameter> <optional>, <parameter>count</parameter></optional>)</literal></entry>
<entry><type>text</type></entry>
<entry>
- Extract specified substring (same as
+ Extract substring (same as
<literal>substring(<parameter>string</parameter> from <parameter>from</parameter> for <parameter>count</parameter>)</literal>)
</entry>
<entry><literal>substr('alphabet', 3, 2)</literal></entry>
</row>
<row>
- <entry><function>to_ascii</function>(<type>text</type>
- <optional>, <parameter>encoding</parameter></optional>)</entry>
+ <entry><literal><function>to_ascii</function>(<type>text</type>
+ <optional>, <parameter>encoding</parameter></optional>)</literal></entry>
<entry><type>text</type></entry>
<entry>
</row>
<row>
- <entry><function>to_hex</function>(<parameter>number</parameter> <type>integer</type>
- or <type>bigint</type>)</entry>
+ <entry><literal><function>to_hex</function>(<parameter>number</parameter> <type>integer</type>
+ or <type>bigint</type>)</literal></entry>
<entry><type>text</type></entry>
<entry>Convert <parameter>number</parameter> to its equivalent hexadecimal
representation
</entry>
- <entry><literal>to_hex(9223372036854775807::bigint)</literal></entry>
+ <entry><literal>to_hex(9223372036854775807)</literal></entry>
<entry><literal>7fffffffffffffff</literal></entry>
</row>
<row>
<entry>
- <function>translate</function>(<parameter>string</parameter>
+ <literal><function>translate</function>(<parameter>string</parameter>
<type>text</type>,
<parameter>from</parameter> <type>text</type>,
- <parameter>to</parameter> <type>text</type>)
+ <parameter>to</parameter> <type>text</type>)</literal>
</entry>
<entry><type>text</type></entry>
<entry>
<para>
This section describes functions and operators for examining and
- manipulating binary string values. Strings in this context mean
- values of the type <type>BYTEA</type>.
+ manipulating values of type <type>bytea</type>.
</para>
<para>
<tbody>
<row>
- <entry> <parameter>string</parameter> <literal>||</literal>
- <parameter>string</parameter> </entry>
+ <entry><literal><parameter>string</parameter> <literal>||</literal>
+ <parameter>string</parameter></literal></entry>
<entry> <type>bytea</type> </entry>
<entry>
String concatenation
</row>
<row>
- <entry><function>octet_length</function>(<parameter>string</parameter>)</entry>
+ <entry><literal><function>octet_length</function>(<parameter>string</parameter>)</literal></entry>
<entry><type>integer</type></entry>
<entry>Number of bytes in binary string</entry>
<entry><literal>octet_length('jo\\000se'::bytea)</literal></entry>
</row>
<row>
- <entry><function>position</function>(<parameter>substring</parameter> in <parameter>string</parameter>)</entry>
+ <entry><literal><function>position</function>(<parameter>substring</parameter> in <parameter>string</parameter>)</literal></entry>
<entry><type>integer</type></entry>
<entry>Location of specified substring</entry>
<entry><literal>position('\\000om'::bytea in 'Th\\000omas'::bytea)</literal></entry>
</row>
<row>
- <entry><function>substring</function>(<parameter>string</parameter> <optional>from <type>integer</type></optional> <optional>for <type>integer</type></optional>)</entry>
+ <entry><literal><function>substring</function>(<parameter>string</parameter> <optional>from <type>integer</type></optional> <optional>for <type>integer</type></optional>)</literal></entry>
<entry><type>bytea</type></entry>
<entry>
Extract substring
<row>
<entry>
- <function>trim</function>(<optional>both</optional>
- <parameter>characters</parameter> from
- <parameter>string</parameter>)
+ <literal><function>trim</function>(<optional>both</optional>
+ <parameter>bytes</parameter> from
+ <parameter>string</parameter>)</literal>
</entry>
<entry><type>bytea</type></entry>
<entry>
- Remove the longest string containing only the
- <parameter>characters</parameter> from the
- beginning/end/both ends of the <parameter>string</parameter>
+ Remove the longest string containing only the bytes in
+ <parameter>bytes</parameter> from the start
+ and end of <parameter>string</parameter>
</entry>
<entry><literal>trim('\\000'::bytea from '\\000Tom\\000'::bytea)</literal></entry>
<entry><literal>Tom</literal></entry>
<tbody>
<row>
- <entry><function>btrim</function>(<parameter>string</parameter>
- <type>bytea</type> <parameter>trim</parameter> <type>bytea</type>)</entry>
+ <entry><literal><function>btrim</function>(<parameter>string</parameter>
+ <type>bytea</type> <parameter>bytes</parameter> <type>bytea</type>)</literal></entry>
<entry><type>bytea</type></entry>
<entry>
- Remove (trim) the longest string consisting only of characters
- in <parameter>trim</parameter> from the start and end of
+ Remove the longest string consisting only of bytes
+ in <parameter>bytes</parameter> from the start and end of
<parameter>string</parameter>.
</entry>
<entry><literal>btrim('\\000trim\\000'::bytea,'\\000'::bytea)</literal></entry>
</row>
<row>
- <entry><function>length</function>(<parameter>string</parameter>)</entry>
+ <entry><literal><function>length</function>(<parameter>string</parameter>)</literal></entry>
<entry><type>integer</type></entry>
<entry>
Length of binary string
<row>
<entry>
- <function>encode</function>(<parameter>string</parameter> <type>bytea</type>,
- <parameter>type</parameter> <type>text</type>)
+ <literal><function>decode</function>(<parameter>string</parameter> <type>text</type>,
+ <parameter>type</parameter> <type>text</type>)</literal>
</entry>
- <entry><type>text</type></entry>
+ <entry><type>bytea</type></entry>
<entry>
- Encode binary string to <acronym>ASCII</acronym>-only representation. Supported
- types are: base64, hex, escape.
+ Decode binary string from <parameter>string</parameter> previously
+ encoded with <literal>encode</>. Parameter type is same as in <literal>encode</>.
</entry>
- <entry><literal>encode('123\\000456'::bytea, 'escape')</literal></entry>
+ <entry><literal>decode('123\\000456', 'escape')</literal></entry>
<entry><literal>123\000456</literal></entry>
</row>
<row>
<entry>
- <function>decode</function>(<parameter>string</parameter> <type>text</type>,
- <parameter>type</parameter> <type>text</type>)
+ <literal><function>encode</function>(<parameter>string</parameter> <type>bytea</type>,
+ <parameter>type</parameter> <type>text</type>)</literal>
</entry>
- <entry><type>bytea</type></entry>
+ <entry><type>text</type></entry>
<entry>
- Decode binary string from <parameter>string</parameter> previously
- encoded with <literal>encode()</>. Parameter type is same as in <literal>encode()</>.
+ Encode binary string to <acronym>ASCII</acronym>-only representation. Supported
+ types are: <literal>base64</>, <literal>hex</>, <literal>escape</>.
</entry>
- <entry><literal>decode('123\\000456', 'escape')</literal></entry>
+ <entry><literal>encode('123\\000456'::bytea, 'escape')</literal></entry>
<entry><literal>123\000456</literal></entry>
</row>
<sect1 id="functions-matching">
<title>Pattern Matching</title>
+ <indexterm zone="functions-matching">
+ <primary>pattern matching</primary>
+ </indexterm>
+
<para>
There are three separate approaches to pattern matching provided by
<productname>PostgreSQL</productname>: the traditional
<function>SIMILAR TO</function> operator, and
<acronym>POSIX</acronym>-style regular expressions.
Additionally, a pattern matching function,
- <function>SUBSTRING</function>, is available, using either
+ <function>substring</function>, is available, using either
<acronym>SQL99</acronym>-style or POSIX-style regular expressions.
</para>
<para>
Note that the backslash already has a special meaning in string
literals, so to write a pattern constant that contains a backslash
- you must write two backslashes in the query. Thus, writing a pattern
+ you must write two backslashes in an SQL statement. Thus, writing a pattern
that actually matches a literal backslash means writing four backslashes
- in the query. You can avoid this by selecting a different escape
- character with <literal>ESCAPE</literal>; then backslash is not special
+ in the statement. You can avoid this by selecting a different escape
+ character with <literal>ESCAPE</literal>; then a backslash is not special
to <function>LIKE</function> anymore. (But it is still special to the string
literal parser, so you still need two of them.)
</para>
</para>
<para>
- The keyword <token>ILIKE</token> can be used instead of
+ The key word <token>ILIKE</token> can be used instead of
<token>LIKE</token> to make the match case insensitive according
to the active locale. This is not in the <acronym>SQL</acronym> standard but is a
<productname>PostgreSQL</productname> extension.
<function>ILIKE</function>. There are also
<literal>!~~</literal> and <literal>!~~*</literal> operators that
represent <function>NOT LIKE</function> and <function>NOT
- ILIKE</function>. All of these operators are
+ ILIKE</function>, respectively. All of these operators are
<productname>PostgreSQL</productname>-specific.
</para>
</sect2>
may match any part of the string.
Also like
<function>LIKE</function>, <function>SIMILAR TO</function> uses
- <literal>%</> and <literal>_</> as wildcard characters denoting
- any string and any single character, respectively (these are
- comparable to <literal>.*</> and <literal>.</> in POSIX regular
+ <literal>_</> and <literal>%</> as wildcard characters denoting
+ any single character and any string, respectively (these are
+ comparable to <literal>.</> and <literal>.*</> in POSIX regular
expressions).
</para>
</itemizedlist>
Notice that bounded repetition (<literal>?</> and <literal>{...}</>)
- are not provided, though they exist in POSIX. Also, dot (<literal>.</>)
+ are not provided, though they exist in POSIX. Also, the dot (<literal>.</>)
is not a metacharacter.
</para>
</para>
<para>
- The <function>SUBSTRING</> function with three parameters,
- <function>SUBSTRING(<parameter>string</parameter> FROM
- <replaceable>pattern</replaceable> FOR
- <replaceable>escape</replaceable>)</function>, provides
+ The <function>substring</> function with three parameters,
+ <function>substring(<parameter>string</parameter> from
+ <replaceable>pattern</replaceable> for
+ <replaceable>escape-character</replaceable>)</function>, provides
extraction of a substring that matches a <acronym>SQL99</acronym>
regular expression pattern. As with <literal>SIMILAR TO</>, the
specified pattern must match to the entire data string, else the
function fails and returns null. To indicate the part of the
- pattern that should be returned on success,
- <acronym>SQL99</acronym> specifies that the pattern must contain
- two occurrences of the escape character followed by double quote
+ pattern that should be returned on success, the pattern must contain
+ two occurrences of the escape character followed by a double quote
(<literal>"</>). The text matching the portion of the pattern
between these markers is returned.
</para>
<para>
Some examples:
<programlisting>
-SUBSTRING('foobar' FROM '%#"o_b#"%' FOR '#') <lineannotation>oob</lineannotation>
-SUBSTRING('foobar' FROM '#"o_b#"%' FOR '#') <lineannotation>NULL</lineannotation>
+substring('foobar' from '%#"o_b#"%' for '#') <lineannotation>oob</lineannotation>
+substring('foobar' from '#"o_b#"%' for '#') <lineannotation>NULL</lineannotation>
</programlisting>
</para>
</sect2>
</para>
<para>
- The <function>SUBSTRING</> function with two parameters,
- <function>SUBSTRING(<parameter>string</parameter> FROM
+ The <function>substring</> function with two parameters,
+ <function>substring(<parameter>string</parameter> from
<replaceable>pattern</replaceable>)</function>, provides extraction of a substring
that matches a POSIX regular expression pattern. It returns null if
there is no match, otherwise the portion of the text that matched the
<para>
Some examples:
<programlisting>
-SUBSTRING('foobar' FROM 'o.b') <lineannotation>oob</lineannotation>
-SUBSTRING('foobar' FROM 'o(.)b') <lineannotation>o</lineannotation>
+substring('foobar' from 'o.b') <lineannotation>oob</lineannotation>
+substring('foobar' from 'o(.)b') <lineannotation>o</lineannotation>
</programlisting>
</para>
Remember that the backslash (<literal>\</literal>) already has a special
meaning in <productname>PostgreSQL</> string literals.
To write a pattern constant that contains a backslash,
- you must write two backslashes in the query.
+ you must write two backslashes in the statement.
</para>
</note>
<thead>
<row>
<entry>Function</entry>
- <entry>Returns</entry>
+ <entry>Return Type</entry>
<entry>Description</entry>
<entry>Example</entry>
</row>
</thead>
<tbody>
<row>
- <entry><function>to_char</function>(<type>timestamp</type>, <type>text</type>)</entry>
+ <entry><literal><function>to_char</function>(<type>timestamp</type>, <type>text</type>)</literal></entry>
<entry><type>text</type></entry>
<entry>convert time stamp to string</entry>
- <entry><literal>to_char(timestamp 'now','HH12:MI:SS')</literal></entry>
+ <entry><literal>to_char(current_timestamp, 'HH12:MI:SS')</literal></entry>
</row>
<row>
- <entry><function>to_char</function>(<type>interval</type>, <type>text</type>)</entry>
+ <entry><literal><function>to_char</function>(<type>interval</type>, <type>text</type>)</literal></entry>
<entry><type>text</type></entry>
<entry>convert interval to string</entry>
- <entry><literal>to_char(interval '15h 2m 12s','HH24:MI:SS')</literal></entry>
+ <entry><literal>to_char(interval '15h 2m 12s', 'HH24:MI:SS')</literal></entry>
</row>
<row>
- <entry><function>to_char</function>(<type>int</type>, <type>text</type>)</entry>
+ <entry><literal><function>to_char</function>(<type>int</type>, <type>text</type>)</literal></entry>
<entry><type>text</type></entry>
<entry>convert integer to string</entry>
<entry><literal>to_char(125, '999')</literal></entry>
</row>
<row>
- <entry><function>to_char</function>(<type>double precision</type>,
- <type>text</type>)</entry>
+ <entry><literal><function>to_char</function>(<type>double precision</type>,
+ <type>text</type>)</literal></entry>
<entry><type>text</type></entry>
<entry>convert real/double precision to string</entry>
- <entry><literal>to_char(125.8, '999D9')</literal></entry>
+ <entry><literal>to_char(125.8::real, '999D9')</literal></entry>
</row>
<row>
- <entry><function>to_char</function>(<type>numeric</type>, <type>text</type>)</entry>
+ <entry><literal><function>to_char</function>(<type>numeric</type>, <type>text</type>)</literal></entry>
<entry><type>text</type></entry>
<entry>convert numeric to string</entry>
- <entry><literal>to_char(numeric '-125.8', '999D99S')</literal></entry>
+ <entry><literal>to_char(-125.8, '999D99S')</literal></entry>
</row>
<row>
- <entry><function>to_date</function>(<type>text</type>, <type>text</type>)</entry>
+ <entry><literal><function>to_date</function>(<type>text</type>, <type>text</type>)</literal></entry>
<entry><type>date</type></entry>
<entry>convert string to date</entry>
- <entry><literal>to_date('05 Dec 2000', 'DD Mon YYYY')</literal></entry>
+ <entry><literal>to_date('05 Dec 2000', 'DD Mon YYYY')</literal></entry>
</row>
<row>
- <entry><function>to_timestamp</function>(<type>text</type>, <type>text</type>)</entry>
+ <entry><literal><function>to_timestamp</function>(<type>text</type>, <type>text</type>)</literal></entry>
<entry><type>timestamp</type></entry>
<entry>convert string to time stamp</entry>
- <entry><literal>to_timestamp('05 Dec 2000', 'DD Mon YYYY')</literal></entry>
+ <entry><literal>to_timestamp('05 Dec 2000', 'DD Mon YYYY')</literal></entry>
</row>
<row>
- <entry><function>to_number</function>(<type>text</type>, <type>text</type>)</entry>
+ <entry><literal><function>to_number</function>(<type>text</type>, <type>text</type>)</literal></entry>
<entry><type>numeric</type></entry>
<entry>convert string to numeric</entry>
<entry><literal>to_number('12,454.8-', '99G999D9S')</literal></entry>
</table>
<para>
- In an output template string, there are certain patterns that are
+ In an output template string (for <function>to_char</>), there are certain patterns that are
recognized and replaced with appropriately-formatted data from the value
to be formatted. Any text that is not a template pattern is simply
- copied verbatim. Similarly, in an input template string, template patterns
+ copied verbatim. Similarly, in an input template string (for anything but <function>to_char</>), template patterns
identify the parts of the input data string to be looked at and the
values to be found there.
</para>
</para>
<table id="functions-formatting-datetime-table">
- <title>Template patterns for date/time conversions</title>
+ <title>Template Patterns for Date/Time Formatting</title>
<tgroup cols="2">
<thead>
<row>
</row>
<row>
<entry><literal>MONTH</literal></entry>
- <entry>full upper case month name (blank-padded to 9 chars)</entry>
+ <entry>full upper-case month name (blank-padded to 9 chars)</entry>
</row>
<row>
<entry><literal>Month</literal></entry>
- <entry>full mixed case month name (blank-padded to 9 chars)</entry>
+ <entry>full mixed-case month name (blank-padded to 9 chars)</entry>
</row>
<row>
<entry><literal>month</literal></entry>
- <entry>full lower case month name (blank-padded to 9 chars)</entry>
+ <entry>full lower-case month name (blank-padded to 9 chars)</entry>
</row>
<row>
<entry><literal>MON</literal></entry>
- <entry>abbreviated upper case month name (3 chars)</entry>
+ <entry>abbreviated upper-case month name (3 chars)</entry>
</row>
<row>
<entry><literal>Mon</literal></entry>
- <entry>abbreviated mixed case month name (3 chars)</entry>
+ <entry>abbreviated mixed-case month name (3 chars)</entry>
</row>
<row>
<entry><literal>mon</literal></entry>
- <entry>abbreviated lower case month name (3 chars)</entry>
+ <entry>abbreviated lower-case month name (3 chars)</entry>
</row>
<row>
<entry><literal>MM</literal></entry>
</row>
<row>
<entry><literal>DAY</literal></entry>
- <entry>full upper case day name (blank-padded to 9 chars)</entry>
+ <entry>full upper-case day name (blank-padded to 9 chars)</entry>
</row>
<row>
<entry><literal>Day</literal></entry>
- <entry>full mixed case day name (blank-padded to 9 chars)</entry>
+ <entry>full mixed-case day name (blank-padded to 9 chars)</entry>
</row>
<row>
<entry><literal>day</literal></entry>
- <entry>full lower case day name (blank-padded to 9 chars)</entry>
+ <entry>full lower-case day name (blank-padded to 9 chars)</entry>
</row>
<row>
<entry><literal>DY</literal></entry>
- <entry>abbreviated upper case day name (3 chars)</entry>
+ <entry>abbreviated upper-case day name (3 chars)</entry>
</row>
<row>
<entry><literal>Dy</literal></entry>
- <entry>abbreviated mixed case day name (3 chars)</entry>
+ <entry>abbreviated mixed-case day name (3 chars)</entry>
</row>
<row>
<entry><literal>dy</literal></entry>
- <entry>abbreviated lower case day name (3 chars)</entry>
+ <entry>abbreviated lower-case day name (3 chars)</entry>
</row>
<row>
<entry><literal>DDD</literal></entry>
</row>
<row>
<entry><literal>D</literal></entry>
- <entry>day of week (1-7; SUN=1)</entry>
+ <entry>day of week (1-7; Sunday is 1)</entry>
</row>
<row>
<entry><literal>W</literal></entry>
- <entry>week of month (1-5) where first week start on the first day of the month</entry>
+ <entry>week of month (1-5) (The first week starts on the first day of the month.)</entry>
</row>
<row>
<entry><literal>WW</literal></entry>
- <entry>week number of year (1-53) where first week start on the first day of the year</entry>
+ <entry>week number of year (1-53) (The first week starts on the first day of the year.)</entry>
</row>
<row>
<entry><literal>IW</literal></entry>
</row>
<row>
<entry><literal>RM</literal></entry>
- <entry>month in Roman Numerals (I-XII; I=January) - upper case</entry>
+ <entry>month in Roman numerals (I-XII; I=January) (upper case)</entry>
</row>
<row>
<entry><literal>rm</literal></entry>
- <entry>month in Roman Numerals (I-XII; I=January) - lower case</entry>
+ <entry>month in Roman numerals (i-xii; i=January) (lower case)</entry>
</row>
<row>
<entry><literal>TZ</literal></entry>
- <entry>time-zone name - upper case</entry>
+ <entry>time-zone name (upper case)</entry>
</row>
<row>
<entry><literal>tz</literal></entry>
- <entry>time-zone name - lower case</entry>
+ <entry>time-zone name (lower case)</entry>
</row>
</tbody>
</tgroup>
<para>
Certain modifiers may be applied to any template pattern to alter its
- behavior. For example, <quote><literal>FMMonth</literal></quote>
- is the <quote><literal>Month</literal></quote> pattern with the
- <quote><literal>FM</literal></quote> prefix.
+ behavior. For example, <literal>FMMonth</literal>
+ is the <literal>Month</literal> pattern with the
+ <literal>FM</literal> modifier.
<xref linkend="functions-formatting-datetimemod-table"> shows the
modifier patterns for date/time formatting.
</para>
<table id="functions-formatting-datetimemod-table">
- <title>Template pattern modifiers for date/time conversions</title>
+ <title>Template Pattern Modifiers for Date/Time Formatting</title>
<tgroup cols="3">
<thead>
<row>
</row>
<row>
<entry><literal>TH</literal> suffix</entry>
- <entry>add upper-case ordinal number suffix</entry>
+ <entry>upper-case ordinal number suffix</entry>
<entry><literal>DDTH</literal></entry>
</row>
<row>
<entry><literal>th</literal> suffix</entry>
- <entry>add lower-case ordinal number suffix</entry>
+ <entry>lower-case ordinal number suffix</entry>
<entry><literal>DDth</literal></entry>
</row>
<row>
<entry><literal>FX</literal> prefix</entry>
<entry>fixed format global option (see usage notes)</entry>
- <entry><literal>FX Month DD Day</literal></entry>
+ <entry><literal>FX Month DD Day</literal></entry>
</row>
<row>
<entry><literal>SP</literal> suffix</entry>
<function>to_timestamp</function> and <function>to_date</function>
skip multiple blank spaces in the input string if the <literal>FX</literal> option
is not used. <literal>FX</literal> must be specified as the first item
- in the template; for example
- <literal>to_timestamp('2000 JUN','YYYY MON')</literal> is right, but
- <literal>to_timestamp('2000 JUN','FXYYYY MON')</literal> returns an error,
- because <function>to_timestamp</function> expects one blank space only.
- </para>
- </listitem>
-
- <listitem>
- <para>
- If a backslash (<quote><literal>\</literal></quote>) is desired
- in a string constant, a double backslash
- (<quote><literal>\\</literal></quote>) must be entered; for
- example <literal>'\\HH\\MI\\SS'</literal>. This is true for
- any string constant in <productname>PostgreSQL</productname>.
+ in the template. For example
+ <literal>to_timestamp('2000 JUN', 'YYYY MON')</literal> is correct, but
+ <literal>to_timestamp('2000 JUN', 'FXYYYY MON')</literal> returns an error,
+ because <function>to_timestamp</function> expects one space only.
</para>
</listitem>
Ordinary text is allowed in <function>to_char</function>
templates and will be output literally. You can put a substring
in double quotes to force it to be interpreted as literal text
- even if it contains pattern keywords. For example, in
+ even if it contains pattern key words. For example, in
<literal>'"Hello Year "YYYY'</literal>, the <literal>YYYY</literal>
- will be replaced by the year data, but the single <literal>Y</literal> in <quote>Year</quote>
+ will be replaced by the year data, but the single <literal>Y</literal> in <literal>Year</literal>
will not be.
</para>
</listitem>
If you want to have a double quote in the output you must
precede it with a backslash, for example <literal>'\\"YYYY
Month\\"'</literal>. <!-- "" font-lock sanity :-) -->
+ (Two backslashes are necessary because the backslash already
+ has a special meaning in a string constant.)
</para>
</listitem>
<listitem>
<para>
- <literal>YYYY</literal> conversion from string to <type>timestamp</type> or
- <type>date</type> is restricted if you use a year with more than 4 digits. You must
+ The <literal>YYYY</literal> conversion from string to <type>timestamp</type> or
+ <type>date</type> has a restriction if you use a year with more than 4 digits. You must
use some non-digit character or template after <literal>YYYY</literal>,
otherwise the year is always interpreted as 4 digits. For example
- (with year 20000):
+ (with the year 20000):
<literal>to_date('200001131', 'YYYYMMDD')</literal> will be
- interpreted as a 4-digit year; better is to use a non-digit
+ interpreted as a 4-digit year; instead use a non-digit
separator after the year, like
<literal>to_date('20000-1131', 'YYYY-MMDD')</literal> or
<literal>to_date('20000Nov31', 'YYYYMonDD')</literal>.
<listitem>
<para>
- Millisecond <literal>MS</literal> and microsecond <literal>US</literal>
- values in a conversion from string to time stamp are used as part of the
+ Millisecond (<literal>MS</literal>) and microsecond (<literal>US</literal>)
+ values in a conversion from string to <type>timestamp</type> are used as part of the
seconds after the decimal point. For example
<literal>to_timestamp('12:3', 'SS:MS')</literal> is not 3 milliseconds,
- but 300, because the conversion counts it as 12 + 0.3.
+ but 300, because the conversion counts it as 12 + 0.3 seconds.
This means for the format <literal>SS:MS</literal>, the input values
<literal>12:3</literal>, <literal>12:30</literal>, and <literal>12:300</literal> specify the
same number of milliseconds. To get three milliseconds, one must use
<para>
Here is a more
complex example:
- <literal>to_timestamp('15:12:02.020.001230','HH:MI:SS.MS.US')</literal>
+ <literal>to_timestamp('15:12:02.020.001230', 'HH:MI:SS.MS.US')</literal>
is 15 hours, 12 minutes, and 2 seconds + 20 milliseconds +
1230 microseconds = 2.021230 seconds.
</para>
</para>
<table id="functions-formatting-numeric-table">
- <title>Template patterns for numeric conversions</title>
+ <title>Template Patterns for Numeric Formatting</title>
<tgroup cols="2">
<thead>
<row>
</row>
<row>
<entry><literal>S</literal></entry>
- <entry>negative value with minus sign (uses locale)</entry>
+ <entry>sign anchored to number (uses locale)</entry>
</row>
<row>
<entry><literal>L</literal></entry>
</row>
<row>
<entry><literal>TH</literal> or <literal>th</literal></entry>
- <entry>convert to ordinal number</entry>
+ <entry>ordinal number suffix</entry>
</row>
<row>
<entry><literal>V</literal></entry>
- <entry>shift <replaceable>n</replaceable> digits (see
- notes)</entry>
+ <entry>shift specified number of digits (see notes)</entry>
</row>
<row>
<entry><literal>EEEE</literal></entry>
<listitem>
<para>
A sign formatted using <literal>SG</literal>, <literal>PL</literal>, or
- <literal>MI</literal> is not an anchor in
+ <literal>MI</literal> is not anchored to
the number; for example,
- <literal>to_char(-12, 'S9999')</literal> produces <literal>' -12'</literal>,
- but <literal>to_char(-12, 'MI9999')</literal> produces <literal>'- 12'</literal>.
+ <literal>to_char(-12, 'S9999')</literal> produces <literal>' -12'</literal>,
+ but <literal>to_char(-12, 'MI9999')</literal> produces <literal>'- 12'</literal>.
The Oracle implementation does not allow the use of
<literal>MI</literal> ahead of <literal>9</literal>, but rather
requires that <literal>9</literal> precede
<listitem>
<para>
- <literal>9</literal> specifies a value with the same number of
+ <literal>9</literal> results in a value with the same number of
digits as there are <literal>9</literal>s. If a digit is
not available it outputs a space.
</para>
<listitem>
<para>
<literal>TH</literal> does not convert values less than zero
- and does not convert decimal numbers.
+ and does not convert fractional numbers.
</para>
</listitem>
<tgroup cols="2">
<thead>
<row>
- <entry>Input</entry>
- <entry>Output</entry>
+ <entry>Expression</entry>
+ <entry>Result</entry>
</row>
</thead>
<tbody>
<row>
- <entry><literal>to_char(now(),'Day, DD HH12:MI:SS')</literal></entry>
- <entry><literal>'Tuesday , 06 05:39:18'</literal></entry>
+ <entry><literal>to_char(current_timestamp, 'Day, DD HH12:MI:SS')</literal></entry>
+ <entry><literal>'Tuesday , 06 05:39:18'</literal></entry>
</row>
<row>
- <entry><literal>to_char(now(),'FMDay, FMDD HH12:MI:SS')</literal></entry>
- <entry><literal>'Tuesday, 6 05:39:18'</literal></entry>
+ <entry><literal>to_char(current_timestamp, 'FMDay, FMDD HH12:MI:SS')</literal></entry>
+ <entry><literal>'Tuesday, 6 05:39:18'</literal></entry>
</row>
<row>
- <entry><literal>to_char(-0.1,'99.99')</literal></entry>
- <entry><literal>' -.10'</literal></entry>
+ <entry><literal>to_char(-0.1, '99.99')</literal></entry>
+ <entry><literal>' -.10'</literal></entry>
</row>
<row>
- <entry><literal>to_char(-0.1,'FM9.99')</literal></entry>
+ <entry><literal>to_char(-0.1, 'FM9.99')</literal></entry>
<entry><literal>'-.1'</literal></entry>
</row>
<row>
- <entry><literal>to_char(0.1,'0.9')</literal></entry>
- <entry><literal>' 0.1'</literal></entry>
+ <entry><literal>to_char(0.1, '0.9')</literal></entry>
+ <entry><literal>' 0.1'</literal></entry>
</row>
<row>
- <entry><literal>to_char(12,'9990999.9')</literal></entry>
- <entry><literal>' 0012.0'</literal></entry>
+ <entry><literal>to_char(12, '9990999.9')</literal></entry>
+ <entry><literal>' 0012.0'</literal></entry>
</row>
<row>
- <entry><literal>to_char(12,'FM9990999.9')</literal></entry>
+ <entry><literal>to_char(12, 'FM9990999.9')</literal></entry>
<entry><literal>'0012'</literal></entry>
</row>
<row>
- <entry><literal>to_char(485,'999')</literal></entry>
- <entry><literal>' 485'</literal></entry>
+ <entry><literal>to_char(485, '999')</literal></entry>
+ <entry><literal>' 485'</literal></entry>
</row>
<row>
- <entry><literal>to_char(-485,'999')</literal></entry>
+ <entry><literal>to_char(-485, '999')</literal></entry>
<entry><literal>'-485'</literal></entry>
</row>
<row>
- <entry><literal>to_char(485,'9 9 9')</literal></entry>
- <entry><literal>' 4 8 5'</literal></entry>
+ <entry><literal>to_char(485, '9 9 9')</literal></entry>
+ <entry><literal>' 4 8 5'</literal></entry>
</row>
<row>
- <entry><literal>to_char(1485,'9,999')</literal></entry>
- <entry><literal>' 1,485'</literal></entry>
+ <entry><literal>to_char(1485, '9,999')</literal></entry>
+ <entry><literal>' 1,485'</literal></entry>
</row>
<row>
- <entry><literal>to_char(1485,'9G999')</literal></entry>
- <entry><literal>' 1 485'</literal></entry>
+ <entry><literal>to_char(1485, '9G999')</literal></entry>
+ <entry><literal>' 1 485'</literal></entry>
</row>
<row>
- <entry><literal>to_char(148.5,'999.999')</literal></entry>
+ <entry><literal>to_char(148.5, '999.999')</literal></entry>
<entry><literal>' 148.500'</literal></entry>
</row>
<row>
- <entry><literal>to_char(148.5,'999D999')</literal></entry>
- <entry><literal>' 148,500'</literal></entry>
+ <entry><literal>to_char(148.5, '999D999')</literal></entry>
+ <entry><literal>' 148,500'</literal></entry>
</row>
<row>
- <entry><literal>to_char(3148.5,'9G999D999')</literal></entry>
- <entry><literal>' 3 148,500'</literal></entry>
+ <entry><literal>to_char(3148.5, '9G999D999')</literal></entry>
+ <entry><literal>' 3 148,500'</literal></entry>
</row>
<row>
- <entry><literal>to_char(-485,'999S')</literal></entry>
+ <entry><literal>to_char(-485, '999S')</literal></entry>
<entry><literal>'485-'</literal></entry>
</row>
<row>
- <entry><literal>to_char(-485,'999MI')</literal></entry>
+ <entry><literal>to_char(-485, '999MI')</literal></entry>
<entry><literal>'485-'</literal></entry>
</row>
<row>
- <entry><literal>to_char(485,'999MI')</literal></entry>
+ <entry><literal>to_char(485, '999MI')</literal></entry>
<entry><literal>'485'</literal></entry>
</row>
<row>
- <entry><literal>to_char(485,'PL999')</literal></entry>
+ <entry><literal>to_char(485, 'PL999')</literal></entry>
<entry><literal>'+485'</literal></entry>
</row>
<row>
- <entry><literal>to_char(485,'SG999')</literal></entry>
+ <entry><literal>to_char(485, 'SG999')</literal></entry>
<entry><literal>'+485'</literal></entry>
</row>
<row>
- <entry><literal>to_char(-485,'SG999')</literal></entry>
+ <entry><literal>to_char(-485, 'SG999')</literal></entry>
<entry><literal>'-485'</literal></entry>
</row>
<row>
- <entry><literal>to_char(-485,'9SG99')</literal></entry>
+ <entry><literal>to_char(-485, '9SG99')</literal></entry>
<entry><literal>'4-85'</literal></entry>
</row>
<row>
- <entry><literal>to_char(-485,'999PR')</literal></entry>
+ <entry><literal>to_char(-485, '999PR')</literal></entry>
<entry><literal>'<485>'</literal></entry>
</row>
<row>
- <entry><literal>to_char(485,'L999')</literal></entry>
- <entry><literal>'DM 485</literal></entry>
+ <entry><literal>to_char(485, 'L999')</literal></entry>
+ <entry><literal>'DM 485</literal></entry>
</row>
<row>
- <entry><literal>to_char(485,'RN')</literal></entry>
- <entry><literal>' CDLXXXV'</literal></entry>
+ <entry><literal>to_char(485, 'RN')</literal></entry>
+ <entry><literal>' CDLXXXV'</literal></entry>
</row>
<row>
- <entry><literal>to_char(485,'FMRN')</literal></entry>
+ <entry><literal>to_char(485, 'FMRN')</literal></entry>
<entry><literal>'CDLXXXV'</literal></entry>
</row>
<row>
- <entry><literal>to_char(5.2,'FMRN')</literal></entry>
- <entry><literal>V</literal></entry>
+ <entry><literal>to_char(5.2, 'FMRN')</literal></entry>
+ <entry><literal>'V'</literal></entry>
</row>
<row>
- <entry><literal>to_char(482,'999th')</literal></entry>
- <entry><literal>' 482nd'</literal></entry>
+ <entry><literal>to_char(482, '999th')</literal></entry>
+ <entry><literal>' 482nd'</literal></entry>
</row>
<row>
- <entry><literal>to_char(485, '"Good number:"999')</literal></entry>
- <entry><literal>'Good number: 485'</literal></entry>
+ <entry><literal>to_char(485, '"Good number:"999')</literal></entry>
+ <entry><literal>'Good number: 485'</literal></entry>
</row>
<row>
- <entry><literal>to_char(485.8,'"Pre:"999" Post:" .999')</literal></entry>
- <entry><literal>'Pre: 485 Post: .800'</literal></entry>
+ <entry><literal>to_char(485.8, '"Pre:"999" Post:" .999')</literal></entry>
+ <entry><literal>'Pre: 485 Post: .800'</literal></entry>
</row>
<row>
- <entry><literal>to_char(12,'99V999')</literal></entry>
- <entry><literal>' 12000'</literal></entry>
+ <entry><literal>to_char(12, '99V999')</literal></entry>
+ <entry><literal>' 12000'</literal></entry>
</row>
<row>
- <entry><literal>to_char(12.4,'99V999')</literal></entry>
- <entry><literal>' 12400'</literal></entry>
+ <entry><literal>to_char(12.4, '99V999')</literal></entry>
+ <entry><literal>' 12400'</literal></entry>
</row>
<row>
<entry><literal>to_char(12.45, '99V9')</literal></entry>
- <entry><literal>' 125'</literal></entry>
+ <entry><literal>' 125'</literal></entry>
</row>
</tbody>
</tgroup>
the basic arithmetic operators (<literal>+</literal>,
<literal>*</literal>, etc.). For formatting functions, refer to
<xref linkend="functions-formatting">. You should be familiar with
- the background information on date/time data types (see <xref
- linkend="datatype-datetime">).
+ the background information on date/time data types from <xref
+ linkend="datatype-datetime">.
</para>
<para>
- All the functions and operators described below that take time or timestamp
- inputs actually come in two variants: one that takes time or timestamp
- with time zone, and one that takes time or timestamp without time zone.
+ All the functions and operators described below that take <type>time</type> or <type>timestamp</type>
+ inputs actually come in two variants: one that takes <type>time with time zone</type> or <type>timestamp
+ with time zone</type>, and one that takes <type>time without time zone</type> or <type>timestamp without time zone</type>.
For brevity, these variants are not shown separately.
</para>
<tgroup cols="3">
<thead>
<row>
- <entry>Name</entry>
+ <entry>Operator</entry>
<entry>Example</entry>
<entry>Result</entry>
</row>
<tgroup cols="5">
<thead>
<row>
- <entry>Name</entry>
+ <entry>Function</entry>
<entry>Return Type</entry>
<entry>Description</entry>
<entry>Example</entry>
<tbody>
<row>
- <entry><function>age</function>(<type>timestamp</type>)</entry>
+ <entry><literal><function>age</function>(<type>timestamp</type>)</literal></entry>
<entry><type>interval</type></entry>
<entry>Subtract from today</entry>
<entry><literal>age(timestamp '1957-06-13')</literal></entry>
</row>
<row>
- <entry><function>age</function>(<type>timestamp</type>, <type>timestamp</type>)</entry>
+ <entry><literal><function>age</function>(<type>timestamp</type>, <type>timestamp</type>)</literal></entry>
<entry><type>interval</type></entry>
<entry>Subtract arguments</entry>
<entry><literal>age('2001-04-10', timestamp '1957-06-13')</literal></entry>
</row>
<row>
- <entry><function>current_date</function></entry>
+ <entry><literal><function>current_date</function></literal></entry>
<entry><type>date</type></entry>
<entry>Today's date; see <xref linkend="functions-datetime-current">
</entry>
</row>
<row>
- <entry><function>current_time</function></entry>
+ <entry><literal><function>current_time</function></literal></entry>
<entry><type>time with time zone</type></entry>
<entry>Time of day; see <xref linkend="functions-datetime-current">
</entry>
</row>
<row>
- <entry><function>current_timestamp</function></entry>
+ <entry><literal><function>current_timestamp</function></literal></entry>
<entry><type>timestamp with time zone</type></entry>
<entry>Date and time; see <xref linkend="functions-datetime-current">
</entry>
</row>
<row>
- <entry><function>date_part</function>(<type>text</type>, <type>timestamp</type>)</entry>
+ <entry><literal><function>date_part</function>(<type>text</type>, <type>timestamp</type>)</literal></entry>
<entry><type>double precision</type></entry>
<entry>Get subfield (equivalent to
- <function>extract</function>); see also <link
- linkend="functions-datetime-datepart">below</link>
+ <function>extract</function>); see <xref linkend="functions-datetime-extract">
</entry>
<entry><literal>date_part('hour', timestamp '2001-02-16 20:38:40')</literal></entry>
<entry><literal>20</literal></entry>
</row>
<row>
- <entry><function>date_part</function>(<type>text</type>, <type>interval</type>)</entry>
+ <entry><literal><function>date_part</function>(<type>text</type>, <type>interval</type>)</literal></entry>
<entry><type>double precision</type></entry>
<entry>Get subfield (equivalent to
- <function>extract</function>); see also <link
- linkend="functions-datetime-datepart">below</link>
+ <function>extract</function>); see <xref linkend="functions-datetime-extract">
</entry>
<entry><literal>date_part('month', interval '2 years 3 months')</literal></entry>
<entry><literal>3</literal></entry>
</row>
<row>
- <entry><function>date_trunc</function>(<type>text</type>, <type>timestamp</type>)</entry>
+ <entry><literal><function>date_trunc</function>(<type>text</type>, <type>timestamp</type>)</literal></entry>
<entry><type>timestamp</type></entry>
<entry>Truncate to specified precision; see also <xref
linkend="functions-datetime-trunc">
</row>
<row>
- <entry><function>extract</function>(<parameter>field</parameter> from
- <type>timestamp</type>)</entry>
+ <entry><literal><function>extract</function>(<parameter>field</parameter> from
+ <type>timestamp</type>)</literal></entry>
<entry><type>double precision</type></entry>
- <entry>Get subfield; see also <xref
- linkend="functions-datetime-extract">
+ <entry>Get subfield; see <xref linkend="functions-datetime-extract">
</entry>
<entry><literal>extract(hour from timestamp '2001-02-16 20:38:40')</literal></entry>
<entry><literal>20</literal></entry>
</row>
<row>
- <entry><function>extract</function>(<parameter>field</parameter> from
- <type>interval</type>)</entry>
+ <entry><literal><function>extract</function>(<parameter>field</parameter> from
+ <type>interval</type>)</literal></entry>
<entry><type>double precision</type></entry>
- <entry>Get subfield; see also <xref
- linkend="functions-datetime-extract">
+ <entry>Get subfield; see <xref linkend="functions-datetime-extract">
</entry>
<entry><literal>extract(month from interval '2 years 3 months')</literal></entry>
<entry><literal>3</literal></entry>
</row>
<row>
- <entry><function>isfinite</function>(<type>timestamp</type>)</entry>
+ <entry><literal><function>isfinite</function>(<type>timestamp</type>)</literal></entry>
<entry><type>boolean</type></entry>
- <entry>Test for finite time stamp (neither invalid nor infinity)</entry>
+ <entry>Test for finite time stamp (not equal to infinity)</entry>
<entry><literal>isfinite(timestamp '2001-02-16 21:28:30')</literal></entry>
<entry><literal>true</literal></entry>
</row>
<row>
- <entry><function>isfinite</function>(<type>interval</type>)</entry>
+ <entry><literal><function>isfinite</function>(<type>interval</type>)</literal></entry>
<entry><type>boolean</type></entry>
<entry>Test for finite interval</entry>
<entry><literal>isfinite(interval '4 hours')</literal></entry>
</row>
<row>
- <entry><function>localtime</function></entry>
+ <entry><literal><function>localtime</function></literal></entry>
<entry><type>time</type></entry>
<entry>Time of day; see <xref linkend="functions-datetime-current">
</entry>
</row>
<row>
- <entry><function>localtimestamp</function></entry>
+ <entry><literal><function>localtimestamp</function></literal></entry>
<entry><type>timestamp</type></entry>
<entry>Date and time; see <xref linkend="functions-datetime-current">
</entry>
</row>
<row>
- <entry><function>now</function>()</entry>
+ <entry><literal><function>now</function>()</literal></entry>
<entry><type>timestamp with time zone</type></entry>
<entry>Current date and time (equivalent to
<function>current_timestamp</function>); see <xref
</row>
<row>
- <entry><function>timeofday()</function></entry>
+ <entry><literal><function>timeofday()</function></literal></entry>
<entry><type>text</type></entry>
<entry>Current date and time; see <xref
linkend="functions-datetime-current">
string that selects what field to extract from the source value.
The <function>extract</function> function returns values of type
<type>double precision</type>.
- The following are valid values:
+ The following are valid field names:
<!-- alphabetical -->
<variablelist>
<term><literal>timezone_hour</literal></term>
<listitem>
<para>
- The hour component of the time zone offset.
+ The hour component of the time zone offset
</para>
</listitem>
</varlistentry>
<term><literal>timezone_minute</literal></term>
<listitem>
<para>
- The minute component of the time zone offset.
+ The minute component of the time zone offset
</para>
</listitem>
</varlistentry>
<term><literal>week</literal></term>
<listitem>
<para>
- From a <type>timestamp</type> value, calculate the number of
+ The number of
the week of the year that the day is in. By definition
(<acronym>ISO</acronym> 8601), the first week of a year
- contains January 4 of that year. (The <acronym>ISO</acronym>
+ contains January 4 of that year. (The <acronym>ISO</acronym>-8601
week starts on Monday.) In other words, the first Thursday of
- a year is in week 1 of that year.
+ a year is in week 1 of that year. (for <type>timestamp</type> values only)
</para>
<screen>
display, see <xref linkend="functions-formatting">.
</para>
- <anchor id="functions-datetime-datepart">
<para>
The <function>date_part</function> function is modeled on the traditional
<productname>Ingres</productname> equivalent to the
date_part('<replaceable>field</replaceable>', <replaceable>source</replaceable>)
</synopsis>
Note that here the <replaceable>field</replaceable> parameter needs to
- be a string value, not a name. The valid field values for
+ be a string value, not a name. The valid field names for
<function>date_part</function> are the same as for
<function>extract</function>.
</para>
date_trunc('<replaceable>field</replaceable>', <replaceable>source</replaceable>)
</synopsis>
<replaceable>source</replaceable> is a value expression of type
- <type>timestamp</type> (values of type <type>date</type> and
- <type>time</type> are cast automatically).
+ <type>timestamp</type>. (Values of type <type>date</type> and
+ <type>time</type> are cast automatically.)
<replaceable>field</replaceable> selects to which precision to
truncate the time stamp value. The return value is of type
<type>timestamp</type> with all fields that are less than the
<para>
Valid values for <replaceable>field</replaceable> are:
<simplelist>
- <member>microseconds</member>
- <member>milliseconds</member>
- <member>second</member>
- <member>minute</member>
- <member>hour</member>
- <member>day</member>
- <member>month</member>
- <member>year</member>
- <member>decade</member>
- <member>century</member>
- <member>millennium</member>
+ <member><literal>microseconds</literal></member>
+ <member><literal>milliseconds</literal></member>
+ <member><literal>second</literal></member>
+ <member><literal>minute</literal></member>
+ <member><literal>hour</literal></member>
+ <member><literal>day</literal></member>
+ <member><literal>month</literal></member>
+ <member><literal>year</literal></member>
+ <member><literal>decade</literal></member>
+ <member><literal>century</literal></member>
+ <member><literal>millennium</literal></member>
</simplelist>
</para>
</sect2>
<sect2 id="functions-datetime-zoneconvert">
- <title><function>AT TIME ZONE</function></title>
+ <title><literal>AT TIME ZONE</literal></title>
<indexterm>
- <primary>timezone</primary>
+ <primary>time zone</primary>
<secondary>conversion</secondary>
</indexterm>
<para>
- The <function>AT TIME ZONE</function> construct allows conversions
- of timestamps to different timezones.
+ The <literal>AT TIME ZONE</literal> construct allows conversions
+ of time stamps to different time zones. <xref
+ linkend="functions-datetime-zoneconvert-table"> shows its
+ variants.
</para>
<table id="functions-datetime-zoneconvert-table">
- <title>AT TIME ZONE Variants</title>
+ <title><literal>AT TIME ZONE</literal> Variants</title>
<tgroup cols="3">
<thead>
<row>
<entry>Expression</entry>
- <entry>Returns</entry>
+ <entry>Return Type</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
-
<row>
<entry>
- <type>timestamp without time zone</type>
- <literal>AT TIME ZONE</literal>
- <replaceable>zone</>
+ <literal><type>timestamp without time zone</type> AT TIME ZONE <replaceable>zone</></literal>
</entry>
<entry><type>timestamp with time zone</type></entry>
- <entry>Convert local time in given timezone to UTC</entry>
+ <entry>Convert local time in given time zone to UTC</entry>
</row>
<row>
<entry>
- <type>timestamp with time zone</type>
- <literal>AT TIME ZONE</literal>
- <replaceable>zone</>
+ <literal><type>timestamp with time zone</type> AT TIME ZONE <replaceable>zone</></literal>
</entry>
<entry><type>timestamp without time zone</type></entry>
- <entry>Convert UTC to local time in given timezone</entry>
+ <entry>Convert UTC to local time in given time zone</entry>
</row>
<row>
<entry>
- <type>time with time zone</type>
- <literal>AT TIME ZONE</literal>
- <replaceable>zone</>
+ <literal><type>time with time zone</type> AT TIME ZONE <replaceable>zone</></literal>
</entry>
<entry><type>time with time zone</type></entry>
- <entry>Convert local time across timezones</entry>
+ <entry>Convert local time across time zones</entry>
</row>
-
</tbody>
</tgroup>
</table>
<para>
- In these expressions, the desired time <replaceable>zone</> can be
+ In these expressions, the desired time zone <replaceable>zone</> can be
specified either as a text string (e.g., <literal>'PST'</literal>)
or as an interval (e.g., <literal>INTERVAL '-08:00'</literal>).
</para>
<para>
- Examples (supposing that <varname>TimeZone</> is <literal>PST8PDT</>):
+ Examples (supposing that the local time zone is <literal>PST8PDT</>):
<screen>
SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'MST';
<lineannotation>Result: </lineannotation><computeroutput>2001-02-16 19:38:40-08</computeroutput>
SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'MST';
<lineannotation>Result: </lineannotation><computeroutput>2001-02-16 18:38:40</computeroutput>
</screen>
- The first example takes a zone-less timestamp and interprets it as MST time
- (GMT-7) to produce a UTC timestamp, which is then rotated to PST (GMT-8)
- for display. The second example takes a timestamp specified in EST
- (GMT-5) and converts it to local time in MST (GMT-7).
+ The first example takes a zone-less time stamp and interprets it as MST time
+ (UTC-7) to produce a UTC time stamp, which is then rotated to PST (UTC-8)
+ for display. The second example takes a time stamp specified in EST
+ (UTC-5) and converts it to local time in MST (UTC-7).
</para>
<para>
- The function <function>timezone</function>(<replaceable>zone</>,
- <replaceable>timestamp</>) is equivalent to the SQL-compliant construct
- <replaceable>timestamp</> <literal>AT TIME ZONE</literal>
- <replaceable>zone</>.
+ The function <literal><function>timezone</function>(<replaceable>zone</>,
+ <replaceable>timestamp</>)</literal> is equivalent to the SQL-conforming construct
+ <literal><replaceable>timestamp</> AT TIME ZONE
+ <replaceable>zone</></literal>.
</para>
</sect2>
<function>LOCALTIMESTAMP</function>
can optionally be given
a precision parameter, which causes the result to be rounded
- to that many fractional digits. Without a precision parameter,
+ to that many fractional digits in the seconds field. Without a precision parameter,
the result is given to the full available precision.
</para>
Some examples:
<screen>
SELECT CURRENT_TIME;
-<computeroutput>14:39:53.662522-05</computeroutput>
+<lineannotation>Result: </lineannotation><computeroutput>14:39:53.662522-05</computeroutput>
SELECT CURRENT_DATE;
-<computeroutput>2001-12-23</computeroutput>
+<lineannotation>Result: </lineannotation><computeroutput>2001-12-23</computeroutput>
SELECT CURRENT_TIMESTAMP;
-<computeroutput>2001-12-23 14:39:53.662522-05</computeroutput>
+<lineannotation>Result: </lineannotation><computeroutput>2001-12-23 14:39:53.662522-05</computeroutput>
SELECT CURRENT_TIMESTAMP(2);
-<computeroutput>2001-12-23 14:39:53.66-05</computeroutput>
+<lineannotation>Result: </lineannotation><computeroutput>2001-12-23 14:39:53.66-05</computeroutput>
SELECT LOCALTIMESTAMP;
-<computeroutput>2001-12-23 14:39:53.662522</computeroutput>
+<lineannotation>Result: </lineannotation><computeroutput>2001-12-23 14:39:53.662522</computeroutput>
</screen>
</para>
</para>
<para>
- There is also <function>timeofday()</function>, which for historical
+ There is also the function <function>timeofday()</function>, which for historical
reasons returns a text string rather than a <type>timestamp</type> value:
<screen>
SELECT timeofday();
- Sat Feb 17 19:07:32.000126 2001 EST
+<lineannotation>Result: </lineannotation><computeroutput>Sat Feb 17 19:07:32.000126 2001 EST</computeroutput>
</screen>
</para>
<para>
- It is important to realize that
+ It is important to know that
<function>CURRENT_TIMESTAMP</function> and related functions return
the start time of the current transaction; their values do not
change during the transaction. <function>timeofday()</function>
- returns the wall clock time and does advance during transactions.
+ returns the wall-clock time and does advance during transactions.
</para>
<note>
- <para>
- Many other database systems advance these values more
+ <para>
+ Other database systems may advance these values more
frequently.
</para>
</note>
<row>
<entry>Operator</entry>
<entry>Description</entry>
- <entry>Usage</entry>
+ <entry>Example</entry>
</row>
</thead>
<tbody>
<row>
- <entry> + </entry>
+ <entry> <literal>+</literal> </entry>
<entry>Translation</entry>
<entry><literal>box '((0,0),(1,1))' + point '(2.0,0)'</literal></entry>
</row>
<row>
- <entry> - </entry>
+ <entry> <literal>-</literal> </entry>
<entry>Translation</entry>
<entry><literal>box '((0,0),(1,1))' - point '(2.0,0)'</literal></entry>
</row>
<row>
- <entry> * </entry>
+ <entry> <literal>*</literal> </entry>
<entry>Scaling/rotation</entry>
<entry><literal>box '((0,0),(1,1))' * point '(2.0,0)'</literal></entry>
</row>
<row>
- <entry> / </entry>
+ <entry> <literal>/</literal> </entry>
<entry>Scaling/rotation</entry>
<entry><literal>box '((0,0),(2,2))' / point '(2.0,0)'</literal></entry>
</row>
<row>
- <entry> # </entry>
- <entry>Intersection</entry>
+ <entry> <literal>#</literal> </entry>
+ <entry>Point or box of intersection</entry>
<entry><literal>'((1,-1),(-1,1))' # '((1,1),(-1,-1))'</literal></entry>
</row>
<row>
- <entry> # </entry>
+ <entry> <literal>#</literal> </entry>
<entry>Number of points in path or polygon</entry>
<entry><literal># '((1,0),(0,1),(-1,0))'</literal></entry>
</row>
<row>
- <entry> @-@ </entry>
+ <entry> <literal>@-@</literal> </entry>
<entry>Length or circumference</entry>
<entry><literal>@-@ path '((0,0),(1,0))'</literal></entry>
</row>
<row>
- <entry> @@ </entry>
- <entry>Center of</entry>
+ <entry> <literal>@@</literal> </entry>
+ <entry>Center</entry>
<entry><literal>@@ circle '((0,0),10)'</literal></entry>
</row>
<row>
- <entry> ## </entry>
- <entry>Point of closest proximity</entry>
+ <entry> <literal>##</literal> </entry>
+ <entry>Closest point to first operand on second operand</entry>
<entry><literal>point '(0,0)' ## lseg '((2,0),(0,2))'</literal></entry>
</row>
<row>
- <entry> <-> </entry>
+ <entry> <literal><-></literal> </entry>
<entry>Distance between</entry>
<entry><literal>circle '((0,0),1)' <-> circle '((5,0),1)'</literal></entry>
</row>
<row>
- <entry> && </entry>
+ <entry> <literal>&&</literal> </entry>
<entry>Overlaps?</entry>
<entry><literal>box '((0,0),(1,1))' && box '((0,0),(2,2))'</literal></entry>
</row>
<row>
- <entry> &< </entry>
+ <entry> <literal>&<</literal> </entry>
<entry>Overlaps or is left of?</entry>
<entry><literal>box '((0,0),(1,1))' &< box '((0,0),(2,2))'</literal></entry>
</row>
<row>
- <entry> &> </entry>
+ <entry> <literal>&></literal> </entry>
<entry>Overlaps or is right of?</entry>
<entry><literal>box '((0,0),(3,3))' &> box '((0,0),(2,2))'</literal></entry>
</row>
<row>
- <entry> << </entry>
- <entry>Left of?</entry>
+ <entry> <literal><<</literal> </entry>
+ <entry>Is left of?</entry>
<entry><literal>circle '((0,0),1)' << circle '((5,0),1)'</literal></entry>
</row>
<row>
- <entry> >> </entry>
- <entry>Right of?</entry>
+ <entry> <literal>>></literal> </entry>
+ <entry>Is right of?</entry>
<entry><literal>circle '((5,0),1)' >> circle '((0,0),1)'</literal></entry>
</row>
<row>
- <entry> <^ </entry>
- <entry>Below?</entry>
+ <entry> <literal><^</literal> </entry>
+ <entry>Is below?</entry>
<entry><literal>circle '((0,0),1)' <^ circle '((0,5),1)'</literal></entry>
</row>
<row>
- <entry> >^ </entry>
- <entry>Above?</entry>
+ <entry> <literal>>^</literal> </entry>
+ <entry>Is above?</entry>
<entry><literal>circle '((0,5),1)' >^ circle '((0,0),1)'</literal></entry>
</row>
<row>
- <entry> ?# </entry>
- <entry>Intersect?</entry>
+ <entry> <literal>?#</literal> </entry>
+ <entry>Intersects?</entry>
<entry><literal>lseg '((-1,0),(1,0))' ?# box '((-2,-2),(2,2))'</literal></entry>
</row>
<row>
- <entry> ?- </entry>
- <entry>Horizontal?</entry>
+ <entry> <literal>?-</literal> </entry>
+ <entry>Is horizontal?</entry>
<entry><literal>?- lseg '((-1,0),(1,0))'</literal></entry>
</row>
<row>
- <entry> ?- </entry>
- <entry>Horizontally aligned?</entry>
+ <entry> <literal>?-</literal> </entry>
+ <entry>Are horizontally aligned?</entry>
<entry><literal>point '(1,0)' ?- point '(0,0)'</literal></entry>
</row>
<row>
- <entry> ?| </entry>
- <entry>Vertical?</entry>
+ <entry> <literal>?|</literal> </entry>
+ <entry>Is vertical?</entry>
<entry><literal>?| lseg '((-1,0),(1,0))'</literal></entry>
</row>
<row>
- <entry> ?| </entry>
- <entry>Vertically aligned?</entry>
+ <entry> <literal>?|</literal> </entry>
+ <entry>Are vertically aligned?</entry>
<entry><literal>point '(0,1)' ?| point '(0,0)'</literal></entry>
</row>
<row>
- <entry> ?-| </entry>
- <entry>Perpendicular?</entry>
+ <entry> <literal>?-|</literal> </entry>
+ <entry>Is perpendicular?</entry>
<entry><literal>lseg '((0,0),(0,1))' ?-| lseg '((0,0),(1,0))'</literal></entry>
</row>
<row>
- <entry> ?|| </entry>
- <entry>Parallel?</entry>
+ <entry> <literal>?||</literal> </entry>
+ <entry>Are parallel?</entry>
<entry><literal>lseg '((-1,0),(1,0))' ?|| lseg '((-1,2),(1,2))'</literal></entry>
</row>
<row>
- <entry> ~ </entry>
+ <entry> <literal>~</literal> </entry>
<entry>Contains?</entry>
<entry><literal>circle '((0,0),2)' ~ point '(1,1)'</literal></entry>
</row>
<row>
- <entry> @ </entry>
+ <entry> <literal>@</literal> </entry>
<entry>Contained in or on?</entry>
<entry><literal>point '(1,1)' @ circle '((0,0),2)'</literal></entry>
</row>
<row>
- <entry> ~= </entry>
+ <entry> <literal>~=</literal> </entry>
<entry>Same as?</entry>
<entry><literal>polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))'</literal></entry>
</row>
<thead>
<row>
<entry>Function</entry>
- <entry>Returns</entry>
+ <entry>Return Type</entry>
<entry>Description</entry>
<entry>Example</entry>
</row>
</thead>
<tbody>
<row>
- <entry><function>area</function>(object)</entry>
+ <entry><literal><function>area</function>(<replaceable>object</>)</literal></entry>
<entry><type>double precision</type></entry>
- <entry>area of item</entry>
+ <entry>area</entry>
<entry><literal>area(box '((0,0),(1,1))')</literal></entry>
</row>
<row>
- <entry><function>box</function>(box, box)</entry>
+ <entry><literal><function>box</function>(<type>box</>, <type>box</>)</literal></entry>
<entry><type>box</type></entry>
<entry>intersection box</entry>
<entry><literal>box(box '((0,0),(1,1))',box '((0.5,0.5),(2,2))')</literal></entry>
</row>
<row>
- <entry><function>center</function>(object)</entry>
+ <entry><literal><function>center</function>(<replaceable>object</>)</literal></entry>
<entry><type>point</type></entry>
- <entry>center of item</entry>
+ <entry>center</entry>
<entry><literal>center(box '((0,0),(1,2))')</literal></entry>
</row>
<row>
- <entry><function>diameter</function>(circle)</entry>
+ <entry><literal><function>diameter</function>(<type>circle</>)</literal></entry>
<entry><type>double precision</type></entry>
<entry>diameter of circle</entry>
<entry><literal>diameter(circle '((0,0),2.0)')</literal></entry>
</row>
<row>
- <entry><function>height</function>(box)</entry>
+ <entry><literal><function>height</function>(<type>box</>)</literal></entry>
<entry><type>double precision</type></entry>
<entry>vertical size of box</entry>
<entry><literal>height(box '((0,0),(1,1))')</literal></entry>
</row>
<row>
- <entry><function>isclosed</function>(path)</entry>
+ <entry><literal><function>isclosed</function>(<type>path</>)</literal></entry>
<entry><type>boolean</type></entry>
<entry>a closed path?</entry>
<entry><literal>isclosed(path '((0,0),(1,1),(2,0))')</literal></entry>
</row>
<row>
- <entry><function>isopen</function>(path)</entry>
+ <entry><literal><function>isopen</function>(<type>path</>)</literal></entry>
<entry><type>boolean</type></entry>
<entry>an open path?</entry>
<entry><literal>isopen(path '[(0,0),(1,1),(2,0)]')</literal></entry>
</row>
<row>
- <entry><function>length</function>(object)</entry>
+ <entry><literal><function>length</function>(<replaceable>object</>)</literal></entry>
<entry><type>double precision</type></entry>
- <entry>length of item</entry>
+ <entry>length</entry>
<entry><literal>length(path '((-1,0),(1,0))')</literal></entry>
</row>
<row>
- <entry><function>npoints</function>(path)</entry>
+ <entry><literal><function>npoints</function>(<type>path</>)</literal></entry>
<entry><type>integer</type></entry>
<entry>number of points</entry>
<entry><literal>npoints(path '[(0,0),(1,1),(2,0)]')</literal></entry>
</row>
<row>
- <entry><function>npoints</function>(polygon)</entry>
+ <entry><literal><function>npoints</function>(<type>polygon</>)</literal></entry>
<entry><type>integer</type></entry>
<entry>number of points</entry>
<entry><literal>npoints(polygon '((1,1),(0,0))')</literal></entry>
</row>
<row>
- <entry><function>pclose</function>(path)</entry>
+ <entry><literal><function>pclose</function>(<type>path</>)</literal></entry>
<entry><type>path</type></entry>
<entry>convert path to closed</entry>
<entry><literal>popen(path '[(0,0),(1,1),(2,0)]')</literal></entry>
<![IGNORE[
<!-- Not defined by this name. Implements the intersection operator '#' -->
<row>
- <entry><function>point</function>(lseg,lseg)</entry>
+ <entry><literal><function>point</function>(<type>lseg</>, <type>lseg</>)</literal></entry>
<entry><type>point</type></entry>
<entry>intersection</entry>
<entry><literal>point(lseg '((-1,0),(1,0))',lseg '((-2,-2),(2,2))')</literal></entry>
</row>
]]>
<row>
- <entry><function>popen</function>(path)</entry>
+ <entry><literal><function>popen</function>(<type>path</>)</literal></entry>
<entry><type>path</type></entry>
- <entry>convert path to open path</entry>
+ <entry>convert path to open</entry>
<entry><literal>popen(path '((0,0),(1,1),(2,0))')</literal></entry>
</row>
<row>
- <entry><function>radius</function>(circle)</entry>
+ <entry><literal><function>radius</function>(<type>circle</type>)</literal></entry>
<entry><type>double precision</type></entry>
<entry>radius of circle</entry>
<entry><literal>radius(circle '((0,0),2.0)')</literal></entry>
</row>
<row>
- <entry><function>width</function>(box)</entry>
+ <entry><literal><function>width</function>(<type>box</>)</literal></entry>
<entry><type>double precision</type></entry>
- <entry>horizontal size</entry>
+ <entry>horizontal size of box</entry>
<entry><literal>width(box '((0,0),(1,1))')</literal></entry>
</row>
</tbody>
<thead>
<row>
<entry>Function</entry>
- <entry>Returns</entry>
+ <entry>Return Type</entry>
<entry>Description</entry>
<entry>Example</entry>
</row>
</thead>
<tbody>
<row>
- <entry><function>box</function>(<type>circle</type>)</entry>
+ <entry><literal><function>box</function>(<type>circle</type>)</literal></entry>
<entry><type>box</type></entry>
<entry>circle to box</entry>
<entry><literal>box(circle '((0,0),2.0)')</literal></entry>
</row>
<row>
- <entry><function>box</function>(<type>point</type>, <type>point</type>)</entry>
+ <entry><literal><function>box</function>(<type>point</type>, <type>point</type>)</literal></entry>
<entry><type>box</type></entry>
<entry>points to box</entry>
<entry><literal>box(point '(0,0)', point '(1,1)')</literal></entry>
</row>
<row>
- <entry><function>box</function>(<type>polygon</type>)</entry>
+ <entry><literal><function>box</function>(<type>polygon</type>)</literal></entry>
<entry><type>box</type></entry>
<entry>polygon to box</entry>
<entry><literal>box(polygon '((0,0),(1,1),(2,0))')</literal></entry>
</row>
<row>
- <entry><function>circle</function>(<type>box</type>)</entry>
+ <entry><literal><function>circle</function>(<type>box</type>)</literal></entry>
<entry><type>circle</type></entry>
- <entry>to circle</entry>
+ <entry>box to circle</entry>
<entry><literal>circle(box '((0,0),(1,1))')</literal></entry>
</row>
<row>
- <entry><function>circle</function>(<type>point</type>, <type>double precision</type>)</entry>
+ <entry><literal><function>circle</function>(<type>point</type>, <type>double precision</type>)</literal></entry>
<entry><type>circle</type></entry>
- <entry>point to circle</entry>
+ <entry>point and radius to circle</entry>
<entry><literal>circle(point '(0,0)', 2.0)</literal></entry>
</row>
<row>
- <entry><function>lseg</function>(<type>box</type>)</entry>
+ <entry><literal><function>lseg</function>(<type>box</type>)</literal></entry>
<entry><type>lseg</type></entry>
- <entry>box diagonal to <type>lseg</type></entry>
+ <entry>box diagonal to line segment</entry>
<entry><literal>lseg(box '((-1,0),(1,0))')</literal></entry>
</row>
<row>
- <entry><function>lseg</function>(<type>point</type>, <type>point</type>)</entry>
+ <entry><literal><function>lseg</function>(<type>point</type>, <type>point</type>)</literal></entry>
<entry><type>lseg</type></entry>
- <entry>points to <type>lseg</type></entry>
+ <entry>points to line segment</entry>
<entry><literal>lseg(point '(-1,0)', point '(1,0)')</literal></entry>
</row>
<row>
- <entry><function>path</function>(<type>polygon</type>)</entry>
+ <entry><literal><function>path</function>(<type>polygon</type>)</literal></entry>
<entry><type>point</type></entry>
<entry>polygon to path</entry>
<entry><literal>path(polygon '((0,0),(1,1),(2,0))')</literal></entry>
</row>
<row>
- <entry><function>point</function>(<type>circle</type>)</entry>
+ <entry><literal><function>point</function>(<type>circle</type>)</literal></entry>
<entry><type>point</type></entry>
- <entry>center</entry>
+ <entry>center of circle</entry>
<entry><literal>point(circle '((0,0),2.0)')</literal></entry>
</row>
<row>
- <entry><function>point</function>(<type>lseg</type>, <type>lseg</type>)</entry>
+ <entry><literal><function>point</function>(<type>lseg</type>, <type>lseg</type>)</literal></entry>
<entry><type>point</type></entry>
<entry>intersection</entry>
<entry><literal>point(lseg '((-1,0),(1,0))', lseg '((-2,-2),(2,2))')</literal></entry>
</row>
<row>
- <entry><function>point</function>(<type>polygon</type>)</entry>
+ <entry><literal><function>point</function>(<type>polygon</type>)</literal></entry>
<entry><type>point</type></entry>
- <entry>center</entry>
+ <entry>center of polygon</entry>
<entry><literal>point(polygon '((0,0),(1,1),(2,0))')</literal></entry>
</row>
<row>
- <entry><function>polygon</function>(<type>box</type>)</entry>
+ <entry><literal><function>polygon</function>(<type>box</type>)</literal></entry>
<entry><type>polygon</type></entry>
- <entry>4-point polygon</entry>
+ <entry>box to 4-point polygon</entry>
<entry><literal>polygon(box '((0,0),(1,1))')</literal></entry>
</row>
<row>
- <entry><function>polygon</function>(<type>circle</type>)</entry>
+ <entry><literal><function>polygon</function>(<type>circle</type>)</literal></entry>
<entry><type>polygon</type></entry>
- <entry>12-point polygon</entry>
+ <entry>circle to 12-point polygon</entry>
<entry><literal>polygon(circle '((0,0),2.0)')</literal></entry>
</row>
<row>
- <entry><function>polygon</function>(<replaceable class="parameter">npts</replaceable>, <type>circle</type>)</entry>
+ <entry><literal><function>polygon</function>(<replaceable class="parameter">npts</replaceable>, <type>circle</type>)</literal></entry>
<entry><type>polygon</type></entry>
- <entry><replaceable class="parameter">npts</replaceable> polygon</entry>
+ <entry>circle to <replaceable class="parameter">npts</replaceable>-point polygon</entry>
<entry><literal>polygon(12, circle '((0,0),2.0)')</literal></entry>
</row>
<row>
- <entry><function>polygon</function>(<type>path</type>)</entry>
+ <entry><literal><function>polygon</function>(<type>path</type>)</literal></entry>
<entry><type>polygon</type></entry>
<entry>path to polygon</entry>
<entry><literal>polygon(path '((0,0),(1,1),(2,0))')</literal></entry>
<para>
It is possible to access the two component numbers of a <type>point</>
- as though it were an array with subscripts 0, 1. For example, if
+ as though it were an array with indices 0 and 1. For example, if
<literal>t.p</> is a <type>point</> column then
- <literal>SELECT p[0] FROM t</> retrieves the X coordinate;
+ <literal>SELECT p[0] FROM t</> retrieves the X coordinate and
<literal>UPDATE t SET p[1] = ...</> changes the Y coordinate.
- In the same way, a <type>box</> or an <type>lseg</> may be treated
- as an array of two <type>point</>s.
+ In the same way, a value of type <type>box</> or <type>lseg</> may be treated
+ as an array of two <type>point</> values.
</para>
</sect1>
<para>
<xref linkend="cidr-inet-operators-table"> shows the operators
- available for the <type>inet</type> and <type>cidr</type> types.
+ available for the <type>cidr</type> and <type>inet</type> types.
The operators <literal><<</literal>,
- <literal><<=</literal>, <literal>>></literal>,
- <literal>>>=</literal> test for subnet inclusion: they
+ <literal><<=</literal>, <literal>>></literal>, and
+ <literal>>>=</literal> test for subnet inclusion. They
consider only the network parts of the two addresses, ignoring any
host part, and determine whether one network part is identical to
or a subnet of the other.
</para>
- <table tocentry="1" id="cidr-inet-operators-table">
+ <table id="cidr-inet-operators-table">
<title><type>cidr</type> and <type>inet</type> Operators</title>
<tgroup cols="3">
<thead>
<row>
<entry>Operator</entry>
<entry>Description</entry>
- <entry>Usage</entry>
+ <entry>Example</entry>
</row>
</thead>
<tbody>
<row>
- <entry> < </entry>
- <entry>Less than</entry>
+ <entry> <literal><</literal> </entry>
+ <entry>is less than</entry>
<entry><literal>inet '192.168.1.5' < inet '192.168.1.6'</literal></entry>
</row>
<row>
- <entry> <= </entry>
- <entry>Less than or equal</entry>
+ <entry> <literal><=</literal> </entry>
+ <entry>is less than or equal</entry>
<entry><literal>inet '192.168.1.5' <= inet '192.168.1.5'</literal></entry>
</row>
<row>
- <entry> = </entry>
- <entry>Equals</entry>
+ <entry> <literal>=</literal> </entry>
+ <entry>equals</entry>
<entry><literal>inet '192.168.1.5' = inet '192.168.1.5'</literal></entry>
</row>
<row>
- <entry> >= </entry>
- <entry>Greater or equal</entry>
+ <entry> <literal>>=</literal> </entry>
+ <entry>is greater or equal</entry>
<entry><literal>inet '192.168.1.5' >= inet '192.168.1.5'</literal></entry>
</row>
<row>
- <entry> > </entry>
- <entry>Greater</entry>
+ <entry> <literal>></literal> </entry>
+ <entry>is greater than</entry>
<entry><literal>inet '192.168.1.5' > inet '192.168.1.4'</literal></entry>
</row>
<row>
- <entry> <> </entry>
- <entry>Not equal</entry>
+ <entry> <literal><></literal> </entry>
+ <entry>is not equal</entry>
<entry><literal>inet '192.168.1.5' <> inet '192.168.1.4'</literal></entry>
</row>
<row>
- <entry> << </entry>
+ <entry> <literal><<</literal> </entry>
<entry>is contained within</entry>
<entry><literal>inet '192.168.1.5' << inet '192.168.1/24'</literal></entry>
</row>
<row>
- <entry> <<= </entry>
+ <entry> <literal><<=</literal> </entry>
<entry>is contained within or equals</entry>
<entry><literal>inet '192.168.1/24' <<= inet '192.168.1/24'</literal></entry>
</row>
<row>
- <entry> >> </entry>
+ <entry> <literal>>></literal> </entry>
<entry>contains</entry>
<entry><literal>inet'192.168.1/24' >> inet '192.168.1.5'</literal></entry>
</row>
<row>
- <entry> >>= </entry>
+ <entry> <literal>>>=</literal> </entry>
<entry>contains or equals</entry>
<entry><literal>inet '192.168.1/24' >>= inet '192.168.1/24'</literal></entry>
</row>
<para>
<xref linkend="cidr-inet-functions-table"> shows the functions
- available for use with the <type>inet</type> and <type>cidr</type>
- types. The <function>host()</function>,
- <function>text()</function>, and <function>abbrev()</function>
+ available for use with the <type>cidr</type> and <type>inet</type>
+ types. The <function>host</function>,
+ <function>text</function>, and <function>abbrev</function>
functions are primarily intended to offer alternative display
- formats. You can cast a text field to inet using normal casting
- syntax: <literal>inet(expression)</literal> or
- <literal>colname::inet</literal>.
+ formats. You can cast a text value to <type>inet</> using normal casting
+ syntax: <literal>inet(<replaceable>expression</>)</literal> or
+ <literal><replaceable>colname</>::inet</literal>.
</para>
- <table tocentry="1" id="cidr-inet-functions-table">
+ <table id="cidr-inet-functions-table">
<title><type>cidr</type> and <type>inet</type> Functions</title>
<tgroup cols="5">
<thead>
<row>
<entry>Function</entry>
- <entry>Returns</entry>
+ <entry>Return Type</entry>
<entry>Description</entry>
<entry>Example</entry>
<entry>Result</entry>
</thead>
<tbody>
<row>
- <entry><function>broadcast</function>(<type>inet</type>)</entry>
+ <entry><literal><function>broadcast</function>(<type>inet</type>)</literal></entry>
<entry><type>inet</type></entry>
<entry>broadcast address for network</entry>
<entry><literal>broadcast('192.168.1.5/24')</literal></entry>
<entry><literal>192.168.1.255/24</literal></entry>
</row>
<row>
- <entry><function>host</function>(<type>inet</type>)</entry>
+ <entry><literal><function>host</function>(<type>inet</type>)</literal></entry>
<entry><type>text</type></entry>
<entry>extract IP address as text</entry>
<entry><literal>host('192.168.1.5/24')</literal></entry>
<entry><literal>192.168.1.5</literal></entry>
</row>
<row>
- <entry><function>masklen</function>(<type>inet</type>)</entry>
+ <entry><literal><function>masklen</function>(<type>inet</type>)</literal></entry>
<entry><type>integer</type></entry>
<entry>extract netmask length</entry>
<entry><literal>masklen('192.168.1.5/24')</literal></entry>
<entry><literal>24</literal></entry>
</row>
<row>
- <entry><function>set_masklen</function>(<type>inet</type>,<type>integer</type>)</entry>
+ <entry><literal><function>set_masklen</function>(<type>inet</type>,<type>integer</type>)</literal></entry>
<entry><type>inet</type></entry>
<entry>set netmask length for <type>inet</type> value</entry>
<entry><literal>set_masklen('192.168.1.5/24',16)</literal></entry>
<entry><literal>192.168.1.5/16</literal></entry>
</row>
<row>
- <entry><function>netmask</function>(<type>inet</type>)</entry>
+ <entry><literal><function>netmask</function>(<type>inet</type>)</literal></entry>
<entry><type>inet</type></entry>
<entry>construct netmask for network</entry>
<entry><literal>netmask('192.168.1.5/24')</literal></entry>
<entry><literal>255.255.255.0</literal></entry>
</row>
<row>
- <entry><function>network</function>(<type>inet</type>)</entry>
+ <entry><literal><function>network</function>(<type>inet</type>)</literal></entry>
<entry><type>cidr</type></entry>
<entry>extract network part of address</entry>
<entry><literal>network('192.168.1.5/24')</literal></entry>
<entry><literal>192.168.1.0/24</literal></entry>
</row>
<row>
- <entry><function>text</function>(<type>inet</type>)</entry>
+ <entry><literal><function>text</function>(<type>inet</type>)</literal></entry>
<entry><type>text</type></entry>
- <entry>extract IP address and masklen as text</entry>
+ <entry>extract IP address and netmask length as text</entry>
<entry><literal>text(inet '192.168.1.5')</literal></entry>
<entry><literal>192.168.1.5/32</literal></entry>
</row>
<row>
- <entry><function>abbrev</function>(<type>inet</type>)</entry>
+ <entry><literal><function>abbrev</function>(<type>inet</type>)</literal></entry>
<entry><type>text</type></entry>
- <entry>extract abbreviated display as text</entry>
+ <entry>abbreviated display format as text</entry>
<entry><literal>abbrev(cidr '10.1.0.0/16')</literal></entry>
<entry><literal>10.1/16</literal></entry>
</row>
<para>
<xref linkend="macaddr-functions-table"> shows the functions
- available for use with the <type>mac</type> type. The function
- <function>trunc</function>(<type>macaddr</type>) returns a MAC
- address with the last 3 bytes set to 0. This can be used to
+ available for use with the <type>macaddr</type> type. The function
+ <literal><function>trunc</function>(<type>macaddr</type>)</literal> returns a MAC
+ address with the last 3 bytes set to zero. This can be used to
associate the remaining prefix with a manufacturer. The directory
<filename>contrib/mac</filename> in the source distribution
contains some utilities to create and maintain such an association
table.
</para>
- <table tocentry="1" id="macaddr-functions-table">
+ <table id="macaddr-functions-table">
<title><type>macaddr</type> Functions</title>
<tgroup cols="5">
<thead>
<row>
<entry>Function</entry>
- <entry>Returns</entry>
+ <entry>Return Type</entry>
<entry>Description</entry>
<entry>Example</entry>
<entry>Result</entry>
</thead>
<tbody>
<row>
- <entry><function>trunc</function>(<type>macaddr</type>)</entry>
+ <entry><literal><function>trunc</function>(<type>macaddr</type>)</literal></entry>
<entry><type>macaddr</type></entry>
<entry>set last 3 bytes to zero</entry>
<entry><literal>trunc(macaddr '12:34:56:78:90:ab')</literal></entry>
<title>Sequence Functions</title>
<tgroup cols="3">
<thead>
- <row><entry>Function</entry> <entry>Returns</entry> <entry>Description</entry></row>
+ <row><entry>Function</entry> <entry>Return Type</entry> <entry>Description</entry></row>
</thead>
<tbody>
<row>
- <entry><function>nextval</function>(<type>text</type>)</entry>
+ <entry><literal><function>nextval</function>(<type>text</type>)</literal></entry>
<entry><type>bigint</type></entry>
<entry>Advance sequence and return new value</entry>
</row>
<row>
- <entry><function>currval</function>(<type>text</type>)</entry>
+ <entry><literal><function>currval</function>(<type>text</type>)</literal></entry>
<entry><type>bigint</type></entry>
<entry>Return value most recently obtained with <function>nextval</function></entry>
</row>
<row>
- <entry><function>setval</function>(<type>text</type>,<type>bigint</type>)</entry>
+ <entry><literal><function>setval</function>(<type>text</type>, <type>bigint</type>)</literal></entry>
<entry><type>bigint</type></entry>
<entry>Set sequence's current value</entry>
</row>
<row>
- <entry><function>setval</function>(<type>text</type>,<type>bigint</type>,<type>boolean</type>)</entry>
+ <entry><literal><function>setval</function>(<type>text</type>, <type>bigint</type>, <type>boolean</type>)</literal></entry>
<entry><type>bigint</type></entry>
<entry>Set sequence's current value and <literal>is_called</literal> flag</entry>
</row>
<function>nextval</function>. For example,
<screen>
-SELECT setval('foo', 42); <lineannotation>Next <function>nextval()</> will return 43</lineannotation>
+SELECT setval('foo', 42); <lineannotation>Next <function>nextval</> will return 43</lineannotation>
SELECT setval('foo', 42, true); <lineannotation>Same as above</lineannotation>
-SELECT setval('foo', 42, false); <lineannotation>Next <function>nextval()</> will return 42</lineannotation>
+SELECT setval('foo', 42, false); <lineannotation>Next <function>nextval</> will return 42</lineannotation>
</screen>
The result returned by <function>setval</function> is just the value of its
<para>
If a sequence object has been created with default parameters,
- <function>nextval()</function> calls on it will return successive values
- beginning with one. Other behaviors can be obtained by using
+ <function>nextval</function> calls on it will return successive values
+ beginning with 1. Other behaviors can be obtained by using
special parameters in the <command>CREATE SEQUENCE</command> command;
see its command reference page for more information.
</para>
</tip>
<sect2>
- <title>CASE</title>
+ <title><literal>CASE</></title>
+
+ <para>
+ The <acronym>SQL</acronym> <token>CASE</token> expression is a
+ generic conditional expression, similar to if/else statements in
+ other languages:
<synopsis>
CASE WHEN <replaceable>condition</replaceable> THEN <replaceable>result</replaceable>
END
</synopsis>
- <para>
- The <acronym>SQL</acronym> <token>CASE</token> expression is a
- generic conditional expression, similar to if/else statements in
- other languages. <token>CASE</token> clauses can be used wherever
+ <token>CASE</token> clauses can be used wherever
an expression is valid. <replaceable>condition</replaceable> is an
expression that returns a <type>boolean</type> result. If the result is true
- then the value of the <token>CASE</token> expression is
- <replaceable>result</replaceable>. If the result is false any
+ then the value of the <token>CASE</token> expression is the
+ <replaceable>result</replaceable> that follows the condition. If the result is false any
subsequent <token>WHEN</token> clauses are searched in the same
manner. If no <token>WHEN</token>
<replaceable>condition</replaceable> is true then the value of the
<para>
An example:
<screen>
-<prompt>=></prompt> <userinput>SELECT * FROM test;</userinput>
-<computeroutput>
+SELECT * FROM test;
+
a
---
1
2
3
-</computeroutput>
-
-<prompt>=></prompt> <userinput>SELECT a,
- CASE WHEN a=1 THEN 'one'
- WHEN a=2 THEN 'two'
- ELSE 'other'
- END
- FROM test;</userinput>
-<computeroutput>
+
+
+SELECT a,
+ CASE WHEN a=1 THEN 'one'
+ WHEN a=2 THEN 'two'
+ ELSE 'other'
+ END
+ FROM test;
+
a | case
---+-------
1 | one
2 | two
3 | other
-</computeroutput>
</screen>
</para>
<para>
The data types of all the <replaceable>result</replaceable>
- expressions must be coercible to a single output type.
+ expressions must be convertible to a single output type.
See <xref linkend="typeconv-union-case"> for more detail.
</para>
+ <para>
+ The following <quote>simple</quote> <token>CASE</token> expression is a
+ specialized variant of the general form above:
+
<synopsis>
CASE <replaceable>expression</replaceable>
WHEN <replaceable>value</replaceable> THEN <replaceable>result</replaceable>
END
</synopsis>
- <para>
- This <quote>simple</quote> <token>CASE</token> expression is a
- specialized variant of the general form above. The
+ The
<replaceable>expression</replaceable> is computed and compared to
- all the <replaceable>value</replaceable>s in the
+ all the <replaceable>value</replaceable> specifications in the
<token>WHEN</token> clauses until one is found that is equal. If
no match is found, the <replaceable>result</replaceable> in the
<token>ELSE</token> clause (or a null value) is returned. This is similar
The example above can be written using the simple
<token>CASE</token> syntax:
<screen>
-<prompt>=></prompt> <userinput>SELECT a,
- CASE a WHEN 1 THEN 'one'
- WHEN 2 THEN 'two'
- ELSE 'other'
- END
- FROM test;</userinput>
-<computeroutput>
+SELECT a,
+ CASE a WHEN 1 THEN 'one'
+ WHEN 2 THEN 'two'
+ ELSE 'other'
+ END
+ FROM test;
+
a | case
---+-------
1 | one
2 | two
3 | other
-</computeroutput>
</screen>
</para>
</sect2>
<sect2>
- <title>COALESCE</title>
+ <title><literal>COALESCE</></title>
<synopsis>
<function>COALESCE</function>(<replaceable>value</replaceable> <optional>, ...</optional>)
</sect2>
<sect2>
- <title>NULLIF</title>
+ <title><literal>NULLIF</></title>
<indexterm>
<primary>nullif</primary>
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 pg_catalog are included in the search
+ 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>
- <indexterm>
- <primary>search path</primary>
- <secondary>changing at runtime</secondary>
- </indexterm>
- The search path may be altered by a run-time setting. The
- command to use is <command>
- SET SEARCH_PATH '<varname>schema</varname>'[,'<varname>schema</varname>']...
- </command>
- </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>
<indexterm zone="functions-misc">
<primary>version</primary>
</para>
<table id="functions-misc-set-table">
- <title>Configuration Settings Information Functions</title>
+ <title>Configuration Settings Functions</title>
<tgroup cols="3">
<thead>
<row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry></row>
<tbody>
<row>
<entry>
- <function>current_setting</function>(<parameter>setting_name</parameter>)
+ <literal><function>current_setting</function>(<parameter>setting_name</parameter>)</literal>
</entry>
<entry><type>text</type></entry>
- <entry>value of current setting</entry>
+ <entry>current value of setting</entry>
</row>
<row>
<entry>
- <function>set_config(<parameter>setting_name</parameter>,
+ <literal><function>set_config(<parameter>setting_name</parameter>,
<parameter>new_value</parameter>,
- <parameter>is_local</parameter>)</function>
+ <parameter>is_local</parameter>)</function></literal>
</entry>
<entry><type>text</type></entry>
- <entry>new value of current setting</entry>
+ <entry>set parameter and return new value</entry>
</row>
</tbody>
</tgroup>
</table>
<indexterm zone="functions-misc">
- <primary>setting</primary>
- <secondary>current</secondary>
+ <primary>SET</primary>
+ </indexterm>
+
+ <indexterm zone="functions-misc">
+ <primary>SHOW</primary>
</indexterm>
<indexterm zone="functions-misc">
- <primary>setting</primary>
- <secondary>set</secondary>
+ <primary>configuration</primary>
+ <secondary>run time</secondary>
</indexterm>
<para>
- The <function>current_setting</function> is used to obtain the current
- value of the <parameter>setting_name</parameter> setting, as a query
- result. It is the equivalent to the <acronym>SQL</acronym>
- <command>SHOW</command> command.
- For example:
+ The function <function>current_setting</function> yields the
+ current value of the setting <parameter>setting_name</parameter>,
+ as part of a query result. It corresponds to the
+ <acronym>SQL</acronym> command <command>SHOW</command>. An
+ example:
<programlisting>
-select current_setting('DateStyle');
+SELECT current_setting('datestyle');
+
current_setting
---------------------------------------
ISO with US (NonEuropean) conventions
</para>
<para>
- <function>set_config</function> allows the <parameter>setting_name
- </parameter> setting to be changed to <parameter>new_value</parameter>.
- If <parameter>is_local</parameter> is set to <literal>true</literal>,
- the new value will only apply to the current transaction. If you want
+ <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. It is the equivalent to the
- <acronym>SQL</acronym> <command>SET</command> command. For example:
+ <literal>false</literal> instead. The function corresponds to the
+ SQL command <command>SET</command>. An example:
<programlisting>
-select set_config('show_statement_stats','off','f');
+SELECT set_config('show_statement_stats', 'off', false);
+
set_config
------------
off
<tbody>
<row>
- <entry><function>has_table_privilege</function>(<parameter>user</parameter>,
+ <entry><literal><function>has_table_privilege</function>(<parameter>user</parameter>,
<parameter>table</parameter>,
- <parameter>access</parameter>)
+ <parameter>privilege</parameter>)</literal>
</entry>
<entry><type>boolean</type></entry>
- <entry>does user have access to table</entry>
+ <entry>does user have privilege for table</entry>
</row>
<row>
- <entry><function>has_table_privilege</function>(<parameter>table</parameter>,
- <parameter>access</parameter>)
+ <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 access to table</entry>
+ <entry>does current user have privilege for table</entry>
</row>
<row>
- <entry><function>has_database_privilege</function>(<parameter>user</parameter>,
+ <entry><literal><function>has_database_privilege</function>(<parameter>user</parameter>,
<parameter>database</parameter>,
- <parameter>access</parameter>)
+ <parameter>privilege</parameter>)</literal>
</entry>
<entry><type>boolean</type></entry>
- <entry>does user have access to database</entry>
+ <entry>does user have privilege for database</entry>
</row>
<row>
- <entry><function>has_database_privilege</function>(<parameter>database</parameter>,
- <parameter>access</parameter>)
+ <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 access to database</entry>
+ <entry>does current user have privilege for database</entry>
</row>
<row>
- <entry><function>has_function_privilege</function>(<parameter>user</parameter>,
+ <entry><literal><function>has_function_privilege</function>(<parameter>user</parameter>,
<parameter>function</parameter>,
- <parameter>access</parameter>)
+ <parameter>privilege</parameter>)</literal>
</entry>
<entry><type>boolean</type></entry>
- <entry>does user have access to function</entry>
+ <entry>does user have privilege for function</entry>
</row>
<row>
- <entry><function>has_function_privilege</function>(<parameter>function</parameter>,
- <parameter>access</parameter>)
+ <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 access to function</entry>
+ <entry>does current user have privilege for function</entry>
</row>
<row>
- <entry><function>has_language_privilege</function>(<parameter>user</parameter>,
+ <entry><literal><function>has_language_privilege</function>(<parameter>user</parameter>,
<parameter>language</parameter>,
- <parameter>access</parameter>)
+ <parameter>privilege</parameter>)</literal>
</entry>
<entry><type>boolean</type></entry>
- <entry>does user have access to language</entry>
+ <entry>does user have privilege for language</entry>
</row>
<row>
- <entry><function>has_language_privilege</function>(<parameter>language</parameter>,
- <parameter>access</parameter>)
+ <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 access to language</entry>
+ <entry>does current user have privilege for language</entry>
</row>
<row>
- <entry><function>has_schema_privilege</function>(<parameter>user</parameter>,
+ <entry><literal><function>has_schema_privilege</function>(<parameter>user</parameter>,
<parameter>schema</parameter>,
- <parameter>access</parameter>)
+ <parameter>privilege</parameter>)</literal>
</entry>
<entry><type>boolean</type></entry>
- <entry>does user have access to schema</entry>
+ <entry>does user have privilege for schema</entry>
</row>
<row>
- <entry><function>has_schema_privilege</function>(<parameter>schema</parameter>,
- <parameter>access</parameter>)
+ <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 access to schema</entry>
+ <entry>does current user have privilege for schema</entry>
</row>
</tbody>
</tgroup>
<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
- (<classname>pg_user</classname>.<structfield>usesysid</structfield>), or if the argument is
+ (<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 type
+ 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
<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 type must evaluate to
+ The desired access privilege type must evaluate to
<literal>CREATE</literal>,
<literal>TEMPORARY</literal>, or
<literal>TEMP</literal> (which is equivalent to
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 type must currently evaluate to
+ The desired access privilege type must currently evaluate to
<literal>EXECUTE</literal>.
</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 type must currently evaluate to
+ The desired access privilege type must currently evaluate to
<literal>USAGE</literal>.
</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 type must evaluate to
+ The desired access privilege type must evaluate to
<literal>CREATE</literal> or
<literal>USAGE</literal>.
</para>
<tbody>
<row>
- <entry><function>pg_table_is_visible</function>(<parameter>tableOID</parameter>)
+ <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><function>pg_type_is_visible</function>(<parameter>typeOID</parameter>)
+ <entry><literal><function>pg_type_is_visible</function>(<parameter>type_oid</parameter>)</literal>
</entry>
<entry><type>boolean</type></entry>
<entry>is type visible in search path</entry>
</row>
<row>
- <entry><function>pg_function_is_visible</function>(<parameter>functionOID</parameter>)
+ <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><function>pg_operator_is_visible</function>(<parameter>operatorOID</parameter>)
+ <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><function>pg_opclass_is_visible</function>(<parameter>opclassOID</parameter>)
+ <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>
<para>
<xref linkend="functions-misc-catalog-table"> lists functions that
extract information from the system catalogs.
- <function>pg_get_viewdef()</function>,
- <function>pg_get_ruledef()</function>,
- <function>pg_get_indexdef()</function>, and
- <function>pg_get_constraintdef()</function> respectively
+ <function>pg_get_viewdef</function>,
+ <function>pg_get_ruledef</function>,
+ <function>pg_get_indexdef</function>, and
+ <function>pg_get_constraintdef</function> respectively
reconstruct the creating command for a view, rule, index, or
constraint. (Note that this is a decompiled reconstruction, not
the verbatim text of the command.) At present
- <function>pg_get_constraintdef()</function> only works for
- foreign-key constraints. <function>pg_get_userbyid()</function>
- extracts a user's name given a <structfield>usesysid</structfield>
- value.
+ <function>pg_get_constraintdef</function> only works for
+ foreign-key constraints. <function>pg_get_userbyid</function>
+ extracts a user's name given a user ID number.
</para>
<table id="functions-misc-catalog-table">
- <title>Catalog Information Functions</title>
+ <title>System Catalog Information Functions</title>
<tgroup cols="3">
<thead>
<row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry></row>
<tbody>
<row>
- <entry><function>pg_get_viewdef</function>(<parameter>viewname</parameter>)</entry>
+ <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>
+ <entry>get <command>CREATE VIEW</> command for view (<emphasis>deprecated</emphasis>)</entry>
</row>
<row>
- <entry><function>pg_get_viewdef</function>(<parameter>viewOID</parameter>)</entry>
+ <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>
+ <entry>get <command>CREATE VIEW</> command for view</entry>
</row>
<row>
- <entry><function>pg_get_ruledef</function>(<parameter>ruleOID</parameter>)</entry>
+ <entry><literal><function>pg_get_ruledef</function>(<parameter>rule_oid</parameter>)</literal></entry>
<entry><type>text</type></entry>
- <entry>Get <command>CREATE RULE</> command for rule</entry>
+ <entry>get <command>CREATE RULE</> command for rule</entry>
</row>
<row>
- <entry><function>pg_get_indexdef</function>(<parameter>indexOID</parameter>)</entry>
+ <entry><literal><function>pg_get_indexdef</function>(<parameter>index_oid</parameter>)</literal></entry>
<entry><type>text</type></entry>
- <entry>Get <command>CREATE INDEX</> command for index</entry>
+ <entry>get <command>CREATE INDEX</> command for index</entry>
</row>
<row>
- <entry><function>pg_get_constraintdef</function>(<parameter>constraintOID</parameter>)</entry>
+ <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>
+ <entry>get definition of a constraint</entry>
</row>
<row>
- <entry><function>pg_get_userbyid</function>(<parameter>userid</parameter>)</entry>
+ <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>
+ <entry>get user name with given ID</entry>
</row>
</tbody>
</tgroup>
The function 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 can be found matching the
+ null value is returned if no comment could be found matching the
specified parameters.
</para>
<tbody>
<row>
- <entry><function>obj_description</function>(<parameter>objectOID</parameter>, <parameter>tablename</parameter>)</entry>
+ <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>
+ <entry>get comment for a database object</entry>
</row>
<row>
- <entry><function>obj_description</function>(<parameter>objectOID</parameter>)</entry>
+ <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>
+ <entry>get comment for a database object (<emphasis>deprecated</emphasis>)</entry>
</row>
<row>
- <entry><function>col_description</function>(<parameter>tableOID</parameter>, <parameter>columnnumber</parameter>)</entry>
+ <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>
+ <entry>get comment for a table column</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
- The two-parameter form of <function>obj_description()</function> returns the
+ 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 one-parameter form of <function>obj_description</function> requires only
the object OID. It is now deprecated since there is no guarantee that
OIDs are unique across different system catalogs; therefore, the wrong
comment could be returned.
</para>
<para>
- <function>col_description()</function> returns the comment for a table column,
+ <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
+ <function>obj_description</function> cannot be used for table columns since
columns do not have OIDs of their own.
</para>
<para>
<firstterm>Aggregate functions</firstterm> compute a single result
value from a set of input values. <xref
- linkend="functions-aggregate-table"> show the built-in aggregate
+ 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 the &cite-tutorial; for additional introductory
<entry>
<type>smallint</type>, <type>integer</type>,
<type>bigint</type>, <type>real</type>, <type>double
- precision</type>, <type>numeric</type>, or <type>interval</type>.
+ precision</type>, <type>numeric</type>, or <type>interval</type>
</entry>
<entry>
<type>numeric</type> for any integer type argument,
<entry>
<type>smallint</type>, <type>integer</type>,
<type>bigint</type>, <type>real</type>, <type>double
- precision</type>, or <type>numeric</type>.
+ precision</type>, or <type>numeric</type>
</entry>
<entry>
<type>double precision</type> for floating-point arguments,
- otherwise <type>numeric</type>.
+ otherwise <type>numeric</type>
</entry>
<entry>sample standard deviation of the input values</entry>
</row>
<entry>
<type>smallint</type>, <type>integer</type>,
<type>bigint</type>, <type>real</type>, <type>double
- precision</type>, or <type>numeric</type>.
+ precision</type>, or <type>numeric</type>
</entry>
<entry>
<type>double precision</type> for floating-point arguments,
- otherwise <type>numeric</type>.
+ otherwise <type>numeric</type>
</entry>
<entry>sample variance of the input values (square of the sample standard deviation)</entry>
</row>
</para>
<sect2>
- <title>EXISTS</title>
+ <title><literal>EXISTS</literal></title>
<synopsis>
EXISTS ( <replaceable>subquery</replaceable> )
</sect2>
<sect2>
- <title>IN (scalar form)</title>
+ <title><literal>IN</literal> (scalar form)</title>
<synopsis>
<replaceable>expression</replaceable> IN (<replaceable>value</replaceable><optional>, ...</optional>)
OR
...
</synopsis>
+ </para>
+ <para>
Note that if the left-hand expression yields null, or if there are
no equal right-hand values and at least one right-hand expression yields
null, the result of the <token>IN</token> construct will be null, not false.
</sect2>
<sect2>
- <title>IN (subquery form)</title>
+ <title><literal>IN</literal> (subquery form)</title>
<synopsis>
<replaceable>expression</replaceable> IN (<replaceable>subquery</replaceable>)
</sect2>
<sect2>
- <title>NOT IN (scalar form)</title>
+ <title><literal>NOT IN</literal> (scalar form)</title>
<synopsis>
<replaceable>expression</replaceable> NOT IN (<replaceable>value</replaceable><optional>, ...</optional>)
AND
...
</synopsis>
+ </para>
+ <para>
Note that if the left-hand expression yields null, or if there are
no equal right-hand values and at least one right-hand expression yields
null, the result of the <token>NOT IN</token> construct will be null, not true
</sect2>
<sect2>
- <title>NOT IN (subquery form)</title>
+ <title><literal>NOT IN </literal>(subquery form)</title>
<synopsis>
<replaceable>expression</replaceable> NOT IN (<replaceable>subquery</replaceable>)
</sect2>
<sect2>
- <title>ANY/SOME</title>
+ <title><literal>ANY</literal>/<literal>SOME</literal></title>
<synopsis>
<replaceable>expression</replaceable> <replaceable>operator</replaceable> ANY (<replaceable>subquery</replaceable>)
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> queries.
+ 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
</sect2>
<sect2>
- <title>ALL</title>
+ <title><literal>ALL</literal></title>
<synopsis>
<replaceable>expression</replaceable> <replaceable>operator</replaceable> ALL (<replaceable>subquery</replaceable>)
be evaluated completely.
</para>
- <synopsis>
+<synopsis>
(<replaceable>expression</replaceable> <optional>, <replaceable>expression</replaceable> ...</optional>) <replaceable>operator</replaceable> ALL (<replaceable>subquery</replaceable>)
- </synopsis>
+</synopsis>
<para>
The right-hand side of this form of <token>ALL</token> is a parenthesized
<sect2>
<title>Row-wise Comparison</title>
- <synopsis>
+<synopsis>
(<replaceable>expression</replaceable> <optional>, <replaceable>expression</replaceable> ...</optional>) <replaceable>operator</replaceable> (<replaceable>subquery</replaceable>)
(<replaceable>expression</replaceable> <optional>, <replaceable>expression</replaceable> ...</optional>) <replaceable>operator</replaceable> (<replaceable>expression</replaceable> <optional>, <replaceable>expression</replaceable> ...</optional>)
- </synopsis>
+</synopsis>
<para>
The left-hand side is a list of scalar expressions. The right-hand side
-<!-- $Header: /cvsroot/pgsql/doc/src/sgml/indices.sgml,v 1.38 2002/11/11 20:14:03 petere Exp $ -->
+<!-- $Header: /cvsroot/pgsql/doc/src/sgml/indices.sgml,v 1.39 2003/03/13 01:30:28 petere Exp $ -->
<chapter id="indexes">
<title id="indexes-title">Indexes</title>
</para>
<para>
- Indexes can benefit <command>UPDATE</command>s and
- <command>DELETE</command>s with search conditions. Indexes can also be
+ Indexes can also benefit <command>UPDATE</command> and
+ <command>DELETE</command> commands with search conditions. Indexes can moreover be
used in join queries. Thus,
an index defined on a column that is part of a join condition can
significantly speed up queries with joins.
By
default, the <command>CREATE INDEX</command> command will create a
B-tree index, which fits the most common situations. In
- particular, the <productname>PostgreSQL</productname> query optimizer
+ particular, the <productname>PostgreSQL</productname> query planner
will consider using a B-tree index whenever an indexed column is
involved in a comparison using one of these operators:
<synopsis>
CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable> USING RTREE (<replaceable>column</replaceable>);
</synopsis>
- The <productname>PostgreSQL</productname> query optimizer will
+ The <productname>PostgreSQL</productname> query planner will
consider using an R-tree index whenever an indexed column is
involved in a comparison using one of these operators:
<primary>hash</primary>
<see>indexes</see>
</indexterm>
- The query optimizer will consider using a hash index whenever an
+ The query planner will consider using a hash index whenever an
indexed column is involved in a comparison using the
<literal>=</literal> operator. The following command is used to
create a hash index:
standard R-trees using Guttman's quadratic split algorithm. The
hash index is an implementation of Litwin's linear hashing. We
mention the algorithms used solely to indicate that all of these
- access methods are fully dynamic and do not have to be optimized
- periodically (as is the case with, for example, static hash access
- methods).
+ index methods are fully dynamic and do not have to be optimized
+ periodically (as is the case with, for example, static hash methods).
</para>
</sect1>
</para>
<para>
- The query optimizer can use a multicolumn index for queries that
- involve the first <parameter>n</parameter> consecutive columns in
- the index (when used with appropriate operators), up to the total
- number of columns specified in the index definition. For example,
+ The query planner can use a multicolumn index for queries that
+ involve the leftmost column in the index definition and any number
+ of columns listed to the right of it without a gap (when
+ used with appropriate operators). For example,
an index on <literal>(a, b, c)</literal> can be used in queries
involving all of <literal>a</literal>, <literal>b</literal>, and
<literal>c</literal>, or in queries involving both
<literal>a</literal> and <literal>b</literal>, or in queries
involving only <literal>a</literal>, but not in other combinations.
(In a query involving <literal>a</literal> and <literal>c</literal>
- the optimizer might choose to use the index for
+ the planner might choose to use the index for
<literal>a</literal> only and treat <literal>c</literal> like an
ordinary unindexed column.)
</para>
<para>
When an index is declared unique, multiple table rows with equal
- indexed values will not be allowed. NULL values are not considered
+ indexed values will not be allowed. Null values are not considered
equal.
</para>
SELECT * FROM test1 WHERE lower(col1) = 'value';
</programlisting>
This query can use an index, if one has been
- defined on the result of the <literal>lower(column)</literal>
+ defined on the result of the <literal>lower(col1)</literal>
operation:
<programlisting>
CREATE INDEX test1_lower_col1_idx ON test1 (lower(col1));
The function in the index definition can take more than one
argument, but they must be table columns, not constants.
Functional indexes are always single-column (namely, the function
- result) even if the function uses more than one input field; there
+ result) even if the function uses more than one input column; there
cannot be multicolumn indexes that contain function calls.
</para>
CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable> (<replaceable>column</replaceable> <replaceable>opclass</replaceable> <optional>, ...</optional>);
</synopsis>
The operator class identifies the operators to be used by the index
- for that column. For example, a B-tree index on four-byte integers
+ for that column. For example, a B-tree index on the type <type>int4</type>
would use the <literal>int4_ops</literal> class; this operator
- class includes comparison functions for four-byte integers. In
+ class includes comparison functions for values of type <type>int4</type>. In
practice the default operator class for the column's data type is
usually sufficient. The main point of having operator classes is
that for some data types, there could be more than one meaningful
ordering. For example, we might want to sort a complex-number data
type either by absolute value or by real part. We could do this by
defining two operator classes for the data type and then selecting
- the proper class when making an index. There are also some
- operator classes with special purposes:
+ the proper class when making an index.
+ </para>
+
+ <para>
+ There are also some built-in operator classes besides the default ones:
<itemizedlist>
<listitem>
<para>
The operator classes <literal>box_ops</literal> and
<literal>bigbox_ops</literal> both support R-tree indexes on the
- <literal>box</literal> data type. The difference between them is
+ <type>box</type> data type. The difference between them is
that <literal>bigbox_ops</literal> scales box coordinates down,
to avoid floating-point exceptions from doing multiplication,
addition, and subtraction on very large floating-point
coordinates. If the field on which your rectangles lie is about
- 20 000 units square or larger, you should use
+ 20 000 square units or larger, you should use
<literal>bigbox_ops</literal>.
</para>
</listitem>
<para>
The following query shows all defined operator classes:
- <programlisting>
-SELECT am.amname AS acc_method,
- opc.opcname AS ops_name
+<programlisting>
+SELECT am.amname AS index_method,
+ opc.opcname AS opclass_name
FROM pg_am am, pg_opclass opc
WHERE opc.opcamid = am.oid
- ORDER BY acc_method, ops_name;
- </programlisting>
+ ORDER BY index_method, opclass_name;
+</programlisting>
It can be extended to show all the operators included in each class:
- <programlisting>
-SELECT am.amname AS acc_method,
- opc.opcname AS ops_name,
- opr.oprname AS ops_comp
+<programlisting>
+SELECT am.amname AS index_method,
+ opc.opcname AS opclass_name,
+ opr.oprname AS opclass_operator
FROM pg_am am, pg_opclass opc, pg_amop amop, pg_operator opr
WHERE opc.opcamid = am.oid AND
amop.amopclaid = opc.oid AND
amop.amopopr = opr.oid
- ORDER BY acc_method, ops_name, ops_comp;
- </programlisting>
+ ORDER BY index_method, opclass_name, opclass_operator;
+</programlisting>
</para>
</sect1>
<para>
Suppose you are storing web server access logs in a database.
- Most accesses originate from the IP range of your organization but
+ Most accesses originate from the IP address range of your organization but
some are from elsewhere (say, employees on dial-up connections).
If your searches by IP are primarily for outside accesses,
you probably do not need to index the IP range that corresponds to your
predicate must match the conditions used in the queries that
are supposed to benefit from the index. To be precise, a partial
index can be used in a query only if the system can recognize that
- the query's WHERE condition mathematically <firstterm>implies</>
- the index's predicate.
+ the <literal>WHERE</> condition of the query mathematically implies
+ the predicate of the index.
<productname>PostgreSQL</productname> does not have a sophisticated
theorem prover that can recognize mathematically equivalent
- predicates that are written in different forms. (Not
+ expressions that are written in different forms. (Not
only is such a general theorem prover extremely difficult to
create, it would probably be too slow to be of any real use.)
The system can recognize simple inequality implications, for example
<quote>x < 1</quote> implies <quote>x < 2</quote>; otherwise
- the predicate condition must exactly match the query's WHERE condition
+ the predicate condition must exactly match the query's <literal>WHERE</> condition
or the index will not be recognized to be usable.
</para>
a given subject and target combination, but there might be any number of
<quote>unsuccessful</> entries. Here is one way to do it:
<programlisting>
-CREATE TABLE tests (subject text,
- target text,
- success bool,
- ...);
+CREATE TABLE tests (
+ subject text,
+ target text,
+ success boolean,
+ ...
+);
+
CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target)
WHERE success;
</programlisting>
This is a particularly efficient way of doing it when there are few
- successful trials and many unsuccessful ones.
+ successful tests and many unsuccessful ones.
</para>
</example>
-<!-- $Header: /cvsroot/pgsql/doc/src/sgml/installation.sgml,v 1.128 2003/01/19 00:13:28 momjian Exp $ -->
+<!-- $Header: /cvsroot/pgsql/doc/src/sgml/installation.sgml,v 1.129 2003/03/13 01:30:28 petere Exp $ -->
<chapter id="installation">
<title><![%standalone-include[<productname>PostgreSQL</>]]>
<acronym>GNU</> <application>make</> is often installed under
the name <filename>gmake</filename>; this document will always
refer to it by that name. (On some systems
- <acronym>GNU</acronym> make is the default tool with the name
+ <acronym>GNU</acronym> <application>make</> is the default tool with the name
<filename>make</>.) To test for <acronym>GNU</acronym>
<application>make</application> enter
<screen>
<listitem>
<para>
<application>gzip</> is needed to unpack the distribution in the
- first place. If you are reading this, you probably already got
- past that hurdle.
+ first place.<![%standalone-include;[ If you are reading this, you probably already got
+ past that hurdle.]]>
</para>
</listitem>
specify the <option>--without-readline</option> option for
<filename>configure</>. (On <productname>NetBSD</productname>,
the <filename>libedit</filename> library is
- <productname>readline</productname>-compatible and is used if
+ <productname>Readline</productname>-compatible and is used if
<filename>libreadline</filename> is not found.)
</para>
</listitem>
<systemitem class="osname">Solaris</>), for other systems you
can download an add-on package from here: <ulink
url="http://www.postgresql.org/~petere/gettext.html" ></ulink>.
- If you are using the <application>gettext</> implementation in
+ If you are using the <application>Gettext</> implementation in
the <acronym>GNU</acronym> C library then you will additionally
need the <productname>GNU Gettext</productname> package for some
utility programs. For any of the other implementations you will
</para>
<para>
- If you are build from a <acronym>CVS</acronym> tree instead of
+ If you are building from a <acronym>CVS</acronym> tree instead of
using a released source package, or if you want to do development,
you also need the following packages:
</screen>
Versions prior to 7.0 do not have this
<filename>postmaster.pid</> file. If you are using such a version
- you must find out the process id of the server yourself, for
+ you must find out the process ID of the server yourself, for
example by typing <userinput>ps ax | grep postmaster</>, and
supply it to the <command>kill</> command.
</para>
<para>
To use this option, you will need an implementation of the
- <application>gettext</> API; see above.
+ <application>Gettext</> API; see above.
</para>
</listitem>
</varlistentry>
<screen>
<userinput>gmake -C src/interfaces/python install</userinput>
</screen>
- If you do not have superuser access you are on your own:
+ If you do not have root access you are on your own:
you can still take the required files and place them in
other directories where Python can find them, but how to
do that is left as an exercise.
<para>
After the installation you can make room by removing the built
files from the source tree with the command <command>gmake
- clean</>. This will preserve the files made by the configure
+ clean</>. This will preserve the files made by the <command>configure</command>
program, so that you can rebuild everything with <command>gmake</>
later on. To reset the source tree to the state in which it was
distributed, use <command>gmake distclean</>. If you are going to
</formalpara>
<para>
- If you perform a build and then discover that your configure
- options were wrong, or if you change anything that configure
+ If you perform a build and then discover that your <command>configure</>
+ options were wrong, or if you change anything that <command>configure</>
investigates (for example, software upgrades), then it's a good
idea to do <command>gmake distclean</> before reconfiguring and
rebuilding. Without this, your changes in configuration choices
<para>
On <systemitem class="osname">Cygwin</systemitem>, put the library
directory in the <envar>PATH</envar> or move the
- <filename>.dll</filename> files into the <filename>bin/</filename>
+ <filename>.dll</filename> files into the <filename>bin</filename>
directory.
</para>
<seealso>man pages</seealso>
</indexterm>
To enable your system to find the <application>man</>
- documentation, you need to add a line like the following to a
+ documentation, you need to add lines like the following to a
shell start-up file unless you installed into a location that is
searched by default.
<programlisting>
<entry>7.3</entry>
<entry>2002-10-28,
10.20 Tom Lane (<email>tgl@sss.pgh.pa.us</email>),
- 11.00, 11.11, 32 & 64 bit, Giles Lean (<email>giles@nemeton.com.au</email>)</entry>
- <entry>gcc and cc; see also <filename>doc/FAQ_HPUX</filename></entry>
+ 11.00, 11.11, 32 and 64 bit, Giles Lean (<email>giles@nemeton.com.au</email>)</entry>
+ <entry><command>gcc</> and <command>cc</>; see also <filename>doc/FAQ_HPUX</filename></entry>
</row>
<row>
<entry><systemitem class="osname">IRIX</></entry>
<entry>7.3</entry>
<entry>2002-11-19,
Permaine Cheung <email>pcheung@redhat.com</email>)</entry>
- <entry>#undef HAS_TEST_AND_SET, remove slock_t typedef</entry>
+ <entry><literal>#undef HAS_TEST_AND_SET</>, remove <type>slock_t</> <literal>typedef</></entry>
</row>
<row>
<entry><systemitem class="osname">Linux</></entry>
<entry><systemitem>x86</></entry>
<entry>7.3.1</entry>
<entry>2002-12-11, Shibashish Satpathy (<email>shib@postmark.net</>)</entry>
- <entry>5.0.4, gcc; see also <filename>doc/FAQ_SCO</filename></entry>
+ <entry>5.0.4, <command>gcc</>; see also <filename>doc/FAQ_SCO</filename></entry>
</row>
<row>
<entry><systemitem class="osname">Solaris</></entry>
<entry>7.3</entry>
<entry>2002-10-28,
Andrew Sullivan (<email>andrew@libertyrms.info</email>)</entry>
- <entry>Solaris 7 & 8; see also <filename>doc/FAQ_Solaris</filename></entry>
+ <entry>Solaris 7 and 8; see also <filename>doc/FAQ_Solaris</filename></entry>
</row>
<row>
<entry><systemitem class="osname">Solaris</></entry>
<entry>7.2</entry>
<entry>2001-11-29,
Cyril Velter (<email>cyril.velter@libertysurf.fr</email>)</entry>
- <entry>needs updates to semaphore code</entry>
+ <entry>needs updates to semaphore code</entry>
</row>
<row>
<entry><systemitem class="osname">DG/UX 5.4R4.11</></entry>
</indexterm>
<indexterm zone="pgtcl">
- <primary>Tcl</primary>
+ <primary>pgtcl</primary>
</indexterm>
- <sect1 id="pgtcl-intro">
- <title>Introduction</title>
+ <indexterm zone="pgtcl">
+ <primary>Tcl</primary>
+ </indexterm>
<para>
<application>pgtcl</application> is a Tcl package for client
<application>libpq</application> available to Tcl scripts.
</para>
- <para>
- This package was originally written by Jolly Chen.
- </para>
+ <sect1 id="pgtcl-overview">
+ <title>Overview</title>
<para>
<xref linkend="pgtcl-commands-table"> gives an overview over the
</para>
-<TABLE TOCENTRY="1" id="pgtcl-commands-table">
-<TITLE><literal>pgtcl</literal> Commands</TITLE>
-<TGROUP COLS="2">
-<THEAD>
- <ROW>
- <ENTRY>Command</ENTRY>
- <ENTRY>Description</ENTRY>
- </ROW>
-</THEAD>
-<TBODY>
- <ROW>
- <ENTRY><function>pg_connect</function></ENTRY>
- <ENTRY>opens a connection to the backend server</ENTRY>
- </ROW>
- <ROW>
- <ENTRY><function>pg_disconnect</function></ENTRY>
- <ENTRY>closes a connection</ENTRY>
- </ROW>
- <ROW>
- <ENTRY><function>pg_conndefaults</function></ENTRY>
- <ENTRY>get connection options and their defaults</ENTRY>
- </ROW>
- <ROW>
- <ENTRY><function>pg_exec</function></ENTRY>
- <ENTRY>send a query to the backend</ENTRY>
- </ROW>
- <ROW>
- <ENTRY><function>pg_result</function></ENTRY>
- <ENTRY>manipulate the results of a query</ENTRY>
- </ROW>
- <ROW>
- <ENTRY><function>pg_select</function></ENTRY>
- <ENTRY>loop over the result of a SELECT statement</ENTRY>
- </ROW>
- <ROW>
- <ENTRY><function>pg_execute</function></ENTRY>
- <ENTRY>send a query and optionally loop over the results</ENTRY>
- </ROW>
- <ROW>
- <ENTRY><function>pg_listen</function></ENTRY>
- <ENTRY>establish a callback for NOTIFY messages</ENTRY>
- </ROW>
- <ROW>
- <ENTRY><function>pg_on_connection_loss</function></ENTRY>
- <ENTRY>establish a callback for unexpected connection loss</ENTRY>
- </ROW>
-
- <ROW>
- <ENTRY><function>pg_lo_creat</function></ENTRY>
- <ENTRY>create a large object</ENTRY>
- </ROW>
- <ROW>
- <ENTRY><function>pg_lo_open</function></ENTRY>
- <ENTRY>open a large object</ENTRY>
- </ROW>
- <ROW>
- <ENTRY><function>pg_lo_close</function></ENTRY>
- <ENTRY>close a large object</ENTRY>
- </ROW>
- <ROW>
- <ENTRY><function>pg_lo_read</function></ENTRY>
- <ENTRY>read a large object</ENTRY>
- </ROW>
- <ROW>
- <ENTRY><function>pg_lo_write</function></ENTRY>
- <ENTRY>write a large object</ENTRY>
- </ROW>
- <ROW>
- <ENTRY><function>pg_lo_lseek</function></ENTRY>
- <ENTRY>seek to a position in a large object</ENTRY>
- </ROW>
- <ROW>
- <ENTRY><function>pg_lo_tell</function></ENTRY>
- <ENTRY>return the current seek position of a large object</ENTRY>
- </ROW>
- <ROW>
- <ENTRY><function>pg_lo_unlink</function></ENTRY>
- <ENTRY>delete a large object</ENTRY>
- </ROW>
- <ROW>
- <ENTRY><function>pg_lo_import</function></ENTRY>
- <ENTRY>import a Unix file into a large object</ENTRY>
- </ROW>
- <ROW>
- <ENTRY><function>pg_lo_export</function></ENTRY>
- <ENTRY>export a large object into a Unix file</ENTRY>
- </ROW>
-</TBODY>
-</TGROUP>
-</TABLE>
+<table id="pgtcl-commands-table">
+<title><application>pgtcl</application> Commands</title>
+<tgroup cols="2">
+<thead>
+ <row>
+ <entry>Command</entry>
+ <entry>Description</entry>
+ </row>
+</thead>
+
+<tbody>
+ <row>
+ <entry><function>pg_connect</function></entry>
+ <entry>open a connection to the server</entry>
+ </row>
+ <row>
+ <entry><function>pg_disconnect</function></entry>
+ <entry>close a connection to the server</entry>
+ </row>
+ <row>
+ <entry><function>pg_conndefaults</function></entry>
+ <entry>get connection options and their defaults</entry>
+ </row>
+ <row>
+ <entry><function>pg_exec</function></entry>
+ <entry>send a command to the server</entry>
+ </row>
+ <row>
+ <entry><function>pg_result</function></entry>
+ <entry>get information about a command result</entry>
+ </row>
+ <row>
+ <entry><function>pg_select</function></entry>
+ <entry>loop over the result of a query</entry>
+ </row>
+ <row>
+ <entry><function>pg_execute</function></entry>
+ <entry>send a query and optionally loop over the results</entry>
+ </row>
+ <row>
+ <entry><function>pg_listen</function></entry>
+ <entry>set or change a callback for asynchronous notification messages</entry>
+ </row>
+ <row>
+ <entry><function>pg_on_connection_loss</function></entry>
+ <entry>set or change a callback for unexpected connection loss</entry>
+ </row>
+
+ <row>
+ <entry><function>pg_lo_creat</function></entry>
+ <entry>create a large object</entry>
+ </row>
+ <row>
+ <entry><function>pg_lo_open</function></entry>
+ <entry>open a large object</entry>
+ </row>
+ <row>
+ <entry><function>pg_lo_close</function></entry>
+ <entry>close a large object</entry>
+ </row>
+ <row>
+ <entry><function>pg_lo_read</function></entry>
+ <entry>read from a large object</entry>
+ </row>
+ <row>
+ <entry><function>pg_lo_write</function></entry>
+ <entry>write to a large object</entry>
+ </row>
+ <row>
+ <entry><function>pg_lo_lseek</function></entry>
+ <entry>seek to a position in a large object</entry>
+ </row>
+ <row>
+ <entry><function>pg_lo_tell</function></entry>
+ <entry>return the current seek position of a large object</entry>
+ </row>
+ <row>
+ <entry><function>pg_lo_unlink</function></entry>
+ <entry>delete a large object</entry>
+ </row>
+ <row>
+ <entry><function>pg_lo_import</function></entry>
+ <entry>import a large object from a file</entry>
+ </row>
+ <row>
+ <entry><function>pg_lo_export</function></entry>
+ <entry>export a large object to a file</entry>
+ </row>
+</tbody>
+</tgroup>
+</table>
<para>
- The <function>pg_lo_*</function> routines are interfaces to the
- large object features of <ProductName>PostgreSQL</ProductName>.
- The functions are designed to mimic the analogous file system
- functions in the standard Unix file system interface. The
- <function>pg_lo_*</function> routines should be used within a
+ The <function>pg_lo_*</function> commands are interfaces to the
+ large object features of
+ <ProductName>PostgreSQL</ProductName>.<indexterm><primary>Large
+ Object</></> The functions are designed to mimic the analogous file
+ system functions in the standard Unix file system interface. The
+ <function>pg_lo_*</function> commands should be used within a
<command>BEGIN</command>/<command>COMMIT</command> transaction
- block because the file descriptor returned by
+ block because the descriptor returned by
<function>pg_lo_open</function> is only valid for the current
transaction. <function>pg_lo_import</function> and
<function>pg_lo_export</function> <emphasis>must</emphasis> be used
block.
</para>
- <para>
- <xref linkend="pgtcl-example"> shows a small example of how to use
- the routines.
- </para>
-
- <example id="pgtcl-example">
- <title><application>pgtcl</application> Example Program</title>
-
-<programlisting>
-# getDBs :
-# get the names of all the databases at a given host and port number
-# with the defaults being the localhost and port 5432
-# return them in alphabetical order
-proc getDBs { {host "localhost"} {port "5432"} } {
- # datnames is the list to be result
- set conn [pg_connect template1 -host $host -port $port]
- set res [pg_exec $conn "SELECT datname FROM pg_database ORDER BY datname"]
- set ntups [pg_result $res -numTuples]
- for {set i 0} {$i < $ntups} {incr i} {
- lappend datnames [pg_result $res -getTuple $i]
- }
- pg_result $res -clear
- pg_disconnect $conn
- return $datnames
-}
-</programlisting>
- </example>
</sect1>
-<Sect1 id="libpgtcl-loading">
-<Title>Loading <application>pgtcl</application> into your application</Title>
+<sect1 id="libpgtcl-loading">
+<title>Loading <application>pgtcl</application> into an Application</title>
<para>
Before using <application>pgtcl</application> commands, you must load
- <filename>libpgtcl</> into your Tcl application. This is normally
+ the <filename>libpgtcl</> library into your Tcl application. This is normally
done with the Tcl <literal>load</> command. Here is an example:
<programlisting>
linking. See the source code for <application>pgtclsh</> for an example.
</para>
-</Sect1>
-
-<Sect1 id="libpgtcl-ref">
-<Title><application>pgtcl</application> Command Reference Information</Title>
-
-<REFENTRY ID="PGTCL-PGCONNECT">
-<REFMETA>
-<REFENTRYTITLE>pg_connect</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Connection Management</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_connect
-</REFNAME>
-<REFPURPOSE>open a connection to the backend server
-</REFPURPOSE>
-<INDEXTERM ID="IX-PGTCL-PGCONNECT-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>connecting</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGCONNECT-2"><PRIMARY>pg_connect</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>1997-12-24</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
-pg_connect -conninfo <REPLACEABLE CLASS="PARAMETER">connectOptions</REPLACEABLE>
-pg_connect <REPLACEABLE CLASS="PARAMETER">dbName</REPLACEABLE> <OPTIONAL>-host <REPLACEABLE CLASS="PARAMETER">hostName</REPLACEABLE></OPTIONAL>
- <OPTIONAL>-port <REPLACEABLE
- CLASS="PARAMETER">portNumber</REPLACEABLE></OPTIONAL> <OPTIONAL>-tty <REPLACEABLE
- CLASS="PARAMETER">pqtty</REPLACEABLE></OPTIONAL>
- <OPTIONAL>-options <REPLACEABLE
- CLASS="PARAMETER">optionalBackendArgs</REPLACEABLE></OPTIONAL>
-</SYNOPSIS>
-
-<REFSECT2 ID="R2-PGTCL-PGCONNECT-1">
-<REFSECT2INFO>
-<DATE>1998-10-07</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs (new style)
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">connectOptions</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>A string of connection options, each written in the form keyword = value.
-A list of valid options can be found in <filename>libpq</>'s
-<function>PQconnectdb()</> manual entry.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGCONNECT-2">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs (old style)
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">dbName</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid database name.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <OPTIONAL>-host <REPLACEABLE CLASS="PARAMETER">hostName</REPLACEABLE></OPTIONAL>
-</TERM>
-<LISTITEM>
-<PARA>Specifies the domain name of the backend server for <REPLACEABLE CLASS="PARAMETER">dbName</REPLACEABLE>.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <OPTIONAL>-port <REPLACEABLE CLASS="PARAMETER">portNumber</REPLACEABLE></OPTIONAL>
-</TERM>
-<LISTITEM>
-<PARA>Specifies the IP port number of the backend server for <REPLACEABLE CLASS="PARAMETER">dbName</REPLACEABLE>.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <OPTIONAL>-tty <REPLACEABLE CLASS="PARAMETER">pqtty</REPLACEABLE></OPTIONAL>
-</TERM>
-<LISTITEM>
-<PARA>Specifies file or <acronym>tty</acronym> for optional debug output from backend.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <OPTIONAL>-options <REPLACEABLE CLASS="PARAMETER">optionalBackendArgs</REPLACEABLE></OPTIONAL>
-</TERM>
-<LISTITEM>
-<PARA>Specifies options for the backend server for <REPLACEABLE CLASS="PARAMETER">dbName</REPLACEABLE>.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGCONNECT-3">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">dbHandle</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>
-If successful, a handle for a database connection is returned.
-Handles start with the prefix <literal>pgsql</literal>.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-</REFSYNOPSISDIV>
-
-<!-- ********************************************************** -->
-
-<REFSECT1 ID="R1-PGTCL-PGCONNECT-1">
-<REFSECT1INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-<PARA><FUNCTION>pg_connect</FUNCTION> opens a connection to the
-<ProductName>PostgreSQL</ProductName> backend.
-</Para>
-
-<para>
-Two syntaxes are available. In the older one, each possible option
-has a separate option switch in the pg_connect statement. In the
-newer form, a single option string is supplied that can contain
-multiple option values. See <FUNCTION>pg_conndefaults</FUNCTION>
-for info about the available options in the newer syntax.
-</PARA>
-</REFSECT1>
-<REFSECT1 ID="R1-PGTCL-PGCONNECT-2">
-<TITLE>Usage
-</TITLE>
-<comment>
- XXX thomas 1997-12-24
-</comment>
-</REFSECT1>
-</REFENTRY>
-
-<REFENTRY ID="PGTCL-PGDISCONNECT">
-<REFMETA>
-<REFENTRYTITLE>pg_disconnect</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Connection Management</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_disconnect
-</REFNAME>
-<REFPURPOSE>close a connection to the backend server
-</REFPURPOSE>
-<INDEXTERM ID="IX-PGTCL-PGDISCONNECT-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>connecting</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGDISCONNECT-2"><PRIMARY>pg_connect</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>1997-12-24</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
-pg_disconnect <REPLACEABLE CLASS="PARAMETER">dbHandle</REPLACEABLE>
-</SYNOPSIS>
-
-<REFSECT2 ID="R2-PGTCL-PGDISCONNECT-1">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">dbHandle</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid database handle.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGDISCONNECT-2">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- None
-</TERM>
-<LISTITEM>
-<PARA>
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-</REFSYNOPSISDIV>
-
-<REFSECT1 ID="R1-PGTCL-PGDISCONNECT-1">
-<REFSECT1INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-<PARA><FUNCTION>pg_disconnect</FUNCTION> closes a connection to the <ProductName>PostgreSQL</ProductName> backend.
-</PARA>
-</REFSECT1>
-
-</REFENTRY>
-
-
-
-
-<REFENTRY ID="PGTCL-PGCONNDEFAULTS">
-<REFMETA>
-<REFENTRYTITLE>pg_conndefaults</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Connection Management</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_conndefaults
-</REFNAME>
-<REFPURPOSE>obtain information about default connection parameters
-</REFPURPOSE>
-<INDEXTERM ID="IX-PGTCL-PGCONNDEFAULTS-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>connecting</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGCONNDEFAULTS-2"><PRIMARY>pg_conndefaults</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>1998-10-07</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
+</sect1>
+
+<sect1 id="libpgtcl-ref">
+<title><application>pgtcl</application> Command Reference</title>
+
+<refentry ID="PGTCL-PGCONNECT">
+ <refmeta>
+ <refentrytitle>pg_connect</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_connect</refname>
+ <refpurpose>open a connection to the server</refpurpose>
+ <indexterm ID="IX-PGTCL-PGCONNECT-2"><primary>pg_connect</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+pg_connect -conninfo <parameter>connectOptions</parameter>
+pg_connect <parameter>dbName</parameter> <optional>-host <parameter>hostName</parameter></optional> <optional>-port <parameter>portNumber</parameter></optional> <optional>-tty <parameter>tty</parameter</optional> <optional>-options <parameter>serverOptions</parameter></optional>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_connect</function> opens a connection to the
+ <ProductName>PostgreSQL</ProductName> server.
+ </para>
+
+ <para>
+ Two syntaxes are available. In the older one, each possible option
+ has a separate option switch in the <command>pg_connect</command>
+ command. In the newer form, a single option string is supplied
+ that can contain multiple option values.
+ <function>pg_conndefaults</function> can be used to retrieve
+ information about the available options in the newer syntax.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <title>New style</title>
+
+ <varlistentry>
+ <term><parameter>connectOptions</parameter></term>
+ <listitem>
+ <para>
+ A string of connection options, each written in the form
+ <literal>keyword = value</>. A list of valid options can be
+ found in the description of the <application>libpq</> function
+ <function>PQconnectdb</>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <variablelist>
+ <title>Old style</title>
+
+ <varlistentry>
+ <term><parameter>dbName</parameter></term>
+ <listitem>
+ <para>
+ The name of the database to connect to.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-host <parameter>hostName</parameter></option></term>
+ <listitem>
+ <para>
+ The host name of the database server to connect to.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-port <parameter>portNumber</parameter></option></term>
+ <listitem>
+ <para>
+ The TCP port number of the database server to connect to.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-tty <parameter>tty</parameter></option></term>
+ <listitem>
+ <para>
+ A file or <acronym>TTY</acronym> for optional debug output from
+ the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-options <parameter>serverOptions</parameter></option></term>
+ <listitem>
+ <para>
+ Additional configuration options to pass to the server.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ If successful, a handle for a database connection is returned.
+ Handles start with the prefix <literal>pgsql</literal>.
+ </para>
+ </refsect1>
+</refentry>
+
+
+<refentry ID="PGTCL-PGDISCONNECT">
+ <refmeta>
+ <refentrytitle>pg_disconnect</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_disconnect</refname>
+ <refpurpose>close a connection to the server</refpurpose>
+ <indexterm ID="IX-PGTCL-PGDISCONNECT-2"><primary>pg_disconnect</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+pg_disconnect <parameter>conn</parameter>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_disconnect</function> closes a connection to the
+ <productname>PostgreSQL</productname> server.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>conn</parameter></term>
+ <listitem>
+ <para>
+ The handle of the connection to be closed.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ None
+ </para>
+ </refsect1>
+</refentry>
+
+
+<refentry ID="PGTCL-PGCONNDEFAULTS">
+ <refmeta>
+ <refentrytitle>pg_conndefaults</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_conndefaults</refname>
+ <refpurpose>get connection options and their defaults</refpurpose>
+ <indexterm ID="IX-PGTCL-PGCONNDEFAULTS-2"><primary>pg_conndefaults</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
pg_conndefaults
-</SYNOPSIS>
-
-<REFSECT2 ID="R2-PGTCL-PGCONNDEFAULTS-1">
-<REFSECT2INFO>
-<DATE>1998-10-07</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs
-</TITLE>
-<PARA>
-None.
-</PARA>
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGCONNDEFAULTS-2">
-<REFSECT2INFO>
-<DATE>1998-10-07</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">option list</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>
-The result is a list describing the possible connection options and their
-current default values.
-Each entry in the list is a sublist of the format:
-</Para>
-<screen>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_conndefaults</function> returns information about the
+ connection options available in <function>pg_connect
+ -conninfo</function> and the current default value for each option.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <para>
+ None
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ The result is a list describing the possible connection options and
+ their current default values. Each entry in the list is a sublist
+ of the format:
+<synopsis>
{optname label dispchar dispsize value}
-</screen>
-<Para>
-where the <replaceable>optname</> is usable as an option in
-<FUNCTION>pg_connect -conninfo</FUNCTION>.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-</REFSYNOPSISDIV>
-
-<REFSECT1 ID="R1-PGTCL-PGCONNDEFAULTS-1">
-<REFSECT1INFO>
-<DATE>1998-10-07</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-
-<para>
-<FUNCTION>pg_conndefaults</FUNCTION> returns info about the connection
-options available in <FUNCTION>pg_connect -conninfo</FUNCTION> and the
-current default value for each option.
-</PARA>
-</REFSECT1>
-<REFSECT1 ID="R1-PGTCL-PGCONNDEFAULTS-2">
-<TITLE>Usage
-</TITLE>
-<PARA><literal>pg_conndefaults</>
-</PARA>
-</REFSECT1>
-</REFENTRY>
-
-<REFENTRY ID="PGTCL-PGEXEC">
-<REFMETA>
-<REFENTRYTITLE>pg_exec</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Query Processing</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_exec
-</REFNAME>
-<REFPURPOSE>
-send a command string to the server
-</REFPURPOSE>
-<INDEXTERM ID="IX-PGTCL-PGEXEC-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>connecting</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGEXEC-2"><PRIMARY>pg_connect</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>1997-12-24</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
-pg_exec <REPLACEABLE CLASS="PARAMETER">dbHandle</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">queryString</REPLACEABLE>
-</SYNOPSIS>
-
-<!-- ********************************************************** -->
-
-<REFSECT2 ID="R2-PGTCL-PGEXEC-1">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">dbHandle</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid database handle.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">queryString</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid SQL query.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGEXEC-2">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">resultHandle</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>
-A Tcl error will be returned if <application>pgtcl</application> was unable to obtain a backend
-response. Otherwise, a query result object is created and a handle for
-it is returned. This handle can be passed to <FUNCTION>pg_result</FUNCTION>
-to obtain the results of the query.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2></REFSYNOPSISDIV>
-
-<REFSECT1 ID="R1-PGTCL-PGEXEC-1">
-<REFSECT1INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-<PARA>
-<FUNCTION>pg_exec</FUNCTION> submits a query to the <ProductName>PostgreSQL</ProductName> backend and returns a result.
-
-Query result handles start with the connection handle and add a period
-and a result number.
-</Para>
-
-<PARA>
-Note that lack of a Tcl error is not proof that the query succeeded!
-An error message returned by the backend will be processed
-as a query result with failure status, not by generating a Tcl error
-in pg_exec.
-</PARA>
-</REFSECT1>
+</synopsis>
+ where the <replaceable>optname</> is usable as an option in
+ <function>pg_connect -conninfo</function>.
+ </para>
+ </refsect1>
</refentry>
-<REFENTRY ID="PGTCL-PGRESULT">
-<REFMETA>
-<REFENTRYTITLE>pg_result</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Query Processing</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_result
-</REFNAME>
-<REFPURPOSE>
-get information about a query result
-</REFPURPOSE>
-<INDEXTERM ID="IX-PGTCL-PGRESULT-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>connecting</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGRESULT-2"><PRIMARY>pg_connect</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>1997-12-24</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
-pg_result <REPLACEABLE CLASS="PARAMETER">resultHandle</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">resultOption</REPLACEABLE>
-</SYNOPSIS>
-<REFSECT2 ID="R2-PGTCL-PGRESULT-1">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">resultHandle</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>
- The handle for a query result.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">resultOption</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>
-Specifies one of several possible options.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-
-<REFSECT3>
-<TITLE>Options</TITLE>
-
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
-<option>-status</option>
-</TERM>
-<LISTITEM>
-<PARA>
-the status of the result.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
-<option>-error</option>
-</TERM>
-<LISTITEM>
-<PARA>
-the error message, if the status indicates error; otherwise an empty string.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
-<option>-conn</option>
-</TERM>
-<LISTITEM>
-<PARA>
-the connection that produced the result.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
-<option>-oid</option>
-</TERM>
-<LISTITEM>
-<PARA>
-if the command was an INSERT, the OID of the
-inserted tuple; otherwise 0.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
-<option>-numTuples</option>
-</TERM>
-<LISTITEM>
-<PARA>
-the number of tuples returned by the query.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
-<option>-cmdTuples</option>
-</TERM>
-<LISTITEM>
-<PARA>
-the number of tuples affected by the query.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
-<option>-numAttrs</option>
-</TERM>
-<LISTITEM>
-<PARA>
-the number of attributes in each tuple.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
-<option>-assign arrayName</option>
-</TERM>
-<LISTITEM>
-<PARA>
-assign the results to an array, using subscripts of the form
-<literal>(tupno,attributeName)</literal>.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
-<option>-assignbyidx arrayName ?appendstr?</option>
-</TERM>
-<LISTITEM>
-<PARA>
-assign the results to an array using the first attribute's value and
-the remaining attributes' names as keys. If <parameter>appendstr</> is given then
-it is appended to each key. In short, all but the first field of each
-tuple are stored into the array, using subscripts of the form
-<literal>(firstFieldValue,fieldNameAppendStr)</literal>.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
-<option>-getTuple tupleNumber</option>
-</TERM>
-<LISTITEM>
-<PARA>
-returns the fields of the indicated tuple in a list. Tuple numbers
-start at zero.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
-<option>-tupleArray tupleNumber arrayName</option>
-</TERM>
-<LISTITEM>
-<PARA>
-stores the fields of the tuple in array <parameter>arrayName</parameter>, indexed by field names.
-Tuple numbers start at zero.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
-<option>-attributes</option>
-</TERM>
-<LISTITEM>
-<PARA>
-returns a list of the names of the tuple attributes.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
-<option>-lAttributes</option>
-</TERM>
-<LISTITEM>
-<PARA>
-returns a list of sublists, <literal>{name ftype fsize}</literal> for each tuple attribute.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
-<option>-clear</option>
-</TERM>
-<LISTITEM>
-<PARA>
-clear the result query object.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT3>
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGRESULT-2">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<PARA>
-The result depends on the selected option, as described above.
-</PARA>
-</REFSECT2></REFSYNOPSISDIV>
-
-<REFSECT1 ID="R1-PGTCL-PGRESULT-1">
-<REFSECT1INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-<PARA>
-<FUNCTION>pg_result</FUNCTION> returns information about a query result
-created by a prior <FUNCTION>pg_exec</FUNCTION>.
-</Para>
-
-<para>
-You can keep a query result around for as long as you need it, but when
-you are done with it, be sure to free it by
-executing <FUNCTION>pg_result -clear</FUNCTION>. Otherwise, you have
-a memory leak, and <application>Pgtcl</> will eventually start complaining that you've
-created too many query result objects.
-</PARA>
-</REFSECT1>
-</REFENTRY>
-
-<!-- ********************************************************** -->
-
-<REFENTRY ID="PGTCL-PGSELECT">
-<REFMETA>
-<REFENTRYTITLE>pg_select</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Query Processing</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_select
-</REFNAME>
-<REFPURPOSE>
-loop over the result of a SELECT statement
-</REFPURPOSE>
-<INDEXTERM ID="IX-PGTCL-PGSELECT-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>connecting</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGSELECT-2"><PRIMARY>pg_connect</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>1997-12-24</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
-pg_select <REPLACEABLE CLASS="PARAMETER">dbHandle</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">queryString</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">arrayVar</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">queryProcedure</REPLACEABLE>
-</SYNOPSIS>
-
-<REFSECT2 ID="R2-PGTCL-PGSELECT-1">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">dbHandle</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid database handle.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">queryString</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid SQL select query.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">arrayVar</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Array variable for tuples returned.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">queryProcedure</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Procedure run on each tuple found.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGSELECT-2">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<Para>
-None.
-</Para>
-</REFSECT2></REFSYNOPSISDIV>
-
-<REFSECT1 ID="R1-PGTCL-PGSELECT-1">
-<REFSECT1INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-<PARA>
-<FUNCTION>pg_select</FUNCTION> submits a SELECT query to the
-<ProductName>PostgreSQL</ProductName> backend, and executes a
-given chunk of code for each tuple in the result.
- The <REPLACEABLE CLASS="PARAMETER">queryString</REPLACEABLE>
- must be a SELECT statement. Anything else returns an error.
- The <REPLACEABLE CLASS="PARAMETER">arrayVar</REPLACEABLE>
- variable is an array name used in the loop. For each tuple,
- <REPLACEABLE CLASS="PARAMETER">arrayVar</REPLACEABLE> is filled in
- with the tuple field values, using the field names as the array
- indexes. Then the
- <REPLACEABLE CLASS="PARAMETER">queryProcedure</REPLACEABLE>
- is executed.
-</PARA>
-
-<PARA>
- In addition to the field values, the following special entries are
-made in the array:
-
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM><literal>.headers</></TERM>
-<LISTITEM>
-<PARA>A list of the column names returned by the SELECT.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM><literal>.numcols</></TERM>
-<LISTITEM>
-<PARA>The number of columns returned by the SELECT.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM><literal>.tupno</></TERM>
-<LISTITEM>
-<PARA>The current tuple number, starting at zero and incrementing
-for each iteration of the loop body.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</PARA>
-
-</REFSECT1>
-
-<REFSECT1 ID="R1-PGTCL-PGSELECT-2">
-<TITLE>Usage
-</TITLE>
-<PARA>
-This would work if table <classname>table</> has fields <structfield>control</> and <structfield>name</>
-(and, perhaps, other fields):
-<ProgramListing>
- pg_select $pgconn "SELECT * FROM table" array {
- puts [format "%5d %s" $array(control) $array(name)]
- }
-</ProgramListing>
-</PARA>
-</REFSECT1>
-
-</REFENTRY>
-
-<!-- ********************************************************** -->
-
-<REFENTRY ID="PGTCL-PGEXECUTE">
-<REFMETA>
-<REFENTRYTITLE>pg_execute</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Query Processing</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_execute
-</REFNAME>
-<REFPURPOSE>
-send a query and optionally loop over the results
-</REFPURPOSE>
-<INDEXTERM ID="IX-PGTCL-PGEXECUTE-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>query</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGEXECUTE-2"><PRIMARY>pg_execute</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>2002-03-06</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
-pg_execute <OPTIONAL>-array <REPLACEABLE CLASS="PARAMETER">arrayVar</REPLACEABLE></OPTIONAL> <OPTIONAL>-oid <REPLACEABLE CLASS="PARAMETER">oidVar</REPLACEABLE></OPTIONAL> <REPLACEABLE CLASS="PARAMETER">dbHandle</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">queryString</REPLACEABLE> <OPTIONAL><REPLACEABLE CLASS="PARAMETER">queryProcedure</REPLACEABLE></OPTIONAL>
-</SYNOPSIS>
-
-<REFSECT2 ID="R2-PGTCL-PGEXECUTE-1">
-<REFSECT2INFO>
-<DATE>2002-03-06</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <OPTIONAL>-array <REPLACEABLE CLASS="PARAMETER">arrayVar</REPLACEABLE></OPTIONAL>
-</TERM>
-<LISTITEM>
-<PARA>Specifies the name of an array variable where result tuples are stored,
-indexed by the field names.
-This is ignored if <replaceable class=parameter>queryString</> is not a SELECT statement. For SELECT
-statements, if this option is not used, result tuples values are stored
-in individual variables named according to the field names in the result.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <OPTIONAL>-oid <REPLACEABLE CLASS="PARAMETER">oidVar</REPLACEABLE></OPTIONAL>
-</TERM>
-<LISTITEM>
-<PARA>Specifies the name of a variable into which the OID from an INSERT
-statement will be stored.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">dbHandle</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid database handle.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">queryString</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid SQL query.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <OPTIONAL><REPLACEABLE CLASS="PARAMETER">queryProcedure</REPLACEABLE></OPTIONAL>
-</TERM>
-<LISTITEM>
-<PARA>Optional command to execute for each result tuple of a SELECT statement.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGEXECUTE-2">
-<REFSECT2INFO>
-<DATE>2002-03-06</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">ntuples</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>
-The number of tuples affected or returned by the query.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2></REFSYNOPSISDIV>
-
-<REFSECT1 ID="R1-PGTCL-PGEXECUTE-1">
-<REFSECT1INFO>
-<DATE>2002-03-06</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-<PARA>
-<FUNCTION>pg_execute</FUNCTION> submits a query to the
-<PRODUCTNAME>PostgreSQL</> backend.
-</PARA>
-<PARA>
-If the query is not a SELECT statement, the query is executed and the
-number of tuples affected by the query is returned. If the query is an
-INSERT and a single tuple is inserted, the OID of the inserted tuple is
-stored in the <replaceable>oidVar</> variable if the optional <PARAMETER>-oid</PARAMETER>
-argument is supplied.
-</PARA>
-<PARA>
-If the query is a SELECT statement, the query is executed. For each tuple
-in the result, the tuple field values are stored in the
-<PARAMETER>arrayVar</PARAMETER> variable,
-if supplied, using the field names as the array indexes, else in variables
-named by the field names, and then the optional
-<PARAMETER>queryProcedure</PARAMETER> is executed if supplied.
-(Omitting the <PARAMETER>queryProcedure</PARAMETER> probably makes sense
-only if the query will return a single tuple.)
-The number of tuples selected is returned.
-</PARA>
-<PARA>
-The <PARAMETER>queryProcedure</PARAMETER> can use the Tcl
-<LITERAL>break</LITERAL>, <LITERAL>continue</LITERAL>, and
-<LITERAL>return</LITERAL> commands, with the expected behavior.
-Note that if the <PARAMETER>queryProcedure</PARAMETER> executes
-<LITERAL>return</LITERAL>, <FUNCTION>pg_execute</FUNCTION> does
-not return <PARAMETER>ntuples</PARAMETER>.
-</PARA>
-<PARA>
-<FUNCTION>pg_execute</FUNCTION> is a newer function which provides a
-superset of the features of <FUNCTION>pg_select</FUNCTION>, and can
-replace <FUNCTION>pg_exec</FUNCTION> in many cases where access to
-the result handle is not needed.
-</PARA>
-<PARA>
-For backend-handled errors, <FUNCTION>pg_execute</FUNCTION> will
-throw a Tcl error and return two element list. The first element
-is an error code such as <LITERAL>PGRES_FATAL_ERROR</LITERAL>, and
-the second element is the backend error text. For more serious
-errors, such as failure to communicate with the backend,
-<FUNCTION>pg_execute</FUNCTION> will throw a Tcl error and return
-just the error message text.
-</PARA>
-
-</REFSECT1>
-
-<REFSECT1 ID="R1-PGTCL-PGEXECUTE-2">
-<TITLE>Usage
-</TITLE>
-<PARA>
-In the following examples, error checking with <LITERAL>catch</LITERAL>
-has been omitted for clarity.
-</PARA>
-<PARA>
-Insert a row and save the OID in <varname>result_oid</>:
-<ProgramListing>
- pg_execute -oid result_oid $pgconn "insert into mytable values (1)"
-</ProgramListing>
-</PARA>
-<PARA>
-Print the item and value fields from each row:
-<ProgramListing>
- pg_execute -array d $pgconn "select item, value from mytable" {
- puts "Item=$d(item) Value=$d(value)"
- }
-</ProgramListing>
-</PARA>
-<PARA>
-Find the maximum and minimum values and store them in $s(max) and $s(min):
-<ProgramListing>
- pg_execute -array s $pgconn "select max(value) as max,\
- min(value) as min from mytable"
-</ProgramListing>
-</PARA>
-<PARA>
-Find the maximum and minimum values and store them in $max and $min:
-<ProgramListing>
- pg_execute $pgconn "select max(value) as max, min(value) as min from mytable"
-</ProgramListing>
-</PARA>
-</REFSECT1>
-
-</REFENTRY>
-
-<!-- ********************************************************** -->
-
-<REFENTRY ID="PGTCL-PGLISTEN">
-<REFMETA>
-<REFENTRYTITLE>pg_listen</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Asynchronous Notify</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_listen
-</REFNAME>
-<REFPURPOSE>set or change a callback for asynchronous NOTIFY messages
-</REFPURPOSE>
-<INDEXTERM ID="IX-PGTCL-PGLISTEN-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>notify</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGLISTEN-2"><PRIMARY>notify</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>1998-5-22</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
-pg_listen <REPLACEABLE CLASS="PARAMETER">dbHandle</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">notifyName</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">callbackCommand</REPLACEABLE>
-</SYNOPSIS>
-
-<REFSECT2 ID="R2-PGTCL-PGLISTEN-1">
-<REFSECT2INFO>
-<DATE>1998-5-22</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">dbHandle</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid database handle.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">notifyName</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies the notify condition name to start or stop listening to.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">callbackCommand</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>If present, provides the command string to execute
-when a matching notification arrives.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGLISTEN-2">
-<REFSECT2INFO>
-<DATE>1998-5-22</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- None
-</TERM>
-<LISTITEM>
-<PARA>
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-</REFSYNOPSISDIV>
-
-<REFSECT1 ID="R1-PGTCL-PGLISTEN-1">
-<REFSECT1INFO>
-<DATE>1998-5-22</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-<PARA><FUNCTION>pg_listen</FUNCTION> creates, changes, or cancels a request
-to listen for asynchronous NOTIFY messages from the
-<ProductName>PostgreSQL</ProductName> backend. With a <parameter>callbackCommand</>
-parameter, the request is established, or the command string of an already
-existing request is replaced. With no <parameter>callbackCommand</> parameter, a prior
-request is canceled.
-</PARA>
-
-<para>
-After a <FUNCTION>pg_listen</FUNCTION> request is established,
-the specified command string is executed whenever a NOTIFY message bearing
-the given name arrives from the backend. This occurs when any
-<ProductName>PostgreSQL</ProductName> client application issues a NOTIFY command
-referencing that name. (Note that the name can be, but does not have to be,
-that of an existing relation in the database.)
-The command string is executed from the Tcl idle loop. That is the normal
-idle state of an application written with Tk. In non-Tk Tcl shells, you can
-execute <FUNCTION>update</FUNCTION> or <FUNCTION>vwait</FUNCTION> to cause
-the idle loop to be entered.
-</Para>
-
-<para>
-You should not invoke the SQL statements <command>LISTEN</command> or <command>UNLISTEN</command> directly when
-using <FUNCTION>pg_listen</FUNCTION>. <application>Pgtcl</application> takes care of issuing those
-statements for you. But if you want to send a NOTIFY message yourself,
-invoke the SQL NOTIFY statement using <FUNCTION>pg_exec</FUNCTION>.
-</PARA>
-</REFSECT1>
-
-</REFENTRY>
-
-<!-- ********************************************************** -->
-
-<REFENTRY ID="PGTCL-PGON-CONNECTION-LOSS">
-<REFMETA>
-<REFENTRYTITLE>pg_on_connection_loss</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Asynchronous Notify</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_on_connection_loss
-</REFNAME>
-<REFPURPOSE>set or change a callback for unexpected connection loss
-</REFPURPOSE>
-<INDEXTERM
-ID="IX-PGTCL-PGON-CONNECTION-LOSS-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>connection loss</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGON-CONNECTION-LOSS-2"><PRIMARY>connection loss</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>2002-09-02</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
-pg_on_connection_loss <REPLACEABLE CLASS="PARAMETER">dbHandle</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">callbackCommand</REPLACEABLE>
-</SYNOPSIS>
-
-<REFSECT2 ID="R2-PGTCL-PGON-CONNECTION-LOSS-1">
-<REFSECT2INFO>
-<DATE>2002-09-02</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">dbHandle</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid database handle.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">callbackCommand</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>If present, provides the command string to execute
-when connection loss is detected.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGON-CONNECTION-LOSS-2">
-<REFSECT2INFO>
-<DATE>2002-09-02</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- None
-</TERM>
-<LISTITEM>
-<PARA>
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-</REFSYNOPSISDIV>
-
-<REFSECT1 ID="R1-PGTCL-PGON-CONNECTION-LOSS-1">
-<REFSECT1INFO>
-<DATE>2002-09-02</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-<PARA><FUNCTION>pg_on_connection_loss</FUNCTION> creates, changes, or cancels
-a request to execute a callback command if an unexpected loss of connection
-to the database occurs.
-With a <parameter>callbackCommand</>
-parameter, the request is established, or the command string of an already
-existing request is replaced. With no <parameter>callbackCommand</>
-parameter, a prior request is canceled.
-</PARA>
-
-<para>
-The callback command string is executed from the Tcl idle loop. That is the
-normal idle state of an application written with Tk. In non-Tk Tcl shells,
-you can
-execute <FUNCTION>update</FUNCTION> or <FUNCTION>vwait</FUNCTION> to cause
-the idle loop to be entered.
-</Para>
-</REFSECT1>
-
-</REFENTRY>
-
-<!-- ********************************************************** -->
-
-<REFENTRY ID="PGTCL-PGLOCREAT">
-<REFMETA>
-<REFENTRYTITLE>pg_lo_creat</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Large Objects</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_lo_creat
-</REFNAME>
-<REFPURPOSE>create a large object
-</REFPURPOSE>
-<INDEXTERM ID="IX-PGTCL-PGLOCREAT-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>creating</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGLOCREAT-2"><PRIMARY>pg_lo_creat</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>1997-12-24</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
-pg_lo_creat <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">mode</REPLACEABLE>
-</SYNOPSIS>
-
-<REFSECT2 ID="R2-PGTCL-PGLOCREAT-1">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid database connection.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">mode</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies the access mode for the large object</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGLOCREAT-2">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">objOid</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>
-The OID of the large object created.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-</REFSYNOPSISDIV>
-
-<REFSECT1 ID="R1-PGTCL-PGLOCREAT-1">
-<REFSECT1INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-<PARA><FUNCTION>pg_lo_creat</FUNCTION> creates an Inversion Large Object.
-</PARA>
-</REFSECT1>
-<REFSECT1 ID="R1-PGTCL-PGLOCREAT-2">
-<TITLE>Usage
-</TITLE>
-<PARA>
-mode can be any or'ing together of <literal>INV_READ</> and <literal>INV_WRITE</>.
-The <quote>or</quote> operator is <literal>|</literal>.
-<ProgramListing>
+
+<refentry ID="PGTCL-PGEXEC">
+ <refmeta>
+ <refentrytitle>pg_exec</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_exec</refname>
+ <refpurpose>send a command to the server</refpurpose>
+ <indexterm ID="IX-PGTCL-PGEXEC-2"><primary>pg_exec</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+pg_exec <parameter>conn</parameter> <parameter>commandString</parameter>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_exec</function> submits a command to the
+ <productname>PostgreSQL</productname> server and returns a result.
+ Command result handles start with the connection handle and add a
+ period and a result number.
+ </para>
+
+ <para>
+ Note that lack of a Tcl error is not proof that the command
+ succeeded! An error message returned by the server will be
+ processed as a command result with failure status, not by
+ generating a Tcl error in <function>pg_exec</function>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>conn</parameter></term>
+ <listitem>
+ <para>
+ The handle of the connection on which to execute the command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>commandString</parameter></term>
+ <listitem>
+ <para>
+ The SQL command to execute.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ A result handle. A Tcl error will be returned if
+ <application>pgtcl</application> was unable to obtain a server
+ response. Otherwise, a command result object is created and a
+ handle for it is returned. This handle can be passed to
+ <function>pg_result</function> to obtain the results of the
+ command.
+ </para>
+ </refsect1
+</refentry>
+
+
+<refentry ID="PGTCL-PGRESULT">
+ <refmeta>
+ <refentrytitle>pg_result</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_result</refname>
+ <refpurpose>get information about a command result</refpurpose>
+ <indexterm ID="IX-PGTCL-PGRESULT-2"><primary>pg_result</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+pg_result <parameter>resultHandle</parameter> <parameter>resultOption</parameter>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_result</function> returns information about a command
+ result created by a prior <function>pg_exec</function>.
+ </para>
+
+ <para>
+ You can keep a command result around for as long as you need it,
+ but when you are done with it, be sure to free it by executing
+ <function>pg_result -clear</function>. Otherwise, you have a
+ memory leak, and <application>pgtcl</> will eventually start
+ complaining that you have created too many command result objects.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>resultHandle</parameter></term>
+ <listitem>
+ <para>
+ The handle of the command result.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>resultOption</parameter></term>
+ <listitem>
+ <para>
+ One of the following options, specifying which piece of result
+ information to return:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-status</option></term>
+ <listitem>
+ <para>
+ The status of the result.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-error</option></term>
+ <listitem>
+ <para>
+ The error message, if the status indicates an error,
+ otherwise an empty string.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-conn</option></term>
+ <listitem>
+ <para>
+ The connection that produced the result.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-oid</option></term>
+ <listitem>
+ <para>
+ If the command was an <command>INSERT</command>, the OID of
+ the inserted row, otherwise 0.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-numTuples</option></term>
+ <listitem>
+ <para>
+ The number of rows (tuples) returned by the query.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-cmdTuples</option></term>
+ <listitem>
+ <para>
+ The number of rows (tuples) affected by the command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-numAttrs</option></term>
+ <listitem>
+ <para>
+ The number of columns (attributes) in each row.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-assign <parameter>arrayName</parameter></option></term>
+ <listitem>
+ <para>
+ Assign the results to an array, using subscripts of the form
+ <literal>(rowNumber, columnName)</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-assignbyidx <parameter>arrayName</> <optional><parameter>appendstr</></optional></option></term>
+ <listitem>
+ <para>
+ Assign the results to an array using the values of the
+ first column and the names of the remaining column as keys.
+ If <parameter>appendstr</> is given then it is appended to
+ each key. In short, all but the first column of each row
+ are stored into the array, using subscripts of the form
+ <literal>(firstColumnValue, columnNameAppendStr)</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-getTuple <parameter>rowNumber</parameter></option></term>
+ <listitem>
+ <para>
+ Returns the columns of the indicated row in a list. Row
+ numbers start at zero.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-tupleArray <parameter>rowNumber</> <parameter>arrayName</></option></term>
+ <listitem>
+ <para>
+ Stores the columns of the row in array
+ <parameter>arrayName</parameter>, indexed by column names.
+ Row numbers start at zero.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-attributes</option></term>
+ <listitem>
+ <para>
+ Returns a list of the names of the columns in the result.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-lAttributes</option></term>
+ <listitem>
+ <para>
+ Returns a list of sublists, <literal>{name typeOid
+ typeSize}</literal> for each column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-clear</option></term>
+ <listitem>
+ <para>
+ Clear the command result object.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ The result depends on the selected option, as described above.
+ </para>
+ </refsect1>
+</refentry>
+
+
+<refentry ID="PGTCL-PGSELECT">
+ <refmeta>
+ <refentrytitle>pg_select</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_select</refname>
+ <refpurpose>loop over the result of a query</refpurpose>
+ <indexterm ID="IX-PGTCL-PGSELECT-2"><primary>pg_select</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+pg_select <parameter>conn</parameter> <parameter>commandString</parameter> <parameter>arrayVar</parameter> <parameter>procedure</parameter>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_select</function> submits a query
+ (<command>SELECT</command> statement) to the
+ <productname>PostgreSQL</productname> server and executes a given
+ chunk of code for each row in the result. The
+ <parameter>commandString</parameter> must be a
+ <command>SELECT</command> statement; anything else returns an
+ error. The <parameter>arrayVar</parameter> variable is an array
+ name used in the loop. For each row,
+ <parameter>arrayVar</parameter> is filled in with the row values,
+ using the column names as the array indices. Then the
+ <parameter>procedure</parameter> is executed.
+ </para>
+
+ <para>
+ In addition to the column values, the following special entries are
+ made in the array:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>.headers</></term>
+ <listitem>
+ <para>
+ A list of the column names returned by the query.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>.numcols</></term>
+ <listitem>
+ <para>
+ The number of columns returned by the query.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>.tupno</></term>
+ <listitem>
+ <para>
+ The current row number, starting at zero and incrementing for
+ each iteration of the loop body.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>conn</parameter></term>
+ <listitem>
+ <para>
+ The handle of the connection on which to execute the query.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>commandString</parameter></term>
+ <listitem>
+ <para>
+ The SQL query to execute.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>arrayVar</parameter></term>
+ <listitem>
+ <para>
+ An array variable for returned rows.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>procedure</parameter></term>
+ <listitem>
+ <para>
+ The procedure to run for each returned row.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+ <para>
+ None
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ This examples assumes that the table <classname>table1</> has
+ columns <structfield>control</> and <structfield>name</> (and
+ perhaps others):
+<programlisting>
+pg_select $pgconn "SELECT * FROM table1;" array {
+ puts [format "%5d %s" $array(control) $array(name)]
+}
+</programlisting>
+ </para>
+ </refsect1>
+</refentry>
+
+
+<refentry ID="PGTCL-PGEXECUTE">
+ <refmeta>
+ <refentrytitle>pg_execute</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_execute</refname>
+ <refpurpose>send a query and optionally loop over the results</refpurpose>
+ <indexterm ID="IX-PGTCL-PGEXECUTE-2"><primary>pg_execute</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+pg_execute <optional>-array <parameter>arrayVar</parameter></optional> <optional>-oid <parameter>oidVar</parameter></optional> <parameter>conn</parameter> <parameter>commandString</parameter> <optional><parameter>procedure</parameter></optional>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_execute</function> submits a command to the
+ <productname>PostgreSQL</> server.
+ </para>
+
+ <para>
+ If the command is not a <command>SELECT</command> statement, the
+ number of rows affected by the command is returned. If the command
+ is an <command>INSERT</command> statement and a single row is
+ inserted, the OID of the inserted row is stored in the variable
+ <parameter>oidVar</> if the optional <parameter>-oid</parameter>
+ argument is supplied.
+ </para>
+
+ <para>
+ If the command is a <command>SELECT</command> statement, then, for
+ each row in the result, the row values are stored in the
+ <parameter>arrayVar</parameter> variable, if supplied, using the
+ column names as the array indices, else in variables named by the
+ column names, and then the optional
+ <parameter>procedure</parameter> is executed if supplied.
+ (Omitting the <parameter>procedure</parameter> probably makes sense
+ only if the query will return a single row.) The number of rows
+ selected is returned.
+ </para>
+
+ <para>
+ The <parameter>procedure</parameter> can use the Tcl commands
+ <literal>break</literal>, <literal>continue</literal>, and
+ <literal>return</literal> with the expected behavior. Note that if
+ the <parameter>procedure</parameter> executes
+ <literal>return</literal>, then <function>pg_execute</function>
+ does not return the number of affected rows.
+ </para>
+
+ <para>
+ <function>pg_execute</function> is a newer function which provides
+ a superset of the features of <function>pg_select</function> and
+ can replace <function>pg_exec</function> in many cases where access
+ to the result handle is not needed.
+ </para>
+
+ <para>
+ For server-handled errors, <function>pg_execute</function> will
+ throw a Tcl error and return a two-element list. The first element
+ is an error code, such as <literal>PGRES_FATAL_ERROR</literal>, and
+ the second element is the server error text. For more serious
+ errors, such as failure to communicate with the server,
+ <function>pg_execute</function> will throw a Tcl error and return
+ just the error message text.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-array <parameter>arrayVar</parameter></option></term>
+ <listitem>
+ <para>
+ Specifies the name of an array variable where result rows are
+ stored, indexed by the column names. This is ignored if
+ <parameter>commandString</> is not a <command>SELECT</>
+ statement.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-oid <parameter>oidVar</parameter></option></term>
+ <listitem>
+ <para>
+ Specifies the name of a variable into which the OID from an
+ <command>INSERT</command> statement will be stored.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>conn</parameter></term>
+ <listitem>
+ <para>
+ The handle of the connection on which to execute the command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>commandString</parameter></term>
+ <listitem>
+ <para>
+ The SQL command to execute.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>procedure</parameter></term>
+ <listitem>
+ <para>
+ Optional procedure to execute for each result row of a
+ <command>SELECT</command> statement.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ The number of rows affected or returned by the command.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ In the following examples, error checking with
+ <literal>catch</literal> has been omitted for clarity.
+ </para>
+
+ <para>
+ Insert a row and save the OID in <varname>result_oid</>:
+<programlisting>
+pg_execute -oid result_oid $pgconn "INSERT INTO mytable VALUES (1);"
+</programlisting>
+ </para>
+
+ <para>
+ Print the columns <literal>item</> and <literal>value</> from each
+ row:
+<programlisting>
+pg_execute -array d $pgconn "SELECT item, value FROM mytable;" {
+ puts "Item=$d(item) Value=$d(value)"
+}
+</programlisting>
+ </para>
+
+ <para>
+ Find the maximum and minimum values and store them in
+ <literal>$s(max)</> and <literal>$s(min)</>:
+<programlisting>
+pg_execute -array s $pgconn "SELECT max(value) AS max, min(value) AS min FROM mytable;"
+</programlisting>
+ </para>
+
+ <para>
+ Find the maximum and minimum values and store them in
+ <literal>$max</> and <literal>$min</>:
+<programlisting>
+pg_execute $pgconn "SELECT max(value) AS max, min(value) AS min FROM mytable;"
+</programlisting>
+ </para>
+ </refsect1>
+</refentry>
+
+
+<refentry ID="PGTCL-PGLISTEN">
+ <refmeta>
+ <refentrytitle>pg_listen</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_listen</refname>
+ <refpurpose>set or change a callback for asynchronous notification messages</refpurpose>
+ <indexterm ID="IX-PGTCL-PGLISTEN-2"><primary>pg_listen</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+pg_listen <parameter>conn</parameter> <parameter>notifyName</parameter> <optional><parameter>callbackCommand</parameter></optional>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_listen</function> creates, changes, or cancels a
+ request to listen for asynchronous notification messages from the
+ <productname>PostgreSQL</productname> server. With a
+ <parameter>callbackCommand</> parameter, the request is
+ established, or the command string of an already existing request
+ is replaced. With no <parameter>callbackCommand</> parameter, a
+ prior request is canceled.
+ </para>
+
+ <para>
+ After a <function>pg_listen</function> request is established, the
+ specified command string is executed whenever a notification
+ message bearing the given name arrives from the server. This
+ occurs when any <productname>PostgreSQL</productname> client
+ application issues a
+ <command>NOTIFY</command><indexterm><primary>NOTIFY</><secondary>in
+ pgtcl</></> command referencing that name. The command string is
+ executed from the Tcl idle loop. That is the normal idle state of
+ an application written with Tk. In non-Tk Tcl shells, you can
+ execute <function>update</function> or <function>vwait</function>
+ to cause the idle loop to be entered.
+ </para>
+
+ <para>
+ You should not invoke the SQL statements <command>LISTEN</command>
+ or <command>UNLISTEN</command> directly when using
+ <function>pg_listen</function>. <application>pgtcl</application>
+ takes care of issuing those statements for you. But if you want to
+ send a notification message yourself, invoke the SQL
+ <command>NOTIFY</command> statement using
+ <function>pg_exec</function>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>conn</parameter></term>
+ <listitem>
+ <para>
+ The handle of the connection on which to listen for notifications.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>notifyName</parameter></term>
+ <listitem>
+ <para>
+ The name of the notification condition to start or stop
+ listening to.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>callbackCommand</parameter></term>
+ <listitem>
+ <para>
+ If present, provides the command string to execute when a
+ matching notification arrives.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ None
+ </para>
+ </refsect1>
+</refentry>
+
+
+<refentry ID="PGTCL-PGON-CONNECTION-LOSS">
+ <refmeta>
+ <refentrytitle>pg_on_connection_loss</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_on_connection_loss</refname>
+ <refpurpose>set or change a callback for unexpected connection loss</refpurpose>
+ <indexterm ID="IX-PGTCL-PGON-CONNECTION-LOSS-2"><primary>pg_on_connection_loss</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+pg_on_connection_loss <parameter>conn</parameter> <optional><parameter>callbackCommand</parameter></optional>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_on_connection_loss</function> creates, changes, or
+ cancels a request to execute a callback command if an unexpected
+ loss of connection to the database occurs. With a
+ <parameter>callbackCommand</> parameter, the request is
+ established, or the command string of an already existing request
+ is replaced. With no <parameter>callbackCommand</> parameter, a
+ prior request is canceled.
+ </para>
+
+ <para>
+ The callback command string is executed from the Tcl idle loop.
+ That is the normal idle state of an application written with Tk.
+ In non-Tk Tcl shells, you can execute <function>update</function>
+ or <function>vwait</function> to cause the idle loop to be entered.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>conn</parameter></term>
+ <listitem>
+ <para>
+ The handle to watch for connection losses.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>callbackCommand</parameter></term>
+ <listitem>
+ <para>
+ If present, provides the command string to execute when
+ connection loss is detected.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ None
+ </para>
+ </refsect1>
+</refentry>
+
+
+<refentry ID="PGTCL-PGLOCREAT">
+ <refmeta>
+ <refentrytitle>pg_lo_creat</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_lo_creat</refname>
+ <refpurpose>create a large object</refpurpose>
+ <indexterm ID="IX-PGTCL-PGLOCREAT-2"><primary>pg_lo_creat</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+pg_lo_creat <parameter>conn</parameter> <parameter>mode</parameter>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_lo_creat</function> creates a large object.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>conn</parameter></term>
+ <listitem>
+ <para>
+ The handle of a database connection in which to create the large
+ object.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>mode</parameter></term>
+ <listitem>
+ <para>
+ The access mode for the large object. It can be any or'ing
+ together of <literal>INV_READ</> and <literal>INV_WRITE</>. The
+ <quote>or</quote> operator is <literal>|</literal>. For
+ example:
+<programlisting>
[pg_lo_creat $conn "INV_READ|INV_WRITE"]
-</ProgramListing>
-</PARA>
-</REFSECT1>
-</REFENTRY>
-
-<!-- ********************************************************** -->
-
-<REFENTRY ID="PGTCL-PGLOOPEN">
-<REFMETA>
-<REFENTRYTITLE>pg_lo_open</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Large Objects</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_lo_open
-</REFNAME>
-<REFPURPOSE>open a large object
-</REFPURPOSE>
-<INDEXTERM ID="IX-PGTCL-PGLOOPEN-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>opening</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGLOOPEN-2"><PRIMARY>pg_lo_open</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>1997-12-24</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
-pg_lo_open <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">objOid</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">mode</REPLACEABLE>
-</SYNOPSIS>
-
-<REFSECT2 ID="R2-PGTCL-PGLOOPEN-1">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid database connection.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">objOid</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid large object OID.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">mode</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies the access mode for the large object</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGLOOPEN-2">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">fd</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>
-A file descriptor for use in later pg_lo* routines.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-</REFSYNOPSISDIV>
-
-<REFSECT1 ID="R1-PGTCL-PGLOOPEN-1">
-<REFSECT1INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-<PARA><FUNCTION>pg_lo_open</FUNCTION> open an Inversion Large Object.
-</PARA>
-</REFSECT1>
-<REFSECT1 ID="R1-PGTCL-PGLOOPEN-2">
-<TITLE>Usage
-</TITLE>
-<PARA>
-Mode can be either <literal>r</>, <literal>w</>, or <literal>rw</>.
-</PARA>
-</REFSECT1>
-</REFENTRY>
-
-<!-- ********************************************************** -->
-
-<REFENTRY ID="PGTCL-PGLOCLOSE">
-<REFMETA>
-<REFENTRYTITLE>pg_lo_close</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Large Objects</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_lo_close
-</REFNAME>
-<REFPURPOSE>close a large object
-</REFPURPOSE>
-<INDEXTERM ID="IX-PGTCL-PGLOCLOSE-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>closing</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGLOCLOSE-2"><PRIMARY>pg_lo_close</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>1997-12-24</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
-pg_lo_close <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">fd</REPLACEABLE>
-</SYNOPSIS>
-
-<REFSECT2 ID="R2-PGTCL-PGLOCLOSE-1">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid database connection.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">fd</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>
-A file descriptor for use in later pg_lo* routines.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGLOCLOSE-2">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<PARA>None</PARA>
-</REFSECT2>
-</REFSYNOPSISDIV>
-
-<REFSECT1 ID="R1-PGTCL-PGLOCLOSE-1">
-<REFSECT1INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-<PARA><FUNCTION>pg_lo_close</FUNCTION> closes an Inversion Large Object.
-</PARA>
-</REFSECT1>
-<REFSECT1 ID="R1-PGTCL-PGLOCLOSE-2">
-<TITLE>Usage
-</TITLE>
-<PARA>
-</PARA>
-</REFSECT1>
-</REFENTRY>
-
-<!-- ********************************************************** -->
-
-<REFENTRY ID="PGTCL-PGLOREAD">
-<REFMETA>
-<REFENTRYTITLE>pg_lo_read</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Large Objects</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_lo_read
-</REFNAME>
-<REFPURPOSE>read a large object
-</REFPURPOSE>
-<INDEXTERM ID="IX-PGTCL-PGLOREAD-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>reading</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGLOREAD-2"><PRIMARY>pg_lo_read</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>1997-12-24</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
-pg_lo_read <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">fd</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">bufVar</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">len</REPLACEABLE>
-</SYNOPSIS>
-
-<REFSECT2 ID="R2-PGTCL-PGLOREAD-1">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid database connection.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">fd</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>
-File descriptor for the large object from pg_lo_open.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">bufVar</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid buffer variable to contain the large object segment.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">len</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies the maximum allowable size of the large object segment.</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGLOREAD-2">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<PARA>None</PARA>
-</REFSECT2>
-</REFSYNOPSISDIV>
-
-<REFSECT1 ID="R1-PGTCL-PGLOREAD-1">
-<REFSECT1INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-<PARA><FUNCTION>pg_lo_read</FUNCTION> reads
-at most <REPLACEABLE CLASS="PARAMETER">len</REPLACEABLE> bytes from a large object into a variable
- named <REPLACEABLE CLASS="PARAMETER">bufVar</REPLACEABLE>.
-</PARA>
-</REFSECT1>
-<REFSECT1 ID="R1-PGTCL-PGLOREAD-2">
-<TITLE>Usage
-</TITLE>
-<PARA>
-<REPLACEABLE CLASS="PARAMETER">bufVar</REPLACEABLE> must be a valid variable name.
-</PARA>
-</REFSECT1>
-</REFENTRY>
-
-<!-- ********************************************************** -->
-
-<REFENTRY ID="PGTCL-PGLOWRITE">
-<REFMETA>
-<REFENTRYTITLE>pg_lo_write</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Large Objects</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_lo_write
-</REFNAME>
-<REFPURPOSE>write a large object
-</REFPURPOSE>
-<INDEXTERM ID="IX-PGTCL-PGLOWRITE-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>writing</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGLOWRITE-2"><PRIMARY>pg_lo_write</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>1997-12-24</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
-pg_lo_write <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">fd</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">buf</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">len</REPLACEABLE>
-</SYNOPSIS>
-
-<REFSECT2 ID="R2-PGTCL-PGLOWRITE-1">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid database connection.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">fd</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>
-File descriptor for the large object from pg_lo_open.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">buf</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid string variable to write to the large object.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">len</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies the maximum size of the string to write.</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGLOWRITE-2">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<PARA>None</PARA>
-</REFSECT2>
-</REFSYNOPSISDIV>
-
-<REFSECT1 ID="R1-PGTCL-PGLOWRITE-1">
-<REFSECT1INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-<PARA><FUNCTION>pg_lo_write</FUNCTION> writes
-at most <REPLACEABLE CLASS="PARAMETER">len</REPLACEABLE> bytes to a large object from a variable
- <REPLACEABLE CLASS="PARAMETER">buf</REPLACEABLE>.
-</PARA>
-</REFSECT1>
-<REFSECT1 ID="R1-PGTCL-PGLOWRITE-2">
-<TITLE>Usage
-</TITLE>
-<PARA>
-<REPLACEABLE CLASS="PARAMETER">buf</REPLACEABLE> must be
-the actual string to write, not a variable name.
-</PARA>
-</REFSECT1>
-</REFENTRY>
-
-<!-- ********************************************************** -->
-
-<REFENTRY ID="PGTCL-PGLOLSEEK">
-<REFMETA>
-<REFENTRYTITLE>pg_lo_lseek</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Large Objects</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_lo_lseek
-</REFNAME>
-<REFPURPOSE>seek to a position in a large object
-</REFPURPOSE>
-<INDEXTERM ID="IX-PGTCL-PGLOLSEEK-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>positioning</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGLOLSEEK-2"><PRIMARY>pg_lo_lseek</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>1997-12-24</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
-pg_lo_lseek <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">fd</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">offset</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">whence</REPLACEABLE>
-</SYNOPSIS>
-
-<REFSECT2 ID="R2-PGTCL-PGLOLSEEK-1">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid database connection.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">fd</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>
-File descriptor for the large object from pg_lo_open.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">offset</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a zero-based offset in bytes.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">whence</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA> whence can be <literal>SEEK_CUR</>, <literal>SEEK_END</>, or <literal>SEEK_SET</> </PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGLOLSEEK-2">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<PARA>None</PARA>
-</REFSECT2>
-</REFSYNOPSISDIV>
-
-<REFSECT1 ID="R1-PGTCL-PGLOLSEEK-1">
-<REFSECT1INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-<PARA><FUNCTION>pg_lo_lseek</FUNCTION> positions
-to <REPLACEABLE CLASS="PARAMETER">offset</REPLACEABLE> bytes from the beginning of the large object.
-</PARA>
-</REFSECT1>
-<REFSECT1 ID="R1-PGTCL-PGLOLSEEK-2">
-<TITLE>Usage
-</TITLE>
-<PARA>
-<REPLACEABLE CLASS="PARAMETER">whence</REPLACEABLE>
-can be <literal>SEEK_CUR</literal>, <literal>SEEK_END</>, or <literal>SEEK_SET</literal>.
-</PARA>
-</REFSECT1>
-</REFENTRY>
-
-<!-- ********************************************************** -->
-
-<REFENTRY ID="PGTCL-PGLOTELL">
-<REFMETA>
-<REFENTRYTITLE>pg_lo_tell</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Large Objects</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_lo_tell
-</REFNAME>
-<REFPURPOSE>return the current seek position of a large object
-</REFPURPOSE>
-<INDEXTERM ID="IX-PGTCL-PGLOTELL-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>positioning</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGLOTELL-2"><PRIMARY>pg_lo_tell</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>1997-12-24</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
-pg_lo_tell <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">fd</REPLACEABLE>
-</SYNOPSIS>
-
-<REFSECT2 ID="R2-PGTCL-PGLOTELL-1">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid database connection.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">fd</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>
-File descriptor for the large object from pg_lo_open.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGLOTELL-2">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">offset</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>A zero-based offset in bytes suitable for input to <Function>pg_lo_lseek</Function>.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-</REFSYNOPSISDIV>
-
-<REFSECT1 ID="R1-PGTCL-PGLOTELL-1">
-<REFSECT1INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-<PARA><FUNCTION>pg_lo_tell</FUNCTION> returns the current
-to <REPLACEABLE CLASS="PARAMETER">offset</REPLACEABLE> in bytes from the beginning of the large object.
-</PARA>
-</REFSECT1>
-<REFSECT1 ID="R1-PGTCL-PGLOTELL-2">
-<TITLE>Usage
-</TITLE>
-<PARA>
-</PARA>
-</REFSECT1>
-</REFENTRY>
-
-<!-- ********************************************************** -->
-
-<REFENTRY ID="PGTCL-PGLOUNLINK">
-<REFMETA>
-<REFENTRYTITLE>pg_lo_unlink</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Large Objects</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_lo_unlink
-</REFNAME>
-<REFPURPOSE>delete a large object
-</REFPURPOSE>
-<INDEXTERM ID="IX-PGTCL-PGLOUNLINK-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>delete</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGLOUNLINK-2"><PRIMARY>pg_lo_unlink</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>1997-12-24</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
-pg_lo_unlink <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">lobjId</REPLACEABLE>
-</SYNOPSIS>
-
-<REFSECT2 ID="R2-PGTCL-PGLOUNLINK-1">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid database connection.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">lobjId</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>
-Identifier for a large object.
-<comment>
- XXX Is this the same as <parameter>objOid</parameter> in other calls?? - thomas 1998-01-11
-</comment>
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGLOUNLINK-2">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<PARA>
-None
-</PARA>
-</REFSECT2>
-</REFSYNOPSISDIV>
-
-<REFSECT1 ID="R1-PGTCL-PGLOUNLINK-1">
-<REFSECT1INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-<PARA><FUNCTION>pg_lo_unlink</FUNCTION> deletes the specified large object.
-</PARA>
-</REFSECT1>
-<REFSECT1 ID="R1-PGTCL-PGLOUNLINK-2">
-<TITLE>Usage
-</TITLE>
-<PARA>
-</PARA>
-</REFSECT1>
-</REFENTRY>
-
-<!-- ********************************************************** -->
-
-<REFENTRY ID="PGTCL-PGLOIMPORT">
-<REFMETA>
-<REFENTRYTITLE>pg_lo_import</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Large Objects</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_lo_import
-</REFNAME>
-<REFPURPOSE>import a large object from a file
-</REFPURPOSE>
-<INDEXTERM ID="IX-PGTCL-PGLOIMPORT-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>import</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGLOIMPORT-2"><PRIMARY>pg_lo_import</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>1997-12-24</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
-pg_lo_import <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">filename</REPLACEABLE>
-</SYNOPSIS>
-
-<REFSECT2 ID="R2-PGTCL-PGLOIMPORT-1">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid database connection.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">filename</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>
-Unix file name.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGLOIMPORT-2">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<PARA>
-None
-<comment>
- XXX Does this return a lobjId? Is that the same as the objOid in other calls? thomas - 1998-01-11
-</comment>
-</PARA>
-</REFSECT2>
-</REFSYNOPSISDIV>
-
-<REFSECT1 ID="R1-PGTCL-PGLOIMPORT-1">
-<REFSECT1INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-<PARA><FUNCTION>pg_lo_import</FUNCTION> reads the specified file and places the contents into a large object.
-</PARA>
-</REFSECT1>
-<REFSECT1 ID="R1-PGTCL-PGLOIMPORT-2">
-<TITLE>Usage
-</TITLE>
-<PARA>
- <Function>pg_lo_import</Function> must be called within a BEGIN/END transaction block.
-</PARA>
-</REFSECT1>
-</REFENTRY>
-
-<!-- ********************************************************** -->
-
-<REFENTRY ID="PGTCL-PGLOEXPORT">
-<REFMETA>
-<REFENTRYTITLE>pg_lo_export</REFENTRYTITLE>
-<REFMISCINFO>PGTCL - Large Objects</REFMISCINFO>
-</REFMETA>
-<REFNAMEDIV>
-<REFNAME>pg_lo_export
-</REFNAME>
-<REFPURPOSE>export a large object to a file
-</REFPURPOSE>
-<INDEXTERM ID="IX-PGTCL-PGLOEXPORT-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>export</SECONDARY></INDEXTERM>
-<INDEXTERM ID="IX-PGTCL-PGLOEXPORT-2"><PRIMARY>pg_lo_export</PRIMARY></INDEXTERM>
-</REFNAMEDIV>
-<REFSYNOPSISDIV>
-<REFSYNOPSISDIVINFO>
-<DATE>1997-12-24</DATE>
-</REFSYNOPSISDIVINFO>
-<SYNOPSIS>
-pg_lo_export <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">lobjId</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">filename</REPLACEABLE>
-</SYNOPSIS>
-
-<REFSECT2 ID="R2-PGTCL-PGLOEXPORT-1">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Inputs
-</TITLE>
-<VARIABLELIST>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">conn</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>Specifies a valid database connection.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">lobjId</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>
-Large object identifier.
-<comment>
- XXX Is this the same as the objOid in other calls?? thomas - 1998-01-11
-</comment>
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-<VARLISTENTRY>
-<TERM>
- <REPLACEABLE CLASS="PARAMETER">filename</REPLACEABLE>
-</TERM>
-<LISTITEM>
-<PARA>
-Unix file name.
-</PARA>
-</LISTITEM>
-</VARLISTENTRY>
-</VARIABLELIST>
-</REFSECT2>
-
-<REFSECT2 ID="R2-PGTCL-PGLOEXPORT-2">
-<REFSECT2INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT2INFO>
-<TITLE>Outputs
-</TITLE>
-<PARA>
-None
-<comment>
- XXX Does this return a lobjId? Is that the same as the objOid in other calls? thomas - 1998-01-11
-</comment>
-</PARA>
-</REFSECT2>
-</REFSYNOPSISDIV>
-
-<REFSECT1 ID="R1-PGTCL-PGLOEXPORT-1">
-<REFSECT1INFO>
-<DATE>1997-12-24</DATE>
-</REFSECT1INFO>
-<TITLE>Description
-</TITLE>
-<PARA><FUNCTION>pg_lo_export</FUNCTION> writes the specified large object into a Unix file.
-</PARA>
-</REFSECT1>
-<REFSECT1 ID="R1-PGTCL-PGLOEXPORT-2">
-<TITLE>Usage
-</TITLE>
-<PARA>
- <Function>pg_lo_export</Function> must be called within a BEGIN/END transaction block.
-</PARA>
-</REFSECT1>
-</REFENTRY>
-
-</Sect1>
-</Chapter>
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ The OID of the large object created.
+ </para>
+ </refsect1>
+</refentry>
+
+
+<refentry ID="PGTCL-PGLOOPEN">
+ <refmeta>
+ <refentrytitle>pg_lo_open</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_lo_open</refname>
+ <refpurpose>open a large object</refpurpose>
+ <indexterm ID="IX-PGTCL-PGLOOPEN-2"><primary>pg_lo_open</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+pg_lo_open <parameter>conn</parameter> <parameter>loid</parameter> <parameter>mode</parameter>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_lo_open</function> opens a large object.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>conn</parameter></term>
+
+ <listitem>
+ <para>
+ The handle of a database connection in which the large object to
+ be opened exists.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>loid</parameter></term>
+ <listitem>
+ <para>
+ The OID of the large object.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>mode</parameter></term>
+ <listitem>
+ <para>
+ Specifies the access mode for the large object. Mode can be
+ either <literal>r</>, <literal>w</>, or <literal>rw</>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ A descriptor for use in later large-object commands.
+ </para>
+ </refsect1>
+</refentry>
+
+
+<refentry ID="PGTCL-PGLOCLOSE">
+ <refmeta>
+ <refentrytitle>pg_lo_close</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_lo_close</refname>
+ <refpurpose>close a large object</refpurpose>
+ <indexterm ID="IX-PGTCL-PGLOCLOSE-2"><primary>pg_lo_close</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+pg_lo_close <parameter>conn</parameter> <parameter>descriptor</parameter>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_lo_close</function> closes a large object.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>conn</parameter></term>
+ <listitem>
+ <para>
+ The handle of a database connection in which the large object
+ exists.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>descriptor</parameter></term>
+ <listitem>
+ <para>
+ A descriptor for the large object from
+ <function>pg_lo_open</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ None
+ </para>
+ </refsect1>
+</refentry>
+
+
+<refentry ID="PGTCL-PGLOREAD">
+ <refmeta>
+ <refentrytitle>pg_lo_read</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_lo_read</refname>
+ <refpurpose>read from a large object</refpurpose>
+ <indexterm ID="IX-PGTCL-PGLOREAD-2"><primary>pg_lo_read</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+pg_lo_read <parameter>conn</parameter> <parameter>descriptor</parameter> <parameter>bufVar</parameter> <parameter>len</parameter>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_lo_read</function> reads at most
+ <parameter>len</parameter> bytes from a large object into a
+ variable named <parameter>bufVar</parameter>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>conn</parameter></term>
+ <listitem>
+ <para>
+ The handle of a database connection in which the large object
+ exists.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>descriptor</parameter></term>
+ <listitem>
+ <para>
+ A descriptor for the large object from
+ <function>pg_lo_open</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>bufVar</parameter></term>
+ <listitem>
+ <para>
+ The name of a buffer variable to contain the large object
+ segment.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>len</parameter></term>
+ <listitem>
+ <para>
+ The maximum number of bytes to read.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ None
+ </para>
+ </refsect1>
+</refentry>
+
+
+<refentry ID="PGTCL-PGLOWRITE">
+ <refmeta>
+ <refentrytitle>pg_lo_write</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_lo_write</refname>
+ <refpurpose>write to a large object</refpurpose>
+ <indexterm ID="IX-PGTCL-PGLOWRITE-2"><primary>pg_lo_write</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+pg_lo_write <parameter>conn</parameter> <parameter>descriptor</parameter> <parameter>buf</parameter> <parameter>len</parameter>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_lo_write</function> writes at most
+ <parameter>len</parameter> bytes from a variable
+ <parameter>buf</parameter> to a large object.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>conn</parameter></term>
+ <listitem>
+ <para>
+ The handle of a database connection in which the large object
+ exists.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>descriptor</parameter></term>
+ <listitem>
+ <para>
+ A descriptor for the large object from
+ <function>pg_lo_open</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>buf</parameter></term>
+ <listitem>
+ <para>
+ The string to write to the large object (not a variable name).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>len</parameter></term>
+ <listitem>
+ <para>
+ The maximum number of bytes to write.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ None
+ </para>
+ </refsect1>
+</refentry>
+
+
+<refentry ID="PGTCL-PGLOLSEEK">
+ <refmeta>
+ <refentrytitle>pg_lo_lseek</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_lo_lseek</refname>
+ <refpurpose>seek to a position of a large object</refpurpose>
+ <indexterm ID="IX-PGTCL-PGLOLSEEK-2"><primary>pg_lo_lseek</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+pg_lo_lseek <parameter>conn</parameter> <parameter>descriptor</parameter> <parameter>offset</parameter> <parameter>whence</parameter>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_lo_lseek</function> moves the current read/write
+ position to <parameter>offset</parameter> bytes from the position
+ specified by <parameter>whence</parameter>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>conn</parameter></term>
+ <listitem>
+ <para>
+ The handle of a database connection in which the large object
+ exists.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>descriptor</parameter></term>
+ <listitem>
+ <para>
+ A descriptor for the large object from
+ <function>pg_lo_open</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>offset</parameter></term>
+ <listitem>
+ <para>
+ The new seek position in bytes.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>whence</parameter></term>
+ <listitem>
+ <para>
+ Specified from where to calculate the new seek position:
+ <literal>SEEK_CUR</> (from current position),
+ <literal>SEEK_END</> (from end), or <literal>SEEK_SET</> (from
+ start).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ None
+ </para>
+ </refsect1>
+</refentry>
+
+
+<refentry ID="PGTCL-PGLOTELL">
+ <refmeta>
+ <refentrytitle>pg_lo_tell</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_lo_tell</refname>
+ <refpurpose>return the current seek position of a large object</refpurpose>
+ <indexterm ID="IX-PGTCL-PGLOTELL-2"><primary>pg_lo_tell</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+pg_lo_tell <parameter>conn</parameter> <parameter>descriptor</parameter>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_lo_tell</function> returns the current read/write
+ position in bytes from the beginning of the large object.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>conn</parameter></term>
+
+ <listitem>
+ <para>
+ The handle of a database connection in which the large object
+ exists.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>descriptor</parameter></term>
+ <listitem>
+ <para>
+ A descriptor for the large object from
+ <function>pg_lo_open</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ A zero-based offset in bytes suitable for input to
+ <function>pg_lo_lseek</function>.
+ </para>
+ </refsect1>
+</refentry>
+
+
+<refentry ID="PGTCL-PGLOUNLINK">
+ <refmeta>
+ <refentrytitle>pg_lo_unlink</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_lo_unlink</refname>
+ <refpurpose>delete a large object</refpurpose>
+ <indexterm ID="IX-PGTCL-PGLOUNLINK-2"><primary>pg_lo_unlink</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+pg_lo_unlink <parameter>conn</parameter> <parameter>loid</parameter>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_lo_unlink</function> deletes the specified large
+ object.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>conn</parameter></term>
+ <listitem>
+ <para>
+ The handle of a database connection in which the large object
+ exists.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>loid</parameter></term>
+ <listitem>
+ <para>
+ The OID of the large object.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ None
+ </para>
+ </refsect1>
+</refentry>
+
+
+<refentry ID="PGTCL-PGLOIMPORT">
+ <refmeta>
+ <refentrytitle>pg_lo_import</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_lo_import</refname>
+ <refpurpose>import a large object from a file</refpurpose>
+ <indexterm ID="IX-PGTCL-PGLOIMPORT-2"><primary>pg_lo_import</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+pg_lo_import <parameter>conn</parameter> <parameter>filename</parameter>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_lo_import</function> reads the specified file and
+ places the contents into a new large object.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>conn</parameter></term>
+ <listitem>
+ <para>
+ The handle of a database connection in which to create the large
+ object.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>filename</parameter></term>
+ <listitem>
+ <para>
+ Specified the file from which to import the data.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ The OID of the large object created.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <function>pg_lo_import</function> must be called within a
+ <command>BEGIN</>/<command>COMMIT</> transaction block.
+ </para>
+ </refsect1>
+</refentry>
+
+
+<refentry ID="PGTCL-PGLOEXPORT">
+ <refmeta>
+ <refentrytitle>pg_lo_export</refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_lo_export</refname>
+ <refpurpose>export a large object to a file</refpurpose>
+ <indexterm ID="IX-PGTCL-PGLOEXPORT-2"><primary>pg_lo_export</primary></indexterm>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+pg_lo_export <parameter>conn</parameter> <parameter>loid</parameter> <parameter>filename</parameter>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>pg_lo_export</function> writes the specified large object
+ into a file.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>conn</parameter></term>
+ <listitem>
+ <para>
+ The handle of a database connection in which the large object
+ exists.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>loid</parameter></term>
+ <listitem>
+ <para>
+ The OID of the large object.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>filename</parameter></term>
+ <listitem>
+ <para>
+ Specifies the file into which the data is to be exported.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+ <para>
+ None
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <function>pg_lo_export</function> must be called within a
+ <command>BEGIN</>/<command>COMMIT</> transaction block.
+ </para>
+ </refsect1>
+</refentry>
+
+</sect1>
+
+
+<sect1 id="pgtcl-examplesect">
+ <title>Example Program</title>
+
+ <para>
+ <xref linkend="pgtcl-example"> shows a small example of how to use
+ the <application>pgtcl</application> commands.
+ </para>
+
+ <example id="pgtcl-example">
+ <title><application>pgtcl</application> Example Program</title>
+
+<programlisting>
+# getDBs :
+# get the names of all the databases at a given host and port number
+# with the defaults being the localhost and port 5432
+# return them in alphabetical order
+proc getDBs { {host "localhost"} {port "5432"} } {
+ # datnames is the list to be result
+ set conn [pg_connect template1 -host $host -port $port]
+ set res [pg_exec $conn "SELECT datname FROM pg_database ORDER BY datname;"]
+ set ntups [pg_result $res -numTuples]
+ for {set i 0} {$i < $ntups} {incr i} {
+ lappend datnames [pg_result $res -getTuple $i]
+ }
+ pg_result $res -clear
+ pg_disconnect $conn
+ return $datnames
+}
+</programlisting>
+ </example>
+ </sect1>
+
+</chapter>
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.111 2003/02/19 03:59:02 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.112 2003/03/13 01:30:28 petere Exp $
-->
<chapter id="libpq">
<primary>libpq</primary>
</indexterm>
- <sect1 id="libpq-intro">
- <title>Introduction</title>
-
<para>
<application>libpq</application> is the <acronym>C</acronym>
application programmer's interface to
<productname>PostgreSQL</productname>. <application>libpq</application> is a set
- of library routines that allow client programs to pass queries to the
+ of library functions that allow client programs to pass queries to the
<productname>PostgreSQL</productname> backend server and to receive the
results of these queries. <application>libpq</application> is also the
underlying engine for several other <productname>PostgreSQL</productname>
application interfaces, including <application>libpq++</application> (C++),
- <filename>libpgtcl</filename> (Tcl), <productname>Perl</productname>, and
- <filename>ecpg</filename>. So some aspects of <application>libpq</>'s behavior will be
+ <application>libpgtcl</application> (Tcl), <productname>Perl</productname>, and
+ <application>ECPG</application>. So some aspects of <application>libpq</>'s behavior will be
important to you if you use one of those packages.
</para>
<para>
- Three short programs are included at the end of this section to show how
- to write programs that use <filename>libpq</filename>. There are several
- complete examples of <filename>libpq</filename> applications in the
- following directories:
-
- <simplelist>
- <member><filename>src/test/examples</filename></member>
- <member><filename>src/bin/psql</filename></member>
- </simplelist>
+ Three short programs are included at the end of this chapter (<xref linkend="libpq-example">) to show how
+ to write programs that use <application>libpq</application>. There are also several
+ complete examples of <application>libpq</application> applications in the
+ directory <filename>src/test/examples</filename> in the source code distribution.
</para>
<para>
- Frontend programs that use <filename>libpq</filename> must include the
+ Client programs that use <application>libpq</application> must include the
header file <filename>libpq-fe.h</filename> and must link with the
- <filename>libpq</filename> library.
+ <application>libpq</application> library.
</para>
- </sect1>
<sect1 id="libpq-connect">
<title>Database Connection Functions</title>
<para>
- The following routines deal with making a connection to a
- <productname>PostgreSQL</productname> backend server. The
+ The following functions deal with making a connection to a
+ <productname>PostgreSQL</productname> backend server. An
application program can have several backend connections open at
one time. (One reason to do that is to access more than one
database.) Each connection is represented by a
- <structname>PGconn</> object which is obtained from
+ <structname>PGconn</> object which is obtained from the function
<function>PQconnectdb</> or <function>PQsetdbLogin</>. Note that
these functions will always return a non-null object pointer,
unless perhaps there is too little memory even to allocate the
should be called to check whether a connection was successfully
made before queries are sent via the connection object.
- <itemizedlist>
+ <variablelist>
+ <varlistentry>
+ <term><function>PQconnectdb</function></term>
<listitem>
<para>
- <function>PQconnectdb</function>
Makes a new connection to the database server.
- <synopsis>
-PGconn *PQconnectdb(const char *conninfo)
- </synopsis>
+<synopsis>
+PGconn *PQconnectdb(const char *conninfo);
+</synopsis>
+</para>
- This routine opens a new database connection using the parameters taken
+<para>
+ This function opens a new database connection using the parameters taken
from the string <literal>conninfo</literal>. Unlike <function>PQsetdbLogin</> below,
the parameter set can be extended without changing the function signature,
- so use either of this routine or the nonblocking analogues <function>PQconnectStart</>
- and <function>PQconnectPoll</function> is preferred for application programming. The passed string
- can be empty to use all default parameters, or it can contain one or more
- parameter settings separated by whitespace.
+ so use either of this function or the nonblocking analogues <function>PQconnectStart</>
+ and <function>PQconnectPoll</function> is preferred for new application programming.
</para>
<para>
+ The passed string
+ can be empty to use all default parameters, or it can contain one or more
+ parameter settings separated by whitespace.
Each parameter setting is in the form <literal>keyword = value</literal>.
(To write an empty value or a value containing
spaces, surround it with single quotes, e.g.,
<literal>keyword = 'a value'</literal>.
Single quotes and backslashes within the value must be escaped with a
- backslash, e.g., <literal>\'</literal> or <literal>\\</literal>.)
- Spaces around the equal sign are optional. The currently recognized
- parameter keywords are:
+ backslash, i.e., <literal>\'</literal> and <literal>\\</literal>.)
+ Spaces around the equal sign are optional.
+ </para>
+
+ <para>
+ The currently recognized parameter key words are:
<variablelist>
<varlistentry>
<term><literal>hostaddr</literal></term>
<listitem>
<para>
- IP address of host to connect to. This should be in standard
- IPv4 address format, e.g. <literal>172.28.40.9</>. If your machine
- supports IPv6, you can also use those addresses. If a nonzero-length
- string is specified, TCP/IP communication is used.
+ IP address of host to connect to. This should be in the
+ standard IPv4 address format, e.g., <literal>172.28.40.9</>. If
+ your machine supports IPv6, you can also use those addresses. If
+ a nonzero-length string is specified, TCP/IP communication is
+ used.
</para>
<para>
- Using <literal>hostaddr</> instead of host allows the application to avoid a host
+ Using <literal>hostaddr</> instead of <literal>host</> allows the application to avoid a host
name look-up, which may be important in applications with time
constraints. However, Kerberos authentication requires the host
- name. The following therefore applies: If host is specified without
+ name. The following therefore applies: If <literal>host</> is specified without
<literal>hostaddr</>, a host name lookup is forced. If <literal>hostaddr</> is specified without
- host, the value for <literal>hostaddr</> gives the remote address; if Kerberos is
- used, this causes a reverse name query. If both host and <literal>hostaddr</> are
+ <literal>host</>, the value for <literal>hostaddr</> gives the remote address; if Kerberos is
+ used, this causes a reverse name query. If both <literal>host</> and <literal>hostaddr</> are
specified, the value for <literal>hostaddr</> gives the remote address; the value
- for host is ignored, unless Kerberos is used, in which case that value
+ for <literal>host</> is ignored, unless Kerberos is used, in which case that value
is used for Kerberos authentication. Note that authentication is likely
to fail if <application>libpq</application> is passed a host name that is not the name of the
machine at <literal>hostaddr</>.
<term><literal>connect_timeout</literal></term>
<listitem>
<para>
- Time space in seconds given to connect routine. Zero or not set means infinite.
+ Time space in seconds given to connection function. Zero or not set means infinite.
</para>
</listitem>
</varlistentry>
<term><literal>options</literal></term>
<listitem>
<para>
- Trace/debug options to be sent to the server.
+ Configuration options to be sent to the server.
</para>
</listitem>
</varlistentry>
<term><literal>tty</literal></term>
<listitem>
<para>
- A file or <acronym>tty</acronym> for optional debug output from the backend.
+ A file or <acronym>TTY</acronym> for optional debug output from the server.
</para>
</listitem>
</varlistentry>
<term><literal>requiressl</literal></term>
<listitem>
<para>
- Set to 1 to require <acronym>SSL</acronym> connection to the server.
- <application>Libpq</> will then refuse to connect if the server does not
+ If set to 1, an <acronym>SSL</acronym> connection to the server is required.
+ <application>libpq</> will then refuse to connect if the server does not
accept an <acronym>SSL</acronym> connection.
- Set to 0 (default) to negotiate with server.
+ If set to 0 (default), <application>libpq</> will negotiate the connection type with server.
This option is only available if
<productname>PostgreSQL</> is compiled with SSL support.
</para>
<listitem>
<para>
Service name to use for additional parameters. It specifies a service
- name in pg_service.conf that holds additional connection parameters.
+ name in <filename>pg_service.conf</filename> that holds additional connection parameters.
This allows applications to specify only a service name so connection parameters
can be centrally maintained. See
<filename><replaceable>PREFIX</>/share/pg_service.conf.sample</> for
environment variable (see <xref linkend="libpq-envars">)
is checked. If the environment variable is not set either,
then hardwired defaults are used.
- The return value is a pointer to an abstract <type>struct</type>
- representing the connection to the backend.
</para>
</listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><function>PQsetdbLogin</function></term>
<listitem>
<para>
- <function>PQsetdbLogin</function>
Makes a new connection to the database server.
<synopsis>
PGconn *PQsetdbLogin(const char *pghost,
const char *pgtty,
const char *dbName,
const char *login,
- const char *pwd)
+ const char *pwd);
</synopsis>
+</para>
+<para>
This is the predecessor of <function>PQconnectdb</function> with a fixed number
of parameters but the same functionality.
</para>
</listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><function>PQsetdb</function></term>
<listitem>
<para>
- <function>PQsetdb</function> Makes a new connection to the database server.
+ Makes a new connection to the database server.
<synopsis>
PGconn *PQsetdb(char *pghost,
char *pgport,
char *pgoptions,
char *pgtty,
- char *dbName)
+ char *dbName);
</synopsis>
+</para>
+
+<para>
This is a macro that calls <function>PQsetdbLogin</function> with null pointers
for the <parameter>login</> and <parameter>pwd</> parameters. It is provided primarily
for backward compatibility with old programs.
</para>
</listitem>
+ </varlistentry>
- <listitem>
+ <varlistentry>
+ <term><function>PQconnectStart</function></term>
+ <term><function>PQconnectPoll</function></term>
+ <listitem>
<para>
- <function>PQconnectStart</function>,
- <function>PQconnectPoll</function>
<indexterm><primary>nonblocking connection</primary></indexterm>
Make a connection to the database server in a nonblocking manner.
<synopsis>
-PGconn *PQconnectStart(const char *conninfo)
+PGconn *PQconnectStart(const char *conninfo);
</synopsis>
<synopsis>
-PostgresPollingStatusType PQconnectPoll(PGconn *conn)
+PostgresPollingStatusType PQconnectPoll(PGconn *conn);
</synopsis>
- These two routines are used to open a connection to a database server such
+</para>
+<para>
+ These two functions are used to open a connection to a database server such
that your application's thread of execution is not blocked on remote I/O
whilst doing so.
</para>
</para>
<para>
- To begin, call <literal>conn=PQconnectStart("<replaceable>connection_info_string</>")</literal>.
- If <varname>conn</varname> is NULL, then <application>libpq</> has been unable to allocate a new <structname>PGconn</>
+ To begin a nonblocking connection request, call <literal>conn = PQconnectStart("<replaceable>connection_info_string</>")</literal>.
+ If <varname>conn</varname> is null, then <application>libpq</> has been unable to allocate a new <structname>PGconn</>
structure. Otherwise, a valid <structname>PGconn</> pointer is returned (though not yet
representing a valid connection to the database). On return from
- <function>PQconnectStart</function>, call <literal>status=PQstatus(conn)</literal>. If status equals
+ <function>PQconnectStart</function>, call <literal>status = PQstatus(conn)</literal>. If <varname>status</varname> equals
<symbol>CONNECTION_BAD</symbol>, <function>PQconnectStart</function> has failed.
</para>
<para>
proceed with the connection sequence. Loop thus: Consider a connection
<quote>inactive</quote> by default. If <function>PQconnectPoll</function> last returned <symbol>PGRES_POLLING_ACTIVE</>,
consider it <quote>active</quote> instead. If <function>PQconnectPoll(conn)</function> last returned
- <symbol>PGRES_POLLING_READING</symbol>, perform a <function>select()</> for reading on <function>PQsocket(conn)</function>. If
+ <symbol>PGRES_POLLING_READING</symbol>, perform a <function>select()</> for reading on the socket determined using <function>PQsocket(conn)</function>. If
it last returned <symbol>PGRES_POLLING_WRITING</symbol>, perform a <function>select()</> for writing on
- <function>PQsocket(conn)</function>. If you have yet to call <function>PQconnectPoll</function>, i.e. after the call
+ that same socket. If you have yet to call <function>PQconnectPoll</function>, i.e., after the call
to <function>PQconnectStart</function>, behave as if it last returned <symbol>PGRES_POLLING_WRITING</symbol>. If
- the <function>select()</> shows that the socket is ready, consider it <quote>active</quote>. If it has
+ <function>select()</> shows that the socket is ready, consider it <quote>active</quote>. If it has
been decided that this connection is <quote>active</quote>, call <function>PQconnectPoll(conn)</function>
again. If this call returns <symbol>PGRES_POLLING_FAILED</symbol>, the connection procedure
has failed. If this call returns <symbol>PGRES_POLLING_OK</symbol>, the connection has been
<para>
At any time during connection, the status of the connection may be
- checked, by calling <function>PQstatus</>. If this is <symbol>CONNECTION_BAD</>, then the
- connection procedure has failed; if this is <function>CONNECTION_OK</>, then the
- connection is ready. Either of these states should be equally detectable
- from the return value of <function>PQconnectPoll</>, as above. Other states may be
- shown during (and only during) an asynchronous connection procedure. These
- indicate the current stage of the connection procedure, and may be useful
- to provide feedback to the user for example. These statuses may include:
+ checked, by calling <function>PQstatus</>. If this gives <symbol>CONNECTION_BAD</>, then the
+ connection procedure has failed; if it gives <function>CONNECTION_OK</>, then the
+ connection is ready. Both of these states are equally detectable
+ from the return value of <function>PQconnectPoll</>, described above. Other states may also occur
+ during (and only during) an asynchronous connection procedure. These
+ indicate the current stage of the connection procedure and may be useful
+ to provide feedback to the user for example. These statuses are:
<variablelist>
<varlistentry>
</para>
<para>
- Note that if <function>PQconnectStart</function> returns a non-NULL pointer, you must call
+ Note that if <function>PQconnectStart</function> returns a non-null pointer, you must call
<function>PQfinish</function> when you are finished with it, in order to dispose of
the structure and any associated memory blocks. This must be done even if a
call to <function>PQconnectStart</function> or <function>PQconnectPoll</function> failed.
<para>
<function>PQconnectPoll</function> will currently block if
- <application>libpq</> is compiled with <symbol>USE_SSL</symbol>
- defined. This restriction may be removed in the future.
+ <application>libpq</> is compiled with SSL support. This restriction may be removed in the future.
</para>
<para>
- These functions leave the socket in a nonblocking state as if
+ Finally, these functions leave the socket in a nonblocking state as if
<function>PQsetnonblocking</function> had been called.
</para>
- </listitem>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><function>PQconndefaults</function></term>
<listitem>
<para>
- <function>PQconndefaults</function> Returns the default connection options.
+ Returns the default connection options.
<synopsis>
-PQconninfoOption *PQconndefaults(void)
+PQconninfoOption *PQconndefaults(void);
-struct PQconninfoOption
+typedef struct
{
char *keyword; /* The keyword of the option */
char *envvar; /* Fallback environment variable name */
"*" Password field - hide value
"D" Debug option - don't show by default */
int dispsize; /* Field size in characters for dialog */
-}
+} PQconninfoOption;
</synopsis>
+</para>
+
+<para>
+ converts an escaped string representation of binary data into binary
+ data --- the reverse of <function>PQescapeBytea</function>.
Returns a connection options array. This may
be used to determine all possible <function>PQconnectdb</function> options and their
current default values. The return value points to an array of
- <structname>PQconninfoOption</structname> <type>struct</>s, which ends with an entry having a NULL
- keyword pointer. Note that the default values (<structfield>val</structfield> fields)
+ <structname>PQconninfoOption</structname> structures, which ends with an entry having a null
+ key-word pointer. Note that the current default values (<structfield>val</structfield> fields)
will depend on environment variables and other context.
Callers must treat the connection options data as read-only.
</para>
was not thread-safe, so the behavior has been changed.
</para>
</listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><function>PQfinish</function></term>
<listitem>
<para>
- <function>PQfinish</function>
- Close the connection to the backend. Also frees
+ Closes the connection to the server. Also frees
memory used by the <structname>PGconn</structname> object.
<synopsis>
-void PQfinish(PGconn *conn)
+void PQfinish(PGconn *conn);
</synopsis>
- Note that even if the backend connection attempt fails (as
+</para>
+
+<para>
+ Note that even if the server connection attempt fails (as
indicated by <function>PQstatus</function>), the application should call <function>PQfinish</function>
to free the memory used by the <structname>PGconn</structname> object.
The <structname>PGconn</> pointer should not be used after <function>PQfinish</function> has been called.
</para>
</listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><function>PQreset</function></term>
<listitem>
<para>
- <function>PQreset</function>
- Reset the communication port with the backend.
+ Resets the communication channel to the server.
<synopsis>
-void PQreset(PGconn *conn)
+void PQreset(PGconn *conn);
</synopsis>
+</para>
+
+<para>
This function will close the connection
- to the backend and attempt to reestablish a new
+ to the server and attempt to reestablish a new
connection to the same server, using all the same
parameters previously used. This may be useful for
error recovery if a working connection is lost.
</para>
</listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><function>PQresetStart</function></term>
+ <term><function>PQresetPoll</function></term>
<listitem>
<para>
- <function>PQresetStart</function>
- <function>PQresetPoll</function>
- Reset the communication port with the backend, in a nonblocking manner.
+ Reset the communication channel to the server, in a nonblocking manner.
<synopsis>
int PQresetStart(PGconn *conn);
</synopsis>
<synopsis>
PostgresPollingStatusType PQresetPoll(PGconn *conn);
</synopsis>
- These functions will close the connection to the backend and attempt to
+</para>
+
+<para>
+ These functions will close the connection to the server and attempt to
reestablish a new connection to the same server, using all the same
parameters previously used. This may be useful for error recovery if a
working connection is lost. They differ from <function>PQreset</function> (above) in that they
restrictions as <function>PQconnectStart</> and <function>PQconnectPoll</>.
</para>
<para>
- Call <function>PQresetStart</function>. If it returns 0, the reset has failed. If it returns 1,
+ To initiate a connection reset, call <function>PQresetStart</function>. If it returns 0, the reset has failed. If it returns 1,
poll the reset using <function>PQresetPoll</function> in exactly the same way as you would
create the connection using <function>PQconnectPoll</function>.
</para>
</listitem>
+ </varlistentry>
- </itemizedlist>
+ </variablelist>
</para>
<para>
at the contents of <structname>PGconn</structname>. Avoid directly referencing the fields of the
<structname>PGconn</> structure because they are subject to change in the future.
(Beginning in <productname>PostgreSQL</productname> release 6.4, the
-definition of <type>struct PGconn</> is not even provided in <filename>libpq-fe.h</filename>.
+definition of the <type>struct</type> behind <structname>PGconn</> is not even provided in <filename>libpq-fe.h</filename>.
If you have old code that accesses <structname>PGconn</structname> fields directly, you can keep using it
by including <filename>libpq-int.h</filename> too, but you are encouraged to fix the code
soon.)
-<itemizedlist>
+<variablelist>
+<varlistentry>
+<term><function>PQdb</function></term>
<listitem>
<para>
-<function>PQdb</function>
Returns the database name of the connection.
<synopsis>
-char *PQdb(const PGconn *conn)
+char *PQdb(const PGconn *conn);
</synopsis>
+</para>
+
+<para>
<function>PQdb</> and the next several functions return the values established
at connection. These values are fixed for the life of the <structname>PGconn</>
object.
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQuser</function></term>
<listitem>
<para>
-<function>PQuser</function>
Returns the user name of the connection.
<synopsis>
-char *PQuser(const PGconn *conn)
+char *PQuser(const PGconn *conn);
</synopsis>
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQpass</function></term>
<listitem>
<para>
-<function>PQpass</function>
Returns the password of the connection.
<synopsis>
-char *PQpass(const PGconn *conn)
+char *PQpass(const PGconn *conn);
</synopsis>
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQhost</function></term>
<listitem>
<para>
-<function>PQhost</function>
Returns the server host name of the connection.
<synopsis>
-char *PQhost(const PGconn *conn)
+char *PQhost(const PGconn *conn);
</synopsis>
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQport</function></term>
<listitem>
<para>
-<function>PQport</function>
Returns the port of the connection.
<synopsis>
-char *PQport(const PGconn *conn)
+char *PQport(const PGconn *conn);
</synopsis>
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQtty</function></term>
<listitem>
<para>
-<function>PQtty</function>
- Returns the debug <acronym>tty</acronym> of the connection.
+ Returns the debug <acronym>TTY</acronym> of the connection.
<synopsis>
-char *PQtty(const PGconn *conn)
+char *PQtty(const PGconn *conn);
</synopsis>
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQoptions</function></term>
<listitem>
<para>
-<function>PQoptions</function>
- Returns the backend options used in the connection.
+ Returns the configuration options passed in the connection request.
<synopsis>
-char *PQoptions(const PGconn *conn)
+char *PQoptions(const PGconn *conn);
</synopsis>
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQstatus</function></term>
<listitem>
<para>
-<function>PQstatus</function>
Returns the status of the connection.
<synopsis>
-ConnStatusType PQstatus(const PGconn *conn)
+ConnStatusType PQstatus(const PGconn *conn);
</synopsis>
</para>
<para>
The status can be one of a number of values.
However, only two of these are
- seen outside of an asynchronous connection procedure -
- <literal>CONNECTION_OK</literal> or
+ seen outside of an asynchronous connection procedure:
+ <literal>CONNECTION_OK</literal> and
<literal>CONNECTION_BAD</literal>. A good
connection to the database has the status <literal>CONNECTION_OK</literal>.
A failed connection
that might be seen.
</para>
</listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><function>PQerrorMessage</function></term>
<listitem>
<para>
- <function>PQerrorMessage</function>
<indexterm><primary>error message</></>
Returns the error message most recently generated by
an operation on the connection.
- <synopsis>
+<synopsis>
char *PQerrorMessage(const PGconn* conn);
- </synopsis>
+</synopsis>
</para>
<para>
- Nearly all <application>libpq</> functions will set
+ Nearly all <application>libpq</> functions will set a message for
<function>PQerrorMessage</function> if they fail.
- Note that by <application>libpq</application> convention, a non-empty
- <function>PQerrorMessage</function> will
+ Note that by <application>libpq</application> convention, a nonempty
+ <function>PQerrorMessage</function> result will
include a trailing newline.
</para>
</listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><function>PQsocket</function></term>
<listitem>
<para>
- <function>PQbackendPID</function>
- Returns the process <acronym>ID</acronym> of the backend server
- handling this connection.
- <synopsis>
+ Obtains the file descriptor number of the connection socket to
+ the server. A valid descriptor will be greater than or equal
+ to 0; a result of -1 indicates that no server connection is
+ currently open.
+<synopsis>
+int PQsocket(const PGconn *conn);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PQbackendPID</function></term>
+ <listitem>
+ <para>
+ Returns the process <acronym>ID</acronym> of the backend server process
+ handling this connection.
+<synopsis>
int PQbackendPID(const PGconn *conn);
- </synopsis>
+</synopsis>
+</para>
+
+<para>
The backend <acronym>PID</acronym> is useful for debugging
purposes and for comparison to <command>NOTIFY</command>
messages (which include the <acronym>PID</acronym> of the
- notifying backend). Note that the <acronym>PID</acronym>
- belongs to a process executing on the database server host, not
- the local host!
+ notifying backend process). Note that the
+ <acronym>PID</acronym> belongs to a process executing on the
+ database server host, not the local host!
</para>
</listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><function>PQgetssl</function></term>
<listitem>
<para>
- <function>PQgetssl</function>
<indexterm><primary>SSL</></>
- Returns the SSL structure used in the connection, or NULL
+ Returns the SSL structure used in the connection, or null
if SSL is not in use.
- <synopsis>
+<synopsis>
SSL *PQgetssl(const PGconn *conn);
- </synopsis>
+</synopsis>
+</para>
+
+<para>
This structure can be used to verify encryption levels, check
- server certificate and more. Refer to the SSL documentation
+ server certificates, and more. Refer to the <productname>OpenSSL</> documentation
for information about this structure.
</para>
<para>
- You must define <literal>USE_SSL</literal> in order to get the
+ You must define <symbol>USE_SSL</symbol> in order to get the
prototype for this function. Doing this will also
automatically include <filename>ssl.h</filename> from <productname>OpenSSL</productname>.
</para>
</listitem>
+ </varlistentry>
- </itemizedlist>
+ </variablelist>
</para>
</sect1>
</para>
<sect2 id="libpq-exec-main">
- <title>Main Routines</title>
-<itemizedlist>
+ <title>Main Functions</title>
+
+<variablelist>
+<varlistentry>
+<term><function>PQexec</function></term>
<listitem>
<para>
-<function>PQexec</function>
- Submit a command to the server
- and wait for the result.
+ Submits a command to the server
+ and waits for the result.
<synopsis>
PGresult *PQexec(PGconn *conn,
- const char *query);
+ const char *command);
</synopsis>
- Returns a <structname>PGresult</structname> pointer or possibly a NULL pointer.
- A non-NULL pointer will generally be returned except in
+</para>
+
+<para>
+ Returns a <structname>PGresult</structname> pointer or possibly a null pointer.
+ A non-null pointer will generally be returned except in
out-of-memory conditions or serious errors such as inability
- to send the command to the backend.
- If a NULL is returned, it
+ to send the command to the server.
+ If a null pointer is returned, it
should be treated like a <symbol>PGRES_FATAL_ERROR</symbol> result. Use
<function>PQerrorMessage</function> to get more information about the error.
</para>
</listitem>
-</itemizedlist>
+</varlistentry>
+</variablelist>
<para>
The <function>PGresult</function> structure encapsulates the result
-returned by the backend.
-<filename>libpq</filename> application programmers should be careful to
+returned by the server.
+<application>libpq</application> application programmers should be careful to
maintain the <structname>PGresult</structname> abstraction. Use the accessor functions below to get
at the contents of <structname>PGresult</structname>. Avoid directly referencing the fields of the
<structname>PGresult</structname> structure because they are subject to change in the future.
(Beginning in <productname>PostgreSQL</productname> 6.4, the
-definition of <type>struct PGresult</> is not even provided in <filename>libpq-fe.h</>. If you
+definition of <type>struct</> behind <structname>PGresult</> is not even provided in <filename>libpq-fe.h</>. If you
have old code that accesses <structname>PGresult</structname> fields directly, you can keep using it
by including <filename>libpq-int.h</filename> too, but you are encouraged to fix the code
soon.)
</para>
-<itemizedlist>
+<variablelist>
+<varlistentry>
+<term><function>PQresultStatus</function></term>
<listitem>
<para>
-<function>PQresultStatus</function>
Returns the result status of the command.
<synopsis>
-ExecStatusType PQresultStatus(const PGresult *res)
+ExecStatusType PQresultStatus(const PGresult *res);
</synopsis>
+</para>
+
+<para>
<function>PQresultStatus</function> can return one of the following values:
-<itemizedlist>
- <listitem>
- <para><literal>PGRES_EMPTY_QUERY</literal> -- The string sent to the backend was empty.</para>
- </listitem>
- <listitem>
- <para><literal>PGRES_COMMAND_OK</literal> -- Successful completion of a command returning no data</para>
- </listitem>
- <listitem>
- <para><literal>PGRES_TUPLES_OK</literal> -- The query successfully executed</para>
- </listitem>
- <listitem>
- <para><literal>PGRES_COPY_OUT</literal> -- Copy Out (from server) data transfer started</para>
- </listitem>
- <listitem>
- <para><literal>PGRES_COPY_IN</literal> -- Copy In (to server) data transfer started</para>
- </listitem>
- <listitem>
- <para><literal>PGRES_BAD_RESPONSE</literal> -- The server's response was not understood</para>
- </listitem>
- <listitem>
- <para><literal>PGRES_NONFATAL_ERROR</literal></para>
- </listitem>
- <listitem>
- <para><literal>PGRES_FATAL_ERROR</literal></para>
- </listitem>
-</itemizedlist>
+<variablelist>
+ <varlistentry>
+ <term><literal>PGRES_EMPTY_QUERY</literal></term>
+ <listitem>
+ <para>The string sent to the server was empty.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGRES_COMMAND_OK</literal></term>
+ <listitem>
+ <para>Successful completion of a command returning no data.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGRES_TUPLES_OK</literal></term>
+ <listitem>
+ <para>The query successfully executed.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGRES_COPY_OUT</literal></term>
+ <listitem>
+ <para>Copy Out (from server) data transfer started.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGRES_COPY_IN</literal></term>
+ <listitem>
+ <para>Copy In (to server) data transfer started.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGRES_BAD_RESPONSE</literal></term>
+ <listitem>
+ <para>The server's response was not understood.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGRES_NONFATAL_ERROR</literal></term>
+ <listitem>
+ <para>A nonfatal error occurred.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGRES_FATAL_ERROR</literal></term>
+ <listitem>
+ <para>A fatal error occurred.</para>
+ </listitem>
+ </varlistentry>
+</variablelist>
If the result status is <literal>PGRES_TUPLES_OK</literal>, then the
-routines described below can be used to retrieve the rows returned by
+functions described below can be used to retrieve the rows returned by
the query. Note that a <command>SELECT</command> command that happens
to retrieve zero rows still shows <literal>PGRES_TUPLES_OK</literal>.
<literal>PGRES_COMMAND_OK</literal> is for commands that can never
return rows (<command>INSERT</command>, <command>UPDATE</command>,
etc.). A response of <literal>PGRES_EMPTY_QUERY</literal> often
-indicates a bug in the client software.
+exposes a bug in the client software.
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQresStatus</function></term>
<listitem>
<para>
-<function>PQresStatus</function>
Converts the enumerated type returned by <function>PQresultStatus</> into
a string constant describing the status code.
<synopsis>
</synopsis>
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQresultErrorMessage</function></term>
<listitem>
<para>
-<function>PQresultErrorMessage</function>
-returns the error message associated with the query, or an empty string
+Returns the error message associated with the command, or an empty string
if there was no error.
<synopsis>
char *PQresultErrorMessage(const PGresult *res);
</synopsis>
+</para>
+
+<para>
Immediately following a <function>PQexec</function> or <function>PQgetResult</function>
call, <function>PQerrorMessage</function> (on the connection) will return the same
string as <function>PQresultErrorMessage</function> (on the result). However, a
when you want to know the status from the latest operation on the connection.
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQclear</function></term>
<listitem>
<para>
-<function>PQclear</function>
- Frees the storage associated with the <structname>PGresult</structname>.
- Every query result should be freed via <function>PQclear</function> when
+ Frees the storage associated with a <structname>PGresult</structname>.
+ Every command result should be freed via <function>PQclear</function> when
it is no longer needed.
<synopsis>
void PQclear(PQresult *res);
</synopsis>
+</para>
+
+<para>
You can keep a <structname>PGresult</structname> object around for as long as you
- need it; it does not go away when you issue a new query,
+ need it; it does not go away when you issue a new command,
nor even if you close the connection. To get rid of it,
you must call <function>PQclear</function>. Failure to do this will
- result in memory leaks in the frontend application.
+ result in memory leaks in your client application.
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQmakeEmptyPGresult</function></term>
<listitem>
<para>
-<function>PQmakeEmptyPGresult</function>
Constructs an empty <structname>PGresult</structname> object with the given status.
<synopsis>
PGresult* PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status);
</synopsis>
-This is <application>libpq</>'s internal routine to allocate and initialize an empty
+</para>
+
+<para>
+This is <application>libpq</>'s internal function to allocate and initialize an empty
<structname>PGresult</structname> object. It is exported because some applications find it
useful to generate result objects (particularly objects with error
-status) themselves. If <parameter>conn</parameter> is not NULL and status indicates an error,
-the connection's current error message is copied into the <structname>PGresult.</structname>
+status) themselves. If <parameter>conn</parameter> is not null and <parameter>status</> indicates an error,
+the current error message of the specified connection is copied into the <structname>PGresult</structname>.
Note that <function>PQclear</function> should eventually be called on the object, just
as with a <structname>PGresult</structname> returned by <application>libpq</application> itself.
</para>
</listitem>
-</itemizedlist>
+</varlistentry>
+</variablelist>
</sect2>
<sect2 id="libpq-exec-escape-string">
- <title>Escaping strings for inclusion in SQL queries</title>
+ <title>Escaping Strings for Inclusion in SQL Commands</title>
<indexterm zone="libpq-exec-escape-string"><primary>escaping strings</></>
<para>
-<function>PQescapeString</function>
- Escapes a string for use within an SQL query.
+<function>PQescapeString</function> escapes a string for use within an SQL commmand.
<synopsis>
size_t PQescapeString (char *to, const char *from, size_t length);
</synopsis>
-If you want to include strings that have been received
+</para>
+
+<para>
+If you want to use strings that have been received
from a source that is not trustworthy (for example, because a random user
-entered them), you cannot directly include them in SQL
-queries for security reasons. Instead, you have to quote special
-characters that are otherwise interpreted by the SQL parser.
+entered them), you should not directly include them in SQL
+commands for security reasons. Instead, you have to escape certain
+characters that are otherwise interpreted specially by the SQL parser.
+<function>PQescapeString</> performs this operation.
</para>
<para>
-<function>PQescapeString</> performs this operation. The
-<parameter>from</> points to the first character of the string that
+The
+parameter <parameter>from</> points to the first character of the string that
is to be escaped, and the <parameter>length</> parameter counts the
-number of characters in this string (a terminating zero byte is
-neither necessary nor counted). <parameter>to</> shall point to a
+number of characters in this string. (A terminating zero byte is
+neither necessary nor counted.) <parameter>to</> shall point to a
buffer that is able to hold at least one more character than twice
the value of <parameter>length</>, otherwise the behavior is
undefined. A call to <function>PQescapeString</> writes an escaped
<sect2 id="libpq-exec-escape-bytea">
- <title>Escaping binary strings for inclusion in SQL queries</title>
+ <title>Escaping Binary Strings for Inclusion in SQL Commands</title>
<indexterm zone="libpq-exec-escape-bytea">
<primary>escaping binary strings</primary>
</indexterm>
+
+ <variablelist>
+ <varlistentry>
+ <term><function>PQescapeBytea</function></term>
+ <listitem>
<para>
- <function>PQescapeBytea</function>
- Escapes a binary string (<type>bytea</type> type) for use within an SQL query.
- <synopsis>
- unsigned char *PQescapeBytea(const unsigned char *from,
- size_t from_length,
- size_t *to_length);
- </synopsis>
-
- Certain <acronym>ASCII</acronym> characters <emphasis>must</emphasis>
- be escaped (but all characters <emphasis>may</emphasis> be escaped)
- when used as part of a <type>bytea</type>
- string literal in an <acronym>SQL</acronym> statement. In general, to
- escape a character, it is converted into the three digit octal number
- equal to the decimal <acronym>ASCII</acronym> value, and preceded by
- two backslashes. The single quote (') and backslash (\) characters have
- special alternate escape sequences. See the &cite-user;
- for more information. <function>PQescapeBytea
- </function> performs this operation, escaping only the minimally
- required characters.
+ Escapes binary data for use within an SQL command with the type <type>bytea</type>.
+<synopsis>
+unsigned char *PQescapeBytea(const unsigned char *from,
+ size_t from_length,
+ size_t *to_length);
+</synopsis>
+</para>
+
+<para>
+ Certain byte values <emphasis>must</emphasis> be escaped (but all
+ byte values <emphasis>may</emphasis> be escaped) when used as part
+ of a <type>bytea</type> literal in an <acronym>SQL</acronym>
+ statement. In general, to escape a byte, it is converted into the
+ three digit octal number equal to the octet value, and preceded by
+ two backslashes. The single quote (<literal>'</>) and backslash
+ (<literal>\</>) characters have special alternative escape
+ sequences. See the &cite-user; for more
+ information. <function>PQescapeBytea</function> performs this
+ operation, escaping only the minimally required bytes.
</para>
<para>
The <parameter>from</parameter> parameter points to the first
- character of the string that is to be escaped, and the
+ byte of the string that is to be escaped, and the
<parameter>from_length</parameter> parameter reflects the number of
- characters in this binary string (a terminating zero byte is
- neither necessary nor counted). The <parameter>to_length</parameter>
- parameter shall point to a buffer suitable to hold the resultant
+ bytes in this binary string. (A terminating zero byte is
+ neither necessary nor counted.) The <parameter>to_length</parameter>
+ parameter points to a variable that will hold the resultant
escaped string length. The result string length includes the terminating
zero byte of the result.
</para>
<para>
<function>PQescapeBytea</> returns an escaped version of the
- <parameter>from</parameter> parameter binary string, to a
- caller-provided buffer. The return string has all special
- characters replaced so that they can be properly processed by the
- <productname>PostgreSQL</> string literal parser, and the
- <type>bytea</type> input function. A terminating zero byte is also
- added. The single quotes that must surround
- <productname>PostgreSQL</> string literals are not part of the
- result string.
+ <parameter>from</parameter> parameter binary string in memory allocated with <function>malloc()</>.
+ The return string has all special characters replaced
+ so that they can be properly processed by the PostgreSQL string literal
+ parser, and the <type>bytea</type> input function. A terminating zero
+ byte is also added. The single quotes that must surround
+ PostgreSQL string literals are not part of the result string.
</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><function>PQunescapeBytea</function></term>
+ <listitem>
<para>
- <function>PQunescapeBytea</function>
Converts an escaped string representation of binary data into binary
- data - the reverse of <function>PQescapeBytea</function>.
- <synopsis>
- unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length);
- </synopsis>
+ data --- the reverse of <function>PQescapeBytea</function>.
+<synopsis>
+unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length);
+</synopsis>
+</para>
+<para>
The <parameter>from</parameter> parameter points to an escaped string
- such as might be returned by <function>PQgetvalue</function> of a
- <type>BYTEA</type> column. <function>PQunescapeBytea</function> converts
- this string representation into its binary representation, filling the supplied buffer.
- It returns a pointer to the buffer which is NULL on error, and the size
- of the buffer in <parameter>to_length</parameter>. The pointer may
- subsequently be used as an argument to the function
- <function>free(3)</function>.
+ such as might be returned by <function>PQgetvalue</function> when applied to a
+ <type>bytea</type> column. <function>PQunescapeBytea</function> converts
+ this string representation into its binary representation.
+ It returns a pointer to a buffer allocated with <function>malloc()</function>, or null on error, and puts the size
+ of the buffer in <parameter>to_length</parameter>.
</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
</sect2>
<sect2 id="libpq-exec-select-info">
- <title>Retrieving SELECT Result Information</title>
+ <title>Retrieving Query Result Information</title>
-<itemizedlist>
+<variablelist>
+<varlistentry>
+<term><function>PQntuples</function></term>
<listitem>
<para>
-<function>PQntuples</function>
- Returns the number of tuples (rows)
+ Returns the number of rows (tuples)
in the query result.
<synopsis>
int PQntuples(const PGresult *res);
</synopsis>
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQnfields</function></term>
<listitem>
<para>
-<function>PQnfields</function>
- Returns the number of fields
- (columns) in each row of the query result.
+ Returns the number of columns (fields)
+ in each row of the query result.
<synopsis>
int PQnfields(const PGresult *res);
</synopsis>
</para>
</listitem>
+</varlistentry>
-
+<varlistentry>
+<term><function>PQfname</function></term>
<listitem>
<para>
-<function>PQfname</function>
- Returns the field (column) name associated with the given field index.
- Field indices start at 0.
+ Returns the column name associated with the given column number.
+ Column numbers start at 0.
<synopsis>
char *PQfname(const PGresult *res,
- int field_index);
+ int column_number);
</synopsis>
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQfnumber</function></term>
<listitem>
<para>
-<function>PQfnumber</function>
- Returns the field (column) index
- associated with the given field name.
+ Returns the column number
+ associated with the given column name.
<synopsis>
int PQfnumber(const PGresult *res,
- const char *field_name);
+ const char *column_name);
</synopsis>
</para>
<para>
- -1 is returned if the given name does not match any field.
+ -1 is returned if the given name does not match any column.
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQftype</function></term>
<listitem>
<para>
-<function>PQftype</function>
- Returns the field type associated with the
- given field index. The integer returned is an
- internal coding of the type. Field indices start
+ Returns the column data type associated with the
+ given column number. The integer returned is the
+ internal OID number of the type. Column numbers start
at 0.
<synopsis>
Oid PQftype(const PGresult *res,
- int field_index);
+ int column_number);
</synopsis>
+</para>
+
+<para>
You can query the system table <literal>pg_type</literal> to obtain
the name and properties of the various data types. The <acronym>OID</acronym>s
-of the built-in data types are defined in <filename>src/include/catalog/pg_type.h</filename>
+of the built-in data types are defined in the file <filename>src/include/catalog/pg_type.h</filename>
in the source tree.
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQfmod</function></term>
<listitem>
<para>
-<function>PQfmod</function>
- Returns the type-specific modification data of the field
- associated with the given field index.
- Field indices start at 0.
+ Returns the type-specific modification data of the column
+ associated with the given column number.
+ Column numbers start at 0.
<synopsis>
int PQfmod(const PGresult *res,
- int field_index);
+ int column_number);
</synopsis>
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQfsize</function></term>
<listitem>
<para>
-<function>PQfsize</function>
- Returns the size in bytes of the field
- associated with the given field index.
- Field indices start at 0.
+ Returns the size in bytes of the column
+ associated with the given column number.
+ Column numbers start at 0.
<synopsis>
int PQfsize(const PGresult *res,
- int field_index);
+ int column_number);
</synopsis>
- <function>PQfsize</> returns the space allocated for this field in a database
- tuple, in other words the size of the server's binary representation
- of the data type. -1 is returned if the field is variable size.
</para>
+<para>
+ <function>PQfsize</> returns the space allocated for this column in a database
+ row, in other words the size of the server's binary representation
+ of the data type. -1 is returned if the column has a variable size.
+</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQbinaryTuples</function></term>
<listitem>
<para>
-<function>PQbinaryTuples</function>
- Returns 1 if the <structname>PGresult</> contains binary tuple data,
- 0 if it contains ASCII data.
+ Returns 1 if the <structname>PGresult</> contains binary row data
+ and 0 if it contains text data.
<synopsis>
int PQbinaryTuples(const PGresult *res);
</synopsis>
-Currently, binary tuple data can only be returned by a query that
+</para>
+
+<para>
+Currently, binary row data can only be returned by a query that
extracts data from a binary cursor.
</para>
</listitem>
-</itemizedlist>
+</varlistentry>
+</variablelist>
</sect2>
<sect2 id="libpq-exec-select-values">
- <title>Retrieving SELECT Result Values</title>
+ <title>Retrieving Query Result Values</title>
-<itemizedlist>
+<variablelist>
+<varlistentry>
+<term><function>PQgetvalue</function></term>
<listitem>
<para>
-<function>PQgetvalue</function>
- Returns a single field (column) value of one tuple (row)
+ Returns a single column value of one row
of a <structname>PGresult</structname>.
- Tuple and field indices start at 0.
+ Row and colums indices start at 0.
<synopsis>
char* PQgetvalue(const PGresult *res,
- int tup_num,
- int field_num);
+ int row_number,
+ int column_number);
</synopsis>
+</para>
+
+<para>
For most queries, the value returned by <function>PQgetvalue</function>
is a null-terminated character string representation
-of the attribute value. But if <function>PQbinaryTuples()</function> is 1,
+of the column value. But if <function>PQbinaryTuples</function> returns 1,
the value returned by <function>PQgetvalue</function> is the binary
representation of the
type in the internal format of the backend server
-(but not including the size word, if the field is variable-length).
+(but not including the size word, if the column is variable-length).
It is then the programmer's responsibility to cast and
-convert the data to the correct C type. The pointer
+convert the data to the correct C type.
+</para>
+
+<para>
+The pointer
returned by <function>PQgetvalue</function> points to storage that is
-part of the <structname>PGresult</structname> structure. One should not modify it,
+part of the <structname>PGresult</structname> structure. One should not modify the data it points to,
and one must explicitly
-copy the value into other storage if it is to
+copy the data into other storage if it is to
be used past the lifetime of the <structname>PGresult</structname> structure itself.
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQgetisnull</function></term>
<listitem>
<para>
-<function>PQgetisnull</function>
- Tests a field for a NULL entry.
- Tuple and field indices start at 0.
+ Tests a column for a null value.
+ Row and column numbers start at 0.
<synopsis>
int PQgetisnull(const PGresult *res,
- int tup_num,
- int field_num);
+ int row_number,
+ int column_number);
</synopsis>
- This function returns 1 if the field contains a NULL, 0 if
+</para>
+
+<para>
+ This function returns 1 if the column is null and 0 if
it contains a non-null value. (Note that <function>PQgetvalue</function>
- will return an empty string, not a null pointer, for a NULL
- field.)
+ will return an empty string, not a null pointer, for a null
+ column.)
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQgetlength</function></term>
<listitem>
<para>
-<function>PQgetlength</function>
- Returns the length of a field (attribute) value in bytes.
- Tuple and field indices start at 0.
+ Returns the length of a column value in bytes.
+ Row and column numbers start at 0.
<synopsis>
int PQgetlength(const PGresult *res,
- int tup_num,
- int field_num);
+ int row_number,
+ int column_number);
</synopsis>
-This is the actual data length for the particular data value, that is the
+</para>
+
+<para>
+This is the actual data length for the particular data value, that is, the
size of the object pointed to by <function>PQgetvalue</function>. Note that for character-represented
values, this size has little to do with the binary size reported by <function>PQfsize</function>.
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQprint</function></term>
<listitem>
<para>
-<function>PQprint</function>
- Prints out all the tuples and, optionally, the
- attribute names to the specified output stream.
- <synopsis>
+ Prints out all the rows and, optionally, the
+ column names to the specified output stream.
+<synopsis>
void PQprint(FILE* fout, /* output stream */
const PGresult *res,
const PQprintOpt *po);
-struct {
+typedef struct {
pqbool header; /* print output field headings and row count */
pqbool align; /* fill align the fields */
pqbool standard; /* old brain dead format */
- pqbool html3; /* output html tables */
+ pqbool html3; /* output HTML tables */
pqbool expanded; /* expand tables */
pqbool pager; /* use pager for output if needed */
char *fieldSep; /* field separator */
- char *tableOpt; /* insert to HTML <replaceable>table ...</replaceable> */
- char *caption; /* HTML <replaceable>caption</replaceable> */
- char **fieldName; /* null terminated array of replacement field names */
+ char *tableOpt; /* attributes for HTML table element */
+ char *caption; /* HTML table caption */
+ char **fieldName; /* null-terminated array of replacement field names */
} PQprintOpt;
- </synopsis>
+</synopsis>
+</para>
+
+<para>
This function was formerly used by <application>psql</application>
to print query results, but this is no longer the case and this
function is no longer actively supported.
</para>
</listitem>
-</itemizedlist>
+</varlistentry>
+</variablelist>
</sect2>
<sect2 id="libpq-exec-nonselect">
- <title>Retrieving Non-SELECT Result Information</title>
+ <title>Retrieving Result Information for Other Commands</title>
-<itemizedlist>
+<variablelist>
+<varlistentry>
+<term><function>PQcmdStatus</function></term>
<listitem>
<para>
-<function>PQcmdStatus</function>
Returns the command status string from the SQL command that
generated the <structname>PGresult</structname>.
<synopsis>
</synopsis>
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQcmdTuples</function></term>
<listitem>
<para>
-<function>PQcmdTuples</function>
Returns the number of rows affected by the SQL command.
<synopsis>
char * PQcmdTuples(PGresult *res);
</synopsis>
+</para>
+
+<para>
If the <acronym>SQL</acronym> command that generated the
- <structname>PGresult</structname> was <command>INSERT</command>,
- <command>UPDATE</command>, <command>DELETE</command>,
- <command>MOVE</command>, or <command>FETCH</command> this
- returns a string containing the number of rows affected. If the
- command was anything else, it returns the empty string.
+ <structname>PGresult</structname> was <command>INSERT</>, <command>UPDATE</>, or <command>DELETE</command>, this returns a
+ string containing the number of rows affected. If the
+ command was anything else, it returns the empty string.
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQoidValue</function></term>
<listitem>
<para>
-<function>PQoidValue</function>
- Returns the object ID of the inserted row, if the
- <acronym>SQL</acronym> command was an <command>INSERT</command>
- that inserted exactly one row into a table that has OIDs.
- Otherwise, returns <literal>InvalidOid</literal>.
+ Returns the OID of the inserted row, if the
+ <acronym>SQL</acronym> command was an <command>INSERT</command>
+ that inserted exactly one row into a table that has OIDs.
+ Otherwise, returns <literal>InvalidOid</literal>.
<synopsis>
Oid PQoidValue(const PGresult *res);
</synopsis>
+</para>
+
+<para>
The type <type>Oid</type> and the constant
- <literal>InvalidOid</literal> will be defined if you include the
- <application>libpq</application> header file. They will both be
- some integer type.
+ <literal>InvalidOid</literal> will be defined if you include
+ the <application>libpq</application> header file. They will
+ both be some integer type.
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQoidStatus</function></term>
<listitem>
<para>
-<function>PQoidStatus</function>
- Returns a string with the object ID
- of the inserted row, if the <acronym>SQL</acronym> command
- was an <command>INSERT</command>. (The string will be
- <literal>0</> if the <command>INSERT</command> did not
- insert exactly one row, or if the target table does not have
- OIDs.) If the command was not an <command>INSERT</command>,
- returns an empty string.
+ Returns a string with the OID of the inserted row, if the
+ <acronym>SQL</acronym> command was an
+ <command>INSERT</command>. (The string will be
+ <literal>0</> if the <command>INSERT</command> did not
+ insert exactly one row, or if the target table does not have
+ OIDs.) If the command was not an <command>INSERT</command>,
+ returns an empty string.
<synopsis>
char * PQoidStatus(const PGresult *res);
</synopsis>
+</para>
+
+<para>
This function is deprecated in favor of <function>PQoidValue</function>
and is not thread-safe.
</para>
</listitem>
-</itemizedlist>
+</varlistentry>
+</variablelist>
</sect2>
</sect1>
<sect1 id="libpq-async">
-<title>Asynchronous Query Processing</title>
+<title>Asynchronous Command Processing</title>
<indexterm zone="libpq-async"><primary>nonblocking connection</></>
<para>
The <function>PQexec</function> function is adequate for submitting commands in
-simple synchronous
-applications. It has a couple of major deficiencies however:
+normal, synchronous
+applications. It has a couple of deficiencies, however, that can be of importance to some users:
<itemizedlist>
<listitem>
</listitem>
<listitem>
<para>
-Since control is buried inside <function>PQexec</function>, it is hard for the frontend
-to decide it would like to try to cancel the ongoing command. (It can be
-done from a signal handler, but not otherwise.)
+Since the execution of the client application is suspended while it
+waits for the result, it is hard for the application to decide that it
+would like to try to cancel the ongoing command. (It can be done from
+a signal handler, but not otherwise.)
</para>
</listitem>
<listitem>
<para>
Older programs that used this functionality as well as
<function>PQputline</function> and <function>PQputnbytes</function>
-could block waiting to send data to the backend. To
+could block waiting to send data to the server. To
address that issue, the function <function>PQsetnonblocking</function>
was added.
-</para>
-<para>
Old applications can neglect to use <function>PQsetnonblocking</function>
-and get the older potentially blocking behavior. Newer programs can use
+and get the old potentially blocking behavior. Newer programs can use
<function>PQsetnonblocking</function> to achieve a completely nonblocking
-connection to the backend.
+connection to the server.
-<itemizedlist>
+<variablelist>
+<varlistentry>
+ <term><function>PQsetnonblocking</function></term>
<listitem>
<para>
- <function>PQsetnonblocking</function> Sets the nonblocking status of the
- connection.
+ Sets the nonblocking status of the connection.
<synopsis>
-int PQsetnonblocking(PGconn *conn, int arg)
+int PQsetnonblocking(PGconn *conn, int arg);
</synopsis>
- Sets the state of the connection to nonblocking if <parameter>arg</parameter> is 1,
+</para>
+
+<para>
+ Sets the state of the connection to nonblocking if <parameter>arg</parameter> is 1 and
blocking if <parameter>arg</parameter> is 0. Returns 0 if OK, -1 if error.
</para>
<para>
In the nonblocking state, calls to
<function>PQputline</function>, <function>PQputnbytes</function>,
- <function>PQsendQuery</function> and <function>PQendcopy</function>
+ <function>PQsendQuery</function>, and <function>PQendcopy</function>
will not block but instead return an error if they need to be called
again.
</para>
<para>
When a database connection has been set to nonblocking mode and
<function>PQexec</function> is called, it will temporarily set the state
- of the connection to blocking until the <function>PQexec</function>
+ of the connection to blocking until the <function>PQexec</function> call
completes.
</para>
<para>
More of <application>libpq</application> is expected to be made safe for
- <function>PQsetnonblocking</function> functionality in the near future.
+ the nonblocking mode in the future.
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQisnonblocking</function></term>
<listitem>
<para>
-<function>PQisnonblocking</function>
Returns the blocking status of the database connection.
<synopsis>
-int PQisnonblocking(const PGconn *conn)
+int PQisnonblocking(const PGconn *conn);
</synopsis>
- Returns 1 if the connection is set to nonblocking mode,
+</para>
+
+<para>
+ Returns 1 if the connection is set to nonblocking mode and
0 if blocking.
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQsendQuery</function></term>
<listitem>
<para>
-<function>PQsendQuery</function>
- Submit a command to the server without
+ Submits a command to the server without
waiting for the result(s). 1 is returned if the command was
- successfully dispatched, 0 if not (in which case, use
+ successfully dispatched and 0 if not (in which case, use
<function>PQerrorMessage</> to get more information about the failure).
<synopsis>
int PQsendQuery(PGconn *conn,
- const char *query);
+ const char *command);
</synopsis>
+</para>
+
+<para>
After successfully calling <function>PQsendQuery</function>, call
<function>PQgetResult</function> one or more
times to obtain the results. <function>PQsendQuery</function> may not be called
- again (on the same connection) until <function>PQgetResult</function> has returned NULL,
+ again (on the same connection) until <function>PQgetResult</function> has returned a null pointer,
indicating that the command is done.
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQgetResult</function></term>
<listitem>
<para>
-<function>PQgetResult</function>
- Wait for the next result from a prior <function>PQsendQuery</function>,
- and return it. NULL is returned when the query is complete
+ Waits for the next result from a prior <function>PQsendQuery</function>,
+ and return it. A null pointer is returned when the command is complete
and there will be no more results.
<synopsis>
PGresult *PQgetResult(PGconn *conn);
</synopsis>
- <function>PQgetResult</function> must be called repeatedly until it returns NULL,
+</para>
+
+<para>
+ <function>PQgetResult</function> must be called repeatedly until it returns a null pointer,
indicating that the command is done. (If called when no command is
- active, <function>PQgetResult</function> will just return NULL at once.)
- Each non-NULL result from <function>PQgetResult</function> should be processed using
+ active, <function>PQgetResult</function> will just return a null pointer at once.)
+ Each non-null result from <function>PQgetResult</function> should be processed using
the same <structname>PGresult</> accessor functions previously described.
Don't forget to free each result object with <function>PQclear</function> when done with it.
- Note that <function>PQgetResult</function> will block only if a query is active and the
+ Note that <function>PQgetResult</function> will block only if a command is active and the
necessary response data has not yet been read by <function>PQconsumeInput</function>.
</para>
</listitem>
-
-</itemizedlist>
+</varlistentry>
+</variablelist>
</para>
<para>
solves one of <function>PQexec</function>'s problems:
If a command string contains multiple <acronym>SQL</acronym> commands, the results of those
commands can be obtained individually. (This allows a simple form of
-overlapped processing, by the way: the frontend can be handling the
-results of one query while the backend is still working on later
+overlapped processing, by the way: the client can be handling the
+results of one command while the server is still working on later
queries in the same command string.) However, calling <function>PQgetResult</function> will
-still cause the frontend to block until the backend completes the
+still cause the client to block until the server completes the
next <acronym>SQL</acronym> command. This can be avoided by proper use of three more
functions:
-<itemizedlist>
+<variablelist>
+<varlistentry>
+<term><function>PQconsumeInput</function></term>
<listitem>
<para>
-<function>PQconsumeInput</function>
- If input is available from the backend, consume it.
+ If input is available from the server, consume it.
<synopsis>
int PQconsumeInput(PGconn *conn);
</synopsis>
+</para>
+
+<para>
<function>PQconsumeInput</function> normally returns 1 indicating <quote>no error</quote>,
but returns 0 if there was some kind of trouble (in which case
-<function>PQerrorMessage</function> is set). Note that the result does not say
+<function>PQerrorMessage</function> can be used). Note that the result does not say
whether any input data was actually collected. After calling
<function>PQconsumeInput</function>, the application may check
<function>PQisBusy</function> and/or <function>PQnotifies</function> to see if
<para>
<function>PQconsumeInput</function> may be called even if the application is not
prepared to deal with a result or notification just yet. The
-routine will read available data and save it in a buffer, thereby
+function will read available data and save it in a buffer, thereby
causing a <function>select()</function> read-ready indication to go away. The
application can thus use <function>PQconsumeInput</function> to clear the
<function>select()</function> condition immediately, and then examine the results at leisure.
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQisBusy</function></term>
<listitem>
<para>
-<function>PQisBusy</function>
-Returns 1 if a query is busy, that is, <function>PQgetResult</function> would block
+Returns 1 if a command is busy, that is, <function>PQgetResult</function> would block
waiting for input. A 0 return indicates that <function>PQgetResult</function> can
be called with assurance of not blocking.
<synopsis>
int PQisBusy(PGconn *conn);
</synopsis>
-<function>PQisBusy</function> will not itself attempt to read data from the backend;
+</para>
+
+<para>
+<function>PQisBusy</function> will not itself attempt to read data from the server;
therefore <function>PQconsumeInput</function> must be invoked first, or the busy
state will never end.
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQflush</function></term>
<listitem>
<para>
-<function>PQflush</function> Attempt to flush any data queued to the backend,
+Attempts to flush any data queued to the server,
returns 0 if successful (or if the send queue is empty) or <symbol>EOF</symbol> if it failed for
some reason.
<synopsis>
int PQflush(PGconn *conn);
</synopsis>
+</para>
+
+<para>
<function>PQflush</function> needs to be called on a nonblocking connection
before calling <function>select()</function> to determine if a response has
arrived. If 0 is returned it ensures that there is no data queued to the
-backend that has not actually been sent. Only applications that have used
+server that has not actually been sent. Only applications that have used
<function>PQsetnonblocking</function> have a need for this.
</para>
</listitem>
-
-<listitem>
-<para>
-<function>PQsocket</function>
- Obtain the file descriptor number for the backend connection socket.
- A valid descriptor will be >= 0; a result of -1 indicates that
- no backend connection is currently open.
-<synopsis>
-int PQsocket(const PGconn *conn);
-</synopsis>
-<function>PQsocket</function> should be used to obtain the backend socket descriptor
-in preparation for executing <function>select()</function>. This allows an
-application using a blocking connection to wait for either backend responses or
-other conditions.
-If the result of <function>select()</function> indicates that data can be read from
-the backend socket, then <function>PQconsumeInput</function> should be called to read the
-data; after which, <function>PQisBusy</function>, <function>PQgetResult</function>,
-and/or <function>PQnotifies</function> can be used to process the response.
-</para>
-<para>
-Nonblocking connections (that have used <function>PQsetnonblocking</function>)
-should not use <function>select()</function> until <function>PQflush</function>
-has returned 0 indicating that there is no buffered data waiting to be sent
-to the backend.
-</para>
-</listitem>
-
-</itemizedlist>
+</varlistentry>
+</variablelist>
</para>
<para>
-A typical frontend using these functions will have a main loop that uses
-<function>select</function> to wait for all the conditions that it must
-respond to. One of the conditions will be input available from the backend,
-which in <function>select</function>'s terms is readable data on the file
+A typical application using these functions will have a main loop that uses
+<function>select()</function> to wait for all the conditions that it must
+respond to. One of the conditions will be input available from the server,
+which in terms of <function>select()</function> means readable data on the file
descriptor identified by <function>PQsocket</function>.
When the main loop detects input ready, it should call
<function>PQconsumeInput</function> to read the input. It can then call
<function>PQisBusy</function>, followed by <function>PQgetResult</function>
if <function>PQisBusy</function> returns false (0). It can also call
-<function>PQnotifies</function> to detect <command>NOTIFY</command>
-messages (see <xref linkend="libpq-notify">).
+<function>PQnotifies</function> to detect <command>NOTIFY</> messages (see <xref linkend="libpq-notify">).
</para>
<para>
-A frontend that uses <function>PQsendQuery</function>/<function>PQgetResult</function>
-can also attempt to cancel a command that is still being processed by the backend.
+Nonblocking connections (that have used <function>PQsetnonblocking</function>)
+should not use <function>select()</function> until <function>PQflush</function>
+has returned 0 indicating that there is no buffered data waiting to be sent
+to the server.
</para>
<para>
-<itemizedlist>
+A client that uses <function>PQsendQuery</function>/<function>PQgetResult</function>
+can also attempt to cancel a command that is still being processed by the server.
+
+<variablelist>
+<varlistentry>
+<term><function>PQrequestCancel</function></term>
<listitem>
<para>
-<function>PQrequestCancel</function>
- Request that <productname>PostgreSQL</productname> abandon
+ Requests that the server abandon
processing of the current command.
<synopsis>
int PQrequestCancel(PGconn *conn);
</synopsis>
+</para>
+
+<para>
The return value is 1 if the cancel request was successfully
-dispatched, 0 if not. (If not, <function>PQerrorMessage</function> tells why not.)
+dispatched and 0 if not. (If not, <function>PQerrorMessage</function> tells why not.)
Successful dispatch is no guarantee that the request will have any
effect, however. Regardless of the return value of <function>PQrequestCancel</function>,
the application must continue with the normal result-reading
sequence using <function>PQgetResult</function>. If the cancellation
is effective, the current command will terminate early and return
an error result. If the cancellation fails (say, because the
-backend was already done processing the command), then there will
+server was already done processing the command), then there will
be no visible result at all.
</para>
-</listitem>
-</itemizedlist>
-</para>
<para>
-Note that if the current command is part of a transaction, cancellation
+Note that if the current command is part of a transaction block, cancellation
will abort the whole transaction.
</para>
So, it is also possible to use it in conjunction with plain
<function>PQexec</function>, if the decision to cancel can be made in a signal
handler. For example, <application>psql</application> invokes
-<function>PQrequestCancel</function> from a <systemitem>SIGINT</> signal handler, thus allowing
-interactive cancellation of queries that it issues through <function>PQexec</function>.
-Note that <function>PQrequestCancel</function> will have no effect if the connection
-is not currently open or the backend is not currently processing a command.
+<function>PQrequestCancel</function> from a <symbol>SIGINT</> signal handler, thus allowing
+interactive cancellation of commands that it issues through <function>PQexec</function>.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
</para>
</sect1>
<para>
<productname>PostgreSQL</productname> provides a fast-path interface to send
-function calls to the backend. This is a trapdoor into system internals and
+function calls to the server. This is a trapdoor into system internals and
can be a potential security hole. Most users will not need this feature.
+</para>
-<itemizedlist>
-<listitem>
<para>
-<function>PQfn</function>
- Request execution of a backend function via the fast-path interface.
+The function <function>PQfn</function> requests execution of a server
+function via the fast-path interface:
<synopsis>
PGresult* PQfn(PGconn* conn,
int fnid,
int result_is_int,
const PQArgBlock *args,
int nargs);
-</synopsis>
- The <parameter>fnid</> argument is the object identifier of the function to be
- executed.
- <parameter>result_buf</parameter> is the buffer in which
- to place the return value. The caller must have allocated
- sufficient space to store the return value (there is no check!).
- The actual result length will be returned in the integer pointed
- to by <parameter>result_len</parameter>. If a 4-byte integer result is expected, set
- <parameter>result_is_int</parameter> to 1; otherwise set it to 0. (Setting <parameter>result_is_int</parameter> to 1
- tells <application>libpq</> to byte-swap the value if necessary, so that it is
- delivered as a proper int value for the client machine. When
- <parameter>result_is_int</> is 0, the byte string sent by the backend is returned
- unmodified.)
- <parameter>args</> and <parameter>nargs</> specify the arguments to be passed to the function.
-<synopsis>
+
typedef struct {
int len;
int isint;
} u;
} PQArgBlock;
</synopsis>
- <function>PQfn</function> always returns a valid <structname>PGresult*</structname>. The result status
+</para>
+
+<para>
+ The <parameter>fnid</> argument is the OID of the function to be
+ executed.
+ <parameter>result_buf</parameter> is the buffer in which
+ to place the return value. The caller must have allocated
+ sufficient space to store the return value. (There is no check!)
+ The actual result length will be returned in the integer pointed
+ to by <parameter>result_len</parameter>. If a 4-byte integer result is expected, set
+ <parameter>result_is_int</parameter> to 1, otherwise set it to 0. (Setting <parameter>result_is_int</parameter> to 1
+ tells <application>libpq</> to byte-swap the value if necessary, so that it is
+ delivered as a proper <type>int</type> value for the client machine. When
+ <parameter>result_is_int</> is 0, the byte string sent by the server is returned
+ unmodified.)
+ <parameter>args</> and <parameter>nargs</> specify the arguments to be passed to the function.
+</para>
+
+<para>
+ <function>PQfn</function> always returns a valid <structname>PGresult</structname> pointer. The result status
should be checked before the result is used. The
caller is responsible for freeing the <structname>PGresult</structname> with
<function>PQclear</function> when it is no longer needed.
</para>
-</listitem>
-</itemizedlist>
-</para>
</sect1>
<indexterm zone="libpq-notify"><primary>NOTIFY</primary></indexterm>
<para>
-<productname>PostgreSQL</productname> supports asynchronous notification via the
-<command>LISTEN</command> and <command>NOTIFY</command> commands. A backend registers its interest in a particular
+<productname>PostgreSQL</productname> offers asynchronous notification via the
+<command>LISTEN</command> and <command>NOTIFY</command> commands. A server-side session registers its interest in a particular
notification condition with the <command>LISTEN</command> command (and can stop listening
-with the <command>UNLISTEN</command> command). All backends listening on a
-particular condition will be notified asynchronously when a <command>NOTIFY</command> of that
-condition name is executed by any backend. No additional information is
+with the <command>UNLISTEN</command> command). All sessions listening on a
+particular condition will be notified asynchronously when a <command>NOTIFY</command> command with that
+condition name is executed by any session. No additional information is
passed from the notifier to the listener. Thus, typically, any actual data
-that needs to be communicated is transferred through a database relation.
-Commonly the condition name is the same as the associated relation, but it is
-not necessary for there to be any associated relation.
+that needs to be communicated is transferred through a database table.
+Commonly, the condition name is the same as the associated table, but it is
+not necessary for there to be any associated table.
</para>
<para>
-<filename>libpq</filename> applications submit <command>LISTEN</command> and <command>UNLISTEN</command>
-commands as ordinary SQL command. Subsequently, arrival of <command>NOTIFY</command>
-messages can be detected by calling <function>PQnotifies</function>.
+<application>libpq</application> applications submit <command>LISTEN</command> and <command>UNLISTEN</command>
+commands as ordinary SQL command. The arrival of <command>NOTIFY</command>
+messages can subsequently be detected by calling <function>PQnotifies</function>.
+</para>
-<itemizedlist>
-<listitem>
<para>
-<function>PQnotifies</function>
- Returns the next notification from a list of unhandled
- notification messages received from the backend. Returns NULL if
+The function <function>PQnotifies</function>
+ returns the next notification from a list of unhandled
+ notification messages received from the server. It returns a null pointer if
there are no pending notifications. Once a notification is
returned from <function>PQnotifies</>, it is considered handled and will be
removed from the list of notifications.
PGnotify* PQnotifies(PGconn *conn);
typedef struct pgNotify {
- char *relname; /* name of relation containing data */
- int be_pid; /* process id of backend */
+ char *relname; /* notification name */
+ int be_pid; /* process ID of server process */
} PGnotify;
</synopsis>
After processing a <structname>PGnotify</structname> object returned by <function>PQnotifies</function>,
be sure to free it with <function>free()</function> to avoid a memory leak.
</para>
+
<note>
<para>
In <productname>PostgreSQL</productname> 6.4 and later,
- the <literal>be_pid</literal> is that of the notifying backend,
- whereas in earlier versions it was always the <acronym>PID</acronym> of your own backend.
+ the <literal>be_pid</literal> is that of the notifying backend process,
+ whereas in earlier versions it was always the <acronym>PID</acronym> of your own backend process.
</para>
</note>
-</listitem>
-</itemizedlist>
-</para>
<para>
-The second sample program gives an example of the use
+<xref linkend="libpq-example-2"> gives a sample program that illustrates the use
of asynchronous notification.
</para>
<para>
-<function>PQnotifies()</function> does not actually read backend data; it just
+<function>PQnotifies()</function> does not actually read data from the server; it just
returns messages previously absorbed by another <application>libpq</application>
function. In prior releases of <application>libpq</application>, the only way
-to ensure timely receipt of <command>NOTIFY</command> messages was to constantly submit queries,
+to ensure timely receipt of <command>NOTIFY</> messages was to constantly submit commands,
even empty ones, and then check <function>PQnotifies()</function> after each
<function>PQexec()</function>. While this still works, it is
deprecated as a waste of processing power.
</para>
+
<para>
-A better way to check for <command>NOTIFY</command>
-messages when you have no useful queries to make is to call
+A better way to check for <command>NOTIFY</>
+messages when you have no useful commands to execute is to call
<function>PQconsumeInput()</function>, then check
<function>PQnotifies()</function>.
-You can use <function>select()</function> to wait for backend data to
-arrive, thereby using no <acronym>CPU</acronym> power unless there is something
+You can use <function>select()</function> to wait for data to
+arrive from the server, thereby using no <acronym>CPU</acronym> power unless there is something
to do. (See <function>PQsocket()</function> to obtain the file descriptor
number to use with <function>select()</function>.)
-Note that this will work OK whether you submit queries with
+Note that this will work OK whether you submit commands with
<function>PQsendQuery</function>/<function>PQgetResult</function> or simply
use <function>PQexec</function>. You should, however, remember to
check <function>PQnotifies()</function> after each
<function>PQgetResult</function> or <function>PQexec</function>, to see
-if any notifications came in during the processing of the query.
+if any notifications came in during the processing of the command.
</para>
</sect1>
<sect1 id="libpq-copy">
-<title>Functions Associated with the COPY Command</title>
+<title>Functions Associated with the <command>COPY</command> Command</title>
<indexterm zone="libpq-copy">
<primary>COPY</primary>
</indexterm>
<para>
- The COPY command in <productname>PostgreSQL</productname> has options to read from
- or write to the network connection used by <filename>libpq</filename>.
+ The <command>COPY</command> command in <productname>PostgreSQL</productname> has options to read from
+ or write to the network connection used by <application>libpq</application>.
Therefore, functions are necessary to access this network
connection directly so applications may take advantage of this capability.
</para>
<para>
- These functions should be executed only after obtaining a <literal>PGRES_COPY_OUT</literal>
- or <literal>PGRES_COPY_IN</literal> result object from <function>PQexec</function>
- or <function>PQgetResult</function>.
+ These functions should be executed only after obtaining a result
+ status of <literal>PGRES_COPY_OUT</literal> or
+ <literal>PGRES_COPY_IN</literal> from <function>PQexec</function> or
+ <function>PQgetResult</function>.
</para>
-<para>
-<itemizedlist>
+<variablelist>
+<varlistentry>
+<term><function>PQgetline</function></term>
<listitem>
<para>
-<function>PQgetline</function>
Reads a newline-terminated line of characters
- (transmitted by the backend server) into a buffer
- string of size length.
+ (transmitted by the server) into a buffer
+ string of size <parameter>length</>.
<synopsis>
int PQgetline(PGconn *conn,
- char *string,
- int length)
+ char *buffer,
+ int length);
</synopsis>
-Like <function>fgets</function>, this routine copies up to length-1 characters
-into string. It is like <function>gets</function>, however, in that it converts
+</para>
+
+<para>
+This function copies up to <parameter>length</>-1 characters
+into the buffer and converts
the terminating newline into a zero byte.
<function>PQgetline</function> returns <symbol>EOF</symbol> at the end of input, 0 if the
entire line has been read, and 1 if the buffer is full but the
terminating newline has not yet been read.
</para>
<para>
-Notice that the application must check to see if a
+Note that the application must check to see if a
new line consists of the two characters <literal>\.</literal>,
-which indicates that the backend server has finished sending
-the results of the copy command.
+which indicates that the server has finished sending
+the results of the <command>COPY</command> command.
If the application might
-receive lines that are more than length-1 characters long,
-care is needed to be sure one recognizes the <literal>\.</literal> line correctly
+receive lines that are more than <parameter>length</>-1 characters long,
+care is needed to be sure it recognizes the <literal>\.</literal> line correctly
(and does not, for example, mistake the end of a long data line
for a terminator line).
-The code in
-<filename>
-src/bin/psql/copy.c
-</filename>
-contains example routines that correctly handle the copy protocol.
+The code in the file
+<filename>src/bin/psql/copy.c</filename>
+contains example functions that correctly handle the <command>COPY</command> protocol.
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQgetlineAsync</function></term>
<listitem>
<para>
-<function>PQgetlineAsync</function>
Reads a newline-terminated line of characters
- (transmitted by the backend server) into a buffer
+ (transmitted by the server) into a buffer
without blocking.
<synopsis>
int PQgetlineAsync(PGconn *conn,
char *buffer,
- int bufsize)
+ int length);
</synopsis>
-This routine is similar to <function>PQgetline</function>, but it can be used
+</para>
+
+<para>
+This function is similar to <function>PQgetline</function>, but it can be used
by applications
-that must read COPY data asynchronously, that is without blocking.
-Having issued the COPY command and gotten a <literal>PGRES_COPY_OUT</literal>
+that must read <command>COPY</command> data asynchronously, that is, without blocking.
+Having issued the <command>COPY</command> command and gotten a <literal>PGRES_COPY_OUT</literal>
response, the
application should call <function>PQconsumeInput</function> and
<function>PQgetlineAsync</function> until the
-end-of-data signal is detected. Unlike <function>PQgetline</function>, this routine takes
+end-of-data signal is detected.
+</para>
+<para>
+Unlike <function>PQgetline</function>, this function takes
responsibility for detecting end-of-data.
On each call, <function>PQgetlineAsync</function> will return data if a complete newline-
terminated data line is available in <application>libpq</>'s input buffer, or if the
incoming data line is too long to fit in the buffer offered by the caller.
Otherwise, no data is returned until the rest of the line arrives.
-</para>
-<para>
-The routine returns -1 if the end-of-copy-data marker has been recognized,
+The function returns -1 if the end-of-copy-data marker has been recognized,
or 0 if no data is available, or a positive number giving the number of
bytes of data returned. If -1 is returned, the caller must next call
<function>PQendcopy</function>, and then return to normal processing.
+</para>
+<para>
The data returned will not extend beyond a newline character. If possible
a whole line will be returned at one time. But if the buffer offered by
-the caller is too small to hold a line sent by the backend, then a partial
+the caller is too small to hold a line sent by the server, then a partial
data line will be returned. This can be detected by testing whether the
last returned byte is <literal>\n</literal> or not.
The returned string is not null-terminated. (If you want to add a
-terminating null, be sure to pass a <parameter>bufsize</parameter> one smaller than the room
+terminating null, be sure to pass a <parameter>length</parameter> one smaller than the room
actually available.)
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQputline</function></term>
<listitem>
<para>
-<function>PQputline</function>
-Sends a null-terminated string to the backend server.
-Returns 0 if OK, <symbol>EOF</symbol> if unable to send the string.
+Sends a null-terminated string to the server.
+Returns 0 if OK and <symbol>EOF</symbol> if unable to send the string.
<synopsis>
int PQputline(PGconn *conn,
const char *string);
</synopsis>
+</para>
+
+<para>
Note the application must explicitly send the two
characters <literal>\.</literal> on a final line to indicate to
-the backend that it has finished sending its data.
+the server that it has finished sending its data.
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQputnbytes</function></term>
<listitem>
<para>
-<function>PQputnbytes</function>
-Sends a non-null-terminated string to the backend server.
-Returns 0 if OK, <symbol>EOF</symbol> if unable to send the string.
+Sends a non-null-terminated string to the server.
+Returns 0 if OK and <symbol>EOF</symbol> if unable to send the string.
<synopsis>
int PQputnbytes(PGconn *conn,
const char *buffer,
int nbytes);
</synopsis>
+</para>
+
+<para>
This is exactly like <function>PQputline</function>, except that the data buffer need
not be null-terminated since the number of bytes to send is
specified directly.
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQendcopy</function></term>
<listitem>
<para>
-<function>PQendcopy</function>
- Synchronizes with the backend. This function waits until
- the backend has finished the copy. It should
+ Synchronizes with the server.
+<synopsis>
+int PQendcopy(PGconn *conn);
+</synopsis>
+ This function waits until
+ the server has finished the copying. It should
either be issued when the last string has been
- sent to the backend using <function>PQputline</function> or when the
- last string has been received from the backend
- using <function>PGgetline</function>. It must be issued or the backend
- may get <quote>out of sync</quote> with the frontend. Upon
- return from this function, the backend is ready to
+ sent to the server using <function>PQputline</function> or when the
+ last string has been received from the server
+ using <function>PGgetline</function>. It must be issued or the server
+ may get <quote>out of sync</quote> with the client. Upon
+ return from this function, the server is ready to
receive the next SQL command.
The return value is 0 on successful completion,
nonzero otherwise.
-<synopsis>
-int PQendcopy(PGconn *conn);
-</synopsis>
-</para>
-
-<para>
-As an example:
-
-<programlisting>
-PQexec(conn, "CREATE TABLE foo (a int4, b char(16), d double precision)");
-PQexec(conn, "COPY foo FROM STDIN");
-PQputline(conn, "3\thello world\t4.5\n");
-PQputline(conn,"4\tgoodbye world\t7.11\n");
-...
-PQputline(conn,"\\.\n");
-PQendcopy(conn);
-</programlisting>
-</para>
-</listitem>
-</itemizedlist>
</para>
<para>
a <literal>PGRES_COPY_OUT</literal> result by executing <function>PQgetline</function>
repeatedly, followed by <function>PQendcopy</function> after the terminator line is seen.
It should then return to the <function>PQgetResult</function> loop until
-<function>PQgetResult</function> returns NULL. Similarly a <literal>PGRES_COPY_IN</literal>
+<function>PQgetResult</function> returns a null pointer. Similarly a <literal>PGRES_COPY_IN</literal>
result is processed by a series of <function>PQputline</function> calls followed by
<function>PQendcopy</function>, then return to the <function>PQgetResult</function> loop.
This arrangement will ensure that
-a copy in or copy out command embedded in a series of <acronym>SQL</acronym> commands
+a <command>COPY</command> command embedded in a series of <acronym>SQL</acronym> commands
will be executed correctly.
</para>
+
<para>
-Older applications are likely to submit a copy in or copy out
+Older applications are likely to submit a <command>COPY</command>
via <function>PQexec</function> and assume that the transaction is done after
<function>PQendcopy</function>.
-This will work correctly only if the copy in/out is the only
+This will work correctly only if the <command>COPY</command> is the only
<acronym>SQL</acronym> command in the command string.
</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+<para>
+An example:
+
+<programlisting>
+PQexec(conn, "CREATE TABLE foo (a integer, b varchar(16), d double precision);");
+PQexec(conn, "COPY foo FROM STDIN;");
+PQputline(conn, "3\thello world\t4.5\n");
+PQputline(conn, "4\tgoodbye world\t7.11\n");
+...
+PQputline(conn, "\\.\n");
+PQendcopy(conn);
+</programlisting>
+</para>
</sect1>
<sect1 id="libpq-trace">
-<title><application>libpq</application> Tracing Functions</title>
+<title>Tracing Functions</title>
-<para>
-<itemizedlist>
+<variablelist>
+<varlistentry>
+<term><function>PQtrace</function></term>
<listitem>
<para>
-<function>PQtrace</function>
- Enable tracing of the frontend/backend communication to a debugging file stream.
+ Enables tracing of the client/server communication to a debugging file stream.
<synopsis>
void PQtrace(PGconn *conn
- FILE *debug_port)
+ FILE *stream);
</synopsis>
</para>
</listitem>
+</varlistentry>
+<varlistentry>
+<term><function>PQuntrace</function></term>
<listitem>
<para>
-<function>PQuntrace</function>
- Disable tracing started by <function>PQtrace</function>.
+ Disables tracing started by <function>PQtrace</function>.
<synopsis>
-void PQuntrace(PGconn *conn)
+void PQuntrace(PGconn *conn);
</synopsis>
</para>
</listitem>
-</itemizedlist>
-</para>
+</varlistentry>
+</variablelist>
</sect1>
<sect1 id="libpq-control">
-<title><application>libpq</application> Control Functions</title>
+<title>Notice Processing</title>
<para>
-<itemizedlist>
-<listitem>
-<para>
-<function>PQsetNoticeProcessor</function>
+The function <function>PQsetNoticeProcessor</function>
<indexterm><primary>notice processor</></>
-Control reporting of notice and warning messages generated by <application>libpq</>.
+controls the reporting of notice and warning messages generated by the server.
<synopsis>
typedef void (*PQnoticeProcessor) (void *arg, const char *message);
void *arg);
</synopsis>
</para>
-</listitem>
-</itemizedlist>
-</para>
<para>
-By default, <application>libpq</application> prints notice
-messages from the backend on <filename>stderr</filename>,
-as well as a few error messages that it generates by itself.
+By default, <application>libpq</application> prints notice messages
+from the server, as well as a few error messages that it generates by
+itself, on <filename>stderr</filename>.
This behavior can be overridden by supplying a callback function that
-does something else with the messages. The callback function is passed
-the text of the error message (which includes a trailing newline), plus
+does something else with the messages, a so-called notice processor.
+The callback function is passed
+the text of the message (which includes a trailing newline), plus
a void pointer that is the same one passed to
<function>PQsetNoticeProcessor</function>.
(This pointer can be used to access application-specific state if needed.)
<para>
The return value is the pointer to the previous notice processor.
-If you supply a callback function pointer of NULL, no action is taken,
+If you supply a null callback function pointer, no action is taken,
but the current pointer is returned.
</para>
could be called as long as either the <structname>PGconn</> object or <structname>PGresult</> objects
made from it exist. At creation of a <structname>PGresult</>, the <structname>PGconn</>'s current
notice processor pointer is copied into the <structname>PGresult</> for possible use by
-routines like <function>PQgetvalue</function>.
+functions like <function>PQgetvalue</function>.
</para>
</sect1>
<function>PQconnectdb</>, <function>PQsetdbLogin</> and
<function>PQsetdb</> if no value is directly specified by the calling
code. These are useful to avoid hard-coding database connection
-information into simple client applications.
+information into simple client applications, for example.
<itemizedlist>
<listitem>
</indexterm>
<envar>PGPORT</envar> sets the default TCP port number or Unix-domain
socket file extension for communicating with the
-<productname>PostgreSQL</productname> backend.
+<productname>PostgreSQL</productname> server.
</para>
</listitem>
<listitem>
<primary><envar>PGUSER</envar></primary>
</indexterm>
<envar>PGUSER</envar>
-sets the user name used to connect to the database and for authentication.
+sets the user name used to connect to the database.
</para>
</listitem>
<listitem>
<primary><envar>PGPASSWORD</envar></primary>
</indexterm>
<envar>PGPASSWORD</envar>
-sets the password used if the backend demands password
-authentication. This functionality is deprecated for security
-reasons; consider migrating to use the <link linkend='pgpassfile'>
-<filename>$HOME/.pgpass</></link>
-file.
+sets the password used if the server demands password
+authentication. This environment variable is deprecated for security
+reasons; consider migrating to use the <filename>$HOME/.pgpass</>
+file (see <xref linkend="libpq-pgpass">).
</para>
</listitem>
<listitem>
<para>
<envar>PGREALM</envar> sets the Kerberos realm to use with
<productname>PostgreSQL</productname>, if it is different from the local realm.
-If <envar>PGREALM</envar> is set, <productname>PostgreSQL</productname>
+If <envar>PGREALM</envar> is set, <application>libpq</application>
applications will attempt authentication with servers for this realm and use
separate ticket files to avoid conflicts with local
ticket files. This environment variable is only
-used if Kerberos authentication is selected by the backend.
+used if Kerberos authentication is selected by the server.
</para>
</listitem>
<listitem>
<para>
<envar>PGOPTIONS</envar> sets additional run-time options for
-the <productname>PostgreSQL</productname> backend.
+the <productname>PostgreSQL</productname> server.
</para>
</listitem>
<listitem>
<para>
-<envar>PGTTY</envar> sets the file or tty on which debugging
-messages from the backend server are displayed.
+<envar>PGTTY</envar> sets the file or <acronym>TTY</> on which debugging
+messages from the server are displayed.
</para>
</listitem>
<listitem>
</para>
<para>
-The following environment variables can be used to specify user-level default
-behavior for every <productname>PostgreSQL</productname> session:
+The following environment variables can be used to specify default
+behavior for every <productname>PostgreSQL</productname> session.
<itemizedlist>
<listitem>
<para>
<envar>PGDATESTYLE</envar>
sets the default style of date/time representation.
+(Equivalent to <literal>SET datestyle TO ...</literal>.)
</para>
</listitem>
<listitem>
<para>
<envar>PGTZ</envar>
sets the default time zone.
+(Equivalent to <literal>SET timezone TO ...</literal>.)
</para>
</listitem>
<listitem>
<para>
<envar>PGCLIENTENCODING</envar>
-sets the default client encoding.
+sets the default client character set encoding.
+(Equivalent to <literal>SET client_encoding TO ...</literal>.)
</para>
</listitem>
-</itemizedlist>
-</para>
-
-<para>
-The following environment variables can be used to specify default internal
-behavior for every <productname>PostgreSQL</productname> session:
-
-<itemizedlist>
<listitem>
<para>
<envar>PGGEQO</envar>
-sets the default mode for the genetic optimizer.
+sets the default mode for the genetic query optimizer.
+(Equivalent to <literal>SET geqo TO ...</literal>.)
</para>
</listitem>
</itemizedlist>
-</para>
-<para>
-Refer to the <command>SET</command> <acronym>SQL</acronym> command
+Refer to the <acronym>SQL</acronym> command <command>SET</command>
for information on correct values for these environment variables.
</para>
</sect1>
-<sect1 id="libpq-files">
-<title>Files</title>
+<sect1 id="libpq-pgpass">
+<title>The Password File</title>
-<indexterm zone="libpq-files">
- <primary>files</primary>
+<indexterm zone="libpq-pgpass">
+ <primary>password file</primary>
</indexterm>
-<para>
-<anchor id="pgpassfile">
-<indexterm>
- <primary>password</primary>
- <secondary>.pgpass</secondary>
+<indexterm zone="libpq-pgpass">
+ <primary>.pgpass</primary>
</indexterm>
-The <filename>.pgpass</filename> file in a user's home directory is a
-file that can contain passwords to be used if the connection requires
-a password. This file should have the format:
+
+<para>
+The file <filename>.pgpass</filename> in a user's home directory is a file
+that can contain passwords to be used if the connection requires a
+password (and no password has been specified otherwise).
+This file should have lines of the following format:
<synopsis>
<replaceable>hostname</replaceable>:<replaceable>port</replaceable>:<replaceable>database</replaceable>:<replaceable>username</replaceable>:<replaceable>password</replaceable>
</synopsis>
-Any of these may be a literal name, or <literal>*</literal>, which
+Each of these fields may be a literal name or <literal>*</literal>, which
matches anything. The first matching entry will be used, so put more-specific
-entries first. When an entry contains <literal>:</literal> or
+entries first. When an entry contain <literal>:</literal> or
<literal>\</literal>, it must be escaped with <literal>\</literal>.
</para>
<para>
</indexterm>
<para>
-<filename>libpq</filename> is thread-safe as of
+<application>libpq</application> is thread-safe as of
<productname>PostgreSQL</productname> 7.0, so long as no two threads
attempt to manipulate the same <structname>PGconn</> object at the same
-time. In particular, you cannot issue concurrent queries from different
+time. In particular, you cannot issue concurrent commands from different
threads through the same connection object. (If you need to run
-concurrent queries, start up multiple connections.)
+concurrent commands, start up multiple connections.)
</para>
<para>
</para>
<para>
-<filename>Libpq</filename> clients using the <literal>crypt</literal>
-encryption method rely on the <literal>crypt()</literal> operating
-system function, which is often not thread-safe. It is better to use
-<literal>MD5</literal> encryption, which is thread-safe on all
+<application>libpq</application> applications that use the <literal>crypt</literal>
+authentication method rely on the <literal>crypt()</literal> operating
+system function, which is often not thread-safe. It is better to use the
+<literal>md5</literal> method, which is thread-safe on all
platforms.
</para>
</sect1>
<sect1 id="libpq-build">
- <title>Building <application>Libpq</application> Programs</title>
+ <title>Building <application>libpq</application> Programs</title>
<para>
To build (i.e., compile and link) your <application>libpq</application> programs you need to
<literal>-lpq</literal> so that the <application>libpq</application> library gets pulled
in, as well as the option
<literal>-L<replaceable>directory</replaceable></literal> to
- point it to the directory where the <application>libpq</application> library resides. (Again, the
+ point the compiler to the directory where the <application>libpq</application> library resides. (Again, the
compiler will search some directories by default.) For maximum
portability, put the <option>-L</option> option before the
<option>-lpq</option> option. For example:
<screen>
/usr/bin/ld: cannot find -lpq
</screen>
- This means you forgot the <option>-L</option> or did not specify
- the right path.
+ This means you forgot the <option>-L</option> option or did not specify
+ the right directory.
</para>
</listitem>
</itemizedlist>
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.27 2002/04/18 14:28:14 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.28 2003/03/13 01:30:28 petere Exp $
-->
<chapter id="largeObjects">
<indexterm zone="largeobjects"><primary>large object</></>
<indexterm><primary>BLOB</><see>large object</></>
- <sect1 id="lo-intro">
- <title>Introduction</title>
-
<para>
In <productname>PostgreSQL</productname> releases prior to 7.1,
the size of any row in the database could not exceed the size of a
size of a data value was relatively low. To support the storage of
larger atomic values, <productname>PostgreSQL</productname>
provided and continues to provide a large object interface. This
- interface provides file-oriented access to user data that has been
- declared to be a large object.
+ interface provides file-oriented access to user data that is stored in
+ a special large-object structure.
</para>
<para>
+ This chapter describes the implementation and the programming and
+ query language interfaces to <productname>PostgreSQL</productname>
+ large object data. We use the <application>libpq</application> C
+ library for the examples in this chapter, but most programming
+ interfaces native to <productname>PostgreSQL</productname> support
+ equivalent functionality. Other interfaces may use the large
+ object interface internally to provide generic support for large
+ values. This is not described here.
+ </para>
+
+ <sect1 id="lo-history">
+ <title>History</title>
+
+ <para>
<productname>POSTGRES 4.2</productname>, the indirect predecessor
of <productname>PostgreSQL</productname>, supported three standard
implementations of large objects: as files external to the
(nicknamed <quote><acronym>TOAST</acronym></quote>) that allows
data rows to be much larger than individual data pages. This
makes the large object interface partially obsolete. One
- remaining advantage of the large object interface is that it
- allows random access to the data, i.e., the ability to read or
- write small chunks of a large value. It is planned to equip
- <acronym>TOAST</acronym> with such functionality in the future.
- </para>
-
- <para>
- This section describes the implementation and the programming and
- query language interfaces to <productname>PostgreSQL</productname>
- large object data. We use the <application>libpq</application> C
- library for the examples in this section, but most programming
- interfaces native to <productname>PostgreSQL</productname> support
- equivalent functionality. Other interfaces may use the large
- object interface internally to provide generic support for large
- values. This is not described here.
+ remaining advantage of the large object interface is that it allows values up
+ to 2 GB in size, whereas <acronym>TOAST</acronym> can only handle 1 GB.
</para>
</sect1>
<para>
The large object implementation breaks large
objects up into <quote>chunks</quote> and stores the chunks in
- tuples in the database. A B-tree index guarantees fast
+ rows in the database. A B-tree index guarantees fast
searches for the correct chunk number when doing random
access reads and writes.
</para>
</sect1>
<sect1 id="lo-interfaces">
- <title>Interfaces</title>
+ <title>Client Interfaces</title>
<para>
- The facilities <productname>PostgreSQL</productname> provides to
- access large objects, both in the backend as part of user-defined
- functions or the front end as part of an application
- using the interface, are described below. For users
- familiar with <productname>POSTGRES 4.2</productname>,
- <productname>PostgreSQL</productname> has a new set of
- functions providing a more coherent interface.
-
- <note>
- <para>
- All large object manipulation <emphasis>must</emphasis> take
- place within an SQL transaction. This requirement is strictly
- enforced as of <productname>PostgreSQL 6.5</>, though it has been an
- implicit requirement in previous versions, resulting in
- misbehavior if ignored.
- </para>
- </note>
+ This section describes the facilities that
+ <productname>PostgreSQL</productname> client interface libraries
+ provide for accessing large objects. All large object
+ manipulation using these functions <emphasis>must</emphasis> take
+ place within an SQL transaction block. (This requirement is
+ strictly enforced as of <productname>PostgreSQL 6.5</>, though it
+ has been an implicit requirement in previous versions, resulting
+ in misbehavior if ignored.)
+ The <productname>PostgreSQL</productname> large object interface is modeled after
+ the <acronym>Unix</acronym> file-system interface, with analogues of
+ <function>open</function>, <function>read</function>,
+ <function>write</function>,
+ <function>lseek</function>, etc.
</para>
<para>
- The <productname>PostgreSQL</productname> large object interface is modeled after
- the <acronym>Unix</acronym> file-system interface, with analogues of
- <function>open(2)</function>, <function>read(2)</function>,
- <function>write(2)</function>,
- <function>lseek(2)</function>, etc. User
- functions call these routines to retrieve only the data of
- interest from a large object. For example, if a large
- object type called <type>mugshot</type> existed that stored
- photographs of faces, then a function called <function>beard</function> could
- be declared on <type>mugshot</type> data. <function>beard</> could look at the
- lower third of a photograph, and determine the color of
- the beard that appeared there, if any. The entire
- large-object value need not be buffered, or even
- examined, by the <function>beard</function> function.
- Large objects may be accessed from dynamically-loaded <acronym>C</acronym>
- functions or database client programs that link the
- library. <productname>PostgreSQL</productname> provides a set of routines that
- support opening, reading, writing, closing, and seeking on
- large objects.
+ Client applications which use the large object interface in
+ <application>libpq</application> should include the header file
+ <filename>libpq/libpq-fs.h</filename> and link with the
+ <application>libpq</application> library.
</para>
<sect2>
<title>Creating a Large Object</title>
<para>
- The routine
+ The function
<synopsis>
-Oid lo_creat(PGconn *<replaceable class="parameter">conn</replaceable>, int <replaceable class="parameter">mode</replaceable>)
+Oid lo_creat(PGconn *conn, int mode);
</synopsis>
creates a new large object.
<replaceable class="parameter">mode</replaceable> is a bit mask
historically been used at Berkeley to designate the storage manager number on which the large object
should reside. These
bits should always be zero now.
- The commands below create a large object:
+ The return value is the OID that was assigned to the new large object.
+ </para>
+
+ <para>
+ An example:
<programlisting>
inv_oid = lo_creat(INV_READ|INV_WRITE);
</programlisting>
<para>
To import an operating system file as a large object, call
<synopsis>
-Oid lo_import(PGconn *<replaceable class="parameter">conn</replaceable>, const char *<replaceable class="parameter">filename</replaceable>)
+Oid lo_import(PGconn *conn, const char *filename);
</synopsis>
<replaceable class="parameter">filename</replaceable>
specifies the operating system name of
the file to be imported as a large object.
+ The return value is the OID that was assigned to the new large object.
</para>
</sect2>
To export a large object
into an operating system file, call
<synopsis>
-int lo_export(PGconn *<replaceable class="parameter">conn</replaceable>, Oid <replaceable class="parameter">lobjId</replaceable>, const char *<replaceable class="parameter">filename</replaceable>)
+int lo_export(PGconn *conn, Oid lobjId, const char *filename);
</synopsis>
The <parameter>lobjId</parameter> argument specifies the OID of the large
object to export and the <parameter>filename</parameter> argument specifies
<para>
To open an existing large object, call
<synopsis>
-int lo_open(PGconn *conn, Oid lobjId, int mode)
+int lo_open(PGconn *conn, Oid lobjId, int mode);
</synopsis>
The <parameter>lobjId</parameter> argument specifies the OID of the large
object to open. The <parameter>mode</parameter> bits control whether the
<title>Writing Data to a Large Object</title>
<para>
- The routine
-<programlisting>
-int lo_write(PGconn *conn, int fd, const char *buf, size_t len)
-</programlisting>
+ The function
+<synopsis>
+int lo_write(PGconn *conn, int fd, const char *buf, size_t len);
+</synopsis>
writes <parameter>len</parameter> bytes from <parameter>buf</parameter> to large object <parameter>fd</>. The <parameter>fd</parameter>
argument must have been returned by a previous <function>lo_open</function>.
The number of bytes actually written is returned. In
<title>Reading Data from a Large Object</title>
<para>
- The routine
-<programlisting>
-int lo_read(PGconn *conn, int fd, char *buf, size_t len)
-</programlisting>
+ The function
+<synopsis>
+int lo_read(PGconn *conn, int fd, char *buf, size_t len);
+</synopsis>
reads <parameter>len</parameter> bytes from large object <parameter>fd</parameter> into <parameter>buf</parameter>. The <parameter>fd</parameter>
argument must have been returned by a previous <function>lo_open</function>.
The number of bytes actually read is returned. In
<para>
To change the current read or write location on a large
object, call
-<programlisting>
-int lo_lseek(PGconn *conn, int fd, int offset, int whence)
-</programlisting>
- This routine moves the current location pointer for the
+<synopsis>
+int lo_lseek(PGconn *conn, int fd, int offset, int whence);
+</synopsis>
+ This function moves the current location pointer for the
large object described by <parameter>fd</> to the new location specified
by <parameter>offset</>. The valid values for <parameter>whence</> are
- <symbol>SEEK_SET</>, <symbol>SEEK_CUR</>, and <symbol>SEEK_END</>.
+ <symbol>SEEK_SET</> (seek from object start), <symbol>SEEK_CUR</> (seek from current position), and <symbol>SEEK_END</> (seek from object end). The return value is the new location pointer.
+</para>
+</sect2>
+
+<sect2>
+<title>Obtaining the Seek Position of a Large Object</title>
+
+<para>
+ To obtain the current read or write location of a large object,
+ call
+<synopsis>
+int lo_tell(PGconn *conn, int fd);
+</synopsis>
+ If there is an error, the return value is negative.
</para>
</sect2>
<para>
A large object may be closed by calling
-<programlisting>
-int lo_close(PGconn *conn, int fd)
-</programlisting>
+<synopsis>
+int lo_close(PGconn *conn, int fd);
+</synopsis>
where <parameter>fd</> is a large object descriptor returned by
<function>lo_open</function>. On success, <function>lo_close</function>
returns zero. On error, the return value is negative.
<para>
To remove a large object from the database, call
<synopsis>
-int lo_unlink(PGconn *<replaceable class="parameter">conn</replaceable>, Oid lobjId)
+int lo_unlink(PGconn *conn, Oid lobjId);
</synopsis>
The <parameter>lobjId</parameter> argument specifies the OID of the large
object to remove. In the event of an error, the return value is negative.
</sect1>
<sect1 id="lo-funcs">
-<title>Server-side Built-in Functions</title>
+<title>Server-side Functions</title>
<para>
- There are two built-in registered functions, <function>lo_import</function>
- and <function>lo_export</function> which are convenient for use
+ There are two built-in server-side functions, <function>lo_import</function>
+ and <function>lo_export</function>, for large object access, which are available for use
in <acronym>SQL</acronym>
- queries.
- Here is an example of their use
+ commands.
+ Here is an example of their use:
<programlisting>
CREATE TABLE image (
name text,
</para>
</sect1>
-<sect1 id="lo-libpq">
-<title>Accessing Large Objects from <application>Libpq</application></title>
+<sect1 id="lo-examplesect">
+<title>Example Program</title>
<para>
<xref linkend="lo-example"> is a sample program which shows how the large object
interface
in <application>libpq</> can be used. Parts of the program are
commented out but are left in the source for the reader's
- benefit. This program can be found in
+ benefit. This program can also be found in
<filename>src/test/examples/testlo.c</filename> in the source distribution.
- Frontend applications which use the large object interface
- in <application>libpq</application> should include the header file
- <filename>libpq/libpq-fs.h</filename> and link with the <application>libpq</application> library.
</para>
<example id="lo-example">
- <title>Large Objects with <application>Libpq</application> Example Program</title>
+ <title>Large Objects with <application>libpq</application> Example Program</title>
<programlisting>
/*--------------------------------------------------------------
*
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/manage-ag.sgml,v 2.24 2002/11/15 03:11:17 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/manage-ag.sgml,v 2.25 2003/03/13 01:30:29 petere Exp $
-->
<chapter id="managing-databases">
them.
</para>
- <sect1>
+ <sect1 id="manage-ag-overview">
<title>Overview</title>
<para>
(<quote>database objects</quote>). Generally, every database
object (tables, functions, etc.) belongs to one and only one
database. (But there are a few system catalogs, for example
- <literal>pg_database</>, that belong to a whole installation and
- are accessible from each database within the installation.) More
+ <literal>pg_database</>, that belong to a whole cluster and
+ are accessible from each database within the cluster.) More
accurately, a database is a collection of schemas and the schemas
contain the tables, functions, etc. So the full hierarchy is:
server, database, schema, table (or something else instead of a
</para>
<para>
- Databases are created with the query language command
+ Databases are created with the SQL command
<command>CREATE DATABASE</command>:
<synopsis>
-CREATE DATABASE <replaceable>name</>
+CREATE DATABASE <replaceable>name</>;
</synopsis>
where <replaceable>name</> follows the usual rules for
<acronym>SQL</acronym> identifiers. The current user automatically
question remains how the <emphasis>first</> database at any given
site can be created. The first database is always created by the
<command>initdb</> command when the data storage area is
- initialized. (See <xref linkend="creating-cluster">.) By convention
- this database is called <literal>template1</>. So to create the
+ initialized. (See <xref linkend="creating-cluster">.)
+ This database is called <literal>template1</>. So to create the
first <quote>real</> database you can connect to
<literal>template1</>.
</para>
<para>
- The name <quote>template1</quote> is no accident: When a new
+ The name <literal>template1</literal> is no accident: When a new
database is created, the template database is essentially cloned.
This means that any changes you make in <literal>template1</> are
propagated to all subsequently created databases. This implies that
createdb <replaceable class="parameter">dbname</replaceable>
</synopsis>
- <command>createdb</> does no magic. It connects to the template1
+ <command>createdb</> does no magic. It connects to the <literal>template1</>
database and issues the <command>CREATE DATABASE</> command,
- exactly as described above. It uses the <application>psql</> program
+ exactly as described above. It uses the <command>psql</> program
internally. The reference page on <command>createdb</> contains the invocation
details. Note that <command>createdb</> without any arguments will create
a database with the current user name, which may or may not be what
<literal>template1</>, that is, only the standard objects predefined by
your version of <productname>PostgreSQL</productname>.
<literal>template0</> should never be changed
- after <literal>initdb</>. By instructing <command>CREATE DATABASE</> to
+ after <command>initdb</>. By instructing <command>CREATE DATABASE</> to
copy <literal>template0</> instead of <literal>template1</>, you can
create a <quote>virgin</> user database that contains none of the
site-local additions in <literal>template1</>. This is particularly
<para>
It is possible to create additional template databases, and indeed
- one might copy any database in an installation by specifying its name
+ one might copy any database in a cluster by specifying its name
as the template for <command>CREATE DATABASE</>. It is important to
understand, however, that this is not (yet) intended as
a general-purpose <quote><command>COPY DATABASE</command></quote> facility. In particular, it is
in progress)
for the duration of the copying operation. <command>CREATE DATABASE</>
will check
- that no backend processes (other than itself) are connected to
+ that no session (other than itself) is connected to
the source database at the start of the operation, but this does not
guarantee that changes cannot be made while the copy proceeds, which
would result in an inconsistent copied database. Therefore,
If <literal>datallowconn</literal> is false, then no new connections
to that database will be allowed (but existing sessions are not killed
simply by setting the flag false). The <literal>template0</literal>
- database is normally marked <literal>datallowconn</literal> =
- <literal>false</> to prevent modification of it.
+ database is normally marked <literal>datallowconn = false</> to prevent modification of it.
Both <literal>template0</literal> and <literal>template1</literal>
- should always be marked with <literal>datistemplate</literal> =
- <literal>true</>.
+ should always be marked with <literal>datistemplate = true</>.
</para>
<para>
it is a good idea to perform
<command>VACUUM FREEZE</> or <command>VACUUM FULL FREEZE</> in that
database. If this is done when there are no other open transactions
- in the same database, then it is guaranteed that all tuples in the
+ in the same database, then it is guaranteed that all rows in the
database are <quote>frozen</> and will not be subject to transaction
ID wraparound problems. This is particularly important for a database
that will have <literal>datallowconn</literal> set to false, since it
- will be impossible to do routine maintenance <command>VACUUM</>s on
+ will be impossible to do routine maintenance <command>VACUUM</> in
such a database.
See <xref linkend="vacuum-for-wraparound"> for more information.
</para>
<para>
It is possible to create a database in a location other than the
- default location for the installation. Remember that all database access
+ default location for the installation. But remember that all database access
occurs through the
database server, so any location specified must be
accessible by the server.
<para>
To create the variable in the environment of the server process
you must first shut down the server, define the variable,
- initialize the data area, and finally restart the server. (See
+ initialize the data area, and finally restart the server. (See also
<xref linkend="postmaster-shutdown"> and <xref
linkend="postmaster-start">.) To set an environment variable, type
<programlisting>
<programlisting>
setenv PGDATA2 /home/postgres/data
</programlisting>
- in <application>csh</> or <application>tcsh</>. You have to make sure that this environment
+ in <command>csh</> or <command>tcsh</>. You have to make sure that this environment
variable is always defined in the server environment, otherwise
you won't be able to access that database. Therefore you probably
want to set it in some sort of shell start-up file or server
<para>
To create a database within the new location, use the command
<synopsis>
-CREATE DATABASE <replaceable>name</> WITH LOCATION = '<replaceable>location</>'
+CREATE DATABASE <replaceable>name</> WITH LOCATION '<replaceable>location</>';
</synopsis>
where <replaceable>location</> is the environment variable you
used, <envar>PGDATA2</> in this example. The <command>createdb</>
<para>
Databases are destroyed with the command <command>DROP DATABASE</command>:
<synopsis>
-DROP DATABASE <replaceable>name</>
+DROP DATABASE <replaceable>name</>;
</synopsis>
- Only the owner of the database (i.e., the user that created it), or
+ Only the owner of the database (i.e., the user that created it) or
a superuser, can drop a database. Dropping a database removes all objects
that were
contained within the database. The destruction of a database cannot
You cannot execute the <command>DROP DATABASE</command> command
while connected to the victim database. You can, however, be
connected to any other database, including the <literal>template1</>
- database,
- which would be the only option for dropping the last user database of a
+ database.
+ <literal>template1</> would be the only option for dropping the last user database of a
given cluster.
</para>
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.33 2003/02/19 04:06:28 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.34 2003/03/13 01:30:29 petere Exp $
-->
<chapter id="mvcc">
<table tocentry="1" id="mvcc-isolevel-table">
<title><acronym>SQL</acronym> Transaction Isolation Levels</title>
- <titleabbrev>Isolation Levels</titleabbrev>
<tgroup cols="4">
<thead>
<row>
executed within its own transaction, even though they are not yet
committed.) In effect, a <command>SELECT</command> query
sees a snapshot of the database as of the instant that that query
- begins to run. Notice that two successive <command>SELECT</command>s can
+ begins to run. Notice that two successive <command>SELECT</command> commands can
see different data, even though they are within a single transaction, if
other transactions
commit changes during execution of the first <command>SELECT</command>.
<command>UPDATE</command>, <command>DELETE</command>, and <command>SELECT
FOR UPDATE</command> commands behave the same as <command>SELECT</command>
in terms of searching for target rows: they will only find target rows
- that were committed as of the query start time. However, such a target
+ that were committed as of the command start time. However, such a target
row may have already been updated (or deleted or marked for update) by
another concurrent transaction by the time it is found. In this case, the
would-be updater will wait for the first updating transaction to commit or
updating the originally found row. If the first updater commits, the
second updater will ignore the row if the first updater deleted it,
otherwise it will attempt to apply its operation to the updated version of
- the row. The query search condition (<literal>WHERE</> clause) is
+ the row. The search condition of the command (the <literal>WHERE</> clause) is
re-evaluated to see if the updated version of the row still matches the
search condition. If so, the second updater proceeds with its operation,
starting from the updated version of the row.
</para>
<para>
- Because of the above rule, it is possible for updating queries to see
- inconsistent snapshots --- they can see the effects of concurrent updating
- queries that affected the same rows they are trying to update, but they
- do not see effects of those queries on other rows in the database.
- This behavior makes Read Committed mode unsuitable for queries that
+ Because of the above rule, it is possible for an updating command to see an
+ inconsistent snapshot: it can see the effects of concurrent updating
+ commands that affected the same rows it is trying to update, but it
+ does not see effects of those commands on other rows in the database.
+ This behavior makes Read Committed mode unsuitable for commands that
involve complex search conditions. However, it is just right for simpler
cases. For example, consider updating bank balances with transactions
like
If two such transactions concurrently try to change the balance of account
12345, we clearly want the second transaction to start from the updated
- version of the account's row. Because each query is affecting only a
+ version of the account's row. Because each command is affecting only a
predetermined row, letting it see the updated version of the row does
not create any troublesome inconsistency.
</para>
<para>
- Since in Read Committed mode each new query starts with a new snapshot
+ Since in Read Committed mode each new command starts with a new snapshot
that includes all transactions committed up to that instant, subsequent
- queries in the same transaction will see the effects of the committed
+ commands in the same transaction will see the effects of the committed
concurrent transaction in any case. The point at issue here is whether
- or not within a <emphasis>single</> query we see an absolutely consistent
+ or not within a <emphasis>single</> command we see an absolutely consistent
view of the database.
</para>
<indexterm>
<primary>isolation levels</primary>
- <secondary>read serializable</secondary>
+ <secondary>serializable</secondary>
</indexterm>
<para>
- <firstterm>Serializable</firstterm> provides the strictest transaction
+ The level <firstterm>Serializable</firstterm> provides the strictest transaction
isolation. This level emulates serial transaction execution,
as if transactions had been executed one after another, serially,
rather than concurrently. However, applications using this level must
<command>SELECT</command>
sees a snapshot as of the start of the transaction, not as of the start
of the current query within the transaction. Thus, successive
- <command>SELECT</command>s within a single transaction always see the same
+ <command>SELECT</command> commands within a single transaction always see the same
data.
</para>
</para>
<para>
- Note that only updating transactions may need to be retried --- read-only
+ Note that only updating transactions may need to be retried; read-only
transactions will never have serialization conflicts.
</para>
this mode is recommended only when updating transactions contain logic
sufficiently complex that they may give wrong answers in Read
Committed mode. Most commonly, Serializable mode is necessary when
- a transaction performs several successive queries that must see
+ a transaction executes several successive commands that must see
identical views of the database.
</para>
</sect2>
<productname>PostgreSQL</productname>.
Remember that all of these lock modes are table-level locks,
even if the name contains the word
- <quote>row</quote>. The names of the lock modes are historical.
+ <quote>row</quote>; the names of the lock modes are historical.
To some extent the names reflect the typical usage of each lock
mode --- but the semantics are all the same. The only real difference
between one lock mode and another is the set of lock modes with
which each conflicts. Two transactions cannot hold locks of conflicting
modes on the same table at the same time. (However, a transaction
- never conflicts with itself --- for example, it may acquire
+ never conflicts with itself. For example, it may acquire
<literal>ACCESS EXCLUSIVE</literal> lock and later acquire
<literal>ACCESS SHARE</literal> lock on the same table.) Non-conflicting
lock modes may be held concurrently by many transactions. Notice in
particular that some lock modes are self-conflicting (for example,
- <literal>ACCESS EXCLUSIVE</literal> cannot be held by more than one
+ an <literal>ACCESS EXCLUSIVE</literal> lock cannot be held by more than one
transaction at a time) while others are not self-conflicting (for example,
- <literal>ACCESS SHARE</literal> can be held by multiple transactions).
- Once acquired, a lock mode is held till end of transaction.
+ an <literal>ACCESS SHARE</literal> lock can be held by multiple transactions).
+ Once acquired, a lock is held till end of transaction.
</para>
- <para>
- To examine a list of the currently outstanding locks in a
- database server, use the <literal>pg_locks</literal> system
- view. For more information on monitoring the status of the lock
- manager subsystem, refer to the &cite-admin;.
- </para>
+ <para>
+ To examine a list of the currently outstanding locks in a database
+ server, use the <literal>pg_locks</literal> system view. For more
+ information on monitoring the status of the lock manager
+ subsystem, refer to the &cite-admin;.
+ </para>
<variablelist>
<title>Table-level lock modes</title>
acquire this lock mode on the target table (in addition to
<literal>ACCESS SHARE</literal> locks on any other referenced
tables). In general, this lock mode will be acquired by any
- query that modifies the data in a table.
+ command that modifies the data in a table.
</para>
</listitem>
</varlistentry>
EXCLUSIVE</literal>, <literal>SHARE</literal>, <literal>SHARE
ROW EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
<literal>ACCESS EXCLUSIVE</literal> lock modes.
- This mode allows only concurrent <literal>ACCESS SHARE</literal>,
+ This mode allows only concurrent <literal>ACCESS SHARE</literal> locks,
i.e., only reads from the table can proceed in parallel with a
transaction holding this lock mode.
</para>
</varlistentry>
</variablelist>
- <note>
+ <tip>
<para>
Only an <literal>ACCESS EXCLUSIVE</literal> lock blocks a
<command>SELECT</command> (without <option>FOR UPDATE</option>)
statement.
</para>
- </note>
+ </tip>
</sect2>
<para>
In addition to table and row locks, page-level share/exclusive locks are
used to control read/write access to table pages in the shared buffer
- pool. These locks are released immediately after a tuple is fetched or
+ pool. These locks are released immediately after a row is fetched or
updated. Application developers normally need not be concerned with
page-level locks, but we mention them for completeness.
</para>
example, a banking application might wish to check that the sum of
all credits in one table equals the sum of debits in another table,
when both tables are being actively updated. Comparing the results of two
- successive <literal>SELECT SUM(...)</literal> commands will not work reliably under
+ successive <literal>SELECT sum(...)</literal> commands will not work reliably under
Read Committed mode, since the second query will likely include the results
of transactions not counted by the first. Doing the two sums in a
single serializable transaction will give an accurate picture of the
Read Committed mode, or in Serializable mode be careful to obtain the
lock(s) before performing queries. An explicit lock obtained in a
serializable transaction guarantees that no other transactions modifying
- the table are still running --- but if the snapshot seen by the
+ the table are still running, but if the snapshot seen by the
transaction predates obtaining the lock, it may predate some now-committed
changes in the table. A serializable transaction's snapshot is actually
- frozen at the start of its first query (<literal>SELECT</>, <literal>INSERT</>,
+ frozen at the start of its first query or data-modification command
+ (<literal>SELECT</>, <literal>INSERT</>,
<literal>UPDATE</>, or <literal>DELETE</>), so
it's possible to obtain explicit locks before the snapshot is
frozen.
data, nonblocking read/write access is not currently offered for every
index access method implemented
in <productname>PostgreSQL</productname>.
- </para>
-
- <para>
The various index types are handled as follows:
<variablelist>
<para>
Short-term share/exclusive page-level locks are used for
read/write access. Locks are released immediately after each
- index tuple is fetched or inserted. B-tree indexes provide
+ index row is fetched or inserted. B-tree indexes provide
the highest concurrency without deadlock conditions.
</para>
</listitem>
<listitem>
<para>
Share/exclusive index-level locks are used for read/write access.
- Locks are released after the statement (command) is done.
+ Locks are released after the command is done.
</para>
</listitem>
</varlistentry>
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/perform.sgml,v 1.26 2003/01/28 03:34:29 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/perform.sgml,v 1.27 2003/03/13 01:30:29 petere Exp $
-->
<chapter id="performance-tips">
<listitem>
<para>
- Estimated total cost (If all rows are retrieved, which they may not
- be --- a query with a <literal>LIMIT</> clause will stop short of paying the total cost,
+ Estimated total cost (If all rows were to be retrieved, which they may not
+ be: a query with a <literal>LIMIT</> clause will stop short of paying the total cost,
for example.)
</para>
</listitem>
<listitem>
<para>
Estimated number of rows output by this plan node (Again, only if
- executed to completion.)
+ executed to completion)
</para>
</listitem>
the cost of all its child nodes. It's also important to realize that
the cost only reflects things that the planner/optimizer cares about.
In particular, the cost does not consider the time spent transmitting
- result rows to the frontend --- which could be a pretty dominant
- factor in the true elapsed time, but the planner ignores it because
+ result rows to the frontend, which could be a pretty dominant
+ factor in the true elapsed time; but the planner ignores it because
it cannot change it by altering the plan. (Every correct plan will
output the same row set, we trust.)
</para>
<para>
Rows output is a little tricky because it is <emphasis>not</emphasis> the
number of rows
- processed/scanned by the query --- it is usually less, reflecting the
- estimated selectivity of any <literal>WHERE</>-clause constraints that are being
+ processed/scanned by the query, it is usually less, reflecting the
+ estimated selectivity of any <literal>WHERE</>-clause conditions that are being
applied at this node. Ideally the top-level rows estimate will
approximate the number of rows actually returned, updated, or deleted
by the query.
</para>
<para>
- Here are some examples (using the regress test database after a
+ Here are some examples (using the regression test database after a
<literal>VACUUM ANALYZE</>, and 7.3 development sources):
<programlisting>
-regression=# EXPLAIN SELECT * FROM tenk1;
+EXPLAIN SELECT * FROM tenk1;
+
QUERY PLAN
-------------------------------------------------------------
Seq Scan on tenk1 (cost=0.00..333.00 rows=10000 width=148)
Now let's modify the query to add a <literal>WHERE</> condition:
<programlisting>
-regression=# EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 1000;
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 1000;
+
QUERY PLAN
------------------------------------------------------------
Seq Scan on tenk1 (cost=0.00..358.00 rows=1033 width=148)
Modify the query to restrict the condition even more:
<programlisting>
-regression=# EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 50;
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 50;
+
QUERY PLAN
-------------------------------------------------------------------------------
Index Scan using tenk1_unique1 on tenk1 (cost=0.00..179.33 rows=49 width=148)
</para>
<para>
- Add another clause to the <literal>WHERE</> condition:
+ Add another condition to the <literal>WHERE</> clause:
<programlisting>
-regression=# EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 50 AND
-regression-# stringu1 = 'xxx';
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 50 AND stringu1 = 'xxx';
+
QUERY PLAN
-------------------------------------------------------------------------------
Index Scan using tenk1_unique1 on tenk1 (cost=0.00..179.45 rows=1 width=148)
Filter: (stringu1 = 'xxx'::name)
</programlisting>
- The added clause <literal>stringu1 = 'xxx'</literal> reduces the
+ The added condition <literal>stringu1 = 'xxx'</literal> reduces the
output-rows estimate, but not the cost because we still have to visit the
same set of rows. Notice that the <literal>stringu1</> clause
cannot be applied as an index condition (since this index is only on
</para>
<para>
- Let's try joining two tables, using the fields we have been discussing:
+ Let's try joining two tables, using the columns we have been discussing:
<programlisting>
-regression=# EXPLAIN SELECT * FROM tenk1 t1, tenk2 t2 WHERE t1.unique1 < 50
-regression-# AND t1.unique2 = t2.unique2;
+EXPLAIN SELECT * FROM tenk1 t1, tenk2 t2 WHERE t1.unique1 < 50 AND t1.unique2 = t2.unique2;
+
QUERY PLAN
----------------------------------------------------------------------------
Nested Loop (cost=0.00..327.02 rows=49 width=296)
<para>
In this nested-loop join, the outer scan is the same index scan we had
in the example before last, and so its cost and row count are the same
- because we are applying the <literal>unique1 < 50</literal> <literal>WHERE</> clause at that node.
+ because we are applying the <literal>WHERE</> clause <literal>unique1 < 50</literal> at that node.
The <literal>t1.unique2 = t2.unique2</literal> clause is not relevant yet, so it doesn't
affect row count of the outer scan. For the inner scan, the <literal>unique2</> value of the
current
</para>
<para>
- In this example the loop's output row count is the same as the product
+ In this example the join's output row count is the same as the product
of the two scans' row counts, but that's not true in general, because
- in general you can have <literal>WHERE</> clauses that mention both relations and
+ in general you can have <literal>WHERE</> clauses that mention both tables and
so can only be applied at the join point, not to either input scan.
For example, if we added <literal>WHERE ... AND t1.hundred < t2.hundred</literal>,
that would decrease the output row count of the join node, but not change
also <xref linkend="explicit-joins">.)
<programlisting>
-regression=# SET enable_nestloop = off;
-SET
-regression=# EXPLAIN SELECT * FROM tenk1 t1, tenk2 t2 WHERE t1.unique1 < 50
-regression-# AND t1.unique2 = t2.unique2;
+SET enable_nestloop = off;
+EXPLAIN SELECT * FROM tenk1 t1, tenk2 t2 WHERE t1.unique1 < 50 AND t1.unique2 = t2.unique2;
+
QUERY PLAN
--------------------------------------------------------------------------
Hash Join (cost=179.45..563.06 rows=49 width=296)
For example, we might get a result like this:
<screen>
-regression=# EXPLAIN ANALYZE
-regression-# SELECT * FROM tenk1 t1, tenk2 t2
-regression-# WHERE t1.unique1 < 50 AND t1.unique2 = t2.unique2;
+EXPLAIN ANALYZE SELECT * FROM tenk1 t1, tenk2 t2 WHERE t1.unique1 < 50 AND t1.unique2 = t2.unique2;
+
QUERY PLAN
-------------------------------------------------------------------------------
Nested Loop (cost=0.00..327.02 rows=49 width=296)
<para>
One component of the statistics is the total number of entries in each
table and index, as well as the number of disk blocks occupied by each
- table and index. This information is kept in
- <structname>pg_class</structname>'s <structfield>reltuples</structfield>
- and <structfield>relpages</structfield> columns. We can look at it
+ table and index. This information is kept in the table
+ <structname>pg_class</structname> in the columns <structfield>reltuples</structfield>
+ and <structfield>relpages</structfield>. We can look at it
with queries similar to this one:
<screen>
-regression=# SELECT relname, relkind, reltuples, relpages FROM pg_class
-regression-# WHERE relname LIKE 'tenk1%';
+SELECT relname, relkind, reltuples, relpages FROM pg_class WHERE relname LIKE 'tenk1%';
+
relname | relkind | reltuples | relpages
---------------+---------+-----------+----------
tenk1 | r | 10000 | 233
to having <literal>WHERE</> clauses that restrict the rows to be examined.
The planner thus needs to make an estimate of the
<firstterm>selectivity</> of <literal>WHERE</> clauses, that is, the fraction of
- rows that match each clause of the <literal>WHERE</> condition. The information
+ rows that match each condition in the <literal>WHERE</> clause. The information
used for this task is stored in the <structname>pg_statistic</structname>
system catalog. Entries in <structname>pg_statistic</structname> are
- updated by <command>ANALYZE</> and <command>VACUUM ANALYZE</> commands,
+ updated by <command>ANALYZE</> and <command>VACUUM ANALYZE</> commands
and are always approximate even when freshly updated.
</para>
when examining the statistics manually. <structname>pg_stats</structname>
is designed to be more easily readable. Furthermore,
<structname>pg_stats</structname> is readable by all, whereas
- <structname>pg_statistic</structname> is only readable by the superuser.
+ <structname>pg_statistic</structname> is only readable by a superuser.
(This prevents unprivileged users from learning something about
the contents of other people's tables from the statistics. The
<structname>pg_stats</structname> view is restricted to show only
For example, we might do:
<screen>
-regression=# SELECT attname, n_distinct, most_common_vals FROM pg_stats WHERE tablename = 'road';
+SELECT attname, n_distinct, most_common_vals FROM pg_stats WHERE tablename = 'road';
+
attname | n_distinct | most_common_vals
---------+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
name | -0.467008 | {"I- 580 Ramp","I- 880 Ramp","Sp Railroad ","I- 580 ","I- 680 Ramp","I- 80 Ramp","14th St ","5th St ","Mission Blvd","I- 880 "}
thepath | 20 | {"[(-122.089,37.71),(-122.0886,37.711)]"}
(2 rows)
-regression=#
</screen>
</para>
<thead>
<row>
<entry>Name</entry>
- <entry>Type</entry>
+ <entry>Data Type</entry>
<entry>Description</entry>
</row>
</thead>
<row>
<entry><literal>tablename</literal></entry>
<entry><type>name</type></entry>
- <entry>Name of the table containing the column</entry>
+ <entry>Name of the table containing the column.</entry>
</row>
<row>
<entry><literal>attname</literal></entry>
<entry><type>name</type></entry>
- <entry>Column described by this row</entry>
+ <entry>Name of the column described by this row.</entry>
</row>
<row>
<entry><literal>null_frac</literal></entry>
<entry><type>real</type></entry>
- <entry>Fraction of column's entries that are null</entry>
+ <entry>Fraction of column entries that are null.</entry>
</row>
<row>
<entry><literal>avg_width</literal></entry>
<entry><type>integer</type></entry>
- <entry>Average width in bytes of the column's entries</entry>
+ <entry>Average width in bytes of the column entries.</entry>
</row>
<row>
</row>
<row>
- <entry>histogram_bounds</entry>
+ <entry><literal>histogram_bounds</literal></entry>
<entry><type>text[]</type></entry>
<entry>A list of values that divide the column's values into
- groups of approximately equal population. The
- <structfield>most_common_vals</>, if present, are omitted from the
- histogram calculation. (Omitted if column data type does not have a
- <literal><</> operator, or if the <structfield>most_common_vals</>
+ groups of approximately equal population. The values in
+ <structfield>most_common_vals</>, if present, are omitted from this
+ histogram calculation. (This columns is not filled if the column data type does not have a
+ <literal><</> operator or if the <structfield>most_common_vals</>
list accounts for the entire population.)
</entry>
</row>
<row>
- <entry>correlation</entry>
+ <entry><literal>correlation</literal></entry>
<entry><type>real</type></entry>
<entry>Statistical correlation between physical row ordering and
logical ordering of the column values. This ranges from -1 to +1.
When the value is near -1 or +1, an index scan on the column will
be estimated to be cheaper than when it is near zero, due to reduction
- of random access to the disk. (Omitted if column data type does
+ of random access to the disk. (This column is not filled if the column data type does
not have a <literal><</> operator.)
</entry>
</row>
<title>Controlling the Planner with Explicit <literal>JOIN</> Clauses</title>
<para>
- Beginning with <productname>PostgreSQL</productname> 7.1 it has been possible
+ It is possible
to control the query planner to some extent by using the explicit <literal>JOIN</>
syntax. To see why this matters, we first need some background.
</para>
the <literal>WHERE</> condition <literal>a.id = b.id</>, and then
joins C to this joined table, using the other <literal>WHERE</>
condition. Or it could join B to C and then join A to that result.
- Or it could join A to C and then join them with B --- but that
+ Or it could join A to C and then join them with B, but that
would be inefficient, since the full Cartesian product of A and C
would have to be formed, there being no applicable condition in the
<literal>WHERE</> clause to allow optimization of the join. (All
<productname>PostgreSQL</productname> planner will switch from exhaustive
search to a <firstterm>genetic</firstterm> probabilistic search
through a limited number of possibilities. (The switch-over threshold is
- set by the <varname>GEQO_THRESHOLD</varname> run-time
+ set by the <varname>geqo_threshold</varname> run-time
parameter described in the &cite-admin;.)
The genetic search takes less time, but it won't
necessarily find the best possible plan.
<para>
To force the planner to follow the <literal>JOIN</> order for inner joins,
- set the <varname>JOIN_COLLAPSE_LIMIT</> run-time parameter to 1.
+ set the <varname>join_collapse_limit</> run-time parameter to 1.
(Other possible values are discussed below.)
</para>
<programlisting>
SELECT * FROM a CROSS JOIN b, c, d, e WHERE ...;
</programlisting>
- With <varname>JOIN_COLLAPSE_LIMIT</> = 1, this
+ With <varname>join_collapse_limit</> = 1, this
forces the planner to join A to B before joining them to other tables,
but doesn't constrain its choices otherwise. In this example, the
number of possible join orders is reduced by a factor of 5.
<para>
A closely related issue that affects planning time is collapsing of
- sub-SELECTs into their parent query. For example, consider
+ subqueries into their parent query. For example, consider
<programlisting>
SELECT *
FROM x, y,
- (SELECT * FROM a, b, c WHERE something) AS ss
-WHERE somethingelse
+ (SELECT * FROM a, b, c WHERE something) AS ss
+WHERE somethingelse;
</programlisting>
This situation might arise from use of a view that contains a join;
- the view's SELECT rule will be inserted in place of the view reference,
+ the view's <literal>SELECT</> rule will be inserted in place of the view reference,
yielding a query much like the above. Normally, the planner will try
- to collapse the sub-query into the parent, yielding
+ to collapse the subquery into the parent, yielding
<programlisting>
-SELECT * FROM x, y, a, b, c WHERE something AND somethingelse
+SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
</programlisting>
- This usually results in a better plan than planning the sub-query
- separately. (For example, the outer WHERE conditions might be such that
+ This usually results in a better plan than planning the subquery
+ separately. (For example, the outer <literal>WHERE</> conditions might be such that
joining X to A first eliminates many rows of A, thus avoiding the need to
- form the full logical output of the sub-select.) But at the same time,
+ form the full logical output of the subquery.) But at the same time,
we have increased the planning time; here, we have a five-way join
problem replacing two separate three-way join problems. Because of the
exponential growth of the number of possibilities, this makes a big
difference. The planner tries to avoid getting stuck in huge join search
- problems by not collapsing a sub-query if more than
- <varname>FROM_COLLAPSE_LIMIT</> FROM-items would result in the parent
+ problems by not collapsing a subquery if more than
+ <varname>from_collapse_limit</> <literal>FROM</> items would result in the parent
query. You can trade off planning time against quality of plan by
adjusting this run-time parameter up or down.
</para>
<para>
- <varname>FROM_COLLAPSE_LIMIT</> and <varname>JOIN_COLLAPSE_LIMIT</>
+ <varname>from_collapse_limit</> and <varname>join_collapse_limit</>
are similarly named because they do almost the same thing: one controls
- when the planner will <quote>flatten out</> sub-SELECTs, and the
- other controls when it will flatten out explicit inner JOINs. Typically
- you would either set <varname>JOIN_COLLAPSE_LIMIT</> equal to
- <varname>FROM_COLLAPSE_LIMIT</> (so that explicit JOINs and sub-SELECTs
- act similarly) or set <varname>JOIN_COLLAPSE_LIMIT</> to 1 (if you want
- to control join order with explicit JOINs). But you might set them
+ when the planner will <quote>flatten out</> subselects, and the
+ other controls when it will flatten out explicit inner joins. Typically
+ you would either set <varname>join_collapse_limit</> equal to
+ <varname>from_collapse_limit</> (so that explicit joins and subselects
+ act similarly) or set <varname>join_collapse_limit</> to 1 (if you want
+ to control join order with explicit joins). But you might set them
differently if you are trying to fine-tune the tradeoff between planning
time and run time.
</para>
make sure the library does it when you want it done.)
If you allow each insertion to be committed separately,
<productname>PostgreSQL</productname> is doing a lot of work for each
- record added.
+ row added.
An additional benefit of doing all insertions in one transaction
- is that if the insertion of one record were to fail then the
- insertion of all records inserted up to that point would be rolled
+ is that if the insertion of one row were to fail then the
+ insertion of all rows inserted up to that point would be rolled
back, so you won't be stuck with partially loaded data.
</para>
</sect2>
<sect2 id="populate-copy-from">
- <title>Use COPY FROM</title>
+ <title>Use <command>COPY FROM</command></title>
<para>
- Use <command>COPY FROM STDIN</command> to load all the records in one
+ Use <command>COPY FROM STDIN</command> to load all the rows in one
command, instead of using
a series of <command>INSERT</command> commands. This reduces parsing,
planning, etc.
create the table, bulk-load with <command>COPY</command>, then create any
indexes needed
for the table. Creating an index on pre-existing data is quicker than
- updating it incrementally as each record is loaded.
+ updating it incrementally as each row is loaded.
</para>
<para>
- If you are augmenting an existing table, you can <command>DROP
- INDEX</command>, load the table, then recreate the index. Of
+ If you are augmenting an existing table, you can drop the index,
+ load the table, then recreate the index. Of
course, the database performance for other users may be adversely
affected during the time that the index is missing. One should also
think twice before dropping unique indexes, since the error checking
</sect2>
<sect2 id="populate-analyze">
- <title>Run ANALYZE Afterwards</title>
+ <title>Run <command>ANALYZE</command> Afterwards</title>
<para>
It's a good idea to run <command>ANALYZE</command> or <command>VACUUM
-<!-- $Header: /cvsroot/pgsql/doc/src/sgml/queries.sgml,v 1.19 2002/11/11 20:14:03 petere Exp $ -->
+<!-- $Header: /cvsroot/pgsql/doc/src/sgml/queries.sgml,v 1.20 2003/03/13 01:30:29 petere Exp $ -->
<chapter id="queries">
<title>Queries</title>
row consisting of all columns in <replaceable>T1</replaceable>
followed by all columns in <replaceable>T2</replaceable>. If
the tables have N and M rows respectively, the joined
- table will have N * M rows. A cross join is equivalent to an
- <literal>INNER JOIN ON TRUE</literal>.
+ table will have N * M rows.
</para>
- <tip>
- <para>
- <literal>FROM <replaceable>T1</replaceable> CROSS JOIN
- <replaceable>T2</replaceable></literal> is equivalent to
- <literal>FROM <replaceable>T1</replaceable>,
- <replaceable>T2</replaceable></literal>.
- </para>
- </tip>
+ <para>
+ <literal>FROM <replaceable>T1</replaceable> CROSS JOIN
+ <replaceable>T2</replaceable></literal> is equivalent to
+ <literal>FROM <replaceable>T1</replaceable>,
+ <replaceable>T2</replaceable></literal>. It is also equivalent to
+ <literal>FROM <replaceable>T1</replaceable> INNER JOIN
+ <replaceable>T2</replaceable> ON TRUE</literal> (see below).
+ </para>
</listitem>
</varlistentry>
<para>
The possible types of qualified join are:
- </para>
<variablelist>
<varlistentry>
</listitem>
</varlistentry>
</variablelist>
+ </para>
</listitem>
</varlistentry>
</variablelist>
condition of the <literal>WHERE</> clause are eliminated from
<literal>fdt</literal>. Notice the use of scalar subqueries as
value expressions. Just like any other query, the subqueries can
- employ complex table expressions. Notice how
+ employ complex table expressions. Notice also how
<literal>fdt</literal> is referenced in the subqueries.
Qualifying <literal>c1</> as <literal>fdt.c1</> is only necessary
if <literal>c1</> is also the name of a column in the derived
- input table of the subquery. Qualifying the column name adds
- clarity even when it is not needed. This shows how the column
+ input table of the subquery. But qualifying the column name adds
+ clarity even when it is not needed. This example shows how the column
naming scope of an outer query extends into its inner queries.
</para>
</sect2>
</synopsis>
<para>
- The <literal>GROUP BY</> clause is used to group together rows in
+ The <literal>GROUP BY</> clause is used to group together those rows in
a table that share the same values in all the columns listed. The
order in which the columns are listed does not matter. The
purpose is to reduce each group of rows sharing common values into
c | 2
(3 rows)
</screen>
- Here <literal>sum()</literal> is an aggregate function that
+ Here <literal>sum</literal> is an aggregate function that
computes a single value over the entire group. More information
about the available aggregate functions can be found in <xref
linkend="functions-aggregate">.
</tip>
<para>
- Here is another example: <function>sum(sales)</function> on a
- table grouped by product code gives the total sales for each
- product, not the total sales on all products.
+ Here is another example: it calculates the total sales for each
+ product (rather than the total sales on all products).
<programlisting>
SELECT product_id, p.name, (sum(s.units) * p.price) AS sales
FROM products p LEFT JOIN sales s USING (product_id)
unnecessary, but this is not implemented yet.) The column
<literal>s.units</> does not have to be in the <literal>GROUP
BY</> list since it is only used in an aggregate expression
- (<function>sum()</function>), which represents the group of sales
- of a product. For each product, a summary row is returned about
+ (<literal>sum(...)</literal>), which represents the sales
+ of a product. For each product, the query returns a summary row about
all sales of the product.
</para>
HAVING sum(p.price * s.units) > 5000;
</programlisting>
In the example above, the <literal>WHERE</> clause is selecting
- rows by a column that is not grouped, while the <literal>HAVING</>
+ rows by a column that is not grouped (the expression is only true for
+ sales during the last four weeks), while the <literal>HAVING</>
clause restricts the output to groups with total gross sales over
5000. Note that the aggregate expressions do not necessarily need
- to be the same everywhere.
+ to be the same in all parts of the query.
</para>
</sect2>
</sect1>
If more than one table has a column of the same name, the table
name must also be given, as in
<programlisting>
-SELECT tbl1.a, tbl2.b, tbl1.c FROM ...
+SELECT tbl1.a, tbl2.a, tbl1.b FROM ...
</programlisting>
(See also <xref linkend="queries-where">.)
</para>
<para>
If an arbitrary value expression is used in the select list, it
conceptually adds a new virtual column to the returned table. The
- value expression is evaluated once for each retrieved row, with
+ value expression is evaluated once for each result row, with
the row's values substituted for any column references. But the
expressions in the select list do not have to reference any
columns in the table expression of the <literal>FROM</> clause;
</para>
<para>
- If no output column name is specified via AS, the system assigns a
+ If no output column name is specified using <literal>AS</>, the system assigns a
default name. For simple column references, this is the name of the
referenced column. For function
calls, this is the name of the function. For complex expressions,
<para>
<literal>OFFSET</> says to skip that many rows before beginning to
- return rows to the client. <literal>OFFSET 0</> is the same as
+ return rows. <literal>OFFSET 0</> is the same as
omitting the <literal>OFFSET</> clause. If both <literal>OFFSET</>
and <literal>LIMIT</> appear, then <literal>OFFSET</> rows are
skipped before starting to count the <literal>LIMIT</> rows that
When using <literal>LIMIT</>, it is a good idea to use an
<literal>ORDER BY</> clause that constrains the result rows into a
unique order. Otherwise you will get an unpredictable subset of
- the query's rows---you may be asking for the tenth through
+ the query's rows. --- You may be asking for the tenth through
twentieth rows, but tenth through twentieth in what ordering? The
ordering is unknown, unless you specified <literal>ORDER BY</>.
</para>
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/query.sgml,v 1.28 2002/11/11 20:14:03 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/query.sgml,v 1.29 2003/03/13 01:30:29 petere Exp $
-->
<chapter id="tutorial-sql">
The <type>point</type> type requires a coordinate pair as input,
as shown here:
<programlisting>
-INSERT INTO cities VALUES ('San Francisco', '(-194.0, 53.0)');
+INSERT INTO cities VALUES ('San Francisco', '(-194.0, 53.0)');
</programlisting>
</para>
</para>
<para>
- You may specify any arbitrary expressions in the target list. For
+ You may specify any arbitrary expressions in the select list. For
example, you can do:
<programlisting>
SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date FROM weather;
<indexterm><primary>DISTINCT</primary></indexterm>
<indexterm><primary>duplicate</primary></indexterm>
- As a final note, you can request that the results of a select can
+ As a final note, you can request that the results of a query can
be returned in sorted order or with duplicate rows removed:
<programlisting>
<literal>WHERE</literal> clause must not contain aggregate functions;
it makes no sense to try to use an aggregate to determine which rows
will be inputs to the aggregates. On the other hand,
- <literal>HAVING</literal> clauses always contain aggregate functions.
+ <literal>HAVING</literal> clause always contains aggregate functions.
(Strictly speaking, you are allowed to write a <literal>HAVING</literal>
clause that doesn't use aggregates, but it's wasteful: The same condition
could be used more efficiently at the <literal>WHERE</literal> stage.)
-<!-- $Header: /cvsroot/pgsql/doc/src/sgml/regress.sgml,v 1.30 2002/11/08 20:26:12 tgl Exp $ -->
+<!-- $Header: /cvsroot/pgsql/doc/src/sgml/regress.sgml,v 1.31 2003/03/13 01:30:29 petere Exp $ -->
<chapter id="regress">
<title id="regress-title">Regression Tests</title>
- <sect1 id="regress-intro">
- <title>Introduction</title>
-
<para>
The regression tests are a comprehensive set of tests for the SQL
implementation in <productname>PostgreSQL</productname>. They test
standard SQL operations as well as the extended capabilities of
- <productname>PostgreSQL</productname>. The test suite was
- originally developed by Jolly Chen and Andrew Yu, and was
- extensively revised and repackaged by Marc Fournier and Thomas
- Lockhart. From <productname>PostgreSQL</productname> 6.1 onward
- the regression tests are current for every official release.
+ <productname>PostgreSQL</productname>. From
+ <productname>PostgreSQL</productname> 6.1 onward, the regression
+ tests are current for every official release.
</para>
- </sect1>
-
<sect1 id="regress-run">
<title>Running the Tests</title>
To run the regression tests after building but before installation,
type
<screen>
-<prompt>$ </prompt><userinput>gmake check</userinput>
+gmake check
</screen>
in the top-level directory. (Or you can change to
<filename>src/test/regress</filename> and run the command there.)
This will first build several auxiliary files, such as
- platform-dependent <quote>expected</quote> files and some sample
+ some sample
user-defined trigger functions, and then run the test driver
script. At the end you should see something like
<screen>
If you already did the build as root, you do not have to start all
over. Instead, make the regression test directory writable by
some other user, log in as that user, and restart the tests.
- For example,
+ For example
<screen>
<prompt>root# </prompt><userinput>chmod -R a+w src/test/regress</userinput>
<prompt>root# </prompt><userinput>chmod -R a+w contrib/spi</userinput>
<para>
The parallel regression test starts quite a few processes under your
user ID. Presently, the maximum concurrency is twenty parallel test
- scripts, which means sixty processes --- there's a backend, a <application>psql</>,
+ scripts, which means sixty processes: there's a server process, a <application>psql</>,
and usually a shell parent process for the <application>psql</> for each test script.
So if your system enforces a per-user limit on the number of processes,
make sure this limit is at least seventy-five or so, else you may get
too many child processes in parallel. This may cause the parallel
test run to lock up or fail. In such cases, specify a different
Bourne-compatible shell on the command line, for example:
- <informalexample>
<screen>
-<prompt>$ </prompt><userinput>gmake SHELL=/bin/ksh check</userinput>
+gmake SHELL=/bin/ksh check
</screen>
- </informalexample>
If no non-broken shell is available, you can alter the parallel test
schedule as suggested above.
</para>
initialize a data area and start the
server, <![%standalone-ignore;[as explained in <xref linkend="runtime">, ]]> then type
<screen>
-<prompt>$ </prompt><userinput>gmake installcheck</userinput>
+gmake installcheck
</screen>
The tests will expect to contact the server at the local host and the
default port number, unless directed otherwise by <envar>PGHOST</envar> and <envar>PGPORT</envar>
<quote>fail</quote> some of these regression tests due to
platform-specific artifacts such as varying floating-point representation
and time zone support. The tests are currently evaluated using a simple
- <application>diff</application> comparison against the outputs
+ <command>diff</command> comparison against the outputs
generated on a reference system, so the results are sensitive to
small system differences. When a test is reported as
<quote>failed</quote>, always examine the differences between
<para>
The actual outputs of the regression tests are in files in the
<filename>src/test/regress/results</filename> directory. The test
- script uses <application>diff</application> to compare each output
+ script uses <command>diff</command> to compare each output
file against the reference outputs stored in the
<filename>src/test/regress/expected</filename> directory. Any
differences are saved for your inspection in
<filename>src/test/regress/regression.diffs</filename>. (Or you
- can run <application>diff</application> yourself, if you prefer.)
+ can run <command>diff</command> yourself, if you prefer.)
</para>
<sect2>
failures. The regression test suite is set up to handle this
problem by providing alternative result files that together are
known to handle a large number of locales. For example, for the
- <quote>char</quote> test, the expected file
+ <literal>char</literal> test, the expected file
<filename>char.out</filename> handles the <literal>C</> and <literal>POSIX</> locales,
and the file <filename>char_1.out</filename> handles many other
locales. The regression test driver will automatically pick the
fail if you run the test on the day of a daylight-saving time
changeover, or the day before or after one. These queries assume
that the intervals between midnight yesterday, midnight today and
- midnight tomorrow are exactly twenty-four hours -- which is wrong
+ midnight tomorrow are exactly twenty-four hours --- which is wrong
if daylight-saving time went into or out of effect meanwhile.
</para>
<para>
Most of the date and time results are dependent on the time zone
environment. The reference files are generated for time zone
- <literal>PST8PDT</literal> (Berkeley, California) and there will be apparent
+ <literal>PST8PDT</literal> (Berkeley, California), and there will be apparent
failures if the tests are not run with that time zone setting.
The regression test driver sets environment variable
<envar>PGTZ</envar> to <literal>PST8PDT</literal>, which normally
- ensures proper results. However, your system must provide library
+ ensures proper results. However, your operating system must provide
support for the <literal>PST8PDT</literal> time zone, or the time zone-dependent
tests will fail. To verify that your machine does have this
support, type the following:
<screen>
-<prompt>$ </prompt><userinput>env TZ=PST8PDT date</userinput>
+env TZ=PST8PDT date
</screen>
The command above should have returned the current system time in
- the <literal>PST8PDT</literal> time zone. If the <literal>PST8PDT</literal> database is not available,
+ the <literal>PST8PDT</literal> time zone. If the <literal>PST8PDT</literal> time zone is not available,
then your system may have returned the time in GMT. If the
- <literal>PST8PDT</literal> time zone is not available, you can set the time zone
+ <literal>PST8PDT</literal> time zone is missing, you can set the time zone
rules explicitly:
<programlisting>
PGTZ='PST8PDT7,M04.01.0,M10.05.03'; export PGTZ
</para>
<para>
- Some systems using older time zone libraries fail to apply
+ Some systems using older time-zone libraries fail to apply
daylight-saving corrections to dates before 1970, causing
pre-1970 <acronym>PDT</acronym> times to be displayed in <acronym>PST</acronym> instead. This will
result in localized differences in the test results.
<title>Floating-point differences</title>
<para>
- Some of the tests involve computing 64-bit (<type>double
- precision</type>) numbers from table columns. Differences in
+ Some of the tests involve computing 64-bit floating-point numbers (<type>double
+ precision</type>) from table columns. Differences in
results involving mathematical functions of <type>double
precision</type> columns have been observed. The <literal>float8</> and
<literal>geometry</> tests are particularly prone to small differences
You might see differences in which the same rows are output in a
different order than what appears in the expected file. In most cases
this is not, strictly speaking, a bug. Most of the regression test
-scripts are not so pedantic as to use an ORDER BY for every single
-SELECT, and so their result row orderings are not well-defined
+scripts are not so pedantic as to use an <literal>ORDER BY</> for every single
+<literal>SELECT</>, and so their result row orderings are not well-defined
according to the letter of the SQL specification. In practice, since we are
looking at the same queries being executed on the same data by the same
software, we usually get the same result ordering on all platforms, and
-so the lack of ORDER BY isn't a problem. Some queries do exhibit
+so the lack of <literal>ORDER BY</> isn't a problem. Some queries do exhibit
cross-platform ordering differences, however. (Ordering differences
can also be triggered by non-C locale settings.)
</para>
<para>
Therefore, if you see an ordering difference, it's not something to
-worry about, unless the query does have an ORDER BY that your result
+worry about, unless the query does have an <literal>ORDER BY</> that your result
is violating. But please report it anyway, so that we can add an
-ORDER BY to that particular query and thereby eliminate the bogus
+<literal>ORDER BY</> to that particular query and thereby eliminate the bogus
<quote>failure</quote> in future releases.
</para>
<para>
-You might wonder why we don't order all the regress test queries explicitly to
+You might wonder why we don't order all the regression test queries explicitly to
get rid of this issue once and for all. The reason is that that would
make the regression tests less useful, not more, since they'd tend
to exercise query plan types that produce ordered results to the
<title>The <quote>random</quote> test</title>
<para>
- There is at least one case in the <quote>random</quote> test
+ There is at least one case in the <literal>random</literal> test
script that is intended to produce random results. This causes
random to fail the regression test once in a while (perhaps once
in every five to ten trials). Typing
testname/platformpattern=comparisonfilename
</synopsis>
The test name is just the name of the particular regression test
- module. The platform pattern is a pattern in the style of
- <citerefentry><refentrytitle>expr</><manvolnum>1</></citerefentry> (that is, a regular expression with an implicit
+ module. The platform pattern is a pattern in the style of the Unix
+ tool <command>expr</> (that is, a regular expression with an implicit
<literal>^</literal> anchor
at the start). It is matched against the platform name as printed
- by <filename>config.guess</filename> followed by
+ by <command>config.guess</command> followed by
<literal>:gcc</literal> or <literal>:cc</literal>, depending on
whether you use the GNU compiler or the system's native compiler
(on systems where there is a difference). The comparison file
horology/hppa=horology-no-DST-before-1970
</programlisting>
which will trigger on any machine for which the output of <command>config.guess</command>
- begins with <quote><literal>hppa</literal></quote>. Other lines
+ begins with <literal>hppa</literal>. Other lines
in <filename>resultmap</> select the variant comparison file for other
platforms where it's appropriate.
</para>
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/syntax.sgml,v 1.75 2003/02/19 03:13:24 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/syntax.sgml,v 1.76 2003/03/13 01:30:29 petere Exp $
-->
<chapter id="sql-syntax">
<para>
Quoting an identifier also makes it case-sensitive, whereas
unquoted names are always folded to lower case. For example, the
- identifiers <literal>FOO</literal>, <literal>foo</literal> and
+ identifiers <literal>FOO</literal>, <literal>foo</literal>, and
<literal>"foo"</literal> are considered the same by
<productname>PostgreSQL</productname>, but <literal>"Foo"</literal>
and <literal>"FOO"</literal> are different from these three and
function-call syntaxes can also be used to specify run-time type
conversions of arbitrary expressions, as discussed in <xref
linkend="sql-syntax-type-casts">. But the form
- <replaceable>type</replaceable> '<replaceable>string</replaceable>'
+ <literal><replaceable>type</replaceable> '<replaceable>string</replaceable>'</literal>
can only be used to specify the type of a literal constant.
Another restriction on
- <replaceable>type</replaceable> '<replaceable>string</replaceable>'
+ <literal><replaceable>type</replaceable> '<replaceable>string</replaceable>'</literal>
is that it does not work for array types; use <literal>::</literal>
or <literal>CAST()</literal> to specify the type of an array constant.
</para>
<listitem>
<para>
- The period (<literal>.</literal>) is used in floating-point
+ The period (<literal>.</literal>) is used in numeric
constants, and to separate schema, table, and column names.
</para>
</listitem>
<listitem>
<para>
- A positional parameter reference, in the body of a function declaration.
+ A positional parameter reference, in the body of a function definition.
</para>
</listitem>
+<!--
+$Header: /cvsroot/pgsql/doc/src/sgml/typeconv.sgml,v 1.27 2003/03/13 01:30:29 petere Exp $
+-->
+
<chapter Id="typeconv">
<title>Type Conversion</title>
<para>
-<acronym>SQL</acronym> queries can, intentionally or not, require
+<acronym>SQL</acronym> statements can, intentionally or not, require
mixing of different data types in the same expression.
<productname>PostgreSQL</productname> has extensive facilities for
evaluating mixed-type expressions.
However, the implicit conversions done by <productname>PostgreSQL</productname>
can affect the results of a query. When necessary, these results
can be tailored by a user or programmer
-using <emphasis>explicit</emphasis> type coercion.
+using <emphasis>explicit</emphasis> type conversion.
</para>
<para>
<para>
The &cite-programmer; has more details on the exact algorithms used for
-implicit type conversion and coercion.
+implicit type conversion and conversion.
</para>
<sect1 id="typeconv-overview">
<para>
The <productname>PostgreSQL</productname> scanner/parser decodes lexical
elements into only five fundamental categories: integers, floating-point numbers, strings,
-names, and key words. Most extended types are first tokenized into
+names, and key words. Most extended types are first classified as
strings. The <acronym>SQL</acronym> language definition allows specifying type
names with strings, and this mechanism can be used in
<productname>PostgreSQL</productname> to start the parser down the correct
path. For example, the query
<screen>
-tgl=> SELECT text 'Origin' AS "Label", point '(0,0)' AS "Value";
- Label | Value
+SELECT text 'Origin' AS "label", point '(0,0)' AS "value";
+
+ label | value
--------+-------
Origin | (0,0)
(1 row)
has two literal constants, of type <type>text</type> and <type>point</type>.
If a type is not specified for a string literal, then the placeholder type
-<firstterm>unknown</firstterm> is assigned initially, to be resolved in later
+<type>unknown</type> is assigned initially, to be resolved in later
stages as described below.
</para>
There are four fundamental <acronym>SQL</acronym> constructs requiring
distinct type conversion rules in the <productname>PostgreSQL</productname>
parser:
-</para>
<variablelist>
<varlistentry>
<listitem>
<para>
Much of the <productname>PostgreSQL</productname> type system is built around a
-rich set of functions. Function calls have one or more arguments which, for
-any specific query, must be matched to the functions available in the system
-catalog. Since <productname>PostgreSQL</productname> permits function
+rich set of functions. Function calls can have one or more arguments.
+Since <productname>PostgreSQL</productname> permits function
overloading, the function name alone does not uniquely identify the function
to be called; the parser must select the right function based on the data
types of the supplied arguments.
</varlistentry>
<varlistentry>
<term>
-Query targets
+Value Storage
</term>
<listitem>
<para>
<acronym>SQL</acronym> <command>INSERT</command> and <command>UPDATE</command> statements place the results of
-expressions into a table. The expressions in the query must be matched up
+expressions into a table. The expressions in the statement must be matched up
with, and perhaps converted to, the types of the target columns.
</para>
</listitem>
</term>
<listitem>
<para>
-Since all select results from a unionized <literal>SELECT</literal> statement must appear in a single
+Since all query results from a unionized <literal>SELECT</literal> statement must appear in a single
set of columns, the types of the results
of each <literal>SELECT</> clause must be matched up and converted to a uniform set.
-Similarly, the result expressions of a <literal>CASE</> construct must be coerced to
+Similarly, the branch expressions of a <literal>CASE</> construct must be converted to
a common type so that the <literal>CASE</> expression as a whole has a known output type.
</para>
</listitem>
</varlistentry>
</variablelist>
-
-<para>
-Many of the general type conversion rules use simple conventions built on
-the <productname>PostgreSQL</productname> function and operator system tables.
-There are some heuristics included in the conversion rules to better support
-conventions for the <acronym>SQL</acronym> standard native types such as
-<type>smallint</type>, <type>integer</type>, and <type>real</type>.
</para>
<para>
when there is ambiguity.
In the user-defined category, each type is its own preferred type.
Ambiguous expressions (those with multiple candidate parsing solutions)
-can often be resolved when there are multiple possible built-in types, but
+can therefore often be resolved when there are multiple possible built-in types, but
they will raise an error when there are multiple choices for user-defined
types.
</para>
<para>
User-defined types are not related. Currently, <productname>PostgreSQL</productname>
does not have information available to it on relationships between types, other than
-hardcoded heuristics for built-in types and implicit relationships based on available functions
-in the catalog.
+hardcoded heuristics for built-in types and implicit relationships based on available functions.
</para>
</listitem>
if a query does not need implicit type conversion.
That is, if a query is well formulated and the types already match up, then the query should proceed
without spending extra time in the parser and without introducing unnecessary implicit conversion
-functions into the query.
+calls into the query.
</para>
<para>
Additionally, if a query usually requires an implicit conversion for a function, and
-if then the user defines an explicit function with the correct argument types, the parser
+if then the user defines a new function with the correct argument types, the parser
should use this new function and will no longer do the implicit conversion using the old function.
</para>
</listitem>
<para>
Select the operators to be considered from the
<classname>pg_operator</classname> system catalog. If an unqualified
-operator name is used (the usual case), the operators
+operator name was used (the usual case), the operators
considered are those of the right name and argument count that are
visible in the current search path (see <xref linkend="ddl-schemas-path">).
If a qualified operator name was given, only operators in the specified
<substeps>
<step performance="optional">
<para>
-If one argument of a binary operator is <type>unknown</type> type,
+If one argument of a binary operator invocation is of the <type>unknown</type> type,
then assume it is the same type as the other argument for this check.
Other cases involving <type>unknown</type> will never find a match at
this step.
<step performance="required">
<para>
Discard candidate operators for which the input types do not match
-and cannot be coerced (using an implicit coercion function) to match.
+and cannot be converted (using an implicit conversion) to match.
<type>unknown</type> literals are
-assumed to be coercible to anything for this purpose. If only one
+assumed to be convertible to anything for this purpose. If only one
candidate remains, use it; else continue to the next step.
</para>
</step>
<step performance="required">
<para>
Run through all candidates and keep those that accept preferred types at
-the most positions where type coercion will be required.
+the most positions where type conversion will be required.
Keep all candidates if none accept preferred types.
If only one candidate remains, use it; else continue to the next step.
</para>
</step>
<step performance="required">
<para>
-If any input arguments are <quote>unknown</quote>, check the type
+If any input arguments are <type>unknown</type>, check the type
categories accepted at those argument positions by the remaining
-candidates. At each position, select the <quote>string</quote> category if any
-candidate accepts that category (this bias towards string is appropriate
-since an unknown-type literal does look like a string). Otherwise, if
+candidates. At each position, select the <literal>string</literal> category if any
+candidate accepts that category. (This bias towards string is appropriate
+since an unknown-type literal does look like a string.) Otherwise, if
all the remaining candidates accept the same type category, select that
category; otherwise fail because the correct choice cannot be deduced
-without more clues. Also note whether any of the candidates accept a
-preferred data type within the selected category. Now discard operator
-candidates that do not accept the selected type category; furthermore,
+without more clues. Now discard operator
+candidates that do not accept the selected type category. Furthermore,
if any candidate accepts a preferred type at a given argument position,
discard candidates that accept non-preferred types for that argument.
</para>
</step>
</procedure>
-<bridgehead renderas="sect2">Examples</bridgehead>
+<para>
+Some examples follow.
+</para>
<example>
<title>Exponentiation Operator Type Resolution</title>
The scanner assigns an initial type of <type>integer</type> to both arguments
of this query expression:
<screen>
-tgl=> SELECT 2 ^ 3 AS "Exp";
- Exp
+SELECT 2 ^ 3 AS "exp";
+
+ exp
-----
8
(1 row)
is equivalent to
<screen>
-tgl=> SELECT CAST(2 AS double precision) ^ CAST(3 AS double precision) AS "Exp";
- Exp
------
- 8
-(1 row)
-</screen>
-
-or
-
-<screen>
-tgl=> SELECT 2.0 ^ 3.0 AS "Exp";
- Exp
------
- 8
-(1 row)
+SELECT CAST(2 AS double precision) ^ CAST(3 AS double precision) AS "exp";
</screen>
-
-<note>
-<para>
-This last form has the least overhead, since no functions are called to do
-implicit type conversion. This is not an issue for small queries, but may
-have an impact on the performance of queries involving large tables.
-</para>
-</note>
</para>
</example>
<para>
A string-like syntax is used for working with string types as well as for
-working with complex extended types.
+working with complex extension types.
Strings with unspecified type are matched with likely operator candidates.
</para>
<para>
An example with one unspecified argument:
<screen>
-tgl=> SELECT text 'abc' || 'def' AS "Text and Unknown";
- Text and Unknown
+SELECT text 'abc' || 'def' AS "text and unknown";
+
+ text and unknown
------------------
abcdef
(1 row)
</para>
<para>
-Concatenation on unspecified types:
+Here is a concatenation on unspecified types:
<screen>
-tgl=> SELECT 'abc' || 'def' AS "Unspecified";
- Unspecified
+SELECT 'abc' || 'def' AS "unspecified";
+
+ unspecified
-------------
abcdef
(1 row)
and finds that there are candidates accepting both string-category and
bit-string-category inputs. Since string category is preferred when available,
that category is selected, and then the
-<quote>preferred type</quote> for strings, <type>text</type>, is used as the specific
+preferred type for strings, <type>text</type>, is used as the specific
type to resolve the unknown literals to.
</para>
</example>
the numeric category. Therefore, <productname>PostgreSQL</productname>
will use that entry when faced with a non-numeric input:
<screen>
-tgl=> select @ text '-4.5' as "abs";
+SELECT @ '-4.5' AS "abs";
abs
-----
4.5
(1 row)
</screen>
-Here the system has performed an implicit text-to-float8 conversion
-before applying the chosen operator. We can verify that float8 and
+Here the system has performed an implicit conversion from <type>text</type> to <type>float8</type>
+before applying the chosen operator. We can verify that <type>float8</type> and
not some other type was used:
<screen>
-tgl=> select @ text '-4.5e500' as "abs";
+SELECT @ '-4.5e500' AS "abs";
+
ERROR: Input '-4.5e500' is out of range for float8
</screen>
</para>
<para>
On the other hand, the postfix operator <literal>!</> (factorial)
-is defined only for integer data types, not for float8. So, if we
+is defined only for integer data types, not for <type>float8</type>. So, if we
try a similar case with <literal>!</>, we get:
<screen>
-tgl=> select text '20' ! as "factorial";
+SELECT '20' ! AS "factorial";
+
ERROR: Unable to identify a postfix operator '!' for type 'text'
You may need to add parentheses or an explicit cast
</screen>
possible <literal>!</> operators should be preferred. We can help
it out with an explicit cast:
<screen>
-tgl=> select cast(text '20' as int8) ! as "factorial";
+SELECT CAST('20' AS int8) ! AS "factorial";
+
factorial
---------------------
2432902008176640000
<para>
Select the functions to be considered from the
<classname>pg_proc</classname> system catalog. If an unqualified
-function name is used, the functions
+function name was used, the functions
considered are those of the right name and argument count that are
visible in the current search path (see <xref linkend="ddl-schemas-path">).
If a qualified function name was given, only functions in the specified
functions considered), use it.
(Cases involving <type>unknown</type> will never find a match at
this step.)
-</para></step>
+</para>
+</step>
+
<step performance="required">
<para>
If no exact match is found, see whether the function call appears
-to be a trivial type coercion request. This happens if the function call
+to be a trivial type conversion request. This happens if the function call
has just one argument and the function name is the same as the (internal)
name of some data type. Furthermore, the function argument must be either
an unknown-type literal or a type that is binary-compatible with the named
-data type. When these conditions are met, the function argument is coerced
-to the named data type without any explicit function call.
+data type. When these conditions are met, the function argument is converted
+to the named data type without any actual function call.
</para>
</step>
<step performance="required">
<step performance="required">
<para>
Discard candidate functions for which the input types do not match
-and cannot be coerced (using an implicit coercion function) to match.
+and cannot be converted (using an implicit conversion) to match.
<type>unknown</type> literals are
-assumed to be coercible to anything for this purpose. If only one
+assumed to be convertible to anything for this purpose. If only one
candidate remains, use it; else continue to the next step.
</para>
</step>
<step performance="required">
<para>
Run through all candidates and keep those that accept preferred types at
-the most positions where type coercion will be required.
+the most positions where type conversion will be required.
Keep all candidates if none accept preferred types.
If only one candidate remains, use it; else continue to the next step.
</para>
<para>
If any input arguments are <type>unknown</type>, check the type categories accepted
at those argument positions by the remaining candidates. At each position,
-select the <type>string</type> category if any candidate accepts that category
-(this bias towards string
-is appropriate since an unknown-type literal does look like a string).
+select the <type>string</type> category if any candidate accepts that category.
+(This bias towards string
+is appropriate since an unknown-type literal does look like a string.)
Otherwise, if all the remaining candidates accept the same type category,
select that category; otherwise fail because
-the correct choice cannot be deduced without more clues. Also note whether
-any of the candidates accept a preferred data type within the selected category.
+the correct choice cannot be deduced without more clues.
Now discard candidates that do not accept the selected type category;
furthermore, if any candidate accepts a preferred type at a given argument
position, discard candidates that accept non-preferred types for that
</step>
</procedure>
-<bridgehead renderas="sect2">Examples</bridgehead>
+<para>
+Some examples follow.
+</para>
<example>
-<title>Factorial Function Argument Type Resolution</title>
+<title>Rounding Function Argument Type Resolution</title>
<para>
-There is only one <function>int4fac</function> function defined in the
-<classname>pg_proc</classname> catalog.
-So the following query automatically converts the <type>int2</type> argument
-to <type>int4</type>:
+There is only one <function>round</function> function with two
+arguments. (The first is <type>numeric</type>, the second is
+<type>integer</type>.) So the following query automatically converts
+the first argument of type <type>integer</type> to
+<type>numeric</type>:
<screen>
-tgl=> SELECT int4fac(int2 '4');
- int4fac
----------
- 24
+SELECT round(4, 4);
+
+ round
+--------
+ 4.0000
(1 row)
</screen>
-and is actually transformed by the parser to
+That query is actually transformed by the parser to
<screen>
-tgl=> SELECT int4fac(int4(int2 '4'));
- int4fac
----------
- 24
-(1 row)
+SELECT round(CAST (4 AS numeric), 4);
+</screen>
+</para>
+
+<para>
+Since numeric constants with decimal points are initially assigned the
+type <type>numeric</type>, the following query will require no type
+conversion and may therefore be slightly more efficient:
+<screen>
+SELECT round(4.0, 4);
</screen>
</para>
</example>
<title>Substring Function Type Resolution</title>
<para>
-There are two <function>substr</function> functions declared in <classname>pg_proc</classname>. However,
-only one takes two arguments, of types <type>text</type> and <type>int4</type>.
-</para>
+There are several <function>substr</function> functions, one of which
+takes types <type>text</type> and <type>integer</type>. If called
+with a string constant of unspecified type, the system chooses the
+candidate function that accepts an argument of the preferred category
+<literal>string</literal> (namely of type <type>text</type>).
-<para>
-If called with a string constant of unspecified type, the type is matched up
-directly with the only candidate function type:
<screen>
-tgl=> SELECT substr('1234', 3);
+SELECT substr('1234', 3);
+
substr
--------
34
<para>
If the string is declared to be of type <type>varchar</type>, as might be the case
-if it comes from a table, then the parser will try to coerce it to become <type>text</type>:
+if it comes from a table, then the parser will try to convert it to become <type>text</type>:
<screen>
-tgl=> SELECT substr(varchar '1234', 3);
+SELECT substr(varchar '1234', 3);
+
substr
--------
34
(1 row)
</screen>
-which is transformed by the parser to become
+
+This is transformed by the parser to effectively become
<screen>
-tgl=> SELECT substr(text(varchar '1234'), 3);
- substr
---------
- 34
-(1 row)
+SELECT substr(CAST (varchar '1234' AS text), 3);
</screen>
</para>
<para>
<note>
<para>
-Actually, the parser is aware that <type>text</type> and <type>varchar</type>
-are <firstterm>binary-compatible</>, meaning that one can be passed to a function that
+The parser is aware that <type>text</type> and <type>varchar</type>
+are binary-compatible, meaning that one can be passed to a function that
accepts the other without doing any physical conversion. Therefore, no
explicit type conversion call is really inserted in this case.
</para>
</para>
<para>
-And, if the function is called with an <type>int4</type>, the parser will
+And, if the function is called with an argument of type <type>integer</type>, the parser will
try to convert that to <type>text</type>:
<screen>
-tgl=> SELECT substr(1234, 3);
+SELECT substr(1234, 3);
+
substr
--------
34
(1 row)
</screen>
-which actually executes as
+
+This actually executes as
<screen>
-tgl=> SELECT substr(text(1234), 3);
- substr
---------
- 34
-(1 row)
+SELECT substr(CAST (1234 AS text), 3);
</screen>
-This succeeds because there is a conversion function text(int4) in the
-system catalog.
+This automatic transformation can succeed because there is an
+implicitly invocable cast from <type>integer</type> to
+<type>text</type>.
</para>
</example>
</sect1>
<sect1 id="typeconv-query">
-<title>Query Targets</title>
+<title>Value Storage</title>
<para>
- Values to be inserted into a table are coerced to the destination
+ Values to be inserted into a table are converted to the destination
column's data type according to the
following steps.
</para>
<procedure>
-<title>Query Target Type Resolution</title>
+<title>Value Storage Type Conversion</title>
<step performance="required">
<para>
Check for an exact match with the target.
-</para></step>
+</para>
+</step>
+
<step performance="required">
<para>
-Otherwise, try to coerce the expression to the target type. This will succeed
-if the two types are known binary-compatible, or if there is a conversion
-function. If the expression is an unknown-type literal, the contents of
+Otherwise, try to convert the expression to the target type. This will succeed
+if there is a registered cast between the two types.
+If the expression is an unknown-type literal, the contents of
the literal string will be fed to the input conversion routine for the target
type.
-</para></step>
+</para>
+</step>
<step performance="required">
<para>
-If the target is a fixed-length type (e.g. <type>char</type> or <type>varchar</type>
+If the target is a fixed-length type (e.g., <type>char</type> or <type>varchar</type>
declared with a length) then try to find a sizing function for the target
type. A sizing function is a function of the same name as the type,
-taking two arguments of which the first is that type and the second is an
-integer, and returning the same type. If one is found, it is applied,
+taking two arguments of which the first is that type and the second is of type
+<type>integer</type>, and returning the same type. If one is found, it is applied,
passing the column's declared length as the second parameter.
-</para></step>
+</para>
+</step>
</procedure>
<title><type>character</type> Storage Type Conversion</title>
<para>
-For a target column declared as <type>character(20)</type> the following query
-ensures that the target is sized correctly:
+For a target column declared as <type>character(20)</type> the following statement
+ensures that the stored value is sized correctly:
<screen>
-tgl=> CREATE TABLE vv (v character(20));
-CREATE
-tgl=> INSERT INTO vv SELECT 'abc' || 'def';
-INSERT 392905 1
-tgl=> SELECT v, length(v) FROM vv;
+CREATE TABLE vv (v character(20));
+INSERT INTO vv SELECT 'abc' || 'def';
+SELECT v, length(v) FROM vv;
+
v | length
----------------------+--------
abcdef | 20
(1 row)
</screen>
+</para>
+<para>
What has really happened here is that the two unknown literals are resolved
to <type>text</type> by default, allowing the <literal>||</literal> operator
to be resolved as <type>text</type> concatenation. Then the <type>text</type>
-result of the operator is coerced to <type>bpchar</type> (<quote>blank-padded
-char</>, the internal name of the character data type) to match the target
-column type. (Since the parser knows that <type>text</type> and
-<type>bpchar</type> are binary-compatible, this coercion is implicit and does
+result of the operator is converted to <type>bpchar</type> (<quote>blank-padded
+char</>, the internal name of the <type>character</type> data type) to match the target
+column type. (Since the types <type>text</type> and
+<type>bpchar</type> are binary-compatible, this conversion does
not insert any real function call.) Finally, the sizing function
-<literal>bpchar(bpchar, integer)</literal> is found in the system catalogs
+<literal>bpchar(bpchar, integer)</literal> is found in the system catalog
and applied to the operator's result and the stored column length. This
type-specific function performs the required length check and addition of
padding spaces.
A <literal>CASE</> construct also uses the identical algorithm to match up its
component expressions and select a result data type.
</para>
+
<procedure>
<title><literal>UNION</> and <literal>CASE</> Type Resolution</title>
<step performance="required">
<para>
If all inputs are of type <type>unknown</type>, resolve as type
-<type>text</type> (the preferred type for string category).
-Otherwise, ignore the <type>unknown</type> inputs while choosing the type.
-</para></step>
+<type>text</type> (the preferred type of the string category).
+Otherwise, ignore the <type>unknown</type> inputs while choosing the result type.
+</para>
+</step>
<step performance="required">
<para>
If the non-unknown inputs are not all of the same type category, fail.
-</para></step>
+</para>
+</step>
<step performance="required">
<para>
Choose the first non-unknown input type which is a preferred type in
that category or allows all the non-unknown inputs to be implicitly
-coerced to it.
-</para></step>
+converted to it.
+</para>
+</step>
<step performance="required">
<para>
-Coerce all inputs to the selected type.
-</para></step>
+Convert all inputs to the selected type.
+</para>
+</step>
</procedure>
-<bridgehead renderas="sect2">Examples</bridgehead>
+<para>
+Some examples follow.
+</para>
<example>
-<title>Underspecified Types in a Union</title>
+<title>Type Resolution with Underspecified Types in a Union</title>
<para>
<screen>
-tgl=> SELECT text 'a' AS "Text" UNION SELECT 'b';
- Text
+SELECT text 'a' AS "text" UNION SELECT 'b';
+
+ text
------
a
b
(2 rows)
</screen>
-Here, the unknown-type literal <literal>'b'</literal> will be resolved as type text.
+Here, the unknown-type literal <literal>'b'</literal> will be resolved as type <type>text</type>.
</para>
</example>
<example>
-<title>Type Conversion in a Simple Union</title>
+<title>Type Resolution in a Simple Union</title>
<para>
<screen>
-tgl=> SELECT 1.2 AS "Numeric" UNION SELECT 1;
- Numeric
+SELECT 1.2 AS "numeric" UNION SELECT 1;
+
+ numeric
---------
1
1.2
(2 rows)
</screen>
The literal <literal>1.2</> is of type <type>numeric</>,
-and the integer value <literal>1</> can be cast implicitly to
+and the <type>integer</type> value <literal>1</> can be cast implicitly to
<type>numeric</>, so that type is used.
</para>
</example>
<example>
-<title>Type Conversion in a Transposed Union</title>
+<title>Type Resolution in a Transposed Union</title>
<para>
<screen>
-tgl=> SELECT 1 AS "Real"
-tgl-> UNION SELECT CAST('2.2' AS REAL);
- Real
+SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL);
+
+ real
------
1
2.2
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/user-manag.sgml,v 1.18 2002/11/11 20:14:04 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/user-manag.sgml,v 1.19 2003/03/13 01:30:29 petere Exp $
-->
<chapter id="user-manag">
per individual database). To create a user use the <command>CREATE
USER</command> SQL command:
<synopsis>
-CREATE USER <replaceable>name</replaceable>
+CREATE USER <replaceable>name</replaceable>;
</synopsis>
<replaceable>name</replaceable> follows the rules for SQL
identifiers: either unadorned without special characters, or
double-quoted. To remove an existing user, use the analogous
<command>DROP USER</command> command:
<synopsis>
-DROP USER <replaceable>name</replaceable>
+DROP USER <replaceable>name</replaceable>;
</synopsis>
</para>
<para>
- For convenience, the programs <application>createuser</application>
- and <application>dropuser</application> are provided as wrappers
+ For convenience, the programs <command>createuser</command>
+ and <command>dropuser</command> are provided as wrappers
around these SQL commands that can be called from the shell command
line:
<synopsis>
In order to bootstrap the database system, a freshly initialized
system always contains one predefined user. This user will have the
fixed ID 1, and by default (unless altered when running
- <application>initdb</application>) it will have the same name as
- the operating system user that initialized the database
+ <command>initdb</command>) it will have the same name as the
+ operating system user that initialized the database
cluster. Customarily, this user will be named
- <systemitem>postgres</systemitem>. In order to create more users
- you first have to connect as this initial user.
+ <literal>postgres</literal>. In order to create more users you
+ first have to connect as this initial user.
</para>
<para>
database server. The user name to use for a particular database
connection is indicated by the client that is initiating the
connection request in an application-specific fashion. For example,
- the <application>psql</application> program uses the
+ the <command>psql</command> program uses the
<option>-U</option> command line option to indicate the user to
connect as. Many applications assume the name of the current
operating system user by default (including
- <application>createuser</> and <application>psql</>). Therefore it
+ <command>createuser</> and <command>psql</>). Therefore it
is convenient to maintain a naming correspondence between the two
user sets.
</para>
make use of passwords. Database passwords are separate from
operating system passwords. Specify a password upon user
creation with <literal>CREATE USER
- <replaceable>name</replaceable> PASSWORD 'string'</literal>.
+ <replaceable>name</replaceable> PASSWORD '<replaceable>string</>'</literal>.
</para>
</listitem>
</varlistentry>
management of privileges: privileges can be granted to, or revoked
from, a group as a whole. To create a group, use
<synopsis>
-CREATE GROUP <replaceable>name</replaceable>
+CREATE GROUP <replaceable>name</replaceable>;
</synopsis>
To add users to or remove users from a group, use
<synopsis>
-ALTER GROUP <replaceable>name</replaceable> ADD USER <replaceable>uname1</replaceable>, ...
-ALTER GROUP <replaceable>name</replaceable> DROP USER <replaceable>uname1</replaceable>, ...
+ALTER GROUP <replaceable>name</replaceable> ADD USER <replaceable>uname1</replaceable>, ... ;
+ALTER GROUP <replaceable>name</replaceable> DROP USER <replaceable>uname1</replaceable>, ... ;
</synopsis>
</para>
</sect1>
<para>
Functions and triggers allow users to insert code into the backend
server that other users may execute without knowing it. Hence, both
- mechanisms permit users to <firstterm>Trojan horse</firstterm>
+ mechanisms permit users to <quote>Trojan horse</quote>
others with relative impunity. The only real protection is tight
control over who can define functions.
</para>