1334 lines
38 KiB
Groff
1334 lines
38 KiB
Groff
.\" This is -*-nroff-*-
|
|
.\" XXX standard disclaimer belongs here....
|
|
.\" $Header: /cvsroot/pgsql/src/man/Attic/libpq.3,v 1.25 1998/10/14 05:31:50 momjian Exp $
|
|
.TH LIBPQ INTRO 08/08/98 PostgreSQL PostgreSQL
|
|
.SH DESCRIPTION
|
|
Current documentation for this topic is available in the new Programmer's Guide
|
|
chapter on libpq.
|
|
This man page is obsolete, though in sync with the Programmer's Guide as of 1998/08/15.
|
|
.PP
|
|
Libpq is the programmer's interface to Postgres. Libpq is a set of
|
|
library routines which allows
|
|
client programs to pass queries to the Postgres backend
|
|
server and to receive the results of these queries.
|
|
.PP
|
|
This version of the documentation describes the C interface library.
|
|
Three short programs are included at the end of this section to show how
|
|
to write programs that use Libpq.
|
|
.PP
|
|
There are several examples of Libpq applications in the following
|
|
directories:
|
|
.nf
|
|
\&../src/test/regress
|
|
\&../src/test/examples
|
|
\&../src/bin/psql
|
|
.fi
|
|
.PP
|
|
Frontend programs which use Libpq must include the header file
|
|
.B "libpq-fe.h"
|
|
and must link with the
|
|
.B libpq
|
|
library.
|
|
.SH "Control and Initialization"
|
|
.PP
|
|
The following environment variables can be used to set up default
|
|
environment values to avoid hard-coding database names into
|
|
an application program:
|
|
.sp
|
|
\(bu
|
|
.B PGHOST
|
|
sets the default server name.
|
|
If it is set to a non-zero-length string, it causes TCP/IP
|
|
communication to be used, rather than the default local Unix domain sockets.
|
|
.sp
|
|
\(bu
|
|
.B PGUSER
|
|
sets the username used to connect to the database and for authentication.
|
|
.sp
|
|
\(bu
|
|
.B PGOPTIONS
|
|
sets additional runtime options for the Postgres backend.
|
|
.sp
|
|
\(bu
|
|
.B PGPORT
|
|
sets the default port or local Unix domain socket file extension
|
|
for communicating with the Postgres backend.
|
|
.sp
|
|
\(bu
|
|
.B PGTTY
|
|
sets the file or tty on which debugging messages from the backend server
|
|
are displayed.
|
|
.sp
|
|
\(bu
|
|
.B PGDATABASE
|
|
sets the default Postgres database name.
|
|
.sp
|
|
\(bu
|
|
.B PGREALM
|
|
sets the
|
|
.I Kerberos
|
|
realm to use with Postgres, if it is different from the local realm. If
|
|
.B PGREALM
|
|
is set, Postgres applications will attempt authentication with servers
|
|
for this realm and use separate ticket files to avoid conflicts with
|
|
local ticket files. This environment variable is only used if
|
|
.I Kerberos
|
|
authentication is enabled.
|
|
|
|
.PP
|
|
The following environment variables can be used to specify user-level default behavior
|
|
for every Postgres session:
|
|
.sp
|
|
\(bu
|
|
.B PGDATESTYLE
|
|
sets the default style of date/time representation.
|
|
.sp
|
|
\(bu
|
|
.B PGTZ
|
|
sets the default time zone.
|
|
|
|
.PP
|
|
The following environment variables can be used to specify default internal
|
|
behavior for every Postgres session:
|
|
.sp
|
|
\(bu
|
|
.B PGGEQO
|
|
sets the default mode for the genetic optimizer.
|
|
.sp
|
|
\(bu
|
|
.B PGRPLANS
|
|
sets the default mode to allow or disable right-sided plans in the optimizer.
|
|
.sp
|
|
\(bu
|
|
.B PGCOSTHEAP
|
|
sets the default cost for heap searches for the optimizer.
|
|
.sp
|
|
\(bu
|
|
.B PGCOSTINDEX
|
|
sets the default cost for indexed searches for the optimizer.
|
|
\(bu
|
|
.B PGQUERY_LIMIT
|
|
sets the maximum number of rows returned by a query.
|
|
.sp
|
|
|
|
.PP
|
|
See the
|
|
set(l)
|
|
man page for information on the arguments for these environment variables.
|
|
|
|
.SH "Database Connection Functions"
|
|
.PP
|
|
The following routines deal with making a connection to a backend
|
|
from a C program.
|
|
.PP
|
|
.B PQsetdb
|
|
.br
|
|
.B PQsetdbLogin
|
|
.IP
|
|
Makes a new connection to a backend.
|
|
.B PQsetdb
|
|
is the method usually used to
|
|
connect to the database when username/password authentication is not
|
|
needed.
|
|
.nf
|
|
PGconn *PQsetdb(char *pghost,
|
|
char *pgport,
|
|
char *pgoptions,
|
|
char *pgtty,
|
|
char *dbName);
|
|
.fi
|
|
|
|
.IP
|
|
.B PQsetdbLogin
|
|
is the method used to
|
|
connect to the database when username/password authentication is
|
|
needed.
|
|
.nf
|
|
PGconn *PQsetdbLogin(char *pghost,
|
|
char *pgport,
|
|
char *pgoptions,
|
|
char *pgtty,
|
|
char *dbName,
|
|
char *login,
|
|
char *pwd);
|
|
.fi
|
|
|
|
If any argument is NULL, then the corresponding environment variable
|
|
is checked. If the environment variable is also not set, then hardwired
|
|
defaults are used.
|
|
.IP
|
|
.I PQsetdb
|
|
and
|
|
.I PQsetdbLogin
|
|
always return a valid PGconn pointer. The
|
|
.I PQstatus
|
|
(see below) command should be called to ensure that a connection was
|
|
properly made before queries are sent via the connection. Libpq
|
|
programmers should be careful to maintain the PGconn abstraction. Use
|
|
the accessor functions below to get at the contents of PGconn. Avoid
|
|
directly referencing the fields of the PGconn structure as they are
|
|
subject to change in the future.
|
|
.IP
|
|
|
|
.B PQdb
|
|
returns the database name of the connection.
|
|
.nf
|
|
char *PQdb(PGconn *conn)
|
|
.fi
|
|
|
|
.B PQhost
|
|
returns the host name of the connection.
|
|
.nf
|
|
char *PQhost(PGconn *conn)
|
|
.fi
|
|
|
|
.B PQoptions
|
|
returns the pgoptions used in the connection.
|
|
.nf
|
|
char *PQoptions(PGconn *conn)
|
|
.fi
|
|
|
|
.B PQport
|
|
returns the pgport of the connection.
|
|
.nf
|
|
char *PQport(PGconn *conn)
|
|
.fi
|
|
|
|
.B PQtty
|
|
returns the pgtty of the connection.
|
|
.nf
|
|
char *PQtty(PGconn *conn)
|
|
.fi
|
|
|
|
.B PQstatus
|
|
Returns the status of the connection. The status can be CONNECTION_OK or
|
|
CONNECTION_BAD.
|
|
.nf
|
|
ConnStatusType *PQstatus(PGconn *conn)
|
|
.fi
|
|
|
|
.B PQerrorMessage
|
|
returns the error message associated with the connection
|
|
.nf
|
|
char *PQerrorMessage(PGconn* conn);
|
|
.fi
|
|
.PP
|
|
.B PQfinish
|
|
.IP
|
|
Close the connection to the backend. Also frees memory used by the
|
|
PGconn structure. The PGconn pointer should not be used after PQfinish
|
|
has been called.
|
|
.nf
|
|
void PQfinish(PGconn *conn)
|
|
.fi
|
|
.PP
|
|
.B PQreset
|
|
.IP
|
|
Reset the communication port with the backend. This function will close
|
|
the IPC socket connection to the backend and attempt to reestablish a
|
|
new connection to the same backend.
|
|
.nf
|
|
void PQreset(PGconn *conn)
|
|
.fi
|
|
.PP
|
|
.SH "Query Execution Functions"
|
|
.PP
|
|
.B PQexec
|
|
.IP
|
|
Submit a query to Postgres. Returns a PGresult
|
|
pointer or possibly a NULL pointer. If a NULL is returned, it
|
|
should be treated like a PGRES_FATAL_ERROR result: use
|
|
.I PQerrorMessage
|
|
to get more information about the error.
|
|
.nf
|
|
PGresult *PQexec(PGconn *conn,
|
|
const char *query);
|
|
.fi
|
|
The PGresult structure encapsulates the query result returned by the
|
|
backend. Libpq programmers should be careful to maintain the PGresult
|
|
abstraction. Use the accessor functions described below to retrieve the
|
|
results of the query. Avoid directly referencing the fields of the PGresult
|
|
structure as they are subject to change in the future.
|
|
.PP
|
|
.B PQresultStatus
|
|
.IP
|
|
Returns the result status of the query.
|
|
.I PQresultStatus
|
|
can return one of the following values:
|
|
.nf
|
|
PGRES_EMPTY_QUERY,
|
|
PGRES_COMMAND_OK, /* the query was a command returning no data */
|
|
PGRES_TUPLES_OK, /* the query successfully returned tuples */
|
|
PGRES_COPY_OUT,
|
|
PGRES_COPY_IN,
|
|
PGRES_BAD_RESPONSE, /* an unexpected response was received */
|
|
PGRES_NONFATAL_ERROR,
|
|
PGRES_FATAL_ERROR
|
|
.fi
|
|
.IP
|
|
If the result status is PGRES_TUPLES_OK, then the following routines can
|
|
be used to retrieve the tuples returned by the query.
|
|
.IP
|
|
|
|
.B PQntuples
|
|
returns the number of tuples (instances) in the query result.
|
|
|
|
.nf
|
|
int PQntuples(PGresult *res);
|
|
.fi
|
|
|
|
.B PQnfields
|
|
returns the number of fields (attributes) in the query result.
|
|
.nf
|
|
int PQnfields(PGresult *res);
|
|
.fi
|
|
|
|
.B PQfname
|
|
returns the field (attribute) name associated with the given field index.
|
|
Field indices start at 0.
|
|
.nf
|
|
char *PQfname(PGresult *res,
|
|
int field_index);
|
|
.fi
|
|
|
|
.B PQfnumber
|
|
returns the field (attribute) index associated with the given field name.
|
|
.nf
|
|
int PQfnumber(PGresult *res,
|
|
char* field_name);
|
|
.fi
|
|
|
|
.B PQftype
|
|
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.
|
|
.nf
|
|
Oid PQftype(PGresult *res,
|
|
int field_num);
|
|
.fi
|
|
|
|
.B PQfsize
|
|
returns the size in bytes of the field associated with the given field
|
|
index. If the size returned is -1, the field is a variable length field.
|
|
Field indices start at 0.
|
|
.nf
|
|
short PQfsize(PGresult *res,
|
|
int field_index);
|
|
.fi
|
|
|
|
.B PQfmod
|
|
returns the type-specific modification data of the field
|
|
associated with the given field index.
|
|
Field indices start at 0.
|
|
.nf
|
|
int PQfmod(PGresult *res,
|
|
int field_index);
|
|
.fi
|
|
|
|
.B PQgetvalue
|
|
returns the field (attribute) value. For most queries, the value
|
|
returned by
|
|
.I PQgetvalue
|
|
is a null-terminated ASCII string representation
|
|
of the attribute value. If the query was a result of a
|
|
.B BINARY
|
|
cursor, then the value returned by
|
|
.I PQgetvalue
|
|
is the binary representation of the type in the internal format of the
|
|
backend server. It is the programmer's responsibility to cast and
|
|
convert the data to the correct C type. The value returned by
|
|
.I PQgetvalue
|
|
points to storage that is part of the PGresult structure. One must
|
|
explicitly copy the value into other storage if it is to be used past
|
|
the lifetime of the PGresult structure itself.
|
|
.nf
|
|
char* PQgetvalue(PGresult *res,
|
|
int tup_num,
|
|
int field_num);
|
|
.fi
|
|
|
|
.B PQgetlength
|
|
returns the length of a field (attribute) in bytes. If the field
|
|
is a
|
|
.I "struct varlena" ,
|
|
the length returned here does
|
|
.B not
|
|
include the size field of the varlena, i.e., it is 4 bytes less.
|
|
.nf
|
|
int PQgetlength(PGresult *res,
|
|
int tup_num,
|
|
int field_num);
|
|
.fi
|
|
|
|
.B PQgetisnull
|
|
returns the NULL status of a field.
|
|
.nf
|
|
int PQgetisnull(PGresult *res,
|
|
int tup_num,
|
|
int field_num);
|
|
.fi
|
|
|
|
.PP
|
|
.B PQcmdStatus
|
|
.IP
|
|
Returns the command status associated with the last query command.
|
|
.nf
|
|
char *PQcmdStatus(PGresult *res);
|
|
.fi
|
|
|
|
.PP
|
|
.B PQcmdTuples
|
|
.IP
|
|
Returns the number of tuples (instances) affected by INSERT, UPDATE, and
|
|
DELETE queries.
|
|
.nf
|
|
char *PQcmdTuples(PGresult *res);
|
|
.fi
|
|
|
|
.PP
|
|
.B PQoidStatus
|
|
.IP
|
|
Returns a string with the object id of the tuple inserted if the last
|
|
query is an INSERT command. Otherwise, returns an empty string.
|
|
.nf
|
|
char* PQoidStatus(PGresult *res);
|
|
.fi
|
|
.PP
|
|
.B PQprint
|
|
.IP
|
|
+ Prints out all the tuples in an intelligent manner. The
|
|
.B psql
|
|
+ program uses this function for its output.
|
|
.nf
|
|
void PQprint(
|
|
FILE* fout, /* output stream */
|
|
PGresult* res, /* query results */
|
|
PQprintOpt *ps /* option structure */
|
|
);
|
|
|
|
.fi
|
|
.I PQprintOpt
|
|
is a typedef'ed structure as defined below.
|
|
.(C
|
|
typedef struct _PQprintOpt {
|
|
bool header; /* print table headings and row count */
|
|
bool align; /* fill align the fields */
|
|
bool standard; /* old brain dead format (needs align) */
|
|
bool html3; /* output html3+ tables */
|
|
bool expanded; /* expand tables */
|
|
bool pager; /* use pager if needed */
|
|
char *fieldSep; /* field separator */
|
|
char *caption; /* html table caption (or NULL) */
|
|
char **fieldName; /* null terminated array of field names (or NULL) */
|
|
} PQprintOpt;
|
|
.fi
|
|
.LP
|
|
.B PQclear
|
|
.IP
|
|
Frees the storage associated with the PGresult. Every query result
|
|
should be properly freed when it is no longer used. Failure to do this
|
|
will result in memory leaks in the frontend application. The PQresult*
|
|
passed in should be a value which is returned from PQexec(). Calling
|
|
PQclear() on an uninitialized PQresult pointer will very likely result
|
|
in a core dump.
|
|
.nf
|
|
void PQclear(PQresult *res);
|
|
.fi
|
|
|
|
.PP
|
|
.SH "Asynchronous Query Processing"
|
|
.PP
|
|
The PQexec function is adequate for submitting queries in simple synchronous
|
|
applications. It has a couple of major deficiencies however:
|
|
.IP
|
|
PQexec waits for the query 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.
|
|
.IP
|
|
Since control is buried inside PQexec, it is hard for the frontend
|
|
to decide it would like to try to cancel the ongoing query. (It can be
|
|
done from a signal handler, but not otherwise.)
|
|
.IP
|
|
PQexec can return only one PGresult structure. If the submitted query
|
|
string contains multiple SQL commands, all but the last PGresult are
|
|
discarded by PQexec.
|
|
|
|
.PP
|
|
Applications that do not like these limitations can instead use the
|
|
underlying functions that PQexec is built from: PQsendQuery and
|
|
PQgetResult.
|
|
|
|
.PP
|
|
.B PQsendQuery
|
|
.IP
|
|
Submit a query to Postgres without
|
|
waiting for the result(s). TRUE is returned if the query was
|
|
successfully dispatched, FALSE if not (in which case, use
|
|
PQerrorMessage to get more information about the failure).
|
|
.nf
|
|
int PQsendQuery(PGconn *conn,
|
|
const char *query);
|
|
.fi
|
|
After successfully calling PQsendQuery, call PQgetResult one or more
|
|
times to obtain the query results. PQsendQuery may not be called
|
|
again (on the same connection) until PQgetResult has returned NULL,
|
|
indicating that the query is done.
|
|
|
|
.PP
|
|
.B PQgetResult
|
|
.IP
|
|
Wait for the next result from a prior PQsendQuery,
|
|
and return it. NULL is returned when the query is complete
|
|
and there will be no more results.
|
|
.nf
|
|
PGresult *PQgetResult(PGconn *conn);
|
|
.fi
|
|
PQgetResult must be called repeatedly until it returns NULL,
|
|
indicating that the query is done. (If called when no query is
|
|
active, PQgetResult will just return NULL at once.)
|
|
Each non-null result from PQgetResult should be processed using
|
|
the same PGresult accessor functions previously described.
|
|
Don't forget to free each result object with PQclear when done with it.
|
|
Note that PQgetResult will block only if a query is active and the
|
|
necessary response data has not yet been read by PQconsumeInput.
|
|
|
|
.PP
|
|
Using PQsendQuery and PQgetResult solves one of PQexec's problems:
|
|
if a query string contains multiple SQL 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 PQgetResult will
|
|
still cause the frontend to block until the backend completes the
|
|
next SQL command. This can be avoided by proper use of three more
|
|
functions:
|
|
|
|
.PP
|
|
.B PQconsumeInput
|
|
.IP
|
|
If input is available from the backend, consume it.
|
|
.nf
|
|
void PQconsumeInput(PGconn *conn);
|
|
.fi
|
|
No direct return value is available from PQconsumeInput, but
|
|
after calling it, the application may check PQisBusy and/or
|
|
PQnotifies to see if their state has changed.
|
|
PQconsumeInput may be called even if the application is not
|
|
prepared to deal with a result or notification just yet.
|
|
It will read available data and save it in a buffer, thereby
|
|
causing a select(2) read-ready indication to go away. The
|
|
application can thus use PQconsumeInput to clear the select
|
|
condition immediately, and then examine the results at leisure.
|
|
|
|
.PP
|
|
.B PQisBusy
|
|
.IP
|
|
Returns TRUE if a query is busy, that is, PQgetResult would block
|
|
waiting for input. A FALSE return indicates that PQgetResult can
|
|
be called with assurance of not blocking.
|
|
.nf
|
|
int PQisBusy(PGconn *conn);
|
|
.fi
|
|
PQisBusy will not itself attempt to read data from the backend;
|
|
therefore PQconsumeInput must be invoked first, or the busy
|
|
state will never end.
|
|
|
|
.PP
|
|
.B PQsocket
|
|
.IP
|
|
Obtain the file descriptor number for the backend connection socket.
|
|
A valid descriptor will be >= 0; a result of -1 indicates that
|
|
no backend connection is currently open.
|
|
.nf
|
|
int PQsocket(PGconn *conn);
|
|
.fi
|
|
PQsocket should be used to obtain the backend socket descriptor
|
|
in preparation for executing select(2). This allows an application
|
|
to wait for either backend responses or other conditions.
|
|
If the result of select(2) indicates that data can be read from
|
|
the backend socket, then PQconsumeInput should be called to read the
|
|
data; after which, PQisBusy, PQgetResult, and/or PQnotifies can be
|
|
used to process the response.
|
|
|
|
.PP
|
|
A typical frontend using these functions will have a main loop that uses
|
|
select(2) to wait for all the conditions that it must respond to. One of
|
|
the conditions will be input available from the backend, which in select's
|
|
terms is readable data on the file descriptor identified by PQsocket.
|
|
When the main loop detects input ready, it should call PQconsumeInput
|
|
to read the input. It can then call PQisBusy, followed by PQgetResult
|
|
if PQisBusy returns FALSE. It can also call PQnotifies to detect NOTIFY
|
|
messages (see "Asynchronous Notification", below). An example is given
|
|
in the sample programs section.
|
|
|
|
.PP
|
|
A frontend that uses PQsendQuery/PQgetResult can also attempt to cancel
|
|
a query that is still being processed by the backend.
|
|
|
|
.PP
|
|
.B PQrequestCancel
|
|
.IP
|
|
Request that <ProductName>Postgres</ProductName> abandon
|
|
processing of the current query.
|
|
.nf
|
|
int PQrequestCancel(PGconn *conn);
|
|
.fi
|
|
The return value is TRUE if the cancel request was successfully
|
|
dispatched, FALSE if not. (If not, PQerrorMessage tells why not.)
|
|
Successful dispatch is no guarantee that the request will have any
|
|
effect, however. Regardless of the return value of PQrequestCancel,
|
|
the application must continue with the normal result-reading
|
|
sequence using PQgetResult. If the cancellation
|
|
is effective, the current query 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
|
|
be no visible result at all.
|
|
|
|
.PP
|
|
Note that if the current query is part of a transaction, cancellation
|
|
will abort the whole transaction.
|
|
|
|
.PP
|
|
PQrequestCancel can safely be invoked from a signal handler. So, it is
|
|
also possible to use it in conjunction with plain PQexec, if the decision
|
|
to cancel can be made in a signal handler. For example, psql invokes
|
|
PQrequestCancel from a SIGINT signal handler, thus allowing interactive
|
|
cancellation of queries that it issues through PQexec. Note that
|
|
PQrequestCancel will have no effect if the connection is not currently open
|
|
or the backend is not currently processing a query.
|
|
|
|
|
|
.PP
|
|
.SH "Fast Path"
|
|
.PP
|
|
Postgres provides a
|
|
.B "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.
|
|
.nf
|
|
PGresult* PQfn(PGconn* conn,
|
|
int fnid,
|
|
int *result_buf,
|
|
int *result_len,
|
|
int result_is_int,
|
|
PQArgBlock *args,
|
|
int nargs);
|
|
.fi
|
|
.PP
|
|
The
|
|
.I fnid
|
|
argument is the object identifier of the function to be executed.
|
|
.I result_buf
|
|
is the buffer in which to load the return value. The caller must have
|
|
allocated sufficient space to store the return value.
|
|
The result length will be returned in the storage pointed to by
|
|
.I result_len.
|
|
If the result is to be an integer value, than
|
|
.I result_is_int
|
|
should be set to 1; otherwise it should be set to 0.
|
|
.I args
|
|
and
|
|
.I nargs
|
|
specify the arguments to the function.
|
|
.nf
|
|
typedef struct {
|
|
int len;
|
|
int isint;
|
|
union {
|
|
int *ptr;
|
|
int integer;
|
|
} u;
|
|
} PQArgBlock;
|
|
.fi
|
|
.PP
|
|
.I PQfn
|
|
always returns a valid PGresult*. The resultStatus should be checked
|
|
before the result is used. The caller is responsible for freeing the
|
|
PGresult with
|
|
.I PQclear
|
|
when it is no longer needed.
|
|
.PP
|
|
.SH "Asynchronous Notification"
|
|
.PP
|
|
Postgres supports asynchronous notification via the
|
|
.I LISTEN
|
|
and
|
|
.I NOTIFY
|
|
commands. A backend registers its interest in a particular
|
|
notification condition with the LISTEN command. All backends listening on a
|
|
particular condition will be notified asynchronously when a NOTIFY of that
|
|
condition name is executed by any 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 database relation.
|
|
Commonly the condition name is the same as the associated relation, but it is
|
|
not necessary for there to be any associated relation.
|
|
.PP
|
|
libpq applications submit LISTEN commands as ordinary
|
|
SQL queries. Subsequently, arrival of NOTIFY messages can be detected by
|
|
calling PQnotifies().
|
|
.PP
|
|
.B PQNotifies
|
|
.IP
|
|
Returns the next notification from a list of unhandled
|
|
notification messages received from the backend. Returns NULL if
|
|
there are no pending notifications. PQnotifies behaves like the
|
|
popping of a stack. Once a notification is returned from
|
|
PQnotifies, it is considered handled and will be removed from the
|
|
list of notifications.
|
|
.nf
|
|
PGnotify* PQNotifies(PGconn *conn);
|
|
.fi
|
|
After processing a PGnotify object returned by PQnotifies,
|
|
be sure to free it with free() to avoid a memory leak.
|
|
.PP
|
|
The second sample program gives an example of the use of asynchronous
|
|
notification.
|
|
.PP
|
|
PQnotifies() does not actually read backend data; it just returns messages
|
|
previously absorbed by another libpq function. In prior
|
|
releases of libpq, the only way to ensure timely receipt
|
|
of NOTIFY messages was to constantly submit queries, even empty ones, and then
|
|
check PQnotifies() after each PQexec(). While this still works, it is
|
|
deprecated as a waste of processing power. A better way to check for NOTIFY
|
|
messages when you have no useful queries to make is to call PQconsumeInput(),
|
|
then check PQnotifies(). You can use select(2) to wait for backend data to
|
|
arrive, thereby using no CPU power unless there is something to do. Note that
|
|
this will work OK whether you use PQsendQuery/PQgetResult or plain old PQexec
|
|
for queries. You should, however, remember to check PQnotifies() after each
|
|
PQgetResult or PQexec to see if any notifications came in during the
|
|
processing of the query.
|
|
|
|
.PP
|
|
.SH "Functions Associated with the COPY Command"
|
|
.PP
|
|
The
|
|
.I copy
|
|
command in Postgres has options to read from or write to the network
|
|
connection used by Libpq. Therefore, functions are necessary to
|
|
access this network connection directly so applications may take full
|
|
advantage of this capability.
|
|
.PP
|
|
These functions should be executed only after obtaining a PGRES_COPY_OUT
|
|
or PGRES_COPY_IN result object from PQexec or PQgetResult.
|
|
.PP
|
|
.B PQgetline
|
|
.IP
|
|
Reads a newline-terminated line of characters (transmitted by the
|
|
backend server) into a buffer
|
|
.I string
|
|
of size
|
|
.I length .
|
|
Like
|
|
.I fgets(3),
|
|
this routine copies up to
|
|
.I length "-1"
|
|
characters into
|
|
.I string .
|
|
It is like
|
|
.I gets(3),
|
|
however, in that it converts the terminating newline into a null
|
|
character.
|
|
.IP
|
|
.I PQgetline
|
|
returns EOF at EOF, 0 if the entire line has been read, and 1 if the
|
|
buffer is full but the terminating newline has not yet been read.
|
|
.IP
|
|
Notice that the application must check to see if a new line consists
|
|
of the two characters \*(lq\\.\*(rq, which indicates that the backend
|
|
server has finished sending the results of the
|
|
.I copy
|
|
command. Therefore, if the application ever expects to receive lines
|
|
that are more than
|
|
.I length "-1"
|
|
characters long, the application must be sure to check the return
|
|
value of
|
|
.I PQgetline
|
|
very carefully.
|
|
.IP
|
|
The code in
|
|
.nf
|
|
\&../src/bin/psql/psql.c
|
|
.fi
|
|
contains routines that correctly handle the copy protocol.
|
|
.nf
|
|
int PQgetline(PGconn *conn,
|
|
char *string,
|
|
int length)
|
|
.fi
|
|
.PP
|
|
.B PQputline
|
|
.IP
|
|
Sends a null-terminated
|
|
.I string
|
|
to the backend server.
|
|
.IP
|
|
The application must explicitly send the two characters \*(lq\\.\*(rq
|
|
on a final line
|
|
to indicate to the backend that it has finished sending its data.
|
|
.nf
|
|
void PQputline(PGconn *conn,
|
|
char *string);
|
|
.fi
|
|
.PP
|
|
.B PQendcopy
|
|
.IP
|
|
Syncs 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
|
|
.I PQputline
|
|
or when the last string has been received from the backend using
|
|
.I PGgetline .
|
|
It must be issued or the backend may get \*(lqout of sync\*(rq with
|
|
the frontend. Upon return from this function, the backend is ready to
|
|
receive the next query.
|
|
.IP
|
|
The return value is 0 on successful completion, nonzero otherwise.
|
|
.nf
|
|
int PQendcopy(PGconn *conn);
|
|
.fi
|
|
As an example:
|
|
.nf
|
|
PQexec(conn, "create table foo (a int4, b name, d float8)");
|
|
PQexec(conn, "copy foo from stdin");
|
|
PQputline(conn, "3<TAB>hello world<TAB>4.5\en");
|
|
PQputline(conn,"4<TAB>goodbye world<TAB>7.11\en");
|
|
\&...
|
|
PQputline(conn,"\\.\en");
|
|
PQendcopy(conn);
|
|
.fi
|
|
.PP
|
|
When using PQgetResult, the application should respond to
|
|
a PGRES_COPY_OUT result by executing PQgetline repeatedly,
|
|
followed by PQendcopy after the terminator line is seen.
|
|
It should then return to the PQgetResult loop until PQgetResult
|
|
returns NULL. Similarly a PGRES_COPY_IN result is processed
|
|
by a series of PQputline calls followed by PQendcopy, then
|
|
return to the PQgetResult loop. This arrangement will ensure that
|
|
a copy in or copy out command embedded in a series of SQL commands
|
|
will be executed correctly.
|
|
Older applications are likely to submit a copy in or copy out
|
|
via PQexec and assume that the transaction is done after PQendcopy.
|
|
This will work correctly only if the copy in/out is the only
|
|
SQL command in the query string.
|
|
|
|
.PP
|
|
.SH "LIBPQ Tracing Functions"
|
|
.PP
|
|
.B PQtrace
|
|
.IP
|
|
Enable tracing of the frontend/backend communication to a debugging file
|
|
stream.
|
|
.nf
|
|
void PQtrace(PGconn *conn
|
|
FILE *debug_port)
|
|
.fi
|
|
.PP
|
|
.B PQuntrace
|
|
.IP
|
|
Disable tracing started by
|
|
.I PQtrace
|
|
.nf
|
|
void PQuntrace(PGconn *conn)
|
|
.fi
|
|
|
|
.PP
|
|
.SH "LIBPQ Control Functions"
|
|
.PP
|
|
.B PQsetNoticeProcessor
|
|
.IP
|
|
Control reporting of notice and warning messages generated by libpq.
|
|
.nf
|
|
void PQsetNoticeProcessor (PGconn * conn,
|
|
void (*noticeProcessor) (void * arg, const char * message),
|
|
void * arg)
|
|
.fi
|
|
By default, libpq prints "notice" messages from the backend on stderr,
|
|
as well as a few error messages that it generates by itself.
|
|
This behavior can be overridden by supplying a callback function that
|
|
does something else with the messages. The callback function is passed
|
|
the text of the error message (which includes a trailing newline), plus
|
|
a void pointer that is the same one passed to PQsetNoticeProcessor.
|
|
(This pointer can be used to access application-specific state if needed.)
|
|
The default notice processor is simply
|
|
.nf
|
|
static void
|
|
defaultNoticeProcessor(void * arg, const char * message)
|
|
{
|
|
fprintf(stderr, "%s", message);
|
|
}
|
|
.fi
|
|
To use a special notice processor, call PQsetNoticeProcessor just after
|
|
any creation of a new PGconn object.
|
|
|
|
.PP
|
|
.SH "User Authentication Functions"
|
|
.PP
|
|
If the user has generated the appropriate authentication credentials
|
|
(e.g., obtaining
|
|
.I Kerberos
|
|
tickets), the frontend/backend authentication process is handled by
|
|
.I PQexec
|
|
without any further intervention. The authentication method is now
|
|
determined entirely by the DBA (see pga_hba.conf(5)). The following
|
|
routines no longer have any effect and should not be used.
|
|
.PP
|
|
.B fe_getauthname
|
|
.IP
|
|
Returns a pointer to static space containing whatever name the user
|
|
has authenticated. Use of this routine in place of calls to
|
|
.I getenv(3)
|
|
or
|
|
.I getpwuid(3)
|
|
by applications is highly recommended, as it is entirely possible that
|
|
the authenticated user name is
|
|
.B not
|
|
the same as value of the
|
|
.B USER
|
|
environment variable or the user's entry in
|
|
.I /etc/passwd .
|
|
.nf
|
|
char *fe_getauthname(char* errorMessage)
|
|
.fi
|
|
.PP
|
|
.B fe_setauthsvc
|
|
.IP
|
|
Specifies that Libpq should use authentication service
|
|
.I name
|
|
rather than its compiled-in default. This value is typically taken
|
|
from a command-line switch.
|
|
.nf
|
|
void fe_setauthsvc(char *name,
|
|
char* errorMessage)
|
|
.fi
|
|
Any error messages from the authentication attempts are returned in the
|
|
errorMessage argument.
|
|
.PP
|
|
.SH "BUGS"
|
|
.PP
|
|
The query buffer is 8192 bytes long, and queries over that length will
|
|
be rejected.
|
|
.PP
|
|
.SH "Sample Programs"
|
|
.bp
|
|
.SH "Sample Program 1"
|
|
.PP
|
|
.nf M
|
|
/*
|
|
* testlibpq.c
|
|
* Test the C version of Libpq, the Postgres frontend library.
|
|
*
|
|
*
|
|
*/
|
|
#include <stdio.h>
|
|
#include "libpq-fe.h"
|
|
|
|
void
|
|
exit_nicely(PGconn *conn)
|
|
{
|
|
PQfinish(conn);
|
|
exit(1);
|
|
}
|
|
|
|
main()
|
|
{
|
|
char *pghost,
|
|
*pgport,
|
|
*pgoptions,
|
|
*pgtty;
|
|
char *dbName;
|
|
int nFields;
|
|
int i,
|
|
j;
|
|
|
|
/* FILE *debug; */
|
|
|
|
PGconn *conn;
|
|
PGresult *res;
|
|
|
|
/*
|
|
* begin, by setting the parameters for a backend connection if the
|
|
* parameters are null, then the system will try to use reasonable
|
|
* defaults by looking up environment variables or, failing that,
|
|
* using hardwired constants
|
|
*/
|
|
pghost = NULL; /* host name of the backend server */
|
|
pgport = NULL; /* port of the backend server */
|
|
pgoptions = NULL; /* special options to start up the backend
|
|
* server */
|
|
pgtty = NULL; /* debugging tty for the backend server */
|
|
dbName = "template1";
|
|
|
|
/* make a connection to the database */
|
|
conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
|
|
|
|
/* check to see that the backend connection was successfully made */
|
|
if (PQstatus(conn) == CONNECTION_BAD)
|
|
{
|
|
fprintf(stderr, "Connection to database '%s' failed.\\n", dbName);
|
|
fprintf(stderr, "%s", PQerrorMessage(conn));
|
|
exit_nicely(conn);
|
|
}
|
|
|
|
/* debug = fopen("/tmp/trace.out","w"); */
|
|
/* PQtrace(conn, debug); */
|
|
|
|
/* start a transaction block */
|
|
res = PQexec(conn, "BEGIN");
|
|
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
|
{
|
|
fprintf(stderr, "BEGIN command failed\\n");
|
|
PQclear(res);
|
|
exit_nicely(conn);
|
|
}
|
|
|
|
/*
|
|
* should PQclear PGresult whenever it is no longer needed to avoid
|
|
* memory leaks
|
|
*/
|
|
PQclear(res);
|
|
|
|
/*
|
|
* fetch instances from the pg_database, the system catalog of
|
|
* databases
|
|
*/
|
|
res = PQexec(conn, "DECLARE mycursor CURSOR FOR select * from pg_database");
|
|
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
|
{
|
|
fprintf(stderr, "DECLARE CURSOR command failed\\n");
|
|
PQclear(res);
|
|
exit_nicely(conn);
|
|
}
|
|
PQclear(res);
|
|
|
|
res = PQexec(conn, "FETCH ALL in mycursor");
|
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
|
{
|
|
fprintf(stderr, "FETCH ALL command didn't return tuples properly\\n");
|
|
PQclear(res);
|
|
exit_nicely(conn);
|
|
}
|
|
|
|
/* first, print out the attribute names */
|
|
nFields = PQnfields(res);
|
|
for (i = 0; i < nFields; i++)
|
|
printf("%-15s", PQfname(res, i));
|
|
printf("\\n\\n");
|
|
|
|
/* next, print out the instances */
|
|
for (i = 0; i < PQntuples(res); i++)
|
|
{
|
|
for (j = 0; j < nFields; j++)
|
|
printf("%-15s", PQgetvalue(res, i, j));
|
|
printf("\\n");
|
|
}
|
|
|
|
PQclear(res);
|
|
|
|
/* close the cursor */
|
|
res = PQexec(conn, "CLOSE mycursor");
|
|
PQclear(res);
|
|
|
|
/* commit the transaction */
|
|
res = PQexec(conn, "COMMIT");
|
|
PQclear(res);
|
|
|
|
/* close the connection to the database and cleanup */
|
|
PQfinish(conn);
|
|
|
|
/* fclose(debug); */
|
|
}
|
|
|
|
.fi
|
|
.bp
|
|
.SH "Sample Program 2"
|
|
.PP
|
|
.nf M
|
|
/*
|
|
* testlibpq2.c
|
|
* Test of the asynchronous notification interface
|
|
*
|
|
populate a database with the following:
|
|
|
|
CREATE TABLE TBL1 (i int4);
|
|
|
|
CREATE TABLE TBL2 (i int4);
|
|
|
|
CREATE RULE r1 AS ON INSERT TO TBL1 DO [INSERT INTO TBL2 values (new.i); NOTIFY TBL2];
|
|
|
|
* Then start up this program
|
|
* After the program has begun, do
|
|
|
|
INSERT INTO TBL1 values (10);
|
|
|
|
*
|
|
*
|
|
*/
|
|
#include <stdio.h>
|
|
#include "libpq-fe.h"
|
|
|
|
void
|
|
exit_nicely(PGconn *conn)
|
|
{
|
|
PQfinish(conn);
|
|
exit(1);
|
|
}
|
|
|
|
main()
|
|
{
|
|
char *pghost,
|
|
*pgport,
|
|
*pgoptions,
|
|
*pgtty;
|
|
char *dbName;
|
|
int nFields;
|
|
int i,
|
|
j;
|
|
|
|
PGconn *conn;
|
|
PGresult *res;
|
|
PGnotify *notify;
|
|
|
|
/*
|
|
* begin, by setting the parameters for a backend connection if the
|
|
* parameters are null, then the system will try to use reasonable
|
|
* defaults by looking up environment variables or, failing that,
|
|
* using hardwired constants
|
|
*/
|
|
pghost = NULL; /* host name of the backend server */
|
|
pgport = NULL; /* port of the backend server */
|
|
pgoptions = NULL; /* special options to start up the backend
|
|
* server */
|
|
pgtty = NULL; /* debugging tty for the backend server */
|
|
dbName = getenv("USER"); /* change this to the name of your test
|
|
* database */
|
|
|
|
/* make a connection to the database */
|
|
conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
|
|
|
|
/* check to see that the backend connection was successfully made */
|
|
if (PQstatus(conn) == CONNECTION_BAD)
|
|
{
|
|
fprintf(stderr, "Connection to database '%s' failed.\\n", dbName);
|
|
fprintf(stderr, "%s", PQerrorMessage(conn));
|
|
exit_nicely(conn);
|
|
}
|
|
|
|
res = PQexec(conn, "LISTEN TBL2");
|
|
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
|
{
|
|
fprintf(stderr, "LISTEN command failed\\n");
|
|
PQclear(res);
|
|
exit_nicely(conn);
|
|
}
|
|
|
|
/*
|
|
* should PQclear PGresult whenever it is no longer needed to avoid
|
|
* memory leaks
|
|
*/
|
|
PQclear(res);
|
|
|
|
while (1)
|
|
{
|
|
/* wait a little bit between checks;
|
|
* waiting with select() would be more efficient.
|
|
*/
|
|
sleep(1);
|
|
/* collect any asynchronous backend messages */
|
|
PQconsumeInput(conn);
|
|
/* check for asynchronous notify messages */
|
|
while ((notify = PQnotifies(conn)) != NULL) {
|
|
fprintf(stderr,
|
|
"ASYNC NOTIFY of '%s' from backend pid '%d' received\\n",
|
|
notify->relname, notify->be_pid);
|
|
free(notify);
|
|
}
|
|
}
|
|
|
|
/* close the connection to the database and cleanup */
|
|
PQfinish(conn);
|
|
|
|
}
|
|
|
|
.fi
|
|
.bp
|
|
.SH "Sample Program 3"
|
|
.PP
|
|
.nf M
|
|
/*
|
|
* testlibpq3.c
|
|
* Test the C version of Libpq, the Postgres frontend library.
|
|
* tests the binary cursor interface
|
|
*
|
|
*
|
|
*
|
|
populate a database by doing the following:
|
|
|
|
CREATE TABLE test1 (i int4, d float4, p polygon);
|
|
|
|
INSERT INTO test1 values (1, 3.567, '(3.0, 4.0, 1.0, 2.0)'::polygon);
|
|
|
|
INSERT INTO test1 values (2, 89.05, '(4.0, 3.0, 2.0, 1.0)'::polygon);
|
|
|
|
the expected output is:
|
|
|
|
tuple 0: got
|
|
i = (4 bytes) 1,
|
|
d = (4 bytes) 3.567000,
|
|
p = (4 bytes) 2 points boundbox = (hi=3.000000/4.000000, lo = 1.000000,2.000000)
|
|
tuple 1: got
|
|
i = (4 bytes) 2,
|
|
d = (4 bytes) 89.050003,
|
|
p = (4 bytes) 2 points boundbox = (hi=4.000000/3.000000, lo = 2.000000,1.000000)
|
|
|
|
*
|
|
*/
|
|
#include <stdio.h>
|
|
#include "libpq-fe.h"
|
|
#include "utils/geo-decls.h" /* for the POLYGON type */
|
|
|
|
void
|
|
exit_nicely(PGconn *conn)
|
|
{
|
|
PQfinish(conn);
|
|
exit(1);
|
|
}
|
|
|
|
main()
|
|
{
|
|
char *pghost,
|
|
*pgport,
|
|
*pgoptions,
|
|
*pgtty;
|
|
char *dbName;
|
|
int nFields;
|
|
int i,
|
|
j;
|
|
int i_fnum,
|
|
d_fnum,
|
|
p_fnum;
|
|
|
|
PGconn *conn;
|
|
PGresult *res;
|
|
|
|
/*
|
|
* begin, by setting the parameters for a backend connection if the
|
|
* parameters are null, then the system will try to use reasonable
|
|
* defaults by looking up environment variables or, failing that,
|
|
* using hardwired constants
|
|
*/
|
|
pghost = NULL; /* host name of the backend server */
|
|
pgport = NULL; /* port of the backend server */
|
|
pgoptions = NULL; /* special options to start up the backend
|
|
* server */
|
|
pgtty = NULL; /* debugging tty for the backend server */
|
|
|
|
dbName = getenv("USER"); /* change this to the name of your test
|
|
* database */
|
|
|
|
/* make a connection to the database */
|
|
conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
|
|
|
|
/* check to see that the backend connection was successfully made */
|
|
if (PQstatus(conn) == CONNECTION_BAD)
|
|
{
|
|
fprintf(stderr, "Connection to database '%s' failed.\\n", dbName);
|
|
fprintf(stderr, "%s", PQerrorMessage(conn));
|
|
exit_nicely(conn);
|
|
}
|
|
|
|
/* start a transaction block */
|
|
res = PQexec(conn, "BEGIN");
|
|
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
|
{
|
|
fprintf(stderr, "BEGIN command failed\\n");
|
|
PQclear(res);
|
|
exit_nicely(conn);
|
|
}
|
|
|
|
/*
|
|
* should PQclear PGresult whenever it is no longer needed to avoid
|
|
* memory leaks
|
|
*/
|
|
PQclear(res);
|
|
|
|
/*
|
|
* fetch instances from the pg_database, the system catalog of
|
|
* databases
|
|
*/
|
|
res = PQexec(conn, "DECLARE mycursor BINARY CURSOR FOR select * from test1");
|
|
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
|
{
|
|
fprintf(stderr, "DECLARE CURSOR command failed\\n");
|
|
PQclear(res);
|
|
exit_nicely(conn);
|
|
}
|
|
PQclear(res);
|
|
|
|
res = PQexec(conn, "FETCH ALL in mycursor");
|
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
|
{
|
|
fprintf(stderr, "FETCH ALL command didn't return tuples properly\\n");
|
|
PQclear(res);
|
|
exit_nicely(conn);
|
|
}
|
|
|
|
i_fnum = PQfnumber(res, "i");
|
|
d_fnum = PQfnumber(res, "d");
|
|
p_fnum = PQfnumber(res, "p");
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
printf("type[%d] = %d, size[%d] = %d\\n",
|
|
i, PQftype(res, i),
|
|
i, PQfsize(res, i));
|
|
}
|
|
for (i = 0; i < PQntuples(res); i++)
|
|
{
|
|
int *ival;
|
|
float *dval;
|
|
int plen;
|
|
POLYGON *pval;
|
|
|
|
/* we hard-wire this to the 3 fields we know about */
|
|
ival = (int *) PQgetvalue(res, i, i_fnum);
|
|
dval = (float *) PQgetvalue(res, i, d_fnum);
|
|
plen = PQgetlength(res, i, p_fnum);
|
|
|
|
/*
|
|
* plen doesn't include the length field so need to increment by
|
|
* VARHDSZ
|
|
*/
|
|
pval = (POLYGON *) malloc(plen + VARHDRSZ);
|
|
pval->size = plen;
|
|
memmove((char *) &pval->npts, PQgetvalue(res, i, p_fnum), plen);
|
|
printf("tuple %d: got\\n", i);
|
|
printf(" i = (%d bytes) %d,\\n",
|
|
PQgetlength(res, i, i_fnum), *ival);
|
|
printf(" d = (%d bytes) %f,\\n",
|
|
PQgetlength(res, i, d_fnum), *dval);
|
|
printf(" p = (%d bytes) %d points \\tboundbox = (hi=%f/%f, lo = %f,%f)\\n",
|
|
PQgetlength(res, i, d_fnum),
|
|
pval->npts,
|
|
pval->boundbox.xh,
|
|
pval->boundbox.yh,
|
|
pval->boundbox.xl,
|
|
pval->boundbox.yl);
|
|
}
|
|
|
|
PQclear(res);
|
|
|
|
/* close the cursor */
|
|
res = PQexec(conn, "CLOSE mycursor");
|
|
PQclear(res);
|
|
|
|
/* commit the transaction */
|
|
res = PQexec(conn, "COMMIT");
|
|
PQclear(res);
|
|
|
|
/* close the connection to the database and cleanup */
|
|
PQfinish(conn);
|
|
|
|
}
|
|
.fi
|