1 diff -urN freetds/configure.ac freetds.current/configure.ac
2 --- freetds/configure.ac 2008-05-08 00:57:52.000000000 +0200
3 +++ freetds.current/configure.ac 2008-05-28 15:40:28.000000000 +0200
5 dnl Process this file with autoconf to produce a configure script.
7 dnl ------------------------------------------------------------
10 dnl If you're trying to create a new configure test, try
12 dnl http://autogen.sourceforge.net/conftest.html
15 AC_CHECK_HEADERS([unistd.h errno.h wchar.h sys/time.h sys/types.h \
16 sys/param.h sys/stat.h sys/wait.h limits.h locale.h odbcss.h readpassphrase.h \
17 -signal.h libgen.h poll.h])
18 +signal.h libgen.h poll.h getopt.h])
19 if test $tds_mingw = no; then
20 AC_CHECK_HEADERS([sys/socket.h arpa/inet.h netdb.h netinet/in.h \
21 netinet/tcp.h paths.h sys/ioctl.h langinfo.h])
26 +AC_MSG_CHECKING([whether getopt has optreset support])
27 +AC_TRY_LINK([#ifdef HAVE_GETOPT_H
29 +#endif], [extern int optreset; optreset = 0;],
31 +AC_DEFINE(HAVE_GETOPT_OPTRESET, 1, [Define if your getopt(3) defines and uses optreset])],
36 # ------------------------------------------------------------
37 # Checks for compiler characteristics.
38 # ------------------------------------------------------------
39 diff -urN freetds/include/cspublic.h freetds.current/include/cspublic.h
40 --- freetds/include/cspublic.h 2007-06-25 11:48:20.000000000 +0200
41 +++ freetds.current/include/cspublic.h 2008-05-19 16:23:52.000000000 +0200
43 #define TDS_STATIC_CAST(type, a) ((type)(a))
46 -static const char rcsid_cspublic_h[] = "$Id$";
47 +static const char rcsid_cspublic_h[] = "$Id$";
48 static const void *const no_unused_cspublic_h_warn[] = { rcsid_cspublic_h, no_unused_cspublic_h_warn };
53 #define BLK_VERSION_100 CS_VERSION_100
54 #define BLK_VERSION_110 CS_VERSION_100
55 +#define BLK_VERSION_120 CS_VERSION_120
56 +#define BLK_VERSION_125 CS_VERSION_125
57 +#define BLK_VERSION_150 CS_VERSION_150
59 #define CS_FORCE_EXIT 300
60 #define CS_FORCE_CLOSE 301
61 diff -urN freetds/include/tdsbytes.h freetds.current/include/tdsbytes.h
62 --- freetds/include/tdsbytes.h 2005-08-10 14:06:03.000000000 +0200
63 +++ freetds.current/include/tdsbytes.h 2008-05-26 14:49:56.000000000 +0200
72 #error tds.h must be included before tdsbytes.h
74 #define TDS_GET_A2BE(ptr) TDS_GET_UA2BE(ptr)
76 #define TDS_PUT_UA2LE(ptr,val) do {\
77 - ((TDS_UCHAR*)(ptr))[1] = (val)>>8; ((TDS_UCHAR*)(ptr))[0] = (val); } while(0)
78 + ((TDS_UCHAR*)(ptr))[1] = (TDS_UCHAR)((val)>>8); ((TDS_UCHAR*)(ptr))[0] = (TDS_UCHAR)(val); } while(0)
79 #define TDS_PUT_UA2BE(ptr,val) do {\
80 - ((TDS_UCHAR*)(ptr))[0] = (val)>>8; ((TDS_UCHAR*)(ptr))[1] = (val); } while(0)
81 + ((TDS_UCHAR*)(ptr))[0] = (TDS_UCHAR)((val)>>8); ((TDS_UCHAR*)(ptr))[1] = (TDS_UCHAR)(val); } while(0)
82 #define TDS_PUT_A2LE(ptr,val) TDS_PUT_UA2LE(ptr,val)
83 #define TDS_PUT_A2BE(ptr,val) TDS_PUT_UA2BE(ptr,val)
86 #define TDS_GET_A4BE(ptr) TDS_GET_UA4BE(ptr)
88 #define TDS_PUT_UA4LE(ptr,val) do {\
89 - ((TDS_UCHAR*)(ptr))[3] = (val)>>24; ((TDS_UCHAR*)(ptr))[2] = (val)>>16;\
90 - ((TDS_UCHAR*)(ptr))[1] = (val)>>8; ((TDS_UCHAR*)(ptr))[0] = (val); } while(0)
91 + ((TDS_UCHAR*)(ptr))[3] = (TDS_UCHAR)((val)>>24); ((TDS_UCHAR*)(ptr))[2] = (TDS_UCHAR)((val)>>16);\
92 + ((TDS_UCHAR*)(ptr))[1] = (TDS_UCHAR)((val)>>8); ((TDS_UCHAR*)(ptr))[0] = (TDS_UCHAR)(val); } while(0)
93 #define TDS_PUT_UA4BE(ptr,val) do {\
94 - ((TDS_UCHAR*)(ptr))[0] = (val)>>24; ((TDS_UCHAR*)(ptr))[1] = (val)>>16;\
95 - ((TDS_UCHAR*)(ptr))[2] = (val)>>8; ((TDS_UCHAR*)(ptr))[3] = (val); } while(0)
96 + ((TDS_UCHAR*)(ptr))[0] = (TDS_UCHAR)((val)>>24); ((TDS_UCHAR*)(ptr))[1] = (TDS_UCHAR)((val)>>16);\
97 + ((TDS_UCHAR*)(ptr))[2] = (TDS_UCHAR)((val)>>8); ((TDS_UCHAR*)(ptr))[3] = (TDS_UCHAR)(val); } while(0)
98 #define TDS_PUT_A4LE(ptr,val) TDS_PUT_UA4LE(ptr,val)
99 #define TDS_PUT_A4BE(ptr,val) TDS_PUT_UA4BE(ptr,val)
101 diff -urN freetds/include/tds.h freetds.current/include/tds.h
102 --- freetds/include/tds.h 2007-12-27 14:45:22.000000000 +0100
103 +++ freetds.current/include/tds.h 2008-05-28 00:48:50.000000000 +0200
115 +#if HAVE_ARPA_INET_H
116 +#include <arpa/inet.h>
117 +#endif /* HAVE_ARPA_INET_H */
119 /* forward declaration */
120 typedef struct tdsiconvinfo TDSICONV;
121 typedef struct tds_socket TDSSOCKET;
125 #define TDS_MAX_CAPABILITY 22
126 -#define MAXPRECISION 80
127 +#define MAXPRECISION 77
128 #define TDS_MAX_CONN 4096
129 #define TDS_MAX_DYNID_LEN 30
131 diff -urN freetds/src/apps/freebcp.c freetds.current/src/apps/freebcp.c
132 --- freetds/src/apps/freebcp.c 2006-12-01 22:51:11.000000000 +0100
133 +++ freetds.current/src/apps/freebcp.c 2008-05-28 22:07:55.000000000 +0200
138 -static char software_version[] = "$Id$";
139 +static char software_version[] = "$Id$";
140 static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
150 DBSETLUSER(login, pdata->user);
151 DBSETLPWD(login, pdata->pass);
154 if ((*pdbproc = dbopen(login, pdata->server)) == NULL) {
155 fprintf(stderr, "Can't connect to server \"%s\".\n", pdata->server);
156 + dbloginfree(login);
159 + dbloginfree(login);
162 /* set hint if any */
164 diff -urN freetds/src/apps/tsql.c freetds.current/src/apps/tsql.c
165 --- freetds/src/apps/tsql.c 2008-01-11 13:46:52.000000000 +0100
166 +++ freetds.current/src/apps/tsql.c 2008-05-31 10:53:39.000000000 +0200
168 #include "tdsconvert.h"
169 #include "replacements.h"
171 -TDS_RCSID(var, "$Id$");
172 +TDS_RCSID(var, "$Id$");
174 +#define TDS_ISSPACE(c) isspace((unsigned char) (c))
185 +#ifdef HAVE_GETOPT_OPTRESET
192 * The 'GO' command may be followed by options that apply to the batch.
193 * If they don't appear to be right, assume the letters "go" are part of the
198 - optind = 0; /* reset getopt */
200 opterr = 0; /* suppress error messages */
201 while ((opt = getopt(argc, argv, "fhqtv")) != -1) {
203 @@ -396,24 +407,24 @@
204 opt_flags_str = optarg;
207 - hostname = (char *) malloc(strlen(optarg) + 1);
208 - strcpy(hostname, optarg);
210 + hostname = strdup(optarg);
213 - servername = (char *) malloc(strlen(optarg) + 1);
214 - strcpy(servername, optarg);
216 + servername = strdup(optarg);
219 - username = (char *) malloc(strlen(optarg) + 1);
220 - strcpy(username, optarg);
222 + username = strdup(optarg);
225 - password = (char *) malloc(strlen(optarg) + 1);
226 - strcpy(password, optarg);
228 + password = strdup(optarg);
231 - confile = (char *) malloc(strlen(optarg) + 1);
232 - strcpy(confile, optarg);
234 + confile = strdup(optarg);
241 /* free up all the memory */
253 extern const char STD_DATETIME_FMT[];
255 * The rest of the line may include options that apply to the batch,
256 * and perhaps whitespace.
258 - if (0 == strncasecmp(s, "go", 2) && (strlen(s) == 2 || isspace(s[2]))) {
259 + if (0 == strncasecmp(s, "go", 2) && (strlen(s) == 2 || TDS_ISSPACE(s[2]))) {
260 char *go_line = strdup(s);
263 diff -urN freetds/src/dblib/bcp.c freetds.current/src/dblib/bcp.c
264 --- freetds/src/dblib/bcp.c 2008-01-08 16:38:31.000000000 +0100
265 +++ freetds.current/src/dblib/bcp.c 2008-05-26 14:49:56.000000000 +0200
270 -TDS_RCSID(var, "$Id$");
271 +TDS_RCSID(var, "$Id$");
274 typedef off_t offset_type;
275 @@ -799,11 +799,13 @@
277 if (dbproc->bcpinfo->direction == DB_QUERYOUT ) {
278 if (tds_submit_query(tds, dbproc->bcpinfo->tablename) == TDS_FAIL) {
283 /* TODO quote if needed */
284 if (tds_submit_queryf(tds, "select * from %s", dbproc->bcpinfo->tablename) == TDS_FAIL) {
289 @@ -1061,6 +1063,7 @@
292 if( plen != 0 && written != 1 ) {
294 dbperror(dbproc, SYBEBCWE, errno);
297 @@ -1073,6 +1076,7 @@
299 written = fwrite(hostcol->bcp_column_data->data, buflen, 1, hostfile);
302 dbperror(dbproc, SYBEBCWE, errno);
305 @@ -1082,6 +1086,7 @@
306 if (hostcol->terminator && hostcol->term_len > 0) {
307 written = fwrite(hostcol->terminator, hostcol->term_len, 1, hostfile);
310 dbperror(dbproc, SYBEBCWE, errno);
313 @@ -1094,6 +1099,7 @@
314 dbperror(dbproc, SYBEBCUC, errno);
319 if (dbproc->hostfileinfo->firstrow > 0 && row_of_query < dbproc->hostfileinfo->firstrow) {
321 @@ -1896,8 +1902,10 @@
325 - if (_bcp_start_copy_in(dbproc) == FAIL)
326 + if (_bcp_start_copy_in(dbproc) == FAIL) {
331 tds->out_flag = TDS_BULK;
332 tds_set_state(tds, TDS_QUERYING);
333 @@ -1922,6 +1930,7 @@
335 if (errfile == NULL && dbproc->hostfileinfo->errorfile) {
336 if (!(errfile = fopen(dbproc->hostfileinfo->errorfile, "w"))) {
338 dbperror(dbproc, SYBEBUOE, 0);
341 @@ -2003,6 +2012,7 @@
342 if (tds_process_simple_query(tds) != TDS_SUCCEED) {
349 diff -urN freetds/src/dblib/dblib.c freetds.current/src/dblib/dblib.c
350 --- freetds/src/dblib/dblib.c 2008-01-02 00:09:46.000000000 +0100
351 +++ freetds.current/src/dblib/dblib.c 2008-05-26 14:49:56.000000000 +0200
356 -TDS_RCSID(var, "$Id$");
357 +TDS_RCSID(var, "$Id$");
359 static RETCODE _dbresults(DBPROCESS * dbproc);
360 static int _db_get_server_type(int bindtype);
361 @@ -3325,8 +3325,10 @@
365 - if (i >= tds->num_comp_info)
366 + if (i >= tds->num_comp_info) {
367 + free(col_printlens);
370 resinfo = tds->comp_info[i];
371 if (resinfo->computeid == computeid)
373 diff -urN freetds/src/odbc/odbc.c freetds.current/src/odbc/odbc.c
374 --- freetds/src/odbc/odbc.c 2008-04-30 16:59:32.000000000 +0200
375 +++ freetds.current/src/odbc/odbc.c 2008-06-18 06:11:39.000000000 +0200
380 -TDS_RCSID(var, "$Id$");
381 +TDS_RCSID(var, "$Id$");
383 static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
384 static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
385 @@ -3608,10 +3608,6 @@
387 stmt->errs.lastrc = SQL_SUCCESS_WITH_INFO;
390 - /* TODO change when we code cursors support... */
391 - /* stop looping, forward cursor support only one row */
394 if (drec_ard->sql_desc_octet_length_ptr)
395 *AT_ROW(drec_ard->sql_desc_octet_length_ptr, SQLLEN) = len;
396 @@ -3648,11 +3644,33 @@
398 SQLFetch(SQLHSTMT hstmt)
401 + SQLULEN save_sql_desc_array_size;
402 + SQLULEN *save_sql_desc_rows_processed_ptr;
403 + SQLUSMALLINT *save_sql_desc_array_status_ptr;
407 tdsdump_log(TDS_DBG_FUNC, "SQLFetch(%p)\n", hstmt);
409 - ODBC_RETURN(stmt, _SQLFetch(stmt, SQL_FETCH_NEXT, 0));
410 + if (stmt->dbc->env->attr.odbc_version != SQL_OV_ODBC3) {
411 + save_sql_desc_array_size = stmt->ard->header.sql_desc_array_size;
412 + stmt->ard->header.sql_desc_array_size = 1;
413 + save_sql_desc_rows_processed_ptr = stmt->ird->header.sql_desc_rows_processed_ptr;
414 + stmt->ird->header.sql_desc_rows_processed_ptr = NULL;
415 + save_sql_desc_array_status_ptr = stmt->ird->header.sql_desc_array_status_ptr;
416 + stmt->ird->header.sql_desc_array_status_ptr = NULL;
419 + ret = _SQLFetch(stmt, SQL_FETCH_NEXT, 0);
421 + if (stmt->dbc->env->attr.odbc_version != SQL_OV_ODBC3) {
422 + stmt->ard->header.sql_desc_array_size = save_sql_desc_array_size;
423 + stmt->ird->header.sql_desc_rows_processed_ptr = save_sql_desc_rows_processed_ptr;
424 + stmt->ird->header.sql_desc_array_status_ptr = save_sql_desc_array_status_ptr;
427 + ODBC_RETURN(stmt, ret);
430 #if (ODBCVER >= 0x0300)
431 @@ -4564,6 +4582,8 @@
435 + int extra_bytes = 0;
439 tdsdump_log(TDS_DBG_FUNC, "SQLGetData(%p, %u, %d, %p, %d, %p)\n",
440 @@ -4601,42 +4621,140 @@
441 if (colinfo->column_cur_size < 0) {
442 *pcbValue = SQL_NULL_DATA;
444 + nSybType = tds_get_conversion_type(colinfo->column_type, colinfo->column_size);
445 + if (fCType == SQL_C_DEFAULT)
446 + fCType = odbc_sql_to_c_type_default(stmt->ird->records[icol - 1].sql_desc_concise_type);
447 + if (fCType == SQL_ARD_TYPE) {
448 + if (icol > stmt->ard->header.sql_desc_count) {
449 + odbc_errs_add(&stmt->errs, "07009", NULL);
450 + ODBC_RETURN(stmt, SQL_ERROR);
452 + fCType = stmt->ard->records[icol - 1].sql_desc_concise_type;
456 src = (TDS_CHAR *) colinfo->column_data;
457 if (is_variable_type(colinfo->column_type)) {
458 - if (colinfo->column_text_sqlgetdatapos > 0
459 - && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
460 - ODBC_RETURN(stmt, SQL_NO_DATA);
464 /* 2003-8-29 check for an old bug -- freddy77 */
465 assert(colinfo->column_text_sqlgetdatapos >= 0);
466 if (is_blob_type(colinfo->column_type))
467 src = ((TDSBLOB *) src)->textvalue;
468 - src += colinfo->column_text_sqlgetdatapos;
469 - srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
471 + if (fCType == SQL_C_CHAR && colinfo->column_text_sqlgetdatapos) {
475 + switch (nSybType) {
476 + case SYBLONGBINARY:
481 + case XSYBVARBINARY:
482 + case TDS_CONVERT_BINARY:
483 + if (colinfo->column_text_sqlgetdatapos % 2) {
484 + nread = (colinfo->column_text_sqlgetdatapos - 1) / 2;
485 + if (nread >= colinfo->column_cur_size)
486 + ODBC_RETURN(stmt, SQL_NO_DATA);
488 + if (cbValueMax > 2) {
489 + len = convert_tds2sql(context, nSybType, src + nread, 1, fCType, buf, sizeof(buf), NULL);
492 + odbc_convert_err_set(&stmt->errs, len);
493 + ODBC_RETURN(stmt, SQL_ERROR);
495 + *(TDS_CHAR *) rgbValue = buf[1];
496 + *((TDS_CHAR *) rgbValue + 1) = 0;
504 + if (nread >= colinfo->column_cur_size)
505 + ODBC_RETURN_(stmt);
508 + *(TDS_CHAR *) rgbValue = 0;
509 + odbc_errs_add(&stmt->errs, "01004", "String data, right truncated");
510 + ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
513 + nread = colinfo->column_text_sqlgetdatapos / 2;
514 + if (nread >= colinfo->column_cur_size)
515 + ODBC_RETURN(stmt, SQL_NO_DATA);
519 + srclen = colinfo->column_cur_size - nread;
522 + if (colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
523 + ODBC_RETURN(stmt, SQL_NO_DATA);
525 + src += colinfo->column_text_sqlgetdatapos;
526 + srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
529 + } else if (fCType == SQL_C_BINARY) {
530 + switch (nSybType) {
536 + nread = (src[0] == '0' && toupper(src[1]) == 'X')? 2 : 0;
538 + while ((nread < colinfo->column_cur_size) && (src[nread] == ' ' || src[nread] == '\0'))
541 + nread += colinfo->column_text_sqlgetdatapos * 2;
543 + if (nread && nread >= colinfo->column_cur_size)
544 + ODBC_RETURN(stmt, SQL_NO_DATA);
547 + srclen = colinfo->column_cur_size - nread;
550 + if (colinfo->column_text_sqlgetdatapos > 0
551 + && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
552 + ODBC_RETURN(stmt, SQL_NO_DATA);
554 + src += colinfo->column_text_sqlgetdatapos;
555 + srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
558 + if (colinfo->column_text_sqlgetdatapos > 0
559 + && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
560 + ODBC_RETURN(stmt, SQL_NO_DATA);
562 + src += colinfo->column_text_sqlgetdatapos;
563 + srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
566 if (colinfo->column_text_sqlgetdatapos > 0
567 - && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
568 + && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
569 ODBC_RETURN(stmt, SQL_NO_DATA);
571 srclen = colinfo->column_cur_size;
573 - nSybType = tds_get_conversion_type(colinfo->column_type, colinfo->column_size);
574 - if (fCType == SQL_C_DEFAULT)
575 - fCType = odbc_sql_to_c_type_default(stmt->ird->records[icol - 1].sql_desc_concise_type);
576 - if (fCType == SQL_ARD_TYPE) {
577 - if (icol > stmt->ard->header.sql_desc_count) {
578 - odbc_errs_add(&stmt->errs, "07009", NULL);
579 - ODBC_RETURN(stmt, SQL_ERROR);
581 - fCType = stmt->ard->records[icol - 1].sql_desc_concise_type;
585 *pcbValue = convert_tds2sql(context, nSybType, src, srclen, fCType, (TDS_CHAR *) rgbValue, cbValueMax, NULL);
587 odbc_convert_err_set(&stmt->errs, *pcbValue);
588 ODBC_RETURN(stmt, SQL_ERROR);
593 + colinfo->column_text_sqlgetdatapos += extra_bytes;
594 + *pcbValue += extra_bytes;
597 if (is_variable_type(colinfo->column_type) && (fCType == SQL_C_CHAR || fCType == SQL_C_BINARY)) {
598 /* calc how many bytes was readed */
599 int readed = cbValueMax;
600 diff -urN freetds/src/odbc/unittests/cursor6.c freetds.current/src/odbc/unittests/cursor6.c
601 --- freetds/src/odbc/unittests/cursor6.c 1970-01-01 01:00:00.000000000 +0100
602 +++ freetds.current/src/odbc/unittests/cursor6.c 2008-06-06 18:52:23.000000000 +0200
606 +/* Test SQLFetchScroll with no binded columns */
608 +static char software_version[] = "$Id$";
609 +static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
611 +static int bind_all = 0;
612 +static int normal_fetch = 0;
613 +static int use_cursors = 1;
615 +#define CHK(func,params) do { \
616 + if (func params != SQL_SUCCESS) \
617 + ODBC_REPORT_ERROR(#func); \
620 +static void Test(void)
629 + SQLUSMALLINT statuses[ROWS];
634 + /* this should not fail or return warnings */
636 + CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CONCURRENCY, int2ptr(SQL_CONCUR_READ_ONLY), 0));
637 + CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_TYPE, int2ptr(SQL_CURSOR_STATIC), 0));
639 + CHK(SQLPrepare, (Statement, (SQLCHAR *) "SELECT c, i FROM #cursor6_test", SQL_NTS));
640 + CHK(SQLExecute, (Statement));
641 + CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_BIND_TYPE, int2ptr(sizeof(data[0])), 0));
642 + CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_ARRAY_SIZE, int2ptr(ROWS), 0));
643 + CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_STATUS_PTR, statuses, 0));
644 + CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROWS_FETCHED_PTR, &num_row, 0));
646 + CHK(SQLBindCol, (Statement, 1, SQL_C_CHAR, &data[0].c, sizeof(data[0].c), &data[0].ind_c));
647 + CHK(SQLBindCol, (Statement, 2, SQL_C_LONG, &data[0].i, sizeof(data[0].i), &data[0].ind_i));
649 +#define FILL(s, n) do { \
650 + int _n; for (_n = 0; _n < sizeof(s)/sizeof(s[0]); ++_n) s[_n] = n; \
652 + FILL(statuses, 9876);
654 + data[0].i = 0xdeadbeef;
655 + data[1].i = 0xdeadbeef;
657 + CHK(SQLFetch, (Statement));
659 + CHK(SQLFetchScroll, (Statement, SQL_FETCH_NEXT, 0));
661 + /* now check row numbers */
662 + printf("num_row %d statuses[0] %d statuses[1] %d odbc3 %d\n", (int) num_row,
663 + (int) statuses[0], (int) statuses[1], use_odbc_version3);
665 + if (use_odbc_version3 || !normal_fetch) {
666 + if (num_row != ROWS || statuses[0] != SQL_ROW_SUCCESS || statuses[1] != SQL_ROW_SUCCESS) {
667 + fprintf(stderr, "result error 1\n");
671 + if (data[0].i != 1 || data[1].i != 0xdeadbeef) {
672 + fprintf(stderr, "result error 2\n");
677 + FILL(statuses, 8765);
680 + CHK(SQLFetch, (Statement));
682 + CHK(SQLFetchScroll, (Statement, SQL_FETCH_NEXT, 0));
685 +static void Init(void)
690 + Command(Statement, "CREATE TABLE #cursor6_test (i INT, c VARCHAR(20))");
691 + for (i = 1; i <= 10; ++i) {
692 + sprintf(sql, "INSERT INTO #cursor6_test(i,c) VALUES(%d, 'a%db%dc%d')", i, i, i, i);
693 + Command(Statement, sql);
699 +main(int argc, char *argv[])
701 + unsigned char sqlstate[6];
702 + unsigned char msg[256];
705 + use_odbc_version3 = 1;
708 + retcode = SQLSetConnectAttr(Connection, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, SQL_IS_INTEGER);
709 + if (retcode != SQL_SUCCESS) {
710 + CHK(SQLGetDiagRec, (SQL_HANDLE_DBC, Connection, 1, sqlstate, NULL, (SQLCHAR *) msg, sizeof(msg), NULL));
712 + if (strcmp((const char*) sqlstate, "S1092") == 0) {
713 + printf("Your connection seems to not support cursors, probably you are using wrong protocol version or Sybase\n");
717 + ODBC_REPORT_ERROR("SQLSetConnectAttr");
722 +#define ALL(n) for (n = 0; n < 2; ++n)
730 + use_odbc_version3 = 0;
744 diff -urN freetds/src/odbc/unittests/getdata.c freetds.current/src/odbc/unittests/getdata.c
745 --- freetds/src/odbc/unittests/getdata.c 2008-01-29 11:14:31.000000000 +0100
746 +++ freetds.current/src/odbc/unittests/getdata.c 2008-06-18 06:11:39.000000000 +0200
750 -static char software_version[] = "$Id$";
751 +static char software_version[] = "$Id$";
752 static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
754 static char odbc_err[256];
757 memset(odbc_err, 0, sizeof(odbc_err));
758 memset(odbc_sqlstate, 0, sizeof(odbc_sqlstate));
759 - if (!SQL_SUCCEEDED(SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, (SQLCHAR *) odbc_sqlstate, NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL))) {
760 + if (!SQL_SUCCEEDED(SQLGetDiagRec(SQL_HANDLE_STMT
763 + , (SQLCHAR *) odbc_sqlstate
765 + , (SQLCHAR *) odbc_err
768 printf("SQLGetDiagRec should not fail\n");
771 diff -urN freetds/src/odbc/unittests/Makefile.am freetds.current/src/odbc/unittests/Makefile.am
772 --- freetds/src/odbc/unittests/Makefile.am 2008-02-29 10:23:51.000000000 +0100
773 +++ freetds.current/src/odbc/unittests/Makefile.am 2008-06-06 18:52:23.000000000 +0200
778 t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
779 t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
781 connect2$(EXEEXT) timeout4$(EXEEXT) freeclose$(EXEEXT) \
782 cursor3$(EXEEXT) cursor4$(EXEEXT) cursor5$(EXEEXT) \
783 attributes$(EXEEXT) hidden$(EXEEXT) blob1$(EXEEXT) \
785 + rowset$(EXEEXT) cursor6$(EXEEXT)
787 check_PROGRAMS = $(TESTS)
790 hidden_SOURCES = hidden.c common.c common.h
791 blob1_SOURCES = blob1.c common.c common.h
792 rowset_SOURCES = rowset.c common.c common.h
793 +cursor6_SOURCES = cursor6.c common.c common.h
795 AM_CPPFLAGS = -I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_SRCDIR=\"$(srcdir)\"
797 diff -urN freetds/src/server/server.c freetds.current/src/server/server.c
798 --- freetds/src/server/server.c 2008-01-07 15:07:21.000000000 +0100
799 +++ freetds.current/src/server/server.c 2008-05-28 23:08:03.000000000 +0200
804 -static char software_version[] = "$Id$";
805 +static char software_version[] = "$Id$";
806 static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
809 @@ -117,13 +117,17 @@
810 const char *msgtext, const char *srvname, const char *procname, int line)
815 tds_put_byte(tds, TDS_INFO_TOKEN);
818 + len = strlen(procname);
819 msgsz = 4 /* msg no */
823 - + (IS_TDS7_PLUS(tds) ? 2 : 1) * (strlen(msgtext) + 1 + strlen(srvname) + 1 + strlen(procname))
824 + + (IS_TDS7_PLUS(tds) ? 2 : 1) * (strlen(msgtext) + 1 + strlen(srvname) + 1 + len)
825 + 1 + 2; /* line number */
826 tds_put_smallint(tds, msgsz);
827 tds_put_int(tds, msgno);
828 @@ -135,10 +139,10 @@
829 tds_put_byte(tds, strlen(srvname));
831 tds_put_string(tds, srvname, strlen(srvname));
832 - if (procname && strlen(procname)) {
833 - tds_put_byte(tds, strlen(procname));
835 + tds_put_byte(tds, len);
837 - tds_put_string(tds, procname, strlen(procname));
838 + tds_put_string(tds, procname, len);
840 tds_put_byte(tds, 0);
842 diff -urN freetds/src/tds/mem.c freetds.current/src/tds/mem.c
843 --- freetds/src/tds/mem.c 2007-12-31 11:06:50.000000000 +0100
844 +++ freetds.current/src/tds/mem.c 2008-05-26 14:49:56.000000000 +0200
849 -TDS_RCSID(var, "$Id$");
850 +TDS_RCSID(var, "$Id$");
852 static void tds_free_env(TDSSOCKET * tds);
853 static void tds_free_compute_results(TDSSOCKET * tds);
854 @@ -1040,6 +1040,9 @@
856 tds_free_connection(TDSCONNECTION * connection)
861 tds_dstr_free(&connection->server_name);
862 tds_dstr_free(&connection->client_host_name);
863 tds_dstr_free(&connection->server_host_name);