NCBI C++ ToolKit
convert_tds2sql.c
Go to the documentation of this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

1 /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
2  * Copyright (C) 1998-1999 Brian Bruns
3  * Copyright (C) 2003-2010 Frediano Ziglio
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20 
21 #include <config.h>
22 
23 #include <assert.h>
24 
25 #if HAVE_STDLIB_H
26 #include <stdlib.h>
27 #endif /* HAVE_STDLIB_H */
28 
29 #if HAVE_STRING_H
30 #include <string.h>
31 #endif /* HAVE_STRING_H */
32 
33 #include <ctype.h>
34 
35 #include <freetds/odbc.h>
36 #include <freetds/convert.h>
37 #include <freetds/iconv.h>
38 #include <freetds/string.h>
39 #include <odbcss.h>
40 
41 #define TDS_ISSPACE(c) isspace((unsigned char) (c))
42 
43 /**
44  * Handle conversions from TDS (N)CHAR to ODBC (W)CHAR
45  */
46 static SQLLEN
47 odbc_convert_char(TDS_STMT * stmt, TDSCOLUMN * curcol, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen)
48 {
49  const char *ib;
50  char *ob;
51  size_t il, ol, char_size;
52 
53  /* FIXME MARS not correct cause is the global tds but stmt->tds can be NULL on SQLGetData */
54  TDSSOCKET *tds = stmt->dbc->tds_socket;
55  TDSICONV *conv;
56 
57  if (curcol == NULL) {
58  odbc_errs_add(&stmt->errs, "HY013", NULL);
59  return SQL_NULL_DATA;
60  }
61 
62  conv = curcol->char_conv;
63  if (!conv)
65  if (desttype == SQL_C_WCHAR) {
66  const char *charset = odbc_get_wide_name(tds->conn);
67  /* SQL_C_WCHAR, convert to wide encode */
68  conv = tds_iconv_get(tds->conn, charset, conv->to.charset.name);
69  if (!conv)
70  conv = tds_iconv_get(tds->conn, charset, "ISO-8859-1");
71 #ifdef ENABLE_ODBC_WIDE
72  } else {
73  conv = tds_iconv_get(tds->conn, tds_dstr_cstr(&stmt->dbc->original_charset), conv->to.charset.name);
74  if (!conv)
75  conv = tds_iconv_get(tds->conn, tds_dstr_cstr(&stmt->dbc->original_charset), "ISO-8859-1");
76  if (!conv)
77  conv = tds_iconv_get(tds->conn, "ISO-8859-1", "ISO-8859-1");
78 #endif
79  }
80 
81  ib = src;
82  il = srclen;
83  ob = dest;
84  ol = 0;
85  char_size = desttype == SQL_C_CHAR ? 1 : SIZEOF_SQLWCHAR;
86  if (destlen >= char_size) {
87  ol = destlen - char_size;
88  memset(&conv->suppress, 0, sizeof(conv->suppress));
89  conv->suppress.e2big = 1;
90  /* TODO check return value */
91  tds_iconv(tds, conv, to_client, &ib, &il, &ob, &ol);
92  ol = ob - dest; /* bytes written */
93  curcol->column_text_sqlgetdatapos += (TDS_INT) (ib - src);
94  /* terminate string */
95  memset(ob, 0, char_size);
96  }
97 
98  /* returned size have to take into account buffer left unconverted */
100  && conv->to.charset.min_bytes_per_char == conv->to.charset.max_bytes_per_char)) {
101  ol += il * conv->from.charset.min_bytes_per_char / conv->to.charset.min_bytes_per_char;
102  } else if ((conv->flags & TDS_ENCODING_MEMCPY) != 0) {
103  ol += il;
104  } else {
105  /* TODO convert and discard ?? or return proper SQL_NO_TOTAL values ?? */
106  return SQL_NO_TOTAL;
107  }
108  return ol;
109 }
110 
111 /**
112  * Handle conversions from TDS NCHAR to ISO8859-1 striping spaces (for fixed types)
113  */
114 static int
116 {
117  TDS_CHAR *p;
118  /*
119  * TODO check for endian
120  * This affect for instance Sybase under little endian system
121  */
122 
123  /* skip white spaces */
124  while (srclen > 1 && src[1] == 0 && TDS_ISSPACE(src[0])) {
125  srclen -= 2;
126  src += 2;
127  }
128 
129  /* convert */
130  p = buf;
131  while (buf_len > 1 && srclen > 1 && src[1] == 0) {
132  *p++ = src[0];
133  --buf_len;
134  srclen -= 2;
135  src += 2;
136  }
137 
138  /* skip white spaces */
139  while (srclen > 1 && src[1] == 0 && TDS_ISSPACE(src[0])) {
140  srclen -= 2;
141  src += 2;
142  }
143 
144  /* still characters, wrong format */
145  if (srclen)
146  return -1;
147 
148  *p = 0;
149  return (int) (p - buf);
150 }
151 
152 /* The following structure is going to write in these structure not using them
153  * but just knowing the ABI. Check these ABI. Mainly make sure the alignment
154  * is still correct.
155  */
156 TDS_COMPILE_CHECK(ss_time2, sizeof(SQL_SS_TIME2_STRUCT) == 12
157  && TDS_OFFSET(SQL_SS_TIME2_STRUCT, fraction) == 8);
158 TDS_COMPILE_CHECK(ss_timestampoffset, sizeof(SQL_SS_TIMESTAMPOFFSET_STRUCT) == 20
159  && TDS_OFFSET(SQL_SS_TIMESTAMPOFFSET_STRUCT, fraction) == 12);
160 TDS_COMPILE_CHECK(date_struct, sizeof(DATE_STRUCT) == 6
161  && TDS_OFFSET(DATE_STRUCT, year) == 0
162  && TDS_OFFSET(DATE_STRUCT, month) == 2
163  && TDS_OFFSET(DATE_STRUCT, day) == 4);
164 TDS_COMPILE_CHECK(timestamp_struct, sizeof(TIMESTAMP_STRUCT) == 16
165  && TDS_OFFSET(TIMESTAMP_STRUCT, year) == 0
166  && TDS_OFFSET(TIMESTAMP_STRUCT, month) == 2
167  && TDS_OFFSET(TIMESTAMP_STRUCT, day) == 4
168  && TDS_OFFSET(TIMESTAMP_STRUCT, hour) == 6
169  && TDS_OFFSET(TIMESTAMP_STRUCT, minute) == 8
170  && TDS_OFFSET(TIMESTAMP_STRUCT, second) == 10
171  && TDS_OFFSET(TIMESTAMP_STRUCT, fraction) == 12);
172 
173 /**
174  * Handle conversions from MSSQL 2008 DATE/TIME types to binary.
175  * These types have a different binary representation in libTDS.
176  */
177 static SQLLEN
179 {
180  TDS_INT len, cplen;
181  TDS_USMALLINT buf[10];
182  TDSDATEREC when;
183 
184  tds_datecrack(srctype, dta, &when);
185 
186  len = 0;
187  if (srctype != SYBMSTIME && srctype != SYBTIME && srctype != SYB5BIGTIME) {
188  buf[0] = when.year;
189  buf[1] = when.month + 1;
190  buf[2] = when.day;
191  len = 3;
192  }
193  if (srctype != SYBMSDATE && srctype != SYBDATE) {
194  buf[len++] = when.hour;
195  buf[len++] = when.minute;
196  buf[len++] = when.second;
197  if ((len % 2) != 0)
198  buf[len++] = 0;
199  *((TDS_UINT*) (buf+len)) = when.decimicrosecond * 100u;
200  len += 2;
201  }
202  if (srctype == SYBMSDATETIMEOFFSET) {
203  /* TODO check for negative hour/minutes */
204  buf[8] = dta->offset / 60;
205  buf[9] = dta->offset % 60;
206  len = 10;
207  }
208  len *= 2;
209 
210  /* just return length */
211  if (destlen == 0)
212  return len;
213 
214  cplen = (destlen > len) ? len : (TDS_INT) destlen;
215  memcpy(dest, buf, cplen);
216  if (curcol)
217  curcol->column_text_sqlgetdatapos += cplen;
218  return len;
219 }
220 
221 static SQLLEN
222 odbc_convert_to_binary(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TDS_UINT srclen, TDS_CHAR * dest, SQLULEN destlen)
223 {
224  SQLLEN ret = srclen;
225 
226  /* special case for date/time */
227  switch (srctype) {
228  case SYBMSTIME:
229  case SYBMSDATE:
230  case SYBMSDATETIME2:
231  case SYBMSDATETIMEOFFSET:
232  case SYBDATE:
233  case SYBTIME:
234  case SYB5BIGTIME:
235  case SYB5BIGDATETIME:
236  return odbc_convert_datetime_to_binary(stmt, curcol, srctype, (TDS_DATETIMEALL *) src, dest, destlen);
237  }
238 
239  /* if destlen == 0 we return only length */
240  if (destlen > 0) {
241  size_t cplen = (destlen > srclen) ? srclen : destlen;
242  /* do not NUL terminate binary buffer */
243  memcpy(dest, src, cplen);
244  if (curcol)
245  curcol->column_text_sqlgetdatapos += cplen;
246  }
247  return ret;
248 }
249 
250 SQLLEN
251 odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen,
252  const struct _drecord *drec_ixd)
253 {
254  TDS_INT nDestSybType;
255  TDS_INT nRetVal = TDS_CONVERT_FAIL;
256  TDSCONTEXT *context = stmt->dbc->env->tds_ctx;
257 
258  CONV_RESULT ores;
259 
260  SQLLEN ret = SQL_NULL_DATA;
261  int i;
262  SQLULEN cplen;
263  int binary_conversion = 0;
264  TDS_CHAR conv_buf[256];
265 
266  tdsdump_log(TDS_DBG_FUNC, "odbc_tds2sql: src is %d dest = %d\n", srctype, desttype);
267 
268  assert(desttype != SQL_C_DEFAULT);
269 
270  if (curcol) {
271  if (is_blob_col(curcol)) {
272  if (srctype == SYBLONGBINARY && (
273  curcol->column_usertype == USER_UNICHAR_TYPE ||
275  srctype = SYBTEXT;
276  if (curcol->column_type == SYBVARIANT)
277  srctype = ((TDSVARIANT *) src)->type;
278  src = ((TDSBLOB *) src)->textvalue;
279  }
280  if (is_variable_type(curcol->column_type)) {
281  src += curcol->column_text_sqlgetdatapos;
282  srclen -= curcol->column_text_sqlgetdatapos;
283  }
284  }
285 
286  nDestSybType = odbc_c_to_server_type(desttype);
287  if (!nDestSybType) {
288  odbc_errs_add(&stmt->errs, "HY003", NULL);
289  return SQL_NULL_DATA;
290  }
291 
292  /* special case for binary type */
293  if (desttype == SQL_C_BINARY) {
294  tdsdump_log(TDS_DBG_FUNC, "odbc_tds2sql: outputting binary data destlen = %lu \n", (unsigned long) destlen);
295 
296  if (is_numeric_type(srctype)) {
297  desttype = SQL_C_NUMERIC;
298  nDestSybType = SYBNUMERIC;
299  /* prevent buffer overflow */
300  if (destlen < sizeof(SQL_NUMERIC_STRUCT)) {
301  odbc_errs_add(&stmt->errs, "07006", NULL);
302  return SQL_NULL_DATA;
303  }
304  ores.n.precision = ((TDS_NUMERIC *) src)->precision;
305  ores.n.scale = ((TDS_NUMERIC *) src)->scale;
306  } else {
307  return odbc_convert_to_binary(stmt, curcol, srctype, src, srclen, dest, destlen);
308  }
309  } else if (is_numeric_type(nDestSybType)) {
310  /* TODO use descriptor information (APD) ?? However APD can contain SQL_C_DEFAULT... */
311  if (drec_ixd)
312  ores.n.precision
313  = (unsigned char) drec_ixd->sql_desc_precision;
314  else
315  ores.n.precision = 38;
316  ores.n.scale = 0;
317  }
318 
319  if (is_char_type(srctype)) {
320  if (desttype == SQL_C_CHAR || desttype == SQL_C_WCHAR)
321  return odbc_convert_char(stmt, curcol, src, srclen, desttype, dest, destlen);
322  if (is_unicode_type(srctype)) {
323  /*
324  * convert to single and then process normally.
325  * Here we processed SQL_C_BINARY and SQL_C_*CHAR so only fixed types are left
326  */
327  i = odbc_tds_convert_wide_iso(curcol, src, srclen, conv_buf, sizeof(conv_buf));
328  if (i < 0)
329  return SQL_NULL_DATA;
330  src = conv_buf;
331  srclen = i;
332  srctype = SYBVARCHAR;
333  }
334  }
335 
336  if (desttype == SQL_C_WCHAR)
337  destlen /= sizeof(SQLWCHAR);
338  if (desttype == SQL_C_CHAR || desttype == SQL_C_WCHAR) {
339  switch (srctype) {
340  case SYBLONGBINARY:
341  case SYBBINARY:
342  case SYBVARBINARY:
343  case SYBIMAGE:
344  case XSYBBINARY:
345  case XSYBVARBINARY:
346  binary_conversion = 1;
347  if (destlen && !(destlen % 2))
348  --destlen;
349  }
350 
351  nDestSybType = TDS_CONVERT_CHAR;
352  ores.cc.len = destlen;
353  ores.cc.c = dest;
354  }
355 
356  if (desttype == SQL_C_CHAR || desttype == SQL_C_WCHAR) {
357  char buf[48];
358  TDSDATEREC when;
359  int prec;
360  const char *fmt = NULL;
361  const TDS_DATETIMEALL *dta = (const TDS_DATETIMEALL *) src;
362 
363  switch (srctype) {
364  case SYBMSDATETIMEOFFSET:
365  case SYBMSDATETIME2:
366  prec = dta->time_prec;
367  goto datetime;
368  case SYB5BIGDATETIME:
369  prec = 6;
370  goto datetime;
371  case SYBDATETIME:
372  prec = 3;
373  goto datetime;
374  case SYBDATETIME4:
375  prec = 0;
376  datetime:
377  fmt = "%Y-%m-%d %H:%M:%S.%z";
378  break;
379  case SYBMSTIME:
380  prec = dta->time_prec;
381  goto time;
382  case SYB5BIGTIME:
383  prec = 6;
384  goto time;
385  case SYBTIME:
386  prec = 3;
387  time:
388  fmt = "%H:%M:%S.%z";
389  break;
390  case SYBMSDATE:
391  case SYBDATE:
392  prec = 0;
393  fmt = "%Y-%m-%d";
394  break;
395  }
396  if (!fmt) goto normal_conversion;
397 
398  tds_datecrack(srctype, src, &when);
399  tds_strftime(buf, sizeof(buf), fmt, &when, prec);
400 
401  if (srctype == SYBMSDATETIMEOFFSET) {
402  char sign = '+';
403  int off = dta->offset;
404  if (off < 0) {
405  sign = '-';
406  off = -off;
407  }
408  sprintf(buf + strlen(buf), " %c%02d:%02d", sign, off / 60, off % 60);
409  }
410 
411  nRetVal = (TDS_INT) strlen(buf);
412  memcpy(dest, buf,
413  destlen < (SQLULEN) nRetVal ? destlen : nRetVal);
414  } else {
415 normal_conversion:
416  nRetVal = tds_convert(context, srctype, src, srclen, nDestSybType, &ores);
417  }
418  if (nRetVal < 0) {
419  odbc_convert_err_set(&stmt->errs, nRetVal);
420  return SQL_NULL_DATA;
421  }
422 
423  switch (desttype) {
424 
425  case SQL_C_CHAR:
426  tdsdump_log(TDS_DBG_FUNC, "odbc_tds2sql: outputting character data destlen = %lu \n", (unsigned long) destlen);
427 
428  ret = nRetVal;
429  /* TODO handle not terminated configuration */
430  if (destlen > 0) {
431  cplen = (destlen - 1) > (SQLULEN) nRetVal
432  ? nRetVal : (destlen - 1);
433  assert(cplen >= 0);
434  /*
435  * odbc always terminate but do not overwrite
436  * destination buffer more than needed
437  */
438  /* update datapos only for binary source (char already handled) */
439  if (curcol && binary_conversion)
440  curcol->column_text_sqlgetdatapos += cplen / 2;
441  dest[cplen] = 0;
442  } else {
443  /* if destlen == 0 we return only length */
444  }
445  break;
446 
447  case SQL_C_WCHAR:
448  tdsdump_log(TDS_DBG_FUNC, "odbc_tds2sql: outputting character data destlen = %lu \n", (unsigned long) destlen);
449 
450  ret = nRetVal * sizeof(SQLWCHAR);
451  /* TODO handle not terminated configuration */
452  if (destlen > 0) {
453  SQLWCHAR *wp = (SQLWCHAR *) dest;
454  SQLCHAR *p = (SQLCHAR *) dest;
455 
456  cplen = (destlen - 1) > (SQLULEN) nRetVal
457  ? nRetVal : (destlen - 1);
458  assert(cplen >= 0);
459  /*
460  * odbc always terminate but do not overwrite
461  * destination buffer more than needed
462  */
463  /* update datapos only for binary source (char already handled) */
464  if (curcol && binary_conversion)
465  curcol->column_text_sqlgetdatapos += cplen / 2;
466  /* convert in place and terminate */
467  wp[cplen] = 0;
468  while (cplen > 0) {
469  --cplen;
470  wp[cplen] = p[cplen];
471  }
472  } else {
473  /* if destlen == 0 we return only length */
474  }
475  break;
476 
477  case SQL_C_TYPE_DATE:
478  case SQL_C_DATE:
479  {
480  TDSDATEREC dr;
481  DATE_STRUCT *dsp = (DATE_STRUCT *) dest;
482 
483  /*
484  * we've already converted the returned value to a SYBMSDATETIME2
485  * now decompose date into constituent parts...
486  */
487  tds_datecrack(SYBMSDATETIME2, &(ores.dt), &dr);
488 
489  dsp->year = dr.year;
490  dsp->month = dr.month + 1;
491  dsp->day = dr.day;
492 
493  ret = sizeof(DATE_STRUCT);
494  }
495  break;
496 
497  case SQL_C_TYPE_TIME:
498  case SQL_C_TIME:
499  {
500  TDSDATEREC dr;
501  TIME_STRUCT *tsp = (TIME_STRUCT *) dest;
502 
503  /*
504  * we've already converted the returned value to a SYBMSDATETIME2
505  * now decompose date into constituent parts...
506  */
507  tds_datecrack(SYBMSDATETIME2, &(ores.dt), &dr);
508 
509  tsp->hour = dr.hour;
510  tsp->minute = dr.minute;
511  tsp->second = dr.second;
512 
513  ret = sizeof(TIME_STRUCT);
514  }
515  break;
516 
518  case SQL_C_TIMESTAMP:
519  {
520  TDSDATEREC dr;
521  TIMESTAMP_STRUCT *tssp = (TIMESTAMP_STRUCT *) dest;
522 
523  /*
524  * we've already converted the returned value to a SYBMSDATETIME2
525  * now decompose date into constituent parts...
526  */
527  tds_datecrack(SYBMSDATETIME2, &(ores.dt), &dr);
528 
529  tssp->year = dr.year;
530  tssp->month = dr.month + 1;
531  tssp->day = dr.day;
532  tssp->hour = dr.hour;
533  tssp->minute = dr.minute;
534  tssp->second = dr.second;
535  tssp->fraction = dr.decimicrosecond * 100u;
536 
537  ret = sizeof(TIMESTAMP_STRUCT);
538  }
539  break;
540 
541 #ifdef SQL_C_SBIGINT
542  case SQL_C_SBIGINT:
543  case SQL_C_UBIGINT:
544  *((TDS_INT8 *) dest) = ores.bi;
545  ret = sizeof(TDS_INT8);
546  break;
547 #endif
548 
549  case SQL_C_LONG:
550  case SQL_C_SLONG:
551  case SQL_C_ULONG:
552  *((TDS_INT *) dest) = ores.i;
553  ret = sizeof(TDS_INT);
554  break;
555 
556  case SQL_C_SHORT:
557  case SQL_C_SSHORT:
558  case SQL_C_USHORT:
559  *((TDS_SMALLINT *) dest) = ores.si;
560  ret = sizeof(TDS_SMALLINT);
561  break;
562 
563  case SQL_C_TINYINT:
564  case SQL_C_STINYINT:
565  case SQL_C_UTINYINT:
566  case SQL_C_BIT:
567  *((TDS_TINYINT *) dest) = ores.ti;
568  ret = sizeof(TDS_TINYINT);
569  break;
570 
571  case SQL_C_DOUBLE:
572  *((TDS_FLOAT *) dest) = ores.f;
573  ret = sizeof(TDS_FLOAT);
574  break;
575 
576  case SQL_C_FLOAT:
577  *((TDS_REAL *) dest) = ores.r;
578  ret = sizeof(TDS_REAL);
579  break;
580 
581  case SQL_C_NUMERIC:
582  {
583  /* ODBC numeric is quite different from TDS one ... */
584  SQL_NUMERIC_STRUCT *num = (SQL_NUMERIC_STRUCT *) dest;
585  num->precision = ores.n.precision;
586  num->scale = ores.n.scale;
587  num->sign = ores.n.array[0] ^ 1;
588  /*
589  * TODO can be greater than SQL_MAX_NUMERIC_LEN ??
590  * seeing Sybase manual wire support bigger numeric but currently
591  * DBs so not support such precision
592  */
594  memcpy(num->val, ores.n.array + 1, i);
595  tds_swap_bytes(num->val, i);
596  if (i < SQL_MAX_NUMERIC_LEN)
597  memset(num->val + i, 0, SQL_MAX_NUMERIC_LEN - i);
598  ret = sizeof(SQL_NUMERIC_STRUCT);
599  }
600  break;
601 
602 #ifdef SQL_C_GUID
603  case SQL_C_GUID:
604  memcpy(dest, &(ores.u), sizeof(TDS_UNIQUE));
605  ret = sizeof(TDS_UNIQUE);
606  break;
607 #endif
608 
609  default:
610  break;
611  }
612 
613  return ret;
614 }
static TDSICONV * conv
Definition: charconv.c:168
static TDSSOCKET * tds
Definition: collations.c:37
#define TDS_CONVERT_CHAR
Definition: convert.h:83
#define TDS_CONVERT_FAIL
Definition: convert.h:76
static int odbc_tds_convert_wide_iso(TDSCOLUMN *curcol, TDS_CHAR *src, TDS_UINT srclen, TDS_CHAR *buf, TDS_UINT buf_len)
Handle conversions from TDS NCHAR to ISO8859-1 striping spaces (for fixed types)
TDS_COMPILE_CHECK(ss_time2, sizeof(SQL_SS_TIME2_STRUCT)==12 &&TDS_OFFSET(SQL_SS_TIME2_STRUCT, fraction)==8)
static SQLLEN odbc_convert_char(TDS_STMT *stmt, TDSCOLUMN *curcol, TDS_CHAR *src, TDS_UINT srclen, int desttype, TDS_CHAR *dest, SQLULEN destlen)
Handle conversions from TDS (N)CHAR to ODBC (W)CHAR.
static SQLLEN odbc_convert_datetime_to_binary(TDS_STMT *stmt, TDSCOLUMN *curcol, int srctype, TDS_DATETIMEALL *dta, TDS_CHAR *dest, SQLULEN destlen)
Handle conversions from MSSQL 2008 DATE/TIME types to binary.
#define TDS_ISSPACE(c)
SQLLEN odbc_tds2sql(TDS_STMT *stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR *src, TDS_UINT srclen, int desttype, TDS_CHAR *dest, SQLULEN destlen, const struct _drecord *drec_ixd)
static SQLLEN odbc_convert_to_binary(TDS_STMT *stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR *src, TDS_UINT srclen, TDS_CHAR *dest, SQLULEN destlen)
#define NULL
Definition: ncbistd.hpp:225
static const char * tds_dstr_cstr(DSTR *s)
Returns a C version (NUL terminated string) of dstr.
Definition: string.h:66
TDS_SERVER_TYPE odbc_c_to_server_type(int c_type)
Pass this an SQL_C_* type and get a SYB* type which most closely corresponds to the SQL_C_* type.
Definition: odbc_util.c:605
void odbc_convert_err_set(struct _sql_errors *errs, TDS_INT err)
Definition: odbc_util.c:1175
@ to_client
Definition: iconv.h:70
#define TDS_ENCODING_MEMCPY
Definition: iconv.h:95
char * buf
int i
int len
#define SIZEOF_SQLWCHAR
Definition: ncbiconf_msvc.h:48
#define SQLULEN
Definition: odbc.h:49
void odbc_errs_add(struct _sql_errors *errs, const char *sqlstate, const char *msg)
add an error to list
Definition: error.c:382
#define SQLLEN
Definition: odbc.h:52
#define ODBC_MIN(a, b)
Definition: odbc.h:92
@ SYBVARIANT
Definition: proto.h:200
@ SYBLONGBINARY
Definition: proto.h:211
@ XSYBVARBINARY
Definition: proto.h:197
@ SYB5BIGTIME
Definition: proto.h:231
@ XSYBBINARY
Definition: proto.h:198
@ SYB5BIGDATETIME
Definition: proto.h:230
struct tdsunique TDS_UNIQUE
@ USER_UNICHAR_TYPE
Definition: proto.h:237
@ USER_UNIVARCHAR_TYPE
Definition: proto.h:238
static HSTMT stmt
Definition: rebindpar.c:12
#define tds_iconv
#define tds_strftime
#define tds_swap_bytes
#define tds_numeric_bytes_per_prec
#define tds_datecrack
#define tds_iconv_get
#define tds_convert
#define SQL_NULL_DATA
Definition: sql.h:29
#define SQL_C_DOUBLE
Definition: sqlext.h:515
#define SQL_C_TYPE_TIMESTAMP
Definition: sqlext.h:531
#define SQL_C_TYPE_DATE
Definition: sqlext.h:529
#define SQL_C_ULONG
Definition: sqlext.h:556
#define SQL_C_TINYINT
Definition: sqlext.h:552
#define SQL_C_SLONG
Definition: sqlext.h:553
#define SQL_C_GUID
Definition: sqlext.h:567
#define SQL_C_TYPE_TIME
Definition: sqlext.h:530
#define SQL_C_BINARY
Definition: sqlext.h:546
#define SQL_C_DEFAULT
Definition: sqlext.h:519
#define SQL_C_SHORT
Definition: sqlext.h:513
#define SQL_C_LONG
Definition: sqlext.h:512
#define SQL_C_STINYINT
Definition: sqlext.h:555
#define SQL_C_TIME
Definition: sqlext.h:526
#define SQL_C_FLOAT
Definition: sqlext.h:514
#define SQL_C_SSHORT
Definition: sqlext.h:554
#define SQL_C_BIT
Definition: sqlext.h:547
#define SQL_C_UBIGINT
Definition: sqlext.h:550
#define SQL_C_UTINYINT
Definition: sqlext.h:558
#define SQL_NO_TOTAL
Definition: sqlext.h:671
#define SQL_C_DATE
Definition: sqlext.h:525
#define SQL_C_USHORT
Definition: sqlext.h:557
#define SQL_C_SBIGINT
Definition: sqlext.h:549
#define SQL_C_TIMESTAMP
Definition: sqlext.h:527
#define SQL_C_NUMERIC
Definition: sqlext.h:517
#define SQL_C_CHAR
Definition: sqlext.h:511
struct tagSQL_NUMERIC_STRUCT SQL_NUMERIC_STRUCT
struct tagDATE_STRUCT DATE_STRUCT
WCHAR SQLWCHAR
Definition: sqltypes.h:458
struct tagTIMESTAMP_STRUCT TIMESTAMP_STRUCT
struct tagTIME_STRUCT TIME_STRUCT
unsigned char SQLCHAR
Definition: sqltypes.h:125
#define SQL_MAX_NUMERIC_LEN
Definition: sqltypes.h:422
#define SQL_C_WCHAR
Definition: sqlucode.h:17
#define assert(x)
Definition: srv_diag.hpp:58
this structure is not directed connected to a TDS protocol but keeps any DATE/TIME information.
Definition: tds.h:167
TDS_SMALLINT offset
time offset
Definition: tds.h:170
TDS_USMALLINT time_prec
Definition: tds.h:171
Definition: odbc.h:164
SQLSMALLINT sql_desc_precision
Definition: odbc.h:190
Definition: odbc.h:390
TDS_UINT len
Definition: convert.h:64
TDS_CHAR * c
Definition: convert.h:63
SQLSMALLINT year
Definition: sqltypes.h:284
SQLUSMALLINT day
Definition: sqltypes.h:286
SQLUSMALLINT month
Definition: sqltypes.h:285
SQLCHAR val[16]
Definition: sqltypes.h:428
SQLUSMALLINT hour
Definition: sqltypes.h:309
SQLUINTEGER fraction
Definition: sqltypes.h:312
SQLUSMALLINT second
Definition: sqltypes.h:311
SQLSMALLINT year
Definition: sqltypes.h:306
SQLUSMALLINT month
Definition: sqltypes.h:307
SQLUSMALLINT day
Definition: sqltypes.h:308
SQLUSMALLINT minute
Definition: sqltypes.h:310
SQLUSMALLINT hour
Definition: sqltypes.h:295
SQLUSMALLINT minute
Definition: sqltypes.h:296
SQLUSMALLINT second
Definition: sqltypes.h:297
Information about blobs (e.g.
Definition: tds.h:658
Metadata about columns in regular and compute rows.
Definition: tds.h:761
TDS_SERVER_TYPE column_type
This type can be different from wire type because conversion (e.g.
Definition: tds.h:768
TDSICONV * char_conv
refers to previously allocated iconv information
Definition: tds.h:784
TDS_INT column_usertype
Definition: tds.h:763
TDS_INT column_text_sqlgetdatapos
Definition: tds.h:822
TDSICONV ** char_convs
Definition: tds.h:1161
unsigned char max_bytes_per_char
Definition: tds.h:687
unsigned char min_bytes_per_char
Definition: tds.h:686
unsigned int e2big
Definition: iconv.h:79
Information for a server connection.
Definition: tds.h:1211
TDSCONNECTION conn[1]
Definition: tds.h:1215
Store variant informations.
Definition: tds.h:669
Used by tds_datecrack.
Definition: tds.h:180
TDS_INT year
year
Definition: tds.h:181
TDS_INT minute
0-59
Definition: tds.h:188
TDS_INT day
day of month (1-31)
Definition: tds.h:184
TDS_INT decimicrosecond
0-9999999
Definition: tds.h:190
TDS_INT second
0-59
Definition: tds.h:189
TDS_INT hour
0-23
Definition: tds.h:187
TDS_INT month
month number (0-11)
Definition: tds.h:183
TDS_ENCODING charset
Definition: iconv.h:86
unsigned int flags
Definition: iconv.h:96
struct tdsiconvdir to from
Definition: iconv.h:93
TDS_ERRNO_MESSAGE_FLAGS suppress
Definition: iconv.h:106
unsigned char scale
Definition: proto.h:28
unsigned char precision
Definition: proto.h:27
unsigned char array[33]
Definition: proto.h:29
#define SYBMSDATE
Definition: sybdb.h:222
#define SYBNUMERIC
Definition: sybdb.h:202
#define SYBVARCHAR
Definition: sybdb.h:162
#define SYBTEXT
Definition: sybdb.h:182
#define SYBDATE
Definition: sybdb.h:214
#define SYBMSDATETIME2
Definition: sybdb.h:226
#define SYBIMAGE
Definition: sybdb.h:186
#define SYBMSDATETIMEOFFSET
Definition: sybdb.h:228
#define SYBDATETIME4
Definition: sybdb.h:192
#define SYBBINARY
Definition: sybdb.h:196
#define SYBTIME
Definition: sybdb.h:216
#define SYBMSTIME
Definition: sybdb.h:224
#define SYBDATETIME
Definition: sybdb.h:176
#define SYBVARBINARY
Definition: sybdb.h:200
#define is_numeric_type(x)
Definition: tds.h:454
#define TDS_OFFSET(str, field)
Definition: tds.h:364
tds_sysdep_int32_type TDS_INT
Definition: tds.h:149
#define is_variable_type(x)
Definition: tds.h:440
@ client2server_chardata
Definition: tds.h:1110
#define tdsdump_log
Definition: tds.h:1561
tds_sysdep_real64_type TDS_FLOAT
Definition: tds.h:152
tds_sysdep_int64_type TDS_INT8
Definition: tds.h:153
#define is_unicode_type(x)
Definition: tds.h:457
#define is_blob_col(x)
Definition: tds.h:445
tds_sysdep_real32_type TDS_REAL
Definition: tds.h:151
unsigned char TDS_TINYINT
Definition: tds.h:146
tds_sysdep_int16_type TDS_SMALLINT
Definition: tds.h:147
#define is_char_type(x)
Definition: tds.h:460
char TDS_CHAR
Definition: tds.h:144
tds_sysdep_uint16_type TDS_USMALLINT
Definition: tds.h:148
tds_sysdep_uint32_type TDS_UINT
Definition: tds.h:150
#define TDS_DBG_FUNC
Definition: tds.h:898
TDS_TINYINT ti
Definition: convert.h:36
TDS_DATETIME dt
Definition: convert.h:47
TDS_SMALLINT si
Definition: convert.h:37
TDS_INT i
Definition: convert.h:39
TDS_NUMERIC n
Definition: convert.h:54
TDS_UNIQUE u
Definition: convert.h:55
struct conv_result::cc_t cc
TDS_INT8 bi
Definition: convert.h:41
TDS_REAL r
Definition: convert.h:44
TDS_FLOAT f
Definition: convert.h:43
Modified on Tue Apr 09 07:57:24 2024 by modify_doxy.py rev. 669887
Modified on Wed Apr 10 07:32:48 2024 by modify_doxy.py rev. 669887
Modified on Thu Apr 11 15:05:34 2024 by modify_doxy.py rev. 669887
Modified on Fri Apr 12 17:17:48 2024 by modify_doxy.py rev. 669887
Modified on Sat Apr 13 11:45:48 2024 by modify_doxy.py rev. 669887
Modified on Sun Apr 14 05:26:14 2024 by modify_doxy.py rev. 669887