예제 #1
0
파일: flags.c 프로젝트: DmitrySigaev/ncbi
int
main(int argc, char **argv)
{
	TDSRESULTINFO *info;
	char mymsg[256];

	fprintf(stdout, "%s: Testing flags from server\n", __FILE__);
	if (try_tds_login(&login, &tds, __FILE__, 0) != TDS_SUCCESS) {
		fprintf(stderr, "try_tds_login() failed\n");
		return 1;
	}

	if (run_query(tds, "create table #tmp1 (i numeric(10,0) identity primary key, b varchar(20) null, c int not null)") !=
	    TDS_SUCCESS)
		fatal_error("creating table error");

	/* TDS 4.2 without FOR BROWSE clause seem to forget flags... */
	if (!IS_TDS42(tds->conn)) {
		/* check select of all fields */
		test_begin("select * from #tmp1");
		info = tds->current_results;

		if (info->num_cols != 3) {
			sprintf(mymsg,"wrong number of columns returned expected 3 got %d", info->num_cols);
			fatal_error(mymsg);
		}

		check_flags(info->columns[0], 0, "identity");
		check_flags(info->columns[1], 1, "nullable writable");
		check_flags(info->columns[2], 2, "writable");

		test_end();
	}


	/* check select of 2 field */
	test_begin("select c, b from #tmp1 for browse");
	info = tds->current_results;

	if (info->num_cols != 3)
		fatal_error("wrong number of columns returned");

	check_flags(info->columns[0], 0, "writable");

	if (!IS_TDS42(tds->conn)) {
		check_flags(info->columns[1], 1, "nullable writable");
	} else {
		check_flags(info->columns[1], 1, "writable-nullable writable");
	}
	/* TDS5 return not identity information altough documented.. */
	check_flags(info->columns[2], 2, "writable identity key hidden-writable key hidden");

	test_end();

	try_tds_logout(login, tds, 0);
	return 0;
}
예제 #2
0
파일: utf8_2.c 프로젝트: dparnell/freetds
int
main(int argc, char **argv)
{
	TDSLOGIN *login;
	int ret;
	int verbose = 0;
	int i;
	typedef int (*perr)(const TDSCONTEXT *, TDSSOCKET *, TDSMESSAGE *);
	const perr * my_err;

	/* use ISO8859-1 as our coding */
	strcpy(CHARSET, "ISO8859-1");

	ret = try_tds_login(&login, &tds, __FILE__, verbose);
	if (ret != TDS_SUCCEED) {
		fprintf(stderr, "try_tds_login() failed\n");
		return 1;
	}

	/* override a const in a safe way */
	my_err = &tds->tds_ctx->err_handler;
	*((perr*)my_err) = err_handler;

	/* prepend some characters to check part of sequence error */
	einval_error = 1;
	eilseq_error = 1;
	/* do not stop on first error so we check conversion correct */
	for (i = 0; i <= 192; ++i)
		test(i, 0);

	/* try creating a double conversion warning */
	eilseq_error = 0;
	einval_error = 0;	/* we already tested this error above */
	for (i = 0; i <= 192; ++i) {
		eilseq_count = 0;
		test(i, 1);
		if (eilseq_count > 1) {
			fprintf(stderr, "Two warnings returned instead of one in %s\n", test_name);
			g_result = 1;
			break;
		}
		if (eilseq_count < 1 && invalid_char == '?') {
			fprintf(stderr, "No warning returned in %s\n", test_name);
			g_result = 1;
		}
	}

	try_tds_logout(login, tds, verbose);
	return g_result;
}
예제 #3
0
int
main(int argc, char **argv)
{
	TDSLOGIN *login;
	int ret;
	int verbose = 0;

	/* use UTF-8 as our coding */
	strcpy(CHARSET, "UTF-8");

	ret = try_tds_login(&login, &tds, __FILE__, verbose);
	if (ret != TDS_SUCCESS) {
		fprintf(stderr, "try_tds_login() failed\n");
		return 1;
	}

	if (IS_TDS7_PLUS(tds->conn)) {
		char type[32];
		char buf[1024];
		int i, len;

		strcpy(buf, "aaa");
		len = 0;
		for (i = 0; strlen(buf) < 980 && len < 200; ++i) {
			char tmp[256];

			strcat(buf, japanese);
			len += strlen(to_utf8(japanese, tmp));
		}
		strings[sizeof(strings) / sizeof(strings[0]) - 5] = buf + 3;
		strings[sizeof(strings) / sizeof(strings[0]) - 4] = buf + 2;
		strings[sizeof(strings) / sizeof(strings[0]) - 3] = buf + 1;
		strings[sizeof(strings) / sizeof(strings[0]) - 2] = buf;

		test("NVARCHAR(500)", "NVARCHAR with large size");

		sprintf(type, "NVARCHAR(%d)", utf8_max_len);
		test(type, "NVARCHAR with sufficient size");

		test("NTEXT", "TEXT");

		/* TODO test parameters */
	}

	try_tds_logout(login, tds, verbose);
	return 0;
}
예제 #4
0
int
main(int argc, char **argv)
{
	TDSLOGIN *login;
	TDSSOCKET *tds;
	int ret;
	int verbose = 0;

	fprintf(stdout, "%s: Testing login, logout\n", __FILE__);
	ret = try_tds_login(&login, &tds, __FILE__, verbose);
	if (ret != TDS_SUCCEED) {
		fprintf(stderr, "try_tds_login() failed\n");
		return 1;
	}

	try_tds_logout(login, tds, verbose);
	return 0;
}
예제 #5
0
파일: t0003.c 프로젝트: DmitrySigaev/ncbi
int
main(int argc, char **argv)
{
	TDSLOGIN *login;
	TDSSOCKET *tds;
	int verbose = 0;
	int rc;

	fprintf(stdout, "%s: Testing DB change -- 'use tempdb'\n", __FILE__);
	rc = try_tds_login(&login, &tds, __FILE__, verbose);
	if (rc != TDS_SUCCESS) {
		fprintf(stderr, "try_tds_login() failed\n");
		return 1;
	}

	rc = tds_submit_query(tds, "use tempdb");
	if (rc != TDS_SUCCESS) {
		fprintf(stderr, "tds_submit_query() failed\n");
		return 1;
	}

	/* warning: this mucks with some internals to get the env chg message */
	if (tds_process_simple_query(tds) != TDS_SUCCESS) {
		fprintf(stderr, "query results failed\n");
		return 1;
	}

	if (!tds || !tds->conn->env.database) {
		fprintf(stderr, "No database ??\n");
		return 1;
	}

	/* Test currently disabled during TDSENV changes */
	if (verbose) {
		fprintf(stdout, "database changed to %s\n", tds->conn->env.database);
	}
	if (strcmp(tds->conn->env.database, "tempdb")) {
		fprintf(stderr, "Wrong database, %s != tempdb\n", tds->conn->env.database);
		return 1;
	}

	try_tds_logout(login, tds, verbose);
	return 0;
}
예제 #6
0
파일: utf8_3.c 프로젝트: mabrand/freetds
int
main(int argc, char **argv)
{
	TDSLOGIN *login;
	int ret;
	int verbose = 0;

	/* use UTF-8 as our coding */
	strcpy(CHARSET, "UTF-8");

	ret = try_tds_login(&login, &tds, __FILE__, verbose);
	if (ret != TDS_SUCCESS) {
		fprintf(stderr, "try_tds_login() failed\n");
		return 1;
	}

	if (IS_TDS7_PLUS(tds->conn)) {
		char buf[129 * 8];
		int i;

		/* build a string of length 128 */
		strcpy(buf, "");
		for (i = 1; i <= 128; ++i) {
			sprintf(strchr(buf, 0), "&#x%04x;", 0x4000 + i);
		}

		/* do all test */
		for (i = 1;;) {
			printf("Testing len %d\n", i);
			test(buf + 8 * (128 - i));
			if (i == 128)
				break;
			++i;
			if (i > 12)
				i += 3;
			if (i >= 128)
				i = 128;
		}
	}

	try_tds_logout(login, tds, verbose);
	return 0;
}
예제 #7
0
파일: corrupt.c 프로젝트: DougBeck/freetds
int
main(int argc, char **argv)
{
	TDSLOGIN *login;
	TDSSOCKET *tds;
	int ret;
	int verbose = 0;
	TDS_INT8 i8;
	unsigned limit;

	fprintf(stdout, "%s: Testing login, logout\n", __FILE__);
	ret = try_tds_login(&login, &tds, __FILE__, verbose);
	if (ret != TDS_SUCCESS) {
		fprintf(stderr, "try_tds_login() failed\n");
		return 1;
	}

	unfinished_query_test(tds);

	tds->out_flag = TDS_QUERY;
	if (tds_set_state(tds, TDS_WRITING) != TDS_WRITING) {
		return 1;
	}

	tds_put_n(tds, "aaa", 3);
	limit = tds->out_buf_max / 8 + 100;
	for (i8 = 0; i8 < limit; ++i8) {
		CHECK_TDS_EXTRA(tds);
		tds_put_int8(tds, i8);
	}

	tds_send_cancel(tds);
	tds_process_simple_query(tds);

	try_tds_logout(login, tds, verbose);
	return 0;
}
예제 #8
0
파일: t0006.c 프로젝트: Distrotech/freetds
int
main(int argc, char **argv)
{
	TDSLOGIN *login;
	TDSSOCKET *tds;
	int verbose = 0;
	int rc;
	int row_count, i;

	/* variables for conversions */
	TDSCOLUMN *curcol;
	TDSRESULTINFO *resinfo;
	unsigned char *src;

	CONV_RESULT cr;
	TDS_INT srctype, srclen;

	int src_id = 0;
	double src_val;
	double src_err;
	double tolerance = 0.000001;

	char sql[256];
	int num_sybreal = 5;
	float sybreal[5];
	int num_sybflt8 = 7;
	double sybflt8[7];
	int result_type;

	memset(&ctx, 0, sizeof(ctx));

	sybreal[0] = 1.1;
	sybreal[1] = 12345678;
	sybreal[2] = 0.012345678;
	sybreal[3] = 1.234567890e+20;
	sybreal[4] = 1.234567890e-20;

	sybflt8[0] = 1.1;
	sybflt8[1] = 1234567890123456.0;
	sybflt8[2] = 0.01234567890123456;
	sybflt8[3] = 1.234567890123456e+20;
	sybflt8[4] = 1.234567890123456e-20;
	sybflt8[5] = 1.234567890123456e+200;
	sybflt8[6] = 1.234567890123456e-200;

	printf("%s: Test SYBREAL, SYBFLT8 values\n", __FILE__);
	rc = try_tds_login(&login, &tds, __FILE__, verbose);
	if (rc != TDS_SUCCEED) {
		fprintf(stderr, "try_tds_login() failed\n");
		return 1;
	}


	/*
	 * SYBREAL tests
	 */
	if (verbose)
		printf("Starting SYBREAL tests\n");
	rc = run_query(tds, "DROP TABLE #test_table");
	if (rc != TDS_SUCCEED) {
		return 1;
	}
	rc = run_query(tds, "CREATE TABLE #test_table (id int, val real)");
	if (rc != TDS_SUCCEED) {
		return 1;
	}

	for (i = 0; i < num_sybreal; i++) {
		sprintf(sql, "INSERT #test_table (id, val) VALUES (%d, %.8g)", i, sybreal[i]);
		if (verbose)
			printf("%s\n", sql);
		rc = run_query(tds, sql);
		if (rc != TDS_SUCCEED) {
			return 1;
		}
	}

	rc = tds_submit_query(tds, "SELECT * FROM #test_table");

	row_count = 0;
	while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_RETURN_ROW|TDS_RETURN_COMPUTE)) == TDS_SUCCEED) {
		switch (result_type) {
		case TDS_ROW_RESULT:
			resinfo = tds->res_info;
			for (i = 0; i < resinfo->num_cols; i++) {
				curcol = resinfo->columns[i];
				src = curcol->column_data;
				if (verbose) {
					srctype = curcol->column_type;
					srclen = curcol->column_size;
					tds_convert(&ctx, srctype, (TDS_CHAR *) src, srclen, SYBCHAR, &cr);
					printf("col %i is %s\n", i, cr.c);
				}
				if (i == 0) {
					src_id = *(int *) src;
				} else {
					src_val = *(float *) src;
					src_err = src_val - sybreal[src_id];
					if (src_err != 0.0) {
						src_err = src_err / src_val;
					}
					if (src_err < -tolerance || src_err > tolerance) {
						fprintf(stderr, "SYBREAL expected %.8g  got %.8g\n",
							sybreal[src_id], src_val);
						fprintf(stderr, "Error was %.4g%%\n", 100 * src_err);
						return 1;
					}
				}
			}
			row_count++;
		case TDS_COMPUTE_RESULT:
			break;
		default:
			fprintf(stderr, "tds_process_tokens() unexpected result\n");
			break;
		}
	}
	if (rc != TDS_NO_MORE_RESULTS) {
		fprintf(stderr, "tds_process_tokens() unexpected return\n");
	}


	/*
	 * SYBFLT8 tests
	 */
	if (verbose)
		printf("Starting SYBFLT8 tests\n");
	rc = run_query(tds, "DROP TABLE #test_table");
	if (rc != TDS_SUCCEED) {
		return 1;
	}
	rc = run_query(tds, "CREATE TABLE #test_table (id int, val float(48))");
	if (rc != TDS_SUCCEED) {
		return 1;
	}

	for (i = 0; i < num_sybflt8; i++) {
		sprintf(sql, "INSERT #test_table (id, val) VALUES (%d, %.15g)", i, sybflt8[i]);
		if (verbose)
			printf("%s\n", sql);
		rc = run_query(tds, sql);
		if (rc != TDS_SUCCEED) {
			return 1;
		}
	}

	rc = tds_submit_query(tds, "SELECT * FROM #test_table");
	while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_RETURN_ROW|TDS_RETURN_COMPUTE)) == TDS_SUCCEED) {
		switch (result_type) {
		case TDS_ROW_RESULT:
			resinfo = tds->res_info;
			for (i = 0; i < resinfo->num_cols; i++) {
				curcol = resinfo->columns[i];
				src = curcol->column_data;
				if (verbose) {
					srctype = curcol->column_type;
					srclen = curcol->column_size;
					tds_convert(&ctx, srctype, (TDS_CHAR *) src, srclen, SYBCHAR, &cr);
					printf("col %i is %s\n", i, cr.c);
				}
				if (i == 0) {
					src_id = *(int *) src;
				} else {
					memcpy(&src_val, src, 8);
					src_err = src_val - sybflt8[src_id];
					if (src_err != 0.0) {
						src_err = src_err / src_val;
					}
					if (src_err < -tolerance || src_err > tolerance) {
						fprintf(stderr, "SYBFLT8 expected %.16g  got %.16g\n",
							sybflt8[src_id], src_val);
						fprintf(stderr, "Error was %.4g%%\n", 100 * src_err);
						return 1;
					}
				}
			}
		case TDS_COMPUTE_RESULT:
			break;
		default:
			fprintf(stderr, "tds_process_tokens() returned unexpected result\n");
			break;
		}
	}
	if (rc != TDS_NO_MORE_RESULTS) {
		fprintf(stderr, "tds_process_tokens() unexpected return\n");
	}

	try_tds_logout(login, tds, verbose);
	return 0;
}
예제 #9
0
int
main(int argc, char **argv)
{
	TDSLOGIN *login;
	TDSSOCKET *tds;
	int verbose = 0;
	TDSDYNAMIC *dyn = NULL;
	int rc;

	fprintf(stdout, "%s: Test dynamic queries\n", __FILE__);
	rc = try_tds_login(&login, &tds, __FILE__, verbose);
	if (rc != TDS_SUCCEED)
		fatal_error("try_tds_login() failed");

	run_query(tds, "DROP TABLE #dynamic1");
	if (run_query(tds, "CREATE TABLE #dynamic1 (i INT, c VARCHAR(40))") != TDS_SUCCEED)
		fatal_error("creating table error");

	if (tds->cur_dyn)
		fatal_error("already a dynamic query??");

	/* prepare to insert */
	if (tds_submit_prepare(tds, "INSERT INTO #dynamic1(i,c) VALUES(?,?)", NULL, &dyn, NULL) != TDS_SUCCEED)
		fatal_error("tds_submit_prepare() error");
	if (discard_result(tds) != TDS_SUCCEED)
		fatal_error("tds_submit_prepare() output error");

	if (!dyn)
		fatal_error("dynamic not present??");

	/* insert one record */
	test(tds, dyn, 123, "dynamic");

	/* some test */
	if (run_query(tds, "DECLARE @n INT SELECT @n = COUNT(*) FROM #dynamic1 IF @n <> 1 SELECT 0") != TDS_SUCCEED)
		fatal_error("checking rows");

	if (run_query(tds, "DECLARE @n INT SELECT @n = COUNT(*) FROM #dynamic1 WHERE i = 123 AND c = 'dynamic' IF @n <> 1 SELECT 0")
	    != TDS_SUCCEED)
		fatal_error("checking rows 1");

	/* insert one record */
	test(tds, dyn, 654321, "a longer string");

	/* some test */
	if (run_query(tds, "DECLARE @n INT SELECT @n = COUNT(*) FROM #dynamic1 IF @n <> 2 SELECT 0") != TDS_SUCCEED)
		fatal_error("checking rows");

	if (run_query(tds, "DECLARE @n INT SELECT @n = COUNT(*) FROM #dynamic1 WHERE i = 123 AND c = 'dynamic' IF @n <> 1 SELECT 0")
	    != TDS_SUCCEED)
		fatal_error("checking rows 2");

	if (run_query
	    (tds,
	     "DECLARE @n INT SELECT @n = COUNT(*) FROM #dynamic1 WHERE i = 654321 AND c = 'a longer string' IF @n <> 1 SELECT 0") !=
	    TDS_SUCCEED)
		fatal_error("checking rows 3");

	if (run_query(tds, "DROP TABLE #dynamic1") != TDS_SUCCEED)
		fatal_error("dropping table error");

	try_tds_logout(login, tds, verbose);
	return 0;
}
예제 #10
0
파일: t0002.c 프로젝트: RQZeng/freetds
int
main(int argc, char **argv)
{
	TDSLOGIN *login;
	TDSSOCKET *tds;
	int verbose = 0;
	int num_cols = 2;
	TDS_INT result_type;
	int rc;
	int i, done_flags;

	fprintf(stdout, "%s: Test basic submit query, results\n", __FILE__);
	rc = try_tds_login(&login, &tds, __FILE__, verbose);
	if (rc != TDS_SUCCESS) {
		fprintf(stderr, "try_tds_login() failed\n");
		return 1;
	}

	rc = tds_submit_query(tds, "select db_name() dbname, user_name() username");
	if (rc != TDS_SUCCESS) {
		fprintf(stderr, "tds_submit_query() failed\n");
		return 1;
	}

	while ((rc = tds_process_tokens(tds, &result_type, &done_flags, TDS_TOKEN_RESULTS)) == TDS_SUCCESS) {
		switch (result_type) {
		case TDS_ROWFMT_RESULT:
			if (tds->res_info->num_cols != num_cols) {
				fprintf(stderr, "Error:  num_cols != %d in %s\n", num_cols, __FILE__);
				return 1;
			}
			if (tds->res_info->columns[0]->column_type != SYBVARCHAR
			    || tds->res_info->columns[1]->column_type != SYBVARCHAR) {
				fprintf(stderr, "Wrong column_type in %s\n", __FILE__);
				return 1;
			}
			if (strcmp(tds_dstr_cstr(&tds->res_info->columns[0]->column_name), "dbname")
			    || strcmp(tds_dstr_cstr(&tds->res_info->columns[1]->column_name), "username")) {
				fprintf(stderr, "Wrong column_name in %s\n", __FILE__);
				return 1;
			}
			break;

		case TDS_ROW_RESULT:

			while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_STOPAT_ROWFMT|TDS_RETURN_DONE|TDS_RETURN_ROW|TDS_RETURN_COMPUTE)) == TDS_SUCCESS) {
				if (result_type != TDS_ROW_RESULT || result_type != TDS_COMPUTE_RESULT)
					break;
				if (verbose) {
					for (i = 0; i < num_cols; i++) {
						printf("col %i is %s\n", i, value_as_string(tds, i));
					}
				}
			}
			if (rc != TDS_SUCCESS) {
				fprintf(stderr, "tds_process_tokens() unexpected return\n");
			}
			break;

		case TDS_DONE_RESULT:
		case TDS_DONEPROC_RESULT:
		case TDS_DONEINPROC_RESULT:
			if (!(done_flags & TDS_DONE_ERROR))
				break;

		default:
			fprintf(stderr, "tds_process_tokens() unexpected result_type\n");
			break;
		}
	}
	if (rc != TDS_NO_MORE_RESULTS) {
		fprintf(stderr, "tds_process_tokens() unexpected return\n");
	}

	try_tds_logout(login, tds, verbose);
	return 0;
}
예제 #11
0
파일: t0004.c 프로젝트: DmitrySigaev/ncbi
int
main(int argc, char **argv)
{
	TDSLOGIN *login;
	TDSSOCKET *tds;
	int verbose = 0;
	int rc, i;

	int result_type;
	int rows_returned = 0;

	const char *len200 =
		"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
	char *long_query = (char*) malloc(5000);

	strcpy(long_query, "SELECT name FROM #longquerytest WHERE (");
	for (i = 0; i < 20; ++i)
		sprintf(strchr(long_query, 0), "name = '%c%s' OR ", 'A'+i, len200);
	strcat(long_query, "name = 'correct')");

	fprintf(stdout, "%s: Test large (>4096 bytes) queries\n", __FILE__);
	rc = try_tds_login(&login, &tds, __FILE__, verbose);
	if (rc != TDS_SUCCESS) {
		fprintf(stderr, "try_tds_login() failed\n");
		return 1;
	}

	/* do not check error here, if TABLE is not create this give error */
	rc = run_query(tds, "DROP TABLE #longquerytest");
	rc = run_query(tds, "CREATE TABLE #longquerytest (name varchar(255))");
	if (rc != TDS_SUCCESS) {
		return 1;
	}
	rc = run_query(tds, "INSERT #longquerytest (name) VALUES ('incorrect')");
	if (rc != TDS_SUCCESS) {
		return 1;
	}
	rc = run_query(tds, "INSERT #longquerytest (name) VALUES ('correct')");
	if (rc != TDS_SUCCESS) {
		return 1;
	}

	/*
	 * The heart of the test
	 */
	if (verbose) {
		fprintf(stdout, "block size %d\n", tds->conn->env.block_size);
	}
	rc = tds_submit_query(tds, long_query);
	while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_RETURN_ROWFMT|TDS_RETURN_ROW)) == TDS_SUCCESS) {
		switch (result_type) {
		case TDS_ROWFMT_RESULT:
			if (tds->res_info->columns[0]->column_type != SYBVARCHAR) {
				fprintf(stderr, "Wrong column_type in %s\n", __FILE__);
				return 1;
			}
			break;
		case TDS_ROW_RESULT:
			++rows_returned;
			if (verbose) {
				printf("col 0 is %s\n", varchar_as_string(tds, 0));
			}
			break;
		default:
			break;
		}
	}
	if (rc == TDS_FAIL) {
		fprintf(stderr, "tds_process_tokens() returned TDS_FAIL for long query\n");
		return 1;
	} else if (rc != TDS_NO_MORE_RESULTS) {
		fprintf(stderr, "tds_process_tokens() unexpected return\n");
	}

	if (rows_returned != 1) {
		fprintf(stderr, "%d rows returned, 1 expected\n", rows_returned);
		return 1;
	}

	/* do not check error here, if TABLE is not create this give error */
	rc = run_query(tds, "DROP TABLE #longquerytest");

	try_tds_logout(login, tds, verbose);
	free(long_query);
	return 0;
}
예제 #12
0
파일: dataread.c 프로젝트: dparnell/freetds
int
main(int argc, char **argv)
{
	fprintf(stdout, "%s: Testing conversion from server\n", __FILE__);
	if (try_tds_login(&login, &tds, __FILE__, 0) != TDS_SUCCEED) {
		fprintf(stderr, "try_tds_login() failed\n");
		return 1;
	}

	/* bit */
	test("BIT", "0", NULL);
	test("BIT", "1", NULL);

	/* integers */
	test("TINYINT", "234", NULL);
	test("SMALLINT", "-31789", NULL);
	test("INT", "16909060", NULL);

	/* floating point */
	test("REAL", "1.23", NULL);
	test("FLOAT", "-49586.345", NULL);

	/* money */
	test("MONEY", "-123.3400", "-123.34");
	test("MONEY", "-123.3450", "-123.35");
	test("MONEY", "123.3450", "123.35");
	/* very long money, this test int64 operations too */
	test("MONEY", "123456789012345.67", NULL);
	/* test smaller money */
	test("MONEY", "-922337203685477.5808", "-922337203685477.58");
	test("SMALLMONEY", "89123.12", NULL);
	test("SMALLMONEY", "-123.3400", "-123.34");
	test("SMALLMONEY", "-123.3450", "-123.35");
	test("SMALLMONEY", "123.3450", "123.35");
	/* test smallest smallmoney */
	test("SMALLMONEY", "-214748.3648", "-214748.36");

	/* char */
	test("CHAR(10)", "pippo", "pippo     ");
	test("VARCHAR(20)", "pippo", NULL);
	test0("TEXT", "a", NULL, "foofoo", NULL, "try with a relatively long value, we hope for the best", NULL, NULL);

	/* binary */
	test("VARBINARY(6)", "foo", "666f6f");
	test("BINARY(6)", "foo", "666f6f000000");
	test0("IMAGE", "foo", "666f6f", "foofoofoofoo", "666f6f666f6f666f6f666f6f", NULL);

	/* numeric */
	test("NUMERIC(10,2)", "12765.76", NULL);
	test("NUMERIC(18,4)", "12765.761234", "12765.7612");

	/* date */
	free(test_context->locale->date_fmt);
	test_context->locale->date_fmt = tds_strdup("%Y-%m-%d %H:%M:%S");

	test("DATETIME", "2003-04-21 17:50:03", NULL);
	test("SMALLDATETIME", "2003-04-21 17:50:03", "2003-04-21 17:50:00");

	if (IS_TDS7_PLUS(tds)) {
		test("UNIQUEIDENTIFIER", "12345678-1234-A234-9876-543298765432", NULL);
		test("NVARCHAR(20)", "Excellent test", NULL);
		test("NCHAR(20)", "Excellent test", "Excellent test      ");
		test("NTEXT", "Excellent test", NULL);
	}

	try_tds_logout(login, tds, 0);
	return g_result;
}