aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/interfaces/libpq/fe-exec.c117
-rw-r--r--src/interfaces/libpq/fe-protocol3.c18
-rw-r--r--src/test/modules/libpq_pipeline/libpq_pipeline.c12
3 files changed, 36 insertions, 111 deletions
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 97f6894244d..0274c1b156c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -1433,7 +1433,6 @@ static int
PQsendQueryInternal(PGconn *conn, const char *query, bool newQuery)
{
PGcmdQueueEntry *entry = NULL;
- PGcmdQueueEntry *entry2 = NULL;
if (!PQsendQueryStart(conn, newQuery))
return 0;
@@ -1446,103 +1445,48 @@ PQsendQueryInternal(PGconn *conn, const char *query, bool newQuery)
return 0;
}
- entry = pqAllocCmdQueueEntry(conn);
- if (entry == NULL)
- return 0; /* error msg already set */
if (conn->pipelineStatus != PQ_PIPELINE_OFF)
{
- entry2 = pqAllocCmdQueueEntry(conn);
- if (entry2 == NULL)
- goto sendFailed;
+ appendPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("%s not allowed in pipeline mode\n"),
+ "PQsendQuery");
+ return 0;
}
+ entry = pqAllocCmdQueueEntry(conn);
+ if (entry == NULL)
+ return 0; /* error msg already set */
+
/* Send the query message(s) */
- if (conn->pipelineStatus == PQ_PIPELINE_OFF)
+ /* construct the outgoing Query message */
+ if (pqPutMsgStart('Q', conn) < 0 ||
+ pqPuts(query, conn) < 0 ||
+ pqPutMsgEnd(conn) < 0)
{
- /* construct the outgoing Query message */
- if (pqPutMsgStart('Q', conn) < 0 ||
- pqPuts(query, conn) < 0 ||
- pqPutMsgEnd(conn) < 0)
- {
- /* error message should be set up already */
- pqRecycleCmdQueueEntry(conn, entry);
- return 0;
- }
-
- /* remember we are using simple query protocol */
- entry->queryclass = PGQUERY_SIMPLE;
- /* and remember the query text too, if possible */
- entry->query = strdup(query);
+ /* error message should be set up already */
+ pqRecycleCmdQueueEntry(conn, entry);
+ return 0;
}
- else
- {
- /*
- * In pipeline mode we cannot use the simple protocol, so we send
- * Parse, Bind, Describe Portal, Execute, Close Portal (with the
- * unnamed portal).
- */
- if (pqPutMsgStart('P', conn) < 0 ||
- pqPuts("", conn) < 0 ||
- pqPuts(query, conn) < 0 ||
- pqPutInt(0, 2, conn) < 0 ||
- pqPutMsgEnd(conn) < 0)
- goto sendFailed;
- if (pqPutMsgStart('B', conn) < 0 ||
- pqPuts("", conn) < 0 ||
- pqPuts("", conn) < 0 ||
- pqPutInt(0, 2, conn) < 0 ||
- pqPutInt(0, 2, conn) < 0 ||
- pqPutInt(0, 2, conn) < 0 ||
- pqPutMsgEnd(conn) < 0)
- goto sendFailed;
- if (pqPutMsgStart('D', conn) < 0 ||
- pqPutc('P', conn) < 0 ||
- pqPuts("", conn) < 0 ||
- pqPutMsgEnd(conn) < 0)
- goto sendFailed;
- if (pqPutMsgStart('E', conn) < 0 ||
- pqPuts("", conn) < 0 ||
- pqPutInt(0, 4, conn) < 0 ||
- pqPutMsgEnd(conn) < 0)
- goto sendFailed;
- if (pqPutMsgStart('C', conn) < 0 ||
- pqPutc('P', conn) < 0 ||
- pqPuts("", conn) < 0 ||
- pqPutMsgEnd(conn) < 0)
- goto sendFailed;
- entry->queryclass = PGQUERY_EXTENDED;
- entry->query = strdup(query);
- }
+ /* remember we are using simple query protocol */
+ entry->queryclass = PGQUERY_SIMPLE;
+ /* and remember the query text too, if possible */
+ entry->query = strdup(query);
/*
* Give the data a push. In nonblock mode, don't complain if we're unable
* to send it all; PQgetResult() will do any additional flushing needed.
*/
- if (pqPipelineFlush(conn) < 0)
+ if (pqFlush(conn) < 0)
goto sendFailed;
/* OK, it's launched! */
pqAppendCmdQueueEntry(conn, entry);
- /*
- * When pipeline mode is in use, we need a second entry in the command
- * queue to represent Close Portal message. This allows us later to wait
- * for the CloseComplete message to be received before getting in IDLE
- * state.
- */
- if (conn->pipelineStatus != PQ_PIPELINE_OFF)
- {
- entry2->queryclass = PGQUERY_CLOSE;
- entry2->query = NULL;
- pqAppendCmdQueueEntry(conn, entry2);
- }
-
return 1;
sendFailed:
pqRecycleCmdQueueEntry(conn, entry);
- pqRecycleCmdQueueEntry(conn, entry2);
/* error message should be set up already */
return 0;
}
@@ -2246,22 +2190,6 @@ PQgetResult(PGconn *conn)
break;
}
- /* If the next command we expect is CLOSE, read and consume it */
- if (conn->asyncStatus == PGASYNC_PIPELINE_IDLE &&
- conn->cmd_queue_head &&
- conn->cmd_queue_head->queryclass == PGQUERY_CLOSE)
- {
- if (res && res->resultStatus != PGRES_FATAL_ERROR)
- {
- conn->asyncStatus = PGASYNC_BUSY;
- parseInput(conn);
- conn->asyncStatus = PGASYNC_PIPELINE_IDLE;
- }
- else
- /* we won't ever see the Close */
- pqCommandQueueAdvance(conn);
- }
-
/* Time to fire PGEVT_RESULTCREATE events, if there are any */
if (res && res->nEvents > 0)
(void) PQfireResultCreateEvents(conn, res);
@@ -2977,8 +2905,9 @@ PQfn(PGconn *conn,
if (conn->pipelineStatus != PQ_PIPELINE_OFF)
{
- appendPQExpBufferStr(&conn->errorMessage,
- libpq_gettext("PQfn not allowed in pipeline mode\n"));
+ appendPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("%s not allowed in pipeline mode\n"),
+ "PQfn");
return NULL;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index bbfb55542df..f001137b769 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -282,24 +282,8 @@ pqParseInput3(PGconn *conn)
}
break;
case '2': /* Bind Complete */
- /* Nothing to do for this message type */
- break;
case '3': /* Close Complete */
- /*
- * If we get CloseComplete when waiting for it, consume
- * the queue element and keep going. A result is not
- * expected from this message; it is just there so that
- * we know to wait for it when PQsendQuery is used in
- * pipeline mode, before going in IDLE state. Failing to
- * do this makes us receive CloseComplete when IDLE, which
- * creates problems.
- */
- if (conn->cmd_queue_head &&
- conn->cmd_queue_head->queryclass == PGQUERY_CLOSE)
- {
- pqCommandQueueAdvance(conn);
- }
-
+ /* Nothing to do for these message types */
break;
case 'S': /* parameter status */
if (getParameterStatus(conn))
diff --git a/src/test/modules/libpq_pipeline/libpq_pipeline.c b/src/test/modules/libpq_pipeline/libpq_pipeline.c
index de4d75cfa82..c609f422589 100644
--- a/src/test/modules/libpq_pipeline/libpq_pipeline.c
+++ b/src/test/modules/libpq_pipeline/libpq_pipeline.c
@@ -106,6 +106,18 @@ test_disallowed_in_pipeline(PGconn *conn)
res = PQexec(conn, "SELECT 1");
if (PQresultStatus(res) != PGRES_FATAL_ERROR)
pg_fatal("PQexec should fail in pipeline mode but succeeded");
+ if (strcmp(PQerrorMessage(conn),
+ "synchronous command execution functions are not allowed in pipeline mode\n") != 0)
+ pg_fatal("did not get expected error message; got: \"%s\"",
+ PQerrorMessage(conn));
+
+ /* PQsendQuery should fail in pipeline mode */
+ if (PQsendQuery(conn, "SELECT 1") != 0)
+ pg_fatal("PQsendQuery should fail in pipeline mode but succeeded");
+ if (strcmp(PQerrorMessage(conn),
+ "PQsendQuery not allowed in pipeline mode\n") != 0)
+ pg_fatal("did not get expected error message; got: \"%s\"",
+ PQerrorMessage(conn));
/* Entering pipeline mode when already in pipeline mode is OK */
if (PQenterPipelineMode(conn) != 1)