diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index b5c8bebae8ffe760888541df99bd772ae4f1fd8b..38eebd0967653591e640be44dbc9685964edc494 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -36,6 +36,8 @@ 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. @@ -45,7 +47,9 @@ -PGPORT sets the default port for communicating with the Postgres backend. +PGPORT sets the default port or local Unix domain socket +file extension for communicating with the Postgres +backend. @@ -71,6 +75,63 @@ + + +The following environment variables can be used to specify user-level default +behavior for every Postgres session: + + + + +PGDATESTYLE +sets the default style of date/time representation. + + + + +PGTZ +sets the default time zone. + + + + + + +The following environment variables can be used to specify default internal +behavior for every Postgres session: + + + + +PGGEQO +sets the default mode for the genetic optimizer. + + + + +PGRPLANS +sets the default mode to allow or disable right-sided plans in the optimizer. + + + + +PGCOSTHEAP +sets the default cost for heap searches for the optimizer. + + + + +PGCOSTINDEX +sets the default cost for indexed searches for the optimizer. + + + + + + +See the set(l) +man page for information on the arguments for these environment variables. + @@ -250,30 +311,6 @@ void PQreset(PGconn *conn) - - - -PQtrace - Enables tracing of messages passed between the - frontend and the backend. The messages are echoed - to the debug_port file stream. - -void PQtrace(PGconn *conn, - FILE* debug_port); - - - - - - -PQuntrace - Disables tracing of messages passed between the - frontend and the backend. - -void PQuntrace(PGconn *conn); - - - @@ -445,7 +482,7 @@ int PQgetisnull(PGresult *res, int field_num); This function returns 1 if the field contains a NULL, 0 if - it contains a known value.. + it contains a known value. @@ -597,8 +634,9 @@ want to block waiting for the response. -Since control is buried inside PQexec, there is no way for the frontend -to decide it would like to try to cancel the ongoing query. +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.) @@ -773,10 +811,13 @@ Note that if the current query is part of a transaction, cancellation will abort the whole transaction. -The current implementation of cancel requests uses "out of band" messages. -This feature is supported only on TCP/IP connections. If the backend -communication is being done through a Unix socket, PQrequestCancel will -always fail. +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. @@ -819,7 +860,7 @@ typedef struct { 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 - PQclear when it is not longer needed. + PQclear when it is no longer needed. @@ -966,6 +1007,10 @@ void PQputline(PGconn *conn, int PQendcopy(PGconn *conn); + + +As an example: + PQexec(conn, "create table foo (a int4, b char16, d float8)"); PQexec(conn, "copy foo from stdin"); @@ -1036,7 +1081,9 @@ void PQuntrace(PGconn *conn) (e.g., obtaining Kerberos tickets), the frontend/backend authentication process is handled by PQexec without any further intervention. - The following routines may be called by libpq programs to tailor the behavior of the authentication process. +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. @@ -1157,7 +1204,7 @@ void fe_setauthsvc(char *name, PQclear(res); /* fetch instances from the pg_database, the system catalog of databases*/ - res = PQexec(conn,"DECLARE myportal CURSOR FOR select * from pg_database"); + 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); @@ -1165,7 +1212,7 @@ void fe_setauthsvc(char *name, } PQclear(res); - res = PQexec(conn,"FETCH ALL in myportal"); + 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); @@ -1189,8 +1236,8 @@ void fe_setauthsvc(char *name, PQclear(res); - /* close the portal */ - res = PQexec(conn, "CLOSE myportal"); + /* close the cursor */ + res = PQexec(conn, "CLOSE mycursor"); PQclear(res); /* end the transaction */ @@ -1446,7 +1493,7 @@ void fe_setauthsvc(char *name, PQclear(res); - /* close the portal */ + /* close the cursor */ res = PQexec(conn, "CLOSE mycursor"); PQclear(res); diff --git a/src/man/libpq.3 b/src/man/libpq.3 index e89e5ebc01c3a685118ec92c09f8de91ef5c42bd..8afe20632ce8e828bfc48ebfc13c94193a2af3c2 100644 --- a/src/man/libpq.3 +++ b/src/man/libpq.3 @@ -1,11 +1,12 @@ .\" This is -*-nroff-*- .\" XXX standard disclaimer belongs here.... -.\" $Header: /cvsroot/pgsql/src/man/Attic/libpq.3,v 1.18 1998/07/04 17:50:04 momjian Exp $ -.TH LIBPQ INTRO 03/12/94 PostgreSQL PostgreSQL +.\" $Header: /cvsroot/pgsql/src/man/Attic/libpq.3,v 1.19 1998/07/09 03:30:49 scrappy Exp $ +.TH LIBPQ INTRO 07/08/98 PostgreSQL PostgreSQL .SH DESCRIPTION Libpq is the programmer's interface to Postgres. Libpq is a set of -library routines that allows queries to pass to the Postgres backend and -instances to return through an IPC channel. +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 @@ -222,13 +223,14 @@ void PQreset(PGconn *conn) .PP .B PQexec .IP -Submit a query to Postgres. Returns a PGresult pointer if the query was -successful or a NULL otherwise. If a NULL is returned, +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 -can be used to get more information about the error. +to get more information about the error. .nf PGresult *PQexec(PGconn *conn, - char *query); + const char *query); .fi The PGresult structure encapsulates the query result returned by the backend. Libpq programmers should be careful to maintain the PGresult @@ -243,7 +245,7 @@ Returns the result status of the query. can return one of the following values: .nf PGRES_EMPTY_QUERY, -PGRES_COMMAND_OK, /* the query was a command */ +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, @@ -263,14 +265,6 @@ returns the number of tuples (instances) in the query result. int PQntuples(PGresult *res); .fi -.B PQcmdTuples -returns the number of tuples (instances) affected by INSERT, UPDATE, and -DELETE queries. - -.nf -char *PQcmdTuples(PGresult *res); -.fi - .B PQnfields returns the number of fields (attributes) in the query result. .nf @@ -306,7 +300,16 @@ 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 -int2 PQfsize(PGresult *res, +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 +short PQfmod(PGresult *res, int field_index); .fi @@ -360,6 +363,16 @@ 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 @@ -409,6 +422,170 @@ 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 Postgres 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 @@ -458,7 +635,7 @@ 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 not longer needed. +when it is no longer needed. .PP .SH "Asynchronous Notification" .PP @@ -466,41 +643,50 @@ Postgres supports asynchronous notification via the .I LISTEN and .I NOTIFY -commands. A backend registers its interest in a particular relation -with the LISTEN command. All backends listening on a particular -relation will be notified asynchronously when a NOTIFY of that relation -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. +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 are notified whenever a connected backend has -received an asynchronous notification. However, the communication from -the backend to the frontend is not asynchronous. Notification comes -piggy-backed on other query results. Thus, an application must submit -queries, even empty ones, in order to receive notice of backend -notification. In effect, the Libpq application must poll the backend to -see if there is any pending notification information. After the -execution of a query, a frontend may call -.I PQNotifies -to see if any notification data is available from the backend. +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 notification from a list of unhandled notifications from the -backend. Returns NULL if there are no pending notifications from the -backend. -.I PQNotifies -behaves like the popping of a stack. Once a notification is returned -from -.I PQnotifies, -it is considered handled and will be removed from the list of -notifications. +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 @@ -511,6 +697,9 @@ 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 @@ -534,7 +723,7 @@ 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 characters \*(lq\\.\*(rq, which indicates that the backend +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 @@ -562,7 +751,8 @@ Sends a null-terminated .I string to the backend server. .IP -The application must explicitly send the characters \*(lq\\.\*(rq +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, @@ -595,6 +785,21 @@ PQputline(conn,"4goodbye world7.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 @@ -660,7 +865,7 @@ errorMessage argument. .SH "BUGS" .PP The query buffer is 8192 bytes long, and queries over that length will -be silently truncated. +be rejected. .PP .SH "Sample Programs" .bp @@ -883,21 +1088,19 @@ main() while (1) { - /* async notification only come back as a result of a query */ - /* we can send empty queries */ - res = PQexec(conn, ""); -/* printf("res->status = %s\\n", pgresStatus[PQresultStatus(res)]); */ - /* check for asynchronous returns */ - notify = PQnotifies(conn); - if (notify) - { + /* 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); - break; } - PQclear(res); } /* close the connection to the database and cleanup */