diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c index fb4033d..3ca2e6b 100644 --- a/src/interfaces/libpq/fe-protocol3.c +++ b/src/interfaces/libpq/fe-protocol3.c @@ -157,10 +157,24 @@ pqParseInput3(PGconn *conn) } else if (conn->asyncStatus != PGASYNC_BUSY) { + if (conn->asyncStatus == PGASYNC_MEMORY_FULL) + { + if (id == 'C') + { + pqClearAsyncResult(conn); + conn->result = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR); + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("out of memory during parsing\n")); + pqSaveErrorResult(conn); + conn->asyncStatus = PGASYNC_READY; + } + conn->inCursor += msgLength; + } /* If not IDLE state, just wait ... */ - if (conn->asyncStatus != PGASYNC_IDLE) + else if (conn->asyncStatus != PGASYNC_IDLE) + { return; - + } /* * Unexpected message in IDLE state; need to recover somehow. * ERROR messages are displayed using the notice processor; @@ -170,7 +184,7 @@ pqParseInput3(PGconn *conn) * it is about to close the connection, so we don't want to just * discard it...) */ - if (id == 'E') + else if (id == 'E') { if (pqGetErrorNotice3(conn, false /* treat as notice */ )) return; @@ -268,9 +282,14 @@ pqParseInput3(PGconn *conn) if (conn->result == NULL || conn->queryclass == PGQUERY_DESCRIBE) { + int const before = conn->inCursor; /* First 'T' in a query sequence */ if (getRowDescriptions(conn)) - return; + { + conn->asyncStatus = PGASYNC_MEMORY_FULL; + conn->inCursor = before + msgLength; + break; + } /* * If we're doing a Describe, we're ready to pass the diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h index 31b517c..333fc7b 100644 --- a/src/interfaces/libpq/libpq-int.h +++ b/src/interfaces/libpq/libpq-int.h @@ -219,7 +219,8 @@ typedef enum PGASYNC_READY, /* result ready for PQgetResult */ PGASYNC_COPY_IN, /* Copy In data transfer in progress */ PGASYNC_COPY_OUT, /* Copy Out data transfer in progress */ - PGASYNC_COPY_BOTH /* Copy In/Out data transfer in progress */ + PGASYNC_COPY_BOTH, /* Copy In/Out data transfer in progress */ + PGASYNC_MEMORY_FULL /* not enough memory for parsing */ } PGAsyncStatusType; /* PGQueryClass tracks which query protocol we are now executing */