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 + sizeof (*dsp));
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 + sizeof (*dsp));
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 + sizeof (*dsp));
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 + sizeof (*dsp));
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 if (nalloc < t->nalloc) {
1408 goto nomem;
1409 }
1410 resnew = xrealloc(t->resarr, sizeof (char *) * nalloc);
1411 if (!resnew) {
1412nomem:
1413 t->rc = SQLITE_NOMEM;
1414 return 1;
1415 }
1416 t->nalloc = nalloc;
1417 t->resarr = resnew;
1418 }
1419 /* column names when first row */
1420 if (t->nrow == 0) {
1421 t->ncol = ncol;
1422 for (i = 0; i < ncol; i++) {
1423 p = (char *) sqlite3_column_name(t->stmt, i);
1424 if (p) {
1425 char *q = xmalloc(strlen(p) + 1);
1426
1427 if (!q) {
1428 goto nomem;
1429 }
1430 strcpy(q, p);
1431 p = q;
1432 }
1433 t->resarr[t->ndata++] = p;
1434 }
1435 if (t->s && t->s->guessed_types) {
1436 int ncol2 = ncol;
1437
1438 setupdyncols(t->s, t->stmt, &ncol2);
1439 t->s->guessed_types = 0;
1440 t->s->ncols = ncol;
1441 }
1442 } else if (t->ncol != ncol) {
1443 t->errmsg = sqlite3_mprintf("drvgettable() called with two or"
1444 " more incompatible queries");
1445 t->rc = SQLITE_ERROR;
1446 return 1;
1447 }
1448 /* copy row data */
1449 if (rc == SQLITE_ROW) {
1450 for (i = 0; i < ncol; i++) {
1451 int coltype = sqlite3_column_type(t->stmt, i);
1452
1453 p = NULL;
1454 if (coltype == SQLITE_BLOB) {
1455 int k, nbytes = sqlite3_column_bytes(t->stmt, i);
1456 char *qp;
1457 unsigned const char *bp;
1458
1459 bp = sqlite3_column_blob(t->stmt, i);
1460 qp = xmalloc(nbytes * 2 + 4);
1461 if (!qp) {
1462 goto nomem;
1463 }
1464 p = qp;
1465 *qp++ = 'X';
1466 *qp++ = '\'';
1467 for (k = 0; k < nbytes; k++) {
1468 *qp++ = xdigits[(bp[k] >> 4)];
1469 *qp++ = xdigits[(bp[k] & 0xF)];
1470 }
1471 *qp++ = '\'';
1472 *qp = '\0';
1473#ifdef _MSC_VER
1474 } else if (coltype == SQLITE_FLOAT) {
1475 struct lconv *lc = 0;
1476 double val = sqlite3_column_double(t->stmt, i);
1477 char buffer[128];
1478
1479 /*
1480 * This avoids floating point rounding
1481 * and formatting problems of some SQLite
1482 * versions in conjunction with MSVC 2010.
1483 */
1484 snprintf(buffer, sizeof (buffer), "%.15g", val);
1485 lc = localeconv();
1486 if (lc && lc->decimal_point && lc->decimal_point[0] &&
1487 lc->decimal_point[0] != '.') {
1488 p = strchr(buffer, lc->decimal_point[0]);
1489 if (p) {
1490 *p = '.';
1491 }
1492 }
1493 p = xstrdup(buffer);
1494 if (!p) {
1495 goto nomem;
1496 }
1497#endif
1498 } else if (coltype != SQLITE_NULL) {
1499 p = xstrdup((char *) sqlite3_column_text(t->stmt, i));
1500 if (!p) {
1501 goto nomem;
1502 }
1503 }
1504 t->resarr[t->ndata++] = p;
1505 }
1506 t->nrow++;
1507 }
1508 return 0;
1509}
1510
1511static int
1512drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp,
1513 int *ncolp, char **errp, int nparam, BINDPARM *p)
1514{
1515 DBC *d = (DBC *) s->dbc;
1516 int rc = SQLITE_OK, keep = sql == NULL;
1517 TBLRES tres;
1518 const char *sqlleft = 0;
1519 int nretry = 0, haveerr = 0;
1520
1521 if (!resp) {
1522 return SQLITE_ERROR;
1523 }
1524 *resp = NULL;
1525 if (nrowp) {
1526 *nrowp = 0;
1527 }
1528 if (ncolp) {
1529 *ncolp = 0;
1530 }
1531 tres.errmsg = NULL;
1532 tres.nrow = 0;
1533 tres.ncol = 0;
1534 tres.ndata = 1;
1535 tres.nalloc = 20;
1536 tres.rc = SQLITE_OK;
1537 tres.resarr = xmalloc(sizeof (char *) * tres.nalloc);
1538 tres.stmt = NULL;
1539 tres.s = s;
1540 if (!tres.resarr) {
1541 return SQLITE_NOMEM;
1542 }
1543 tres.resarr[0] = 0;
1544 if (sql == NULL) {
1545 tres.stmt = s->s3stmt;
1546 if (tres.stmt == NULL) {
1547 return SQLITE_NOMEM;
1548 }
1549 goto retrieve;
1550 }
1551 while (sql && *sql && (rc == SQLITE_OK ||
1552 (rc == SQLITE_SCHEMA && (++nretry) < 2))) {
1553 int ncol;
1554
1555 tres.stmt = NULL;
1556#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
1557 dbtraceapi(d, "sqlite3_prepare_v2", sql);
1558 rc = sqlite3_prepare_v2(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
1559#else
1560 dbtraceapi(d, "sqlite3_prepare", sql);
1561 rc = sqlite3_prepare(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
1562#endif
1563 if (rc != SQLITE_OK) {
1564 if (tres.stmt) {
1565 dbtraceapi(d, "sqlite3_finalize", 0);
1566 sqlite3_finalize(tres.stmt);
1567 tres.stmt = NULL;
1568 }
1569 continue;
1570 }
1571 if (!tres.stmt) {
1572 /* this happens for a comment or white-space */
1573 sql = sqlleft;
1574 continue;
1575 }
1576retrieve:
1577 if (sqlite3_bind_parameter_count(tres.stmt) != nparam) {
1578 if (errp) {
1579 *errp =
1580 sqlite3_mprintf("%s", "parameter marker count incorrect");
1581 }
1582 haveerr = 1;
1583 rc = SQLITE_ERROR;
1584 goto tbldone;
1585 }
1586 s3bind(d, tres.stmt, nparam, p);
1587 ncol = sqlite3_column_count(tres.stmt);
1588 while (1) {
1589 if (s->max_rows && tres.nrow >= s->max_rows) {
1590 rc = SQLITE_OK;
1591 break;
1592 }
1593 rc = sqlite3_step(tres.stmt);
1594 if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
1595 if (drvgettable_row(&tres, ncol, rc)) {
1596 rc = SQLITE_ABORT;
1597 goto tbldone;
1598 }
1599 }
1600 if (rc != SQLITE_ROW) {
1601 if (keep) {
1602 dbtraceapi(d, "sqlite3_reset", 0);
1603 rc = sqlite3_reset(tres.stmt);
1604 s->s3stmt_noreset = 1;
1605 } else {
1606 dbtraceapi(d, "sqlite3_finalize", 0);
1607 rc = sqlite3_finalize(tres.stmt);
1608 }
1609 tres.stmt = 0;
1610 if (rc != SQLITE_SCHEMA) {
1611 nretry = 0;
1612 sql = sqlleft;
1613 while (sql && ISSPACE(*sql)) {
1614 sql++;
1615 }
1616 }
1617 if (rc == SQLITE_DONE) {
1618 rc = SQLITE_OK;
1619 }
1620 break;
1621 }
1622 }
1623 }
1624tbldone:
1625 if (tres.stmt) {
1626 if (keep) {
1627 if (!s->s3stmt_noreset) {
1628 dbtraceapi(d, "sqlite3_reset", 0);
1629 sqlite3_reset(tres.stmt);
1630 s->s3stmt_noreset = 1;
1631 }
1632 } else {
1633 dbtraceapi(d, "sqlite3_finalize", 0);
1634 sqlite3_finalize(tres.stmt);
1635 }
1636 }
1637 if (haveerr) {
1638 /* message already in *errp if any */
1639 } else if (rc != SQLITE_OK && rc == sqlite3_errcode(d->sqlite) && errp) {
1640 *errp = sqlite3_mprintf("%s", sqlite3_errmsg(d->sqlite));
1641 } else if (errp) {
1642 *errp = NULL;
1643 }
1644 if (tres.resarr) {
1645 tres.resarr[0] = (char *) (tres.ndata - 1);
1646 }
1647 if (rc == SQLITE_ABORT) {
1648 freerows(&tres.resarr[1]);
1649 if (tres.errmsg) {
1650 if (errp) {
1651 if (*errp) {
1652 sqlite3_free(*errp);
1653 }
1654 *errp = tres.errmsg;
1655 } else {
1656 sqlite3_free(tres.errmsg);
1657 }
1658 }
1659 return tres.rc;
1660 }
1661 sqlite3_free(tres.errmsg);
1662 if (rc != SQLITE_OK) {
1663 freerows(&tres.resarr[1]);
1664 return rc;
1665 }
1666 *resp = &tres.resarr[1];
1667 if (ncolp) {
1668 *ncolp = tres.ncol;
1669 }
1670 if (nrowp) {
1671 *nrowp = tres.nrow;
1672 }
1673 return rc;
1674}
1675
1684#if defined(__GNUC__) && (__GNUC__ >= 2)
1685static void setstatd(DBC *, int, char *, char *, ...)
1686 __attribute__((format (printf, 3, 5)));
1687#endif
1688
1689static void
1690setstatd(DBC *d, int naterr, char *msg, char *st, ...)
1691{
1692 va_list ap;
1693
1694 if (!d) {
1695 return;
1696 }
1697 d->naterr = naterr;
1698 d->logmsg[0] = '\0';
1699 if (msg) {
1700 int count;
1701
1702 va_start(ap, st);
1703 count = vsnprintf((char *) d->logmsg, sizeof (d->logmsg), msg, ap);
1704 va_end(ap);
1705 if (count < 0) {
1706 d->logmsg[sizeof (d->logmsg) - 1] = '\0';
1707 }
1708 }
1709 if (!st) {
1710 st = "?????";
1711 }
1712 strncpy(d->sqlstate, st, 5);
1713 d->sqlstate[5] = '\0';
1714}
1715
1724#if defined(__GNUC__) && (__GNUC__ >= 2)
1725static void setstat(STMT *, int, char *, char *, ...)
1726 __attribute__((format (printf, 3, 5)));
1727#endif
1728
1729static void
1730setstat(STMT *s, int naterr, char *msg, char *st, ...)
1731{
1732 va_list ap;
1733
1734 if (!s) {
1735 return;
1736 }
1737 s->naterr = naterr;
1738 s->logmsg[0] = '\0';
1739 if (msg) {
1740 int count;
1741
1742 va_start(ap, st);
1743 count = vsnprintf((char *) s->logmsg, sizeof (s->logmsg), msg, ap);
1744 va_end(ap);
1745 if (count < 0) {
1746 s->logmsg[sizeof (s->logmsg) - 1] = '\0';
1747 }
1748 }
1749 if (!st) {
1750 st = "?????";
1751 }
1752 strncpy(s->sqlstate, st, 5);
1753 s->sqlstate[5] = '\0';
1754}
1755
1762static SQLRETURN
1764{
1765 DBC *d;
1766
1767 if (dbc == SQL_NULL_HDBC) {
1768 return SQL_INVALID_HANDLE;
1769 }
1770 d = (DBC *) dbc;
1771 setstatd(d, -1, "not supported", "IM001");
1772 return SQL_ERROR;
1773}
1774
1781static SQLRETURN
1783{
1784 STMT *s;
1785
1786 if (stmt == SQL_NULL_HSTMT) {
1787 return SQL_INVALID_HANDLE;
1788 }
1789 s = (STMT *) stmt;
1790 setstat(s, -1, "not supported", "IM001");
1791 return SQL_ERROR;
1792}
1793
1799static void
1800freep(void *x)
1801{
1802 if (x && ((char **) x)[0]) {
1803 xfree(((char **) x)[0]);
1804 ((char **) x)[0] = NULL;
1805 }
1806}
1807
1814static SQLRETURN
1816{
1817 setstat(s, -1, "out of memory", (*s->ov3) ? "HY000" : "S1000");
1818 return SQL_ERROR;
1819}
1820
1827static SQLRETURN
1829{
1830 setstat(s, -1, "not connected", (*s->ov3) ? "HY000" : "S1000");
1831 return SQL_ERROR;
1832}
1833
1841#if defined(HAVE_LOCALECONV) || defined(_WIN32) || defined(_WIN64)
1842
1843static double
1844ln_strtod(const char *data, char **endp)
1845{
1846 struct lconv *lc = 0;
1847 char buf[128], *p, *end;
1848 double value;
1849
1850 lc = localeconv();
1851 if (lc && lc->decimal_point && lc->decimal_point[0] &&
1852 lc->decimal_point[0] != '.') {
1853 strncpy(buf, data, sizeof (buf) - 1);
1854 buf[sizeof (buf) - 1] = '\0';
1855 p = strchr(buf, '.');
1856 if (p) {
1857 *p = lc->decimal_point[0];
1858 }
1859 p = buf;
1860 } else {
1861 p = (char *) data;
1862 }
1863 value = strtod(p, &end);
1864 end = (char *) data + (end - p);
1865 if (endp) {
1866 *endp = end;
1867 }
1868 return value;
1869}
1870
1871#else
1872
1873#define ln_strtod(A,B) strtod(A,B)
1874
1875#endif
1876
1882static char *
1883unquote(char *str)
1884{
1885 if (str) {
1886 int len = strlen(str);
1887
1888 if (len > 1) {
1889 int end = len - 1;
1890
1891 if ((str[0] == '\'' && str[end] == '\'') ||
1892 (str[0] == '"' && str[end] == '"') ||
1893 (str[0] == '[' && str[end] == ']')) {
1894 memmove(str, str + 1, end - 1);
1895 str[end - 1] = '\0';
1896 }
1897 }
1898 }
1899 return str;
1900}
1901
1909static int
1910unescpat(char *str)
1911{
1912 char *p, *q;
1913 int count = 0;
1914
1915 p = str;
1916 while ((q = strchr(p, '_')) != NULL) {
1917 if (q == str || q[-1] != '\\') {
1918 count++;
1919 }
1920 p = q + 1;
1921 }
1922 p = str;
1923 while ((q = strchr(p, '%')) != NULL) {
1924 if (q == str || q[-1] != '\\') {
1925 count++;
1926 }
1927 p = q + 1;
1928 }
1929 p = str;
1930 while ((q = strchr(p, '\\')) != NULL) {
1931 if (q[1] == '\\' || q[1] == '_' || q[1] == '%') {
1932 memmove(q, q + 1, strlen(q));
1933 }
1934 p = q + 1;
1935 }
1936 return count;
1937}
1938
1947static int
1948namematch(char *str, char *pat, int esc)
1949{
1950 int cp, ch;
1951
1952 while (1) {
1953 cp = TOLOWER(*pat);
1954 if (cp == '\0') {
1955 if (*str != '\0') {
1956 goto nomatch;
1957 }
1958 break;
1959 }
1960 if (*str == '\0' && cp != '%') {
1961 goto nomatch;
1962 }
1963 if (cp == '%') {
1964 while (*pat == '%') {
1965 ++pat;
1966 }
1967 cp = TOLOWER(*pat);
1968 if (cp == '\0') {
1969 break;
1970 }
1971 while (1) {
1972 if (cp != '_' && cp != '\\') {
1973 while (*str) {
1974 ch = TOLOWER(*str);
1975 if (ch == cp) {
1976 break;
1977 }
1978 ++str;
1979 }
1980 }
1981 if (namematch(str, pat, esc)) {
1982 goto match;
1983 }
1984 if (*str == '\0') {
1985 goto nomatch;
1986 }
1987 ch = TOLOWER(*str);
1988 ++str;
1989 }
1990 }
1991 if (cp == '_') {
1992 pat++;
1993 str++;
1994 continue;
1995 }
1996 if (esc && cp == '\\' &&
1997 (pat[1] == '\\' || pat[1] == '%' || pat[1] == '_')) {
1998 ++pat;
1999 cp = TOLOWER(*pat);
2000 }
2001 ch = TOLOWER(*str++);
2002 ++pat;
2003 if (ch != cp) {
2004 goto nomatch;
2005 }
2006 }
2007match:
2008 return 1;
2009nomatch:
2010 return 0;
2011}
2012
2020static int
2021busy_handler(void *udata, int count)
2022{
2023 DBC *d = (DBC *) udata;
2024 long t1;
2025 int ret = 0;
2026#if !defined(_WIN32) && !defined(_WIN64)
2027 struct timeval tv;
2028#ifdef HAVE_NANOSLEEP
2029 struct timespec ts;
2030#endif
2031#endif
2032
2033 if (d->busyint) {
2034 d->busyint = 0;
2035 return ret;
2036 }
2037 if (d->timeout <= 0) {
2038 return ret;
2039 }
2040 if (count <= 1) {
2041#if defined(_WIN32) || defined(_WIN64)
2042 d->t0 = GetTickCount();
2043#else
2044 gettimeofday(&tv, NULL);
2045 d->t0 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
2046#endif
2047 }
2048#if defined(_WIN32) || defined(_WIN64)
2049 t1 = GetTickCount();
2050#else
2051 gettimeofday(&tv, NULL);
2052 t1 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
2053#endif
2054 if (t1 - d->t0 > d->timeout) {
2055 goto done;
2056 }
2057#if defined(_WIN32) || defined(_WIN64)
2058 Sleep(10);
2059#else
2060#ifdef HAVE_NANOSLEEP
2061 ts.tv_sec = 0;
2062 ts.tv_nsec = 10000000;
2063 do {
2064 ret = nanosleep(&ts, &ts);
2065 if (ret < 0 && errno != EINTR) {
2066 ret = 0;
2067 }
2068 } while (ret);
2069#else
2070#ifdef HAVE_USLEEP
2071 usleep(10000);
2072#else
2073 tv.tv_sec = 0;
2074 tv.tv_usec = 10000;
2075 select(0, NULL, NULL, NULL, &tv);
2076#endif
2077#endif
2078#endif
2079 ret = 1;
2080done:
2081 return ret;
2082}
2083
2095static int
2096setsqliteopts(sqlite3 *x, DBC *d)
2097{
2098 int count = 0, step = 0, max, rc = SQLITE_ERROR;
2099
2100#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
2101 max = d->longnames ? 3 : 1;
2102#else
2103 max = 3;
2104#endif
2105 if (d->shortnames) {
2106 max = 3;
2107 }
2108 while (step < max) {
2109 if (step < 1) {
2110 rc = sqlite3_exec(x, "PRAGMA empty_result_callbacks = on;",
2111 NULL, NULL, NULL);
2112 if (rc == SQLITE_OK) {
2113 rc = sqlite3_exec(x, d->fksupport ?
2114 "PRAGMA foreign_keys = on;" :
2115 "PRAGMA foreign_keys = off;",
2116 NULL, NULL, NULL);
2117 }
2118 } else if (step < 2) {
2119 rc = sqlite3_exec(x, d->shortnames ?
2120 "PRAGMA full_column_names = off;" :
2121 "PRAGMA full_column_names = on;",
2122 NULL, NULL, NULL);
2123 } else if (step < 3) {
2124 rc = sqlite3_exec(x, d->shortnames ?
2125 "PRAGMA short_column_names = on;" :
2126 "PRAGMA short_column_names = off;",
2127 NULL, NULL, NULL);
2128 }
2129 if (rc != SQLITE_OK) {
2130 if (rc != SQLITE_BUSY ||
2131 !busy_handler((void *) d, ++count)) {
2132 return rc;
2133 }
2134 continue;
2135 }
2136 count = 0;
2137 ++step;
2138 }
2139 sqlite3_busy_handler(x, busy_handler, (void *) d);
2140 return SQLITE_OK;
2141}
2142
2152static void
2153freerows(char **rowp)
2154{
2155 PTRDIFF_T size, i;
2156
2157 if (!rowp) {
2158 return;
2159 }
2160 --rowp;
2161 size = (PTRDIFF_T) rowp[0];
2162 for (i = 1; i <= size; i++) {
2163 freep(&rowp[i]);
2164 }
2165 freep(&rowp);
2166}
2167
2178static int
2179mapsqltype(const char *typename, int *nosign, int ov3, int nowchar,
2180 int dobigint)
2181{
2182 char *p, *q;
2183 int testsign = 0, result;
2184
2185#ifdef WINTERFACE
2186 result = nowchar ? SQL_VARCHAR : SQL_WVARCHAR;
2187#else
2188 result = SQL_VARCHAR;
2189#endif
2190 if (!typename) {
2191 return result;
2192 }
2193 q = p = xmalloc(strlen(typename) + 1);
2194 if (!p) {
2195 return result;
2196 }
2197 strcpy(p, typename);
2198 while (*q) {
2199 *q = TOLOWER(*q);
2200 ++q;
2201 }
2202 if (strncmp(p, "inter", 5) == 0) {
2203 } else if (strncmp(p, "int", 3) == 0 ||
2204 strncmp(p, "mediumint", 9) == 0) {
2205 testsign = 1;
2206 result = SQL_INTEGER;
2207 } else if (strncmp(p, "numeric", 7) == 0) {
2208 result = SQL_DOUBLE;
2209 } else if (strncmp(p, "tinyint", 7) == 0) {
2210 testsign = 1;
2211 result = SQL_TINYINT;
2212 } else if (strncmp(p, "smallint", 8) == 0) {
2213 testsign = 1;
2214 result = SQL_SMALLINT;
2215 } else if (strncmp(p, "float", 5) == 0) {
2216 result = SQL_DOUBLE;
2217 } else if (strncmp(p, "double", 6) == 0 ||
2218 strncmp(p, "real", 4) == 0) {
2219 result = SQL_DOUBLE;
2220 } else if (strncmp(p, "timestamp", 9) == 0) {
2221#ifdef SQL_TYPE_TIMESTAMP
2222 result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
2223#else
2224 result = SQL_TIMESTAMP;
2225#endif
2226 } else if (strncmp(p, "datetime", 8) == 0) {
2227#ifdef SQL_TYPE_TIMESTAMP
2228 result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
2229#else
2230 result = SQL_TIMESTAMP;
2231#endif
2232 } else if (strncmp(p, "time", 4) == 0) {
2233#ifdef SQL_TYPE_TIME
2234 result = ov3 ? SQL_TYPE_TIME : SQL_TIME;
2235#else
2236 result = SQL_TIME;
2237#endif
2238 } else if (strncmp(p, "date", 4) == 0) {
2239#ifdef SQL_TYPE_DATE
2240 result = ov3 ? SQL_TYPE_DATE : SQL_DATE;
2241#else
2242 result = SQL_DATE;
2243#endif
2244#ifdef SQL_LONGVARCHAR
2245 } else if (strncmp(p, "text", 4) == 0 ||
2246 strncmp(p, "memo", 4) == 0 ||
2247 strncmp(p, "longvarchar", 11) == 0) {
2248#ifdef WINTERFACE
2249 result = nowchar ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
2250#else
2251 result = SQL_LONGVARCHAR;
2252#endif
2253#ifdef WINTERFACE
2254 } else if (strncmp(p, "wtext", 5) == 0 ||
2255 strncmp(p, "wvarchar", 8) == 0 ||
2256 strncmp(p, "longwvarchar", 12) == 0) {
2257 result = SQL_WLONGVARCHAR;
2258#endif
2259#endif
2260#ifdef SQL_BIT
2261 } else if (strncmp(p, "bool", 4) == 0 ||
2262 strncmp(p, "bit", 3) == 0) {
2263 result = SQL_BIT;
2264#endif
2265#ifdef SQL_BIGINT
2266 } else if (strncmp(p, "bigint", 6) == 0) {
2267 testsign = 1;
2268 result = SQL_BIGINT;
2269#endif
2270 } else if (strncmp(p, "blob", 4) == 0) {
2271 result = SQL_BINARY;
2272 } else if (strncmp(p, "varbinary", 9) == 0) {
2273 result = SQL_VARBINARY;
2274 } else if (strncmp(p, "longvarbinary", 13) == 0) {
2275 result = SQL_LONGVARBINARY;
2276 }
2277 if (nosign) {
2278 if (testsign) {
2279 *nosign = strstr(p, "unsigned") != NULL;
2280 } else {
2281 *nosign = 1;
2282 }
2283 }
2284#ifdef SQL_BIGINT
2285 if (dobigint && result == SQL_INTEGER) {
2286 result = SQL_BIGINT;
2287 }
2288#endif
2289 xfree(p);
2290 return result;
2291}
2292
2302static void
2303getmd(const char *typename, int sqltype, int *mp, int *dp)
2304{
2305 int m = 0, d = 0;
2306
2307 switch (sqltype) {
2308 case SQL_INTEGER: m = 10; d = 9; break;
2309 case SQL_TINYINT: m = 4; d = 3; break;
2310 case SQL_SMALLINT: m = 6; d = 5; break;
2311 case SQL_FLOAT: m = 25; d = 24; break;
2312 case SQL_DOUBLE: m = 54; d = 53; break;
2313 case SQL_VARCHAR: m = 255; d = 0; break;
2314#ifdef WINTERFACE
2315#ifdef SQL_WVARCHAR
2316 case SQL_WVARCHAR: m = 255; d = 0; break;
2317#endif
2318#endif
2319#ifdef SQL_TYPE_DATE
2320 case SQL_TYPE_DATE:
2321#endif
2322 case SQL_DATE: m = 10; d = 0; break;
2323#ifdef SQL_TYPE_TIME
2324 case SQL_TYPE_TIME:
2325#endif
2326 case SQL_TIME: m = 8; d = 0; break;
2327#ifdef SQL_TYPE_TIMESTAMP
2328 case SQL_TYPE_TIMESTAMP:
2329#endif
2330 case SQL_TIMESTAMP: m = 32; d = 3; break;
2331#ifdef SQL_LONGVARCHAR
2332 case SQL_LONGVARCHAR : m = 65536; d = 0; break;
2333#endif
2334#ifdef WINTERFACE
2335#ifdef SQL_WLONGVARCHAR
2336 case SQL_WLONGVARCHAR: m = 65536; d = 0; break;
2337#endif
2338#endif
2339 case SQL_BINARY:
2340 case SQL_VARBINARY: m = 255; d = 0; break;
2341 case SQL_LONGVARBINARY: m = 65536; d = 0; break;
2342#ifdef SQL_BIGINT
2343 case SQL_BIGINT: m = 20; d = 19; break;
2344#endif
2345#ifdef SQL_BIT
2346 case SQL_BIT: m = 1; d = 1; break;
2347#endif
2348 }
2349 if (m && typename) {
2350 int mm, dd;
2351 char clbr[4];
2352
2353 if (sscanf(typename, "%*[^(](%d,%d %1[)]", &mm, &dd, clbr) == 3) {
2354 m = mm;
2355 d = dd;
2356 } else if (sscanf(typename, "%*[^(](%d %1[)]", &mm, clbr) == 2) {
2357 if (sqltype == SQL_TIMESTAMP) {
2358 d = mm;
2359 }
2360#ifdef SQL_TYPE_TIMESTAMP
2361 else if (sqltype == SQL_TYPE_TIMESTAMP) {
2362 d = mm;
2363 }
2364#endif
2365 else {
2366 m = d = mm;
2367 }
2368 }
2369 }
2370 if (mp) {
2371 *mp = m;
2372 }
2373 if (dp) {
2374 *dp = d;
2375 }
2376}
2377
2387static int
2388mapdeftype(int type, int stype, int nosign, int nowchar)
2389{
2390 if (type == SQL_C_DEFAULT) {
2391 switch (stype) {
2392 case SQL_INTEGER:
2393 type = (nosign > 0) ? SQL_C_ULONG : SQL_C_LONG;
2394 break;
2395 case SQL_TINYINT:
2396 type = (nosign > 0) ? SQL_C_UTINYINT : SQL_C_TINYINT;
2397 break;
2398 case SQL_SMALLINT:
2399 type = (nosign > 0) ? SQL_C_USHORT : SQL_C_SHORT;
2400 break;
2401 case SQL_FLOAT:
2402 type = SQL_C_FLOAT;
2403 break;
2404 case SQL_DOUBLE:
2405 type = SQL_C_DOUBLE;
2406 break;
2407 case SQL_TIMESTAMP:
2408 type = SQL_C_TIMESTAMP;
2409 break;
2410 case SQL_TIME:
2411 type = SQL_C_TIME;
2412 break;
2413 case SQL_DATE:
2414 type = SQL_C_DATE;
2415 break;
2416#ifdef SQL_C_TYPE_TIMESTAMP
2417 case SQL_TYPE_TIMESTAMP:
2418 type = SQL_C_TYPE_TIMESTAMP;
2419 break;
2420#endif
2421#ifdef SQL_C_TYPE_TIME
2422 case SQL_TYPE_TIME:
2423 type = SQL_C_TYPE_TIME;
2424 break;
2425#endif
2426#ifdef SQL_C_TYPE_DATE
2427 case SQL_TYPE_DATE:
2428 type = SQL_C_TYPE_DATE;
2429 break;
2430#endif
2431#ifdef WINTERFACE
2432 case SQL_WVARCHAR:
2433 case SQL_WCHAR:
2434#ifdef SQL_WLONGVARCHAR
2435 case SQL_WLONGVARCHAR:
2436#endif
2437 type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
2438 break;
2439#endif
2440 case SQL_BINARY:
2441 case SQL_VARBINARY:
2442 case SQL_LONGVARBINARY:
2443 type = SQL_C_BINARY;
2444 break;
2445#ifdef SQL_BIT
2446 case SQL_BIT:
2447 type = SQL_C_BIT;
2448 break;
2449#endif
2450#ifdef SQL_BIGINT
2451 case SQL_BIGINT:
2452 type = SQL_C_CHAR;
2453 break;
2454#endif
2455 default:
2456#ifdef WINTERFACE
2457 type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
2458#else
2459 type = SQL_C_CHAR;
2460#endif
2461 break;
2462 }
2463 }
2464 return type;
2465}
2466
2473static int
2474checkddl(char *sql)
2475{
2476 int isddl = 0;
2477
2478 while (*sql && ISSPACE(*sql)) {
2479 ++sql;
2480 }
2481 if (*sql && *sql != ';') {
2482 int i, size;
2483 static const struct {
2484 int len;
2485 const char *str;
2486 } ddlstr[] = {
2487 { 5, "alter" },
2488 { 7, "analyze" },
2489 { 6, "attach" },
2490 { 5, "begin" },
2491 { 6, "commit" },
2492 { 6, "create" },
2493 { 6, "detach" },
2494 { 4, "drop" },
2495 { 3, "end" },
2496 { 7, "reindex" },
2497 { 7, "release" },
2498 { 8, "rollback" },
2499 { 9, "savepoint" },
2500 { 6, "vacuum" }
2501 };
2502
2503 size = strlen(sql);
2504 for (i = 0; i < array_size(ddlstr); i++) {
2505 if (size >= ddlstr[i].len &&
2506 strncasecmp(sql, ddlstr[i].str, ddlstr[i].len) == 0) {
2507 isddl = 1;
2508 break;
2509 }
2510 }
2511 }
2512 return isddl;
2513}
2514
2526static char *
2527fixupsql(char *sql, int sqlLen, int cte, int *nparam, int *isselect,
2528 char **errmsg)
2529{
2530 char *q = sql, *qz = NULL, *p, *inq = NULL, *out;
2531 int np = 0, isddl = -1, size;
2532
2533 if (errmsg) {
2534 *errmsg = NULL;
2535 }
2536 if (sqlLen != SQL_NTS) {
2537 qz = q = xmalloc(sqlLen + 1);
2538 if (!qz) {
2539 return NULL;
2540 }
2541 memcpy(q, sql, sqlLen);
2542 q[sqlLen] = '\0';
2543 size = sqlLen * 4;
2544 } else {
2545 size = strlen(sql) * 4;
2546 }
2547 size += sizeof (char *) - 1;
2548 size &= ~(sizeof (char *) - 1);
2549 p = xmalloc(size);
2550 if (!p) {
2551errout:
2552 freep(&qz);
2553 return NULL;
2554 }
2555 memset(p, 0, size);
2556 out = p;
2557 while (*q) {
2558 switch (*q) {
2559 case '\'':
2560 case '\"':
2561 if (q == inq) {
2562 inq = NULL;
2563 } else if (!inq) {
2564 inq = q + 1;
2565
2566 while (*inq) {
2567 if (*inq == *q) {
2568 if (inq[1] == *q) {
2569 inq++;
2570 } else {
2571 break;
2572 }
2573 }
2574 inq++;
2575 }
2576 }
2577 *p++ = *q;
2578 break;
2579 case '-':
2580 *p++ = *q;
2581 if (!inq && q[1] == '-') {
2582 ++q;
2583 while (*q) {
2584 *p++ = *q++;
2585 if (*q == '\n') {
2586 break;
2587 }
2588 }
2589 }
2590 break;
2591 case '?':
2592 *p++ = *q;
2593 if (!inq) {
2594 np++;
2595 }
2596 break;
2597 case ';':
2598 if (!inq) {
2599 if (isddl < 0) {
2600 isddl = checkddl(out);
2601 }
2602 if (isddl == 0) {
2603 char *qq = q;
2604
2605 do {
2606 ++qq;
2607 } while (*qq && ISSPACE(*qq));
2608 if (*qq && *qq != ';') {
2609 freep(&out);
2610 if (errmsg) {
2611 *errmsg = "only one SQL statement allowed";
2612 }
2613 goto errout;
2614 }
2615 }
2616 }
2617 *p++ = *q;
2618 break;
2619 case '{':
2620 /*
2621 * Deal with escape sequences:
2622 * {d 'YYYY-MM-DD'}, {t ...}, {ts ...}
2623 * {oj ...}, {fn ...} etc.
2624 */
2625 if (!inq) {
2626 int ojfn = 0, brc = 0;
2627 char *inq2 = NULL, *end = q + 1, *start;
2628
2629 while (*end && ISSPACE(*end)) {
2630 ++end;
2631 }
2632 if (*end != 'd' && *end != 'D' &&
2633 *end != 't' && *end != 'T') {
2634 ojfn = 1;
2635 }
2636 start = end;
2637 while (*end) {
2638 if (inq2 && *end == *inq2) {
2639 inq2 = NULL;
2640 } else if (inq2 == NULL && *end == '{') {
2641 char *nerr = 0, *nsql;
2642
2643 nsql = fixupsql(end, SQL_NTS, cte, 0, 0, &nerr);
2644 if (nsql && !nerr) {
2645 strcpy(end, nsql);
2646 } else {
2647 brc++;
2648 }
2649 freep(&nsql);
2650 } else if (inq2 == NULL && *end == '}') {
2651 if (brc-- <= 0) {
2652 break;
2653 }
2654 } else if (inq2 == NULL && (*end == '\'' || *end == '"')) {
2655 inq2 = end;
2656 } else if (inq2 == NULL && *end == '?') {
2657 np++;
2658 }
2659 ++end;
2660 }
2661 if (*end == '}') {
2662 char *end2 = end - 1;
2663
2664 if (ojfn) {
2665 while (start < end) {
2666 if (ISSPACE(*start)) {
2667 break;
2668 }
2669 ++start;
2670 }
2671 while (start < end) {
2672 *p++ = *start;
2673 ++start;
2674 }
2675 q = end;
2676 break;
2677 } else {
2678 while (start < end2 && *start != '\'') {
2679 ++start;
2680 }
2681 while (end2 > start && *end2 != '\'') {
2682 --end2;
2683 }
2684 if (*start == '\'' && *end2 == '\'') {
2685 while (start <= end2) {
2686 *p++ = *start;
2687 ++start;
2688 }
2689 q = end;
2690 break;
2691 }
2692 }
2693 }
2694 }
2695 /* FALL THROUGH */
2696 default:
2697 *p++ = *q;
2698 }
2699 ++q;
2700 }
2701 freep(&qz);
2702 *p = '\0';
2703 if (nparam) {
2704 *nparam = np;
2705 }
2706 if (isselect) {
2707 if (isddl < 0) {
2708 isddl = checkddl(out);
2709 }
2710 if (isddl > 0) {
2711 *isselect = 2;
2712 } else {
2713 int incom = 0;
2714
2715 p = out;
2716 while (*p) {
2717 switch (*p) {
2718 case '-':
2719 if (!incom && p[1] == '-') {
2720 incom = -1;
2721 }
2722 break;
2723 case '\n':
2724 if (incom < 0) {
2725 incom = 0;
2726 }
2727 break;
2728 case '/':
2729 if (incom > 0 && p[-1] == '*') {
2730 incom = 0;
2731 p++;
2732 continue;
2733 } else if (!incom && p[1] == '*') {
2734 incom = 1;
2735 }
2736 break;
2737 }
2738 if (!incom && !ISSPACE(*p)) {
2739 break;
2740 }
2741 p++;
2742 }
2743 size = strlen(p);
2744 if (size >= 6 &&
2745 (strncasecmp(p, "select", 6) == 0 ||
2746 strncasecmp(p, "pragma", 6) == 0)) {
2747 *isselect = 1;
2748 } else if (cte && size >= 4 && strncasecmp(p, "with", 4) == 0) {
2749 *isselect = 1;
2750 } else if (size >= 7 && strncasecmp(p, "explain", 7) == 0) {
2751 *isselect = 1;
2752 } else {
2753 *isselect = 0;
2754 }
2755 }
2756 }
2757 return out;
2758}
2759
2765static void
2766replilike(char *sql)
2767{
2768 char *q = sql, *inq = NULL;
2769
2770 while (*q) {
2771 switch (*q) {
2772 case '\'':
2773 case '\"':
2774 if (q == inq) {
2775 inq = NULL;
2776 } else if (!inq) {
2777 inq = q + 1;
2778
2779 while (*inq) {
2780 if (*inq == *q) {
2781 if (inq[1] == *q) {
2782 inq++;
2783 } else {
2784 break;
2785 }
2786 }
2787 inq++;
2788 }
2789 }
2790 break;
2791 case '-':
2792 if (!inq && q[1] == '-') {
2793 ++q;
2794 while (*q) {
2795 if (*q == '\n') {
2796 break;
2797 }
2798 }
2799 }
2800 break;
2801 default:
2802 if (!inq && ISSPACE(*q) && q[1]) {
2803 if (strncasecmp(q + 1, "ilike", 5) == 0) {
2804 if ((q[2] != '\0') && (q[3] != '\0') &&
2805 (q[4] != '\0') && (q[5] != '\0') &&
2806 ((q[6] == '\0') || ISSPACE(q[6]))) {
2807 q++;
2808 memmove(q, q + 1, strlen(q));
2809 q += 3;
2810 }
2811 }
2812 }
2813 break;
2814 }
2815 ++q;
2816 }
2817}
2818
2827static int
2828findcol(char **cols, int ncols, char *name)
2829{
2830 int i;
2831
2832 if (cols) {
2833 for (i = 0; i < ncols; i++) {
2834 if (strcmp(cols[i], name) == 0) {
2835 return i;
2836 }
2837 }
2838 }
2839 return -1;
2840}
2841
2858static void
2860{
2861 int i, k;
2862#ifndef FULL_METADATA
2863 int pk, nn, t, r, nrows, ncols;
2864 char **rowp, *flagp, flags[128];
2865#endif
2866
2867 if (!s->dyncols) {
2868 return;
2869 }
2870 /* fixup labels */
2871 if (!s->longnames) {
2872 if (s->dcols > 1) {
2873 char *table = s->dyncols[0].table;
2874
2875 for (i = 1; table[0] && i < s->dcols; i++) {
2876 if (strcmp(s->dyncols[i].table, table)) {
2877 break;
2878 }
2879 }
2880 if (i >= s->dcols) {
2881 for (i = 0; i < s->dcols; i++) {
2882 s->dyncols[i].label = s->dyncols[i].column;
2883 }
2884 }
2885 } else if (s->dcols == 1) {
2886 s->dyncols[0].label = s->dyncols[0].column;
2887 }
2888 }
2889 for (i = 0; i < s->dcols; i++) {
2890 s->dyncols[i].type =
2891 mapsqltype(s->dyncols[i].typename, &s->dyncols[i].nosign, *s->ov3,
2892 s->nowchar[0] || s->nowchar[1], s->dobigint);
2893 getmd(s->dyncols[i].typename, s->dyncols[i].type,
2894 &s->dyncols[i].size, &s->dyncols[i].prec);
2895#ifdef SQL_LONGVARCHAR
2896 if (s->dyncols[i].type == SQL_VARCHAR &&
2897 s->dyncols[i].size > 255) {
2898 s->dyncols[i].type = SQL_LONGVARCHAR;
2899 }
2900#endif
2901#ifdef WINTERFACE
2902#ifdef SQL_WLONGVARCHAR
2903 if (s->dyncols[i].type == SQL_WVARCHAR &&
2904 s->dyncols[i].size > 255) {
2905 s->dyncols[i].type = SQL_WLONGVARCHAR;
2906 }
2907#endif
2908#endif
2909 if (s->dyncols[i].type == SQL_VARBINARY &&
2910 s->dyncols[i].size > 255) {
2911 s->dyncols[i].type = SQL_LONGVARBINARY;
2912 }
2913 }
2914#ifndef FULL_METADATA
2915 if (s->dcols > array_size(flags)) {
2916 flagp = xmalloc(sizeof (flags[0]) * s->dcols);
2917 if (flagp == NULL) {
2918 return;
2919 }
2920 } else {
2921 flagp = flags;
2922 }
2923 memset(flagp, 0, sizeof (flags[0]) * s->dcols);
2924 for (i = 0; i < s->dcols; i++) {
2925 s->dyncols[i].autoinc = SQL_FALSE;
2926 s->dyncols[i].notnull = SQL_NULLABLE;
2927 }
2928 for (i = 0; i < s->dcols; i++) {
2929 int ret, lastpk = -1, autoinccount = 0;
2930 char *sql;
2931
2932 if (!s->dyncols[i].table[0]) {
2933 continue;
2934 }
2935 if (flagp[i]) {
2936 continue;
2937 }
2938 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", s->dyncols[i].table);
2939 if (!sql) {
2940 continue;
2941 }
2942 dbtraceapi(d, "sqlite3_get_table", sql);
2943 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, NULL);
2944 sqlite3_free(sql);
2945 if (ret != SQLITE_OK) {
2946 continue;
2947 }
2948 k = findcol(rowp, ncols, "name");
2949 t = findcol(rowp, ncols, "type");
2950 pk = findcol(rowp, ncols, "pk");
2951 nn = findcol(rowp, ncols, "notnull");
2952 if (k < 0 || t < 0) {
2953 goto freet;
2954 }
2955 for (r = 1; r <= nrows; r++) {
2956 int m;
2957
2958 for (m = i; m < s->dcols; m++) {
2959 char *colname = s->dyncols[m].column;
2960
2961 if (s->longnames) {
2962 char *dotp = strchr(colname, '.');
2963
2964 if (dotp) {
2965 colname = dotp + 1;
2966 }
2967 }
2968 if (!flagp[m] &&
2969 strcmp(colname, rowp[r * ncols + k]) == 0 &&
2970 strcmp(s->dyncols[m].table, s->dyncols[i].table) == 0) {
2971 char *typename = rowp[r * ncols + t];
2972
2973 flagp[m] = i + 1;
2974 freep(&s->dyncols[m].typename);
2975 s->dyncols[m].typename = xstrdup(typename);
2976 s->dyncols[m].type =
2977 mapsqltype(typename, &s->dyncols[m].nosign, *s->ov3,
2978 s->nowchar[0] || s->nowchar[1],
2979 s->dobigint);
2980 getmd(typename, s->dyncols[m].type, &s->dyncols[m].size,
2981 &s->dyncols[m].prec);
2982#ifdef SQL_LONGVARCHAR
2983 if (s->dyncols[m].type == SQL_VARCHAR &&
2984 s->dyncols[m].size > 255) {
2985 s->dyncols[m].type = SQL_LONGVARCHAR;
2986 }
2987#endif
2988#ifdef WINTERFACE
2989#ifdef SQL_WLONGVARCHAR
2990 if (s->dyncols[i].type == SQL_WVARCHAR &&
2991 s->dyncols[i].size > 255) {
2992 s->dyncols[i].type = SQL_WLONGVARCHAR;
2993 }
2994#endif
2995#endif
2996 if (s->dyncols[i].type == SQL_VARBINARY &&
2997 s->dyncols[i].size > 255) {
2998 s->dyncols[i].type = SQL_LONGVARBINARY;
2999 }
3000 if (pk >= 0 && strcmp(rowp[r * ncols + pk], "1") == 0) {
3001 s->dyncols[m].ispk = 1;
3002 if (++autoinccount > 1) {
3003 if (lastpk >= 0) {
3004 s->dyncols[lastpk].autoinc = SQL_FALSE;
3005 lastpk = -1;
3006 }
3007 } else {
3008 lastpk = m;
3009 if (strlen(typename) == 7 &&
3010 strncasecmp(typename, "integer", 7) == 0) {
3011 s->dyncols[m].autoinc = SQL_TRUE;
3012 }
3013 }
3014 } else {
3015 s->dyncols[m].ispk = 0;
3016 }
3017 if (nn >= 0 && rowp[r * ncols + nn][0] != '0') {
3018 s->dyncols[m].notnull = SQL_NO_NULLS;
3019 }
3020 }
3021 }
3022 }
3023freet:
3024 sqlite3_free_table(rowp);
3025 }
3026 for (i = k = 0; i < s->dcols; i++) {
3027 if (flagp[i] == 0) {
3028 break;
3029 }
3030 if (k == 0) {
3031 k = flagp[i];
3032 } else if (flagp[i] != k) {
3033 k = 0;
3034 break;
3035 }
3036 }
3037 s->one_tbl = k ? 1 : 0;
3038 k = 0;
3039 if (s->one_tbl) {
3040 for (i = 0; i < s->dcols; i++) {
3041 if (s->dyncols[i].ispk > 0) {
3042 ++k;
3043 }
3044 }
3045 }
3046 s->has_pk = k;
3047 if (flagp != flags) {
3048 freep(&flagp);
3049 }
3050#else
3051 for (i = 1, k = 0; i < s->dcols; i++) {
3052 if (strcmp(s->dyncols[i].table, s->dyncols[0].table) == 0) {
3053 k++;
3054 }
3055 }
3056 s->one_tbl = (k && k + 1 == s->dcols) ? 1 : 0;
3057 k = 0;
3058 if (s->one_tbl) {
3059 for (i = 0; i < s->dcols; i++) {
3060 if (s->dyncols[i].ispk > 0) {
3061 ++k;
3062 if (s->has_rowid < 0 && s->dyncols[i].isrowid > 0) {
3063 s->has_rowid = i;
3064 }
3065 }
3066 }
3067 }
3068 s->has_pk = k;
3069#endif
3070}
3071
3078static void
3079convJD2YMD(double jd, DATE_STRUCT *ds)
3080{
3081 int z, a, b, c, d, e, x1;
3082 sqlite_int64 ijd;
3083
3084 ijd = jd * 86400000.0 + 0.5;
3085 z = (int) ((ijd + 43200000) / 86400000);
3086 a = (int) ((z - 1867216.25) / 36524.25);
3087 a = z + 1 + a - (a / 4);
3088 b = a + 1524;
3089 c = (int) ((b - 122.1) / 365.25);
3090 d = (36525 * c) / 100;
3091 e = (int) ((b - d) / 30.6001);
3092 x1 = (int) (30.6001 * e);
3093 ds->day = b - d - x1;
3094 ds->month = (e < 14) ? (e - 1) : (e - 13);
3095 ds->year = (ds->month > 2) ? (c - 4716) : (c - 4715);
3096}
3097
3098
3106static void
3107convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
3108{
3109 int s;
3110 double ds;
3111 sqlite_int64 ijd;
3112
3113 ijd = jd * 86400000.0 + 0.5;
3114 s = (int)((ijd + 43200000) % 86400000);
3115 ds = s / 1000.0;
3116 if (fp) {
3117 *fp = (s % 1000) * 1000000;
3118 }
3119 s = (int) ds;
3120 ds -= s;
3121 ts->hour = s / 3600;
3122 s -= ts->hour * 3600;
3123 ts->minute = s / 60;
3124 ds += s - ts->minute *60;
3125 ts->second = (int) ds;
3126}
3127
3135static int
3136getmdays(int year, int month)
3137{
3138 static const int mdays[] = {
3139 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
3140 };
3141 int mday;
3142
3143 if (month < 1) {
3144 return 0;
3145 }
3146 mday = mdays[(month - 1) % 12];
3147 if (mday == 28 && year % 4 == 0 &&
3148 (!(year % 100 == 0) || year % 400 == 0)) {
3149 mday++;
3150 }
3151 return mday;
3152}
3153
3169static int
3170str2date(int jdconv, char *str, DATE_STRUCT *ds)
3171{
3172 int i, err = 0;
3173 double jd;
3174 char *p, *q, sepc = '\0';
3175
3176 ds->year = ds->month = ds->day = 0;
3177 if (jdconv) {
3178 p = strchr(str, '.');
3179 if (p) {
3180 /* julian day format */
3181 p = 0;
3182 jd = ln_strtod(str, &p);
3183 if (p && p > str) {
3184 convJD2YMD(jd, ds);
3185 return 0;
3186 }
3187 }
3188 }
3189 p = str;
3190 while (*p && !ISDIGIT(*p)) {
3191 ++p;
3192 }
3193 q = p;
3194 i = 0;
3195 while (*q && !ISDIGIT(*q)) {
3196 ++i;
3197 ++q;
3198 }
3199 if (i >= 8) {
3200 char buf[8];
3201
3202 strncpy(buf, p + 0, 4); buf[4] = '\0';
3203 ds->year = strtol(buf, NULL, 10);
3204 strncpy(buf, p + 4, 2); buf[2] = '\0';
3205 ds->month = strtol(buf, NULL, 10);
3206 strncpy(buf, p + 6, 2); buf[2] = '\0';
3207 ds->day = strtol(buf, NULL, 10);
3208 goto done;
3209 }
3210 i = 0;
3211 while (i < 3) {
3212 int n;
3213
3214 q = NULL;
3215 n = strtol(p, &q, 10);
3216 if (!q || q == p) {
3217 if (*q == '\0') {
3218 if (i == 0) {
3219 err = 1;
3220 }
3221 goto done;
3222 }
3223 }
3224 if (!sepc) {
3225 sepc = *q;
3226 }
3227 if (*q == '-' || *q == '/' || *q == '\0' || i == 2) {
3228 switch (i) {
3229 case 0: ds->year = n; break;
3230 case 1: ds->month = n; break;
3231 case 2: ds->day = n; break;
3232 }
3233 ++i;
3234 if (*q) {
3235 ++q;
3236 }
3237 } else {
3238 i = 0;
3239 while (*q && !ISDIGIT(*q)) {
3240 ++q;
3241 }
3242 }
3243 p = q;
3244 }
3245done:
3246 /* final check for overflow */
3247 if (err ||
3248 ds->month < 1 || ds->month > 12 ||
3249 ds->day < 1 || ds->day > getmdays(ds->year, ds->month)) {
3250 if (sepc == '/') {
3251 /* Try MM/DD/YYYY format */
3252 int t[3];
3253
3254 t[0] = ds->year;
3255 t[1] = ds->month;
3256 t[2] = ds->day;
3257 ds->year = t[2];
3258 ds->day = t[1];
3259 ds->month = t[0];
3260 if (ds->month >= 1 && ds->month <= 12 &&
3261 (ds->day >= 1 || ds->day <= getmdays(ds->year, ds->month))) {
3262 return 0;
3263 }
3264 }
3265 return -1;
3266 }
3267 return 0;
3268}
3269
3284static int
3285str2time(int jdconv, char *str, TIME_STRUCT *ts)
3286{
3287 int i, err = 0, ampm = -1;
3288 double jd;
3289 char *p, *q;
3290
3291 ts->hour = ts->minute = ts->second = 0;
3292 if (jdconv) {
3293 p = strchr(str, '.');
3294 if (p) {
3295 /* julian day format */
3296 p = 0;
3297 jd = ln_strtod(str, &p);
3298 if (p && p > str) {
3299 convJD2HMS(jd, ts, 0);
3300 return 0;
3301 }
3302 }
3303 }
3304 p = str;
3305 while (*p && !ISDIGIT(*p)) {
3306 ++p;
3307 }
3308 q = p;
3309 i = 0;
3310 while (*q && ISDIGIT(*q)) {
3311 ++i;
3312 ++q;
3313 }
3314 if (i >= 6) {
3315 char buf[4];
3316
3317 strncpy(buf, p + 0, 2); buf[2] = '\0';
3318 ts->hour = strtol(buf, NULL, 10);
3319 strncpy(buf, p + 2, 2); buf[2] = '\0';
3320 ts->minute = strtol(buf, NULL, 10);
3321 strncpy(buf, p + 4, 2); buf[2] = '\0';
3322 ts->second = strtol(buf, NULL, 10);
3323 goto done;
3324 }
3325 i = 0;
3326 while (i < 3) {
3327 int n;
3328
3329 q = NULL;
3330 n = strtol(p, &q, 10);
3331 if (!q || q == p) {
3332 if (*q == '\0') {
3333 if (i == 0) {
3334 err = 1;
3335 }
3336 goto done;
3337 }
3338 }
3339 if (*q == ':' || *q == '\0' || i == 2) {
3340 switch (i) {
3341 case 0: ts->hour = n; break;
3342 case 1: ts->minute = n; break;
3343 case 2: ts->second = n; break;
3344 }
3345 ++i;
3346 if (*q) {
3347 ++q;
3348 }
3349 } else {
3350 i = 0;
3351 while (*q && !ISDIGIT(*q)) {
3352 ++q;
3353 }
3354 }
3355 p = q;
3356 }
3357 if (!err) {
3358 while (*p) {
3359 if ((p[0] == 'p' || p[0] == 'P') &&
3360 (p[1] == 'm' || p[1] == 'M')) {
3361 ampm = 1;
3362 } else if ((p[0] == 'a' || p[0] == 'A') &&
3363 (p[1] == 'm' || p[1] == 'M')) {
3364 ampm = 0;
3365 }
3366 ++p;
3367 }
3368 if (ampm > 0) {
3369 if (ts->hour < 12) {
3370 ts->hour += 12;
3371 }
3372 } else if (ampm == 0) {
3373 if (ts->hour == 12) {
3374 ts->hour = 0;
3375 }
3376 }
3377 }
3378done:
3379 /* final check for overflow */
3380 if (err || ts->hour > 23 || ts->minute > 59 || ts->second > 59) {
3381 return -1;
3382 }
3383 return 0;
3384}
3385
3405static int
3406str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
3407{
3408 int i, m, n, err = 0, ampm = -1;
3409 double jd;
3410 char *p, *q, in = '\0', sepc = '\0';
3411
3412 tss->year = tss->month = tss->day = 0;
3413 tss->hour = tss->minute = tss->second = 0;
3414 tss->fraction = 0;
3415 if (jdconv) {
3416 p = strchr(str, '.');
3417 if (p) {
3418 q = strchr(str, '-');
3419 if (q == str) {
3420 q = 0;
3421 }
3422 if (!q) {
3423 q = strchr(str, '/');
3424 if (!q) {
3425 q = strchr(str, ':');
3426 }
3427 }
3428 if (!q || q > p) {
3429 /* julian day format */
3430 p = 0;
3431 jd = ln_strtod(str, &p);
3432 if (p && p > str) {
3433 DATE_STRUCT ds;
3434 TIME_STRUCT ts;
3435
3436 convJD2YMD(jd, &ds);
3437 convJD2HMS(jd, &ts, &n);
3438 tss->year = ds.year;
3439 tss->month = ds.month;
3440 tss->day = ds.day;
3441 tss->hour = ts.hour;
3442 tss->minute = ts.minute;
3443 tss->second = ts.second;
3444 tss->fraction = n;
3445 return 0;
3446 }
3447 }
3448 }
3449 }
3450 p = str;
3451 while (*p && !ISDIGIT(*p)) {
3452 ++p;
3453 }
3454 q = p;
3455 i = 0;
3456 while (*q && ISDIGIT(*q)) {
3457 ++i;
3458 ++q;
3459 }
3460 if (i >= 14) {
3461 char buf[16];
3462
3463 strncpy(buf, p + 0, 4); buf[4] = '\0';
3464 tss->year = strtol(buf, NULL, 10);
3465 strncpy(buf, p + 4, 2); buf[2] = '\0';
3466 tss->month = strtol(buf, NULL, 10);
3467 strncpy(buf, p + 6, 2); buf[2] = '\0';
3468 tss->day = strtol(buf, NULL, 10);
3469 strncpy(buf, p + 8, 2); buf[2] = '\0';
3470 tss->hour = strtol(buf, NULL, 10);
3471 strncpy(buf, p + 10, 2); buf[2] = '\0';
3472 tss->minute = strtol(buf, NULL, 10);
3473 strncpy(buf, p + 12, 2); buf[2] = '\0';
3474 tss->second = strtol(buf, NULL, 10);
3475 if (i > 14) {
3476 m = i - 14;
3477 strncpy(buf, p + 14, m);
3478 while (m < 9) {
3479 buf[m] = '0';
3480 ++m;
3481 }
3482 buf[m] = '\0';
3483 tss->fraction = strtol(buf, NULL, 10);
3484 }
3485 m = 7;
3486 goto done;
3487 }
3488 m = i = 0;
3489 while ((m & 7) != 7) {
3490 q = NULL;
3491 n = strtol(p, &q, 10);
3492 if (!q || q == p) {
3493 if (*q == '\0') {
3494 if (m < 1) {
3495 err = 1;
3496 }
3497 goto done;
3498 }
3499 }
3500 if (in == '\0') {
3501 switch (*q) {
3502 case '-':
3503 case '/':
3504 if ((m & 1) == 0) {
3505 in = *q;
3506 i = 0;
3507 }
3508 break;
3509 case ':':
3510 if ((m & 2) == 0) {
3511 in = *q;
3512 i = 0;
3513 }
3514 break;
3515 case ' ':
3516 case '.':
3517 break;
3518 default:
3519 in = '\0';
3520 i = 0;
3521 break;
3522 }
3523 }
3524 switch (in) {
3525 case '-':
3526 case '/':
3527 if (!sepc) {
3528 sepc = in;
3529 }
3530 switch (i) {
3531 case 0: tss->year = n; break;
3532 case 1: tss->month = n; break;
3533 case 2: tss->day = n; break;
3534 }
3535 if (++i >= 3) {
3536 i = 0;
3537 m |= 1;
3538 if (!(m & 2)) {
3539 m |= 8;
3540 }
3541 goto skip;
3542 } else {
3543 ++q;
3544 }
3545 break;
3546 case ':':
3547 switch (i) {
3548 case 0: tss->hour = n; break;
3549 case 1: tss->minute = n; break;
3550 case 2: tss->second = n; break;
3551 }
3552 if (++i >= 3) {
3553 i = 0;
3554 m |= 2;
3555 if (*q == '.') {
3556 in = '.';
3557 goto skip2;
3558 }
3559 if (*q == ' ') {
3560 if ((m & 1) == 0) {
3561 char *e = NULL;
3562
3563 (void) strtol(q + 1, &e, 10);
3564 if (e && *e == '-') {
3565 goto skip;
3566 }
3567 }
3568 in = '.';
3569 goto skip2;
3570 }
3571 goto skip;
3572 } else {
3573 ++q;
3574 }
3575 break;
3576 case '.':
3577 if (++i >= 1) {
3578 int ndig = q - p;
3579
3580 if (p[0] == '+' || p[0] == '-') {
3581 ndig--;
3582 }
3583 while (ndig < 9) {
3584 n = n * 10;
3585 ++ndig;
3586 }
3587 tss->fraction = n;
3588 m |= 4;
3589 i = 0;
3590 }
3591 default:
3592 skip:
3593 in = '\0';
3594 skip2:
3595 while (*q && !ISDIGIT(*q)) {
3596 if ((q[0] == 'a' || q[0] == 'A') &&
3597 (q[1] == 'm' || q[1] == 'M')) {
3598 ampm = 0;
3599 ++q;
3600 } else if ((q[0] == 'p' || q[0] == 'P') &&
3601 (q[1] == 'm' || q[1] == 'M')) {
3602 ampm = 1;
3603 ++q;
3604 }
3605 ++q;
3606 }
3607 }
3608 p = q;
3609 }
3610 if ((m & 7) > 1 && (m & 8)) {
3611 /* ISO8601 timezone */
3612 if (p > str && ISDIGIT(*p)) {
3613 int nn, sign;
3614
3615 q = p - 1;
3616 if (*q != '+' && *q != '-') {
3617 goto done;
3618 }
3619 sign = (*q == '+') ? -1 : 1;
3620 q = NULL;
3621 n = strtol(p, &q, 10);
3622 if (!q || *q++ != ':' || !ISDIGIT(*q)) {
3623 goto done;
3624 }
3625 p = q;
3626 q = NULL;
3627 nn = strtol(p, &q, 10);
3628 tss->minute += nn * sign;
3629 if ((SQLSMALLINT) tss->minute < 0) {
3630 tss->hour -= 1;
3631 tss->minute += 60;
3632 } else if (tss->minute >= 60) {
3633 tss->hour += 1;
3634 tss->minute -= 60;
3635 }
3636 tss->hour += n * sign;
3637 if ((SQLSMALLINT) tss->hour < 0) {
3638 tss->day -= 1;
3639 tss->hour += 24;
3640 } else if (tss->hour >= 24) {
3641 tss->day += 1;
3642 tss->hour -= 24;
3643 }
3644 if ((short) tss->day < 1 || tss->day >= 28) {
3645 int mday, pday, pmon;
3646
3647 mday = getmdays(tss->year, tss->month);
3648 pmon = tss->month - 1;
3649 if (pmon < 1) {
3650 pmon = 12;
3651 }
3652 pday = getmdays(tss->year, pmon);
3653 if ((SQLSMALLINT) tss->day < 1) {
3654 tss->month -= 1;
3655 tss->day = pday;
3656 } else if (tss->day > mday) {
3657 tss->month += 1;
3658 tss->day = 1;
3659 }
3660 if ((SQLSMALLINT) tss->month < 1) {
3661 tss->year -= 1;
3662 tss->month = 12;
3663 } else if (tss->month > 12) {
3664 tss->year += 1;
3665 tss->month = 1;
3666 }
3667 }
3668 }
3669 }
3670done:
3671 if ((m & 1) &&
3672 (tss->month < 1 || tss->month > 12 ||
3673 tss->day < 1 || tss->day > getmdays(tss->year, tss->month))) {
3674 if (sepc == '/') {
3675 /* Try MM/DD/YYYY format */
3676 int t[3];
3677
3678 t[0] = tss->year;
3679 t[1] = tss->month;
3680 t[2] = tss->day;
3681 tss->year = t[2];
3682 tss->day = t[1];
3683 tss->month = t[0];
3684 }
3685 }
3686 /* Replace missing year/month/day with current date */
3687 if (!err && (m & 1) == 0) {
3688#ifdef _WIN32
3689 SYSTEMTIME t;
3690
3691 GetLocalTime(&t);
3692 tss->year = t.wYear;
3693 tss->month = t.wMonth;
3694 tss->day = t.wDay;
3695#else
3696 struct timeval tv;
3697 struct tm tm;
3698
3699 gettimeofday(&tv, NULL);
3700 tm = *localtime(&tv.tv_sec);
3701 tss->year = tm.tm_year + 1900;
3702 tss->month = tm.tm_mon + 1;
3703 tss->day = tm.tm_mday;
3704#endif
3705 }
3706 /* Normalize fraction */
3707 if (tss->fraction < 0) {
3708 tss->fraction = 0;
3709 }
3710 /* Final check for overflow */
3711 if (err ||
3712 tss->month < 1 || tss->month > 12 ||
3713 tss->day < 1 || tss->day > getmdays(tss->year, tss->month) ||
3714 tss->hour > 23 || tss->minute > 59 || tss->second > 59) {
3715 return -1;
3716 }
3717 if ((m & 7) > 1) {
3718 if (ampm > 0) {
3719 if (tss->hour < 12) {
3720 tss->hour += 12;
3721 }
3722 } else if (ampm == 0) {
3723 if (tss->hour == 12) {
3724 tss->hour = 0;
3725 }
3726 }
3727 }
3728 return ((m & 7) < 1) ? -1 : 0;
3729}
3730
3737static int
3738getbool(char *string)
3739{
3740 if (string) {
3741 return string[0] && strchr("Yy123456789Tt", string[0]) != NULL;
3742 }
3743 return 0;
3744}
3745
3753static void
3754blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
3755{
3756#if 0
3757 DBC *d = (DBC *) sqlite3_user_data(ctx);
3758#endif
3759 char *filename = 0;
3760
3761 if (nargs > 0) {
3762 if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
3763 filename = (char *) sqlite3_value_text(args[0]);
3764 }
3765 }
3766 if (filename) {
3767#ifdef _WIN32
3768 char *wname = utf_to_wmb(filename, -1);
3769 FILE *f;
3770#else
3771 FILE *f = fopen(filename, "r");
3772#endif
3773 char *p;
3774 long n, nn;
3775
3776#ifdef _WIN32
3777 if (wname) {
3778 f = fopen(wname, "rb");
3779 } else {
3780 sqlite3_result_error(ctx, "out of memory", -1);
3781 return;
3782 }
3783 uc_free(wname);
3784#endif
3785 if (f) {
3786 if (fseek(f, 0, SEEK_END) == 0) {
3787 n = ftell(f);
3788 if (fseek(f, 0, SEEK_SET) == 0) {
3789 p = sqlite3_malloc(n);
3790 if (p) {
3791 nn = fread(p, 1, n, f);
3792 if (nn != n) {
3793 sqlite3_result_error(ctx, "read error", -1);
3794 sqlite3_free(p);
3795 } else {
3796 sqlite3_result_blob(ctx, p, n, sqlite3_free);
3797 }
3798 } else {
3799 sqlite3_result_error(ctx, "out of memory", -1);
3800 }
3801 } else {
3802 sqlite3_result_error(ctx, "seek error", -1);
3803 }
3804 } else {
3805 sqlite3_result_error(ctx, "seek error", -1);
3806 }
3807 fclose(f);
3808 } else {
3809 sqlite3_result_error(ctx, "cannot open file", -1);
3810 }
3811 } else {
3812 sqlite3_result_error(ctx, "no filename given", -1);
3813 }
3814}
3815
3823static void
3824blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
3825{
3826#if 0
3827 DBC *d = (DBC *) sqlite3_user_data(ctx);
3828#endif
3829 char *filename = 0;
3830 char *p = 0;
3831 int n = 0;
3832
3833 if (nargs > 0) {
3834 p = (char *) sqlite3_value_blob(args[0]);
3835 n = sqlite3_value_bytes(args[0]);
3836 }
3837 if (nargs > 1) {
3838 if (sqlite3_value_type(args[1]) != SQLITE_NULL) {
3839 filename = (char *) sqlite3_value_text(args[1]);
3840 }
3841 }
3842 if (p) {
3843 if (filename) {
3844#ifdef _WIN32
3845 char *wname = utf_to_wmb(filename, -1);
3846 FILE *f;
3847#else
3848 FILE *f = fopen(filename, "w");
3849#endif
3850 int nn;
3851
3852#ifdef _WIN32
3853 if (wname) {
3854 f = fopen(wname, "wb");
3855 } else {
3856 sqlite3_result_error(ctx, "out of memory", -1);
3857 return;
3858 }
3859 uc_free(wname);
3860#endif
3861 if (f) {
3862 nn = fwrite(p, 1, n, f);
3863 fclose(f);
3864 if (nn != n) {
3865 sqlite3_result_error(ctx, "write error", -1);
3866 } else {
3867 sqlite3_result_int(ctx, nn);
3868 }
3869 } else {
3870 sqlite3_result_error(ctx, "cannot open file", -1);
3871 }
3872 } else {
3873 sqlite3_result_error(ctx, "no filename given", -1);
3874 }
3875 } else {
3876 sqlite3_result_null(ctx);
3877 }
3878}
3879
3887static void
3888#if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3889dbtrace(void *arg, const char *msg, sqlite_uint64 et)
3890#else
3891dbtrace(void *arg, const char *msg)
3892#endif
3893{
3894 DBC *d = (DBC *) arg;
3895
3896 if (msg && d->trace) {
3897 int len = strlen(msg);
3898#if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3899 unsigned long s, f;
3900#endif
3901
3902 if (len > 0) {
3903 char *end = "\n";
3904
3905 if (msg[len - 1] != ';') {
3906 end = ";\n";
3907 }
3908 fprintf(d->trace, "%s%s", msg, end);
3909#if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3910 s = et / 1000000000LL;
3911 f = et % 1000000000LL;
3912 fprintf(d->trace, "-- took %lu.%09lu seconds\n", s, f);
3913#endif
3914 fflush(d->trace);
3915 }
3916 }
3917}
3918
3926static void
3927dbtraceapi(DBC *d, char *fn, const char *sql)
3928{
3929 if (fn && d->trace) {
3930 if (sql) {
3931 fprintf(d->trace, "-- %s: %s\n", fn, sql);
3932 } else {
3933 fprintf(d->trace, "-- %s\n", fn);
3934 }
3935 fflush(d->trace);
3936 }
3937}
3938
3946static void
3947dbtracerc(DBC *d, int rc, char *err)
3948{
3949 if (rc != SQLITE_OK && d->trace) {
3950 fprintf(d->trace, "-- SQLITE ERROR CODE %d", rc);
3951 fprintf(d->trace, err ? ": %s\n" : "\n", err);
3952 fflush(d->trace);
3953 }
3954}
3955
3970static SQLRETURN
3971dbopen(DBC *d, char *name, int isu, char *dsn, char *sflag,
3972 char *spflag, char *ntflag, char *jmode, char *busy)
3973{
3974 char *endp = NULL;
3975 int rc, tmp, busyto = 100000;
3976#if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
3977 int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
3978 char *uname = name;
3979 const char *vfs_name = NULL;
3980#endif
3981
3982 if (d->sqlite) {
3983 if (d->trace) {
3984 fprintf(d->trace, "-- sqlite3_close (deferred): '%s'\n",
3985 d->dbname);
3986 fflush(d->trace);
3987 }
3988#if defined(HAVE_SQLITE3CLOSEV2) && (HAVE_SQLITE3CLOSEV2)
3989 sqlite3_close_v2(d->sqlite);
3990#else
3991 sqlite3_close(d->sqlite);
3992#endif
3993 d->sqlite = NULL;
3994 }
3995#if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
3996 if (d->nocreat) {
3997 flags &= ~ SQLITE_OPEN_CREATE;
3998 }
3999#if defined(_WIN32) || defined(_WIN64)
4000 if (!isu) {
4001 char expname[SQL_MAX_MESSAGE_LENGTH * 2];
4002
4003 expname[0] = '\0';
4004 rc = ExpandEnvironmentStrings(name, expname, sizeof (expname));
4005 if (rc <= sizeof (expname)) {
4006 uname = wmb_to_utf(expname, rc - 1);
4007 } else {
4008 uname = wmb_to_utf(name, -1);
4009 }
4010 if (!uname) {
4011 rc = SQLITE_NOMEM;
4012 setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
4013 return SQL_ERROR;
4014 }
4015 }
4016#endif
4017#if defined(ENABLE_NVFS) && (ENABLE_NVFS)
4018 vfs_name = nvfs_makevfs(uname);
4019#endif
4020#ifdef SQLITE_OPEN_URI
4021 flags |= SQLITE_OPEN_URI;
4022#endif
4023 rc = sqlite3_open_v2(uname, &d->sqlite, flags, vfs_name);
4024#if defined(WINTERFACE) || defined(_WIN32) || defined(_WIN64)
4025 if (uname != name) {
4026 uc_free(uname);
4027 }
4028#endif
4029#else
4030#if defined(_WIN32) || defined(_WIN64)
4031 if (d->nocreat) {
4032 char *cname = NULL;
4033
4034 if (isu) {
4035 cname = utf_to_wmb(name, -1);
4036 }
4037 if (GetFileAttributesA(cname ? cname : name) ==
4038 INVALID_FILE_ATTRIBUTES) {
4039 uc_free(cname);
4040 rc = SQLITE_CANTOPEN;
4041 setstatd(d, rc, "cannot open database",
4042 (*d->ov3) ? "HY000" : "S1000");
4043 return SQL_ERROR;
4044 }
4045 uc_free(cname);
4046 }
4047#else
4048 if (d->nocreat && access(name, 004) < 0) {
4049 rc = SQLITE_CANTOPEN;
4050 setstatd(d, rc, "cannot open database", (*d->ov3) ? "HY000" : "S1000");
4051 return SQL_ERROR;
4052 }
4053#endif
4054#if defined(_WIN32) || defined(_WIN64)
4055 if (!isu) {
4056 WCHAR *wname = wmb_to_uc(name, -1);
4057
4058 if (!wname) {
4059 rc = SQLITE_NOMEM;
4060 setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
4061 return SQL_ERROR;
4062 }
4063 rc = sqlite3_open16(wname, &d->sqlite);
4064 uc_free(wname);
4065 } else
4066#endif
4067 rc = sqlite3_open(name, &d->sqlite);
4068#endif /* !HAVE_SQLITE3VFS */
4069 if (rc != SQLITE_OK) {
4070connfail:
4071 setstatd(d, rc, "connect failed", (*d->ov3) ? "HY000" : "S1000");
4072 if (d->sqlite) {
4073 sqlite3_close(d->sqlite);
4074 d->sqlite = NULL;
4075 }
4076 return SQL_ERROR;
4077 }
4078#if defined(SQLITE_DYNLOAD) || defined(SQLITE_HAS_CODEC)
4079 if (d->pwd) {
4080 sqlite3_key(d->sqlite, d->pwd, d->pwdLen);
4081 }
4082#endif
4083 d->pwd = NULL;
4084 d->pwdLen = 0;
4085 if (d->trace) {
4086#if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
4087 sqlite3_profile(d->sqlite, dbtrace, d);
4088#else
4089 sqlite3_trace(d->sqlite, dbtrace, d);
4090#endif
4091 }
4092 d->step_enable = getbool(sflag);
4093 d->trans_disable = getbool(ntflag);
4094 d->curtype = d->step_enable ?
4095 SQL_CURSOR_FORWARD_ONLY : SQL_CURSOR_STATIC;
4096 tmp = strtol(busy, &endp, 0);
4097 if (endp && *endp == '\0' && endp != busy) {
4098 busyto = tmp;
4099 }
4100 if (busyto < 1 || busyto > 1000000) {
4101 busyto = 1000000;
4102 }
4103 d->timeout = busyto;
4104 freep(&d->dbname);
4105 d->dbname = xstrdup(name);
4106 freep(&d->dsn);
4107 d->dsn = xstrdup(dsn);
4108 if ((rc = setsqliteopts(d->sqlite, d)) != SQLITE_OK) {
4109 if (d->trace) {
4110 fprintf(d->trace, "-- sqlite3_close: '%s'\n",
4111 d->dbname);
4112 fflush(d->trace);
4113 }
4114 sqlite3_close(d->sqlite);
4115 d->sqlite = NULL;
4116 goto connfail;
4117 }
4118 if (!spflag || spflag[0] == '\0') {
4119 spflag = "NORMAL";
4120 }
4121 if (spflag[0] != '\0') {
4122 char syncp[128];
4123
4124 sprintf(syncp, "PRAGMA synchronous = %8.8s;", spflag);
4125 sqlite3_exec(d->sqlite, syncp, NULL, NULL, NULL);
4126 }
4127 if (jmode[0] != '\0') {
4128 char jourp[128];
4129
4130 sprintf(jourp, "PRAGMA journal_mode = %16.16s;", jmode);
4131 sqlite3_exec(d->sqlite, jourp, NULL, NULL, NULL);
4132 }
4133 if (d->trace) {
4134 fprintf(d->trace, "-- sqlite3_open: '%s'\n", d->dbname);
4135 fflush(d->trace);
4136 }
4137#if defined(_WIN32) || defined(_WIN64)
4138 {
4139 char pname[MAX_PATH];
4140 HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
4141 FALSE, GetCurrentProcessId());
4142
4143 pname[0] = '\0';
4144 if (h) {
4145 HMODULE m = NULL, l = LoadLibrary("psapi.dll");
4146 DWORD need;
4147 typedef BOOL (WINAPI *epmfunc)(HANDLE, HMODULE *, DWORD, LPDWORD);
4148 typedef BOOL (WINAPI *gmbfunc)(HANDLE, HMODULE, LPSTR, DWORD);
4149 epmfunc epm;
4150 gmbfunc gmb;
4151
4152 if (l) {
4153 epm = (epmfunc) GetProcAddress(l, "EnumProcessModules");
4154 gmb = (gmbfunc) GetProcAddress(l, "GetModuleBaseNameA");
4155 if (epm && gmb && epm(h, &m, sizeof (m), &need)) {
4156 gmb(h, m, pname, sizeof (pname));
4157 }
4158 FreeLibrary(l);
4159 }
4160 CloseHandle(h);
4161 }
4162 d->xcelqrx = strncasecmp(pname, "EXCEL", 5) == 0 ||
4163 strncasecmp(pname, "MSQRY", 5) == 0;
4164 if (d->trace && d->xcelqrx) {
4165
4166 fprintf(d->trace, "-- enabled EXCEL quirks\n");
4167 fflush(d->trace);
4168 }
4169 }
4170#endif
4171 sqlite3_create_function(d->sqlite, "blob_import", 1, SQLITE_UTF8,
4172 d, blob_import, 0, 0);
4173 sqlite3_create_function(d->sqlite, "blob_export", 2, SQLITE_UTF8,
4174 d, blob_export, 0, 0);
4175 return SQL_SUCCESS;
4176}
4177
4184static void
4185dbloadext(DBC *d, char *exts)
4186{
4187#if defined(HAVE_SQLITE3LOADEXTENSION) && (HAVE_SQLITE3LOADEXTENSION)
4188 char *p;
4189 char path[SQL_MAX_MESSAGE_LENGTH];
4190 int plen = 0;
4191
4192 if (!d->sqlite) {
4193 return;
4194 }
4195 sqlite3_enable_load_extension(d->sqlite, 1);
4196#if defined(_WIN32) || defined(_WIN64)
4197 GetModuleFileName(hModule, path, sizeof (path));
4198 p = strrchr(path, '\\');
4199 plen = p ? ((p + 1) - path) : 0;
4200#endif
4201 do {
4202 p = strchr(exts, ',');
4203 if (p) {
4204 strncpy(path + plen, exts, p - exts);
4205 path[plen + (p - exts)] = '\0';
4206 } else {
4207 strcpy(path + plen, exts);
4208 }
4209 if (exts[0]) {
4210 char *errmsg = NULL;
4211 int rc;
4212#if defined(_WIN32) || defined(_WIN64)
4213 int i;
4214 char *q;
4215
4216 q = path + plen;
4217 if (!(q[0] &&
4218 ((q[1] == ':' && (q[2] == '\\' || q[2] == '/')) ||
4219 q[0] == '\\' || q[0] == '/' || q[0] == '.'))) {
4220 q = path;
4221 }
4222 /* sqlite3_load_extension() dislikes backslashes */
4223 for (i = 0; q[i] != '\0'; i++) {
4224 if (q[i] == '\\') {
4225 q[i] = '/';
4226 }
4227 }
4228 rc = sqlite3_load_extension(d->sqlite, q, 0, &errmsg);
4229#else
4230 rc = sqlite3_load_extension(d->sqlite, path, 0, &errmsg);
4231#endif
4232 if (rc != SQLITE_OK) {
4233#if defined(_WIN32) || defined(_WIN64)
4234 char buf[512], msg[512];
4235
4236 LoadString(hModule, IDS_EXTERR, buf, sizeof (buf));
4237 wsprintf(msg, buf, q, errmsg ?
4238 errmsg : "no error info available");
4239 LoadString(hModule, IDS_EXTTITLE, buf, sizeof (buf));
4240 MessageBox(NULL, msg, buf,
4241 MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
4242 MB_SETFOREGROUND);
4243#else
4244 fprintf(stderr, "extension '%s' did not load%s%s\n",
4245 path, errmsg ? ": " : "", errmsg ? errmsg : "");
4246#endif
4247 }
4248 }
4249 if (p) {
4250 exts = p + 1;
4251 }
4252 } while (p);
4253#endif /* HAVE_SQLITE3LOADEXTENSION */
4254}
4255
4262static void
4263dbattas(DBC *d, char *attas)
4264{
4265 char *p;
4266 char as[SQL_MAX_MESSAGE_LENGTH];
4267
4268 if (!d->sqlite) {
4269 return;
4270 }
4271 do {
4272 p = strchr(attas, ',');
4273 if (p) {
4274 strncpy(as, attas, p - attas);
4275 as[p - attas] = '\0';
4276 } else {
4277 strcpy(as, attas);
4278 }
4279 if (attas[0]) {
4280 char *sql;
4281
4282 sql = sqlite3_mprintf("ATTACH %Q AS %s", d->dbname, as);
4283 if (sql != NULL) {
4284 sqlite3_exec(d->sqlite, sql, NULL, NULL, NULL);
4285 sqlite3_free(sql);
4286 }
4287 }
4288 if (p) {
4289 attas = p + 1;
4290 }
4291 } while (p);
4292}
4293
4303static char *
4304s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
4305{
4306 char *typename = (char *) sqlite3_column_decltype(s3stmt, col);
4307 char guess[64];
4308
4309 guess[0] = '\0';
4310 if (!typename) {
4311 int coltype = sqlite3_column_type(s3stmt, col);
4312
4313 if (guessed_types) {
4314 guessed_types[0]++;
4315 }
4316 if (d->trace) {
4317 sprintf(guess, " (guessed from %d)", coltype);
4318 }
4319 switch (coltype) {
4320 case SQLITE_INTEGER: typename = "integer"; break;
4321 case SQLITE_FLOAT: typename = "double"; break;
4322 default:
4323 case SQLITE_TEXT: typename = "varchar"; break;
4324 case SQLITE_BLOB: typename = "blob"; break;
4325#if 0
4326 case SQLITE_NULL: typename = "null"; break;
4327#endif
4328 }
4329 }
4330 if (d->trace) {
4331 fprintf(d->trace, "-- column %d type%s: '%s'\n", col + 1,
4332 guess, typename);
4333 fflush(d->trace);
4334 }
4335 return typename;
4336}
4337
4338#ifdef FULL_METADATA
4339
4348static void
4349s3stmt_addmeta(sqlite3_stmt *s3stmt, int col, DBC *d, COL *ci)
4350{
4351 int nn = 0, pk = 0, ai = 0;
4352 const char *dn = NULL, *tn = NULL, *cn = NULL, *dummy[4];
4353
4354 dn = sqlite3_column_database_name(s3stmt, col);
4355 tn = sqlite3_column_table_name(s3stmt, col);
4356 cn = sqlite3_column_origin_name(s3stmt, col);
4357 dummy[0] = dummy[1] = 0;
4358 if (tn && cn) {
4359 sqlite3_table_column_metadata(d->sqlite, dn, tn, cn,
4360 dummy, dummy + 1,
4361 &nn, &pk, &ai);
4362 }
4363 ci->autoinc = ai ? SQL_TRUE: SQL_FALSE;
4364 ci->notnull = nn ? SQL_NO_NULLS : SQL_NULLABLE;
4365 ci->ispk = pk ? 1 : 0;
4366 if (d->trace) {
4367 fprintf(d->trace, "-- column %d %s\n",
4368 col + 1, nn ? "notnull" : "nullable");
4369 if (ai) {
4370 fprintf(d->trace, "-- column %d autoincrement\n", col + 1);
4371 }
4372 fflush(d->trace);
4373 }
4374 ci->isrowid = 0;
4375 if (ci->ispk && tn) {
4376 nn = pk = ai = 0;
4377 dummy[2] = dummy[3] = 0;
4378
4379 sqlite3_table_column_metadata(d->sqlite, dn, tn, "rowid",
4380 dummy + 2, dummy + 3,
4381 &nn, &pk, &ai);
4382 if (pk && dummy[0] && dummy[0] == dummy[2]) {
4383 ci->isrowid = 1;
4384 }
4385 }
4386}
4387
4388#endif
4389
4396static int
4398{
4399 DBC *d = (DBC *) s->dbc;
4400 char **rowd = NULL;
4401 const char *errp = NULL;
4402 int i, ncols, rc;
4403
4404 if (s != d->cur_s3stmt || !s->s3stmt) {
4405 setstat(s, -1, "stale statement", (*s->ov3) ? "HY000" : "S1000");
4406 return SQL_ERROR;
4407 }
4408 rc = sqlite3_step(s->s3stmt);
4409 if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
4410 ++s->s3stmt_rownum;
4411 ncols = sqlite3_column_count(s->s3stmt);
4412 if (d->s3stmt_needmeta && s->s3stmt_rownum == 0 && ncols > 0) {
4413 PTRDIFF_T size;
4414 char *p;
4415 COL *dyncols;
4416 const char *colname, *typename;
4417#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4418 char *tblname;
4419#endif
4420#if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
4421 char *dbname;
4422#endif
4423
4424 for (i = size = 0; i < ncols; i++) {
4425 colname = sqlite3_column_name(s->s3stmt, i);
4426 size += 3 + 3 * strlen(colname);
4427 }
4428#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4429 tblname = (char *) size;
4430 for (i = 0; i < ncols; i++) {
4431 p = (char *) sqlite3_column_table_name(s->s3stmt, i);
4432 size += 2 + (p ? strlen(p) : 0);
4433 }
4434#endif
4435#if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
4436 dbname = (char *) size;
4437 for (i = 0; i < ncols; i++) {
4438 p = (char *) sqlite3_column_database_name(s->s3stmt, i);
4439 size += 2 + (p ? strlen(p) : 0);
4440 }
4441#endif
4442 dyncols = xmalloc(ncols * sizeof (COL) + size);
4443 if (!dyncols) {
4444 freedyncols(s);
4445 s->ncols = 0;
4446 dbtraceapi(d, "sqlite3_finalize", 0);
4447 sqlite3_finalize(s->s3stmt);
4448 s->s3stmt = NULL;
4449 d->cur_s3stmt = NULL;
4450 return nomem(s);
4451 }
4452 p = (char *) (dyncols + ncols);
4453#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4454 tblname = p + (PTRDIFF_T) tblname;
4455#endif
4456#if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
4457 dbname = p + (PTRDIFF_T) dbname;
4458#endif
4459 for (i = 0; i < ncols; i++) {
4460 char *q;
4461
4462 colname = sqlite3_column_name(s->s3stmt, i);
4463 if (d->trace) {
4464 fprintf(d->trace, "-- column %d name: '%s'\n",
4465 i + 1, colname);
4466 fflush(d->trace);
4467 }
4468#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4469 q = (char *) sqlite3_column_table_name(s->s3stmt, i);
4470 strcpy(tblname, q ? q : "");
4471 if (d->trace) {
4472 fprintf(d->trace, "-- table %d name: '%s'\n",
4473 i + 1, tblname);
4474 fflush(d->trace);
4475 }
4476 dyncols[i].table = tblname;
4477 tblname += strlen(tblname) + 1;
4478#endif
4479#if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
4480 q = (char *) sqlite3_column_database_name(s->s3stmt, i);
4481 strcpy(dbname, q ? q : "");
4482 if (d->trace) {
4483 fprintf(d->trace, "-- database %d name: '%s'\n",
4484 i + 1, dbname);
4485 fflush(d->trace);
4486 }
4487 dyncols[i].db = dbname;
4488 dbname += strlen(dbname) + 1;
4489#else
4490 dyncols[i].db = ((DBC *) (s->dbc))->dbname;
4491#endif
4492 typename = s3stmt_coltype(s->s3stmt, i, d, 0);
4493 strcpy(p, colname);
4494 dyncols[i].label = p;
4495 p += strlen(p) + 1;
4496 q = strchr(colname, '.');
4497 if (q) {
4498 char *q2 = strchr(q + 1, '.');
4499
4500 /* SQLite 3.3.4 produces view.table.column sometimes */
4501 if (q2) {
4502 q = q2;
4503 }
4504 }
4505 if (q) {
4506#if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
4507 dyncols[i].table = p;
4508#endif
4509 strncpy(p, colname, q - colname);
4510 p[q - colname] = '\0';
4511 p += strlen(p) + 1;
4512 strcpy(p, q + 1);
4513 dyncols[i].column = p;
4514 p += strlen(p) + 1;
4515 } else {
4516#if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
4517 dyncols[i].table = "";
4518#endif
4519 strcpy(p, colname);
4520 dyncols[i].column = p;
4521 p += strlen(p) + 1;
4522 }
4523 if (s->longnames) {
4524 dyncols[i].column = dyncols[i].label;
4525 }
4526#ifdef SQL_LONGVARCHAR
4527 dyncols[i].type = SQL_LONGVARCHAR;
4528 dyncols[i].size = 65535;
4529#else
4530 dyncols[i].type = SQL_VARCHAR;
4531 dyncols[i].size = 255;
4532#endif
4533 dyncols[i].index = i;
4534 dyncols[i].scale = 0;
4535 dyncols[i].prec = 0;
4536 dyncols[i].nosign = 1;
4537 dyncols[i].autoinc = SQL_FALSE;
4538 dyncols[i].notnull = SQL_NULLABLE;
4539 dyncols[i].ispk = -1;
4540 dyncols[i].isrowid = -1;
4541#ifdef FULL_METADATA
4542 s3stmt_addmeta(s->s3stmt, i, d, &dyncols[i]);
4543#endif
4544 dyncols[i].typename = xstrdup(typename);
4545 }
4546 freedyncols(s);
4547 s->ncols = s->dcols = ncols;
4548 s->dyncols = s->cols = dyncols;
4549 fixupdyncols(s, d);
4550 mkbindcols(s, s->ncols);
4551 d->s3stmt_needmeta = 0;
4552 }
4553 if (ncols <= 0) {
4554 goto killstmt;
4555 }
4556 if (rc == SQLITE_DONE) {
4557 freeresult(s, 0);
4558 s->nrows = 0;
4559 dbtraceapi(d, "sqlite3_finalize", 0);
4560 sqlite3_finalize(s->s3stmt);
4561 s->s3stmt = NULL;
4562 d->cur_s3stmt = NULL;
4563 return SQL_SUCCESS;
4564 }
4565 rowd = xmalloc((1 + 2 * ncols) * sizeof (char *));
4566 if (rowd) {
4567 const unsigned char *value;
4568
4569 rowd[0] = (char *) ((PTRDIFF_T) (ncols * 2));
4570 ++rowd;
4571 for (i = 0; i < ncols; i++) {
4572 int coltype = sqlite3_column_type(s->s3stmt, i);
4573
4574 rowd[i] = rowd[i + ncols] = NULL;
4575 if (coltype == SQLITE_BLOB) {
4576 int k, nbytes = sqlite3_column_bytes(s->s3stmt, i);
4577 char *qp;
4578 unsigned const char *bp;
4579
4580 bp = sqlite3_column_blob(s->s3stmt, i);
4581 qp = xmalloc(nbytes * 2 + 4);
4582 if (qp) {
4583 rowd[i + ncols] = qp;
4584 *qp++ = 'X';
4585 *qp++ = '\'';
4586 for (k = 0; k < nbytes; k++) {
4587 *qp++ = xdigits[(bp[k] >> 4)];
4588 *qp++ = xdigits[(bp[k] & 0xF)];
4589 }
4590 *qp++ = '\'';
4591 *qp = '\0';
4592 }
4593#ifdef _MSC_VER
4594 } else if (coltype == SQLITE_FLOAT) {
4595 struct lconv *lc = 0;
4596 double d = sqlite3_column_double(s->s3stmt, i);
4597 char *p, buffer[128];
4598
4599 /*
4600 * This avoids floating point rounding
4601 * and formatting problems of some SQLite
4602 * versions in conjunction with MSVC 2010.
4603 */
4604 snprintf(buffer, sizeof (buffer), "%.15g", d);
4605 lc = localeconv();
4606 if (lc && lc->decimal_point && lc->decimal_point[0] &&
4607 lc->decimal_point[0] != '.') {
4608 p = strchr(buffer, lc->decimal_point[0]);
4609 if (p) {
4610 *p = '.';
4611 }
4612 }
4613 rowd[i + ncols] = xstrdup(buffer);
4614#endif
4615 } else if (coltype != SQLITE_NULL) {
4616 value = sqlite3_column_text(s->s3stmt, i);
4617 rowd[i + ncols] = xstrdup((char *) value);
4618 }
4619 }
4620 for (i = 0; i < ncols; i++) {
4621 int coltype = sqlite3_column_type(s->s3stmt, i);
4622
4623 value = NULL;
4624 if (coltype == SQLITE_BLOB) {
4625 value = sqlite3_column_blob(s->s3stmt, i);
4626 } else if (coltype != SQLITE_NULL) {
4627 value = sqlite3_column_text(s->s3stmt, i);
4628 }
4629 if (value && !rowd[i + ncols]) {
4630 freerows(rowd);
4631 rowd = 0;
4632 break;
4633 }
4634 }
4635 }
4636 if (rowd) {
4637 freeresult(s, 0);
4638 s->nrows = 1;
4639 s->rows = rowd;
4640 s->rowfree = freerows;
4641 if (rc == SQLITE_DONE) {
4642 dbtraceapi(d, "sqlite3_finalize", 0);
4643 sqlite3_finalize(s->s3stmt);
4644 s->s3stmt = NULL;
4645 d->cur_s3stmt = NULL;
4646 }
4647 return SQL_SUCCESS;
4648 }
4649 }
4650killstmt:
4651 dbtraceapi(d, "sqlite3_reset", 0);
4652 rc = sqlite3_reset(s->s3stmt);
4653 s->s3stmt_noreset = 1;
4654 errp = sqlite3_errmsg(d->sqlite);
4655 if (d->cur_s3stmt == s) {
4656 d->cur_s3stmt = NULL;
4657 }
4658 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
4659 errp ? errp : "unknown error", rc);
4660 return SQL_ERROR;
4661}
4662
4668static void
4670{
4671 DBC *d;
4672
4673 if (!s || !s->s3stmt) {
4674 return;
4675 }
4676 d = (DBC *) s->dbc;
4677 if (d) {
4678 d->busyint = 0;
4679 }
4680 if (!s->s3stmt_noreset) {
4681 dbtraceapi(d, "sqlite3_reset", 0);
4682 sqlite3_reset(s->s3stmt);
4683 s->s3stmt_noreset = 1;
4684 s->s3stmt_rownum = -1;
4685 }
4686 if (d->cur_s3stmt == s) {
4687 d->cur_s3stmt = NULL;
4688 }
4689}
4690
4696static void
4698{
4699 DBC *d = (DBC *) s->dbc;
4700
4701 if (d) {
4702 d->busyint = 0;
4703 }
4704 if (d && d->cur_s3stmt == s) {
4705 s3stmt_end(s);
4706 }
4707}
4708
4714static void
4716{
4717 if (s->s3stmt) {
4718 DBC *d = (DBC *) s->dbc;
4719
4720 if (d) {
4721 dbtraceapi(d, "sqlite3_finalize", 0);
4722 }
4723 sqlite3_finalize(s->s3stmt);
4724 s->s3stmt = NULL;
4725 s->s3stmt_rownum = 0;
4726 }
4727}
4728
4735static SQLRETURN
4737{
4738 DBC *d = (DBC *) s->dbc;
4739 const char *endp;
4740 sqlite3_stmt *s3stmt = NULL;
4741 int rc, nretry = 0;
4742
4743 d->s3stmt_needmeta = 0;
4744 if (!s->s3stmt) {
4745#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
4746 dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
4747#else
4748 dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
4749#endif
4750 do {
4751 s3stmt = NULL;
4752#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
4753 rc = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
4754 &s3stmt, &endp);
4755#else
4756 rc = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
4757 &s3stmt, &endp);
4758#endif
4759 if (rc != SQLITE_OK) {
4760 if (s3stmt) {
4761 sqlite3_finalize(s3stmt);
4762 s3stmt = NULL;
4763 }
4764 }
4765 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
4766 dbtracerc(d, rc, NULL);
4767 if (rc != SQLITE_OK) {
4768 if (s3stmt) {
4769 dbtraceapi(d, "sqlite3_finalize", NULL);
4770 sqlite3_finalize(s3stmt);
4771 }
4772 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
4773 sqlite3_errmsg(d->sqlite), rc);
4774 return SQL_ERROR;
4775 }
4776 if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
4777 dbtraceapi(d, "sqlite3_finalize", 0);
4778 sqlite3_finalize(s3stmt);
4779 setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
4780 (*s->ov3) ? "HY000" : "S1000");
4781 return SQL_ERROR;
4782 }
4783 s->s3stmt = s3stmt;
4784 s->s3stmt_noreset = 1;
4785 d->s3stmt_needmeta = 1;
4786 }
4787 d->cur_s3stmt = s;
4788 s->s3stmt_rownum = -1;
4789 s3bind(d, s->s3stmt, s->nparams, s->bindparms);
4790 return SQL_SUCCESS;
4791}
4792
4793#ifndef WINTERFACE
4798SQLRETURN SQL_API
4799SQLDataSources(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *srvname,
4800 SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
4801 SQLCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
4802{
4803 if (env == SQL_NULL_HENV) {
4804 return SQL_INVALID_HANDLE;
4805 }
4806 return SQL_ERROR;
4807}
4808#endif
4809
4810#ifdef WINTERFACE
4815SQLRETURN SQL_API
4816SQLDataSourcesW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *srvname,
4817 SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
4818 SQLWCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
4819{
4820 if (env == SQL_NULL_HENV) {
4821 return SQL_INVALID_HANDLE;
4822 }
4823 return SQL_ERROR;
4824}
4825#endif
4826
4827#ifndef WINTERFACE
4832SQLRETURN SQL_API
4833SQLDrivers(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *drvdesc,
4834 SQLSMALLINT descmax, SQLSMALLINT *desclenp,
4835 SQLCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
4836{
4837 if (env == SQL_NULL_HENV) {
4838 return SQL_INVALID_HANDLE;
4839 }
4840 return SQL_ERROR;
4841}
4842#endif
4843
4844#ifdef WINTERFACE
4849SQLRETURN SQL_API
4850SQLDriversW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *drvdesc,
4851 SQLSMALLINT descmax, SQLSMALLINT *desclenp,
4852 SQLWCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
4853{
4854 if (env == SQL_NULL_HENV) {
4855 return SQL_INVALID_HANDLE;
4856 }
4857 return SQL_ERROR;
4858}
4859#endif
4860
4861#ifndef WINTERFACE
4866SQLRETURN SQL_API
4867SQLBrowseConnect(SQLHDBC dbc, SQLCHAR *connin, SQLSMALLINT conninLen,
4868 SQLCHAR *connout, SQLSMALLINT connoutMax,
4869 SQLSMALLINT *connoutLen)
4870{
4871 SQLRETURN ret;
4872
4873 HDBC_LOCK(dbc);
4874 ret = drvunimpldbc(dbc);
4876 return ret;
4877}
4878#endif
4879
4880#ifdef WINTERFACE
4885SQLRETURN SQL_API
4886SQLBrowseConnectW(SQLHDBC dbc, SQLWCHAR *connin, SQLSMALLINT conninLen,
4887 SQLWCHAR *connout, SQLSMALLINT connoutMax,
4888 SQLSMALLINT *connoutLen)
4889{
4890 SQLRETURN ret;
4891
4892 HDBC_LOCK(dbc);
4893 ret = drvunimpldbc(dbc);
4895 return ret;
4896}
4897#endif
4898
4907static SQLRETURN
4908drvputdata(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
4909{
4910 STMT *s;
4911 int i, dlen, done = 0;
4912 BINDPARM *p;
4913
4914 if (stmt == SQL_NULL_HSTMT) {
4915 return SQL_INVALID_HANDLE;
4916 }
4917 s = (STMT *) stmt;
4918 if (!s->query || s->nparams <= 0) {
4919seqerr:
4920 setstat(s, -1, "sequence error", "HY010");
4921 return SQL_ERROR;
4922 }
4923 for (i = (s->pdcount < 0) ? 0 : s->pdcount; i < s->nparams; i++) {
4924 p = &s->bindparms[i];
4925 if (p->need > 0) {
4926 int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
4927
4928 if (len == SQL_NULL_DATA) {
4929 freep(&p->parbuf);
4930 p->param = NULL;
4931 p->len = SQL_NULL_DATA;
4932 p->need = -1;
4933 } else if (type != SQL_C_CHAR
4934#ifdef WCHARSUPPORT
4935 && type != SQL_C_WCHAR
4936#endif
4937 && type != SQL_C_BINARY) {
4938 int size = 0;
4939
4940 switch (type) {
4941 case SQL_C_TINYINT:
4942 case SQL_C_UTINYINT:
4943 case SQL_C_STINYINT:
4944#ifdef SQL_BIT
4945 case SQL_C_BIT:
4946#endif
4947 size = sizeof (SQLCHAR);
4948 break;
4949 case SQL_C_SHORT:
4950 case SQL_C_USHORT:
4951 case SQL_C_SSHORT:
4952 size = sizeof (SQLSMALLINT);
4953 break;
4954 case SQL_C_LONG:
4955 case SQL_C_ULONG:
4956 case SQL_C_SLONG:
4957 size = sizeof (SQLINTEGER);
4958 break;
4959#ifdef SQL_BIGINT
4960 case SQL_C_UBIGINT:
4961 case SQL_C_SBIGINT:
4962 size = sizeof (SQLBIGINT);
4963 break;
4964#endif
4965 case SQL_C_FLOAT:
4966 size = sizeof (float);
4967 break;
4968 case SQL_C_DOUBLE:
4969 size = sizeof (double);
4970 break;
4971#ifdef SQL_C_TYPE_DATE
4972 case SQL_C_TYPE_DATE:
4973#endif
4974 case SQL_C_DATE:
4975 size = sizeof (DATE_STRUCT);
4976 break;
4977#ifdef SQL_C_TYPE_DATE
4978 case SQL_C_TYPE_TIME:
4979#endif
4980 case SQL_C_TIME:
4981 size = sizeof (TIME_STRUCT);
4982 break;
4983#ifdef SQL_C_TYPE_DATE
4984 case SQL_C_TYPE_TIMESTAMP:
4985#endif
4986 case SQL_C_TIMESTAMP:
4987 size = sizeof (TIMESTAMP_STRUCT);
4988 break;
4989 }
4990 freep(&p->parbuf);
4991 p->parbuf = xmalloc(size);
4992 if (!p->parbuf) {
4993 return nomem(s);
4994 }
4995 p->param = p->parbuf;
4996 memcpy(p->param, data, size);
4997 p->len = size;
4998 p->need = -1;
4999 } else if (len == SQL_NTS && (
5000 type == SQL_C_CHAR
5001#ifdef WCHARSUPPORT
5002 || type == SQL_C_WCHAR
5003#endif
5004 )) {
5005 char *dp = data;
5006
5007#ifdef WCHARSUPPORT
5008 if (type == SQL_C_WCHAR) {
5009 dp = uc_to_utf(data, len);
5010 if (!dp) {
5011 return nomem(s);
5012 }
5013 }
5014#endif
5015#if defined(_WIN32) || defined(_WIN64)
5016 if (*s->oemcp) {
5017 dp = wmb_to_utf(data, strlen (data));
5018 if (!dp) {
5019 return nomem(s);
5020 }
5021 }
5022#endif
5023 dlen = strlen(dp);
5024 freep(&p->parbuf);
5025 p->parbuf = xmalloc(dlen + 1);
5026 if (!p->parbuf) {
5027 if (dp != data) {
5028 uc_free(dp);
5029 }
5030 return nomem(s);
5031 }
5032 p->param = p->parbuf;
5033 strcpy(p->param, dp);
5034 if (dp != data) {
5035 uc_free(dp);
5036 }
5037 p->len = dlen;
5038 p->need = -1;
5039 } else if (len < 0) {
5040 setstat(s, -1, "invalid length", "HY090");
5041 return SQL_ERROR;
5042 } else {
5043 dlen = min(p->len - p->offs, len);
5044 if (!p->param) {
5045 setstat(s, -1, "no memory for parameter", "HY013");
5046 return SQL_ERROR;
5047 }
5048 memcpy((char *) p->param + p->offs, data, dlen);
5049 p->offs += dlen;
5050 if (p->offs >= p->len) {
5051#ifdef WCHARSUPPORT
5052 if (type == SQL_C_WCHAR) {
5053 char *dp = uc_to_utf(p->param, p->len);
5054 char *np;
5055 int nlen;
5056
5057 if (!dp) {
5058 return nomem(s);
5059 }
5060 nlen = strlen(dp);
5061 np = xmalloc(nlen + 1);
5062 if (!np) {
5063 uc_free(dp);
5064 return nomem(s);
5065 }
5066 strcpy(np, dp);
5067 uc_free(dp);
5068 if (p->param == p->parbuf) {
5069 freep(&p->parbuf);
5070 }
5071 p->parbuf = p->param = np;
5072 p->len = nlen;
5073 } else {
5074 *((char *) p->param + p->len) = '\0';
5075 }
5076 p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR)
5077 ? -1 : 0;
5078#else
5079 *((char *) p->param + p->len) = '\0';
5080 p->need = (type == SQL_C_CHAR) ? -1 : 0;
5081#endif
5082#if defined(_WIN32) || defined(_WIN64)
5083 if (type == SQL_C_CHAR && *s->oemcp &&
5084 !(p->stype == SQL_BINARY ||
5085 p->stype == SQL_VARBINARY ||
5086 p->stype == SQL_LONGVARBINARY)) {
5087 char *dp = wmb_to_utf(p->param, p->len);
5088
5089 if (!dp) {
5090 return nomem(s);
5091 }
5092 if (p->param == p->parbuf) {
5093 freep(&p->parbuf);
5094 }
5095 p->parbuf = p->param = dp;
5096 p->len = strlen(dp);
5097 }
5098 if (p->type == SQL_C_WCHAR &&
5099 (p->stype == SQL_VARCHAR ||
5100 p->stype == SQL_LONGVARCHAR) &&
5101 p->len == p->coldef * sizeof (SQLWCHAR)) {
5102 /* fix for MS-Access */
5103 p->len = p->coldef;
5104 }
5105#endif
5106 }
5107 }
5108 done = 1;
5109 break;
5110 }
5111 }
5112 if (!done) {
5113 goto seqerr;
5114 }
5115 return SQL_SUCCESS;
5116}
5117
5126SQLRETURN SQL_API
5127SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
5128{
5129 SQLRETURN ret;
5130
5132 ret = drvputdata(stmt, data, len);
5134 return ret;
5135}
5136
5142static SQLRETURN
5144{
5145 if (s->bindparms) {
5146 int n;
5147
5148 for (n = 0; n < s->nbindparms; n++) {
5149 freep(&s->bindparms[n].parbuf);
5150 memset(&s->bindparms[n], 0, sizeof (BINDPARM));
5151 }
5152 }
5153 return SQL_SUCCESS;
5154}
5155
5167static SQLRETURN
5168setupparam(STMT *s, char *sql, int pnum)
5169{
5170 int type, len = 0, needalloc = 0;
5171 BINDPARM *p;
5172
5173 if (!s->bindparms || pnum < 0 || pnum >= s->nbindparms) {
5174 goto error;
5175 }
5176 p = &s->bindparms[pnum];
5177 type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
5178#if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
5179 /* MS Access hack part 4 (map SQL_C_DEFAULT to SQL_C_CHAR) */
5180 if (type == SQL_C_WCHAR && p->type == SQL_C_DEFAULT) {
5181 type = SQL_C_CHAR;
5182 }
5183#endif
5184 if (p->need > 0) {
5185 return setupparbuf(s, p);
5186 }
5187 p->strbuf[0] = '\0';
5188 if (!p->param || (p->lenp && *p->lenp == SQL_NULL_DATA)) {
5189 p->s3type = SQLITE_NULL;
5190 p->s3size = 0;
5191 return SQL_SUCCESS;
5192 }
5193 if (type == SQL_C_CHAR &&
5194 (p->stype == SQL_BINARY ||
5195 p->stype == SQL_VARBINARY ||
5196 p->stype == SQL_LONGVARBINARY)) {
5197 type = SQL_C_BINARY;
5198 }
5199 switch (type) {
5200 case SQL_C_BINARY:
5201 p->s3type = SQLITE_BLOB;
5202 p->s3val = p->param;
5203 if (!p->lenp) {
5204 len = p->len;
5205 } else if (*p->lenp == SQL_DATA_AT_EXEC) {
5206 len = p->len;
5207 } else {
5208 len = *p->lenp;
5209 if (len <= SQL_LEN_DATA_AT_EXEC_OFFSET) {
5210 len = SQL_LEN_DATA_AT_EXEC(len);
5211 }
5212 }
5213 if (len < 0) {
5214 setstat(s, -1, "invalid length", "HY009");
5215 return SQL_ERROR;
5216 }
5217 p->len = len;
5218 p->max = p->len;
5219 p->s3size = len;
5220 break;
5221#ifdef WCHARSUPPORT
5222 case SQL_C_WCHAR:
5223#endif
5224 case SQL_C_CHAR:
5225 p->s3type = SQLITE_TEXT;
5226 p->s3size = -1;
5227 p->s3val = p->param;
5228 if (!p->parbuf) {
5229#ifdef WCHARSUPPORT
5230 if (type == SQL_C_WCHAR) {
5231 if (!p->lenp || *p->lenp == SQL_NTS) {
5232 p->max = uc_strlen(p->param) * sizeof (SQLWCHAR);
5233 } else if (*p->lenp >= 0) {
5234 p->max = *p->lenp;
5235 }
5236 } else
5237#endif
5238 if (type == SQL_C_CHAR) {
5239 if (!p->lenp || *p->lenp == SQL_NTS) {
5240 p->len = p->max = strlen(p->param);
5241#if defined(_WIN32) || defined(_WIN64)
5242 needalloc = 1;
5243#endif
5244 } else if (*p->lenp >= 0) {
5245 p->len = p->max = *p->lenp;
5246 needalloc = 1;
5247 }
5248 }
5249 }
5250 if (p->need < 0 && p->parbuf == p->param) {
5251 break;
5252 }
5253#ifdef WCHARSUPPORT
5254 if (type == SQL_C_WCHAR) {
5255 char *dp = uc_to_utf(p->param, p->max);
5256
5257 if (!dp) {
5258 return nomem(s);
5259 }
5260 if (p->param == p->parbuf) {
5261 freep(&p->parbuf);
5262 }
5263 p->parbuf = p->param = dp;
5264 p->need = -1;
5265 p->len = strlen(p->param);
5266 p->s3val = p->param;
5267 p->s3size = p->len;
5268 } else
5269#endif
5270 if (type == SQL_C_CHAR) {
5271 p->s3val = p->param;
5272 if (needalloc) {
5273 char *dp;
5274
5275#if defined(_WIN32) || defined(_WIN64)
5276 if (*s->oemcp) {
5277 dp = wmb_to_utf(p->param, p->len);
5278 } else {
5279 dp = xmalloc(p->len + 1);
5280 }
5281#else
5282 dp = xmalloc(p->len + 1);
5283#endif
5284 if (!dp) {
5285 return nomem(s);
5286 }
5287#if defined(_WIN32) || defined(_WIN64)
5288 if (*s->oemcp) {
5289 p->len = strlen(dp);
5290 } else {
5291 memcpy(dp, p->param, p->len);
5292 dp[p->len] = '\0';
5293 }
5294#else
5295 memcpy(dp, p->param, p->len);
5296 dp[p->len] = '\0';
5297#endif
5298 if (p->param == p->parbuf) {
5299 freep(&p->parbuf);
5300 }
5301 p->parbuf = p->param = dp;
5302 p->need = -1;
5303 p->s3val = p->param;
5304 p->s3size = p->len;
5305 }
5306 }
5307 break;
5308 case SQL_C_UTINYINT:
5309 case SQL_C_TINYINT:
5310 case SQL_C_STINYINT:
5311 p->s3type = SQLITE_INTEGER;
5312 p->s3size = sizeof (int);
5313 p->s3ival = *((SQLCHAR *) p->param);
5314 break;
5315 case SQL_C_USHORT:
5316 p->s3type = SQLITE_INTEGER;
5317 p->s3size = sizeof (int);
5318 p->s3ival = *((SQLUSMALLINT *) p->param);
5319 break;
5320 case SQL_C_SHORT:
5321 case SQL_C_SSHORT:
5322 p->s3type = SQLITE_INTEGER;
5323 p->s3size = sizeof (int);
5324 p->s3ival = *((SQLSMALLINT *) p->param);
5325 break;
5326 case SQL_C_ULONG:
5327 p->s3type = SQLITE_INTEGER;
5328 p->s3size = sizeof (int);
5329 p->s3ival = *((SQLUINTEGER *) p->param);
5330 break;
5331 case SQL_C_LONG:
5332 case SQL_C_SLONG:
5333 p->s3type = SQLITE_INTEGER;
5334 p->s3size = sizeof (int);
5335 p->s3ival = *((SQLINTEGER *) p->param);
5336 break;
5337#ifdef SQL_BIT
5338 case SQL_C_BIT:
5339 p->s3type = SQLITE_INTEGER;
5340 p->s3size = sizeof (int);
5341 p->s3ival = (*((SQLCHAR *) p->param)) ? 1 : 0;
5342 break;
5343#endif
5344#ifdef SQL_BIGINT
5345 case SQL_C_SBIGINT:
5346 p->s3type = SQLITE_INTEGER;
5347 p->s3size = sizeof (sqlite_int64);
5348 p->s3lival = *((sqlite_int64 *) p->param);
5349 break;
5350 case SQL_C_UBIGINT:
5351 p->s3type = SQLITE_INTEGER;
5352 p->s3size = sizeof (sqlite_int64);
5353 p->s3lival = *((sqlite_uint64 *) p->param);
5354 break;
5355#endif
5356 case SQL_C_FLOAT:
5357 p->s3type = SQLITE_FLOAT;
5358 p->s3size = sizeof (double);
5359 p->s3dval = *((float *) p->param);
5360 break;
5361 case SQL_C_DOUBLE:
5362 p->s3type = SQLITE_FLOAT;
5363 p->s3size = sizeof (double);
5364 p->s3dval = *((double *) p->param);
5365 break;
5366#ifdef SQL_C_TYPE_DATE
5367 case SQL_C_TYPE_DATE:
5368#endif
5369 case SQL_C_DATE:
5370 if (*s->jdconv) {
5371 int a, b, x1, x2, y, m, d;
5372
5373 p->s3type = SQLITE_FLOAT;
5374 p->s3size = sizeof (double);
5375 y = ((DATE_STRUCT *) p->param)->year;
5376 m = ((DATE_STRUCT *) p->param)->month;
5377 d = ((DATE_STRUCT *) p->param)->day;
5378 if (m <= 2) {
5379 y--;
5380 m += 12;
5381 }
5382 a = y / 100;
5383 b = 2 - a + (a / 4);
5384 x1 = 36525 * (y + 4716) / 100;
5385 x2 = 306001 * (m + 1) / 10000;
5386 p->s3dval = x1 + x2 + d + b - 1524.5;
5387 break;
5388 }
5389 sprintf(p->strbuf, "%04d-%02d-%02d",
5390 ((DATE_STRUCT *) p->param)->year,
5391 ((DATE_STRUCT *) p->param)->month,
5392 ((DATE_STRUCT *) p->param)->day);
5393 p->s3type = SQLITE_TEXT;
5394 p->s3size = -1;
5395 p->s3val = p->strbuf;
5396 break;
5397#ifdef SQL_C_TYPE_TIME
5398 case SQL_C_TYPE_TIME:
5399#endif
5400 case SQL_C_TIME:
5401 if (*s->jdconv) {
5402 p->s3type = SQLITE_FLOAT;
5403 p->s3size = sizeof (double);
5404 p->s3dval = 2451544.5 +
5405 (((TIME_STRUCT *) p->param)->hour * 3600000.0 +
5406 ((TIME_STRUCT *) p->param)->minute * 60000.0 +
5407 ((TIME_STRUCT *) p->param)->second * 1000.0) / 86400000.0;
5408 break;
5409 }
5410 sprintf(p->strbuf, "%02d:%02d:%02d",
5411 ((TIME_STRUCT *) p->param)->hour,
5412 ((TIME_STRUCT *) p->param)->minute,
5413 ((TIME_STRUCT *) p->param)->second);
5414 p->s3type = SQLITE_TEXT;
5415 p->s3size = -1;
5416 p->s3val = p->strbuf;
5417 break;
5418#ifdef SQL_C_TYPE_TIMESTAMP
5419 case SQL_C_TYPE_TIMESTAMP:
5420#endif
5421 case SQL_C_TIMESTAMP:
5422 if (*s->jdconv) {
5423 int a, b, x1, x2, y, m, d;
5424
5425 p->s3type = SQLITE_FLOAT;
5426 p->s3size = sizeof (double);
5427 y = ((TIMESTAMP_STRUCT *) p->param)->year;
5428 m = ((TIMESTAMP_STRUCT *) p->param)->month;
5429 d = ((TIMESTAMP_STRUCT *) p->param)->day;
5430 if (m <= 2) {
5431 y--;
5432 m += 12;
5433 }
5434 a = y / 100;
5435 b = 2 - a + (a / 4);
5436 x1 = 36525 * (y + 4716) / 100;
5437 x2 = 306001 * (m + 1) / 10000;
5438 p->s3dval = x1 + x2 + d + b - 1524.5 +
5439 (((TIMESTAMP_STRUCT *) p->param)->hour * 3600000.0 +
5440 ((TIMESTAMP_STRUCT *) p->param)->minute * 60000.0 +
5441 ((TIMESTAMP_STRUCT *) p->param)->second * 1000.0 +
5442 ((TIMESTAMP_STRUCT *) p->param)->fraction / 1.0E6)
5443 / 86400000.0;
5444 break;
5445 }
5446 len = (int) ((TIMESTAMP_STRUCT *) p->param)->fraction;
5447 len /= 1000000;
5448 len = len % 1000;
5449 if (len < 0) {
5450 len = 0;
5451 }
5452 if (p->coldef && p->coldef <= 16) {
5453 sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
5454 ((TIMESTAMP_STRUCT *) p->param)->year,
5455 ((TIMESTAMP_STRUCT *) p->param)->month,
5456 ((TIMESTAMP_STRUCT *) p->param)->day,
5457 ((TIMESTAMP_STRUCT *) p->param)->hour,
5458 ((TIMESTAMP_STRUCT *) p->param)->minute);
5459 } else if (p->coldef && p->coldef <= 19) {
5460 sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
5461 ((TIMESTAMP_STRUCT *) p->param)->year,
5462 ((TIMESTAMP_STRUCT *) p->param)->month,
5463 ((TIMESTAMP_STRUCT *) p->param)->day,
5464 ((TIMESTAMP_STRUCT *) p->param)->hour,
5465 ((TIMESTAMP_STRUCT *) p->param)->minute,
5466 ((TIMESTAMP_STRUCT *) p->param)->second);
5467 } else {
5468 sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
5469 ((TIMESTAMP_STRUCT *) p->param)->year,
5470 ((TIMESTAMP_STRUCT *) p->param)->month,
5471 ((TIMESTAMP_STRUCT *) p->param)->day,
5472 ((TIMESTAMP_STRUCT *) p->param)->hour,
5473 ((TIMESTAMP_STRUCT *) p->param)->minute,
5474 ((TIMESTAMP_STRUCT *) p->param)->second,
5475 len);
5476 }
5477 p->s3type = SQLITE_TEXT;
5478 p->s3size = -1;
5479 p->s3val = p->strbuf;
5480 break;
5481 default:
5482 error:
5483 setstat(s, -1, "unsupported parameter type",
5484 (*s->ov3) ? "07009" : "S1093");
5485 return SQL_ERROR;
5486 }
5487 return SQL_SUCCESS;
5488}
5489
5505static SQLRETURN
5506drvbindparam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
5507 SQLSMALLINT buftype, SQLSMALLINT ptype, SQLUINTEGER coldef,
5508 SQLSMALLINT scale,
5509 SQLPOINTER data, SQLINTEGER buflen, SQLLEN *len)
5510{
5511 STMT *s;
5512 BINDPARM *p;
5513
5514 if (stmt == SQL_NULL_HSTMT) {
5515 return SQL_INVALID_HANDLE;
5516 }
5517 s = (STMT *) stmt;
5518 if (pnum == 0) {
5519 setstat(s, -1, "invalid parameter", (*s->ov3) ? "07009" : "S1093");
5520 return SQL_ERROR;
5521 }
5522 if (!data && !len) {
5523 setstat(s, -1, "invalid buffer", "HY003");
5524 return SQL_ERROR;
5525 }
5526 --pnum;
5527 if (s->bindparms) {
5528 if (pnum >= s->nbindparms) {
5529 BINDPARM *newparms;
5530
5531 newparms = xrealloc(s->bindparms,
5532 (pnum + 1) * sizeof (BINDPARM));
5533 if (!newparms) {
5534outofmem:
5535 return nomem(s);
5536 }
5537 s->bindparms = newparms;
5538 memset(&s->bindparms[s->nbindparms], 0,
5539 (pnum + 1 - s->nbindparms) * sizeof (BINDPARM));
5540 s->nbindparms = pnum + 1;
5541 }
5542 } else {
5543 int npar = max(10, pnum + 1);
5544
5545 s->bindparms = xmalloc(npar * sizeof (BINDPARM));
5546 if (!s->bindparms) {
5547 goto outofmem;
5548 }
5549 memset(s->bindparms, 0, npar * sizeof (BINDPARM));
5550 s->nbindparms = npar;
5551 }
5552 switch (buftype) {
5553 case SQL_C_STINYINT:
5554 case SQL_C_UTINYINT:
5555 case SQL_C_TINYINT:
5556#ifdef SQL_C_BIT
5557 case SQL_C_BIT:
5558#endif
5559 buflen = sizeof (SQLCHAR);
5560 break;
5561 case SQL_C_SHORT:
5562 case SQL_C_USHORT:
5563 case SQL_C_SSHORT:
5564 buflen = sizeof (SQLSMALLINT);
5565 break;
5566 case SQL_C_SLONG:
5567 case SQL_C_ULONG:
5568 case SQL_C_LONG:
5569 buflen = sizeof (SQLINTEGER);
5570 break;
5571 case SQL_C_FLOAT:
5572 buflen = sizeof (float);
5573 break;
5574 case SQL_C_DOUBLE:
5575 buflen = sizeof (double);
5576 break;
5577 case SQL_C_TIMESTAMP:
5578#ifdef SQL_C_TYPE_TIMESTAMP
5579 case SQL_C_TYPE_TIMESTAMP:
5580#endif
5581 buflen = sizeof (TIMESTAMP_STRUCT);
5582 break;
5583 case SQL_C_TIME:
5584#ifdef SQL_C_TYPE_TIME
5585 case SQL_C_TYPE_TIME:
5586#endif
5587 buflen = sizeof (TIME_STRUCT);
5588 break;
5589 case SQL_C_DATE:
5590#ifdef SQL_C_TYPE_DATE
5591 case SQL_C_TYPE_DATE:
5592#endif
5593 buflen = sizeof (DATE_STRUCT);
5594 break;
5595#ifdef SQL_C_UBIGINT
5596 case SQL_C_UBIGINT:
5597 buflen = sizeof (SQLBIGINT);
5598 break;
5599#endif
5600#ifdef SQL_C_SBIGINT
5601 case SQL_C_SBIGINT:
5602 buflen = sizeof (SQLBIGINT);
5603 break;
5604#endif
5605#ifdef SQL_C_BIGINT
5606 case SQL_C_BIGINT:
5607 buflen = sizeof (SQLBIGINT);
5608 break;
5609#endif
5610 }
5611 p = &s->bindparms[pnum];
5612 p->type = buftype;
5613 p->stype = ptype;
5614 p->coldef = coldef;
5615 p->scale = scale;
5616 p->max = buflen;
5617 p->inc = buflen;
5618 p->lenp = p->lenp0 = len;
5619 p->offs = 0;
5620 p->len = 0;
5621 p->param0 = data;
5622 freep(&p->parbuf);
5623 p->param = p->param0;
5624 p->bound = 1;
5625 p->need = 0;
5626 return SQL_SUCCESS;
5627}
5628
5644SQLRETURN SQL_API
5645SQLBindParameter(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
5646 SQLSMALLINT buftype, SQLSMALLINT ptype, SQLULEN coldef,
5647 SQLSMALLINT scale,
5648 SQLPOINTER data, SQLLEN buflen, SQLLEN *len)
5649{
5650 SQLRETURN ret;
5651
5653 ret = drvbindparam(stmt, pnum, iotype, buftype, ptype, coldef,
5654 scale, data, buflen, len);
5656 return ret;
5657}
5658
5659#ifndef HAVE_IODBC
5673SQLRETURN SQL_API
5674SQLBindParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT vtype,
5675 SQLSMALLINT ptype, SQLULEN lenprec,
5676 SQLSMALLINT scale, SQLPOINTER val,
5677 SQLLEN *lenp)
5678{
5679 SQLRETURN ret;
5680
5682 ret = drvbindparam(stmt, pnum, SQL_PARAM_INPUT, vtype, ptype,
5683 lenprec, scale, val, 0, lenp);
5685 return ret;
5686}
5687#endif
5688
5696SQLRETURN SQL_API
5697SQLNumParams(SQLHSTMT stmt, SQLSMALLINT *nparam)
5698{
5699 STMT *s;
5700 SQLSMALLINT dummy;
5701
5703 if (stmt == SQL_NULL_HSTMT) {
5704 return SQL_INVALID_HANDLE;
5705 }
5706 s = (STMT *) stmt;
5707 if (!nparam) {
5708 nparam = &dummy;
5709 }
5710 *nparam = s->nparams;
5712 return SQL_SUCCESS;
5713}
5714
5722static SQLRETURN
5724{
5725 if (!p->parbuf) {
5726 if (*p->lenp == SQL_DATA_AT_EXEC) {
5727 p->len = p->max;
5728 } else {
5729 p->len = SQL_LEN_DATA_AT_EXEC(*p->lenp);
5730 }
5731 if (p->len < 0 && p->len != SQL_NTS &&
5732 p->len != SQL_NULL_DATA) {
5733 setstat(s, -1, "invalid length", "HY009");
5734 return SQL_ERROR;
5735 }
5736 if (p->len >= 0) {
5737 p->parbuf = xmalloc(p->len + 2);
5738 if (!p->parbuf) {
5739 return nomem(s);
5740 }
5741 p->param = p->parbuf;
5742 } else {
5743 p->param = NULL;
5744 }
5745 }
5746 return SQL_NEED_DATA;
5747}
5748
5756SQLRETURN SQL_API
5757SQLParamData(SQLHSTMT stmt, SQLPOINTER *pind)
5758{
5759 STMT *s;
5760 int i;
5761 SQLPOINTER dummy;
5762 SQLRETURN ret;
5763 BINDPARM *p;
5764
5766 if (stmt == SQL_NULL_HSTMT) {
5767 return SQL_INVALID_HANDLE;
5768 }
5769 s = (STMT *) stmt;
5770 if (!pind) {
5771 pind = &dummy;
5772 }
5773 if (s->pdcount < s->nparams) {
5774 s->pdcount++;
5775 }
5776 for (i = 0; i < s->pdcount; i++) {
5777 p = &s->bindparms[i];
5778 if (p->need > 0) {
5779 int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
5780
5781 p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR) ? -1 : 0;
5782 }
5783 }
5784 for (; i < s->nparams; i++) {
5785 p = &s->bindparms[i];
5786 if (p->need > 0) {
5787 *pind = (SQLPOINTER) p->param0;
5788 ret = setupparbuf(s, p);
5789 s->pdcount = i;
5790 goto done;
5791 }
5792 }
5793 ret = drvexecute(stmt, 0);
5794done:
5796 return ret;
5797}
5798
5810SQLRETURN SQL_API
5811SQLDescribeParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT *dtype,
5812 SQLULEN *size, SQLSMALLINT *decdigits, SQLSMALLINT *nullable)
5813{
5814 STMT *s;
5815 SQLRETURN ret = SQL_ERROR;
5816
5818 if (stmt == SQL_NULL_HSTMT) {
5819 return SQL_INVALID_HANDLE;
5820 }
5821 s = (STMT *) stmt;
5822 --pnum;
5823 if (pnum >= s->nparams) {
5824 setstat(s, -1, "invalid parameter index",
5825 (*s->ov3) ? "HY000" : "S1000");
5826 goto done;
5827 }
5828 if (dtype) {
5829#ifdef SQL_LONGVARCHAR
5830#ifdef WINTERFACE
5831 *dtype = s->nowchar[0] ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
5832#else
5833 *dtype = SQL_LONGVARCHAR;
5834#endif
5835#else
5836#ifdef WINTERFACE
5837 *dtype = s->nowchar[0] ? SQL_VARCHAR : SQL_WVARCHAR;
5838#else
5839 *dtype = SQL_VARCHAR;
5840#endif
5841#endif
5842 }
5843 if (size) {
5844#ifdef SQL_LONGVARCHAR
5845 *size = 65536;
5846#else
5847 *size = 255;
5848#endif
5849 }
5850 if (decdigits) {
5851 *decdigits = 0;
5852 }
5853 if (nullable) {
5854 *nullable = SQL_NULLABLE;
5855 }
5856 ret = SQL_SUCCESS;
5857done:
5859 return ret;
5860}
5861
5875SQLRETURN SQL_API
5876SQLSetParam(SQLHSTMT stmt, SQLUSMALLINT par, SQLSMALLINT type,
5877 SQLSMALLINT sqltype, SQLULEN coldef,
5878 SQLSMALLINT scale, SQLPOINTER val, SQLLEN *nval)
5879{
5880 SQLRETURN ret;
5881
5883 ret = drvbindparam(stmt, par, SQL_PARAM_INPUT,
5884 type, sqltype, coldef, scale, val,
5885 SQL_SETPARAM_VALUE_MAX, nval);
5887 return ret;
5888}
5889
5894SQLRETURN SQL_API
5895SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
5896{
5897 SQLRETURN ret;
5898
5900 ret = drvunimplstmt(stmt);
5902 return ret;
5903}
5904
5905#ifndef WINTERFACE
5910SQLRETURN SQL_API
5911SQLGetDescField(SQLHDESC handle, SQLSMALLINT recno,
5912 SQLSMALLINT fieldid, SQLPOINTER value,
5913 SQLINTEGER buflen, SQLINTEGER *strlen)
5914{
5915 return SQL_ERROR;
5916}
5917#endif
5918
5919#ifdef WINTERFACE
5924SQLRETURN SQL_API
5925SQLGetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
5926 SQLSMALLINT fieldid, SQLPOINTER value,
5927 SQLINTEGER buflen, SQLINTEGER *strlen)
5928{
5929 return SQL_ERROR;
5930}
5931#endif
5932
5933#ifndef WINTERFACE
5938SQLRETURN SQL_API
5939SQLSetDescField(SQLHDESC handle, SQLSMALLINT recno,
5940 SQLSMALLINT fieldid, SQLPOINTER value,
5941 SQLINTEGER buflen)
5942{
5943 return SQL_ERROR;
5944}
5945#endif
5946
5947#ifdef WINTERFACE
5952SQLRETURN SQL_API
5953SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
5954 SQLSMALLINT fieldid, SQLPOINTER value,
5955 SQLINTEGER buflen)
5956{
5957 return SQL_ERROR;
5958}
5959#endif
5960
5961#ifndef WINTERFACE
5966SQLRETURN SQL_API
5967SQLGetDescRec(SQLHDESC handle, SQLSMALLINT recno,
5968 SQLCHAR *name, SQLSMALLINT buflen,
5969 SQLSMALLINT *strlen, SQLSMALLINT *type,
5970 SQLSMALLINT *subtype, SQLLEN *len,
5971 SQLSMALLINT *prec, SQLSMALLINT *scale,
5972 SQLSMALLINT *nullable)
5973{
5974 return SQL_ERROR;
5975}
5976#endif
5977
5978#ifdef WINTERFACE
5983SQLRETURN SQL_API
5984SQLGetDescRecW(SQLHDESC handle, SQLSMALLINT recno,
5985 SQLWCHAR *name, SQLSMALLINT buflen,
5986 SQLSMALLINT *strlen, SQLSMALLINT *type,
5987 SQLSMALLINT *subtype, SQLLEN *len,
5988 SQLSMALLINT *prec, SQLSMALLINT *scale,
5989 SQLSMALLINT *nullable)
5990{
5991 return SQL_ERROR;
5992}
5993#endif
5994
5999SQLRETURN SQL_API
6000SQLSetDescRec(SQLHDESC handle, SQLSMALLINT recno,
6001 SQLSMALLINT type, SQLSMALLINT subtype,
6002 SQLLEN len, SQLSMALLINT prec,
6003 SQLSMALLINT scale, SQLPOINTER data,
6004 SQLLEN *strlen, SQLLEN *indicator)
6005{
6006 return SQL_ERROR;
6007}
6008
6020static SQLRETURN
6021mkresultset(HSTMT stmt, COL *colspec, int ncols, COL *colspec3,
6022 int ncols3, int *nret)
6023{
6024 STMT *s;
6025 DBC *d;
6026
6027 if (stmt == SQL_NULL_HSTMT) {
6028 return SQL_INVALID_HANDLE;
6029 }
6030 s = (STMT *) stmt;
6031 if (s->dbc == SQL_NULL_HDBC) {
6032noconn:
6033 return noconn(s);
6034 }
6035 d = (DBC *) s->dbc;
6036 if (!d->sqlite) {
6037 goto noconn;
6038 }
6039 s3stmt_end_if(s);
6040 freeresult(s, 0);
6041 if (colspec3 && *s->ov3) {
6042 s->ncols = ncols3;
6043 s->cols = colspec3;
6044 } else {
6045 s->ncols = ncols;
6046 s->cols = colspec;
6047 }
6048 mkbindcols(s, s->ncols);
6049 s->nowchar[1] = 1;
6050 s->nrows = 0;
6051 s->rowp = s->rowprs = -1;
6052 s->isselect = -1;
6053 if (nret) {
6054 *nret = s->ncols;
6055 }
6056 return SQL_SUCCESS;
6057}
6058
6064 { "SYSTEM", "TABLEPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
6065 { "SYSTEM", "TABLEPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
6066 { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6067 { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6068 { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6069 { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
6070 { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
6071};
6072
6074 { "SYSTEM", "TABLEPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
6075 { "SYSTEM", "TABLEPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
6076 { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6077 { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6078 { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6079 { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
6080 { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
6081};
6082
6095static SQLRETURN
6097 SQLCHAR *cat, SQLSMALLINT catLen,
6098 SQLCHAR *schema, SQLSMALLINT schemaLen,
6099 SQLCHAR *table, SQLSMALLINT tableLen)
6100{
6101 SQLRETURN ret;
6102 STMT *s;
6103 DBC *d;
6104 int ncols, rc, size, npatt;
6105 char *errp = NULL, *sql, tname[512];
6106
6109 if (ret != SQL_SUCCESS) {
6110 return ret;
6111 }
6112 s = (STMT *) stmt;
6113 d = (DBC *) s->dbc;
6114 if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
6115 table = NULL;
6116 goto doit;
6117 }
6118 if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
6119 schema[0] == '%') {
6120 if ((!cat || catLen == 0 || !cat[0]) &&
6121 (!table || tableLen == 0 || !table[0])) {
6122 table = NULL;
6123 goto doit;
6124 }
6125 }
6126doit:
6127 if (!table) {
6128 size = 1;
6129 tname[0] = '%';
6130 } else {
6131 if (tableLen == SQL_NTS) {
6132 size = sizeof (tname) - 1;
6133 } else {
6134 size = min(sizeof (tname) - 1, tableLen);
6135 }
6136 strncpy(tname, (char *) table, size);
6137 }
6138 tname[size] = '\0';
6139 npatt = unescpat(tname);
6140#if defined(_WIN32) || defined(_WIN64)
6141 if (npatt) {
6142 sql = sqlite3_mprintf("select %s as 'TABLE_QUALIFIER', "
6143 "%s as 'TABLE_OWNER', "
6144 "tbl_name as 'TABLE_NAME', "
6145 "'' as 'GRANTOR', "
6146 "'' as 'GRANTEE', "
6147 "'SELECT' AS 'PRIVILEGE', "
6148 "NULL as 'IS_GRANTABLE' "
6149 "from sqlite_master where "
6150 "(type = 'table' or type = 'view') "
6151 "and tbl_name like %Q "
6152 "UNION "
6153 "select %s as 'TABLE_QUALIFIER', "
6154 "%s as 'TABLE_OWNER', "
6155 "tbl_name as 'TABLE_NAME', "
6156 "'' as 'GRANTOR', "
6157 "'' as 'GRANTEE', "
6158 "'UPDATE' AS 'PRIVILEGE', "
6159 "NULL as 'IS_GRANTABLE' "
6160 "from sqlite_master where "
6161 "(type = 'table' or type = 'view') "
6162 "and tbl_name like %Q "
6163 "UNION "
6164 "select %s as 'TABLE_QUALIFIER', "
6165 "%s as 'TABLE_OWNER', "
6166 "tbl_name as 'TABLE_NAME', "
6167 "'' as 'GRANTOR', "
6168 "'' as 'GRANTEE', "
6169 "'DELETE' AS 'PRIVILEGE', "
6170 "NULL as 'IS_GRANTABLE' "
6171 "from sqlite_master where "
6172 "(type = 'table' or type = 'view') "
6173 "and tbl_name like %Q "
6174 "UNION "
6175 "select %s as 'TABLE_QUALIFIER', "
6176 "%s as 'TABLE_OWNER', "
6177 "tbl_name as 'TABLE_NAME', "
6178 "'' as 'GRANTOR', "
6179 "'' as 'GRANTEE', "
6180 "'INSERT' AS 'PRIVILEGE', "
6181 "NULL as 'IS_GRANTABLE' "
6182 "from sqlite_master where "
6183 "(type = 'table' or type = 'view') "
6184 "and tbl_name like %Q "
6185 "UNION "
6186 "select %s as 'TABLE_QUALIFIER', "
6187 "%s as 'TABLE_OWNER', "
6188 "tbl_name as 'TABLE_NAME', "
6189 "'' as 'GRANTOR', "
6190 "'' as 'GRANTEE', "
6191 "'REFERENCES' AS 'PRIVILEGE', "
6192 "NULL as 'IS_GRANTABLE' "
6193 "from sqlite_master where "
6194 "(type = 'table' or type = 'view') "
6195 "and tbl_name like %Q",
6196 d->xcelqrx ? "'main'" : "NULL",
6197 d->xcelqrx ? "''" : "NULL",
6198 tname,
6199 d->xcelqrx ? "'main'" : "NULL",
6200 d->xcelqrx ? "''" : "NULL",
6201 tname,
6202 d->xcelqrx ? "'main'" : "NULL",
6203 d->xcelqrx ? "''" : "NULL",
6204 tname,
6205 d->xcelqrx ? "'main'" : "NULL",
6206 d->xcelqrx ? "''" : "NULL",
6207 tname,
6208 d->xcelqrx ? "'main'" : "NULL",
6209 d->xcelqrx ? "''" : "NULL",
6210 tname);
6211 } else {
6212 sql = sqlite3_mprintf("select %s as 'TABLE_QUALIFIER', "
6213 "%s as 'TABLE_OWNER', "
6214 "tbl_name as 'TABLE_NAME', "
6215 "'' as 'GRANTOR', "
6216 "'' as 'GRANTEE', "
6217 "'SELECT' AS 'PRIVILEGE', "
6218 "NULL as 'IS_GRANTABLE' "
6219 "from sqlite_master where "
6220 "(type = 'table' or type = 'view') "
6221 "and lower(tbl_name) = lower(%Q) "
6222 "UNION "
6223 "select %s as 'TABLE_QUALIFIER', "
6224 "%s as 'TABLE_OWNER', "
6225 "tbl_name as 'TABLE_NAME', "
6226 "'' as 'GRANTOR', "
6227 "'' as 'GRANTEE', "
6228 "'UPDATE' AS 'PRIVILEGE', "
6229 "NULL as 'IS_GRANTABLE' "
6230 "from sqlite_master where "
6231 "(type = 'table' or type = 'view') "
6232 "and lower(tbl_name) = lower(%Q) "
6233 "UNION "
6234 "select %s as 'TABLE_QUALIFIER', "
6235 "%s as 'TABLE_OWNER', "
6236 "tbl_name as 'TABLE_NAME', "
6237 "'' as 'GRANTOR', "
6238 "'' as 'GRANTEE', "
6239 "'DELETE' AS 'PRIVILEGE', "
6240 "NULL as 'IS_GRANTABLE' "
6241 "from sqlite_master where "
6242 "(type = 'table' or type = 'view') "
6243 "and lower(tbl_name) = lower(%Q) "
6244 "UNION "
6245 "select %s as 'TABLE_QUALIFIER', "
6246 "%s as 'TABLE_OWNER', "
6247 "tbl_name as 'TABLE_NAME', "
6248 "'' as 'GRANTOR', "
6249 "'' as 'GRANTEE', "
6250 "'INSERT' AS 'PRIVILEGE', "
6251 "NULL as 'IS_GRANTABLE' "
6252 "from sqlite_master where "
6253 "(type = 'table' or type = 'view') "
6254 "and lower(tbl_name) = lower(%Q) "
6255 "UNION "
6256 "select %s as 'TABLE_QUALIFIER', "
6257 "%s as 'TABLE_OWNER', "
6258 "tbl_name as 'TABLE_NAME', "
6259 "'' as 'GRANTOR', "
6260 "'' as 'GRANTEE', "
6261 "'REFERENCES' AS 'PRIVILEGE', "
6262 "NULL as 'IS_GRANTABLE' "
6263 "from sqlite_master where "
6264 "(type = 'table' or type = 'view') "
6265 "and lower(tbl_name) = lower(%Q)",
6266 d->xcelqrx ? "'main'" : "NULL",
6267 d->xcelqrx ? "''" : "NULL",
6268 tname,
6269 d->xcelqrx ? "'main'" : "NULL",
6270 d->xcelqrx ? "''" : "NULL",
6271 tname,
6272 d->xcelqrx ? "'main'" : "NULL",
6273 d->xcelqrx ? "''" : "NULL",
6274 tname,
6275 d->xcelqrx ? "'main'" : "NULL",
6276 d->xcelqrx ? "''" : "NULL",
6277 tname,
6278 d->xcelqrx ? "'main'" : "NULL",
6279 d->xcelqrx ? "''" : "NULL",
6280 tname);
6281 }
6282#else
6283 if (npatt) {
6284 sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
6285 "NULL as 'TABLE_OWNER', "
6286 "tbl_name as 'TABLE_NAME', "
6287 "'' as 'GRANTOR', "
6288 "'' as 'GRANTEE', "
6289 "'SELECT' AS 'PRIVILEGE', "
6290 "NULL as 'IS_GRANTABLE' "
6291 "from sqlite_master where "
6292 "(type = 'table' or type = 'view') "
6293 "and tbl_name like %Q "
6294 "UNION "
6295 "select NULL as 'TABLE_QUALIFIER', "
6296 "NULL as 'TABLE_OWNER', "
6297 "tbl_name as 'TABLE_NAME', "
6298 "'' as 'GRANTOR', "
6299 "'' as 'GRANTEE', "
6300 "'UPDATE' AS 'PRIVILEGE', "
6301 "NULL as 'IS_GRANTABLE' "
6302 "from sqlite_master where "
6303 "(type = 'table' or type = 'view') "
6304 "and tbl_name like %Q "
6305 "UNION "
6306 "select NULL as 'TABLE_QUALIFIER', "
6307 "NULL as 'TABLE_OWNER', "
6308 "tbl_name as 'TABLE_NAME', "
6309 "'' as 'GRANTOR', "
6310 "'' as 'GRANTEE', "
6311 "'DELETE' AS 'PRIVILEGE', "
6312 "NULL as 'IS_GRANTABLE' "
6313 "from sqlite_master where "
6314 "(type = 'table' or type = 'view') "
6315 "and tbl_name like %Q "
6316 "UNION "
6317 "select NULL as 'TABLE_QUALIFIER', "
6318 "NULL as 'TABLE_OWNER', "
6319 "tbl_name as 'TABLE_NAME', "
6320 "'' as 'GRANTOR', "
6321 "'' as 'GRANTEE', "
6322 "'INSERT' AS 'PRIVILEGE', "
6323 "NULL as 'IS_GRANTABLE' "
6324 "from sqlite_master where "
6325 "(type = 'table' or type = 'view') "
6326 "and tbl_name like %Q "
6327 "UNION "
6328 "select NULL as 'TABLE_QUALIFIER', "
6329 "NULL as 'TABLE_OWNER', "
6330 "tbl_name as 'TABLE_NAME', "
6331 "'' as 'GRANTOR', "
6332 "'' as 'GRANTEE', "
6333 "'REFERENCES' AS 'PRIVILEGE', "
6334 "NULL as 'IS_GRANTABLE' "
6335 "from sqlite_master where "
6336 "(type = 'table' or type = 'view') "
6337 "and tbl_name like %Q",
6338 tname, tname, tname, tname, tname);
6339 } else {
6340 sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
6341 "NULL as 'TABLE_OWNER', "
6342 "tbl_name as 'TABLE_NAME', "
6343 "'' as 'GRANTOR', "
6344 "'' as 'GRANTEE', "
6345 "'SELECT' AS 'PRIVILEGE', "
6346 "NULL as 'IS_GRANTABLE' "
6347 "from sqlite_master where "
6348 "(type = 'table' or type = 'view') "
6349 "and lower(tbl_name) = lower(%Q) "
6350 "UNION "
6351 "select NULL as 'TABLE_QUALIFIER', "
6352 "NULL as 'TABLE_OWNER', "
6353 "tbl_name as 'TABLE_NAME', "
6354 "'' as 'GRANTOR', "
6355 "'' as 'GRANTEE', "
6356 "'UPDATE' AS 'PRIVILEGE', "
6357 "NULL as 'IS_GRANTABLE' "
6358 "from sqlite_master where "
6359 "(type = 'table' or type = 'view') "
6360 "and lower(tbl_name) = lower(%Q) "
6361 "UNION "
6362 "select NULL as 'TABLE_QUALIFIER', "
6363 "NULL as 'TABLE_OWNER', "
6364 "tbl_name as 'TABLE_NAME', "
6365 "'' as 'GRANTOR', "
6366 "'' as 'GRANTEE', "
6367 "'DELETE' AS 'PRIVILEGE', "
6368 "NULL as 'IS_GRANTABLE' "
6369 "from sqlite_master where "
6370 "(type = 'table' or type = 'view') "
6371 "and lower(tbl_name) = lower(%Q) "
6372 "UNION "
6373 "select NULL as 'TABLE_QUALIFIER', "
6374 "NULL as 'TABLE_OWNER', "
6375 "tbl_name as 'TABLE_NAME', "
6376 "'' as 'GRANTOR', "
6377 "'' as 'GRANTEE', "
6378 "'INSERT' AS 'PRIVILEGE', "
6379 "NULL as 'IS_GRANTABLE' "
6380 "from sqlite_master where "
6381 "(type = 'table' or type = 'view') "
6382 "and lower(tbl_name) = lower(%Q) "
6383 "UNION "
6384 "select NULL as 'TABLE_QUALIFIER', "
6385 "NULL as 'TABLE_OWNER', "
6386 "tbl_name as 'TABLE_NAME', "
6387 "'' as 'GRANTOR', "
6388 "'' as 'GRANTEE', "
6389 "'REFERENCES' AS 'PRIVILEGE', "
6390 "NULL as 'IS_GRANTABLE' "
6391 "from sqlite_master where "
6392 "(type = 'table' or type = 'view') "
6393 "and lower(tbl_name) = lower(%Q)",
6394 tname, tname, tname, tname, tname);
6395 }
6396#endif
6397 if (!sql) {
6398 return nomem(s);
6399 }
6400 ret = starttran(s);
6401 if (ret != SQL_SUCCESS) {
6402 sqlite3_free(sql);
6403 return ret;
6404 }
6405 dbtraceapi(d, "sqlite3_get_table", sql);
6406 rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
6407 sqlite3_free(sql);
6408 if (rc == SQLITE_OK) {
6409 if (ncols != s->ncols) {
6410 freeresult(s, 0);
6411 s->nrows = 0;
6412 } else {
6413 s->rowfree = sqlite3_free_table;
6414 }
6415 } else {
6416 s->nrows = 0;
6417 s->rows = NULL;
6418 s->rowfree = NULL;
6419 }
6420 if (errp) {
6421 sqlite3_free(errp);
6422 errp = NULL;
6423 }
6424 s->rowp = s->rowprs = -1;
6425 return SQL_SUCCESS;
6426}
6427
6428
6429#if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
6442SQLRETURN SQL_API
6443SQLTablePrivileges(SQLHSTMT stmt,
6444 SQLCHAR *catalog, SQLSMALLINT catalogLen,
6445 SQLCHAR *schema, SQLSMALLINT schemaLen,
6446 SQLCHAR *table, SQLSMALLINT tableLen)
6447{
6448#if defined(_WIN32) || defined(_WIN64)
6449 char *c = NULL, *s = NULL, *t = NULL;
6450#endif
6451 SQLRETURN ret;
6452
6454#if defined(_WIN32) || defined(_WIN64)
6455 if (!((STMT *) stmt)->oemcp[0]) {
6456 ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
6457 table, tableLen);
6458 goto done2;
6459 }
6460 if (catalog) {
6461 c = wmb_to_utf_c((char *) catalog, catalogLen);
6462 if (!c) {
6463 ret = nomem((STMT *) stmt);
6464 goto done;
6465 }
6466 }
6467 if (schema) {
6468 s = wmb_to_utf_c((char *) schema, schemaLen);
6469 if (!s) {
6470 ret = nomem((STMT *) stmt);
6471 goto done;
6472 }
6473 }
6474 if (table) {
6475 t = wmb_to_utf_c((char *) table, tableLen);
6476 if (!t) {
6477 ret = nomem((STMT *) stmt);
6478 goto done;
6479 }
6480 }
6481 ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
6482 (SQLCHAR *) s, SQL_NTS,
6483 (SQLCHAR *) t, SQL_NTS);
6484#else
6485 ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
6486 table, tableLen);
6487#endif
6488#if defined(_WIN32) || defined(_WIN64)
6489done:
6490 uc_free(t);
6491 uc_free(s);
6492 uc_free(c);
6493done2:
6494 ;
6495#endif
6497 return ret;
6498}
6499#endif
6500
6501#if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
6502#ifdef WINTERFACE
6515SQLRETURN SQL_API
6517 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
6518 SQLWCHAR *schema, SQLSMALLINT schemaLen,
6519 SQLWCHAR *table, SQLSMALLINT tableLen)
6520{
6521 char *c = NULL, *s = NULL, *t = NULL;
6522 SQLRETURN ret;
6523
6525 if (catalog) {
6526 c = uc_to_utf_c(catalog, catalogLen);
6527 if (!c) {
6528 ret = nomem((STMT *) stmt);
6529 goto done;
6530 }
6531 }
6532 if (schema) {
6533 s = uc_to_utf_c(schema, schemaLen);
6534 if (!s) {
6535 ret = nomem((STMT *) stmt);
6536 goto done;
6537 }
6538 }
6539 if (table) {
6540 t = uc_to_utf_c(table, tableLen);
6541 if (!t) {
6542 ret = nomem((STMT *) stmt);
6543 goto done;
6544 }
6545 }
6546 ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
6547 (SQLCHAR *) s, SQL_NTS,
6548 (SQLCHAR *) t, SQL_NTS);
6549done:
6550 uc_free(t);
6551 uc_free(s);
6552 uc_free(c);
6554 return ret;
6555}
6556#endif
6557#endif
6558
6563static COL colPrivSpec2[] = {
6564 { "SYSTEM", "COLPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
6565 { "SYSTEM", "COLPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
6566 { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6567 { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6568 { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6569 { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6570 { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
6571};
6572
6573static COL colPrivSpec3[] = {
6574 { "SYSTEM", "COLPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
6575 { "SYSTEM", "COLPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
6576 { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6577 { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6578 { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6579 { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6580 { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
6581};
6582
6583#if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
6598SQLRETURN SQL_API
6599SQLColumnPrivileges(SQLHSTMT stmt,
6600 SQLCHAR *catalog, SQLSMALLINT catalogLen,
6601 SQLCHAR *schema, SQLSMALLINT schemaLen,
6602 SQLCHAR *table, SQLSMALLINT tableLen,
6603 SQLCHAR *column, SQLSMALLINT columnLen)
6604{
6605 SQLRETURN ret;
6606
6611 return ret;
6612}
6613#endif
6614
6615#if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
6616#ifdef WINTERFACE
6631SQLRETURN SQL_API
6633 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
6634 SQLWCHAR *schema, SQLSMALLINT schemaLen,
6635 SQLWCHAR *table, SQLSMALLINT tableLen,
6636 SQLWCHAR *column, SQLSMALLINT columnLen)
6637{
6638 SQLRETURN ret;
6639
6644 return ret;
6645}
6646#endif
6647#endif
6648
6653static COL pkeySpec2[] = {
6654 { "SYSTEM", "PRIMARYKEY", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
6655 { "SYSTEM", "PRIMARYKEY", "TABLE_OWNER", SCOL_VARCHAR, 50 },
6656 { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
6657 { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6658 { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
6659 { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
6660};
6661
6662static COL pkeySpec3[] = {
6663 { "SYSTEM", "PRIMARYKEY", "TABLE_CAT", SCOL_VARCHAR, 50 },
6664 { "SYSTEM", "PRIMARYKEY", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
6665 { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
6666 { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6667 { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
6668 { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
6669};
6670
6683static SQLRETURN
6685 SQLCHAR *cat, SQLSMALLINT catLen,
6686 SQLCHAR *schema, SQLSMALLINT schemaLen,
6687 SQLCHAR *table, SQLSMALLINT tableLen)
6688{
6689 STMT *s;
6690 DBC *d;
6691 SQLRETURN sret;
6692 int i, asize, ret, nrows, ncols, nrows2 = 0, ncols2 = 0;
6693 int namec = -1, uniquec = -1, namec2 = -1, uniquec2 = -1, offs, seq = 1;
6694 PTRDIFF_T size;
6695 char **rowp = NULL, **rowp2 = NULL, *errp = NULL, *sql, tname[512];
6696
6698 pkeySpec3, array_size(pkeySpec3), &asize);
6699 if (sret != SQL_SUCCESS) {
6700 return sret;
6701 }
6702 s = (STMT *) stmt;
6703 d = (DBC *) s->dbc;
6704 if (!table || table[0] == '\0' || table[0] == '%') {
6705 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
6706 return SQL_ERROR;
6707 }
6708 if (tableLen == SQL_NTS) {
6709 size = sizeof (tname) - 1;
6710 } else {
6711 size = min(sizeof (tname) - 1, tableLen);
6712 }
6713 strncpy(tname, (char *) table, size);
6714 tname[size] = '\0';
6715 unescpat(tname);
6716 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
6717 if (!sql) {
6718 return nomem(s);
6719 }
6720 sret = starttran(s);
6721 if (sret != SQL_SUCCESS) {
6722 sqlite3_free(sql);
6723 return sret;
6724 }
6725 dbtraceapi(d, "sqlite3_get_table", sql);
6726 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
6727 sqlite3_free(sql);
6728 if (ret != SQLITE_OK) {
6729 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6730 errp ? errp : "unknown error", ret);
6731 if (errp) {
6732 sqlite3_free(errp);
6733 errp = NULL;
6734 }
6735 return SQL_ERROR;
6736 }
6737 if (errp) {
6738 sqlite3_free(errp);
6739 errp = NULL;
6740 }
6741 size = 0;
6742 if (ncols * nrows > 0) {
6743 int typec;
6744
6745 namec = findcol(rowp, ncols, "name");
6746 uniquec = findcol(rowp, ncols, "pk");
6747 typec = findcol(rowp, ncols, "type");
6748 if (namec >= 0 && uniquec >= 0 && typec >= 0) {
6749 for (i = 1; i <= nrows; i++) {
6750 if (*rowp[i * ncols + uniquec] != '0') {
6751 size++;
6752 }
6753 }
6754 }
6755 }
6756 if (size == 0) {
6757 sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
6758 if (!sql) {
6759 sqlite3_free_table(rowp);
6760 return nomem(s);
6761 }
6762 dbtraceapi(d, "sqlite3_get_table", sql);
6763 ret = sqlite3_get_table(d->sqlite, sql, &rowp2, &nrows2, &ncols2,
6764 &errp);
6765 sqlite3_free(sql);
6766 if (ret != SQLITE_OK) {
6767 sqlite3_free_table(rowp);
6768 sqlite3_free_table(rowp2);
6769 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6770 errp ? errp : "unknown error", ret);
6771 if (errp) {
6772 sqlite3_free(errp);
6773 errp = NULL;
6774 }
6775 return SQL_ERROR;
6776 }
6777 if (errp) {
6778 sqlite3_free(errp);
6779 errp = NULL;
6780 }
6781 }
6782 if (ncols2 * nrows2 > 0) {
6783 namec2 = findcol(rowp2, ncols2, "name");
6784 uniquec2 = findcol(rowp2, ncols2, "unique");
6785 if (namec2 >= 0 && uniquec2 >= 0) {
6786 for (i = 1; i <= nrows2; i++) {
6787 int nnrows, nncols, nlen = 0;
6788 char **rowpp;
6789
6790 if (rowp2[i * ncols2 + namec2]) {
6791 nlen = strlen(rowp2[i * ncols2 + namec2]);
6792 }
6793 if (nlen < 17 ||
6794 strncmp(rowp2[i * ncols2 + namec2],
6795 "sqlite_autoindex_", 17)) {
6796 continue;
6797 }
6798 if (*rowp2[i * ncols2 + uniquec2] != '0') {
6799 ret = SQLITE_ERROR;
6800 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6801 rowp2[i * ncols2 + namec2]);
6802 if (sql) {
6803 dbtraceapi(d, "sqlite3_get_table", sql);
6804 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6805 &nnrows, &nncols, NULL);
6806 sqlite3_free(sql);
6807 }
6808 if (ret == SQLITE_OK) {
6809 size += nnrows;
6810 sqlite3_free_table(rowpp);
6811 }
6812 }
6813 }
6814 }
6815 }
6816 if (size == 0) {
6817 sqlite3_free_table(rowp);
6818 sqlite3_free_table(rowp2);
6819 return SQL_SUCCESS;
6820 }
6821 s->nrows = size;
6822 size = (size + 1) * asize;
6823 s->rows = xmalloc((size + 1) * sizeof (char *));
6824 if (!s->rows) {
6825 s->nrows = 0;
6826 sqlite3_free_table(rowp);
6827 sqlite3_free_table(rowp2);
6828 return nomem(s);
6829 }
6830 s->rows[0] = (char *) size;
6831 s->rows += 1;
6832 memset(s->rows, 0, sizeof (char *) * size);
6833 s->rowfree = freerows;
6834 offs = s->ncols;
6835 if (rowp) {
6836 for (i = 1; i <= nrows; i++) {
6837 if (*rowp[i * ncols + uniquec] != '0') {
6838 char buf[32];
6839
6840#if defined(_WIN32) || defined(_WIN64)
6841 s->rows[offs + 0] = xstrdup(d->xcelqrx ? "main" : "");
6842 s->rows[offs + 1] = xstrdup("");
6843#else
6844 s->rows[offs + 0] = xstrdup("");
6845 s->rows[offs + 1] = xstrdup("");
6846#endif
6847 s->rows[offs + 2] = xstrdup(tname);
6848 s->rows[offs + 3] = xstrdup(rowp[i * ncols + namec]);
6849 sprintf(buf, "%d", seq++);
6850 s->rows[offs + 4] = xstrdup(buf);
6851 offs += s->ncols;
6852 }
6853 }
6854 }
6855 if (rowp2) {
6856 for (i = 1; i <= nrows2; i++) {
6857 int nnrows, nncols, nlen = 0;
6858 char **rowpp;
6859
6860 if (rowp2[i * ncols2 + namec2]) {
6861 nlen = strlen(rowp2[i * ncols2 + namec2]);
6862 }
6863 if (nlen < 17 ||
6864 strncmp(rowp2[i * ncols2 + namec2], "sqlite_autoindex_", 17)) {
6865 continue;
6866 }
6867 if (*rowp2[i * ncols2 + uniquec2] != '0') {
6868 int k;
6869
6870 ret = SQLITE_ERROR;
6871 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6872 rowp2[i * ncols2 + namec2]);
6873 if (sql) {
6874 dbtraceapi(d, "sqlite3_get_table", sql);
6875 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6876 &nnrows, &nncols, NULL);
6877 sqlite3_free(sql);
6878 }
6879 if (ret != SQLITE_OK) {
6880 continue;
6881 }
6882 for (k = 0; nnrows && k < nncols; k++) {
6883 if (strcmp(rowpp[k], "name") == 0) {
6884 int m;
6885
6886 for (m = 1; m <= nnrows; m++) {
6887 int roffs = offs + (m - 1) * s->ncols;
6888
6889#if defined(_WIN32) || defined(_WIN64)
6890 s->rows[roffs + 0] =
6891 xstrdup(d->xcelqrx ? "main" : "");
6892 s->rows[roffs + 1] = xstrdup("");
6893#else
6894 s->rows[roffs + 0] = xstrdup("");
6895 s->rows[roffs + 1] = xstrdup("");
6896#endif
6897 s->rows[roffs + 2] = xstrdup(tname);
6898 s->rows[roffs + 3] =
6899 xstrdup(rowpp[m * nncols + k]);
6900 s->rows[roffs + 5] =
6901 xstrdup(rowp2[i * ncols2 + namec2]);
6902 }
6903 } else if (strcmp(rowpp[k], "seqno") == 0) {
6904 int m;
6905
6906 for (m = 1; m <= nnrows; m++) {
6907 int roffs = offs + (m - 1) * s->ncols;
6908 int pos = m - 1;
6909 char buf[32];
6910
6911 sscanf(rowpp[m * nncols + k], "%d", &pos);
6912 sprintf(buf, "%d", pos + 1);
6913 s->rows[roffs + 4] = xstrdup(buf);
6914 }
6915 }
6916 }
6917 offs += nnrows * s->ncols;
6918 sqlite3_free_table(rowpp);
6919 }
6920 }
6921 }
6922 sqlite3_free_table(rowp);
6923 sqlite3_free_table(rowp2);
6924 return SQL_SUCCESS;
6925}
6926
6927#ifndef WINTERFACE
6940SQLRETURN SQL_API
6941SQLPrimaryKeys(SQLHSTMT stmt,
6942 SQLCHAR *cat, SQLSMALLINT catLen,
6943 SQLCHAR *schema, SQLSMALLINT schemaLen,
6944 SQLCHAR *table, SQLSMALLINT tableLen)
6945{
6946#if defined(_WIN32) || defined(_WIN64)
6947 char *c = NULL, *s = NULL, *t = NULL;
6948#endif
6949 SQLRETURN ret;
6950
6952#if defined(_WIN32) || defined(_WIN64)
6953 if (!((STMT *) stmt)->oemcp[0]) {
6954 ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
6955 table, tableLen);
6956 goto done2;
6957 }
6958 if (cat) {
6959 c = wmb_to_utf_c((char *) cat, catLen);
6960 if (!c) {
6961 ret = nomem((STMT *) stmt);
6962 goto done;
6963 }
6964 }
6965 if (schema) {
6966 s = wmb_to_utf_c((char *) schema, schemaLen);
6967 if (!s) {
6968 ret = nomem((STMT *) stmt);
6969 goto done;
6970 }
6971 }
6972 if (table) {
6973 t = wmb_to_utf_c((char *) table, tableLen);
6974 if (!t) {
6975 ret = nomem((STMT *) stmt);
6976 goto done;
6977 }
6978 }
6979 ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
6980 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
6981#else
6982 ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
6983 table, tableLen);
6984#endif
6985#if defined(_WIN32) || defined(_WIN64)
6986done:
6987 uc_free(t);
6988 uc_free(s);
6989 uc_free(c);
6990done2:
6991 ;
6992#endif
6994 return ret;
6995}
6996#endif
6997
6998#ifdef WINTERFACE
7011SQLRETURN SQL_API
7013 SQLWCHAR *cat, SQLSMALLINT catLen,
7014 SQLWCHAR *schema, SQLSMALLINT schemaLen,
7015 SQLWCHAR *table, SQLSMALLINT tableLen)
7016{
7017 char *c = NULL, *s = NULL, *t = NULL;
7018 SQLRETURN ret;
7019
7021 if (cat) {
7022 c = uc_to_utf_c(cat, catLen);
7023 if (!c) {
7024 ret = nomem((STMT *) stmt);
7025 goto done;
7026 }
7027 }
7028 if (schema) {
7029 s = uc_to_utf_c(schema, schemaLen);
7030 if (!s) {
7031 ret = nomem((STMT *) stmt);
7032 goto done;
7033 }
7034 }
7035 if (table) {
7036 t = uc_to_utf_c(table, tableLen);
7037 if (!t) {
7038 ret = nomem((STMT *) stmt);
7039 goto done;
7040 }
7041 }
7042 ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
7043 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
7044done:
7045 uc_free(t);
7046 uc_free(s);
7047 uc_free(c);
7049 return ret;
7050}
7051#endif
7052
7057static COL scolSpec2[] = {
7058 { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
7059 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
7060 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
7061 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
7062 { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
7063 { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
7064 { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
7065 { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
7066 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
7067};
7068
7069static COL scolSpec3[] = {
7070 { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
7071 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
7072 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
7073 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
7074 { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
7075 { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
7076 { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
7077 { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
7078 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
7079};
7080
7096static SQLRETURN
7097drvspecialcolumns(SQLHSTMT stmt, SQLUSMALLINT id,
7098 SQLCHAR *cat, SQLSMALLINT catLen,
7099 SQLCHAR *schema, SQLSMALLINT schemaLen,
7100 SQLCHAR *table, SQLSMALLINT tableLen,
7101 SQLUSMALLINT scope, SQLUSMALLINT nullable)
7102{
7103 STMT *s;
7104 DBC *d;
7105 SQLRETURN sret;
7106 int i, asize, ret, nrows, ncols, nnnrows, nnncols, offs;
7107 PTRDIFF_T size;
7108 int namec = -1, uniquec = -1, namecc = -1, typecc = -1;
7109 int notnullcc = -1, mkrowid = 0;
7110 char *errp = NULL, *sql, tname[512];
7111 char **rowp = NULL, **rowppp = NULL;
7112
7114 scolSpec3, array_size(scolSpec3), &asize);
7115 if (sret != SQL_SUCCESS) {
7116 return sret;
7117 }
7118 s = (STMT *) stmt;
7119 d = (DBC *) s->dbc;
7120 if (!table || table[0] == '\0' || table[0] == '%') {
7121 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
7122 return SQL_ERROR;
7123 }
7124 if (tableLen == SQL_NTS) {
7125 size = sizeof (tname) - 1;
7126 } else {
7127 size = min(sizeof (tname) - 1, tableLen);
7128 }
7129 strncpy(tname, (char *) table, size);
7130 tname[size] = '\0';
7131 unescpat(tname);
7132 if (id != SQL_BEST_ROWID) {
7133 return SQL_SUCCESS;
7134 }
7135 sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
7136 if (!sql) {
7137 return nomem(s);
7138 }
7139 sret = starttran(s);
7140 if (sret != SQL_SUCCESS) {
7141 sqlite3_free(sql);
7142 return sret;
7143 }
7144 dbtraceapi(d, "sqlite3_get_table", sql);
7145 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
7146 sqlite3_free(sql);
7147 if (ret != SQLITE_OK) {
7148doerr:
7149 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7150 errp ? errp : "unknown error", ret);
7151 if (errp) {
7152 sqlite3_free(errp);
7153 errp = NULL;
7154 }
7155 return SQL_ERROR;
7156 }
7157 if (errp) {
7158 sqlite3_free(errp);
7159 errp = NULL;
7160 }
7161 size = 0; /* number result rows */
7162 if (ncols * nrows <= 0) {
7163 goto nodata_but_rowid;
7164 }
7165 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
7166 if (!sql) {
7167 return nomem(s);
7168 }
7169 dbtraceapi(d, "sqlite3_get_table", sql);
7170 ret = sqlite3_get_table(d->sqlite, sql, &rowppp, &nnnrows, &nnncols,
7171 &errp);
7172 sqlite3_free(sql);
7173 if (ret != SQLITE_OK) {
7174 sqlite3_free_table(rowp);
7175 goto doerr;
7176 }
7177 if (errp) {
7178 sqlite3_free(errp);
7179 errp = NULL;
7180 }
7181 namec = findcol(rowp, ncols, "name");
7182 uniquec = findcol(rowp, ncols, "unique");
7183 if (namec < 0 || uniquec < 0) {
7184 goto nodata_but_rowid;
7185 }
7186 namecc = findcol(rowppp, nnncols, "name");
7187 typecc = findcol(rowppp, nnncols, "type");
7188 notnullcc = findcol(rowppp, nnncols, "notnull");
7189 for (i = 1; i <= nrows; i++) {
7190 int nnrows, nncols;
7191 char **rowpp = NULL;
7192
7193 if (*rowp[i * ncols + uniquec] != '0') {
7194 ret = SQLITE_ERROR;
7195 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
7196 rowp[i * ncols + namec]);
7197 if (sql) {
7198 dbtraceapi(d, "sqlite3_get_table", sql);
7199 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7200 &nnrows, &nncols, NULL);
7201 sqlite3_free(sql);
7202 }
7203 if (ret == SQLITE_OK) {
7204 size += nnrows;
7205 sqlite3_free_table(rowpp);
7206 }
7207 }
7208 }
7209nodata_but_rowid:
7210 if (size == 0) {
7211 size = 1;
7212 mkrowid = 1;
7213 }
7214 s->nrows = size;
7215 size = (size + 1) * asize;
7216 s->rows = xmalloc((size + 1) * sizeof (char *));
7217 if (!s->rows) {
7218 s->nrows = 0;
7219 sqlite3_free_table(rowp);
7220 sqlite3_free_table(rowppp);
7221 return nomem(s);
7222 }
7223 s->rows[0] = (char *) size;
7224 s->rows += 1;
7225 memset(s->rows, 0, sizeof (char *) * size);
7226 s->rowfree = freerows;
7227 if (mkrowid) {
7228 s->nrows = 0;
7229 goto mkrowid;
7230 }
7231 offs = 0;
7232 for (i = 1; i <= nrows; i++) {
7233 int nnrows, nncols;
7234 char **rowpp = NULL;
7235
7236 if (*rowp[i * ncols + uniquec] != '0') {
7237 int k;
7238
7239 ret = SQLITE_ERROR;
7240 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
7241 rowp[i * ncols + namec]);
7242 if (sql) {
7243 dbtraceapi(d, "sqlite3_get_table", sql);
7244 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7245 &nnrows, &nncols, NULL);
7246 sqlite3_free(sql);
7247 }
7248 if (ret != SQLITE_OK) {
7249 continue;
7250 }
7251 for (k = 0; nnrows && k < nncols; k++) {
7252 if (strcmp(rowpp[k], "name") == 0) {
7253 int m;
7254
7255 for (m = 1; m <= nnrows; m++) {
7256 int roffs = (offs + m) * s->ncols;
7257
7258 s->rows[roffs + 0] =
7259 xstrdup(stringify(SQL_SCOPE_SESSION));
7260 s->rows[roffs + 1] = xstrdup(rowpp[m * nncols + k]);
7261 s->rows[roffs + 4] = xstrdup("0");
7262 s->rows[roffs + 7] =
7263 xstrdup(stringify(SQL_PC_NOT_PSEUDO));
7264 if (namecc >= 0 && typecc >= 0) {
7265 int ii;
7266
7267 for (ii = 1; ii <= nnnrows; ii++) {
7268 if (strcmp(rowppp[ii * nnncols + namecc],
7269 rowpp[m * nncols + k]) == 0) {
7270 char *typen = rowppp[ii * nnncols + typecc];
7271 int sqltype, mm, dd, isnullable = 0;
7272 char buf[32];
7273
7274 s->rows[roffs + 3] = xstrdup(typen);
7275 sqltype = mapsqltype(typen, NULL, *s->ov3,
7276 s->nowchar[0],
7277 s->dobigint);
7278 getmd(typen, sqltype, &mm, &dd);
7279#ifdef SQL_LONGVARCHAR
7280 if (sqltype == SQL_VARCHAR && mm > 255) {
7281 sqltype = SQL_LONGVARCHAR;
7282 }
7283#endif
7284#ifdef WINTERFACE
7285#ifdef SQL_WLONGVARCHAR
7286 if (sqltype == SQL_WVARCHAR && mm > 255) {
7287 sqltype = SQL_WLONGVARCHAR;
7288 }
7289#endif
7290#endif
7291 if (sqltype == SQL_VARBINARY && mm > 255) {
7292 sqltype = SQL_LONGVARBINARY;
7293 }
7294 sprintf(buf, "%d", sqltype);
7295 s->rows[roffs + 2] = xstrdup(buf);
7296 sprintf(buf, "%d", mm);
7297 s->rows[roffs + 5] = xstrdup(buf);
7298 sprintf(buf, "%d", dd);
7299 s->rows[roffs + 6] = xstrdup(buf);
7300 if (notnullcc >= 0) {
7301 char *inp =
7302 rowppp[ii * nnncols + notnullcc];
7303
7304 isnullable = inp[0] != '0';
7305 }
7306 sprintf(buf, "%d", isnullable);
7307 s->rows[roffs + 8] = xstrdup(buf);
7308 }
7309 }
7310 }
7311 }
7312 }
7313 }
7314 offs += nnrows;
7315 sqlite3_free_table(rowpp);
7316 }
7317 }
7318 if (nullable == SQL_NO_NULLS) {
7319 for (i = 1; i < s->nrows; i++) {
7320 if (s->rows[i * s->ncols + 8][0] == '0') {
7321 int m, i1 = i + 1;
7322
7323 for (m = 0; m < s->ncols; m++) {
7324 freep(&s->rows[i * s->ncols + m]);
7325 }
7326 size = s->ncols * sizeof (char *) * (s->nrows - i1);
7327 if (size > 0) {
7328 memmove(s->rows + i * s->ncols,
7329 s->rows + i1 * s->ncols,
7330 size);
7331 memset(s->rows + s->nrows * s->ncols, 0,
7332 s->ncols * sizeof (char *));
7333 }
7334 s->nrows--;
7335 --i;
7336 }
7337 }
7338 }
7339mkrowid:
7340 sqlite3_free_table(rowp);
7341 sqlite3_free_table(rowppp);
7342 if (s->nrows == 0) {
7343 s->rows[s->ncols + 0] = xstrdup(stringify(SQL_SCOPE_SESSION));
7344 s->rows[s->ncols + 1] = xstrdup("_ROWID_");
7345 s->rows[s->ncols + 2] = xstrdup(stringify(SQL_INTEGER));
7346 s->rows[s->ncols + 3] = xstrdup("integer");
7347 s->rows[s->ncols + 4] = xstrdup("0");
7348 s->rows[s->ncols + 5] = xstrdup("10");
7349 s->rows[s->ncols + 6] = xstrdup("9");
7350 s->rows[s->ncols + 7] = xstrdup(stringify(SQL_PC_PSEUDO));
7351 s->rows[s->ncols + 8] = xstrdup(stringify(SQL_FALSE));
7352 s->nrows = 1;
7353 }
7354 return SQL_SUCCESS;
7355}
7356
7357#ifndef WINTERFACE
7373SQLRETURN SQL_API
7374SQLSpecialColumns(SQLHSTMT stmt, SQLUSMALLINT id,
7375 SQLCHAR *cat, SQLSMALLINT catLen,
7376 SQLCHAR *schema, SQLSMALLINT schemaLen,
7377 SQLCHAR *table, SQLSMALLINT tableLen,
7378 SQLUSMALLINT scope, SQLUSMALLINT nullable)
7379{
7380#if defined(_WIN32) || defined(_WIN64)
7381 char *c = NULL, *s = NULL, *t = NULL;
7382#endif
7383 SQLRETURN ret;
7384
7386#if defined(_WIN32) || defined(_WIN64)
7387 if (!((STMT *) stmt)->oemcp[0]) {
7388 ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
7389 table, tableLen, scope, nullable);
7390 goto done2;
7391 }
7392 if (cat) {
7393 c = wmb_to_utf_c((char *) cat, catLen);
7394 if (!c) {
7395 ret = nomem((STMT *) stmt);
7396 goto done;
7397 }
7398 }
7399 if (schema) {
7400 s = wmb_to_utf_c((char *) schema, schemaLen);
7401 if (!s) {
7402 ret = nomem((STMT *) stmt);
7403 goto done;
7404 }
7405 }
7406 if (table) {
7407 t = wmb_to_utf_c((char *) table, tableLen);
7408 if (!t) {
7409 ret = nomem((STMT *) stmt);
7410 goto done;
7411 }
7412 }
7413 ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
7414 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
7415 scope, nullable);
7416#else
7417 ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
7418 table, tableLen, scope, nullable);
7419#endif
7420#if defined(_WIN32) || defined(_WIN64)
7421done:
7422 uc_free(t);
7423 uc_free(s);
7424 uc_free(c);
7425done2:
7426 ;
7427#endif
7429 return ret;
7430}
7431#endif
7432
7433#ifdef WINTERFACE
7449SQLRETURN SQL_API
7450SQLSpecialColumnsW(SQLHSTMT stmt, SQLUSMALLINT id,
7451 SQLWCHAR *cat, SQLSMALLINT catLen,
7452 SQLWCHAR *schema, SQLSMALLINT schemaLen,
7453 SQLWCHAR *table, SQLSMALLINT tableLen,
7454 SQLUSMALLINT scope, SQLUSMALLINT nullable)
7455{
7456 char *c = NULL, *s = NULL, *t = NULL;
7457 SQLRETURN ret;
7458
7460 if (cat) {
7461 c = uc_to_utf_c(cat, catLen);
7462 if (!c) {
7463 ret = nomem((STMT *) stmt);
7464 goto done;
7465 }
7466 }
7467 if (schema) {
7468 s = uc_to_utf_c(schema, schemaLen);
7469 if (!s) {
7470 ret = nomem((STMT *) stmt);
7471 goto done;
7472 }
7473 }
7474 if (table) {
7475 t = uc_to_utf_c(table, tableLen);
7476 if (!t) {
7477 ret = nomem((STMT *) stmt);
7478 goto done;
7479 }
7480 }
7481 ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
7482 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
7483 scope, nullable);
7484done:
7485 uc_free(t);
7486 uc_free(s);
7487 uc_free(c);
7489 return ret;
7490}
7491#endif
7492
7497static COL fkeySpec2[] = {
7498 { "SYSTEM", "FOREIGNKEY", "PKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
7499 { "SYSTEM", "FOREIGNKEY", "PKTABLE_OWNER", SCOL_VARCHAR, 50 },
7500 { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
7501 { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7502 { "SYSTEM", "FOREIGNKEY", "FKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
7503 { "SYSTEM", "FOREIGNKEY", "FKTABLE_OWNER", SCOL_VARCHAR, 50 },
7504 { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
7505 { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7506 { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
7507 { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
7508 { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
7509 { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
7510 { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
7511 { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
7512};
7513
7514static COL fkeySpec3[] = {
7515 { "SYSTEM", "FOREIGNKEY", "PKTABLE_CAT", SCOL_VARCHAR, 50 },
7516 { "SYSTEM", "FOREIGNKEY", "PKTABLE_SCHEM", SCOL_VARCHAR, 50 },
7517 { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
7518 { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7519 { "SYSTEM", "FOREIGNKEY", "FKTABLE_CAT", SCOL_VARCHAR, 50 },
7520 { "SYSTEM", "FOREIGNKEY", "FKTABLE_SCHEM", SCOL_VARCHAR, 50 },
7521 { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
7522 { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7523 { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
7524 { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
7525 { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
7526 { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
7527 { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
7528 { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
7529};
7530
7549static SQLRETURN SQL_API
7551 SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7552 SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
7553 SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
7554 SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7555 SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
7556 SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
7557{
7558 STMT *s;
7559 DBC *d;
7560 SQLRETURN sret;
7561 int i, asize, ret, nrows, ncols, offs, namec, seqc, fromc, toc;
7562 int onu, ond;
7563 PTRDIFF_T size;
7564 char **rowp, *errp = NULL, *sql, pname[512], fname[512];
7565
7567 fkeySpec3, array_size(fkeySpec3), &asize);
7568 if (sret != SQL_SUCCESS) {
7569 return sret;
7570 }
7571 s = (STMT *) stmt;
7572 sret = starttran(s);
7573 if (sret != SQL_SUCCESS) {
7574 return sret;
7575 }
7576 d = (DBC *) s->dbc;
7577 if ((!PKtable || PKtable[0] == '\0' || PKtable[0] == '%') &&
7578 (!FKtable || FKtable[0] == '\0' || FKtable[0] == '%')) {
7579 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
7580 return SQL_ERROR;
7581 }
7582 size = 0;
7583 if (PKtable) {
7584 if (PKtableLen == SQL_NTS) {
7585 size = sizeof (pname) - 1;
7586 } else {
7587 size = min(sizeof (pname) - 1, PKtableLen);
7588 }
7589 strncpy(pname, (char *) PKtable, size);
7590 }
7591 pname[size] = '\0';
7592 size = 0;
7593 if (FKtable) {
7594
7595 if (FKtableLen == SQL_NTS) {
7596 size = sizeof (fname) - 1;
7597 } else {
7598 size = min(sizeof (fname) - 1, FKtableLen);
7599 }
7600 strncpy(fname, (char *) FKtable, size);
7601 }
7602 fname[size] = '\0';
7603 if (fname[0] != '\0') {
7604 int plen;
7605
7606 ret = SQLITE_ERROR;
7607 sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", fname);
7608 if (sql) {
7609 dbtraceapi(d, "sqlite3_get_table", sql);
7610 ret = sqlite3_get_table(d->sqlite, sql, &rowp,
7611 &nrows, &ncols, &errp);
7612 sqlite3_free(sql);
7613 }
7614 if (ret != SQLITE_OK) {
7615 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7616 errp ? errp : "unknown error", ret);
7617 if (errp) {
7618 sqlite3_free(errp);
7619 errp = NULL;
7620 }
7621 return SQL_ERROR;
7622 }
7623 if (errp) {
7624 sqlite3_free(errp);
7625 errp = NULL;
7626 }
7627 if (ncols * nrows <= 0) {
7628nodata:
7629 sqlite3_free_table(rowp);
7630 return SQL_SUCCESS;
7631 }
7632 size = 0;
7633 namec = findcol(rowp, ncols, "table");
7634 seqc = findcol(rowp, ncols, "seq");
7635 fromc = findcol(rowp, ncols, "from");
7636 toc = findcol(rowp, ncols, "to");
7637 onu = findcol(rowp, ncols, "on_update");
7638 ond = findcol(rowp, ncols, "on_delete");
7639 if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7640 goto nodata;
7641 }
7642 plen = strlen(pname);
7643 for (i = 1; i <= nrows; i++) {
7644 char *ptab = unquote(rowp[i * ncols + namec]);
7645
7646 if (plen && ptab) {
7647 int len = strlen(ptab);
7648
7649 if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
7650 continue;
7651 }
7652 }
7653 size++;
7654 }
7655 if (size == 0) {
7656 goto nodata;
7657 }
7658 s->nrows = size;
7659 size = (size + 1) * asize;
7660 s->rows = xmalloc((size + 1) * sizeof (char *));
7661 if (!s->rows) {
7662 s->nrows = 0;
7663 return nomem(s);
7664 }
7665 s->rows[0] = (char *) size;
7666 s->rows += 1;
7667 memset(s->rows, 0, sizeof (char *) * size);
7668 s->rowfree = freerows;
7669 offs = 0;
7670 for (i = 1; i <= nrows; i++) {
7671 int pos = 0, roffs = (offs + 1) * s->ncols;
7672 char *ptab = rowp[i * ncols + namec];
7673 char buf[32];
7674
7675 if (plen && ptab) {
7676 int len = strlen(ptab);
7677
7678 if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
7679 continue;
7680 }
7681 }
7682#if defined(_WIN32) || defined(_WIN64)
7683 s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
7684 s->rows[roffs + 1] = xstrdup("");
7685#else
7686 s->rows[roffs + 0] = xstrdup("");
7687 s->rows[roffs + 1] = xstrdup("");
7688#endif
7689 s->rows[roffs + 2] = xstrdup(ptab);
7690 s->rows[roffs + 3] = xstrdup(rowp[i * ncols + toc]);
7691 s->rows[roffs + 4] = xstrdup("");
7692 s->rows[roffs + 5] = xstrdup("");
7693 s->rows[roffs + 6] = xstrdup(fname);
7694 s->rows[roffs + 7] = xstrdup(rowp[i * ncols + fromc]);
7695 sscanf(rowp[i * ncols + seqc], "%d", &pos);
7696 sprintf(buf, "%d", pos + 1);
7697 s->rows[roffs + 8] = xstrdup(buf);
7698 if (onu < 0) {
7699 s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7700 } else {
7701 if (strcmp(rowp[i * ncols + onu], "SET NULL") == 0) {
7702 s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
7703 } else if (strcmp(rowp[i * ncols + onu], "SET DEFAULT") == 0) {
7704 s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_DEFAULT));
7705 } else if (strcmp(rowp[i * ncols + onu], "CASCADE") == 0) {
7706 s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
7707 } else if (strcmp(rowp[i * ncols + onu], "RESTRICT") == 0) {
7708 s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
7709 } else {
7710 s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7711 }
7712 }
7713 if (ond < 0) {
7714 s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7715 } else {
7716 if (strcmp(rowp[i * ncols + ond], "SET NULL") == 0) {
7717 s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
7718 } else if (strcmp(rowp[i * ncols + ond], "SET DEFAULT") == 0) {
7719 s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_DEFAULT));
7720 } else if (strcmp(rowp[i * ncols + ond], "CASCADE") == 0) {
7721 s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
7722 } else if (strcmp(rowp[i * ncols + ond], "RESTRICT") == 0) {
7723 s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
7724 } else {
7725 s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7726 }
7727 }
7728 s->rows[roffs + 11] = NULL;
7729 s->rows[roffs + 12] = NULL;
7730 s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
7731 offs++;
7732 }
7733 sqlite3_free_table(rowp);
7734 } else {
7735 int nnrows, nncols, plen = strlen(pname);
7736 char **rowpp;
7737
7738 sql = "select name from sqlite_master where type='table'";
7739 dbtraceapi(d, "sqlite3_get_table", sql);
7740 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
7741 if (ret != SQLITE_OK) {
7742 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7743 errp ? errp : "unknown error", ret);
7744 if (errp) {
7745 sqlite3_free(errp);
7746 errp = NULL;
7747 }
7748 return SQL_ERROR;
7749 }
7750 if (errp) {
7751 sqlite3_free(errp);
7752 errp = NULL;
7753 }
7754 if (ncols * nrows <= 0) {
7755 goto nodata;
7756 }
7757 size = 0;
7758 for (i = 1; i <= nrows; i++) {
7759 int k;
7760
7761 if (!rowp[i]) {
7762 continue;
7763 }
7764 rowpp = NULL;
7765 ret = SQLITE_ERROR;
7766 sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
7767 if (sql) {
7768 dbtraceapi(d, "sqlite3_get_table", sql);
7769 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7770 &nnrows, &nncols, NULL);
7771 sqlite3_free(sql);
7772 }
7773 if (ret != SQLITE_OK || nncols * nnrows <= 0) {
7774 sqlite3_free_table(rowpp);
7775 continue;
7776 }
7777 namec = findcol(rowpp, nncols, "table");
7778 seqc = findcol(rowpp, nncols, "seq");
7779 fromc = findcol(rowpp, nncols, "from");
7780 toc = findcol(rowpp, nncols, "to");
7781 if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7782 sqlite3_free_table(rowpp);
7783 continue;
7784 }
7785 for (k = 1; k <= nnrows; k++) {
7786 char *ptab = unquote(rowpp[k * nncols + namec]);
7787
7788 if (plen && ptab) {
7789 int len = strlen(ptab);
7790
7791 if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
7792 continue;
7793 }
7794 }
7795 size++;
7796 }
7797 sqlite3_free_table(rowpp);
7798 }
7799 if (size == 0) {
7800 goto nodata;
7801 }
7802 s->nrows = size;
7803 size = (size + 1) * asize;
7804 s->rows = xmalloc((size + 1) * sizeof (char *));
7805 if (!s->rows) {
7806 s->nrows = 0;
7807 return nomem(s);
7808 }
7809 s->rows[0] = (char *) size;
7810 s->rows += 1;
7811 memset(s->rows, 0, sizeof (char *) * size);
7812 s->rowfree = freerows;
7813 offs = 0;
7814 for (i = 1; i <= nrows; i++) {
7815 int k;
7816
7817 if (!rowp[i]) {
7818 continue;
7819 }
7820 rowpp = NULL;
7821 ret = SQLITE_ERROR;
7822 sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
7823 if (sql) {
7824 dbtraceapi(d, "sqlite3_get_table", sql);
7825 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7826 &nnrows, &nncols, NULL);
7827 sqlite3_free(sql);
7828 }
7829 if (ret != SQLITE_OK || nncols * nnrows <= 0) {
7830 sqlite3_free_table(rowpp);
7831 continue;
7832 }
7833 namec = findcol(rowpp, nncols, "table");
7834 seqc = findcol(rowpp, nncols, "seq");
7835 fromc = findcol(rowpp, nncols, "from");
7836 toc = findcol(rowpp, nncols, "to");
7837 onu = findcol(rowpp, nncols, "on_update");
7838 ond = findcol(rowpp, nncols, "on_delete");
7839 if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7840 sqlite3_free_table(rowpp);
7841 continue;
7842 }
7843 for (k = 1; k <= nnrows; k++) {
7844 int pos = 0, roffs = (offs + 1) * s->ncols;
7845 char *ptab = unquote(rowpp[k * nncols + namec]);
7846 char buf[32];
7847
7848 if (plen && ptab) {
7849 int len = strlen(ptab);
7850
7851 if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
7852 continue;
7853 }
7854 }
7855#if defined(_WIN32) || defined(_WIN64)
7856 s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
7857 s->rows[roffs + 1] = xstrdup("");
7858#else
7859 s->rows[roffs + 0] = xstrdup("");
7860 s->rows[roffs + 1] = xstrdup("");
7861#endif
7862 s->rows[roffs + 2] = xstrdup(ptab);
7863 s->rows[roffs + 3] = xstrdup(rowpp[k * nncols + toc]);
7864 s->rows[roffs + 4] = xstrdup("");
7865 s->rows[roffs + 5] = xstrdup("");
7866 s->rows[roffs + 6] = xstrdup(rowp[i]);
7867 s->rows[roffs + 7] = xstrdup(rowpp[k * nncols + fromc]);
7868 sscanf(rowpp[k * nncols + seqc], "%d", &pos);
7869 sprintf(buf, "%d", pos + 1);
7870 s->rows[roffs + 8] = xstrdup(buf);
7871 if (onu < 0) {
7872 s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7873 } else {
7874 if (strcmp(rowpp[k * nncols + onu], "SET NULL") == 0) {
7875 s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
7876 } else if (strcmp(rowpp[k * nncols + onu], "SET DEFAULT")
7877 == 0) {
7878 s->rows[roffs + 9] =
7879 xstrdup(stringify(SQL_SET_DEFAULT));
7880 } else if (strcmp(rowpp[k * nncols + onu], "CASCADE")
7881 == 0) {
7882 s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
7883 } else if (strcmp(rowpp[k * nncols + onu], "RESTRICT")
7884 == 0) {
7885 s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
7886 } else {
7887 s->rows[roffs + 9] =
7888 xstrdup(stringify(SQL_NO_ACTION));
7889 }
7890 }
7891 if (ond < 0) {
7892 s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7893 } else {
7894 if (strcmp(rowpp[k * nncols + ond], "SET NULL") == 0) {
7895 s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
7896 } else if (strcmp(rowpp[k * nncols + ond], "SET DEFAULT")
7897 == 0) {
7898 s->rows[roffs + 10] =
7899 xstrdup(stringify(SQL_SET_DEFAULT));
7900 } else if (strcmp(rowpp[k * nncols + ond], "CASCADE")
7901 == 0) {
7902 s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
7903 } else if (strcmp(rowpp[k * nncols + ond], "RESTRICT")
7904 == 0) {
7905 s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
7906 } else {
7907 s->rows[roffs + 10] =
7908 xstrdup(stringify(SQL_NO_ACTION));
7909 }
7910 }
7911 s->rows[roffs + 11] = NULL;
7912 s->rows[roffs + 12] = NULL;
7913 s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
7914 offs++;
7915 }
7916 sqlite3_free_table(rowpp);
7917 }
7918 sqlite3_free_table(rowp);
7919 }
7920 return SQL_SUCCESS;
7921}
7922
7923#ifndef WINTERFACE
7942SQLRETURN SQL_API
7943SQLForeignKeys(SQLHSTMT stmt,
7944 SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7945 SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
7946 SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
7947 SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7948 SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
7949 SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
7950{
7951#if defined(_WIN32) || defined(_WIN64)
7952 char *pc = NULL, *ps = NULL, *pt = NULL;
7953 char *fc = NULL, *fs = NULL, *ft = NULL;
7954#endif
7955 SQLRETURN ret;
7956
7958#if defined(_WIN32) || defined(_WIN64)
7959 if (!((STMT *) stmt)->oemcp[0]) {
7960 ret = drvforeignkeys(stmt,
7961 PKcatalog, PKcatalogLen,
7962 PKschema, PKschemaLen, PKtable, PKtableLen,
7963 FKcatalog, FKcatalogLen,
7964 FKschema, FKschemaLen,
7965 FKtable, FKtableLen);
7966 goto done2;
7967 }
7968 if (PKcatalog) {
7969 pc = wmb_to_utf_c((char *) PKcatalog, PKcatalogLen);
7970 if (!pc) {
7971 ret = nomem((STMT *) stmt);
7972 goto done;
7973 }
7974 }
7975 if (PKschema) {
7976 ps = wmb_to_utf_c((char *) PKschema, PKschemaLen);
7977 if (!ps) {
7978 ret = nomem((STMT *) stmt);
7979 goto done;
7980 }
7981 }
7982 if (PKtable) {
7983 pt = wmb_to_utf_c((char *) PKtable, PKtableLen);
7984 if (!pt) {
7985 ret = nomem((STMT *) stmt);
7986 goto done;
7987 }
7988 }
7989 if (FKcatalog) {
7990 fc = wmb_to_utf_c((char *) FKcatalog, FKcatalogLen);
7991 if (!fc) {
7992 ret = nomem((STMT *) stmt);
7993 goto done;
7994 }
7995 }
7996 if (FKschema) {
7997 fs = wmb_to_utf_c((char *) FKschema, FKschemaLen);
7998 if (!fs) {
7999 ret = nomem((STMT *) stmt);
8000 goto done;
8001 }
8002 }
8003 if (FKtable) {
8004 ft = wmb_to_utf_c((char *) FKtable, FKtableLen);
8005 if (!ft) {
8006 ret = nomem((STMT *) stmt);
8007 goto done;
8008 }
8009 }
8010 ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
8011 (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
8012 (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
8013 (SQLCHAR *) ft, SQL_NTS);
8014#else
8015 ret = drvforeignkeys(stmt,
8016 PKcatalog, PKcatalogLen,
8017 PKschema, PKschemaLen, PKtable, PKtableLen,
8018 FKcatalog, FKcatalogLen,
8019 FKschema, FKschemaLen,
8020 FKtable, FKtableLen);
8021#endif
8022#if defined(_WIN32) || defined(_WIN64)
8023done:
8024 uc_free(ft);
8025 uc_free(fs);
8026 uc_free(fc);
8027 uc_free(pt);
8028 uc_free(ps);
8029 uc_free(pc);
8030done2:
8031 ;
8032#endif
8034 return ret;
8035}
8036#endif
8037
8038#ifdef WINTERFACE
8057SQLRETURN SQL_API
8059 SQLWCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
8060 SQLWCHAR *PKschema, SQLSMALLINT PKschemaLen,
8061 SQLWCHAR *PKtable, SQLSMALLINT PKtableLen,
8062 SQLWCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
8063 SQLWCHAR *FKschema, SQLSMALLINT FKschemaLen,
8064 SQLWCHAR *FKtable, SQLSMALLINT FKtableLen)
8065{
8066 char *pc = NULL, *ps = NULL, *pt = NULL;
8067 char *fc = NULL, *fs = NULL, *ft = NULL;
8068 SQLRETURN ret;
8069
8071 if (PKcatalog) {
8072 pc = uc_to_utf_c(PKcatalog, PKcatalogLen);
8073 if (!pc) {
8074 ret = nomem((STMT *) stmt);
8075 goto done;
8076 }
8077 }
8078 if (PKschema) {
8079 ps = uc_to_utf_c(PKschema, PKschemaLen);
8080 if (!ps) {
8081 ret = nomem((STMT *) stmt);
8082 goto done;
8083 }
8084 }
8085 if (PKtable) {
8086 pt = uc_to_utf_c(PKtable, PKtableLen);
8087 if (!pt) {
8088 ret = nomem((STMT *) stmt);
8089 goto done;
8090 }
8091 }
8092 if (FKcatalog) {
8093 fc = uc_to_utf_c(FKcatalog, FKcatalogLen);
8094 if (!fc) {
8095 ret = nomem((STMT *) stmt);
8096 goto done;
8097 }
8098 }
8099 if (FKschema) {
8100 fs = uc_to_utf_c(FKschema, FKschemaLen);
8101 if (!fs) {
8102 ret = nomem((STMT *) stmt);
8103 goto done;
8104 }
8105 }
8106 if (FKtable) {
8107 ft = uc_to_utf_c(FKtable, FKtableLen);
8108 if (!ft) {
8109 ret = nomem((STMT *) stmt);
8110 goto done;
8111 }
8112 }
8113 ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
8114 (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
8115 (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
8116 (SQLCHAR *) ft, SQL_NTS);
8117done:
8118 uc_free(ft);
8119 uc_free(fs);
8120 uc_free(fc);
8121 uc_free(pt);
8122 uc_free(ps);
8123 uc_free(pc);
8125 return ret;
8126}
8127#endif
8128
8135static SQLRETURN
8137{
8138 int ret = SQL_SUCCESS, rc, busy_count = 0;
8139 char *errp = NULL;
8140 DBC *d = (DBC *) s->dbc;
8141
8142 if (!d->autocommit && !d->intrans && !d->trans_disable) {
8143begin_again:
8144 rc = sqlite3_exec(d->sqlite, "BEGIN TRANSACTION", NULL, NULL, &errp);
8145 if (rc == SQLITE_BUSY) {
8146 if (busy_handler((void *) d, ++busy_count)) {
8147 if (errp) {
8148 sqlite3_free(errp);
8149 errp = NULL;
8150 }
8151 goto begin_again;
8152 }
8153 }
8154 dbtracerc(d, rc, errp);
8155 if (rc != SQLITE_OK) {
8156 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
8157 errp ? errp : "unknown error", rc);
8158 ret = SQL_ERROR;
8159 } else {
8160 d->intrans = 1;
8161 }
8162 if (errp) {
8163 sqlite3_free(errp);
8164 errp = NULL;
8165 }
8166 }
8167 return ret;
8168}
8169
8178static SQLRETURN
8179endtran(DBC *d, SQLSMALLINT comptype, int force)
8180{
8181 int ret, busy_count = 0;
8182 char *sql, *errp = NULL;
8183
8184 if (!d->sqlite) {
8185 setstatd(d, -1, "not connected", (*d->ov3) ? "HY000" : "S1000");
8186 return SQL_ERROR;
8187 }
8188 if ((!force && d->autocommit) || !d->intrans) {
8189 return SQL_SUCCESS;
8190 }
8191 switch (comptype) {
8192 case SQL_COMMIT:
8193 sql = "COMMIT TRANSACTION";
8194 goto doit;
8195 case SQL_ROLLBACK:
8196 sql = "ROLLBACK TRANSACTION";
8197 doit:
8198 ret = sqlite3_exec(d->sqlite, sql, NULL, NULL, &errp);
8199 dbtracerc(d, ret, errp);
8200 if (ret == SQLITE_BUSY && busy_count < 10) {
8201 if (busy_handler((void *) d, ++busy_count)) {
8202 if (errp) {
8203 sqlite3_free(errp);
8204 errp = NULL;
8205 }
8206 goto doit;
8207 }
8208 }
8209 if (ret != SQLITE_OK) {
8210 setstatd(d, ret, "%s", (*d->ov3) ? "HY000" : "S1000",
8211 errp ? errp : "transaction failed");
8212 if (errp) {
8213 sqlite3_free(errp);
8214 errp = NULL;
8215 }
8216 return SQL_ERROR;
8217 }
8218 if (errp) {
8219 sqlite3_free(errp);
8220 errp = NULL;
8221 }
8222 d->intrans = 0;
8223 return SQL_SUCCESS;
8224 }
8225 setstatd(d, -1, "invalid completion type", (*d->ov3) ? "HY000" : "S1000");
8226 return SQL_ERROR;
8227}
8228
8237static SQLRETURN
8238drvendtran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
8239{
8240 DBC *dbc = NULL;
8241 int fail = 0;
8242 SQLRETURN ret;
8243#if defined(_WIN32) || defined(_WIN64)
8244 ENV *env;
8245#endif
8246
8247 switch (type) {
8248 case SQL_HANDLE_DBC:
8249 HDBC_LOCK((SQLHDBC) handle);
8250 if (handle == SQL_NULL_HDBC) {
8251 return SQL_INVALID_HANDLE;
8252 }
8253 dbc = (DBC *) handle;
8254 ret = endtran(dbc, comptype, 0);
8255 HDBC_UNLOCK((SQLHDBC) handle);
8256 return ret;
8257 case SQL_HANDLE_ENV:
8258 if (handle == SQL_NULL_HENV) {
8259 return SQL_INVALID_HANDLE;
8260 }
8261#if defined(_WIN32) || defined(_WIN64)
8262 env = (ENV *) handle;
8263 if (env->magic != ENV_MAGIC) {
8264 return SQL_INVALID_HANDLE;
8265 }
8266 EnterCriticalSection(&env->cs);
8267#endif
8268 dbc = ((ENV *) handle)->dbcs;
8269 while (dbc) {
8270 HDBC_LOCK((SQLHDBC) dbc);
8271 ret = endtran(dbc, comptype, 0);
8272 HDBC_UNLOCK((SQLHDBC) dbc);
8273 if (ret != SQL_SUCCESS) {
8274 fail++;
8275 }
8276 dbc = dbc->next;
8277 }
8278#if defined(_WIN32) || defined(_WIN64)
8279 LeaveCriticalSection(&env->cs);
8280#endif
8281 return fail ? SQL_ERROR : SQL_SUCCESS;
8282 }
8283 return SQL_INVALID_HANDLE;
8284}
8285
8294SQLRETURN SQL_API
8295SQLEndTran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
8296{
8297 return drvendtran(type, handle, comptype);
8298}
8299
8308SQLRETURN SQL_API
8309SQLTransact(SQLHENV env, SQLHDBC dbc, SQLUSMALLINT type)
8310{
8311 if (dbc != SQL_NULL_HDBC) {
8312 return drvendtran(SQL_HANDLE_DBC, (SQLHANDLE) dbc, type);
8313 }
8314 return drvendtran(SQL_HANDLE_ENV, (SQLHANDLE) env, type);
8315}
8316
8321SQLRETURN SQL_API
8322SQLCopyDesc(SQLHDESC source, SQLHDESC target)
8323{
8324 return SQL_ERROR;
8325}
8326
8327#ifndef WINTERFACE
8339SQLRETURN SQL_API
8340SQLNativeSql(SQLHSTMT stmt, SQLCHAR *sqlin, SQLINTEGER sqlinLen,
8341 SQLCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
8342{
8343 int outLen = 0;
8344 SQLRETURN ret = SQL_SUCCESS;
8345
8347 if (sqlinLen == SQL_NTS) {
8348 sqlinLen = strlen((char *) sqlin);
8349 }
8350 if (sql) {
8351 if (sqlMax > 0) {
8352 strncpy((char *) sql, (char *) sqlin, sqlMax - 1);
8353 sqlin[sqlMax - 1] = '\0';
8354 outLen = min(sqlMax - 1, sqlinLen);
8355 }
8356 } else {
8357 outLen = sqlinLen;
8358 }
8359 if (sqlLen) {
8360 *sqlLen = outLen;
8361 }
8362 if (sql && outLen < sqlinLen) {
8363 setstat((STMT *) stmt, -1, "data right truncated", "01004");
8364 ret = SQL_SUCCESS_WITH_INFO;
8365 }
8367 return ret;
8368}
8369#endif
8370
8371#ifdef WINTERFACE
8383SQLRETURN SQL_API
8384SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen,
8385 SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
8386{
8387 int outLen = 0;
8388 SQLRETURN ret = SQL_SUCCESS;
8389
8391 if (sqlinLen == SQL_NTS) {
8392 sqlinLen = uc_strlen(sqlin);
8393 }
8394 if (sql) {
8395 if (sqlMax > 0) {
8396 uc_strncpy(sql, sqlin, sqlMax - 1);
8397 sqlin[sqlMax - 1] = 0;
8398 outLen = min(sqlMax - 1, sqlinLen);
8399 }
8400 } else {
8401 outLen = sqlinLen;
8402 }
8403 if (sqlLen) {
8404 *sqlLen = outLen;
8405 }
8406 if (sql && outLen < sqlinLen) {
8407 setstat((STMT *) stmt, -1, "data right truncated", "01004");
8408 ret = SQL_SUCCESS_WITH_INFO;
8409 }
8411 return ret;
8412}
8413#endif
8414
8419static COL procSpec2[] = {
8420 { "SYSTEM", "PROCEDURE", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
8421 { "SYSTEM", "PROCEDURE", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
8422 { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8423 { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
8424 { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
8425 { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
8426 { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
8427 { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
8428};
8429
8430static COL procSpec3[] = {
8431 { "SYSTEM", "PROCEDURE", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
8432 { "SYSTEM", "PROCEDURE", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
8433 { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8434 { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
8435 { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
8436 { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
8437 { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
8438 { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
8439};
8440
8441#ifndef WINTERFACE
8454SQLRETURN SQL_API
8455SQLProcedures(SQLHSTMT stmt,
8456 SQLCHAR *catalog, SQLSMALLINT catalogLen,
8457 SQLCHAR *schema, SQLSMALLINT schemaLen,
8458 SQLCHAR *proc, SQLSMALLINT procLen)
8459{
8460 SQLRETURN ret;
8461
8466 return ret;
8467}
8468#endif
8469
8470#ifdef WINTERFACE
8483SQLRETURN SQL_API
8485 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
8486 SQLWCHAR *schema, SQLSMALLINT schemaLen,
8487 SQLWCHAR *proc, SQLSMALLINT procLen)
8488{
8489 SQLRETURN ret;
8490
8495 return ret;
8496}
8497#endif
8498
8503static COL procColSpec2[] = {
8504 { "SYSTEM", "PROCCOL", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
8505 { "SYSTEM", "PROCCOL", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
8506 { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8507 { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
8508 { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
8509 { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
8510 { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
8511 { "SYSTEM", "PROCCOL", "PRECISION", SQL_INTEGER, 10 },
8512 { "SYSTEM", "PROCCOL", "LENGTH", SQL_INTEGER, 10 },
8513 { "SYSTEM", "PROCCOL", "SCALE", SQL_SMALLINT, 5 },
8514 { "SYSTEM", "PROCCOL", "RADIX", SQL_SMALLINT, 5 },
8515 { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
8516 { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
8517 { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
8518 { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
8519 { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
8520 { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
8521 { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
8522 { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
8523};
8524
8525static COL procColSpec3[] = {
8526 { "SYSTEM", "PROCCOL", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
8527 { "SYSTEM", "PROCCOL", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
8528 { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8529 { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
8530 { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
8531 { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
8532 { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
8533 { "SYSTEM", "PROCCOL", "COLUMN_SIZE", SQL_INTEGER, 10 },
8534 { "SYSTEM", "PROCCOL", "BUFFER_LENGTH", SQL_INTEGER, 10 },
8535 { "SYSTEM", "PROCCOL", "DECIMAL_DIGITS", SQL_SMALLINT, 5 },
8536 { "SYSTEM", "PROCCOL", "NUM_PREC_RADIX", SQL_SMALLINT, 5 },
8537 { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
8538 { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
8539 { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
8540 { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
8541 { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
8542 { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
8543 { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
8544 { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
8545};
8546
8547#ifndef WINTERFACE
8562SQLRETURN SQL_API
8563SQLProcedureColumns(SQLHSTMT stmt,
8564 SQLCHAR *catalog, SQLSMALLINT catalogLen,
8565 SQLCHAR *schema, SQLSMALLINT schemaLen,
8566 SQLCHAR *proc, SQLSMALLINT procLen,
8567 SQLCHAR *column, SQLSMALLINT columnLen)
8568{
8569 SQLRETURN ret;
8570
8575 return ret;
8576}
8577#endif
8578
8579#ifdef WINTERFACE
8595SQLRETURN SQL_API
8597 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
8598 SQLWCHAR *schema, SQLSMALLINT schemaLen,
8599 SQLWCHAR *proc, SQLSMALLINT procLen,
8600 SQLWCHAR *column, SQLSMALLINT columnLen)
8601{
8602 SQLRETURN ret;
8603
8608 return ret;
8609}
8610#endif
8611
8622SQLRETURN SQL_API
8623SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val,
8624 SQLINTEGER len, SQLINTEGER *lenp)
8625{
8626 ENV *e;
8627 SQLRETURN ret = SQL_ERROR;
8628
8629 if (env == SQL_NULL_HENV) {
8630 return SQL_INVALID_HANDLE;
8631 }
8632 e = (ENV *) env;
8633 if (!e || e->magic != ENV_MAGIC) {
8634 return SQL_INVALID_HANDLE;
8635 }
8636#if defined(_WIN32) || defined(_WIN64)
8637 EnterCriticalSection(&e->cs);
8638#endif
8639 switch (attr) {
8640 case SQL_ATTR_CONNECTION_POOLING:
8641 if (val) {
8642 *((SQLINTEGER *) val) = e->pool ?
8643 SQL_CP_ONE_PER_DRIVER : SQL_CP_OFF;
8644 }
8645 if (lenp) {
8646 *lenp = sizeof (SQLINTEGER);
8647 }
8648 ret = SQL_SUCCESS;
8649 break;
8650 case SQL_ATTR_CP_MATCH:
8651 *((SQLINTEGER *) val) = SQL_CP_RELAXED_MATCH;
8652 if (lenp) {
8653 *lenp = sizeof (SQLINTEGER);
8654 }
8655 ret = SQL_SUCCESS;
8656 break;
8657 case SQL_ATTR_OUTPUT_NTS:
8658 if (val) {
8659 *((SQLINTEGER *) val) = SQL_TRUE;
8660 }
8661 if (lenp) {
8662 *lenp = sizeof (SQLINTEGER);
8663 }
8664 ret = SQL_SUCCESS;
8665 break;
8666 case SQL_ATTR_ODBC_VERSION:
8667 if (val) {
8668 *((SQLINTEGER *) val) = e->ov3 ? SQL_OV_ODBC3 : SQL_OV_ODBC2;
8669 }
8670 if (lenp) {
8671 *lenp = sizeof (SQLINTEGER);
8672 }
8673 ret = SQL_SUCCESS;
8674 break;
8675 }
8676#if defined(_WIN32) || defined(_WIN64)
8677 LeaveCriticalSection(&e->cs);
8678#endif
8679 return ret;
8680}
8681
8691SQLRETURN SQL_API
8692SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
8693{
8694 ENV *e;
8695 SQLRETURN ret = SQL_ERROR;
8696
8697 if (env == SQL_NULL_HENV) {
8698 return SQL_INVALID_HANDLE;
8699 }
8700 e = (ENV *) env;
8701 if (!e || e->magic != ENV_MAGIC) {
8702 return SQL_INVALID_HANDLE;
8703 }
8704#if defined(_WIN32) || defined(_WIN64)
8705 EnterCriticalSection(&e->cs);
8706#endif
8707 switch (attr) {
8708 case SQL_ATTR_CONNECTION_POOLING:
8709 if (val == (SQLPOINTER) SQL_CP_ONE_PER_DRIVER) {
8710 e->pool = 1;
8711 ret = SQL_SUCCESS;
8712 } else if (val == (SQLPOINTER) SQL_CP_OFF) {
8713 e->pool = 0;
8714 ret = SQL_SUCCESS;
8715 }
8716 break;
8717 case SQL_ATTR_CP_MATCH:
8718 ret = SQL_SUCCESS;
8719 break;
8720 case SQL_ATTR_OUTPUT_NTS:
8721 if (val == (SQLPOINTER) SQL_TRUE) {
8722 ret = SQL_SUCCESS;
8723 }
8724 break;
8725 case SQL_ATTR_ODBC_VERSION:
8726 if (!val) {
8727 break;
8728 }
8729 if (val == (SQLPOINTER) SQL_OV_ODBC2) {
8730 e->ov3 = 0;
8731 ret = SQL_SUCCESS;
8732 } else if (val == (SQLPOINTER) SQL_OV_ODBC3) {
8733 e->ov3 = 1;
8734 ret = SQL_SUCCESS;
8735 }
8736 break;
8737 }
8738#if defined(_WIN32) || defined(_WIN64)
8739 LeaveCriticalSection(&e->cs);
8740#endif
8741 return ret;
8742}
8743
8757static SQLRETURN
8758drvgetdiagrec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8759 SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
8760 SQLSMALLINT buflen, SQLSMALLINT *msglen)
8761{
8762 DBC *d = NULL;
8763 STMT *s = NULL;
8764 int len, naterr;
8765 char *logmsg, *sqlst;
8766 SQLRETURN ret = SQL_ERROR;
8767
8768 if (handle == SQL_NULL_HANDLE) {
8769 return SQL_INVALID_HANDLE;
8770 }
8771 if (sqlstate) {
8772 sqlstate[0] = '\0';
8773 }
8774 if (msg && buflen > 0) {
8775 msg[0] = '\0';
8776 }
8777 if (msglen) {
8778 *msglen = 0;
8779 }
8780 if (nativeerr) {
8781 *nativeerr = 0;
8782 }
8783 switch (htype) {
8784 case SQL_HANDLE_ENV:
8785 case SQL_HANDLE_DESC:
8786 return SQL_NO_DATA;
8787 case SQL_HANDLE_DBC:
8788 HDBC_LOCK((SQLHDBC) handle);
8789 d = (DBC *) handle;
8790 logmsg = (char *) d->logmsg;
8791 sqlst = d->sqlstate;
8792 naterr = d->naterr;
8793 break;
8794 case SQL_HANDLE_STMT:
8795 HSTMT_LOCK((SQLHSTMT) handle);
8796 s = (STMT *) handle;
8797 logmsg = (char *) s->logmsg;
8798 sqlst = s->sqlstate;
8799 naterr = s->naterr;
8800 break;
8801 default:
8802 return SQL_INVALID_HANDLE;
8803 }
8804 if (buflen < 0) {
8805 goto done;
8806 }
8807 if (recno > 1) {
8808 ret = SQL_NO_DATA;
8809 goto done;
8810 }
8811 len = strlen(logmsg);
8812 if (len == 0) {
8813 ret = SQL_NO_DATA;
8814 goto done;
8815 }
8816 if (nativeerr) {
8817 *nativeerr = naterr;
8818 }
8819 if (sqlstate) {
8820 strcpy((char *) sqlstate, sqlst);
8821 }
8822 if (msglen) {
8823 *msglen = len;
8824 }
8825 if (len >= buflen) {
8826 if (msg && buflen > 0) {
8827 strncpy((char *) msg, logmsg, buflen);
8828 msg[buflen - 1] = '\0';
8829 logmsg[0] = '\0';
8830 }
8831 } else if (msg) {
8832 strcpy((char *) msg, logmsg);
8833 logmsg[0] = '\0';
8834 }
8835 ret = SQL_SUCCESS;
8836done:
8837 switch (htype) {
8838 case SQL_HANDLE_DBC:
8839 HDBC_UNLOCK((SQLHDBC) handle);
8840 break;
8841 case SQL_HANDLE_STMT:
8842 HSTMT_UNLOCK((SQLHSTMT) handle);
8843 break;
8844 }
8845 return ret;
8846}
8847
8848#if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
8862SQLRETURN SQL_API
8863SQLGetDiagRec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8864 SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
8865 SQLSMALLINT buflen, SQLSMALLINT *msglen)
8866{
8867 return drvgetdiagrec(htype, handle, recno, sqlstate,
8868 nativeerr, msg, buflen, msglen);
8869}
8870#endif
8871
8872#if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
8873#ifdef WINTERFACE
8888SQLRETURN SQL_API
8889SQLGetDiagRecW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8890 SQLWCHAR *sqlstate, SQLINTEGER *nativeerr, SQLWCHAR *msg,
8891 SQLSMALLINT buflen, SQLSMALLINT *msglen)
8892{
8893 char state[16];
8894 SQLSMALLINT len;
8895 SQLRETURN ret;
8896
8897 ret = drvgetdiagrec(htype, handle, recno, (SQLCHAR *) state,
8898 nativeerr, (SQLCHAR *) msg, buflen, &len);
8899 if (ret == SQL_SUCCESS) {
8900 if (sqlstate) {
8901 uc_from_utf_buf((SQLCHAR *) state, -1, sqlstate,
8902 6 * sizeof (SQLWCHAR));
8903 }
8904 if (msg) {
8905 if (len > 0) {
8906 SQLWCHAR *m = NULL;
8907
8908 m = uc_from_utf((unsigned char *) msg, len);
8909 if (m) {
8910 if (buflen) {
8911 buflen /= sizeof (SQLWCHAR);
8912 uc_strncpy(msg, m, buflen);
8913 m[len] = 0;
8914 len = min(buflen, uc_strlen(m));
8915 } else {
8916 len = uc_strlen(m);
8917 }
8918 uc_free(m);
8919 } else {
8920 len = 0;
8921 }
8922 }
8923 if (len <= 0) {
8924 len = 0;
8925 if (buflen > 0) {
8926 msg[0] = 0;
8927 }
8928 }
8929 } else {
8930 /* estimated length !!! */
8931 len *= sizeof (SQLWCHAR);
8932 }
8933 if (msglen) {
8934 *msglen = len;
8935 }
8936 } else if (ret == SQL_NO_DATA) {
8937 if (sqlstate) {
8938 sqlstate[0] = 0;
8939 }
8940 if (msg) {
8941 if (buflen > 0) {
8942 msg[0] = 0;
8943 }
8944 }
8945 if (msglen) {
8946 *msglen = 0;
8947 }
8948 }
8949 return ret;
8950}
8951#endif
8952#endif
8953
8966static SQLRETURN
8967drvgetdiagfield(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8968 SQLSMALLINT id, SQLPOINTER info,
8969 SQLSMALLINT buflen, SQLSMALLINT *stringlen)
8970{
8971 DBC *d = NULL;
8972 STMT *s = NULL;
8973 int len, naterr, strbuf = 1;
8974 char *logmsg, *sqlst, *clrmsg = NULL;
8975 SQLRETURN ret = SQL_ERROR;
8976
8977 if (handle == SQL_NULL_HANDLE) {
8978 return SQL_INVALID_HANDLE;
8979 }
8980 if (stringlen) {
8981 *stringlen = 0;
8982 }
8983 switch (htype) {
8984 case SQL_HANDLE_ENV:
8985 case SQL_HANDLE_DESC:
8986 return SQL_NO_DATA;
8987 case SQL_HANDLE_DBC:
8988 HDBC_LOCK((SQLHDBC) handle);
8989 d = (DBC *) handle;
8990 logmsg = (char *) d->logmsg;
8991 sqlst = d->sqlstate;
8992 naterr = d->naterr;
8993 break;
8994 case SQL_HANDLE_STMT:
8995 HSTMT_LOCK((SQLHSTMT) handle);
8996 s = (STMT *) handle;
8997 d = (DBC *) s->dbc;
8998 logmsg = (char *) s->logmsg;
8999 sqlst = s->sqlstate;
9000 naterr = s->naterr;
9001 break;
9002 default:
9003 return SQL_INVALID_HANDLE;
9004 }
9005 if (buflen < 0) {
9006 switch (buflen) {
9007 case SQL_IS_POINTER:
9008 case SQL_IS_UINTEGER:
9009 case SQL_IS_INTEGER:
9010 case SQL_IS_USMALLINT:
9011 case SQL_IS_SMALLINT:
9012 strbuf = 0;
9013 break;
9014 default:
9015 ret = SQL_ERROR;
9016 goto done;
9017 }
9018 }
9019 if (recno > 1) {
9020 ret = SQL_NO_DATA;
9021 goto done;
9022 }
9023 switch (id) {
9024 case SQL_DIAG_CLASS_ORIGIN:
9025 logmsg = "ISO 9075";
9026 if (sqlst[0] == 'I' && sqlst[1] == 'M') {
9027 logmsg = "ODBC 3.0";
9028 }
9029 break;
9030 case SQL_DIAG_SUBCLASS_ORIGIN:
9031 logmsg = "ISO 9075";
9032 if (sqlst[0] == 'I' && sqlst[1] == 'M') {
9033 logmsg = "ODBC 3.0";
9034 } else if (sqlst[0] == 'H' && sqlst[1] == 'Y') {
9035 logmsg = "ODBC 3.0";
9036 } else if (sqlst[0] == '2' || sqlst[0] == '0' || sqlst[0] == '4') {
9037 logmsg = "ODBC 3.0";
9038 }
9039 break;
9040 case SQL_DIAG_CONNECTION_NAME:
9041 case SQL_DIAG_SERVER_NAME:
9042 logmsg = d->dsn ? d->dsn : "No DSN";
9043 break;
9044 case SQL_DIAG_SQLSTATE:
9045 logmsg = sqlst;
9046 break;
9047 case SQL_DIAG_MESSAGE_TEXT:
9048 if (info) {
9049 clrmsg = logmsg;
9050 }
9051 break;
9052 case SQL_DIAG_NUMBER:
9053 naterr = 1;
9054 /* fall through */
9055 case SQL_DIAG_NATIVE:
9056 len = strlen(logmsg);
9057 if (len == 0) {
9058 ret = SQL_NO_DATA;
9059 goto done;
9060 }
9061 if (info) {
9062 *((SQLINTEGER *) info) = naterr;
9063 }
9064 ret = SQL_SUCCESS;
9065 goto done;
9066 case SQL_DIAG_DYNAMIC_FUNCTION:
9067 logmsg = "";
9068 break;
9069 case SQL_DIAG_CURSOR_ROW_COUNT:
9070 if (htype == SQL_HANDLE_STMT) {
9071 SQLULEN count;
9072
9073 count = (s->isselect == 1 || s->isselect == -1) ? s->nrows : 0;
9074 *((SQLULEN *) info) = count;
9075 ret = SQL_SUCCESS;
9076 }
9077 goto done;
9078 case SQL_DIAG_ROW_COUNT:
9079 if (htype == SQL_HANDLE_STMT) {
9080 SQLULEN count;
9081
9082 count = s->isselect ? 0 : s->nrows;
9083 *((SQLULEN *) info) = count;
9084 ret = SQL_SUCCESS;
9085 }
9086 goto done;
9087 default:
9088 goto done;
9089 }
9090 if (info && buflen > 0) {
9091 ((char *) info)[0] = '\0';
9092 }
9093 len = strlen(logmsg);
9094 if (len == 0) {
9095 ret = SQL_NO_DATA;
9096 goto done;
9097 }
9098 if (stringlen) {
9099 *stringlen = len;
9100 }
9101 if (strbuf) {
9102 if (len >= buflen) {
9103 if (info && buflen > 0) {
9104 if (stringlen) {
9105 *stringlen = buflen - 1;
9106 }
9107 strncpy((char *) info, logmsg, buflen);
9108 ((char *) info)[buflen - 1] = '\0';
9109 }
9110 } else if (info) {
9111 strcpy((char *) info, logmsg);
9112 }
9113 }
9114 if (clrmsg) {
9115 *clrmsg = '\0';
9116 }
9117 ret = SQL_SUCCESS;
9118done:
9119 switch (htype) {
9120 case SQL_HANDLE_DBC:
9121 HDBC_UNLOCK((SQLHDBC) handle);
9122 break;
9123 case SQL_HANDLE_STMT:
9124 HSTMT_UNLOCK((SQLHSTMT) handle);
9125 break;
9126 }
9127 return ret;
9128}
9129
9130#ifndef WINTERFACE
9143SQLRETURN SQL_API
9144SQLGetDiagField(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
9145 SQLSMALLINT id, SQLPOINTER info,
9146 SQLSMALLINT buflen, SQLSMALLINT *stringlen)
9147{
9148 return drvgetdiagfield(htype, handle, recno, id, info, buflen, stringlen);
9149}
9150#endif
9151
9152#ifdef WINTERFACE
9165SQLRETURN SQL_API
9166SQLGetDiagFieldW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
9167 SQLSMALLINT id, SQLPOINTER info,
9168 SQLSMALLINT buflen, SQLSMALLINT *stringlen)
9169{
9170 SQLSMALLINT len;
9171 SQLRETURN ret;
9172
9173 ret = drvgetdiagfield(htype, handle, recno, id, info, buflen, &len);
9174 if (ret == SQL_SUCCESS) {
9175 if (info) {
9176 switch (id) {
9177 case SQL_DIAG_CLASS_ORIGIN:
9178 case SQL_DIAG_SUBCLASS_ORIGIN:
9179 case SQL_DIAG_CONNECTION_NAME:
9180 case SQL_DIAG_SERVER_NAME:
9181 case SQL_DIAG_SQLSTATE:
9182 case SQL_DIAG_MESSAGE_TEXT:
9183 case SQL_DIAG_DYNAMIC_FUNCTION:
9184 if (len > 0) {
9185 SQLWCHAR *m = NULL;
9186
9187 m = uc_from_utf((unsigned char *) info, len);
9188 if (m) {
9189 if (buflen) {
9190 buflen /= sizeof (SQLWCHAR);
9191 uc_strncpy(info, m, buflen);
9192 m[len] = 0;
9193 len = min(buflen, uc_strlen(m));
9194 } else {
9195 len = uc_strlen(m);
9196 }
9197 uc_free(m);
9198 len *= sizeof (SQLWCHAR);
9199 } else {
9200 len = 0;
9201 }
9202 }
9203 if (len <= 0) {
9204 len = 0;
9205 if (buflen > 0) {
9206 ((SQLWCHAR *) info)[0] = 0;
9207 }
9208 }
9209 }
9210 } else {
9211 switch (id) {
9212 case SQL_DIAG_CLASS_ORIGIN:
9213 case SQL_DIAG_SUBCLASS_ORIGIN:
9214 case SQL_DIAG_CONNECTION_NAME:
9215 case SQL_DIAG_SERVER_NAME:
9216 case SQL_DIAG_SQLSTATE:
9217 case SQL_DIAG_MESSAGE_TEXT:
9218 case SQL_DIAG_DYNAMIC_FUNCTION:
9219 len *= sizeof (SQLWCHAR);
9220 break;
9221 }
9222 }
9223 if (stringlen) {
9224 *stringlen = len;
9225 }
9226 }
9227 return ret;
9228}
9229#endif
9230
9241static SQLRETURN
9242drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9243 SQLINTEGER bufmax, SQLINTEGER *buflen)
9244{
9245 STMT *s = (STMT *) stmt;
9246 SQLULEN *uval = (SQLULEN *) val;
9247 SQLINTEGER dummy;
9248 char dummybuf[16];
9249
9250 if (!buflen) {
9251 buflen = &dummy;
9252 }
9253 if (!uval) {
9254 uval = (SQLPOINTER) dummybuf;
9255 }
9256 switch (attr) {
9257 case SQL_QUERY_TIMEOUT:
9258 *uval = 0;
9259 *buflen = sizeof (SQLULEN);
9260 return SQL_SUCCESS;
9261 case SQL_ATTR_CURSOR_TYPE:
9262 *uval = s->curtype;
9263 *buflen = sizeof (SQLULEN);
9264 return SQL_SUCCESS;
9265 case SQL_ATTR_CURSOR_SCROLLABLE:
9266 *uval = (s->curtype != SQL_CURSOR_FORWARD_ONLY) ?
9267 SQL_SCROLLABLE : SQL_NONSCROLLABLE;
9268 *buflen = sizeof (SQLULEN);
9269 return SQL_SUCCESS;
9270#ifdef SQL_ATTR_CURSOR_SENSITIVITY
9271 case SQL_ATTR_CURSOR_SENSITIVITY:
9272 *uval = SQL_UNSPECIFIED;
9273 *buflen = sizeof (SQLULEN);
9274 return SQL_SUCCESS;
9275#endif
9276 case SQL_ATTR_ROW_NUMBER:
9277 if (s->s3stmt) {
9278 *uval = (s->s3stmt_rownum < 0) ?
9279 SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
9280 } else {
9281 *uval = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
9282 }
9283 *buflen = sizeof (SQLULEN);
9284 return SQL_SUCCESS;
9285 case SQL_ATTR_ASYNC_ENABLE:
9286 *uval = SQL_ASYNC_ENABLE_OFF;
9287 *buflen = sizeof (SQLULEN);
9288 return SQL_SUCCESS;
9289 case SQL_CONCURRENCY:
9290 *uval = SQL_CONCUR_LOCK;
9291 *buflen = sizeof (SQLULEN);
9292 return SQL_SUCCESS;
9293 case SQL_ATTR_RETRIEVE_DATA:
9294 *uval = s->retr_data;
9295 *buflen = sizeof (SQLULEN);
9296 return SQL_SUCCESS;
9297 case SQL_ROWSET_SIZE:
9298 case SQL_ATTR_ROW_ARRAY_SIZE:
9299 *uval = s->rowset_size;
9300 *buflen = sizeof (SQLULEN);
9301 return SQL_SUCCESS;
9302 /* Needed for some driver managers, but dummies for now */
9303 case SQL_ATTR_IMP_ROW_DESC:
9304 case SQL_ATTR_APP_ROW_DESC:
9305 case SQL_ATTR_IMP_PARAM_DESC:
9306 case SQL_ATTR_APP_PARAM_DESC:
9307 *((SQLHDESC *) uval) = (SQLHDESC) DEAD_MAGIC;
9308 *buflen = sizeof (SQLHDESC);
9309 return SQL_SUCCESS;
9310 case SQL_ATTR_ROW_STATUS_PTR:
9311 *((SQLUSMALLINT **) uval) = s->row_status;
9312 *buflen = sizeof (SQLUSMALLINT *);
9313 return SQL_SUCCESS;
9314 case SQL_ATTR_ROWS_FETCHED_PTR:
9315 *((SQLULEN **) uval) = s->row_count;
9316 *buflen = sizeof (SQLULEN *);
9317 return SQL_SUCCESS;
9318 case SQL_ATTR_USE_BOOKMARKS: {
9319 STMT *s = (STMT *) stmt;
9320
9321 *(SQLUINTEGER *) uval = s->bkmrk;
9322 *buflen = sizeof (SQLUINTEGER);
9323 return SQL_SUCCESS;
9324 }
9325 case SQL_ATTR_FETCH_BOOKMARK_PTR:
9326 *(SQLPOINTER *) uval = s->bkmrkptr;
9327 *buflen = sizeof (SQLPOINTER);
9328 return SQL_SUCCESS;
9329 case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
9330 *((SQLULEN **) uval) = s->parm_bind_offs;
9331 *buflen = sizeof (SQLULEN *);
9332 return SQL_SUCCESS;
9333 case SQL_ATTR_PARAM_BIND_TYPE:
9334 *((SQLULEN *) uval) = s->parm_bind_type;
9335 *buflen = sizeof (SQLULEN);
9336 return SQL_SUCCESS;
9337 case SQL_ATTR_PARAM_OPERATION_PTR:
9338 *((SQLUSMALLINT **) uval) = s->parm_oper;
9339 *buflen = sizeof (SQLUSMALLINT *);
9340 return SQL_SUCCESS;
9341 case SQL_ATTR_PARAM_STATUS_PTR:
9342 *((SQLUSMALLINT **) uval) = s->parm_status;
9343 *buflen = sizeof (SQLUSMALLINT *);
9344 return SQL_SUCCESS;
9345 case SQL_ATTR_PARAMS_PROCESSED_PTR:
9346 *((SQLULEN **) uval) = s->parm_proc;
9347 *buflen = sizeof (SQLULEN *);
9348 return SQL_SUCCESS;
9349 case SQL_ATTR_PARAMSET_SIZE:
9350 *((SQLULEN *) uval) = s->paramset_size;
9351 *buflen = sizeof (SQLULEN);
9352 return SQL_SUCCESS;
9353 case SQL_ATTR_ROW_BIND_TYPE:
9354 *(SQLULEN *) uval = s->bind_type;
9355 *buflen = sizeof (SQLULEN);
9356 return SQL_SUCCESS;
9357 case SQL_ATTR_ROW_BIND_OFFSET_PTR:
9358 *((SQLULEN **) uval) = s->bind_offs;
9359 *buflen = sizeof (SQLULEN *);
9360 return SQL_SUCCESS;
9361 case SQL_ATTR_MAX_ROWS:
9362 *((SQLULEN *) uval) = s->max_rows;
9363 *buflen = sizeof (SQLULEN);
9364 return SQL_SUCCESS;
9365 case SQL_ATTR_MAX_LENGTH:
9366 *((SQLULEN *) uval) = 1000000000;
9367 *buflen = sizeof (SQLULEN);
9368 return SQL_SUCCESS;
9369#ifdef SQL_ATTR_METADATA_ID
9370 case SQL_ATTR_METADATA_ID:
9371 *((SQLULEN *) uval) = SQL_FALSE;
9372 *buflen = sizeof (SQLULEN);
9373 return SQL_SUCCESS;
9374#endif
9375 }
9376 return drvunimplstmt(stmt);
9377}
9378
9379#if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
9390SQLRETURN SQL_API
9391SQLGetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9392 SQLINTEGER bufmax, SQLINTEGER *buflen)
9393{
9394 SQLRETURN ret;
9395
9397 ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
9399 return ret;
9400}
9401#endif
9402
9403#ifdef WINTERFACE
9414SQLRETURN SQL_API
9415SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9416 SQLINTEGER bufmax, SQLINTEGER *buflen)
9417{
9418 SQLRETURN ret;
9419
9421 ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
9423 return ret;
9424}
9425#endif
9426
9436static SQLRETURN
9437drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9438 SQLINTEGER buflen)
9439{
9440 STMT *s = (STMT *) stmt;
9441#if defined(SQL_BIGINT) && defined(__WORDSIZE) && (__WORDSIZE == 64)
9442 SQLBIGINT uval;
9443
9444 uval = (SQLBIGINT) val;
9445#else
9446 SQLULEN uval;
9447
9448 uval = (SQLULEN) val;
9449#endif
9450 switch (attr) {
9451 case SQL_ATTR_CURSOR_TYPE:
9452 if (val == (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY) {
9453 s->curtype = SQL_CURSOR_FORWARD_ONLY;
9454 } else {
9455 s->curtype = SQL_CURSOR_STATIC;
9456 }
9457 if (val != (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY &&
9458 val != (SQLPOINTER) SQL_CURSOR_STATIC) {
9459 goto e01s02;
9460 }
9461 return SQL_SUCCESS;
9462 case SQL_ATTR_CURSOR_SCROLLABLE:
9463 if (val == (SQLPOINTER) SQL_NONSCROLLABLE) {
9464 s->curtype = SQL_CURSOR_FORWARD_ONLY;
9465 } else {
9466 s->curtype = SQL_CURSOR_STATIC;
9467 }
9468 return SQL_SUCCESS;
9469 case SQL_ATTR_ASYNC_ENABLE:
9470 if (val != (SQLPOINTER) SQL_ASYNC_ENABLE_OFF) {
9471 e01s02:
9472 setstat(s, -1, "option value changed", "01S02");
9473 return SQL_SUCCESS_WITH_INFO;
9474 }
9475 return SQL_SUCCESS;
9476 case SQL_CONCURRENCY:
9477 if (val != (SQLPOINTER) SQL_CONCUR_LOCK) {
9478 goto e01s02;
9479 }
9480 return SQL_SUCCESS;
9481#ifdef SQL_ATTR_CURSOR_SENSITIVITY
9482 case SQL_ATTR_CURSOR_SENSITIVITY:
9483 if (val != (SQLPOINTER) SQL_UNSPECIFIED) {
9484 goto e01s02;
9485 }
9486 return SQL_SUCCESS;
9487#endif
9488 case SQL_ATTR_QUERY_TIMEOUT:
9489 return SQL_SUCCESS;
9490 case SQL_ATTR_RETRIEVE_DATA:
9491 if (val != (SQLPOINTER) SQL_RD_ON &&
9492 val != (SQLPOINTER) SQL_RD_OFF) {
9493 goto e01s02;
9494 }
9495 s->retr_data = uval;
9496 return SQL_SUCCESS;
9497 case SQL_ROWSET_SIZE:
9498 case SQL_ATTR_ROW_ARRAY_SIZE:
9499 if (uval < 1) {
9500 setstat(s, -1, "invalid rowset size", "HY000");
9501 return SQL_ERROR;
9502 } else {
9503 SQLUSMALLINT *rst = &s->row_status1;
9504
9505 if (uval > 1) {
9506 rst = xmalloc(sizeof (SQLUSMALLINT) * uval);
9507 if (!rst) {
9508 return nomem(s);
9509 }
9510 }
9511 if (s->row_status0 != &s->row_status1) {
9512 freep(&s->row_status0);
9513 }
9514 s->row_status0 = rst;
9515 s->rowset_size = uval;
9516 }
9517 return SQL_SUCCESS;
9518 case SQL_ATTR_ROW_STATUS_PTR:
9519 s->row_status = (SQLUSMALLINT *) val;
9520 return SQL_SUCCESS;
9521 case SQL_ATTR_ROWS_FETCHED_PTR:
9522 s->row_count = (SQLULEN *) val;
9523 return SQL_SUCCESS;
9524 case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
9525 s->parm_bind_offs = (SQLULEN *) val;
9526 return SQL_SUCCESS;
9527 case SQL_ATTR_PARAM_BIND_TYPE:
9528 s->parm_bind_type = uval;
9529 return SQL_SUCCESS;
9530 case SQL_ATTR_PARAM_OPERATION_PTR:
9531 s->parm_oper = (SQLUSMALLINT *) val;
9532 return SQL_SUCCESS;
9533 case SQL_ATTR_PARAM_STATUS_PTR:
9534 s->parm_status = (SQLUSMALLINT *) val;
9535 return SQL_SUCCESS;
9536 case SQL_ATTR_PARAMS_PROCESSED_PTR:
9537 s->parm_proc = (SQLULEN *) val;
9538 return SQL_SUCCESS;
9539 case SQL_ATTR_PARAMSET_SIZE:
9540 if (uval < 1) {
9541 goto e01s02;
9542 }
9543 s->paramset_size = uval;
9544 s->paramset_count = 0;
9545 return SQL_SUCCESS;
9546 case SQL_ATTR_ROW_BIND_TYPE:
9547 s->bind_type = uval;
9548 return SQL_SUCCESS;
9549 case SQL_ATTR_ROW_BIND_OFFSET_PTR:
9550 s->bind_offs = (SQLULEN *) val;
9551 return SQL_SUCCESS;
9552 case SQL_ATTR_USE_BOOKMARKS:
9553 if (val != (SQLPOINTER) SQL_UB_OFF &&
9554 val != (SQLPOINTER) SQL_UB_ON &&
9555 val != (SQLPOINTER) SQL_UB_VARIABLE) {
9556 goto e01s02;
9557 }
9558 if (*s->ov3 && val == (SQLPOINTER) SQL_UB_VARIABLE) {
9559 s->bkmrk = SQL_UB_VARIABLE;
9560 return SQL_SUCCESS;
9561 }
9562 if (val == (SQLPOINTER) SQL_UB_VARIABLE) {
9563 s->bkmrk = SQL_UB_ON;
9564 goto e01s02;
9565 }
9566 s->bkmrk = (val == (SQLPOINTER) SQL_UB_ON) ? SQL_UB_ON : SQL_UB_OFF;
9567 return SQL_SUCCESS;
9568 case SQL_ATTR_FETCH_BOOKMARK_PTR:
9569 s->bkmrkptr = (SQLINTEGER *) val;
9570 return SQL_SUCCESS;
9571 case SQL_ATTR_MAX_ROWS:
9572 s->max_rows = uval;
9573 return SQL_SUCCESS;
9574 case SQL_ATTR_MAX_LENGTH:
9575 if (val != (SQLPOINTER) 1000000000) {
9576 goto e01s02;
9577 }
9578 return SQL_SUCCESS;
9579#ifdef SQL_ATTR_METADATA_ID
9580 case SQL_ATTR_METADATA_ID:
9581 if (val != (SQLPOINTER) SQL_FALSE) {
9582 goto e01s02;
9583 }
9584 return SQL_SUCCESS;
9585#endif
9586 }
9587 return drvunimplstmt(stmt);
9588}
9589
9590#if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
9600SQLRETURN SQL_API
9601SQLSetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9602 SQLINTEGER buflen)
9603{
9604 SQLRETURN ret;
9605
9607 ret = drvsetstmtattr(stmt, attr, val, buflen);
9609 return ret;
9610}
9611#endif
9612
9613#ifdef WINTERFACE
9623SQLRETURN SQL_API
9624SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9625 SQLINTEGER buflen)
9626{
9627 SQLRETURN ret;
9628
9630 ret = drvsetstmtattr(stmt, attr, val, buflen);
9632 return ret;
9633}
9634#endif
9635
9644static SQLRETURN
9645drvgetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9646{
9647 STMT *s = (STMT *) stmt;
9648 SQLUINTEGER *ret = (SQLUINTEGER *) param;
9649
9650 switch (opt) {
9651 case SQL_QUERY_TIMEOUT:
9652 *ret = 0;
9653 return SQL_SUCCESS;
9654 case SQL_CURSOR_TYPE:
9655 *ret = s->curtype;
9656 return SQL_SUCCESS;
9657 case SQL_ROW_NUMBER:
9658 if (s->s3stmt) {
9659 *ret = (s->s3stmt_rownum < 0) ?
9660 SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
9661 } else {
9662 *ret = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
9663 }
9664 return SQL_SUCCESS;
9665 case SQL_ASYNC_ENABLE:
9666 *ret = SQL_ASYNC_ENABLE_OFF;
9667 return SQL_SUCCESS;
9668 case SQL_CONCURRENCY:
9669 *ret = SQL_CONCUR_LOCK;
9670 return SQL_SUCCESS;
9671 case SQL_ATTR_RETRIEVE_DATA:
9672 *ret = s->retr_data;
9673 return SQL_SUCCESS;
9674 case SQL_ROWSET_SIZE:
9675 case SQL_ATTR_ROW_ARRAY_SIZE:
9676 *ret = s->rowset_size;
9677 return SQL_SUCCESS;
9678 case SQL_ATTR_MAX_ROWS:
9679 *ret = s->max_rows;
9680 return SQL_SUCCESS;
9681 case SQL_ATTR_MAX_LENGTH:
9682 *ret = 1000000000;
9683 return SQL_SUCCESS;
9684 }
9685 return drvunimplstmt(stmt);
9686}
9687
9696SQLRETURN SQL_API
9697SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9698{
9699 SQLRETURN ret;
9700
9702 ret = drvgetstmtoption(stmt, opt, param);
9704 return ret;
9705}
9706
9707#ifdef WINTERFACE
9716SQLRETURN SQL_API
9717SQLGetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9718{
9719 SQLRETURN ret;
9720
9722 ret = drvgetstmtoption(stmt, opt, param);
9724 return ret;
9725}
9726#endif
9727
9736static SQLRETURN
9737drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
9738{
9739 STMT *s = (STMT *) stmt;
9740
9741 switch (opt) {
9742 case SQL_CURSOR_TYPE:
9743 if (param == SQL_CURSOR_FORWARD_ONLY) {
9744 s->curtype = param;
9745 } else {
9746 s->curtype = SQL_CURSOR_STATIC;
9747 }
9748 if (param != SQL_CURSOR_FORWARD_ONLY &&
9749 param != SQL_CURSOR_STATIC) {
9750 goto e01s02;
9751 }
9752 return SQL_SUCCESS;
9753 case SQL_ASYNC_ENABLE:
9754 if (param != SQL_ASYNC_ENABLE_OFF) {
9755 goto e01s02;
9756 }
9757 return SQL_SUCCESS;
9758 case SQL_CONCURRENCY:
9759 if (param != SQL_CONCUR_LOCK) {
9760 goto e01s02;
9761 }
9762 return SQL_SUCCESS;
9763 case SQL_QUERY_TIMEOUT:
9764 return SQL_SUCCESS;
9765 case SQL_RETRIEVE_DATA:
9766 if (param != SQL_RD_ON && param != SQL_RD_OFF) {
9767 e01s02:
9768 setstat(s, -1, "option value changed", "01S02");
9769 return SQL_SUCCESS_WITH_INFO;
9770 }
9771 s->retr_data = (int) param;
9772 return SQL_SUCCESS;
9773 case SQL_ROWSET_SIZE:
9774 case SQL_ATTR_ROW_ARRAY_SIZE:
9775 if (param < 1) {
9776 setstat(s, -1, "invalid rowset size", "HY000");
9777 return SQL_ERROR;
9778 } else {
9779 SQLUSMALLINT *rst = &s->row_status1;
9780
9781 if (param > 1) {
9782 rst = xmalloc(sizeof (SQLUSMALLINT) * param);
9783 if (!rst) {
9784 return nomem(s);
9785 }
9786 }
9787 if (s->row_status0 != &s->row_status1) {
9788 freep(&s->row_status0);
9789 }
9790 s->row_status0 = rst;
9791 s->rowset_size = param;
9792 }
9793 return SQL_SUCCESS;
9794 case SQL_ATTR_MAX_ROWS:
9795 s->max_rows = param;
9796 return SQL_SUCCESS;
9797 case SQL_ATTR_MAX_LENGTH:
9798 if (param != 1000000000) {
9799 goto e01s02;
9800 }
9801 return SQL_SUCCESS;
9802 }
9803 return drvunimplstmt(stmt);
9804}
9805
9814SQLRETURN SQL_API
9815SQLSetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt,
9817{
9818 SQLRETURN ret;
9819
9821 ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
9823 return ret;
9824}
9825
9826#ifdef WINTERFACE
9835SQLRETURN SQL_API
9836SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt,
9838{
9839 SQLRETURN ret;
9840
9842 ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
9844 return ret;
9845}
9846#endif
9847
9854static SQLRETURN
9856{
9857 int i;
9858
9859 if (!s->bindcols || s->nbindcols < s->ncols) {
9860unbound:
9861 setstat(s, -1, "unbound columns", (*s->ov3) ? "HY000" : "S1000");
9862 return SQL_ERROR;
9863 }
9864 for (i = 0; i < s->ncols; i++) {
9865 BINDCOL *b = &s->bindcols[i];
9866
9867 if (b->type == SQL_UNKNOWN_TYPE || !b->valp) {
9868 goto unbound;
9869 }
9870 }
9871 return SQL_SUCCESS;
9872}
9873
9885static SQLRETURN
9886setposbind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
9887{
9888 DBC *d = (DBC *) s->dbc;
9889 SQLPOINTER dp = 0;
9890 SQLLEN *lp = 0;
9891 BINDCOL *b = &s->bindcols[i];
9892 COL *c = &s->cols[i];
9893 char strbuf[128], *cp;
9894
9895 if (b->valp) {
9896 if (s->bind_type != SQL_BIND_BY_COLUMN) {
9897 dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
9898 } else {
9899 dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
9900 }
9901 if (s->bind_offs) {
9902 dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
9903 }
9904 }
9905 if (b->lenp) {
9906 if (s->bind_type != SQL_BIND_BY_COLUMN) {
9907 lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
9908 } else {
9909 lp = b->lenp + rsi;
9910 }
9911 if (s->bind_offs) {
9912 lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
9913 }
9914 }
9915 if (!dp || !lp) {
9916 setstat(s, -1, "unbound column in positional update",
9917 (*s->ov3) ? "HY000" : "S1000");
9918 return SQL_ERROR;
9919 }
9920 if (*lp == SQL_NULL_DATA) {
9921 sqlite3_bind_null(stmt, si);
9922 if (d->trace) {
9923 fprintf(d->trace, "-- parameter %d: NULL\n", si);
9924 fflush(d->trace);
9925 }
9926 return SQL_SUCCESS;
9927 }
9928 switch (b->type) {
9929 case SQL_C_UTINYINT:
9930 case SQL_C_TINYINT:
9931 case SQL_C_STINYINT:
9932 sqlite3_bind_int(stmt, si, *(SQLCHAR *) dp);
9933 if (d->trace) {
9934 fprintf(d->trace, "-- parameter %d: %d\n", si, *(SQLCHAR *) dp);
9935 fflush(d->trace);
9936 }
9937 break;
9938#ifdef SQL_BIT
9939 case SQL_C_BIT:
9940 sqlite3_bind_int(stmt, si, (*(SQLCHAR *) dp) ? 1 : 0);
9941 if (d->trace) {
9942 fprintf(d->trace, "-- parameter %d: %d\n", si,
9943 (*(SQLCHAR *) dp) ? 1 : 0);
9944 fflush(d->trace);
9945 }
9946 break;
9947#endif
9948 case SQL_C_USHORT:
9949 sqlite3_bind_int(stmt, si, *(SQLUSMALLINT *) dp);
9950 if (d->trace) {
9951 fprintf(d->trace, "-- parameter %d: %d\n", si,
9952 *(SQLUSMALLINT *) dp);
9953 fflush(d->trace);
9954 }
9955 break;
9956 case SQL_C_SHORT:
9957 case SQL_C_SSHORT:
9958 sqlite3_bind_int(stmt, si, *(SQLSMALLINT *) dp);
9959 if (d->trace) {
9960 fprintf(d->trace, "-- parameter %d: %d\n", si,
9961 *(SQLSMALLINT *) dp);
9962 fflush(d->trace);
9963 }
9964 break;
9965 case SQL_C_ULONG:
9966 sqlite3_bind_int(stmt, si, *(SQLUINTEGER *) dp);
9967 if (d->trace) {
9968 fprintf(d->trace, "-- parameter %d: %ld\n", si,
9969 (long) *(SQLUINTEGER *) dp);
9970 fflush(d->trace);
9971 }
9972 break;
9973 case SQL_C_LONG:
9974 case SQL_C_SLONG:
9975 sqlite3_bind_int(stmt, si, *(SQLINTEGER *) dp);
9976 if (d->trace) {
9977 fprintf(d->trace, "-- parameter %d: %ld\n", si,
9978 (long) *(SQLINTEGER *) dp);
9979 fflush(d->trace);
9980 }
9981 break;
9982#ifdef SQL_BIGINT
9983 case SQL_C_UBIGINT:
9984 case SQL_C_SBIGINT:
9985 sqlite3_bind_int64(stmt, si, *(SQLBIGINT *) dp);
9986 if (d->trace) {
9987 fprintf(d->trace,
9988#ifdef _WIN32
9989 "-- parameter %d: %I64d\n",
9990#else
9991 "-- parameter %d: %lld\n",
9992#endif
9993 si, (sqlite_int64) *(SQLBIGINT *) dp);
9994 fflush(d->trace);
9995 }
9996 break;
9997#endif
9998 case SQL_C_FLOAT:
9999 sqlite3_bind_double(stmt, si, *(float *) dp);
10000 if (d->trace) {
10001 fprintf(d->trace, "-- parameter %d: %g\n", si,
10002 *(float *) dp);
10003 fflush(d->trace);
10004 }
10005 break;
10006 case SQL_C_DOUBLE:
10007 sqlite3_bind_double(stmt, si, *(double *) dp);
10008 if (d->trace) {
10009 fprintf(d->trace, "-- parameter %d: %g\n", si,
10010 *(double *) dp);
10011 fflush(d->trace);
10012 }
10013 break;
10014 case SQL_C_BINARY:
10015 sqlite3_bind_blob(stmt, si, (char *) dp, *lp, SQLITE_STATIC);
10016 if (d->trace) {
10017 fprintf(d->trace, "-- parameter %d: [BLOB]\n", si);
10018 fflush(d->trace);
10019 }
10020 break;
10021#ifdef WCHARSUPPORT
10022 case SQL_C_WCHAR:
10023 cp = uc_to_utf((SQLWCHAR *) dp, *lp);
10024 if (!cp) {
10025 return nomem(s);
10026 }
10027 sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
10028 if (d->trace) {
10029 fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
10030 fflush(d->trace);
10031 }
10032 uc_free(cp);
10033 break;
10034#endif
10035 case SQL_C_CHAR:
10036#if defined(_WIN32) || defined(_WIN64)
10037 if (*s->oemcp) {
10038 cp = wmb_to_utf((char *) dp, *lp);
10039 if (!cp) {
10040 return nomem(s);
10041 }
10042 sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
10043 if (d->trace) {
10044 fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
10045 fflush(d->trace);
10046 }
10047 uc_free(cp);
10048 } else
10049#endif
10050 {
10051 if (*lp == SQL_NTS) {
10052 sqlite3_bind_text(stmt, si, (char *) dp, -1,
10053 SQLITE_STATIC);
10054 if (d->trace) {
10055 fprintf(d->trace, "-- parameter %d: '%s'\n", si,
10056 (char *) dp);
10057 fflush(d->trace);
10058 }
10059 } else {
10060 sqlite3_bind_text(stmt, si, (char *) dp, *lp,
10061 SQLITE_STATIC);
10062 if (d->trace) {
10063 fprintf(d->trace, "-- parameter %d: '%*s'\n", si,
10064 (int) *lp, (char *) dp);
10065 fflush(d->trace);
10066 }
10067 }
10068 }
10069 break;
10070#ifdef SQL_C_TYPE_DATE
10071 case SQL_C_TYPE_DATE:
10072#endif
10073 case SQL_C_DATE:
10074 if (*s->jdconv) {
10075 int a, b, x1, x2, y, m, dd;
10076 double v;
10077
10078 y = ((DATE_STRUCT *) dp)->year;
10079 m = ((DATE_STRUCT *) dp)->month;
10080 dd = ((DATE_STRUCT *) dp)->day;
10081 if (m <= 2) {
10082 y--;
10083 m += 12;
10084 }
10085 a = y / 100;
10086 b = 2 - a + (a / 4);
10087 x1 = 36525 * (y + 4716) / 100;
10088 x2 = 306001 * (m + 1) / 10000;
10089 v = x1 + x2 + dd + b - 1524.5;
10090 sqlite3_bind_double(stmt, si, v);
10091 if (d->trace) {
10092 fprintf(d->trace, "-- parameter %d: %g\n", si, v);
10093 fflush(d->trace);
10094 }
10095 } else {
10096 sprintf(strbuf, "%04d-%02d-%02d",
10097 ((DATE_STRUCT *) dp)->year,
10098 ((DATE_STRUCT *) dp)->month,
10099 ((DATE_STRUCT *) dp)->day);
10100 sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
10101 if (d->trace) {
10102 fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
10103 fflush(d->trace);
10104 }
10105 }
10106 break;
10107#ifdef SQL_C_TYPE_TIME
10108 case SQL_C_TYPE_TIME:
10109#endif
10110 case SQL_C_TIME:
10111 if (*s->jdconv) {
10112 double v;
10113
10114 v = 2451544.5 +
10115 (((TIME_STRUCT *) dp)->hour * 3600000.0 +
10116 ((TIME_STRUCT *) dp)->minute * 60000.0 +
10117 ((TIME_STRUCT *) dp)->second * 1000.0) / 86400000.0;
10118 sqlite3_bind_double(stmt, si, v);
10119 if (d->trace) {
10120 fprintf(d->trace, "-- parameter %d: %g\n", si, v);
10121 fflush(d->trace);
10122 }
10123 } else {
10124 sprintf(strbuf, "%02d:%02d:%02d",
10125 ((TIME_STRUCT *) dp)->hour,
10126 ((TIME_STRUCT *) dp)->minute,
10127 ((TIME_STRUCT *) dp)->second);
10128 sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
10129 if (d->trace) {
10130 fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
10131 fflush(d->trace);
10132 }
10133 }
10134 break;
10135#ifdef SQL_C_TYPE_TIMESTAMP
10136 case SQL_C_TYPE_TIMESTAMP:
10137#endif
10138 case SQL_C_TIMESTAMP:
10139 if (*s->jdconv) {
10140 int a, b, x1, x2, y, m, dd;
10141 double v;
10142
10143 y = ((TIMESTAMP_STRUCT *) dp)->year;
10144 m = ((TIMESTAMP_STRUCT *) dp)->month;
10145 dd = ((TIMESTAMP_STRUCT *) dp)->day;
10146 if (m <= 2) {
10147 y--;
10148 m += 12;
10149 }
10150 a = y / 100;
10151 b = 2 - a + (a / 4);
10152 x1 = 36525 * (y + 4716) / 100;
10153 x2 = 306001 * (m + 1) / 10000;
10154 v = x1 + x2 + dd + b - 1524.5 +
10155 (((TIMESTAMP_STRUCT *) dp)->hour * 3600000.0 +
10156 ((TIMESTAMP_STRUCT *) dp)->minute * 60000.0 +
10157 ((TIMESTAMP_STRUCT *) dp)->second * 1000.0 +
10158 ((TIMESTAMP_STRUCT *) dp)->fraction / 1.0E6)
10159 / 86400000.0;
10160 sqlite3_bind_double(stmt, si, v);
10161 if (d->trace) {
10162 fprintf(d->trace, "-- parameter %d: %g\n", si, v);
10163 fflush(d->trace);
10164 }
10165 } else {
10166 int frac;
10167
10168 frac = (int) ((TIMESTAMP_STRUCT *) dp)->fraction;
10169 frac /= 1000000;
10170 frac = frac % 1000;
10171 if (frac < 0) {
10172 frac = 0;
10173 }
10174 if (c->prec && c->prec <= 16) {
10175 sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
10176 ((TIMESTAMP_STRUCT *) dp)->year,
10177 ((TIMESTAMP_STRUCT *) dp)->month,
10178 ((TIMESTAMP_STRUCT *) dp)->day,
10179 ((TIMESTAMP_STRUCT *) dp)->hour,
10180 ((TIMESTAMP_STRUCT *) dp)->minute);
10181 } else if (c->prec && c->prec <= 19) {
10182 sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
10183 ((TIMESTAMP_STRUCT *) dp)->year,
10184 ((TIMESTAMP_STRUCT *) dp)->month,
10185 ((TIMESTAMP_STRUCT *) dp)->day,
10186 ((TIMESTAMP_STRUCT *) dp)->hour,
10187 ((TIMESTAMP_STRUCT *) dp)->minute,
10188 ((TIMESTAMP_STRUCT *) dp)->second);
10189 } else {
10190 sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
10191 ((TIMESTAMP_STRUCT *) dp)->year,
10192 ((TIMESTAMP_STRUCT *) dp)->month,
10193 ((TIMESTAMP_STRUCT *) dp)->day,
10194 ((TIMESTAMP_STRUCT *) dp)->hour,
10195 ((TIMESTAMP_STRUCT *) dp)->minute,
10196 ((TIMESTAMP_STRUCT *) dp)->second,
10197 frac);
10198 }
10199 sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
10200 if (d->trace) {
10201 fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
10202 fflush(d->trace);
10203 }
10204 }
10205 break;
10206 default:
10207 setstat(s, -1, "unsupported column type in positional update",
10208 (*s->ov3) ? "HY000" : "S1000");
10209 return SQL_ERROR;
10210 }
10211 return SQL_SUCCESS;
10212}
10213
10225static SQLRETURN
10226setposibind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
10227{
10228 DBC *d = (DBC *) s->dbc;
10229 char **data;
10230 int pos;
10231
10232 pos = s->rowprs;
10233 if (pos < 0) {
10234 setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
10235 return SQL_ERROR;
10236 }
10237 pos += rsi;
10238 data = s->rows + s->ncols + (pos * s->ncols) + i;
10239 if (*data == NULL) {
10240 sqlite3_bind_null(stmt, si);
10241 if (d->trace) {
10242 fprintf(d->trace, "-- parameter %d: NULL\n", si);
10243 fflush(d->trace);
10244 }
10245 } else {
10246 sqlite3_bind_text(stmt, si, *data, -1, SQLITE_STATIC);
10247 if (d->trace) {
10248 fprintf(d->trace, "-- parameter %d: '%s'\n", si, *data);
10249 fflush(d->trace);
10250 }
10251 }
10252 return SQL_SUCCESS;
10253}
10254
10262static SQLRETURN
10263setposrefr(STMT *s, int rsi)
10264{
10265 int i, withinfo = 0;
10266 SQLRETURN ret = SQL_SUCCESS;
10267
10268 for (i = 0; s->bindcols && i < s->ncols; i++) {
10269 BINDCOL *b = &s->bindcols[i];
10270 SQLPOINTER dp = 0;
10271 SQLLEN *lp = 0;
10272
10273 b->offs = 0;
10274 if (b->valp) {
10275 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10276 dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
10277 } else {
10278 dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
10279 }
10280 if (s->bind_offs) {
10281 dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
10282 }
10283 }
10284 if (b->lenp) {
10285 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10286 lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
10287 } else {
10288 lp = b->lenp + rsi;
10289 }
10290 if (s->bind_offs) {
10291 lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
10292 }
10293 }
10294 if (dp || lp) {
10295 int rowp = s->rowp;
10296
10297 s->rowp = s->rowprs + rsi;
10298 ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp,
10299 b->max, lp, 0);
10300 s->rowp = rowp;
10301 if (!SQL_SUCCEEDED(ret)) {
10302 s->row_status0[rsi] = SQL_ROW_ERROR;
10303 break;
10304 }
10305 if (ret != SQL_SUCCESS) {
10306 withinfo = 1;
10307#ifdef SQL_ROW_SUCCESS_WITH_INFO
10308 s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
10309#endif
10310 }
10311 }
10312 }
10313 if (SQL_SUCCEEDED(ret)) {
10314 ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
10315 }
10316 return ret;
10317}
10318
10328static SQLRETURN
10329drvsetpos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10330{
10331 STMT *s = (STMT *) stmt;
10332 DBC *d = (DBC *) s->dbc;
10333 int rowp, i, k, rc, nretry = 0;
10334 dstr *sql = 0;
10335 const char *endp;
10336 sqlite3_stmt *s3stmt = NULL;
10337 SQLRETURN ret;
10338
10339 if (lock != SQL_LOCK_NO_CHANGE) {
10340 setstat(s, -1, "unsupported locking mode",
10341 (*s->ov3) ? "HY000" : "S1000");
10342 return SQL_ERROR;
10343 }
10344 if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10345 setstat(s, -1, "incompatible statement",
10346 (*s->ov3) ? "HY000" : "S1000");
10347 return SQL_ERROR;
10348 }
10349 if (op == SQL_ADD) {
10350 if (s->one_tbl <= 0) {
10351 setstat(s, -1, "incompatible rowset",
10352 (*s->ov3) ? "HY000" : "S1000");
10353 return SQL_ERROR;
10354 }
10355 if (row == 0 || row > s->rowset_size + 1) {
10356 goto rowoor;
10357 }
10358 ret = chkunbound(s);
10359 if (ret != SQL_SUCCESS) {
10360 return ret;
10361 }
10362 sql = dsappend(sql, "INSERT INTO ");
10363 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10364 sql = dsappendq(sql, s->dyncols[0].db);
10365 sql = dsappend(sql, ".");
10366 }
10367 sql = dsappendq(sql, s->dyncols[0].table);
10368 for (i = 0; i < s->ncols; i++) {
10369 sql = dsappend(sql, (i > 0) ? "," : "(");
10370 sql = dsappendq(sql, s->dyncols[i].column);
10371 }
10372 sql = dsappend(sql, ") VALUES ");
10373 for (i = 0; i < s->ncols; i++) {
10374 sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10375 }
10376 sql = dsappend(sql, ")");
10377 if (dserr(sql)) {
10378 dsfree(sql);
10379 return nomem(s);
10380 }
10381#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10382 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10383#else
10384 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10385#endif
10386 do {
10387 s3stmt = NULL;
10388#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10389 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10390 &s3stmt, &endp);
10391#else
10392 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10393 &s3stmt, &endp);
10394#endif
10395 if (rc != SQLITE_OK) {
10396 if (s3stmt) {
10397 sqlite3_finalize(s3stmt);
10398 s3stmt = NULL;
10399 }
10400 }
10401 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10402 dbtracerc(d, rc, NULL);
10403 dsfree(sql);
10404 if (rc != SQLITE_OK) {
10405istmterr:
10406 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10407 sqlite3_errmsg(d->sqlite), rc);
10408 if (s3stmt) {
10409 dbtraceapi(d, "sqlite3_finalize", NULL);
10410 sqlite3_finalize(s3stmt);
10411 }
10412 return SQL_ERROR;
10413 }
10414 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10415 ret = setposbind(s, s3stmt, i, k, row - 1);
10416 if (ret != SQL_SUCCESS) {
10417 dbtraceapi(d, "sqlite3_finalize", NULL);
10418 sqlite3_finalize(s3stmt);
10419 return ret;
10420 }
10421 k++;
10422 }
10423 rc = sqlite3_step(s3stmt);
10424 if (rc != SQLITE_DONE) {
10425 goto istmterr;
10426 }
10427 sqlite3_finalize(s3stmt);
10428 if (sqlite3_changes(d->sqlite) > 0 && row <= s->rowset_size) {
10429 if (s->row_status0) {
10430 s->row_status0[row - 1] = SQL_ROW_ADDED;
10431 }
10432 if (s->row_status) {
10433 s->row_status[row - 1] = SQL_ROW_ADDED;
10434 }
10435 }
10436 return SQL_SUCCESS;
10437 } else if (op == SQL_UPDATE || op == SQL_DELETE) {
10438 if (s->one_tbl <= 0 || s->has_pk <= 0) {
10439 setstat(s, -1, "incompatible rowset",
10440 (*s->ov3) ? "HY000" : "S1000");
10441 return SQL_ERROR;
10442 }
10443 if (row == 0) {
10444 ret = SQL_SUCCESS;
10445 for (i = 1; i <= s->rowset_size; i++) {
10446 ret = drvsetpos(stmt, i, op, lock);
10447 if (!SQL_SUCCEEDED(ret)) {
10448 break;
10449 }
10450 }
10451 return ret;
10452 }
10453 if (row > s->rowset_size) {
10454 goto rowoor;
10455 }
10456 }
10457 if (op != SQL_POSITION && op != SQL_REFRESH &&
10458 op != SQL_DELETE && op != SQL_UPDATE) {
10459 return drvunimplstmt(stmt);
10460 }
10461 if (op == SQL_POSITION) {
10462 rowp = s->rowp + row - 1;
10463 if (!s->rows || row == 0 || rowp < -1 || rowp >= s->nrows) {
10464rowoor:
10465 setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
10466 return SQL_ERROR;
10467 }
10468 s->rowp = rowp;
10469 } else if (op == SQL_REFRESH) {
10470 if (row > s->rowset_size) {
10471 goto rowoor;
10472 }
10473 if (row == 0) {
10474 ret = SQL_SUCCESS;
10475 for (i = 0; i < s->rowset_size; i++) {
10476 ret = setposrefr(s, i);
10477 if (!SQL_SUCCEEDED(ret)) {
10478 break;
10479 }
10480 }
10481 return ret;
10482 }
10483 return setposrefr(s, row - 1);
10484 } else if (op == SQL_DELETE) {
10485 sql = dsappend(sql, "DELETE FROM ");
10486 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10487 sql = dsappendq(sql, s->dyncols[0].db);
10488 sql = dsappend(sql, ".");
10489 }
10490 sql = dsappendq(sql, s->dyncols[0].table);
10491 for (i = k = 0; i < s->ncols; i++) {
10492 if (s->dyncols[i].ispk <= 0) {
10493 continue;
10494 }
10495 sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10496 sql = dsappendq(sql, s->dyncols[i].column);
10497 sql = dsappend(sql, " = ?");
10498 k++;
10499 }
10500 if (dserr(sql)) {
10501 dsfree(sql);
10502 return nomem(s);
10503 }
10504#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10505 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10506#else
10507 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10508#endif
10509 do {
10510 s3stmt = NULL;
10511#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10512 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10513 &s3stmt, &endp);
10514#else
10515 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10516 &s3stmt, &endp);
10517#endif
10518 if (rc != SQLITE_OK) {
10519 if (s3stmt) {
10520 sqlite3_finalize(s3stmt);
10521 s3stmt = NULL;
10522 }
10523 }
10524 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10525 dbtracerc(d, rc, NULL);
10526 dsfree(sql);
10527 if (rc != SQLITE_OK) {
10528dstmterr:
10529 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10530 sqlite3_errmsg(d->sqlite), rc);
10531 if (s3stmt) {
10532 dbtraceapi(d, "sqlite3_finalize", NULL);
10533 sqlite3_finalize(s3stmt);
10534 }
10535 return SQL_ERROR;
10536 }
10537 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10538 if (s->dyncols[i].ispk <= 0) {
10539 continue;
10540 }
10541 ret = setposibind(s, s3stmt, i, k, row - 1);
10542 if (ret != SQL_SUCCESS) {
10543 dbtraceapi(d, "sqlite3_finalize", NULL);
10544 sqlite3_finalize(s3stmt);
10545 return ret;
10546 }
10547 k++;
10548 }
10549 rc = sqlite3_step(s3stmt);
10550 if (rc != SQLITE_DONE) {
10551 goto dstmterr;
10552 }
10553 sqlite3_finalize(s3stmt);
10554 if (sqlite3_changes(d->sqlite) > 0) {
10555 if (s->row_status0) {
10556 s->row_status0[row - 1] = SQL_ROW_DELETED;
10557 }
10558 if (s->row_status) {
10559 s->row_status[row - 1] = SQL_ROW_DELETED;
10560 }
10561 }
10562 return SQL_SUCCESS;
10563 } else if (op == SQL_UPDATE) {
10564 ret = chkunbound(s);
10565 if (ret != SQL_SUCCESS) {
10566 return ret;
10567 }
10568 sql = dsappend(sql, "UPDATE ");
10569 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10570 sql = dsappendq(sql, s->dyncols[0].db);
10571 sql = dsappend(sql, ".");
10572 }
10573 sql = dsappendq(sql, s->dyncols[0].table);
10574 for (i = 0; i < s->ncols; i++) {
10575 sql = dsappend(sql, (i > 0) ? ", " : " SET ");
10576 sql = dsappendq(sql, s->dyncols[i].column);
10577 sql = dsappend(sql, " = ?");
10578 }
10579 for (i = k = 0; i < s->ncols; i++) {
10580 if (s->dyncols[i].ispk <= 0) {
10581 continue;
10582 }
10583 sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10584 sql = dsappendq(sql, s->dyncols[i].column);
10585 sql = dsappend(sql, " = ?");
10586 k++;
10587 }
10588 if (dserr(sql)) {
10589 dsfree(sql);
10590 return nomem(s);
10591 }
10592#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10593 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10594#else
10595 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10596#endif
10597 do {
10598 s3stmt = NULL;
10599#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10600 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10601 &s3stmt, &endp);
10602#else
10603 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10604 &s3stmt, &endp);
10605#endif
10606 if (rc != SQLITE_OK) {
10607 if (s3stmt) {
10608 sqlite3_finalize(s3stmt);
10609 s3stmt = NULL;
10610 }
10611 }
10612 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10613 dbtracerc(d, rc, NULL);
10614 dsfree(sql);
10615 if (rc != SQLITE_OK) {
10616ustmterr:
10617 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10618 sqlite3_errmsg(d->sqlite), rc);
10619 if (s3stmt) {
10620 dbtraceapi(d, "sqlite3_finalize", NULL);
10621 sqlite3_finalize(s3stmt);
10622 }
10623 return SQL_ERROR;
10624 }
10625 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10626 ret = setposbind(s, s3stmt, i, k, row - 1);
10627 if (ret != SQL_SUCCESS) {
10628 dbtraceapi(d, "sqlite3_finalize", NULL);
10629 sqlite3_finalize(s3stmt);
10630 return ret;
10631 }
10632 k++;
10633 }
10634 for (i = 0; s->bindcols && i < s->ncols; i++) {
10635 if (s->dyncols[i].ispk <= 0) {
10636 continue;
10637 }
10638 ret = setposibind(s, s3stmt, i, k, row - 1);
10639 if (ret != SQL_SUCCESS) {
10640 dbtraceapi(d, "sqlite3_finalize", NULL);
10641 sqlite3_finalize(s3stmt);
10642 return ret;
10643 }
10644 k++;
10645 }
10646 rc = sqlite3_step(s3stmt);
10647 if (rc != SQLITE_DONE) {
10648 goto ustmterr;
10649 }
10650 sqlite3_finalize(s3stmt);
10651 if (sqlite3_changes(d->sqlite) > 0) {
10652 if (s->row_status0) {
10653 s->row_status0[row - 1] = SQL_ROW_UPDATED;
10654 }
10655 if (s->row_status) {
10656 s->row_status[row - 1] = SQL_ROW_UPDATED;
10657 }
10658 }
10659 return SQL_SUCCESS;
10660 }
10661 return SQL_SUCCESS;
10662}
10663
10673SQLRETURN SQL_API
10674SQLSetPos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10675{
10676 SQLRETURN ret;
10677
10679 ret = drvsetpos(stmt, row, op, lock);
10681 return ret;
10682}
10683
10691static SQLRETURN
10692drvbulkoperations(SQLHSTMT stmt, SQLSMALLINT op)
10693{
10694 STMT *s = (STMT *) stmt;
10695 DBC *d = (DBC *) s->dbc;
10696 int row, i, k, rc, nretry = 0;
10697 dstr *sql = 0;
10698 const char *endp;
10699 sqlite3_stmt *s3stmt = NULL;
10700 SQLRETURN ret;
10701
10702 if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10703 setstat(s, -1, "incompatible statement",
10704 (*s->ov3) ? "HY000" : "S1000");
10705 return SQL_ERROR;
10706 }
10707 if (op == SQL_ADD) {
10708 if (s->one_tbl <= 0) {
10709 setstat(s, -1, "incompatible rowset",
10710 (*s->ov3) ? "HY000" : "S1000");
10711 return SQL_ERROR;
10712 }
10713 ret = chkunbound(s);
10714 if (ret != SQL_SUCCESS) {
10715 return ret;
10716 }
10717 sql = dsappend(sql, "INSERT INTO ");
10718 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10719 sql = dsappendq(sql, s->dyncols[0].db);
10720 sql = dsappend(sql, ".");
10721 }
10722 sql = dsappendq(sql, s->dyncols[0].table);
10723 for (i = 0; i < s->ncols; i++) {
10724 sql = dsappend(sql, (i > 0) ? "," : "(");
10725 sql = dsappendq(sql, s->dyncols[i].column);
10726 }
10727 sql = dsappend(sql, ") VALUES ");
10728 for (i = 0; i < s->ncols; i++) {
10729 sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10730 }
10731 sql = dsappend(sql, ")");
10732 if (dserr(sql)) {
10733 dsfree(sql);
10734 return nomem(s);
10735 }
10736#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10737 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10738#else
10739 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10740#endif
10741 do {
10742 s3stmt = NULL;
10743#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10744 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10745 &s3stmt, &endp);
10746#else
10747 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10748 &s3stmt, &endp);
10749#endif
10750 if (rc != SQLITE_OK) {
10751 if (s3stmt) {
10752 sqlite3_finalize(s3stmt);
10753 s3stmt = NULL;
10754 }
10755 }
10756 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10757 dbtracerc(d, rc, NULL);
10758 dsfree(sql);
10759 if (rc != SQLITE_OK) {
10760 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10761 sqlite3_errmsg(d->sqlite), rc);
10762 if (s3stmt) {
10763 dbtraceapi(d, "sqlite3_finalize", NULL);
10764 sqlite3_finalize(s3stmt);
10765 }
10766 return SQL_ERROR;
10767 }
10768 for (row = 0; row < s->rowset_size; row++) {
10769 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10770 ret = setposbind(s, s3stmt, i, k, row);
10771 if (ret != SQL_SUCCESS) {
10772istmterr:
10773 if (s->row_status0) {
10774 s->row_status0[row] = SQL_ROW_ERROR;
10775 }
10776 if (s->row_status) {
10777 s->row_status[row] = SQL_ROW_ERROR;
10778 }
10779 dbtraceapi(d, "sqlite3_finalize", NULL);
10780 sqlite3_finalize(s3stmt);
10781 return ret;
10782 }
10783 k++;
10784 }
10785 rc = sqlite3_step(s3stmt);
10786 if (rc != SQLITE_DONE) {
10787 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10788 sqlite3_errmsg(d->sqlite), rc);
10789 ret = SQL_ERROR;
10790 goto istmterr;
10791 }
10792 if (sqlite3_changes(d->sqlite) > 0) {
10793 if (s->row_status0) {
10794 s->row_status0[row] = SQL_ROW_ADDED;
10795 }
10796 if (s->row_status) {
10797 s->row_status[row] = SQL_ROW_ADDED;
10798 }
10799 }
10800 if (s->bkmrk == SQL_UB_VARIABLE &&
10801 s->bkmrkcol.type == SQL_C_VARBOOKMARK &&
10802 s->bkmrkcol.valp) {
10803 SQLPOINTER *val;
10804
10805 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10806 val = (SQLPOINTER)
10807 ((char *) s->bkmrkcol.valp + s->bind_type * row);
10808 } else {
10809 val = (SQLPOINTER)
10810 ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10811 }
10812 if (s->bind_offs) {
10813 val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10814 }
10815 *(sqlite_int64 *) val = sqlite3_last_insert_rowid(d->sqlite);
10816 if (s->bkmrkcol.lenp) {
10817 SQLLEN *ival;
10818
10819 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10820 ival = (SQLLEN *)
10821 ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10822 } else {
10823 ival = &s->bkmrkcol.lenp[row];
10824 }
10825 if (s->bind_offs) {
10826 ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10827 }
10828 *ival = sizeof (sqlite_int64);
10829 }
10830 }
10831 dbtraceapi(d, "sqlite3_reset", NULL);
10832 sqlite3_reset(s3stmt);
10833 }
10834 dbtraceapi(d, "sqlite3_finalize", NULL);
10835 sqlite3_finalize(s3stmt);
10836 return SQL_SUCCESS;
10837 } else if (op == SQL_DELETE_BY_BOOKMARK) {
10838 if (s->has_rowid < 0 ||
10839 s->bkmrk != SQL_UB_VARIABLE ||
10840 s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10841 !s->bkmrkcol.valp) {
10842 setstat(s, -1, "incompatible rowset",
10843 (*s->ov3) ? "HY000" : "S1000");
10844 return SQL_ERROR;
10845 }
10846 sql = dsappend(sql, "DELETE FROM ");
10847 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10848 sql = dsappendq(sql, s->dyncols[0].db);
10849 sql = dsappend(sql, ".");
10850 }
10851 sql = dsappendq(sql, s->dyncols[0].table);
10852 sql = dsappend(sql, " WHERE ");
10853 sql = dsappendq(sql, s->dyncols[0].column);
10854 sql = dsappend(sql, " = ?");
10855 if (dserr(sql)) {
10856 dsfree(sql);
10857 return nomem(s);
10858 }
10859#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10860 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10861#else
10862 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10863#endif
10864 do {
10865 s3stmt = NULL;
10866#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10867 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10868 &s3stmt, &endp);
10869#else
10870 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10871 &s3stmt, &endp);
10872#endif
10873 if (rc != SQLITE_OK) {
10874 if (s3stmt) {
10875 sqlite3_finalize(s3stmt);
10876 s3stmt = NULL;
10877 }
10878 }
10879 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10880 dbtracerc(d, rc, NULL);
10881 dsfree(sql);
10882 if (rc != SQLITE_OK) {
10883 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10884 sqlite3_errmsg(d->sqlite), rc);
10885 if (s3stmt) {
10886 dbtraceapi(d, "sqlite3_finalize", NULL);
10887 sqlite3_finalize(s3stmt);
10888 }
10889 return SQL_ERROR;
10890 }
10891 for (row = 0; row < s->rowset_size; row++) {
10892 SQLPOINTER *val;
10893 sqlite_int64 rowid;
10894
10895 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10896 val = (SQLPOINTER)
10897 ((char *) s->bkmrkcol.valp + s->bind_type * row);
10898 } else {
10899 val = (SQLPOINTER)
10900 ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10901 }
10902 if (s->bind_offs) {
10903 val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10904 }
10905 if (s->bkmrkcol.lenp) {
10906 SQLLEN *ival;
10907
10908 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10909 ival = (SQLLEN *)
10910 ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10911 } else {
10912 ival = &s->bkmrkcol.lenp[row];
10913 }
10914 if (s->bind_offs) {
10915 ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10916 }
10917 if (*ival != sizeof (sqlite_int64)) {
10918 continue;
10919 }
10920 }
10921 rowid = *(sqlite_int64 *) val;
10922 sqlite3_bind_int64(s3stmt, 1, rowid);
10923 if (d->trace) {
10924 fprintf(d->trace,
10925#ifdef _WIN32
10926 "-- parameter 1: %I64d\n",
10927#else
10928 "-- parameter 1: %lld\n",
10929#endif
10930 rowid);
10931 fflush(d->trace);
10932 }
10933 rc = sqlite3_step(s3stmt);
10934 if (rc != SQLITE_DONE) {
10935 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10936 sqlite3_errmsg(d->sqlite), rc);
10937 if (s->row_status0) {
10938 s->row_status0[row] = SQL_ROW_ERROR;
10939 }
10940 if (s->row_status) {
10941 s->row_status[row] = SQL_ROW_ERROR;
10942 }
10943 dbtraceapi(d, "sqlite3_finalize", NULL);
10944 sqlite3_finalize(s3stmt);
10945 return SQL_ERROR;
10946 }
10947 if (sqlite3_changes(d->sqlite) > 0) {
10948 if (s->row_status0) {
10949 s->row_status0[row] = SQL_ROW_DELETED;
10950 }
10951 if (s->row_status) {
10952 s->row_status[row] = SQL_ROW_DELETED;
10953 }
10954 }
10955 dbtraceapi(d, "sqlite3_reset", NULL);
10956 sqlite3_reset(s3stmt);
10957 }
10958 dbtraceapi(d, "sqlite3_finalize", NULL);
10959 sqlite3_finalize(s3stmt);
10960 return SQL_SUCCESS;
10961 } else if (op == SQL_UPDATE_BY_BOOKMARK) {
10962 if (s->has_rowid < 0 ||
10963 s->bkmrk != SQL_UB_VARIABLE ||
10964 s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10965 !s->bkmrkcol.valp) {
10966 setstat(s, -1, "incompatible rowset",
10967 (*s->ov3) ? "HY000" : "S1000");
10968 return SQL_ERROR;
10969 }
10970 ret = chkunbound(s);
10971 if (ret != SQL_SUCCESS) {
10972 return ret;
10973 }
10974 sql = dsappend(sql, "UPDATE ");
10975 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10976 sql = dsappendq(sql, s->dyncols[0].db);
10977 sql = dsappend(sql, ".");
10978 }
10979 sql = dsappendq(sql, s->dyncols[0].table);
10980 for (i = 0, k = 0; i < s->ncols; i++) {
10981 sql = dsappend(sql, (k > 0) ? ", " : " SET ");
10982 sql = dsappendq(sql, s->dyncols[i].column);
10983 sql = dsappend(sql, " = ?");
10984 k++;
10985 }
10986 sql = dsappend(sql, " WHERE ");
10987 sql = dsappendq(sql, s->dyncols[s->has_rowid].column);
10988 sql = dsappend(sql, " = ?");
10989 if (dserr(sql)) {
10990 dsfree(sql);
10991 return nomem(s);
10992 }
10993#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10994 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10995#else
10996 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10997#endif
10998 do {
10999 s3stmt = NULL;
11000#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
11001 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
11002 &s3stmt, &endp);
11003#else
11004 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
11005 &s3stmt, &endp);
11006#endif
11007 if (rc != SQLITE_OK) {
11008 if (s3stmt) {
11009 sqlite3_finalize(s3stmt);
11010 s3stmt = NULL;
11011 }
11012 }
11013 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
11014 dbtracerc(d, rc, NULL);
11015 dsfree(sql);
11016 if (rc != SQLITE_OK) {
11017 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
11018 sqlite3_errmsg(d->sqlite), rc);
11019 if (s3stmt) {
11020 dbtraceapi(d, "sqlite3_finalize", NULL);
11021 sqlite3_finalize(s3stmt);
11022 }
11023 return SQL_ERROR;
11024 }
11025 for (row = 0; row < s->rowset_size; row++) {
11026 SQLPOINTER *val;
11027 sqlite_int64 rowid;
11028
11029 if (s->bind_type != SQL_BIND_BY_COLUMN) {
11030 val = (SQLPOINTER)
11031 ((char *) s->bkmrkcol.valp + s->bind_type * row);
11032 } else {
11033 val = (SQLPOINTER)
11034 ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
11035 }
11036 if (s->bind_offs) {
11037 val = (SQLPOINTER) ((char *) val + *s->bind_offs);
11038 }
11039 if (s->bkmrkcol.lenp) {
11040 SQLLEN *ival;
11041
11042 if (s->bind_type != SQL_BIND_BY_COLUMN) {
11043 ival = (SQLLEN *)
11044 ((char *) s->bkmrkcol.lenp + s->bind_type * row);
11045 } else {
11046 ival = &s->bkmrkcol.lenp[row];
11047 }
11048 if (s->bind_offs) {
11049 ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
11050 }
11051 if (*ival != sizeof (sqlite_int64)) {
11052 continue;
11053 }
11054 }
11055 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
11056 ret = setposbind(s, s3stmt, i, k, row);
11057 if (ret != SQL_SUCCESS) {
11058ustmterr:
11059 if (s->row_status0) {
11060 s->row_status0[row] = SQL_ROW_ERROR;
11061 }
11062 if (s->row_status) {
11063 s->row_status[row] = SQL_ROW_ERROR;
11064 }
11065 dbtraceapi(d, "sqlite3_finalize", NULL);
11066 sqlite3_finalize(s3stmt);
11067 return ret;
11068 }
11069 k++;
11070 }
11071 rowid = *(sqlite_int64 *) val;
11072 sqlite3_bind_int64(s3stmt, k, rowid);
11073 if (d->trace) {
11074 fprintf(d->trace,
11075#ifdef _WIN32
11076 "-- parameter %d: %I64d\n",
11077#else
11078 "-- parameter %d: %lld\n",
11079#endif
11080 k, rowid);
11081 fflush(d->trace);
11082 }
11083 rc = sqlite3_step(s3stmt);
11084 if (rc != SQLITE_DONE) {
11085 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
11086 sqlite3_errmsg(d->sqlite), rc);
11087 ret = SQL_ERROR;
11088 goto ustmterr;
11089 }
11090 if (sqlite3_changes(d->sqlite) > 0) {
11091 if (s->row_status0) {
11092 s->row_status0[row] = SQL_ROW_UPDATED;
11093 }
11094 if (s->row_status) {
11095 s->row_status[row] = SQL_ROW_UPDATED;
11096 }
11097 }
11098 dbtraceapi(d, "sqlite3_reset", NULL);
11099 sqlite3_reset(s3stmt);
11100 }
11101 dbtraceapi(d, "sqlite3_finalize", NULL);
11102 sqlite3_finalize(s3stmt);
11103 return SQL_SUCCESS;
11104 }
11105 setstat(s, -1, "unsupported operation", (*s->ov3) ? "HY000" : "S1000");
11106 return SQL_ERROR;
11107}
11108
11116SQLRETURN SQL_API
11117SQLBulkOperations(SQLHSTMT stmt, SQLSMALLINT oper)
11118{
11119 SQLRETURN ret;
11120
11122 ret = drvbulkoperations(stmt, oper);
11124 return ret;
11125}
11126
11127
11132SQLRETURN SQL_API
11133SQLSetScrollOptions(SQLHSTMT stmt, SQLUSMALLINT concur, SQLLEN rowkeyset,
11134 SQLUSMALLINT rowset)
11135{
11136 SQLRETURN ret;
11137
11139 ret = drvunimplstmt(stmt);
11141 return ret;
11142}
11143
11144#define strmak(dst, src, max, lenp) { \
11145 int len = strlen(src); \
11146 int cnt = min(len + 1, max); \
11147 strncpy(dst, src, cnt); \
11148 *lenp = (cnt > len) ? len : cnt; \
11149}
11150
11161static SQLRETURN
11162drvgetinfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11163 SQLSMALLINT *valLen)
11164{
11165 DBC *d;
11166 char dummyc[301];
11167 SQLSMALLINT dummy;
11168#if defined(_WIN32) || defined(_WIN64)
11169 char pathbuf[301], *drvname;
11170#else
11171 static char drvname[] = "sqlite3odbc.so";
11172#endif
11173
11174 if (dbc == SQL_NULL_HDBC) {
11175 return SQL_INVALID_HANDLE;
11176 }
11177 d = (DBC *) dbc;
11178 if (valMax) {
11179 valMax--;
11180 }
11181 if (!valLen) {
11182 valLen = &dummy;
11183 }
11184 if (!val) {
11185 val = dummyc;
11186 valMax = sizeof (dummyc) - 1;
11187 }
11188 switch (type) {
11189 case SQL_MAX_USER_NAME_LEN:
11190 *((SQLSMALLINT *) val) = 16;
11191 *valLen = sizeof (SQLSMALLINT);
11192 break;
11193 case SQL_USER_NAME:
11194 strmak(val, "", valMax, valLen);
11195 break;
11196 case SQL_DRIVER_ODBC_VER:
11197#if 0
11198 strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
11199#else
11200 strmak(val, "03.00", valMax, valLen);
11201#endif
11202 break;
11203 case SQL_ACTIVE_CONNECTIONS:
11204 case SQL_ACTIVE_STATEMENTS:
11205 *((SQLSMALLINT *) val) = 0;
11206 *valLen = sizeof (SQLSMALLINT);
11207 break;
11208#ifdef SQL_ASYNC_MODE
11209 case SQL_ASYNC_MODE:
11210 *((SQLUINTEGER *) val) = SQL_AM_NONE;
11211 *valLen = sizeof (SQLUINTEGER);
11212 break;
11213#endif
11214#ifdef SQL_CREATE_TABLE
11215 case SQL_CREATE_TABLE:
11216 *((SQLUINTEGER *) val) = SQL_CT_CREATE_TABLE |
11217 SQL_CT_COLUMN_DEFAULT |
11218 SQL_CT_COLUMN_CONSTRAINT |
11219 SQL_CT_CONSTRAINT_NON_DEFERRABLE;
11220 *valLen = sizeof (SQLUINTEGER);
11221 break;
11222#endif
11223#ifdef SQL_CREATE_VIEW
11224 case SQL_CREATE_VIEW:
11225 *((SQLUINTEGER *) val) = SQL_CV_CREATE_VIEW;
11226 *valLen = sizeof (SQLUINTEGER);
11227 break;
11228#endif
11229#ifdef SQL_DDL_INDEX
11230 case SQL_DDL_INDEX:
11231 *((SQLUINTEGER *) val) = SQL_DI_CREATE_INDEX | SQL_DI_DROP_INDEX;
11232 *valLen = sizeof (SQLUINTEGER);
11233 break;
11234#endif
11235#ifdef SQL_DROP_TABLE
11236 case SQL_DROP_TABLE:
11237 *((SQLUINTEGER *) val) = SQL_DT_DROP_TABLE;
11238 *valLen = sizeof (SQLUINTEGER);
11239 break;
11240#endif
11241#ifdef SQL_DROP_VIEW
11242 case SQL_DROP_VIEW:
11243 *((SQLUINTEGER *) val) = SQL_DV_DROP_VIEW;
11244 *valLen = sizeof (SQLUINTEGER);
11245 break;
11246#endif
11247#ifdef SQL_INDEX_KEYWORDS
11248 case SQL_INDEX_KEYWORDS:
11249 *((SQLUINTEGER *) val) = SQL_IK_ALL;
11250 *valLen = sizeof (SQLUINTEGER);
11251 break;
11252#endif
11253 case SQL_DATA_SOURCE_NAME:
11254 strmak(val, d->dsn ? d->dsn : "", valMax, valLen);
11255 break;
11256 case SQL_DRIVER_NAME:
11257#if defined(_WIN32) || defined(_WIN64)
11258 GetModuleFileName(hModule, pathbuf, sizeof (pathbuf));
11259 drvname = strrchr(pathbuf, '\\');
11260 if (drvname == NULL) {
11261 drvname = strrchr(pathbuf, '/');
11262 }
11263 if (drvname == NULL) {
11264 drvname = pathbuf;
11265 } else {
11266 drvname++;
11267 }
11268#endif
11269 strmak(val, drvname, valMax, valLen);
11270 break;
11271 case SQL_DRIVER_VER:
11272 strmak(val, DRIVER_VER_INFO, valMax, valLen);
11273 break;
11274 case SQL_FETCH_DIRECTION:
11275 *((SQLUINTEGER *) val) = SQL_FD_FETCH_NEXT | SQL_FD_FETCH_FIRST |
11276 SQL_FD_FETCH_LAST | SQL_FD_FETCH_PRIOR | SQL_FD_FETCH_ABSOLUTE;
11277 *valLen = sizeof (SQLUINTEGER);
11278 break;
11279 case SQL_ODBC_VER:
11280 strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
11281 break;
11282 case SQL_ODBC_SAG_CLI_CONFORMANCE:
11283 *((SQLSMALLINT *) val) = SQL_OSCC_NOT_COMPLIANT;
11284 *valLen = sizeof (SQLSMALLINT);
11285 break;
11286 case SQL_STANDARD_CLI_CONFORMANCE:
11287 *((SQLUINTEGER *) val) = SQL_SCC_XOPEN_CLI_VERSION1;
11288 *valLen = sizeof (SQLUINTEGER);
11289 break;
11290 case SQL_SQL_CONFORMANCE:
11291 *((SQLUINTEGER *) val) = SQL_SC_SQL92_ENTRY;
11292 *valLen = sizeof (SQLUINTEGER);
11293 break;
11294 case SQL_SERVER_NAME:
11295 case SQL_DATABASE_NAME:
11296 strmak(val, d->dbname ? d->dbname : "", valMax, valLen);
11297 break;
11298 case SQL_SEARCH_PATTERN_ESCAPE:
11299 strmak(val, "\\", valMax, valLen);
11300 break;
11301 case SQL_ODBC_SQL_CONFORMANCE:
11302 *((SQLSMALLINT *) val) = SQL_OSC_MINIMUM;
11303 *valLen = sizeof (SQLSMALLINT);
11304 break;
11305 case SQL_ODBC_API_CONFORMANCE:
11306 *((SQLSMALLINT *) val) = SQL_OAC_LEVEL1;
11307 *valLen = sizeof (SQLSMALLINT);
11308 break;
11309 case SQL_DBMS_NAME:
11310 strmak(val, "SQLite", valMax, valLen);
11311 break;
11312 case SQL_DBMS_VER:
11313 strmak(val, SQLITE_VERSION, valMax, valLen);
11314 break;
11315 case SQL_COLUMN_ALIAS:
11316 case SQL_NEED_LONG_DATA_LEN:
11317 case SQL_OUTER_JOINS:
11318 strmak(val, "Y", valMax, valLen);
11319 break;
11320 case SQL_ROW_UPDATES:
11321 case SQL_ACCESSIBLE_PROCEDURES:
11322 case SQL_PROCEDURES:
11323 case SQL_EXPRESSIONS_IN_ORDERBY:
11324 case SQL_ODBC_SQL_OPT_IEF:
11325 case SQL_LIKE_ESCAPE_CLAUSE:
11326 case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11327 case SQL_ACCESSIBLE_TABLES:
11328 case SQL_MULT_RESULT_SETS:
11329 case SQL_MULTIPLE_ACTIVE_TXN:
11330 case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11331 strmak(val, "N", valMax, valLen);
11332 break;
11333#ifdef SQL_CATALOG_NAME
11334 case SQL_CATALOG_NAME:
11335#if defined(_WIN32) || defined(_WIN64)
11336 strmak(val, d->xcelqrx ? "Y" : "N", valMax, valLen);
11337#else
11338 strmak(val, "N", valMax, valLen);
11339#endif
11340 break;
11341#endif
11342 case SQL_DATA_SOURCE_READ_ONLY:
11343 strmak(val, "N", valMax, valLen);
11344 break;
11345#ifdef SQL_OJ_CAPABILITIES
11346 case SQL_OJ_CAPABILITIES:
11347 *((SQLUINTEGER *) val) = SQL_OJ_LEFT;
11348 *valLen = sizeof (SQLUINTEGER);
11349 break;
11350#endif
11351#ifdef SQL_MAX_IDENTIFIER_LEN
11352 case SQL_MAX_IDENTIFIER_LEN:
11353 *((SQLUSMALLINT *) val) = 255;
11354 *valLen = sizeof (SQLUSMALLINT);
11355 break;
11356#endif
11357 case SQL_CONCAT_NULL_BEHAVIOR:
11358 *((SQLSMALLINT *) val) = SQL_CB_NULL;
11359 *valLen = sizeof (SQLSMALLINT);
11360 break;
11361 case SQL_CURSOR_COMMIT_BEHAVIOR:
11362 case SQL_CURSOR_ROLLBACK_BEHAVIOR:
11363 *((SQLSMALLINT *) val) = SQL_CB_PRESERVE;
11364 *valLen = sizeof (SQLSMALLINT);
11365 break;
11366#ifdef SQL_CURSOR_SENSITIVITY
11367 case SQL_CURSOR_SENSITIVITY:
11368 *((SQLUINTEGER *) val) = SQL_UNSPECIFIED;
11369 *valLen = sizeof (SQLUINTEGER);
11370 break;
11371#endif
11372 case SQL_DEFAULT_TXN_ISOLATION:
11373 *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11374 *valLen = sizeof (SQLUINTEGER);
11375 break;
11376#ifdef SQL_DESCRIBE_PARAMETER
11377 case SQL_DESCRIBE_PARAMETER:
11378 strmak(val, "Y", valMax, valLen);
11379 break;
11380#endif
11381 case SQL_TXN_ISOLATION_OPTION:
11382 *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11383 *valLen = sizeof (SQLUINTEGER);
11384 break;
11385 case SQL_IDENTIFIER_CASE:
11386 *((SQLSMALLINT *) val) = SQL_IC_SENSITIVE;
11387 *valLen = sizeof (SQLSMALLINT);
11388 break;
11389 case SQL_IDENTIFIER_QUOTE_CHAR:
11390 strmak(val, "\"", valMax, valLen);
11391 break;
11392 case SQL_MAX_TABLE_NAME_LEN:
11393 case SQL_MAX_COLUMN_NAME_LEN:
11394 *((SQLSMALLINT *) val) = 255;
11395 *valLen = sizeof (SQLSMALLINT);
11396 break;
11397 case SQL_MAX_CURSOR_NAME_LEN:
11398 *((SQLSMALLINT *) val) = 255;
11399 *valLen = sizeof (SQLSMALLINT);
11400 break;
11401 case SQL_MAX_PROCEDURE_NAME_LEN:
11402 *((SQLSMALLINT *) val) = 0;
11403 break;
11404 case SQL_MAX_QUALIFIER_NAME_LEN:
11405 case SQL_MAX_OWNER_NAME_LEN:
11406 *((SQLSMALLINT *) val) = 255;
11407 break;
11408 case SQL_OWNER_TERM:
11409 strmak(val, "", valMax, valLen);
11410 break;
11411 case SQL_PROCEDURE_TERM:
11412 strmak(val, "PROCEDURE", valMax, valLen);
11413 break;
11414 case SQL_QUALIFIER_NAME_SEPARATOR:
11415 strmak(val, ".", valMax, valLen);
11416 break;
11417 case SQL_QUALIFIER_TERM:
11418#if defined(_WIN32) || defined(_WIN64)
11419 strmak(val, d->xcelqrx ? "catalog" : "", valMax, valLen);
11420#else
11421 strmak(val, "", valMax, valLen);
11422#endif
11423 break;
11424 case SQL_QUALIFIER_USAGE:
11425#if defined(_WIN32) || defined(_WIN64)
11426 *((SQLUINTEGER *) val) = d->xcelqrx ?
11427 (SQL_CU_DML_STATEMENTS | SQL_CU_INDEX_DEFINITION |
11428 SQL_CU_TABLE_DEFINITION) : 0;
11429#else
11430 *((SQLUINTEGER *) val) = 0;
11431#endif
11432 *valLen = sizeof (SQLUINTEGER);
11433 break;
11434 case SQL_SCROLL_CONCURRENCY:
11435 *((SQLUINTEGER *) val) = SQL_SCCO_LOCK;
11436 *valLen = sizeof (SQLUINTEGER);
11437 break;
11438 case SQL_SCROLL_OPTIONS:
11439 *((SQLUINTEGER *) val) = SQL_SO_STATIC | SQL_SO_FORWARD_ONLY;
11440 *valLen = sizeof (SQLUINTEGER);
11441 break;
11442 case SQL_TABLE_TERM:
11443 strmak(val, "TABLE", valMax, valLen);
11444 break;
11445 case SQL_TXN_CAPABLE:
11446 *((SQLSMALLINT *) val) = SQL_TC_ALL;
11447 *valLen = sizeof (SQLSMALLINT);
11448 break;
11449 case SQL_CONVERT_FUNCTIONS:
11450 *((SQLUINTEGER *) val) = 0;
11451 *valLen = sizeof (SQLUINTEGER);
11452 break;
11453 case SQL_SYSTEM_FUNCTIONS:
11454 case SQL_NUMERIC_FUNCTIONS:
11455 case SQL_STRING_FUNCTIONS:
11456 case SQL_TIMEDATE_FUNCTIONS:
11457 *((SQLUINTEGER *) val) = 0;
11458 *valLen = sizeof (SQLUINTEGER);
11459 break;
11460 case SQL_CONVERT_BIGINT:
11461 case SQL_CONVERT_BIT:
11462 case SQL_CONVERT_CHAR:
11463 case SQL_CONVERT_DATE:
11464 case SQL_CONVERT_DECIMAL:
11465 case SQL_CONVERT_DOUBLE:
11466 case SQL_CONVERT_FLOAT:
11467 case SQL_CONVERT_INTEGER:
11468 case SQL_CONVERT_LONGVARCHAR:
11469 case SQL_CONVERT_NUMERIC:
11470 case SQL_CONVERT_REAL:
11471 case SQL_CONVERT_SMALLINT:
11472 case SQL_CONVERT_TIME:
11473 case SQL_CONVERT_TIMESTAMP:
11474 case SQL_CONVERT_TINYINT:
11475 case SQL_CONVERT_VARCHAR:
11476 *((SQLUINTEGER *) val) =
11477 SQL_CVT_CHAR | SQL_CVT_NUMERIC | SQL_CVT_DECIMAL |
11478 SQL_CVT_INTEGER | SQL_CVT_SMALLINT | SQL_CVT_FLOAT | SQL_CVT_REAL |
11479 SQL_CVT_DOUBLE | SQL_CVT_VARCHAR | SQL_CVT_LONGVARCHAR |
11480 SQL_CVT_BIT | SQL_CVT_TINYINT | SQL_CVT_BIGINT |
11481 SQL_CVT_DATE | SQL_CVT_TIME | SQL_CVT_TIMESTAMP;
11482 *valLen = sizeof (SQLUINTEGER);
11483 break;
11484 case SQL_CONVERT_BINARY:
11485 case SQL_CONVERT_VARBINARY:
11486 case SQL_CONVERT_LONGVARBINARY:
11487 *((SQLUINTEGER *) val) = 0;
11488 *valLen = sizeof (SQLUINTEGER);
11489 break;
11490 case SQL_POSITIONED_STATEMENTS:
11491 *((SQLUINTEGER *) val) = 0;
11492 *valLen = sizeof (SQLUINTEGER);
11493 break;
11494 case SQL_LOCK_TYPES:
11495 *((SQLUINTEGER *) val) = SQL_LCK_NO_CHANGE;
11496 *valLen = sizeof (SQLUINTEGER);
11497 break;
11498 case SQL_BOOKMARK_PERSISTENCE:
11499 *((SQLUINTEGER *) val) = SQL_BP_SCROLL;
11500 *valLen = sizeof (SQLUINTEGER);
11501 break;
11502 case SQL_UNION:
11503 *((SQLUINTEGER *) val) = SQL_U_UNION | SQL_U_UNION_ALL;
11504 *valLen = sizeof (SQLUINTEGER);
11505 break;
11506 case SQL_OWNER_USAGE:
11507 case SQL_SUBQUERIES:
11508 case SQL_TIMEDATE_ADD_INTERVALS:
11509 case SQL_TIMEDATE_DIFF_INTERVALS:
11510 *((SQLUINTEGER *) val) = 0;
11511 *valLen = sizeof (SQLUINTEGER);
11512 break;
11513 case SQL_QUOTED_IDENTIFIER_CASE:
11514 *((SQLUSMALLINT *) val) = SQL_IC_SENSITIVE;
11515 *valLen = sizeof (SQLUSMALLINT);
11516 break;
11517 case SQL_POS_OPERATIONS:
11518 *((SQLUINTEGER *) val) = SQL_POS_POSITION | SQL_POS_UPDATE |
11519 SQL_POS_DELETE | SQL_POS_ADD | SQL_POS_REFRESH;
11520 *valLen = sizeof (SQLUINTEGER);
11521 break;
11522 case SQL_ALTER_TABLE:
11523 *((SQLUINTEGER *) val) = 0;
11524 *valLen = sizeof (SQLUINTEGER);
11525 break;
11526 case SQL_CORRELATION_NAME:
11527 *((SQLSMALLINT *) val) = SQL_CN_ANY;
11528 *valLen = sizeof (SQLSMALLINT);
11529 break;
11530 case SQL_NON_NULLABLE_COLUMNS:
11531 *((SQLSMALLINT *) val) = SQL_NNC_NON_NULL;
11532 *valLen = sizeof (SQLSMALLINT);
11533 break;
11534 case SQL_NULL_COLLATION:
11535 *((SQLSMALLINT *) val) = SQL_NC_START;
11536 *valLen = sizeof (SQLSMALLINT);
11537 break;
11538 case SQL_MAX_COLUMNS_IN_GROUP_BY:
11539 case SQL_MAX_COLUMNS_IN_ORDER_BY:
11540 case SQL_MAX_COLUMNS_IN_SELECT:
11541 case SQL_MAX_COLUMNS_IN_TABLE:
11542 case SQL_MAX_ROW_SIZE:
11543 case SQL_MAX_TABLES_IN_SELECT:
11544 *((SQLSMALLINT *) val) = 0;
11545 *valLen = sizeof (SQLSMALLINT);
11546 break;
11547 case SQL_MAX_BINARY_LITERAL_LEN:
11548 case SQL_MAX_CHAR_LITERAL_LEN:
11549 *((SQLUINTEGER *) val) = 0;
11550 *valLen = sizeof (SQLUINTEGER);
11551 break;
11552 case SQL_MAX_COLUMNS_IN_INDEX:
11553 *((SQLSMALLINT *) val) = 0;
11554 *valLen = sizeof (SQLSMALLINT);
11555 break;
11556 case SQL_MAX_INDEX_SIZE:
11557 *((SQLUINTEGER *) val) = 0;
11558 *valLen = sizeof (SQLUINTEGER);
11559 break;
11560#ifdef SQL_MAX_IDENTIFIER_LENGTH
11561 case SQL_MAX_IDENTIFIER_LENGTH:
11562 *((SQLUINTEGER *) val) = 255;
11563 *valLen = sizeof (SQLUINTEGER);
11564 break;
11565#endif
11566 case SQL_MAX_STATEMENT_LEN:
11567 *((SQLUINTEGER *) val) = 16384;
11568 *valLen = sizeof (SQLUINTEGER);
11569 break;
11570 case SQL_QUALIFIER_LOCATION:
11571 *((SQLSMALLINT *) val) = SQL_QL_START;
11572 *valLen = sizeof (SQLSMALLINT);
11573 break;
11574 case SQL_GETDATA_EXTENSIONS:
11575 *((SQLUINTEGER *) val) =
11576 SQL_GD_ANY_COLUMN | SQL_GD_ANY_ORDER | SQL_GD_BOUND;
11577 *valLen = sizeof (SQLUINTEGER);
11578 break;
11579 case SQL_STATIC_SENSITIVITY:
11580 *((SQLUINTEGER *) val) = 0;
11581 *valLen = sizeof (SQLUINTEGER);
11582 break;
11583 case SQL_FILE_USAGE:
11584#if defined(_WIN32) || defined(_WIN64)
11585 *((SQLSMALLINT *) val) =
11586 d->xcelqrx ? SQL_FILE_CATALOG : SQL_FILE_NOT_SUPPORTED;
11587#else
11588 *((SQLSMALLINT *) val) = SQL_FILE_NOT_SUPPORTED;
11589#endif
11590 *valLen = sizeof (SQLSMALLINT);
11591 break;
11592 case SQL_GROUP_BY:
11593 *((SQLSMALLINT *) val) = SQL_GB_GROUP_BY_EQUALS_SELECT;
11594 *valLen = sizeof (SQLSMALLINT);
11595 break;
11596 case SQL_KEYWORDS:
11597 strmak(val, "CREATE,SELECT,DROP,DELETE,UPDATE,INSERT,"
11598 "INTO,VALUES,TABLE,INDEX,FROM,SET,WHERE,AND,CURRENT,OF",
11599 valMax, valLen);
11600 break;
11601 case SQL_SPECIAL_CHARACTERS:
11602#ifdef SQL_COLLATION_SEQ
11603 case SQL_COLLATION_SEQ:
11604#endif
11605 strmak(val, "", valMax, valLen);
11606 break;
11607 case SQL_BATCH_SUPPORT:
11608 case SQL_BATCH_ROW_COUNT:
11609 case SQL_PARAM_ARRAY_ROW_COUNTS:
11610 *((SQLUINTEGER *) val) = 0;
11611 *valLen = sizeof (SQLUINTEGER);
11612 break;
11613 case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1:
11614 *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_BOOKMARK;
11615 *valLen = sizeof (SQLUINTEGER);
11616 break;
11617 case SQL_STATIC_CURSOR_ATTRIBUTES1:
11618 *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE |
11619 SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK | SQL_CA1_POS_POSITION |
11620 SQL_CA1_POS_DELETE | SQL_CA1_POS_UPDATE | SQL_CA1_POS_REFRESH |
11621 SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_BULK_ADD |
11622 SQL_CA1_BULK_UPDATE_BY_BOOKMARK | SQL_CA1_BULK_DELETE_BY_BOOKMARK;
11623 *valLen = sizeof (SQLUINTEGER);
11624 break;
11625 case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2:
11626 case SQL_STATIC_CURSOR_ATTRIBUTES2:
11627 *((SQLUINTEGER *) val) = SQL_CA2_READ_ONLY_CONCURRENCY |
11628 SQL_CA2_LOCK_CONCURRENCY;
11629 *valLen = sizeof (SQLUINTEGER);
11630 break;
11631 case SQL_KEYSET_CURSOR_ATTRIBUTES1:
11632 case SQL_KEYSET_CURSOR_ATTRIBUTES2:
11633 case SQL_DYNAMIC_CURSOR_ATTRIBUTES1:
11634 case SQL_DYNAMIC_CURSOR_ATTRIBUTES2:
11635 *((SQLUINTEGER *) val) = 0;
11636 *valLen = sizeof (SQLUINTEGER);
11637 break;
11638 case SQL_ODBC_INTERFACE_CONFORMANCE:
11639 *((SQLUINTEGER *) val) = SQL_OIC_CORE;
11640 *valLen = sizeof (SQLUINTEGER);
11641 break;
11642 default:
11643 setstatd(d, -1, "unsupported info option %d",
11644 (*d->ov3) ? "HYC00" : "S1C00", type);
11645 return SQL_ERROR;
11646 }
11647 return SQL_SUCCESS;
11648}
11649
11650#if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
11661SQLRETURN SQL_API
11662SQLGetInfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11663 SQLSMALLINT *valLen)
11664{
11665 SQLRETURN ret;
11666
11667 HDBC_LOCK(dbc);
11668 ret = drvgetinfo(dbc, type, val, valMax, valLen);
11670 return ret;
11671}
11672#endif
11673
11674#ifdef WINTERFACE
11685SQLRETURN SQL_API
11686SQLGetInfoW(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11687 SQLSMALLINT *valLen)
11688{
11689 SQLRETURN ret;
11690 SQLSMALLINT len = 0;
11691
11692 HDBC_LOCK(dbc);
11693 ret = drvgetinfo(dbc, type, val, valMax, &len);
11695 if (ret == SQL_SUCCESS) {
11696 SQLWCHAR *v = NULL;
11697
11698 switch (type) {
11699 case SQL_USER_NAME:
11700 case SQL_DRIVER_ODBC_VER:
11701 case SQL_DATA_SOURCE_NAME:
11702 case SQL_DRIVER_NAME:
11703 case SQL_DRIVER_VER:
11704 case SQL_ODBC_VER:
11705 case SQL_SERVER_NAME:
11706 case SQL_DATABASE_NAME:
11707 case SQL_SEARCH_PATTERN_ESCAPE:
11708 case SQL_DBMS_NAME:
11709 case SQL_DBMS_VER:
11710 case SQL_NEED_LONG_DATA_LEN:
11711 case SQL_ROW_UPDATES:
11712 case SQL_ACCESSIBLE_PROCEDURES:
11713 case SQL_PROCEDURES:
11714 case SQL_EXPRESSIONS_IN_ORDERBY:
11715 case SQL_ODBC_SQL_OPT_IEF:
11716 case SQL_LIKE_ESCAPE_CLAUSE:
11717 case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11718 case SQL_OUTER_JOINS:
11719 case SQL_COLUMN_ALIAS:
11720 case SQL_ACCESSIBLE_TABLES:
11721 case SQL_MULT_RESULT_SETS:
11722 case SQL_MULTIPLE_ACTIVE_TXN:
11723 case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11724 case SQL_DATA_SOURCE_READ_ONLY:
11725#ifdef SQL_DESCRIBE_PARAMETER
11726 case SQL_DESCRIBE_PARAMETER:
11727#endif
11728 case SQL_IDENTIFIER_QUOTE_CHAR:
11729 case SQL_OWNER_TERM:
11730 case SQL_PROCEDURE_TERM:
11731 case SQL_QUALIFIER_NAME_SEPARATOR:
11732 case SQL_QUALIFIER_TERM:
11733 case SQL_TABLE_TERM:
11734 case SQL_KEYWORDS:
11735 case SQL_SPECIAL_CHARACTERS:
11736#ifdef SQL_CATALOG_NAME
11737 case SQL_CATALOG_NAME:
11738#endif
11739#ifdef SQL_COLLATION_SEQ
11740 case SQL_COLLATION_SEQ:
11741#endif
11742 if (val) {
11743 if (len > 0) {
11744 v = uc_from_utf((SQLCHAR *) val, len);
11745 if (v) {
11746 int vmax = valMax / sizeof (SQLWCHAR);
11747
11748 uc_strncpy(val, v, vmax);
11749 if (len < vmax) {
11750 len = min(vmax, uc_strlen(v));
11751 v[len] = 0;
11752 } else {
11753 len = vmax;
11754 }
11755 uc_free(v);
11756 len *= sizeof (SQLWCHAR);
11757 } else {
11758 len = 0;
11759 }
11760 }
11761 if (len <= 0) {
11762 len = 0;
11763 if (valMax >= sizeof (SQLWCHAR)) {
11764 *((SQLWCHAR *)val) = 0;
11765 }
11766 }
11767 } else {
11768 len *= sizeof (SQLWCHAR);
11769 }
11770 break;
11771 }
11772 if (valLen) {
11773 *valLen = len;
11774 }
11775 }
11776 return ret;
11777}
11778#endif
11779
11788SQLRETURN SQL_API
11789SQLGetFunctions(SQLHDBC dbc, SQLUSMALLINT func,
11790 SQLUSMALLINT *flags)
11791{
11792 int i;
11793 SQLUSMALLINT exists[100];
11794
11795 if (dbc == SQL_NULL_HDBC) {
11796 return SQL_INVALID_HANDLE;
11797 }
11798 for (i = 0; i < array_size(exists); i++) {
11799 exists[i] = SQL_FALSE;
11800 }
11801 exists[SQL_API_SQLALLOCCONNECT] = SQL_TRUE;
11802 exists[SQL_API_SQLFETCH] = SQL_TRUE;
11803 exists[SQL_API_SQLALLOCENV] = SQL_TRUE;
11804 exists[SQL_API_SQLFREECONNECT] = SQL_TRUE;
11805 exists[SQL_API_SQLALLOCSTMT] = SQL_TRUE;
11806 exists[SQL_API_SQLFREEENV] = SQL_TRUE;
11807 exists[SQL_API_SQLBINDCOL] = SQL_TRUE;
11808 exists[SQL_API_SQLFREESTMT] = SQL_TRUE;
11809 exists[SQL_API_SQLCANCEL] = SQL_TRUE;
11810 exists[SQL_API_SQLGETCURSORNAME] = SQL_TRUE;
11811 exists[SQL_API_SQLCOLATTRIBUTES] = SQL_TRUE;
11812 exists[SQL_API_SQLNUMRESULTCOLS] = SQL_TRUE;
11813 exists[SQL_API_SQLCONNECT] = SQL_TRUE;
11814 exists[SQL_API_SQLPREPARE] = SQL_TRUE;
11815 exists[SQL_API_SQLDESCRIBECOL] = SQL_TRUE;
11816 exists[SQL_API_SQLROWCOUNT] = SQL_TRUE;
11817 exists[SQL_API_SQLDISCONNECT] = SQL_TRUE;
11818 exists[SQL_API_SQLSETCURSORNAME] = SQL_FALSE;
11819 exists[SQL_API_SQLERROR] = SQL_TRUE;
11820 exists[SQL_API_SQLSETPARAM] = SQL_TRUE;
11821 exists[SQL_API_SQLEXECDIRECT] = SQL_TRUE;
11822 exists[SQL_API_SQLTRANSACT] = SQL_TRUE;
11823 exists[SQL_API_SQLBULKOPERATIONS] = SQL_TRUE;
11824 exists[SQL_API_SQLEXECUTE] = SQL_TRUE;
11825 exists[SQL_API_SQLBINDPARAMETER] = SQL_TRUE;
11826 exists[SQL_API_SQLGETTYPEINFO] = SQL_TRUE;
11827 exists[SQL_API_SQLCOLUMNS] = SQL_TRUE;
11828 exists[SQL_API_SQLPARAMDATA] = SQL_TRUE;
11829 exists[SQL_API_SQLDRIVERCONNECT] = SQL_TRUE;
11830 exists[SQL_API_SQLPUTDATA] = SQL_TRUE;
11831 exists[SQL_API_SQLGETCONNECTOPTION] = SQL_TRUE;
11832 exists[SQL_API_SQLSETCONNECTOPTION] = SQL_TRUE;
11833 exists[SQL_API_SQLGETDATA] = SQL_TRUE;
11834 exists[SQL_API_SQLSETSTMTOPTION] = SQL_TRUE;
11835 exists[SQL_API_SQLGETFUNCTIONS] = SQL_TRUE;
11836 exists[SQL_API_SQLSPECIALCOLUMNS] = SQL_TRUE;
11837 exists[SQL_API_SQLGETINFO] = SQL_TRUE;
11838 exists[SQL_API_SQLSTATISTICS] = SQL_TRUE;
11839 exists[SQL_API_SQLGETSTMTOPTION] = SQL_TRUE;
11840 exists[SQL_API_SQLTABLES] = SQL_TRUE;
11841 exists[SQL_API_SQLBROWSECONNECT] = SQL_FALSE;
11842 exists[SQL_API_SQLNUMPARAMS] = SQL_TRUE;
11843 exists[SQL_API_SQLCOLUMNPRIVILEGES] = SQL_FALSE;
11844 exists[SQL_API_SQLPARAMOPTIONS] = SQL_FALSE;
11845 exists[SQL_API_SQLDATASOURCES] = SQL_TRUE;
11846 exists[SQL_API_SQLPRIMARYKEYS] = SQL_TRUE;
11847 exists[SQL_API_SQLDESCRIBEPARAM] = SQL_TRUE;
11848 exists[SQL_API_SQLPROCEDURECOLUMNS] = SQL_TRUE;
11849 exists[SQL_API_SQLDRIVERS] = SQL_FALSE;
11850 exists[SQL_API_SQLPROCEDURES] = SQL_TRUE;
11851 exists[SQL_API_SQLEXTENDEDFETCH] = SQL_TRUE;
11852 exists[SQL_API_SQLSETPOS] = SQL_TRUE;
11853 exists[SQL_API_SQLFOREIGNKEYS] = SQL_TRUE;
11854 exists[SQL_API_SQLSETSCROLLOPTIONS] = SQL_TRUE;
11855 exists[SQL_API_SQLMORERESULTS] = SQL_TRUE;
11856 exists[SQL_API_SQLTABLEPRIVILEGES] = SQL_TRUE;
11857 exists[SQL_API_SQLNATIVESQL] = SQL_TRUE;
11858 if (func == SQL_API_ALL_FUNCTIONS) {
11859 memcpy(flags, exists, sizeof (exists));
11860 } else if (func == SQL_API_ODBC3_ALL_FUNCTIONS) {
11861 int i;
11862#define SET_EXISTS(x) \
11863 flags[(x) >> 4] |= (1 << ((x) & 0xF))
11864#define CLR_EXISTS(x) \
11865 flags[(x) >> 4] &= ~(1 << ((x) & 0xF))
11866
11867 memset(flags, 0,
11868 sizeof (SQLUSMALLINT) * SQL_API_ODBC3_ALL_FUNCTIONS_SIZE);
11869 for (i = 0; i < array_size(exists); i++) {
11870 if (exists[i]) {
11871 flags[i >> 4] |= (1 << (i & 0xF));
11872 }
11873 }
11874 SET_EXISTS(SQL_API_SQLALLOCHANDLE);
11875 SET_EXISTS(SQL_API_SQLFREEHANDLE);
11876 SET_EXISTS(SQL_API_SQLGETSTMTATTR);
11877 SET_EXISTS(SQL_API_SQLSETSTMTATTR);
11878 SET_EXISTS(SQL_API_SQLGETCONNECTATTR);
11879 SET_EXISTS(SQL_API_SQLSETCONNECTATTR);
11880 SET_EXISTS(SQL_API_SQLGETENVATTR);
11881 SET_EXISTS(SQL_API_SQLSETENVATTR);
11882 SET_EXISTS(SQL_API_SQLCLOSECURSOR);
11883 SET_EXISTS(SQL_API_SQLBINDPARAM);
11884#if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11885 /*
11886 * Some unixODBC versions have problems with
11887 * SQLError() vs. SQLGetDiagRec() with loss
11888 * of error/warning messages.
11889 */
11890 SET_EXISTS(SQL_API_SQLGETDIAGREC);
11891#endif
11892 SET_EXISTS(SQL_API_SQLGETDIAGFIELD);
11893 SET_EXISTS(SQL_API_SQLFETCHSCROLL);
11894 SET_EXISTS(SQL_API_SQLENDTRAN);
11895 } else {
11896 if (func < array_size(exists)) {
11897 *flags = exists[func];
11898 } else {
11899 switch (func) {
11900 case SQL_API_SQLALLOCHANDLE:
11901 case SQL_API_SQLFREEHANDLE:
11902 case SQL_API_SQLGETSTMTATTR:
11903 case SQL_API_SQLSETSTMTATTR:
11904 case SQL_API_SQLGETCONNECTATTR:
11905 case SQL_API_SQLSETCONNECTATTR:
11906 case SQL_API_SQLGETENVATTR:
11907 case SQL_API_SQLSETENVATTR:
11908 case SQL_API_SQLCLOSECURSOR:
11909 case SQL_API_SQLBINDPARAM:
11910#if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11911 /*
11912 * Some unixODBC versions have problems with
11913 * SQLError() vs. SQLGetDiagRec() with loss
11914 * of error/warning messages.
11915 */
11916 case SQL_API_SQLGETDIAGREC:
11917#endif
11918 case SQL_API_SQLGETDIAGFIELD:
11919 case SQL_API_SQLFETCHSCROLL:
11920 case SQL_API_SQLENDTRAN:
11921 *flags = SQL_TRUE;
11922 break;
11923 default:
11924 *flags = SQL_FALSE;
11925 }
11926 }
11927 }
11928 return SQL_SUCCESS;
11929}
11930
11937static SQLRETURN
11938drvallocenv(SQLHENV *env)
11939{
11940 ENV *e;
11941
11942 if (env == NULL) {
11943 return SQL_INVALID_HANDLE;
11944 }
11945 e = (ENV *) xmalloc(sizeof (ENV));
11946 if (e == NULL) {
11947 *env = SQL_NULL_HENV;
11948 return SQL_ERROR;
11949 }
11950 e->magic = ENV_MAGIC;
11951 e->ov3 = 0;
11952 e->pool = 0;
11953#if defined(_WIN32) || defined(_WIN64)
11954 InitializeCriticalSection(&e->cs);
11955#else
11956#if defined(ENABLE_NVFS) && (ENABLE_NVFS)
11957 nvfs_init();
11958#endif
11959#endif
11960 e->dbcs = NULL;
11961 *env = (SQLHENV) e;
11962 return SQL_SUCCESS;
11963}
11964
11971SQLRETURN SQL_API
11972SQLAllocEnv(SQLHENV *env)
11973{
11974 return drvallocenv(env);
11975}
11976
11983static SQLRETURN
11984drvfreeenv(SQLHENV env)
11985{
11986 ENV *e;
11987
11988 if (env == SQL_NULL_HENV) {
11989 return SQL_INVALID_HANDLE;
11990 }
11991 e = (ENV *) env;
11992 if (e->magic != ENV_MAGIC) {
11993 return SQL_SUCCESS;
11994 }
11995#if defined(_WIN32) || defined(_WIN64)
11996 EnterCriticalSection(&e->cs);
11997#endif
11998 if (e->dbcs) {
11999#if defined(_WIN32) || defined(_WIN64)
12000 LeaveCriticalSection(&e->cs);
12001#endif
12002 return SQL_ERROR;
12003 }
12004 e->magic = DEAD_MAGIC;
12005#if defined(_WIN32) || defined(_WIN64)
12006 LeaveCriticalSection(&e->cs);
12007 DeleteCriticalSection(&e->cs);
12008#endif
12009 xfree(e);
12010 return SQL_SUCCESS;
12011}
12012
12019SQLRETURN SQL_API
12020SQLFreeEnv(SQLHENV env)
12021{
12022 return drvfreeenv(env);
12023}
12024
12032static SQLRETURN
12033drvallocconnect(SQLHENV env, SQLHDBC *dbc)
12034{
12035 DBC *d;
12036 ENV *e;
12037 const char *verstr;
12038 int maj = 0, min = 0, lev = 0;
12039
12040 if (dbc == NULL) {
12041 return SQL_ERROR;
12042 }
12043 d = (DBC *) xmalloc(sizeof (DBC));
12044 if (d == NULL) {
12045 *dbc = SQL_NULL_HDBC;
12046 return SQL_ERROR;
12047 }
12048 memset(d, 0, sizeof (DBC));
12049 d->curtype = SQL_CURSOR_STATIC;
12050 d->ov3 = &d->ov3val;
12051 verstr = sqlite3_libversion();
12052 sscanf(verstr, "%d.%d.%d", &maj, &min, &lev);
12053 d->version = verinfo(maj & 0xFF, min & 0xFF, lev & 0xFF);
12054 e = (ENV *) env;
12055#if defined(_WIN32) || defined(_WIN64)
12056 if (e->magic == ENV_MAGIC) {
12057 EnterCriticalSection(&e->cs);
12058 }
12059#endif
12060 if (e->magic == ENV_MAGIC) {
12061 DBC *n, *p;
12062
12063 d->env = e;
12064 d->ov3 = &e->ov3;
12065 p = NULL;
12066 n = e->dbcs;
12067 while (n) {
12068 p = n;
12069 n = n->next;
12070 }
12071 if (p) {
12072 p->next = d;
12073 } else {
12074 e->dbcs = d;
12075 }
12076 }
12077#if defined(_WIN32) || defined(_WIN64)
12078 InitializeCriticalSection(&d->cs);
12079 d->owner = 0;
12080 if (e->magic == ENV_MAGIC) {
12081 LeaveCriticalSection(&e->cs);
12082 }
12083 d->oemcp = 1;
12084#endif
12085 d->autocommit = 1;
12086 d->magic = DBC_MAGIC;
12087 *dbc = (SQLHDBC) d;
12088 drvgetgpps(d);
12089 return SQL_SUCCESS;
12090}
12091
12099SQLRETURN SQL_API
12100SQLAllocConnect(SQLHENV env, SQLHDBC *dbc)
12101{
12102 return drvallocconnect(env, dbc);
12103}
12104
12111static SQLRETURN
12113{
12114 DBC *d;
12115 ENV *e;
12116 SQLRETURN ret = SQL_ERROR;
12117
12118 if (dbc == SQL_NULL_HDBC) {
12119 return SQL_INVALID_HANDLE;
12120 }
12121 d = (DBC *) dbc;
12122 if (d->magic != DBC_MAGIC) {
12123 return SQL_INVALID_HANDLE;
12124 }
12125 e = d->env;
12126 if (e && e->magic == ENV_MAGIC) {
12127#if defined(_WIN32) || defined(_WIN64)
12128 EnterCriticalSection(&e->cs);
12129#endif
12130 } else {
12131 e = NULL;
12132 }
12133 HDBC_LOCK(dbc);
12134 if (d->sqlite) {
12135 setstatd(d, -1, "not disconnected", (*d->ov3) ? "HY000" : "S1000");
12137 goto done;
12138 }
12139 while (d->stmt) {
12140 freestmt((HSTMT) d->stmt);
12141 }
12142 if (e && e->magic == ENV_MAGIC) {
12143 DBC *n, *p;
12144
12145 p = NULL;
12146 n = e->dbcs;
12147 while (n) {
12148 if (n == d) {
12149 break;
12150 }
12151 p = n;
12152 n = n->next;
12153 }
12154 if (n) {
12155 if (p) {
12156 p->next = d->next;
12157 } else {
12158 e->dbcs = d->next;
12159 }
12160 }
12161 }
12162 drvrelgpps(d);
12163 d->magic = DEAD_MAGIC;
12164 if (d->trace) {
12165 fclose(d->trace);
12166 }
12167#if defined(_WIN32) || defined(_WIN64)
12168 d->owner = 0;
12169 LeaveCriticalSection(&d->cs);
12170 DeleteCriticalSection(&d->cs);
12171#endif
12172 xfree(d);
12173 ret = SQL_SUCCESS;
12174done:
12175#if defined(_WIN32) || defined(_WIN64)
12176 if (e) {
12177 LeaveCriticalSection(&e->cs);
12178 }
12179#endif
12180 return ret;
12181}
12182
12189SQLRETURN SQL_API
12191{
12192 return drvfreeconnect(dbc);
12193}
12194
12205static SQLRETURN
12206drvgetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12207 SQLINTEGER bufmax, SQLINTEGER *buflen)
12208{
12209 DBC *d;
12210 SQLINTEGER dummy;
12211
12212 if (dbc == SQL_NULL_HDBC) {
12213 return SQL_INVALID_HANDLE;
12214 }
12215 d = (DBC *) dbc;
12216 if (!val) {
12217 val = (SQLPOINTER) &dummy;
12218 }
12219 if (!buflen) {
12220 buflen = &dummy;
12221 }
12222 switch (attr) {
12223 case SQL_ATTR_CONNECTION_DEAD:
12224 *((SQLINTEGER *) val) = d->sqlite ? SQL_CD_FALSE : SQL_CD_TRUE;
12225 *buflen = sizeof (SQLINTEGER);
12226 break;
12227 case SQL_ATTR_ACCESS_MODE:
12228 *((SQLINTEGER *) val) = SQL_MODE_READ_WRITE;
12229 *buflen = sizeof (SQLINTEGER);
12230 break;
12231 case SQL_ATTR_AUTOCOMMIT:
12232 *((SQLINTEGER *) val) =
12233 d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
12234 *buflen = sizeof (SQLINTEGER);
12235 break;
12236 case SQL_ATTR_LOGIN_TIMEOUT:
12237 *((SQLINTEGER *) val) = 100;
12238 *buflen = sizeof (SQLINTEGER);
12239 break;
12240 case SQL_ATTR_ODBC_CURSORS:
12241 *((SQLINTEGER *) val) = SQL_CUR_USE_DRIVER;
12242 *buflen = sizeof (SQLINTEGER);
12243 break;
12244 case SQL_ATTR_PACKET_SIZE:
12245 *((SQLINTEGER *) val) = 16384;
12246 *buflen = sizeof (SQLINTEGER);
12247 break;
12248 case SQL_ATTR_TXN_ISOLATION:
12249 *((SQLINTEGER *) val) = SQL_TXN_SERIALIZABLE;
12250 *buflen = sizeof (SQLINTEGER);
12251 break;
12252 case SQL_ATTR_TRACEFILE:
12253 case SQL_ATTR_TRANSLATE_LIB:
12254 *((SQLCHAR *) val) = 0;
12255 *buflen = 0;
12256 break;
12257 case SQL_ATTR_CURRENT_CATALOG:
12258#if defined(_WIN32) || defined(_WIN64)
12259 if (d->xcelqrx) {
12260 if ((bufmax > 4) && (val != (SQLPOINTER) &dummy)) {
12261 strcpy((char *) val, "main");
12262 *buflen = 4;
12263 break;
12264 }
12265 }
12266#endif
12267 *((SQLCHAR *) val) = 0;
12268 *buflen = 0;
12269 break;
12270 case SQL_ATTR_TRACE:
12271 case SQL_ATTR_QUIET_MODE:
12272 case SQL_ATTR_TRANSLATE_OPTION:
12273 case SQL_ATTR_KEYSET_SIZE:
12274 case SQL_ATTR_QUERY_TIMEOUT:
12275 *((SQLINTEGER *) val) = 0;
12276 *buflen = sizeof (SQLINTEGER);
12277 break;
12278 case SQL_ATTR_PARAM_BIND_TYPE:
12279 *((SQLULEN *) val) = SQL_PARAM_BIND_BY_COLUMN;
12280 *buflen = sizeof (SQLUINTEGER);
12281 break;
12282 case SQL_ATTR_ROW_BIND_TYPE:
12283 *((SQLULEN *) val) = SQL_BIND_BY_COLUMN;
12284 *buflen = sizeof (SQLULEN);
12285 break;
12286 case SQL_ATTR_USE_BOOKMARKS:
12287 *((SQLINTEGER *) val) = SQL_UB_OFF;
12288 *buflen = sizeof (SQLINTEGER);
12289 break;
12290 case SQL_ATTR_ASYNC_ENABLE:
12291 *((SQLINTEGER *) val) = SQL_ASYNC_ENABLE_OFF;
12292 *buflen = sizeof (SQLINTEGER);
12293 break;
12294 case SQL_ATTR_NOSCAN:
12295 *((SQLINTEGER *) val) = SQL_NOSCAN_ON;
12296 *buflen = sizeof (SQLINTEGER);
12297 break;
12298 case SQL_ATTR_CONCURRENCY:
12299 *((SQLINTEGER *) val) = SQL_CONCUR_LOCK;
12300 *buflen = sizeof (SQLINTEGER);
12301 break;
12302#ifdef SQL_ATTR_CURSOR_SENSITIVITY
12303 case SQL_ATTR_CURSOR_SENSITIVITY:
12304 *((SQLINTEGER *) val) = SQL_UNSPECIFIED;
12305 *buflen = sizeof (SQLINTEGER);
12306 break;
12307#endif
12308 case SQL_ATTR_SIMULATE_CURSOR:
12309 *((SQLINTEGER *) val) = SQL_SC_NON_UNIQUE;
12310 *buflen = sizeof (SQLINTEGER);
12311 break;
12312 case SQL_ATTR_MAX_ROWS:
12313 *((SQLINTEGER *) val) = 0;
12314 *buflen = sizeof (SQLINTEGER);
12315 case SQL_ATTR_MAX_LENGTH:
12316 *((SQLINTEGER *) val) = 1000000000;
12317 *buflen = sizeof (SQLINTEGER);
12318 break;
12319 case SQL_ATTR_CURSOR_TYPE:
12320 *((SQLINTEGER *) val) = d->curtype;
12321 *buflen = sizeof (SQLINTEGER);
12322 break;
12323 case SQL_ATTR_RETRIEVE_DATA:
12324 *((SQLINTEGER *) val) = SQL_RD_ON;
12325 *buflen = sizeof (SQLINTEGER);
12326 break;
12327#ifdef SQL_ATTR_METADATA_ID
12328 case SQL_ATTR_METADATA_ID:
12329 *((SQLULEN *) val) = SQL_FALSE;
12330 return SQL_SUCCESS;
12331#endif
12332 default:
12333 *((SQLINTEGER *) val) = 0;
12334 *buflen = sizeof (SQLINTEGER);
12335 setstatd(d, -1, "unsupported connect attribute %d",
12336 (*d->ov3) ? "HYC00" : "S1C00", (int) attr);
12337 return SQL_ERROR;
12338 }
12339 return SQL_SUCCESS;
12340}
12341
12342#ifndef WINTERFACE
12353SQLRETURN SQL_API
12354SQLGetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12355 SQLINTEGER bufmax, SQLINTEGER *buflen)
12356{
12357 SQLRETURN ret;
12358
12359 HDBC_LOCK(dbc);
12360 ret = drvgetconnectattr(dbc, attr, val, bufmax, buflen);
12362 return ret;
12363}
12364#endif
12365
12366#ifdef WINTERFACE
12377SQLRETURN SQL_API
12378SQLGetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12379 SQLINTEGER bufmax, SQLINTEGER *buflen)
12380{
12381 SQLRETURN ret;
12382 SQLINTEGER len = 0;
12383
12384 HDBC_LOCK(dbc);
12385 ret = drvgetconnectattr(dbc, attr, val, bufmax, &len);
12386 if (ret == SQL_SUCCESS) {
12387 SQLWCHAR *v = NULL;
12388
12389 switch (attr) {
12390 case SQL_ATTR_TRACEFILE:
12391 case SQL_ATTR_CURRENT_CATALOG:
12392 case SQL_ATTR_TRANSLATE_LIB:
12393 if (val) {
12394 if (len > 0) {
12395 v = uc_from_utf((SQLCHAR *) val, len);
12396 if (v) {
12397 int vmax = bufmax / sizeof (SQLWCHAR);
12398
12399 uc_strncpy(val, v, vmax);
12400 if (len < vmax) {
12401 len = min(vmax, uc_strlen(v));
12402 v[len] = 0;
12403 } else {
12404 len = vmax;
12405 }
12406 uc_free(v);
12407 len *= sizeof (SQLWCHAR);
12408 } else {
12409 len = 0;
12410 }
12411 }
12412 if (len <= 0) {
12413 len = 0;
12414 if (bufmax >= sizeof (SQLWCHAR)) {
12415 *((SQLWCHAR *)val) = 0;
12416 }
12417 }
12418 } else {
12419 len *= sizeof (SQLWCHAR);
12420 }
12421 break;
12422 }
12423 if (buflen) {
12424 *buflen = len;
12425 }
12426 }
12428 return ret;
12429}
12430#endif
12431
12441static SQLRETURN
12442drvsetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12443 SQLINTEGER len)
12444{
12445 DBC *d;
12446
12447 if (dbc == SQL_NULL_HDBC) {
12448 return SQL_INVALID_HANDLE;
12449 }
12450 d = (DBC *) dbc;
12451 switch (attr) {
12452 case SQL_AUTOCOMMIT:
12453 d->autocommit = val == (SQLPOINTER) SQL_AUTOCOMMIT_ON;
12454 if (d->autocommit && d->intrans) {
12455 return endtran(d, SQL_COMMIT, 1);
12456 } else if (!d->autocommit) {
12458 }
12459 break;
12460#ifdef SQL_ATTR_METADATA_ID
12461 case SQL_ATTR_METADATA_ID:
12462 if (val == (SQLPOINTER) SQL_FALSE) {
12463 break;
12464 }
12465 /* fall through */
12466#endif
12467 default:
12468 setstatd(d, -1, "option value changed", "01S02");
12469 return SQL_SUCCESS_WITH_INFO;
12470 }
12471 return SQL_SUCCESS;
12472}
12473
12474#ifndef WINTERFACE
12484SQLRETURN SQL_API
12485SQLSetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12486 SQLINTEGER len)
12487{
12488 SQLRETURN ret;
12489
12490 HDBC_LOCK(dbc);
12491 ret = drvsetconnectattr(dbc, attr, val, len);
12493 return ret;
12494}
12495#endif
12496
12497#ifdef WINTERFACE
12507SQLRETURN SQL_API
12508SQLSetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12509 SQLINTEGER len)
12510{
12511 SQLRETURN ret;
12512
12513 HDBC_LOCK(dbc);
12514 ret = drvsetconnectattr(dbc, attr, val, len);
12516 return ret;
12517}
12518#endif
12519
12528static SQLRETURN
12529drvgetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12530{
12531 DBC *d;
12532 SQLINTEGER dummy;
12533
12534 if (dbc == SQL_NULL_HDBC) {
12535 return SQL_INVALID_HANDLE;
12536 }
12537 d = (DBC *) dbc;
12538 if (!param) {
12539 param = (SQLPOINTER) &dummy;
12540 }
12541 switch (opt) {
12542 case SQL_ACCESS_MODE:
12543 *((SQLINTEGER *) param) = SQL_MODE_READ_WRITE;
12544 break;
12545 case SQL_AUTOCOMMIT:
12546 *((SQLINTEGER *) param) =
12547 d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
12548 break;
12549 case SQL_LOGIN_TIMEOUT:
12550 *((SQLINTEGER *) param) = 100;
12551 break;
12552 case SQL_ODBC_CURSORS:
12553 *((SQLINTEGER *) param) = SQL_CUR_USE_DRIVER;
12554 break;
12555 case SQL_PACKET_SIZE:
12556 *((SQLINTEGER *) param) = 16384;
12557 break;
12558 case SQL_TXN_ISOLATION:
12559 *((SQLINTEGER *) param) = SQL_TXN_SERIALIZABLE;
12560 break;
12561 case SQL_OPT_TRACE:
12562 case SQL_OPT_TRACEFILE:
12563 case SQL_QUIET_MODE:
12564 case SQL_TRANSLATE_DLL:
12565 case SQL_TRANSLATE_OPTION:
12566 case SQL_KEYSET_SIZE:
12567 case SQL_QUERY_TIMEOUT:
12568 case SQL_BIND_TYPE:
12569 case SQL_CURRENT_QUALIFIER:
12570 *((SQLINTEGER *) param) = 0;
12571 break;
12572 case SQL_USE_BOOKMARKS:
12573 *((SQLINTEGER *) param) = SQL_UB_OFF;
12574 break;
12575 case SQL_ASYNC_ENABLE:
12576 *((SQLINTEGER *) param) = SQL_ASYNC_ENABLE_OFF;
12577 break;
12578 case SQL_NOSCAN:
12579 *((SQLINTEGER *) param) = SQL_NOSCAN_ON;
12580 break;
12581 case SQL_CONCURRENCY:
12582 *((SQLINTEGER *) param) = SQL_CONCUR_LOCK;
12583 break;
12584 case SQL_SIMULATE_CURSOR:
12585 *((SQLINTEGER *) param) = SQL_SC_NON_UNIQUE;
12586 break;
12587 case SQL_MAX_ROWS:
12588 *((SQLINTEGER *) param) = 0;
12589 break;
12590 case SQL_ROWSET_SIZE:
12591 case SQL_MAX_LENGTH:
12592 *((SQLINTEGER *) param) = 1000000000;
12593 break;
12594 case SQL_CURSOR_TYPE:
12595 *((SQLINTEGER *) param) = d->curtype;
12596 break;
12597 case SQL_RETRIEVE_DATA:
12598 *((SQLINTEGER *) param) = SQL_RD_ON;
12599 break;
12600 default:
12601 *((SQLINTEGER *) param) = 0;
12602 setstatd(d, -1, "unsupported connect option %d",
12603 (*d->ov3) ? "HYC00" : "S1C00", opt);
12604 return SQL_ERROR;
12605 }
12606 return SQL_SUCCESS;
12607}
12608
12609#ifndef WINTERFACE
12618SQLRETURN SQL_API
12619SQLGetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12620{
12621 SQLRETURN ret;
12622
12623 HDBC_LOCK(dbc);
12624 ret = drvgetconnectoption(dbc, opt, param);
12626 return ret;
12627}
12628#endif
12629
12630#ifdef WINTERFACE
12639SQLRETURN SQL_API
12640SQLGetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12641{
12642 SQLRETURN ret;
12643
12644 HDBC_LOCK(dbc);
12645 ret = drvgetconnectoption(dbc, opt, param);
12646 if (SQL_SUCCEEDED(ret)) {
12647 switch (opt) {
12648 case SQL_OPT_TRACEFILE:
12649 case SQL_CURRENT_QUALIFIER:
12650 case SQL_TRANSLATE_DLL:
12651 if (param) {
12652 *(SQLWCHAR *) param = 0;
12653 }
12654 break;
12655 }
12656 }
12658 return ret;
12659}
12660#endif
12661
12670static SQLRETURN
12671drvsetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
12672{
12673 DBC *d;
12674
12675 if (dbc == SQL_NULL_HDBC) {
12676 return SQL_INVALID_HANDLE;
12677 }
12678 d = (DBC *) dbc;
12679 switch (opt) {
12680 case SQL_AUTOCOMMIT:
12681 d->autocommit = param == SQL_AUTOCOMMIT_ON;
12682 if (d->autocommit && d->intrans) {
12683 return endtran(d, SQL_COMMIT, 1);
12684 } else if (!d->autocommit) {
12686 }
12687 break;
12688 default:
12689 setstatd(d, -1, "option value changed", "01S02");
12690 return SQL_SUCCESS_WITH_INFO;
12691 }
12692 return SQL_SUCCESS;
12693}
12694
12695#ifndef WINTERFACE
12704SQLRETURN SQL_API
12705SQLSetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12706{
12707 SQLRETURN ret;
12708
12709 HDBC_LOCK(dbc);
12710 ret = drvsetconnectoption(dbc, opt, param);
12712 return ret;
12713}
12714#endif
12715
12716#ifdef WINTERFACE
12725SQLRETURN SQL_API
12726SQLSetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12727{
12728 SQLRETURN ret;
12729
12730 HDBC_LOCK(dbc);
12731 ret = drvsetconnectoption(dbc, opt, param);
12733 return ret;
12734}
12735#endif
12736
12737#if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
12738
12749static int
12750getdsnattr(char *dsn, char *attr, char *out, int outLen)
12751{
12752 char *str = dsn, *start;
12753 int len = strlen(attr);
12754
12755 while (*str) {
12756 while (*str && *str == ';') {
12757 ++str;
12758 }
12759 start = str;
12760 if ((str = strchr(str, '=')) == NULL) {
12761 return 0;
12762 }
12763 if (str - start == len && strncasecmp(start, attr, len) == 0) {
12764 start = ++str;
12765 while (*str && *str != ';') {
12766 ++str;
12767 }
12768 len = min(outLen - 1, str - start);
12769 strncpy(out, start, len);
12770 out[len] = '\0';
12771 return 1;
12772 }
12773 while (*str && *str != ';') {
12774 ++str;
12775 }
12776 }
12777 return 0;
12778}
12779#endif
12780
12792static SQLRETURN
12793drvconnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen, char *pwd,
12794 int pwdLen, int isu)
12795{
12796 DBC *d;
12797 int len;
12798 SQLRETURN ret;
12799 char buf[SQL_MAX_MESSAGE_LENGTH * 6], dbname[SQL_MAX_MESSAGE_LENGTH];
12800 char busy[SQL_MAX_MESSAGE_LENGTH / 4], tracef[SQL_MAX_MESSAGE_LENGTH];
12801 char loadext[SQL_MAX_MESSAGE_LENGTH], attas[SQL_MAX_MESSAGE_LENGTH];
12802 char sflag[32], spflag[32], ntflag[32], nwflag[32], biflag[32];
12803 char snflag[32], lnflag[32], ncflag[32], fkflag[32], jmode[32];
12804 char jdflag[32], ilflag[32];
12805#if defined(_WIN32) || defined(_WIN64)
12806 char oemcp[32];
12807#endif
12808
12809 if (dbc == SQL_NULL_HDBC) {
12810 return SQL_INVALID_HANDLE;
12811 }
12812 d = (DBC *) dbc;
12813 if (d->magic != DBC_MAGIC) {
12814 return SQL_INVALID_HANDLE;
12815 }
12816 if (d->sqlite != NULL) {
12817 setstatd(d, -1, "connection already established", "08002");
12818 return SQL_ERROR;
12819 }
12820 buf[0] = '\0';
12821 if (dsnLen == SQL_NTS) {
12822 len = sizeof (buf) - 1;
12823 } else {
12824 len = min(sizeof (buf) - 1, dsnLen);
12825 }
12826 if (dsn != NULL) {
12827 strncpy(buf, (char *) dsn, len);
12828 }
12829 buf[len] = '\0';
12830 if (buf[0] == '\0') {
12831 setstatd(d, -1, "invalid DSN", (*d->ov3) ? "HY090" : "S1090");
12832 return SQL_ERROR;
12833 }
12834#if defined(_WIN32) || defined(_WIN64)
12835 /*
12836 * When DSN is in UTF it must be converted to ANSI
12837 * here for ANSI SQLGetPrivateProfileString()
12838 */
12839 if (isu) {
12840 char *cdsn = utf_to_wmb(buf, len);
12841
12842 if (!cdsn) {
12843 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12844 return SQL_ERROR;
12845 }
12846 strcpy(buf, cdsn);
12847 uc_free(cdsn);
12848 }
12849#endif
12850 busy[0] = '\0';
12851 dbname[0] = '\0';
12852#ifdef WITHOUT_DRIVERMGR
12853 getdsnattr(buf, "database", dbname, sizeof (dbname));
12854 if (dbname[0] == '\0') {
12855 strncpy(dbname, buf, sizeof (dbname));
12856 dbname[sizeof (dbname) - 1] = '\0';
12857 }
12858 getdsnattr(buf, "timeout", busy, sizeof (busy));
12859 sflag[0] = '\0';
12860 getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
12861 spflag[0] = '\0';
12862 getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
12863 ntflag[0] = '\0';
12864 getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
12865 nwflag[0] = '\0';
12866 getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
12867 snflag[0] = '\0';
12868 getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
12869 lnflag[0] = '\0';
12870 getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
12871 ncflag[0] = '\0';
12872 getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
12873 fkflag[0] = '\0';
12874 getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
12875 loadext[0] = '\0';
12876 getdsnattr(buf, "loadext", loadext, sizeof (loadext));
12877 jmode[0] = '\0';
12878 getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
12879 jdflag[0] = '\0';
12880 getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
12881#if defined(_WIN32) || defined(_WIN64)
12882 oemcp[0] = '\0';
12883 getdsnattr(buf, "oemcp", oemcp, sizeof (oemcp));
12884#endif
12885 biflag[0] = '\0';
12886 getdsnattr(buf, "bigint", biflag, sizeof (biflag));
12887 attas[0] = '\0';
12888 getdsnattr(buf, "attachas", attas, sizeof (attas));
12889 ilflag[0] = '\0';
12890 getdsnattr(buf, "ilike", ilflag, sizeof (ilflag));
12891#else
12892 SQLGetPrivateProfileString(buf, "timeout", "100000",
12893 busy, sizeof (busy), ODBC_INI);
12894 SQLGetPrivateProfileString(buf, "database", "",
12895 dbname, sizeof (dbname), ODBC_INI);
12896#if defined(_WIN32) || defined(_WIN64)
12897 /* database name read from registry is not UTF8 !!! */
12898 isu = 0;
12899#endif
12900 SQLGetPrivateProfileString(buf, "stepapi", "",
12901 sflag, sizeof (sflag), ODBC_INI);
12902 SQLGetPrivateProfileString(buf, "syncpragma", "NORMAL",
12903 spflag, sizeof (spflag), ODBC_INI);
12904 SQLGetPrivateProfileString(buf, "notxn", "",
12905 ntflag, sizeof (ntflag), ODBC_INI);
12906 SQLGetPrivateProfileString(buf, "nowchar", "",
12907 nwflag, sizeof (nwflag), ODBC_INI);
12908 SQLGetPrivateProfileString(buf, "shortnames", "",
12909 snflag, sizeof (snflag), ODBC_INI);
12910 SQLGetPrivateProfileString(buf, "longnames", "",
12911 lnflag, sizeof (lnflag), ODBC_INI);
12912 SQLGetPrivateProfileString(buf, "nocreat", "",
12913 ncflag, sizeof (ncflag), ODBC_INI);
12914 SQLGetPrivateProfileString(buf, "fksupport", "",
12915 fkflag, sizeof (fkflag), ODBC_INI);
12916 SQLGetPrivateProfileString(buf, "loadext", "",
12917 loadext, sizeof (loadext), ODBC_INI);
12918 SQLGetPrivateProfileString(buf, "journalmode", "",
12919 jmode, sizeof (jmode), ODBC_INI);
12920 SQLGetPrivateProfileString(buf, "jdconv", "",
12921 jdflag, sizeof (jdflag), ODBC_INI);
12922#if defined(_WIN32) || defined(_WIN64)
12923 SQLGetPrivateProfileString(buf, "oemcp", "1",
12924 oemcp, sizeof (oemcp), ODBC_INI);
12925#endif
12926 SQLGetPrivateProfileString(buf, "bigint", "",
12927 biflag, sizeof (biflag), ODBC_INI);
12928 SQLGetPrivateProfileString(buf, "attachas", "",
12929 attas, sizeof (attas), ODBC_INI);
12930 SQLGetPrivateProfileString(buf, "ilike", "",
12931 ilflag, sizeof (ilflag), ODBC_INI);
12932#endif
12933 tracef[0] = '\0';
12934#ifdef WITHOUT_DRIVERMGR
12935 getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
12936#else
12937 SQLGetPrivateProfileString(buf, "tracefile", "",
12938 tracef, sizeof (tracef), ODBC_INI);
12939#endif
12940 if (tracef[0] != '\0') {
12941 d->trace = fopen(tracef, "a");
12942 }
12943 d->nowchar = getbool(nwflag);
12944 d->shortnames = getbool(snflag);
12945 d->longnames = getbool(lnflag);
12946 d->nocreat = getbool(ncflag);
12947 d->fksupport = getbool(fkflag);
12948 d->jdconv = getbool(jdflag);
12949 d->ilike = getbool(ilflag);
12950#if defined(_WIN32) || defined(_WIN64)
12951 d->oemcp = getbool(oemcp);
12952#else
12953 d->oemcp = 0;
12954#endif
12955 d->dobigint = getbool(biflag);
12956 d->pwd = pwd;
12957 d->pwdLen = 0;
12958 if (d->pwd) {
12959 d->pwdLen = (pwdLen == SQL_NTS) ? strlen(d->pwd) : pwdLen;
12960 }
12961 ret = dbopen(d, dbname, isu, (char *) dsn, sflag, spflag, ntflag,
12962 jmode, busy);
12963 if (ret == SQL_SUCCESS) {
12964 dbloadext(d, loadext);
12965 dbattas(d, attas);
12966 }
12967 return ret;
12968}
12969
12970#ifndef WINTERFACE
12983SQLRETURN SQL_API
12984SQLConnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen,
12985 SQLCHAR *uid, SQLSMALLINT uidLen,
12986 SQLCHAR *pwd, SQLSMALLINT pwdLen)
12987{
12988 SQLRETURN ret;
12989
12990 HDBC_LOCK(dbc);
12991 ret = drvconnect(dbc, dsn, dsnLen, (char *) pwd, pwdLen, 0);
12993 return ret;
12994}
12995#endif
12996
12997#ifdef WINTERFACE
13010SQLRETURN SQL_API
13011SQLConnectW(SQLHDBC dbc, SQLWCHAR *dsn, SQLSMALLINT dsnLen,
13012 SQLWCHAR *uid, SQLSMALLINT uidLen,
13013 SQLWCHAR *pwd, SQLSMALLINT pwdLen)
13014{
13015 char *dsna = NULL;
13016 char *pwda = NULL;
13017 SQLRETURN ret;
13018
13019 HDBC_LOCK(dbc);
13020 if (dsn) {
13021 dsna = uc_to_utf_c(dsn, dsnLen);
13022 if (!dsna) {
13023 DBC *d = (DBC *) dbc;
13024
13025 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
13026 ret = SQL_ERROR;
13027 goto done;
13028 }
13029 }
13030 if (pwd) {
13031 pwda = uc_to_utf_c(pwd, pwdLen);
13032 if (!pwda) {
13033 DBC *d = (DBC *) dbc;
13034
13035 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
13036 ret = SQL_ERROR;
13037 goto done;
13038 }
13039 }
13040 ret = drvconnect(dbc, (SQLCHAR *) dsna, SQL_NTS, pwda, SQL_NTS, 1);
13041done:
13043 uc_free(dsna);
13044 uc_free(pwda);
13045 return ret;
13046}
13047#endif
13048
13055static SQLRETURN
13057{
13058 DBC *d;
13059 int rc;
13060
13061 if (dbc == SQL_NULL_HDBC) {
13062 return SQL_INVALID_HANDLE;
13063 }
13064 d = (DBC *) dbc;
13065 if (d->magic != DBC_MAGIC) {
13066 return SQL_INVALID_HANDLE;
13067 }
13068 if (d->intrans) {
13069 setstatd(d, -1, "incomplete transaction", "25000");
13070 return SQL_ERROR;
13071 }
13072 if (d->cur_s3stmt) {
13074 }
13075 if (d->sqlite) {
13076 if (d->trace) {
13077 fprintf(d->trace, "-- sqlite3_close: '%s'\n",
13078 d->dbname);
13079 fflush(d->trace);
13080 }
13081 rc = sqlite3_close(d->sqlite);
13082 if (rc == SQLITE_BUSY) {
13083 setstatd(d, -1, "unfinished statements", "25000");
13084 return SQL_ERROR;
13085 }
13086 d->sqlite = NULL;
13087 }
13088 freep(&d->dbname);
13089 freep(&d->dsn);
13090 return SQL_SUCCESS;
13091}
13092
13099SQLRETURN SQL_API
13101{
13102 SQLRETURN ret;
13103
13104 HDBC_LOCK(dbc);
13105 ret = drvdisconnect(dbc);
13107 return ret;
13108}
13109
13110#if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
13111
13125static SQLRETURN
13126drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
13127 SQLCHAR *connIn, SQLSMALLINT connInLen,
13128 SQLCHAR *connOut, SQLSMALLINT connOutMax,
13129 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
13130{
13131 DBC *d;
13132 int len;
13133 SQLRETURN ret;
13134 char buf[SQL_MAX_MESSAGE_LENGTH * 8], dbname[SQL_MAX_MESSAGE_LENGTH];
13135 char dsn[SQL_MAX_MESSAGE_LENGTH], busy[SQL_MAX_MESSAGE_LENGTH / 4];
13136 char tracef[SQL_MAX_MESSAGE_LENGTH], loadext[SQL_MAX_MESSAGE_LENGTH];
13137 char pwd[SQL_MAX_MESSAGE_LENGTH], attas[SQL_MAX_MESSAGE_LENGTH];
13138 char sflag[32], spflag[32], ntflag[32], snflag[32], lnflag[32];
13139 char ncflag[32], nwflag[32], fkflag[32], jmode[32], biflag[32];
13140 char jdflag[32], ilflag[32];
13141
13142 if (dbc == SQL_NULL_HDBC) {
13143 return SQL_INVALID_HANDLE;
13144 }
13145 if (drvcompl != SQL_DRIVER_COMPLETE &&
13146 drvcompl != SQL_DRIVER_COMPLETE_REQUIRED &&
13147 drvcompl != SQL_DRIVER_PROMPT &&
13148 drvcompl != SQL_DRIVER_NOPROMPT) {
13149 return SQL_NO_DATA;
13150 }
13151 d = (DBC *) dbc;
13152 if (d->sqlite) {
13153 setstatd(d, -1, "connection already established", "08002");
13154 return SQL_ERROR;
13155 }
13156 buf[0] = '\0';
13157 if (connInLen == SQL_NTS) {
13158 len = sizeof (buf) - 1;
13159 } else {
13160 len = min(connInLen, sizeof (buf) - 1);
13161 }
13162 if (connIn != NULL) {
13163 strncpy(buf, (char *) connIn, len);
13164 }
13165 buf[len] = '\0';
13166 if (!buf[0]) {
13167 setstatd(d, -1, "invalid connect attributes",
13168 (*d->ov3) ? "HY090" : "S1090");
13169 return SQL_ERROR;
13170 }
13171 dsn[0] = '\0';
13172 getdsnattr(buf, "DSN", dsn, sizeof (dsn));
13173
13174 /* special case: connIn is sole DSN value without keywords */
13175 if (!dsn[0] && !strchr(buf, ';') && !strchr(buf, '=')) {
13176 strncpy(dsn, buf, sizeof (dsn) - 1);
13177 dsn[sizeof (dsn) - 1] = '\0';
13178 }
13179
13180 busy[0] = '\0';
13181 getdsnattr(buf, "timeout", busy, sizeof (busy));
13182#ifndef WITHOUT_DRIVERMGR
13183 if (dsn[0] && !busy[0]) {
13184 SQLGetPrivateProfileString(dsn, "timeout", "100000",
13185 busy, sizeof (busy), ODBC_INI);
13186 }
13187#endif
13188 dbname[0] = '\0';
13189 getdsnattr(buf, "database", dbname, sizeof (dbname));
13190#ifndef WITHOUT_DRIVERMGR
13191 if (dsn[0] && !dbname[0]) {
13192 SQLGetPrivateProfileString(dsn, "database", "",
13193 dbname, sizeof (dbname), ODBC_INI);
13194 }
13195#endif
13196 sflag[0] = '\0';
13197 getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
13198#ifndef WITHOUT_DRIVERMGR
13199 if (dsn[0] && !sflag[0]) {
13200 SQLGetPrivateProfileString(dsn, "stepapi", "",
13201 sflag, sizeof (sflag), ODBC_INI);
13202 }
13203#endif
13204 spflag[0] = '\0';
13205 getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
13206#ifndef WITHOUT_DRIVERMGR
13207 if (dsn[0] && !spflag[0]) {
13208 SQLGetPrivateProfileString(dsn, "syncpragma", "NORMAL",
13209 spflag, sizeof (spflag), ODBC_INI);
13210 }
13211#endif
13212 ntflag[0] = '\0';
13213 getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
13214#ifndef WITHOUT_DRIVERMGR
13215 if (dsn[0] && !ntflag[0]) {
13216 SQLGetPrivateProfileString(dsn, "notxn", "",
13217 ntflag, sizeof (ntflag), ODBC_INI);
13218 }
13219#endif
13220 snflag[0] = '\0';
13221 getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
13222#ifndef WITHOUT_DRIVERMGR
13223 if (dsn[0] && !snflag[0]) {
13224 SQLGetPrivateProfileString(dsn, "shortnames", "",
13225 snflag, sizeof (snflag), ODBC_INI);
13226 }
13227#endif
13228 lnflag[0] = '\0';
13229 getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
13230#ifndef WITHOUT_DRIVERMGR
13231 if (dsn[0] && !lnflag[0]) {
13232 SQLGetPrivateProfileString(dsn, "longnames", "",
13233 lnflag, sizeof (lnflag), ODBC_INI);
13234 }
13235#endif
13236 ncflag[0] = '\0';
13237 getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
13238#ifndef WITHOUT_DRIVERMGR
13239 if (dsn[0] && !ncflag[0]) {
13240 SQLGetPrivateProfileString(dsn, "nocreat", "",
13241 ncflag, sizeof (ncflag), ODBC_INI);
13242 }
13243#endif
13244 nwflag[0] = '\0';
13245 getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
13246#ifndef WITHOUT_DRIVERMGR
13247 if (dsn[0] && !nwflag[0]) {
13248 SQLGetPrivateProfileString(dsn, "nowchar", "",
13249 nwflag, sizeof (nwflag), ODBC_INI);
13250 }
13251#endif
13252 fkflag[0] = '\0';
13253 getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
13254#ifndef WITHOUT_DRIVERMGR
13255 if (dsn[0] && !fkflag[0]) {
13256 SQLGetPrivateProfileString(dsn, "fksupport", "",
13257 fkflag, sizeof (fkflag), ODBC_INI);
13258 }
13259#endif
13260 loadext[0] = '\0';
13261 getdsnattr(buf, "loadext", loadext, sizeof (loadext));
13262#ifndef WITHOUT_DRIVERMGR
13263 if (dsn[0] && !loadext[0]) {
13264 SQLGetPrivateProfileString(dsn, "loadext", "",
13265 loadext, sizeof (loadext), ODBC_INI);
13266 }
13267#endif
13268 jmode[0] = '\0';
13269 getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
13270#ifndef WITHOUT_DRIVERMGR
13271 if (dsn[0] && !jmode[0]) {
13272 SQLGetPrivateProfileString(dsn, "journalmode", "",
13273 jmode, sizeof (jmode), ODBC_INI);
13274 }
13275#endif
13276 biflag[0] = '\0';
13277 getdsnattr(buf, "bigint", biflag, sizeof (biflag));
13278#ifndef WITHOUT_DRIVERMGR
13279 if (dsn[0] && !biflag[0]) {
13280 SQLGetPrivateProfileString(dsn, "bigint", "",
13281 biflag, sizeof (biflag), ODBC_INI);
13282 }
13283#endif
13284 jdflag[0] = '\0';
13285 getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
13286#ifndef WITHOUT_DRIVERMGR
13287 if (dsn[0] && !jdflag[0]) {
13288 SQLGetPrivateProfileString(dsn, "jdconv", "",
13289 jdflag, sizeof (jdflag), ODBC_INI);
13290 }
13291#endif
13292 pwd[0] = '\0';
13293 getdsnattr(buf, "pwd", pwd, sizeof (pwd));
13294#ifndef WITHOUT_DRIVERMGR
13295 if (dsn[0] && !pwd[0]) {
13296 SQLGetPrivateProfileString(dsn, "pwd", "",
13297 pwd, sizeof (pwd), ODBC_INI);
13298 }
13299#endif
13300 attas[0] = '\0';
13301 getdsnattr(buf, "attachas", attas, sizeof (attas));
13302#ifndef WITHOUT_DRIVERMGR
13303 if (dsn[0] && !attas[0]) {
13304 SQLGetPrivateProfileString(dsn, "attachas", "",
13305 attas, sizeof (attas), ODBC_INI);
13306 }
13307#endif
13308 ilflag[0] = '\0';
13309 getdsnattr(buf, "ilike", ilflag, sizeof (ilflag));
13310#ifndef WITHOUT_DRIVERMGR
13311 if (dsn[0] && !ilflag[0]) {
13312 SQLGetPrivateProfileString(dsn, "ilike", "",
13313 ilflag, sizeof (ilflag), ODBC_INI);
13314 }
13315#endif
13316
13317 if (!dbname[0] && !dsn[0]) {
13318 strcpy(dsn, "SQLite");
13319 strncpy(dbname, buf, sizeof (dbname));
13320 dbname[sizeof (dbname) - 1] = '\0';
13321 }
13322 tracef[0] = '\0';
13323 getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
13324#ifndef WITHOUT_DRIVERMGR
13325 if (dsn[0] && !tracef[0]) {
13326 SQLGetPrivateProfileString(dsn, "tracefile", "",
13327 tracef, sizeof (tracef), ODBC_INI);
13328 }
13329#endif
13330 if (connOut || connOutLen) {
13331 int count;
13332
13333 buf[0] = '\0';
13334 count = snprintf(buf, sizeof (buf),
13335 "DSN=%s;Database=%s;StepAPI=%s;Timeout=%s;"
13336 "SyncPragma=%s;NoTXN=%s;ShortNames=%s;LongNames=%s;"
13337 "NoCreat=%s;NoWCHAR=%s;FKSupport=%s;Tracefile=%s;"
13338 "JournalMode=%s;LoadExt=%s;BigInt=%s;JDConv=%s;"
13339 "PWD=%s;AttachAs=%s;ILike=%s",
13340 dsn, dbname, sflag, busy, spflag, ntflag,
13341 snflag, lnflag, ncflag, nwflag, fkflag, tracef,
13342 jmode, loadext, biflag, jdflag, pwd, attas, ilflag);
13343 if (count < 0) {
13344 buf[sizeof (buf) - 1] = '\0';
13345 }
13346 len = min(connOutMax - 1, strlen(buf));
13347 if (connOut) {
13348 strncpy((char *) connOut, buf, len);
13349 connOut[len] = '\0';
13350 }
13351 if (connOutLen) {
13352 *connOutLen = len;
13353 }
13354 }
13355 if (tracef[0] != '\0') {
13356 d->trace = fopen(tracef, "a");
13357 }
13358 d->shortnames = getbool(snflag);
13359 d->longnames = getbool(lnflag);
13360 d->nocreat = getbool(ncflag);
13361 d->nowchar = getbool(nwflag);
13362 d->fksupport = getbool(fkflag);
13363 d->dobigint = getbool(biflag);
13364 d->jdconv = getbool(jdflag);
13365 d->ilike = getbool(ilflag);
13366 d->oemcp = 0;
13367 d->pwdLen = strlen(pwd);
13368 d->pwd = (d->pwdLen > 0) ? pwd : NULL;
13369 ret = dbopen(d, dbname, 0, dsn, sflag, spflag, ntflag, jmode, busy);
13370 memset(pwd, 0, sizeof (pwd));
13371 if (ret == SQL_SUCCESS) {
13372 dbloadext(d, loadext);
13373 dbattas(d, attas);
13374 }
13375 return ret;
13376}
13377#endif
13378
13385static SQLRETURN
13387{
13388 STMT *s;
13389 DBC *d;
13390
13391 if (stmt == SQL_NULL_HSTMT) {
13392 return SQL_INVALID_HANDLE;
13393 }
13394 s = (STMT *) stmt;
13395 s3stmt_drop(s);
13396 freeresult(s, 1);
13397 freep(&s->query);
13398 d = (DBC *) s->dbc;
13399 if (d && d->magic == DBC_MAGIC) {
13400 STMT *p, *n;
13401
13402 p = NULL;
13403 n = d->stmt;
13404 while (n) {
13405 if (n == s) {
13406 break;
13407 }
13408 p = n;
13409 n = n->next;
13410 }
13411 if (n) {
13412 if (p) {
13413 p->next = s->next;
13414 } else {
13415 d->stmt = s->next;
13416 }
13417 }
13418 }
13419 freeparams(s);
13420 freep(&s->bindparms);
13421 if (s->row_status0 != &s->row_status1) {
13422 freep(&s->row_status0);
13423 s->rowset_size = 1;
13424 s->row_status0 = &s->row_status1;
13425 }
13426 xfree(s);
13427 return SQL_SUCCESS;
13428}
13429
13437static SQLRETURN
13438drvallocstmt(SQLHDBC dbc, SQLHSTMT *stmt)
13439{
13440 DBC *d;
13441 STMT *s, *sl, *pl;
13442
13443 if (dbc == SQL_NULL_HDBC) {
13444 return SQL_INVALID_HANDLE;
13445 }
13446 d = (DBC *) dbc;
13447 if (d->magic != DBC_MAGIC || stmt == NULL) {
13448 return SQL_INVALID_HANDLE;
13449 }
13450 s = (STMT *) xmalloc(sizeof (STMT));
13451 if (s == NULL) {
13452 *stmt = SQL_NULL_HSTMT;
13453 return SQL_ERROR;
13454 }
13455 *stmt = (SQLHSTMT) s;
13456 memset(s, 0, sizeof (STMT));
13457 s->dbc = dbc;
13458 s->ov3 = d->ov3;
13459 s->bkmrk = SQL_UB_OFF;
13460 s->bkmrkptr = 0;
13461 s->oemcp = &d->oemcp;
13462 s->jdconv = &d->jdconv;
13463 s->ilike = &d->ilike;
13464 s->nowchar[0] = d->nowchar;
13465 s->nowchar[1] = 0;
13466 s->dobigint = d->dobigint;
13467 s->curtype = d->curtype;
13468 s->row_status0 = &s->row_status1;
13469 s->rowset_size = 1;
13470 s->longnames = d->longnames;
13471 s->retr_data = SQL_RD_ON;
13472 s->max_rows = 0;
13473 s->bind_type = SQL_BIND_BY_COLUMN;
13474 s->bind_offs = NULL;
13475 s->paramset_size = 1;
13476 s->parm_bind_type = SQL_PARAM_BIND_BY_COLUMN;
13477 s->one_tbl = -1;
13478 s->has_pk = -1;
13479 s->has_rowid = -1;
13480#ifdef _WIN64
13481 sprintf((char *) s->cursorname, "CUR_%I64X", (SQLUBIGINT) *stmt);
13482#else
13483 sprintf((char *) s->cursorname, "CUR_%016lX", (long) *stmt);
13484#endif
13485 sl = d->stmt;
13486 pl = NULL;
13487 while (sl) {
13488 pl = sl;
13489 sl = sl->next;
13490 }
13491 if (pl) {
13492 pl->next = s;
13493 } else {
13494 d->stmt = s;
13495 }
13496 return SQL_SUCCESS;
13497}
13498
13506SQLRETURN SQL_API
13507SQLAllocStmt(SQLHDBC dbc, SQLHSTMT *stmt)
13508{
13509 SQLRETURN ret;
13510
13511 HDBC_LOCK(dbc);
13512 ret = drvallocstmt(dbc, stmt);
13514 return ret;
13515}
13516
13524static SQLRETURN
13525drvfreestmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13526{
13527 STMT *s;
13528 SQLRETURN ret = SQL_SUCCESS;
13529 SQLHDBC dbc;
13530
13531 if (stmt == SQL_NULL_HSTMT) {
13532 return SQL_INVALID_HANDLE;
13533 }
13535 s = (STMT *) stmt;
13536 dbc = s->dbc;
13537 switch (opt) {
13538 case SQL_RESET_PARAMS:
13539 freeparams(s);
13540 break;
13541 case SQL_UNBIND:
13542 unbindcols(s);
13543 break;
13544 case SQL_CLOSE:
13545 s3stmt_end_if(s);
13546 freeresult(s, 0);
13547 break;
13548 case SQL_DROP:
13549 s3stmt_end_if(s);
13550 ret = freestmt(stmt);
13551 break;
13552 default:
13553 setstat(s, -1, "unsupported option", (*s->ov3) ? "HYC00" : "S1C00");
13554 ret = SQL_ERROR;
13555 break;
13556 }
13558 return ret;
13559}
13560
13568SQLRETURN SQL_API
13569SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13570{
13571 return drvfreestmt(stmt, opt);
13572}
13573
13580SQLRETURN SQL_API
13582{
13583 if (stmt != SQL_NULL_HSTMT) {
13584 DBC *d = (DBC *) ((STMT *) stmt)->dbc;
13585#if defined(_WIN32) || defined(_WIN64)
13586 /* interrupt when other thread owns critical section */
13587 if (d->magic == DBC_MAGIC && d->owner != GetCurrentThreadId() &&
13588 d->owner != 0) {
13589 d->busyint = 1;
13590 sqlite3_interrupt(d->sqlite);
13591 return SQL_SUCCESS;
13592 }
13593#else
13594 if (d->magic == DBC_MAGIC) {
13595 d->busyint = 1;
13596 sqlite3_interrupt(d->sqlite);
13597 }
13598#endif
13599 }
13600 return drvfreestmt(stmt, SQL_CLOSE);
13601}
13602
13612static SQLRETURN
13613drvgetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13614 SQLSMALLINT *lenp)
13615{
13616 STMT *s;
13617
13618 if (stmt == SQL_NULL_HSTMT) {
13619 return SQL_INVALID_HANDLE;
13620 }
13621 s = (STMT *) stmt;
13622 if (lenp && !cursor) {
13623 *lenp = strlen((char *) s->cursorname);
13624 return SQL_SUCCESS;
13625 }
13626 if (cursor) {
13627 if (buflen > 0) {
13628 strncpy((char *) cursor, (char *) s->cursorname, buflen - 1);
13629 cursor[buflen - 1] = '\0';
13630 }
13631 if (lenp) {
13632 *lenp = min(strlen((char *) s->cursorname), buflen - 1);
13633 }
13634 }
13635 return SQL_SUCCESS;
13636}
13637
13638#ifndef WINTERFACE
13648SQLRETURN SQL_API
13649SQLGetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13650 SQLSMALLINT *lenp)
13651{
13652 SQLRETURN ret;
13653#if defined(_WIN32) || defined(_WIN64)
13654 SQLSMALLINT len = 0;
13655#endif
13656
13658#if defined(_WIN32) || defined(_WIN64)
13659 if (!((STMT *) stmt)->oemcp[0]) {
13660 ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13661 goto done;
13662 }
13663 ret = drvgetcursorname(stmt, cursor, buflen, &len);
13664 if (ret == SQL_SUCCESS) {
13665 char *c = NULL;
13666
13667 if (cursor) {
13668 c = utf_to_wmb((char *) cursor, len);
13669 if (!c) {
13670 ret = nomem((STMT *) stmt);
13671 goto done;
13672 }
13673 c[len] = 0;
13674 len = strlen(c);
13675 if (buflen > 0) {
13676 strncpy((char *) cursor, c, buflen - 1);
13677 cursor[buflen - 1] = 0;
13678 }
13679 uc_free(c);
13680 }
13681 if (lenp) {
13682 *lenp = min(len, buflen - 1);
13683 }
13684 }
13685done:
13686 ;
13687#else
13688 ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13689#endif
13691 return ret;
13692}
13693#endif
13694
13695#ifdef WINTERFACE
13705SQLRETURN SQL_API
13706SQLGetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT buflen,
13707 SQLSMALLINT *lenp)
13708{
13709 SQLRETURN ret;
13710 SQLSMALLINT len = 0;
13711
13713 ret = drvgetcursorname(stmt, (SQLCHAR *) cursor, buflen, &len);
13714 if (ret == SQL_SUCCESS) {
13715 SQLWCHAR *c = NULL;
13716
13717 if (cursor) {
13718 c = uc_from_utf((SQLCHAR *) cursor, len);
13719 if (!c) {
13720 ret = nomem((STMT *) stmt);
13721 goto done;
13722 }
13723 c[len] = 0;
13724 len = uc_strlen(c);
13725 if (buflen > 0) {
13726 uc_strncpy(cursor, c, buflen - 1);
13727 cursor[buflen - 1] = 0;
13728 }
13729 uc_free(c);
13730 }
13731 if (lenp) {
13732 *lenp = min(len, buflen - 1);
13733 }
13734 }
13735done:
13737 return ret;
13738}
13739#endif
13740
13749static SQLRETURN
13750drvsetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13751{
13752 STMT *s;
13753
13754 if (stmt == SQL_NULL_HSTMT) {
13755 return SQL_INVALID_HANDLE;
13756 }
13757 s = (STMT *) stmt;
13758 if (!cursor ||
13759 !((cursor[0] >= 'A' && cursor[0] <= 'Z') ||
13760 (cursor[0] >= 'a' && cursor[0] <= 'z'))) {
13761 setstat(s, -1, "invalid cursor name", (*s->ov3) ? "HYC00" : "S1C00");
13762 return SQL_ERROR;
13763 }
13764 if (len == SQL_NTS) {
13765 len = sizeof (s->cursorname) - 1;
13766 } else {
13767 len = min(sizeof (s->cursorname) - 1, len);
13768 }
13769 strncpy((char *) s->cursorname, (char *) cursor, len);
13770 s->cursorname[len] = '\0';
13771 return SQL_SUCCESS;
13772}
13773
13774#ifndef WINTERFACE
13783SQLRETURN SQL_API
13784SQLSetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13785{
13786#if defined(_WIN32) || defined(_WIN64)
13787 char *c = NULL;
13788#endif
13789 SQLRETURN ret;
13790
13792#if defined(_WIN32) || defined(_WIN64)
13793 if (!((STMT *) stmt)->oemcp[0]) {
13794 ret = drvsetcursorname(stmt, cursor, len);
13795 goto done2;
13796 }
13797 if (cursor) {
13798 c = wmb_to_utf_c((char *) cursor, len);
13799 if (!c) {
13800 ret = nomem((STMT *) stmt);
13801 goto done;
13802 }
13803 }
13804 ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13805#else
13806 ret = drvsetcursorname(stmt, cursor, len);
13807#endif
13808#if defined(_WIN32) || defined(_WIN64)
13809done:
13810 uc_free(c);
13811done2:
13812 ;
13813#endif
13815 return ret;
13816}
13817#endif
13818
13819#ifdef WINTERFACE
13828SQLRETURN SQL_API
13829SQLSetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT len)
13830{
13831 char *c = NULL;
13832 SQLRETURN ret;
13833
13835 if (cursor) {
13836 c = uc_to_utf_c(cursor, len);
13837 if (!c) {
13838 ret = nomem((STMT *) stmt);
13839 goto done;
13840 }
13841 }
13842 ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13843done:
13844 uc_free(c);
13846 return ret;
13847}
13848#endif
13849
13856SQLRETURN SQL_API
13858{
13859 return drvfreestmt(stmt, SQL_CLOSE);
13860}
13861
13870SQLRETURN SQL_API
13871SQLAllocHandle(SQLSMALLINT type, SQLHANDLE input, SQLHANDLE *output)
13872{
13873 SQLRETURN ret;
13874
13875 switch (type) {
13876 case SQL_HANDLE_ENV:
13877 ret = drvallocenv((SQLHENV *) output);
13878 if (ret == SQL_SUCCESS) {
13879 ENV *e = (ENV *) *output;
13880
13881 if (e && e->magic == ENV_MAGIC) {
13882 e->ov3 = 1;
13883 }
13884 }
13885 return ret;
13886 case SQL_HANDLE_DBC:
13887 return drvallocconnect((SQLHENV) input, (SQLHDBC *) output);
13888 case SQL_HANDLE_STMT:
13889 HDBC_LOCK((SQLHDBC) input);
13890 ret = drvallocstmt((SQLHDBC) input, (SQLHSTMT *) output);
13891 HDBC_UNLOCK((SQLHDBC) input);
13892 return ret;
13893 }
13894 return SQL_ERROR;
13895}
13896
13904SQLRETURN SQL_API
13905SQLFreeHandle(SQLSMALLINT type, SQLHANDLE h)
13906{
13907 switch (type) {
13908 case SQL_HANDLE_ENV:
13909 return drvfreeenv((SQLHENV) h);
13910 case SQL_HANDLE_DBC:
13911 return drvfreeconnect((SQLHDBC) h);
13912 case SQL_HANDLE_STMT:
13913 return drvfreestmt((SQLHSTMT) h, SQL_DROP);
13914 }
13915 return SQL_ERROR;
13916}
13917
13923static void
13925{
13926 if (s->dyncols) {
13927 int i;
13928
13929 for (i = 0; i < s->dcols; i++) {
13930 freep(&s->dyncols[i].typename);
13931 }
13932 if (s->cols == s->dyncols) {
13933 s->cols = NULL;
13934 s->ncols = 0;
13935 }
13936 freep(&s->dyncols);
13937 }
13938 s->dcols = 0;
13939}
13940
13952static void
13953freeresult(STMT *s, int clrcols)
13954{
13955 freep(&s->bincache);
13956 s->bincell = NULL;
13957 s->binlen = 0;
13958 if (s->rows) {
13959 if (s->rowfree) {
13960 s->rowfree(s->rows);
13961 s->rowfree = NULL;
13962 }
13963 s->rows = NULL;
13964 }
13965 s->nrows = -1;
13966 if (clrcols > 0) {
13967 freep(&s->bindcols);
13968 s->nbindcols = 0;
13969 }
13970 if (clrcols) {
13971 freedyncols(s);
13972 s->cols = NULL;
13973 s->ncols = 0;
13974 s->nowchar[1] = 0;
13975 s->one_tbl = -1;
13976 s->has_pk = -1;
13977 s->has_rowid = -1;
13978 }
13979}
13980
13986static void
13988{
13989 int i;
13990
13991 for (i = 0; s->bindcols && i < s->nbindcols; i++) {
13992 s->bindcols[i].type = SQL_UNKNOWN_TYPE;
13993 s->bindcols[i].max = 0;
13994 s->bindcols[i].lenp = NULL;
13995 s->bindcols[i].valp = NULL;
13996 s->bindcols[i].index = i;
13997 s->bindcols[i].offs = 0;
13998 }
13999}
14000
14008static SQLRETURN
14009mkbindcols(STMT *s, int ncols)
14010{
14011 if (s->bindcols) {
14012 if (s->nbindcols < ncols) {
14013 int i;
14014 BINDCOL *bindcols =
14015 xrealloc(s->bindcols, ncols * sizeof (BINDCOL));
14016
14017 if (!bindcols) {
14018 return nomem(s);
14019 }
14020 for (i = s->nbindcols; i < ncols; i++) {
14021 bindcols[i].type = SQL_UNKNOWN_TYPE;
14022 bindcols[i].max = 0;
14023 bindcols[i].lenp = NULL;
14024 bindcols[i].valp = NULL;
14025 bindcols[i].index = i;
14026 bindcols[i].offs = 0;
14027 }
14028 s->bindcols = bindcols;
14029 s->nbindcols = ncols;
14030 }
14031 } else if (ncols > 0) {
14032 s->bindcols = (BINDCOL *) xmalloc(ncols * sizeof (BINDCOL));
14033 if (!s->bindcols) {
14034 return nomem(s);
14035 }
14036 s->nbindcols = ncols;
14037 unbindcols(s);
14038 }
14039 return SQL_SUCCESS;
14040}
14041
14055static SQLRETURN
14056getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype,
14057 SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp, int partial)
14058{
14059 char **data, valdummy[16];
14060 SQLLEN dummy;
14061 SQLINTEGER *ilenp = NULL;
14062 int valnull = 0;
14063 int type = otype;
14064 SQLRETURN sret = SQL_NO_DATA;
14065
14066 if (!lenp) {
14067 lenp = &dummy;
14068 }
14069 /* workaround for JDK 1.7.0 on x86_64 */
14070 if (((SQLINTEGER *) lenp) + 1 == (SQLINTEGER *) val) {
14071 ilenp = (SQLINTEGER *) lenp;
14072 lenp = &dummy;
14073 }
14074 if (col >= s->ncols) {
14075 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
14076 return SQL_ERROR;
14077 }
14078 if (s->retr_data != SQL_RD_ON) {
14079 return SQL_SUCCESS;
14080 }
14081 if (!s->rows) {
14082 *lenp = SQL_NULL_DATA;
14083 goto done;
14084 }
14085 if (s->rowp < 0 || s->rowp >= s->nrows) {
14086 *lenp = SQL_NULL_DATA;
14087 goto done;
14088 }
14089 type = mapdeftype(type, s->cols[col].type, s->cols[col].nosign ? 1 : 0,
14090 s->nowchar[0]);
14091#if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
14092 /* MS Access hack part 3 (map SQL_C_DEFAULT to SQL_C_CHAR) */
14093 if (type == SQL_C_WCHAR && otype == SQL_C_DEFAULT) {
14094 type = SQL_C_CHAR;
14095 }
14096#endif
14097 data = s->rows + s->ncols + (s->rowp * s->ncols) + col;
14098 if (!val) {
14099 valnull = 1;
14100 val = (SQLPOINTER) valdummy;
14101 }
14102 if (*data == NULL) {
14103 *lenp = SQL_NULL_DATA;
14104 switch (type) {
14105 case SQL_C_UTINYINT:
14106 case SQL_C_TINYINT:
14107 case SQL_C_STINYINT:
14108#ifdef SQL_BIT
14109 case SQL_C_BIT:
14110#endif
14111 *((SQLCHAR *) val) = 0;
14112 break;
14113 case SQL_C_USHORT:
14114 case SQL_C_SHORT:
14115 case SQL_C_SSHORT:
14116 *((SQLSMALLINT *) val) = 0;
14117 break;
14118 case SQL_C_ULONG:
14119 case SQL_C_LONG:
14120 case SQL_C_SLONG:
14121 *((SQLINTEGER *) val) = 0;
14122 break;
14123#ifdef SQL_BIGINT
14124 case SQL_C_SBIGINT:
14125 case SQL_C_UBIGINT:
14126 *((SQLBIGINT *) val) = 0;
14127 break;
14128#endif
14129 case SQL_C_FLOAT:
14130 *((float *) val) = 0;
14131 break;
14132 case SQL_C_DOUBLE:
14133 *((double *) val) = 0;
14134 break;
14135 case SQL_C_BINARY:
14136 case SQL_C_CHAR:
14137 if (len > 0) {
14138 *((SQLCHAR *) val) = '\0';
14139 }
14140 break;
14141#ifdef WCHARSUPPORT
14142 case SQL_C_WCHAR:
14143 if (len > 0) {
14144 *((SQLWCHAR *) val) = '\0';
14145 }
14146 break;
14147#endif
14148#ifdef SQL_C_TYPE_DATE
14149 case SQL_C_TYPE_DATE:
14150#endif
14151 case SQL_C_DATE:
14152 memset((DATE_STRUCT *) val, 0, sizeof (DATE_STRUCT));
14153 break;
14154#ifdef SQL_C_TYPE_TIME
14155 case SQL_C_TYPE_TIME:
14156#endif
14157 case SQL_C_TIME:
14158 memset((TIME_STRUCT *) val, 0, sizeof (TIME_STRUCT));
14159 break;
14160#ifdef SQL_C_TYPE_TIMESTAMP
14161 case SQL_C_TYPE_TIMESTAMP:
14162#endif
14163 case SQL_C_TIMESTAMP:
14164 memset((TIMESTAMP_STRUCT *) val, 0, sizeof (TIMESTAMP_STRUCT));
14165 break;
14166 default:
14167 return SQL_ERROR;
14168 }
14169 } else {
14170 char *endp = NULL;
14171#if defined(_WIN32) || defined(_WIN64)
14172#ifdef SQL_BIGINT
14173 char endc;
14174#endif
14175#endif
14176
14177 switch (type) {
14178 case SQL_C_UTINYINT:
14179 case SQL_C_TINYINT:
14180 case SQL_C_STINYINT:
14181 *((SQLCHAR *) val) = strtol(*data, &endp, 0);
14182 if (endp && endp == *data) {
14183 *lenp = SQL_NULL_DATA;
14184 } else {
14185 *lenp = sizeof (SQLCHAR);
14186 }
14187 break;
14188#ifdef SQL_BIT
14189 case SQL_C_BIT:
14190 *((SQLCHAR *) val) = getbool(*data);
14191 *lenp = sizeof (SQLCHAR);
14192 break;
14193#endif
14194 case SQL_C_USHORT:
14195 case SQL_C_SHORT:
14196 case SQL_C_SSHORT:
14197 *((SQLSMALLINT *) val) = strtol(*data, &endp, 0);
14198 if (endp && endp == *data) {
14199 *lenp = SQL_NULL_DATA;
14200 } else {
14201 *lenp = sizeof (SQLSMALLINT);
14202 }
14203 break;
14204 case SQL_C_ULONG:
14205 case SQL_C_LONG:
14206 case SQL_C_SLONG:
14207 *((SQLINTEGER *) val) = strtol(*data, &endp, 0);
14208 if (endp && endp == *data) {
14209 *lenp = SQL_NULL_DATA;
14210 } else {
14211 *lenp = sizeof (SQLINTEGER);
14212 }
14213 break;
14214#ifdef SQL_BIGINT
14215 case SQL_C_UBIGINT:
14216#if defined(_WIN32) || defined(_WIN64)
14217 if (sscanf(*data, "%I64u%c", (SQLUBIGINT *) val, &endc) != 1) {
14218 *lenp = SQL_NULL_DATA;
14219 } else {
14220 *lenp = sizeof (SQLUBIGINT);
14221 }
14222#else
14223#ifdef __osf__
14224 *((SQLUBIGINT *) val) = strtoul(*data, &endp, 0);
14225#else
14226 *((SQLUBIGINT *) val) = strtoull(*data, &endp, 0);
14227#endif
14228 if (endp && endp == *data) {
14229 *lenp = SQL_NULL_DATA;
14230 } else {
14231 *lenp = sizeof (SQLUBIGINT);
14232 }
14233#endif
14234 break;
14235 case SQL_C_SBIGINT:
14236#if defined(_WIN32) || defined(_WIN64)
14237 if (sscanf(*data, "%I64d%c", (SQLBIGINT *) val, &endc) != 1) {
14238 *lenp = SQL_NULL_DATA;
14239 } else {
14240 *lenp = sizeof (SQLBIGINT);
14241 }
14242#else
14243#ifdef __osf__
14244 *((SQLBIGINT *) val) = strtol(*data, &endp, 0);
14245#else
14246 *((SQLBIGINT *) val) = strtoll(*data, &endp, 0);
14247#endif
14248 if (endp && endp == *data) {
14249 *lenp = SQL_NULL_DATA;
14250 } else {
14251 *lenp = sizeof (SQLBIGINT);
14252 }
14253#endif
14254 break;
14255#endif
14256 case SQL_C_FLOAT:
14257 *((float *) val) = ln_strtod(*data, &endp);
14258 if (endp && endp == *data) {
14259 *lenp = SQL_NULL_DATA;
14260 } else {
14261 *lenp = sizeof (float);
14262 }
14263 break;
14264 case SQL_C_DOUBLE:
14265 *((double *) val) = ln_strtod(*data, &endp);
14266 if (endp && endp == *data) {
14267 *lenp = SQL_NULL_DATA;
14268 } else {
14269 *lenp = sizeof (double);
14270 }
14271 break;
14272 case SQL_C_BINARY: {
14273 int dlen, offs = 0;
14274 char *bin;
14275
14276 if (valnull) {
14277 freep(&s->bincache);
14278 s->binlen = 0;
14279 goto doCHAR;
14280 }
14281 if (*data == s->bincell) {
14282 if (s->bincache) {
14283 bin = s->bincache;
14284 dlen = s->binlen;
14285 } else {
14286 goto doCHAR;
14287 }
14288 } else {
14289 char *dp;
14290 int i;
14291
14292 freep(&s->bincache);
14293 dp = *data;
14294 dlen = strlen(dp);
14295 s->bincell = dp;
14296 s->binlen = 0;
14297 if (!(dp[0] == 'x' || dp[0] == 'X') || dp[1] != '\'' ||
14298 dp[dlen - 1] != '\'') {
14299 goto doCHAR;
14300 }
14301 dlen -= 2;
14302 dp += 2;
14303 dlen = dlen / 2;
14304 s->bincache = bin = xmalloc(dlen + 1);
14305 if (!bin) {
14306 return nomem(s);
14307 }
14308 s->binlen = dlen;
14309 memset(bin, 0, dlen);
14310 bin[dlen] = '\0'; /* terminator, just in case */
14311 for (i = 0; i < dlen; i++) {
14312 char *x;
14313 int v;
14314
14315 if (!*dp || !(x = strchr(xdigits, *dp))) {
14316 goto converr;
14317 }
14318 v = x - xdigits;
14319 bin[i] = (v >= 16) ? ((v - 6) << 4) : (v << 4);
14320 ++dp;
14321 if (!*dp || !(x = strchr(xdigits, *dp))) {
14322converr:
14323 freep(&s->bincache);
14324 s->binlen = 0;
14325 setstat(s, -1, "conversion error",
14326 (*s->ov3) ? "HY000" : "S1000");
14327 return SQL_ERROR;
14328 }
14329 v = x - xdigits;
14330 bin[i] |= (v >= 16) ? (v - 6) : v;
14331 ++dp;
14332 }
14333 bin = s->bincache;
14334 }
14335 if (partial && len && s->bindcols) {
14336 if (s->bindcols[col].offs >= dlen) {
14337 *lenp = 0;
14338 if (!dlen && s->bindcols[col].offs == dlen) {
14339 s->bindcols[col].offs = 1;
14340 sret = SQL_SUCCESS;
14341 goto done;
14342 }
14343 s->bindcols[col].offs = 0;
14344 sret = SQL_NO_DATA;
14345 goto done;
14346 }
14347 offs = s->bindcols[col].offs;
14348 dlen -= offs;
14349 }
14350 if (val && len) {
14351 memcpy(val, bin + offs, min(len, dlen));
14352 }
14353 if (len < 1) {
14354 *lenp = dlen;
14355 } else {
14356 *lenp = min(len, dlen);
14357 if (*lenp == len && *lenp != dlen) {
14358 *lenp = SQL_NO_TOTAL;
14359 }
14360 }
14361 if (partial && len && s->bindcols) {
14362 if (*lenp == SQL_NO_TOTAL) {
14363 *lenp = dlen;
14364 s->bindcols[col].offs += len;
14365 setstat(s, -1, "data right truncated", "01004");
14366 if (s->bindcols[col].lenp) {
14367 *s->bindcols[col].lenp = dlen;
14368 }
14369 sret = SQL_SUCCESS_WITH_INFO;
14370 goto done;
14371 }
14372 s->bindcols[col].offs += *lenp;
14373 }
14374 if (*lenp == SQL_NO_TOTAL) {
14375 *lenp = dlen;
14376 setstat(s, -1, "data right truncated", "01004");
14377 sret = SQL_SUCCESS_WITH_INFO;
14378 goto done;
14379 }
14380 break;
14381 }
14382 doCHAR:
14383#ifdef WCHARSUPPORT
14384 case SQL_C_WCHAR:
14385#endif
14386 case SQL_C_CHAR: {
14387 int doz, zlen = len - 1;
14388 int dlen = strlen(*data);
14389 int offs = 0;
14390#ifdef WCHARSUPPORT
14391 SQLWCHAR *ucdata = NULL;
14392 SQLCHAR *cdata = (SQLCHAR *) *data;
14393#endif
14394
14395#if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
14396 /* MS Access hack part 2 (reserved error -7748) */
14397 if (!valnull &&
14398 (s->cols == statSpec2P || s->cols == statSpec3P) &&
14399 type == SQL_C_WCHAR) {
14400 if (len > 0 && len <= sizeof (SQLWCHAR)) {
14401 ((char *) val)[0] = data[0][0];
14402 memset((char *) val + 1, 0, len - 1);
14403 *lenp = 1;
14404 sret = SQL_SUCCESS;
14405 goto done;
14406 }
14407 }
14408#endif
14409
14410#ifdef WCHARSUPPORT
14411 switch (type) {
14412 case SQL_C_CHAR:
14413 doz = 1;
14414 break;
14415 case SQL_C_WCHAR:
14416 doz = sizeof (SQLWCHAR);
14417 break;
14418 default:
14419 doz = 0;
14420 break;
14421 }
14422 if (type == SQL_C_WCHAR) {
14423 ucdata = uc_from_utf(cdata, dlen);
14424 if (!ucdata) {
14425 return nomem(s);
14426 }
14427 dlen = uc_strlen(ucdata) * sizeof (SQLWCHAR);
14428 }
14429#if defined(_WIN32) || defined(_WIN64)
14430 else if (*s->oemcp && type == SQL_C_CHAR) {
14431 ucdata = (SQLWCHAR *) utf_to_wmb((char *) cdata, dlen);
14432 if (!ucdata) {
14433 return nomem(s);
14434 }
14435 cdata = (SQLCHAR *) ucdata;
14436 dlen = strlen((char *) cdata);
14437 }
14438#endif
14439#else
14440 doz = (type == SQL_C_CHAR) ? 1 : 0;
14441#endif
14442 if (partial && len && s->bindcols) {
14443 if (s->bindcols[col].offs >= dlen) {
14444#ifdef WCHARSUPPORT
14445 uc_free(ucdata);
14446#endif
14447 *lenp = 0;
14448 if (doz && val) {
14449#ifdef WCHARSUPPORT
14450 if (type == SQL_C_WCHAR) {
14451 ((SQLWCHAR *) val)[0] = 0;
14452 } else {
14453 ((char *) val)[0] = '\0';
14454 }
14455#else
14456 ((char *) val)[0] = '\0';
14457#endif
14458 }
14459 if (!dlen && s->bindcols[col].offs == dlen) {
14460 s->bindcols[col].offs = 1;
14461 sret = SQL_SUCCESS;
14462 goto done;
14463 }
14464 s->bindcols[col].offs = 0;
14465 sret = SQL_NO_DATA;
14466 goto done;
14467 }
14468 offs = s->bindcols[col].offs;
14469 dlen -= offs;
14470 }
14471 if (val && !valnull && len) {
14472#ifdef WCHARSUPPORT
14473 if (type == SQL_C_WCHAR) {
14474 uc_strncpy(val, ucdata + offs / sizeof (SQLWCHAR),
14475 (len - doz) / sizeof (SQLWCHAR));
14476 } else {
14477 strncpy(val, (char *) cdata + offs, len - doz);
14478 }
14479#else
14480 strncpy(val, *data + offs, len - doz);
14481#endif
14482 }
14483 if (valnull || len < 1) {
14484 *lenp = dlen;
14485 } else {
14486 *lenp = min(len - doz, dlen);
14487 if (*lenp == len - doz && *lenp != dlen) {
14488 *lenp = SQL_NO_TOTAL;
14489 } else if (*lenp < zlen) {
14490 zlen = *lenp;
14491 }
14492 }
14493 if (len && !valnull && doz) {
14494#ifdef WCHARSUPPORT
14495 if (type == SQL_C_WCHAR) {
14496 ((SQLWCHAR *) val)[zlen / sizeof (SQLWCHAR)] = 0;
14497 } else {
14498 ((char *) val)[zlen] = '\0';
14499 }
14500#else
14501 ((char *) val)[zlen] = '\0';
14502#endif
14503 }
14504#ifdef WCHARSUPPORT
14505 uc_free(ucdata);
14506#endif
14507 if (partial && len && s->bindcols) {
14508 if (*lenp == SQL_NO_TOTAL) {
14509 *lenp = dlen;
14510 s->bindcols[col].offs += len - doz;
14511 setstat(s, -1, "data right truncated", "01004");
14512 if (s->bindcols[col].lenp) {
14513 *s->bindcols[col].lenp = dlen;
14514 }
14515 sret = SQL_SUCCESS_WITH_INFO;
14516 goto done;
14517 }
14518 s->bindcols[col].offs += *lenp;
14519 }
14520 if (*lenp == SQL_NO_TOTAL) {
14521 *lenp = dlen;
14522 setstat(s, -1, "data right truncated", "01004");
14523 sret = SQL_SUCCESS_WITH_INFO;
14524 goto done;
14525 }
14526 break;
14527 }
14528#ifdef SQL_C_TYPE_DATE
14529 case SQL_C_TYPE_DATE:
14530#endif
14531 case SQL_C_DATE:
14532 if (str2date(*s->jdconv, *data, (DATE_STRUCT *) val) < 0) {
14533 *lenp = SQL_NULL_DATA;
14534 } else {
14535 *lenp = sizeof (DATE_STRUCT);
14536 }
14537 break;
14538#ifdef SQL_C_TYPE_TIME
14539 case SQL_C_TYPE_TIME:
14540#endif
14541 case SQL_C_TIME:
14542 if (str2time(*s->jdconv, *data, (TIME_STRUCT *) val) < 0) {
14543 *lenp = SQL_NULL_DATA;
14544 } else {
14545 *lenp = sizeof (TIME_STRUCT);
14546 }
14547 break;
14548#ifdef SQL_C_TYPE_TIMESTAMP
14549 case SQL_C_TYPE_TIMESTAMP:
14550#endif
14551 case SQL_C_TIMESTAMP:
14552 if (str2timestamp(*s->jdconv, *data,
14553 (TIMESTAMP_STRUCT *) val) < 0) {
14554 *lenp = SQL_NULL_DATA;
14555 } else {
14556 *lenp = sizeof (TIMESTAMP_STRUCT);
14557 }
14558 switch (s->cols[col].prec) {
14559 case 0:
14560 ((TIMESTAMP_STRUCT *) val)->fraction = 0;
14561 break;
14562 case 1:
14563 ((TIMESTAMP_STRUCT *) val)->fraction /= 100000000;
14564 ((TIMESTAMP_STRUCT *) val)->fraction *= 100000000;
14565 break;
14566 case 2:
14567 ((TIMESTAMP_STRUCT *) val)->fraction /= 10000000;
14568 ((TIMESTAMP_STRUCT *) val)->fraction *= 10000000;
14569 break;
14570 }
14571 break;
14572 default:
14573 return SQL_ERROR;
14574 }
14575 }
14576 sret = SQL_SUCCESS;
14577done:
14578 if (ilenp) {
14579 *ilenp = *lenp;
14580 }
14581 return sret;
14582}
14583
14595static SQLRETURN
14596drvbindcol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14597 SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14598{
14599 STMT *s;
14600 int sz = 0;
14601
14602 if (stmt == SQL_NULL_HSTMT) {
14603 return SQL_INVALID_HANDLE;
14604 }
14605 s = (STMT *) stmt;
14606 if (col < 1) {
14607 if (col == 0 && s->bkmrk == SQL_UB_ON &&
14608 type == SQL_C_BOOKMARK) {
14609 s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14610 s->bkmrkcol.max = val ? sizeof (SQLINTEGER) : 0;
14611 s->bkmrkcol.lenp = val ? lenp : 0;
14612 s->bkmrkcol.valp = val;
14613 s->bkmrkcol.offs = 0;
14614 if (val && lenp) {
14615 *lenp = 0;
14616 }
14617 return SQL_SUCCESS;
14618 } else if (col == 0 && s->bkmrk == SQL_UB_VARIABLE &&
14619 type == SQL_C_VARBOOKMARK &&
14620 max >= sizeof (sqlite_int64)) {
14621 s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14622 s->bkmrkcol.max = val ? max : 0;
14623 s->bkmrkcol.lenp = val ? lenp : 0;
14624 s->bkmrkcol.valp = val;
14625 s->bkmrkcol.offs = 0;
14626 if (val && lenp) {
14627 *lenp = 0;
14628 }
14629 return SQL_SUCCESS;
14630 }
14631 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
14632 return SQL_ERROR;
14633 }
14634 if (mkbindcols(s, col) != SQL_SUCCESS) {
14635 return SQL_ERROR;
14636 }
14637 --col;
14638 if (type == SQL_C_DEFAULT) {
14639 type = mapdeftype(type, s->cols[col].type, 0,
14640 s->nowchar[0] || s->nowchar[1]);
14641 }
14642 switch (type) {
14643 case SQL_C_LONG:
14644 case SQL_C_ULONG:
14645 case SQL_C_SLONG:
14646 sz = sizeof (SQLINTEGER);
14647 break;
14648 case SQL_C_TINYINT:
14649 case SQL_C_UTINYINT:
14650 case SQL_C_STINYINT:
14651 sz = sizeof (SQLCHAR);
14652 break;
14653 case SQL_C_SHORT:
14654 case SQL_C_USHORT:
14655 case SQL_C_SSHORT:
14656 sz = sizeof (SQLSMALLINT);
14657 break;
14658 case SQL_C_FLOAT:
14659 sz = sizeof (SQLFLOAT);
14660 break;
14661 case SQL_C_DOUBLE:
14662 sz = sizeof (SQLDOUBLE);
14663 break;
14664 case SQL_C_TIMESTAMP:
14665 sz = sizeof (SQL_TIMESTAMP_STRUCT);
14666 break;
14667 case SQL_C_TIME:
14668 sz = sizeof (SQL_TIME_STRUCT);
14669 break;
14670 case SQL_C_DATE:
14671 sz = sizeof (SQL_DATE_STRUCT);
14672 break;
14673 case SQL_C_CHAR:
14674 break;
14675#ifdef WCHARSUPPORT
14676 case SQL_C_WCHAR:
14677 break;
14678#endif
14679#ifdef SQL_C_TYPE_DATE
14680 case SQL_C_TYPE_DATE:
14681 sz = sizeof (SQL_DATE_STRUCT);
14682 break;
14683#endif
14684#ifdef SQL_C_TYPE_TIME
14685 case SQL_C_TYPE_TIME:
14686 sz = sizeof (SQL_TIME_STRUCT);
14687 break;
14688#endif
14689#ifdef SQL_C_TYPE_TIMESTAMP
14690 case SQL_C_TYPE_TIMESTAMP:
14691 sz = sizeof (SQL_TIMESTAMP_STRUCT);
14692 break;
14693#endif
14694#ifdef SQL_BIT
14695 case SQL_C_BIT:
14696 sz = sizeof (SQLCHAR);
14697 break;
14698#endif
14699 case SQL_C_BINARY:
14700 break;
14701#ifdef SQL_BIGINT
14702 case SQL_C_SBIGINT:
14703 case SQL_C_UBIGINT:
14704 sz = sizeof (SQLBIGINT);
14705 break;
14706#endif
14707 default:
14708 if (val == NULL) {
14709 /* fall through, unbinding column */
14710 break;
14711 }
14712 setstat(s, -1, "invalid type %d", "HY003", type);
14713 return SQL_ERROR;
14714 }
14715 if (val == NULL) {
14716 /* unbind column */
14717 s->bindcols[col].type = SQL_UNKNOWN_TYPE;
14718 s->bindcols[col].max = 0;
14719 s->bindcols[col].lenp = NULL;
14720 s->bindcols[col].valp = NULL;
14721 s->bindcols[col].offs = 0;
14722 } else {
14723 if (sz == 0 && max < 0) {
14724 setstat(s, -1, "invalid length", "HY090");
14725 return SQL_ERROR;
14726 }
14727 s->bindcols[col].type = type;
14728 s->bindcols[col].max = (sz == 0) ? max : sz;
14729 s->bindcols[col].lenp = lenp;
14730 s->bindcols[col].valp = val;
14731 s->bindcols[col].offs = 0;
14732 if (lenp) {
14733 *lenp = 0;
14734 }
14735 }
14736 return SQL_SUCCESS;
14737}
14738
14750SQLRETURN SQL_API
14751SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14752 SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14753{
14754 SQLRETURN ret;
14755
14757 ret = drvbindcol(stmt, col, type, val, max, lenp);
14759 return ret;
14760}
14761
14766static COL tableSpec2[] = {
14767 { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
14768 { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
14769 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14770 { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14771 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14772};
14773
14774static COL tableSpec3[] = {
14775 { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
14776 { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
14777 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14778 { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14779 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14780};
14781
14796static SQLRETURN
14798 SQLCHAR *cat, SQLSMALLINT catLen,
14799 SQLCHAR *schema, SQLSMALLINT schemaLen,
14800 SQLCHAR *table, SQLSMALLINT tableLen,
14801 SQLCHAR *type, SQLSMALLINT typeLen)
14802{
14803 SQLRETURN ret;
14804 STMT *s;
14805 DBC *d;
14806 int ncols, asize, rc, size, npatt;
14807 char *errp = NULL, *sql, tname[512];
14808 char *where = "(type = 'table' or type = 'view')";
14809
14811 tableSpec3, array_size(tableSpec3), &asize);
14812 if (ret != SQL_SUCCESS) {
14813 return ret;
14814 }
14815 s = (STMT *) stmt;
14816 d = (DBC *) s->dbc;
14817 if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] == '%') {
14818 int size = 3 * asize;
14819
14820 s->rows = xmalloc(size * sizeof (char *));
14821 if (!s->rows) {
14822 s->nrows = 0;
14823 return nomem(s);
14824 }
14825 memset(s->rows, 0, sizeof (char *) * size);
14826 s->ncols = asize;
14827 s->rows[s->ncols + 0] = "";
14828 s->rows[s->ncols + 1] = "";
14829 s->rows[s->ncols + 2] = "";
14830 s->rows[s->ncols + 3] = "TABLE";
14831 s->rows[s->ncols + 5] = "";
14832 s->rows[s->ncols + 6] = "";
14833 s->rows[s->ncols + 7] = "";
14834 s->rows[s->ncols + 8] = "VIEW";
14835#ifdef MEMORY_DEBUG
14836 s->rowfree = xfree__;
14837#else
14838 s->rowfree = sqlite3_free;
14839#endif
14840 s->nrows = 2;
14841 s->rowp = s->rowprs = -1;
14842 return SQL_SUCCESS;
14843 }
14844 if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
14845 table = NULL;
14846 goto doit;
14847 }
14848 if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
14849 schema[0] == '%') {
14850 if ((!cat || catLen == 0 || !cat[0]) &&
14851 (!table || tableLen == 0 || !table[0])) {
14852 table = NULL;
14853 goto doit;
14854 }
14855 }
14856 if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] != '\0') {
14857 char tmp[256], *t;
14858 int with_view = 0, with_table = 0;
14859
14860 if (typeLen == SQL_NTS) {
14861 strncpy(tmp, (char *) type, sizeof (tmp));
14862 tmp[sizeof (tmp) - 1] = '\0';
14863 } else {
14864 int len = min(sizeof (tmp) - 1, typeLen);
14865
14866 strncpy(tmp, (char *) type, len);
14867 tmp[len] = '\0';
14868 }
14869 t = tmp;
14870 while (*t) {
14871 *t = TOLOWER(*t);
14872 t++;
14873 }
14874 t = tmp;
14875 unescpat(t);
14876 while (t) {
14877 if (t[0] == '\'') {
14878 ++t;
14879 }
14880 if (strncmp(t, "table", 5) == 0) {
14881 with_table++;
14882 } else if (strncmp(t, "view", 4) == 0) {
14883 with_view++;
14884 }
14885 t = strchr(t, ',');
14886 if (t) {
14887 ++t;
14888 }
14889 }
14890 if (with_view && with_table) {
14891 /* where is already preset */
14892 } else if (with_view && !with_table) {
14893 where = "type = 'view'";
14894 } else if (!with_view && with_table) {
14895 where = "type = 'table'";
14896 } else {
14897 return SQL_SUCCESS;
14898 }
14899 }
14900doit:
14901 if (!table) {
14902 size = 1;
14903 tname[0] = '%';
14904 } else {
14905 if (tableLen == SQL_NTS) {
14906 size = sizeof (tname) - 1;
14907 } else {
14908 size = min(sizeof (tname) - 1, tableLen);
14909 }
14910 strncpy(tname, (char *) table, size);
14911 }
14912 tname[size] = '\0';
14913 npatt = unescpat(tname);
14914#if defined(_WIN32) || defined(_WIN64)
14915 if (npatt) {
14916 sql = sqlite3_mprintf("select %s as 'TABLE_CAT', "
14917 "%s as 'TABLE_SCHEM', "
14918 "tbl_name as 'TABLE_NAME', "
14919 "upper(type) as 'TABLE_TYPE', "
14920 "NULL as 'REMARKS' "
14921 "from sqlite_master where %s "
14922 "and tbl_name like %Q",
14923 d->xcelqrx ? "'main'" : "NULL",
14924 d->xcelqrx ? "''" : "NULL",
14925 where, tname);
14926 } else {
14927 sql = sqlite3_mprintf("select %s as 'TABLE_CAT', "
14928 "%s as 'TABLE_SCHEM', "
14929 "tbl_name as 'TABLE_NAME', "
14930 "upper(type) as 'TABLE_TYPE', "
14931 "NULL as 'REMARKS' "
14932 "from sqlite_master where %s "
14933 "and lower(tbl_name) = lower(%Q)",
14934 d->xcelqrx ? "'main'" : "NULL",
14935 d->xcelqrx ? "''" : "NULL",
14936 where, tname);
14937 }
14938#else
14939 if (npatt) {
14940 sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
14941 "NULL as 'TABLE_OWNER', "
14942 "tbl_name as 'TABLE_NAME', "
14943 "upper(type) as 'TABLE_TYPE', "
14944 "NULL as 'REMARKS' "
14945 "from sqlite_master where %s "
14946 "and tbl_name like %Q",
14947 where, tname);
14948 } else {
14949 sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
14950 "NULL as 'TABLE_OWNER', "
14951 "tbl_name as 'TABLE_NAME', "
14952 "upper(type) as 'TABLE_TYPE', "
14953 "NULL as 'REMARKS' "
14954 "from sqlite_master where %s "
14955 "and lower(tbl_name) = lower(%Q)",
14956 where, tname);
14957 }
14958#endif
14959 if (!sql) {
14960 return nomem(s);
14961 }
14962 ret = starttran(s);
14963 if (ret != SQL_SUCCESS) {
14964 sqlite3_free(sql);
14965 return ret;
14966 }
14967 dbtraceapi(d, "sqlite3_get_table", sql);
14968 rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
14969 sqlite3_free(sql);
14970 if (rc == SQLITE_OK) {
14971 if (ncols != s->ncols) {
14972 freeresult(s, 0);
14973 s->nrows = 0;
14974 } else {
14975 s->rowfree = sqlite3_free_table;
14976 }
14977 } else {
14978 s->nrows = 0;
14979 s->rows = NULL;
14980 s->rowfree = NULL;
14981 }
14982 if (errp) {
14983 sqlite3_free(errp);
14984 errp = NULL;
14985 }
14986 s->rowp = s->rowprs = -1;
14987 return SQL_SUCCESS;
14988}
14989
14990#ifndef WINTERFACE
15005SQLRETURN SQL_API
15006SQLTables(SQLHSTMT stmt,
15007 SQLCHAR *cat, SQLSMALLINT catLen,
15008 SQLCHAR *schema, SQLSMALLINT schemaLen,
15009 SQLCHAR *table, SQLSMALLINT tableLen,
15010 SQLCHAR *type, SQLSMALLINT typeLen)
15011{
15012#if defined(_WIN32) || defined(_WIN64)
15013 char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
15014#endif
15015 SQLRETURN ret;
15016
15018#if defined(_WIN32) || defined(_WIN64)
15019 if (!((STMT *) stmt)->oemcp[0]) {
15020 ret = drvtables(stmt, cat, catLen, schema, schemaLen,
15021 table, tableLen, type, typeLen);
15022 goto done2;
15023 }
15024 if (cat) {
15025 c = wmb_to_utf_c((char *) cat, catLen);
15026 if (!c) {
15027 ret = nomem((STMT *) stmt);
15028 goto done;
15029 }
15030 }
15031 if (schema) {
15032 s = wmb_to_utf_c((char *) schema, schemaLen);
15033 if (!s) {
15034 ret = nomem((STMT *) stmt);
15035 goto done;
15036 }
15037 }
15038 if (table) {
15039 t = wmb_to_utf_c((char *) table, tableLen);
15040 if (!t) {
15041 ret = nomem((STMT *) stmt);
15042 goto done;
15043 }
15044 }
15045 if (type) {
15046 y = wmb_to_utf_c((char *) type, typeLen);
15047 if (!y) {
15048 ret = nomem((STMT *) stmt);
15049 goto done;
15050 }
15051 }
15052 ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15053 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
15054#else
15055 ret = drvtables(stmt, cat, catLen, schema, schemaLen,
15056 table, tableLen, type, typeLen);
15057#endif
15058#if defined(_WIN32) || defined(_WIN64)
15059done:
15060 uc_free(y);
15061 uc_free(t);
15062 uc_free(s);
15063 uc_free(c);
15064done2:
15065 ;
15066#endif
15068 return ret;
15069}
15070#endif
15071
15072#ifdef WINTERFACE
15087SQLRETURN SQL_API
15089 SQLWCHAR *cat, SQLSMALLINT catLen,
15090 SQLWCHAR *schema, SQLSMALLINT schemaLen,
15091 SQLWCHAR *table, SQLSMALLINT tableLen,
15092 SQLWCHAR *type, SQLSMALLINT typeLen)
15093{
15094 char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
15095 SQLRETURN ret;
15096
15098 if (cat) {
15099 c = uc_to_utf_c(cat, catLen);
15100 if (!c) {
15101 ret = nomem((STMT *) stmt);
15102 goto done;
15103 }
15104 }
15105 if (schema) {
15106 s = uc_to_utf_c(schema, schemaLen);
15107 if (!s) {
15108 ret = nomem((STMT *) stmt);
15109 goto done;
15110 }
15111 }
15112 if (table) {
15113 t = uc_to_utf_c(table, tableLen);
15114 if (!t) {
15115 ret = nomem((STMT *) stmt);
15116 goto done;
15117 }
15118 }
15119 if (type) {
15120 y = uc_to_utf_c(type, typeLen);
15121 if (!y) {
15122 ret = nomem((STMT *) stmt);
15123 goto done;
15124 }
15125 }
15126 ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15127 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
15128done:
15129 uc_free(y);
15130 uc_free(t);
15131 uc_free(s);
15132 uc_free(c);
15134 return ret;
15135}
15136#endif
15137
15142static COL colSpec2[] = {
15143 { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
15144 { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
15145 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
15146 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15147 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
15148 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
15149 { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
15150 { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
15151 { "SYSTEM", "COLUMN", "SCALE", SQL_SMALLINT, 50 },
15152 { "SYSTEM", "COLUMN", "RADIX", SQL_SMALLINT, 50 },
15153 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
15154 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
15155 { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
15156 { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
15157 { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
15158 { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
15159 { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
15160 { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
15161};
15162
15163static COL colSpec3[] = {
15164 { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
15165 { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
15166 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
15167 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15168 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
15169 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
15170 { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
15171 { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
15172 { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_SMALLINT, 50 },
15173 { "SYSTEM", "COLUMN", "NUM_PREC_RADIX", SQL_SMALLINT, 50 },
15174 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
15175 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
15176 { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
15177 { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
15178 { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
15179 { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
15180 { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
15181 { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
15182};
15183
15198static SQLRETURN
15200 SQLCHAR *cat, SQLSMALLINT catLen,
15201 SQLCHAR *schema, SQLSMALLINT schemaLen,
15202 SQLCHAR *table, SQLSMALLINT tableLen,
15203 SQLCHAR *col, SQLSMALLINT colLen)
15204{
15205 SQLRETURN sret;
15206 STMT *s;
15207 DBC *d;
15208 int ret, nrows, ncols, asize, i, k, roffs, namec;
15209 int tnrows, tncols, npatt;
15210 PTRDIFF_T size;
15211 char *errp = NULL, *sql, tname[512], cname[512], **rowp, **trows;
15212
15214 colSpec3, array_size(colSpec3), &asize);
15215 if (sret != SQL_SUCCESS) {
15216 return sret;
15217 }
15218 s = (STMT *) stmt;
15219 d = (DBC *) s->dbc;
15220 if (!table) {
15221 size = 1;
15222 tname[0] = '%';
15223 } else {
15224 if (tableLen == SQL_NTS) {
15225 size = sizeof (tname) - 1;
15226 } else {
15227 size = min(sizeof (tname) - 1, tableLen);
15228 }
15229 strncpy(tname, (char *) table, size);
15230 }
15231 tname[size] = '\0';
15232 npatt = unescpat(tname);
15233 size = 0;
15234 if (col) {
15235 if (colLen == SQL_NTS) {
15236 size = sizeof (cname) - 1;
15237 } else {
15238 size = min(sizeof (cname) - 1, colLen);
15239 }
15240 strncpy(cname, (char *) col, size);
15241 }
15242 cname[size] = '\0';
15243 if (!strcmp(cname, "%")) {
15244 cname[0] = '\0';
15245 }
15246 if (npatt) {
15247 sql = sqlite3_mprintf("select tbl_name from sqlite_master where "
15248 "(type = 'table' or type = 'view') "
15249 "and tbl_name like %Q", tname);
15250 } else {
15251 sql = sqlite3_mprintf("select tbl_name from sqlite_master where "
15252 "(type = 'table' or type = 'view') "
15253 "and lower(tbl_name) = lower(%Q)", tname);
15254 }
15255 if (!sql) {
15256 return nomem(s);
15257 }
15258 sret = starttran(s);
15259 if (sret != SQL_SUCCESS) {
15260 sqlite3_free(sql);
15261 return sret;
15262 }
15263 dbtraceapi(d, "sqlite3_get_table", sql);
15264 ret = sqlite3_get_table(d->sqlite, sql, &trows, &tnrows, &tncols, &errp);
15265 sqlite3_free(sql);
15266 if (ret != SQLITE_OK) {
15267 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15268 errp ? errp : "unknown error", ret);
15269 if (errp) {
15270 sqlite3_free(errp);
15271 errp = NULL;
15272 }
15273 return SQL_ERROR;
15274 }
15275 if (errp) {
15276 sqlite3_free(errp);
15277 errp = NULL;
15278 }
15279 /* pass 1: compute number of rows of result set */
15280 if (tncols * tnrows <= 0) {
15281 sqlite3_free_table(trows);
15282 return SQL_SUCCESS;
15283 }
15284 size = 0;
15285 for (i = 1; i <= tnrows; i++) {
15286 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
15287 if (!sql) {
15288 sqlite3_free_table(trows);
15289 return nomem(s);
15290 }
15291 dbtraceapi(d, "sqlite3_get_table", sql);
15292 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15293 sqlite3_free(sql);
15294 if (ret != SQLITE_OK) {
15295 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15296 errp ? errp : "unknown error", ret);
15297 if (errp) {
15298 sqlite3_free(errp);
15299 errp = NULL;
15300 }
15301 sqlite3_free_table(trows);
15302 return SQL_ERROR;
15303 }
15304 if (errp) {
15305 sqlite3_free(errp);
15306 errp = NULL;
15307 }
15308 if (ncols * nrows > 0) {
15309 namec = -1;
15310 for (k = 0; k < ncols; k++) {
15311 if (strcmp(rowp[k], "name") == 0) {
15312 namec = k;
15313 break;
15314 }
15315 }
15316 if (cname[0]) {
15317 if (namec >= 0) {
15318 for (k = 1; k <= nrows; k++) {
15319 if (namematch(rowp[k * ncols + namec], cname, 1)) {
15320 size++;
15321 }
15322 }
15323 }
15324 } else {
15325 size += nrows;
15326 }
15327 }
15328 sqlite3_free_table(rowp);
15329 }
15330 /* pass 2: fill result set */
15331 if (size <= 0) {
15332 sqlite3_free_table(trows);
15333 return SQL_SUCCESS;
15334 }
15335 s->nrows = size;
15336 size = (size + 1) * asize;
15337 s->rows = xmalloc((size + 1) * sizeof (char *));
15338 if (!s->rows) {
15339 s->nrows = 0;
15340 sqlite3_free_table(trows);
15341 return nomem(s);
15342 }
15343 s->rows[0] = (char *) size;
15344 s->rows += 1;
15345 memset(s->rows, 0, sizeof (char *) * size);
15346 s->rowfree = freerows;
15347 roffs = 1;
15348 for (i = 1; i <= tnrows; i++) {
15349 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
15350 if (!sql) {
15351 sqlite3_free_table(trows);
15352 return nomem(s);
15353 }
15354 dbtraceapi(d, "sqlite3_get_table", sql);
15355 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15356 sqlite3_free(sql);
15357 if (ret != SQLITE_OK) {
15358 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15359 errp ? errp : "unknown error", ret);
15360 if (errp) {
15361 sqlite3_free(errp);
15362 errp = NULL;
15363 }
15364 sqlite3_free_table(trows);
15365 return SQL_ERROR;
15366 }
15367 if (errp) {
15368 sqlite3_free(errp);
15369 errp = NULL;
15370 }
15371 if (ncols * nrows > 0) {
15372 int m, mr, nr = nrows;
15373
15374 namec = -1;
15375 for (k = 0; k < ncols; k++) {
15376 if (strcmp(rowp[k], "name") == 0) {
15377 namec = k;
15378 break;
15379 }
15380 }
15381 if (cname[0]) {
15382 nr = 0;
15383 if (namec >= 0) {
15384 for (k = 1; k <= nrows; k++) {
15385 if (namematch(rowp[k * ncols + namec], cname, 1)) {
15386 nr++;
15387 }
15388 }
15389 }
15390 }
15391 for (k = 0; k < nr; k++) {
15392 m = asize * (roffs + k);
15393#if defined(_WIN32) || defined(_WIN64)
15394 s->rows[m + 0] = xstrdup(d->xcelqrx ? "main" : "");
15395 s->rows[m + 1] = xstrdup("");
15396#else
15397 s->rows[m + 0] = xstrdup("");
15398 s->rows[m + 1] = xstrdup("");
15399#endif
15400 s->rows[m + 2] = xstrdup(trows[i]);
15401 s->rows[m + 8] = xstrdup("10");
15402 s->rows[m + 9] = xstrdup("0");
15403 s->rows[m + 15] = xstrdup("16384");
15404 }
15405 for (k = 0; nr && k < ncols; k++) {
15406 if (strcmp(rowp[k], "cid") == 0) {
15407 for (mr = 0, m = 1; m <= nrows; m++) {
15408 char buf[256];
15409 int ir, coln = k;
15410
15411 if (cname[0] &&
15412 !namematch(rowp[m * ncols + namec], cname, 1)) {
15413 continue;
15414 }
15415 ir = asize * (roffs + mr);
15416 sscanf(rowp[m * ncols + k], "%d", &coln);
15417 sprintf(buf, "%d", coln + 1);
15418 s->rows[ir + 16] = xstrdup(buf);
15419 ++mr;
15420 }
15421 } else if (k == namec) {
15422 for (mr = 0, m = 1; m <= nrows; m++) {
15423 int ir;
15424
15425 if (cname[0] &&
15426 !namematch(rowp[m * ncols + namec], cname, 1)) {
15427 continue;
15428 }
15429 ir = asize * (roffs + mr);
15430 s->rows[ir + 3] = xstrdup(rowp[m * ncols + k]);
15431 ++mr;
15432 }
15433 } else if (strcmp(rowp[k], "notnull") == 0) {
15434 for (mr = 0, m = 1; m <= nrows; m++) {
15435 int ir;
15436
15437 if (cname[0] &&
15438 !namematch(rowp[m * ncols + namec], cname, 1)) {
15439 continue;
15440 }
15441 ir = asize * (roffs + mr);
15442 if (*rowp[m * ncols + k] != '0') {
15443 s->rows[ir + 10] = xstrdup(stringify(SQL_FALSE));
15444 } else {
15445 s->rows[ir + 10] = xstrdup(stringify(SQL_TRUE));
15446 }
15447 s->rows[ir + 17] =
15448 xstrdup((*rowp[m * ncols + k] != '0') ?
15449 "NO" : "YES");
15450 ++mr;
15451 }
15452 } else if (strcmp(rowp[k], "dflt_value") == 0) {
15453 for (mr = 0, m = 1; m <= nrows; m++) {
15454 char *dflt = unquote(rowp[m * ncols + k]);
15455 int ir;
15456
15457 if (cname[0] &&
15458 !namematch(rowp[m * ncols + namec], cname, 1)) {
15459 continue;
15460 }
15461 ir = asize * (roffs + mr);
15462 s->rows[ir + 12] = xstrdup(dflt ? dflt : "NULL");
15463 ++mr;
15464 }
15465 } else if (strcmp(rowp[k], "type") == 0) {
15466 for (mr = 0, m = 1; m <= nrows; m++) {
15467 char *typename = rowp[m * ncols + k];
15468 int sqltype, mm, dd, ir;
15469 char buf[256];
15470
15471 if (cname[0] &&
15472 !namematch(rowp[m * ncols + namec], cname, 1)) {
15473 continue;
15474 }
15475 ir = asize * (roffs + mr);
15476 s->rows[ir + 5] = xstrdup(typename);
15477 sqltype = mapsqltype(typename, NULL, *s->ov3,
15478 s->nowchar[0], s->dobigint);
15479 getmd(typename, sqltype, &mm, &dd);
15480#ifdef SQL_LONGVARCHAR
15481 if (sqltype == SQL_VARCHAR && mm > 255) {
15482 sqltype = SQL_LONGVARCHAR;
15483 }
15484#endif
15485#ifdef WINTERFACE
15486#ifdef SQL_WLONGVARCHAR
15487 if (sqltype == SQL_WVARCHAR && mm > 255) {
15488 sqltype = SQL_WLONGVARCHAR;
15489 }
15490#endif
15491#endif
15492 if (sqltype == SQL_VARBINARY && mm > 255) {
15493 sqltype = SQL_LONGVARBINARY;
15494 }
15495 sprintf(buf, "%d", sqltype);
15496 s->rows[ir + 4] = xstrdup(buf);
15497 s->rows[ir + 13] = xstrdup(buf);
15498 sprintf(buf, "%d", mm);
15499 s->rows[ir + 7] = xstrdup(buf);
15500 sprintf(buf, "%d", dd);
15501 s->rows[ir + 6] = xstrdup(buf);
15502 ++mr;
15503 }
15504 }
15505 }
15506 roffs += nr;
15507 }
15508 sqlite3_free_table(rowp);
15509 }
15510 sqlite3_free_table(trows);
15511 return SQL_SUCCESS;
15512}
15513
15514#ifndef WINTERFACE
15529SQLRETURN SQL_API
15530SQLColumns(SQLHSTMT stmt,
15531 SQLCHAR *cat, SQLSMALLINT catLen,
15532 SQLCHAR *schema, SQLSMALLINT schemaLen,
15533 SQLCHAR *table, SQLSMALLINT tableLen,
15534 SQLCHAR *col, SQLSMALLINT colLen)
15535{
15536#if defined(_WIN32) || defined(_WIN64)
15537 char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15538#endif
15539 SQLRETURN ret;
15540
15542#if defined(_WIN32) || defined(_WIN64)
15543 if (!((STMT *) stmt)->oemcp[0]) {
15544 ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15545 table, tableLen, col, colLen);
15546 goto done2;
15547 }
15548 if (cat) {
15549 c = wmb_to_utf_c((char *) cat, catLen);
15550 if (!c) {
15551 ret = nomem((STMT *) stmt);
15552 goto done;
15553 }
15554 }
15555 if (schema) {
15556 s = wmb_to_utf_c((char *) schema, schemaLen);
15557 if (!s) {
15558 ret = nomem((STMT *) stmt);
15559 goto done;
15560 }
15561 }
15562 if (table) {
15563 t = wmb_to_utf_c((char *) table, tableLen);
15564 if (!t) {
15565 ret = nomem((STMT *) stmt);
15566 goto done;
15567 }
15568 }
15569 if (col) {
15570 k = wmb_to_utf_c((char *) col, colLen);
15571 if (!k) {
15572 ret = nomem((STMT *) stmt);
15573 goto done;
15574 }
15575 }
15576 ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15577 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15578#else
15579 ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15580 table, tableLen, col, colLen);
15581#endif
15582#if defined(_WIN32) || defined(_WIN64)
15583done:
15584 uc_free(k);
15585 uc_free(t);
15586 uc_free(s);
15587 uc_free(c);
15588done2:
15589 ;
15590#endif
15592 return ret;
15593}
15594#endif
15595
15596#ifdef WINTERFACE
15611SQLRETURN SQL_API
15613 SQLWCHAR *cat, SQLSMALLINT catLen,
15614 SQLWCHAR *schema, SQLSMALLINT schemaLen,
15615 SQLWCHAR *table, SQLSMALLINT tableLen,
15616 SQLWCHAR *col, SQLSMALLINT colLen)
15617{
15618 char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15619 SQLRETURN ret;
15620
15622 if (cat) {
15623 c = uc_to_utf_c(cat, catLen);
15624 if (!c) {
15625 ret = nomem((STMT *) stmt);
15626 goto done;
15627 }
15628 }
15629 if (schema) {
15630 s = uc_to_utf_c(schema, schemaLen);
15631 if (!s) {
15632 ret = nomem((STMT *) stmt);
15633 goto done;
15634 }
15635 }
15636 if (table) {
15637 t = uc_to_utf_c(table, tableLen);
15638 if (!t) {
15639 ret = nomem((STMT *) stmt);
15640 goto done;
15641 }
15642 }
15643 if (col) {
15644 k = uc_to_utf_c(col, colLen);
15645 if (!k) {
15646 ret = nomem((STMT *) stmt);
15647 goto done;
15648 }
15649 }
15650 ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15651 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15652done:
15653 uc_free(k);
15654 uc_free(t);
15655 uc_free(s);
15656 uc_free(c);
15658 return ret;
15659
15660}
15661#endif
15662
15667static COL typeSpec2[] = {
15668 { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15669 { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15670 { "SYSTEM", "TYPE", "PRECISION", SQL_INTEGER, 9 },
15671 { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15672 { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15673 { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15674 { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15675 { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15676 { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15677 { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15678 { "SYSTEM", "TYPE", "MONEY", SQL_SMALLINT, 2 },
15679 { "SYSTEM", "TYPE", "AUTO_INCREMENT", SQL_SMALLINT, 2 },
15680 { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15681 { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15682 { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 }
15683};
15684
15685static COL typeSpec3[] = {
15686 { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15687 { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15688 { "SYSTEM", "TYPE", "COLUMN_SIZE", SQL_INTEGER, 9 },
15689 { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15690 { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15691 { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15692 { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15693 { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15694 { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15695 { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15696 { "SYSTEM", "TYPE", "FIXED_PREC_SCALE", SQL_SMALLINT, 2 },
15697 { "SYSTEM", "TYPE", "AUTO_UNIQUE_VALUE", SQL_SMALLINT, 2 },
15698 { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15699 { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15700 { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 },
15701 { "SYSTEM", "TYPE", "SQL_DATA_TYPE", SQL_SMALLINT, 2 },
15702 { "SYSTEM", "TYPE", "SQL_DATETIME_SUB", SQL_SMALLINT, 2 },
15703 { "SYSTEM", "TYPE", "NUM_PREC_RADIX", SQL_INTEGER, 4 },
15704 { "SYSTEM", "TYPE", "INTERVAL_PRECISION", SQL_SMALLINT, 2 }
15705};
15706
15717static void
15718mktypeinfo(STMT *s, int row, int asize, char *typename, int type, int tind)
15719{
15720 int offs = row * asize;
15721 char *tcode, *crpar = NULL, *sign = stringify(SQL_FALSE);
15722 char *quote[2] = { NULL, NULL };
15723 static char tcodes[32 * 32];
15724
15725 if (tind <= 0) {
15726 tind = row;
15727 }
15728 tcode = tcodes + tind * 32;
15729 sprintf(tcode, "%d", type);
15730 s->rows[offs + 0] = typename;
15731 s->rows[offs + 1] = tcode;
15732 if (asize >= 17) {
15733 s->rows[offs + 15] = tcode;
15734 s->rows[offs + 16] = "0";
15735 }
15736 switch (type) {
15737 default:
15738#ifdef SQL_LONGVARCHAR
15739 case SQL_LONGVARCHAR:
15740#ifdef WINTERFACE
15741 case SQL_WLONGVARCHAR:
15742#endif
15743 crpar = "length";
15744 quote[0] = quote[1] = "'";
15745 sign = NULL;
15746 s->rows[offs + 2] = "65536";
15747 break;
15748#endif
15749#ifdef SQL_BIT
15750 case SQL_BIT:
15751 sign = NULL;
15752 s->rows[offs + 2] = "1";
15753 break;
15754#endif
15755 case SQL_CHAR:
15756 case SQL_VARCHAR:
15757#ifdef WINTERFACE
15758 case SQL_WCHAR:
15759 case SQL_WVARCHAR:
15760#endif
15761 s->rows[offs + 2] = "255";
15762 crpar = "length";
15763 quote[0] = quote[1] = "'";
15764 sign = NULL;
15765 break;
15766 case SQL_TINYINT:
15767 s->rows[offs + 2] = "3";
15768 break;
15769 case SQL_SMALLINT:
15770 s->rows[offs + 2] = "5";
15771 break;
15772 case SQL_INTEGER:
15773 s->rows[offs + 2] = "9";
15774 break;
15775#ifdef SQL_BIGINT
15776 case SQL_BIGINT:
15777 s->rows[offs + 2] = "19";
15778 break;
15779#endif
15780 case SQL_FLOAT:
15781 s->rows[offs + 2] = "7";
15782 break;
15783 case SQL_DOUBLE:
15784 s->rows[offs + 2] = "15";
15785 break;
15786#ifdef SQL_TYPE_DATE
15787 case SQL_TYPE_DATE:
15788#endif
15789 case SQL_DATE:
15790 s->rows[offs + 2] = "10";
15791 quote[0] = quote[1] = "'";
15792 sign = NULL;
15793 break;
15794#ifdef SQL_TYPE_TIME
15795 case SQL_TYPE_TIME:
15796#endif
15797 case SQL_TIME:
15798 s->rows[offs + 2] = "8";
15799 quote[0] = quote[1] = "'";
15800 sign = NULL;
15801 break;
15802#ifdef SQL_TYPE_TIMESTAMP
15803 case SQL_TYPE_TIMESTAMP:
15804#endif
15805 case SQL_TIMESTAMP:
15806 s->rows[offs + 2] = "32";
15807 quote[0] = quote[1] = "'";
15808 sign = NULL;
15809 break;
15810 case SQL_VARBINARY:
15811 quote[0] = "0x";
15812 sign = NULL;
15813 s->rows[offs + 2] = "255";
15814 break;
15815 case SQL_LONGVARBINARY:
15816 quote[0] = "0x";
15817 sign = NULL;
15818 s->rows[offs + 2] = "65536";
15819 break;
15820 }
15821 s->rows[offs + 3] = quote[0];
15822 s->rows[offs + 4] = quote[1];
15823 s->rows[offs + 5] = crpar;
15824 s->rows[offs + 6] = stringify(SQL_NULLABLE);
15825 s->rows[offs + 7] = stringify(SQL_FALSE);
15826 s->rows[offs + 8] = stringify(SQL_SEARCHABLE);
15827 s->rows[offs + 9] = sign;
15828 s->rows[offs + 10] = stringify(SQL_FALSE);
15829 s->rows[offs + 11] = stringify(SQL_FALSE);
15830 s->rows[offs + 12] = typename;
15831 switch (type) {
15832 case SQL_DATE:
15833 case SQL_TIME:
15834 s->rows[offs + 13] = "0";
15835 s->rows[offs + 14] = "0";
15836 break;
15837#ifdef SQL_TYPE_TIMESTAMP
15838 case SQL_TYPE_TIMESTAMP:
15839#endif
15840 case SQL_TIMESTAMP:
15841 s->rows[offs + 13] = "0";
15842 s->rows[offs + 14] = "3";
15843 break;
15844 default:
15845 s->rows[offs + 13] = NULL;
15846 s->rows[offs + 14] = NULL;
15847 break;
15848 }
15849}
15850
15859static int
15860typeinfosort(const void *a, const void *b)
15861{
15862 char **pa = (char **) a;
15863 char **pb = (char **) b;
15864 int na, nb;
15865
15866 na = strtol(pa[1], NULL, 0);
15867 nb = strtol(pb[1], NULL, 0);
15868 return na - nb;
15869}
15870
15878static SQLRETURN
15879drvgettypeinfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
15880{
15881 SQLRETURN ret;
15882 STMT *s;
15883 int asize;
15884
15886 typeSpec3, array_size(typeSpec3), &asize);
15887 if (ret != SQL_SUCCESS) {
15888 return ret;
15889 }
15890 s = (STMT *) stmt;
15891#ifdef SQL_LONGVARCHAR
15892 s->nrows = (sqltype == SQL_ALL_TYPES) ? 13 : 1;
15893#else
15894 s->nrows = (sqltype == SQL_ALL_TYPES) ? 12 : 1;
15895#endif
15896 if (sqltype == SQL_ALL_TYPES) {
15897#ifdef WINTERFACE
15898 s->nrows += 2;
15899#ifdef SQL_WLONGVARCHAR
15900 s->nrows += 2;
15901#endif
15902#endif
15903 }
15904 if (sqltype == SQL_ALL_TYPES) {
15905 s->nrows += 2;
15906#ifdef SQL_BIT
15907 s->nrows += 1;
15908#endif
15909#ifdef SQL_BIGINT
15910 s->nrows += 1;
15911#endif
15912 }
15913 s->rows = (char **) xmalloc(sizeof (char *) * (s->nrows + 1) * asize);
15914 if (!s->rows) {
15915 s->nrows = 0;
15916 return nomem(s);
15917 }
15918#ifdef MEMORY_DEBUG
15919 s->rowfree = xfree__;
15920#else
15921 s->rowfree = sqlite3_free;
15922#endif
15923 memset(s->rows, 0, sizeof (char *) * (s->nrows + 1) * asize);
15924 if (sqltype == SQL_ALL_TYPES) {
15925 int cc = 1;
15926
15927 mktypeinfo(s, cc++, asize, "varchar", SQL_VARCHAR, 0);
15928 mktypeinfo(s, cc++, asize, "tinyint", SQL_TINYINT, 0);
15929 mktypeinfo(s, cc++, asize, "smallint", SQL_SMALLINT, 0);
15930 mktypeinfo(s, cc++, asize, "integer", SQL_INTEGER, 0);
15931 mktypeinfo(s, cc++, asize, "float", SQL_FLOAT, 0);
15932 mktypeinfo(s, cc++, asize, "double", SQL_DOUBLE, 0);
15933#ifdef SQL_TYPE_DATE
15934 mktypeinfo(s, cc++, asize, "date",
15935 (*s->ov3) ? SQL_TYPE_DATE : SQL_DATE, 0);
15936#else
15937 mktypeinfo(s, cc++, asize, "date", SQL_DATE, 0);
15938#endif
15939#ifdef SQL_TYPE_TIME
15940 mktypeinfo(s, cc++, asize, "time",
15941 (*s->ov3) ? SQL_TYPE_TIME : SQL_TIME, 0);
15942#else
15943 mktypeinfo(s, cc++, asize, "time", SQL_TIME, 0);
15944#endif
15945#ifdef SQL_TYPE_TIMESTAMP
15946 mktypeinfo(s, cc++, asize, "timestamp",
15947 (*s->ov3) ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP, 0);
15948#else
15949 mktypeinfo(s, cc++, asize, "timestamp", SQL_TIMESTAMP, 0);
15950#endif
15951 mktypeinfo(s, cc++, asize, "char", SQL_CHAR, 0);
15952 mktypeinfo(s, cc++, asize, "numeric", SQL_DOUBLE, 0);
15953#ifdef SQL_LONGVARCHAR
15954 mktypeinfo(s, cc++, asize, "text", SQL_LONGVARCHAR, 0);
15955 mktypeinfo(s, cc++, asize, "longvarchar", SQL_LONGVARCHAR, 0);
15956#else
15957 mktypeinfo(s, cc++, asize, "text", SQL_VARCHAR, 0);
15958#endif
15959 mktypeinfo(s, cc++, asize, "varbinary", SQL_VARBINARY, 0);
15960 mktypeinfo(s, cc++, asize, "longvarbinary", SQL_LONGVARBINARY, 0);
15961#ifdef SQL_BIT
15962 mktypeinfo(s, cc++, asize, "bit", SQL_BIT, 0);
15963#endif
15964#ifdef SQL_BIGINT
15965 mktypeinfo(s, cc++, asize, "bigint", SQL_BIGINT, 0);
15966#endif
15967#ifdef WINTERFACE
15968 mktypeinfo(s, cc++, asize, "wvarchar", SQL_WVARCHAR, 0);
15969 mktypeinfo(s, cc++, asize, "wchar", SQL_WCHAR, 0);
15970#ifdef SQL_WLONGVARCHAR
15971 mktypeinfo(s, cc++, asize, "wtext", SQL_WLONGVARCHAR, 0);
15972 mktypeinfo(s, cc++, asize, "longwvarchar", SQL_WLONGVARCHAR, 0);
15973#endif
15974#endif
15975 qsort(s->rows + asize, s->nrows, sizeof (char *) * asize,
15976 typeinfosort);
15977 } else {
15978 switch (sqltype) {
15979 case SQL_CHAR:
15980 mktypeinfo(s, 1, asize, "char", SQL_CHAR, 10);
15981 break;
15982 case SQL_VARCHAR:
15983 mktypeinfo(s, 1, asize, "varchar", SQL_VARCHAR, 1);
15984 break;
15985 case SQL_TINYINT:
15986 mktypeinfo(s, 1, asize, "tinyint", SQL_TINYINT, 2);
15987 break;
15988 case SQL_SMALLINT:
15989 mktypeinfo(s, 1, asize, "smallint", SQL_SMALLINT, 3);
15990 break;
15991 case SQL_INTEGER:
15992 mktypeinfo(s, 1, asize, "integer", SQL_INTEGER, 4);
15993 break;
15994 case SQL_FLOAT:
15995 mktypeinfo(s, 1, asize, "float", SQL_FLOAT, 5);
15996 break;
15997 case SQL_DOUBLE:
15998 mktypeinfo(s, 1, asize, "double", SQL_DOUBLE, 6);
15999 break;
16000#ifdef SQL_TYPE_DATE
16001 case SQL_TYPE_DATE:
16002 mktypeinfo(s, 1, asize, "date", SQL_TYPE_DATE, 25);
16003 break;
16004#endif
16005 case SQL_DATE:
16006 mktypeinfo(s, 1, asize, "date", SQL_DATE, 7);
16007 break;
16008#ifdef SQL_TYPE_TIME
16009 case SQL_TYPE_TIME:
16010 mktypeinfo(s, 1, asize, "time", SQL_TYPE_TIME, 26);
16011 break;
16012#endif
16013 case SQL_TIME:
16014 mktypeinfo(s, 1, asize, "time", SQL_TIME, 8);
16015 break;
16016#ifdef SQL_TYPE_TIMESTAMP
16017 case SQL_TYPE_TIMESTAMP:
16018 mktypeinfo(s, 1, asize, "timestamp", SQL_TYPE_TIMESTAMP, 27);
16019 break;
16020#endif
16021 case SQL_TIMESTAMP:
16022 mktypeinfo(s, 1, asize, "timestamp", SQL_TIMESTAMP, 9);
16023 break;
16024#ifdef SQL_LONGVARCHAR
16025 case SQL_LONGVARCHAR:
16026 mktypeinfo(s, 1, asize, "longvarchar", SQL_LONGVARCHAR, 12);
16027 break;
16028#endif
16029 case SQL_VARBINARY:
16030 mktypeinfo(s, 1, asize, "varbinary", SQL_VARBINARY, 30);
16031 break;
16032 case SQL_LONGVARBINARY:
16033 mktypeinfo(s, 1, asize, "longvarbinary", SQL_LONGVARBINARY, 31);
16034 break;
16035#ifdef SQL_BIT
16036 case SQL_BIT:
16037 mktypeinfo(s, 1, asize, "bit", SQL_BIT, 29);
16038 break;
16039#endif
16040#ifdef SQL_BIGINT
16041 case SQL_BIGINT:
16042 mktypeinfo(s, 1, asize, "bigint", SQL_BIGINT, 28);
16043 break;
16044#endif
16045#ifdef WINTERFACE
16046#ifdef SQL_WCHAR
16047 case SQL_WCHAR:
16048 mktypeinfo(s, 1, asize, "wchar", SQL_WCHAR, 18);
16049 break;
16050#endif
16051#ifdef SQL_WVARCHAR
16052 case SQL_WVARCHAR:
16053 mktypeinfo(s, 1, asize, "wvarchar", SQL_WVARCHAR, 19);
16054 break;
16055#endif
16056#ifdef SQL_WLONGVARCHAR
16057 case SQL_WLONGVARCHAR:
16058 mktypeinfo(s, 1, asize, "longwvarchar", SQL_WLONGVARCHAR, 20);
16059 break;
16060#endif
16061#endif
16062 default:
16063 s->nrows = 0;
16064 }
16065 }
16066 return SQL_SUCCESS;
16067}
16068
16069#ifndef WINTERFACE
16077SQLRETURN SQL_API
16078SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
16079{
16080 SQLRETURN ret;
16081
16083 ret = drvgettypeinfo(stmt, sqltype);
16085 return ret;
16086}
16087#endif
16088
16089#ifdef WINTERFACE
16097SQLRETURN SQL_API
16098SQLGetTypeInfoW(SQLHSTMT stmt, SQLSMALLINT sqltype)
16099{
16100 SQLRETURN ret;
16101
16103 ret = drvgettypeinfo(stmt, sqltype);
16105 return ret;
16106}
16107#endif
16108
16113static COL statSpec2[] = {
16114 { "SYSTEM", "STATISTICS", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
16115 { "SYSTEM", "STATISTICS", "TABLE_OWNER", SCOL_VARCHAR, 50 },
16116 { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
16117 { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
16118 { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
16119 { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
16120 { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
16121 { "SYSTEM", "STATISTICS", "SEQ_IN_INDEX", SQL_SMALLINT, 50 },
16122 { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
16123 { "SYSTEM", "STATISTICS", "COLLATION", SCOL_CHAR, 1 },
16124 { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
16125 { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
16126 { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
16127};
16128
16129static COL statSpec3[] = {
16130 { "SYSTEM", "STATISTICS", "TABLE_CAT", SCOL_VARCHAR, 50 },
16131 { "SYSTEM", "STATISTICS", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
16132 { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
16133 { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
16134 { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
16135 { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
16136 { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
16137 { "SYSTEM", "STATISTICS", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
16138 { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
16139 { "SYSTEM", "STATISTICS", "ASC_OR_DESC", SCOL_CHAR, 1 },
16140 { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
16141 { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
16142 { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
16143};
16144
16159static SQLRETURN
16160drvstatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
16161 SQLCHAR *schema, SQLSMALLINT schemaLen,
16162 SQLCHAR *table, SQLSMALLINT tableLen,
16163 SQLUSMALLINT itype, SQLUSMALLINT resv)
16164{
16165 SQLRETURN sret;
16166 STMT *s;
16167 DBC *d;
16168 int i, asize, ret, nrows, ncols, offs, namec, uniquec, addipk = 0;
16169 PTRDIFF_T size;
16170 char **rowp, *errp = NULL, *sql, tname[512];
16171
16173 statSpec3, array_size(statSpec3), &asize);
16174 if (sret != SQL_SUCCESS) {
16175 return sret;
16176 }
16177 s = (STMT *) stmt;
16178 d = (DBC *) s->dbc;
16179 if (!table || table[0] == '\0' || table[0] == '%') {
16180 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
16181 return SQL_ERROR;
16182 }
16183 if (tableLen == SQL_NTS) {
16184 size = sizeof (tname) - 1;
16185 } else {
16186 size = min(sizeof (tname) - 1, tableLen);
16187 }
16188 strncpy(tname, (char *) table, size);
16189 tname[size] = '\0';
16190 unescpat(tname);
16191 sret = starttran(s);
16192 if (sret != SQL_SUCCESS) {
16193 return sret;
16194 }
16195 /*
16196 * Try integer primary key (autoincrement) first
16197 */
16198 if (itype == SQL_INDEX_UNIQUE || itype == SQL_INDEX_ALL) {
16199 rowp = 0;
16200 ret = SQLITE_ERROR;
16201 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
16202 if (sql) {
16203 dbtraceapi(d, "sqlite3_get_table", sql);
16204 ret = sqlite3_get_table(d->sqlite, sql, &rowp,
16205 &nrows, &ncols, NULL);
16206 sqlite3_free(sql);
16207 }
16208 if (ret == SQLITE_OK) {
16209 int colid, typec, npk = 0, npkint = 0;
16210
16211 namec = findcol(rowp, ncols, "name");
16212 uniquec = findcol(rowp, ncols, "pk");
16213 typec = findcol(rowp, ncols, "type");
16214 colid = findcol(rowp, ncols, "cid");
16215 if (namec < 0 || uniquec < 0 || typec < 0 || colid < 0) {
16216 goto noipk;
16217 }
16218 for (i = 1; i <= nrows; i++) {
16219 if (*rowp[i * ncols + uniquec] != '0') {
16220 npk++;
16221 if (strlen(rowp[i * ncols + typec]) == 7 &&
16222 strncasecmp(rowp[i * ncols + typec], "integer", 7)
16223 == 0) {
16224 npkint++;
16225 }
16226 }
16227 }
16228 if (npkint == 1 && npk == npkint) {
16229 addipk = 1;
16230 }
16231 }
16232noipk:
16233 sqlite3_free_table(rowp);
16234 }
16235 sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
16236 if (!sql) {
16237 return nomem(s);
16238 }
16239 dbtraceapi(d, "sqlite3_get_table", sql);
16240 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
16241 sqlite3_free(sql);
16242 if (ret != SQLITE_OK) {
16243 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
16244 errp ? errp : "unknown error", ret);
16245 if (errp) {
16246 sqlite3_free(errp);
16247 errp = NULL;
16248 }
16249 return SQL_ERROR;
16250 }
16251 if (errp) {
16252 sqlite3_free(errp);
16253 errp = NULL;
16254 }
16255 size = 0;
16256 namec = findcol(rowp, ncols, "name");
16257 uniquec = findcol(rowp, ncols, "unique");
16258 if (namec < 0 || uniquec < 0) {
16259 goto nodata;
16260 }
16261 for (i = 1; i <= nrows; i++) {
16262 int nnrows, nncols;
16263 char **rowpp;
16264 int isuniq;
16265
16266 isuniq = *rowp[i * ncols + uniquec] != '0';
16267 if (isuniq || itype == SQL_INDEX_ALL) {
16268 ret = SQLITE_ERROR;
16269 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
16270 rowp[i * ncols + namec]);
16271 if (sql) {
16272 dbtraceapi(d, "sqlite3_get_table", sql);
16273 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16274 &nnrows, &nncols, NULL);
16275 sqlite3_free(sql);
16276 }
16277 if (ret == SQLITE_OK) {
16278 size += nnrows;
16279 sqlite3_free_table(rowpp);
16280 }
16281 }
16282 }
16283nodata:
16284 if (addipk) {
16285 size++;
16286 }
16287 if (size == 0) {
16288 sqlite3_free_table(rowp);
16289 return SQL_SUCCESS;
16290 }
16291 s->nrows = size;
16292 size = (size + 1) * asize;
16293 s->rows = xmalloc((size + 1) * sizeof (char *));
16294 if (!s->rows) {
16295 s->nrows = 0;
16296 return nomem(s);
16297 }
16298 s->rows[0] = (char *) size;
16299 s->rows += 1;
16300 memset(s->rows, 0, sizeof (char *) * size);
16301 s->rowfree = freerows;
16302 offs = 0;
16303 if (addipk) {
16304 char **rowpp = 0;
16305 int nrows2, ncols2;
16306
16307 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
16308 if (sql) {
16309 dbtraceapi(d, "sqlite3_get_table", sql);
16310 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16311 &nrows2, &ncols2, NULL);
16312 sqlite3_free(sql);
16313 }
16314 if (ret == SQLITE_OK) {
16315 int colid, typec, roffs, namecc, uniquecc;
16316
16317 namecc = findcol(rowpp, ncols2, "name");
16318 uniquecc = findcol(rowpp, ncols2, "pk");
16319 typec = findcol(rowpp, ncols2, "type");
16320 colid = findcol(rowpp, ncols2, "cid");
16321 if (namecc < 0 || uniquecc < 0 || typec < 0 || colid < 0) {
16322 addipk = 0;
16323 s->nrows--;
16324 goto nodata2;
16325 }
16326 for (i = 1; i <= nrows2; i++) {
16327 if (*rowpp[i * ncols2 + uniquecc] != '0' &&
16328 strlen(rowpp[i * ncols2 + typec]) == 7 &&
16329 strncasecmp(rowpp[i * ncols2 + typec], "integer", 7)
16330 == 0) {
16331 break;
16332 }
16333 }
16334 if (i > nrows2) {
16335 addipk = 0;
16336 s->nrows--;
16337 goto nodata2;
16338 }
16339 roffs = s->ncols;
16340#if defined(_WIN32) || defined(_WIN64)
16341 s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
16342 s->rows[roffs + 1] = xstrdup("");
16343#else
16344 s->rows[roffs + 0] = xstrdup("");
16345 s->rows[roffs + 1] = xstrdup("");
16346#endif
16347 s->rows[roffs + 2] = xstrdup(tname);
16348 s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16349 s->rows[roffs + 5] = xstrdup("sqlite_autoindex_0");
16350 s->rows[roffs + 6] = xstrdup(stringify(SQL_INDEX_OTHER));
16351 s->rows[roffs + 7] = xstrdup("1");
16352 s->rows[roffs + 8] = xstrdup(rowpp[i * ncols2 + namecc]);
16353 s->rows[roffs + 9] = xstrdup("A");
16354 }
16355nodata2:
16356 sqlite3_free_table(rowpp);
16357 }
16358 for (i = 1; i <= nrows; i++) {
16359 int nnrows, nncols;
16360 char **rowpp = 0;
16361
16362 if (*rowp[i * ncols + uniquec] != '0' || itype == SQL_INDEX_ALL) {
16363 int k;
16364
16365 ret = SQLITE_ERROR;
16366 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
16367 rowp[i * ncols + namec]);
16368 if (sql) {
16369 dbtraceapi(d, "sqlite3_get_table", sql);
16370 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16371 &nnrows, &nncols, NULL);
16372 sqlite3_free(sql);
16373 }
16374 if (ret != SQLITE_OK) {
16375 continue;
16376 }
16377 for (k = 0; nnrows && k < nncols; k++) {
16378 if (strcmp(rowpp[k], "name") == 0) {
16379 int m;
16380
16381 for (m = 1; m <= nnrows; m++) {
16382 int roffs = (offs + addipk + m) * s->ncols;
16383 int isuniq;
16384
16385 isuniq = *rowp[i * ncols + uniquec] != '0';
16386 s->rows[roffs + 0] = xstrdup("");
16387 s->rows[roffs + 1] = xstrdup("");
16388 s->rows[roffs + 2] = xstrdup(tname);
16389 if (isuniq) {
16390 s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16391 } else {
16392 s->rows[roffs + 3] = xstrdup(stringify(SQL_TRUE));
16393 }
16394 s->rows[roffs + 5] = xstrdup(rowp[i * ncols + namec]);
16395 s->rows[roffs + 6] =
16396 xstrdup(stringify(SQL_INDEX_OTHER));
16397 s->rows[roffs + 8] = xstrdup(rowpp[m * nncols + k]);
16398 s->rows[roffs + 9] = xstrdup("A");
16399 }
16400 } else if (strcmp(rowpp[k], "seqno") == 0) {
16401 int m;
16402
16403 for (m = 1; m <= nnrows; m++) {
16404 int roffs = (offs + addipk + m) * s->ncols;
16405 int pos = m - 1;
16406 char buf[32];
16407
16408 sscanf(rowpp[m * nncols + k], "%d", &pos);
16409 sprintf(buf, "%d", pos + 1);
16410 s->rows[roffs + 7] = xstrdup(buf);
16411 }
16412 }
16413 }
16414 offs += nnrows;
16415 sqlite3_free_table(rowpp);
16416 }
16417 }
16418 sqlite3_free_table(rowp);
16419 return SQL_SUCCESS;
16420}
16421
16422#ifndef WINTERFACE
16437SQLRETURN SQL_API
16438SQLStatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
16439 SQLCHAR *schema, SQLSMALLINT schemaLen,
16440 SQLCHAR *table, SQLSMALLINT tableLen,
16441 SQLUSMALLINT itype, SQLUSMALLINT resv)
16442{
16443#if defined(_WIN32) || defined(_WIN64)
16444 char *c = NULL, *s = NULL, *t = NULL;
16445#endif
16446 SQLRETURN ret;
16447
16449#if defined(_WIN32) || defined(_WIN64)
16450 if (!((STMT *) stmt)->oemcp[0]) {
16451 ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16452 table, tableLen, itype, resv);
16453 goto done2;
16454 }
16455 if (cat) {
16456 c = wmb_to_utf_c((char *) cat, catLen);
16457 if (!c) {
16458 ret = nomem((STMT *) stmt);
16459 goto done;
16460 }
16461 }
16462 if (schema) {
16463 s = wmb_to_utf_c((char *) schema, schemaLen);
16464 if (!s) {
16465 ret = nomem((STMT *) stmt);
16466 goto done;
16467 }
16468 }
16469 if (table) {
16470 t = wmb_to_utf_c((char *) table, tableLen);
16471 if (!t) {
16472 ret = nomem((STMT *) stmt);
16473 goto done;
16474 }
16475 }
16476 ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16477 (SQLCHAR *) t, SQL_NTS, itype, resv);
16478#else
16479 ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16480 table, tableLen, itype, resv);
16481#endif
16482#if defined(_WIN32) || defined(_WIN64)
16483done:
16484 uc_free(t);
16485 uc_free(s);
16486 uc_free(c);
16487done2:
16488 ;
16489#endif
16491 return ret;
16492}
16493#endif
16494
16495#ifdef WINTERFACE
16510SQLRETURN SQL_API
16511SQLStatisticsW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen,
16512 SQLWCHAR *schema, SQLSMALLINT schemaLen,
16513 SQLWCHAR *table, SQLSMALLINT tableLen,
16514 SQLUSMALLINT itype, SQLUSMALLINT resv)
16515{
16516 char *c = NULL, *s = NULL, *t = NULL;
16517 SQLRETURN ret;
16518
16520 if (cat) {
16521 c = uc_to_utf_c(cat, catLen);
16522 if (!c) {
16523 ret = nomem((STMT *) stmt);
16524 goto done;
16525 }
16526 }
16527 if (schema) {
16528 s = uc_to_utf_c(schema, schemaLen);
16529 if (!s) {
16530 ret = nomem((STMT *) stmt);
16531 goto done;
16532 }
16533 }
16534 if (table) {
16535 t = uc_to_utf_c(table, tableLen);
16536 if (!t) {
16537 ret = nomem((STMT *) stmt);
16538 goto done;
16539 }
16540 }
16541 ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16542 (SQLCHAR *) t, SQL_NTS, itype, resv);
16543done:
16544 uc_free(t);
16545 uc_free(s);
16546 uc_free(c);
16548 return ret;
16549}
16550#endif
16551
16563SQLRETURN SQL_API
16564SQLGetData(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
16565 SQLPOINTER val, SQLLEN len, SQLLEN *lenp)
16566{
16567 STMT *s;
16568 SQLRETURN ret = SQL_ERROR;
16569
16571 if (stmt == SQL_NULL_HSTMT) {
16572 return SQL_INVALID_HANDLE;
16573 }
16574 s = (STMT *) stmt;
16575 if (col == 0 && s->bkmrk != SQL_UB_OFF) {
16576 if (s->bkmrk == SQL_UB_ON && type == SQL_C_BOOKMARK) {
16577 *((SQLINTEGER *) val) = s->rowp;
16578 if (lenp) {
16579 *lenp = sizeof (SQLINTEGER);
16580 }
16581 ret = SQL_SUCCESS;
16582 goto done;
16583 } else if (s->bkmrk == SQL_UB_VARIABLE && type == SQL_C_VARBOOKMARK) {
16584 if (s->has_rowid >= 0) {
16585 char **data, *endp = 0;
16586
16587 data = s->rows + s->ncols + (s->rowp * s->ncols)
16588 + s->has_rowid;
16589#ifdef __osf__
16590 *((sqlite_int64 *) val) = strtol(*data, &endp, 0);
16591#else
16592 *((sqlite_int64 *) val) = strtoll(*data, &endp, 0);
16593#endif
16594 } else {
16595 *((sqlite_int64 *) val) = s->rowp;
16596 }
16597 if (lenp) {
16598 *lenp = sizeof (sqlite_int64);
16599 }
16600 ret = SQL_SUCCESS;
16601 goto done;
16602 }
16603 }
16604 if (col < 1 || col > s->ncols) {
16605 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
16606 goto done;
16607 }
16608 --col;
16609 ret = getrowdata(s, col, type, val, len, lenp, 1);
16610done:
16612 return ret;
16613}
16614
16622static SQLRETURN
16623dofetchbind(STMT *s, int rsi)
16624{
16625 int ret, i, withinfo = 0;
16626
16627 s->row_status0[rsi] = SQL_ROW_SUCCESS;
16628 if (s->bkmrk != SQL_UB_OFF && s->bkmrkcol.valp) {
16629 int bsize = sizeof (SQLINTEGER);
16630
16631 if (s->bkmrkcol.type == SQL_C_VARBOOKMARK) {
16632 SQLPOINTER *val;
16633
16634 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16635 val = (SQLPOINTER)
16636 ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16637 } else {
16638 val = (SQLPOINTER)
16639 ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * rsi);
16640 }
16641 if (s->bind_offs) {
16642 val = (SQLPOINTER) ((char *) val + *s->bind_offs);
16643 }
16644 if (s->has_rowid >= 0) {
16645 char **data, *endp = 0;
16646
16647 data = s->rows + s->ncols + (s->rowp * s->ncols)
16648 + s->has_rowid;
16649#ifdef __osf__
16650 *(sqlite_int64 *) val = strtol(*data, &endp, 0);
16651#else
16652 *(sqlite_int64 *) val = strtoll(*data, &endp, 0);
16653#endif
16654 } else {
16655 *(sqlite_int64 *) val = s->rowp;
16656 }
16657 bsize = sizeof (sqlite_int64);
16658 } else {
16659 SQLINTEGER *val;
16660
16661 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16662 val = (SQLINTEGER *)
16663 ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16664 } else {
16665 val = (SQLINTEGER *) s->bkmrkcol.valp + rsi;
16666 }
16667 if (s->bind_offs) {
16668 val = (SQLINTEGER *) ((char *) val + *s->bind_offs);
16669 }
16670 *val = s->rowp;
16671 }
16672 if (s->bkmrkcol.lenp) {
16673 SQLLEN *ival;
16674
16675 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16676 ival = (SQLLEN *)
16677 ((char *) s->bkmrkcol.lenp + s->bind_type * rsi);
16678 } else {
16679 ival = &s->bkmrkcol.lenp[rsi];
16680 }
16681 if (s->bind_offs) {
16682 ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
16683 }
16684 *ival = bsize;
16685 }
16686 }
16687 ret = SQL_SUCCESS;
16688 for (i = 0; s->bindcols && i < s->ncols; i++) {
16689 BINDCOL *b = &s->bindcols[i];
16690 SQLPOINTER dp = 0;
16691 SQLLEN *lp = 0;
16692
16693 b->offs = 0;
16694 if (b->valp) {
16695 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16696 dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
16697 } else {
16698 dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
16699 }
16700 if (s->bind_offs) {
16701 dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
16702 }
16703 }
16704 if (b->lenp) {
16705 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16706 lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
16707 } else {
16708 lp = b->lenp + rsi;
16709 }
16710 if (s->bind_offs) {
16711 lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
16712 }
16713 }
16714 if (dp || lp) {
16715 ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp, b->max, lp, 0);
16716 if (!SQL_SUCCEEDED(ret)) {
16717 s->row_status0[rsi] = SQL_ROW_ERROR;
16718 break;
16719 }
16720 if (ret != SQL_SUCCESS) {
16721 withinfo = 1;
16722#ifdef SQL_ROW_SUCCESS_WITH_INFO
16723 s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
16724#endif
16725 }
16726 }
16727 }
16728 if (SQL_SUCCEEDED(ret)) {
16729 ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16730 }
16731 return ret;
16732}
16733
16742static SQLRETURN
16743drvfetchscroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLINTEGER offset)
16744{
16745 STMT *s;
16746 int i, withinfo = 0;
16747 SQLRETURN ret;
16748
16749 if (stmt == SQL_NULL_HSTMT) {
16750 return SQL_INVALID_HANDLE;
16751 }
16752 s = (STMT *) stmt;
16753 for (i = 0; i < s->rowset_size; i++) {
16754 s->row_status0[i] = SQL_ROW_NOROW;
16755 }
16756 if (s->row_status) {
16757 memcpy(s->row_status, s->row_status0,
16758 sizeof (SQLUSMALLINT) * s->rowset_size);
16759 }
16760 s->row_count0 = 0;
16761 if (s->row_count) {
16762 *s->row_count = s->row_count0;
16763 }
16764 if (!s->bindcols) {
16765 for (i = 0; i < s->rowset_size; i++) {
16766 s->row_status0[i] = SQL_ROW_ERROR;
16767 }
16768 ret = SQL_ERROR;
16769 i = 0;
16770 goto done2;
16771 }
16772 if (s->isselect != 1 && s->isselect != -1) {
16773 if (s->isselect != 0 || s->ncols <= 0) {
16774 setstat(s, -1, "no result set available", "24000");
16775 ret = SQL_ERROR;
16776 i = s->nrows;
16777 goto done2;
16778 } else {
16779 /* INSERT/UPDATE/DELETE ... RETURNING ... has columns */
16780 }
16781 }
16782 if (s->curtype == SQL_CURSOR_FORWARD_ONLY && orient != SQL_FETCH_NEXT) {
16783 setstat(s, -1, "wrong fetch direction", "01000");
16784 ret = SQL_ERROR;
16785 i = 0;
16786 goto done2;
16787 }
16788 ret = SQL_SUCCESS;
16789 i = 0;
16790 if (((DBC *) (s->dbc))->cur_s3stmt == s && s->s3stmt) {
16791 s->rowp = s->rowprs = 0;
16792 for (; i < s->rowset_size; i++) {
16793 if (s->max_rows && s->s3stmt_rownum + 1 >= s->max_rows) {
16794 ret = (i == 0) ? SQL_NO_DATA : SQL_SUCCESS;
16795 break;
16796 }
16797 ret = s3stmt_step(s);
16798 if (ret != SQL_SUCCESS) {
16799 s->row_status0[i] = SQL_ROW_ERROR;
16800 break;
16801 }
16802 if (s->nrows < 1) {
16803 break;
16804 }
16805 ret = dofetchbind(s, i);
16806 if (!SQL_SUCCEEDED(ret)) {
16807 break;
16808 } else if (ret == SQL_SUCCESS_WITH_INFO) {
16809 withinfo = 1;
16810 }
16811 }
16812 } else if (s->rows) {
16813 switch (orient) {
16814 case SQL_FETCH_NEXT:
16815 if (s->nrows < 1) {
16816 return SQL_NO_DATA;
16817 }
16818 if (s->rowp < 0) {
16819 s->rowp = -1;
16820 }
16821 if (s->rowp >= s->nrows) {
16822 s->rowp = s->rowprs = s->nrows;
16823 return SQL_NO_DATA;
16824 }
16825 break;
16826 case SQL_FETCH_PRIOR:
16827 if (s->nrows < 1 || s->rowp <= 0) {
16828 s->rowp = s->rowprs = -1;
16829 return SQL_NO_DATA;
16830 }
16831 s->rowp -= s->rowset_size + 1;
16832 if (s->rowp < -1) {
16833 s->rowp = s->rowprs = -1;
16834 return SQL_NO_DATA;
16835 }
16836 break;
16837 case SQL_FETCH_FIRST:
16838 if (s->nrows < 1) {
16839 return SQL_NO_DATA;
16840 }
16841 s->rowp = -1;
16842 break;
16843 case SQL_FETCH_LAST:
16844 if (s->nrows < 1) {
16845 return SQL_NO_DATA;
16846 }
16847 s->rowp = s->nrows - s->rowset_size;
16848 if (--s->rowp < -1) {
16849 s->rowp = -1;
16850 }
16851 break;
16852 case SQL_FETCH_ABSOLUTE:
16853 if (offset == 0) {
16854 s->rowp = s->rowprs = -1;
16855 return SQL_NO_DATA;
16856 } else if (offset < 0) {
16857 if (0 - offset <= s->nrows) {
16858 s->rowp = s->nrows + offset - 1;
16859 break;
16860 }
16861 s->rowp = s->rowprs = -1;
16862 return SQL_NO_DATA;
16863 } else if (offset > s->nrows) {
16864 s->rowp = s->rowprs = s->nrows;
16865 return SQL_NO_DATA;
16866 }
16867 s->rowp = offset - 1 - 1;
16868 break;
16869 case SQL_FETCH_RELATIVE:
16870 if (offset >= 0) {
16871 s->rowp += offset * s->rowset_size - 1;
16872 if (s->rowp >= s->nrows) {
16873 s->rowp = s->rowprs = s->nrows;
16874 return SQL_NO_DATA;
16875 }
16876 } else {
16877 s->rowp += offset * s->rowset_size - 1;
16878 if (s->rowp < -1) {
16879 s->rowp = s->rowprs = -1;
16880 return SQL_NO_DATA;
16881 }
16882 }
16883 break;
16884 case SQL_FETCH_BOOKMARK:
16885 if (s->bkmrk == SQL_UB_ON && !s->bkmrkptr) {
16886 if (offset < 0 || offset >= s->nrows) {
16887 return SQL_NO_DATA;
16888 }
16889 s->rowp = offset - 1;
16890 break;
16891 }
16892 if (s->bkmrk != SQL_UB_OFF && s->bkmrkptr) {
16893 int rowp;
16894
16895 if (s->bkmrk == SQL_UB_VARIABLE) {
16896 if (s->has_rowid >= 0) {
16897 sqlite_int64 bkmrk, rowid;
16898
16899 bkmrk = *(sqlite_int64 *) s->bkmrkptr;
16900 for (rowp = 0; rowp < s->nrows; rowp++) {
16901 char **data, *endp = 0;
16902
16903 data = s->rows + s->ncols + (rowp * s->ncols)
16904 + s->has_rowid;
16905#ifdef __osf__
16906 rowid = strtol(*data, &endp, 0);
16907#else
16908 rowid = strtoll(*data, &endp, 0);
16909#endif
16910 if (rowid == bkmrk) {
16911 break;
16912 }
16913 }
16914 } else {
16915 rowp = *(sqlite_int64 *) s->bkmrkptr;
16916 }
16917 } else {
16918 rowp = *(int *) s->bkmrkptr;
16919 }
16920 if (rowp + offset < 0 || rowp + offset >= s->nrows) {
16921 return SQL_NO_DATA;
16922 }
16923 s->rowp = rowp + offset - 1;
16924 break;
16925 }
16926 /* fall through */
16927 default:
16928 s->row_status0[0] = SQL_ROW_ERROR;
16929 ret = SQL_ERROR;
16930 goto done;
16931 }
16932 s->rowprs = s->rowp + 1;
16933 for (; i < s->rowset_size; i++) {
16934 ++s->rowp;
16935 if (s->rowp < 0 || s->rowp >= s->nrows) {
16936 break;
16937 }
16938 ret = dofetchbind(s, i);
16939 if (!SQL_SUCCEEDED(ret)) {
16940 break;
16941 } else if (ret == SQL_SUCCESS_WITH_INFO) {
16942 withinfo = 1;
16943 }
16944 }
16945 }
16946done:
16947 if (i == 0) {
16948 if (SQL_SUCCEEDED(ret)) {
16949 return SQL_NO_DATA;
16950 }
16951 return ret;
16952 }
16953 if (SQL_SUCCEEDED(ret)) {
16954 ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16955 }
16956done2:
16957 if (s->row_status) {
16958 memcpy(s->row_status, s->row_status0,
16959 sizeof (SQLUSMALLINT) * s->rowset_size);
16960 }
16961 s->row_count0 = i;
16962 if (s->row_count) {
16963 *s->row_count = s->row_count0;
16964 }
16965 return ret;
16966}
16967
16974SQLRETURN SQL_API
16976{
16977 SQLRETURN ret;
16978
16980 ret = drvfetchscroll(stmt, SQL_FETCH_NEXT, 0);
16982 return ret;
16983}
16984
16993SQLRETURN SQL_API
16994SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLLEN offset)
16995{
16996 SQLRETURN ret;
16997
16999 ret = drvfetchscroll(stmt, orient, offset);
17001 return ret;
17002}
17003
17014SQLRETURN SQL_API
17015SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT orient, SQLROWOFFSET offset,
17016 SQLROWSETSIZE *rowcount, SQLUSMALLINT *rowstatus)
17017{
17018 STMT *s;
17019 SQLRETURN ret;
17020 SQLUSMALLINT *rst;
17021 SQLINTEGER *bkmrkptr;
17022
17024 if (stmt == SQL_NULL_HSTMT) {
17025 return SQL_INVALID_HANDLE;
17026 }
17027 s = (STMT *) stmt;
17028 /* temporarily turn off SQL_ATTR_ROW_STATUS_PTR */
17029 rst = s->row_status;
17030 s->row_status = 0;
17031 bkmrkptr = s->bkmrkptr;
17032 s->bkmrkptr = 0;
17033 ret = drvfetchscroll(stmt, orient, offset);
17034 s->row_status = rst;
17035 s->bkmrkptr = bkmrkptr;
17036 if (rowstatus) {
17037 memcpy(rowstatus, s->row_status0,
17038 sizeof (SQLUSMALLINT) * s->rowset_size);
17039 }
17040 if (rowcount) {
17041 *rowcount = s->row_count0;
17042 }
17044 return ret;
17045}
17046
17054SQLRETURN SQL_API
17055SQLRowCount(SQLHSTMT stmt, SQLLEN *nrows)
17056{
17057 STMT *s;
17058
17060 if (stmt == SQL_NULL_HSTMT) {
17061 return SQL_INVALID_HANDLE;
17062 }
17063 s = (STMT *) stmt;
17064 if (nrows) {
17065 *nrows = s->isselect ? 0 : s->nrows;
17066 }
17068 return SQL_SUCCESS;
17069}
17070
17078SQLRETURN SQL_API
17079SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *ncols)
17080{
17081 STMT *s;
17082
17084 if (stmt == SQL_NULL_HSTMT) {
17085 return SQL_INVALID_HANDLE;
17086 }
17087 s = (STMT *) stmt;
17088 if (ncols) {
17089 *ncols = s->ncols;
17090 }
17092 return SQL_SUCCESS;
17093}
17094
17109static SQLRETURN
17110drvdescribecol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
17111 SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
17112 SQLSMALLINT *type, SQLULEN *size,
17113 SQLSMALLINT *digits, SQLSMALLINT *nullable)
17114{
17115 STMT *s;
17116 COL *c;
17117 int didname = 0;
17118
17119 if (stmt == SQL_NULL_HSTMT) {
17120 return SQL_INVALID_HANDLE;
17121 }
17122 s = (STMT *) stmt;
17123 if (!s->cols) {
17124 setstat(s, -1, "no columns", (*s->ov3) ? "07009" : "S1002");
17125 return SQL_ERROR;
17126 }
17127 if (col < 1 || col > s->ncols) {
17128 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
17129 return SQL_ERROR;
17130 }
17131 c = s->cols + col - 1;
17132 if (name && nameMax > 0) {
17133 strncpy((char *) name, c->column, nameMax);
17134 name[nameMax - 1] = '\0';
17135 didname = 1;
17136 }
17137 if (nameLen) {
17138 if (didname) {
17139 *nameLen = strlen((char *) name);
17140 } else {
17141 *nameLen = strlen(c->column);
17142 }
17143 }
17144 if (type) {
17145 *type = c->type;
17146#ifdef WINTERFACE
17147 if (s->nowchar[0] || s->nowchar[1]) {
17148 switch (c->type) {
17149 case SQL_WCHAR:
17150 *type = SQL_CHAR;
17151 break;
17152 case SQL_WVARCHAR:
17153 *type = SQL_VARCHAR;
17154 break;
17155#ifdef SQL_LONGVARCHAR
17156 case SQL_WLONGVARCHAR:
17157 *type = SQL_LONGVARCHAR;
17158 break;
17159#endif
17160 }
17161 }
17162#endif
17163 }
17164 if (size) {
17165 *size = c->size;
17166 }
17167 if (digits) {
17168 *digits = 0;
17169 }
17170 if (nullable) {
17171 *nullable = 1;
17172 }
17173 return SQL_SUCCESS;
17174}
17175
17176#ifndef WINTERFACE
17191SQLRETURN SQL_API
17192SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
17193 SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
17194 SQLSMALLINT *type, SQLULEN *size,
17195 SQLSMALLINT *digits, SQLSMALLINT *nullable)
17196{
17197#if defined(_WIN32) || defined(_WIN64)
17198 SQLSMALLINT len = 0;
17199#endif
17200 SQLRETURN ret;
17201
17203#if defined(_WIN32) || defined(_WIN64)
17204 if (!((STMT *) stmt)->oemcp[0]) {
17205 ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
17206 type, size, digits, nullable);
17207 goto done;
17208 }
17209 ret = drvdescribecol(stmt, col, name, nameMax,
17210 &len, type, size, digits, nullable);
17211 if (ret == SQL_SUCCESS) {
17212 if (name) {
17213 if (len > 0) {
17214 SQLCHAR *n = NULL;
17215
17216 n = (SQLCHAR *) utf_to_wmb((char *) name, len);
17217 if (n) {
17218 strncpy((char *) name, (char *) n, nameMax);
17219 n[len] = 0;
17220 len = min(nameMax, strlen((char *) n));
17221 uc_free(n);
17222 } else {
17223 len = 0;
17224 }
17225 }
17226 if (len <= 0) {
17227 len = 0;
17228 if (nameMax > 0) {
17229 name[0] = 0;
17230 }
17231 }
17232 } else {
17233 STMT *s = (STMT *) stmt;
17234 COL *c = s->cols + col - 1;
17235
17236 len = 0;
17237 if (c->column) {
17238 len = strlen(c->column);
17239 }
17240 }
17241 if (nameLen) {
17242 *nameLen = len;
17243 }
17244 }
17245done:
17246 ;
17247#else
17248 ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
17249 type, size, digits, nullable);
17250#endif
17252 return ret;
17253}
17254#endif
17255
17256#ifdef WINTERFACE
17271SQLRETURN SQL_API
17272SQLDescribeColW(SQLHSTMT stmt, SQLUSMALLINT col, SQLWCHAR *name,
17273 SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
17274 SQLSMALLINT *type, SQLULEN *size,
17275 SQLSMALLINT *digits, SQLSMALLINT *nullable)
17276{
17277 SQLRETURN ret;
17278 SQLSMALLINT len = 0;
17279
17281 ret = drvdescribecol(stmt, col, (SQLCHAR *) name,
17282 (SQLSMALLINT) (nameMax * sizeof (SQLWCHAR)),
17283 &len, type, size, digits, nullable);
17284 if (ret == SQL_SUCCESS) {
17285 if (name) {
17286 if (len > 0) {
17287 SQLWCHAR *n = NULL;
17288
17289 n = uc_from_utf((SQLCHAR *) name, len);
17290 if (n) {
17291 uc_strncpy(name, n, nameMax);
17292 n[len] = 0;
17293 len = min(nameMax, uc_strlen(n));
17294 uc_free(n);
17295 } else {
17296 len = 0;
17297 }
17298 }
17299 if (len <= 0) {
17300 len = 0;
17301 if (nameMax > 0) {
17302 name[0] = 0;
17303 }
17304 }
17305 } else {
17306 STMT *s = (STMT *) stmt;
17307 COL *c = s->cols + col - 1;
17308
17309 len = 0;
17310 if (c->column) {
17311 len = strlen(c->column);
17312 }
17313 }
17314 if (nameLen) {
17315 *nameLen = len;
17316 }
17317 }
17319 return ret;
17320}
17321#endif
17322
17335static SQLRETURN
17336drvcolattributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17337 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17338 SQLLEN *val2)
17339{
17340 STMT *s;
17341 COL *c;
17342 SQLSMALLINT dummy;
17343 char *valc = (char *) val;
17344
17345 if (stmt == SQL_NULL_HSTMT) {
17346 return SQL_INVALID_HANDLE;
17347 }
17348 s = (STMT *) stmt;
17349 if (!s->cols) {
17350 return SQL_ERROR;
17351 }
17352 if (!valLen) {
17353 valLen = &dummy;
17354 }
17355 if (id == SQL_COLUMN_COUNT) {
17356 if (val2) {
17357 *val2 = s->ncols;
17358 }
17359 *valLen = sizeof (int);
17360 return SQL_SUCCESS;
17361 }
17362 if (id == SQL_COLUMN_TYPE && col == 0) {
17363 if (val2) {
17364 *val2 = SQL_INTEGER;
17365 }
17366 *valLen = sizeof (int);
17367 return SQL_SUCCESS;
17368 }
17369#ifdef SQL_DESC_OCTET_LENGTH
17370 if (id == SQL_DESC_OCTET_LENGTH && col == 0) {
17371 if (val2) {
17372 *val2 = 4;
17373 }
17374 *valLen = sizeof (int);
17375 return SQL_SUCCESS;
17376 }
17377#endif
17378 if (col < 1 || col > s->ncols) {
17379 setstat(s, -1, "invalid column", (*s->ov3) ? "07009": "S1002");
17380 return SQL_ERROR;
17381 }
17382 c = s->cols + col - 1;
17383
17384 switch (id) {
17385 case SQL_COLUMN_LABEL:
17386 if (c->label) {
17387 if (valc && valMax > 0) {
17388 strncpy(valc, c->label, valMax);
17389 valc[valMax - 1] = '\0';
17390 }
17391 *valLen = strlen(c->label);
17392 goto checkLen;
17393 }
17394 /* fall through */
17395 case SQL_COLUMN_NAME:
17396 case SQL_DESC_NAME:
17397 if (valc && valMax > 0) {
17398 strncpy(valc, c->column, valMax);
17399 valc[valMax - 1] = '\0';
17400 }
17401 *valLen = strlen(c->column);
17402checkLen:
17403 if (*valLen >= valMax) {
17404 setstat(s, -1, "data right truncated", "01004");
17405 return SQL_SUCCESS_WITH_INFO;
17406 }
17407 return SQL_SUCCESS;
17408#ifdef SQL_DESC_BASE_COLUMN_NAME
17409 case SQL_DESC_BASE_COLUMN_NAME:
17410 if (strchr(c->column, '(') || strchr(c->column, ')')) {
17411 if (valc && valMax > 0) {
17412 valc[0] = '\0';
17413 }
17414 *valLen = 0;
17415 } else if (valc && valMax > 0) {
17416 strncpy(valc, c->column, valMax);
17417 valc[valMax - 1] = '\0';
17418 *valLen = strlen(c->column);
17419 }
17420 goto checkLen;
17421#endif
17422 case SQL_COLUMN_TYPE:
17423 case SQL_DESC_TYPE:
17424#ifdef WINTERFACE
17425 {
17426 int type = c->type;
17427
17428 if (s->nowchar[0] || s->nowchar[1]) {
17429 switch (type) {
17430 case SQL_WCHAR:
17431 type = SQL_CHAR;
17432 break;
17433 case SQL_WVARCHAR:
17434 type = SQL_VARCHAR;
17435 break;
17436#ifdef SQL_LONGVARCHAR
17437 case SQL_WLONGVARCHAR:
17438 type = SQL_LONGVARCHAR;
17439 break;
17440 }
17441 }
17442 if (val2) {
17443 *val2 = type;
17444 }
17445#endif
17446 }
17447#else
17448 if (val2) {
17449 *val2 = c->type;
17450 }
17451#endif
17452 *valLen = sizeof (int);
17453 return SQL_SUCCESS;
17454 case SQL_COLUMN_DISPLAY_SIZE:
17455 if (val2) {
17456 *val2 = c->size;
17457 }
17458 *valLen = sizeof (int);
17459 return SQL_SUCCESS;
17460 case SQL_COLUMN_UNSIGNED:
17461 if (val2) {
17462 *val2 = c->nosign ? SQL_TRUE : SQL_FALSE;
17463 }
17464 *valLen = sizeof (int);
17465 return SQL_SUCCESS;
17466 case SQL_COLUMN_SCALE:
17467 case SQL_DESC_SCALE:
17468 if (val2) {
17469 *val2 = c->scale;
17470 }
17471 *valLen = sizeof (int);
17472 return SQL_SUCCESS;
17473 case SQL_COLUMN_PRECISION:
17474 case SQL_DESC_PRECISION:
17475 if (val2) {
17476 switch (c->type) {
17477 case SQL_SMALLINT:
17478 *val2 = 5;
17479 break;
17480 case SQL_INTEGER:
17481 *val2 = 10;
17482 break;
17483 case SQL_FLOAT:
17484 case SQL_REAL:
17485 case SQL_DOUBLE:
17486 *val2 = 15;
17487 break;
17488 case SQL_DATE:
17489 *val2 = 0;
17490 break;
17491 case SQL_TIME:
17492 *val2 = 0;
17493 break;
17494#ifdef SQL_TYPE_TIMESTAMP
17495 case SQL_TYPE_TIMESTAMP:
17496#endif
17497 case SQL_TIMESTAMP:
17498 *val2 = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
17499 break;
17500 default:
17501 *val2 = c->prec;
17502 break;
17503 }
17504 }
17505 *valLen = sizeof (int);
17506 return SQL_SUCCESS;
17507 case SQL_COLUMN_MONEY:
17508 if (val2) {
17509 *val2 = SQL_FALSE;
17510 }
17511 *valLen = sizeof (int);
17512 return SQL_SUCCESS;
17513 case SQL_COLUMN_AUTO_INCREMENT:
17514 if (val2) {
17515 *val2 = c->autoinc;
17516 }
17517 *valLen = sizeof (int);
17518 return SQL_SUCCESS;
17519 case SQL_COLUMN_LENGTH:
17520 case SQL_DESC_LENGTH:
17521 if (val2) {
17522 *val2 = c->size;
17523 }
17524 *valLen = sizeof (int);
17525 return SQL_SUCCESS;
17526 case SQL_COLUMN_NULLABLE:
17527 case SQL_DESC_NULLABLE:
17528 if (val2) {
17529 *val2 = c->notnull;
17530 }
17531 *valLen = sizeof (int);
17532 return SQL_SUCCESS;
17533 case SQL_COLUMN_SEARCHABLE:
17534 if (val2) {
17535 *val2 = SQL_SEARCHABLE;
17536 }
17537 *valLen = sizeof (int);
17538 return SQL_SUCCESS;
17539 case SQL_COLUMN_CASE_SENSITIVE:
17540 if (val2) {
17541 *val2 = SQL_TRUE;
17542 }
17543 *valLen = sizeof (int);
17544 return SQL_SUCCESS;
17545 case SQL_COLUMN_UPDATABLE:
17546 if (val2) {
17547 *val2 = SQL_TRUE;
17548 }
17549 *valLen = sizeof (int);
17550 return SQL_SUCCESS;
17551 case SQL_DESC_COUNT:
17552 if (val2) {
17553 *val2 = s->ncols;
17554 }
17555 *valLen = sizeof (int);
17556 return SQL_SUCCESS;
17557 case SQL_COLUMN_TYPE_NAME: {
17558 char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17559
17560#ifdef WINTERFACE
17561 if (c->type == SQL_WCHAR ||
17562 c->type == SQL_WVARCHAR ||
17563 c->type == SQL_WLONGVARCHAR) {
17564 if (!(s->nowchar[0] || s->nowchar[1])) {
17565 if (strcasecmp(tn, "varchar") == 0) {
17566 tn = "wvarchar";
17567 }
17568 }
17569 }
17570#endif
17571 if (valc && valMax > 0) {
17572 strncpy(valc, tn, valMax);
17573 valc[valMax - 1] = '\0';
17574 p = strchr(valc, '(');
17575 if (p) {
17576 *p = '\0';
17577 while (p > valc && ISSPACE(p[-1])) {
17578 --p;
17579 *p = '\0';
17580 }
17581 }
17582 *valLen = strlen(valc);
17583 } else {
17584 *valLen = strlen(tn);
17585 p = strchr(tn, '(');
17586 if (p) {
17587 *valLen = p - tn;
17588 while (p > tn && ISSPACE(p[-1])) {
17589 --p;
17590 *valLen -= 1;
17591 }
17592 }
17593 }
17594 goto checkLen;
17595 }
17596 case SQL_COLUMN_OWNER_NAME:
17597 case SQL_COLUMN_QUALIFIER_NAME: {
17598 char *z = "";
17599
17600 if (valc && valMax > 0) {
17601 strncpy(valc, z, valMax);
17602 valc[valMax - 1] = '\0';
17603 }
17604 *valLen = strlen(z);
17605 goto checkLen;
17606 }
17607 case SQL_COLUMN_TABLE_NAME:
17608#if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17609 case SQL_DESC_TABLE_NAME:
17610#endif
17611#ifdef SQL_DESC_BASE_TABLE_NAME
17612 case SQL_DESC_BASE_TABLE_NAME:
17613#endif
17614 if (valc && valMax > 0) {
17615 strncpy(valc, c->table, valMax);
17616 valc[valMax - 1] = '\0';
17617 }
17618 *valLen = strlen(c->table);
17619 goto checkLen;
17620#ifdef SQL_DESC_NUM_PREC_RADIX
17621 case SQL_DESC_NUM_PREC_RADIX:
17622 if (val2) {
17623 switch (c->type) {
17624#ifdef WINTERFACE
17625 case SQL_WCHAR:
17626 case SQL_WVARCHAR:
17627#ifdef SQL_LONGVARCHAR
17628 case SQL_WLONGVARCHAR:
17629#endif
17630#endif
17631 case SQL_CHAR:
17632 case SQL_VARCHAR:
17633#ifdef SQL_LONGVARCHAR
17634 case SQL_LONGVARCHAR:
17635#endif
17636 case SQL_BINARY:
17637 case SQL_VARBINARY:
17638 case SQL_LONGVARBINARY:
17639 *val2 = 0;
17640 break;
17641 default:
17642 *val2 = 2;
17643 }
17644 }
17645 *valLen = sizeof (int);
17646 return SQL_SUCCESS;
17647#endif
17648 }
17649 setstat(s, -1, "unsupported column attributes %d", "HY091", id);
17650 return SQL_ERROR;
17651}
17652
17653#ifndef WINTERFACE
17666SQLRETURN SQL_API
17667SQLColAttributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17668 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17669 SQLLEN *val2)
17670{
17671#if defined(_WIN32) || defined(_WIN64)
17672 SQLSMALLINT len = 0;
17673#endif
17674 SQLRETURN ret;
17675
17677#if defined(_WIN32) || defined(_WIN64)
17678 if (!((STMT *) stmt)->oemcp[0]) {
17679 ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17680 goto done;
17681 }
17682 ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17683 if (SQL_SUCCEEDED(ret)) {
17684 char *v = NULL;
17685
17686 switch (id) {
17687 case SQL_COLUMN_LABEL:
17688 case SQL_COLUMN_NAME:
17689 case SQL_DESC_NAME:
17690 case SQL_COLUMN_TYPE_NAME:
17691 case SQL_COLUMN_OWNER_NAME:
17692 case SQL_COLUMN_QUALIFIER_NAME:
17693 case SQL_COLUMN_TABLE_NAME:
17694#if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17695 case SQL_DESC_TABLE_NAME:
17696#endif
17697#ifdef SQL_DESC_BASE_COLUMN_NAME
17698 case SQL_DESC_BASE_COLUMN_NAME:
17699#endif
17700#ifdef SQL_DESC_BASE_TABLE_NAME
17701 case SQL_DESC_BASE_TABLE_NAME:
17702#endif
17703 if (val && valMax > 0) {
17704 int vmax = valMax;
17705
17706 v = utf_to_wmb((char *) val, SQL_NTS);
17707 if (v) {
17708 strncpy(val, v, vmax);
17709 len = min(vmax, strlen(v));
17710 uc_free(v);
17711 }
17712 if (vmax > 0) {
17713 v = (char *) val;
17714 v[vmax - 1] = '\0';
17715 }
17716 }
17717 if (len <= 0) {
17718 len = 0;
17719 }
17720 break;
17721 }
17722 if (valLen) {
17723 *valLen = len;
17724 }
17725 }
17726done:
17727 ;
17728#else
17729 ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17730#endif
17732 return ret;
17733}
17734#endif
17735
17736#ifdef WINTERFACE
17749SQLRETURN SQL_API
17750SQLColAttributesW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17751 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17752 SQLLEN *val2)
17753{
17754 SQLRETURN ret;
17755 SQLSMALLINT len = 0;
17756
17758 ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17759 if (SQL_SUCCEEDED(ret)) {
17760 SQLWCHAR *v = NULL;
17761
17762 switch (id) {
17763 case SQL_COLUMN_LABEL:
17764 case SQL_COLUMN_NAME:
17765 case SQL_DESC_NAME:
17766 case SQL_COLUMN_TYPE_NAME:
17767 case SQL_COLUMN_OWNER_NAME:
17768 case SQL_COLUMN_QUALIFIER_NAME:
17769 case SQL_COLUMN_TABLE_NAME:
17770#if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17771 case SQL_DESC_TABLE_NAME:
17772#endif
17773#ifdef SQL_DESC_BASE_COLUMN_NAME
17774 case SQL_DESC_BASE_COLUMN_NAME:
17775#endif
17776#ifdef SQL_DESC_BASE_TABLE_NAME
17777 case SQL_DESC_BASE_TABLE_NAME:
17778#endif
17779 if (val && valMax > 0) {
17780 int vmax = valMax / sizeof (SQLWCHAR);
17781
17782 v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
17783 if (v) {
17784 uc_strncpy(val, v, vmax);
17785 len = min(vmax, uc_strlen(v));
17786 uc_free(v);
17787 len *= sizeof (SQLWCHAR);
17788 }
17789 if (vmax > 0) {
17790 v = (SQLWCHAR *) val;
17791 v[vmax - 1] = '\0';
17792 }
17793 }
17794 if (len <= 0) {
17795 len = 0;
17796 }
17797 break;
17798 }
17799 if (valLen) {
17800 *valLen = len;
17801 }
17802 }
17804 return ret;
17805}
17806#endif
17807
17820static SQLRETURN
17821drvcolattribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17822 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17823 SQLPOINTER val2)
17824{
17825 STMT *s;
17826 COL *c;
17827 int v = 0;
17828 char *valc = (char *) val;
17829 SQLSMALLINT dummy;
17830
17831 if (stmt == SQL_NULL_HSTMT) {
17832 return SQL_INVALID_HANDLE;
17833 }
17834 s = (STMT *) stmt;
17835 if (!s->cols) {
17836 return SQL_ERROR;
17837 }
17838 if (col < 1 || col > s->ncols) {
17839 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
17840 return SQL_ERROR;
17841 }
17842 if (!valLen) {
17843 valLen = &dummy;
17844 }
17845 c = s->cols + col - 1;
17846 switch (id) {
17847 case SQL_DESC_COUNT:
17848 v = s->ncols;
17849 break;
17850 case SQL_DESC_CATALOG_NAME:
17851 if (valc && valMax > 0) {
17852 strncpy(valc, c->db, valMax);
17853 valc[valMax - 1] = '\0';
17854 }
17855 *valLen = strlen(c->db);
17856checkLen:
17857 if (*valLen >= valMax) {
17858 setstat(s, -1, "data right truncated", "01004");
17859 return SQL_SUCCESS_WITH_INFO;
17860 }
17861 break;
17862 case SQL_COLUMN_LENGTH:
17863 case SQL_DESC_LENGTH:
17864 v = c->size;
17865 break;
17866 case SQL_COLUMN_LABEL:
17867 if (c->label) {
17868 if (valc && valMax > 0) {
17869 strncpy(valc, c->label, valMax);
17870 valc[valMax - 1] = '\0';
17871 }
17872 *valLen = strlen(c->label);
17873 goto checkLen;
17874 }
17875 /* fall through */
17876 case SQL_COLUMN_NAME:
17877 case SQL_DESC_NAME:
17878 if (valc && valMax > 0) {
17879 strncpy(valc, c->column, valMax);
17880 valc[valMax - 1] = '\0';
17881 }
17882 *valLen = strlen(c->column);
17883 goto checkLen;
17884 case SQL_DESC_SCHEMA_NAME: {
17885 char *z = "";
17886
17887 if (valc && valMax > 0) {
17888 strncpy(valc, z, valMax);
17889 valc[valMax - 1] = '\0';
17890 }
17891 *valLen = strlen(z);
17892 goto checkLen;
17893 }
17894#ifdef SQL_DESC_BASE_COLUMN_NAME
17895 case SQL_DESC_BASE_COLUMN_NAME:
17896 if (strchr(c->column, '(') || strchr(c->column, ')')) {
17897 valc[0] = '\0';
17898 *valLen = 0;
17899 } else if (valc && valMax > 0) {
17900 strncpy(valc, c->column, valMax);
17901 valc[valMax - 1] = '\0';
17902 *valLen = strlen(c->column);
17903 }
17904 goto checkLen;
17905#endif
17906 case SQL_DESC_TYPE_NAME: {
17907 char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17908
17909#ifdef WINTERFACE
17910 if (c->type == SQL_WCHAR ||
17911 c->type == SQL_WVARCHAR ||
17912 c->type == SQL_WLONGVARCHAR) {
17913 if (!(s->nowchar[0] || s->nowchar[1])) {
17914 if (strcasecmp(tn, "varchar") == 0) {
17915 tn = "wvarchar";
17916 }
17917 }
17918 }
17919#endif
17920 if (valc && valMax > 0) {
17921 strncpy(valc, tn, valMax);
17922 valc[valMax - 1] = '\0';
17923 p = strchr(valc, '(');
17924 if (p) {
17925 *p = '\0';
17926 while (p > valc && ISSPACE(p[-1])) {
17927 --p;
17928 *p = '\0';
17929 }
17930 }
17931 *valLen = strlen(valc);
17932 } else {
17933 *valLen = strlen(tn);
17934 p = strchr(tn, '(');
17935 if (p) {
17936 *valLen = p - tn;
17937 while (p > tn && ISSPACE(p[-1])) {
17938 --p;
17939 *valLen -= 1;
17940 }
17941 }
17942 }
17943 goto checkLen;
17944 }
17945 case SQL_DESC_OCTET_LENGTH:
17946 v = c->size;
17947#ifdef WINTERFACE
17948 if (c->type == SQL_WCHAR ||
17949 c->type == SQL_WVARCHAR ||
17950 c->type == SQL_WLONGVARCHAR) {
17951 if (!(s->nowchar[0] || s->nowchar[1])) {
17952 v *= sizeof (SQLWCHAR);
17953 }
17954 }
17955#endif
17956 break;
17957#if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17958 case SQL_COLUMN_TABLE_NAME:
17959#endif
17960#ifdef SQL_DESC_BASE_TABLE_NAME
17961 case SQL_DESC_BASE_TABLE_NAME:
17962#endif
17963 case SQL_DESC_TABLE_NAME:
17964 if (valc && valMax > 0) {
17965 strncpy(valc, c->table, valMax);
17966 valc[valMax - 1] = '\0';
17967 }
17968 *valLen = strlen(c->table);
17969 goto checkLen;
17970 case SQL_DESC_TYPE:
17971 v = c->type;
17972#ifdef WINTERFACE
17973 if (s->nowchar[0] || s->nowchar[1]) {
17974 switch (v) {
17975 case SQL_WCHAR:
17976 v = SQL_CHAR;
17977 break;
17978 case SQL_WVARCHAR:
17979 v = SQL_VARCHAR;
17980 break;
17981#ifdef SQL_LONGVARCHAR
17982 case SQL_WLONGVARCHAR:
17983 v = SQL_LONGVARCHAR;
17984 break;
17985#endif
17986 }
17987 }
17988#endif
17989 break;
17990 case SQL_DESC_CONCISE_TYPE:
17991 switch (c->type) {
17992 case SQL_INTEGER:
17993 v = SQL_C_LONG;
17994 break;
17995 case SQL_TINYINT:
17996 v = SQL_C_TINYINT;
17997 break;
17998 case SQL_SMALLINT:
17999 v = SQL_C_SHORT;
18000 break;
18001 case SQL_FLOAT:
18002 v = SQL_C_FLOAT;
18003 break;
18004 case SQL_DOUBLE:
18005 v = SQL_C_DOUBLE;
18006 break;
18007 case SQL_TIMESTAMP:
18008 v = SQL_C_TIMESTAMP;
18009 break;
18010 case SQL_TIME:
18011 v = SQL_C_TIME;
18012 break;
18013 case SQL_DATE:
18014 v = SQL_C_DATE;
18015 break;
18016#ifdef SQL_C_TYPE_TIMESTAMP
18017 case SQL_TYPE_TIMESTAMP:
18018 v = SQL_C_TYPE_TIMESTAMP;
18019 break;
18020#endif
18021#ifdef SQL_C_TYPE_TIME
18022 case SQL_TYPE_TIME:
18023 v = SQL_C_TYPE_TIME;
18024 break;
18025#endif
18026#ifdef SQL_C_TYPE_DATE
18027 case SQL_TYPE_DATE:
18028 v = SQL_C_TYPE_DATE;
18029 break;
18030#endif
18031#ifdef SQL_BIT
18032 case SQL_BIT:
18033 v = SQL_C_BIT;
18034 break;
18035#endif
18036#ifdef SQL_BIGINT
18037 case SQL_BIGINT:
18038 v = SQL_C_SBIGINT;
18039 break;
18040#endif
18041 default:
18042#ifdef WINTERFACE
18043 v = (s->nowchar[0] || s->nowchar[1]) ? SQL_C_CHAR : SQL_C_WCHAR;
18044#else
18045 v = SQL_C_CHAR;
18046#endif
18047 break;
18048 }
18049 break;
18050 case SQL_DESC_UPDATABLE:
18051 v = SQL_TRUE;
18052 break;
18053 case SQL_COLUMN_DISPLAY_SIZE:
18054 v = c->size;
18055 break;
18056 case SQL_COLUMN_UNSIGNED:
18057 v = c->nosign ? SQL_TRUE : SQL_FALSE;
18058 break;
18059 case SQL_COLUMN_SEARCHABLE:
18060 v = SQL_SEARCHABLE;
18061 break;
18062 case SQL_COLUMN_SCALE:
18063 case SQL_DESC_SCALE:
18064 v = c->scale;
18065 break;
18066 case SQL_COLUMN_PRECISION:
18067 case SQL_DESC_PRECISION:
18068 switch (c->type) {
18069 case SQL_SMALLINT:
18070 v = 5;
18071 break;
18072 case SQL_INTEGER:
18073 v = 10;
18074 break;
18075 case SQL_FLOAT:
18076 case SQL_REAL:
18077 case SQL_DOUBLE:
18078 v = 15;
18079 break;
18080 case SQL_DATE:
18081 v = 0;
18082 break;
18083 case SQL_TIME:
18084 v = 0;
18085 break;
18086#ifdef SQL_TYPE_TIMESTAMP
18087 case SQL_TYPE_TIMESTAMP:
18088#endif
18089 case SQL_TIMESTAMP:
18090 v = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
18091 break;
18092 default:
18093 v = c->prec;
18094 break;
18095 }
18096 break;
18097 case SQL_COLUMN_MONEY:
18098 v = SQL_FALSE;
18099 break;
18100 case SQL_COLUMN_AUTO_INCREMENT:
18101 v = c->autoinc;
18102 break;
18103 case SQL_DESC_NULLABLE:
18104 v = c->notnull;
18105 break;
18106#ifdef SQL_DESC_NUM_PREC_RADIX
18107 case SQL_DESC_NUM_PREC_RADIX:
18108 switch (c->type) {
18109#ifdef WINTERFACE
18110 case SQL_WCHAR:
18111 case SQL_WVARCHAR:
18112#ifdef SQL_LONGVARCHAR
18113 case SQL_WLONGVARCHAR:
18114#endif
18115#endif
18116 case SQL_CHAR:
18117 case SQL_VARCHAR:
18118#ifdef SQL_LONGVARCHAR
18119 case SQL_LONGVARCHAR:
18120#endif
18121 case SQL_BINARY:
18122 case SQL_VARBINARY:
18123 case SQL_LONGVARBINARY:
18124 v = 0;
18125 break;
18126 default:
18127 v = 2;
18128 }
18129 break;
18130#endif
18131 default:
18132 setstat(s, -1, "unsupported column attribute %d", "HY091", id);
18133 return SQL_ERROR;
18134 }
18135 if (val2) {
18136 *(SQLLEN *) val2 = v;
18137 }
18138 return SQL_SUCCESS;
18139}
18140
18141#ifndef WINTERFACE
18154SQLRETURN SQL_API
18155SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
18156 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
18158{
18159#if defined(_WIN32) || defined(_WIN64)
18160 SQLSMALLINT len = 0;
18161#endif
18162 SQLRETURN ret;
18163
18165#if defined(_WIN32) || defined(_WIN64)
18166 if (!((STMT *) stmt)->oemcp[0]) {
18167 ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
18168 (SQLPOINTER) val2);
18169 goto done;
18170 }
18171 ret = drvcolattribute(stmt, col, id, val, valMax, &len,
18172 (SQLPOINTER) val2);
18173 if (SQL_SUCCEEDED(ret)) {
18174 char *v = NULL;
18175
18176 switch (id) {
18177 case SQL_DESC_SCHEMA_NAME:
18178 case SQL_DESC_CATALOG_NAME:
18179 case SQL_COLUMN_LABEL:
18180 case SQL_DESC_NAME:
18181 case SQL_DESC_TABLE_NAME:
18182#ifdef SQL_DESC_BASE_TABLE_NAME
18183 case SQL_DESC_BASE_TABLE_NAME:
18184#endif
18185#ifdef SQL_DESC_BASE_COLUMN_NAME
18186 case SQL_DESC_BASE_COLUMN_NAME:
18187#endif
18188 case SQL_DESC_TYPE_NAME:
18189 if (val && valMax > 0) {
18190 int vmax = valMax;
18191
18192 v = utf_to_wmb((char *) val, SQL_NTS);
18193 if (v) {
18194 strncpy(val, v, vmax);
18195 len = min(vmax, strlen(v));
18196 uc_free(v);
18197 }
18198 if (vmax > 0) {
18199 v = (char *) val;
18200 v[vmax - 1] = '\0';
18201 }
18202 }
18203 if (len <= 0) {
18204 len = 0;
18205 }
18206 break;
18207 }
18208 if (valLen) {
18209 *valLen = len;
18210 }
18211 }
18212done:
18213 ;
18214#else
18215 ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
18216 (SQLPOINTER) val2);
18217#endif
18219 return ret;
18220}
18221#endif
18222
18223#ifdef WINTERFACE
18236SQLRETURN SQL_API
18237SQLColAttributeW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
18238 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
18240{
18241 SQLRETURN ret;
18242 SQLSMALLINT len = 0;
18243
18245 ret = drvcolattribute(stmt, col, id, val, valMax, &len,
18246 (SQLPOINTER) val2);
18247 if (SQL_SUCCEEDED(ret)) {
18248 SQLWCHAR *v = NULL;
18249
18250 switch (id) {
18251 case SQL_DESC_SCHEMA_NAME:
18252 case SQL_DESC_CATALOG_NAME:
18253 case SQL_COLUMN_LABEL:
18254 case SQL_DESC_NAME:
18255 case SQL_DESC_TABLE_NAME:
18256#ifdef SQL_DESC_BASE_TABLE_NAME
18257 case SQL_DESC_BASE_TABLE_NAME:
18258#endif
18259#ifdef SQL_DESC_BASE_COLUMN_NAME
18260 case SQL_DESC_BASE_COLUMN_NAME:
18261#endif
18262 case SQL_DESC_TYPE_NAME:
18263 if (val && valMax > 0) {
18264 int vmax = valMax / sizeof (SQLWCHAR);
18265
18266 v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
18267 if (v) {
18268 uc_strncpy(val, v, vmax);
18269 len = min(vmax, uc_strlen(v));
18270 uc_free(v);
18271 len *= sizeof (SQLWCHAR);
18272 }
18273 if (vmax > 0) {
18274 v = (SQLWCHAR *) val;
18275 v[vmax - 1] = '\0';
18276 }
18277 }
18278 if (len <= 0) {
18279 len = 0;
18280 }
18281 break;
18282 }
18283 if (valLen) {
18284 *valLen = len;
18285 }
18286 }
18288 return ret;
18289}
18290#endif
18291
18305static SQLRETURN
18306drverror(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18307 SQLCHAR *sqlState, SQLINTEGER *nativeErr,
18308 SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18309{
18310 SQLCHAR dummy0[6];
18311 SQLINTEGER dummy1;
18312 SQLSMALLINT dummy2;
18313
18314 if (env == SQL_NULL_HENV &&
18315 dbc == SQL_NULL_HDBC &&
18316 stmt == SQL_NULL_HSTMT) {
18317 return SQL_INVALID_HANDLE;
18318 }
18319 if (sqlState) {
18320 sqlState[0] = '\0';
18321 } else {
18322 sqlState = dummy0;
18323 }
18324 if (!nativeErr) {
18325 nativeErr = &dummy1;
18326 }
18327 *nativeErr = 0;
18328 if (!errlen) {
18329 errlen = &dummy2;
18330 }
18331 *errlen = 0;
18332 if (errmsg) {
18333 if (errmax > 0) {
18334 errmsg[0] = '\0';
18335 }
18336 } else {
18337 errmsg = dummy0;
18338 errmax = 0;
18339 }
18340 if (stmt) {
18341 STMT *s = (STMT *) stmt;
18342
18344 if (s->logmsg[0] == '\0') {
18346 goto noerr;
18347 }
18348 *nativeErr = s->naterr;
18349 strcpy((char *) sqlState, s->sqlstate);
18350 if (errmax == SQL_NTS) {
18351 strcpy((char *) errmsg, "[SQLite]");
18352 strcat((char *) errmsg, (char *) s->logmsg);
18353 *errlen = strlen((char *) errmsg);
18354 } else {
18355 strncpy((char *) errmsg, "[SQLite]", errmax);
18356 if (errmax - 8 > 0) {
18357 strncpy((char *) errmsg + 8, (char *) s->logmsg, errmax - 8);
18358 }
18359 *errlen = min(strlen((char *) s->logmsg) + 8, errmax);
18360 }
18361 s->logmsg[0] = '\0';
18363 return SQL_SUCCESS;
18364 }
18365 if (dbc) {
18366 DBC *d = (DBC *) dbc;
18367
18368 HDBC_LOCK(dbc);
18369 if (d->magic != DBC_MAGIC || d->logmsg[0] == '\0') {
18371 goto noerr;
18372 }
18373 *nativeErr = d->naterr;
18374 strcpy((char *) sqlState, d->sqlstate);
18375 if (errmax == SQL_NTS) {
18376 strcpy((char *) errmsg, "[SQLite]");
18377 strcat((char *) errmsg, (char *) d->logmsg);
18378 *errlen = strlen((char *) errmsg);
18379 } else {
18380 strncpy((char *) errmsg, "[SQLite]", errmax);
18381 if (errmax - 8 > 0) {
18382 strncpy((char *) errmsg + 8, (char *) d->logmsg, errmax - 8);
18383 }
18384 *errlen = min(strlen((char *) d->logmsg) + 8, errmax);
18385 }
18386 d->logmsg[0] = '\0';
18388 return SQL_SUCCESS;
18389 }
18390noerr:
18391 sqlState[0] = '\0';
18392 errmsg[0] = '\0';
18393 *nativeErr = 0;
18394 *errlen = 0;
18395 return SQL_NO_DATA;
18396}
18397
18398#ifndef WINTERFACE
18412SQLRETURN SQL_API
18413SQLError(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18414 SQLCHAR *sqlState, SQLINTEGER *nativeErr,
18415 SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18416{
18417 return drverror(env, dbc, stmt, sqlState, nativeErr,
18418 errmsg, errmax, errlen);
18419}
18420#endif
18421
18422#ifdef WINTERFACE
18436SQLRETURN SQL_API
18437SQLErrorW(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18438 SQLWCHAR *sqlState, SQLINTEGER *nativeErr,
18439 SQLWCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18440{
18441 char state[16];
18442 SQLSMALLINT len = 0;
18443 SQLRETURN ret;
18444
18445 ret = drverror(env, dbc, stmt, (SQLCHAR *) state, nativeErr,
18446 (SQLCHAR *) errmsg, errmax, &len);
18447 if (ret == SQL_SUCCESS) {
18448 if (sqlState) {
18449 uc_from_utf_buf((SQLCHAR *) state, -1, sqlState,
18450 6 * sizeof (SQLWCHAR));
18451 }
18452 if (errmsg) {
18453 if (len > 0) {
18454 SQLWCHAR *e = NULL;
18455
18456 e = uc_from_utf((SQLCHAR *) errmsg, len);
18457 if (e) {
18458 if (errmax > 0) {
18459 uc_strncpy(errmsg, e, errmax);
18460 e[len] = 0;
18461 len = min(errmax, uc_strlen(e));
18462 } else {
18463 len = uc_strlen(e);
18464 }
18465 uc_free(e);
18466 } else {
18467 len = 0;
18468 }
18469 }
18470 if (len <= 0) {
18471 len = 0;
18472 if (errmax > 0) {
18473 errmsg[0] = 0;
18474 }
18475 }
18476 } else {
18477 len = 0;
18478 }
18479 if (errlen) {
18480 *errlen = len;
18481 }
18482 } else if (ret == SQL_NO_DATA) {
18483 if (sqlState) {
18484 sqlState[0] = 0;
18485 }
18486 if (errmsg) {
18487 if (errmax > 0) {
18488 errmsg[0] = 0;
18489 }
18490 }
18491 if (errlen) {
18492 *errlen = 0;
18493 }
18494 }
18495 return ret;
18496}
18497#endif
18498
18505SQLRETURN SQL_API
18506SQLMoreResults(SQLHSTMT stmt)
18507{
18509 if (stmt == SQL_NULL_HSTMT) {
18510 return SQL_INVALID_HANDLE;
18511 }
18513 return SQL_NO_DATA;
18514}
18515
18524static SQLRETURN
18525setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp)
18526{
18527 int ncols = *ncolsp, guessed_types = 0;
18528 SQLRETURN ret = SQL_SUCCESS;
18529
18530 if (ncols > 0) {
18531 int i;
18532 PTRDIFF_T size;
18533 char *p;
18534 COL *dyncols;
18535 DBC *d = (DBC *) s->dbc;
18536 const char *colname, *typename;
18537#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18538 char *tblname;
18539#endif
18540#if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18541 char *dbname;
18542#endif
18543
18544 for (i = size = 0; i < ncols; i++) {
18545 colname = sqlite3_column_name(s3stmt, i);
18546 size += 3 + 3 * strlen(colname);
18547 }
18548#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18549 tblname = (char *) size;
18550 for (i = 0; i < ncols; i++) {
18551 p = (char *) sqlite3_column_table_name(s3stmt, i);
18552 size += 2 + (p ? strlen(p) : 0);
18553 }
18554#endif
18555#if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18556 dbname = (char *) size;
18557 for (i = 0; i < ncols; i++) {
18558 p = (char *) sqlite3_column_database_name(s3stmt, i);
18559 size += 2 + (p ? strlen(p) : 0);
18560 }
18561#endif
18562 dyncols = xmalloc(ncols * sizeof (COL) + size);
18563 if (!dyncols) {
18564 freedyncols(s);
18565 *ncolsp = 0;
18566 ret = SQL_ERROR;
18567 } else {
18568 p = (char *) (dyncols + ncols);
18569#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18570 tblname = p + (PTRDIFF_T) tblname;
18571#endif
18572#if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18573 dbname = p + (PTRDIFF_T) dbname;
18574#endif
18575 for (i = 0; i < ncols; i++) {
18576 char *q;
18577
18578 colname = sqlite3_column_name(s3stmt, i);
18579 if (d->trace) {
18580 fprintf(d->trace, "-- column %d name: '%s'\n",
18581 i + 1, colname);
18582 fflush(d->trace);
18583 }
18584#if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18585 q = (char *) sqlite3_column_table_name(s3stmt, i);
18586 strcpy(tblname, q ? q : "");
18587 if (d->trace) {
18588 fprintf(d->trace, "-- table %d name: '%s'\n",
18589 i + 1, tblname);
18590 fflush(d->trace);
18591 }
18592 dyncols[i].table = tblname;
18593 tblname += strlen(tblname) + 1;
18594#endif
18595#if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18596 q = (char *) sqlite3_column_database_name(s3stmt, i);
18597 strcpy(dbname, q ? q : "");
18598 if (d->trace) {
18599 fprintf(d->trace, "-- database %d name: '%s'\n",
18600 i + 1, dbname);
18601 fflush(d->trace);
18602 }
18603 dyncols[i].db = dbname;
18604 dbname += strlen(dbname) + 1;
18605#else
18606 dyncols[i].db = ((DBC *) (s->dbc))->dbname;
18607#endif
18608 typename = s3stmt_coltype(s3stmt, i, d, &guessed_types);
18609 strcpy(p, colname);
18610 dyncols[i].label = p;
18611 p += strlen(p) + 1;
18612 q = strchr(colname, '.');
18613 if (q) {
18614 char *q2 = strchr(q + 1, '.');
18615
18616 /* SQLite 3.3.4 produces view.table.column sometimes */
18617 if (q2) {
18618 q = q2;
18619 }
18620 }
18621 if (q) {
18622#if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18623 dyncols[i].table = p;
18624#endif
18625 strncpy(p, colname, q - colname);
18626 p[q - colname] = '\0';
18627 p += strlen(p) + 1;
18628 strcpy(p, q + 1);
18629 dyncols[i].column = p;
18630 p += strlen(p) + 1;
18631 } else {
18632#if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18633 dyncols[i].table = "";
18634#endif
18635 strcpy(p, colname);
18636 dyncols[i].column = p;
18637 p += strlen(p) + 1;
18638 }
18639 if (s->longnames) {
18640 dyncols[i].column = dyncols[i].label;
18641 }
18642#ifdef SQL_LONGVARCHAR
18643 dyncols[i].type = SQL_LONGVARCHAR;
18644 dyncols[i].size = 65535;
18645#else
18646 dyncols[i].type = SQL_VARCHAR;
18647 dyncols[i].size = 255;
18648#endif
18649 dyncols[i].index = i;
18650 dyncols[i].scale = 0;
18651 dyncols[i].prec = 0;
18652 dyncols[i].nosign = 1;
18653 dyncols[i].autoinc = SQL_FALSE;
18654 dyncols[i].notnull = SQL_NULLABLE;
18655 dyncols[i].ispk = -1;
18656 dyncols[i].isrowid = -1;
18657#ifdef FULL_METADATA
18658 s3stmt_addmeta(s3stmt, i, d, &dyncols[i]);
18659#endif
18660 dyncols[i].typename = xstrdup(typename);
18661 }
18662 freedyncols(s);
18663 s->dyncols = s->cols = dyncols;
18664 s->dcols = ncols;
18665 fixupdyncols(s, d);
18666 s->guessed_types = guessed_types;
18667 }
18668 }
18669 return ret;
18670}
18671
18680static SQLRETURN
18681drvprepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18682{
18683 STMT *s;
18684 DBC *d;
18685 char *errp = NULL;
18686 SQLRETURN sret;
18687
18688 if (stmt == SQL_NULL_HSTMT) {
18689 return SQL_INVALID_HANDLE;
18690 }
18691 s = (STMT *) stmt;
18692 if (s->dbc == SQL_NULL_HDBC) {
18693noconn:
18694 return noconn(s);
18695 }
18696 d = s->dbc;
18697 if (!d->sqlite) {
18698 goto noconn;
18699 }
18700 s3stmt_end(s);
18701 s3stmt_drop(s);
18702 sret = starttran(s);
18703 if (sret != SQL_SUCCESS) {
18704 return sret;
18705 }
18706 freep(&s->query);
18707 s->query = (SQLCHAR *) fixupsql((char *) query, queryLen,
18708 (d->version >= 0x030805),
18709 &s->nparams, &s->isselect, &errp);
18710 if (!s->query) {
18711 if (errp) {
18712 setstat(s, -1, "%s", (*s->ov3) ? "HY000" : "S1000", errp);
18713 return SQL_ERROR;
18714 }
18715 return nomem(s);
18716 }
18717 if (*s->ilike) {
18718 replilike((char *) s->query);
18719 }
18720 errp = NULL;
18721 freeresult(s, -1);
18722 if (s->isselect == 1) {
18723 int ret, ncols, nretry = 0;
18724 const char *rest;
18725 sqlite3_stmt *s3stmt = NULL;
18726
18727#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18728 dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
18729#else
18730 dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
18731#endif
18732 do {
18733 s3stmt = NULL;
18734#if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18735 ret = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
18736 &s3stmt, &rest);
18737#else
18738 ret = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
18739 &s3stmt, &rest);
18740#endif
18741 if (ret != SQLITE_OK) {
18742 if (s3stmt) {
18743 sqlite3_finalize(s3stmt);
18744 s3stmt = NULL;
18745 }
18746 }
18747 } while (ret == SQLITE_SCHEMA && (++nretry) < 2);
18748 dbtracerc(d, ret, NULL);
18749 if (ret != SQLITE_OK) {
18750 if (s3stmt) {
18751 dbtraceapi(d, "sqlite3_finalize", 0);
18752 sqlite3_finalize(s3stmt);
18753 }
18754 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18755 sqlite3_errmsg(d->sqlite), ret);
18756 return SQL_ERROR;
18757 }
18758 if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
18759 dbtraceapi(d, "sqlite3_finalize", 0);
18760 sqlite3_finalize(s3stmt);
18761 setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
18762 (*s->ov3) ? "HY000" : "S1000");
18763 return SQL_ERROR;
18764 }
18765 ncols = sqlite3_column_count(s3stmt);
18766 s->guessed_types = 0;
18767 setupdyncols(s, s3stmt, &ncols);
18768 s->ncols = ncols;
18769 s->s3stmt = s3stmt;
18770 } else {
18771 s->guessed_types = 1;
18772 }
18773 mkbindcols(s, s->ncols);
18774 s->paramset_count = 0;
18775 return SQL_SUCCESS;
18776}
18777
18785static SQLRETURN
18786drvexecute(SQLHSTMT stmt, int initial)
18787{
18788 STMT *s;
18789 DBC *d;
18790 char *errp = NULL;
18791 int rc, i, ncols = 0, nrows = 0, busy_count;
18792 SQLRETURN ret;
18793
18794 if (stmt == SQL_NULL_HSTMT) {
18795 return SQL_INVALID_HANDLE;
18796 }
18797 s = (STMT *) stmt;
18798 if (s->dbc == SQL_NULL_HDBC) {
18799noconn:
18800 return noconn(s);
18801 }
18802 d = (DBC *) s->dbc;
18803 if (!d->sqlite) {
18804 goto noconn;
18805 }
18806 if (!s->query) {
18807 setstat(s, -1, "no query prepared", (*s->ov3) ? "HY000" : "S1000");
18808 return SQL_ERROR;
18809 }
18810 if (s->nbindparms < s->nparams) {
18811unbound:
18812 setstat(s, -1, "unbound parameters in query",
18813 (*s->ov3) ? "HY000" : "S1000");
18814 return SQL_ERROR;
18815 }
18816 for (i = 0; i < s->nparams; i++) {
18817 BINDPARM *p = &s->bindparms[i];
18818
18819 if (!p->bound) {
18820 goto unbound;
18821 }
18822 if (initial) {
18823 SQLLEN *lenp = p->lenp;
18824
18825 if (lenp && *lenp < 0 && *lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18826 *lenp != SQL_NTS && *lenp != SQL_NULL_DATA &&
18827 *lenp != SQL_DATA_AT_EXEC) {
18828 setstat(s, -1, "invalid length reference", "HY009");
18829 return SQL_ERROR;
18830 }
18831 if (lenp && (*lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18832 *lenp == SQL_DATA_AT_EXEC)) {
18833 p->need = 1;
18834 p->offs = 0;
18835 p->len = 0;
18836 }
18837 }
18838 }
18839 ret = starttran(s);
18840 if (ret != SQL_SUCCESS) {
18841 goto cleanup;
18842 }
18843 busy_count = 0;
18844again:
18845 s3stmt_end(s);
18846 if (initial) {
18847 /* fixup data-at-execution parameters and alloc'ed blobs */
18848 s->pdcount = -1;
18849 for (i = 0; i < s->nparams; i++) {
18850 BINDPARM *p = &s->bindparms[i];
18851
18852 if (p->param == p->parbuf) {
18853 p->param = NULL;
18854 }
18855 freep(&p->parbuf);
18856 if (p->need <= 0 &&
18857 p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18858 *p->lenp == SQL_DATA_AT_EXEC)) {
18859 p->need = 1;
18860 p->offs = 0;
18861 p->len = 0;
18862 }
18863 }
18864 }
18865 if (s->nparams) {
18866 for (i = 0; i < s->nparams; i++) {
18867 ret = setupparam(s, (char *) s->query, i);
18868 if (ret != SQL_SUCCESS) {
18869 goto cleanup;
18870 }
18871 }
18872 }
18873 freeresult(s, 0);
18874 if (s->isselect == 1 && !d->intrans &&
18875 s->curtype == SQL_CURSOR_FORWARD_ONLY &&
18876 d->step_enable && s->nparams == 0 && d->cur_s3stmt == NULL) {
18877 s->nrows = -1;
18878 ret = s3stmt_start(s);
18879 if (ret == SQL_SUCCESS) {
18880 goto done2;
18881 }
18882 }
18883 rc = drvgettable(s, s->s3stmt ? NULL : (char *) s->query, &s->rows,
18884 &s->nrows, &ncols, &errp, s->nparams, s->bindparms);
18885 dbtracerc(d, rc, errp);
18886 if (rc == SQLITE_BUSY) {
18887 if (busy_handler((void *) d, ++busy_count)) {
18888 if (errp) {
18889 sqlite3_free(errp);
18890 errp = NULL;
18891 }
18892 for (i = 0; i < s->nparams; i++) {
18893 BINDPARM *p = &s->bindparms[i];
18894
18895 if (p->param == p->parbuf) {
18896 p->param = NULL;
18897 }
18898 freep(&p->parbuf);
18899 if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18900 *p->lenp != SQL_DATA_AT_EXEC)) {
18901 p->param = p->param0;
18902 }
18903 p->lenp = p->lenp0;
18904 }
18905 s->nrows = 0;
18906 goto again;
18907 }
18908 }
18909 if (rc != SQLITE_OK) {
18910 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18911 errp ? errp : "unknown error", rc);
18912 if (errp) {
18913 sqlite3_free(errp);
18914 errp = NULL;
18915 }
18916 ret = SQL_ERROR;
18917 goto cleanup;
18918 }
18919 if (errp) {
18920 sqlite3_free(errp);
18921 errp = NULL;
18922 }
18923 s->rowfree = freerows;
18924 if (s->isselect <= 0 || s->isselect > 1) {
18925 /*
18926 * DDL results are immediately released.
18927 * INSERT/UPDATE/DELETE depends on number of columns in
18928 * result set, if zero, result is immediately released.
18929 */
18930 if (s->isselect != 0 || ncols == 0) {
18931 freeresult(s, -1);
18932 nrows += sqlite3_changes(d->sqlite);
18933 s->nrows = nrows;
18934 } else {
18935 s->ncols = ncols;
18936 }
18937 goto done;
18938 }
18939 if (s->ncols != ncols) {
18940 /*
18941 * Weird result.
18942 */
18943 setstat(s, -1, "broken result set %d/%d",
18944 (*s->ov3) ? "HY000" : "S1000", s->ncols, ncols);
18945 ret = SQL_ERROR;
18946 goto cleanup;
18947 }
18948done:
18949 mkbindcols(s, s->ncols);
18950done2:
18951 ret = SQL_SUCCESS;
18952 s->rowp = s->rowprs = -1;
18953 s->paramset_count++;
18954 s->paramset_nrows = s->nrows;
18955 if (s->paramset_count < s->paramset_size) {
18956 for (i = 0; i < s->nparams; i++) {
18957 BINDPARM *p = &s->bindparms[i];
18958
18959 if (p->param == p->parbuf) {
18960 p->param = NULL;
18961 }
18962 freep(&p->parbuf);
18963 if (p->lenp0 &&
18964 s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18965 p->lenp = (SQLLEN *) ((char *) p->lenp0 +
18967 } else if (p->lenp0 && p->inc > 0) {
18968 p->lenp = p->lenp0 + s->paramset_count;
18969 }
18970 if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18971 *p->lenp != SQL_DATA_AT_EXEC)) {
18972 if (p->param0 &&
18973 s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18974 p->param = (char *) p->param0 +
18976 } else if (p->param0 && p->inc > 0) {
18977 p->param = (char *) p->param0 +
18978 s->paramset_count * p->inc;
18979 }
18980 } else if (p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18981 *p->lenp == SQL_DATA_AT_EXEC)) {
18982 p->need = 1;
18983 p->offs = 0;
18984 p->len = 0;
18985 }
18986 }
18987 goto again;
18988 }
18989cleanup:
18990 if (ret != SQL_NEED_DATA) {
18991 for (i = 0; i < s->nparams; i++) {
18992 BINDPARM *p = &s->bindparms[i];
18993
18994 if (p->param == p->parbuf) {
18995 p->param = NULL;
18996 }
18997 freep(&p->parbuf);
18998 if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18999 *p->lenp != SQL_DATA_AT_EXEC)) {
19000 p->param = p->param0;
19001 }
19002 p->lenp = p->lenp0;
19003 }
19004 s->nrows = s->paramset_nrows;
19005 if (s->parm_proc) {
19006 *s->parm_proc = s->paramset_count;
19007 }
19008 s->paramset_count = 0;
19009 s->paramset_nrows = 0;
19010 }
19011 /*
19012 * For INSERT/UPDATE/DELETE statements change the return code
19013 * to SQL_NO_DATA if the number of rows affected was 0.
19014 */
19015 if (*s->ov3 && s->isselect == 0 &&
19016 ret == SQL_SUCCESS && nrows == 0) {
19017 ret = SQL_NO_DATA;
19018 }
19019 return ret;
19020}
19021
19022#ifndef WINTERFACE
19031SQLRETURN SQL_API
19032SQLPrepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
19033{
19034 SQLRETURN ret;
19035#if defined(_WIN32) || defined(_WIN64)
19036 char *q;
19037#endif
19038
19040#if defined(_WIN32) || defined(_WIN64)
19041 if (!((STMT *) stmt)->oemcp[0]) {
19042 ret = drvprepare(stmt, query, queryLen);
19043 goto done;
19044 }
19045 q = wmb_to_utf_c((char *) query, queryLen);
19046 if (!q) {
19047 ret = nomem((STMT *) stmt);
19048 goto done;
19049 }
19050 query = (SQLCHAR *) q;
19051 queryLen = SQL_NTS;
19052#endif
19053 ret = drvprepare(stmt, query, queryLen);
19054#if defined(_WIN32) || defined(_WIN64)
19055 uc_free(q);
19056done:
19057 ;
19058#endif
19060 return ret;
19061}
19062#endif
19063
19064#ifdef WINTERFACE
19073SQLRETURN SQL_API
19074SQLPrepareW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
19075{
19076 SQLRETURN ret;
19077 char *q = uc_to_utf_c(query, queryLen);
19078
19080 if (!q) {
19081 ret = nomem((STMT *) stmt);
19082 goto done;
19083 }
19084 ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
19085 uc_free(q);
19086done:
19088 return ret;
19089}
19090#endif
19091
19098SQLRETURN SQL_API
19099SQLExecute(SQLHSTMT stmt)
19100{
19101 SQLRETURN ret;
19102
19104 ret = drvexecute(stmt, 1);
19106 return ret;
19107}
19108
19109#ifndef WINTERFACE
19118SQLRETURN SQL_API
19119SQLExecDirect(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
19120{
19121 SQLRETURN ret;
19122#if defined(_WIN32) || defined(_WIN64)
19123 char *q;
19124#endif
19125
19127#if defined(_WIN32) || defined(_WIN64)
19128 if (!((STMT *) stmt)->oemcp[0]) {
19129 ret = drvprepare(stmt, query, queryLen);
19130 if (ret == SQL_SUCCESS) {
19131 ret = drvexecute(stmt, 1);
19132 }
19133 goto done;
19134 }
19135 q = wmb_to_utf_c((char *) query, queryLen);
19136 if (!q) {
19137 ret = nomem((STMT *) stmt);
19138 goto done;
19139 }
19140 query = (SQLCHAR *) q;
19141 queryLen = SQL_NTS;
19142#endif
19143 ret = drvprepare(stmt, query, queryLen);
19144 if (ret == SQL_SUCCESS) {
19145 ret = drvexecute(stmt, 1);
19146 }
19147#if defined(_WIN32) || defined(_WIN64)
19148 uc_free(q);
19149done:
19150 ;
19151#endif
19153 return ret;
19154}
19155#endif
19156
19157#ifdef WINTERFACE
19166SQLRETURN SQL_API
19167SQLExecDirectW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
19168{
19169 SQLRETURN ret;
19170 char *q = uc_to_utf_c(query, queryLen);
19171
19173 if (!q) {
19174 ret = nomem((STMT *) stmt);
19175 goto done;
19176 }
19177 ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
19178 uc_free(q);
19179 if (ret == SQL_SUCCESS) {
19180 ret = drvexecute(stmt, 1);
19181 }
19182done:
19184 return ret;
19185}
19186#endif
19187
19188
19189#if defined(_WIN32) || defined(_WIN64)
19190#ifndef WITHOUT_DRIVERMGR
19191
19192/*
19193 * Windows configuration dialog stuff.
19194 */
19195
19196#include <windowsx.h>
19197#include <winuser.h>
19198
19199#define MAXPATHLEN (259+1) /* Max path length */
19200#define MAXKEYLEN (15+1) /* Max keyword length */
19201#define MAXDESC (255+1) /* Max description length */
19202#define MAXDSNAME (255+1) /* Max data source name length */
19203#define MAXTONAME (32+1) /* Max timeout length */
19204#define MAXDBNAME MAXPATHLEN
19205
19206/* Attribute key indexes into an array of Attr structs, see below */
19207
19208#define KEY_DSN 0
19209#define KEY_DESC 1
19210#define KEY_DBNAME 2
19211#define KEY_BUSY 3
19212#define KEY_DRIVER 4
19213#define KEY_STEPAPI 5
19214#define KEY_SYNCP 6
19215#define KEY_NOTXN 7
19216#define KEY_SHORTNAM 8
19217#define KEY_LONGNAM 9
19218#define KEY_NOCREAT 10
19219#define KEY_NOWCHAR 11
19220#define KEY_LOADEXT 12
19221#define KEY_JMODE 13
19222#define KEY_FKSUPPORT 14
19223#define KEY_OEMCP 15
19224#define KEY_BIGINT 16
19225#define KEY_PASSWD 17
19226#define KEY_JDCONV 18
19227#define KEY_ATTAS 19
19228#define KEY_ILIKE 20
19229#define NUMOFKEYS 21
19230
19231typedef struct {
19232 BOOL supplied;
19233 char attr[MAXPATHLEN*4];
19234} ATTR;
19235
19236typedef struct {
19237 SQLHWND parent;
19238 LPCSTR driver;
19239 ATTR attr[NUMOFKEYS];
19240 char DSN[MAXDSNAME];
19241 BOOL newDSN;
19242 BOOL defDSN;
19243} SETUPDLG;
19244
19245static struct {
19246 char *key;
19247 int ikey;
19248} attrLookup[] = {
19249 { "DSN", KEY_DSN },
19250 { "DESC", KEY_DESC },
19251 { "Description", KEY_DESC},
19252 { "Database", KEY_DBNAME },
19253 { "Timeout", KEY_BUSY },
19254 { "Driver", KEY_DRIVER },
19255 { "StepAPI", KEY_STEPAPI },
19256 { "SyncPragma", KEY_SYNCP },
19257 { "NoTXN", KEY_NOTXN },
19258 { "ShortNames", KEY_SHORTNAM },
19259 { "LongNames", KEY_LONGNAM },
19260 { "NoCreat", KEY_NOCREAT },
19261 { "NoWCHAR", KEY_NOWCHAR },
19262 { "LoadExt", KEY_LOADEXT },
19263 { "JournalMode", KEY_JMODE },
19264 { "FKSupport", KEY_FKSUPPORT },
19265 { "OEMCP", KEY_OEMCP },
19266 { "BigInt", KEY_BIGINT },
19267 { "PWD", KEY_PASSWD },
19268 { "JDConv", KEY_JDCONV },
19269 { "AttachAs", KEY_ATTAS },
19270 { "ILike", KEY_ILIKE },
19271 { NULL, 0 }
19272};
19273
19280static void
19281ParseAttributes(LPCSTR attribs, SETUPDLG *setupdlg)
19282{
19283 char *str = (char *) attribs, *start, key[MAXKEYLEN];
19284 int elem, nkey;
19285
19286 while (*str) {
19287 start = str;
19288 if ((str = strchr(str, '=')) == NULL) {
19289 return;
19290 }
19291 elem = -1;
19292 nkey = str - start;
19293 if (nkey < sizeof (key)) {
19294 int i;
19295
19296 memcpy(key, start, nkey);
19297 key[nkey] = '\0';
19298 for (i = 0; attrLookup[i].key; i++) {
19299 if (strcasecmp(attrLookup[i].key, key) == 0) {
19300 elem = attrLookup[i].ikey;
19301 break;
19302 }
19303 }
19304 }
19305 start = ++str;
19306 while (*str && *str != ';') {
19307 ++str;
19308 }
19309 if (elem >= 0) {
19310 int end = min(str - start, sizeof (setupdlg->attr[elem].attr) - 1);
19311
19312 setupdlg->attr[elem].supplied = TRUE;
19313 memcpy(setupdlg->attr[elem].attr, start, end);
19314 setupdlg->attr[elem].attr[end] = '\0';
19315 }
19316 ++str;
19317 }
19318}
19319
19327static BOOL
19328SetDSNAttributes(HWND parent, SETUPDLG *setupdlg)
19329{
19330 char *dsn = setupdlg->attr[KEY_DSN].attr;
19331
19332 if (setupdlg->newDSN && strlen(dsn) == 0) {
19333 return FALSE;
19334 }
19335 if (!SQLWriteDSNToIni(dsn, setupdlg->driver)) {
19336 if (parent) {
19337 char buf[MAXPATHLEN], msg[MAXPATHLEN];
19338
19339 LoadString(hModule, IDS_BADDSN, buf, sizeof (buf));
19340 wsprintf(msg, buf, dsn);
19341 LoadString(hModule, IDS_MSGTITLE, buf, sizeof (buf));
19342 MessageBox(parent, msg, buf,
19343 MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
19344 MB_SETFOREGROUND);
19345 }
19346 return FALSE;
19347 }
19348 if (parent || setupdlg->attr[KEY_DESC].supplied) {
19349 SQLWritePrivateProfileString(dsn, "Description",
19350 setupdlg->attr[KEY_DESC].attr,
19351 ODBC_INI);
19352 }
19353 if (parent || setupdlg->attr[KEY_DBNAME].supplied) {
19354 SQLWritePrivateProfileString(dsn, "Database",
19355 setupdlg->attr[KEY_DBNAME].attr,
19356 ODBC_INI);
19357 }
19358 if (parent || setupdlg->attr[KEY_BUSY].supplied) {
19359 SQLWritePrivateProfileString(dsn, "Timeout",
19360 setupdlg->attr[KEY_BUSY].attr,
19361 ODBC_INI);
19362 }
19363 if (parent || setupdlg->attr[KEY_STEPAPI].supplied) {
19364 SQLWritePrivateProfileString(dsn, "StepAPI",
19365 setupdlg->attr[KEY_STEPAPI].attr,
19366 ODBC_INI);
19367 }
19368 if (parent || setupdlg->attr[KEY_SYNCP].supplied) {
19369 SQLWritePrivateProfileString(dsn, "SyncPragma",
19370 setupdlg->attr[KEY_SYNCP].attr,
19371 ODBC_INI);
19372 }
19373 if (parent || setupdlg->attr[KEY_NOTXN].supplied) {
19374 SQLWritePrivateProfileString(dsn, "NoTXN",
19375 setupdlg->attr[KEY_NOTXN].attr,
19376 ODBC_INI);
19377 }
19378 if (parent || setupdlg->attr[KEY_SHORTNAM].supplied) {
19379 SQLWritePrivateProfileString(dsn, "ShortNames",
19380 setupdlg->attr[KEY_SHORTNAM].attr,
19381 ODBC_INI);
19382 }
19383 if (parent || setupdlg->attr[KEY_LONGNAM].supplied) {
19384 SQLWritePrivateProfileString(dsn, "LongNames",
19385 setupdlg->attr[KEY_LONGNAM].attr,
19386 ODBC_INI);
19387 }
19388 if (parent || setupdlg->attr[KEY_NOCREAT].supplied) {
19389 SQLWritePrivateProfileString(dsn, "NoCreat",
19390 setupdlg->attr[KEY_NOCREAT].attr,
19391 ODBC_INI);
19392 }
19393 if (parent || setupdlg->attr[KEY_NOWCHAR].supplied) {
19394 SQLWritePrivateProfileString(dsn, "NoWCHAR",
19395 setupdlg->attr[KEY_NOWCHAR].attr,
19396 ODBC_INI);
19397 }
19398 if (parent || setupdlg->attr[KEY_FKSUPPORT].supplied) {
19399 SQLWritePrivateProfileString(dsn, "FKSupport",
19400 setupdlg->attr[KEY_FKSUPPORT].attr,
19401 ODBC_INI);
19402 }
19403 if (parent || setupdlg->attr[KEY_OEMCP].supplied) {
19404 SQLWritePrivateProfileString(dsn, "OEMCP",
19405 setupdlg->attr[KEY_OEMCP].attr,
19406 ODBC_INI);
19407 }
19408 if (parent || setupdlg->attr[KEY_LOADEXT].supplied) {
19409 SQLWritePrivateProfileString(dsn, "LoadExt",
19410 setupdlg->attr[KEY_LOADEXT].attr,
19411 ODBC_INI);
19412 }
19413 if (parent || setupdlg->attr[KEY_BIGINT].supplied) {
19414 SQLWritePrivateProfileString(dsn, "BigInt",
19415 setupdlg->attr[KEY_BIGINT].attr,
19416 ODBC_INI);
19417 }
19418 if (parent || setupdlg->attr[KEY_JDCONV].supplied) {
19419 SQLWritePrivateProfileString(dsn, "JDConv",
19420 setupdlg->attr[KEY_JDCONV].attr,
19421 ODBC_INI);
19422 }
19423 if (parent || setupdlg->attr[KEY_ATTAS].supplied) {
19424 SQLWritePrivateProfileString(dsn, "AttachAs",
19425 setupdlg->attr[KEY_ATTAS].attr,
19426 ODBC_INI);
19427 }
19428 if (parent || setupdlg->attr[KEY_ILIKE].supplied) {
19429 SQLWritePrivateProfileString(dsn, "ILike",
19430 setupdlg->attr[KEY_ILIKE].attr,
19431 ODBC_INI);
19432 }
19433 if (parent || setupdlg->attr[KEY_PASSWD].supplied) {
19434 SQLWritePrivateProfileString(dsn, "PWD",
19435 setupdlg->attr[KEY_PASSWD].attr,
19436 ODBC_INI);
19437 }
19438 if (setupdlg->attr[KEY_DSN].supplied &&
19439 strcasecmp(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr)) {
19440 SQLRemoveDSNFromIni(setupdlg->DSN);
19441 }
19442 return TRUE;
19443}
19444
19450static void
19451GetAttributes(SETUPDLG *setupdlg)
19452{
19453 char *dsn = setupdlg->attr[KEY_DSN].attr;
19454
19455 if (!setupdlg->attr[KEY_DESC].supplied) {
19456 SQLGetPrivateProfileString(dsn, "Description", "",
19457 setupdlg->attr[KEY_DESC].attr,
19458 sizeof (setupdlg->attr[KEY_DESC].attr),
19459 ODBC_INI);
19460 }
19461 if (!setupdlg->attr[KEY_DBNAME].supplied) {
19462 SQLGetPrivateProfileString(dsn, "Database", "",
19463 setupdlg->attr[KEY_DBNAME].attr,
19464 sizeof (setupdlg->attr[KEY_DBNAME].attr),
19465 ODBC_INI);
19466 }
19467 if (!setupdlg->attr[KEY_BUSY].supplied) {
19468 SQLGetPrivateProfileString(dsn, "Timeout", "100000",
19469 setupdlg->attr[KEY_BUSY].attr,
19470 sizeof (setupdlg->attr[KEY_BUSY].attr),
19471 ODBC_INI);
19472 }
19473 if (!setupdlg->attr[KEY_STEPAPI].supplied) {
19474 SQLGetPrivateProfileString(dsn, "StepAPI", "0",
19475 setupdlg->attr[KEY_STEPAPI].attr,
19476 sizeof (setupdlg->attr[KEY_STEPAPI].attr),
19477 ODBC_INI);
19478 }
19479 if (!setupdlg->attr[KEY_SYNCP].supplied) {
19480 SQLGetPrivateProfileString(dsn, "SyncPragma", "NORMAL",
19481 setupdlg->attr[KEY_SYNCP].attr,
19482 sizeof (setupdlg->attr[KEY_SYNCP].attr),
19483 ODBC_INI);
19484 }
19485 if (!setupdlg->attr[KEY_NOTXN].supplied) {
19486 SQLGetPrivateProfileString(dsn, "NoTXN", "",
19487 setupdlg->attr[KEY_NOTXN].attr,
19488 sizeof (setupdlg->attr[KEY_NOTXN].attr),
19489 ODBC_INI);
19490 }
19491 if (!setupdlg->attr[KEY_SHORTNAM].supplied) {
19492 SQLGetPrivateProfileString(dsn, "ShortNames", "",
19493 setupdlg->attr[KEY_SHORTNAM].attr,
19494 sizeof (setupdlg->attr[KEY_SHORTNAM].attr),
19495 ODBC_INI);
19496 }
19497 if (!setupdlg->attr[KEY_LONGNAM].supplied) {
19498 SQLGetPrivateProfileString(dsn, "LongNames", "",
19499 setupdlg->attr[KEY_LONGNAM].attr,
19500 sizeof (setupdlg->attr[KEY_LONGNAM].attr),
19501 ODBC_INI);
19502 }
19503 if (!setupdlg->attr[KEY_NOCREAT].supplied) {
19504 SQLGetPrivateProfileString(dsn, "NoCreat", "",
19505 setupdlg->attr[KEY_NOCREAT].attr,
19506 sizeof (setupdlg->attr[KEY_NOCREAT].attr),
19507 ODBC_INI);
19508 }
19509 if (!setupdlg->attr[KEY_NOWCHAR].supplied) {
19510 SQLGetPrivateProfileString(dsn, "NoWCHAR", "",
19511 setupdlg->attr[KEY_NOWCHAR].attr,
19512 sizeof (setupdlg->attr[KEY_NOWCHAR].attr),
19513 ODBC_INI);
19514 }
19515 if (!setupdlg->attr[KEY_FKSUPPORT].supplied) {
19516 SQLGetPrivateProfileString(dsn, "FKSupport", "",
19517 setupdlg->attr[KEY_FKSUPPORT].attr,
19518 sizeof (setupdlg->attr[KEY_FKSUPPORT].attr),
19519 ODBC_INI);
19520 }
19521 if (!setupdlg->attr[KEY_OEMCP].supplied) {
19522 SQLGetPrivateProfileString(dsn, "OEMCP", "",
19523 setupdlg->attr[KEY_OEMCP].attr,
19524 sizeof (setupdlg->attr[KEY_OEMCP].attr),
19525 ODBC_INI);
19526 }
19527 if (!setupdlg->attr[KEY_LOADEXT].supplied) {
19528 SQLGetPrivateProfileString(dsn, "LoadExt", "",
19529 setupdlg->attr[KEY_LOADEXT].attr,
19530 sizeof (setupdlg->attr[KEY_LOADEXT].attr),
19531 ODBC_INI);
19532 }
19533 if (!setupdlg->attr[KEY_JMODE].supplied) {
19534 SQLGetPrivateProfileString(dsn, "JournalMode", "",
19535 setupdlg->attr[KEY_JMODE].attr,
19536 sizeof (setupdlg->attr[KEY_JMODE].attr),
19537 ODBC_INI);
19538 }
19539 if (!setupdlg->attr[KEY_BIGINT].supplied) {
19540 SQLGetPrivateProfileString(dsn, "BigInt", "",
19541 setupdlg->attr[KEY_BIGINT].attr,
19542 sizeof (setupdlg->attr[KEY_BIGINT].attr),
19543 ODBC_INI);
19544 }
19545 if (!setupdlg->attr[KEY_PASSWD].supplied) {
19546 SQLGetPrivateProfileString(dsn, "PWD", "",
19547 setupdlg->attr[KEY_PASSWD].attr,
19548 sizeof (setupdlg->attr[KEY_PASSWD].attr),
19549 ODBC_INI);
19550 }
19551 if (!setupdlg->attr[KEY_JDCONV].supplied) {
19552 SQLGetPrivateProfileString(dsn, "JDConv", "",
19553 setupdlg->attr[KEY_JDCONV].attr,
19554 sizeof (setupdlg->attr[KEY_JDCONV].attr),
19555 ODBC_INI);
19556 }
19557 if (!setupdlg->attr[KEY_ATTAS].supplied) {
19558 SQLGetPrivateProfileString(dsn, "AttachAs", "",
19559 setupdlg->attr[KEY_ATTAS].attr,
19560 sizeof (setupdlg->attr[KEY_ATTAS].attr),
19561 ODBC_INI);
19562 }
19563 if (!setupdlg->attr[KEY_ILIKE].supplied) {
19564 SQLGetPrivateProfileString(dsn, "ILike", "",
19565 setupdlg->attr[KEY_ILIKE].attr,
19566 sizeof (setupdlg->attr[KEY_ILIKE].attr),
19567 ODBC_INI);
19568 }
19569}
19570
19576static void
19577GetDBFile(HWND hdlg)
19578{
19579#ifdef _WIN64
19580 SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19581#else
19582 SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19583#endif
19584 OPENFILENAME ofn;
19585
19586 memset(&ofn, 0, sizeof (ofn));
19587 ofn.lStructSize = sizeof (ofn);
19588 ofn.hwndOwner = hdlg;
19589#ifdef _WIN64
19590 ofn.hInstance = (HINSTANCE) GetWindowLongPtr(hdlg, GWLP_HINSTANCE);
19591#else
19592 ofn.hInstance = (HINSTANCE) GetWindowLong(hdlg, GWL_HINSTANCE);
19593#endif
19594 ofn.lpstrFile = (LPTSTR) setupdlg->attr[KEY_DBNAME].attr;
19595 ofn.nMaxFile = MAXPATHLEN;
19596 ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST |
19597 OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_FILEMUSTEXIST;
19598 if (GetOpenFileName(&ofn)) {
19599 SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19600 setupdlg->attr[KEY_DBNAME].supplied = TRUE;
19601 }
19602}
19603
19613static BOOL CALLBACK
19614ConfigDlgProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19615{
19616 SETUPDLG *setupdlg = NULL;
19617 WORD index;
19618
19619 switch (wmsg) {
19620 case WM_INITDIALOG:
19621#ifdef _WIN64
19622 SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19623#else
19624 SetWindowLong(hdlg, DWL_USER, lparam);
19625#endif
19626 setupdlg = (SETUPDLG *) lparam;
19627 GetAttributes(setupdlg);
19628 SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19629 SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19630 SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19631 SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19632 SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19633 SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19634 (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19635 SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19636 (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19637 SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19638 (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19639 SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19640 (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19641 SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19642 (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19643 CheckDlgButton(hdlg, IDC_STEPAPI,
19644 getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19645 BST_CHECKED : BST_UNCHECKED);
19646 CheckDlgButton(hdlg, IDC_NOTXN,
19647 getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19648 BST_CHECKED : BST_UNCHECKED);
19649 CheckDlgButton(hdlg, IDC_SHORTNAM,
19650 getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19651 BST_CHECKED : BST_UNCHECKED);
19652 CheckDlgButton(hdlg, IDC_LONGNAM,
19653 getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19654 BST_CHECKED : BST_UNCHECKED);
19655 CheckDlgButton(hdlg, IDC_NOCREAT,
19656 getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19657 BST_CHECKED : BST_UNCHECKED);
19658 CheckDlgButton(hdlg, IDC_NOWCHAR,
19659 getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19660 BST_CHECKED : BST_UNCHECKED);
19661 CheckDlgButton(hdlg, IDC_FKSUPPORT,
19662 getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19663 BST_CHECKED : BST_UNCHECKED);
19664 CheckDlgButton(hdlg, IDC_OEMCP,
19665 getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19666 BST_CHECKED : BST_UNCHECKED);
19667 CheckDlgButton(hdlg, IDC_BIGINT,
19668 getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19669 BST_CHECKED : BST_UNCHECKED);
19670 CheckDlgButton(hdlg, IDC_JDCONV,
19671 getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19672 BST_CHECKED : BST_UNCHECKED);
19673 SetDlgItemText(hdlg, IDC_ATTAS, setupdlg->attr[KEY_ATTAS].attr);
19674 CheckDlgButton(hdlg, IDC_ILIKE,
19675 getbool(setupdlg->attr[KEY_ILIKE].attr) ?
19676 BST_CHECKED : BST_UNCHECKED);
19677 SendDlgItemMessage(hdlg, IDC_SYNCP,
19678 CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19679 SendDlgItemMessage(hdlg, IDC_SYNCP,
19680 CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19681 SendDlgItemMessage(hdlg, IDC_SYNCP,
19682 CB_ADDSTRING, 0, (LPARAM) "OFF");
19683 SendDlgItemMessage(hdlg, IDC_SYNCP,
19684 CB_ADDSTRING, 0, (LPARAM) "FULL");
19685 SendDlgItemMessage(hdlg, IDC_SYNCP,
19686 CB_SELECTSTRING, (WPARAM) -1,
19687 (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19688 if (setupdlg->defDSN) {
19689 EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19690 EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19691 }
19692 return TRUE;
19693 case WM_COMMAND:
19694 switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19695 case IDC_DSNAME:
19696 if (GET_WM_COMMAND_CMD(wparam, lparam) == EN_CHANGE) {
19697 char item[MAXDSNAME];
19698
19699 EnableWindow(GetDlgItem(hdlg, IDOK),
19700 GetDlgItemText(hdlg, IDC_DSNAME,
19701 item, sizeof (item)));
19702 return TRUE;
19703 }
19704 break;
19705 case IDC_BROWSE:
19706 GetDBFile(hdlg);
19707 break;
19708 case IDOK:
19709#ifdef _WIN64
19710 setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19711#else
19712 setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19713#endif
19714 if (!setupdlg->defDSN) {
19715 GetDlgItemText(hdlg, IDC_DSNAME,
19716 setupdlg->attr[KEY_DSN].attr,
19717 sizeof (setupdlg->attr[KEY_DSN].attr));
19718 }
19719 GetDlgItemText(hdlg, IDC_DESC,
19720 setupdlg->attr[KEY_DESC].attr,
19721 sizeof (setupdlg->attr[KEY_DESC].attr));
19722 GetDlgItemText(hdlg, IDC_DBNAME,
19723 setupdlg->attr[KEY_DBNAME].attr,
19724 sizeof (setupdlg->attr[KEY_DBNAME].attr));
19725 GetDlgItemText(hdlg, IDC_TONAME,
19726 setupdlg->attr[KEY_BUSY].attr,
19727 sizeof (setupdlg->attr[KEY_BUSY].attr));
19728 GetDlgItemText(hdlg, IDC_LOADEXT,
19729 setupdlg->attr[KEY_LOADEXT].attr,
19730 sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19731 index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19732 CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19733 if (index != (WORD) CB_ERR) {
19734 SendDlgItemMessage(hdlg, IDC_SYNCP,
19735 CB_GETLBTEXT, index,
19736 (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19737 }
19738 strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19739 (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19740 "1" : "0");
19741 strcpy(setupdlg->attr[KEY_NOTXN].attr,
19742 (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19743 "1" : "0");
19744 strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19745 (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19746 "1" : "0");
19747 strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19748 (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19749 "1" : "0");
19750 strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19751 (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19752 "1" : "0");
19753 strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19754 (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19755 "1" : "0");
19756 strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19757 (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19758 "1" : "0");
19759 strcpy(setupdlg->attr[KEY_OEMCP].attr,
19760 (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19761 "1" : "0");
19762 strcpy(setupdlg->attr[KEY_BIGINT].attr,
19763 (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19764 "1" : "0");
19765 strcpy(setupdlg->attr[KEY_JDCONV].attr,
19766 (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19767 "1" : "0");
19768 GetDlgItemText(hdlg, IDC_ATTAS,
19769 setupdlg->attr[KEY_ATTAS].attr,
19770 sizeof (setupdlg->attr[KEY_ATTAS].attr));
19771 strcpy(setupdlg->attr[KEY_ILIKE].attr,
19772 (IsDlgButtonChecked(hdlg, IDC_ILIKE) == BST_CHECKED) ?
19773 "1" : "0");
19774 SetDSNAttributes(hdlg, setupdlg);
19775 /* FALL THROUGH */
19776 case IDCANCEL:
19777 EndDialog(hdlg, wparam);
19778 return TRUE;
19779 }
19780 break;
19781 }
19782 return FALSE;
19783}
19784
19794BOOL INSTAPI
19795ConfigDSN(HWND hwnd, WORD request, LPCSTR driver, LPCSTR attribs)
19796{
19797 BOOL success;
19798 SETUPDLG *setupdlg;
19799
19800 setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
19801 if (setupdlg == NULL) {
19802 return FALSE;
19803 }
19804 memset(setupdlg, 0, sizeof (SETUPDLG));
19805 if (attribs) {
19806 ParseAttributes(attribs, setupdlg);
19807 }
19808 if (setupdlg->attr[KEY_DSN].supplied) {
19809 strcpy(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr);
19810 } else {
19811 setupdlg->DSN[0] = '\0';
19812 }
19813 if (request == ODBC_REMOVE_DSN) {
19814 if (!setupdlg->attr[KEY_DSN].supplied) {
19815 success = FALSE;
19816 } else {
19817 success = SQLRemoveDSNFromIni(setupdlg->attr[KEY_DSN].attr);
19818 }
19819 } else {
19820 setupdlg->parent = hwnd;
19821 setupdlg->driver = driver;
19822 setupdlg->newDSN = request == ODBC_ADD_DSN;
19823 setupdlg->defDSN = strcasecmp(setupdlg->attr[KEY_DSN].attr,
19824 "Default") == 0;
19825 if (hwnd) {
19826 success = DialogBoxParam(hModule, MAKEINTRESOURCE(CONFIGDSN),
19827 hwnd, (DLGPROC) ConfigDlgProc,
19828 (LPARAM) setupdlg) == IDOK;
19829 } else if (setupdlg->attr[KEY_DSN].supplied) {
19830 success = SetDSNAttributes(hwnd, setupdlg);
19831 } else {
19832 success = FALSE;
19833 }
19834 }
19835 xfree(setupdlg);
19836 return success;
19837}
19838
19848static BOOL CALLBACK
19849DriverConnectProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19850{
19851 SETUPDLG *setupdlg;
19852 WORD index;
19853
19854 switch (wmsg) {
19855 case WM_INITDIALOG:
19856#ifdef _WIN64
19857 SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19858#else
19859 SetWindowLong(hdlg, DWL_USER, lparam);
19860#endif
19861 setupdlg = (SETUPDLG *) lparam;
19862 SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19863 SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19864 SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19865 SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19866 SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19867 SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19868 (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19869 SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19870 (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19871 SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19872 (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19873 SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19874 (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19875 SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19876 (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19877 CheckDlgButton(hdlg, IDC_STEPAPI,
19878 getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19879 BST_CHECKED : BST_UNCHECKED);
19880 CheckDlgButton(hdlg, IDC_NOTXN,
19881 getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19882 BST_CHECKED : BST_UNCHECKED);
19883 CheckDlgButton(hdlg, IDC_SHORTNAM,
19884 getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19885 BST_CHECKED : BST_UNCHECKED);
19886 CheckDlgButton(hdlg, IDC_LONGNAM,
19887 getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19888 BST_CHECKED : BST_UNCHECKED);
19889 CheckDlgButton(hdlg, IDC_NOCREAT,
19890 getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19891 BST_CHECKED : BST_UNCHECKED);
19892 CheckDlgButton(hdlg, IDC_NOWCHAR,
19893 getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19894 BST_CHECKED : BST_UNCHECKED);
19895 CheckDlgButton(hdlg, IDC_FKSUPPORT,
19896 getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19897 BST_CHECKED : BST_UNCHECKED);
19898 CheckDlgButton(hdlg, IDC_OEMCP,
19899 getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19900 BST_CHECKED : BST_UNCHECKED);
19901 CheckDlgButton(hdlg, IDC_BIGINT,
19902 getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19903 BST_CHECKED : BST_UNCHECKED);
19904 CheckDlgButton(hdlg, IDC_JDCONV,
19905 getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19906 BST_CHECKED : BST_UNCHECKED);
19907 SendDlgItemMessage(hdlg, IDC_SYNCP,
19908 CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19909 SendDlgItemMessage(hdlg, IDC_SYNCP,
19910 CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19911 SendDlgItemMessage(hdlg, IDC_SYNCP,
19912 CB_ADDSTRING, 0, (LPARAM) "OFF");
19913 SendDlgItemMessage(hdlg, IDC_SYNCP,
19914 CB_ADDSTRING, 0, (LPARAM) "FULL");
19915 SendDlgItemMessage(hdlg, IDC_SYNCP,
19916 CB_SELECTSTRING, (WORD) -1,
19917 (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19918 if (setupdlg->defDSN) {
19919 EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19920 EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19921 }
19922 SetDlgItemText(hdlg, IDC_ATTAS, setupdlg->attr[KEY_ATTAS].attr);
19923 CheckDlgButton(hdlg, IDC_ILIKE,
19924 getbool(setupdlg->attr[KEY_ILIKE].attr) ?
19925 BST_CHECKED : BST_UNCHECKED);
19926 return TRUE;
19927 case WM_COMMAND:
19928 switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19929 case IDC_BROWSE:
19930 GetDBFile(hdlg);
19931 break;
19932 case IDOK:
19933#ifdef _WIN64
19934 setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19935#else
19936 setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19937#endif
19938 GetDlgItemText(hdlg, IDC_DSNAME,
19939 setupdlg->attr[KEY_DSN].attr,
19940 sizeof (setupdlg->attr[KEY_DSN].attr));
19941 GetDlgItemText(hdlg, IDC_DBNAME,
19942 setupdlg->attr[KEY_DBNAME].attr,
19943 sizeof (setupdlg->attr[KEY_DBNAME].attr));
19944 GetDlgItemText(hdlg, IDC_TONAME,
19945 setupdlg->attr[KEY_BUSY].attr,
19946 sizeof (setupdlg->attr[KEY_BUSY].attr));
19947 GetDlgItemText(hdlg, IDC_LOADEXT,
19948 setupdlg->attr[KEY_LOADEXT].attr,
19949 sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19950 index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19951 CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19952 if (index != (WORD) CB_ERR) {
19953 SendDlgItemMessage(hdlg, IDC_SYNCP,
19954 CB_GETLBTEXT, index,
19955 (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19956 }
19957 strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19958 (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19959 "1" : "0");
19960 strcpy(setupdlg->attr[KEY_NOTXN].attr,
19961 (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19962 "1" : "0");
19963 strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19964 (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19965 "1" : "0");
19966 strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19967 (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19968 "1" : "0");
19969 strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19970 (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19971 "1" : "0");
19972 strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19973 (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19974 "1" : "0");
19975 strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19976 (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19977 "1" : "0");
19978 strcpy(setupdlg->attr[KEY_OEMCP].attr,
19979 (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19980 "1" : "0");
19981 strcpy(setupdlg->attr[KEY_BIGINT].attr,
19982 (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19983 "1" : "0");
19984 strcpy(setupdlg->attr[KEY_JDCONV].attr,
19985 (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19986 "1" : "0");
19987 GetDlgItemText(hdlg, IDC_ATTAS,
19988 setupdlg->attr[KEY_ATTAS].attr,
19989 sizeof (setupdlg->attr[KEY_ATTAS].attr));
19990 strcpy(setupdlg->attr[KEY_ILIKE].attr,
19991 (IsDlgButtonChecked(hdlg, IDC_ILIKE) == BST_CHECKED) ?
19992 "1" : "0");
19993 /* FALL THROUGH */
19994 case IDCANCEL:
19995 EndDialog(hdlg, GET_WM_COMMAND_ID(wparam, lparam) == IDOK);
19996 return TRUE;
19997 }
19998 }
19999 return FALSE;
20000}
20001
20015static SQLRETURN
20016drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
20017 SQLCHAR *connIn, SQLSMALLINT connInLen,
20018 SQLCHAR *connOut, SQLSMALLINT connOutMax,
20019 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
20020{
20021 BOOL maybeprompt, prompt = FALSE, defaultdsn = FALSE;
20022 DBC *d;
20023 SETUPDLG *setupdlg;
20024 SQLRETURN ret;
20025 char *dsn = NULL, *driver = NULL, *dbname = NULL;
20026
20027 if (dbc == SQL_NULL_HDBC) {
20028 return SQL_INVALID_HANDLE;
20029 }
20030 d = (DBC *) dbc;
20031 if (d->sqlite) {
20032 setstatd(d, -1, "connection already established", "08002");
20033 return SQL_ERROR;
20034 }
20035 setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
20036 if (setupdlg == NULL) {
20037 return SQL_ERROR;
20038 }
20039 memset(setupdlg, 0, sizeof (SETUPDLG));
20040 maybeprompt = drvcompl == SQL_DRIVER_COMPLETE ||
20041 drvcompl == SQL_DRIVER_COMPLETE_REQUIRED;
20042 if (connIn == NULL || !connInLen ||
20043 (connInLen == SQL_NTS && !connIn[0])) {
20044 prompt = TRUE;
20045 } else {
20046 ParseAttributes((LPCSTR) connIn, setupdlg);
20047 if (!setupdlg->attr[KEY_DSN].attr[0] &&
20048 drvcompl == SQL_DRIVER_COMPLETE_REQUIRED) {
20049 strcpy(setupdlg->attr[KEY_DSN].attr, "DEFAULT");
20050 defaultdsn = TRUE;
20051 }
20052 GetAttributes(setupdlg);
20053 if (drvcompl == SQL_DRIVER_PROMPT ||
20054 (maybeprompt &&
20055 !setupdlg->attr[KEY_DBNAME].attr[0])) {
20056 prompt = TRUE;
20057 }
20058 }
20059retry:
20060 if (prompt) {
20061 short dlgret;
20062
20063 setupdlg->defDSN = setupdlg->attr[KEY_DRIVER].attr[0] != '\0';
20064 dlgret = DialogBoxParam(hModule, MAKEINTRESOURCE(DRIVERCONNECT),
20065 hwnd, (DLGPROC) DriverConnectProc,
20066 (LPARAM) setupdlg);
20067
20068 if (!dlgret || dlgret == -1) {
20069 xfree(setupdlg);
20070 return SQL_NO_DATA;
20071 }
20072 }
20073 dsn = setupdlg->attr[KEY_DSN].attr;
20074 driver = setupdlg->attr[KEY_DRIVER].attr;
20075 dbname = setupdlg->attr[KEY_DBNAME].attr;
20076 if (connOut || connOutLen) {
20077 char buf[SQL_MAX_MESSAGE_LENGTH * 8];
20078 int len, count;
20079 char dsn_0 = (dsn && !defaultdsn) ? dsn[0] : '\0';
20080 char drv_0 = driver ? driver[0] : '\0';
20081
20082 buf[0] = '\0';
20083 count = snprintf(buf, sizeof (buf),
20084 "%s%s%s%s%s%sDatabase=%s;StepAPI=%s;"
20085 "SyncPragma=%s;NoTXN=%s;Timeout=%s;"
20086 "ShortNames=%s;LongNames=%s;"
20087 "NoCreat=%s;NoWCHAR=%s;"
20088 "FKSupport=%s;JournalMode=%s;OEMCP=%s;LoadExt=%s;"
20089 "BigInt=%s;JDConv=%s;PWD=%s;AttachAs=%s;ILike=%s",
20090 dsn_0 ? "DSN=" : "",
20091 dsn_0 ? dsn : "",
20092 dsn_0 ? ";" : "",
20093 drv_0 ? "Driver=" : "",
20094 drv_0 ? driver : "",
20095 drv_0 ? ";" : "",
20096 dbname ? dbname : "",
20097 setupdlg->attr[KEY_STEPAPI].attr,
20098 setupdlg->attr[KEY_SYNCP].attr,
20099 setupdlg->attr[KEY_NOTXN].attr,
20100 setupdlg->attr[KEY_BUSY].attr,
20101 setupdlg->attr[KEY_SHORTNAM].attr,
20102 setupdlg->attr[KEY_LONGNAM].attr,
20103 setupdlg->attr[KEY_NOCREAT].attr,
20104 setupdlg->attr[KEY_NOWCHAR].attr,
20105 setupdlg->attr[KEY_FKSUPPORT].attr,
20106 setupdlg->attr[KEY_JMODE].attr,
20107 setupdlg->attr[KEY_OEMCP].attr,
20108 setupdlg->attr[KEY_LOADEXT].attr,
20109 setupdlg->attr[KEY_BIGINT].attr,
20110 setupdlg->attr[KEY_JDCONV].attr,
20111 setupdlg->attr[KEY_PASSWD].attr,
20112 setupdlg->attr[KEY_ATTAS].attr,
20113 setupdlg->attr[KEY_ILIKE].attr);
20114 if (count < 0) {
20115 buf[sizeof (buf) - 1] = '\0';
20116 }
20117 len = min(connOutMax - 1, strlen(buf));
20118 if (connOut) {
20119 strncpy((char *) connOut, buf, len);
20120 connOut[len] = '\0';
20121 }
20122 if (connOutLen) {
20123 *connOutLen = len;
20124 }
20125 }
20126 if (dsn[0]) {
20127 char tracef[SQL_MAX_MESSAGE_LENGTH];
20128
20129 tracef[0] = '\0';
20130 SQLGetPrivateProfileString(setupdlg->attr[KEY_DSN].attr,
20131 "tracefile", "", tracef,
20132 sizeof (tracef), ODBC_INI);
20133 if (tracef[0] != '\0') {
20134 d->trace = fopen(tracef, "a");
20135 }
20136 }
20137 d->nowchar = getbool(setupdlg->attr[KEY_NOWCHAR].attr);
20138 d->shortnames = getbool(setupdlg->attr[KEY_SHORTNAM].attr);
20139 d->longnames = getbool(setupdlg->attr[KEY_LONGNAM].attr);
20140 d->nocreat = getbool(setupdlg->attr[KEY_NOCREAT].attr);
20141 d->fksupport = getbool(setupdlg->attr[KEY_FKSUPPORT].attr);
20142 d->oemcp = getbool(setupdlg->attr[KEY_OEMCP].attr);
20143 d->dobigint = getbool(setupdlg->attr[KEY_BIGINT].attr);
20144 d->jdconv = getbool(setupdlg->attr[KEY_JDCONV].attr);
20145 d->ilike = getbool(setupdlg->attr[KEY_ILIKE].attr);
20146 d->pwdLen = strlen(setupdlg->attr[KEY_PASSWD].attr);
20147 d->pwd = (d->pwdLen > 0) ? setupdlg->attr[KEY_PASSWD].attr : NULL;
20148 ret = dbopen(d, dbname ? dbname : "", 0,
20149 dsn ? dsn : "",
20150 setupdlg->attr[KEY_STEPAPI].attr,
20151 setupdlg->attr[KEY_SYNCP].attr,
20152 setupdlg->attr[KEY_NOTXN].attr,
20153 setupdlg->attr[KEY_JMODE].attr,
20154 setupdlg->attr[KEY_BUSY].attr);
20155 if (ret != SQL_SUCCESS) {
20156 if (maybeprompt && !prompt) {
20157 prompt = TRUE;
20158 goto retry;
20159 }
20160 }
20161 memset(setupdlg->attr[KEY_PASSWD].attr, 0,
20162 sizeof (setupdlg->attr[KEY_PASSWD].attr));
20163 if (ret == SQL_SUCCESS) {
20164 dbloadext(d, setupdlg->attr[KEY_LOADEXT].attr);
20165 dbattas(d, setupdlg->attr[KEY_ATTAS].attr);
20166 }
20167 xfree(setupdlg);
20168 return ret;
20169}
20170
20171#endif /* WITHOUT_DRIVERMGR */
20172#endif /* _WIN32 || _WIN64 */
20173
20174#ifndef WINTERFACE
20188SQLRETURN SQL_API
20189SQLDriverConnect(SQLHDBC dbc, SQLHWND hwnd,
20190 SQLCHAR *connIn, SQLSMALLINT connInLen,
20191 SQLCHAR *connOut, SQLSMALLINT connOutMax,
20192 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
20193{
20194 SQLRETURN ret;
20195
20196 HDBC_LOCK(dbc);
20197 ret = drvdriverconnect(dbc, hwnd, connIn, connInLen,
20198 connOut, connOutMax, connOutLen, drvcompl);
20200 return ret;
20201}
20202#endif
20203
20204#ifdef WINTERFACE
20218SQLRETURN SQL_API
20219SQLDriverConnectW(SQLHDBC dbc, SQLHWND hwnd,
20220 SQLWCHAR *connIn, SQLSMALLINT connInLen,
20221 SQLWCHAR *connOut, SQLSMALLINT connOutMax,
20222 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
20223{
20224 SQLRETURN ret;
20225 char *ci = NULL;
20226 SQLSMALLINT len = 0;
20227
20228 HDBC_LOCK(dbc);
20229 if (connIn) {
20230#if defined(_WIN32) || defined(_WIN64)
20231 if (connInLen == SQL_NTS) {
20232 connInLen = -1;
20233 }
20234 ci = uc_to_wmb(connIn, connInLen);
20235#else
20236 ci = uc_to_utf(connIn, connInLen);
20237#endif
20238 if (!ci) {
20239 DBC *d = (DBC *) dbc;
20240
20241 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
20243 return SQL_ERROR;
20244 }
20245 }
20246 ret = drvdriverconnect(dbc, hwnd, (SQLCHAR *) ci, SQL_NTS,
20247 (SQLCHAR *) connOut, connOutMax, &len, drvcompl);
20249 uc_free(ci);
20250 if (ret == SQL_SUCCESS) {
20251 SQLWCHAR *co = NULL;
20252
20253 if (connOut) {
20254 if (len > 0) {
20255#if defined(_WIN32) || defined(_WIN64)
20256 co = wmb_to_uc((char *) connOut, len);
20257#else
20258 co = uc_from_utf((SQLCHAR *) connOut, len);
20259#endif
20260 if (co) {
20261 uc_strncpy(connOut, co, connOutMax / sizeof (SQLWCHAR));
20262 len = min(connOutMax / sizeof (SQLWCHAR), uc_strlen(co));
20263 uc_free(co);
20264 } else {
20265 len = 0;
20266 }
20267 }
20268 if (len <= 0) {
20269 len = 0;
20270 connOut[0] = 0;
20271 }
20272 } else {
20273 len = 0;
20274 }
20275 if (connOutLen) {
20276 *connOutLen = len;
20277 }
20278 }
20279 return ret;
20280}
20281#endif
20282
20283#if defined(_WIN32) || defined(_WIN64)
20284
20293BOOL APIENTRY
20294LibMain(HANDLE hinst, DWORD reason, LPVOID reserved)
20295{
20296 static int initialized = 0;
20297
20298 switch (reason) {
20299 case DLL_PROCESS_ATTACH:
20300 if (!initialized++) {
20301 hModule = hinst;
20302#ifdef WINTERFACE
20303 /* MS Access hack part 1 (reserved error -7748) */
20304 statSpec2P = statSpec2;
20305 statSpec3P = statSpec3;
20306#endif
20307#ifdef SQLITE_DYNLOAD
20308 dls_init();
20309#endif
20310#ifdef SQLITE_HAS_CODEC
20311 sqlite3_activate_see(SQLITE_ACTIVATION_KEY);
20312#endif
20313 }
20314#if defined(ENABLE_NVFS) && (ENABLE_NVFS)
20315 nvfs_init();
20316#endif
20317 break;
20318 case DLL_THREAD_ATTACH:
20319 break;
20320 case DLL_PROCESS_DETACH:
20321 if (--initialized <= 0) {
20322#ifdef SQLITE_DYNLOAD
20323 dls_fini();
20324#endif
20325 }
20326 break;
20327 case DLL_THREAD_DETACH:
20328 break;
20329 default:
20330 break;
20331 }
20332 return TRUE;
20333}
20334
20343int __stdcall
20344DllMain(HANDLE hinst, DWORD reason, LPVOID reserved)
20345{
20346 return LibMain(hinst, reason, reserved);
20347}
20348
20349#ifndef WITHOUT_INSTALLER
20350
20357static BOOL
20358InUnError(char *name)
20359{
20360 WORD err = 1;
20361 DWORD code;
20362 char errmsg[301];
20363 WORD errlen, errmax = sizeof (errmsg) - 1;
20364 int sqlret;
20365 BOOL ret = FALSE;
20366
20367 do {
20368 errmsg[0] = '\0';
20369 sqlret = SQLInstallerError(err, &code, errmsg, errmax, &errlen);
20370 if (SQL_SUCCEEDED(sqlret)) {
20371 MessageBox(NULL, errmsg, name,
20372 MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
20373 ret = TRUE;
20374 }
20375 err++;
20376 } while (sqlret != SQL_NO_DATA);
20377 return ret;
20378}
20379
20386static BOOL
20387InUn(int remove, char *cmdline)
20388{
20389#ifdef SQLITE_HAS_CODEC
20390 static char *drivername = "SQLite3 ODBC Driver (SEE)";
20391 static char *dsname = "SQLite3 SEE Datasource";
20392#else
20393 static char *drivername = "SQLite3 ODBC Driver";
20394 static char *dsname = "SQLite3 Datasource";
20395#endif
20396 char *dllname, *p;
20397 char dllbuf[301], path[301], driver[300], attr[300], inst[400];
20398 WORD pathmax = sizeof (path) - 1, pathlen;
20399 DWORD usecnt, mincnt;
20400 int quiet = 0;
20401
20402 dllbuf[0] = '\0';
20403 GetModuleFileName(hModule, dllbuf, sizeof (dllbuf));
20404 p = strrchr(dllbuf, '\\');
20405 dllname = p ? (p + 1) : dllbuf;
20406 quiet = cmdline && strstr(cmdline, "quiet");
20407 if (SQLInstallDriverManager(path, pathmax, &pathlen)) {
20408 sprintf(driver, "%s;Driver=%s;Setup=%s;",
20409 drivername, dllname, dllname);
20410 p = driver;
20411 while (*p) {
20412 if (*p == ';') {
20413 *p = '\0';
20414 }
20415 ++p;
20416 }
20417 usecnt = 0;
20418 path[0] = '\0';
20419 SQLInstallDriverEx(driver, NULL, path, pathmax, NULL,
20420 ODBC_INSTALL_INQUIRY, &usecnt);
20421 pathlen = strlen(path);
20422 while (pathlen > 0 && path[pathlen - 1] == '\\') {
20423 --pathlen;
20424 path[pathlen] = '\0';
20425 }
20426 sprintf(driver, "%s;Driver=%s\\%s;Setup=%s\\%s;",
20427 drivername, path, dllname, path, dllname);
20428 p = driver;
20429 while (*p) {
20430 if (*p == ';') {
20431 *p = '\0';
20432 }
20433 ++p;
20434 }
20435 sprintf(inst, "%s\\%s", path, dllname);
20436 if (!remove && usecnt > 0) {
20437 /* first install try: copy over driver dll, keeping DSNs */
20438 if (GetFileAttributesA(dllbuf) != INVALID_FILE_ATTRIBUTES &&
20439 CopyFile(dllbuf, inst, 0)) {
20440 if (!quiet) {
20441 char buf[512];
20442
20443 sprintf(buf, "%s replaced.", drivername);
20444 MessageBox(NULL, buf, "Info",
20445 MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20446 MB_SETFOREGROUND);
20447 }
20448 return TRUE;
20449 }
20450 }
20451 mincnt = remove ? 1 : 0;
20452 while (usecnt != mincnt) {
20453 if (!SQLRemoveDriver(driver, TRUE, &usecnt)) {
20454 break;
20455 }
20456 }
20457 if (remove) {
20458 if (usecnt && !SQLRemoveDriver(driver, TRUE, &usecnt)) {
20459 InUnError("SQLRemoveDriver");
20460 return FALSE;
20461 }
20462 if (!usecnt) {
20463 char buf[512];
20464
20465 DeleteFile(inst);
20466 if (!quiet) {
20467 sprintf(buf, "%s uninstalled.", drivername);
20468 MessageBox(NULL, buf, "Info",
20469 MB_ICONINFORMATION |MB_OK | MB_TASKMODAL |
20470 MB_SETFOREGROUND);
20471 }
20472 }
20473 sprintf(attr, "DSN=%s;Database=;", dsname);
20474 p = attr;
20475 while (*p) {
20476 if (*p == ';') {
20477 *p = '\0';
20478 }
20479 ++p;
20480 }
20481 SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20482 return TRUE;
20483 }
20484 if (GetFileAttributesA(dllbuf) == INVALID_FILE_ATTRIBUTES) {
20485 return FALSE;
20486 }
20487 if (strcasecmp(dllbuf, inst) != 0 && !CopyFile(dllbuf, inst, 0)) {
20488 char buf[512];
20489
20490 sprintf(buf, "Copy %s to %s failed.", dllbuf, inst);
20491 MessageBox(NULL, buf, "CopyFile",
20492 MB_ICONSTOP |MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
20493 return FALSE;
20494 }
20495 if (!SQLInstallDriverEx(driver, path, path, pathmax, &pathlen,
20496 ODBC_INSTALL_COMPLETE, &usecnt)) {
20497 InUnError("SQLInstallDriverEx");
20498 return FALSE;
20499 }
20500 sprintf(attr, "DSN=%s;Database=;", dsname);
20501 p = attr;
20502 while (*p) {
20503 if (*p == ';') {
20504 *p = '\0';
20505 }
20506 ++p;
20507 }
20508 SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20509 if (!SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN, drivername, attr)) {
20510 InUnError("SQLConfigDataSource");
20511 return FALSE;
20512 }
20513 if (!quiet) {
20514 char buf[512];
20515
20516 sprintf(buf, "%s installed.", drivername);
20517 MessageBox(NULL, buf, "Info",
20518 MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20519 MB_SETFOREGROUND);
20520 }
20521 } else {
20522 InUnError("SQLInstallDriverManager");
20523 return FALSE;
20524 }
20525 return TRUE;
20526}
20527
20536void CALLBACK
20537install(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20538{
20539 InUn(0, lpszCmdLine);
20540}
20541
20550void CALLBACK
20551uninstall(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20552{
20553 InUn(1, lpszCmdLine);
20554}
20555
20556#endif /* WITHOUT_INSTALLER */
20557
20558#ifndef WITHOUT_SHELL
20559
20568static void
20569setargv(int *argcp, char ***argvp, char *cmdline, char *argv0)
20570{
20571 char *p, *arg, *argspace, **argv;
20572 int argc, size, inquote, copy, slashes;
20573
20574 size = 2 + (argv0 ? 1 : 0);
20575 for (p = cmdline; *p != '\0'; p++) {
20576 if (ISSPACE(*p)) {
20577 size++;
20578 while (ISSPACE(*p)) {
20579 p++;
20580 }
20581 if (*p == '\0') {
20582 break;
20583 }
20584 }
20585 }
20586 argspace = malloc(size * sizeof (char *) + strlen(cmdline) + 1);
20587 argv = (char **) argspace;
20588 argspace += size * sizeof (char *);
20589 size--;
20590 argc = 0;
20591 if (argv0) {
20592 argv[argc++] = argv0;
20593 }
20594 p = cmdline;
20595 for (; argc < size; argc++) {
20596 argv[argc] = arg = argspace;
20597 while (ISSPACE(*p)) {
20598 p++;
20599 }
20600 if (*p == '\0') {
20601 break;
20602 }
20603 inquote = 0;
20604 slashes = 0;
20605 while (1) {
20606 copy = 1;
20607 while (*p == '\\') {
20608 slashes++;
20609 p++;
20610 }
20611 if (*p == '"') {
20612 if ((slashes & 1) == 0) {
20613 copy = 0;
20614 if (inquote && p[1] == '"') {
20615 p++;
20616 copy = 1;
20617 } else {
20618 inquote = !inquote;
20619 }
20620 }
20621 slashes >>= 1;
20622 }
20623 while (slashes) {
20624 *arg = '\\';
20625 arg++;
20626 slashes--;
20627 }
20628 if (*p == '\0' || (!inquote && ISSPACE(*p))) {
20629 break;
20630 }
20631 if (copy != 0) {
20632 *arg = *p;
20633 arg++;
20634 }
20635 p++;
20636 }
20637 *arg = '\0';
20638 argspace = arg + 1;
20639 }
20640 argv[argc] = 0;
20641 *argcp = argc;
20642 *argvp = argv;
20643}
20644
20653void CALLBACK
20654shell(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20655{
20656 int argc, needcon = 0;
20657 char **argv;
20658 extern int sqlite3_main(int, char **);
20659 static const char *name = "SQLite3 Shell";
20660 DWORD ftype0, ftype1, ftype2;
20661
20662 ftype0 = GetFileType(GetStdHandle(STD_INPUT_HANDLE));
20663 ftype1 = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
20664 ftype2 = GetFileType(GetStdHandle(STD_ERROR_HANDLE));
20665 if (ftype0 != FILE_TYPE_DISK && ftype0 != FILE_TYPE_CHAR &&
20666 ftype0 != FILE_TYPE_PIPE) {
20667 fclose(stdin);
20668 ++needcon;
20669 ftype0 = FILE_TYPE_UNKNOWN;
20670 }
20671 if (ftype1 != FILE_TYPE_DISK && ftype1 != FILE_TYPE_CHAR &&
20672 ftype1 != FILE_TYPE_PIPE) {
20673 fclose(stdout);
20674 ++needcon;
20675 ftype1 = FILE_TYPE_UNKNOWN;
20676 }
20677 if (ftype2 != FILE_TYPE_DISK && ftype2 != FILE_TYPE_CHAR &&
20678 ftype2 != FILE_TYPE_PIPE) {
20679 fclose(stderr);
20680 ++needcon;
20681 ftype2 = FILE_TYPE_UNKNOWN;
20682 }
20683 if (needcon > 0) {
20684 AllocConsole();
20685 SetConsoleTitle(name);
20686 }
20687 if (ftype0 == FILE_TYPE_UNKNOWN) {
20688 freopen("CONIN$", "r", stdin);
20689 }
20690 if (ftype1 == FILE_TYPE_UNKNOWN) {
20691 freopen("CONOUT$", "w", stdout);
20692 }
20693 if (ftype2 == FILE_TYPE_UNKNOWN) {
20694 freopen("CONOUT$", "w", stderr);
20695 }
20696 setargv(&argc, &argv, lpszCmdLine, (char *) name);
20697#if defined(ENABLE_NVFS) && (ENABLE_NVFS)
20698 nvfs_init();
20699#endif
20700 sqlite3_main(argc, argv);
20701}
20702
20703#endif /* WITHOUT_SHELL */
20704
20705#endif /* _WIN32 || _WIN64 */
20706
20707#if defined(HAVE_ODBCINSTEXT_H) && (HAVE_ODBCINSTEXT_H)
20708
20709/*
20710 * unixODBC property page for this driver,
20711 * may or may not work depending on unixODBC version.
20712 */
20713
20714#include <odbcinstext.h>
20715
20716int
20717ODBCINSTGetProperties(HODBCINSTPROPERTY prop)
20718{
20719 static const char *instYN[] = { "No", "Yes", NULL };
20720 static const char *syncPragma[] = { "NORMAL", "OFF", "FULL", NULL };
20721 static const char *jmPragma[] = {
20722 "DELETE", "PERSIST", "OFF", "TRUNCATE", "MEMORY", "WAL", NULL
20723 };
20724
20725 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20726 prop = prop->pNext;
20727 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20728 prop->nPromptType = ODBCINST_PROMPTTYPE_FILENAME;
20729 strncpy(prop->szName, "Database", INI_MAX_PROPERTY_NAME);
20730 strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20731 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20732 prop = prop->pNext;
20733 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20734 prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20735 strncpy(prop->szName, "Timeout", INI_MAX_PROPERTY_NAME);
20736 strncpy(prop->szValue, "100000", INI_MAX_PROPERTY_VALUE);
20737 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20738 prop = prop->pNext;
20739 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20740 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20741 prop->aPromptData = malloc(sizeof (instYN));
20742 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20743 strncpy(prop->szName, "StepAPI", INI_MAX_PROPERTY_NAME);
20744 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20745 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20746 prop = prop->pNext;
20747 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20748 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20749 prop->aPromptData = malloc(sizeof (instYN));
20750 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20751 strncpy(prop->szName, "ShortNames", INI_MAX_PROPERTY_NAME);
20752 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20753 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20754 prop = prop->pNext;
20755 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20756 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20757 prop->aPromptData = malloc(sizeof (instYN));
20758 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20759 strncpy(prop->szName, "LongNames", INI_MAX_PROPERTY_NAME);
20760 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20761 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20762 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20763 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20764 prop->aPromptData = malloc(sizeof (instYN));
20765 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20766 strncpy(prop->szName, "NoCreat", INI_MAX_PROPERTY_NAME);
20767 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20768#ifdef WINTERFACE
20769 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20770 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20771 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20772 prop->aPromptData = malloc(sizeof (instYN));
20773 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20774 strncpy(prop->szName, "NoWCHAR", INI_MAX_PROPERTY_NAME);
20775 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20776#endif
20777 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20778 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20779 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20780 prop->aPromptData = malloc(sizeof (instYN));
20781 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20782 strncpy(prop->szName, "FKSupport", INI_MAX_PROPERTY_NAME);
20783 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20784 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20785 prop = prop->pNext;
20786 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20787 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20788 prop->aPromptData = malloc(sizeof (syncPragma));
20789 memcpy(prop->aPromptData, syncPragma, sizeof (syncPragma));
20790 strncpy(prop->szName, "SyncPragma", INI_MAX_PROPERTY_NAME);
20791 strncpy(prop->szValue, "NORMAL", INI_MAX_PROPERTY_VALUE);
20792 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20793 prop = prop->pNext;
20794 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20795 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20796 prop->aPromptData = malloc(sizeof (jmPragma));
20797 memcpy(prop->aPromptData, jmPragma, sizeof (jmPragma));
20798 strncpy(prop->szName, "JournalMode", INI_MAX_PROPERTY_NAME);
20799 strncpy(prop->szValue, "DELETE", INI_MAX_PROPERTY_VALUE);
20800 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20801 prop = prop->pNext;
20802 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20803 prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20804 strncpy(prop->szName, "LoadExt", INI_MAX_PROPERTY_NAME);
20805 strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20806 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20807 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20808 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20809 prop->aPromptData = malloc(sizeof (instYN));
20810 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20811 strncpy(prop->szName, "BigInt", INI_MAX_PROPERTY_NAME);
20812 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20813 return 1;
20814}
20815
20816#endif /* HAVE_ODBCINSTEXT_H */
20817
20818#ifdef SQLITE_DYNLOAD
20819
20820/*
20821 * SQLite3 shared library/DLL stubs.
20822 */
20823
20824static void
20825dls_void(void)
20826{
20827}
20828
20829static int
20830dls_error(void)
20831{
20832 return SQLITE_ERROR;
20833}
20834
20835static int
20836dls_0(void)
20837{
20838 return 0;
20839}
20840
20841static sqlite_int64
20842dls_0LL(void)
20843{
20844 return 0;
20845}
20846
20847static double
20848dls_00(void)
20849{
20850 return 0;
20851}
20852
20853static void *
20854dls_null(void)
20855{
20856 return NULL;
20857}
20858
20859static const char *
20860dls_empty(void)
20861{
20862 return "";
20863}
20864
20865static int
20866dls_snull(void)
20867{
20868 return SQLITE_NULL;
20869}
20870
20871#define DLS_ENT(name, func) \
20872 { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, name), \
20873 (void *) func }
20874
20875#define DLS_ENT3(name, off, func) \
20876 { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, off), \
20877 (void *) func }
20878
20879#define DLS_END { NULL, 0, NULL }
20880
20881static struct {
20882 const char *name;
20883 int offset;
20884 void *func;
20885} dls_nametab[] = {
20886 DLS_ENT(activate_see, dls_void),
20887 DLS_ENT(bind_blob, dls_error),
20888 DLS_ENT(bind_double, dls_error),
20889 DLS_ENT(bind_int, dls_error),
20890 DLS_ENT(bind_int64, dls_error),
20891 DLS_ENT(bind_null, dls_error),
20892 DLS_ENT(bind_parameter_count, dls_0),
20893 DLS_ENT(bind_text, dls_error),
20894 DLS_ENT(busy_handler, dls_error),
20895 DLS_ENT(changes, dls_0),
20896 DLS_ENT(close, dls_error),
20897 DLS_ENT(column_blob, dls_null),
20898 DLS_ENT(column_bytes, dls_0),
20899 DLS_ENT(column_count, dls_0),
20900 DLS_ENT(column_database_name, dls_empty),
20901 DLS_ENT(column_decltype, dls_empty),
20902 DLS_ENT(column_double, dls_00),
20903 DLS_ENT(column_name, dls_empty),
20904 DLS_ENT(column_origin_name, dls_null),
20905 DLS_ENT(column_table_name, dls_null),
20906 DLS_ENT(column_text, dls_null),
20907 DLS_ENT(column_type, dls_snull),
20908 DLS_ENT(create_function, dls_error),
20909 DLS_ENT(enable_load_extension, dls_error),
20910 DLS_ENT(errcode, dls_error),
20911 DLS_ENT(errmsg, dls_empty),
20912 DLS_ENT(exec, dls_error),
20913 DLS_ENT(finalize, dls_error),
20914 DLS_ENT(free, free),
20915 DLS_ENT(free_table, dls_void),
20916 DLS_ENT(get_table, dls_error),
20917 DLS_ENT(interrupt, dls_void),
20918 DLS_ENT(key, dls_error),
20919 DLS_ENT(last_insert_rowid, dls_0LL),
20920 DLS_ENT(libversion, dls_empty),
20921 DLS_ENT(load_extension, dls_error),
20922 DLS_ENT(malloc, malloc),
20923 DLS_ENT(mprintf, dls_null),
20924 DLS_ENT(open, dls_error),
20925 DLS_ENT(open16, dls_error),
20926 DLS_ENT(open_v2, dls_error),
20927 DLS_ENT(prepare, dls_error),
20928 DLS_ENT(prepare_v2, dls_error),
20929 DLS_ENT(profile, dls_null),
20930 DLS_ENT(realloc, realloc),
20931 DLS_ENT(rekey, dls_error),
20932 DLS_ENT(reset, dls_error),
20933 DLS_ENT(result_blob, dls_void),
20934 DLS_ENT(result_error, dls_void),
20935 DLS_ENT(result_int, dls_void),
20936 DLS_ENT(result_null, dls_void),
20937 DLS_ENT(step, dls_error),
20938#if defined(_WIN32) || defined(_WIN64)
20939 DLS_ENT3(strnicmp, xstrnicmp, _strnicmp),
20940#else
20941 DLS_ENT3(strnicmp, xstrnicmp, strncasecmp),
20942#endif
20943 DLS_ENT(table_column_metadata, dls_error),
20944 DLS_ENT(trace, dls_null),
20945 DLS_ENT(user_data, dls_null),
20946 DLS_ENT(value_blob, dls_null),
20947 DLS_ENT(value_bytes, dls_0),
20948 DLS_ENT(value_text, dls_empty),
20949 DLS_ENT(value_type, dls_snull),
20950 DLS_END
20951};
20952
20953#if defined(_WIN32) || defined(_WIN64)
20954
20955static HMODULE sqlite3_dll = 0;
20956
20957static void
20958dls_init(void)
20959{
20960 int i;
20961 static const char *dll_names[] = {
20962 "System.Data.SQLite.dll",
20963 "sqlite3.dll",
20964 NULL,
20965 };
20966
20967 i = 0;
20968 while (dll_names[i]) {
20969 sqlite3_dll = LoadLibrary(dll_names[i]);
20970 if (sqlite3_dll) {
20971 break;
20972 }
20973 ++i;
20974 }
20975 i = 0;
20976 while (dls_nametab[i].name) {
20977 void *func = 0, **loc;
20978
20979 if (sqlite3_dll) {
20980 func = (void *) GetProcAddress(sqlite3_dll, dls_nametab[i].name);
20981 }
20982 if (!func) {
20983 func = dls_nametab[i].func;
20984 }
20985 loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
20986 *loc = func;
20987 ++i;
20988 }
20989 if (!sqlite3_dll) {
20990 char buf[MAXPATHLEN], msg[MAXPATHLEN];
20991
20992 LoadString(hModule, IDS_DRVTITLE, buf, sizeof (buf));
20993 LoadString(hModule, IDS_DLLERR, msg, sizeof (msg));
20994 MessageBox(NULL, msg, buf,
20995 MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
20996 MB_SETFOREGROUND);
20997 }
20998}
20999
21000static void
21001dls_fini(void)
21002{
21003 if (sqlite3_dll) {
21004 FreeLibrary(sqlite3_dll);
21005 sqlite3_dll = 0;
21006 }
21007}
21008
21009#else
21010
21011#include <dlfcn.h>
21012
21013static void *libsqlite3_so = 0;
21014
21015void
21016dls_init(void)
21017{
21018 int i;
21019
21020 libsqlite3_so = dlopen("libsqlite3.so.0", RTLD_NOW | RTLD_GLOBAL);
21021 i = 0;
21022 while (dls_nametab[i].name) {
21023 void *func = 0, **loc;
21024
21025 if (libsqlite3_so) {
21026 func = dlsym(libsqlite3_so, dls_nametab[i].name);
21027 }
21028 if (!func) {
21029 func = dls_nametab[i].func;
21030 }
21031 loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
21032 *loc = func;
21033 ++i;
21034 }
21035 if (!libsqlite3_so) {
21036 const char errmsg[] = "SQLite3 shared library not found.\n";
21037
21038 write(2, errmsg, sizeof (errmsg) - 1);
21039 }
21040}
21041
21042void
21043dls_fini(void)
21044{
21045 if (libsqlite3_so) {
21046 dlclose(libsqlite3_so);
21047 libsqlite3_so = 0;
21048 }
21049}
21050
21051#endif
21052
21053#endif
21054
21055/*
21056 * Local Variables:
21057 * mode: c
21058 * c-basic-offset: 4
21059 * fill-column: 78
21060 * tab-width: 8
21061 * End:
21062 */
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:3136
static COL procColSpec3[]
Definition: sqlite3odbc.c:8525
static SQLRETURN drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Internal get option of HSTMT.
Definition: sqlite3odbc.c:9242
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:7450
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:6684
static SQLRETURN nomem(STMT *s)
Report S1000 (out of memory) SQL error given STMT.
Definition: sqlite3odbc.c:1815
SQLRETURN SQL_API SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER buflen)
Set option on HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9624
static SQLRETURN setupparbuf(STMT *s, BINDPARM *p)
Setup parameter buffer for deferred parameter.
Definition: sqlite3odbc.c:5723
SQLRETURN SQL_API SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len, SQLINTEGER *lenp)
Get information of HENV.
Definition: sqlite3odbc.c:8623
SQLRETURN SQL_API SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SETSTMTOPTION_LAST_ARG_TYPE param)
Set option on HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9836
#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:9886
#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:3889
#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:6000
static SQLRETURN drvendtran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
Internal commit or rollback transaction.
Definition: sqlite3odbc.c:8238
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:2303
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:4304
#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:9697
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:7097
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:7514
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:5168
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:5925
static void convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
Convert julian day to hour/minute/second.
Definition: sqlite3odbc.c:3107
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:8484
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:5811
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:1948
#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:6021
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:8309
SQLRETURN SQL_API SQLNumParams(SQLHSTMT stmt, SQLSMALLINT *nparam)
Return number of parameters.
Definition: sqlite3odbc.c:5697
static const char * xdigits
Definition: sqlite3odbc.c:279
static COL scolSpec2[]
Columns for result set of SQLSpecialColumns().
Definition: sqlite3odbc.c:7057
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:1512
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:9166
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:1763
#define SET_EXISTS(x)
static COL procColSpec2[]
Columns for result set of SQLProcedureColumns().
Definition: sqlite3odbc.c:8503
static SQLRETURN drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
Internal set option on HSTMT.
Definition: sqlite3odbc.c:9737
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:8967
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:2859
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:7069
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:8384
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:9815
static int str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
Convert string to ODBC TIMESTAMP_STRUCT.
Definition: sqlite3odbc.c:3406
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:2096
#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:9415
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:9645
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:4736
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().
static void dbattas(DBC *d, char *attas)
Perform ATTACH commands to same database file.
Definition: sqlite3odbc.c:4263
#define WCHARSUPPORT
Definition: sqlite3odbc.c:185
static SQLRETURN noconn(STMT *s)
Report S1000 (not connected) SQL error given STMT.
Definition: sqlite3odbc.c:1828
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:6516
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:5143
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:8179
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:1910
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:8322
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:5876
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:6573
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:4850
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:9437
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:5757
SQLRETURN SQL_API SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
Put (partial) parameter data into executing statement.
Definition: sqlite3odbc.c:5127
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:9717
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:3927
SQLRETURN SQL_API SQLBrowseConnectW(SQLHDBC dbc, SQLWCHAR *connin, SQLSMALLINT conninLen, SQLWCHAR *connout, SQLSMALLINT connoutMax, SQLSMALLINT *connoutLen)
Function not implemented.
Definition: sqlite3odbc.c:4886
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:8058
static int s3stmt_step(STMT *s)
Do one sqlite statement step gathering one result row.
Definition: sqlite3odbc.c:4397
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:1844
static void s3stmt_drop(STMT *s)
Drop running sqlite statement in STMT.
Definition: sqlite3odbc.c:4715
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:8295
static char * unquote(char *str)
Strip quotes from quoted string in-place.
Definition: sqlite3odbc.c:1883
#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:6662
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:8889
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:5674
static void setstat(STMT *s, int naterr, char *msg, char *st,...)
Set error message and SQL state on statement.
Definition: sqlite3odbc.c:1730
#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:2179
#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:4908
SQLRETURN SQL_API SQLGetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
Get connect option of HDBC (UNICODE version).
static void replilike(char *sql)
Replace ILIKE with LIKE in-place given query string.
Definition: sqlite3odbc.c:2766
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:5895
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:6632
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:6653
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:5506
static void dbloadext(DBC *d, char *exts)
Load SQLite extension modules, if any.
Definition: sqlite3odbc.c:4185
static void blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function to import a BLOB from a file.
Definition: sqlite3odbc.c:3754
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:3285
static int getbool(char *string)
Get boolean flag from string.
Definition: sqlite3odbc.c:3738
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:8692
#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:9855
static int mapdeftype(int type, int stype, int nosign, int nowchar)
Map SQL_C_DEFAULT to proper C type.
Definition: sqlite3odbc.c:2388
static COL tableSpec3[]
static void freep(void *x)
Free memory given pointer to memory pointer.
Definition: sqlite3odbc.c:1800
static void blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function to export a BLOB to a file.
Definition: sqlite3odbc.c:3824
SQLRETURN SQL_API SQLFreeEnv(SQLHENV env)
Free HENV.
static int busy_handler(void *udata, int count)
Busy callback for SQLite.
Definition: sqlite3odbc.c:2021
SQLRETURN SQL_API SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno, SQLSMALLINT fieldid, SQLPOINTER value, SQLINTEGER buflen)
Function not implemented.
Definition: sqlite3odbc.c:5953
#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:8136
#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:5984
#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:2153
static COL tablePrivSpec3[]
Definition: sqlite3odbc.c:6073
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:7550
static void s3stmt_end_if(STMT *s)
Conditionally stop running sqlite statement.
Definition: sqlite3odbc.c:4697
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:8758
#define stringify(s)
Definition: sqlite3odbc.c:236
static void s3stmt_end(STMT *s)
Stop running sqlite statement.
Definition: sqlite3odbc.c:4669
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:6096
static COL tablePrivSpec2[]
Columns for result set of SQLTablePrivileges().
Definition: sqlite3odbc.c:6063
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:3971
#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:5645
static void dbtracerc(DBC *d, int rc, char *err)
Trace function for SQLite return codes.
Definition: sqlite3odbc.c:3947
static void convJD2YMD(double jd, DATE_STRUCT *ds)
Convert julian day to year/month/day.
Definition: sqlite3odbc.c:3079
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:7012
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:2527
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:2474
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:1782
static void setstatd(DBC *d, int naterr, char *msg, char *st,...)
Set error message and SQL state on DBC.
Definition: sqlite3odbc.c:1690
static COL colPrivSpec2[]
Columns for result set of SQLColumnPrivileges().
Definition: sqlite3odbc.c:6563
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:8596
#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:8419
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:4816
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:7497
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:2828
static int str2date(int jdconv, char *str, DATE_STRUCT *ds)
Convert string to ODBC DATE_STRUCT.
Definition: sqlite3odbc.c:3170
static COL procSpec3[]
Definition: sqlite3odbc.c:8430
#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:189
SQLINTEGER max
Max.
Definition: sqlite3odbc.h:191
SQLLEN * lenp
Value return, actual size of value buffer.
Definition: sqlite3odbc.h:192
SQLPOINTER valp
Value buffer.
Definition: sqlite3odbc.h:193
int offs
Byte offset for SQLGetData()
Definition: sqlite3odbc.h:195
SQLSMALLINT type
ODBC type.
Definition: sqlite3odbc.h:190
int index
Index of column in result.
Definition: sqlite3odbc.h:194
Internal structure for bound parameter (SQLBindParameter).
Definition: sqlite3odbc.h:204
double s3dval
SQLite3 float value.
Definition: sqlite3odbc.h:223
void * param0
Parameter buffer, initial value.
Definition: sqlite3odbc.h:211
int need
True when SQL_LEN_DATA_AT_EXEC.
Definition: sqlite3odbc.h:213
int s3type
SQLite3 type.
Definition: sqlite3odbc.h:218
int scale
from SQLBindParameter()
Definition: sqlite3odbc.h:206
int len
Offset/length for SQLParamData()/SQLPutData()
Definition: sqlite3odbc.h:215
void * param
Parameter buffer.
Definition: sqlite3odbc.h:210
void * parbuf
Buffer for SQL_LEN_DATA_AT_EXEC etc.
Definition: sqlite3odbc.h:216
int inc
Increment for paramset size > 1.
Definition: sqlite3odbc.h:212
SQLLEN * lenp0
Actual size of parameter buffer, initial value.
Definition: sqlite3odbc.h:209
void * s3val
SQLite3 value buffer.
Definition: sqlite3odbc.h:220
int coldef
Definition: sqlite3odbc.h:206
int stype
ODBC and SQL types.
Definition: sqlite3odbc.h:205
SQLLEN max
Max.
Definition: sqlite3odbc.h:207
char strbuf[64]
String buffer for scalar data.
Definition: sqlite3odbc.h:217
int bound
True when SQLBindParameter() called.
Definition: sqlite3odbc.h:214
sqlite_int64 s3lival
SQLite3 64bit integer value.
Definition: sqlite3odbc.h:222
int s3ival
SQLite3 integer value.
Definition: sqlite3odbc.h:221
SQLLEN * lenp
Actual size of parameter buffer.
Definition: sqlite3odbc.h:208
int s3size
SQLite3 size.
Definition: sqlite3odbc.h:219
Internal structure to describe a column in a result set.
Definition: sqlite3odbc.h:165
char * column
Column name.
Definition: sqlite3odbc.h:168
char * label
Column label or NULL.
Definition: sqlite3odbc.h:180
int nosign
Unsigned type.
Definition: sqlite3odbc.h:172
char * typename
Column type name or NULL.
Definition: sqlite3odbc.h:179
int notnull
NOT NULL constraint on column.
Definition: sqlite3odbc.h:176
int ispk
Flag for primary key (> 0)
Definition: sqlite3odbc.h:177
int prec
Precision of column.
Definition: sqlite3odbc.h:174
char * table
Table name.
Definition: sqlite3odbc.h:167
char * db
Database name.
Definition: sqlite3odbc.h:166
int type
Data type of column.
Definition: sqlite3odbc.h:169
int isrowid
Flag for ROWID column (> 0)
Definition: sqlite3odbc.h:178
int scale
Scale of column.
Definition: sqlite3odbc.h:173
int autoinc
AUTO_INCREMENT column.
Definition: sqlite3odbc.h:175
int size
Size of column.
Definition: sqlite3odbc.h:170
int index
Index of column in result.
Definition: sqlite3odbc.h:171
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:146
int s3stmt_needmeta
True to get meta data in s3stmt_step().
Definition: sqlite3odbc.h:144
int nowchar
Don't try to use WCHAR.
Definition: sqlite3odbc.h:131
struct stmt * cur_s3stmt
Current STMT executing sqlite statement.
Definition: sqlite3odbc.h:143
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:147
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:145
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 ilike
True for ILIKE fixup.
Definition: sqlite3odbc.h:142
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:232
SQLUSMALLINT * row_status0
Internal status array.
Definition: sqlite3odbc.h:269
int * ov3
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:237
SQLUSMALLINT row_status1
Internal status array for 1 row rowsets.
Definition: sqlite3odbc.h:270
BINDCOL * bindcols
Array of bound columns.
Definition: sqlite3odbc.h:249
int naterr
Native error code.
Definition: sqlite3odbc.h:260
SQLULEN * parm_bind_offs
SQL_ATTR_PARAM_BIND_OFFSET_PTR.
Definition: sqlite3odbc.h:280
int dcols
Number of entries in dyncols.
Definition: sqlite3odbc.h:245
SQLULEN bind_type
SQL_ATTR_ROW_BIND_TYPE.
Definition: sqlite3odbc.h:277
BINDCOL bkmrkcol
Bookmark bound column.
Definition: sqlite3odbc.h:248
int nbindparms
Number bound parameters.
Definition: sqlite3odbc.h:251
COL * dyncols
Column array, but malloc()ed.
Definition: sqlite3odbc.h:244
COL * cols
Result column array.
Definition: sqlite3odbc.h:243
int dobigint
Force SQL_BIGINT for INTEGER columns.
Definition: sqlite3odbc.h:264
int s3stmt_rownum
Current row number.
Definition: sqlite3odbc.h:288
SQLCHAR logmsg[1024]
Message for SQLError()
Definition: sqlite3odbc.h:262
int ncols
Number of result columns.
Definition: sqlite3odbc.h:242
SQLULEN * row_count
Row count pointer.
Definition: sqlite3odbc.h:271
SQLULEN paramset_count
Internal for paramset.
Definition: sqlite3odbc.h:274
SQLUSMALLINT * parm_oper
SQL_ATTR_PARAM_OPERATION_PTR.
Definition: sqlite3odbc.h:281
int nowchar[2]
Don't try to use WCHAR.
Definition: sqlite3odbc.h:263
int binlen
Length of blob data.
Definition: sqlite3odbc.h:291
int longnames
Don't shorten column names.
Definition: sqlite3odbc.h:265
SQLULEN parm_bind_type
SQL_ATTR_PARAM_BIND_TYPE.
Definition: sqlite3odbc.h:284
int guessed_types
Flag for drvprepare()/drvexecute()
Definition: sqlite3odbc.h:292
char * bincell
Cache for blob data.
Definition: sqlite3odbc.h:289
SQLCHAR cursorname[32]
Cursor name.
Definition: sqlite3odbc.h:235
int nrows
Number of result rows.
Definition: sqlite3odbc.h:255
SQLULEN paramset_size
SQL_ATTR_PARAMSET_SIZE.
Definition: sqlite3odbc.h:273
int bkmrk
True when bookmarks used.
Definition: sqlite3odbc.h:246
int * jdconv
True for julian day conversion.
Definition: sqlite3odbc.h:239
SQLULEN * parm_proc
SQL_ATTR_PARAMS_PROCESSED_PTR.
Definition: sqlite3odbc.h:283
sqlite3_stmt * s3stmt
SQLite statement handle or NULL.
Definition: sqlite3odbc.h:286
SQLULEN * bind_offs
SQL_ATTR_ROW_BIND_OFFSET_PTR.
Definition: sqlite3odbc.h:278
SQLULEN retr_data
SQL_ATTR_RETRIEVE_DATA.
Definition: sqlite3odbc.h:266
SQLULEN max_rows
SQL_ATTR_MAX_ROWS.
Definition: sqlite3odbc.h:276
HDBC dbc
Pointer to DBC.
Definition: sqlite3odbc.h:234
BINDPARM * bindparms
Array of bound parameters.
Definition: sqlite3odbc.h:252
int has_rowid
Flag for ROWID (>= 0 or -1)
Definition: sqlite3odbc.h:295
SQLUSMALLINT * parm_status
SQL_ATTR_PARAMS_STATUS_PTR.
Definition: sqlite3odbc.h:282
int one_tbl
Flag for single table (> 0)
Definition: sqlite3odbc.h:293
int curtype
Cursor type.
Definition: sqlite3odbc.h:285
int rowprs
Current start row of rowset.
Definition: sqlite3odbc.h:257
char ** rows
2-dim array, result set
Definition: sqlite3odbc.h:258
int isselect
‍0 if query is a SELECT statement
Definition: sqlite3odbc.h:241
int s3stmt_noreset
False when sqlite3_reset() needed.
Definition: sqlite3odbc.h:287
SQLULEN rowset_size
Size of rowset.
Definition: sqlite3odbc.h:267
int nparams
Number of parameters in query.
Definition: sqlite3odbc.h:253
SQLUINTEGER paramset_nrows
Row count for paramset handling.
Definition: sqlite3odbc.h:275
int nbindcols
Number of entries in bindcols.
Definition: sqlite3odbc.h:250
SQLCHAR * query
Current query, raw string.
Definition: sqlite3odbc.h:236
int * oemcp
True for Win32 OEM CP translation.
Definition: sqlite3odbc.h:238
int rowp
Current result row.
Definition: sqlite3odbc.h:256
char * bincache
Cache for blob data.
Definition: sqlite3odbc.h:290
int pdcount
SQLParamData() counter.
Definition: sqlite3odbc.h:254
SQLUSMALLINT * row_status
Row status pointer.
Definition: sqlite3odbc.h:268
int has_pk
Flag for primary key (> 0)
Definition: sqlite3odbc.h:294
char sqlstate[6]
SQL state for SQLError()
Definition: sqlite3odbc.h:261
struct stmt * next
Linkage for STMT list in DBC.
Definition: sqlite3odbc.h:233
int * ilike
True for ILIKE fixup.
Definition: sqlite3odbc.h:240
SQLULEN row_count0
Row count.
Definition: sqlite3odbc.h:272
void(* rowfree)()
Free function for rows.
Definition: sqlite3odbc.h:259
SQLINTEGER * bkmrkptr
SQL_ATTR_FETCH_BOOKMARK_PTR.
Definition: sqlite3odbc.h:247
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 Sun Nov 26 2023 by doxygen.
Contact: chw@ch-werner.de