Example #1
0
int
main(int argc, char *argv[])
{
	SQLSMALLINT len;
	const char * const*p;
	SQLINTEGER n;

	if (odbc_read_login_info())
		exit(1);

	/* connect string using DSN */
	init_connect();
	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;ClientCharset=UTF-8;", odbc_server, odbc_user, odbc_password, odbc_database);
	CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp)/sizeof(SQLTCHAR), &len, SQL_DRIVER_NOPROMPT, "SI");
	if (!odbc_driver_is_freetds()) {
		odbc_disconnect();
		printf("Driver is not FreeTDS, exiting\n");
		return 0;
	}

	if (!odbc_db_is_microsoft() || odbc_db_version_int() < 0x08000000u) {
		odbc_disconnect();
		printf("Test for MSSQL only\n");
		return 0;
	}

	CHKAllocStmt(&odbc_stmt, "S");

	/* create test table */
	sprintf(tmp, "IF OBJECT_ID(N'%s') IS NOT NULL DROP TABLE %s", table_name, table_name);
	odbc_command(tmp);
	sprintf(tmp, "CREATE TABLE %s (k int, c NCHAR(10), vc NVARCHAR(10))", table_name);
	odbc_command(tmp);

	/* insert with INSERT statements */
	for (n = 1, p = strings; p[0] && p[1]; p += 2, ++n) {
		sprintf(tmp, "INSERT INTO %s VALUES (%d,N'%s',N'%s')", table_name, (int) n, p[0], p[1]);
		odbc_command(tmp);
	}

	/* check rows */
	for (n = 1, p = strings_hex; p[0] && p[1]; p += 2, ++n) {
		sprintf(tmp, "IF NOT EXISTS(SELECT * FROM %s WHERE k = %d AND c = %s AND vc = %s) SELECT 1", table_name, (int) n, p[0], p[1]);
		CheckNoRow(tmp);
	}

	TestBinding(0);

	TestBinding(1);

	/* cleanup */
	sprintf(tmp, "IF OBJECT_ID(N'%s') IS NOT NULL DROP TABLE %s", table_name, table_name);
	odbc_command(tmp);

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

	if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x09000000u)
		mssql2005 = 1;

	Test(1);

	Test(0);

	odbc_disconnect();
	return 0;
}
Example #3
0
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;
}
Example #4
0
int
main(int argc, char *argv[])
{
	SQLLEN ind;
	int len = strlen(test_text), n, i;
	const char *p;
	char *pp;
	SQLPOINTER ptr;
	unsigned char buf[256], *pb;
	SQLRETURN RetCode;
	int type, lc, sql_type;

	odbc_connect();

	/* create table to hold data */
	odbc_command("CREATE TABLE #putdata (c TEXT NULL, b IMAGE NULL)");

	sql_type = SQL_LONGVARCHAR;
	type = SQL_C_CHAR;
	lc = 1;
	for (;;) {
		CHKBindParameter(1, SQL_PARAM_INPUT, type, sql_type, 0, 0, (SQLPOINTER) 123, 0, &ind, "S");
		/* length required */
		ind = SQL_LEN_DATA_AT_EXEC(len * lc);

		/* 
		 * test for char 
		 */

		CHKPrepare(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "S");

		CHKExecute("Ne");

		p = test_text;
		n = 5;
		CHKParamData(&ptr, "Ne");
		if (ptr != (SQLPOINTER) 123)
			ODBC_REPORT_ERROR("Wrong pointer from SQLParamData");
		while (*p) {
			int l = strlen(p);

			if (l < n)
				n = l;
			if (type == SQL_C_CHAR) {
				CHKPutData((char *) p, n, "S");
			} else {
				SQLWCHAR buf[256];
				CHKPutData((char *) buf, to_sqlwchar(buf, p, n), "S");
			}
			p += n;
			n *= 2;
		}
		CHKParamData(&ptr, "S");

		CHKParamData(&ptr, "E");

		/* check state  and reset some possible buffers */
		odbc_command("DECLARE @i INT");

		/* use server ntext if available */
		if (sql_type == SQL_LONGVARCHAR && odbc_db_is_microsoft() && odbc_db_version_int() >= 0x08000000u) {
			sql_type = SQL_WLONGVARCHAR;
			continue;
		}

		if (type != SQL_C_CHAR)
			break;
		sql_type = SQL_LONGVARCHAR;
		type = SQL_C_WCHAR;
		lc = sizeof(SQLWCHAR);
	}

	/* update row setting binary field */
	for (i = 0; i < 255; ++i)
		buf[i] = BYTE_AT(i);

	/* 
	 * test for binary 
	 */

	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0, 0, (SQLPOINTER) 4567, 0, &ind, "S");
	ind = SQL_LEN_DATA_AT_EXEC(254);

	CHKPrepare(T("UPDATE #putdata SET b = ?"), SQL_NTS, "S");

	CHKExecute("Ne");

	pb = buf;
	n = 7;
	CHKParamData(&ptr, "Ne");
	if (ptr != (SQLPOINTER) 4567)
		ODBC_REPORT_ERROR("Wrong pointer from SQLParamData");
	while (pb != (buf + 254)) {
		int l = buf + 254 - pb;

		if (l < n)
			n = l;
		CHKPutData((char *) pb, n, "S");
		pb += n;
		n *= 2;
	}
	CHKParamData(&ptr, "S");

	CHKParamData(&ptr, "E");

	/* check state  and reset some possible buffers */
	odbc_command("DECLARE @i2 INT");


	CHKFreeStmt(SQL_RESET_PARAMS, "S");

	/* check inserts ... there should be all equal rows */
	strcpy(sql, "IF EXISTS(SELECT * FROM #putdata WHERE CONVERT(VARBINARY(255),b) <> 0x");
	/* append binary */
	for (i = 0; i < 254; ++i)
		sprintf(strchr(sql, 0), "%02x", buf[i]);
	strcat(sql, " OR CONVERT(VARCHAR(255),c) <> '");
	/* append string */
	pp = strchr(sql, 0);
	p = test_text;
	do {
		*pp++ = *p;
		if (*p == '\'')
			*pp++ = *p;
	} while(*p++);
	strcat(sql, "') SELECT 1");
	odbc_check_no_row(sql);

	odbc_command("DELETE FROM #putdata");

	/* test len == 0 case from ML */
	type = SQL_C_CHAR;
	for (;;) {
		CHKPrepare(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "S");

		CHKBindParameter(1, SQL_PARAM_INPUT, type, SQL_LONGVARCHAR, 0, 0, (PTR) 2, 0, &ind, "S");

		ind = SQL_LEN_DATA_AT_EXEC(0);

		RetCode = CHKExecute("Ne");
		while (RetCode == SQL_NEED_DATA) {
			RetCode = SQLParamData(odbc_stmt, &ptr);
			if (RetCode == SQL_NEED_DATA) {
				if (type == SQL_C_CHAR) {
					CHKPutData("abc", 3, "S");
				} else {
					SQLWCHAR buf[10];
					CHKPutData(buf, to_sqlwchar(buf, "abc", 3), "S");
				}
			}
		}
		if (type != SQL_C_CHAR)
			break;
		type = SQL_C_WCHAR;
		odbc_reset_statement();
	}

	/* check inserts ... */
	odbc_check_no_row("IF EXISTS(SELECT * FROM #putdata WHERE c NOT LIKE 'abc') SELECT 1");

	odbc_command("DELETE FROM #putdata");

	/* test putting 0 bytes from Sebastien Flaesch */
	if (odbc_db_is_microsoft()) {
		type = SQL_C_CHAR;
		for (;;) {
			CHKPrepare(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "S");

			CHKBindParameter(1, SQL_PARAM_INPUT, type, SQL_LONGVARCHAR, 10, 0, (PTR) 2, 10, &ind, "S");

			ind = SQL_DATA_AT_EXEC;

			RetCode = CHKExecute("Ne");
			while (RetCode == SQL_NEED_DATA) {
				RetCode = SQLParamData(odbc_stmt, &ptr);
				if (RetCode == SQL_NEED_DATA)
					CHKPutData("", 0, "S");
			}
			if (type != SQL_C_CHAR)
				break;
			type = SQL_C_WCHAR;
			odbc_reset_statement();
		}

		/* check inserts ... */
		odbc_check_no_row("IF EXISTS(SELECT * FROM #putdata WHERE c NOT LIKE '') SELECT 1");
	}

	/* TODO test cancel inside SQLExecute */

	odbc_disconnect();

	printf("Done.\n");
	return 0;
}
Example #5
0
static void
AllTests(void)
{
    struct tm *ltime;
    char buf[80];
    time_t curr_time;

    SQLINTEGER y, m, d;
    char date[128];

    printf("use_cursors %d exec_direct %d prepare_before %d\n", use_cursors, exec_direct, prepare_before);

    /* test some NULLs */
    NullInput(SQL_C_CHAR, SQL_VARCHAR, "VARCHAR(100)");
    NullInput(SQL_C_CHAR, SQL_LONGVARCHAR, "TEXT");
    NullInput(SQL_C_LONG, SQL_INTEGER, "INTEGER");
    NullInput(SQL_C_LONG, SQL_LONGVARCHAR, "TEXT");
    NullInput(SQL_C_TYPE_TIMESTAMP, SQL_TYPE_TIMESTAMP, "DATETIME");
    NullInput(SQL_C_FLOAT,  SQL_REAL, "FLOAT");
    NullInput(SQL_C_NUMERIC, SQL_LONGVARCHAR, "TEXT");
    if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x08000000u)
        NullInput(SQL_C_BIT, SQL_BIT, "BIT");
    NullInput(SQL_C_DOUBLE, SQL_DOUBLE, "MONEY");

    /* FIXME why should return 38 0 as precision and scale ?? correct ?? */
    precision = 18;
    TestOutput("NUMERIC(18,2)", "123", SQL_C_NUMERIC, SQL_NUMERIC, "18 0 1 7B");
    TestOutput("DECIMAL(18,2)", "123", SQL_C_NUMERIC, SQL_DECIMAL, "18 0 1 7B");
    precision = 38;
    TestOutput("NUMERIC(18,2)", "123", SQL_C_NUMERIC, SQL_NUMERIC, "38 0 1 7B");
    TestInput(SQL_C_LONG, "INTEGER", SQL_VARCHAR, "VARCHAR(20)", "12345");
    TestInput(SQL_C_LONG, "INTEGER", SQL_LONGVARCHAR, "TEXT", "12345");
    /*
     * MS driver behavior for output parameters is different
     * former returns "313233" while newer "333133323333"
     */
    if (odbc_driver_is_freetds())
        TestOutput("VARCHAR(20)", "313233", SQL_C_BINARY, SQL_VARCHAR, "333133323333");

    only_test = 1;
    precision = 3;
    if (TestOutput("DATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP, pack("ssssssl", 2004, 2, 24, 15, 16, 17, 0))) {
        /* FIXME our driver ignore precision for date */
        precision = 3;
        /* Some MS driver incorrectly prepare with smalldatetime*/
        if (!use_cursors || odbc_driver_is_freetds()) {
            TestOutput("DATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP, pack("ll", 0x9497, 0xFBAA2C));
        }
        TestOutput("SMALLDATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP, pack("ll", 0x9497, 0xFB9640));
    } else {
        TestOutput("SMALLDATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP, pack("ssssssl", 2004, 2, 24, 15, 16, 0, 0));
    }
    TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34");

    /* test timestamp millisecond round off */
    TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.001 -> 2005-07-22 09:51:34.000");
    TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.002 -> 2005-07-22 09:51:34.003");
    TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.003 -> 2005-07-22 09:51:34.003");
    TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.004 -> 2005-07-22 09:51:34.003");
    TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.005 -> 2005-07-22 09:51:34.007");
    TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.006 -> 2005-07-22 09:51:34.007");

    /* FIXME on ms driver first SQLFetch return SUCCESS_WITH_INFO for truncation error */
    TestInput(SQL_C_TYPE_DATE, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 13:02:03 -> 2005-07-22 00:00:00");

    /* replace date information with current date */
    time(&curr_time);
    ltime = localtime(&curr_time);
    y = ltime->tm_year + 1900;
    m = ltime->tm_mon + 1;
    d = ltime->tm_mday;
    /* server concept of data can be different so try ask to server */
    odbc_command("SELECT GETDATE()");
    SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, date, sizeof(date), NULL);
    if (SQLFetch(odbc_stmt) == SQL_SUCCESS) {
        int a, b, c;
        if (sscanf(date, "%d-%d-%d", &a, &b, &c) == 3) {
            y = a;
            m = b;
            d = c;
        }
    }
    SQLFetch(odbc_stmt);
    SQLMoreResults(odbc_stmt);
    SQLFreeStmt(odbc_stmt, SQL_UNBIND);
    sprintf(buf, "2003-07-22 13:02:03 -> %04d-%02d-%02d 13:02:03", (int) y, (int) m, (int) d);
    TestInput(SQL_C_TYPE_TIME, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", buf);

    TestInput(SQL_C_FLOAT,  "FLOAT", SQL_REAL, "FLOAT", "1234.25");
    TestInput(SQL_C_DOUBLE, "REAL", SQL_REAL, "FLOAT", "-1234.25");
    TestInput(SQL_C_FLOAT,  "REAL", SQL_REAL, "FLOAT", "1234.25");
    TestInput(SQL_C_DOUBLE, "FLOAT", SQL_REAL, "FLOAT", "-1234.25");
    TestInput(SQL_C_FLOAT,  "FLOAT", SQL_FLOAT, "FLOAT", "1234.25");
    TestInput(SQL_C_DOUBLE, "REAL", SQL_FLOAT, "FLOAT", "-1234.25");
    TestInput(SQL_C_FLOAT,  "FLOAT", SQL_DOUBLE, "FLOAT", "1234.25");
    TestInput(SQL_C_DOUBLE, "REAL", SQL_DOUBLE, "FLOAT", "-1234.25");

    TestInput(SQL_C_UTINYINT, "TINYINT", SQL_TINYINT, "TINYINT", "231");

    TestInput(SQL_C_NUMERIC, "NUMERIC(20,3)", SQL_NUMERIC, "NUMERIC(20,3)", "765432.2 -> 765432");
    TestInput(SQL_C_NUMERIC, "NUMERIC(20,3)", SQL_VARCHAR, "VARCHAR(20)", "578246.234 -> 578246");
    TestInput(SQL_C_NUMERIC, "NUMERIC(20,3)", SQL_LONGVARCHAR, "TEXT", "578246.234 -> 578246");

    TestInput(SQL_C_CHAR, "VARCHAR(100)", SQL_VARBINARY, "VARBINARY(20)", "4145544F -> AETO");
    TestInput(SQL_C_CHAR, "TEXT", SQL_VARBINARY, "VARBINARY(20)", "4145544F -> AETO");
    TestInput(SQL_C_CHAR, "VARCHAR(100)", SQL_LONGVARBINARY, "IMAGE", "4145544F -> AETO");
    TestInput(SQL_C_BINARY, "VARBINARY(100)", SQL_VARCHAR, "VARCHAR(20)", "0x4145544F -> AETO");
    TestInput(SQL_C_BINARY, "IMAGE", SQL_VARCHAR, "VARCHAR(20)", "0x4145544F -> AETO");

    TestInput(SQL_C_BIT, "BIT", SQL_BIT, "BIT", "0");
    TestInput(SQL_C_BIT, "BIT", SQL_BIT, "BIT", "1");

    TestInput(SQL_C_DOUBLE, "MONEY", SQL_DOUBLE, "MONEY", "123.34");

    TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_VARCHAR, "VARCHAR(20)", "1EasyTest");
    TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_LONGVARCHAR, "TEXT", "1EasyTest");
    TestInput(SQL_C_WCHAR, "VARCHAR(10)", SQL_VARCHAR, "VARCHAR(10)", "Test 12345");
    TestInput(SQL_C_WCHAR, "VARCHAR(10)", SQL_LONGVARCHAR, "TEXT", "Test 12345");
    /* TODO use collate in syntax if available */
    TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_VARCHAR, "VARCHAR(20)", "me\xf4");
    TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_LONGVARCHAR, "TEXT", "me\xf4");

    precision = 6;
    /* output from char with conversions */
    TestOutput("VARCHAR(20)", "foo test", SQL_C_CHAR, SQL_VARCHAR, "6 foo te");
    /* TODO use collate in sintax if available */
    TestOutput("VARCHAR(20)", "0xf8f9", SQL_C_CHAR, SQL_VARCHAR, "2 \xf8\xf9");

    if ((odbc_db_is_microsoft() && odbc_db_version_int() >= 0x08000000u && odbc_tds_version() > 0x700)
            || (!odbc_db_is_microsoft() && strncmp(odbc_db_version(), "15.00.", 6) >= 0)) {
        TestOutput("BIGINT", "-987654321065432", SQL_C_BINARY, SQL_BIGINT, big_endian ? "FFFC7DBBCF083228" : "283208CFBB7DFCFF");
        TestInput(SQL_C_SBIGINT, "BIGINT", SQL_BIGINT, "BIGINT", "-12345678901234");
    }
    if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x08000000u) {
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "test");
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WLONGVARCHAR, "NTEXT", "test");
        /* test for invalid stream due to truncation*/
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "01234567890");
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WLONGVARCHAR, "NTEXT", "01234567890");
#ifdef ENABLE_DEVELOPING
        check_truncation = 1;
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "012345678901234567890");
        check_truncation = 1;
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WLONGVARCHAR, "NTEXT", "012345678901234567890");
#endif
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "\xa3h\xf9 -> 0xA3006800f900");
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WLONGVARCHAR, "NTEXT", "\xa3h\xf9 -> 0xA3006800f900");
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "0xA3006800f900 -> \xa3h\xf9");
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WLONGVARCHAR, "NTEXT", "0xA3006800f900 -> \xa3h\xf9");

        TestInput(SQL_C_LONG, "INT", SQL_WVARCHAR, "NVARCHAR(100)", "45236");
        TestInput(SQL_C_LONG, "INT", SQL_WLONGVARCHAR, "NTEXT", "45236");

        precision = 6;
        TestOutput("NVARCHAR(20)", "foo test", SQL_C_CHAR, SQL_WVARCHAR, "6 foo te");
        precision = 12;
        TestOutput("NVARCHAR(20)", "foo test", SQL_C_CHAR, SQL_WVARCHAR, "8 foo test");
        /* TODO use collate in sintax if available */
        TestOutput("NVARCHAR(20)", "0xf800f900", SQL_C_CHAR, SQL_WVARCHAR, "2 \xf8\xf9");

        TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_WVARCHAR, "NVARCHAR(10)", "1EasyTest2");
        TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_WLONGVARCHAR, "NTEXT", "1EasyTest2");
        use_nts = 1;
        TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_WVARCHAR, "NVARCHAR(10)", "1EasyTest3");
        use_nts = 1;
        TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_WLONGVARCHAR, "NTEXT", "1EasyTest3");
        TestInput(SQL_C_WCHAR, "NVARCHAR(3)", SQL_WVARCHAR, "NVARCHAR(3)", "0xf800a300bc06");
        TestInput(SQL_C_WCHAR, "NVARCHAR(3)", SQL_WLONGVARCHAR, "NTEXT", "0xf800a300bc06");

        TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_INTEGER, "INT", " -423785  -> -423785");

        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_VARBINARY, "VARBINARY(20)", "4145544F -> AETO");
        TestInput(SQL_C_CHAR, "NTEXT", SQL_VARBINARY, "VARBINARY(20)", "4145544F -> AETO");

        TestInput(SQL_C_BINARY, "VARBINARY(100)", SQL_WVARCHAR, "NVARCHAR(20)", "0x4100450054004F00 -> AETO");
        TestInput(SQL_C_BINARY, "IMAGE", SQL_WVARCHAR, "NVARCHAR(20)", "0x4100450054004F00 -> AETO");
    }
    if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x09000000u) {
        TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_LONGVARCHAR, "VARCHAR(MAX)", "1EasyTest");
        TestInput(SQL_C_BINARY, "VARBINARY(20)", SQL_LONGVARBINARY, "VARBINARY(MAX)", "Anything will suite!");
    }
}
Example #6
0
int
main(int argc, char *argv[])
{
	char tmp[512];
	char out[32];
	SQLLEN n_len;
	SQLSMALLINT len;
	const char * const*p;
	int n;

	if (odbc_read_login_info())
		exit(1);

	/* connect string using DSN */
	init_connect();
	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;ClientCharset=UTF-8;", odbc_server, odbc_user, odbc_password, odbc_database);
	CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp)/sizeof(SQLTCHAR), &len, SQL_DRIVER_NOPROMPT, "SI");
	if (!odbc_driver_is_freetds()) {
		odbc_disconnect();
		printf("Driver is not FreeTDS, exiting\n");
		odbc_test_skipped();
		return 0;
	}

	if (!odbc_db_is_microsoft() || odbc_db_version_int() < 0x08000000u || odbc_tds_version() < 0x701) {
		odbc_disconnect();
		/* protocol till 7.1 does not support telling encoding so we
		 * cannot understand how the string is encoded
		 */
		printf("Test for MSSQL only using protocol 7.1\n");
		odbc_test_skipped();
		return 0;
	}

	CHKAllocStmt(&odbc_stmt, "S");

	/* create test table */
	odbc_command("CREATE TABLE #tmpHebrew (i INT, v VARCHAR(10) COLLATE Hebrew_CI_AI)");

	/* insert with INSERT statements */
	for (n = 0, p = strings_hex; p[n]; ++n) {
		sprintf(tmp, "INSERT INTO #tmpHebrew VALUES(%d, CAST(%s AS NVARCHAR(10)))", n+1, p[n]);
		odbc_command(tmp);
	}

	/* test conversions in libTDS */
	odbc_command("SELECT v FROM #tmpHebrew");

	/* insert with SQLPrepare/SQLBindParameter/SQLExecute */
	CHKBindCol(1, SQL_C_CHAR, out, sizeof(out), &n_len, "S");
	for (n = 0, p = strings; p[n]; ++n) {
		CHKFetch("S");
		if (n_len != strlen(p[n]) || strcmp(p[n], out) != 0) {
			fprintf(stderr, "Wrong row %d %s\n", n, out);
			odbc_disconnect();
			return 1;
		}
	}

	odbc_disconnect();
	printf("Done.\n");
	return 0;
}
Example #7
0
int
main(int argc, char *argv[])
{
	int big_endian = 1;
	int test_2008_date_to_binary = 0;

	odbc_connect();

	if (((char *) &big_endian)[0] == 1)
		big_endian = 0;

	Test("NUMERIC(18,2)", "123", SQL_C_NUMERIC, "38 0 1 7B");

	/* all binary results */
	/* cases (2) */
	Test("CHAR(7)", "pippo", SQL_C_BINARY, "706970706F2020");
	Test("TEXT", "mickey", SQL_C_BINARY, "6D69636B6579");
	Test("VARCHAR(20)", "foo", SQL_C_BINARY, "666F6F");

	Test("BINARY(5)", "qwer", SQL_C_BINARY, "7177657200");
	Test("IMAGE", "cricetone", SQL_C_BINARY, "6372696365746F6E65");
	Test("VARBINARY(20)", "teo", SQL_C_BINARY, "74656F");
	/* TODO only MS ?? */
	if (odbc_db_is_microsoft())
		Test("TIMESTAMP", "abcdefghi", SQL_C_BINARY, "6162636465666768");

	Test("DATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, big_endian ? "0000949700FBAA2C" : "979400002CAAFB00");
	Test("SMALLDATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, big_endian ? "94970394" : "97949403");

	Test("BIT", "1", SQL_C_BINARY, "01");
	Test("BIT", "0", SQL_C_BINARY, "00");
	Test("TINYINT", "231", SQL_C_BINARY, "E7");
	Test("SMALLINT", "4321", SQL_C_BINARY, big_endian ? "10E1" : "E110");
	Test("INT", "1234567", SQL_C_BINARY, big_endian ? "0012D687" : "87D61200");
	if ((odbc_db_is_microsoft() && odbc_db_version_int() >= 0x08000000u)
	    || (!odbc_db_is_microsoft() && strncmp(odbc_db_version(), "15.00.", 6) >= 0)) {
		int old_result = result;

		Test("BIGINT", "123456789012345", SQL_C_BINARY, big_endian ? "00007048860DDF79" : "79DF0D8648700000");
		if (result && strcmp(sbuf, "13000179DF0D86487000000000000000000000") == 0) {
			fprintf(stderr, "Ignore previous error. You should configure TDS 7.1 for this!!!\n");
			if (!old_result)
				result = 0;
		}
	}

	Test("INT", "-123", SQL_C_CHAR, "4 -123");
	Test("INT", "78654", SQL_C_WCHAR, "5 78654");
	Test("VARCHAR(10)", "  51245  ", SQL_C_LONG, "51245");
	Test("VARCHAR(20)", "  15.1245  ", SQL_C_NUMERIC, "38 0 1 0F");
	Test("VARCHAR(20)", "  15  ", SQL_C_NUMERIC, "38 0 1 0F");
	if (odbc_db_is_microsoft() && (strncmp(odbc_db_version(), "08.00.", 6) == 0 || strncmp(odbc_db_version(), "09.00.", 6) == 0)) {
		/* nvarchar without extended characters */
		Test("NVARCHAR(20)", "test", SQL_C_CHAR, "4 test");
		/* nvarchar with extended characters */
		/* don't test with MS which usually have a not compatible encoding */
		if (odbc_driver_is_freetds())
			Test("NVARCHAR(20)", "0x830068006900f200", SQL_C_CHAR, "4 \x83hi\xf2");

		Test("VARCHAR(20)", "test", SQL_C_WCHAR, "4 test");
		/* nvarchar with extended characters */
		Test("NVARCHAR(20)", "0x830068006900f200", SQL_C_WCHAR, "4 \x83hi\xf2");
		Test("NVARCHAR(20)", "0xA406A5FB", SQL_C_WCHAR, "2 \\u06a4\\ufba5");
		/* NVARCHAR -> SQL_C_LONG */
		Test("NVARCHAR(20)", "-24785  ", SQL_C_LONG, "-24785");
	}

	ignore_select_error = 1;
	Test("UNIVARCHAR(10)", "u&'\\06A4\\FBA5'", SQL_C_WCHAR, "2 \\u06a4\\ufba5");

	/* case (1) */
	Test("DECIMAL", "1234.5678", SQL_C_BINARY, "120001D3040000000000000000000000000000");
	Test("NUMERIC", "8765.4321", SQL_C_BINARY, "1200013D220000000000000000000000000000");

	Test("FLOAT", "1234.5678", SQL_C_BINARY, big_endian ? "40934A456D5CFAAD" : "ADFA5C6D454A9340");
	Test("REAL", "8765.4321", SQL_C_BINARY, big_endian ? "4608F5BA" : "BAF50846");

	Test("SMALLMONEY", "765.4321", SQL_C_BINARY, big_endian ? "0074CBB1" : "B1CB7400");
	Test("MONEY", "4321234.5678", SQL_C_BINARY, big_endian ? "0000000A0FA8114E" : "0A0000004E11A80F");

	/* behavior is different from MS ODBC */
	if (odbc_db_is_microsoft()) {
		Test("NCHAR(7)", "donald", SQL_C_BINARY, "64006F006E0061006C0064002000");
		Test("NTEXT", "duck", SQL_C_BINARY, "6400750063006B00");
		Test("NVARCHAR(20)", "daffy", SQL_C_BINARY, "64006100660066007900");
	}

	if (odbc_db_is_microsoft())
		Test("UNIQUEIDENTIFIER", "0DDF3B64-E692-11D1-AB06-00AA00BDD685", SQL_C_BINARY,
		     big_endian ? "0DDF3B64E69211D1AB0600AA00BDD685" : "643BDF0D92E6D111AB0600AA00BDD685");

	/* case (4) */
	Test("DATETIME", "2006-06-09 11:22:44", SQL_C_CHAR, "23 2006-06-09 11:22:44.000");
	Test("SMALLDATETIME", "2006-06-12 22:37:21", SQL_C_CHAR, "19 2006-06-12 22:37:00");
	Test("DATETIME", "2006-06-09 11:22:44", SQL_C_WCHAR, "23 2006-06-09 11:22:44.000");
	Test("SMALLDATETIME", "2006-06-12 22:37:21", SQL_C_WCHAR, "19 2006-06-12 22:37:00");

	if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x08000000u) {
		Test("SQL_VARIANT", "CAST('123' AS INT)", SQL_C_CHAR, "3 123");
		Test("SQL_VARIANT", "CAST('hello' AS CHAR(6))", SQL_C_CHAR, "6 hello ");
		Test("SQL_VARIANT", "CAST('ciao' AS VARCHAR(10))", SQL_C_CHAR, "4 ciao");
		Test("SQL_VARIANT", "CAST('foo' AS NVARCHAR(10))", SQL_C_CHAR, "3 foo");
		Test("SQL_VARIANT", "CAST('Super' AS NCHAR(8))", SQL_C_CHAR, "8 Super   ");
		Test("SQL_VARIANT", "CAST('321' AS VARBINARY(10))", SQL_C_CHAR, "6 333231");
		/* for some reasons MS ODBC seems to convert -123.4 to -123.40000000000001 */
		Test("SQL_VARIANT", "CAST('-123.5' AS FLOAT)", SQL_C_CHAR, "6 -123.5");
		Test("SQL_VARIANT", "CAST('-123.4' AS NUMERIC(10,2))", SQL_C_CHAR, "7 -123.40");
		Test("SQL_VARIANT", "CAST('0DDF3B64-E692-11D1-AB06-00AA00BDD685' AS UNIQUEIDENTIFIER)", SQL_C_CHAR, "36 0DDF3B64-E692-11D1-AB06-00AA00BDD685");
	}

	if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x09000000u) {
		Test("VARCHAR(MAX)", "goodbye!", SQL_C_CHAR, "8 goodbye!");
		Test("NVARCHAR(MAX)", "Micio mao", SQL_C_CHAR, "9 Micio mao");
		Test("VARBINARY(MAX)", "ciao", SQL_C_BINARY, "6369616F");
		Test("XML", "<a b=\"aaa\"><b>ciao</b>hi</a>", SQL_C_CHAR, "28 <a b=\"aaa\"><b>ciao</b>hi</a>");

		/* XML with schema */
		odbc_command("IF EXISTS(SELECT * FROM sys.xml_schema_collections WHERE [name] = 'test_schema') DROP XML SCHEMA COLLECTION test_schema");
		odbc_command("CREATE XML SCHEMA COLLECTION test_schema AS '<schema xmlns=\"http://www.w3.org/2001/XMLSchema\"><element name=\"test\" type=\"string\"/></schema>'");
		Test("XML(test_schema)", "<test>ciao</test>", SQL_C_CHAR, "17 <test>ciao</test>");
		odbc_command("DROP XML SCHEMA COLLECTION test_schema");
	}

	/* MSSQL 2008*/
	if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x0A000000u) {
		int save_result = result;

		/* check right protocol */
		result = 0;
		test_2008_date_to_binary = 1;
		Test("DATE", "1923-12-02", SQL_C_BINARY, big_endian ? "0783000C0002" : "83070C000200");
		if (result) {
			result = 0;
			Test("DATE", "1923-12-02", SQL_C_BINARY, "31003900320033002D00310032002D0030003200");
			if (!result) {
				printf("previous error expected: wrong protocol used\n");
				test_2008_date_to_binary = 0;
			}
		}
		if (save_result)
			result = 1;

		Test("DATE", "1923-12-02", SQL_C_CHAR, "10 1923-12-02");

		Test("TIME", "12:23:45", SQL_C_CHAR, "16 12:23:45.0000000");
		Test("TIME(4)", "12:23:45.765", SQL_C_CHAR, "13 12:23:45.7650");
		Test("TIME(0)", "12:23:45.765", SQL_C_CHAR, "8 12:23:46");

		Test("DATETIME2", "2011-08-10 12:23:45", SQL_C_CHAR, "27 2011-08-10 12:23:45.0000000");
		Test("DATETIME2(4)", "12:23:45.345888", SQL_C_CHAR, "24 1900-01-01 12:23:45.3459");
		Test("DATETIME2(0)", "2011-08-10 12:23:45.93", SQL_C_CHAR, "19 2011-08-10 12:23:46");

		Test("DATETIMEOFFSET", "12:23:45 -02:30", SQL_C_CHAR, "34 1900-01-01 12:23:45.0000000 -02:30");
		Test("DATETIMEOFFSET(4)", "12:23:45", SQL_C_CHAR, "31 1900-01-01 12:23:45.0000 +00:00");
	}

	if (test_2008_date_to_binary) {
		Test("DATE", "1923-12-02", SQL_C_BINARY, big_endian ? "0783000C0002" : "83070C000200");
		Test("TIME", "12:23:45", SQL_C_BINARY, big_endian ? "000C0017002D000000000000" : "0C0017002D00000000000000");
		Test("TIME(4)", "12:23:45.765", SQL_C_BINARY, big_endian ? "000C0017002D00002D98F940" : "0C0017002D00000040F9982D");
		Test("DATETIME2", "2011-08-10 12:23:45", SQL_C_BINARY, big_endian ? "07DB0008000A000C0017002D00000000" : "DB0708000A000C0017002D0000000000");
		Test("DATETIME2(4)", "12:23:45", SQL_C_BINARY, big_endian ? "076C00010001000C0017002D00000000" : "6C07010001000C0017002D0000000000");
		Test("DATETIMEOFFSET", "12:23:45 -08:30", SQL_C_BINARY, big_endian ? "076C00010001000C0017002D00000000FFF8FFE2" : "6C07010001000C0017002D0000000000F8FFE2FF");
		Test("DATETIMEOFFSET(4)", "12:23:45", SQL_C_BINARY, big_endian ? "076C00010001000C0017002D0000000000000000" : "6C07010001000C0017002D000000000000000000");
	}

	if (!odbc_db_is_microsoft() && strncmp(odbc_db_version(), "15.00.", 6) >= 0) {
		/* FIXME sure ?? with date and time always ?? */
		Test("DATE", "1923-12-02", SQL_C_CHAR, "23 1923-12-02 00:00:00.000");
		Test("TIME", "12:23:45", SQL_C_CHAR, "23 1900-01-01 12:23:45.000");
	}

	odbc_disconnect();

	if (!result)
		printf("Done successfully!\n");
	return result;
}
Example #8
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;
}