Add regression test for batch execution.
authorHiroshi Inoue <h-inoue@dream.email.ne.jp>
Tue, 19 May 2020 12:22:17 +0000 (21:22 +0900)
committerHiroshi Inoue <h-inoue@dream.email.ne.jp>
Wed, 20 May 2020 04:56:36 +0000 (13:56 +0900)
test/expected/params-batch-exec.out [new file with mode: 0644]
test/src/params-batch-exec-test.c [new file with mode: 0644]
test/tests

diff --git a/test/expected/params-batch-exec.out b/test/expected/params-batch-exec.out
new file mode 100644 (file)
index 0000000..d00d9dd
--- /dev/null
@@ -0,0 +1,54 @@
+connected
+one by one execution
+insert into test_batch returns 1
+row 0 status=success
+row 1 status=success_with_info
+row 2 status=success
+row 3 status=success
+row 4 status=success_with_info
+row 5 status=success
+row 6 status=success
+row 7 status=success_with_info
+row 8 status=success
+row 9 status=success
+insert into test_batch returns -1
+
+22001=ERROR: value too long for type character varying(4);
+Error while executing the query
+row 0 status=success_with_info
+row 1 status=success_with_info
+row 2 status=success_with_info
+row 3 status=success_with_info
+row 4 status=success_with_info
+row 5 status=success_with_info
+row 6 status=success_with_info
+row 7 status=error
+row 8 status=unused
+row 9 status=unused
+batch execution
+insert into test_batch returns 1
+row 0 status=success_with_info
+row 1 status=success_with_info
+row 2 status=success
+row 3 status=success
+row 4 status=success_with_info
+row 5 status=success_with_info
+row 6 status=success_with_info
+row 7 status=success_with_info
+row 8 status=success
+row 9 status=success
+insert into test_batch returns -1
+
+22001=ERROR: value too long for type character varying(4);
+Error while executing the query
+row 0 status=success_with_info
+row 1 status=success_with_info
+row 2 status=success_with_info
+row 3 status=success_with_info
+row 4 status=success_with_info
+row 5 status=success_with_info
+row 6 status=error
+row 7 status=error
+row 8 status=unused
+row 9 status=unused
+disconnecting\r
diff --git a/test/src/params-batch-exec-test.c b/test/src/params-batch-exec-test.c
new file mode 100644 (file)
index 0000000..e0d9ab2
--- /dev/null
@@ -0,0 +1,129 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "common.h"
+#ifdef ODBCVER // supress warning
+#undef ODBCVER
+#endif
+#include "../../pgapifunc.h"
+
+static void b_result(SQLRETURN rc, HSTMT stmt,  int repcnt, SQLUSMALLINT status[])
+{
+   printf("insert into test_batch returns %d\n", rc);
+   if (!SQL_SUCCEEDED(rc))
+       print_diag("", SQL_HANDLE_STMT, stmt);
+   /*
+   if (SQL_SUCCESS != rc)
+       disp_stmt_error(stmt);
+   */
+   for (int i = 0; i < repcnt; i++)
+   {
+       printf("row %d status=%s\n", i,
+           (status[i] == SQL_PARAM_SUCCESS ? "success" :
+           (status[i] == SQL_PARAM_UNUSED ? "unused" :
+               (status[i] == SQL_PARAM_ERROR ? "error" :
+               (status[i] == SQL_PARAM_SUCCESS_WITH_INFO ? "success_with_info" : "????")
+                   ))));
+   }
+}
+
+#define    BATCHCNT    10
+static SQLRETURN   BatchExecute(HDBC conn, int batch_size)
+{
+   SQLRETURN   rc;
+   HSTMT       hstmt;
+   int vals[BATCHCNT] = { 0, 0, 1, 2, 2, 3, 4, 4, 5, 6};
+   SQLCHAR strs[BATCHCNT][10] = { "0", "0-2", "1", "2", "2-2", "3", "4", "4-2", "5", "6" };
+   SQLUSMALLINT    status[BATCHCNT];
+
+   rc = SQLSetConnectAttr(conn, SQL_ATTR_PGOPT_BATCHSIZE, (SQLPOINTER)(SQLLEN)batch_size, 0);
+   if (!SQL_SUCCEEDED(rc))
+   {
+       print_diag("SQLSetConnectAttr SQL_ATTR_PGOPT_BATCHSIZE failed", SQL_HANDLE_DBC, conn);
+       exit(1);
+   }
+
+   rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
+
+   SQLSetStmtAttr(hstmt , SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER)BATCHCNT, 0);
+   SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_STATUS_PTR, status, 0);
+   rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, vals, 0, NULL);
+   CHECK_STMT_RESULT(rc, "SQLBindParameter 1 failed", hstmt);
+   rc = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(strs[0]), 0, strs, sizeof(strs[0]), NULL);
+   CHECK_STMT_RESULT(rc, "SQLBindParameter 2 failed", hstmt);
+   rc = SQLExecDirect(hstmt, "INSERT INTO test_batch VALUES (?, ?)"
+       " ON CONFLICT (id) DO UPDATE SET dt=EXCLUDED.dt"
+       , SQL_NTS);
+   b_result(rc, hstmt, BATCHCNT, status);
+   /**
+   rc = SQLExecDirect(hstmt, "SELECT * FROM test_batch where id=?"
+       , SQL_NTS);
+   b_result(rc, hstmt, BATCHCNT, status);
+   SQLCloseCursor(hstmt);
+   **/
+   strncpy((LPTSTR) &strs[BATCHCNT - 3], "4-long", sizeof(strs[0]));
+   rc = SQLExecDirect(hstmt, "INSERT INTO test_batch VALUES (?, ?)"
+       " ON CONFLICT (id) DO UPDATE SET dt=EXCLUDED.dt"
+       , SQL_NTS);
+   b_result(rc, hstmt, BATCHCNT, status);
+
+   rc = SQLFreeStmt(hstmt, SQL_DROP);
+   CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
+
+   return rc;
+}
+
+int main(int argc, char **argv)
+{
+   SQLRETURN rc;
+   HSTMT hstmt = SQL_NULL_HSTMT;
+
+   test_connect();
+
+   rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
+   if (!SQL_SUCCEEDED(rc))
+   {
+       print_diag("failed to allocate stmt handle", SQL_HANDLE_DBC, conn);
+       exit(1);
+   }
+
+   /* Drop the existent tables */
+   rc = SQLExecDirect(hstmt, "drop table if exists test_batch", SQL_NTS);
+   CHECK_STMT_RESULT(rc, "drop table failed", hstmt);
+   /* Create temp table */
+   rc = SQLExecDirect(hstmt, "create temporary table test_batch(id int4 primary key, dt varchar(4))", SQL_NTS);
+   CHECK_STMT_RESULT(rc, "create table failed", hstmt);
+   /* Create function */
+   rc = SQLExecDirect(hstmt,
+       "CREATE OR REPLACE FUNCTION batch_update_notice() RETURNS TRIGGER"
+       " AS $$"
+       " BEGIN"
+       "  RAISE NOTICE 'id=% updated', NEW.id;"
+       "  RETURN NULL;"
+       " END;"
+       " $$ LANGUAGE plpgsql"
+       , SQL_NTS);
+   CHECK_STMT_RESULT(rc, "create function failed", hstmt);
+   /* Create trigger */
+   rc = SQLExecDirect(hstmt,
+       "CREATE TRIGGER batch_update_notice"
+       " BEFORE update on test_batch"
+       " FOR EACH ROW EXECUTE PROCEDURE batch_update_notice()"
+       , SQL_NTS);
+   CHECK_STMT_RESULT(rc, "create trigger failed", hstmt);
+
+   /* 1 by 1 executiton */
+   printf("one by one execution\n");
+   BatchExecute(conn, 1);
+   /* Truncate table */
+   rc = SQLExecDirect(hstmt, "truncate table test_batch", SQL_NTS);
+   CHECK_STMT_RESULT(rc, "truncate table failed", hstmt);
+   /* batch executiton batch_size=2*/
+   printf("batch execution\n");
+   BatchExecute(conn, 2);
+
+   /* Clean up */
+   test_disconnect();
+
+   return 0;
+}
index e6e195c09a3dfe2f9a3036ca7fe2cd7f181d84c6..8d960397173f722a1ac12a0cd7cbbcbe28d37be9 100644 (file)
@@ -52,4 +52,5 @@ TESTBINS = exe/connect-test \
    exe/large-object-test \
    exe/large-object-data-at-exec-test \
    exe/odbc-escapes-test \
-   exe/wchar-char-test
+   exe/wchar-char-test \
+   exe/params-batch-exec-test