/* First 'T' in a query sequence */
if (getRowDescriptions(conn, msgLength))
return;
- /* getRowDescriptions() moves inStart itself */
- continue;
}
else
{
case 't': /* Parameter Description */
if (getParamDescriptions(conn, msgLength))
return;
- /* getParamDescriptions() moves inStart itself */
- continue;
+ break;
case 'D': /* Data Row */
if (conn->result != NULL &&
conn->result->resultStatus == PGRES_TUPLES_OK)
/* Read another tuple of a normal query response */
if (getAnotherTuple(conn, msgLength))
return;
- /* getAnotherTuple() moves inStart itself */
- continue;
}
else if (conn->result != NULL &&
conn->result->resultStatus == PGRES_FATAL_ERROR)
* command for a prepared statement) containing the attribute data.
* Returns: 0 if processed message successfully, EOF to suspend parsing
* (the latter case is not actually used currently).
- * In the former case, conn->inStart has been advanced past the message.
*/
static int
getRowDescriptions(PGconn *conn, int msgLength)
result->binary = 0;
}
- /* Sanity check that we absorbed all the data */
- if (conn->inCursor != conn->inStart + 5 + msgLength)
- {
- errmsg = libpq_gettext("extraneous data in \"T\" message");
- goto advance_and_error;
- }
-
/* Success! */
conn->result = result;
- /* Advance inStart to show that the "T" message has been processed. */
- conn->inStart = conn->inCursor;
-
/*
* If we're doing a Describe, we're done, and ready to pass the result
* back to the client.
if (result && result != conn->result)
PQclear(result);
- /* Discard the failed message by pretending we read it */
- conn->inStart += 5 + msgLength;
-
/*
* Replace partially constructed result with an error result. First
* discard the old result to try to win back some memory.
printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
pqSaveErrorResult(conn);
+ /*
+ * Show the message as fully consumed, else pqParseInput3 will overwrite
+ * our error with a complaint about that.
+ */
+ conn->inCursor = conn->inStart + 5 + msgLength;
+
/*
* Return zero to allow input parsing to continue. Subsequent "D"
* messages will be ignored until we get to end of data, since an error
/*
* parseInput subroutine to read a 't' (ParameterDescription) message.
* We'll build a new PGresult structure containing the parameter data.
- * Returns: 0 if completed message, EOF if not enough data yet.
- * In the former case, conn->inStart has been advanced past the message.
- *
- * Note that if we run out of data, we have to release the partially
- * constructed PGresult, and rebuild it again next time. Fortunately,
- * that shouldn't happen often, since 't' messages usually fit in a packet.
+ * Returns: 0 if processed message successfully, EOF to suspend parsing
+ * (the latter case is not actually used currently).
*/
static int
getParamDescriptions(PGconn *conn, int msgLength)
result->paramDescs[i].typid = typid;
}
- /* Sanity check that we absorbed all the data */
- if (conn->inCursor != conn->inStart + 5 + msgLength)
- {
- errmsg = libpq_gettext("extraneous data in \"t\" message");
- goto advance_and_error;
- }
-
/* Success! */
conn->result = result;
- /* Advance inStart to show that the "t" message has been processed. */
- conn->inStart = conn->inCursor;
-
return 0;
not_enough_data:
- PQclear(result);
- return EOF;
+ errmsg = libpq_gettext("insufficient data in \"t\" message");
advance_and_error:
/* Discard unsaved result, if any */
if (result && result != conn->result)
PQclear(result);
- /* Discard the failed message by pretending we read it */
- conn->inStart += 5 + msgLength;
-
/*
* Replace partially constructed result with an error result. First
* discard the old result to try to win back some memory.
printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
pqSaveErrorResult(conn);
+ /*
+ * Show the message as fully consumed, else pqParseInput3 will overwrite
+ * our error with a complaint about that.
+ */
+ conn->inCursor = conn->inStart + 5 + msgLength;
+
/*
* Return zero to allow input parsing to continue. Essentially, we've
* replaced the COMMAND_OK result with an error result, but since this
* We fill rowbuf with column pointers and then call the row processor.
* Returns: 0 if processed message successfully, EOF to suspend parsing
* (the latter case is not actually used currently).
- * In the former case, conn->inStart has been advanced past the message.
*/
static int
getAnotherTuple(PGconn *conn, int msgLength)
}
}
- /* Sanity check that we absorbed all the data */
- if (conn->inCursor != conn->inStart + 5 + msgLength)
- {
- errmsg = libpq_gettext("extraneous data in \"D\" message");
- goto advance_and_error;
- }
-
- /* Advance inStart to show that the "D" message has been processed. */
- conn->inStart = conn->inCursor;
-
/* Process the collected row */
errmsg = NULL;
if (pqRowProcessor(conn, &errmsg))
return 0; /* normal, successful exit */
- goto set_error_result; /* pqRowProcessor failed, report it */
+ /* pqRowProcessor failed, fall through to report it */
advance_and_error:
- /* Discard the failed message by pretending we read it */
- conn->inStart += 5 + msgLength;
-
-set_error_result:
/*
* Replace partially constructed result with an error result. First
printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
pqSaveErrorResult(conn);
+ /*
+ * Show the message as fully consumed, else pqParseInput3 will overwrite
+ * our error with a complaint about that.
+ */
+ conn->inCursor = conn->inStart + 5 + msgLength;
+
/*
* Return zero to allow input parsing to continue. Subsequent "D"
* messages will be ignored until we get to end of data, since an error