TAP test now checks multi-statement

v2.x_pg_PrepStmtBase_240714
Rahim Kanji 2 years ago
parent b01792cae9
commit 2766627b3f

@ -25,6 +25,15 @@
res; \
})
#define PQSENDQUERY(conn,query) ({int send_status = PQsendQuery(conn,query); \
if (send_status != 1) { \
fprintf(stderr, "File %s, line %d, status %d, %s\n", \
__FILE__, __LINE__, status, PQerrorMessage(conn)); \
} \
send_status; \
})
CommandLine cl;
PGconn* create_new_connection(bool with_ssl) {
@ -35,18 +44,18 @@ PGconn* create_new_connection(bool with_ssl) {
if (with_ssl) {
ss << " sslmode=require";
} else {
} else {
ss << " sslmode=disable";
}
PGconn* conn = PQconnectdb(ss.str().c_str());
}
PGconn* conn = PQconnectdb(ss.str().c_str());
const bool res = (conn && PQstatus(conn) == CONNECTION_OK);
ok(res, "Connection created successfully. %s", PQerrorMessage(conn));
if (res) return conn;
PQfinish(conn);
return nullptr;
PQfinish(conn);
return nullptr;
}
// Function to set up the test environment
@ -259,6 +268,324 @@ void test_constraint_violation(PGconn* conn) {
PQclear(res);
}
void test_multi_statement_transaction(PGconn* conn) {
PGresult* res;
int status;
// Execute multi-statement transaction
status = PQsendQuery(conn, "BEGIN; "
"INSERT INTO test_table (value) VALUES ('multi statement'); "
"UPDATE test_table SET value = 'multi statement updated' WHERE value = 'multi statement'; "
"COMMIT;");
ok(status == 1, "Multi-statement transaction sent");
PQconsumeInput(conn);
while (PQisBusy(conn)) {
PQconsumeInput(conn);
}
// Check result of BEGIN
res = PQgetResult(conn);
ok(PQresultStatus(res) == PGRES_COMMAND_OK, "BEGIN executed successfully");
PQclear(res);
// Check result of INSERT
res = PQgetResult(conn);
ok(PQresultStatus(res) == PGRES_COMMAND_OK, "INSERT executed successfully");
PQclear(res);
// Check result of UPDATE
res = PQgetResult(conn);
ok(PQresultStatus(res) == PGRES_COMMAND_OK, "UPDATE executed successfully");
PQclear(res);
// Check result of COMMIT
res = PQgetResult(conn);
ok(PQresultStatus(res) == PGRES_COMMAND_OK, "COMMIT executed successfully");
PQclear(res);
res = PQgetResult(conn);
ok(PQtransactionStatus(conn) == PQTRANS_IDLE, "Connection in Idle state");
// Verify the results
status = PQsendQuery(conn, "SELECT value FROM test_table WHERE value = 'multi statement updated'");
ok(status == 1, "Verification query sent");
PQconsumeInput(conn);
while (PQisBusy(conn)) {
PQconsumeInput(conn);
}
res = PQgetResult(conn);
if (PQresultStatus(res) == PGRES_TUPLES_OK) {
int nRows = PQntuples(res);
ok(nRows == 1, "Multi-statement transaction committed correctly");
char* result = PQgetvalue(res, 0, 0);
ok(strcmp(result, "multi statement updated") == 0, "Multi-statement transaction result is correct");
} else {
ok(0, "Failed to verify multi-statement transaction");
}
PQclear(res);
PQgetResult(conn);
}
void test_multi_statement_transaction_with_error(PGconn* conn) {
PGresult* res;
int status;
// Execute multi-statement transaction with an error
status = PQSENDQUERY(conn, "BEGIN; "
"INSERT INTO test_table (value) VALUES ('multi statement error'); "
"UPDATE test_table SET value = 'multi statement error updated' WHERE value = 'multi statement error'; "
"INSERT INTO test_table (non_existent_column) VALUES ('error'); "
"COMMIT;");
ok(status == 1, "Multi-statement transaction with error sent");
PQconsumeInput(conn);
while (PQisBusy(conn)) {
PQconsumeInput(conn);
}
// Check result of BEGIN
res = PQgetResult(conn);
ok(PQresultStatus(res) == PGRES_COMMAND_OK, "BEGIN executed successfully");
PQclear(res);
// Check result of INSERT
res = PQgetResult(conn);
ok(PQresultStatus(res) == PGRES_COMMAND_OK, "INSERT executed successfully");
PQclear(res);
// Check result of UPDATE
res = PQgetResult(conn);
ok(PQresultStatus(res) == PGRES_COMMAND_OK, "UPDATE executed successfully");
PQclear(res);
// Check result of erroneous INSERT
res = PQgetResult(conn);
ok(PQresultStatus(res) == PGRES_FATAL_ERROR, "Erroneous INSERT failed as expected");
PQclear(res);
PQgetResult(conn);
// Ensure the transaction is in error state
ok(PQtransactionStatus(conn) == PQTRANS_INERROR, "Connection in Error Transaction state");
// Rollback the transaction
status = PQsendQuery(conn, "ROLLBACK");
ok(status == 1, "ROLLBACK sent");
PQconsumeInput(conn);
while (PQisBusy(conn)) {
PQconsumeInput(conn);
}
res = PQgetResult(conn);
ok(PQresultStatus(res) == PGRES_COMMAND_OK, "ROLLBACK executed successfully");
PQclear(res);
PQgetResult(conn);
ok(PQtransactionStatus(conn) == PQTRANS_IDLE, "Connection in Idle state");
// Verify the results
status = PQsendQuery(conn, "SELECT value FROM test_table WHERE value = 'multi statement error' OR value = 'multi statement error updated'");
ok(status == 1, "Verification query sent");
PQconsumeInput(conn);
while (PQisBusy(conn)) {
PQconsumeInput(conn);
}
res = PQgetResult(conn);
if (PQresultStatus(res) == PGRES_TUPLES_OK) {
int nRows = PQntuples(res);
ok(nRows == 0, "Multi-statement transaction with error rolled back correctly");
} else {
ok(0, "Failed to verify rollback of multi-statement transaction with error");
}
PQclear(res);
PQgetResult(conn);
}
void test_multi_statement_select_insert(PGconn* conn) {
PGresult* res;
int status;
// Execute multi-statement SELECT and INSERT
status = PQsendQuery(conn, "SELECT value FROM test_table WHERE id = 1; "
"INSERT INTO test_table (value) VALUES ('multi statement select insert');");
ok(status == 1, "Multi-statement SELECT and INSERT sent");
PQconsumeInput(conn);
while (PQisBusy(conn)) {
PQconsumeInput(conn);
}
// Check result of SELECT
res = PQgetResult(conn);
ok(PQresultStatus(res) == PGRES_TUPLES_OK, "SELECT executed successfully");
PQclear(res);
// Check result of INSERT
res = PQgetResult(conn);
ok(PQresultStatus(res) == PGRES_COMMAND_OK, "INSERT executed successfully");
PQclear(res);
PQgetResult(conn);
// Verify the results
status = PQsendQuery(conn, "SELECT value FROM test_table WHERE value = 'multi statement select insert'");
ok(status == 1, "Verification query sent");
PQconsumeInput(conn);
while (PQisBusy(conn)) {
PQconsumeInput(conn);
}
res = PQgetResult(conn);
if (PQresultStatus(res) == PGRES_TUPLES_OK) {
int nRows = PQntuples(res);
ok(nRows == 1, "Multi-statement SELECT and INSERT committed correctly");
char* result = PQgetvalue(res, 0, 0);
ok(strcmp(result, "multi statement select insert") == 0, "Multi-statement SELECT and INSERT result is correct");
} else {
ok(0, "Failed to verify multi-statement SELECT and INSERT");
}
PQclear(res);
PQgetResult(conn);
}
void test_multi_statement_delete_update(PGconn* conn) {
PGresult* res;
int status;
// Execute multi-statement DELETE and UPDATE
status = PQsendQuery(conn, "DELETE FROM test_table WHERE value = 'test1'; "
"UPDATE test_table SET value = 'multi statement delete update' WHERE value = 'test4';");
ok(status == 1, "Multi-statement DELETE and UPDATE sent");
PQconsumeInput(conn);
while (PQisBusy(conn)) {
PQconsumeInput(conn);
}
// Check result of DELETE
res = PQgetResult(conn);
ok(PQresultStatus(res) == PGRES_COMMAND_OK, "DELETE executed successfully");
PQclear(res);
// Check result of UPDATE
res = PQgetResult(conn);
ok(PQresultStatus(res) == PGRES_COMMAND_OK, "UPDATE executed successfully");
PQclear(res);
PQgetResult(conn);
// Verify the results
status = PQsendQuery(conn, "SELECT value FROM test_table WHERE value = 'multi statement delete update'");
ok(status == 1, "Verification query sent");
PQconsumeInput(conn);
while (PQisBusy(conn)) {
PQconsumeInput(conn);
}
res = PQgetResult(conn);
if (PQresultStatus(res) == PGRES_TUPLES_OK) {
int nRows = PQntuples(res);
ok(nRows == 1, "Multi-statement DELETE and UPDATE committed correctly");
char* result = PQgetvalue(res, 0, 0);
ok(strcmp(result, "multi statement delete update") == 0, "Multi-statement DELETE and UPDATE result is correct");
} else {
ok(0, "Failed to verify multi-statement DELETE and UPDATE");
}
PQclear(res);
PQgetResult(conn);
}
void test_multi_statement_with_error(PGconn* conn) {
PGresult* res;
int status;
// Execute multi-statement with an error
status = PQsendQuery(conn, "INSERT INTO test_table (value) VALUES ('multi statement error'); "
"UPDATE test_table SET value = 'multi statement error updated' WHERE value = 'multi statement error'; "
"INSERT INTO test_table (non_existent_column) VALUES ('error');");
ok(status == 1, "Multi-statement with error sent");
PQconsumeInput(conn);
while (PQisBusy(conn)) {
PQconsumeInput(conn);
}
// Check result of INSERT
res = PQgetResult(conn);
ok(PQresultStatus(res) == PGRES_COMMAND_OK, "INSERT executed successfully");
PQclear(res);
// Check result of UPDATE
res = PQgetResult(conn);
ok(PQresultStatus(res) == PGRES_COMMAND_OK, "UPDATE executed successfully");
PQclear(res);
// Check result of erroneous INSERT
res = PQgetResult(conn);
ok(PQresultStatus(res) == PGRES_FATAL_ERROR, "Erroneous INSERT failed as expected");
PQclear(res);
PQgetResult(conn);
// Verify the results
status = PQsendQuery(conn, "SELECT value FROM test_table WHERE value = 'multi statement error' OR value = 'multi statement error updated'");
ok(status == 1, "Verification query sent");
PQconsumeInput(conn);
while (PQisBusy(conn)) {
PQconsumeInput(conn);
}
res = PQgetResult(conn);
if (PQresultStatus(res) == PGRES_TUPLES_OK) {
int nRows = PQntuples(res);
ok(nRows == 0, "No rows are inserted or updated");
} else {
ok(0, "Failed to verify rows from multi-statement with error");
}
PQclear(res);
PQgetResult(conn);
}
void test_multi_statement_insert_select_select(PGconn* conn) {
PGresult* res;
int status;
// Execute multi-statement INSERT, SELECT, and SELECT
status = PQsendQuery(conn, "INSERT INTO test_table (value) VALUES ('multi statement select1'), ('multi statement select2'); "
"SELECT value FROM test_table WHERE value = 'multi statement select1'; "
"SELECT value FROM test_table WHERE value = 'multi statement select2';");
ok(status == 1, "Multi-statement INSERT and SELECTs sent");
PQconsumeInput(conn);
while (PQisBusy(conn)) {
PQconsumeInput(conn);
}
// Check result of the INSERT
res = PQgetResult(conn);
ok(PQresultStatus(res) == PGRES_COMMAND_OK, "INSERT executed successfully");
PQclear(res);
// Check result of the first SELECT
res = PQgetResult(conn);
if (PQresultStatus(res) == PGRES_TUPLES_OK) {
int nRows = PQntuples(res);
ok(nRows == 1, "First SELECT executed successfully");
if (nRows > 0) {
char* result = PQgetvalue(res, 0, 0);
ok(strcmp(result, "multi statement select1") == 0, "First SELECT result is correct");
}
} else {
ok(0, "First SELECT failed");
}
PQclear(res);
// Check result of the second SELECT
res = PQgetResult(conn);
if (PQresultStatus(res) == PGRES_TUPLES_OK) {
int nRows = PQntuples(res);
ok(nRows == 1, "Second SELECT executed successfully");
if (nRows > 0) {
char* result = PQgetvalue(res, 0, 0);
ok(strcmp(result, "multi statement select2") == 0, "Second SELECT result is correct");
}
} else {
ok(0, "Second SELECT failed");
}
PQclear(res);
PQgetResult(conn);
}
void teardown_database(PGconn* conn) {
PGresult* res;
@ -271,7 +598,7 @@ void test_invalid_connection(bool with_ssl) {
std::stringstream ss;
ss << "host=invalid_host port=invalid_port dbname=invalid_db user=invalid_user password=invalid_password";
if (with_ssl) {
ss << " sslmode=require";
} else {
@ -300,6 +627,12 @@ void execute_tests(bool with_ssl) {
test_transaction_error(conn);
test_null_value(conn);
test_constraint_violation(conn);
test_multi_statement_transaction(conn);
test_multi_statement_transaction_with_error(conn);
test_multi_statement_select_insert(conn);
test_multi_statement_delete_update(conn);
test_multi_statement_with_error(conn);
test_multi_statement_insert_select_select(conn);
teardown_database(conn);
test_invalid_connection(with_ssl);
@ -307,8 +640,8 @@ void execute_tests(bool with_ssl) {
}
int main(int argc, char** argv) {
plan(88); // Total number of tests planned
plan(176); // Total number of tests planned
if (cl.getEnv())
return exit_status();

Loading…
Cancel
Save