mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-24 18:55:04 +08:00
Editorial review
This commit is contained in:
parent
a510bf4326
commit
731204e090
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/biblio.sgml,v 1.16 2001/11/21 05:53:40 thomas Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/biblio.sgml,v 1.17 2002/01/07 02:29:11 petere Exp $
|
||||
-->
|
||||
|
||||
<bibliography id="biblio">
|
||||
@ -148,76 +148,6 @@ $Header: /cvsroot/pgsql/doc/src/sgml/biblio.sgml,v 1.16 2001/11/21 05:53:40 thom
|
||||
<title>PostgreSQL-Specific Documentation</title>
|
||||
<para>This section is for related documentation.</para>
|
||||
|
||||
<biblioentry id="admin-guide">
|
||||
<title>The <productname>PostgreSQL</productname> Administrator's Guide</title>
|
||||
<titleabbrev>The Administrator's Guide</titleabbrev>
|
||||
<editor>
|
||||
<firstname>Thomas</firstname>
|
||||
<surname>Lockhart</surname>
|
||||
</editor>
|
||||
|
||||
<pubdate>2001-04-13</pubdate>
|
||||
<publisher>
|
||||
<publishername>The PostgreSQL Global Development Group</publishername>
|
||||
</publisher>
|
||||
</biblioentry>
|
||||
|
||||
<biblioentry id="dev-guide">
|
||||
<title>The <productname>PostgreSQL</productname> Developer's Guide</title>
|
||||
<titleabbrev>The Developer's Guide</titleabbrev>
|
||||
<editor>
|
||||
<firstname>Thomas</firstname>
|
||||
<surname>Lockhart</surname>
|
||||
</editor>
|
||||
|
||||
<pubdate>2001-04-13</pubdate>
|
||||
<publisher>
|
||||
<publishername>The PostgreSQL Global Development Group</publishername>
|
||||
</publisher>
|
||||
</biblioentry>
|
||||
|
||||
<biblioentry id="pro-guide">
|
||||
<title>The <productname>PostgreSQL</productname> Programmer's Guide</title>
|
||||
<titleabbrev>The Programmer's Guide</titleabbrev>
|
||||
<editor>
|
||||
<firstname>Thomas</firstname>
|
||||
<surname>Lockhart</surname>
|
||||
</editor>
|
||||
|
||||
<pubdate>2001-04-13</pubdate>
|
||||
<publisher>
|
||||
<publishername>The PostgreSQL Global Development Group</publishername>
|
||||
</publisher>
|
||||
</biblioentry>
|
||||
|
||||
<biblioentry id="tutorial-guide">
|
||||
<title>The <productname>PostgreSQL</productname> Tutorial Introduction</title>
|
||||
<titleabbrev>The Tutorial</titleabbrev>
|
||||
<editor>
|
||||
<firstname>Thomas</firstname>
|
||||
<surname>Lockhart</surname>
|
||||
</editor>
|
||||
|
||||
<pubdate>2001-04-13</pubdate>
|
||||
<publisher>
|
||||
<publishername>The PostgreSQL Global Development Group</publishername>
|
||||
</publisher>
|
||||
</biblioentry>
|
||||
|
||||
<biblioentry id="users-guide">
|
||||
<title>The <productname>PostgreSQL</productname> User's Guide</title>
|
||||
<titleabbrev>The User's Guide</titleabbrev>
|
||||
<editor>
|
||||
<firstname>Thomas</firstname>
|
||||
<surname>Lockhart</surname>
|
||||
</editor>
|
||||
|
||||
<pubdate>2001-04-13</pubdate>
|
||||
<publisher>
|
||||
<publishername>The PostgreSQL Global Development Group</publishername>
|
||||
</publisher>
|
||||
</biblioentry>
|
||||
|
||||
<biblioentry id="SIM98">
|
||||
<title>Enhancement of the ANSI SQL Implementation of PostgreSQL</title>
|
||||
<titleabbrev>Simkovics, 1998</titleabbrev>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.82 2002/01/04 17:02:02 thomas Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.83 2002/01/07 02:29:11 petere Exp $
|
||||
-->
|
||||
|
||||
<chapter id="datatype">
|
||||
@ -270,7 +270,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.82 2002/01/04 17:02:02 th
|
||||
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
|
||||
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
|
||||
@ -354,7 +354,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.82 2002/01/04 17:02:02 th
|
||||
<para>
|
||||
Numeric types consist of two-, four-, and eight-byte integers,
|
||||
four- and eight-byte
|
||||
floating point numbers and fixed-precision decimals.
|
||||
floating-point numbers and fixed-precision decimals.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -511,7 +511,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.82 2002/01/04 17:02:02 th
|
||||
numbers and carry out all calculations exactly. It is especially
|
||||
recommended for storing monetary amounts and other quantities
|
||||
where exactness is required. However, the <type>numeric</type>
|
||||
type is very slow compared to the floating point types described
|
||||
type is very slow compared to the floating-point types described
|
||||
in the next section.
|
||||
</para>
|
||||
|
||||
@ -568,11 +568,11 @@ NUMERIC
|
||||
|
||||
|
||||
<sect2 id="datatype-float">
|
||||
<title>Floating Point Types</title>
|
||||
<title>Floating-Point Types</title>
|
||||
|
||||
<para>
|
||||
The data types <type>real</type> and <type>double
|
||||
precision</type> are inexact, variable precision numeric types.
|
||||
precision</type> are inexact, variable-precision numeric types.
|
||||
In practice, these types are usually implementations of <acronym>IEEE</acronym> 754
|
||||
binary floating point (single and double precision,
|
||||
respectively), to the extent that the underlying processor,
|
||||
@ -606,7 +606,7 @@ NUMERIC
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Comparing two floating point values for equality may or may
|
||||
Comparing two floating-point values for equality may or may
|
||||
not work as expected.
|
||||
</para>
|
||||
</listitem>
|
||||
@ -682,14 +682,6 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (
|
||||
will never be duplicates, either.
|
||||
</para>
|
||||
|
||||
<important>
|
||||
<para>
|
||||
The implicit sequence created for the <type>serial</type> type will
|
||||
<emphasis>not</emphasis> be automatically removed when the
|
||||
table is dropped.
|
||||
</para>
|
||||
</important>
|
||||
|
||||
<para>
|
||||
The type names <type>serial</type> and <type>serial4</type> are
|
||||
equivalent: both create <type>integer</type> columns. The type
|
||||
@ -741,7 +733,7 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (<replaceabl
|
||||
|
||||
<para>
|
||||
Input is accepted in a variety of formats, including integer and
|
||||
floating point literals, as well as <quote>typical</quote>
|
||||
floating-point literals, as well as <quote>typical</quote>
|
||||
currency formatting, such as <literal>'$1,000.00'</literal>.
|
||||
Output is in the latter form.
|
||||
</para>
|
||||
@ -1165,8 +1157,6 @@ SELECT b, char_length(b) FROM test2;
|
||||
escape character.
|
||||
</para>
|
||||
|
||||
<sect2 id="datatype-binary-compat">
|
||||
<title>Compatibility</title>
|
||||
<para>
|
||||
<type>Bytea</type> provides most of the functionality of the binary
|
||||
string type per SQL99 section 4.3. A comparison of SQL99 Binary
|
||||
@ -1248,7 +1238,6 @@ SELECT b, char_length(b) FROM test2;
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
|
||||
@ -1335,7 +1324,7 @@ SELECT b, char_length(b) FROM test2;
|
||||
specifies the number of fractional digits retained in the seconds
|
||||
field. By default, there is no explicit bound on precision. The
|
||||
effective limit of precision is determined by the underlying double
|
||||
precision floating point number used to store values (in seconds
|
||||
precision floating-point number used to store values (in seconds
|
||||
for <type>interval</type> and
|
||||
in seconds since 2000-01-01 for <type>timestamp</type>). The
|
||||
useful range of <replaceable>p</replaceable> is from 0 to about
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/dfunc.sgml,v 1.17 2001/11/21 05:53:41 thomas Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/dfunc.sgml,v 1.18 2002/01/07 02:29:11 petere Exp $
|
||||
-->
|
||||
|
||||
<sect2 id="dfunc">
|
||||
@ -40,7 +40,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/dfunc.sgml,v 1.17 2001/11/21 05:53:41 thoma
|
||||
|
||||
<para>
|
||||
In the following examples we assume that your source code is in a
|
||||
file <filename>foo.c</filename> and we will create an shared library
|
||||
file <filename>foo.c</filename> and we will create a shared library
|
||||
<filename>foo.so</filename>. The intermediate object file will be
|
||||
called <filename>foo.o</filename> unless otherwise noted. A shared
|
||||
library can contain more than one object file, but we only use one
|
||||
@ -121,8 +121,8 @@ ld -b -o foo.sl foo.o
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><productname>Irix</productname></term>
|
||||
<indexterm><primary>Irix</></>
|
||||
<term><productname>IRIX</productname></term>
|
||||
<indexterm><primary>IRIX</></>
|
||||
<listitem>
|
||||
<para>
|
||||
<acronym>PIC</acronym> is the default, no special compiler
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/ecpg.sgml,v 1.32 2002/01/06 17:54:14 momjian Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/ecpg.sgml,v 1.33 2002/01/07 02:29:11 petere Exp $
|
||||
-->
|
||||
|
||||
<chapter id="ecpg">
|
||||
@ -300,7 +300,7 @@ struct sqlca
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><computeroutput>-206 (ECPG_FLOAT_FORMAT): Not correctly formatted floating point type: %s line %d.</computeroutput></term>
|
||||
<term><computeroutput>-206 (ECPG_FLOAT_FORMAT): Not correctly formatted floating-point type: %s line %d.</computeroutput></term>
|
||||
<listitem>
|
||||
<para>
|
||||
This means the host variable is of type <type>float</type> and
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/extend.sgml,v 1.14 2001/11/21 05:53:41 thomas Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/extend.sgml,v 1.15 2002/01/07 02:29:11 petere Exp $
|
||||
-->
|
||||
|
||||
<chapter id="extend">
|
||||
@ -18,7 +18,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/extend.sgml,v 1.14 2001/11/21 05:53:41 thom
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
types
|
||||
data types
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
@ -56,17 +56,16 @@ $Header: /cvsroot/pgsql/doc/src/sgml/extend.sgml,v 1.14 2001/11/21 05:53:41 thom
|
||||
extended by users. By comparison, conventional
|
||||
database systems can only be extended by changing hardcoded
|
||||
procedures within the <acronym>DBMS</acronym> or by loading modules
|
||||
specially-written by the <acronym>DBMS</acronym> vendor.
|
||||
specially written by the <acronym>DBMS</acronym> vendor.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<productname>PostgreSQL</productname> is also unlike most other data managers in
|
||||
that the server can incorporate user-written code into
|
||||
itself through dynamic loading. That is, the user can
|
||||
specify an object code file (e.g., a compiled .o file
|
||||
or shared library) that implements a new type or function
|
||||
specify an object code file (e.g., a shared library) that implements a new type or function
|
||||
and <productname>PostgreSQL</productname> will load it as required. Code written
|
||||
in <acronym>SQL</acronym> are even more trivial to add to the server.
|
||||
in <acronym>SQL</acronym> is even more trivial to add to the server.
|
||||
This ability to modify its operation <quote>on the fly</quote> makes
|
||||
<productname>PostgreSQL</productname> uniquely suited for rapid prototyping of new
|
||||
applications and storage structures.
|
||||
@ -80,14 +79,14 @@ $Header: /cvsroot/pgsql/doc/src/sgml/extend.sgml,v 1.14 2001/11/21 05:53:41 thom
|
||||
The <productname>PostgreSQL</productname> type system
|
||||
can be broken down in several ways.
|
||||
Types are divided into base types and composite types.
|
||||
Base types are those, like <firstterm>int4</firstterm>, that are implemented
|
||||
in a language such as <productname>C</productname>. They generally correspond to
|
||||
Base types are those, like <type>int4</type>, that are implemented
|
||||
in a language such as C. They generally correspond to
|
||||
what are often known as <firstterm>abstract data types</firstterm>; <productname>PostgreSQL</productname>
|
||||
can only operate on such types through methods provided
|
||||
by the user and only understands the behavior of such
|
||||
types to the extent that the user describes them.
|
||||
Composite types are created whenever the user creates a
|
||||
table. EMP is an example of a composite type.
|
||||
table.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -100,10 +99,10 @@ $Header: /cvsroot/pgsql/doc/src/sgml/extend.sgml,v 1.14 2001/11/21 05:53:41 thom
|
||||
<productname>PostgreSQL</productname> base types are further
|
||||
divided into built-in
|
||||
types and user-defined types. Built-in types (like
|
||||
<firstterm>int4</firstterm>) are those that are compiled
|
||||
<type>int4</type>) are those that are compiled
|
||||
into the system.
|
||||
User-defined types are those created by the user in the
|
||||
manner to be described below.
|
||||
manner to be described later.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
@ -118,7 +117,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/extend.sgml,v 1.14 2001/11/21 05:53:41 thom
|
||||
information given here, so mark this page for later
|
||||
reference.
|
||||
All system catalogs have names that begin with
|
||||
<firstterm>pg_</firstterm>.
|
||||
<literal>pg_</literal>.
|
||||
The following tables contain information that may be
|
||||
useful to the end user. (There are many other system
|
||||
catalogs, but there should rarely be a reason to query
|
||||
@ -149,15 +148,15 @@ $Header: /cvsroot/pgsql/doc/src/sgml/extend.sgml,v 1.14 2001/11/21 05:53:41 thom
|
||||
</row>
|
||||
<row>
|
||||
<entry>pg_index</entry>
|
||||
<entry> secondary indexes</entry>
|
||||
<entry> indexes</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>pg_proc</entry>
|
||||
<entry> procedures (both C and SQL)</entry>
|
||||
<entry> procedures/functions </entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>pg_type</entry>
|
||||
<entry> types (both base and complex)</entry>
|
||||
<entry> data types (both base and complex)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>pg_operator</entry>
|
||||
@ -165,7 +164,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/extend.sgml,v 1.14 2001/11/21 05:53:41 thom
|
||||
</row>
|
||||
<row>
|
||||
<entry>pg_aggregate</entry>
|
||||
<entry> aggregates and aggregate functions</entry>
|
||||
<entry> aggregate functions</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>pg_am</entry>
|
||||
@ -198,7 +197,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/extend.sgml,v 1.14 2001/11/21 05:53:41 thom
|
||||
</mediaobject>
|
||||
</figure>
|
||||
|
||||
The Reference Manual gives a more detailed explanation
|
||||
The <citetitle>Developer's Guide</citetitle> gives a more detailed explanation
|
||||
of these catalogs and their columns. However,
|
||||
<xref linkend="EXTEND-CATALOGS">
|
||||
shows the major entities and their relationships
|
||||
@ -257,10 +256,9 @@ $Header: /cvsroot/pgsql/doc/src/sgml/extend.sgml,v 1.14 2001/11/21 05:53:41 thom
|
||||
have obvious meanings, but there are many
|
||||
(particularly those that have to do with access
|
||||
methods) that do not. The relationships between
|
||||
pg_am, pg_amop, pg_amproc, pg_operator and
|
||||
pg_opclass are particularly hard to understand
|
||||
and will be described in depth (in the section
|
||||
on interfacing types and operators to indexes)
|
||||
<classname>pg_am</>, <classname>pg_amop</>, <classname>pg_amproc</>, <classname>pg_operator</>, and
|
||||
<classname>pg_opclass</> are particularly hard to understand
|
||||
and will be described in depth (in <xref linkend="xindex">)
|
||||
after we have discussed basic extensions.
|
||||
</para>
|
||||
</listitem>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.89 2001/12/27 21:36:57 tgl Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.90 2002/01/07 02:29:12 petere Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
@ -4506,7 +4506,7 @@ SELECT NULLIF(value, '(none)') ...
|
||||
<type>bigint</type>, <type>real</type>, <type>double
|
||||
precision</type>, <type>numeric</type>, <type>interval</type>.
|
||||
The result is of type <type>numeric</type> for any integer type
|
||||
input, <type>double precision</type> for floating point input,
|
||||
input, <type>double precision</type> for floating-point input,
|
||||
otherwise the same as the input data type.
|
||||
</entry>
|
||||
</row>
|
||||
@ -4555,7 +4555,7 @@ SELECT NULLIF(value, '(none)') ...
|
||||
data types: <type>smallint</type>, <type>integer</type>,
|
||||
<type>bigint</type>, <type>real</type>, <type>double
|
||||
precision</type>, <type>numeric</type>. The result is of type
|
||||
<type>double precision</type> for floating point input,
|
||||
<type>double precision</type> for floating-point input,
|
||||
otherwise <type>numeric</type>.
|
||||
</entry>
|
||||
</row>
|
||||
@ -4571,7 +4571,7 @@ SELECT NULLIF(value, '(none)') ...
|
||||
The result is of type <type>bigint</type> for <type>smallint</type>
|
||||
or <type>integer</type> input, <type>numeric</type> for
|
||||
<type>bigint</type>
|
||||
input, <type>double precision</type> for floating point input,
|
||||
input, <type>double precision</type> for floating-point input,
|
||||
otherwise the same as the input data type.
|
||||
</entry>
|
||||
</row>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/history.sgml,v 1.18 2001/11/28 20:49:10 petere Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/history.sgml,v 1.19 2002/01/07 02:29:12 petere Exp $
|
||||
-->
|
||||
|
||||
<sect1 id="history">
|
||||
@ -9,7 +9,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/history.sgml,v 1.18 2001/11/28 20:49:10 pet
|
||||
The object-relational database management system now known as
|
||||
<productname>PostgreSQL</productname> (and briefly called
|
||||
<productname>Postgres95</productname>) is derived from the
|
||||
<productname>Postgres</productname> package written at the University of
|
||||
<productname>POSTGRES</productname> package written at the University of
|
||||
California at Berkeley. With over a decade of
|
||||
development behind it, <productname>PostgreSQL</productname>
|
||||
is the most advanced open-source database available anywhere,
|
||||
@ -20,10 +20,10 @@ $Header: /cvsroot/pgsql/doc/src/sgml/history.sgml,v 1.18 2001/11/28 20:49:10 pet
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>The Berkeley <productname>Postgres</productname> Project</title>
|
||||
<title>The Berkeley <productname>POSTGRES</productname> Project</title>
|
||||
|
||||
<para>
|
||||
Implementation of the <productname>Postgres</productname>
|
||||
Implementation of the <productname>POSTGRES</productname>
|
||||
<acronym>DBMS</acronym> began in 1986. The
|
||||
initial concepts for the system were presented in
|
||||
<xref linkend="STON86">
|
||||
@ -60,24 +60,24 @@ $Header: /cvsroot/pgsql/doc/src/sgml/history.sgml,v 1.18 2001/11/28 20:49:10 pet
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<productname>Postgres</productname> has been used
|
||||
<productname>POSTGRES</productname> has been used
|
||||
to implement many different
|
||||
research and production applications. These include: a
|
||||
financial data analysis system, a jet engine
|
||||
performance monitoring package, an asteroid tracking
|
||||
database, a medical information database, and several
|
||||
geographic information systems.
|
||||
<productname>Postgres</productname> has also been
|
||||
<productname>POSTGRES</productname> has also been
|
||||
used as an educational tool at several universities.
|
||||
Finally,
|
||||
<ulink url="http://www.illustra.com/">Illustra Information Technologies</ulink>
|
||||
(since merged into
|
||||
<ulink url="http://www.informix.com/"><productname>Informix</productname></ulink>)
|
||||
Illustra Information Technologies (later merged into
|
||||
<ulink url="http://www.informix.com/"><productname>Informix</productname></ulink>,
|
||||
which is now owned by <ulink url="http://www.ibm.com/">IBM</ulink>.)
|
||||
picked up
|
||||
the code and commercialized it.
|
||||
<productname>Postgres</productname> became the primary data manager
|
||||
<productname>POSTGRES</productname> became the primary data manager
|
||||
for the
|
||||
<ulink url="http://www.sdsc.edu/0/Parts_Collabs/S2K/s2k_home.html">Sequoia 2000</ulink>
|
||||
<ulink url="http://meteora.ucsd.edu/s2k/s2k_home.html">Sequoia 2000</ulink>
|
||||
scientific computing project in late 1992.
|
||||
</para>
|
||||
|
||||
@ -88,7 +88,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/history.sgml,v 1.18 2001/11/28 20:49:10 pet
|
||||
support was taking up large amounts of time that should
|
||||
have been devoted to database research. In an effort
|
||||
to reduce this support burden, the Berkeley
|
||||
<productname>Postgres</productname> project officially
|
||||
<productname>POSTGRES</productname> project officially
|
||||
ended with Version 4.2.
|
||||
</para>
|
||||
</sect2>
|
||||
@ -98,10 +98,10 @@ $Header: /cvsroot/pgsql/doc/src/sgml/history.sgml,v 1.18 2001/11/28 20:49:10 pet
|
||||
|
||||
<para>
|
||||
In 1994, Andrew Yu and Jolly Chen
|
||||
added a SQL language interpreter to <productname>Postgres</productname>.
|
||||
added a SQL language interpreter to <productname>POSTGRES</productname>.
|
||||
<productname>Postgres95</productname> was subsequently released to
|
||||
the Web to find its own way in the world as an
|
||||
open-source descendant of the original <productname>Postgres</productname>
|
||||
open-source descendant of the original <productname>POSTGRES</productname>
|
||||
Berkeley code.
|
||||
</para>
|
||||
|
||||
@ -109,15 +109,15 @@ $Header: /cvsroot/pgsql/doc/src/sgml/history.sgml,v 1.18 2001/11/28 20:49:10 pet
|
||||
<productname>Postgres95</productname> code was completely
|
||||
ANSI C and trimmed in size by 25%. Many
|
||||
internal changes improved performance and maintainability.
|
||||
<productname>Postgres95</productname> v1.0.x ran about 30-50%
|
||||
<productname>Postgres95</productname> release 1.0.x ran about 30-50%
|
||||
faster on the Wisconsin Benchmark compared to
|
||||
<productname>Postgres</productname> v4.2.
|
||||
Apart from bug fixes, these were the major enhancements:
|
||||
<productname>POSTGRES</productname>, Version 4.2.
|
||||
Apart from bug fixes, the following were the major enhancements:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
The query language <productname>Postquel</productname> was replaced with
|
||||
The query language PostQUEL was replaced with
|
||||
<acronym>SQL</acronym> (implemented in the server).
|
||||
Subqueries were not supported until
|
||||
<productname>PostgreSQL</productname> (see below), but they
|
||||
@ -150,7 +150,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/history.sgml,v 1.18 2001/11/28 20:49:10 pet
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
The large object interface was overhauled. The Inversion large objects were
|
||||
The large-object interface was overhauled. The Inversion large objects were
|
||||
the only mechanism for storing large objects.
|
||||
(The Inversion file system was removed.)
|
||||
</para>
|
||||
@ -175,7 +175,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/history.sgml,v 1.18 2001/11/28 20:49:10 pet
|
||||
<para>
|
||||
<acronym>GNU</acronym> make (instead of <acronym>BSD</acronym> make) was used
|
||||
for the build. Also, <productname>Postgres95</productname> could be
|
||||
compiled with an unpatched <productname>gcc</productname>
|
||||
compiled with an unpatched <productname>GCC</productname>
|
||||
(data alignment of doubles was fixed).
|
||||
</para>
|
||||
</listitem>
|
||||
@ -190,11 +190,11 @@ $Header: /cvsroot/pgsql/doc/src/sgml/history.sgml,v 1.18 2001/11/28 20:49:10 pet
|
||||
By 1996, it became clear that the name <quote>Postgres95</quote> would
|
||||
not stand the test of time. We chose a new name,
|
||||
<productname>PostgreSQL</productname>, to reflect the relationship
|
||||
between the original <productname>Postgres</productname> and the more
|
||||
between the original <productname>POSTGRES</productname> and the more
|
||||
recent versions with <acronym>SQL</acronym> capability. At the same
|
||||
time, we set the version numbering to start at 6.0, putting the
|
||||
numbers back into the sequence originally begun by the
|
||||
<productname>Postgres</productname> Project.
|
||||
numbers back into the sequence originally begun by the Berkeley
|
||||
<productname>POSTGRES</productname> project.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -212,9 +212,9 @@ $Header: /cvsroot/pgsql/doc/src/sgml/history.sgml,v 1.18 2001/11/28 20:49:10 pet
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Table-level locking has been replaced with multiversion concurrency control,
|
||||
Table-level locking has been replaced by multiversion concurrency control,
|
||||
which allows readers to continue reading consistent data during writer activity
|
||||
and enables hot backups from pg_dump while the database stays available for
|
||||
and enables hot backups from <application>pg_dump</> while the database stays available for
|
||||
queries.
|
||||
</para>
|
||||
</listitem>
|
||||
@ -244,7 +244,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/history.sgml,v 1.18 2001/11/28 20:49:10 pet
|
||||
<listitem>
|
||||
<para>
|
||||
Overall backend code speed has been increased by approximately 20-40%,
|
||||
and backend start-up time has decreased 80% since version 6.0 was released.
|
||||
and backend start-up time has decreased by 80% since version 6.0 was released.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/indices.sgml,v 1.30 2001/12/04 01:22:13 tgl Exp $ -->
|
||||
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/indices.sgml,v 1.31 2002/01/07 02:29:12 petere Exp $ -->
|
||||
|
||||
<chapter id="indexes">
|
||||
<title id="indexes-title">Indexes</title>
|
||||
@ -397,8 +397,8 @@ CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable>
|
||||
<literal>bigbox_ops</literal> both support R-tree indexes on the
|
||||
<literal>box</literal> 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
|
||||
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
|
||||
<literal>bigbox_ops</literal>.
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/inherit.sgml,v 1.17 2001/11/21 05:53:41 thomas Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/inherit.sgml,v 1.18 2002/01/07 02:29:12 petere Exp $
|
||||
-->
|
||||
|
||||
<chapter id="inherit">
|
||||
@ -28,7 +28,7 @@ CREATE TABLE capitals (
|
||||
<type>text</type>, a native <productname>PostgreSQL</productname> type for variable length
|
||||
ASCII strings. The type of the attribute population is
|
||||
<type>float</type>, a native <productname>PostgreSQL</productname> type for double precision
|
||||
floating point numbers. State capitals have an extra
|
||||
floating-point numbers. State capitals have an extra
|
||||
attribute, state, that shows their state. In <productname>PostgreSQL</productname>,
|
||||
a table can inherit from zero or more other tables,
|
||||
and a query can reference either all rows of a
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/intro.sgml,v 1.18 2001/11/23 22:06:20 tgl Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/intro.sgml,v 1.19 2002/01/07 02:29:12 petere Exp $
|
||||
-->
|
||||
|
||||
<preface id="preface">
|
||||
@ -38,8 +38,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/intro.sgml,v 1.18 2001/11/23 22:06:20 tgl E
|
||||
type. In current commercial systems, possible types
|
||||
include floating point numbers, integers, character
|
||||
strings, money, and dates. It is commonly recognized
|
||||
that this model is inadequate for future data
|
||||
processing applications.
|
||||
that this model is inadequate for future data-processing applications.
|
||||
The relational model successfully replaced previous
|
||||
models in part because of its <quote>Spartan simplicity</quote>.
|
||||
However, this simplicity makes the
|
||||
@ -76,7 +75,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/intro.sgml,v 1.18 2001/11/23 22:06:20 tgl E
|
||||
<simpara>rules</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>transaction integrity</simpara>
|
||||
<simpara>transactional integrity</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpgeasy.sgml,v 2.7 2001/10/01 21:47:24 momjian Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpgeasy.sgml,v 2.8 2002/01/07 02:29:12 petere Exp $
|
||||
-->
|
||||
|
||||
<chapter id="pgeasy-chapter">
|
||||
<title id="pgeasy"><application>libpgeasy</application> - Simplified C Library</title>
|
||||
<chapter id="pgeasy">
|
||||
<title><application>libpgeasy</application> - Simplified C Library</title>
|
||||
|
||||
<note>
|
||||
<title>Author</title>
|
||||
@ -16,9 +16,10 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpgeasy.sgml,v 2.7 2001/10/01 21:47
|
||||
</note>
|
||||
|
||||
<para>
|
||||
<productname>pgeasy</productname> allows you to cleanly interface
|
||||
to the <productname>libpq</productname> library,
|
||||
more like a 4GL SQL interface.
|
||||
<application>pgeasy</application> allows you to cleanly interface
|
||||
to the <application>libpq</application> library, more like a 4GL
|
||||
SQL interface. Refer to <xref linkend="libpq"> for more
|
||||
information about <application>libpq</application>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -111,8 +112,8 @@ void unset_result(PGresult *oldres);
|
||||
For <literal>SELECT</literal> queries, <function>fetch</function>
|
||||
allows you to pass pointers as parameters, and on return the variables
|
||||
are filled with data from the binary cursor you opened. These binary
|
||||
cursors can not be used if you are running the
|
||||
<productname>pgeasy</productname>
|
||||
cursors cannot be used if you are running the
|
||||
<application>pgeasy</application>
|
||||
client on a system with a different architecture than the database
|
||||
server. If you pass a NULL pointer parameter, the column is skipped.
|
||||
<function>fetchwithnulls</function> allows you to retrieve the NULL
|
||||
|
@ -9,22 +9,28 @@
|
||||
<primary>Tcl</primary>
|
||||
</indexterm>
|
||||
|
||||
<Para>
|
||||
<literal>pgtcl</literal> is a Tcl package for front-end programs
|
||||
to interface with <ProductName>PostgreSQL</ProductName>
|
||||
backends. It makes most of the functionality of <literal>libpq</literal> available to
|
||||
Tcl scripts.
|
||||
</Para>
|
||||
<sect1 id="pgtcl-intro">
|
||||
<title>Introduction</title>
|
||||
|
||||
<Para>
|
||||
This package was originally written by Jolly Chen.
|
||||
</Para>
|
||||
<para>
|
||||
<application>pgtcl</application> is a Tcl package for client
|
||||
programs to interface with <ProductName>PostgreSQL</ProductName>
|
||||
servers. It makes most of the functionality of
|
||||
<application>libpq</application> available to Tcl scripts.
|
||||
</para>
|
||||
|
||||
<Sect1 id="libpgtcl-commands">
|
||||
<Title>Commands</Title>
|
||||
<para>
|
||||
This package was originally written by Jolly Chen.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
<TABLE TOCENTRY="1">
|
||||
<para>
|
||||
<xref linkend="pgtcl-commands-table"> gives an overview over the
|
||||
commands available in <application>pgtcl</application>. These
|
||||
commands are described further on subsequent pages.
|
||||
</para>
|
||||
|
||||
|
||||
<TABLE TOCENTRY="1" id="pgtcl-commands-table">
|
||||
<TITLE><literal>pgtcl</literal> Commands</TITLE>
|
||||
<TGROUP COLS="2">
|
||||
<THEAD>
|
||||
@ -106,34 +112,30 @@ This package was originally written by Jolly Chen.
|
||||
</TBODY>
|
||||
</TGROUP>
|
||||
</TABLE>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
These commands are described further on subsequent pages.
|
||||
</Para>
|
||||
<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
|
||||
<command>BEGIN</command>/<command>COMMIT</command> transaction
|
||||
block because the file 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
|
||||
in a <command>BEGIN</command>/<command>COMMIT</command> transaction
|
||||
block.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
The pg_lo* 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 pg_lo* routines should be used within a BEGIN/END transaction
|
||||
block because the file descriptor returned by pg_lo_open is only valid for
|
||||
the current transaction. pg_lo_import and pg_lo_export MUST be used
|
||||
in a BEGIN/END transaction block.
|
||||
</Para>
|
||||
<para>
|
||||
<xref linkend="pgtcl-example"> shows a small example of how to use
|
||||
the routines.
|
||||
</para>
|
||||
|
||||
</Sect1>
|
||||
|
||||
<Sect1 id="libpgtcl-examples">
|
||||
<Title>Examples</Title>
|
||||
|
||||
<example>
|
||||
<example id="pgtcl-example">
|
||||
<title><application>pgtcl</application> Example Program</title>
|
||||
|
||||
<para>
|
||||
Here's a small example of how to use the routines:
|
||||
|
||||
<programlisting>
|
||||
# getDBs :
|
||||
# get the names of all the databases at a given host and port number
|
||||
@ -151,10 +153,9 @@ proc getDBs { {host "localhost"} {port "5432"} } {
|
||||
pg_disconnect $conn
|
||||
return $datnames
|
||||
}
|
||||
</ProgramListing>
|
||||
</para>
|
||||
</programlisting>
|
||||
</example>
|
||||
</Sect1>
|
||||
</sect1>
|
||||
|
||||
<Sect1 id="libpgtcl-loading">
|
||||
<Title>Loading <application>pgtcl</application> into your application</Title>
|
||||
@ -165,7 +166,7 @@ proc getDBs { {host "localhost"} {port "5432"} } {
|
||||
done with the Tcl <literal>load</> command. Here is an example:
|
||||
|
||||
<programlisting>
|
||||
load libpgtcl[info sharedlibextension]
|
||||
load libpgtcl[info sharedlibextension]
|
||||
</programlisting>
|
||||
|
||||
The use of <literal>info sharedlibextension</> is recommended in
|
||||
@ -174,11 +175,13 @@ proc getDBs { {host "localhost"} {port "5432"} } {
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <literal>load</> command will fail unless the system's dynamic loader
|
||||
knows where to look for the <filename>libpgtcl</> shared library file.
|
||||
You may need to work with <literal>ldconfig</>, or set the environment
|
||||
variable <envar>LD_LIBRARY_PATH</>, or use some equivalent facility for
|
||||
your platform to make it work.
|
||||
The <literal>load</> command will fail unless the system's dynamic
|
||||
loader knows where to look for the <filename>libpgtcl</> shared
|
||||
library file. You may need to work with <command>ldconfig</>, or
|
||||
set the environment variable <envar>LD_LIBRARY_PATH</>, or use
|
||||
some equivalent facility for your platform to make it work. Refer
|
||||
to the <productname>PostgreSQL</> installation instructions for
|
||||
more information.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -209,7 +212,7 @@ proc getDBs { {host "localhost"} {port "5432"} } {
|
||||
<REFNAMEDIV>
|
||||
<REFNAME>pg_connect
|
||||
</REFNAME>
|
||||
<REFPURPOSE>opens a connection to the backend server
|
||||
<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>
|
||||
@ -363,7 +366,7 @@ for info about the available options in the newer syntax.
|
||||
<REFNAMEDIV>
|
||||
<REFNAME>pg_disconnect
|
||||
</REFNAME>
|
||||
<REFPURPOSE>closes a connection to the backend server
|
||||
<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>
|
||||
@ -522,7 +525,7 @@ current default value for each option.
|
||||
<REFNAME>pg_exec
|
||||
</REFNAME>
|
||||
<REFPURPOSE>
|
||||
send a query string to the backend
|
||||
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>
|
||||
@ -999,7 +1002,7 @@ This would work if table <classname>table</> has fields <structfield>control</>
|
||||
<REFNAMEDIV>
|
||||
<REFNAME>pg_listen
|
||||
</REFNAME>
|
||||
<REFPURPOSE>sets or changes a callback for asynchronous NOTIFY messages
|
||||
<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>
|
||||
@ -1859,7 +1862,7 @@ None
|
||||
<REFNAMEDIV>
|
||||
<REFNAME>pg_lo_import
|
||||
</REFNAME>
|
||||
<REFPURPOSE>import a large object from a Unix file
|
||||
<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>
|
||||
@ -1944,7 +1947,7 @@ None
|
||||
<REFNAMEDIV>
|
||||
<REFNAME>pg_lo_export
|
||||
</REFNAME>
|
||||
<REFPURPOSE>export a large object to a Unix file
|
||||
<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>
|
||||
|
@ -1,28 +1,38 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.39 2001/11/29 16:01:15 petere Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.40 2002/01/07 02:29:12 petere Exp $
|
||||
-->
|
||||
|
||||
<chapter id="libpqplusplus">
|
||||
<title><application>libpq++</application> - C++ Binding Library</title>
|
||||
|
||||
<indexterm zone="libpqplusplus">
|
||||
<primary>libpq++</primary>
|
||||
</indexterm>
|
||||
<indexterm zone="libpqplusplus">
|
||||
<primary>C++</primary>
|
||||
</indexterm>
|
||||
|
||||
<sect1 id="libpqpp-introduction">
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>
|
||||
<filename>libpq++</filename> is the C++ API to
|
||||
<application>libpq++</application> is the C++ API to
|
||||
<productname>PostgreSQL</productname>.
|
||||
<filename>libpq++</filename> is a set of classes that allow
|
||||
<application>libpq++</application> is a set of classes that allow
|
||||
client programs to connect to the
|
||||
<productname>PostgreSQL</productname> backend server. These connections
|
||||
come in two forms: a Database Class and a Large Object class.
|
||||
come in two forms: a database class and a large object class.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The Database Class is intended for manipulating a database. You can
|
||||
send all sorts of SQL queries to the <productname>PostgreSQL</productname>
|
||||
The database class is intended for manipulating a database. You can
|
||||
send all sorts of SQL queries and commands to the <productname>PostgreSQL</productname>
|
||||
backend server and retrieve the responses of the server.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The Large Object Class is intended for manipulating a large object
|
||||
in a database. Although a Large Object instance can send normal
|
||||
The large object class is intended for manipulating a large object
|
||||
in a database. Although a large object instance can send normal
|
||||
queries to the <productname>PostgreSQL</productname> backend server
|
||||
it is only intended for simple
|
||||
queries that do not return any data. A large object should be seen
|
||||
@ -35,16 +45,15 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.39 2001/11/29 16:01:
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This chapter is based on the documentation
|
||||
for the <filename>libpq</filename> C library. Three
|
||||
short programs are listed at the end of this section as examples of
|
||||
<filename>libpq++</filename> programming
|
||||
(though not necessarily of good programming).
|
||||
There are several examples of <filename>libpq++</filename>
|
||||
This chapter is based on the documentation for the
|
||||
<application>libpq</application> C library (see <xref
|
||||
linkend="libpq">). There
|
||||
are several examples of <application>libpq++</application>
|
||||
applications in
|
||||
<filename>src/libpq++/examples</filename>, including the source
|
||||
code for the three examples in this chapter.
|
||||
<filename>src/interfaces/libpq++/examples</filename> in the source
|
||||
distribution.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="libpqpp-init">
|
||||
<title>Control and Initialization</title>
|
||||
@ -217,45 +226,51 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.39 2001/11/29 16:01:
|
||||
<para>
|
||||
<function>PgConnection</function>
|
||||
makes a new connection to a backend database server.
|
||||
<synopsis>
|
||||
PgConnection::PgConnection(const char *conninfo)
|
||||
</synopsis>
|
||||
The <quote>conninfo</> string is the same as for the underlying
|
||||
libpq <function>PQconnectdb</> function.
|
||||
<synopsis>
|
||||
PgConnection::PgConnection(const char *conninfo)
|
||||
</synopsis>
|
||||
The <parameter>conninfo</> string is the same as for the underlying
|
||||
<application>libpq</> <function>PQconnectdb</> function.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Although typically called from one of the access classes, a connection to
|
||||
a backend server is possible by creating a <classname>PgConnection</> object.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>ConnectionBad</function>
|
||||
returns whether or not the connection to the backend server succeeded or
|
||||
failed.
|
||||
<synopsis>
|
||||
bool PgConnection::ConnectionBad() const
|
||||
</synopsis>
|
||||
<synopsis>
|
||||
bool PgConnection::ConnectionBad() const
|
||||
</synopsis>
|
||||
Returns true if the connection failed.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>Status</function>
|
||||
returns the status of the connection to the backend server.
|
||||
<synopsis>
|
||||
ConnStatusType PgConnection::Status()
|
||||
</synopsis>
|
||||
Returns either CONNECTION_OK or CONNECTION_BAD depending on the state
|
||||
of the connection.
|
||||
<synopsis>
|
||||
ConnStatusType PgConnection::Status()
|
||||
</synopsis>
|
||||
Returns either <symbol>CONNECTION_OK</> or
|
||||
<symbol>CONNECTION_BAD</> depending on the state of the
|
||||
connection.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PgDatabase</function>
|
||||
makes a new connection to a backend database server.
|
||||
<synopsis>
|
||||
PgDatabase(const char *conninfo)
|
||||
</synopsis>
|
||||
<synopsis>
|
||||
PgDatabase(const char *conninfo)
|
||||
</synopsis>
|
||||
After a <classname>PgDatabase</classname> has been created it should be checked to make sure
|
||||
the connection to the database succeeded before sending
|
||||
queries to the object. This can easily be done by
|
||||
@ -263,24 +278,26 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.39 2001/11/29 16:01:
|
||||
<function>Status</function> or <function>ConnectionBad</function> methods.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>DBName</function>
|
||||
Returns the name of the current database.
|
||||
<synopsis>
|
||||
const char *PgConnection::DBName()
|
||||
</synopsis>
|
||||
returns the name of the current database.
|
||||
<synopsis>
|
||||
const char *PgConnection::DBName()
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>Notifies</function>
|
||||
Returns the next notification from a list of unhandled notification messages
|
||||
returns the next notification from a list of unhandled notification messages
|
||||
received from the backend.
|
||||
<synopsis>
|
||||
PGnotify* PgConnection::Notifies()
|
||||
</synopsis>
|
||||
See <function>PQnotifies</function> for details.
|
||||
<synopsis>
|
||||
PGnotify* PgConnection::Notifies()
|
||||
</synopsis>
|
||||
See <function>PQnotifies</function> in <application>libpq</> for details.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
@ -297,19 +314,20 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.39 2001/11/29 16:01:
|
||||
<listitem>
|
||||
<para>
|
||||
<function>Exec</function>
|
||||
Sends a query to the backend server. It's probably more desirable to
|
||||
sends a command to the backend server. It's probably more desirable to
|
||||
use one of the next two functions.
|
||||
<synopsis>
|
||||
ExecStatusType PgConnection::Exec(const char* query)
|
||||
</synopsis>
|
||||
Returns the result of the query. The following status results can be expected:
|
||||
<synopsis>
|
||||
ExecStatusType PgConnection::Exec(const char* query)
|
||||
</synopsis>
|
||||
Returns the result status of the command. The following status
|
||||
results can be expected:
|
||||
|
||||
<simplelist>
|
||||
<member>
|
||||
<symbol>PGRES_EMPTY_QUERY</symbol>
|
||||
</member>
|
||||
<member>
|
||||
<symbol>PGRES_COMMAND_OK</symbol>, if the query was a command
|
||||
<symbol>PGRES_COMMAND_OK</symbol>, if the command was not a query
|
||||
</member>
|
||||
<member>
|
||||
<symbol>PGRES_TUPLES_OK</symbol>, if the query successfully returned tuples
|
||||
@ -332,353 +350,342 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.39 2001/11/29 16:01:
|
||||
</simplelist>
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>ExecCommandOk</function>
|
||||
Sends a command query to the backend server.
|
||||
<synopsis>
|
||||
int PgConnection::ExecCommandOk(const char *query)
|
||||
</synopsis>
|
||||
Returns TRUE if the command query succeeds.
|
||||
<function>ExecCommandOk</function> sends a non-query command
|
||||
(one that does not return rows) to the backend server.
|
||||
<synopsis>
|
||||
int PgConnection::ExecCommandOk(const char *query)
|
||||
</synopsis>
|
||||
Returns true (1) if the command succeeds.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>ExecTuplesOk</function>
|
||||
Sends a command query to the backend server.
|
||||
<synopsis>
|
||||
int PgConnection::ExecTuplesOk(const char *query)
|
||||
</synopsis>
|
||||
Returns TRUE if the command query succeeds.
|
||||
Sends a query command (one that returns rows) to the backend server.
|
||||
<synopsis>
|
||||
int PgConnection::ExecTuplesOk(const char *query)
|
||||
</synopsis>
|
||||
Returns true (1) if the query succeeds.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>ErrorMessage</function>
|
||||
Returns the last error message text.
|
||||
<synopsis>
|
||||
const char *PgConnection::ErrorMessage()
|
||||
</synopsis>
|
||||
returns the last error message text.
|
||||
<synopsis>
|
||||
const char *PgConnection::ErrorMessage()
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="libpqpp-exec-select-info">
|
||||
<title>Retrieving SELECT Result Information</title>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>Tuples</function>
|
||||
Returns the number of tuples (rows) in the query result.
|
||||
<synopsis>
|
||||
int PgDatabase::Tuples() const
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>Fields</function>
|
||||
Returns the number of fields (attributes) in each tuple of the query result.
|
||||
<synopsis>
|
||||
int PgDatabase::Fields()
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>FieldName</function>
|
||||
Returns the field (attribute) name associated with the given field index.
|
||||
Field indices start at 0.
|
||||
<synopsis>
|
||||
const char *PgDatabase::FieldName(int field_num) const
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>FieldNum</function>
|
||||
<function>PQfnumber</function> Returns the field (attribute) index associated with
|
||||
the given field name.
|
||||
<synopsis>
|
||||
int PgDatabase::FieldNum(const char* field_name) const
|
||||
</synopsis>
|
||||
-1 is returned if the given name does not match any field.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>FieldType</function>
|
||||
Returns the field type associated with the given field index. The
|
||||
integer returned is an internal coding of the type. Field indices
|
||||
start at 0.
|
||||
<synopsis>
|
||||
Oid PgDatabase::FieldType(int field_num) const
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>FieldType</function>
|
||||
Returns the field type associated with the given field name. The
|
||||
integer returned is an internal coding of the type. Field indices
|
||||
start at 0.
|
||||
<synopsis>
|
||||
Oid PgDatabase::FieldType(const char* field_name) const
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>FieldSize</function>
|
||||
Returns the size in bytes of the field associated with the given
|
||||
field index. Field indices start at 0.
|
||||
<synopsis>
|
||||
int PgDatabase::FieldSize(int field_num) const
|
||||
</synopsis>
|
||||
Returns the space allocated for this field in a database tuple given
|
||||
the field number. 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>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>FieldSize</function>
|
||||
Returns the size in bytes of the field associated with the given
|
||||
field index. Field indices start at 0.
|
||||
<synopsis>
|
||||
int PgDatabase::FieldSize(const char *field_name) const
|
||||
</synopsis>
|
||||
Returns the space allocated for this field in a database tuple given
|
||||
the field name. 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>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>Tuples</function>
|
||||
returns the number of tuples (rows) in the query result.
|
||||
<synopsis>
|
||||
int PgDatabase::Tuples() const
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>Fields</function>
|
||||
returns the number of fields (rows) in each tuple of the query result.
|
||||
<synopsis>
|
||||
int PgDatabase::Fields()
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>FieldName</function>
|
||||
returns the field (column) name associated with the given field index.
|
||||
Field indices start at 0.
|
||||
<synopsis>
|
||||
const char *PgDatabase::FieldName(int field_num) const
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>FieldNum</function>
|
||||
returns the field (column) index associated with
|
||||
the given field name.
|
||||
<synopsis>
|
||||
int PgDatabase::FieldNum(const char* field_name) const
|
||||
</synopsis>
|
||||
-1 is returned if the given name does not match any field.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>FieldType</function>
|
||||
returns the field type associated with the given field index. The
|
||||
integer returned is an internal coding of the type. Field indices
|
||||
start at 0.
|
||||
<synopsis>
|
||||
Oid PgDatabase::FieldType(int field_num) const
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>FieldType</function>
|
||||
returns the field type associated with the given field name. The
|
||||
integer returned is an internal coding of the type. Field indices
|
||||
start at 0.
|
||||
<synopsis>
|
||||
Oid PgDatabase::FieldType(const char* field_name) const
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>FieldSize</function>
|
||||
returns the size in bytes of the field associated with the given
|
||||
field index. Field indices start at 0.
|
||||
<synopsis>
|
||||
int PgDatabase::FieldSize(int field_num) const
|
||||
</synopsis>
|
||||
Returns the space allocated for this field in a database tuple
|
||||
given the field number. 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>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>FieldSize</function>
|
||||
returns the size in bytes of the field associated with the given
|
||||
field index. Field indices start at 0.
|
||||
<synopsis>
|
||||
int PgDatabase::FieldSize(const char *field_name) const
|
||||
</synopsis>
|
||||
Returns the space allocated for this field in a database tuple
|
||||
given the field name. 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>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
|
||||
|
||||
<sect2 id="libpqpp-exec-select-values">
|
||||
<title>Retrieving SELECT Result Values</title>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>GetValue</function>
|
||||
Returns a single field (attribute) value of one tuple of a <structname>PGresult</structname>.
|
||||
Tuple and field indices start at 0.
|
||||
<synopsis>
|
||||
const char *PgDatabase::GetValue(int tup_num, int field_num) const
|
||||
</synopsis>
|
||||
For most queries, the value returned by <function>GetValue</function> is a null-terminated
|
||||
string representation of the attribute value. But if <function>BinaryTuples</function>
|
||||
is TRUE, the value returned by <function>GetValue</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). It is then the programmer's
|
||||
responsibility to cast and convert the data to the correct C type. The
|
||||
pointer returned by <function>GetValue</function> points to storage that is part of the
|
||||
<structname>PGresult</structname> structure. One should not modify it, and one must explicitly
|
||||
copy the value into other storage if it is to be used past the lifetime
|
||||
of the <structname>PGresult</structname> structure itself. <function>BinaryTuples</function> is not yet implemented.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>GetValue</function>
|
||||
Returns a single field (attribute) value of one tuple of a <structname>PGresult</structname>.
|
||||
Tuple and field indices start at 0.
|
||||
<synopsis>
|
||||
const char *PgDatabase::GetValue(int tup_num, const char *field_name) const
|
||||
</synopsis>
|
||||
For most queries, the value returned by <function>GetValue</function> is a null-terminated
|
||||
string representation of the attribute value. But if <function>BinaryTuples</function>
|
||||
is TRUE, the value returned by <function>GetValue</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). It is then the programmer's
|
||||
responsibility to cast and convert the data to the correct C type. The
|
||||
pointer returned by <function>GetValue</function> points to storage that is part of the
|
||||
<structname>PGresult</structname> structure. One should not modify it, and one must explicitly
|
||||
copy the value into other storage if it is to be used past the lifetime
|
||||
of the <structname>PGresult</structname> structure itself. <function>BinaryTuples</function> is not yet implemented.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>GetLength</function>
|
||||
Returns the length of a field (attribute) in bytes. Tuple and field
|
||||
indices start at 0.
|
||||
<synopsis>
|
||||
int PgDatabase::GetLength(int tup_num, int field_num) const
|
||||
</synopsis>
|
||||
This is the actual data length for the particular data value, that
|
||||
is the size of the object pointed to by <function>GetValue</function>. Note that for
|
||||
ASCII-represented values, this size has little to do with the binary
|
||||
size reported by <function>PQfsize</function>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>GetLength</function>
|
||||
Returns the length of a field (attribute) in bytes. Tuple and field
|
||||
indices start at 0.
|
||||
<synopsis>
|
||||
int PgDatabase::GetLength(int tup_num, const char* field_name) const
|
||||
</synopsis>
|
||||
This is the actual data length for the particular data value, that
|
||||
is the size of the object pointed to by <function>GetValue</function>. Note that for
|
||||
ASCII-represented values, this size has little to do with the binary
|
||||
size reported by <function>PQfsize</function>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>GetIsNull</function>
|
||||
Returns whether a field has the null value.
|
||||
<synopsis>
|
||||
bool GetIsNull(int tup_num, int field_num) const
|
||||
</synopsis>
|
||||
Note that <function>GetValue</function> will return the empty string for null fields, not
|
||||
the NULL pointer.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>GetIsNull</function>
|
||||
Returns whether a field has the null value.
|
||||
<synopsis>
|
||||
bool GetIsNull(int tup_num, const char *field_name) const
|
||||
</synopsis>
|
||||
Note that <function>GetValue</function> will return the empty string for null fields, not
|
||||
the NULL pointer.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>DisplayTuples</function>
|
||||
OBSOLESCENT: Prints out all the tuples and, optionally, the attribute names to the
|
||||
specified output stream.
|
||||
<synopsis>
|
||||
void PgDatabase::DisplayTuples(FILE *out = 0, bool fillAlign = true,
|
||||
const char* fieldSep = "|",bool printHeader = true, bool quiet = false) const
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PrintTuples</function>
|
||||
OBSOLESCENT: Prints out all the tuples and, optionally, the attribute names to the
|
||||
specified output stream.
|
||||
<synopsis>
|
||||
void PgDatabase::PrintTuples(FILE *out = 0, bool printAttName = true,
|
||||
bool terseOutput = false, bool fillAlign = false) const
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>GetValue</function> returns a single field (column)
|
||||
value of one tuple of a <structname>PGresult</structname>.
|
||||
Tuple and field indices start at 0.
|
||||
<synopsis>
|
||||
const char *PgDatabase::GetValue(int tup_num, int field_num) const
|
||||
</synopsis>
|
||||
For most queries, the value returned by
|
||||
<function>GetValue</function> is a null-terminated string
|
||||
representation of the attribute value. But if
|
||||
<function>BinaryTuples</function> is true, the value returned by
|
||||
<function>GetValue</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). It is
|
||||
then the programmer's responsibility to cast and convert the
|
||||
data to the correct C type. The pointer returned by
|
||||
<function>GetValue</function> points to storage that is part of
|
||||
the <structname>PGresult</structname> structure. One should not
|
||||
modify it, and one must explicitly copy the value into other
|
||||
storage if it is to be used past the lifetime of the
|
||||
<structname>PGresult</structname> structure itself.
|
||||
<function>BinaryTuples</function> is not yet implemented.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>GetValue</function> returns a single field (column)
|
||||
value of one tuple of a <structname>PGresult</structname>.
|
||||
Tuple and field indices start at 0.
|
||||
<synopsis>
|
||||
const char *PgDatabase::GetValue(int tup_num, const char *field_name) const
|
||||
</synopsis>
|
||||
For most queries, the value returned by
|
||||
<function>GetValue</function> is a null-terminated string
|
||||
representation of the attribute value. But if
|
||||
<function>BinaryTuples</function> is true, the value returned by
|
||||
<function>GetValue</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). It is
|
||||
then the programmer's responsibility to cast and convert the
|
||||
data to the correct C type. The pointer returned by
|
||||
<function>GetValue</function> points to storage that is part of
|
||||
the <structname>PGresult</structname> structure. One should not
|
||||
modify it, and one must explicitly copy the value into other
|
||||
storage if it is to be used past the lifetime of the
|
||||
<structname>PGresult</structname> structure itself.
|
||||
<function>BinaryTuples</function> is not yet implemented.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>GetLength</function> returns the length of a field
|
||||
(column) in bytes. Tuple and field indices start at 0.
|
||||
<synopsis>
|
||||
int PgDatabase::GetLength(int tup_num, int field_num) const
|
||||
</synopsis>
|
||||
This is the actual data length for the particular data value,
|
||||
that is the size of the object pointed to by
|
||||
<function>GetValue</function>. Note that for
|
||||
character-represented values, this size has little to do with
|
||||
the binary size reported by <function>PQfsize</function>.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>GetLength</function> returns the length of a field
|
||||
(column) in bytes. Tuple and field indices start at 0.
|
||||
<synopsis>
|
||||
int PgDatabase::GetLength(int tup_num, const char* field_name) const
|
||||
</synopsis>
|
||||
This is the actual data length for the particular data value,
|
||||
that is the size of the object pointed to by
|
||||
<function>GetValue</function>. Note that for
|
||||
character-represented values, this size has little to do with
|
||||
the binary size reported by <function>PQfsize</function>.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>GetIsNull</function>
|
||||
returns whether a field has the null value.
|
||||
<synopsis>
|
||||
bool GetIsNull(int tup_num, int field_num) const
|
||||
</synopsis>
|
||||
Note that <function>GetValue</function> will return the empty
|
||||
string for null fields, not the NULL pointer.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>GetIsNull</function> returns whether a field has the
|
||||
null value.
|
||||
<synopsis>
|
||||
bool GetIsNull(int tup_num, const char *field_name) const
|
||||
</synopsis>
|
||||
Note that <function>GetValue</function> will return the empty
|
||||
string for null fields, not the NULL pointer.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>DisplayTuples</function> prints out all the tuples
|
||||
and, optionally, the attribute names to the specified output
|
||||
stream.
|
||||
<synopsis>
|
||||
void PgDatabase::DisplayTuples(FILE *out = 0, bool fillAlign = true,
|
||||
const char* fieldSep = "|", bool printHeader = true, bool quiet = false) const
|
||||
</synopsis>
|
||||
This function is obsolescent.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PrintTuples</function> prints out all the tuples and,
|
||||
optionally, the attribute names to the specified output stream.
|
||||
<synopsis>
|
||||
void PgDatabase::PrintTuples(FILE *out = 0, bool printAttName = true,
|
||||
bool terseOutput = false, bool fillAlign = false) const
|
||||
</synopsis>
|
||||
This function is obsolescent.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="libpqpp-exec-nonselect">
|
||||
<title>Retrieving Non-SELECT Result Information</title>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>CmdTuples</function>
|
||||
Returns the number of rows affected after an INSERT, UPDATE or DELETE.
|
||||
If the command was anything else, it returns -1.
|
||||
<synopsis>
|
||||
int PgDatabase::CmdTuples() const
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>CmdTuples</function> returns the number of rows
|
||||
affected after an <command>INSERT</command>,
|
||||
<command>UPDATE</command>, or <command>DELETE</command>. If the
|
||||
command was anything else, it returns -1.
|
||||
<synopsis>
|
||||
int PgDatabase::CmdTuples() const
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>OidStatus</function>
|
||||
<synopsis>
|
||||
const char *PgDatabase::OidStatus() const
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>OidStatus</function>
|
||||
<synopsis>
|
||||
const char *PgDatabase::OidStatus() const
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="libpqpp-exec-copy">
|
||||
<title>Handling COPY Queries</title>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>GetLine</function>
|
||||
<synopsis>
|
||||
int PgDatabase::GetLine(char* string, int length)
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PutLine</function>
|
||||
<synopsis>
|
||||
void PgDatabase::PutLine(const char* string)
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>EndCopy</function>
|
||||
<synopsis>
|
||||
int PgDatabase::EndCopy()
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
</sect2>
|
||||
</sect1>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="libpqpp-notify">
|
||||
<title>Asynchronous Notification</title>
|
||||
|
||||
<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 semaphore
|
||||
with the <command>LISTEN</command> command.
|
||||
All backends that are listening on a
|
||||
particular named semaphore will be notified asynchronously when
|
||||
a <command>NOTIFY</command> of
|
||||
that name is executed by another backend. No additional
|
||||
information is passed from the notifier to the listener. Thus,
|
||||
typically, any actual data that needs to be communicated is transferred
|
||||
through the relation.
|
||||
|
||||
<note>
|
||||
<para>
|
||||
In the past, the documentation has associated the names used for asynchronous
|
||||
notification with relations or classes. However, there is in fact no
|
||||
direct linkage of the two concepts in the implementation, and the
|
||||
named semaphore in fact does not need to have a corresponding relation
|
||||
previously defined.
|
||||
</para>
|
||||
</note>
|
||||
<productname>PostgreSQL</productname> supports asynchronous
|
||||
notification via the <command>LISTEN</command> and
|
||||
<command>NOTIFY</command> commands. A backend registers its
|
||||
interest in a particular notification condition with the
|
||||
<command>LISTEN</command> command. All backends that are
|
||||
listening on a particular condition will be notified
|
||||
asynchronously when a <command>NOTIFY</command> of that name is
|
||||
executed by another backend. 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
|
||||
relation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<filename>libpq++</filename> applications are notified whenever a
|
||||
<application>libpq++</application> applications are notified whenever a
|
||||
connected backend has
|
||||
received an asynchronous notification. However, the communication from
|
||||
the backend to the frontend is not asynchronous.
|
||||
The <filename>libpq++</filename> application
|
||||
The <application>libpq++</application> application
|
||||
must poll the backend to see if there is any pending notification
|
||||
information. After the execution of a query, a frontend may call
|
||||
information. After the execution of a command, a frontend may call
|
||||
<function>PgDatabase::Notifies</function>
|
||||
to see if any notification data is currently available from the backend.
|
||||
<function>PgDatabase::Notifies</function>
|
||||
returns the notification from a list of unhandled notifications from the
|
||||
backend. The function returns NULL if there are no pending notifications
|
||||
backend. The function returns <symbol>NULL</symbol> if there are no pending notifications
|
||||
from the backend.
|
||||
<function>PgDatabase::Notifies</function>
|
||||
behaves like the popping of a stack. Once a notification is returned
|
||||
@ -692,9 +699,9 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.39 2001/11/29 16:01:
|
||||
<function>PgDatabase::Notifies</function>
|
||||
retrieves pending notifications from the server.
|
||||
|
||||
<synopsis>
|
||||
PGnotify* PgDatabase::Notifies()
|
||||
</synopsis>
|
||||
<synopsis>
|
||||
PGnotify* PgDatabase::Notifies()
|
||||
</synopsis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
@ -709,9 +716,9 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.39 2001/11/29 16:01:
|
||||
<title>Functions Associated with the COPY Command</title>
|
||||
|
||||
<para>
|
||||
The <command>copy</command> command in <productname>PostgreSQL</productname>
|
||||
The <command>COPY</command> command in <productname>PostgreSQL</productname>
|
||||
has options to read from or write to the network
|
||||
connection used by <filename>libpq++</filename>.
|
||||
connection used by <application>libpq++</application>.
|
||||
Therefore, functions are necessary to
|
||||
access this network connection directly so applications may take full
|
||||
advantage of this capability.
|
||||
@ -724,32 +731,33 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.39 2001/11/29 16:01:
|
||||
backend server) into a buffer
|
||||
<replaceable class="parameter">string</replaceable>
|
||||
of size <replaceable class="parameter">length</replaceable>.
|
||||
<synopsis>
|
||||
int PgDatabase::GetLine(char* string, int length)
|
||||
</synopsis>
|
||||
<synopsis>
|
||||
int PgDatabase::GetLine(char* string, int length)
|
||||
</synopsis>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Like the Unix system routine
|
||||
<function>fgets (3)</function>,
|
||||
<function>fgets()</function>,
|
||||
this routine copies up to
|
||||
<literal><replaceable class="parameter">length</replaceable>-1</literal>
|
||||
characters into
|
||||
<replaceable class="parameter">string</replaceable>.
|
||||
It is like
|
||||
<function>gets (3)</function>,
|
||||
however, in that it converts the terminating newline into a null
|
||||
character.
|
||||
<function>gets()</function>,
|
||||
however, in that it converts the terminating newline into a zero byte.
|
||||
</para>
|
||||
<para>
|
||||
<function>PgDatabase::GetLine</function>
|
||||
returns EOF at end of file, 0 if the entire line has been read, and 1 if the
|
||||
returns <symbol>EOF</symbol> at end of file, 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 new line consists
|
||||
of a single period ("."), which indicates that the backend
|
||||
of a backslash followed by a period (<literal>\.</>), which indicates
|
||||
that the backend
|
||||
server has finished sending the results of the
|
||||
<command>copy</command>.
|
||||
<command>COPY</command>.
|
||||
Therefore, if the application ever expects to receive lines
|
||||
that are more than
|
||||
<literal><replaceable class="parameter">length</replaceable>-1</literal>
|
||||
@ -762,24 +770,24 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.39 2001/11/29 16:01:
|
||||
<function>PgDatabase::PutLine</function>
|
||||
Sends a null-terminated <replaceable class="parameter">string</replaceable>
|
||||
to the backend server.
|
||||
<synopsis>
|
||||
void PgDatabase::PutLine(char* string)
|
||||
</synopsis>
|
||||
<synopsis>
|
||||
void PgDatabase::PutLine(char* string)
|
||||
</synopsis>
|
||||
</para>
|
||||
<para>
|
||||
The application must explicitly send a single period character (".")
|
||||
The application must explicitly send the characters <literal>\.</literal>
|
||||
to indicate to the backend that it has finished sending its data.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PgDatabase::EndCopy</function>
|
||||
syncs with the backend.
|
||||
<synopsis>
|
||||
int PgDatabase::EndCopy()
|
||||
</synopsis>
|
||||
synchronizes with the backend.
|
||||
<synopsis>
|
||||
int PgDatabase::EndCopy()
|
||||
</synopsis>
|
||||
This function waits until the backend has
|
||||
finished processing the <command>copy</command>.
|
||||
finished processing the <command>COPY</command>.
|
||||
It should either be issued when the
|
||||
last string has been sent to the backend using
|
||||
<function>PgDatabase::PutLine</function>
|
||||
@ -787,7 +795,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.39 2001/11/29 16:01:
|
||||
<function>PgDatabase::GetLine</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
|
||||
receive the next query.
|
||||
receive the next command.
|
||||
</para>
|
||||
<para>
|
||||
The return value is 0 on successful completion, nonzero otherwise.
|
||||
@ -795,19 +803,20 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.39 2001/11/29 16:01:
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
As an example:
|
||||
|
||||
<programlisting>
|
||||
<programlisting>
|
||||
PgDatabase data;
|
||||
data.Exec("CREATE TABLE foo (a int4, b char(16), d double precision)");
|
||||
data.Exec("COPY foo FROM STDIN");
|
||||
data.PutLine("3\tHello World\t4.5\n");
|
||||
data.PutLine("4\tGoodbye World\t7.11\n");
|
||||
&...
|
||||
...
|
||||
data.PutLine("\\.\n");
|
||||
data.EndCopy();
|
||||
</programlisting>
|
||||
</programlisting>
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.84 2001/11/29 16:01:15 petere Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.85 2002/01/07 02:29:12 petere Exp $
|
||||
-->
|
||||
|
||||
<chapter id="libpq">
|
||||
@ -9,6 +9,9 @@ $Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.84 2001/11/29 16:01:15 peter
|
||||
<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
|
||||
@ -40,6 +43,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.84 2001/11/29 16:01:15 peter
|
||||
header file <filename>libpq-fe.h</filename> and must link with the
|
||||
<filename>libpq</filename> library.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="libpq-connect">
|
||||
<title>Database Connection Functions</title>
|
||||
@ -303,11 +307,11 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn)
|
||||
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 SELECT for reading on <function>PQsocket(conn)</function>. If
|
||||
it last returned <symbol>PGRES_POLLING_WRITING</symbol>, perform a SELECT for writing on
|
||||
<symbol>PGRES_POLLING_READING</symbol>, perform a <function>select()</> for reading on <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
|
||||
to <function>PQconnectStart</function>, behave as if it last returned <symbol>PGRES_POLLING_WRITING</symbol>. If
|
||||
the SELECT shows that the socket is ready, consider it <quote>active</quote>. If it has
|
||||
the <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
|
||||
@ -353,7 +357,7 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn)
|
||||
<term><symbol>CONNECTION_AWAITING_RESPONSE</symbol></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Waiting for a response from the postmaster.
|
||||
Waiting for a response from the server.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -362,7 +366,7 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn)
|
||||
<term><symbol>CONNECTION_AUTH_OK</symbol></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Received authentication; waiting for backend start-up.
|
||||
Received authentication; waiting for connection start-up to continue.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -372,14 +376,14 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn)
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Negotiating environment.
|
||||
Negotiating environment (part of the connection start-up).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
Note that, although these constants will remain (in order to maintain
|
||||
compatibility) an application should never rely upon these appearing in a
|
||||
compatibility), an application should never rely upon these appearing in a
|
||||
particular order, or at all, or on the status always being one of these
|
||||
documented values. An application may do something like this:
|
||||
<programlisting>
|
||||
@ -487,7 +491,7 @@ void PQreset(PGconn *conn)
|
||||
</synopsis>
|
||||
This function will close the connection
|
||||
to the backend and attempt to reestablish a new
|
||||
connection to the same postmaster, using all the same
|
||||
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>
|
||||
@ -505,7 +509,7 @@ int PQresetStart(PGconn *conn);
|
||||
PostgresPollingStatusType PQresetPoll(PGconn *conn);
|
||||
</synopsis>
|
||||
These functions will close the connection to the backend and attempt to
|
||||
reestablish a new connection to the same postmaster, using all the same
|
||||
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
|
||||
act in a nonblocking manner. These functions suffer from the same
|
||||
@ -528,7 +532,7 @@ PostgresPollingStatusType PQresetPoll(PGconn *conn);
|
||||
maintain the <structname>PGconn</structname> abstraction. Use the accessor functions below to get
|
||||
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>PostgreSQK</productname> release 6.4, the
|
||||
(Beginning in <productname>PostgreSQL</productname> release 6.4, the
|
||||
definition of struct <structname>PGconn</structname> 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
|
||||
@ -623,7 +627,7 @@ ConnStatusType PQstatus(const PGconn *conn)
|
||||
seen outside of an asynchronous connection procedure -
|
||||
<literal>CONNECTION_OK</literal> or
|
||||
<literal>CONNECTION_BAD</literal>. A good
|
||||
connection to the database has the status CONNECTION_OK.
|
||||
connection to the database has the status <literal>CONNECTION_OK</literal>.
|
||||
A failed connection
|
||||
attempt is signaled by status
|
||||
<literal>CONNECTION_BAD</literal>.
|
||||
@ -705,7 +709,7 @@ SSL *PQgetssl(const PGconn *conn);
|
||||
</sect1>
|
||||
|
||||
<sect1 id="libpq-exec">
|
||||
<title>Query Execution Functions</title>
|
||||
<title>Command Execution Functions</title>
|
||||
|
||||
<para>
|
||||
Once a connection to a database server has been successfully
|
||||
@ -719,7 +723,7 @@ SQL queries and commands.
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PQexec</function>
|
||||
Submit a query to the server
|
||||
Submit a command to the server
|
||||
and wait for the result.
|
||||
<synopsis>
|
||||
PGresult *PQexec(PGconn *conn,
|
||||
@ -728,7 +732,7 @@ PGresult *PQexec(PGconn *conn,
|
||||
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 query to the backend.
|
||||
to send the command to the backend.
|
||||
If a NULL 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.
|
||||
@ -737,7 +741,7 @@ PGresult *PQexec(PGconn *conn,
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
The <function>PGresult</function> structure encapsulates the query result
|
||||
The <function>PGresult</function> structure encapsulates the result
|
||||
returned by the backend.
|
||||
<filename>libpq</filename> application programmers should be careful to
|
||||
maintain the <structname>PGresult</structname> abstraction. Use the accessor functions below to get
|
||||
@ -754,7 +758,7 @@ soon.)
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PQresultStatus</function>
|
||||
Returns the result status of the query.
|
||||
Returns the result status of the command.
|
||||
<synopsis>
|
||||
ExecStatusType PQresultStatus(const PGresult *res)
|
||||
</synopsis>
|
||||
@ -789,9 +793,9 @@ ExecStatusType PQresultStatus(const PGresult *res)
|
||||
|
||||
If the result status is <literal>PGRES_TUPLES_OK</literal>, then the
|
||||
routines described below can be used to retrieve the
|
||||
tuples returned by the query. Note that a SELECT that
|
||||
happens to retrieve zero tuples still shows <literal>PGRES_TUPLES_OK</literal>.
|
||||
<literal>PGRES_COMMAND_OK</literal> is for commands that can never return tuples
|
||||
rows returned by the query. Note that a SELECT 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
|
||||
(INSERT, UPDATE, etc.). A response of <literal>PGRES_EMPTY_QUERY</literal> often
|
||||
exposes a bug in the client software.
|
||||
</para>
|
||||
@ -875,8 +879,8 @@ as with a <structname>PGresult</structname> returned by <application>libpq</appl
|
||||
size_t PQescapeString (char *to, const char *from, size_t length);
|
||||
</synopsis>
|
||||
If you want to include strings that have been received
|
||||
from a source that is not trustworthy (for example, because they were
|
||||
transmitted across a network), you cannot directly include them in SQL
|
||||
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.
|
||||
</para>
|
||||
@ -884,20 +888,20 @@ characters that are otherwise interpreted by the SQL parser.
|
||||
<function>PQescapeString</> performs this operation. The
|
||||
<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 NUL character is
|
||||
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
|
||||
version of the <parameter>from</> string to the <parameter>to</>
|
||||
buffer, replacing special characters so that they cannot cause any
|
||||
harm, and adding a terminating NUL character. The single quotes that
|
||||
harm, and adding a terminating zero byte. The single quotes that
|
||||
must surround <productname>PostgreSQL</> string literals are not part of the result
|
||||
string.
|
||||
</para>
|
||||
<para>
|
||||
<function>PQescapeString</> returns the number of characters written
|
||||
to <parameter>to</>, not including the terminating NUL character.
|
||||
to <parameter>to</>, not including the terminating zero byte.
|
||||
Behavior is undefined when the <parameter>to</> and <parameter>from</>
|
||||
strings overlap.
|
||||
</para>
|
||||
@ -911,21 +915,22 @@ strings overlap.
|
||||
</indexterm>
|
||||
<para>
|
||||
<function>PQescapeBytea</function>
|
||||
Escapes a binary string (bytea type) for use within an SQL query.
|
||||
Escapes a binary string (<type>bytea</type> type) for use within an SQL query.
|
||||
<synopsis>
|
||||
unsigned char *PQescapeBytea(unsigned char *from,
|
||||
size_t from_length,
|
||||
size_t *to_length);
|
||||
</synopsis>
|
||||
|
||||
Certain <acronym>ASCII</acronym> characters MUST be escaped (but all
|
||||
characters MAY be escaped) when used as part of a <type>BYTEA</type>
|
||||
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 Binary String data type
|
||||
in the User's Guide for more information. <function>PQescapeBytea
|
||||
special alternate escape sequences. See the <citetitle>User's Guide</citetitle>
|
||||
for more information. <function>PQescapeBytea
|
||||
</function> performs this operation, escaping only the minimally
|
||||
required characters.
|
||||
</para>
|
||||
@ -934,20 +939,20 @@ strings overlap.
|
||||
The <parameter>from</parameter> parameter points to the first
|
||||
character 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 NUL character is
|
||||
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
|
||||
escaped string length. The result string length does not
|
||||
include the terminating NUL character of the result.
|
||||
include 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
|
||||
<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 PostgreSQL string literal
|
||||
parser, and the <type>bytea</type> input function. A terminating NUL
|
||||
character is also added. The single quotes that must surround
|
||||
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>
|
||||
</sect2>
|
||||
@ -972,7 +977,7 @@ int PQntuples(const PGresult *res);
|
||||
<para>
|
||||
<function>PQnfields</function>
|
||||
Returns the number of fields
|
||||
(attributes) in each tuple of the query result.
|
||||
(columns) in each row of the query result.
|
||||
<synopsis>
|
||||
int PQnfields(const PGresult *res);
|
||||
</synopsis>
|
||||
@ -983,7 +988,7 @@ int PQnfields(const PGresult *res);
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PQfname</function>
|
||||
Returns the field (attribute) name associated with the given field index.
|
||||
Returns the field (column) name associated with the given field index.
|
||||
Field indices start at 0.
|
||||
<synopsis>
|
||||
char *PQfname(const PGresult *res,
|
||||
@ -995,7 +1000,7 @@ char *PQfname(const PGresult *res,
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PQfnumber</function>
|
||||
Returns the field (attribute) index
|
||||
Returns the field (column) index
|
||||
associated with the given field name.
|
||||
<synopsis>
|
||||
int PQfnumber(const PGresult *res,
|
||||
@ -1065,7 +1070,7 @@ int PQfsize(const PGresult *res,
|
||||
int PQbinaryTuples(const PGresult *res);
|
||||
</synopsis>
|
||||
Currently, binary tuple data can only be returned by a query that
|
||||
extracts data from a <acronym>BINARY</acronym> cursor.
|
||||
extracts data from a binary cursor.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
@ -1078,7 +1083,7 @@ extracts data from a <acronym>BINARY</acronym> cursor.
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PQgetvalue</function>
|
||||
Returns a single field (attribute) value of one tuple
|
||||
Returns a single field (column) value of one tuple (row)
|
||||
of a <structname>PGresult</structname>.
|
||||
Tuple and field indices start at 0.
|
||||
<synopsis>
|
||||
@ -1087,7 +1092,7 @@ char* PQgetvalue(const PGresult *res,
|
||||
int field_num);
|
||||
</synopsis>
|
||||
For most queries, the value returned by <function>PQgetvalue</function>
|
||||
is a null-terminated <acronym>ASCII</acronym> string representation
|
||||
is a null-terminated character string representation
|
||||
of the attribute value. But if <function>PQbinaryTuples()</function> is 1,
|
||||
the value returned by <function>PQgetvalue</function> is the binary
|
||||
representation of the
|
||||
@ -1199,7 +1204,7 @@ char * PQcmdTuples(const PGresult *res);
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PQoidValue</function>
|
||||
Returns the object id of the tuple inserted, if the
|
||||
Returns the object ID of the inserted row, if the
|
||||
<acronym>SQL</acronym> command was an INSERT
|
||||
that inserted exactly one row into a table that has OIDs.
|
||||
Otherwise, returns <literal>InvalidOid</literal>.
|
||||
@ -1215,7 +1220,7 @@ Oid PQoidValue(const PGresult *res);
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PQoidStatus</function>
|
||||
Returns a string with the object id of the tuple inserted, if the
|
||||
Returns a string with the object ID of the inserted row, if the
|
||||
<acronym>SQL</acronym> command was an INSERT.
|
||||
(The string will be <literal>0</> if the INSERT did not insert exactly one
|
||||
row, or if the target table does not have OIDs.) If the command
|
||||
@ -1238,14 +1243,14 @@ and is not thread-safe.
|
||||
<indexterm zone="libpq-async"><primary>nonblocking connection</></>
|
||||
|
||||
<para>
|
||||
The <function>PQexec</function> function is adequate for submitting queries in
|
||||
The <function>PQexec</function> function is adequate for submitting commands in
|
||||
simple synchronous
|
||||
applications. It has a couple of major deficiencies however:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PQexec</function> waits for the query to be completed. The application may have other
|
||||
<function>PQexec</function> waits for the command to be completed. The application may have other
|
||||
work to do (such as maintaining a user interface), in which case it won't
|
||||
want to block waiting for the response.
|
||||
</para>
|
||||
@ -1253,13 +1258,13 @@ want to block waiting for the response.
|
||||
<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 query. (It can be
|
||||
to decide 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>
|
||||
<function>PQexec</function> can return only one <structname>PGresult</structname> structure. If the submitted query
|
||||
<function>PQexec</function> can return only one <structname>PGresult</structname> structure. If the submitted command
|
||||
string contains multiple <acronym>SQL</acronym> commands, all but the last <structname>PGresult</structname> are
|
||||
discarded by <function>PQexec</function>.
|
||||
</para>
|
||||
@ -1275,7 +1280,7 @@ underlying functions that <function>PQexec</function> is built from:
|
||||
<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 backend. To
|
||||
address that issue, the function <function>PQsetnonblocking</function>
|
||||
was added.
|
||||
</para>
|
||||
@ -1304,7 +1309,7 @@ int PQsetnonblocking(PGconn *conn, int arg)
|
||||
again.
|
||||
</para>
|
||||
<para>
|
||||
When a database connection has been set to non-blocking mode and
|
||||
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>
|
||||
completes.
|
||||
@ -1330,19 +1335,19 @@ int PQisnonblocking(const PGconn *conn)
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PQsendQuery</function>
|
||||
Submit a query to <productname>PostgreSQL</productname> without
|
||||
waiting for the result(s). 1 is returned if the query was
|
||||
Submit 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
|
||||
PQerrorMessage to get more information about the failure).
|
||||
<function>PQerrorMessage</> to get more information about the failure).
|
||||
<synopsis>
|
||||
int PQsendQuery(PGconn *conn,
|
||||
const char *query);
|
||||
</synopsis>
|
||||
After successfully calling <function>PQsendQuery</function>, call
|
||||
<function>PQgetResult</function> one or more
|
||||
times to obtain the query results. <function>PQsendQuery</function> may not be called
|
||||
times to obtain the results. <function>PQsendQuery</function> may not be called
|
||||
again (on the same connection) until <function>PQgetResult</function> has returned NULL,
|
||||
indicating that the query is done.
|
||||
indicating that the command is done.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
@ -1356,9 +1361,9 @@ int PQsendQuery(PGconn *conn,
|
||||
PGresult *PQgetResult(PGconn *conn);
|
||||
</synopsis>
|
||||
<function>PQgetResult</function> must be called repeatedly until it returns NULL,
|
||||
indicating that the query is done. (If called when no query is
|
||||
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
|
||||
Each non-NULL result from <function>PQgetResult</function> should be processed using
|
||||
the same 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
|
||||
@ -1372,11 +1377,11 @@ PGresult *PQgetResult(PGconn *conn);
|
||||
<para>
|
||||
Using <function>PQsendQuery</function> and <function>PQgetResult</function>
|
||||
solves one of <function>PQexec</function>'s problems:
|
||||
If a query string contains multiple <acronym>SQL</acronym> commands, the results of those
|
||||
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
|
||||
queries in the same query string.) However, calling <function>PQgetResult</function> will
|
||||
queries in the same command string.) However, calling <function>PQgetResult</function> will
|
||||
still cause the frontend to block until the backend completes the
|
||||
next <acronym>SQL</acronym> command. This can be avoided by proper use of three more
|
||||
functions:
|
||||
@ -1401,9 +1406,9 @@ their state has changed.
|
||||
<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
|
||||
causing a <function>select</function>(2) read-ready indication to go away. The
|
||||
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.
|
||||
<function>select()</function> condition immediately, and then examine the results at leisure.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
@ -1425,13 +1430,13 @@ state will never end.
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PQflush</function> Attempt to flush any data queued to the backend,
|
||||
returns 0 if successful (or if the send queue is empty) or EOF if it failed for
|
||||
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>
|
||||
<function>PQflush</function> needs to be called on a nonblocking connection
|
||||
before calling <function>select</function> to determine if a response has
|
||||
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
|
||||
<function>PQsetnonblocking</function> have a need for this.
|
||||
@ -1448,17 +1453,17 @@ backend that has not actually been sent. Only applications that have used
|
||||
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>(2). This allows an
|
||||
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>(2) indicates that data can be read from
|
||||
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>
|
||||
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>
|
||||
@ -1469,7 +1474,7 @@ to the backend.
|
||||
|
||||
<para>
|
||||
A typical frontend using these functions will have a main loop that uses
|
||||
<function>select</function>(2) to wait for all the conditions that it must
|
||||
<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
|
||||
descriptor identified by <function>PQsocket</function>.
|
||||
@ -1482,7 +1487,7 @@ if <function>PQisBusy</function> returns false (0). It can also call
|
||||
|
||||
<para>
|
||||
A frontend that uses <function>PQsendQuery</function>/<function>PQgetResult</function>
|
||||
can also attempt to cancel a query that is still being processed by the backend.
|
||||
can also attempt to cancel a command that is still being processed by the backend.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -1491,7 +1496,7 @@ can also attempt to cancel a query that is still being processed by the backend.
|
||||
<para>
|
||||
<function>PQrequestCancel</function>
|
||||
Request that <productname>PostgreSQL</productname> abandon
|
||||
processing of the current query.
|
||||
processing of the current command.
|
||||
<synopsis>
|
||||
int PQrequestCancel(PGconn *conn);
|
||||
</synopsis>
|
||||
@ -1501,9 +1506,9 @@ 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 query will terminate early and return
|
||||
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 query), then there will
|
||||
backend was already done processing the command), then there will
|
||||
be no visible result at all.
|
||||
</para>
|
||||
</listitem>
|
||||
@ -1511,7 +1516,7 @@ be no visible result at all.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Note that if the current query is part of a transaction, cancellation
|
||||
Note that if the current command is part of a transaction, cancellation
|
||||
will abort the whole transaction.
|
||||
</para>
|
||||
|
||||
@ -1523,16 +1528,16 @@ 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 query.
|
||||
is not currently open or the backend is not currently processing a command.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1 id="libpq-fastpath">
|
||||
<title>Fast Path</title>
|
||||
<title>The Fast-Path Interface</title>
|
||||
|
||||
<para>
|
||||
<productname>PostgreSQL</productname> provides a fast path interface to send
|
||||
<productname>PostgreSQL</productname> provides a fast-path interface to send
|
||||
function calls to the backend. This is a trapdoor into system internals and
|
||||
can be a potential security hole. Most users will not need this feature.
|
||||
|
||||
@ -1540,7 +1545,7 @@ can be a potential security hole. Most users will not need this feature.
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PQfn</function>
|
||||
Request execution of a backend function via the fast path interface.
|
||||
Request execution of a backend function via the fast-path interface.
|
||||
<synopsis>
|
||||
PGresult* PQfn(PGconn* conn,
|
||||
int fnid,
|
||||
@ -1560,7 +1565,7 @@ PGresult* PQfn(PGconn* conn,
|
||||
<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
|
||||
result_is_int is 0, the byte string sent by the backend is returned
|
||||
<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>
|
||||
@ -1604,7 +1609,7 @@ not necessary for there to be any associated relation.
|
||||
|
||||
<para>
|
||||
<filename>libpq</filename> applications submit <command>LISTEN</command> and <command>UNLISTEN</command>
|
||||
commands as ordinary SQL queries. Subsequently, arrival of <command>NOTIFY</command>
|
||||
commands as ordinary SQL command. Subsequently, arrival of <command>NOTIFY</command>
|
||||
messages can be detected by calling <function>PQnotifies</function>.
|
||||
|
||||
<itemizedlist>
|
||||
@ -1658,10 +1663,10 @@ A better way to check for NOTIFY
|
||||
messages when you have no useful queries to make is to call
|
||||
<function>PQconsumeInput()</function>, then check
|
||||
<function>PQnotifies()</function>.
|
||||
You can use <function>select</function>(2) to wait for backend data to
|
||||
You can use <function>select()</function> to wait for backend data to
|
||||
arrive, 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>.)
|
||||
number to use with <function>select()</function>.)
|
||||
Note that this will work OK whether you submit queries with
|
||||
<function>PQsendQuery</function>/<function>PQgetResult</function> or simply
|
||||
use <function>PQexec</function>. You should, however, remember to
|
||||
@ -1706,10 +1711,10 @@ int PQgetline(PGconn *conn,
|
||||
char *string,
|
||||
int length)
|
||||
</synopsis>
|
||||
Like <function>fgets</function>(3), this routine copies up to length-1 characters
|
||||
into string. It is like <function>gets</function>(3), however, in that it converts
|
||||
the terminating newline into a null character.
|
||||
<function>PQgetline</function> returns <literal>EOF</literal> at EOF, 0 if the
|
||||
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
|
||||
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>
|
||||
@ -1776,7 +1781,7 @@ actually available.)
|
||||
<para>
|
||||
<function>PQputline</function>
|
||||
Sends a null-terminated string to the backend server.
|
||||
Returns 0 if OK, <literal>EOF</literal> if unable to send the string.
|
||||
Returns 0 if OK, <symbol>EOF</symbol> if unable to send the string.
|
||||
<synopsis>
|
||||
int PQputline(PGconn *conn,
|
||||
const char *string);
|
||||
@ -1791,7 +1796,7 @@ the backend that it has finished sending its data.
|
||||
<para>
|
||||
<function>PQputnbytes</function>
|
||||
Sends a non-null-terminated string to the backend server.
|
||||
Returns 0 if OK, EOF if unable to send the string.
|
||||
Returns 0 if OK, <symbol>EOF</symbol> if unable to send the string.
|
||||
<synopsis>
|
||||
int PQputnbytes(PGconn *conn,
|
||||
const char *buffer,
|
||||
@ -1806,7 +1811,7 @@ specified directly.
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PQendcopy</function>
|
||||
Syncs with the backend. This function waits until
|
||||
Synchronizes with the backend. This function waits until
|
||||
the backend has finished the copy. It should
|
||||
either be issued when the last string has been
|
||||
sent to the backend using <function>PQputline</function> or when the
|
||||
@ -1814,7 +1819,7 @@ specified directly.
|
||||
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
|
||||
receive the next query.
|
||||
receive the next SQL command.
|
||||
The return value is 0 on successful completion,
|
||||
nonzero otherwise.
|
||||
<synopsis>
|
||||
@ -1856,7 +1861,7 @@ Older applications are likely to submit a copy in or copy out
|
||||
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
|
||||
<acronym>SQL</acronym> command in the query string.
|
||||
<acronym>SQL</acronym> command in the command string.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
@ -2065,7 +2070,7 @@ sets the default time zone.
|
||||
<listitem>
|
||||
<para>
|
||||
<envar>PGCLIENTENCODING</envar>
|
||||
sets the default client encoding (if MULTIBYTE support was selected
|
||||
sets the default client encoding (if multibyte support was selected
|
||||
when configuring <productname>PostgreSQL</productname>).
|
||||
</para>
|
||||
</listitem>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.24 2001/11/12 19:19:39 petere Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.25 2002/01/07 02:29:12 petere Exp $
|
||||
-->
|
||||
|
||||
<chapter id="largeObjects">
|
||||
@ -106,19 +106,19 @@ $Header: /cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.24 2001/11/12 19:19:39 petere
|
||||
|
||||
<para>
|
||||
The <productname>PostgreSQL</productname> large object interface is modeled after
|
||||
the <acronym>Unix</acronym> file system interface, with analogues of
|
||||
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 beard could
|
||||
be declared on <type>mugshot</type> data. Beard could look at the
|
||||
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 beard function.
|
||||
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
|
||||
@ -140,7 +140,7 @@ Oid lo_creat(PGconn *<replaceable class="parameter">conn</replaceable>, int <rep
|
||||
object. The symbolic constants listed here are defined
|
||||
in the header file <filename>libpq/libpq-fs.h</filename>.
|
||||
The access type (read, write, or both) is controlled by
|
||||
OR'ing together the bits <symbol>INV_READ</symbol> and
|
||||
or'ing together the bits <symbol>INV_READ</symbol> and
|
||||
<symbol>INV_WRITE</symbol>. The low-order sixteen bits of the mask have
|
||||
historically been used at Berkeley to designate the storage manager number on which the large object
|
||||
should reside. These
|
||||
@ -156,12 +156,12 @@ inv_oid = lo_creat(INV_READ|INV_WRITE);
|
||||
<title>Importing a Large Object</title>
|
||||
|
||||
<para>
|
||||
To import a <acronym>UNIX</acronym> file as a large object, call
|
||||
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>)
|
||||
</synopsis>
|
||||
<replaceable class="parameter">filename</replaceable>
|
||||
specifies the <acronym>Unix</acronym> path name of
|
||||
specifies the operating system name of
|
||||
the file to be imported as a large object.
|
||||
</para>
|
||||
</sect2>
|
||||
@ -171,13 +171,13 @@ Oid lo_import(PGconn *<replaceable class="parameter">conn</replaceable>, const c
|
||||
|
||||
<para>
|
||||
To export a large object
|
||||
into <acronym>UNIX</acronym> file, call
|
||||
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>)
|
||||
</synopsis>
|
||||
The <parameter>lobjId</parameter> argument specifies the Oid of the large
|
||||
object to export and the <parameter>filename</parameter> argument specifies
|
||||
the <acronym>UNIX</acronym> path name of the file.
|
||||
the operating system name name of the file.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
@ -191,7 +191,7 @@ int lo_open(PGconn *conn, Oid lobjId, int mode)
|
||||
</synopsis>
|
||||
The <parameter>lobjId</parameter> argument specifies the Oid of the large
|
||||
object to open. The <parameter>mode</parameter> bits control whether the
|
||||
object is opened for reading (<symbol>INV_READ</>), writing or
|
||||
object is opened for reading (<symbol>INV_READ</>), writing (<symbol>INV_WRITE</symbol>), or
|
||||
both.
|
||||
A large object cannot be opened before it is created.
|
||||
<function>lo_open</function> returns a large object descriptor
|
||||
@ -241,9 +241,9 @@ int lo_read(PGconn *conn, int fd, char *buf, size_t len)
|
||||
int lo_lseek(PGconn *conn, int fd, int offset, int whence)
|
||||
</programlisting>
|
||||
This routine moves the current location pointer for the
|
||||
large object described by fd to the new location specified
|
||||
by offset. The valid values for whence are
|
||||
SEEK_SET, SEEK_CUR, and SEEK_END.
|
||||
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</>.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
@ -255,7 +255,7 @@ int lo_lseek(PGconn *conn, int fd, int offset, int whence)
|
||||
<programlisting>
|
||||
int lo_close(PGconn *conn, int fd)
|
||||
</programlisting>
|
||||
where fd is a large object descriptor returned by
|
||||
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>
|
||||
@ -281,8 +281,8 @@ Oid lo_unlink(PGconn *<replaceable class="parameter">conn</replaceable>, Oid lob
|
||||
<title>Server-side Built-in Functions</title>
|
||||
|
||||
<para>
|
||||
There are two built-in registered functions, <acronym>lo_import</acronym>
|
||||
and <acronym>lo_export</acronym> which are convenient for use
|
||||
There are two built-in registered functions, <function>lo_import</function>
|
||||
and <function>lo_export</function> which are convenient for use
|
||||
in <acronym>SQL</acronym>
|
||||
queries.
|
||||
Here is an example of their use
|
||||
@ -295,7 +295,7 @@ CREATE TABLE image (
|
||||
INSERT INTO image (name, raster)
|
||||
VALUES ('beautiful image', lo_import('/etc/motd'));
|
||||
|
||||
SELECT lo_export(image.raster, '/tmp/motd') from image
|
||||
SELECT lo_export(image.raster, '/tmp/motd') FROM image
|
||||
WHERE name = 'beautiful image';
|
||||
</programlisting>
|
||||
</para>
|
||||
@ -305,24 +305,18 @@ SELECT lo_export(image.raster, '/tmp/motd') from image
|
||||
<title>Accessing Large Objects from <application>Libpq</application></title>
|
||||
|
||||
<para>
|
||||
Below is a sample program which shows how the large object
|
||||
<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 readers
|
||||
commented out but are left in the source for the reader's
|
||||
benefit. This program can be found in
|
||||
<filename>
|
||||
../src/test/examples
|
||||
</filename>
|
||||
<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>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="lo-example">
|
||||
<title>Example Program</title>
|
||||
|
||||
<example>
|
||||
<example id="lo-example">
|
||||
<title>Large Objects with <application>Libpq</application> Example Program</title>
|
||||
<programlisting>
|
||||
/*--------------------------------------------------------------
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/odbc.sgml,v 1.28 2001/11/21 05:53:41 thomas Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/odbc.sgml,v 1.29 2002/01/07 02:29:12 petere Exp $
|
||||
-->
|
||||
|
||||
<chapter id="odbc">
|
||||
@ -23,6 +23,9 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/odbc.sgml,v 1.28 2001/11/21 05:53:41
|
||||
<primary>ODBC</primary>
|
||||
</indexterm>
|
||||
|
||||
<sect1 id="odbc-intro">
|
||||
<title>Introduction</title>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Background information originally by Tim Goeke
|
||||
@ -38,12 +41,9 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/odbc.sgml,v 1.28 2001/11/21 05:53:41
|
||||
<acronym>ODBC</acronym> provides a product-neutral interface
|
||||
between frontend applications and database servers,
|
||||
allowing a user or developer to write applications that are
|
||||
transportable between servers from different manufacturers..
|
||||
portable between servers from different manufacturers..
|
||||
</para>
|
||||
|
||||
<sect1 id="odbc-background">
|
||||
<title>Background</title>
|
||||
|
||||
<para>
|
||||
The <acronym>ODBC</acronym> <acronym>API</acronym> matches up
|
||||
on the backend to an <acronym>ODBC</acronym>-compatible data source.
|
||||
@ -52,9 +52,9 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/odbc.sgml,v 1.28 2001/11/21 05:53:41
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The backend access come from <acronym>ODBC</acronym> drivers,
|
||||
The backend access comes from <acronym>ODBC</acronym> drivers,
|
||||
or vendor-specific drivers that
|
||||
allow data access. <productname>psqlODBC</productname> is such a driver,
|
||||
allow data access. <productname>psqlODBC</productname>, which is included in the <productname>PostgreSQL</> distribution, is such a driver,
|
||||
along with others that are
|
||||
available, such as the <productname>OpenLink</productname> <acronym>ODBC</acronym> drivers.
|
||||
</para>
|
||||
@ -62,7 +62,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/odbc.sgml,v 1.28 2001/11/21 05:53:41
|
||||
<para>
|
||||
Once you write an <acronym>ODBC</acronym> application,
|
||||
you <emphasis>should</emphasis> be able to connect to <emphasis>any</emphasis>
|
||||
back end database, regardless of the vendor, as long as the database schema
|
||||
back-end database, regardless of the vendor, as long as the database schema
|
||||
is the same.
|
||||
</para>
|
||||
|
||||
@ -71,8 +71,8 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/odbc.sgml,v 1.28 2001/11/21 05:53:41
|
||||
and <productname>PostgreSQL</productname> servers that have
|
||||
exactly the same data. Using <acronym>ODBC</acronym>,
|
||||
your Windows application would make exactly the
|
||||
same calls and the back end data source would look the same (to the Windows
|
||||
app).
|
||||
same calls and the back-end data source would look the same (to the Windows
|
||||
application).
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
@ -173,7 +173,7 @@ psql -d template1 -f <replaceable>LOCATION</>/odbc.sql
|
||||
<filename>~/.odbc.ini</filename> contains user-specified access information
|
||||
for the <productname>psqlODBC</productname> driver.
|
||||
The file uses conventions typical for <productname>Windows</productname>
|
||||
Registry files, but despite this restriction can be made to work.
|
||||
Registry files.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -186,12 +186,12 @@ psql -d template1 -f <replaceable>LOCATION</>/odbc.sql
|
||||
Each section must be labeled with the name given in
|
||||
<literal>[ODBC Data Sources]</literal> and must contain the following entries:
|
||||
|
||||
<programlisting>
|
||||
<programlisting>
|
||||
Driver = <replaceable>prefix</replaceable>/lib/libpsqlodbc.so
|
||||
Database=<replaceable>DatabaseName</replaceable>
|
||||
Servername=localhost
|
||||
Port=5432
|
||||
</programlisting>
|
||||
Database = <replaceable>DatabaseName</replaceable>
|
||||
Servername = localhost
|
||||
Port = 5432
|
||||
</programlisting>
|
||||
|
||||
<tip>
|
||||
<para>
|
||||
@ -212,7 +212,7 @@ Port=5432
|
||||
Here is an example <filename>.odbc.ini</filename> file,
|
||||
showing access information for three databases:
|
||||
|
||||
<programlisting>
|
||||
<programlisting>
|
||||
[ODBC Data Sources]
|
||||
DataEntry = Read/Write Database
|
||||
QueryOnly = Read-only Database
|
||||
@ -246,7 +246,7 @@ Driver = /opt/postgres/current/lib/libpsqlodbc.so
|
||||
|
||||
[ODBC]
|
||||
InstallDir = /opt/applix/axdata/axshlib
|
||||
</programlisting>
|
||||
</programlisting>
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
@ -298,19 +298,20 @@ InstallDir = /opt/applix/axdata/axshlib
|
||||
The <acronym>ODBC</acronym> <acronym>API</acronym>
|
||||
is the way to go.
|
||||
For <productname>Visual C++</productname> coding you can find out more at
|
||||
Microsoft's web site or in your <productname>VC++</productname> docs.
|
||||
Microsoft's web site or in your <productname>Visual C++</productname>
|
||||
documentation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Visual Basic and the other <acronym>RAD</acronym> tools have <classname>Recordset</classname> objects
|
||||
that use <acronym>ODBC</acronym>
|
||||
directly to access data. Using the data-aware controls, you can quickly
|
||||
link to the <acronym>ODBC</acronym> back end database
|
||||
link to the <acronym>ODBC</acronym> back-end database
|
||||
(<emphasis>very</emphasis> quickly).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Playing around with MS Access will help you sort this out. Try using
|
||||
Playing around with <productname>MS Access</> will help you sort this out. Try using
|
||||
<menuchoice><guimenu>File</><guimenuitem>Get External Data</></menuchoice>.
|
||||
</para>
|
||||
|
||||
@ -354,7 +355,7 @@ InstallDir = /opt/applix/axdata/axshlib
|
||||
<title>Enabling <application>ApplixWare</application> Database Access</title>
|
||||
|
||||
<para>
|
||||
These instructions are for the <literal>4.4.2</literal> release of
|
||||
These instructions are for the 4.4.2 release of
|
||||
<productname>ApplixWare</productname> on <productname>Linux</productname>.
|
||||
Refer to the <citetitle>Linux Sys Admin</citetitle> on-line book
|
||||
for more detailed information.
|
||||
@ -411,7 +412,7 @@ libFor elfodbc <replaceable>applixroot</replaceable>/applix/axdata/axshlib/lib
|
||||
<step performance="required">
|
||||
<para>
|
||||
Create <filename>.odbc.ini</filename> as
|
||||
described above. You may also want to add the flag
|
||||
described in <xref linkend="odbc-config">. You may also want to add the flag
|
||||
|
||||
<programlisting>
|
||||
TextAsLongVarchar=0
|
||||
@ -476,7 +477,7 @@ TextAsLongVarchar=0
|
||||
</step>
|
||||
<step performance="required">
|
||||
<para>
|
||||
The <literal>Ready</literal> message will appear in the lower left corner of the data
|
||||
The <quote>Ready</quote> message will appear in the lower left corner of the data
|
||||
window. This indicates that you can now enter queries.
|
||||
</para>
|
||||
</step>
|
||||
@ -549,7 +550,7 @@ TextAsLongVarchar=0
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
The September release of <application>ApplixWare</application> v4.4.1 (the first release with official
|
||||
The September release of <application>ApplixWare</application> 4.4.1 (the first release with official
|
||||
<acronym>ODBC</acronym> support under Linux) shows problems when user names
|
||||
exceed eight (8) characters in length.
|
||||
Problem description contributed by Steve Campbell
|
||||
@ -574,7 +575,7 @@ TextAsLongVarchar=0
|
||||
The <application>axnet</application> program's security system
|
||||
seems a little suspect. <application>axnet</application> does things
|
||||
on behalf of the user and on a true
|
||||
multiple user system it really should be run with root security
|
||||
multiuser system it really should be run with root security
|
||||
(so it can read/write in each user's directory).
|
||||
I would hesitate to recommend this, however, since we have no idea what
|
||||
security holes this creates.
|
||||
@ -633,7 +634,7 @@ cary 27883 0.9 31.0 12692 4596 ? S 10:24 0:04 axmain
|
||||
Many of the error messages from <productname>ApplixWare</productname>
|
||||
go to <filename>stderr</filename>,
|
||||
but I'm not sure where <filename>stderr</filename>
|
||||
is sent, so <application>strace</application> is the way to find out.
|
||||
is sent, so <command>strace</command> is the way to find out.
|
||||
</para>
|
||||
</note>
|
||||
</step>
|
||||
@ -641,16 +642,13 @@ cary 27883 0.9 31.0 12692 4596 ? S 10:24 0:04 axmain
|
||||
|
||||
<para>
|
||||
For example, after getting
|
||||
a <literal>Cannot launch gateway on server</literal>,
|
||||
a <errorname>Cannot launch gateway on server</errorname>,
|
||||
I ran <command>strace</command> on <literal>axnet</literal> and got
|
||||
|
||||
<screen>
|
||||
[pid 27947] open("/usr/lib/libodbc.so", O_RDONLY) = -1 ENOENT
|
||||
(No such file or directory)
|
||||
[pid 27947] open("/lib/libodbc.so", O_RDONLY) = -1 ENOENT
|
||||
(No such file or directory)
|
||||
[pid 27947] write(2, "/usr2/applix/axdata/elfodbc:
|
||||
can't load library 'libodbc.so'\n", 61) = -1 EIO (I/O error)
|
||||
[pid 27947] open("/usr/lib/libodbc.so", O_RDONLY) = -1 ENOENT (No such file or directory)
|
||||
[pid 27947] open("/lib/libodbc.so", O_RDONLY) = -1 ENOENT (No such file or directory)
|
||||
[pid 27947] write(2, "/usr2/applix/axdata/elfodbc: can't load library 'libodbc.so'\n", 61) = -1 EIO (I/O error)
|
||||
</screen>
|
||||
So what is happening is that <literal>applix elfodbc</literal> is searching for <filename>libodbc.so</filename>, but it
|
||||
cannot find it. That is why <filename>axnet.cnf</filename> needed to be changed.
|
||||
@ -660,6 +658,8 @@ can't load library 'libodbc.so'\n", 61) = -1 EIO (I/O error)
|
||||
<sect2>
|
||||
<title>Running the <application>ApplixWare</application> Demo</title>
|
||||
|
||||
<comment>I think the condition this refers to is gone. -- petere 2002-01-07</comment>
|
||||
|
||||
<para>
|
||||
In order to go through the
|
||||
<citetitle>ApplixWare Data Tutorial</citetitle>, you need to create
|
||||
@ -668,6 +668,7 @@ can't load library 'libodbc.so'\n", 61) = -1 EIO (I/O error)
|
||||
on many of the database columns,
|
||||
and <productname>PostgreSQL</productname> does not currently allow this option.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To get around this problem, you can do the following:
|
||||
</para>
|
||||
@ -717,7 +718,7 @@ can't load library 'libodbc.so'\n", 61) = -1 EIO (I/O error)
|
||||
|
||||
<step performance="required">
|
||||
<para>
|
||||
Select <command>File->Compile and Save</command>.
|
||||
Select <menuchoice><guimenu>File</><guimenuitem>Compile and Save</></menuchoice>.
|
||||
</para>
|
||||
</step>
|
||||
|
||||
@ -735,13 +736,13 @@ can't load library 'libodbc.so'\n", 61) = -1 EIO (I/O error)
|
||||
|
||||
<step performance="required">
|
||||
<para>
|
||||
Select <command>*->Run Macro</command>
|
||||
Select <menuchoice><guimenu>*</><guimenuitem>Run Macro</guimenuitem></menuchoice>.
|
||||
</para>
|
||||
</step>
|
||||
|
||||
<step performance="required">
|
||||
<para>
|
||||
Enter the value <literal>sqldemo</literal>, then click <command>OK</command>.
|
||||
Enter the value <literal>sqldemo</literal>, then click <guibutton>OK</guibutton>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -757,6 +758,7 @@ can't load library 'libodbc.so'\n", 61) = -1 EIO (I/O error)
|
||||
</step>
|
||||
</procedure>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Useful Macros</title>
|
||||
|
||||
@ -766,12 +768,12 @@ can't load library 'libodbc.so'\n", 61) = -1 EIO (I/O error)
|
||||
macro file. This is an example
|
||||
<filename>~/axhome/macros/login.am</filename> file:
|
||||
|
||||
<programlisting>
|
||||
<programlisting>
|
||||
macro login
|
||||
set_set_system_var@("sql_username@","tgl")
|
||||
set_system_var@("sql_passwd@","no$way")
|
||||
endmacro
|
||||
</programlisting>
|
||||
</programlisting>
|
||||
|
||||
<caution>
|
||||
<para>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/plperl.sgml,v 2.11 2001/11/21 05:53:41 thomas Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/plperl.sgml,v 2.12 2002/01/07 02:29:13 petere Exp $
|
||||
-->
|
||||
|
||||
<chapter id="plperl">
|
||||
@ -13,15 +13,19 @@ $Header: /cvsroot/pgsql/doc/src/sgml/plperl.sgml,v 2.11 2001/11/21 05:53:41 thom
|
||||
<primary>Perl</primary>
|
||||
</indexterm>
|
||||
|
||||
<sect1 id="intro">
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>
|
||||
PL/Perl allows you to write functions in the Perl programming
|
||||
language that may be used in SQL queries as if they were built into
|
||||
PL/Perl allows you to write functions in the <ulink
|
||||
url="http://www.perl.com">Perl</ulink> programming language that may
|
||||
be used in SQL queries as if they were built into
|
||||
<productname>PostgreSQL</productname>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The PL/Perl interpreter (when installed as trusted interpreter with
|
||||
default name <literal>plperl</>) interpreter is a full Perl interpreter. However, certain
|
||||
default name <literal>plperl</>) is a full Perl interpreter. However, certain
|
||||
operations have been disabled in order to maintain the security of
|
||||
the system. In general, the operations that are restricted are
|
||||
those that interact with the environment. This includes file handle
|
||||
@ -33,8 +37,9 @@ $Header: /cvsroot/pgsql/doc/src/sgml/plperl.sgml,v 2.11 2001/11/21 05:53:41 thom
|
||||
</para>
|
||||
<para>
|
||||
When PL/Perl is installed as <quote>untrusted</> interpreter (with name <literal>plperlu</literal>),
|
||||
everything is permitted, and any Perl code can be loaded (by superuser only).
|
||||
everything is permitted, and any Perl code can be loaded (by a superuser only).
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="plperl-install">
|
||||
<title>Building and Installing</title>
|
||||
@ -54,10 +59,9 @@ $Header: /cvsroot/pgsql/doc/src/sgml/plperl.sgml,v 2.11 2001/11/21 05:53:41 thom
|
||||
fact:
|
||||
<screen>
|
||||
<computeroutput>
|
||||
*****
|
||||
* Cannot build PL/Perl because libperl is not a shared library.
|
||||
* Skipped.
|
||||
*****
|
||||
*** Cannot build PL/Perl because libperl is not a shared library.
|
||||
*** You might have to rebuild your Perl installation. Refer to
|
||||
*** the documentation for details.
|
||||
</computeroutput>
|
||||
</screen>
|
||||
Therefore it is likely that you will have to re-build and install
|
||||
@ -84,7 +88,7 @@ gmake install
|
||||
<prompt>$</prompt> <userinput>createlang plperl template1</userinput>
|
||||
</screen>
|
||||
Alternatively, to create untrusted interpreter (where functions can only
|
||||
be created by superuser, but the functions are not restricted), use:
|
||||
be created by a superuser, but the functions are not restricted), use:
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>createlang plperlu template1</userinput>
|
||||
</screen>
|
||||
@ -99,7 +103,7 @@ be created by superuser, but the functions are not restricted), use:
|
||||
<para>
|
||||
Assume you have the following table:
|
||||
<programlisting>
|
||||
CREATE TABLE EMPLOYEE (
|
||||
CREATE TABLE employee (
|
||||
name text,
|
||||
basesalary integer,
|
||||
bonus integer
|
||||
@ -111,7 +115,7 @@ CREATE TABLE EMPLOYEE (
|
||||
<programlisting>
|
||||
CREATE FUNCTION totalcomp(integer, integer) RETURNS integer
|
||||
AS 'return $_[0] + $_[1]'
|
||||
LANGUAGE 'plperl';
|
||||
LANGUAGE plperl;
|
||||
</programlisting>
|
||||
|
||||
Notice that the arguments to the function are passed in
|
||||
@ -131,7 +135,7 @@ SELECT name, totalcomp(basesalary, bonus) FROM employee;
|
||||
CREATE FUNCTION empcomp(employee) RETURNS integer AS '
|
||||
my $emp = shift;
|
||||
return $emp->{''basesalary''} + $emp->{''bonus''};
|
||||
' LANGUAGE 'plperl';
|
||||
' LANGUAGE plperl;
|
||||
</programlisting>
|
||||
A tuple is passed as a reference to a hash. The keys are the names
|
||||
of the fields in the tuples. The hash values are values of the
|
||||
@ -151,7 +155,7 @@ CREATE FUNCTION empcomp(employee) RETURNS integer AS '
|
||||
</tip>
|
||||
|
||||
<para>
|
||||
The new function <function>empcomp</function> can used like:
|
||||
The new function <function>empcomp</function> can be used like:
|
||||
<programlisting>
|
||||
SELECT name, empcomp(employee) FROM employee;
|
||||
</programlisting>
|
||||
@ -165,18 +169,22 @@ CREATE FUNCTION badfunc() RETURNS integer AS '
|
||||
open(TEMP, ">/tmp/badfile");
|
||||
print TEMP "Gotcha!\n";
|
||||
return 1;
|
||||
' LANGUAGE 'plperl';
|
||||
' LANGUAGE plperl;
|
||||
</programlisting>
|
||||
The creation of the function will succeed, but executing it will not.
|
||||
|
||||
</para>
|
||||
<para>
|
||||
Note that if same function was created by superuser using language
|
||||
<literal>plperlu</>, execution would succeed.
|
||||
</para>
|
||||
<para>
|
||||
Access to database itself from your Perl function can be done via
|
||||
an experimental module <ulink url="http://www.formenos.org/PgSPI/"><literal>DBD::PgSPI</literal></ulink>. This module makes available a <acronym>DBI</>-compliant
|
||||
database-handle named <varname>$pg_dbh</varname>, and you can use that to make queries with
|
||||
normal <acronym>DBI</> syntax.
|
||||
Access to database itself from your Perl function can be done via
|
||||
an experimental module <ulink
|
||||
url="http://www.formenos.org/PgSPI/"><literal>DBD::PgSPI</literal></ulink>
|
||||
(also on <ulink url="http://www.cpan.org">CPAN</ulink>). This
|
||||
module makes available a <acronym>DBI</>-compliant database-handle
|
||||
named <varname>$pg_dbh</varname>, and you can use that to perform
|
||||
queries with normal <acronym>DBI</> syntax.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/plpython.sgml,v 1.7 2001/11/21 05:53:41 thomas Exp $ -->
|
||||
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/plpython.sgml,v 1.8 2002/01/07 02:29:13 petere Exp $ -->
|
||||
|
||||
<chapter id="plpython">
|
||||
<title>PL/Python - Python Procedural Language</title>
|
||||
@ -6,44 +6,74 @@
|
||||
<indexterm zone="plpython"><primary>PL/Python</></>
|
||||
<indexterm zone="plpython"><primary>Python</></>
|
||||
|
||||
<note>
|
||||
<sect1 id="plpython-intro">
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>
|
||||
This chapter is not fully developed yet.
|
||||
The <application>PL/Python</application> procedural language allows
|
||||
<productname>PostgreSQL</productname> functions to be written in
|
||||
the <ulink url="http://www.python.org">Python</ulink> language.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The current version of PL/Python functions as a trusted language only;
|
||||
access to the filesystem and other local resources are disabled.
|
||||
Specifically, PL/Python uses the Python restricted execution environment,
|
||||
further restricts it to prevent the use of the file open call, and
|
||||
allows only modules from a specific list to be imported. Presently,
|
||||
that list includes: array, bisect, binascii, calendar, cmath, codecs,
|
||||
errno, marshal, math, md5, mpz, operator, pcre, pickle, random, re,
|
||||
regex, sre, sha, string, StringIO, struct, time, whrandom, and zlib.
|
||||
The current version of <application>PL/Python</application>
|
||||
functions as a trusted language only; access to the file system and
|
||||
other local resources is disabled. Specifically,
|
||||
<application>PL/Python</application> uses the Python restricted
|
||||
execution environment, further restricts it to prevent the use of
|
||||
the file <function>open</> call, and allows only modules from a
|
||||
specific list to be imported. Presently, that list includes:
|
||||
array, bisect, binascii, calendar, cmath, codecs, errno, marshal,
|
||||
math, md5, mpz, operator, pcre, pickle, random, re, regex, sre,
|
||||
sha, string, StringIO, struct, time, whrandom, and zlib.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
There is discussion on creating an untrusted language variant for a
|
||||
In the current version, any database error encountered while
|
||||
running a <application>PL/Python</application> function will result
|
||||
in the immediate termination of that function by the server. It is
|
||||
not possible to trap error conditions using Python <literal>try
|
||||
... catch</literal> constructs. For example, a syntax error in an
|
||||
SQL statement passed to the <literal>plpy.execute()</literal> call
|
||||
will terminate the function. This behavior may be changed in a
|
||||
future release.
|
||||
</para>
|
||||
<para>
|
||||
In the current version, any postgresql error encountered while running
|
||||
a PL/Python function will result in the immediate termination of that
|
||||
function by the backend. It is not possible to trap error conditions
|
||||
using Python try ... catch constructs. For example, a syntax error in
|
||||
an SQL statement passed to the plpy.execute() call will terminate the
|
||||
function. This behavior may be changed in a future release.
|
||||
</para>
|
||||
</note>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="plpython-install">
|
||||
<title>Installation</title>
|
||||
|
||||
<para>
|
||||
... needs to be worked out.
|
||||
To build PL/Python, the <option>--with-python</option> option needs
|
||||
to be specified when running <filename>configure</filename>. If
|
||||
after building and installing you have a file called
|
||||
<filename>plpython.so</filename> (possibly a different extension),
|
||||
then everything went well. Otherwise you should have seen a notice
|
||||
like this flying by:
|
||||
<screen>
|
||||
*** Cannot build PL/Python because libpython is not a shared library.
|
||||
*** You might have to rebuild your Python installation. Refer to
|
||||
*** the documentation for details.
|
||||
</screen>
|
||||
That means you have to rebuild (part of) your Python installation
|
||||
to supply this shared library.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The catch is that the Python distribution or the Python maintainers
|
||||
do not provide any direct way to do this. The closest thing we can
|
||||
offer you is the information in <ulink
|
||||
url="http://www.python.org/doc/FAQ.html#3.30">Python FAQ
|
||||
3.30</ulink>. On some operating systems you don't really have to
|
||||
build a shared library, but then you will have to convince the
|
||||
PostgreSQL build system of this. Consult the
|
||||
<filename>Makefile</filename> in the
|
||||
<filename>src/pl/plpython</filename> directory for details.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="plpython-using">
|
||||
<title>Using</title>
|
||||
<title>Using PL/Python</title>
|
||||
|
||||
<para>
|
||||
There are sample functions in
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/plsql.sgml,v 2.52 2002/01/02 00:41:26 tgl Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/plsql.sgml,v 2.53 2002/01/07 02:29:13 petere Exp $
|
||||
-->
|
||||
|
||||
<chapter id="plpgsql">
|
||||
@ -1700,7 +1700,7 @@ RAISE EXCEPTION ''Inexistent ID --> %'',user_id;
|
||||
<para>
|
||||
It is possible to hook into the error mechanism to notice that this
|
||||
happens. But currently it is impossible to tell what really
|
||||
caused the abort (input/output conversion error, floating point
|
||||
caused the abort (input/output conversion error, floating-point
|
||||
error, parse error). And it is possible that the database backend
|
||||
is in an inconsistent state at this point so returning to the upper
|
||||
executor or issuing more commands might corrupt the whole database.
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/problems.sgml,v 2.11 2001/11/21 05:53:41 thomas Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/problems.sgml,v 2.12 2002/01/07 02:29:13 petere Exp $
|
||||
-->
|
||||
|
||||
<sect1 id="bug-reporting">
|
||||
@ -252,7 +252,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/problems.sgml,v 2.11 2001/11/21 05:53:41 th
|
||||
Do not spend all your time to figure out which changes in the input make
|
||||
the problem go away. This will probably not help solving it. If it turns
|
||||
out that the bug cannot be fixed right away, you will still have time to
|
||||
find and share your work around. Also, once again, do not waste your time
|
||||
find and share your work-around. Also, once again, do not waste your time
|
||||
guessing why the bug exists. We will find that out soon enough.
|
||||
</para>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/programmer.sgml,v 1.38 2001/05/12 22:51:35 petere Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/programmer.sgml,v 1.39 2002/01/07 02:29:13 petere Exp $
|
||||
|
||||
PostgreSQL Programmer's Guide.
|
||||
-->
|
||||
@ -16,30 +16,17 @@ PostgreSQL Programmer's Guide.
|
||||
&intro;
|
||||
]]>
|
||||
|
||||
<preface id="organization">
|
||||
<title>Organization</title>
|
||||
|
||||
<para>
|
||||
The first part of this manual is the description of the client-side
|
||||
programming interfaces and support libraries for various languages.
|
||||
The second part explains the <productname>PostgreSQL</productname>
|
||||
approach to extensibility and describe how users can extend
|
||||
<productname>PostgreSQL</productname> by adding user-defined types,
|
||||
operators, aggregates, and both query language and programming
|
||||
language functions. After a discussion of the
|
||||
<productname>PostgreSQL</productname> rule system, we discuss the
|
||||
trigger and SPI interfaces. The third part documents the
|
||||
procedural languages available in the
|
||||
<productname>PostgreSQL</productname> distribution.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Proficiency with Unix and C programming is assumed.
|
||||
</para>
|
||||
</preface>
|
||||
|
||||
<part id="programmer-client">
|
||||
<title>Client Interfaces</title>
|
||||
|
||||
<partintro>
|
||||
<para>
|
||||
This part of the manual is the description of the client-side
|
||||
programming interfaces and support libraries for various
|
||||
languages.
|
||||
</para>
|
||||
</partintro>
|
||||
|
||||
&libpq;
|
||||
&lobj;
|
||||
&libpqpp;
|
||||
@ -53,6 +40,20 @@ PostgreSQL Programmer's Guide.
|
||||
|
||||
<part id="programmer-server">
|
||||
<title>Server Programming</title>
|
||||
|
||||
<partintro>
|
||||
<para>
|
||||
This second part of the manual explains the
|
||||
<productname>PostgreSQL</productname> approach to extensibility
|
||||
and describe how users can extend
|
||||
<productname>PostgreSQL</productname> by adding user-defined
|
||||
types, operators, aggregates, and both query language and
|
||||
programming language functions. After a discussion of the
|
||||
<productname>PostgreSQL</productname> rule system, we discuss the
|
||||
trigger and SPI interfaces.
|
||||
</para>
|
||||
</partintro>
|
||||
|
||||
&arch-pg;
|
||||
&extend;
|
||||
&xfunc;
|
||||
@ -70,6 +71,14 @@ PostgreSQL Programmer's Guide.
|
||||
<part id="programmer-pl">
|
||||
<title>Procedural Languages</title>
|
||||
|
||||
<partintro>
|
||||
<para>
|
||||
This part documents the procedural languages available in the
|
||||
<productname>PostgreSQL</productname> distribution as well as
|
||||
general issues concerning procedural languages.
|
||||
</para>
|
||||
</partintro>
|
||||
|
||||
&xplang;
|
||||
&plsql;
|
||||
&pltcl;
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/query.sgml,v 1.23 2001/11/28 20:49:10 petere Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/query.sgml,v 1.24 2002/01/07 02:29:13 petere Exp $
|
||||
-->
|
||||
|
||||
<chapter id="tutorial-sql">
|
||||
@ -137,7 +137,7 @@ CREATE TABLE weather (
|
||||
<type>varchar(80)</type> specifies a data type that can store
|
||||
arbitrary character strings up to 80 characters in length.
|
||||
<type>int</type> is the normal integer type. <type>real</type> is
|
||||
a type for storing single precision floating point numbers.
|
||||
a type for storing single precision floating-point numbers.
|
||||
<type>date</type> should be self-explanatory. (Yes, the column of
|
||||
type <type>date</type> is also named <literal>date</literal>.
|
||||
This may be convenient or confusing -- you choose.)
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_operator.sgml,v 1.22 2001/12/08 03:24:34 thomas Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_operator.sgml,v 1.23 2002/01/07 02:29:15 petere Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
@ -343,7 +343,7 @@ MYBOXES.description <<< box '((0,0), (1,1))'
|
||||
<replaceable class="parameter">res_proc</replaceable>
|
||||
must be a registered function (meaning it is already defined using
|
||||
<command>CREATE FUNCTION</command>) which accepts arguments of the correct
|
||||
data types and returns a floating point number. The
|
||||
data types and returns a floating-point number. The
|
||||
query optimizer simply calls this function, passing the
|
||||
parameter <literal>((0,0), (1,1))</literal> and multiplies the result by the relation
|
||||
size to get the expected number of instances.
|
||||
@ -352,7 +352,7 @@ MYBOXES.description <<< box '((0,0), (1,1))'
|
||||
Similarly, when the operands of the operator both contain
|
||||
instance variables, the query optimizer must estimate the
|
||||
size of the resulting join. The function join_proc will
|
||||
return another floating point number which will be multiplied
|
||||
return another floating-point number which will be multiplied
|
||||
by the cardinalities of the two tables involved to
|
||||
compute the expected result size.
|
||||
</para>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/set.sgml,v 1.56 2001/12/29 20:29:49 momjian Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/set.sgml,v 1.57 2002/01/07 02:29:15 petere Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
@ -195,8 +195,8 @@ SET TIME ZONE { '<replaceable class="PARAMETER">timezone</replaceable>' | LOCAL
|
||||
<para>
|
||||
The value for the seed to be used by the
|
||||
<function>random</function> function. Allowed
|
||||
values are floating point numbers between 0 and 1, which
|
||||
are then multiplied by 2^31-1. This product will
|
||||
values are floating-point numbers between 0 and 1, which
|
||||
are then multiplied by 2<superscript>31</>-1. This product will
|
||||
silently overflow if a number outside the range is used.
|
||||
</para>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/regress.sgml,v 1.23 2001/12/04 01:49:17 tgl Exp $ -->
|
||||
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/regress.sgml,v 1.24 2002/01/07 02:29:13 petere Exp $ -->
|
||||
|
||||
<chapter id="regress">
|
||||
<title id="regress-title">Regression Tests</title>
|
||||
@ -135,7 +135,7 @@
|
||||
Some properly installed and fully functional
|
||||
<productname>PostgreSQL</productname> installations can
|
||||
<quote>fail</quote> some of these regression tests due to
|
||||
platform-specific artifacts such as varying floating point representation
|
||||
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
|
||||
generated on a reference system, so the results are sensitive to
|
||||
@ -248,7 +248,7 @@ PGTZ='PST8PDT7,M04.01.0,M10.05.03'; export PGTZ
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Floating point differences</title>
|
||||
<title>Floating-point differences</title>
|
||||
|
||||
<para>
|
||||
Some of the tests involve computing 64-bit (<type>double
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/rules.sgml,v 1.19 2001/11/21 06:09:45 thomas Exp $ -->
|
||||
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/rules.sgml,v 1.20 2002/01/07 02:29:13 petere Exp $ -->
|
||||
|
||||
<Chapter Id="rules">
|
||||
<Title>The Rule System</Title>
|
||||
@ -14,6 +14,9 @@
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<sect1 id="rules-intro">
|
||||
<title>Introduction</title>
|
||||
|
||||
<Para>
|
||||
Production rule systems are conceptually simple, but
|
||||
there are many subtle points involved in actually using
|
||||
@ -42,6 +45,9 @@
|
||||
as well as
|
||||
<XRef LinkEnd="STON90b">.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<Sect1 id="querytree">
|
||||
<Title>What is a Query Tree?</Title>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.100 2001/12/27 21:37:34 tgl Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.101 2002/01/07 02:29:13 petere Exp $
|
||||
-->
|
||||
|
||||
<Chapter Id="runtime">
|
||||
@ -128,9 +128,9 @@ postgres$ <userinput>initdb -D /usr/local/pgsql/data</userinput>
|
||||
password to the database superuser. After <command>initdb</command>,
|
||||
modify <filename>pg_hba.conf</filename> to use <literal>md5</> or
|
||||
<literal>password</>, instead of <literal>trust</>, authentication
|
||||
<emphasis>before</> you first start the postmaster. (Other, possibly
|
||||
<emphasis>before</> you start the server for the first time. (Other, possibly
|
||||
more convenient approaches include using <literal>ident</literal>
|
||||
authentication or filesystem permissions to restrict connections. See
|
||||
authentication or file system permissions to restrict connections. See
|
||||
<xref linkend="client-authentication"> for more information.)
|
||||
</para>
|
||||
|
||||
@ -493,7 +493,7 @@ log_connections = yes
|
||||
syslog = 2
|
||||
</programlisting>
|
||||
As you see, options are one per line. The equal sign between name
|
||||
and value is optional. White space is insignificant, blank lines
|
||||
and value is optional. Whitespace is insignificant, blank lines
|
||||
are ignored. Hash marks (<quote>#</quote>) introduce comments
|
||||
anywhere.
|
||||
</para>
|
||||
@ -504,7 +504,7 @@ syslog = 2
|
||||
</indexterm>
|
||||
The configuration file is reread whenever the postmaster receives
|
||||
a <systemitem>SIGHUP</> signal (which is most easily sent by means
|
||||
of <application>pg_ctl reload</>). The postmaster also propagates
|
||||
of <literal>pg_ctl reload</>). The postmaster also propagates
|
||||
this signal to all already-running backend processes, so that
|
||||
existing sessions also get the new default.
|
||||
Alternatively, you can send the signal to only one backend process
|
||||
@ -886,7 +886,7 @@ env PGOPTIONS='-c geqo=off' psql
|
||||
<term><varname>LOG_PID</varname> (<type>boolean</type>)</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Prefixes each server log message with the process id of the
|
||||
Prefixes each server log message with the process ID of the
|
||||
backend process. This is useful to sort out which messages
|
||||
pertain to which connection. The default is off.
|
||||
</para>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/syntax.sgml,v 1.55 2001/12/08 03:24:23 thomas Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/syntax.sgml,v 1.56 2002/01/07 02:29:13 petere Exp $
|
||||
-->
|
||||
|
||||
<chapter id="sql-syntax">
|
||||
@ -102,7 +102,8 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there');
|
||||
|
||||
<para>
|
||||
SQL identifiers and key words must begin with a letter
|
||||
(<literal>a</literal>-<literal>z</literal>) or underscore
|
||||
(<literal>a</literal>-<literal>z</literal>, but also letters with
|
||||
diacritical marks and non-Latin letters) or an underscore
|
||||
(<literal>_</literal>). Subsequent characters in an identifier or
|
||||
key word can be letters, digits
|
||||
(<literal>0</literal>-<literal>9</literal>), or underscores,
|
||||
@ -200,9 +201,9 @@ UPDATE "my_table" SET "a" = 5;
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
There are four kinds of <firstterm>implicitly typed
|
||||
There are four kinds of <firstterm>implicitly-typed
|
||||
constants</firstterm> in <productname>PostgreSQL</productname>:
|
||||
strings, bit strings, integers, and floating point numbers.
|
||||
strings, bit strings, integers, and floating-point numbers.
|
||||
Constants can also be specified with explicit types, which can
|
||||
enable more accurate representation and more efficient handling by
|
||||
the system. The implicit constants are described below; explicit
|
||||
@ -266,12 +267,12 @@ SELECT 'foobar';
|
||||
SELECT 'foo' 'bar';
|
||||
</programlisting>
|
||||
is not valid syntax, and <productname>PostgreSQL</productname> is
|
||||
consistant with <acronym>SQL9x</acronym> in this regard.
|
||||
consistent with <acronym>SQL9x</acronym> in this regard.
|
||||
</para>
|
||||
</sect3>
|
||||
|
||||
<sect3 id="sql-syntax-bit-strings">
|
||||
<title>Bit String Constants</title>
|
||||
<title>Bit-String Constants</title>
|
||||
|
||||
<indexterm zone="sql-syntax-bit-strings">
|
||||
<primary>bit strings</primary>
|
||||
@ -279,12 +280,12 @@ SELECT 'foo' 'bar';
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
Bit string constants look like string constants with a
|
||||
Bit-string constants look like string constants with a
|
||||
<literal>B</literal> (upper or lower case) immediately before the
|
||||
opening quote (no intervening whitespace), e.g.,
|
||||
<literal>B'1001'</literal>. The only characters allowed within
|
||||
bit string constants are <literal>0</literal> and
|
||||
<literal>1</literal>. Bit string constants can be continued
|
||||
bit-string constants are <literal>0</literal> and
|
||||
<literal>1</literal>. Bit-string constants can be continued
|
||||
across lines in the same way as regular string constants.
|
||||
</para>
|
||||
</sect3>
|
||||
@ -303,7 +304,7 @@ SELECT 'foo' 'bar';
|
||||
</sect3>
|
||||
|
||||
<sect3>
|
||||
<title>Floating Point Constants</title>
|
||||
<title>Floating-Point Constants</title>
|
||||
|
||||
<indexterm>
|
||||
<primary>floating point</primary>
|
||||
@ -311,7 +312,7 @@ SELECT 'foo' 'bar';
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
Floating point constants are accepted in these general forms:
|
||||
Floating-point constants are accepted in these general forms:
|
||||
<synopsis>
|
||||
<replaceable>digits</replaceable>.<optional><replaceable>digits</replaceable></optional><optional>e<optional>+-</optional><replaceable>digits</replaceable></optional>
|
||||
<optional><replaceable>digits</replaceable></optional>.<replaceable>digits</replaceable><optional>e<optional>+-</optional><replaceable>digits</replaceable></optional>
|
||||
@ -321,7 +322,7 @@ SELECT 'foo' 'bar';
|
||||
digits. At least one digit must be before or after the decimal
|
||||
point. At least one digit must follow the exponent delimiter
|
||||
(<literal>e</literal>) if that field is present.
|
||||
Thus, a floating point constant is distinguished from an integer
|
||||
Thus, a floating-point constant is distinguished from an integer
|
||||
constant by the presence of either the decimal point or the
|
||||
exponent clause (or both). There must not be a space or other
|
||||
characters embedded in the constant.
|
||||
@ -329,7 +330,7 @@ SELECT 'foo' 'bar';
|
||||
|
||||
<informalexample>
|
||||
<para>
|
||||
These are some examples of valid floating point constants:
|
||||
These are some examples of valid floating-point constants:
|
||||
<literallayout>
|
||||
3.5
|
||||
4.
|
||||
@ -341,7 +342,7 @@ SELECT 'foo' 'bar';
|
||||
</informalexample>
|
||||
|
||||
<para>
|
||||
Floating point constants are of type <type>DOUBLE
|
||||
Floating-point constants are of type <type>DOUBLE
|
||||
PRECISION</type>. <type>REAL</type> can be specified explicitly
|
||||
by using <acronym>SQL</acronym> string notation or
|
||||
<productname>PostgreSQL</productname> type notation:
|
||||
@ -385,9 +386,13 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> )
|
||||
<replaceable>typename</replaceable> ( <replaceable>value</replaceable> )
|
||||
</synopsis>
|
||||
although this only works for types whose names are also valid as
|
||||
function names. (For example, <literal>double precision</literal>
|
||||
can't be used this way --- but the equivalent <literal>float8</literal>
|
||||
can.)
|
||||
function names. For example, <literal>double precision</literal>
|
||||
can't be used this way, but the equivalent <literal>float8</literal>
|
||||
can. Also, the names <literal>interval</>, <literal>time</>, and
|
||||
<literal>timestamp</> can only be used in this context if they are
|
||||
double-quoted, because of parser conflicts. Therefore, the use of
|
||||
the function-like cast syntax leads to inconsistencies and should
|
||||
probably be avoided in new applications.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -429,8 +434,8 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> )
|
||||
<para>
|
||||
Individual array elements can be placed between double-quote
|
||||
marks (<literal>"</literal>) <!-- " --> to avoid ambiguity
|
||||
problems with respect to white space. Without quote marks, the
|
||||
array-value parser will skip leading white space.
|
||||
problems with respect to whitespace. Without quote marks, the
|
||||
array-value parser will skip leading whitespace.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -495,7 +500,7 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> )
|
||||
<para>
|
||||
When working with non-SQL-standard operator names, you will usually
|
||||
need to separate adjacent operators with spaces to avoid ambiguity.
|
||||
For example, if you have defined a left-unary operator named <literal>@</literal>,
|
||||
For example, if you have defined a left unary operator named <literal>@</literal>,
|
||||
you cannot write <literal>X*@Y</literal>; you must write
|
||||
<literal>X* @Y</literal> to ensure that
|
||||
<productname>PostgreSQL</productname> reads it as two operator names
|
||||
@ -574,7 +579,7 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> )
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
The period (<literal>.</literal>) is used in floating point
|
||||
The period (<literal>.</literal>) is used in floating-point
|
||||
constants, and to separate table and column names.
|
||||
</para>
|
||||
</listitem>
|
||||
@ -670,8 +675,8 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> )
|
||||
<listitem>
|
||||
<para>
|
||||
The identity (transaction ID) of the inserting transaction for
|
||||
this tuple. (Note: a tuple is an individual state of a row;
|
||||
each UPDATE of a row creates a new tuple for the same logical row.)
|
||||
this tuple. (Note: A tuple is an individual state of a row;
|
||||
each update of a row creates a new tuple for the same logical row.)
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -733,7 +738,7 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> )
|
||||
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 index on the OID column of each table for which the OID will be
|
||||
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
|
||||
@ -756,12 +761,6 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> )
|
||||
In practice this limit is not a problem --- note that the limit is on
|
||||
number of SQL queries, not number of tuples processed.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For further information on the system attributes consult
|
||||
<xref linkend="STON87a">.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
|
||||
@ -916,7 +915,7 @@ $<replaceable>number</replaceable>
|
||||
<programlisting>
|
||||
CREATE FUNCTION dept (text) RETURNS dept
|
||||
AS 'SELECT * FROM dept WHERE name = $1'
|
||||
LANGUAGE 'sql';
|
||||
LANGUAGE SQL;
|
||||
</programlisting>
|
||||
|
||||
Here the <literal>$1</literal> will be replaced by the first
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/xaggr.sgml,v 1.15 2001/11/21 06:09:45 thomas Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/xaggr.sgml,v 1.16 2002/01/07 02:29:14 petere Exp $
|
||||
-->
|
||||
|
||||
<chapter id="xaggr">
|
||||
@ -39,42 +39,42 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xaggr.sgml,v 1.15 2001/11/21 06:09:45 thoma
|
||||
the column values from each row. <function>Sum</> is an
|
||||
example of this kind of aggregate. <function>Sum</> starts at
|
||||
zero and always adds the current row's value to
|
||||
its running total. For example, if we want to make a Sum
|
||||
its running total. For example, if we want to make a <function>sum</>
|
||||
aggregate to work on a data type for complex numbers,
|
||||
we only need the addition function for that data type.
|
||||
The aggregate definition is:
|
||||
|
||||
<programlisting>
|
||||
<programlisting>
|
||||
CREATE AGGREGATE complex_sum (
|
||||
sfunc = complex_add,
|
||||
basetype = complex,
|
||||
stype = complex,
|
||||
initcond = '(0,0)'
|
||||
);
|
||||
</programlisting>
|
||||
|
||||
<screen>
|
||||
SELECT complex_sum(a) FROM test_complex;
|
||||
|
||||
+------------+
|
||||
|complex_sum |
|
||||
+------------+
|
||||
|(34,53.9) |
|
||||
+------------+
|
||||
</programlisting>
|
||||
complex_sum
|
||||
-------------
|
||||
(34,53.9)
|
||||
</screen>
|
||||
|
||||
(In practice, we'd just name the aggregate <function>sum</function>, and rely on
|
||||
<productname>PostgreSQL</productname> to figure out which kind
|
||||
of sum to apply to a complex column.)
|
||||
of sum to apply to a column of type <type>complex</type>.)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The above definition of <function>Sum</function> will return zero (the initial
|
||||
The above definition of <function>sum</function> will return zero (the initial
|
||||
state condition) if there are no non-null input values.
|
||||
Perhaps we want to return NULL in that case instead --- SQL92
|
||||
expects <function>Sum</function> to behave that way. We can do this simply by
|
||||
Perhaps we want to return NULL in that case instead --- the SQL standard
|
||||
expects <function>sum</function> to behave that way. We can do this simply by
|
||||
omitting the <literal>initcond</literal> phrase, so that the initial state
|
||||
condition is NULL. Ordinarily this would mean that the <literal>sfunc</literal>
|
||||
would need to check for a NULL state-condition input, but for
|
||||
<function>Sum</function> and some other simple aggregates like <function>Max</> and <function>Min</>,
|
||||
<function>sum</function> and some other simple aggregates like <function>max</> and <function>min</>,
|
||||
it's sufficient to insert the first non-null input value into
|
||||
the state variable and then start applying the transition function
|
||||
at the second non-null input value. <productname>PostgreSQL</productname>
|
||||
@ -93,7 +93,7 @@ SELECT complex_sum(a) FROM test_complex;
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>Average</> is a more complex example of an aggregate. It requires
|
||||
<function>Avg</> (average) is a more complex example of an aggregate. It requires
|
||||
two pieces of running state: the sum of the inputs and the count
|
||||
of the number of inputs. The final result is obtained by dividing
|
||||
these quantities. Average is typically implemented by using a
|
||||
@ -101,7 +101,7 @@ SELECT complex_sum(a) FROM test_complex;
|
||||
the built-in implementation of <function>avg(float8)</function>
|
||||
looks like:
|
||||
|
||||
<programlisting>
|
||||
<programlisting>
|
||||
CREATE AGGREGATE avg (
|
||||
sfunc = float8_accum,
|
||||
basetype = float8,
|
||||
@ -109,18 +109,13 @@ CREATE AGGREGATE avg (
|
||||
finalfunc = float8_avg,
|
||||
initcond = '{0,0}'
|
||||
);
|
||||
</programlisting>
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For further details see
|
||||
<!--
|
||||
Not available in the Programmer's Guide
|
||||
<xref endterm="sql-createaggregate-title"
|
||||
linkend="sql-createaggregate-title">.
|
||||
-->
|
||||
<command>CREATE AGGREGATE</command> in
|
||||
<citetitle>The PostgreSQL User's Guide</citetitle>.
|
||||
For further details see the description of the <command>CREATE
|
||||
AGGREGATE</command> command in the <citetitle>Reference
|
||||
Manual</citetitle>.
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.45 2001/11/21 06:09:45 thomas Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.46 2002/01/07 02:29:14 petere Exp $
|
||||
-->
|
||||
|
||||
<chapter id="xfunc">
|
||||
@ -59,7 +59,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.45 2001/11/21 06:09:45 thoma
|
||||
|
||||
<para>
|
||||
Every kind
|
||||
of function can take a base type, a composite type or
|
||||
of function can take a base type, a composite type, or
|
||||
some combination as arguments (parameters). In addition,
|
||||
every kind of function can return a base type or
|
||||
a composite type. It's easiest to define <acronym>SQL</acronym>
|
||||
@ -67,6 +67,12 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.45 2001/11/21 06:09:45 thoma
|
||||
can also be found in <filename>funcs.sql</filename>
|
||||
and <filename>funcs.c</filename> in the tutorial directory.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Throughout this chapter, it can be useful to look at the reference
|
||||
page of the <command>CREATE FUNCTION</command> command to
|
||||
understand the examples better.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="xfunc-sql">
|
||||
@ -268,7 +274,7 @@ SELECT name, double_salary(EMP) AS dream
|
||||
<para>
|
||||
Notice the use of the syntax <literal>$1.salary</literal>
|
||||
to select one field of the argument row value. Also notice
|
||||
how the calling SELECT command uses a table name to denote
|
||||
how the calling <command>SELECT</> command uses a table name to denote
|
||||
the entire current row of that table as a composite value.
|
||||
</para>
|
||||
|
||||
@ -376,7 +382,7 @@ ERROR: parser: parse error at or near "."
|
||||
|
||||
<para>
|
||||
Another way to use a function returning a row result is to declare a
|
||||
second function accepting a rowtype parameter, and pass the function
|
||||
second function accepting a row type parameter, and pass the function
|
||||
result to it:
|
||||
|
||||
<programlisting>
|
||||
@ -400,15 +406,15 @@ SELECT getname(new_emp());
|
||||
|
||||
<para>
|
||||
As previously mentioned, an SQL function may be declared as
|
||||
returning <literal>SETOF</literal> <replaceable>sometype</>.
|
||||
In this case the function's final SELECT query is executed to
|
||||
returning <literal>SETOF <replaceable>sometype</></literal>.
|
||||
In this case the function's final <command>SELECT</> query is executed to
|
||||
completion, and each row it outputs is returned as an element
|
||||
of the set.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Functions returning sets may only be called in the target list
|
||||
of a SELECT query. For each row that the SELECT generates by itself,
|
||||
of a <command>SELECT</> query. For each row that the <command>SELECT</> generates by itself,
|
||||
the function returning set is invoked, and an output row is generated
|
||||
for each element of the function's result set. An example:
|
||||
|
||||
@ -449,9 +455,9 @@ SELECT name, listchildren(name) FROM nodes;
|
||||
(5 rows)
|
||||
</screen>
|
||||
|
||||
In the last SELECT,
|
||||
notice that no output row appears for Child2, Child3, etc.
|
||||
This happens because listchildren() returns an empty set
|
||||
In the last <command>SELECT</command>,
|
||||
notice that no output row appears for <literal>Child2</>, <literal>Child3</>, etc.
|
||||
This happens because <function>listchildren</function> returns an empty set
|
||||
for those inputs, so no output rows are generated.
|
||||
</para>
|
||||
</sect2>
|
||||
@ -607,7 +613,7 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision
|
||||
|
||||
<note>
|
||||
<para>
|
||||
The user id the <application>PostgreSQL</application> server runs
|
||||
The user ID the <application>PostgreSQL</application> server runs
|
||||
as must be able to traverse the path to the file you intend to
|
||||
load. Making the file or a higher-level directory not readable
|
||||
and/or not executable by the <quote>postgres</quote> user is a
|
||||
@ -671,7 +677,7 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision
|
||||
<para>
|
||||
<xref linkend="xfunc-c-type-table"> gives the C type required for
|
||||
parameters in the C functions that will be loaded into
|
||||
<productname>PostgreSQL</>
|
||||
<productname>PostgreSQL</>.
|
||||
The <quote>Defined In</quote> column gives the header file that
|
||||
needs to be included to get the type definition. (The actual
|
||||
definition may be in a different file that is included by the
|
||||
@ -1262,9 +1268,9 @@ concat_text(PG_FUNCTION_ARGS)
|
||||
At first glance, the version-1 coding conventions may appear to
|
||||
be just pointless obscurantism. However, they do offer a number
|
||||
of improvements, because the macros can hide unnecessary detail.
|
||||
An example is that in coding add_one_float8, we no longer need to
|
||||
be aware that float8 is a pass-by-reference type. Another
|
||||
example is that the GETARG macros for variable-length types hide
|
||||
An example is that in coding <function>add_one_float8</>, we no longer need to
|
||||
be aware that <type>float8</type> is a pass-by-reference type. Another
|
||||
example is that the <literal>GETARG</> macros for variable-length types hide
|
||||
the need to deal with fetching <quote>toasted</quote> (compressed or
|
||||
out-of-line) values. The old-style <function>copytext</function>
|
||||
and <function>concat_text</function> functions shown above are
|
||||
@ -1277,7 +1283,7 @@ concat_text(PG_FUNCTION_ARGS)
|
||||
|
||||
<para>
|
||||
One big improvement in version-1 functions is better handling of NULL
|
||||
inputs and results. The macro <function>PG_ARGISNULL(n)</function>
|
||||
inputs and results. The macro <function>PG_ARGISNULL(<replaceable>n</>)</function>
|
||||
allows a function to test whether each input is NULL (of course, doing
|
||||
this is only necessary in functions not declared <quote>strict</>).
|
||||
As with the
|
||||
@ -1287,7 +1293,7 @@ concat_text(PG_FUNCTION_ARGS)
|
||||
<function>PG_GETARG_<replaceable>xxx</replaceable>()</function> until
|
||||
one has verified that the argument isn't NULL.
|
||||
To return a NULL result, execute <function>PG_RETURN_NULL()</function>;
|
||||
this works in both strict and non-strict functions.
|
||||
this works in both strict and nonstrict functions.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -1323,7 +1329,7 @@ FROM emp
|
||||
WHERE name = 'Bill' OR name = 'Sam';
|
||||
</programlisting>
|
||||
|
||||
In the query above, we can define c_overpaid as:
|
||||
In the query above, we can define <function>c_overpaid</> as:
|
||||
|
||||
<programlisting>
|
||||
#include "postgres.h"
|
||||
@ -1371,13 +1377,13 @@ c_overpaid(PG_FUNCTION_ARGS)
|
||||
three arguments: the argument of type <type>TupleTableSlot*</type> passed into
|
||||
the function, the name of the desired attribute, and a
|
||||
return parameter that tells whether the attribute
|
||||
is null. <function>GetAttributeByName</function> returns a Datum
|
||||
value that you can convert to the proper datatype by using the
|
||||
is null. <function>GetAttributeByName</function> returns a <type>Datum</type>
|
||||
value that you can convert to the proper data type by using the
|
||||
appropriate <function>DatumGet<replaceable>XXX</replaceable>()</function> macro.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The following query lets <productname>PostgreSQL</productname>
|
||||
The following command lets <productname>PostgreSQL</productname>
|
||||
know about the <function>c_overpaid</function> function:
|
||||
|
||||
<programlisting>
|
||||
|
@ -1,15 +1,18 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.21 2001/11/21 06:09:45 thomas Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.22 2002/01/07 02:29:14 petere Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
<chapter id="xindex">
|
||||
<title>Interfacing Extensions To Indexes</title>
|
||||
<chapter id="xindex">
|
||||
<title>Interfacing Extensions To Indexes</title>
|
||||
|
||||
<sect1 id="xindex-intro">
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>
|
||||
The procedures described thus far let you define a new type, new
|
||||
functions and new operators. However, we cannot yet define a secondary
|
||||
index (such as a <acronym>B-tree</acronym>, <acronym>R-tree</acronym> or
|
||||
The procedures described thus far let you define new types, new
|
||||
functions, and new operators. However, we cannot yet define a secondary
|
||||
index (such as a B-tree, R-tree, or
|
||||
hash access method) over a new type or its operators.
|
||||
</para>
|
||||
|
||||
@ -25,14 +28,19 @@ PostgreSQL documentation
|
||||
class for the <acronym>B-tree</acronym> access method that stores and
|
||||
sorts complex numbers in ascending absolute value order.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="xindex-am">
|
||||
<title>Access Methods</title>
|
||||
|
||||
<para>
|
||||
The <filename>pg_am</filename> table contains one row for every index
|
||||
access method. Support for the heap access method is built into
|
||||
<productname>PostgreSQL</productname>, but every other access method is
|
||||
described in <filename>pg_am</filename>. The schema is
|
||||
The <filename>pg_am</filename> table contains one row for every
|
||||
index access method. Support for the heap access method is built
|
||||
into <productname>PostgreSQL</productname>, but all other access
|
||||
methods are described in <filename>pg_am</filename>. The schema is
|
||||
shown in <xref linkend="xindex-pgam-table">.
|
||||
|
||||
<table tocentry="1">
|
||||
<table tocentry="1" id="xindex-pgam-table">
|
||||
<title>Index Access Method Schema</title>
|
||||
|
||||
<tgroup cols="2">
|
||||
@ -49,7 +57,7 @@ PostgreSQL documentation
|
||||
</row>
|
||||
<row>
|
||||
<entry>amowner</entry>
|
||||
<entry>user id of the owner</entry>
|
||||
<entry>user ID of the owner (currently not used)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>amstrategies</entry>
|
||||
@ -66,7 +74,7 @@ PostgreSQL documentation
|
||||
</row>
|
||||
<row>
|
||||
<entry>amcanunique</entry>
|
||||
<entry>does AM support UNIQUE indexes?</entry>
|
||||
<entry>does AM support unique indexes?</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>amcanmulticol</entry>
|
||||
@ -89,7 +97,7 @@ PostgreSQL documentation
|
||||
<row>
|
||||
<entry>...</entry>
|
||||
<entry>procedure identifiers for interface routines to the access
|
||||
method. For example, regproc ids for opening, closing, and
|
||||
method. For example, regproc IDs for opening, closing, and
|
||||
getting rows from the access method appear here.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
@ -104,49 +112,55 @@ PostgreSQL documentation
|
||||
you are interested in is the <acronym>object ID</acronym> of the access
|
||||
method you want to extend:
|
||||
|
||||
<programlisting>
|
||||
<screen>
|
||||
SELECT oid FROM pg_am WHERE amname = 'btree';
|
||||
|
||||
oid
|
||||
-----
|
||||
403
|
||||
(1 row)
|
||||
</programlisting>
|
||||
</screen>
|
||||
|
||||
We will use that <command>SELECT</command> in a <command>WHERE</command>
|
||||
We will use that query in a <literal>WHERE</literal>
|
||||
clause later.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="xindex-strategies">
|
||||
<title>Access Method Strategies</title>
|
||||
|
||||
<para>
|
||||
The <filename>amstrategies</filename> column exists to standardize
|
||||
comparisons across data types. For example, <acronym>B-tree</acronym>s
|
||||
The <structfield>amstrategies</structfield> column exists to standardize
|
||||
comparisons across data types. For example, B-trees
|
||||
impose a strict ordering on keys, lesser to greater. Since
|
||||
<productname>PostgreSQL</productname> allows the user to define operators,
|
||||
<productname>PostgreSQL</productname> cannot look at the name of an operator
|
||||
(e.g., <literal>></> or <literal><</>) and tell what kind of comparison it is. In fact,
|
||||
some access methods don't impose any ordering at all. For example,
|
||||
<acronym>R-tree</acronym>s express a rectangle-containment relationship,
|
||||
R-trees express a rectangle-containment relationship,
|
||||
whereas a hashed data structure expresses only bitwise similarity based
|
||||
on the value of a hash function. <productname>PostgreSQL</productname>
|
||||
needs some consistent way of taking a qualification in your query,
|
||||
looking at the operator and then deciding if a usable index exists. This
|
||||
looking at the operator, and then deciding if a usable index exists. This
|
||||
implies that <productname>PostgreSQL</productname> needs to know, for
|
||||
example, that the <literal><=</> and <literal>></> operators partition a
|
||||
<acronym>B-tree</acronym>. <productname>PostgreSQL</productname>
|
||||
uses strategies to express these relationships between
|
||||
B-tree. <productname>PostgreSQL</productname>
|
||||
uses <firstterm>strategies</firstterm> to express these relationships between
|
||||
operators and the way they can be used to scan indexes.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Defining a new set of strategies is beyond the scope of this discussion,
|
||||
but we'll explain how <acronym>B-tree</acronym> strategies work because
|
||||
Defining a new set of strategies is beyond the scope of this
|
||||
discussion, but we'll explain how B-tree strategies work because
|
||||
you'll need to know that to add a new B-tree operator class. In the
|
||||
<filename>pg_am</filename> table, the amstrategies column is the
|
||||
number of strategies defined for this access method. For
|
||||
<acronym>B-tree</acronym>s, this number is 5. These strategies
|
||||
correspond to
|
||||
<classname>pg_am</classname> table, the
|
||||
<structfield>amstrategies</structfield> column sets the number of
|
||||
strategies defined for this access method. For B-trees, this number
|
||||
is 5. The meanings of these strategies are shown in <xref
|
||||
linkend="xindex-btree-table">.
|
||||
</para>
|
||||
|
||||
<table tocentry="1">
|
||||
<table tocentry="1" id="xindex-btree-table">
|
||||
<title>B-tree Strategies</title>
|
||||
<titleabbrev>B-tree</titleabbrev>
|
||||
<tgroup cols="2">
|
||||
@ -180,26 +194,29 @@ SELECT oid FROM pg_am WHERE amname = 'btree';
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The idea is that you'll need to add operators corresponding to the
|
||||
comparisons above to the <filename>pg_amop</filename> relation (see below).
|
||||
The idea is that you'll need to add operators corresponding to these strategies
|
||||
to the <classname>pg_amop</classname> relation (see below).
|
||||
The access method code can use these strategy numbers, regardless of data
|
||||
type, to figure out how to partition the <acronym>B-tree</acronym>,
|
||||
type, to figure out how to partition the B-tree,
|
||||
compute selectivity, and so on. Don't worry about the details of adding
|
||||
operators yet; just understand that there must be a set of these
|
||||
operators for <filename>int2, int4, oid,</filename> and every other
|
||||
data type on which a <acronym>B-tree</acronym> can operate.
|
||||
operators for <type>int2</>, <type>int4</>, <type>oid</>, and all other
|
||||
data types on which a B-tree can operate.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="xindex-support">
|
||||
<title>Access Method Support Routines</title>
|
||||
|
||||
<para>
|
||||
Sometimes, strategies aren't enough information for the system to figure
|
||||
out how to use an index. Some access methods require additional support
|
||||
routines in order to work. For example, the <acronym>B-tree</acronym>
|
||||
routines in order to work. For example, the B-tree
|
||||
access method must be able to compare two keys and determine whether one
|
||||
is greater than, equal to, or less than the other. Similarly, the
|
||||
<acronym>R-tree</acronym> access method must be able to compute
|
||||
R-tree access method must be able to compute
|
||||
intersections, unions, and sizes of rectangles. These
|
||||
operations do not correspond to operators used in qualifications in
|
||||
SQL queries; they are administrative routines used by
|
||||
@ -209,60 +226,60 @@ SELECT oid FROM pg_am WHERE amname = 'btree';
|
||||
<para>
|
||||
In order to manage diverse support routines consistently across all
|
||||
<productname>PostgreSQL</productname> access methods,
|
||||
<filename>pg_am</filename> includes a column called
|
||||
<filename>amsupport</filename>. This column records the number of
|
||||
support routines used by an access method. For <acronym>B-tree</acronym>s,
|
||||
this number is one -- the routine to take two keys and return -1, 0, or
|
||||
+1, depending on whether the first key is less than, equal
|
||||
to, or greater than the second.
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Strictly speaking, this routine can return a negative
|
||||
number (< 0), zero, or a non-zero positive number (> 0).
|
||||
</para>
|
||||
</note>
|
||||
<classname>pg_am</classname> includes a column called
|
||||
<structfield>amsupport</structfield>. This column records the
|
||||
number of support routines used by an access method. For B-trees,
|
||||
this number is one: the routine to take two keys and return -1, 0,
|
||||
or +1, depending on whether the first key is less than, equal to,
|
||||
or greater than the second. (Strictly speaking, this routine can
|
||||
return a negative number (< 0), zero, or a non-zero positive
|
||||
number (> 0).)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <filename>amstrategies</filename> entry in <filename>pg_am</filename>
|
||||
is just the number
|
||||
of strategies defined for the access method in question. The operators
|
||||
for less than, less equal, and so on don't appear in
|
||||
<filename>pg_am</filename>. Similarly, <filename>amsupport</filename>
|
||||
is just the number of support routines required by the access
|
||||
method. The actual routines are listed elsewhere.
|
||||
The <structfield>amstrategies</structfield> entry in
|
||||
<classname>pg_am</classname> is just the number of strategies
|
||||
defined for the access method in question. The operators for less
|
||||
than, less equal, and so on don't appear in
|
||||
<classname>pg_am</classname>. Similarly,
|
||||
<structfield>amsupport</structfield> is just the number of support
|
||||
routines required by the access method. The actual routines are
|
||||
listed elsewhere.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
By the way, the <filename>amorderstrategy</filename> entry tells whether
|
||||
By the way, the <structfield>amorderstrategy</structfield> column tells whether
|
||||
the access method supports ordered scan. Zero means it doesn't; if it
|
||||
does, <filename>amorderstrategy</filename> is the number of the strategy
|
||||
does, <structfield>amorderstrategy</structfield> is the number of the strategy
|
||||
routine that corresponds to the ordering operator. For example, B-tree
|
||||
has <filename>amorderstrategy</filename> = 1 which is its
|
||||
has <structfield>amorderstrategy</structfield> = 1, which is its
|
||||
<quote>less than</quote> strategy number.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="xindex-opclass">
|
||||
<title>Operator Classes</title>
|
||||
|
||||
<para>
|
||||
The next table of interest is <filename>pg_opclass</filename>. This table
|
||||
The next table of interest is <classname>pg_opclass</classname>. This table
|
||||
defines operator class names and input data types for each of the operator
|
||||
classes supported by a given index access method. The same class name
|
||||
can be used for several different access methods (for example, both B-tree
|
||||
and hash access methods have operator classes named
|
||||
<filename>oid_ops</filename>), but a separate
|
||||
<literal>oid_ops</literal>), but a separate
|
||||
<filename>pg_opclass</filename> row must appear for each access method.
|
||||
The <filename>oid</filename> of the <filename>pg_opclass</filename> row is
|
||||
The OID of the <classname>pg_opclass</classname> row is
|
||||
used as a foreign
|
||||
key in other tables to associate specific operators and support routines
|
||||
with the operator class.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You need to add a row with your opclass name (for example,
|
||||
<filename>complex_abs_ops</filename>) to
|
||||
<filename>pg_opclass</filename>:
|
||||
You need to add a row with your operator class name (for example,
|
||||
<literal>complex_abs_ops</literal>) to
|
||||
<classname>pg_opclass</classname>:
|
||||
|
||||
<programlisting>
|
||||
<programlisting>
|
||||
INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype)
|
||||
VALUES (
|
||||
(SELECT oid FROM pg_am WHERE amname = 'btree'),
|
||||
@ -279,52 +296,50 @@ SELECT oid, *
|
||||
--------+---------+-----------------+-----------+------------+------------
|
||||
277975 | 403 | complex_abs_ops | 277946 | t | 0
|
||||
(1 row)
|
||||
</programlisting>
|
||||
</programlisting>
|
||||
|
||||
Note that the oid for your <filename>pg_opclass</filename> row will
|
||||
Note that the OID for your <classname>pg_opclass</classname> row will
|
||||
be different! Don't worry about this though. We'll get this number
|
||||
from the system later just like we got the oid of the type here.
|
||||
from the system later just like we got the OID of the type here.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The above example assumes that you want to make this new opclass the
|
||||
default B-tree opclass for the <filename>complex</filename> data type.
|
||||
If you don't, just set <filename>opcdefault</filename> to false instead.
|
||||
<filename>opckeytype</filename> is not described here; it should always
|
||||
be zero for B-tree opclasses.
|
||||
The above example assumes that you want to make this new operator class the
|
||||
default B-tree operator class for the <type>complex</type> data type.
|
||||
If you don't, just set <structfield>opcdefault</structfield> to false instead.
|
||||
<structfield>opckeytype</structfield> is not described here; it should always
|
||||
be zero for B-tree operator classes.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="xindex-operators">
|
||||
<title>Creating the Operators and Support Routines</title>
|
||||
|
||||
<para>
|
||||
So now we have an access method and an operator class.
|
||||
We still need a set of operators. The procedure for
|
||||
defining operators was discussed earlier in this manual.
|
||||
For the <filename>complex_abs_ops</filename> operator class on B-trees,
|
||||
defining operators was discussed in <xref linkend="xoper">.
|
||||
For the <literal>complex_abs_ops</literal> operator class on B-trees,
|
||||
the operators we require are:
|
||||
|
||||
<programlisting>
|
||||
absolute value less-than
|
||||
absolute value less-than-or-equal
|
||||
absolute value equal
|
||||
absolute value greater-than-or-equal
|
||||
absolute value greater-than
|
||||
</programlisting>
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem><simpara>absolute-value less-than (strategy 1)</></>
|
||||
<listitem><simpara>absolute-value less-than-or-equal (strategy 2)</></>
|
||||
<listitem><simpara>absolute-value equal (strategy 3)</></>
|
||||
<listitem><simpara>absolute-value greater-than-or-equal (strategy 4)</></>
|
||||
<listitem><simpara>absolute-value greater-than (strategy 5)</></>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Suppose the code that implements these functions
|
||||
is stored in the file
|
||||
<replaceable>PGROOT</replaceable><filename>/tutorial/complex.c</filename>,
|
||||
<filename><replaceable>PGROOT</replaceable>/src/tutorial/complex.c</filename>,
|
||||
which we have compiled into
|
||||
<replaceable>PGROOT</replaceable><filename>/tutorial/complex.so</filename>.
|
||||
</para>
|
||||
<filename><replaceable>PGROOT</replaceable>/src/tutorial/complex.so</filename>.
|
||||
Part of the C code looks like this:
|
||||
|
||||
<para>
|
||||
Part of the C code looks like this: (note that we will only show the
|
||||
equality operator for the rest of the examples. The other four
|
||||
operators are very similar. Refer to <filename>complex.c</filename>
|
||||
or <filename>complex.source</filename> for the details.)
|
||||
|
||||
<programlisting>
|
||||
<programlisting>
|
||||
#define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y)
|
||||
|
||||
bool
|
||||
@ -333,23 +348,27 @@ SELECT oid, *
|
||||
double amag = Mag(a), bmag = Mag(b);
|
||||
return (amag==bmag);
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting>
|
||||
(Note that we will only show the equality operator for the rest of
|
||||
the examples. The other four operators are very similar. Refer to
|
||||
<filename>complex.c</filename> or
|
||||
<filename>complex.source</filename> for the details.)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
We make the function known to <productname>PostgreSQL</productname> like this:
|
||||
<programlisting>
|
||||
CREATE FUNCTION complex_abs_eq(complex, complex)
|
||||
RETURNS bool
|
||||
AS '<replaceable>PGROOT</replaceable>/tutorial/complex'
|
||||
LANGUAGE C;
|
||||
</programlisting>
|
||||
<programlisting>
|
||||
CREATE FUNCTION complex_abs_eq(complex, complex) RETURNS boolean
|
||||
AS '<replaceable>PGROOT</replaceable>/src/tutorial/complex'
|
||||
LANGUAGE C;
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
There are some important things that are happening here.
|
||||
</para>
|
||||
There are some important things that are happening here:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
First, note that operators for less-than, less-than-or-equal, equal,
|
||||
greater-than-or-equal, and greater-than for <filename>complex</filename>
|
||||
@ -358,9 +377,11 @@ CREATE FUNCTION complex_abs_eq(complex, complex)
|
||||
we don't have any other operator = for <filename>complex</filename>,
|
||||
but if we were building a practical data type we'd probably want = to
|
||||
be the ordinary equality operation for complex numbers. In that case,
|
||||
we'd need to use some other operator name for complex_abs_eq.
|
||||
we'd need to use some other operator name for <function>complex_abs_eq</>.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Second, although <productname>PostgreSQL</productname> can cope with operators having
|
||||
the same name as long as they have different input data types, C can only
|
||||
@ -369,7 +390,9 @@ CREATE FUNCTION complex_abs_eq(complex, complex)
|
||||
Usually it's a good practice to include the data type name in the C
|
||||
function name, so as not to conflict with functions for other data types.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Third, we could have made the <productname>PostgreSQL</productname> name of the function
|
||||
<filename>abs_eq</filename>, relying on <productname>PostgreSQL</productname> to distinguish it
|
||||
@ -377,58 +400,63 @@ CREATE FUNCTION complex_abs_eq(complex, complex)
|
||||
To keep the example simple, we make the function have the same names
|
||||
at the C level and <productname>PostgreSQL</productname> level.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Finally, note that these operator functions return Boolean values.
|
||||
In practice, all operators defined as index access method strategies
|
||||
must return Boolean, since they must appear at the top level of a WHERE
|
||||
clause to be used with an index.
|
||||
(On the other
|
||||
hand, the support function returns whatever the particular access method
|
||||
expects -- in this case, a signed integer.)
|
||||
In practice, all operators defined as index access method
|
||||
strategies must return type <type>boolean</type>, since they must
|
||||
appear at the top level of a <literal>WHERE</> clause to be used with an index.
|
||||
(On the other hand, the support function returns whatever the
|
||||
particular access method expects -- in this case, a signed
|
||||
integer.)
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The final routine in the
|
||||
file is the <quote>support routine</quote> mentioned when we discussed the amsupport
|
||||
column of the <filename>pg_am</filename> table. We will use this
|
||||
later on. For now, ignore it.
|
||||
The final routine in the file is the <quote>support routine</quote>
|
||||
mentioned when we discussed the <structfield>amsupport</> column of the
|
||||
<classname>pg_am</classname> table. We will use this later on. For
|
||||
now, ignore it.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Now we are ready to define the operators:
|
||||
|
||||
<programlisting>
|
||||
<programlisting>
|
||||
CREATE OPERATOR = (
|
||||
leftarg = complex, rightarg = complex,
|
||||
procedure = complex_abs_eq,
|
||||
restrict = eqsel, join = eqjoinsel
|
||||
);
|
||||
</programlisting>
|
||||
</programlisting>
|
||||
|
||||
The important
|
||||
things here are the procedure names (which are the <acronym>C</acronym>
|
||||
things here are the procedure names (which are the C
|
||||
functions defined above) and the restriction and join selectivity
|
||||
functions. You should just use the selectivity functions used in
|
||||
the example (see <filename>complex.source</filename>).
|
||||
Note that there
|
||||
are different such functions for the less-than, equal, and greater-than
|
||||
cases. These must be supplied, or the optimizer will be unable to
|
||||
cases. These must be supplied or the optimizer will be unable to
|
||||
make effective use of the index.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The next step is to add entries for these operators to
|
||||
the <filename>pg_amop</filename> relation. To do this,
|
||||
we'll need the <filename>oid</filename>s of the operators we just
|
||||
the <classname>pg_amop</classname> relation. To do this,
|
||||
we'll need the OIDs of the operators we just
|
||||
defined. We'll look up the names of all the operators that take
|
||||
two <filename>complex</filename>es, and pick ours out:
|
||||
two operands of type <type>complex</type>, and pick ours out:
|
||||
|
||||
<programlisting>
|
||||
SELECT o.oid AS opoid, o.oprname
|
||||
INTO TEMP TABLE complex_ops_tmp
|
||||
FROM pg_operator o, pg_type t
|
||||
WHERE o.oprleft = t.oid and o.oprright = t.oid
|
||||
<screen>
|
||||
SELECT o.oid AS opoid, o.oprname
|
||||
INTO TEMP TABLE complex_ops_tmp
|
||||
FROM pg_operator o, pg_type t
|
||||
WHERE o.oprleft = t.oid and o.oprright = t.oid
|
||||
and t.typname = 'complex';
|
||||
|
||||
opoid | oprname
|
||||
@ -440,30 +468,30 @@ CREATE OPERATOR = (
|
||||
277973 | >=
|
||||
277974 | >
|
||||
(6 rows)
|
||||
</programlisting>
|
||||
</screen>
|
||||
|
||||
(Again, some of your <filename>oid</filename> numbers will almost
|
||||
(Again, some of your OID numbers will almost
|
||||
certainly be different.) The operators we are interested in are those
|
||||
with <filename>oid</filename>s 277970 through 277974. The values you
|
||||
with OIDs 277970 through 277974. The values you
|
||||
get will probably be different, and you should substitute them for the
|
||||
values below. We will do this with a select statement.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Now we are ready to insert entries into <filename>pg_amop</filename> for
|
||||
Now we are ready to insert entries into <classname>pg_amop</classname> for
|
||||
our new operator class. These entries must associate the correct
|
||||
B-tree strategy numbers with each of the operators we need.
|
||||
The command to insert the less-than operator looks like:
|
||||
|
||||
<programlisting>
|
||||
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
|
||||
SELECT opcl.oid, 1, false, c.opoid
|
||||
<programlisting>
|
||||
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
|
||||
SELECT opcl.oid, 1, false, c.opoid
|
||||
FROM pg_opclass opcl, complex_ops_tmp c
|
||||
WHERE
|
||||
opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree') AND
|
||||
opcname = 'complex_abs_ops' AND
|
||||
c.oprname = '<';
|
||||
</programlisting>
|
||||
</programlisting>
|
||||
|
||||
Now do this for the other operators substituting for the <literal>1</> in the
|
||||
second line above and the <literal><</> in the last line. Note the order:
|
||||
@ -478,51 +506,58 @@ CREATE OPERATOR = (
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The final step is registration of the <quote>support routine</quote> previously
|
||||
described in our discussion of <filename>pg_am</filename>. The
|
||||
<filename>oid</filename> of this support routine is stored in the
|
||||
<filename>pg_amproc</filename> table, keyed by the operator class
|
||||
<filename>oid</filename> and the support routine number.
|
||||
The final step is the registration of the <quote>support routine</quote> previously
|
||||
described in our discussion of <classname>pg_am</classname>. The
|
||||
OID of this support routine is stored in the
|
||||
<classname>pg_amproc</classname> table, keyed by the operator class
|
||||
OID and the support routine number.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
First, we need to register the function in
|
||||
<productname>PostgreSQL</productname> (recall that we put the
|
||||
<acronym>C</acronym> code that implements this routine in the bottom of
|
||||
C code that implements this routine in the bottom of
|
||||
the file in which we implemented the operator routines):
|
||||
|
||||
<programlisting>
|
||||
CREATE FUNCTION complex_abs_cmp(complex, complex)
|
||||
RETURNS int4
|
||||
AS '<replaceable>PGROOT</replaceable>/tutorial/complex'
|
||||
LANGUAGE C;
|
||||
<programlisting>
|
||||
CREATE FUNCTION complex_abs_cmp(complex, complex)
|
||||
RETURNS integer
|
||||
AS '<replaceable>PGROOT</replaceable>/src/tutorial/complex'
|
||||
LANGUAGE C;
|
||||
|
||||
SELECT oid, proname FROM pg_proc
|
||||
WHERE proname = 'complex_abs_cmp';
|
||||
SELECT oid, proname FROM pg_proc
|
||||
WHERE proname = 'complex_abs_cmp';
|
||||
|
||||
oid | proname
|
||||
--------+-----------------
|
||||
277997 | complex_abs_cmp
|
||||
(1 row)
|
||||
</programlisting>
|
||||
</programlisting>
|
||||
|
||||
(Again, your <filename>oid</filename> number will probably be different.)
|
||||
(Again, your OID number will probably be different.)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
We can add the new row as follows:
|
||||
|
||||
<programlisting>
|
||||
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
|
||||
SELECT opcl.oid, 1, p.oid
|
||||
<programlisting>
|
||||
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
|
||||
SELECT opcl.oid, 1, p.oid
|
||||
FROM pg_opclass opcl, pg_proc p
|
||||
WHERE
|
||||
opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree') AND
|
||||
opcname = 'complex_abs_ops' AND
|
||||
p.proname = 'complex_abs_cmp';
|
||||
</programlisting>
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
And we're done! (Whew.) It should now be possible to create
|
||||
and use B-tree indexes on <filename>complex</filename> columns.
|
||||
and use B-tree indexes on <type>complex</type> columns.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
|
@ -1,19 +1,22 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/xoper.sgml,v 1.16 2001/11/21 06:09:45 thomas Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/xoper.sgml,v 1.17 2002/01/07 02:29:14 petere Exp $
|
||||
-->
|
||||
|
||||
<Chapter Id="xoper">
|
||||
<Title>Extending <Acronym>SQL</Acronym>: Operators</Title>
|
||||
|
||||
<sect1 id="xoper-intro">
|
||||
<title>Introduction</title>
|
||||
|
||||
<Para>
|
||||
<ProductName>PostgreSQL</ProductName> supports left unary,
|
||||
right unary and binary
|
||||
right unary, and binary
|
||||
operators. Operators can be overloaded; that is,
|
||||
the same operator name can be used for different operators
|
||||
that have different numbers and types of arguments. If
|
||||
that have different numbers and types of operands. If
|
||||
there is an ambiguous situation and the system cannot
|
||||
determine the correct operator to use, it will return
|
||||
an error. You may have to typecast the left and/or
|
||||
an error. You may have to type-cast the left and/or
|
||||
right operands to help it understand which operator you
|
||||
meant to use.
|
||||
</Para>
|
||||
@ -22,20 +25,24 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xoper.sgml,v 1.16 2001/11/21 06:09:45 thoma
|
||||
Every operator is <quote>syntactic sugar</quote> for a call to an
|
||||
underlying function that does the real work; so you must
|
||||
first create the underlying function before you can create
|
||||
the operator. However, an operator is <emphasis>not</emphasis>
|
||||
merely syntactic sugar, because it carries additional information
|
||||
the operator. However, an operator is <emphasis>not merely</emphasis>
|
||||
syntactic sugar, because it carries additional information
|
||||
that helps the query planner optimize queries that use the
|
||||
operator. Much of this chapter will be devoted to explaining
|
||||
that additional information.
|
||||
</Para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="xoper-example">
|
||||
<title>Example</title>
|
||||
|
||||
<Para>
|
||||
Here is an example of creating an operator for adding two
|
||||
complex numbers. We assume we've already created the definition
|
||||
of type complex. First we need a function that does the work;
|
||||
then we can define the operator:
|
||||
Here is an example of creating an operator for adding two complex
|
||||
numbers. We assume we've already created the definition of type
|
||||
<type>complex</type> (see <xref linkend="xtypes">). First we need a
|
||||
function that does the work, then we can define the operator:
|
||||
|
||||
<ProgramListing>
|
||||
<ProgramListing>
|
||||
CREATE FUNCTION complex_add(complex, complex)
|
||||
RETURNS complex
|
||||
AS '<replaceable>PGROOT</replaceable>/tutorial/complex'
|
||||
@ -47,34 +54,33 @@ CREATE OPERATOR + (
|
||||
procedure = complex_add,
|
||||
commutator = +
|
||||
);
|
||||
</ProgramListing>
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Now we can do:
|
||||
|
||||
<ProgramListing>
|
||||
<screen>
|
||||
SELECT (a + b) AS c FROM test_complex;
|
||||
|
||||
+----------------+
|
||||
|c |
|
||||
+----------------+
|
||||
|(5.2,6.05) |
|
||||
+----------------+
|
||||
|(133.42,144.95) |
|
||||
+----------------+
|
||||
</ProgramListing>
|
||||
c
|
||||
-----------------
|
||||
(5.2,6.05)
|
||||
(133.42,144.95)
|
||||
</screen>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
We've shown how to create a binary operator here. To
|
||||
create unary operators, just omit one of leftarg (for
|
||||
left unary) or rightarg (for right unary). The procedure
|
||||
clause and the argument clauses are the only required items
|
||||
in CREATE OPERATOR. The COMMUTATOR clause shown in the example
|
||||
is an optional hint to the query optimizer. Further details about
|
||||
COMMUTATOR and other optimizer hints appear below.
|
||||
We've shown how to create a binary operator here. To create unary
|
||||
operators, just omit one of <literal>leftarg</> (for left unary) or
|
||||
<literal>rightarg</> (for right unary). The <literal>procedure</>
|
||||
clause and the argument clauses are the only required items in
|
||||
<command>CREATE OPERATOR</command>. The <literal>commutator</>
|
||||
clause shown in the example is an optional hint to the query
|
||||
optimizer. Further details about <literal>commutator</> and other
|
||||
optimizer hints appear below.
|
||||
</Para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="xoper-optimization">
|
||||
<title>Operator Optimization Information</title>
|
||||
@ -102,28 +108,28 @@ SELECT (a + b) AS c FROM test_complex;
|
||||
<para>
|
||||
Additional optimization clauses might be added in future versions of
|
||||
<ProductName>PostgreSQL</ProductName>. The ones described here are all
|
||||
the ones that release 6.5 understands.
|
||||
the ones that release &version; understands.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>COMMUTATOR</title>
|
||||
|
||||
<para>
|
||||
The COMMUTATOR clause, if provided, names an operator that is the
|
||||
The <literal>COMMUTATOR</> clause, if provided, names an operator that is the
|
||||
commutator of the operator being defined. We say that operator A is the
|
||||
commutator of operator B if (x A y) equals (y B x) for all possible input
|
||||
values x,y. Notice that B is also the commutator of A. For example,
|
||||
values x, y. Notice that B is also the commutator of A. For example,
|
||||
operators <literal><</> and <literal>></> for a particular data type are usually each others'
|
||||
commutators, and operator <literal>+</> is usually commutative with itself.
|
||||
But operator <literal>-</> is usually not commutative with anything.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The left argument type of a commuted operator is the same as the
|
||||
right argument type of its commutator, and vice versa. So the name of
|
||||
The left operand type of a commuted operator is the same as the
|
||||
right operand type of its commutator, and vice versa. So the name of
|
||||
the commutator operator is all that <ProductName>PostgreSQL</ProductName>
|
||||
needs to be given to look up the commutator, and that's all that need
|
||||
be provided in the COMMUTATOR clause.
|
||||
needs to be given to look up the commutator, and that's all that needs to
|
||||
be provided in the <literal>COMMUTATOR</> clause.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -136,29 +142,29 @@ SELECT (a + b) AS c FROM test_complex;
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
One way is to omit the COMMUTATOR clause in the first operator that
|
||||
One way is to omit the <literal>COMMUTATOR</> clause in the first operator that
|
||||
you define, and then provide one in the second operator's definition.
|
||||
Since <ProductName>PostgreSQL</ProductName> knows that commutative
|
||||
operators come in pairs, when it sees the second definition it will
|
||||
automatically go back and fill in the missing COMMUTATOR clause in
|
||||
automatically go back and fill in the missing <literal>COMMUTATOR</> clause in
|
||||
the first definition.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
The other, more straightforward way is just to include COMMUTATOR clauses
|
||||
The other, more straightforward way is just to include <literal>COMMUTATOR</> clauses
|
||||
in both definitions. When <ProductName>PostgreSQL</ProductName> processes
|
||||
the first definition and realizes that COMMUTATOR refers to a non-existent
|
||||
the first definition and realizes that <literal>COMMUTATOR</> refers to a non-existent
|
||||
operator, the system will make a dummy entry for that operator in the
|
||||
system's pg_operator table. This dummy entry will have valid data only
|
||||
for the operator name, left and right argument types, and result type,
|
||||
system catalog. This dummy entry will have valid data only
|
||||
for the operator name, left and right operand types, and result type,
|
||||
since that's all that <ProductName>PostgreSQL</ProductName> can deduce
|
||||
at this point. The first operator's catalog entry will link to this
|
||||
dummy entry. Later, when you define the second operator, the system
|
||||
updates the dummy entry with the additional information from the second
|
||||
definition. If you try to use the dummy operator before it's been filled
|
||||
in, you'll just get an error message. (Note: this procedure did not work
|
||||
in, you'll just get an error message. (Note: This procedure did not work
|
||||
reliably in <ProductName>PostgreSQL</ProductName> versions before 6.5,
|
||||
but it is now the recommended way to do things.)
|
||||
</para>
|
||||
@ -171,29 +177,29 @@ SELECT (a + b) AS c FROM test_complex;
|
||||
<title>NEGATOR</title>
|
||||
|
||||
<para>
|
||||
The NEGATOR clause, if provided, names an operator that is the
|
||||
The <literal>NEGATOR</> clause, if provided, names an operator that is the
|
||||
negator of the operator being defined. We say that operator A
|
||||
is the negator of operator B if both return boolean results and
|
||||
(x A y) equals NOT (x B y) for all possible inputs x,y.
|
||||
is the negator of operator B if both return Boolean results and
|
||||
(x A y) equals NOT (x B y) for all possible inputs x, y.
|
||||
Notice that B is also the negator of A.
|
||||
For example, <literal><</> and <literal>>=</> are a negator pair for most data types.
|
||||
An operator can never be validly be its own negator.
|
||||
An operator can never validly be its own negator.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Unlike COMMUTATOR, a pair of unary operators could validly be marked
|
||||
Unlike commutators, a pair of unary operators could validly be marked
|
||||
as each others' negators; that would mean (A x) equals NOT (B x)
|
||||
for all x, or the equivalent for right-unary operators.
|
||||
for all x, or the equivalent for right unary operators.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
An operator's negator must have the same left and/or right argument types
|
||||
as the operator itself, so just as with COMMUTATOR, only the operator
|
||||
name need be given in the NEGATOR clause.
|
||||
An operator's negator must have the same left and/or right operand types
|
||||
as the operator itself, so just as with <literal>COMMUTATOR</>, only the operator
|
||||
name need be given in the <literal>NEGATOR</> clause.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Providing NEGATOR is very helpful to the query optimizer since
|
||||
Providing a negator is very helpful to the query optimizer since
|
||||
it allows expressions like NOT (x = y) to be simplified into
|
||||
x <> y. This comes up more often than you might think, because
|
||||
NOTs can be inserted as a consequence of other rearrangements.
|
||||
@ -210,21 +216,21 @@ SELECT (a + b) AS c FROM test_complex;
|
||||
<title>RESTRICT</title>
|
||||
|
||||
<para>
|
||||
The RESTRICT clause, if provided, names a restriction selectivity
|
||||
The <literal>RESTRICT</> clause, if provided, names a restriction selectivity
|
||||
estimation function for the operator (note that this is a function
|
||||
name, not an operator name). RESTRICT clauses only make sense for
|
||||
binary operators that return boolean. The idea behind a restriction
|
||||
name, not an operator name). <literal>RESTRICT</> clauses only make sense for
|
||||
binary operators that return <type>boolean</>. The idea behind a restriction
|
||||
selectivity estimator is to guess what fraction of the rows in a
|
||||
table will satisfy a WHERE-clause condition of the form
|
||||
<ProgramListing>
|
||||
field OP constant
|
||||
</ProgramListing>
|
||||
table will satisfy a <literal>WHERE</literal>-clause condition of the form
|
||||
<ProgramListing>
|
||||
column OP constant
|
||||
</ProgramListing>
|
||||
for the current operator and a particular constant value.
|
||||
This assists the optimizer by
|
||||
giving it some idea of how many rows will be eliminated by WHERE
|
||||
giving it some idea of how many rows will be eliminated by <literal>WHERE</>
|
||||
clauses that have this form. (What happens if the constant is on
|
||||
the left, you may be wondering? Well, that's one of the things that
|
||||
COMMUTATOR is for...)
|
||||
<literal>COMMUTATOR</> is for...)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -232,12 +238,12 @@ SELECT (a + b) AS c FROM test_complex;
|
||||
the scope of this chapter, but fortunately you can usually just use
|
||||
one of the system's standard estimators for many of your own operators.
|
||||
These are the standard restriction estimators:
|
||||
<ProgramListing>
|
||||
eqsel for =
|
||||
neqsel for <>
|
||||
scalarltsel for < or <=
|
||||
scalargtsel for > or >=
|
||||
</ProgramListing>
|
||||
<simplelist>
|
||||
<member><function>eqsel</> for <literal>=</></member>
|
||||
<member><function>neqsel</> for <literal><></></member>
|
||||
<member><function>scalarltsel</> for <literal><</> or <literal><=</></member>
|
||||
<member><function>scalargtsel</> for <literal>></> or <literal>>=</></member>
|
||||
</simplelist>
|
||||
It might seem a little odd that these are the categories, but they
|
||||
make sense if you think about it. <literal>=</> will typically accept only
|
||||
a small fraction of the rows in a table; <literal><></> will typically reject
|
||||
@ -252,28 +258,28 @@ SELECT (a + b) AS c FROM test_complex;
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You can frequently get away with using either eqsel or neqsel for
|
||||
You can frequently get away with using either <function>eqsel</function> or <function>neqsel</function> for
|
||||
operators that have very high or very low selectivity, even if they
|
||||
aren't really equality or inequality. For example, the
|
||||
approximate-equality geometric operators use eqsel on the assumption that
|
||||
approximate-equality geometric operators use <function>eqsel</function> on the assumption that
|
||||
they'll usually only match a small fraction of the entries in a table.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You can use scalarltsel and scalargtsel for comparisons on data types that
|
||||
You can use <function>scalarltsel</> and <function>scalargtsel</> for comparisons on data types that
|
||||
have some sensible means of being converted into numeric scalars for
|
||||
range comparisons. If possible, add the data type to those understood
|
||||
by the routine convert_to_scalar() in <filename>src/backend/utils/adt/selfuncs.c</filename>.
|
||||
by the routine <function>convert_to_scalar()</function> in <filename>src/backend/utils/adt/selfuncs.c</filename>.
|
||||
(Eventually, this routine should be replaced by per-data-type functions
|
||||
identified through a column of the pg_type table; but that hasn't happened
|
||||
identified through a column of the <classname>pg_type</> system catalog; but that hasn't happened
|
||||
yet.) If you do not do this, things will still work, but the optimizer's
|
||||
estimates won't be as good as they could be.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
There are additional selectivity functions designed for geometric
|
||||
operators in <filename>src/backend/utils/adt/geo_selfuncs.c</filename>: areasel, positionsel,
|
||||
and contsel. At this writing these are just stubs, but you may want
|
||||
operators in <filename>src/backend/utils/adt/geo_selfuncs.c</filename>: <function>areasel</function>, <function>positionsel</function>,
|
||||
and <function>contsel</function>. At this writing these are just stubs, but you may want
|
||||
to use them (or even better, improve them) anyway.
|
||||
</para>
|
||||
</sect2>
|
||||
@ -282,16 +288,16 @@ SELECT (a + b) AS c FROM test_complex;
|
||||
<title>JOIN</title>
|
||||
|
||||
<para>
|
||||
The JOIN clause, if provided, names a join selectivity
|
||||
The <literal>JOIN</> clause, if provided, names a join selectivity
|
||||
estimation function for the operator (note that this is a function
|
||||
name, not an operator name). JOIN clauses only make sense for
|
||||
binary operators that return boolean. The idea behind a join
|
||||
name, not an operator name). <literal>JOIN</> clauses only make sense for
|
||||
binary operators that return <type>boolean</type>. The idea behind a join
|
||||
selectivity estimator is to guess what fraction of the rows in a
|
||||
pair of tables will satisfy a WHERE-clause condition of the form
|
||||
<ProgramListing>
|
||||
table1.field1 OP table2.field2
|
||||
</ProgramListing>
|
||||
for the current operator. As with the RESTRICT clause, this helps
|
||||
pair of tables will satisfy a <literal>WHERE</>-clause condition of the form
|
||||
<ProgramListing>
|
||||
table1.column1 OP table2.column2
|
||||
</ProgramListing>
|
||||
for the current operator. As with the <literal>RESTRICT</literal> clause, this helps
|
||||
the optimizer very substantially by letting it figure out which
|
||||
of several possible join sequences is likely to take the least work.
|
||||
</para>
|
||||
@ -300,15 +306,15 @@ SELECT (a + b) AS c FROM test_complex;
|
||||
As before, this chapter will make no attempt to explain how to write
|
||||
a join selectivity estimator function, but will just suggest that
|
||||
you use one of the standard estimators if one is applicable:
|
||||
<ProgramListing>
|
||||
eqjoinsel for =
|
||||
neqjoinsel for <>
|
||||
scalarltjoinsel for < or <=
|
||||
scalargtjoinsel for > or >=
|
||||
areajoinsel for 2D area-based comparisons
|
||||
positionjoinsel for 2D position-based comparisons
|
||||
contjoinsel for 2D containment-based comparisons
|
||||
</ProgramListing>
|
||||
<simplelist>
|
||||
<member><function>eqjoinsel</> for <literal>=</></member>
|
||||
<member><function>neqjoinsel</> for <literal><></></member>
|
||||
<member><function>scalarltjoinsel</> for <literal><</> or <literal><=</></member>
|
||||
<member><function>scalargtjoinsel</> for <literal>></> or <literal>>=</></member>
|
||||
<member><function>areajoinsel</> for 2D area-based comparisons</member>
|
||||
<member><function>positionjoinsel</> for 2D position-based comparisons</member>
|
||||
<member><function>contjoinsel</> for 2D containment-based comparisons</member>
|
||||
</simplelist>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
@ -316,19 +322,19 @@ SELECT (a + b) AS c FROM test_complex;
|
||||
<title>HASHES</title>
|
||||
|
||||
<para>
|
||||
The HASHES clause, if present, tells the system that it is OK to
|
||||
use the hash join method for a join based on this operator. HASHES
|
||||
only makes sense for binary operators that return boolean, and
|
||||
The <literal>HASHES</literal> clause, if present, tells the system that it is OK to
|
||||
use the hash join method for a join based on this operator. <literal>HASHES</>
|
||||
only makes sense for binary operators that return <literal>boolean</>, and
|
||||
in practice the operator had better be equality for some data type.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The assumption underlying hash join is that the join operator can
|
||||
only return TRUE for pairs of left and right values that hash to the
|
||||
only return true for pairs of left and right values that hash to the
|
||||
same hash code. If two values get put in different hash buckets, the
|
||||
join will never compare them at all, implicitly assuming that the
|
||||
result of the join operator must be FALSE. So it never makes sense
|
||||
to specify HASHES for operators that do not represent equality.
|
||||
result of the join operator must be false. So it never makes sense
|
||||
to specify <literal>HASHES</literal> for operators that do not represent equality.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -353,18 +359,18 @@ SELECT (a + b) AS c FROM test_complex;
|
||||
There are also machine-dependent ways in which a hash join might fail
|
||||
to do the right thing. For example, if your data type
|
||||
is a structure in which there may be uninteresting pad bits, it's unsafe
|
||||
to mark the equality operator HASHES. (Unless, perhaps, you write
|
||||
to mark the equality operator <literal>HASHES</>. (Unless, perhaps, you write
|
||||
your other operators to ensure that the unused bits are always zero.)
|
||||
Another example is that the FLOAT data types are unsafe for hash
|
||||
joins. On machines that meet the <acronym>IEEE</> floating point standard, minus
|
||||
Another example is that the floating-point data types are unsafe for hash
|
||||
joins. On machines that meet the <acronym>IEEE</> floating-point standard, minus
|
||||
zero and plus zero are different values (different bit patterns) but
|
||||
they are defined to compare equal. So, if float equality were marked
|
||||
HASHES, a minus zero and a plus zero would probably not be matched up
|
||||
they are defined to compare equal. So, if the equality operator on floating-point data types were marked
|
||||
<literal>HASHES</>, a minus zero and a plus zero would probably not be matched up
|
||||
by a hash join, but they would be matched up by any other join process.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The bottom line is that you should probably only use HASHES for
|
||||
The bottom line is that you should probably only use <literal>HASHES</literal> for
|
||||
equality operators that are (or could be) implemented by <function>memcmp()</function>.
|
||||
</para>
|
||||
|
||||
@ -374,11 +380,11 @@ SELECT (a + b) AS c FROM test_complex;
|
||||
<title>SORT1 and SORT2</title>
|
||||
|
||||
<para>
|
||||
The SORT clauses, if present, tell the system that it is permissible to use
|
||||
The <literal>SORT</literal> clauses, if present, tell the system that it is permissible to use
|
||||
the merge join method for a join based on the current operator.
|
||||
Both must be specified if either is. The current operator must be
|
||||
equality for some pair of data types, and the SORT1 and SORT2 clauses
|
||||
name the ordering operator ('<' operator) for the left and right-side
|
||||
equality for some pair of data types, and the <literal>SORT1</> and <literal>SORT2</> clauses
|
||||
name the ordering operator (<quote><</quote> operator) for the left and right-side
|
||||
data types respectively.
|
||||
</para>
|
||||
|
||||
@ -388,29 +394,29 @@ SELECT (a + b) AS c FROM test_complex;
|
||||
be capable of being fully ordered, and the join operator must be one
|
||||
that can only succeed for pairs of values that fall at the <quote>same place</>
|
||||
in the sort order. In practice this means that the join operator must
|
||||
behave like equality. But unlike hashjoin, where the left and right
|
||||
behave like equality. But unlike hash join, where the left and right
|
||||
data types had better be the same (or at least bitwise equivalent),
|
||||
it is possible to mergejoin two
|
||||
it is possible to merge-join two
|
||||
distinct data types so long as they are logically compatible. For
|
||||
example, the int2-versus-int4 equality operator is mergejoinable.
|
||||
example, the <type>int2</type>-versus-<type>int4</type> equality operator is merge-joinable.
|
||||
We only need sorting operators that will bring both data types into a
|
||||
logically compatible sequence.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
When specifying merge sort operators, the current operator and both
|
||||
referenced operators must return boolean; the SORT1 operator must have
|
||||
both input data types equal to the current operator's left argument type,
|
||||
and the SORT2 operator must have
|
||||
both input data types equal to the current operator's right argument type.
|
||||
(As with COMMUTATOR and NEGATOR, this means that the operator name is
|
||||
When specifying merge-sort operators, the current operator and both
|
||||
referenced operators must return <type>boolean</type>; the <literal>SORT1</> operator must have
|
||||
both input data types equal to the current operator's left operand type,
|
||||
and the <literal>SORT2</> operator must have
|
||||
both input data types equal to the current operator's right operand type.
|
||||
(As with <literal>COMMUTATOR</> and <literal>NEGATOR</>, this means that the operator name is
|
||||
sufficient to specify the operator, and the system is able to make dummy
|
||||
operator entries if you happen to define the equality operator before
|
||||
the other ones.)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In practice you should only write SORT clauses for an <literal>=</> operator,
|
||||
In practice you should only write <literal>SORT</> clauses for an <literal>=</> operator,
|
||||
and the two referenced operators should always be named <literal><</>. Trying
|
||||
to use merge join with operators named anything else will result in
|
||||
hopeless confusion, for reasons we'll see in a moment.
|
||||
@ -418,14 +424,14 @@ SELECT (a + b) AS c FROM test_complex;
|
||||
|
||||
<para>
|
||||
There are additional restrictions on operators that you mark
|
||||
mergejoinable. These restrictions are not currently checked by
|
||||
CREATE OPERATOR, but a merge join may fail at runtime if any are
|
||||
merge-joinable. These restrictions are not currently checked by
|
||||
<command>CREATE OPERATOR</command>, but a merge join may fail at run time if any are
|
||||
not true:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
The mergejoinable equality operator must have a commutator
|
||||
The merge-joinable equality operator must have a commutator
|
||||
(itself if the two data types are the same, or a related equality operator
|
||||
if they are different).
|
||||
</para>
|
||||
@ -434,13 +440,13 @@ SELECT (a + b) AS c FROM test_complex;
|
||||
<listitem>
|
||||
<para>
|
||||
There must be <literal><</> and <literal>></> ordering operators having the same left and
|
||||
right input data types as the mergejoinable operator itself. These
|
||||
right operand data types as the merge-joinable operator itself. These
|
||||
operators <emphasis>must</emphasis> be named <literal><</> and <literal>></>; you do
|
||||
not have any choice in the matter, since there is no provision for
|
||||
specifying them explicitly. Note that if the left and right data types
|
||||
are different, neither of these operators is the same as either
|
||||
SORT operator. But they had better order the data values compatibly
|
||||
with the SORT operators, or mergejoin will fail to work.
|
||||
<literal>SORT</literal> operator. But they had better order the data values compatibly
|
||||
with the <literal>SORT</literal> operators, or the merge join will fail to work.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
@ -1,10 +1,13 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/xplang.sgml,v 1.16 2001/11/21 06:09:45 thomas Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/xplang.sgml,v 1.17 2002/01/07 02:29:14 petere Exp $
|
||||
-->
|
||||
|
||||
<chapter id="xplang">
|
||||
<title id="xplang-title">Procedural Languages</title>
|
||||
|
||||
<sect1 id="xplang-intro">
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>
|
||||
<productname>PostgreSQL</productname> allows users to add new
|
||||
programming languages to be available for writing functions and
|
||||
@ -23,11 +26,12 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xplang.sgml,v 1.16 2001/11/21 06:09:45 thom
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Writing a handler for a new procedural language is outside the
|
||||
scope of this manual, although some information is provided in
|
||||
the CREATE LANGUAGE reference page. Several procedural languages are
|
||||
available in the standard <productname>PostgreSQL</productname> distribution.
|
||||
Writing a handler for a new procedural language is described in
|
||||
<xref linkend="xfunc-plhandler">. Several procedural languages are
|
||||
available in the standard <productname>PostgreSQL</productname>
|
||||
distribution, which can serve as examples.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="xplang-install">
|
||||
<title>Installing Procedural Languages</title>
|
||||
@ -73,7 +77,7 @@ createlang plpgsql template1
|
||||
</para>
|
||||
</step>
|
||||
|
||||
<step performance="required">
|
||||
<step performance="required" id="xplang-install-cr1">
|
||||
<para>
|
||||
The handler must be declared with the command
|
||||
<synopsis>
|
||||
@ -88,43 +92,51 @@ CREATE FUNCTION <replaceable>handler_function_name</replaceable> ()
|
||||
</para>
|
||||
</step>
|
||||
|
||||
<step performance="required">
|
||||
<step performance="required" id="xplang-install-cr2">
|
||||
<para>
|
||||
The PL must be declared with the command
|
||||
<synopsis>
|
||||
CREATE <optional>TRUSTED</optional> <optional>PROCEDURAL</optional> LANGUAGE <replaceable>language-name</replaceable>
|
||||
HANDLER <replaceable>handler_function_name</replaceable>;
|
||||
</synopsis>
|
||||
The optional key word <token>TRUSTED</token> tells
|
||||
whether ordinary database users that have no superuser
|
||||
privileges should be allowed to use this language to create functions
|
||||
and trigger procedures. Since PL functions are
|
||||
executed inside the database backend, the <acronym>TRUSTED</acronym>
|
||||
flag should only be given for
|
||||
languages that do not allow access to database backends
|
||||
internals or the file system. The languages <application>PL/pgSQL</application>,
|
||||
<application>PL/Tcl</application>, and <application>PL/Perl</application> are known to be trusted; the language <application>PL/TclU</application>
|
||||
should <emphasis>not</emphasis> be marked trusted.
|
||||
The optional key word <literal>TRUSTED</literal> tells whether
|
||||
ordinary database users that have no superuser privileges should
|
||||
be allowed to use this language to create functions and trigger
|
||||
procedures. Since PL functions are executed inside the database
|
||||
server, the <literal>TRUSTED</literal> flag should only be given
|
||||
for languages that do not allow access to database server
|
||||
internals or the file system. The languages
|
||||
<application>PL/pgSQL</application>,
|
||||
<application>PL/Tcl</application>,
|
||||
<application>PL/Perl</application>, and
|
||||
<application>PL/Python</application> are known to be trusted;
|
||||
the languages <application>PL/TclU</application> and
|
||||
<application>PL/PerlU</application> are designed to provide
|
||||
unlimited functionality should <emphasis>not</emphasis> be
|
||||
marked trusted.
|
||||
</para>
|
||||
</step>
|
||||
</procedure>
|
||||
|
||||
<para>
|
||||
In a default <productname>PostgreSQL</productname> installation, the
|
||||
handler for the <application>PL/pgSQL</application> language is built and installed into the
|
||||
<quote>library</quote> directory. If Tcl/Tk support is configured
|
||||
in, the handlers for PL/Tcl and PL/TclU are also built and installed in
|
||||
the same location. Likewise, the PL/Perl handler is built and installed
|
||||
if Perl support is configured. The <filename>createlang</filename>
|
||||
script automates the two CREATE steps described above.
|
||||
In a default <productname>PostgreSQL</productname> installation,
|
||||
the handler for the <application>PL/pgSQL</application> language
|
||||
is built and installed into the <quote>library</quote>
|
||||
directory. If Tcl/Tk support is configured in, the handlers for
|
||||
PL/Tcl and PL/TclU are also built and installed in the same
|
||||
location. Likewise, the PL/Perl and PL/PerlU handlers are built
|
||||
and installed if Perl support is configured, and PL/Python is
|
||||
installed if Python support is configured. The
|
||||
<filename>createlang</filename> script automates <xref
|
||||
linkend="xplang-install-cr1"> and <xref
|
||||
linkend="xplang-install-cr2"> described above.
|
||||
</para>
|
||||
|
||||
<procedure>
|
||||
<title>Example</title>
|
||||
<example>
|
||||
<title>Manual Installation of <application>PL/pgSQL</application></title>
|
||||
|
||||
<step performance="required">
|
||||
<para>
|
||||
The following command tells the database where to find the
|
||||
The following command tells the database server where to find the
|
||||
shared object for the <application>PL/pgSQL</application> language's call handler function.
|
||||
|
||||
<programlisting>
|
||||
@ -132,9 +144,7 @@ CREATE FUNCTION plpgsql_call_handler () RETURNS OPAQUE AS
|
||||
'$libdir/plpgsql' LANGUAGE C;
|
||||
</programlisting>
|
||||
</para>
|
||||
</step>
|
||||
|
||||
<step performance="Required">
|
||||
<para>
|
||||
The command
|
||||
<programlisting>
|
||||
@ -145,8 +155,7 @@ CREATE TRUSTED PROCEDURAL LANGUAGE plpgsql
|
||||
should be invoked for functions and trigger procedures where the
|
||||
language attribute is <literal>plpgsql</literal>.
|
||||
</para>
|
||||
</step>
|
||||
</procedure>
|
||||
</example>
|
||||
|
||||
</sect1>
|
||||
|
||||
|
@ -6,55 +6,73 @@
|
||||
<secondary>extending</secondary>
|
||||
</indexterm>
|
||||
|
||||
<comment>
|
||||
This chapter needs to be updated for the version-1 function manager
|
||||
interface.
|
||||
</comment>
|
||||
|
||||
<para>
|
||||
As previously mentioned, there are two kinds of types
|
||||
in <productname>PostgreSQL</productname>: base types (defined in a programming language)
|
||||
and composite types.
|
||||
Examples in this section up to interfacing indexes can
|
||||
be found in <filename>complex.sql</filename> and <filename>complex.c</filename>. Composite examples
|
||||
are in <filename>funcs.sql</filename>.
|
||||
As previously mentioned, there are two kinds of types in
|
||||
<productname>PostgreSQL</productname>: base types (defined in a
|
||||
programming language) and composite types. This chapter describes
|
||||
how to define new base types.
|
||||
</para>
|
||||
|
||||
<sect1 id="xtypes-userdefined">
|
||||
<title>User-Defined Types</title>
|
||||
<para>
|
||||
The examples in this section can be found in
|
||||
<filename>complex.sql</filename> and <filename>complex.c</filename>
|
||||
in the tutorial directory. Composite examples are in
|
||||
<filename>funcs.sql</filename>.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>Functions Needed for a User-Defined Type</title>
|
||||
<para>
|
||||
A user-defined type must always have input and output
|
||||
functions. These functions determine how the type
|
||||
appears in strings (for input by the user and output to
|
||||
the user) and how the type is organized in memory. The
|
||||
input function takes a null-delimited character string
|
||||
as its input and returns the internal (in memory)
|
||||
representation of the type. The output function takes the
|
||||
internal representation of the type and returns a null
|
||||
delimited character string.
|
||||
Suppose we want to define a complex type which represents
|
||||
complex numbers. Naturally, we choose to represent a
|
||||
complex in memory as the following <acronym>C</acronym> structure:
|
||||
<para>
|
||||
<indexterm>
|
||||
<primary>input function</primary>
|
||||
</indexterm>
|
||||
<indexterm>
|
||||
<primary>output function</primary>
|
||||
</indexterm>
|
||||
A user-defined type must always have input and output functions.
|
||||
These functions determine how the type appears in strings (for input
|
||||
by the user and output to the user) and how the type is organized in
|
||||
memory. The input function takes a null-terminated character string
|
||||
as its input and returns the internal (in memory) representation of
|
||||
the type. The output function takes the internal representation of
|
||||
the type and returns a null-terminated character string.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
<para>
|
||||
Suppose we want to define a complex type which represents complex
|
||||
numbers. Naturally, we would choose to represent a complex in memory
|
||||
as the following <acronym>C</acronym> structure:
|
||||
|
||||
<programlisting>
|
||||
typedef struct Complex {
|
||||
double x;
|
||||
double y;
|
||||
} Complex;
|
||||
</programlisting>
|
||||
</programlisting>
|
||||
|
||||
and a string of the form (x,y) as the external string
|
||||
representation.
|
||||
These functions are usually not hard to write, especially
|
||||
the output function. However, there are a number of points
|
||||
to remember:
|
||||
and a string of the form <literal>(x,y)</literal> as the external string
|
||||
representation.
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para> When defining your external (string) representation,
|
||||
remember that you must eventually write a
|
||||
complete and robust parser for that representation
|
||||
as your input function!
|
||||
<para>
|
||||
The functions are usually not hard to write, especially the output
|
||||
function. However, there are a number of points to remember:
|
||||
|
||||
<programlisting>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
When defining your external (string) representation, remember
|
||||
that you must eventually write a complete and robust parser for
|
||||
that representation as your input function!
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For instance:
|
||||
|
||||
<programlisting>
|
||||
Complex *
|
||||
complex_in(char *str)
|
||||
{
|
||||
@ -69,11 +87,13 @@ complex_in(char *str)
|
||||
result->y = y;
|
||||
return (result);
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
The output function can simply be:
|
||||
<para>
|
||||
The output function can simply be:
|
||||
|
||||
<programlisting>
|
||||
<programlisting>
|
||||
char *
|
||||
complex_out(Complex *complex)
|
||||
{
|
||||
@ -84,30 +104,30 @@ complex_out(Complex *complex)
|
||||
sprintf(result, "(%g,%g)", complex->x, complex->y);
|
||||
return(result);
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
You should try to make the input and output
|
||||
functions inverses of each other. If you do
|
||||
not, you will have severe problems when you need
|
||||
to dump your data into a file and then read it
|
||||
back in (say, into someone else's database on
|
||||
another computer). This is a particularly common
|
||||
problem when floating-point numbers are
|
||||
involved.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
To define the <acronym>complex</acronym> type, we need to create the two
|
||||
user-defined functions complex_in and complex_out
|
||||
before creating the type:
|
||||
</listitem>
|
||||
|
||||
<programlisting>
|
||||
<listitem>
|
||||
<para>
|
||||
You should try to make the input and output functions inverses of
|
||||
each other. If you do not, you will have severe problems when
|
||||
you need to dump your data into a file and then read it back in
|
||||
(say, into someone else's database on another computer). This is
|
||||
a particularly common problem when floating-point numbers are
|
||||
involved.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To define the <type>complex</type> type, we need to create the two
|
||||
user-defined functions <function>complex_in</function> and
|
||||
<function>complex_out</function> before creating the type:
|
||||
|
||||
<programlisting>
|
||||
CREATE FUNCTION complex_in(opaque)
|
||||
RETURNS complex
|
||||
AS '<replaceable>PGROOT</replaceable>/tutorial/complex'
|
||||
@ -117,47 +137,57 @@ CREATE FUNCTION complex_out(opaque)
|
||||
RETURNS opaque
|
||||
AS '<replaceable>PGROOT</replaceable>/tutorial/complex'
|
||||
LANGUAGE C;
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Finally, we can declare the data type:
|
||||
<programlisting>
|
||||
CREATE TYPE complex (
|
||||
internallength = 16,
|
||||
input = complex_in,
|
||||
output = complex_out
|
||||
);
|
||||
</programlisting>
|
||||
</para>
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
As discussed earlier, <productname>PostgreSQL</productname> fully supports arrays of
|
||||
base types. Additionally, <productname>PostgreSQL</productname> supports arrays of
|
||||
user-defined types as well. When you define a type,
|
||||
<productname>PostgreSQL</productname> automatically provides support for arrays of
|
||||
that type. For historical reasons, the array type has
|
||||
the same name as the user-defined type with the
|
||||
underscore character _ prepended.
|
||||
Composite types do not need any function defined on
|
||||
them, since the system already understands what they
|
||||
look like inside.
|
||||
</para>
|
||||
</sect2>
|
||||
<para>
|
||||
<indexterm>
|
||||
<primary>arrays</primary>
|
||||
</indexterm>
|
||||
As discussed earlier, <productname>PostgreSQL</productname> fully
|
||||
supports arrays of base types. Additionally,
|
||||
<productname>PostgreSQL</productname> supports arrays of
|
||||
user-defined types as well. When you define a type,
|
||||
<productname>PostgreSQL</productname> automatically provides support
|
||||
for arrays of that type. For historical reasons, the array type has
|
||||
the same name as the user-defined type with the underscore character
|
||||
<literal>_</> prepended.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>Large Objects</title>
|
||||
<para>
|
||||
Composite types do not need any function defined on them, since the
|
||||
system already understands what they look like inside.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If the values of your datatype might exceed a few hundred bytes in
|
||||
size (in internal form), you should be careful to mark them TOASTable.
|
||||
To do this, the internal representation must follow the standard
|
||||
layout for variable-length data: the first four bytes must be an int32
|
||||
containing the total length in bytes of the datum (including itself).
|
||||
Then, all your functions that accept values of the type must be careful
|
||||
to call pg_detoast_datum() on the supplied values --- after checking
|
||||
that the value is not NULL, if your function is not strict. Finally,
|
||||
select the appropriate storage option when giving the CREATE TYPE
|
||||
command.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
<para>
|
||||
<indexterm>
|
||||
<primary>TOAST</primary>
|
||||
<secondary>and user-defined types</secondary>
|
||||
</indexterm>
|
||||
If the values of your datatype might exceed a few hundred bytes in
|
||||
size (in internal form), you should be careful to mark them
|
||||
TOAST-able. To do this, the internal representation must follow the
|
||||
standard layout for variable-length data: the first four bytes must
|
||||
be an <type>int32</type> containing the total length in bytes of the
|
||||
datum (including itself). Then, all your functions that accept
|
||||
values of the type must be careful to call
|
||||
<function>pg_detoast_datum()</function> on the supplied values ---
|
||||
after checking that the value is not NULL, if your function is not
|
||||
strict. Finally, select the appropriate storage option when giving
|
||||
the <command>CREATE TYPE</command> command.
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/error.c,v 1.14 2001/12/23 12:17:41 meskes Exp $ */
|
||||
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/error.c,v 1.15 2002/01/07 02:29:15 petere Exp $ */
|
||||
|
||||
#include "postgres_fe.h"
|
||||
|
||||
@ -54,7 +54,7 @@ ECPGraise(int line, int code, const char *str)
|
||||
|
||||
case ECPG_FLOAT_FORMAT:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Not correctly formatted floating point type: %s in line %d.", str, line);
|
||||
"Not correctly formatted floating-point type: %s in line %d.", str, line);
|
||||
break;
|
||||
|
||||
case ECPG_CONVERT_BOOL:
|
||||
|
Loading…
Reference in New Issue
Block a user