Allow PQcmdTuples to return row counts for MOVE and FETCH.
Neil Conway
This commit is contained in:
parent
1eb9fd49d1
commit
81f6db4803
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.110 2003/02/14 02:21:25 momjian Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.111 2003/02/19 03:59:02 momjian Exp $
|
||||
-->
|
||||
|
||||
<chapter id="libpq">
|
||||
@ -702,12 +702,11 @@ char *PQerrorMessage(const PGconn* conn);
|
||||
int PQbackendPID(const PGconn *conn);
|
||||
</synopsis>
|
||||
The backend <acronym>PID</acronym> is useful for debugging
|
||||
purposes and for comparison
|
||||
to NOTIFY messages (which include the <acronym>PID</acronym> of
|
||||
the notifying backend).
|
||||
Note that the <acronym>PID</acronym> belongs to a process
|
||||
executing on the database
|
||||
server host, not the local host!
|
||||
purposes and for comparison to <command>NOTIFY</command>
|
||||
messages (which include the <acronym>PID</acronym> of the
|
||||
notifying backend). Note that the <acronym>PID</acronym>
|
||||
belongs to a process executing on the database server host, not
|
||||
the local host!
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
@ -818,13 +817,14 @@ ExecStatusType PQresultStatus(const PGresult *res)
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
If the result status is <literal>PGRES_TUPLES_OK</literal>, then the
|
||||
routines described below can be used to retrieve the
|
||||
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.
|
||||
If the result status is <literal>PGRES_TUPLES_OK</literal>, then the
|
||||
routines described below can be used to retrieve the rows returned by
|
||||
the query. Note that a <command>SELECT</command> command that happens
|
||||
to retrieve zero rows still shows <literal>PGRES_TUPLES_OK</literal>.
|
||||
<literal>PGRES_COMMAND_OK</literal> is for commands that can never
|
||||
return rows (<command>INSERT</command>, <command>UPDATE</command>,
|
||||
etc.). A response of <literal>PGRES_EMPTY_QUERY</literal> often
|
||||
indicates a bug in the client software.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
@ -1243,36 +1243,41 @@ char * PQcmdStatus(PGresult *res);
|
||||
char * PQcmdTuples(PGresult *res);
|
||||
</synopsis>
|
||||
If the <acronym>SQL</acronym> command that generated the
|
||||
<structname>PGresult</structname> was INSERT, UPDATE or DELETE, this returns a
|
||||
string containing the number of rows affected. If the
|
||||
command was anything else, it returns the empty string.
|
||||
<structname>PGresult</structname> was <command>INSERT</command>,
|
||||
<command>UPDATE</command>, <command>DELETE</command>,
|
||||
<command>MOVE</command>, or <command>FETCH</command> this
|
||||
returns a string containing the number of rows affected. If the
|
||||
command was anything else, it returns the empty string.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PQoidValue</function>
|
||||
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>.
|
||||
Returns the object ID of the inserted row, if the
|
||||
<acronym>SQL</acronym> command was an <command>INSERT</command>
|
||||
that inserted exactly one row into a table that has OIDs.
|
||||
Otherwise, returns <literal>InvalidOid</literal>.
|
||||
<synopsis>
|
||||
Oid PQoidValue(const PGresult *res);
|
||||
</synopsis>
|
||||
The type <type>Oid</type> and the constant <literal>InvalidOid</literal>
|
||||
will be defined if you include the <application>libpq</application>
|
||||
header file. They will both be some integer type.
|
||||
The type <type>Oid</type> and the constant
|
||||
<literal>InvalidOid</literal> will be defined if you include the
|
||||
<application>libpq</application> header file. They will both be
|
||||
some integer type.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>PQoidStatus</function>
|
||||
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
|
||||
was not an INSERT, returns an empty string.
|
||||
Returns a string with the object ID
|
||||
of the inserted row, if the <acronym>SQL</acronym> command
|
||||
was an <command>INSERT</command>. (The string will be
|
||||
<literal>0</> if the <command>INSERT</command> did not
|
||||
insert exactly one row, or if the target table does not have
|
||||
OIDs.) If the command was not an <command>INSERT</command>,
|
||||
returns an empty string.
|
||||
<synopsis>
|
||||
char * PQoidStatus(const PGresult *res);
|
||||
</synopsis>
|
||||
@ -1530,7 +1535,8 @@ When the main loop detects input ready, it should call
|
||||
<function>PQconsumeInput</function> to read the input. It can then call
|
||||
<function>PQisBusy</function>, followed by <function>PQgetResult</function>
|
||||
if <function>PQisBusy</function> returns false (0). It can also call
|
||||
<function>PQnotifies</function> to detect NOTIFY messages (see <xref linkend="libpq-notify">).
|
||||
<function>PQnotifies</function> to detect <command>NOTIFY</command>
|
||||
messages (see <xref linkend="libpq-notify">).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -1700,13 +1706,13 @@ of asynchronous notification.
|
||||
<function>PQnotifies()</function> does not actually read backend data; it just
|
||||
returns messages previously absorbed by another <application>libpq</application>
|
||||
function. In prior releases of <application>libpq</application>, the only way
|
||||
to ensure timely receipt of NOTIFY messages was to constantly submit queries,
|
||||
to ensure timely receipt of <command>NOTIFY</command> messages was to constantly submit queries,
|
||||
even empty ones, and then check <function>PQnotifies()</function> after each
|
||||
<function>PQexec()</function>. While this still works, it is
|
||||
deprecated as a waste of processing power.
|
||||
</para>
|
||||
<para>
|
||||
A better way to check for NOTIFY
|
||||
A better way to check for <command>NOTIFY</command>
|
||||
messages when you have no useful queries to make is to call
|
||||
<function>PQconsumeInput()</function>, then check
|
||||
<function>PQnotifies()</function>.
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/protocol.sgml,v 1.24 2002/03/22 19:20:21 petere Exp $ -->
|
||||
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/protocol.sgml,v 1.25 2003/02/19 03:59:02 momjian Exp $ -->
|
||||
|
||||
<chapter id="protocol">
|
||||
<title>Frontend/Backend Protocol</title>
|
||||
@ -1335,6 +1335,20 @@ CompletedResponse (B)
|
||||
<literal>UPDATE <Replaceable>rows</Replaceable></literal> where
|
||||
<Replaceable>rows</Replaceable> is the number of rows updated.
|
||||
</Para>
|
||||
|
||||
<para>
|
||||
For a <command>MOVE</command> command, the tag is
|
||||
<literal>MOVE <replaceable>rows</replaceable></literal> where
|
||||
<replaceable>rows</replaceable> is the number of rows the
|
||||
cursor's position has been changed by.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For a <command>FETCH</command> command, the tag is
|
||||
<literal>FETCH <replaceable>rows</replaceable></literal> where
|
||||
<replaceable>rows</replaceable> is the number of rows that
|
||||
have been retrieved from the cursor.
|
||||
</para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
</VariableList>
|
||||
|
@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.192 2003/02/13 05:20:01 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.193 2003/02/19 03:59:02 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -254,7 +254,7 @@ ProcessUtility(Node *parsetree,
|
||||
switch (nodeTag(parsetree))
|
||||
{
|
||||
/*
|
||||
* ******************************** transactions ********************************
|
||||
* ******************** transactions ********************
|
||||
*/
|
||||
case T_TransactionStmt:
|
||||
{
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.124 2003/01/07 22:23:17 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.125 2003/02/19 03:59:02 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -2272,7 +2272,7 @@ PQoidStatus(const PGresult *res)
|
||||
|
||||
/*
|
||||
PQoidValue -
|
||||
a perhaps preferable form of the above which just returns
|
||||
a perhaps preferable form of the above which just returns
|
||||
an Oid type
|
||||
*/
|
||||
Oid
|
||||
@ -2300,53 +2300,54 @@ PQoidValue(const PGresult *res)
|
||||
|
||||
/*
|
||||
PQcmdTuples -
|
||||
if the last command was an INSERT/UPDATE/DELETE, return number
|
||||
of inserted/affected tuples, if not, return ""
|
||||
If the last command was an INSERT/UPDATE/DELETE/MOVE/FETCH, return a
|
||||
string containing the number of inserted/affected tuples. If not,
|
||||
return "".
|
||||
|
||||
XXX: this should probably return an int
|
||||
*/
|
||||
char *
|
||||
PQcmdTuples(PGresult *res)
|
||||
{
|
||||
char noticeBuf[128];
|
||||
char *p;
|
||||
|
||||
if (!res)
|
||||
return "";
|
||||
|
||||
if (strncmp(res->cmdStatus, "INSERT", 6) == 0 ||
|
||||
strncmp(res->cmdStatus, "DELETE", 6) == 0 ||
|
||||
strncmp(res->cmdStatus, "UPDATE", 6) == 0)
|
||||
if (strncmp(res->cmdStatus, "INSERT ", 7) == 0)
|
||||
{
|
||||
char *p = res->cmdStatus + 6;
|
||||
|
||||
if (*p == 0)
|
||||
{
|
||||
if (res->noticeHook)
|
||||
{
|
||||
snprintf(noticeBuf, sizeof(noticeBuf),
|
||||
libpq_gettext("could not interpret result from server: %s\n"),
|
||||
res->cmdStatus);
|
||||
DONOTICE(res, noticeBuf);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
p = res->cmdStatus + 6;
|
||||
p++;
|
||||
if (*(res->cmdStatus) != 'I') /* UPDATE/DELETE */
|
||||
return p;
|
||||
/* INSERT: skip oid */
|
||||
while (*p != ' ' && *p)
|
||||
p++; /* INSERT: skip oid */
|
||||
if (*p == 0)
|
||||
{
|
||||
if (res->noticeHook)
|
||||
{
|
||||
snprintf(noticeBuf, sizeof(noticeBuf),
|
||||
libpq_gettext("no row count available\n"));
|
||||
DONOTICE(res, noticeBuf);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
p++;
|
||||
return p;
|
||||
p++;
|
||||
}
|
||||
return "";
|
||||
else if (strncmp(res->cmdStatus, "DELETE ", 7) == 0 ||
|
||||
strncmp(res->cmdStatus, "UPDATE ", 7) == 0)
|
||||
p = res->cmdStatus + 6;
|
||||
else if (strncmp(res->cmdStatus, "FETCH ", 6) == 0)
|
||||
p = res->cmdStatus + 5;
|
||||
else if (strncmp(res->cmdStatus, "MOVE ", 5) == 0)
|
||||
p = res->cmdStatus + 4;
|
||||
else
|
||||
return "";
|
||||
|
||||
p++;
|
||||
|
||||
if (*p == 0)
|
||||
{
|
||||
if (res->noticeHook)
|
||||
{
|
||||
snprintf(noticeBuf, sizeof(noticeBuf),
|
||||
libpq_gettext("could not interpret result from server: %s\n"),
|
||||
res->cmdStatus);
|
||||
DONOTICE(res, noticeBuf);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user