Re: BUG #5697: Infinite loop inside PQexecStart function - Mailing list pgsql-bugs
From | Boris Bondarenko |
---|---|
Subject | Re: BUG #5697: Infinite loop inside PQexecStart function |
Date | |
Msg-id | 4CADEC88.9040308@nyc.yamaha.com Whole thread Raw |
In response to | Re: BUG #5697: Infinite loop inside PQexecStart function (Tom Lane <tgl@sss.pgh.pa.us>) |
List | pgsql-bugs |
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" <admin@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 -:- bbondarenko@nyc.yamaha.com Yamaha Music Interactive Inc. YMIA
pgsql-bugs by date: