That was a short form i used to point out the issue, the actual code from src/interfaces/libpq/fe-exec.c

   1368 static bool
   1369 PQexecStart(PGconn *conn)
   1370 {
   1371         PGresult   *result;
   1372
   1373         if (!conn)
   1374                 return false;
   1375
   1376         /*
1377 * Silently discard any prior query result that application didn't eat. 1378 * This is probably poor design, but it's here for backward compatibility.
   1379          */
   1380         while ((result = PQgetResult(conn)) != NULL)
   1381         {
   1382                 ExecStatusType resultStatus = result->resultStatus;
   1383
1384 PQclear(result); /* only need its status */
   1385                 if (resultStatus == PGRES_COPY_IN)
   1386                 {
   1387                         if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
   1388                         {
1389 /* In protocol 3, we can get out of a COPY IN state */
   1390                                 if (PQputCopyEnd(conn,
1391 libpq_gettext("COPY terminated by new PQexec")) < 0)
   1392                                         return false;
1393 /* keep waiting to swallow the copy's failure message */
   1394                         }
   1395                         else
   1396                         {
1397 /* In older protocols we have to punt */ 1398 printfPQExpBuffer(&conn->errorMessage, 1399 libpq_gettext("COPY IN state must be terminated first\n"));
   1400                                 return false;
   1401                         }
   1402                 }
   1403                 else if (resultStatus == PGRES_COPY_OUT)
   1404                 {
   1405                         if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
   1406                         {
   1407                                 /*
1408 * In protocol 3, we can get out of a COPY OUT state: we just 1409 * switch back to BUSY and allow the remaining COPY data to be
   1410                                  * dropped on the floor.
   1411                                  */
   1412                                 conn->asyncStatus = PGASYNC_BUSY;
1413 /* keep waiting to swallow the copy's completion message */
   1414                         }
   1415                         else
   1416                         {
1417 /* In older protocols we have to punt */ 1418 printfPQExpBuffer(&conn->errorMessage, 1419 libpq_gettext("COPY OUT state must be terminated first\n"));
   1420                                 return false;
   1421                         }
   1422                 }
   1423                 /* check for loss of connection, too */
   1424                 if (conn->status == CONNECTION_BAD)
   1425                         return false;
   1426         }
   1427
   1428         /* OK to send a command */
   1429         return true;
   1430 }


Sorry for the confusion from the shortened form.


Tom Lane wrote:
"Boris" <ad...@nyc.yamaha.com> writes:
while ((result = PQgetResult(conn)) != NULL){
    ExecStatusType resultStatus = result->resultStatus;
    PQclear(result); /* only need its status */
    /* check for loss of connection, too */
if (result->resultStatus == PGRES_COPY_IN || result->resultStatus == PGRES_COPY_OUT || conn->status == CONNECTION_BAD) break; }

This code is broken: once you've done PQclear() it's unsafe to access
the PGresult.  I think you meant just "resultStatus" not
"result->resultStatus" in the if().

                        regards, tom lane


--
Boris Bondarenko -:- bbondare...@nyc.yamaha.com
        Yamaha Music Interactive Inc.

YMIA


--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

Reply via email to