OSDN Git Service

Teach PQcmdTuples() that a COPY command tag might contain a row count,
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 3 Mar 2006 20:57:32 +0000 (20:57 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 3 Mar 2006 20:57:32 +0000 (20:57 +0000)
and tighten up its sanity checking of the tag as a safety measure.
Volkan Yazici.

doc/src/sgml/libpq.sgml
src/interfaces/libpq/fe-exec.c

index 9c48948..ccec9c7 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.204 2006/03/01 00:23:21 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.205 2006/03/03 20:57:32 tgl Exp $
 -->
 
  <chapter id="libpq">
@@ -2127,12 +2127,13 @@ char *PQcmdTuples(PGresult *res);
           affected by the <acronym>SQL</> statement that generated the
           <structname>PGresult</>. This function can only be used
           following the execution of an <command>INSERT</>,
-          <command>UPDATE</>, <command>DELETE</>, <command>MOVE</>, or
-          <command>FETCH</> statement, or an <command>EXECUTE</> of a
-          prepared query that contains a <command>INSERT</>,
+          <command>UPDATE</>, <command>DELETE</>, <command>MOVE</>,
+          <command>FETCH</>, or <command>COPY</> statement,
+          or an <command>EXECUTE</> of a
+          prepared query that contains an <command>INSERT</>,
           <command>UPDATE</>, or <command>DELETE</> statement.  If the
           command that generated the <structname>PGresult</> was
-          anything else, <function>PQcmdTuples</> returns the empty
+          anything else, <function>PQcmdTuples</> returns an empty
           string. The caller should not free the return value
           directly. It will be freed when the associated
           <structname>PGresult</> handle is passed to
index 4edb065..2643166 100644 (file)
@@ -8,13 +8,12 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.179 2006/01/25 20:44:32 tgl Exp $
+ *       $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.180 2006/03/03 20:57:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "postgres_fe.h"
 
-#include <errno.h>
 #include <ctype.h>
 #include <fcntl.h>
 
@@ -2168,8 +2167,8 @@ PQoidValue(const PGresult *res)
 
 /*
  * PQcmdTuples -
- *     If the last command was an INSERT/UPDATE/DELETE/MOVE/FETCH, return a
- *     string containing the number of inserted/affected tuples. If not,
+ *     If the last command was INSERT/UPDATE/DELETE/MOVE/FETCH/COPY, return
+ *     string containing the number of inserted/affected tuples. If not,
  *     return "".
  *
  *     XXX: this should probably return an int
@@ -2177,40 +2176,48 @@ PQoidValue(const PGresult *res)
 char *
 PQcmdTuples(PGresult *res)
 {
-       char       *p;
+       char       *p, *c;
 
        if (!res)
                return "";
 
        if (strncmp(res->cmdStatus, "INSERT ", 7) == 0)
        {
-               p = res->cmdStatus + 6;
-               p++;
-               /* INSERT: skip oid */
-               while (*p != ' ' && *p)
+               p = res->cmdStatus + 7;
+               /* INSERT: skip oid and space */
+               while (*p && *p != ' ')
                        p++;
+               if (*p == 0)
+                       goto interpret_error;                           /* no space? */
+               p++;
        }
        else if (strncmp(res->cmdStatus, "DELETE ", 7) == 0 ||
                         strncmp(res->cmdStatus, "UPDATE ", 7) == 0)
-               p = res->cmdStatus + 6;
+               p = res->cmdStatus + 7;
        else if (strncmp(res->cmdStatus, "FETCH ", 6) == 0)
+               p = res->cmdStatus + 6;
+       else if (strncmp(res->cmdStatus, "MOVE ", 5) == 0 ||
+                        strncmp(res->cmdStatus, "COPY ", 5) == 0)
                p = res->cmdStatus + 5;
-       else if (strncmp(res->cmdStatus, "MOVE ", 5) == 0)
-               p = res->cmdStatus + 4;
        else
                return "";
 
-       p++;
-
-       if (*p == 0)
+       /* check that we have an integer (at least one digit, nothing else) */
+       for (c = p; *c; c++)
        {
-               pqInternalNotice(&res->noticeHooks,
-                                                "could not interpret result from server: %s",
-                                                res->cmdStatus);
-               return "";
+               if (!isdigit((unsigned char) *c))
+                       goto interpret_error;
        }
+       if (c == p)
+               goto interpret_error;
 
        return p;
+       
+interpret_error:
+       pqInternalNotice(&res->noticeHooks,
+                                        "could not interpret result from server: %s",
+                                        res->cmdStatus);
+       return "";
 }
 
 /*