167 lines
5.7 KiB
Diff
167 lines
5.7 KiB
Diff
From c15f7cfea5c2974d4d66ebb8c63594283eca6c30 Mon Sep 17 00:00:00 2001
|
|
From: Hiroshi Inoue <h-inoue@dream.email.ne.jp>
|
|
Date: Sat, 26 Mar 2016 22:20:38 +0900
|
|
Subject: [PATCH] Add test declare-block-test. It contains 3 cases which
|
|
correspond to bugs introduced in 9.05.0100. They are all in declare/fetch
|
|
mode. 1. Using block cursors. 2. Scroll BOF -> EOF -> BOF ... 3. When
|
|
fetching a row "behind" the rowset by "fetch absolute", how many rows can be
|
|
fetched?
|
|
|
|
---
|
|
test/expected/declare-fetch-block.out | 10 +++
|
|
test/src/declare-fetch-block-test.c | 125 ++++++++++++++++++++++++++++++++++
|
|
2 files changed, 135 insertions(+)
|
|
create mode 100644 test/expected/declare-fetch-block.out
|
|
create mode 100644 test/src/declare-fetch-block-test.c
|
|
|
|
diff --git a/test/expected/declare-fetch-block.out b/test/expected/declare-fetch-block.out
|
|
new file mode 100644
|
|
index 0000000..2368b59
|
|
--- /dev/null
|
|
+++ b/test/expected/declare-fetch-block.out
|
|
@@ -0,0 +1,10 @@
|
|
+connected
|
|
+fetchIdx=1, fetched rows=84, total rows=84
|
|
+fetchIdx=2, fetched rows=36, total rows=120
|
|
+next total rows=120
|
|
+prior total rows=120
|
|
+next total rows=120
|
|
+prior total rows=120
|
|
+FetchScroll beyond the end failed 100
|
|
+encountered EOF at 120
|
|
+disconnecting
|
|
diff --git a/test/src/declare-fetch-block-test.c b/test/src/declare-fetch-block-test.c
|
|
new file mode 100644
|
|
index 0000000..2ecd0c2
|
|
--- /dev/null
|
|
+++ b/test/src/declare-fetch-block-test.c
|
|
@@ -0,0 +1,125 @@
|
|
+/*
|
|
+ * Test what happens when using block cursors, scrolling next and prior, or
|
|
+ * fetching a row "behind" the rowset by "fetch absolute".
|
|
+ */
|
|
+
|
|
+#include <string.h>
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+
|
|
+#include "common.h"
|
|
+
|
|
+#define TOTAL 120
|
|
+#define BLOCK 84
|
|
+int main(int argc, char **argv)
|
|
+{
|
|
+ int rc;
|
|
+ HSTMT hstmt = SQL_NULL_HSTMT;
|
|
+ int i;
|
|
+ int count = TOTAL;
|
|
+ char query[100];
|
|
+ int totalRows = 0;
|
|
+ int fetchIdx = 0;
|
|
+ SQLLEN rowArraySize = BLOCK;
|
|
+ SQLULEN rowsFetched;
|
|
+ SQLINTEGER id[BLOCK];
|
|
+ SQLLEN cbLen[BLOCK];
|
|
+
|
|
+ /****
|
|
+ * Run this test with UseDeclareFetch = 1 and Fetch=100(default).
|
|
+ */
|
|
+ test_connect_ext("UseDeclareFetch=1");
|
|
+
|
|
+ rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
|
|
+ if (!SQL_SUCCEEDED(rc))
|
|
+ {
|
|
+ print_diag("failed to allocate stmt handle", SQL_HANDLE_DBC, conn);
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ rc = SQLExecDirect(hstmt, (SQLCHAR *) "create temporary table tmptable(id int4 primary key)", SQL_NTS);
|
|
+ CHECK_STMT_RESULT(rc, "SQLExecDirect create table failed", hstmt);
|
|
+
|
|
+ /* insert into a table */
|
|
+ for (i = 0; i < count; i++)
|
|
+ {
|
|
+ snprintf(query, sizeof(query), "insert into tmptable values (%d)", i);
|
|
+ rc = SQLExecDirect(hstmt, (SQLCHAR *) query, SQL_NTS);
|
|
+ CHECK_STMT_RESULT(rc, "insert into table failed", hstmt);
|
|
+ }
|
|
+ rc = SQLFreeStmt(hstmt, SQL_CLOSE);
|
|
+ CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
|
|
+
|
|
+ /*
|
|
+ * Block cursor
|
|
+ */
|
|
+ rc = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) rowArraySize, 0);
|
|
+ CHECK_STMT_RESULT(rc, "SQLSetStmtAttr ROW_ARRAY_SIZE failed", hstmt);
|
|
+ rc = SQLSetStmtAttr(hstmt, SQL_ATTR_ROWS_FETCHED_PTR, (SQLPOINTER) &rowsFetched, 0);
|
|
+ CHECK_STMT_RESULT(rc, "SQLSetStmtAttr ROWS_FETCHED_PTR failed", hstmt);
|
|
+ rc = SQLBindCol(hstmt, 1, SQL_C_SLONG, &id, 0, cbLen);
|
|
+ CHECK_STMT_RESULT(rc, "SQLBindCol failed", hstmt);
|
|
+ rc = SQLExecDirect(hstmt, (SQLCHAR *) "select * from tmptable", SQL_NTS);
|
|
+ CHECK_STMT_RESULT(rc, "select failed", hstmt);
|
|
+ while (rc = SQLFetch(hstmt), SQL_SUCCEEDED(rc))
|
|
+ {
|
|
+ fetchIdx++;
|
|
+ totalRows += (int) rowsFetched;
|
|
+ printf("fetchIdx=%d, fetched rows=%d, total rows=%d\n", fetchIdx, (int) rowsFetched, totalRows);
|
|
+ }
|
|
+ rc = SQLFreeStmt(hstmt, SQL_CLOSE);
|
|
+ CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
|
|
+ /*
|
|
+ * Scroll next -> EOF -> prior -> BOF -> next -> EOF -> prior -> BOF
|
|
+ */
|
|
+ rc = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) 1, SQL_IS_UINTEGER);
|
|
+ CHECK_STMT_RESULT(rc, "SQLSetStmtAttr ROW_ARRAY_SIZE failed", hstmt);
|
|
+ rc = SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_STATIC, 0);
|
|
+ CHECK_STMT_RESULT(rc, "SQLSetStmtAttr CURSOR_TYPE failed", hstmt);
|
|
+ rc = SQLSetStmtAttr(hstmt, SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0);
|
|
+ CHECK_STMT_RESULT(rc, "SQLSetStmtAttr CONCURRENCY failed", hstmt);
|
|
+ rc = SQLExecDirect(hstmt, (SQLCHAR *) "select * from tmptable", SQL_NTS);
|
|
+ CHECK_STMT_RESULT(rc, "select failed", hstmt);
|
|
+ for (i = 0; i < 2; i++)
|
|
+ {
|
|
+ totalRows = 0;
|
|
+ while (rc = SQLFetchScroll(hstmt, SQL_FETCH_NEXT, 0), SQL_SUCCEEDED(rc))
|
|
+ totalRows += (int) rowsFetched;
|
|
+ if (SQL_NO_DATA != rc)
|
|
+ CHECK_STMT_RESULT(rc, "fetch failed", hstmt);
|
|
+ printf("next total rows=%d\n", totalRows);
|
|
+ totalRows = 0;
|
|
+ while (rc = SQLFetchScroll(hstmt, SQL_FETCH_PRIOR, 0), SQL_SUCCEEDED(rc))
|
|
+ totalRows += (int) rowsFetched;
|
|
+ if (SQL_NO_DATA != rc)
|
|
+ CHECK_STMT_RESULT(rc, "fetch failed", hstmt);
|
|
+ printf("prior total rows=%d\n", totalRows);
|
|
+ }
|
|
+ rc = SQLFreeStmt(hstmt, SQL_CLOSE);
|
|
+ CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
|
|
+ /*
|
|
+ * When fetching a row "behind" the rowset by "fetch absolute" only the first ones of the result set can be fetched?
|
|
+ */
|
|
+ rc = SQLExecDirect(hstmt, (SQLCHAR *) "select * from tmptable", SQL_NTS);
|
|
+ CHECK_STMT_RESULT(rc, "select failed", hstmt);
|
|
+ if (rc = SQLFetchScroll(hstmt, SQL_FETCH_ABSOLUTE, count + 1), !SQL_SUCCEEDED(rc))
|
|
+ {
|
|
+ printf("FetchScroll beyond the end failed %d\n", rc);
|
|
+ }
|
|
+ rc = SQLFetchScroll(hstmt, SQL_FETCH_ABSOLUTE, 1);
|
|
+ CHECK_STMT_RESULT(rc, "FetchScroll the 1st row failed", hstmt);
|
|
+ for (i = 1; i < count; i++)
|
|
+ {
|
|
+ if (!SQL_SUCCEEDED(rc = SQLFetchScroll(hstmt, SQL_FETCH_NEXT, 0)))
|
|
+ break;
|
|
+ }
|
|
+ printf("encountered EOF at %d\n", i);
|
|
+
|
|
+ rc = SQLFreeStmt(hstmt, SQL_CLOSE);
|
|
+ CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
|
|
+
|
|
+ /* Clean up */
|
|
+ test_disconnect();
|
|
+
|
|
+ return 0;
|
|
+}
|
|
--
|
|
2.5.5
|
|
|