88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.135 2003/05/08 18:16:37 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.136 2003/05/26 20:05:20 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -55,7 +55,7 @@ static void parseInput(PGconn *conn);
5555static void handleSendFailure (PGconn * conn );
5656static void handleSyncLoss (PGconn * conn ,char id ,int msgLength );
5757static int getRowDescriptions (PGconn * conn );
58- static int getAnotherTuple (PGconn * conn );
58+ static int getAnotherTuple (PGconn * conn , int msgLength );
5959static int getParameterStatus (PGconn * conn );
6060static int getNotify (PGconn * conn );
6161
@@ -835,17 +835,28 @@ parseInput(PGconn *conn)
835835}
836836break ;
837837case 'D' :/* Data Row */
838- if (conn -> result != NULL )
838+ if (conn -> result != NULL &&
839+ conn -> result -> resultStatus == PGRES_TUPLES_OK )
839840{
840841/* Read another tuple of a normal query response */
841- if (getAnotherTuple (conn ))
842+ if (getAnotherTuple (conn , msgLength ))
842843return ;
843844}
845+ else if (conn -> result != NULL &&
846+ conn -> result -> resultStatus == PGRES_FATAL_ERROR )
847+ {
848+ /*
849+ * We've already choked for some reason. Just discard
850+ * tuples till we get to the end of the query.
851+ */
852+ conn -> inCursor += msgLength ;
853+ }
844854else
845855{
846- snprintf (noticeWorkspace ,sizeof (noticeWorkspace ),
856+ /* Set up to report error at end of query */
857+ printfPQExpBuffer (& conn -> errorMessage ,
847858libpq_gettext ("server sent data (\"D\" message) without prior row description (\"T\" message)\n" ));
848- DONOTICE (conn , noticeWorkspace );
859+ saveErrorResult (conn );
849860/* Discard the unexpected message */
850861conn -> inCursor += msgLength ;
851862}
@@ -888,6 +899,7 @@ parseInput(PGconn *conn)
888899id );
889900/* build an error result holding the error message */
890901saveErrorResult (conn );
902+ /* not sure if we will see more, so go to ready state */
891903conn -> asyncStatus = PGASYNC_READY ;
892904/* Discard the unexpected message */
893905conn -> inCursor += msgLength ;
@@ -931,6 +943,7 @@ handleSyncLoss(PGconn *conn, char id, int msgLength)
931943pqsecure_close (conn );
932944closesocket (conn -> sock );
933945conn -> sock = -1 ;
946+ conn -> asyncStatus = PGASYNC_READY ;/* drop out of GetResult wait loop */
934947}
935948
936949/*
@@ -1023,7 +1036,7 @@ getRowDescriptions(PGconn *conn)
10231036 */
10241037
10251038static int
1026- getAnotherTuple (PGconn * conn )
1039+ getAnotherTuple (PGconn * conn , int msgLength )
10271040{
10281041PGresult * result = conn -> result ;
10291042int nfields = result -> numAttributes ;
@@ -1050,12 +1063,11 @@ getAnotherTuple(PGconn *conn)
10501063if (tupnfields != nfields )
10511064{
10521065/* Replace partially constructed result with an error result */
1053- pqClearAsyncResult (conn );
10541066printfPQExpBuffer (& conn -> errorMessage ,
10551067libpq_gettext ("unexpected field count in D message\n" ));
10561068saveErrorResult (conn );
1057- conn -> asyncStatus = PGASYNC_READY ;
10581069/* Discard the failed message by pretending we read it */
1070+ conn -> inCursor = conn -> inStart + 5 + msgLength ;
10591071return 0 ;
10601072}
10611073
@@ -1102,14 +1114,15 @@ getAnotherTuple(PGconn *conn)
11021114
11031115/*
11041116 * we do NOT use saveErrorResult() here, because of the likelihood
1105- * that there's not enough memory to concatenate messages...
1117+ * that there's not enough memory to concatenate messages. Instead,
1118+ * discard the old result first to try to win back some memory.
11061119 */
11071120pqClearAsyncResult (conn );
11081121printfPQExpBuffer (& conn -> errorMessage ,
1109- libpq_gettext ("out of memory\n" ));
1122+ libpq_gettext ("out of memory for query result \n" ));
11101123conn -> result = PQmakeEmptyPGresult (conn ,PGRES_FATAL_ERROR );
1111- conn -> asyncStatus = PGASYNC_READY ;
11121124/* Discard the failed message by pretending we read it */
1125+ conn -> inCursor = conn -> inStart + 5 + msgLength ;
11131126return 0 ;
11141127}
11151128