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