sqlite3odbc.c
Go to the documentation of this file.
1
14#if defined(SQLITE_HAS_CODEC) && defined(SQLITE_API)
15#undef WITH_SQLITE_DLLS
16#undef SQLITE_DYNLOAD
17#include "sqlite3.c"
18#endif
19
20#if defined(WITH_SQLITE_DLLS) && (WITH_SQLITE_DLLS > 1)
21#define SQLITE_DYNLOAD 1
22#undef HAVE_SQLITE3CLOSEV2
23#endif
24
25#include "sqlite3odbc.h"
26
27#ifdef SQLITE_DYNLOAD
28
29#undef MEMORY_DEBUG
30
31#if defined(_WIN32) || defined(_WIN64)
32static void dls_init(void);
33static void dls_fini(void);
34#else
35void dls_init(void);
36void dls_fini(void);
37#endif
38
39static struct dl_sqlite3_funcs {
40 void (*activate_see)(const char *p0);
41 int (*bind_blob)(sqlite3_stmt *p0, int p1, const void *p2, int p3,
42 void (*p4)(void *));
43 int (*bind_double)(sqlite3_stmt *p0, int p1, double p2);
44 int (*bind_int)(sqlite3_stmt *p0, int p1, int p2);
45 int (*bind_int64)(sqlite3_stmt *p0, int p1, sqlite_int64 p2);
46 int (*bind_null)(sqlite3_stmt *p0, int p1);
47 int (*bind_parameter_count)(sqlite3_stmt *p0);
48 int (*bind_text)(sqlite3_stmt *p0, int p1, const char *p2, int p3,
49 void (*p4)(void *));
50 int (*busy_handler)(sqlite3 *p0, int (*p2)(void *, int), void *p3);
51 int (*changes)(sqlite3 *p0);
52 int (*close)(sqlite3 *p0);
53 const void * (*column_blob)(sqlite3_stmt *p0, int p1);
54 int (*column_bytes)(sqlite3_stmt *p0, int p1);
55 int (*column_count)(sqlite3_stmt *p0);
56 const char * (*column_database_name)(sqlite3_stmt *p0, int p1);
57 const char * (*column_decltype)(sqlite3_stmt *p0, int p1);
58 double (*column_double)(sqlite3_stmt *p0, int p1);
59 const char * (*column_name)(sqlite3_stmt *p0, int p1);
60 const char * (*column_origin_name)(sqlite3_stmt *p0, int p1);
61 const char * (*column_table_name)(sqlite3_stmt *p0, int p1);
62 const unsigned char * (*column_text)(sqlite3_stmt *p0, int p1);
63 int (*column_type)(sqlite3_stmt *p0, int p1);
64 int (*create_function)(sqlite3 *p0, const char *p1, int p2, int p3,
65 void *p4,
66 void (*p5)(sqlite3_context *, int, sqlite3_value **),
67 void (*p6)(sqlite3_context *, int, sqlite3_value **),
68 void (*p7)(sqlite3_context *));
69 int (*enable_load_extension)(sqlite3 *p0, int p1);
70 int (*errcode)(sqlite3 *p0);
71 const char * (*errmsg)(sqlite3 *p0);
72 int (*exec)(sqlite3 *p0, const char *p1,
73 int (*p2)(void *, int, char **, char **),
74 void *p3, char **p4);
75 int (*finalize)(sqlite3_stmt *p0);
76 void (*free)(void *p0);
77 void (*free_table)(char **p0);
78 int (*get_table)(sqlite3 *p0, const char *p1, char ***p2,
79 int *p3, int *p4, char **p5);
80 void (*interrupt)(sqlite3 *p0);
81 int (*key)(sqlite3 *p0, const void *p1, int p2);
82 sqlite_int64 (*last_insert_rowid)(sqlite3 *p0);
83 const char * (*libversion)(void);
84 int (*load_extension)(sqlite3 *p0, const char *p1, const char *p2,
85 char **p3);
86 void * (*malloc)(int p0);
87 char * (*mprintf)(const char *p0, ...);
88 int (*open)(const char *p0, sqlite3 **p1);
89 int (*open16)(const void *p0, sqlite3 **p1);
90 int (*open_v2)(const char *p0, sqlite3 **p1, int p2, const char *p3);
91 int (*prepare)(sqlite3 *p0, const char *p1, int p2, sqlite3_stmt **p3,
92 const char **p4);
93 int (*prepare_v2)(sqlite3 *p0, const char *p1, int p2, sqlite3_stmt **p3,
94 const char **p4);
95 void * (*profile)(sqlite3 *p0,
96 void (*p1)(void *, const char *, sqlite3_uint64),
97 void *p2);
98 void * (*realloc)(void *p0, int p1);
99 int (*rekey)(sqlite3 *p0, const void *p1, int p2);
100 int (*reset)(sqlite3_stmt *p0);
101 void (*result_blob)(sqlite3_context *p0, const void *p1,
102 int p2, void (*p3)(void *));
103 void (*result_error)(sqlite3_context *p0, const char *p1, int p2);
104 void (*result_int)(sqlite3_context *p0, int p1);
105 void (*result_null)(sqlite3_context *p0);
106 int (*step)(sqlite3_stmt *p0);
107 int (*xstrnicmp)(const char *p0, const char *p1, int p2);
108 int (*table_column_metadata)(sqlite3 *p0, const char *p1,
109 const char *p2, const char *p3,
110 char const **p4, char const **p5,
111 int *p6, int *p7, int *p8);
112 void * (*trace)(sqlite3 *p0, void (*p1)(void *, const char *), void *p2);
113 void * (*user_data)(sqlite3_context *p0);
114 const void * (*value_blob)(sqlite3_value *p0);
115 int (*value_bytes)(sqlite3_value *p0);
116 const unsigned char * (*value_text)(sqlite3_value *p0);
117 int (*value_type)(sqlite3_value *p0);
118} dls_funcs;
119
120#define sqlite3_activate_see dls_funcs.activate_see
121#define sqlite3_bind_blob dls_funcs.bind_blob
122#define sqlite3_bind_double dls_funcs.bind_double
123#define sqlite3_bind_int dls_funcs.bind_int
124#define sqlite3_bind_int64 dls_funcs.bind_int64
125#define sqlite3_bind_null dls_funcs.bind_null
126#define sqlite3_bind_parameter_count dls_funcs.bind_parameter_count
127#define sqlite3_bind_text dls_funcs.bind_text
128#define sqlite3_busy_handler dls_funcs.busy_handler
129#define sqlite3_changes dls_funcs.changes
130#define sqlite3_close dls_funcs.close
131#define sqlite3_column_blob dls_funcs.column_blob
132#define sqlite3_column_bytes dls_funcs.column_bytes
133#define sqlite3_column_count dls_funcs.column_count
134#define sqlite3_column_database_name dls_funcs.column_database_name
135#define sqlite3_column_decltype dls_funcs.column_decltype
136#define sqlite3_column_double dls_funcs.column_double
137#define sqlite3_column_name dls_funcs.column_name
138#define sqlite3_column_origin_name dls_funcs.column_origin_name
139#define sqlite3_column_table_name dls_funcs.column_table_name
140#define sqlite3_column_text dls_funcs.column_text
141#define sqlite3_column_type dls_funcs.column_type
142#define sqlite3_create_function dls_funcs.create_function
143#define sqlite3_enable_load_extension dls_funcs.enable_load_extension
144#define sqlite3_errcode dls_funcs.errcode
145#define sqlite3_errmsg dls_funcs.errmsg
146#define sqlite3_exec dls_funcs.exec
147#define sqlite3_finalize dls_funcs.finalize
148#define sqlite3_free dls_funcs.free
149#define sqlite3_free_table dls_funcs.free_table
150#define sqlite3_get_table dls_funcs.get_table
151#define sqlite3_interrupt dls_funcs.interrupt
152#define sqlite3_key dls_funcs.key
153#define sqlite3_last_insert_rowid dls_funcs.last_insert_rowid
154#define sqlite3_libversion dls_funcs.libversion
155#define sqlite3_load_extension dls_funcs.load_extension
156#define sqlite3_malloc dls_funcs.malloc
157#define sqlite3_mprintf dls_funcs.mprintf
158#define sqlite3_open dls_funcs.open
159#define sqlite3_open16 dls_funcs.open16
160#define sqlite3_open_v2 dls_funcs.open_v2
161#define sqlite3_prepare dls_funcs.prepare
162#define sqlite3_prepare_v2 dls_funcs.prepare_v2
163#define sqlite3_profile dls_funcs.profile
164#define sqlite3_realloc dls_funcs.realloc
165#define sqlite3_rekey dls_funcs.rekey
166#define sqlite3_reset dls_funcs.reset
167#define sqlite3_result_blob dls_funcs.result_blob
168#define sqlite3_result_error dls_funcs.result_error
169#define sqlite3_result_int dls_funcs.result_int
170#define sqlite3_result_null dls_funcs.result_null
171#define sqlite3_step dls_funcs.step
172#define sqlite3_strnicmp dls_funcs.xstrnicmp
173#define sqlite3_table_column_metadata dls_funcs.table_column_metadata
174#define sqlite3_trace dls_funcs.trace
175#define sqlite3_user_data dls_funcs.user_data
176#define sqlite3_value_blob dls_funcs.value_blob
177#define sqlite3_value_bytes dls_funcs.value_bytes
178#define sqlite3_value_text dls_funcs.value_text
179#define sqlite3_value_type dls_funcs.value_type
180
181#endif
182
183#ifndef WITHOUT_WINTERFACE
184#define WINTERFACE
185#define WCHARSUPPORT
186#endif
187
188#if !defined(_WIN32) && !defined(_WIN64)
189#if !defined(WCHARSUPPORT) && defined(HAVE_SQLWCHAR) && (HAVE_SQLWCHAR)
190#define WCHARSUPPORT
191#endif
192#endif
193
194#if defined(WINTERFACE)
195#include <sqlucode.h>
196#endif
197
198#if defined(_WIN32) || defined(_WIN64)
199#include "resource3.h"
200#define ODBC_INI "ODBC.INI"
201#ifndef DRIVER_VER_INFO
202#define DRIVER_VER_INFO VERSION
203#endif
204#else
205#define ODBC_INI ".odbc.ini"
206#endif
207
208#ifndef DRIVER_VER_INFO
209#define DRIVER_VER_INFO "0.0"
210#endif
211
212#ifndef COLATTRIBUTE_LAST_ARG_TYPE
213#ifdef _WIN64
214#define COLATTRIBUTE_LAST_ARG_TYPE SQLLEN *
215#else
216#define COLATTRIBUTE_LAST_ARG_TYPE SQLPOINTER
217#endif
218#endif
219
220#ifndef SETSTMTOPTION_LAST_ARG_TYPE
221#define SETSTMTOPTION_LAST_ARG_TYPE SQLROWCOUNT
222#endif
223
224#undef min
225#define min(a, b) ((a) < (b) ? (a) : (b))
226#undef max
227#define max(a, b) ((a) < (b) ? (b) : (a))
228
229#ifndef PTRDIFF_T
230#define PTRDIFF_T int
231#endif
232
233#define array_size(x) (sizeof (x) / sizeof (x[0]))
234
235#define stringify1(s) #s
236#define stringify(s) stringify1(s)
237
238#define verinfo(maj, min, lev) ((maj) << 16 | (min) << 8 | (lev))
239
240/* Column meta data from SQLite support */
241#undef FULL_METADATA
242#if defined(HAVE_SQLITE3TABLECOLUMNMETADATA) && (HAVE_SQLITE3TABLECOLUMNMETADATA)
243#if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
244#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
245#if defined(HAVE_SQLITE3COLUMNORIGINNAME) && (HAVE_SQLITE3COLUMNORIGINNAME)
246#define FULL_METADATA 1
247#endif
248#endif
249#endif
250#endif
251
252/* Column types for static string column descriptions (SQLTables etc.) */
253
254#if defined(WINTERFACE) && !defined(_WIN32) && !defined(_WIN64)
255#define SCOL_VARCHAR SQL_WVARCHAR
256#define SCOL_CHAR SQL_WCHAR
257#else
258#define SCOL_VARCHAR SQL_VARCHAR
259#define SCOL_CHAR SQL_CHAR
260#endif
261
262#define ENV_MAGIC 0x53544145
263#define DBC_MAGIC 0x53544144
264#define DEAD_MAGIC 0xdeadbeef
265
272typedef struct dstr {
273 int len;
274 int max;
275 int oom;
276 char buffer[1];
278
279static const char *xdigits = "0123456789ABCDEFabcdef";
280
281#ifdef MEMORY_DEBUG
282
283static void *
284xmalloc_(int n, char *file, int line)
285{
286 int nn = n + 4 * sizeof (long);
287 long *p;
288
289 p = malloc(nn);
290 if (!p) {
291#if (MEMORY_DEBUG > 1)
292 fprintf(stderr, "malloc\t%d\tNULL\t%s:%d\n", n, file, line);
293#endif
294 return NULL;
295 }
296 p[0] = 0xdead1234;
297 nn = nn / sizeof (long) - 1;
298 p[1] = n;
299 p[nn] = 0xdead5678;
300#if (MEMORY_DEBUG > 1)
301 fprintf(stderr, "malloc\t%d\t%p\t%s:%d\n", n, &p[2], file, line);
302#endif
303 return (void *) &p[2];
304}
305
306static void *
307xrealloc_(void *old, int n, char *file, int line)
308{
309 int nn = n + 4 * sizeof (long), nnn;
310 long *p, *pp;
311
312 if (n == 0 || !old) {
313 return xmalloc_(n, file, line);
314 }
315 p = &((long *) old)[-2];
316 if (p[0] != 0xdead1234) {
317 fprintf(stderr, "*** low end corruption @ %p\n", old);
318 abort();
319 }
320 nnn = p[1] + 4 * sizeof (long);
321 nnn = nnn / sizeof (long) - 1;
322 if (p[nnn] != 0xdead5678) {
323 fprintf(stderr, "*** high end corruption @ %p\n", old);
324 abort();
325 }
326 pp = realloc(p, nn);
327 if (!pp) {
328#if (MEMORY_DEBUG > 1)
329 fprintf(stderr, "realloc\t%p,%d\tNULL\t%s:%d\n", old, n, file, line);
330#endif
331 return NULL;
332 }
333#if (MEMORY_DEBUG > 1)
334 fprintf(stderr, "realloc\t%p,%d\t%p\t%s:%d\n", old, n, &pp[2], file, line);
335#endif
336 p = pp;
337 p[1] = n;
338 nn = nn / sizeof (long) - 1;
339 p[nn] = 0xdead5678;
340 return (void *) &p[2];
341}
342
343static void
344xfree_(void *x, char *file, int line)
345{
346 long *p;
347 int n;
348
349 if (!x) {
350 return;
351 }
352 p = &((long *) x)[-2];
353 if (p[0] != 0xdead1234) {
354 fprintf(stderr, "*** low end corruption @ %p\n", x);
355 abort();
356 }
357 n = p[1] + 4 * sizeof (long);
358 n = n / sizeof (long) - 1;
359 if (p[n] != 0xdead5678) {
360 fprintf(stderr, "*** high end corruption @ %p\n", x);
361 abort();
362 }
363#if (MEMORY_DEBUG > 1)
364 fprintf(stderr, "free\t%p\t\t%s:%d\n", x, file, line);
365#endif
366 free(p);
367}
368
369static void
370xfree__(void *x)
371{
372 xfree_(x, "unknown location", 0);
373}
374
375static char *
376xstrdup_(const char *str, char *file, int line)
377{
378 char *p;
379
380 if (!str) {
381#if (MEMORY_DEBUG > 1)
382 fprintf(stderr, "strdup\tNULL\tNULL\t%s:%d\n", file, line);
383#endif
384 return NULL;
385 }
386 p = xmalloc_(strlen(str) + 1, file, line);
387 if (p) {
388 strcpy(p, str);
389 }
390#if (MEMORY_DEBUG > 1)
391 fprintf(stderr, "strdup\t%p\t%p\t%s:%d\n", str, p, file, line);
392#endif
393 return p;
394}
395
396#define xmalloc(x) xmalloc_(x, __FILE__, __LINE__)
397#define xrealloc(x,y) xrealloc_(x, y, __FILE__, __LINE__)
398#define xfree(x) xfree_(x, __FILE__, __LINE__)
399#define xstrdup(x) xstrdup_(x, __FILE__, __LINE__)
400
401#else
402
403#define xmalloc(x) sqlite3_malloc(x)
404#define xrealloc(x,y) sqlite3_realloc(x, y)
405#define xfree(x) sqlite3_free(x)
406#define xstrdup(x) strdup_(x)
407
408#endif
409
410#if defined(_WIN32) || defined(_WIN64)
411
412#define vsnprintf _vsnprintf
413#define snprintf _snprintf
414#define strcasecmp _stricmp
415#define strncasecmp _strnicmp
416
417#ifdef _MSC_VER
418#define strtoll _strtoi64
419#define strtoull _strtoui64
420#endif
421
422static HINSTANCE NEAR hModule; /* Saved module handle for resources */
423
424#endif
425
426#ifdef HAVE_SQLITE3STRNICMP
427#undef strncasecmp
428#define strncasecmp(A,B,C) sqlite3_strnicmp(A,B,C)
429#undef strcasecmp
430#define strcasecmp(A,B) strcasecmp_(A,B)
431
432#if defined(__GNUC__) && (__GNUC__ >= 2)
433static int strcasecmp_(const char *a, const char *b)
434 __attribute__((__unused__));
435#endif
436
437static int strcasecmp_(const char *a, const char *b)
438{
439 int c = strlen(a), d = strlen(b);
440
441 if (c > d) {
442 return strncasecmp(a, b, c);
443 }
444 return strncasecmp(a, b, d);
445}
446#endif
447
448#if defined(_WIN32) || defined(_WIN64)
449
450/*
451 * SQLHENV, SQLHDBC, and SQLHSTMT synchronization
452 * is done using a critical section in ENV and DBC
453 * structures.
454 */
455
456#define HDBC_LOCK(hdbc) \
457{ \
458 DBC *d; \
459 \
460 if ((hdbc) == SQL_NULL_HDBC) { \
461 return SQL_INVALID_HANDLE; \
462 } \
463 d = (DBC *) (hdbc); \
464 if (d->magic != DBC_MAGIC) { \
465 return SQL_INVALID_HANDLE; \
466 } \
467 EnterCriticalSection(&d->cs); \
468 d->owner = GetCurrentThreadId(); \
469}
470
471#define HDBC_UNLOCK(hdbc) \
472 if ((hdbc) != SQL_NULL_HDBC) { \
473 DBC *d; \
474 \
475 d = (DBC *) (hdbc); \
476 if (d->magic == DBC_MAGIC) { \
477 d->owner = 0; \
478 LeaveCriticalSection(&d->cs); \
479 } \
480 }
481
482#define HSTMT_LOCK(hstmt) \
483{ \
484 DBC *d; \
485 \
486 if ((hstmt) == SQL_NULL_HSTMT) { \
487 return SQL_INVALID_HANDLE; \
488 } \
489 d = (DBC *) ((STMT *) (hstmt))->dbc; \
490 if (d->magic != DBC_MAGIC) { \
491 return SQL_INVALID_HANDLE; \
492 } \
493 EnterCriticalSection(&d->cs); \
494 d->owner = GetCurrentThreadId(); \
495}
496
497#define HSTMT_UNLOCK(hstmt) \
498 if ((hstmt) != SQL_NULL_HSTMT) { \
499 DBC *d; \
500 \
501 d = (DBC *) ((STMT *) (hstmt))->dbc; \
502 if (d->magic == DBC_MAGIC) { \
503 d->owner = 0; \
504 LeaveCriticalSection(&d->cs); \
505 } \
506 }
507
508#else
509
510/*
511 * On UN*X assume that we are single-threaded or
512 * the driver manager provides serialization for us.
513 *
514 * In iODBC (3.52.x) serialization can be turned
515 * on using the DSN property "ThreadManager=yes".
516 *
517 * In unixODBC that property is named
518 * "Threading=0-3" and takes one of these values:
519 *
520 * 0 - no protection
521 * 1 - statement level protection
522 * 2 - connection level protection
523 * 3 - environment level protection
524 *
525 * unixODBC 2.2.11 uses environment level protection
526 * by default when it has been built with pthread
527 * support.
528 */
529
530#define HDBC_LOCK(hdbc)
531#define HDBC_UNLOCK(hdbc)
532#define HSTMT_LOCK(hdbc)
533#define HSTMT_UNLOCK(hdbc)
534
535#endif
536
537#if defined(ENABLE_NVFS) && (ENABLE_NVFS)
538extern void nvfs_init(void);
539extern const char *nvfs_makevfs(const char *);
540#endif
541
542/*
543 * tolower() replacement w/o locale
544 */
545
546static const char upper_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
547static const char lower_chars[] = "abcdefghijklmnopqrstuvwxyz";
548
549static int
551{
552 if (c) {
553 char *p = strchr(upper_chars, c);
554
555 if (p) {
556 c = lower_chars[p - upper_chars];
557 }
558 }
559 return c;
560}
561
562/*
563 * isdigit() replacement w/o ctype.h
564 */
565
566static const char digit_chars[] = "0123456789";
567
568#define ISDIGIT(c) \
569 ((c) && strchr(digit_chars, (c)) != NULL)
570
571/*
572 * isspace() replacement w/o ctype.h
573 */
574
575static const char space_chars[] = " \f\n\r\t\v";
576
577#define ISSPACE(c) \
578 ((c) && strchr(space_chars, (c)) != NULL)
579
580
581/*
582 * Forward declarations of static functions.
583 */
584
585static void dbtraceapi(DBC *d, char *fn, const char *sql);
586static void freedyncols(STMT *s);
587static void freeresult(STMT *s, int clrcols);
588static void freerows(char **rowp);
589static void unbindcols(STMT *s);
590static void s3stmt_drop(STMT *s);
591
592static SQLRETURN drvexecute(SQLHSTMT stmt, int initial);
593static SQLRETURN freestmt(HSTMT stmt);
594static SQLRETURN mkbindcols(STMT *s, int ncols);
595static SQLRETURN setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp);
596static SQLRETURN setupparbuf(STMT *s, BINDPARM *p);
597static SQLRETURN starttran(STMT *s);
598static SQLRETURN setupparam(STMT *s, char *sql, int pnum);
599static SQLRETURN getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype,
600 SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp,
601 int partial);
602
603#if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
604/* MS Access hack part 1 (reserved error -7748) */
605static COL *statSpec2P, *statSpec3P;
606#endif
607
608#if (MEMORY_DEBUG < 1)
615static char *
616strdup_(const char *str)
617{
618 char *p = NULL;
619
620 if (str) {
621 p = xmalloc(strlen(str) + 1);
622 if (p) {
623 strcpy(p, str);
624 }
625 }
626 return p;
627}
628#endif
629
637static dstr *
638dsappend(dstr *dsp, const char *str)
639{
640 int len;
641
642 if (!str) {
643 return dsp;
644 }
645 len = strlen(str);
646 if (!dsp) {
647 int max = 256;
648
649 if (max < len) {
650 max += len;
651 }
652 dsp = xmalloc(max);
653 if (dsp) {
654 dsp->max = max;
655 dsp->len = dsp->oom = 0;
656 goto copy;
657 }
658 return dsp;
659 }
660 if (dsp->oom) {
661 return dsp;
662 }
663 if (dsp->len + len > dsp->max) {
664 int max = dsp->max + len + 256;
665 dstr *ndsp = xrealloc(dsp, max);
666
667 if (!ndsp) {
668 strcpy(dsp->buffer, "OUT OF MEMORY");
669 dsp->max = dsp->len = 13;
670 dsp->oom = 1;
671 return dsp;
672 }
673 dsp = ndsp;
674 dsp->max = max;
675 }
676copy:
677 strcpy(dsp->buffer + dsp->len, str);
678 dsp->len += len;
679 return dsp;
680}
681
689static dstr *
690dsappendq(dstr *dsp, const char *str)
691{
692 int len;
693 const char *p;
694 char *q;
695
696 if (!str) {
697 return dsp;
698 }
699 len = strlen(str);
700 for (p = str; *p; ++p) {
701 if (p[0] == '"') {
702 ++len;
703 }
704 }
705 len += 2;
706 if (!dsp) {
707 int max = 256;
708
709 if (max < len) {
710 max += len;
711 }
712 dsp = xmalloc(max);
713 if (dsp) {
714 dsp->max = max;
715 dsp->len = dsp->oom = 0;
716 goto copy;
717 }
718 return dsp;
719 }
720 if (dsp->oom) {
721 return dsp;
722 }
723 if (dsp->len + len > dsp->max) {
724 int max = dsp->max + len + 256;
725 dstr *ndsp = xrealloc(dsp, max);
726
727 if (!ndsp) {
728 strcpy(dsp->buffer, "OUT OF MEMORY");
729 dsp->max = dsp->len = 13;
730 dsp->oom = 1;
731 return dsp;
732 }
733 dsp = ndsp;
734 dsp->max = max;
735 }
736copy:
737 q = dsp->buffer + dsp->len;
738 *q++ = '"';
739 for (p = str; *p; ++p) {
740 *q++ = *p;
741 if (p[0] == '"') {
742 *q++ = '"';
743 }
744 }
745 *q++ = '"';
746 *q = '\0';
747 dsp->len += len;
748 return dsp;
749}
750
757static const char *
759{
760 if (dsp) {
761 return (const char *) dsp->buffer;
762 }
763 return "ERROR";
764}
765
772static int
774{
775 return !dsp || dsp->oom;
776}
777
783static void
785{
786 if (dsp) {
787 xfree(dsp);
788 }
789}
790
791#ifdef WCHARSUPPORT
792
799static int
800uc_strlen(SQLWCHAR *str)
801{
802 int len = 0;
803
804 if (str) {
805 while (*str) {
806 ++len;
807 ++str;
808 }
809 }
810 return len;
811}
812
821static SQLWCHAR *
822uc_strncpy(SQLWCHAR *dest, SQLWCHAR *src, int len)
823{
824 int i = 0;
825
826 while (i < len) {
827 if (!src[i]) {
828 break;
829 }
830 dest[i] = src[i];
831 ++i;
832 }
833 if (i < len) {
834 dest[i] = 0;
835 }
836 return dest;
837}
838
847static void
848uc_from_utf_buf(unsigned char *str, int len, SQLWCHAR *uc, int ucLen)
849{
850 ucLen = ucLen / sizeof (SQLWCHAR);
851 if (!uc || ucLen < 0) {
852 return;
853 }
854 if (len < 0) {
855 len = ucLen * 5;
856 }
857 uc[0] = 0;
858 if (str) {
859 int i = 0;
860
861 while (i < len && *str && i < ucLen) {
862 unsigned char c = str[0];
863
864 if (c < 0x80) {
865 uc[i++] = c;
866 ++str;
867 } else if (c <= 0xc1 || c >= 0xf5) {
868 /* illegal, ignored */
869 ++str;
870 } else if (c < 0xe0) {
871 if ((str[1] & 0xc0) == 0x80) {
872 unsigned long t = ((c & 0x1f) << 6) | (str[1] & 0x3f);
873
874 uc[i++] = t;
875 str += 2;
876 } else {
877 uc[i++] = c;
878 ++str;
879 }
880 } else if (c < 0xf0) {
881 if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80) {
882 unsigned long t = ((c & 0x0f) << 12) |
883 ((str[1] & 0x3f) << 6) | (str[2] & 0x3f);
884
885 uc[i++] = t;
886 str += 3;
887 } else {
888 uc[i++] = c;
889 ++str;
890 }
891 } else if (c < 0xf8) {
892 if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 &&
893 (str[3] & 0xc0) == 0x80) {
894 unsigned long t = ((c & 0x03) << 18) |
895 ((str[1] & 0x3f) << 12) | ((str[2] & 0x3f) << 6) |
896 (str[3] & 0x3f);
897
898 if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
899 t >= 0x10000) {
900 t -= 0x10000;
901 uc[i++] = 0xd800 | ((t >> 10) & 0x3ff);
902 if (i >= ucLen) {
903 break;
904 }
905 t = 0xdc00 | (t & 0x3ff);
906 }
907 uc[i++] = t;
908 str += 4;
909 } else {
910 uc[i++] = c;
911 ++str;
912 }
913 } else {
914 /* ignore */
915 ++str;
916 }
917 }
918 if (i < ucLen) {
919 uc[i] = 0;
920 }
921 }
922}
923
931static SQLWCHAR *
932uc_from_utf(unsigned char *str, int len)
933{
934 SQLWCHAR *uc = NULL;
935 int ucLen;
936
937 if (str) {
938 if (len == SQL_NTS) {
939 len = strlen((char *) str);
940 }
941 ucLen = sizeof (SQLWCHAR) * (len + 1);
942 uc = xmalloc(ucLen);
943 if (uc) {
944 uc_from_utf_buf(str, len, uc, ucLen);
945 }
946 }
947 return uc;
948}
949
957static char *
958uc_to_utf(SQLWCHAR *str, int len)
959{
960 int i;
961 char *cp, *ret = NULL;
962
963 if (!str) {
964 return ret;
965 }
966 if (len == SQL_NTS) {
967 len = uc_strlen(str);
968 } else {
969 len = len / sizeof (SQLWCHAR);
970 }
971 cp = xmalloc(len * 6 + 1);
972 if (!cp) {
973 return ret;
974 }
975 ret = cp;
976 for (i = 0; i < len; i++) {
977 unsigned long c = str[i];
978
979 if (sizeof (SQLWCHAR) == 2 * sizeof (char)) {
980 c &= 0xffff;
981 }
982 if (c < 0x80) {
983 *cp++ = c;
984 } else if (c < 0x800) {
985 *cp++ = 0xc0 | ((c >> 6) & 0x1f);
986 *cp++ = 0x80 | (c & 0x3f);
987 } else if (c < 0x10000) {
988 if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
989 c >= 0xd800 && c <= 0xdbff && i + 1 < len) {
990 unsigned long c2 = str[i + 1] & 0xffff;
991
992 if (c2 >= 0xdc00 && c2 <= 0xdfff) {
993 c = (((c & 0x3ff) << 10) | (c2 & 0x3ff)) + 0x10000;
994 *cp++ = 0xf0 | ((c >> 18) & 0x07);
995 *cp++ = 0x80 | ((c >> 12) & 0x3f);
996 *cp++ = 0x80 | ((c >> 6) & 0x3f);
997 *cp++ = 0x80 | (c & 0x3f);
998 ++i;
999 continue;
1000 }
1001 }
1002 *cp++ = 0xe0 | ((c >> 12) & 0x0f);
1003 *cp++ = 0x80 | ((c >> 6) & 0x3f);
1004 *cp++ = 0x80 | (c & 0x3f);
1005 } else if (c <= 0x10ffff) {
1006 *cp++ = 0xf0 | ((c >> 18) & 0x07);
1007 *cp++ = 0x80 | ((c >> 12) & 0x3f);
1008 *cp++ = 0x80 | ((c >> 6) & 0x3f);
1009 *cp++ = 0x80 | (c & 0x3f);
1010 }
1011 }
1012 *cp = '\0';
1013 return ret;
1014}
1015
1016#endif
1017
1018#ifdef WINTERFACE
1019
1027static char *
1028uc_to_utf_c(SQLWCHAR *str, int len)
1029{
1030 if (len != SQL_NTS) {
1031 len = len * sizeof (SQLWCHAR);
1032 }
1033 return uc_to_utf(str, len);
1034}
1035
1036#endif
1037
1038#if defined(WCHARSUPPORT) || defined(_WIN32) || defined(_WIN64)
1039
1045static void
1046uc_free(void *str)
1047{
1048 if (str) {
1049 xfree(str);
1050 }
1051}
1052
1053#endif
1054
1055#if defined(_WIN32) || defined(_WIN64)
1056
1064static char *
1065wmb_to_utf(char *str, int len)
1066{
1067 WCHAR *wstr;
1068 OSVERSIONINFO ovi;
1069 int nchar, is2k, cp = CP_OEMCP;
1070
1071 ovi.dwOSVersionInfoSize = sizeof (ovi);
1072 GetVersionEx(&ovi);
1073 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1074 if (AreFileApisANSI()) {
1075 cp = is2k ? CP_THREAD_ACP : CP_ACP;
1076 }
1077 nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
1078 wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
1079 if (!wstr) {
1080 return NULL;
1081 }
1082 wstr[0] = 0;
1083 nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
1084 wstr[nchar] = 0;
1085 str = xmalloc((nchar + 1) * 7);
1086 if (!str) {
1087 xfree(wstr);
1088 return NULL;
1089 }
1090 str[0] = '\0';
1091 nchar = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, nchar * 7, 0, 0);
1092 str[nchar] = '\0';
1093 xfree(wstr);
1094 return str;
1095}
1096
1097#ifndef WINTERFACE
1098
1106static char *
1107wmb_to_utf_c(char *str, int len)
1108{
1109 if (len == SQL_NTS) {
1110 len = strlen(str);
1111 }
1112 return wmb_to_utf(str, len);
1113}
1114
1115#endif
1116
1124static char *
1125utf_to_wmb(char *str, int len)
1126{
1127 WCHAR *wstr;
1128 OSVERSIONINFO ovi;
1129 int nchar, is2k, cp = CP_OEMCP;
1130
1131 ovi.dwOSVersionInfoSize = sizeof (ovi);
1132 GetVersionEx(&ovi);
1133 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1134 if (AreFileApisANSI()) {
1135 cp = is2k ? CP_THREAD_ACP : CP_ACP;
1136 }
1137 nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
1138 wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
1139 if (!wstr) {
1140 return NULL;
1141 }
1142 wstr[0] = 0;
1143 nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, wstr, nchar);
1144 wstr[nchar] = 0;
1145 str = xmalloc((nchar + 1) * 7);
1146 if (!str) {
1147 xfree(wstr);
1148 return NULL;
1149 }
1150 str[0] = '\0';
1151 nchar = WideCharToMultiByte(cp, 0, wstr, -1, str, nchar * 7, 0, 0);
1152 str[nchar] = '\0';
1153 xfree(wstr);
1154 return str;
1155}
1156
1157#ifdef WINTERFACE
1158
1166static WCHAR *
1167wmb_to_uc(char *str, int len)
1168{
1169 WCHAR *wstr;
1170 OSVERSIONINFO ovi;
1171 int nchar, is2k, cp = CP_OEMCP;
1172
1173 ovi.dwOSVersionInfoSize = sizeof (ovi);
1174 GetVersionEx(&ovi);
1175 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1176 if (AreFileApisANSI()) {
1177 cp = is2k ? CP_THREAD_ACP : CP_ACP;
1178 }
1179 nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
1180 wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
1181 if (!wstr) {
1182 return NULL;
1183 }
1184 wstr[0] = 0;
1185 nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
1186 wstr[nchar] = 0;
1187 return wstr;
1188}
1189
1197static char *
1198uc_to_wmb(WCHAR *wstr, int len)
1199{
1200 char *str;
1201 OSVERSIONINFO ovi;
1202 int nchar, is2k, cp = CP_OEMCP;
1203
1204 ovi.dwOSVersionInfoSize = sizeof (ovi);
1205 GetVersionEx(&ovi);
1206 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1207 if (AreFileApisANSI()) {
1208 cp = is2k ? CP_THREAD_ACP : CP_ACP;
1209 }
1210 nchar = WideCharToMultiByte(cp, 0, wstr, len, NULL, 0, 0, 0);
1211 str = xmalloc((nchar + 1) * 2);
1212 if (!str) {
1213 return NULL;
1214 }
1215 str[0] = '\0';
1216 nchar = WideCharToMultiByte(cp, 0, wstr, len, str, nchar * 2, 0, 0);
1217 str[nchar] = '\0';
1218 return str;
1219}
1220
1221#endif /* WINTERFACE */
1222
1223#endif /* _WIN32 || _WIN64 */
1224
1225
1226#ifdef USE_DLOPEN_FOR_GPPS
1227
1228#include <dlfcn.h>
1229
1230#define SQLGetPrivateProfileString(A,B,C,D,E,F) drvgpps(d,A,B,C,D,E,F)
1231
1232/*
1233 * EXPERIMENTAL: SQLGetPrivateProfileString infrastructure using
1234 * dlopen(), in theory this makes the driver independent from the
1235 * driver manager, i.e. the same driver binary can run with iODBC
1236 * and unixODBC.
1237 */
1238
1239static void
1240drvgetgpps(DBC *d)
1241{
1242 void *lib;
1243 int (*gpps)();
1244
1245 lib = dlopen("libodbcinst.so.2", RTLD_LAZY);
1246 if (!lib) {
1247 lib = dlopen("libodbcinst.so.1", RTLD_LAZY);
1248 }
1249 if (!lib) {
1250 lib = dlopen("libodbcinst.so", RTLD_LAZY);
1251 }
1252 if (!lib) {
1253 lib = dlopen("libiodbcinst.so.2", RTLD_LAZY);
1254 }
1255 if (!lib) {
1256 lib = dlopen("libiodbcinst.so", RTLD_LAZY);
1257 }
1258 if (lib) {
1259 gpps = (int (*)()) dlsym(lib, "SQLGetPrivateProfileString");
1260 if (!gpps) {
1261 dlclose(lib);
1262 return;
1263 }
1264 d->instlib = lib;
1265 d->gpps = gpps;
1266 }
1267}
1268
1269static void
1270drvrelgpps(DBC *d)
1271{
1272 if (d->instlib) {
1273 dlclose(d->instlib);
1274 d->instlib = 0;
1275 }
1276}
1277
1278static int
1279drvgpps(DBC *d, char *sect, char *ent, char *def, char *buf,
1280 int bufsiz, char *fname)
1281{
1282 if (d->gpps) {
1283 return d->gpps(sect, ent, def, buf, bufsiz, fname);
1284 }
1285 strncpy(buf, def, bufsiz);
1286 buf[bufsiz - 1] = '\0';
1287 return 1;
1288}
1289#else
1290#include <odbcinst.h>
1291#define drvgetgpps(d)
1292#define drvrelgpps(d)
1293#endif
1294
1295/*
1296 * Internal function to bind SQLite3 parameters.
1297 */
1298
1299static void
1300s3bind(DBC *d, sqlite3_stmt *stmt, int nparams, BINDPARM *p)
1301{
1302 int i;
1303
1304 if (stmt && p && nparams > 0) {
1305 for (i = 0; i < nparams; i++, p++) {
1306 switch (p->s3type) {
1307 default:
1308 case SQLITE_NULL:
1309 sqlite3_bind_null(stmt, i + 1);
1310 if (d->trace) {
1311 fprintf(d->trace, "-- parameter %d: NULL\n", i + 1);
1312 fflush(d->trace);
1313 }
1314 break;
1315 case SQLITE_TEXT:
1316 sqlite3_bind_text(stmt, i + 1, p->s3val, p->s3size,
1317 SQLITE_STATIC);
1318 if (d->trace) {
1319 fprintf(d->trace, "-- parameter %d: '%*s'\n", i + 1,
1320 p->s3size, (char *) p->s3val);
1321 fflush(d->trace);
1322 }
1323 break;
1324 case SQLITE_BLOB:
1325 sqlite3_bind_blob(stmt, i + 1, p->s3val, p->s3size,
1326 SQLITE_STATIC);
1327 if (d->trace) {
1328 fprintf(d->trace, "-- parameter %d: [BLOB]'\n", i + 1);
1329 fflush(d->trace);
1330 }
1331 break;
1332 case SQLITE_FLOAT:
1333 sqlite3_bind_double(stmt, i + 1, p->s3dval);
1334 if (d->trace) {
1335 fprintf(d->trace, "-- parameter %d: %g\n",
1336 i + 1, p->s3dval);
1337 fflush(d->trace);
1338 }
1339 break;
1340 case SQLITE_INTEGER:
1341 if (p->s3size > sizeof (int)) {
1342 sqlite3_bind_int64(stmt, i + 1, p->s3lival);
1343 if (d->trace) {
1344 fprintf(d->trace,
1345#ifdef _WIN32
1346 "-- parameter %d: %I64d\n",
1347#else
1348 "-- parameter %d: %lld\n",
1349#endif
1350 i + 1, p->s3lival);
1351 fflush(d->trace);
1352 }
1353 } else {
1354 sqlite3_bind_int(stmt, i + 1, p->s3ival);
1355 if (d->trace) {
1356 fprintf(d->trace, "-- parameter %d: %d\n",
1357 i + 1, p->s3ival);
1358 fflush(d->trace);
1359 }
1360 }
1361 break;
1362 }
1363 }
1364 }
1365}
1366
1374typedef struct tblres {
1375 char **resarr;
1376 char *errmsg;
1377 sqlite3_stmt *stmt;
1380 int nrow;
1381 int ncol;
1383 int rc;
1385
1386/*
1387 * Driver's version of sqlite3_get_table() and friends which are
1388 * capable of dealing with blobs.
1389 */
1390
1391static int
1392drvgettable_row(TBLRES *t, int ncol, int rc)
1393{
1394 int need;
1395 int i;
1396 char *p;
1397
1398 if (t->nrow == 0 && rc == SQLITE_ROW) {
1399 need = ncol * 2;
1400 } else {
1401 need = ncol;
1402 }
1403 if (t->ndata + need >= t->nalloc) {
1404 char **resnew;
1405 int nalloc = t->nalloc * 2 + need + 1;
1406
1407 resnew = xrealloc(t->resarr, sizeof (char *) * nalloc);
1408 if (!resnew) {
1409nomem:
1410 t->rc = SQLITE_NOMEM;
1411 return 1;
1412 }
1413 t->nalloc = nalloc;
1414 t->resarr = resnew;
1415 }
1416 /* column names when first row */
1417 if (t->nrow == 0) {
1418 t->ncol = ncol;
1419 for (i = 0; i < ncol; i++) {
1420 p = (char *) sqlite3_column_name(t->stmt, i);
1421 if (p) {
1422 char *q = xmalloc(strlen(p) + 1);
1423
1424 if (!q) {
1425 goto nomem;
1426 }
1427 strcpy(q, p);
1428 p = q;
1429 }
1430 t->resarr[t->ndata++] = p;
1431 }
1432 if (t->s && t->s->guessed_types) {
1433 int ncol2 = ncol;
1434
1435 setupdyncols(t->s, t->stmt, &ncol2);
1436 t->s->guessed_types = 0;
1437 t->s->ncols = ncol;
1438 }
1439 } else if (t->ncol != ncol) {
1440 t->errmsg = sqlite3_mprintf("drvgettable() called with two or"
1441 " more incompatible queries");
1442 t->rc = SQLITE_ERROR;
1443 return 1;
1444 }
1445 /* copy row data */
1446 if (rc == SQLITE_ROW) {
1447 for (i = 0; i < ncol; i++) {
1448 int coltype = sqlite3_column_type(t->stmt, i);
1449
1450 p = NULL;
1451 if (coltype == SQLITE_BLOB) {
1452 int k, nbytes = sqlite3_column_bytes(t->stmt, i);
1453 char *qp;
1454 unsigned const char *bp;
1455
1456 bp = sqlite3_column_blob(t->stmt, i);
1457 qp = xmalloc(nbytes * 2 + 4);
1458 if (!qp) {
1459 goto nomem;
1460 }
1461 p = qp;
1462 *qp++ = 'X';
1463 *qp++ = '\'';
1464 for (k = 0; k < nbytes; k++) {
1465 *qp++ = xdigits[(bp[k] >> 4)];
1466 *qp++ = xdigits[(bp[k] & 0xF)];
1467 }
1468 *qp++ = '\'';
1469 *qp = '\0';
1470#ifdef _MSC_VER
1471 } else if (coltype == SQLITE_FLOAT) {
1472 struct lconv *lc = 0;
1473 double val = sqlite3_column_double(t->stmt, i);
1474 char buffer[128];
1475
1476 /*
1477 * This avoids floating point rounding
1478 * and formatting problems of some SQLite
1479 * versions in conjunction with MSVC 2010.
1480 */
1481 snprintf(buffer, sizeof (buffer), "%.15g", val);
1482 lc = localeconv();
1483 if (lc && lc->decimal_point && lc->decimal_point[0] &&
1484 lc->decimal_point[0] != '.') {
1485 p = strchr(buffer, lc->decimal_point[0]);
1486 if (p) {
1487 *p = '.';
1488 }
1489 }
1490 p = xstrdup(buffer);
1491 if (!p) {
1492 goto nomem;
1493 }
1494#endif
1495 } else if (coltype != SQLITE_NULL) {
1496 p = xstrdup((char *) sqlite3_column_text(t->stmt, i));
1497 if (!p) {
1498 goto nomem;
1499 }
1500 }
1501 t->resarr[t->ndata++] = p;
1502 }
1503 t->nrow++;
1504 }
1505 return 0;
1506}
1507
1508static int
1509drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp,
1510 int *ncolp, char **errp, int nparam, BINDPARM *p)
1511{
1512 DBC *d = (DBC *) s->dbc;
1513 int rc = SQLITE_OK, keep = sql == NULL;
1514 TBLRES tres;
1515 const char *sqlleft = 0;
1516 int nretry = 0, haveerr = 0;
1517
1518 if (!resp) {
1519 return SQLITE_ERROR;
1520 }
1521 *resp = NULL;
1522 if (nrowp) {
1523 *nrowp = 0;
1524 }
1525 if (ncolp) {
1526 *ncolp = 0;
1527 }
1528 tres.errmsg = NULL;
1529 tres.nrow = 0;
1530 tres.ncol = 0;
1531 tres.ndata = 1;
1532 tres.nalloc = 20;
1533 tres.rc = SQLITE_OK;
1534 tres.resarr = xmalloc(sizeof (char *) * tres.nalloc);
1535 tres.stmt = NULL;
1536 tres.s = s;
1537 if (!tres.resarr) {
1538 return SQLITE_NOMEM;
1539 }
1540 tres.resarr[0] = 0;
1541 if (sql == NULL) {
1542 tres.stmt = s->s3stmt;
1543 if (tres.stmt == NULL) {
1544 return SQLITE_NOMEM;
1545 }
1546 goto retrieve;
1547 }
1548 while (sql && *sql && (rc == SQLITE_OK ||
1549 (rc == SQLITE_SCHEMA && (++nretry) < 2))) {
1550 int ncol;
1551
1552 tres.stmt = NULL;
1553#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
1554 dbtraceapi(d, "sqlite3_prepare_v2", sql);
1555 rc = sqlite3_prepare_v2(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
1556#else
1557 dbtraceapi(d, "sqlite3_prepare", sql);
1558 rc = sqlite3_prepare(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
1559#endif
1560 if (rc != SQLITE_OK) {
1561 if (tres.stmt) {
1562 dbtraceapi(d, "sqlite3_finalize", 0);
1563 sqlite3_finalize(tres.stmt);
1564 tres.stmt = NULL;
1565 }
1566 continue;
1567 }
1568 if (!tres.stmt) {
1569 /* this happens for a comment or white-space */
1570 sql = sqlleft;
1571 continue;
1572 }
1573retrieve:
1574 if (sqlite3_bind_parameter_count(tres.stmt) != nparam) {
1575 if (errp) {
1576 *errp =
1577 sqlite3_mprintf("%s", "parameter marker count incorrect");
1578 }
1579 haveerr = 1;
1580 rc = SQLITE_ERROR;
1581 goto tbldone;
1582 }
1583 s3bind(d, tres.stmt, nparam, p);
1584 ncol = sqlite3_column_count(tres.stmt);
1585 while (1) {
1586 if (s->max_rows && tres.nrow >= s->max_rows) {
1587 rc = SQLITE_OK;
1588 break;
1589 }
1590 rc = sqlite3_step(tres.stmt);
1591 if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
1592 if (drvgettable_row(&tres, ncol, rc)) {
1593 rc = SQLITE_ABORT;
1594 goto tbldone;
1595 }
1596 }
1597 if (rc != SQLITE_ROW) {
1598 if (keep) {
1599 dbtraceapi(d, "sqlite3_reset", 0);
1600 rc = sqlite3_reset(tres.stmt);
1601 s->s3stmt_noreset = 1;
1602 } else {
1603 dbtraceapi(d, "sqlite3_finalize", 0);
1604 rc = sqlite3_finalize(tres.stmt);
1605 }
1606 tres.stmt = 0;
1607 if (rc != SQLITE_SCHEMA) {
1608 nretry = 0;
1609 sql = sqlleft;
1610 while (sql && ISSPACE(*sql)) {
1611 sql++;
1612 }
1613 }
1614 if (rc == SQLITE_DONE) {
1615 rc = SQLITE_OK;
1616 }
1617 break;
1618 }
1619 }
1620 }
1621tbldone:
1622 if (tres.stmt) {
1623 if (keep) {
1624 if (!s->s3stmt_noreset) {
1625 dbtraceapi(d, "sqlite3_reset", 0);
1626 sqlite3_reset(tres.stmt);
1627 s->s3stmt_noreset = 1;
1628 }
1629 } else {
1630 dbtraceapi(d, "sqlite3_finalize", 0);
1631 sqlite3_finalize(tres.stmt);
1632 }
1633 }
1634 if (haveerr) {
1635 /* message already in *errp if any */
1636 } else if (rc != SQLITE_OK && rc == sqlite3_errcode(d->sqlite) && errp) {
1637 *errp = sqlite3_mprintf("%s", sqlite3_errmsg(d->sqlite));
1638 } else if (errp) {
1639 *errp = NULL;
1640 }
1641 if (tres.resarr) {
1642 tres.resarr[0] = (char *) (tres.ndata - 1);
1643 }
1644 if (rc == SQLITE_ABORT) {
1645 freerows(&tres.resarr[1]);
1646 if (tres.errmsg) {
1647 if (errp) {
1648 if (*errp) {
1649 sqlite3_free(*errp);
1650 }
1651 *errp = tres.errmsg;
1652 } else {
1653 sqlite3_free(tres.errmsg);
1654 }
1655 }
1656 return tres.rc;
1657 }
1658 sqlite3_free(tres.errmsg);
1659 if (rc != SQLITE_OK) {
1660 freerows(&tres.resarr[1]);
1661 return rc;
1662 }
1663 *resp = &tres.resarr[1];
1664 if (ncolp) {
1665 *ncolp = tres.ncol;
1666 }
1667 if (nrowp) {
1668 *nrowp = tres.nrow;
1669 }
1670 return rc;
1671}
1672
1681#if defined(__GNUC__) && (__GNUC__ >= 2)
1682static void setstatd(DBC *, int, char *, char *, ...)
1683 __attribute__((format (printf, 3, 5)));
1684#endif
1685
1686static void
1687setstatd(DBC *d, int naterr, char *msg, char *st, ...)
1688{
1689 va_list ap;
1690
1691 if (!d) {
1692 return;
1693 }
1694 d->naterr = naterr;
1695 d->logmsg[0] = '\0';
1696 if (msg) {
1697 int count;
1698
1699 va_start(ap, st);
1700 count = vsnprintf((char *) d->logmsg, sizeof (d->logmsg), msg, ap);
1701 va_end(ap);
1702 if (count < 0) {
1703 d->logmsg[sizeof (d->logmsg) - 1] = '\0';
1704 }
1705 }
1706 if (!st) {
1707 st = "?????";
1708 }
1709 strncpy(d->sqlstate, st, 5);
1710 d->sqlstate[5] = '\0';
1711}
1712
1721#if defined(__GNUC__) && (__GNUC__ >= 2)
1722static void setstat(STMT *, int, char *, char *, ...)
1723 __attribute__((format (printf, 3, 5)));
1724#endif
1725
1726static void
1727setstat(STMT *s, int naterr, char *msg, char *st, ...)
1728{
1729 va_list ap;
1730
1731 if (!s) {
1732 return;
1733 }
1734 s->naterr = naterr;
1735 s->logmsg[0] = '\0';
1736 if (msg) {
1737 int count;
1738
1739 va_start(ap, st);
1740 count = vsnprintf((char *) s->logmsg, sizeof (s->logmsg), msg, ap);
1741 va_end(ap);
1742 if (count < 0) {
1743 s->logmsg[sizeof (s->logmsg) - 1] = '\0';
1744 }
1745 }
1746 if (!st) {
1747 st = "?????";
1748 }
1749 strncpy(s->sqlstate, st, 5);
1750 s->sqlstate[5] = '\0';
1751}
1752
1759static SQLRETURN
1761{
1762 DBC *d;
1763
1764 if (dbc == SQL_NULL_HDBC) {
1765 return SQL_INVALID_HANDLE;
1766 }
1767 d = (DBC *) dbc;
1768 setstatd(d, -1, "not supported", "IM001");
1769 return SQL_ERROR;
1770}
1771
1778static SQLRETURN
1780{
1781 STMT *s;
1782
1783 if (stmt == SQL_NULL_HSTMT) {
1784 return SQL_INVALID_HANDLE;
1785 }
1786 s = (STMT *) stmt;
1787 setstat(s, -1, "not supported", "IM001");
1788 return SQL_ERROR;
1789}
1790
1796static void
1797freep(void *x)
1798{
1799 if (x && ((char **) x)[0]) {
1800 xfree(((char **) x)[0]);
1801 ((char **) x)[0] = NULL;
1802 }
1803}
1804
1811static SQLRETURN
1813{
1814 setstat(s, -1, "out of memory", (*s->ov3) ? "HY000" : "S1000");
1815 return SQL_ERROR;
1816}
1817
1824static SQLRETURN
1826{
1827 setstat(s, -1, "not connected", (*s->ov3) ? "HY000" : "S1000");
1828 return SQL_ERROR;
1829}
1830
1838#if defined(HAVE_LOCALECONV) || defined(_WIN32) || defined(_WIN64)
1839
1840static double
1841ln_strtod(const char *data, char **endp)
1842{
1843 struct lconv *lc = 0;
1844 char buf[128], *p, *end;
1845 double value;
1846
1847 lc = localeconv();
1848 if (lc && lc->decimal_point && lc->decimal_point[0] &&
1849 lc->decimal_point[0] != '.') {
1850 strncpy(buf, data, sizeof (buf) - 1);
1851 buf[sizeof (buf) - 1] = '\0';
1852 p = strchr(buf, '.');
1853 if (p) {
1854 *p = lc->decimal_point[0];
1855 }
1856 p = buf;
1857 } else {
1858 p = (char *) data;
1859 }
1860 value = strtod(p, &end);
1861 end = (char *) data + (end - p);
1862 if (endp) {
1863 *endp = end;
1864 }
1865 return value;
1866}
1867
1868#else
1869
1870#define ln_strtod(A,B) strtod(A,B)
1871
1872#endif
1873
1879static char *
1880unquote(char *str)
1881{
1882 if (str) {
1883 int len = strlen(str);
1884
1885 if (len > 1) {
1886 int end = len - 1;
1887
1888 if ((str[0] == '\'' && str[end] == '\'') ||
1889 (str[0] == '"' && str[end] == '"') ||
1890 (str[0] == '[' && str[end] == ']')) {
1891 memmove(str, str + 1, end - 1);
1892 str[end - 1] = '\0';
1893 }
1894 }
1895 }
1896 return str;
1897}
1898
1906static int
1907unescpat(char *str)
1908{
1909 char *p, *q;
1910 int count = 0;
1911
1912 p = str;
1913 while ((q = strchr(p, '_')) != NULL) {
1914 if (q == str || q[-1] != '\\') {
1915 count++;
1916 }
1917 p = q + 1;
1918 }
1919 p = str;
1920 while ((q = strchr(p, '%')) != NULL) {
1921 if (q == str || q[-1] != '\\') {
1922 count++;
1923 }
1924 p = q + 1;
1925 }
1926 p = str;
1927 while ((q = strchr(p, '\\')) != NULL) {
1928 if (q[1] == '\\' || q[1] == '_' || q[1] == '%') {
1929 memmove(q, q + 1, strlen(q));
1930 }
1931 p = q + 1;
1932 }
1933 return count;
1934}
1935
1944static int
1945namematch(char *str, char *pat, int esc)
1946{
1947 int cp, ch;
1948
1949 while (1) {
1950 cp = TOLOWER(*pat);
1951 if (cp == '\0') {
1952 if (*str != '\0') {
1953 goto nomatch;
1954 }
1955 break;
1956 }
1957 if (*str == '\0' && cp != '%') {
1958 goto nomatch;
1959 }
1960 if (cp == '%') {
1961 while (*pat == '%') {
1962 ++pat;
1963 }
1964 cp = TOLOWER(*pat);
1965 if (cp == '\0') {
1966 break;
1967 }
1968 while (1) {
1969 if (cp != '_' && cp != '\\') {
1970 while (*str) {
1971 ch = TOLOWER(*str);
1972 if (ch == cp) {
1973 break;
1974 }
1975 ++str;
1976 }
1977 }
1978 if (namematch(str, pat, esc)) {
1979 goto match;
1980 }
1981 if (*str == '\0') {
1982 goto nomatch;
1983 }
1984 ch = TOLOWER(*str);
1985 ++str;
1986 }
1987 }
1988 if (cp == '_') {
1989 pat++;
1990 str++;
1991 continue;
1992 }
1993 if (esc && cp == '\\' &&
1994 (pat[1] == '\\' || pat[1] == '%' || pat[1] == '_')) {
1995 ++pat;
1996 cp = TOLOWER(*pat);
1997 }
1998 ch = TOLOWER(*str++);
1999 ++pat;
2000 if (ch != cp) {
2001 goto nomatch;
2002 }
2003 }
2004match:
2005 return 1;
2006nomatch:
2007 return 0;
2008}
2009
2017static int
2018busy_handler(void *udata, int count)
2019{
2020 DBC *d = (DBC *) udata;
2021 long t1;
2022 int ret = 0;
2023#if !defined(_WIN32) && !defined(_WIN64)
2024 struct timeval tv;
2025#ifdef HAVE_NANOSLEEP
2026 struct timespec ts;
2027#endif
2028#endif
2029
2030 if (d->busyint) {
2031 d->busyint = 0;
2032 return ret;
2033 }
2034 if (d->timeout <= 0) {
2035 return ret;
2036 }
2037 if (count <= 1) {
2038#if defined(_WIN32) || defined(_WIN64)
2039 d->t0 = GetTickCount();
2040#else
2041 gettimeofday(&tv, NULL);
2042 d->t0 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
2043#endif
2044 }
2045#if defined(_WIN32) || defined(_WIN64)
2046 t1 = GetTickCount();
2047#else
2048 gettimeofday(&tv, NULL);
2049 t1 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
2050#endif
2051 if (t1 - d->t0 > d->timeout) {
2052 goto done;
2053 }
2054#if defined(_WIN32) || defined(_WIN64)
2055 Sleep(10);
2056#else
2057#ifdef HAVE_NANOSLEEP
2058 ts.tv_sec = 0;
2059 ts.tv_nsec = 10000000;
2060 do {
2061 ret = nanosleep(&ts, &ts);
2062 if (ret < 0 && errno != EINTR) {
2063 ret = 0;
2064 }
2065 } while (ret);
2066#else
2067#ifdef HAVE_USLEEP
2068 usleep(10000);
2069#else
2070 tv.tv_sec = 0;
2071 tv.tv_usec = 10000;
2072 select(0, NULL, NULL, NULL, &tv);
2073#endif
2074#endif
2075#endif
2076 ret = 1;
2077done:
2078 return ret;
2079}
2080
2092static int
2093setsqliteopts(sqlite3 *x, DBC *d)
2094{
2095 int count = 0, step = 0, max, rc = SQLITE_ERROR;
2096
2097#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
2098 max = d->longnames ? 3 : 1;
2099#else
2100 max = 3;
2101#endif
2102 if (d->shortnames) {
2103 max = 3;
2104 }
2105 while (step < max) {
2106 if (step < 1) {
2107 rc = sqlite3_exec(x, "PRAGMA empty_result_callbacks = on;",
2108 NULL, NULL, NULL);
2109 if (rc == SQLITE_OK) {
2110 rc = sqlite3_exec(x, d->fksupport ?
2111 "PRAGMA foreign_keys = on;" :
2112 "PRAGMA foreign_keys = off;",
2113 NULL, NULL, NULL);
2114 }
2115 } else if (step < 2) {
2116 rc = sqlite3_exec(x, d->shortnames ?
2117 "PRAGMA full_column_names = off;" :
2118 "PRAGMA full_column_names = on;",
2119 NULL, NULL, NULL);
2120 } else if (step < 3) {
2121 rc = sqlite3_exec(x, d->shortnames ?
2122 "PRAGMA short_column_names = on;" :
2123 "PRAGMA short_column_names = off;",
2124 NULL, NULL, NULL);
2125 }
2126 if (rc != SQLITE_OK) {
2127 if (rc != SQLITE_BUSY ||
2128 !busy_handler((void *) d, ++count)) {
2129 return rc;
2130 }
2131 continue;
2132 }
2133 count = 0;
2134 ++step;
2135 }
2136 sqlite3_busy_handler(x, busy_handler, (void *) d);
2137 return SQLITE_OK;
2138}
2139
2149static void
2150freerows(char **rowp)
2151{
2152 PTRDIFF_T size, i;
2153
2154 if (!rowp) {
2155 return;
2156 }
2157 --rowp;
2158 size = (PTRDIFF_T) rowp[0];
2159 for (i = 1; i <= size; i++) {
2160 freep(&rowp[i]);
2161 }
2162 freep(&rowp);
2163}
2164
2175static int
2176mapsqltype(const char *typename, int *nosign, int ov3, int nowchar,
2177 int dobigint)
2178{
2179 char *p, *q;
2180 int testsign = 0, result;
2181
2182#ifdef WINTERFACE
2183 result = nowchar ? SQL_VARCHAR : SQL_WVARCHAR;
2184#else
2185 result = SQL_VARCHAR;
2186#endif
2187 if (!typename) {
2188 return result;
2189 }
2190 q = p = xmalloc(strlen(typename) + 1);
2191 if (!p) {
2192 return result;
2193 }
2194 strcpy(p, typename);
2195 while (*q) {
2196 *q = TOLOWER(*q);
2197 ++q;
2198 }
2199 if (strncmp(p, "inter", 5) == 0) {
2200 } else if (strncmp(p, "int", 3) == 0 ||
2201 strncmp(p, "mediumint", 9) == 0) {
2202 testsign = 1;
2203 result = SQL_INTEGER;
2204 } else if (strncmp(p, "numeric", 7) == 0) {
2205 result = SQL_DOUBLE;
2206 } else if (strncmp(p, "tinyint", 7) == 0) {
2207 testsign = 1;
2208 result = SQL_TINYINT;
2209 } else if (strncmp(p, "smallint", 8) == 0) {
2210 testsign = 1;
2211 result = SQL_SMALLINT;
2212 } else if (strncmp(p, "float", 5) == 0) {
2213 result = SQL_DOUBLE;
2214 } else if (strncmp(p, "double", 6) == 0 ||
2215 strncmp(p, "real", 4) == 0) {
2216 result = SQL_DOUBLE;
2217 } else if (strncmp(p, "timestamp", 9) == 0) {
2218#ifdef SQL_TYPE_TIMESTAMP
2219 result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
2220#else
2221 result = SQL_TIMESTAMP;
2222#endif
2223 } else if (strncmp(p, "datetime", 8) == 0) {
2224#ifdef SQL_TYPE_TIMESTAMP
2225 result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
2226#else
2227 result = SQL_TIMESTAMP;
2228#endif
2229 } else if (strncmp(p, "time", 4) == 0) {
2230#ifdef SQL_TYPE_TIME
2231 result = ov3 ? SQL_TYPE_TIME : SQL_TIME;
2232#else
2233 result = SQL_TIME;
2234#endif
2235 } else if (strncmp(p, "date", 4) == 0) {
2236#ifdef SQL_TYPE_DATE
2237 result = ov3 ? SQL_TYPE_DATE : SQL_DATE;
2238#else
2239 result = SQL_DATE;
2240#endif
2241#ifdef SQL_LONGVARCHAR
2242 } else if (strncmp(p, "text", 4) == 0 ||
2243 strncmp(p, "memo", 4) == 0 ||
2244 strncmp(p, "longvarchar", 11) == 0) {
2245#ifdef WINTERFACE
2246 result = nowchar ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
2247#else
2248 result = SQL_LONGVARCHAR;
2249#endif
2250#ifdef WINTERFACE
2251 } else if (strncmp(p, "wtext", 5) == 0 ||
2252 strncmp(p, "wvarchar", 8) == 0 ||
2253 strncmp(p, "longwvarchar", 12) == 0) {
2254 result = SQL_WLONGVARCHAR;
2255#endif
2256#endif
2257#ifdef SQL_BIT
2258 } else if (strncmp(p, "bool", 4) == 0 ||
2259 strncmp(p, "bit", 3) == 0) {
2260 result = SQL_BIT;
2261#endif
2262#ifdef SQL_BIGINT
2263 } else if (strncmp(p, "bigint", 6) == 0) {
2264 testsign = 1;
2265 result = SQL_BIGINT;
2266#endif
2267 } else if (strncmp(p, "blob", 4) == 0) {
2268 result = SQL_BINARY;
2269 } else if (strncmp(p, "varbinary", 9) == 0) {
2270 result = SQL_VARBINARY;
2271 } else if (strncmp(p, "longvarbinary", 13) == 0) {
2272 result = SQL_LONGVARBINARY;
2273 }
2274 if (nosign) {
2275 if (testsign) {
2276 *nosign = strstr(p, "unsigned") != NULL;
2277 } else {
2278 *nosign = 1;
2279 }
2280 }
2281#ifdef SQL_BIGINT
2282 if (dobigint && result == SQL_INTEGER) {
2283 result = SQL_BIGINT;
2284 }
2285#endif
2286 xfree(p);
2287 return result;
2288}
2289
2299static void
2300getmd(const char *typename, int sqltype, int *mp, int *dp)
2301{
2302 int m = 0, d = 0;
2303
2304 switch (sqltype) {
2305 case SQL_INTEGER: m = 10; d = 9; break;
2306 case SQL_TINYINT: m = 4; d = 3; break;
2307 case SQL_SMALLINT: m = 6; d = 5; break;
2308 case SQL_FLOAT: m = 25; d = 24; break;
2309 case SQL_DOUBLE: m = 54; d = 53; break;
2310 case SQL_VARCHAR: m = 255; d = 0; break;
2311#ifdef WINTERFACE
2312#ifdef SQL_WVARCHAR
2313 case SQL_WVARCHAR: m = 255; d = 0; break;
2314#endif
2315#endif
2316#ifdef SQL_TYPE_DATE
2317 case SQL_TYPE_DATE:
2318#endif
2319 case SQL_DATE: m = 10; d = 0; break;
2320#ifdef SQL_TYPE_TIME
2321 case SQL_TYPE_TIME:
2322#endif
2323 case SQL_TIME: m = 8; d = 0; break;
2324#ifdef SQL_TYPE_TIMESTAMP
2325 case SQL_TYPE_TIMESTAMP:
2326#endif
2327 case SQL_TIMESTAMP: m = 32; d = 3; break;
2328#ifdef SQL_LONGVARCHAR
2329 case SQL_LONGVARCHAR : m = 65536; d = 0; break;
2330#endif
2331#ifdef WINTERFACE
2332#ifdef SQL_WLONGVARCHAR
2333 case SQL_WLONGVARCHAR: m = 65536; d = 0; break;
2334#endif
2335#endif
2336 case SQL_BINARY:
2337 case SQL_VARBINARY: m = 255; d = 0; break;
2338 case SQL_LONGVARBINARY: m = 65536; d = 0; break;
2339#ifdef SQL_BIGINT
2340 case SQL_BIGINT: m = 20; d = 19; break;
2341#endif
2342#ifdef SQL_BIT
2343 case SQL_BIT: m = 1; d = 1; break;
2344#endif
2345 }
2346 if (m && typename) {
2347 int mm, dd;
2348 char clbr[4];
2349
2350 if (sscanf(typename, "%*[^(](%d,%d %1[)]", &mm, &dd, clbr) == 3) {
2351 m = mm;
2352 d = dd;
2353 } else if (sscanf(typename, "%*[^(](%d %1[)]", &mm, clbr) == 2) {
2354 if (sqltype == SQL_TIMESTAMP) {
2355 d = mm;
2356 }
2357#ifdef SQL_TYPE_TIMESTAMP
2358 else if (sqltype == SQL_TYPE_TIMESTAMP) {
2359 d = mm;
2360 }
2361#endif
2362 else {
2363 m = d = mm;
2364 }
2365 }
2366 }
2367 if (mp) {
2368 *mp = m;
2369 }
2370 if (dp) {
2371 *dp = d;
2372 }
2373}
2374
2384static int
2385mapdeftype(int type, int stype, int nosign, int nowchar)
2386{
2387 if (type == SQL_C_DEFAULT) {
2388 switch (stype) {
2389 case SQL_INTEGER:
2390 type = (nosign > 0) ? SQL_C_ULONG : SQL_C_LONG;
2391 break;
2392 case SQL_TINYINT:
2393 type = (nosign > 0) ? SQL_C_UTINYINT : SQL_C_TINYINT;
2394 break;
2395 case SQL_SMALLINT:
2396 type = (nosign > 0) ? SQL_C_USHORT : SQL_C_SHORT;
2397 break;
2398 case SQL_FLOAT:
2399 type = SQL_C_FLOAT;
2400 break;
2401 case SQL_DOUBLE:
2402 type = SQL_C_DOUBLE;
2403 break;
2404 case SQL_TIMESTAMP:
2405 type = SQL_C_TIMESTAMP;
2406 break;
2407 case SQL_TIME:
2408 type = SQL_C_TIME;
2409 break;
2410 case SQL_DATE:
2411 type = SQL_C_DATE;
2412 break;
2413#ifdef SQL_C_TYPE_TIMESTAMP
2414 case SQL_TYPE_TIMESTAMP:
2415 type = SQL_C_TYPE_TIMESTAMP;
2416 break;
2417#endif
2418#ifdef SQL_C_TYPE_TIME
2419 case SQL_TYPE_TIME:
2420 type = SQL_C_TYPE_TIME;
2421 break;
2422#endif
2423#ifdef SQL_C_TYPE_DATE
2424 case SQL_TYPE_DATE:
2425 type = SQL_C_TYPE_DATE;
2426 break;
2427#endif
2428#ifdef WINTERFACE
2429 case SQL_WVARCHAR:
2430 case SQL_WCHAR:
2431#ifdef SQL_WLONGVARCHAR
2432 case SQL_WLONGVARCHAR:
2433#endif
2434 type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
2435 break;
2436#endif
2437 case SQL_BINARY:
2438 case SQL_VARBINARY:
2439 case SQL_LONGVARBINARY:
2440 type = SQL_C_BINARY;
2441 break;
2442#ifdef SQL_BIT
2443 case SQL_BIT:
2444 type = SQL_C_BIT;
2445 break;
2446#endif
2447#ifdef SQL_BIGINT
2448 case SQL_BIGINT:
2449 type = SQL_C_CHAR;
2450 break;
2451#endif
2452 default:
2453#ifdef WINTERFACE
2454 type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
2455#else
2456 type = SQL_C_CHAR;
2457#endif
2458 break;
2459 }
2460 }
2461 return type;
2462}
2463
2470static int
2471checkddl(char *sql)
2472{
2473 int isddl = 0;
2474
2475 while (*sql && ISSPACE(*sql)) {
2476 ++sql;
2477 }
2478 if (*sql && *sql != ';') {
2479 int i, size;
2480 static const struct {
2481 int len;
2482 const char *str;
2483 } ddlstr[] = {
2484 { 5, "alter" },
2485 { 7, "analyze" },
2486 { 6, "attach" },
2487 { 5, "begin" },
2488 { 6, "commit" },
2489 { 6, "create" },
2490 { 6, "detach" },
2491 { 4, "drop" },
2492 { 3, "end" },
2493 { 7, "reindex" },
2494 { 7, "release" },
2495 { 8, "rollback" },
2496 { 9, "savepoint" },
2497 { 6, "vacuum" }
2498 };
2499
2500 size = strlen(sql);
2501 for (i = 0; i < array_size(ddlstr); i++) {
2502 if (size >= ddlstr[i].len &&
2503 strncasecmp(sql, ddlstr[i].str, ddlstr[i].len) == 0) {
2504 isddl = 1;
2505 break;
2506 }
2507 }
2508 }
2509 return isddl;
2510}
2511
2523static char *
2524fixupsql(char *sql, int sqlLen, int cte, int *nparam, int *isselect,
2525 char **errmsg)
2526{
2527 char *q = sql, *qz = NULL, *p, *inq = NULL, *out;
2528 int np = 0, isddl = -1, size;
2529
2530 if (errmsg) {
2531 *errmsg = NULL;
2532 }
2533 if (sqlLen != SQL_NTS) {
2534 qz = q = xmalloc(sqlLen + 1);
2535 if (!qz) {
2536 return NULL;
2537 }
2538 memcpy(q, sql, sqlLen);
2539 q[sqlLen] = '\0';
2540 size = sqlLen * 4;
2541 } else {
2542 size = strlen(sql) * 4;
2543 }
2544 size += sizeof (char *) - 1;
2545 size &= ~(sizeof (char *) - 1);
2546 p = xmalloc(size);
2547 if (!p) {
2548errout:
2549 freep(&qz);
2550 return NULL;
2551 }
2552 memset(p, 0, size);
2553 out = p;
2554 while (*q) {
2555 switch (*q) {
2556 case '\'':
2557 case '\"':
2558 if (q == inq) {
2559 inq = NULL;
2560 } else if (!inq) {
2561 inq = q + 1;
2562
2563 while (*inq) {
2564 if (*inq == *q) {
2565 if (inq[1] == *q) {
2566 inq++;
2567 } else {
2568 break;
2569 }
2570 }
2571 inq++;
2572 }
2573 }
2574 *p++ = *q;
2575 break;
2576 case '?':
2577 *p++ = *q;
2578 if (!inq) {
2579 np++;
2580 }
2581 break;
2582 case ';':
2583 if (!inq) {
2584 if (isddl < 0) {
2585 isddl = checkddl(out);
2586 }
2587 if (isddl == 0) {
2588 char *qq = q;
2589
2590 do {
2591 ++qq;
2592 } while (*qq && ISSPACE(*qq));
2593 if (*qq && *qq != ';') {
2594 freep(&out);
2595 if (errmsg) {
2596 *errmsg = "only one SQL statement allowed";
2597 }
2598 goto errout;
2599 }
2600 }
2601 }
2602 *p++ = *q;
2603 break;
2604 case '{':
2605 /*
2606 * Deal with escape sequences:
2607 * {d 'YYYY-MM-DD'}, {t ...}, {ts ...}
2608 * {oj ...}, {fn ...} etc.
2609 */
2610 if (!inq) {
2611 int ojfn = 0, brc = 0;
2612 char *inq2 = NULL, *end = q + 1, *start;
2613
2614 while (*end && ISSPACE(*end)) {
2615 ++end;
2616 }
2617 if (*end != 'd' && *end != 'D' &&
2618 *end != 't' && *end != 'T') {
2619 ojfn = 1;
2620 }
2621 start = end;
2622 while (*end) {
2623 if (inq2 && *end == *inq2) {
2624 inq2 = NULL;
2625 } else if (inq2 == NULL && *end == '{') {
2626 char *nerr = 0, *nsql;
2627
2628 nsql = fixupsql(end, SQL_NTS, cte, 0, 0, &nerr);
2629 if (nsql && !nerr) {
2630 strcpy(end, nsql);
2631 } else {
2632 brc++;
2633 }
2634 freep(&nsql);
2635 } else if (inq2 == NULL && *end == '}') {
2636 if (brc-- <= 0) {
2637 break;
2638 }
2639 } else if (inq2 == NULL && (*end == '\'' || *end == '"')) {
2640 inq2 = end;
2641 } else if (inq2 == NULL && *end == '?') {
2642 np++;
2643 }
2644 ++end;
2645 }
2646 if (*end == '}') {
2647 char *end2 = end - 1;
2648
2649 if (ojfn) {
2650 while (start < end) {
2651 if (ISSPACE(*start)) {
2652 break;
2653 }
2654 ++start;
2655 }
2656 while (start < end) {
2657 *p++ = *start;
2658 ++start;
2659 }
2660 q = end;
2661 break;
2662 } else {
2663 while (start < end2 && *start != '\'') {
2664 ++start;
2665 }
2666 while (end2 > start && *end2 != '\'') {
2667 --end2;
2668 }
2669 if (*start == '\'' && *end2 == '\'') {
2670 while (start <= end2) {
2671 *p++ = *start;
2672 ++start;
2673 }
2674 q = end;
2675 break;
2676 }
2677 }
2678 }
2679 }
2680 /* FALL THROUGH */
2681 default:
2682 *p++ = *q;
2683 }
2684 ++q;
2685 }
2686 freep(&qz);
2687 *p = '\0';
2688 if (nparam) {
2689 *nparam = np;
2690 }
2691 if (isselect) {
2692 if (isddl < 0) {
2693 isddl = checkddl(out);
2694 }
2695 if (isddl > 0) {
2696 *isselect = 2;
2697 } else {
2698 int incom = 0;
2699
2700 p = out;
2701 while (*p) {
2702 switch (*p) {
2703 case '-':
2704 if (!incom && p[1] == '-') {
2705 incom = -1;
2706 }
2707 break;
2708 case '\n':
2709 if (incom < 0) {
2710 incom = 0;
2711 }
2712 break;
2713 case '/':
2714 if (incom > 0 && p[-1] == '*') {
2715 incom = 0;
2716 p++;
2717 continue;
2718 } else if (!incom && p[1] == '*') {
2719 incom = 1;
2720 }
2721 break;
2722 }
2723 if (!incom && !ISSPACE(*p)) {
2724 break;
2725 }
2726 p++;
2727 }
2728 size = strlen(p);
2729 if (size >= 6 &&
2730 (strncasecmp(p, "select", 6) == 0 ||
2731 strncasecmp(p, "pragma", 6) == 0)) {
2732 *isselect = 1;
2733 } else if (cte && size >= 4 && strncasecmp(p, "with", 4) == 0) {
2734 *isselect = 1;
2735 } else if (size >= 7 && strncasecmp(p, "explain", 7) == 0) {
2736 *isselect = 1;
2737 } else {
2738 *isselect = 0;
2739 }
2740 }
2741 }
2742 return out;
2743}
2744
2753static int
2754findcol(char **cols, int ncols, char *name)
2755{
2756 int i;
2757
2758 if (cols) {
2759 for (i = 0; i < ncols; i++) {
2760 if (strcmp(cols[i], name) == 0) {
2761 return i;
2762 }
2763 }
2764 }
2765 return -1;
2766}
2767
2784static void
2786{
2787 int i, k;
2788#ifndef FULL_METADATA
2789 int pk, nn, t, r, nrows, ncols;
2790 char **rowp, *flagp, flags[128];
2791#endif
2792
2793 if (!s->dyncols) {
2794 return;
2795 }
2796 /* fixup labels */
2797 if (!s->longnames) {
2798 if (s->dcols > 1) {
2799 char *table = s->dyncols[0].table;
2800
2801 for (i = 1; table[0] && i < s->dcols; i++) {
2802 if (strcmp(s->dyncols[i].table, table)) {
2803 break;
2804 }
2805 }
2806 if (i >= s->dcols) {
2807 for (i = 0; i < s->dcols; i++) {
2808 s->dyncols[i].label = s->dyncols[i].column;
2809 }
2810 }
2811 } else if (s->dcols == 1) {
2812 s->dyncols[0].label = s->dyncols[0].column;
2813 }
2814 }
2815 for (i = 0; i < s->dcols; i++) {
2816 s->dyncols[i].type =
2817 mapsqltype(s->dyncols[i].typename, &s->dyncols[i].nosign, *s->ov3,
2818 s->nowchar[0] || s->nowchar[1], s->dobigint);
2819 getmd(s->dyncols[i].typename, s->dyncols[i].type,
2820 &s->dyncols[i].size, &s->dyncols[i].prec);
2821#ifdef SQL_LONGVARCHAR
2822 if (s->dyncols[i].type == SQL_VARCHAR &&
2823 s->dyncols[i].size > 255) {
2824 s->dyncols[i].type = SQL_LONGVARCHAR;
2825 }
2826#endif
2827#ifdef WINTERFACE
2828#ifdef SQL_WLONGVARCHAR
2829 if (s->dyncols[i].type == SQL_WVARCHAR &&
2830 s->dyncols[i].size > 255) {
2831 s->dyncols[i].type = SQL_WLONGVARCHAR;
2832 }
2833#endif
2834#endif
2835 if (s->dyncols[i].type == SQL_VARBINARY &&
2836 s->dyncols[i].size > 255) {
2837 s->dyncols[i].type = SQL_LONGVARBINARY;
2838 }
2839 }
2840#ifndef FULL_METADATA
2841 if (s->dcols > array_size(flags)) {
2842 flagp = xmalloc(sizeof (flags[0]) * s->dcols);
2843 if (flagp == NULL) {
2844 return;
2845 }
2846 } else {
2847 flagp = flags;
2848 }
2849 memset(flagp, 0, sizeof (flags[0]) * s->dcols);
2850 for (i = 0; i < s->dcols; i++) {
2851 s->dyncols[i].autoinc = SQL_FALSE;
2852 s->dyncols[i].notnull = SQL_NULLABLE;
2853 }
2854 for (i = 0; i < s->dcols; i++) {
2855 int ret, lastpk = -1, autoinccount = 0;
2856 char *sql;
2857
2858 if (!s->dyncols[i].table[0]) {
2859 continue;
2860 }
2861 if (flagp[i]) {
2862 continue;
2863 }
2864 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", s->dyncols[i].table);
2865 if (!sql) {
2866 continue;
2867 }
2868 dbtraceapi(d, "sqlite3_get_table", sql);
2869 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, NULL);
2870 sqlite3_free(sql);
2871 if (ret != SQLITE_OK) {
2872 continue;
2873 }
2874 k = findcol(rowp, ncols, "name");
2875 t = findcol(rowp, ncols, "type");
2876 pk = findcol(rowp, ncols, "pk");
2877 nn = findcol(rowp, ncols, "notnull");
2878 if (k < 0 || t < 0) {
2879 goto freet;
2880 }
2881 for (r = 1; r <= nrows; r++) {
2882 int m;
2883
2884 for (m = i; m < s->dcols; m++) {
2885 char *colname = s->dyncols[m].column;
2886
2887 if (s->longnames) {
2888 char *dotp = strchr(colname, '.');
2889
2890 if (dotp) {
2891 colname = dotp + 1;
2892 }
2893 }
2894 if (!flagp[m] &&
2895 strcmp(colname, rowp[r * ncols + k]) == 0 &&
2896 strcmp(s->dyncols[m].table, s->dyncols[i].table) == 0) {
2897 char *typename = rowp[r * ncols + t];
2898
2899 flagp[m] = i + 1;
2900 freep(&s->dyncols[m].typename);
2901 s->dyncols[m].typename = xstrdup(typename);
2902 s->dyncols[m].type =
2903 mapsqltype(typename, &s->dyncols[m].nosign, *s->ov3,
2904 s->nowchar[0] || s->nowchar[1],
2905 s->dobigint);
2906 getmd(typename, s->dyncols[m].type, &s->dyncols[m].size,
2907 &s->dyncols[m].prec);
2908#ifdef SQL_LONGVARCHAR
2909 if (s->dyncols[m].type == SQL_VARCHAR &&
2910 s->dyncols[m].size > 255) {
2911 s->dyncols[m].type = SQL_LONGVARCHAR;
2912 }
2913#endif
2914#ifdef WINTERFACE
2915#ifdef SQL_WLONGVARCHAR
2916 if (s->dyncols[i].type == SQL_WVARCHAR &&
2917 s->dyncols[i].size > 255) {
2918 s->dyncols[i].type = SQL_WLONGVARCHAR;
2919 }
2920#endif
2921#endif
2922 if (s->dyncols[i].type == SQL_VARBINARY &&
2923 s->dyncols[i].size > 255) {
2924 s->dyncols[i].type = SQL_LONGVARBINARY;
2925 }
2926 if (pk >= 0 && strcmp(rowp[r * ncols + pk], "1") == 0) {
2927 s->dyncols[m].ispk = 1;
2928 if (++autoinccount > 1) {
2929 if (lastpk >= 0) {
2930 s->dyncols[lastpk].autoinc = SQL_FALSE;
2931 lastpk = -1;
2932 }
2933 } else {
2934 lastpk = m;
2935 if (strlen(typename) == 7 &&
2936 strncasecmp(typename, "integer", 7) == 0) {
2937 s->dyncols[m].autoinc = SQL_TRUE;
2938 }
2939 }
2940 } else {
2941 s->dyncols[m].ispk = 0;
2942 }
2943 if (nn >= 0 && rowp[r * ncols + nn][0] != '0') {
2944 s->dyncols[m].notnull = SQL_NO_NULLS;
2945 }
2946 }
2947 }
2948 }
2949freet:
2950 sqlite3_free_table(rowp);
2951 }
2952 for (i = k = 0; i < s->dcols; i++) {
2953 if (flagp[i] == 0) {
2954 break;
2955 }
2956 if (k == 0) {
2957 k = flagp[i];
2958 } else if (flagp[i] != k) {
2959 k = 0;
2960 break;
2961 }
2962 }
2963 s->one_tbl = k ? 1 : 0;
2964 k = 0;
2965 if (s->one_tbl) {
2966 for (i = 0; i < s->dcols; i++) {
2967 if (s->dyncols[i].ispk > 0) {
2968 ++k;
2969 }
2970 }
2971 }
2972 s->has_pk = k;
2973 if (flagp != flags) {
2974 freep(&flagp);
2975 }
2976#else
2977 for (i = 1, k = 0; i < s->dcols; i++) {
2978 if (strcmp(s->dyncols[i].table, s->dyncols[0].table) == 0) {
2979 k++;
2980 }
2981 }
2982 s->one_tbl = (k && k + 1 == s->dcols) ? 1 : 0;
2983 k = 0;
2984 if (s->one_tbl) {
2985 for (i = 0; i < s->dcols; i++) {
2986 if (s->dyncols[i].ispk > 0) {
2987 ++k;
2988 if (s->has_rowid < 0 && s->dyncols[i].isrowid > 0) {
2989 s->has_rowid = i;
2990 }
2991 }
2992 }
2993 }
2994 s->has_pk = k;
2995#endif
2996}
2997
3004static void
3005convJD2YMD(double jd, DATE_STRUCT *ds)
3006{
3007 int z, a, b, c, d, e, x1;
3008 sqlite_int64 ijd;
3009
3010 ijd = jd * 86400000.0 + 0.5;
3011 z = (int) ((ijd + 43200000) / 86400000);
3012 a = (int) ((z - 1867216.25) / 36524.25);
3013 a = z + 1 + a - (a / 4);
3014 b = a + 1524;
3015 c = (int) ((b - 122.1) / 365.25);
3016 d = (36525 * c) / 100;
3017 e = (int) ((b - d) / 30.6001);
3018 x1 = (int) (30.6001 * e);
3019 ds->day = b - d - x1;
3020 ds->month = (e < 14) ? (e - 1) : (e - 13);
3021 ds->year = (ds->month > 2) ? (c - 4716) : (c - 4715);
3022}
3023
3024
3032static void
3033convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
3034{
3035 int s;
3036 double ds;
3037 sqlite_int64 ijd;
3038
3039 ijd = jd * 86400000.0 + 0.5;
3040 s = (int)((ijd + 43200000) % 86400000);
3041 ds = s / 1000.0;
3042 if (fp) {
3043 *fp = (s % 1000) * 1000000;
3044 }
3045 s = (int) ds;
3046 ds -= s;
3047 ts->hour = s / 3600;
3048 s -= ts->hour * 3600;
3049 ts->minute = s / 60;
3050 ds += s - ts->minute *60;
3051 ts->second = (int) ds;
3052}
3053
3061static int
3062getmdays(int year, int month)
3063{
3064 static const int mdays[] = {
3065 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
3066 };
3067 int mday;
3068
3069 if (month < 1) {
3070 return 0;
3071 }
3072 mday = mdays[(month - 1) % 12];
3073 if (mday == 28 && year % 4 == 0 &&
3074 (!(year % 100 == 0) || year % 400 == 0)) {
3075 mday++;
3076 }
3077 return mday;
3078}
3079
3095static int
3096str2date(int jdconv, char *str, DATE_STRUCT *ds)
3097{
3098 int i, err = 0;
3099 double jd;
3100 char *p, *q, sepc = '\0';
3101
3102 ds->year = ds->month = ds->day = 0;
3103 if (jdconv) {
3104 p = strchr(str, '.');
3105 if (p) {
3106 /* julian day format */
3107 p = 0;
3108 jd = ln_strtod(str, &p);
3109 if (p && p > str) {
3110 convJD2YMD(jd, ds);
3111 return 0;
3112 }
3113 }
3114 }
3115 p = str;
3116 while (*p && !ISDIGIT(*p)) {
3117 ++p;
3118 }
3119 q = p;
3120 i = 0;
3121 while (*q && !ISDIGIT(*q)) {
3122 ++i;
3123 ++q;
3124 }
3125 if (i >= 8) {
3126 char buf[8];
3127
3128 strncpy(buf, p + 0, 4); buf[4] = '\0';
3129 ds->year = strtol(buf, NULL, 10);
3130 strncpy(buf, p + 4, 2); buf[2] = '\0';
3131 ds->month = strtol(buf, NULL, 10);
3132 strncpy(buf, p + 6, 2); buf[2] = '\0';
3133 ds->day = strtol(buf, NULL, 10);
3134 goto done;
3135 }
3136 i = 0;
3137 while (i < 3) {
3138 int n;
3139
3140 q = NULL;
3141 n = strtol(p, &q, 10);
3142 if (!q || q == p) {
3143 if (*q == '\0') {
3144 if (i == 0) {
3145 err = 1;
3146 }
3147 goto done;
3148 }
3149 }
3150 if (!sepc) {
3151 sepc = *q;
3152 }
3153 if (*q == '-' || *q == '/' || *q == '\0' || i == 2) {
3154 switch (i) {
3155 case 0: ds->year = n; break;
3156 case 1: ds->month = n; break;
3157 case 2: ds->day = n; break;
3158 }
3159 ++i;
3160 if (*q) {
3161 ++q;
3162 }
3163 } else {
3164 i = 0;
3165 while (*q && !ISDIGIT(*q)) {
3166 ++q;
3167 }
3168 }
3169 p = q;
3170 }
3171done:
3172 /* final check for overflow */
3173 if (err ||
3174 ds->month < 1 || ds->month > 12 ||
3175 ds->day < 1 || ds->day > getmdays(ds->year, ds->month)) {
3176 if (sepc == '/') {
3177 /* Try MM/DD/YYYY format */
3178 int t[3];
3179
3180 t[0] = ds->year;
3181 t[1] = ds->month;
3182 t[2] = ds->day;
3183 ds->year = t[2];
3184 ds->day = t[1];
3185 ds->month = t[0];
3186 if (ds->month >= 1 && ds->month <= 12 &&
3187 (ds->day >= 1 || ds->day <= getmdays(ds->year, ds->month))) {
3188 return 0;
3189 }
3190 }
3191 return -1;
3192 }
3193 return 0;
3194}
3195
3210static int
3211str2time(int jdconv, char *str, TIME_STRUCT *ts)
3212{
3213 int i, err = 0, ampm = -1;
3214 double jd;
3215 char *p, *q;
3216
3217 ts->hour = ts->minute = ts->second = 0;
3218 if (jdconv) {
3219 p = strchr(str, '.');
3220 if (p) {
3221 /* julian day format */
3222 p = 0;
3223 jd = ln_strtod(str, &p);
3224 if (p && p > str) {
3225 convJD2HMS(jd, ts, 0);
3226 return 0;
3227 }
3228 }
3229 }
3230 p = str;
3231 while (*p && !ISDIGIT(*p)) {
3232 ++p;
3233 }
3234 q = p;
3235 i = 0;
3236 while (*q && ISDIGIT(*q)) {
3237 ++i;
3238 ++q;
3239 }
3240 if (i >= 6) {
3241 char buf[4];
3242
3243 strncpy(buf, p + 0, 2); buf[2] = '\0';
3244 ts->hour = strtol(buf, NULL, 10);
3245 strncpy(buf, p + 2, 2); buf[2] = '\0';
3246 ts->minute = strtol(buf, NULL, 10);
3247 strncpy(buf, p + 4, 2); buf[2] = '\0';
3248 ts->second = strtol(buf, NULL, 10);
3249 goto done;
3250 }
3251 i = 0;
3252 while (i < 3) {
3253 int n;
3254
3255 q = NULL;
3256 n = strtol(p, &q, 10);
3257 if (!q || q == p) {
3258 if (*q == '\0') {
3259 if (i == 0) {
3260 err = 1;
3261 }
3262 goto done;
3263 }
3264 }
3265 if (*q == ':' || *q == '\0' || i == 2) {
3266 switch (i) {
3267 case 0: ts->hour = n; break;
3268 case 1: ts->minute = n; break;
3269 case 2: ts->second = n; break;
3270 }
3271 ++i;
3272 if (*q) {
3273 ++q;
3274 }
3275 } else {
3276 i = 0;
3277 while (*q && !ISDIGIT(*q)) {
3278 ++q;
3279 }
3280 }
3281 p = q;
3282 }
3283 if (!err) {
3284 while (*p) {
3285 if ((p[0] == 'p' || p[0] == 'P') &&
3286 (p[1] == 'm' || p[1] == 'M')) {
3287 ampm = 1;
3288 } else if ((p[0] == 'a' || p[0] == 'A') &&
3289 (p[1] == 'm' || p[1] == 'M')) {
3290 ampm = 0;
3291 }
3292 ++p;
3293 }
3294 if (ampm > 0) {
3295 if (ts->hour < 12) {
3296 ts->hour += 12;
3297 }
3298 } else if (ampm == 0) {
3299 if (ts->hour == 12) {
3300 ts->hour = 0;
3301 }
3302 }
3303 }
3304done:
3305 /* final check for overflow */
3306 if (err || ts->hour > 23 || ts->minute > 59 || ts->second > 59) {
3307 return -1;
3308 }
3309 return 0;
3310}
3311
3331static int
3332str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
3333{
3334 int i, m, n, err = 0, ampm = -1;
3335 double jd;
3336 char *p, *q, in = '\0', sepc = '\0';
3337
3338 tss->year = tss->month = tss->day = 0;
3339 tss->hour = tss->minute = tss->second = 0;
3340 tss->fraction = 0;
3341 if (jdconv) {
3342 p = strchr(str, '.');
3343 if (p) {
3344 q = strchr(str, '-');
3345 if (q == str) {
3346 q = 0;
3347 }
3348 if (!q) {
3349 q = strchr(str, '/');
3350 if (!q) {
3351 q = strchr(str, ':');
3352 }
3353 }
3354 if (!q || q > p) {
3355 /* julian day format */
3356 p = 0;
3357 jd = ln_strtod(str, &p);
3358 if (p && p > str) {
3359 DATE_STRUCT ds;
3360 TIME_STRUCT ts;
3361
3362 convJD2YMD(jd, &ds);
3363 convJD2HMS(jd, &ts, &n);
3364 tss->year = ds.year;
3365 tss->month = ds.month;
3366 tss->day = ds.day;
3367 tss->hour = ts.hour;
3368 tss->minute = ts.minute;
3369 tss->second = ts.second;
3370 tss->fraction = n;
3371 return 0;
3372 }
3373 }
3374 }
3375 }
3376 p = str;
3377 while (*p && !ISDIGIT(*p)) {
3378 ++p;
3379 }
3380 q = p;
3381 i = 0;
3382 while (*q && ISDIGIT(*q)) {
3383 ++i;
3384 ++q;
3385 }
3386 if (i >= 14) {
3387 char buf[16];
3388
3389 strncpy(buf, p + 0, 4); buf[4] = '\0';
3390 tss->year = strtol(buf, NULL, 10);
3391 strncpy(buf, p + 4, 2); buf[2] = '\0';
3392 tss->month = strtol(buf, NULL, 10);
3393 strncpy(buf, p + 6, 2); buf[2] = '\0';
3394 tss->day = strtol(buf, NULL, 10);
3395 strncpy(buf, p + 8, 2); buf[2] = '\0';
3396 tss->hour = strtol(buf, NULL, 10);
3397 strncpy(buf, p + 10, 2); buf[2] = '\0';
3398 tss->minute = strtol(buf, NULL, 10);
3399 strncpy(buf, p + 12, 2); buf[2] = '\0';
3400 tss->second = strtol(buf, NULL, 10);
3401 if (i > 14) {
3402 m = i - 14;
3403 strncpy(buf, p + 14, m);
3404 while (m < 9) {
3405 buf[m] = '0';
3406 ++m;
3407 }
3408 buf[m] = '\0';
3409 tss->fraction = strtol(buf, NULL, 10);
3410 }
3411 m = 7;
3412 goto done;
3413 }
3414 m = i = 0;
3415 while ((m & 7) != 7) {
3416 q = NULL;
3417 n = strtol(p, &q, 10);
3418 if (!q || q == p) {
3419 if (*q == '\0') {
3420 if (m < 1) {
3421 err = 1;
3422 }
3423 goto done;
3424 }
3425 }
3426 if (in == '\0') {
3427 switch (*q) {
3428 case '-':
3429 case '/':
3430 if ((m & 1) == 0) {
3431 in = *q;
3432 i = 0;
3433 }
3434 break;
3435 case ':':
3436 if ((m & 2) == 0) {
3437 in = *q;
3438 i = 0;
3439 }
3440 break;
3441 case ' ':
3442 case '.':
3443 break;
3444 default:
3445 in = '\0';
3446 i = 0;
3447 break;
3448 }
3449 }
3450 switch (in) {
3451 case '-':
3452 case '/':
3453 if (!sepc) {
3454 sepc = in;
3455 }
3456 switch (i) {
3457 case 0: tss->year = n; break;
3458 case 1: tss->month = n; break;
3459 case 2: tss->day = n; break;
3460 }
3461 if (++i >= 3) {
3462 i = 0;
3463 m |= 1;
3464 if (!(m & 2)) {
3465 m |= 8;
3466 }
3467 goto skip;
3468 } else {
3469 ++q;
3470 }
3471 break;
3472 case ':':
3473 switch (i) {
3474 case 0: tss->hour = n; break;
3475 case 1: tss->minute = n; break;
3476 case 2: tss->second = n; break;
3477 }
3478 if (++i >= 3) {
3479 i = 0;
3480 m |= 2;
3481 if (*q == '.') {
3482 in = '.';
3483 goto skip2;
3484 }
3485 if (*q == ' ') {
3486 if ((m & 1) == 0) {
3487 char *e = NULL;
3488
3489 (void) strtol(q + 1, &e, 10);
3490 if (e && *e == '-') {
3491 goto skip;
3492 }
3493 }
3494 in = '.';
3495 goto skip2;
3496 }
3497 goto skip;
3498 } else {
3499 ++q;
3500 }
3501 break;
3502 case '.':
3503 if (++i >= 1) {
3504 int ndig = q - p;
3505
3506 if (p[0] == '+' || p[0] == '-') {
3507 ndig--;
3508 }
3509 while (ndig < 9) {
3510 n = n * 10;
3511 ++ndig;
3512 }
3513 tss->fraction = n;
3514 m |= 4;
3515 i = 0;
3516 }
3517 default:
3518 skip:
3519 in = '\0';
3520 skip2:
3521 while (*q && !ISDIGIT(*q)) {
3522 if ((q[0] == 'a' || q[0] == 'A') &&
3523 (q[1] == 'm' || q[1] == 'M')) {
3524 ampm = 0;
3525 ++q;
3526 } else if ((q[0] == 'p' || q[0] == 'P') &&
3527 (q[1] == 'm' || q[1] == 'M')) {
3528 ampm = 1;
3529 ++q;
3530 }
3531 ++q;
3532 }
3533 }
3534 p = q;
3535 }
3536 if ((m & 7) > 1 && (m & 8)) {
3537 /* ISO8601 timezone */
3538 if (p > str && ISDIGIT(*p)) {
3539 int nn, sign;
3540
3541 q = p - 1;
3542 if (*q != '+' && *q != '-') {
3543 goto done;
3544 }
3545 sign = (*q == '+') ? -1 : 1;
3546 q = NULL;
3547 n = strtol(p, &q, 10);
3548 if (!q || *q++ != ':' || !ISDIGIT(*q)) {
3549 goto done;
3550 }
3551 p = q;
3552 q = NULL;
3553 nn = strtol(p, &q, 10);
3554 tss->minute += nn * sign;
3555 if ((SQLSMALLINT) tss->minute < 0) {
3556 tss->hour -= 1;
3557 tss->minute += 60;
3558 } else if (tss->minute >= 60) {
3559 tss->hour += 1;
3560 tss->minute -= 60;
3561 }
3562 tss->hour += n * sign;
3563 if ((SQLSMALLINT) tss->hour < 0) {
3564 tss->day -= 1;
3565 tss->hour += 24;
3566 } else if (tss->hour >= 24) {
3567 tss->day += 1;
3568 tss->hour -= 24;
3569 }
3570 if ((short) tss->day < 1 || tss->day >= 28) {
3571 int mday, pday, pmon;
3572
3573 mday = getmdays(tss->year, tss->month);
3574 pmon = tss->month - 1;
3575 if (pmon < 1) {
3576 pmon = 12;
3577 }
3578 pday = getmdays(tss->year, pmon);
3579 if ((SQLSMALLINT) tss->day < 1) {
3580 tss->month -= 1;
3581 tss->day = pday;
3582 } else if (tss->day > mday) {
3583 tss->month += 1;
3584 tss->day = 1;
3585 }
3586 if ((SQLSMALLINT) tss->month < 1) {
3587 tss->year -= 1;
3588 tss->month = 12;
3589 } else if (tss->month > 12) {
3590 tss->year += 1;
3591 tss->month = 1;
3592 }
3593 }
3594 }
3595 }
3596done:
3597 if ((m & 1) &&
3598 (tss->month < 1 || tss->month > 12 ||
3599 tss->day < 1 || tss->day > getmdays(tss->year, tss->month))) {
3600 if (sepc == '/') {
3601 /* Try MM/DD/YYYY format */
3602 int t[3];
3603
3604 t[0] = tss->year;
3605 t[1] = tss->month;
3606 t[2] = tss->day;
3607 tss->year = t[2];
3608 tss->day = t[1];
3609 tss->month = t[0];
3610 }
3611 }
3612 /* Replace missing year/month/day with current date */
3613 if (!err && (m & 1) == 0) {
3614#ifdef _WIN32
3615 SYSTEMTIME t;
3616
3617 GetLocalTime(&t);
3618 tss->year = t.wYear;
3619 tss->month = t.wMonth;
3620 tss->day = t.wDay;
3621#else
3622 struct timeval tv;
3623 struct tm tm;
3624
3625 gettimeofday(&tv, NULL);
3626 tm = *localtime(&tv.tv_sec);
3627 tss->year = tm.tm_year + 1900;
3628 tss->month = tm.tm_mon + 1;
3629 tss->day = tm.tm_mday;
3630#endif
3631 }
3632 /* Normalize fraction */
3633 if (tss->fraction < 0) {
3634 tss->fraction = 0;
3635 }
3636 /* Final check for overflow */
3637 if (err ||
3638 tss->month < 1 || tss->month > 12 ||
3639 tss->day < 1 || tss->day > getmdays(tss->year, tss->month) ||
3640 tss->hour > 23 || tss->minute > 59 || tss->second > 59) {
3641 return -1;
3642 }
3643 if ((m & 7) > 1) {
3644 if (ampm > 0) {
3645 if (tss->hour < 12) {
3646 tss->hour += 12;
3647 }
3648 } else if (ampm == 0) {
3649 if (tss->hour == 12) {
3650 tss->hour = 0;
3651 }
3652 }
3653 }
3654 return ((m & 7) < 1) ? -1 : 0;
3655}
3656
3663static int
3664getbool(char *string)
3665{
3666 if (string) {
3667 return string[0] && strchr("Yy123456789Tt", string[0]) != NULL;
3668 }
3669 return 0;
3670}
3671
3679static void
3680blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
3681{
3682#if 0
3683 DBC *d = (DBC *) sqlite3_user_data(ctx);
3684#endif
3685 char *filename = 0;
3686
3687 if (nargs > 0) {
3688 if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
3689 filename = (char *) sqlite3_value_text(args[0]);
3690 }
3691 }
3692 if (filename) {
3693#ifdef _WIN32
3694 char *wname = utf_to_wmb(filename, -1);
3695 FILE *f;
3696#else
3697 FILE *f = fopen(filename, "r");
3698#endif
3699 char *p;
3700 long n, nn;
3701
3702#ifdef _WIN32
3703 if (wname) {
3704 f = fopen(wname, "rb");
3705 } else {
3706 sqlite3_result_error(ctx, "out of memory", -1);
3707 return;
3708 }
3709 uc_free(wname);
3710#endif
3711 if (f) {
3712 if (fseek(f, 0, SEEK_END) == 0) {
3713 n = ftell(f);
3714 if (fseek(f, 0, SEEK_SET) == 0) {
3715 p = sqlite3_malloc(n);
3716 if (p) {
3717 nn = fread(p, 1, n, f);
3718 if (nn != n) {
3719 sqlite3_result_error(ctx, "read error", -1);
3720 sqlite3_free(p);
3721 } else {
3722 sqlite3_result_blob(ctx, p, n, sqlite3_free);
3723 }
3724 } else {
3725 sqlite3_result_error(ctx, "out of memory", -1);
3726 }
3727 } else {
3728 sqlite3_result_error(ctx, "seek error", -1);
3729 }
3730 } else {
3731 sqlite3_result_error(ctx, "seek error", -1);
3732 }
3733 fclose(f);
3734 } else {
3735 sqlite3_result_error(ctx, "cannot open file", -1);
3736 }
3737 } else {
3738 sqlite3_result_error(ctx, "no filename given", -1);
3739 }
3740}
3741
3749static void
3750blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
3751{
3752#if 0
3753 DBC *d = (DBC *) sqlite3_user_data(ctx);
3754#endif
3755 char *filename = 0;
3756 char *p = 0;
3757 int n = 0;
3758
3759 if (nargs > 0) {
3760 p = (char *) sqlite3_value_blob(args[0]);
3761 n = sqlite3_value_bytes(args[0]);
3762 }
3763 if (nargs > 1) {
3764 if (sqlite3_value_type(args[1]) != SQLITE_NULL) {
3765 filename = (char *) sqlite3_value_text(args[1]);
3766 }
3767 }
3768 if (p) {
3769 if (filename) {
3770#ifdef _WIN32
3771 char *wname = utf_to_wmb(filename, -1);
3772 FILE *f;
3773#else
3774 FILE *f = fopen(filename, "w");
3775#endif
3776 int nn;
3777
3778#ifdef _WIN32
3779 if (wname) {
3780 f = fopen(wname, "wb");
3781 } else {
3782 sqlite3_result_error(ctx, "out of memory", -1);
3783 return;
3784 }
3785 uc_free(wname);
3786#endif
3787 if (f) {
3788 nn = fwrite(p, 1, n, f);
3789 fclose(f);
3790 if (nn != n) {
3791 sqlite3_result_error(ctx, "write error", -1);
3792 } else {
3793 sqlite3_result_int(ctx, nn);
3794 }
3795 } else {
3796 sqlite3_result_error(ctx, "cannot open file", -1);
3797 }
3798 } else {
3799 sqlite3_result_error(ctx, "no filename given", -1);
3800 }
3801 } else {
3802 sqlite3_result_null(ctx);
3803 }
3804}
3805
3813static void
3814#if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3815dbtrace(void *arg, const char *msg, sqlite_uint64 et)
3816#else
3817dbtrace(void *arg, const char *msg)
3818#endif
3819{
3820 DBC *d = (DBC *) arg;
3821
3822 if (msg && d->trace) {
3823 int len = strlen(msg);
3824#if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3825 unsigned long s, f;
3826#endif
3827
3828 if (len > 0) {
3829 char *end = "\n";
3830
3831 if (msg[len - 1] != ';') {
3832 end = ";\n";
3833 }
3834 fprintf(d->trace, "%s%s", msg, end);
3835#if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3836 s = et / 1000000000LL;
3837 f = et % 1000000000LL;
3838 fprintf(d->trace, "-- took %lu.%09lu seconds\n", s, f);
3839#endif
3840 fflush(d->trace);
3841 }
3842 }
3843}
3844
3852static void
3853dbtraceapi(DBC *d, char *fn, const char *sql)
3854{
3855 if (fn && d->trace) {
3856 if (sql) {
3857 fprintf(d->trace, "-- %s: %s\n", fn, sql);
3858 } else {
3859 fprintf(d->trace, "-- %s\n", fn);
3860 }
3861 fflush(d->trace);
3862 }
3863}
3864
3872static void
3873dbtracerc(DBC *d, int rc, char *err)
3874{
3875 if (rc != SQLITE_OK && d->trace) {
3876 fprintf(d->trace, "-- SQLITE ERROR CODE %d", rc);
3877 fprintf(d->trace, err ? ": %s\n" : "\n", err);
3878 fflush(d->trace);
3879 }
3880}
3881
3896static SQLRETURN
3897dbopen(DBC *d, char *name, int isu, char *dsn, char *sflag,
3898 char *spflag, char *ntflag, char *jmode, char *busy)
3899{
3900 char *endp = NULL;
3901 int rc, tmp, busyto = 100000;
3902#if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
3903 int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
3904 char *uname = name;
3905 const char *vfs_name = NULL;
3906#endif
3907
3908 if (d->sqlite) {
3909 if (d->trace) {
3910 fprintf(d->trace, "-- sqlite3_close (deferred): '%s'\n",
3911 d->dbname);
3912 fflush(d->trace);
3913 }
3914#if defined(HAVE_SQLITE3CLOSEV2) && (HAVE_SQLITE3CLOSEV2)
3915 sqlite3_close_v2(d->sqlite);
3916#else
3917 sqlite3_close(d->sqlite);
3918#endif
3919 d->sqlite = NULL;
3920 }
3921#if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
3922 if (d->nocreat) {
3923 flags &= ~ SQLITE_OPEN_CREATE;
3924 }
3925#if defined(_WIN32) || defined(_WIN64)
3926 if (!isu) {
3927 char expname[SQL_MAX_MESSAGE_LENGTH * 2];
3928
3929 expname[0] = '\0';
3930 rc = ExpandEnvironmentStrings(name, expname, sizeof (expname));
3931 if (rc <= sizeof (expname)) {
3932 uname = wmb_to_utf(expname, rc - 1);
3933 } else {
3934 uname = wmb_to_utf(name, -1);
3935 }
3936 if (!uname) {
3937 rc = SQLITE_NOMEM;
3938 setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
3939 return SQL_ERROR;
3940 }
3941 }
3942#endif
3943#if defined(ENABLE_NVFS) && (ENABLE_NVFS)
3944 vfs_name = nvfs_makevfs(uname);
3945#endif
3946#ifdef SQLITE_OPEN_URI
3947 flags |= SQLITE_OPEN_URI;
3948#endif
3949 rc = sqlite3_open_v2(uname, &d->sqlite, flags, vfs_name);
3950#if defined(WINTERFACE) || defined(_WIN32) || defined(_WIN64)
3951 if (uname != name) {
3952 uc_free(uname);
3953 }
3954#endif
3955#else
3956#if defined(_WIN32) || defined(_WIN64)
3957 if (d->nocreat) {
3958 char *cname = NULL;
3959
3960 if (isu) {
3961 cname = utf_to_wmb(name, -1);
3962 }
3963 if (GetFileAttributesA(cname ? cname : name) ==
3964 INVALID_FILE_ATTRIBUTES) {
3965 uc_free(cname);
3966 rc = SQLITE_CANTOPEN;
3967 setstatd(d, rc, "cannot open database",
3968 (*d->ov3) ? "HY000" : "S1000");
3969 return SQL_ERROR;
3970 }
3971 uc_free(cname);
3972 }
3973#else
3974 if (d->nocreat && access(name, 004) < 0) {
3975 rc = SQLITE_CANTOPEN;
3976 setstatd(d, rc, "cannot open database", (*d->ov3) ? "HY000" : "S1000");
3977 return SQL_ERROR;
3978 }
3979#endif
3980#if defined(_WIN32) || defined(_WIN64)
3981 if (!isu) {
3982 WCHAR *wname = wmb_to_uc(name, -1);
3983
3984 if (!wname) {
3985 rc = SQLITE_NOMEM;
3986 setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
3987 return SQL_ERROR;
3988 }
3989 rc = sqlite3_open16(wname, &d->sqlite);
3990 uc_free(wname);
3991 } else
3992#endif
3993 rc = sqlite3_open(name, &d->sqlite);
3994#endif /* !HAVE_SQLITE3VFS */
3995 if (rc != SQLITE_OK) {
3996connfail:
3997 setstatd(d, rc, "connect failed", (*d->ov3) ? "HY000" : "S1000");
3998 if (d->sqlite) {
3999 sqlite3_close(d->sqlite);
4000 d->sqlite = NULL;
4001 }
4002 return SQL_ERROR;
4003 }
4004#if defined(SQLITE_DYNLOAD) || defined(SQLITE_HAS_CODEC)
4005 if (d->pwd) {
4006 sqlite3_key(d->sqlite, d->pwd, d->pwdLen);
4007 }
4008#endif
4009 d->pwd = NULL;
4010 d->pwdLen = 0;
4011 if (d->trace) {
4012#if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
4013 sqlite3_profile(d->sqlite, dbtrace, d);
4014#else
4015 sqlite3_trace(d->sqlite, dbtrace, d);
4016#endif
4017 }
4018 d->step_enable = getbool(sflag);
4019 d->trans_disable = getbool(ntflag);
4020 d->curtype = d->step_enable ?
4021 SQL_CURSOR_FORWARD_ONLY : SQL_CURSOR_STATIC;
4022 tmp = strtol(busy, &endp, 0);
4023 if (endp && *endp == '\0' && endp != busy) {
4024 busyto = tmp;
4025 }
4026 if (busyto < 1 || busyto > 1000000) {
4027 busyto = 1000000;
4028 }
4029 d->timeout = busyto;
4030 freep(&d->dbname);
4031 d->dbname = xstrdup(name);
4032 freep(&d->dsn);
4033 d->dsn = xstrdup(dsn);
4034 if ((rc = setsqliteopts(d->sqlite, d)) != SQLITE_OK) {
4035 if (d->trace) {
4036 fprintf(d->trace, "-- sqlite3_close: '%s'\n",
4037 d->dbname);
4038 fflush(d->trace);
4039 }
4040 sqlite3_close(d->sqlite);
4041 d->sqlite = NULL;
4042 goto connfail;
4043 }
4044 if (!spflag || spflag[0] == '\0') {
4045 spflag = "NORMAL";
4046 }
4047 if (spflag[0] != '\0') {
4048 char syncp[128];
4049
4050 sprintf(syncp, "PRAGMA synchronous = %8.8s;", spflag);
4051 sqlite3_exec(d->sqlite, syncp, NULL, NULL, NULL);
4052 }
4053 if (jmode[0] != '\0') {
4054 char jourp[128];
4055
4056 sprintf(jourp, "PRAGMA journal_mode = %16.16s;", jmode);
4057 sqlite3_exec(d->sqlite, jourp, NULL, NULL, NULL);
4058 }
4059 if (d->trace) {
4060 fprintf(d->trace, "-- sqlite3_open: '%s'\n", d->dbname);
4061 fflush(d->trace);
4062 }
4063#if defined(_WIN32) || defined(_WIN64)
4064 {
4065 char pname[MAX_PATH];
4066 HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
4067 FALSE, GetCurrentProcessId());
4068
4069 pname[0] = '\0';
4070 if (h) {
4071 HMODULE m = NULL, l = LoadLibrary("psapi.dll");
4072 DWORD need;
4073 typedef BOOL (WINAPI *epmfunc)(HANDLE, HMODULE *, DWORD, LPDWORD);
4074 typedef BOOL (WINAPI *gmbfunc)(HANDLE, HMODULE, LPSTR, DWORD);
4075 epmfunc epm;
4076 gmbfunc gmb;
4077
4078 if (l) {
4079 epm = (epmfunc) GetProcAddress(l, "EnumProcessModules");
4080 gmb = (gmbfunc) GetProcAddress(l, "GetModuleBaseNameA");
4081 if (epm && gmb && epm(h, &m, sizeof (m), &need)) {
4082 gmb(h, m, pname, sizeof (pname));
4083 }
4084 FreeLibrary(l);
4085 }
4086 CloseHandle(h);
4087 }
4088 d->xcelqrx = strncasecmp(pname, "EXCEL", 5) == 0 ||
4089 strncasecmp(pname, "MSQRY", 5) == 0;
4090 if (d->trace && d->xcelqrx) {
4091
4092 fprintf(d->trace, "-- enabled EXCEL quirks\n");
4093 fflush(d->trace);
4094 }
4095 }
4096#endif
4097 sqlite3_create_function(d->sqlite, "blob_import", 1, SQLITE_UTF8,
4098 d, blob_import, 0, 0);
4099 sqlite3_create_function(d->sqlite, "blob_export", 2, SQLITE_UTF8,
4100 d, blob_export, 0, 0);
4101 return SQL_SUCCESS;
4102}
4103
4110static void
4111dbloadext(DBC *d, char *exts)
4112{
4113#if defined(HAVE_SQLITE3LOADEXTENSION) && (HAVE_SQLITE3LOADEXTENSION)
4114 char *p;
4115 char path[SQL_MAX_MESSAGE_LENGTH];
4116 int plen = 0;
4117
4118 if (!d->sqlite) {
4119 return;
4120 }
4121 sqlite3_enable_load_extension(d->sqlite, 1);
4122#if defined(_WIN32) || defined(_WIN64)
4123 GetModuleFileName(hModule, path, sizeof (path));
4124 p = strrchr(path, '\\');
4125 plen = p ? ((p + 1) - path) : 0;
4126#endif
4127 do {
4128 p = strchr(exts, ',');
4129 if (p) {
4130 strncpy(path + plen, exts, p - exts);
4131 path[plen + (p - exts)] = '\0';
4132 } else {
4133 strcpy(path + plen, exts);
4134 }
4135 if (exts[0]) {
4136 char *errmsg = NULL;
4137 int rc;
4138#if defined(_WIN32) || defined(_WIN64)
4139 int i;
4140 char *q;
4141
4142 q = path + plen;
4143 if (!(q[0] &&
4144 ((q[1] == ':' && (q[2] == '\\' || q[2] == '/')) ||
4145 q[0] == '\\' || q[0] == '/' || q[0] == '.'))) {
4146 q = path;
4147 }
4148 /* sqlite3_load_extension() dislikes backslashes */
4149 for (i = 0; q[i] != '\0'; i++) {
4150 if (q[i] == '\\') {
4151 q[i] = '/';
4152 }
4153 }
4154 rc = sqlite3_load_extension(d->sqlite, q, 0, &errmsg);
4155#else
4156 rc = sqlite3_load_extension(d->sqlite, path, 0, &errmsg);
4157#endif
4158 if (rc != SQLITE_OK) {
4159#if defined(_WIN32) || defined(_WIN64)
4160 char buf[512], msg[512];
4161
4162 LoadString(hModule, IDS_EXTERR, buf, sizeof (buf));
4163 wsprintf(msg, buf, q, errmsg ?
4164 errmsg : "no error info available");
4165 LoadString(hModule, IDS_EXTTITLE, buf, sizeof (buf));
4166 MessageBox(NULL, msg, buf,
4167 MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
4168 MB_SETFOREGROUND);
4169#else
4170 fprintf(stderr, "extension '%s' did not load%s%s\n",
4171 path, errmsg ? ": " : "", errmsg ? errmsg : "");
4172#endif
4173 }
4174 }
4175 if (p) {
4176 exts = p + 1;
4177 }
4178 } while (p);
4179#endif /* HAVE_SQLITE3LOADEXTENSION */
4180}
4181
4191static char *
4192s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
4193{
4194 char *typename = (char *) sqlite3_column_decltype(s3stmt, col);
4195 char guess[64];
4196
4197 guess[0] = '\0';
4198 if (!typename) {
4199 int coltype = sqlite3_column_type(s3stmt, col);
4200
4201 if (guessed_types) {
4202 guessed_types[0]++;
4203 }
4204 if (d->trace) {
4205 sprintf(guess, " (guessed from %d)", coltype);
4206 }
4207 switch (coltype) {
4208 case SQLITE_INTEGER: typename = "integer"; break;
4209 case SQLITE_FLOAT: typename = "double"; break;
4210 default:
4211 case SQLITE_TEXT: typename = "varchar"; break;
4212 case SQLITE_BLOB: typename = "blob"; break;
4213#if 0
4214 case SQLITE_NULL: typename = "null"; break;
4215#endif
4216 }
4217 }
4218 if (d->trace) {
4219 fprintf(d->trace, "-- column %d type%s: '%s'\n", col + 1,
4220 guess, typename);
4221 fflush(d->trace);
4222 }
4223 return typename;
4224}
4225
4226#ifdef FULL_METADATA
4227
4236static void
4237s3stmt_addmeta(sqlite3_stmt *s3stmt, int col, DBC *d, COL *ci)
4238{
4239 int nn = 0, pk = 0, ai = 0;
4240 const char *dn = NULL, *tn = NULL, *cn = NULL, *dummy[4];
4241
4242 dn = sqlite3_column_database_name(s3stmt, col);
4243 tn = sqlite3_column_table_name(s3stmt, col);
4244 cn = sqlite3_column_origin_name(s3stmt, col);
4245 dummy[0] = dummy[1] = 0;
4246 if (tn && cn) {
4247 sqlite3_table_column_metadata(d->sqlite, dn, tn, cn,
4248 dummy, dummy + 1,
4249 &nn, &pk, &ai);
4250 }
4251 ci->autoinc = ai ? SQL_TRUE: SQL_FALSE;
4252 ci->notnull = nn ? SQL_NO_NULLS : SQL_NULLABLE;
4253 ci->ispk = pk ? 1 : 0;
4254 if (d->trace) {
4255 fprintf(d->trace, "-- column %d %s\n",
4256 col + 1, nn ? "notnull" : "nullable");
4257 if (ai) {
4258 fprintf(d->trace, "-- column %d autoincrement\n", col + 1);
4259 }
4260 fflush(d->trace);
4261 }
4262 ci->isrowid = 0;
4263 if (ci->ispk && tn) {
4264 nn = pk = ai = 0;
4265 dummy[2] = dummy[3] = 0;
4266
4267 sqlite3_table_column_metadata(d->sqlite, dn, tn, "rowid",
4268 dummy + 2, dummy + 3,
4269 &nn, &pk, &ai);
4270 if (pk && dummy[0] && dummy[0] == dummy[2]) {
4271 ci->isrowid = 1;
4272 }
4273 }
4274}
4275
4276#endif
4277
4284static int
4286{
4287 DBC *d = (DBC *) s->dbc;
4288 char **rowd = NULL;
4289 const char *errp = NULL;
4290 int i, ncols, rc;
4291
4292 if (s != d->cur_s3stmt || !s->s3stmt) {
4293 setstat(s, -1, "stale statement", (*s->ov3) ? "HY000" : "S1000");
4294 return SQL_ERROR;
4295 }
4296 rc = sqlite3_step(s->s3stmt);
4297 if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
4298 ++s->s3stmt_rownum;
4299 ncols = sqlite3_column_count(s->s3stmt);
4300 if (d->s3stmt_needmeta && s->s3stmt_rownum == 0 && ncols > 0) {
4301 PTRDIFF_T size;
4302 char *p;
4303 COL *dyncols;
4304 const char *colname, *typename;
4305#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4306 char *tblname;
4307#endif
4308#if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
4309 char *dbname;
4310#endif
4311
4312 for (i = size = 0; i < ncols; i++) {
4313 colname = sqlite3_column_name(s->s3stmt, i);
4314 size += 3 + 3 * strlen(colname);
4315 }
4316#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4317 tblname = (char *) size;
4318 for (i = 0; i < ncols; i++) {
4319 p = (char *) sqlite3_column_table_name(s->s3stmt, i);
4320 size += 2 + (p ? strlen(p) : 0);
4321 }
4322#endif
4323#if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
4324 dbname = (char *) size;
4325 for (i = 0; i < ncols; i++) {
4326 p = (char *) sqlite3_column_database_name(s->s3stmt, i);
4327 size += 2 + (p ? strlen(p) : 0);
4328 }
4329#endif
4330 dyncols = xmalloc(ncols * sizeof (COL) + size);
4331 if (!dyncols) {
4332 freedyncols(s);
4333 s->ncols = 0;
4334 dbtraceapi(d, "sqlite3_finalize", 0);
4335 sqlite3_finalize(s->s3stmt);
4336 s->s3stmt = NULL;
4337 d->cur_s3stmt = NULL;
4338 return nomem(s);
4339 }
4340 p = (char *) (dyncols + ncols);
4341#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4342 tblname = p + (PTRDIFF_T) tblname;
4343#endif
4344#if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
4345 dbname = p + (PTRDIFF_T) dbname;
4346#endif
4347 for (i = 0; i < ncols; i++) {
4348 char *q;
4349
4350 colname = sqlite3_column_name(s->s3stmt, i);
4351 if (d->trace) {
4352 fprintf(d->trace, "-- column %d name: '%s'\n",
4353 i + 1, colname);
4354 fflush(d->trace);
4355 }
4356#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4357 q = (char *) sqlite3_column_table_name(s->s3stmt, i);
4358 strcpy(tblname, q ? q : "");
4359 if (d->trace) {
4360 fprintf(d->trace, "-- table %d name: '%s'\n",
4361 i + 1, tblname);
4362 fflush(d->trace);
4363 }
4364 dyncols[i].table = tblname;
4365 tblname += strlen(tblname) + 1;
4366#endif
4367#if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
4368 q = (char *) sqlite3_column_database_name(s->s3stmt, i);
4369 strcpy(dbname, q ? q : "");
4370 if (d->trace) {
4371 fprintf(d->trace, "-- database %d name: '%s'\n",
4372 i + 1, dbname);
4373 fflush(d->trace);
4374 }
4375 dyncols[i].db = dbname;
4376 dbname += strlen(dbname) + 1;
4377#else
4378 dyncols[i].db = ((DBC *) (s->dbc))->dbname;
4379#endif
4380 typename = s3stmt_coltype(s->s3stmt, i, d, 0);
4381 strcpy(p, colname);
4382 dyncols[i].label = p;
4383 p += strlen(p) + 1;
4384 q = strchr(colname, '.');
4385 if (q) {
4386 char *q2 = strchr(q + 1, '.');
4387
4388 /* SQLite 3.3.4 produces view.table.column sometimes */
4389 if (q2) {
4390 q = q2;
4391 }
4392 }
4393 if (q) {
4394#if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
4395 dyncols[i].table = p;
4396#endif
4397 strncpy(p, colname, q - colname);
4398 p[q - colname] = '\0';
4399 p += strlen(p) + 1;
4400 strcpy(p, q + 1);
4401 dyncols[i].column = p;
4402 p += strlen(p) + 1;
4403 } else {
4404#if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
4405 dyncols[i].table = "";
4406#endif
4407 strcpy(p, colname);
4408 dyncols[i].column = p;
4409 p += strlen(p) + 1;
4410 }
4411 if (s->longnames) {
4412 dyncols[i].column = dyncols[i].label;
4413 }
4414#ifdef SQL_LONGVARCHAR
4415 dyncols[i].type = SQL_LONGVARCHAR;
4416 dyncols[i].size = 65535;
4417#else
4418 dyncols[i].type = SQL_VARCHAR;
4419 dyncols[i].size = 255;
4420#endif
4421 dyncols[i].index = i;
4422 dyncols[i].scale = 0;
4423 dyncols[i].prec = 0;
4424 dyncols[i].nosign = 1;
4425 dyncols[i].autoinc = SQL_FALSE;
4426 dyncols[i].notnull = SQL_NULLABLE;
4427 dyncols[i].ispk = -1;
4428 dyncols[i].isrowid = -1;
4429#ifdef FULL_METADATA
4430 s3stmt_addmeta(s->s3stmt, i, d, &dyncols[i]);
4431#endif
4432 dyncols[i].typename = xstrdup(typename);
4433 }
4434 freedyncols(s);
4435 s->ncols = s->dcols = ncols;
4436 s->dyncols = s->cols = dyncols;
4437 fixupdyncols(s, d);
4438 mkbindcols(s, s->ncols);
4439 d->s3stmt_needmeta = 0;
4440 }
4441 if (ncols <= 0) {
4442 goto killstmt;
4443 }
4444 if (rc == SQLITE_DONE) {
4445 freeresult(s, 0);
4446 s->nrows = 0;
4447 dbtraceapi(d, "sqlite3_finalize", 0);
4448 sqlite3_finalize(s->s3stmt);
4449 s->s3stmt = NULL;
4450 d->cur_s3stmt = NULL;
4451 return SQL_SUCCESS;
4452 }
4453 rowd = xmalloc((1 + 2 * ncols) * sizeof (char *));
4454 if (rowd) {
4455 const unsigned char *value;
4456
4457 rowd[0] = (char *) ((PTRDIFF_T) (ncols * 2));
4458 ++rowd;
4459 for (i = 0; i < ncols; i++) {
4460 int coltype = sqlite3_column_type(s->s3stmt, i);
4461
4462 rowd[i] = rowd[i + ncols] = NULL;
4463 if (coltype == SQLITE_BLOB) {
4464 int k, nbytes = sqlite3_column_bytes(s->s3stmt, i);
4465 char *qp;
4466 unsigned const char *bp;
4467
4468 bp = sqlite3_column_blob(s->s3stmt, i);
4469 qp = xmalloc(nbytes * 2 + 4);
4470 if (qp) {
4471 rowd[i + ncols] = qp;
4472 *qp++ = 'X';
4473 *qp++ = '\'';
4474 for (k = 0; k < nbytes; k++) {
4475 *qp++ = xdigits[(bp[k] >> 4)];
4476 *qp++ = xdigits[(bp[k] & 0xF)];
4477 }
4478 *qp++ = '\'';
4479 *qp = '\0';
4480 }
4481#ifdef _MSC_VER
4482 } else if (coltype == SQLITE_FLOAT) {
4483 struct lconv *lc = 0;
4484 double d = sqlite3_column_double(s->s3stmt, i);
4485 char *p, buffer[128];
4486
4487 /*
4488 * This avoids floating point rounding
4489 * and formatting problems of some SQLite
4490 * versions in conjunction with MSVC 2010.
4491 */
4492 snprintf(buffer, sizeof (buffer), "%.15g", d);
4493 lc = localeconv();
4494 if (lc && lc->decimal_point && lc->decimal_point[0] &&
4495 lc->decimal_point[0] != '.') {
4496 p = strchr(buffer, lc->decimal_point[0]);
4497 if (p) {
4498 *p = '.';
4499 }
4500 }
4501 rowd[i + ncols] = xstrdup(buffer);
4502#endif
4503 } else if (coltype != SQLITE_NULL) {
4504 value = sqlite3_column_text(s->s3stmt, i);
4505 rowd[i + ncols] = xstrdup((char *) value);
4506 }
4507 }
4508 for (i = 0; i < ncols; i++) {
4509 int coltype = sqlite3_column_type(s->s3stmt, i);
4510
4511 value = NULL;
4512 if (coltype == SQLITE_BLOB) {
4513 value = sqlite3_column_blob(s->s3stmt, i);
4514 } else if (coltype != SQLITE_NULL) {
4515 value = sqlite3_column_text(s->s3stmt, i);
4516 }
4517 if (value && !rowd[i + ncols]) {
4518 freerows(rowd);
4519 rowd = 0;
4520 break;
4521 }
4522 }
4523 }
4524 if (rowd) {
4525 freeresult(s, 0);
4526 s->nrows = 1;
4527 s->rows = rowd;
4528 s->rowfree = freerows;
4529 if (rc == SQLITE_DONE) {
4530 dbtraceapi(d, "sqlite3_finalize", 0);
4531 sqlite3_finalize(s->s3stmt);
4532 s->s3stmt = NULL;
4533 d->cur_s3stmt = NULL;
4534 }
4535 return SQL_SUCCESS;
4536 }
4537 }
4538killstmt:
4539 dbtraceapi(d, "sqlite3_reset", 0);
4540 rc = sqlite3_reset(s->s3stmt);
4541 s->s3stmt_noreset = 1;
4542 errp = sqlite3_errmsg(d->sqlite);
4543 if (d->cur_s3stmt == s) {
4544 d->cur_s3stmt = NULL;
4545 }
4546 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
4547 errp ? errp : "unknown error", rc);
4548 return SQL_ERROR;
4549}
4550
4556static void
4558{
4559 DBC *d;
4560
4561 if (!s || !s->s3stmt) {
4562 return;
4563 }
4564 d = (DBC *) s->dbc;
4565 if (d) {
4566 d->busyint = 0;
4567 }
4568 if (!s->s3stmt_noreset) {
4569 dbtraceapi(d, "sqlite3_reset", 0);
4570 sqlite3_reset(s->s3stmt);
4571 s->s3stmt_noreset = 1;
4572 s->s3stmt_rownum = -1;
4573 }
4574 if (d->cur_s3stmt == s) {
4575 d->cur_s3stmt = NULL;
4576 }
4577}
4578
4584static void
4586{
4587 DBC *d = (DBC *) s->dbc;
4588
4589 if (d) {
4590 d->busyint = 0;
4591 }
4592 if (d && d->cur_s3stmt == s) {
4593 s3stmt_end(s);
4594 }
4595}
4596
4602static void
4604{
4605 if (s->s3stmt) {
4606 DBC *d = (DBC *) s->dbc;
4607
4608 if (d) {
4609 dbtraceapi(d, "sqlite3_finalize", 0);
4610 }
4611 sqlite3_finalize(s->s3stmt);
4612 s->s3stmt = NULL;
4613 s->s3stmt_rownum = 0;
4614 }
4615}
4616
4623static SQLRETURN
4625{
4626 DBC *d = (DBC *) s->dbc;
4627 const char *endp;
4628 sqlite3_stmt *s3stmt = NULL;
4629 int rc, nretry = 0;
4630
4631 d->s3stmt_needmeta = 0;
4632 if (!s->s3stmt) {
4633#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
4634 dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
4635#else
4636 dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
4637#endif
4638 do {
4639 s3stmt = NULL;
4640#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
4641 rc = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
4642 &s3stmt, &endp);
4643#else
4644 rc = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
4645 &s3stmt, &endp);
4646#endif
4647 if (rc != SQLITE_OK) {
4648 if (s3stmt) {
4649 sqlite3_finalize(s3stmt);
4650 s3stmt = NULL;
4651 }
4652 }
4653 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
4654 dbtracerc(d, rc, NULL);
4655 if (rc != SQLITE_OK) {
4656 if (s3stmt) {
4657 dbtraceapi(d, "sqlite3_finalize", NULL);
4658 sqlite3_finalize(s3stmt);
4659 }
4660 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
4661 sqlite3_errmsg(d->sqlite), rc);
4662 return SQL_ERROR;
4663 }
4664 if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
4665 dbtraceapi(d, "sqlite3_finalize", 0);
4666 sqlite3_finalize(s3stmt);
4667 setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
4668 (*s->ov3) ? "HY000" : "S1000");
4669 return SQL_ERROR;
4670 }
4671 s->s3stmt = s3stmt;
4672 s->s3stmt_noreset = 1;
4673 d->s3stmt_needmeta = 1;
4674 }
4675 d->cur_s3stmt = s;
4676 s->s3stmt_rownum = -1;
4677 s3bind(d, s->s3stmt, s->nparams, s->bindparms);
4678 return SQL_SUCCESS;
4679}
4680
4681#ifndef WINTERFACE
4686SQLRETURN SQL_API
4687SQLDataSources(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *srvname,
4688 SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
4689 SQLCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
4690{
4691 if (env == SQL_NULL_HENV) {
4692 return SQL_INVALID_HANDLE;
4693 }
4694 return SQL_ERROR;
4695}
4696#endif
4697
4698#ifdef WINTERFACE
4703SQLRETURN SQL_API
4704SQLDataSourcesW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *srvname,
4705 SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
4706 SQLWCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
4707{
4708 if (env == SQL_NULL_HENV) {
4709 return SQL_INVALID_HANDLE;
4710 }
4711 return SQL_ERROR;
4712}
4713#endif
4714
4715#ifndef WINTERFACE
4720SQLRETURN SQL_API
4721SQLDrivers(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *drvdesc,
4722 SQLSMALLINT descmax, SQLSMALLINT *desclenp,
4723 SQLCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
4724{
4725 if (env == SQL_NULL_HENV) {
4726 return SQL_INVALID_HANDLE;
4727 }
4728 return SQL_ERROR;
4729}
4730#endif
4731
4732#ifdef WINTERFACE
4737SQLRETURN SQL_API
4738SQLDriversW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *drvdesc,
4739 SQLSMALLINT descmax, SQLSMALLINT *desclenp,
4740 SQLWCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
4741{
4742 if (env == SQL_NULL_HENV) {
4743 return SQL_INVALID_HANDLE;
4744 }
4745 return SQL_ERROR;
4746}
4747#endif
4748
4749#ifndef WINTERFACE
4754SQLRETURN SQL_API
4755SQLBrowseConnect(SQLHDBC dbc, SQLCHAR *connin, SQLSMALLINT conninLen,
4756 SQLCHAR *connout, SQLSMALLINT connoutMax,
4757 SQLSMALLINT *connoutLen)
4758{
4759 SQLRETURN ret;
4760
4761 HDBC_LOCK(dbc);
4762 ret = drvunimpldbc(dbc);
4764 return ret;
4765}
4766#endif
4767
4768#ifdef WINTERFACE
4773SQLRETURN SQL_API
4774SQLBrowseConnectW(SQLHDBC dbc, SQLWCHAR *connin, SQLSMALLINT conninLen,
4775 SQLWCHAR *connout, SQLSMALLINT connoutMax,
4776 SQLSMALLINT *connoutLen)
4777{
4778 SQLRETURN ret;
4779
4780 HDBC_LOCK(dbc);
4781 ret = drvunimpldbc(dbc);
4783 return ret;
4784}
4785#endif
4786
4795static SQLRETURN
4796drvputdata(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
4797{
4798 STMT *s;
4799 int i, dlen, done = 0;
4800 BINDPARM *p;
4801
4802 if (stmt == SQL_NULL_HSTMT) {
4803 return SQL_INVALID_HANDLE;
4804 }
4805 s = (STMT *) stmt;
4806 if (!s->query || s->nparams <= 0) {
4807seqerr:
4808 setstat(s, -1, "sequence error", "HY010");
4809 return SQL_ERROR;
4810 }
4811 for (i = (s->pdcount < 0) ? 0 : s->pdcount; i < s->nparams; i++) {
4812 p = &s->bindparms[i];
4813 if (p->need > 0) {
4814 int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
4815
4816 if (len == SQL_NULL_DATA) {
4817 freep(&p->parbuf);
4818 p->param = NULL;
4819 p->len = SQL_NULL_DATA;
4820 p->need = -1;
4821 } else if (type != SQL_C_CHAR
4822#ifdef WCHARSUPPORT
4823 && type != SQL_C_WCHAR
4824#endif
4825 && type != SQL_C_BINARY) {
4826 int size = 0;
4827
4828 switch (type) {
4829 case SQL_C_TINYINT:
4830 case SQL_C_UTINYINT:
4831 case SQL_C_STINYINT:
4832#ifdef SQL_BIT
4833 case SQL_C_BIT:
4834#endif
4835 size = sizeof (SQLCHAR);
4836 break;
4837 case SQL_C_SHORT:
4838 case SQL_C_USHORT:
4839 case SQL_C_SSHORT:
4840 size = sizeof (SQLSMALLINT);
4841 break;
4842 case SQL_C_LONG:
4843 case SQL_C_ULONG:
4844 case SQL_C_SLONG:
4845 size = sizeof (SQLINTEGER);
4846 break;
4847#ifdef SQL_BIGINT
4848 case SQL_C_UBIGINT:
4849 case SQL_C_SBIGINT:
4850 size = sizeof (SQLBIGINT);
4851 break;
4852#endif
4853 case SQL_C_FLOAT:
4854 size = sizeof (float);
4855 break;
4856 case SQL_C_DOUBLE:
4857 size = sizeof (double);
4858 break;
4859#ifdef SQL_C_TYPE_DATE
4860 case SQL_C_TYPE_DATE:
4861#endif
4862 case SQL_C_DATE:
4863 size = sizeof (DATE_STRUCT);
4864 break;
4865#ifdef SQL_C_TYPE_DATE
4866 case SQL_C_TYPE_TIME:
4867#endif
4868 case SQL_C_TIME:
4869 size = sizeof (TIME_STRUCT);
4870 break;
4871#ifdef SQL_C_TYPE_DATE
4872 case SQL_C_TYPE_TIMESTAMP:
4873#endif
4874 case SQL_C_TIMESTAMP:
4875 size = sizeof (TIMESTAMP_STRUCT);
4876 break;
4877 }
4878 freep(&p->parbuf);
4879 p->parbuf = xmalloc(size);
4880 if (!p->parbuf) {
4881 return nomem(s);
4882 }
4883 p->param = p->parbuf;
4884 memcpy(p->param, data, size);
4885 p->len = size;
4886 p->need = -1;
4887 } else if (len == SQL_NTS && (
4888 type == SQL_C_CHAR
4889#ifdef WCHARSUPPORT
4890 || type == SQL_C_WCHAR
4891#endif
4892 )) {
4893 char *dp = data;
4894
4895#ifdef WCHARSUPPORT
4896 if (type == SQL_C_WCHAR) {
4897 dp = uc_to_utf(data, len);
4898 if (!dp) {
4899 return nomem(s);
4900 }
4901 }
4902#endif
4903#if defined(_WIN32) || defined(_WIN64)
4904 if (*s->oemcp) {
4905 dp = wmb_to_utf(data, strlen (data));
4906 if (!dp) {
4907 return nomem(s);
4908 }
4909 }
4910#endif
4911 dlen = strlen(dp);
4912 freep(&p->parbuf);
4913 p->parbuf = xmalloc(dlen + 1);
4914 if (!p->parbuf) {
4915 if (dp != data) {
4916 uc_free(dp);
4917 }
4918 return nomem(s);
4919 }
4920 p->param = p->parbuf;
4921 strcpy(p->param, dp);
4922 if (dp != data) {
4923 uc_free(dp);
4924 }
4925 p->len = dlen;
4926 p->need = -1;
4927 } else if (len < 0) {
4928 setstat(s, -1, "invalid length", "HY090");
4929 return SQL_ERROR;
4930 } else {
4931 dlen = min(p->len - p->offs, len);
4932 if (!p->param) {
4933 setstat(s, -1, "no memory for parameter", "HY013");
4934 return SQL_ERROR;
4935 }
4936 memcpy((char *) p->param + p->offs, data, dlen);
4937 p->offs += dlen;
4938 if (p->offs >= p->len) {
4939#ifdef WCHARSUPPORT
4940 if (type == SQL_C_WCHAR) {
4941 char *dp = uc_to_utf(p->param, p->len);
4942 char *np;
4943 int nlen;
4944
4945 if (!dp) {
4946 return nomem(s);
4947 }
4948 nlen = strlen(dp);
4949 np = xmalloc(nlen + 1);
4950 if (!np) {
4951 uc_free(dp);
4952 return nomem(s);
4953 }
4954 strcpy(np, dp);
4955 uc_free(dp);
4956 if (p->param == p->parbuf) {
4957 freep(&p->parbuf);
4958 }
4959 p->parbuf = p->param = np;
4960 p->len = nlen;
4961 } else {
4962 *((char *) p->param + p->len) = '\0';
4963 }
4964 p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR)
4965 ? -1 : 0;
4966#else
4967 *((char *) p->param + p->len) = '\0';
4968 p->need = (type == SQL_C_CHAR) ? -1 : 0;
4969#endif
4970#if defined(_WIN32) || defined(_WIN64)
4971 if (type == SQL_C_CHAR && *s->oemcp &&
4972 !(p->stype == SQL_BINARY ||
4973 p->stype == SQL_VARBINARY ||
4974 p->stype == SQL_LONGVARBINARY)) {
4975 char *dp = wmb_to_utf(p->param, p->len);
4976
4977 if (!dp) {
4978 return nomem(s);
4979 }
4980 if (p->param == p->parbuf) {
4981 freep(&p->parbuf);
4982 }
4983 p->parbuf = p->param = dp;
4984 p->len = strlen(dp);
4985 }
4986 if (p->type == SQL_C_WCHAR &&
4987 (p->stype == SQL_VARCHAR ||
4988 p->stype == SQL_LONGVARCHAR) &&
4989 p->len == p->coldef * sizeof (SQLWCHAR)) {
4990 /* fix for MS-Access */
4991 p->len = p->coldef;
4992 }
4993#endif
4994 }
4995 }
4996 done = 1;
4997 break;
4998 }
4999 }
5000 if (!done) {
5001 goto seqerr;
5002 }
5003 return SQL_SUCCESS;
5004}
5005
5014SQLRETURN SQL_API
5015SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
5016{
5017 SQLRETURN ret;
5018
5020 ret = drvputdata(stmt, data, len);
5022 return ret;
5023}
5024
5030static SQLRETURN
5032{
5033 if (s->bindparms) {
5034 int n;
5035
5036 for (n = 0; n < s->nbindparms; n++) {
5037 freep(&s->bindparms[n].parbuf);
5038 memset(&s->bindparms[n], 0, sizeof (BINDPARM));
5039 }
5040 }
5041 return SQL_SUCCESS;
5042}
5043
5055static SQLRETURN
5056setupparam(STMT *s, char *sql, int pnum)
5057{
5058 int type, len = 0, needalloc = 0;
5059 BINDPARM *p;
5060
5061 if (!s->bindparms || pnum < 0 || pnum >= s->nbindparms) {
5062 goto error;
5063 }
5064 p = &s->bindparms[pnum];
5065 type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
5066#if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
5067 /* MS Access hack part 4 (map SQL_C_DEFAULT to SQL_C_CHAR) */
5068 if (type == SQL_C_WCHAR && p->type == SQL_C_DEFAULT) {
5069 type = SQL_C_CHAR;
5070 }
5071#endif
5072 if (p->need > 0) {
5073 return setupparbuf(s, p);
5074 }
5075 p->strbuf[0] = '\0';
5076 if (!p->param || (p->lenp && *p->lenp == SQL_NULL_DATA)) {
5077 p->s3type = SQLITE_NULL;
5078 p->s3size = 0;
5079 return SQL_SUCCESS;
5080 }
5081 if (type == SQL_C_CHAR &&
5082 (p->stype == SQL_BINARY ||
5083 p->stype == SQL_VARBINARY ||
5084 p->stype == SQL_LONGVARBINARY)) {
5085 type = SQL_C_BINARY;
5086 }
5087 switch (type) {
5088 case SQL_C_BINARY:
5089 p->s3type = SQLITE_BLOB;
5090 p->s3size = p->len;
5091 p->s3val = p->param;
5092 if (p->need < 0) {
5093 break;
5094 }
5095 if (!p->lenp) {
5096 len = p->len;
5097 } else if (*p->lenp == SQL_DATA_AT_EXEC) {
5098 len = p->len;
5099 } else {
5100 len = *p->lenp;
5101 if (len <= SQL_LEN_DATA_AT_EXEC_OFFSET) {
5102 len = SQL_LEN_DATA_AT_EXEC(len);
5103 }
5104 }
5105 if (len < 0) {
5106 setstat(s, -1, "invalid length", "HY009");
5107 return SQL_ERROR;
5108 }
5109 p->len = len;
5110 p->max = p->len;
5111 p->need = -1;
5112 p->s3size = len;
5113 break;
5114#ifdef WCHARSUPPORT
5115 case SQL_C_WCHAR:
5116#endif
5117 case SQL_C_CHAR:
5118 p->s3type = SQLITE_TEXT;
5119 p->s3size = -1;
5120 p->s3val = p->param;
5121 if (!p->parbuf) {
5122#ifdef WCHARSUPPORT
5123 if (type == SQL_C_WCHAR) {
5124 if (!p->lenp || *p->lenp == SQL_NTS) {
5125 p->max = uc_strlen(p->param) * sizeof (SQLWCHAR);
5126 } else if (*p->lenp >= 0) {
5127 p->max = *p->lenp;
5128 }
5129 } else
5130#endif
5131 if (type == SQL_C_CHAR) {
5132 if (!p->lenp || *p->lenp == SQL_NTS) {
5133 p->len = p->max = strlen(p->param);
5134#if defined(_WIN32) || defined(_WIN64)
5135 needalloc = 1;
5136#endif
5137 } else if (*p->lenp >= 0) {
5138 p->len = p->max = *p->lenp;
5139 needalloc = 1;
5140 }
5141 }
5142 }
5143 if (p->need < 0 && p->parbuf == p->param) {
5144 break;
5145 }
5146#ifdef WCHARSUPPORT
5147 if (type == SQL_C_WCHAR) {
5148 char *dp = uc_to_utf(p->param, p->max);
5149
5150 if (!dp) {
5151 return nomem(s);
5152 }
5153 if (p->param == p->parbuf) {
5154 freep(&p->parbuf);
5155 }
5156 p->parbuf = p->param = dp;
5157 p->need = -1;
5158 p->len = strlen(p->param);
5159 p->s3val = p->param;
5160 p->s3size = p->len;
5161 } else
5162#endif
5163 if (type == SQL_C_CHAR) {
5164 p->s3val = p->param;
5165 if (needalloc) {
5166 char *dp;
5167
5168#if defined(_WIN32) || defined(_WIN64)
5169 if (*s->oemcp) {
5170 dp = wmb_to_utf(p->param, p->len);
5171 } else {
5172 dp = xmalloc(p->len + 1);
5173 }
5174#else
5175 dp = xmalloc(p->len + 1);
5176#endif
5177 if (!dp) {
5178 return nomem(s);
5179 }
5180#if defined(_WIN32) || defined(_WIN64)
5181 if (*s->oemcp) {
5182 p->len = strlen(dp);
5183 } else {
5184 memcpy(dp, p->param, p->len);
5185 dp[p->len] = '\0';
5186 }
5187#else
5188 memcpy(dp, p->param, p->len);
5189 dp[p->len] = '\0';
5190#endif
5191 if (p->param == p->parbuf) {
5192 freep(&p->parbuf);
5193 }
5194 p->parbuf = p->param = dp;
5195 p->need = -1;
5196 p->s3val = p->param;
5197 p->s3size = p->len;
5198 }
5199 }
5200 break;
5201 case SQL_C_UTINYINT:
5202 case SQL_C_TINYINT:
5203 case SQL_C_STINYINT:
5204 p->s3type = SQLITE_INTEGER;
5205 p->s3size = sizeof (int);
5206 p->s3ival = *((SQLCHAR *) p->param);
5207 break;
5208 case SQL_C_USHORT:
5209 p->s3type = SQLITE_INTEGER;
5210 p->s3size = sizeof (int);
5211 p->s3ival = *((SQLUSMALLINT *) p->param);
5212 break;
5213 case SQL_C_SHORT:
5214 case SQL_C_SSHORT:
5215 p->s3type = SQLITE_INTEGER;
5216 p->s3size = sizeof (int);
5217 p->s3ival = *((SQLSMALLINT *) p->param);
5218 break;
5219 case SQL_C_ULONG:
5220 p->s3type = SQLITE_INTEGER;
5221 p->s3size = sizeof (int);
5222 p->s3ival = *((SQLUINTEGER *) p->param);
5223 break;
5224 case SQL_C_LONG:
5225 case SQL_C_SLONG:
5226 p->s3type = SQLITE_INTEGER;
5227 p->s3size = sizeof (int);
5228 p->s3ival = *((SQLINTEGER *) p->param);
5229 break;
5230#ifdef SQL_BIT
5231 case SQL_C_BIT:
5232 p->s3type = SQLITE_INTEGER;
5233 p->s3size = sizeof (int);
5234 p->s3ival = (*((SQLCHAR *) p->param)) ? 1 : 0;
5235 break;
5236#endif
5237#ifdef SQL_BIGINT
5238 case SQL_C_SBIGINT:
5239 p->s3type = SQLITE_INTEGER;
5240 p->s3size = sizeof (sqlite_int64);
5241 p->s3lival = *((sqlite_int64 *) p->param);
5242 break;
5243 case SQL_C_UBIGINT:
5244 p->s3type = SQLITE_INTEGER;
5245 p->s3size = sizeof (sqlite_int64);
5246 p->s3lival = *((sqlite_uint64 *) p->param);
5247 break;
5248#endif
5249 case SQL_C_FLOAT:
5250 p->s3type = SQLITE_FLOAT;
5251 p->s3size = sizeof (double);
5252 p->s3dval = *((float *) p->param);
5253 break;
5254 case SQL_C_DOUBLE:
5255 p->s3type = SQLITE_FLOAT;
5256 p->s3size = sizeof (double);
5257 p->s3dval = *((double *) p->param);
5258 break;
5259#ifdef SQL_C_TYPE_DATE
5260 case SQL_C_TYPE_DATE:
5261#endif
5262 case SQL_C_DATE:
5263 if (*s->jdconv) {
5264 int a, b, x1, x2, y, m, d;
5265
5266 p->s3type = SQLITE_FLOAT;
5267 p->s3size = sizeof (double);
5268 y = ((DATE_STRUCT *) p->param)->year;
5269 m = ((DATE_STRUCT *) p->param)->month;
5270 d = ((DATE_STRUCT *) p->param)->day;
5271 if (m <= 2) {
5272 y--;
5273 m += 12;
5274 }
5275 a = y / 100;
5276 b = 2 - a + (a / 4);
5277 x1 = 36525 * (y + 4716) / 100;
5278 x2 = 306001 * (m + 1) / 10000;
5279 p->s3dval = x1 + x2 + d + b - 1524.5;
5280 break;
5281 }
5282 sprintf(p->strbuf, "%04d-%02d-%02d",
5283 ((DATE_STRUCT *) p->param)->year,
5284 ((DATE_STRUCT *) p->param)->month,
5285 ((DATE_STRUCT *) p->param)->day);
5286 p->s3type = SQLITE_TEXT;
5287 p->s3size = -1;
5288 p->s3val = p->strbuf;
5289 break;
5290#ifdef SQL_C_TYPE_TIME
5291 case SQL_C_TYPE_TIME:
5292#endif
5293 case SQL_C_TIME:
5294 if (*s->jdconv) {
5295 p->s3type = SQLITE_FLOAT;
5296 p->s3size = sizeof (double);
5297 p->s3dval = 2451544.5 +
5298 (((TIME_STRUCT *) p->param)->hour * 3600000.0 +
5299 ((TIME_STRUCT *) p->param)->minute * 60000.0 +
5300 ((TIME_STRUCT *) p->param)->second * 1000.0) / 86400000.0;
5301 break;
5302 }
5303 sprintf(p->strbuf, "%02d:%02d:%02d",
5304 ((TIME_STRUCT *) p->param)->hour,
5305 ((TIME_STRUCT *) p->param)->minute,
5306 ((TIME_STRUCT *) p->param)->second);
5307 p->s3type = SQLITE_TEXT;
5308 p->s3size = -1;
5309 p->s3val = p->strbuf;
5310 break;
5311#ifdef SQL_C_TYPE_TIMESTAMP
5312 case SQL_C_TYPE_TIMESTAMP:
5313#endif
5314 case SQL_C_TIMESTAMP:
5315 if (*s->jdconv) {
5316 int a, b, x1, x2, y, m, d;
5317
5318 p->s3type = SQLITE_FLOAT;
5319 p->s3size = sizeof (double);
5320 y = ((TIMESTAMP_STRUCT *) p->param)->year;
5321 m = ((TIMESTAMP_STRUCT *) p->param)->month;
5322 d = ((TIMESTAMP_STRUCT *) p->param)->day;
5323 if (m <= 2) {
5324 y--;
5325 m += 12;
5326 }
5327 a = y / 100;
5328 b = 2 - a + (a / 4);
5329 x1 = 36525 * (y + 4716) / 100;
5330 x2 = 306001 * (m + 1) / 10000;
5331 p->s3dval = x1 + x2 + d + b - 1524.5 +
5332 (((TIMESTAMP_STRUCT *) p->param)->hour * 3600000.0 +
5333 ((TIMESTAMP_STRUCT *) p->param)->minute * 60000.0 +
5334 ((TIMESTAMP_STRUCT *) p->param)->second * 1000.0 +
5335 ((TIMESTAMP_STRUCT *) p->param)->fraction / 1.0E6)
5336 / 86400000.0;
5337 break;
5338 }
5339 len = (int) ((TIMESTAMP_STRUCT *) p->param)->fraction;
5340 len /= 1000000;
5341 len = len % 1000;
5342 if (len < 0) {
5343 len = 0;
5344 }
5345 if (p->coldef && p->coldef <= 16) {
5346 sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
5347 ((TIMESTAMP_STRUCT *) p->param)->year,
5348 ((TIMESTAMP_STRUCT *) p->param)->month,
5349 ((TIMESTAMP_STRUCT *) p->param)->day,
5350 ((TIMESTAMP_STRUCT *) p->param)->hour,
5351 ((TIMESTAMP_STRUCT *) p->param)->minute);
5352 } else if (p->coldef && p->coldef <= 19) {
5353 sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
5354 ((TIMESTAMP_STRUCT *) p->param)->year,
5355 ((TIMESTAMP_STRUCT *) p->param)->month,
5356 ((TIMESTAMP_STRUCT *) p->param)->day,
5357 ((TIMESTAMP_STRUCT *) p->param)->hour,
5358 ((TIMESTAMP_STRUCT *) p->param)->minute,
5359 ((TIMESTAMP_STRUCT *) p->param)->second);
5360 } else {
5361 sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
5362 ((TIMESTAMP_STRUCT *) p->param)->year,
5363 ((TIMESTAMP_STRUCT *) p->param)->month,
5364 ((TIMESTAMP_STRUCT *) p->param)->day,
5365 ((TIMESTAMP_STRUCT *) p->param)->hour,
5366 ((TIMESTAMP_STRUCT *) p->param)->minute,
5367 ((TIMESTAMP_STRUCT *) p->param)->second,
5368 len);
5369 }
5370 p->s3type = SQLITE_TEXT;
5371 p->s3size = -1;
5372 p->s3val = p->strbuf;
5373 break;
5374 default:
5375 error:
5376 setstat(s, -1, "unsupported parameter type",
5377 (*s->ov3) ? "07009" : "S1093");
5378 return SQL_ERROR;
5379 }
5380 return SQL_SUCCESS;
5381}
5382
5398static SQLRETURN
5399drvbindparam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
5400 SQLSMALLINT buftype, SQLSMALLINT ptype, SQLUINTEGER coldef,
5401 SQLSMALLINT scale,
5402 SQLPOINTER data, SQLINTEGER buflen, SQLLEN *len)
5403{
5404 STMT *s;
5405 BINDPARM *p;
5406
5407 if (stmt == SQL_NULL_HSTMT) {
5408 return SQL_INVALID_HANDLE;
5409 }
5410 s = (STMT *) stmt;
5411 if (pnum == 0) {
5412 setstat(s, -1, "invalid parameter", (*s->ov3) ? "07009" : "S1093");
5413 return SQL_ERROR;
5414 }
5415 if (!data && !len) {
5416 setstat(s, -1, "invalid buffer", "HY003");
5417 return SQL_ERROR;
5418 }
5419 --pnum;
5420 if (s->bindparms) {
5421 if (pnum >= s->nbindparms) {
5422 BINDPARM *newparms;
5423
5424 newparms = xrealloc(s->bindparms,
5425 (pnum + 1) * sizeof (BINDPARM));
5426 if (!newparms) {
5427outofmem:
5428 return nomem(s);
5429 }
5430 s->bindparms = newparms;
5431 memset(&s->bindparms[s->nbindparms], 0,
5432 (pnum + 1 - s->nbindparms) * sizeof (BINDPARM));
5433 s->nbindparms = pnum + 1;
5434 }
5435 } else {
5436 int npar = max(10, pnum + 1);
5437
5438 s->bindparms = xmalloc(npar * sizeof (BINDPARM));
5439 if (!s->bindparms) {
5440 goto outofmem;
5441 }
5442 memset(s->bindparms, 0, npar * sizeof (BINDPARM));
5443 s->nbindparms = npar;
5444 }
5445 switch (buftype) {
5446 case SQL_C_STINYINT:
5447 case SQL_C_UTINYINT:
5448 case SQL_C_TINYINT:
5449#ifdef SQL_C_BIT
5450 case SQL_C_BIT:
5451#endif
5452 buflen = sizeof (SQLCHAR);
5453 break;
5454 case SQL_C_SHORT:
5455 case SQL_C_USHORT:
5456 case SQL_C_SSHORT:
5457 buflen = sizeof (SQLSMALLINT);
5458 break;
5459 case SQL_C_SLONG:
5460 case SQL_C_ULONG:
5461 case SQL_C_LONG:
5462 buflen = sizeof (SQLINTEGER);
5463 break;
5464 case SQL_C_FLOAT:
5465 buflen = sizeof (float);
5466 break;
5467 case SQL_C_DOUBLE:
5468 buflen = sizeof (double);
5469 break;
5470 case SQL_C_TIMESTAMP:
5471#ifdef SQL_C_TYPE_TIMESTAMP
5472 case SQL_C_TYPE_TIMESTAMP:
5473#endif
5474 buflen = sizeof (TIMESTAMP_STRUCT);
5475 break;
5476 case SQL_C_TIME:
5477#ifdef SQL_C_TYPE_TIME
5478 case SQL_C_TYPE_TIME:
5479#endif
5480 buflen = sizeof (TIME_STRUCT);
5481 break;
5482 case SQL_C_DATE:
5483#ifdef SQL_C_TYPE_DATE
5484 case SQL_C_TYPE_DATE:
5485#endif
5486 buflen = sizeof (DATE_STRUCT);
5487 break;
5488#ifdef SQL_C_UBIGINT
5489 case SQL_C_UBIGINT:
5490 buflen = sizeof (SQLBIGINT);
5491 break;
5492#endif
5493#ifdef SQL_C_SBIGINT
5494 case SQL_C_SBIGINT:
5495 buflen = sizeof (SQLBIGINT);
5496 break;
5497#endif
5498#ifdef SQL_C_BIGINT
5499 case SQL_C_BIGINT:
5500 buflen = sizeof (SQLBIGINT);
5501 break;
5502#endif
5503 }
5504 p = &s->bindparms[pnum];
5505 p->type = buftype;
5506 p->stype = ptype;
5507 p->coldef = coldef;
5508 p->scale = scale;
5509 p->max = buflen;
5510 p->inc = buflen;
5511 p->lenp = p->lenp0 = len;
5512 p->offs = 0;
5513 p->len = 0;
5514 p->param0 = data;
5515 freep(&p->parbuf);
5516 p->param = p->param0;
5517 p->bound = 1;
5518 p->need = 0;
5519 return SQL_SUCCESS;
5520}
5521
5537SQLRETURN SQL_API
5538SQLBindParameter(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
5539 SQLSMALLINT buftype, SQLSMALLINT ptype, SQLULEN coldef,
5540 SQLSMALLINT scale,
5541 SQLPOINTER data, SQLLEN buflen, SQLLEN *len)
5542{
5543 SQLRETURN ret;
5544
5546 ret = drvbindparam(stmt, pnum, iotype, buftype, ptype, coldef,
5547 scale, data, buflen, len);
5549 return ret;
5550}
5551
5552#ifndef HAVE_IODBC
5566SQLRETURN SQL_API
5567SQLBindParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT vtype,
5568 SQLSMALLINT ptype, SQLULEN lenprec,
5569 SQLSMALLINT scale, SQLPOINTER val,
5570 SQLLEN *lenp)
5571{
5572 SQLRETURN ret;
5573
5575 ret = drvbindparam(stmt, pnum, SQL_PARAM_INPUT, vtype, ptype,
5576 lenprec, scale, val, 0, lenp);
5578 return ret;
5579}
5580#endif
5581
5589SQLRETURN SQL_API
5590SQLNumParams(SQLHSTMT stmt, SQLSMALLINT *nparam)
5591{
5592 STMT *s;
5593 SQLSMALLINT dummy;
5594
5596 if (stmt == SQL_NULL_HSTMT) {
5597 return SQL_INVALID_HANDLE;
5598 }
5599 s = (STMT *) stmt;
5600 if (!nparam) {
5601 nparam = &dummy;
5602 }
5603 *nparam = s->nparams;
5605 return SQL_SUCCESS;
5606}
5607
5615static SQLRETURN
5617{
5618 if (!p->parbuf) {
5619 if (*p->lenp == SQL_DATA_AT_EXEC) {
5620 p->len = p->max;
5621 } else {
5622 p->len = SQL_LEN_DATA_AT_EXEC(*p->lenp);
5623 }
5624 if (p->len < 0 && p->len != SQL_NTS &&
5625 p->len != SQL_NULL_DATA) {
5626 setstat(s, -1, "invalid length", "HY009");
5627 return SQL_ERROR;
5628 }
5629 if (p->len >= 0) {
5630 p->parbuf = xmalloc(p->len + 2);
5631 if (!p->parbuf) {
5632 return nomem(s);
5633 }
5634 p->param = p->parbuf;
5635 } else {
5636 p->param = NULL;
5637 }
5638 }
5639 return SQL_NEED_DATA;
5640}
5641
5649SQLRETURN SQL_API
5650SQLParamData(SQLHSTMT stmt, SQLPOINTER *pind)
5651{
5652 STMT *s;
5653 int i;
5654 SQLPOINTER dummy;
5655 SQLRETURN ret;
5656 BINDPARM *p;
5657
5659 if (stmt == SQL_NULL_HSTMT) {
5660 return SQL_INVALID_HANDLE;
5661 }
5662 s = (STMT *) stmt;
5663 if (!pind) {
5664 pind = &dummy;
5665 }
5666 if (s->pdcount < s->nparams) {
5667 s->pdcount++;
5668 }
5669 for (i = 0; i < s->pdcount; i++) {
5670 p = &s->bindparms[i];
5671 if (p->need > 0) {
5672 int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
5673
5674 p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR) ? -1 : 0;
5675 }
5676 }
5677 for (; i < s->nparams; i++) {
5678 p = &s->bindparms[i];
5679 if (p->need > 0) {
5680 *pind = (SQLPOINTER) p->param0;
5681 ret = setupparbuf(s, p);
5682 s->pdcount = i;
5683 goto done;
5684 }
5685 }
5686 ret = drvexecute(stmt, 0);
5687done:
5689 return ret;
5690}
5691
5703SQLRETURN SQL_API
5704SQLDescribeParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT *dtype,
5705 SQLULEN *size, SQLSMALLINT *decdigits, SQLSMALLINT *nullable)
5706{
5707 STMT *s;
5708 SQLRETURN ret = SQL_ERROR;
5709
5711 if (stmt == SQL_NULL_HSTMT) {
5712 return SQL_INVALID_HANDLE;
5713 }
5714 s = (STMT *) stmt;
5715 --pnum;
5716 if (pnum >= s->nparams) {
5717 setstat(s, -1, "invalid parameter index",
5718 (*s->ov3) ? "HY000" : "S1000");
5719 goto done;
5720 }
5721 if (dtype) {
5722#ifdef SQL_LONGVARCHAR
5723#ifdef WINTERFACE
5724 *dtype = s->nowchar[0] ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
5725#else
5726 *dtype = SQL_LONGVARCHAR;
5727#endif
5728#else
5729#ifdef WINTERFACE
5730 *dtype = s->nowchar[0] ? SQL_VARCHAR : SQL_WVARCHAR;
5731#else
5732 *dtype = SQL_VARCHAR;
5733#endif
5734#endif
5735 }
5736 if (size) {
5737#ifdef SQL_LONGVARCHAR
5738 *size = 65536;
5739#else
5740 *size = 255;
5741#endif
5742 }
5743 if (decdigits) {
5744 *decdigits = 0;
5745 }
5746 if (nullable) {
5747 *nullable = SQL_NULLABLE;
5748 }
5749 ret = SQL_SUCCESS;
5750done:
5752 return ret;
5753}
5754
5768SQLRETURN SQL_API
5769SQLSetParam(SQLHSTMT stmt, SQLUSMALLINT par, SQLSMALLINT type,
5770 SQLSMALLINT sqltype, SQLULEN coldef,
5771 SQLSMALLINT scale, SQLPOINTER val, SQLLEN *nval)
5772{
5773 SQLRETURN ret;
5774
5776 ret = drvbindparam(stmt, par, SQL_PARAM_INPUT,
5777 type, sqltype, coldef, scale, val,
5778 SQL_SETPARAM_VALUE_MAX, nval);
5780 return ret;
5781}
5782
5787SQLRETURN SQL_API
5788SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
5789{
5790 SQLRETURN ret;
5791
5793 ret = drvunimplstmt(stmt);
5795 return ret;
5796}
5797
5798#ifndef WINTERFACE
5803SQLRETURN SQL_API
5804SQLGetDescField(SQLHDESC handle, SQLSMALLINT recno,
5805 SQLSMALLINT fieldid, SQLPOINTER value,
5806 SQLINTEGER buflen, SQLINTEGER *strlen)
5807{
5808 return SQL_ERROR;
5809}
5810#endif
5811
5812#ifdef WINTERFACE
5817SQLRETURN SQL_API
5818SQLGetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
5819 SQLSMALLINT fieldid, SQLPOINTER value,
5820 SQLINTEGER buflen, SQLINTEGER *strlen)
5821{
5822 return SQL_ERROR;
5823}
5824#endif
5825
5826#ifndef WINTERFACE
5831SQLRETURN SQL_API
5832SQLSetDescField(SQLHDESC handle, SQLSMALLINT recno,
5833 SQLSMALLINT fieldid, SQLPOINTER value,
5834 SQLINTEGER buflen)
5835{
5836 return SQL_ERROR;
5837}
5838#endif
5839
5840#ifdef WINTERFACE
5845SQLRETURN SQL_API
5846SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
5847 SQLSMALLINT fieldid, SQLPOINTER value,
5848 SQLINTEGER buflen)
5849{
5850 return SQL_ERROR;
5851}
5852#endif
5853
5854#ifndef WINTERFACE
5859SQLRETURN SQL_API
5860SQLGetDescRec(SQLHDESC handle, SQLSMALLINT recno,
5861 SQLCHAR *name, SQLSMALLINT buflen,
5862 SQLSMALLINT *strlen, SQLSMALLINT *type,
5863 SQLSMALLINT *subtype, SQLLEN *len,
5864 SQLSMALLINT *prec, SQLSMALLINT *scale,
5865 SQLSMALLINT *nullable)
5866{
5867 return SQL_ERROR;
5868}
5869#endif
5870
5871#ifdef WINTERFACE
5876SQLRETURN SQL_API
5877SQLGetDescRecW(SQLHDESC handle, SQLSMALLINT recno,
5878 SQLWCHAR *name, SQLSMALLINT buflen,
5879 SQLSMALLINT *strlen, SQLSMALLINT *type,
5880 SQLSMALLINT *subtype, SQLLEN *len,
5881 SQLSMALLINT *prec, SQLSMALLINT *scale,
5882 SQLSMALLINT *nullable)
5883{
5884 return SQL_ERROR;
5885}
5886#endif
5887
5892SQLRETURN SQL_API
5893SQLSetDescRec(SQLHDESC handle, SQLSMALLINT recno,
5894 SQLSMALLINT type, SQLSMALLINT subtype,
5895 SQLLEN len, SQLSMALLINT prec,
5896 SQLSMALLINT scale, SQLPOINTER data,
5897 SQLLEN *strlen, SQLLEN *indicator)
5898{
5899 return SQL_ERROR;
5900}
5901
5913static SQLRETURN
5914mkresultset(HSTMT stmt, COL *colspec, int ncols, COL *colspec3,
5915 int ncols3, int *nret)
5916{
5917 STMT *s;
5918 DBC *d;
5919
5920 if (stmt == SQL_NULL_HSTMT) {
5921 return SQL_INVALID_HANDLE;
5922 }
5923 s = (STMT *) stmt;
5924 if (s->dbc == SQL_NULL_HDBC) {
5925noconn:
5926 return noconn(s);
5927 }
5928 d = (DBC *) s->dbc;
5929 if (!d->sqlite) {
5930 goto noconn;
5931 }
5932 s3stmt_end_if(s);
5933 freeresult(s, 0);
5934 if (colspec3 && *s->ov3) {
5935 s->ncols = ncols3;
5936 s->cols = colspec3;
5937 } else {
5938 s->ncols = ncols;
5939 s->cols = colspec;
5940 }
5941 mkbindcols(s, s->ncols);
5942 s->nowchar[1] = 1;
5943 s->nrows = 0;
5944 s->rowp = s->rowprs = -1;
5945 s->isselect = -1;
5946 if (nret) {
5947 *nret = s->ncols;
5948 }
5949 return SQL_SUCCESS;
5950}
5951
5957 { "SYSTEM", "TABLEPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
5958 { "SYSTEM", "TABLEPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
5959 { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
5960 { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
5961 { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
5962 { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
5963 { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
5964};
5965
5967 { "SYSTEM", "TABLEPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
5968 { "SYSTEM", "TABLEPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
5969 { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
5970 { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
5971 { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
5972 { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
5973 { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
5974};
5975
5988static SQLRETURN
5990 SQLCHAR *cat, SQLSMALLINT catLen,
5991 SQLCHAR *schema, SQLSMALLINT schemaLen,
5992 SQLCHAR *table, SQLSMALLINT tableLen)
5993{
5994 SQLRETURN ret;
5995 STMT *s;
5996 DBC *d;
5997 int ncols, rc, size, npatt;
5998 char *errp = NULL, *sql, tname[512];
5999
6002 if (ret != SQL_SUCCESS) {
6003 return ret;
6004 }
6005 s = (STMT *) stmt;
6006 d = (DBC *) s->dbc;
6007 if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
6008 table = NULL;
6009 goto doit;
6010 }
6011 if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
6012 schema[0] == '%') {
6013 if ((!cat || catLen == 0 || !cat[0]) &&
6014 (!table || tableLen == 0 || !table[0])) {
6015 table = NULL;
6016 goto doit;
6017 }
6018 }
6019doit:
6020 if (!table) {
6021 size = 1;
6022 tname[0] = '%';
6023 } else {
6024 if (tableLen == SQL_NTS) {
6025 size = sizeof (tname) - 1;
6026 } else {
6027 size = min(sizeof (tname) - 1, tableLen);
6028 }
6029 strncpy(tname, (char *) table, size);
6030 }
6031 tname[size] = '\0';
6032 npatt = unescpat(tname);
6033#if defined(_WIN32) || defined(_WIN64)
6034 if (npatt) {
6035 sql = sqlite3_mprintf("select %s as 'TABLE_QUALIFIER', "
6036 "%s as 'TABLE_OWNER', "
6037 "tbl_name as 'TABLE_NAME', "
6038 "'' as 'GRANTOR', "
6039 "'' as 'GRANTEE', "
6040 "'SELECT' AS 'PRIVILEGE', "
6041 "NULL as 'IS_GRANTABLE' "
6042 "from sqlite_master where "
6043 "(type = 'table' or type = 'view') "
6044 "and tbl_name like %Q "
6045 "UNION "
6046 "select %s as 'TABLE_QUALIFIER', "
6047 "%s as 'TABLE_OWNER', "
6048 "tbl_name as 'TABLE_NAME', "
6049 "'' as 'GRANTOR', "
6050 "'' as 'GRANTEE', "
6051 "'UPDATE' AS 'PRIVILEGE', "
6052 "NULL as 'IS_GRANTABLE' "
6053 "from sqlite_master where "
6054 "(type = 'table' or type = 'view') "
6055 "and tbl_name like %Q "
6056 "UNION "
6057 "select %s as 'TABLE_QUALIFIER', "
6058 "%s as 'TABLE_OWNER', "
6059 "tbl_name as 'TABLE_NAME', "
6060 "'' as 'GRANTOR', "
6061 "'' as 'GRANTEE', "
6062 "'DELETE' AS 'PRIVILEGE', "
6063 "NULL as 'IS_GRANTABLE' "
6064 "from sqlite_master where "
6065 "(type = 'table' or type = 'view') "
6066 "and tbl_name like %Q "
6067 "UNION "
6068 "select %s as 'TABLE_QUALIFIER', "
6069 "%s as 'TABLE_OWNER', "
6070 "tbl_name as 'TABLE_NAME', "
6071 "'' as 'GRANTOR', "
6072 "'' as 'GRANTEE', "
6073 "'INSERT' AS 'PRIVILEGE', "
6074 "NULL as 'IS_GRANTABLE' "
6075 "from sqlite_master where "
6076 "(type = 'table' or type = 'view') "
6077 "and tbl_name like %Q "
6078 "UNION "
6079 "select %s as 'TABLE_QUALIFIER', "
6080 "%s as 'TABLE_OWNER', "
6081 "tbl_name as 'TABLE_NAME', "
6082 "'' as 'GRANTOR', "
6083 "'' as 'GRANTEE', "
6084 "'REFERENCES' AS 'PRIVILEGE', "
6085 "NULL as 'IS_GRANTABLE' "
6086 "from sqlite_master where "
6087 "(type = 'table' or type = 'view') "
6088 "and tbl_name like %Q",
6089 d->xcelqrx ? "'main'" : "NULL",
6090 d->xcelqrx ? "''" : "NULL",
6091 tname,
6092 d->xcelqrx ? "'main'" : "NULL",
6093 d->xcelqrx ? "''" : "NULL",
6094 tname,
6095 d->xcelqrx ? "'main'" : "NULL",
6096 d->xcelqrx ? "''" : "NULL",
6097 tname,
6098 d->xcelqrx ? "'main'" : "NULL",
6099 d->xcelqrx ? "''" : "NULL",
6100 tname,
6101 d->xcelqrx ? "'main'" : "NULL",
6102 d->xcelqrx ? "''" : "NULL",
6103 tname);
6104 } else {
6105 sql = sqlite3_mprintf("select %s as 'TABLE_QUALIFIER', "
6106 "%s as 'TABLE_OWNER', "
6107 "tbl_name as 'TABLE_NAME', "
6108 "'' as 'GRANTOR', "
6109 "'' as 'GRANTEE', "
6110 "'SELECT' AS 'PRIVILEGE', "
6111 "NULL as 'IS_GRANTABLE' "
6112 "from sqlite_master where "
6113 "(type = 'table' or type = 'view') "
6114 "and lower(tbl_name) = lower(%Q) "
6115 "UNION "
6116 "select %s as 'TABLE_QUALIFIER', "
6117 "%s as 'TABLE_OWNER', "
6118 "tbl_name as 'TABLE_NAME', "
6119 "'' as 'GRANTOR', "
6120 "'' as 'GRANTEE', "
6121 "'UPDATE' AS 'PRIVILEGE', "
6122 "NULL as 'IS_GRANTABLE' "
6123 "from sqlite_master where "
6124 "(type = 'table' or type = 'view') "
6125 "and lower(tbl_name) = lower(%Q) "
6126 "UNION "
6127 "select %s as 'TABLE_QUALIFIER', "
6128 "%s as 'TABLE_OWNER', "
6129 "tbl_name as 'TABLE_NAME', "
6130 "'' as 'GRANTOR', "
6131 "'' as 'GRANTEE', "
6132 "'DELETE' AS 'PRIVILEGE', "
6133 "NULL as 'IS_GRANTABLE' "
6134 "from sqlite_master where "
6135 "(type = 'table' or type = 'view') "
6136 "and lower(tbl_name) = lower(%Q) "
6137 "UNION "
6138 "select %s as 'TABLE_QUALIFIER', "
6139 "%s as 'TABLE_OWNER', "
6140 "tbl_name as 'TABLE_NAME', "
6141 "'' as 'GRANTOR', "
6142 "'' as 'GRANTEE', "
6143 "'INSERT' AS 'PRIVILEGE', "
6144 "NULL as 'IS_GRANTABLE' "
6145 "from sqlite_master where "
6146 "(type = 'table' or type = 'view') "
6147 "and lower(tbl_name) = lower(%Q) "
6148 "UNION "
6149 "select %s as 'TABLE_QUALIFIER', "
6150 "%s as 'TABLE_OWNER', "
6151 "tbl_name as 'TABLE_NAME', "
6152 "'' as 'GRANTOR', "
6153 "'' as 'GRANTEE', "
6154 "'REFERENCES' AS 'PRIVILEGE', "
6155 "NULL as 'IS_GRANTABLE' "
6156 "from sqlite_master where "
6157 "(type = 'table' or type = 'view') "
6158 "and lower(tbl_name) = lower(%Q)",
6159 d->xcelqrx ? "'main'" : "NULL",
6160 d->xcelqrx ? "''" : "NULL",
6161 tname,
6162 d->xcelqrx ? "'main'" : "NULL",
6163 d->xcelqrx ? "''" : "NULL",
6164 tname,
6165 d->xcelqrx ? "'main'" : "NULL",
6166 d->xcelqrx ? "''" : "NULL",
6167 tname,
6168 d->xcelqrx ? "'main'" : "NULL",
6169 d->xcelqrx ? "''" : "NULL",
6170 tname,
6171 d->xcelqrx ? "'main'" : "NULL",
6172 d->xcelqrx ? "''" : "NULL",
6173 tname);
6174 }
6175#else
6176 if (npatt) {
6177 sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
6178 "NULL as 'TABLE_OWNER', "
6179 "tbl_name as 'TABLE_NAME', "
6180 "'' as 'GRANTOR', "
6181 "'' as 'GRANTEE', "
6182 "'SELECT' AS 'PRIVILEGE', "
6183 "NULL as 'IS_GRANTABLE' "
6184 "from sqlite_master where "
6185 "(type = 'table' or type = 'view') "
6186 "and tbl_name like %Q "
6187 "UNION "
6188 "select NULL as 'TABLE_QUALIFIER', "
6189 "NULL as 'TABLE_OWNER', "
6190 "tbl_name as 'TABLE_NAME', "
6191 "'' as 'GRANTOR', "
6192 "'' as 'GRANTEE', "
6193 "'UPDATE' AS 'PRIVILEGE', "
6194 "NULL as 'IS_GRANTABLE' "
6195 "from sqlite_master where "
6196 "(type = 'table' or type = 'view') "
6197 "and tbl_name like %Q "
6198 "UNION "
6199 "select NULL as 'TABLE_QUALIFIER', "
6200 "NULL as 'TABLE_OWNER', "
6201 "tbl_name as 'TABLE_NAME', "
6202 "'' as 'GRANTOR', "
6203 "'' as 'GRANTEE', "
6204 "'DELETE' AS 'PRIVILEGE', "
6205 "NULL as 'IS_GRANTABLE' "
6206 "from sqlite_master where "
6207 "(type = 'table' or type = 'view') "
6208 "and tbl_name like %Q "
6209 "UNION "
6210 "select NULL as 'TABLE_QUALIFIER', "
6211 "NULL as 'TABLE_OWNER', "
6212 "tbl_name as 'TABLE_NAME', "
6213 "'' as 'GRANTOR', "
6214 "'' as 'GRANTEE', "
6215 "'INSERT' AS 'PRIVILEGE', "
6216 "NULL as 'IS_GRANTABLE' "
6217 "from sqlite_master where "
6218 "(type = 'table' or type = 'view') "
6219 "and tbl_name like %Q "
6220 "UNION "
6221 "select NULL as 'TABLE_QUALIFIER', "
6222 "NULL as 'TABLE_OWNER', "
6223 "tbl_name as 'TABLE_NAME', "
6224 "'' as 'GRANTOR', "
6225 "'' as 'GRANTEE', "
6226 "'REFERENCES' AS 'PRIVILEGE', "
6227 "NULL as 'IS_GRANTABLE' "
6228 "from sqlite_master where "
6229 "(type = 'table' or type = 'view') "
6230 "and tbl_name like %Q",
6231 tname, tname, tname, tname, tname);
6232 } else {
6233 sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
6234 "NULL as 'TABLE_OWNER', "
6235 "tbl_name as 'TABLE_NAME', "
6236 "'' as 'GRANTOR', "
6237 "'' as 'GRANTEE', "
6238 "'SELECT' AS 'PRIVILEGE', "
6239 "NULL as 'IS_GRANTABLE' "
6240 "from sqlite_master where "
6241 "(type = 'table' or type = 'view') "
6242 "and lower(tbl_name) = lower(%Q) "
6243 "UNION "
6244 "select NULL as 'TABLE_QUALIFIER', "
6245 "NULL as 'TABLE_OWNER', "
6246 "tbl_name as 'TABLE_NAME', "
6247 "'' as 'GRANTOR', "
6248 "'' as 'GRANTEE', "
6249 "'UPDATE' AS 'PRIVILEGE', "
6250 "NULL as 'IS_GRANTABLE' "
6251 "from sqlite_master where "
6252 "(type = 'table' or type = 'view') "
6253 "and lower(tbl_name) = lower(%Q) "
6254 "UNION "
6255 "select NULL as 'TABLE_QUALIFIER', "
6256 "NULL as 'TABLE_OWNER', "
6257 "tbl_name as 'TABLE_NAME', "
6258 "'' as 'GRANTOR', "
6259 "'' as 'GRANTEE', "
6260 "'DELETE' AS 'PRIVILEGE', "
6261 "NULL as 'IS_GRANTABLE' "
6262 "from sqlite_master where "
6263 "(type = 'table' or type = 'view') "
6264 "and lower(tbl_name) = lower(%Q) "
6265 "UNION "
6266 "select NULL as 'TABLE_QUALIFIER', "
6267 "NULL as 'TABLE_OWNER', "
6268 "tbl_name as 'TABLE_NAME', "
6269 "'' as 'GRANTOR', "
6270 "'' as 'GRANTEE', "
6271 "'INSERT' AS 'PRIVILEGE', "
6272 "NULL as 'IS_GRANTABLE' "
6273 "from sqlite_master where "
6274 "(type = 'table' or type = 'view') "
6275 "and lower(tbl_name) = lower(%Q) "
6276 "UNION "
6277 "select NULL as 'TABLE_QUALIFIER', "
6278 "NULL as 'TABLE_OWNER', "
6279 "tbl_name as 'TABLE_NAME', "
6280 "'' as 'GRANTOR', "
6281 "'' as 'GRANTEE', "
6282 "'REFERENCES' AS 'PRIVILEGE', "
6283 "NULL as 'IS_GRANTABLE' "
6284 "from sqlite_master where "
6285 "(type = 'table' or type = 'view') "
6286 "and lower(tbl_name) = lower(%Q)",
6287 tname, tname, tname, tname, tname);
6288 }
6289#endif
6290 if (!sql) {
6291 return nomem(s);
6292 }
6293 ret = starttran(s);
6294 if (ret != SQL_SUCCESS) {
6295 sqlite3_free(sql);
6296 return ret;
6297 }
6298 dbtraceapi(d, "sqlite3_get_table", sql);
6299 rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
6300 sqlite3_free(sql);
6301 if (rc == SQLITE_OK) {
6302 if (ncols != s->ncols) {
6303 freeresult(s, 0);
6304 s->nrows = 0;
6305 } else {
6306 s->rowfree = sqlite3_free_table;
6307 }
6308 } else {
6309 s->nrows = 0;
6310 s->rows = NULL;
6311 s->rowfree = NULL;
6312 }
6313 if (errp) {
6314 sqlite3_free(errp);
6315 errp = NULL;
6316 }
6317 s->rowp = s->rowprs = -1;
6318 return SQL_SUCCESS;
6319}
6320
6321
6322#if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
6335SQLRETURN SQL_API
6336SQLTablePrivileges(SQLHSTMT stmt,
6337 SQLCHAR *catalog, SQLSMALLINT catalogLen,
6338 SQLCHAR *schema, SQLSMALLINT schemaLen,
6339 SQLCHAR *table, SQLSMALLINT tableLen)
6340{
6341#if defined(_WIN32) || defined(_WIN64)
6342 char *c = NULL, *s = NULL, *t = NULL;
6343#endif
6344 SQLRETURN ret;
6345
6347#if defined(_WIN32) || defined(_WIN64)
6348 if (!((STMT *) stmt)->oemcp[0]) {
6349 ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
6350 table, tableLen);
6351 goto done2;
6352 }
6353 if (catalog) {
6354 c = wmb_to_utf_c((char *) catalog, catalogLen);
6355 if (!c) {
6356 ret = nomem((STMT *) stmt);
6357 goto done;
6358 }
6359 }
6360 if (schema) {
6361 s = wmb_to_utf_c((char *) schema, schemaLen);
6362 if (!s) {
6363 ret = nomem((STMT *) stmt);
6364 goto done;
6365 }
6366 }
6367 if (table) {
6368 t = wmb_to_utf_c((char *) table, tableLen);
6369 if (!t) {
6370 ret = nomem((STMT *) stmt);
6371 goto done;
6372 }
6373 }
6374 ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
6375 (SQLCHAR *) s, SQL_NTS,
6376 (SQLCHAR *) t, SQL_NTS);
6377#else
6378 ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
6379 table, tableLen);
6380#endif
6381#if defined(_WIN32) || defined(_WIN64)
6382done:
6383 uc_free(t);
6384 uc_free(s);
6385 uc_free(c);
6386done2:
6387 ;
6388#endif
6390 return ret;
6391}
6392#endif
6393
6394#if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
6395#ifdef WINTERFACE
6408SQLRETURN SQL_API
6410 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
6411 SQLWCHAR *schema, SQLSMALLINT schemaLen,
6412 SQLWCHAR *table, SQLSMALLINT tableLen)
6413{
6414 char *c = NULL, *s = NULL, *t = NULL;
6415 SQLRETURN ret;
6416
6418 if (catalog) {
6419 c = uc_to_utf_c(catalog, catalogLen);
6420 if (!c) {
6421 ret = nomem((STMT *) stmt);
6422 goto done;
6423 }
6424 }
6425 if (schema) {
6426 s = uc_to_utf_c(schema, schemaLen);
6427 if (!s) {
6428 ret = nomem((STMT *) stmt);
6429 goto done;
6430 }
6431 }
6432 if (table) {
6433 t = uc_to_utf_c(table, tableLen);
6434 if (!t) {
6435 ret = nomem((STMT *) stmt);
6436 goto done;
6437 }
6438 }
6439 ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
6440 (SQLCHAR *) s, SQL_NTS,
6441 (SQLCHAR *) t, SQL_NTS);
6442done:
6443 uc_free(t);
6444 uc_free(s);
6445 uc_free(c);
6447 return ret;
6448}
6449#endif
6450#endif
6451
6456static COL colPrivSpec2[] = {
6457 { "SYSTEM", "COLPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
6458 { "SYSTEM", "COLPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
6459 { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6460 { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6461 { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6462 { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6463 { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
6464};
6465
6466static COL colPrivSpec3[] = {
6467 { "SYSTEM", "COLPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
6468 { "SYSTEM", "COLPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
6469 { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6470 { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6471 { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6472 { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6473 { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
6474};
6475
6476#if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
6491SQLRETURN SQL_API
6492SQLColumnPrivileges(SQLHSTMT stmt,
6493 SQLCHAR *catalog, SQLSMALLINT catalogLen,
6494 SQLCHAR *schema, SQLSMALLINT schemaLen,
6495 SQLCHAR *table, SQLSMALLINT tableLen,
6496 SQLCHAR *column, SQLSMALLINT columnLen)
6497{
6498 SQLRETURN ret;
6499
6504 return ret;
6505}
6506#endif
6507
6508#if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
6509#ifdef WINTERFACE
6524SQLRETURN SQL_API
6526 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
6527 SQLWCHAR *schema, SQLSMALLINT schemaLen,
6528 SQLWCHAR *table, SQLSMALLINT tableLen,
6529 SQLWCHAR *column, SQLSMALLINT columnLen)
6530{
6531 SQLRETURN ret;
6532
6537 return ret;
6538}
6539#endif
6540#endif
6541
6546static COL pkeySpec2[] = {
6547 { "SYSTEM", "PRIMARYKEY", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
6548 { "SYSTEM", "PRIMARYKEY", "TABLE_OWNER", SCOL_VARCHAR, 50 },
6549 { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
6550 { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6551 { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
6552 { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
6553};
6554
6555static COL pkeySpec3[] = {
6556 { "SYSTEM", "PRIMARYKEY", "TABLE_CAT", SCOL_VARCHAR, 50 },
6557 { "SYSTEM", "PRIMARYKEY", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
6558 { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
6559 { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6560 { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
6561 { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
6562};
6563
6576static SQLRETURN
6578 SQLCHAR *cat, SQLSMALLINT catLen,
6579 SQLCHAR *schema, SQLSMALLINT schemaLen,
6580 SQLCHAR *table, SQLSMALLINT tableLen)
6581{
6582 STMT *s;
6583 DBC *d;
6584 SQLRETURN sret;
6585 int i, asize, ret, nrows, ncols, nrows2 = 0, ncols2 = 0;
6586 int namec = -1, uniquec = -1, namec2 = -1, uniquec2 = -1, offs, seq = 1;
6587 PTRDIFF_T size;
6588 char **rowp = NULL, **rowp2 = NULL, *errp = NULL, *sql, tname[512];
6589
6591 pkeySpec3, array_size(pkeySpec3), &asize);
6592 if (sret != SQL_SUCCESS) {
6593 return sret;
6594 }
6595 s = (STMT *) stmt;
6596 d = (DBC *) s->dbc;
6597 if (!table || table[0] == '\0' || table[0] == '%') {
6598 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
6599 return SQL_ERROR;
6600 }
6601 if (tableLen == SQL_NTS) {
6602 size = sizeof (tname) - 1;
6603 } else {
6604 size = min(sizeof (tname) - 1, tableLen);
6605 }
6606 strncpy(tname, (char *) table, size);
6607 tname[size] = '\0';
6608 unescpat(tname);
6609 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
6610 if (!sql) {
6611 return nomem(s);
6612 }
6613 sret = starttran(s);
6614 if (sret != SQL_SUCCESS) {
6615 sqlite3_free(sql);
6616 return sret;
6617 }
6618 dbtraceapi(d, "sqlite3_get_table", sql);
6619 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
6620 sqlite3_free(sql);
6621 if (ret != SQLITE_OK) {
6622 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6623 errp ? errp : "unknown error", ret);
6624 if (errp) {
6625 sqlite3_free(errp);
6626 errp = NULL;
6627 }
6628 return SQL_ERROR;
6629 }
6630 if (errp) {
6631 sqlite3_free(errp);
6632 errp = NULL;
6633 }
6634 size = 0;
6635 if (ncols * nrows > 0) {
6636 int typec;
6637
6638 namec = findcol(rowp, ncols, "name");
6639 uniquec = findcol(rowp, ncols, "pk");
6640 typec = findcol(rowp, ncols, "type");
6641 if (namec >= 0 && uniquec >= 0 && typec >= 0) {
6642 for (i = 1; i <= nrows; i++) {
6643 if (*rowp[i * ncols + uniquec] != '0') {
6644 size++;
6645 }
6646 }
6647 }
6648 }
6649 if (size == 0) {
6650 sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
6651 if (!sql) {
6652 sqlite3_free_table(rowp);
6653 return nomem(s);
6654 }
6655 dbtraceapi(d, "sqlite3_get_table", sql);
6656 ret = sqlite3_get_table(d->sqlite, sql, &rowp2, &nrows2, &ncols2,
6657 &errp);
6658 sqlite3_free(sql);
6659 if (ret != SQLITE_OK) {
6660 sqlite3_free_table(rowp);
6661 sqlite3_free_table(rowp2);
6662 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6663 errp ? errp : "unknown error", ret);
6664 if (errp) {
6665 sqlite3_free(errp);
6666 errp = NULL;
6667 }
6668 return SQL_ERROR;
6669 }
6670 if (errp) {
6671 sqlite3_free(errp);
6672 errp = NULL;
6673 }
6674 }
6675 if (ncols2 * nrows2 > 0) {
6676 namec2 = findcol(rowp2, ncols2, "name");
6677 uniquec2 = findcol(rowp2, ncols2, "unique");
6678 if (namec2 >= 0 && uniquec2 >= 0) {
6679 for (i = 1; i <= nrows2; i++) {
6680 int nnrows, nncols, nlen = 0;
6681 char **rowpp;
6682
6683 if (rowp2[i * ncols2 + namec2]) {
6684 nlen = strlen(rowp2[i * ncols2 + namec2]);
6685 }
6686 if (nlen < 17 ||
6687 strncmp(rowp2[i * ncols2 + namec2],
6688 "sqlite_autoindex_", 17)) {
6689 continue;
6690 }
6691 if (*rowp2[i * ncols2 + uniquec2] != '0') {
6692 ret = SQLITE_ERROR;
6693 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6694 rowp2[i * ncols2 + namec2]);
6695 if (sql) {
6696 dbtraceapi(d, "sqlite3_get_table", sql);
6697 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6698 &nnrows, &nncols, NULL);
6699 sqlite3_free(sql);
6700 }
6701 if (ret == SQLITE_OK) {
6702 size += nnrows;
6703 sqlite3_free_table(rowpp);
6704 }
6705 }
6706 }
6707 }
6708 }
6709 if (size == 0) {
6710 sqlite3_free_table(rowp);
6711 sqlite3_free_table(rowp2);
6712 return SQL_SUCCESS;
6713 }
6714 s->nrows = size;
6715 size = (size + 1) * asize;
6716 s->rows = xmalloc((size + 1) * sizeof (char *));
6717 if (!s->rows) {
6718 s->nrows = 0;
6719 sqlite3_free_table(rowp);
6720 sqlite3_free_table(rowp2);
6721 return nomem(s);
6722 }
6723 s->rows[0] = (char *) size;
6724 s->rows += 1;
6725 memset(s->rows, 0, sizeof (char *) * size);
6726 s->rowfree = freerows;
6727 offs = s->ncols;
6728 if (rowp) {
6729 for (i = 1; i <= nrows; i++) {
6730 if (*rowp[i * ncols + uniquec] != '0') {
6731 char buf[32];
6732
6733#if defined(_WIN32) || defined(_WIN64)
6734 s->rows[offs + 0] = xstrdup(d->xcelqrx ? "main" : "");
6735 s->rows[offs + 1] = xstrdup("");
6736#else
6737 s->rows[offs + 0] = xstrdup("");
6738 s->rows[offs + 1] = xstrdup("");
6739#endif
6740 s->rows[offs + 2] = xstrdup(tname);
6741 s->rows[offs + 3] = xstrdup(rowp[i * ncols + namec]);
6742 sprintf(buf, "%d", seq++);
6743 s->rows[offs + 4] = xstrdup(buf);
6744 offs += s->ncols;
6745 }
6746 }
6747 }
6748 if (rowp2) {
6749 for (i = 1; i <= nrows2; i++) {
6750 int nnrows, nncols, nlen = 0;
6751 char **rowpp;
6752
6753 if (rowp2[i * ncols2 + namec2]) {
6754 nlen = strlen(rowp2[i * ncols2 + namec2]);
6755 }
6756 if (nlen < 17 ||
6757 strncmp(rowp2[i * ncols2 + namec2], "sqlite_autoindex_", 17)) {
6758 continue;
6759 }
6760 if (*rowp2[i * ncols2 + uniquec2] != '0') {
6761 int k;
6762
6763 ret = SQLITE_ERROR;
6764 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6765 rowp2[i * ncols2 + namec2]);
6766 if (sql) {
6767 dbtraceapi(d, "sqlite3_get_table", sql);
6768 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6769 &nnrows, &nncols, NULL);
6770 sqlite3_free(sql);
6771 }
6772 if (ret != SQLITE_OK) {
6773 continue;
6774 }
6775 for (k = 0; nnrows && k < nncols; k++) {
6776 if (strcmp(rowpp[k], "name") == 0) {
6777 int m;
6778
6779 for (m = 1; m <= nnrows; m++) {
6780 int roffs = offs + (m - 1) * s->ncols;
6781
6782#if defined(_WIN32) || defined(_WIN64)
6783 s->rows[roffs + 0] =
6784 xstrdup(d->xcelqrx ? "main" : "");
6785 s->rows[roffs + 1] = xstrdup("");
6786#else
6787 s->rows[roffs + 0] = xstrdup("");
6788 s->rows[roffs + 1] = xstrdup("");
6789#endif
6790 s->rows[roffs + 2] = xstrdup(tname);
6791 s->rows[roffs + 3] =
6792 xstrdup(rowpp[m * nncols + k]);
6793 s->rows[roffs + 5] =
6794 xstrdup(rowp2[i * ncols2 + namec2]);
6795 }
6796 } else if (strcmp(rowpp[k], "seqno") == 0) {
6797 int m;
6798
6799 for (m = 1; m <= nnrows; m++) {
6800 int roffs = offs + (m - 1) * s->ncols;
6801 int pos = m - 1;
6802 char buf[32];
6803
6804 sscanf(rowpp[m * nncols + k], "%d", &pos);
6805 sprintf(buf, "%d", pos + 1);
6806 s->rows[roffs + 4] = xstrdup(buf);
6807 }
6808 }
6809 }
6810 offs += nnrows * s->ncols;
6811 sqlite3_free_table(rowpp);
6812 }
6813 }
6814 }
6815 sqlite3_free_table(rowp);
6816 sqlite3_free_table(rowp2);
6817 return SQL_SUCCESS;
6818}
6819
6820#ifndef WINTERFACE
6833SQLRETURN SQL_API
6834SQLPrimaryKeys(SQLHSTMT stmt,
6835 SQLCHAR *cat, SQLSMALLINT catLen,
6836 SQLCHAR *schema, SQLSMALLINT schemaLen,
6837 SQLCHAR *table, SQLSMALLINT tableLen)
6838{
6839#if defined(_WIN32) || defined(_WIN64)
6840 char *c = NULL, *s = NULL, *t = NULL;
6841#endif
6842 SQLRETURN ret;
6843
6845#if defined(_WIN32) || defined(_WIN64)
6846 if (!((STMT *) stmt)->oemcp[0]) {
6847 ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
6848 table, tableLen);
6849 goto done2;
6850 }
6851 if (cat) {
6852 c = wmb_to_utf_c((char *) cat, catLen);
6853 if (!c) {
6854 ret = nomem((STMT *) stmt);
6855 goto done;
6856 }
6857 }
6858 if (schema) {
6859 s = wmb_to_utf_c((char *) schema, schemaLen);
6860 if (!s) {
6861 ret = nomem((STMT *) stmt);
6862 goto done;
6863 }
6864 }
6865 if (table) {
6866 t = wmb_to_utf_c((char *) table, tableLen);
6867 if (!t) {
6868 ret = nomem((STMT *) stmt);
6869 goto done;
6870 }
6871 }
6872 ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
6873 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
6874#else
6875 ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
6876 table, tableLen);
6877#endif
6878#if defined(_WIN32) || defined(_WIN64)
6879done:
6880 uc_free(t);
6881 uc_free(s);
6882 uc_free(c);
6883done2:
6884 ;
6885#endif
6887 return ret;
6888}
6889#endif
6890
6891#ifdef WINTERFACE
6904SQLRETURN SQL_API
6906 SQLWCHAR *cat, SQLSMALLINT catLen,
6907 SQLWCHAR *schema, SQLSMALLINT schemaLen,
6908 SQLWCHAR *table, SQLSMALLINT tableLen)
6909{
6910 char *c = NULL, *s = NULL, *t = NULL;
6911 SQLRETURN ret;
6912
6914 if (cat) {
6915 c = uc_to_utf_c(cat, catLen);
6916 if (!c) {
6917 ret = nomem((STMT *) stmt);
6918 goto done;
6919 }
6920 }
6921 if (schema) {
6922 s = uc_to_utf_c(schema, schemaLen);
6923 if (!s) {
6924 ret = nomem((STMT *) stmt);
6925 goto done;
6926 }
6927 }
6928 if (table) {
6929 t = uc_to_utf_c(table, tableLen);
6930 if (!t) {
6931 ret = nomem((STMT *) stmt);
6932 goto done;
6933 }
6934 }
6935 ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
6936 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
6937done:
6938 uc_free(t);
6939 uc_free(s);
6940 uc_free(c);
6942 return ret;
6943}
6944#endif
6945
6950static COL scolSpec2[] = {
6951 { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
6952 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6953 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
6954 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
6955 { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
6956 { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
6957 { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
6958 { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
6959 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
6960};
6961
6962static COL scolSpec3[] = {
6963 { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
6964 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6965 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
6966 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
6967 { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
6968 { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
6969 { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
6970 { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
6971 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
6972};
6973
6989static SQLRETURN
6990drvspecialcolumns(SQLHSTMT stmt, SQLUSMALLINT id,
6991 SQLCHAR *cat, SQLSMALLINT catLen,
6992 SQLCHAR *schema, SQLSMALLINT schemaLen,
6993 SQLCHAR *table, SQLSMALLINT tableLen,
6994 SQLUSMALLINT scope, SQLUSMALLINT nullable)
6995{
6996 STMT *s;
6997 DBC *d;
6998 SQLRETURN sret;
6999 int i, asize, ret, nrows, ncols, nnnrows, nnncols, offs;
7000 PTRDIFF_T size;
7001 int namec = -1, uniquec = -1, namecc = -1, typecc = -1;
7002 int notnullcc = -1, mkrowid = 0;
7003 char *errp = NULL, *sql, tname[512];
7004 char **rowp = NULL, **rowppp = NULL;
7005
7007 scolSpec3, array_size(scolSpec3), &asize);
7008 if (sret != SQL_SUCCESS) {
7009 return sret;
7010 }
7011 s = (STMT *) stmt;
7012 d = (DBC *) s->dbc;
7013 if (!table || table[0] == '\0' || table[0] == '%') {
7014 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
7015 return SQL_ERROR;
7016 }
7017 if (tableLen == SQL_NTS) {
7018 size = sizeof (tname) - 1;
7019 } else {
7020 size = min(sizeof (tname) - 1, tableLen);
7021 }
7022 strncpy(tname, (char *) table, size);
7023 tname[size] = '\0';
7024 unescpat(tname);
7025 if (id != SQL_BEST_ROWID) {
7026 return SQL_SUCCESS;
7027 }
7028 sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
7029 if (!sql) {
7030 return nomem(s);
7031 }
7032 sret = starttran(s);
7033 if (sret != SQL_SUCCESS) {
7034 sqlite3_free(sql);
7035 return sret;
7036 }
7037 dbtraceapi(d, "sqlite3_get_table", sql);
7038 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
7039 sqlite3_free(sql);
7040 if (ret != SQLITE_OK) {
7041doerr:
7042 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7043 errp ? errp : "unknown error", ret);
7044 if (errp) {
7045 sqlite3_free(errp);
7046 errp = NULL;
7047 }
7048 return SQL_ERROR;
7049 }
7050 if (errp) {
7051 sqlite3_free(errp);
7052 errp = NULL;
7053 }
7054 size = 0; /* number result rows */
7055 if (ncols * nrows <= 0) {
7056 goto nodata_but_rowid;
7057 }
7058 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
7059 if (!sql) {
7060 return nomem(s);
7061 }
7062 dbtraceapi(d, "sqlite3_get_table", sql);
7063 ret = sqlite3_get_table(d->sqlite, sql, &rowppp, &nnnrows, &nnncols,
7064 &errp);
7065 sqlite3_free(sql);
7066 if (ret != SQLITE_OK) {
7067 sqlite3_free_table(rowp);
7068 goto doerr;
7069 }
7070 if (errp) {
7071 sqlite3_free(errp);
7072 errp = NULL;
7073 }
7074 namec = findcol(rowp, ncols, "name");
7075 uniquec = findcol(rowp, ncols, "unique");
7076 if (namec < 0 || uniquec < 0) {
7077 goto nodata_but_rowid;
7078 }
7079 namecc = findcol(rowppp, nnncols, "name");
7080 typecc = findcol(rowppp, nnncols, "type");
7081 notnullcc = findcol(rowppp, nnncols, "notnull");
7082 for (i = 1; i <= nrows; i++) {
7083 int nnrows, nncols;
7084 char **rowpp = NULL;
7085
7086 if (*rowp[i * ncols + uniquec] != '0') {
7087 ret = SQLITE_ERROR;
7088 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
7089 rowp[i * ncols + namec]);
7090 if (sql) {
7091 dbtraceapi(d, "sqlite3_get_table", sql);
7092 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7093 &nnrows, &nncols, NULL);
7094 sqlite3_free(sql);
7095 }
7096 if (ret == SQLITE_OK) {
7097 size += nnrows;
7098 sqlite3_free_table(rowpp);
7099 }
7100 }
7101 }
7102nodata_but_rowid:
7103 if (size == 0) {
7104 size = 1;
7105 mkrowid = 1;
7106 }
7107 s->nrows = size;
7108 size = (size + 1) * asize;
7109 s->rows = xmalloc((size + 1) * sizeof (char *));
7110 if (!s->rows) {
7111 s->nrows = 0;
7112 sqlite3_free_table(rowp);
7113 sqlite3_free_table(rowppp);
7114 return nomem(s);
7115 }
7116 s->rows[0] = (char *) size;
7117 s->rows += 1;
7118 memset(s->rows, 0, sizeof (char *) * size);
7119 s->rowfree = freerows;
7120 if (mkrowid) {
7121 s->nrows = 0;
7122 goto mkrowid;
7123 }
7124 offs = 0;
7125 for (i = 1; i <= nrows; i++) {
7126 int nnrows, nncols;
7127 char **rowpp = NULL;
7128
7129 if (*rowp[i * ncols + uniquec] != '0') {
7130 int k;
7131
7132 ret = SQLITE_ERROR;
7133 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
7134 rowp[i * ncols + namec]);
7135 if (sql) {
7136 dbtraceapi(d, "sqlite3_get_table", sql);
7137 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7138 &nnrows, &nncols, NULL);
7139 sqlite3_free(sql);
7140 }
7141 if (ret != SQLITE_OK) {
7142 continue;
7143 }
7144 for (k = 0; nnrows && k < nncols; k++) {
7145 if (strcmp(rowpp[k], "name") == 0) {
7146 int m;
7147
7148 for (m = 1; m <= nnrows; m++) {
7149 int roffs = (offs + m) * s->ncols;
7150
7151 s->rows[roffs + 0] =
7152 xstrdup(stringify(SQL_SCOPE_SESSION));
7153 s->rows[roffs + 1] = xstrdup(rowpp[m * nncols + k]);
7154 s->rows[roffs + 4] = xstrdup("0");
7155 s->rows[roffs + 7] =
7156 xstrdup(stringify(SQL_PC_NOT_PSEUDO));
7157 if (namecc >= 0 && typecc >= 0) {
7158 int ii;
7159
7160 for (ii = 1; ii <= nnnrows; ii++) {
7161 if (strcmp(rowppp[ii * nnncols + namecc],
7162 rowpp[m * nncols + k]) == 0) {
7163 char *typen = rowppp[ii * nnncols + typecc];
7164 int sqltype, mm, dd, isnullable = 0;
7165 char buf[32];
7166
7167 s->rows[roffs + 3] = xstrdup(typen);
7168 sqltype = mapsqltype(typen, NULL, *s->ov3,
7169 s->nowchar[0],
7170 s->dobigint);
7171 getmd(typen, sqltype, &mm, &dd);
7172#ifdef SQL_LONGVARCHAR
7173 if (sqltype == SQL_VARCHAR && mm > 255) {
7174 sqltype = SQL_LONGVARCHAR;
7175 }
7176#endif
7177#ifdef WINTERFACE
7178#ifdef SQL_WLONGVARCHAR
7179 if (sqltype == SQL_WVARCHAR && mm > 255) {
7180 sqltype = SQL_WLONGVARCHAR;
7181 }
7182#endif
7183#endif
7184 if (sqltype == SQL_VARBINARY && mm > 255) {
7185 sqltype = SQL_LONGVARBINARY;
7186 }
7187 sprintf(buf, "%d", sqltype);
7188 s->rows[roffs + 2] = xstrdup(buf);
7189 sprintf(buf, "%d", mm);
7190 s->rows[roffs + 5] = xstrdup(buf);
7191 sprintf(buf, "%d", dd);
7192 s->rows[roffs + 6] = xstrdup(buf);
7193 if (notnullcc >= 0) {
7194 char *inp =
7195 rowppp[ii * nnncols + notnullcc];
7196
7197 isnullable = inp[0] != '0';
7198 }
7199 sprintf(buf, "%d", isnullable);
7200 s->rows[roffs + 8] = xstrdup(buf);
7201 }
7202 }
7203 }
7204 }
7205 }
7206 }
7207 offs += nnrows;
7208 sqlite3_free_table(rowpp);
7209 }
7210 }
7211 if (nullable == SQL_NO_NULLS) {
7212 for (i = 1; i < s->nrows; i++) {
7213 if (s->rows[i * s->ncols + 8][0] == '0') {
7214 int m, i1 = i + 1;
7215
7216 for (m = 0; m < s->ncols; m++) {
7217 freep(&s->rows[i * s->ncols + m]);
7218 }
7219 size = s->ncols * sizeof (char *) * (s->nrows - i1);
7220 if (size > 0) {
7221 memmove(s->rows + i * s->ncols,
7222 s->rows + i1 * s->ncols,
7223 size);
7224 memset(s->rows + s->nrows * s->ncols, 0,
7225 s->ncols * sizeof (char *));
7226 }
7227 s->nrows--;
7228 --i;
7229 }
7230 }
7231 }
7232mkrowid:
7233 sqlite3_free_table(rowp);
7234 sqlite3_free_table(rowppp);
7235 if (s->nrows == 0) {
7236 s->rows[s->ncols + 0] = xstrdup(stringify(SQL_SCOPE_SESSION));
7237 s->rows[s->ncols + 1] = xstrdup("_ROWID_");
7238 s->rows[s->ncols + 2] = xstrdup(stringify(SQL_INTEGER));
7239 s->rows[s->ncols + 3] = xstrdup("integer");
7240 s->rows[s->ncols + 4] = xstrdup("0");
7241 s->rows[s->ncols + 5] = xstrdup("10");
7242 s->rows[s->ncols + 6] = xstrdup("9");
7243 s->rows[s->ncols + 7] = xstrdup(stringify(SQL_PC_PSEUDO));
7244 s->rows[s->ncols + 8] = xstrdup(stringify(SQL_FALSE));
7245 s->nrows = 1;
7246 }
7247 return SQL_SUCCESS;
7248}
7249
7250#ifndef WINTERFACE
7266SQLRETURN SQL_API
7267SQLSpecialColumns(SQLHSTMT stmt, SQLUSMALLINT id,
7268 SQLCHAR *cat, SQLSMALLINT catLen,
7269 SQLCHAR *schema, SQLSMALLINT schemaLen,
7270 SQLCHAR *table, SQLSMALLINT tableLen,
7271 SQLUSMALLINT scope, SQLUSMALLINT nullable)
7272{
7273#if defined(_WIN32) || defined(_WIN64)
7274 char *c = NULL, *s = NULL, *t = NULL;
7275#endif
7276 SQLRETURN ret;
7277
7279#if defined(_WIN32) || defined(_WIN64)
7280 if (!((STMT *) stmt)->oemcp[0]) {
7281 ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
7282 table, tableLen, scope, nullable);
7283 goto done2;
7284 }
7285 if (cat) {
7286 c = wmb_to_utf_c((char *) cat, catLen);
7287 if (!c) {
7288 ret = nomem((STMT *) stmt);
7289 goto done;
7290 }
7291 }
7292 if (schema) {
7293 s = wmb_to_utf_c((char *) schema, schemaLen);
7294 if (!s) {
7295 ret = nomem((STMT *) stmt);
7296 goto done;
7297 }
7298 }
7299 if (table) {
7300 t = wmb_to_utf_c((char *) table, tableLen);
7301 if (!t) {
7302 ret = nomem((STMT *) stmt);
7303 goto done;
7304 }
7305 }
7306 ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
7307 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
7308 scope, nullable);
7309#else
7310 ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
7311 table, tableLen, scope, nullable);
7312#endif
7313#if defined(_WIN32) || defined(_WIN64)
7314done:
7315 uc_free(t);
7316 uc_free(s);
7317 uc_free(c);
7318done2:
7319 ;
7320#endif
7322 return ret;
7323}
7324#endif
7325
7326#ifdef WINTERFACE
7342SQLRETURN SQL_API
7343SQLSpecialColumnsW(SQLHSTMT stmt, SQLUSMALLINT id,
7344 SQLWCHAR *cat, SQLSMALLINT catLen,
7345 SQLWCHAR *schema, SQLSMALLINT schemaLen,
7346 SQLWCHAR *table, SQLSMALLINT tableLen,
7347 SQLUSMALLINT scope, SQLUSMALLINT nullable)
7348{
7349 char *c = NULL, *s = NULL, *t = NULL;
7350 SQLRETURN ret;
7351
7353 if (cat) {
7354 c = uc_to_utf_c(cat, catLen);
7355 if (!c) {
7356 ret = nomem((STMT *) stmt);
7357 goto done;
7358 }
7359 }
7360 if (schema) {
7361 s = uc_to_utf_c(schema, schemaLen);
7362 if (!s) {
7363 ret = nomem((STMT *) stmt);
7364 goto done;
7365 }
7366 }
7367 if (table) {
7368 t = uc_to_utf_c(table, tableLen);
7369 if (!t) {
7370 ret = nomem((STMT *) stmt);
7371 goto done;
7372 }
7373 }
7374 ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
7375 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
7376 scope, nullable);
7377done:
7378 uc_free(t);
7379 uc_free(s);
7380 uc_free(c);
7382 return ret;
7383}
7384#endif
7385
7390static COL fkeySpec2[] = {
7391 { "SYSTEM", "FOREIGNKEY", "PKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
7392 { "SYSTEM", "FOREIGNKEY", "PKTABLE_OWNER", SCOL_VARCHAR, 50 },
7393 { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
7394 { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7395 { "SYSTEM", "FOREIGNKEY", "FKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
7396 { "SYSTEM", "FOREIGNKEY", "FKTABLE_OWNER", SCOL_VARCHAR, 50 },
7397 { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
7398 { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7399 { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
7400 { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
7401 { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
7402 { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
7403 { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
7404 { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
7405};
7406
7407static COL fkeySpec3[] = {
7408 { "SYSTEM", "FOREIGNKEY", "PKTABLE_CAT", SCOL_VARCHAR, 50 },
7409 { "SYSTEM", "FOREIGNKEY", "PKTABLE_SCHEM", SCOL_VARCHAR, 50 },
7410 { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
7411 { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7412 { "SYSTEM", "FOREIGNKEY", "FKTABLE_CAT", SCOL_VARCHAR, 50 },
7413 { "SYSTEM", "FOREIGNKEY", "FKTABLE_SCHEM", SCOL_VARCHAR, 50 },
7414 { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
7415 { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7416 { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
7417 { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
7418 { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
7419 { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
7420 { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
7421 { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
7422};
7423
7442static SQLRETURN SQL_API
7444 SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7445 SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
7446 SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
7447 SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7448 SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
7449 SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
7450{
7451 STMT *s;
7452 DBC *d;
7453 SQLRETURN sret;
7454 int i, asize, ret, nrows, ncols, offs, namec, seqc, fromc, toc;
7455 int onu, ond;
7456 PTRDIFF_T size;
7457 char **rowp, *errp = NULL, *sql, pname[512], fname[512];
7458
7460 fkeySpec3, array_size(fkeySpec3), &asize);
7461 if (sret != SQL_SUCCESS) {
7462 return sret;
7463 }
7464 s = (STMT *) stmt;
7465 sret = starttran(s);
7466 if (sret != SQL_SUCCESS) {
7467 return sret;
7468 }
7469 d = (DBC *) s->dbc;
7470 if ((!PKtable || PKtable[0] == '\0' || PKtable[0] == '%') &&
7471 (!FKtable || FKtable[0] == '\0' || FKtable[0] == '%')) {
7472 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
7473 return SQL_ERROR;
7474 }
7475 size = 0;
7476 if (PKtable) {
7477 if (PKtableLen == SQL_NTS) {
7478 size = sizeof (pname) - 1;
7479 } else {
7480 size = min(sizeof (pname) - 1, PKtableLen);
7481 }
7482 strncpy(pname, (char *) PKtable, size);
7483 }
7484 pname[size] = '\0';
7485 size = 0;
7486 if (FKtable) {
7487
7488 if (FKtableLen == SQL_NTS) {
7489 size = sizeof (fname) - 1;
7490 } else {
7491 size = min(sizeof (fname) - 1, FKtableLen);
7492 }
7493 strncpy(fname, (char *) FKtable, size);
7494 }
7495 fname[size] = '\0';
7496 if (fname[0] != '\0') {
7497 int plen;
7498
7499 ret = SQLITE_ERROR;
7500 sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", fname);
7501 if (sql) {
7502 dbtraceapi(d, "sqlite3_get_table", sql);
7503 ret = sqlite3_get_table(d->sqlite, sql, &rowp,
7504 &nrows, &ncols, &errp);
7505 sqlite3_free(sql);
7506 }
7507 if (ret != SQLITE_OK) {
7508 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7509 errp ? errp : "unknown error", ret);
7510 if (errp) {
7511 sqlite3_free(errp);
7512 errp = NULL;
7513 }
7514 return SQL_ERROR;
7515 }
7516 if (errp) {
7517 sqlite3_free(errp);
7518 errp = NULL;
7519 }
7520 if (ncols * nrows <= 0) {
7521nodata:
7522 sqlite3_free_table(rowp);
7523 return SQL_SUCCESS;
7524 }
7525 size = 0;
7526 namec = findcol(rowp, ncols, "table");
7527 seqc = findcol(rowp, ncols, "seq");
7528 fromc = findcol(rowp, ncols, "from");
7529 toc = findcol(rowp, ncols, "to");
7530 onu = findcol(rowp, ncols, "on_update");
7531 ond = findcol(rowp, ncols, "on_delete");
7532 if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7533 goto nodata;
7534 }
7535 plen = strlen(pname);
7536 for (i = 1; i <= nrows; i++) {
7537 char *ptab = unquote(rowp[i * ncols + namec]);
7538
7539 if (plen && ptab) {
7540 int len = strlen(ptab);
7541
7542 if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
7543 continue;
7544 }
7545 }
7546 size++;
7547 }
7548 if (size == 0) {
7549 goto nodata;
7550 }
7551 s->nrows = size;
7552 size = (size + 1) * asize;
7553 s->rows = xmalloc((size + 1) * sizeof (char *));
7554 if (!s->rows) {
7555 s->nrows = 0;
7556 return nomem(s);
7557 }
7558 s->rows[0] = (char *) size;
7559 s->rows += 1;
7560 memset(s->rows, 0, sizeof (char *) * size);
7561 s->rowfree = freerows;
7562 offs = 0;
7563 for (i = 1; i <= nrows; i++) {
7564 int pos = 0, roffs = (offs + 1) * s->ncols;
7565 char *ptab = rowp[i * ncols + namec];
7566 char buf[32];
7567
7568 if (plen && ptab) {
7569 int len = strlen(ptab);
7570
7571 if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
7572 continue;
7573 }
7574 }
7575#if defined(_WIN32) || defined(_WIN64)
7576 s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
7577 s->rows[roffs + 1] = xstrdup("");
7578#else
7579 s->rows[roffs + 0] = xstrdup("");
7580 s->rows[roffs + 1] = xstrdup("");
7581#endif
7582 s->rows[roffs + 2] = xstrdup(ptab);
7583 s->rows[roffs + 3] = xstrdup(rowp[i * ncols + toc]);
7584 s->rows[roffs + 4] = xstrdup("");
7585 s->rows[roffs + 5] = xstrdup("");
7586 s->rows[roffs + 6] = xstrdup(fname);
7587 s->rows[roffs + 7] = xstrdup(rowp[i * ncols + fromc]);
7588 sscanf(rowp[i * ncols + seqc], "%d", &pos);
7589 sprintf(buf, "%d", pos + 1);
7590 s->rows[roffs + 8] = xstrdup(buf);
7591 if (onu < 0) {
7592 s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7593 } else {
7594 if (strcmp(rowp[i * ncols + onu], "SET NULL") == 0) {
7595 s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
7596 } else if (strcmp(rowp[i * ncols + onu], "SET DEFAULT") == 0) {
7597 s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_DEFAULT));
7598 } else if (strcmp(rowp[i * ncols + onu], "CASCADE") == 0) {
7599 s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
7600 } else if (strcmp(rowp[i * ncols + onu], "RESTRICT") == 0) {
7601 s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
7602 } else {
7603 s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7604 }
7605 }
7606 if (ond < 0) {
7607 s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7608 } else {
7609 if (strcmp(rowp[i * ncols + ond], "SET NULL") == 0) {
7610 s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
7611 } else if (strcmp(rowp[i * ncols + ond], "SET DEFAULT") == 0) {
7612 s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_DEFAULT));
7613 } else if (strcmp(rowp[i * ncols + ond], "CASCADE") == 0) {
7614 s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
7615 } else if (strcmp(rowp[i * ncols + ond], "RESTRICT") == 0) {
7616 s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
7617 } else {
7618 s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7619 }
7620 }
7621 s->rows[roffs + 11] = NULL;
7622 s->rows[roffs + 12] = NULL;
7623 s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
7624 offs++;
7625 }
7626 sqlite3_free_table(rowp);
7627 } else {
7628 int nnrows, nncols, plen = strlen(pname);
7629 char **rowpp;
7630
7631 sql = "select name from sqlite_master where type='table'";
7632 dbtraceapi(d, "sqlite3_get_table", sql);
7633 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
7634 if (ret != SQLITE_OK) {
7635 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7636 errp ? errp : "unknown error", ret);
7637 if (errp) {
7638 sqlite3_free(errp);
7639 errp = NULL;
7640 }
7641 return SQL_ERROR;
7642 }
7643 if (errp) {
7644 sqlite3_free(errp);
7645 errp = NULL;
7646 }
7647 if (ncols * nrows <= 0) {
7648 goto nodata;
7649 }
7650 size = 0;
7651 for (i = 1; i <= nrows; i++) {
7652 int k;
7653
7654 if (!rowp[i]) {
7655 continue;
7656 }
7657 rowpp = NULL;
7658 ret = SQLITE_ERROR;
7659 sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
7660 if (sql) {
7661 dbtraceapi(d, "sqlite3_get_table", sql);
7662 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7663 &nnrows, &nncols, NULL);
7664 sqlite3_free(sql);
7665 }
7666 if (ret != SQLITE_OK || nncols * nnrows <= 0) {
7667 sqlite3_free_table(rowpp);
7668 continue;
7669 }
7670 namec = findcol(rowpp, nncols, "table");
7671 seqc = findcol(rowpp, nncols, "seq");
7672 fromc = findcol(rowpp, nncols, "from");
7673 toc = findcol(rowpp, nncols, "to");
7674 if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7675 sqlite3_free_table(rowpp);
7676 continue;
7677 }
7678 for (k = 1; k <= nnrows; k++) {
7679 char *ptab = unquote(rowpp[k * nncols + namec]);
7680
7681 if (plen && ptab) {
7682 int len = strlen(ptab);
7683
7684 if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
7685 continue;
7686 }
7687 }
7688 size++;
7689 }
7690 sqlite3_free_table(rowpp);
7691 }
7692 if (size == 0) {
7693 goto nodata;
7694 }
7695 s->nrows = size;
7696 size = (size + 1) * asize;
7697 s->rows = xmalloc((size + 1) * sizeof (char *));
7698 if (!s->rows) {
7699 s->nrows = 0;
7700 return nomem(s);
7701 }
7702 s->rows[0] = (char *) size;
7703 s->rows += 1;
7704 memset(s->rows, 0, sizeof (char *) * size);
7705 s->rowfree = freerows;
7706 offs = 0;
7707 for (i = 1; i <= nrows; i++) {
7708 int k;
7709
7710 if (!rowp[i]) {
7711 continue;
7712 }
7713 rowpp = NULL;
7714 ret = SQLITE_ERROR;
7715 sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
7716 if (sql) {
7717 dbtraceapi(d, "sqlite3_get_table", sql);
7718 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7719 &nnrows, &nncols, NULL);
7720 sqlite3_free(sql);
7721 }
7722 if (ret != SQLITE_OK || nncols * nnrows <= 0) {
7723 sqlite3_free_table(rowpp);
7724 continue;
7725 }
7726 namec = findcol(rowpp, nncols, "table");
7727 seqc = findcol(rowpp, nncols, "seq");
7728 fromc = findcol(rowpp, nncols, "from");
7729 toc = findcol(rowpp, nncols, "to");
7730 onu = findcol(rowpp, nncols, "on_update");
7731 ond = findcol(rowpp, nncols, "on_delete");
7732 if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7733 sqlite3_free_table(rowpp);
7734 continue;
7735 }
7736 for (k = 1; k <= nnrows; k++) {
7737 int pos = 0, roffs = (offs + 1) * s->ncols;
7738 char *ptab = unquote(rowpp[k * nncols + namec]);
7739 char buf[32];
7740
7741 if (plen && ptab) {
7742 int len = strlen(ptab);
7743
7744 if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
7745 continue;
7746 }
7747 }
7748#if defined(_WIN32) || defined(_WIN64)
7749 s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
7750 s->rows[roffs + 1] = xstrdup("");
7751#else
7752 s->rows[roffs + 0] = xstrdup("");
7753 s->rows[roffs + 1] = xstrdup("");
7754#endif
7755 s->rows[roffs + 2] = xstrdup(ptab);
7756 s->rows[roffs + 3] = xstrdup(rowpp[k * nncols + toc]);
7757 s->rows[roffs + 4] = xstrdup("");
7758 s->rows[roffs + 5] = xstrdup("");
7759 s->rows[roffs + 6] = xstrdup(rowp[i]);
7760 s->rows[roffs + 7] = xstrdup(rowpp[k * nncols + fromc]);
7761 sscanf(rowpp[k * nncols + seqc], "%d", &pos);
7762 sprintf(buf, "%d", pos + 1);
7763 s->rows[roffs + 8] = xstrdup(buf);
7764 if (onu < 0) {
7765 s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7766 } else {
7767 if (strcmp(rowpp[k * nncols + onu], "SET NULL") == 0) {
7768 s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
7769 } else if (strcmp(rowpp[k * nncols + onu], "SET DEFAULT")
7770 == 0) {
7771 s->rows[roffs + 9] =
7772 xstrdup(stringify(SQL_SET_DEFAULT));
7773 } else if (strcmp(rowpp[k * nncols + onu], "CASCADE")
7774 == 0) {
7775 s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
7776 } else if (strcmp(rowpp[k * nncols + onu], "RESTRICT")
7777 == 0) {
7778 s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
7779 } else {
7780 s->rows[roffs + 9] =
7781 xstrdup(stringify(SQL_NO_ACTION));
7782 }
7783 }
7784 if (ond < 0) {
7785 s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7786 } else {
7787 if (strcmp(rowpp[k * nncols + ond], "SET NULL") == 0) {
7788 s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
7789 } else if (strcmp(rowpp[k * nncols + ond], "SET DEFAULT")
7790 == 0) {
7791 s->rows[roffs + 10] =
7792 xstrdup(stringify(SQL_SET_DEFAULT));
7793 } else if (strcmp(rowpp[k * nncols + ond], "CASCADE")
7794 == 0) {
7795 s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
7796 } else if (strcmp(rowpp[k * nncols + ond], "RESTRICT")
7797 == 0) {
7798 s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
7799 } else {
7800 s->rows[roffs + 10] =
7801 xstrdup(stringify(SQL_NO_ACTION));
7802 }
7803 }
7804 s->rows[roffs + 11] = NULL;
7805 s->rows[roffs + 12] = NULL;
7806 s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
7807 offs++;
7808 }
7809 sqlite3_free_table(rowpp);
7810 }
7811 sqlite3_free_table(rowp);
7812 }
7813 return SQL_SUCCESS;
7814}
7815
7816#ifndef WINTERFACE
7835SQLRETURN SQL_API
7836SQLForeignKeys(SQLHSTMT stmt,
7837 SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7838 SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
7839 SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
7840 SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7841 SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
7842 SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
7843{
7844#if defined(_WIN32) || defined(_WIN64)
7845 char *pc = NULL, *ps = NULL, *pt = NULL;
7846 char *fc = NULL, *fs = NULL, *ft = NULL;
7847#endif
7848 SQLRETURN ret;
7849
7851#if defined(_WIN32) || defined(_WIN64)
7852 if (!((STMT *) stmt)->oemcp[0]) {
7853 ret = drvforeignkeys(stmt,
7854 PKcatalog, PKcatalogLen,
7855 PKschema, PKschemaLen, PKtable, PKtableLen,
7856 FKcatalog, FKcatalogLen,
7857 FKschema, FKschemaLen,
7858 FKtable, FKtableLen);
7859 goto done2;
7860 }
7861 if (PKcatalog) {
7862 pc = wmb_to_utf_c((char *) PKcatalog, PKcatalogLen);
7863 if (!pc) {
7864 ret = nomem((STMT *) stmt);
7865 goto done;
7866 }
7867 }
7868 if (PKschema) {
7869 ps = wmb_to_utf_c((char *) PKschema, PKschemaLen);
7870 if (!ps) {
7871 ret = nomem((STMT *) stmt);
7872 goto done;
7873 }
7874 }
7875 if (PKtable) {
7876 pt = wmb_to_utf_c((char *) PKtable, PKtableLen);
7877 if (!pt) {
7878 ret = nomem((STMT *) stmt);
7879 goto done;
7880 }
7881 }
7882 if (FKcatalog) {
7883 fc = wmb_to_utf_c((char *) FKcatalog, FKcatalogLen);
7884 if (!fc) {
7885 ret = nomem((STMT *) stmt);
7886 goto done;
7887 }
7888 }
7889 if (FKschema) {
7890 fs = wmb_to_utf_c((char *) FKschema, FKschemaLen);
7891 if (!fs) {
7892 ret = nomem((STMT *) stmt);
7893 goto done;
7894 }
7895 }
7896 if (FKtable) {
7897 ft = wmb_to_utf_c((char *) FKtable, FKtableLen);
7898 if (!ft) {
7899 ret = nomem((STMT *) stmt);
7900 goto done;
7901 }
7902 }
7903 ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
7904 (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
7905 (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
7906 (SQLCHAR *) ft, SQL_NTS);
7907#else
7908 ret = drvforeignkeys(stmt,
7909 PKcatalog, PKcatalogLen,
7910 PKschema, PKschemaLen, PKtable, PKtableLen,
7911 FKcatalog, FKcatalogLen,
7912 FKschema, FKschemaLen,
7913 FKtable, FKtableLen);
7914#endif
7915#if defined(_WIN32) || defined(_WIN64)
7916done:
7917 uc_free(ft);
7918 uc_free(fs);
7919 uc_free(fc);
7920 uc_free(pt);
7921 uc_free(ps);
7922 uc_free(pc);
7923done2:
7924 ;
7925#endif
7927 return ret;
7928}
7929#endif
7930
7931#ifdef WINTERFACE
7950SQLRETURN SQL_API
7952 SQLWCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7953 SQLWCHAR *PKschema, SQLSMALLINT PKschemaLen,
7954 SQLWCHAR *PKtable, SQLSMALLINT PKtableLen,
7955 SQLWCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7956 SQLWCHAR *FKschema, SQLSMALLINT FKschemaLen,
7957 SQLWCHAR *FKtable, SQLSMALLINT FKtableLen)
7958{
7959 char *pc = NULL, *ps = NULL, *pt = NULL;
7960 char *fc = NULL, *fs = NULL, *ft = NULL;
7961 SQLRETURN ret;
7962
7964 if (PKcatalog) {
7965 pc = uc_to_utf_c(PKcatalog, PKcatalogLen);
7966 if (!pc) {
7967 ret = nomem((STMT *) stmt);
7968 goto done;
7969 }
7970 }
7971 if (PKschema) {
7972 ps = uc_to_utf_c(PKschema, PKschemaLen);
7973 if (!ps) {
7974 ret = nomem((STMT *) stmt);
7975 goto done;
7976 }
7977 }
7978 if (PKtable) {
7979 pt = uc_to_utf_c(PKtable, PKtableLen);
7980 if (!pt) {
7981 ret = nomem((STMT *) stmt);
7982 goto done;
7983 }
7984 }
7985 if (FKcatalog) {
7986 fc = uc_to_utf_c(FKcatalog, FKcatalogLen);
7987 if (!fc) {
7988 ret = nomem((STMT *) stmt);
7989 goto done;
7990 }
7991 }
7992 if (FKschema) {
7993 fs = uc_to_utf_c(FKschema, FKschemaLen);
7994 if (!fs) {
7995 ret = nomem((STMT *) stmt);
7996 goto done;
7997 }
7998 }
7999 if (FKtable) {
8000 ft = uc_to_utf_c(FKtable, FKtableLen);
8001 if (!ft) {
8002 ret = nomem((STMT *) stmt);
8003 goto done;
8004 }
8005 }
8006 ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
8007 (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
8008 (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
8009 (SQLCHAR *) ft, SQL_NTS);
8010done:
8011 uc_free(ft);
8012 uc_free(fs);
8013 uc_free(fc);
8014 uc_free(pt);
8015 uc_free(ps);
8016 uc_free(pc);
8018 return ret;
8019}
8020#endif
8021
8028static SQLRETURN
8030{
8031 int ret = SQL_SUCCESS, rc, busy_count = 0;
8032 char *errp = NULL;
8033 DBC *d = (DBC *) s->dbc;
8034
8035 if (!d->autocommit && !d->intrans && !d->trans_disable) {
8036begin_again:
8037 rc = sqlite3_exec(d->sqlite, "BEGIN TRANSACTION", NULL, NULL, &errp);
8038 if (rc == SQLITE_BUSY) {
8039 if (busy_handler((void *) d, ++busy_count)) {
8040 if (errp) {
8041 sqlite3_free(errp);
8042 errp = NULL;
8043 }
8044 goto begin_again;
8045 }
8046 }
8047 dbtracerc(d, rc, errp);
8048 if (rc != SQLITE_OK) {
8049 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
8050 errp ? errp : "unknown error", rc);
8051 ret = SQL_ERROR;
8052 } else {
8053 d->intrans = 1;
8054 }
8055 if (errp) {
8056 sqlite3_free(errp);
8057 errp = NULL;
8058 }
8059 }
8060 return ret;
8061}
8062
8071static SQLRETURN
8072endtran(DBC *d, SQLSMALLINT comptype, int force)
8073{
8074 int ret, busy_count = 0;
8075 char *sql, *errp = NULL;
8076
8077 if (!d->sqlite) {
8078 setstatd(d, -1, "not connected", (*d->ov3) ? "HY000" : "S1000");
8079 return SQL_ERROR;
8080 }
8081 if ((!force && d->autocommit) || !d->intrans) {
8082 return SQL_SUCCESS;
8083 }
8084 switch (comptype) {
8085 case SQL_COMMIT:
8086 sql = "COMMIT TRANSACTION";
8087 goto doit;
8088 case SQL_ROLLBACK:
8089 sql = "ROLLBACK TRANSACTION";
8090 doit:
8091 ret = sqlite3_exec(d->sqlite, sql, NULL, NULL, &errp);
8092 dbtracerc(d, ret, errp);
8093 if (ret == SQLITE_BUSY && busy_count < 10) {
8094 if (busy_handler((void *) d, ++busy_count)) {
8095 if (errp) {
8096 sqlite3_free(errp);
8097 errp = NULL;
8098 }
8099 goto doit;
8100 }
8101 }
8102 if (ret != SQLITE_OK) {
8103 setstatd(d, ret, "%s", (*d->ov3) ? "HY000" : "S1000",
8104 errp ? errp : "transaction failed");
8105 if (errp) {
8106 sqlite3_free(errp);
8107 errp = NULL;
8108 }
8109 return SQL_ERROR;
8110 }
8111 if (errp) {
8112 sqlite3_free(errp);
8113 errp = NULL;
8114 }
8115 d->intrans = 0;
8116 return SQL_SUCCESS;
8117 }
8118 setstatd(d, -1, "invalid completion type", (*d->ov3) ? "HY000" : "S1000");
8119 return SQL_ERROR;
8120}
8121
8130static SQLRETURN
8131drvendtran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
8132{
8133 DBC *dbc = NULL;
8134 int fail = 0;
8135 SQLRETURN ret;
8136#if defined(_WIN32) || defined(_WIN64)
8137 ENV *env;
8138#endif
8139
8140 switch (type) {
8141 case SQL_HANDLE_DBC:
8142 HDBC_LOCK((SQLHDBC) handle);
8143 if (handle == SQL_NULL_HDBC) {
8144 return SQL_INVALID_HANDLE;
8145 }
8146 dbc = (DBC *) handle;
8147 ret = endtran(dbc, comptype, 0);
8148 HDBC_UNLOCK((SQLHDBC) handle);
8149 return ret;
8150 case SQL_HANDLE_ENV:
8151 if (handle == SQL_NULL_HENV) {
8152 return SQL_INVALID_HANDLE;
8153 }
8154#if defined(_WIN32) || defined(_WIN64)
8155 env = (ENV *) handle;
8156 if (env->magic != ENV_MAGIC) {
8157 return SQL_INVALID_HANDLE;
8158 }
8159 EnterCriticalSection(&env->cs);
8160#endif
8161 dbc = ((ENV *) handle)->dbcs;
8162 while (dbc) {
8163 HDBC_LOCK((SQLHDBC) dbc);
8164 ret = endtran(dbc, comptype, 0);
8165 HDBC_UNLOCK((SQLHDBC) dbc);
8166 if (ret != SQL_SUCCESS) {
8167 fail++;
8168 }
8169 dbc = dbc->next;
8170 }
8171#if defined(_WIN32) || defined(_WIN64)
8172 LeaveCriticalSection(&env->cs);
8173#endif
8174 return fail ? SQL_ERROR : SQL_SUCCESS;
8175 }
8176 return SQL_INVALID_HANDLE;
8177}
8178
8187SQLRETURN SQL_API
8188SQLEndTran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
8189{
8190 return drvendtran(type, handle, comptype);
8191}
8192
8201SQLRETURN SQL_API
8202SQLTransact(SQLHENV env, SQLHDBC dbc, SQLUSMALLINT type)
8203{
8204 if (dbc != SQL_NULL_HDBC) {
8205 return drvendtran(SQL_HANDLE_DBC, (SQLHANDLE) dbc, type);
8206 }
8207 return drvendtran(SQL_HANDLE_ENV, (SQLHANDLE) env, type);
8208}
8209
8214SQLRETURN SQL_API
8215SQLCopyDesc(SQLHDESC source, SQLHDESC target)
8216{
8217 return SQL_ERROR;
8218}
8219
8220#ifndef WINTERFACE
8232SQLRETURN SQL_API
8233SQLNativeSql(SQLHSTMT stmt, SQLCHAR *sqlin, SQLINTEGER sqlinLen,
8234 SQLCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
8235{
8236 int outLen = 0;
8237 SQLRETURN ret = SQL_SUCCESS;
8238
8240 if (sqlinLen == SQL_NTS) {
8241 sqlinLen = strlen((char *) sqlin);
8242 }
8243 if (sql) {
8244 if (sqlMax > 0) {
8245 strncpy((char *) sql, (char *) sqlin, sqlMax - 1);
8246 sqlin[sqlMax - 1] = '\0';
8247 outLen = min(sqlMax - 1, sqlinLen);
8248 }
8249 } else {
8250 outLen = sqlinLen;
8251 }
8252 if (sqlLen) {
8253 *sqlLen = outLen;
8254 }
8255 if (sql && outLen < sqlinLen) {
8256 setstat((STMT *) stmt, -1, "data right truncated", "01004");
8257 ret = SQL_SUCCESS_WITH_INFO;
8258 }
8260 return ret;
8261}
8262#endif
8263
8264#ifdef WINTERFACE
8276SQLRETURN SQL_API
8277SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen,
8278 SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
8279{
8280 int outLen = 0;
8281 SQLRETURN ret = SQL_SUCCESS;
8282
8284 if (sqlinLen == SQL_NTS) {
8285 sqlinLen = uc_strlen(sqlin);
8286 }
8287 if (sql) {
8288 if (sqlMax > 0) {
8289 uc_strncpy(sql, sqlin, sqlMax - 1);
8290 sqlin[sqlMax - 1] = 0;
8291 outLen = min(sqlMax - 1, sqlinLen);
8292 }
8293 } else {
8294 outLen = sqlinLen;
8295 }
8296 if (sqlLen) {
8297 *sqlLen = outLen;
8298 }
8299 if (sql && outLen < sqlinLen) {
8300 setstat((STMT *) stmt, -1, "data right truncated", "01004");
8301 ret = SQL_SUCCESS_WITH_INFO;
8302 }
8304 return ret;
8305}
8306#endif
8307
8312static COL procSpec2[] = {
8313 { "SYSTEM", "PROCEDURE", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
8314 { "SYSTEM", "PROCEDURE", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
8315 { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8316 { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
8317 { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
8318 { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
8319 { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
8320 { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
8321};
8322
8323static COL procSpec3[] = {
8324 { "SYSTEM", "PROCEDURE", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
8325 { "SYSTEM", "PROCEDURE", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
8326 { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8327 { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
8328 { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
8329 { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
8330 { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
8331 { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
8332};
8333
8334#ifndef WINTERFACE
8347SQLRETURN SQL_API
8348SQLProcedures(SQLHSTMT stmt,
8349 SQLCHAR *catalog, SQLSMALLINT catalogLen,
8350 SQLCHAR *schema, SQLSMALLINT schemaLen,
8351 SQLCHAR *proc, SQLSMALLINT procLen)
8352{
8353 SQLRETURN ret;
8354
8359 return ret;
8360}
8361#endif
8362
8363#ifdef WINTERFACE
8376SQLRETURN SQL_API
8378 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
8379 SQLWCHAR *schema, SQLSMALLINT schemaLen,
8380 SQLWCHAR *proc, SQLSMALLINT procLen)
8381{
8382 SQLRETURN ret;
8383
8388 return ret;
8389}
8390#endif
8391
8396static COL procColSpec2[] = {
8397 { "SYSTEM", "PROCCOL", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
8398 { "SYSTEM", "PROCCOL", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
8399 { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8400 { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
8401 { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
8402 { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
8403 { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
8404 { "SYSTEM", "PROCCOL", "PRECISION", SQL_INTEGER, 10 },
8405 { "SYSTEM", "PROCCOL", "LENGTH", SQL_INTEGER, 10 },
8406 { "SYSTEM", "PROCCOL", "SCALE", SQL_SMALLINT, 5 },
8407 { "SYSTEM", "PROCCOL", "RADIX", SQL_SMALLINT, 5 },
8408 { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
8409 { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
8410 { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
8411 { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
8412 { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
8413 { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
8414 { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
8415 { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
8416};
8417
8418static COL procColSpec3[] = {
8419 { "SYSTEM", "PROCCOL", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
8420 { "SYSTEM", "PROCCOL", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
8421 { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8422 { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
8423 { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
8424 { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
8425 { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
8426 { "SYSTEM", "PROCCOL", "COLUMN_SIZE", SQL_INTEGER, 10 },
8427 { "SYSTEM", "PROCCOL", "BUFFER_LENGTH", SQL_INTEGER, 10 },
8428 { "SYSTEM", "PROCCOL", "DECIMAL_DIGITS", SQL_SMALLINT, 5 },
8429 { "SYSTEM", "PROCCOL", "NUM_PREC_RADIX", SQL_SMALLINT, 5 },
8430 { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
8431 { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
8432 { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
8433 { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
8434 { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
8435 { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
8436 { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
8437 { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
8438};
8439
8440#ifndef WINTERFACE
8455SQLRETURN SQL_API
8456SQLProcedureColumns(SQLHSTMT stmt,
8457 SQLCHAR *catalog, SQLSMALLINT catalogLen,
8458 SQLCHAR *schema, SQLSMALLINT schemaLen,
8459 SQLCHAR *proc, SQLSMALLINT procLen,
8460 SQLCHAR *column, SQLSMALLINT columnLen)
8461{
8462 SQLRETURN ret;
8463
8468 return ret;
8469}
8470#endif
8471
8472#ifdef WINTERFACE
8488SQLRETURN SQL_API
8490 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
8491 SQLWCHAR *schema, SQLSMALLINT schemaLen,
8492 SQLWCHAR *proc, SQLSMALLINT procLen,
8493 SQLWCHAR *column, SQLSMALLINT columnLen)
8494{
8495 SQLRETURN ret;
8496
8501 return ret;
8502}
8503#endif
8504
8515SQLRETURN SQL_API
8516SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val,
8517 SQLINTEGER len, SQLINTEGER *lenp)
8518{
8519 ENV *e;
8520 SQLRETURN ret = SQL_ERROR;
8521
8522 if (env == SQL_NULL_HENV) {
8523 return SQL_INVALID_HANDLE;
8524 }
8525 e = (ENV *) env;
8526 if (!e || e->magic != ENV_MAGIC) {
8527 return SQL_INVALID_HANDLE;
8528 }
8529#if defined(_WIN32) || defined(_WIN64)
8530 EnterCriticalSection(&e->cs);
8531#endif
8532 switch (attr) {
8533 case SQL_ATTR_CONNECTION_POOLING:
8534 if (val) {
8535 *((SQLINTEGER *) val) = e->pool ?
8536 SQL_CP_ONE_PER_DRIVER : SQL_CP_OFF;
8537 }
8538 if (lenp) {
8539 *lenp = sizeof (SQLINTEGER);
8540 }
8541 ret = SQL_SUCCESS;
8542 break;
8543 case SQL_ATTR_CP_MATCH:
8544 *((SQLINTEGER *) val) = SQL_CP_RELAXED_MATCH;
8545 if (lenp) {
8546 *lenp = sizeof (SQLINTEGER);
8547 }
8548 ret = SQL_SUCCESS;
8549 break;
8550 case SQL_ATTR_OUTPUT_NTS:
8551 if (val) {
8552 *((SQLINTEGER *) val) = SQL_TRUE;
8553 }
8554 if (lenp) {
8555 *lenp = sizeof (SQLINTEGER);
8556 }
8557 ret = SQL_SUCCESS;
8558 break;
8559 case SQL_ATTR_ODBC_VERSION:
8560 if (val) {
8561 *((SQLINTEGER *) val) = e->ov3 ? SQL_OV_ODBC3 : SQL_OV_ODBC2;
8562 }
8563 if (lenp) {
8564 *lenp = sizeof (SQLINTEGER);
8565 }
8566 ret = SQL_SUCCESS;
8567 break;
8568 }
8569#if defined(_WIN32) || defined(_WIN64)
8570 LeaveCriticalSection(&e->cs);
8571#endif
8572 return ret;
8573}
8574
8584SQLRETURN SQL_API
8585SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
8586{
8587 ENV *e;
8588 SQLRETURN ret = SQL_ERROR;
8589
8590 if (env == SQL_NULL_HENV) {
8591 return SQL_INVALID_HANDLE;
8592 }
8593 e = (ENV *) env;
8594 if (!e || e->magic != ENV_MAGIC) {
8595 return SQL_INVALID_HANDLE;
8596 }
8597#if defined(_WIN32) || defined(_WIN64)
8598 EnterCriticalSection(&e->cs);
8599#endif
8600 switch (attr) {
8601 case SQL_ATTR_CONNECTION_POOLING:
8602 if (val == (SQLPOINTER) SQL_CP_ONE_PER_DRIVER) {
8603 e->pool = 1;
8604 ret = SQL_SUCCESS;
8605 } else if (val == (SQLPOINTER) SQL_CP_OFF) {
8606 e->pool = 0;
8607 ret = SQL_SUCCESS;
8608 }
8609 break;
8610 case SQL_ATTR_CP_MATCH:
8611 ret = SQL_SUCCESS;
8612 break;
8613 case SQL_ATTR_OUTPUT_NTS:
8614 if (val == (SQLPOINTER) SQL_TRUE) {
8615 ret = SQL_SUCCESS;
8616 }
8617 break;
8618 case SQL_ATTR_ODBC_VERSION:
8619 if (!val) {
8620 break;
8621 }
8622 if (val == (SQLPOINTER) SQL_OV_ODBC2) {
8623 e->ov3 = 0;
8624 ret = SQL_SUCCESS;
8625 } else if (val == (SQLPOINTER) SQL_OV_ODBC3) {
8626 e->ov3 = 1;
8627 ret = SQL_SUCCESS;
8628 }
8629 break;
8630 }
8631#if defined(_WIN32) || defined(_WIN64)
8632 LeaveCriticalSection(&e->cs);
8633#endif
8634 return ret;
8635}
8636
8650static SQLRETURN
8651drvgetdiagrec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8652 SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
8653 SQLSMALLINT buflen, SQLSMALLINT *msglen)
8654{
8655 DBC *d = NULL;
8656 STMT *s = NULL;
8657 int len, naterr;
8658 char *logmsg, *sqlst;
8659 SQLRETURN ret = SQL_ERROR;
8660
8661 if (handle == SQL_NULL_HANDLE) {
8662 return SQL_INVALID_HANDLE;
8663 }
8664 if (sqlstate) {
8665 sqlstate[0] = '\0';
8666 }
8667 if (msg && buflen > 0) {
8668 msg[0] = '\0';
8669 }
8670 if (msglen) {
8671 *msglen = 0;
8672 }
8673 if (nativeerr) {
8674 *nativeerr = 0;
8675 }
8676 switch (htype) {
8677 case SQL_HANDLE_ENV:
8678 case SQL_HANDLE_DESC:
8679 return SQL_NO_DATA;
8680 case SQL_HANDLE_DBC:
8681 HDBC_LOCK((SQLHDBC) handle);
8682 d = (DBC *) handle;
8683 logmsg = (char *) d->logmsg;
8684 sqlst = d->sqlstate;
8685 naterr = d->naterr;
8686 break;
8687 case SQL_HANDLE_STMT:
8688 HSTMT_LOCK((SQLHSTMT) handle);
8689 s = (STMT *) handle;
8690 logmsg = (char *) s->logmsg;
8691 sqlst = s->sqlstate;
8692 naterr = s->naterr;
8693 break;
8694 default:
8695 return SQL_INVALID_HANDLE;
8696 }
8697 if (buflen < 0) {
8698 goto done;
8699 }
8700 if (recno > 1) {
8701 ret = SQL_NO_DATA;
8702 goto done;
8703 }
8704 len = strlen(logmsg);
8705 if (len == 0) {
8706 ret = SQL_NO_DATA;
8707 goto done;
8708 }
8709 if (nativeerr) {
8710 *nativeerr = naterr;
8711 }
8712 if (sqlstate) {
8713 strcpy((char *) sqlstate, sqlst);
8714 }
8715 if (msglen) {
8716 *msglen = len;
8717 }
8718 if (len >= buflen) {
8719 if (msg && buflen > 0) {
8720 strncpy((char *) msg, logmsg, buflen);
8721 msg[buflen - 1] = '\0';
8722 logmsg[0] = '\0';
8723 }
8724 } else if (msg) {
8725 strcpy((char *) msg, logmsg);
8726 logmsg[0] = '\0';
8727 }
8728 ret = SQL_SUCCESS;
8729done:
8730 switch (htype) {
8731 case SQL_HANDLE_DBC:
8732 HDBC_UNLOCK((SQLHDBC) handle);
8733 break;
8734 case SQL_HANDLE_STMT:
8735 HSTMT_UNLOCK((SQLHSTMT) handle);
8736 break;
8737 }
8738 return ret;
8739}
8740
8741#if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
8755SQLRETURN SQL_API
8756SQLGetDiagRec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8757 SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
8758 SQLSMALLINT buflen, SQLSMALLINT *msglen)
8759{
8760 return drvgetdiagrec(htype, handle, recno, sqlstate,
8761 nativeerr, msg, buflen, msglen);
8762}
8763#endif
8764
8765#if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
8766#ifdef WINTERFACE
8781SQLRETURN SQL_API
8782SQLGetDiagRecW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8783 SQLWCHAR *sqlstate, SQLINTEGER *nativeerr, SQLWCHAR *msg,
8784 SQLSMALLINT buflen, SQLSMALLINT *msglen)
8785{
8786 char state[16];
8787 SQLSMALLINT len;
8788 SQLRETURN ret;
8789
8790 ret = drvgetdiagrec(htype, handle, recno, (SQLCHAR *) state,
8791 nativeerr, (SQLCHAR *) msg, buflen, &len);
8792 if (ret == SQL_SUCCESS) {
8793 if (sqlstate) {
8794 uc_from_utf_buf((SQLCHAR *) state, -1, sqlstate,
8795 6 * sizeof (SQLWCHAR));
8796 }
8797 if (msg) {
8798 if (len > 0) {
8799 SQLWCHAR *m = NULL;
8800
8801 m = uc_from_utf((unsigned char *) msg, len);
8802 if (m) {
8803 if (buflen) {
8804 buflen /= sizeof (SQLWCHAR);
8805 uc_strncpy(msg, m, buflen);
8806 m[len] = 0;
8807 len = min(buflen, uc_strlen(m));
8808 } else {
8809 len = uc_strlen(m);
8810 }
8811 uc_free(m);
8812 } else {
8813 len = 0;
8814 }
8815 }
8816 if (len <= 0) {
8817 len = 0;
8818 if (buflen > 0) {
8819 msg[0] = 0;
8820 }
8821 }
8822 } else {
8823 /* estimated length !!! */
8824 len *= sizeof (SQLWCHAR);
8825 }
8826 if (msglen) {
8827 *msglen = len;
8828 }
8829 } else if (ret == SQL_NO_DATA) {
8830 if (sqlstate) {
8831 sqlstate[0] = 0;
8832 }
8833 if (msg) {
8834 if (buflen > 0) {
8835 msg[0] = 0;
8836 }
8837 }
8838 if (msglen) {
8839 *msglen = 0;
8840 }
8841 }
8842 return ret;
8843}
8844#endif
8845#endif
8846
8859static SQLRETURN
8860drvgetdiagfield(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8861 SQLSMALLINT id, SQLPOINTER info,
8862 SQLSMALLINT buflen, SQLSMALLINT *stringlen)
8863{
8864 DBC *d = NULL;
8865 STMT *s = NULL;
8866 int len, naterr, strbuf = 1;
8867 char *logmsg, *sqlst, *clrmsg = NULL;
8868 SQLRETURN ret = SQL_ERROR;
8869
8870 if (handle == SQL_NULL_HANDLE) {
8871 return SQL_INVALID_HANDLE;
8872 }
8873 if (stringlen) {
8874 *stringlen = 0;
8875 }
8876 switch (htype) {
8877 case SQL_HANDLE_ENV:
8878 case SQL_HANDLE_DESC:
8879 return SQL_NO_DATA;
8880 case SQL_HANDLE_DBC:
8881 HDBC_LOCK((SQLHDBC) handle);
8882 d = (DBC *) handle;
8883 logmsg = (char *) d->logmsg;
8884 sqlst = d->sqlstate;
8885 naterr = d->naterr;
8886 break;
8887 case SQL_HANDLE_STMT:
8888 HSTMT_LOCK((SQLHSTMT) handle);
8889 s = (STMT *) handle;
8890 d = (DBC *) s->dbc;
8891 logmsg = (char *) s->logmsg;
8892 sqlst = s->sqlstate;
8893 naterr = s->naterr;
8894 break;
8895 default:
8896 return SQL_INVALID_HANDLE;
8897 }
8898 if (buflen < 0) {
8899 switch (buflen) {
8900 case SQL_IS_POINTER:
8901 case SQL_IS_UINTEGER:
8902 case SQL_IS_INTEGER:
8903 case SQL_IS_USMALLINT:
8904 case SQL_IS_SMALLINT:
8905 strbuf = 0;
8906 break;
8907 default:
8908 ret = SQL_ERROR;
8909 goto done;
8910 }
8911 }
8912 if (recno > 1) {
8913 ret = SQL_NO_DATA;
8914 goto done;
8915 }
8916 switch (id) {
8917 case SQL_DIAG_CLASS_ORIGIN:
8918 logmsg = "ISO 9075";
8919 if (sqlst[0] == 'I' && sqlst[1] == 'M') {
8920 logmsg = "ODBC 3.0";
8921 }
8922 break;
8923 case SQL_DIAG_SUBCLASS_ORIGIN:
8924 logmsg = "ISO 9075";
8925 if (sqlst[0] == 'I' && sqlst[1] == 'M') {
8926 logmsg = "ODBC 3.0";
8927 } else if (sqlst[0] == 'H' && sqlst[1] == 'Y') {
8928 logmsg = "ODBC 3.0";
8929 } else if (sqlst[0] == '2' || sqlst[0] == '0' || sqlst[0] == '4') {
8930 logmsg = "ODBC 3.0";
8931 }
8932 break;
8933 case SQL_DIAG_CONNECTION_NAME:
8934 case SQL_DIAG_SERVER_NAME:
8935 logmsg = d->dsn ? d->dsn : "No DSN";
8936 break;
8937 case SQL_DIAG_SQLSTATE:
8938 logmsg = sqlst;
8939 break;
8940 case SQL_DIAG_MESSAGE_TEXT:
8941 if (info) {
8942 clrmsg = logmsg;
8943 }
8944 break;
8945 case SQL_DIAG_NUMBER:
8946 naterr = 1;
8947 /* fall through */
8948 case SQL_DIAG_NATIVE:
8949 len = strlen(logmsg);
8950 if (len == 0) {
8951 ret = SQL_NO_DATA;
8952 goto done;
8953 }
8954 if (info) {
8955 *((SQLINTEGER *) info) = naterr;
8956 }
8957 ret = SQL_SUCCESS;
8958 goto done;
8959 case SQL_DIAG_DYNAMIC_FUNCTION:
8960 logmsg = "";
8961 break;
8962 case SQL_DIAG_CURSOR_ROW_COUNT:
8963 if (htype == SQL_HANDLE_STMT) {
8964 SQLULEN count;
8965
8966 count = (s->isselect == 1 || s->isselect == -1) ? s->nrows : 0;
8967 *((SQLULEN *) info) = count;
8968 ret = SQL_SUCCESS;
8969 }
8970 goto done;
8971 case SQL_DIAG_ROW_COUNT:
8972 if (htype == SQL_HANDLE_STMT) {
8973 SQLULEN count;
8974
8975 count = s->isselect ? 0 : s->nrows;
8976 *((SQLULEN *) info) = count;
8977 ret = SQL_SUCCESS;
8978 }
8979 goto done;
8980 default:
8981 goto done;
8982 }
8983 if (info && buflen > 0) {
8984 ((char *) info)[0] = '\0';
8985 }
8986 len = strlen(logmsg);
8987 if (len == 0) {
8988 ret = SQL_NO_DATA;
8989 goto done;
8990 }
8991 if (stringlen) {
8992 *stringlen = len;
8993 }
8994 if (strbuf) {
8995 if (len >= buflen) {
8996 if (info && buflen > 0) {
8997 if (stringlen) {
8998 *stringlen = buflen - 1;
8999 }
9000 strncpy((char *) info, logmsg, buflen);
9001 ((char *) info)[buflen - 1] = '\0';
9002 }
9003 } else if (info) {
9004 strcpy((char *) info, logmsg);
9005 }
9006 }
9007 if (clrmsg) {
9008 *clrmsg = '\0';
9009 }
9010 ret = SQL_SUCCESS;
9011done:
9012 switch (htype) {
9013 case SQL_HANDLE_DBC:
9014 HDBC_UNLOCK((SQLHDBC) handle);
9015 break;
9016 case SQL_HANDLE_STMT:
9017 HSTMT_UNLOCK((SQLHSTMT) handle);
9018 break;
9019 }
9020 return ret;
9021}
9022
9023#ifndef WINTERFACE
9036SQLRETURN SQL_API
9037SQLGetDiagField(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
9038 SQLSMALLINT id, SQLPOINTER info,
9039 SQLSMALLINT buflen, SQLSMALLINT *stringlen)
9040{
9041 return drvgetdiagfield(htype, handle, recno, id, info, buflen, stringlen);
9042}
9043#endif
9044
9045#ifdef WINTERFACE
9058SQLRETURN SQL_API
9059SQLGetDiagFieldW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
9060 SQLSMALLINT id, SQLPOINTER info,
9061 SQLSMALLINT buflen, SQLSMALLINT *stringlen)
9062{
9063 SQLSMALLINT len;
9064 SQLRETURN ret;
9065
9066 ret = drvgetdiagfield(htype, handle, recno, id, info, buflen, &len);
9067 if (ret == SQL_SUCCESS) {
9068 if (info) {
9069 switch (id) {
9070 case SQL_DIAG_CLASS_ORIGIN:
9071 case SQL_DIAG_SUBCLASS_ORIGIN:
9072 case SQL_DIAG_CONNECTION_NAME:
9073 case SQL_DIAG_SERVER_NAME:
9074 case SQL_DIAG_SQLSTATE:
9075 case SQL_DIAG_MESSAGE_TEXT:
9076 case SQL_DIAG_DYNAMIC_FUNCTION:
9077 if (len > 0) {
9078 SQLWCHAR *m = NULL;
9079
9080 m = uc_from_utf((unsigned char *) info, len);
9081 if (m) {
9082 if (buflen) {
9083 buflen /= sizeof (SQLWCHAR);
9084 uc_strncpy(info, m, buflen);
9085 m[len] = 0;
9086 len = min(buflen, uc_strlen(m));
9087 } else {
9088 len = uc_strlen(m);
9089 }
9090 uc_free(m);
9091 len *= sizeof (SQLWCHAR);
9092 } else {
9093 len = 0;
9094 }
9095 }
9096 if (len <= 0) {
9097 len = 0;
9098 if (buflen > 0) {
9099 ((SQLWCHAR *) info)[0] = 0;
9100 }
9101 }
9102 }
9103 } else {
9104 switch (id) {
9105 case SQL_DIAG_CLASS_ORIGIN:
9106 case SQL_DIAG_SUBCLASS_ORIGIN:
9107 case SQL_DIAG_CONNECTION_NAME:
9108 case SQL_DIAG_SERVER_NAME:
9109 case SQL_DIAG_SQLSTATE:
9110 case SQL_DIAG_MESSAGE_TEXT:
9111 case SQL_DIAG_DYNAMIC_FUNCTION:
9112 len *= sizeof (SQLWCHAR);
9113 break;
9114 }
9115 }
9116 if (stringlen) {
9117 *stringlen = len;
9118 }
9119 }
9120 return ret;
9121}
9122#endif
9123
9134static SQLRETURN
9135drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9136 SQLINTEGER bufmax, SQLINTEGER *buflen)
9137{
9138 STMT *s = (STMT *) stmt;
9139 SQLULEN *uval = (SQLULEN *) val;
9140 SQLINTEGER dummy;
9141 char dummybuf[16];
9142
9143 if (!buflen) {
9144 buflen = &dummy;
9145 }
9146 if (!uval) {
9147 uval = (SQLPOINTER) dummybuf;
9148 }
9149 switch (attr) {
9150 case SQL_QUERY_TIMEOUT:
9151 *uval = 0;
9152 *buflen = sizeof (SQLULEN);
9153 return SQL_SUCCESS;
9154 case SQL_ATTR_CURSOR_TYPE:
9155 *uval = s->curtype;
9156 *buflen = sizeof (SQLULEN);
9157 return SQL_SUCCESS;
9158 case SQL_ATTR_CURSOR_SCROLLABLE:
9159 *uval = (s->curtype != SQL_CURSOR_FORWARD_ONLY) ?
9160 SQL_SCROLLABLE : SQL_NONSCROLLABLE;
9161 *buflen = sizeof (SQLULEN);
9162 return SQL_SUCCESS;
9163#ifdef SQL_ATTR_CURSOR_SENSITIVITY
9164 case SQL_ATTR_CURSOR_SENSITIVITY:
9165 *uval = SQL_UNSPECIFIED;
9166 *buflen = sizeof (SQLULEN);
9167 return SQL_SUCCESS;
9168#endif
9169 case SQL_ATTR_ROW_NUMBER:
9170 if (s->s3stmt) {
9171 *uval = (s->s3stmt_rownum < 0) ?
9172 SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
9173 } else {
9174 *uval = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
9175 }
9176 *buflen = sizeof (SQLULEN);
9177 return SQL_SUCCESS;
9178 case SQL_ATTR_ASYNC_ENABLE:
9179 *uval = SQL_ASYNC_ENABLE_OFF;
9180 *buflen = sizeof (SQLULEN);
9181 return SQL_SUCCESS;
9182 case SQL_CONCURRENCY:
9183 *uval = SQL_CONCUR_LOCK;
9184 *buflen = sizeof (SQLULEN);
9185 return SQL_SUCCESS;
9186 case SQL_ATTR_RETRIEVE_DATA:
9187 *uval = s->retr_data;
9188 *buflen = sizeof (SQLULEN);
9189 return SQL_SUCCESS;
9190 case SQL_ROWSET_SIZE:
9191 case SQL_ATTR_ROW_ARRAY_SIZE:
9192 *uval = s->rowset_size;
9193 *buflen = sizeof (SQLULEN);
9194 return SQL_SUCCESS;
9195 /* Needed for some driver managers, but dummies for now */
9196 case SQL_ATTR_IMP_ROW_DESC:
9197 case SQL_ATTR_APP_ROW_DESC:
9198 case SQL_ATTR_IMP_PARAM_DESC:
9199 case SQL_ATTR_APP_PARAM_DESC:
9200 *((SQLHDESC *) uval) = (SQLHDESC) DEAD_MAGIC;
9201 *buflen = sizeof (SQLHDESC);
9202 return SQL_SUCCESS;
9203 case SQL_ATTR_ROW_STATUS_PTR:
9204 *((SQLUSMALLINT **) uval) = s->row_status;
9205 *buflen = sizeof (SQLUSMALLINT *);
9206 return SQL_SUCCESS;
9207 case SQL_ATTR_ROWS_FETCHED_PTR:
9208 *((SQLULEN **) uval) = s->row_count;
9209 *buflen = sizeof (SQLULEN *);
9210 return SQL_SUCCESS;
9211 case SQL_ATTR_USE_BOOKMARKS: {
9212 STMT *s = (STMT *) stmt;
9213
9214 *(SQLUINTEGER *) uval = s->bkmrk;
9215 *buflen = sizeof (SQLUINTEGER);
9216 return SQL_SUCCESS;
9217 }
9218 case SQL_ATTR_FETCH_BOOKMARK_PTR:
9219 *(SQLPOINTER *) uval = s->bkmrkptr;
9220 *buflen = sizeof (SQLPOINTER);
9221 return SQL_SUCCESS;
9222 case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
9223 *((SQLULEN **) uval) = s->parm_bind_offs;
9224 *buflen = sizeof (SQLULEN *);
9225 return SQL_SUCCESS;
9226 case SQL_ATTR_PARAM_BIND_TYPE:
9227 *((SQLULEN *) uval) = s->parm_bind_type;
9228 *buflen = sizeof (SQLULEN);
9229 return SQL_SUCCESS;
9230 case SQL_ATTR_PARAM_OPERATION_PTR:
9231 *((SQLUSMALLINT **) uval) = s->parm_oper;
9232 *buflen = sizeof (SQLUSMALLINT *);
9233 return SQL_SUCCESS;
9234 case SQL_ATTR_PARAM_STATUS_PTR:
9235 *((SQLUSMALLINT **) uval) = s->parm_status;
9236 *buflen = sizeof (SQLUSMALLINT *);
9237 return SQL_SUCCESS;
9238 case SQL_ATTR_PARAMS_PROCESSED_PTR:
9239 *((SQLULEN **) uval) = s->parm_proc;
9240 *buflen = sizeof (SQLULEN *);
9241 return SQL_SUCCESS;
9242 case SQL_ATTR_PARAMSET_SIZE:
9243 *((SQLULEN *) uval) = s->paramset_size;
9244 *buflen = sizeof (SQLULEN);
9245 return SQL_SUCCESS;
9246 case SQL_ATTR_ROW_BIND_TYPE:
9247 *(SQLULEN *) uval = s->bind_type;
9248 *buflen = sizeof (SQLULEN);
9249 return SQL_SUCCESS;
9250 case SQL_ATTR_ROW_BIND_OFFSET_PTR:
9251 *((SQLULEN **) uval) = s->bind_offs;
9252 *buflen = sizeof (SQLULEN *);
9253 return SQL_SUCCESS;
9254 case SQL_ATTR_MAX_ROWS:
9255 *((SQLULEN *) uval) = s->max_rows;
9256 *buflen = sizeof (SQLULEN);
9257 return SQL_SUCCESS;
9258 case SQL_ATTR_MAX_LENGTH:
9259 *((SQLULEN *) uval) = 1000000000;
9260 *buflen = sizeof (SQLULEN);
9261 return SQL_SUCCESS;
9262#ifdef SQL_ATTR_METADATA_ID
9263 case SQL_ATTR_METADATA_ID:
9264 *((SQLULEN *) uval) = SQL_FALSE;
9265 *buflen = sizeof (SQLULEN);
9266 return SQL_SUCCESS;
9267#endif
9268 }
9269 return drvunimplstmt(stmt);
9270}
9271
9272#if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
9283SQLRETURN SQL_API
9284SQLGetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9285 SQLINTEGER bufmax, SQLINTEGER *buflen)
9286{
9287 SQLRETURN ret;
9288
9290 ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
9292 return ret;
9293}
9294#endif
9295
9296#ifdef WINTERFACE
9307SQLRETURN SQL_API
9308SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9309 SQLINTEGER bufmax, SQLINTEGER *buflen)
9310{
9311 SQLRETURN ret;
9312
9314 ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
9316 return ret;
9317}
9318#endif
9319
9329static SQLRETURN
9330drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9331 SQLINTEGER buflen)
9332{
9333 STMT *s = (STMT *) stmt;
9334#if defined(SQL_BIGINT) && defined(__WORDSIZE) && (__WORDSIZE == 64)
9335 SQLBIGINT uval;
9336
9337 uval = (SQLBIGINT) val;
9338#else
9339 SQLULEN uval;
9340
9341 uval = (SQLULEN) val;
9342#endif
9343 switch (attr) {
9344 case SQL_ATTR_CURSOR_TYPE:
9345 if (val == (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY) {
9346 s->curtype = SQL_CURSOR_FORWARD_ONLY;
9347 } else {
9348 s->curtype = SQL_CURSOR_STATIC;
9349 }
9350 if (val != (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY &&
9351 val != (SQLPOINTER) SQL_CURSOR_STATIC) {
9352 goto e01s02;
9353 }
9354 return SQL_SUCCESS;
9355 case SQL_ATTR_CURSOR_SCROLLABLE:
9356 if (val == (SQLPOINTER) SQL_NONSCROLLABLE) {
9357 s->curtype = SQL_CURSOR_FORWARD_ONLY;
9358 } else {
9359 s->curtype = SQL_CURSOR_STATIC;
9360 }
9361 return SQL_SUCCESS;
9362 case SQL_ATTR_ASYNC_ENABLE:
9363 if (val != (SQLPOINTER) SQL_ASYNC_ENABLE_OFF) {
9364 e01s02:
9365 setstat(s, -1, "option value changed", "01S02");
9366 return SQL_SUCCESS_WITH_INFO;
9367 }
9368 return SQL_SUCCESS;
9369 case SQL_CONCURRENCY:
9370 if (val != (SQLPOINTER) SQL_CONCUR_LOCK) {
9371 goto e01s02;
9372 }
9373 return SQL_SUCCESS;
9374#ifdef SQL_ATTR_CURSOR_SENSITIVITY
9375 case SQL_ATTR_CURSOR_SENSITIVITY:
9376 if (val != (SQLPOINTER) SQL_UNSPECIFIED) {
9377 goto e01s02;
9378 }
9379 return SQL_SUCCESS;
9380#endif
9381 case SQL_ATTR_QUERY_TIMEOUT:
9382 return SQL_SUCCESS;
9383 case SQL_ATTR_RETRIEVE_DATA:
9384 if (val != (SQLPOINTER) SQL_RD_ON &&
9385 val != (SQLPOINTER) SQL_RD_OFF) {
9386 goto e01s02;
9387 }
9388 s->retr_data = uval;
9389 return SQL_SUCCESS;
9390 case SQL_ROWSET_SIZE:
9391 case SQL_ATTR_ROW_ARRAY_SIZE:
9392 if (uval < 1) {
9393 setstat(s, -1, "invalid rowset size", "HY000");
9394 return SQL_ERROR;
9395 } else {
9396 SQLUSMALLINT *rst = &s->row_status1;
9397
9398 if (uval > 1) {
9399 rst = xmalloc(sizeof (SQLUSMALLINT) * uval);
9400 if (!rst) {
9401 return nomem(s);
9402 }
9403 }
9404 if (s->row_status0 != &s->row_status1) {
9405 freep(&s->row_status0);
9406 }
9407 s->row_status0 = rst;
9408 s->rowset_size = uval;
9409 }
9410 return SQL_SUCCESS;
9411 case SQL_ATTR_ROW_STATUS_PTR:
9412 s->row_status = (SQLUSMALLINT *) val;
9413 return SQL_SUCCESS;
9414 case SQL_ATTR_ROWS_FETCHED_PTR:
9415 s->row_count = (SQLULEN *) val;
9416 return SQL_SUCCESS;
9417 case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
9418 s->parm_bind_offs = (SQLULEN *) val;
9419 return SQL_SUCCESS;
9420 case SQL_ATTR_PARAM_BIND_TYPE:
9421 s->parm_bind_type = uval;
9422 return SQL_SUCCESS;
9423 case SQL_ATTR_PARAM_OPERATION_PTR:
9424 s->parm_oper = (SQLUSMALLINT *) val;
9425 return SQL_SUCCESS;
9426 case SQL_ATTR_PARAM_STATUS_PTR:
9427 s->parm_status = (SQLUSMALLINT *) val;
9428 return SQL_SUCCESS;
9429 case SQL_ATTR_PARAMS_PROCESSED_PTR:
9430 s->parm_proc = (SQLULEN *) val;
9431 return SQL_SUCCESS;
9432 case SQL_ATTR_PARAMSET_SIZE:
9433 if (uval < 1) {
9434 goto e01s02;
9435 }
9436 s->paramset_size = uval;
9437 s->paramset_count = 0;
9438 return SQL_SUCCESS;
9439 case SQL_ATTR_ROW_BIND_TYPE:
9440 s->bind_type = uval;
9441 return SQL_SUCCESS;
9442 case SQL_ATTR_ROW_BIND_OFFSET_PTR:
9443 s->bind_offs = (SQLULEN *) val;
9444 return SQL_SUCCESS;
9445 case SQL_ATTR_USE_BOOKMARKS:
9446 if (val != (SQLPOINTER) SQL_UB_OFF &&
9447 val != (SQLPOINTER) SQL_UB_ON &&
9448 val != (SQLPOINTER) SQL_UB_VARIABLE) {
9449 goto e01s02;
9450 }
9451 if (*s->ov3 && val == (SQLPOINTER) SQL_UB_VARIABLE) {
9452 s->bkmrk = SQL_UB_VARIABLE;
9453 return SQL_SUCCESS;
9454 }
9455 if (val == (SQLPOINTER) SQL_UB_VARIABLE) {
9456 s->bkmrk = SQL_UB_ON;
9457 goto e01s02;
9458 }
9459 s->bkmrk = (val == (SQLPOINTER) SQL_UB_ON) ? SQL_UB_ON : SQL_UB_OFF;
9460 return SQL_SUCCESS;
9461 case SQL_ATTR_FETCH_BOOKMARK_PTR:
9462 s->bkmrkptr = (SQLINTEGER *) val;
9463 return SQL_SUCCESS;
9464 case SQL_ATTR_MAX_ROWS:
9465 s->max_rows = uval;
9466 return SQL_SUCCESS;
9467 case SQL_ATTR_MAX_LENGTH:
9468 if (val != (SQLPOINTER) 1000000000) {
9469 goto e01s02;
9470 }
9471 return SQL_SUCCESS;
9472#ifdef SQL_ATTR_METADATA_ID
9473 case SQL_ATTR_METADATA_ID:
9474 if (val != (SQLPOINTER) SQL_FALSE) {
9475 goto e01s02;
9476 }
9477 return SQL_SUCCESS;
9478#endif
9479 }
9480 return drvunimplstmt(stmt);
9481}
9482
9483#if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
9493SQLRETURN SQL_API
9494SQLSetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9495 SQLINTEGER buflen)
9496{
9497 SQLRETURN ret;
9498
9500 ret = drvsetstmtattr(stmt, attr, val, buflen);
9502 return ret;
9503}
9504#endif
9505
9506#ifdef WINTERFACE
9516SQLRETURN SQL_API
9517SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9518 SQLINTEGER buflen)
9519{
9520 SQLRETURN ret;
9521
9523 ret = drvsetstmtattr(stmt, attr, val, buflen);
9525 return ret;
9526}
9527#endif
9528
9537static SQLRETURN
9538drvgetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9539{
9540 STMT *s = (STMT *) stmt;
9541 SQLUINTEGER *ret = (SQLUINTEGER *) param;
9542
9543 switch (opt) {
9544 case SQL_QUERY_TIMEOUT:
9545 *ret = 0;
9546 return SQL_SUCCESS;
9547 case SQL_CURSOR_TYPE:
9548 *ret = s->curtype;
9549 return SQL_SUCCESS;
9550 case SQL_ROW_NUMBER:
9551 if (s->s3stmt) {
9552 *ret = (s->s3stmt_rownum < 0) ?
9553 SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
9554 } else {
9555 *ret = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
9556 }
9557 return SQL_SUCCESS;
9558 case SQL_ASYNC_ENABLE:
9559 *ret = SQL_ASYNC_ENABLE_OFF;
9560 return SQL_SUCCESS;
9561 case SQL_CONCURRENCY:
9562 *ret = SQL_CONCUR_LOCK;
9563 return SQL_SUCCESS;
9564 case SQL_ATTR_RETRIEVE_DATA:
9565 *ret = s->retr_data;
9566 return SQL_SUCCESS;
9567 case SQL_ROWSET_SIZE:
9568 case SQL_ATTR_ROW_ARRAY_SIZE:
9569 *ret = s->rowset_size;
9570 return SQL_SUCCESS;
9571 case SQL_ATTR_MAX_ROWS:
9572 *ret = s->max_rows;
9573 return SQL_SUCCESS;
9574 case SQL_ATTR_MAX_LENGTH:
9575 *ret = 1000000000;
9576 return SQL_SUCCESS;
9577 }
9578 return drvunimplstmt(stmt);
9579}
9580
9589SQLRETURN SQL_API
9590SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9591{
9592 SQLRETURN ret;
9593
9595 ret = drvgetstmtoption(stmt, opt, param);
9597 return ret;
9598}
9599
9600#ifdef WINTERFACE
9609SQLRETURN SQL_API
9610SQLGetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9611{
9612 SQLRETURN ret;
9613
9615 ret = drvgetstmtoption(stmt, opt, param);
9617 return ret;
9618}
9619#endif
9620
9629static SQLRETURN
9630drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
9631{
9632 STMT *s = (STMT *) stmt;
9633
9634 switch (opt) {
9635 case SQL_CURSOR_TYPE:
9636 if (param == SQL_CURSOR_FORWARD_ONLY) {
9637 s->curtype = param;
9638 } else {
9639 s->curtype = SQL_CURSOR_STATIC;
9640 }
9641 if (param != SQL_CURSOR_FORWARD_ONLY &&
9642 param != SQL_CURSOR_STATIC) {
9643 goto e01s02;
9644 }
9645 return SQL_SUCCESS;
9646 case SQL_ASYNC_ENABLE:
9647 if (param != SQL_ASYNC_ENABLE_OFF) {
9648 goto e01s02;
9649 }
9650 return SQL_SUCCESS;
9651 case SQL_CONCURRENCY:
9652 if (param != SQL_CONCUR_LOCK) {
9653 goto e01s02;
9654 }
9655 return SQL_SUCCESS;
9656 case SQL_QUERY_TIMEOUT:
9657 return SQL_SUCCESS;
9658 case SQL_RETRIEVE_DATA:
9659 if (param != SQL_RD_ON && param != SQL_RD_OFF) {
9660 e01s02:
9661 setstat(s, -1, "option value changed", "01S02");
9662 return SQL_SUCCESS_WITH_INFO;
9663 }
9664 s->retr_data = (int) param;
9665 return SQL_SUCCESS;
9666 case SQL_ROWSET_SIZE:
9667 case SQL_ATTR_ROW_ARRAY_SIZE:
9668 if (param < 1) {
9669 setstat(s, -1, "invalid rowset size", "HY000");
9670 return SQL_ERROR;
9671 } else {
9672 SQLUSMALLINT *rst = &s->row_status1;
9673
9674 if (param > 1) {
9675 rst = xmalloc(sizeof (SQLUSMALLINT) * param);
9676 if (!rst) {
9677 return nomem(s);
9678 }
9679 }
9680 if (s->row_status0 != &s->row_status1) {
9681 freep(&s->row_status0);
9682 }
9683 s->row_status0 = rst;
9684 s->rowset_size = param;
9685 }
9686 return SQL_SUCCESS;
9687 case SQL_ATTR_MAX_ROWS:
9688 s->max_rows = param;
9689 return SQL_SUCCESS;
9690 case SQL_ATTR_MAX_LENGTH:
9691 if (param != 1000000000) {
9692 goto e01s02;
9693 }
9694 return SQL_SUCCESS;
9695 }
9696 return drvunimplstmt(stmt);
9697}
9698
9707SQLRETURN SQL_API
9708SQLSetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt,
9710{
9711 SQLRETURN ret;
9712
9714 ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
9716 return ret;
9717}
9718
9719#ifdef WINTERFACE
9728SQLRETURN SQL_API
9729SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt,
9731{
9732 SQLRETURN ret;
9733
9735 ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
9737 return ret;
9738}
9739#endif
9740
9747static SQLRETURN
9749{
9750 int i;
9751
9752 if (!s->bindcols || s->nbindcols < s->ncols) {
9753unbound:
9754 setstat(s, -1, "unbound columns", (*s->ov3) ? "HY000" : "S1000");
9755 return SQL_ERROR;
9756 }
9757 for (i = 0; i < s->ncols; i++) {
9758 BINDCOL *b = &s->bindcols[i];
9759
9760 if (b->type == SQL_UNKNOWN_TYPE || !b->valp) {
9761 goto unbound;
9762 }
9763 }
9764 return SQL_SUCCESS;
9765}
9766
9778static SQLRETURN
9779setposbind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
9780{
9781 DBC *d = (DBC *) s->dbc;
9782 SQLPOINTER dp = 0;
9783 SQLLEN *lp = 0;
9784 BINDCOL *b = &s->bindcols[i];
9785 COL *c = &s->cols[i];
9786 char strbuf[128], *cp;
9787
9788 if (b->valp) {
9789 if (s->bind_type != SQL_BIND_BY_COLUMN) {
9790 dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
9791 } else {
9792 dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
9793 }
9794 if (s->bind_offs) {
9795 dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
9796 }
9797 }
9798 if (b->lenp) {
9799 if (s->bind_type != SQL_BIND_BY_COLUMN) {
9800 lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
9801 } else {
9802 lp = b->lenp + rsi;
9803 }
9804 if (s->bind_offs) {
9805 lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
9806 }
9807 }
9808 if (!dp || !lp) {
9809 setstat(s, -1, "unbound column in positional update",
9810 (*s->ov3) ? "HY000" : "S1000");
9811 return SQL_ERROR;
9812 }
9813 if (*lp == SQL_NULL_DATA) {
9814 sqlite3_bind_null(stmt, si);
9815 if (d->trace) {
9816 fprintf(d->trace, "-- parameter %d: NULL\n", si);
9817 fflush(d->trace);
9818 }
9819 return SQL_SUCCESS;
9820 }
9821 switch (b->type) {
9822 case SQL_C_UTINYINT:
9823 case SQL_C_TINYINT:
9824 case SQL_C_STINYINT:
9825 sqlite3_bind_int(stmt, si, *(SQLCHAR *) dp);
9826 if (d->trace) {
9827 fprintf(d->trace, "-- parameter %d: %d\n", si, *(SQLCHAR *) dp);
9828 fflush(d->trace);
9829 }
9830 break;
9831#ifdef SQL_BIT
9832 case SQL_C_BIT:
9833 sqlite3_bind_int(stmt, si, (*(SQLCHAR *) dp) ? 1 : 0);
9834 if (d->trace) {
9835 fprintf(d->trace, "-- parameter %d: %d\n", si,
9836 (*(SQLCHAR *) dp) ? 1 : 0);
9837 fflush(d->trace);
9838 }
9839 break;
9840#endif
9841 case SQL_C_USHORT:
9842 sqlite3_bind_int(stmt, si, *(SQLUSMALLINT *) dp);
9843 if (d->trace) {
9844 fprintf(d->trace, "-- parameter %d: %d\n", si,
9845 *(SQLUSMALLINT *) dp);
9846 fflush(d->trace);
9847 }
9848 break;
9849 case SQL_C_SHORT:
9850 case SQL_C_SSHORT:
9851 sqlite3_bind_int(stmt, si, *(SQLSMALLINT *) dp);
9852 if (d->trace) {
9853 fprintf(d->trace, "-- parameter %d: %d\n", si,
9854 *(SQLSMALLINT *) dp);
9855 fflush(d->trace);
9856 }
9857 break;
9858 case SQL_C_ULONG:
9859 sqlite3_bind_int(stmt, si, *(SQLUINTEGER *) dp);
9860 if (d->trace) {
9861 fprintf(d->trace, "-- parameter %d: %ld\n", si,
9862 (long) *(SQLUINTEGER *) dp);
9863 fflush(d->trace);
9864 }
9865 break;
9866 case SQL_C_LONG:
9867 case SQL_C_SLONG:
9868 sqlite3_bind_int(stmt, si, *(SQLINTEGER *) dp);
9869 if (d->trace) {
9870 fprintf(d->trace, "-- parameter %d: %ld\n", si,
9871 (long) *(SQLINTEGER *) dp);
9872 fflush(d->trace);
9873 }
9874 break;
9875#ifdef SQL_BIGINT
9876 case SQL_C_UBIGINT:
9877 case SQL_C_SBIGINT:
9878 sqlite3_bind_int64(stmt, si, *(SQLBIGINT *) dp);
9879 if (d->trace) {
9880 fprintf(d->trace,
9881#ifdef _WIN32
9882 "-- parameter %d: %I64d\n",
9883#else
9884 "-- parameter %d: %lld\n",
9885#endif
9886 si, (sqlite_int64) *(SQLBIGINT *) dp);
9887 fflush(d->trace);
9888 }
9889 break;
9890#endif
9891 case SQL_C_FLOAT:
9892 sqlite3_bind_double(stmt, si, *(float *) dp);
9893 if (d->trace) {
9894 fprintf(d->trace, "-- parameter %d: %g\n", si,
9895 *(float *) dp);
9896 fflush(d->trace);
9897 }
9898 break;
9899 case SQL_C_DOUBLE:
9900 sqlite3_bind_double(stmt, si, *(double *) dp);
9901 if (d->trace) {
9902 fprintf(d->trace, "-- parameter %d: %g\n", si,
9903 *(double *) dp);
9904 fflush(d->trace);
9905 }
9906 break;
9907 case SQL_C_BINARY:
9908 sqlite3_bind_blob(stmt, si, (char *) dp, *lp, SQLITE_STATIC);
9909 if (d->trace) {
9910 fprintf(d->trace, "-- parameter %d: [BLOB]\n", si);
9911 fflush(d->trace);
9912 }
9913 break;
9914#ifdef WCHARSUPPORT
9915 case SQL_C_WCHAR:
9916 cp = uc_to_utf((SQLWCHAR *) dp, *lp);
9917 if (!cp) {
9918 return nomem(s);
9919 }
9920 sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
9921 if (d->trace) {
9922 fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
9923 fflush(d->trace);
9924 }
9925 uc_free(cp);
9926 break;
9927#endif
9928 case SQL_C_CHAR:
9929#if defined(_WIN32) || defined(_WIN64)
9930 if (*s->oemcp) {
9931 cp = wmb_to_utf((char *) dp, *lp);
9932 if (!cp) {
9933 return nomem(s);
9934 }
9935 sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
9936 if (d->trace) {
9937 fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
9938 fflush(d->trace);
9939 }
9940 uc_free(cp);
9941 } else
9942#endif
9943 {
9944 if (*lp == SQL_NTS) {
9945 sqlite3_bind_text(stmt, si, (char *) dp, -1,
9946 SQLITE_STATIC);
9947 if (d->trace) {
9948 fprintf(d->trace, "-- parameter %d: '%s'\n", si,
9949 (char *) dp);
9950 fflush(d->trace);
9951 }
9952 } else {
9953 sqlite3_bind_text(stmt, si, (char *) dp, *lp,
9954 SQLITE_STATIC);
9955 if (d->trace) {
9956 fprintf(d->trace, "-- parameter %d: '%*s'\n", si,
9957 (int) *lp, (char *) dp);
9958 fflush(d->trace);
9959 }
9960 }
9961 }
9962 break;
9963#ifdef SQL_C_TYPE_DATE
9964 case SQL_C_TYPE_DATE:
9965#endif
9966 case SQL_C_DATE:
9967 if (*s->jdconv) {
9968 int a, b, x1, x2, y, m, dd;
9969 double v;
9970
9971 y = ((DATE_STRUCT *) dp)->year;
9972 m = ((DATE_STRUCT *) dp)->month;
9973 dd = ((DATE_STRUCT *) dp)->day;
9974 if (m <= 2) {
9975 y--;
9976 m += 12;
9977 }
9978 a = y / 100;
9979 b = 2 - a + (a / 4);
9980 x1 = 36525 * (y + 4716) / 100;
9981 x2 = 306001 * (m + 1) / 10000;
9982 v = x1 + x2 + dd + b - 1524.5;
9983 sqlite3_bind_double(stmt, si, v);
9984 if (d->trace) {
9985 fprintf(d->trace, "-- parameter %d: %g\n", si, v);
9986 fflush(d->trace);
9987 }
9988 } else {
9989 sprintf(strbuf, "%04d-%02d-%02d",
9990 ((DATE_STRUCT *) dp)->year,
9991 ((DATE_STRUCT *) dp)->month,
9992 ((DATE_STRUCT *) dp)->day);
9993 sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
9994 if (d->trace) {
9995 fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
9996 fflush(d->trace);
9997 }
9998 }
9999 break;
10000#ifdef SQL_C_TYPE_TIME
10001 case SQL_C_TYPE_TIME:
10002#endif
10003 case SQL_C_TIME:
10004 if (*s->jdconv) {
10005 double v;
10006
10007 v = 2451544.5 +
10008 (((TIME_STRUCT *) dp)->hour * 3600000.0 +
10009 ((TIME_STRUCT *) dp)->minute * 60000.0 +
10010 ((TIME_STRUCT *) dp)->second * 1000.0) / 86400000.0;
10011 sqlite3_bind_double(stmt, si, v);
10012 if (d->trace) {
10013 fprintf(d->trace, "-- parameter %d: %g\n", si, v);
10014 fflush(d->trace);
10015 }
10016 } else {
10017 sprintf(strbuf, "%02d:%02d:%02d",
10018 ((TIME_STRUCT *) dp)->hour,
10019 ((TIME_STRUCT *) dp)->minute,
10020 ((TIME_STRUCT *) dp)->second);
10021 sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
10022 if (d->trace) {
10023 fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
10024 fflush(d->trace);
10025 }
10026 }
10027 break;
10028#ifdef SQL_C_TYPE_TIMESTAMP
10029 case SQL_C_TYPE_TIMESTAMP:
10030#endif
10031 case SQL_C_TIMESTAMP:
10032 if (*s->jdconv) {
10033 int a, b, x1, x2, y, m, dd;
10034 double v;
10035
10036 y = ((TIMESTAMP_STRUCT *) dp)->year;
10037 m = ((TIMESTAMP_STRUCT *) dp)->month;
10038 dd = ((TIMESTAMP_STRUCT *) dp)->day;
10039 if (m <= 2) {
10040 y--;
10041 m += 12;
10042 }
10043 a = y / 100;
10044 b = 2 - a + (a / 4);
10045 x1 = 36525 * (y + 4716) / 100;
10046 x2 = 306001 * (m + 1) / 10000;
10047 v = x1 + x2 + dd + b - 1524.5 +
10048 (((TIMESTAMP_STRUCT *) dp)->hour * 3600000.0 +
10049 ((TIMESTAMP_STRUCT *) dp)->minute * 60000.0 +
10050 ((TIMESTAMP_STRUCT *) dp)->second * 1000.0 +
10051 ((TIMESTAMP_STRUCT *) dp)->fraction / 1.0E6)
10052 / 86400000.0;
10053 sqlite3_bind_double(stmt, si, v);
10054 if (d->trace) {
10055 fprintf(d->trace, "-- parameter %d: %g\n", si, v);
10056 fflush(d->trace);
10057 }
10058 } else {
10059 int frac;
10060
10061 frac = (int) ((TIMESTAMP_STRUCT *) dp)->fraction;
10062 frac /= 1000000;
10063 frac = frac % 1000;
10064 if (frac < 0) {
10065 frac = 0;
10066 }
10067 if (c->prec && c->prec <= 16) {
10068 sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
10069 ((TIMESTAMP_STRUCT *) dp)->year,
10070 ((TIMESTAMP_STRUCT *) dp)->month,
10071 ((TIMESTAMP_STRUCT *) dp)->day,
10072 ((TIMESTAMP_STRUCT *) dp)->hour,
10073 ((TIMESTAMP_STRUCT *) dp)->minute);
10074 } else if (c->prec && c->prec <= 19) {
10075 sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
10076 ((TIMESTAMP_STRUCT *) dp)->year,
10077 ((TIMESTAMP_STRUCT *) dp)->month,
10078 ((TIMESTAMP_STRUCT *) dp)->day,
10079 ((TIMESTAMP_STRUCT *) dp)->hour,
10080 ((TIMESTAMP_STRUCT *) dp)->minute,
10081 ((TIMESTAMP_STRUCT *) dp)->second);
10082 } else {
10083 sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
10084 ((TIMESTAMP_STRUCT *) dp)->year,
10085 ((TIMESTAMP_STRUCT *) dp)->month,
10086 ((TIMESTAMP_STRUCT *) dp)->day,
10087 ((TIMESTAMP_STRUCT *) dp)->hour,
10088 ((TIMESTAMP_STRUCT *) dp)->minute,
10089 ((TIMESTAMP_STRUCT *) dp)->second,
10090 frac);
10091 }
10092 sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
10093 if (d->trace) {
10094 fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
10095 fflush(d->trace);
10096 }
10097 }
10098 break;
10099 default:
10100 setstat(s, -1, "unsupported column type in positional update",
10101 (*s->ov3) ? "HY000" : "S1000");
10102 return SQL_ERROR;
10103 }
10104 return SQL_SUCCESS;
10105}
10106
10118static SQLRETURN
10119setposibind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
10120{
10121 DBC *d = (DBC *) s->dbc;
10122 char **data;
10123 int pos;
10124
10125 pos = s->rowprs;
10126 if (pos < 0) {
10127 setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
10128 return SQL_ERROR;
10129 }
10130 pos += rsi;
10131 data = s->rows + s->ncols + (pos * s->ncols) + i;
10132 if (*data == NULL) {
10133 sqlite3_bind_null(stmt, si);
10134 if (d->trace) {
10135 fprintf(d->trace, "-- parameter %d: NULL\n", si);
10136 fflush(d->trace);
10137 }
10138 } else {
10139 sqlite3_bind_text(stmt, si, *data, -1, SQLITE_STATIC);
10140 if (d->trace) {
10141 fprintf(d->trace, "-- parameter %d: '%s'\n", si, *data);
10142 fflush(d->trace);
10143 }
10144 }
10145 return SQL_SUCCESS;
10146}
10147
10155static SQLRETURN
10156setposrefr(STMT *s, int rsi)
10157{
10158 int i, withinfo = 0;
10159 SQLRETURN ret = SQL_SUCCESS;
10160
10161 for (i = 0; s->bindcols && i < s->ncols; i++) {
10162 BINDCOL *b = &s->bindcols[i];
10163 SQLPOINTER dp = 0;
10164 SQLLEN *lp = 0;
10165
10166 b->offs = 0;
10167 if (b->valp) {
10168 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10169 dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
10170 } else {
10171 dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
10172 }
10173 if (s->bind_offs) {
10174 dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
10175 }
10176 }
10177 if (b->lenp) {
10178 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10179 lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
10180 } else {
10181 lp = b->lenp + rsi;
10182 }
10183 if (s->bind_offs) {
10184 lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
10185 }
10186 }
10187 if (dp || lp) {
10188 int rowp = s->rowp;
10189
10190 s->rowp = s->rowprs + rsi;
10191 ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp,
10192 b->max, lp, 0);
10193 s->rowp = rowp;
10194 if (!SQL_SUCCEEDED(ret)) {
10195 s->row_status0[rsi] = SQL_ROW_ERROR;
10196 break;
10197 }
10198 if (ret != SQL_SUCCESS) {
10199 withinfo = 1;
10200#ifdef SQL_ROW_SUCCESS_WITH_INFO
10201 s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
10202#endif
10203 }
10204 }
10205 }
10206 if (SQL_SUCCEEDED(ret)) {
10207 ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
10208 }
10209 return ret;
10210}
10211
10221static SQLRETURN
10222drvsetpos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10223{
10224 STMT *s = (STMT *) stmt;
10225 DBC *d = (DBC *) s->dbc;
10226 int rowp, i, k, rc, nretry = 0;
10227 dstr *sql = 0;
10228 const char *endp;
10229 sqlite3_stmt *s3stmt = NULL;
10230 SQLRETURN ret;
10231
10232 if (lock != SQL_LOCK_NO_CHANGE) {
10233 setstat(s, -1, "unsupported locking mode",
10234 (*s->ov3) ? "HY000" : "S1000");
10235 return SQL_ERROR;
10236 }
10237 if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10238 setstat(s, -1, "incompatible statement",
10239 (*s->ov3) ? "HY000" : "S1000");
10240 return SQL_ERROR;
10241 }
10242 if (op == SQL_ADD) {
10243 if (s->one_tbl <= 0) {
10244 setstat(s, -1, "incompatible rowset",
10245 (*s->ov3) ? "HY000" : "S1000");
10246 return SQL_ERROR;
10247 }
10248 if (row == 0 || row > s->rowset_size + 1) {
10249 goto rowoor;
10250 }
10251 ret = chkunbound(s);
10252 if (ret != SQL_SUCCESS) {
10253 return ret;
10254 }
10255 sql = dsappend(sql, "INSERT INTO ");
10256 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10257 sql = dsappendq(sql, s->dyncols[0].db);
10258 sql = dsappend(sql, ".");
10259 }
10260 sql = dsappendq(sql, s->dyncols[0].table);
10261 for (i = 0; i < s->ncols; i++) {
10262 sql = dsappend(sql, (i > 0) ? "," : "(");
10263 sql = dsappendq(sql, s->dyncols[i].column);
10264 }
10265 sql = dsappend(sql, ") VALUES ");
10266 for (i = 0; i < s->ncols; i++) {
10267 sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10268 }
10269 sql = dsappend(sql, ")");
10270 if (dserr(sql)) {
10271 dsfree(sql);
10272 return nomem(s);
10273 }
10274#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10275 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10276#else
10277 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10278#endif
10279 do {
10280 s3stmt = NULL;
10281#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10282 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10283 &s3stmt, &endp);
10284#else
10285 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10286 &s3stmt, &endp);
10287#endif
10288 if (rc != SQLITE_OK) {
10289 if (s3stmt) {
10290 sqlite3_finalize(s3stmt);
10291 s3stmt = NULL;
10292 }
10293 }
10294 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10295 dbtracerc(d, rc, NULL);
10296 dsfree(sql);
10297 if (rc != SQLITE_OK) {
10298istmterr:
10299 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10300 sqlite3_errmsg(d->sqlite), rc);
10301 if (s3stmt) {
10302 dbtraceapi(d, "sqlite3_finalize", NULL);
10303 sqlite3_finalize(s3stmt);
10304 }
10305 return SQL_ERROR;
10306 }
10307 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10308 ret = setposbind(s, s3stmt, i, k, row - 1);
10309 if (ret != SQL_SUCCESS) {
10310 dbtraceapi(d, "sqlite3_finalize", NULL);
10311 sqlite3_finalize(s3stmt);
10312 return ret;
10313 }
10314 k++;
10315 }
10316 rc = sqlite3_step(s3stmt);
10317 if (rc != SQLITE_DONE) {
10318 goto istmterr;
10319 }
10320 sqlite3_finalize(s3stmt);
10321 if (sqlite3_changes(d->sqlite) > 0 && row <= s->rowset_size) {
10322 if (s->row_status0) {
10323 s->row_status0[row - 1] = SQL_ROW_ADDED;
10324 }
10325 if (s->row_status) {
10326 s->row_status[row - 1] = SQL_ROW_ADDED;
10327 }
10328 }
10329 return SQL_SUCCESS;
10330 } else if (op == SQL_UPDATE || op == SQL_DELETE) {
10331 if (s->one_tbl <= 0 || s->has_pk <= 0) {
10332 setstat(s, -1, "incompatible rowset",
10333 (*s->ov3) ? "HY000" : "S1000");
10334 return SQL_ERROR;
10335 }
10336 if (row == 0) {
10337 ret = SQL_SUCCESS;
10338 for (i = 1; i <= s->rowset_size; i++) {
10339 ret = drvsetpos(stmt, i, op, lock);
10340 if (!SQL_SUCCEEDED(ret)) {
10341 break;
10342 }
10343 }
10344 return ret;
10345 }
10346 if (row > s->rowset_size) {
10347 goto rowoor;
10348 }
10349 }
10350 if (op != SQL_POSITION && op != SQL_REFRESH &&
10351 op != SQL_DELETE && op != SQL_UPDATE) {
10352 return drvunimplstmt(stmt);
10353 }
10354 if (op == SQL_POSITION) {
10355 rowp = s->rowp + row - 1;
10356 if (!s->rows || row == 0 || rowp < -1 || rowp >= s->nrows) {
10357rowoor:
10358 setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
10359 return SQL_ERROR;
10360 }
10361 s->rowp = rowp;
10362 } else if (op == SQL_REFRESH) {
10363 if (row > s->rowset_size) {
10364 goto rowoor;
10365 }
10366 if (row == 0) {
10367 ret = SQL_SUCCESS;
10368 for (i = 0; i < s->rowset_size; i++) {
10369 ret = setposrefr(s, i);
10370 if (!SQL_SUCCEEDED(ret)) {
10371 break;
10372 }
10373 }
10374 return ret;
10375 }
10376 return setposrefr(s, row - 1);
10377 } else if (op == SQL_DELETE) {
10378 sql = dsappend(sql, "DELETE FROM ");
10379 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10380 sql = dsappendq(sql, s->dyncols[0].db);
10381 sql = dsappend(sql, ".");
10382 }
10383 sql = dsappendq(sql, s->dyncols[0].table);
10384 for (i = k = 0; i < s->ncols; i++) {
10385 if (s->dyncols[i].ispk <= 0) {
10386 continue;
10387 }
10388 sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10389 sql = dsappendq(sql, s->dyncols[i].column);
10390 sql = dsappend(sql, " = ?");
10391 k++;
10392 }
10393 if (dserr(sql)) {
10394 dsfree(sql);
10395 return nomem(s);
10396 }
10397#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10398 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10399#else
10400 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10401#endif
10402 do {
10403 s3stmt = NULL;
10404#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10405 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10406 &s3stmt, &endp);
10407#else
10408 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10409 &s3stmt, &endp);
10410#endif
10411 if (rc != SQLITE_OK) {
10412 if (s3stmt) {
10413 sqlite3_finalize(s3stmt);
10414 s3stmt = NULL;
10415 }
10416 }
10417 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10418 dbtracerc(d, rc, NULL);
10419 dsfree(sql);
10420 if (rc != SQLITE_OK) {
10421dstmterr:
10422 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10423 sqlite3_errmsg(d->sqlite), rc);
10424 if (s3stmt) {
10425 dbtraceapi(d, "sqlite3_finalize", NULL);
10426 sqlite3_finalize(s3stmt);
10427 }
10428 return SQL_ERROR;
10429 }
10430 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10431 if (s->dyncols[i].ispk <= 0) {
10432 continue;
10433 }
10434 ret = setposibind(s, s3stmt, i, k, row - 1);
10435 if (ret != SQL_SUCCESS) {
10436 dbtraceapi(d, "sqlite3_finalize", NULL);
10437 sqlite3_finalize(s3stmt);
10438 return ret;
10439 }
10440 k++;
10441 }
10442 rc = sqlite3_step(s3stmt);
10443 if (rc != SQLITE_DONE) {
10444 goto dstmterr;
10445 }
10446 sqlite3_finalize(s3stmt);
10447 if (sqlite3_changes(d->sqlite) > 0) {
10448 if (s->row_status0) {
10449 s->row_status0[row - 1] = SQL_ROW_DELETED;
10450 }
10451 if (s->row_status) {
10452 s->row_status[row - 1] = SQL_ROW_DELETED;
10453 }
10454 }
10455 return SQL_SUCCESS;
10456 } else if (op == SQL_UPDATE) {
10457 ret = chkunbound(s);
10458 if (ret != SQL_SUCCESS) {
10459 return ret;
10460 }
10461 sql = dsappend(sql, "UPDATE ");
10462 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10463 sql = dsappendq(sql, s->dyncols[0].db);
10464 sql = dsappend(sql, ".");
10465 }
10466 sql = dsappendq(sql, s->dyncols[0].table);
10467 for (i = 0; i < s->ncols; i++) {
10468 sql = dsappend(sql, (i > 0) ? ", " : " SET ");
10469 sql = dsappendq(sql, s->dyncols[i].column);
10470 sql = dsappend(sql, " = ?");
10471 }
10472 for (i = k = 0; i < s->ncols; i++) {
10473 if (s->dyncols[i].ispk <= 0) {
10474 continue;
10475 }
10476 sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10477 sql = dsappendq(sql, s->dyncols[i].column);
10478 sql = dsappend(sql, " = ?");
10479 k++;
10480 }
10481 if (dserr(sql)) {
10482 dsfree(sql);
10483 return nomem(s);
10484 }
10485#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10486 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10487#else
10488 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10489#endif
10490 do {
10491 s3stmt = NULL;
10492#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10493 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10494 &s3stmt, &endp);
10495#else
10496 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10497 &s3stmt, &endp);
10498#endif
10499 if (rc != SQLITE_OK) {
10500 if (s3stmt) {
10501 sqlite3_finalize(s3stmt);
10502 s3stmt = NULL;
10503 }
10504 }
10505 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10506 dbtracerc(d, rc, NULL);
10507 dsfree(sql);
10508 if (rc != SQLITE_OK) {
10509ustmterr:
10510 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10511 sqlite3_errmsg(d->sqlite), rc);
10512 if (s3stmt) {
10513 dbtraceapi(d, "sqlite3_finalize", NULL);
10514 sqlite3_finalize(s3stmt);
10515 }
10516 return SQL_ERROR;
10517 }
10518 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10519 ret = setposbind(s, s3stmt, i, k, row - 1);
10520 if (ret != SQL_SUCCESS) {
10521 dbtraceapi(d, "sqlite3_finalize", NULL);
10522 sqlite3_finalize(s3stmt);
10523 return ret;
10524 }
10525 k++;
10526 }
10527 for (i = 0; s->bindcols && i < s->ncols; i++) {
10528 if (s->dyncols[i].ispk <= 0) {
10529 continue;
10530 }
10531 ret = setposibind(s, s3stmt, i, k, row - 1);
10532 if (ret != SQL_SUCCESS) {
10533 dbtraceapi(d, "sqlite3_finalize", NULL);
10534 sqlite3_finalize(s3stmt);
10535 return ret;
10536 }
10537 k++;
10538 }
10539 rc = sqlite3_step(s3stmt);
10540 if (rc != SQLITE_DONE) {
10541 goto ustmterr;
10542 }
10543 sqlite3_finalize(s3stmt);
10544 if (sqlite3_changes(d->sqlite) > 0) {
10545 if (s->row_status0) {
10546 s->row_status0[row - 1] = SQL_ROW_UPDATED;
10547 }
10548 if (s->row_status) {
10549 s->row_status[row - 1] = SQL_ROW_UPDATED;
10550 }
10551 }
10552 return SQL_SUCCESS;
10553 }
10554 return SQL_SUCCESS;
10555}
10556
10566SQLRETURN SQL_API
10567SQLSetPos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10568{
10569 SQLRETURN ret;
10570
10572 ret = drvsetpos(stmt, row, op, lock);
10574 return ret;
10575}
10576
10584static SQLRETURN
10585drvbulkoperations(SQLHSTMT stmt, SQLSMALLINT op)
10586{
10587 STMT *s = (STMT *) stmt;
10588 DBC *d = (DBC *) s->dbc;
10589 int row, i, k, rc, nretry = 0;
10590 dstr *sql = 0;
10591 const char *endp;
10592 sqlite3_stmt *s3stmt = NULL;
10593 SQLRETURN ret;
10594
10595 if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10596 setstat(s, -1, "incompatible statement",
10597 (*s->ov3) ? "HY000" : "S1000");
10598 return SQL_ERROR;
10599 }
10600 if (op == SQL_ADD) {
10601 if (s->one_tbl <= 0) {
10602 setstat(s, -1, "incompatible rowset",
10603 (*s->ov3) ? "HY000" : "S1000");
10604 return SQL_ERROR;
10605 }
10606 ret = chkunbound(s);
10607 if (ret != SQL_SUCCESS) {
10608 return ret;
10609 }
10610 sql = dsappend(sql, "INSERT INTO ");
10611 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10612 sql = dsappendq(sql, s->dyncols[0].db);
10613 sql = dsappend(sql, ".");
10614 }
10615 sql = dsappendq(sql, s->dyncols[0].table);
10616 for (i = 0; i < s->ncols; i++) {
10617 sql = dsappend(sql, (i > 0) ? "," : "(");
10618 sql = dsappendq(sql, s->dyncols[i].column);
10619 }
10620 sql = dsappend(sql, ") VALUES ");
10621 for (i = 0; i < s->ncols; i++) {
10622 sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10623 }
10624 sql = dsappend(sql, ")");
10625 if (dserr(sql)) {
10626 dsfree(sql);
10627 return nomem(s);
10628 }
10629#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10630 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10631#else
10632 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10633#endif
10634 do {
10635 s3stmt = NULL;
10636#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10637 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10638 &s3stmt, &endp);
10639#else
10640 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10641 &s3stmt, &endp);
10642#endif
10643 if (rc != SQLITE_OK) {
10644 if (s3stmt) {
10645 sqlite3_finalize(s3stmt);
10646 s3stmt = NULL;
10647 }
10648 }
10649 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10650 dbtracerc(d, rc, NULL);
10651 dsfree(sql);
10652 if (rc != SQLITE_OK) {
10653 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10654 sqlite3_errmsg(d->sqlite), rc);
10655 if (s3stmt) {
10656 dbtraceapi(d, "sqlite3_finalize", NULL);
10657 sqlite3_finalize(s3stmt);
10658 }
10659 return SQL_ERROR;
10660 }
10661 for (row = 0; row < s->rowset_size; row++) {
10662 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10663 ret = setposbind(s, s3stmt, i, k, row);
10664 if (ret != SQL_SUCCESS) {
10665istmterr:
10666 if (s->row_status0) {
10667 s->row_status0[row] = SQL_ROW_ERROR;
10668 }
10669 if (s->row_status) {
10670 s->row_status[row] = SQL_ROW_ERROR;
10671 }
10672 dbtraceapi(d, "sqlite3_finalize", NULL);
10673 sqlite3_finalize(s3stmt);
10674 return ret;
10675 }
10676 k++;
10677 }
10678 rc = sqlite3_step(s3stmt);
10679 if (rc != SQLITE_DONE) {
10680 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10681 sqlite3_errmsg(d->sqlite), rc);
10682 ret = SQL_ERROR;
10683 goto istmterr;
10684 }
10685 if (sqlite3_changes(d->sqlite) > 0) {
10686 if (s->row_status0) {
10687 s->row_status0[row] = SQL_ROW_ADDED;
10688 }
10689 if (s->row_status) {
10690 s->row_status[row] = SQL_ROW_ADDED;
10691 }
10692 }
10693 if (s->bkmrk == SQL_UB_VARIABLE &&
10694 s->bkmrkcol.type == SQL_C_VARBOOKMARK &&
10695 s->bkmrkcol.valp) {
10696 SQLPOINTER *val;
10697
10698 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10699 val = (SQLPOINTER)
10700 ((char *) s->bkmrkcol.valp + s->bind_type * row);
10701 } else {
10702 val = (SQLPOINTER)
10703 ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10704 }
10705 if (s->bind_offs) {
10706 val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10707 }
10708 *(sqlite_int64 *) val = sqlite3_last_insert_rowid(d->sqlite);
10709 if (s->bkmrkcol.lenp) {
10710 SQLLEN *ival;
10711
10712 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10713 ival = (SQLLEN *)
10714 ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10715 } else {
10716 ival = &s->bkmrkcol.lenp[row];
10717 }
10718 if (s->bind_offs) {
10719 ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10720 }
10721 *ival = sizeof (sqlite_int64);
10722 }
10723 }
10724 dbtraceapi(d, "sqlite3_reset", NULL);
10725 sqlite3_reset(s3stmt);
10726 }
10727 dbtraceapi(d, "sqlite3_finalize", NULL);
10728 sqlite3_finalize(s3stmt);
10729 return SQL_SUCCESS;
10730 } else if (op == SQL_DELETE_BY_BOOKMARK) {
10731 if (s->has_rowid < 0 ||
10732 s->bkmrk != SQL_UB_VARIABLE ||
10733 s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10734 !s->bkmrkcol.valp) {
10735 setstat(s, -1, "incompatible rowset",
10736 (*s->ov3) ? "HY000" : "S1000");
10737 return SQL_ERROR;
10738 }
10739 sql = dsappend(sql, "DELETE FROM ");
10740 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10741 sql = dsappendq(sql, s->dyncols[0].db);
10742 sql = dsappend(sql, ".");
10743 }
10744 sql = dsappendq(sql, s->dyncols[0].table);
10745 sql = dsappend(sql, " WHERE ");
10746 sql = dsappendq(sql, s->dyncols[0].column);
10747 sql = dsappend(sql, " = ?");
10748 if (dserr(sql)) {
10749 dsfree(sql);
10750 return nomem(s);
10751 }
10752#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10753 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10754#else
10755 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10756#endif
10757 do {
10758 s3stmt = NULL;
10759#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10760 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10761 &s3stmt, &endp);
10762#else
10763 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10764 &s3stmt, &endp);
10765#endif
10766 if (rc != SQLITE_OK) {
10767 if (s3stmt) {
10768 sqlite3_finalize(s3stmt);
10769 s3stmt = NULL;
10770 }
10771 }
10772 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10773 dbtracerc(d, rc, NULL);
10774 dsfree(sql);
10775 if (rc != SQLITE_OK) {
10776 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10777 sqlite3_errmsg(d->sqlite), rc);
10778 if (s3stmt) {
10779 dbtraceapi(d, "sqlite3_finalize", NULL);
10780 sqlite3_finalize(s3stmt);
10781 }
10782 return SQL_ERROR;
10783 }
10784 for (row = 0; row < s->rowset_size; row++) {
10785 SQLPOINTER *val;
10786 sqlite_int64 rowid;
10787
10788 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10789 val = (SQLPOINTER)
10790 ((char *) s->bkmrkcol.valp + s->bind_type * row);
10791 } else {
10792 val = (SQLPOINTER)
10793 ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10794 }
10795 if (s->bind_offs) {
10796 val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10797 }
10798 if (s->bkmrkcol.lenp) {
10799 SQLLEN *ival;
10800
10801 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10802 ival = (SQLLEN *)
10803 ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10804 } else {
10805 ival = &s->bkmrkcol.lenp[row];
10806 }
10807 if (s->bind_offs) {
10808 ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10809 }
10810 if (*ival != sizeof (sqlite_int64)) {
10811 continue;
10812 }
10813 }
10814 rowid = *(sqlite_int64 *) val;
10815 sqlite3_bind_int64(s3stmt, 1, rowid);
10816 if (d->trace) {
10817 fprintf(d->trace,
10818#ifdef _WIN32
10819 "-- parameter 1: %I64d\n",
10820#else
10821 "-- parameter 1: %lld\n",
10822#endif
10823 rowid);
10824 fflush(d->trace);
10825 }
10826 rc = sqlite3_step(s3stmt);
10827 if (rc != SQLITE_DONE) {
10828 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10829 sqlite3_errmsg(d->sqlite), rc);
10830 if (s->row_status0) {
10831 s->row_status0[row] = SQL_ROW_ERROR;
10832 }
10833 if (s->row_status) {
10834 s->row_status[row] = SQL_ROW_ERROR;
10835 }
10836 dbtraceapi(d, "sqlite3_finalize", NULL);
10837 sqlite3_finalize(s3stmt);
10838 return SQL_ERROR;
10839 }
10840 if (sqlite3_changes(d->sqlite) > 0) {
10841 if (s->row_status0) {
10842 s->row_status0[row] = SQL_ROW_DELETED;
10843 }
10844 if (s->row_status) {
10845 s->row_status[row] = SQL_ROW_DELETED;
10846 }
10847 }
10848 dbtraceapi(d, "sqlite3_reset", NULL);
10849 sqlite3_reset(s3stmt);
10850 }
10851 dbtraceapi(d, "sqlite3_finalize", NULL);
10852 sqlite3_finalize(s3stmt);
10853 return SQL_SUCCESS;
10854 } else if (op == SQL_UPDATE_BY_BOOKMARK) {
10855 if (s->has_rowid < 0 ||
10856 s->bkmrk != SQL_UB_VARIABLE ||
10857 s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10858 !s->bkmrkcol.valp) {
10859 setstat(s, -1, "incompatible rowset",
10860 (*s->ov3) ? "HY000" : "S1000");
10861 return SQL_ERROR;
10862 }
10863 ret = chkunbound(s);
10864 if (ret != SQL_SUCCESS) {
10865 return ret;
10866 }
10867 sql = dsappend(sql, "UPDATE ");
10868 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10869 sql = dsappendq(sql, s->dyncols[0].db);
10870 sql = dsappend(sql, ".");
10871 }
10872 sql = dsappendq(sql, s->dyncols[0].table);
10873 for (i = 0, k = 0; i < s->ncols; i++) {
10874 sql = dsappend(sql, (k > 0) ? ", " : " SET ");
10875 sql = dsappendq(sql, s->dyncols[i].column);
10876 sql = dsappend(sql, " = ?");
10877 k++;
10878 }
10879 sql = dsappend(sql, " WHERE ");
10880 sql = dsappendq(sql, s->dyncols[s->has_rowid].column);
10881 sql = dsappend(sql, " = ?");
10882 if (dserr(sql)) {
10883 dsfree(sql);
10884 return nomem(s);
10885 }
10886#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10887 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10888#else
10889 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10890#endif
10891 do {
10892 s3stmt = NULL;
10893#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10894 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10895 &s3stmt, &endp);
10896#else
10897 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10898 &s3stmt, &endp);
10899#endif
10900 if (rc != SQLITE_OK) {
10901 if (s3stmt) {
10902 sqlite3_finalize(s3stmt);
10903 s3stmt = NULL;
10904 }
10905 }
10906 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10907 dbtracerc(d, rc, NULL);
10908 dsfree(sql);
10909 if (rc != SQLITE_OK) {
10910 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10911 sqlite3_errmsg(d->sqlite), rc);
10912 if (s3stmt) {
10913 dbtraceapi(d, "sqlite3_finalize", NULL);
10914 sqlite3_finalize(s3stmt);
10915 }
10916 return SQL_ERROR;
10917 }
10918 for (row = 0; row < s->rowset_size; row++) {
10919 SQLPOINTER *val;
10920 sqlite_int64 rowid;
10921
10922 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10923 val = (SQLPOINTER)
10924 ((char *) s->bkmrkcol.valp + s->bind_type * row);
10925 } else {
10926 val = (SQLPOINTER)
10927 ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10928 }
10929 if (s->bind_offs) {
10930 val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10931 }
10932 if (s->bkmrkcol.lenp) {
10933 SQLLEN *ival;
10934
10935 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10936 ival = (SQLLEN *)
10937 ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10938 } else {
10939 ival = &s->bkmrkcol.lenp[row];
10940 }
10941 if (s->bind_offs) {
10942 ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10943 }
10944 if (*ival != sizeof (sqlite_int64)) {
10945 continue;
10946 }
10947 }
10948 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10949 ret = setposbind(s, s3stmt, i, k, row);
10950 if (ret != SQL_SUCCESS) {
10951ustmterr:
10952 if (s->row_status0) {
10953 s->row_status0[row] = SQL_ROW_ERROR;
10954 }
10955 if (s->row_status) {
10956 s->row_status[row] = SQL_ROW_ERROR;
10957 }
10958 dbtraceapi(d, "sqlite3_finalize", NULL);
10959 sqlite3_finalize(s3stmt);
10960 return ret;
10961 }
10962 k++;
10963 }
10964 rowid = *(sqlite_int64 *) val;
10965 sqlite3_bind_int64(s3stmt, k, rowid);
10966 if (d->trace) {
10967 fprintf(d->trace,
10968#ifdef _WIN32
10969 "-- parameter %d: %I64d\n",
10970#else
10971 "-- parameter %d: %lld\n",
10972#endif
10973 k, rowid);
10974 fflush(d->trace);
10975 }
10976 rc = sqlite3_step(s3stmt);
10977 if (rc != SQLITE_DONE) {
10978 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10979 sqlite3_errmsg(d->sqlite), rc);
10980 ret = SQL_ERROR;
10981 goto ustmterr;
10982 }
10983 if (sqlite3_changes(d->sqlite) > 0) {
10984 if (s->row_status0) {
10985 s->row_status0[row] = SQL_ROW_UPDATED;
10986 }
10987 if (s->row_status) {
10988 s->row_status[row] = SQL_ROW_UPDATED;
10989 }
10990 }
10991 dbtraceapi(d, "sqlite3_reset", NULL);
10992 sqlite3_reset(s3stmt);
10993 }
10994 dbtraceapi(d, "sqlite3_finalize", NULL);
10995 sqlite3_finalize(s3stmt);
10996 return SQL_SUCCESS;
10997 }
10998 setstat(s, -1, "unsupported operation", (*s->ov3) ? "HY000" : "S1000");
10999 return SQL_ERROR;
11000}
11001
11009SQLRETURN SQL_API
11010SQLBulkOperations(SQLHSTMT stmt, SQLSMALLINT oper)
11011{
11012 SQLRETURN ret;
11013
11015 ret = drvbulkoperations(stmt, oper);
11017 return ret;
11018}
11019
11020
11025SQLRETURN SQL_API
11026SQLSetScrollOptions(SQLHSTMT stmt, SQLUSMALLINT concur, SQLLEN rowkeyset,
11027 SQLUSMALLINT rowset)
11028{
11029 SQLRETURN ret;
11030
11032 ret = drvunimplstmt(stmt);
11034 return ret;
11035}
11036
11037#define strmak(dst, src, max, lenp) { \
11038 int len = strlen(src); \
11039 int cnt = min(len + 1, max); \
11040 strncpy(dst, src, cnt); \
11041 *lenp = (cnt > len) ? len : cnt; \
11042}
11043
11054static SQLRETURN
11055drvgetinfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11056 SQLSMALLINT *valLen)
11057{
11058 DBC *d;
11059 char dummyc[301];
11060 SQLSMALLINT dummy;
11061#if defined(_WIN32) || defined(_WIN64)
11062 char pathbuf[301], *drvname;
11063#else
11064 static char drvname[] = "sqlite3odbc.so";
11065#endif
11066
11067 if (dbc == SQL_NULL_HDBC) {
11068 return SQL_INVALID_HANDLE;
11069 }
11070 d = (DBC *) dbc;
11071 if (valMax) {
11072 valMax--;
11073 }
11074 if (!valLen) {
11075 valLen = &dummy;
11076 }
11077 if (!val) {
11078 val = dummyc;
11079 valMax = sizeof (dummyc) - 1;
11080 }
11081 switch (type) {
11082 case SQL_MAX_USER_NAME_LEN:
11083 *((SQLSMALLINT *) val) = 16;
11084 *valLen = sizeof (SQLSMALLINT);
11085 break;
11086 case SQL_USER_NAME:
11087 strmak(val, "", valMax, valLen);
11088 break;
11089 case SQL_DRIVER_ODBC_VER:
11090#if 0
11091 strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
11092#else
11093 strmak(val, "03.00", valMax, valLen);
11094#endif
11095 break;
11096 case SQL_ACTIVE_CONNECTIONS:
11097 case SQL_ACTIVE_STATEMENTS:
11098 *((SQLSMALLINT *) val) = 0;
11099 *valLen = sizeof (SQLSMALLINT);
11100 break;
11101#ifdef SQL_ASYNC_MODE
11102 case SQL_ASYNC_MODE:
11103 *((SQLUINTEGER *) val) = SQL_AM_NONE;
11104 *valLen = sizeof (SQLUINTEGER);
11105 break;
11106#endif
11107#ifdef SQL_CREATE_TABLE
11108 case SQL_CREATE_TABLE:
11109 *((SQLUINTEGER *) val) = SQL_CT_CREATE_TABLE |
11110 SQL_CT_COLUMN_DEFAULT |
11111 SQL_CT_COLUMN_CONSTRAINT |
11112 SQL_CT_CONSTRAINT_NON_DEFERRABLE;
11113 *valLen = sizeof (SQLUINTEGER);
11114 break;
11115#endif
11116#ifdef SQL_CREATE_VIEW
11117 case SQL_CREATE_VIEW:
11118 *((SQLUINTEGER *) val) = SQL_CV_CREATE_VIEW;
11119 *valLen = sizeof (SQLUINTEGER);
11120 break;
11121#endif
11122#ifdef SQL_DDL_INDEX
11123 case SQL_DDL_INDEX:
11124 *((SQLUINTEGER *) val) = SQL_DI_CREATE_INDEX | SQL_DI_DROP_INDEX;
11125 *valLen = sizeof (SQLUINTEGER);
11126 break;
11127#endif
11128#ifdef SQL_DROP_TABLE
11129 case SQL_DROP_TABLE:
11130 *((SQLUINTEGER *) val) = SQL_DT_DROP_TABLE;
11131 *valLen = sizeof (SQLUINTEGER);
11132 break;
11133#endif
11134#ifdef SQL_DROP_VIEW
11135 case SQL_DROP_VIEW:
11136 *((SQLUINTEGER *) val) = SQL_DV_DROP_VIEW;
11137 *valLen = sizeof (SQLUINTEGER);
11138 break;
11139#endif
11140#ifdef SQL_INDEX_KEYWORDS
11141 case SQL_INDEX_KEYWORDS:
11142 *((SQLUINTEGER *) val) = SQL_IK_ALL;
11143 *valLen = sizeof (SQLUINTEGER);
11144 break;
11145#endif
11146 case SQL_DATA_SOURCE_NAME:
11147 strmak(val, d->dsn ? d->dsn : "", valMax, valLen);
11148 break;
11149 case SQL_DRIVER_NAME:
11150#if defined(_WIN32) || defined(_WIN64)
11151 GetModuleFileName(hModule, pathbuf, sizeof (pathbuf));
11152 drvname = strrchr(pathbuf, '\\');
11153 if (drvname == NULL) {
11154 drvname = strrchr(pathbuf, '/');
11155 }
11156 if (drvname == NULL) {
11157 drvname = pathbuf;
11158 } else {
11159 drvname++;
11160 }
11161#endif
11162 strmak(val, drvname, valMax, valLen);
11163 break;
11164 case SQL_DRIVER_VER:
11165 strmak(val, DRIVER_VER_INFO, valMax, valLen);
11166 break;
11167 case SQL_FETCH_DIRECTION:
11168 *((SQLUINTEGER *) val) = SQL_FD_FETCH_NEXT | SQL_FD_FETCH_FIRST |
11169 SQL_FD_FETCH_LAST | SQL_FD_FETCH_PRIOR | SQL_FD_FETCH_ABSOLUTE;
11170 *valLen = sizeof (SQLUINTEGER);
11171 break;
11172 case SQL_ODBC_VER:
11173 strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
11174 break;
11175 case SQL_ODBC_SAG_CLI_CONFORMANCE:
11176 *((SQLSMALLINT *) val) = SQL_OSCC_NOT_COMPLIANT;
11177 *valLen = sizeof (SQLSMALLINT);
11178 break;
11179 case SQL_STANDARD_CLI_CONFORMANCE:
11180 *((SQLUINTEGER *) val) = SQL_SCC_XOPEN_CLI_VERSION1;
11181 *valLen = sizeof (SQLUINTEGER);
11182 break;
11183 case SQL_SQL_CONFORMANCE:
11184 *((SQLUINTEGER *) val) = SQL_SC_SQL92_ENTRY;
11185 *valLen = sizeof (SQLUINTEGER);
11186 break;
11187 case SQL_SERVER_NAME:
11188 case SQL_DATABASE_NAME:
11189 strmak(val, d->dbname ? d->dbname : "", valMax, valLen);
11190 break;
11191 case SQL_SEARCH_PATTERN_ESCAPE:
11192 strmak(val, "\\", valMax, valLen);
11193 break;
11194 case SQL_ODBC_SQL_CONFORMANCE:
11195 *((SQLSMALLINT *) val) = SQL_OSC_MINIMUM;
11196 *valLen = sizeof (SQLSMALLINT);
11197 break;
11198 case SQL_ODBC_API_CONFORMANCE:
11199 *((SQLSMALLINT *) val) = SQL_OAC_LEVEL1;
11200 *valLen = sizeof (SQLSMALLINT);
11201 break;
11202 case SQL_DBMS_NAME:
11203 strmak(val, "SQLite", valMax, valLen);
11204 break;
11205 case SQL_DBMS_VER:
11206 strmak(val, SQLITE_VERSION, valMax, valLen);
11207 break;
11208 case SQL_COLUMN_ALIAS:
11209 case SQL_NEED_LONG_DATA_LEN:
11210 case SQL_OUTER_JOINS:
11211 strmak(val, "Y", valMax, valLen);
11212 break;
11213 case SQL_ROW_UPDATES:
11214 case SQL_ACCESSIBLE_PROCEDURES:
11215 case SQL_PROCEDURES:
11216 case SQL_EXPRESSIONS_IN_ORDERBY:
11217 case SQL_ODBC_SQL_OPT_IEF:
11218 case SQL_LIKE_ESCAPE_CLAUSE:
11219 case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11220 case SQL_ACCESSIBLE_TABLES:
11221 case SQL_MULT_RESULT_SETS:
11222 case SQL_MULTIPLE_ACTIVE_TXN:
11223 case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11224 strmak(val, "N", valMax, valLen);
11225 break;
11226#ifdef SQL_CATALOG_NAME
11227 case SQL_CATALOG_NAME:
11228#if defined(_WIN32) || defined(_WIN64)
11229 strmak(val, d->xcelqrx ? "Y" : "N", valMax, valLen);
11230#else
11231 strmak(val, "N", valMax, valLen);
11232#endif
11233 break;
11234#endif
11235 case SQL_DATA_SOURCE_READ_ONLY:
11236 strmak(val, "N", valMax, valLen);
11237 break;
11238#ifdef SQL_OJ_CAPABILITIES
11239 case SQL_OJ_CAPABILITIES:
11240 *((SQLUINTEGER *) val) = SQL_OJ_LEFT;
11241 *valLen = sizeof (SQLUINTEGER);
11242 break;
11243#endif
11244#ifdef SQL_MAX_IDENTIFIER_LEN
11245 case SQL_MAX_IDENTIFIER_LEN:
11246 *((SQLUSMALLINT *) val) = 255;
11247 *valLen = sizeof (SQLUSMALLINT);
11248 break;
11249#endif
11250 case SQL_CONCAT_NULL_BEHAVIOR:
11251 *((SQLSMALLINT *) val) = SQL_CB_NULL;
11252 *valLen = sizeof (SQLSMALLINT);
11253 break;
11254 case SQL_CURSOR_COMMIT_BEHAVIOR:
11255 case SQL_CURSOR_ROLLBACK_BEHAVIOR:
11256 *((SQLSMALLINT *) val) = SQL_CB_PRESERVE;
11257 *valLen = sizeof (SQLSMALLINT);
11258 break;
11259#ifdef SQL_CURSOR_SENSITIVITY
11260 case SQL_CURSOR_SENSITIVITY:
11261 *((SQLUINTEGER *) val) = SQL_UNSPECIFIED;
11262 *valLen = sizeof (SQLUINTEGER);
11263 break;
11264#endif
11265 case SQL_DEFAULT_TXN_ISOLATION:
11266 *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11267 *valLen = sizeof (SQLUINTEGER);
11268 break;
11269#ifdef SQL_DESCRIBE_PARAMETER
11270 case SQL_DESCRIBE_PARAMETER:
11271 strmak(val, "Y", valMax, valLen);
11272 break;
11273#endif
11274 case SQL_TXN_ISOLATION_OPTION:
11275 *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11276 *valLen = sizeof (SQLUINTEGER);
11277 break;
11278 case SQL_IDENTIFIER_CASE:
11279 *((SQLSMALLINT *) val) = SQL_IC_SENSITIVE;
11280 *valLen = sizeof (SQLSMALLINT);
11281 break;
11282 case SQL_IDENTIFIER_QUOTE_CHAR:
11283 strmak(val, "\"", valMax, valLen);
11284 break;
11285 case SQL_MAX_TABLE_NAME_LEN:
11286 case SQL_MAX_COLUMN_NAME_LEN:
11287 *((SQLSMALLINT *) val) = 255;
11288 *valLen = sizeof (SQLSMALLINT);
11289 break;
11290 case SQL_MAX_CURSOR_NAME_LEN:
11291 *((SQLSMALLINT *) val) = 255;
11292 *valLen = sizeof (SQLSMALLINT);
11293 break;
11294 case SQL_MAX_PROCEDURE_NAME_LEN:
11295 *((SQLSMALLINT *) val) = 0;
11296 break;
11297 case SQL_MAX_QUALIFIER_NAME_LEN:
11298 case SQL_MAX_OWNER_NAME_LEN:
11299 *((SQLSMALLINT *) val) = 255;
11300 break;
11301 case SQL_OWNER_TERM:
11302 strmak(val, "", valMax, valLen);
11303 break;
11304 case SQL_PROCEDURE_TERM:
11305 strmak(val, "PROCEDURE", valMax, valLen);
11306 break;
11307 case SQL_QUALIFIER_NAME_SEPARATOR:
11308 strmak(val, ".", valMax, valLen);
11309 break;
11310 case SQL_QUALIFIER_TERM:
11311#if defined(_WIN32) || defined(_WIN64)
11312 strmak(val, d->xcelqrx ? "catalog" : "", valMax, valLen);
11313#else
11314 strmak(val, "", valMax, valLen);
11315#endif
11316 break;
11317 case SQL_QUALIFIER_USAGE:
11318#if defined(_WIN32) || defined(_WIN64)
11319 *((SQLUINTEGER *) val) = d->xcelqrx ?
11320 (SQL_CU_DML_STATEMENTS | SQL_CU_INDEX_DEFINITION |
11321 SQL_CU_TABLE_DEFINITION) : 0;
11322#else
11323 *((SQLUINTEGER *) val) = 0;
11324#endif
11325 *valLen = sizeof (SQLUINTEGER);
11326 break;
11327 case SQL_SCROLL_CONCURRENCY:
11328 *((SQLUINTEGER *) val) = SQL_SCCO_LOCK;
11329 *valLen = sizeof (SQLUINTEGER);
11330 break;
11331 case SQL_SCROLL_OPTIONS:
11332 *((SQLUINTEGER *) val) = SQL_SO_STATIC | SQL_SO_FORWARD_ONLY;
11333 *valLen = sizeof (SQLUINTEGER);
11334 break;
11335 case SQL_TABLE_TERM:
11336 strmak(val, "TABLE", valMax, valLen);
11337 break;
11338 case SQL_TXN_CAPABLE:
11339 *((SQLSMALLINT *) val) = SQL_TC_ALL;
11340 *valLen = sizeof (SQLSMALLINT);
11341 break;
11342 case SQL_CONVERT_FUNCTIONS:
11343 *((SQLUINTEGER *) val) = 0;
11344 *valLen = sizeof (SQLUINTEGER);
11345 break;
11346 case SQL_SYSTEM_FUNCTIONS:
11347 case SQL_NUMERIC_FUNCTIONS:
11348 case SQL_STRING_FUNCTIONS:
11349 case SQL_TIMEDATE_FUNCTIONS:
11350 *((SQLUINTEGER *) val) = 0;
11351 *valLen = sizeof (SQLUINTEGER);
11352 break;
11353 case SQL_CONVERT_BIGINT:
11354 case SQL_CONVERT_BIT:
11355 case SQL_CONVERT_CHAR:
11356 case SQL_CONVERT_DATE:
11357 case SQL_CONVERT_DECIMAL:
11358 case SQL_CONVERT_DOUBLE:
11359 case SQL_CONVERT_FLOAT:
11360 case SQL_CONVERT_INTEGER:
11361 case SQL_CONVERT_LONGVARCHAR:
11362 case SQL_CONVERT_NUMERIC:
11363 case SQL_CONVERT_REAL:
11364 case SQL_CONVERT_SMALLINT:
11365 case SQL_CONVERT_TIME:
11366 case SQL_CONVERT_TIMESTAMP:
11367 case SQL_CONVERT_TINYINT:
11368 case SQL_CONVERT_VARCHAR:
11369 *((SQLUINTEGER *) val) =
11370 SQL_CVT_CHAR | SQL_CVT_NUMERIC | SQL_CVT_DECIMAL |
11371 SQL_CVT_INTEGER | SQL_CVT_SMALLINT | SQL_CVT_FLOAT | SQL_CVT_REAL |
11372 SQL_CVT_DOUBLE | SQL_CVT_VARCHAR | SQL_CVT_LONGVARCHAR |
11373 SQL_CVT_BIT | SQL_CVT_TINYINT | SQL_CVT_BIGINT |
11374 SQL_CVT_DATE | SQL_CVT_TIME | SQL_CVT_TIMESTAMP;
11375 *valLen = sizeof (SQLUINTEGER);
11376 break;
11377 case SQL_CONVERT_BINARY:
11378 case SQL_CONVERT_VARBINARY:
11379 case SQL_CONVERT_LONGVARBINARY:
11380 *((SQLUINTEGER *) val) = 0;
11381 *valLen = sizeof (SQLUINTEGER);
11382 break;
11383 case SQL_POSITIONED_STATEMENTS:
11384 *((SQLUINTEGER *) val) = 0;
11385 *valLen = sizeof (SQLUINTEGER);
11386 break;
11387 case SQL_LOCK_TYPES:
11388 *((SQLUINTEGER *) val) = SQL_LCK_NO_CHANGE;
11389 *valLen = sizeof (SQLUINTEGER);
11390 break;
11391 case SQL_BOOKMARK_PERSISTENCE:
11392 *((SQLUINTEGER *) val) = SQL_BP_SCROLL;
11393 *valLen = sizeof (SQLUINTEGER);
11394 break;
11395 case SQL_UNION:
11396 *((SQLUINTEGER *) val) = SQL_U_UNION | SQL_U_UNION_ALL;
11397 *valLen = sizeof (SQLUINTEGER);
11398 break;
11399 case SQL_OWNER_USAGE:
11400 case SQL_SUBQUERIES:
11401 case SQL_TIMEDATE_ADD_INTERVALS:
11402 case SQL_TIMEDATE_DIFF_INTERVALS:
11403 *((SQLUINTEGER *) val) = 0;
11404 *valLen = sizeof (SQLUINTEGER);
11405 break;
11406 case SQL_QUOTED_IDENTIFIER_CASE:
11407 *((SQLUSMALLINT *) val) = SQL_IC_SENSITIVE;
11408 *valLen = sizeof (SQLUSMALLINT);
11409 break;
11410 case SQL_POS_OPERATIONS:
11411 *((SQLUINTEGER *) val) = SQL_POS_POSITION | SQL_POS_UPDATE |
11412 SQL_POS_DELETE | SQL_POS_ADD | SQL_POS_REFRESH;
11413 *valLen = sizeof (SQLUINTEGER);
11414 break;
11415 case SQL_ALTER_TABLE:
11416 *((SQLUINTEGER *) val) = 0;
11417 *valLen = sizeof (SQLUINTEGER);
11418 break;
11419 case SQL_CORRELATION_NAME:
11420 *((SQLSMALLINT *) val) = SQL_CN_DIFFERENT;
11421 *valLen = sizeof (SQLSMALLINT);
11422 break;
11423 case SQL_NON_NULLABLE_COLUMNS:
11424 *((SQLSMALLINT *) val) = SQL_NNC_NON_NULL;
11425 *valLen = sizeof (SQLSMALLINT);
11426 break;
11427 case SQL_NULL_COLLATION:
11428 *((SQLSMALLINT *) val) = SQL_NC_START;
11429 *valLen = sizeof (SQLSMALLINT);
11430 break;
11431 case SQL_MAX_COLUMNS_IN_GROUP_BY:
11432 case SQL_MAX_COLUMNS_IN_ORDER_BY:
11433 case SQL_MAX_COLUMNS_IN_SELECT:
11434 case SQL_MAX_COLUMNS_IN_TABLE:
11435 case SQL_MAX_ROW_SIZE:
11436 case SQL_MAX_TABLES_IN_SELECT:
11437 *((SQLSMALLINT *) val) = 0;
11438 *valLen = sizeof (SQLSMALLINT);
11439 break;
11440 case SQL_MAX_BINARY_LITERAL_LEN:
11441 case SQL_MAX_CHAR_LITERAL_LEN:
11442 *((SQLUINTEGER *) val) = 0;
11443 *valLen = sizeof (SQLUINTEGER);
11444 break;
11445 case SQL_MAX_COLUMNS_IN_INDEX:
11446 *((SQLSMALLINT *) val) = 0;
11447 *valLen = sizeof (SQLSMALLINT);
11448 break;
11449 case SQL_MAX_INDEX_SIZE:
11450 *((SQLUINTEGER *) val) = 0;
11451 *valLen = sizeof (SQLUINTEGER);
11452 break;
11453#ifdef SQL_MAX_IDENTIFIER_LENGTH
11454 case SQL_MAX_IDENTIFIER_LENGTH:
11455 *((SQLUINTEGER *) val) = 255;
11456 *valLen = sizeof (SQLUINTEGER);
11457 break;
11458#endif
11459 case SQL_MAX_STATEMENT_LEN:
11460 *((SQLUINTEGER *) val) = 16384;
11461 *valLen = sizeof (SQLUINTEGER);
11462 break;
11463 case SQL_QUALIFIER_LOCATION:
11464 *((SQLSMALLINT *) val) = SQL_QL_START;
11465 *valLen = sizeof (SQLSMALLINT);
11466 break;
11467 case SQL_GETDATA_EXTENSIONS:
11468 *((SQLUINTEGER *) val) =
11469 SQL_GD_ANY_COLUMN | SQL_GD_ANY_ORDER | SQL_GD_BOUND;
11470 *valLen = sizeof (SQLUINTEGER);
11471 break;
11472 case SQL_STATIC_SENSITIVITY:
11473 *((SQLUINTEGER *) val) = 0;
11474 *valLen = sizeof (SQLUINTEGER);
11475 break;
11476 case SQL_FILE_USAGE:
11477#if defined(_WIN32) || defined(_WIN64)
11478 *((SQLSMALLINT *) val) =
11479 d->xcelqrx ? SQL_FILE_CATALOG : SQL_FILE_NOT_SUPPORTED;
11480#else
11481 *((SQLSMALLINT *) val) = SQL_FILE_NOT_SUPPORTED;
11482#endif
11483 *valLen = sizeof (SQLSMALLINT);
11484 break;
11485 case SQL_GROUP_BY:
11486 *((SQLSMALLINT *) val) = SQL_GB_GROUP_BY_EQUALS_SELECT;
11487 *valLen = sizeof (SQLSMALLINT);
11488 break;
11489 case SQL_KEYWORDS:
11490 strmak(val, "CREATE,SELECT,DROP,DELETE,UPDATE,INSERT,"
11491 "INTO,VALUES,TABLE,INDEX,FROM,SET,WHERE,AND,CURRENT,OF",
11492 valMax, valLen);
11493 break;
11494 case SQL_SPECIAL_CHARACTERS:
11495#ifdef SQL_COLLATION_SEQ
11496 case SQL_COLLATION_SEQ:
11497#endif
11498 strmak(val, "", valMax, valLen);
11499 break;
11500 case SQL_BATCH_SUPPORT:
11501 case SQL_BATCH_ROW_COUNT:
11502 case SQL_PARAM_ARRAY_ROW_COUNTS:
11503 *((SQLUINTEGER *) val) = 0;
11504 *valLen = sizeof (SQLUINTEGER);
11505 break;
11506 case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1:
11507 *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_BOOKMARK;
11508 *valLen = sizeof (SQLUINTEGER);
11509 break;
11510 case SQL_STATIC_CURSOR_ATTRIBUTES1:
11511 *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE |
11512 SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK | SQL_CA1_POS_POSITION |
11513 SQL_CA1_POS_DELETE | SQL_CA1_POS_UPDATE | SQL_CA1_POS_REFRESH |
11514 SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_BULK_ADD |
11515 SQL_CA1_BULK_UPDATE_BY_BOOKMARK | SQL_CA1_BULK_DELETE_BY_BOOKMARK;
11516 *valLen = sizeof (SQLUINTEGER);
11517 break;
11518 case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2:
11519 case SQL_STATIC_CURSOR_ATTRIBUTES2:
11520 *((SQLUINTEGER *) val) = SQL_CA2_READ_ONLY_CONCURRENCY |
11521 SQL_CA2_LOCK_CONCURRENCY;
11522 *valLen = sizeof (SQLUINTEGER);
11523 break;
11524 case SQL_KEYSET_CURSOR_ATTRIBUTES1:
11525 case SQL_KEYSET_CURSOR_ATTRIBUTES2:
11526 case SQL_DYNAMIC_CURSOR_ATTRIBUTES1:
11527 case SQL_DYNAMIC_CURSOR_ATTRIBUTES2:
11528 *((SQLUINTEGER *) val) = 0;
11529 *valLen = sizeof (SQLUINTEGER);
11530 break;
11531 case SQL_ODBC_INTERFACE_CONFORMANCE:
11532 *((SQLUINTEGER *) val) = SQL_OIC_CORE;
11533 *valLen = sizeof (SQLUINTEGER);
11534 break;
11535 default:
11536 setstatd(d, -1, "unsupported info option %d",
11537 (*d->ov3) ? "HYC00" : "S1C00", type);
11538 return SQL_ERROR;
11539 }
11540 return SQL_SUCCESS;
11541}
11542
11543#if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
11554SQLRETURN SQL_API
11555SQLGetInfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11556 SQLSMALLINT *valLen)
11557{
11558 SQLRETURN ret;
11559
11560 HDBC_LOCK(dbc);
11561 ret = drvgetinfo(dbc, type, val, valMax, valLen);
11563 return ret;
11564}
11565#endif
11566
11567#ifdef WINTERFACE
11578SQLRETURN SQL_API
11579SQLGetInfoW(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11580 SQLSMALLINT *valLen)
11581{
11582 SQLRETURN ret;
11583 SQLSMALLINT len = 0;
11584
11585 HDBC_LOCK(dbc);
11586 ret = drvgetinfo(dbc, type, val, valMax, &len);
11588 if (ret == SQL_SUCCESS) {
11589 SQLWCHAR *v = NULL;
11590
11591 switch (type) {
11592 case SQL_USER_NAME:
11593 case SQL_DRIVER_ODBC_VER:
11594 case SQL_DATA_SOURCE_NAME:
11595 case SQL_DRIVER_NAME:
11596 case SQL_DRIVER_VER:
11597 case SQL_ODBC_VER:
11598 case SQL_SERVER_NAME:
11599 case SQL_DATABASE_NAME:
11600 case SQL_SEARCH_PATTERN_ESCAPE:
11601 case SQL_DBMS_NAME:
11602 case SQL_DBMS_VER:
11603 case SQL_NEED_LONG_DATA_LEN:
11604 case SQL_ROW_UPDATES:
11605 case SQL_ACCESSIBLE_PROCEDURES:
11606 case SQL_PROCEDURES:
11607 case SQL_EXPRESSIONS_IN_ORDERBY:
11608 case SQL_ODBC_SQL_OPT_IEF:
11609 case SQL_LIKE_ESCAPE_CLAUSE:
11610 case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11611 case SQL_OUTER_JOINS:
11612 case SQL_COLUMN_ALIAS:
11613 case SQL_ACCESSIBLE_TABLES:
11614 case SQL_MULT_RESULT_SETS:
11615 case SQL_MULTIPLE_ACTIVE_TXN:
11616 case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11617 case SQL_DATA_SOURCE_READ_ONLY:
11618#ifdef SQL_DESCRIBE_PARAMETER
11619 case SQL_DESCRIBE_PARAMETER:
11620#endif
11621 case SQL_IDENTIFIER_QUOTE_CHAR:
11622 case SQL_OWNER_TERM:
11623 case SQL_PROCEDURE_TERM:
11624 case SQL_QUALIFIER_NAME_SEPARATOR:
11625 case SQL_QUALIFIER_TERM:
11626 case SQL_TABLE_TERM:
11627 case SQL_KEYWORDS:
11628 case SQL_SPECIAL_CHARACTERS:
11629#ifdef SQL_CATALOG_NAME
11630 case SQL_CATALOG_NAME:
11631#endif
11632#ifdef SQL_COLLATION_SEQ
11633 case SQL_COLLATION_SEQ:
11634#endif
11635 if (val) {
11636 if (len > 0) {
11637 v = uc_from_utf((SQLCHAR *) val, len);
11638 if (v) {
11639 int vmax = valMax / sizeof (SQLWCHAR);
11640
11641 uc_strncpy(val, v, vmax);
11642 if (len < vmax) {
11643 len = min(vmax, uc_strlen(v));
11644 v[len] = 0;
11645 } else {
11646 len = vmax;
11647 }
11648 uc_free(v);
11649 len *= sizeof (SQLWCHAR);
11650 } else {
11651 len = 0;
11652 }
11653 }
11654 if (len <= 0) {
11655 len = 0;
11656 if (valMax >= sizeof (SQLWCHAR)) {
11657 *((SQLWCHAR *)val) = 0;
11658 }
11659 }
11660 } else {
11661 len *= sizeof (SQLWCHAR);
11662 }
11663 break;
11664 }
11665 if (valLen) {
11666 *valLen = len;
11667 }
11668 }
11669 return ret;
11670}
11671#endif
11672
11681SQLRETURN SQL_API
11682SQLGetFunctions(SQLHDBC dbc, SQLUSMALLINT func,
11683 SQLUSMALLINT *flags)
11684{
11685 int i;
11686 SQLUSMALLINT exists[100];
11687
11688 if (dbc == SQL_NULL_HDBC) {
11689 return SQL_INVALID_HANDLE;
11690 }
11691 for (i = 0; i < array_size(exists); i++) {
11692 exists[i] = SQL_FALSE;
11693 }
11694 exists[SQL_API_SQLALLOCCONNECT] = SQL_TRUE;
11695 exists[SQL_API_SQLFETCH] = SQL_TRUE;
11696 exists[SQL_API_SQLALLOCENV] = SQL_TRUE;
11697 exists[SQL_API_SQLFREECONNECT] = SQL_TRUE;
11698 exists[SQL_API_SQLALLOCSTMT] = SQL_TRUE;
11699 exists[SQL_API_SQLFREEENV] = SQL_TRUE;
11700 exists[SQL_API_SQLBINDCOL] = SQL_TRUE;
11701 exists[SQL_API_SQLFREESTMT] = SQL_TRUE;
11702 exists[SQL_API_SQLCANCEL] = SQL_TRUE;
11703 exists[SQL_API_SQLGETCURSORNAME] = SQL_TRUE;
11704 exists[SQL_API_SQLCOLATTRIBUTES] = SQL_TRUE;
11705 exists[SQL_API_SQLNUMRESULTCOLS] = SQL_TRUE;
11706 exists[SQL_API_SQLCONNECT] = SQL_TRUE;
11707 exists[SQL_API_SQLPREPARE] = SQL_TRUE;
11708 exists[SQL_API_SQLDESCRIBECOL] = SQL_TRUE;
11709 exists[SQL_API_SQLROWCOUNT] = SQL_TRUE;
11710 exists[SQL_API_SQLDISCONNECT] = SQL_TRUE;
11711 exists[SQL_API_SQLSETCURSORNAME] = SQL_FALSE;
11712 exists[SQL_API_SQLERROR] = SQL_TRUE;
11713 exists[SQL_API_SQLSETPARAM] = SQL_TRUE;
11714 exists[SQL_API_SQLEXECDIRECT] = SQL_TRUE;
11715 exists[SQL_API_SQLTRANSACT] = SQL_TRUE;
11716 exists[SQL_API_SQLBULKOPERATIONS] = SQL_TRUE;
11717 exists[SQL_API_SQLEXECUTE] = SQL_TRUE;
11718 exists[SQL_API_SQLBINDPARAMETER] = SQL_TRUE;
11719 exists[SQL_API_SQLGETTYPEINFO] = SQL_TRUE;
11720 exists[SQL_API_SQLCOLUMNS] = SQL_TRUE;
11721 exists[SQL_API_SQLPARAMDATA] = SQL_TRUE;
11722 exists[SQL_API_SQLDRIVERCONNECT] = SQL_TRUE;
11723 exists[SQL_API_SQLPUTDATA] = SQL_TRUE;
11724 exists[SQL_API_SQLGETCONNECTOPTION] = SQL_TRUE;
11725 exists[SQL_API_SQLSETCONNECTOPTION] = SQL_TRUE;
11726 exists[SQL_API_SQLGETDATA] = SQL_TRUE;
11727 exists[SQL_API_SQLSETSTMTOPTION] = SQL_TRUE;
11728 exists[SQL_API_SQLGETFUNCTIONS] = SQL_TRUE;
11729 exists[SQL_API_SQLSPECIALCOLUMNS] = SQL_TRUE;
11730 exists[SQL_API_SQLGETINFO] = SQL_TRUE;
11731 exists[SQL_API_SQLSTATISTICS] = SQL_TRUE;
11732 exists[SQL_API_SQLGETSTMTOPTION] = SQL_TRUE;
11733 exists[SQL_API_SQLTABLES] = SQL_TRUE;
11734 exists[SQL_API_SQLBROWSECONNECT] = SQL_FALSE;
11735 exists[SQL_API_SQLNUMPARAMS] = SQL_TRUE;
11736 exists[SQL_API_SQLCOLUMNPRIVILEGES] = SQL_FALSE;
11737 exists[SQL_API_SQLPARAMOPTIONS] = SQL_FALSE;
11738 exists[SQL_API_SQLDATASOURCES] = SQL_TRUE;
11739 exists[SQL_API_SQLPRIMARYKEYS] = SQL_TRUE;
11740 exists[SQL_API_SQLDESCRIBEPARAM] = SQL_TRUE;
11741 exists[SQL_API_SQLPROCEDURECOLUMNS] = SQL_TRUE;
11742 exists[SQL_API_SQLDRIVERS] = SQL_FALSE;
11743 exists[SQL_API_SQLPROCEDURES] = SQL_TRUE;
11744 exists[SQL_API_SQLEXTENDEDFETCH] = SQL_TRUE;
11745 exists[SQL_API_SQLSETPOS] = SQL_TRUE;
11746 exists[SQL_API_SQLFOREIGNKEYS] = SQL_TRUE;
11747 exists[SQL_API_SQLSETSCROLLOPTIONS] = SQL_TRUE;
11748 exists[SQL_API_SQLMORERESULTS] = SQL_TRUE;
11749 exists[SQL_API_SQLTABLEPRIVILEGES] = SQL_TRUE;
11750 exists[SQL_API_SQLNATIVESQL] = SQL_TRUE;
11751 if (func == SQL_API_ALL_FUNCTIONS) {
11752 memcpy(flags, exists, sizeof (exists));
11753 } else if (func == SQL_API_ODBC3_ALL_FUNCTIONS) {
11754 int i;
11755#define SET_EXISTS(x) \
11756 flags[(x) >> 4] |= (1 << ((x) & 0xF))
11757#define CLR_EXISTS(x) \
11758 flags[(x) >> 4] &= ~(1 << ((x) & 0xF))
11759
11760 memset(flags, 0,
11761 sizeof (SQLUSMALLINT) * SQL_API_ODBC3_ALL_FUNCTIONS_SIZE);
11762 for (i = 0; i < array_size(exists); i++) {
11763 if (exists[i]) {
11764 flags[i >> 4] |= (1 << (i & 0xF));
11765 }
11766 }
11767 SET_EXISTS(SQL_API_SQLALLOCHANDLE);
11768 SET_EXISTS(SQL_API_SQLFREEHANDLE);
11769 SET_EXISTS(SQL_API_SQLGETSTMTATTR);
11770 SET_EXISTS(SQL_API_SQLSETSTMTATTR);
11771 SET_EXISTS(SQL_API_SQLGETCONNECTATTR);
11772 SET_EXISTS(SQL_API_SQLSETCONNECTATTR);
11773 SET_EXISTS(SQL_API_SQLGETENVATTR);
11774 SET_EXISTS(SQL_API_SQLSETENVATTR);
11775 SET_EXISTS(SQL_API_SQLCLOSECURSOR);
11776 SET_EXISTS(SQL_API_SQLBINDPARAM);
11777#if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11778 /*
11779 * Some unixODBC versions have problems with
11780 * SQLError() vs. SQLGetDiagRec() with loss
11781 * of error/warning messages.
11782 */
11783 SET_EXISTS(SQL_API_SQLGETDIAGREC);
11784#endif
11785 SET_EXISTS(SQL_API_SQLGETDIAGFIELD);
11786 SET_EXISTS(SQL_API_SQLFETCHSCROLL);
11787 SET_EXISTS(SQL_API_SQLENDTRAN);
11788 } else {
11789 if (func < array_size(exists)) {
11790 *flags = exists[func];
11791 } else {
11792 switch (func) {
11793 case SQL_API_SQLALLOCHANDLE:
11794 case SQL_API_SQLFREEHANDLE:
11795 case SQL_API_SQLGETSTMTATTR:
11796 case SQL_API_SQLSETSTMTATTR:
11797 case SQL_API_SQLGETCONNECTATTR:
11798 case SQL_API_SQLSETCONNECTATTR:
11799 case SQL_API_SQLGETENVATTR:
11800 case SQL_API_SQLSETENVATTR:
11801 case SQL_API_SQLCLOSECURSOR:
11802 case SQL_API_SQLBINDPARAM:
11803#if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11804 /*
11805 * Some unixODBC versions have problems with
11806 * SQLError() vs. SQLGetDiagRec() with loss
11807 * of error/warning messages.
11808 */
11809 case SQL_API_SQLGETDIAGREC:
11810#endif
11811 case SQL_API_SQLGETDIAGFIELD:
11812 case SQL_API_SQLFETCHSCROLL:
11813 case SQL_API_SQLENDTRAN:
11814 *flags = SQL_TRUE;
11815 break;
11816 default:
11817 *flags = SQL_FALSE;
11818 }
11819 }
11820 }
11821 return SQL_SUCCESS;
11822}
11823
11830static SQLRETURN
11831drvallocenv(SQLHENV *env)
11832{
11833 ENV *e;
11834
11835 if (env == NULL) {
11836 return SQL_INVALID_HANDLE;
11837 }
11838 e = (ENV *) xmalloc(sizeof (ENV));
11839 if (e == NULL) {
11840 *env = SQL_NULL_HENV;
11841 return SQL_ERROR;
11842 }
11843 e->magic = ENV_MAGIC;
11844 e->ov3 = 0;
11845 e->pool = 0;
11846#if defined(_WIN32) || defined(_WIN64)
11847 InitializeCriticalSection(&e->cs);
11848#else
11849#if defined(ENABLE_NVFS) && (ENABLE_NVFS)
11850 nvfs_init();
11851#endif
11852#endif
11853 e->dbcs = NULL;
11854 *env = (SQLHENV) e;
11855 return SQL_SUCCESS;
11856}
11857
11864SQLRETURN SQL_API
11865SQLAllocEnv(SQLHENV *env)
11866{
11867 return drvallocenv(env);
11868}
11869
11876static SQLRETURN
11877drvfreeenv(SQLHENV env)
11878{
11879 ENV *e;
11880
11881 if (env == SQL_NULL_HENV) {
11882 return SQL_INVALID_HANDLE;
11883 }
11884 e = (ENV *) env;
11885 if (e->magic != ENV_MAGIC) {
11886 return SQL_SUCCESS;
11887 }
11888#if defined(_WIN32) || defined(_WIN64)
11889 EnterCriticalSection(&e->cs);
11890#endif
11891 if (e->dbcs) {
11892#if defined(_WIN32) || defined(_WIN64)
11893 LeaveCriticalSection(&e->cs);
11894#endif
11895 return SQL_ERROR;
11896 }
11897 e->magic = DEAD_MAGIC;
11898#if defined(_WIN32) || defined(_WIN64)
11899 LeaveCriticalSection(&e->cs);
11900 DeleteCriticalSection(&e->cs);
11901#endif
11902 xfree(e);
11903 return SQL_SUCCESS;
11904}
11905
11912SQLRETURN SQL_API
11913SQLFreeEnv(SQLHENV env)
11914{
11915 return drvfreeenv(env);
11916}
11917
11925static SQLRETURN
11926drvallocconnect(SQLHENV env, SQLHDBC *dbc)
11927{
11928 DBC *d;
11929 ENV *e;
11930 const char *verstr;
11931 int maj = 0, min = 0, lev = 0;
11932
11933 if (dbc == NULL) {
11934 return SQL_ERROR;
11935 }
11936 d = (DBC *) xmalloc(sizeof (DBC));
11937 if (d == NULL) {
11938 *dbc = SQL_NULL_HDBC;
11939 return SQL_ERROR;
11940 }
11941 memset(d, 0, sizeof (DBC));
11942 d->curtype = SQL_CURSOR_STATIC;
11943 d->ov3 = &d->ov3val;
11944 verstr = sqlite3_libversion();
11945 sscanf(verstr, "%d.%d.%d", &maj, &min, &lev);
11946 d->version = verinfo(maj & 0xFF, min & 0xFF, lev & 0xFF);
11947 e = (ENV *) env;
11948#if defined(_WIN32) || defined(_WIN64)
11949 if (e->magic == ENV_MAGIC) {
11950 EnterCriticalSection(&e->cs);
11951 }
11952#endif
11953 if (e->magic == ENV_MAGIC) {
11954 DBC *n, *p;
11955
11956 d->env = e;
11957 d->ov3 = &e->ov3;
11958 p = NULL;
11959 n = e->dbcs;
11960 while (n) {
11961 p = n;
11962 n = n->next;
11963 }
11964 if (p) {
11965 p->next = d;
11966 } else {
11967 e->dbcs = d;
11968 }
11969 }
11970#if defined(_WIN32) || defined(_WIN64)
11971 InitializeCriticalSection(&d->cs);
11972 d->owner = 0;
11973 if (e->magic == ENV_MAGIC) {
11974 LeaveCriticalSection(&e->cs);
11975 }
11976 d->oemcp = 1;
11977#endif
11978 d->autocommit = 1;
11979 d->magic = DBC_MAGIC;
11980 *dbc = (SQLHDBC) d;
11981 drvgetgpps(d);
11982 return SQL_SUCCESS;
11983}
11984
11992SQLRETURN SQL_API
11993SQLAllocConnect(SQLHENV env, SQLHDBC *dbc)
11994{
11995 return drvallocconnect(env, dbc);
11996}
11997
12004static SQLRETURN
12006{
12007 DBC *d;
12008 ENV *e;
12009 SQLRETURN ret = SQL_ERROR;
12010
12011 if (dbc == SQL_NULL_HDBC) {
12012 return SQL_INVALID_HANDLE;
12013 }
12014 d = (DBC *) dbc;
12015 if (d->magic != DBC_MAGIC) {
12016 return SQL_INVALID_HANDLE;
12017 }
12018 e = d->env;
12019 if (e && e->magic == ENV_MAGIC) {
12020#if defined(_WIN32) || defined(_WIN64)
12021 EnterCriticalSection(&e->cs);
12022#endif
12023 } else {
12024 e = NULL;
12025 }
12026 HDBC_LOCK(dbc);
12027 if (d->sqlite) {
12028 setstatd(d, -1, "not disconnected", (*d->ov3) ? "HY000" : "S1000");
12030 goto done;
12031 }
12032 while (d->stmt) {
12033 freestmt((HSTMT) d->stmt);
12034 }
12035 if (e && e->magic == ENV_MAGIC) {
12036 DBC *n, *p;
12037
12038 p = NULL;
12039 n = e->dbcs;
12040 while (n) {
12041 if (n == d) {
12042 break;
12043 }
12044 p = n;
12045 n = n->next;
12046 }
12047 if (n) {
12048 if (p) {
12049 p->next = d->next;
12050 } else {
12051 e->dbcs = d->next;
12052 }
12053 }
12054 }
12055 drvrelgpps(d);
12056 d->magic = DEAD_MAGIC;
12057 if (d->trace) {
12058 fclose(d->trace);
12059 }
12060#if defined(_WIN32) || defined(_WIN64)
12061 d->owner = 0;
12062 LeaveCriticalSection(&d->cs);
12063 DeleteCriticalSection(&d->cs);
12064#endif
12065 xfree(d);
12066 ret = SQL_SUCCESS;
12067done:
12068#if defined(_WIN32) || defined(_WIN64)
12069 if (e) {
12070 LeaveCriticalSection(&e->cs);
12071 }
12072#endif
12073 return ret;
12074}
12075
12082SQLRETURN SQL_API
12084{
12085 return drvfreeconnect(dbc);
12086}
12087
12098static SQLRETURN
12099drvgetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12100 SQLINTEGER bufmax, SQLINTEGER *buflen)
12101{
12102 DBC *d;
12103 SQLINTEGER dummy;
12104
12105 if (dbc == SQL_NULL_HDBC) {
12106 return SQL_INVALID_HANDLE;
12107 }
12108 d = (DBC *) dbc;
12109 if (!val) {
12110 val = (SQLPOINTER) &dummy;
12111 }
12112 if (!buflen) {
12113 buflen = &dummy;
12114 }
12115 switch (attr) {
12116 case SQL_ATTR_CONNECTION_DEAD:
12117 *((SQLINTEGER *) val) = d->sqlite ? SQL_CD_FALSE : SQL_CD_TRUE;
12118 *buflen = sizeof (SQLINTEGER);
12119 break;
12120 case SQL_ATTR_ACCESS_MODE:
12121 *((SQLINTEGER *) val) = SQL_MODE_READ_WRITE;
12122 *buflen = sizeof (SQLINTEGER);
12123 break;
12124 case SQL_ATTR_AUTOCOMMIT:
12125 *((SQLINTEGER *) val) =
12126 d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
12127 *buflen = sizeof (SQLINTEGER);
12128 break;
12129 case SQL_ATTR_LOGIN_TIMEOUT:
12130 *((SQLINTEGER *) val) = 100;
12131 *buflen = sizeof (SQLINTEGER);
12132 break;
12133 case SQL_ATTR_ODBC_CURSORS:
12134 *((SQLINTEGER *) val) = SQL_CUR_USE_DRIVER;
12135 *buflen = sizeof (SQLINTEGER);
12136 break;
12137 case SQL_ATTR_PACKET_SIZE:
12138 *((SQLINTEGER *) val) = 16384;
12139 *buflen = sizeof (SQLINTEGER);
12140 break;
12141 case SQL_ATTR_TXN_ISOLATION:
12142 *((SQLINTEGER *) val) = SQL_TXN_SERIALIZABLE;
12143 *buflen = sizeof (SQLINTEGER);
12144 break;
12145 case SQL_ATTR_TRACEFILE:
12146 case SQL_ATTR_TRANSLATE_LIB:
12147 *((SQLCHAR *) val) = 0;
12148 *buflen = 0;
12149 break;
12150 case SQL_ATTR_CURRENT_CATALOG:
12151#if defined(_WIN32) || defined(_WIN64)
12152 if (d->xcelqrx) {
12153 if ((bufmax > 4) && (val != (SQLPOINTER) &dummy)) {
12154 strcpy((char *) val, "main");
12155 *buflen = 4;
12156 break;
12157 }
12158 }
12159#endif
12160 *((SQLCHAR *) val) = 0;
12161 *buflen = 0;
12162 break;
12163 case SQL_ATTR_TRACE:
12164 case SQL_ATTR_QUIET_MODE:
12165 case SQL_ATTR_TRANSLATE_OPTION:
12166 case SQL_ATTR_KEYSET_SIZE:
12167 case SQL_ATTR_QUERY_TIMEOUT:
12168 *((SQLINTEGER *) val) = 0;
12169 *buflen = sizeof (SQLINTEGER);
12170 break;
12171 case SQL_ATTR_PARAM_BIND_TYPE:
12172 *((SQLULEN *) val) = SQL_PARAM_BIND_BY_COLUMN;
12173 *buflen = sizeof (SQLUINTEGER);
12174 break;
12175 case SQL_ATTR_ROW_BIND_TYPE:
12176 *((SQLULEN *) val) = SQL_BIND_BY_COLUMN;
12177 *buflen = sizeof (SQLULEN);
12178 break;
12179 case SQL_ATTR_USE_BOOKMARKS:
12180 *((SQLINTEGER *) val) = SQL_UB_OFF;
12181 *buflen = sizeof (SQLINTEGER);
12182 break;
12183 case SQL_ATTR_ASYNC_ENABLE:
12184 *((SQLINTEGER *) val) = SQL_ASYNC_ENABLE_OFF;
12185 *buflen = sizeof (SQLINTEGER);
12186 break;
12187 case SQL_ATTR_NOSCAN:
12188 *((SQLINTEGER *) val) = SQL_NOSCAN_ON;
12189 *buflen = sizeof (SQLINTEGER);
12190 break;
12191 case SQL_ATTR_CONCURRENCY:
12192 *((SQLINTEGER *) val) = SQL_CONCUR_LOCK;
12193 *buflen = sizeof (SQLINTEGER);
12194 break;
12195#ifdef SQL_ATTR_CURSOR_SENSITIVITY
12196 case SQL_ATTR_CURSOR_SENSITIVITY:
12197 *((SQLINTEGER *) val) = SQL_UNSPECIFIED;
12198 *buflen = sizeof (SQLINTEGER);
12199 break;
12200#endif
12201 case SQL_ATTR_SIMULATE_CURSOR:
12202 *((SQLINTEGER *) val) = SQL_SC_NON_UNIQUE;
12203 *buflen = sizeof (SQLINTEGER);
12204 break;
12205 case SQL_ATTR_MAX_ROWS:
12206 *((SQLINTEGER *) val) = 0;
12207 *buflen = sizeof (SQLINTEGER);
12208 case SQL_ATTR_MAX_LENGTH:
12209 *((SQLINTEGER *) val) = 1000000000;
12210 *buflen = sizeof (SQLINTEGER);
12211 break;
12212 case SQL_ATTR_CURSOR_TYPE:
12213 *((SQLINTEGER *) val) = d->curtype;
12214 *buflen = sizeof (SQLINTEGER);
12215 break;
12216 case SQL_ATTR_RETRIEVE_DATA:
12217 *((SQLINTEGER *) val) = SQL_RD_ON;
12218 *buflen = sizeof (SQLINTEGER);
12219 break;
12220#ifdef SQL_ATTR_METADATA_ID
12221 case SQL_ATTR_METADATA_ID:
12222 *((SQLULEN *) val) = SQL_FALSE;
12223 return SQL_SUCCESS;
12224#endif
12225 default:
12226 *((SQLINTEGER *) val) = 0;
12227 *buflen = sizeof (SQLINTEGER);
12228 setstatd(d, -1, "unsupported connect attribute %d",
12229 (*d->ov3) ? "HYC00" : "S1C00", (int) attr);
12230 return SQL_ERROR;
12231 }
12232 return SQL_SUCCESS;
12233}
12234
12235#ifndef WINTERFACE
12246SQLRETURN SQL_API
12247SQLGetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12248 SQLINTEGER bufmax, SQLINTEGER *buflen)
12249{
12250 SQLRETURN ret;
12251
12252 HDBC_LOCK(dbc);
12253 ret = drvgetconnectattr(dbc, attr, val, bufmax, buflen);
12255 return ret;
12256}
12257#endif
12258
12259#ifdef WINTERFACE
12270SQLRETURN SQL_API
12271SQLGetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12272 SQLINTEGER bufmax, SQLINTEGER *buflen)
12273{
12274 SQLRETURN ret;
12275 SQLINTEGER len = 0;
12276
12277 HDBC_LOCK(dbc);
12278 ret = drvgetconnectattr(dbc, attr, val, bufmax, &len);
12279 if (ret == SQL_SUCCESS) {
12280 SQLWCHAR *v = NULL;
12281
12282 switch (attr) {
12283 case SQL_ATTR_TRACEFILE:
12284 case SQL_ATTR_CURRENT_CATALOG:
12285 case SQL_ATTR_TRANSLATE_LIB:
12286 if (val) {
12287 if (len > 0) {
12288 v = uc_from_utf((SQLCHAR *) val, len);
12289 if (v) {
12290 int vmax = bufmax / sizeof (SQLWCHAR);
12291
12292 uc_strncpy(val, v, vmax);
12293 if (len < vmax) {
12294 len = min(vmax, uc_strlen(v));
12295 v[len] = 0;
12296 } else {
12297 len = vmax;
12298 }
12299 uc_free(v);
12300 len *= sizeof (SQLWCHAR);
12301 } else {
12302 len = 0;
12303 }
12304 }
12305 if (len <= 0) {
12306 len = 0;
12307 if (bufmax >= sizeof (SQLWCHAR)) {
12308 *((SQLWCHAR *)val) = 0;
12309 }
12310 }
12311 } else {
12312 len *= sizeof (SQLWCHAR);
12313 }
12314 break;
12315 }
12316 if (buflen) {
12317 *buflen = len;
12318 }
12319 }
12321 return ret;
12322}
12323#endif
12324
12334static SQLRETURN
12335drvsetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12336 SQLINTEGER len)
12337{
12338 DBC *d;
12339
12340 if (dbc == SQL_NULL_HDBC) {
12341 return SQL_INVALID_HANDLE;
12342 }
12343 d = (DBC *) dbc;
12344 switch (attr) {
12345 case SQL_AUTOCOMMIT:
12346 d->autocommit = val == (SQLPOINTER) SQL_AUTOCOMMIT_ON;
12347 if (d->autocommit && d->intrans) {
12348 return endtran(d, SQL_COMMIT, 1);
12349 } else if (!d->autocommit) {
12351 }
12352 break;
12353 return SQL_SUCCESS;
12354#ifdef SQL_ATTR_METADATA_ID
12355 case SQL_ATTR_METADATA_ID:
12356 if (val == (SQLPOINTER) SQL_FALSE) {
12357 break;
12358 }
12359 /* fall through */
12360#endif
12361 default:
12362 setstatd(d, -1, "option value changed", "01S02");
12363 return SQL_SUCCESS_WITH_INFO;
12364 }
12365 return SQL_SUCCESS;
12366}
12367
12368#ifndef WINTERFACE
12378SQLRETURN SQL_API
12379SQLSetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12380 SQLINTEGER len)
12381{
12382 SQLRETURN ret;
12383
12384 HDBC_LOCK(dbc);
12385 ret = drvsetconnectattr(dbc, attr, val, len);
12387 return ret;
12388}
12389#endif
12390
12391#ifdef WINTERFACE
12401SQLRETURN SQL_API
12402SQLSetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12403 SQLINTEGER len)
12404{
12405 SQLRETURN ret;
12406
12407 HDBC_LOCK(dbc);
12408 ret = drvsetconnectattr(dbc, attr, val, len);
12410 return ret;
12411}
12412#endif
12413
12422static SQLRETURN
12423drvgetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12424{
12425 DBC *d;
12426 SQLINTEGER dummy;
12427
12428 if (dbc == SQL_NULL_HDBC) {
12429 return SQL_INVALID_HANDLE;
12430 }
12431 d = (DBC *) dbc;
12432 if (!param) {
12433 param = (SQLPOINTER) &dummy;
12434 }
12435 switch (opt) {
12436 case SQL_ACCESS_MODE:
12437 *((SQLINTEGER *) param) = SQL_MODE_READ_WRITE;
12438 break;
12439 case SQL_AUTOCOMMIT:
12440 *((SQLINTEGER *) param) =
12441 d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
12442 break;
12443 case SQL_LOGIN_TIMEOUT:
12444 *((SQLINTEGER *) param) = 100;
12445 break;
12446 case SQL_ODBC_CURSORS:
12447 *((SQLINTEGER *) param) = SQL_CUR_USE_DRIVER;
12448 break;
12449 case SQL_PACKET_SIZE:
12450 *((SQLINTEGER *) param) = 16384;
12451 break;
12452 case SQL_TXN_ISOLATION:
12453 *((SQLINTEGER *) param) = SQL_TXN_SERIALIZABLE;
12454 break;
12455 case SQL_OPT_TRACE:
12456 case SQL_OPT_TRACEFILE:
12457 case SQL_QUIET_MODE:
12458 case SQL_TRANSLATE_DLL:
12459 case SQL_TRANSLATE_OPTION:
12460 case SQL_KEYSET_SIZE:
12461 case SQL_QUERY_TIMEOUT:
12462 case SQL_BIND_TYPE:
12463 case SQL_CURRENT_QUALIFIER:
12464 *((SQLINTEGER *) param) = 0;
12465 break;
12466 case SQL_USE_BOOKMARKS:
12467 *((SQLINTEGER *) param) = SQL_UB_OFF;
12468 break;
12469 case SQL_ASYNC_ENABLE:
12470 *((SQLINTEGER *) param) = SQL_ASYNC_ENABLE_OFF;
12471 break;
12472 case SQL_NOSCAN:
12473 *((SQLINTEGER *) param) = SQL_NOSCAN_ON;
12474 break;
12475 case SQL_CONCURRENCY:
12476 *((SQLINTEGER *) param) = SQL_CONCUR_LOCK;
12477 break;
12478 case SQL_SIMULATE_CURSOR:
12479 *((SQLINTEGER *) param) = SQL_SC_NON_UNIQUE;
12480 break;
12481 case SQL_MAX_ROWS:
12482 *((SQLINTEGER *) param) = 0;
12483 break;
12484 case SQL_ROWSET_SIZE:
12485 case SQL_MAX_LENGTH:
12486 *((SQLINTEGER *) param) = 1000000000;
12487 break;
12488 case SQL_CURSOR_TYPE:
12489 *((SQLINTEGER *) param) = d->curtype;
12490 break;
12491 case SQL_RETRIEVE_DATA:
12492 *((SQLINTEGER *) param) = SQL_RD_ON;
12493 break;
12494 default:
12495 *((SQLINTEGER *) param) = 0;
12496 setstatd(d, -1, "unsupported connect option %d",
12497 (*d->ov3) ? "HYC00" : "S1C00", opt);
12498 return SQL_ERROR;
12499 }
12500 return SQL_SUCCESS;
12501}
12502
12503#ifndef WINTERFACE
12512SQLRETURN SQL_API
12513SQLGetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12514{
12515 SQLRETURN ret;
12516
12517 HDBC_LOCK(dbc);
12518 ret = drvgetconnectoption(dbc, opt, param);
12520 return ret;
12521}
12522#endif
12523
12524#ifdef WINTERFACE
12533SQLRETURN SQL_API
12534SQLGetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12535{
12536 SQLRETURN ret;
12537
12538 HDBC_LOCK(dbc);
12539 ret = drvgetconnectoption(dbc, opt, param);
12540 if (SQL_SUCCEEDED(ret)) {
12541 switch (opt) {
12542 case SQL_OPT_TRACEFILE:
12543 case SQL_CURRENT_QUALIFIER:
12544 case SQL_TRANSLATE_DLL:
12545 if (param) {
12546 *(SQLWCHAR *) param = 0;
12547 }
12548 break;
12549 }
12550 }
12552 return ret;
12553}
12554#endif
12555
12564static SQLRETURN
12565drvsetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
12566{
12567 DBC *d;
12568
12569 if (dbc == SQL_NULL_HDBC) {
12570 return SQL_INVALID_HANDLE;
12571 }
12572 d = (DBC *) dbc;
12573 switch (opt) {
12574 case SQL_AUTOCOMMIT:
12575 d->autocommit = param == SQL_AUTOCOMMIT_ON;
12576 if (d->autocommit && d->intrans) {
12577 return endtran(d, SQL_COMMIT, 1);
12578 } else if (!d->autocommit) {
12580 }
12581 break;
12582 default:
12583 setstatd(d, -1, "option value changed", "01S02");
12584 return SQL_SUCCESS_WITH_INFO;
12585 }
12586 return SQL_SUCCESS;
12587}
12588
12589#ifndef WINTERFACE
12598SQLRETURN SQL_API
12599SQLSetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12600{
12601 SQLRETURN ret;
12602
12603 HDBC_LOCK(dbc);
12604 ret = drvsetconnectoption(dbc, opt, param);
12606 return ret;
12607}
12608#endif
12609
12610#ifdef WINTERFACE
12619SQLRETURN SQL_API
12620SQLSetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12621{
12622 SQLRETURN ret;
12623
12624 HDBC_LOCK(dbc);
12625 ret = drvsetconnectoption(dbc, opt, param);
12627 return ret;
12628}
12629#endif
12630
12631#if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
12632
12643static int
12644getdsnattr(char *dsn, char *attr, char *out, int outLen)
12645{
12646 char *str = dsn, *start;
12647 int len = strlen(attr);
12648
12649 while (*str) {
12650 while (*str && *str == ';') {
12651 ++str;
12652 }
12653 start = str;
12654 if ((str = strchr(str, '=')) == NULL) {
12655 return 0;
12656 }
12657 if (str - start == len && strncasecmp(start, attr, len) == 0) {
12658 start = ++str;
12659 while (*str && *str != ';') {
12660 ++str;
12661 }
12662 len = min(outLen - 1, str - start);
12663 strncpy(out, start, len);
12664 out[len] = '\0';
12665 return 1;
12666 }
12667 while (*str && *str != ';') {
12668 ++str;
12669 }
12670 }
12671 return 0;
12672}
12673#endif
12674
12686static SQLRETURN
12687drvconnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen, char *pwd,
12688 int pwdLen, int isu)
12689{
12690 DBC *d;
12691 int len;
12692 SQLRETURN ret;
12693 char buf[SQL_MAX_MESSAGE_LENGTH * 6], dbname[SQL_MAX_MESSAGE_LENGTH];
12694 char busy[SQL_MAX_MESSAGE_LENGTH / 4], tracef[SQL_MAX_MESSAGE_LENGTH];
12695 char loadext[SQL_MAX_MESSAGE_LENGTH];
12696 char sflag[32], spflag[32], ntflag[32], nwflag[32], biflag[32];
12697 char snflag[32], lnflag[32], ncflag[32], fkflag[32], jmode[32];
12698 char jdflag[32];
12699#if defined(_WIN32) || defined(_WIN64)
12700 char oemcp[32];
12701#endif
12702
12703 if (dbc == SQL_NULL_HDBC) {
12704 return SQL_INVALID_HANDLE;
12705 }
12706 d = (DBC *) dbc;
12707 if (d->magic != DBC_MAGIC) {
12708 return SQL_INVALID_HANDLE;
12709 }
12710 if (d->sqlite != NULL) {
12711 setstatd(d, -1, "connection already established", "08002");
12712 return SQL_ERROR;
12713 }
12714 buf[0] = '\0';
12715 if (dsnLen == SQL_NTS) {
12716 len = sizeof (buf) - 1;
12717 } else {
12718 len = min(sizeof (buf) - 1, dsnLen);
12719 }
12720 if (dsn != NULL) {
12721 strncpy(buf, (char *) dsn, len);
12722 }
12723 buf[len] = '\0';
12724 if (buf[0] == '\0') {
12725 setstatd(d, -1, "invalid DSN", (*d->ov3) ? "HY090" : "S1090");
12726 return SQL_ERROR;
12727 }
12728#if defined(_WIN32) || defined(_WIN64)
12729 /*
12730 * When DSN is in UTF it must be converted to ANSI
12731 * here for ANSI SQLGetPrivateProfileString()
12732 */
12733 if (isu) {
12734 char *cdsn = utf_to_wmb(buf, len);
12735
12736 if (!cdsn) {
12737 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12738 return SQL_ERROR;
12739 }
12740 strcpy(buf, cdsn);
12741 uc_free(cdsn);
12742 }
12743#endif
12744 busy[0] = '\0';
12745 dbname[0] = '\0';
12746#ifdef WITHOUT_DRIVERMGR
12747 getdsnattr(buf, "database", dbname, sizeof (dbname));
12748 if (dbname[0] == '\0') {
12749 strncpy(dbname, buf, sizeof (dbname));
12750 dbname[sizeof (dbname) - 1] = '\0';
12751 }
12752 getdsnattr(buf, "timeout", busy, sizeof (busy));
12753 sflag[0] = '\0';
12754 getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
12755 spflag[0] = '\0';
12756 getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
12757 ntflag[0] = '\0';
12758 getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
12759 nwflag[0] = '\0';
12760 getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
12761 snflag[0] = '\0';
12762 getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
12763 lnflag[0] = '\0';
12764 getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
12765 ncflag[0] = '\0';
12766 getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
12767 fkflag[0] = '\0';
12768 getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
12769 loadext[0] = '\0';
12770 getdsnattr(buf, "loadext", loadext, sizeof (loadext));
12771 jmode[0] = '\0';
12772 getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
12773 jdflag[0] = '\0';
12774 getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
12775#if defined(_WIN32) || defined(_WIN64)
12776 oemcp[0] = '\0';
12777 getdsnattr(buf, "oemcp", oemcp, sizeof (oemcp));
12778#endif
12779 biflag[0] = '\0';
12780 getdsnattr(buf, "bigint", biflag, sizeof (biflag));
12781#else
12782 SQLGetPrivateProfileString(buf, "timeout", "100000",
12783 busy, sizeof (busy), ODBC_INI);
12784 SQLGetPrivateProfileString(buf, "database", "",
12785 dbname, sizeof (dbname), ODBC_INI);
12786#if defined(_WIN32) || defined(_WIN64)
12787 /* database name read from registry is not UTF8 !!! */
12788 isu = 0;
12789#endif
12790 SQLGetPrivateProfileString(buf, "stepapi", "",
12791 sflag, sizeof (sflag), ODBC_INI);
12792 SQLGetPrivateProfileString(buf, "syncpragma", "NORMAL",
12793 spflag, sizeof (spflag), ODBC_INI);
12794 SQLGetPrivateProfileString(buf, "notxn", "",
12795 ntflag, sizeof (ntflag), ODBC_INI);
12796 SQLGetPrivateProfileString(buf, "nowchar", "",
12797 nwflag, sizeof (nwflag), ODBC_INI);
12798 SQLGetPrivateProfileString(buf, "shortnames", "",
12799 snflag, sizeof (snflag), ODBC_INI);
12800 SQLGetPrivateProfileString(buf, "longnames", "",
12801 lnflag, sizeof (lnflag), ODBC_INI);
12802 SQLGetPrivateProfileString(buf, "nocreat", "",
12803 ncflag, sizeof (ncflag), ODBC_INI);
12804 SQLGetPrivateProfileString(buf, "fksupport", "",
12805 fkflag, sizeof (fkflag), ODBC_INI);
12806 SQLGetPrivateProfileString(buf, "loadext", "",
12807 loadext, sizeof (loadext), ODBC_INI);
12808 SQLGetPrivateProfileString(buf, "journalmode", "",
12809 jmode, sizeof (jmode), ODBC_INI);
12810 SQLGetPrivateProfileString(buf, "jdconv", "",
12811 jdflag, sizeof (jdflag), ODBC_INI);
12812#if defined(_WIN32) || defined(_WIN64)
12813 SQLGetPrivateProfileString(buf, "oemcp", "1",
12814 oemcp, sizeof (oemcp), ODBC_INI);
12815#endif
12816 SQLGetPrivateProfileString(buf, "bigint", "",
12817 biflag, sizeof (biflag), ODBC_INI);
12818#endif
12819 tracef[0] = '\0';
12820#ifdef WITHOUT_DRIVERMGR
12821 getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
12822#else
12823 SQLGetPrivateProfileString(buf, "tracefile", "",
12824 tracef, sizeof (tracef), ODBC_INI);
12825#endif
12826 if (tracef[0] != '\0') {
12827 d->trace = fopen(tracef, "a");
12828 }
12829 d->nowchar = getbool(nwflag);
12830 d->shortnames = getbool(snflag);
12831 d->longnames = getbool(lnflag);
12832 d->nocreat = getbool(ncflag);
12833 d->fksupport = getbool(fkflag);
12834 d->jdconv = getbool(jdflag);
12835#if defined(_WIN32) || defined(_WIN64)
12836 d->oemcp = getbool(oemcp);
12837#else
12838 d->oemcp = 0;
12839#endif
12840 d->dobigint = getbool(biflag);
12841 d->pwd = pwd;
12842 d->pwdLen = 0;
12843 if (d->pwd) {
12844 d->pwdLen = (pwdLen == SQL_NTS) ? strlen(d->pwd) : pwdLen;
12845 }
12846 ret = dbopen(d, dbname, isu, (char *) dsn, sflag, spflag, ntflag,
12847 jmode, busy);
12848 if (ret == SQL_SUCCESS) {
12849 dbloadext(d, loadext);
12850 }
12851 return ret;
12852}
12853
12854#ifndef WINTERFACE
12867SQLRETURN SQL_API
12868SQLConnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen,
12869 SQLCHAR *uid, SQLSMALLINT uidLen,
12870 SQLCHAR *pwd, SQLSMALLINT pwdLen)
12871{
12872 SQLRETURN ret;
12873
12874 HDBC_LOCK(dbc);
12875 ret = drvconnect(dbc, dsn, dsnLen, (char *) pwd, pwdLen, 0);
12877 return ret;
12878}
12879#endif
12880
12881#ifdef WINTERFACE
12894SQLRETURN SQL_API
12895SQLConnectW(SQLHDBC dbc, SQLWCHAR *dsn, SQLSMALLINT dsnLen,
12896 SQLWCHAR *uid, SQLSMALLINT uidLen,
12897 SQLWCHAR *pwd, SQLSMALLINT pwdLen)
12898{
12899 char *dsna = NULL;
12900 char *pwda = NULL;
12901 SQLRETURN ret;
12902
12903 HDBC_LOCK(dbc);
12904 if (dsn) {
12905 dsna = uc_to_utf_c(dsn, dsnLen);
12906 if (!dsna) {
12907 DBC *d = (DBC *) dbc;
12908
12909 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12910 ret = SQL_ERROR;
12911 goto done;
12912 }
12913 }
12914 if (pwd) {
12915 pwda = uc_to_utf_c(pwd, pwdLen);
12916 if (!pwda) {
12917 DBC *d = (DBC *) dbc;
12918
12919 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12920 ret = SQL_ERROR;
12921 goto done;
12922 }
12923 }
12924 ret = drvconnect(dbc, (SQLCHAR *) dsna, SQL_NTS, pwda, SQL_NTS, 1);
12925done:
12927 uc_free(dsna);
12928 uc_free(pwda);
12929 return ret;
12930}
12931#endif
12932
12939static SQLRETURN
12941{
12942 DBC *d;
12943 int rc;
12944
12945 if (dbc == SQL_NULL_HDBC) {
12946 return SQL_INVALID_HANDLE;
12947 }
12948 d = (DBC *) dbc;
12949 if (d->magic != DBC_MAGIC) {
12950 return SQL_INVALID_HANDLE;
12951 }
12952 if (d->intrans) {
12953 setstatd(d, -1, "incomplete transaction", "25000");
12954 return SQL_ERROR;
12955 }
12956 if (d->cur_s3stmt) {
12958 }
12959 if (d->sqlite) {
12960 if (d->trace) {
12961 fprintf(d->trace, "-- sqlite3_close: '%s'\n",
12962 d->dbname);
12963 fflush(d->trace);
12964 }
12965 rc = sqlite3_close(d->sqlite);
12966 if (rc == SQLITE_BUSY) {
12967 setstatd(d, -1, "unfinished statements", "25000");
12968 return SQL_ERROR;
12969 }
12970 d->sqlite = NULL;
12971 }
12972 freep(&d->dbname);
12973 freep(&d->dsn);
12974 return SQL_SUCCESS;
12975}
12976
12983SQLRETURN SQL_API
12985{
12986 SQLRETURN ret;
12987
12988 HDBC_LOCK(dbc);
12989 ret = drvdisconnect(dbc);
12991 return ret;
12992}
12993
12994#if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
12995
13009static SQLRETURN
13010drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
13011 SQLCHAR *connIn, SQLSMALLINT connInLen,
13012 SQLCHAR *connOut, SQLSMALLINT connOutMax,
13013 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
13014{
13015 DBC *d;
13016 int len;
13017 SQLRETURN ret;
13018 char buf[SQL_MAX_MESSAGE_LENGTH * 8], dbname[SQL_MAX_MESSAGE_LENGTH];
13019 char dsn[SQL_MAX_MESSAGE_LENGTH], busy[SQL_MAX_MESSAGE_LENGTH / 4];
13020 char tracef[SQL_MAX_MESSAGE_LENGTH], loadext[SQL_MAX_MESSAGE_LENGTH];
13021 char pwd[SQL_MAX_MESSAGE_LENGTH];
13022 char sflag[32], spflag[32], ntflag[32], snflag[32], lnflag[32];
13023 char ncflag[32], nwflag[32], fkflag[32], jmode[32], biflag[32];
13024 char jdflag[32];
13025
13026 if (dbc == SQL_NULL_HDBC) {
13027 return SQL_INVALID_HANDLE;
13028 }
13029 if (drvcompl != SQL_DRIVER_COMPLETE &&
13030 drvcompl != SQL_DRIVER_COMPLETE_REQUIRED &&
13031 drvcompl != SQL_DRIVER_PROMPT &&
13032 drvcompl != SQL_DRIVER_NOPROMPT) {
13033 return SQL_NO_DATA;
13034 }
13035 d = (DBC *) dbc;
13036 if (d->sqlite) {
13037 setstatd(d, -1, "connection already established", "08002");
13038 return SQL_ERROR;
13039 }
13040 buf[0] = '\0';
13041 if (connInLen == SQL_NTS) {
13042 len = sizeof (buf) - 1;
13043 } else {
13044 len = min(connInLen, sizeof (buf) - 1);
13045 }
13046 if (connIn != NULL) {
13047 strncpy(buf, (char *) connIn, len);
13048 }
13049 buf[len] = '\0';
13050 if (!buf[0]) {
13051 setstatd(d, -1, "invalid connect attributes",
13052 (*d->ov3) ? "HY090" : "S1090");
13053 return SQL_ERROR;
13054 }
13055 dsn[0] = '\0';
13056 getdsnattr(buf, "DSN", dsn, sizeof (dsn));
13057
13058 /* special case: connIn is sole DSN value without keywords */
13059 if (!dsn[0] && !strchr(buf, ';') && !strchr(buf, '=')) {
13060 strncpy(dsn, buf, sizeof (dsn) - 1);
13061 dsn[sizeof (dsn) - 1] = '\0';
13062 }
13063
13064 busy[0] = '\0';
13065 getdsnattr(buf, "timeout", busy, sizeof (busy));
13066#ifndef WITHOUT_DRIVERMGR
13067 if (dsn[0] && !busy[0]) {
13068 SQLGetPrivateProfileString(dsn, "timeout", "100000",
13069 busy, sizeof (busy), ODBC_INI);
13070 }
13071#endif
13072 dbname[0] = '\0';
13073 getdsnattr(buf, "database", dbname, sizeof (dbname));
13074#ifndef WITHOUT_DRIVERMGR
13075 if (dsn[0] && !dbname[0]) {
13076 SQLGetPrivateProfileString(dsn, "database", "",
13077 dbname, sizeof (dbname), ODBC_INI);
13078 }
13079#endif
13080 sflag[0] = '\0';
13081 getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
13082#ifndef WITHOUT_DRIVERMGR
13083 if (dsn[0] && !sflag[0]) {
13084 SQLGetPrivateProfileString(dsn, "stepapi", "",
13085 sflag, sizeof (sflag), ODBC_INI);
13086 }
13087#endif
13088 spflag[0] = '\0';
13089 getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
13090#ifndef WITHOUT_DRIVERMGR
13091 if (dsn[0] && !spflag[0]) {
13092 SQLGetPrivateProfileString(dsn, "syncpragma", "NORMAL",
13093 spflag, sizeof (spflag), ODBC_INI);
13094 }
13095#endif
13096 ntflag[0] = '\0';
13097 getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
13098#ifndef WITHOUT_DRIVERMGR
13099 if (dsn[0] && !ntflag[0]) {
13100 SQLGetPrivateProfileString(dsn, "notxn", "",
13101 ntflag, sizeof (ntflag), ODBC_INI);
13102 }
13103#endif
13104 snflag[0] = '\0';
13105 getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
13106#ifndef WITHOUT_DRIVERMGR
13107 if (dsn[0] && !snflag[0]) {
13108 SQLGetPrivateProfileString(dsn, "shortnames", "",
13109 snflag, sizeof (snflag), ODBC_INI);
13110 }
13111#endif
13112 lnflag[0] = '\0';
13113 getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
13114#ifndef WITHOUT_DRIVERMGR
13115 if (dsn[0] && !lnflag[0]) {
13116 SQLGetPrivateProfileString(dsn, "longnames", "",
13117 lnflag, sizeof (lnflag), ODBC_INI);
13118 }
13119#endif
13120 ncflag[0] = '\0';
13121 getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
13122#ifndef WITHOUT_DRIVERMGR
13123 if (dsn[0] && !ncflag[0]) {
13124 SQLGetPrivateProfileString(dsn, "nocreat", "",
13125 ncflag, sizeof (ncflag), ODBC_INI);
13126 }
13127#endif
13128 nwflag[0] = '\0';
13129 getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
13130#ifndef WITHOUT_DRIVERMGR
13131 if (dsn[0] && !nwflag[0]) {
13132 SQLGetPrivateProfileString(dsn, "nowchar", "",
13133 nwflag, sizeof (nwflag), ODBC_INI);
13134 }
13135#endif
13136 fkflag[0] = '\0';
13137 getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
13138#ifndef WITHOUT_DRIVERMGR
13139 if (dsn[0] && !fkflag[0]) {
13140 SQLGetPrivateProfileString(dsn, "fksupport", "",
13141 fkflag, sizeof (fkflag), ODBC_INI);
13142 }
13143#endif
13144 loadext[0] = '\0';
13145 getdsnattr(buf, "loadext", loadext, sizeof (loadext));
13146#ifndef WITHOUT_DRIVERMGR
13147 if (dsn[0] && !loadext[0]) {
13148 SQLGetPrivateProfileString(dsn, "loadext", "",
13149 loadext, sizeof (loadext), ODBC_INI);
13150 }
13151#endif
13152 jmode[0] = '\0';
13153 getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
13154#ifndef WITHOUT_DRIVERMGR
13155 if (dsn[0] && !jmode[0]) {
13156 SQLGetPrivateProfileString(dsn, "journalmode", "",
13157 jmode, sizeof (jmode), ODBC_INI);
13158 }
13159#endif
13160 biflag[0] = '\0';
13161 getdsnattr(buf, "bigint", biflag, sizeof (biflag));
13162#ifndef WITHOUT_DRIVERMGR
13163 if (dsn[0] && !biflag[0]) {
13164 SQLGetPrivateProfileString(dsn, "bigint", "",
13165 biflag, sizeof (biflag), ODBC_INI);
13166 }
13167#endif
13168 jdflag[0] = '\0';
13169 getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
13170#ifndef WITHOUT_DRIVERMGR
13171 if (dsn[0] && !jdflag[0]) {
13172 SQLGetPrivateProfileString(dsn, "jdconv", "",
13173 jdflag, sizeof (jdflag), ODBC_INI);
13174 }
13175#endif
13176 pwd[0] = '\0';
13177 getdsnattr(buf, "pwd", pwd, sizeof (pwd));
13178#ifndef WITHOUT_DRIVERMGR
13179 if (dsn[0] && !pwd[0]) {
13180 SQLGetPrivateProfileString(dsn, "pwd", "",
13181 pwd, sizeof (pwd), ODBC_INI);
13182 }
13183#endif
13184
13185 if (!dbname[0] && !dsn[0]) {
13186 strcpy(dsn, "SQLite");
13187 strncpy(dbname, buf, sizeof (dbname));
13188 dbname[sizeof (dbname) - 1] = '\0';
13189 }
13190 tracef[0] = '\0';
13191 getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
13192#ifndef WITHOUT_DRIVERMGR
13193 if (dsn[0] && !tracef[0]) {
13194 SQLGetPrivateProfileString(dsn, "tracefile", "",
13195 tracef, sizeof (tracef), ODBC_INI);
13196 }
13197#endif
13198 if (connOut || connOutLen) {
13199 int count;
13200
13201 buf[0] = '\0';
13202 count = snprintf(buf, sizeof (buf),
13203 "DSN=%s;Database=%s;StepAPI=%s;Timeout=%s;"
13204 "SyncPragma=%s;NoTXN=%s;ShortNames=%s;LongNames=%s;"
13205 "NoCreat=%s;NoWCHAR=%s;FKSupport=%s;Tracefile=%s;"
13206 "JournalMode=%s;LoadExt=%s;BigInt=%s;JDConv=%s;"
13207 "PWD=%s",
13208 dsn, dbname, sflag, busy, spflag, ntflag,
13209 snflag, lnflag, ncflag, nwflag, fkflag, tracef,
13210 jmode, loadext, biflag, jdflag, pwd);
13211 if (count < 0) {
13212 buf[sizeof (buf) - 1] = '\0';
13213 }
13214 len = min(connOutMax - 1, strlen(buf));
13215 if (connOut) {
13216 strncpy((char *) connOut, buf, len);
13217 connOut[len] = '\0';
13218 }
13219 if (connOutLen) {
13220 *connOutLen = len;
13221 }
13222 }
13223 if (tracef[0] != '\0') {
13224 d->trace = fopen(tracef, "a");
13225 }
13226 d->shortnames = getbool(snflag);
13227 d->longnames = getbool(lnflag);
13228 d->nocreat = getbool(ncflag);
13229 d->nowchar = getbool(nwflag);
13230 d->fksupport = getbool(fkflag);
13231 d->dobigint = getbool(biflag);
13232 d->jdconv = getbool(jdflag);
13233 d->oemcp = 0;
13234 d->pwdLen = strlen(pwd);
13235 d->pwd = (d->pwdLen > 0) ? pwd : NULL;
13236 ret = dbopen(d, dbname, 0, dsn, sflag, spflag, ntflag, jmode, busy);
13237 memset(pwd, 0, sizeof (pwd));
13238 if (ret == SQL_SUCCESS) {
13239 dbloadext(d, loadext);
13240 }
13241 return ret;
13242}
13243#endif
13244
13251static SQLRETURN
13253{
13254 STMT *s;
13255 DBC *d;
13256
13257 if (stmt == SQL_NULL_HSTMT) {
13258 return SQL_INVALID_HANDLE;
13259 }
13260 s = (STMT *) stmt;
13261 s3stmt_drop(s);
13262 freeresult(s, 1);
13263 freep(&s->query);
13264 d = (DBC *) s->dbc;
13265 if (d && d->magic == DBC_MAGIC) {
13266 STMT *p, *n;
13267
13268 p = NULL;
13269 n = d->stmt;
13270 while (n) {
13271 if (n == s) {
13272 break;
13273 }
13274 p = n;
13275 n = n->next;
13276 }
13277 if (n) {
13278 if (p) {
13279 p->next = s->next;
13280 } else {
13281 d->stmt = s->next;
13282 }
13283 }
13284 }
13285 freeparams(s);
13286 freep(&s->bindparms);
13287 if (s->row_status0 != &s->row_status1) {
13288 freep(&s->row_status0);
13289 s->rowset_size = 1;
13290 s->row_status0 = &s->row_status1;
13291 }
13292 xfree(s);
13293 return SQL_SUCCESS;
13294}
13295
13303static SQLRETURN
13304drvallocstmt(SQLHDBC dbc, SQLHSTMT *stmt)
13305{
13306 DBC *d;
13307 STMT *s, *sl, *pl;
13308
13309 if (dbc == SQL_NULL_HDBC) {
13310 return SQL_INVALID_HANDLE;
13311 }
13312 d = (DBC *) dbc;
13313 if (d->magic != DBC_MAGIC || stmt == NULL) {
13314 return SQL_INVALID_HANDLE;
13315 }
13316 s = (STMT *) xmalloc(sizeof (STMT));
13317 if (s == NULL) {
13318 *stmt = SQL_NULL_HSTMT;
13319 return SQL_ERROR;
13320 }
13321 *stmt = (SQLHSTMT) s;
13322 memset(s, 0, sizeof (STMT));
13323 s->dbc = dbc;
13324 s->ov3 = d->ov3;
13325 s->bkmrk = SQL_UB_OFF;
13326 s->bkmrkptr = 0;
13327 s->oemcp = &d->oemcp;
13328 s->jdconv = &d->jdconv;
13329 s->nowchar[0] = d->nowchar;
13330 s->nowchar[1] = 0;
13331 s->dobigint = d->dobigint;
13332 s->curtype = d->curtype;
13333 s->row_status0 = &s->row_status1;
13334 s->rowset_size = 1;
13335 s->longnames = d->longnames;
13336 s->retr_data = SQL_RD_ON;
13337 s->max_rows = 0;
13338 s->bind_type = SQL_BIND_BY_COLUMN;
13339 s->bind_offs = NULL;
13340 s->paramset_size = 1;
13341 s->parm_bind_type = SQL_PARAM_BIND_BY_COLUMN;
13342 s->one_tbl = -1;
13343 s->has_pk = -1;
13344 s->has_rowid = -1;
13345#ifdef _WIN64
13346 sprintf((char *) s->cursorname, "CUR_%I64X", (SQLUBIGINT) *stmt);
13347#else
13348 sprintf((char *) s->cursorname, "CUR_%016lX", (long) *stmt);
13349#endif
13350 sl = d->stmt;
13351 pl = NULL;
13352 while (sl) {
13353 pl = sl;
13354 sl = sl->next;
13355 }
13356 if (pl) {
13357 pl->next = s;
13358 } else {
13359 d->stmt = s;
13360 }
13361 return SQL_SUCCESS;
13362}
13363
13371SQLRETURN SQL_API
13372SQLAllocStmt(SQLHDBC dbc, SQLHSTMT *stmt)
13373{
13374 SQLRETURN ret;
13375
13376 HDBC_LOCK(dbc);
13377 ret = drvallocstmt(dbc, stmt);
13379 return ret;
13380}
13381
13389static SQLRETURN
13390drvfreestmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13391{
13392 STMT *s;
13393 SQLRETURN ret = SQL_SUCCESS;
13394 SQLHDBC dbc;
13395
13396 if (stmt == SQL_NULL_HSTMT) {
13397 return SQL_INVALID_HANDLE;
13398 }
13400 s = (STMT *) stmt;
13401 dbc = s->dbc;
13402 switch (opt) {
13403 case SQL_RESET_PARAMS:
13404 freeparams(s);
13405 break;
13406 case SQL_UNBIND:
13407 unbindcols(s);
13408 break;
13409 case SQL_CLOSE:
13410 s3stmt_end_if(s);
13411 freeresult(s, 0);
13412 break;
13413 case SQL_DROP:
13414 s3stmt_end_if(s);
13415 ret = freestmt(stmt);
13416 break;
13417 default:
13418 setstat(s, -1, "unsupported option", (*s->ov3) ? "HYC00" : "S1C00");
13419 ret = SQL_ERROR;
13420 break;
13421 }
13423 return ret;
13424}
13425
13433SQLRETURN SQL_API
13434SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13435{
13436 return drvfreestmt(stmt, opt);
13437}
13438
13445SQLRETURN SQL_API
13447{
13448 if (stmt != SQL_NULL_HSTMT) {
13449 DBC *d = (DBC *) ((STMT *) stmt)->dbc;
13450#if defined(_WIN32) || defined(_WIN64)
13451 /* interrupt when other thread owns critical section */
13452 if (d->magic == DBC_MAGIC && d->owner != GetCurrentThreadId() &&
13453 d->owner != 0) {
13454 d->busyint = 1;
13455 sqlite3_interrupt(d->sqlite);
13456 return SQL_SUCCESS;
13457 }
13458#else
13459 if (d->magic == DBC_MAGIC) {
13460 d->busyint = 1;
13461 sqlite3_interrupt(d->sqlite);
13462 }
13463#endif
13464 }
13465 return drvfreestmt(stmt, SQL_CLOSE);
13466}
13467
13477static SQLRETURN
13478drvgetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13479 SQLSMALLINT *lenp)
13480{
13481 STMT *s;
13482
13483 if (stmt == SQL_NULL_HSTMT) {
13484 return SQL_INVALID_HANDLE;
13485 }
13486 s = (STMT *) stmt;
13487 if (lenp && !cursor) {
13488 *lenp = strlen((char *) s->cursorname);
13489 return SQL_SUCCESS;
13490 }
13491 if (cursor) {
13492 if (buflen > 0) {
13493 strncpy((char *) cursor, (char *) s->cursorname, buflen - 1);
13494 cursor[buflen - 1] = '\0';
13495 }
13496 if (lenp) {
13497 *lenp = min(strlen((char *) s->cursorname), buflen - 1);
13498 }
13499 }
13500 return SQL_SUCCESS;
13501}
13502
13503#ifndef WINTERFACE
13513SQLRETURN SQL_API
13514SQLGetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13515 SQLSMALLINT *lenp)
13516{
13517 SQLRETURN ret;
13518#if defined(_WIN32) || defined(_WIN64)
13519 SQLSMALLINT len = 0;
13520#endif
13521
13523#if defined(_WIN32) || defined(_WIN64)
13524 if (!((STMT *) stmt)->oemcp[0]) {
13525 ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13526 goto done;
13527 }
13528 ret = drvgetcursorname(stmt, cursor, buflen, &len);
13529 if (ret == SQL_SUCCESS) {
13530 char *c = NULL;
13531
13532 if (cursor) {
13533 c = utf_to_wmb((char *) cursor, len);
13534 if (!c) {
13535 ret = nomem((STMT *) stmt);
13536 goto done;
13537 }
13538 c[len] = 0;
13539 len = strlen(c);
13540 if (buflen > 0) {
13541 strncpy((char *) cursor, c, buflen - 1);
13542 cursor[buflen - 1] = 0;
13543 }
13544 uc_free(c);
13545 }
13546 if (lenp) {
13547 *lenp = min(len, buflen - 1);
13548 }
13549 }
13550done:
13551 ;
13552#else
13553 ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13554#endif
13556 return ret;
13557}
13558#endif
13559
13560#ifdef WINTERFACE
13570SQLRETURN SQL_API
13571SQLGetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT buflen,
13572 SQLSMALLINT *lenp)
13573{
13574 SQLRETURN ret;
13575 SQLSMALLINT len = 0;
13576
13578 ret = drvgetcursorname(stmt, (SQLCHAR *) cursor, buflen, &len);
13579 if (ret == SQL_SUCCESS) {
13580 SQLWCHAR *c = NULL;
13581
13582 if (cursor) {
13583 c = uc_from_utf((SQLCHAR *) cursor, len);
13584 if (!c) {
13585 ret = nomem((STMT *) stmt);
13586 goto done;
13587 }
13588 c[len] = 0;
13589 len = uc_strlen(c);
13590 if (buflen > 0) {
13591 uc_strncpy(cursor, c, buflen - 1);
13592 cursor[buflen - 1] = 0;
13593 }
13594 uc_free(c);
13595 }
13596 if (lenp) {
13597 *lenp = min(len, buflen - 1);
13598 }
13599 }
13600done:
13602 return ret;
13603}
13604#endif
13605
13614static SQLRETURN
13615drvsetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13616{
13617 STMT *s;
13618
13619 if (stmt == SQL_NULL_HSTMT) {
13620 return SQL_INVALID_HANDLE;
13621 }
13622 s = (STMT *) stmt;
13623 if (!cursor ||
13624 !((cursor[0] >= 'A' && cursor[0] <= 'Z') ||
13625 (cursor[0] >= 'a' && cursor[0] <= 'z'))) {
13626 setstat(s, -1, "invalid cursor name", (*s->ov3) ? "HYC00" : "S1C00");
13627 return SQL_ERROR;
13628 }
13629 if (len == SQL_NTS) {
13630 len = sizeof (s->cursorname) - 1;
13631 } else {
13632 len = min(sizeof (s->cursorname) - 1, len);
13633 }
13634 strncpy((char *) s->cursorname, (char *) cursor, len);
13635 s->cursorname[len] = '\0';
13636 return SQL_SUCCESS;
13637}
13638
13639#ifndef WINTERFACE
13648SQLRETURN SQL_API
13649SQLSetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13650{
13651#if defined(_WIN32) || defined(_WIN64)
13652 char *c = NULL;
13653#endif
13654 SQLRETURN ret;
13655
13657#if defined(_WIN32) || defined(_WIN64)
13658 if (!((STMT *) stmt)->oemcp[0]) {
13659 ret = drvsetcursorname(stmt, cursor, len);
13660 goto done2;
13661 }
13662 if (cursor) {
13663 c = wmb_to_utf_c((char *) cursor, len);
13664 if (!c) {
13665 ret = nomem((STMT *) stmt);
13666 goto done;
13667 }
13668 }
13669 ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13670#else
13671 ret = drvsetcursorname(stmt, cursor, len);
13672#endif
13673#if defined(_WIN32) || defined(_WIN64)
13674done:
13675 uc_free(c);
13676done2:
13677 ;
13678#endif
13680 return ret;
13681}
13682#endif
13683
13684#ifdef WINTERFACE
13693SQLRETURN SQL_API
13694SQLSetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT len)
13695{
13696 char *c = NULL;
13697 SQLRETURN ret;
13698
13700 if (cursor) {
13701 c = uc_to_utf_c(cursor, len);
13702 if (!c) {
13703 ret = nomem((STMT *) stmt);
13704 goto done;
13705 }
13706 }
13707 ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13708done:
13709 uc_free(c);
13711 return ret;
13712}
13713#endif
13714
13721SQLRETURN SQL_API
13723{
13724 return drvfreestmt(stmt, SQL_CLOSE);
13725}
13726
13735SQLRETURN SQL_API
13736SQLAllocHandle(SQLSMALLINT type, SQLHANDLE input, SQLHANDLE *output)
13737{
13738 SQLRETURN ret;
13739
13740 switch (type) {
13741 case SQL_HANDLE_ENV:
13742 ret = drvallocenv((SQLHENV *) output);
13743 if (ret == SQL_SUCCESS) {
13744 ENV *e = (ENV *) *output;
13745
13746 if (e && e->magic == ENV_MAGIC) {
13747 e->ov3 = 1;
13748 }
13749 }
13750 return ret;
13751 case SQL_HANDLE_DBC:
13752 return drvallocconnect((SQLHENV) input, (SQLHDBC *) output);
13753 case SQL_HANDLE_STMT:
13754 HDBC_LOCK((SQLHDBC) input);
13755 ret = drvallocstmt((SQLHDBC) input, (SQLHSTMT *) output);
13756 HDBC_UNLOCK((SQLHDBC) input);
13757 return ret;
13758 }
13759 return SQL_ERROR;
13760}
13761
13769SQLRETURN SQL_API
13770SQLFreeHandle(SQLSMALLINT type, SQLHANDLE h)
13771{
13772 switch (type) {
13773 case SQL_HANDLE_ENV:
13774 return drvfreeenv((SQLHENV) h);
13775 case SQL_HANDLE_DBC:
13776 return drvfreeconnect((SQLHDBC) h);
13777 case SQL_HANDLE_STMT:
13778 return drvfreestmt((SQLHSTMT) h, SQL_DROP);
13779 }
13780 return SQL_ERROR;
13781}
13782
13788static void
13790{
13791 if (s->dyncols) {
13792 int i;
13793
13794 for (i = 0; i < s->dcols; i++) {
13795 freep(&s->dyncols[i].typename);
13796 }
13797 if (s->cols == s->dyncols) {
13798 s->cols = NULL;
13799 s->ncols = 0;
13800 }
13801 freep(&s->dyncols);
13802 }
13803 s->dcols = 0;
13804}
13805
13817static void
13818freeresult(STMT *s, int clrcols)
13819{
13820 freep(&s->bincache);
13821 s->bincell = NULL;
13822 s->binlen = 0;
13823 if (s->rows) {
13824 if (s->rowfree) {
13825 s->rowfree(s->rows);
13826 s->rowfree = NULL;
13827 }
13828 s->rows = NULL;
13829 }
13830 s->nrows = -1;
13831 if (clrcols > 0) {
13832 freep(&s->bindcols);
13833 s->nbindcols = 0;
13834 }
13835 if (clrcols) {
13836 freedyncols(s);
13837 s->cols = NULL;
13838 s->ncols = 0;
13839 s->nowchar[1] = 0;
13840 s->one_tbl = -1;
13841 s->has_pk = -1;
13842 s->has_rowid = -1;
13843 }
13844}
13845
13851static void
13853{
13854 int i;
13855
13856 for (i = 0; s->bindcols && i < s->nbindcols; i++) {
13857 s->bindcols[i].type = SQL_UNKNOWN_TYPE;
13858 s->bindcols[i].max = 0;
13859 s->bindcols[i].lenp = NULL;
13860 s->bindcols[i].valp = NULL;
13861 s->bindcols[i].index = i;
13862 s->bindcols[i].offs = 0;
13863 }
13864}
13865
13873static SQLRETURN
13874mkbindcols(STMT *s, int ncols)
13875{
13876 if (s->bindcols) {
13877 if (s->nbindcols < ncols) {
13878 int i;
13879 BINDCOL *bindcols =
13880 xrealloc(s->bindcols, ncols * sizeof (BINDCOL));
13881
13882 if (!bindcols) {
13883 return nomem(s);
13884 }
13885 for (i = s->nbindcols; i < ncols; i++) {
13886 bindcols[i].type = SQL_UNKNOWN_TYPE;
13887 bindcols[i].max = 0;
13888 bindcols[i].lenp = NULL;
13889 bindcols[i].valp = NULL;
13890 bindcols[i].index = i;
13891 bindcols[i].offs = 0;
13892 }
13893 s->bindcols = bindcols;
13894 s->nbindcols = ncols;
13895 }
13896 } else if (ncols > 0) {
13897 s->bindcols = (BINDCOL *) xmalloc(ncols * sizeof (BINDCOL));
13898 if (!s->bindcols) {
13899 return nomem(s);
13900 }
13901 s->nbindcols = ncols;
13902 unbindcols(s);
13903 }
13904 return SQL_SUCCESS;
13905}
13906
13920static SQLRETURN
13921getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype,
13922 SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp, int partial)
13923{
13924 char **data, valdummy[16];
13925 SQLLEN dummy;
13926 SQLINTEGER *ilenp = NULL;
13927 int valnull = 0;
13928 int type = otype;
13929 SQLRETURN sret = SQL_NO_DATA;
13930
13931 if (!lenp) {
13932 lenp = &dummy;
13933 }
13934 /* workaround for JDK 1.7.0 on x86_64 */
13935 if (((SQLINTEGER *) lenp) + 1 == (SQLINTEGER *) val) {
13936 ilenp = (SQLINTEGER *) lenp;
13937 lenp = &dummy;
13938 }
13939 if (col >= s->ncols) {
13940 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
13941 return SQL_ERROR;
13942 }
13943 if (s->retr_data != SQL_RD_ON) {
13944 return SQL_SUCCESS;
13945 }
13946 if (!s->rows) {
13947 *lenp = SQL_NULL_DATA;
13948 goto done;
13949 }
13950 if (s->rowp < 0 || s->rowp >= s->nrows) {
13951 *lenp = SQL_NULL_DATA;
13952 goto done;
13953 }
13954 type = mapdeftype(type, s->cols[col].type, s->cols[col].nosign ? 1 : 0,
13955 s->nowchar[0]);
13956#if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
13957 /* MS Access hack part 3 (map SQL_C_DEFAULT to SQL_C_CHAR) */
13958 if (type == SQL_C_WCHAR && otype == SQL_C_DEFAULT) {
13959 type = SQL_C_CHAR;
13960 }
13961#endif
13962 data = s->rows + s->ncols + (s->rowp * s->ncols) + col;
13963 if (!val) {
13964 valnull = 1;
13965 val = (SQLPOINTER) valdummy;
13966 }
13967 if (*data == NULL) {
13968 *lenp = SQL_NULL_DATA;
13969 switch (type) {
13970 case SQL_C_UTINYINT:
13971 case SQL_C_TINYINT:
13972 case SQL_C_STINYINT:
13973#ifdef SQL_BIT
13974 case SQL_C_BIT:
13975#endif
13976 *((SQLCHAR *) val) = 0;
13977 break;
13978 case SQL_C_USHORT:
13979 case SQL_C_SHORT:
13980 case SQL_C_SSHORT:
13981 *((SQLSMALLINT *) val) = 0;
13982 break;
13983 case SQL_C_ULONG:
13984 case SQL_C_LONG:
13985 case SQL_C_SLONG:
13986 *((SQLINTEGER *) val) = 0;
13987 break;
13988#ifdef SQL_BIGINT
13989 case SQL_C_SBIGINT:
13990 case SQL_C_UBIGINT:
13991 *((SQLBIGINT *) val) = 0;
13992 break;
13993#endif
13994 case SQL_C_FLOAT:
13995 *((float *) val) = 0;
13996 break;
13997 case SQL_C_DOUBLE:
13998 *((double *) val) = 0;
13999 break;
14000 case SQL_C_BINARY:
14001 case SQL_C_CHAR:
14002 if (len > 0) {
14003 *((SQLCHAR *) val) = '\0';
14004 }
14005 break;
14006#ifdef WCHARSUPPORT
14007 case SQL_C_WCHAR:
14008 if (len > 0) {
14009 *((SQLWCHAR *) val) = '\0';
14010 }
14011 break;
14012#endif
14013#ifdef SQL_C_TYPE_DATE
14014 case SQL_C_TYPE_DATE:
14015#endif
14016 case SQL_C_DATE:
14017 memset((DATE_STRUCT *) val, 0, sizeof (DATE_STRUCT));
14018 break;
14019#ifdef SQL_C_TYPE_TIME
14020 case SQL_C_TYPE_TIME:
14021#endif
14022 case SQL_C_TIME:
14023 memset((TIME_STRUCT *) val, 0, sizeof (TIME_STRUCT));
14024 break;
14025#ifdef SQL_C_TYPE_TIMESTAMP
14026 case SQL_C_TYPE_TIMESTAMP:
14027#endif
14028 case SQL_C_TIMESTAMP:
14029 memset((TIMESTAMP_STRUCT *) val, 0, sizeof (TIMESTAMP_STRUCT));
14030 break;
14031 default:
14032 return SQL_ERROR;
14033 }
14034 } else {
14035 char *endp = NULL;
14036#if defined(_WIN32) || defined(_WIN64)
14037#ifdef SQL_BIGINT
14038 char endc;
14039#endif
14040#endif
14041
14042 switch (type) {
14043 case SQL_C_UTINYINT:
14044 case SQL_C_TINYINT:
14045 case SQL_C_STINYINT:
14046 *((SQLCHAR *) val) = strtol(*data, &endp, 0);
14047 if (endp && endp == *data) {
14048 *lenp = SQL_NULL_DATA;
14049 } else {
14050 *lenp = sizeof (SQLCHAR);
14051 }
14052 break;
14053#ifdef SQL_BIT
14054 case SQL_C_BIT:
14055 *((SQLCHAR *) val) = getbool(*data);
14056 *lenp = sizeof (SQLCHAR);
14057 break;
14058#endif
14059 case SQL_C_USHORT:
14060 case SQL_C_SHORT:
14061 case SQL_C_SSHORT:
14062 *((SQLSMALLINT *) val) = strtol(*data, &endp, 0);
14063 if (endp && endp == *data) {
14064 *lenp = SQL_NULL_DATA;
14065 } else {
14066 *lenp = sizeof (SQLSMALLINT);
14067 }
14068 break;
14069 case SQL_C_ULONG:
14070 case SQL_C_LONG:
14071 case SQL_C_SLONG:
14072 *((SQLINTEGER *) val) = strtol(*data, &endp, 0);
14073 if (endp && endp == *data) {
14074 *lenp = SQL_NULL_DATA;
14075 } else {
14076 *lenp = sizeof (SQLINTEGER);
14077 }
14078 break;
14079#ifdef SQL_BIGINT
14080 case SQL_C_UBIGINT:
14081#if defined(_WIN32) || defined(_WIN64)
14082 if (sscanf(*data, "%I64u%c", (SQLUBIGINT *) val, &endc) != 1) {
14083 *lenp = SQL_NULL_DATA;
14084 } else {
14085 *lenp = sizeof (SQLUBIGINT);
14086 }
14087#else
14088#ifdef __osf__
14089 *((SQLUBIGINT *) val) = strtoul(*data, &endp, 0);
14090#else
14091 *((SQLUBIGINT *) val) = strtoull(*data, &endp, 0);
14092#endif
14093 if (endp && endp == *data) {
14094 *lenp = SQL_NULL_DATA;
14095 } else {
14096 *lenp = sizeof (SQLUBIGINT);
14097 }
14098#endif
14099 break;
14100 case SQL_C_SBIGINT:
14101#if defined(_WIN32) || defined(_WIN64)
14102 if (sscanf(*data, "%I64d%c", (SQLBIGINT *) val, &endc) != 1) {
14103 *lenp = SQL_NULL_DATA;
14104 } else {
14105 *lenp = sizeof (SQLBIGINT);
14106 }
14107#else
14108#ifdef __osf__
14109 *((SQLBIGINT *) val) = strtol(*data, &endp, 0);
14110#else
14111 *((SQLBIGINT *) val) = strtoll(*data, &endp, 0);
14112#endif
14113 if (endp && endp == *data) {
14114 *lenp = SQL_NULL_DATA;
14115 } else {
14116 *lenp = sizeof (SQLBIGINT);
14117 }
14118#endif
14119 break;
14120#endif
14121 case SQL_C_FLOAT:
14122 *((float *) val) = ln_strtod(*data, &endp);
14123 if (endp && endp == *data) {
14124 *lenp = SQL_NULL_DATA;
14125 } else {
14126 *lenp = sizeof (float);
14127 }
14128 break;
14129 case SQL_C_DOUBLE:
14130 *((double *) val) = ln_strtod(*data, &endp);
14131 if (endp && endp == *data) {
14132 *lenp = SQL_NULL_DATA;
14133 } else {
14134 *lenp = sizeof (double);
14135 }
14136 break;
14137 case SQL_C_BINARY: {
14138 int dlen, offs = 0;
14139 char *bin;
14140
14141 if (valnull) {
14142 freep(&s->bincache);
14143 s->binlen = 0;
14144 goto doCHAR;
14145 }
14146 if (*data == s->bincell) {
14147 if (s->bincache) {
14148 bin = s->bincache;
14149 dlen = s->binlen;
14150 } else {
14151 goto doCHAR;
14152 }
14153 } else {
14154 char *dp;
14155 int i;
14156
14157 freep(&s->bincache);
14158 dp = *data;
14159 dlen = strlen(dp);
14160 s->bincell = dp;
14161 s->binlen = 0;
14162 if (!(dp[0] == 'x' || dp[0] == 'X') || dp[1] != '\'' ||
14163 dp[dlen - 1] != '\'') {
14164 goto doCHAR;
14165 }
14166 dlen -= 2;
14167 dp += 2;
14168 dlen = dlen / 2;
14169 s->bincache = bin = xmalloc(dlen + 1);
14170 if (!bin) {
14171 return nomem(s);
14172 }
14173 s->binlen = dlen;
14174 memset(bin, 0, dlen);
14175 bin[dlen] = '\0'; /* terminator, just in case */
14176 for (i = 0; i < dlen; i++) {
14177 char *x;
14178 int v;
14179
14180 if (!*dp || !(x = strchr(xdigits, *dp))) {
14181 goto converr;
14182 }
14183 v = x - xdigits;
14184 bin[i] = (v >= 16) ? ((v - 6) << 4) : (v << 4);
14185 ++dp;
14186 if (!*dp || !(x = strchr(xdigits, *dp))) {
14187converr:
14188 freep(&s->bincache);
14189 s->binlen = 0;
14190 setstat(s, -1, "conversion error",
14191 (*s->ov3) ? "HY000" : "S1000");
14192 return SQL_ERROR;
14193 }
14194 v = x - xdigits;
14195 bin[i] |= (v >= 16) ? (v - 6) : v;
14196 ++dp;
14197 }
14198 bin = s->bincache;
14199 }
14200 if (partial && len && s->bindcols) {
14201 if (s->bindcols[col].offs >= dlen) {
14202 *lenp = 0;
14203 if (!dlen && s->bindcols[col].offs == dlen) {
14204 s->bindcols[col].offs = 1;
14205 sret = SQL_SUCCESS;
14206 goto done;
14207 }
14208 s->bindcols[col].offs = 0;
14209 sret = SQL_NO_DATA;
14210 goto done;
14211 }
14212 offs = s->bindcols[col].offs;
14213 dlen -= offs;
14214 }
14215 if (val && len) {
14216 memcpy(val, bin + offs, min(len, dlen));
14217 }
14218 if (len < 1) {
14219 *lenp = dlen;
14220 } else {
14221 *lenp = min(len, dlen);
14222 if (*lenp == len && *lenp != dlen) {
14223 *lenp = SQL_NO_TOTAL;
14224 }
14225 }
14226 if (partial && len && s->bindcols) {
14227 if (*lenp == SQL_NO_TOTAL) {
14228 *lenp = dlen;
14229 s->bindcols[col].offs += len;
14230 setstat(s, -1, "data right truncated", "01004");
14231 if (s->bindcols[col].lenp) {
14232 *s->bindcols[col].lenp = dlen;
14233 }
14234 sret = SQL_SUCCESS_WITH_INFO;
14235 goto done;
14236 }
14237 s->bindcols[col].offs += *lenp;
14238 }
14239 if (*lenp == SQL_NO_TOTAL) {
14240 *lenp = dlen;
14241 setstat(s, -1, "data right truncated", "01004");
14242 sret = SQL_SUCCESS_WITH_INFO;
14243 goto done;
14244 }
14245 break;
14246 }
14247 doCHAR:
14248#ifdef WCHARSUPPORT
14249 case SQL_C_WCHAR:
14250#endif
14251 case SQL_C_CHAR: {
14252 int doz, zlen = len - 1;
14253 int dlen = strlen(*data);
14254 int offs = 0;
14255#ifdef WCHARSUPPORT
14256 SQLWCHAR *ucdata = NULL;
14257 SQLCHAR *cdata = (SQLCHAR *) *data;
14258#endif
14259
14260#if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
14261 /* MS Access hack part 2 (reserved error -7748) */
14262 if (!valnull &&
14263 (s->cols == statSpec2P || s->cols == statSpec3P) &&
14264 type == SQL_C_WCHAR) {
14265 if (len > 0 && len <= sizeof (SQLWCHAR)) {
14266 ((char *) val)[0] = data[0][0];
14267 memset((char *) val + 1, 0, len - 1);
14268 *lenp = 1;
14269 sret = SQL_SUCCESS;
14270 goto done;
14271 }
14272 }
14273#endif
14274
14275#ifdef WCHARSUPPORT
14276 switch (type) {
14277 case SQL_C_CHAR:
14278 doz = 1;
14279 break;
14280 case SQL_C_WCHAR:
14281 doz = sizeof (SQLWCHAR);
14282 break;
14283 default:
14284 doz = 0;
14285 break;
14286 }
14287 if (type == SQL_C_WCHAR) {
14288 ucdata = uc_from_utf(cdata, dlen);
14289 if (!ucdata) {
14290 return nomem(s);
14291 }
14292 dlen = uc_strlen(ucdata) * sizeof (SQLWCHAR);
14293 }
14294#if defined(_WIN32) || defined(_WIN64)
14295 else if (*s->oemcp && type == SQL_C_CHAR) {
14296 ucdata = (SQLWCHAR *) utf_to_wmb((char *) cdata, dlen);
14297 if (!ucdata) {
14298 return nomem(s);
14299 }
14300 cdata = (SQLCHAR *) ucdata;
14301 dlen = strlen((char *) cdata);
14302 }
14303#endif
14304#else
14305 doz = (type == SQL_C_CHAR) ? 1 : 0;
14306#endif
14307 if (partial && len && s->bindcols) {
14308 if (s->bindcols[col].offs >= dlen) {
14309#ifdef WCHARSUPPORT
14310 uc_free(ucdata);
14311#endif
14312 *lenp = 0;
14313 if (doz && val) {
14314#ifdef WCHARSUPPORT
14315 if (type == SQL_C_WCHAR) {
14316 ((SQLWCHAR *) val)[0] = 0;
14317 } else {
14318 ((char *) val)[0] = '\0';
14319 }
14320#else
14321 ((char *) val)[0] = '\0';
14322#endif
14323 }
14324 if (!dlen && s->bindcols[col].offs == dlen) {
14325 s->bindcols[col].offs = 1;
14326 sret = SQL_SUCCESS;
14327 goto done;
14328 }
14329 s->bindcols[col].offs = 0;
14330 sret = SQL_NO_DATA;
14331 goto done;
14332 }
14333 offs = s->bindcols[col].offs;
14334 dlen -= offs;
14335 }
14336 if (val && !valnull && len) {
14337#ifdef WCHARSUPPORT
14338 if (type == SQL_C_WCHAR) {
14339 uc_strncpy(val, ucdata + offs / sizeof (SQLWCHAR),
14340 (len - doz) / sizeof (SQLWCHAR));
14341 } else {
14342 strncpy(val, (char *) cdata + offs, len - doz);
14343 }
14344#else
14345 strncpy(val, *data + offs, len - doz);
14346#endif
14347 }
14348 if (valnull || len < 1) {
14349 *lenp = dlen;
14350 } else {
14351 *lenp = min(len - doz, dlen);
14352 if (*lenp == len - doz && *lenp != dlen) {
14353 *lenp = SQL_NO_TOTAL;
14354 } else if (*lenp < zlen) {
14355 zlen = *lenp;
14356 }
14357 }
14358 if (len && !valnull && doz) {
14359#ifdef WCHARSUPPORT
14360 if (type == SQL_C_WCHAR) {
14361 ((SQLWCHAR *) val)[zlen / sizeof (SQLWCHAR)] = 0;
14362 } else {
14363 ((char *) val)[zlen] = '\0';
14364 }
14365#else
14366 ((char *) val)[zlen] = '\0';
14367#endif
14368 }
14369#ifdef WCHARSUPPORT
14370 uc_free(ucdata);
14371#endif
14372 if (partial && len && s->bindcols) {
14373 if (*lenp == SQL_NO_TOTAL) {
14374 *lenp = dlen;
14375 s->bindcols[col].offs += len - doz;
14376 setstat(s, -1, "data right truncated", "01004");
14377 if (s->bindcols[col].lenp) {
14378 *s->bindcols[col].lenp = dlen;
14379 }
14380 sret = SQL_SUCCESS_WITH_INFO;
14381 goto done;
14382 }
14383 s->bindcols[col].offs += *lenp;
14384 }
14385 if (*lenp == SQL_NO_TOTAL) {
14386 *lenp = dlen;
14387 setstat(s, -1, "data right truncated", "01004");
14388 sret = SQL_SUCCESS_WITH_INFO;
14389 goto done;
14390 }
14391 break;
14392 }
14393#ifdef SQL_C_TYPE_DATE
14394 case SQL_C_TYPE_DATE:
14395#endif
14396 case SQL_C_DATE:
14397 if (str2date(*s->jdconv, *data, (DATE_STRUCT *) val) < 0) {
14398 *lenp = SQL_NULL_DATA;
14399 } else {
14400 *lenp = sizeof (DATE_STRUCT);
14401 }
14402 break;
14403#ifdef SQL_C_TYPE_TIME
14404 case SQL_C_TYPE_TIME:
14405#endif
14406 case SQL_C_TIME:
14407 if (str2time(*s->jdconv, *data, (TIME_STRUCT *) val) < 0) {
14408 *lenp = SQL_NULL_DATA;
14409 } else {
14410 *lenp = sizeof (TIME_STRUCT);
14411 }
14412 break;
14413#ifdef SQL_C_TYPE_TIMESTAMP
14414 case SQL_C_TYPE_TIMESTAMP:
14415#endif
14416 case SQL_C_TIMESTAMP:
14417 if (str2timestamp(*s->jdconv, *data,
14418 (TIMESTAMP_STRUCT *) val) < 0) {
14419 *lenp = SQL_NULL_DATA;
14420 } else {
14421 *lenp = sizeof (TIMESTAMP_STRUCT);
14422 }
14423 switch (s->cols[col].prec) {
14424 case 0:
14425 ((TIMESTAMP_STRUCT *) val)->fraction = 0;
14426 break;
14427 case 1:
14428 ((TIMESTAMP_STRUCT *) val)->fraction /= 100000000;
14429 ((TIMESTAMP_STRUCT *) val)->fraction *= 100000000;
14430 break;
14431 case 2:
14432 ((TIMESTAMP_STRUCT *) val)->fraction /= 10000000;
14433 ((TIMESTAMP_STRUCT *) val)->fraction *= 10000000;
14434 break;
14435 }
14436 break;
14437 default:
14438 return SQL_ERROR;
14439 }
14440 }
14441 sret = SQL_SUCCESS;
14442done:
14443 if (ilenp) {
14444 *ilenp = *lenp;
14445 }
14446 return sret;
14447}
14448
14460static SQLRETURN
14461drvbindcol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14462 SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14463{
14464 STMT *s;
14465 int sz = 0;
14466
14467 if (stmt == SQL_NULL_HSTMT) {
14468 return SQL_INVALID_HANDLE;
14469 }
14470 s = (STMT *) stmt;
14471 if (col < 1) {
14472 if (col == 0 && s->bkmrk == SQL_UB_ON &&
14473 type == SQL_C_BOOKMARK) {
14474 s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14475 s->bkmrkcol.max = val ? sizeof (SQLINTEGER) : 0;
14476 s->bkmrkcol.lenp = val ? lenp : 0;
14477 s->bkmrkcol.valp = val;
14478 s->bkmrkcol.offs = 0;
14479 if (val && lenp) {
14480 *lenp = 0;
14481 }
14482 return SQL_SUCCESS;
14483 } else if (col == 0 && s->bkmrk == SQL_UB_VARIABLE &&
14484 type == SQL_C_VARBOOKMARK &&
14485 max >= sizeof (sqlite_int64)) {
14486 s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14487 s->bkmrkcol.max = val ? max : 0;
14488 s->bkmrkcol.lenp = val ? lenp : 0;
14489 s->bkmrkcol.valp = val;
14490 s->bkmrkcol.offs = 0;
14491 if (val && lenp) {
14492 *lenp = 0;
14493 }
14494 return SQL_SUCCESS;
14495 }
14496 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
14497 return SQL_ERROR;
14498 }
14499 if (mkbindcols(s, col) != SQL_SUCCESS) {
14500 return SQL_ERROR;
14501 }
14502 --col;
14503 if (type == SQL_C_DEFAULT) {
14504 type = mapdeftype(type, s->cols[col].type, 0,
14505 s->nowchar[0] || s->nowchar[1]);
14506 }
14507 switch (type) {
14508 case SQL_C_LONG:
14509 case SQL_C_ULONG:
14510 case SQL_C_SLONG:
14511 sz = sizeof (SQLINTEGER);
14512 break;
14513 case SQL_C_TINYINT:
14514 case SQL_C_UTINYINT:
14515 case SQL_C_STINYINT:
14516 sz = sizeof (SQLCHAR);
14517 break;
14518 case SQL_C_SHORT:
14519 case SQL_C_USHORT:
14520 case SQL_C_SSHORT:
14521 sz = sizeof (SQLSMALLINT);
14522 break;
14523 case SQL_C_FLOAT:
14524 sz = sizeof (SQLFLOAT);
14525 break;
14526 case SQL_C_DOUBLE:
14527 sz = sizeof (SQLDOUBLE);
14528 break;
14529 case SQL_C_TIMESTAMP:
14530 sz = sizeof (SQL_TIMESTAMP_STRUCT);
14531 break;
14532 case SQL_C_TIME:
14533 sz = sizeof (SQL_TIME_STRUCT);
14534 break;
14535 case SQL_C_DATE:
14536 sz = sizeof (SQL_DATE_STRUCT);
14537 break;
14538 case SQL_C_CHAR:
14539 break;
14540#ifdef WCHARSUPPORT
14541 case SQL_C_WCHAR:
14542 break;
14543#endif
14544#ifdef SQL_C_TYPE_DATE
14545 case SQL_C_TYPE_DATE:
14546 sz = sizeof (SQL_DATE_STRUCT);
14547 break;
14548#endif
14549#ifdef SQL_C_TYPE_TIME
14550 case SQL_C_TYPE_TIME:
14551 sz = sizeof (SQL_TIME_STRUCT);
14552 break;
14553#endif
14554#ifdef SQL_C_TYPE_TIMESTAMP
14555 case SQL_C_TYPE_TIMESTAMP:
14556 sz = sizeof (SQL_TIMESTAMP_STRUCT);
14557 break;
14558#endif
14559#ifdef SQL_BIT
14560 case SQL_C_BIT:
14561 sz = sizeof (SQLCHAR);
14562 break;
14563#endif
14564 case SQL_C_BINARY:
14565 break;
14566#ifdef SQL_BIGINT
14567 case SQL_C_SBIGINT:
14568 case SQL_C_UBIGINT:
14569 sz = sizeof (SQLBIGINT);
14570 break;
14571#endif
14572 default:
14573 if (val == NULL) {
14574 /* fall through, unbinding column */
14575 break;
14576 }
14577 setstat(s, -1, "invalid type %d", "HY003", type);
14578 return SQL_ERROR;
14579 }
14580 if (val == NULL) {
14581 /* unbind column */
14582 s->bindcols[col].type = SQL_UNKNOWN_TYPE;
14583 s->bindcols[col].max = 0;
14584 s->bindcols[col].lenp = NULL;
14585 s->bindcols[col].valp = NULL;
14586 s->bindcols[col].offs = 0;
14587 } else {
14588 if (sz == 0 && max < 0) {
14589 setstat(s, -1, "invalid length", "HY090");
14590 return SQL_ERROR;
14591 }
14592 s->bindcols[col].type = type;
14593 s->bindcols[col].max = (sz == 0) ? max : sz;
14594 s->bindcols[col].lenp = lenp;
14595 s->bindcols[col].valp = val;
14596 s->bindcols[col].offs = 0;
14597 if (lenp) {
14598 *lenp = 0;
14599 }
14600 }
14601 return SQL_SUCCESS;
14602}
14603
14615SQLRETURN SQL_API
14616SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14617 SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14618{
14619 SQLRETURN ret;
14620
14622 ret = drvbindcol(stmt, col, type, val, max, lenp);
14624 return ret;
14625}
14626
14631static COL tableSpec2[] = {
14632 { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
14633 { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
14634 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14635 { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14636 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14637};
14638
14639static COL tableSpec3[] = {
14640 { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
14641 { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
14642 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14643 { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14644 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14645};
14646
14661static SQLRETURN
14663 SQLCHAR *cat, SQLSMALLINT catLen,
14664 SQLCHAR *schema, SQLSMALLINT schemaLen,
14665 SQLCHAR *table, SQLSMALLINT tableLen,
14666 SQLCHAR *type, SQLSMALLINT typeLen)
14667{
14668 SQLRETURN ret;
14669 STMT *s;
14670 DBC *d;
14671 int ncols, asize, rc, size, npatt;
14672 char *errp = NULL, *sql, tname[512];
14673 char *where = "(type = 'table' or type = 'view')";
14674
14676 tableSpec3, array_size(tableSpec3), &asize);
14677 if (ret != SQL_SUCCESS) {
14678 return ret;
14679 }
14680 s = (STMT *) stmt;
14681 d = (DBC *) s->dbc;
14682 if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] == '%') {
14683 int size = 3 * asize;
14684
14685 s->rows = xmalloc(size * sizeof (char *));
14686 if (!s->rows) {
14687 s->nrows = 0;
14688 return nomem(s);
14689 }
14690 memset(s->rows, 0, sizeof (char *) * size);
14691 s->ncols = asize;
14692 s->rows[s->ncols + 0] = "";
14693 s->rows[s->ncols + 1] = "";
14694 s->rows[s->ncols + 2] = "";
14695 s->rows[s->ncols + 3] = "TABLE";
14696 s->rows[s->ncols + 5] = "";
14697 s->rows[s->ncols + 6] = "";
14698 s->rows[s->ncols + 7] = "";
14699 s->rows[s->ncols + 8] = "VIEW";
14700#ifdef MEMORY_DEBUG
14701 s->rowfree = xfree__;
14702#else
14703 s->rowfree = sqlite3_free;
14704#endif
14705 s->nrows = 2;
14706 s->rowp = s->rowprs = -1;
14707 return SQL_SUCCESS;
14708 }
14709 if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
14710 table = NULL;
14711 goto doit;
14712 }
14713 if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
14714 schema[0] == '%') {
14715 if ((!cat || catLen == 0 || !cat[0]) &&
14716 (!table || tableLen == 0 || !table[0])) {
14717 table = NULL;
14718 goto doit;
14719 }
14720 }
14721 if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] != '\0') {
14722 char tmp[256], *t;
14723 int with_view = 0, with_table = 0;
14724
14725 if (typeLen == SQL_NTS) {
14726 strncpy(tmp, (char *) type, sizeof (tmp));
14727 tmp[sizeof (tmp) - 1] = '\0';
14728 } else {
14729 int len = min(sizeof (tmp) - 1, typeLen);
14730
14731 strncpy(tmp, (char *) type, len);
14732 tmp[len] = '\0';
14733 }
14734 t = tmp;
14735 while (*t) {
14736 *t = TOLOWER(*t);
14737 t++;
14738 }
14739 t = tmp;
14740 unescpat(t);
14741 while (t) {
14742 if (t[0] == '\'') {
14743 ++t;
14744 }
14745 if (strncmp(t, "table", 5) == 0) {
14746 with_table++;
14747 } else if (strncmp(t, "view", 4) == 0) {
14748 with_view++;
14749 }
14750 t = strchr(t, ',');
14751 if (t) {
14752 ++t;
14753 }
14754 }
14755 if (with_view && with_table) {
14756 /* where is already preset */
14757 } else if (with_view && !with_table) {
14758 where = "type = 'view'";
14759 } else if (!with_view && with_table) {
14760 where = "type = 'table'";
14761 } else {
14762 return SQL_SUCCESS;
14763 }
14764 }
14765doit:
14766 if (!table) {
14767 size = 1;
14768 tname[0] = '%';
14769 } else {
14770 if (tableLen == SQL_NTS) {
14771 size = sizeof (tname) - 1;
14772 } else {
14773 size = min(sizeof (tname) - 1, tableLen);
14774 }
14775 strncpy(tname, (char *) table, size);
14776 }
14777 tname[size] = '\0';
14778 npatt = unescpat(tname);
14779#if defined(_WIN32) || defined(_WIN64)
14780 if (npatt) {
14781 sql = sqlite3_mprintf("select %s as 'TABLE_CAT', "
14782 "%s as 'TABLE_SCHEM', "
14783 "tbl_name as 'TABLE_NAME', "
14784 "upper(type) as 'TABLE_TYPE', "
14785 "NULL as 'REMARKS' "
14786 "from sqlite_master where %s "
14787 "and tbl_name like %Q",
14788 d->xcelqrx ? "'main'" : "NULL",
14789 d->xcelqrx ? "''" : "NULL",
14790 where, tname);
14791 } else {
14792 sql = sqlite3_mprintf("select %s as 'TABLE_CAT', "
14793 "%s as 'TABLE_SCHEM', "
14794 "tbl_name as 'TABLE_NAME', "
14795 "upper(type) as 'TABLE_TYPE', "
14796 "NULL as 'REMARKS' "
14797 "from sqlite_master where %s "
14798 "and lower(tbl_name) = lower(%Q)",
14799 d->xcelqrx ? "'main'" : "NULL",
14800 d->xcelqrx ? "''" : "NULL",
14801 where, tname);
14802 }
14803#else
14804 if (npatt) {
14805 sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
14806 "NULL as 'TABLE_OWNER', "
14807 "tbl_name as 'TABLE_NAME', "
14808 "upper(type) as 'TABLE_TYPE', "
14809 "NULL as 'REMARKS' "
14810 "from sqlite_master where %s "
14811 "and tbl_name like %Q",
14812 where, tname);
14813 } else {
14814 sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
14815 "NULL as 'TABLE_OWNER', "
14816 "tbl_name as 'TABLE_NAME', "
14817 "upper(type) as 'TABLE_TYPE', "
14818 "NULL as 'REMARKS' "
14819 "from sqlite_master where %s "
14820 "and lower(tbl_name) = lower(%Q)",
14821 where, tname);
14822 }
14823#endif
14824 if (!sql) {
14825 return nomem(s);
14826 }
14827 ret = starttran(s);
14828 if (ret != SQL_SUCCESS) {
14829 sqlite3_free(sql);
14830 return ret;
14831 }
14832 dbtraceapi(d, "sqlite3_get_table", sql);
14833 rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
14834 sqlite3_free(sql);
14835 if (rc == SQLITE_OK) {
14836 if (ncols != s->ncols) {
14837 freeresult(s, 0);
14838 s->nrows = 0;
14839 } else {
14840 s->rowfree = sqlite3_free_table;
14841 }
14842 } else {
14843 s->nrows = 0;
14844 s->rows = NULL;
14845 s->rowfree = NULL;
14846 }
14847 if (errp) {
14848 sqlite3_free(errp);
14849 errp = NULL;
14850 }
14851 s->rowp = s->rowprs = -1;
14852 return SQL_SUCCESS;
14853}
14854
14855#ifndef WINTERFACE
14870SQLRETURN SQL_API
14871SQLTables(SQLHSTMT stmt,
14872 SQLCHAR *cat, SQLSMALLINT catLen,
14873 SQLCHAR *schema, SQLSMALLINT schemaLen,
14874 SQLCHAR *table, SQLSMALLINT tableLen,
14875 SQLCHAR *type, SQLSMALLINT typeLen)
14876{
14877#if defined(_WIN32) || defined(_WIN64)
14878 char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
14879#endif
14880 SQLRETURN ret;
14881
14883#if defined(_WIN32) || defined(_WIN64)
14884 if (!((STMT *) stmt)->oemcp[0]) {
14885 ret = drvtables(stmt, cat, catLen, schema, schemaLen,
14886 table, tableLen, type, typeLen);
14887 goto done2;
14888 }
14889 if (cat) {
14890 c = wmb_to_utf_c((char *) cat, catLen);
14891 if (!c) {
14892 ret = nomem((STMT *) stmt);
14893 goto done;
14894 }
14895 }
14896 if (schema) {
14897 s = wmb_to_utf_c((char *) schema, schemaLen);
14898 if (!s) {
14899 ret = nomem((STMT *) stmt);
14900 goto done;
14901 }
14902 }
14903 if (table) {
14904 t = wmb_to_utf_c((char *) table, tableLen);
14905 if (!t) {
14906 ret = nomem((STMT *) stmt);
14907 goto done;
14908 }
14909 }
14910 if (type) {
14911 y = wmb_to_utf_c((char *) type, typeLen);
14912 if (!y) {
14913 ret = nomem((STMT *) stmt);
14914 goto done;
14915 }
14916 }
14917 ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
14918 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
14919#else
14920 ret = drvtables(stmt, cat, catLen, schema, schemaLen,
14921 table, tableLen, type, typeLen);
14922#endif
14923#if defined(_WIN32) || defined(_WIN64)
14924done:
14925 uc_free(y);
14926 uc_free(t);
14927 uc_free(s);
14928 uc_free(c);
14929done2:
14930 ;
14931#endif
14933 return ret;
14934}
14935#endif
14936
14937#ifdef WINTERFACE
14952SQLRETURN SQL_API
14954 SQLWCHAR *cat, SQLSMALLINT catLen,
14955 SQLWCHAR *schema, SQLSMALLINT schemaLen,
14956 SQLWCHAR *table, SQLSMALLINT tableLen,
14957 SQLWCHAR *type, SQLSMALLINT typeLen)
14958{
14959 char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
14960 SQLRETURN ret;
14961
14963 if (cat) {
14964 c = uc_to_utf_c(cat, catLen);
14965 if (!c) {
14966 ret = nomem((STMT *) stmt);
14967 goto done;
14968 }
14969 }
14970 if (schema) {
14971 s = uc_to_utf_c(schema, schemaLen);
14972 if (!s) {
14973 ret = nomem((STMT *) stmt);
14974 goto done;
14975 }
14976 }
14977 if (table) {
14978 t = uc_to_utf_c(table, tableLen);
14979 if (!t) {
14980 ret = nomem((STMT *) stmt);
14981 goto done;
14982 }
14983 }
14984 if (type) {
14985 y = uc_to_utf_c(type, typeLen);
14986 if (!y) {
14987 ret = nomem((STMT *) stmt);
14988 goto done;
14989 }
14990 }
14991 ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
14992 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
14993done:
14994 uc_free(y);
14995 uc_free(t);
14996 uc_free(s);
14997 uc_free(c);
14999 return ret;
15000}
15001#endif
15002
15007static COL colSpec2[] = {
15008 { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
15009 { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
15010 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
15011 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15012 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
15013 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
15014 { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
15015 { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
15016 { "SYSTEM", "COLUMN", "SCALE", SQL_SMALLINT, 50 },
15017 { "SYSTEM", "COLUMN", "RADIX", SQL_SMALLINT, 50 },
15018 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
15019 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
15020 { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
15021 { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
15022 { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
15023 { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
15024 { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
15025 { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
15026};
15027
15028static COL colSpec3[] = {
15029 { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
15030 { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
15031 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
15032 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15033 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
15034 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
15035 { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
15036 { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
15037 { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_SMALLINT, 50 },
15038 { "SYSTEM", "COLUMN", "NUM_PREC_RADIX", SQL_SMALLINT, 50 },
15039 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
15040 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
15041 { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
15042 { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
15043 { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
15044 { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
15045 { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
15046 { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
15047};
15048
15063static SQLRETURN
15065 SQLCHAR *cat, SQLSMALLINT catLen,
15066 SQLCHAR *schema, SQLSMALLINT schemaLen,
15067 SQLCHAR *table, SQLSMALLINT tableLen,
15068 SQLCHAR *col, SQLSMALLINT colLen)
15069{
15070 SQLRETURN sret;
15071 STMT *s;
15072 DBC *d;
15073 int ret, nrows, ncols, asize, i, k, roffs, namec;
15074 int tnrows, tncols, npatt;
15075 PTRDIFF_T size;
15076 char *errp = NULL, *sql, tname[512], cname[512], **rowp, **trows;
15077
15079 colSpec3, array_size(colSpec3), &asize);
15080 if (sret != SQL_SUCCESS) {
15081 return sret;
15082 }
15083 s = (STMT *) stmt;
15084 d = (DBC *) s->dbc;
15085 if (!table) {
15086 size = 1;
15087 tname[0] = '%';
15088 } else {
15089 if (tableLen == SQL_NTS) {
15090 size = sizeof (tname) - 1;
15091 } else {
15092 size = min(sizeof (tname) - 1, tableLen);
15093 }
15094 strncpy(tname, (char *) table, size);
15095 }
15096 tname[size] = '\0';
15097 npatt = unescpat(tname);
15098 size = 0;
15099 if (col) {
15100 if (colLen == SQL_NTS) {
15101 size = sizeof (cname) - 1;
15102 } else {
15103 size = min(sizeof (cname) - 1, colLen);
15104 }
15105 strncpy(cname, (char *) col, size);
15106 }
15107 cname[size] = '\0';
15108 if (!strcmp(cname, "%")) {
15109 cname[0] = '\0';
15110 }
15111 if (npatt) {
15112 sql = sqlite3_mprintf("select tbl_name from sqlite_master where "
15113 "(type = 'table' or type = 'view') "
15114 "and tbl_name like %Q", tname);
15115 } else {
15116 sql = sqlite3_mprintf("select tbl_name from sqlite_master where "
15117 "(type = 'table' or type = 'view') "
15118 "and lower(tbl_name) = lower(%Q)", tname);
15119 }
15120 if (!sql) {
15121 return nomem(s);
15122 }
15123 sret = starttran(s);
15124 if (sret != SQL_SUCCESS) {
15125 sqlite3_free(sql);
15126 return sret;
15127 }
15128 dbtraceapi(d, "sqlite3_get_table", sql);
15129 ret = sqlite3_get_table(d->sqlite, sql, &trows, &tnrows, &tncols, &errp);
15130 sqlite3_free(sql);
15131 if (ret != SQLITE_OK) {
15132 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15133 errp ? errp : "unknown error", ret);
15134 if (errp) {
15135 sqlite3_free(errp);
15136 errp = NULL;
15137 }
15138 return SQL_ERROR;
15139 }
15140 if (errp) {
15141 sqlite3_free(errp);
15142 errp = NULL;
15143 }
15144 /* pass 1: compute number of rows of result set */
15145 if (tncols * tnrows <= 0) {
15146 sqlite3_free_table(trows);
15147 return SQL_SUCCESS;
15148 }
15149 size = 0;
15150 for (i = 1; i <= tnrows; i++) {
15151 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
15152 if (!sql) {
15153 sqlite3_free_table(trows);
15154 return nomem(s);
15155 }
15156 dbtraceapi(d, "sqlite3_get_table", sql);
15157 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15158 sqlite3_free(sql);
15159 if (ret != SQLITE_OK) {
15160 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15161 errp ? errp : "unknown error", ret);
15162 if (errp) {
15163 sqlite3_free(errp);
15164 errp = NULL;
15165 }
15166 sqlite3_free_table(trows);
15167 return SQL_ERROR;
15168 }
15169 if (errp) {
15170 sqlite3_free(errp);
15171 errp = NULL;
15172 }
15173 if (ncols * nrows > 0) {
15174 namec = -1;
15175 for (k = 0; k < ncols; k++) {
15176 if (strcmp(rowp[k], "name") == 0) {
15177 namec = k;
15178 break;
15179 }
15180 }
15181 if (cname[0]) {
15182 if (namec >= 0) {
15183 for (k = 1; k <= nrows; k++) {
15184 if (namematch(rowp[k * ncols + namec], cname, 1)) {
15185 size++;
15186 }
15187 }
15188 }
15189 } else {
15190 size += nrows;
15191 }
15192 }
15193 sqlite3_free_table(rowp);
15194 }
15195 /* pass 2: fill result set */
15196 if (size <= 0) {
15197 sqlite3_free_table(trows);
15198 return SQL_SUCCESS;
15199 }
15200 s->nrows = size;
15201 size = (size + 1) * asize;
15202 s->rows = xmalloc((size + 1) * sizeof (char *));
15203 if (!s->rows) {
15204 s->nrows = 0;
15205 sqlite3_free_table(trows);
15206 return nomem(s);
15207 }
15208 s->rows[0] = (char *) size;
15209 s->rows += 1;
15210 memset(s->rows, 0, sizeof (char *) * size);
15211 s->rowfree = freerows;
15212 roffs = 1;
15213 for (i = 1; i <= tnrows; i++) {
15214 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
15215 if (!sql) {
15216 sqlite3_free_table(trows);
15217 return nomem(s);
15218 }
15219 dbtraceapi(d, "sqlite3_get_table", sql);
15220 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15221 sqlite3_free(sql);
15222 if (ret != SQLITE_OK) {
15223 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15224 errp ? errp : "unknown error", ret);
15225 if (errp) {
15226 sqlite3_free(errp);
15227 errp = NULL;
15228 }
15229 sqlite3_free_table(trows);
15230 return SQL_ERROR;
15231 }
15232 if (errp) {
15233 sqlite3_free(errp);
15234 errp = NULL;
15235 }
15236 if (ncols * nrows > 0) {
15237 int m, mr, nr = nrows;
15238
15239 namec = -1;
15240 for (k = 0; k < ncols; k++) {
15241 if (strcmp(rowp[k], "name") == 0) {
15242 namec = k;
15243 break;
15244 }
15245 }
15246 if (cname[0]) {
15247 nr = 0;
15248 if (namec >= 0) {
15249 for (k = 1; k <= nrows; k++) {
15250 if (namematch(rowp[k * ncols + namec], cname, 1)) {
15251 nr++;
15252 }
15253 }
15254 }
15255 }
15256 for (k = 0; k < nr; k++) {
15257 m = asize * (roffs + k);
15258#if defined(_WIN32) || defined(_WIN64)
15259 s->rows[m + 0] = xstrdup(d->xcelqrx ? "main" : "");
15260 s->rows[m + 1] = xstrdup("");
15261#else
15262 s->rows[m + 0] = xstrdup("");
15263 s->rows[m + 1] = xstrdup("");
15264#endif
15265 s->rows[m + 2] = xstrdup(trows[i]);
15266 s->rows[m + 8] = xstrdup("10");
15267 s->rows[m + 9] = xstrdup("0");
15268 s->rows[m + 15] = xstrdup("16384");
15269 }
15270 for (k = 0; nr && k < ncols; k++) {
15271 if (strcmp(rowp[k], "cid") == 0) {
15272 for (mr = 0, m = 1; m <= nrows; m++) {
15273 char buf[256];
15274 int ir, coln = k;
15275
15276 if (cname[0] &&
15277 !namematch(rowp[m * ncols + namec], cname, 1)) {
15278 continue;
15279 }
15280 ir = asize * (roffs + mr);
15281 sscanf(rowp[m * ncols + k], "%d", &coln);
15282 sprintf(buf, "%d", coln + 1);
15283 s->rows[ir + 16] = xstrdup(buf);
15284 ++mr;
15285 }
15286 } else if (k == namec) {
15287 for (mr = 0, m = 1; m <= nrows; m++) {
15288 int ir;
15289
15290 if (cname[0] &&
15291 !namematch(rowp[m * ncols + namec], cname, 1)) {
15292 continue;
15293 }
15294 ir = asize * (roffs + mr);
15295 s->rows[ir + 3] = xstrdup(rowp[m * ncols + k]);
15296 ++mr;
15297 }
15298 } else if (strcmp(rowp[k], "notnull") == 0) {
15299 for (mr = 0, m = 1; m <= nrows; m++) {
15300 int ir;
15301
15302 if (cname[0] &&
15303 !namematch(rowp[m * ncols + namec], cname, 1)) {
15304 continue;
15305 }
15306 ir = asize * (roffs + mr);
15307 if (*rowp[m * ncols + k] != '0') {
15308 s->rows[ir + 10] = xstrdup(stringify(SQL_FALSE));
15309 } else {
15310 s->rows[ir + 10] = xstrdup(stringify(SQL_TRUE));
15311 }
15312 s->rows[ir + 17] =
15313 xstrdup((*rowp[m * ncols + k] != '0') ?
15314 "NO" : "YES");
15315 ++mr;
15316 }
15317 } else if (strcmp(rowp[k], "dflt_value") == 0) {
15318 for (mr = 0, m = 1; m <= nrows; m++) {
15319 char *dflt = unquote(rowp[m * ncols + k]);
15320 int ir;
15321
15322 if (cname[0] &&
15323 !namematch(rowp[m * ncols + namec], cname, 1)) {
15324 continue;
15325 }
15326 ir = asize * (roffs + mr);
15327 s->rows[ir + 12] = xstrdup(dflt ? dflt : "NULL");
15328 ++mr;
15329 }
15330 } else if (strcmp(rowp[k], "type") == 0) {
15331 for (mr = 0, m = 1; m <= nrows; m++) {
15332 char *typename = rowp[m * ncols + k];
15333 int sqltype, mm, dd, ir;
15334 char buf[256];
15335
15336 if (cname[0] &&
15337 !namematch(rowp[m * ncols + namec], cname, 1)) {
15338 continue;
15339 }
15340 ir = asize * (roffs + mr);
15341 s->rows[ir + 5] = xstrdup(typename);
15342 sqltype = mapsqltype(typename, NULL, *s->ov3,
15343 s->nowchar[0], s->dobigint);
15344 getmd(typename, sqltype, &mm, &dd);
15345#ifdef SQL_LONGVARCHAR
15346 if (sqltype == SQL_VARCHAR && mm > 255) {
15347 sqltype = SQL_LONGVARCHAR;
15348 }
15349#endif
15350#ifdef WINTERFACE
15351#ifdef SQL_WLONGVARCHAR
15352 if (sqltype == SQL_WVARCHAR && mm > 255) {
15353 sqltype = SQL_WLONGVARCHAR;
15354 }
15355#endif
15356#endif
15357 if (sqltype == SQL_VARBINARY && mm > 255) {
15358 sqltype = SQL_LONGVARBINARY;
15359 }
15360 sprintf(buf, "%d", sqltype);
15361 s->rows[ir + 4] = xstrdup(buf);
15362 s->rows[ir + 13] = xstrdup(buf);
15363 sprintf(buf, "%d", mm);
15364 s->rows[ir + 7] = xstrdup(buf);
15365 sprintf(buf, "%d", dd);
15366 s->rows[ir + 6] = xstrdup(buf);
15367 ++mr;
15368 }
15369 }
15370 }
15371 roffs += nr;
15372 }
15373 sqlite3_free_table(rowp);
15374 }
15375 sqlite3_free_table(trows);
15376 return SQL_SUCCESS;
15377}
15378
15379#ifndef WINTERFACE
15394SQLRETURN SQL_API
15395SQLColumns(SQLHSTMT stmt,
15396 SQLCHAR *cat, SQLSMALLINT catLen,
15397 SQLCHAR *schema, SQLSMALLINT schemaLen,
15398 SQLCHAR *table, SQLSMALLINT tableLen,
15399 SQLCHAR *col, SQLSMALLINT colLen)
15400{
15401#if defined(_WIN32) || defined(_WIN64)
15402 char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15403#endif
15404 SQLRETURN ret;
15405
15407#if defined(_WIN32) || defined(_WIN64)
15408 if (!((STMT *) stmt)->oemcp[0]) {
15409 ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15410 table, tableLen, col, colLen);
15411 goto done2;
15412 }
15413 if (cat) {
15414 c = wmb_to_utf_c((char *) cat, catLen);
15415 if (!c) {
15416 ret = nomem((STMT *) stmt);
15417 goto done;
15418 }
15419 }
15420 if (schema) {
15421 s = wmb_to_utf_c((char *) schema, schemaLen);
15422 if (!s) {
15423 ret = nomem((STMT *) stmt);
15424 goto done;
15425 }
15426 }
15427 if (table) {
15428 t = wmb_to_utf_c((char *) table, tableLen);
15429 if (!t) {
15430 ret = nomem((STMT *) stmt);
15431 goto done;
15432 }
15433 }
15434 if (col) {
15435 k = wmb_to_utf_c((char *) col, colLen);
15436 if (!k) {
15437 ret = nomem((STMT *) stmt);
15438 goto done;
15439 }
15440 }
15441 ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15442 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15443#else
15444 ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15445 table, tableLen, col, colLen);
15446#endif
15447#if defined(_WIN32) || defined(_WIN64)
15448done:
15449 uc_free(k);
15450 uc_free(t);
15451 uc_free(s);
15452 uc_free(c);
15453done2:
15454 ;
15455#endif
15457 return ret;
15458}
15459#endif
15460
15461#ifdef WINTERFACE
15476SQLRETURN SQL_API
15478 SQLWCHAR *cat, SQLSMALLINT catLen,
15479 SQLWCHAR *schema, SQLSMALLINT schemaLen,
15480 SQLWCHAR *table, SQLSMALLINT tableLen,
15481 SQLWCHAR *col, SQLSMALLINT colLen)
15482{
15483 char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15484 SQLRETURN ret;
15485
15487 if (cat) {
15488 c = uc_to_utf_c(cat, catLen);
15489 if (!c) {
15490 ret = nomem((STMT *) stmt);
15491 goto done;
15492 }
15493 }
15494 if (schema) {
15495 s = uc_to_utf_c(schema, schemaLen);
15496 if (!s) {
15497 ret = nomem((STMT *) stmt);
15498 goto done;
15499 }
15500 }
15501 if (table) {
15502 t = uc_to_utf_c(table, tableLen);
15503 if (!t) {
15504 ret = nomem((STMT *) stmt);
15505 goto done;
15506 }
15507 }
15508 if (col) {
15509 k = uc_to_utf_c(col, colLen);
15510 if (!k) {
15511 ret = nomem((STMT *) stmt);
15512 goto done;
15513 }
15514 }
15515 ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15516 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15517done:
15518 uc_free(k);
15519 uc_free(t);
15520 uc_free(s);
15521 uc_free(c);
15523 return ret;
15524
15525}
15526#endif
15527
15532static COL typeSpec2[] = {
15533 { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15534 { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15535 { "SYSTEM", "TYPE", "PRECISION", SQL_INTEGER, 9 },
15536 { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15537 { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15538 { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15539 { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15540 { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15541 { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15542 { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15543 { "SYSTEM", "TYPE", "MONEY", SQL_SMALLINT, 2 },
15544 { "SYSTEM", "TYPE", "AUTO_INCREMENT", SQL_SMALLINT, 2 },
15545 { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15546 { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15547 { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 }
15548};
15549
15550static COL typeSpec3[] = {
15551 { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15552 { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15553 { "SYSTEM", "TYPE", "COLUMN_SIZE", SQL_INTEGER, 9 },
15554 { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15555 { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15556 { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15557 { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15558 { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15559 { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15560 { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15561 { "SYSTEM", "TYPE", "FIXED_PREC_SCALE", SQL_SMALLINT, 2 },
15562 { "SYSTEM", "TYPE", "AUTO_UNIQUE_VALUE", SQL_SMALLINT, 2 },
15563 { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15564 { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15565 { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 },
15566 { "SYSTEM", "TYPE", "SQL_DATA_TYPE", SQL_SMALLINT, 2 },
15567 { "SYSTEM", "TYPE", "SQL_DATETIME_SUB", SQL_SMALLINT, 2 },
15568 { "SYSTEM", "TYPE", "NUM_PREC_RADIX", SQL_INTEGER, 4 },
15569 { "SYSTEM", "TYPE", "INTERVAL_PRECISION", SQL_SMALLINT, 2 }
15570};
15571
15582static void
15583mktypeinfo(STMT *s, int row, int asize, char *typename, int type, int tind)
15584{
15585 int offs = row * asize;
15586 char *tcode, *crpar = NULL, *sign = stringify(SQL_FALSE);
15587 char *quote[2] = { NULL, NULL };
15588 static char tcodes[32 * 32];
15589
15590 if (tind <= 0) {
15591 tind = row;
15592 }
15593 tcode = tcodes + tind * 32;
15594 sprintf(tcode, "%d", type);
15595 s->rows[offs + 0] = typename;
15596 s->rows[offs + 1] = tcode;
15597 if (asize >= 17) {
15598 s->rows[offs + 15] = tcode;
15599 s->rows[offs + 16] = "0";
15600 }
15601 switch (type) {
15602 default:
15603#ifdef SQL_LONGVARCHAR
15604 case SQL_LONGVARCHAR:
15605#ifdef WINTERFACE
15606 case SQL_WLONGVARCHAR:
15607#endif
15608 crpar = "length";
15609 quote[0] = quote[1] = "'";
15610 sign = NULL;
15611 s->rows[offs + 2] = "65536";
15612 break;
15613#endif
15614#ifdef SQL_BIT
15615 case SQL_BIT:
15616 sign = NULL;
15617 s->rows[offs + 2] = "1";
15618 break;
15619#endif
15620 case SQL_CHAR:
15621 case SQL_VARCHAR:
15622#ifdef WINTERFACE
15623 case SQL_WCHAR:
15624 case SQL_WVARCHAR:
15625#endif
15626 s->rows[offs + 2] = "255";
15627 crpar = "length";
15628 quote[0] = quote[1] = "'";
15629 sign = NULL;
15630 break;
15631 case SQL_TINYINT:
15632 s->rows[offs + 2] = "3";
15633 break;
15634 case SQL_SMALLINT:
15635 s->rows[offs + 2] = "5";
15636 break;
15637 case SQL_INTEGER:
15638 s->rows[offs + 2] = "9";
15639 break;
15640#ifdef SQL_BIGINT
15641 case SQL_BIGINT:
15642 s->rows[offs + 2] = "19";
15643 break;
15644#endif
15645 case SQL_FLOAT:
15646 s->rows[offs + 2] = "7";
15647 break;
15648 case SQL_DOUBLE:
15649 s->rows[offs + 2] = "15";
15650 break;
15651#ifdef SQL_TYPE_DATE
15652 case SQL_TYPE_DATE:
15653#endif
15654 case SQL_DATE:
15655 s->rows[offs + 2] = "10";
15656 quote[0] = quote[1] = "'";
15657 sign = NULL;
15658 break;
15659#ifdef SQL_TYPE_TIME
15660 case SQL_TYPE_TIME:
15661#endif
15662 case SQL_TIME:
15663 s->rows[offs + 2] = "8";
15664 quote[0] = quote[1] = "'";
15665 sign = NULL;
15666 break;
15667#ifdef SQL_TYPE_TIMESTAMP
15668 case SQL_TYPE_TIMESTAMP:
15669#endif
15670 case SQL_TIMESTAMP:
15671 s->rows[offs + 2] = "32";
15672 quote[0] = quote[1] = "'";
15673 sign = NULL;
15674 break;
15675 case SQL_VARBINARY:
15676 quote[0] = "0x";
15677 sign = NULL;
15678 s->rows[offs + 2] = "255";
15679 break;
15680 case SQL_LONGVARBINARY:
15681 quote[0] = "0x";
15682 sign = NULL;
15683 s->rows[offs + 2] = "65536";
15684 break;
15685 }
15686 s->rows[offs + 3] = quote[0];
15687 s->rows[offs + 4] = quote[1];
15688 s->rows[offs + 5] = crpar;
15689 s->rows[offs + 6] = stringify(SQL_NULLABLE);
15690 s->rows[offs + 7] = stringify(SQL_FALSE);
15691 s->rows[offs + 8] = stringify(SQL_SEARCHABLE);
15692 s->rows[offs + 9] = sign;
15693 s->rows[offs + 10] = stringify(SQL_FALSE);
15694 s->rows[offs + 11] = stringify(SQL_FALSE);
15695 s->rows[offs + 12] = typename;
15696 switch (type) {
15697 case SQL_DATE:
15698 case SQL_TIME:
15699 s->rows[offs + 13] = "0";
15700 s->rows[offs + 14] = "0";
15701 break;
15702#ifdef SQL_TYPE_TIMESTAMP
15703 case SQL_TYPE_TIMESTAMP:
15704#endif
15705 case SQL_TIMESTAMP:
15706 s->rows[offs + 13] = "0";
15707 s->rows[offs + 14] = "3";
15708 break;
15709 default:
15710 s->rows[offs + 13] = NULL;
15711 s->rows[offs + 14] = NULL;
15712 break;
15713 }
15714}
15715
15724static int
15725typeinfosort(const void *a, const void *b)
15726{
15727 char **pa = (char **) a;
15728 char **pb = (char **) b;
15729 int na, nb;
15730
15731 na = strtol(pa[1], NULL, 0);
15732 nb = strtol(pb[1], NULL, 0);
15733 return na - nb;
15734}
15735
15743static SQLRETURN
15744drvgettypeinfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
15745{
15746 SQLRETURN ret;
15747 STMT *s;
15748 int asize;
15749
15751 typeSpec3, array_size(typeSpec3), &asize);
15752 if (ret != SQL_SUCCESS) {
15753 return ret;
15754 }
15755 s = (STMT *) stmt;
15756#ifdef SQL_LONGVARCHAR
15757 s->nrows = (sqltype == SQL_ALL_TYPES) ? 13 : 1;
15758#else
15759 s->nrows = (sqltype == SQL_ALL_TYPES) ? 12 : 1;
15760#endif
15761 if (sqltype == SQL_ALL_TYPES) {
15762#ifdef WINTERFACE
15763 s->nrows += 2;
15764#ifdef SQL_WLONGVARCHAR
15765 s->nrows += 2;
15766#endif
15767#endif
15768 }
15769 if (sqltype == SQL_ALL_TYPES) {
15770 s->nrows += 2;
15771#ifdef SQL_BIT
15772 s->nrows += 1;
15773#endif
15774#ifdef SQL_BIGINT
15775 s->nrows += 1;
15776#endif
15777 }
15778 s->rows = (char **) xmalloc(sizeof (char *) * (s->nrows + 1) * asize);
15779 if (!s->rows) {
15780 s->nrows = 0;
15781 return nomem(s);
15782 }
15783#ifdef MEMORY_DEBUG
15784 s->rowfree = xfree__;
15785#else
15786 s->rowfree = sqlite3_free;
15787#endif
15788 memset(s->rows, 0, sizeof (char *) * (s->nrows + 1) * asize);
15789 if (sqltype == SQL_ALL_TYPES) {
15790 int cc = 1;
15791
15792 mktypeinfo(s, cc++, asize, "varchar", SQL_VARCHAR, 0);
15793 mktypeinfo(s, cc++, asize, "tinyint", SQL_TINYINT, 0);
15794 mktypeinfo(s, cc++, asize, "smallint", SQL_SMALLINT, 0);
15795 mktypeinfo(s, cc++, asize, "integer", SQL_INTEGER, 0);
15796 mktypeinfo(s, cc++, asize, "float", SQL_FLOAT, 0);
15797 mktypeinfo(s, cc++, asize, "double", SQL_DOUBLE, 0);
15798#ifdef SQL_TYPE_DATE
15799 mktypeinfo(s, cc++, asize, "date",
15800 (*s->ov3) ? SQL_TYPE_DATE : SQL_DATE, 0);
15801#else
15802 mktypeinfo(s, cc++, asize, "date", SQL_DATE, 0);
15803#endif
15804#ifdef SQL_TYPE_TIME
15805 mktypeinfo(s, cc++, asize, "time",
15806 (*s->ov3) ? SQL_TYPE_TIME : SQL_TIME, 0);
15807#else
15808 mktypeinfo(s, cc++, asize, "time", SQL_TIME, 0);
15809#endif
15810#ifdef SQL_TYPE_TIMESTAMP
15811 mktypeinfo(s, cc++, asize, "timestamp",
15812 (*s->ov3) ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP, 0);
15813#else
15814 mktypeinfo(s, cc++, asize, "timestamp", SQL_TIMESTAMP, 0);
15815#endif
15816 mktypeinfo(s, cc++, asize, "char", SQL_CHAR, 0);
15817 mktypeinfo(s, cc++, asize, "numeric", SQL_DOUBLE, 0);
15818#ifdef SQL_LONGVARCHAR
15819 mktypeinfo(s, cc++, asize, "text", SQL_LONGVARCHAR, 0);
15820 mktypeinfo(s, cc++, asize, "longvarchar", SQL_LONGVARCHAR, 0);
15821#else
15822 mktypeinfo(s, cc++, asize, "text", SQL_VARCHAR, 0);
15823#endif
15824 mktypeinfo(s, cc++, asize, "varbinary", SQL_VARBINARY, 0);
15825 mktypeinfo(s, cc++, asize, "longvarbinary", SQL_LONGVARBINARY, 0);
15826#ifdef SQL_BIT
15827 mktypeinfo(s, cc++, asize, "bit", SQL_BIT, 0);
15828#endif
15829#ifdef SQL_BIGINT
15830 mktypeinfo(s, cc++, asize, "bigint", SQL_BIGINT, 0);
15831#endif
15832#ifdef WINTERFACE
15833 mktypeinfo(s, cc++, asize, "wvarchar", SQL_WVARCHAR, 0);
15834 mktypeinfo(s, cc++, asize, "wchar", SQL_WCHAR, 0);
15835#ifdef SQL_WLONGVARCHAR
15836 mktypeinfo(s, cc++, asize, "wtext", SQL_WLONGVARCHAR, 0);
15837 mktypeinfo(s, cc++, asize, "longwvarchar", SQL_WLONGVARCHAR, 0);
15838#endif
15839#endif
15840 qsort(s->rows + asize, s->nrows, sizeof (char *) * asize,
15841 typeinfosort);
15842 } else {
15843 switch (sqltype) {
15844 case SQL_CHAR:
15845 mktypeinfo(s, 1, asize, "char", SQL_CHAR, 10);
15846 break;
15847 case SQL_VARCHAR:
15848 mktypeinfo(s, 1, asize, "varchar", SQL_VARCHAR, 1);
15849 break;
15850 case SQL_TINYINT:
15851 mktypeinfo(s, 1, asize, "tinyint", SQL_TINYINT, 2);
15852 break;
15853 case SQL_SMALLINT:
15854 mktypeinfo(s, 1, asize, "smallint", SQL_SMALLINT, 3);
15855 break;
15856 case SQL_INTEGER:
15857 mktypeinfo(s, 1, asize, "integer", SQL_INTEGER, 4);
15858 break;
15859 case SQL_FLOAT:
15860 mktypeinfo(s, 1, asize, "float", SQL_FLOAT, 5);
15861 break;
15862 case SQL_DOUBLE:
15863 mktypeinfo(s, 1, asize, "double", SQL_DOUBLE, 6);
15864 break;
15865#ifdef SQL_TYPE_DATE
15866 case SQL_TYPE_DATE:
15867 mktypeinfo(s, 1, asize, "date", SQL_TYPE_DATE, 25);
15868 break;
15869#endif
15870 case SQL_DATE:
15871 mktypeinfo(s, 1, asize, "date", SQL_DATE, 7);
15872 break;
15873#ifdef SQL_TYPE_TIME
15874 case SQL_TYPE_TIME:
15875 mktypeinfo(s, 1, asize, "time", SQL_TYPE_TIME, 26);
15876 break;
15877#endif
15878 case SQL_TIME:
15879 mktypeinfo(s, 1, asize, "time", SQL_TIME, 8);
15880 break;
15881#ifdef SQL_TYPE_TIMESTAMP
15882 case SQL_TYPE_TIMESTAMP:
15883 mktypeinfo(s, 1, asize, "timestamp", SQL_TYPE_TIMESTAMP, 27);
15884 break;
15885#endif
15886 case SQL_TIMESTAMP:
15887 mktypeinfo(s, 1, asize, "timestamp", SQL_TIMESTAMP, 9);
15888 break;
15889#ifdef SQL_LONGVARCHAR
15890 case SQL_LONGVARCHAR:
15891 mktypeinfo(s, 1, asize, "longvarchar", SQL_LONGVARCHAR, 12);
15892 break;
15893#endif
15894 case SQL_VARBINARY:
15895 mktypeinfo(s, 1, asize, "varbinary", SQL_VARBINARY, 30);
15896 break;
15897 case SQL_LONGVARBINARY:
15898 mktypeinfo(s, 1, asize, "longvarbinary", SQL_LONGVARBINARY, 31);
15899 break;
15900#ifdef SQL_BIT
15901 case SQL_BIT:
15902 mktypeinfo(s, 1, asize, "bit", SQL_BIT, 29);
15903 break;
15904#endif
15905#ifdef SQL_BIGINT
15906 case SQL_BIGINT:
15907 mktypeinfo(s, 1, asize, "bigint", SQL_BIGINT, 28);
15908 break;
15909#endif
15910#ifdef WINTERFACE
15911#ifdef SQL_WCHAR
15912 case SQL_WCHAR:
15913 mktypeinfo(s, 1, asize, "wchar", SQL_WCHAR, 18);
15914 break;
15915#endif
15916#ifdef SQL_WVARCHAR
15917 case SQL_WVARCHAR:
15918 mktypeinfo(s, 1, asize, "wvarchar", SQL_WVARCHAR, 19);
15919 break;
15920#endif
15921#ifdef SQL_WLONGVARCHAR
15922 case SQL_WLONGVARCHAR:
15923 mktypeinfo(s, 1, asize, "longwvarchar", SQL_WLONGVARCHAR, 20);
15924 break;
15925#endif
15926#endif
15927 default:
15928 s->nrows = 0;
15929 }
15930 }
15931 return SQL_SUCCESS;
15932}
15933
15934#ifndef WINTERFACE
15942SQLRETURN SQL_API
15943SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
15944{
15945 SQLRETURN ret;
15946
15948 ret = drvgettypeinfo(stmt, sqltype);
15950 return ret;
15951}
15952#endif
15953
15954#ifdef WINTERFACE
15962SQLRETURN SQL_API
15963SQLGetTypeInfoW(SQLHSTMT stmt, SQLSMALLINT sqltype)
15964{
15965 SQLRETURN ret;
15966
15968 ret = drvgettypeinfo(stmt, sqltype);
15970 return ret;
15971}
15972#endif
15973
15978static COL statSpec2[] = {
15979 { "SYSTEM", "STATISTICS", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
15980 { "SYSTEM", "STATISTICS", "TABLE_OWNER", SCOL_VARCHAR, 50 },
15981 { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
15982 { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
15983 { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
15984 { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
15985 { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
15986 { "SYSTEM", "STATISTICS", "SEQ_IN_INDEX", SQL_SMALLINT, 50 },
15987 { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15988 { "SYSTEM", "STATISTICS", "COLLATION", SCOL_CHAR, 1 },
15989 { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
15990 { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
15991 { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
15992};
15993
15994static COL statSpec3[] = {
15995 { "SYSTEM", "STATISTICS", "TABLE_CAT", SCOL_VARCHAR, 50 },
15996 { "SYSTEM", "STATISTICS", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
15997 { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
15998 { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
15999 { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
16000 { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
16001 { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
16002 { "SYSTEM", "STATISTICS", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
16003 { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
16004 { "SYSTEM", "STATISTICS", "ASC_OR_DESC", SCOL_CHAR, 1 },
16005 { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
16006 { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
16007 { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
16008};
16009
16024static SQLRETURN
16025drvstatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
16026 SQLCHAR *schema, SQLSMALLINT schemaLen,
16027 SQLCHAR *table, SQLSMALLINT tableLen,
16028 SQLUSMALLINT itype, SQLUSMALLINT resv)
16029{
16030 SQLRETURN sret;
16031 STMT *s;
16032 DBC *d;
16033 int i, asize, ret, nrows, ncols, offs, namec, uniquec, addipk = 0;
16034 PTRDIFF_T size;
16035 char **rowp, *errp = NULL, *sql, tname[512];
16036
16038 statSpec3, array_size(statSpec3), &asize);
16039 if (sret != SQL_SUCCESS) {
16040 return sret;
16041 }
16042 s = (STMT *) stmt;
16043 d = (DBC *) s->dbc;
16044 if (!table || table[0] == '\0' || table[0] == '%') {
16045 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
16046 return SQL_ERROR;
16047 }
16048 if (tableLen == SQL_NTS) {
16049 size = sizeof (tname) - 1;
16050 } else {
16051 size = min(sizeof (tname) - 1, tableLen);
16052 }
16053 strncpy(tname, (char *) table, size);
16054 tname[size] = '\0';
16055 unescpat(tname);
16056 sret = starttran(s);
16057 if (sret != SQL_SUCCESS) {
16058 return sret;
16059 }
16060 /*
16061 * Try integer primary key (autoincrement) first
16062 */
16063 if (itype == SQL_INDEX_UNIQUE || itype == SQL_INDEX_ALL) {
16064 rowp = 0;
16065 ret = SQLITE_ERROR;
16066 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
16067 if (sql) {
16068 dbtraceapi(d, "sqlite3_get_table", sql);
16069 ret = sqlite3_get_table(d->sqlite, sql, &rowp,
16070 &nrows, &ncols, NULL);
16071 sqlite3_free(sql);
16072 }
16073 if (ret == SQLITE_OK) {
16074 int colid, typec, npk = 0, npkint = 0;
16075
16076 namec = findcol(rowp, ncols, "name");
16077 uniquec = findcol(rowp, ncols, "pk");
16078 typec = findcol(rowp, ncols, "type");
16079 colid = findcol(rowp, ncols, "cid");
16080 if (namec < 0 || uniquec < 0 || typec < 0 || colid < 0) {
16081 goto noipk;
16082 }
16083 for (i = 1; i <= nrows; i++) {
16084 if (*rowp[i * ncols + uniquec] != '0') {
16085 npk++;
16086 if (strlen(rowp[i * ncols + typec]) == 7 &&
16087 strncasecmp(rowp[i * ncols + typec], "integer", 7)
16088 == 0) {
16089 npkint++;
16090 }
16091 }
16092 }
16093 if (npkint == 1 && npk == npkint) {
16094 addipk = 1;
16095 }
16096 }
16097noipk:
16098 sqlite3_free_table(rowp);
16099 }
16100 sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
16101 if (!sql) {
16102 return nomem(s);
16103 }
16104 dbtraceapi(d, "sqlite3_get_table", sql);
16105 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
16106 sqlite3_free(sql);
16107 if (ret != SQLITE_OK) {
16108 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
16109 errp ? errp : "unknown error", ret);
16110 if (errp) {
16111 sqlite3_free(errp);
16112 errp = NULL;
16113 }
16114 return SQL_ERROR;
16115 }
16116 if (errp) {
16117 sqlite3_free(errp);
16118 errp = NULL;
16119 }
16120 size = 0;
16121 namec = findcol(rowp, ncols, "name");
16122 uniquec = findcol(rowp, ncols, "unique");
16123 if (namec < 0 || uniquec < 0) {
16124 goto nodata;
16125 }
16126 for (i = 1; i <= nrows; i++) {
16127 int nnrows, nncols;
16128 char **rowpp;
16129 int isuniq;
16130
16131 isuniq = *rowp[i * ncols + uniquec] != '0';
16132 if (isuniq || itype == SQL_INDEX_ALL) {
16133 ret = SQLITE_ERROR;
16134 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
16135 rowp[i * ncols + namec]);
16136 if (sql) {
16137 dbtraceapi(d, "sqlite3_get_table", sql);
16138 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16139 &nnrows, &nncols, NULL);
16140 sqlite3_free(sql);
16141 }
16142 if (ret == SQLITE_OK) {
16143 size += nnrows;
16144 sqlite3_free_table(rowpp);
16145 }
16146 }
16147 }
16148nodata:
16149 if (addipk) {
16150 size++;
16151 }
16152 if (size == 0) {
16153 sqlite3_free_table(rowp);
16154 return SQL_SUCCESS;
16155 }
16156 s->nrows = size;
16157 size = (size + 1) * asize;
16158 s->rows = xmalloc((size + 1) * sizeof (char *));
16159 if (!s->rows) {
16160 s->nrows = 0;
16161 return nomem(s);
16162 }
16163 s->rows[0] = (char *) size;
16164 s->rows += 1;
16165 memset(s->rows, 0, sizeof (char *) * size);
16166 s->rowfree = freerows;
16167 offs = 0;
16168 if (addipk) {
16169 char **rowpp = 0;
16170 int nrows2, ncols2;
16171
16172 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
16173 if (sql) {
16174 dbtraceapi(d, "sqlite3_get_table", sql);
16175 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16176 &nrows2, &ncols2, NULL);
16177 sqlite3_free(sql);
16178 }
16179 if (ret == SQLITE_OK) {
16180 int colid, typec, roffs, namecc, uniquecc;
16181
16182 namecc = findcol(rowpp, ncols2, "name");
16183 uniquecc = findcol(rowpp, ncols2, "pk");
16184 typec = findcol(rowpp, ncols2, "type");
16185 colid = findcol(rowpp, ncols2, "cid");
16186 if (namecc < 0 || uniquecc < 0 || typec < 0 || colid < 0) {
16187 addipk = 0;
16188 s->nrows--;
16189 goto nodata2;
16190 }
16191 for (i = 1; i <= nrows2; i++) {
16192 if (*rowpp[i * ncols2 + uniquecc] != '0' &&
16193 strlen(rowpp[i * ncols2 + typec]) == 7 &&
16194 strncasecmp(rowpp[i * ncols2 + typec], "integer", 7)
16195 == 0) {
16196 break;
16197 }
16198 }
16199 if (i > nrows2) {
16200 addipk = 0;
16201 s->nrows--;
16202 goto nodata2;
16203 }
16204 roffs = s->ncols;
16205#if defined(_WIN32) || defined(_WIN64)
16206 s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
16207 s->rows[roffs + 1] = xstrdup("");
16208#else
16209 s->rows[roffs + 0] = xstrdup("");
16210 s->rows[roffs + 1] = xstrdup("");
16211#endif
16212 s->rows[roffs + 2] = xstrdup(tname);
16213 s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16214 s->rows[roffs + 5] = xstrdup("sqlite_autoindex_0");
16215 s->rows[roffs + 6] = xstrdup(stringify(SQL_INDEX_OTHER));
16216 s->rows[roffs + 7] = xstrdup("1");
16217 s->rows[roffs + 8] = xstrdup(rowpp[i * ncols2 + namecc]);
16218 s->rows[roffs + 9] = xstrdup("A");
16219 }
16220nodata2:
16221 sqlite3_free_table(rowpp);
16222 }
16223 for (i = 1; i <= nrows; i++) {
16224 int nnrows, nncols;
16225 char **rowpp = 0;
16226
16227 if (*rowp[i * ncols + uniquec] != '0' || itype == SQL_INDEX_ALL) {
16228 int k;
16229
16230 ret = SQLITE_ERROR;
16231 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
16232 rowp[i * ncols + namec]);
16233 if (sql) {
16234 dbtraceapi(d, "sqlite3_get_table", sql);
16235 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16236 &nnrows, &nncols, NULL);
16237 sqlite3_free(sql);
16238 }
16239 if (ret != SQLITE_OK) {
16240 continue;
16241 }
16242 for (k = 0; nnrows && k < nncols; k++) {
16243 if (strcmp(rowpp[k], "name") == 0) {
16244 int m;
16245
16246 for (m = 1; m <= nnrows; m++) {
16247 int roffs = (offs + addipk + m) * s->ncols;
16248 int isuniq;
16249
16250 isuniq = *rowp[i * ncols + uniquec] != '0';
16251 s->rows[roffs + 0] = xstrdup("");
16252 s->rows[roffs + 1] = xstrdup("");
16253 s->rows[roffs + 2] = xstrdup(tname);
16254 if (isuniq) {
16255 s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16256 } else {
16257 s->rows[roffs + 3] = xstrdup(stringify(SQL_TRUE));
16258 }
16259 s->rows[roffs + 5] = xstrdup(rowp[i * ncols + namec]);
16260 s->rows[roffs + 6] =
16261 xstrdup(stringify(SQL_INDEX_OTHER));
16262 s->rows[roffs + 8] = xstrdup(rowpp[m * nncols + k]);
16263 s->rows[roffs + 9] = xstrdup("A");
16264 }
16265 } else if (strcmp(rowpp[k], "seqno") == 0) {
16266 int m;
16267
16268 for (m = 1; m <= nnrows; m++) {
16269 int roffs = (offs + addipk + m) * s->ncols;
16270 int pos = m - 1;
16271 char buf[32];
16272
16273 sscanf(rowpp[m * nncols + k], "%d", &pos);
16274 sprintf(buf, "%d", pos + 1);
16275 s->rows[roffs + 7] = xstrdup(buf);
16276 }
16277 }
16278 }
16279 offs += nnrows;
16280 sqlite3_free_table(rowpp);
16281 }
16282 }
16283 sqlite3_free_table(rowp);
16284 return SQL_SUCCESS;
16285}
16286
16287#ifndef WINTERFACE
16302SQLRETURN SQL_API
16303SQLStatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
16304 SQLCHAR *schema, SQLSMALLINT schemaLen,
16305 SQLCHAR *table, SQLSMALLINT tableLen,
16306 SQLUSMALLINT itype, SQLUSMALLINT resv)
16307{
16308#if defined(_WIN32) || defined(_WIN64)
16309 char *c = NULL, *s = NULL, *t = NULL;
16310#endif
16311 SQLRETURN ret;
16312
16314#if defined(_WIN32) || defined(_WIN64)
16315 if (!((STMT *) stmt)->oemcp[0]) {
16316 ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16317 table, tableLen, itype, resv);
16318 goto done2;
16319 }
16320 if (cat) {
16321 c = wmb_to_utf_c((char *) cat, catLen);
16322 if (!c) {
16323 ret = nomem((STMT *) stmt);
16324 goto done;
16325 }
16326 }
16327 if (schema) {
16328 s = wmb_to_utf_c((char *) schema, schemaLen);
16329 if (!s) {
16330 ret = nomem((STMT *) stmt);
16331 goto done;
16332 }
16333 }
16334 if (table) {
16335 t = wmb_to_utf_c((char *) table, tableLen);
16336 if (!t) {
16337 ret = nomem((STMT *) stmt);
16338 goto done;
16339 }
16340 }
16341 ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16342 (SQLCHAR *) t, SQL_NTS, itype, resv);
16343#else
16344 ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16345 table, tableLen, itype, resv);
16346#endif
16347#if defined(_WIN32) || defined(_WIN64)
16348done:
16349 uc_free(t);
16350 uc_free(s);
16351 uc_free(c);
16352done2:
16353 ;
16354#endif
16356 return ret;
16357}
16358#endif
16359
16360#ifdef WINTERFACE
16375SQLRETURN SQL_API
16376SQLStatisticsW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen,
16377 SQLWCHAR *schema, SQLSMALLINT schemaLen,
16378 SQLWCHAR *table, SQLSMALLINT tableLen,
16379 SQLUSMALLINT itype, SQLUSMALLINT resv)
16380{
16381 char *c = NULL, *s = NULL, *t = NULL;
16382 SQLRETURN ret;
16383
16385 if (cat) {
16386 c = uc_to_utf_c(cat, catLen);
16387 if (!c) {
16388 ret = nomem((STMT *) stmt);
16389 goto done;
16390 }
16391 }
16392 if (schema) {
16393 s = uc_to_utf_c(schema, schemaLen);
16394 if (!s) {
16395 ret = nomem((STMT *) stmt);
16396 goto done;
16397 }
16398 }
16399 if (table) {
16400 t = uc_to_utf_c(table, tableLen);
16401 if (!t) {
16402 ret = nomem((STMT *) stmt);
16403 goto done;
16404 }
16405 }
16406 ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16407 (SQLCHAR *) t, SQL_NTS, itype, resv);
16408done:
16409 uc_free(t);
16410 uc_free(s);
16411 uc_free(c);
16413 return ret;
16414}
16415#endif
16416
16428SQLRETURN SQL_API
16429SQLGetData(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
16430 SQLPOINTER val, SQLLEN len, SQLLEN *lenp)
16431{
16432 STMT *s;
16433 SQLRETURN ret = SQL_ERROR;
16434
16436 if (stmt == SQL_NULL_HSTMT) {
16437 return SQL_INVALID_HANDLE;
16438 }
16439 s = (STMT *) stmt;
16440 if (col == 0 && s->bkmrk != SQL_UB_OFF) {
16441 if (s->bkmrk == SQL_UB_ON && type == SQL_C_BOOKMARK) {
16442 *((SQLINTEGER *) val) = s->rowp;
16443 if (lenp) {
16444 *lenp = sizeof (SQLINTEGER);
16445 }
16446 ret = SQL_SUCCESS;
16447 goto done;
16448 } else if (s->bkmrk == SQL_UB_VARIABLE && type == SQL_C_VARBOOKMARK) {
16449 if (s->has_rowid >= 0) {
16450 char **data, *endp = 0;
16451
16452 data = s->rows + s->ncols + (s->rowp * s->ncols)
16453 + s->has_rowid;
16454#ifdef __osf__
16455 *((sqlite_int64 *) val) = strtol(*data, &endp, 0);
16456#else
16457 *((sqlite_int64 *) val) = strtoll(*data, &endp, 0);
16458#endif
16459 } else {
16460 *((sqlite_int64 *) val) = s->rowp;
16461 }
16462 if (lenp) {
16463 *lenp = sizeof (sqlite_int64);
16464 }
16465 ret = SQL_SUCCESS;
16466 goto done;
16467 }
16468 }
16469 if (col < 1 || col > s->ncols) {
16470 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
16471 goto done;
16472 }
16473 --col;
16474 ret = getrowdata(s, col, type, val, len, lenp, 1);
16475done:
16477 return ret;
16478}
16479
16487static SQLRETURN
16488dofetchbind(STMT *s, int rsi)
16489{
16490 int ret, i, withinfo = 0;
16491
16492 s->row_status0[rsi] = SQL_ROW_SUCCESS;
16493 if (s->bkmrk != SQL_UB_OFF && s->bkmrkcol.valp) {
16494 int bsize = sizeof (SQLINTEGER);
16495
16496 if (s->bkmrkcol.type == SQL_C_VARBOOKMARK) {
16497 SQLPOINTER *val;
16498
16499 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16500 val = (SQLPOINTER)
16501 ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16502 } else {
16503 val = (SQLPOINTER)
16504 ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * rsi);
16505 }
16506 if (s->bind_offs) {
16507 val = (SQLPOINTER) ((char *) val + *s->bind_offs);
16508 }
16509 if (s->has_rowid >= 0) {
16510 char **data, *endp = 0;
16511
16512 data = s->rows + s->ncols + (s->rowp * s->ncols)
16513 + s->has_rowid;
16514#ifdef __osf__
16515 *(sqlite_int64 *) val = strtol(*data, &endp, 0);
16516#else
16517 *(sqlite_int64 *) val = strtoll(*data, &endp, 0);
16518#endif
16519 } else {
16520 *(sqlite_int64 *) val = s->rowp;
16521 }
16522 bsize = sizeof (sqlite_int64);
16523 } else {
16524 SQLINTEGER *val;
16525
16526 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16527 val = (SQLINTEGER *)
16528 ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16529 } else {
16530 val = (SQLINTEGER *) s->bkmrkcol.valp + rsi;
16531 }
16532 if (s->bind_offs) {
16533 val = (SQLINTEGER *) ((char *) val + *s->bind_offs);
16534 }
16535 *val = s->rowp;
16536 }
16537 if (s->bkmrkcol.lenp) {
16538 SQLLEN *ival;
16539
16540 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16541 ival = (SQLLEN *)
16542 ((char *) s->bkmrkcol.lenp + s->bind_type * rsi);
16543 } else {
16544 ival = &s->bkmrkcol.lenp[rsi];
16545 }
16546 if (s->bind_offs) {
16547 ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
16548 }
16549 *ival = bsize;
16550 }
16551 }
16552 ret = SQL_SUCCESS;
16553 for (i = 0; s->bindcols && i < s->ncols; i++) {
16554 BINDCOL *b = &s->bindcols[i];
16555 SQLPOINTER dp = 0;
16556 SQLLEN *lp = 0;
16557
16558 b->offs = 0;
16559 if (b->valp) {
16560 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16561 dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
16562 } else {
16563 dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
16564 }
16565 if (s->bind_offs) {
16566 dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
16567 }
16568 }
16569 if (b->lenp) {
16570 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16571 lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
16572 } else {
16573 lp = b->lenp + rsi;
16574 }
16575 if (s->bind_offs) {
16576 lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
16577 }
16578 }
16579 if (dp || lp) {
16580 ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp, b->max, lp, 0);
16581 if (!SQL_SUCCEEDED(ret)) {
16582 s->row_status0[rsi] = SQL_ROW_ERROR;
16583 break;
16584 }
16585 if (ret != SQL_SUCCESS) {
16586 withinfo = 1;
16587#ifdef SQL_ROW_SUCCESS_WITH_INFO
16588 s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
16589#endif
16590 }
16591 }
16592 }
16593 if (SQL_SUCCEEDED(ret)) {
16594 ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16595 }
16596 return ret;
16597}
16598
16607static SQLRETURN
16608drvfetchscroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLINTEGER offset)
16609{
16610 STMT *s;
16611 int i, withinfo = 0;
16612 SQLRETURN ret;
16613
16614 if (stmt == SQL_NULL_HSTMT) {
16615 return SQL_INVALID_HANDLE;
16616 }
16617 s = (STMT *) stmt;
16618 for (i = 0; i < s->rowset_size; i++) {
16619 s->row_status0[i] = SQL_ROW_NOROW;
16620 }
16621 if (s->row_status) {
16622 memcpy(s->row_status, s->row_status0,
16623 sizeof (SQLUSMALLINT) * s->rowset_size);
16624 }
16625 s->row_count0 = 0;
16626 if (s->row_count) {
16627 *s->row_count = s->row_count0;
16628 }
16629 if (!s->bindcols) {
16630 for (i = 0; i < s->rowset_size; i++) {
16631 s->row_status0[i] = SQL_ROW_ERROR;
16632 }
16633 ret = SQL_ERROR;
16634 i = 0;
16635 goto done2;
16636 }
16637 if (s->isselect != 1 && s->isselect != -1) {
16638 setstat(s, -1, "no result set available", "24000");
16639 ret = SQL_ERROR;
16640 i = s->nrows;
16641 goto done2;
16642 }
16643 if (s->curtype == SQL_CURSOR_FORWARD_ONLY && orient != SQL_FETCH_NEXT) {
16644 setstat(s, -1, "wrong fetch direction", "01000");
16645 ret = SQL_ERROR;
16646 i = 0;
16647 goto done2;
16648 }
16649 ret = SQL_SUCCESS;
16650 i = 0;
16651 if (((DBC *) (s->dbc))->cur_s3stmt == s && s->s3stmt) {
16652 s->rowp = s->rowprs = 0;
16653 for (; i < s->rowset_size; i++) {
16654 if (s->max_rows && s->s3stmt_rownum + 1 >= s->max_rows) {
16655 ret = (i == 0) ? SQL_NO_DATA : SQL_SUCCESS;
16656 break;
16657 }
16658 ret = s3stmt_step(s);
16659 if (ret != SQL_SUCCESS) {
16660 s->row_status0[i] = SQL_ROW_ERROR;
16661 break;
16662 }
16663 if (s->nrows < 1) {
16664 break;
16665 }
16666 ret = dofetchbind(s, i);
16667 if (!SQL_SUCCEEDED(ret)) {
16668 break;
16669 } else if (ret == SQL_SUCCESS_WITH_INFO) {
16670 withinfo = 1;
16671 }
16672 }
16673 } else if (s->rows) {
16674 switch (orient) {
16675 case SQL_FETCH_NEXT:
16676 if (s->nrows < 1) {
16677 return SQL_NO_DATA;
16678 }
16679 if (s->rowp < 0) {
16680 s->rowp = -1;
16681 }
16682 if (s->rowp >= s->nrows) {
16683 s->rowp = s->rowprs = s->nrows;
16684 return SQL_NO_DATA;
16685 }
16686 break;
16687 case SQL_FETCH_PRIOR:
16688 if (s->nrows < 1 || s->rowp <= 0) {
16689 s->rowp = s->rowprs = -1;
16690 return SQL_NO_DATA;
16691 }
16692 s->rowp -= s->rowset_size + 1;
16693 if (s->rowp < -1) {
16694 s->rowp = s->rowprs = -1;
16695 return SQL_NO_DATA;
16696 }
16697 break;
16698 case SQL_FETCH_FIRST:
16699 if (s->nrows < 1) {
16700 return SQL_NO_DATA;
16701 }
16702 s->rowp = -1;
16703 break;
16704 case SQL_FETCH_LAST:
16705 if (s->nrows < 1) {
16706 return SQL_NO_DATA;
16707 }
16708 s->rowp = s->nrows - s->rowset_size;
16709 if (--s->rowp < -1) {
16710 s->rowp = -1;
16711 }
16712 break;
16713 case SQL_FETCH_ABSOLUTE:
16714 if (offset == 0) {
16715 s->rowp = s->rowprs = -1;
16716 return SQL_NO_DATA;
16717 } else if (offset < 0) {
16718 if (0 - offset <= s->nrows) {
16719 s->rowp = s->nrows + offset - 1;
16720 break;
16721 }
16722 s->rowp = s->rowprs = -1;
16723 return SQL_NO_DATA;
16724 } else if (offset > s->nrows) {
16725 s->rowp = s->rowprs = s->nrows;
16726 return SQL_NO_DATA;
16727 }
16728 s->rowp = offset - 1 - 1;
16729 break;
16730 case SQL_FETCH_RELATIVE:
16731 if (offset >= 0) {
16732 s->rowp += offset * s->rowset_size - 1;
16733 if (s->rowp >= s->nrows) {
16734 s->rowp = s->rowprs = s->nrows;
16735 return SQL_NO_DATA;
16736 }
16737 } else {
16738 s->rowp += offset * s->rowset_size - 1;
16739 if (s->rowp < -1) {
16740 s->rowp = s->rowprs = -1;
16741 return SQL_NO_DATA;
16742 }
16743 }
16744 break;
16745 case SQL_FETCH_BOOKMARK:
16746 if (s->bkmrk == SQL_UB_ON && !s->bkmrkptr) {
16747 if (offset < 0 || offset >= s->nrows) {
16748 return SQL_NO_DATA;
16749 }
16750 s->rowp = offset - 1;
16751 break;
16752 }
16753 if (s->bkmrk != SQL_UB_OFF && s->bkmrkptr) {
16754 int rowp;
16755
16756 if (s->bkmrk == SQL_UB_VARIABLE) {
16757 if (s->has_rowid >= 0) {
16758 sqlite_int64 bkmrk, rowid;
16759
16760 bkmrk = *(sqlite_int64 *) s->bkmrkptr;
16761 for (rowp = 0; rowp < s->nrows; rowp++) {
16762 char **data, *endp = 0;
16763
16764 data = s->rows + s->ncols + (rowp * s->ncols)
16765 + s->has_rowid;
16766#ifdef __osf__
16767 rowid = strtol(*data, &endp, 0);
16768#else
16769 rowid = strtoll(*data, &endp, 0);
16770#endif
16771 if (rowid == bkmrk) {
16772 break;
16773 }
16774 }
16775 } else {
16776 rowp = *(sqlite_int64 *) s->bkmrkptr;
16777 }
16778 } else {
16779 rowp = *(int *) s->bkmrkptr;
16780 }
16781 if (rowp + offset < 0 || rowp + offset >= s->nrows) {
16782 return SQL_NO_DATA;
16783 }
16784 s->rowp = rowp + offset - 1;
16785 break;
16786 }
16787 /* fall through */
16788 default:
16789 s->row_status0[0] = SQL_ROW_ERROR;
16790 ret = SQL_ERROR;
16791 goto done;
16792 }
16793 s->rowprs = s->rowp + 1;
16794 for (; i < s->rowset_size; i++) {
16795 ++s->rowp;
16796 if (s->rowp < 0 || s->rowp >= s->nrows) {
16797 break;
16798 }
16799 ret = dofetchbind(s, i);
16800 if (!SQL_SUCCEEDED(ret)) {
16801 break;
16802 } else if (ret == SQL_SUCCESS_WITH_INFO) {
16803 withinfo = 1;
16804 }
16805 }
16806 }
16807done:
16808 if (i == 0) {
16809 if (SQL_SUCCEEDED(ret)) {
16810 return SQL_NO_DATA;
16811 }
16812 return ret;
16813 }
16814 if (SQL_SUCCEEDED(ret)) {
16815 ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16816 }
16817done2:
16818 if (s->row_status) {
16819 memcpy(s->row_status, s->row_status0,
16820 sizeof (SQLUSMALLINT) * s->rowset_size);
16821 }
16822 s->row_count0 = i;
16823 if (s->row_count) {
16824 *s->row_count = s->row_count0;
16825 }
16826 return ret;
16827}
16828
16835SQLRETURN SQL_API
16837{
16838 SQLRETURN ret;
16839
16841 ret = drvfetchscroll(stmt, SQL_FETCH_NEXT, 0);
16843 return ret;
16844}
16845
16854SQLRETURN SQL_API
16855SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLLEN offset)
16856{
16857 SQLRETURN ret;
16858
16860 ret = drvfetchscroll(stmt, orient, offset);
16862 return ret;
16863}
16864
16875SQLRETURN SQL_API
16876SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT orient, SQLROWOFFSET offset,
16877 SQLROWSETSIZE *rowcount, SQLUSMALLINT *rowstatus)
16878{
16879 STMT *s;
16880 SQLRETURN ret;
16881 SQLUSMALLINT *rst;
16882 SQLINTEGER *bkmrkptr;
16883
16885 if (stmt == SQL_NULL_HSTMT) {
16886 return SQL_INVALID_HANDLE;
16887 }
16888 s = (STMT *) stmt;
16889 /* temporarily turn off SQL_ATTR_ROW_STATUS_PTR */
16890 rst = s->row_status;
16891 s->row_status = 0;
16892 bkmrkptr = s->bkmrkptr;
16893 s->bkmrkptr = 0;
16894 ret = drvfetchscroll(stmt, orient, offset);
16895 s->row_status = rst;
16896 s->bkmrkptr = bkmrkptr;
16897 if (rowstatus) {
16898 memcpy(rowstatus, s->row_status0,
16899 sizeof (SQLUSMALLINT) * s->rowset_size);
16900 }
16901 if (rowcount) {
16902 *rowcount = s->row_count0;
16903 }
16905 return ret;
16906}
16907
16915SQLRETURN SQL_API
16916SQLRowCount(SQLHSTMT stmt, SQLLEN *nrows)
16917{
16918 STMT *s;
16919
16921 if (stmt == SQL_NULL_HSTMT) {
16922 return SQL_INVALID_HANDLE;
16923 }
16924 s = (STMT *) stmt;
16925 if (nrows) {
16926 *nrows = s->isselect ? 0 : s->nrows;
16927 }
16929 return SQL_SUCCESS;
16930}
16931
16939SQLRETURN SQL_API
16940SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *ncols)
16941{
16942 STMT *s;
16943
16945 if (stmt == SQL_NULL_HSTMT) {
16946 return SQL_INVALID_HANDLE;
16947 }
16948 s = (STMT *) stmt;
16949 if (ncols) {
16950 *ncols = s->ncols;
16951 }
16953 return SQL_SUCCESS;
16954}
16955
16970static SQLRETURN
16971drvdescribecol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
16972 SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
16973 SQLSMALLINT *type, SQLULEN *size,
16974 SQLSMALLINT *digits, SQLSMALLINT *nullable)
16975{
16976 STMT *s;
16977 COL *c;
16978 int didname = 0;
16979
16980 if (stmt == SQL_NULL_HSTMT) {
16981 return SQL_INVALID_HANDLE;
16982 }
16983 s = (STMT *) stmt;
16984 if (!s->cols) {
16985 setstat(s, -1, "no columns", (*s->ov3) ? "07009" : "S1002");
16986 return SQL_ERROR;
16987 }
16988 if (col < 1 || col > s->ncols) {
16989 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
16990 return SQL_ERROR;
16991 }
16992 c = s->cols + col - 1;
16993 if (name && nameMax > 0) {
16994 strncpy((char *) name, c->column, nameMax);
16995 name[nameMax - 1] = '\0';
16996 didname = 1;
16997 }
16998 if (nameLen) {
16999 if (didname) {
17000 *nameLen = strlen((char *) name);
17001 } else {
17002 *nameLen = strlen(c->column);
17003 }
17004 }
17005 if (type) {
17006 *type = c->type;
17007#ifdef WINTERFACE
17008 if (s->nowchar[0] || s->nowchar[1]) {
17009 switch (c->type) {
17010 case SQL_WCHAR:
17011 *type = SQL_CHAR;
17012 break;
17013 case SQL_WVARCHAR:
17014 *type = SQL_VARCHAR;
17015 break;
17016#ifdef SQL_LONGVARCHAR
17017 case SQL_WLONGVARCHAR:
17018 *type = SQL_LONGVARCHAR;
17019 break;
17020#endif
17021 }
17022 }
17023#endif
17024 }
17025 if (size) {
17026 *size = c->size;
17027 }
17028 if (digits) {
17029 *digits = 0;
17030 }
17031 if (nullable) {
17032 *nullable = 1;
17033 }
17034 return SQL_SUCCESS;
17035}
17036
17037#ifndef WINTERFACE
17052SQLRETURN SQL_API
17053SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
17054 SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
17055 SQLSMALLINT *type, SQLULEN *size,
17056 SQLSMALLINT *digits, SQLSMALLINT *nullable)
17057{
17058#if defined(_WIN32) || defined(_WIN64)
17059 SQLSMALLINT len = 0;
17060#endif
17061 SQLRETURN ret;
17062
17064#if defined(_WIN32) || defined(_WIN64)
17065 if (!((STMT *) stmt)->oemcp[0]) {
17066 ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
17067 type, size, digits, nullable);
17068 goto done;
17069 }
17070 ret = drvdescribecol(stmt, col, name, nameMax,
17071 &len, type, size, digits, nullable);
17072 if (ret == SQL_SUCCESS) {
17073 if (name) {
17074 if (len > 0) {
17075 SQLCHAR *n = NULL;
17076
17077 n = (SQLCHAR *) utf_to_wmb((char *) name, len);
17078 if (n) {
17079 strncpy((char *) name, (char *) n, nameMax);
17080 n[len] = 0;
17081 len = min(nameMax, strlen((char *) n));
17082 uc_free(n);
17083 } else {
17084 len = 0;
17085 }
17086 }
17087 if (len <= 0) {
17088 len = 0;
17089 if (nameMax > 0) {
17090 name[0] = 0;
17091 }
17092 }
17093 } else {
17094 STMT *s = (STMT *) stmt;
17095 COL *c = s->cols + col - 1;
17096
17097 len = 0;
17098 if (c->column) {
17099 len = strlen(c->column);
17100 }
17101 }
17102 if (nameLen) {
17103 *nameLen = len;
17104 }
17105 }
17106done:
17107 ;
17108#else
17109 ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
17110 type, size, digits, nullable);
17111#endif
17113 return ret;
17114}
17115#endif
17116
17117#ifdef WINTERFACE
17132SQLRETURN SQL_API
17133SQLDescribeColW(SQLHSTMT stmt, SQLUSMALLINT col, SQLWCHAR *name,
17134 SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
17135 SQLSMALLINT *type, SQLULEN *size,
17136 SQLSMALLINT *digits, SQLSMALLINT *nullable)
17137{
17138 SQLRETURN ret;
17139 SQLSMALLINT len = 0;
17140
17142 ret = drvdescribecol(stmt, col, (SQLCHAR *) name,
17143 (SQLSMALLINT) (nameMax * sizeof (SQLWCHAR)),
17144 &len, type, size, digits, nullable);
17145 if (ret == SQL_SUCCESS) {
17146 if (name) {
17147 if (len > 0) {
17148 SQLWCHAR *n = NULL;
17149
17150 n = uc_from_utf((SQLCHAR *) name, len);
17151 if (n) {
17152 uc_strncpy(name, n, nameMax);
17153 n[len] = 0;
17154 len = min(nameMax, uc_strlen(n));
17155 uc_free(n);
17156 } else {
17157 len = 0;
17158 }
17159 }
17160 if (len <= 0) {
17161 len = 0;
17162 if (nameMax > 0) {
17163 name[0] = 0;
17164 }
17165 }
17166 } else {
17167 STMT *s = (STMT *) stmt;
17168 COL *c = s->cols + col - 1;
17169
17170 len = 0;
17171 if (c->column) {
17172 len = strlen(c->column);
17173 }
17174 }
17175 if (nameLen) {
17176 *nameLen = len;
17177 }
17178 }
17180 return ret;
17181}
17182#endif
17183
17196static SQLRETURN
17197drvcolattributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17198 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17199 SQLLEN *val2)
17200{
17201 STMT *s;
17202 COL *c;
17203 SQLSMALLINT dummy;
17204 char *valc = (char *) val;
17205
17206 if (stmt == SQL_NULL_HSTMT) {
17207 return SQL_INVALID_HANDLE;
17208 }
17209 s = (STMT *) stmt;
17210 if (!s->cols) {
17211 return SQL_ERROR;
17212 }
17213 if (!valLen) {
17214 valLen = &dummy;
17215 }
17216 if (id == SQL_COLUMN_COUNT) {
17217 if (val2) {
17218 *val2 = s->ncols;
17219 }
17220 *valLen = sizeof (int);
17221 return SQL_SUCCESS;
17222 }
17223 if (id == SQL_COLUMN_TYPE && col == 0) {
17224 if (val2) {
17225 *val2 = SQL_INTEGER;
17226 }
17227 *valLen = sizeof (int);
17228 return SQL_SUCCESS;
17229 }
17230#ifdef SQL_DESC_OCTET_LENGTH
17231 if (id == SQL_DESC_OCTET_LENGTH && col == 0) {
17232 if (val2) {
17233 *val2 = 4;
17234 }
17235 *valLen = sizeof (int);
17236 return SQL_SUCCESS;
17237 }
17238#endif
17239 if (col < 1 || col > s->ncols) {
17240 setstat(s, -1, "invalid column", (*s->ov3) ? "07009": "S1002");
17241 return SQL_ERROR;
17242 }
17243 c = s->cols + col - 1;
17244
17245 switch (id) {
17246 case SQL_COLUMN_LABEL:
17247 if (c->label) {
17248 if (valc && valMax > 0) {
17249 strncpy(valc, c->label, valMax);
17250 valc[valMax - 1] = '\0';
17251 }
17252 *valLen = strlen(c->label);
17253 goto checkLen;
17254 }
17255 /* fall through */
17256 case SQL_COLUMN_NAME:
17257 case SQL_DESC_NAME:
17258 if (valc && valMax > 0) {
17259 strncpy(valc, c->column, valMax);
17260 valc[valMax - 1] = '\0';
17261 }
17262 *valLen = strlen(c->column);
17263checkLen:
17264 if (*valLen >= valMax) {
17265 setstat(s, -1, "data right truncated", "01004");
17266 return SQL_SUCCESS_WITH_INFO;
17267 }
17268 return SQL_SUCCESS;
17269#ifdef SQL_DESC_BASE_COLUMN_NAME
17270 case SQL_DESC_BASE_COLUMN_NAME:
17271 if (strchr(c->column, '(') || strchr(c->column, ')')) {
17272 if (valc && valMax > 0) {
17273 valc[0] = '\0';
17274 }
17275 *valLen = 0;
17276 } else if (valc && valMax > 0) {
17277 strncpy(valc, c->column, valMax);
17278 valc[valMax - 1] = '\0';
17279 *valLen = strlen(c->column);
17280 }
17281 goto checkLen;
17282#endif
17283 case SQL_COLUMN_TYPE:
17284 case SQL_DESC_TYPE:
17285#ifdef WINTERFACE
17286 {
17287 int type = c->type;
17288
17289 if (s->nowchar[0] || s->nowchar[1]) {
17290 switch (type) {
17291 case SQL_WCHAR:
17292 type = SQL_CHAR;
17293 break;
17294 case SQL_WVARCHAR:
17295 type = SQL_VARCHAR;
17296 break;
17297#ifdef SQL_LONGVARCHAR
17298 case SQL_WLONGVARCHAR:
17299 type = SQL_LONGVARCHAR;
17300 break;
17301 }
17302 }
17303 if (val2) {
17304 *val2 = type;
17305 }
17306#endif
17307 }
17308#else
17309 if (val2) {
17310 *val2 = c->type;
17311 }
17312#endif
17313 *valLen = sizeof (int);
17314 return SQL_SUCCESS;
17315 case SQL_COLUMN_DISPLAY_SIZE:
17316 if (val2) {
17317 *val2 = c->size;
17318 }
17319 *valLen = sizeof (int);
17320 return SQL_SUCCESS;
17321 case SQL_COLUMN_UNSIGNED:
17322 if (val2) {
17323 *val2 = c->nosign ? SQL_TRUE : SQL_FALSE;
17324 }
17325 *valLen = sizeof (int);
17326 return SQL_SUCCESS;
17327 case SQL_COLUMN_SCALE:
17328 case SQL_DESC_SCALE:
17329 if (val2) {
17330 *val2 = c->scale;
17331 }
17332 *valLen = sizeof (int);
17333 return SQL_SUCCESS;
17334 case SQL_COLUMN_PRECISION:
17335 case SQL_DESC_PRECISION:
17336 if (val2) {
17337 switch (c->type) {
17338 case SQL_SMALLINT:
17339 *val2 = 5;
17340 break;
17341 case SQL_INTEGER:
17342 *val2 = 10;
17343 break;
17344 case SQL_FLOAT:
17345 case SQL_REAL:
17346 case SQL_DOUBLE:
17347 *val2 = 15;
17348 break;
17349 case SQL_DATE:
17350 *val2 = 0;
17351 break;
17352 case SQL_TIME:
17353 *val2 = 0;
17354 break;
17355#ifdef SQL_TYPE_TIMESTAMP
17356 case SQL_TYPE_TIMESTAMP:
17357#endif
17358 case SQL_TIMESTAMP:
17359 *val2 = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
17360 break;
17361 default:
17362 *val2 = c->prec;
17363 break;
17364 }
17365 }
17366 *valLen = sizeof (int);
17367 return SQL_SUCCESS;
17368 case SQL_COLUMN_MONEY:
17369 if (val2) {
17370 *val2 = SQL_FALSE;
17371 }
17372 *valLen = sizeof (int);
17373 return SQL_SUCCESS;
17374 case SQL_COLUMN_AUTO_INCREMENT:
17375 if (val2) {
17376 *val2 = c->autoinc;
17377 }
17378 *valLen = sizeof (int);
17379 return SQL_SUCCESS;
17380 case SQL_COLUMN_LENGTH:
17381 case SQL_DESC_LENGTH:
17382 if (val2) {
17383 *val2 = c->size;
17384 }
17385 *valLen = sizeof (int);
17386 return SQL_SUCCESS;
17387 case SQL_COLUMN_NULLABLE:
17388 case SQL_DESC_NULLABLE:
17389 if (val2) {
17390 *val2 = c->notnull;
17391 }
17392 *valLen = sizeof (int);
17393 return SQL_SUCCESS;
17394 case SQL_COLUMN_SEARCHABLE:
17395 if (val2) {
17396 *val2 = SQL_SEARCHABLE;
17397 }
17398 *valLen = sizeof (int);
17399 return SQL_SUCCESS;
17400 case SQL_COLUMN_CASE_SENSITIVE:
17401 if (val2) {
17402 *val2 = SQL_TRUE;
17403 }
17404 *valLen = sizeof (int);
17405 return SQL_SUCCESS;
17406 case SQL_COLUMN_UPDATABLE:
17407 if (val2) {
17408 *val2 = SQL_TRUE;
17409 }
17410 *valLen = sizeof (int);
17411 return SQL_SUCCESS;
17412 case SQL_DESC_COUNT:
17413 if (val2) {
17414 *val2 = s->ncols;
17415 }
17416 *valLen = sizeof (int);
17417 return SQL_SUCCESS;
17418 case SQL_COLUMN_TYPE_NAME: {
17419 char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17420
17421#ifdef WINTERFACE
17422 if (c->type == SQL_WCHAR ||
17423 c->type == SQL_WVARCHAR ||
17424 c->type == SQL_WLONGVARCHAR) {
17425 if (!(s->nowchar[0] || s->nowchar[1])) {
17426 if (strcasecmp(tn, "varchar") == 0) {
17427 tn = "wvarchar";
17428 }
17429 }
17430 }
17431#endif
17432 if (valc && valMax > 0) {
17433 strncpy(valc, tn, valMax);
17434 valc[valMax - 1] = '\0';
17435 p = strchr(valc, '(');
17436 if (p) {
17437 *p = '\0';
17438 while (p > valc && ISSPACE(p[-1])) {
17439 --p;
17440 *p = '\0';
17441 }
17442 }
17443 *valLen = strlen(valc);
17444 } else {
17445 *valLen = strlen(tn);
17446 p = strchr(tn, '(');
17447 if (p) {
17448 *valLen = p - tn;
17449 while (p > tn && ISSPACE(p[-1])) {
17450 --p;
17451 *valLen -= 1;
17452 }
17453 }
17454 }
17455 goto checkLen;
17456 }
17457 case SQL_COLUMN_OWNER_NAME:
17458 case SQL_COLUMN_QUALIFIER_NAME: {
17459 char *z = "";
17460
17461 if (valc && valMax > 0) {
17462 strncpy(valc, z, valMax);
17463 valc[valMax - 1] = '\0';
17464 }
17465 *valLen = strlen(z);
17466 goto checkLen;
17467 }
17468 case SQL_COLUMN_TABLE_NAME:
17469#if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17470 case SQL_DESC_TABLE_NAME:
17471#endif
17472#ifdef SQL_DESC_BASE_TABLE_NAME
17473 case SQL_DESC_BASE_TABLE_NAME:
17474#endif
17475 if (valc && valMax > 0) {
17476 strncpy(valc, c->table, valMax);
17477 valc[valMax - 1] = '\0';
17478 }
17479 *valLen = strlen(c->table);
17480 goto checkLen;
17481#ifdef SQL_DESC_NUM_PREC_RADIX
17482 case SQL_DESC_NUM_PREC_RADIX:
17483 if (val2) {
17484 switch (c->type) {
17485#ifdef WINTERFACE
17486 case SQL_WCHAR:
17487 case SQL_WVARCHAR:
17488#ifdef SQL_LONGVARCHAR
17489 case SQL_WLONGVARCHAR:
17490#endif
17491#endif
17492 case SQL_CHAR:
17493 case SQL_VARCHAR:
17494#ifdef SQL_LONGVARCHAR
17495 case SQL_LONGVARCHAR:
17496#endif
17497 case SQL_BINARY:
17498 case SQL_VARBINARY:
17499 case SQL_LONGVARBINARY:
17500 *val2 = 0;
17501 break;
17502 default:
17503 *val2 = 2;
17504 }
17505 }
17506 *valLen = sizeof (int);
17507 return SQL_SUCCESS;
17508#endif
17509 }
17510 setstat(s, -1, "unsupported column attributes %d", "HY091", id);
17511 return SQL_ERROR;
17512}
17513
17514#ifndef WINTERFACE
17527SQLRETURN SQL_API
17528SQLColAttributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17529 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17530 SQLLEN *val2)
17531{
17532#if defined(_WIN32) || defined(_WIN64)
17533 SQLSMALLINT len = 0;
17534#endif
17535 SQLRETURN ret;
17536
17538#if defined(_WIN32) || defined(_WIN64)
17539 if (!((STMT *) stmt)->oemcp[0]) {
17540 ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17541 goto done;
17542 }
17543 ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17544 if (SQL_SUCCEEDED(ret)) {
17545 char *v = NULL;
17546
17547 switch (id) {
17548 case SQL_COLUMN_LABEL:
17549 case SQL_COLUMN_NAME:
17550 case SQL_DESC_NAME:
17551 case SQL_COLUMN_TYPE_NAME:
17552 case SQL_COLUMN_OWNER_NAME:
17553 case SQL_COLUMN_QUALIFIER_NAME:
17554 case SQL_COLUMN_TABLE_NAME:
17555#if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17556 case SQL_DESC_TABLE_NAME:
17557#endif
17558#ifdef SQL_DESC_BASE_COLUMN_NAME
17559 case SQL_DESC_BASE_COLUMN_NAME:
17560#endif
17561#ifdef SQL_DESC_BASE_TABLE_NAME
17562 case SQL_DESC_BASE_TABLE_NAME:
17563#endif
17564 if (val && valMax > 0) {
17565 int vmax = valMax;
17566
17567 v = utf_to_wmb((char *) val, SQL_NTS);
17568 if (v) {
17569 strncpy(val, v, vmax);
17570 len = min(vmax, strlen(v));
17571 uc_free(v);
17572 }
17573 if (vmax > 0) {
17574 v = (char *) val;
17575 v[vmax - 1] = '\0';
17576 }
17577 }
17578 if (len <= 0) {
17579 len = 0;
17580 }
17581 break;
17582 }
17583 if (valLen) {
17584 *valLen = len;
17585 }
17586 }
17587done:
17588 ;
17589#else
17590 ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17591#endif
17593 return ret;
17594}
17595#endif
17596
17597#ifdef WINTERFACE
17610SQLRETURN SQL_API
17611SQLColAttributesW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17612 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17613 SQLLEN *val2)
17614{
17615 SQLRETURN ret;
17616 SQLSMALLINT len = 0;
17617
17619 ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17620 if (SQL_SUCCEEDED(ret)) {
17621 SQLWCHAR *v = NULL;
17622
17623 switch (id) {
17624 case SQL_COLUMN_LABEL:
17625 case SQL_COLUMN_NAME:
17626 case SQL_DESC_NAME:
17627 case SQL_COLUMN_TYPE_NAME:
17628 case SQL_COLUMN_OWNER_NAME:
17629 case SQL_COLUMN_QUALIFIER_NAME:
17630 case SQL_COLUMN_TABLE_NAME:
17631#if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17632 case SQL_DESC_TABLE_NAME:
17633#endif
17634#ifdef SQL_DESC_BASE_COLUMN_NAME
17635 case SQL_DESC_BASE_COLUMN_NAME:
17636#endif
17637#ifdef SQL_DESC_BASE_TABLE_NAME
17638 case SQL_DESC_BASE_TABLE_NAME:
17639#endif
17640 if (val && valMax > 0) {
17641 int vmax = valMax / sizeof (SQLWCHAR);
17642
17643 v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
17644 if (v) {
17645 uc_strncpy(val, v, vmax);
17646 len = min(vmax, uc_strlen(v));
17647 uc_free(v);
17648 len *= sizeof (SQLWCHAR);
17649 }
17650 if (vmax > 0) {
17651 v = (SQLWCHAR *) val;
17652 v[vmax - 1] = '\0';
17653 }
17654 }
17655 if (len <= 0) {
17656 len = 0;
17657 }
17658 break;
17659 }
17660 if (valLen) {
17661 *valLen = len;
17662 }
17663 }
17665 return ret;
17666}
17667#endif
17668
17681static SQLRETURN
17682drvcolattribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17683 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17684 SQLPOINTER val2)
17685{
17686 STMT *s;
17687 COL *c;
17688 int v = 0;
17689 char *valc = (char *) val;
17690 SQLSMALLINT dummy;
17691
17692 if (stmt == SQL_NULL_HSTMT) {
17693 return SQL_INVALID_HANDLE;
17694 }
17695 s = (STMT *) stmt;
17696 if (!s->cols) {
17697 return SQL_ERROR;
17698 }
17699 if (col < 1 || col > s->ncols) {
17700 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
17701 return SQL_ERROR;
17702 }
17703 if (!valLen) {
17704 valLen = &dummy;
17705 }
17706 c = s->cols + col - 1;
17707 switch (id) {
17708 case SQL_DESC_COUNT:
17709 v = s->ncols;
17710 break;
17711 case SQL_DESC_CATALOG_NAME:
17712 if (valc && valMax > 0) {
17713 strncpy(valc, c->db, valMax);
17714 valc[valMax - 1] = '\0';
17715 }
17716 *valLen = strlen(c->db);
17717checkLen:
17718 if (*valLen >= valMax) {
17719 setstat(s, -1, "data right truncated", "01004");
17720 return SQL_SUCCESS_WITH_INFO;
17721 }
17722 break;
17723 case SQL_COLUMN_LENGTH:
17724 case SQL_DESC_LENGTH:
17725 v = c->size;
17726 break;
17727 case SQL_COLUMN_LABEL:
17728 if (c->label) {
17729 if (valc && valMax > 0) {
17730 strncpy(valc, c->label, valMax);
17731 valc[valMax - 1] = '\0';
17732 }
17733 *valLen = strlen(c->label);
17734 goto checkLen;
17735 }
17736 /* fall through */
17737 case SQL_COLUMN_NAME:
17738 case SQL_DESC_NAME:
17739 if (valc && valMax > 0) {
17740 strncpy(valc, c->column, valMax);
17741 valc[valMax - 1] = '\0';
17742 }
17743 *valLen = strlen(c->column);
17744 goto checkLen;
17745 case SQL_DESC_SCHEMA_NAME: {
17746 char *z = "";
17747
17748 if (valc && valMax > 0) {
17749 strncpy(valc, z, valMax);
17750 valc[valMax - 1] = '\0';
17751 }
17752 *valLen = strlen(z);
17753 goto checkLen;
17754 }
17755#ifdef SQL_DESC_BASE_COLUMN_NAME
17756 case SQL_DESC_BASE_COLUMN_NAME:
17757 if (strchr(c->column, '(') || strchr(c->column, ')')) {
17758 valc[0] = '\0';
17759 *valLen = 0;
17760 } else if (valc && valMax > 0) {
17761 strncpy(valc, c->column, valMax);
17762 valc[valMax - 1] = '\0';
17763 *valLen = strlen(c->column);
17764 }
17765 goto checkLen;
17766#endif
17767 case SQL_DESC_TYPE_NAME: {
17768 char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17769
17770#ifdef WINTERFACE
17771 if (c->type == SQL_WCHAR ||
17772 c->type == SQL_WVARCHAR ||
17773 c->type == SQL_WLONGVARCHAR) {
17774 if (!(s->nowchar[0] || s->nowchar[1])) {
17775 if (strcasecmp(tn, "varchar") == 0) {
17776 tn = "wvarchar";
17777 }
17778 }
17779 }
17780#endif
17781 if (valc && valMax > 0) {
17782 strncpy(valc, tn, valMax);
17783 valc[valMax - 1] = '\0';
17784 p = strchr(valc, '(');
17785 if (p) {
17786 *p = '\0';
17787 while (p > valc && ISSPACE(p[-1])) {
17788 --p;
17789 *p = '\0';
17790 }
17791 }
17792 *valLen = strlen(valc);
17793 } else {
17794 *valLen = strlen(tn);
17795 p = strchr(tn, '(');
17796 if (p) {
17797 *valLen = p - tn;
17798 while (p > tn && ISSPACE(p[-1])) {
17799 --p;
17800 *valLen -= 1;
17801 }
17802 }
17803 }
17804 goto checkLen;
17805 }
17806 case SQL_DESC_OCTET_LENGTH:
17807 v = c->size;
17808#ifdef WINTERFACE
17809 if (c->type == SQL_WCHAR ||
17810 c->type == SQL_WVARCHAR ||
17811 c->type == SQL_WLONGVARCHAR) {
17812 if (!(s->nowchar[0] || s->nowchar[1])) {
17813 v *= sizeof (SQLWCHAR);
17814 }
17815 }
17816#endif
17817 break;
17818#if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17819 case SQL_COLUMN_TABLE_NAME:
17820#endif
17821#ifdef SQL_DESC_BASE_TABLE_NAME
17822 case SQL_DESC_BASE_TABLE_NAME:
17823#endif
17824 case SQL_DESC_TABLE_NAME:
17825 if (valc && valMax > 0) {
17826 strncpy(valc, c->table, valMax);
17827 valc[valMax - 1] = '\0';
17828 }
17829 *valLen = strlen(c->table);
17830 goto checkLen;
17831 case SQL_DESC_TYPE:
17832 v = c->type;
17833#ifdef WINTERFACE
17834 if (s->nowchar[0] || s->nowchar[1]) {
17835 switch (v) {
17836 case SQL_WCHAR:
17837 v = SQL_CHAR;
17838 break;
17839 case SQL_WVARCHAR:
17840 v = SQL_VARCHAR;
17841 break;
17842#ifdef SQL_LONGVARCHAR
17843 case SQL_WLONGVARCHAR:
17844 v = SQL_LONGVARCHAR;
17845 break;
17846#endif
17847 }
17848 }
17849#endif
17850 break;
17851 case SQL_DESC_CONCISE_TYPE:
17852 switch (c->type) {
17853 case SQL_INTEGER:
17854 v = SQL_C_LONG;
17855 break;
17856 case SQL_TINYINT:
17857 v = SQL_C_TINYINT;
17858 break;
17859 case SQL_SMALLINT:
17860 v = SQL_C_SHORT;
17861 break;
17862 case SQL_FLOAT:
17863 v = SQL_C_FLOAT;
17864 break;
17865 case SQL_DOUBLE:
17866 v = SQL_C_DOUBLE;
17867 break;
17868 case SQL_TIMESTAMP:
17869 v = SQL_C_TIMESTAMP;
17870 break;
17871 case SQL_TIME:
17872 v = SQL_C_TIME;
17873 break;
17874 case SQL_DATE:
17875 v = SQL_C_DATE;
17876 break;
17877#ifdef SQL_C_TYPE_TIMESTAMP
17878 case SQL_TYPE_TIMESTAMP:
17879 v = SQL_C_TYPE_TIMESTAMP;
17880 break;
17881#endif
17882#ifdef SQL_C_TYPE_TIME
17883 case SQL_TYPE_TIME:
17884 v = SQL_C_TYPE_TIME;
17885 break;
17886#endif
17887#ifdef SQL_C_TYPE_DATE
17888 case SQL_TYPE_DATE:
17889 v = SQL_C_TYPE_DATE;
17890 break;
17891#endif
17892#ifdef SQL_BIT
17893 case SQL_BIT:
17894 v = SQL_C_BIT;
17895 break;
17896#endif
17897#ifdef SQL_BIGINT
17898 case SQL_BIGINT:
17899 v = SQL_C_SBIGINT;
17900 break;
17901#endif
17902 default:
17903#ifdef WINTERFACE
17904 v = (s->nowchar[0] || s->nowchar[1]) ? SQL_C_CHAR : SQL_C_WCHAR;
17905#else
17906 v = SQL_C_CHAR;
17907#endif
17908 break;
17909 }
17910 break;
17911 case SQL_DESC_UPDATABLE:
17912 v = SQL_TRUE;
17913 break;
17914 case SQL_COLUMN_DISPLAY_SIZE:
17915 v = c->size;
17916 break;
17917 case SQL_COLUMN_UNSIGNED:
17918 v = c->nosign ? SQL_TRUE : SQL_FALSE;
17919 break;
17920 case SQL_COLUMN_SEARCHABLE:
17921 v = SQL_SEARCHABLE;
17922 break;
17923 case SQL_COLUMN_SCALE:
17924 case SQL_DESC_SCALE:
17925 v = c->scale;
17926 break;
17927 case SQL_COLUMN_PRECISION:
17928 case SQL_DESC_PRECISION:
17929 switch (c->type) {
17930 case SQL_SMALLINT:
17931 v = 5;
17932 break;
17933 case SQL_INTEGER:
17934 v = 10;
17935 break;
17936 case SQL_FLOAT:
17937 case SQL_REAL:
17938 case SQL_DOUBLE:
17939 v = 15;
17940 break;
17941 case SQL_DATE:
17942 v = 0;
17943 break;
17944 case SQL_TIME:
17945 v = 0;
17946 break;
17947#ifdef SQL_TYPE_TIMESTAMP
17948 case SQL_TYPE_TIMESTAMP:
17949#endif
17950 case SQL_TIMESTAMP:
17951 v = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
17952 break;
17953 default:
17954 v = c->prec;
17955 break;
17956 }
17957 break;
17958 case SQL_COLUMN_MONEY:
17959 v = SQL_FALSE;
17960 break;
17961 case SQL_COLUMN_AUTO_INCREMENT:
17962 v = c->autoinc;
17963 break;
17964 case SQL_DESC_NULLABLE:
17965 v = c->notnull;
17966 break;
17967#ifdef SQL_DESC_NUM_PREC_RADIX
17968 case SQL_DESC_NUM_PREC_RADIX:
17969 switch (c->type) {
17970#ifdef WINTERFACE
17971 case SQL_WCHAR:
17972 case SQL_WVARCHAR:
17973#ifdef SQL_LONGVARCHAR
17974 case SQL_WLONGVARCHAR:
17975#endif
17976#endif
17977 case SQL_CHAR:
17978 case SQL_VARCHAR:
17979#ifdef SQL_LONGVARCHAR
17980 case SQL_LONGVARCHAR:
17981#endif
17982 case SQL_BINARY:
17983 case SQL_VARBINARY:
17984 case SQL_LONGVARBINARY:
17985 v = 0;
17986 break;
17987 default:
17988 v = 2;
17989 }
17990 break;
17991#endif
17992 default:
17993 setstat(s, -1, "unsupported column attribute %d", "HY091", id);
17994 return SQL_ERROR;
17995 }
17996 if (val2) {
17997 *(SQLLEN *) val2 = v;
17998 }
17999 return SQL_SUCCESS;
18000}
18001
18002#ifndef WINTERFACE
18015SQLRETURN SQL_API
18016SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
18017 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
18019{
18020#if defined(_WIN32) || defined(_WIN64)
18021 SQLSMALLINT len = 0;
18022#endif
18023 SQLRETURN ret;
18024
18026#if defined(_WIN32) || defined(_WIN64)
18027 if (!((STMT *) stmt)->oemcp[0]) {
18028 ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
18029 (SQLPOINTER) val2);
18030 goto done;
18031 }
18032 ret = drvcolattribute(stmt, col, id, val, valMax, &len,
18033 (SQLPOINTER) val2);
18034 if (SQL_SUCCEEDED(ret)) {
18035 char *v = NULL;
18036
18037 switch (id) {
18038 case SQL_DESC_SCHEMA_NAME:
18039 case SQL_DESC_CATALOG_NAME:
18040 case SQL_COLUMN_LABEL:
18041 case SQL_DESC_NAME:
18042 case SQL_DESC_TABLE_NAME:
18043#ifdef SQL_DESC_BASE_TABLE_NAME
18044 case SQL_DESC_BASE_TABLE_NAME:
18045#endif
18046#ifdef SQL_DESC_BASE_COLUMN_NAME
18047 case SQL_DESC_BASE_COLUMN_NAME:
18048#endif
18049 case SQL_DESC_TYPE_NAME:
18050 if (val && valMax > 0) {
18051 int vmax = valMax;
18052
18053 v = utf_to_wmb((char *) val, SQL_NTS);
18054 if (v) {
18055 strncpy(val, v, vmax);
18056 len = min(vmax, strlen(v));
18057 uc_free(v);
18058 }
18059 if (vmax > 0) {
18060 v = (char *) val;
18061 v[vmax - 1] = '\0';
18062 }
18063 }
18064 if (len <= 0) {
18065 len = 0;
18066 }
18067 break;
18068 }
18069 if (valLen) {
18070 *valLen = len;
18071 }
18072 }
18073done:
18074 ;
18075#else
18076 ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
18077 (SQLPOINTER) val2);
18078#endif
18080 return ret;
18081}
18082#endif
18083
18084#ifdef WINTERFACE
18097SQLRETURN SQL_API
18098SQLColAttributeW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
18099 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
18101{
18102 SQLRETURN ret;
18103 SQLSMALLINT len = 0;
18104
18106 ret = drvcolattribute(stmt, col, id, val, valMax, &len,
18107 (SQLPOINTER) val2);
18108 if (SQL_SUCCEEDED(ret)) {
18109 SQLWCHAR *v = NULL;
18110
18111 switch (id) {
18112 case SQL_DESC_SCHEMA_NAME:
18113 case SQL_DESC_CATALOG_NAME:
18114 case SQL_COLUMN_LABEL:
18115 case SQL_DESC_NAME:
18116 case SQL_DESC_TABLE_NAME:
18117#ifdef SQL_DESC_BASE_TABLE_NAME
18118 case SQL_DESC_BASE_TABLE_NAME:
18119#endif
18120#ifdef SQL_DESC_BASE_COLUMN_NAME
18121 case SQL_DESC_BASE_COLUMN_NAME:
18122#endif
18123 case SQL_DESC_TYPE_NAME:
18124 if (val && valMax > 0) {
18125 int vmax = valMax / sizeof (SQLWCHAR);
18126
18127 v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
18128 if (v) {
18129 uc_strncpy(val, v, vmax);
18130 len = min(vmax, uc_strlen(v));
18131 uc_free(v);
18132 len *= sizeof (SQLWCHAR);
18133 }
18134 if (vmax > 0) {
18135 v = (SQLWCHAR *) val;
18136 v[vmax - 1] = '\0';
18137 }
18138 }
18139 if (len <= 0) {
18140 len = 0;
18141 }
18142 break;
18143 }
18144 if (valLen) {
18145 *valLen = len;
18146 }
18147 }
18149 return ret;
18150}
18151#endif
18152
18166static SQLRETURN
18167drverror(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18168 SQLCHAR *sqlState, SQLINTEGER *nativeErr,
18169 SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18170{
18171 SQLCHAR dummy0[6];
18172 SQLINTEGER dummy1;
18173 SQLSMALLINT dummy2;
18174
18175 if (env == SQL_NULL_HENV &&
18176 dbc == SQL_NULL_HDBC &&
18177 stmt == SQL_NULL_HSTMT) {
18178 return SQL_INVALID_HANDLE;
18179 }
18180 if (sqlState) {
18181 sqlState[0] = '\0';
18182 } else {
18183 sqlState = dummy0;
18184 }
18185 if (!nativeErr) {
18186 nativeErr = &dummy1;
18187 }
18188 *nativeErr = 0;
18189 if (!errlen) {
18190 errlen = &dummy2;
18191 }
18192 *errlen = 0;
18193 if (errmsg) {
18194 if (errmax > 0) {
18195 errmsg[0] = '\0';
18196 }
18197 } else {
18198 errmsg = dummy0;
18199 errmax = 0;
18200 }
18201 if (stmt) {
18202 STMT *s = (STMT *) stmt;
18203
18205 if (s->logmsg[0] == '\0') {
18207 goto noerr;
18208 }
18209 *nativeErr = s->naterr;
18210 strcpy((char *) sqlState, s->sqlstate);
18211 if (errmax == SQL_NTS) {
18212 strcpy((char *) errmsg, "[SQLite]");
18213 strcat((char *) errmsg, (char *) s->logmsg);
18214 *errlen = strlen((char *) errmsg);
18215 } else {
18216 strncpy((char *) errmsg, "[SQLite]", errmax);
18217 if (errmax - 8 > 0) {
18218 strncpy((char *) errmsg + 8, (char *) s->logmsg, errmax - 8);
18219 }
18220 *errlen = min(strlen((char *) s->logmsg) + 8, errmax);
18221 }
18222 s->logmsg[0] = '\0';
18224 return SQL_SUCCESS;
18225 }
18226 if (dbc) {
18227 DBC *d = (DBC *) dbc;
18228
18229 HDBC_LOCK(dbc);
18230 if (d->magic != DBC_MAGIC || d->logmsg[0] == '\0') {
18232 goto noerr;
18233 }
18234 *nativeErr = d->naterr;
18235 strcpy((char *) sqlState, d->sqlstate);
18236 if (errmax == SQL_NTS) {
18237 strcpy((char *) errmsg, "[SQLite]");
18238 strcat((char *) errmsg, (char *) d->logmsg);
18239 *errlen = strlen((char *) errmsg);
18240 } else {
18241 strncpy((char *) errmsg, "[SQLite]", errmax);
18242 if (errmax - 8 > 0) {
18243 strncpy((char *) errmsg + 8, (char *) d->logmsg, errmax - 8);
18244 }
18245 *errlen = min(strlen((char *) d->logmsg) + 8, errmax);
18246 }
18247 d->logmsg[0] = '\0';
18249 return SQL_SUCCESS;
18250 }
18251noerr:
18252 sqlState[0] = '\0';
18253 errmsg[0] = '\0';
18254 *nativeErr = 0;
18255 *errlen = 0;
18256 return SQL_NO_DATA;
18257}
18258
18259#ifndef WINTERFACE
18273SQLRETURN SQL_API
18274SQLError(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18275 SQLCHAR *sqlState, SQLINTEGER *nativeErr,
18276 SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18277{
18278 return drverror(env, dbc, stmt, sqlState, nativeErr,
18279 errmsg, errmax, errlen);
18280}
18281#endif
18282
18283#ifdef WINTERFACE
18297SQLRETURN SQL_API
18298SQLErrorW(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18299 SQLWCHAR *sqlState, SQLINTEGER *nativeErr,
18300 SQLWCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18301{
18302 char state[16];
18303 SQLSMALLINT len = 0;
18304 SQLRETURN ret;
18305
18306 ret = drverror(env, dbc, stmt, (SQLCHAR *) state, nativeErr,
18307 (SQLCHAR *) errmsg, errmax, &len);
18308 if (ret == SQL_SUCCESS) {
18309 if (sqlState) {
18310 uc_from_utf_buf((SQLCHAR *) state, -1, sqlState,
18311 6 * sizeof (SQLWCHAR));
18312 }
18313 if (errmsg) {
18314 if (len > 0) {
18315 SQLWCHAR *e = NULL;
18316
18317 e = uc_from_utf((SQLCHAR *) errmsg, len);
18318 if (e) {
18319 if (errmax > 0) {
18320 uc_strncpy(errmsg, e, errmax);
18321 e[len] = 0;
18322 len = min(errmax, uc_strlen(e));
18323 } else {
18324 len = uc_strlen(e);
18325 }
18326 uc_free(e);
18327 } else {
18328 len = 0;
18329 }
18330 }
18331 if (len <= 0) {
18332 len = 0;
18333 if (errmax > 0) {
18334 errmsg[0] = 0;
18335 }
18336 }
18337 } else {
18338 len = 0;
18339 }
18340 if (errlen) {
18341 *errlen = len;
18342 }
18343 } else if (ret == SQL_NO_DATA) {
18344 if (sqlState) {
18345 sqlState[0] = 0;
18346 }
18347 if (errmsg) {
18348 if (errmax > 0) {
18349 errmsg[0] = 0;
18350 }
18351 }
18352 if (errlen) {
18353 *errlen = 0;
18354 }
18355 }
18356 return ret;
18357}
18358#endif
18359
18366SQLRETURN SQL_API
18367SQLMoreResults(SQLHSTMT stmt)
18368{
18370 if (stmt == SQL_NULL_HSTMT) {
18371 return SQL_INVALID_HANDLE;
18372 }
18374 return SQL_NO_DATA;
18375}
18376
18385static SQLRETURN
18386setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp)
18387{
18388 int ncols = *ncolsp, guessed_types = 0;
18389 SQLRETURN ret = SQL_SUCCESS;
18390
18391 if (ncols > 0) {
18392 int i;
18393 PTRDIFF_T size;
18394 char *p;
18395 COL *dyncols;
18396 DBC *d = (DBC *) s->dbc;
18397 const char *colname, *typename;
18398#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18399 char *tblname;
18400#endif
18401#if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18402 char *dbname;
18403#endif
18404
18405 for (i = size = 0; i < ncols; i++) {
18406 colname = sqlite3_column_name(s3stmt, i);
18407 size += 3 + 3 * strlen(colname);
18408 }
18409#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18410 tblname = (char *) size;
18411 for (i = 0; i < ncols; i++) {
18412 p = (char *) sqlite3_column_table_name(s3stmt, i);
18413 size += 2 + (p ? strlen(p) : 0);
18414 }
18415#endif
18416#if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18417 dbname = (char *) size;
18418 for (i = 0; i < ncols; i++) {
18419 p = (char *) sqlite3_column_database_name(s3stmt, i);
18420 size += 2 + (p ? strlen(p) : 0);
18421 }
18422#endif
18423 dyncols = xmalloc(ncols * sizeof (COL) + size);
18424 if (!dyncols) {
18425 freedyncols(s);
18426 *ncolsp = 0;
18427 ret = SQL_ERROR;
18428 } else {
18429 p = (char *) (dyncols + ncols);
18430#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18431 tblname = p + (PTRDIFF_T) tblname;
18432#endif
18433#if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18434 dbname = p + (PTRDIFF_T) dbname;
18435#endif
18436 for (i = 0; i < ncols; i++) {
18437 char *q;
18438
18439 colname = sqlite3_column_name(s3stmt, i);
18440 if (d->trace) {
18441 fprintf(d->trace, "-- column %d name: '%s'\n",
18442 i + 1, colname);
18443 fflush(d->trace);
18444 }
18445#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18446 q = (char *) sqlite3_column_table_name(s3stmt, i);
18447 strcpy(tblname, q ? q : "");
18448 if (d->trace) {
18449 fprintf(d->trace, "-- table %d name: '%s'\n",
18450 i + 1, tblname);
18451 fflush(d->trace);
18452 }
18453 dyncols[i].table = tblname;
18454 tblname += strlen(tblname) + 1;
18455#endif
18456#if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18457 q = (char *) sqlite3_column_database_name(s3stmt, i);
18458 strcpy(dbname, q ? q : "");
18459 if (d->trace) {
18460 fprintf(d->trace, "-- database %d name: '%s'\n",
18461 i + 1, dbname);
18462 fflush(d->trace);
18463 }
18464 dyncols[i].db = dbname;
18465 dbname += strlen(dbname) + 1;
18466#else
18467 dyncols[i].db = ((DBC *) (s->dbc))->dbname;
18468#endif
18469 typename = s3stmt_coltype(s3stmt, i, d, &guessed_types);
18470 strcpy(p, colname);
18471 dyncols[i].label = p;
18472 p += strlen(p) + 1;
18473 q = strchr(colname, '.');
18474 if (q) {
18475 char *q2 = strchr(q + 1, '.');
18476
18477 /* SQLite 3.3.4 produces view.table.column sometimes */
18478 if (q2) {
18479 q = q2;
18480 }
18481 }
18482 if (q) {
18483#if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18484 dyncols[i].table = p;
18485#endif
18486 strncpy(p, colname, q - colname);
18487 p[q - colname] = '\0';
18488 p += strlen(p) + 1;
18489 strcpy(p, q + 1);
18490 dyncols[i].column = p;
18491 p += strlen(p) + 1;
18492 } else {
18493#if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18494 dyncols[i].table = "";
18495#endif
18496 strcpy(p, colname);
18497 dyncols[i].column = p;
18498 p += strlen(p) + 1;
18499 }
18500 if (s->longnames) {
18501 dyncols[i].column = dyncols[i].label;
18502 }
18503#ifdef SQL_LONGVARCHAR
18504 dyncols[i].type = SQL_LONGVARCHAR;
18505 dyncols[i].size = 65535;
18506#else
18507 dyncols[i].type = SQL_VARCHAR;
18508 dyncols[i].size = 255;
18509#endif
18510 dyncols[i].index = i;
18511 dyncols[i].scale = 0;
18512 dyncols[i].prec = 0;
18513 dyncols[i].nosign = 1;
18514 dyncols[i].autoinc = SQL_FALSE;
18515 dyncols[i].notnull = SQL_NULLABLE;
18516 dyncols[i].ispk = -1;
18517 dyncols[i].isrowid = -1;
18518#ifdef FULL_METADATA
18519 s3stmt_addmeta(s3stmt, i, d, &dyncols[i]);
18520#endif
18521 dyncols[i].typename = xstrdup(typename);
18522 }
18523 freedyncols(s);
18524 s->dyncols = s->cols = dyncols;
18525 s->dcols = ncols;
18526 fixupdyncols(s, d);
18527 s->guessed_types = guessed_types;
18528 }
18529 }
18530 return ret;
18531}
18532
18541static SQLRETURN
18542drvprepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18543{
18544 STMT *s;
18545 DBC *d;
18546 char *errp = NULL;
18547 SQLRETURN sret;
18548
18549 if (stmt == SQL_NULL_HSTMT) {
18550 return SQL_INVALID_HANDLE;
18551 }
18552 s = (STMT *) stmt;
18553 if (s->dbc == SQL_NULL_HDBC) {
18554noconn:
18555 return noconn(s);
18556 }
18557 d = s->dbc;
18558 if (!d->sqlite) {
18559 goto noconn;
18560 }
18561 s3stmt_end(s);
18562 s3stmt_drop(s);
18563 sret = starttran(s);
18564 if (sret != SQL_SUCCESS) {
18565 return sret;
18566 }
18567 freep(&s->query);
18568 s->query = (SQLCHAR *) fixupsql((char *) query, queryLen,
18569 (d->version >= 0x030805),
18570 &s->nparams, &s->isselect, &errp);
18571 if (!s->query) {
18572 if (errp) {
18573 setstat(s, -1, "%s", (*s->ov3) ? "HY000" : "S1000", errp);
18574 return SQL_ERROR;
18575 }
18576 return nomem(s);
18577 }
18578 errp = NULL;
18579 freeresult(s, -1);
18580 if (s->isselect == 1) {
18581 int ret, ncols, nretry = 0;
18582 const char *rest;
18583 sqlite3_stmt *s3stmt = NULL;
18584
18585#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18586 dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
18587#else
18588 dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
18589#endif
18590 do {
18591 s3stmt = NULL;
18592#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18593 ret = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
18594 &s3stmt, &rest);
18595#else
18596 ret = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
18597 &s3stmt, &rest);
18598#endif
18599 if (ret != SQLITE_OK) {
18600 if (s3stmt) {
18601 sqlite3_finalize(s3stmt);
18602 s3stmt = NULL;
18603 }
18604 }
18605 } while (ret == SQLITE_SCHEMA && (++nretry) < 2);
18606 dbtracerc(d, ret, NULL);
18607 if (ret != SQLITE_OK) {
18608 if (s3stmt) {
18609 dbtraceapi(d, "sqlite3_finalize", 0);
18610 sqlite3_finalize(s3stmt);
18611 }
18612 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18613 sqlite3_errmsg(d->sqlite), ret);
18614 return SQL_ERROR;
18615 }
18616 if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
18617 dbtraceapi(d, "sqlite3_finalize", 0);
18618 sqlite3_finalize(s3stmt);
18619 setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
18620 (*s->ov3) ? "HY000" : "S1000");
18621 return SQL_ERROR;
18622 }
18623 ncols = sqlite3_column_count(s3stmt);
18624 s->guessed_types = 0;
18625 setupdyncols(s, s3stmt, &ncols);
18626 s->ncols = ncols;
18627 s->s3stmt = s3stmt;
18628 }
18629 mkbindcols(s, s->ncols);
18630 s->paramset_count = 0;
18631 return SQL_SUCCESS;
18632}
18633
18641static SQLRETURN
18642drvexecute(SQLHSTMT stmt, int initial)
18643{
18644 STMT *s;
18645 DBC *d;
18646 char *errp = NULL;
18647 int rc, i, ncols = 0, nrows = 0, busy_count;
18648 SQLRETURN ret;
18649
18650 if (stmt == SQL_NULL_HSTMT) {
18651 return SQL_INVALID_HANDLE;
18652 }
18653 s = (STMT *) stmt;
18654 if (s->dbc == SQL_NULL_HDBC) {
18655noconn:
18656 return noconn(s);
18657 }
18658 d = (DBC *) s->dbc;
18659 if (!d->sqlite) {
18660 goto noconn;
18661 }
18662 if (!s->query) {
18663 setstat(s, -1, "no query prepared", (*s->ov3) ? "HY000" : "S1000");
18664 return SQL_ERROR;
18665 }
18666 if (s->nbindparms < s->nparams) {
18667unbound:
18668 setstat(s, -1, "unbound parameters in query",
18669 (*s->ov3) ? "HY000" : "S1000");
18670 return SQL_ERROR;
18671 }
18672 for (i = 0; i < s->nparams; i++) {
18673 BINDPARM *p = &s->bindparms[i];
18674
18675 if (!p->bound) {
18676 goto unbound;
18677 }
18678 if (initial) {
18679 SQLLEN *lenp = p->lenp;
18680
18681 if (lenp && *lenp < 0 && *lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18682 *lenp != SQL_NTS && *lenp != SQL_NULL_DATA &&
18683 *lenp != SQL_DATA_AT_EXEC) {
18684 setstat(s, -1, "invalid length reference", "HY009");
18685 return SQL_ERROR;
18686 }
18687 if (lenp && (*lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18688 *lenp == SQL_DATA_AT_EXEC)) {
18689 p->need = 1;
18690 p->offs = 0;
18691 p->len = 0;
18692 }
18693 }
18694 }
18695 ret = starttran(s);
18696 if (ret != SQL_SUCCESS) {
18697 goto cleanup;
18698 }
18699 busy_count = 0;
18700again:
18701 s3stmt_end(s);
18702 if (initial) {
18703 /* fixup data-at-execution parameters and alloc'ed blobs */
18704 s->pdcount = -1;
18705 for (i = 0; i < s->nparams; i++) {
18706 BINDPARM *p = &s->bindparms[i];
18707
18708 if (p->param == p->parbuf) {
18709 p->param = NULL;
18710 }
18711 freep(&p->parbuf);
18712 if (p->need <= 0 &&
18713 p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18714 *p->lenp == SQL_DATA_AT_EXEC)) {
18715 p->need = 1;
18716 p->offs = 0;
18717 p->len = 0;
18718 }
18719 }
18720 }
18721 if (s->nparams) {
18722 for (i = 0; i < s->nparams; i++) {
18723 ret = setupparam(s, (char *) s->query, i);
18724 if (ret != SQL_SUCCESS) {
18725 goto cleanup;
18726 }
18727 }
18728 }
18729 freeresult(s, 0);
18730 if (s->isselect == 1 && !d->intrans &&
18731 s->curtype == SQL_CURSOR_FORWARD_ONLY &&
18732 d->step_enable && s->nparams == 0 && d->cur_s3stmt == NULL) {
18733 s->nrows = -1;
18734 ret = s3stmt_start(s);
18735 if (ret == SQL_SUCCESS) {
18736 goto done2;
18737 }
18738 }
18739 rc = drvgettable(s, s->s3stmt ? NULL : (char *) s->query, &s->rows,
18740 &s->nrows, &ncols, &errp, s->nparams, s->bindparms);
18741 dbtracerc(d, rc, errp);
18742 if (rc == SQLITE_BUSY) {
18743 if (busy_handler((void *) d, ++busy_count)) {
18744 if (errp) {
18745 sqlite3_free(errp);
18746 errp = NULL;
18747 }
18748 for (i = 0; i < s->nparams; i++) {
18749 BINDPARM *p = &s->bindparms[i];
18750
18751 if (p->param == p->parbuf) {
18752 p->param = NULL;
18753 }
18754 freep(&p->parbuf);
18755 if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18756 *p->lenp != SQL_DATA_AT_EXEC)) {
18757 p->param = p->param0;
18758 }
18759 p->lenp = p->lenp0;
18760 }
18761 s->nrows = 0;
18762 goto again;
18763 }
18764 }
18765 if (rc != SQLITE_OK) {
18766 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18767 errp ? errp : "unknown error", rc);
18768 if (errp) {
18769 sqlite3_free(errp);
18770 errp = NULL;
18771 }
18772 ret = SQL_ERROR;
18773 goto cleanup;
18774 }
18775 if (errp) {
18776 sqlite3_free(errp);
18777 errp = NULL;
18778 }
18779 s->rowfree = freerows;
18780 if (s->isselect <= 0 || s->isselect > 1) {
18781 /*
18782 * INSERT/UPDATE/DELETE or DDL results are immediately released.
18783 */
18784 freeresult(s, -1);
18785 nrows += sqlite3_changes(d->sqlite);
18786 s->nrows = nrows;
18787 goto done;
18788 }
18789 if (s->ncols != ncols) {
18790 /*
18791 * Weird result.
18792 */
18793 setstat(s, -1, "broken result set %d/%d",
18794 (*s->ov3) ? "HY000" : "S1000", s->ncols, ncols);
18795 ret = SQL_ERROR;
18796 goto cleanup;
18797 }
18798done:
18799 mkbindcols(s, s->ncols);
18800done2:
18801 ret = SQL_SUCCESS;
18802 s->rowp = s->rowprs = -1;
18803 s->paramset_count++;
18804 s->paramset_nrows = s->nrows;
18805 if (s->paramset_count < s->paramset_size) {
18806 for (i = 0; i < s->nparams; i++) {
18807 BINDPARM *p = &s->bindparms[i];
18808
18809 if (p->param == p->parbuf) {
18810 p->param = NULL;
18811 }
18812 freep(&p->parbuf);
18813 if (p->lenp0 &&
18814 s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18815 p->lenp = (SQLLEN *) ((char *) p->lenp0 +
18817 } else if (p->lenp0 && p->inc > 0) {
18818 p->lenp = p->lenp0 + s->paramset_count;
18819 }
18820 if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18821 *p->lenp != SQL_DATA_AT_EXEC)) {
18822 if (p->param0 &&
18823 s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18824 p->param = (char *) p->param0 +
18826 } else if (p->param0 && p->inc > 0) {
18827 p->param = (char *) p->param0 +
18828 s->paramset_count * p->inc;
18829 }
18830 } else if (p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18831 *p->lenp == SQL_DATA_AT_EXEC)) {
18832 p->need = 1;
18833 p->offs = 0;
18834 p->len = 0;
18835 }
18836 }
18837 goto again;
18838 }
18839cleanup:
18840 if (ret != SQL_NEED_DATA) {
18841 for (i = 0; i < s->nparams; i++) {
18842 BINDPARM *p = &s->bindparms[i];
18843
18844 if (p->param == p->parbuf) {
18845 p->param = NULL;
18846 }
18847 freep(&p->parbuf);
18848 if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18849 *p->lenp != SQL_DATA_AT_EXEC)) {
18850 p->param = p->param0;
18851 }
18852 p->lenp = p->lenp0;
18853 }
18854 s->nrows = s->paramset_nrows;
18855 if (s->parm_proc) {
18856 *s->parm_proc = s->paramset_count;
18857 }
18858 s->paramset_count = 0;
18859 s->paramset_nrows = 0;
18860 }
18861 /*
18862 * For INSERT/UPDATE/DELETE statements change the return code
18863 * to SQL_NO_DATA if the number of rows affected was 0.
18864 */
18865 if (*s->ov3 && s->isselect == 0 &&
18866 ret == SQL_SUCCESS && nrows == 0) {
18867 ret = SQL_NO_DATA;
18868 }
18869 return ret;
18870}
18871
18872#ifndef WINTERFACE
18881SQLRETURN SQL_API
18882SQLPrepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18883{
18884 SQLRETURN ret;
18885#if defined(_WIN32) || defined(_WIN64)
18886 char *q;
18887#endif
18888
18890#if defined(_WIN32) || defined(_WIN64)
18891 if (!((STMT *) stmt)->oemcp[0]) {
18892 ret = drvprepare(stmt, query, queryLen);
18893 goto done;
18894 }
18895 q = wmb_to_utf_c((char *) query, queryLen);
18896 if (!q) {
18897 ret = nomem((STMT *) stmt);
18898 goto done;
18899 }
18900 query = (SQLCHAR *) q;
18901 queryLen = SQL_NTS;
18902#endif
18903 ret = drvprepare(stmt, query, queryLen);
18904#if defined(_WIN32) || defined(_WIN64)
18905 uc_free(q);
18906done:
18907 ;
18908#endif
18910 return ret;
18911}
18912#endif
18913
18914#ifdef WINTERFACE
18923SQLRETURN SQL_API
18924SQLPrepareW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
18925{
18926 SQLRETURN ret;
18927 char *q = uc_to_utf_c(query, queryLen);
18928
18930 if (!q) {
18931 ret = nomem((STMT *) stmt);
18932 goto done;
18933 }
18934 ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
18935 uc_free(q);
18936done:
18938 return ret;
18939}
18940#endif
18941
18948SQLRETURN SQL_API
18949SQLExecute(SQLHSTMT stmt)
18950{
18951 SQLRETURN ret;
18952
18954 ret = drvexecute(stmt, 1);
18956 return ret;
18957}
18958
18959#ifndef WINTERFACE
18968SQLRETURN SQL_API
18969SQLExecDirect(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18970{
18971 SQLRETURN ret;
18972#if defined(_WIN32) || defined(_WIN64)
18973 char *q;
18974#endif
18975
18977#if defined(_WIN32) || defined(_WIN64)
18978 if (!((STMT *) stmt)->oemcp[0]) {
18979 ret = drvprepare(stmt, query, queryLen);
18980 if (ret == SQL_SUCCESS) {
18981 ret = drvexecute(stmt, 1);
18982 }
18983 goto done;
18984 }
18985 q = wmb_to_utf_c((char *) query, queryLen);
18986 if (!q) {
18987 ret = nomem((STMT *) stmt);
18988 goto done;
18989 }
18990 query = (SQLCHAR *) q;
18991 queryLen = SQL_NTS;
18992#endif
18993 ret = drvprepare(stmt, query, queryLen);
18994 if (ret == SQL_SUCCESS) {
18995 ret = drvexecute(stmt, 1);
18996 }
18997#if defined(_WIN32) || defined(_WIN64)
18998 uc_free(q);
18999done:
19000 ;
19001#endif
19003 return ret;
19004}
19005#endif
19006
19007#ifdef WINTERFACE
19016SQLRETURN SQL_API
19017SQLExecDirectW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
19018{
19019 SQLRETURN ret;
19020 char *q = uc_to_utf_c(query, queryLen);
19021
19023 if (!q) {
19024 ret = nomem((STMT *) stmt);
19025 goto done;
19026 }
19027 ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
19028 uc_free(q);
19029 if (ret == SQL_SUCCESS) {
19030 ret = drvexecute(stmt, 1);
19031 }
19032done:
19034 return ret;
19035}
19036#endif
19037
19038
19039#if defined(_WIN32) || defined(_WIN64)
19040#ifndef WITHOUT_DRIVERMGR
19041
19042/*
19043 * Windows configuration dialog stuff.
19044 */
19045
19046#include <windowsx.h>
19047#include <winuser.h>
19048
19049#define MAXPATHLEN (259+1) /* Max path length */
19050#define MAXKEYLEN (15+1) /* Max keyword length */
19051#define MAXDESC (255+1) /* Max description length */
19052#define MAXDSNAME (255+1) /* Max data source name length */
19053#define MAXTONAME (32+1) /* Max timeout length */
19054#define MAXDBNAME MAXPATHLEN
19055
19056/* Attribute key indexes into an array of Attr structs, see below */
19057
19058#define KEY_DSN 0
19059#define KEY_DESC 1
19060#define KEY_DBNAME 2
19061#define KEY_BUSY 3
19062#define KEY_DRIVER 4
19063#define KEY_STEPAPI 5
19064#define KEY_SYNCP 6
19065#define KEY_NOTXN 7
19066#define KEY_SHORTNAM 8
19067#define KEY_LONGNAM 9
19068#define KEY_NOCREAT 10
19069#define KEY_NOWCHAR 11
19070#define KEY_LOADEXT 12
19071#define KEY_JMODE 13
19072#define KEY_FKSUPPORT 14
19073#define KEY_OEMCP 15
19074#define KEY_BIGINT 16
19075#define KEY_PASSWD 17
19076#define KEY_JDCONV 18
19077#define NUMOFKEYS 19
19078
19079typedef struct {
19080 BOOL supplied;
19081 char attr[MAXPATHLEN*4];
19082} ATTR;
19083
19084typedef struct {
19085 SQLHWND parent;
19086 LPCSTR driver;
19087 ATTR attr[NUMOFKEYS];
19088 char DSN[MAXDSNAME];
19089 BOOL newDSN;
19090 BOOL defDSN;
19091} SETUPDLG;
19092
19093static struct {
19094 char *key;
19095 int ikey;
19096} attrLookup[] = {
19097 { "DSN", KEY_DSN },
19098 { "DESC", KEY_DESC },
19099 { "Description", KEY_DESC},
19100 { "Database", KEY_DBNAME },
19101 { "Timeout", KEY_BUSY },
19102 { "Driver", KEY_DRIVER },
19103 { "StepAPI", KEY_STEPAPI },
19104 { "SyncPragma", KEY_SYNCP },
19105 { "NoTXN", KEY_NOTXN },
19106 { "ShortNames", KEY_SHORTNAM },
19107 { "LongNames", KEY_LONGNAM },
19108 { "NoCreat", KEY_NOCREAT },
19109 { "NoWCHAR", KEY_NOWCHAR },
19110 { "LoadExt", KEY_LOADEXT },
19111 { "JournalMode", KEY_JMODE },
19112 { "FKSupport", KEY_FKSUPPORT },
19113 { "OEMCP", KEY_OEMCP },
19114 { "BigInt", KEY_BIGINT },
19115 { "PWD", KEY_PASSWD },
19116 { "JDConv", KEY_JDCONV },
19117 { NULL, 0 }
19118};
19119
19126static void
19127ParseAttributes(LPCSTR attribs, SETUPDLG *setupdlg)
19128{
19129 char *str = (char *) attribs, *start, key[MAXKEYLEN];
19130 int elem, nkey;
19131
19132 while (*str) {
19133 start = str;
19134 if ((str = strchr(str, '=')) == NULL) {
19135 return;
19136 }
19137 elem = -1;
19138 nkey = str - start;
19139 if (nkey < sizeof (key)) {
19140 int i;
19141
19142 memcpy(key, start, nkey);
19143 key[nkey] = '\0';
19144 for (i = 0; attrLookup[i].key; i++) {
19145 if (strcasecmp(attrLookup[i].key, key) == 0) {
19146 elem = attrLookup[i].ikey;
19147 break;
19148 }
19149 }
19150 }
19151 start = ++str;
19152 while (*str && *str != ';') {
19153 ++str;
19154 }
19155 if (elem >= 0) {
19156 int end = min(str - start, sizeof (setupdlg->attr[elem].attr) - 1);
19157
19158 setupdlg->attr[elem].supplied = TRUE;
19159 memcpy(setupdlg->attr[elem].attr, start, end);
19160 setupdlg->attr[elem].attr[end] = '\0';
19161 }
19162 ++str;
19163 }
19164}
19165
19173static BOOL
19174SetDSNAttributes(HWND parent, SETUPDLG *setupdlg)
19175{
19176 char *dsn = setupdlg->attr[KEY_DSN].attr;
19177
19178 if (setupdlg->newDSN && strlen(dsn) == 0) {
19179 return FALSE;
19180 }
19181 if (!SQLWriteDSNToIni(dsn, setupdlg->driver)) {
19182 if (parent) {
19183 char buf[MAXPATHLEN], msg[MAXPATHLEN];
19184
19185 LoadString(hModule, IDS_BADDSN, buf, sizeof (buf));
19186 wsprintf(msg, buf, dsn);
19187 LoadString(hModule, IDS_MSGTITLE, buf, sizeof (buf));
19188 MessageBox(parent, msg, buf,
19189 MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
19190 MB_SETFOREGROUND);
19191 }
19192 return FALSE;
19193 }
19194 if (parent || setupdlg->attr[KEY_DESC].supplied) {
19195 SQLWritePrivateProfileString(dsn, "Description",
19196 setupdlg->attr[KEY_DESC].attr,
19197 ODBC_INI);
19198 }
19199 if (parent || setupdlg->attr[KEY_DBNAME].supplied) {
19200 SQLWritePrivateProfileString(dsn, "Database",
19201 setupdlg->attr[KEY_DBNAME].attr,
19202 ODBC_INI);
19203 }
19204 if (parent || setupdlg->attr[KEY_BUSY].supplied) {
19205 SQLWritePrivateProfileString(dsn, "Timeout",
19206 setupdlg->attr[KEY_BUSY].attr,
19207 ODBC_INI);
19208 }
19209 if (parent || setupdlg->attr[KEY_STEPAPI].supplied) {
19210 SQLWritePrivateProfileString(dsn, "StepAPI",
19211 setupdlg->attr[KEY_STEPAPI].attr,
19212 ODBC_INI);
19213 }
19214 if (parent || setupdlg->attr[KEY_SYNCP].supplied) {
19215 SQLWritePrivateProfileString(dsn, "SyncPragma",
19216 setupdlg->attr[KEY_SYNCP].attr,
19217 ODBC_INI);
19218 }
19219 if (parent || setupdlg->attr[KEY_NOTXN].supplied) {
19220 SQLWritePrivateProfileString(dsn, "NoTXN",
19221 setupdlg->attr[KEY_NOTXN].attr,
19222 ODBC_INI);
19223 }
19224 if (parent || setupdlg->attr[KEY_SHORTNAM].supplied) {
19225 SQLWritePrivateProfileString(dsn, "ShortNames",
19226 setupdlg->attr[KEY_SHORTNAM].attr,
19227 ODBC_INI);
19228 }
19229 if (parent || setupdlg->attr[KEY_LONGNAM].supplied) {
19230 SQLWritePrivateProfileString(dsn, "LongNames",
19231 setupdlg->attr[KEY_LONGNAM].attr,
19232 ODBC_INI);
19233 }
19234 if (parent || setupdlg->attr[KEY_NOCREAT].supplied) {
19235 SQLWritePrivateProfileString(dsn, "NoCreat",
19236 setupdlg->attr[KEY_NOCREAT].attr,
19237 ODBC_INI);
19238 }
19239 if (parent || setupdlg->attr[KEY_NOWCHAR].supplied) {
19240 SQLWritePrivateProfileString(dsn, "NoWCHAR",
19241 setupdlg->attr[KEY_NOWCHAR].attr,
19242 ODBC_INI);
19243 }
19244 if (parent || setupdlg->attr[KEY_FKSUPPORT].supplied) {
19245 SQLWritePrivateProfileString(dsn, "FKSupport",
19246 setupdlg->attr[KEY_FKSUPPORT].attr,
19247 ODBC_INI);
19248 }
19249 if (parent || setupdlg->attr[KEY_OEMCP].supplied) {
19250 SQLWritePrivateProfileString(dsn, "OEMCP",
19251 setupdlg->attr[KEY_OEMCP].attr,
19252 ODBC_INI);
19253 }
19254 if (parent || setupdlg->attr[KEY_LOADEXT].supplied) {
19255 SQLWritePrivateProfileString(dsn, "LoadExt",
19256 setupdlg->attr[KEY_LOADEXT].attr,
19257 ODBC_INI);
19258 }
19259 if (parent || setupdlg->attr[KEY_BIGINT].supplied) {
19260 SQLWritePrivateProfileString(dsn, "BigInt",
19261 setupdlg->attr[KEY_BIGINT].attr,
19262 ODBC_INI);
19263 }
19264 if (parent || setupdlg->attr[KEY_JDCONV].supplied) {
19265 SQLWritePrivateProfileString(dsn, "JDConv",
19266 setupdlg->attr[KEY_JDCONV].attr,
19267 ODBC_INI);
19268 }
19269 if (parent || setupdlg->attr[KEY_PASSWD].supplied) {
19270 SQLWritePrivateProfileString(dsn, "PWD",
19271 setupdlg->attr[KEY_PASSWD].attr,
19272 ODBC_INI);
19273 }
19274 if (setupdlg->attr[KEY_DSN].supplied &&
19275 strcasecmp(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr)) {
19276 SQLRemoveDSNFromIni(setupdlg->DSN);
19277 }
19278 return TRUE;
19279}
19280
19286static void
19287GetAttributes(SETUPDLG *setupdlg)
19288{
19289 char *dsn = setupdlg->attr[KEY_DSN].attr;
19290
19291 if (!setupdlg->attr[KEY_DESC].supplied) {
19292 SQLGetPrivateProfileString(dsn, "Description", "",
19293 setupdlg->attr[KEY_DESC].attr,
19294 sizeof (setupdlg->attr[KEY_DESC].attr),
19295 ODBC_INI);
19296 }
19297 if (!setupdlg->attr[KEY_DBNAME].supplied) {
19298 SQLGetPrivateProfileString(dsn, "Database", "",
19299 setupdlg->attr[KEY_DBNAME].attr,
19300 sizeof (setupdlg->attr[KEY_DBNAME].attr),
19301 ODBC_INI);
19302 }
19303 if (!setupdlg->attr[KEY_BUSY].supplied) {
19304 SQLGetPrivateProfileString(dsn, "Timeout", "100000",
19305 setupdlg->attr[KEY_BUSY].attr,
19306 sizeof (setupdlg->attr[KEY_BUSY].attr),
19307 ODBC_INI);
19308 }
19309 if (!setupdlg->attr[KEY_STEPAPI].supplied) {
19310 SQLGetPrivateProfileString(dsn, "StepAPI", "0",
19311 setupdlg->attr[KEY_STEPAPI].attr,
19312 sizeof (setupdlg->attr[KEY_STEPAPI].attr),
19313 ODBC_INI);
19314 }
19315 if (!setupdlg->attr[KEY_SYNCP].supplied) {
19316 SQLGetPrivateProfileString(dsn, "SyncPragma", "NORMAL",
19317 setupdlg->attr[KEY_SYNCP].attr,
19318 sizeof (setupdlg->attr[KEY_SYNCP].attr),
19319 ODBC_INI);
19320 }
19321 if (!setupdlg->attr[KEY_NOTXN].supplied) {
19322 SQLGetPrivateProfileString(dsn, "NoTXN", "",
19323 setupdlg->attr[KEY_NOTXN].attr,
19324 sizeof (setupdlg->attr[KEY_NOTXN].attr),
19325 ODBC_INI);
19326 }
19327 if (!setupdlg->attr[KEY_SHORTNAM].supplied) {
19328 SQLGetPrivateProfileString(dsn, "ShortNames", "",
19329 setupdlg->attr[KEY_SHORTNAM].attr,
19330 sizeof (setupdlg->attr[KEY_SHORTNAM].attr),
19331 ODBC_INI);
19332 }
19333 if (!setupdlg->attr[KEY_LONGNAM].supplied) {
19334 SQLGetPrivateProfileString(dsn, "LongNames", "",
19335 setupdlg->attr[KEY_LONGNAM].attr,
19336 sizeof (setupdlg->attr[KEY_LONGNAM].attr),
19337 ODBC_INI);
19338 }
19339 if (!setupdlg->attr[KEY_NOCREAT].supplied) {
19340 SQLGetPrivateProfileString(dsn, "NoCreat", "",
19341 setupdlg->attr[KEY_NOCREAT].attr,
19342 sizeof (setupdlg->attr[KEY_NOCREAT].attr),
19343 ODBC_INI);
19344 }
19345 if (!setupdlg->attr[KEY_NOWCHAR].supplied) {
19346 SQLGetPrivateProfileString(dsn, "NoWCHAR", "",
19347 setupdlg->attr[KEY_NOWCHAR].attr,
19348 sizeof (setupdlg->attr[KEY_NOWCHAR].attr),
19349 ODBC_INI);
19350 }
19351 if (!setupdlg->attr[KEY_FKSUPPORT].supplied) {
19352 SQLGetPrivateProfileString(dsn, "FKSupport", "",
19353 setupdlg->attr[KEY_FKSUPPORT].attr,
19354 sizeof (setupdlg->attr[KEY_FKSUPPORT].attr),
19355 ODBC_INI);
19356 }
19357 if (!setupdlg->attr[KEY_OEMCP].supplied) {
19358 SQLGetPrivateProfileString(dsn, "OEMCP", "",
19359 setupdlg->attr[KEY_OEMCP].attr,
19360 sizeof (setupdlg->attr[KEY_OEMCP].attr),
19361 ODBC_INI);
19362 }
19363 if (!setupdlg->attr[KEY_LOADEXT].supplied) {
19364 SQLGetPrivateProfileString(dsn, "LoadExt", "",
19365 setupdlg->attr[KEY_LOADEXT].attr,
19366 sizeof (setupdlg->attr[KEY_LOADEXT].attr),
19367 ODBC_INI);
19368 }
19369 if (!setupdlg->attr[KEY_JMODE].supplied) {
19370 SQLGetPrivateProfileString(dsn, "JournalMode", "",
19371 setupdlg->attr[KEY_JMODE].attr,
19372 sizeof (setupdlg->attr[KEY_JMODE].attr),
19373 ODBC_INI);
19374 }
19375 if (!setupdlg->attr[KEY_BIGINT].supplied) {
19376 SQLGetPrivateProfileString(dsn, "BigInt", "",
19377 setupdlg->attr[KEY_BIGINT].attr,
19378 sizeof (setupdlg->attr[KEY_BIGINT].attr),
19379 ODBC_INI);
19380 }
19381 if (!setupdlg->attr[KEY_PASSWD].supplied) {
19382 SQLGetPrivateProfileString(dsn, "PWD", "",
19383 setupdlg->attr[KEY_PASSWD].attr,
19384 sizeof (setupdlg->attr[KEY_PASSWD].attr),
19385 ODBC_INI);
19386 }
19387 if (!setupdlg->attr[KEY_JDCONV].supplied) {
19388 SQLGetPrivateProfileString(dsn, "JDConv", "",
19389 setupdlg->attr[KEY_JDCONV].attr,
19390 sizeof (setupdlg->attr[KEY_JDCONV].attr),
19391 ODBC_INI);
19392 }
19393}
19394
19400static void
19401GetDBFile(HWND hdlg)
19402{
19403#ifdef _WIN64
19404 SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19405#else
19406 SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19407#endif
19408 OPENFILENAME ofn;
19409
19410 memset(&ofn, 0, sizeof (ofn));
19411 ofn.lStructSize = sizeof (ofn);
19412 ofn.hwndOwner = hdlg;
19413#ifdef _WIN64
19414 ofn.hInstance = (HINSTANCE) GetWindowLongPtr(hdlg, GWLP_HINSTANCE);
19415#else
19416 ofn.hInstance = (HINSTANCE) GetWindowLong(hdlg, GWL_HINSTANCE);
19417#endif
19418 ofn.lpstrFile = (LPTSTR) setupdlg->attr[KEY_DBNAME].attr;
19419 ofn.nMaxFile = MAXPATHLEN;
19420 ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST |
19421 OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_FILEMUSTEXIST;
19422 if (GetOpenFileName(&ofn)) {
19423 SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19424 setupdlg->attr[KEY_DBNAME].supplied = TRUE;
19425 }
19426}
19427
19437static BOOL CALLBACK
19438ConfigDlgProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19439{
19440 SETUPDLG *setupdlg = NULL;
19441 WORD index;
19442
19443 switch (wmsg) {
19444 case WM_INITDIALOG:
19445#ifdef _WIN64
19446 SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19447#else
19448 SetWindowLong(hdlg, DWL_USER, lparam);
19449#endif
19450 setupdlg = (SETUPDLG *) lparam;
19451 GetAttributes(setupdlg);
19452 SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19453 SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19454 SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19455 SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19456 SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19457 SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19458 (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19459 SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19460 (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19461 SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19462 (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19463 SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19464 (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19465 SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19466 (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19467 CheckDlgButton(hdlg, IDC_STEPAPI,
19468 getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19469 BST_CHECKED : BST_UNCHECKED);
19470 CheckDlgButton(hdlg, IDC_NOTXN,
19471 getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19472 BST_CHECKED : BST_UNCHECKED);
19473 CheckDlgButton(hdlg, IDC_SHORTNAM,
19474 getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19475 BST_CHECKED : BST_UNCHECKED);
19476 CheckDlgButton(hdlg, IDC_LONGNAM,
19477 getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19478 BST_CHECKED : BST_UNCHECKED);
19479 CheckDlgButton(hdlg, IDC_NOCREAT,
19480 getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19481 BST_CHECKED : BST_UNCHECKED);
19482 CheckDlgButton(hdlg, IDC_NOWCHAR,
19483 getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19484 BST_CHECKED : BST_UNCHECKED);
19485 CheckDlgButton(hdlg, IDC_FKSUPPORT,
19486 getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19487 BST_CHECKED : BST_UNCHECKED);
19488 CheckDlgButton(hdlg, IDC_OEMCP,
19489 getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19490 BST_CHECKED : BST_UNCHECKED);
19491 CheckDlgButton(hdlg, IDC_BIGINT,
19492 getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19493 BST_CHECKED : BST_UNCHECKED);
19494 CheckDlgButton(hdlg, IDC_JDCONV,
19495 getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19496 BST_CHECKED : BST_UNCHECKED);
19497 SendDlgItemMessage(hdlg, IDC_SYNCP,
19498 CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19499 SendDlgItemMessage(hdlg, IDC_SYNCP,
19500 CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19501 SendDlgItemMessage(hdlg, IDC_SYNCP,
19502 CB_ADDSTRING, 0, (LPARAM) "OFF");
19503 SendDlgItemMessage(hdlg, IDC_SYNCP,
19504 CB_ADDSTRING, 0, (LPARAM) "FULL");
19505 SendDlgItemMessage(hdlg, IDC_SYNCP,
19506 CB_SELECTSTRING, (WPARAM) -1,
19507 (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19508 if (setupdlg->defDSN) {
19509 EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19510 EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19511 }
19512 return TRUE;
19513 case WM_COMMAND:
19514 switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19515 case IDC_DSNAME:
19516 if (GET_WM_COMMAND_CMD(wparam, lparam) == EN_CHANGE) {
19517 char item[MAXDSNAME];
19518
19519 EnableWindow(GetDlgItem(hdlg, IDOK),
19520 GetDlgItemText(hdlg, IDC_DSNAME,
19521 item, sizeof (item)));
19522 return TRUE;
19523 }
19524 break;
19525 case IDC_BROWSE:
19526 GetDBFile(hdlg);
19527 break;
19528 case IDOK:
19529#ifdef _WIN64
19530 setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19531#else
19532 setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19533#endif
19534 if (!setupdlg->defDSN) {
19535 GetDlgItemText(hdlg, IDC_DSNAME,
19536 setupdlg->attr[KEY_DSN].attr,
19537 sizeof (setupdlg->attr[KEY_DSN].attr));
19538 }
19539 GetDlgItemText(hdlg, IDC_DESC,
19540 setupdlg->attr[KEY_DESC].attr,
19541 sizeof (setupdlg->attr[KEY_DESC].attr));
19542 GetDlgItemText(hdlg, IDC_DBNAME,
19543 setupdlg->attr[KEY_DBNAME].attr,
19544 sizeof (setupdlg->attr[KEY_DBNAME].attr));
19545 GetDlgItemText(hdlg, IDC_TONAME,
19546 setupdlg->attr[KEY_BUSY].attr,
19547 sizeof (setupdlg->attr[KEY_BUSY].attr));
19548 GetDlgItemText(hdlg, IDC_LOADEXT,
19549 setupdlg->attr[KEY_LOADEXT].attr,
19550 sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19551 index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19552 CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19553 if (index != (WORD) CB_ERR) {
19554 SendDlgItemMessage(hdlg, IDC_SYNCP,
19555 CB_GETLBTEXT, index,
19556 (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19557 }
19558 strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19559 (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19560 "1" : "0");
19561 strcpy(setupdlg->attr[KEY_NOTXN].attr,
19562 (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19563 "1" : "0");
19564 strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19565 (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19566 "1" : "0");
19567 strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19568 (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19569 "1" : "0");
19570 strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19571 (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19572 "1" : "0");
19573 strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19574 (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19575 "1" : "0");
19576 strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19577 (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19578 "1" : "0");
19579 strcpy(setupdlg->attr[KEY_OEMCP].attr,
19580 (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19581 "1" : "0");
19582 strcpy(setupdlg->attr[KEY_BIGINT].attr,
19583 (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19584 "1" : "0");
19585 strcpy(setupdlg->attr[KEY_JDCONV].attr,
19586 (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19587 "1" : "0");
19588 SetDSNAttributes(hdlg, setupdlg);
19589 /* FALL THROUGH */
19590 case IDCANCEL:
19591 EndDialog(hdlg, wparam);
19592 return TRUE;
19593 }
19594 break;
19595 }
19596 return FALSE;
19597}
19598
19608BOOL INSTAPI
19609ConfigDSN(HWND hwnd, WORD request, LPCSTR driver, LPCSTR attribs)
19610{
19611 BOOL success;
19612 SETUPDLG *setupdlg;
19613
19614 setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
19615 if (setupdlg == NULL) {
19616 return FALSE;
19617 }
19618 memset(setupdlg, 0, sizeof (SETUPDLG));
19619 if (attribs) {
19620 ParseAttributes(attribs, setupdlg);
19621 }
19622 if (setupdlg->attr[KEY_DSN].supplied) {
19623 strcpy(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr);
19624 } else {
19625 setupdlg->DSN[0] = '\0';
19626 }
19627 if (request == ODBC_REMOVE_DSN) {
19628 if (!setupdlg->attr[KEY_DSN].supplied) {
19629 success = FALSE;
19630 } else {
19631 success = SQLRemoveDSNFromIni(setupdlg->attr[KEY_DSN].attr);
19632 }
19633 } else {
19634 setupdlg->parent = hwnd;
19635 setupdlg->driver = driver;
19636 setupdlg->newDSN = request == ODBC_ADD_DSN;
19637 setupdlg->defDSN = strcasecmp(setupdlg->attr[KEY_DSN].attr,
19638 "Default") == 0;
19639 if (hwnd) {
19640 success = DialogBoxParam(hModule, MAKEINTRESOURCE(CONFIGDSN),
19641 hwnd, (DLGPROC) ConfigDlgProc,
19642 (LPARAM) setupdlg) == IDOK;
19643 } else if (setupdlg->attr[KEY_DSN].supplied) {
19644 success = SetDSNAttributes(hwnd, setupdlg);
19645 } else {
19646 success = FALSE;
19647 }
19648 }
19649 xfree(setupdlg);
19650 return success;
19651}
19652
19662static BOOL CALLBACK
19663DriverConnectProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19664{
19665 SETUPDLG *setupdlg;
19666 WORD index;
19667
19668 switch (wmsg) {
19669 case WM_INITDIALOG:
19670#ifdef _WIN64
19671 SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19672#else
19673 SetWindowLong(hdlg, DWL_USER, lparam);
19674#endif
19675 setupdlg = (SETUPDLG *) lparam;
19676 SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19677 SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19678 SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19679 SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19680 SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19681 SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19682 (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19683 SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19684 (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19685 SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19686 (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19687 SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19688 (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19689 SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19690 (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19691 CheckDlgButton(hdlg, IDC_STEPAPI,
19692 getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19693 BST_CHECKED : BST_UNCHECKED);
19694 CheckDlgButton(hdlg, IDC_NOTXN,
19695 getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19696 BST_CHECKED : BST_UNCHECKED);
19697 CheckDlgButton(hdlg, IDC_SHORTNAM,
19698 getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19699 BST_CHECKED : BST_UNCHECKED);
19700 CheckDlgButton(hdlg, IDC_LONGNAM,
19701 getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19702 BST_CHECKED : BST_UNCHECKED);
19703 CheckDlgButton(hdlg, IDC_NOCREAT,
19704 getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19705 BST_CHECKED : BST_UNCHECKED);
19706 CheckDlgButton(hdlg, IDC_NOWCHAR,
19707 getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19708 BST_CHECKED : BST_UNCHECKED);
19709 CheckDlgButton(hdlg, IDC_FKSUPPORT,
19710 getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19711 BST_CHECKED : BST_UNCHECKED);
19712 CheckDlgButton(hdlg, IDC_OEMCP,
19713 getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19714 BST_CHECKED : BST_UNCHECKED);
19715 CheckDlgButton(hdlg, IDC_BIGINT,
19716 getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19717 BST_CHECKED : BST_UNCHECKED);
19718 CheckDlgButton(hdlg, IDC_JDCONV,
19719 getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19720 BST_CHECKED : BST_UNCHECKED);
19721 SendDlgItemMessage(hdlg, IDC_SYNCP,
19722 CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19723 SendDlgItemMessage(hdlg, IDC_SYNCP,
19724 CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19725 SendDlgItemMessage(hdlg, IDC_SYNCP,
19726 CB_ADDSTRING, 0, (LPARAM) "OFF");
19727 SendDlgItemMessage(hdlg, IDC_SYNCP,
19728 CB_ADDSTRING, 0, (LPARAM) "FULL");
19729 SendDlgItemMessage(hdlg, IDC_SYNCP,
19730 CB_SELECTSTRING, (WORD) -1,
19731 (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19732 if (setupdlg->defDSN) {
19733 EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19734 EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19735 }
19736 return TRUE;
19737 case WM_COMMAND:
19738 switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19739 case IDC_BROWSE:
19740 GetDBFile(hdlg);
19741 break;
19742 case IDOK:
19743#ifdef _WIN64
19744 setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19745#else
19746 setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19747#endif
19748 GetDlgItemText(hdlg, IDC_DSNAME,
19749 setupdlg->attr[KEY_DSN].attr,
19750 sizeof (setupdlg->attr[KEY_DSN].attr));
19751 GetDlgItemText(hdlg, IDC_DBNAME,
19752 setupdlg->attr[KEY_DBNAME].attr,
19753 sizeof (setupdlg->attr[KEY_DBNAME].attr));
19754 GetDlgItemText(hdlg, IDC_TONAME,
19755 setupdlg->attr[KEY_BUSY].attr,
19756 sizeof (setupdlg->attr[KEY_BUSY].attr));
19757 GetDlgItemText(hdlg, IDC_LOADEXT,
19758 setupdlg->attr[KEY_LOADEXT].attr,
19759 sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19760 index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19761 CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19762 if (index != (WORD) CB_ERR) {
19763 SendDlgItemMessage(hdlg, IDC_SYNCP,
19764 CB_GETLBTEXT, index,
19765 (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19766 }
19767 strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19768 (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19769 "1" : "0");
19770 strcpy(setupdlg->attr[KEY_NOTXN].attr,
19771 (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19772 "1" : "0");
19773 strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19774 (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19775 "1" : "0");
19776 strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19777 (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19778 "1" : "0");
19779 strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19780 (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19781 "1" : "0");
19782 strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19783 (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19784 "1" : "0");
19785 strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19786 (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19787 "1" : "0");
19788 strcpy(setupdlg->attr[KEY_OEMCP].attr,
19789 (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19790 "1" : "0");
19791 strcpy(setupdlg->attr[KEY_BIGINT].attr,
19792 (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19793 "1" : "0");
19794 strcpy(setupdlg->attr[KEY_JDCONV].attr,
19795 (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19796 "1" : "0");
19797 /* FALL THROUGH */
19798 case IDCANCEL:
19799 EndDialog(hdlg, GET_WM_COMMAND_ID(wparam, lparam) == IDOK);
19800 return TRUE;
19801 }
19802 }
19803 return FALSE;
19804}
19805
19819static SQLRETURN
19820drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
19821 SQLCHAR *connIn, SQLSMALLINT connInLen,
19822 SQLCHAR *connOut, SQLSMALLINT connOutMax,
19823 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19824{
19825 BOOL maybeprompt, prompt = FALSE, defaultdsn = FALSE;
19826 DBC *d;
19827 SETUPDLG *setupdlg;
19828 SQLRETURN ret;
19829 char *dsn = NULL, *driver = NULL, *dbname = NULL;
19830
19831 if (dbc == SQL_NULL_HDBC) {
19832 return SQL_INVALID_HANDLE;
19833 }
19834 d = (DBC *) dbc;
19835 if (d->sqlite) {
19836 setstatd(d, -1, "connection already established", "08002");
19837 return SQL_ERROR;
19838 }
19839 setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
19840 if (setupdlg == NULL) {
19841 return SQL_ERROR;
19842 }
19843 memset(setupdlg, 0, sizeof (SETUPDLG));
19844 maybeprompt = drvcompl == SQL_DRIVER_COMPLETE ||
19845 drvcompl == SQL_DRIVER_COMPLETE_REQUIRED;
19846 if (connIn == NULL || !connInLen ||
19847 (connInLen == SQL_NTS && !connIn[0])) {
19848 prompt = TRUE;
19849 } else {
19850 ParseAttributes((LPCSTR) connIn, setupdlg);
19851 if (!setupdlg->attr[KEY_DSN].attr[0] &&
19852 drvcompl == SQL_DRIVER_COMPLETE_REQUIRED) {
19853 strcpy(setupdlg->attr[KEY_DSN].attr, "DEFAULT");
19854 defaultdsn = TRUE;
19855 }
19856 GetAttributes(setupdlg);
19857 if (drvcompl == SQL_DRIVER_PROMPT ||
19858 (maybeprompt &&
19859 !setupdlg->attr[KEY_DBNAME].attr[0])) {
19860 prompt = TRUE;
19861 }
19862 }
19863retry:
19864 if (prompt) {
19865 short dlgret;
19866
19867 setupdlg->defDSN = setupdlg->attr[KEY_DRIVER].attr[0] != '\0';
19868 dlgret = DialogBoxParam(hModule, MAKEINTRESOURCE(DRIVERCONNECT),
19869 hwnd, (DLGPROC) DriverConnectProc,
19870 (LPARAM) setupdlg);
19871
19872 if (!dlgret || dlgret == -1) {
19873 xfree(setupdlg);
19874 return SQL_NO_DATA;
19875 }
19876 }
19877 dsn = setupdlg->attr[KEY_DSN].attr;
19878 driver = setupdlg->attr[KEY_DRIVER].attr;
19879 dbname = setupdlg->attr[KEY_DBNAME].attr;
19880 if (connOut || connOutLen) {
19881 char buf[SQL_MAX_MESSAGE_LENGTH * 8];
19882 int len, count;
19883 char dsn_0 = (dsn && !defaultdsn) ? dsn[0] : '\0';
19884 char drv_0 = driver ? driver[0] : '\0';
19885
19886 buf[0] = '\0';
19887 count = snprintf(buf, sizeof (buf),
19888 "%s%s%s%s%s%sDatabase=%s;StepAPI=%s;"
19889 "SyncPragma=%s;NoTXN=%s;Timeout=%s;"
19890 "ShortNames=%s;LongNames=%s;"
19891 "NoCreat=%s;NoWCHAR=%s;"
19892 "FKSupport=%s;JournalMode=%s;OEMCP=%s;LoadExt=%s;"
19893 "BigInt=%s;JDConv=%s;PWD=%s",
19894 dsn_0 ? "DSN=" : "",
19895 dsn_0 ? dsn : "",
19896 dsn_0 ? ";" : "",
19897 drv_0 ? "Driver=" : "",
19898 drv_0 ? driver : "",
19899 drv_0 ? ";" : "",
19900 dbname ? dbname : "",
19901 setupdlg->attr[KEY_STEPAPI].attr,
19902 setupdlg->attr[KEY_SYNCP].attr,
19903 setupdlg->attr[KEY_NOTXN].attr,
19904 setupdlg->attr[KEY_BUSY].attr,
19905 setupdlg->attr[KEY_SHORTNAM].attr,
19906 setupdlg->attr[KEY_LONGNAM].attr,
19907 setupdlg->attr[KEY_NOCREAT].attr,
19908 setupdlg->attr[KEY_NOWCHAR].attr,
19909 setupdlg->attr[KEY_FKSUPPORT].attr,
19910 setupdlg->attr[KEY_JMODE].attr,
19911 setupdlg->attr[KEY_OEMCP].attr,
19912 setupdlg->attr[KEY_LOADEXT].attr,
19913 setupdlg->attr[KEY_BIGINT].attr,
19914 setupdlg->attr[KEY_JDCONV].attr,
19915 setupdlg->attr[KEY_PASSWD].attr);
19916 if (count < 0) {
19917 buf[sizeof (buf) - 1] = '\0';
19918 }
19919 len = min(connOutMax - 1, strlen(buf));
19920 if (connOut) {
19921 strncpy((char *) connOut, buf, len);
19922 connOut[len] = '\0';
19923 }
19924 if (connOutLen) {
19925 *connOutLen = len;
19926 }
19927 }
19928 if (dsn[0]) {
19929 char tracef[SQL_MAX_MESSAGE_LENGTH];
19930
19931 tracef[0] = '\0';
19932 SQLGetPrivateProfileString(setupdlg->attr[KEY_DSN].attr,
19933 "tracefile", "", tracef,
19934 sizeof (tracef), ODBC_INI);
19935 if (tracef[0] != '\0') {
19936 d->trace = fopen(tracef, "a");
19937 }
19938 }
19939 d->nowchar = getbool(setupdlg->attr[KEY_NOWCHAR].attr);
19940 d->shortnames = getbool(setupdlg->attr[KEY_SHORTNAM].attr);
19941 d->longnames = getbool(setupdlg->attr[KEY_LONGNAM].attr);
19942 d->nocreat = getbool(setupdlg->attr[KEY_NOCREAT].attr);
19943 d->fksupport = getbool(setupdlg->attr[KEY_FKSUPPORT].attr);
19944 d->oemcp = getbool(setupdlg->attr[KEY_OEMCP].attr);
19945 d->dobigint = getbool(setupdlg->attr[KEY_BIGINT].attr);
19946 d->jdconv = getbool(setupdlg->attr[KEY_JDCONV].attr);
19947 d->pwdLen = strlen(setupdlg->attr[KEY_PASSWD].attr);
19948 d->pwd = (d->pwdLen > 0) ? setupdlg->attr[KEY_PASSWD].attr : NULL;
19949 ret = dbopen(d, dbname ? dbname : "", 0,
19950 dsn ? dsn : "",
19951 setupdlg->attr[KEY_STEPAPI].attr,
19952 setupdlg->attr[KEY_SYNCP].attr,
19953 setupdlg->attr[KEY_NOTXN].attr,
19954 setupdlg->attr[KEY_JMODE].attr,
19955 setupdlg->attr[KEY_BUSY].attr);
19956 if (ret != SQL_SUCCESS) {
19957 if (maybeprompt && !prompt) {
19958 prompt = TRUE;
19959 goto retry;
19960 }
19961 }
19962 memset(setupdlg->attr[KEY_PASSWD].attr, 0,
19963 sizeof (setupdlg->attr[KEY_PASSWD].attr));
19964 if (ret == SQL_SUCCESS) {
19965 dbloadext(d, setupdlg->attr[KEY_LOADEXT].attr);
19966 }
19967 xfree(setupdlg);
19968 return ret;
19969}
19970
19971#endif /* WITHOUT_DRIVERMGR */
19972#endif /* _WIN32 || _WIN64 */
19973
19974#ifndef WINTERFACE
19988SQLRETURN SQL_API
19989SQLDriverConnect(SQLHDBC dbc, SQLHWND hwnd,
19990 SQLCHAR *connIn, SQLSMALLINT connInLen,
19991 SQLCHAR *connOut, SQLSMALLINT connOutMax,
19992 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19993{
19994 SQLRETURN ret;
19995
19996 HDBC_LOCK(dbc);
19997 ret = drvdriverconnect(dbc, hwnd, connIn, connInLen,
19998 connOut, connOutMax, connOutLen, drvcompl);
20000 return ret;
20001}
20002#endif
20003
20004#ifdef WINTERFACE
20018SQLRETURN SQL_API
20019SQLDriverConnectW(SQLHDBC dbc, SQLHWND hwnd,
20020 SQLWCHAR *connIn, SQLSMALLINT connInLen,
20021 SQLWCHAR *connOut, SQLSMALLINT connOutMax,
20022 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
20023{
20024 SQLRETURN ret;
20025 char *ci = NULL;
20026 SQLSMALLINT len = 0;
20027
20028 HDBC_LOCK(dbc);
20029 if (connIn) {
20030#if defined(_WIN32) || defined(_WIN64)
20031 if (connInLen == SQL_NTS) {
20032 connInLen = -1;
20033 }
20034 ci = uc_to_wmb(connIn, connInLen);
20035#else
20036 ci = uc_to_utf(connIn, connInLen);
20037#endif
20038 if (!ci) {
20039 DBC *d = (DBC *) dbc;
20040
20041 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
20043 return SQL_ERROR;
20044 }
20045 }
20046 ret = drvdriverconnect(dbc, hwnd, (SQLCHAR *) ci, SQL_NTS,
20047 (SQLCHAR *) connOut, connOutMax, &len, drvcompl);
20049 uc_free(ci);
20050 if (ret == SQL_SUCCESS) {
20051 SQLWCHAR *co = NULL;
20052
20053 if (connOut) {
20054 if (len > 0) {
20055#if defined(_WIN32) || defined(_WIN64)
20056 co = wmb_to_uc((char *) connOut, len);
20057#else
20058 co = uc_from_utf((SQLCHAR *) connOut, len);
20059#endif
20060 if (co) {
20061 uc_strncpy(connOut, co, connOutMax / sizeof (SQLWCHAR));
20062 len = min(connOutMax / sizeof (SQLWCHAR), uc_strlen(co));
20063 uc_free(co);
20064 } else {
20065 len = 0;
20066 }
20067 }
20068 if (len <= 0) {
20069 len = 0;
20070 connOut[0] = 0;
20071 }
20072 } else {
20073 len = 0;
20074 }
20075 if (connOutLen) {
20076 *connOutLen = len;
20077 }
20078 }
20079 return ret;
20080}
20081#endif
20082
20083#if defined(_WIN32) || defined(_WIN64)
20084
20093BOOL APIENTRY
20094LibMain(HANDLE hinst, DWORD reason, LPVOID reserved)
20095{
20096 static int initialized = 0;
20097
20098 switch (reason) {
20099 case DLL_PROCESS_ATTACH:
20100 if (!initialized++) {
20101 hModule = hinst;
20102#ifdef WINTERFACE
20103 /* MS Access hack part 1 (reserved error -7748) */
20104 statSpec2P = statSpec2;
20105 statSpec3P = statSpec3;
20106#endif
20107#ifdef SQLITE_DYNLOAD
20108 dls_init();
20109#endif
20110#ifdef SQLITE_HAS_CODEC
20111 sqlite3_activate_see(SQLITE_ACTIVATION_KEY);
20112#endif
20113 }
20114#if defined(ENABLE_NVFS) && (ENABLE_NVFS)
20115 nvfs_init();
20116#endif
20117 break;
20118 case DLL_THREAD_ATTACH:
20119 break;
20120 case DLL_PROCESS_DETACH:
20121 if (--initialized <= 0) {
20122#ifdef SQLITE_DYNLOAD
20123 dls_fini();
20124#endif
20125 }
20126 break;
20127 case DLL_THREAD_DETACH:
20128 break;
20129 default:
20130 break;
20131 }
20132 return TRUE;
20133}
20134
20143int __stdcall
20144DllMain(HANDLE hinst, DWORD reason, LPVOID reserved)
20145{
20146 return LibMain(hinst, reason, reserved);
20147}
20148
20149#ifndef WITHOUT_INSTALLER
20150
20157static BOOL
20158InUnError(char *name)
20159{
20160 WORD err = 1;
20161 DWORD code;
20162 char errmsg[301];
20163 WORD errlen, errmax = sizeof (errmsg) - 1;
20164 int sqlret;
20165 BOOL ret = FALSE;
20166
20167 do {
20168 errmsg[0] = '\0';
20169 sqlret = SQLInstallerError(err, &code, errmsg, errmax, &errlen);
20170 if (SQL_SUCCEEDED(sqlret)) {
20171 MessageBox(NULL, errmsg, name,
20172 MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
20173 ret = TRUE;
20174 }
20175 err++;
20176 } while (sqlret != SQL_NO_DATA);
20177 return ret;
20178}
20179
20186static BOOL
20187InUn(int remove, char *cmdline)
20188{
20189#ifdef SQLITE_HAS_CODEC
20190 static char *drivername = "SQLite3 ODBC Driver (SEE)";
20191 static char *dsname = "SQLite3 SEE Datasource";
20192#else
20193 static char *drivername = "SQLite3 ODBC Driver";
20194 static char *dsname = "SQLite3 Datasource";
20195#endif
20196 char *dllname, *p;
20197 char dllbuf[301], path[301], driver[300], attr[300], inst[400];
20198 WORD pathmax = sizeof (path) - 1, pathlen;
20199 DWORD usecnt, mincnt;
20200 int quiet = 0;
20201
20202 dllbuf[0] = '\0';
20203 GetModuleFileName(hModule, dllbuf, sizeof (dllbuf));
20204 p = strrchr(dllbuf, '\\');
20205 dllname = p ? (p + 1) : dllbuf;
20206 quiet = cmdline && strstr(cmdline, "quiet");
20207 if (SQLInstallDriverManager(path, pathmax, &pathlen)) {
20208 sprintf(driver, "%s;Driver=%s;Setup=%s;",
20209 drivername, dllname, dllname);
20210 p = driver;
20211 while (*p) {
20212 if (*p == ';') {
20213 *p = '\0';
20214 }
20215 ++p;
20216 }
20217 usecnt = 0;
20218 path[0] = '\0';
20219 SQLInstallDriverEx(driver, NULL, path, pathmax, NULL,
20220 ODBC_INSTALL_INQUIRY, &usecnt);
20221 pathlen = strlen(path);
20222 while (pathlen > 0 && path[pathlen - 1] == '\\') {
20223 --pathlen;
20224 path[pathlen] = '\0';
20225 }
20226 sprintf(driver, "%s;Driver=%s\\%s;Setup=%s\\%s;",
20227 drivername, path, dllname, path, dllname);
20228 p = driver;
20229 while (*p) {
20230 if (*p == ';') {
20231 *p = '\0';
20232 }
20233 ++p;
20234 }
20235 sprintf(inst, "%s\\%s", path, dllname);
20236 if (!remove && usecnt > 0) {
20237 /* first install try: copy over driver dll, keeping DSNs */
20238 if (GetFileAttributesA(dllbuf) != INVALID_FILE_ATTRIBUTES &&
20239 CopyFile(dllbuf, inst, 0)) {
20240 if (!quiet) {
20241 char buf[512];
20242
20243 sprintf(buf, "%s replaced.", drivername);
20244 MessageBox(NULL, buf, "Info",
20245 MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20246 MB_SETFOREGROUND);
20247 }
20248 return TRUE;
20249 }
20250 }
20251 mincnt = remove ? 1 : 0;
20252 while (usecnt != mincnt) {
20253 if (!SQLRemoveDriver(driver, TRUE, &usecnt)) {
20254 break;
20255 }
20256 }
20257 if (remove) {
20258 if (usecnt && !SQLRemoveDriver(driver, TRUE, &usecnt)) {
20259 InUnError("SQLRemoveDriver");
20260 return FALSE;
20261 }
20262 if (!usecnt) {
20263 char buf[512];
20264
20265 DeleteFile(inst);
20266 if (!quiet) {
20267 sprintf(buf, "%s uninstalled.", drivername);
20268 MessageBox(NULL, buf, "Info",
20269 MB_ICONINFORMATION |MB_OK | MB_TASKMODAL |
20270 MB_SETFOREGROUND);
20271 }
20272 }
20273 sprintf(attr, "DSN=%s;Database=;", dsname);
20274 p = attr;
20275 while (*p) {
20276 if (*p == ';') {
20277 *p = '\0';
20278 }
20279 ++p;
20280 }
20281 SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20282 return TRUE;
20283 }
20284 if (GetFileAttributesA(dllbuf) == INVALID_FILE_ATTRIBUTES) {
20285 return FALSE;
20286 }
20287 if (strcasecmp(dllbuf, inst) != 0 && !CopyFile(dllbuf, inst, 0)) {
20288 char buf[512];
20289
20290 sprintf(buf, "Copy %s to %s failed.", dllbuf, inst);
20291 MessageBox(NULL, buf, "CopyFile",
20292 MB_ICONSTOP |MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
20293 return FALSE;
20294 }
20295 if (!SQLInstallDriverEx(driver, path, path, pathmax, &pathlen,
20296 ODBC_INSTALL_COMPLETE, &usecnt)) {
20297 InUnError("SQLInstallDriverEx");
20298 return FALSE;
20299 }
20300 sprintf(attr, "DSN=%s;Database=;", dsname);
20301 p = attr;
20302 while (*p) {
20303 if (*p == ';') {
20304 *p = '\0';
20305 }
20306 ++p;
20307 }
20308 SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20309 if (!SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN, drivername, attr)) {
20310 InUnError("SQLConfigDataSource");
20311 return FALSE;
20312 }
20313 if (!quiet) {
20314 char buf[512];
20315
20316 sprintf(buf, "%s installed.", drivername);
20317 MessageBox(NULL, buf, "Info",
20318 MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20319 MB_SETFOREGROUND);
20320 }
20321 } else {
20322 InUnError("SQLInstallDriverManager");
20323 return FALSE;
20324 }
20325 return TRUE;
20326}
20327
20336void CALLBACK
20337install(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20338{
20339 InUn(0, lpszCmdLine);
20340}
20341
20350void CALLBACK
20351uninstall(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20352{
20353 InUn(1, lpszCmdLine);
20354}
20355
20356#endif /* WITHOUT_INSTALLER */
20357
20358#ifndef WITHOUT_SHELL
20359
20368static void
20369setargv(int *argcp, char ***argvp, char *cmdline, char *argv0)
20370{
20371 char *p, *arg, *argspace, **argv;
20372 int argc, size, inquote, copy, slashes;
20373
20374 size = 2 + (argv0 ? 1 : 0);
20375 for (p = cmdline; *p != '\0'; p++) {
20376 if (ISSPACE(*p)) {
20377 size++;
20378 while (ISSPACE(*p)) {
20379 p++;
20380 }
20381 if (*p == '\0') {
20382 break;
20383 }
20384 }
20385 }
20386 argspace = malloc(size * sizeof (char *) + strlen(cmdline) + 1);
20387 argv = (char **) argspace;
20388 argspace += size * sizeof (char *);
20389 size--;
20390 argc = 0;
20391 if (argv0) {
20392 argv[argc++] = argv0;
20393 }
20394 p = cmdline;
20395 for (; argc < size; argc++) {
20396 argv[argc] = arg = argspace;
20397 while (ISSPACE(*p)) {
20398 p++;
20399 }
20400 if (*p == '\0') {
20401 break;
20402 }
20403 inquote = 0;
20404 slashes = 0;
20405 while (1) {
20406 copy = 1;
20407 while (*p == '\\') {
20408 slashes++;
20409 p++;
20410 }
20411 if (*p == '"') {
20412 if ((slashes & 1) == 0) {
20413 copy = 0;
20414 if (inquote && p[1] == '"') {
20415 p++;
20416 copy = 1;
20417 } else {
20418 inquote = !inquote;
20419 }
20420 }
20421 slashes >>= 1;
20422 }
20423 while (slashes) {
20424 *arg = '\\';
20425 arg++;
20426 slashes--;
20427 }
20428 if (*p == '\0' || (!inquote && ISSPACE(*p))) {
20429 break;
20430 }
20431 if (copy != 0) {
20432 *arg = *p;
20433 arg++;
20434 }
20435 p++;
20436 }
20437 *arg = '\0';
20438 argspace = arg + 1;
20439 }
20440 argv[argc] = 0;
20441 *argcp = argc;
20442 *argvp = argv;
20443}
20444
20453void CALLBACK
20454shell(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20455{
20456 int argc, needcon = 0;
20457 char **argv;
20458 extern int sqlite3_main(int, char **);
20459 static const char *name = "SQLite3 Shell";
20460 DWORD ftype0, ftype1, ftype2;
20461
20462 ftype0 = GetFileType(GetStdHandle(STD_INPUT_HANDLE));
20463 ftype1 = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
20464 ftype2 = GetFileType(GetStdHandle(STD_ERROR_HANDLE));
20465 if (ftype0 != FILE_TYPE_DISK && ftype0 != FILE_TYPE_CHAR &&
20466 ftype0 != FILE_TYPE_PIPE) {
20467 fclose(stdin);
20468 ++needcon;
20469 ftype0 = FILE_TYPE_UNKNOWN;
20470 }
20471 if (ftype1 != FILE_TYPE_DISK && ftype1 != FILE_TYPE_CHAR &&
20472 ftype1 != FILE_TYPE_PIPE) {
20473 fclose(stdout);
20474 ++needcon;
20475 ftype1 = FILE_TYPE_UNKNOWN;
20476 }
20477 if (ftype2 != FILE_TYPE_DISK && ftype2 != FILE_TYPE_CHAR &&
20478 ftype2 != FILE_TYPE_PIPE) {
20479 fclose(stderr);
20480 ++needcon;
20481 ftype2 = FILE_TYPE_UNKNOWN;
20482 }
20483 if (needcon > 0) {
20484 AllocConsole();
20485 SetConsoleTitle(name);
20486 }
20487 if (ftype0 == FILE_TYPE_UNKNOWN) {
20488 freopen("CONIN$", "r", stdin);
20489 }
20490 if (ftype1 == FILE_TYPE_UNKNOWN) {
20491 freopen("CONOUT$", "w", stdout);
20492 }
20493 if (ftype2 == FILE_TYPE_UNKNOWN) {
20494 freopen("CONOUT$", "w", stderr);
20495 }
20496 setargv(&argc, &argv, lpszCmdLine, (char *) name);
20497#if defined(ENABLE_NVFS) && (ENABLE_NVFS)
20498 nvfs_init();
20499#endif
20500 sqlite3_main(argc, argv);
20501}
20502
20503#endif /* WITHOUT_SHELL */
20504
20505#endif /* _WIN32 || _WIN64 */
20506
20507#if defined(HAVE_ODBCINSTEXT_H) && (HAVE_ODBCINSTEXT_H)
20508
20509/*
20510 * unixODBC property page for this driver,
20511 * may or may not work depending on unixODBC version.
20512 */
20513
20514#include <odbcinstext.h>
20515
20516int
20517ODBCINSTGetProperties(HODBCINSTPROPERTY prop)
20518{
20519 static const char *instYN[] = { "No", "Yes", NULL };
20520 static const char *syncPragma[] = { "NORMAL", "OFF", "FULL", NULL };
20521 static const char *jmPragma[] = {
20522 "DELETE", "PERSIST", "OFF", "TRUNCATE", "MEMORY", "WAL", NULL
20523 };
20524
20525 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20526 prop = prop->pNext;
20527 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20528 prop->nPromptType = ODBCINST_PROMPTTYPE_FILENAME;
20529 strncpy(prop->szName, "Database", INI_MAX_PROPERTY_NAME);
20530 strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20531 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20532 prop = prop->pNext;
20533 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20534 prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20535 strncpy(prop->szName, "Timeout", INI_MAX_PROPERTY_NAME);
20536 strncpy(prop->szValue, "100000", INI_MAX_PROPERTY_VALUE);
20537 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20538 prop = prop->pNext;
20539 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20540 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20541 prop->aPromptData = malloc(sizeof (instYN));
20542 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20543 strncpy(prop->szName, "StepAPI", INI_MAX_PROPERTY_NAME);
20544 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20545 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20546 prop = prop->pNext;
20547 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20548 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20549 prop->aPromptData = malloc(sizeof (instYN));
20550 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20551 strncpy(prop->szName, "ShortNames", INI_MAX_PROPERTY_NAME);
20552 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20553 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20554 prop = prop->pNext;
20555 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20556 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20557 prop->aPromptData = malloc(sizeof (instYN));
20558 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20559 strncpy(prop->szName, "LongNames", INI_MAX_PROPERTY_NAME);
20560 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20561 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20562 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20563 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20564 prop->aPromptData = malloc(sizeof (instYN));
20565 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20566 strncpy(prop->szName, "NoCreat", INI_MAX_PROPERTY_NAME);
20567 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20568#ifdef WINTERFACE
20569 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20570 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20571 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20572 prop->aPromptData = malloc(sizeof (instYN));
20573 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20574 strncpy(prop->szName, "NoWCHAR", INI_MAX_PROPERTY_NAME);
20575 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20576#endif
20577 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20578 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20579 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20580 prop->aPromptData = malloc(sizeof (instYN));
20581 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20582 strncpy(prop->szName, "FKSupport", INI_MAX_PROPERTY_NAME);
20583 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20584 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20585 prop = prop->pNext;
20586 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20587 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20588 prop->aPromptData = malloc(sizeof (syncPragma));
20589 memcpy(prop->aPromptData, syncPragma, sizeof (syncPragma));
20590 strncpy(prop->szName, "SyncPragma", INI_MAX_PROPERTY_NAME);
20591 strncpy(prop->szValue, "NORMAL", INI_MAX_PROPERTY_VALUE);
20592 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20593 prop = prop->pNext;
20594 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20595 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20596 prop->aPromptData = malloc(sizeof (jmPragma));
20597 memcpy(prop->aPromptData, jmPragma, sizeof (jmPragma));
20598 strncpy(prop->szName, "JournalMode", INI_MAX_PROPERTY_NAME);
20599 strncpy(prop->szValue, "DELETE", INI_MAX_PROPERTY_VALUE);
20600 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20601 prop = prop->pNext;
20602 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20603 prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20604 strncpy(prop->szName, "LoadExt", INI_MAX_PROPERTY_NAME);
20605 strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20606 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20607 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20608 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20609 prop->aPromptData = malloc(sizeof (instYN));
20610 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20611 strncpy(prop->szName, "BigInt", INI_MAX_PROPERTY_NAME);
20612 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20613 return 1;
20614}
20615
20616#endif /* HAVE_ODBCINSTEXT_H */
20617
20618#ifdef SQLITE_DYNLOAD
20619
20620/*
20621 * SQLite3 shared library/DLL stubs.
20622 */
20623
20624static void
20625dls_void(void)
20626{
20627}
20628
20629static int
20630dls_error(void)
20631{
20632 return SQLITE_ERROR;
20633}
20634
20635static int
20636dls_0(void)
20637{
20638 return 0;
20639}
20640
20641static sqlite_int64
20642dls_0LL(void)
20643{
20644 return 0;
20645}
20646
20647static double
20648dls_00(void)
20649{
20650 return 0;
20651}
20652
20653static void *
20654dls_null(void)
20655{
20656 return NULL;
20657}
20658
20659static const char *
20660dls_empty(void)
20661{
20662 return "";
20663}
20664
20665static int
20666dls_snull(void)
20667{
20668 return SQLITE_NULL;
20669}
20670
20671#define DLS_ENT(name, func) \
20672 { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, name), \
20673 (void *) func }
20674
20675#define DLS_ENT3(name, off, func) \
20676 { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, off), \
20677 (void *) func }
20678
20679#define DLS_END { NULL, 0, NULL }
20680
20681static struct {
20682 const char *name;
20683 int offset;
20684 void *func;
20685} dls_nametab[] = {
20686 DLS_ENT(activate_see, dls_void),
20687 DLS_ENT(bind_blob, dls_error),
20688 DLS_ENT(bind_double, dls_error),
20689 DLS_ENT(bind_int, dls_error),
20690 DLS_ENT(bind_int64, dls_error),
20691 DLS_ENT(bind_null, dls_error),
20692 DLS_ENT(bind_parameter_count, dls_0),
20693 DLS_ENT(bind_text, dls_error),
20694 DLS_ENT(busy_handler, dls_error),
20695 DLS_ENT(changes, dls_0),
20696 DLS_ENT(close, dls_error),
20697 DLS_ENT(column_blob, dls_null),
20698 DLS_ENT(column_bytes, dls_0),
20699 DLS_ENT(column_count, dls_0),
20700 DLS_ENT(column_database_name, dls_empty),
20701 DLS_ENT(column_decltype, dls_empty),
20702 DLS_ENT(column_double, dls_00),
20703 DLS_ENT(column_name, dls_empty),
20704 DLS_ENT(column_origin_name, dls_null),
20705 DLS_ENT(column_table_name, dls_null),
20706 DLS_ENT(column_text, dls_null),
20707 DLS_ENT(column_type, dls_snull),
20708 DLS_ENT(create_function, dls_error),
20709 DLS_ENT(enable_load_extension, dls_error),
20710 DLS_ENT(errcode, dls_error),
20711 DLS_ENT(errmsg, dls_empty),
20712 DLS_ENT(exec, dls_error),
20713 DLS_ENT(finalize, dls_error),
20714 DLS_ENT(free, free),
20715 DLS_ENT(free_table, dls_void),
20716 DLS_ENT(get_table, dls_error),
20717 DLS_ENT(interrupt, dls_void),
20718 DLS_ENT(key, dls_error),
20719 DLS_ENT(last_insert_rowid, dls_0LL),
20720 DLS_ENT(libversion, dls_empty),
20721 DLS_ENT(load_extension, dls_error),
20722 DLS_ENT(malloc, malloc),
20723 DLS_ENT(mprintf, dls_null),
20724 DLS_ENT(open, dls_error),
20725 DLS_ENT(open16, dls_error),
20726 DLS_ENT(open_v2, dls_error),
20727 DLS_ENT(prepare, dls_error),
20728 DLS_ENT(prepare_v2, dls_error),
20729 DLS_ENT(profile, dls_null),
20730 DLS_ENT(realloc, realloc),
20731 DLS_ENT(rekey, dls_error),
20732 DLS_ENT(reset, dls_error),
20733 DLS_ENT(result_blob, dls_void),
20734 DLS_ENT(result_error, dls_void),
20735 DLS_ENT(result_int, dls_void),
20736 DLS_ENT(result_null, dls_void),
20737 DLS_ENT(step, dls_error),
20738#if defined(_WIN32) || defined(_WIN64)
20739 DLS_ENT3(strnicmp, xstrnicmp, _strnicmp),
20740#else
20741 DLS_ENT3(strnicmp, xstrnicmp, strncasecmp),
20742#endif
20743 DLS_ENT(table_column_metadata, dls_error),
20744 DLS_ENT(trace, dls_null),
20745 DLS_ENT(user_data, dls_null),
20746 DLS_ENT(value_blob, dls_null),
20747 DLS_ENT(value_bytes, dls_0),
20748 DLS_ENT(value_text, dls_empty),
20749 DLS_ENT(value_type, dls_snull),
20750 DLS_END
20751};
20752
20753#if defined(_WIN32) || defined(_WIN64)
20754
20755static HMODULE sqlite3_dll = 0;
20756
20757static void
20758dls_init(void)
20759{
20760 int i;
20761 static const char *dll_names[] = {
20762 "System.Data.SQLite.dll",
20763 "sqlite3.dll",
20764 NULL,
20765 };
20766
20767 i = 0;
20768 while (dll_names[i]) {
20769 sqlite3_dll = LoadLibrary(dll_names[i]);
20770 if (sqlite3_dll) {
20771 break;
20772 }
20773 ++i;
20774 }
20775 i = 0;
20776 while (dls_nametab[i].name) {
20777 void *func = 0, **loc;
20778
20779 if (sqlite3_dll) {
20780 func = (void *) GetProcAddress(sqlite3_dll, dls_nametab[i].name);
20781 }
20782 if (!func) {
20783 func = dls_nametab[i].func;
20784 }
20785 loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
20786 *loc = func;
20787 ++i;
20788 }
20789 if (!sqlite3_dll) {
20790 char buf[MAXPATHLEN], msg[MAXPATHLEN];
20791
20792 LoadString(hModule, IDS_DRVTITLE, buf, sizeof (buf));
20793 LoadString(hModule, IDS_DLLERR, msg, sizeof (msg));
20794 MessageBox(NULL, msg, buf,
20795 MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
20796 MB_SETFOREGROUND);
20797 }
20798}
20799
20800static void
20801dls_fini(void)
20802{
20803 if (sqlite3_dll) {
20804 FreeLibrary(sqlite3_dll);
20805 sqlite3_dll = 0;
20806 }
20807}
20808
20809#else
20810
20811#include <dlfcn.h>
20812
20813static void *libsqlite3_so = 0;
20814
20815void
20816dls_init(void)
20817{
20818 int i;
20819
20820 libsqlite3_so = dlopen("libsqlite3.so.0", RTLD_NOW | RTLD_GLOBAL);
20821 i = 0;
20822 while (dls_nametab[i].name) {
20823 void *func = 0, **loc;
20824
20825 if (libsqlite3_so) {
20826 func = dlsym(libsqlite3_so, dls_nametab[i].name);
20827 }
20828 if (!func) {
20829 func = dls_nametab[i].func;
20830 }
20831 loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
20832 *loc = func;
20833 ++i;
20834 }
20835 if (!libsqlite3_so) {
20836 const char errmsg[] = "SQLite3 shared library not found.\n";
20837
20838 write(2, errmsg, sizeof (errmsg) - 1);
20839 }
20840}
20841
20842void
20843dls_fini(void)
20844{
20845 if (libsqlite3_so) {
20846 dlclose(libsqlite3_so);
20847 libsqlite3_so = 0;
20848 }
20849}
20850
20851#endif
20852
20853#endif
20854
20855/*
20856 * Local Variables:
20857 * mode: c
20858 * c-basic-offset: 4
20859 * fill-column: 78
20860 * tab-width: 8
20861 * End:
20862 */
static int quiet
Definition: inst.c:60
static BOOL InUn(int remove, char *drivername, char *dllname, char *dll2name, char *dsname)
Driver installer/uninstaller.
Definition: inst.c:153
#define SCOL_VARCHAR
Definition: sqlite3odbc.c:255
static int getmdays(int year, int month)
Return number of month days.
Definition: sqlite3odbc.c:3062
static COL procColSpec3[]
Definition: sqlite3odbc.c:8418
static SQLRETURN drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Internal get option of HSTMT.
Definition: sqlite3odbc.c:9135
SQLRETURN SQL_API SQLCloseCursor(SQLHSTMT stmt)
Close open cursor.
SQLRETURN SQL_API SQLFreeConnect(SQLHDBC dbc)
Free connection (HDBC).
static SQLRETURN drvfreeenv(SQLHENV env)
Internal free HENV.
SQLRETURN SQL_API SQLSetPos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
Set position on result in HSTMT.
SQLRETURN SQL_API SQLSpecialColumnsW(SQLHSTMT stmt, SQLUSMALLINT id, SQLWCHAR *cat, SQLSMALLINT catLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen, SQLUSMALLINT scope, SQLUSMALLINT nullable)
Retrieve information about indexed columns (UNICODE version).
Definition: sqlite3odbc.c:7343
static SQLRETURN drvprimarykeys(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen)
Internal retrieve information about indexed columns.
Definition: sqlite3odbc.c:6577
static SQLRETURN nomem(STMT *s)
Report S1000 (out of memory) SQL error given STMT.
Definition: sqlite3odbc.c:1812
SQLRETURN SQL_API SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER buflen)
Set option on HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9517
static SQLRETURN setupparbuf(STMT *s, BINDPARM *p)
Setup parameter buffer for deferred parameter.
Definition: sqlite3odbc.c:5616
SQLRETURN SQL_API SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len, SQLINTEGER *lenp)
Get information of HENV.
Definition: sqlite3odbc.c:8516
SQLRETURN SQL_API SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SETSTMTOPTION_LAST_ARG_TYPE param)
Set option on HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9729
#define xfree(x)
Definition: sqlite3odbc.c:405
static SQLRETURN setposbind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
Internal handler to setup parameters for positional updates from bound user buffers.
Definition: sqlite3odbc.c:9779
#define SETSTMTOPTION_LAST_ARG_TYPE
Definition: sqlite3odbc.c:221
static SQLWCHAR * uc_strncpy(SQLWCHAR *dest, SQLWCHAR *src, int len)
Copy UNICODE string like strncpy().
Definition: sqlite3odbc.c:822
static void dbtrace(void *arg, const char *msg, sqlite_uint64 et)
SQLite trace or profile callback.
Definition: sqlite3odbc.c:3815
#define HSTMT_LOCK(hdbc)
Definition: sqlite3odbc.c:532
SQLRETURN SQL_API SQLSetDescRec(SQLHDESC handle, SQLSMALLINT recno, SQLSMALLINT type, SQLSMALLINT subtype, SQLLEN len, SQLSMALLINT prec, SQLSMALLINT scale, SQLPOINTER data, SQLLEN *strlen, SQLLEN *indicator)
Function not implemented.
Definition: sqlite3odbc.c:5893
static SQLRETURN drvendtran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
Internal commit or rollback transaction.
Definition: sqlite3odbc.c:8131
static void freeresult(STMT *s, int clrcols)
Free statement's result.
#define ENV_MAGIC
Definition: sqlite3odbc.c:262
SQLRETURN SQL_API SQLConnectW(SQLHDBC dbc, SQLWCHAR *dsn, SQLSMALLINT dsnLen, SQLWCHAR *uid, SQLSMALLINT uidLen, SQLWCHAR *pwd, SQLSMALLINT pwdLen)
Connect to SQLite database.
static void getmd(const char *typename, int sqltype, int *mp, int *dp)
Get maximum display size and number of digits after decimal point from field type specification.
Definition: sqlite3odbc.c:2300
static SQLRETURN drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd, SQLCHAR *connIn, SQLSMALLINT connInLen, SQLCHAR *connOut, SQLSMALLINT connOutMax, SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
Internal standalone (w/o driver manager) database connect.
static char * s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
Find out column type.
Definition: sqlite3odbc.c:4192
#define DRIVER_VER_INFO
Definition: sqlite3odbc.c:209
static const char digit_chars[]
Definition: sqlite3odbc.c:566
SQLRETURN SQL_API SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
Get option of HSTMT.
Definition: sqlite3odbc.c:9590
SQLRETURN SQL_API SQLGetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Get connect attribute of HDBC (UNICODE version).
SQLRETURN SQL_API SQLAllocConnect(SQLHENV env, SQLHDBC *dbc)
Allocate HDBC.
static SQLRETURN drvspecialcolumns(SQLHSTMT stmt, SQLUSMALLINT id, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen, SQLUSMALLINT scope, SQLUSMALLINT nullable)
Internal retrieve information about indexed columns.
Definition: sqlite3odbc.c:6990
static SQLRETURN drvgetinfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen)
Internal return information about what this ODBC driver supports.
static COL fkeySpec3[]
Definition: sqlite3odbc.c:7407
static SQLRETURN mkbindcols(STMT *s, int ncols)
Reallocate space for bound columns.
#define xstrdup(x)
Definition: sqlite3odbc.c:406
static void freedyncols(STMT *s)
Free dynamically allocated column descriptions of STMT.
static SQLRETURN setupparam(STMT *s, char *sql, int pnum)
Setup SQLite3 parameter for statement parameter.
Definition: sqlite3odbc.c:5056
static COL colSpec3[]
SQLRETURN SQL_API SQLGetDescFieldW(SQLHDESC handle, SQLSMALLINT recno, SQLSMALLINT fieldid, SQLPOINTER value, SQLINTEGER buflen, SQLINTEGER *strlen)
Function not implemented.
Definition: sqlite3odbc.c:5818
static void convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
Convert julian day to hour/minute/second.
Definition: sqlite3odbc.c:3033
SQLRETURN SQL_API SQLProceduresW(SQLHSTMT stmt, SQLWCHAR *catalog, SQLSMALLINT catalogLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *proc, SQLSMALLINT procLen)
Retrieve information about stored procedures (UNICODE version).
Definition: sqlite3odbc.c:8377
static void mktypeinfo(STMT *s, int row, int asize, char *typename, int type, int tind)
Internal function to build up data type information as row in result set.
SQLRETURN SQL_API SQLDescribeParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT *dtype, SQLULEN *size, SQLSMALLINT *decdigits, SQLSMALLINT *nullable)
Return information about parameter.
Definition: sqlite3odbc.c:5704
static SQLRETURN drvgetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
Internal get connect option of HDBC.
static int namematch(char *str, char *pat, int esc)
SQL LIKE string match with optional backslash escape handling.
Definition: sqlite3odbc.c:1945
#define drvgetgpps(d)
Definition: sqlite3odbc.c:1291
static SQLRETURN mkresultset(HSTMT stmt, COL *colspec, int ncols, COL *colspec3, int ncols3, int *nret)
Setup empty result set from constant column specification.
Definition: sqlite3odbc.c:5914
static COL statSpec3[]
SQLRETURN SQL_API SQLTablesW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen, SQLWCHAR *type, SQLSMALLINT typeLen)
Retrieve information on tables and/or views.
SQLRETURN SQL_API SQLTransact(SQLHENV env, SQLHDBC dbc, SQLUSMALLINT type)
Commit or rollback transaction.
Definition: sqlite3odbc.c:8202
SQLRETURN SQL_API SQLNumParams(SQLHSTMT stmt, SQLSMALLINT *nparam)
Return number of parameters.
Definition: sqlite3odbc.c:5590
static const char * xdigits
Definition: sqlite3odbc.c:279
static COL scolSpec2[]
Columns for result set of SQLSpecialColumns().
Definition: sqlite3odbc.c:6950
SQLRETURN SQL_API SQLGetTypeInfoW(SQLHSTMT stmt, SQLSMALLINT sqltype)
Return data type information (UNICODE version).
static int drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp, int *ncolp, char **errp, int nparam, BINDPARM *p)
Definition: sqlite3odbc.c:1509
static int TOLOWER(int c)
Definition: sqlite3odbc.c:550
SQLRETURN SQL_API SQLGetDiagFieldW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno, SQLSMALLINT id, SQLPOINTER info, SQLSMALLINT buflen, SQLSMALLINT *stringlen)
Get error record given handle (HDBC or HSTMT).
Definition: sqlite3odbc.c:9059
SQLRETURN SQL_API SQLSetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
Set connect attribute of HDBC (UNICODE version).
static void s3bind(DBC *d, sqlite3_stmt *stmt, int nparams, BINDPARM *p)
Definition: sqlite3odbc.c:1300
static SQLRETURN drvunimpldbc(HDBC dbc)
Report IM001 (not implemented) SQL error code for HDBC.
Definition: sqlite3odbc.c:1760
#define SET_EXISTS(x)
static COL procColSpec2[]
Columns for result set of SQLProcedureColumns().
Definition: sqlite3odbc.c:8396
static SQLRETURN drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
Internal set option on HSTMT.
Definition: sqlite3odbc.c:9630
static SQLRETURN drvgetdiagfield(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno, SQLSMALLINT id, SQLPOINTER info, SQLSMALLINT buflen, SQLSMALLINT *stringlen)
Get error record given handle (HDBC or HSTMT).
Definition: sqlite3odbc.c:8860
static SQLRETURN drvfreeconnect(SQLHDBC dbc)
Internal free connection (HDBC).
static SQLRETURN drvallocconnect(SQLHENV env, SQLHDBC *dbc)
Internal allocate HDBC.
static void fixupdyncols(STMT *s, DBC *d)
Fixup column information for a running statement.
Definition: sqlite3odbc.c:2785
static SQLRETURN getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype, SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp, int partial)
Internal function to retrieve row data, used by SQLFetch() and friends and SQLGetData().
SQLRETURN SQL_API SQLAllocStmt(SQLHDBC dbc, SQLHSTMT *stmt)
Allocate HSTMT given HDBC.
static COL scolSpec3[]
Definition: sqlite3odbc.c:6962
static void uc_free(void *str)
Free converted UTF8 or UNICODE string.
Definition: sqlite3odbc.c:1046
static SQLWCHAR * uc_from_utf(unsigned char *str, int len)
Make UNICODE string from UTF8 string.
Definition: sqlite3odbc.c:932
SQLRETURN SQL_API SQLGetFunctions(SQLHDBC dbc, SQLUSMALLINT func, SQLUSMALLINT *flags)
Return information about supported ODBC API functions.
SQLRETURN SQL_API SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen, SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
Translate SQL string (UNICODE version).
Definition: sqlite3odbc.c:8277
static SQLRETURN drvtables(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen, SQLCHAR *type, SQLSMALLINT typeLen)
Retrieve information on tables and/or views.
#define COLATTRIBUTE_LAST_ARG_TYPE
Definition: sqlite3odbc.c:216
SQLRETURN SQL_API SQLSetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SETSTMTOPTION_LAST_ARG_TYPE param)
Set option on HSTMT.
Definition: sqlite3odbc.c:9708
static int str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
Convert string to ODBC TIMESTAMP_STRUCT.
Definition: sqlite3odbc.c:3332
SQLRETURN SQL_API SQLFreeHandle(SQLSMALLINT type, SQLHANDLE h)
Free a HENV, HDBC, or HSTMT handle.
static int setsqliteopts(sqlite3 *x, DBC *d)
Set SQLite options (PRAGMAs) given SQLite handle.
Definition: sqlite3odbc.c:2093
#define DEAD_MAGIC
Definition: sqlite3odbc.c:264
SQLRETURN SQL_API SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *ncols)
Return number of columns of result set given HSTMT.
SQLRETURN SQL_API SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Get option of HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9308
static SQLRETURN drvgetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen, SQLSMALLINT *lenp)
Internal function to get cursor name of STMT.
static SQLRETURN drvgetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
Internal get option of HSTMT.
Definition: sqlite3odbc.c:9538
static SQLRETURN drvstatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen, SQLUSMALLINT itype, SQLUSMALLINT resv)
Internal return statistic information on table indices.
SQLRETURN SQL_API SQLGetData(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type, SQLPOINTER val, SQLLEN len, SQLLEN *lenp)
Retrieve row data after fetch.
static SQLRETURN s3stmt_start(STMT *s)
Start sqlite statement for execution of SELECT statement.
Definition: sqlite3odbc.c:4624
static char * strdup_(const char *str)
Duplicate string using xmalloc().
Definition: sqlite3odbc.c:616
static SQLRETURN setposibind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
Internal handler to setup parameters for positional updates from driver side result set.
static void uc_from_utf_buf(unsigned char *str, int len, SQLWCHAR *uc, int ucLen)
Make UNICODE string from UTF8 string into buffer.
Definition: sqlite3odbc.c:848
static COL colSpec2[]
Columns for result set of SQLColumns().
#define WCHARSUPPORT
Definition: sqlite3odbc.c:185
static SQLRETURN noconn(STMT *s)
Report S1000 (not connected) SQL error given STMT.
Definition: sqlite3odbc.c:1825
static int drvgettable_row(TBLRES *t, int ncol, int rc)
Definition: sqlite3odbc.c:1392
SQLRETURN SQL_API SQLTablePrivilegesW(SQLHSTMT stmt, SQLWCHAR *catalog, SQLSMALLINT catalogLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen)
Retrieve privileges on tables and/or views (UNICODE version).
Definition: sqlite3odbc.c:6409
static SQLRETURN drvsetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
Internal set option on HDBC.
static SQLRETURN freeparams(STMT *s)
Clear out parameter bindings, if any.
Definition: sqlite3odbc.c:5031
SQLRETURN SQL_API SQLSetScrollOptions(SQLHSTMT stmt, SQLUSMALLINT concur, SQLLEN rowkeyset, SQLUSMALLINT rowset)
Function not implemented.
static SQLRETURN endtran(DBC *d, SQLSMALLINT comptype, int force)
Internal commit or rollback transaction.
Definition: sqlite3odbc.c:8072
static SQLRETURN drvallocenv(SQLHENV *env)
Internal allocate HENV.
SQLRETURN SQL_API SQLAllocHandle(SQLSMALLINT type, SQLHANDLE input, SQLHANDLE *output)
Allocate a HENV, HDBC, or HSTMT handle.
struct tblres TBLRES
static COL statSpec2[]
Columns for result set of SQLStatistics().
#define PTRDIFF_T
Definition: sqlite3odbc.c:230
static int unescpat(char *str)
Unescape search pattern for e.g.
Definition: sqlite3odbc.c:1907
static SQLRETURN drvconnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen, char *pwd, int pwdLen, int isu)
Internal connect to SQLite database.
SQLRETURN SQL_API SQLCopyDesc(SQLHDESC source, SQLHDESC target)
Function not implemented.
Definition: sqlite3odbc.c:8215
SQLRETURN SQL_API SQLSetParam(SQLHSTMT stmt, SQLUSMALLINT par, SQLSMALLINT type, SQLSMALLINT sqltype, SQLULEN coldef, SQLSMALLINT scale, SQLPOINTER val, SQLLEN *nval)
Set information on parameter.
Definition: sqlite3odbc.c:5769
static SQLRETURN drvgetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Internal get connect attribute of HDBC.
static COL colPrivSpec3[]
Definition: sqlite3odbc.c:6466
SQLRETURN SQL_API SQLDriversW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *drvdesc, SQLSMALLINT descmax, SQLSMALLINT *desclenp, SQLWCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
Function not implemented.
Definition: sqlite3odbc.c:4738
SQLRETURN SQL_API SQLDescribeColW(SQLHSTMT stmt, SQLUSMALLINT col, SQLWCHAR *name, SQLSMALLINT nameMax, SQLSMALLINT *nameLen, SQLSMALLINT *type, SQLULEN *size, SQLSMALLINT *digits, SQLSMALLINT *nullable)
Describe column information (UNICODE version).
static SQLRETURN drvbindcol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type, SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
Internal bind C variable to column of result set.
static SQLRETURN drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER buflen)
Internal set option on HSTMT.
Definition: sqlite3odbc.c:9330
SQLRETURN SQL_API SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT opt)
Free HSTMT.
static const char upper_chars[]
Definition: sqlite3odbc.c:546
static SQLRETURN drvgettypeinfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
Internal return data type information.
SQLRETURN SQL_API SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLLEN offset)
Fetch result row with scrolling.
SQLRETURN SQL_API SQLParamData(SQLHSTMT stmt, SQLPOINTER *pind)
Retrieve next parameter for sending data to executing query.
Definition: sqlite3odbc.c:5650
SQLRETURN SQL_API SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
Put (partial) parameter data into executing statement.
Definition: sqlite3odbc.c:5015
static const char lower_chars[]
Definition: sqlite3odbc.c:547
SQLRETURN SQL_API SQLGetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
Get option of HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9610
static int getdsnattr(char *dsn, char *attr, char *out, int outLen)
Handling of SQLConnect() connection attributes for standalone operation without driver manager.
static COL tableSpec2[]
Columns for result set of SQLTables().
#define array_size(x)
Definition: sqlite3odbc.c:233
SQLRETURN SQL_API SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT orient, SQLROWOFFSET offset, SQLROWSETSIZE *rowcount, SQLUSMALLINT *rowstatus)
Fetch result row with scrolling and row status.
static void dbtraceapi(DBC *d, char *fn, const char *sql)
Trace function for SQLite API calls.
Definition: sqlite3odbc.c:3853
SQLRETURN SQL_API SQLBrowseConnectW(SQLHDBC dbc, SQLWCHAR *connin, SQLSMALLINT conninLen, SQLWCHAR *connout, SQLSMALLINT connoutMax, SQLSMALLINT *connoutLen)
Function not implemented.
Definition: sqlite3odbc.c:4774
SQLRETURN SQL_API SQLForeignKeysW(SQLHSTMT stmt, SQLWCHAR *PKcatalog, SQLSMALLINT PKcatalogLen, SQLWCHAR *PKschema, SQLSMALLINT PKschemaLen, SQLWCHAR *PKtable, SQLSMALLINT PKtableLen, SQLWCHAR *FKcatalog, SQLSMALLINT FKcatalogLen, SQLWCHAR *FKschema, SQLSMALLINT FKschemaLen, SQLWCHAR *FKtable, SQLSMALLINT FKtableLen)
Retrieve information about primary/foreign keys (UNICODE version).
Definition: sqlite3odbc.c:7951
static int s3stmt_step(STMT *s)
Do one sqlite statement step gathering one result row.
Definition: sqlite3odbc.c:4285
static int dserr(dstr *dsp)
Check error on dynamic string.
Definition: sqlite3odbc.c:773
static SQLRETURN drvfreestmt(SQLHSTMT stmt, SQLUSMALLINT opt)
Internal function to perform certain kinds of free/close on STMT.
static SQLRETURN drvdescribecol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name, SQLSMALLINT nameMax, SQLSMALLINT *nameLen, SQLSMALLINT *type, SQLULEN *size, SQLSMALLINT *digits, SQLSMALLINT *nullable)
Internal describe column information.
static double ln_strtod(const char *data, char **endp)
Internal locale neutral strtod function.
Definition: sqlite3odbc.c:1841
static void s3stmt_drop(STMT *s)
Drop running sqlite statement in STMT.
Definition: sqlite3odbc.c:4603
static char * uc_to_utf_c(SQLWCHAR *str, int len)
Make UTF8 string from UNICODE string.
Definition: sqlite3odbc.c:1028
SQLRETURN SQL_API SQLGetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT buflen, SQLSMALLINT *lenp)
Get cursor name of STMT (UNICODE version).
static const char * dsval(dstr *dsp)
Return dynamic string's value.
Definition: sqlite3odbc.c:758
SQLRETURN SQL_API SQLEndTran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
Commit or rollback transaction.
Definition: sqlite3odbc.c:8188
static char * unquote(char *str)
Strip quotes from quoted string in-place.
Definition: sqlite3odbc.c:1880
#define strmak(dst, src, max, lenp)
static int uc_strlen(SQLWCHAR *str)
Return length of UNICODE string.
Definition: sqlite3odbc.c:800
SQLRETURN SQL_API SQLSetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT len)
Set cursor name on STMT (UNICODE version).
static COL pkeySpec3[]
Definition: sqlite3odbc.c:6555
SQLRETURN SQL_API SQLGetDiagRecW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno, SQLWCHAR *sqlstate, SQLINTEGER *nativeerr, SQLWCHAR *msg, SQLSMALLINT buflen, SQLSMALLINT *msglen)
Get error message given handle (HENV, HDBC, or HSTMT) (UNICODE version).
Definition: sqlite3odbc.c:8782
static void dsfree(dstr *dsp)
Free dynamic string.
Definition: sqlite3odbc.c:784
SQLRETURN SQL_API SQLBindParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT vtype, SQLSMALLINT ptype, SQLULEN lenprec, SQLSMALLINT scale, SQLPOINTER val, SQLLEN *lenp)
Bind parameter on HSTMT.
Definition: sqlite3odbc.c:5567
static void setstat(STMT *s, int naterr, char *msg, char *st,...)
Set error message and SQL state on statement.
Definition: sqlite3odbc.c:1727
#define HDBC_LOCK(hdbc)
Definition: sqlite3odbc.c:530
static SQLRETURN drvallocstmt(SQLHDBC dbc, SQLHSTMT *stmt)
Allocate HSTMT given HDBC (driver internal version).
static SQLRETURN drvsetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
Internal set connect attribute of HDBC.
static int mapsqltype(const char *typename, int *nosign, int ov3, int nowchar, int dobigint)
Map SQL field type from string to ODBC integer type code.
Definition: sqlite3odbc.c:2176
#define DBC_MAGIC
Definition: sqlite3odbc.c:263
static SQLRETURN drvputdata(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
Internal put (partial) parameter data into executing statement.
Definition: sqlite3odbc.c:4796
SQLRETURN SQL_API SQLGetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
Get connect option of HDBC (UNICODE version).
static SQLRETURN dofetchbind(STMT *s, int rsi)
Internal: fetch and bind from statement's current row.
static SQLRETURN drvsetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
Internal function to set cursor name on STMT.
SQLRETURN SQL_API SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
Function not implemented.
Definition: sqlite3odbc.c:5788
SQLRETURN SQL_API SQLColumnPrivilegesW(SQLHSTMT stmt, SQLWCHAR *catalog, SQLSMALLINT catalogLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen, SQLWCHAR *column, SQLSMALLINT columnLen)
Retrieve privileges on columns (UNICODE version).
Definition: sqlite3odbc.c:6525
static SQLRETURN setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp)
SQLRETURN SQL_API SQLFetch(SQLHSTMT stmt)
Fetch next result row.
SQLRETURN SQL_API SQLCancel(SQLHSTMT stmt)
Cancel HSTMT closing cursor.
static COL pkeySpec2[]
Columns for result set of SQLPrimaryKeys().
Definition: sqlite3odbc.c:6546
static COL typeSpec3[]
static SQLRETURN drvbindparam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype, SQLSMALLINT buftype, SQLSMALLINT ptype, SQLUINTEGER coldef, SQLSMALLINT scale, SQLPOINTER data, SQLINTEGER buflen, SQLLEN *len)
Internal bind parameter on HSTMT.
Definition: sqlite3odbc.c:5399
static void dbloadext(DBC *d, char *exts)
Load SQLite extension modules, if any.
Definition: sqlite3odbc.c:4111
static void blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function to import a BLOB from a file.
Definition: sqlite3odbc.c:3680
SQLRETURN SQL_API SQLBulkOperations(SQLHSTMT stmt, SQLSMALLINT oper)
Perform bulk operation on HSTMT.
static int str2time(int jdconv, char *str, TIME_STRUCT *ts)
Convert string to ODBC TIME_STRUCT.
Definition: sqlite3odbc.c:3211
static int getbool(char *string)
Get boolean flag from string.
Definition: sqlite3odbc.c:3664
static dstr * dsappendq(dstr *dsp, const char *str)
Append a string double quoted to dynamic string.
Definition: sqlite3odbc.c:690
SQLRETURN SQL_API SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
Set information in HENV.
Definition: sqlite3odbc.c:8585
#define xrealloc(x, y)
Definition: sqlite3odbc.c:404
static int typeinfosort(const void *a, const void *b)
Helper function to sort type information.
#define ISDIGIT(c)
Definition: sqlite3odbc.c:568
static SQLRETURN chkunbound(STMT *s)
Check for unbound result columns.
Definition: sqlite3odbc.c:9748
static int mapdeftype(int type, int stype, int nosign, int nowchar)
Map SQL_C_DEFAULT to proper C type.
Definition: sqlite3odbc.c:2385
static COL tableSpec3[]
static void freep(void *x)
Free memory given pointer to memory pointer.
Definition: sqlite3odbc.c:1797
static void blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function to export a BLOB to a file.
Definition: sqlite3odbc.c:3750
SQLRETURN SQL_API SQLFreeEnv(SQLHENV env)
Free HENV.
static int busy_handler(void *udata, int count)
Busy callback for SQLite.
Definition: sqlite3odbc.c:2018
SQLRETURN SQL_API SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno, SQLSMALLINT fieldid, SQLPOINTER value, SQLINTEGER buflen)
Function not implemented.
Definition: sqlite3odbc.c:5846
#define xmalloc(x)
Definition: sqlite3odbc.c:403
#define drvrelgpps(d)
Definition: sqlite3odbc.c:1292
#define HDBC_UNLOCK(hdbc)
Definition: sqlite3odbc.c:531
static SQLRETURN starttran(STMT *s)
Start transaction when autocommit off.
Definition: sqlite3odbc.c:8029
#define verinfo(maj, min, lev)
Definition: sqlite3odbc.c:238
static SQLRETURN setposrefr(STMT *s, int rsi)
Internal handler to refresh user buffers from driver side result set.
SQLRETURN SQL_API SQLGetDescRecW(SQLHDESC handle, SQLSMALLINT recno, SQLWCHAR *name, SQLSMALLINT buflen, SQLSMALLINT *strlen, SQLSMALLINT *type, SQLSMALLINT *subtype, SQLLEN *len, SQLSMALLINT *prec, SQLSMALLINT *scale, SQLSMALLINT *nullable)
Function not implemented.
Definition: sqlite3odbc.c:5877
#define min(a, b)
Definition: sqlite3odbc.c:225
SQLRETURN SQL_API SQLAllocEnv(SQLHENV *env)
Allocate HENV.
static void freerows(char **rowp)
Free counted array of char pointers.
Definition: sqlite3odbc.c:2150
static COL tablePrivSpec3[]
Definition: sqlite3odbc.c:5966
static SQLRETURN drvexecute(SQLHSTMT stmt, int initial)
static SQLRETURN SQL_API drvforeignkeys(SQLHSTMT stmt, SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen, SQLCHAR *PKschema, SQLSMALLINT PKschemaLen, SQLCHAR *PKtable, SQLSMALLINT PKtableLen, SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen, SQLCHAR *FKschema, SQLSMALLINT FKschemaLen, SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
Internal retrieve information about primary/foreign keys.
Definition: sqlite3odbc.c:7443
static void s3stmt_end_if(STMT *s)
Conditionally stop running sqlite statement.
Definition: sqlite3odbc.c:4585
static SQLRETURN drvcolattributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id, SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen, SQLLEN *val2)
Internal retrieve column attributes.
SQLRETURN SQL_API SQLGetInfoW(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen)
Return information about what this ODBC driver supports.
SQLRETURN SQL_API SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type, SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
Bind C variable to column of result set.
static SQLRETURN drvbulkoperations(SQLHSTMT stmt, SQLSMALLINT op)
Internal perform bulk operation on HSTMT.
static SQLRETURN drvgetdiagrec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno, SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg, SQLSMALLINT buflen, SQLSMALLINT *msglen)
Internal get error message given handle (HENV, HDBC, or HSTMT).
Definition: sqlite3odbc.c:8651
#define stringify(s)
Definition: sqlite3odbc.c:236
static void s3stmt_end(STMT *s)
Stop running sqlite statement.
Definition: sqlite3odbc.c:4557
static SQLRETURN drvtableprivileges(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen)
Retrieve privileges on tables and/or views.
Definition: sqlite3odbc.c:5989
static COL tablePrivSpec2[]
Columns for result set of SQLTablePrivileges().
Definition: sqlite3odbc.c:5956
static COL typeSpec2[]
Columns for result set of SQLGetTypeInfo().
static SQLRETURN dbopen(DBC *d, char *name, int isu, char *dsn, char *sflag, char *spflag, char *ntflag, char *jmode, char *busy)
Open SQLite database file given file name and flags.
Definition: sqlite3odbc.c:3897
#define ODBC_INI
Definition: sqlite3odbc.c:205
SQLRETURN SQL_API SQLBindParameter(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype, SQLSMALLINT buftype, SQLSMALLINT ptype, SQLULEN coldef, SQLSMALLINT scale, SQLPOINTER data, SQLLEN buflen, SQLLEN *len)
Bind parameter on HSTMT.
Definition: sqlite3odbc.c:5538
static void dbtracerc(DBC *d, int rc, char *err)
Trace function for SQLite return codes.
Definition: sqlite3odbc.c:3873
static void convJD2YMD(double jd, DATE_STRUCT *ds)
Convert julian day to year/month/day.
Definition: sqlite3odbc.c:3005
static SQLRETURN drvsetpos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
Internal set position on result in HSTMT.
static dstr * dsappend(dstr *dsp, const char *str)
Append string to dynamic string.
Definition: sqlite3odbc.c:638
SQLRETURN SQL_API SQLDisconnect(SQLHDBC dbc)
Disconnect given HDBC.
SQLRETURN SQL_API SQLSetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
Set option on HDBC (UNICODE version).
SQLRETURN SQL_API SQLPrimaryKeysW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen)
Retrieve information about indexed columns (UNICODE version).
Definition: sqlite3odbc.c:6905
static char * fixupsql(char *sql, int sqlLen, int cte, int *nparam, int *isselect, char **errmsg)
Fixup query string with optional parameter markers.
Definition: sqlite3odbc.c:2524
static void unbindcols(STMT *s)
Reset bound columns to unbound state.
static SQLRETURN drvdisconnect(SQLHDBC dbc)
Internal disconnect given HDBC.
static int checkddl(char *sql)
Check if query is a DDL statement.
Definition: sqlite3odbc.c:2471
static SQLRETURN drvfetchscroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLINTEGER offset)
Internal fetch function for SQLFetchScroll() and SQLExtendedFetch().
static SQLRETURN drvunimplstmt(HSTMT stmt)
Report IM001 (not implemented) SQL error code for HSTMT.
Definition: sqlite3odbc.c:1779
static void setstatd(DBC *d, int naterr, char *msg, char *st,...)
Set error message and SQL state on DBC.
Definition: sqlite3odbc.c:1687
static COL colPrivSpec2[]
Columns for result set of SQLColumnPrivileges().
Definition: sqlite3odbc.c:6456
SQLRETURN SQL_API SQLProcedureColumnsW(SQLHSTMT stmt, SQLWCHAR *catalog, SQLSMALLINT catalogLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *proc, SQLSMALLINT procLen, SQLWCHAR *column, SQLSMALLINT columnLen)
Retrieve information about columns in result set of stored procedures (UNICODE version).
Definition: sqlite3odbc.c:8489
#define ISSPACE(c)
Definition: sqlite3odbc.c:577
static SQLRETURN drvcolumns(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen, SQLCHAR *col, SQLSMALLINT colLen)
Internal retrieve column information on table.
static COL procSpec2[]
Columns for result set of SQLProcedures().
Definition: sqlite3odbc.c:8312
SQLRETURN SQL_API SQLColumnsW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen, SQLWCHAR *col, SQLSMALLINT colLen)
Retrieve column information on table (UNICODE version).
#define HSTMT_UNLOCK(hdbc)
Definition: sqlite3odbc.c:533
SQLRETURN SQL_API SQLDataSourcesW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *srvname, SQLSMALLINT buflen1, SQLSMALLINT *lenp1, SQLWCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
Function not implemented.
Definition: sqlite3odbc.c:4704
static char * uc_to_utf(SQLWCHAR *str, int len)
Make UTF8 string from UNICODE string.
Definition: sqlite3odbc.c:958
static const char space_chars[]
Definition: sqlite3odbc.c:575
#define SCOL_CHAR
Definition: sqlite3odbc.c:256
SQLRETURN SQL_API SQLStatisticsW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen, SQLUSMALLINT itype, SQLUSMALLINT resv)
Return statistic information on table indices (UNICODE version).
static COL fkeySpec2[]
Columns for result set of SQLForeignKeys().
Definition: sqlite3odbc.c:7390
SQLRETURN SQL_API SQLRowCount(SQLHSTMT stmt, SQLLEN *nrows)
Return number of affected rows of HSTMT.
static SQLRETURN freestmt(HSTMT stmt)
static int findcol(char **cols, int ncols, char *name)
Find column given name in string array.
Definition: sqlite3odbc.c:2754
static int str2date(int jdconv, char *str, DATE_STRUCT *ds)
Convert string to ODBC DATE_STRUCT.
Definition: sqlite3odbc.c:3096
static COL procSpec3[]
Definition: sqlite3odbc.c:8323
#define max(a, b)
Definition: sqlite3odbc.c:227
Header file for SQLite3 ODBC driver.
#define SQLULEN
Definition: sqlite3odbc.h:68
#define SQLROWOFFSET
Definition: sqlite3odbc.h:80
#define SQLLEN
Definition: sqlite3odbc.h:62
#define SQLROWSETSIZE
Definition: sqlite3odbc.h:84
#define SQL_API
Definition: sqlite3odbc.h:58
#define SQLSETPOSIROW
Definition: sqlite3odbc.h:76
Internal structure for bound column (SQLBindCol).
Definition: sqlite3odbc.h:188
SQLINTEGER max
Max.
Definition: sqlite3odbc.h:190
SQLLEN * lenp
Value return, actual size of value buffer.
Definition: sqlite3odbc.h:191
SQLPOINTER valp
Value buffer.
Definition: sqlite3odbc.h:192
int offs
Byte offset for SQLGetData()
Definition: sqlite3odbc.h:194
SQLSMALLINT type
ODBC type.
Definition: sqlite3odbc.h:189
int index
Index of column in result.
Definition: sqlite3odbc.h:193
Internal structure for bound parameter (SQLBindParameter).
Definition: sqlite3odbc.h:203
double s3dval
SQLite3 float value.
Definition: sqlite3odbc.h:222
void * param0
Parameter buffer, initial value.
Definition: sqlite3odbc.h:210
int need
True when SQL_LEN_DATA_AT_EXEC.
Definition: sqlite3odbc.h:212
int s3type
SQLite3 type.
Definition: sqlite3odbc.h:217
int scale
from SQLBindParameter()
Definition: sqlite3odbc.h:205
int len
Offset/length for SQLParamData()/SQLPutData()
Definition: sqlite3odbc.h:214
void * param
Parameter buffer.
Definition: sqlite3odbc.h:209
void * parbuf
Buffer for SQL_LEN_DATA_AT_EXEC etc.
Definition: sqlite3odbc.h:215
int inc
Increment for paramset size > 1.
Definition: sqlite3odbc.h:211
SQLLEN * lenp0
Actual size of parameter buffer, initial value.
Definition: sqlite3odbc.h:208
void * s3val
SQLite3 value buffer.
Definition: sqlite3odbc.h:219
int coldef
Definition: sqlite3odbc.h:205
int stype
ODBC and SQL types.
Definition: sqlite3odbc.h:204
SQLLEN max
Max.
Definition: sqlite3odbc.h:206
char strbuf[64]
String buffer for scalar data.
Definition: sqlite3odbc.h:216
int bound
True when SQLBindParameter() called.
Definition: sqlite3odbc.h:213
sqlite_int64 s3lival
SQLite3 64bit integer value.
Definition: sqlite3odbc.h:221
int s3ival
SQLite3 integer value.
Definition: sqlite3odbc.h:220
SQLLEN * lenp
Actual size of parameter buffer.
Definition: sqlite3odbc.h:207
int s3size
SQLite3 size.
Definition: sqlite3odbc.h:218
Internal structure to describe a column in a result set.
Definition: sqlite3odbc.h:164
char * column
Column name.
Definition: sqlite3odbc.h:167
char * label
Column label or NULL.
Definition: sqlite3odbc.h:179
int nosign
Unsigned type.
Definition: sqlite3odbc.h:171
char * typename
Column type name or NULL.
Definition: sqlite3odbc.h:178
int notnull
NOT NULL constraint on column.
Definition: sqlite3odbc.h:175
int ispk
Flag for primary key (> 0)
Definition: sqlite3odbc.h:176
int prec
Precision of column.
Definition: sqlite3odbc.h:173
char * table
Table name.
Definition: sqlite3odbc.h:166
char * db
Database name.
Definition: sqlite3odbc.h:165
int type
Data type of column.
Definition: sqlite3odbc.h:168
int isrowid
Flag for ROWID column (> 0)
Definition: sqlite3odbc.h:177
int scale
Scale of column.
Definition: sqlite3odbc.h:172
int autoinc
AUTO_INCREMENT column.
Definition: sqlite3odbc.h:174
int size
Size of column.
Definition: sqlite3odbc.h:169
int index
Index of column in result.
Definition: sqlite3odbc.h:170
Driver internal structure for environment (HENV).
Definition: sqlite3odbc.h:96
int pool
True for SQL_CP_ONE_PER_DRIVER.
Definition: sqlite3odbc.h:99
int ov3
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:98
int magic
Magic cookie.
Definition: sqlite3odbc.h:97
struct dbc * dbcs
Pointer to first DBC.
Definition: sqlite3odbc.h:103
Driver internal structure for database connection (HDBC).
Definition: sqlite3odbc.h:112
int busyint
Interrupt busy handler from SQLCancel()
Definition: sqlite3odbc.h:122
char * pwd
Password or NULL.
Definition: sqlite3odbc.h:145
int s3stmt_needmeta
True to get meta data in s3stmt_step().
Definition: sqlite3odbc.h:143
int nowchar
Don't try to use WCHAR.
Definition: sqlite3odbc.h:131
struct stmt * cur_s3stmt
Current STMT executing sqlite statement.
Definition: sqlite3odbc.h:142
long t0
Start time for SQLITE busy handler.
Definition: sqlite3odbc.h:121
int curtype
Default cursor type.
Definition: sqlite3odbc.h:137
int step_enable
True for sqlite_compile/step/finalize.
Definition: sqlite3odbc.h:138
int intrans
True when transaction started.
Definition: sqlite3odbc.h:126
char * dsn
ODBC data source name.
Definition: sqlite3odbc.h:119
struct stmt * stmt
STMT list of this DBC.
Definition: sqlite3odbc.h:127
int pwdLen
Length of password.
Definition: sqlite3odbc.h:146
int * ov3
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:123
int magic
Magic cookie.
Definition: sqlite3odbc.h:113
FILE * trace
sqlite3_trace() file pointer or NULL
Definition: sqlite3odbc.h:144
int oemcp
True for Win32 OEM CP translation.
Definition: sqlite3odbc.h:140
int longnames
Don't shorten column names.
Definition: sqlite3odbc.h:134
int trans_disable
True for no transaction support.
Definition: sqlite3odbc.h:139
ENV * env
Pointer to environment.
Definition: sqlite3odbc.h:114
int dobigint
Force SQL_BIGINT for INTEGER columns.
Definition: sqlite3odbc.h:132
int fksupport
Foreign keys on or off.
Definition: sqlite3odbc.h:136
int naterr
Native error code.
Definition: sqlite3odbc.h:128
char sqlstate[6]
SQL state for SQLError()
Definition: sqlite3odbc.h:129
int version
SQLITE version number.
Definition: sqlite3odbc.h:117
int autocommit
Auto commit state.
Definition: sqlite3odbc.h:125
int jdconv
True for julian day conversion.
Definition: sqlite3odbc.h:141
struct dbc * next
Pointer to next DBC.
Definition: sqlite3odbc.h:115
char * dbname
SQLITE database name.
Definition: sqlite3odbc.h:118
int shortnames
Always use short column names.
Definition: sqlite3odbc.h:133
SQLCHAR logmsg[1024]
Message for SQLError()
Definition: sqlite3odbc.h:130
int ov3val
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:124
int nocreat
Don't auto create database file.
Definition: sqlite3odbc.h:135
sqlite3 * sqlite
SQLITE database handle.
Definition: sqlite3odbc.h:116
int timeout
Lock timeout value.
Definition: sqlite3odbc.h:120
Internal structure representing dynamic strings.
Definition: sqlite3odbc.c:272
int oom
True when out of memory.
Definition: sqlite3odbc.c:275
int len
Current length.
Definition: sqlite3odbc.c:273
int max
Maximum length of buffer.
Definition: sqlite3odbc.c:274
char buffer[1]
String buffer.
Definition: sqlite3odbc.c:276
Driver internal structure representing SQL statement (HSTMT).
Definition: sqlite3odbc.h:231
SQLUSMALLINT * row_status0
Internal status array.
Definition: sqlite3odbc.h:267
int * ov3
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:236
SQLUSMALLINT row_status1
Internal status array for 1 row rowsets.
Definition: sqlite3odbc.h:268
BINDCOL * bindcols
Array of bound columns.
Definition: sqlite3odbc.h:247
int naterr
Native error code.
Definition: sqlite3odbc.h:258
SQLULEN * parm_bind_offs
SQL_ATTR_PARAM_BIND_OFFSET_PTR.
Definition: sqlite3odbc.h:278
int dcols
Number of entries in dyncols.
Definition: sqlite3odbc.h:243
SQLULEN bind_type
SQL_ATTR_ROW_BIND_TYPE.
Definition: sqlite3odbc.h:275
BINDCOL bkmrkcol
Bookmark bound column.
Definition: sqlite3odbc.h:246
int nbindparms
Number bound parameters.
Definition: sqlite3odbc.h:249
COL * dyncols
Column array, but malloc()ed.
Definition: sqlite3odbc.h:242
COL * cols
Result column array.
Definition: sqlite3odbc.h:241
int dobigint
Force SQL_BIGINT for INTEGER columns.
Definition: sqlite3odbc.h:262
int s3stmt_rownum
Current row number.
Definition: sqlite3odbc.h:286
SQLCHAR logmsg[1024]
Message for SQLError()
Definition: sqlite3odbc.h:260
int ncols
Number of result columns.
Definition: sqlite3odbc.h:240
SQLULEN * row_count
Row count pointer.
Definition: sqlite3odbc.h:269
SQLULEN paramset_count
Internal for paramset.
Definition: sqlite3odbc.h:272
SQLUSMALLINT * parm_oper
SQL_ATTR_PARAM_OPERATION_PTR.
Definition: sqlite3odbc.h:279
int nowchar[2]
Don't try to use WCHAR.
Definition: sqlite3odbc.h:261
int binlen
Length of blob data.
Definition: sqlite3odbc.h:289
int longnames
Don't shorten column names.
Definition: sqlite3odbc.h:263
SQLULEN parm_bind_type
SQL_ATTR_PARAM_BIND_TYPE.
Definition: sqlite3odbc.h:282
int guessed_types
Flag for drvprepare()/drvexecute()
Definition: sqlite3odbc.h:290
char * bincell
Cache for blob data.
Definition: sqlite3odbc.h:287
SQLCHAR cursorname[32]
Cursor name.
Definition: sqlite3odbc.h:234
int nrows
Number of result rows.
Definition: sqlite3odbc.h:253
SQLULEN paramset_size
SQL_ATTR_PARAMSET_SIZE.
Definition: sqlite3odbc.h:271
int bkmrk
True when bookmarks used.
Definition: sqlite3odbc.h:244
int * jdconv
True for julian day conversion.
Definition: sqlite3odbc.h:238
SQLULEN * parm_proc
SQL_ATTR_PARAMS_PROCESSED_PTR.
Definition: sqlite3odbc.h:281
sqlite3_stmt * s3stmt
SQLite statement handle or NULL.
Definition: sqlite3odbc.h:284
SQLULEN * bind_offs
SQL_ATTR_ROW_BIND_OFFSET_PTR.
Definition: sqlite3odbc.h:276
SQLULEN retr_data
SQL_ATTR_RETRIEVE_DATA.
Definition: sqlite3odbc.h:264
SQLULEN max_rows
SQL_ATTR_MAX_ROWS.
Definition: sqlite3odbc.h:274
HDBC dbc
Pointer to DBC.
Definition: sqlite3odbc.h:233
BINDPARM * bindparms
Array of bound parameters.
Definition: sqlite3odbc.h:250
int has_rowid
Flag for ROWID (>= 0 or -1)
Definition: sqlite3odbc.h:293
SQLUSMALLINT * parm_status
SQL_ATTR_PARAMS_STATUS_PTR.
Definition: sqlite3odbc.h:280
int one_tbl
Flag for single table (> 0)
Definition: sqlite3odbc.h:291
int curtype
Cursor type.
Definition: sqlite3odbc.h:283
int rowprs
Current start row of rowset.
Definition: sqlite3odbc.h:255
char ** rows
2-dim array, result set
Definition: sqlite3odbc.h:256
int isselect
‍0 if query is a SELECT statement
Definition: sqlite3odbc.h:239
int s3stmt_noreset
False when sqlite3_reset() needed.
Definition: sqlite3odbc.h:285
SQLULEN rowset_size
Size of rowset.
Definition: sqlite3odbc.h:265
int nparams
Number of parameters in query.
Definition: sqlite3odbc.h:251
SQLUINTEGER paramset_nrows
Row count for paramset handling.
Definition: sqlite3odbc.h:273
int nbindcols
Number of entries in bindcols.
Definition: sqlite3odbc.h:248
SQLCHAR * query
Current query, raw string.
Definition: sqlite3odbc.h:235
int * oemcp
True for Win32 OEM CP translation.
Definition: sqlite3odbc.h:237
int rowp
Current result row.
Definition: sqlite3odbc.h:254
char * bincache
Cache for blob data.
Definition: sqlite3odbc.h:288
int pdcount
SQLParamData() counter.
Definition: sqlite3odbc.h:252
SQLUSMALLINT * row_status
Row status pointer.
Definition: sqlite3odbc.h:266
int has_pk
Flag for primary key (> 0)
Definition: sqlite3odbc.h:292
char sqlstate[6]
SQL state for SQLError()
Definition: sqlite3odbc.h:259
struct stmt * next
Linkage for STMT list in DBC.
Definition: sqlite3odbc.h:232
SQLULEN row_count0
Row count.
Definition: sqlite3odbc.h:270
void(* rowfree)()
Free function for rows.
Definition: sqlite3odbc.h:257
SQLINTEGER * bkmrkptr
SQL_ATTR_FETCH_BOOKMARK_PTR.
Definition: sqlite3odbc.h:245
Internal dynamic string buffer.
Definition: blobtoxy.c:1212
Internal structure for managing driver's sqlite3_get_table() implementation.
Definition: sqlite3odbc.c:1374
sqlite3_stmt * stmt
SQLite3 statement pointer.
Definition: sqlite3odbc.c:1377
int rc
SQLite return code.
Definition: sqlite3odbc.c:1383
int ncol
number of columns in result array
Definition: sqlite3odbc.c:1381
char ** resarr
result array
Definition: sqlite3odbc.c:1375
int nrow
number of rows in result array
Definition: sqlite3odbc.c:1380
PTRDIFF_T ndata
index into result array
Definition: sqlite3odbc.c:1382
int nalloc
alloc'ed size of result array
Definition: sqlite3odbc.c:1379
STMT * s
Driver statement pointer.
Definition: sqlite3odbc.c:1378
char * errmsg
error message or NULL
Definition: sqlite3odbc.c:1376
static int initialized
Definition: xpath.c:66

Generated on Mon Aug 17 2020 by doxygen.
Contact: chw@ch-werner.de