8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -55,7 +55,7 @@ static void parseInput(PGconn *conn);
55
55
static void handleSendFailure (PGconn * conn );
56
56
static void handleSyncLoss (PGconn * conn , char id , int msgLength );
57
57
static int getRowDescriptions (PGconn * conn );
58
- static int getAnotherTuple (PGconn * conn );
58
+ static int getAnotherTuple (PGconn * conn , int msgLength );
59
59
static int getParameterStatus (PGconn * conn );
60
60
static int getNotify (PGconn * conn );
61
61
@@ -835,17 +835,28 @@ parseInput(PGconn *conn)
835
835
}
836
836
break ;
837
837
case 'D' : /* Data Row */
838
- if (conn -> result != NULL )
838
+ if (conn -> result != NULL &&
839
+ conn -> result -> resultStatus == PGRES_TUPLES_OK )
839
840
{
840
841
/* Read another tuple of a normal query response */
841
- if (getAnotherTuple (conn ))
842
+ if (getAnotherTuple (conn , msgLength ))
842
843
return ;
843
844
}
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
+ }
844
854
else
845
855
{
846
- snprintf (noticeWorkspace , sizeof (noticeWorkspace ),
856
+ /* Set up to report error at end of query */
857
+ printfPQExpBuffer (& conn -> errorMessage ,
847
858
libpq_gettext ("server sent data (\"D\" message) without prior row description (\"T\" message)\n" ));
848
- DONOTICE (conn , noticeWorkspace );
859
+ saveErrorResult (conn );
849
860
/* Discard the unexpected message */
850
861
conn -> inCursor += msgLength ;
851
862
}
@@ -888,6 +899,7 @@ parseInput(PGconn *conn)
888
899
id );
889
900
/* build an error result holding the error message */
890
901
saveErrorResult (conn );
902
+ /* not sure if we will see more, so go to ready state */
891
903
conn -> asyncStatus = PGASYNC_READY ;
892
904
/* Discard the unexpected message */
893
905
conn -> inCursor += msgLength ;
@@ -931,6 +943,7 @@ handleSyncLoss(PGconn *conn, char id, int msgLength)
931
943
pqsecure_close (conn );
932
944
closesocket (conn -> sock );
933
945
conn -> sock = -1 ;
946
+ conn -> asyncStatus = PGASYNC_READY ; /* drop out of GetResult wait loop */
934
947
}
935
948
936
949
/*
@@ -1023,7 +1036,7 @@ getRowDescriptions(PGconn *conn)
1023
1036
*/
1024
1037
1025
1038
static int
1026
- getAnotherTuple (PGconn * conn )
1039
+ getAnotherTuple (PGconn * conn , int msgLength )
1027
1040
{
1028
1041
PGresult * result = conn -> result ;
1029
1042
int nfields = result -> numAttributes ;
@@ -1050,12 +1063,11 @@ getAnotherTuple(PGconn *conn)
1050
1063
if (tupnfields != nfields )
1051
1064
{
1052
1065
/* Replace partially constructed result with an error result */
1053
- pqClearAsyncResult (conn );
1054
1066
printfPQExpBuffer (& conn -> errorMessage ,
1055
1067
libpq_gettext ("unexpected field count in D message\n" ));
1056
1068
saveErrorResult (conn );
1057
- conn -> asyncStatus = PGASYNC_READY ;
1058
1069
/* Discard the failed message by pretending we read it */
1070
+ conn -> inCursor = conn -> inStart + 5 + msgLength ;
1059
1071
return 0 ;
1060
1072
}
1061
1073
@@ -1102,14 +1114,15 @@ getAnotherTuple(PGconn *conn)
1102
1114
1103
1115
/*
1104
1116
* 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.
1106
1119
*/
1107
1120
pqClearAsyncResult (conn );
1108
1121
printfPQExpBuffer (& conn -> errorMessage ,
1109
- libpq_gettext ("out of memory\n" ));
1122
+ libpq_gettext ("out of memory for query result \n" ));
1110
1123
conn -> result = PQmakeEmptyPGresult (conn , PGRES_FATAL_ERROR );
1111
- conn -> asyncStatus = PGASYNC_READY ;
1112
1124
/* Discard the failed message by pretending we read it */
1125
+ conn -> inCursor = conn -> inStart + 5 + msgLength ;
1113
1126
return 0 ;
1114
1127
}
1115
1128
0 commit comments