Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : /*
14 : * This code was created by Peter Harvey (mostly during Christmas 98/99).
15 : * This code is LGPL. Please ensure that this message remains in future
16 : * distributions and uses of this code (thats about all I get out of it).
17 : * - Peter Harvey pharvey@codebydesign.com
18 : *
19 : * This file has been modified for the MonetDB project. See the file
20 : * Copyright in this directory for more information.
21 : */
22 :
23 : /**********************************************
24 : * ODBCUtil.c
25 : *
26 : * Description:
27 : * This file contains utility functions for
28 : * the ODBC driver implementation.
29 : *
30 : * Author: Martin van Dinther, Sjoerd Mullender
31 : * Date : 30 aug 2002
32 : *
33 : **********************************************/
34 :
35 : #include "ODBCUtil.h"
36 : #include "ODBCDbc.h"
37 : #include <float.h>
38 :
39 :
40 : #ifdef WIN32
41 : /* Windows seems to need this */
42 : BOOL WINAPI
43 : DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved)
44 : {
45 : #ifdef ODBCDEBUG
46 : ODBCLOG("DllMain %ld (MonetDB %s)\n", (long) reason, MONETDB_VERSION);
47 : #endif
48 : (void) hinstDLL;
49 : (void) reason;
50 : (void) reserved;
51 :
52 : return TRUE;
53 : }
54 : #endif
55 :
56 : /*
57 : * Utility function to duplicate an ODBC string (with a length
58 : * specified, may not be null terminated) to a normal C string (null
59 : * terminated).
60 : *
61 : * Precondition: inStr != NULL
62 : * Postcondition: returns a newly allocated null terminated string.
63 : */
64 : char *
65 1029 : dupODBCstring(const SQLCHAR *inStr, size_t length)
66 : {
67 1029 : char *tmp = (char *) malloc((length + 1) * sizeof(char));
68 :
69 1029 : if (tmp == NULL)
70 : return NULL;
71 1029 : strcpy_len(tmp, (const char *) inStr, length + 1);
72 1029 : return tmp;
73 : }
74 :
75 : /* Convert a SQLWCHAR (UTF-16 encoded string) to UTF-8. On success,
76 : clears the location pointed to by errmsg and returns NULL or a
77 : newly allocated buffer. On error, assigns a string with an error
78 : message to the location pointed to by errmsg and returns NULL.
79 : The first two arguments describe the input string in the normal
80 : ODBC fashion.
81 : */
82 : SQLCHAR *
83 4 : ODBCwchar2utf8(const SQLWCHAR *src, SQLLEN length, const char **errmsg)
84 : {
85 4 : size_t i = 0;
86 4 : SQLLEN j = 0;
87 4 : uint32_t c;
88 4 : SQLCHAR *dest;
89 :
90 4 : if (errmsg)
91 4 : *errmsg = NULL;
92 4 : if (src == NULL || length == SQL_NULL_DATA)
93 : return NULL;
94 4 : if (length == SQL_NTS) {
95 : /* a very large (positive) number that fits in SQLLEN */
96 : length = (SQLLEN) (~(SQLULEN)0 >> 1);
97 3 : } else if (length < 0) {
98 0 : if (errmsg)
99 0 : *errmsg = "Invalid length parameter";
100 0 : return NULL;
101 : }
102 4 : if (src[j] == 0xFEFF)
103 0 : j++;
104 94 : while (j < length && src[j]) {
105 90 : if (src[j] <= 0x7F) {
106 90 : i += 1;
107 0 : } else if (src[j] <= 0x7FF) {
108 0 : i += 2;
109 0 : } else if (
110 : #if SIZEOF_SQLWCHAR == 2
111 : (src[j] & 0xFC00) != 0xD800
112 : #else
113 : src[j] <= 0xFFFF
114 : #endif
115 : ) {
116 0 : if ((src[j] & 0xF800) == 0xD800) {
117 0 : if (errmsg)
118 0 : *errmsg = "Illegal surrogate";
119 0 : return NULL;
120 : }
121 0 : i += 3;
122 : } else {
123 : #if SIZEOF_SQLWCHAR == 2
124 : /* (src[j] & 0xFC00) == 0xD800, i.e. high surrogate */
125 0 : if ((src[j+1] & 0xFC00) != 0xDC00) {
126 0 : if (errmsg)
127 0 : *errmsg = "Illegal surrogate";
128 0 : return NULL;
129 : }
130 0 : j++;
131 : #else
132 : c = src[j+0];
133 : if (c > 0x10FFFF || (c & 0x1FF800) == 0xD800) {
134 : if (errmsg)
135 : *errmsg = "Illegal wide character value";
136 : return NULL;
137 : }
138 : #endif
139 0 : i += 4;
140 : }
141 90 : j++;
142 : }
143 4 : length = j; /* figured out the real length (might not change) */
144 4 : dest = malloc((i + 1) * sizeof(SQLCHAR));
145 4 : if (dest == NULL)
146 : return NULL;
147 : i = 0;
148 : j = 0;
149 : if (src[j] == 0xFEFF)
150 : j++;
151 94 : while (j < length) {
152 90 : if (src[j] <= 0x7F) {
153 90 : dest[i++] = (SQLCHAR) src[j];
154 0 : } else if (src[j] <= 0x7FF) {
155 0 : dest[i++] = 0xC0 | (src[j] >> 6);
156 0 : dest[i++] = 0x80 | (src[j] & 0x3F);
157 0 : } else if (
158 : #if SIZEOF_SQLWCHAR == 2
159 : (src[j] & 0xFC00) != 0xD800
160 : #else
161 : src[j] <= 0xFFFF
162 : #endif
163 : ) {
164 0 : dest[i++] = 0xE0 | (src[j] >> 12);
165 0 : dest[i++] = 0x80 | ((src[j] >> 6) & 0x3F);
166 0 : dest[i++] = 0x80 | (src[j] & 0x3F);
167 : } else {
168 : #if SIZEOF_SQLWCHAR == 2
169 0 : c = ((src[j+0] & 0x03FF) + 0x40) << 10
170 0 : | (src[j+1] & 0x03FF);
171 0 : j++;
172 : #else
173 : c = src[j+0];
174 : #endif
175 0 : dest[i++] = 0xF0 | (c >> 18);
176 0 : dest[i++] = 0x80 | ((c >> 12) & 0x3F);
177 0 : dest[i++] = 0x80 | ((c >> 6) & 0x3F);
178 0 : dest[i++] = 0x80 | (c & 0x3F);
179 : }
180 90 : j++;
181 : }
182 4 : dest[i] = 0;
183 4 : return dest;
184 : }
185 :
186 : /* Convert a UTF-8 encoded string to UTF-16 (SQLWCHAR). On success
187 : returns NULL, on error returns a string with an error message. The
188 : first two arguments describe the input, the next three arguments
189 : describe the output, both in the normal ODBC fashion.
190 : The last argument is the count of the number of input bytes
191 : actually converted to the output. */
192 : const char *
193 464 : ODBCutf82wchar(const SQLCHAR *src,
194 : SQLINTEGER length,
195 : SQLWCHAR *buf,
196 : SQLLEN buflen,
197 : SQLSMALLINT *buflenout,
198 : size_t *consumed)
199 : {
200 464 : SQLLEN i = 0;
201 464 : SQLINTEGER j = 0;
202 464 : uint32_t c;
203 :
204 464 : if (buf == NULL)
205 : buflen = 0;
206 463 : else if (buflen == 0)
207 1 : buf = NULL;
208 :
209 464 : if (src == NULL || length == SQL_NULL_DATA) {
210 0 : if (buflen > 0)
211 0 : buf[0] = 0;
212 0 : if (buflenout)
213 0 : *buflenout = 0;
214 0 : if (consumed)
215 0 : *consumed = 0;
216 0 : return NULL;
217 : }
218 464 : if (length == SQL_NTS)
219 464 : length = (SQLINTEGER) (~(SQLUINTEGER)0 >> 1);
220 76 : else if (length < 0)
221 : return "Invalid length parameter";
222 :
223 67684 : while (j < length && i + 1 < buflen && src[j]) {
224 67220 : if ((src[j+0] & 0x80) == 0) {
225 67220 : buf[i++] = src[j+0];
226 67220 : j += 1;
227 0 : } else if (j + 1 < length
228 0 : && (src[j+0] & 0xE0) == 0xC0
229 0 : && (src[j+1] & 0xC0) == 0x80
230 0 : && (src[j+0] & 0x1E) != 0) {
231 0 : buf[i++] = (src[j+0] & 0x1F) << 6
232 0 : | (src[j+1] & 0x3F);
233 0 : j += 2;
234 0 : } else if (j + 2 < length
235 0 : && (src[j+0] & 0xF0) == 0xE0
236 0 : && (src[j+1] & 0xC0) == 0x80
237 0 : && (src[j+2] & 0xC0) == 0x80
238 0 : && ((src[j+0] & 0x0F) != 0
239 0 : || (src[j+1] & 0x20) != 0)) {
240 0 : buf[i++] = (src[j+0] & 0x0F) << 12
241 0 : | (src[j+1] & 0x3F) << 6
242 0 : | (src[j+2] & 0x3F);
243 0 : j += 3;
244 0 : } else if (j + 3 < length
245 0 : && (src[j+0] & 0xF8) == 0xF0
246 0 : && (src[j+1] & 0xC0) == 0x80
247 0 : && (src[j+2] & 0xC0) == 0x80
248 0 : && (src[j+3] & 0xC0) == 0x80
249 0 : && ((src[j+0] & 0x07) != 0
250 0 : || (src[j+1] & 0x30) != 0)) {
251 0 : c = (src[j+0] & 0x07) << 18
252 0 : | (src[j+1] & 0x3F) << 12
253 0 : | (src[j+2] & 0x3F) << 6
254 0 : | (src[j+3] & 0x3F);
255 0 : if (c > 0x10FFFF || (c & 0x1FF800) == 0x00D800)
256 : return "Illegal code point";
257 : #if SIZEOF_SQLWCHAR == 2
258 0 : if (i + 2 >= buflen)
259 : break;
260 0 : buf[i++] = 0xD800 | ((c - 0x10000) >> 10);
261 0 : buf[i++] = 0xDC00 | (c & 0x3FF);
262 : #else
263 : buf[i++] = c;
264 : #endif
265 0 : j += 4;
266 : } else {
267 : return "Illegal code point";
268 : }
269 : }
270 464 : if (buflen > 0)
271 463 : buf[i] = 0;
272 464 : if (consumed)
273 388 : *consumed = (size_t) j;
274 11301 : while (j < length && src[j]) {
275 10837 : i++;
276 10837 : if ((src[j+0] & 0x80) == 0) {
277 10837 : j += 1;
278 0 : } else if (j + 1 < length
279 0 : && (src[j+0] & 0xE0) == 0xC0
280 0 : && (src[j+1] & 0xC0) == 0x80
281 0 : && (src[j+0] & 0x1E) != 0) {
282 0 : j += 2;
283 0 : } else if (j + 2 < length
284 0 : && (src[j+0] & 0xF0) == 0xE0
285 0 : && (src[j+1] & 0xC0) == 0x80
286 0 : && (src[j+2] & 0xC0) == 0x80
287 0 : && ((src[j+0] & 0x0F) != 0
288 0 : || (src[j+1] & 0x20) != 0)) {
289 0 : j += 3;
290 0 : } else if (j + 3 < length
291 0 : && (src[j+0] & 0xF8) == 0xF0
292 0 : && (src[j+1] & 0xC0) == 0x80
293 0 : && (src[j+2] & 0xC0) == 0x80
294 0 : && (src[j+3] & 0xC0) == 0x80
295 0 : && ((src[j+0] & 0x07) != 0
296 0 : || (src[j+1] & 0x30) != 0)) {
297 0 : c = (src[j+0] & 0x07) << 18
298 0 : | (src[j+1] & 0x3F) << 12
299 0 : | (src[j+2] & 0x3F) << 6
300 0 : | (src[j+3] & 0x3F);
301 0 : if (c > 0x10FFFF || (c & 0x1FF800) == 0x00D800)
302 : return "Illegal code point";
303 : #if SIZEOF_SQLWCHAR == 2
304 0 : i++;
305 : #endif
306 0 : j += 4;
307 : } else {
308 : return "Illegal code point";
309 : }
310 : }
311 464 : if (buflenout)
312 448 : *buflenout = (SQLSMALLINT) i;
313 : return NULL;
314 : }
315 :
316 : /*
317 : * Translate an ODBC-compatible query to one that the SQL server
318 : * understands.
319 : *
320 : * Precondition: query != NULL
321 : * Postcondition: returns a newly allocated null terminated string.
322 : */
323 : /*
324 : Escape sequences:
325 : {d 'yyyy-mm-dd'}
326 : {t 'hh:mm:ss'}
327 : {ts 'yyyy-mm-dd hh:mm:ss[.f...]'}
328 : {interval ...}
329 : {guid 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'}
330 : {fn scalar-function}
331 : {escape 'escape-character'}
332 : {oj outer-join}
333 : where outer-join is:
334 : table-reference {LEFT|RIGHT|FULL} OUTER JOIN
335 : {table-reference | outer-join} ON search condition
336 : {[?=]call procedure-name[([parameter][,[parameter]]...)]}
337 : */
338 :
339 : static struct scalars {
340 : const char *name;
341 : int nargs;
342 : const char *repl;
343 : } scalars[] = {
344 : {
345 : .name = "abs",
346 : .nargs = 1,
347 : .repl = "sys.\"abs\"",
348 : },
349 : {
350 : .name = "acos",
351 : .nargs = 1,
352 : .repl = "sys.\"acos\"",
353 : },
354 : {
355 : .name = "ascii",
356 : .nargs = 1,
357 : .repl = "sys.\"ascii\"",
358 : },
359 : {
360 : .name = "asin",
361 : .nargs = 1,
362 : .repl = "sys.\"asin\"",
363 : },
364 : {
365 : .name = "atan",
366 : .nargs = 1,
367 : .repl = "sys.\"atan\"",
368 : },
369 : {
370 : .name = "atan2",
371 : .nargs = 2,
372 : .repl = "sys.\"atan\"", /* note: not atan2 */
373 : },
374 : {
375 : .name = "bit_length",
376 : .nargs = 1,
377 : .repl = NULL,
378 : },
379 : {
380 : .name = "ceiling",
381 : .nargs = 1,
382 : .repl = "sys.\"ceiling\"",
383 : },
384 : {
385 : .name = "char",
386 : .nargs = 1,
387 : .repl = "sys.\"code\"",
388 : },
389 : {
390 : .name = "character_length",
391 : .nargs = 1,
392 : .repl = "sys.\"character_length\"",
393 : },
394 : {
395 : .name = "char_length",
396 : .nargs = 1,
397 : .repl = "sys.\"char_length\"",
398 : },
399 : {
400 : .name = "concat",
401 : .nargs = 2,
402 : .repl = "sys.\"concat\"",
403 : },
404 : {
405 : /* second argument is an ODBC type name that also gets
406 : * translated. Note: convert is implemented in the
407 : * parser */
408 : .name = "convert",
409 : .nargs = 2,
410 : .repl = NULL,
411 : },
412 : {
413 : .name = "cos",
414 : .nargs = 1,
415 : .repl = "sys.\"cos\"",
416 : },
417 : {
418 : .name = "cot",
419 : .nargs = 1,
420 : .repl = "sys.\"cot\"",
421 : },
422 : {
423 : .name = "curdate",
424 : .nargs = 0,
425 : .repl = "sys.\"curdate\"",
426 : },
427 : {
428 : .name = "current_date",
429 : .nargs = 0,
430 : .repl = "sys.\"current_date\"",
431 : },
432 : {
433 : .name = "current_time",
434 : .nargs = 0,
435 : .repl = "sys.\"current_time\"",
436 : },
437 : {
438 : .name = "current_time",
439 : .nargs = 1,
440 : .repl = NULL,
441 : },
442 : {
443 : .name = "current_timestamp",
444 : .nargs = 0,
445 : .repl = "sys.\"current_timestamp\"",
446 : },
447 : {
448 : .name = "current_timestamp",
449 : .nargs = 1,
450 : .repl = NULL,
451 : },
452 : {
453 : .name = "curtime",
454 : .nargs = 0,
455 : .repl = "sys.\"curtime\"",
456 : },
457 : {
458 : .name = "database",
459 : .nargs = 0,
460 : .repl = NULL,
461 : },
462 : {
463 : .name = "dayname",
464 : .nargs = 1,
465 : .repl = NULL,
466 : },
467 : {
468 : .name = "dayofmonth",
469 : .nargs = 1,
470 : .repl = "sys.\"dayofmonth\"",
471 : },
472 : {
473 : .name = "dayofweek",
474 : .nargs = 1,
475 : .repl = "sys.\"dayofweek\"",
476 : },
477 : {
478 : .name = "dayofyear",
479 : .nargs = 1,
480 : .repl = "sys.\"dayofyear\"",
481 : },
482 : {
483 : .name = "degrees",
484 : .nargs = 1,
485 : .repl = "sys.\"degrees\"",
486 : },
487 : {
488 : .name = "difference",
489 : .nargs = 2,
490 : .repl = "sys.\"difference\"",
491 : },
492 : {
493 : .name = "exp",
494 : .nargs = 1,
495 : .repl = "sys.\"exp\"",
496 : },
497 : {
498 : .name = "extract",
499 : .nargs = 1,
500 : .repl = "EXTRACT", /* include "X FROM " in argument */
501 : },
502 : {
503 : .name = "floor",
504 : .nargs = 1,
505 : .repl = "sys.\"floor\"",
506 : },
507 : {
508 : .name = "hour",
509 : .nargs = 1,
510 : .repl = "sys.\"hour\"",
511 : },
512 : {
513 : .name = "ifnull",
514 : .nargs = 2,
515 : .repl = "sys.\"coalesce\"",
516 : },
517 : {
518 : .name = "insert",
519 : .nargs = 4,
520 : .repl = "sys.\"insert\"",
521 : },
522 : {
523 : .name = "lcase",
524 : .nargs = 1,
525 : .repl = "sys.\"lcase\"",
526 : },
527 : {
528 : .name = "left",
529 : .nargs = 2,
530 : .repl = "sys.\"left\"",
531 : },
532 : {
533 : .name = "length",
534 : .nargs = 1,
535 : .repl = "sys.\"length\"",
536 : },
537 : {
538 : .name = "locate",
539 : .nargs = 2,
540 : .repl = "sys.\"locate\"",
541 : },
542 : {
543 : .name = "locate",
544 : .nargs = 3,
545 : .repl = "sys.\"locate\"",
546 : },
547 : {
548 : .name = "log10",
549 : .nargs = 1,
550 : .repl = "sys.\"log10\"",
551 : },
552 : {
553 : .name = "log",
554 : .nargs = 1,
555 : .repl = "sys.\"log\"",
556 : },
557 : {
558 : .name = "ltrim",
559 : .nargs = 1,
560 : .repl = "sys.\"ltrim\"",
561 : },
562 : {
563 : .name = "minute",
564 : .nargs = 1,
565 : .repl = "sys.\"minute\"",
566 : },
567 : {
568 : .name = "mod",
569 : .nargs = 2,
570 : .repl = "sys.\"mod\"",
571 : },
572 : {
573 : .name = "month",
574 : .nargs = 1,
575 : .repl = "sys.\"month\"",
576 : },
577 : {
578 : .name = "monthname",
579 : .nargs = 1,
580 : .repl = NULL,
581 : },
582 : {
583 : .name = "now",
584 : .nargs = 0,
585 : .repl = "sys.\"now\"",
586 : },
587 : {
588 : .name = "octet_length",
589 : .nargs = 1,
590 : .repl = "sys.\"octet_length\"",
591 : },
592 : {
593 : .name = "pi",
594 : .nargs = 0,
595 : .repl = "sys.\"pi\"",
596 : },
597 : {
598 : .name = "position",
599 : .nargs = 1,
600 : /* includes " IN str" in first argument. Note:
601 : * POSITION is implemented in the parser. */
602 : .repl = "position",
603 : },
604 : {
605 : .name = "power",
606 : .nargs = 2,
607 : .repl = "sys.\"power\"",
608 : },
609 : {
610 : .name = "quarter",
611 : .nargs = 1,
612 : .repl = "sys.\"quarter\"",
613 : },
614 : {
615 : .name = "radians",
616 : .nargs = 1,
617 : .repl = "sys.\"radians\"",
618 : },
619 : {
620 : .name = "rand",
621 : .nargs = 0,
622 : .repl = "sys.\"rand\"",
623 : },
624 : {
625 : .name = "rand",
626 : .nargs = 1,
627 : .repl = "sys.\"rand\"",
628 : },
629 : {
630 : .name = "repeat",
631 : .nargs = 2,
632 : .repl = "sys.\"repeat\"",
633 : },
634 : {
635 : .name = "replace",
636 : .nargs = 3,
637 : .repl = "sys.\"replace\"",
638 : },
639 : {
640 : .name = "right",
641 : .nargs = 2,
642 : .repl = "sys.\"right\"",
643 : },
644 : {
645 : .name = "round",
646 : .nargs = 2,
647 : .repl = "sys.\"round\"",
648 : },
649 : {
650 : .name = "rtrim",
651 : .nargs = 1,
652 : .repl = "sys.\"rtrim\"",
653 : },
654 : {
655 : .name = "second",
656 : .nargs = 1,
657 : .repl = "sys.\"second\"",
658 : },
659 : {
660 : .name = "sign",
661 : .nargs = 1,
662 : .repl = "sys.\"sign\"",
663 : },
664 : {
665 : .name = "sin",
666 : .nargs = 1,
667 : .repl = "sys.\"sin\"",
668 : },
669 : {
670 : .name = "soundex",
671 : .nargs = 1,
672 : .repl = "sys.\"soundex\"",
673 : },
674 : {
675 : .name = "space",
676 : .nargs = 1,
677 : .repl = "sys.\"space\"",
678 : },
679 : {
680 : .name = "sqrt",
681 : .nargs = 1,
682 : .repl = "sys.\"sqrt\"",
683 : },
684 : {
685 : .name = "substring",
686 : .nargs = 3,
687 : .repl = "sys.\"substring\"",
688 : },
689 : {
690 : .name = "tan",
691 : .nargs = 1,
692 : .repl = "sys.\"tan\"",
693 : },
694 : {
695 : .name = "timestampadd",
696 : .nargs = 3,
697 : .repl = NULL,
698 : },
699 : {
700 : .name = "timestampdiff",
701 : .nargs = 3,
702 : .repl = NULL,
703 : },
704 : {
705 : .name = "truncate",
706 : .nargs = 2,
707 : .repl = "sys.\"ms_trunc\"",
708 : },
709 : {
710 : .name = "ucase",
711 : .nargs = 1,
712 : .repl = "sys.\"ucase\"",
713 : },
714 : {
715 : .name = "user",
716 : .nargs = 0,
717 : .repl = NULL,
718 : },
719 : {
720 : .name = "week",
721 : .nargs = 1,
722 : .repl = "sys.\"week\"",
723 : },
724 : {
725 : .name = "year",
726 : .nargs = 1,
727 : .repl = "sys.\"year\"",
728 : },
729 : {
730 : 0 /* sentinel */
731 : },
732 : };
733 :
734 : static struct convert {
735 : const char *odbc;
736 : const char *server;
737 : } convert[] = {
738 : {
739 : .odbc = "SQL_BIGINT",
740 : .server = "bigint",
741 : },
742 : {
743 : .odbc = "SQL_BINARY",
744 : .server = "binary large object",
745 : },
746 : {
747 : .odbc = "SQL_BIT",
748 : .server = "boolean",
749 : },
750 : {
751 : .odbc = "SQL_CHAR",
752 : .server = "character",
753 : },
754 : {
755 : .odbc = "SQL_DATE",
756 : .server = "date",
757 : },
758 : {
759 : .odbc = "SQL_DECIMAL",
760 : .server = "decimal(18,7)",
761 : },
762 : {
763 : .odbc = "SQL_DOUBLE",
764 : .server = "double",
765 : },
766 : {
767 : .odbc = "SQL_FLOAT",
768 : .server = "float",
769 : },
770 : {
771 : .odbc = "SQL_GUID",
772 : .server = "uuid",
773 : },
774 : {
775 : .odbc = "SQL_HUGEINT",
776 : .server = "hugeint",
777 : },
778 : {
779 : .odbc = "SQL_INTEGER",
780 : .server = "integer",
781 : },
782 : {
783 : .odbc = "SQL_INTERVAL_DAY_TO_HOUR",
784 : .server = "interval day to hour",
785 : },
786 : {
787 : .odbc = "SQL_INTERVAL_DAY_TO_MINUTE",
788 : .server = "interval day to minute",
789 : },
790 : {
791 : .odbc = "SQL_INTERVAL_DAY_TO_SECOND",
792 : .server = "interval day to second",
793 : },
794 : {
795 : .odbc = "SQL_INTERVAL_DAY",
796 : .server = "interval day",
797 : },
798 : {
799 : .odbc = "SQL_INTERVAL_HOUR_TO_MINUTE",
800 : .server = "interval hour to minute",
801 : },
802 : {
803 : .odbc = "SQL_INTERVAL_HOUR_TO_SECOND",
804 : .server = "interval hour to second",
805 : },
806 : {
807 : .odbc = "SQL_INTERVAL_HOUR",
808 : .server = "interval hour",
809 : },
810 : {
811 : .odbc = "SQL_INTERVAL_MINUTE_TO_SECOND",
812 : .server = "interval minute to second",
813 : },
814 : {
815 : .odbc = "SQL_INTERVAL_MINUTE",
816 : .server = "interval minute",
817 : },
818 : {
819 : .odbc = "SQL_INTERVAL_MONTH",
820 : .server = "interval month",
821 : },
822 : {
823 : .odbc = "SQL_INTERVAL_SECOND",
824 : .server = "interval second",
825 : },
826 : {
827 : .odbc = "SQL_INTERVAL_YEAR_TO_MONTH",
828 : .server = "interval year to month",
829 : },
830 : {
831 : .odbc = "SQL_INTERVAL_YEAR",
832 : .server = "interval year",
833 : },
834 : {
835 : .odbc = "SQL_LONGVARBINARY",
836 : .server = "binary large object",
837 : },
838 : {
839 : .odbc = "SQL_LONGVARCHAR",
840 : .server = "character large object",
841 : },
842 : {
843 : .odbc = "SQL_NUMERIC",
844 : .server = "numeric(18,7)",
845 : },
846 : {
847 : .odbc = "SQL_REAL",
848 : .server = "real",
849 : },
850 : {
851 : .odbc = "SQL_SMALLINT",
852 : .server = "smallint",
853 : },
854 : {
855 : .odbc = "SQL_TIMESTAMP",
856 : .server = "timestamp",
857 : },
858 : {
859 : .odbc = "SQL_TIME",
860 : .server = "time",
861 : },
862 : {
863 : .odbc = "SQL_TINYINT",
864 : .server = "tinyint",
865 : },
866 : {
867 : .odbc = "SQL_VARBINARY",
868 : .server = "binary large object",
869 : },
870 : {
871 : .odbc = "SQL_VARCHAR",
872 : .server = "character varying",
873 : },
874 : {
875 : .odbc = "SQL_WCHAR",
876 : .server = "character",
877 : },
878 : {
879 : .odbc = "SQL_WLONGVARCHAR",
880 : .server = "character large object",
881 : },
882 : {
883 : .odbc = "SQL_WVARCHAR",
884 : .server = "character varying",
885 : },
886 : {
887 : 0 /* sentinel */
888 : },
889 : };
890 :
891 : char *
892 106 : ODBCTranslateSQL(ODBCDbc *dbc, const SQLCHAR *query, size_t length, SQLULEN noscan)
893 : {
894 : /* we only need to read limited amounts of data into these
895 : * buffers (timestamp, interval, function name), so 128 bytes is
896 : * plenty long enough */
897 106 : char buf[128], buf2[128];
898 :
899 : /* From Jun2023 release (11.47) the mserver5 SQL parser supports all
900 : * ODBC escape sequences, so no scanning or translation is required here.
901 : */
902 106 : if (dbc->minor >= 47)
903 : noscan = SQL_NOSCAN_ON;
904 :
905 0 : if (noscan != SQL_NOSCAN_ON) {
906 : char *nquery;
907 : bool quoted = false, rawstring = false, dquoted = false;
908 :
909 0 : for (size_t i = 0; i < length; i++) {
910 0 : if (quoted && query[i] == '\\') {
911 0 : i++;
912 0 : continue;
913 : }
914 0 : if (quoted || rawstring) {
915 0 : if (query[i] == '\'')
916 0 : quoted = rawstring = false;
917 0 : continue;
918 : }
919 0 : if (dquoted) {
920 0 : if (query[i] == '"')
921 0 : dquoted = false;
922 0 : continue;
923 : }
924 0 : if (query[i] == '\'') {
925 0 : if (dbc->raw_strings ?
926 0 : (i > 0 &&
927 0 : query[i - 1] != 'e' &&
928 : query[i - 1] != 'E') :
929 0 : (i > 0 &&
930 0 : (query[i - 1] == 'r' ||
931 : query[i - 1] == 'R')))
932 : rawstring = true;
933 : else
934 : quoted = true;
935 0 : continue;
936 : }
937 0 : if (query[i] == '"') {
938 0 : dquoted = true;
939 0 : continue;
940 : }
941 0 : if (query[i] != '{')
942 0 : continue;
943 0 : size_t n = 0;
944 0 : if (sscanf((const char *) query + i, "{ ts '%127[0-9:. -]' }%zn", buf, &n) >= 1 && n > 0) {
945 0 : char *rest = ODBCTranslateSQL(dbc, query + i + n, length - i - n, noscan);
946 0 : size_t len = strlen(buf) + strlen(rest);
947 0 : nquery = malloc(i + len + 13);
948 0 : snprintf(nquery, i + len + 13,
949 : "%.*sTIMESTAMP '%s'%s",
950 : (int) i, query, buf, rest);
951 0 : free(rest);
952 0 : return nquery;
953 : }
954 0 : if (sscanf((const char *) query + i, "{ t '%127[0-9:]' }%zn", buf, &n) >= 1 && n > 0) {
955 0 : char *rest = ODBCTranslateSQL(dbc, query + i + n, length - i - n, noscan);
956 0 : size_t len = strlen(buf) + strlen(rest);
957 0 : nquery = malloc(i + len + 8);
958 0 : snprintf(nquery, i + len + 8,
959 : "%.*sTIME '%s'%s",
960 : (int) i, query, buf, rest);
961 0 : free(rest);
962 0 : return nquery;
963 : }
964 0 : if (sscanf((const char *) query + i, "{ d '%127[0-9-]' }%zn", buf, &n) >= 1 && n > 0) {
965 0 : char *rest = ODBCTranslateSQL(dbc, query + i + n, length - i - n, noscan);
966 0 : size_t len = strlen(buf) + strlen(rest);
967 0 : nquery = malloc(i + len + 8);
968 0 : snprintf(nquery, i + len + 8,
969 : "%.*sDATE '%s'%s",
970 : (int) i, query, buf, rest);
971 0 : free(rest);
972 0 : return nquery;
973 : }
974 0 : if (sscanf((const char *) query + i, "{ guid '%127[0-9a-fA-F-]' }%zn", buf, &n) >= 1 && n > 0) {
975 0 : char *rest = ODBCTranslateSQL(dbc, query + i + n, length - i - n, noscan);
976 0 : size_t len = strlen(buf) + strlen(rest);
977 0 : nquery = malloc(i + len + 8);
978 0 : snprintf(nquery, i + len + 8,
979 : "%.*sUUID '%s'%s",
980 : (int) i, query, buf, rest);
981 0 : free(rest);
982 0 : return nquery;
983 : }
984 0 : if (sscanf((const char *) query + i, "{ escape '%127[^']' }%zn", buf, &n) >= 1 && n > 0) {
985 0 : char *rest = ODBCTranslateSQL(dbc, query + i + n, length - i - n, noscan);
986 0 : size_t len = strlen(buf) + strlen(rest);
987 0 : nquery = malloc(i + len + 10);
988 0 : snprintf(nquery, i + len + 10,
989 : "%.*sESCAPE '%s'%s",
990 : (int) i, query, buf, rest);
991 0 : free(rest);
992 0 : return nquery;
993 : }
994 0 : if (sscanf((const char *) query + i, "{ interval '%127[^']' %127[a-zA-Z ] }%zn", buf, buf2, &n) >= 2 && n > 0) {
995 0 : char *rest = ODBCTranslateSQL(dbc, query + i + n, length - i - n, noscan);
996 0 : size_t len = strlen(buf) + strlen(buf2) + strlen(rest);
997 0 : nquery = malloc(i + len + 14);
998 0 : snprintf(nquery, i + len + 14,
999 : "%.*sINTERVAL '%s' %s %s",
1000 : (int) i, query, buf, buf2, rest);
1001 0 : free(rest);
1002 0 : return nquery;
1003 : }
1004 0 : if (sscanf((const char *) query + i, "{ interval + '%127[^']' %127[a-zA-Z ] }%zn", buf, buf2, &n) >= 2 && n > 0) {
1005 0 : char *rest = ODBCTranslateSQL(dbc, query + i + n, length - i - n, noscan);
1006 0 : size_t len = strlen(buf) + strlen(buf2) + strlen(rest);
1007 0 : nquery = malloc(i + len + 15);
1008 0 : snprintf(nquery, i + len + 15,
1009 : "%.*sINTERVAL +'%s' %s %s",
1010 : (int) i, query, buf, buf2, rest);
1011 0 : free(rest);
1012 0 : return nquery;
1013 : }
1014 0 : if (sscanf((const char *) query + i, "{ interval - '%127[^']' %127[a-zA-Z ] }%zn", buf, buf2, &n) >= 2 && n > 0) {
1015 0 : char *rest = ODBCTranslateSQL(dbc, query + i + n, length - i - n, noscan);
1016 0 : size_t len = strlen(buf) + strlen(buf2) + strlen(rest);
1017 0 : nquery = malloc(i + len + 15);
1018 0 : snprintf(nquery, i + len + 15,
1019 : "%.*sINTERVAL -'%s' %s %s",
1020 : (int) i, query, buf, buf2, rest);
1021 0 : free(rest);
1022 0 : return nquery;
1023 : }
1024 0 : if (sscanf((const char *) query + i, "{ oj %zn", &n) >= 0 && n > 0) {
1025 0 : char *rest = ODBCTranslateSQL(dbc, query + i + n, length - i - n, noscan);
1026 0 : for (size_t j = 0; rest[j]; j++) {
1027 0 : if (quoted && rest[j] == '\\') {
1028 0 : j++;
1029 0 : continue;
1030 : }
1031 0 : if (quoted || rawstring) {
1032 0 : if (rest[j] == '\'')
1033 0 : quoted = rawstring = false;
1034 0 : continue;
1035 : }
1036 0 : if (dquoted) {
1037 0 : if (rest[j] == '"')
1038 0 : dquoted = false;
1039 0 : continue;
1040 : }
1041 0 : if (rest[j] == '\'') {
1042 0 : if (dbc->raw_strings ?
1043 0 : (j > 0 &&
1044 0 : rest[j - 1] != 'e' &&
1045 : rest[j - 1] != 'E') :
1046 0 : (j > 0 &&
1047 0 : (rest[j - 1] == 'r' ||
1048 : rest[j - 1] == 'R')))
1049 : rawstring = true;
1050 : else
1051 : quoted = true;
1052 0 : continue;
1053 : }
1054 0 : if (rest[j] == '"') {
1055 0 : dquoted = true;
1056 0 : continue;
1057 : }
1058 0 : if (rest[j] == '}') {
1059 0 : size_t len = strlen(rest);
1060 0 : nquery = malloc(i + len + 2);
1061 0 : snprintf(nquery, i + len + 2,
1062 : "%.*s %.*s %s",
1063 : (int) i, query,
1064 : (int) j, rest,
1065 0 : rest + j + 1);
1066 0 : free(rest);
1067 0 : return nquery;
1068 : }
1069 : }
1070 0 : free(rest);
1071 0 : continue;
1072 : }
1073 0 : if (sscanf((const char *) query + i, "{ call %zn", &n) >= 0 && n > 0) {
1074 0 : char *rest = ODBCTranslateSQL(dbc, query + i + n, length - i - n, noscan);
1075 0 : for (size_t j = 0; rest[j]; j++) {
1076 0 : if (quoted && rest[j] == '\\') {
1077 0 : j++;
1078 0 : continue;
1079 : }
1080 0 : if (quoted || rawstring) {
1081 0 : if (rest[j] == '\'')
1082 0 : quoted = rawstring = false;
1083 0 : continue;
1084 : }
1085 0 : if (dquoted) {
1086 0 : if (rest[j] == '"')
1087 0 : dquoted = false;
1088 0 : continue;
1089 : }
1090 0 : if (rest[j] == '\'') {
1091 0 : if (dbc->raw_strings ?
1092 0 : (j > 0 &&
1093 0 : rest[j - 1] != 'e' &&
1094 : rest[j - 1] != 'E') :
1095 0 : (j > 0 &&
1096 0 : (rest[j - 1] == 'r' ||
1097 : rest[j - 1] == 'R')))
1098 : rawstring = true;
1099 : else
1100 : quoted = true;
1101 0 : continue;
1102 : }
1103 0 : if (rest[j] == '"') {
1104 0 : dquoted = true;
1105 0 : continue;
1106 : }
1107 0 : if (rest[j] == '}') {
1108 0 : size_t len = strlen(rest);
1109 0 : nquery = malloc(i + len + 6);
1110 0 : snprintf(nquery, i + len + 6,
1111 : "%.*sCALL %.*s %s",
1112 : (int) i, query,
1113 : (int) j, rest,
1114 0 : rest + j + 1);
1115 0 : free(rest);
1116 0 : return nquery;
1117 : }
1118 : }
1119 0 : free(rest);
1120 0 : continue;
1121 : }
1122 0 : if (sscanf((const char *) query + i, "{ fn %127[a-zA-Z0-9_] ( %zn", buf, &n) >= 1 && n > 0) {
1123 0 : char *rest = ODBCTranslateSQL(dbc, query + i + n, length - i - n, noscan);
1124 0 : size_t arglen = 0;
1125 0 : size_t lastarg = 0;
1126 0 : int nargs = 0;
1127 0 : int nparen = 1;
1128 0 : bool seenarg = false;
1129 :
1130 0 : for (size_t j = 0; rest[j] && nargs < 5; j++) {
1131 0 : if (quoted && rest[j] == '\\') {
1132 0 : j++;
1133 0 : continue;
1134 : }
1135 0 : if (quoted || rawstring) {
1136 0 : if (rest[j] == '\'')
1137 0 : quoted = rawstring = false;
1138 0 : continue;
1139 : }
1140 0 : if (dquoted) {
1141 0 : if (rest[j] == '"')
1142 0 : dquoted = false;
1143 0 : continue;
1144 : }
1145 0 : if (rest[j] == '\'') {
1146 0 : seenarg = true;
1147 0 : if (dbc->raw_strings ?
1148 0 : (j > 0 &&
1149 0 : rest[j - 1] != 'e' &&
1150 : rest[j - 1] != 'E') :
1151 0 : (j > 0 &&
1152 0 : (rest[j - 1] == 'r' ||
1153 : rest[j - 1] == 'R')))
1154 : rawstring = true;
1155 : else
1156 : quoted = true;
1157 0 : continue;
1158 : }
1159 0 : if (rest[j] == '"') {
1160 0 : seenarg = true;
1161 0 : dquoted = true;
1162 0 : continue;
1163 : }
1164 0 : if (rest[j] == '(') {
1165 0 : seenarg = true;
1166 0 : nparen++;
1167 0 : continue;
1168 : }
1169 0 : if (nparen > 1) {
1170 0 : if (rest[j] == ')')
1171 0 : nparen--;
1172 0 : continue;
1173 : }
1174 0 : if (rest[j] == ',') {
1175 0 : if (!seenarg)
1176 : break;
1177 0 : nargs++;
1178 0 : seenarg = false;
1179 0 : continue;
1180 : }
1181 0 : if (rest[j] == ')') {
1182 0 : if (--nparen < 0)
1183 : break;
1184 0 : arglen = j;
1185 0 : if (seenarg)
1186 0 : nargs++;
1187 0 : else if (nargs > 0)
1188 : break;
1189 0 : seenarg = false;
1190 0 : continue;
1191 : }
1192 0 : if (rest[j] == '}') {
1193 0 : if (nparen != 0 || seenarg)
1194 : break;
1195 0 : for (struct scalars *func = scalars; func->name; func++) {
1196 0 : if (strcasecmp(func->name, buf) == 0 && func->nargs == nargs) {
1197 0 : const char *repl = func->repl;
1198 0 : const char *repl2 = "";
1199 0 : const char *repl3 = "";
1200 0 : const char *p1 = "(";
1201 0 : const char *p2 = ")";
1202 0 : const char *quote = "";
1203 0 : size_t repl3len = 0;
1204 0 : if (repl == NULL) {
1205 0 : if (strcmp(func->name, "user") == 0) {
1206 0 : repl = dbc->uid;
1207 0 : p1 = p2 = "";
1208 0 : quote = "'";
1209 0 : } else if (strcmp(func->name, "database") == 0) {
1210 0 : repl = dbc->dbname;
1211 0 : p1 = p2 = "";
1212 0 : quote = "'";
1213 0 : } else if (strcmp(func->name, "convert") == 0) {
1214 0 : repl = "convert";
1215 0 : for (struct convert *c = convert; c->odbc; c++) {
1216 0 : if (strncasecmp(rest + lastarg, c->odbc, strlen(c->odbc)) == 0) {
1217 0 : repl2 = c->server;
1218 0 : repl3len = arglen - lastarg - strlen(c->odbc);
1219 0 : repl3 = rest + lastarg + strlen(c->odbc);
1220 0 : arglen = lastarg;
1221 0 : break;
1222 : }
1223 : }
1224 : }
1225 0 : if (repl == NULL)
1226 : break;
1227 : }
1228 0 : size_t l = i + strlen(repl) + 2 + arglen + strlen(rest) - j + 1 + strlen(repl2) + repl3len;
1229 0 : nquery = malloc(l);
1230 0 : snprintf(nquery, l, "%.*s%s%s%s%s%.*s%s%.*s%s%s", (int) i, query, quote, repl, quote, p1, (int) arglen, rest, repl2, (int) repl3len, repl3, p2, rest + j + 1);
1231 0 : free(rest);
1232 0 : return nquery;
1233 : }
1234 : }
1235 : break;
1236 : }
1237 0 : if (!seenarg && !isspace((unsigned char) rest[j])) {
1238 0 : lastarg = j;
1239 0 : seenarg = true;
1240 : }
1241 : }
1242 0 : free(rest);
1243 0 : continue;
1244 : }
1245 : }
1246 : }
1247 106 : return dupODBCstring(query, length);
1248 : }
1249 :
1250 : char *
1251 87 : ODBCParseOA(const char *tab, const char *col, const char *arg, size_t len)
1252 : {
1253 87 : size_t i;
1254 87 : char *res;
1255 87 : const char *s;
1256 :
1257 : /* count length, counting ' and \ double */
1258 722 : for (i = 0, s = arg; s < arg + len; i++, s++) {
1259 635 : if (*s == '\'' || *s == '\\')
1260 0 : i++;
1261 : }
1262 87 : i += strlen(tab) + strlen(col) + 10; /* ""."" = '' */
1263 87 : res = malloc(i + 1);
1264 87 : if (res == NULL)
1265 : return NULL;
1266 87 : snprintf(res, i, "\"%s\".\"%s\" = '", tab, col);
1267 722 : for (i = strlen(res), s = arg; s < arg + len; s++) {
1268 635 : if (*s == '\'' || *s == '\\')
1269 0 : res[i++] = *s;
1270 635 : res[i++] = *s;
1271 : }
1272 87 : res[i++] = '\'';
1273 87 : res[i] = 0;
1274 87 : return res;
1275 : }
1276 :
1277 : char *
1278 66 : ODBCParsePV(const char *tab, const char *col, const char *arg, size_t len, const ODBCDbc *dbc)
1279 : {
1280 66 : size_t i;
1281 66 : char *res;
1282 66 : const char *s;
1283 :
1284 : /* count length, counting ' and \ double */
1285 357 : for (i = 0, s = arg; s < arg + len; i++, s++) {
1286 291 : if (*s == '\'' || *s == '\\')
1287 0 : i++;
1288 : }
1289 66 : i += strlen(tab) + strlen(col) + 25; /* ""."" like '' escape r'\' */
1290 66 : res = malloc(i + 1);
1291 66 : if (res == NULL)
1292 : return NULL;
1293 66 : snprintf(res, i, "\"%s\".\"%s\" like '", tab, col);
1294 357 : for (i = strlen(res), s = arg; s < arg + len; s++) {
1295 291 : if (*s == '\'' || *s == '\\')
1296 0 : res[i++] = *s;
1297 291 : res[i++] = *s;
1298 : }
1299 : /* raw strings prefix syntax is only supported by servers since Jun2020 (11.37) */
1300 66 : if (dbc->major == 11 && dbc->minor >= 37) {
1301 : s = "' escape r'\\'";
1302 : } else {
1303 0 : s = "' escape '\\\\'";
1304 : }
1305 924 : for (; *s; s++)
1306 858 : res[i++] = *s;
1307 66 : res[i] = 0;
1308 66 : return res;
1309 : }
1310 :
1311 : char *
1312 0 : ODBCParseID(const char *tab, const char *col, const char *arg, size_t len)
1313 : {
1314 0 : size_t i;
1315 0 : char *res;
1316 0 : const char *s;
1317 0 : int fold = 1;
1318 :
1319 0 : while (len > 0 && (arg[--len] == ' ' || arg[len] == '\t'))
1320 : ;
1321 0 : len++;
1322 0 : if (len >= 2 && *arg == '"' && arg[len - 1] == '"') {
1323 0 : arg++;
1324 0 : len -= 2;
1325 0 : fold = 0;
1326 : }
1327 :
1328 0 : for (i = 0, s = arg; s < arg + len; i++, s++) {
1329 0 : if (*s == '\'' || *s == '\\')
1330 0 : i++;
1331 : }
1332 0 : i += strlen(tab) + strlen(col) + 10; /* ""."" = '' */
1333 0 : if (fold)
1334 0 : i += 14; /* 2 times upper() */
1335 0 : res = malloc(i + 1);
1336 0 : if (res == NULL)
1337 : return NULL;
1338 0 : if (fold)
1339 0 : snprintf(res, i, "upper(\"%s\".\"%s\") = upper('", tab, col);
1340 : else
1341 0 : snprintf(res, i, "\"%s\".\"%s\" = '", tab, col);
1342 0 : for (i = strlen(res); len != 0; len--, arg++) {
1343 0 : if (*arg == '\'' || *arg == '\\')
1344 0 : res[i++] = *arg;
1345 0 : res[i++] = *arg;
1346 : }
1347 0 : res[i++] = '\'';
1348 0 : if (fold)
1349 0 : res[i++] = ')';
1350 0 : res[i] = 0;
1351 0 : return res;
1352 : }
1353 :
1354 : struct sql_types ODBC_sql_types[] = {
1355 : {
1356 : .concise_type = SQL_CHAR,
1357 : .type = SQL_CHAR,
1358 : .datetime_interval_precision = UNAFFECTED,
1359 : .length = 1,
1360 : .scale = UNAFFECTED,
1361 : .fixed = SQL_FALSE,
1362 : },
1363 : {
1364 : .concise_type = SQL_VARCHAR,
1365 : .type = SQL_VARCHAR,
1366 : .datetime_interval_precision = UNAFFECTED,
1367 : .length = 1,
1368 : .scale = UNAFFECTED,
1369 : .fixed = SQL_FALSE,
1370 : },
1371 : {
1372 : .concise_type = SQL_LONGVARCHAR,
1373 : .type = SQL_LONGVARCHAR,
1374 : .precision = UNAFFECTED,
1375 : .datetime_interval_precision = UNAFFECTED,
1376 : .length = UNAFFECTED,
1377 : .scale = UNAFFECTED,
1378 : .fixed = SQL_FALSE,
1379 : },
1380 : {
1381 : .concise_type = SQL_WCHAR,
1382 : .type = SQL_WCHAR,
1383 : .precision = UNAFFECTED,
1384 : .datetime_interval_precision = UNAFFECTED,
1385 : .length = UNAFFECTED,
1386 : .scale = UNAFFECTED,
1387 : .fixed = SQL_FALSE,
1388 : },
1389 : {
1390 : .concise_type = SQL_WVARCHAR,
1391 : .type = SQL_WVARCHAR,
1392 : .precision = UNAFFECTED,
1393 : .datetime_interval_precision = UNAFFECTED,
1394 : .length = UNAFFECTED,
1395 : .scale = UNAFFECTED,
1396 : .fixed = SQL_FALSE,
1397 : },
1398 : {
1399 : .concise_type = SQL_WLONGVARCHAR,
1400 : .type = SQL_WLONGVARCHAR,
1401 : .precision = UNAFFECTED,
1402 : .datetime_interval_precision = UNAFFECTED,
1403 : .length = UNAFFECTED,
1404 : .scale = UNAFFECTED,
1405 : .fixed = SQL_FALSE,
1406 : },
1407 : {
1408 : .concise_type = SQL_DECIMAL,
1409 : .type = SQL_DECIMAL,
1410 : .precision = 17,
1411 : .datetime_interval_precision = UNAFFECTED,
1412 : .length = UNAFFECTED,
1413 : .radix = 10,
1414 : .fixed = SQL_TRUE,
1415 : },
1416 : {
1417 : .concise_type = SQL_NUMERIC,
1418 : .type = SQL_NUMERIC,
1419 : .precision = 17,
1420 : .datetime_interval_precision = UNAFFECTED,
1421 : .length = UNAFFECTED,
1422 : .radix = 10,
1423 : .fixed = SQL_TRUE,
1424 : },
1425 : {
1426 : .concise_type = SQL_BIT,
1427 : .type = SQL_BIT,
1428 : .precision = UNAFFECTED,
1429 : .datetime_interval_precision = UNAFFECTED,
1430 : .length = UNAFFECTED,
1431 : .scale = UNAFFECTED,
1432 : .fixed = SQL_FALSE,
1433 : },
1434 : {
1435 : .concise_type = SQL_TINYINT,
1436 : .type = SQL_TINYINT,
1437 : .precision = UNAFFECTED,
1438 : .datetime_interval_precision = UNAFFECTED,
1439 : .length = UNAFFECTED,
1440 : .scale = UNAFFECTED,
1441 : .radix = 10,
1442 : .fixed = SQL_TRUE,
1443 : },
1444 : {
1445 : .concise_type = SQL_SMALLINT,
1446 : .type = SQL_SMALLINT,
1447 : .precision = UNAFFECTED,
1448 : .datetime_interval_precision = UNAFFECTED,
1449 : .length = UNAFFECTED,
1450 : .scale = UNAFFECTED,
1451 : .radix = 10,
1452 : .fixed = SQL_TRUE,
1453 : },
1454 : {
1455 : .concise_type = SQL_INTEGER,
1456 : .type = SQL_INTEGER,
1457 : .precision = UNAFFECTED,
1458 : .datetime_interval_precision = UNAFFECTED,
1459 : .length = UNAFFECTED,
1460 : .scale = UNAFFECTED,
1461 : .radix = 10,
1462 : .fixed = SQL_TRUE,
1463 : },
1464 : {
1465 : .concise_type = SQL_BIGINT,
1466 : .type = SQL_BIGINT,
1467 : .precision = UNAFFECTED,
1468 : .datetime_interval_precision = UNAFFECTED,
1469 : .length = UNAFFECTED,
1470 : .scale = UNAFFECTED,
1471 : .radix = 10,
1472 : .fixed = SQL_TRUE,
1473 : },
1474 : {
1475 : .concise_type = SQL_HUGEINT,
1476 : .type = SQL_HUGEINT,
1477 : .precision = UNAFFECTED,
1478 : .datetime_interval_precision = UNAFFECTED,
1479 : .length = UNAFFECTED,
1480 : .scale = UNAFFECTED,
1481 : .radix = 10,
1482 : .fixed = SQL_TRUE,
1483 : },
1484 : {
1485 : .concise_type = SQL_REAL,
1486 : .type = SQL_REAL,
1487 : .precision = FLT_MANT_DIG,
1488 : .datetime_interval_precision = UNAFFECTED,
1489 : .length = UNAFFECTED,
1490 : .scale = UNAFFECTED,
1491 : .radix = 2,
1492 : .fixed = SQL_FALSE,
1493 : },
1494 : {
1495 : .concise_type = SQL_FLOAT,
1496 : .type = SQL_FLOAT,
1497 : .precision = DBL_MANT_DIG,
1498 : .datetime_interval_precision = UNAFFECTED,
1499 : .length = UNAFFECTED,
1500 : .scale = UNAFFECTED,
1501 : .radix = 2,
1502 : .fixed = SQL_FALSE,
1503 : },
1504 : {
1505 : .concise_type = SQL_DOUBLE,
1506 : .type = SQL_DOUBLE,
1507 : .precision = DBL_MANT_DIG,
1508 : .datetime_interval_precision = UNAFFECTED,
1509 : .length = UNAFFECTED,
1510 : .scale = UNAFFECTED,
1511 : .radix = 2,
1512 : .fixed = SQL_FALSE,
1513 : },
1514 : {
1515 : .concise_type = SQL_BINARY,
1516 : .type = SQL_BINARY,
1517 : .datetime_interval_precision = UNAFFECTED,
1518 : .length = 1,
1519 : .scale = UNAFFECTED,
1520 : .fixed = SQL_FALSE,
1521 : },
1522 : {
1523 : .concise_type = SQL_VARBINARY,
1524 : .type = SQL_VARBINARY,
1525 : .datetime_interval_precision = UNAFFECTED,
1526 : .length = 1,
1527 : .scale = UNAFFECTED,
1528 : .fixed = SQL_FALSE,
1529 : },
1530 : {
1531 : .concise_type = SQL_LONGVARBINARY,
1532 : .type = SQL_LONGVARBINARY,
1533 : .precision = UNAFFECTED,
1534 : .datetime_interval_precision = UNAFFECTED,
1535 : .length = UNAFFECTED,
1536 : .scale = UNAFFECTED,
1537 : .fixed = SQL_FALSE,
1538 : },
1539 : {
1540 : .concise_type = SQL_GUID,
1541 : .type = SQL_GUID,
1542 : .precision = UNAFFECTED,
1543 : .datetime_interval_precision = UNAFFECTED,
1544 : .length = UNAFFECTED,
1545 : .scale = UNAFFECTED,
1546 : .fixed = SQL_FALSE,
1547 : },
1548 : {
1549 : .concise_type = SQL_TYPE_DATE,
1550 : .type = SQL_DATETIME,
1551 : .code = SQL_CODE_DATE,
1552 : .datetime_interval_precision = UNAFFECTED,
1553 : .length = UNAFFECTED,
1554 : .scale = UNAFFECTED,
1555 : .fixed = SQL_FALSE,
1556 : },
1557 : {
1558 : .concise_type = SQL_TYPE_TIME,
1559 : .type = SQL_DATETIME,
1560 : .code = SQL_CODE_TIME,
1561 : .datetime_interval_precision = UNAFFECTED,
1562 : .length = UNAFFECTED,
1563 : .scale = UNAFFECTED,
1564 : .fixed = SQL_FALSE,
1565 : },
1566 : {
1567 : .concise_type = SQL_TYPE_TIMESTAMP,
1568 : .type = SQL_DATETIME,
1569 : .code = SQL_CODE_TIMESTAMP,
1570 : .precision = 6,
1571 : .datetime_interval_precision = UNAFFECTED,
1572 : .length = UNAFFECTED,
1573 : .scale = UNAFFECTED,
1574 : .fixed = SQL_FALSE,
1575 : },
1576 : {
1577 : .concise_type = SQL_INTERVAL_MONTH,
1578 : .type = SQL_INTERVAL,
1579 : .code = SQL_CODE_MONTH,
1580 : .datetime_interval_precision = 2,
1581 : .length = UNAFFECTED,
1582 : .scale = UNAFFECTED,
1583 : .fixed = SQL_FALSE,
1584 : },
1585 : {
1586 : .concise_type = SQL_INTERVAL_YEAR,
1587 : .type = SQL_INTERVAL,
1588 : .code = SQL_CODE_YEAR,
1589 : .datetime_interval_precision = 2,
1590 : .length = UNAFFECTED,
1591 : .scale = UNAFFECTED,
1592 : .fixed = SQL_FALSE,
1593 : },
1594 : {
1595 : .concise_type = SQL_INTERVAL_YEAR_TO_MONTH,
1596 : .type = SQL_INTERVAL,
1597 : .code = SQL_CODE_YEAR_TO_MONTH,
1598 : .datetime_interval_precision = 2,
1599 : .length = UNAFFECTED,
1600 : .scale = UNAFFECTED,
1601 : .fixed = SQL_FALSE,
1602 : },
1603 : {
1604 : .concise_type = SQL_INTERVAL_DAY,
1605 : .type = SQL_INTERVAL,
1606 : .code = SQL_CODE_DAY,
1607 : .datetime_interval_precision = 2,
1608 : .length = UNAFFECTED,
1609 : .scale = UNAFFECTED,
1610 : .fixed = SQL_FALSE,
1611 : },
1612 : {
1613 : .concise_type = SQL_INTERVAL_HOUR,
1614 : .type = SQL_INTERVAL,
1615 : .code = SQL_CODE_HOUR,
1616 : .datetime_interval_precision = 2,
1617 : .length = UNAFFECTED,
1618 : .scale = UNAFFECTED,
1619 : .fixed = SQL_FALSE,
1620 : },
1621 : {
1622 : .concise_type = SQL_INTERVAL_MINUTE,
1623 : .type = SQL_INTERVAL,
1624 : .code = SQL_CODE_MINUTE,
1625 : .datetime_interval_precision = 2,
1626 : .length = UNAFFECTED,
1627 : .scale = UNAFFECTED,
1628 : .fixed = SQL_FALSE,
1629 : },
1630 : {
1631 : .concise_type = SQL_INTERVAL_SECOND,
1632 : .type = SQL_INTERVAL,
1633 : .code = SQL_CODE_SECOND,
1634 : .precision = 6,
1635 : .datetime_interval_precision = 2,
1636 : .length = UNAFFECTED,
1637 : .scale = UNAFFECTED,
1638 : .fixed = SQL_FALSE,
1639 : },
1640 : {
1641 : .concise_type = SQL_INTERVAL_DAY_TO_HOUR,
1642 : .type = SQL_INTERVAL,
1643 : .code = SQL_CODE_DAY_TO_HOUR,
1644 : .datetime_interval_precision = 2,
1645 : .length = UNAFFECTED,
1646 : .scale = UNAFFECTED,
1647 : .fixed = SQL_FALSE,
1648 : },
1649 : {
1650 : .concise_type = SQL_INTERVAL_DAY_TO_MINUTE,
1651 : .type = SQL_INTERVAL,
1652 : .code = SQL_CODE_DAY_TO_MINUTE,
1653 : .datetime_interval_precision = 2,
1654 : .length = UNAFFECTED,
1655 : .scale = UNAFFECTED,
1656 : .fixed = SQL_FALSE,
1657 : },
1658 : {
1659 : .concise_type = SQL_INTERVAL_DAY_TO_SECOND,
1660 : .type = SQL_INTERVAL,
1661 : .code = SQL_CODE_DAY_TO_SECOND,
1662 : .precision = 6,
1663 : .datetime_interval_precision = 2,
1664 : .length = UNAFFECTED,
1665 : .scale = UNAFFECTED,
1666 : .fixed = SQL_FALSE,
1667 : },
1668 : {
1669 : .concise_type = SQL_INTERVAL_HOUR_TO_MINUTE,
1670 : .type = SQL_INTERVAL,
1671 : .code = SQL_CODE_HOUR_TO_MINUTE,
1672 : .datetime_interval_precision = 2,
1673 : .length = UNAFFECTED,
1674 : .scale = UNAFFECTED,
1675 : .fixed = SQL_FALSE,
1676 : },
1677 : {
1678 : .concise_type = SQL_INTERVAL_HOUR_TO_SECOND,
1679 : .type = SQL_INTERVAL,
1680 : .code = SQL_CODE_HOUR_TO_SECOND,
1681 : .precision = 6,
1682 : .datetime_interval_precision = 2,
1683 : .length = UNAFFECTED,
1684 : .scale = UNAFFECTED,
1685 : .fixed = SQL_FALSE,
1686 : },
1687 : {
1688 : .concise_type = SQL_INTERVAL_MINUTE_TO_SECOND,
1689 : .type = SQL_INTERVAL,
1690 : .code = SQL_CODE_MINUTE_TO_SECOND,
1691 : .precision = 6,
1692 : .datetime_interval_precision = 2,
1693 : .length = UNAFFECTED,
1694 : .scale = UNAFFECTED,
1695 : .fixed = SQL_FALSE,
1696 : },
1697 : {
1698 : 0 /* sentinel */
1699 : },
1700 : };
1701 :
1702 : struct sql_types ODBC_c_types[] = {
1703 : {
1704 : .concise_type = SQL_C_CHAR,
1705 : .type = SQL_C_CHAR,
1706 : .datetime_interval_precision = UNAFFECTED,
1707 : .length = 1,
1708 : .scale = UNAFFECTED,
1709 : .fixed = SQL_FALSE,
1710 : },
1711 : {
1712 : .concise_type = SQL_C_WCHAR,
1713 : .type = SQL_C_WCHAR,
1714 : .precision = UNAFFECTED,
1715 : .datetime_interval_precision = UNAFFECTED,
1716 : .length = UNAFFECTED,
1717 : .scale = UNAFFECTED,
1718 : .fixed = SQL_FALSE,
1719 : },
1720 : {
1721 : .concise_type = SQL_C_BIT,
1722 : .type = SQL_C_BIT,
1723 : .precision = UNAFFECTED,
1724 : .datetime_interval_precision = UNAFFECTED,
1725 : .length = UNAFFECTED,
1726 : .scale = UNAFFECTED,
1727 : .fixed = SQL_FALSE,
1728 : },
1729 : {
1730 : .concise_type = SQL_C_NUMERIC,
1731 : .type = SQL_C_NUMERIC,
1732 : .precision = 17,
1733 : .datetime_interval_precision = UNAFFECTED,
1734 : .length = UNAFFECTED,
1735 : .radix = 10,
1736 : .fixed = SQL_TRUE,
1737 : },
1738 : {
1739 : .concise_type = SQL_C_STINYINT,
1740 : .type = SQL_C_STINYINT,
1741 : .precision = UNAFFECTED,
1742 : .datetime_interval_precision = UNAFFECTED,
1743 : .length = UNAFFECTED,
1744 : .scale = UNAFFECTED,
1745 : .radix = 10,
1746 : .fixed = SQL_TRUE,
1747 : },
1748 : {
1749 : .concise_type = SQL_C_UTINYINT,
1750 : .type = SQL_C_UTINYINT,
1751 : .precision = UNAFFECTED,
1752 : .datetime_interval_precision = UNAFFECTED,
1753 : .length = UNAFFECTED,
1754 : .scale = UNAFFECTED,
1755 : .radix = 10,
1756 : .fixed = SQL_TRUE,
1757 : },
1758 : {
1759 : .concise_type = SQL_C_TINYINT,
1760 : .type = SQL_C_TINYINT,
1761 : .precision = UNAFFECTED,
1762 : .datetime_interval_precision = UNAFFECTED,
1763 : .length = UNAFFECTED,
1764 : .scale = UNAFFECTED,
1765 : .radix = 10,
1766 : .fixed = SQL_TRUE,
1767 : },
1768 : {
1769 : .concise_type = SQL_C_SBIGINT,
1770 : .type = SQL_C_SBIGINT,
1771 : .precision = UNAFFECTED,
1772 : .datetime_interval_precision = UNAFFECTED,
1773 : .length = UNAFFECTED,
1774 : .scale = UNAFFECTED,
1775 : .radix = 10,
1776 : .fixed = SQL_TRUE,
1777 : },
1778 : {
1779 : .concise_type = SQL_C_UBIGINT,
1780 : .type = SQL_C_UBIGINT,
1781 : .precision = UNAFFECTED,
1782 : .datetime_interval_precision = UNAFFECTED,
1783 : .length = UNAFFECTED,
1784 : .scale = UNAFFECTED,
1785 : .radix = 10,
1786 : .fixed = SQL_TRUE,
1787 : },
1788 : {
1789 : .concise_type = SQL_C_SSHORT,
1790 : .type = SQL_C_SSHORT,
1791 : .precision = UNAFFECTED,
1792 : .datetime_interval_precision = UNAFFECTED,
1793 : .length = UNAFFECTED,
1794 : .scale = UNAFFECTED,
1795 : .radix = 10,
1796 : .fixed = SQL_TRUE,
1797 : },
1798 : {
1799 : .concise_type = SQL_C_USHORT,
1800 : .type = SQL_C_USHORT,
1801 : .precision = UNAFFECTED,
1802 : .datetime_interval_precision = UNAFFECTED,
1803 : .length = UNAFFECTED,
1804 : .scale = UNAFFECTED,
1805 : .radix = 10,
1806 : .fixed = SQL_TRUE,
1807 : },
1808 : {
1809 : .concise_type = SQL_C_SHORT,
1810 : .type = SQL_C_SHORT,
1811 : .precision = UNAFFECTED,
1812 : .datetime_interval_precision = UNAFFECTED,
1813 : .length = UNAFFECTED,
1814 : .scale = UNAFFECTED,
1815 : .radix = 10,
1816 : .fixed = SQL_TRUE,
1817 : },
1818 : {
1819 : .concise_type = SQL_C_SLONG,
1820 : .type = SQL_C_SLONG,
1821 : .precision = UNAFFECTED,
1822 : .datetime_interval_precision = UNAFFECTED,
1823 : .length = UNAFFECTED,
1824 : .scale = UNAFFECTED,
1825 : .radix = 10,
1826 : .fixed = SQL_TRUE,
1827 : },
1828 : {
1829 : .concise_type = SQL_C_ULONG,
1830 : .type = SQL_C_ULONG,
1831 : .precision = UNAFFECTED,
1832 : .datetime_interval_precision = UNAFFECTED,
1833 : .length = UNAFFECTED,
1834 : .scale = UNAFFECTED,
1835 : .radix = 10,
1836 : .fixed = SQL_TRUE,
1837 : },
1838 : {
1839 : .concise_type = SQL_C_LONG,
1840 : .type = SQL_C_LONG,
1841 : .precision = UNAFFECTED,
1842 : .datetime_interval_precision = UNAFFECTED,
1843 : .length = UNAFFECTED,
1844 : .scale = UNAFFECTED,
1845 : .radix = 10,
1846 : .fixed = SQL_TRUE,
1847 : },
1848 : {
1849 : .concise_type = SQL_C_FLOAT,
1850 : .type = SQL_C_FLOAT,
1851 : .precision = FLT_MANT_DIG,
1852 : .datetime_interval_precision = UNAFFECTED,
1853 : .length = UNAFFECTED,
1854 : .scale = UNAFFECTED,
1855 : .radix = 2,
1856 : .fixed = SQL_FALSE,
1857 : },
1858 : {
1859 : .concise_type = SQL_C_DOUBLE,
1860 : .type = SQL_C_DOUBLE,
1861 : .precision = DBL_MANT_DIG,
1862 : .datetime_interval_precision = UNAFFECTED,
1863 : .length = UNAFFECTED,
1864 : .scale = UNAFFECTED,
1865 : .radix = 2,
1866 : .fixed = SQL_FALSE,
1867 : },
1868 : {
1869 : .concise_type = SQL_C_BINARY,
1870 : .type = SQL_C_BINARY,
1871 : .precision = UNAFFECTED,
1872 : .datetime_interval_precision = UNAFFECTED,
1873 : .length = UNAFFECTED,
1874 : .scale = UNAFFECTED,
1875 : .fixed = SQL_FALSE,
1876 : },
1877 : {
1878 : .concise_type = SQL_C_TYPE_DATE,
1879 : .type = SQL_DATETIME,
1880 : .code = SQL_CODE_DATE,
1881 : .datetime_interval_precision = UNAFFECTED,
1882 : .length = UNAFFECTED,
1883 : .scale = UNAFFECTED,
1884 : .fixed = SQL_FALSE,
1885 : },
1886 : {
1887 : .concise_type = SQL_C_TYPE_TIME,
1888 : .type = SQL_DATETIME,
1889 : .code = SQL_CODE_TIME,
1890 : .datetime_interval_precision = UNAFFECTED,
1891 : .length = UNAFFECTED,
1892 : .scale = UNAFFECTED,
1893 : .fixed = SQL_FALSE,
1894 : },
1895 : {
1896 : .concise_type = SQL_C_TYPE_TIMESTAMP,
1897 : .type = SQL_DATETIME,
1898 : .code = SQL_CODE_TIMESTAMP,
1899 : .precision = 6,
1900 : .datetime_interval_precision = UNAFFECTED,
1901 : .length = UNAFFECTED,
1902 : .scale = UNAFFECTED,
1903 : .fixed = SQL_FALSE,
1904 : },
1905 : {
1906 : .concise_type = SQL_C_INTERVAL_MONTH,
1907 : .type = SQL_INTERVAL,
1908 : .code = SQL_CODE_MONTH,
1909 : .precision = UNAFFECTED,
1910 : .datetime_interval_precision = 2,
1911 : .length = UNAFFECTED,
1912 : .scale = UNAFFECTED,
1913 : .fixed = SQL_FALSE,
1914 : },
1915 : {
1916 : .concise_type = SQL_C_INTERVAL_YEAR,
1917 : .type = SQL_INTERVAL,
1918 : .code = SQL_CODE_YEAR,
1919 : .precision = UNAFFECTED,
1920 : .datetime_interval_precision = 2,
1921 : .length = UNAFFECTED,
1922 : .scale = UNAFFECTED,
1923 : .fixed = SQL_FALSE,
1924 : },
1925 : {
1926 : .concise_type = SQL_C_INTERVAL_YEAR_TO_MONTH,
1927 : .type = SQL_INTERVAL,
1928 : .code = SQL_CODE_YEAR_TO_MONTH,
1929 : .precision = UNAFFECTED,
1930 : .datetime_interval_precision = 2,
1931 : .length = UNAFFECTED,
1932 : .scale = UNAFFECTED,
1933 : .fixed = SQL_FALSE,
1934 : },
1935 : {
1936 : .concise_type = SQL_C_INTERVAL_DAY,
1937 : .type = SQL_INTERVAL,
1938 : .code = SQL_CODE_DAY,
1939 : .precision = UNAFFECTED,
1940 : .datetime_interval_precision = 2,
1941 : .length = UNAFFECTED,
1942 : .scale = UNAFFECTED,
1943 : .fixed = SQL_FALSE,
1944 : },
1945 : {
1946 : .concise_type = SQL_C_INTERVAL_HOUR,
1947 : .type = SQL_INTERVAL,
1948 : .code = SQL_CODE_HOUR,
1949 : .precision = UNAFFECTED,
1950 : .datetime_interval_precision = 2,
1951 : .length = UNAFFECTED,
1952 : .scale = UNAFFECTED,
1953 : .fixed = SQL_FALSE,
1954 : },
1955 : {
1956 : .concise_type = SQL_C_INTERVAL_MINUTE,
1957 : .type = SQL_INTERVAL,
1958 : .code = SQL_CODE_MINUTE,
1959 : .precision = UNAFFECTED,
1960 : .datetime_interval_precision = 2,
1961 : .length = UNAFFECTED,
1962 : .scale = UNAFFECTED,
1963 : .fixed = SQL_FALSE,
1964 : },
1965 : {
1966 : .concise_type = SQL_C_INTERVAL_SECOND,
1967 : .type = SQL_INTERVAL,
1968 : .code = SQL_CODE_SECOND,
1969 : .precision = UNAFFECTED,
1970 : .datetime_interval_precision = 6,
1971 : .length = UNAFFECTED,
1972 : .scale = UNAFFECTED,
1973 : .fixed = SQL_FALSE,
1974 : },
1975 : {
1976 : .concise_type = SQL_C_INTERVAL_DAY_TO_HOUR,
1977 : .type = SQL_INTERVAL,
1978 : .code = SQL_CODE_DAY_TO_HOUR,
1979 : .precision = UNAFFECTED,
1980 : .datetime_interval_precision = 2,
1981 : .length = UNAFFECTED,
1982 : .scale = UNAFFECTED,
1983 : .fixed = SQL_FALSE,
1984 : },
1985 : {
1986 : .concise_type = SQL_C_INTERVAL_DAY_TO_MINUTE,
1987 : .type = SQL_INTERVAL,
1988 : .code = SQL_CODE_DAY_TO_MINUTE,
1989 : .precision = UNAFFECTED,
1990 : .datetime_interval_precision = 2,
1991 : .length = UNAFFECTED,
1992 : .scale = UNAFFECTED,
1993 : .fixed = SQL_FALSE,
1994 : },
1995 : {
1996 : .concise_type = SQL_C_INTERVAL_DAY_TO_SECOND,
1997 : .type = SQL_INTERVAL,
1998 : .code = SQL_CODE_DAY_TO_SECOND,
1999 : .precision = UNAFFECTED,
2000 : .datetime_interval_precision = 6,
2001 : .length = UNAFFECTED,
2002 : .scale = UNAFFECTED,
2003 : .fixed = SQL_FALSE,
2004 : },
2005 : {
2006 : .concise_type = SQL_C_INTERVAL_HOUR_TO_MINUTE,
2007 : .type = SQL_INTERVAL,
2008 : .code = SQL_CODE_HOUR_TO_MINUTE,
2009 : .precision = UNAFFECTED,
2010 : .datetime_interval_precision = 2,
2011 : .length = UNAFFECTED,
2012 : .scale = UNAFFECTED,
2013 : .fixed = SQL_FALSE,
2014 : },
2015 : {
2016 : .concise_type = SQL_C_INTERVAL_HOUR_TO_SECOND,
2017 : .type = SQL_INTERVAL,
2018 : .code = SQL_CODE_HOUR_TO_SECOND,
2019 : .precision = UNAFFECTED,
2020 : .datetime_interval_precision = 6,
2021 : .length = UNAFFECTED,
2022 : .scale = UNAFFECTED,
2023 : .fixed = SQL_FALSE,
2024 : },
2025 : {
2026 : .concise_type = SQL_C_INTERVAL_MINUTE_TO_SECOND,
2027 : .type = SQL_INTERVAL,
2028 : .code = SQL_CODE_MINUTE_TO_SECOND,
2029 : .precision = UNAFFECTED,
2030 : .datetime_interval_precision = 6,
2031 : .length = UNAFFECTED,
2032 : .scale = UNAFFECTED,
2033 : .fixed = SQL_FALSE,
2034 : },
2035 : {
2036 : .concise_type = SQL_C_GUID,
2037 : .type = SQL_C_GUID,
2038 : .precision = UNAFFECTED,
2039 : .datetime_interval_precision = UNAFFECTED,
2040 : .length = UNAFFECTED,
2041 : .scale = UNAFFECTED,
2042 : .fixed = SQL_FALSE,
2043 : },
2044 : {
2045 : .concise_type = SQL_C_DEFAULT,
2046 : .type = SQL_C_DEFAULT,
2047 : .precision = UNAFFECTED,
2048 : .datetime_interval_precision = UNAFFECTED,
2049 : .length = UNAFFECTED,
2050 : .scale = UNAFFECTED,
2051 : .fixed = SQL_FALSE,
2052 : },
2053 : {
2054 : 0 /* sentinel */
2055 : },
2056 : };
2057 :
2058 : #ifdef ODBCDEBUG
2059 :
2060 : #ifdef NATIVE_WIN32
2061 : const wchar_t *ODBCdebug;
2062 : #else
2063 : const char *ODBCdebug;
2064 : #endif
2065 : static char unknown[32];
2066 :
2067 : char *
2068 0 : translateCType(SQLSMALLINT ValueType)
2069 : {
2070 0 : switch (ValueType) {
2071 : case SQL_C_CHAR:
2072 : return "SQL_C_CHAR";
2073 0 : case SQL_C_WCHAR:
2074 0 : return "SQL_C_WCHAR";
2075 0 : case SQL_C_BINARY:
2076 0 : return "SQL_C_BINARY";
2077 0 : case SQL_C_BIT:
2078 0 : return "SQL_C_BIT";
2079 0 : case SQL_C_STINYINT:
2080 0 : return "SQL_C_STINYINT";
2081 0 : case SQL_C_UTINYINT:
2082 0 : return "SQL_C_UTINYINT";
2083 0 : case SQL_C_TINYINT:
2084 0 : return "SQL_C_TINYINT";
2085 0 : case SQL_C_SSHORT:
2086 0 : return "SQL_C_SSHORT";
2087 0 : case SQL_C_USHORT:
2088 0 : return "SQL_C_USHORT";
2089 0 : case SQL_C_SHORT:
2090 0 : return "SQL_C_SHORT";
2091 0 : case SQL_C_SLONG:
2092 0 : return "SQL_C_SLONG";
2093 0 : case SQL_C_ULONG:
2094 0 : return "SQL_C_ULONG";
2095 0 : case SQL_C_LONG:
2096 0 : return "SQL_C_LONG";
2097 0 : case SQL_C_SBIGINT:
2098 0 : return "SQL_C_SBIGINT";
2099 0 : case SQL_C_UBIGINT:
2100 0 : return "SQL_C_UBIGINT";
2101 0 : case SQL_C_NUMERIC:
2102 0 : return "SQL_C_NUMERIC";
2103 0 : case SQL_C_FLOAT:
2104 0 : return "SQL_C_FLOAT";
2105 0 : case SQL_C_DOUBLE:
2106 0 : return "SQL_C_DOUBLE";
2107 0 : case SQL_C_TYPE_DATE:
2108 0 : return "SQL_C_TYPE_DATE";
2109 0 : case SQL_C_TYPE_TIME:
2110 0 : return "SQL_C_TYPE_TIME";
2111 0 : case SQL_C_TYPE_TIMESTAMP:
2112 0 : return "SQL_C_TYPE_TIMESTAMP";
2113 0 : case SQL_C_INTERVAL_YEAR:
2114 0 : return "SQL_C_INTERVAL_YEAR";
2115 0 : case SQL_C_INTERVAL_MONTH:
2116 0 : return "SQL_C_INTERVAL_MONTH";
2117 0 : case SQL_C_INTERVAL_YEAR_TO_MONTH:
2118 0 : return "SQL_C_INTERVAL_YEAR_TO_MONTH";
2119 0 : case SQL_C_INTERVAL_DAY:
2120 0 : return "SQL_C_INTERVAL_DAY";
2121 0 : case SQL_C_INTERVAL_HOUR:
2122 0 : return "SQL_C_INTERVAL_HOUR";
2123 0 : case SQL_C_INTERVAL_MINUTE:
2124 0 : return "SQL_C_INTERVAL_MINUTE";
2125 0 : case SQL_C_INTERVAL_SECOND:
2126 0 : return "SQL_C_INTERVAL_SECOND";
2127 0 : case SQL_C_INTERVAL_DAY_TO_HOUR:
2128 0 : return "SQL_C_INTERVAL_DAY_TO_HOUR";
2129 0 : case SQL_C_INTERVAL_DAY_TO_MINUTE:
2130 0 : return "SQL_C_INTERVAL_DAY_TO_MINUTE";
2131 0 : case SQL_C_INTERVAL_DAY_TO_SECOND:
2132 0 : return "SQL_C_INTERVAL_DAY_TO_SECOND";
2133 0 : case SQL_C_INTERVAL_HOUR_TO_MINUTE:
2134 0 : return "SQL_C_INTERVAL_HOUR_TO_MINUTE";
2135 0 : case SQL_C_INTERVAL_HOUR_TO_SECOND:
2136 0 : return "SQL_C_INTERVAL_HOUR_TO_SECOND";
2137 0 : case SQL_C_INTERVAL_MINUTE_TO_SECOND:
2138 0 : return "SQL_C_INTERVAL_MINUTE_TO_SECOND";
2139 0 : case SQL_C_GUID:
2140 0 : return "SQL_C_GUID";
2141 0 : case SQL_C_DEFAULT:
2142 0 : return "SQL_C_DEFAULT";
2143 0 : case SQL_ARD_TYPE:
2144 0 : return "SQL_ARD_TYPE";
2145 0 : case SQL_DATETIME:
2146 0 : return "SQL_DATETIME";
2147 0 : case SQL_INTERVAL:
2148 0 : return "SQL_INTERVAL";
2149 0 : default:
2150 0 : snprintf(unknown, sizeof(unknown), "unknown (%d)",
2151 : (int) ValueType);
2152 0 : return unknown;
2153 : }
2154 : }
2155 :
2156 : char *
2157 0 : translateSQLType(SQLSMALLINT ParameterType)
2158 : {
2159 0 : switch (ParameterType) {
2160 : case SQL_CHAR:
2161 : return "SQL_CHAR";
2162 0 : case SQL_VARCHAR:
2163 0 : return "SQL_VARCHAR";
2164 0 : case SQL_LONGVARCHAR:
2165 0 : return "SQL_LONGVARCHAR";
2166 0 : case SQL_BINARY:
2167 0 : return "SQL_BINARY";
2168 0 : case SQL_VARBINARY:
2169 0 : return "SQL_VARBINARY";
2170 0 : case SQL_LONGVARBINARY:
2171 0 : return "SQL_LONGVARBINARY";
2172 0 : case SQL_TYPE_DATE:
2173 0 : return "SQL_TYPE_DATE";
2174 0 : case SQL_INTERVAL_MONTH:
2175 0 : return "SQL_INTERVAL_MONTH";
2176 0 : case SQL_INTERVAL_YEAR:
2177 0 : return "SQL_INTERVAL_YEAR";
2178 0 : case SQL_INTERVAL_YEAR_TO_MONTH:
2179 0 : return "SQL_INTERVAL_YEAR_TO_MONTH";
2180 0 : case SQL_INTERVAL_DAY:
2181 0 : return "SQL_INTERVAL_DAY";
2182 0 : case SQL_INTERVAL_HOUR:
2183 0 : return "SQL_INTERVAL_HOUR";
2184 0 : case SQL_INTERVAL_MINUTE:
2185 0 : return "SQL_INTERVAL_MINUTE";
2186 0 : case SQL_INTERVAL_DAY_TO_HOUR:
2187 0 : return "SQL_INTERVAL_DAY_TO_HOUR";
2188 0 : case SQL_INTERVAL_DAY_TO_MINUTE:
2189 0 : return "SQL_INTERVAL_DAY_TO_MINUTE";
2190 0 : case SQL_INTERVAL_HOUR_TO_MINUTE:
2191 0 : return "SQL_INTERVAL_HOUR_TO_MINUTE";
2192 0 : case SQL_TYPE_TIME:
2193 0 : return "SQL_TYPE_TIME";
2194 0 : case SQL_TYPE_TIMESTAMP:
2195 0 : return "SQL_TYPE_TIMESTAMP";
2196 0 : case SQL_INTERVAL_SECOND:
2197 0 : return "SQL_INTERVAL_SECOND";
2198 0 : case SQL_INTERVAL_DAY_TO_SECOND:
2199 0 : return "SQL_INTERVAL_DAY_TO_SECOND";
2200 0 : case SQL_INTERVAL_HOUR_TO_SECOND:
2201 0 : return "SQL_INTERVAL_HOUR_TO_SECOND";
2202 0 : case SQL_INTERVAL_MINUTE_TO_SECOND:
2203 0 : return "SQL_INTERVAL_MINUTE_TO_SECOND";
2204 0 : case SQL_DECIMAL:
2205 0 : return "SQL_DECIMAL";
2206 0 : case SQL_NUMERIC:
2207 0 : return "SQL_NUMERIC";
2208 0 : case SQL_FLOAT:
2209 0 : return "SQL_FLOAT";
2210 0 : case SQL_REAL:
2211 0 : return "SQL_REAL";
2212 0 : case SQL_DOUBLE:
2213 0 : return "SQL_DOUBLE";
2214 0 : case SQL_WCHAR:
2215 0 : return "SQL_WCHAR";
2216 0 : case SQL_WVARCHAR:
2217 0 : return "SQL_WVARCHAR";
2218 0 : case SQL_WLONGVARCHAR:
2219 0 : return "SQL_WLONGVARCHAR";
2220 0 : case SQL_BIT:
2221 0 : return "SQL_BIT";
2222 0 : case SQL_TINYINT:
2223 0 : return "SQL_TINYINT";
2224 0 : case SQL_SMALLINT:
2225 0 : return "SQL_SMALLINT";
2226 0 : case SQL_INTEGER:
2227 0 : return "SQL_INTEGER";
2228 0 : case SQL_BIGINT:
2229 0 : return "SQL_BIGINT";
2230 0 : case SQL_HUGEINT:
2231 0 : return "SQL_HUGEINT";
2232 0 : case SQL_GUID:
2233 0 : return "SQL_GUID";
2234 0 : case SQL_DATETIME:
2235 0 : return "SQL_DATETIME";
2236 0 : case SQL_INTERVAL:
2237 0 : return "SQL_INTERVAL";
2238 0 : default:
2239 0 : snprintf(unknown, sizeof(unknown), "unknown (%d)",
2240 : (int) ParameterType);
2241 0 : return unknown;
2242 : }
2243 : }
2244 :
2245 : char *
2246 0 : translateFieldIdentifier(SQLSMALLINT FieldIdentifier)
2247 : {
2248 0 : switch (FieldIdentifier) {
2249 : case SQL_COLUMN_LENGTH:
2250 : return "SQL_COLUMN_LENGTH";
2251 0 : case SQL_COLUMN_PRECISION:
2252 0 : return "SQL_COLUMN_PRECISION";
2253 0 : case SQL_COLUMN_SCALE:
2254 0 : return "SQL_COLUMN_SCALE";
2255 0 : case SQL_DESC_ALLOC_TYPE:
2256 0 : return "SQL_DESC_ALLOC_TYPE";
2257 0 : case SQL_DESC_ARRAY_SIZE:
2258 0 : return "SQL_DESC_ARRAY_SIZE";
2259 0 : case SQL_DESC_ARRAY_STATUS_PTR:
2260 0 : return "SQL_DESC_ARRAY_STATUS_PTR";
2261 0 : case SQL_DESC_AUTO_UNIQUE_VALUE:
2262 0 : return "SQL_DESC_AUTO_UNIQUE_VALUE";
2263 0 : case SQL_DESC_BASE_COLUMN_NAME:
2264 0 : return "SQL_DESC_BASE_COLUMN_NAME";
2265 0 : case SQL_DESC_BASE_TABLE_NAME:
2266 0 : return "SQL_DESC_BASE_TABLE_NAME";
2267 0 : case SQL_DESC_BIND_OFFSET_PTR:
2268 0 : return "SQL_DESC_BIND_OFFSET_PTR";
2269 0 : case SQL_DESC_BIND_TYPE:
2270 0 : return "SQL_DESC_BIND_TYPE";
2271 0 : case SQL_DESC_CASE_SENSITIVE:
2272 0 : return "SQL_DESC_CASE_SENSITIVE";
2273 0 : case SQL_DESC_CATALOG_NAME:
2274 0 : return "SQL_DESC_CATALOG_NAME";
2275 0 : case SQL_DESC_CONCISE_TYPE:
2276 0 : return "SQL_DESC_CONCISE_TYPE";
2277 0 : case SQL_DESC_COUNT:
2278 0 : return "SQL_DESC_COUNT";
2279 0 : case SQL_DESC_DATA_PTR:
2280 0 : return "SQL_DESC_DATA_PTR";
2281 0 : case SQL_DESC_DATETIME_INTERVAL_CODE:
2282 0 : return "SQL_DESC_DATETIME_INTERVAL_CODE";
2283 0 : case SQL_DESC_DATETIME_INTERVAL_PRECISION:
2284 0 : return "SQL_DESC_DATETIME_INTERVAL_PRECISION";
2285 0 : case SQL_DESC_DISPLAY_SIZE:
2286 0 : return "SQL_DESC_DISPLAY_SIZE";
2287 0 : case SQL_DESC_FIXED_PREC_SCALE:
2288 0 : return "SQL_DESC_FIXED_PREC_SCALE";
2289 0 : case SQL_DESC_INDICATOR_PTR:
2290 0 : return "SQL_DESC_INDICATOR_PTR";
2291 0 : case SQL_DESC_LABEL:
2292 0 : return "SQL_DESC_LABEL";
2293 0 : case SQL_DESC_LENGTH:
2294 0 : return "SQL_DESC_LENGTH";
2295 0 : case SQL_DESC_LITERAL_PREFIX:
2296 0 : return "SQL_DESC_LITERAL_PREFIX";
2297 0 : case SQL_DESC_LITERAL_SUFFIX:
2298 0 : return "SQL_DESC_LITERAL_SUFFIX";
2299 0 : case SQL_DESC_LOCAL_TYPE_NAME:
2300 0 : return "SQL_DESC_LOCAL_TYPE_NAME";
2301 0 : case SQL_DESC_NAME:
2302 0 : return "SQL_DESC_NAME";
2303 0 : case SQL_DESC_NULLABLE:
2304 0 : return "SQL_DESC_NULLABLE";
2305 0 : case SQL_DESC_NUM_PREC_RADIX:
2306 0 : return "SQL_DESC_NUM_PREC_RADIX";
2307 0 : case SQL_DESC_OCTET_LENGTH:
2308 0 : return "SQL_DESC_OCTET_LENGTH";
2309 0 : case SQL_DESC_OCTET_LENGTH_PTR:
2310 0 : return "SQL_DESC_OCTET_LENGTH_PTR";
2311 0 : case SQL_DESC_PARAMETER_TYPE:
2312 0 : return "SQL_DESC_PARAMETER_TYPE";
2313 0 : case SQL_DESC_PRECISION:
2314 0 : return "SQL_DESC_PRECISION";
2315 0 : case SQL_DESC_ROWS_PROCESSED_PTR:
2316 0 : return "SQL_DESC_ROWS_PROCESSED_PTR";
2317 0 : case SQL_DESC_ROWVER:
2318 0 : return "SQL_DESC_ROWVER";
2319 0 : case SQL_DESC_SCALE:
2320 0 : return "SQL_DESC_SCALE";
2321 0 : case SQL_DESC_SCHEMA_NAME:
2322 0 : return "SQL_DESC_SCHEMA_NAME";
2323 0 : case SQL_DESC_SEARCHABLE:
2324 0 : return "SQL_DESC_SEARCHABLE";
2325 0 : case SQL_DESC_TABLE_NAME:
2326 0 : return "SQL_DESC_TABLE_NAME";
2327 0 : case SQL_DESC_TYPE:
2328 0 : return "SQL_DESC_TYPE";
2329 0 : case SQL_DESC_TYPE_NAME:
2330 0 : return "SQL_DESC_TYPE_NAME";
2331 0 : case SQL_DESC_UNNAMED:
2332 0 : return "SQL_DESC_UNNAMED";
2333 0 : case SQL_DESC_UNSIGNED:
2334 0 : return "SQL_DESC_UNSIGNED";
2335 0 : case SQL_DESC_UPDATABLE:
2336 0 : return "SQL_DESC_UPDATABLE";
2337 0 : default:
2338 0 : snprintf(unknown, sizeof(unknown), "unknown (%d)",
2339 : (int) FieldIdentifier);
2340 0 : return unknown;
2341 : }
2342 : }
2343 :
2344 : char *
2345 0 : translateFetchOrientation(SQLUSMALLINT FetchOrientation)
2346 : {
2347 0 : switch (FetchOrientation) {
2348 : case SQL_FETCH_NEXT:
2349 : return "SQL_FETCH_NEXT";
2350 0 : case SQL_FETCH_FIRST:
2351 0 : return "SQL_FETCH_FIRST";
2352 0 : case SQL_FETCH_LAST:
2353 0 : return "SQL_FETCH_LAST";
2354 0 : case SQL_FETCH_PRIOR:
2355 0 : return "SQL_FETCH_PRIOR";
2356 0 : case SQL_FETCH_RELATIVE:
2357 0 : return "SQL_FETCH_RELATIVE";
2358 0 : case SQL_FETCH_ABSOLUTE:
2359 0 : return "SQL_FETCH_ABSOLUTE";
2360 0 : case SQL_FETCH_BOOKMARK:
2361 0 : return "SQL_FETCH_BOOKMARK";
2362 0 : default:
2363 0 : snprintf(unknown, sizeof(unknown), "unknown (%u)", (unsigned int) FetchOrientation);
2364 0 : return unknown;
2365 : }
2366 : }
2367 :
2368 : char *
2369 0 : translateConnectAttribute(SQLINTEGER Attribute)
2370 : {
2371 0 : switch (Attribute) {
2372 : case SQL_ATTR_ACCESS_MODE:
2373 : return "SQL_ATTR_ACCESS_MODE";
2374 : #ifdef SQL_ATTR_ANSI_APP
2375 0 : case SQL_ATTR_ANSI_APP:
2376 0 : return "SQL_ATTR_ANSI_APP";
2377 : #endif
2378 : #ifdef SQL_ATTR_ASYNC_DBC_EVENT
2379 : case SQL_ATTR_ASYNC_DBC_EVENT:
2380 : return "SQL_ATTR_ASYNC_DBC_EVENT";
2381 : #endif
2382 : #ifdef SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE
2383 : case SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE:
2384 : return "SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE";
2385 : #endif
2386 : #ifdef SQL_ATTR_ASYNC_DBC_PCALLBACK
2387 : case SQL_ATTR_ASYNC_DBC_PCALLBACK:
2388 : return "SQL_ATTR_ASYNC_DBC_PCALLBACK";
2389 : #endif
2390 : #ifdef SQL_ATTR_ASYNC_DBC_PCONTEXT
2391 : case SQL_ATTR_ASYNC_DBC_PCONTEXT:
2392 : return "SQL_ATTR_ASYNC_DBC_PCONTEXT";
2393 : #endif
2394 0 : case SQL_ATTR_ASYNC_ENABLE:
2395 0 : return "SQL_ATTR_ASYNC_ENABLE";
2396 0 : case SQL_ATTR_AUTOCOMMIT:
2397 0 : return "SQL_ATTR_AUTOCOMMIT";
2398 0 : case SQL_ATTR_AUTO_IPD:
2399 0 : return "SQL_ATTR_AUTO_IPD";
2400 0 : case SQL_ATTR_CONNECTION_DEAD:
2401 0 : return "SQL_ATTR_CONNECTION_DEAD";
2402 0 : case SQL_ATTR_CONNECTION_TIMEOUT:
2403 0 : return "SQL_ATTR_CONNECTION_TIMEOUT";
2404 0 : case SQL_ATTR_CURRENT_CATALOG:
2405 0 : return "SQL_ATTR_CURRENT_CATALOG";
2406 : #ifdef SQL_ATTR_DBC_INFO_TOKEN
2407 : case SQL_ATTR_DBC_INFO_TOKEN:
2408 : return "SQL_ATTR_DBC_INFO_TOKEN";
2409 : #endif
2410 0 : case SQL_ATTR_DISCONNECT_BEHAVIOR:
2411 0 : return "SQL_ATTR_DISCONNECT_BEHAVIOR";
2412 0 : case SQL_ATTR_ENLIST_IN_DTC:
2413 0 : return "SQL_ATTR_ENLIST_IN_DTC";
2414 0 : case SQL_ATTR_ENLIST_IN_XA:
2415 0 : return "SQL_ATTR_ENLIST_IN_XA";
2416 0 : case SQL_ATTR_LOGIN_TIMEOUT:
2417 0 : return "SQL_ATTR_LOGIN_TIMEOUT";
2418 0 : case SQL_ATTR_METADATA_ID:
2419 0 : return "SQL_ATTR_METADATA_ID";
2420 0 : case SQL_ATTR_ODBC_CURSORS:
2421 0 : return "SQL_ATTR_ODBC_CURSORS";
2422 0 : case SQL_ATTR_PACKET_SIZE:
2423 0 : return "SQL_ATTR_PACKET_SIZE";
2424 0 : case SQL_ATTR_QUIET_MODE:
2425 0 : return "SQL_ATTR_QUIET_MODE";
2426 0 : case SQL_ATTR_TRACE:
2427 0 : return "SQL_ATTR_TRACE";
2428 0 : case SQL_ATTR_TRACEFILE:
2429 0 : return "SQL_ATTR_TRACEFILE";
2430 0 : case SQL_ATTR_TRANSLATE_LIB:
2431 0 : return "SQL_ATTR_TRANSLATE_LIB";
2432 0 : case SQL_ATTR_TRANSLATE_OPTION:
2433 0 : return "SQL_ATTR_TRANSLATE_OPTION";
2434 0 : case SQL_ATTR_TXN_ISOLATION:
2435 0 : return "SQL_ATTR_TXN_ISOLATION";
2436 0 : default:
2437 0 : snprintf(unknown, sizeof(unknown), "unknown (%d)",
2438 : (int) Attribute);
2439 0 : return unknown;
2440 : }
2441 : }
2442 :
2443 : char *
2444 0 : translateConnectOption(SQLUSMALLINT Option)
2445 : {
2446 0 : switch (Option) {
2447 : case SQL_ACCESS_MODE:
2448 : return "SQL_ACCESS_MODE";
2449 0 : case SQL_AUTOCOMMIT:
2450 0 : return "SQL_AUTOCOMMIT";
2451 0 : case SQL_LOGIN_TIMEOUT:
2452 0 : return "SQL_LOGIN_TIMEOUT";
2453 0 : case SQL_ODBC_CURSORS:
2454 0 : return "SQL_ODBC_CURSORS";
2455 0 : case SQL_OPT_TRACE:
2456 0 : return "SQL_OPT_TRACE";
2457 0 : case SQL_PACKET_SIZE:
2458 0 : return "SQL_PACKET_SIZE";
2459 0 : case SQL_TRANSLATE_OPTION:
2460 0 : return "SQL_TRANSLATE_OPTION";
2461 0 : case SQL_TXN_ISOLATION:
2462 0 : return "SQL_TXN_ISOLATION";
2463 0 : case SQL_QUIET_MODE:
2464 0 : return "SQL_QUIET_MODE";
2465 0 : case SQL_CURRENT_QUALIFIER:
2466 0 : return "SQL_CURRENT_QUALIFIER";
2467 0 : case SQL_OPT_TRACEFILE:
2468 0 : return "SQL_OPT_TRACEFILE";
2469 0 : case SQL_TRANSLATE_DLL:
2470 0 : return "SQL_TRANSLATE_DLL";
2471 0 : default:
2472 0 : return translateConnectAttribute((SQLSMALLINT) Option);
2473 : }
2474 : }
2475 :
2476 : char *
2477 0 : translateEnvAttribute(SQLINTEGER Attribute)
2478 : {
2479 0 : switch (Attribute) {
2480 : case SQL_ATTR_ODBC_VERSION:
2481 : return "SQL_ATTR_ODBC_VERSION";
2482 0 : case SQL_ATTR_OUTPUT_NTS:
2483 0 : return "SQL_ATTR_OUTPUT_NTS";
2484 0 : case SQL_ATTR_CONNECTION_POOLING:
2485 0 : return "SQL_ATTR_CONNECTION_POOLING";
2486 0 : case SQL_ATTR_CP_MATCH:
2487 0 : return "SQL_ATTR_CP_MATCH";
2488 0 : default:
2489 0 : snprintf(unknown, sizeof(unknown), "unknown (%d)",
2490 : (int) Attribute);
2491 0 : return unknown;
2492 : }
2493 : }
2494 :
2495 : char *
2496 0 : translateStmtAttribute(SQLINTEGER Attribute)
2497 : {
2498 0 : switch (Attribute) {
2499 : case SQL_ATTR_APP_PARAM_DESC:
2500 : return "SQL_ATTR_APP_PARAM_DESC";
2501 0 : case SQL_ATTR_APP_ROW_DESC:
2502 0 : return "SQL_ATTR_APP_ROW_DESC";
2503 0 : case SQL_ATTR_ASYNC_ENABLE:
2504 0 : return "SQL_ATTR_ASYNC_ENABLE";
2505 0 : case SQL_ATTR_CONCURRENCY:
2506 0 : return "SQL_ATTR_CONCURRENCY";
2507 0 : case SQL_ATTR_CURSOR_SCROLLABLE:
2508 0 : return "SQL_ATTR_CURSOR_SCROLLABLE";
2509 0 : case SQL_ATTR_CURSOR_SENSITIVITY:
2510 0 : return "SQL_ATTR_CURSOR_SENSITIVITY";
2511 0 : case SQL_ATTR_CURSOR_TYPE:
2512 0 : return "SQL_ATTR_CURSOR_TYPE";
2513 0 : case SQL_ATTR_IMP_PARAM_DESC:
2514 0 : return "SQL_ATTR_IMP_PARAM_DESC";
2515 0 : case SQL_ATTR_IMP_ROW_DESC:
2516 0 : return "SQL_ATTR_IMP_ROW_DESC";
2517 0 : case SQL_ATTR_MAX_LENGTH:
2518 0 : return "SQL_ATTR_MAX_LENGTH";
2519 0 : case SQL_ATTR_MAX_ROWS:
2520 0 : return "SQL_ATTR_MAX_ROWS";
2521 0 : case SQL_ATTR_NOSCAN:
2522 0 : return "SQL_ATTR_NOSCAN";
2523 0 : case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
2524 0 : return "SQL_ATTR_PARAM_BIND_OFFSET_PTR";
2525 0 : case SQL_ATTR_PARAM_BIND_TYPE:
2526 0 : return "SQL_ATTR_PARAM_BIND_TYPE";
2527 0 : case SQL_ATTR_PARAM_OPERATION_PTR:
2528 0 : return "SQL_ATTR_PARAM_OPERATION_PTR";
2529 0 : case SQL_ATTR_PARAM_STATUS_PTR:
2530 0 : return "SQL_ATTR_PARAM_STATUS_PTR";
2531 0 : case SQL_ATTR_PARAMS_PROCESSED_PTR:
2532 0 : return "SQL_ATTR_PARAMS_PROCESSED_PTR";
2533 0 : case SQL_ATTR_PARAMSET_SIZE:
2534 0 : return "SQL_ATTR_PARAMSET_SIZE";
2535 0 : case SQL_ATTR_RETRIEVE_DATA:
2536 0 : return "SQL_ATTR_RETRIEVE_DATA";
2537 0 : case SQL_ATTR_ROW_ARRAY_SIZE:
2538 0 : return "SQL_ATTR_ROW_ARRAY_SIZE";
2539 0 : case SQL_ROWSET_SIZE:
2540 0 : return "SQL_ROWSET_SIZE";
2541 0 : case SQL_ATTR_ROW_BIND_OFFSET_PTR:
2542 0 : return "SQL_ATTR_ROW_BIND_OFFSET_PTR";
2543 0 : case SQL_ATTR_ROW_BIND_TYPE:
2544 0 : return "SQL_ATTR_ROW_BIND_TYPE";
2545 0 : case SQL_ATTR_ROW_NUMBER:
2546 0 : return "SQL_ATTR_ROW_NUMBER";
2547 0 : case SQL_ATTR_ROW_OPERATION_PTR:
2548 0 : return "SQL_ATTR_ROW_OPERATION_PTR";
2549 0 : case SQL_ATTR_ROW_STATUS_PTR:
2550 0 : return "SQL_ATTR_ROW_STATUS_PTR";
2551 0 : case SQL_ATTR_ROWS_FETCHED_PTR:
2552 0 : return "SQL_ATTR_ROWS_FETCHED_PTR";
2553 0 : case SQL_ATTR_METADATA_ID:
2554 0 : return "SQL_ATTR_METADATA_ID";
2555 0 : case SQL_ATTR_ENABLE_AUTO_IPD:
2556 0 : return "SQL_ATTR_ENABLE_AUTO_IPD";
2557 0 : case SQL_ATTR_FETCH_BOOKMARK_PTR:
2558 0 : return "SQL_ATTR_FETCH_BOOKMARK_PTR";
2559 0 : case SQL_ATTR_KEYSET_SIZE:
2560 0 : return "SQL_ATTR_KEYSET_SIZE";
2561 0 : case SQL_ATTR_QUERY_TIMEOUT:
2562 0 : return "SQL_ATTR_QUERY_TIMEOUT";
2563 0 : case SQL_ATTR_SIMULATE_CURSOR:
2564 0 : return "SQL_ATTR_SIMULATE_CURSOR";
2565 0 : case SQL_ATTR_USE_BOOKMARKS:
2566 0 : return "SQL_ATTR_USE_BOOKMARKS";
2567 0 : default:
2568 0 : snprintf(unknown, sizeof(unknown), "unknown (%d)",
2569 : (int) Attribute);
2570 0 : return unknown;
2571 : }
2572 : }
2573 :
2574 : char *
2575 0 : translateStmtOption(SQLUSMALLINT Option)
2576 : {
2577 0 : switch (Option) {
2578 : case SQL_QUERY_TIMEOUT:
2579 : return "SQL_QUERY_TIMEOUT";
2580 0 : case SQL_MAX_ROWS:
2581 0 : return "SQL_MAX_ROWS";
2582 0 : case SQL_NOSCAN:
2583 0 : return "SQL_NOSCAN";
2584 0 : case SQL_MAX_LENGTH:
2585 0 : return "SQL_MAX_LENGTH";
2586 0 : case SQL_ASYNC_ENABLE:
2587 0 : return "SQL_ASYNC_ENABLE";
2588 0 : case SQL_BIND_TYPE:
2589 0 : return "SQL_BIND_TYPE";
2590 0 : case SQL_CURSOR_TYPE:
2591 0 : return "SQL_CURSOR_TYPE";
2592 0 : case SQL_CONCURRENCY:
2593 0 : return "SQL_CONCURRENCY";
2594 0 : case SQL_KEYSET_SIZE:
2595 0 : return "SQL_KEYSET_SIZE";
2596 0 : case SQL_ROWSET_SIZE:
2597 0 : return "SQL_ROWSET_SIZE";
2598 0 : case SQL_SIMULATE_CURSOR:
2599 0 : return "SQL_SIMULATE_CURSOR";
2600 0 : case SQL_RETRIEVE_DATA:
2601 0 : return "SQL_RETRIEVE_DATA";
2602 0 : case SQL_USE_BOOKMARKS:
2603 0 : return "SQL_USE_BOOKMARKS";
2604 0 : case SQL_ROW_NUMBER:
2605 0 : return "SQL_ROW_NUMBER";
2606 0 : default:
2607 0 : snprintf(unknown, sizeof(unknown), "unknown (%u)", (unsigned int) Option);
2608 0 : return unknown;
2609 : }
2610 : }
2611 :
2612 : char *
2613 0 : translateCompletionType(SQLSMALLINT CompletionType)
2614 : {
2615 0 : switch (CompletionType) {
2616 : case SQL_COMMIT:
2617 : return "SQL_COMMIT";
2618 0 : case SQL_ROLLBACK:
2619 0 : return "SQL_ROLLBACK";
2620 0 : default:
2621 0 : snprintf(unknown, sizeof(unknown), "unknown (%d)",
2622 : (int) CompletionType);
2623 0 : return unknown;
2624 : }
2625 : }
2626 :
2627 : #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901
2628 : void
2629 : ODBCLOG(const char *fmt, ...)
2630 : {
2631 : va_list ap;
2632 :
2633 : va_start(ap, fmt);
2634 : if (ODBCdebug == NULL) {
2635 : #ifdef NATIVE_WIN32
2636 : if ((ODBCdebug = _wgetenv(L"ODBCDEBUG")) == NULL)
2637 : ODBCdebug = _wcsdup(L"");
2638 : else
2639 : ODBCdebug = _wcsdup(ODBCdebug);
2640 : #else
2641 : if ((ODBCdebug = getenv("ODBCDEBUG")) == NULL)
2642 : ODBCdebug = strdup("");
2643 : else
2644 : ODBCdebug = strdup(ODBCdebug);
2645 : #endif
2646 : }
2647 : if (ODBCdebug != NULL && *ODBCdebug != 0) {
2648 : FILE *f;
2649 :
2650 : #ifdef NATIVE_WIN32
2651 : f = _wfopen(ODBCdebug, L"a");
2652 : #else
2653 : f = fopen(ODBCdebug, "a");
2654 : #endif
2655 : if (f) {
2656 : vfprintf(f, fmt, ap);
2657 : fclose(f);
2658 : } else
2659 : vfprintf(stderr, fmt, ap);
2660 : }
2661 : va_end(ap);
2662 : }
2663 : #endif
2664 : #endif
|