Example #1
0
static void
test_with_conversions(void)
{
	SQLLEN ind, ind2, ind3;
	char out2[30];

	/*
	 * test from Bower, Wayne
	 * Cfr ML 2012-03-02 "[freetds] [unixODBC][Driver Manager]Function sequence error (SQL-HY010)"
	 */
	odbc_use_version3 = 1;
	odbc_connect();

	odbc_command("IF OBJECT_ID('TMP_SP_Test_ODBC') IS NOT NULL DROP PROC TMP_SP_Test_ODBC");
	odbc_command("create proc TMP_SP_Test_ODBC @i int,\n@o int output\nas\nset nocount on\nselect @o = 55\nreturn 9\n");
	odbc_reset_statement();

	CHKPrepare(T("{ ? = call TMP_SP_Test_ODBC (?, ?) }"), SQL_NTS, "S");

	ind2 = 2;
	CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 80, 0, "10", 2, &ind2, "S");
	ind3 = SQL_NULL_DATA;
	strcpy(out2, " ");
	CHKBindParameter(3, SQL_PARAM_INPUT_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, 0, 1, out2, 29, &ind3, "S");
	ind = 1;
	CHKBindParameter(1, SQL_PARAM_INPUT_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, 0, 1, out2, 29, &ind, "S");

	/* mssql returns SUCCESS */
	CHKExecute("No");

	ODBC_CHECK_COLS(0);

	odbc_reset_statement();
	odbc_command("drop proc TMP_SP_Test_ODBC");


	odbc_disconnect();
}
Example #2
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 #3
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();
}
Example #4
0
int
main(int argc, char *argv[])
{
	SQLINTEGER input, output;
	SQLLEN ind, ind2, ind3, ind4;
	SQLINTEGER out1;
	char out2[30];

	odbc_connect();

	odbc_command("IF OBJECT_ID('simpleresult') IS NOT NULL DROP PROC simpleresult");

	odbc_command("create proc simpleresult @i int as begin return @i end");

	CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &input, 0, &ind2, "S");
	CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind, "S");

	CHKPrepare(T("{ \n?\t\r= call simpleresult(?)}"), SQL_NTS, "S");

	input = 123;
	ind2 = sizeof(input);
	output = 0xdeadbeef;
	CHKExecute("S");

	if (output != 123) {
		printf("Invalid result\n");
		exit(1);
	}

	/* should return "Invalid cursor state" */
	if (SQLFetch(odbc_stmt) != SQL_ERROR) {
		printf("Data not expected\n");
		exit(1);
	}
	ODBC_CHECK_COLS(0);

	/* just to reset some possible buffers */
	odbc_command("DECLARE @i INT");

	/* same test but with SQLExecDirect and same bindings */
	input = 567;
	ind2 = sizeof(input);
	output = 0xdeadbeef;
	CHKExecDirect(T("{?=call simpleresult(?)}"), SQL_NTS, "S");

	if (output != 567) {
		fprintf(stderr, "Invalid result\n");
		exit(1);
	}

	/* should return "Invalid cursor state" */
	CHKFetch("E");

	odbc_command("drop proc simpleresult");

	odbc_command("IF OBJECT_ID('simpleresult2') IS NOT NULL DROP PROC simpleresult2");

	/* force cursor close */
	SQLCloseCursor(odbc_stmt);

	/* test output parameter */
	odbc_command("create proc simpleresult2 @i int, @x int output, @y varchar(20) output as begin select @x = 6789 select @y = 'test foo' return @i end");

	CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0,  0, &output, 0,            &ind,  "S");
	CHKBindParameter(2, SQL_PARAM_INPUT,  SQL_C_SLONG, SQL_INTEGER, 0,  0, &input,  0,            &ind2, "S");
	CHKBindParameter(3, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0,  0, &out1,   0,            &ind3, "S");
	CHKBindParameter(4, SQL_PARAM_OUTPUT, SQL_C_CHAR,  SQL_VARCHAR, 20, 0, out2,    sizeof(out2), &ind4, "S");

	CHKPrepare(T("{ \n?\t\r= call simpleresult2(?,?,?)}"), SQL_NTS, "S");

	input = 987;
	ind2 = sizeof(input);
	out1 = 888;
	output = 0xdeadbeef;
	ind3 = SQL_DATA_AT_EXEC;
	ind4 = SQL_DEFAULT_PARAM;
	strcpy(out2, "bad!");
	CHKExecute("S");

	if (output != 987 || ind3 <= 0 || ind4 <= 0 || out1 != 6789 || strcmp(out2, "test foo") != 0) {
		printf("ouput = %d ind3 = %d ind4 = %d out1 = %d out2 = %s\n", (int) output, (int) ind3, (int) ind4, (int) out1,
		       out2);
		printf("Invalid result\n");
		exit(1);
	}

	/* should return "Invalid cursor state" */
	CHKFetch("E");

	ODBC_CHECK_COLS(0);

	odbc_command("drop proc simpleresult2");

	/*
	 * test from shiv kumar
	 * Cfr ML 2006-11-21 "specifying a 0 for the StrLen_or_IndPtr in the
	 * SQLBindParameter call is not working on AIX"
	 */
	odbc_command("IF OBJECT_ID('rpc_read') IS NOT NULL DROP PROC rpc_read");

	odbc_reset_statement();

	odbc_command("create proc rpc_read @i int, @x timestamp as begin select 1 return 1234 end");
	SQLCloseCursor(odbc_stmt);

	CHKPrepare(T("{ ? = CALL rpc_read ( ?, ? ) }"), SQL_NTS, "S");

	ind = 0;
	CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &output, 0, &ind, "S");

	ind2 = 0;
	CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &input, 0, &ind2, "S");

	ind3 = 8;
	CHKBindParameter(3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_VARBINARY, 8, 0, out2, 8, &ind3, "S");

	CHKExecute("S");

	CHKFetch("S");

	CHKFetch("No");

	odbc_reset_statement();
	odbc_command("drop proc rpc_read");

	/*
	 * Test from Joao Amaral
	 * This test SQLExecute where a store procedure returns no result
	 * This seems similar to a previous one but use set instead of select
	 * (with is supported only by mssql and do not return all stuff as 
	 * select does)
	 */
	if (odbc_db_is_microsoft()) {

		odbc_reset_statement();

		odbc_command("IF OBJECT_ID('sp_test') IS NOT NULL DROP PROC sp_test");
		odbc_command("create proc sp_test @res int output as set @res = 456");

		odbc_reset_statement();

		CHKPrepare(T("{ call sp_test(?)}"), SQL_NTS, "S");
		CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind, "S");

		output = 0xdeadbeef;
		CHKExecute("S");

		if (output != 456) {
			fprintf(stderr, "Invalid result %d(%x)\n", (int) output, (int) output);
			return 1;
		}
		odbc_command("drop proc sp_test");
	}
	odbc_disconnect();

	if (odbc_db_is_microsoft())
		test_with_conversions();

	printf("Done.\n");
	return 0;
}