]> git.pld-linux.org Git - packages/freetds.git/blame - freetds-cvs-fixes.patch
- release 3
[packages/freetds.git] / freetds-cvs-fixes.patch
CommitLineData
519025e2 1diff -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
4@@ -1,7 +1,7 @@
5 dnl Process this file with autoconf to produce a configure script.
6
7 dnl ------------------------------------------------------------
8-dnl $Id$
9+dnl $Id$
10 dnl If you're trying to create a new configure test, try
11 dnl
12 dnl http://autogen.sourceforge.net/conftest.html
13@@ -240,7 +240,7 @@
14 ])
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])
22@@ -347,6 +347,16 @@
23
24 TYPE_SOCKLEN_T
25
26+AC_MSG_CHECKING([whether getopt has optreset support])
27+AC_TRY_LINK([#ifdef HAVE_GETOPT_H
28+#include <getopt.h>
29+#endif], [extern int optreset; optreset = 0;],
30+[AC_MSG_RESULT(yes)
31+AC_DEFINE(HAVE_GETOPT_OPTRESET, 1, [Define if your getopt(3) defines and uses optreset])],
32+[AC_MSG_RESULT(no)]
33+)
34+
35+
36 # ------------------------------------------------------------
37 # Checks for compiler characteristics.
38 # ------------------------------------------------------------
39diff -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
42@@ -34,7 +34,7 @@
43 #define TDS_STATIC_CAST(type, a) ((type)(a))
44 #endif
45
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 };
49
50 #define CS_PUBLIC
51@@ -447,6 +447,9 @@
52
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
58
59 #define CS_FORCE_EXIT 300
60 #define CS_FORCE_CLOSE 301
61diff -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
64@@ -20,7 +20,7 @@
65 #ifndef _tdsbytes_h_
66 #define _tdsbytes_h_
67
68-/* $Id$ */
69+/* $Id$ */
70
71 #ifndef _tds_h_
72 #error tds.h must be included before tdsbytes.h
73@@ -61,9 +61,9 @@
74 #define TDS_GET_A2BE(ptr) TDS_GET_UA2BE(ptr)
75
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)
84
85@@ -78,11 +78,11 @@
86 #define TDS_GET_A4BE(ptr) TDS_GET_UA4BE(ptr)
87
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)
100
101diff -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
104@@ -20,12 +20,16 @@
105 #ifndef _tds_h_
106 #define _tds_h_
107
108-/* $Id$ */
109+/* $Id$ */
110
111 #include <stdarg.h>
112 #include <stdio.h>
113 #include <time.h>
114
115+#if HAVE_ARPA_INET_H
116+#include <arpa/inet.h>
117+#endif /* HAVE_ARPA_INET_H */
118+
119 /* forward declaration */
120 typedef struct tdsiconvinfo TDSICONV;
121 typedef struct tds_socket TDSSOCKET;
122@@ -747,7 +751,7 @@
123
124
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
130
131diff -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
134@@ -45,7 +45,7 @@
135 #include <sybdb.h>
136 #include "freebcp.h"
137
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 };
141
142 void pusage(void);
143@@ -351,6 +351,8 @@
144 */
145
146 login = dblogin();
147+ if (!login)
148+ return FALSE;
149
150 DBSETLUSER(login, pdata->user);
151 DBSETLPWD(login, pdata->pass);
152@@ -372,8 +374,11 @@
153
154 if ((*pdbproc = dbopen(login, pdata->server)) == NULL) {
155 fprintf(stderr, "Can't connect to server \"%s\".\n", pdata->server);
156+ dbloginfree(login);
157 return (FALSE);
158 }
159+ dbloginfree(login);
160+ login = NULL;
161
162 /* set hint if any */
163 if (pdata->hint) {
164diff -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
167@@ -85,7 +85,9 @@
168 #include "tdsconvert.h"
169 #include "replacements.h"
170
171-TDS_RCSID(var, "$Id$");
172+TDS_RCSID(var, "$Id$");
173+
174+#define TDS_ISSPACE(c) isspace((unsigned char) (c))
175
176 enum
177 {
178@@ -301,6 +303,15 @@
179 progname, progname);
180 }
181
182+static void
183+reset_getopt(void)
184+{
185+#ifdef HAVE_GETOPT_OPTRESET
186+ optreset = 1;
187+#endif
188+ optind = 1;
189+}
190+
191 /*
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
194@@ -324,7 +335,7 @@
195 s = NULL;
196
197 *opt_flags = 0;
198- optind = 0; /* reset getopt */
199+ reset_getopt();
200 opterr = 0; /* suppress error messages */
201 while ((opt = getopt(argc, argv, "fhqtv")) != -1) {
202 switch (opt) {
203@@ -396,24 +407,24 @@
204 opt_flags_str = optarg;
205 break;
206 case 'H':
207- hostname = (char *) malloc(strlen(optarg) + 1);
208- strcpy(hostname, optarg);
209+ free(hostname);
210+ hostname = strdup(optarg);
211 break;
212 case 'S':
213- servername = (char *) malloc(strlen(optarg) + 1);
214- strcpy(servername, optarg);
215+ free(servername);
216+ servername = strdup(optarg);
217 break;
218 case 'U':
219- username = (char *) malloc(strlen(optarg) + 1);
220- strcpy(username, optarg);
221+ free(username);
222+ username = strdup(optarg);
223 break;
224 case 'P':
225- password = (char *) malloc(strlen(optarg) + 1);
226- strcpy(password, optarg);
227+ free(password);
228+ password = strdup(optarg);
229 break;
230 case 'I':
231- confile = (char *) malloc(strlen(optarg) + 1);
232- strcpy(confile, optarg);
233+ free(confile);
234+ confile = strdup(optarg);
235 break;
236 case 'p':
237 port = atoi(optarg);
238@@ -524,6 +535,7 @@
239 }
240
241 /* free up all the memory */
242+ free(confile);
243 free(hostname);
244 free(username);
245 free(password);
246@@ -572,6 +584,7 @@
247 tsql_add_history(s);
248 (*line)++;
249 }
250+ fclose(fp);
251 }
252
253 extern const char STD_DATETIME_FMT[];
254@@ -709,7 +722,7 @@
255 * The rest of the line may include options that apply to the batch,
256 * and perhaps whitespace.
257 */
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);
261 assert(go_line);
262 line = 0;
263diff -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
266@@ -71,7 +71,7 @@
267 }
268 TDS_PBCB;
269
270-TDS_RCSID(var, "$Id$");
271+TDS_RCSID(var, "$Id$");
272
273 #ifdef HAVE_FSEEKO
274 typedef off_t offset_type;
275@@ -799,11 +799,13 @@
276
277 if (dbproc->bcpinfo->direction == DB_QUERYOUT ) {
278 if (tds_submit_query(tds, dbproc->bcpinfo->tablename) == TDS_FAIL) {
279+ fclose(hostfile);
280 return FAIL;
281 }
282 } else {
283 /* TODO quote if needed */
284 if (tds_submit_queryf(tds, "select * from %s", dbproc->bcpinfo->tablename) == TDS_FAIL) {
285+ fclose(hostfile);
286 return FAIL;
287 }
288 }
289@@ -1061,6 +1063,7 @@
290 break;
291 }
292 if( plen != 0 && written != 1 ) {
293+ fclose(hostfile);
294 dbperror(dbproc, SYBEBCWE, errno);
295 return FAIL;
296 }
297@@ -1073,6 +1076,7 @@
298 if (buflen > 0) {
299 written = fwrite(hostcol->bcp_column_data->data, buflen, 1, hostfile);
300 if (written < 1) {
301+ fclose(hostfile);
302 dbperror(dbproc, SYBEBCWE, errno);
303 return FAIL;
304 }
305@@ -1082,6 +1086,7 @@
306 if (hostcol->terminator && hostcol->term_len > 0) {
307 written = fwrite(hostcol->terminator, hostcol->term_len, 1, hostfile);
308 if (written < 1) {
309+ fclose(hostfile);
310 dbperror(dbproc, SYBEBCWE, errno);
311 return FAIL;
312 }
313@@ -1094,6 +1099,7 @@
314 dbperror(dbproc, SYBEBCUC, errno);
315 return (FAIL);
316 }
317+ hostfile = NULL;
318
319 if (dbproc->hostfileinfo->firstrow > 0 && row_of_query < dbproc->hostfileinfo->firstrow) {
320 /*
321@@ -1896,8 +1902,10 @@
322 return FAIL;
323 }
324
325- if (_bcp_start_copy_in(dbproc) == FAIL)
326+ if (_bcp_start_copy_in(dbproc) == FAIL) {
327+ fclose(hostfile);
328 return FAIL;
329+ }
330
331 tds->out_flag = TDS_BULK;
332 tds_set_state(tds, TDS_QUERYING);
333@@ -1922,6 +1930,7 @@
334
335 if (errfile == NULL && dbproc->hostfileinfo->errorfile) {
336 if (!(errfile = fopen(dbproc->hostfileinfo->errorfile, "w"))) {
337+ fclose(hostfile);
338 dbperror(dbproc, SYBEBUOE, 0);
339 return FAIL;
340 }
341@@ -2003,6 +2012,7 @@
342 if (tds_process_simple_query(tds) != TDS_SUCCEED) {
343 if (errfile)
344 fclose(errfile);
345+ fclose(hostfile);
346 return FAIL;
347 }
348
349diff -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
352@@ -76,7 +76,7 @@
353 #include <dmalloc.h>
354 #endif
355
356-TDS_RCSID(var, "$Id$");
357+TDS_RCSID(var, "$Id$");
358
359 static RETCODE _dbresults(DBPROCESS * dbproc);
360 static int _db_get_server_type(int bindtype);
361@@ -3325,8 +3325,10 @@
362 computeid = status;
363
364 for (i = 0;; ++i) {
365- if (i >= tds->num_comp_info)
366+ if (i >= tds->num_comp_info) {
367+ free(col_printlens);
368 return FAIL;
369+ }
370 resinfo = tds->comp_info[i];
371 if (resinfo->computeid == computeid)
372 break;
373diff -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
376@@ -60,7 +60,7 @@
377 #include <dmalloc.h>
378 #endif
379
380-TDS_RCSID(var, "$Id$");
381+TDS_RCSID(var, "$Id$");
382
383 static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
384 static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
385@@ -3608,10 +3608,6 @@
386 truncated = 1;
387 stmt->errs.lastrc = SQL_SUCCESS_WITH_INFO;
388 }
389- } else {
390- /* TODO change when we code cursors support... */
391- /* stop looping, forward cursor support only one row */
392- num_rows = 1;
393 }
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 @@
397 SQLRETURN ODBC_API
398 SQLFetch(SQLHSTMT hstmt)
399 {
400+ SQLRETURN ret;
401+ SQLULEN save_sql_desc_array_size;
402+ SQLULEN *save_sql_desc_rows_processed_ptr;
403+ SQLUSMALLINT *save_sql_desc_array_status_ptr;
404+
405 INIT_HSTMT;
406
407 tdsdump_log(TDS_DBG_FUNC, "SQLFetch(%p)\n", hstmt);
408
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;
417+ }
418+
419+ ret = _SQLFetch(stmt, SQL_FETCH_NEXT, 0);
420+
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;
425+ }
426+
427+ ODBC_RETURN(stmt, ret);
428 }
429
430 #if (ODBCVER >= 0x0300)
431@@ -4564,6 +4582,8 @@
432 SQLLEN dummy_cb;
433 int nSybType;
434
435+ int extra_bytes = 0;
436+
437 INIT_HSTMT;
438
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;
443 } else {
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);
451+ }
452+ fCType = stmt->ard->records[icol - 1].sql_desc_concise_type;
453+ }
454+ assert(fCType);
455+
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);
461-
462+ int nread = 0;
463+
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;
470+
471+ if (fCType == SQL_C_CHAR && colinfo->column_text_sqlgetdatapos) {
472+ TDS_CHAR buf[3];
473+ SQLLEN len;
474+
475+ switch (nSybType) {
476+ case SYBLONGBINARY:
477+ case SYBBINARY:
478+ case SYBVARBINARY:
479+ case SYBIMAGE:
480+ case XSYBBINARY:
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);
487+
488+ if (cbValueMax > 2) {
489+ len = convert_tds2sql(context, nSybType, src + nread, 1, fCType, buf, sizeof(buf), NULL);
490+ if (len < 2) {
491+ if (len < 0)
492+ odbc_convert_err_set(&stmt->errs, len);
493+ ODBC_RETURN(stmt, SQL_ERROR);
494+ }
495+ *(TDS_CHAR *) rgbValue = buf[1];
496+ *((TDS_CHAR *) rgbValue + 1) = 0;
497+
498+ rgbValue++;
499+ cbValueMax--;
500+
501+ extra_bytes = 1;
502+ nread++;
503+
504+ if (nread >= colinfo->column_cur_size)
505+ ODBC_RETURN_(stmt);
506+ } else {
507+ if (cbValueMax)
508+ *(TDS_CHAR *) rgbValue = 0;
509+ odbc_errs_add(&stmt->errs, "01004", "String data, right truncated");
510+ ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
511+ }
512+ } else {
513+ nread = colinfo->column_text_sqlgetdatapos / 2;
514+ if (nread >= colinfo->column_cur_size)
515+ ODBC_RETURN(stmt, SQL_NO_DATA);
516+ }
517+
518+ src += nread;
519+ srclen = colinfo->column_cur_size - nread;
520+ break;
521+ default:
522+ if (colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
523+ ODBC_RETURN(stmt, SQL_NO_DATA);
524+
525+ src += colinfo->column_text_sqlgetdatapos;
526+ srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
527+
528+ }
529+ } else if (fCType == SQL_C_BINARY) {
530+ switch (nSybType) {
531+ case SYBCHAR:
532+ case SYBVARCHAR:
533+ case SYBTEXT:
534+ case XSYBCHAR:
535+ case XSYBVARCHAR:
536+ nread = (src[0] == '0' && toupper(src[1]) == 'X')? 2 : 0;
537+
538+ while ((nread < colinfo->column_cur_size) && (src[nread] == ' ' || src[nread] == '\0'))
539+ nread++;
540+
541+ nread += colinfo->column_text_sqlgetdatapos * 2;
542+
543+ if (nread && nread >= colinfo->column_cur_size)
544+ ODBC_RETURN(stmt, SQL_NO_DATA);
545+
546+ src += nread;
547+ srclen = colinfo->column_cur_size - nread;
548+ break;
549+ default:
550+ if (colinfo->column_text_sqlgetdatapos > 0
551+ && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
552+ ODBC_RETURN(stmt, SQL_NO_DATA);
553+
554+ src += colinfo->column_text_sqlgetdatapos;
555+ srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
556+ }
557+ } else {
558+ if (colinfo->column_text_sqlgetdatapos > 0
559+ && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
560+ ODBC_RETURN(stmt, SQL_NO_DATA);
561+
562+ src += colinfo->column_text_sqlgetdatapos;
563+ srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
564+ }
565 } else {
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);
570
571 srclen = colinfo->column_cur_size;
572 }
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);
580- }
581- fCType = stmt->ard->records[icol - 1].sql_desc_concise_type;
582- }
583- assert(fCType);
584+
585 *pcbValue = convert_tds2sql(context, nSybType, src, srclen, fCType, (TDS_CHAR *) rgbValue, cbValueMax, NULL);
586 if (*pcbValue < 0) {
587 odbc_convert_err_set(&stmt->errs, *pcbValue);
588 ODBC_RETURN(stmt, SQL_ERROR);
589 }
590-
591+
592+ if (extra_bytes) {
593+ colinfo->column_text_sqlgetdatapos += extra_bytes;
594+ *pcbValue += extra_bytes;
595+ }
596+
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;
600diff -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
603@@ -0,0 +1,140 @@
604+#include "common.h"
605+
606+/* Test SQLFetchScroll with no binded columns */
607+
608+static char software_version[] = "$Id$";
609+static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
610+
611+static int bind_all = 0;
612+static int normal_fetch = 0;
613+static int use_cursors = 1;
614+
615+#define CHK(func,params) do { \
616+ if (func params != SQL_SUCCESS) \
617+ ODBC_REPORT_ERROR(#func); \
618+ } while(0)
619+
620+static void Test(void)
621+{
622+#define ROWS 5
623+ struct data_t {
624+ SQLINTEGER i;
625+ SQLLEN ind_i;
626+ char c[20];
627+ SQLLEN ind_c;
628+ } data[ROWS];
629+ SQLUSMALLINT statuses[ROWS];
630+ SQLULEN num_row;
631+
632+ ResetStatement();
633+
634+ /* this should not fail or return warnings */
635+ if (use_cursors) {
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));
638+ }
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));
645+ if (bind_all)
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));
648+
649+#define FILL(s, n) do { \
650+ int _n; for (_n = 0; _n < sizeof(s)/sizeof(s[0]); ++_n) s[_n] = n; \
651+} while(0)
652+ FILL(statuses, 9876);
653+ num_row = -3;
654+ data[0].i = 0xdeadbeef;
655+ data[1].i = 0xdeadbeef;
656+ if (normal_fetch)
657+ CHK(SQLFetch, (Statement));
658+ else
659+ CHK(SQLFetchScroll, (Statement, SQL_FETCH_NEXT, 0));
660+
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);
664+
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");
668+ exit(1);
669+ }
670+ } else {
671+ if (data[0].i != 1 || data[1].i != 0xdeadbeef) {
672+ fprintf(stderr, "result error 2\n");
673+ exit(1);
674+ }
675+ }
676+
677+ FILL(statuses, 8765);
678+ num_row = -3;
679+ if (normal_fetch)
680+ CHK(SQLFetch, (Statement));
681+ else
682+ CHK(SQLFetchScroll, (Statement, SQL_FETCH_NEXT, 0));
683+}
684+
685+static void Init(void)
686+{
687+ int i;
688+ char sql[128];
689+
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);
694+ }
695+
696+}
697+
698+int
699+main(int argc, char *argv[])
700+{
701+ unsigned char sqlstate[6];
702+ unsigned char msg[256];
703+ SQLRETURN retcode;
704+
705+ use_odbc_version3 = 1;
706+ Connect();
707+
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));
711+ sqlstate[5] = 0;
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");
714+ Disconnect();
715+ exit(0);
716+ }
717+ ODBC_REPORT_ERROR("SQLSetConnectAttr");
718+ }
719+
720+ Init();
721+
722+#define ALL(n) for (n = 0; n < 2; ++n)
723+ ALL(use_cursors)
724+ ALL(bind_all)
725+ ALL(normal_fetch)
726+ Test();
727+
728+ Disconnect();
729+
730+ use_odbc_version3 = 0;
731+
732+ Connect();
733+ Init();
734+
735+ ALL(use_cursors)
736+ ALL(bind_all)
737+ ALL(normal_fetch)
738+ Test();
739+
740+ Disconnect();
741+
742+ return 0;
743+}
744diff -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
747@@ -1,6 +1,6 @@
748 #include "common.h"
749
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 };
753
754 static char odbc_err[256];
755@@ -11,7 +11,14 @@
756 {
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
761+ , Statement
762+ , 1
763+ , (SQLCHAR *) odbc_sqlstate
764+ , NULL
765+ , (SQLCHAR *) odbc_err
766+ , sizeof(odbc_err)
767+ , NULL))) {
768 printf("SQLGetDiagRec should not fail\n");
769 exit(1);
770 }
771diff -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
774@@ -1,4 +1,4 @@
775-# $Id$
776+# $Id$
777 TESTS = \
778 t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
779 t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
780@@ -21,7 +21,7 @@
781 connect2$(EXEEXT) timeout4$(EXEEXT) freeclose$(EXEEXT) \
782 cursor3$(EXEEXT) cursor4$(EXEEXT) cursor5$(EXEEXT) \
783 attributes$(EXEEXT) hidden$(EXEEXT) blob1$(EXEEXT) \
784- rowset$(EXEEXT)
785+ rowset$(EXEEXT) cursor6$(EXEEXT)
786
787 check_PROGRAMS = $(TESTS)
788
789@@ -81,6 +81,7 @@
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
794
795 AM_CPPFLAGS = -I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_SRCDIR=\"$(srcdir)\"
796 if MINGW32
797diff -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
800@@ -30,7 +30,7 @@
801 #include "tds.h"
802 #include "tdssrv.h"
803
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 };
807
808 void
809@@ -117,13 +117,17 @@
810 const char *msgtext, const char *srvname, const char *procname, int line)
811 {
812 int msgsz;
813+ size_t len;
814
815 tds_put_byte(tds, TDS_INFO_TOKEN);
816+ if (!procname)
817+ procname = "";
818+ len = strlen(procname);
819 msgsz = 4 /* msg no */
820 + 1 /* msg state */
821 + 1 /* severity */
822 /* FIXME ucs2 */
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));
830 /* FIXME ucs2 */
831 tds_put_string(tds, srvname, strlen(srvname));
832- if (procname && strlen(procname)) {
833- tds_put_byte(tds, strlen(procname));
834+ if (len) {
835+ tds_put_byte(tds, len);
836 /* FIXME ucs2 */
837- tds_put_string(tds, procname, strlen(procname));
838+ tds_put_string(tds, procname, len);
839 } else {
840 tds_put_byte(tds, 0);
841 }
842diff -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
845@@ -47,7 +47,7 @@
846 #include <dmalloc.h>
847 #endif
848
849-TDS_RCSID(var, "$Id$");
850+TDS_RCSID(var, "$Id$");
851
852 static void tds_free_env(TDSSOCKET * tds);
853 static void tds_free_compute_results(TDSSOCKET * tds);
854@@ -1040,6 +1040,9 @@
855 void
856 tds_free_connection(TDSCONNECTION * connection)
857 {
858+ if (!connection)
859+ return;
860+
861 tds_dstr_free(&connection->server_name);
862 tds_dstr_free(&connection->client_host_name);
863 tds_dstr_free(&connection->server_host_name);
This page took 0.248495 seconds and 4 git commands to generate.