int main(int argc, char **argv) { #define ARRAY_SIZE 10 SQLCHAR v_dec[ARRAY_SIZE][21]; SQLLEN v_ind[ARRAY_SIZE]; SQLULEN nrows; odbc_use_version3 = 1; odbc_connect(); odbc_check_cursor(); odbc_command("IF OBJECT_ID('mytab1') IS NOT NULL DROP TABLE mytab1"); odbc_command("CREATE TABLE mytab1 ( k INT, d DECIMAL(10,2))"); odbc_command("INSERT INTO mytab1 VALUES ( 201, 111.11 )"); /*SQLExecDirect(m_hstmt, (SQLCHAR *) "insert into mytab1 values ( 202, 222.22 )", SQL_NTS); */ odbc_command("INSERT INTO mytab1 VALUES ( 202, null )"); odbc_reset_statement(); CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER, "S"); CHKSetStmtAttr(SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER, "S"); CHKSetStmtAttr(SQL_ATTR_ROW_BIND_TYPE, (SQLPOINTER) SQL_BIND_BY_COLUMN, SQL_IS_UINTEGER, "S"); CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ARRAY_SIZE, SQL_IS_UINTEGER, "S"); CHKSetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR, (SQLPOINTER) & (nrows), SQL_IS_UINTEGER, "S"); CHKPrepare(T("SELECT SUM(d) FROM mytab1"), SQL_NTS, "S"); CHKExecute("I"); #if 0 CHKMoreResults("S"); /* skip warning*/ #endif CHKBindCol(1, SQL_C_CHAR, v_dec, 21, v_ind, "S"); CHKFetch("S"); printf("fetch 1: rows fetched = %d\n", (int) nrows); printf("fetch 1: value = [%s]\n", v_dec[0]); CHKFetch("No"); CHKMoreResults("No"); odbc_command("drop table mytab1"); odbc_disconnect(); return 0; }
/* stripped down version of TestInput for NULLs */ static void NullInput(SQLSMALLINT out_c_type, SQLSMALLINT out_sql_type, const char *param_type) { char sbuf[1024]; SQLLEN out_len = SQL_NULL_DATA; odbc_reset_statement(); /* create a table with a column of that type */ odbc_reset_statement(); sprintf(sbuf, "CREATE TABLE #tmp_insert (col %s NULL)", param_type); odbc_command(sbuf); if (use_cursors) { odbc_reset_statement(); CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0, "S"); CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S"); } /* insert data using prepared statements */ sprintf(sbuf, "INSERT INTO #tmp_insert VALUES(?)"); if (exec_direct) { CHKBindParameter(1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, NULL, 1, &out_len, "S"); CHKExecDirect(T(sbuf), SQL_NTS, "SNo"); } else { if (prepare_before) CHKPrepare(T(sbuf), SQL_NTS, "S"); CHKBindParameter(1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, NULL, 1, &out_len, "S"); if (!prepare_before) CHKPrepare(T(sbuf), SQL_NTS, "S"); CHKExecute("SNo"); } /* check if row is present */ odbc_reset_statement(); if (!odbc_db_is_microsoft() && strcmp(param_type, "TEXT") == 0) odbc_command("SELECT * FROM #tmp_insert WHERE col LIKE ''"); else odbc_command("SELECT * FROM #tmp_insert WHERE col IS NULL"); CHKFetch("S"); CHKFetch("No"); CHKMoreResults("No"); odbc_command("DROP TABLE #tmp_insert"); ODBC_FREE(); }
static int Test(int txn, const char *expected) { int dirty, repeatable, phantom; char buf[128]; SWAP_CONN(); if (test_with_connect) { odbc_disconnect(); ConnectWithTxn(txn); CHKSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0, "S"); } else { CHKSetConnectAttr(SQL_ATTR_TXN_ISOLATION, int2ptr(txn), 0, "S"); } SWAP_CONN(); dirty = CheckDirtyRead(); repeatable = CheckNonrepeatableRead(); phantom = CheckPhantom(); sprintf(buf, "dirty %d non repeatable %d phantom %d", dirty, repeatable, phantom); if (strcmp(buf, expected) != 0) { if (hide_error) { hide_error = 0; return 0; } fprintf(stderr, "detected wrong TXN\nexpected '%s' got '%s'\n", expected, buf); exit(1); } hide_error = 0; return 1; }
static void test_params(void) { #define ARRAY_SIZE 2 const rows_set_t *p; SQLULEN len; SQLUINTEGER *ids = MALLOC_N(SQLUINTEGER,ARRAY_SIZE); SQLLEN *id_lens = MALLOC_N(SQLLEN,ARRAY_SIZE); unsigned long int h, l; unsigned int n; for (n = 0; n < ARRAY_SIZE; ++n) { ids[n] = n; id_lens[n] = 0; } /* test setting just some test pointers */ set_ipd_params1(int2ptr(0x01020304)); check_ipd_params(); set_ipd_params2(int2ptr(0xabcdef12)); check_ipd_params(); set_ipd_params3(int2ptr(0x87654321)); check_ipd_params(); /* now see results */ for (p = param_set; *p != NULL; ++p) { odbc_reset_statement(); len = 0xdeadbeef; len <<= 16; len <<= 16; len |= 12345678; (*p)(&len); check_ipd_params(); CHKSetStmtAttr(SQL_ATTR_PARAMSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S"); CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, ids, 0, id_lens, "S"); odbc_command("INSERT INTO #tmp1(i) VALUES(?)"); SQLMoreResults(odbc_stmt); for (n = 0; n < ARRAY_SIZE; ++n) SQLMoreResults(odbc_stmt); l = len; len >>= 16; h = len >> 16; l &= 0xfffffffflu; if (h != 0 || l != 2) { fprintf(stderr, "Wrong number returned in param rows high %lu low %lu\n", h, l); exit(1); } } free(ids); free(id_lens); }
static void test_err(int n) { CHKSetStmtAttr(SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(n), 0, "E"); odbc_read_error(); if (strcmp(odbc_sqlstate, "HY024") != 0) { fprintf(stderr, "Unexpected sql state returned\n"); odbc_disconnect(); exit(1); } }
static int Test(int direct) { SQLTCHAR buf[256]; SQLTCHAR sqlstate[6]; time_t start_time, end_time; odbc_mark_sockets_opened(); odbc_connect(); if (!shutdown_last_socket()) { fprintf(stderr, "Error shutting down connection\n"); return 1; } CHKSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 10, SQL_IS_UINTEGER, "S"); alarm(30); start_time = time(NULL); if (direct) { CHKExecDirect(T("SELECT 1"), SQL_NTS, "E"); } else { SQLSMALLINT cols; /* force dialog with server */ if (CHKPrepare(T("SELECT 1"), SQL_NTS, "SE") == SQL_SUCCESS) CHKNumResultCols(&cols, "E"); } end_time = time(NULL); alarm(0); memset(sqlstate, 'X', sizeof(sqlstate)); CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, sqlstate, NULL, buf, ODBC_VECTOR_SIZE(buf), NULL, "SI"); sqlstate[5] = 0; printf("Message: %s - %s\n", C(sqlstate), C(buf)); if (strcmp(C(sqlstate), "HYT00") || !strstr(C(buf), "Timeout")) { fprintf(stderr, "Invalid timeout message\n"); return 1; } if (end_time - start_time < 10 || end_time - start_time > 26) { fprintf(stderr, "Unexpected connect timeout (%d)\n", (int) (end_time - start_time)); return 1; } odbc_disconnect(); if (end_socket >= 0) close(end_socket); printf("Done.\n"); return 0; }
int main(int argc, char **argv) { char buff[64]; SQLLEN ind; odbc_use_version3 = 1; odbc_connect(); odbc_check_cursor(); exec_direct("CREATE TABLE #t1 ( k INT, c VARCHAR(20))"); exec_direct("INSERT INTO #t1 VALUES (1, 'aaa')"); odbc_reset_statement(); CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_LOCK, SQL_IS_UINTEGER, "S"); CHKSetCursorName(T("c112"), SQL_NTS, "S"); CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, int2ptr(SQL_AUTOCOMMIT_OFF), 0, "S"); CHKPrepare(T("SELECT * FROM #t1 FOR UPDATE"), SQL_NTS, "S"); CHKExecute("S"); CHKFetch("S"); exec_direct("UPDATE #t1 SET c = 'xxx' WHERE CURRENT OF c112"); CHKCloseCursor("SI"); CHKEndTran(SQL_HANDLE_DBC, odbc_conn, SQL_COMMIT, "S"); CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, int2ptr(SQL_AUTOCOMMIT_ON), 0, "S"); CHKExecDirect(T("SELECT c FROM #t1 WHERE k = 1"), SQL_NTS, "S"); CHKFetch("S"); CHKGetData(1, SQL_C_CHAR, buff, sizeof(buff), &ind, "S"); printf(">> New value after update = [%s] (should be [xxx]) \n", buff); CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) odbc_stmt, "S"); odbc_stmt = SQL_NULL_HSTMT; odbc_disconnect(); return 0; }
int main(int argc, char *argv[]) { int i; odbc_connect(); odbc_command("create table #timeout(i int)"); odbc_command("insert into #timeout values(1)"); for (i = 0; i < 2; ++i) { printf("Loop %d\n", i); CHKSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 10, SQL_IS_UINTEGER, "S"); CHKPrepare(T("select * from #timeout"), SQL_NTS, "S"); CHKExecute("S"); do { while (CHKFetch("SNo") == SQL_SUCCESS) ; } while (CHKMoreResults("SNo") == SQL_SUCCESS); if (i == 0) { printf("Sleep 15 seconds to test if timeout occurs\n"); tds_sleep_s(15); } SQLFreeStmt(odbc_stmt, SQL_CLOSE); SQLFreeStmt(odbc_stmt, SQL_UNBIND); SQLFreeStmt(odbc_stmt, SQL_RESET_PARAMS); SQLCloseCursor(odbc_stmt); } odbc_disconnect(); ODBC_FREE(); return 0; }
int main(int argc, char *argv[]) { #define ROWS 3 #define C_LEN 10 SQLUINTEGER n[ROWS]; char c[ROWS][C_LEN]; SQLLEN c_len[ROWS], n_len[ROWS]; SQLUSMALLINT statuses[ROWS]; SQLUSMALLINT i; SQLULEN num_row; int i_test; typedef struct _test { SQLUSMALLINT type; SQLINTEGER irow; int start; int num; } TEST; static const TEST tests[] = { {SQL_FETCH_NEXT, 0, 1, 3}, {SQL_FETCH_NEXT, 0, 4, 2}, {SQL_FETCH_PRIOR, 0, 1, 3}, {SQL_FETCH_NEXT, 0, 4, 2}, {SQL_FETCH_NEXT, 0, -1, -1}, {SQL_FETCH_FIRST, 0, 1, 3}, {SQL_FETCH_ABSOLUTE, 3, 3, 3}, {SQL_FETCH_RELATIVE, 1, 4, 2}, {SQL_FETCH_LAST, 0, 3, 3} }; const int num_tests = sizeof(tests) / sizeof(TEST); odbc_use_version3 = 1; odbc_connect(); odbc_check_cursor(); /* create test table */ odbc_command("IF OBJECT_ID('tempdb..#test') IS NOT NULL DROP TABLE #test"); odbc_command("CREATE TABLE #test(i int, c varchar(6))"); odbc_command("INSERT INTO #test(i, c) VALUES(1, 'a')"); odbc_command("INSERT INTO #test(i, c) VALUES(2, 'bb')"); odbc_command("INSERT INTO #test(i, c) VALUES(3, 'ccc')"); odbc_command("INSERT INTO #test(i, c) VALUES(4, 'dddd')"); odbc_command("INSERT INTO #test(i, c) VALUES(5, 'eeeee')"); /* set cursor options */ odbc_reset_statement(); CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0, "S"); CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0, "S"); CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S"); CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ROWS, 0, "S"); CHKSetStmtAttr(SQL_ATTR_ROW_STATUS_PTR, (SQLPOINTER) statuses, 0, "S"); CHKSetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR, &num_row, 0, "S"); /* */ CHKExecDirect(T("SELECT i, c FROM #test"), SQL_NTS, "S"); /* bind some rows at a time */ CHKBindCol(1, SQL_C_ULONG, n, 0, n_len, "S"); CHKBindCol(2, SQL_C_CHAR, c, C_LEN, c_len, "S"); for (i_test = 0; i_test < num_tests; ++i_test) { const TEST *t = &tests[i_test]; printf("Test %d\n", i_test + 1); if (t->start == -1) { CHKFetchScroll(t->type, t->irow, "No"); } else { CHKFetchScroll(t->type, t->irow, "S"); if (t->start < 1) { fprintf(stderr, "Rows not expected\n"); exit(1); } /* print, just for debug */ for (i = 0; i < num_row; ++i) printf("row %d i %d c %s\n", (int) (i + 1), (int) n[i], c[i]); printf("---\n"); if (num_row != t->num) { fprintf(stderr, "Expected %d rows, got %d\n", t->num, (int) num_row); exit(1); } for (i = 0; i < num_row; ++i) { char name[10]; memset(name, 0, sizeof(name)); memset(name, 'a' - 1 + i + t->start, i + t->start); if (n[i] != i + t->start || c_len[i] != strlen(name) || strcmp(c[i], name) != 0) { fprintf(stderr, "Wrong row returned\n"); fprintf(stderr, "\tn %d %d\n", (int) n[i], i + t->start); fprintf(stderr, "\tc len %d %d\n", (int) c_len[i], (int) strlen(name)); fprintf(stderr, "\tc %s %s\n", c[i], name); exit(1); } } } } odbc_reset_statement(); odbc_disconnect(); return 0; }
int main(int argc, char *argv[]) { int i; SQLLEN len; #ifdef HAVE_SQLROWSETSIZE SQLROWSETSIZE row_count; #else SQLULEN row_count; #endif SQLUSMALLINT statuses[10]; char buf[32]; odbc_use_version3 = 1; odbc_connect(); /* initial value should be 1 */ CHKGetStmtAttr(SQL_ROWSET_SIZE, &len, sizeof(len), NULL, "S"); if (len != 1) { fprintf(stderr, "len should be 1\n"); odbc_disconnect(); return 1; } /* check invalid parameter values */ test_err(-123); test_err(-1); test_err(0); odbc_check_cursor(); /* set some correct values */ CHKSetStmtAttr(SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(2), 0, "S"); CHKSetStmtAttr(SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(1), 0, "S"); /* now check that SQLExtendedFetch works as expected */ odbc_command("CREATE TABLE #rowset(n INTEGER, c VARCHAR(20))"); for (i = 0; i < 10; ++i) { char s[10]; char sql[128]; memset(s, 'a' + i, 9); s[9] = 0; sprintf(sql, "INSERT INTO #rowset(n,c) VALUES(%d,'%s')", i+1, s); odbc_command(sql); } odbc_reset_statement(); CHKSetStmtOption(SQL_ATTR_CURSOR_TYPE, SQL_CURSOR_DYNAMIC, "S"); CHKExecDirect((SQLCHAR *) "SELECT * FROM #rowset ORDER BY n", SQL_NTS, "SI"); CHKBindCol(2, SQL_C_CHAR, buf, sizeof(buf), &len, "S"); row_count = 0xdeadbeef; memset(statuses, 0x55, sizeof(statuses)); CHKExtendedFetch(SQL_FETCH_NEXT, 1, &row_count, statuses, "S"); if (row_count != 1 || statuses[0] != SQL_ROW_SUCCESS || strcmp(buf, "aaaaaaaaa") != 0) { fprintf(stderr, "Invalid result\n"); odbc_disconnect(); return 1; } odbc_disconnect(); printf("Done.\n"); return 0; }
static void Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *select_sql) { #define ROWS 4 #define C_LEN 10 SQLUINTEGER n[ROWS]; char c[ROWS][C_LEN]; SQLLEN c_len[ROWS], n_len[ROWS]; SQLUSMALLINT statuses[ROWS]; SQLUSMALLINT i; SQLULEN num_row; SQLHSTMT stmt2; /* create test table */ odbc_command("IF OBJECT_ID('tempdb..#test') IS NOT NULL DROP TABLE #test"); odbc_command(create_sql); for (i = 1; i <= 6; ++i) { char sql_buf[80], data[10]; memset(data, 'a' + (i - 1), sizeof(data)); data[i] = 0; sprintf(sql_buf, insert_sql, data, i); odbc_command(sql_buf); } /* set cursor options */ odbc_reset_statement(); CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0, "S"); CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S"); CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ROWS, 0, "S"); CHKSetStmtAttr(SQL_ATTR_ROW_STATUS_PTR, (SQLPOINTER) statuses, 0, "S"); CHKSetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR, &num_row, 0, "S"); CHKSetCursorName(T("C1"), SQL_NTS, "S"); /* */ CHKExecDirect(T(select_sql), SQL_NTS, "S"); /* bind some rows at a time */ CHKBindCol(1, SQL_C_ULONG, n, 0, n_len, "S"); CHKBindCol(2, SQL_C_CHAR, c, C_LEN, c_len, "S"); /* allocate an additional statement */ CHKAllocStmt(&stmt2, "S"); while (CHKFetchScroll(SQL_FETCH_NEXT, 0, "SNo") == SQL_SUCCESS) { /* print, just for debug */ for (i = 0; i < num_row; ++i) printf("row %d i %d c %s\n", (int) (i + 1), (int) n[i], c[i]); printf("---\n"); /* delete a row */ i = 1; if (i > 0 && i <= num_row) { if (mssql2005) CHKSetPos(i, use_sql ? SQL_POSITION : SQL_DELETE, SQL_LOCK_NO_CHANGE, "SI"); else CHKSetPos(i, use_sql ? SQL_POSITION : SQL_DELETE, SQL_LOCK_NO_CHANGE, "S"); if (use_sql) { SWAP_STMT(stmt2); CHKPrepare(T("DELETE FROM #test WHERE CURRENT OF C1"), SQL_NTS, "S"); CHKExecute("S"); SWAP_STMT(stmt2); } } /* update another row */ i = 2; if (i > 0 && i <= num_row) { strcpy(c[i - 1], "foo"); c_len[i - 1] = 3; if (strstr(select_sql, "#a") == NULL || use_sql) { CHKSetPos(i, use_sql ? SQL_POSITION : SQL_UPDATE, SQL_LOCK_NO_CHANGE, "S"); } else { SQLTCHAR sqlstate[6]; SQLTCHAR msg[256]; n[i - 1] = 321; CHKSetPos(i, use_sql ? SQL_POSITION : SQL_UPDATE, SQL_LOCK_NO_CHANGE, "E"); CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, sqlstate, NULL, msg, ODBC_VECTOR_SIZE(msg), NULL, "S"); if (strstr(C(msg), "Invalid column name 'c'") == NULL) { fprintf(stderr, "Expected message not found at line %d\n", __LINE__); exit(1); } } if (use_sql) { SWAP_STMT(stmt2); CHKPrepare(T("UPDATE #test SET c=? WHERE CURRENT OF C1"), SQL_NTS, "S"); CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, C_LEN, 0, c[i - 1], 0, NULL, "S"); CHKExecute("S"); /* FIXME this is not necessary for mssql driver */ SQLMoreResults(odbc_stmt); SWAP_STMT(stmt2); } } } SWAP_STMT(stmt2); CHKFreeStmt(SQL_DROP, "S"); SWAP_STMT(stmt2); odbc_reset_statement(); /* test values */ CheckNoRow("IF (SELECT COUNT(*) FROM #test) <> 4 SELECT 1"); CheckNoRow("IF NOT EXISTS(SELECT * FROM #test WHERE i = 3 AND c = 'ccc') SELECT 1"); CheckNoRow("IF NOT EXISTS(SELECT * FROM #test WHERE i = 4 AND c = 'dddd') SELECT 1"); if (strstr(select_sql, "#a") == NULL || use_sql) { CheckNoRow("IF NOT EXISTS(SELECT * FROM #test WHERE i = 2 AND c = 'foo') SELECT 1"); CheckNoRow("IF NOT EXISTS(SELECT * FROM #test WHERE i = 6 AND c = 'foo') SELECT 1"); } }
static int TestOutput(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, SQLSMALLINT out_sql_type, const char *expected) { char sbuf[1024]; unsigned char out_buf[256]; SQLLEN out_len = 0; const char *sep; odbc_reset_statement(); /* build store procedure to test */ odbc_command("IF OBJECT_ID('spTestProc') IS NOT NULL DROP PROC spTestProc"); sep = "'"; if (strncmp(value_to_convert, "0x", 2) == 0) sep = ""; sprintf(sbuf, "CREATE PROC spTestProc @i %s OUTPUT AS SELECT @i = CONVERT(%s, %s%s%s)", type, type, sep, value_to_convert, sep); odbc_command(sbuf); memset(out_buf, 0, sizeof(out_buf)); if (use_cursors) { odbc_reset_statement(); CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0, "S"); CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S"); } /* bind parameter */ if (exec_direct) { CHKBindParameter(1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, precision, 0, out_buf, sizeof(out_buf), &out_len, "S"); /* call store procedure */ CHKExecDirect(T("{call spTestProc(?)}"), SQL_NTS, "S"); } else { if (prepare_before) CHKPrepare(T("{call spTestProc(?)}"), SQL_NTS, "S"); CHKBindParameter(1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, precision, 0, out_buf, sizeof(out_buf), &out_len, "S"); if (!prepare_before) CHKPrepare(T("{call spTestProc(?)}"), SQL_NTS, "S"); CHKExecute("S"); } /* * MS OBDC requires it cause first recordset is a recordset with a * warning caused by the way it execute RPC (via EXEC statement) */ if (use_cursors && !odbc_driver_is_freetds()) SQLMoreResults(odbc_stmt); /* test results */ odbc_c2string(sbuf, out_c_type, out_buf, out_len); if (strcmp(sbuf, expected) != 0) { if (only_test) { odbc_command("drop proc spTestProc"); ODBC_FREE(); return 1; } fprintf(stderr, "Wrong result\n Got: %s\n Expected: %s\n", sbuf, expected); exit(1); } only_test = 0; odbc_command("drop proc spTestProc"); ODBC_FREE(); return 0; }
static void TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, const char *param_type, const char *value_to_convert) { char sbuf[1024]; unsigned char out_buf[256]; SQLLEN out_len = 0; const char *expected = value_to_convert; size_t value_len = strlen(value_to_convert); const char *p; const char *sep = "'"; odbc_reset_statement(); /* execute a select to get data as wire */ if ((p = strstr(value_to_convert, " -> ")) != NULL) { value_len = p - value_to_convert; expected = p + 4; } if (value_len >= 2 && strncmp(value_to_convert, "0x", 2) == 0) sep = ""; sprintf(sbuf, "SELECT CONVERT(%s, %s%.*s%s)", type, sep, (int) value_len, value_to_convert, sep); odbc_command(sbuf); SQLBindCol(odbc_stmt, 1, out_c_type, out_buf, sizeof(out_buf), &out_len); CHKFetch("SI"); CHKFetch("No"); CHKMoreResults("No"); if (use_nts) { out_len = SQL_NTS; use_nts = 0; } /* create a table with a column of that type */ odbc_reset_statement(); sprintf(sbuf, "CREATE TABLE #tmp_insert (col %s)", param_type); odbc_command(sbuf); if (use_cursors) { odbc_reset_statement(); CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0, "S"); CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S"); } /* insert data using prepared statements */ sprintf(sbuf, "INSERT INTO #tmp_insert VALUES(?)"); if (exec_direct) { CHKBindParameter(1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len, "S"); if (check_truncation) CHKExecDirect(T(sbuf), SQL_NTS, "E"); else CHKExecDirect(T(sbuf), SQL_NTS, "SNo"); } else { if (prepare_before) CHKPrepare(T(sbuf), SQL_NTS, "S"); CHKBindParameter(1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len, "S"); if (!prepare_before) CHKPrepare(T(sbuf), SQL_NTS, "S"); if (check_truncation) CHKExecute("E"); else CHKExecute("SNo"); } /* check if row is present */ if (!check_truncation) { odbc_reset_statement(); sep = "'"; if (strncmp(expected, "0x", 2) == 0) sep = ""; if (strcmp(param_type, "TEXT") == 0) sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE CONVERT(VARCHAR(255), col) = CONVERT(VARCHAR(255), %s%s%s)", sep, expected, sep); else if (strcmp(param_type, "NTEXT") == 0) sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE CONVERT(NVARCHAR(2000), col) = CONVERT(NVARCHAR(2000), %s%s%s)", sep, expected, sep); else if (strcmp(param_type, "IMAGE") == 0) sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE CONVERT(VARBINARY(255), col) = CONVERT(VARBINARY(255), %s%s%s)", sep, expected, sep); else sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE col = CONVERT(%s, %s%s%s)", param_type, sep, expected, sep); odbc_command(sbuf); CHKFetch("S"); CHKFetch("No"); CHKMoreResults("No"); } check_truncation = 0; odbc_command("DROP TABLE #tmp_insert"); ODBC_FREE(); }
int main(int argc, char **argv) { SQLRETURN RetCode; SQLHSTMT old_odbc_stmt = SQL_NULL_HSTMT; int i; int key; SQLLEN vind0; int cnt = 2, wide; char sql[256]; test_info *t = NULL; odbc_use_version3 = 1; odbc_connect(); /* tests (W)CHAR/BINARY -> (W)CHAR/BINARY (9 cases) */ add_test(SQL_C_BINARY, SQL_LONGVARCHAR, "TEXT", 123, 1 ); add_test(SQL_C_BINARY, SQL_LONGVARBINARY, "IMAGE", 987, 25); add_test(SQL_C_CHAR, SQL_LONGVARBINARY, "IMAGE", 987, 25); add_test(SQL_C_CHAR, SQL_LONGVARCHAR, "TEXT", 343, 47); add_test(SQL_C_WCHAR, SQL_LONGVARBINARY, "IMAGE", 561, 29); add_test(SQL_C_WCHAR, SQL_LONGVARCHAR, "TEXT", 698, 24); if (odbc_db_is_microsoft()) { add_test(SQL_C_BINARY, SQL_WLONGVARCHAR, "NTEXT", 765, 12); add_test(SQL_C_CHAR, SQL_WLONGVARCHAR, "NTEXT", 237, 71); add_test(SQL_C_WCHAR, SQL_WLONGVARCHAR, "NTEXT", 687, 68); } strcpy(sql, "CREATE TABLE #tt(k INT"); for (t = test_infos; t < test_infos+num_tests; ++t) sprintf(strchr(sql, 0), ",f%u %s", t->num, t->db_type); strcat(sql, ",v INT)"); odbc_command(sql); old_odbc_stmt = odbc_stmt; odbc_stmt = SQL_NULL_HSTMT; /* Insert rows ... */ for (i = 0; i < cnt; i++) { /* MS do not save correctly char -> binary */ if (!odbc_driver_is_freetds() && i) continue; CHKAllocHandle(SQL_HANDLE_STMT, odbc_conn, &odbc_stmt, "S"); strcpy(sql, "INSERT INTO #tt VALUES(?"); for (t = test_infos; t < test_infos+num_tests; ++t) strcat(sql, ",?"); strcat(sql, ",?)"); CHKPrepare(T(sql), SQL_NTS, "S"); CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0, "S"); for (t = test_infos; t < test_infos+num_tests; ++t) CHKBindParameter(t->num+1, SQL_PARAM_INPUT, t->c_type, t->sql_type, 0x10000000, 0, t->buf, 0, &t->vind, "S"); CHKBindParameter(num_tests+2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0, "S"); key = i; vind0 = 0; printf(">> insert... %d\n", i); RetCode = CHKExecute("SINe"); while (RetCode == SQL_NEED_DATA) { char *p; RetCode = CHKParamData((SQLPOINTER) & p, "SINe"); printf(">> SQLParamData: ptr = %p RetCode = %d\n", (void *) p, RetCode); if (RetCode == SQL_NEED_DATA) { for (t = test_infos; t < test_infos+num_tests && t->buf != p; ++t) ; assert(t < test_infos+num_tests); if (t->c_type == SQL_C_CHAR || t->c_type == SQL_C_WCHAR) { unsigned char_len = 1; fill_hex(p, NBYTES, t->gen1, t->gen2); if (t->c_type == SQL_C_WCHAR) { char_len = sizeof(SQLWCHAR); odbc_to_sqlwchar((SQLWCHAR*) p, p, NBYTES * 2); } CHKPutData(p, (NBYTES - (i&1)) * char_len, "S"); printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES - (i&1)); CHKPutData(p + (NBYTES - (i&1)) * char_len, (NBYTES + (i&1)) * char_len, "S"); printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES + (i&1)); } else { CHKPutData(p, NBYTES, "S"); printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES); } } } CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) odbc_stmt, "S"); odbc_stmt = SQL_NULL_HSTMT; } /* Now fetch rows ... */ for (wide = 0; wide < 2; ++wide) for (i = 0; i < cnt; i++) { /* MS do not save correctly char -> binary */ if (!odbc_driver_is_freetds() && i) continue; CHKAllocHandle(SQL_HANDLE_STMT, odbc_conn, &odbc_stmt, "S"); if (odbc_db_is_microsoft()) { CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER, "S"); CHKSetStmtAttr(SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER, "S"); } strcpy(sql, "SELECT "); for (t = test_infos; t < test_infos+num_tests; ++t) sprintf(strchr(sql, 0), "f%u,", t->num); strcat(sql, "v FROM #tt WHERE k = ?"); CHKPrepare(T(sql), SQL_NTS, "S"); CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i, 0, &vind0, "S"); for (t = test_infos; t < test_infos+num_tests; ++t) { t->vind = SQL_DATA_AT_EXEC; CHKBindCol(t->num, SQL_C_BINARY, NULL, 0, &t->vind, "S"); } CHKBindCol(num_tests+1, SQL_C_LONG, &key, 0, &vind0, "S"); vind0 = 0; CHKExecute("S"); CHKFetchScroll(SQL_FETCH_NEXT, 0, "S"); printf(">> fetch... %d\n", i); for (t = test_infos; t < test_infos+num_tests; ++t) { if (t->c_type == SQL_C_CHAR || t->c_type == SQL_C_WCHAR) readBlobAsChar(t, i, wide); else readBlob(t); } CHKCloseCursor("S"); CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) odbc_stmt, "S"); odbc_stmt = SQL_NULL_HSTMT; } odbc_stmt = old_odbc_stmt; free_tests(); odbc_disconnect(); if (!failed) printf("ok!\n"); return failed ? 1 : 0; }
int main(int argc, char *argv[]) { odbc_use_version3 = 1; odbc_connect(); /* Invalid argument value */ CHKSetConnectAttr(SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ | SQL_TXN_READ_COMMITTED), 0, "E"); ReadErrorConn(); if (strcmp(odbc_sqlstate, "HY024") != 0) { odbc_disconnect(); fprintf(stderr, "Unexpected success\n"); return 1; } /* here we can't use temporary table cause we use two connection */ odbc_command("IF OBJECT_ID('test_transaction') IS NOT NULL DROP TABLE test_transaction"); odbc_command("CREATE TABLE test_transaction(n NUMERIC(18,0) PRIMARY KEY, t VARCHAR(30))"); CHKSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0, "S"); AutoCommit(SQL_AUTOCOMMIT_OFF); odbc_command("INSERT INTO test_transaction(n, t) VALUES(1, 'initial')"); #ifdef ENABLE_DEVELOPING /* test setting with active transaction "Operation invalid at this time" */ CHKSetConnectAttr(SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ), 0, "E"); ReadErrorConn(); if (strcmp(odbc_sqlstate, "HY011") != 0) { odbc_disconnect(); fprintf(stderr, "Unexpected success\n"); return 1; } #endif EndTransaction(SQL_COMMIT); odbc_command("SELECT * FROM test_transaction"); /* test setting with pending data */ CHKSetConnectAttr(SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ), 0, "E"); ReadErrorConn(); if (strcmp(odbc_sqlstate, "HY011") != 0) { odbc_disconnect(); fprintf(stderr, "Unexpected success\n"); return 1; } SQLMoreResults(odbc_stmt); EndTransaction(SQL_COMMIT); /* save this connection and do another */ SWAP_CONN(); odbc_connect(); CHKSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0, "S"); AutoCommit(SQL_AUTOCOMMIT_OFF); SWAP_CONN(); for (test_with_connect = 0; test_with_connect <= 1; ++test_with_connect) { Test(SQL_TXN_READ_UNCOMMITTED, "dirty 1 non repeatable 1 phantom 1"); Test(SQL_TXN_READ_COMMITTED, "dirty 0 non repeatable 1 phantom 1"); if (odbc_db_is_microsoft()) { Test(SQL_TXN_REPEATABLE_READ, "dirty 0 non repeatable 0 phantom 1"); } else { hide_error = 1; if (!Test(SQL_TXN_REPEATABLE_READ, "dirty 0 non repeatable 0 phantom 1")) Test(SQL_TXN_REPEATABLE_READ, "dirty 0 non repeatable 0 phantom 0"); } Test(SQL_TXN_SERIALIZABLE, "dirty 0 non repeatable 0 phantom 0"); } odbc_disconnect(); SWAP_CONN(); EndTransaction(SQL_COMMIT); /* Sybase do not accept DROP TABLE during a transaction */ AutoCommit(SQL_AUTOCOMMIT_ON); odbc_command("DROP TABLE test_transaction"); odbc_disconnect(); return 0; }
static void Test(void) { #define ROWS 5 struct data_t { SQLINTEGER i; SQLLEN ind_i; char c[20]; SQLLEN ind_c; } data[ROWS]; SQLUSMALLINT statuses[ROWS]; SQLLEN num_row; odbc_reset_statement(); /* this should not fail or return warnings */ if (use_cursors) { CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, int2ptr(SQL_CONCUR_READ_ONLY), 0, "S"); CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, int2ptr(SQL_CURSOR_STATIC), 0, "S"); } CHKPrepare(T("SELECT c, i FROM #cursor6_test"), SQL_NTS, "S"); CHKExecute("S"); CHKSetStmtAttr(SQL_ATTR_ROW_BIND_TYPE, int2ptr(sizeof(data[0])), 0, "S"); CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, int2ptr(ROWS), 0, "S"); CHKSetStmtAttr(SQL_ATTR_ROW_STATUS_PTR, statuses, 0, "S"); CHKSetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR, &num_row, 0, "S"); if (bind_all) CHKBindCol(1, SQL_C_CHAR, &data[0].c, sizeof(data[0].c), &data[0].ind_c, "S"); CHKBindCol(2, SQL_C_LONG, &data[0].i, sizeof(data[0].i), &data[0].ind_i, "S"); #define FILL(s, n) do { \ int _n; for (_n = 0; _n < sizeof(s)/sizeof(s[0]); ++_n) s[_n] = n; \ } while(0) FILL(statuses, 9876); num_row = -3; data[0].i = (SQLINTEGER) 0xdeadbeef; data[1].i = (SQLINTEGER) 0xdeadbeef; if (normal_fetch) CHKFetch("S"); else CHKFetchScroll(SQL_FETCH_NEXT, 0, "S"); /* now check row numbers */ printf("num_row %ld statuses[0] %d statuses[1] %d odbc3 %d\n", (long int) num_row, (int) statuses[0], (int) statuses[1], odbc_use_version3); if (odbc_use_version3 || !normal_fetch) { if (num_row != ROWS || statuses[0] != SQL_ROW_SUCCESS || statuses[1] != SQL_ROW_SUCCESS) { fprintf(stderr, "result error 1\n"); exit(1); } } else { if (data[0].i != 1 || data[1].i != 0xdeadbeef) { fprintf(stderr, "result error 2\n"); exit(1); } } FILL(statuses, 8765); num_row = -3; if (normal_fetch) CHKFetch("S"); else CHKFetchScroll(SQL_FETCH_NEXT, 0, "S"); }
static void set_ird_params1(SQLULEN *ptr) { CHKSetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR, ptr, 0, "S"); }
static void set_ipd_params1(SQLULEN *ptr) { CHKSetStmtAttr(SQL_ATTR_PARAMS_PROCESSED_PTR, ptr, 0, "S"); }
static void test_rows(void) { const rows_set_t *p; SQLULEN len; SQLUINTEGER *ids = MALLOC_N(SQLUINTEGER,ARRAY_SIZE); SQLLEN *id_lens = MALLOC_N(SQLLEN,ARRAY_SIZE); unsigned long int h, l; unsigned int n; for (n = 0; n < ARRAY_SIZE; ++n) { ids[n] = n; id_lens[n] = 0; } /* test setting just some test pointers */ set_ird_params1(int2ptr(0x01020304)); check_ird_params(); set_ird_params2(int2ptr(0xabcdef12)); check_ird_params(); /* now see results */ for (p = row_set; ; ++p) { const char *test_name = NULL; odbc_reset_statement(); len = 0xdeadbeef; len <<= 16; len <<= 16; len |= 12345678; if (*p) (*p)(&len); check_ird_params(); #if 0 CHKSetStmtAttr(SQL_ATTR_PARAMSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S"); CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, ids, 0, id_lens, "S"); #endif CHKBindCol(1, SQL_C_ULONG, ids, 0, id_lens, "S"); if (*p) { CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S"); odbc_command("SELECT DISTINCT i FROM #tmp1"); SQLFetch(odbc_stmt); test_name = "SQLSetStmtAttr"; } else { CHKSetStmtAttr(SQL_ROWSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S"); odbc_command("SELECT DISTINCT i FROM #tmp1"); CHKExtendedFetch(SQL_FETCH_NEXT, 0, &len, NULL, "S"); test_name = "SQLExtendedFetch"; } SQLMoreResults(odbc_stmt); l = len; len >>= 16; h = len >> 16; l &= 0xfffffffflu; if (h != 0 || l != 2) { fprintf(stderr, "Wrong number returned in rows high %lu(0x%lx) low %lu(0x%lx) test %s\n", h, h, l, l, test_name); exit(1); } if (!*p) break; } free(ids); free(id_lens); }