static int CheckDirtyRead(void) { SQLRETURN RetCode; /* transaction 1 try to change a row but not commit */ odbc_command("UPDATE test_transaction SET t = 'second' WHERE n = 1"); SWAP_CONN(); /* second transaction try to fetch uncommited row */ RetCode = odbc_command2("SELECT * FROM test_transaction WHERE t = 'second' AND n = 1", "SE"); if (RetCode == SQL_ERROR) { EndTransaction(SQL_ROLLBACK); SWAP_CONN(); EndTransaction(SQL_ROLLBACK); return 0; /* no dirty read */ } CHKFetch("S"); CHKFetch("No"); SQLMoreResults(odbc_stmt); EndTransaction(SQL_ROLLBACK); SWAP_CONN(); EndTransaction(SQL_ROLLBACK); return 1; }
int main(int argc, char *argv[]) { odbc_connect(); /* issue print statement and test message returned */ odbc_command2("SELECT DATEADD(dd,-100000,getdate())", "E"); odbc_disconnect(); printf("Done.\n"); return 0; }
static void Test(int use_threads, int return_data) { tds_thread wait_thread; #if !HAVE_ALARM if (!use_threads) return; #endif printf("testing with %s\n", use_threads ? "threads" : "signals"); printf(">> Wait 5 minutes...\n"); if (!use_threads) { alarm(4); signal(SIGALRM, sigalrm_handler); } else { int err; exit_thread = 0; err = tds_thread_create(&wait_thread, wait_thread_proc, NULL); if (err != 0) { perror("tds_thread_create"); exit(1); } } if (!return_data) CHKExecDirect(T("WAITFOR DELAY '000:05:00'"), SQL_NTS, "E"); else odbc_command2("SELECT MAX(p1.k) FROM tab1 p1, tab1 p2, tab1 p3, tab1 p4", "E"); tds_mutex_lock(&mtx); exit_thread = 1; tds_mutex_unlock(&mtx); if (!use_threads) { alarm(0); } else { tds_thread_join(wait_thread, NULL); } getErrorInfo(SQL_HANDLE_STMT, odbc_stmt); if (strcmp(C(sqlstate), "HY008") != 0) { fprintf(stderr, "Unexpected sql state returned\n"); odbc_disconnect(); exit(1); } odbc_reset_statement(); odbc_command("SELECT name FROM sysobjects WHERE 0=1"); }
static void Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, const char *expected) { char sbuf[1024]; unsigned char out_buf[256]; SQLLEN out_len = 0; SQLFreeStmt(odbc_stmt, SQL_UNBIND); SQLFreeStmt(odbc_stmt, SQL_RESET_PARAMS); /* execute a select to get data as wire */ sprintf(sbuf, "SELECT CONVERT(%s, '%s') AS data", type, value_to_convert); if (strncmp(value_to_convert, "0x", 2) == 0) sprintf(sbuf, "SELECT CONVERT(%s, %s) COLLATE Latin1_General_CI_AS AS data", type, value_to_convert); else if (strcmp(type, "SQL_VARIANT") == 0) sprintf(sbuf, "SELECT CONVERT(SQL_VARIANT, %s) AS data", value_to_convert); else if (strncmp(value_to_convert, "u&'", 3) == 0) sprintf(sbuf, "SELECT CONVERT(%s, %s) AS data", type, value_to_convert); if (ignore_select_error) { if (odbc_command2(sbuf, "SENo") == SQL_ERROR) { odbc_reset_statement(); ignore_select_error = 0; ignore_result = 0; return; } } else { odbc_command(sbuf); } SQLBindCol(odbc_stmt, 1, out_c_type, out_buf, sizeof(out_buf), &out_len); CHKFetch("S"); CHKFetch("No"); CHKMoreResults("No"); /* test results */ odbc_c2string(sbuf, out_c_type, out_buf, out_len); if (!ignore_result && strcmp(sbuf, expected) != 0) { fprintf(stderr, "Wrong result\n Got: %s\n Expected: %s\n", sbuf, expected); result = 1; } ignore_select_error = 0; ignore_result = 0; }
static int CheckPhantom(void) { SQLRETURN RetCode; /* transaction 2 read a row */ SWAP_CONN(); odbc_command("SELECT * FROM test_transaction WHERE t = 'initial'"); SQLMoreResults(odbc_stmt); /* transaction 1 insert a row that match critera */ SWAP_CONN(); RetCode = odbc_command2("INSERT INTO test_transaction(n, t) VALUES(2, 'initial')", "SE"); if (RetCode == SQL_ERROR) { EndTransaction(SQL_ROLLBACK); SWAP_CONN(); EndTransaction(SQL_ROLLBACK); SWAP_CONN(); return 0; /* no dirty read */ } EndTransaction(SQL_COMMIT); SWAP_CONN(); /* second transaction try to fetch commited row */ odbc_command("SELECT * FROM test_transaction WHERE t = 'initial'"); CHKFetch("S"); CHKFetch("S"); CHKFetch("No"); SQLMoreResults(odbc_stmt); EndTransaction(SQL_ROLLBACK); SWAP_CONN(); odbc_command("DELETE test_transaction WHERE n = 2"); EndTransaction(SQL_COMMIT); return 1; }
static int CheckNonrepeatableRead(void) { SQLRETURN RetCode; /* transaction 2 read a row */ SWAP_CONN(); odbc_command("SELECT * FROM test_transaction WHERE t = 'initial' AND n = 1"); SQLMoreResults(odbc_stmt); /* transaction 1 change a row and commit */ SWAP_CONN(); RetCode = odbc_command2("UPDATE test_transaction SET t = 'second' WHERE n = 1", "SE"); if (RetCode == SQL_ERROR) { EndTransaction(SQL_ROLLBACK); SWAP_CONN(); EndTransaction(SQL_ROLLBACK); SWAP_CONN(); return 0; /* no dirty read */ } EndTransaction(SQL_COMMIT); SWAP_CONN(); /* second transaction try to fetch commited row */ odbc_command("SELECT * FROM test_transaction WHERE t = 'second' AND n = 1"); CHKFetch("S"); CHKFetch("No"); SQLMoreResults(odbc_stmt); EndTransaction(SQL_ROLLBACK); SWAP_CONN(); odbc_command("UPDATE test_transaction SET t = 'initial' WHERE n = 1"); EndTransaction(SQL_COMMIT); return 1; }
int main(int argc, char *argv[]) { char buf[32]; SQLINTEGER int_buf; SQLLEN len; SQLRETURN rc; odbc_connect(); lc = 1; type = SQL_C_CHAR; test_split(""); lc = sizeof(SQLWCHAR); type = SQL_C_WCHAR; test_split(""); if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x07000000u) { lc = 1; type = SQL_C_CHAR; test_split("N"); lc = sizeof(SQLWCHAR); type = SQL_C_WCHAR; test_split("N"); } /* test with fixed length */ odbc_command("SELECT CONVERT(INT, 12345)"); CHKFetch("S"); int_buf = 0xdeadbeef; CHKGetData(1, SQL_C_SLONG, &int_buf, 0, NULL, "S"); if (int_buf != 12345) { printf("Wrong data result\n"); exit(1); } CHKGetData(1, SQL_C_SLONG, &int_buf, 0, NULL, "No"); if (int_buf != 12345) { printf("Wrong data result 2 res = %d\n", (int) int_buf); exit(1); } odbc_reset_statement(); /* test with numeric */ odbc_command("SELECT CONVERT(NUMERIC(18,5), 1850000000000)"); CHKFetch("S"); memset(buf, 'x', sizeof(buf)); CHKGetData(1, SQL_C_CHAR, buf, 14, NULL, "S"); buf[sizeof(buf)-1] = 0; if (strcmp(buf, "1850000000000") != 0) { printf("Wrong data result: %s\n", buf); exit(1); } /* should give NO DATA */ CHKGetData(1, SQL_C_CHAR, buf, 14, NULL, "No"); buf[sizeof(buf)-1] = 0; if (strcmp(buf, "1850000000000") != 0) { printf("Wrong data result 3 res = %s\n", buf); exit(1); } odbc_reset_statement(); /* test int to truncated string */ odbc_command("SELECT CONVERT(INTEGER, 12345)"); CHKFetch("S"); /* error 22003 */ memset(buf, 'x', sizeof(buf)); CHKGetData(1, SQL_C_CHAR, buf, 4, NULL, "E"); #ifdef ENABLE_DEVELOPING buf[4] = 0; if (strcmp(buf, "xxxx") != 0) { fprintf(stderr, "Wrong buffer result buf = %s\n", buf); exit(1); } #endif odbc_read_error(); if (strcmp(odbc_sqlstate, "22003") != 0) { fprintf(stderr, "Unexpected sql state %s returned\n", odbc_sqlstate); odbc_disconnect(); exit(1); } CHKGetData(1, SQL_C_CHAR, buf, 2, NULL, "No"); odbc_reset_statement(); /* test unique identifier to truncated string */ rc = odbc_command2("SELECT CONVERT(UNIQUEIDENTIFIER, 'AA7DF450-F119-11CD-8465-00AA00425D90')", "SENo"); if (rc != SQL_ERROR) { CHKFetch("S"); /* error 22003 */ CHKGetData(1, SQL_C_CHAR, buf, 17, NULL, "E"); odbc_read_error(); if (strcmp(odbc_sqlstate, "22003") != 0) { fprintf(stderr, "Unexpected sql state %s returned\n", odbc_sqlstate); odbc_disconnect(); exit(1); } CHKGetData(1, SQL_C_CHAR, buf, 2, NULL, "No"); } odbc_reset_statement(); odbc_disconnect(); odbc_use_version3 = 1; odbc_connect(); /* test error from SQLGetData */ /* wrong constant, SQL_VARCHAR is invalid as C type */ test_err("prova 123", SQL_VARCHAR, "HY003"); /* use ARD but no ARD data column */ test_err("prova 123", SQL_ARD_TYPE, "07009"); /* wrong conversion, int */ test_err("prova 123", SQL_C_LONG, "22018"); /* wrong conversion, date */ test_err("prova 123", SQL_C_TIMESTAMP, "22018"); /* overflow */ test_err("1234567890123456789", SQL_C_LONG, "22003"); /* test for empty string from mssql */ if (odbc_db_is_microsoft()) { lc = 1; type = SQL_C_CHAR; for (;;) { void *buf = ODBC_GET(lc); odbc_command("SELECT CONVERT(TEXT,'')"); CHKFetch("S"); len = 1234; CHKGetData(1, type, buf, lc, &len, "S"); if (len != 0) { fprintf(stderr, "Wrong len returned, returned %ld\n", (long) len); return 1; } CHKGetData(1, type, buf, lc, NULL, "No"); odbc_reset_statement(); ODBC_FREE(); buf = ODBC_GET(4096*lc); odbc_command("SELECT CONVERT(TEXT,'')"); CHKFetch("S"); len = 1234; CHKGetData(1, type, buf, lc*4096, &len, "S"); if (len != 0) { fprintf(stderr, "Wrong len returned, returned %ld\n", (long) len); return 1; } CHKGetData(1, type, buf, lc*4096, NULL, "No"); odbc_reset_statement(); ODBC_FREE(); if (type != SQL_C_CHAR) break; lc = sizeof(SQLWCHAR); type = SQL_C_WCHAR; } odbc_command("SELECT CONVERT(TEXT,'')"); CHKFetch("S"); len = 1234; CHKGetData(1, SQL_C_BINARY, buf, 1, &len, "S"); if (len != 0) { fprintf(stderr, "Wrong len returned, returned %ld\n", (long) len); return 1; } CHKGetData(1, SQL_C_BINARY, buf, 1, NULL, "No"); } odbc_disconnect(); printf("Done.\n"); return 0; }
static int test(int odbc3) { SQLLEN cnamesize; const char *query; odbc_use_version3 = odbc3; odbc_connect(); /* issue print statement and test message returned */ output[0] = 0; query = "print 'START' select count(*) from sysobjects where name='sysobjects' print 'END'"; odbc_command2(query, "I"); odbc_read_error(); if (!strstr(odbc_err, "START")) { printf("Message invalid\n"); return 1; } odbc_err[0] = 0; if (odbc3) { ODBC_CHECK_COLS(0); ODBC_CHECK_ROWS(-1); CHKFetch("E"); CHKMoreResults("S"); } ODBC_CHECK_COLS(1); ODBC_CHECK_ROWS(-1); CHKFetch("S"); ODBC_CHECK_COLS(1); ODBC_CHECK_ROWS(-1); /* check no data */ CHKFetch("No"); ODBC_CHECK_COLS(1); ODBC_CHECK_ROWS(1); /* SQLMoreResults return NO DATA or SUCCESS WITH INFO ... */ if (tds_no_dm && !odbc3) CHKMoreResults("No"); else if (odbc3) CHKMoreResults("I"); else CHKMoreResults("INo"); /* * ... but read error * (unixODBC till 2.2.11 do not read errors on NO DATA, skip test) */ if (tds_no_dm || odbc3) { odbc_read_error(); if (!strstr(odbc_err, "END")) { printf("Message invalid\n"); return 1; } odbc_err[0] = 0; } if (odbc3) { ODBC_CHECK_COLS(0); ODBC_CHECK_ROWS(-1); CHKMoreResults("No"); } /* issue invalid command and test error */ odbc_command2("SELECT donotexistsfield FROM donotexiststable", "E"); odbc_read_error(); /* test no data returned */ CHKFetch("E"); odbc_read_error(); CHKGetData(1, SQL_C_CHAR, output, sizeof(output), &cnamesize, "E"); odbc_read_error(); odbc_disconnect(); return 0; }
int main(int argc, char *argv[]) { SQLINTEGER len, out; int i; SQLHSTMT stmt1, stmt2; SQLHSTMT *pcur_stmt = NULL; odbc_use_version3 = 1; odbc_set_conn_attr = my_attrs; odbc_connect(); stmt1 = odbc_stmt; out = 0; len = sizeof(out); CHKGetConnectAttr(1224, (SQLPOINTER) &out, sizeof(out), &len, "S"); /* test we really support MARS on this connection */ /* TODO should out be correct ?? */ printf("Following row can contain an error due to MARS detection (is expected)\n"); if (!out || odbc_command2("BEGIN TRANSACTION", "SNoE") != SQL_ERROR) { printf("MARS not supported for this connection\n"); odbc_disconnect(); odbc_test_skipped(); return 0; } odbc_read_error(); if (!strstr(odbc_err, "MARS")) { printf("Error message invalid \"%s\"\n", odbc_err); return 1; } /* create a test table with some data */ odbc_command("create table #mars1 (n int, v varchar(100))"); for (i = 0; i < 60; ++i) { char cmd[120], buf[80]; memset(buf, 'a' + (i % 26), sizeof(buf)); buf[i * 7 % 73] = 0; sprintf(cmd, "insert into #mars1 values(%d, '%s')", i, buf); odbc_command(cmd); } /* and another to avid locking problems */ odbc_command("create table #mars2 (n int, v varchar(100))"); AutoCommit(SQL_AUTOCOMMIT_OFF); /* try to do a select which return a lot of data (to test server didn't cache everything) */ odbc_command("select a.n, b.n, a.v from #mars1 a, #mars1 b order by a.n, b.n"); CHKFetch("S"); /* try to do other commands */ CHKAllocStmt(&stmt2, "S"); SET_STMT(stmt2); odbc_command("insert into #mars2 values(1, 'foo')"); SET_STMT(stmt1); CHKFetch("S"); /* reset statements */ odbc_reset_statement(); SET_STMT(stmt2); odbc_reset_statement(); /* now to 2 select with prepare/execute */ CHKPrepare(T("select a.n, b.n, a.v from #mars1 a, #mars1 b order by a.n, b.n"), SQL_NTS, "S"); SET_STMT(stmt1); CHKPrepare(T("select a.n, b.n, a.v from #mars1 a, #mars1 b order by a.n desc, b.n"), SQL_NTS, "S"); SET_STMT(stmt2); CHKExecute("S"); SET_STMT(stmt1); CHKExecute("S"); SET_STMT(stmt2); CHKFetch("S"); SET_STMT(stmt1); CHKFetch("S"); SET_STMT(stmt2); CHKFetch("S"); odbc_reset_statement(); SET_STMT(stmt1); CHKFetch("S"); odbc_reset_statement(); EndTransaction(SQL_COMMIT); /* TODO test receiving large data should not take much memory */ odbc_disconnect(); return 0; }
static void Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, const char *expected) { unsigned char out_buf[256]; SQLLEN out_len = 0; SQL_NUMERIC_STRUCT *num; SQLWCHAR *wp; int i; SQLFreeStmt(odbc_stmt, SQL_UNBIND); SQLFreeStmt(odbc_stmt, SQL_RESET_PARAMS); /* execute a select to get data as wire */ sprintf(sbuf, "SELECT CONVERT(%s, '%s') AS data", type, value_to_convert); if (strncmp(value_to_convert, "0x", 2) == 0) sprintf(sbuf, "SELECT CONVERT(%s, %s) COLLATE Latin1_General_CI_AS AS data", type, value_to_convert); else if (strcmp(type, "SQL_VARIANT") == 0) sprintf(sbuf, "SELECT CONVERT(SQL_VARIANT, %s) AS data", value_to_convert); else if (strncmp(value_to_convert, "u&'", 3) == 0) sprintf(sbuf, "SELECT CONVERT(%s, %s) AS data", type, value_to_convert); if (ignore_select_error) { if (odbc_command2(sbuf, "SENo") == SQL_ERROR) { odbc_reset_statement(); return; } } else { odbc_command(sbuf); } ignore_select_error = 0; SQLBindCol(odbc_stmt, 1, out_c_type, out_buf, sizeof(out_buf), &out_len); CHKFetch("S"); CHKFetch("No"); CHKMoreResults("No"); /* test results */ sbuf[0] = 0; switch (out_c_type) { case SQL_C_NUMERIC: num = (SQL_NUMERIC_STRUCT *) out_buf; sprintf(sbuf, "%d %d %d ", num->precision, num->scale, num->sign); i = SQL_MAX_NUMERIC_LEN; for (; i > 0 && !num->val[--i];); for (; i >= 0; --i) sprintf(strchr(sbuf, 0), "%02X", num->val[i]); break; case SQL_C_BINARY: assert(out_len >= 0); for (i = 0; i < out_len; ++i) sprintf(strchr(sbuf, 0), "%02X", (int) out_buf[i]); break; case SQL_C_CHAR: out_buf[sizeof(out_buf) - 1] = 0; sprintf(sbuf,"%u %s", (unsigned int) strlen((char *) out_buf), out_buf); break; case SQL_C_WCHAR: assert(out_len >=0 && (out_len % sizeof(SQLWCHAR)) == 0); sprintf(sbuf, "%u ", (unsigned int) (out_len / sizeof(SQLWCHAR))); wp = (SQLWCHAR*) out_buf; for (i = 0; i < out_len / sizeof(SQLWCHAR); ++i) if ((unsigned int) wp[i] < 256) sprintf(strchr(sbuf, 0), "%c", (char) wp[i]); else sprintf(strchr(sbuf, 0), "\\u%04x", (unsigned int) wp[i]); break; case SQL_C_LONG: assert(out_len == sizeof(SQLINTEGER)); sprintf(sbuf, "%ld", (long int) *((SQLINTEGER *) out_buf)); break; default: /* not supported */ assert(0); break; } if (strcmp(sbuf, expected) != 0) { fprintf(stderr, "Wrong result\n Got: %s\n Expected: %s\n", sbuf, expected); result = 1; } }
int main(int argc, char *argv[]) { int cond = 1; #define TEST_FILE "data.in" const char *in_file = FREETDS_SRCDIR "/" TEST_FILE; FILE *f; odbc_connect(); odbc_init_bools(); f = fopen(in_file, "r"); if (!f) f = fopen(TEST_FILE, "r"); if (!f) { fprintf(stderr, "error opening test file\n"); exit(1); } odbc_init_parser(f); for (;;) { char *p; const char *cmd = odbc_get_cmd_line(&p, &cond); if (!cmd) break; /* select type */ if (!strcmp(cmd, "select")) { const char *type = odbc_get_tok(&p); const char *value = odbc_get_str(&p); int c_type = lookup(odbc_get_tok(&p), sql_c_types); const char *expected = odbc_get_str(&p); if (!cond) continue; ignore_select_error = 1; Test(type, value, c_type, expected); continue; } /* select type setting condition */ if (!strcmp(cmd, "select_cond")) { const char *bool_name = odbc_get_tok(&p); const char *type = odbc_get_tok(&p); const char *value = odbc_get_str(&p); int c_type = lookup(odbc_get_tok(&p), sql_c_types); const char *expected = odbc_get_str(&p); int save_result = result; if (!bool_name) odbc_fatal(": no condition name\n"); if (!cond) continue; ignore_select_error = 1; ignore_result = 1; result = 0; Test(type, value, c_type, expected); odbc_set_bool(bool_name, result == 0); result = save_result; continue; } /* execute a sql command */ if (!strcmp(cmd, "sql")) { const char *sql = odbc_get_str(&p); if (!cond) continue; odbc_command(sql); continue; } if (!strcmp(cmd, "sql_cond")) { const char *bool_name = odbc_get_tok(&p); const char *sql = odbc_get_str(&p); if (!cond) continue; odbc_set_bool(bool_name, odbc_command2(sql, "SENo") != SQL_ERROR); continue; } odbc_fatal(": unknown command\n"); } odbc_clear_bools(); fclose(f); printf("\n"); odbc_disconnect(); if (!result) printf("Done successfully!\n"); return result; }