21#include "catalog/pg_type_d.h"
39#define pg_debug(...) do { fprintf(stderr, __VA_ARGS__); } while (0)
45"DROP TABLE IF EXISTS pq_pipeline_demo";
47"CREATE UNLOGGED TABLE pq_pipeline_demo(id serial primary key, itemno integer,"
50"INSERT INTO pq_pipeline_demo(itemno) VALUES ($1)";
52"INSERT INTO pq_pipeline_demo(itemno,int8filler) VALUES ($1, $2)";
73#define pg_fatal(...) pg_fatal_impl(__LINE__, __VA_ARGS__)
94#define confirm_result_status(conn, status) confirm_result_status_impl(__LINE__, conn, status)
102 pg_fatal_impl(line,
"PQgetResult returned null unexpectedly: %s",
105 pg_fatal_impl(line,
"PQgetResult returned status %s, expected %s: %s",
116#define consume_result_status(conn, status) consume_result_status_impl(__LINE__, conn, status)
129#define consume_null_result(conn) consume_null_result_impl(__LINE__, conn)
145#define consume_query_cancel(conn) consume_query_cancel_impl(__LINE__, conn)
153 pg_fatal_impl(line,
"query failed with a different error than cancellation: %s",
168 char *
state,
char *event)
186 "SELECT count(*) FROM pg_stat_activity WHERE "
187 "pid = $1 AND state = $2",
191 "SELECT count(*) FROM pg_stat_activity WHERE "
192 "pid = $1 AND wait_event = $2",
216#define send_cancellable_query(conn, monitorConn) \
217 send_cancellable_query_impl(__LINE__, conn, monitorConn)
281 pg_fatal(
"Connection to database failed: %s",
467 pg_fatal(
"Expected blocking connection mode");
470 pg_fatal(
"Unable to enter pipeline mode");
473 pg_fatal(
"Pipeline mode not activated properly");
478 pg_fatal(
"PQexec should fail in pipeline mode but succeeded");
480 "synchronous command execution functions are not allowed in pipeline mode\n") != 0)
481 pg_fatal(
"did not get expected error message; got: \"%s\"",
487 pg_fatal(
"PQsendQuery should fail in pipeline mode but succeeded");
489 "PQsendQuery not allowed in pipeline mode\n") != 0)
490 pg_fatal(
"did not get expected error message; got: \"%s\"",
495 pg_fatal(
"re-entering pipeline mode should be a no-op but failed");
498 pg_fatal(
"PQisBusy should return 0 when idle in pipeline mode, returned 1");
502 pg_fatal(
"couldn't exit idle empty pipeline mode");
505 pg_fatal(
"Pipeline mode not terminated properly");
509 pg_fatal(
"pipeline mode exit when not in pipeline mode should succeed but failed");
514 pg_fatal(
"PQexec should succeed after exiting pipeline mode but failed with: %s",
569 pg_fatal(
"exiting pipeline mode after query but before sync succeeded incorrectly");
579 pg_fatal(
"exiting pipeline mode after query but before sync succeeded incorrectly");
592 pg_fatal(
"Fell out of pipeline mode somehow");
596 pg_fatal(
"attempt to exit pipeline mode failed when it should've succeeded: %s",
600 pg_fatal(
"exiting pipeline mode didn't seem to work");
622 pg_fatal(
"could not enter pipeline mode");
651 pg_fatal(
"failed to send flush request");
733 pg_fatal(
"dispatching second-pipeline insert failed: %s",
765 pg_fatal(
"pipeline should be flagged as aborted but isn't");
774 pg_fatal(
"pipeline should be flagged as aborted but isn't");
778 pg_fatal(
"Fell out of pipeline mode somehow");
789 pg_fatal(
"sync should've cleared the aborted flag but didn't");
793 pg_fatal(
"Fell out of pipeline mode somehow");
819 pg_fatal(
"expected error about multiple commands, got %s",
831 pg_fatal(
"did not get cannot-insert-multiple-commands error");
857 pg_fatal(
"expected division-by-zero, got: %s (%s)",
860 printf(
"got expected division-by-zero\n");
869 pg_fatal(
"did not get division-by-zero error");
878 pg_fatal(
"Fell out of pipeline mode somehow");
882 pg_fatal(
"attempt to exit pipeline mode failed when it should've succeeded: %s",
886 pg_fatal(
"exiting pipeline mode didn't seem to work");
903 res =
PQexec(
conn,
"SELECT itemno FROM pq_pipeline_demo");
906 pg_fatal(
"Expected tuples, got %s: %s",
915 pg_fatal(
"expected only insert with value 3, got %s",
val);
966 sql =
"BEGIN TRANSACTION";
1096 pg_fatal(
"%s reported status %s, expected %s\n"
1097 "Error message: \"%s\"",
1102 pg_fatal(
"%s expected command tag '%s', got '%s'",
1159 fprintf(stdout,
"pipeline sync sent\n");
1173 pg_fatal(
"attempt to exit pipeline mode failed when it should've succeeded: %s",
1213 pg_fatal(
"expected %zu columns, got %d",
1219 pg_fatal(
"field %d: expected type %u, got %u",
1265 res =
PQexec(
conn,
"DECLARE cursor_one CURSOR FOR SELECT 1");
1279 pg_fatal(
"portal: expected type %u, got %u",
1330 int protocol_version;
1352 if (
strcmp(opt->keyword,
"max_protocol_version") == 0)
1372 pg_fatal(
"Connection to database failed: %s",
1376 if (protocol_version != 30000)
1377 pg_fatal(
"expected 30000, got %d", protocol_version);
1388 pg_fatal(
"Connection to database failed: %s",
1392 if (protocol_version != 30000)
1393 pg_fatal(
"expected 30000, got %d", protocol_version);
1405 pg_fatal(
"Connecting with max_protocol_version 3.1 should have failed.");
1416 pg_fatal(
"Connection to database failed: %s",
1420 if (protocol_version != 30002)
1421 pg_fatal(
"expected 30002, got %d", protocol_version);
1432 pg_fatal(
"Connection to database failed: %s",
1436 if (protocol_version != 30002)
1437 pg_fatal(
"expected 30002, got %d", protocol_version);
1480 pg_fatal(
"exiting pipeline succeeded when it shouldn't");
1482 strlen(
"cannot exit pipeline mode")) != 0)
1483 pg_fatal(
"did not get expected error; got: %s",
1529 pg_fatal(
"Expected blocking connection mode");
1540 pg_fatal(
"exiting pipeline mode with work in progress should fail, but succeeded");
1554 pg_fatal(
"exiting pipeline mode after query but before sync succeeded incorrectly");
1562 pg_fatal(
"Fell out of pipeline mode somehow");
1566 pg_fatal(
"attempt to exit pipeline mode failed when it should've succeeded: %s",
1570 pg_fatal(
"Exiting pipeline mode didn't seem to work");
1583 pg_fatal(
"failed to enter pipeline mode: %s",
1587 for (
i = 0;
i < 3;
i++)
1594 "SELECT generate_series(42, $1)",
1597 (
const char *
const *) param,
1601 pg_fatal(
"failed to send query: %s",
1618 pg_fatal(
"PQsetSingleRowMode() failed for i=%d",
i);
1633 pg_fatal(
"Expected three results, got %d",
i);
1641 pg_fatal(
"Expected PGRES_SINGLE_TUPLE for query %d, got %s",
1644 pg_fatal(
"Expected PGRES_TUPLES_OK for query %d, got %s",
1660 pg_fatal(
"Expected to follow PGRES_SINGLE_TUPLE, but received PGRES_TUPLES_OK directly instead");
1675 pg_fatal(
"didn't get expected terminating TUPLES_OK");
1685 pg_fatal(
"failed to send query: %s",
1688 pg_fatal(
"failed to send flush request");
1690 pg_fatal(
"PQsetSingleRowMode() failed");
1700 pg_fatal(
"failed to send query: %s",
1703 pg_fatal(
"failed to send flush request");
1715 pg_fatal(
"failed to send query: %s",
1718 pg_fatal(
"failed to send flush request");
1720 pg_fatal(
"PQsetChunkedRowsMode() failed");
1756 res =
PQexec(
conn,
"DROP TABLE IF EXISTS pq_pipeline_tst;"
1757 "CREATE TABLE pq_pipeline_tst (id int)");
1759 pg_fatal(
"failed to create test table: %s",
1764 pg_fatal(
"failed to enter pipeline mode: %s",
1767 pg_fatal(
"could not send prepare on pipeline: %s",
1773 pg_fatal(
"failed to send query: %s",
1778 pg_fatal(
"failed to send query: %s",
1786 pg_fatal(
"failed to execute prepared: %s",
1791 "INSERT INTO pq_pipeline_tst VALUES (1)",
1793 pg_fatal(
"failed to send query: %s",
1804 "INSERT INTO pq_pipeline_tst VALUES (2)",
1806 pg_fatal(
"failed to send query: %s",
1817 pg_fatal(
"failed to execute prepared: %s",
1825 "INSERT INTO pq_pipeline_tst VALUES (3)",
1827 pg_fatal(
"failed to send query: %s",
1838 for (
int i = 0;;
i++)
1845 printf(
"%d: got NULL result\n",
i);
1847 pg_fatal(
"did not expect NULL here");
1859 printf(
": command didn't run because pipeline aborted\n");
1879 res =
PQexec(
conn,
"SELECT * FROM pq_pipeline_tst");
1885 pg_fatal(
"did not get expected tuple");
1925 res =
PQexec(
conn,
"drop table if exists ppln_uniqviol;"
1926 "create table ppln_uniqviol(id bigint primary key, idata bigint)");
1937 "insert into ppln_uniqviol values ($1, $2) returning id",
1944 pg_fatal(
"failed to enter pipeline mode");
2032 pg_fatal(
"failed to send flush request");
2056 pg_fatal(
"did not get expected error");
2112 fprintf(
stderr,
" -t TRACEFILE generate a libpq trace to TRACEFILE\n");
2113 fprintf(
stderr,
" -r NUMROWS use NUMROWS as the test size\n");
2120 printf(
"disallowed_in_pipeline\n");
2121 printf(
"multi_pipelines\n");
2123 printf(
"pipeline_abort\n");
2124 printf(
"pipeline_idle\n");
2125 printf(
"pipelined_insert\n");
2127 printf(
"protocol_version\n");
2128 printf(
"simple_pipeline\n");
2137 const char *conninfo =
"";
2141 int numrows = 10000;
2145 while ((
c =
getopt(argc, argv,
"r:t:")) != -1)
2152 if (
errno != 0 || numrows <= 0)
2154 fprintf(
stderr,
"couldn't parse \"%s\" as a positive integer\n",
2197 res =
PQexec(
conn,
"SET lc_messages TO \"C\"");
2201 res =
PQexec(
conn,
"SET debug_parallel_query = off");
#define Assert(condition)
#define pg_attribute_printf(f, a)
static PGcancel *volatile cancelConn
#define fprintf(file, fmt, msg)
PGcancel * PQgetCancel(PGconn *conn)
void PQcancelReset(PGcancelConn *cancelConn)
PGcancelConn * PQcancelCreate(PGconn *conn)
ConnStatusType PQcancelStatus(const PGcancelConn *cancelConn)
int PQcancelBlocking(PGcancelConn *cancelConn)
int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
PostgresPollingStatusType PQcancelPoll(PGcancelConn *cancelConn)
void PQcancelFinish(PGcancelConn *cancelConn)
int PQrequestCancel(PGconn *conn)
void PQfreeCancel(PGcancel *cancel)
int PQcancelSocket(const PGcancelConn *cancelConn)
char * PQcancelErrorMessage(const PGcancelConn *cancelConn)
int PQcancelStart(PGcancelConn *cancelConn)
int PQfullProtocolVersion(const PGconn *conn)
PGconn * PQconnectdb(const char *conninfo)
PQconninfoOption * PQconninfo(PGconn *conn)
void PQconninfoFree(PQconninfoOption *connOptions)
ConnStatusType PQstatus(const PGconn *conn)
void PQfinish(PGconn *conn)
int PQbackendPID(const PGconn *conn)
PGpipelineStatus PQpipelineStatus(const PGconn *conn)
PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg)
char * PQerrorMessage(const PGconn *conn)
int PQsocket(const PGconn *conn)
PGconn * PQconnectdbParams(const char *const *keywords, const char *const *values, int expand_dbname)
int PQsendQueryParams(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
int PQsetSingleRowMode(PGconn *conn)
int PQflush(PGconn *conn)
Oid PQftype(const PGresult *res, int field_num)
PGresult * PQdescribePrepared(PGconn *conn, const char *stmt)
PGresult * PQexecParams(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
int PQexitPipelineMode(PGconn *conn)
int PQsendClosePortal(PGconn *conn, const char *portal)
int PQenterPipelineMode(PGconn *conn)
PGresult * PQclosePrepared(PGconn *conn, const char *stmt)
PGresult * PQclosePortal(PGconn *conn, const char *portal)
int PQsendClosePrepared(PGconn *conn, const char *stmt)
int PQsendPipelineSync(PGconn *conn)
PGresult * PQprepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
int PQsendDescribePrepared(PGconn *conn, const char *stmt)
int PQconsumeInput(PGconn *conn)
int PQsetnonblocking(PGconn *conn, int arg)
int PQsendPrepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
PGresult * PQdescribePortal(PGconn *conn, const char *portal)
int PQsetChunkedRowsMode(PGconn *conn, int chunkSize)
int PQsendQuery(PGconn *conn, const char *query)
int PQpipelineSync(PGconn *conn)
int PQsendDescribePortal(PGconn *conn, const char *portal)
char * PQresStatus(ExecStatusType status)
int PQisBusy(PGconn *conn)
PGresult * PQexec(PGconn *conn, const char *query)
int PQsendQueryPrepared(PGconn *conn, const char *stmtName, int nParams, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
int PQsendFlushRequest(PGconn *conn)
int PQisnonblocking(const PGconn *conn)
void PQtrace(PGconn *conn, FILE *debug_port)
void PQsetTraceFlags(PGconn *conn, int flags)
void * pg_malloc(size_t size)
char * pg_strdup(const char *in)
void * pg_malloc0(size_t size)
static const JsonPathKeyword keywords[]
#define PQresultErrorField
#define PQTRACE_SUPPRESS_TIMESTAMPS
PostgresPollingStatusType
#define PQTRACE_REGRESS_MODE
static void print_test_list(void)
static const char *const insert_sql2
static void wait_for_connection_state(int line, PGconn *monitorConn, int procpid, char *state, char *event)
#define consume_query_cancel(conn)
static void exit_nicely(PGconn *conn)
static void test_uniqviol(PGconn *conn)
static void send_cancellable_query_impl(int line, PGconn *conn, PGconn *monitorConn)
static void test_simple_pipeline(PGconn *conn)
static pg_noreturn void static bool process_result(PGconn *conn, PGresult *res, int results, int numsent)
static void test_multi_pipelines(PGconn *conn)
static void test_pipeline_idle(PGconn *conn)
static const char *const create_table_sql
static void consume_result_status_impl(int line, PGconn *conn, ExecStatusType status)
static const char *const insert_sql
static void consume_null_result_impl(int line, PGconn *conn)
static void test_protocol_version(PGconn *conn)
static void test_nosync(PGconn *conn)
#define consume_null_result(conn)
static PGresult * confirm_result_status_impl(int line, PGconn *conn, ExecStatusType status)
#define confirm_result_status(conn, status)
static const char *const progname
static void test_pipeline_abort(PGconn *conn)
static pg_noreturn void pg_fatal_impl(int line, const char *fmt,...) pg_attribute_printf(2
static const char *const drop_table_sql
#define send_cancellable_query(conn, monitorConn)
static void notice_processor(void *arg, const char *message)
#define consume_result_status(conn, status)
static void test_transaction(PGconn *conn)
static PGconn * copy_connection(PGconn *conn)
static void test_prepared(PGconn *conn)
static void test_cancel(PGconn *conn)
static void test_singlerowmode(PGconn *conn)
static void consume_query_cancel_impl(int line, PGconn *conn)
static void test_disallowed_in_pipeline(PGconn *conn)
static void test_pipelined_insert(PGconn *conn, int n_rows)
void pfree(void *pointer)
static AmcheckOptions opts
int getopt(int nargc, char *const *nargv, const char *ostr)
PGDLLIMPORT char * optarg
char * psprintf(const char *fmt,...)
void pg_usleep(long microsec)
#define select(n, r, w, e, timeout)