Esempio n. 1
0
void
odbc_init_parser(FILE *f)
{
	if (parse_file)
		odbc_fatal("parser file already setup\n");
	parse_file = f;
	odbc_line_num = 0;
	odbc_tds_version();
}
Esempio n. 2
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!");
    }
}
Esempio n. 3
0
const char *
odbc_get_cmd_line(char **p_s, int *cond)
{
	while (fgets(line_buf, sizeof(line_buf), parse_file)) {
		char *p = line_buf;
		const char *cmd;

		++odbc_line_num;

		cmd = odbc_get_tok(&p);

		/* skip comments */
		if (!cmd || cmd[0] == '#' || cmd[0] == 0 || cmd[0] == '\n')
			continue;

		/* conditional statement */
		if (!strcmp(cmd, "else")) {
			int c = pop_condition();
			push_condition(c);
			*cond = c && !*cond;
			continue;
		}
		if (!strcmp(cmd, "endif")) {
			*cond = pop_condition();
			continue;
		}
		if (!strcmp(cmd, "if")) {
			push_condition(*cond);
			if (*cond)
				*cond = get_condition(&p);
			continue;
		}

		if (strcmp(cmd, "tds_version_cmp") == 0) {
			const char *bool_name = odbc_get_tok(&p);
			const char *cmp = odbc_get_tok(&p);
			const char *s_ver = odbc_get_tok(&p);
			int ver = odbc_tds_version();
			int expected;
			int res;
			unsigned M, m;

			if (!cmp || !s_ver)
				odbc_fatal(": missing parameters\n");
			if (sscanf(s_ver, "%u.%u", &M, &m) != 2)
				odbc_fatal(": invalid version %s\n", s_ver);
			expected = M * 0x100u + m;

			if (strcmp(cmp, ">") == 0)
				res = ver > expected;
			else if (strcmp(cmp, ">=") == 0)
				res = ver >= expected;
			else if (strcmp(cmp, "<") == 0)
				res = ver < expected;
			else if (strcmp(cmp, "<=") == 0)
				res = ver <= expected;
			else if (strcmp(cmp, "==") == 0)
				res = ver == expected;
			else if (strcmp(cmp, "!=") == 0)
				res = ver != expected;
			else
				odbc_fatal(": invalid operator %s\n", cmp);

			if (*cond)
				odbc_set_bool(bool_name, res);
			continue;
		}

		*p_s = p;
		return cmd;
	}
	return NULL;
}
Esempio n. 4
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;
}