Example #1
0
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;
}
Example #2
0
int
main(void)
{
	odbc_use_version3 = 1;

	odbc_mark_sockets_opened();
	odbc_connect();

	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_OFF, 0, "S");

	odbc_command("SELECT 1");
	CHKMoreResults("No");

	if (!close_last_socket()) {
		fprintf(stderr, "Error closing connection\n");
		return 1;
	}
	CHKEndTran(SQL_HANDLE_DBC, odbc_conn, SQL_ROLLBACK, "E");

	/* the error should be written in the connection, not in the statement */
	ReadErrorConn();
	if (strcmp(odbc_sqlstate, "08S01") != 0 || strstr(odbc_err, "Write to the server") == NULL) {
		odbc_disconnect();
		fprintf(stderr, "Unexpected error message %s %s\n", odbc_sqlstate, odbc_err);
		return 1;
	}

	odbc_disconnect();
	return 0;
}
Example #3
0
int
main(int argc, char **argv)
{
	if (tds_mutex_init(&mtx))
		return 1;

	if (odbc_read_login_info())
		exit(1);

	/*
	 * prepare our odbcinst.ini
	 * is better to do it before connect cause uniODBC cache INIs
	 * the name must be odbcinst.ini cause unixODBC accept only this name
	 */
	if (odbc_driver[0]) {
		FILE *f = fopen("odbcinst.ini", "w");

		if (f) {
			fprintf(f, "[FreeTDS]\nDriver = %s\nThreading = 0\n", odbc_driver);
			fclose(f);
			/* force iODBC */
			setenv("ODBCINSTINI", "./odbcinst.ini", 1);
			setenv("SYSODBCINSTINI", "./odbcinst.ini", 1);
			/* force unixODBC (only directory) */
			setenv("ODBCSYSINI", ".", 1);
		}
	}

	odbc_use_version3 = 1;
	odbc_connect();

	odbc_command("IF OBJECT_ID('tab1') IS NOT NULL DROP TABLE tab1");
	odbc_command("CREATE TABLE tab1 ( k INT, vc VARCHAR(200) )");

	printf(">> Creating tab1...\n");
	odbc_command("DECLARE @i INT\n"
		"SET @i = 1\n"
		"WHILE @i <= 2000 BEGIN\n"
		"INSERT INTO tab1 VALUES ( @i, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' )\n"
		"SET @i = @i + 1\n"
		"END");
	while (CHKMoreResults("SNo") == SQL_SUCCESS)
		continue;
	printf(">> ...done.\n");

	odbc_reset_statement();

	Test(0, 0);
	Test(1, 0);
	Test(0, 1);
	Test(1, 1);

	odbc_command("DROP TABLE tab1");

	odbc_disconnect();
	return 0;
}
Example #4
0
static void
DoTest(int prepared)
{
	odbc_command("create table #odbctestdata (i int)");

	/* test that 2 empty result set are returned correctly */
	if (!prepared) {
		odbc_command("select * from #odbctestdata select * from #odbctestdata");
	} else {
		CHKPrepare(T("select * from #odbctestdata select * from #odbctestdata"), SQL_NTS, "S");
		CHKExecute("S");
	}

	CHKFetch("No");

	CHKMoreResults("S");
	printf("Getting next recordset\n");

	CHKFetch("No");

	CHKMoreResults("No");

	/* test that skipping a no empty result go to other result set */
	odbc_command("insert into #odbctestdata values(123)");
	if (!prepared) {
		odbc_command("select * from #odbctestdata select * from #odbctestdata");
	} else {
		CHKPrepare(T("select * from #odbctestdata select * from #odbctestdata"), SQL_NTS, "S");
		CHKExecute("S");
	}

	CHKMoreResults("S");
	printf("Getting next recordset\n");

	CHKFetch("S");

	CHKFetch("No");

	CHKMoreResults("No");

	odbc_command("drop table #odbctestdata");

	ODBC_FREE();
}
Example #5
0
static void
Flushodbc_stmt(void)
{
	while (CHKFetch("SNo") == SQL_SUCCESS)
		;

	/* Sybase store procedure seems to return extra empty results */
	while (CHKMoreResults("SNo") == SQL_SUCCESS)
		;
}
Example #6
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();
}
Example #7
0
static void
CheckNoRow(const char *query)
{
	SQLRETURN rc;

	rc = CHKExecDirect(T(query), SQL_NTS, "SINo");
	if (rc == SQL_NO_DATA)
		return;

	do {
		SQLSMALLINT cols;

		CHKNumResultCols(&cols, "S");
		if (cols != 0) {
			fprintf(stderr, "Data not expected here, query:\n\t%s\n", query);
			exit(1);
		}
	} while (CHKMoreResults("SNo") == SQL_SUCCESS);
}
Example #8
0
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;
}
Example #9
0
static void
TestInsert(char *buf)
{
	SQLLEN ind;
	int l = strlen(buf);
	char sql[200];

	/* insert some data and test success */
	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, l, 0, buf, l, &ind, "S");

	ind = l;
	CHKExecute("S");

	SWAP_STMT(stmt);
	sprintf(sql, "SELECT 1 FROM #tmp1 WHERE c = '%s'", buf);
	odbc_command(sql);
	CHKFetch("S");
	CHKFetch("No");
	CHKMoreResults("No");
	SWAP_STMT(stmt);
}
Example #10
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;
}
Example #11
0
int
main(int argc, char *argv[])
{
	char output[256];
	SQLLEN dataSize;

	odbc_connect();

	odbc_command_with_result(odbc_stmt, "drop proc sp_norowset_test");

	odbc_command("create proc sp_norowset_test as begin declare @i int end");

	odbc_command("exec sp_norowset_test");

	/* note, mssql 2005 seems to not return row for tempdb, use always master */
	odbc_command("select name from master..sysobjects where name = 'sysobjects'");
	CHKFetch("S");

	CHKGetData(1, SQL_C_CHAR, output, sizeof(output), &dataSize, "S");

	if (strcmp(output, "sysobjects") != 0) {
		printf("Unexpected result\n");
		exit(1);
	}

	CHKFetch("No");

	CHKMoreResults("No");

	odbc_command("drop proc sp_norowset_test");

	odbc_disconnect();

	printf("Done.\n");
	return 0;
}
Example #12
0
int
main(int argc, char *argv[])
{
	odbc_connect();

	/* MSSQL 2012+, compute not supported */
	if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x0b000000u) {
		odbc_disconnect();
		return 0;
	}

	odbc_command("create table #tmp1 (c varchar(20), i int)");
	odbc_command("insert into #tmp1 values('pippo', 12)");
	odbc_command("insert into #tmp1 values('pippo', 34)");
	odbc_command("insert into #tmp1 values('pluto', 1)");
	odbc_command("insert into #tmp1 values('pluto', 2)");
	odbc_command("insert into #tmp1 values('pluto', 3)");


	/* 
	 * TODO skip rows/column on compute (compute.c)
	 * TODO check rows/column after moreresults after compute
	 */


	/* select * from #tmp1 compute sum(i) */
	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
	odbc_command("select * from #tmp1 order by c, i compute sum(i)");
	CheckFetch("c", "pippo", "12");
	CheckFetch("c", "pippo", "34");
	CheckFetch("c", "pluto", "1");
	CheckFetch("c", "pluto", "2");
	CheckFetch("c", "pluto", "3");
	CHKFetch("No");
	CHKMoreResults("S");

	/* why I need to rebind ?? ms bug of feature ?? */
	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
	col2[0] = '@';
	CheckFetch("sum", "52", "@");
	CHKFetch("No");
	CHKMoreResults("No");




	/* select * from #tmp1 order by c compute sum(i) by c */
	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
	odbc_command("select c as mao, i from #tmp1 order by c, i compute sum(i) by c compute max(i)");
	CheckFetch("mao", "pippo", "12");
	CheckFetch("mao", "pippo", "34");
	CHKFetch("No");
	CHKMoreResults("S");

	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
	strcpy(col2, "##");
	CheckFetch("sum", "46", "##");
	CHKFetch("No");
	CHKMoreResults("S");

	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
	CheckFetch("mao", "pluto", "1");
	CheckFetch("mao", "pluto", "2");
	CheckFetch("mao", "pluto", "3");
	CHKFetch("No");
	CHKMoreResults("S");

	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
	strcpy(col2, "%");
	CheckFetch("sum", "6", "%");
	CHKFetch("No");
	CHKMoreResults("S");

	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
	strcpy(col2, "&");
	CheckFetch("max", "34", "&");
	CHKFetch("No");
	CHKMoreResults("No");



	/* test skip recordset with computed rows */

	/* select * from #tmp1 where i = 2 compute min(i) */
	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
	odbc_command("select * from #tmp1 where i = 2 or i = 34 order by c, i compute min(i) by c");
	CheckFetch("c", "pippo", "34");
	CHKFetch("No");
	CHKMoreResults("S");

	/* here just skip results, before a row */
	CHKMoreResults("S");

	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
	CheckFetch("c", "pluto", "2");
	CHKFetch("No");
	CHKMoreResults("S");

	/* here just skip results, before done */
	CHKMoreResults("No");


	odbc_disconnect();
	return 0;
}
Example #13
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();
}
Example #14
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;
}
Example #15
0
static void
Test(int level)
{
	SQLRETURN result;
	SQLSMALLINT InParam = level;
	SQLSMALLINT OutParam = 1;
	SQLLEN cbReturnCode = 0, cbInParam = 0, cbOutParam = 0;
	SQLLEN cbOutString = SQL_NTS;

	char sql[80];

	printf("ODBC %d nocount %s select %s level %d\n", odbc_use_version3 ? 3 : 2,
	       g_nocount ? "yes" : "no", g_second_select ? "yes" : "no", level);

	ReturnCode = INVALID_RETURN;
	memset(&OutString, 0, sizeof(OutString));

	/* test with SQLExecDirect */
	sprintf(sql, "RAISERROR('An error occurred.', %d, 1)", level);
	result = odbc_command_with_result(odbc_stmt, sql);

	TestResult(result, level, "SQLExecDirect");

	/* test with SQLPrepare/SQLExecute */
	if (!SQL_SUCCEEDED(SQLPrepare(odbc_stmt, T(SP_TEXT), strlen(SP_TEXT)))) {
		fprintf(stderr, "SQLPrepare failure!\n");
		exit(1);
	}

	SQLBindParameter(odbc_stmt, 1, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &ReturnCode, 0, &cbReturnCode);
	SQLBindParameter(odbc_stmt, 2, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &InParam, 0, &cbInParam);
	SQLBindParameter(odbc_stmt, 3, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &OutParam, 0, &cbOutParam);
	strcpy(OutString, "Invalid!");
	SQLBindParameter(odbc_stmt, 4, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, OUTSTRING_LEN, 0, OutString, OUTSTRING_LEN,
			 &cbOutString);

	CHKExecute("S");

	/* first select, check data are returned.
	 * SET statements before does not affect results
	 */
	CheckData("");
	CHKFetch("S");
	CheckData("Here is the first row");

	result = SQLFetch(odbc_stmt);
	if (odbc_use_version3) {
		SQLTCHAR SqlState[6];
		SQLINTEGER NativeError;
		SQLTCHAR MessageText[1000];
		SQLSMALLINT TextLength;
		SQLRETURN expected;
		SQLLEN rows;

		if (result != SQL_NO_DATA)
			ODBC_REPORT_ERROR("SQLFetch should return NO DATA");
		CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, SqlState, &NativeError, MessageText,
				       ODBC_VECTOR_SIZE(MessageText), &TextLength, "No");
		result = SQLMoreResults(odbc_stmt);
		expected = level > 10 ? SQL_ERROR : SQL_SUCCESS_WITH_INFO;
		if (result != expected)
			ODBC_REPORT_ERROR("SQLMoreResults returned unexpected result");
		if (!g_second_select && g_nocount) {
			if (ReturnCode == INVALID_RETURN) {
				result = SQLMoreResults(odbc_stmt);
			} else {
				CheckReturnCode(result, 0);
				ReturnCode = INVALID_RETURN;
				TestResult(result, level, "SQLMoreResults");
				ReturnCode = 0;
			}
		} else {
			TestResult(result, level, "SQLMoreResults");
		}

		/* a recordset with only warnings/errors do not contains rows */
		if (CHKRowCount(&rows, "SE") == SQL_SUCCESS && rows != -1)
			ODBC_REPORT_ERROR("SQLRowCount returned some rows");
	} else {
		/* in ODBC 2 errors/warnings are not handled as different recordset */
		TestResult(result, level, "SQLFetch");
	}

	if (odbc_driver_is_freetds())
		CheckData("");

	if (!g_second_select) {
		SQLLEN rows;

		if (CHKRowCount(&rows, "SE") == SQL_SUCCESS && rows != -1)
			ODBC_REPORT_ERROR("SQLRowCount returned some rows");
		CheckReturnCode(result, g_nocount ? 0 : INVALID_RETURN);

		result = SQLMoreResults(odbc_stmt);
#ifdef ENABLE_DEVELOPING
		if (result != SQL_NO_DATA)
			ODBC_REPORT_ERROR("SQLMoreResults should return NO DATA");

		ODBC_CHECK_ROWS(-2);
#endif
		CheckReturnCode(result, 0);
		return;
	}

	if (!odbc_use_version3 || !g_nocount) {
		/* mssql 2008 return SUCCESS_WITH_INFO with previous error */
		CHKMoreResults("S");
		result = SQL_SUCCESS;
	}

	CheckReturnCode(result, INVALID_RETURN);

	CheckData("");
	if (g_nocount && odbc_use_version3 && g_second_select && level >= 10) {
		if (CHKFetch("SE") == SQL_ERROR) {
			SQLMoreResults(odbc_stmt);
			CHKFetch("S");
		}
	} else {
		CHKFetch("S");
	}
	CheckData("Here is the last row");

	CHKFetch("No");
	CheckData("");

	if (!odbc_use_version3 || g_nocount)
		CheckReturnCode(result, 0);
#ifdef ENABLE_DEVELOPING
	else
		CheckReturnCode(result, INVALID_RETURN);
#endif

	/* FIXME how to handle return in store procedure ??  */
	result = SQLMoreResults(odbc_stmt);
#ifdef ENABLE_DEVELOPING
	if (result != SQL_NO_DATA)
		ODBC_REPORT_ERROR("SQLMoreResults return other data");
#endif

	CheckReturnCode(result, 0);

	CheckData("");
	ODBC_FREE();
}
Example #16
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;
	}
}
Example #17
0
static void
DoTest(int prepare)
{
	int n = 0;
	static const char query[] =
		/* on prepared this recordset should be skipped */
		"DECLARE @b INT SELECT @b = 25 "
		"SELECT * FROM #tmp1 WHERE i <= 3 "
		/* on prepare we cannot distinguish these recordset */
		"INSERT INTO #tmp2 SELECT * FROM #tmp1 WHERE i = 1 "
		"INSERT INTO #tmp2 SELECT * FROM #tmp1 WHERE i <= 3 "
		"SELECT * FROM #tmp1 WHERE i = 1 "
		/* but FreeTDS can detect last recordset */
		"UPDATE #tmp1 SET i=i+1 WHERE i >= 2";

	if (prepare) {
		CHKPrepare(T(query), SQL_NTS, "S");
		CHKExecute("S");
	} else {

		/* execute a batch command select insert insert select and check rows */
		CHKExecDirect(T(query), SQL_NTS, "S");
	}
	if (!prepare) {
		printf("Result %d\n", ++n);
		ODBC_CHECK_COLS(0);
		ODBC_CHECK_ROWS(1);
		CHKMoreResults("S");
	}
	printf("Result %d\n", ++n);
	ODBC_CHECK_COLS(1);
	ODBC_CHECK_ROWS(-1);
	CHKFetch("S");
	CHKFetch("S");
	ODBC_CHECK_COLS(1);
	ODBC_CHECK_ROWS(-1);
	CHKFetch("No");
	ODBC_CHECK_COLS(1);
	ODBC_CHECK_ROWS(2);
	CHKMoreResults("S");
	if (!prepare) {
		printf("Result %d\n", ++n);
		ODBC_CHECK_COLS(0);
		ODBC_CHECK_ROWS(1);
		CHKMoreResults("S");
		printf("Result %d\n", ++n);
		ODBC_CHECK_COLS(0);
		ODBC_CHECK_ROWS(2);
		CHKMoreResults("S");
	}
	printf("Result %d\n", ++n);
	ODBC_CHECK_COLS(1);
	ODBC_CHECK_ROWS(-1);
	CHKFetch("S");
	ODBC_CHECK_COLS(1);
	ODBC_CHECK_ROWS(-1);
	CHKFetch("No");
	ODBC_CHECK_COLS(1);
	if (prepare) {
		/* collapse 2 recordset... after a lot of testing this is the behavior! */
		if (odbc_driver_is_freetds())
			ODBC_CHECK_ROWS(2);
	} else {
		ODBC_CHECK_ROWS(1);
		CHKMoreResults("S");
		ODBC_CHECK_COLS(0);
		ODBC_CHECK_ROWS(2);
	}

	CHKMoreResults("No");
#ifndef TDS_NO_DM
	if (!prepare)
		ODBC_CHECK_COLS(-1);
	ODBC_CHECK_ROWS(-2);
#endif
	ODBC_FREE();
}