mirror of
https://github.com/postgres/postgres.git
synced 2025-10-09 00:05:07 -04:00
Make libpq_pipeline.c shorter and more uniform via helper functions.
There are many places in this test program that need to consume a PGresult while checking that its PQresultStatus is as-expected, or related tasks such as checking that PQgetResult has nothing more to return. These tasks were open-coded in a rather inconsistent way, leading to some outright bugs, some memory leakage, and frequent inconsistencies about what would be reported in event of an error. Invent a few helper functions to standardize the behavior and reduce code duplication. Also, rename the one pre-existing helper function from confirm_query_canceled to consume_query_cancel, per Álvaro's suggestion that "confirm" is a poor choice of verb for a function that will discard the PGresult. While at it, clean up assorted other places that were leaking PGresults or even server connections. This is pure neatnik-ism, since the test doesn't run long enough for those leaks to be of any real-world concern. While this fixes some things that are clearly bugs, it's only a test program, and none of the bugs seem serious enough to justify back-patching. Bug: #18960 Reported-by: Dmitry Kovalenko <d.kovalenko@postgrespro.ru> Author: Tom Lane <tgl@sss.pgh.pa.us> Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de> Discussion: https://postgr.es/m/18960-09cd4a5100152e58@postgresql.org
This commit is contained in:
parent
38b602b028
commit
e351e5c4fe
@ -88,20 +88,67 @@ pg_fatal_impl(int line, const char *fmt,...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that the query on the given connection got canceled.
|
* Check that libpq next returns a PGresult with the specified status,
|
||||||
|
* returning the PGresult so that caller can perform additional checks.
|
||||||
*/
|
*/
|
||||||
#define confirm_query_canceled(conn) confirm_query_canceled_impl(__LINE__, conn)
|
#define confirm_result_status(conn, status) confirm_result_status_impl(__LINE__, conn, status)
|
||||||
static void
|
static PGresult *
|
||||||
confirm_query_canceled_impl(int line, PGconn *conn)
|
confirm_result_status_impl(int line, PGconn *conn, ExecStatusType status)
|
||||||
{
|
{
|
||||||
PGresult *res = NULL;
|
PGresult *res;
|
||||||
|
|
||||||
res = PQgetResult(conn);
|
res = PQgetResult(conn);
|
||||||
if (res == NULL)
|
if (res == NULL)
|
||||||
pg_fatal_impl(line, "PQgetResult returned null: %s",
|
pg_fatal_impl(line, "PQgetResult returned null unexpectedly: %s",
|
||||||
PQerrorMessage(conn));
|
PQerrorMessage(conn));
|
||||||
if (PQresultStatus(res) != PGRES_FATAL_ERROR)
|
if (PQresultStatus(res) != status)
|
||||||
pg_fatal_impl(line, "query did not fail when it was expected");
|
pg_fatal_impl(line, "PQgetResult returned status %s, expected %s: %s",
|
||||||
|
PQresStatus(PQresultStatus(res)),
|
||||||
|
PQresStatus(status),
|
||||||
|
PQerrorMessage(conn));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that libpq next returns a PGresult with the specified status,
|
||||||
|
* then free the PGresult.
|
||||||
|
*/
|
||||||
|
#define consume_result_status(conn, status) consume_result_status_impl(__LINE__, conn, status)
|
||||||
|
static void
|
||||||
|
consume_result_status_impl(int line, PGconn *conn, ExecStatusType status)
|
||||||
|
{
|
||||||
|
PGresult *res;
|
||||||
|
|
||||||
|
res = confirm_result_status_impl(line, conn, status);
|
||||||
|
PQclear(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that libpq next returns a null PGresult.
|
||||||
|
*/
|
||||||
|
#define consume_null_result(conn) consume_null_result_impl(__LINE__, conn)
|
||||||
|
static void
|
||||||
|
consume_null_result_impl(int line, PGconn *conn)
|
||||||
|
{
|
||||||
|
PGresult *res;
|
||||||
|
|
||||||
|
res = PQgetResult(conn);
|
||||||
|
if (res != NULL)
|
||||||
|
pg_fatal_impl(line, "expected NULL PGresult, got %s: %s",
|
||||||
|
PQresStatus(PQresultStatus(res)),
|
||||||
|
PQerrorMessage(conn));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that the query on the given connection got canceled.
|
||||||
|
*/
|
||||||
|
#define consume_query_cancel(conn) consume_query_cancel_impl(__LINE__, conn)
|
||||||
|
static void
|
||||||
|
consume_query_cancel_impl(int line, PGconn *conn)
|
||||||
|
{
|
||||||
|
PGresult *res;
|
||||||
|
|
||||||
|
res = confirm_result_status_impl(line, conn, PGRES_FATAL_ERROR);
|
||||||
if (strcmp(PQresultErrorField(res, PG_DIAG_SQLSTATE), "57014") != 0)
|
if (strcmp(PQresultErrorField(res, PG_DIAG_SQLSTATE), "57014") != 0)
|
||||||
pg_fatal_impl(line, "query failed with a different error than cancellation: %s",
|
pg_fatal_impl(line, "query failed with a different error than cancellation: %s",
|
||||||
PQerrorMessage(conn));
|
PQerrorMessage(conn));
|
||||||
@ -234,6 +281,10 @@ copy_connection(PGconn *conn)
|
|||||||
pg_fatal("Connection to database failed: %s",
|
pg_fatal("Connection to database failed: %s",
|
||||||
PQerrorMessage(copyConn));
|
PQerrorMessage(copyConn));
|
||||||
|
|
||||||
|
pfree(keywords);
|
||||||
|
pfree(vals);
|
||||||
|
PQconninfoFree(opts);
|
||||||
|
|
||||||
return copyConn;
|
return copyConn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,13 +316,13 @@ test_cancel(PGconn *conn)
|
|||||||
cancel = PQgetCancel(conn);
|
cancel = PQgetCancel(conn);
|
||||||
if (!PQcancel(cancel, errorbuf, sizeof(errorbuf)))
|
if (!PQcancel(cancel, errorbuf, sizeof(errorbuf)))
|
||||||
pg_fatal("failed to run PQcancel: %s", errorbuf);
|
pg_fatal("failed to run PQcancel: %s", errorbuf);
|
||||||
confirm_query_canceled(conn);
|
consume_query_cancel(conn);
|
||||||
|
|
||||||
/* PGcancel object can be reused for the next query */
|
/* PGcancel object can be reused for the next query */
|
||||||
send_cancellable_query(conn, monitorConn);
|
send_cancellable_query(conn, monitorConn);
|
||||||
if (!PQcancel(cancel, errorbuf, sizeof(errorbuf)))
|
if (!PQcancel(cancel, errorbuf, sizeof(errorbuf)))
|
||||||
pg_fatal("failed to run PQcancel: %s", errorbuf);
|
pg_fatal("failed to run PQcancel: %s", errorbuf);
|
||||||
confirm_query_canceled(conn);
|
consume_query_cancel(conn);
|
||||||
|
|
||||||
PQfreeCancel(cancel);
|
PQfreeCancel(cancel);
|
||||||
|
|
||||||
@ -279,14 +330,14 @@ test_cancel(PGconn *conn)
|
|||||||
send_cancellable_query(conn, monitorConn);
|
send_cancellable_query(conn, monitorConn);
|
||||||
if (!PQrequestCancel(conn))
|
if (!PQrequestCancel(conn))
|
||||||
pg_fatal("failed to run PQrequestCancel: %s", PQerrorMessage(conn));
|
pg_fatal("failed to run PQrequestCancel: %s", PQerrorMessage(conn));
|
||||||
confirm_query_canceled(conn);
|
consume_query_cancel(conn);
|
||||||
|
|
||||||
/* test PQcancelBlocking */
|
/* test PQcancelBlocking */
|
||||||
send_cancellable_query(conn, monitorConn);
|
send_cancellable_query(conn, monitorConn);
|
||||||
cancelConn = PQcancelCreate(conn);
|
cancelConn = PQcancelCreate(conn);
|
||||||
if (!PQcancelBlocking(cancelConn))
|
if (!PQcancelBlocking(cancelConn))
|
||||||
pg_fatal("failed to run PQcancelBlocking: %s", PQcancelErrorMessage(cancelConn));
|
pg_fatal("failed to run PQcancelBlocking: %s", PQcancelErrorMessage(cancelConn));
|
||||||
confirm_query_canceled(conn);
|
consume_query_cancel(conn);
|
||||||
PQcancelFinish(cancelConn);
|
PQcancelFinish(cancelConn);
|
||||||
|
|
||||||
/* test PQcancelCreate and then polling with PQcancelPoll */
|
/* test PQcancelCreate and then polling with PQcancelPoll */
|
||||||
@ -340,7 +391,7 @@ test_cancel(PGconn *conn)
|
|||||||
}
|
}
|
||||||
if (PQcancelStatus(cancelConn) != CONNECTION_OK)
|
if (PQcancelStatus(cancelConn) != CONNECTION_OK)
|
||||||
pg_fatal("unexpected cancel connection status: %s", PQcancelErrorMessage(cancelConn));
|
pg_fatal("unexpected cancel connection status: %s", PQcancelErrorMessage(cancelConn));
|
||||||
confirm_query_canceled(conn);
|
consume_query_cancel(conn);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* test PQcancelReset works on the cancel connection and it can be reused
|
* test PQcancelReset works on the cancel connection and it can be reused
|
||||||
@ -397,9 +448,10 @@ test_cancel(PGconn *conn)
|
|||||||
}
|
}
|
||||||
if (PQcancelStatus(cancelConn) != CONNECTION_OK)
|
if (PQcancelStatus(cancelConn) != CONNECTION_OK)
|
||||||
pg_fatal("unexpected cancel connection status: %s", PQcancelErrorMessage(cancelConn));
|
pg_fatal("unexpected cancel connection status: %s", PQcancelErrorMessage(cancelConn));
|
||||||
confirm_query_canceled(conn);
|
consume_query_cancel(conn);
|
||||||
|
|
||||||
PQcancelFinish(cancelConn);
|
PQcancelFinish(cancelConn);
|
||||||
|
PQfinish(monitorConn);
|
||||||
|
|
||||||
fprintf(stderr, "ok\n");
|
fprintf(stderr, "ok\n");
|
||||||
}
|
}
|
||||||
@ -428,6 +480,7 @@ test_disallowed_in_pipeline(PGconn *conn)
|
|||||||
"synchronous command execution functions are not allowed in pipeline mode\n") != 0)
|
"synchronous command execution functions are not allowed in pipeline mode\n") != 0)
|
||||||
pg_fatal("did not get expected error message; got: \"%s\"",
|
pg_fatal("did not get expected error message; got: \"%s\"",
|
||||||
PQerrorMessage(conn));
|
PQerrorMessage(conn));
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
/* PQsendQuery should fail in pipeline mode */
|
/* PQsendQuery should fail in pipeline mode */
|
||||||
if (PQsendQuery(conn, "SELECT 1") != 0)
|
if (PQsendQuery(conn, "SELECT 1") != 0)
|
||||||
@ -460,6 +513,7 @@ test_disallowed_in_pipeline(PGconn *conn)
|
|||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||||
pg_fatal("PQexec should succeed after exiting pipeline mode but failed with: %s",
|
pg_fatal("PQexec should succeed after exiting pipeline mode but failed with: %s",
|
||||||
PQerrorMessage(conn));
|
PQerrorMessage(conn));
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
fprintf(stderr, "ok\n");
|
fprintf(stderr, "ok\n");
|
||||||
}
|
}
|
||||||
@ -467,7 +521,6 @@ test_disallowed_in_pipeline(PGconn *conn)
|
|||||||
static void
|
static void
|
||||||
test_multi_pipelines(PGconn *conn)
|
test_multi_pipelines(PGconn *conn)
|
||||||
{
|
{
|
||||||
PGresult *res = NULL;
|
|
||||||
const char *dummy_params[1] = {"1"};
|
const char *dummy_params[1] = {"1"};
|
||||||
Oid dummy_param_oids[1] = {INT4OID};
|
Oid dummy_param_oids[1] = {INT4OID};
|
||||||
|
|
||||||
@ -508,87 +561,31 @@ test_multi_pipelines(PGconn *conn)
|
|||||||
/* OK, start processing the results */
|
/* OK, start processing the results */
|
||||||
|
|
||||||
/* first pipeline */
|
/* first pipeline */
|
||||||
|
consume_result_status(conn, PGRES_TUPLES_OK);
|
||||||
|
|
||||||
res = PQgetResult(conn);
|
consume_null_result(conn);
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("PQgetResult returned null when there's a pipeline item: %s",
|
|
||||||
PQerrorMessage(conn));
|
|
||||||
|
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
|
||||||
pg_fatal("Unexpected result code %s from first pipeline item",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
PQclear(res);
|
|
||||||
res = NULL;
|
|
||||||
|
|
||||||
if (PQgetResult(conn) != NULL)
|
|
||||||
pg_fatal("PQgetResult returned something extra after first result");
|
|
||||||
|
|
||||||
if (PQexitPipelineMode(conn) != 0)
|
if (PQexitPipelineMode(conn) != 0)
|
||||||
pg_fatal("exiting pipeline mode after query but before sync succeeded incorrectly");
|
pg_fatal("exiting pipeline mode after query but before sync succeeded incorrectly");
|
||||||
|
|
||||||
res = PQgetResult(conn);
|
consume_result_status(conn, PGRES_PIPELINE_SYNC);
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("PQgetResult returned null when sync result expected: %s",
|
|
||||||
PQerrorMessage(conn));
|
|
||||||
|
|
||||||
if (PQresultStatus(res) != PGRES_PIPELINE_SYNC)
|
|
||||||
pg_fatal("Unexpected result code %s instead of sync result, error: %s",
|
|
||||||
PQresStatus(PQresultStatus(res)), PQerrorMessage(conn));
|
|
||||||
PQclear(res);
|
|
||||||
|
|
||||||
/* second pipeline */
|
/* second pipeline */
|
||||||
|
consume_result_status(conn, PGRES_TUPLES_OK);
|
||||||
|
|
||||||
res = PQgetResult(conn);
|
consume_null_result(conn);
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("PQgetResult returned null when there's a pipeline item: %s",
|
|
||||||
PQerrorMessage(conn));
|
|
||||||
|
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
|
||||||
pg_fatal("Unexpected result code %s from second pipeline item",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
PQclear(res);
|
|
||||||
res = NULL;
|
|
||||||
|
|
||||||
if (PQgetResult(conn) != NULL)
|
|
||||||
pg_fatal("PQgetResult returned something extra after first result");
|
|
||||||
|
|
||||||
if (PQexitPipelineMode(conn) != 0)
|
if (PQexitPipelineMode(conn) != 0)
|
||||||
pg_fatal("exiting pipeline mode after query but before sync succeeded incorrectly");
|
pg_fatal("exiting pipeline mode after query but before sync succeeded incorrectly");
|
||||||
|
|
||||||
res = PQgetResult(conn);
|
consume_result_status(conn, PGRES_PIPELINE_SYNC);
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("PQgetResult returned null when sync result expected: %s",
|
|
||||||
PQerrorMessage(conn));
|
|
||||||
|
|
||||||
if (PQresultStatus(res) != PGRES_PIPELINE_SYNC)
|
|
||||||
pg_fatal("Unexpected result code %s instead of sync result, error: %s",
|
|
||||||
PQresStatus(PQresultStatus(res)), PQerrorMessage(conn));
|
|
||||||
PQclear(res);
|
|
||||||
|
|
||||||
/* third pipeline */
|
/* third pipeline */
|
||||||
|
consume_result_status(conn, PGRES_TUPLES_OK);
|
||||||
|
|
||||||
res = PQgetResult(conn);
|
consume_null_result(conn);
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("PQgetResult returned null when there's a pipeline item: %s",
|
|
||||||
PQerrorMessage(conn));
|
|
||||||
|
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
consume_result_status(conn, PGRES_PIPELINE_SYNC);
|
||||||
pg_fatal("Unexpected result code %s from third pipeline item",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
|
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (res != NULL)
|
|
||||||
pg_fatal("Expected null result, got %s",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
|
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("PQgetResult returned null when there's a pipeline item: %s",
|
|
||||||
PQerrorMessage(conn));
|
|
||||||
|
|
||||||
if (PQresultStatus(res) != PGRES_PIPELINE_SYNC)
|
|
||||||
pg_fatal("Unexpected result code %s from second pipeline sync",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
|
|
||||||
/* We're still in pipeline mode ... */
|
/* We're still in pipeline mode ... */
|
||||||
if (PQpipelineStatus(conn) == PQ_PIPELINE_OFF)
|
if (PQpipelineStatus(conn) == PQ_PIPELINE_OFF)
|
||||||
@ -657,36 +654,17 @@ test_nosync(PGconn *conn)
|
|||||||
/* Now read all results */
|
/* Now read all results */
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
PGresult *res;
|
|
||||||
|
|
||||||
res = PQgetResult(conn);
|
|
||||||
|
|
||||||
/* NULL results are only expected after TUPLES_OK */
|
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("got unexpected NULL result after %d results", results);
|
|
||||||
|
|
||||||
/* We expect exactly one TUPLES_OK result for each query we sent */
|
/* We expect exactly one TUPLES_OK result for each query we sent */
|
||||||
if (PQresultStatus(res) == PGRES_TUPLES_OK)
|
consume_result_status(conn, PGRES_TUPLES_OK);
|
||||||
{
|
|
||||||
PGresult *res2;
|
|
||||||
|
|
||||||
/* and one NULL result should follow each */
|
/* and one NULL result should follow each */
|
||||||
res2 = PQgetResult(conn);
|
consume_null_result(conn);
|
||||||
if (res2 != NULL)
|
|
||||||
pg_fatal("expected NULL, got %s",
|
|
||||||
PQresStatus(PQresultStatus(res2)));
|
|
||||||
PQclear(res);
|
|
||||||
results++;
|
|
||||||
|
|
||||||
/* if we're done, we're done */
|
results++;
|
||||||
if (results == numqueries)
|
|
||||||
break;
|
|
||||||
|
|
||||||
continue;
|
/* if we're done, we're done */
|
||||||
}
|
if (results == numqueries)
|
||||||
|
break;
|
||||||
/* anything else is unexpected */
|
|
||||||
pg_fatal("got unexpected %s\n", PQresStatus(PQresultStatus(res)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "ok\n");
|
fprintf(stderr, "ok\n");
|
||||||
@ -716,10 +694,12 @@ test_pipeline_abort(PGconn *conn)
|
|||||||
res = PQexec(conn, drop_table_sql);
|
res = PQexec(conn, drop_table_sql);
|
||||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||||
pg_fatal("dispatching DROP TABLE failed: %s", PQerrorMessage(conn));
|
pg_fatal("dispatching DROP TABLE failed: %s", PQerrorMessage(conn));
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
res = PQexec(conn, create_table_sql);
|
res = PQexec(conn, create_table_sql);
|
||||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||||
pg_fatal("dispatching CREATE TABLE failed: %s", PQerrorMessage(conn));
|
pg_fatal("dispatching CREATE TABLE failed: %s", PQerrorMessage(conn));
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Queue up a couple of small pipelines and process each without returning
|
* Queue up a couple of small pipelines and process each without returning
|
||||||
@ -763,33 +743,16 @@ test_pipeline_abort(PGconn *conn)
|
|||||||
* a pipeline aborted message for the second insert, a pipeline-end, then
|
* a pipeline aborted message for the second insert, a pipeline-end, then
|
||||||
* a command-ok and a pipeline-ok for the second pipeline operation.
|
* a command-ok and a pipeline-ok for the second pipeline operation.
|
||||||
*/
|
*/
|
||||||
res = PQgetResult(conn);
|
consume_result_status(conn, PGRES_COMMAND_OK);
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("Unexpected NULL result: %s", PQerrorMessage(conn));
|
|
||||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
|
||||||
pg_fatal("Unexpected result status %s: %s",
|
|
||||||
PQresStatus(PQresultStatus(res)),
|
|
||||||
PQresultErrorMessage(res));
|
|
||||||
PQclear(res);
|
|
||||||
|
|
||||||
/* NULL result to signal end-of-results for this command */
|
/* NULL result to signal end-of-results for this command */
|
||||||
if ((res = PQgetResult(conn)) != NULL)
|
consume_null_result(conn);
|
||||||
pg_fatal("Expected null result, got %s",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
|
|
||||||
/* Second query caused error, so we expect an error next */
|
/* Second query caused error, so we expect an error next */
|
||||||
res = PQgetResult(conn);
|
consume_result_status(conn, PGRES_FATAL_ERROR);
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("Unexpected NULL result: %s", PQerrorMessage(conn));
|
|
||||||
if (PQresultStatus(res) != PGRES_FATAL_ERROR)
|
|
||||||
pg_fatal("Unexpected result code -- expected PGRES_FATAL_ERROR, got %s",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
PQclear(res);
|
|
||||||
|
|
||||||
/* NULL result to signal end-of-results for this command */
|
/* NULL result to signal end-of-results for this command */
|
||||||
if ((res = PQgetResult(conn)) != NULL)
|
consume_null_result(conn);
|
||||||
pg_fatal("Expected null result, got %s",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pipeline should now be aborted.
|
* pipeline should now be aborted.
|
||||||
@ -802,17 +765,10 @@ test_pipeline_abort(PGconn *conn)
|
|||||||
pg_fatal("pipeline should be flagged as aborted but isn't");
|
pg_fatal("pipeline should be flagged as aborted but isn't");
|
||||||
|
|
||||||
/* third query in pipeline, the second insert */
|
/* third query in pipeline, the second insert */
|
||||||
res = PQgetResult(conn);
|
consume_result_status(conn, PGRES_PIPELINE_ABORTED);
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("Unexpected NULL result: %s", PQerrorMessage(conn));
|
|
||||||
if (PQresultStatus(res) != PGRES_PIPELINE_ABORTED)
|
|
||||||
pg_fatal("Unexpected result code -- expected PGRES_PIPELINE_ABORTED, got %s",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
PQclear(res);
|
|
||||||
|
|
||||||
/* NULL result to signal end-of-results for this command */
|
/* NULL result to signal end-of-results for this command */
|
||||||
if ((res = PQgetResult(conn)) != NULL)
|
consume_null_result(conn);
|
||||||
pg_fatal("Expected null result, got %s", PQresStatus(PQresultStatus(res)));
|
|
||||||
|
|
||||||
if (PQpipelineStatus(conn) != PQ_PIPELINE_ABORTED)
|
if (PQpipelineStatus(conn) != PQ_PIPELINE_ABORTED)
|
||||||
pg_fatal("pipeline should be flagged as aborted but isn't");
|
pg_fatal("pipeline should be flagged as aborted but isn't");
|
||||||
@ -827,14 +783,7 @@ test_pipeline_abort(PGconn *conn)
|
|||||||
* (This is so clients know to start processing results normally again and
|
* (This is so clients know to start processing results normally again and
|
||||||
* can tell the difference between skipped commands and the sync.)
|
* can tell the difference between skipped commands and the sync.)
|
||||||
*/
|
*/
|
||||||
res = PQgetResult(conn);
|
consume_result_status(conn, PGRES_PIPELINE_SYNC);
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("Unexpected NULL result: %s", PQerrorMessage(conn));
|
|
||||||
if (PQresultStatus(res) != PGRES_PIPELINE_SYNC)
|
|
||||||
pg_fatal("Unexpected result code from first pipeline sync\n"
|
|
||||||
"Expected PGRES_PIPELINE_SYNC, got %s",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
PQclear(res);
|
|
||||||
|
|
||||||
if (PQpipelineStatus(conn) == PQ_PIPELINE_ABORTED)
|
if (PQpipelineStatus(conn) == PQ_PIPELINE_ABORTED)
|
||||||
pg_fatal("sync should've cleared the aborted flag but didn't");
|
pg_fatal("sync should've cleared the aborted flag but didn't");
|
||||||
@ -844,30 +793,16 @@ test_pipeline_abort(PGconn *conn)
|
|||||||
pg_fatal("Fell out of pipeline mode somehow");
|
pg_fatal("Fell out of pipeline mode somehow");
|
||||||
|
|
||||||
/* the insert from the second pipeline */
|
/* the insert from the second pipeline */
|
||||||
res = PQgetResult(conn);
|
consume_result_status(conn, PGRES_COMMAND_OK);
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("Unexpected NULL result: %s", PQerrorMessage(conn));
|
|
||||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
|
||||||
pg_fatal("Unexpected result code %s from first item in second pipeline",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
PQclear(res);
|
|
||||||
|
|
||||||
/* Read the NULL result at the end of the command */
|
/* Read the NULL result at the end of the command */
|
||||||
if ((res = PQgetResult(conn)) != NULL)
|
consume_null_result(conn);
|
||||||
pg_fatal("Expected null result, got %s", PQresStatus(PQresultStatus(res)));
|
|
||||||
|
|
||||||
/* the second pipeline sync */
|
/* the second pipeline sync */
|
||||||
if ((res = PQgetResult(conn)) == NULL)
|
consume_result_status(conn, PGRES_PIPELINE_SYNC);
|
||||||
pg_fatal("Unexpected NULL result: %s", PQerrorMessage(conn));
|
|
||||||
if (PQresultStatus(res) != PGRES_PIPELINE_SYNC)
|
|
||||||
pg_fatal("Unexpected result code %s from second pipeline sync",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
PQclear(res);
|
|
||||||
|
|
||||||
if ((res = PQgetResult(conn)) != NULL)
|
/* Read the NULL result at the end of the command */
|
||||||
pg_fatal("Expected null result, got %s: %s",
|
consume_null_result(conn);
|
||||||
PQresStatus(PQresultStatus(res)),
|
|
||||||
PQerrorMessage(conn));
|
|
||||||
|
|
||||||
/* Try to send two queries in one command */
|
/* Try to send two queries in one command */
|
||||||
if (PQsendQueryParams(conn, "SELECT 1; SELECT 2", 0, NULL, NULL, NULL, NULL, 0) != 1)
|
if (PQsendQueryParams(conn, "SELECT 1; SELECT 2", 0, NULL, NULL, NULL, NULL, 0) != 1)
|
||||||
@ -890,15 +825,14 @@ test_pipeline_abort(PGconn *conn)
|
|||||||
pg_fatal("got unexpected status %s", PQresStatus(PQresultStatus(res)));
|
pg_fatal("got unexpected status %s", PQresStatus(PQresultStatus(res)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
PQclear(res);
|
||||||
}
|
}
|
||||||
if (!goterror)
|
if (!goterror)
|
||||||
pg_fatal("did not get cannot-insert-multiple-commands error");
|
pg_fatal("did not get cannot-insert-multiple-commands error");
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (res == NULL)
|
/* the second pipeline sync */
|
||||||
pg_fatal("got NULL result");
|
consume_result_status(conn, PGRES_PIPELINE_SYNC);
|
||||||
if (PQresultStatus(res) != PGRES_PIPELINE_SYNC)
|
|
||||||
pg_fatal("Unexpected result code %s from pipeline sync",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
fprintf(stderr, "ok\n");
|
fprintf(stderr, "ok\n");
|
||||||
|
|
||||||
/* Test single-row mode with an error partways */
|
/* Test single-row mode with an error partways */
|
||||||
@ -935,13 +869,9 @@ test_pipeline_abort(PGconn *conn)
|
|||||||
pg_fatal("did not get division-by-zero error");
|
pg_fatal("did not get division-by-zero error");
|
||||||
if (gotrows != 3)
|
if (gotrows != 3)
|
||||||
pg_fatal("did not get three rows");
|
pg_fatal("did not get three rows");
|
||||||
|
|
||||||
/* the third pipeline sync */
|
/* the third pipeline sync */
|
||||||
if ((res = PQgetResult(conn)) == NULL)
|
consume_result_status(conn, PGRES_PIPELINE_SYNC);
|
||||||
pg_fatal("Unexpected NULL result: %s", PQerrorMessage(conn));
|
|
||||||
if (PQresultStatus(res) != PGRES_PIPELINE_SYNC)
|
|
||||||
pg_fatal("Unexpected result code %s from third pipeline sync",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
PQclear(res);
|
|
||||||
|
|
||||||
/* We're still in pipeline mode... */
|
/* We're still in pipeline mode... */
|
||||||
if (PQpipelineStatus(conn) == PQ_PIPELINE_OFF)
|
if (PQpipelineStatus(conn) == PQ_PIPELINE_OFF)
|
||||||
@ -1274,21 +1204,11 @@ test_prepared(PGconn *conn)
|
|||||||
if (PQpipelineSync(conn) != 1)
|
if (PQpipelineSync(conn) != 1)
|
||||||
pg_fatal("pipeline sync failed: %s", PQerrorMessage(conn));
|
pg_fatal("pipeline sync failed: %s", PQerrorMessage(conn));
|
||||||
|
|
||||||
res = PQgetResult(conn);
|
consume_result_status(conn, PGRES_COMMAND_OK);
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("PQgetResult returned null");
|
|
||||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
|
||||||
pg_fatal("expected COMMAND_OK, got %s", PQresStatus(PQresultStatus(res)));
|
|
||||||
PQclear(res);
|
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (res != NULL)
|
|
||||||
pg_fatal("expected NULL result");
|
|
||||||
|
|
||||||
res = PQgetResult(conn);
|
consume_null_result(conn);
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("PQgetResult returned NULL");
|
res = confirm_result_status(conn, PGRES_COMMAND_OK);
|
||||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
|
||||||
pg_fatal("expected COMMAND_OK, got %s", PQresStatus(PQresultStatus(res)));
|
|
||||||
if (PQnfields(res) != lengthof(expected_oids))
|
if (PQnfields(res) != lengthof(expected_oids))
|
||||||
pg_fatal("expected %zu columns, got %d",
|
pg_fatal("expected %zu columns, got %d",
|
||||||
lengthof(expected_oids), PQnfields(res));
|
lengthof(expected_oids), PQnfields(res));
|
||||||
@ -1300,13 +1220,10 @@ test_prepared(PGconn *conn)
|
|||||||
i, expected_oids[i], typ);
|
i, expected_oids[i], typ);
|
||||||
}
|
}
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (res != NULL)
|
|
||||||
pg_fatal("expected NULL result");
|
|
||||||
|
|
||||||
res = PQgetResult(conn);
|
consume_null_result(conn);
|
||||||
if (PQresultStatus(res) != PGRES_PIPELINE_SYNC)
|
|
||||||
pg_fatal("expected PGRES_PIPELINE_SYNC, got %s", PQresStatus(PQresultStatus(res)));
|
consume_result_status(conn, PGRES_PIPELINE_SYNC);
|
||||||
|
|
||||||
fprintf(stderr, "closing statement..");
|
fprintf(stderr, "closing statement..");
|
||||||
if (PQsendClosePrepared(conn, "select_one") != 1)
|
if (PQsendClosePrepared(conn, "select_one") != 1)
|
||||||
@ -1314,18 +1231,11 @@ test_prepared(PGconn *conn)
|
|||||||
if (PQpipelineSync(conn) != 1)
|
if (PQpipelineSync(conn) != 1)
|
||||||
pg_fatal("pipeline sync failed: %s", PQerrorMessage(conn));
|
pg_fatal("pipeline sync failed: %s", PQerrorMessage(conn));
|
||||||
|
|
||||||
res = PQgetResult(conn);
|
consume_result_status(conn, PGRES_COMMAND_OK);
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("expected non-NULL result");
|
consume_null_result(conn);
|
||||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
|
||||||
pg_fatal("expected COMMAND_OK, got %s", PQresStatus(PQresultStatus(res)));
|
consume_result_status(conn, PGRES_PIPELINE_SYNC);
|
||||||
PQclear(res);
|
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (res != NULL)
|
|
||||||
pg_fatal("expected NULL result");
|
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (PQresultStatus(res) != PGRES_PIPELINE_SYNC)
|
|
||||||
pg_fatal("expected PGRES_PIPELINE_SYNC, got %s", PQresStatus(PQresultStatus(res)));
|
|
||||||
|
|
||||||
if (PQexitPipelineMode(conn) != 1)
|
if (PQexitPipelineMode(conn) != 1)
|
||||||
pg_fatal("could not exit pipeline mode: %s", PQerrorMessage(conn));
|
pg_fatal("could not exit pipeline mode: %s", PQerrorMessage(conn));
|
||||||
@ -1334,6 +1244,7 @@ test_prepared(PGconn *conn)
|
|||||||
res = PQdescribePrepared(conn, "select_one");
|
res = PQdescribePrepared(conn, "select_one");
|
||||||
if (PQresultStatus(res) != PGRES_FATAL_ERROR)
|
if (PQresultStatus(res) != PGRES_FATAL_ERROR)
|
||||||
pg_fatal("expected FATAL_ERROR, got %s", PQresStatus(PQresultStatus(res)));
|
pg_fatal("expected FATAL_ERROR, got %s", PQresStatus(PQresultStatus(res)));
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Also test the blocking close, this should not fail since closing a
|
* Also test the blocking close, this should not fail since closing a
|
||||||
@ -1342,32 +1253,36 @@ test_prepared(PGconn *conn)
|
|||||||
res = PQclosePrepared(conn, "select_one");
|
res = PQclosePrepared(conn, "select_one");
|
||||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||||
pg_fatal("expected COMMAND_OK, got %s", PQresStatus(PQresultStatus(res)));
|
pg_fatal("expected COMMAND_OK, got %s", PQresStatus(PQresultStatus(res)));
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
fprintf(stderr, "creating portal... ");
|
fprintf(stderr, "creating portal... ");
|
||||||
PQexec(conn, "BEGIN");
|
|
||||||
PQexec(conn, "DECLARE cursor_one CURSOR FOR SELECT 1");
|
res = PQexec(conn, "BEGIN");
|
||||||
|
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||||
|
pg_fatal("BEGIN failed: %s", PQerrorMessage(conn));
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
|
res = PQexec(conn, "DECLARE cursor_one CURSOR FOR SELECT 1");
|
||||||
|
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||||
|
pg_fatal("DECLARE CURSOR failed: %s", PQerrorMessage(conn));
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
PQenterPipelineMode(conn);
|
PQenterPipelineMode(conn);
|
||||||
if (PQsendDescribePortal(conn, "cursor_one") != 1)
|
if (PQsendDescribePortal(conn, "cursor_one") != 1)
|
||||||
pg_fatal("PQsendDescribePortal failed: %s", PQerrorMessage(conn));
|
pg_fatal("PQsendDescribePortal failed: %s", PQerrorMessage(conn));
|
||||||
if (PQpipelineSync(conn) != 1)
|
if (PQpipelineSync(conn) != 1)
|
||||||
pg_fatal("pipeline sync failed: %s", PQerrorMessage(conn));
|
pg_fatal("pipeline sync failed: %s", PQerrorMessage(conn));
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("PQgetResult returned null");
|
|
||||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
|
||||||
pg_fatal("expected COMMAND_OK, got %s", PQresStatus(PQresultStatus(res)));
|
|
||||||
|
|
||||||
|
res = confirm_result_status(conn, PGRES_COMMAND_OK);
|
||||||
typ = PQftype(res, 0);
|
typ = PQftype(res, 0);
|
||||||
if (typ != INT4OID)
|
if (typ != INT4OID)
|
||||||
pg_fatal("portal: expected type %u, got %u",
|
pg_fatal("portal: expected type %u, got %u",
|
||||||
INT4OID, typ);
|
INT4OID, typ);
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (res != NULL)
|
consume_null_result(conn);
|
||||||
pg_fatal("expected NULL result");
|
|
||||||
res = PQgetResult(conn);
|
consume_result_status(conn, PGRES_PIPELINE_SYNC);
|
||||||
if (PQresultStatus(res) != PGRES_PIPELINE_SYNC)
|
|
||||||
pg_fatal("expected PGRES_PIPELINE_SYNC, got %s", PQresStatus(PQresultStatus(res)));
|
|
||||||
|
|
||||||
fprintf(stderr, "closing portal... ");
|
fprintf(stderr, "closing portal... ");
|
||||||
if (PQsendClosePortal(conn, "cursor_one") != 1)
|
if (PQsendClosePortal(conn, "cursor_one") != 1)
|
||||||
@ -1375,18 +1290,11 @@ test_prepared(PGconn *conn)
|
|||||||
if (PQpipelineSync(conn) != 1)
|
if (PQpipelineSync(conn) != 1)
|
||||||
pg_fatal("pipeline sync failed: %s", PQerrorMessage(conn));
|
pg_fatal("pipeline sync failed: %s", PQerrorMessage(conn));
|
||||||
|
|
||||||
res = PQgetResult(conn);
|
consume_result_status(conn, PGRES_COMMAND_OK);
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("expected non-NULL result");
|
consume_null_result(conn);
|
||||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
|
||||||
pg_fatal("expected COMMAND_OK, got %s", PQresStatus(PQresultStatus(res)));
|
consume_result_status(conn, PGRES_PIPELINE_SYNC);
|
||||||
PQclear(res);
|
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (res != NULL)
|
|
||||||
pg_fatal("expected NULL result");
|
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (PQresultStatus(res) != PGRES_PIPELINE_SYNC)
|
|
||||||
pg_fatal("expected PGRES_PIPELINE_SYNC, got %s", PQresStatus(PQresultStatus(res)));
|
|
||||||
|
|
||||||
if (PQexitPipelineMode(conn) != 1)
|
if (PQexitPipelineMode(conn) != 1)
|
||||||
pg_fatal("could not exit pipeline mode: %s", PQerrorMessage(conn));
|
pg_fatal("could not exit pipeline mode: %s", PQerrorMessage(conn));
|
||||||
@ -1395,6 +1303,7 @@ test_prepared(PGconn *conn)
|
|||||||
res = PQdescribePortal(conn, "cursor_one");
|
res = PQdescribePortal(conn, "cursor_one");
|
||||||
if (PQresultStatus(res) != PGRES_FATAL_ERROR)
|
if (PQresultStatus(res) != PGRES_FATAL_ERROR)
|
||||||
pg_fatal("expected FATAL_ERROR, got %s", PQresStatus(PQresultStatus(res)));
|
pg_fatal("expected FATAL_ERROR, got %s", PQresStatus(PQresultStatus(res)));
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Also test the blocking close, this should not fail since closing a
|
* Also test the blocking close, this should not fail since closing a
|
||||||
@ -1403,6 +1312,7 @@ test_prepared(PGconn *conn)
|
|||||||
res = PQclosePortal(conn, "cursor_one");
|
res = PQclosePortal(conn, "cursor_one");
|
||||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||||
pg_fatal("expected COMMAND_OK, got %s", PQresStatus(PQresultStatus(res)));
|
pg_fatal("expected COMMAND_OK, got %s", PQresStatus(PQresultStatus(res)));
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
fprintf(stderr, "ok\n");
|
fprintf(stderr, "ok\n");
|
||||||
}
|
}
|
||||||
@ -1509,6 +1419,10 @@ test_protocol_version(PGconn *conn)
|
|||||||
pg_fatal("expected 30002, got %d", protocol_version);
|
pg_fatal("expected 30002, got %d", protocol_version);
|
||||||
|
|
||||||
PQfinish(conn);
|
PQfinish(conn);
|
||||||
|
|
||||||
|
pfree(keywords);
|
||||||
|
pfree(vals);
|
||||||
|
PQconninfoFree(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Notice processor: print notices, and count how many we got */
|
/* Notice processor: print notices, and count how many we got */
|
||||||
@ -1525,7 +1439,6 @@ notice_processor(void *arg, const char *message)
|
|||||||
static void
|
static void
|
||||||
test_pipeline_idle(PGconn *conn)
|
test_pipeline_idle(PGconn *conn)
|
||||||
{
|
{
|
||||||
PGresult *res;
|
|
||||||
int n_notices = 0;
|
int n_notices = 0;
|
||||||
|
|
||||||
fprintf(stderr, "\npipeline idle...\n");
|
fprintf(stderr, "\npipeline idle...\n");
|
||||||
@ -1538,17 +1451,11 @@ test_pipeline_idle(PGconn *conn)
|
|||||||
if (PQsendQueryParams(conn, "SELECT 1", 0, NULL, NULL, NULL, NULL, 0) != 1)
|
if (PQsendQueryParams(conn, "SELECT 1", 0, NULL, NULL, NULL, NULL, 0) != 1)
|
||||||
pg_fatal("failed to send query: %s", PQerrorMessage(conn));
|
pg_fatal("failed to send query: %s", PQerrorMessage(conn));
|
||||||
PQsendFlushRequest(conn);
|
PQsendFlushRequest(conn);
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (res == NULL)
|
consume_result_status(conn, PGRES_TUPLES_OK);
|
||||||
pg_fatal("PQgetResult returned null when there's a pipeline item: %s",
|
|
||||||
PQerrorMessage(conn));
|
consume_null_result(conn);
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
|
||||||
pg_fatal("unexpected result code %s from first pipeline item",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
PQclear(res);
|
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (res != NULL)
|
|
||||||
pg_fatal("did not receive terminating NULL");
|
|
||||||
if (PQsendQueryParams(conn, "SELECT 2", 0, NULL, NULL, NULL, NULL, 0) != 1)
|
if (PQsendQueryParams(conn, "SELECT 2", 0, NULL, NULL, NULL, NULL, 0) != 1)
|
||||||
pg_fatal("failed to send query: %s", PQerrorMessage(conn));
|
pg_fatal("failed to send query: %s", PQerrorMessage(conn));
|
||||||
if (PQexitPipelineMode(conn) == 1)
|
if (PQexitPipelineMode(conn) == 1)
|
||||||
@ -1558,14 +1465,11 @@ test_pipeline_idle(PGconn *conn)
|
|||||||
pg_fatal("did not get expected error; got: %s",
|
pg_fatal("did not get expected error; got: %s",
|
||||||
PQerrorMessage(conn));
|
PQerrorMessage(conn));
|
||||||
PQsendFlushRequest(conn);
|
PQsendFlushRequest(conn);
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
consume_result_status(conn, PGRES_TUPLES_OK);
|
||||||
pg_fatal("unexpected result code %s from second pipeline item",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
consume_null_result(conn);
|
||||||
PQclear(res);
|
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (res != NULL)
|
|
||||||
pg_fatal("did not receive terminating NULL");
|
|
||||||
if (PQexitPipelineMode(conn) != 1)
|
if (PQexitPipelineMode(conn) != 1)
|
||||||
pg_fatal("exiting pipeline failed: %s", PQerrorMessage(conn));
|
pg_fatal("exiting pipeline failed: %s", PQerrorMessage(conn));
|
||||||
|
|
||||||
@ -1579,11 +1483,9 @@ test_pipeline_idle(PGconn *conn)
|
|||||||
if (PQsendQueryParams(conn, "SELECT pg_catalog.pg_advisory_unlock(1,1)", 0, NULL, NULL, NULL, NULL, 0) != 1)
|
if (PQsendQueryParams(conn, "SELECT pg_catalog.pg_advisory_unlock(1,1)", 0, NULL, NULL, NULL, NULL, 0) != 1)
|
||||||
pg_fatal("failed to send query: %s", PQerrorMessage(conn));
|
pg_fatal("failed to send query: %s", PQerrorMessage(conn));
|
||||||
PQsendFlushRequest(conn);
|
PQsendFlushRequest(conn);
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (res == NULL)
|
consume_result_status(conn, PGRES_TUPLES_OK);
|
||||||
pg_fatal("unexpected NULL result received");
|
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
|
||||||
pg_fatal("unexpected result code %s", PQresStatus(PQresultStatus(res)));
|
|
||||||
if (PQexitPipelineMode(conn) != 1)
|
if (PQexitPipelineMode(conn) != 1)
|
||||||
pg_fatal("failed to exit pipeline mode: %s", PQerrorMessage(conn));
|
pg_fatal("failed to exit pipeline mode: %s", PQerrorMessage(conn));
|
||||||
fprintf(stderr, "ok - 2\n");
|
fprintf(stderr, "ok - 2\n");
|
||||||
@ -1592,7 +1494,6 @@ test_pipeline_idle(PGconn *conn)
|
|||||||
static void
|
static void
|
||||||
test_simple_pipeline(PGconn *conn)
|
test_simple_pipeline(PGconn *conn)
|
||||||
{
|
{
|
||||||
PGresult *res = NULL;
|
|
||||||
const char *dummy_params[1] = {"1"};
|
const char *dummy_params[1] = {"1"};
|
||||||
Oid dummy_param_oids[1] = {INT4OID};
|
Oid dummy_param_oids[1] = {INT4OID};
|
||||||
|
|
||||||
@ -1623,20 +1524,9 @@ test_simple_pipeline(PGconn *conn)
|
|||||||
if (PQpipelineSync(conn) != 1)
|
if (PQpipelineSync(conn) != 1)
|
||||||
pg_fatal("pipeline sync failed: %s", PQerrorMessage(conn));
|
pg_fatal("pipeline sync failed: %s", PQerrorMessage(conn));
|
||||||
|
|
||||||
res = PQgetResult(conn);
|
consume_result_status(conn, PGRES_TUPLES_OK);
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("PQgetResult returned null when there's a pipeline item: %s",
|
|
||||||
PQerrorMessage(conn));
|
|
||||||
|
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
consume_null_result(conn);
|
||||||
pg_fatal("Unexpected result code %s from first pipeline item",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
|
|
||||||
PQclear(res);
|
|
||||||
res = NULL;
|
|
||||||
|
|
||||||
if (PQgetResult(conn) != NULL)
|
|
||||||
pg_fatal("PQgetResult returned something extra after first query result.");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Even though we've processed the result there's still a sync to come and
|
* Even though we've processed the result there's still a sync to come and
|
||||||
@ -1645,21 +1535,9 @@ test_simple_pipeline(PGconn *conn)
|
|||||||
if (PQexitPipelineMode(conn) != 0)
|
if (PQexitPipelineMode(conn) != 0)
|
||||||
pg_fatal("exiting pipeline mode after query but before sync succeeded incorrectly");
|
pg_fatal("exiting pipeline mode after query but before sync succeeded incorrectly");
|
||||||
|
|
||||||
res = PQgetResult(conn);
|
consume_result_status(conn, PGRES_PIPELINE_SYNC);
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("PQgetResult returned null when sync result PGRES_PIPELINE_SYNC expected: %s",
|
|
||||||
PQerrorMessage(conn));
|
|
||||||
|
|
||||||
if (PQresultStatus(res) != PGRES_PIPELINE_SYNC)
|
consume_null_result(conn);
|
||||||
pg_fatal("Unexpected result code %s instead of PGRES_PIPELINE_SYNC, error: %s",
|
|
||||||
PQresStatus(PQresultStatus(res)), PQerrorMessage(conn));
|
|
||||||
|
|
||||||
PQclear(res);
|
|
||||||
res = NULL;
|
|
||||||
|
|
||||||
if (PQgetResult(conn) != NULL)
|
|
||||||
pg_fatal("PQgetResult returned something extra after pipeline end: %s",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
|
|
||||||
/* We're still in pipeline mode... */
|
/* We're still in pipeline mode... */
|
||||||
if (PQpipelineStatus(conn) == PQ_PIPELINE_OFF)
|
if (PQpipelineStatus(conn) == PQ_PIPELINE_OFF)
|
||||||
@ -1792,20 +1670,12 @@ test_singlerowmode(PGconn *conn)
|
|||||||
pg_fatal("failed to send flush request");
|
pg_fatal("failed to send flush request");
|
||||||
if (PQsetSingleRowMode(conn) != 1)
|
if (PQsetSingleRowMode(conn) != 1)
|
||||||
pg_fatal("PQsetSingleRowMode() failed");
|
pg_fatal("PQsetSingleRowMode() failed");
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (res == NULL)
|
consume_result_status(conn, PGRES_SINGLE_TUPLE);
|
||||||
pg_fatal("unexpected NULL");
|
|
||||||
if (PQresultStatus(res) != PGRES_SINGLE_TUPLE)
|
consume_result_status(conn, PGRES_TUPLES_OK);
|
||||||
pg_fatal("Expected PGRES_SINGLE_TUPLE, got %s",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
consume_null_result(conn);
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("unexpected NULL");
|
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
|
||||||
pg_fatal("Expected PGRES_TUPLES_OK, got %s",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
if (PQgetResult(conn) != NULL)
|
|
||||||
pg_fatal("expected NULL result");
|
|
||||||
|
|
||||||
if (PQsendQueryParams(conn, "SELECT 1",
|
if (PQsendQueryParams(conn, "SELECT 1",
|
||||||
0, NULL, NULL, NULL, NULL, 0) != 1)
|
0, NULL, NULL, NULL, NULL, 0) != 1)
|
||||||
@ -1813,14 +1683,10 @@ test_singlerowmode(PGconn *conn)
|
|||||||
PQerrorMessage(conn));
|
PQerrorMessage(conn));
|
||||||
if (PQsendFlushRequest(conn) != 1)
|
if (PQsendFlushRequest(conn) != 1)
|
||||||
pg_fatal("failed to send flush request");
|
pg_fatal("failed to send flush request");
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (res == NULL)
|
consume_result_status(conn, PGRES_TUPLES_OK);
|
||||||
pg_fatal("unexpected NULL");
|
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
consume_null_result(conn);
|
||||||
pg_fatal("Expected PGRES_TUPLES_OK, got %s",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
if (PQgetResult(conn) != NULL)
|
|
||||||
pg_fatal("expected NULL result");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try chunked mode as well; make sure that it correctly delivers a
|
* Try chunked mode as well; make sure that it correctly delivers a
|
||||||
@ -1834,33 +1700,23 @@ test_singlerowmode(PGconn *conn)
|
|||||||
pg_fatal("failed to send flush request");
|
pg_fatal("failed to send flush request");
|
||||||
if (PQsetChunkedRowsMode(conn, 3) != 1)
|
if (PQsetChunkedRowsMode(conn, 3) != 1)
|
||||||
pg_fatal("PQsetChunkedRowsMode() failed");
|
pg_fatal("PQsetChunkedRowsMode() failed");
|
||||||
res = PQgetResult(conn);
|
|
||||||
if (res == NULL)
|
res = confirm_result_status(conn, PGRES_TUPLES_CHUNK);
|
||||||
pg_fatal("unexpected NULL");
|
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_CHUNK)
|
|
||||||
pg_fatal("Expected PGRES_TUPLES_CHUNK, got %s: %s",
|
|
||||||
PQresStatus(PQresultStatus(res)),
|
|
||||||
PQerrorMessage(conn));
|
|
||||||
if (PQntuples(res) != 3)
|
if (PQntuples(res) != 3)
|
||||||
pg_fatal("Expected 3 rows, got %d", PQntuples(res));
|
pg_fatal("Expected 3 rows, got %d", PQntuples(res));
|
||||||
res = PQgetResult(conn);
|
PQclear(res);
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("unexpected NULL");
|
res = confirm_result_status(conn, PGRES_TUPLES_CHUNK);
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_CHUNK)
|
|
||||||
pg_fatal("Expected PGRES_TUPLES_CHUNK, got %s",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
if (PQntuples(res) != 2)
|
if (PQntuples(res) != 2)
|
||||||
pg_fatal("Expected 2 rows, got %d", PQntuples(res));
|
pg_fatal("Expected 2 rows, got %d", PQntuples(res));
|
||||||
res = PQgetResult(conn);
|
PQclear(res);
|
||||||
if (res == NULL)
|
|
||||||
pg_fatal("unexpected NULL");
|
res = confirm_result_status(conn, PGRES_TUPLES_OK);
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
|
||||||
pg_fatal("Expected PGRES_TUPLES_OK, got %s",
|
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
if (PQntuples(res) != 0)
|
if (PQntuples(res) != 0)
|
||||||
pg_fatal("Expected 0 rows, got %d", PQntuples(res));
|
pg_fatal("Expected 0 rows, got %d", PQntuples(res));
|
||||||
if (PQgetResult(conn) != NULL)
|
PQclear(res);
|
||||||
pg_fatal("expected NULL result");
|
|
||||||
|
consume_null_result(conn);
|
||||||
|
|
||||||
if (PQexitPipelineMode(conn) != 1)
|
if (PQexitPipelineMode(conn) != 1)
|
||||||
pg_fatal("failed to end pipeline mode: %s", PQerrorMessage(conn));
|
pg_fatal("failed to end pipeline mode: %s", PQerrorMessage(conn));
|
||||||
@ -1995,9 +1851,8 @@ test_transaction(PGconn *conn)
|
|||||||
if (num_syncs <= 0)
|
if (num_syncs <= 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (PQgetResult(conn) != NULL)
|
|
||||||
pg_fatal("returned something extra after all the syncs: %s",
|
consume_null_result(conn);
|
||||||
PQresStatus(PQresultStatus(res)));
|
|
||||||
|
|
||||||
if (PQexitPipelineMode(conn) != 1)
|
if (PQexitPipelineMode(conn) != 1)
|
||||||
pg_fatal("failed to end pipeline mode: %s", PQerrorMessage(conn));
|
pg_fatal("failed to end pipeline mode: %s", PQerrorMessage(conn));
|
||||||
@ -2053,16 +1908,19 @@ test_uniqviol(PGconn *conn)
|
|||||||
"create table ppln_uniqviol(id bigint primary key, idata bigint)");
|
"create table ppln_uniqviol(id bigint primary key, idata bigint)");
|
||||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||||
pg_fatal("failed to create table: %s", PQerrorMessage(conn));
|
pg_fatal("failed to create table: %s", PQerrorMessage(conn));
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
res = PQexec(conn, "begin");
|
res = PQexec(conn, "begin");
|
||||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||||
pg_fatal("failed to begin transaction: %s", PQerrorMessage(conn));
|
pg_fatal("failed to begin transaction: %s", PQerrorMessage(conn));
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
res = PQprepare(conn, "insertion",
|
res = PQprepare(conn, "insertion",
|
||||||
"insert into ppln_uniqviol values ($1, $2) returning id",
|
"insert into ppln_uniqviol values ($1, $2) returning id",
|
||||||
2, paramTypes);
|
2, paramTypes);
|
||||||
if (res == NULL || PQresultStatus(res) != PGRES_COMMAND_OK)
|
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||||
pg_fatal("failed to prepare query: %s", PQerrorMessage(conn));
|
pg_fatal("failed to prepare query: %s", PQerrorMessage(conn));
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
if (PQenterPipelineMode(conn) != 1)
|
if (PQenterPipelineMode(conn) != 1)
|
||||||
pg_fatal("failed to enter pipeline mode");
|
pg_fatal("failed to enter pipeline mode");
|
||||||
@ -2191,7 +2049,6 @@ test_uniqviol(PGconn *conn)
|
|||||||
static bool
|
static bool
|
||||||
process_result(PGconn *conn, PGresult *res, int results, int numsent)
|
process_result(PGconn *conn, PGresult *res, int results, int numsent)
|
||||||
{
|
{
|
||||||
PGresult *res2;
|
|
||||||
bool got_error = false;
|
bool got_error = false;
|
||||||
|
|
||||||
if (res == NULL)
|
if (res == NULL)
|
||||||
@ -2203,29 +2060,19 @@ process_result(PGconn *conn, PGresult *res, int results, int numsent)
|
|||||||
got_error = true;
|
got_error = true;
|
||||||
fprintf(stderr, "result %d/%d (error): %s\n", results, numsent, PQerrorMessage(conn));
|
fprintf(stderr, "result %d/%d (error): %s\n", results, numsent, PQerrorMessage(conn));
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
|
consume_null_result(conn);
|
||||||
res2 = PQgetResult(conn);
|
|
||||||
if (res2 != NULL)
|
|
||||||
pg_fatal("expected NULL, got %s",
|
|
||||||
PQresStatus(PQresultStatus(res2)));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PGRES_TUPLES_OK:
|
case PGRES_TUPLES_OK:
|
||||||
fprintf(stderr, "result %d/%d: %s\n", results, numsent, PQgetvalue(res, 0, 0));
|
fprintf(stderr, "result %d/%d: %s\n", results, numsent, PQgetvalue(res, 0, 0));
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
|
consume_null_result(conn);
|
||||||
res2 = PQgetResult(conn);
|
|
||||||
if (res2 != NULL)
|
|
||||||
pg_fatal("expected NULL, got %s",
|
|
||||||
PQresStatus(PQresultStatus(res2)));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PGRES_PIPELINE_ABORTED:
|
case PGRES_PIPELINE_ABORTED:
|
||||||
fprintf(stderr, "result %d/%d: pipeline aborted\n", results, numsent);
|
fprintf(stderr, "result %d/%d: pipeline aborted\n", results, numsent);
|
||||||
res2 = PQgetResult(conn);
|
PQclear(res);
|
||||||
if (res2 != NULL)
|
consume_null_result(conn);
|
||||||
pg_fatal("expected NULL, got %s",
|
|
||||||
PQresStatus(PQresultStatus(res2)));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -2271,7 +2118,7 @@ main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
const char *conninfo = "";
|
const char *conninfo = "";
|
||||||
PGconn *conn;
|
PGconn *conn;
|
||||||
FILE *trace;
|
FILE *trace = NULL;
|
||||||
char *testname;
|
char *testname;
|
||||||
int numrows = 10000;
|
int numrows = 10000;
|
||||||
PGresult *res;
|
PGresult *res;
|
||||||
@ -2332,9 +2179,11 @@ main(int argc, char **argv)
|
|||||||
res = PQexec(conn, "SET lc_messages TO \"C\"");
|
res = PQexec(conn, "SET lc_messages TO \"C\"");
|
||||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||||
pg_fatal("failed to set \"lc_messages\": %s", PQerrorMessage(conn));
|
pg_fatal("failed to set \"lc_messages\": %s", PQerrorMessage(conn));
|
||||||
|
PQclear(res);
|
||||||
res = PQexec(conn, "SET debug_parallel_query = off");
|
res = PQexec(conn, "SET debug_parallel_query = off");
|
||||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||||
pg_fatal("failed to set \"debug_parallel_query\": %s", PQerrorMessage(conn));
|
pg_fatal("failed to set \"debug_parallel_query\": %s", PQerrorMessage(conn));
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
/* Set the trace file, if requested */
|
/* Set the trace file, if requested */
|
||||||
if (tracefile != NULL)
|
if (tracefile != NULL)
|
||||||
@ -2388,5 +2237,9 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
/* close the connection to the database and cleanup */
|
/* close the connection to the database and cleanup */
|
||||||
PQfinish(conn);
|
PQfinish(conn);
|
||||||
|
|
||||||
|
if (trace && trace != stdout)
|
||||||
|
fclose(trace);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user