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)
32 static void dls_init(void);
33 static void dls_fini(void);
34 #else
35 void dls_init(void);
36 void dls_fini(void);
37 #endif
38 
39 static 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 
272 typedef struct dstr {
273  int len;
274  int max;
275  int oom;
276  char buffer[1];
278 
279 static const char *xdigits = "0123456789ABCDEFabcdef";
280 
281 #ifdef MEMORY_DEBUG
282 
283 static void *
284 xmalloc_(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 
306 static void *
307 xrealloc_(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 
343 static void
344 xfree_(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 
369 static void
370 xfree__(void *x)
371 {
372  xfree_(x, "unknown location", 0);
373 }
374 
375 static char *
376 xstrdup_(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 
422 static 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)
433 static int strcasecmp_(const char *a, const char *b)
434  __attribute__((__unused__));
435 #endif
436 
437 static 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)
538 extern void nvfs_init(void);
539 extern const char *nvfs_makevfs(const char *);
540 #endif
541 
542 /*
543  * tolower() replacement w/o locale
544  */
545 
546 static const char upper_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
547 static const char lower_chars[] = "abcdefghijklmnopqrstuvwxyz";
548 
549 static int
550 TOLOWER(int c)
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 
566 static 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 
575 static 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 
585 static void dbtraceapi(DBC *d, char *fn, const char *sql);
586 static void freedyncols(STMT *s);
587 static void freeresult(STMT *s, int clrcols);
588 static void freerows(char **rowp);
589 static void unbindcols(STMT *s);
590 static void s3stmt_drop(STMT *s);
591 
592 static SQLRETURN drvexecute(SQLHSTMT stmt, int initial);
593 static SQLRETURN freestmt(HSTMT stmt);
594 static SQLRETURN mkbindcols(STMT *s, int ncols);
595 static SQLRETURN setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp);
596 static SQLRETURN setupparbuf(STMT *s, BINDPARM *p);
597 static SQLRETURN starttran(STMT *s);
598 static SQLRETURN setupparam(STMT *s, char *sql, int pnum);
599 static 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) */
605 static COL *statSpec2P, *statSpec3P;
606 #endif
607 
608 #if (MEMORY_DEBUG < 1)
609 
615 static char *
616 strdup_(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 
637 static dstr *
638 dsappend(dstr *dsp, const char *str)
639 {
640  int len;
641 
642  if (!str) {
643  return dsp;
644  }
645  len = strlen(str);
646  if (!dsp) {
647  int max = 256;
648 
649  if (max < len) {
650  max += len;
651  }
652  dsp = xmalloc(max);
653  if (dsp) {
654  dsp->max = max;
655  dsp->len = dsp->oom = 0;
656  goto copy;
657  }
658  return dsp;
659  }
660  if (dsp->oom) {
661  return dsp;
662  }
663  if (dsp->len + len > dsp->max) {
664  int max = dsp->max + len + 256;
665  dstr *ndsp = xrealloc(dsp, max);
666 
667  if (!ndsp) {
668  strcpy(dsp->buffer, "OUT OF MEMORY");
669  dsp->max = dsp->len = 13;
670  dsp->oom = 1;
671  return dsp;
672  }
673  dsp = ndsp;
674  dsp->max = max;
675  }
676 copy:
677  strcpy(dsp->buffer + dsp->len, str);
678  dsp->len += len;
679  return dsp;
680 }
681 
689 static dstr *
690 dsappendq(dstr *dsp, const char *str)
691 {
692  int len;
693  const char *p;
694  char *q;
695 
696  if (!str) {
697  return dsp;
698  }
699  len = strlen(str);
700  for (p = str; *p; ++p) {
701  if (p[0] == '"') {
702  ++len;
703  }
704  }
705  len += 2;
706  if (!dsp) {
707  int max = 256;
708 
709  if (max < len) {
710  max += len;
711  }
712  dsp = xmalloc(max);
713  if (dsp) {
714  dsp->max = max;
715  dsp->len = dsp->oom = 0;
716  goto copy;
717  }
718  return dsp;
719  }
720  if (dsp->oom) {
721  return dsp;
722  }
723  if (dsp->len + len > dsp->max) {
724  int max = dsp->max + len + 256;
725  dstr *ndsp = xrealloc(dsp, max);
726 
727  if (!ndsp) {
728  strcpy(dsp->buffer, "OUT OF MEMORY");
729  dsp->max = dsp->len = 13;
730  dsp->oom = 1;
731  return dsp;
732  }
733  dsp = ndsp;
734  dsp->max = max;
735  }
736 copy:
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 
757 static const char *
758 dsval(dstr *dsp)
759 {
760  if (dsp) {
761  return (const char *) dsp->buffer;
762  }
763  return "ERROR";
764 }
765 
772 static int
773 dserr(dstr *dsp)
774 {
775  return !dsp || dsp->oom;
776 }
777 
783 static void
785 {
786  if (dsp) {
787  xfree(dsp);
788  }
789 }
790 
791 #ifdef WCHARSUPPORT
792 
799 static int
800 uc_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 
821 static SQLWCHAR *
822 uc_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 
847 static void
848 uc_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 
931 static SQLWCHAR *
932 uc_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 
957 static char *
958 uc_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 
1027 static char *
1028 uc_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 
1045 static void
1046 uc_free(void *str)
1047 {
1048  if (str) {
1049  xfree(str);
1050  }
1051 }
1052 
1053 #endif
1054 
1055 #if defined(_WIN32) || defined(_WIN64)
1056 
1064 static char *
1065 wmb_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 
1106 static char *
1107 wmb_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 
1124 static char *
1125 utf_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 
1166 static WCHAR *
1167 wmb_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 
1197 static char *
1198 uc_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 
1239 static void
1240 drvgetgpps(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 
1269 static void
1270 drvrelgpps(DBC *d)
1271 {
1272  if (d->instlib) {
1273  dlclose(d->instlib);
1274  d->instlib = 0;
1275  }
1276 }
1277 
1278 static int
1279 drvgpps(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 
1299 static void
1300 s3bind(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 
1374 typedef struct tblres {
1375  char **resarr;
1376  char *errmsg;
1377  sqlite3_stmt *stmt;
1378  STMT *s;
1379  int nalloc;
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 
1391 static int
1392 drvgettable_row(TBLRES *t, int ncol, int rc)
1393 {
1394  int need;
1395  int i;
1396  char *p;
1397 
1398  if (t->nrow == 0 && rc == SQLITE_ROW) {
1399  need = ncol * 2;
1400  } else {
1401  need = ncol;
1402  }
1403  if (t->ndata + need >= t->nalloc) {
1404  char **resnew;
1405  int nalloc = t->nalloc * 2 + need + 1;
1406 
1407  resnew = xrealloc(t->resarr, sizeof (char *) * nalloc);
1408  if (!resnew) {
1409 nomem:
1410  t->rc = SQLITE_NOMEM;
1411  return 1;
1412  }
1413  t->nalloc = nalloc;
1414  t->resarr = resnew;
1415  }
1416  /* column names when first row */
1417  if (t->nrow == 0) {
1418  t->ncol = ncol;
1419  for (i = 0; i < ncol; i++) {
1420  p = (char *) sqlite3_column_name(t->stmt, i);
1421  if (p) {
1422  char *q = xmalloc(strlen(p) + 1);
1423 
1424  if (!q) {
1425  goto nomem;
1426  }
1427  strcpy(q, p);
1428  p = q;
1429  }
1430  t->resarr[t->ndata++] = p;
1431  }
1432  if (t->s && t->s->guessed_types) {
1433  int ncol2 = ncol;
1434 
1435  setupdyncols(t->s, t->stmt, &ncol2);
1436  t->s->guessed_types = 0;
1437  t->s->ncols = ncol;
1438  }
1439  } else if (t->ncol != ncol) {
1440  t->errmsg = sqlite3_mprintf("drvgettable() called with two or"
1441  " more incompatible queries");
1442  t->rc = SQLITE_ERROR;
1443  return 1;
1444  }
1445  /* copy row data */
1446  if (rc == SQLITE_ROW) {
1447  for (i = 0; i < ncol; i++) {
1448  int coltype = sqlite3_column_type(t->stmt, i);
1449 
1450  p = NULL;
1451  if (coltype == SQLITE_BLOB) {
1452  int k, nbytes = sqlite3_column_bytes(t->stmt, i);
1453  char *qp;
1454  unsigned const char *bp;
1455 
1456  bp = sqlite3_column_blob(t->stmt, i);
1457  qp = xmalloc(nbytes * 2 + 4);
1458  if (!qp) {
1459  goto nomem;
1460  }
1461  p = qp;
1462  *qp++ = 'X';
1463  *qp++ = '\'';
1464  for (k = 0; k < nbytes; k++) {
1465  *qp++ = xdigits[(bp[k] >> 4)];
1466  *qp++ = xdigits[(bp[k] & 0xF)];
1467  }
1468  *qp++ = '\'';
1469  *qp = '\0';
1470 #ifdef _MSC_VER
1471  } else if (coltype == SQLITE_FLOAT) {
1472  struct lconv *lc = 0;
1473  double val = sqlite3_column_double(t->stmt, i);
1474  char buffer[128];
1475 
1476  /*
1477  * This avoids floating point rounding
1478  * and formatting problems of some SQLite
1479  * versions in conjunction with MSVC 2010.
1480  */
1481  snprintf(buffer, sizeof (buffer), "%.15g", val);
1482  lc = localeconv();
1483  if (lc && lc->decimal_point && lc->decimal_point[0] &&
1484  lc->decimal_point[0] != '.') {
1485  p = strchr(buffer, lc->decimal_point[0]);
1486  if (p) {
1487  *p = '.';
1488  }
1489  }
1490  p = xstrdup(buffer);
1491  if (!p) {
1492  goto nomem;
1493  }
1494 #endif
1495  } else if (coltype != SQLITE_NULL) {
1496  p = xstrdup((char *) sqlite3_column_text(t->stmt, i));
1497  if (!p) {
1498  goto nomem;
1499  }
1500  }
1501  t->resarr[t->ndata++] = p;
1502  }
1503  t->nrow++;
1504  }
1505  return 0;
1506 }
1507 
1508 static int
1509 drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp,
1510  int *ncolp, char **errp, int nparam, BINDPARM *p)
1511 {
1512  DBC *d = (DBC *) s->dbc;
1513  int rc = SQLITE_OK, keep = sql == NULL;
1514  TBLRES tres;
1515  const char *sqlleft = 0;
1516  int nretry = 0, haveerr = 0;
1517 
1518  if (!resp) {
1519  return SQLITE_ERROR;
1520  }
1521  *resp = NULL;
1522  if (nrowp) {
1523  *nrowp = 0;
1524  }
1525  if (ncolp) {
1526  *ncolp = 0;
1527  }
1528  tres.errmsg = NULL;
1529  tres.nrow = 0;
1530  tres.ncol = 0;
1531  tres.ndata = 1;
1532  tres.nalloc = 20;
1533  tres.rc = SQLITE_OK;
1534  tres.resarr = xmalloc(sizeof (char *) * tres.nalloc);
1535  tres.stmt = NULL;
1536  tres.s = s;
1537  if (!tres.resarr) {
1538  return SQLITE_NOMEM;
1539  }
1540  tres.resarr[0] = 0;
1541  if (sql == NULL) {
1542  tres.stmt = s->s3stmt;
1543  if (tres.stmt == NULL) {
1544  return SQLITE_NOMEM;
1545  }
1546  goto retrieve;
1547  }
1548  while (sql && *sql && (rc == SQLITE_OK ||
1549  (rc == SQLITE_SCHEMA && (++nretry) < 2))) {
1550  int ncol;
1551 
1552  tres.stmt = NULL;
1553 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
1554  dbtraceapi(d, "sqlite3_prepare_v2", sql);
1555  rc = sqlite3_prepare_v2(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
1556 #else
1557  dbtraceapi(d, "sqlite3_prepare", sql);
1558  rc = sqlite3_prepare(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
1559 #endif
1560  if (rc != SQLITE_OK) {
1561  if (tres.stmt) {
1562  dbtraceapi(d, "sqlite3_finalize", 0);
1563  sqlite3_finalize(tres.stmt);
1564  tres.stmt = NULL;
1565  }
1566  continue;
1567  }
1568  if (!tres.stmt) {
1569  /* this happens for a comment or white-space */
1570  sql = sqlleft;
1571  continue;
1572  }
1573 retrieve:
1574  if (sqlite3_bind_parameter_count(tres.stmt) != nparam) {
1575  if (errp) {
1576  *errp =
1577  sqlite3_mprintf("%s", "parameter marker count incorrect");
1578  }
1579  haveerr = 1;
1580  rc = SQLITE_ERROR;
1581  goto tbldone;
1582  }
1583  s3bind(d, tres.stmt, nparam, p);
1584  ncol = sqlite3_column_count(tres.stmt);
1585  while (1) {
1586  if (s->max_rows && tres.nrow >= s->max_rows) {
1587  rc = SQLITE_OK;
1588  break;
1589  }
1590  rc = sqlite3_step(tres.stmt);
1591  if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
1592  if (drvgettable_row(&tres, ncol, rc)) {
1593  rc = SQLITE_ABORT;
1594  goto tbldone;
1595  }
1596  }
1597  if (rc != SQLITE_ROW) {
1598  if (keep) {
1599  dbtraceapi(d, "sqlite3_reset", 0);
1600  rc = sqlite3_reset(tres.stmt);
1601  s->s3stmt_noreset = 1;
1602  } else {
1603  dbtraceapi(d, "sqlite3_finalize", 0);
1604  rc = sqlite3_finalize(tres.stmt);
1605  }
1606  tres.stmt = 0;
1607  if (rc != SQLITE_SCHEMA) {
1608  nretry = 0;
1609  sql = sqlleft;
1610  while (sql && ISSPACE(*sql)) {
1611  sql++;
1612  }
1613  }
1614  if (rc == SQLITE_DONE) {
1615  rc = SQLITE_OK;
1616  }
1617  break;
1618  }
1619  }
1620  }
1621 tbldone:
1622  if (tres.stmt) {
1623  if (keep) {
1624  if (!s->s3stmt_noreset) {
1625  dbtraceapi(d, "sqlite3_reset", 0);
1626  sqlite3_reset(tres.stmt);
1627  s->s3stmt_noreset = 1;
1628  }
1629  } else {
1630  dbtraceapi(d, "sqlite3_finalize", 0);
1631  sqlite3_finalize(tres.stmt);
1632  }
1633  }
1634  if (haveerr) {
1635  /* message already in *errp if any */
1636  } else if (rc != SQLITE_OK && rc == sqlite3_errcode(d->sqlite) && errp) {
1637  *errp = sqlite3_mprintf("%s", sqlite3_errmsg(d->sqlite));
1638  } else if (errp) {
1639  *errp = NULL;
1640  }
1641  if (tres.resarr) {
1642  tres.resarr[0] = (char *) (tres.ndata - 1);
1643  }
1644  if (rc == SQLITE_ABORT) {
1645  freerows(&tres.resarr[1]);
1646  if (tres.errmsg) {
1647  if (errp) {
1648  if (*errp) {
1649  sqlite3_free(*errp);
1650  }
1651  *errp = tres.errmsg;
1652  } else {
1653  sqlite3_free(tres.errmsg);
1654  }
1655  }
1656  return tres.rc;
1657  }
1658  sqlite3_free(tres.errmsg);
1659  if (rc != SQLITE_OK) {
1660  freerows(&tres.resarr[1]);
1661  return rc;
1662  }
1663  *resp = &tres.resarr[1];
1664  if (ncolp) {
1665  *ncolp = tres.ncol;
1666  }
1667  if (nrowp) {
1668  *nrowp = tres.nrow;
1669  }
1670  return rc;
1671 }
1672 
1681 #if defined(__GNUC__) && (__GNUC__ >= 2)
1682 static void setstatd(DBC *, int, char *, char *, ...)
1683  __attribute__((format (printf, 3, 5)));
1684 #endif
1685 
1686 static void
1687 setstatd(DBC *d, int naterr, char *msg, char *st, ...)
1688 {
1689  va_list ap;
1690 
1691  if (!d) {
1692  return;
1693  }
1694  d->naterr = naterr;
1695  d->logmsg[0] = '\0';
1696  if (msg) {
1697  int count;
1698 
1699  va_start(ap, st);
1700  count = vsnprintf((char *) d->logmsg, sizeof (d->logmsg), msg, ap);
1701  va_end(ap);
1702  if (count < 0) {
1703  d->logmsg[sizeof (d->logmsg) - 1] = '\0';
1704  }
1705  }
1706  if (!st) {
1707  st = "?????";
1708  }
1709  strncpy(d->sqlstate, st, 5);
1710  d->sqlstate[5] = '\0';
1711 }
1712 
1721 #if defined(__GNUC__) && (__GNUC__ >= 2)
1722 static void setstat(STMT *, int, char *, char *, ...)
1723  __attribute__((format (printf, 3, 5)));
1724 #endif
1725 
1726 static void
1727 setstat(STMT *s, int naterr, char *msg, char *st, ...)
1728 {
1729  va_list ap;
1730 
1731  if (!s) {
1732  return;
1733  }
1734  s->naterr = naterr;
1735  s->logmsg[0] = '\0';
1736  if (msg) {
1737  int count;
1738 
1739  va_start(ap, st);
1740  count = vsnprintf((char *) s->logmsg, sizeof (s->logmsg), msg, ap);
1741  va_end(ap);
1742  if (count < 0) {
1743  s->logmsg[sizeof (s->logmsg) - 1] = '\0';
1744  }
1745  }
1746  if (!st) {
1747  st = "?????";
1748  }
1749  strncpy(s->sqlstate, st, 5);
1750  s->sqlstate[5] = '\0';
1751 }
1752 
1759 static SQLRETURN
1761 {
1762  DBC *d;
1763 
1764  if (dbc == SQL_NULL_HDBC) {
1765  return SQL_INVALID_HANDLE;
1766  }
1767  d = (DBC *) dbc;
1768  setstatd(d, -1, "not supported", "IM001");
1769  return SQL_ERROR;
1770 }
1771 
1778 static SQLRETURN
1780 {
1781  STMT *s;
1782 
1783  if (stmt == SQL_NULL_HSTMT) {
1784  return SQL_INVALID_HANDLE;
1785  }
1786  s = (STMT *) stmt;
1787  setstat(s, -1, "not supported", "IM001");
1788  return SQL_ERROR;
1789 }
1790 
1796 static void
1797 freep(void *x)
1798 {
1799  if (x && ((char **) x)[0]) {
1800  xfree(((char **) x)[0]);
1801  ((char **) x)[0] = NULL;
1802  }
1803 }
1804 
1811 static SQLRETURN
1813 {
1814  setstat(s, -1, "out of memory", (*s->ov3) ? "HY000" : "S1000");
1815  return SQL_ERROR;
1816 }
1817 
1824 static SQLRETURN
1826 {
1827  setstat(s, -1, "not connected", (*s->ov3) ? "HY000" : "S1000");
1828  return SQL_ERROR;
1829 }
1830 
1838 #if defined(HAVE_LOCALECONV) || defined(_WIN32) || defined(_WIN64)
1839 
1840 static double
1841 ln_strtod(const char *data, char **endp)
1842 {
1843  struct lconv *lc = 0;
1844  char buf[128], *p, *end;
1845  double value;
1846 
1847  lc = localeconv();
1848  if (lc && lc->decimal_point && lc->decimal_point[0] &&
1849  lc->decimal_point[0] != '.') {
1850  strncpy(buf, data, sizeof (buf) - 1);
1851  buf[sizeof (buf) - 1] = '\0';
1852  p = strchr(buf, '.');
1853  if (p) {
1854  *p = lc->decimal_point[0];
1855  }
1856  p = buf;
1857  } else {
1858  p = (char *) data;
1859  }
1860  value = strtod(p, &end);
1861  end = (char *) data + (end - p);
1862  if (endp) {
1863  *endp = end;
1864  }
1865  return value;
1866 }
1867 
1868 #else
1869 
1870 #define ln_strtod(A,B) strtod(A,B)
1871 
1872 #endif
1873 
1879 static char *
1880 unquote(char *str)
1881 {
1882  if (str) {
1883  int len = strlen(str);
1884 
1885  if (len > 1) {
1886  int end = len - 1;
1887 
1888  if ((str[0] == '\'' && str[end] == '\'') ||
1889  (str[0] == '"' && str[end] == '"') ||
1890  (str[0] == '[' && str[end] == ']')) {
1891  memmove(str, str + 1, end - 1);
1892  str[end - 1] = '\0';
1893  }
1894  }
1895  }
1896  return str;
1897 }
1898 
1906 static int
1907 unescpat(char *str)
1908 {
1909  char *p, *q;
1910  int count = 0;
1911 
1912  p = str;
1913  while ((q = strchr(p, '_')) != NULL) {
1914  if (q == str || q[-1] != '\\') {
1915  count++;
1916  }
1917  p = q + 1;
1918  }
1919  p = str;
1920  while ((q = strchr(p, '%')) != NULL) {
1921  if (q == str || q[-1] != '\\') {
1922  count++;
1923  }
1924  p = q + 1;
1925  }
1926  p = str;
1927  while ((q = strchr(p, '\\')) != NULL) {
1928  if (q[1] == '\\' || q[1] == '_' || q[1] == '%') {
1929  memmove(q, q + 1, strlen(q));
1930  }
1931  p = q + 1;
1932  }
1933  return count;
1934 }
1935 
1944 static int
1945 namematch(char *str, char *pat, int esc)
1946 {
1947  int cp, ch;
1948 
1949  while (1) {
1950  cp = TOLOWER(*pat);
1951  if (cp == '\0') {
1952  if (*str != '\0') {
1953  goto nomatch;
1954  }
1955  break;
1956  }
1957  if (*str == '\0' && cp != '%') {
1958  goto nomatch;
1959  }
1960  if (cp == '%') {
1961  while (*pat == '%') {
1962  ++pat;
1963  }
1964  cp = TOLOWER(*pat);
1965  if (cp == '\0') {
1966  break;
1967  }
1968  while (1) {
1969  if (cp != '_' && cp != '\\') {
1970  while (*str) {
1971  ch = TOLOWER(*str);
1972  if (ch == cp) {
1973  break;
1974  }
1975  ++str;
1976  }
1977  }
1978  if (namematch(str, pat, esc)) {
1979  goto match;
1980  }
1981  if (*str == '\0') {
1982  goto nomatch;
1983  }
1984  ch = TOLOWER(*str);
1985  ++str;
1986  }
1987  }
1988  if (cp == '_') {
1989  pat++;
1990  str++;
1991  continue;
1992  }
1993  if (esc && cp == '\\' &&
1994  (pat[1] == '\\' || pat[1] == '%' || pat[1] == '_')) {
1995  ++pat;
1996  cp = TOLOWER(*pat);
1997  }
1998  ch = TOLOWER(*str++);
1999  ++pat;
2000  if (ch != cp) {
2001  goto nomatch;
2002  }
2003  }
2004 match:
2005  return 1;
2006 nomatch:
2007  return 0;
2008 }
2009 
2017 static int
2018 busy_handler(void *udata, int count)
2019 {
2020  DBC *d = (DBC *) udata;
2021  long t1;
2022  int ret = 0;
2023 #if !defined(_WIN32) && !defined(_WIN64)
2024  struct timeval tv;
2025 #ifdef HAVE_NANOSLEEP
2026  struct timespec ts;
2027 #endif
2028 #endif
2029 
2030  if (d->busyint) {
2031  d->busyint = 0;
2032  return ret;
2033  }
2034  if (d->timeout <= 0) {
2035  return ret;
2036  }
2037  if (count <= 1) {
2038 #if defined(_WIN32) || defined(_WIN64)
2039  d->t0 = GetTickCount();
2040 #else
2041  gettimeofday(&tv, NULL);
2042  d->t0 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
2043 #endif
2044  }
2045 #if defined(_WIN32) || defined(_WIN64)
2046  t1 = GetTickCount();
2047 #else
2048  gettimeofday(&tv, NULL);
2049  t1 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
2050 #endif
2051  if (t1 - d->t0 > d->timeout) {
2052  goto done;
2053  }
2054 #if defined(_WIN32) || defined(_WIN64)
2055  Sleep(10);
2056 #else
2057 #ifdef HAVE_NANOSLEEP
2058  ts.tv_sec = 0;
2059  ts.tv_nsec = 10000000;
2060  do {
2061  ret = nanosleep(&ts, &ts);
2062  if (ret < 0 && errno != EINTR) {
2063  ret = 0;
2064  }
2065  } while (ret);
2066 #else
2067 #ifdef HAVE_USLEEP
2068  usleep(10000);
2069 #else
2070  tv.tv_sec = 0;
2071  tv.tv_usec = 10000;
2072  select(0, NULL, NULL, NULL, &tv);
2073 #endif
2074 #endif
2075 #endif
2076  ret = 1;
2077 done:
2078  return ret;
2079 }
2080 
2092 static int
2093 setsqliteopts(sqlite3 *x, DBC *d)
2094 {
2095  int count = 0, step = 0, max, rc = SQLITE_ERROR;
2096 
2097 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
2098  max = d->longnames ? 3 : 1;
2099 #else
2100  max = 3;
2101 #endif
2102  if (d->shortnames) {
2103  max = 3;
2104  }
2105  while (step < max) {
2106  if (step < 1) {
2107  rc = sqlite3_exec(x, "PRAGMA empty_result_callbacks = on;",
2108  NULL, NULL, NULL);
2109  if (rc == SQLITE_OK) {
2110  rc = sqlite3_exec(x, d->fksupport ?
2111  "PRAGMA foreign_keys = on;" :
2112  "PRAGMA foreign_keys = off;",
2113  NULL, NULL, NULL);
2114  }
2115  } else if (step < 2) {
2116  rc = sqlite3_exec(x, d->shortnames ?
2117  "PRAGMA full_column_names = off;" :
2118  "PRAGMA full_column_names = on;",
2119  NULL, NULL, NULL);
2120  } else if (step < 3) {
2121  rc = sqlite3_exec(x, d->shortnames ?
2122  "PRAGMA short_column_names = on;" :
2123  "PRAGMA short_column_names = off;",
2124  NULL, NULL, NULL);
2125  }
2126  if (rc != SQLITE_OK) {
2127  if (rc != SQLITE_BUSY ||
2128  !busy_handler((void *) d, ++count)) {
2129  return rc;
2130  }
2131  continue;
2132  }
2133  count = 0;
2134  ++step;
2135  }
2136  sqlite3_busy_handler(x, busy_handler, (void *) d);
2137  return SQLITE_OK;
2138 }
2139 
2149 static void
2150 freerows(char **rowp)
2151 {
2152  PTRDIFF_T size, i;
2153 
2154  if (!rowp) {
2155  return;
2156  }
2157  --rowp;
2158  size = (PTRDIFF_T) rowp[0];
2159  for (i = 1; i <= size; i++) {
2160  freep(&rowp[i]);
2161  }
2162  freep(&rowp);
2163 }
2164 
2175 static int
2176 mapsqltype(const char *typename, int *nosign, int ov3, int nowchar,
2177  int dobigint)
2178 {
2179  char *p, *q;
2180  int testsign = 0, result;
2181 
2182 #ifdef WINTERFACE
2183  result = nowchar ? SQL_VARCHAR : SQL_WVARCHAR;
2184 #else
2185  result = SQL_VARCHAR;
2186 #endif
2187  if (!typename) {
2188  return result;
2189  }
2190  q = p = xmalloc(strlen(typename) + 1);
2191  if (!p) {
2192  return result;
2193  }
2194  strcpy(p, typename);
2195  while (*q) {
2196  *q = TOLOWER(*q);
2197  ++q;
2198  }
2199  if (strncmp(p, "inter", 5) == 0) {
2200  } else if (strncmp(p, "int", 3) == 0 ||
2201  strncmp(p, "mediumint", 9) == 0) {
2202  testsign = 1;
2203  result = SQL_INTEGER;
2204  } else if (strncmp(p, "numeric", 7) == 0) {
2205  result = SQL_DOUBLE;
2206  } else if (strncmp(p, "tinyint", 7) == 0) {
2207  testsign = 1;
2208  result = SQL_TINYINT;
2209  } else if (strncmp(p, "smallint", 8) == 0) {
2210  testsign = 1;
2211  result = SQL_SMALLINT;
2212  } else if (strncmp(p, "float", 5) == 0) {
2213  result = SQL_DOUBLE;
2214  } else if (strncmp(p, "double", 6) == 0 ||
2215  strncmp(p, "real", 4) == 0) {
2216  result = SQL_DOUBLE;
2217  } else if (strncmp(p, "timestamp", 9) == 0) {
2218 #ifdef SQL_TYPE_TIMESTAMP
2219  result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
2220 #else
2221  result = SQL_TIMESTAMP;
2222 #endif
2223  } else if (strncmp(p, "datetime", 8) == 0) {
2224 #ifdef SQL_TYPE_TIMESTAMP
2225  result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
2226 #else
2227  result = SQL_TIMESTAMP;
2228 #endif
2229  } else if (strncmp(p, "time", 4) == 0) {
2230 #ifdef SQL_TYPE_TIME
2231  result = ov3 ? SQL_TYPE_TIME : SQL_TIME;
2232 #else
2233  result = SQL_TIME;
2234 #endif
2235  } else if (strncmp(p, "date", 4) == 0) {
2236 #ifdef SQL_TYPE_DATE
2237  result = ov3 ? SQL_TYPE_DATE : SQL_DATE;
2238 #else
2239  result = SQL_DATE;
2240 #endif
2241 #ifdef SQL_LONGVARCHAR
2242  } else if (strncmp(p, "text", 4) == 0 ||
2243  strncmp(p, "memo", 4) == 0 ||
2244  strncmp(p, "longvarchar", 11) == 0) {
2245 #ifdef WINTERFACE
2246  result = nowchar ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
2247 #else
2248  result = SQL_LONGVARCHAR;
2249 #endif
2250 #ifdef WINTERFACE
2251  } else if (strncmp(p, "wtext", 5) == 0 ||
2252  strncmp(p, "wvarchar", 8) == 0 ||
2253  strncmp(p, "longwvarchar", 12) == 0) {
2254  result = SQL_WLONGVARCHAR;
2255 #endif
2256 #endif
2257 #ifdef SQL_BIT
2258  } else if (strncmp(p, "bool", 4) == 0 ||
2259  strncmp(p, "bit", 3) == 0) {
2260  result = SQL_BIT;
2261 #endif
2262 #ifdef SQL_BIGINT
2263  } else if (strncmp(p, "bigint", 6) == 0) {
2264  testsign = 1;
2265  result = SQL_BIGINT;
2266 #endif
2267  } else if (strncmp(p, "blob", 4) == 0) {
2268  result = SQL_BINARY;
2269  } else if (strncmp(p, "varbinary", 9) == 0) {
2270  result = SQL_VARBINARY;
2271  } else if (strncmp(p, "longvarbinary", 13) == 0) {
2272  result = SQL_LONGVARBINARY;
2273  }
2274  if (nosign) {
2275  if (testsign) {
2276  *nosign = strstr(p, "unsigned") != NULL;
2277  } else {
2278  *nosign = 1;
2279  }
2280  }
2281 #ifdef SQL_BIGINT
2282  if (dobigint && result == SQL_INTEGER) {
2283  result = SQL_BIGINT;
2284  }
2285 #endif
2286  xfree(p);
2287  return result;
2288 }
2289 
2299 static void
2300 getmd(const char *typename, int sqltype, int *mp, int *dp)
2301 {
2302  int m = 0, d = 0;
2303 
2304  switch (sqltype) {
2305  case SQL_INTEGER: m = 10; d = 9; break;
2306  case SQL_TINYINT: m = 4; d = 3; break;
2307  case SQL_SMALLINT: m = 6; d = 5; break;
2308  case SQL_FLOAT: m = 25; d = 24; break;
2309  case SQL_DOUBLE: m = 54; d = 53; break;
2310  case SQL_VARCHAR: m = 255; d = 0; break;
2311 #ifdef WINTERFACE
2312 #ifdef SQL_WVARCHAR
2313  case SQL_WVARCHAR: m = 255; d = 0; break;
2314 #endif
2315 #endif
2316 #ifdef SQL_TYPE_DATE
2317  case SQL_TYPE_DATE:
2318 #endif
2319  case SQL_DATE: m = 10; d = 0; break;
2320 #ifdef SQL_TYPE_TIME
2321  case SQL_TYPE_TIME:
2322 #endif
2323  case SQL_TIME: m = 8; d = 0; break;
2324 #ifdef SQL_TYPE_TIMESTAMP
2325  case SQL_TYPE_TIMESTAMP:
2326 #endif
2327  case SQL_TIMESTAMP: m = 32; d = 3; break;
2328 #ifdef SQL_LONGVARCHAR
2329  case SQL_LONGVARCHAR : m = 65536; d = 0; break;
2330 #endif
2331 #ifdef WINTERFACE
2332 #ifdef SQL_WLONGVARCHAR
2333  case SQL_WLONGVARCHAR: m = 65536; d = 0; break;
2334 #endif
2335 #endif
2336  case SQL_BINARY:
2337  case SQL_VARBINARY: m = 255; d = 0; break;
2338  case SQL_LONGVARBINARY: m = 65536; d = 0; break;
2339 #ifdef SQL_BIGINT
2340  case SQL_BIGINT: m = 20; d = 19; break;
2341 #endif
2342 #ifdef SQL_BIT
2343  case SQL_BIT: m = 1; d = 1; break;
2344 #endif
2345  }
2346  if (m && typename) {
2347  int mm, dd;
2348  char clbr[4];
2349 
2350  if (sscanf(typename, "%*[^(](%d,%d %1[)]", &mm, &dd, clbr) == 3) {
2351  m = mm;
2352  d = dd;
2353  } else if (sscanf(typename, "%*[^(](%d %1[)]", &mm, clbr) == 2) {
2354  if (sqltype == SQL_TIMESTAMP) {
2355  d = mm;
2356  }
2357 #ifdef SQL_TYPE_TIMESTAMP
2358  else if (sqltype == SQL_TYPE_TIMESTAMP) {
2359  d = mm;
2360  }
2361 #endif
2362  else {
2363  m = d = mm;
2364  }
2365  }
2366  }
2367  if (mp) {
2368  *mp = m;
2369  }
2370  if (dp) {
2371  *dp = d;
2372  }
2373 }
2374 
2384 static int
2385 mapdeftype(int type, int stype, int nosign, int nowchar)
2386 {
2387  if (type == SQL_C_DEFAULT) {
2388  switch (stype) {
2389  case SQL_INTEGER:
2390  type = (nosign > 0) ? SQL_C_ULONG : SQL_C_LONG;
2391  break;
2392  case SQL_TINYINT:
2393  type = (nosign > 0) ? SQL_C_UTINYINT : SQL_C_TINYINT;
2394  break;
2395  case SQL_SMALLINT:
2396  type = (nosign > 0) ? SQL_C_USHORT : SQL_C_SHORT;
2397  break;
2398  case SQL_FLOAT:
2399  type = SQL_C_FLOAT;
2400  break;
2401  case SQL_DOUBLE:
2402  type = SQL_C_DOUBLE;
2403  break;
2404  case SQL_TIMESTAMP:
2405  type = SQL_C_TIMESTAMP;
2406  break;
2407  case SQL_TIME:
2408  type = SQL_C_TIME;
2409  break;
2410  case SQL_DATE:
2411  type = SQL_C_DATE;
2412  break;
2413 #ifdef SQL_C_TYPE_TIMESTAMP
2414  case SQL_TYPE_TIMESTAMP:
2415  type = SQL_C_TYPE_TIMESTAMP;
2416  break;
2417 #endif
2418 #ifdef SQL_C_TYPE_TIME
2419  case SQL_TYPE_TIME:
2420  type = SQL_C_TYPE_TIME;
2421  break;
2422 #endif
2423 #ifdef SQL_C_TYPE_DATE
2424  case SQL_TYPE_DATE:
2425  type = SQL_C_TYPE_DATE;
2426  break;
2427 #endif
2428 #ifdef WINTERFACE
2429  case SQL_WVARCHAR:
2430  case SQL_WCHAR:
2431 #ifdef SQL_WLONGVARCHAR
2432  case SQL_WLONGVARCHAR:
2433 #endif
2434  type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
2435  break;
2436 #endif
2437  case SQL_BINARY:
2438  case SQL_VARBINARY:
2439  case SQL_LONGVARBINARY:
2440  type = SQL_C_BINARY;
2441  break;
2442 #ifdef SQL_BIT
2443  case SQL_BIT:
2444  type = SQL_C_BIT;
2445  break;
2446 #endif
2447 #ifdef SQL_BIGINT
2448  case SQL_BIGINT:
2449  type = SQL_C_CHAR;
2450  break;
2451 #endif
2452  default:
2453 #ifdef WINTERFACE
2454  type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
2455 #else
2456  type = SQL_C_CHAR;
2457 #endif
2458  break;
2459  }
2460  }
2461  return type;
2462 }
2463 
2470 static int
2471 checkddl(char *sql)
2472 {
2473  int isddl = 0;
2474 
2475  while (*sql && ISSPACE(*sql)) {
2476  ++sql;
2477  }
2478  if (*sql && *sql != ';') {
2479  int i, size;
2480  static const struct {
2481  int len;
2482  const char *str;
2483  } ddlstr[] = {
2484  { 5, "alter" },
2485  { 7, "analyze" },
2486  { 6, "attach" },
2487  { 5, "begin" },
2488  { 6, "commit" },
2489  { 6, "create" },
2490  { 6, "detach" },
2491  { 4, "drop" },
2492  { 3, "end" },
2493  { 7, "reindex" },
2494  { 7, "release" },
2495  { 8, "rollback" },
2496  { 9, "savepoint" },
2497  { 6, "vacuum" }
2498  };
2499 
2500  size = strlen(sql);
2501  for (i = 0; i < array_size(ddlstr); i++) {
2502  if (size >= ddlstr[i].len &&
2503  strncasecmp(sql, ddlstr[i].str, ddlstr[i].len) == 0) {
2504  isddl = 1;
2505  break;
2506  }
2507  }
2508  }
2509  return isddl;
2510 }
2511 
2523 static char *
2524 fixupsql(char *sql, int sqlLen, int cte, int *nparam, int *isselect,
2525  char **errmsg)
2526 {
2527  char *q = sql, *qz = NULL, *p, *inq = NULL, *out;
2528  int np = 0, isddl = -1, size;
2529 
2530  if (errmsg) {
2531  *errmsg = NULL;
2532  }
2533  if (sqlLen != SQL_NTS) {
2534  qz = q = xmalloc(sqlLen + 1);
2535  if (!qz) {
2536  return NULL;
2537  }
2538  memcpy(q, sql, sqlLen);
2539  q[sqlLen] = '\0';
2540  size = sqlLen * 4;
2541  } else {
2542  size = strlen(sql) * 4;
2543  }
2544  size += sizeof (char *) - 1;
2545  size &= ~(sizeof (char *) - 1);
2546  p = xmalloc(size);
2547  if (!p) {
2548 errout:
2549  freep(&qz);
2550  return NULL;
2551  }
2552  memset(p, 0, size);
2553  out = p;
2554  while (*q) {
2555  switch (*q) {
2556  case '\'':
2557  case '\"':
2558  if (q == inq) {
2559  inq = NULL;
2560  } else if (!inq) {
2561  inq = q + 1;
2562 
2563  while (*inq) {
2564  if (*inq == *q) {
2565  if (inq[1] == *q) {
2566  inq++;
2567  } else {
2568  break;
2569  }
2570  }
2571  inq++;
2572  }
2573  }
2574  *p++ = *q;
2575  break;
2576  case '?':
2577  *p++ = *q;
2578  if (!inq) {
2579  np++;
2580  }
2581  break;
2582  case ';':
2583  if (!inq) {
2584  if (isddl < 0) {
2585  isddl = checkddl(out);
2586  }
2587  if (isddl == 0) {
2588  char *qq = q;
2589 
2590  do {
2591  ++qq;
2592  } while (*qq && ISSPACE(*qq));
2593  if (*qq && *qq != ';') {
2594  freep(&out);
2595  if (errmsg) {
2596  *errmsg = "only one SQL statement allowed";
2597  }
2598  goto errout;
2599  }
2600  }
2601  }
2602  *p++ = *q;
2603  break;
2604  case '{':
2605  /*
2606  * Deal with escape sequences:
2607  * {d 'YYYY-MM-DD'}, {t ...}, {ts ...}
2608  * {oj ...}, {fn ...} etc.
2609  */
2610  if (!inq) {
2611  int ojfn = 0, brc = 0;
2612  char *inq2 = NULL, *end = q + 1, *start;
2613 
2614  while (*end && ISSPACE(*end)) {
2615  ++end;
2616  }
2617  if (*end != 'd' && *end != 'D' &&
2618  *end != 't' && *end != 'T') {
2619  ojfn = 1;
2620  }
2621  start = end;
2622  while (*end) {
2623  if (inq2 && *end == *inq2) {
2624  inq2 = NULL;
2625  } else if (inq2 == NULL && *end == '{') {
2626  char *nerr = 0, *nsql;
2627 
2628  nsql = fixupsql(end, SQL_NTS, cte, 0, 0, &nerr);
2629  if (nsql && !nerr) {
2630  strcpy(end, nsql);
2631  } else {
2632  brc++;
2633  }
2634  freep(&nsql);
2635  } else if (inq2 == NULL && *end == '}') {
2636  if (brc-- <= 0) {
2637  break;
2638  }
2639  } else if (inq2 == NULL && (*end == '\'' || *end == '"')) {
2640  inq2 = end;
2641  } else if (inq2 == NULL && *end == '?') {
2642  np++;
2643  }
2644  ++end;
2645  }
2646  if (*end == '}') {
2647  char *end2 = end - 1;
2648 
2649  if (ojfn) {
2650  while (start < end) {
2651  if (ISSPACE(*start)) {
2652  break;
2653  }
2654  ++start;
2655  }
2656  while (start < end) {
2657  *p++ = *start;
2658  ++start;
2659  }
2660  q = end;
2661  break;
2662  } else {
2663  while (start < end2 && *start != '\'') {
2664  ++start;
2665  }
2666  while (end2 > start && *end2 != '\'') {
2667  --end2;
2668  }
2669  if (*start == '\'' && *end2 == '\'') {
2670  while (start <= end2) {
2671  *p++ = *start;
2672  ++start;
2673  }
2674  q = end;
2675  break;
2676  }
2677  }
2678  }
2679  }
2680  /* FALL THROUGH */
2681  default:
2682  *p++ = *q;
2683  }
2684  ++q;
2685  }
2686  freep(&qz);
2687  *p = '\0';
2688  if (nparam) {
2689  *nparam = np;
2690  }
2691  if (isselect) {
2692  if (isddl < 0) {
2693  isddl = checkddl(out);
2694  }
2695  if (isddl > 0) {
2696  *isselect = 2;
2697  } else {
2698  int incom = 0;
2699 
2700  p = out;
2701  while (*p) {
2702  switch (*p) {
2703  case '-':
2704  if (!incom && p[1] == '-') {
2705  incom = -1;
2706  }
2707  break;
2708  case '\n':
2709  if (incom < 0) {
2710  incom = 0;
2711  }
2712  break;
2713  case '/':
2714  if (incom > 0 && p[-1] == '*') {
2715  incom = 0;
2716  p++;
2717  continue;
2718  } else if (!incom && p[1] == '*') {
2719  incom = 1;
2720  }
2721  break;
2722  }
2723  if (!incom && !ISSPACE(*p)) {
2724  break;
2725  }
2726  p++;
2727  }
2728  size = strlen(p);
2729  if (size >= 6 &&
2730  (strncasecmp(p, "select", 6) == 0 ||
2731  strncasecmp(p, "pragma", 6) == 0)) {
2732  *isselect = 1;
2733  } else if (cte && size >= 4 && strncasecmp(p, "with", 4) == 0) {
2734  *isselect = 1;
2735  } else if (size >= 7 && strncasecmp(p, "explain", 7) == 0) {
2736  *isselect = 1;
2737  } else {
2738  *isselect = 0;
2739  }
2740  }
2741  }
2742  return out;
2743 }
2744 
2753 static int
2754 findcol(char **cols, int ncols, char *name)
2755 {
2756  int i;
2757 
2758  if (cols) {
2759  for (i = 0; i < ncols; i++) {
2760  if (strcmp(cols[i], name) == 0) {
2761  return i;
2762  }
2763  }
2764  }
2765  return -1;
2766 }
2767 
2784 static void
2786 {
2787  int i, k;
2788 #ifndef FULL_METADATA
2789  int pk, nn, t, r, nrows, ncols;
2790  char **rowp, *flagp, flags[128];
2791 #endif
2792 
2793  if (!s->dyncols) {
2794  return;
2795  }
2796  /* fixup labels */
2797  if (!s->longnames) {
2798  if (s->dcols > 1) {
2799  char *table = s->dyncols[0].table;
2800 
2801  for (i = 1; table[0] && i < s->dcols; i++) {
2802  if (strcmp(s->dyncols[i].table, table)) {
2803  break;
2804  }
2805  }
2806  if (i >= s->dcols) {
2807  for (i = 0; i < s->dcols; i++) {
2808  s->dyncols[i].label = s->dyncols[i].column;
2809  }
2810  }
2811  } else if (s->dcols == 1) {
2812  s->dyncols[0].label = s->dyncols[0].column;
2813  }
2814  }
2815  for (i = 0; i < s->dcols; i++) {
2816  s->dyncols[i].type =
2817  mapsqltype(s->dyncols[i].typename, &s->dyncols[i].nosign, *s->ov3,
2818  s->nowchar[0] || s->nowchar[1], s->dobigint);
2819  getmd(s->dyncols[i].typename, s->dyncols[i].type,
2820  &s->dyncols[i].size, &s->dyncols[i].prec);
2821 #ifdef SQL_LONGVARCHAR
2822  if (s->dyncols[i].type == SQL_VARCHAR &&
2823  s->dyncols[i].size > 255) {
2824  s->dyncols[i].type = SQL_LONGVARCHAR;
2825  }
2826 #endif
2827 #ifdef WINTERFACE
2828 #ifdef SQL_WLONGVARCHAR
2829  if (s->dyncols[i].type == SQL_WVARCHAR &&
2830  s->dyncols[i].size > 255) {
2831  s->dyncols[i].type = SQL_WLONGVARCHAR;
2832  }
2833 #endif
2834 #endif
2835  if (s->dyncols[i].type == SQL_VARBINARY &&
2836  s->dyncols[i].size > 255) {
2837  s->dyncols[i].type = SQL_LONGVARBINARY;
2838  }
2839  }
2840 #ifndef FULL_METADATA
2841  if (s->dcols > array_size(flags)) {
2842  flagp = xmalloc(sizeof (flags[0]) * s->dcols);
2843  if (flagp == NULL) {
2844  return;
2845  }
2846  } else {
2847  flagp = flags;
2848  }
2849  memset(flagp, 0, sizeof (flags[0]) * s->dcols);
2850  for (i = 0; i < s->dcols; i++) {
2851  s->dyncols[i].autoinc = SQL_FALSE;
2852  s->dyncols[i].notnull = SQL_NULLABLE;
2853  }
2854  for (i = 0; i < s->dcols; i++) {
2855  int ret, lastpk = -1, autoinccount = 0;
2856  char *sql;
2857 
2858  if (!s->dyncols[i].table[0]) {
2859  continue;
2860  }
2861  if (flagp[i]) {
2862  continue;
2863  }
2864  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", s->dyncols[i].table);
2865  if (!sql) {
2866  continue;
2867  }
2868  dbtraceapi(d, "sqlite3_get_table", sql);
2869  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, NULL);
2870  sqlite3_free(sql);
2871  if (ret != SQLITE_OK) {
2872  continue;
2873  }
2874  k = findcol(rowp, ncols, "name");
2875  t = findcol(rowp, ncols, "type");
2876  pk = findcol(rowp, ncols, "pk");
2877  nn = findcol(rowp, ncols, "notnull");
2878  if (k < 0 || t < 0) {
2879  goto freet;
2880  }
2881  for (r = 1; r <= nrows; r++) {
2882  int m;
2883 
2884  for (m = i; m < s->dcols; m++) {
2885  char *colname = s->dyncols[m].column;
2886 
2887  if (s->longnames) {
2888  char *dotp = strchr(colname, '.');
2889 
2890  if (dotp) {
2891  colname = dotp + 1;
2892  }
2893  }
2894  if (!flagp[m] &&
2895  strcmp(colname, rowp[r * ncols + k]) == 0 &&
2896  strcmp(s->dyncols[m].table, s->dyncols[i].table) == 0) {
2897  char *typename = rowp[r * ncols + t];
2898 
2899  flagp[m] = i + 1;
2900  freep(&s->dyncols[m].typename);
2901  s->dyncols[m].typename = xstrdup(typename);
2902  s->dyncols[m].type =
2903  mapsqltype(typename, &s->dyncols[m].nosign, *s->ov3,
2904  s->nowchar[0] || s->nowchar[1],
2905  s->dobigint);
2906  getmd(typename, s->dyncols[m].type, &s->dyncols[m].size,
2907  &s->dyncols[m].prec);
2908 #ifdef SQL_LONGVARCHAR
2909  if (s->dyncols[m].type == SQL_VARCHAR &&
2910  s->dyncols[m].size > 255) {
2911  s->dyncols[m].type = SQL_LONGVARCHAR;
2912  }
2913 #endif
2914 #ifdef WINTERFACE
2915 #ifdef SQL_WLONGVARCHAR
2916  if (s->dyncols[i].type == SQL_WVARCHAR &&
2917  s->dyncols[i].size > 255) {
2918  s->dyncols[i].type = SQL_WLONGVARCHAR;
2919  }
2920 #endif
2921 #endif
2922  if (s->dyncols[i].type == SQL_VARBINARY &&
2923  s->dyncols[i].size > 255) {
2924  s->dyncols[i].type = SQL_LONGVARBINARY;
2925  }
2926  if (pk >= 0 && strcmp(rowp[r * ncols + pk], "1") == 0) {
2927  s->dyncols[m].ispk = 1;
2928  if (++autoinccount > 1) {
2929  if (lastpk >= 0) {
2930  s->dyncols[lastpk].autoinc = SQL_FALSE;
2931  lastpk = -1;
2932  }
2933  } else {
2934  lastpk = m;
2935  if (strlen(typename) == 7 &&
2936  strncasecmp(typename, "integer", 7) == 0) {
2937  s->dyncols[m].autoinc = SQL_TRUE;
2938  }
2939  }
2940  } else {
2941  s->dyncols[m].ispk = 0;
2942  }
2943  if (nn >= 0 && rowp[r * ncols + nn][0] != '0') {
2944  s->dyncols[m].notnull = SQL_NO_NULLS;
2945  }
2946  }
2947  }
2948  }
2949 freet:
2950  sqlite3_free_table(rowp);
2951  }
2952  for (i = k = 0; i < s->dcols; i++) {
2953  if (flagp[i] == 0) {
2954  break;
2955  }
2956  if (k == 0) {
2957  k = flagp[i];
2958  } else if (flagp[i] != k) {
2959  k = 0;
2960  break;
2961  }
2962  }
2963  s->one_tbl = k ? 1 : 0;
2964  k = 0;
2965  if (s->one_tbl) {
2966  for (i = 0; i < s->dcols; i++) {
2967  if (s->dyncols[i].ispk > 0) {
2968  ++k;
2969  }
2970  }
2971  }
2972  s->has_pk = k;
2973  if (flagp != flags) {
2974  freep(&flagp);
2975  }
2976 #else
2977  for (i = 1, k = 0; i < s->dcols; i++) {
2978  if (strcmp(s->dyncols[i].table, s->dyncols[0].table) == 0) {
2979  k++;
2980  }
2981  }
2982  s->one_tbl = (k && k + 1 == s->dcols) ? 1 : 0;
2983  k = 0;
2984  if (s->one_tbl) {
2985  for (i = 0; i < s->dcols; i++) {
2986  if (s->dyncols[i].ispk > 0) {
2987  ++k;
2988  if (s->has_rowid < 0 && s->dyncols[i].isrowid > 0) {
2989  s->has_rowid = i;
2990  }
2991  }
2992  }
2993  }
2994  s->has_pk = k;
2995 #endif
2996 }
2997 
3004 static void
3005 convJD2YMD(double jd, DATE_STRUCT *ds)
3006 {
3007  int z, a, b, c, d, e, x1;
3008  sqlite_int64 ijd;
3009 
3010  ijd = jd * 86400000.0 + 0.5;
3011  z = (int) ((ijd + 43200000) / 86400000);
3012  a = (int) ((z - 1867216.25) / 36524.25);
3013  a = z + 1 + a - (a / 4);
3014  b = a + 1524;
3015  c = (int) ((b - 122.1) / 365.25);
3016  d = (36525 * c) / 100;
3017  e = (int) ((b - d) / 30.6001);
3018  x1 = (int) (30.6001 * e);
3019  ds->day = b - d - x1;
3020  ds->month = (e < 14) ? (e - 1) : (e - 13);
3021  ds->year = (ds->month > 2) ? (c - 4716) : (c - 4715);
3022 }
3023 
3024 
3032 static void
3033 convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
3034 {
3035  int s;
3036  double ds;
3037  sqlite_int64 ijd;
3038 
3039  ijd = jd * 86400000.0 + 0.5;
3040  s = (int)((ijd + 43200000) % 86400000);
3041  ds = s / 1000.0;
3042  if (fp) {
3043  *fp = (s % 1000) * 1000000;
3044  }
3045  s = (int) ds;
3046  ds -= s;
3047  ts->hour = s / 3600;
3048  s -= ts->hour * 3600;
3049  ts->minute = s / 60;
3050  ds += s - ts->minute *60;
3051  ts->second = (int) ds;
3052 }
3053 
3061 static int
3062 getmdays(int year, int month)
3063 {
3064  static const int mdays[] = {
3065  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
3066  };
3067  int mday;
3068 
3069  if (month < 1) {
3070  return 0;
3071  }
3072  mday = mdays[(month - 1) % 12];
3073  if (mday == 28 && year % 4 == 0 &&
3074  (!(year % 100 == 0) || year % 400 == 0)) {
3075  mday++;
3076  }
3077  return mday;
3078 }
3079 
3095 static int
3096 str2date(int jdconv, char *str, DATE_STRUCT *ds)
3097 {
3098  int i, err = 0;
3099  double jd;
3100  char *p, *q, sepc = '\0';
3101 
3102  ds->year = ds->month = ds->day = 0;
3103  if (jdconv) {
3104  p = strchr(str, '.');
3105  if (p) {
3106  /* julian day format */
3107  p = 0;
3108  jd = ln_strtod(str, &p);
3109  if (p && p > str) {
3110  convJD2YMD(jd, ds);
3111  return 0;
3112  }
3113  }
3114  }
3115  p = str;
3116  while (*p && !ISDIGIT(*p)) {
3117  ++p;
3118  }
3119  q = p;
3120  i = 0;
3121  while (*q && !ISDIGIT(*q)) {
3122  ++i;
3123  ++q;
3124  }
3125  if (i >= 8) {
3126  char buf[8];
3127 
3128  strncpy(buf, p + 0, 4); buf[4] = '\0';
3129  ds->year = strtol(buf, NULL, 10);
3130  strncpy(buf, p + 4, 2); buf[2] = '\0';
3131  ds->month = strtol(buf, NULL, 10);
3132  strncpy(buf, p + 6, 2); buf[2] = '\0';
3133  ds->day = strtol(buf, NULL, 10);
3134  goto done;
3135  }
3136  i = 0;
3137  while (i < 3) {
3138  int n;
3139 
3140  q = NULL;
3141  n = strtol(p, &q, 10);
3142  if (!q || q == p) {
3143  if (*q == '\0') {
3144  if (i == 0) {
3145  err = 1;
3146  }
3147  goto done;
3148  }
3149  }
3150  if (!sepc) {
3151  sepc = *q;
3152  }
3153  if (*q == '-' || *q == '/' || *q == '\0' || i == 2) {
3154  switch (i) {
3155  case 0: ds->year = n; break;
3156  case 1: ds->month = n; break;
3157  case 2: ds->day = n; break;
3158  }
3159  ++i;
3160  if (*q) {
3161  ++q;
3162  }
3163  } else {
3164  i = 0;
3165  while (*q && !ISDIGIT(*q)) {
3166  ++q;
3167  }
3168  }
3169  p = q;
3170  }
3171 done:
3172  /* final check for overflow */
3173  if (err ||
3174  ds->month < 1 || ds->month > 12 ||
3175  ds->day < 1 || ds->day > getmdays(ds->year, ds->month)) {
3176  if (sepc == '/') {
3177  /* Try MM/DD/YYYY format */
3178  int t[3];
3179 
3180  t[0] = ds->year;
3181  t[1] = ds->month;
3182  t[2] = ds->day;
3183  ds->year = t[2];
3184  ds->day = t[1];
3185  ds->month = t[0];
3186  if (ds->month >= 1 && ds->month <= 12 &&
3187  (ds->day >= 1 || ds->day <= getmdays(ds->year, ds->month))) {
3188  return 0;
3189  }
3190  }
3191  return -1;
3192  }
3193  return 0;
3194 }
3195 
3210 static int
3211 str2time(int jdconv, char *str, TIME_STRUCT *ts)
3212 {
3213  int i, err = 0, ampm = -1;
3214  double jd;
3215  char *p, *q;
3216 
3217  ts->hour = ts->minute = ts->second = 0;
3218  if (jdconv) {
3219  p = strchr(str, '.');
3220  if (p) {
3221  /* julian day format */
3222  p = 0;
3223  jd = ln_strtod(str, &p);
3224  if (p && p > str) {
3225  convJD2HMS(jd, ts, 0);
3226  return 0;
3227  }
3228  }
3229  }
3230  p = str;
3231  while (*p && !ISDIGIT(*p)) {
3232  ++p;
3233  }
3234  q = p;
3235  i = 0;
3236  while (*q && ISDIGIT(*q)) {
3237  ++i;
3238  ++q;
3239  }
3240  if (i >= 6) {
3241  char buf[4];
3242 
3243  strncpy(buf, p + 0, 2); buf[2] = '\0';
3244  ts->hour = strtol(buf, NULL, 10);
3245  strncpy(buf, p + 2, 2); buf[2] = '\0';
3246  ts->minute = strtol(buf, NULL, 10);
3247  strncpy(buf, p + 4, 2); buf[2] = '\0';
3248  ts->second = strtol(buf, NULL, 10);
3249  goto done;
3250  }
3251  i = 0;
3252  while (i < 3) {
3253  int n;
3254 
3255  q = NULL;
3256  n = strtol(p, &q, 10);
3257  if (!q || q == p) {
3258  if (*q == '\0') {
3259  if (i == 0) {
3260  err = 1;
3261  }
3262  goto done;
3263  }
3264  }
3265  if (*q == ':' || *q == '\0' || i == 2) {
3266  switch (i) {
3267  case 0: ts->hour = n; break;
3268  case 1: ts->minute = n; break;
3269  case 2: ts->second = n; break;
3270  }
3271  ++i;
3272  if (*q) {
3273  ++q;
3274  }
3275  } else {
3276  i = 0;
3277  while (*q && !ISDIGIT(*q)) {
3278  ++q;
3279  }
3280  }
3281  p = q;
3282  }
3283  if (!err) {
3284  while (*p) {
3285  if ((p[0] == 'p' || p[0] == 'P') &&
3286  (p[1] == 'm' || p[1] == 'M')) {
3287  ampm = 1;
3288  } else if ((p[0] == 'a' || p[0] == 'A') &&
3289  (p[1] == 'm' || p[1] == 'M')) {
3290  ampm = 0;
3291  }
3292  ++p;
3293  }
3294  if (ampm > 0) {
3295  if (ts->hour < 12) {
3296  ts->hour += 12;
3297  }
3298  } else if (ampm == 0) {
3299  if (ts->hour == 12) {
3300  ts->hour = 0;
3301  }
3302  }
3303  }
3304 done:
3305  /* final check for overflow */
3306  if (err || ts->hour > 23 || ts->minute > 59 || ts->second > 59) {
3307  return -1;
3308  }
3309  return 0;
3310 }
3311 
3331 static int
3332 str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
3333 {
3334  int i, m, n, err = 0, ampm = -1;
3335  double jd;
3336  char *p, *q, in = '\0', sepc = '\0';
3337 
3338  tss->year = tss->month = tss->day = 0;
3339  tss->hour = tss->minute = tss->second = 0;
3340  tss->fraction = 0;
3341  if (jdconv) {
3342  p = strchr(str, '.');
3343  if (p) {
3344  q = strchr(str, '-');
3345  if (q == str) {
3346  q = 0;
3347  }
3348  if (!q) {
3349  q = strchr(str, '/');
3350  if (!q) {
3351  q = strchr(str, ':');
3352  }
3353  }
3354  if (!q || q > p) {
3355  /* julian day format */
3356  p = 0;
3357  jd = ln_strtod(str, &p);
3358  if (p && p > str) {
3359  DATE_STRUCT ds;
3360  TIME_STRUCT ts;
3361 
3362  convJD2YMD(jd, &ds);
3363  convJD2HMS(jd, &ts, &n);
3364  tss->year = ds.year;
3365  tss->month = ds.month;
3366  tss->day = ds.day;
3367  tss->hour = ts.hour;
3368  tss->minute = ts.minute;
3369  tss->second = ts.second;
3370  tss->fraction = n;
3371  return 0;
3372  }
3373  }
3374  }
3375  }
3376  p = str;
3377  while (*p && !ISDIGIT(*p)) {
3378  ++p;
3379  }
3380  q = p;
3381  i = 0;
3382  while (*q && ISDIGIT(*q)) {
3383  ++i;
3384  ++q;
3385  }
3386  if (i >= 14) {
3387  char buf[16];
3388 
3389  strncpy(buf, p + 0, 4); buf[4] = '\0';
3390  tss->year = strtol(buf, NULL, 10);
3391  strncpy(buf, p + 4, 2); buf[2] = '\0';
3392  tss->month = strtol(buf, NULL, 10);
3393  strncpy(buf, p + 6, 2); buf[2] = '\0';
3394  tss->day = strtol(buf, NULL, 10);
3395  strncpy(buf, p + 8, 2); buf[2] = '\0';
3396  tss->hour = strtol(buf, NULL, 10);
3397  strncpy(buf, p + 10, 2); buf[2] = '\0';
3398  tss->minute = strtol(buf, NULL, 10);
3399  strncpy(buf, p + 12, 2); buf[2] = '\0';
3400  tss->second = strtol(buf, NULL, 10);
3401  if (i > 14) {
3402  m = i - 14;
3403  strncpy(buf, p + 14, m);
3404  while (m < 9) {
3405  buf[m] = '0';
3406  ++m;
3407  }
3408  buf[m] = '\0';
3409  tss->fraction = strtol(buf, NULL, 10);
3410  }
3411  m = 7;
3412  goto done;
3413  }
3414  m = i = 0;
3415  while ((m & 7) != 7) {
3416  q = NULL;
3417  n = strtol(p, &q, 10);
3418  if (!q || q == p) {
3419  if (*q == '\0') {
3420  if (m < 1) {
3421  err = 1;
3422  }
3423  goto done;
3424  }
3425  }
3426  if (in == '\0') {
3427  switch (*q) {
3428  case '-':
3429  case '/':
3430  if ((m & 1) == 0) {
3431  in = *q;
3432  i = 0;
3433  }
3434  break;
3435  case ':':
3436  if ((m & 2) == 0) {
3437  in = *q;
3438  i = 0;
3439  }
3440  break;
3441  case ' ':
3442  case '.':
3443  break;
3444  default:
3445  in = '\0';
3446  i = 0;
3447  break;
3448  }
3449  }
3450  switch (in) {
3451  case '-':
3452  case '/':
3453  if (!sepc) {
3454  sepc = in;
3455  }
3456  switch (i) {
3457  case 0: tss->year = n; break;
3458  case 1: tss->month = n; break;
3459  case 2: tss->day = n; break;
3460  }
3461  if (++i >= 3) {
3462  i = 0;
3463  m |= 1;
3464  if (!(m & 2)) {
3465  m |= 8;
3466  }
3467  goto skip;
3468  } else {
3469  ++q;
3470  }
3471  break;
3472  case ':':
3473  switch (i) {
3474  case 0: tss->hour = n; break;
3475  case 1: tss->minute = n; break;
3476  case 2: tss->second = n; break;
3477  }
3478  if (++i >= 3) {
3479  i = 0;
3480  m |= 2;
3481  if (*q == '.') {
3482  in = '.';
3483  goto skip2;
3484  }
3485  if (*q == ' ') {
3486  if ((m & 1) == 0) {
3487  char *e = NULL;
3488 
3489  (void) strtol(q + 1, &e, 10);
3490  if (e && *e == '-') {
3491  goto skip;
3492  }
3493  }
3494  in = '.';
3495  goto skip2;
3496  }
3497  goto skip;
3498  } else {
3499  ++q;
3500  }
3501  break;
3502  case '.':
3503  if (++i >= 1) {
3504  int ndig = q - p;
3505 
3506  if (p[0] == '+' || p[0] == '-') {
3507  ndig--;
3508  }
3509  while (ndig < 9) {
3510  n = n * 10;
3511  ++ndig;
3512  }
3513  tss->fraction = n;
3514  m |= 4;
3515  i = 0;
3516  }
3517  default:
3518  skip:
3519  in = '\0';
3520  skip2:
3521  while (*q && !ISDIGIT(*q)) {
3522  if ((q[0] == 'a' || q[0] == 'A') &&
3523  (q[1] == 'm' || q[1] == 'M')) {
3524  ampm = 0;
3525  ++q;
3526  } else if ((q[0] == 'p' || q[0] == 'P') &&
3527  (q[1] == 'm' || q[1] == 'M')) {
3528  ampm = 1;
3529  ++q;
3530  }
3531  ++q;
3532  }
3533  }
3534  p = q;
3535  }
3536  if ((m & 7) > 1 && (m & 8)) {
3537  /* ISO8601 timezone */
3538  if (p > str && ISDIGIT(*p)) {
3539  int nn, sign;
3540 
3541  q = p - 1;
3542  if (*q != '+' && *q != '-') {
3543  goto done;
3544  }
3545  sign = (*q == '+') ? -1 : 1;
3546  q = NULL;
3547  n = strtol(p, &q, 10);
3548  if (!q || *q++ != ':' || !ISDIGIT(*q)) {
3549  goto done;
3550  }
3551  p = q;
3552  q = NULL;
3553  nn = strtol(p, &q, 10);
3554  tss->minute += nn * sign;
3555  if ((SQLSMALLINT) tss->minute < 0) {
3556  tss->hour -= 1;
3557  tss->minute += 60;
3558  } else if (tss->minute >= 60) {
3559  tss->hour += 1;
3560  tss->minute -= 60;
3561  }
3562  tss->hour += n * sign;
3563  if ((SQLSMALLINT) tss->hour < 0) {
3564  tss->day -= 1;
3565  tss->hour += 24;
3566  } else if (tss->hour >= 24) {
3567  tss->day += 1;
3568  tss->hour -= 24;
3569  }
3570  if ((short) tss->day < 1 || tss->day >= 28) {
3571  int mday, pday, pmon;
3572 
3573  mday = getmdays(tss->year, tss->month);
3574  pmon = tss->month - 1;
3575  if (pmon < 1) {
3576  pmon = 12;
3577  }
3578  pday = getmdays(tss->year, pmon);
3579  if ((SQLSMALLINT) tss->day < 1) {
3580  tss->month -= 1;
3581  tss->day = pday;
3582  } else if (tss->day > mday) {
3583  tss->month += 1;
3584  tss->day = 1;
3585  }
3586  if ((SQLSMALLINT) tss->month < 1) {
3587  tss->year -= 1;
3588  tss->month = 12;
3589  } else if (tss->month > 12) {
3590  tss->year += 1;
3591  tss->month = 1;
3592  }
3593  }
3594  }
3595  }
3596 done:
3597  if ((m & 1) &&
3598  (tss->month < 1 || tss->month > 12 ||
3599  tss->day < 1 || tss->day > getmdays(tss->year, tss->month))) {
3600  if (sepc == '/') {
3601  /* Try MM/DD/YYYY format */
3602  int t[3];
3603 
3604  t[0] = tss->year;
3605  t[1] = tss->month;
3606  t[2] = tss->day;
3607  tss->year = t[2];
3608  tss->day = t[1];
3609  tss->month = t[0];
3610  }
3611  }
3612  /* Replace missing year/month/day with current date */
3613  if (!err && (m & 1) == 0) {
3614 #ifdef _WIN32
3615  SYSTEMTIME t;
3616 
3617  GetLocalTime(&t);
3618  tss->year = t.wYear;
3619  tss->month = t.wMonth;
3620  tss->day = t.wDay;
3621 #else
3622  struct timeval tv;
3623  struct tm tm;
3624 
3625  gettimeofday(&tv, NULL);
3626  tm = *localtime(&tv.tv_sec);
3627  tss->year = tm.tm_year + 1900;
3628  tss->month = tm.tm_mon + 1;
3629  tss->day = tm.tm_mday;
3630 #endif
3631  }
3632  /* Normalize fraction */
3633  if (tss->fraction < 0) {
3634  tss->fraction = 0;
3635  }
3636  /* Final check for overflow */
3637  if (err ||
3638  tss->month < 1 || tss->month > 12 ||
3639  tss->day < 1 || tss->day > getmdays(tss->year, tss->month) ||
3640  tss->hour > 23 || tss->minute > 59 || tss->second > 59) {
3641  return -1;
3642  }
3643  if ((m & 7) > 1) {
3644  if (ampm > 0) {
3645  if (tss->hour < 12) {
3646  tss->hour += 12;
3647  }
3648  } else if (ampm == 0) {
3649  if (tss->hour == 12) {
3650  tss->hour = 0;
3651  }
3652  }
3653  }
3654  return ((m & 7) < 1) ? -1 : 0;
3655 }
3656 
3663 static int
3664 getbool(char *string)
3665 {
3666  if (string) {
3667  return string[0] && strchr("Yy123456789Tt", string[0]) != NULL;
3668  }
3669  return 0;
3670 }
3671 
3679 static void
3680 blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
3681 {
3682 #if 0
3683  DBC *d = (DBC *) sqlite3_user_data(ctx);
3684 #endif
3685  char *filename = 0;
3686 
3687  if (nargs > 0) {
3688  if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
3689  filename = (char *) sqlite3_value_text(args[0]);
3690  }
3691  }
3692  if (filename) {
3693 #ifdef _WIN32
3694  char *wname = utf_to_wmb(filename, -1);
3695  FILE *f;
3696 #else
3697  FILE *f = fopen(filename, "r");
3698 #endif
3699  char *p;
3700  long n, nn;
3701 
3702 #ifdef _WIN32
3703  if (wname) {
3704  f = fopen(wname, "rb");
3705  } else {
3706  sqlite3_result_error(ctx, "out of memory", -1);
3707  return;
3708  }
3709  uc_free(wname);
3710 #endif
3711  if (f) {
3712  if (fseek(f, 0, SEEK_END) == 0) {
3713  n = ftell(f);
3714  if (fseek(f, 0, SEEK_SET) == 0) {
3715  p = sqlite3_malloc(n);
3716  if (p) {
3717  nn = fread(p, 1, n, f);
3718  if (nn != n) {
3719  sqlite3_result_error(ctx, "read error", -1);
3720  sqlite3_free(p);
3721  } else {
3722  sqlite3_result_blob(ctx, p, n, sqlite3_free);
3723  }
3724  } else {
3725  sqlite3_result_error(ctx, "out of memory", -1);
3726  }
3727  } else {
3728  sqlite3_result_error(ctx, "seek error", -1);
3729  }
3730  } else {
3731  sqlite3_result_error(ctx, "seek error", -1);
3732  }
3733  fclose(f);
3734  } else {
3735  sqlite3_result_error(ctx, "cannot open file", -1);
3736  }
3737  } else {
3738  sqlite3_result_error(ctx, "no filename given", -1);
3739  }
3740 }
3741 
3749 static void
3750 blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
3751 {
3752 #if 0
3753  DBC *d = (DBC *) sqlite3_user_data(ctx);
3754 #endif
3755  char *filename = 0;
3756  char *p = 0;
3757  int n = 0;
3758 
3759  if (nargs > 0) {
3760  p = (char *) sqlite3_value_blob(args[0]);
3761  n = sqlite3_value_bytes(args[0]);
3762  }
3763  if (nargs > 1) {
3764  if (sqlite3_value_type(args[1]) != SQLITE_NULL) {
3765  filename = (char *) sqlite3_value_text(args[1]);
3766  }
3767  }
3768  if (p) {
3769  if (filename) {
3770 #ifdef _WIN32
3771  char *wname = utf_to_wmb(filename, -1);
3772  FILE *f;
3773 #else
3774  FILE *f = fopen(filename, "w");
3775 #endif
3776  int nn;
3777 
3778 #ifdef _WIN32
3779  if (wname) {
3780  f = fopen(wname, "wb");
3781  } else {
3782  sqlite3_result_error(ctx, "out of memory", -1);
3783  return;
3784  }
3785  uc_free(wname);
3786 #endif
3787  if (f) {
3788  nn = fwrite(p, 1, n, f);
3789  fclose(f);
3790  if (nn != n) {
3791  sqlite3_result_error(ctx, "write error", -1);
3792  } else {
3793  sqlite3_result_int(ctx, nn);
3794  }
3795  } else {
3796  sqlite3_result_error(ctx, "cannot open file", -1);
3797  }
3798  } else {
3799  sqlite3_result_error(ctx, "no filename given", -1);
3800  }
3801  } else {
3802  sqlite3_result_null(ctx);
3803  }
3804 }
3805 
3813 static void
3814 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3815 dbtrace(void *arg, const char *msg, sqlite_uint64 et)
3816 #else
3817 dbtrace(void *arg, const char *msg)
3818 #endif
3819 {
3820  DBC *d = (DBC *) arg;
3821 
3822  if (msg && d->trace) {
3823  int len = strlen(msg);
3824 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3825  unsigned long s, f;
3826 #endif
3827 
3828  if (len > 0) {
3829  char *end = "\n";
3830 
3831  if (msg[len - 1] != ';') {
3832  end = ";\n";
3833  }
3834  fprintf(d->trace, "%s%s", msg, end);
3835 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3836  s = et / 1000000000LL;
3837  f = et % 1000000000LL;
3838  fprintf(d->trace, "-- took %lu.%09lu seconds\n", s, f);
3839 #endif
3840  fflush(d->trace);
3841  }
3842  }
3843 }
3844 
3852 static void
3853 dbtraceapi(DBC *d, char *fn, const char *sql)
3854 {
3855  if (fn && d->trace) {
3856  if (sql) {
3857  fprintf(d->trace, "-- %s: %s\n", fn, sql);
3858  } else {
3859  fprintf(d->trace, "-- %s\n", fn);
3860  }
3861  fflush(d->trace);
3862  }
3863 }
3864 
3872 static void
3873 dbtracerc(DBC *d, int rc, char *err)
3874 {
3875  if (rc != SQLITE_OK && d->trace) {
3876  fprintf(d->trace, "-- SQLITE ERROR CODE %d", rc);
3877  fprintf(d->trace, err ? ": %s\n" : "\n", err);
3878  fflush(d->trace);
3879  }
3880 }
3881 
3896 static SQLRETURN
3897 dbopen(DBC *d, char *name, int isu, char *dsn, char *sflag,
3898  char *spflag, char *ntflag, char *jmode, char *busy)
3899 {
3900  char *endp = NULL;
3901  int rc, tmp, busyto = 100000;
3902 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
3903  int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
3904  char *uname = name;
3905  const char *vfs_name = NULL;
3906 #endif
3907 
3908  if (d->sqlite) {
3909  if (d->trace) {
3910  fprintf(d->trace, "-- sqlite3_close (deferred): '%s'\n",
3911  d->dbname);
3912  fflush(d->trace);
3913  }
3914 #if defined(HAVE_SQLITE3CLOSEV2) && (HAVE_SQLITE3CLOSEV2)
3915  sqlite3_close_v2(d->sqlite);
3916 #else
3917  sqlite3_close(d->sqlite);
3918 #endif
3919  d->sqlite = NULL;
3920  }
3921 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
3922  if (d->nocreat) {
3923  flags &= ~ SQLITE_OPEN_CREATE;
3924  }
3925 #if defined(_WIN32) || defined(_WIN64)
3926  if (!isu) {
3927  char expname[SQL_MAX_MESSAGE_LENGTH * 2];
3928 
3929  expname[0] = '\0';
3930  rc = ExpandEnvironmentStrings(name, expname, sizeof (expname));
3931  if (rc <= sizeof (expname)) {
3932  uname = wmb_to_utf(expname, rc - 1);
3933  } else {
3934  uname = wmb_to_utf(name, -1);
3935  }
3936  if (!uname) {
3937  rc = SQLITE_NOMEM;
3938  setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
3939  return SQL_ERROR;
3940  }
3941  }
3942 #endif
3943 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
3944  vfs_name = nvfs_makevfs(uname);
3945 #endif
3946 #ifdef SQLITE_OPEN_URI
3947  flags |= SQLITE_OPEN_URI;
3948 #endif
3949  rc = sqlite3_open_v2(uname, &d->sqlite, flags, vfs_name);
3950 #if defined(WINTERFACE) || defined(_WIN32) || defined(_WIN64)
3951  if (uname != name) {
3952  uc_free(uname);
3953  }
3954 #endif
3955 #else
3956 #if defined(_WIN32) || defined(_WIN64)
3957  if (d->nocreat) {
3958  char *cname = NULL;
3959 
3960  if (isu) {
3961  cname = utf_to_wmb(name, -1);
3962  }
3963  if (GetFileAttributesA(cname ? cname : name) ==
3964  INVALID_FILE_ATTRIBUTES) {
3965  uc_free(cname);
3966  rc = SQLITE_CANTOPEN;
3967  setstatd(d, rc, "cannot open database",
3968  (*d->ov3) ? "HY000" : "S1000");
3969  return SQL_ERROR;
3970  }
3971  uc_free(cname);
3972  }
3973 #else
3974  if (d->nocreat && access(name, 004) < 0) {
3975  rc = SQLITE_CANTOPEN;
3976  setstatd(d, rc, "cannot open database", (*d->ov3) ? "HY000" : "S1000");
3977  return SQL_ERROR;
3978  }
3979 #endif
3980 #if defined(_WIN32) || defined(_WIN64)
3981  if (!isu) {
3982  WCHAR *wname = wmb_to_uc(name, -1);
3983 
3984  if (!wname) {
3985  rc = SQLITE_NOMEM;
3986  setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
3987  return SQL_ERROR;
3988  }
3989  rc = sqlite3_open16(wname, &d->sqlite);
3990  uc_free(wname);
3991  } else
3992 #endif
3993  rc = sqlite3_open(name, &d->sqlite);
3994 #endif /* !HAVE_SQLITE3VFS */
3995  if (rc != SQLITE_OK) {
3996 connfail:
3997  setstatd(d, rc, "connect failed", (*d->ov3) ? "HY000" : "S1000");
3998  if (d->sqlite) {
3999  sqlite3_close(d->sqlite);
4000  d->sqlite = NULL;
4001  }
4002  return SQL_ERROR;
4003  }
4004 #if defined(SQLITE_DYNLOAD) || defined(SQLITE_HAS_CODEC)
4005  if (d->pwd) {
4006  sqlite3_key(d->sqlite, d->pwd, d->pwdLen);
4007  }
4008 #endif
4009  d->pwd = NULL;
4010  d->pwdLen = 0;
4011  if (d->trace) {
4012 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
4013  sqlite3_profile(d->sqlite, dbtrace, d);
4014 #else
4015  sqlite3_trace(d->sqlite, dbtrace, d);
4016 #endif
4017  }
4018  d->step_enable = getbool(sflag);
4019  d->trans_disable = getbool(ntflag);
4020  d->curtype = d->step_enable ?
4021  SQL_CURSOR_FORWARD_ONLY : SQL_CURSOR_STATIC;
4022  tmp = strtol(busy, &endp, 0);
4023  if (endp && *endp == '\0' && endp != busy) {
4024  busyto = tmp;
4025  }
4026  if (busyto < 1 || busyto > 1000000) {
4027  busyto = 1000000;
4028  }
4029  d->timeout = busyto;
4030  freep(&d->dbname);
4031  d->dbname = xstrdup(name);
4032  freep(&d->dsn);
4033  d->dsn = xstrdup(dsn);
4034  if ((rc = setsqliteopts(d->sqlite, d)) != SQLITE_OK) {
4035  if (d->trace) {
4036  fprintf(d->trace, "-- sqlite3_close: '%s'\n",
4037  d->dbname);
4038  fflush(d->trace);
4039  }
4040  sqlite3_close(d->sqlite);
4041  d->sqlite = NULL;
4042  goto connfail;
4043  }
4044  if (!spflag || spflag[0] == '\0') {
4045  spflag = "NORMAL";
4046  }
4047  if (spflag[0] != '\0') {
4048  char syncp[128];
4049 
4050  sprintf(syncp, "PRAGMA synchronous = %8.8s;", spflag);
4051  sqlite3_exec(d->sqlite, syncp, NULL, NULL, NULL);
4052  }
4053  if (jmode[0] != '\0') {
4054  char jourp[128];
4055 
4056  sprintf(jourp, "PRAGMA journal_mode = %16.16s;", jmode);
4057  sqlite3_exec(d->sqlite, jourp, NULL, NULL, NULL);
4058  }
4059  if (d->trace) {
4060  fprintf(d->trace, "-- sqlite3_open: '%s'\n", d->dbname);
4061  fflush(d->trace);
4062  }
4063 #if defined(_WIN32) || defined(_WIN64)
4064  {
4065  char pname[MAX_PATH];
4066  HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
4067  FALSE, GetCurrentProcessId());
4068 
4069  pname[0] = '\0';
4070  if (h) {
4071  HMODULE m = NULL, l = LoadLibrary("psapi.dll");
4072  DWORD need;
4073  typedef BOOL (WINAPI *epmfunc)(HANDLE, HMODULE *, DWORD, LPDWORD);
4074  typedef BOOL (WINAPI *gmbfunc)(HANDLE, HMODULE, LPSTR, DWORD);
4075  epmfunc epm;
4076  gmbfunc gmb;
4077 
4078  if (l) {
4079  epm = (epmfunc) GetProcAddress(l, "EnumProcessModules");
4080  gmb = (gmbfunc) GetProcAddress(l, "GetModuleBaseNameA");
4081  if (epm && gmb && epm(h, &m, sizeof (m), &need)) {
4082  gmb(h, m, pname, sizeof (pname));
4083  }
4084  FreeLibrary(l);
4085  }
4086  CloseHandle(h);
4087  }
4088  d->xcelqrx = strncasecmp(pname, "EXCEL", 5) == 0 ||
4089  strncasecmp(pname, "MSQRY", 5) == 0;
4090  if (d->trace && d->xcelqrx) {
4091 
4092  fprintf(d->trace, "-- enabled EXCEL quirks\n");
4093  fflush(d->trace);
4094  }
4095  }
4096 #endif
4097  sqlite3_create_function(d->sqlite, "blob_import", 1, SQLITE_UTF8,
4098  d, blob_import, 0, 0);
4099  sqlite3_create_function(d->sqlite, "blob_export", 2, SQLITE_UTF8,
4100  d, blob_export, 0, 0);
4101  return SQL_SUCCESS;
4102 }
4103 
4110 static void
4111 dbloadext(DBC *d, char *exts)
4112 {
4113 #if defined(HAVE_SQLITE3LOADEXTENSION) && (HAVE_SQLITE3LOADEXTENSION)
4114  char *p;
4115  char path[SQL_MAX_MESSAGE_LENGTH];
4116  int plen = 0;
4117 
4118  if (!d->sqlite) {
4119  return;
4120  }
4121  sqlite3_enable_load_extension(d->sqlite, 1);
4122 #if defined(_WIN32) || defined(_WIN64)
4123  GetModuleFileName(hModule, path, sizeof (path));
4124  p = strrchr(path, '\\');
4125  plen = p ? ((p + 1) - path) : 0;
4126 #endif
4127  do {
4128  p = strchr(exts, ',');
4129  if (p) {
4130  strncpy(path + plen, exts, p - exts);
4131  path[plen + (p - exts)] = '\0';
4132  } else {
4133  strcpy(path + plen, exts);
4134  }
4135  if (exts[0]) {
4136  char *errmsg = NULL;
4137  int rc;
4138 #if defined(_WIN32) || defined(_WIN64)
4139  int i;
4140  char *q;
4141 
4142  q = path + plen;
4143  if (!(q[0] &&
4144  ((q[1] == ':' && (q[2] == '\\' || q[2] == '/')) ||
4145  q[0] == '\\' || q[0] == '/' || q[0] == '.'))) {
4146  q = path;
4147  }
4148  /* sqlite3_load_extension() dislikes backslashes */
4149  for (i = 0; q[i] != '\0'; i++) {
4150  if (q[i] == '\\') {
4151  q[i] = '/';
4152  }
4153  }
4154  rc = sqlite3_load_extension(d->sqlite, q, 0, &errmsg);
4155 #else
4156  rc = sqlite3_load_extension(d->sqlite, path, 0, &errmsg);
4157 #endif
4158  if (rc != SQLITE_OK) {
4159 #if defined(_WIN32) || defined(_WIN64)
4160  char buf[512], msg[512];
4161 
4162  LoadString(hModule, IDS_EXTERR, buf, sizeof (buf));
4163  wsprintf(msg, buf, q, errmsg ?
4164  errmsg : "no error info available");
4165  LoadString(hModule, IDS_EXTTITLE, buf, sizeof (buf));
4166  MessageBox(NULL, msg, buf,
4167  MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
4168  MB_SETFOREGROUND);
4169 #else
4170  fprintf(stderr, "extension '%s' did not load%s%s\n",
4171  path, errmsg ? ": " : "", errmsg ? errmsg : "");
4172 #endif
4173  }
4174  }
4175  if (p) {
4176  exts = p + 1;
4177  }
4178  } while (p);
4179 #endif /* HAVE_SQLITE3LOADEXTENSION */
4180 }
4181 
4191 static char *
4192 s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
4193 {
4194  char *typename = (char *) sqlite3_column_decltype(s3stmt, col);
4195  char guess[64];
4196 
4197  guess[0] = '\0';
4198  if (!typename) {
4199  int coltype = sqlite3_column_type(s3stmt, col);
4200 
4201  if (guessed_types) {
4202  guessed_types[0]++;
4203  }
4204  if (d->trace) {
4205  sprintf(guess, " (guessed from %d)", coltype);
4206  }
4207  switch (coltype) {
4208  case SQLITE_INTEGER: typename = "integer"; break;
4209  case SQLITE_FLOAT: typename = "double"; break;
4210  default:
4211  case SQLITE_TEXT: typename = "varchar"; break;
4212  case SQLITE_BLOB: typename = "blob"; break;
4213 #if 0
4214  case SQLITE_NULL: typename = "null"; break;
4215 #endif
4216  }
4217  }
4218  if (d->trace) {
4219  fprintf(d->trace, "-- column %d type%s: '%s'\n", col + 1,
4220  guess, typename);
4221  fflush(d->trace);
4222  }
4223  return typename;
4224 }
4225 
4226 #ifdef FULL_METADATA
4227 
4236 static void
4237 s3stmt_addmeta(sqlite3_stmt *s3stmt, int col, DBC *d, COL *ci)
4238 {
4239  int nn = 0, pk = 0, ai = 0;
4240  const char *dn = NULL, *tn = NULL, *cn = NULL, *dummy[4];
4241 
4242  dn = sqlite3_column_database_name(s3stmt, col);
4243  tn = sqlite3_column_table_name(s3stmt, col);
4244  cn = sqlite3_column_origin_name(s3stmt, col);
4245  dummy[0] = dummy[1] = 0;
4246  if (tn && cn) {
4247  sqlite3_table_column_metadata(d->sqlite, dn, tn, cn,
4248  dummy, dummy + 1,
4249  &nn, &pk, &ai);
4250  }
4251  ci->autoinc = ai ? SQL_TRUE: SQL_FALSE;
4252  ci->notnull = nn ? SQL_NO_NULLS : SQL_NULLABLE;
4253  ci->ispk = pk ? 1 : 0;
4254  if (d->trace) {
4255  fprintf(d->trace, "-- column %d %s\n",
4256  col + 1, nn ? "notnull" : "nullable");
4257  if (ai) {
4258  fprintf(d->trace, "-- column %d autoincrement\n", col + 1);
4259  }
4260  fflush(d->trace);
4261  }
4262  ci->isrowid = 0;
4263  if (ci->ispk && tn) {
4264  nn = pk = ai = 0;
4265  dummy[2] = dummy[3] = 0;
4266 
4267  sqlite3_table_column_metadata(d->sqlite, dn, tn, "rowid",
4268  dummy + 2, dummy + 3,
4269  &nn, &pk, &ai);
4270  if (pk && dummy[0] && dummy[0] == dummy[2]) {
4271  ci->isrowid = 1;
4272  }
4273  }
4274 }
4275 
4276 #endif
4277 
4284 static int
4286 {
4287  DBC *d = (DBC *) s->dbc;
4288  char **rowd = NULL;
4289  const char *errp = NULL;
4290  int i, ncols, rc;
4291 
4292  if (s != d->cur_s3stmt || !s->s3stmt) {
4293  setstat(s, -1, "stale statement", (*s->ov3) ? "HY000" : "S1000");
4294  return SQL_ERROR;
4295  }
4296  rc = sqlite3_step(s->s3stmt);
4297  if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
4298  ++s->s3stmt_rownum;
4299  ncols = sqlite3_column_count(s->s3stmt);
4300  if (d->s3stmt_needmeta && s->s3stmt_rownum == 0 && ncols > 0) {
4301  PTRDIFF_T size;
4302  char *p;
4303  COL *dyncols;
4304  const char *colname, *typename;
4305 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4306  char *tblname;
4307 #endif
4308 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
4309  char *dbname;
4310 #endif
4311 
4312  for (i = size = 0; i < ncols; i++) {
4313  colname = sqlite3_column_name(s->s3stmt, i);
4314  size += 3 + 3 * strlen(colname);
4315  }
4316 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4317  tblname = (char *) size;
4318  for (i = 0; i < ncols; i++) {
4319  p = (char *) sqlite3_column_table_name(s->s3stmt, i);
4320  size += 2 + (p ? strlen(p) : 0);
4321  }
4322 #endif
4323 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
4324  dbname = (char *) size;
4325  for (i = 0; i < ncols; i++) {
4326  p = (char *) sqlite3_column_database_name(s->s3stmt, i);
4327  size += 2 + (p ? strlen(p) : 0);
4328  }
4329 #endif
4330  dyncols = xmalloc(ncols * sizeof (COL) + size);
4331  if (!dyncols) {
4332  freedyncols(s);
4333  s->ncols = 0;
4334  dbtraceapi(d, "sqlite3_finalize", 0);
4335  sqlite3_finalize(s->s3stmt);
4336  s->s3stmt = NULL;
4337  d->cur_s3stmt = NULL;
4338  return nomem(s);
4339  }
4340  p = (char *) (dyncols + ncols);
4341 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4342  tblname = p + (PTRDIFF_T) tblname;
4343 #endif
4344 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
4345  dbname = p + (PTRDIFF_T) dbname;
4346 #endif
4347  for (i = 0; i < ncols; i++) {
4348  char *q;
4349 
4350  colname = sqlite3_column_name(s->s3stmt, i);
4351  if (d->trace) {
4352  fprintf(d->trace, "-- column %d name: '%s'\n",
4353  i + 1, colname);
4354  fflush(d->trace);
4355  }
4356 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4357  q = (char *) sqlite3_column_table_name(s->s3stmt, i);
4358  strcpy(tblname, q ? q : "");
4359  if (d->trace) {
4360  fprintf(d->trace, "-- table %d name: '%s'\n",
4361  i + 1, tblname);
4362  fflush(d->trace);
4363  }
4364  dyncols[i].table = tblname;
4365  tblname += strlen(tblname) + 1;
4366 #endif
4367 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
4368  q = (char *) sqlite3_column_database_name(s->s3stmt, i);
4369  strcpy(dbname, q ? q : "");
4370  if (d->trace) {
4371  fprintf(d->trace, "-- database %d name: '%s'\n",
4372  i + 1, dbname);
4373  fflush(d->trace);
4374  }
4375  dyncols[i].db = dbname;
4376  dbname += strlen(dbname) + 1;
4377 #else
4378  dyncols[i].db = ((DBC *) (s->dbc))->dbname;
4379 #endif
4380  typename = s3stmt_coltype(s->s3stmt, i, d, 0);
4381  strcpy(p, colname);
4382  dyncols[i].label = p;
4383  p += strlen(p) + 1;
4384  q = strchr(colname, '.');
4385  if (q) {
4386  char *q2 = strchr(q + 1, '.');
4387 
4388  /* SQLite 3.3.4 produces view.table.column sometimes */
4389  if (q2) {
4390  q = q2;
4391  }
4392  }
4393  if (q) {
4394 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
4395  dyncols[i].table = p;
4396 #endif
4397  strncpy(p, colname, q - colname);
4398  p[q - colname] = '\0';
4399  p += strlen(p) + 1;
4400  strcpy(p, q + 1);
4401  dyncols[i].column = p;
4402  p += strlen(p) + 1;
4403  } else {
4404 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
4405  dyncols[i].table = "";
4406 #endif
4407  strcpy(p, colname);
4408  dyncols[i].column = p;
4409  p += strlen(p) + 1;
4410  }
4411  if (s->longnames) {
4412  dyncols[i].column = dyncols[i].label;
4413  }
4414 #ifdef SQL_LONGVARCHAR
4415  dyncols[i].type = SQL_LONGVARCHAR;
4416  dyncols[i].size = 65535;
4417 #else
4418  dyncols[i].type = SQL_VARCHAR;
4419  dyncols[i].size = 255;
4420 #endif
4421  dyncols[i].index = i;
4422  dyncols[i].scale = 0;
4423  dyncols[i].prec = 0;
4424  dyncols[i].nosign = 1;
4425  dyncols[i].autoinc = SQL_FALSE;
4426  dyncols[i].notnull = SQL_NULLABLE;
4427  dyncols[i].ispk = -1;
4428  dyncols[i].isrowid = -1;
4429 #ifdef FULL_METADATA
4430  s3stmt_addmeta(s->s3stmt, i, d, &dyncols[i]);
4431 #endif
4432  dyncols[i].typename = xstrdup(typename);
4433  }
4434  freedyncols(s);
4435  s->ncols = s->dcols = ncols;
4436  s->dyncols = s->cols = dyncols;
4437  fixupdyncols(s, d);
4438  mkbindcols(s, s->ncols);
4439  d->s3stmt_needmeta = 0;
4440  }
4441  if (ncols <= 0) {
4442  goto killstmt;
4443  }
4444  if (rc == SQLITE_DONE) {
4445  freeresult(s, 0);
4446  s->nrows = 0;
4447  dbtraceapi(d, "sqlite3_finalize", 0);
4448  sqlite3_finalize(s->s3stmt);
4449  s->s3stmt = NULL;
4450  d->cur_s3stmt = NULL;
4451  return SQL_SUCCESS;
4452  }
4453  rowd = xmalloc((1 + 2 * ncols) * sizeof (char *));
4454  if (rowd) {
4455  const unsigned char *value;
4456 
4457  rowd[0] = (char *) ((PTRDIFF_T) (ncols * 2));
4458  ++rowd;
4459  for (i = 0; i < ncols; i++) {
4460  int coltype = sqlite3_column_type(s->s3stmt, i);
4461 
4462  rowd[i] = rowd[i + ncols] = NULL;
4463  if (coltype == SQLITE_BLOB) {
4464  int k, nbytes = sqlite3_column_bytes(s->s3stmt, i);
4465  char *qp;
4466  unsigned const char *bp;
4467 
4468  bp = sqlite3_column_blob(s->s3stmt, i);
4469  qp = xmalloc(nbytes * 2 + 4);
4470  if (qp) {
4471  rowd[i + ncols] = qp;
4472  *qp++ = 'X';
4473  *qp++ = '\'';
4474  for (k = 0; k < nbytes; k++) {
4475  *qp++ = xdigits[(bp[k] >> 4)];
4476  *qp++ = xdigits[(bp[k] & 0xF)];
4477  }
4478  *qp++ = '\'';
4479  *qp = '\0';
4480  }
4481 #ifdef _MSC_VER
4482  } else if (coltype == SQLITE_FLOAT) {
4483  struct lconv *lc = 0;
4484  double d = sqlite3_column_double(s->s3stmt, i);
4485  char *p, buffer[128];
4486 
4487  /*
4488  * This avoids floating point rounding
4489  * and formatting problems of some SQLite
4490  * versions in conjunction with MSVC 2010.
4491  */
4492  snprintf(buffer, sizeof (buffer), "%.15g", d);
4493  lc = localeconv();
4494  if (lc && lc->decimal_point && lc->decimal_point[0] &&
4495  lc->decimal_point[0] != '.') {
4496  p = strchr(buffer, lc->decimal_point[0]);
4497  if (p) {
4498  *p = '.';
4499  }
4500  }
4501  rowd[i + ncols] = xstrdup(buffer);
4502 #endif
4503  } else if (coltype != SQLITE_NULL) {
4504  value = sqlite3_column_text(s->s3stmt, i);
4505  rowd[i + ncols] = xstrdup((char *) value);
4506  }
4507  }
4508  for (i = 0; i < ncols; i++) {
4509  int coltype = sqlite3_column_type(s->s3stmt, i);
4510 
4511  value = NULL;
4512  if (coltype == SQLITE_BLOB) {
4513  value = sqlite3_column_blob(s->s3stmt, i);
4514  } else if (coltype != SQLITE_NULL) {
4515  value = sqlite3_column_text(s->s3stmt, i);
4516  }
4517  if (value && !rowd[i + ncols]) {
4518  freerows(rowd);
4519  rowd = 0;
4520  break;
4521  }
4522  }
4523  }
4524  if (rowd) {
4525  freeresult(s, 0);
4526  s->nrows = 1;
4527  s->rows = rowd;
4528  s->rowfree = freerows;
4529  if (rc == SQLITE_DONE) {
4530  dbtraceapi(d, "sqlite3_finalize", 0);
4531  sqlite3_finalize(s->s3stmt);
4532  s->s3stmt = NULL;
4533  d->cur_s3stmt = NULL;
4534  }
4535  return SQL_SUCCESS;
4536  }
4537  }
4538 killstmt:
4539  dbtraceapi(d, "sqlite3_reset", 0);
4540  rc = sqlite3_reset(s->s3stmt);
4541  s->s3stmt_noreset = 1;
4542  errp = sqlite3_errmsg(d->sqlite);
4543  if (d->cur_s3stmt == s) {
4544  d->cur_s3stmt = NULL;
4545  }
4546  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
4547  errp ? errp : "unknown error", rc);
4548  return SQL_ERROR;
4549 }
4550 
4556 static void
4558 {
4559  DBC *d;
4560 
4561  if (!s || !s->s3stmt) {
4562  return;
4563  }
4564  d = (DBC *) s->dbc;
4565  if (d) {
4566  d->busyint = 0;
4567  }
4568  if (!s->s3stmt_noreset) {
4569  dbtraceapi(d, "sqlite3_reset", 0);
4570  sqlite3_reset(s->s3stmt);
4571  s->s3stmt_noreset = 1;
4572  s->s3stmt_rownum = -1;
4573  }
4574  if (d->cur_s3stmt == s) {
4575  d->cur_s3stmt = NULL;
4576  }
4577 }
4578 
4584 static void
4586 {
4587  DBC *d = (DBC *) s->dbc;
4588 
4589  if (d) {
4590  d->busyint = 0;
4591  }
4592  if (d && d->cur_s3stmt == s) {
4593  s3stmt_end(s);
4594  }
4595 }
4596 
4602 static void
4604 {
4605  if (s->s3stmt) {
4606  DBC *d = (DBC *) s->dbc;
4607 
4608  if (d) {
4609  dbtraceapi(d, "sqlite3_finalize", 0);
4610  }
4611  sqlite3_finalize(s->s3stmt);
4612  s->s3stmt = NULL;
4613  s->s3stmt_rownum = 0;
4614  }
4615 }
4616 
4623 static SQLRETURN
4625 {
4626  DBC *d = (DBC *) s->dbc;
4627  const char *endp;
4628  sqlite3_stmt *s3stmt = NULL;
4629  int rc, nretry = 0;
4630 
4631  d->s3stmt_needmeta = 0;
4632  if (!s->s3stmt) {
4633 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
4634  dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
4635 #else
4636  dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
4637 #endif
4638  do {
4639  s3stmt = NULL;
4640 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
4641  rc = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
4642  &s3stmt, &endp);
4643 #else
4644  rc = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
4645  &s3stmt, &endp);
4646 #endif
4647  if (rc != SQLITE_OK) {
4648  if (s3stmt) {
4649  sqlite3_finalize(s3stmt);
4650  s3stmt = NULL;
4651  }
4652  }
4653  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
4654  dbtracerc(d, rc, NULL);
4655  if (rc != SQLITE_OK) {
4656  if (s3stmt) {
4657  dbtraceapi(d, "sqlite3_finalize", NULL);
4658  sqlite3_finalize(s3stmt);
4659  }
4660  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
4661  sqlite3_errmsg(d->sqlite), rc);
4662  return SQL_ERROR;
4663  }
4664  if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
4665  dbtraceapi(d, "sqlite3_finalize", 0);
4666  sqlite3_finalize(s3stmt);
4667  setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
4668  (*s->ov3) ? "HY000" : "S1000");
4669  return SQL_ERROR;
4670  }
4671  s->s3stmt = s3stmt;
4672  s->s3stmt_noreset = 1;
4673  d->s3stmt_needmeta = 1;
4674  }
4675  d->cur_s3stmt = s;
4676  s->s3stmt_rownum = -1;
4677  s3bind(d, s->s3stmt, s->nparams, s->bindparms);
4678  return SQL_SUCCESS;
4679 }
4680 
4681 #ifndef WINTERFACE
4682 
4686 SQLRETURN SQL_API
4687 SQLDataSources(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *srvname,
4688  SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
4689  SQLCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
4690 {
4691  if (env == SQL_NULL_HENV) {
4692  return SQL_INVALID_HANDLE;
4693  }
4694  return SQL_ERROR;
4695 }
4696 #endif
4697 
4698 #ifdef WINTERFACE
4699 
4703 SQLRETURN SQL_API
4704 SQLDataSourcesW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *srvname,
4705  SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
4706  SQLWCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
4707 {
4708  if (env == SQL_NULL_HENV) {
4709  return SQL_INVALID_HANDLE;
4710  }
4711  return SQL_ERROR;
4712 }
4713 #endif
4714 
4715 #ifndef WINTERFACE
4716 
4720 SQLRETURN SQL_API
4721 SQLDrivers(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *drvdesc,
4722  SQLSMALLINT descmax, SQLSMALLINT *desclenp,
4723  SQLCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
4724 {
4725  if (env == SQL_NULL_HENV) {
4726  return SQL_INVALID_HANDLE;
4727  }
4728  return SQL_ERROR;
4729 }
4730 #endif
4731 
4732 #ifdef WINTERFACE
4733 
4737 SQLRETURN SQL_API
4738 SQLDriversW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *drvdesc,
4739  SQLSMALLINT descmax, SQLSMALLINT *desclenp,
4740  SQLWCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
4741 {
4742  if (env == SQL_NULL_HENV) {
4743  return SQL_INVALID_HANDLE;
4744  }
4745  return SQL_ERROR;
4746 }
4747 #endif
4748 
4749 #ifndef WINTERFACE
4750 
4754 SQLRETURN SQL_API
4755 SQLBrowseConnect(SQLHDBC dbc, SQLCHAR *connin, SQLSMALLINT conninLen,
4756  SQLCHAR *connout, SQLSMALLINT connoutMax,
4757  SQLSMALLINT *connoutLen)
4758 {
4759  SQLRETURN ret;
4760 
4761  HDBC_LOCK(dbc);
4762  ret = drvunimpldbc(dbc);
4763  HDBC_UNLOCK(dbc);
4764  return ret;
4765 }
4766 #endif
4767 
4768 #ifdef WINTERFACE
4769 
4773 SQLRETURN SQL_API
4774 SQLBrowseConnectW(SQLHDBC dbc, SQLWCHAR *connin, SQLSMALLINT conninLen,
4775  SQLWCHAR *connout, SQLSMALLINT connoutMax,
4776  SQLSMALLINT *connoutLen)
4777 {
4778  SQLRETURN ret;
4779 
4780  HDBC_LOCK(dbc);
4781  ret = drvunimpldbc(dbc);
4782  HDBC_UNLOCK(dbc);
4783  return ret;
4784 }
4785 #endif
4786 
4795 static SQLRETURN
4796 drvputdata(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
4797 {
4798  STMT *s;
4799  int i, dlen, done = 0;
4800  BINDPARM *p;
4801 
4802  if (stmt == SQL_NULL_HSTMT) {
4803  return SQL_INVALID_HANDLE;
4804  }
4805  s = (STMT *) stmt;
4806  if (!s->query || s->nparams <= 0) {
4807 seqerr:
4808  setstat(s, -1, "sequence error", "HY010");
4809  return SQL_ERROR;
4810  }
4811  for (i = (s->pdcount < 0) ? 0 : s->pdcount; i < s->nparams; i++) {
4812  p = &s->bindparms[i];
4813  if (p->need > 0) {
4814  int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
4815 
4816  if (len == SQL_NULL_DATA) {
4817  freep(&p->parbuf);
4818  p->param = NULL;
4819  p->len = SQL_NULL_DATA;
4820  p->need = -1;
4821  } else if (type != SQL_C_CHAR
4822 #ifdef WCHARSUPPORT
4823  && type != SQL_C_WCHAR
4824 #endif
4825  && type != SQL_C_BINARY) {
4826  int size = 0;
4827 
4828  switch (type) {
4829  case SQL_C_TINYINT:
4830  case SQL_C_UTINYINT:
4831  case SQL_C_STINYINT:
4832 #ifdef SQL_BIT
4833  case SQL_C_BIT:
4834 #endif
4835  size = sizeof (SQLCHAR);
4836  break;
4837  case SQL_C_SHORT:
4838  case SQL_C_USHORT:
4839  case SQL_C_SSHORT:
4840  size = sizeof (SQLSMALLINT);
4841  break;
4842  case SQL_C_LONG:
4843  case SQL_C_ULONG:
4844  case SQL_C_SLONG:
4845  size = sizeof (SQLINTEGER);
4846  break;
4847 #ifdef SQL_BIGINT
4848  case SQL_C_UBIGINT:
4849  case SQL_C_SBIGINT:
4850  size = sizeof (SQLBIGINT);
4851  break;
4852 #endif
4853  case SQL_C_FLOAT:
4854  size = sizeof (float);
4855  break;
4856  case SQL_C_DOUBLE:
4857  size = sizeof (double);
4858  break;
4859 #ifdef SQL_C_TYPE_DATE
4860  case SQL_C_TYPE_DATE:
4861 #endif
4862  case SQL_C_DATE:
4863  size = sizeof (DATE_STRUCT);
4864  break;
4865 #ifdef SQL_C_TYPE_DATE
4866  case SQL_C_TYPE_TIME:
4867 #endif
4868  case SQL_C_TIME:
4869  size = sizeof (TIME_STRUCT);
4870  break;
4871 #ifdef SQL_C_TYPE_DATE
4872  case SQL_C_TYPE_TIMESTAMP:
4873 #endif
4874  case SQL_C_TIMESTAMP:
4875  size = sizeof (TIMESTAMP_STRUCT);
4876  break;
4877  }
4878  freep(&p->parbuf);
4879  p->parbuf = xmalloc(size);
4880  if (!p->parbuf) {
4881  return nomem(s);
4882  }
4883  p->param = p->parbuf;
4884  memcpy(p->param, data, size);
4885  p->len = size;
4886  p->need = -1;
4887  } else if (len == SQL_NTS && (
4888  type == SQL_C_CHAR
4889 #ifdef WCHARSUPPORT
4890  || type == SQL_C_WCHAR
4891 #endif
4892  )) {
4893  char *dp = data;
4894 
4895 #ifdef WCHARSUPPORT
4896  if (type == SQL_C_WCHAR) {
4897  dp = uc_to_utf(data, len);
4898  if (!dp) {
4899  return nomem(s);
4900  }
4901  }
4902 #endif
4903 #if defined(_WIN32) || defined(_WIN64)
4904  if (*s->oemcp) {
4905  dp = wmb_to_utf(data, strlen (data));
4906  if (!dp) {
4907  return nomem(s);
4908  }
4909  }
4910 #endif
4911  dlen = strlen(dp);
4912  freep(&p->parbuf);
4913  p->parbuf = xmalloc(dlen + 1);
4914  if (!p->parbuf) {
4915  if (dp != data) {
4916  uc_free(dp);
4917  }
4918  return nomem(s);
4919  }
4920  p->param = p->parbuf;
4921  strcpy(p->param, dp);
4922  if (dp != data) {
4923  uc_free(dp);
4924  }
4925  p->len = dlen;
4926  p->need = -1;
4927  } else if (len < 0) {
4928  setstat(s, -1, "invalid length", "HY090");
4929  return SQL_ERROR;
4930  } else {
4931  dlen = min(p->len - p->offs, len);
4932  if (!p->param) {
4933  setstat(s, -1, "no memory for parameter", "HY013");
4934  return SQL_ERROR;
4935  }
4936  memcpy((char *) p->param + p->offs, data, dlen);
4937  p->offs += dlen;
4938  if (p->offs >= p->len) {
4939 #ifdef WCHARSUPPORT
4940  if (type == SQL_C_WCHAR) {
4941  char *dp = uc_to_utf(p->param, p->len);
4942  char *np;
4943  int nlen;
4944 
4945  if (!dp) {
4946  return nomem(s);
4947  }
4948  nlen = strlen(dp);
4949  np = xmalloc(nlen + 1);
4950  if (!np) {
4951  uc_free(dp);
4952  return nomem(s);
4953  }
4954  strcpy(np, dp);
4955  uc_free(dp);
4956  if (p->param == p->parbuf) {
4957  freep(&p->parbuf);
4958  }
4959  p->parbuf = p->param = np;
4960  p->len = nlen;
4961  } else {
4962  *((char *) p->param + p->len) = '\0';
4963  }
4964  p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR)
4965  ? -1 : 0;
4966 #else
4967  *((char *) p->param + p->len) = '\0';
4968  p->need = (type == SQL_C_CHAR) ? -1 : 0;
4969 #endif
4970 #if defined(_WIN32) || defined(_WIN64)
4971  if (type == SQL_C_CHAR && *s->oemcp &&
4972  !(p->stype == SQL_BINARY ||
4973  p->stype == SQL_VARBINARY ||
4974  p->stype == SQL_LONGVARBINARY)) {
4975  char *dp = wmb_to_utf(p->param, p->len);
4976 
4977  if (!dp) {
4978  return nomem(s);
4979  }
4980  if (p->param == p->parbuf) {
4981  freep(&p->parbuf);
4982  }
4983  p->parbuf = p->param = dp;
4984  p->len = strlen(dp);
4985  }
4986  if (p->type == SQL_C_WCHAR &&
4987  (p->stype == SQL_VARCHAR ||
4988  p->stype == SQL_LONGVARCHAR) &&
4989  p->len == p->coldef * sizeof (SQLWCHAR)) {
4990  /* fix for MS-Access */
4991  p->len = p->coldef;
4992  }
4993 #endif
4994  }
4995  }
4996  done = 1;
4997  break;
4998  }
4999  }
5000  if (!done) {
5001  goto seqerr;
5002  }
5003  return SQL_SUCCESS;
5004 }
5005 
5014 SQLRETURN SQL_API
5015 SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
5016 {
5017  SQLRETURN ret;
5018 
5019  HSTMT_LOCK(stmt);
5020  ret = drvputdata(stmt, data, len);
5021  HSTMT_UNLOCK(stmt);
5022  return ret;
5023 }
5024 
5030 static SQLRETURN
5032 {
5033  if (s->bindparms) {
5034  int n;
5035 
5036  for (n = 0; n < s->nbindparms; n++) {
5037  freep(&s->bindparms[n].parbuf);
5038  memset(&s->bindparms[n], 0, sizeof (BINDPARM));
5039  }
5040  }
5041  return SQL_SUCCESS;
5042 }
5043 
5055 static SQLRETURN
5056 setupparam(STMT *s, char *sql, int pnum)
5057 {
5058  int type, len = 0, needalloc = 0;
5059  BINDPARM *p;
5060 
5061  if (!s->bindparms || pnum < 0 || pnum >= s->nbindparms) {
5062  goto error;
5063  }
5064  p = &s->bindparms[pnum];
5065  type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
5066 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
5067  /* MS Access hack part 4 (map SQL_C_DEFAULT to SQL_C_CHAR) */
5068  if (type == SQL_C_WCHAR && p->type == SQL_C_DEFAULT) {
5069  type = SQL_C_CHAR;
5070  }
5071 #endif
5072  if (p->need > 0) {
5073  return setupparbuf(s, p);
5074  }
5075  p->strbuf[0] = '\0';
5076  if (!p->param || (p->lenp && *p->lenp == SQL_NULL_DATA)) {
5077  p->s3type = SQLITE_NULL;
5078  p->s3size = 0;
5079  return SQL_SUCCESS;
5080  }
5081  if (type == SQL_C_CHAR &&
5082  (p->stype == SQL_BINARY ||
5083  p->stype == SQL_VARBINARY ||
5084  p->stype == SQL_LONGVARBINARY)) {
5085  type = SQL_C_BINARY;
5086  }
5087  switch (type) {
5088  case SQL_C_BINARY:
5089  p->s3type = SQLITE_BLOB;
5090  p->s3size = p->len;
5091  p->s3val = p->param;
5092  if (p->need < 0) {
5093  break;
5094  }
5095  if (!p->lenp) {
5096  len = p->len;
5097  } else if (*p->lenp == SQL_DATA_AT_EXEC) {
5098  len = p->len;
5099  } else {
5100  len = *p->lenp;
5101  if (len <= SQL_LEN_DATA_AT_EXEC_OFFSET) {
5102  len = SQL_LEN_DATA_AT_EXEC(len);
5103  }
5104  }
5105  if (len < 0) {
5106  setstat(s, -1, "invalid length", "HY009");
5107  return SQL_ERROR;
5108  }
5109  p->len = len;
5110  p->max = p->len;
5111  p->need = -1;
5112  p->s3size = len;
5113  break;
5114 #ifdef WCHARSUPPORT
5115  case SQL_C_WCHAR:
5116 #endif
5117  case SQL_C_CHAR:
5118  p->s3type = SQLITE_TEXT;
5119  p->s3size = -1;
5120  p->s3val = p->param;
5121  if (!p->parbuf) {
5122 #ifdef WCHARSUPPORT
5123  if (type == SQL_C_WCHAR) {
5124  if (!p->lenp || *p->lenp == SQL_NTS) {
5125  p->max = uc_strlen(p->param) * sizeof (SQLWCHAR);
5126  } else if (*p->lenp >= 0) {
5127  p->max = *p->lenp;
5128  }
5129  } else
5130 #endif
5131  if (type == SQL_C_CHAR) {
5132  if (!p->lenp || *p->lenp == SQL_NTS) {
5133  p->len = p->max = strlen(p->param);
5134 #if defined(_WIN32) || defined(_WIN64)
5135  needalloc = 1;
5136 #endif
5137  } else if (*p->lenp >= 0) {
5138  p->len = p->max = *p->lenp;
5139  needalloc = 1;
5140  }
5141  }
5142  }
5143  if (p->need < 0 && p->parbuf == p->param) {
5144  break;
5145  }
5146 #ifdef WCHARSUPPORT
5147  if (type == SQL_C_WCHAR) {
5148  char *dp = uc_to_utf(p->param, p->max);
5149 
5150  if (!dp) {
5151  return nomem(s);
5152  }
5153  if (p->param == p->parbuf) {
5154  freep(&p->parbuf);
5155  }
5156  p->parbuf = p->param = dp;
5157  p->need = -1;
5158  p->len = strlen(p->param);
5159  p->s3val = p->param;
5160  p->s3size = p->len;
5161  } else
5162 #endif
5163  if (type == SQL_C_CHAR) {
5164  p->s3val = p->param;
5165  if (needalloc) {
5166  char *dp;
5167 
5168 #if defined(_WIN32) || defined(_WIN64)
5169  if (*s->oemcp) {
5170  dp = wmb_to_utf(p->param, p->len);
5171  } else {
5172  dp = xmalloc(p->len + 1);
5173  }
5174 #else
5175  dp = xmalloc(p->len + 1);
5176 #endif
5177  if (!dp) {
5178  return nomem(s);
5179  }
5180 #if defined(_WIN32) || defined(_WIN64)
5181  if (*s->oemcp) {
5182  p->len = strlen(dp);
5183  } else {
5184  memcpy(dp, p->param, p->len);
5185  dp[p->len] = '\0';
5186  }
5187 #else
5188  memcpy(dp, p->param, p->len);
5189  dp[p->len] = '\0';
5190 #endif
5191  if (p->param == p->parbuf) {
5192  freep(&p->parbuf);
5193  }
5194  p->parbuf = p->param = dp;
5195  p->need = -1;
5196  p->s3val = p->param;
5197  p->s3size = p->len;
5198  }
5199  }
5200  break;
5201  case SQL_C_UTINYINT:
5202  case SQL_C_TINYINT:
5203  case SQL_C_STINYINT:
5204  p->s3type = SQLITE_INTEGER;
5205  p->s3size = sizeof (int);
5206  p->s3ival = *((SQLCHAR *) p->param);
5207  break;
5208  case SQL_C_USHORT:
5209  p->s3type = SQLITE_INTEGER;
5210  p->s3size = sizeof (int);
5211  p->s3ival = *((SQLUSMALLINT *) p->param);
5212  break;
5213  case SQL_C_SHORT:
5214  case SQL_C_SSHORT:
5215  p->s3type = SQLITE_INTEGER;
5216  p->s3size = sizeof (int);
5217  p->s3ival = *((SQLSMALLINT *) p->param);
5218  break;
5219  case SQL_C_ULONG:
5220  p->s3type = SQLITE_INTEGER;
5221  p->s3size = sizeof (int);
5222  p->s3ival = *((SQLUINTEGER *) p->param);
5223  break;
5224  case SQL_C_LONG:
5225  case SQL_C_SLONG:
5226  p->s3type = SQLITE_INTEGER;
5227  p->s3size = sizeof (int);
5228  p->s3ival = *((SQLINTEGER *) p->param);
5229  break;
5230 #ifdef SQL_BIT
5231  case SQL_C_BIT:
5232  p->s3type = SQLITE_INTEGER;
5233  p->s3size = sizeof (int);
5234  p->s3ival = (*((SQLCHAR *) p->param)) ? 1 : 0;
5235  break;
5236 #endif
5237 #ifdef SQL_BIGINT
5238  case SQL_C_SBIGINT:
5239  p->s3type = SQLITE_INTEGER;
5240  p->s3size = sizeof (sqlite_int64);
5241  p->s3lival = *((sqlite_int64 *) p->param);
5242  break;
5243  case SQL_C_UBIGINT:
5244  p->s3type = SQLITE_INTEGER;
5245  p->s3size = sizeof (sqlite_int64);
5246  p->s3lival = *((sqlite_uint64 *) p->param);
5247  break;
5248 #endif
5249  case SQL_C_FLOAT:
5250  p->s3type = SQLITE_FLOAT;
5251  p->s3size = sizeof (double);
5252  p->s3dval = *((float *) p->param);
5253  break;
5254  case SQL_C_DOUBLE:
5255  p->s3type = SQLITE_FLOAT;
5256  p->s3size = sizeof (double);
5257  p->s3dval = *((double *) p->param);
5258  break;
5259 #ifdef SQL_C_TYPE_DATE
5260  case SQL_C_TYPE_DATE:
5261 #endif
5262  case SQL_C_DATE:
5263  if (*s->jdconv) {
5264  int a, b, x1, x2, y, m, d;
5265 
5266  p->s3type = SQLITE_FLOAT;
5267  p->s3size = sizeof (double);
5268  y = ((DATE_STRUCT *) p->param)->year;
5269  m = ((DATE_STRUCT *) p->param)->month;
5270  d = ((DATE_STRUCT *) p->param)->day;
5271  if (m <= 2) {
5272  y--;
5273  m += 12;
5274  }
5275  a = y / 100;
5276  b = 2 - a + (a / 4);
5277  x1 = 36525 * (y + 4716) / 100;
5278  x2 = 306001 * (m + 1) / 10000;
5279  p->s3dval = x1 + x2 + d + b - 1524.5;
5280  break;
5281  }
5282  sprintf(p->strbuf, "%04d-%02d-%02d",
5283  ((DATE_STRUCT *) p->param)->year,
5284  ((DATE_STRUCT *) p->param)->month,
5285  ((DATE_STRUCT *) p->param)->day);
5286  p->s3type = SQLITE_TEXT;
5287  p->s3size = -1;
5288  p->s3val = p->strbuf;
5289  break;
5290 #ifdef SQL_C_TYPE_TIME
5291  case SQL_C_TYPE_TIME:
5292 #endif
5293  case SQL_C_TIME:
5294  if (*s->jdconv) {
5295  p->s3type = SQLITE_FLOAT;
5296  p->s3size = sizeof (double);
5297  p->s3dval = 2451544.5 +
5298  (((TIME_STRUCT *) p->param)->hour * 3600000.0 +
5299  ((TIME_STRUCT *) p->param)->minute * 60000.0 +
5300  ((TIME_STRUCT *) p->param)->second * 1000.0) / 86400000.0;
5301  break;
5302  }
5303  sprintf(p->strbuf, "%02d:%02d:%02d",
5304  ((TIME_STRUCT *) p->param)->hour,
5305  ((TIME_STRUCT *) p->param)->minute,
5306  ((TIME_STRUCT *) p->param)->second);
5307  p->s3type = SQLITE_TEXT;
5308  p->s3size = -1;
5309  p->s3val = p->strbuf;
5310  break;
5311 #ifdef SQL_C_TYPE_TIMESTAMP
5312  case SQL_C_TYPE_TIMESTAMP:
5313 #endif
5314  case SQL_C_TIMESTAMP:
5315  if (*s->jdconv) {
5316  int a, b, x1, x2, y, m, d;
5317 
5318  p->s3type = SQLITE_FLOAT;
5319  p->s3size = sizeof (double);
5320  y = ((TIMESTAMP_STRUCT *) p->param)->year;
5321  m = ((TIMESTAMP_STRUCT *) p->param)->month;
5322  d = ((TIMESTAMP_STRUCT *) p->param)->day;
5323  if (m <= 2) {
5324  y--;
5325  m += 12;
5326  }
5327  a = y / 100;
5328  b = 2 - a + (a / 4);
5329  x1 = 36525 * (y + 4716) / 100;
5330  x2 = 306001 * (m + 1) / 10000;
5331  p->s3dval = x1 + x2 + d + b - 1524.5 +
5332  (((TIMESTAMP_STRUCT *) p->param)->hour * 3600000.0 +
5333  ((TIMESTAMP_STRUCT *) p->param)->minute * 60000.0 +
5334  ((TIMESTAMP_STRUCT *) p->param)->second * 1000.0 +
5335  ((TIMESTAMP_STRUCT *) p->param)->fraction / 1.0E6)
5336  / 86400000.0;
5337  break;
5338  }
5339  len = (int) ((TIMESTAMP_STRUCT *) p->param)->fraction;
5340  len /= 1000000;
5341  len = len % 1000;
5342  if (len < 0) {
5343  len = 0;
5344  }
5345  if (p->coldef && p->coldef <= 16) {
5346  sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
5347  ((TIMESTAMP_STRUCT *) p->param)->year,
5348  ((TIMESTAMP_STRUCT *) p->param)->month,
5349  ((TIMESTAMP_STRUCT *) p->param)->day,
5350  ((TIMESTAMP_STRUCT *) p->param)->hour,
5351  ((TIMESTAMP_STRUCT *) p->param)->minute);
5352  } else if (p->coldef && p->coldef <= 19) {
5353  sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
5354  ((TIMESTAMP_STRUCT *) p->param)->year,
5355  ((TIMESTAMP_STRUCT *) p->param)->month,
5356  ((TIMESTAMP_STRUCT *) p->param)->day,
5357  ((TIMESTAMP_STRUCT *) p->param)->hour,
5358  ((TIMESTAMP_STRUCT *) p->param)->minute,
5359  ((TIMESTAMP_STRUCT *) p->param)->second);
5360  } else {
5361  sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
5362  ((TIMESTAMP_STRUCT *) p->param)->year,
5363  ((TIMESTAMP_STRUCT *) p->param)->month,
5364  ((TIMESTAMP_STRUCT *) p->param)->day,
5365  ((TIMESTAMP_STRUCT *) p->param)->hour,
5366  ((TIMESTAMP_STRUCT *) p->param)->minute,
5367  ((TIMESTAMP_STRUCT *) p->param)->second,
5368  len);
5369  }
5370  p->s3type = SQLITE_TEXT;
5371  p->s3size = -1;
5372  p->s3val = p->strbuf;
5373  break;
5374  default:
5375  error:
5376  setstat(s, -1, "unsupported parameter type",
5377  (*s->ov3) ? "07009" : "S1093");
5378  return SQL_ERROR;
5379  }
5380  return SQL_SUCCESS;
5381 }
5382 
5398 static SQLRETURN
5399 drvbindparam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
5400  SQLSMALLINT buftype, SQLSMALLINT ptype, SQLUINTEGER coldef,
5401  SQLSMALLINT scale,
5402  SQLPOINTER data, SQLINTEGER buflen, SQLLEN *len)
5403 {
5404  STMT *s;
5405  BINDPARM *p;
5406 
5407  if (stmt == SQL_NULL_HSTMT) {
5408  return SQL_INVALID_HANDLE;
5409  }
5410  s = (STMT *) stmt;
5411  if (pnum == 0) {
5412  setstat(s, -1, "invalid parameter", (*s->ov3) ? "07009" : "S1093");
5413  return SQL_ERROR;
5414  }
5415  if (!data && !len) {
5416  setstat(s, -1, "invalid buffer", "HY003");
5417  return SQL_ERROR;
5418  }
5419  --pnum;
5420  if (s->bindparms) {
5421  if (pnum >= s->nbindparms) {
5422  BINDPARM *newparms;
5423 
5424  newparms = xrealloc(s->bindparms,
5425  (pnum + 1) * sizeof (BINDPARM));
5426  if (!newparms) {
5427 outofmem:
5428  return nomem(s);
5429  }
5430  s->bindparms = newparms;
5431  memset(&s->bindparms[s->nbindparms], 0,
5432  (pnum + 1 - s->nbindparms) * sizeof (BINDPARM));
5433  s->nbindparms = pnum + 1;
5434  }
5435  } else {
5436  int npar = max(10, pnum + 1);
5437 
5438  s->bindparms = xmalloc(npar * sizeof (BINDPARM));
5439  if (!s->bindparms) {
5440  goto outofmem;
5441  }
5442  memset(s->bindparms, 0, npar * sizeof (BINDPARM));
5443  s->nbindparms = npar;
5444  }
5445  switch (buftype) {
5446  case SQL_C_STINYINT:
5447  case SQL_C_UTINYINT:
5448  case SQL_C_TINYINT:
5449 #ifdef SQL_C_BIT
5450  case SQL_C_BIT:
5451 #endif
5452  buflen = sizeof (SQLCHAR);
5453  break;
5454  case SQL_C_SHORT:
5455  case SQL_C_USHORT:
5456  case SQL_C_SSHORT:
5457  buflen = sizeof (SQLSMALLINT);
5458  break;
5459  case SQL_C_SLONG:
5460  case SQL_C_ULONG:
5461  case SQL_C_LONG:
5462  buflen = sizeof (SQLINTEGER);
5463  break;
5464  case SQL_C_FLOAT:
5465  buflen = sizeof (float);
5466  break;
5467  case SQL_C_DOUBLE:
5468  buflen = sizeof (double);
5469  break;
5470  case SQL_C_TIMESTAMP:
5471 #ifdef SQL_C_TYPE_TIMESTAMP
5472  case SQL_C_TYPE_TIMESTAMP:
5473 #endif
5474  buflen = sizeof (TIMESTAMP_STRUCT);
5475  break;
5476  case SQL_C_TIME:
5477 #ifdef SQL_C_TYPE_TIME
5478  case SQL_C_TYPE_TIME:
5479 #endif
5480  buflen = sizeof (TIME_STRUCT);
5481  break;
5482  case SQL_C_DATE:
5483 #ifdef SQL_C_TYPE_DATE
5484  case SQL_C_TYPE_DATE:
5485 #endif
5486  buflen = sizeof (DATE_STRUCT);
5487  break;
5488 #ifdef SQL_C_UBIGINT
5489  case SQL_C_UBIGINT:
5490  buflen = sizeof (SQLBIGINT);
5491  break;
5492 #endif
5493 #ifdef SQL_C_SBIGINT
5494  case SQL_C_SBIGINT:
5495  buflen = sizeof (SQLBIGINT);
5496  break;
5497 #endif
5498 #ifdef SQL_C_BIGINT
5499  case SQL_C_BIGINT:
5500  buflen = sizeof (SQLBIGINT);
5501  break;
5502 #endif
5503  }
5504  p = &s->bindparms[pnum];
5505  p->type = buftype;
5506  p->stype = ptype;
5507  p->coldef = coldef;
5508  p->scale = scale;
5509  p->max = buflen;
5510  p->inc = buflen;
5511  p->lenp = p->lenp0 = len;
5512  p->offs = 0;
5513  p->len = 0;
5514  p->param0 = data;
5515  freep(&p->parbuf);
5516  p->param = p->param0;
5517  p->bound = 1;
5518  p->need = 0;
5519  return SQL_SUCCESS;
5520 }
5521 
5537 SQLRETURN SQL_API
5538 SQLBindParameter(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
5539  SQLSMALLINT buftype, SQLSMALLINT ptype, SQLULEN coldef,
5540  SQLSMALLINT scale,
5541  SQLPOINTER data, SQLLEN buflen, SQLLEN *len)
5542 {
5543  SQLRETURN ret;
5544 
5545  HSTMT_LOCK(stmt);
5546  ret = drvbindparam(stmt, pnum, iotype, buftype, ptype, coldef,
5547  scale, data, buflen, len);
5548  HSTMT_UNLOCK(stmt);
5549  return ret;
5550 }
5551 
5552 #ifndef HAVE_IODBC
5553 
5566 SQLRETURN SQL_API
5567 SQLBindParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT vtype,
5568  SQLSMALLINT ptype, SQLULEN lenprec,
5569  SQLSMALLINT scale, SQLPOINTER val,
5570  SQLLEN *lenp)
5571 {
5572  SQLRETURN ret;
5573 
5574  HSTMT_LOCK(stmt);
5575  ret = drvbindparam(stmt, pnum, SQL_PARAM_INPUT, vtype, ptype,
5576  lenprec, scale, val, 0, lenp);
5577  HSTMT_UNLOCK(stmt);
5578  return ret;
5579 }
5580 #endif
5581 
5589 SQLRETURN SQL_API
5590 SQLNumParams(SQLHSTMT stmt, SQLSMALLINT *nparam)
5591 {
5592  STMT *s;
5593  SQLSMALLINT dummy;
5594 
5595  HSTMT_LOCK(stmt);
5596  if (stmt == SQL_NULL_HSTMT) {
5597  return SQL_INVALID_HANDLE;
5598  }
5599  s = (STMT *) stmt;
5600  if (!nparam) {
5601  nparam = &dummy;
5602  }
5603  *nparam = s->nparams;
5604  HSTMT_UNLOCK(stmt);
5605  return SQL_SUCCESS;
5606 }
5607 
5615 static SQLRETURN
5617 {
5618  if (!p->parbuf) {
5619  if (*p->lenp == SQL_DATA_AT_EXEC) {
5620  p->len = p->max;
5621  } else {
5622  p->len = SQL_LEN_DATA_AT_EXEC(*p->lenp);
5623  }
5624  if (p->len < 0 && p->len != SQL_NTS &&
5625  p->len != SQL_NULL_DATA) {
5626  setstat(s, -1, "invalid length", "HY009");
5627  return SQL_ERROR;
5628  }
5629  if (p->len >= 0) {
5630  p->parbuf = xmalloc(p->len + 2);
5631  if (!p->parbuf) {
5632  return nomem(s);
5633  }
5634  p->param = p->parbuf;
5635  } else {
5636  p->param = NULL;
5637  }
5638  }
5639  return SQL_NEED_DATA;
5640 }
5641 
5649 SQLRETURN SQL_API
5650 SQLParamData(SQLHSTMT stmt, SQLPOINTER *pind)
5651 {
5652  STMT *s;
5653  int i;
5654  SQLPOINTER dummy;
5655  SQLRETURN ret;
5656  BINDPARM *p;
5657 
5658  HSTMT_LOCK(stmt);
5659  if (stmt == SQL_NULL_HSTMT) {
5660  return SQL_INVALID_HANDLE;
5661  }
5662  s = (STMT *) stmt;
5663  if (!pind) {
5664  pind = &dummy;
5665  }
5666  if (s->pdcount < s->nparams) {
5667  s->pdcount++;
5668  }
5669  for (i = 0; i < s->pdcount; i++) {
5670  p = &s->bindparms[i];
5671  if (p->need > 0) {
5672  int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
5673 
5674  p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR) ? -1 : 0;
5675  }
5676  }
5677  for (; i < s->nparams; i++) {
5678  p = &s->bindparms[i];
5679  if (p->need > 0) {
5680  *pind = (SQLPOINTER) p->param0;
5681  ret = setupparbuf(s, p);
5682  s->pdcount = i;
5683  goto done;
5684  }
5685  }
5686  ret = drvexecute(stmt, 0);
5687 done:
5688  HSTMT_UNLOCK(stmt);
5689  return ret;
5690 }
5691 
5703 SQLRETURN SQL_API
5704 SQLDescribeParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT *dtype,
5705  SQLULEN *size, SQLSMALLINT *decdigits, SQLSMALLINT *nullable)
5706 {
5707  STMT *s;
5708  SQLRETURN ret = SQL_ERROR;
5709 
5710  HSTMT_LOCK(stmt);
5711  if (stmt == SQL_NULL_HSTMT) {
5712  return SQL_INVALID_HANDLE;
5713  }
5714  s = (STMT *) stmt;
5715  --pnum;
5716  if (pnum >= s->nparams) {
5717  setstat(s, -1, "invalid parameter index",
5718  (*s->ov3) ? "HY000" : "S1000");
5719  goto done;
5720  }
5721  if (dtype) {
5722 #ifdef SQL_LONGVARCHAR
5723 #ifdef WINTERFACE
5724  *dtype = s->nowchar[0] ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
5725 #else
5726  *dtype = SQL_LONGVARCHAR;
5727 #endif
5728 #else
5729 #ifdef WINTERFACE
5730  *dtype = s->nowchar[0] ? SQL_VARCHAR : SQL_WVARCHAR;
5731 #else
5732  *dtype = SQL_VARCHAR;
5733 #endif
5734 #endif
5735  }
5736  if (size) {
5737 #ifdef SQL_LONGVARCHAR
5738  *size = 65536;
5739 #else
5740  *size = 255;
5741 #endif
5742  }
5743  if (decdigits) {
5744  *decdigits = 0;
5745  }
5746  if (nullable) {
5747  *nullable = SQL_NULLABLE;
5748  }
5749  ret = SQL_SUCCESS;
5750 done:
5751  HSTMT_UNLOCK(stmt);
5752  return ret;
5753 }
5754 
5768 SQLRETURN SQL_API
5769 SQLSetParam(SQLHSTMT stmt, SQLUSMALLINT par, SQLSMALLINT type,
5770  SQLSMALLINT sqltype, SQLULEN coldef,
5771  SQLSMALLINT scale, SQLPOINTER val, SQLLEN *nval)
5772 {
5773  SQLRETURN ret;
5774 
5775  HSTMT_LOCK(stmt);
5776  ret = drvbindparam(stmt, par, SQL_PARAM_INPUT,
5777  type, sqltype, coldef, scale, val,
5778  SQL_SETPARAM_VALUE_MAX, nval);
5779  HSTMT_UNLOCK(stmt);
5780  return ret;
5781 }
5782 
5787 SQLRETURN SQL_API
5788 SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
5789 {
5790  SQLRETURN ret;
5791 
5792  HSTMT_LOCK(stmt);
5793  ret = drvunimplstmt(stmt);
5794  HSTMT_UNLOCK(stmt);
5795  return ret;
5796 }
5797 
5798 #ifndef WINTERFACE
5799 
5803 SQLRETURN SQL_API
5804 SQLGetDescField(SQLHDESC handle, SQLSMALLINT recno,
5805  SQLSMALLINT fieldid, SQLPOINTER value,
5806  SQLINTEGER buflen, SQLINTEGER *strlen)
5807 {
5808  return SQL_ERROR;
5809 }
5810 #endif
5811 
5812 #ifdef WINTERFACE
5813 
5817 SQLRETURN SQL_API
5818 SQLGetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
5819  SQLSMALLINT fieldid, SQLPOINTER value,
5820  SQLINTEGER buflen, SQLINTEGER *strlen)
5821 {
5822  return SQL_ERROR;
5823 }
5824 #endif
5825 
5826 #ifndef WINTERFACE
5827 
5831 SQLRETURN SQL_API
5832 SQLSetDescField(SQLHDESC handle, SQLSMALLINT recno,
5833  SQLSMALLINT fieldid, SQLPOINTER value,
5834  SQLINTEGER buflen)
5835 {
5836  return SQL_ERROR;
5837 }
5838 #endif
5839 
5840 #ifdef WINTERFACE
5841 
5845 SQLRETURN SQL_API
5846 SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
5847  SQLSMALLINT fieldid, SQLPOINTER value,
5848  SQLINTEGER buflen)
5849 {
5850  return SQL_ERROR;
5851 }
5852 #endif
5853 
5854 #ifndef WINTERFACE
5855 
5859 SQLRETURN SQL_API
5860 SQLGetDescRec(SQLHDESC handle, SQLSMALLINT recno,
5861  SQLCHAR *name, SQLSMALLINT buflen,
5862  SQLSMALLINT *strlen, SQLSMALLINT *type,
5863  SQLSMALLINT *subtype, SQLLEN *len,
5864  SQLSMALLINT *prec, SQLSMALLINT *scale,
5865  SQLSMALLINT *nullable)
5866 {
5867  return SQL_ERROR;
5868 }
5869 #endif
5870 
5871 #ifdef WINTERFACE
5872 
5876 SQLRETURN SQL_API
5877 SQLGetDescRecW(SQLHDESC handle, SQLSMALLINT recno,
5878  SQLWCHAR *name, SQLSMALLINT buflen,
5879  SQLSMALLINT *strlen, SQLSMALLINT *type,
5880  SQLSMALLINT *subtype, SQLLEN *len,
5881  SQLSMALLINT *prec, SQLSMALLINT *scale,
5882  SQLSMALLINT *nullable)
5883 {
5884  return SQL_ERROR;
5885 }
5886 #endif
5887 
5892 SQLRETURN SQL_API
5893 SQLSetDescRec(SQLHDESC handle, SQLSMALLINT recno,
5894  SQLSMALLINT type, SQLSMALLINT subtype,
5895  SQLLEN len, SQLSMALLINT prec,
5896  SQLSMALLINT scale, SQLPOINTER data,
5897  SQLLEN *strlen, SQLLEN *indicator)
5898 {
5899  return SQL_ERROR;
5900 }
5901 
5913 static SQLRETURN
5914 mkresultset(HSTMT stmt, COL *colspec, int ncols, COL *colspec3,
5915  int ncols3, int *nret)
5916 {
5917  STMT *s;
5918  DBC *d;
5919 
5920  if (stmt == SQL_NULL_HSTMT) {
5921  return SQL_INVALID_HANDLE;
5922  }
5923  s = (STMT *) stmt;
5924  if (s->dbc == SQL_NULL_HDBC) {
5925 noconn:
5926  return noconn(s);
5927  }
5928  d = (DBC *) s->dbc;
5929  if (!d->sqlite) {
5930  goto noconn;
5931  }
5932  s3stmt_end_if(s);
5933  freeresult(s, 0);
5934  if (colspec3 && *s->ov3) {
5935  s->ncols = ncols3;
5936  s->cols = colspec3;
5937  } else {
5938  s->ncols = ncols;
5939  s->cols = colspec;
5940  }
5941  mkbindcols(s, s->ncols);
5942  s->nowchar[1] = 1;
5943  s->nrows = 0;
5944  s->rowp = s->rowprs = -1;
5945  s->isselect = -1;
5946  if (nret) {
5947  *nret = s->ncols;
5948  }
5949  return SQL_SUCCESS;
5950 }
5951 
5956 static COL tablePrivSpec2[] = {
5957  { "SYSTEM", "TABLEPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
5958  { "SYSTEM", "TABLEPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
5959  { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
5960  { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
5961  { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
5962  { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
5963  { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
5964 };
5965 
5966 static COL tablePrivSpec3[] = {
5967  { "SYSTEM", "TABLEPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
5968  { "SYSTEM", "TABLEPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
5969  { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
5970  { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
5971  { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
5972  { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
5973  { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
5974 };
5975 
5988 static SQLRETURN
5990  SQLCHAR *cat, SQLSMALLINT catLen,
5991  SQLCHAR *schema, SQLSMALLINT schemaLen,
5992  SQLCHAR *table, SQLSMALLINT tableLen)
5993 {
5994  SQLRETURN ret;
5995  STMT *s;
5996  DBC *d;
5997  int ncols, rc, size, npatt;
5998  char *errp = NULL, *sql, tname[512];
5999 
6002  if (ret != SQL_SUCCESS) {
6003  return ret;
6004  }
6005  s = (STMT *) stmt;
6006  d = (DBC *) s->dbc;
6007  if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
6008  table = NULL;
6009  goto doit;
6010  }
6011  if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
6012  schema[0] == '%') {
6013  if ((!cat || catLen == 0 || !cat[0]) &&
6014  (!table || tableLen == 0 || !table[0])) {
6015  table = NULL;
6016  goto doit;
6017  }
6018  }
6019 doit:
6020  if (!table) {
6021  size = 1;
6022  tname[0] = '%';
6023  } else {
6024  if (tableLen == SQL_NTS) {
6025  size = sizeof (tname) - 1;
6026  } else {
6027  size = min(sizeof (tname) - 1, tableLen);
6028  }
6029  strncpy(tname, (char *) table, size);
6030  }
6031  tname[size] = '\0';
6032  npatt = unescpat(tname);
6033 #if defined(_WIN32) || defined(_WIN64)
6034  if (npatt) {
6035  sql = sqlite3_mprintf("select %s as 'TABLE_QUALIFIER', "
6036  "%s as 'TABLE_OWNER', "
6037  "tbl_name as 'TABLE_NAME', "
6038  "'' as 'GRANTOR', "
6039  "'' as 'GRANTEE', "
6040  "'SELECT' AS 'PRIVILEGE', "
6041  "NULL as 'IS_GRANTABLE' "
6042  "from sqlite_master where "
6043  "(type = 'table' or type = 'view') "
6044  "and tbl_name like %Q "
6045  "UNION "
6046  "select %s as 'TABLE_QUALIFIER', "
6047  "%s as 'TABLE_OWNER', "
6048  "tbl_name as 'TABLE_NAME', "
6049  "'' as 'GRANTOR', "
6050  "'' as 'GRANTEE', "
6051  "'UPDATE' AS 'PRIVILEGE', "
6052  "NULL as 'IS_GRANTABLE' "
6053  "from sqlite_master where "
6054  "(type = 'table' or type = 'view') "
6055  "and tbl_name like %Q "
6056  "UNION "
6057  "select %s as 'TABLE_QUALIFIER', "
6058  "%s as 'TABLE_OWNER', "
6059  "tbl_name as 'TABLE_NAME', "
6060  "'' as 'GRANTOR', "
6061  "'' as 'GRANTEE', "
6062  "'DELETE' AS 'PRIVILEGE', "
6063  "NULL as 'IS_GRANTABLE' "
6064  "from sqlite_master where "
6065  "(type = 'table' or type = 'view') "
6066  "and tbl_name like %Q "
6067  "UNION "
6068  "select %s as 'TABLE_QUALIFIER', "
6069  "%s as 'TABLE_OWNER', "
6070  "tbl_name as 'TABLE_NAME', "
6071  "'' as 'GRANTOR', "
6072  "'' as 'GRANTEE', "
6073  "'INSERT' AS 'PRIVILEGE', "
6074  "NULL as 'IS_GRANTABLE' "
6075  "from sqlite_master where "
6076  "(type = 'table' or type = 'view') "
6077  "and tbl_name like %Q "
6078  "UNION "
6079  "select %s as 'TABLE_QUALIFIER', "
6080  "%s as 'TABLE_OWNER', "
6081  "tbl_name as 'TABLE_NAME', "
6082  "'' as 'GRANTOR', "
6083  "'' as 'GRANTEE', "
6084  "'REFERENCES' AS 'PRIVILEGE', "
6085  "NULL as 'IS_GRANTABLE' "
6086  "from sqlite_master where "
6087  "(type = 'table' or type = 'view') "
6088  "and tbl_name like %Q",
6089  d->xcelqrx ? "'main'" : "NULL",
6090  d->xcelqrx ? "''" : "NULL",
6091  tname,
6092  d->xcelqrx ? "'main'" : "NULL",
6093  d->xcelqrx ? "''" : "NULL",
6094  tname,
6095  d->xcelqrx ? "'main'" : "NULL",
6096  d->xcelqrx ? "''" : "NULL",
6097  tname,
6098  d->xcelqrx ? "'main'" : "NULL",
6099  d->xcelqrx ? "''" : "NULL",
6100  tname,
6101  d->xcelqrx ? "'main'" : "NULL",
6102  d->xcelqrx ? "''" : "NULL",
6103  tname);
6104  } else {
6105  sql = sqlite3_mprintf("select %s as 'TABLE_QUALIFIER', "
6106  "%s as 'TABLE_OWNER', "
6107  "tbl_name as 'TABLE_NAME', "
6108  "'' as 'GRANTOR', "
6109  "'' as 'GRANTEE', "
6110  "'SELECT' AS 'PRIVILEGE', "
6111  "NULL as 'IS_GRANTABLE' "
6112  "from sqlite_master where "
6113  "(type = 'table' or type = 'view') "
6114  "and lower(tbl_name) = lower(%Q) "
6115  "UNION "
6116  "select %s as 'TABLE_QUALIFIER', "
6117  "%s as 'TABLE_OWNER', "
6118  "tbl_name as 'TABLE_NAME', "
6119  "'' as 'GRANTOR', "
6120  "'' as 'GRANTEE', "
6121  "'UPDATE' AS 'PRIVILEGE', "
6122  "NULL as 'IS_GRANTABLE' "
6123  "from sqlite_master where "
6124  "(type = 'table' or type = 'view') "
6125  "and lower(tbl_name) = lower(%Q) "
6126  "UNION "
6127  "select %s as 'TABLE_QUALIFIER', "
6128  "%s as 'TABLE_OWNER', "
6129  "tbl_name as 'TABLE_NAME', "
6130  "'' as 'GRANTOR', "
6131  "'' as 'GRANTEE', "
6132  "'DELETE' AS 'PRIVILEGE', "
6133  "NULL as 'IS_GRANTABLE' "
6134  "from sqlite_master where "
6135  "(type = 'table' or type = 'view') "
6136  "and lower(tbl_name) = lower(%Q) "
6137  "UNION "
6138  "select %s as 'TABLE_QUALIFIER', "
6139  "%s as 'TABLE_OWNER', "
6140  "tbl_name as 'TABLE_NAME', "
6141  "'' as 'GRANTOR', "
6142  "'' as 'GRANTEE', "
6143  "'INSERT' AS 'PRIVILEGE', "
6144  "NULL as 'IS_GRANTABLE' "
6145  "from sqlite_master where "
6146  "(type = 'table' or type = 'view') "
6147  "and lower(tbl_name) = lower(%Q) "
6148  "UNION "
6149  "select %s as 'TABLE_QUALIFIER', "
6150  "%s as 'TABLE_OWNER', "
6151  "tbl_name as 'TABLE_NAME', "
6152  "'' as 'GRANTOR', "
6153  "'' as 'GRANTEE', "
6154  "'REFERENCES' AS 'PRIVILEGE', "
6155  "NULL as 'IS_GRANTABLE' "
6156  "from sqlite_master where "
6157  "(type = 'table' or type = 'view') "
6158  "and lower(tbl_name) = lower(%Q)",
6159  d->xcelqrx ? "'main'" : "NULL",
6160  d->xcelqrx ? "''" : "NULL",
6161  tname,
6162  d->xcelqrx ? "'main'" : "NULL",
6163  d->xcelqrx ? "''" : "NULL",
6164  tname,
6165  d->xcelqrx ? "'main'" : "NULL",
6166  d->xcelqrx ? "''" : "NULL",
6167  tname,
6168  d->xcelqrx ? "'main'" : "NULL",
6169  d->xcelqrx ? "''" : "NULL",
6170  tname,
6171  d->xcelqrx ? "'main'" : "NULL",
6172  d->xcelqrx ? "''" : "NULL",
6173  tname);
6174  }
6175 #else
6176  if (npatt) {
6177  sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
6178  "NULL as 'TABLE_OWNER', "
6179  "tbl_name as 'TABLE_NAME', "
6180  "'' as 'GRANTOR', "
6181  "'' as 'GRANTEE', "
6182  "'SELECT' AS 'PRIVILEGE', "
6183  "NULL as 'IS_GRANTABLE' "
6184  "from sqlite_master where "
6185  "(type = 'table' or type = 'view') "
6186  "and tbl_name like %Q "
6187  "UNION "
6188  "select NULL as 'TABLE_QUALIFIER', "
6189  "NULL as 'TABLE_OWNER', "
6190  "tbl_name as 'TABLE_NAME', "
6191  "'' as 'GRANTOR', "
6192  "'' as 'GRANTEE', "
6193  "'UPDATE' AS 'PRIVILEGE', "
6194  "NULL as 'IS_GRANTABLE' "
6195  "from sqlite_master where "
6196  "(type = 'table' or type = 'view') "
6197  "and tbl_name like %Q "
6198  "UNION "
6199  "select NULL as 'TABLE_QUALIFIER', "
6200  "NULL as 'TABLE_OWNER', "
6201  "tbl_name as 'TABLE_NAME', "
6202  "'' as 'GRANTOR', "
6203  "'' as 'GRANTEE', "
6204  "'DELETE' AS 'PRIVILEGE', "
6205  "NULL as 'IS_GRANTABLE' "
6206  "from sqlite_master where "
6207  "(type = 'table' or type = 'view') "
6208  "and tbl_name like %Q "
6209  "UNION "
6210  "select NULL as 'TABLE_QUALIFIER', "
6211  "NULL as 'TABLE_OWNER', "
6212  "tbl_name as 'TABLE_NAME', "
6213  "'' as 'GRANTOR', "
6214  "'' as 'GRANTEE', "
6215  "'INSERT' AS 'PRIVILEGE', "
6216  "NULL as 'IS_GRANTABLE' "
6217  "from sqlite_master where "
6218  "(type = 'table' or type = 'view') "
6219  "and tbl_name like %Q "
6220  "UNION "
6221  "select NULL as 'TABLE_QUALIFIER', "
6222  "NULL as 'TABLE_OWNER', "
6223  "tbl_name as 'TABLE_NAME', "
6224  "'' as 'GRANTOR', "
6225  "'' as 'GRANTEE', "
6226  "'REFERENCES' AS 'PRIVILEGE', "
6227  "NULL as 'IS_GRANTABLE' "
6228  "from sqlite_master where "
6229  "(type = 'table' or type = 'view') "
6230  "and tbl_name like %Q",
6231  tname, tname, tname, tname, tname);
6232  } else {
6233  sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
6234  "NULL as 'TABLE_OWNER', "
6235  "tbl_name as 'TABLE_NAME', "
6236  "'' as 'GRANTOR', "
6237  "'' as 'GRANTEE', "
6238  "'SELECT' AS 'PRIVILEGE', "
6239  "NULL as 'IS_GRANTABLE' "
6240  "from sqlite_master where "
6241  "(type = 'table' or type = 'view') "
6242  "and lower(tbl_name) = lower(%Q) "
6243  "UNION "
6244  "select NULL as 'TABLE_QUALIFIER', "
6245  "NULL as 'TABLE_OWNER', "
6246  "tbl_name as 'TABLE_NAME', "
6247  "'' as 'GRANTOR', "
6248  "'' as 'GRANTEE', "
6249  "'UPDATE' AS 'PRIVILEGE', "
6250  "NULL as 'IS_GRANTABLE' "
6251  "from sqlite_master where "
6252  "(type = 'table' or type = 'view') "
6253  "and lower(tbl_name) = lower(%Q) "
6254  "UNION "
6255  "select NULL as 'TABLE_QUALIFIER', "
6256  "NULL as 'TABLE_OWNER', "
6257  "tbl_name as 'TABLE_NAME', "
6258  "'' as 'GRANTOR', "
6259  "'' as 'GRANTEE', "
6260  "'DELETE' AS 'PRIVILEGE', "
6261  "NULL as 'IS_GRANTABLE' "
6262  "from sqlite_master where "
6263  "(type = 'table' or type = 'view') "
6264  "and lower(tbl_name) = lower(%Q) "
6265  "UNION "
6266  "select NULL as 'TABLE_QUALIFIER', "
6267  "NULL as 'TABLE_OWNER', "
6268  "tbl_name as 'TABLE_NAME', "
6269  "'' as 'GRANTOR', "
6270  "'' as 'GRANTEE', "
6271  "'INSERT' AS 'PRIVILEGE', "
6272  "NULL as 'IS_GRANTABLE' "
6273  "from sqlite_master where "
6274  "(type = 'table' or type = 'view') "
6275  "and lower(tbl_name) = lower(%Q) "
6276  "UNION "
6277  "select NULL as 'TABLE_QUALIFIER', "
6278  "NULL as 'TABLE_OWNER', "
6279  "tbl_name as 'TABLE_NAME', "
6280  "'' as 'GRANTOR', "
6281  "'' as 'GRANTEE', "
6282  "'REFERENCES' AS 'PRIVILEGE', "
6283  "NULL as 'IS_GRANTABLE' "
6284  "from sqlite_master where "
6285  "(type = 'table' or type = 'view') "
6286  "and lower(tbl_name) = lower(%Q)",
6287  tname, tname, tname, tname, tname);
6288  }
6289 #endif
6290  if (!sql) {
6291  return nomem(s);
6292  }
6293  ret = starttran(s);
6294  if (ret != SQL_SUCCESS) {
6295  sqlite3_free(sql);
6296  return ret;
6297  }
6298  dbtraceapi(d, "sqlite3_get_table", sql);
6299  rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
6300  sqlite3_free(sql);
6301  if (rc == SQLITE_OK) {
6302  if (ncols != s->ncols) {
6303  freeresult(s, 0);
6304  s->nrows = 0;
6305  } else {
6306  s->rowfree = sqlite3_free_table;
6307  }
6308  } else {
6309  s->nrows = 0;
6310  s->rows = NULL;
6311  s->rowfree = NULL;
6312  }
6313  if (errp) {
6314  sqlite3_free(errp);
6315  errp = NULL;
6316  }
6317  s->rowp = s->rowprs = -1;
6318  return SQL_SUCCESS;
6319 }
6320 
6321 
6322 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
6323 
6335 SQLRETURN SQL_API
6336 SQLTablePrivileges(SQLHSTMT stmt,
6337  SQLCHAR *catalog, SQLSMALLINT catalogLen,
6338  SQLCHAR *schema, SQLSMALLINT schemaLen,
6339  SQLCHAR *table, SQLSMALLINT tableLen)
6340 {
6341 #if defined(_WIN32) || defined(_WIN64)
6342  char *c = NULL, *s = NULL, *t = NULL;
6343 #endif
6344  SQLRETURN ret;
6345 
6346  HSTMT_LOCK(stmt);
6347 #if defined(_WIN32) || defined(_WIN64)
6348  if (!((STMT *) stmt)->oemcp[0]) {
6349  ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
6350  table, tableLen);
6351  goto done2;
6352  }
6353  if (catalog) {
6354  c = wmb_to_utf_c((char *) catalog, catalogLen);
6355  if (!c) {
6356  ret = nomem((STMT *) stmt);
6357  goto done;
6358  }
6359  }
6360  if (schema) {
6361  s = wmb_to_utf_c((char *) schema, schemaLen);
6362  if (!s) {
6363  ret = nomem((STMT *) stmt);
6364  goto done;
6365  }
6366  }
6367  if (table) {
6368  t = wmb_to_utf_c((char *) table, tableLen);
6369  if (!t) {
6370  ret = nomem((STMT *) stmt);
6371  goto done;
6372  }
6373  }
6374  ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
6375  (SQLCHAR *) s, SQL_NTS,
6376  (SQLCHAR *) t, SQL_NTS);
6377 #else
6378  ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
6379  table, tableLen);
6380 #endif
6381 #if defined(_WIN32) || defined(_WIN64)
6382 done:
6383  uc_free(t);
6384  uc_free(s);
6385  uc_free(c);
6386 done2:
6387  ;
6388 #endif
6389  HSTMT_UNLOCK(stmt);
6390  return ret;
6391 }
6392 #endif
6393 
6394 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
6395 #ifdef WINTERFACE
6396 
6408 SQLRETURN SQL_API
6410  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
6411  SQLWCHAR *schema, SQLSMALLINT schemaLen,
6412  SQLWCHAR *table, SQLSMALLINT tableLen)
6413 {
6414  char *c = NULL, *s = NULL, *t = NULL;
6415  SQLRETURN ret;
6416 
6417  HSTMT_LOCK(stmt);
6418  if (catalog) {
6419  c = uc_to_utf_c(catalog, catalogLen);
6420  if (!c) {
6421  ret = nomem((STMT *) stmt);
6422  goto done;
6423  }
6424  }
6425  if (schema) {
6426  s = uc_to_utf_c(schema, schemaLen);
6427  if (!s) {
6428  ret = nomem((STMT *) stmt);
6429  goto done;
6430  }
6431  }
6432  if (table) {
6433  t = uc_to_utf_c(table, tableLen);
6434  if (!t) {
6435  ret = nomem((STMT *) stmt);
6436  goto done;
6437  }
6438  }
6439  ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
6440  (SQLCHAR *) s, SQL_NTS,
6441  (SQLCHAR *) t, SQL_NTS);
6442 done:
6443  uc_free(t);
6444  uc_free(s);
6445  uc_free(c);
6446  HSTMT_UNLOCK(stmt);
6447  return ret;
6448 }
6449 #endif
6450 #endif
6451 
6456 static COL colPrivSpec2[] = {
6457  { "SYSTEM", "COLPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
6458  { "SYSTEM", "COLPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
6459  { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6460  { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6461  { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6462  { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6463  { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
6464 };
6465 
6466 static COL colPrivSpec3[] = {
6467  { "SYSTEM", "COLPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
6468  { "SYSTEM", "COLPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
6469  { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6470  { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6471  { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6472  { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6473  { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
6474 };
6475 
6476 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
6477 
6491 SQLRETURN SQL_API
6492 SQLColumnPrivileges(SQLHSTMT stmt,
6493  SQLCHAR *catalog, SQLSMALLINT catalogLen,
6494  SQLCHAR *schema, SQLSMALLINT schemaLen,
6495  SQLCHAR *table, SQLSMALLINT tableLen,
6496  SQLCHAR *column, SQLSMALLINT columnLen)
6497 {
6498  SQLRETURN ret;
6499 
6500  HSTMT_LOCK(stmt);
6503  HSTMT_UNLOCK(stmt);
6504  return ret;
6505 }
6506 #endif
6507 
6508 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
6509 #ifdef WINTERFACE
6510 
6524 SQLRETURN SQL_API
6526  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
6527  SQLWCHAR *schema, SQLSMALLINT schemaLen,
6528  SQLWCHAR *table, SQLSMALLINT tableLen,
6529  SQLWCHAR *column, SQLSMALLINT columnLen)
6530 {
6531  SQLRETURN ret;
6532 
6533  HSTMT_LOCK(stmt);
6536  HSTMT_UNLOCK(stmt);
6537  return ret;
6538 }
6539 #endif
6540 #endif
6541 
6546 static COL pkeySpec2[] = {
6547  { "SYSTEM", "PRIMARYKEY", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
6548  { "SYSTEM", "PRIMARYKEY", "TABLE_OWNER", SCOL_VARCHAR, 50 },
6549  { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
6550  { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6551  { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
6552  { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
6553 };
6554 
6555 static COL pkeySpec3[] = {
6556  { "SYSTEM", "PRIMARYKEY", "TABLE_CAT", SCOL_VARCHAR, 50 },
6557  { "SYSTEM", "PRIMARYKEY", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
6558  { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
6559  { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6560  { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
6561  { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
6562 };
6563 
6576 static SQLRETURN
6578  SQLCHAR *cat, SQLSMALLINT catLen,
6579  SQLCHAR *schema, SQLSMALLINT schemaLen,
6580  SQLCHAR *table, SQLSMALLINT tableLen)
6581 {
6582  STMT *s;
6583  DBC *d;
6584  SQLRETURN sret;
6585  int i, asize, ret, nrows, ncols, nrows2 = 0, ncols2 = 0;
6586  int namec = -1, uniquec = -1, namec2 = -1, uniquec2 = -1, offs, seq = 1;
6587  PTRDIFF_T size;
6588  char **rowp = NULL, **rowp2 = NULL, *errp = NULL, *sql, tname[512];
6589 
6591  pkeySpec3, array_size(pkeySpec3), &asize);
6592  if (sret != SQL_SUCCESS) {
6593  return sret;
6594  }
6595  s = (STMT *) stmt;
6596  d = (DBC *) s->dbc;
6597  if (!table || table[0] == '\0' || table[0] == '%') {
6598  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
6599  return SQL_ERROR;
6600  }
6601  if (tableLen == SQL_NTS) {
6602  size = sizeof (tname) - 1;
6603  } else {
6604  size = min(sizeof (tname) - 1, tableLen);
6605  }
6606  strncpy(tname, (char *) table, size);
6607  tname[size] = '\0';
6608  unescpat(tname);
6609  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
6610  if (!sql) {
6611  return nomem(s);
6612  }
6613  sret = starttran(s);
6614  if (sret != SQL_SUCCESS) {
6615  sqlite3_free(sql);
6616  return sret;
6617  }
6618  dbtraceapi(d, "sqlite3_get_table", sql);
6619  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
6620  sqlite3_free(sql);
6621  if (ret != SQLITE_OK) {
6622  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6623  errp ? errp : "unknown error", ret);
6624  if (errp) {
6625  sqlite3_free(errp);
6626  errp = NULL;
6627  }
6628  return SQL_ERROR;
6629  }
6630  if (errp) {
6631  sqlite3_free(errp);
6632  errp = NULL;
6633  }
6634  size = 0;
6635  if (ncols * nrows > 0) {
6636  int typec;
6637 
6638  namec = findcol(rowp, ncols, "name");
6639  uniquec = findcol(rowp, ncols, "pk");
6640  typec = findcol(rowp, ncols, "type");
6641  if (namec >= 0 && uniquec >= 0 && typec >= 0) {
6642  for (i = 1; i <= nrows; i++) {
6643  if (*rowp[i * ncols + uniquec] != '0') {
6644  size++;
6645  }
6646  }
6647  }
6648  }
6649  if (size == 0) {
6650  sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
6651  if (!sql) {
6652  sqlite3_free_table(rowp);
6653  return nomem(s);
6654  }
6655  dbtraceapi(d, "sqlite3_get_table", sql);
6656  ret = sqlite3_get_table(d->sqlite, sql, &rowp2, &nrows2, &ncols2,
6657  &errp);
6658  sqlite3_free(sql);
6659  if (ret != SQLITE_OK) {
6660  sqlite3_free_table(rowp);
6661  sqlite3_free_table(rowp2);
6662  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6663  errp ? errp : "unknown error", ret);
6664  if (errp) {
6665  sqlite3_free(errp);
6666  errp = NULL;
6667  }
6668  return SQL_ERROR;
6669  }
6670  if (errp) {
6671  sqlite3_free(errp);
6672  errp = NULL;
6673  }
6674  }
6675  if (ncols2 * nrows2 > 0) {
6676  namec2 = findcol(rowp2, ncols2, "name");
6677  uniquec2 = findcol(rowp2, ncols2, "unique");
6678  if (namec2 >= 0 && uniquec2 >= 0) {
6679  for (i = 1; i <= nrows2; i++) {
6680  int nnrows, nncols, nlen = 0;
6681  char **rowpp;
6682 
6683  if (rowp2[i * ncols2 + namec2]) {
6684  nlen = strlen(rowp2[i * ncols2 + namec2]);
6685  }
6686  if (nlen < 17 ||
6687  strncmp(rowp2[i * ncols2 + namec2],
6688  "sqlite_autoindex_", 17)) {
6689  continue;
6690  }
6691  if (*rowp2[i * ncols2 + uniquec2] != '0') {
6692  ret = SQLITE_ERROR;
6693  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6694  rowp2[i * ncols2 + namec2]);
6695  if (sql) {
6696  dbtraceapi(d, "sqlite3_get_table", sql);
6697  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6698  &nnrows, &nncols, NULL);
6699  sqlite3_free(sql);
6700  }
6701  if (ret == SQLITE_OK) {
6702  size += nnrows;
6703  sqlite3_free_table(rowpp);
6704  }
6705  }
6706  }
6707  }
6708  }
6709  if (size == 0) {
6710  sqlite3_free_table(rowp);
6711  sqlite3_free_table(rowp2);
6712  return SQL_SUCCESS;
6713  }
6714  s->nrows = size;
6715  size = (size + 1) * asize;
6716  s->rows = xmalloc((size + 1) * sizeof (char *));
6717  if (!s->rows) {
6718  s->nrows = 0;
6719  sqlite3_free_table(rowp);
6720  sqlite3_free_table(rowp2);
6721  return nomem(s);
6722  }
6723  s->rows[0] = (char *) size;
6724  s->rows += 1;
6725  memset(s->rows, 0, sizeof (char *) * size);
6726  s->rowfree = freerows;
6727  offs = s->ncols;
6728  if (rowp) {
6729  for (i = 1; i <= nrows; i++) {
6730  if (*rowp[i * ncols + uniquec] != '0') {
6731  char buf[32];
6732 
6733 #if defined(_WIN32) || defined(_WIN64)
6734  s->rows[offs + 0] = xstrdup(d->xcelqrx ? "main" : "");
6735  s->rows[offs + 1] = xstrdup("");
6736 #else
6737  s->rows[offs + 0] = xstrdup("");
6738  s->rows[offs + 1] = xstrdup("");
6739 #endif
6740  s->rows[offs + 2] = xstrdup(tname);
6741  s->rows[offs + 3] = xstrdup(rowp[i * ncols + namec]);
6742  sprintf(buf, "%d", seq++);
6743  s->rows[offs + 4] = xstrdup(buf);
6744  offs += s->ncols;
6745  }
6746  }
6747  }
6748  if (rowp2) {
6749  for (i = 1; i <= nrows2; i++) {
6750  int nnrows, nncols, nlen = 0;
6751  char **rowpp;
6752 
6753  if (rowp2[i * ncols2 + namec2]) {
6754  nlen = strlen(rowp2[i * ncols2 + namec2]);
6755  }
6756  if (nlen < 17 ||
6757  strncmp(rowp2[i * ncols2 + namec2], "sqlite_autoindex_", 17)) {
6758  continue;
6759  }
6760  if (*rowp2[i * ncols2 + uniquec2] != '0') {
6761  int k;
6762 
6763  ret = SQLITE_ERROR;
6764  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6765  rowp2[i * ncols2 + namec2]);
6766  if (sql) {
6767  dbtraceapi(d, "sqlite3_get_table", sql);
6768  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6769  &nnrows, &nncols, NULL);
6770  sqlite3_free(sql);
6771  }
6772  if (ret != SQLITE_OK) {
6773  continue;
6774  }
6775  for (k = 0; nnrows && k < nncols; k++) {
6776  if (strcmp(rowpp[k], "name") == 0) {
6777  int m;
6778 
6779  for (m = 1; m <= nnrows; m++) {
6780  int roffs = offs + (m - 1) * s->ncols;
6781 
6782 #if defined(_WIN32) || defined(_WIN64)
6783  s->rows[roffs + 0] =
6784  xstrdup(d->xcelqrx ? "main" : "");
6785  s->rows[roffs + 1] = xstrdup("");
6786 #else
6787  s->rows[roffs + 0] = xstrdup("");
6788  s->rows[roffs + 1] = xstrdup("");
6789 #endif
6790  s->rows[roffs + 2] = xstrdup(tname);
6791  s->rows[roffs + 3] =
6792  xstrdup(rowpp[m * nncols + k]);
6793  s->rows[roffs + 5] =
6794  xstrdup(rowp2[i * ncols2 + namec2]);
6795  }
6796  } else if (strcmp(rowpp[k], "seqno") == 0) {
6797  int m;
6798 
6799  for (m = 1; m <= nnrows; m++) {
6800  int roffs = offs + (m - 1) * s->ncols;
6801  int pos = m - 1;
6802  char buf[32];
6803 
6804  sscanf(rowpp[m * nncols + k], "%d", &pos);
6805  sprintf(buf, "%d", pos + 1);
6806  s->rows[roffs + 4] = xstrdup(buf);
6807  }
6808  }
6809  }
6810  offs += nnrows * s->ncols;
6811  sqlite3_free_table(rowpp);
6812  }
6813  }
6814  }
6815  sqlite3_free_table(rowp);
6816  sqlite3_free_table(rowp2);
6817  return SQL_SUCCESS;
6818 }
6819 
6820 #ifndef WINTERFACE
6821 
6833 SQLRETURN SQL_API
6834 SQLPrimaryKeys(SQLHSTMT stmt,
6835  SQLCHAR *cat, SQLSMALLINT catLen,
6836  SQLCHAR *schema, SQLSMALLINT schemaLen,
6837  SQLCHAR *table, SQLSMALLINT tableLen)
6838 {
6839 #if defined(_WIN32) || defined(_WIN64)
6840  char *c = NULL, *s = NULL, *t = NULL;
6841 #endif
6842  SQLRETURN ret;
6843 
6844  HSTMT_LOCK(stmt);
6845 #if defined(_WIN32) || defined(_WIN64)
6846  if (!((STMT *) stmt)->oemcp[0]) {
6847  ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
6848  table, tableLen);
6849  goto done2;
6850  }
6851  if (cat) {
6852  c = wmb_to_utf_c((char *) cat, catLen);
6853  if (!c) {
6854  ret = nomem((STMT *) stmt);
6855  goto done;
6856  }
6857  }
6858  if (schema) {
6859  s = wmb_to_utf_c((char *) schema, schemaLen);
6860  if (!s) {
6861  ret = nomem((STMT *) stmt);
6862  goto done;
6863  }
6864  }
6865  if (table) {
6866  t = wmb_to_utf_c((char *) table, tableLen);
6867  if (!t) {
6868  ret = nomem((STMT *) stmt);
6869  goto done;
6870  }
6871  }
6872  ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
6873  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
6874 #else
6875  ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
6876  table, tableLen);
6877 #endif
6878 #if defined(_WIN32) || defined(_WIN64)
6879 done:
6880  uc_free(t);
6881  uc_free(s);
6882  uc_free(c);
6883 done2:
6884  ;
6885 #endif
6886  HSTMT_UNLOCK(stmt);
6887  return ret;
6888 }
6889 #endif
6890 
6891 #ifdef WINTERFACE
6892 
6904 SQLRETURN SQL_API
6906  SQLWCHAR *cat, SQLSMALLINT catLen,
6907  SQLWCHAR *schema, SQLSMALLINT schemaLen,
6908  SQLWCHAR *table, SQLSMALLINT tableLen)
6909 {
6910  char *c = NULL, *s = NULL, *t = NULL;
6911  SQLRETURN ret;
6912 
6913  HSTMT_LOCK(stmt);
6914  if (cat) {
6915  c = uc_to_utf_c(cat, catLen);
6916  if (!c) {
6917  ret = nomem((STMT *) stmt);
6918  goto done;
6919  }
6920  }
6921  if (schema) {
6922  s = uc_to_utf_c(schema, schemaLen);
6923  if (!s) {
6924  ret = nomem((STMT *) stmt);
6925  goto done;
6926  }
6927  }
6928  if (table) {
6929  t = uc_to_utf_c(table, tableLen);
6930  if (!t) {
6931  ret = nomem((STMT *) stmt);
6932  goto done;
6933  }
6934  }
6935  ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
6936  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
6937 done:
6938  uc_free(t);
6939  uc_free(s);
6940  uc_free(c);
6941  HSTMT_UNLOCK(stmt);
6942  return ret;
6943 }
6944 #endif
6945 
6950 static COL scolSpec2[] = {
6951  { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
6952  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6953  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
6954  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
6955  { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
6956  { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
6957  { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
6958  { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
6959  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
6960 };
6961 
6962 static COL scolSpec3[] = {
6963  { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
6964  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6965  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
6966  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
6967  { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
6968  { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
6969  { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
6970  { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
6971  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
6972 };
6973 
6989 static SQLRETURN
6990 drvspecialcolumns(SQLHSTMT stmt, SQLUSMALLINT id,
6991  SQLCHAR *cat, SQLSMALLINT catLen,
6992  SQLCHAR *schema, SQLSMALLINT schemaLen,
6993  SQLCHAR *table, SQLSMALLINT tableLen,
6994  SQLUSMALLINT scope, SQLUSMALLINT nullable)
6995 {
6996  STMT *s;
6997  DBC *d;
6998  SQLRETURN sret;
6999  int i, asize, ret, nrows, ncols, nnnrows, nnncols, offs;
7000  PTRDIFF_T size;
7001  int namec = -1, uniquec = -1, namecc = -1, typecc = -1;
7002  int notnullcc = -1, mkrowid = 0;
7003  char *errp = NULL, *sql, tname[512];
7004  char **rowp = NULL, **rowppp = NULL;
7005 
7007  scolSpec3, array_size(scolSpec3), &asize);
7008  if (sret != SQL_SUCCESS) {
7009  return sret;
7010  }
7011  s = (STMT *) stmt;
7012  d = (DBC *) s->dbc;
7013  if (!table || table[0] == '\0' || table[0] == '%') {
7014  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
7015  return SQL_ERROR;
7016  }
7017  if (tableLen == SQL_NTS) {
7018  size = sizeof (tname) - 1;
7019  } else {
7020  size = min(sizeof (tname) - 1, tableLen);
7021  }
7022  strncpy(tname, (char *) table, size);
7023  tname[size] = '\0';
7024  unescpat(tname);
7025  if (id != SQL_BEST_ROWID) {
7026  return SQL_SUCCESS;
7027  }
7028  sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
7029  if (!sql) {
7030  return nomem(s);
7031  }
7032  sret = starttran(s);
7033  if (sret != SQL_SUCCESS) {
7034  sqlite3_free(sql);
7035  return sret;
7036  }
7037  dbtraceapi(d, "sqlite3_get_table", sql);
7038  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
7039  sqlite3_free(sql);
7040  if (ret != SQLITE_OK) {
7041 doerr:
7042  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7043  errp ? errp : "unknown error", ret);
7044  if (errp) {
7045  sqlite3_free(errp);
7046  errp = NULL;
7047  }
7048  return SQL_ERROR;
7049  }
7050  if (errp) {
7051  sqlite3_free(errp);
7052  errp = NULL;
7053  }
7054  size = 0; /* number result rows */
7055  if (ncols * nrows <= 0) {
7056  goto nodata_but_rowid;
7057  }
7058  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
7059  if (!sql) {
7060  return nomem(s);
7061  }
7062  dbtraceapi(d, "sqlite3_get_table", sql);
7063  ret = sqlite3_get_table(d->sqlite, sql, &rowppp, &nnnrows, &nnncols,
7064  &errp);
7065  sqlite3_free(sql);
7066  if (ret != SQLITE_OK) {
7067  sqlite3_free_table(rowp);
7068  goto doerr;
7069  }
7070  if (errp) {
7071  sqlite3_free(errp);
7072  errp = NULL;
7073  }
7074  namec = findcol(rowp, ncols, "name");
7075  uniquec = findcol(rowp, ncols, "unique");
7076  if (namec < 0 || uniquec < 0) {
7077  goto nodata_but_rowid;
7078  }
7079  namecc = findcol(rowppp, nnncols, "name");
7080  typecc = findcol(rowppp, nnncols, "type");
7081  notnullcc = findcol(rowppp, nnncols, "notnull");
7082  for (i = 1; i <= nrows; i++) {
7083  int nnrows, nncols;
7084  char **rowpp = NULL;
7085 
7086  if (*rowp[i * ncols + uniquec] != '0') {
7087  ret = SQLITE_ERROR;
7088  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
7089  rowp[i * ncols + namec]);
7090  if (sql) {
7091  dbtraceapi(d, "sqlite3_get_table", sql);
7092  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7093  &nnrows, &nncols, NULL);
7094  sqlite3_free(sql);
7095  }
7096  if (ret == SQLITE_OK) {
7097  size += nnrows;
7098  sqlite3_free_table(rowpp);
7099  }
7100  }
7101  }
7102 nodata_but_rowid:
7103  if (size == 0) {
7104  size = 1;
7105  mkrowid = 1;
7106  }
7107  s->nrows = size;
7108  size = (size + 1) * asize;
7109  s->rows = xmalloc((size + 1) * sizeof (char *));
7110  if (!s->rows) {
7111  s->nrows = 0;
7112  sqlite3_free_table(rowp);
7113  sqlite3_free_table(rowppp);
7114  return nomem(s);
7115  }
7116  s->rows[0] = (char *) size;
7117  s->rows += 1;
7118  memset(s->rows, 0, sizeof (char *) * size);
7119  s->rowfree = freerows;
7120  if (mkrowid) {
7121  s->nrows = 0;
7122  goto mkrowid;
7123  }
7124  offs = 0;
7125  for (i = 1; i <= nrows; i++) {
7126  int nnrows, nncols;
7127  char **rowpp = NULL;
7128 
7129  if (*rowp[i * ncols + uniquec] != '0') {
7130  int k;
7131 
7132  ret = SQLITE_ERROR;
7133  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
7134  rowp[i * ncols + namec]);
7135  if (sql) {
7136  dbtraceapi(d, "sqlite3_get_table", sql);
7137  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7138  &nnrows, &nncols, NULL);
7139  sqlite3_free(sql);
7140  }
7141  if (ret != SQLITE_OK) {
7142  continue;
7143  }
7144  for (k = 0; nnrows && k < nncols; k++) {
7145  if (strcmp(rowpp[k], "name") == 0) {
7146  int m;
7147 
7148  for (m = 1; m <= nnrows; m++) {
7149  int roffs = (offs + m) * s->ncols;
7150 
7151  s->rows[roffs + 0] =
7152  xstrdup(stringify(SQL_SCOPE_SESSION));
7153  s->rows[roffs + 1] = xstrdup(rowpp[m * nncols + k]);
7154  s->rows[roffs + 4] = xstrdup("0");
7155  s->rows[roffs + 7] =
7156  xstrdup(stringify(SQL_PC_NOT_PSEUDO));
7157  if (namecc >= 0 && typecc >= 0) {
7158  int ii;
7159 
7160  for (ii = 1; ii <= nnnrows; ii++) {
7161  if (strcmp(rowppp[ii * nnncols + namecc],
7162  rowpp[m * nncols + k]) == 0) {
7163  char *typen = rowppp[ii * nnncols + typecc];
7164  int sqltype, mm, dd, isnullable = 0;
7165  char buf[32];
7166 
7167  s->rows[roffs + 3] = xstrdup(typen);
7168  sqltype = mapsqltype(typen, NULL, *s->ov3,
7169  s->nowchar[0],
7170  s->dobigint);
7171  getmd(typen, sqltype, &mm, &dd);
7172 #ifdef SQL_LONGVARCHAR
7173  if (sqltype == SQL_VARCHAR && mm > 255) {
7174  sqltype = SQL_LONGVARCHAR;
7175  }
7176 #endif
7177 #ifdef WINTERFACE
7178 #ifdef SQL_WLONGVARCHAR
7179  if (sqltype == SQL_WVARCHAR && mm > 255) {
7180  sqltype = SQL_WLONGVARCHAR;
7181  }
7182 #endif
7183 #endif
7184  if (sqltype == SQL_VARBINARY && mm > 255) {
7185  sqltype = SQL_LONGVARBINARY;
7186  }
7187  sprintf(buf, "%d", sqltype);
7188  s->rows[roffs + 2] = xstrdup(buf);
7189  sprintf(buf, "%d", mm);
7190  s->rows[roffs + 5] = xstrdup(buf);
7191  sprintf(buf, "%d", dd);
7192  s->rows[roffs + 6] = xstrdup(buf);
7193  if (notnullcc >= 0) {
7194  char *inp =
7195  rowppp[ii * nnncols + notnullcc];
7196 
7197  isnullable = inp[0] != '0';
7198  }
7199  sprintf(buf, "%d", isnullable);
7200  s->rows[roffs + 8] = xstrdup(buf);
7201  }
7202  }
7203  }
7204  }
7205  }
7206  }
7207  offs += nnrows;
7208  sqlite3_free_table(rowpp);
7209  }
7210  }
7211  if (nullable == SQL_NO_NULLS) {
7212  for (i = 1; i < s->nrows; i++) {
7213  if (s->rows[i * s->ncols + 8][0] == '0') {
7214  int m, i1 = i + 1;
7215 
7216  for (m = 0; m < s->ncols; m++) {
7217  freep(&s->rows[i * s->ncols + m]);
7218  }
7219  size = s->ncols * sizeof (char *) * (s->nrows - i1);
7220  if (size > 0) {
7221  memmove(s->rows + i * s->ncols,
7222  s->rows + i1 * s->ncols,
7223  size);
7224  memset(s->rows + s->nrows * s->ncols, 0,
7225  s->ncols * sizeof (char *));
7226  }
7227  s->nrows--;
7228  --i;
7229  }
7230  }
7231  }
7232 mkrowid:
7233  sqlite3_free_table(rowp);
7234  sqlite3_free_table(rowppp);
7235  if (s->nrows == 0) {
7236  s->rows[s->ncols + 0] = xstrdup(stringify(SQL_SCOPE_SESSION));
7237  s->rows[s->ncols + 1] = xstrdup("_ROWID_");
7238  s->rows[s->ncols + 2] = xstrdup(stringify(SQL_INTEGER));
7239  s->rows[s->ncols + 3] = xstrdup("integer");
7240  s->rows[s->ncols + 4] = xstrdup("0");
7241  s->rows[s->ncols + 5] = xstrdup("10");
7242  s->rows[s->ncols + 6] = xstrdup("9");
7243  s->rows[s->ncols + 7] = xstrdup(stringify(SQL_PC_PSEUDO));
7244  s->rows[s->ncols + 8] = xstrdup(stringify(SQL_FALSE));
7245  s->nrows = 1;
7246  }
7247  return SQL_SUCCESS;
7248 }
7249 
7250 #ifndef WINTERFACE
7251 
7266 SQLRETURN SQL_API
7267 SQLSpecialColumns(SQLHSTMT stmt, SQLUSMALLINT id,
7268  SQLCHAR *cat, SQLSMALLINT catLen,
7269  SQLCHAR *schema, SQLSMALLINT schemaLen,
7270  SQLCHAR *table, SQLSMALLINT tableLen,
7271  SQLUSMALLINT scope, SQLUSMALLINT nullable)
7272 {
7273 #if defined(_WIN32) || defined(_WIN64)
7274  char *c = NULL, *s = NULL, *t = NULL;
7275 #endif
7276  SQLRETURN ret;
7277 
7278  HSTMT_LOCK(stmt);
7279 #if defined(_WIN32) || defined(_WIN64)
7280  if (!((STMT *) stmt)->oemcp[0]) {
7281  ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
7282  table, tableLen, scope, nullable);
7283  goto done2;
7284  }
7285  if (cat) {
7286  c = wmb_to_utf_c((char *) cat, catLen);
7287  if (!c) {
7288  ret = nomem((STMT *) stmt);
7289  goto done;
7290  }
7291  }
7292  if (schema) {
7293  s = wmb_to_utf_c((char *) schema, schemaLen);
7294  if (!s) {
7295  ret = nomem((STMT *) stmt);
7296  goto done;
7297  }
7298  }
7299  if (table) {
7300  t = wmb_to_utf_c((char *) table, tableLen);
7301  if (!t) {
7302  ret = nomem((STMT *) stmt);
7303  goto done;
7304  }
7305  }
7306  ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
7307  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
7308  scope, nullable);
7309 #else
7310  ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
7311  table, tableLen, scope, nullable);
7312 #endif
7313 #if defined(_WIN32) || defined(_WIN64)
7314 done:
7315  uc_free(t);
7316  uc_free(s);
7317  uc_free(c);
7318 done2:
7319  ;
7320 #endif
7321  HSTMT_UNLOCK(stmt);
7322  return ret;
7323 }
7324 #endif
7325 
7326 #ifdef WINTERFACE
7327 
7342 SQLRETURN SQL_API
7343 SQLSpecialColumnsW(SQLHSTMT stmt, SQLUSMALLINT id,
7344  SQLWCHAR *cat, SQLSMALLINT catLen,
7345  SQLWCHAR *schema, SQLSMALLINT schemaLen,
7346  SQLWCHAR *table, SQLSMALLINT tableLen,
7347  SQLUSMALLINT scope, SQLUSMALLINT nullable)
7348 {
7349  char *c = NULL, *s = NULL, *t = NULL;
7350  SQLRETURN ret;
7351 
7352  HSTMT_LOCK(stmt);
7353  if (cat) {
7354  c = uc_to_utf_c(cat, catLen);
7355  if (!c) {
7356  ret = nomem((STMT *) stmt);
7357  goto done;
7358  }
7359  }
7360  if (schema) {
7361  s = uc_to_utf_c(schema, schemaLen);
7362  if (!s) {
7363  ret = nomem((STMT *) stmt);
7364  goto done;
7365  }
7366  }
7367  if (table) {
7368  t = uc_to_utf_c(table, tableLen);
7369  if (!t) {
7370  ret = nomem((STMT *) stmt);
7371  goto done;
7372  }
7373  }
7374  ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
7375  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
7376  scope, nullable);
7377 done:
7378  uc_free(t);
7379  uc_free(s);
7380  uc_free(c);
7381  HSTMT_UNLOCK(stmt);
7382  return ret;
7383 }
7384 #endif
7385 
7390 static COL fkeySpec2[] = {
7391  { "SYSTEM", "FOREIGNKEY", "PKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
7392  { "SYSTEM", "FOREIGNKEY", "PKTABLE_OWNER", SCOL_VARCHAR, 50 },
7393  { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
7394  { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7395  { "SYSTEM", "FOREIGNKEY", "FKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
7396  { "SYSTEM", "FOREIGNKEY", "FKTABLE_OWNER", SCOL_VARCHAR, 50 },
7397  { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
7398  { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7399  { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
7400  { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
7401  { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
7402  { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
7403  { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
7404  { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
7405 };
7406 
7407 static COL fkeySpec3[] = {
7408  { "SYSTEM", "FOREIGNKEY", "PKTABLE_CAT", SCOL_VARCHAR, 50 },
7409  { "SYSTEM", "FOREIGNKEY", "PKTABLE_SCHEM", SCOL_VARCHAR, 50 },
7410  { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
7411  { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7412  { "SYSTEM", "FOREIGNKEY", "FKTABLE_CAT", SCOL_VARCHAR, 50 },
7413  { "SYSTEM", "FOREIGNKEY", "FKTABLE_SCHEM", SCOL_VARCHAR, 50 },
7414  { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
7415  { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7416  { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
7417  { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
7418  { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
7419  { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
7420  { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
7421  { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
7422 };
7423 
7442 static SQLRETURN SQL_API
7444  SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7445  SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
7446  SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
7447  SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7448  SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
7449  SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
7450 {
7451  STMT *s;
7452  DBC *d;
7453  SQLRETURN sret;
7454  int i, asize, ret, nrows, ncols, offs, namec, seqc, fromc, toc;
7455  int onu, ond;
7456  PTRDIFF_T size;
7457  char **rowp, *errp = NULL, *sql, pname[512], fname[512];
7458 
7460  fkeySpec3, array_size(fkeySpec3), &asize);
7461  if (sret != SQL_SUCCESS) {
7462  return sret;
7463  }
7464  s = (STMT *) stmt;
7465  sret = starttran(s);
7466  if (sret != SQL_SUCCESS) {
7467  return sret;
7468  }
7469  d = (DBC *) s->dbc;
7470  if ((!PKtable || PKtable[0] == '\0' || PKtable[0] == '%') &&
7471  (!FKtable || FKtable[0] == '\0' || FKtable[0] == '%')) {
7472  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
7473  return SQL_ERROR;
7474  }
7475  size = 0;
7476  if (PKtable) {
7477  if (PKtableLen == SQL_NTS) {
7478  size = sizeof (pname) - 1;
7479  } else {
7480  size = min(sizeof (pname) - 1, PKtableLen);
7481  }
7482  strncpy(pname, (char *) PKtable, size);
7483  }
7484  pname[size] = '\0';
7485  size = 0;
7486  if (FKtable) {
7487 
7488  if (FKtableLen == SQL_NTS) {
7489  size = sizeof (fname) - 1;
7490  } else {
7491  size = min(sizeof (fname) - 1, FKtableLen);
7492  }
7493  strncpy(fname, (char *) FKtable, size);
7494  }
7495  fname[size] = '\0';
7496  if (fname[0] != '\0') {
7497  int plen;
7498 
7499  ret = SQLITE_ERROR;
7500  sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", fname);
7501  if (sql) {
7502  dbtraceapi(d, "sqlite3_get_table", sql);
7503  ret = sqlite3_get_table(d->sqlite, sql, &rowp,
7504  &nrows, &ncols, &errp);
7505  sqlite3_free(sql);
7506  }
7507  if (ret != SQLITE_OK) {
7508  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7509  errp ? errp : "unknown error", ret);
7510  if (errp) {
7511  sqlite3_free(errp);
7512  errp = NULL;
7513  }
7514  return SQL_ERROR;
7515  }
7516  if (errp) {
7517  sqlite3_free(errp);
7518  errp = NULL;
7519  }
7520  if (ncols * nrows <= 0) {
7521 nodata:
7522  sqlite3_free_table(rowp);
7523  return SQL_SUCCESS;
7524  }
7525  size = 0;
7526  namec = findcol(rowp, ncols, "table");
7527  seqc = findcol(rowp, ncols, "seq");
7528  fromc = findcol(rowp, ncols, "from");
7529  toc = findcol(rowp, ncols, "to");
7530  onu = findcol(rowp, ncols, "on_update");
7531  ond = findcol(rowp, ncols, "on_delete");
7532  if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7533  goto nodata;
7534  }
7535  plen = strlen(pname);
7536  for (i = 1; i <= nrows; i++) {
7537  char *ptab = unquote(rowp[i * ncols + namec]);
7538 
7539  if (plen && ptab) {
7540  int len = strlen(ptab);
7541 
7542  if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
7543  continue;
7544  }
7545  }
7546  size++;
7547  }
7548  if (size == 0) {
7549  goto nodata;
7550  }
7551  s->nrows = size;
7552  size = (size + 1) * asize;
7553  s->rows = xmalloc((size + 1) * sizeof (char *));
7554  if (!s->rows) {
7555  s->nrows = 0;
7556  return nomem(s);
7557  }
7558  s->rows[0] = (char *) size;
7559  s->rows += 1;
7560  memset(s->rows, 0, sizeof (char *) * size);
7561  s->rowfree = freerows;
7562  offs = 0;
7563  for (i = 1; i <= nrows; i++) {
7564  int pos = 0, roffs = (offs + 1) * s->ncols;
7565  char *ptab = rowp[i * ncols + namec];
7566  char buf[32];
7567 
7568  if (plen && ptab) {
7569  int len = strlen(ptab);
7570 
7571  if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
7572  continue;
7573  }
7574  }
7575 #if defined(_WIN32) || defined(_WIN64)
7576  s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
7577  s->rows[roffs + 1] = xstrdup("");
7578 #else
7579  s->rows[roffs + 0] = xstrdup("");
7580  s->rows[roffs + 1] = xstrdup("");
7581 #endif
7582  s->rows[roffs + 2] = xstrdup(ptab);
7583  s->rows[roffs + 3] = xstrdup(rowp[i * ncols + toc]);
7584  s->rows[roffs + 4] = xstrdup("");
7585  s->rows[roffs + 5] = xstrdup("");
7586  s->rows[roffs + 6] = xstrdup(fname);
7587  s->rows[roffs + 7] = xstrdup(rowp[i * ncols + fromc]);
7588  sscanf(rowp[i * ncols + seqc], "%d", &pos);
7589  sprintf(buf, "%d", pos + 1);
7590  s->rows[roffs + 8] = xstrdup(buf);
7591  if (onu < 0) {
7592  s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7593  } else {
7594  if (strcmp(rowp[i * ncols + onu], "SET NULL") == 0) {
7595  s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
7596  } else if (strcmp(rowp[i * ncols + onu], "SET DEFAULT") == 0) {
7597  s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_DEFAULT));
7598  } else if (strcmp(rowp[i * ncols + onu], "CASCADE") == 0) {
7599  s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
7600  } else if (strcmp(rowp[i * ncols + onu], "RESTRICT") == 0) {
7601  s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
7602  } else {
7603  s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7604  }
7605  }
7606  if (ond < 0) {
7607  s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7608  } else {
7609  if (strcmp(rowp[i * ncols + ond], "SET NULL") == 0) {
7610  s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
7611  } else if (strcmp(rowp[i * ncols + ond], "SET DEFAULT") == 0) {
7612  s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_DEFAULT));
7613  } else if (strcmp(rowp[i * ncols + ond], "CASCADE") == 0) {
7614  s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
7615  } else if (strcmp(rowp[i * ncols + ond], "RESTRICT") == 0) {
7616  s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
7617  } else {
7618  s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7619  }
7620  }
7621  s->rows[roffs + 11] = NULL;
7622  s->rows[roffs + 12] = NULL;
7623  s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
7624  offs++;
7625  }
7626  sqlite3_free_table(rowp);
7627  } else {
7628  int nnrows, nncols, plen = strlen(pname);
7629  char **rowpp;
7630 
7631  sql = "select name from sqlite_master where type='table'";
7632  dbtraceapi(d, "sqlite3_get_table", sql);
7633  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
7634  if (ret != SQLITE_OK) {
7635  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7636  errp ? errp : "unknown error", ret);
7637  if (errp) {
7638  sqlite3_free(errp);
7639  errp = NULL;
7640  }
7641  return SQL_ERROR;
7642  }
7643  if (errp) {
7644  sqlite3_free(errp);
7645  errp = NULL;
7646  }
7647  if (ncols * nrows <= 0) {
7648  goto nodata;
7649  }
7650  size = 0;
7651  for (i = 1; i <= nrows; i++) {
7652  int k;
7653 
7654  if (!rowp[i]) {
7655  continue;
7656  }
7657  rowpp = NULL;
7658  ret = SQLITE_ERROR;
7659  sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
7660  if (sql) {
7661  dbtraceapi(d, "sqlite3_get_table", sql);
7662  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7663  &nnrows, &nncols, NULL);
7664  sqlite3_free(sql);
7665  }
7666  if (ret != SQLITE_OK || nncols * nnrows <= 0) {
7667  sqlite3_free_table(rowpp);
7668  continue;
7669  }
7670  namec = findcol(rowpp, nncols, "table");
7671  seqc = findcol(rowpp, nncols, "seq");
7672  fromc = findcol(rowpp, nncols, "from");
7673  toc = findcol(rowpp, nncols, "to");
7674  if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7675  sqlite3_free_table(rowpp);
7676  continue;
7677  }
7678  for (k = 1; k <= nnrows; k++) {
7679  char *ptab = unquote(rowpp[k * nncols + namec]);
7680 
7681  if (plen && ptab) {
7682  int len = strlen(ptab);
7683 
7684  if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
7685  continue;
7686  }
7687  }
7688  size++;
7689  }
7690  sqlite3_free_table(rowpp);
7691  }
7692  if (size == 0) {
7693  goto nodata;
7694  }
7695  s->nrows = size;
7696  size = (size + 1) * asize;
7697  s->rows = xmalloc((size + 1) * sizeof (char *));
7698  if (!s->rows) {
7699  s->nrows = 0;
7700  return nomem(s);
7701  }
7702  s->rows[0] = (char *) size;
7703  s->rows += 1;
7704  memset(s->rows, 0, sizeof (char *) * size);
7705  s->rowfree = freerows;
7706  offs = 0;
7707  for (i = 1; i <= nrows; i++) {
7708  int k;
7709 
7710  if (!rowp[i]) {
7711  continue;
7712  }
7713  rowpp = NULL;
7714  ret = SQLITE_ERROR;
7715  sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
7716  if (sql) {
7717  dbtraceapi(d, "sqlite3_get_table", sql);
7718  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7719  &nnrows, &nncols, NULL);
7720  sqlite3_free(sql);
7721  }
7722  if (ret != SQLITE_OK || nncols * nnrows <= 0) {
7723  sqlite3_free_table(rowpp);
7724  continue;
7725  }
7726  namec = findcol(rowpp, nncols, "table");
7727  seqc = findcol(rowpp, nncols, "seq");
7728  fromc = findcol(rowpp, nncols, "from");
7729  toc = findcol(rowpp, nncols, "to");
7730  onu = findcol(rowpp, nncols, "on_update");
7731  ond = findcol(rowpp, nncols, "on_delete");
7732  if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7733  sqlite3_free_table(rowpp);
7734  continue;
7735  }
7736  for (k = 1; k <= nnrows; k++) {
7737  int pos = 0, roffs = (offs + 1) * s->ncols;
7738  char *ptab = unquote(rowpp[k * nncols + namec]);
7739  char buf[32];
7740 
7741  if (plen && ptab) {
7742  int len = strlen(ptab);
7743 
7744  if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
7745  continue;
7746  }
7747  }
7748 #if defined(_WIN32) || defined(_WIN64)
7749  s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
7750  s->rows[roffs + 1] = xstrdup("");
7751 #else
7752  s->rows[roffs + 0] = xstrdup("");
7753  s->rows[roffs + 1] = xstrdup("");
7754 #endif
7755  s->rows[roffs + 2] = xstrdup(ptab);
7756  s->rows[roffs + 3] = xstrdup(rowpp[k * nncols + toc]);
7757  s->rows[roffs + 4] = xstrdup("");
7758  s->rows[roffs + 5] = xstrdup("");
7759  s->rows[roffs + 6] = xstrdup(rowp[i]);
7760  s->rows[roffs + 7] = xstrdup(rowpp[k * nncols + fromc]);
7761  sscanf(rowpp[k * nncols + seqc], "%d", &pos);
7762  sprintf(buf, "%d", pos + 1);
7763  s->rows[roffs + 8] = xstrdup(buf);
7764  if (onu < 0) {
7765  s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7766  } else {
7767  if (strcmp(rowpp[k * nncols + onu], "SET NULL") == 0) {
7768  s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
7769  } else if (strcmp(rowpp[k * nncols + onu], "SET DEFAULT")
7770  == 0) {
7771  s->rows[roffs + 9] =
7772  xstrdup(stringify(SQL_SET_DEFAULT));
7773  } else if (strcmp(rowpp[k * nncols + onu], "CASCADE")
7774  == 0) {
7775  s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
7776  } else if (strcmp(rowpp[k * nncols + onu], "RESTRICT")
7777  == 0) {
7778  s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
7779  } else {
7780  s->rows[roffs + 9] =
7781  xstrdup(stringify(SQL_NO_ACTION));
7782  }
7783  }
7784  if (ond < 0) {
7785  s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7786  } else {
7787  if (strcmp(rowpp[k * nncols + ond], "SET NULL") == 0) {
7788  s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
7789  } else if (strcmp(rowpp[k * nncols + ond], "SET DEFAULT")
7790  == 0) {
7791  s->rows[roffs + 10] =
7792  xstrdup(stringify(SQL_SET_DEFAULT));
7793  } else if (strcmp(rowpp[k * nncols + ond], "CASCADE")
7794  == 0) {
7795  s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
7796  } else if (strcmp(rowpp[k * nncols + ond], "RESTRICT")
7797  == 0) {
7798  s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
7799  } else {
7800  s->rows[roffs + 10] =
7801  xstrdup(stringify(SQL_NO_ACTION));
7802  }
7803  }
7804  s->rows[roffs + 11] = NULL;
7805  s->rows[roffs + 12] = NULL;
7806  s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
7807  offs++;
7808  }
7809  sqlite3_free_table(rowpp);
7810  }
7811  sqlite3_free_table(rowp);
7812  }
7813  return SQL_SUCCESS;
7814 }
7815 
7816 #ifndef WINTERFACE
7817 
7835 SQLRETURN SQL_API
7836 SQLForeignKeys(SQLHSTMT stmt,
7837  SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7838  SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
7839  SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
7840  SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7841  SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
7842  SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
7843 {
7844 #if defined(_WIN32) || defined(_WIN64)
7845  char *pc = NULL, *ps = NULL, *pt = NULL;
7846  char *fc = NULL, *fs = NULL, *ft = NULL;
7847 #endif
7848  SQLRETURN ret;
7849 
7850  HSTMT_LOCK(stmt);
7851 #if defined(_WIN32) || defined(_WIN64)
7852  if (!((STMT *) stmt)->oemcp[0]) {
7853  ret = drvforeignkeys(stmt,
7854  PKcatalog, PKcatalogLen,
7855  PKschema, PKschemaLen, PKtable, PKtableLen,
7856  FKcatalog, FKcatalogLen,
7857  FKschema, FKschemaLen,
7858  FKtable, FKtableLen);
7859  goto done2;
7860  }
7861  if (PKcatalog) {
7862  pc = wmb_to_utf_c((char *) PKcatalog, PKcatalogLen);
7863  if (!pc) {
7864  ret = nomem((STMT *) stmt);
7865  goto done;
7866  }
7867  }
7868  if (PKschema) {
7869  ps = wmb_to_utf_c((char *) PKschema, PKschemaLen);
7870  if (!ps) {
7871  ret = nomem((STMT *) stmt);
7872  goto done;
7873  }
7874  }
7875  if (PKtable) {
7876  pt = wmb_to_utf_c((char *) PKtable, PKtableLen);
7877  if (!pt) {
7878  ret = nomem((STMT *) stmt);
7879  goto done;
7880  }
7881  }
7882  if (FKcatalog) {
7883  fc = wmb_to_utf_c((char *) FKcatalog, FKcatalogLen);
7884  if (!fc) {
7885  ret = nomem((STMT *) stmt);
7886  goto done;
7887  }
7888  }
7889  if (FKschema) {
7890  fs = wmb_to_utf_c((char *) FKschema, FKschemaLen);
7891  if (!fs) {
7892  ret = nomem((STMT *) stmt);
7893  goto done;
7894  }
7895  }
7896  if (FKtable) {
7897  ft = wmb_to_utf_c((char *) FKtable, FKtableLen);
7898  if (!ft) {
7899  ret = nomem((STMT *) stmt);
7900  goto done;
7901  }
7902  }
7903  ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
7904  (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
7905  (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
7906  (SQLCHAR *) ft, SQL_NTS);
7907 #else
7908  ret = drvforeignkeys(stmt,
7909  PKcatalog, PKcatalogLen,
7910  PKschema, PKschemaLen, PKtable, PKtableLen,
7911  FKcatalog, FKcatalogLen,
7912  FKschema, FKschemaLen,
7913  FKtable, FKtableLen);
7914 #endif
7915 #if defined(_WIN32) || defined(_WIN64)
7916 done:
7917  uc_free(ft);
7918  uc_free(fs);
7919  uc_free(fc);
7920  uc_free(pt);
7921  uc_free(ps);
7922  uc_free(pc);
7923 done2:
7924  ;
7925 #endif
7926  HSTMT_UNLOCK(stmt);
7927  return ret;
7928 }
7929 #endif
7930 
7931 #ifdef WINTERFACE
7932 
7950 SQLRETURN SQL_API
7952  SQLWCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7953  SQLWCHAR *PKschema, SQLSMALLINT PKschemaLen,
7954  SQLWCHAR *PKtable, SQLSMALLINT PKtableLen,
7955  SQLWCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7956  SQLWCHAR *FKschema, SQLSMALLINT FKschemaLen,
7957  SQLWCHAR *FKtable, SQLSMALLINT FKtableLen)
7958 {
7959  char *pc = NULL, *ps = NULL, *pt = NULL;
7960  char *fc = NULL, *fs = NULL, *ft = NULL;
7961  SQLRETURN ret;
7962 
7963  HSTMT_LOCK(stmt);
7964  if (PKcatalog) {
7965  pc = uc_to_utf_c(PKcatalog, PKcatalogLen);
7966  if (!pc) {
7967  ret = nomem((STMT *) stmt);
7968  goto done;
7969  }
7970  }
7971  if (PKschema) {
7972  ps = uc_to_utf_c(PKschema, PKschemaLen);
7973  if (!ps) {
7974  ret = nomem((STMT *) stmt);
7975  goto done;
7976  }
7977  }
7978  if (PKtable) {
7979  pt = uc_to_utf_c(PKtable, PKtableLen);
7980  if (!pt) {
7981  ret = nomem((STMT *) stmt);
7982  goto done;
7983  }
7984  }
7985  if (FKcatalog) {
7986  fc = uc_to_utf_c(FKcatalog, FKcatalogLen);
7987  if (!fc) {
7988  ret = nomem((STMT *) stmt);
7989  goto done;
7990  }
7991  }
7992  if (FKschema) {
7993  fs = uc_to_utf_c(FKschema, FKschemaLen);
7994  if (!fs) {
7995  ret = nomem((STMT *) stmt);
7996  goto done;
7997  }
7998  }
7999  if (FKtable) {
8000  ft = uc_to_utf_c(FKtable, FKtableLen);
8001  if (!ft) {
8002  ret = nomem((STMT *) stmt);
8003  goto done;
8004  }
8005  }
8006  ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
8007  (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
8008  (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
8009  (SQLCHAR *) ft, SQL_NTS);
8010 done:
8011  uc_free(ft);
8012  uc_free(fs);
8013  uc_free(fc);
8014  uc_free(pt);
8015  uc_free(ps);
8016  uc_free(pc);
8017  HSTMT_UNLOCK(stmt);
8018  return ret;
8019 }
8020 #endif
8021 
8028 static SQLRETURN
8030 {
8031  int ret = SQL_SUCCESS, rc, busy_count = 0;
8032  char *errp = NULL;
8033  DBC *d = (DBC *) s->dbc;
8034 
8035  if (!d->autocommit && !d->intrans && !d->trans_disable) {
8036 begin_again:
8037  rc = sqlite3_exec(d->sqlite, "BEGIN TRANSACTION", NULL, NULL, &errp);
8038  if (rc == SQLITE_BUSY) {
8039  if (busy_handler((void *) d, ++busy_count)) {
8040  if (errp) {
8041  sqlite3_free(errp);
8042  errp = NULL;
8043  }
8044  goto begin_again;
8045  }
8046  }
8047  dbtracerc(d, rc, errp);
8048  if (rc != SQLITE_OK) {
8049  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
8050  errp ? errp : "unknown error", rc);
8051  ret = SQL_ERROR;
8052  } else {
8053  d->intrans = 1;
8054  }
8055  if (errp) {
8056  sqlite3_free(errp);
8057  errp = NULL;
8058  }
8059  }
8060  return ret;
8061 }
8062 
8071 static SQLRETURN
8072 endtran(DBC *d, SQLSMALLINT comptype, int force)
8073 {
8074  int ret, busy_count = 0;
8075  char *sql, *errp = NULL;
8076 
8077  if (!d->sqlite) {
8078  setstatd(d, -1, "not connected", (*d->ov3) ? "HY000" : "S1000");
8079  return SQL_ERROR;
8080  }
8081  if ((!force && d->autocommit) || !d->intrans) {
8082  return SQL_SUCCESS;
8083  }
8084  switch (comptype) {
8085  case SQL_COMMIT:
8086  sql = "COMMIT TRANSACTION";
8087  goto doit;
8088  case SQL_ROLLBACK:
8089  sql = "ROLLBACK TRANSACTION";
8090  doit:
8091  ret = sqlite3_exec(d->sqlite, sql, NULL, NULL, &errp);
8092  dbtracerc(d, ret, errp);
8093  if (ret == SQLITE_BUSY && busy_count < 10) {
8094  if (busy_handler((void *) d, ++busy_count)) {
8095  if (errp) {
8096  sqlite3_free(errp);
8097  errp = NULL;
8098  }
8099  goto doit;
8100  }
8101  }
8102  if (ret != SQLITE_OK) {
8103  setstatd(d, ret, "%s", (*d->ov3) ? "HY000" : "S1000",
8104  errp ? errp : "transaction failed");
8105  if (errp) {
8106  sqlite3_free(errp);
8107  errp = NULL;
8108  }
8109  return SQL_ERROR;
8110  }
8111  if (errp) {
8112  sqlite3_free(errp);
8113  errp = NULL;
8114  }
8115  d->intrans = 0;
8116  return SQL_SUCCESS;
8117  }
8118  setstatd(d, -1, "invalid completion type", (*d->ov3) ? "HY000" : "S1000");
8119  return SQL_ERROR;
8120 }
8121 
8130 static SQLRETURN
8131 drvendtran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
8132 {
8133  DBC *dbc = NULL;
8134  int fail = 0;
8135  SQLRETURN ret;
8136 #if defined(_WIN32) || defined(_WIN64)
8137  ENV *env;
8138 #endif
8139 
8140  switch (type) {
8141  case SQL_HANDLE_DBC:
8142  HDBC_LOCK((SQLHDBC) handle);
8143  if (handle == SQL_NULL_HDBC) {
8144  return SQL_INVALID_HANDLE;
8145  }
8146  dbc = (DBC *) handle;
8147  ret = endtran(dbc, comptype, 0);
8148  HDBC_UNLOCK((SQLHDBC) handle);
8149  return ret;
8150  case SQL_HANDLE_ENV:
8151  if (handle == SQL_NULL_HENV) {
8152  return SQL_INVALID_HANDLE;
8153  }
8154 #if defined(_WIN32) || defined(_WIN64)
8155  env = (ENV *) handle;
8156  if (env->magic != ENV_MAGIC) {
8157  return SQL_INVALID_HANDLE;
8158  }
8159  EnterCriticalSection(&env->cs);
8160 #endif
8161  dbc = ((ENV *) handle)->dbcs;
8162  while (dbc) {
8163  HDBC_LOCK((SQLHDBC) dbc);
8164  ret = endtran(dbc, comptype, 0);
8165  HDBC_UNLOCK((SQLHDBC) dbc);
8166  if (ret != SQL_SUCCESS) {
8167  fail++;
8168  }
8169  dbc = dbc->next;
8170  }
8171 #if defined(_WIN32) || defined(_WIN64)
8172  LeaveCriticalSection(&env->cs);
8173 #endif
8174  return fail ? SQL_ERROR : SQL_SUCCESS;
8175  }
8176  return SQL_INVALID_HANDLE;
8177 }
8178 
8187 SQLRETURN SQL_API
8188 SQLEndTran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
8189 {
8190  return drvendtran(type, handle, comptype);
8191 }
8192 
8201 SQLRETURN SQL_API
8202 SQLTransact(SQLHENV env, SQLHDBC dbc, SQLUSMALLINT type)
8203 {
8204  if (dbc != SQL_NULL_HDBC) {
8205  return drvendtran(SQL_HANDLE_DBC, (SQLHANDLE) dbc, type);
8206  }
8207  return drvendtran(SQL_HANDLE_ENV, (SQLHANDLE) env, type);
8208 }
8209 
8214 SQLRETURN SQL_API
8215 SQLCopyDesc(SQLHDESC source, SQLHDESC target)
8216 {
8217  return SQL_ERROR;
8218 }
8219 
8220 #ifndef WINTERFACE
8221 
8232 SQLRETURN SQL_API
8233 SQLNativeSql(SQLHSTMT stmt, SQLCHAR *sqlin, SQLINTEGER sqlinLen,
8234  SQLCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
8235 {
8236  int outLen = 0;
8237  SQLRETURN ret = SQL_SUCCESS;
8238 
8239  HSTMT_LOCK(stmt);
8240  if (sqlinLen == SQL_NTS) {
8241  sqlinLen = strlen((char *) sqlin);
8242  }
8243  if (sql) {
8244  if (sqlMax > 0) {
8245  strncpy((char *) sql, (char *) sqlin, sqlMax - 1);
8246  sqlin[sqlMax - 1] = '\0';
8247  outLen = min(sqlMax - 1, sqlinLen);
8248  }
8249  } else {
8250  outLen = sqlinLen;
8251  }
8252  if (sqlLen) {
8253  *sqlLen = outLen;
8254  }
8255  if (sql && outLen < sqlinLen) {
8256  setstat((STMT *) stmt, -1, "data right truncated", "01004");
8257  ret = SQL_SUCCESS_WITH_INFO;
8258  }
8259  HSTMT_UNLOCK(stmt);
8260  return ret;
8261 }
8262 #endif
8263 
8264 #ifdef WINTERFACE
8265 
8276 SQLRETURN SQL_API
8277 SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen,
8278  SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
8279 {
8280  int outLen = 0;
8281  SQLRETURN ret = SQL_SUCCESS;
8282 
8283  HSTMT_LOCK(stmt);
8284  if (sqlinLen == SQL_NTS) {
8285  sqlinLen = uc_strlen(sqlin);
8286  }
8287  if (sql) {
8288  if (sqlMax > 0) {
8289  uc_strncpy(sql, sqlin, sqlMax - 1);
8290  sqlin[sqlMax - 1] = 0;
8291  outLen = min(sqlMax - 1, sqlinLen);
8292  }
8293  } else {
8294  outLen = sqlinLen;
8295  }
8296  if (sqlLen) {
8297  *sqlLen = outLen;
8298  }
8299  if (sql && outLen < sqlinLen) {
8300  setstat((STMT *) stmt, -1, "data right truncated", "01004");
8301  ret = SQL_SUCCESS_WITH_INFO;
8302  }
8303  HSTMT_UNLOCK(stmt);
8304  return ret;
8305 }
8306 #endif
8307 
8312 static COL procSpec2[] = {
8313  { "SYSTEM", "PROCEDURE", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
8314  { "SYSTEM", "PROCEDURE", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
8315  { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8316  { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
8317  { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
8318  { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
8319  { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
8320  { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
8321 };
8322 
8323 static COL procSpec3[] = {
8324  { "SYSTEM", "PROCEDURE", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
8325  { "SYSTEM", "PROCEDURE", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
8326  { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8327  { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
8328  { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
8329  { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
8330  { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
8331  { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
8332 };
8333 
8334 #ifndef WINTERFACE
8335 
8347 SQLRETURN SQL_API
8348 SQLProcedures(SQLHSTMT stmt,
8349  SQLCHAR *catalog, SQLSMALLINT catalogLen,
8350  SQLCHAR *schema, SQLSMALLINT schemaLen,
8351  SQLCHAR *proc, SQLSMALLINT procLen)
8352 {
8353  SQLRETURN ret;
8354 
8355  HSTMT_LOCK(stmt);
8357  procSpec3, array_size(procSpec3), NULL);
8358  HSTMT_UNLOCK(stmt);
8359  return ret;
8360 }
8361 #endif
8362 
8363 #ifdef WINTERFACE
8364 
8376 SQLRETURN SQL_API
8378  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
8379  SQLWCHAR *schema, SQLSMALLINT schemaLen,
8380  SQLWCHAR *proc, SQLSMALLINT procLen)
8381 {
8382  SQLRETURN ret;
8383 
8384  HSTMT_LOCK(stmt);
8386  procSpec3, array_size(procSpec3), NULL);
8387  HSTMT_UNLOCK(stmt);
8388  return ret;
8389 }
8390 #endif
8391 
8396 static COL procColSpec2[] = {
8397  { "SYSTEM", "PROCCOL", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
8398  { "SYSTEM", "PROCCOL", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
8399  { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8400  { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
8401  { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
8402  { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
8403  { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
8404  { "SYSTEM", "PROCCOL", "PRECISION", SQL_INTEGER, 10 },
8405  { "SYSTEM", "PROCCOL", "LENGTH", SQL_INTEGER, 10 },
8406  { "SYSTEM", "PROCCOL", "SCALE", SQL_SMALLINT, 5 },
8407  { "SYSTEM", "PROCCOL", "RADIX", SQL_SMALLINT, 5 },
8408  { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
8409  { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
8410  { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
8411  { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
8412  { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
8413  { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
8414  { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
8415  { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
8416 };
8417 
8418 static COL procColSpec3[] = {
8419  { "SYSTEM", "PROCCOL", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
8420  { "SYSTEM", "PROCCOL", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
8421  { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8422  { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
8423  { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
8424  { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
8425  { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
8426  { "SYSTEM", "PROCCOL", "COLUMN_SIZE", SQL_INTEGER, 10 },
8427  { "SYSTEM", "PROCCOL", "BUFFER_LENGTH", SQL_INTEGER, 10 },
8428  { "SYSTEM", "PROCCOL", "DECIMAL_DIGITS", SQL_SMALLINT, 5 },
8429  { "SYSTEM", "PROCCOL", "NUM_PREC_RADIX", SQL_SMALLINT, 5 },
8430  { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
8431  { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
8432  { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
8433  { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
8434  { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
8435  { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
8436  { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
8437  { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
8438 };
8439 
8440 #ifndef WINTERFACE
8441 
8455 SQLRETURN SQL_API
8456 SQLProcedureColumns(SQLHSTMT stmt,
8457  SQLCHAR *catalog, SQLSMALLINT catalogLen,
8458  SQLCHAR *schema, SQLSMALLINT schemaLen,
8459  SQLCHAR *proc, SQLSMALLINT procLen,
8460  SQLCHAR *column, SQLSMALLINT columnLen)
8461 {
8462  SQLRETURN ret;
8463 
8464  HSTMT_LOCK(stmt);
8467  HSTMT_UNLOCK(stmt);
8468  return ret;
8469 }
8470 #endif
8471 
8472 #ifdef WINTERFACE
8473 
8488 SQLRETURN SQL_API
8490  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
8491  SQLWCHAR *schema, SQLSMALLINT schemaLen,
8492  SQLWCHAR *proc, SQLSMALLINT procLen,
8493  SQLWCHAR *column, SQLSMALLINT columnLen)
8494 {
8495  SQLRETURN ret;
8496 
8497  HSTMT_LOCK(stmt);
8500  HSTMT_UNLOCK(stmt);
8501  return ret;
8502 }
8503 #endif
8504 
8515 SQLRETURN SQL_API
8516 SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val,
8517  SQLINTEGER len, SQLINTEGER *lenp)
8518 {
8519  ENV *e;
8520  SQLRETURN ret = SQL_ERROR;
8521 
8522  if (env == SQL_NULL_HENV) {
8523  return SQL_INVALID_HANDLE;
8524  }
8525  e = (ENV *) env;
8526  if (!e || e->magic != ENV_MAGIC) {
8527  return SQL_INVALID_HANDLE;
8528  }
8529 #if defined(_WIN32) || defined(_WIN64)
8530  EnterCriticalSection(&e->cs);
8531 #endif
8532  switch (attr) {
8533  case SQL_ATTR_CONNECTION_POOLING:
8534  if (val) {
8535  *((SQLINTEGER *) val) = e->pool ?
8536  SQL_CP_ONE_PER_DRIVER : SQL_CP_OFF;
8537  }
8538  if (lenp) {
8539  *lenp = sizeof (SQLINTEGER);
8540  }
8541  ret = SQL_SUCCESS;
8542  break;
8543  case SQL_ATTR_CP_MATCH:
8544  *((SQLINTEGER *) val) = SQL_CP_RELAXED_MATCH;
8545  if (lenp) {
8546  *lenp = sizeof (SQLINTEGER);
8547  }
8548  ret = SQL_SUCCESS;
8549  break;
8550  case SQL_ATTR_OUTPUT_NTS:
8551  if (val) {
8552  *((SQLINTEGER *) val) = SQL_TRUE;
8553  }
8554  if (lenp) {
8555  *lenp = sizeof (SQLINTEGER);
8556  }
8557  ret = SQL_SUCCESS;
8558  break;
8559  case SQL_ATTR_ODBC_VERSION:
8560  if (val) {
8561  *((SQLINTEGER *) val) = e->ov3 ? SQL_OV_ODBC3 : SQL_OV_ODBC2;
8562  }
8563  if (lenp) {
8564  *lenp = sizeof (SQLINTEGER);
8565  }
8566  ret = SQL_SUCCESS;
8567  break;
8568  }
8569 #if defined(_WIN32) || defined(_WIN64)
8570  LeaveCriticalSection(&e->cs);
8571 #endif
8572  return ret;
8573 }
8574 
8584 SQLRETURN SQL_API
8585 SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
8586 {
8587  ENV *e;
8588  SQLRETURN ret = SQL_ERROR;
8589 
8590  if (env == SQL_NULL_HENV) {
8591  return SQL_INVALID_HANDLE;
8592  }
8593  e = (ENV *) env;
8594  if (!e || e->magic != ENV_MAGIC) {
8595  return SQL_INVALID_HANDLE;
8596  }
8597 #if defined(_WIN32) || defined(_WIN64)
8598  EnterCriticalSection(&e->cs);
8599 #endif
8600  switch (attr) {
8601  case SQL_ATTR_CONNECTION_POOLING:
8602  if (val == (SQLPOINTER) SQL_CP_ONE_PER_DRIVER) {
8603  e->pool = 1;
8604  ret = SQL_SUCCESS;
8605  } else if (val == (SQLPOINTER) SQL_CP_OFF) {
8606  e->pool = 0;
8607  ret = SQL_SUCCESS;
8608  }
8609  break;
8610  case SQL_ATTR_CP_MATCH:
8611  ret = SQL_SUCCESS;
8612  break;
8613  case SQL_ATTR_OUTPUT_NTS:
8614  if (val == (SQLPOINTER) SQL_TRUE) {
8615  ret = SQL_SUCCESS;
8616  }
8617  break;
8618  case SQL_ATTR_ODBC_VERSION:
8619  if (!val) {
8620  break;
8621  }
8622  if (val == (SQLPOINTER) SQL_OV_ODBC2) {
8623  e->ov3 = 0;
8624  ret = SQL_SUCCESS;
8625  } else if (val == (SQLPOINTER) SQL_OV_ODBC3) {
8626  e->ov3 = 1;
8627  ret = SQL_SUCCESS;
8628  }
8629  break;
8630  }
8631 #if defined(_WIN32) || defined(_WIN64)
8632  LeaveCriticalSection(&e->cs);
8633 #endif
8634  return ret;
8635 }
8636 
8650 static SQLRETURN
8651 drvgetdiagrec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8652  SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
8653  SQLSMALLINT buflen, SQLSMALLINT *msglen)
8654 {
8655  DBC *d = NULL;
8656  STMT *s = NULL;
8657  int len, naterr;
8658  char *logmsg, *sqlst;
8659  SQLRETURN ret = SQL_ERROR;
8660 
8661  if (handle == SQL_NULL_HANDLE) {
8662  return SQL_INVALID_HANDLE;
8663  }
8664  if (sqlstate) {
8665  sqlstate[0] = '\0';
8666  }
8667  if (msg && buflen > 0) {
8668  msg[0] = '\0';
8669  }
8670  if (msglen) {
8671  *msglen = 0;
8672  }
8673  if (nativeerr) {
8674  *nativeerr = 0;
8675  }
8676  switch (htype) {
8677  case SQL_HANDLE_ENV:
8678  case SQL_HANDLE_DESC:
8679  return SQL_NO_DATA;
8680  case SQL_HANDLE_DBC:
8681  HDBC_LOCK((SQLHDBC) handle);
8682  d = (DBC *) handle;
8683  logmsg = (char *) d->logmsg;
8684  sqlst = d->sqlstate;
8685  naterr = d->naterr;
8686  break;
8687  case SQL_HANDLE_STMT:
8688  HSTMT_LOCK((SQLHSTMT) handle);
8689  s = (STMT *) handle;
8690  logmsg = (char *) s->logmsg;
8691  sqlst = s->sqlstate;
8692  naterr = s->naterr;
8693  break;
8694  default:
8695  return SQL_INVALID_HANDLE;
8696  }
8697  if (buflen < 0) {
8698  goto done;
8699  }
8700  if (recno > 1) {
8701  ret = SQL_NO_DATA;
8702  goto done;
8703  }
8704  len = strlen(logmsg);
8705  if (len == 0) {
8706  ret = SQL_NO_DATA;
8707  goto done;
8708  }
8709  if (nativeerr) {
8710  *nativeerr = naterr;
8711  }
8712  if (sqlstate) {
8713  strcpy((char *) sqlstate, sqlst);
8714  }
8715  if (msglen) {
8716  *msglen = len;
8717  }
8718  if (len >= buflen) {
8719  if (msg && buflen > 0) {
8720  strncpy((char *) msg, logmsg, buflen);
8721  msg[buflen - 1] = '\0';
8722  logmsg[0] = '\0';
8723  }
8724  } else if (msg) {
8725  strcpy((char *) msg, logmsg);
8726  logmsg[0] = '\0';
8727  }
8728  ret = SQL_SUCCESS;
8729 done:
8730  switch (htype) {
8731  case SQL_HANDLE_DBC:
8732  HDBC_UNLOCK((SQLHDBC) handle);
8733  break;
8734  case SQL_HANDLE_STMT:
8735  HSTMT_UNLOCK((SQLHSTMT) handle);
8736  break;
8737  }
8738  return ret;
8739 }
8740 
8741 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
8742 
8755 SQLRETURN SQL_API
8756 SQLGetDiagRec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8757  SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
8758  SQLSMALLINT buflen, SQLSMALLINT *msglen)
8759 {
8760  return drvgetdiagrec(htype, handle, recno, sqlstate,
8761  nativeerr, msg, buflen, msglen);
8762 }
8763 #endif
8764 
8765 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
8766 #ifdef WINTERFACE
8767 
8781 SQLRETURN SQL_API
8782 SQLGetDiagRecW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8783  SQLWCHAR *sqlstate, SQLINTEGER *nativeerr, SQLWCHAR *msg,
8784  SQLSMALLINT buflen, SQLSMALLINT *msglen)
8785 {
8786  char state[16];
8787  SQLSMALLINT len;
8788  SQLRETURN ret;
8789 
8790  ret = drvgetdiagrec(htype, handle, recno, (SQLCHAR *) state,
8791  nativeerr, (SQLCHAR *) msg, buflen, &len);
8792  if (ret == SQL_SUCCESS) {
8793  if (sqlstate) {
8794  uc_from_utf_buf((SQLCHAR *) state, -1, sqlstate,
8795  6 * sizeof (SQLWCHAR));
8796  }
8797  if (msg) {
8798  if (len > 0) {
8799  SQLWCHAR *m = NULL;
8800 
8801  m = uc_from_utf((unsigned char *) msg, len);
8802  if (m) {
8803  if (buflen) {
8804  buflen /= sizeof (SQLWCHAR);
8805  uc_strncpy(msg, m, buflen);
8806  m[len] = 0;
8807  len = min(buflen, uc_strlen(m));
8808  } else {
8809  len = uc_strlen(m);
8810  }
8811  uc_free(m);
8812  } else {
8813  len = 0;
8814  }
8815  }
8816  if (len <= 0) {
8817  len = 0;
8818  if (buflen > 0) {
8819  msg[0] = 0;
8820  }
8821  }
8822  } else {
8823  /* estimated length !!! */
8824  len *= sizeof (SQLWCHAR);
8825  }
8826  if (msglen) {
8827  *msglen = len;
8828  }
8829  } else if (ret == SQL_NO_DATA) {
8830  if (sqlstate) {
8831  sqlstate[0] = 0;
8832  }
8833  if (msg) {
8834  if (buflen > 0) {
8835  msg[0] = 0;
8836  }
8837  }
8838  if (msglen) {
8839  *msglen = 0;
8840  }
8841  }
8842  return ret;
8843 }
8844 #endif
8845 #endif
8846 
8859 static SQLRETURN
8860 drvgetdiagfield(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8861  SQLSMALLINT id, SQLPOINTER info,
8862  SQLSMALLINT buflen, SQLSMALLINT *stringlen)
8863 {
8864  DBC *d = NULL;
8865  STMT *s = NULL;
8866  int len, naterr, strbuf = 1;
8867  char *logmsg, *sqlst, *clrmsg = NULL;
8868  SQLRETURN ret = SQL_ERROR;
8869 
8870  if (handle == SQL_NULL_HANDLE) {
8871  return SQL_INVALID_HANDLE;
8872  }
8873  if (stringlen) {
8874  *stringlen = 0;
8875  }
8876  switch (htype) {
8877  case SQL_HANDLE_ENV:
8878  case SQL_HANDLE_DESC:
8879  return SQL_NO_DATA;
8880  case SQL_HANDLE_DBC:
8881  HDBC_LOCK((SQLHDBC) handle);
8882  d = (DBC *) handle;
8883  logmsg = (char *) d->logmsg;
8884  sqlst = d->sqlstate;
8885  naterr = d->naterr;
8886  break;
8887  case SQL_HANDLE_STMT:
8888  HSTMT_LOCK((SQLHSTMT) handle);
8889  s = (STMT *) handle;
8890  d = (DBC *) s->dbc;
8891  logmsg = (char *) s->logmsg;
8892  sqlst = s->sqlstate;
8893  naterr = s->naterr;
8894  break;
8895  default:
8896  return SQL_INVALID_HANDLE;
8897  }
8898  if (buflen < 0) {
8899  switch (buflen) {
8900  case SQL_IS_POINTER:
8901  case SQL_IS_UINTEGER:
8902  case SQL_IS_INTEGER:
8903  case SQL_IS_USMALLINT:
8904  case SQL_IS_SMALLINT:
8905  strbuf = 0;
8906  break;
8907  default:
8908  ret = SQL_ERROR;
8909  goto done;
8910  }
8911  }
8912  if (recno > 1) {
8913  ret = SQL_NO_DATA;
8914  goto done;
8915  }
8916  switch (id) {
8917  case SQL_DIAG_CLASS_ORIGIN:
8918  logmsg = "ISO 9075";
8919  if (sqlst[0] == 'I' && sqlst[1] == 'M') {
8920  logmsg = "ODBC 3.0";
8921  }
8922  break;
8923  case SQL_DIAG_SUBCLASS_ORIGIN:
8924  logmsg = "ISO 9075";
8925  if (sqlst[0] == 'I' && sqlst[1] == 'M') {
8926  logmsg = "ODBC 3.0";
8927  } else if (sqlst[0] == 'H' && sqlst[1] == 'Y') {
8928  logmsg = "ODBC 3.0";
8929  } else if (sqlst[0] == '2' || sqlst[0] == '0' || sqlst[0] == '4') {
8930  logmsg = "ODBC 3.0";
8931  }
8932  break;
8933  case SQL_DIAG_CONNECTION_NAME:
8934  case SQL_DIAG_SERVER_NAME:
8935  logmsg = d->dsn ? d->dsn : "No DSN";
8936  break;
8937  case SQL_DIAG_SQLSTATE:
8938  logmsg = sqlst;
8939  break;
8940  case SQL_DIAG_MESSAGE_TEXT:
8941  if (info) {
8942  clrmsg = logmsg;
8943  }
8944  break;
8945  case SQL_DIAG_NUMBER:
8946  naterr = 1;
8947  /* fall through */
8948  case SQL_DIAG_NATIVE:
8949  len = strlen(logmsg);
8950  if (len == 0) {
8951  ret = SQL_NO_DATA;
8952  goto done;
8953  }
8954  if (info) {
8955  *((SQLINTEGER *) info) = naterr;
8956  }
8957  ret = SQL_SUCCESS;
8958  goto done;
8959  case SQL_DIAG_DYNAMIC_FUNCTION:
8960  logmsg = "";
8961  break;
8962  case SQL_DIAG_CURSOR_ROW_COUNT:
8963  if (htype == SQL_HANDLE_STMT) {
8964  SQLULEN count;
8965 
8966  count = (s->isselect == 1 || s->isselect == -1) ? s->nrows : 0;
8967  *((SQLULEN *) info) = count;
8968  ret = SQL_SUCCESS;
8969  }
8970  goto done;
8971  case SQL_DIAG_ROW_COUNT:
8972  if (htype == SQL_HANDLE_STMT) {
8973  SQLULEN count;
8974 
8975  count = s->isselect ? 0 : s->nrows;
8976  *((SQLULEN *) info) = count;
8977  ret = SQL_SUCCESS;
8978  }
8979  goto done;
8980  default:
8981  goto done;
8982  }
8983  if (info && buflen > 0) {
8984  ((char *) info)[0] = '\0';
8985  }
8986  len = strlen(logmsg);
8987  if (len == 0) {
8988  ret = SQL_NO_DATA;
8989  goto done;
8990  }
8991  if (stringlen) {
8992  *stringlen = len;
8993  }
8994  if (strbuf) {
8995  if (len >= buflen) {
8996  if (info && buflen > 0) {
8997  if (stringlen) {
8998  *stringlen = buflen - 1;
8999  }
9000  strncpy((char *) info, logmsg, buflen);
9001  ((char *) info)[buflen - 1] = '\0';
9002  }
9003  } else if (info) {
9004  strcpy((char *) info, logmsg);
9005  }
9006  }
9007  if (clrmsg) {
9008  *clrmsg = '\0';
9009  }
9010  ret = SQL_SUCCESS;
9011 done:
9012  switch (htype) {
9013  case SQL_HANDLE_DBC:
9014  HDBC_UNLOCK((SQLHDBC) handle);
9015  break;
9016  case SQL_HANDLE_STMT:
9017  HSTMT_UNLOCK((SQLHSTMT) handle);
9018  break;
9019  }
9020  return ret;
9021 }
9022 
9023 #ifndef WINTERFACE
9024 
9036 SQLRETURN SQL_API
9037 SQLGetDiagField(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
9038  SQLSMALLINT id, SQLPOINTER info,
9039  SQLSMALLINT buflen, SQLSMALLINT *stringlen)
9040 {
9041  return drvgetdiagfield(htype, handle, recno, id, info, buflen, stringlen);
9042 }
9043 #endif
9044 
9045 #ifdef WINTERFACE
9046 
9058 SQLRETURN SQL_API
9059 SQLGetDiagFieldW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
9060  SQLSMALLINT id, SQLPOINTER info,
9061  SQLSMALLINT buflen, SQLSMALLINT *stringlen)
9062 {
9063  SQLSMALLINT len;
9064  SQLRETURN ret;
9065 
9066  ret = drvgetdiagfield(htype, handle, recno, id, info, buflen, &len);
9067  if (ret == SQL_SUCCESS) {
9068  if (info) {
9069  switch (id) {
9070  case SQL_DIAG_CLASS_ORIGIN:
9071  case SQL_DIAG_SUBCLASS_ORIGIN:
9072  case SQL_DIAG_CONNECTION_NAME:
9073  case SQL_DIAG_SERVER_NAME:
9074  case SQL_DIAG_SQLSTATE:
9075  case SQL_DIAG_MESSAGE_TEXT:
9076  case SQL_DIAG_DYNAMIC_FUNCTION:
9077  if (len > 0) {
9078  SQLWCHAR *m = NULL;
9079 
9080  m = uc_from_utf((unsigned char *) info, len);
9081  if (m) {
9082  if (buflen) {
9083  buflen /= sizeof (SQLWCHAR);
9084  uc_strncpy(info, m, buflen);
9085  m[len] = 0;
9086  len = min(buflen, uc_strlen(m));
9087  } else {
9088  len = uc_strlen(m);
9089  }
9090  uc_free(m);
9091  len *= sizeof (SQLWCHAR);
9092  } else {
9093  len = 0;
9094  }
9095  }
9096  if (len <= 0) {
9097  len = 0;
9098  if (buflen > 0) {
9099  ((SQLWCHAR *) info)[0] = 0;
9100  }
9101  }
9102  }
9103  } else {
9104  switch (id) {
9105  case SQL_DIAG_CLASS_ORIGIN:
9106  case SQL_DIAG_SUBCLASS_ORIGIN:
9107  case SQL_DIAG_CONNECTION_NAME:
9108  case SQL_DIAG_SERVER_NAME:
9109  case SQL_DIAG_SQLSTATE:
9110  case SQL_DIAG_MESSAGE_TEXT:
9111  case SQL_DIAG_DYNAMIC_FUNCTION:
9112  len *= sizeof (SQLWCHAR);
9113  break;
9114  }
9115  }
9116  if (stringlen) {
9117  *stringlen = len;
9118  }
9119  }
9120  return ret;
9121 }
9122 #endif
9123 
9134 static SQLRETURN
9135 drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9136  SQLINTEGER bufmax, SQLINTEGER *buflen)
9137 {
9138  STMT *s = (STMT *) stmt;
9139  SQLULEN *uval = (SQLULEN *) val;
9140  SQLINTEGER dummy;
9141  char dummybuf[16];
9142 
9143  if (!buflen) {
9144  buflen = &dummy;
9145  }
9146  if (!uval) {
9147  uval = (SQLPOINTER) dummybuf;
9148  }
9149  switch (attr) {
9150  case SQL_QUERY_TIMEOUT:
9151  *uval = 0;
9152  *buflen = sizeof (SQLULEN);
9153  return SQL_SUCCESS;
9154  case SQL_ATTR_CURSOR_TYPE:
9155  *uval = s->curtype;
9156  *buflen = sizeof (SQLULEN);
9157  return SQL_SUCCESS;
9158  case SQL_ATTR_CURSOR_SCROLLABLE:
9159  *uval = (s->curtype != SQL_CURSOR_FORWARD_ONLY) ?
9160  SQL_SCROLLABLE : SQL_NONSCROLLABLE;
9161  *buflen = sizeof (SQLULEN);
9162  return SQL_SUCCESS;
9163 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
9164  case SQL_ATTR_CURSOR_SENSITIVITY:
9165  *uval = SQL_UNSPECIFIED;
9166  *buflen = sizeof (SQLULEN);
9167  return SQL_SUCCESS;
9168 #endif
9169  case SQL_ATTR_ROW_NUMBER:
9170  if (s->s3stmt) {
9171  *uval = (s->s3stmt_rownum < 0) ?
9172  SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
9173  } else {
9174  *uval = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
9175  }
9176  *buflen = sizeof (SQLULEN);
9177  return SQL_SUCCESS;
9178  case SQL_ATTR_ASYNC_ENABLE:
9179  *uval = SQL_ASYNC_ENABLE_OFF;
9180  *buflen = sizeof (SQLULEN);
9181  return SQL_SUCCESS;
9182  case SQL_CONCURRENCY:
9183  *uval = SQL_CONCUR_LOCK;
9184  *buflen = sizeof (SQLULEN);
9185  return SQL_SUCCESS;
9186  case SQL_ATTR_RETRIEVE_DATA:
9187  *uval = s->retr_data;
9188  *buflen = sizeof (SQLULEN);
9189  return SQL_SUCCESS;
9190  case SQL_ROWSET_SIZE:
9191  case SQL_ATTR_ROW_ARRAY_SIZE:
9192  *uval = s->rowset_size;
9193  *buflen = sizeof (SQLULEN);
9194  return SQL_SUCCESS;
9195  /* Needed for some driver managers, but dummies for now */
9196  case SQL_ATTR_IMP_ROW_DESC:
9197  case SQL_ATTR_APP_ROW_DESC:
9198  case SQL_ATTR_IMP_PARAM_DESC:
9199  case SQL_ATTR_APP_PARAM_DESC:
9200  *((SQLHDESC *) uval) = (SQLHDESC) DEAD_MAGIC;
9201  *buflen = sizeof (SQLHDESC);
9202  return SQL_SUCCESS;
9203  case SQL_ATTR_ROW_STATUS_PTR:
9204  *((SQLUSMALLINT **) uval) = s->row_status;
9205  *buflen = sizeof (SQLUSMALLINT *);
9206  return SQL_SUCCESS;
9207  case SQL_ATTR_ROWS_FETCHED_PTR:
9208  *((SQLULEN **) uval) = s->row_count;
9209  *buflen = sizeof (SQLULEN *);
9210  return SQL_SUCCESS;
9211  case SQL_ATTR_USE_BOOKMARKS: {
9212  STMT *s = (STMT *) stmt;
9213 
9214  *(SQLUINTEGER *) uval = s->bkmrk;
9215  *buflen = sizeof (SQLUINTEGER);
9216  return SQL_SUCCESS;
9217  }
9218  case SQL_ATTR_FETCH_BOOKMARK_PTR:
9219  *(SQLPOINTER *) uval = s->bkmrkptr;
9220  *buflen = sizeof (SQLPOINTER);
9221  return SQL_SUCCESS;
9222  case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
9223  *((SQLULEN **) uval) = s->parm_bind_offs;
9224  *buflen = sizeof (SQLULEN *);
9225  return SQL_SUCCESS;
9226  case SQL_ATTR_PARAM_BIND_TYPE:
9227  *((SQLULEN *) uval) = s->parm_bind_type;
9228  *buflen = sizeof (SQLULEN);
9229  return SQL_SUCCESS;
9230  case SQL_ATTR_PARAM_OPERATION_PTR:
9231  *((SQLUSMALLINT **) uval) = s->parm_oper;
9232  *buflen = sizeof (SQLUSMALLINT *);
9233  return SQL_SUCCESS;
9234  case SQL_ATTR_PARAM_STATUS_PTR:
9235  *((SQLUSMALLINT **) uval) = s->parm_status;
9236  *buflen = sizeof (SQLUSMALLINT *);
9237  return SQL_SUCCESS;
9238  case SQL_ATTR_PARAMS_PROCESSED_PTR:
9239  *((SQLULEN **) uval) = s->parm_proc;
9240  *buflen = sizeof (SQLULEN *);
9241  return SQL_SUCCESS;
9242  case SQL_ATTR_PARAMSET_SIZE:
9243  *((SQLULEN *) uval) = s->paramset_size;
9244  *buflen = sizeof (SQLULEN);
9245  return SQL_SUCCESS;
9246  case SQL_ATTR_ROW_BIND_TYPE:
9247  *(SQLULEN *) uval = s->bind_type;
9248  *buflen = sizeof (SQLULEN);
9249  return SQL_SUCCESS;
9250  case SQL_ATTR_ROW_BIND_OFFSET_PTR:
9251  *((SQLULEN **) uval) = s->bind_offs;
9252  *buflen = sizeof (SQLULEN *);
9253  return SQL_SUCCESS;
9254  case SQL_ATTR_MAX_ROWS:
9255  *((SQLULEN *) uval) = s->max_rows;
9256  *buflen = sizeof (SQLULEN);
9257  return SQL_SUCCESS;
9258  case SQL_ATTR_MAX_LENGTH:
9259  *((SQLULEN *) uval) = 1000000000;
9260  *buflen = sizeof (SQLULEN);
9261  return SQL_SUCCESS;
9262 #ifdef SQL_ATTR_METADATA_ID
9263  case SQL_ATTR_METADATA_ID:
9264  *((SQLULEN *) uval) = SQL_FALSE;
9265  *buflen = sizeof (SQLULEN);
9266  return SQL_SUCCESS;
9267 #endif
9268  }
9269  return drvunimplstmt(stmt);
9270 }
9271 
9272 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
9273 
9283 SQLRETURN SQL_API
9284 SQLGetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9285  SQLINTEGER bufmax, SQLINTEGER *buflen)
9286 {
9287  SQLRETURN ret;
9288 
9289  HSTMT_LOCK(stmt);
9290  ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
9291  HSTMT_UNLOCK(stmt);
9292  return ret;
9293 }
9294 #endif
9295 
9296 #ifdef WINTERFACE
9297 
9307 SQLRETURN SQL_API
9308 SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9309  SQLINTEGER bufmax, SQLINTEGER *buflen)
9310 {
9311  SQLRETURN ret;
9312 
9313  HSTMT_LOCK(stmt);
9314  ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
9315  HSTMT_UNLOCK(stmt);
9316  return ret;
9317 }
9318 #endif
9319 
9329 static SQLRETURN
9330 drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9331  SQLINTEGER buflen)
9332 {
9333  STMT *s = (STMT *) stmt;
9334 #if defined(SQL_BIGINT) && defined(__WORDSIZE) && (__WORDSIZE == 64)
9335  SQLBIGINT uval;
9336 
9337  uval = (SQLBIGINT) val;
9338 #else
9339  SQLULEN uval;
9340 
9341  uval = (SQLULEN) val;
9342 #endif
9343  switch (attr) {
9344  case SQL_ATTR_CURSOR_TYPE:
9345  if (val == (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY) {
9346  s->curtype = SQL_CURSOR_FORWARD_ONLY;
9347  } else {
9348  s->curtype = SQL_CURSOR_STATIC;
9349  }
9350  if (val != (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY &&
9351  val != (SQLPOINTER) SQL_CURSOR_STATIC) {
9352  goto e01s02;
9353  }
9354  return SQL_SUCCESS;
9355  case SQL_ATTR_CURSOR_SCROLLABLE:
9356  if (val == (SQLPOINTER) SQL_NONSCROLLABLE) {
9357  s->curtype = SQL_CURSOR_FORWARD_ONLY;
9358  } else {
9359  s->curtype = SQL_CURSOR_STATIC;
9360  }
9361  return SQL_SUCCESS;
9362  case SQL_ATTR_ASYNC_ENABLE:
9363  if (val != (SQLPOINTER) SQL_ASYNC_ENABLE_OFF) {
9364  e01s02:
9365  setstat(s, -1, "option value changed", "01S02");
9366  return SQL_SUCCESS_WITH_INFO;
9367  }
9368  return SQL_SUCCESS;
9369  case SQL_CONCURRENCY:
9370  if (val != (SQLPOINTER) SQL_CONCUR_LOCK) {
9371  goto e01s02;
9372  }
9373  return SQL_SUCCESS;
9374 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
9375  case SQL_ATTR_CURSOR_SENSITIVITY:
9376  if (val != (SQLPOINTER) SQL_UNSPECIFIED) {
9377  goto e01s02;
9378  }
9379  return SQL_SUCCESS;
9380 #endif
9381  case SQL_ATTR_QUERY_TIMEOUT:
9382  return SQL_SUCCESS;
9383  case SQL_ATTR_RETRIEVE_DATA:
9384  if (val != (SQLPOINTER) SQL_RD_ON &&
9385  val != (SQLPOINTER) SQL_RD_OFF) {
9386  goto e01s02;
9387  }
9388  s->retr_data = uval;
9389  return SQL_SUCCESS;
9390  case SQL_ROWSET_SIZE:
9391  case SQL_ATTR_ROW_ARRAY_SIZE:
9392  if (uval < 1) {
9393  setstat(s, -1, "invalid rowset size", "HY000");
9394  return SQL_ERROR;
9395  } else {
9396  SQLUSMALLINT *rst = &s->row_status1;
9397 
9398  if (uval > 1) {
9399  rst = xmalloc(sizeof (SQLUSMALLINT) * uval);
9400  if (!rst) {
9401  return nomem(s);
9402  }
9403  }
9404  if (s->row_status0 != &s->row_status1) {
9405  freep(&s->row_status0);
9406  }
9407  s->row_status0 = rst;
9408  s->rowset_size = uval;
9409  }
9410  return SQL_SUCCESS;
9411  case SQL_ATTR_ROW_STATUS_PTR:
9412  s->row_status = (SQLUSMALLINT *) val;
9413  return SQL_SUCCESS;
9414  case SQL_ATTR_ROWS_FETCHED_PTR:
9415  s->row_count = (SQLULEN *) val;
9416  return SQL_SUCCESS;
9417  case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
9418  s->parm_bind_offs = (SQLULEN *) val;
9419  return SQL_SUCCESS;
9420  case SQL_ATTR_PARAM_BIND_TYPE:
9421  s->parm_bind_type = uval;
9422  return SQL_SUCCESS;
9423  case SQL_ATTR_PARAM_OPERATION_PTR:
9424  s->parm_oper = (SQLUSMALLINT *) val;
9425  return SQL_SUCCESS;
9426  case SQL_ATTR_PARAM_STATUS_PTR:
9427  s->parm_status = (SQLUSMALLINT *) val;
9428  return SQL_SUCCESS;
9429  case SQL_ATTR_PARAMS_PROCESSED_PTR:
9430  s->parm_proc = (SQLULEN *) val;
9431  return SQL_SUCCESS;
9432  case SQL_ATTR_PARAMSET_SIZE:
9433  if (uval < 1) {
9434  goto e01s02;
9435  }
9436  s->paramset_size = uval;
9437  s->paramset_count = 0;
9438  return SQL_SUCCESS;
9439  case SQL_ATTR_ROW_BIND_TYPE:
9440  s->bind_type = uval;
9441  return SQL_SUCCESS;
9442  case SQL_ATTR_ROW_BIND_OFFSET_PTR:
9443  s->bind_offs = (SQLULEN *) val;
9444  return SQL_SUCCESS;
9445  case SQL_ATTR_USE_BOOKMARKS:
9446  if (val != (SQLPOINTER) SQL_UB_OFF &&
9447  val != (SQLPOINTER) SQL_UB_ON &&
9448  val != (SQLPOINTER) SQL_UB_VARIABLE) {
9449  goto e01s02;
9450  }
9451  if (*s->ov3 && val == (SQLPOINTER) SQL_UB_VARIABLE) {
9452  s->bkmrk = SQL_UB_VARIABLE;
9453  return SQL_SUCCESS;
9454  }
9455  if (val == (SQLPOINTER) SQL_UB_VARIABLE) {
9456  s->bkmrk = SQL_UB_ON;
9457  goto e01s02;
9458  }
9459  s->bkmrk = (val == (SQLPOINTER) SQL_UB_ON) ? SQL_UB_ON : SQL_UB_OFF;
9460  return SQL_SUCCESS;
9461  case SQL_ATTR_FETCH_BOOKMARK_PTR:
9462  s->bkmrkptr = (SQLINTEGER *) val;
9463  return SQL_SUCCESS;
9464  case SQL_ATTR_MAX_ROWS:
9465  s->max_rows = uval;
9466  return SQL_SUCCESS;
9467  case SQL_ATTR_MAX_LENGTH:
9468  if (val != (SQLPOINTER) 1000000000) {
9469  goto e01s02;
9470  }
9471  return SQL_SUCCESS;
9472 #ifdef SQL_ATTR_METADATA_ID
9473  case SQL_ATTR_METADATA_ID:
9474  if (val != (SQLPOINTER) SQL_FALSE) {
9475  goto e01s02;
9476  }
9477  return SQL_SUCCESS;
9478 #endif
9479  }
9480  return drvunimplstmt(stmt);
9481 }
9482 
9483 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
9484 
9493 SQLRETURN SQL_API
9494 SQLSetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9495  SQLINTEGER buflen)
9496 {
9497  SQLRETURN ret;
9498 
9499  HSTMT_LOCK(stmt);
9500  ret = drvsetstmtattr(stmt, attr, val, buflen);
9501  HSTMT_UNLOCK(stmt);
9502  return ret;
9503 }
9504 #endif
9505 
9506 #ifdef WINTERFACE
9507 
9516 SQLRETURN SQL_API
9517 SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9518  SQLINTEGER buflen)
9519 {
9520  SQLRETURN ret;
9521 
9522  HSTMT_LOCK(stmt);
9523  ret = drvsetstmtattr(stmt, attr, val, buflen);
9524  HSTMT_UNLOCK(stmt);
9525  return ret;
9526 }
9527 #endif
9528 
9537 static SQLRETURN
9538 drvgetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9539 {
9540  STMT *s = (STMT *) stmt;
9541  SQLUINTEGER *ret = (SQLUINTEGER *) param;
9542 
9543  switch (opt) {
9544  case SQL_QUERY_TIMEOUT:
9545  *ret = 0;
9546  return SQL_SUCCESS;
9547  case SQL_CURSOR_TYPE:
9548  *ret = s->curtype;
9549  return SQL_SUCCESS;
9550  case SQL_ROW_NUMBER:
9551  if (s->s3stmt) {
9552  *ret = (s->s3stmt_rownum < 0) ?
9553  SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
9554  } else {
9555  *ret = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
9556  }
9557  return SQL_SUCCESS;
9558  case SQL_ASYNC_ENABLE:
9559  *ret = SQL_ASYNC_ENABLE_OFF;
9560  return SQL_SUCCESS;
9561  case SQL_CONCURRENCY:
9562  *ret = SQL_CONCUR_LOCK;
9563  return SQL_SUCCESS;
9564  case SQL_ATTR_RETRIEVE_DATA:
9565  *ret = s->retr_data;
9566  return SQL_SUCCESS;
9567  case SQL_ROWSET_SIZE:
9568  case SQL_ATTR_ROW_ARRAY_SIZE:
9569  *ret = s->rowset_size;
9570  return SQL_SUCCESS;
9571  case SQL_ATTR_MAX_ROWS:
9572  *ret = s->max_rows;
9573  return SQL_SUCCESS;
9574  case SQL_ATTR_MAX_LENGTH:
9575  *ret = 1000000000;
9576  return SQL_SUCCESS;
9577  }
9578  return drvunimplstmt(stmt);
9579 }
9580 
9589 SQLRETURN SQL_API
9590 SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9591 {
9592  SQLRETURN ret;
9593 
9594  HSTMT_LOCK(stmt);
9595  ret = drvgetstmtoption(stmt, opt, param);
9596  HSTMT_UNLOCK(stmt);
9597  return ret;
9598 }
9599 
9600 #ifdef WINTERFACE
9601 
9609 SQLRETURN SQL_API
9610 SQLGetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9611 {
9612  SQLRETURN ret;
9613 
9614  HSTMT_LOCK(stmt);
9615  ret = drvgetstmtoption(stmt, opt, param);
9616  HSTMT_UNLOCK(stmt);
9617  return ret;
9618 }
9619 #endif
9620 
9629 static SQLRETURN
9630 drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
9631 {
9632  STMT *s = (STMT *) stmt;
9633 
9634  switch (opt) {
9635  case SQL_CURSOR_TYPE:
9636  if (param == SQL_CURSOR_FORWARD_ONLY) {
9637  s->curtype = param;
9638  } else {
9639  s->curtype = SQL_CURSOR_STATIC;
9640  }
9641  if (param != SQL_CURSOR_FORWARD_ONLY &&
9642  param != SQL_CURSOR_STATIC) {
9643  goto e01s02;
9644  }
9645  return SQL_SUCCESS;
9646  case SQL_ASYNC_ENABLE:
9647  if (param != SQL_ASYNC_ENABLE_OFF) {
9648  goto e01s02;
9649  }
9650  return SQL_SUCCESS;
9651  case SQL_CONCURRENCY:
9652  if (param != SQL_CONCUR_LOCK) {
9653  goto e01s02;
9654  }
9655  return SQL_SUCCESS;
9656  case SQL_QUERY_TIMEOUT:
9657  return SQL_SUCCESS;
9658  case SQL_RETRIEVE_DATA:
9659  if (param != SQL_RD_ON && param != SQL_RD_OFF) {
9660  e01s02:
9661  setstat(s, -1, "option value changed", "01S02");
9662  return SQL_SUCCESS_WITH_INFO;
9663  }
9664  s->retr_data = (int) param;
9665  return SQL_SUCCESS;
9666  case SQL_ROWSET_SIZE:
9667  case SQL_ATTR_ROW_ARRAY_SIZE:
9668  if (param < 1) {
9669  setstat(s, -1, "invalid rowset size", "HY000");
9670  return SQL_ERROR;
9671  } else {
9672  SQLUSMALLINT *rst = &s->row_status1;
9673 
9674  if (param > 1) {
9675  rst = xmalloc(sizeof (SQLUSMALLINT) * param);
9676  if (!rst) {
9677  return nomem(s);
9678  }
9679  }
9680  if (s->row_status0 != &s->row_status1) {
9681  freep(&s->row_status0);
9682  }
9683  s->row_status0 = rst;
9684  s->rowset_size = param;
9685  }
9686  return SQL_SUCCESS;
9687  case SQL_ATTR_MAX_ROWS:
9688  s->max_rows = param;
9689  return SQL_SUCCESS;
9690  case SQL_ATTR_MAX_LENGTH:
9691  if (param != 1000000000) {
9692  goto e01s02;
9693  }
9694  return SQL_SUCCESS;
9695  }
9696  return drvunimplstmt(stmt);
9697 }
9698 
9707 SQLRETURN SQL_API
9708 SQLSetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt,
9710 {
9711  SQLRETURN ret;
9712 
9713  HSTMT_LOCK(stmt);
9714  ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
9715  HSTMT_UNLOCK(stmt);
9716  return ret;
9717 }
9718 
9719 #ifdef WINTERFACE
9720 
9728 SQLRETURN SQL_API
9729 SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt,
9731 {
9732  SQLRETURN ret;
9733 
9734  HSTMT_LOCK(stmt);
9735  ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
9736  HSTMT_UNLOCK(stmt);
9737  return ret;
9738 }
9739 #endif
9740 
9747 static SQLRETURN
9749 {
9750  int i;
9751 
9752  if (!s->bindcols || s->nbindcols < s->ncols) {
9753 unbound:
9754  setstat(s, -1, "unbound columns", (*s->ov3) ? "HY000" : "S1000");
9755  return SQL_ERROR;
9756  }
9757  for (i = 0; i < s->ncols; i++) {
9758  BINDCOL *b = &s->bindcols[i];
9759 
9760  if (b->type == SQL_UNKNOWN_TYPE || !b->valp) {
9761  goto unbound;
9762  }
9763  }
9764  return SQL_SUCCESS;
9765 }
9766 
9778 static SQLRETURN
9779 setposbind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
9780 {
9781  DBC *d = (DBC *) s->dbc;
9782  SQLPOINTER dp = 0;
9783  SQLLEN *lp = 0;
9784  BINDCOL *b = &s->bindcols[i];
9785  COL *c = &s->cols[i];
9786  char strbuf[128], *cp;
9787 
9788  if (b->valp) {
9789  if (s->bind_type != SQL_BIND_BY_COLUMN) {
9790  dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
9791  } else {
9792  dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
9793  }
9794  if (s->bind_offs) {
9795  dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
9796  }
9797  }
9798  if (b->lenp) {
9799  if (s->bind_type != SQL_BIND_BY_COLUMN) {
9800  lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
9801  } else {
9802  lp = b->lenp + rsi;
9803  }
9804  if (s->bind_offs) {
9805  lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
9806  }
9807  }
9808  if (!dp || !lp) {
9809  setstat(s, -1, "unbound column in positional update",
9810  (*s->ov3) ? "HY000" : "S1000");
9811  return SQL_ERROR;
9812  }
9813  if (*lp == SQL_NULL_DATA) {
9814  sqlite3_bind_null(stmt, si);
9815  if (d->trace) {
9816  fprintf(d->trace, "-- parameter %d: NULL\n", si);
9817  fflush(d->trace);
9818  }
9819  return SQL_SUCCESS;
9820  }
9821  switch (b->type) {
9822  case SQL_C_UTINYINT:
9823  case SQL_C_TINYINT:
9824  case SQL_C_STINYINT:
9825  sqlite3_bind_int(stmt, si, *(SQLCHAR *) dp);
9826  if (d->trace) {
9827  fprintf(d->trace, "-- parameter %d: %d\n", si, *(SQLCHAR *) dp);
9828  fflush(d->trace);
9829  }
9830  break;
9831 #ifdef SQL_BIT
9832  case SQL_C_BIT:
9833  sqlite3_bind_int(stmt, si, (*(SQLCHAR *) dp) ? 1 : 0);
9834  if (d->trace) {
9835  fprintf(d->trace, "-- parameter %d: %d\n", si,
9836  (*(SQLCHAR *) dp) ? 1 : 0);
9837  fflush(d->trace);
9838  }
9839  break;
9840 #endif
9841  case SQL_C_USHORT:
9842  sqlite3_bind_int(stmt, si, *(SQLUSMALLINT *) dp);
9843  if (d->trace) {
9844  fprintf(d->trace, "-- parameter %d: %d\n", si,
9845  *(SQLUSMALLINT *) dp);
9846  fflush(d->trace);
9847  }
9848  break;
9849  case SQL_C_SHORT:
9850  case SQL_C_SSHORT:
9851  sqlite3_bind_int(stmt, si, *(SQLSMALLINT *) dp);
9852  if (d->trace) {
9853  fprintf(d->trace, "-- parameter %d: %d\n", si,
9854  *(SQLSMALLINT *) dp);
9855  fflush(d->trace);
9856  }
9857  break;
9858  case SQL_C_ULONG:
9859  sqlite3_bind_int(stmt, si, *(SQLUINTEGER *) dp);
9860  if (d->trace) {
9861  fprintf(d->trace, "-- parameter %d: %ld\n", si,
9862  (long) *(SQLUINTEGER *) dp);
9863  fflush(d->trace);
9864  }
9865  break;
9866  case SQL_C_LONG:
9867  case SQL_C_SLONG:
9868  sqlite3_bind_int(stmt, si, *(SQLINTEGER *) dp);
9869  if (d->trace) {
9870  fprintf(d->trace, "-- parameter %d: %ld\n", si,
9871  (long) *(SQLINTEGER *) dp);
9872  fflush(d->trace);
9873  }
9874  break;
9875 #ifdef SQL_BIGINT
9876  case SQL_C_UBIGINT:
9877  case SQL_C_SBIGINT:
9878  sqlite3_bind_int64(stmt, si, *(SQLBIGINT *) dp);
9879  if (d->trace) {
9880  fprintf(d->trace,
9881 #ifdef _WIN32
9882  "-- parameter %d: %I64d\n",
9883 #else
9884  "-- parameter %d: %lld\n",
9885 #endif
9886  si, (sqlite_int64) *(SQLBIGINT *) dp);
9887  fflush(d->trace);
9888  }
9889  break;
9890 #endif
9891  case SQL_C_FLOAT:
9892  sqlite3_bind_double(stmt, si, *(float *) dp);
9893  if (d->trace) {
9894  fprintf(d->trace, "-- parameter %d: %g\n", si,
9895  *(float *) dp);
9896  fflush(d->trace);
9897  }
9898  break;
9899  case SQL_C_DOUBLE:
9900  sqlite3_bind_double(stmt, si, *(double *) dp);
9901  if (d->trace) {
9902  fprintf(d->trace, "-- parameter %d: %g\n", si,
9903  *(double *) dp);
9904  fflush(d->trace);
9905  }
9906  break;
9907  case SQL_C_BINARY:
9908  sqlite3_bind_blob(stmt, si, (char *) dp, *lp, SQLITE_STATIC);
9909  if (d->trace) {
9910  fprintf(d->trace, "-- parameter %d: [BLOB]\n", si);
9911  fflush(d->trace);
9912  }
9913  break;
9914 #ifdef WCHARSUPPORT
9915  case SQL_C_WCHAR:
9916  cp = uc_to_utf((SQLWCHAR *) dp, *lp);
9917  if (!cp) {
9918  return nomem(s);
9919  }
9920  sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
9921  if (d->trace) {
9922  fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
9923  fflush(d->trace);
9924  }
9925  uc_free(cp);
9926  break;
9927 #endif
9928  case SQL_C_CHAR:
9929 #if defined(_WIN32) || defined(_WIN64)
9930  if (*s->oemcp) {
9931  cp = wmb_to_utf((char *) dp, *lp);
9932  if (!cp) {
9933  return nomem(s);
9934  }
9935  sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
9936  if (d->trace) {
9937  fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
9938  fflush(d->trace);
9939  }
9940  uc_free(cp);
9941  } else
9942 #endif
9943  {
9944  if (*lp == SQL_NTS) {
9945  sqlite3_bind_text(stmt, si, (char *) dp, -1,
9946  SQLITE_STATIC);
9947  if (d->trace) {
9948  fprintf(d->trace, "-- parameter %d: '%s'\n", si,
9949  (char *) dp);
9950  fflush(d->trace);
9951  }
9952  } else {
9953  sqlite3_bind_text(stmt, si, (char *) dp, *lp,
9954  SQLITE_STATIC);
9955  if (d->trace) {
9956  fprintf(d->trace, "-- parameter %d: '%*s'\n", si,
9957  (int) *lp, (char *) dp);
9958  fflush(d->trace);
9959  }
9960  }
9961  }
9962  break;
9963 #ifdef SQL_C_TYPE_DATE
9964  case SQL_C_TYPE_DATE:
9965 #endif
9966  case SQL_C_DATE:
9967  if (*s->jdconv) {
9968  int a, b, x1, x2, y, m, dd;
9969  double v;
9970 
9971  y = ((DATE_STRUCT *) dp)->year;
9972  m = ((DATE_STRUCT *) dp)->month;
9973  dd = ((DATE_STRUCT *) dp)->day;
9974  if (m <= 2) {
9975  y--;
9976  m += 12;
9977  }
9978  a = y / 100;
9979  b = 2 - a + (a / 4);
9980  x1 = 36525 * (y + 4716) / 100;
9981  x2 = 306001 * (m + 1) / 10000;
9982  v = x1 + x2 + dd + b - 1524.5;
9983  sqlite3_bind_double(stmt, si, v);
9984  if (d->trace) {
9985  fprintf(d->trace, "-- parameter %d: %g\n", si, v);
9986  fflush(d->trace);
9987  }
9988  } else {
9989  sprintf(strbuf, "%04d-%02d-%02d",
9990  ((DATE_STRUCT *) dp)->year,
9991  ((DATE_STRUCT *) dp)->month,
9992  ((DATE_STRUCT *) dp)->day);
9993  sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
9994  if (d->trace) {
9995  fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
9996  fflush(d->trace);
9997  }
9998  }
9999  break;
10000 #ifdef SQL_C_TYPE_TIME
10001  case SQL_C_TYPE_TIME:
10002 #endif
10003  case SQL_C_TIME:
10004  if (*s->jdconv) {
10005  double v;
10006 
10007  v = 2451544.5 +
10008  (((TIME_STRUCT *) dp)->hour * 3600000.0 +
10009  ((TIME_STRUCT *) dp)->minute * 60000.0 +
10010  ((TIME_STRUCT *) dp)->second * 1000.0) / 86400000.0;
10011  sqlite3_bind_double(stmt, si, v);
10012  if (d->trace) {
10013  fprintf(d->trace, "-- parameter %d: %g\n", si, v);
10014  fflush(d->trace);
10015  }
10016  } else {
10017  sprintf(strbuf, "%02d:%02d:%02d",
10018  ((TIME_STRUCT *) dp)->hour,
10019  ((TIME_STRUCT *) dp)->minute,
10020  ((TIME_STRUCT *) dp)->second);
10021  sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
10022  if (d->trace) {
10023  fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
10024  fflush(d->trace);
10025  }
10026  }
10027  break;
10028 #ifdef SQL_C_TYPE_TIMESTAMP
10029  case SQL_C_TYPE_TIMESTAMP:
10030 #endif
10031  case SQL_C_TIMESTAMP:
10032  if (*s->jdconv) {
10033  int a, b, x1, x2, y, m, dd;
10034  double v;
10035 
10036  y = ((TIMESTAMP_STRUCT *) dp)->year;
10037  m = ((TIMESTAMP_STRUCT *) dp)->month;
10038  dd = ((TIMESTAMP_STRUCT *) dp)->day;
10039  if (m <= 2) {
10040  y--;
10041  m += 12;
10042  }
10043  a = y / 100;
10044  b = 2 - a + (a / 4);
10045  x1 = 36525 * (y + 4716) / 100;
10046  x2 = 306001 * (m + 1) / 10000;
10047  v = x1 + x2 + dd + b - 1524.5 +
10048  (((TIMESTAMP_STRUCT *) dp)->hour * 3600000.0 +
10049  ((TIMESTAMP_STRUCT *) dp)->minute * 60000.0 +
10050  ((TIMESTAMP_STRUCT *) dp)->second * 1000.0 +
10051  ((TIMESTAMP_STRUCT *) dp)->fraction / 1.0E6)
10052  / 86400000.0;
10053  sqlite3_bind_double(stmt, si, v);
10054  if (d->trace) {
10055  fprintf(d->trace, "-- parameter %d: %g\n", si, v);
10056  fflush(d->trace);
10057  }
10058  } else {
10059  int frac;
10060 
10061  frac = (int) ((TIMESTAMP_STRUCT *) dp)->fraction;
10062  frac /= 1000000;
10063  frac = frac % 1000;
10064  if (frac < 0) {
10065  frac = 0;
10066  }
10067  if (c->prec && c->prec <= 16) {
10068  sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
10069  ((TIMESTAMP_STRUCT *) dp)->year,
10070  ((TIMESTAMP_STRUCT *) dp)->month,
10071  ((TIMESTAMP_STRUCT *) dp)->day,
10072  ((TIMESTAMP_STRUCT *) dp)->hour,
10073  ((TIMESTAMP_STRUCT *) dp)->minute);
10074  } else if (c->prec && c->prec <= 19) {
10075  sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
10076  ((TIMESTAMP_STRUCT *) dp)->year,
10077  ((TIMESTAMP_STRUCT *) dp)->month,
10078  ((TIMESTAMP_STRUCT *) dp)->day,
10079  ((TIMESTAMP_STRUCT *) dp)->hour,
10080  ((TIMESTAMP_STRUCT *) dp)->minute,
10081  ((TIMESTAMP_STRUCT *) dp)->second);
10082  } else {
10083  sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
10084  ((TIMESTAMP_STRUCT *) dp)->year,
10085  ((TIMESTAMP_STRUCT *) dp)->month,
10086  ((TIMESTAMP_STRUCT *) dp)->day,
10087  ((TIMESTAMP_STRUCT *) dp)->hour,
10088  ((TIMESTAMP_STRUCT *) dp)->minute,
10089  ((TIMESTAMP_STRUCT *) dp)->second,
10090  frac);
10091  }
10092  sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
10093  if (d->trace) {
10094  fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
10095  fflush(d->trace);
10096  }
10097  }
10098  break;
10099  default:
10100  setstat(s, -1, "unsupported column type in positional update",
10101  (*s->ov3) ? "HY000" : "S1000");
10102  return SQL_ERROR;
10103  }
10104  return SQL_SUCCESS;
10105 }
10106 
10118 static SQLRETURN
10119 setposibind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
10120 {
10121  DBC *d = (DBC *) s->dbc;
10122  char **data;
10123  int pos;
10124 
10125  pos = s->rowprs;
10126  if (pos < 0) {
10127  setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
10128  return SQL_ERROR;
10129  }
10130  pos += rsi;
10131  data = s->rows + s->ncols + (pos * s->ncols) + i;
10132  if (*data == NULL) {
10133  sqlite3_bind_null(stmt, si);
10134  if (d->trace) {
10135  fprintf(d->trace, "-- parameter %d: NULL\n", si);
10136  fflush(d->trace);
10137  }
10138  } else {
10139  sqlite3_bind_text(stmt, si, *data, -1, SQLITE_STATIC);
10140  if (d->trace) {
10141  fprintf(d->trace, "-- parameter %d: '%s'\n", si, *data);
10142  fflush(d->trace);
10143  }
10144  }
10145  return SQL_SUCCESS;
10146 }
10147 
10155 static SQLRETURN
10156 setposrefr(STMT *s, int rsi)
10157 {
10158  int i, withinfo = 0;
10159  SQLRETURN ret = SQL_SUCCESS;
10160 
10161  for (i = 0; s->bindcols && i < s->ncols; i++) {
10162  BINDCOL *b = &s->bindcols[i];
10163  SQLPOINTER dp = 0;
10164  SQLLEN *lp = 0;
10165 
10166  b->offs = 0;
10167  if (b->valp) {
10168  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10169  dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
10170  } else {
10171  dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
10172  }
10173  if (s->bind_offs) {
10174  dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
10175  }
10176  }
10177  if (b->lenp) {
10178  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10179  lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
10180  } else {
10181  lp = b->lenp + rsi;
10182  }
10183  if (s->bind_offs) {
10184  lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
10185  }
10186  }
10187  if (dp || lp) {
10188  int rowp = s->rowp;
10189 
10190  s->rowp = s->rowprs + rsi;
10191  ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp,
10192  b->max, lp, 0);
10193  s->rowp = rowp;
10194  if (!SQL_SUCCEEDED(ret)) {
10195  s->row_status0[rsi] = SQL_ROW_ERROR;
10196  break;
10197  }
10198  if (ret != SQL_SUCCESS) {
10199  withinfo = 1;
10200 #ifdef SQL_ROW_SUCCESS_WITH_INFO
10201  s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
10202 #endif
10203  }
10204  }
10205  }
10206  if (SQL_SUCCEEDED(ret)) {
10207  ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
10208  }
10209  return ret;
10210 }
10211 
10221 static SQLRETURN
10222 drvsetpos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10223 {
10224  STMT *s = (STMT *) stmt;
10225  DBC *d = (DBC *) s->dbc;
10226  int rowp, i, k, rc, nretry = 0;
10227  dstr *sql = 0;
10228  const char *endp;
10229  sqlite3_stmt *s3stmt = NULL;
10230  SQLRETURN ret;
10231 
10232  if (lock != SQL_LOCK_NO_CHANGE) {
10233  setstat(s, -1, "unsupported locking mode",
10234  (*s->ov3) ? "HY000" : "S1000");
10235  return SQL_ERROR;
10236  }
10237  if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10238  setstat(s, -1, "incompatible statement",
10239  (*s->ov3) ? "HY000" : "S1000");
10240  return SQL_ERROR;
10241  }
10242  if (op == SQL_ADD) {
10243  if (s->one_tbl <= 0) {
10244  setstat(s, -1, "incompatible rowset",
10245  (*s->ov3) ? "HY000" : "S1000");
10246  return SQL_ERROR;
10247  }
10248  if (row == 0 || row > s->rowset_size + 1) {
10249  goto rowoor;
10250  }
10251  ret = chkunbound(s);
10252  if (ret != SQL_SUCCESS) {
10253  return ret;
10254  }
10255  sql = dsappend(sql, "INSERT INTO ");
10256  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10257  sql = dsappendq(sql, s->dyncols[0].db);
10258  sql = dsappend(sql, ".");
10259  }
10260  sql = dsappendq(sql, s->dyncols[0].table);
10261  for (i = 0; i < s->ncols; i++) {
10262  sql = dsappend(sql, (i > 0) ? "," : "(");
10263  sql = dsappendq(sql, s->dyncols[i].column);
10264  }
10265  sql = dsappend(sql, ") VALUES ");
10266  for (i = 0; i < s->ncols; i++) {
10267  sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10268  }
10269  sql = dsappend(sql, ")");
10270  if (dserr(sql)) {
10271  dsfree(sql);
10272  return nomem(s);
10273  }
10274 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10275  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10276 #else
10277  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10278 #endif
10279  do {
10280  s3stmt = NULL;
10281 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10282  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10283  &s3stmt, &endp);
10284 #else
10285  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10286  &s3stmt, &endp);
10287 #endif
10288  if (rc != SQLITE_OK) {
10289  if (s3stmt) {
10290  sqlite3_finalize(s3stmt);
10291  s3stmt = NULL;
10292  }
10293  }
10294  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10295  dbtracerc(d, rc, NULL);
10296  dsfree(sql);
10297  if (rc != SQLITE_OK) {
10298 istmterr:
10299  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10300  sqlite3_errmsg(d->sqlite), rc);
10301  if (s3stmt) {
10302  dbtraceapi(d, "sqlite3_finalize", NULL);
10303  sqlite3_finalize(s3stmt);
10304  }
10305  return SQL_ERROR;
10306  }
10307  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10308  ret = setposbind(s, s3stmt, i, k, row - 1);
10309  if (ret != SQL_SUCCESS) {
10310  dbtraceapi(d, "sqlite3_finalize", NULL);
10311  sqlite3_finalize(s3stmt);
10312  return ret;
10313  }
10314  k++;
10315  }
10316  rc = sqlite3_step(s3stmt);
10317  if (rc != SQLITE_DONE) {
10318  goto istmterr;
10319  }
10320  sqlite3_finalize(s3stmt);
10321  if (sqlite3_changes(d->sqlite) > 0 && row <= s->rowset_size) {
10322  if (s->row_status0) {
10323  s->row_status0[row - 1] = SQL_ROW_ADDED;
10324  }
10325  if (s->row_status) {
10326  s->row_status[row - 1] = SQL_ROW_ADDED;
10327  }
10328  }
10329  return SQL_SUCCESS;
10330  } else if (op == SQL_UPDATE || op == SQL_DELETE) {
10331  if (s->one_tbl <= 0 || s->has_pk <= 0) {
10332  setstat(s, -1, "incompatible rowset",
10333  (*s->ov3) ? "HY000" : "S1000");
10334  return SQL_ERROR;
10335  }
10336  if (row == 0) {
10337  ret = SQL_SUCCESS;
10338  for (i = 1; i <= s->rowset_size; i++) {
10339  ret = drvsetpos(stmt, i, op, lock);
10340  if (!SQL_SUCCEEDED(ret)) {
10341  break;
10342  }
10343  }
10344  return ret;
10345  }
10346  if (row > s->rowset_size) {
10347  goto rowoor;
10348  }
10349  }
10350  if (op != SQL_POSITION && op != SQL_REFRESH &&
10351  op != SQL_DELETE && op != SQL_UPDATE) {
10352  return drvunimplstmt(stmt);
10353  }
10354  if (op == SQL_POSITION) {
10355  rowp = s->rowp + row - 1;
10356  if (!s->rows || row == 0 || rowp < -1 || rowp >= s->nrows) {
10357 rowoor:
10358  setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
10359  return SQL_ERROR;
10360  }
10361  s->rowp = rowp;
10362  } else if (op == SQL_REFRESH) {
10363  if (row > s->rowset_size) {
10364  goto rowoor;
10365  }
10366  if (row == 0) {
10367  ret = SQL_SUCCESS;
10368  for (i = 0; i < s->rowset_size; i++) {
10369  ret = setposrefr(s, i);
10370  if (!SQL_SUCCEEDED(ret)) {
10371  break;
10372  }
10373  }
10374  return ret;
10375  }
10376  return setposrefr(s, row - 1);
10377  } else if (op == SQL_DELETE) {
10378  sql = dsappend(sql, "DELETE FROM ");
10379  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10380  sql = dsappendq(sql, s->dyncols[0].db);
10381  sql = dsappend(sql, ".");
10382  }
10383  sql = dsappendq(sql, s->dyncols[0].table);
10384  for (i = k = 0; i < s->ncols; i++) {
10385  if (s->dyncols[i].ispk <= 0) {
10386  continue;
10387  }
10388  sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10389  sql = dsappendq(sql, s->dyncols[i].column);
10390  sql = dsappend(sql, " = ?");
10391  k++;
10392  }
10393  if (dserr(sql)) {
10394  dsfree(sql);
10395  return nomem(s);
10396  }
10397 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10398  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10399 #else
10400  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10401 #endif
10402  do {
10403  s3stmt = NULL;
10404 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10405  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10406  &s3stmt, &endp);
10407 #else
10408  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10409  &s3stmt, &endp);
10410 #endif
10411  if (rc != SQLITE_OK) {
10412  if (s3stmt) {
10413  sqlite3_finalize(s3stmt);
10414  s3stmt = NULL;
10415  }
10416  }
10417  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10418  dbtracerc(d, rc, NULL);
10419  dsfree(sql);
10420  if (rc != SQLITE_OK) {
10421 dstmterr:
10422  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10423  sqlite3_errmsg(d->sqlite), rc);
10424  if (s3stmt) {
10425  dbtraceapi(d, "sqlite3_finalize", NULL);
10426  sqlite3_finalize(s3stmt);
10427  }
10428  return SQL_ERROR;
10429  }
10430  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10431  if (s->dyncols[i].ispk <= 0) {
10432  continue;
10433  }
10434  ret = setposibind(s, s3stmt, i, k, row - 1);
10435  if (ret != SQL_SUCCESS) {
10436  dbtraceapi(d, "sqlite3_finalize", NULL);
10437  sqlite3_finalize(s3stmt);
10438  return ret;
10439  }
10440  k++;
10441  }
10442  rc = sqlite3_step(s3stmt);
10443  if (rc != SQLITE_DONE) {
10444  goto dstmterr;
10445  }
10446  sqlite3_finalize(s3stmt);
10447  if (sqlite3_changes(d->sqlite) > 0) {
10448  if (s->row_status0) {
10449  s->row_status0[row - 1] = SQL_ROW_DELETED;
10450  }
10451  if (s->row_status) {
10452  s->row_status[row - 1] = SQL_ROW_DELETED;
10453  }
10454  }
10455  return SQL_SUCCESS;
10456  } else if (op == SQL_UPDATE) {
10457  ret = chkunbound(s);
10458  if (ret != SQL_SUCCESS) {
10459  return ret;
10460  }
10461  sql = dsappend(sql, "UPDATE ");
10462  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10463  sql = dsappendq(sql, s->dyncols[0].db);
10464  sql = dsappend(sql, ".");
10465  }
10466  sql = dsappendq(sql, s->dyncols[0].table);
10467  for (i = 0; i < s->ncols; i++) {
10468  sql = dsappend(sql, (i > 0) ? ", " : " SET ");
10469  sql = dsappendq(sql, s->dyncols[i].column);
10470  sql = dsappend(sql, " = ?");
10471  }
10472  for (i = k = 0; i < s->ncols; i++) {
10473  if (s->dyncols[i].ispk <= 0) {
10474  continue;
10475  }
10476  sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10477  sql = dsappendq(sql, s->dyncols[i].column);
10478  sql = dsappend(sql, " = ?");
10479  k++;
10480  }
10481  if (dserr(sql)) {
10482  dsfree(sql);
10483  return nomem(s);
10484  }
10485 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10486  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10487 #else
10488  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10489 #endif
10490  do {
10491  s3stmt = NULL;
10492 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10493  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10494  &s3stmt, &endp);
10495 #else
10496  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10497  &s3stmt, &endp);
10498 #endif
10499  if (rc != SQLITE_OK) {
10500  if (s3stmt) {
10501  sqlite3_finalize(s3stmt);
10502  s3stmt = NULL;
10503  }
10504  }
10505  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10506  dbtracerc(d, rc, NULL);
10507  dsfree(sql);
10508  if (rc != SQLITE_OK) {
10509 ustmterr:
10510  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10511  sqlite3_errmsg(d->sqlite), rc);
10512  if (s3stmt) {
10513  dbtraceapi(d, "sqlite3_finalize", NULL);
10514  sqlite3_finalize(s3stmt);
10515  }
10516  return SQL_ERROR;
10517  }
10518  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10519  ret = setposbind(s, s3stmt, i, k, row - 1);
10520  if (ret != SQL_SUCCESS) {
10521  dbtraceapi(d, "sqlite3_finalize", NULL);
10522  sqlite3_finalize(s3stmt);
10523  return ret;
10524  }
10525  k++;
10526  }
10527  for (i = 0; s->bindcols && i < s->ncols; i++) {
10528  if (s->dyncols[i].ispk <= 0) {
10529  continue;
10530  }
10531  ret = setposibind(s, s3stmt, i, k, row - 1);
10532  if (ret != SQL_SUCCESS) {
10533  dbtraceapi(d, "sqlite3_finalize", NULL);
10534  sqlite3_finalize(s3stmt);
10535  return ret;
10536  }
10537  k++;
10538  }
10539  rc = sqlite3_step(s3stmt);
10540  if (rc != SQLITE_DONE) {
10541  goto ustmterr;
10542  }
10543  sqlite3_finalize(s3stmt);
10544  if (sqlite3_changes(d->sqlite) > 0) {
10545  if (s->row_status0) {
10546  s->row_status0[row - 1] = SQL_ROW_UPDATED;
10547  }
10548  if (s->row_status) {
10549  s->row_status[row - 1] = SQL_ROW_UPDATED;
10550  }
10551  }
10552  return SQL_SUCCESS;
10553  }
10554  return SQL_SUCCESS;
10555 }
10556 
10566 SQLRETURN SQL_API
10567 SQLSetPos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10568 {
10569  SQLRETURN ret;
10570 
10571  HSTMT_LOCK(stmt);
10572  ret = drvsetpos(stmt, row, op, lock);
10573  HSTMT_UNLOCK(stmt);
10574  return ret;
10575 }
10576 
10584 static SQLRETURN
10585 drvbulkoperations(SQLHSTMT stmt, SQLSMALLINT op)
10586 {
10587  STMT *s = (STMT *) stmt;
10588  DBC *d = (DBC *) s->dbc;
10589  int row, i, k, rc, nretry = 0;
10590  dstr *sql = 0;
10591  const char *endp;
10592  sqlite3_stmt *s3stmt = NULL;
10593  SQLRETURN ret;
10594 
10595  if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10596  setstat(s, -1, "incompatible statement",
10597  (*s->ov3) ? "HY000" : "S1000");
10598  return SQL_ERROR;
10599  }
10600  if (op == SQL_ADD) {
10601  if (s->one_tbl <= 0) {
10602  setstat(s, -1, "incompatible rowset",
10603  (*s->ov3) ? "HY000" : "S1000");
10604  return SQL_ERROR;
10605  }
10606  ret = chkunbound(s);
10607  if (ret != SQL_SUCCESS) {
10608  return ret;
10609  }
10610  sql = dsappend(sql, "INSERT INTO ");
10611  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10612  sql = dsappendq(sql, s->dyncols[0].db);
10613  sql = dsappend(sql, ".");
10614  }
10615  sql = dsappendq(sql, s->dyncols[0].table);
10616  for (i = 0; i < s->ncols; i++) {
10617  sql = dsappend(sql, (i > 0) ? "," : "(");
10618  sql = dsappendq(sql, s->dyncols[i].column);
10619  }
10620  sql = dsappend(sql, ") VALUES ");
10621  for (i = 0; i < s->ncols; i++) {
10622  sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10623  }
10624  sql = dsappend(sql, ")");
10625  if (dserr(sql)) {
10626  dsfree(sql);
10627  return nomem(s);
10628  }
10629 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10630  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10631 #else
10632  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10633 #endif
10634  do {
10635  s3stmt = NULL;
10636 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10637  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10638  &s3stmt, &endp);
10639 #else
10640  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10641  &s3stmt, &endp);
10642 #endif
10643  if (rc != SQLITE_OK) {
10644  if (s3stmt) {
10645  sqlite3_finalize(s3stmt);
10646  s3stmt = NULL;
10647  }
10648  }
10649  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10650  dbtracerc(d, rc, NULL);
10651  dsfree(sql);
10652  if (rc != SQLITE_OK) {
10653  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10654  sqlite3_errmsg(d->sqlite), rc);
10655  if (s3stmt) {
10656  dbtraceapi(d, "sqlite3_finalize", NULL);
10657  sqlite3_finalize(s3stmt);
10658  }
10659  return SQL_ERROR;
10660  }
10661  for (row = 0; row < s->rowset_size; row++) {
10662  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10663  ret = setposbind(s, s3stmt, i, k, row);
10664  if (ret != SQL_SUCCESS) {
10665 istmterr:
10666  if (s->row_status0) {
10667  s->row_status0[row] = SQL_ROW_ERROR;
10668  }
10669  if (s->row_status) {
10670  s->row_status[row] = SQL_ROW_ERROR;
10671  }
10672  dbtraceapi(d, "sqlite3_finalize", NULL);
10673  sqlite3_finalize(s3stmt);
10674  return ret;
10675  }
10676  k++;
10677  }
10678  rc = sqlite3_step(s3stmt);
10679  if (rc != SQLITE_DONE) {
10680  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10681  sqlite3_errmsg(d->sqlite), rc);
10682  ret = SQL_ERROR;
10683  goto istmterr;
10684  }
10685  if (sqlite3_changes(d->sqlite) > 0) {
10686  if (s->row_status0) {
10687  s->row_status0[row] = SQL_ROW_ADDED;
10688  }
10689  if (s->row_status) {
10690  s->row_status[row] = SQL_ROW_ADDED;
10691  }
10692  }
10693  if (s->bkmrk == SQL_UB_VARIABLE &&
10694  s->bkmrkcol.type == SQL_C_VARBOOKMARK &&
10695  s->bkmrkcol.valp) {
10696  SQLPOINTER *val;
10697 
10698  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10699  val = (SQLPOINTER)
10700  ((char *) s->bkmrkcol.valp + s->bind_type * row);
10701  } else {
10702  val = (SQLPOINTER)
10703  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10704  }
10705  if (s->bind_offs) {
10706  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10707  }
10708  *(sqlite_int64 *) val = sqlite3_last_insert_rowid(d->sqlite);
10709  if (s->bkmrkcol.lenp) {
10710  SQLLEN *ival;
10711 
10712  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10713  ival = (SQLLEN *)
10714  ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10715  } else {
10716  ival = &s->bkmrkcol.lenp[row];
10717  }
10718  if (s->bind_offs) {
10719  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10720  }
10721  *ival = sizeof (sqlite_int64);
10722  }
10723  }
10724  dbtraceapi(d, "sqlite3_reset", NULL);
10725  sqlite3_reset(s3stmt);
10726  }
10727  dbtraceapi(d, "sqlite3_finalize", NULL);
10728  sqlite3_finalize(s3stmt);
10729  return SQL_SUCCESS;
10730  } else if (op == SQL_DELETE_BY_BOOKMARK) {
10731  if (s->has_rowid < 0 ||
10732  s->bkmrk != SQL_UB_VARIABLE ||
10733  s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10734  !s->bkmrkcol.valp) {
10735  setstat(s, -1, "incompatible rowset",
10736  (*s->ov3) ? "HY000" : "S1000");
10737  return SQL_ERROR;
10738  }
10739  sql = dsappend(sql, "DELETE FROM ");
10740  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10741  sql = dsappendq(sql, s->dyncols[0].db);
10742  sql = dsappend(sql, ".");
10743  }
10744  sql = dsappendq(sql, s->dyncols[0].table);
10745  sql = dsappend(sql, " WHERE ");
10746  sql = dsappendq(sql, s->dyncols[0].column);
10747  sql = dsappend(sql, " = ?");
10748  if (dserr(sql)) {
10749  dsfree(sql);
10750  return nomem(s);
10751  }
10752 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10753  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10754 #else
10755  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10756 #endif
10757  do {
10758  s3stmt = NULL;
10759 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10760  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10761  &s3stmt, &endp);
10762 #else
10763  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10764  &s3stmt, &endp);
10765 #endif
10766  if (rc != SQLITE_OK) {
10767  if (s3stmt) {
10768  sqlite3_finalize(s3stmt);
10769  s3stmt = NULL;
10770  }
10771  }
10772  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10773  dbtracerc(d, rc, NULL);
10774  dsfree(sql);
10775  if (rc != SQLITE_OK) {
10776  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10777  sqlite3_errmsg(d->sqlite), rc);
10778  if (s3stmt) {
10779  dbtraceapi(d, "sqlite3_finalize", NULL);
10780  sqlite3_finalize(s3stmt);
10781  }
10782  return SQL_ERROR;
10783  }
10784  for (row = 0; row < s->rowset_size; row++) {
10785  SQLPOINTER *val;
10786  sqlite_int64 rowid;
10787 
10788  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10789  val = (SQLPOINTER)
10790  ((char *) s->bkmrkcol.valp + s->bind_type * row);
10791  } else {
10792  val = (SQLPOINTER)
10793  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10794  }
10795  if (s->bind_offs) {
10796  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10797  }
10798  if (s->bkmrkcol.lenp) {
10799  SQLLEN *ival;
10800 
10801  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10802  ival = (SQLLEN *)
10803  ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10804  } else {
10805  ival = &s->bkmrkcol.lenp[row];
10806  }
10807  if (s->bind_offs) {
10808  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10809  }
10810  if (*ival != sizeof (sqlite_int64)) {
10811  continue;
10812  }
10813  }
10814  rowid = *(sqlite_int64 *) val;
10815  sqlite3_bind_int64(s3stmt, 1, rowid);
10816  if (d->trace) {
10817  fprintf(d->trace,
10818 #ifdef _WIN32
10819  "-- parameter 1: %I64d\n",
10820 #else
10821  "-- parameter 1: %lld\n",
10822 #endif
10823  rowid);
10824  fflush(d->trace);
10825  }
10826  rc = sqlite3_step(s3stmt);
10827  if (rc != SQLITE_DONE) {
10828  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10829  sqlite3_errmsg(d->sqlite), rc);
10830  if (s->row_status0) {
10831  s->row_status0[row] = SQL_ROW_ERROR;
10832  }
10833  if (s->row_status) {
10834  s->row_status[row] = SQL_ROW_ERROR;
10835  }
10836  dbtraceapi(d, "sqlite3_finalize", NULL);
10837  sqlite3_finalize(s3stmt);
10838  return SQL_ERROR;
10839  }
10840  if (sqlite3_changes(d->sqlite) > 0) {
10841  if (s->row_status0) {
10842  s->row_status0[row] = SQL_ROW_DELETED;
10843  }
10844  if (s->row_status) {
10845  s->row_status[row] = SQL_ROW_DELETED;
10846  }
10847  }
10848  dbtraceapi(d, "sqlite3_reset", NULL);
10849  sqlite3_reset(s3stmt);
10850  }
10851  dbtraceapi(d, "sqlite3_finalize", NULL);
10852  sqlite3_finalize(s3stmt);
10853  return SQL_SUCCESS;
10854  } else if (op == SQL_UPDATE_BY_BOOKMARK) {
10855  if (s->has_rowid < 0 ||
10856  s->bkmrk != SQL_UB_VARIABLE ||
10857  s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10858  !s->bkmrkcol.valp) {
10859  setstat(s, -1, "incompatible rowset",
10860  (*s->ov3) ? "HY000" : "S1000");
10861  return SQL_ERROR;
10862  }
10863  ret = chkunbound(s);
10864  if (ret != SQL_SUCCESS) {
10865  return ret;
10866  }
10867  sql = dsappend(sql, "UPDATE ");
10868  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10869  sql = dsappendq(sql, s->dyncols[0].db);
10870  sql = dsappend(sql, ".");
10871  }
10872  sql = dsappendq(sql, s->dyncols[0].table);
10873  for (i = 0, k = 0; i < s->ncols; i++) {
10874  sql = dsappend(sql, (k > 0) ? ", " : " SET ");
10875  sql = dsappendq(sql, s->dyncols[i].column);
10876  sql = dsappend(sql, " = ?");
10877  k++;
10878  }
10879  sql = dsappend(sql, " WHERE ");
10880  sql = dsappendq(sql, s->dyncols[s->has_rowid].column);
10881  sql = dsappend(sql, " = ?");
10882  if (dserr(sql)) {
10883  dsfree(sql);
10884  return nomem(s);
10885  }
10886 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10887  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10888 #else
10889  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10890 #endif
10891  do {
10892  s3stmt = NULL;
10893 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10894  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10895  &s3stmt, &endp);
10896 #else
10897  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10898  &s3stmt, &endp);
10899 #endif
10900  if (rc != SQLITE_OK) {
10901  if (s3stmt) {
10902  sqlite3_finalize(s3stmt);
10903  s3stmt = NULL;
10904  }
10905  }
10906  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10907  dbtracerc(d, rc, NULL);
10908  dsfree(sql);
10909  if (rc != SQLITE_OK) {
10910  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10911  sqlite3_errmsg(d->sqlite), rc);
10912  if (s3stmt) {
10913  dbtraceapi(d, "sqlite3_finalize", NULL);
10914  sqlite3_finalize(s3stmt);
10915  }
10916  return SQL_ERROR;
10917  }
10918  for (row = 0; row < s->rowset_size; row++) {
10919  SQLPOINTER *val;
10920  sqlite_int64 rowid;
10921 
10922  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10923  val = (SQLPOINTER)
10924  ((char *) s->bkmrkcol.valp + s->bind_type * row);
10925  } else {
10926  val = (SQLPOINTER)
10927  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10928  }
10929  if (s->bind_offs) {
10930  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10931  }
10932  if (s->bkmrkcol.lenp) {
10933  SQLLEN *ival;
10934 
10935  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10936  ival = (SQLLEN *)
10937  ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10938  } else {
10939  ival = &s->bkmrkcol.lenp[row];
10940  }
10941  if (s->bind_offs) {
10942  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10943  }
10944  if (*ival != sizeof (sqlite_int64)) {
10945  continue;
10946  }
10947  }
10948  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10949  ret = setposbind(s, s3stmt, i, k, row);
10950  if (ret != SQL_SUCCESS) {
10951 ustmterr:
10952  if (s->row_status0) {
10953  s->row_status0[row] = SQL_ROW_ERROR;
10954  }
10955  if (s->row_status) {
10956  s->row_status[row] = SQL_ROW_ERROR;
10957  }
10958  dbtraceapi(d, "sqlite3_finalize", NULL);
10959  sqlite3_finalize(s3stmt);
10960  return ret;
10961  }
10962  k++;
10963  }
10964  rowid = *(sqlite_int64 *) val;
10965  sqlite3_bind_int64(s3stmt, k, rowid);
10966  if (d->trace) {
10967  fprintf(d->trace,
10968 #ifdef _WIN32
10969  "-- parameter %d: %I64d\n",
10970 #else
10971  "-- parameter %d: %lld\n",
10972 #endif
10973  k, rowid);
10974  fflush(d->trace);
10975  }
10976  rc = sqlite3_step(s3stmt);
10977  if (rc != SQLITE_DONE) {
10978  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10979  sqlite3_errmsg(d->sqlite), rc);
10980  ret = SQL_ERROR;
10981  goto ustmterr;
10982  }
10983  if (sqlite3_changes(d->sqlite) > 0) {
10984  if (s->row_status0) {
10985  s->row_status0[row] = SQL_ROW_UPDATED;
10986  }
10987  if (s->row_status) {
10988  s->row_status[row] = SQL_ROW_UPDATED;
10989  }
10990  }
10991  dbtraceapi(d, "sqlite3_reset", NULL);
10992  sqlite3_reset(s3stmt);
10993  }
10994  dbtraceapi(d, "sqlite3_finalize", NULL);
10995  sqlite3_finalize(s3stmt);
10996  return SQL_SUCCESS;
10997  }
10998  setstat(s, -1, "unsupported operation", (*s->ov3) ? "HY000" : "S1000");
10999  return SQL_ERROR;
11000 }
11001 
11009 SQLRETURN SQL_API
11010 SQLBulkOperations(SQLHSTMT stmt, SQLSMALLINT oper)
11011 {
11012  SQLRETURN ret;
11013 
11014  HSTMT_LOCK(stmt);
11015  ret = drvbulkoperations(stmt, oper);
11016  HSTMT_UNLOCK(stmt);
11017  return ret;
11018 }
11019 
11020 
11025 SQLRETURN SQL_API
11026 SQLSetScrollOptions(SQLHSTMT stmt, SQLUSMALLINT concur, SQLLEN rowkeyset,
11027  SQLUSMALLINT rowset)
11028 {
11029  SQLRETURN ret;
11030 
11031  HSTMT_LOCK(stmt);
11032  ret = drvunimplstmt(stmt);
11033  HSTMT_UNLOCK(stmt);
11034  return ret;
11035 }
11036 
11037 #define strmak(dst, src, max, lenp) { \
11038  int len = strlen(src); \
11039  int cnt = min(len + 1, max); \
11040  strncpy(dst, src, cnt); \
11041  *lenp = (cnt > len) ? len : cnt; \
11042 }
11043 
11054 static SQLRETURN
11055 drvgetinfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11056  SQLSMALLINT *valLen)
11057 {
11058  DBC *d;
11059  char dummyc[301];
11060  SQLSMALLINT dummy;
11061 #if defined(_WIN32) || defined(_WIN64)
11062  char pathbuf[301], *drvname;
11063 #else
11064  static char drvname[] = "sqlite3odbc.so";
11065 #endif
11066 
11067  if (dbc == SQL_NULL_HDBC) {
11068  return SQL_INVALID_HANDLE;
11069  }
11070  d = (DBC *) dbc;
11071  if (valMax) {
11072  valMax--;
11073  }
11074  if (!valLen) {
11075  valLen = &dummy;
11076  }
11077  if (!val) {
11078  val = dummyc;
11079  valMax = sizeof (dummyc) - 1;
11080  }
11081  switch (type) {
11082  case SQL_MAX_USER_NAME_LEN:
11083  *((SQLSMALLINT *) val) = 16;
11084  *valLen = sizeof (SQLSMALLINT);
11085  break;
11086  case SQL_USER_NAME:
11087  strmak(val, "", valMax, valLen);
11088  break;
11089  case SQL_DRIVER_ODBC_VER:
11090 #if 0
11091  strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
11092 #else
11093  strmak(val, "03.00", valMax, valLen);
11094 #endif
11095  break;
11096  case SQL_ACTIVE_CONNECTIONS:
11097  case SQL_ACTIVE_STATEMENTS:
11098  *((SQLSMALLINT *) val) = 0;
11099  *valLen = sizeof (SQLSMALLINT);
11100  break;
11101 #ifdef SQL_ASYNC_MODE
11102  case SQL_ASYNC_MODE:
11103  *((SQLUINTEGER *) val) = SQL_AM_NONE;
11104  *valLen = sizeof (SQLUINTEGER);
11105  break;
11106 #endif
11107 #ifdef SQL_CREATE_TABLE
11108  case SQL_CREATE_TABLE:
11109  *((SQLUINTEGER *) val) = SQL_CT_CREATE_TABLE |
11110  SQL_CT_COLUMN_DEFAULT |
11111  SQL_CT_COLUMN_CONSTRAINT |
11112  SQL_CT_CONSTRAINT_NON_DEFERRABLE;
11113  *valLen = sizeof (SQLUINTEGER);
11114  break;
11115 #endif
11116 #ifdef SQL_CREATE_VIEW
11117  case SQL_CREATE_VIEW:
11118  *((SQLUINTEGER *) val) = SQL_CV_CREATE_VIEW;
11119  *valLen = sizeof (SQLUINTEGER);
11120  break;
11121 #endif
11122 #ifdef SQL_DDL_INDEX
11123  case SQL_DDL_INDEX:
11124  *((SQLUINTEGER *) val) = SQL_DI_CREATE_INDEX | SQL_DI_DROP_INDEX;
11125  *valLen = sizeof (SQLUINTEGER);
11126  break;
11127 #endif
11128 #ifdef SQL_DROP_TABLE
11129  case SQL_DROP_TABLE:
11130  *((SQLUINTEGER *) val) = SQL_DT_DROP_TABLE;
11131  *valLen = sizeof (SQLUINTEGER);
11132  break;
11133 #endif
11134 #ifdef SQL_DROP_VIEW
11135  case SQL_DROP_VIEW:
11136  *((SQLUINTEGER *) val) = SQL_DV_DROP_VIEW;
11137  *valLen = sizeof (SQLUINTEGER);
11138  break;
11139 #endif
11140 #ifdef SQL_INDEX_KEYWORDS
11141  case SQL_INDEX_KEYWORDS:
11142  *((SQLUINTEGER *) val) = SQL_IK_ALL;
11143  *valLen = sizeof (SQLUINTEGER);
11144  break;
11145 #endif
11146  case SQL_DATA_SOURCE_NAME:
11147  strmak(val, d->dsn ? d->dsn : "", valMax, valLen);
11148  break;
11149  case SQL_DRIVER_NAME:
11150 #if defined(_WIN32) || defined(_WIN64)
11151  GetModuleFileName(hModule, pathbuf, sizeof (pathbuf));
11152  drvname = strrchr(pathbuf, '\\');
11153  if (drvname == NULL) {
11154  drvname = strrchr(pathbuf, '/');
11155  }
11156  if (drvname == NULL) {
11157  drvname = pathbuf;
11158  } else {
11159  drvname++;
11160  }
11161 #endif
11162  strmak(val, drvname, valMax, valLen);
11163  break;
11164  case SQL_DRIVER_VER:
11165  strmak(val, DRIVER_VER_INFO, valMax, valLen);
11166  break;
11167  case SQL_FETCH_DIRECTION:
11168  *((SQLUINTEGER *) val) = SQL_FD_FETCH_NEXT | SQL_FD_FETCH_FIRST |
11169  SQL_FD_FETCH_LAST | SQL_FD_FETCH_PRIOR | SQL_FD_FETCH_ABSOLUTE;
11170  *valLen = sizeof (SQLUINTEGER);
11171  break;
11172  case SQL_ODBC_VER:
11173  strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
11174  break;
11175  case SQL_ODBC_SAG_CLI_CONFORMANCE:
11176  *((SQLSMALLINT *) val) = SQL_OSCC_NOT_COMPLIANT;
11177  *valLen = sizeof (SQLSMALLINT);
11178  break;
11179  case SQL_STANDARD_CLI_CONFORMANCE:
11180  *((SQLUINTEGER *) val) = SQL_SCC_XOPEN_CLI_VERSION1;
11181  *valLen = sizeof (SQLUINTEGER);
11182  break;
11183  case SQL_SQL_CONFORMANCE:
11184  *((SQLUINTEGER *) val) = SQL_SC_SQL92_ENTRY;
11185  *valLen = sizeof (SQLUINTEGER);
11186  break;
11187  case SQL_SERVER_NAME:
11188  case SQL_DATABASE_NAME:
11189  strmak(val, d->dbname ? d->dbname : "", valMax, valLen);
11190  break;
11191  case SQL_SEARCH_PATTERN_ESCAPE:
11192  strmak(val, "\\", valMax, valLen);
11193  break;
11194  case SQL_ODBC_SQL_CONFORMANCE:
11195  *((SQLSMALLINT *) val) = SQL_OSC_MINIMUM;
11196  *valLen = sizeof (SQLSMALLINT);
11197  break;
11198  case SQL_ODBC_API_CONFORMANCE:
11199  *((SQLSMALLINT *) val) = SQL_OAC_LEVEL1;
11200  *valLen = sizeof (SQLSMALLINT);
11201  break;
11202  case SQL_DBMS_NAME:
11203  strmak(val, "SQLite", valMax, valLen);
11204  break;
11205  case SQL_DBMS_VER:
11206  strmak(val, SQLITE_VERSION, valMax, valLen);
11207  break;
11208  case SQL_COLUMN_ALIAS:
11209  case SQL_NEED_LONG_DATA_LEN:
11210  case SQL_OUTER_JOINS:
11211  strmak(val, "Y", valMax, valLen);
11212  break;
11213  case SQL_ROW_UPDATES:
11214  case SQL_ACCESSIBLE_PROCEDURES:
11215  case SQL_PROCEDURES:
11216  case SQL_EXPRESSIONS_IN_ORDERBY:
11217  case SQL_ODBC_SQL_OPT_IEF:
11218  case SQL_LIKE_ESCAPE_CLAUSE:
11219  case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11220  case SQL_ACCESSIBLE_TABLES:
11221  case SQL_MULT_RESULT_SETS:
11222  case SQL_MULTIPLE_ACTIVE_TXN:
11223  case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11224  strmak(val, "N", valMax, valLen);
11225  break;
11226 #ifdef SQL_CATALOG_NAME
11227  case SQL_CATALOG_NAME:
11228 #if defined(_WIN32) || defined(_WIN64)
11229  strmak(val, d->xcelqrx ? "Y" : "N", valMax, valLen);
11230 #else
11231  strmak(val, "N", valMax, valLen);
11232 #endif
11233  break;
11234 #endif
11235  case SQL_DATA_SOURCE_READ_ONLY:
11236  strmak(val, "N", valMax, valLen);
11237  break;
11238 #ifdef SQL_OJ_CAPABILITIES
11239  case SQL_OJ_CAPABILITIES:
11240  *((SQLUINTEGER *) val) = SQL_OJ_LEFT;
11241  *valLen = sizeof (SQLUINTEGER);
11242  break;
11243 #endif
11244 #ifdef SQL_MAX_IDENTIFIER_LEN
11245  case SQL_MAX_IDENTIFIER_LEN:
11246  *((SQLUSMALLINT *) val) = 255;
11247  *valLen = sizeof (SQLUSMALLINT);
11248  break;
11249 #endif
11250  case SQL_CONCAT_NULL_BEHAVIOR:
11251  *((SQLSMALLINT *) val) = SQL_CB_NULL;
11252  *valLen = sizeof (SQLSMALLINT);
11253  break;
11254  case SQL_CURSOR_COMMIT_BEHAVIOR:
11255  case SQL_CURSOR_ROLLBACK_BEHAVIOR:
11256  *((SQLSMALLINT *) val) = SQL_CB_PRESERVE;
11257  *valLen = sizeof (SQLSMALLINT);
11258  break;
11259 #ifdef SQL_CURSOR_SENSITIVITY
11260  case SQL_CURSOR_SENSITIVITY:
11261  *((SQLUINTEGER *) val) = SQL_UNSPECIFIED;
11262  *valLen = sizeof (SQLUINTEGER);
11263  break;
11264 #endif
11265  case SQL_DEFAULT_TXN_ISOLATION:
11266  *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11267  *valLen = sizeof (SQLUINTEGER);
11268  break;
11269 #ifdef SQL_DESCRIBE_PARAMETER
11270  case SQL_DESCRIBE_PARAMETER:
11271  strmak(val, "Y", valMax, valLen);
11272  break;
11273 #endif
11274  case SQL_TXN_ISOLATION_OPTION:
11275  *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11276  *valLen = sizeof (SQLUINTEGER);
11277  break;
11278  case SQL_IDENTIFIER_CASE:
11279  *((SQLSMALLINT *) val) = SQL_IC_SENSITIVE;
11280  *valLen = sizeof (SQLSMALLINT);
11281  break;
11282  case SQL_IDENTIFIER_QUOTE_CHAR:
11283  strmak(val, "\"", valMax, valLen);
11284  break;
11285  case SQL_MAX_TABLE_NAME_LEN:
11286  case SQL_MAX_COLUMN_NAME_LEN:
11287  *((SQLSMALLINT *) val) = 255;
11288  *valLen = sizeof (SQLSMALLINT);
11289  break;
11290  case SQL_MAX_CURSOR_NAME_LEN:
11291  *((SQLSMALLINT *) val) = 255;
11292  *valLen = sizeof (SQLSMALLINT);
11293  break;
11294  case SQL_MAX_PROCEDURE_NAME_LEN:
11295  *((SQLSMALLINT *) val) = 0;
11296  break;
11297  case SQL_MAX_QUALIFIER_NAME_LEN:
11298  case SQL_MAX_OWNER_NAME_LEN:
11299  *((SQLSMALLINT *) val) = 255;
11300  break;
11301  case SQL_OWNER_TERM:
11302  strmak(val, "", valMax, valLen);
11303  break;
11304  case SQL_PROCEDURE_TERM:
11305  strmak(val, "PROCEDURE", valMax, valLen);
11306  break;
11307  case SQL_QUALIFIER_NAME_SEPARATOR:
11308  strmak(val, ".", valMax, valLen);
11309  break;
11310  case SQL_QUALIFIER_TERM:
11311 #if defined(_WIN32) || defined(_WIN64)
11312  strmak(val, d->xcelqrx ? "catalog" : "", valMax, valLen);
11313 #else
11314  strmak(val, "", valMax, valLen);
11315 #endif
11316  break;
11317  case SQL_QUALIFIER_USAGE:
11318 #if defined(_WIN32) || defined(_WIN64)
11319  *((SQLUINTEGER *) val) = d->xcelqrx ?
11320  (SQL_CU_DML_STATEMENTS | SQL_CU_INDEX_DEFINITION |
11321  SQL_CU_TABLE_DEFINITION) : 0;
11322 #else
11323  *((SQLUINTEGER *) val) = 0;
11324 #endif
11325  *valLen = sizeof (SQLUINTEGER);
11326  break;
11327  case SQL_SCROLL_CONCURRENCY:
11328  *((SQLUINTEGER *) val) = SQL_SCCO_LOCK;
11329  *valLen = sizeof (SQLUINTEGER);
11330  break;
11331  case SQL_SCROLL_OPTIONS:
11332  *((SQLUINTEGER *) val) = SQL_SO_STATIC | SQL_SO_FORWARD_ONLY;
11333  *valLen = sizeof (SQLUINTEGER);
11334  break;
11335  case SQL_TABLE_TERM:
11336  strmak(val, "TABLE", valMax, valLen);
11337  break;
11338  case SQL_TXN_CAPABLE:
11339  *((SQLSMALLINT *) val) = SQL_TC_ALL;
11340  *valLen = sizeof (SQLSMALLINT);
11341  break;
11342  case SQL_CONVERT_FUNCTIONS:
11343  *((SQLUINTEGER *) val) = 0;
11344  *valLen = sizeof (SQLUINTEGER);
11345  break;
11346  case SQL_SYSTEM_FUNCTIONS:
11347  case SQL_NUMERIC_FUNCTIONS:
11348  case SQL_STRING_FUNCTIONS:
11349  case SQL_TIMEDATE_FUNCTIONS:
11350  *((SQLUINTEGER *) val) = 0;
11351  *valLen = sizeof (SQLUINTEGER);
11352  break;
11353  case SQL_CONVERT_BIGINT:
11354  case SQL_CONVERT_BIT:
11355  case SQL_CONVERT_CHAR:
11356  case SQL_CONVERT_DATE:
11357  case SQL_CONVERT_DECIMAL:
11358  case SQL_CONVERT_DOUBLE:
11359  case SQL_CONVERT_FLOAT:
11360  case SQL_CONVERT_INTEGER:
11361  case SQL_CONVERT_LONGVARCHAR:
11362  case SQL_CONVERT_NUMERIC:
11363  case SQL_CONVERT_REAL:
11364  case SQL_CONVERT_SMALLINT:
11365  case SQL_CONVERT_TIME:
11366  case SQL_CONVERT_TIMESTAMP:
11367  case SQL_CONVERT_TINYINT:
11368  case SQL_CONVERT_VARCHAR:
11369  *((SQLUINTEGER *) val) =
11370  SQL_CVT_CHAR | SQL_CVT_NUMERIC | SQL_CVT_DECIMAL |
11371  SQL_CVT_INTEGER | SQL_CVT_SMALLINT | SQL_CVT_FLOAT | SQL_CVT_REAL |
11372  SQL_CVT_DOUBLE | SQL_CVT_VARCHAR | SQL_CVT_LONGVARCHAR |
11373  SQL_CVT_BIT | SQL_CVT_TINYINT | SQL_CVT_BIGINT |
11374  SQL_CVT_DATE | SQL_CVT_TIME | SQL_CVT_TIMESTAMP;
11375  *valLen = sizeof (SQLUINTEGER);
11376  break;
11377  case SQL_CONVERT_BINARY:
11378  case SQL_CONVERT_VARBINARY:
11379  case SQL_CONVERT_LONGVARBINARY:
11380  *((SQLUINTEGER *) val) = 0;
11381  *valLen = sizeof (SQLUINTEGER);
11382  break;
11383  case SQL_POSITIONED_STATEMENTS:
11384  *((SQLUINTEGER *) val) = 0;
11385  *valLen = sizeof (SQLUINTEGER);
11386  break;
11387  case SQL_LOCK_TYPES:
11388  *((SQLUINTEGER *) val) = SQL_LCK_NO_CHANGE;
11389  *valLen = sizeof (SQLUINTEGER);
11390  break;
11391  case SQL_BOOKMARK_PERSISTENCE:
11392  *((SQLUINTEGER *) val) = SQL_BP_SCROLL;
11393  *valLen = sizeof (SQLUINTEGER);
11394  break;
11395  case SQL_UNION:
11396  *((SQLUINTEGER *) val) = SQL_U_UNION | SQL_U_UNION_ALL;
11397  *valLen = sizeof (SQLUINTEGER);
11398  break;
11399  case SQL_OWNER_USAGE:
11400  case SQL_SUBQUERIES:
11401  case SQL_TIMEDATE_ADD_INTERVALS:
11402  case SQL_TIMEDATE_DIFF_INTERVALS:
11403  *((SQLUINTEGER *) val) = 0;
11404  *valLen = sizeof (SQLUINTEGER);
11405  break;
11406  case SQL_QUOTED_IDENTIFIER_CASE:
11407  *((SQLUSMALLINT *) val) = SQL_IC_SENSITIVE;
11408  *valLen = sizeof (SQLUSMALLINT);
11409  break;
11410  case SQL_POS_OPERATIONS:
11411  *((SQLUINTEGER *) val) = SQL_POS_POSITION | SQL_POS_UPDATE |
11412  SQL_POS_DELETE | SQL_POS_ADD | SQL_POS_REFRESH;
11413  *valLen = sizeof (SQLUINTEGER);
11414  break;
11415  case SQL_ALTER_TABLE:
11416  *((SQLUINTEGER *) val) = 0;
11417  *valLen = sizeof (SQLUINTEGER);
11418  break;
11419  case SQL_CORRELATION_NAME:
11420  *((SQLSMALLINT *) val) = SQL_CN_DIFFERENT;
11421  *valLen = sizeof (SQLSMALLINT);
11422  break;
11423  case SQL_NON_NULLABLE_COLUMNS:
11424  *((SQLSMALLINT *) val) = SQL_NNC_NON_NULL;
11425  *valLen = sizeof (SQLSMALLINT);
11426  break;
11427  case SQL_NULL_COLLATION:
11428  *((SQLSMALLINT *) val) = SQL_NC_START;
11429  *valLen = sizeof (SQLSMALLINT);
11430  break;
11431  case SQL_MAX_COLUMNS_IN_GROUP_BY:
11432  case SQL_MAX_COLUMNS_IN_ORDER_BY:
11433  case SQL_MAX_COLUMNS_IN_SELECT:
11434  case SQL_MAX_COLUMNS_IN_TABLE:
11435  case SQL_MAX_ROW_SIZE:
11436  case SQL_MAX_TABLES_IN_SELECT:
11437  *((SQLSMALLINT *) val) = 0;
11438  *valLen = sizeof (SQLSMALLINT);
11439  break;
11440  case SQL_MAX_BINARY_LITERAL_LEN:
11441  case SQL_MAX_CHAR_LITERAL_LEN:
11442  *((SQLUINTEGER *) val) = 0;
11443  *valLen = sizeof (SQLUINTEGER);
11444  break;
11445  case SQL_MAX_COLUMNS_IN_INDEX:
11446  *((SQLSMALLINT *) val) = 0;
11447  *valLen = sizeof (SQLSMALLINT);
11448  break;
11449  case SQL_MAX_INDEX_SIZE:
11450  *((SQLUINTEGER *) val) = 0;
11451  *valLen = sizeof (SQLUINTEGER);
11452  break;
11453 #ifdef SQL_MAX_IDENTIFIER_LENGTH
11454  case SQL_MAX_IDENTIFIER_LENGTH:
11455  *((SQLUINTEGER *) val) = 255;
11456  *valLen = sizeof (SQLUINTEGER);
11457  break;
11458 #endif
11459  case SQL_MAX_STATEMENT_LEN:
11460  *((SQLUINTEGER *) val) = 16384;
11461  *valLen = sizeof (SQLUINTEGER);
11462  break;
11463  case SQL_QUALIFIER_LOCATION:
11464  *((SQLSMALLINT *) val) = SQL_QL_START;
11465  *valLen = sizeof (SQLSMALLINT);
11466  break;
11467  case SQL_GETDATA_EXTENSIONS:
11468  *((SQLUINTEGER *) val) =
11469  SQL_GD_ANY_COLUMN | SQL_GD_ANY_ORDER | SQL_GD_BOUND;
11470  *valLen = sizeof (SQLUINTEGER);
11471  break;
11472  case SQL_STATIC_SENSITIVITY:
11473  *((SQLUINTEGER *) val) = 0;
11474  *valLen = sizeof (SQLUINTEGER);
11475  break;
11476  case SQL_FILE_USAGE:
11477 #if defined(_WIN32) || defined(_WIN64)
11478  *((SQLSMALLINT *) val) =
11479  d->xcelqrx ? SQL_FILE_CATALOG : SQL_FILE_NOT_SUPPORTED;
11480 #else
11481  *((SQLSMALLINT *) val) = SQL_FILE_NOT_SUPPORTED;
11482 #endif
11483  *valLen = sizeof (SQLSMALLINT);
11484  break;
11485  case SQL_GROUP_BY:
11486  *((SQLSMALLINT *) val) = SQL_GB_GROUP_BY_EQUALS_SELECT;
11487  *valLen = sizeof (SQLSMALLINT);
11488  break;
11489  case SQL_KEYWORDS:
11490  strmak(val, "CREATE,SELECT,DROP,DELETE,UPDATE,INSERT,"
11491  "INTO,VALUES,TABLE,INDEX,FROM,SET,WHERE,AND,CURRENT,OF",
11492  valMax, valLen);
11493  break;
11494  case SQL_SPECIAL_CHARACTERS:
11495 #ifdef SQL_COLLATION_SEQ
11496  case SQL_COLLATION_SEQ:
11497 #endif
11498  strmak(val, "", valMax, valLen);
11499  break;
11500  case SQL_BATCH_SUPPORT:
11501  case SQL_BATCH_ROW_COUNT:
11502  case SQL_PARAM_ARRAY_ROW_COUNTS:
11503  *((SQLUINTEGER *) val) = 0;
11504  *valLen = sizeof (SQLUINTEGER);
11505  break;
11506  case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1:
11507  *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_BOOKMARK;
11508  *valLen = sizeof (SQLUINTEGER);
11509  break;
11510  case SQL_STATIC_CURSOR_ATTRIBUTES1:
11511  *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE |
11512  SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK | SQL_CA1_POS_POSITION |
11513  SQL_CA1_POS_DELETE | SQL_CA1_POS_UPDATE | SQL_CA1_POS_REFRESH |
11514  SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_BULK_ADD |
11515  SQL_CA1_BULK_UPDATE_BY_BOOKMARK | SQL_CA1_BULK_DELETE_BY_BOOKMARK;
11516  *valLen = sizeof (SQLUINTEGER);
11517  break;
11518  case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2:
11519  case SQL_STATIC_CURSOR_ATTRIBUTES2:
11520  *((SQLUINTEGER *) val) = SQL_CA2_READ_ONLY_CONCURRENCY |
11521  SQL_CA2_LOCK_CONCURRENCY;
11522  *valLen = sizeof (SQLUINTEGER);
11523  break;
11524  case SQL_KEYSET_CURSOR_ATTRIBUTES1:
11525  case SQL_KEYSET_CURSOR_ATTRIBUTES2:
11526  case SQL_DYNAMIC_CURSOR_ATTRIBUTES1:
11527  case SQL_DYNAMIC_CURSOR_ATTRIBUTES2:
11528  *((SQLUINTEGER *) val) = 0;
11529  *valLen = sizeof (SQLUINTEGER);
11530  break;
11531  case SQL_ODBC_INTERFACE_CONFORMANCE:
11532  *((SQLUINTEGER *) val) = SQL_OIC_CORE;
11533  *valLen = sizeof (SQLUINTEGER);
11534  break;
11535  default:
11536  setstatd(d, -1, "unsupported info option %d",
11537  (*d->ov3) ? "HYC00" : "S1C00", type);
11538  return SQL_ERROR;
11539  }
11540  return SQL_SUCCESS;
11541 }
11542 
11543 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
11544 
11554 SQLRETURN SQL_API
11555 SQLGetInfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11556  SQLSMALLINT *valLen)
11557 {
11558  SQLRETURN ret;
11559 
11560  HDBC_LOCK(dbc);
11561  ret = drvgetinfo(dbc, type, val, valMax, valLen);
11562  HDBC_UNLOCK(dbc);
11563  return ret;
11564 }
11565 #endif
11566 
11567 #ifdef WINTERFACE
11568 
11578 SQLRETURN SQL_API
11579 SQLGetInfoW(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11580  SQLSMALLINT *valLen)
11581 {
11582  SQLRETURN ret;
11583  SQLSMALLINT len = 0;
11584 
11585  HDBC_LOCK(dbc);
11586  ret = drvgetinfo(dbc, type, val, valMax, &len);
11587  HDBC_UNLOCK(dbc);
11588  if (ret == SQL_SUCCESS) {
11589  SQLWCHAR *v = NULL;
11590 
11591  switch (type) {
11592  case SQL_USER_NAME:
11593  case SQL_DRIVER_ODBC_VER:
11594  case SQL_DATA_SOURCE_NAME:
11595  case SQL_DRIVER_NAME:
11596  case SQL_DRIVER_VER:
11597  case SQL_ODBC_VER:
11598  case SQL_SERVER_NAME:
11599  case SQL_DATABASE_NAME:
11600  case SQL_SEARCH_PATTERN_ESCAPE:
11601  case SQL_DBMS_NAME:
11602  case SQL_DBMS_VER:
11603  case SQL_NEED_LONG_DATA_LEN:
11604  case SQL_ROW_UPDATES:
11605  case SQL_ACCESSIBLE_PROCEDURES:
11606  case SQL_PROCEDURES:
11607  case SQL_EXPRESSIONS_IN_ORDERBY:
11608  case SQL_ODBC_SQL_OPT_IEF:
11609  case SQL_LIKE_ESCAPE_CLAUSE:
11610  case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11611  case SQL_OUTER_JOINS:
11612  case SQL_COLUMN_ALIAS:
11613  case SQL_ACCESSIBLE_TABLES:
11614  case SQL_MULT_RESULT_SETS:
11615  case SQL_MULTIPLE_ACTIVE_TXN:
11616  case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11617  case SQL_DATA_SOURCE_READ_ONLY:
11618 #ifdef SQL_DESCRIBE_PARAMETER
11619  case SQL_DESCRIBE_PARAMETER:
11620 #endif
11621  case SQL_IDENTIFIER_QUOTE_CHAR:
11622  case SQL_OWNER_TERM:
11623  case SQL_PROCEDURE_TERM:
11624  case SQL_QUALIFIER_NAME_SEPARATOR:
11625  case SQL_QUALIFIER_TERM:
11626  case SQL_TABLE_TERM:
11627  case SQL_KEYWORDS:
11628  case SQL_SPECIAL_CHARACTERS:
11629 #ifdef SQL_CATALOG_NAME
11630  case SQL_CATALOG_NAME:
11631 #endif
11632 #ifdef SQL_COLLATION_SEQ
11633  case SQL_COLLATION_SEQ:
11634 #endif
11635  if (val) {
11636  if (len > 0) {
11637  v = uc_from_utf((SQLCHAR *) val, len);
11638  if (v) {
11639  int vmax = valMax / sizeof (SQLWCHAR);
11640 
11641  uc_strncpy(val, v, vmax);
11642  if (len < vmax) {
11643  len = min(vmax, uc_strlen(v));
11644  v[len] = 0;
11645  } else {
11646  len = vmax;
11647  }
11648  uc_free(v);
11649  len *= sizeof (SQLWCHAR);
11650  } else {
11651  len = 0;
11652  }
11653  }
11654  if (len <= 0) {
11655  len = 0;
11656  if (valMax >= sizeof (SQLWCHAR)) {
11657  *((SQLWCHAR *)val) = 0;
11658  }
11659  }
11660  } else {
11661  len *= sizeof (SQLWCHAR);
11662  }
11663  break;
11664  }
11665  if (valLen) {
11666  *valLen = len;
11667  }
11668  }
11669  return ret;
11670 }
11671 #endif
11672 
11681 SQLRETURN SQL_API
11682 SQLGetFunctions(SQLHDBC dbc, SQLUSMALLINT func,
11683  SQLUSMALLINT *flags)
11684 {
11685  int i;
11686  SQLUSMALLINT exists[100];
11687 
11688  if (dbc == SQL_NULL_HDBC) {
11689  return SQL_INVALID_HANDLE;
11690  }
11691  for (i = 0; i < array_size(exists); i++) {
11692  exists[i] = SQL_FALSE;
11693  }
11694  exists[SQL_API_SQLALLOCCONNECT] = SQL_TRUE;
11695  exists[SQL_API_SQLFETCH] = SQL_TRUE;
11696  exists[SQL_API_SQLALLOCENV] = SQL_TRUE;
11697  exists[SQL_API_SQLFREECONNECT] = SQL_TRUE;
11698  exists[SQL_API_SQLALLOCSTMT] = SQL_TRUE;
11699  exists[SQL_API_SQLFREEENV] = SQL_TRUE;
11700  exists[SQL_API_SQLBINDCOL] = SQL_TRUE;
11701  exists[SQL_API_SQLFREESTMT] = SQL_TRUE;
11702  exists[SQL_API_SQLCANCEL] = SQL_TRUE;
11703  exists[SQL_API_SQLGETCURSORNAME] = SQL_TRUE;
11704  exists[SQL_API_SQLCOLATTRIBUTES] = SQL_TRUE;
11705  exists[SQL_API_SQLNUMRESULTCOLS] = SQL_TRUE;
11706  exists[SQL_API_SQLCONNECT] = SQL_TRUE;
11707  exists[SQL_API_SQLPREPARE] = SQL_TRUE;
11708  exists[SQL_API_SQLDESCRIBECOL] = SQL_TRUE;
11709  exists[SQL_API_SQLROWCOUNT] = SQL_TRUE;
11710  exists[SQL_API_SQLDISCONNECT] = SQL_TRUE;
11711  exists[SQL_API_SQLSETCURSORNAME] = SQL_FALSE;
11712  exists[SQL_API_SQLERROR] = SQL_TRUE;
11713  exists[SQL_API_SQLSETPARAM] = SQL_TRUE;
11714  exists[SQL_API_SQLEXECDIRECT] = SQL_TRUE;
11715  exists[SQL_API_SQLTRANSACT] = SQL_TRUE;
11716  exists[SQL_API_SQLBULKOPERATIONS] = SQL_TRUE;
11717  exists[SQL_API_SQLEXECUTE] = SQL_TRUE;
11718  exists[SQL_API_SQLBINDPARAMETER] = SQL_TRUE;
11719  exists[SQL_API_SQLGETTYPEINFO] = SQL_TRUE;
11720  exists[SQL_API_SQLCOLUMNS] = SQL_TRUE;
11721  exists[SQL_API_SQLPARAMDATA] = SQL_TRUE;
11722  exists[SQL_API_SQLDRIVERCONNECT] = SQL_TRUE;
11723  exists[SQL_API_SQLPUTDATA] = SQL_TRUE;
11724  exists[SQL_API_SQLGETCONNECTOPTION] = SQL_TRUE;
11725  exists[SQL_API_SQLSETCONNECTOPTION] = SQL_TRUE;
11726  exists[SQL_API_SQLGETDATA] = SQL_TRUE;
11727  exists[SQL_API_SQLSETSTMTOPTION] = SQL_TRUE;
11728  exists[SQL_API_SQLGETFUNCTIONS] = SQL_TRUE;
11729  exists[SQL_API_SQLSPECIALCOLUMNS] = SQL_TRUE;
11730  exists[SQL_API_SQLGETINFO] = SQL_TRUE;
11731  exists[SQL_API_SQLSTATISTICS] = SQL_TRUE;
11732  exists[SQL_API_SQLGETSTMTOPTION] = SQL_TRUE;
11733  exists[SQL_API_SQLTABLES] = SQL_TRUE;
11734  exists[SQL_API_SQLBROWSECONNECT] = SQL_FALSE;
11735  exists[SQL_API_SQLNUMPARAMS] = SQL_TRUE;
11736  exists[SQL_API_SQLCOLUMNPRIVILEGES] = SQL_FALSE;
11737  exists[SQL_API_SQLPARAMOPTIONS] = SQL_FALSE;
11738  exists[SQL_API_SQLDATASOURCES] = SQL_TRUE;
11739  exists[SQL_API_SQLPRIMARYKEYS] = SQL_TRUE;
11740  exists[SQL_API_SQLDESCRIBEPARAM] = SQL_TRUE;
11741  exists[SQL_API_SQLPROCEDURECOLUMNS] = SQL_TRUE;
11742  exists[SQL_API_SQLDRIVERS] = SQL_FALSE;
11743  exists[SQL_API_SQLPROCEDURES] = SQL_TRUE;
11744  exists[SQL_API_SQLEXTENDEDFETCH] = SQL_TRUE;
11745  exists[SQL_API_SQLSETPOS] = SQL_TRUE;
11746  exists[SQL_API_SQLFOREIGNKEYS] = SQL_TRUE;
11747  exists[SQL_API_SQLSETSCROLLOPTIONS] = SQL_TRUE;
11748  exists[SQL_API_SQLMORERESULTS] = SQL_TRUE;
11749  exists[SQL_API_SQLTABLEPRIVILEGES] = SQL_TRUE;
11750  exists[SQL_API_SQLNATIVESQL] = SQL_TRUE;
11751  if (func == SQL_API_ALL_FUNCTIONS) {
11752  memcpy(flags, exists, sizeof (exists));
11753  } else if (func == SQL_API_ODBC3_ALL_FUNCTIONS) {
11754  int i;
11755 #define SET_EXISTS(x) \
11756  flags[(x) >> 4] |= (1 << ((x) & 0xF))
11757 #define CLR_EXISTS(x) \
11758  flags[(x) >> 4] &= ~(1 << ((x) & 0xF))
11759 
11760  memset(flags, 0,
11761  sizeof (SQLUSMALLINT) * SQL_API_ODBC3_ALL_FUNCTIONS_SIZE);
11762  for (i = 0; i < array_size(exists); i++) {
11763  if (exists[i]) {
11764  flags[i >> 4] |= (1 << (i & 0xF));
11765  }
11766  }
11767  SET_EXISTS(SQL_API_SQLALLOCHANDLE);
11768  SET_EXISTS(SQL_API_SQLFREEHANDLE);
11769  SET_EXISTS(SQL_API_SQLGETSTMTATTR);
11770  SET_EXISTS(SQL_API_SQLSETSTMTATTR);
11771  SET_EXISTS(SQL_API_SQLGETCONNECTATTR);
11772  SET_EXISTS(SQL_API_SQLSETCONNECTATTR);
11773  SET_EXISTS(SQL_API_SQLGETENVATTR);
11774  SET_EXISTS(SQL_API_SQLSETENVATTR);
11775  SET_EXISTS(SQL_API_SQLCLOSECURSOR);
11776  SET_EXISTS(SQL_API_SQLBINDPARAM);
11777 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11778  /*
11779  * Some unixODBC versions have problems with
11780  * SQLError() vs. SQLGetDiagRec() with loss
11781  * of error/warning messages.
11782  */
11783  SET_EXISTS(SQL_API_SQLGETDIAGREC);
11784 #endif
11785  SET_EXISTS(SQL_API_SQLGETDIAGFIELD);
11786  SET_EXISTS(SQL_API_SQLFETCHSCROLL);
11787  SET_EXISTS(SQL_API_SQLENDTRAN);
11788  } else {
11789  if (func < array_size(exists)) {
11790  *flags = exists[func];
11791  } else {
11792  switch (func) {
11793  case SQL_API_SQLALLOCHANDLE:
11794  case SQL_API_SQLFREEHANDLE:
11795  case SQL_API_SQLGETSTMTATTR:
11796  case SQL_API_SQLSETSTMTATTR:
11797  case SQL_API_SQLGETCONNECTATTR:
11798  case SQL_API_SQLSETCONNECTATTR:
11799  case SQL_API_SQLGETENVATTR:
11800  case SQL_API_SQLSETENVATTR:
11801  case SQL_API_SQLCLOSECURSOR:
11802  case SQL_API_SQLBINDPARAM:
11803 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11804  /*
11805  * Some unixODBC versions have problems with
11806  * SQLError() vs. SQLGetDiagRec() with loss
11807  * of error/warning messages.
11808  */
11809  case SQL_API_SQLGETDIAGREC:
11810 #endif
11811  case SQL_API_SQLGETDIAGFIELD:
11812  case SQL_API_SQLFETCHSCROLL:
11813  case SQL_API_SQLENDTRAN:
11814  *flags = SQL_TRUE;
11815  break;
11816  default:
11817  *flags = SQL_FALSE;
11818  }
11819  }
11820  }
11821  return SQL_SUCCESS;
11822 }
11823 
11830 static SQLRETURN
11831 drvallocenv(SQLHENV *env)
11832 {
11833  ENV *e;
11834 
11835  if (env == NULL) {
11836  return SQL_INVALID_HANDLE;
11837  }
11838  e = (ENV *) xmalloc(sizeof (ENV));
11839  if (e == NULL) {
11840  *env = SQL_NULL_HENV;
11841  return SQL_ERROR;
11842  }
11843  e->magic = ENV_MAGIC;
11844  e->ov3 = 0;
11845  e->pool = 0;
11846 #if defined(_WIN32) || defined(_WIN64)
11847  InitializeCriticalSection(&e->cs);
11848 #else
11849 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
11850  nvfs_init();
11851 #endif
11852 #endif
11853  e->dbcs = NULL;
11854  *env = (SQLHENV) e;
11855  return SQL_SUCCESS;
11856 }
11857 
11864 SQLRETURN SQL_API
11865 SQLAllocEnv(SQLHENV *env)
11866 {
11867  return drvallocenv(env);
11868 }
11869 
11876 static SQLRETURN
11877 drvfreeenv(SQLHENV env)
11878 {
11879  ENV *e;
11880 
11881  if (env == SQL_NULL_HENV) {
11882  return SQL_INVALID_HANDLE;
11883  }
11884  e = (ENV *) env;
11885  if (e->magic != ENV_MAGIC) {
11886  return SQL_SUCCESS;
11887  }
11888 #if defined(_WIN32) || defined(_WIN64)
11889  EnterCriticalSection(&e->cs);
11890 #endif
11891  if (e->dbcs) {
11892 #if defined(_WIN32) || defined(_WIN64)
11893  LeaveCriticalSection(&e->cs);
11894 #endif
11895  return SQL_ERROR;
11896  }
11897  e->magic = DEAD_MAGIC;
11898 #if defined(_WIN32) || defined(_WIN64)
11899  LeaveCriticalSection(&e->cs);
11900  DeleteCriticalSection(&e->cs);
11901 #endif
11902  xfree(e);
11903  return SQL_SUCCESS;
11904 }
11905 
11912 SQLRETURN SQL_API
11913 SQLFreeEnv(SQLHENV env)
11914 {
11915  return drvfreeenv(env);
11916 }
11917 
11925 static SQLRETURN
11926 drvallocconnect(SQLHENV env, SQLHDBC *dbc)
11927 {
11928  DBC *d;
11929  ENV *e;
11930  const char *verstr;
11931  int maj = 0, min = 0, lev = 0;
11932 
11933  if (dbc == NULL) {
11934  return SQL_ERROR;
11935  }
11936  d = (DBC *) xmalloc(sizeof (DBC));
11937  if (d == NULL) {
11938  *dbc = SQL_NULL_HDBC;
11939  return SQL_ERROR;
11940  }
11941  memset(d, 0, sizeof (DBC));
11942  d->curtype = SQL_CURSOR_STATIC;
11943  d->ov3 = &d->ov3val;
11944  verstr = sqlite3_libversion();
11945  sscanf(verstr, "%d.%d.%d", &maj, &min, &lev);
11946  d->version = verinfo(maj & 0xFF, min & 0xFF, lev & 0xFF);
11947  e = (ENV *) env;
11948 #if defined(_WIN32) || defined(_WIN64)
11949  if (e->magic == ENV_MAGIC) {
11950  EnterCriticalSection(&e->cs);
11951  }
11952 #endif
11953  if (e->magic == ENV_MAGIC) {
11954  DBC *n, *p;
11955 
11956  d->env = e;
11957  d->ov3 = &e->ov3;
11958  p = NULL;
11959  n = e->dbcs;
11960  while (n) {
11961  p = n;
11962  n = n->next;
11963  }
11964  if (p) {
11965  p->next = d;
11966  } else {
11967  e->dbcs = d;
11968  }
11969  }
11970 #if defined(_WIN32) || defined(_WIN64)
11971  InitializeCriticalSection(&d->cs);
11972  d->owner = 0;
11973  if (e->magic == ENV_MAGIC) {
11974  LeaveCriticalSection(&e->cs);
11975  }
11976  d->oemcp = 1;
11977 #endif
11978  d->autocommit = 1;
11979  d->magic = DBC_MAGIC;
11980  *dbc = (SQLHDBC) d;
11981  drvgetgpps(d);
11982  return SQL_SUCCESS;
11983 }
11984 
11992 SQLRETURN SQL_API
11993 SQLAllocConnect(SQLHENV env, SQLHDBC *dbc)
11994 {
11995  return drvallocconnect(env, dbc);
11996 }
11997 
12004 static SQLRETURN
12006 {
12007  DBC *d;
12008  ENV *e;
12009  SQLRETURN ret = SQL_ERROR;
12010 
12011  if (dbc == SQL_NULL_HDBC) {
12012  return SQL_INVALID_HANDLE;
12013  }
12014  d = (DBC *) dbc;
12015  if (d->magic != DBC_MAGIC) {
12016  return SQL_INVALID_HANDLE;
12017  }
12018  e = d->env;
12019  if (e && e->magic == ENV_MAGIC) {
12020 #if defined(_WIN32) || defined(_WIN64)
12021  EnterCriticalSection(&e->cs);
12022 #endif
12023  } else {
12024  e = NULL;
12025  }
12026  HDBC_LOCK(dbc);
12027  if (d->sqlite) {
12028  setstatd(d, -1, "not disconnected", (*d->ov3) ? "HY000" : "S1000");
12029  HDBC_UNLOCK(dbc);
12030  goto done;
12031  }
12032  while (d->stmt) {
12033  freestmt((HSTMT) d->stmt);
12034  }
12035  if (e && e->magic == ENV_MAGIC) {
12036  DBC *n, *p;
12037 
12038  p = NULL;
12039  n = e->dbcs;
12040  while (n) {
12041  if (n == d) {
12042  break;
12043  }
12044  p = n;
12045  n = n->next;
12046  }
12047  if (n) {
12048  if (p) {
12049  p->next = d->next;
12050  } else {
12051  e->dbcs = d->next;
12052  }
12053  }
12054  }
12055  drvrelgpps(d);
12056  d->magic = DEAD_MAGIC;
12057  if (d->trace) {
12058  fclose(d->trace);
12059  }
12060 #if defined(_WIN32) || defined(_WIN64)
12061  d->owner = 0;
12062  LeaveCriticalSection(&d->cs);
12063  DeleteCriticalSection(&d->cs);
12064 #endif
12065  xfree(d);
12066  ret = SQL_SUCCESS;
12067 done:
12068 #if defined(_WIN32) || defined(_WIN64)
12069  if (e) {
12070  LeaveCriticalSection(&e->cs);
12071  }
12072 #endif
12073  return ret;
12074 }
12075 
12082 SQLRETURN SQL_API
12084 {
12085  return drvfreeconnect(dbc);
12086 }
12087 
12098 static SQLRETURN
12099 drvgetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12100  SQLINTEGER bufmax, SQLINTEGER *buflen)
12101 {
12102  DBC *d;
12103  SQLINTEGER dummy;
12104 
12105  if (dbc == SQL_NULL_HDBC) {
12106  return SQL_INVALID_HANDLE;
12107  }
12108  d = (DBC *) dbc;
12109  if (!val) {
12110  val = (SQLPOINTER) &dummy;
12111  }
12112  if (!buflen) {
12113  buflen = &dummy;
12114  }
12115  switch (attr) {
12116  case SQL_ATTR_CONNECTION_DEAD:
12117  *((SQLINTEGER *) val) = d->sqlite ? SQL_CD_FALSE : SQL_CD_TRUE;
12118  *buflen = sizeof (SQLINTEGER);
12119  break;
12120  case SQL_ATTR_ACCESS_MODE:
12121  *((SQLINTEGER *) val) = SQL_MODE_READ_WRITE;
12122  *buflen = sizeof (SQLINTEGER);
12123  break;
12124  case SQL_ATTR_AUTOCOMMIT:
12125  *((SQLINTEGER *) val) =
12126  d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
12127  *buflen = sizeof (SQLINTEGER);
12128  break;
12129  case SQL_ATTR_LOGIN_TIMEOUT:
12130  *((SQLINTEGER *) val) = 100;
12131  *buflen = sizeof (SQLINTEGER);
12132  break;
12133  case SQL_ATTR_ODBC_CURSORS:
12134  *((SQLINTEGER *) val) = SQL_CUR_USE_DRIVER;
12135  *buflen = sizeof (SQLINTEGER);
12136  break;
12137  case SQL_ATTR_PACKET_SIZE:
12138  *((SQLINTEGER *) val) = 16384;
12139  *buflen = sizeof (SQLINTEGER);
12140  break;
12141  case SQL_ATTR_TXN_ISOLATION:
12142  *((SQLINTEGER *) val) = SQL_TXN_SERIALIZABLE;
12143  *buflen = sizeof (SQLINTEGER);
12144  break;
12145  case SQL_ATTR_TRACEFILE:
12146  case SQL_ATTR_TRANSLATE_LIB:
12147  *((SQLCHAR *) val) = 0;
12148  *buflen = 0;
12149  break;
12150  case SQL_ATTR_CURRENT_CATALOG:
12151 #if defined(_WIN32) || defined(_WIN64)
12152  if (d->xcelqrx) {
12153  if ((bufmax > 4) && (val != (SQLPOINTER) &dummy)) {
12154  strcpy((char *) val, "main");
12155  *buflen = 4;
12156  break;
12157  }
12158  }
12159 #endif
12160  *((SQLCHAR *) val) = 0;
12161  *buflen = 0;
12162  break;
12163  case SQL_ATTR_TRACE:
12164  case SQL_ATTR_QUIET_MODE:
12165  case SQL_ATTR_TRANSLATE_OPTION:
12166  case SQL_ATTR_KEYSET_SIZE:
12167  case SQL_ATTR_QUERY_TIMEOUT:
12168  *((SQLINTEGER *) val) = 0;
12169  *buflen = sizeof (SQLINTEGER);
12170  break;
12171  case SQL_ATTR_PARAM_BIND_TYPE:
12172  *((SQLULEN *) val) = SQL_PARAM_BIND_BY_COLUMN;
12173  *buflen = sizeof (SQLUINTEGER);
12174  break;
12175  case SQL_ATTR_ROW_BIND_TYPE:
12176  *((SQLULEN *) val) = SQL_BIND_BY_COLUMN;
12177  *buflen = sizeof (SQLULEN);
12178  break;
12179  case SQL_ATTR_USE_BOOKMARKS:
12180  *((SQLINTEGER *) val) = SQL_UB_OFF;
12181  *buflen = sizeof (SQLINTEGER);
12182  break;
12183  case SQL_ATTR_ASYNC_ENABLE:
12184  *((SQLINTEGER *) val) = SQL_ASYNC_ENABLE_OFF;
12185  *buflen = sizeof (SQLINTEGER);
12186  break;
12187  case SQL_ATTR_NOSCAN:
12188  *((SQLINTEGER *) val) = SQL_NOSCAN_ON;
12189  *buflen = sizeof (SQLINTEGER);
12190  break;
12191  case SQL_ATTR_CONCURRENCY:
12192  *((SQLINTEGER *) val) = SQL_CONCUR_LOCK;
12193  *buflen = sizeof (SQLINTEGER);
12194  break;
12195 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
12196  case SQL_ATTR_CURSOR_SENSITIVITY:
12197  *((SQLINTEGER *) val) = SQL_UNSPECIFIED;
12198  *buflen = sizeof (SQLINTEGER);
12199  break;
12200 #endif
12201  case SQL_ATTR_SIMULATE_CURSOR:
12202  *((SQLINTEGER *) val) = SQL_SC_NON_UNIQUE;
12203  *buflen = sizeof (SQLINTEGER);
12204  break;
12205  case SQL_ATTR_MAX_ROWS:
12206  *((SQLINTEGER *) val) = 0;
12207  *buflen = sizeof (SQLINTEGER);
12208  case SQL_ATTR_MAX_LENGTH:
12209  *((SQLINTEGER *) val) = 1000000000;
12210  *buflen = sizeof (SQLINTEGER);
12211  break;
12212  case SQL_ATTR_CURSOR_TYPE:
12213  *((SQLINTEGER *) val) = d->curtype;
12214  *buflen = sizeof (SQLINTEGER);
12215  break;
12216  case SQL_ATTR_RETRIEVE_DATA:
12217  *((SQLINTEGER *) val) = SQL_RD_ON;
12218  *buflen = sizeof (SQLINTEGER);
12219  break;
12220 #ifdef SQL_ATTR_METADATA_ID
12221  case SQL_ATTR_METADATA_ID:
12222  *((SQLULEN *) val) = SQL_FALSE;
12223  return SQL_SUCCESS;
12224 #endif
12225  default:
12226  *((SQLINTEGER *) val) = 0;
12227  *buflen = sizeof (SQLINTEGER);
12228  setstatd(d, -1, "unsupported connect attribute %d",
12229  (*d->ov3) ? "HYC00" : "S1C00", (int) attr);
12230  return SQL_ERROR;
12231  }
12232  return SQL_SUCCESS;
12233 }
12234 
12235 #ifndef WINTERFACE
12236 
12246 SQLRETURN SQL_API
12247 SQLGetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12248  SQLINTEGER bufmax, SQLINTEGER *buflen)
12249 {
12250  SQLRETURN ret;
12251 
12252  HDBC_LOCK(dbc);
12253  ret = drvgetconnectattr(dbc, attr, val, bufmax, buflen);
12254  HDBC_UNLOCK(dbc);
12255  return ret;
12256 }
12257 #endif
12258 
12259 #ifdef WINTERFACE
12260 
12270 SQLRETURN SQL_API
12271 SQLGetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12272  SQLINTEGER bufmax, SQLINTEGER *buflen)
12273 {
12274  SQLRETURN ret;
12275  SQLINTEGER len = 0;
12276 
12277  HDBC_LOCK(dbc);
12278  ret = drvgetconnectattr(dbc, attr, val, bufmax, &len);
12279  if (ret == SQL_SUCCESS) {
12280  SQLWCHAR *v = NULL;
12281 
12282  switch (attr) {
12283  case SQL_ATTR_TRACEFILE:
12284  case SQL_ATTR_CURRENT_CATALOG:
12285  case SQL_ATTR_TRANSLATE_LIB:
12286  if (val) {
12287  if (len > 0) {
12288  v = uc_from_utf((SQLCHAR *) val, len);
12289  if (v) {
12290  int vmax = bufmax / sizeof (SQLWCHAR);
12291 
12292  uc_strncpy(val, v, vmax);
12293  if (len < vmax) {
12294  len = min(vmax, uc_strlen(v));
12295  v[len] = 0;
12296  } else {
12297  len = vmax;
12298  }
12299  uc_free(v);
12300  len *= sizeof (SQLWCHAR);
12301  } else {
12302  len = 0;
12303  }
12304  }
12305  if (len <= 0) {
12306  len = 0;
12307  if (bufmax >= sizeof (SQLWCHAR)) {
12308  *((SQLWCHAR *)val) = 0;
12309  }
12310  }
12311  } else {
12312  len *= sizeof (SQLWCHAR);
12313  }
12314  break;
12315  }
12316  if (buflen) {
12317  *buflen = len;
12318  }
12319  }
12320  HDBC_UNLOCK(dbc);
12321  return ret;
12322 }
12323 #endif
12324 
12334 static SQLRETURN
12335 drvsetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12336  SQLINTEGER len)
12337 {
12338  DBC *d;
12339 
12340  if (dbc == SQL_NULL_HDBC) {
12341  return SQL_INVALID_HANDLE;
12342  }
12343  d = (DBC *) dbc;
12344  switch (attr) {
12345  case SQL_AUTOCOMMIT:
12346  d->autocommit = val == (SQLPOINTER) SQL_AUTOCOMMIT_ON;
12347  if (d->autocommit && d->intrans) {
12348  return endtran(d, SQL_COMMIT, 1);
12349  } else if (!d->autocommit) {
12350  s3stmt_end(d->cur_s3stmt);
12351  }
12352  break;
12353  return SQL_SUCCESS;
12354 #ifdef SQL_ATTR_METADATA_ID
12355  case SQL_ATTR_METADATA_ID:
12356  if (val == (SQLPOINTER) SQL_FALSE) {
12357  break;
12358  }
12359  /* fall through */
12360 #endif
12361  default:
12362  setstatd(d, -1, "option value changed", "01S02");
12363  return SQL_SUCCESS_WITH_INFO;
12364  }
12365  return SQL_SUCCESS;
12366 }
12367 
12368 #ifndef WINTERFACE
12369 
12378 SQLRETURN SQL_API
12379 SQLSetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12380  SQLINTEGER len)
12381 {
12382  SQLRETURN ret;
12383 
12384  HDBC_LOCK(dbc);
12385  ret = drvsetconnectattr(dbc, attr, val, len);
12386  HDBC_UNLOCK(dbc);
12387  return ret;
12388 }
12389 #endif
12390 
12391 #ifdef WINTERFACE
12392 
12401 SQLRETURN SQL_API
12402 SQLSetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12403  SQLINTEGER len)
12404 {
12405  SQLRETURN ret;
12406 
12407  HDBC_LOCK(dbc);
12408  ret = drvsetconnectattr(dbc, attr, val, len);
12409  HDBC_UNLOCK(dbc);
12410  return ret;
12411 }
12412 #endif
12413 
12422 static SQLRETURN
12423 drvgetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12424 {
12425  DBC *d;
12426  SQLINTEGER dummy;
12427 
12428  if (dbc == SQL_NULL_HDBC) {
12429  return SQL_INVALID_HANDLE;
12430  }
12431  d = (DBC *) dbc;
12432  if (!param) {
12433  param = (SQLPOINTER) &dummy;
12434  }
12435  switch (opt) {
12436  case SQL_ACCESS_MODE:
12437  *((SQLINTEGER *) param) = SQL_MODE_READ_WRITE;
12438  break;
12439  case SQL_AUTOCOMMIT:
12440  *((SQLINTEGER *) param) =
12441  d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
12442  break;
12443  case SQL_LOGIN_TIMEOUT:
12444  *((SQLINTEGER *) param) = 100;
12445  break;
12446  case SQL_ODBC_CURSORS:
12447  *((SQLINTEGER *) param) = SQL_CUR_USE_DRIVER;
12448  break;
12449  case SQL_PACKET_SIZE:
12450  *((SQLINTEGER *) param) = 16384;
12451  break;
12452  case SQL_TXN_ISOLATION:
12453  *((SQLINTEGER *) param) = SQL_TXN_SERIALIZABLE;
12454  break;
12455  case SQL_OPT_TRACE:
12456  case SQL_OPT_TRACEFILE:
12457  case SQL_QUIET_MODE:
12458  case SQL_TRANSLATE_DLL:
12459  case SQL_TRANSLATE_OPTION:
12460  case SQL_KEYSET_SIZE:
12461  case SQL_QUERY_TIMEOUT:
12462  case SQL_BIND_TYPE:
12463  case SQL_CURRENT_QUALIFIER:
12464  *((SQLINTEGER *) param) = 0;
12465  break;
12466  case SQL_USE_BOOKMARKS:
12467  *((SQLINTEGER *) param) = SQL_UB_OFF;
12468  break;
12469  case SQL_ASYNC_ENABLE:
12470  *((SQLINTEGER *) param) = SQL_ASYNC_ENABLE_OFF;
12471  break;
12472  case SQL_NOSCAN:
12473  *((SQLINTEGER *) param) = SQL_NOSCAN_ON;
12474  break;
12475  case SQL_CONCURRENCY:
12476  *((SQLINTEGER *) param) = SQL_CONCUR_LOCK;
12477  break;
12478  case SQL_SIMULATE_CURSOR:
12479  *((SQLINTEGER *) param) = SQL_SC_NON_UNIQUE;
12480  break;
12481  case SQL_MAX_ROWS:
12482  *((SQLINTEGER *) param) = 0;
12483  break;
12484  case SQL_ROWSET_SIZE:
12485  case SQL_MAX_LENGTH:
12486  *((SQLINTEGER *) param) = 1000000000;
12487  break;
12488  case SQL_CURSOR_TYPE:
12489  *((SQLINTEGER *) param) = d->curtype;
12490  break;
12491  case SQL_RETRIEVE_DATA:
12492  *((SQLINTEGER *) param) = SQL_RD_ON;
12493  break;
12494  default:
12495  *((SQLINTEGER *) param) = 0;
12496  setstatd(d, -1, "unsupported connect option %d",
12497  (*d->ov3) ? "HYC00" : "S1C00", opt);
12498  return SQL_ERROR;
12499  }
12500  return SQL_SUCCESS;
12501 }
12502 
12503 #ifndef WINTERFACE
12504 
12512 SQLRETURN SQL_API
12513 SQLGetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12514 {
12515  SQLRETURN ret;
12516 
12517  HDBC_LOCK(dbc);
12518  ret = drvgetconnectoption(dbc, opt, param);
12519  HDBC_UNLOCK(dbc);
12520  return ret;
12521 }
12522 #endif
12523 
12524 #ifdef WINTERFACE
12525 
12533 SQLRETURN SQL_API
12534 SQLGetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12535 {
12536  SQLRETURN ret;
12537 
12538  HDBC_LOCK(dbc);
12539  ret = drvgetconnectoption(dbc, opt, param);
12540  if (SQL_SUCCEEDED(ret)) {
12541  switch (opt) {
12542  case SQL_OPT_TRACEFILE:
12543  case SQL_CURRENT_QUALIFIER:
12544  case SQL_TRANSLATE_DLL:
12545  if (param) {
12546  *(SQLWCHAR *) param = 0;
12547  }
12548  break;
12549  }
12550  }
12551  HDBC_UNLOCK(dbc);
12552  return ret;
12553 }
12554 #endif
12555 
12564 static SQLRETURN
12565 drvsetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
12566 {
12567  DBC *d;
12568 
12569  if (dbc == SQL_NULL_HDBC) {
12570  return SQL_INVALID_HANDLE;
12571  }
12572  d = (DBC *) dbc;
12573  switch (opt) {
12574  case SQL_AUTOCOMMIT:
12575  d->autocommit = param == SQL_AUTOCOMMIT_ON;
12576  if (d->autocommit && d->intrans) {
12577  return endtran(d, SQL_COMMIT, 1);
12578  } else if (!d->autocommit) {
12579  s3stmt_end(d->cur_s3stmt);
12580  }
12581  break;
12582  default:
12583  setstatd(d, -1, "option value changed", "01S02");
12584  return SQL_SUCCESS_WITH_INFO;
12585  }
12586  return SQL_SUCCESS;
12587 }
12588 
12589 #ifndef WINTERFACE
12590 
12598 SQLRETURN SQL_API
12599 SQLSetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12600 {
12601  SQLRETURN ret;
12602 
12603  HDBC_LOCK(dbc);
12604  ret = drvsetconnectoption(dbc, opt, param);
12605  HDBC_UNLOCK(dbc);
12606  return ret;
12607 }
12608 #endif
12609 
12610 #ifdef WINTERFACE
12611 
12619 SQLRETURN SQL_API
12620 SQLSetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12621 {
12622  SQLRETURN ret;
12623 
12624  HDBC_LOCK(dbc);
12625  ret = drvsetconnectoption(dbc, opt, param);
12626  HDBC_UNLOCK(dbc);
12627  return ret;
12628 }
12629 #endif
12630 
12631 #if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
12632 
12643 static int
12644 getdsnattr(char *dsn, char *attr, char *out, int outLen)
12645 {
12646  char *str = dsn, *start;
12647  int len = strlen(attr);
12648 
12649  while (*str) {
12650  while (*str && *str == ';') {
12651  ++str;
12652  }
12653  start = str;
12654  if ((str = strchr(str, '=')) == NULL) {
12655  return 0;
12656  }
12657  if (str - start == len && strncasecmp(start, attr, len) == 0) {
12658  start = ++str;
12659  while (*str && *str != ';') {
12660  ++str;
12661  }
12662  len = min(outLen - 1, str - start);
12663  strncpy(out, start, len);
12664  out[len] = '\0';
12665  return 1;
12666  }
12667  while (*str && *str != ';') {
12668  ++str;
12669  }
12670  }
12671  return 0;
12672 }
12673 #endif
12674 
12686 static SQLRETURN
12687 drvconnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen, char *pwd,
12688  int pwdLen, int isu)
12689 {
12690  DBC *d;
12691  int len;
12692  SQLRETURN ret;
12693  char buf[SQL_MAX_MESSAGE_LENGTH * 6], dbname[SQL_MAX_MESSAGE_LENGTH];
12694  char busy[SQL_MAX_MESSAGE_LENGTH / 4], tracef[SQL_MAX_MESSAGE_LENGTH];
12695  char loadext[SQL_MAX_MESSAGE_LENGTH];
12696  char sflag[32], spflag[32], ntflag[32], nwflag[32], biflag[32];
12697  char snflag[32], lnflag[32], ncflag[32], fkflag[32], jmode[32];
12698  char jdflag[32];
12699 #if defined(_WIN32) || defined(_WIN64)
12700  char oemcp[32];
12701 #endif
12702 
12703  if (dbc == SQL_NULL_HDBC) {
12704  return SQL_INVALID_HANDLE;
12705  }
12706  d = (DBC *) dbc;
12707  if (d->magic != DBC_MAGIC) {
12708  return SQL_INVALID_HANDLE;
12709  }
12710  if (d->sqlite != NULL) {
12711  setstatd(d, -1, "connection already established", "08002");
12712  return SQL_ERROR;
12713  }
12714  buf[0] = '\0';
12715  if (dsnLen == SQL_NTS) {
12716  len = sizeof (buf) - 1;
12717  } else {
12718  len = min(sizeof (buf) - 1, dsnLen);
12719  }
12720  if (dsn != NULL) {
12721  strncpy(buf, (char *) dsn, len);
12722  }
12723  buf[len] = '\0';
12724  if (buf[0] == '\0') {
12725  setstatd(d, -1, "invalid DSN", (*d->ov3) ? "HY090" : "S1090");
12726  return SQL_ERROR;
12727  }
12728 #if defined(_WIN32) || defined(_WIN64)
12729  /*
12730  * When DSN is in UTF it must be converted to ANSI
12731  * here for ANSI SQLGetPrivateProfileString()
12732  */
12733  if (isu) {
12734  char *cdsn = utf_to_wmb(buf, len);
12735 
12736  if (!cdsn) {
12737  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12738  return SQL_ERROR;
12739  }
12740  strcpy(buf, cdsn);
12741  uc_free(cdsn);
12742  }
12743 #endif
12744  busy[0] = '\0';
12745  dbname[0] = '\0';
12746 #ifdef WITHOUT_DRIVERMGR
12747  getdsnattr(buf, "database", dbname, sizeof (dbname));
12748  if (dbname[0] == '\0') {
12749  strncpy(dbname, buf, sizeof (dbname));
12750  dbname[sizeof (dbname) - 1] = '\0';
12751  }
12752  getdsnattr(buf, "timeout", busy, sizeof (busy));
12753  sflag[0] = '\0';
12754  getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
12755  spflag[0] = '\0';
12756  getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
12757  ntflag[0] = '\0';
12758  getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
12759  nwflag[0] = '\0';
12760  getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
12761  snflag[0] = '\0';
12762  getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
12763  lnflag[0] = '\0';
12764  getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
12765  ncflag[0] = '\0';
12766  getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
12767  fkflag[0] = '\0';
12768  getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
12769  loadext[0] = '\0';
12770  getdsnattr(buf, "loadext", loadext, sizeof (loadext));
12771  jmode[0] = '\0';
12772  getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
12773  jdflag[0] = '\0';
12774  getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
12775 #if defined(_WIN32) || defined(_WIN64)
12776  oemcp[0] = '\0';
12777  getdsnattr(buf, "oemcp", oemcp, sizeof (oemcp));
12778 #endif
12779  biflag[0] = '\0';
12780  getdsnattr(buf, "bigint", biflag, sizeof (biflag));
12781 #else
12782  SQLGetPrivateProfileString(buf, "timeout", "100000",
12783  busy, sizeof (busy), ODBC_INI);
12784  SQLGetPrivateProfileString(buf, "database", "",
12785  dbname, sizeof (dbname), ODBC_INI);
12786 #if defined(_WIN32) || defined(_WIN64)
12787  /* database name read from registry is not UTF8 !!! */
12788  isu = 0;
12789 #endif
12790  SQLGetPrivateProfileString(buf, "stepapi", "",
12791  sflag, sizeof (sflag), ODBC_INI);
12792  SQLGetPrivateProfileString(buf, "syncpragma", "NORMAL",
12793  spflag, sizeof (spflag), ODBC_INI);
12794  SQLGetPrivateProfileString(buf, "notxn", "",
12795  ntflag, sizeof (ntflag), ODBC_INI);
12796  SQLGetPrivateProfileString(buf, "nowchar", "",
12797  nwflag, sizeof (nwflag), ODBC_INI);
12798  SQLGetPrivateProfileString(buf, "shortnames", "",
12799  snflag, sizeof (snflag), ODBC_INI);
12800  SQLGetPrivateProfileString(buf, "longnames", "",
12801  lnflag, sizeof (lnflag), ODBC_INI);
12802  SQLGetPrivateProfileString(buf, "nocreat", "",
12803  ncflag, sizeof (ncflag), ODBC_INI);
12804  SQLGetPrivateProfileString(buf, "fksupport", "",
12805  fkflag, sizeof (fkflag), ODBC_INI);
12806  SQLGetPrivateProfileString(buf, "loadext", "",
12807  loadext, sizeof (loadext), ODBC_INI);
12808  SQLGetPrivateProfileString(buf, "journalmode", "",
12809  jmode, sizeof (jmode), ODBC_INI);
12810  SQLGetPrivateProfileString(buf, "jdconv", "",
12811  jdflag, sizeof (jdflag), ODBC_INI);
12812 #if defined(_WIN32) || defined(_WIN64)
12813  SQLGetPrivateProfileString(buf, "oemcp", "1",
12814  oemcp, sizeof (oemcp), ODBC_INI);
12815 #endif
12816  SQLGetPrivateProfileString(buf, "bigint", "",
12817  biflag, sizeof (biflag), ODBC_INI);
12818 #endif
12819  tracef[0] = '\0';
12820 #ifdef WITHOUT_DRIVERMGR
12821  getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
12822 #else
12823  SQLGetPrivateProfileString(buf, "tracefile", "",
12824  tracef, sizeof (tracef), ODBC_INI);
12825 #endif
12826  if (tracef[0] != '\0') {
12827  d->trace = fopen(tracef, "a");
12828  }
12829  d->nowchar = getbool(nwflag);
12830  d->shortnames = getbool(snflag);
12831  d->longnames = getbool(lnflag);
12832  d->nocreat = getbool(ncflag);
12833  d->fksupport = getbool(fkflag);
12834  d->jdconv = getbool(jdflag);
12835 #if defined(_WIN32) || defined(_WIN64)
12836  d->oemcp = getbool(oemcp);
12837 #else
12838  d->oemcp = 0;
12839 #endif
12840  d->dobigint = getbool(biflag);
12841  d->pwd = pwd;
12842  d->pwdLen = 0;
12843  if (d->pwd) {
12844  d->pwdLen = (pwdLen == SQL_NTS) ? strlen(d->pwd) : pwdLen;
12845  }
12846  ret = dbopen(d, dbname, isu, (char *) dsn, sflag, spflag, ntflag,
12847  jmode, busy);
12848  if (ret == SQL_SUCCESS) {
12849  dbloadext(d, loadext);
12850  }
12851  return ret;
12852 }
12853 
12854 #ifndef WINTERFACE
12855 
12867 SQLRETURN SQL_API
12868 SQLConnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen,
12869  SQLCHAR *uid, SQLSMALLINT uidLen,
12870  SQLCHAR *pwd, SQLSMALLINT pwdLen)
12871 {
12872  SQLRETURN ret;
12873 
12874  HDBC_LOCK(dbc);
12875  ret = drvconnect(dbc, dsn, dsnLen, (char *) pwd, pwdLen, 0);
12876  HDBC_UNLOCK(dbc);
12877  return ret;
12878 }
12879 #endif
12880 
12881 #ifdef WINTERFACE
12882 
12894 SQLRETURN SQL_API
12895 SQLConnectW(SQLHDBC dbc, SQLWCHAR *dsn, SQLSMALLINT dsnLen,
12896  SQLWCHAR *uid, SQLSMALLINT uidLen,
12897  SQLWCHAR *pwd, SQLSMALLINT pwdLen)
12898 {
12899  char *dsna = NULL;
12900  char *pwda = NULL;
12901  SQLRETURN ret;
12902 
12903  HDBC_LOCK(dbc);
12904  if (dsn) {
12905  dsna = uc_to_utf_c(dsn, dsnLen);
12906  if (!dsna) {
12907  DBC *d = (DBC *) dbc;
12908 
12909  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12910  ret = SQL_ERROR;
12911  goto done;
12912  }
12913  }
12914  if (pwd) {
12915  pwda = uc_to_utf_c(pwd, pwdLen);
12916  if (!pwda) {
12917  DBC *d = (DBC *) dbc;
12918 
12919  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12920  ret = SQL_ERROR;
12921  goto done;
12922  }
12923  }
12924  ret = drvconnect(dbc, (SQLCHAR *) dsna, SQL_NTS, pwda, SQL_NTS, 1);
12925 done:
12926  HDBC_UNLOCK(dbc);
12927  uc_free(dsna);
12928  uc_free(pwda);
12929  return ret;
12930 }
12931 #endif
12932 
12939 static SQLRETURN
12941 {
12942  DBC *d;
12943  int rc;
12944 
12945  if (dbc == SQL_NULL_HDBC) {
12946  return SQL_INVALID_HANDLE;
12947  }
12948  d = (DBC *) dbc;
12949  if (d->magic != DBC_MAGIC) {
12950  return SQL_INVALID_HANDLE;
12951  }
12952  if (d->intrans) {
12953  setstatd(d, -1, "incomplete transaction", "25000");
12954  return SQL_ERROR;
12955  }
12956  if (d->cur_s3stmt) {
12957  s3stmt_end(d->cur_s3stmt);
12958  }
12959  if (d->sqlite) {
12960  if (d->trace) {
12961  fprintf(d->trace, "-- sqlite3_close: '%s'\n",
12962  d->dbname);
12963  fflush(d->trace);
12964  }
12965  rc = sqlite3_close(d->sqlite);
12966  if (rc == SQLITE_BUSY) {
12967  setstatd(d, -1, "unfinished statements", "25000");
12968  return SQL_ERROR;
12969  }
12970  d->sqlite = NULL;
12971  }
12972  freep(&d->dbname);
12973  freep(&d->dsn);
12974  return SQL_SUCCESS;
12975 }
12976 
12983 SQLRETURN SQL_API
12985 {
12986  SQLRETURN ret;
12987 
12988  HDBC_LOCK(dbc);
12989  ret = drvdisconnect(dbc);
12990  HDBC_UNLOCK(dbc);
12991  return ret;
12992 }
12993 
12994 #if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
12995 
13009 static SQLRETURN
13010 drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
13011  SQLCHAR *connIn, SQLSMALLINT connInLen,
13012  SQLCHAR *connOut, SQLSMALLINT connOutMax,
13013  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
13014 {
13015  DBC *d;
13016  int len;
13017  SQLRETURN ret;
13018  char buf[SQL_MAX_MESSAGE_LENGTH * 8], dbname[SQL_MAX_MESSAGE_LENGTH];
13019  char dsn[SQL_MAX_MESSAGE_LENGTH], busy[SQL_MAX_MESSAGE_LENGTH / 4];
13020  char tracef[SQL_MAX_MESSAGE_LENGTH], loadext[SQL_MAX_MESSAGE_LENGTH];
13021  char pwd[SQL_MAX_MESSAGE_LENGTH];
13022  char sflag[32], spflag[32], ntflag[32], snflag[32], lnflag[32];
13023  char ncflag[32], nwflag[32], fkflag[32], jmode[32], biflag[32];
13024  char jdflag[32];
13025 
13026  if (dbc == SQL_NULL_HDBC) {
13027  return SQL_INVALID_HANDLE;
13028  }
13029  if (drvcompl != SQL_DRIVER_COMPLETE &&
13030  drvcompl != SQL_DRIVER_COMPLETE_REQUIRED &&
13031  drvcompl != SQL_DRIVER_PROMPT &&
13032  drvcompl != SQL_DRIVER_NOPROMPT) {
13033  return SQL_NO_DATA;
13034  }
13035  d = (DBC *) dbc;
13036  if (d->sqlite) {
13037  setstatd(d, -1, "connection already established", "08002");
13038  return SQL_ERROR;
13039  }
13040  buf[0] = '\0';
13041  if (connInLen == SQL_NTS) {
13042  len = sizeof (buf) - 1;
13043  } else {
13044  len = min(connInLen, sizeof (buf) - 1);
13045  }
13046  if (connIn != NULL) {
13047  strncpy(buf, (char *) connIn, len);
13048  }
13049  buf[len] = '\0';
13050  if (!buf[0]) {
13051  setstatd(d, -1, "invalid connect attributes",
13052  (*d->ov3) ? "HY090" : "S1090");
13053  return SQL_ERROR;
13054  }
13055  dsn[0] = '\0';
13056  getdsnattr(buf, "DSN", dsn, sizeof (dsn));
13057 
13058  /* special case: connIn is sole DSN value without keywords */
13059  if (!dsn[0] && !strchr(buf, ';') && !strchr(buf, '=')) {
13060  strncpy(dsn, buf, sizeof (dsn) - 1);
13061  dsn[sizeof (dsn) - 1] = '\0';
13062  }
13063 
13064  busy[0] = '\0';
13065  getdsnattr(buf, "timeout", busy, sizeof (busy));
13066 #ifndef WITHOUT_DRIVERMGR
13067  if (dsn[0] && !busy[0]) {
13068  SQLGetPrivateProfileString(dsn, "timeout", "100000",
13069  busy, sizeof (busy), ODBC_INI);
13070  }
13071 #endif
13072  dbname[0] = '\0';
13073  getdsnattr(buf, "database", dbname, sizeof (dbname));
13074 #ifndef WITHOUT_DRIVERMGR
13075  if (dsn[0] && !dbname[0]) {
13076  SQLGetPrivateProfileString(dsn, "database", "",
13077  dbname, sizeof (dbname), ODBC_INI);
13078  }
13079 #endif
13080  sflag[0] = '\0';
13081  getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
13082 #ifndef WITHOUT_DRIVERMGR
13083  if (dsn[0] && !sflag[0]) {
13084  SQLGetPrivateProfileString(dsn, "stepapi", "",
13085  sflag, sizeof (sflag), ODBC_INI);
13086  }
13087 #endif
13088  spflag[0] = '\0';
13089  getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
13090 #ifndef WITHOUT_DRIVERMGR
13091  if (dsn[0] && !spflag[0]) {
13092  SQLGetPrivateProfileString(dsn, "syncpragma", "NORMAL",
13093  spflag, sizeof (spflag), ODBC_INI);
13094  }
13095 #endif
13096  ntflag[0] = '\0';
13097  getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
13098 #ifndef WITHOUT_DRIVERMGR
13099  if (dsn[0] && !ntflag[0]) {
13100  SQLGetPrivateProfileString(dsn, "notxn", "",
13101  ntflag, sizeof (ntflag), ODBC_INI);
13102  }
13103 #endif
13104  snflag[0] = '\0';
13105  getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
13106 #ifndef WITHOUT_DRIVERMGR
13107  if (dsn[0] && !snflag[0]) {
13108  SQLGetPrivateProfileString(dsn, "shortnames", "",
13109  snflag, sizeof (snflag), ODBC_INI);
13110  }
13111 #endif
13112  lnflag[0] = '\0';
13113  getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
13114 #ifndef WITHOUT_DRIVERMGR
13115  if (dsn[0] && !lnflag[0]) {
13116  SQLGetPrivateProfileString(dsn, "longnames", "",
13117  lnflag, sizeof (lnflag), ODBC_INI);
13118  }
13119 #endif
13120  ncflag[0] = '\0';
13121  getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
13122 #ifndef WITHOUT_DRIVERMGR
13123  if (dsn[0] && !ncflag[0]) {
13124  SQLGetPrivateProfileString(dsn, "nocreat", "",
13125  ncflag, sizeof (ncflag), ODBC_INI);
13126  }
13127 #endif
13128  nwflag[0] = '\0';
13129  getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
13130 #ifndef WITHOUT_DRIVERMGR
13131  if (dsn[0] && !nwflag[0]) {
13132  SQLGetPrivateProfileString(dsn, "nowchar", "",
13133  nwflag, sizeof (nwflag), ODBC_INI);
13134  }
13135 #endif
13136  fkflag[0] = '\0';
13137  getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
13138 #ifndef WITHOUT_DRIVERMGR
13139  if (dsn[0] && !fkflag[0]) {
13140  SQLGetPrivateProfileString(dsn, "fksupport", "",
13141  fkflag, sizeof (fkflag), ODBC_INI);
13142  }
13143 #endif
13144  loadext[0] = '\0';
13145  getdsnattr(buf, "loadext", loadext, sizeof (loadext));
13146 #ifndef WITHOUT_DRIVERMGR
13147  if (dsn[0] && !loadext[0]) {
13148  SQLGetPrivateProfileString(dsn, "loadext", "",
13149  loadext, sizeof (loadext), ODBC_INI);
13150  }
13151 #endif
13152  jmode[0] = '\0';
13153  getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
13154 #ifndef WITHOUT_DRIVERMGR
13155  if (dsn[0] && !jmode[0]) {
13156  SQLGetPrivateProfileString(dsn, "journalmode", "",
13157  jmode, sizeof (jmode), ODBC_INI);
13158  }
13159 #endif
13160  biflag[0] = '\0';
13161  getdsnattr(buf, "bigint", biflag, sizeof (biflag));
13162 #ifndef WITHOUT_DRIVERMGR
13163  if (dsn[0] && !biflag[0]) {
13164  SQLGetPrivateProfileString(dsn, "bigint", "",
13165  biflag, sizeof (biflag), ODBC_INI);
13166  }
13167 #endif
13168  jdflag[0] = '\0';
13169  getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
13170 #ifndef WITHOUT_DRIVERMGR
13171  if (dsn[0] && !jdflag[0]) {
13172  SQLGetPrivateProfileString(dsn, "jdconv", "",
13173  jdflag, sizeof (jdflag), ODBC_INI);
13174  }
13175 #endif
13176  pwd[0] = '\0';
13177  getdsnattr(buf, "pwd", pwd, sizeof (pwd));
13178 #ifndef WITHOUT_DRIVERMGR
13179  if (dsn[0] && !pwd[0]) {
13180  SQLGetPrivateProfileString(dsn, "pwd", "",
13181  pwd, sizeof (pwd), ODBC_INI);
13182  }
13183 #endif
13184 
13185  if (!dbname[0] && !dsn[0]) {
13186  strcpy(dsn, "SQLite");
13187  strncpy(dbname, buf, sizeof (dbname));
13188  dbname[sizeof (dbname) - 1] = '\0';
13189  }
13190  tracef[0] = '\0';
13191  getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
13192 #ifndef WITHOUT_DRIVERMGR
13193  if (dsn[0] && !tracef[0]) {
13194  SQLGetPrivateProfileString(dsn, "tracefile", "",
13195  tracef, sizeof (tracef), ODBC_INI);
13196  }
13197 #endif
13198  if (connOut || connOutLen) {
13199  int count;
13200 
13201  buf[0] = '\0';
13202  count = snprintf(buf, sizeof (buf),
13203  "DSN=%s;Database=%s;StepAPI=%s;Timeout=%s;"
13204  "SyncPragma=%s;NoTXN=%s;ShortNames=%s;LongNames=%s;"
13205  "NoCreat=%s;NoWCHAR=%s;FKSupport=%s;Tracefile=%s;"
13206  "JournalMode=%s;LoadExt=%s;BigInt=%s;JDConv=%s;"
13207  "PWD=%s",
13208  dsn, dbname, sflag, busy, spflag, ntflag,
13209  snflag, lnflag, ncflag, nwflag, fkflag, tracef,
13210  jmode, loadext, biflag, jdflag, pwd);
13211  if (count < 0) {
13212  buf[sizeof (buf) - 1] = '\0';
13213  }
13214  len = min(connOutMax - 1, strlen(buf));
13215  if (connOut) {
13216  strncpy((char *) connOut, buf, len);
13217  connOut[len] = '\0';
13218  }
13219  if (connOutLen) {
13220  *connOutLen = len;
13221  }
13222  }
13223  if (tracef[0] != '\0') {
13224  d->trace = fopen(tracef, "a");
13225  }
13226  d->shortnames = getbool(snflag);
13227  d->longnames = getbool(lnflag);
13228  d->nocreat = getbool(ncflag);
13229  d->nowchar = getbool(nwflag);
13230  d->fksupport = getbool(fkflag);
13231  d->dobigint = getbool(biflag);
13232  d->jdconv = getbool(jdflag);
13233  d->oemcp = 0;
13234  d->pwdLen = strlen(pwd);
13235  d->pwd = (d->pwdLen > 0) ? pwd : NULL;
13236  ret = dbopen(d, dbname, 0, dsn, sflag, spflag, ntflag, jmode, busy);
13237  memset(pwd, 0, sizeof (pwd));
13238  if (ret == SQL_SUCCESS) {
13239  dbloadext(d, loadext);
13240  }
13241  return ret;
13242 }
13243 #endif
13244 
13251 static SQLRETURN
13252 freestmt(SQLHSTMT stmt)
13253 {
13254  STMT *s;
13255  DBC *d;
13256 
13257  if (stmt == SQL_NULL_HSTMT) {
13258  return SQL_INVALID_HANDLE;
13259  }
13260  s = (STMT *) stmt;
13261  s3stmt_drop(s);
13262  freeresult(s, 1);
13263  freep(&s->query);
13264  d = (DBC *) s->dbc;
13265  if (d && d->magic == DBC_MAGIC) {
13266  STMT *p, *n;
13267 
13268  p = NULL;
13269  n = d->stmt;
13270  while (n) {
13271  if (n == s) {
13272  break;
13273  }
13274  p = n;
13275  n = n->next;
13276  }
13277  if (n) {
13278  if (p) {
13279  p->next = s->next;
13280  } else {
13281  d->stmt = s->next;
13282  }
13283  }
13284  }
13285  freeparams(s);
13286  freep(&s->bindparms);
13287  if (s->row_status0 != &s->row_status1) {
13288  freep(&s->row_status0);
13289  s->rowset_size = 1;
13290  s->row_status0 = &s->row_status1;
13291  }
13292  xfree(s);
13293  return SQL_SUCCESS;
13294 }
13295 
13303 static SQLRETURN
13304 drvallocstmt(SQLHDBC dbc, SQLHSTMT *stmt)
13305 {
13306  DBC *d;
13307  STMT *s, *sl, *pl;
13308 
13309  if (dbc == SQL_NULL_HDBC) {
13310  return SQL_INVALID_HANDLE;
13311  }
13312  d = (DBC *) dbc;
13313  if (d->magic != DBC_MAGIC || stmt == NULL) {
13314  return SQL_INVALID_HANDLE;
13315  }
13316  s = (STMT *) xmalloc(sizeof (STMT));
13317  if (s == NULL) {
13318  *stmt = SQL_NULL_HSTMT;
13319  return SQL_ERROR;
13320  }
13321  *stmt = (SQLHSTMT) s;
13322  memset(s, 0, sizeof (STMT));
13323  s->dbc = dbc;
13324  s->ov3 = d->ov3;
13325  s->bkmrk = SQL_UB_OFF;
13326  s->bkmrkptr = 0;
13327  s->oemcp = &d->oemcp;
13328  s->jdconv = &d->jdconv;
13329  s->nowchar[0] = d->nowchar;
13330  s->nowchar[1] = 0;
13331  s->dobigint = d->dobigint;
13332  s->curtype = d->curtype;
13333  s->row_status0 = &s->row_status1;
13334  s->rowset_size = 1;
13335  s->longnames = d->longnames;
13336  s->retr_data = SQL_RD_ON;
13337  s->max_rows = 0;
13338  s->bind_type = SQL_BIND_BY_COLUMN;
13339  s->bind_offs = NULL;
13340  s->paramset_size = 1;
13341  s->parm_bind_type = SQL_PARAM_BIND_BY_COLUMN;
13342  s->one_tbl = -1;
13343  s->has_pk = -1;
13344  s->has_rowid = -1;
13345 #ifdef _WIN64
13346  sprintf((char *) s->cursorname, "CUR_%I64X", (SQLUBIGINT) *stmt);
13347 #else
13348  sprintf((char *) s->cursorname, "CUR_%016lX", (long) *stmt);
13349 #endif
13350  sl = d->stmt;
13351  pl = NULL;
13352  while (sl) {
13353  pl = sl;
13354  sl = sl->next;
13355  }
13356  if (pl) {
13357  pl->next = s;
13358  } else {
13359  d->stmt = s;
13360  }
13361  return SQL_SUCCESS;
13362 }
13363 
13371 SQLRETURN SQL_API
13372 SQLAllocStmt(SQLHDBC dbc, SQLHSTMT *stmt)
13373 {
13374  SQLRETURN ret;
13375 
13376  HDBC_LOCK(dbc);
13377  ret = drvallocstmt(dbc, stmt);
13378  HDBC_UNLOCK(dbc);
13379  return ret;
13380 }
13381 
13389 static SQLRETURN
13390 drvfreestmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13391 {
13392  STMT *s;
13393  SQLRETURN ret = SQL_SUCCESS;
13394  SQLHDBC dbc;
13395 
13396  if (stmt == SQL_NULL_HSTMT) {
13397  return SQL_INVALID_HANDLE;
13398  }
13399  HSTMT_LOCK(stmt);
13400  s = (STMT *) stmt;
13401  dbc = s->dbc;
13402  switch (opt) {
13403  case SQL_RESET_PARAMS:
13404  freeparams(s);
13405  break;
13406  case SQL_UNBIND:
13407  unbindcols(s);
13408  break;
13409  case SQL_CLOSE:
13410  s3stmt_end_if(s);
13411  freeresult(s, 0);
13412  break;
13413  case SQL_DROP:
13414  s3stmt_end_if(s);
13415  ret = freestmt(stmt);
13416  break;
13417  default:
13418  setstat(s, -1, "unsupported option", (*s->ov3) ? "HYC00" : "S1C00");
13419  ret = SQL_ERROR;
13420  break;
13421  }
13422  HDBC_UNLOCK(dbc);
13423  return ret;
13424 }
13425 
13433 SQLRETURN SQL_API
13434 SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13435 {
13436  return drvfreestmt(stmt, opt);
13437 }
13438 
13445 SQLRETURN SQL_API
13446 SQLCancel(SQLHSTMT stmt)
13447 {
13448  if (stmt != SQL_NULL_HSTMT) {
13449  DBC *d = (DBC *) ((STMT *) stmt)->dbc;
13450 #if defined(_WIN32) || defined(_WIN64)
13451  /* interrupt when other thread owns critical section */
13452  if (d->magic == DBC_MAGIC && d->owner != GetCurrentThreadId() &&
13453  d->owner != 0) {
13454  d->busyint = 1;
13455  sqlite3_interrupt(d->sqlite);
13456  return SQL_SUCCESS;
13457  }
13458 #else
13459  if (d->magic == DBC_MAGIC) {
13460  d->busyint = 1;
13461  sqlite3_interrupt(d->sqlite);
13462  }
13463 #endif
13464  }
13465  return drvfreestmt(stmt, SQL_CLOSE);
13466 }
13467 
13477 static SQLRETURN
13478 drvgetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13479  SQLSMALLINT *lenp)
13480 {
13481  STMT *s;
13482 
13483  if (stmt == SQL_NULL_HSTMT) {
13484  return SQL_INVALID_HANDLE;
13485  }
13486  s = (STMT *) stmt;
13487  if (lenp && !cursor) {
13488  *lenp = strlen((char *) s->cursorname);
13489  return SQL_SUCCESS;
13490  }
13491  if (cursor) {
13492  if (buflen > 0) {
13493  strncpy((char *) cursor, (char *) s->cursorname, buflen - 1);
13494  cursor[buflen - 1] = '\0';
13495  }
13496  if (lenp) {
13497  *lenp = min(strlen((char *) s->cursorname), buflen - 1);
13498  }
13499  }
13500  return SQL_SUCCESS;
13501 }
13502 
13503 #ifndef WINTERFACE
13504 
13513 SQLRETURN SQL_API
13514 SQLGetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13515  SQLSMALLINT *lenp)
13516 {
13517  SQLRETURN ret;
13518 #if defined(_WIN32) || defined(_WIN64)
13519  SQLSMALLINT len = 0;
13520 #endif
13521 
13522  HSTMT_LOCK(stmt);
13523 #if defined(_WIN32) || defined(_WIN64)
13524  if (!((STMT *) stmt)->oemcp[0]) {
13525  ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13526  goto done;
13527  }
13528  ret = drvgetcursorname(stmt, cursor, buflen, &len);
13529  if (ret == SQL_SUCCESS) {
13530  char *c = NULL;
13531 
13532  if (cursor) {
13533  c = utf_to_wmb((char *) cursor, len);
13534  if (!c) {
13535  ret = nomem((STMT *) stmt);
13536  goto done;
13537  }
13538  c[len] = 0;
13539  len = strlen(c);
13540  if (buflen > 0) {
13541  strncpy((char *) cursor, c, buflen - 1);
13542  cursor[buflen - 1] = 0;
13543  }
13544  uc_free(c);
13545  }
13546  if (lenp) {
13547  *lenp = min(len, buflen - 1);
13548  }
13549  }
13550 done:
13551  ;
13552 #else
13553  ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13554 #endif
13555  HSTMT_UNLOCK(stmt);
13556  return ret;
13557 }
13558 #endif
13559 
13560 #ifdef WINTERFACE
13561 
13570 SQLRETURN SQL_API
13571 SQLGetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT buflen,
13572  SQLSMALLINT *lenp)
13573 {
13574  SQLRETURN ret;
13575  SQLSMALLINT len = 0;
13576 
13577  HSTMT_LOCK(stmt);
13578  ret = drvgetcursorname(stmt, (SQLCHAR *) cursor, buflen, &len);
13579  if (ret == SQL_SUCCESS) {
13580  SQLWCHAR *c = NULL;
13581 
13582  if (cursor) {
13583  c = uc_from_utf((SQLCHAR *) cursor, len);
13584  if (!c) {
13585  ret = nomem((STMT *) stmt);
13586  goto done;
13587  }
13588  c[len] = 0;
13589  len = uc_strlen(c);
13590  if (buflen > 0) {
13591  uc_strncpy(cursor, c, buflen - 1);
13592  cursor[buflen - 1] = 0;
13593  }
13594  uc_free(c);
13595  }
13596  if (lenp) {
13597  *lenp = min(len, buflen - 1);
13598  }
13599  }
13600 done:
13601  HSTMT_UNLOCK(stmt);
13602  return ret;
13603 }
13604 #endif
13605 
13614 static SQLRETURN
13615 drvsetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13616 {
13617  STMT *s;
13618 
13619  if (stmt == SQL_NULL_HSTMT) {
13620  return SQL_INVALID_HANDLE;
13621  }
13622  s = (STMT *) stmt;
13623  if (!cursor ||
13624  !((cursor[0] >= 'A' && cursor[0] <= 'Z') ||
13625  (cursor[0] >= 'a' && cursor[0] <= 'z'))) {
13626  setstat(s, -1, "invalid cursor name", (*s->ov3) ? "HYC00" : "S1C00");
13627  return SQL_ERROR;
13628  }
13629  if (len == SQL_NTS) {
13630  len = sizeof (s->cursorname) - 1;
13631  } else {
13632  len = min(sizeof (s->cursorname) - 1, len);
13633  }
13634  strncpy((char *) s->cursorname, (char *) cursor, len);
13635  s->cursorname[len] = '\0';
13636  return SQL_SUCCESS;
13637 }
13638 
13639 #ifndef WINTERFACE
13640 
13648 SQLRETURN SQL_API
13649 SQLSetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13650 {
13651 #if defined(_WIN32) || defined(_WIN64)
13652  char *c = NULL;
13653 #endif
13654  SQLRETURN ret;
13655 
13656  HSTMT_LOCK(stmt);
13657 #if defined(_WIN32) || defined(_WIN64)
13658  if (!((STMT *) stmt)->oemcp[0]) {
13659  ret = drvsetcursorname(stmt, cursor, len);
13660  goto done2;
13661  }
13662  if (cursor) {
13663  c = wmb_to_utf_c((char *) cursor, len);
13664  if (!c) {
13665  ret = nomem((STMT *) stmt);
13666  goto done;
13667  }
13668  }
13669  ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13670 #else
13671  ret = drvsetcursorname(stmt, cursor, len);
13672 #endif
13673 #if defined(_WIN32) || defined(_WIN64)
13674 done:
13675  uc_free(c);
13676 done2:
13677  ;
13678 #endif
13679  HSTMT_UNLOCK(stmt);
13680  return ret;
13681 }
13682 #endif
13683 
13684 #ifdef WINTERFACE
13685 
13693 SQLRETURN SQL_API
13694 SQLSetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT len)
13695 {
13696  char *c = NULL;
13697  SQLRETURN ret;
13698 
13699  HSTMT_LOCK(stmt);
13700  if (cursor) {
13701  c = uc_to_utf_c(cursor, len);
13702  if (!c) {
13703  ret = nomem((STMT *) stmt);
13704  goto done;
13705  }
13706  }
13707  ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13708 done:
13709  uc_free(c);
13710  HSTMT_UNLOCK(stmt);
13711  return ret;
13712 }
13713 #endif
13714 
13721 SQLRETURN SQL_API
13723 {
13724  return drvfreestmt(stmt, SQL_CLOSE);
13725 }
13726 
13735 SQLRETURN SQL_API
13736 SQLAllocHandle(SQLSMALLINT type, SQLHANDLE input, SQLHANDLE *output)
13737 {
13738  SQLRETURN ret;
13739 
13740  switch (type) {
13741  case SQL_HANDLE_ENV:
13742  ret = drvallocenv((SQLHENV *) output);
13743  if (ret == SQL_SUCCESS) {
13744  ENV *e = (ENV *) *output;
13745 
13746  if (e && e->magic == ENV_MAGIC) {
13747  e->ov3 = 1;
13748  }
13749  }
13750  return ret;
13751  case SQL_HANDLE_DBC:
13752  return drvallocconnect((SQLHENV) input, (SQLHDBC *) output);
13753  case SQL_HANDLE_STMT:
13754  HDBC_LOCK((SQLHDBC) input);
13755  ret = drvallocstmt((SQLHDBC) input, (SQLHSTMT *) output);
13756  HDBC_UNLOCK((SQLHDBC) input);
13757  return ret;
13758  }
13759  return SQL_ERROR;
13760 }
13761 
13769 SQLRETURN SQL_API
13770 SQLFreeHandle(SQLSMALLINT type, SQLHANDLE h)
13771 {
13772  switch (type) {
13773  case SQL_HANDLE_ENV:
13774  return drvfreeenv((SQLHENV) h);
13775  case SQL_HANDLE_DBC:
13776  return drvfreeconnect((SQLHDBC) h);
13777  case SQL_HANDLE_STMT:
13778  return drvfreestmt((SQLHSTMT) h, SQL_DROP);
13779  }
13780  return SQL_ERROR;
13781 }
13782 
13788 static void
13790 {
13791  if (s->dyncols) {
13792  int i;
13793 
13794  for (i = 0; i < s->dcols; i++) {
13795  freep(&s->dyncols[i].typename);
13796  }
13797  if (s->cols == s->dyncols) {
13798  s->cols = NULL;
13799  s->ncols = 0;
13800  }
13801  freep(&s->dyncols);
13802  }
13803  s->dcols = 0;
13804 }
13805 
13817 static void
13818 freeresult(STMT *s, int clrcols)
13819 {
13820  freep(&s->bincache);
13821  s->bincell = NULL;
13822  s->binlen = 0;
13823  if (s->rows) {
13824  if (s->rowfree) {
13825  s->rowfree(s->rows);
13826  s->rowfree = NULL;
13827  }
13828  s->rows = NULL;
13829  }
13830  s->nrows = -1;
13831  if (clrcols > 0) {
13832  freep(&s->bindcols);
13833  s->nbindcols = 0;
13834  }
13835  if (clrcols) {
13836  freedyncols(s);
13837  s->cols = NULL;
13838  s->ncols = 0;
13839  s->nowchar[1] = 0;
13840  s->one_tbl = -1;
13841  s->has_pk = -1;
13842  s->has_rowid = -1;
13843  }
13844 }
13845 
13851 static void
13853 {
13854  int i;
13855 
13856  for (i = 0; s->bindcols && i < s->nbindcols; i++) {
13857  s->bindcols[i].type = SQL_UNKNOWN_TYPE;
13858  s->bindcols[i].max = 0;
13859  s->bindcols[i].lenp = NULL;
13860  s->bindcols[i].valp = NULL;
13861  s->bindcols[i].index = i;
13862  s->bindcols[i].offs = 0;
13863  }
13864 }
13865 
13873 static SQLRETURN
13874 mkbindcols(STMT *s, int ncols)
13875 {
13876  if (s->bindcols) {
13877  if (s->nbindcols < ncols) {
13878  int i;
13879  BINDCOL *bindcols =
13880  xrealloc(s->bindcols, ncols * sizeof (BINDCOL));
13881 
13882  if (!bindcols) {
13883  return nomem(s);
13884  }
13885  for (i = s->nbindcols; i < ncols; i++) {
13886  bindcols[i].type = SQL_UNKNOWN_TYPE;
13887  bindcols[i].max = 0;
13888  bindcols[i].lenp = NULL;
13889  bindcols[i].valp = NULL;
13890  bindcols[i].index = i;
13891  bindcols[i].offs = 0;
13892  }
13893  s->bindcols = bindcols;
13894  s->nbindcols = ncols;
13895  }
13896  } else if (ncols > 0) {
13897  s->bindcols = (BINDCOL *) xmalloc(ncols * sizeof (BINDCOL));
13898  if (!s->bindcols) {
13899  return nomem(s);
13900  }
13901  s->nbindcols = ncols;
13902  unbindcols(s);
13903  }
13904  return SQL_SUCCESS;
13905 }
13906 
13920 static SQLRETURN
13921 getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype,
13922  SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp, int partial)
13923 {
13924  char **data, valdummy[16];
13925  SQLLEN dummy;
13926  SQLINTEGER *ilenp = NULL;
13927  int valnull = 0;
13928  int type = otype;
13929  SQLRETURN sret = SQL_NO_DATA;
13930 
13931  if (!lenp) {
13932  lenp = &dummy;
13933  }
13934  /* workaround for JDK 1.7.0 on x86_64 */
13935  if (((SQLINTEGER *) lenp) + 1 == (SQLINTEGER *) val) {
13936  ilenp = (SQLINTEGER *) lenp;
13937  lenp = &dummy;
13938  }
13939  if (col >= s->ncols) {
13940  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
13941  return SQL_ERROR;
13942  }
13943  if (s->retr_data != SQL_RD_ON) {
13944  return SQL_SUCCESS;
13945  }
13946  if (!s->rows) {
13947  *lenp = SQL_NULL_DATA;
13948  goto done;
13949  }
13950  if (s->rowp < 0 || s->rowp >= s->nrows) {
13951  *lenp = SQL_NULL_DATA;
13952  goto done;
13953  }
13954  type = mapdeftype(type, s->cols[col].type, s->cols[col].nosign ? 1 : 0,
13955  s->nowchar[0]);
13956 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
13957  /* MS Access hack part 3 (map SQL_C_DEFAULT to SQL_C_CHAR) */
13958  if (type == SQL_C_WCHAR && otype == SQL_C_DEFAULT) {
13959  type = SQL_C_CHAR;
13960  }
13961 #endif
13962  data = s->rows + s->ncols + (s->rowp * s->ncols) + col;
13963  if (!val) {
13964  valnull = 1;
13965  val = (SQLPOINTER) valdummy;
13966  }
13967  if (*data == NULL) {
13968  *lenp = SQL_NULL_DATA;
13969  switch (type) {
13970  case SQL_C_UTINYINT:
13971  case SQL_C_TINYINT:
13972  case SQL_C_STINYINT:
13973 #ifdef SQL_BIT
13974  case SQL_C_BIT:
13975 #endif
13976  *((SQLCHAR *) val) = 0;
13977  break;
13978  case SQL_C_USHORT:
13979  case SQL_C_SHORT:
13980  case SQL_C_SSHORT:
13981  *((SQLSMALLINT *) val) = 0;
13982  break;
13983  case SQL_C_ULONG:
13984  case SQL_C_LONG:
13985  case SQL_C_SLONG:
13986  *((SQLINTEGER *) val) = 0;
13987  break;
13988 #ifdef SQL_BIGINT
13989  case SQL_C_SBIGINT:
13990  case SQL_C_UBIGINT:
13991  *((SQLBIGINT *) val) = 0;
13992  break;
13993 #endif
13994  case SQL_C_FLOAT:
13995  *((float *) val) = 0;
13996  break;
13997  case SQL_C_DOUBLE:
13998  *((double *) val) = 0;
13999  break;
14000  case SQL_C_BINARY:
14001  case SQL_C_CHAR:
14002  if (len > 0) {
14003  *((SQLCHAR *) val) = '\0';
14004  }
14005  break;
14006 #ifdef WCHARSUPPORT
14007  case SQL_C_WCHAR:
14008  if (len > 0) {
14009  *((SQLWCHAR *) val) = '\0';
14010  }
14011  break;
14012 #endif
14013 #ifdef SQL_C_TYPE_DATE
14014  case SQL_C_TYPE_DATE:
14015 #endif
14016  case SQL_C_DATE:
14017  memset((DATE_STRUCT *) val, 0, sizeof (DATE_STRUCT));
14018  break;
14019 #ifdef SQL_C_TYPE_TIME
14020  case SQL_C_TYPE_TIME:
14021 #endif
14022  case SQL_C_TIME:
14023  memset((TIME_STRUCT *) val, 0, sizeof (TIME_STRUCT));
14024  break;
14025 #ifdef SQL_C_TYPE_TIMESTAMP
14026  case SQL_C_TYPE_TIMESTAMP:
14027 #endif
14028  case SQL_C_TIMESTAMP:
14029  memset((TIMESTAMP_STRUCT *) val, 0, sizeof (TIMESTAMP_STRUCT));
14030  break;
14031  default:
14032  return SQL_ERROR;
14033  }
14034  } else {
14035  char *endp = NULL;
14036 #if defined(_WIN32) || defined(_WIN64)
14037 #ifdef SQL_BIGINT
14038  char endc;
14039 #endif
14040 #endif
14041 
14042  switch (type) {
14043  case SQL_C_UTINYINT:
14044  case SQL_C_TINYINT:
14045  case SQL_C_STINYINT:
14046  *((SQLCHAR *) val) = strtol(*data, &endp, 0);
14047  if (endp && endp == *data) {
14048  *lenp = SQL_NULL_DATA;
14049  } else {
14050  *lenp = sizeof (SQLCHAR);
14051  }
14052  break;
14053 #ifdef SQL_BIT
14054  case SQL_C_BIT:
14055  *((SQLCHAR *) val) = getbool(*data);
14056  *lenp = sizeof (SQLCHAR);
14057  break;
14058 #endif
14059  case SQL_C_USHORT:
14060  case SQL_C_SHORT:
14061  case SQL_C_SSHORT:
14062  *((SQLSMALLINT *) val) = strtol(*data, &endp, 0);
14063  if (endp && endp == *data) {
14064  *lenp = SQL_NULL_DATA;
14065  } else {
14066  *lenp = sizeof (SQLSMALLINT);
14067  }
14068  break;
14069  case SQL_C_ULONG:
14070  case SQL_C_LONG:
14071  case SQL_C_SLONG:
14072  *((SQLINTEGER *) val) = strtol(*data, &endp, 0);
14073  if (endp && endp == *data) {
14074  *lenp = SQL_NULL_DATA;
14075  } else {
14076  *lenp = sizeof (SQLINTEGER);
14077  }
14078  break;
14079 #ifdef SQL_BIGINT
14080  case SQL_C_UBIGINT:
14081 #if defined(_WIN32) || defined(_WIN64)
14082  if (sscanf(*data, "%I64u%c", (SQLUBIGINT *) val, &endc) != 1) {
14083  *lenp = SQL_NULL_DATA;
14084  } else {
14085  *lenp = sizeof (SQLUBIGINT);
14086  }
14087 #else
14088 #ifdef __osf__
14089  *((SQLUBIGINT *) val) = strtoul(*data, &endp, 0);
14090 #else
14091  *((SQLUBIGINT *) val) = strtoull(*data, &endp, 0);
14092 #endif
14093  if (endp && endp == *data) {
14094  *lenp = SQL_NULL_DATA;
14095  } else {
14096  *lenp = sizeof (SQLUBIGINT);
14097  }
14098 #endif
14099  break;
14100  case SQL_C_SBIGINT:
14101 #if defined(_WIN32) || defined(_WIN64)
14102  if (sscanf(*data, "%I64d%c", (SQLBIGINT *) val, &endc) != 1) {
14103  *lenp = SQL_NULL_DATA;
14104  } else {
14105  *lenp = sizeof (SQLBIGINT);
14106  }
14107 #else
14108 #ifdef __osf__
14109  *((SQLBIGINT *) val) = strtol(*data, &endp, 0);
14110 #else
14111  *((SQLBIGINT *) val) = strtoll(*data, &endp, 0);
14112 #endif
14113  if (endp && endp == *data) {
14114  *lenp = SQL_NULL_DATA;
14115  } else {
14116  *lenp = sizeof (SQLBIGINT);
14117  }
14118 #endif
14119  break;
14120 #endif
14121  case SQL_C_FLOAT:
14122  *((float *) val) = ln_strtod(*data, &endp);
14123  if (endp && endp == *data) {
14124  *lenp = SQL_NULL_DATA;
14125  } else {
14126  *lenp = sizeof (float);
14127  }
14128  break;
14129  case SQL_C_DOUBLE:
14130  *((double *) val) = ln_strtod(*data, &endp);
14131  if (endp && endp == *data) {
14132  *lenp = SQL_NULL_DATA;
14133  } else {
14134  *lenp = sizeof (double);
14135  }
14136  break;
14137  case SQL_C_BINARY: {
14138  int dlen, offs = 0;
14139  char *bin;
14140 
14141  if (valnull) {
14142  freep(&s->bincache);
14143  s->binlen = 0;
14144  goto doCHAR;
14145  }
14146  if (*data == s->bincell) {
14147  if (s->bincache) {
14148  bin = s->bincache;
14149  dlen = s->binlen;
14150  } else {
14151  goto doCHAR;
14152  }
14153  } else {
14154  char *dp;
14155  int i;
14156 
14157  freep(&s->bincache);
14158  dp = *data;
14159  dlen = strlen(dp);
14160  s->bincell = dp;
14161  s->binlen = 0;
14162  if (!(dp[0] == 'x' || dp[0] == 'X') || dp[1] != '\'' ||
14163  dp[dlen - 1] != '\'') {
14164  goto doCHAR;
14165  }
14166  dlen -= 2;
14167  dp += 2;
14168  dlen = dlen / 2;
14169  s->bincache = bin = xmalloc(dlen + 1);
14170  if (!bin) {
14171  return nomem(s);
14172  }
14173  s->binlen = dlen;
14174  memset(bin, 0, dlen);
14175  bin[dlen] = '\0'; /* terminator, just in case */
14176  for (i = 0; i < dlen; i++) {
14177  char *x;
14178  int v;
14179 
14180  if (!*dp || !(x = strchr(xdigits, *dp))) {
14181  goto converr;
14182  }
14183  v = x - xdigits;
14184  bin[i] = (v >= 16) ? ((v - 6) << 4) : (v << 4);
14185  ++dp;
14186  if (!*dp || !(x = strchr(xdigits, *dp))) {
14187 converr:
14188  freep(&s->bincache);
14189  s->binlen = 0;
14190  setstat(s, -1, "conversion error",
14191  (*s->ov3) ? "HY000" : "S1000");
14192  return SQL_ERROR;
14193  }
14194  v = x - xdigits;
14195  bin[i] |= (v >= 16) ? (v - 6) : v;
14196  ++dp;
14197  }
14198  bin = s->bincache;
14199  }
14200  if (partial && len && s->bindcols) {
14201  if (s->bindcols[col].offs >= dlen) {
14202  *lenp = 0;
14203  if (!dlen && s->bindcols[col].offs == dlen) {
14204  s->bindcols[col].offs = 1;
14205  sret = SQL_SUCCESS;
14206  goto done;
14207  }
14208  s->bindcols[col].offs = 0;
14209  sret = SQL_NO_DATA;
14210  goto done;
14211  }
14212  offs = s->bindcols[col].offs;
14213  dlen -= offs;
14214  }
14215  if (val && len) {
14216  memcpy(val, bin + offs, min(len, dlen));
14217  }
14218  if (len < 1) {
14219  *lenp = dlen;
14220  } else {
14221  *lenp = min(len, dlen);
14222  if (*lenp == len && *lenp != dlen) {
14223  *lenp = SQL_NO_TOTAL;
14224  }
14225  }
14226  if (partial && len && s->bindcols) {
14227  if (*lenp == SQL_NO_TOTAL) {
14228  *lenp = dlen;
14229  s->bindcols[col].offs += len;
14230  setstat(s, -1, "data right truncated", "01004");
14231  if (s->bindcols[col].lenp) {
14232  *s->bindcols[col].lenp = dlen;
14233  }
14234  sret = SQL_SUCCESS_WITH_INFO;
14235  goto done;
14236  }
14237  s->bindcols[col].offs += *lenp;
14238  }
14239  if (*lenp == SQL_NO_TOTAL) {
14240  *lenp = dlen;
14241  setstat(s, -1, "data right truncated", "01004");
14242  sret = SQL_SUCCESS_WITH_INFO;
14243  goto done;
14244  }
14245  break;
14246  }
14247  doCHAR:
14248 #ifdef WCHARSUPPORT
14249  case SQL_C_WCHAR:
14250 #endif
14251  case SQL_C_CHAR: {
14252  int doz, zlen = len - 1;
14253  int dlen = strlen(*data);
14254  int offs = 0;
14255 #ifdef WCHARSUPPORT
14256  SQLWCHAR *ucdata = NULL;
14257  SQLCHAR *cdata = (SQLCHAR *) *data;
14258 #endif
14259 
14260 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
14261  /* MS Access hack part 2 (reserved error -7748) */
14262  if (!valnull &&
14263  (s->cols == statSpec2P || s->cols == statSpec3P) &&
14264  type == SQL_C_WCHAR) {
14265  if (len > 0 && len <= sizeof (SQLWCHAR)) {
14266  ((char *) val)[0] = data[0][0];
14267  memset((char *) val + 1, 0, len - 1);
14268  *lenp = 1;
14269  sret = SQL_SUCCESS;
14270  goto done;
14271  }
14272  }
14273 #endif
14274 
14275 #ifdef WCHARSUPPORT
14276  switch (type) {
14277  case SQL_C_CHAR:
14278  doz = 1;
14279  break;
14280  case SQL_C_WCHAR:
14281  doz = sizeof (SQLWCHAR);
14282  break;
14283  default:
14284  doz = 0;
14285  break;
14286  }
14287  if (type == SQL_C_WCHAR) {
14288  ucdata = uc_from_utf(cdata, dlen);
14289  if (!ucdata) {
14290  return nomem(s);
14291  }
14292  dlen = uc_strlen(ucdata) * sizeof (SQLWCHAR);
14293  }
14294 #if defined(_WIN32) || defined(_WIN64)
14295  else if (*s->oemcp && type == SQL_C_CHAR) {
14296  ucdata = (SQLWCHAR *) utf_to_wmb((char *) cdata, dlen);
14297  if (!ucdata) {
14298  return nomem(s);
14299  }
14300  cdata = (SQLCHAR *) ucdata;
14301  dlen = strlen((char *) cdata);
14302  }
14303 #endif
14304 #else
14305  doz = (type == SQL_C_CHAR) ? 1 : 0;
14306 #endif
14307  if (partial && len && s->bindcols) {
14308  if (s->bindcols[col].offs >= dlen) {
14309 #ifdef WCHARSUPPORT
14310  uc_free(ucdata);
14311 #endif
14312  *lenp = 0;
14313  if (doz && val) {
14314 #ifdef WCHARSUPPORT
14315  if (type == SQL_C_WCHAR) {
14316  ((SQLWCHAR *) val)[0] = 0;
14317  } else {
14318  ((char *) val)[0] = '\0';
14319  }
14320 #else
14321  ((char *) val)[0] = '\0';
14322 #endif
14323  }
14324  if (!dlen && s->bindcols[col].offs == dlen) {
14325  s->bindcols[col].offs = 1;
14326  sret = SQL_SUCCESS;
14327  goto done;
14328  }
14329  s->bindcols[col].offs = 0;
14330  sret = SQL_NO_DATA;
14331  goto done;
14332  }
14333  offs = s->bindcols[col].offs;
14334  dlen -= offs;
14335  }
14336  if (val && !valnull && len) {
14337 #ifdef WCHARSUPPORT
14338  if (type == SQL_C_WCHAR) {
14339  uc_strncpy(val, ucdata + offs / sizeof (SQLWCHAR),
14340  (len - doz) / sizeof (SQLWCHAR));
14341  } else {
14342  strncpy(val, (char *) cdata + offs, len - doz);
14343  }
14344 #else
14345  strncpy(val, *data + offs, len - doz);
14346 #endif
14347  }
14348  if (valnull || len < 1) {
14349  *lenp = dlen;
14350  } else {
14351  *lenp = min(len - doz, dlen);
14352  if (*lenp == len - doz && *lenp != dlen) {
14353  *lenp = SQL_NO_TOTAL;
14354  } else if (*lenp < zlen) {
14355  zlen = *lenp;
14356  }
14357  }
14358  if (len && !valnull && doz) {
14359 #ifdef WCHARSUPPORT
14360  if (type == SQL_C_WCHAR) {
14361  ((SQLWCHAR *) val)[zlen / sizeof (SQLWCHAR)] = 0;
14362  } else {
14363  ((char *) val)[zlen] = '\0';
14364  }
14365 #else
14366  ((char *) val)[zlen] = '\0';
14367 #endif
14368  }
14369 #ifdef WCHARSUPPORT
14370  uc_free(ucdata);
14371 #endif
14372  if (partial && len && s->bindcols) {
14373  if (*lenp == SQL_NO_TOTAL) {
14374  *lenp = dlen;
14375  s->bindcols[col].offs += len - doz;
14376  setstat(s, -1, "data right truncated", "01004");
14377  if (s->bindcols[col].lenp) {
14378  *s->bindcols[col].lenp = dlen;
14379  }
14380  sret = SQL_SUCCESS_WITH_INFO;
14381  goto done;
14382  }
14383  s->bindcols[col].offs += *lenp;
14384  }
14385  if (*lenp == SQL_NO_TOTAL) {
14386  *lenp = dlen;
14387  setstat(s, -1, "data right truncated", "01004");
14388  sret = SQL_SUCCESS_WITH_INFO;
14389  goto done;
14390  }
14391  break;
14392  }
14393 #ifdef SQL_C_TYPE_DATE
14394  case SQL_C_TYPE_DATE:
14395 #endif
14396  case SQL_C_DATE:
14397  if (str2date(*s->jdconv, *data, (DATE_STRUCT *) val) < 0) {
14398  *lenp = SQL_NULL_DATA;
14399  } else {
14400  *lenp = sizeof (DATE_STRUCT);
14401  }
14402  break;
14403 #ifdef SQL_C_TYPE_TIME
14404  case SQL_C_TYPE_TIME:
14405 #endif
14406  case SQL_C_TIME:
14407  if (str2time(*s->jdconv, *data, (TIME_STRUCT *) val) < 0) {
14408  *lenp = SQL_NULL_DATA;
14409  } else {
14410  *lenp = sizeof (TIME_STRUCT);
14411  }
14412  break;
14413 #ifdef SQL_C_TYPE_TIMESTAMP
14414  case SQL_C_TYPE_TIMESTAMP:
14415 #endif
14416  case SQL_C_TIMESTAMP:
14417  if (str2timestamp(*s->jdconv, *data,
14418  (TIMESTAMP_STRUCT *) val) < 0) {
14419  *lenp = SQL_NULL_DATA;
14420  } else {
14421  *lenp = sizeof (TIMESTAMP_STRUCT);
14422  }
14423  switch (s->cols[col].prec) {
14424  case 0:
14425  ((TIMESTAMP_STRUCT *) val)->fraction = 0;
14426  break;
14427  case 1:
14428  ((TIMESTAMP_STRUCT *) val)->fraction /= 100000000;
14429  ((TIMESTAMP_STRUCT *) val)->fraction *= 100000000;
14430  break;
14431  case 2:
14432  ((TIMESTAMP_STRUCT *) val)->fraction /= 10000000;
14433  ((TIMESTAMP_STRUCT *) val)->fraction *= 10000000;
14434  break;
14435  }
14436  break;
14437  default:
14438  return SQL_ERROR;
14439  }
14440  }
14441  sret = SQL_SUCCESS;
14442 done:
14443  if (ilenp) {
14444  *ilenp = *lenp;
14445  }
14446  return sret;
14447 }
14448 
14460 static SQLRETURN
14461 drvbindcol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14462  SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14463 {
14464  STMT *s;
14465  int sz = 0;
14466 
14467  if (stmt == SQL_NULL_HSTMT) {
14468  return SQL_INVALID_HANDLE;
14469  }
14470  s = (STMT *) stmt;
14471  if (col < 1) {
14472  if (col == 0 && s->bkmrk == SQL_UB_ON &&
14473  type == SQL_C_BOOKMARK) {
14474  s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14475  s->bkmrkcol.max = val ? sizeof (SQLINTEGER) : 0;
14476  s->bkmrkcol.lenp = val ? lenp : 0;
14477  s->bkmrkcol.valp = val;
14478  s->bkmrkcol.offs = 0;
14479  if (val && lenp) {
14480  *lenp = 0;
14481  }
14482  return SQL_SUCCESS;
14483  } else if (col == 0 && s->bkmrk == SQL_UB_VARIABLE &&
14484  type == SQL_C_VARBOOKMARK &&
14485  max >= sizeof (sqlite_int64)) {
14486  s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14487  s->bkmrkcol.max = val ? max : 0;
14488  s->bkmrkcol.lenp = val ? lenp : 0;
14489  s->bkmrkcol.valp = val;
14490  s->bkmrkcol.offs = 0;
14491  if (val && lenp) {
14492  *lenp = 0;
14493  }
14494  return SQL_SUCCESS;
14495  }
14496  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
14497  return SQL_ERROR;
14498  }
14499  if (mkbindcols(s, col) != SQL_SUCCESS) {
14500  return SQL_ERROR;
14501  }
14502  --col;
14503  if (type == SQL_C_DEFAULT) {
14504  type = mapdeftype(type, s->cols[col].type, 0,
14505  s->nowchar[0] || s->nowchar[1]);
14506  }
14507  switch (type) {
14508  case SQL_C_LONG:
14509  case SQL_C_ULONG:
14510  case SQL_C_SLONG:
14511  sz = sizeof (SQLINTEGER);
14512  break;
14513  case SQL_C_TINYINT:
14514  case SQL_C_UTINYINT:
14515  case SQL_C_STINYINT:
14516  sz = sizeof (SQLCHAR);
14517  break;
14518  case SQL_C_SHORT:
14519  case SQL_C_USHORT:
14520  case SQL_C_SSHORT:
14521  sz = sizeof (SQLSMALLINT);
14522  break;
14523  case SQL_C_FLOAT:
14524  sz = sizeof (SQLFLOAT);
14525  break;
14526  case SQL_C_DOUBLE:
14527  sz = sizeof (SQLDOUBLE);
14528  break;
14529  case SQL_C_TIMESTAMP:
14530  sz = sizeof (SQL_TIMESTAMP_STRUCT);
14531  break;
14532  case SQL_C_TIME:
14533  sz = sizeof (SQL_TIME_STRUCT);
14534  break;
14535  case SQL_C_DATE:
14536  sz = sizeof (SQL_DATE_STRUCT);
14537  break;
14538  case SQL_C_CHAR:
14539  break;
14540 #ifdef WCHARSUPPORT
14541  case SQL_C_WCHAR:
14542  break;
14543 #endif
14544 #ifdef SQL_C_TYPE_DATE
14545  case SQL_C_TYPE_DATE:
14546  sz = sizeof (SQL_DATE_STRUCT);
14547  break;
14548 #endif
14549 #ifdef SQL_C_TYPE_TIME
14550  case SQL_C_TYPE_TIME:
14551  sz = sizeof (SQL_TIME_STRUCT);
14552  break;
14553 #endif
14554 #ifdef SQL_C_TYPE_TIMESTAMP
14555  case SQL_C_TYPE_TIMESTAMP:
14556  sz = sizeof (SQL_TIMESTAMP_STRUCT);
14557  break;
14558 #endif
14559 #ifdef SQL_BIT
14560  case SQL_C_BIT:
14561  sz = sizeof (SQLCHAR);
14562  break;
14563 #endif
14564  case SQL_C_BINARY:
14565  break;
14566 #ifdef SQL_BIGINT
14567  case SQL_C_SBIGINT:
14568  case SQL_C_UBIGINT:
14569  sz = sizeof (SQLBIGINT);
14570  break;
14571 #endif
14572  default:
14573  if (val == NULL) {
14574  /* fall through, unbinding column */
14575  break;
14576  }
14577  setstat(s, -1, "invalid type %d", "HY003", type);
14578  return SQL_ERROR;
14579  }
14580  if (val == NULL) {
14581  /* unbind column */
14582  s->bindcols[col].type = SQL_UNKNOWN_TYPE;
14583  s->bindcols[col].max = 0;
14584  s->bindcols[col].lenp = NULL;
14585  s->bindcols[col].valp = NULL;
14586  s->bindcols[col].offs = 0;
14587  } else {
14588  if (sz == 0 && max < 0) {
14589  setstat(s, -1, "invalid length", "HY090");
14590  return SQL_ERROR;
14591  }
14592  s->bindcols[col].type = type;
14593  s->bindcols[col].max = (sz == 0) ? max : sz;
14594  s->bindcols[col].lenp = lenp;
14595  s->bindcols[col].valp = val;
14596  s->bindcols[col].offs = 0;
14597  if (lenp) {
14598  *lenp = 0;
14599  }
14600  }
14601  return SQL_SUCCESS;
14602 }
14603 
14615 SQLRETURN SQL_API
14616 SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14617  SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14618 {
14619  SQLRETURN ret;
14620 
14621  HSTMT_LOCK(stmt);
14622  ret = drvbindcol(stmt, col, type, val, max, lenp);
14623  HSTMT_UNLOCK(stmt);
14624  return ret;
14625 }
14626 
14631 static COL tableSpec2[] = {
14632  { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
14633  { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
14634  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14635  { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14636  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14637 };
14638 
14639 static COL tableSpec3[] = {
14640  { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
14641  { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
14642  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14643  { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14644  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14645 };
14646 
14661 static SQLRETURN
14662 drvtables(SQLHSTMT stmt,
14663  SQLCHAR *cat, SQLSMALLINT catLen,
14664  SQLCHAR *schema, SQLSMALLINT schemaLen,
14665  SQLCHAR *table, SQLSMALLINT tableLen,
14666  SQLCHAR *type, SQLSMALLINT typeLen)
14667 {
14668  SQLRETURN ret;
14669  STMT *s;
14670  DBC *d;
14671  int ncols, asize, rc, size, npatt;
14672  char *errp = NULL, *sql, tname[512];
14673  char *where = "(type = 'table' or type = 'view')";
14674 
14676  tableSpec3, array_size(tableSpec3), &asize);
14677  if (ret != SQL_SUCCESS) {
14678  return ret;
14679  }
14680  s = (STMT *) stmt;
14681  d = (DBC *) s->dbc;
14682  if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] == '%') {
14683  int size = 3 * asize;
14684 
14685  s->rows = xmalloc(size * sizeof (char *));
14686  if (!s->rows) {
14687  s->nrows = 0;
14688  return nomem(s);
14689  }
14690  memset(s->rows, 0, sizeof (char *) * size);
14691  s->ncols = asize;
14692  s->rows[s->ncols + 0] = "";
14693  s->rows[s->ncols + 1] = "";
14694  s->rows[s->ncols + 2] = "";
14695  s->rows[s->ncols + 3] = "TABLE";
14696  s->rows[s->ncols + 5] = "";
14697  s->rows[s->ncols + 6] = "";
14698  s->rows[s->ncols + 7] = "";
14699  s->rows[s->ncols + 8] = "VIEW";
14700 #ifdef MEMORY_DEBUG
14701  s->rowfree = xfree__;
14702 #else
14703  s->rowfree = sqlite3_free;
14704 #endif
14705  s->nrows = 2;
14706  s->rowp = s->rowprs = -1;
14707  return SQL_SUCCESS;
14708  }
14709  if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
14710  table = NULL;
14711  goto doit;
14712  }
14713  if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
14714  schema[0] == '%') {
14715  if ((!cat || catLen == 0 || !cat[0]) &&
14716  (!table || tableLen == 0 || !table[0])) {
14717  table = NULL;
14718  goto doit;
14719  }
14720  }
14721  if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] != '\0') {
14722  char tmp[256], *t;
14723  int with_view = 0, with_table = 0;
14724 
14725  if (typeLen == SQL_NTS) {
14726  strncpy(tmp, (char *) type, sizeof (tmp));
14727  tmp[sizeof (tmp) - 1] = '\0';
14728  } else {
14729  int len = min(sizeof (tmp) - 1, typeLen);
14730 
14731  strncpy(tmp, (char *) type, len);
14732  tmp[len] = '\0';
14733  }
14734  t = tmp;
14735  while (*t) {
14736  *t = TOLOWER(*t);
14737  t++;
14738  }
14739  t = tmp;
14740  unescpat(t);
14741  while (t) {
14742  if (t[0] == '\'') {
14743  ++t;
14744  }
14745  if (strncmp(t, "table", 5) == 0) {
14746  with_table++;
14747  } else if (strncmp(t, "view", 4) == 0) {
14748  with_view++;
14749  }
14750  t = strchr(t, ',');
14751  if (t) {
14752  ++t;
14753  }
14754  }
14755  if (with_view && with_table) {
14756  /* where is already preset */
14757  } else if (with_view && !with_table) {
14758  where = "type = 'view'";
14759  } else if (!with_view && with_table) {
14760  where = "type = 'table'";
14761  } else {
14762  return SQL_SUCCESS;
14763  }
14764  }
14765 doit:
14766  if (!table) {
14767  size = 1;
14768  tname[0] = '%';
14769  } else {
14770  if (tableLen == SQL_NTS) {
14771  size = sizeof (tname) - 1;
14772  } else {
14773  size = min(sizeof (tname) - 1, tableLen);
14774  }
14775  strncpy(tname, (char *) table, size);
14776  }
14777  tname[size] = '\0';
14778  npatt = unescpat(tname);
14779 #if defined(_WIN32) || defined(_WIN64)
14780  if (npatt) {
14781  sql = sqlite3_mprintf("select %s as 'TABLE_CAT', "
14782  "%s as 'TABLE_SCHEM', "
14783  "tbl_name as 'TABLE_NAME', "
14784  "upper(type) as 'TABLE_TYPE', "
14785  "NULL as 'REMARKS' "
14786  "from sqlite_master where %s "
14787  "and tbl_name like %Q",
14788  d->xcelqrx ? "'main'" : "NULL",
14789  d->xcelqrx ? "''" : "NULL",
14790  where, tname);
14791  } else {
14792  sql = sqlite3_mprintf("select %s as 'TABLE_CAT', "
14793  "%s as 'TABLE_SCHEM', "
14794  "tbl_name as 'TABLE_NAME', "
14795  "upper(type) as 'TABLE_TYPE', "
14796  "NULL as 'REMARKS' "
14797  "from sqlite_master where %s "
14798  "and lower(tbl_name) = lower(%Q)",
14799  d->xcelqrx ? "'main'" : "NULL",
14800  d->xcelqrx ? "''" : "NULL",
14801  where, tname);
14802  }
14803 #else
14804  if (npatt) {
14805  sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
14806  "NULL as 'TABLE_OWNER', "
14807  "tbl_name as 'TABLE_NAME', "
14808  "upper(type) as 'TABLE_TYPE', "
14809  "NULL as 'REMARKS' "
14810  "from sqlite_master where %s "
14811  "and tbl_name like %Q",
14812  where, tname);
14813  } else {
14814  sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
14815  "NULL as 'TABLE_OWNER', "
14816  "tbl_name as 'TABLE_NAME', "
14817  "upper(type) as 'TABLE_TYPE', "
14818  "NULL as 'REMARKS' "
14819  "from sqlite_master where %s "
14820  "and lower(tbl_name) = lower(%Q)",
14821  where, tname);
14822  }
14823 #endif
14824  if (!sql) {
14825  return nomem(s);
14826  }
14827  ret = starttran(s);
14828  if (ret != SQL_SUCCESS) {
14829  sqlite3_free(sql);
14830  return ret;
14831  }
14832  dbtraceapi(d, "sqlite3_get_table", sql);
14833  rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
14834  sqlite3_free(sql);
14835  if (rc == SQLITE_OK) {
14836  if (ncols != s->ncols) {
14837  freeresult(s, 0);
14838  s->nrows = 0;
14839  } else {
14840  s->rowfree = sqlite3_free_table;
14841  }
14842  } else {
14843  s->nrows = 0;
14844  s->rows = NULL;
14845  s->rowfree = NULL;
14846  }
14847  if (errp) {
14848  sqlite3_free(errp);
14849  errp = NULL;
14850  }
14851  s->rowp = s->rowprs = -1;
14852  return SQL_SUCCESS;
14853 }
14854 
14855 #ifndef WINTERFACE
14856 
14870 SQLRETURN SQL_API
14871 SQLTables(SQLHSTMT stmt,
14872  SQLCHAR *cat, SQLSMALLINT catLen,
14873  SQLCHAR *schema, SQLSMALLINT schemaLen,
14874  SQLCHAR *table, SQLSMALLINT tableLen,
14875  SQLCHAR *type, SQLSMALLINT typeLen)
14876 {
14877 #if defined(_WIN32) || defined(_WIN64)
14878  char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
14879 #endif
14880  SQLRETURN ret;
14881 
14882  HSTMT_LOCK(stmt);
14883 #if defined(_WIN32) || defined(_WIN64)
14884  if (!((STMT *) stmt)->oemcp[0]) {
14885  ret = drvtables(stmt, cat, catLen, schema, schemaLen,
14886  table, tableLen, type, typeLen);
14887  goto done2;
14888  }
14889  if (cat) {
14890  c = wmb_to_utf_c((char *) cat, catLen);
14891  if (!c) {
14892  ret = nomem((STMT *) stmt);
14893  goto done;
14894  }
14895  }
14896  if (schema) {
14897  s = wmb_to_utf_c((char *) schema, schemaLen);
14898  if (!s) {
14899  ret = nomem((STMT *) stmt);
14900  goto done;
14901  }
14902  }
14903  if (table) {
14904  t = wmb_to_utf_c((char *) table, tableLen);
14905  if (!t) {
14906  ret = nomem((STMT *) stmt);
14907  goto done;
14908  }
14909  }
14910  if (type) {
14911  y = wmb_to_utf_c((char *) type, typeLen);
14912  if (!y) {
14913  ret = nomem((STMT *) stmt);
14914  goto done;
14915  }
14916  }
14917  ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
14918  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
14919 #else
14920  ret = drvtables(stmt, cat, catLen, schema, schemaLen,
14921  table, tableLen, type, typeLen);
14922 #endif
14923 #if defined(_WIN32) || defined(_WIN64)
14924 done:
14925  uc_free(y);
14926  uc_free(t);
14927  uc_free(s);
14928  uc_free(c);
14929 done2:
14930  ;
14931 #endif
14932  HSTMT_UNLOCK(stmt);
14933  return ret;
14934 }
14935 #endif
14936 
14937 #ifdef WINTERFACE
14938 
14952 SQLRETURN SQL_API
14953 SQLTablesW(SQLHSTMT stmt,
14954  SQLWCHAR *cat, SQLSMALLINT catLen,
14955  SQLWCHAR *schema, SQLSMALLINT schemaLen,
14956  SQLWCHAR *table, SQLSMALLINT tableLen,
14957  SQLWCHAR *type, SQLSMALLINT typeLen)
14958 {
14959  char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
14960  SQLRETURN ret;
14961 
14962  HSTMT_LOCK(stmt);
14963  if (cat) {
14964  c = uc_to_utf_c(cat, catLen);
14965  if (!c) {
14966  ret = nomem((STMT *) stmt);
14967  goto done;
14968  }
14969  }
14970  if (schema) {
14971  s = uc_to_utf_c(schema, schemaLen);
14972  if (!s) {
14973  ret = nomem((STMT *) stmt);
14974  goto done;
14975  }
14976  }
14977  if (table) {
14978  t = uc_to_utf_c(table, tableLen);
14979  if (!t) {
14980  ret = nomem((STMT *) stmt);
14981  goto done;
14982  }
14983  }
14984  if (type) {
14985  y = uc_to_utf_c(type, typeLen);
14986  if (!y) {
14987  ret = nomem((STMT *) stmt);
14988  goto done;
14989  }
14990  }
14991  ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
14992  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
14993 done:
14994  uc_free(y);
14995  uc_free(t);
14996  uc_free(s);
14997  uc_free(c);
14998  HSTMT_UNLOCK(stmt);
14999  return ret;
15000 }
15001 #endif
15002 
15007 static COL colSpec2[] = {
15008  { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
15009  { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
15010  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
15011  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15012  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
15013  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
15014  { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
15015  { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
15016  { "SYSTEM", "COLUMN", "SCALE", SQL_SMALLINT, 50 },
15017  { "SYSTEM", "COLUMN", "RADIX", SQL_SMALLINT, 50 },
15018  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
15019  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
15020  { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
15021  { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
15022  { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
15023  { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
15024  { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
15025  { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
15026 };
15027 
15028 static COL colSpec3[] = {
15029  { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
15030  { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
15031  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
15032  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15033  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
15034  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
15035  { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
15036  { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
15037  { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_SMALLINT, 50 },
15038  { "SYSTEM", "COLUMN", "NUM_PREC_RADIX", SQL_SMALLINT, 50 },
15039  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
15040  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
15041  { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
15042  { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
15043  { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
15044  { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
15045  { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
15046  { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
15047 };
15048 
15063 static SQLRETURN
15064 drvcolumns(SQLHSTMT stmt,
15065  SQLCHAR *cat, SQLSMALLINT catLen,
15066  SQLCHAR *schema, SQLSMALLINT schemaLen,
15067  SQLCHAR *table, SQLSMALLINT tableLen,
15068  SQLCHAR *col, SQLSMALLINT colLen)
15069 {
15070  SQLRETURN sret;
15071  STMT *s;
15072  DBC *d;
15073  int ret, nrows, ncols, asize, i, k, roffs, namec;
15074  int tnrows, tncols, npatt;
15075  PTRDIFF_T size;
15076  char *errp = NULL, *sql, tname[512], cname[512], **rowp, **trows;
15077 
15079  colSpec3, array_size(colSpec3), &asize);
15080  if (sret != SQL_SUCCESS) {
15081  return sret;
15082  }
15083  s = (STMT *) stmt;
15084  d = (DBC *) s->dbc;
15085  if (!table) {
15086  size = 1;
15087  tname[0] = '%';
15088  } else {
15089  if (tableLen == SQL_NTS) {
15090  size = sizeof (tname) - 1;
15091  } else {
15092  size = min(sizeof (tname) - 1, tableLen);
15093  }
15094  strncpy(tname, (char *) table, size);
15095  }
15096  tname[size] = '\0';
15097  npatt = unescpat(tname);
15098  size = 0;
15099  if (col) {
15100  if (colLen == SQL_NTS) {
15101  size = sizeof (cname) - 1;
15102  } else {
15103  size = min(sizeof (cname) - 1, colLen);
15104  }
15105  strncpy(cname, (char *) col, size);
15106  }
15107  cname[size] = '\0';
15108  if (!strcmp(cname, "%")) {
15109  cname[0] = '\0';
15110  }
15111  if (npatt) {
15112  sql = sqlite3_mprintf("select tbl_name from sqlite_master where "
15113  "(type = 'table' or type = 'view') "
15114  "and tbl_name like %Q", tname);
15115  } else {
15116  sql = sqlite3_mprintf("select tbl_name from sqlite_master where "
15117  "(type = 'table' or type = 'view') "
15118  "and lower(tbl_name) = lower(%Q)", tname);
15119  }
15120  if (!sql) {
15121  return nomem(s);
15122  }
15123  sret = starttran(s);
15124  if (sret != SQL_SUCCESS) {
15125  sqlite3_free(sql);
15126  return sret;
15127  }
15128  dbtraceapi(d, "sqlite3_get_table", sql);
15129  ret = sqlite3_get_table(d->sqlite, sql, &trows, &tnrows, &tncols, &errp);
15130  sqlite3_free(sql);
15131  if (ret != SQLITE_OK) {
15132  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15133  errp ? errp : "unknown error", ret);
15134  if (errp) {
15135  sqlite3_free(errp);
15136  errp = NULL;
15137  }
15138  return SQL_ERROR;
15139  }
15140  if (errp) {
15141  sqlite3_free(errp);
15142  errp = NULL;
15143  }
15144  /* pass 1: compute number of rows of result set */
15145  if (tncols * tnrows <= 0) {
15146  sqlite3_free_table(trows);
15147  return SQL_SUCCESS;
15148  }
15149  size = 0;
15150  for (i = 1; i <= tnrows; i++) {
15151  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
15152  if (!sql) {
15153  sqlite3_free_table(trows);
15154  return nomem(s);
15155  }
15156  dbtraceapi(d, "sqlite3_get_table", sql);
15157  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15158  sqlite3_free(sql);
15159  if (ret != SQLITE_OK) {
15160  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15161  errp ? errp : "unknown error", ret);
15162  if (errp) {
15163  sqlite3_free(errp);
15164  errp = NULL;
15165  }
15166  sqlite3_free_table(trows);
15167  return SQL_ERROR;
15168  }
15169  if (errp) {
15170  sqlite3_free(errp);
15171  errp = NULL;
15172  }
15173  if (ncols * nrows > 0) {
15174  namec = -1;
15175  for (k = 0; k < ncols; k++) {
15176  if (strcmp(rowp[k], "name") == 0) {
15177  namec = k;
15178  break;
15179  }
15180  }
15181  if (cname[0]) {
15182  if (namec >= 0) {
15183  for (k = 1; k <= nrows; k++) {
15184  if (namematch(rowp[k * ncols + namec], cname, 1)) {
15185  size++;
15186  }
15187  }
15188  }
15189  } else {
15190  size += nrows;
15191  }
15192  }
15193  sqlite3_free_table(rowp);
15194  }
15195  /* pass 2: fill result set */
15196  if (size <= 0) {
15197  sqlite3_free_table(trows);
15198  return SQL_SUCCESS;
15199  }
15200  s->nrows = size;
15201  size = (size + 1) * asize;
15202  s->rows = xmalloc((size + 1) * sizeof (char *));
15203  if (!s->rows) {
15204  s->nrows = 0;
15205  sqlite3_free_table(trows);
15206  return nomem(s);
15207  }
15208  s->rows[0] = (char *) size;
15209  s->rows += 1;
15210  memset(s->rows, 0, sizeof (char *) * size);
15211  s->rowfree = freerows;
15212  roffs = 1;
15213  for (i = 1; i <= tnrows; i++) {
15214  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
15215  if (!sql) {
15216  sqlite3_free_table(trows);
15217  return nomem(s);
15218  }
15219  dbtraceapi(d, "sqlite3_get_table", sql);
15220  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15221  sqlite3_free(sql);
15222  if (ret != SQLITE_OK) {
15223  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15224  errp ? errp : "unknown error", ret);
15225  if (errp) {
15226  sqlite3_free(errp);
15227  errp = NULL;
15228  }
15229  sqlite3_free_table(trows);
15230  return SQL_ERROR;
15231  }
15232  if (errp) {
15233  sqlite3_free(errp);
15234  errp = NULL;
15235  }
15236  if (ncols * nrows > 0) {
15237  int m, mr, nr = nrows;
15238 
15239  namec = -1;
15240  for (k = 0; k < ncols; k++) {
15241  if (strcmp(rowp[k], "name") == 0) {
15242  namec = k;
15243  break;
15244  }
15245  }
15246  if (cname[0]) {
15247  nr = 0;
15248  if (namec >= 0) {
15249  for (k = 1; k <= nrows; k++) {
15250  if (namematch(rowp[k * ncols + namec], cname, 1)) {
15251  nr++;
15252  }
15253  }
15254  }
15255  }
15256  for (k = 0; k < nr; k++) {
15257  m = asize * (roffs + k);
15258 #if defined(_WIN32) || defined(_WIN64)
15259  s->rows[m + 0] = xstrdup(d->xcelqrx ? "main" : "");
15260  s->rows[m + 1] = xstrdup("");
15261 #else
15262  s->rows[m + 0] = xstrdup("");
15263  s->rows[m + 1] = xstrdup("");
15264 #endif
15265  s->rows[m + 2] = xstrdup(trows[i]);
15266  s->rows[m + 8] = xstrdup("10");
15267  s->rows[m + 9] = xstrdup("0");
15268  s->rows[m + 15] = xstrdup("16384");
15269  }
15270  for (k = 0; nr && k < ncols; k++) {
15271  if (strcmp(rowp[k], "cid") == 0) {
15272  for (mr = 0, m = 1; m <= nrows; m++) {
15273  char buf[256];
15274  int ir, coln = k;
15275 
15276  if (cname[0] &&
15277  !namematch(rowp[m * ncols + namec], cname, 1)) {
15278  continue;
15279  }
15280  ir = asize * (roffs + mr);
15281  sscanf(rowp[m * ncols + k], "%d", &coln);
15282  sprintf(buf, "%d", coln + 1);
15283  s->rows[ir + 16] = xstrdup(buf);
15284  ++mr;
15285  }
15286  } else if (k == namec) {
15287  for (mr = 0, m = 1; m <= nrows; m++) {
15288  int ir;
15289 
15290  if (cname[0] &&
15291  !namematch(rowp[m * ncols + namec], cname, 1)) {
15292  continue;
15293  }
15294  ir = asize * (roffs + mr);
15295  s->rows[ir + 3] = xstrdup(rowp[m * ncols + k]);
15296  ++mr;
15297  }
15298  } else if (strcmp(rowp[k], "notnull") == 0) {
15299  for (mr = 0, m = 1; m <= nrows; m++) {
15300  int ir;
15301 
15302  if (cname[0] &&
15303  !namematch(rowp[m * ncols + namec], cname, 1)) {
15304  continue;
15305  }
15306  ir = asize * (roffs + mr);
15307  if (*rowp[m * ncols + k] != '0') {
15308  s->rows[ir + 10] = xstrdup(stringify(SQL_FALSE));
15309  } else {
15310  s->rows[ir + 10] = xstrdup(stringify(SQL_TRUE));
15311  }
15312  s->rows[ir + 17] =
15313  xstrdup((*rowp[m * ncols + k] != '0') ?
15314  "NO" : "YES");
15315  ++mr;
15316  }
15317  } else if (strcmp(rowp[k], "dflt_value") == 0) {
15318  for (mr = 0, m = 1; m <= nrows; m++) {
15319  char *dflt = unquote(rowp[m * ncols + k]);
15320  int ir;
15321 
15322  if (cname[0] &&
15323  !namematch(rowp[m * ncols + namec], cname, 1)) {
15324  continue;
15325  }
15326  ir = asize * (roffs + mr);
15327  s->rows[ir + 12] = xstrdup(dflt ? dflt : "NULL");
15328  ++mr;
15329  }
15330  } else if (strcmp(rowp[k], "type") == 0) {
15331  for (mr = 0, m = 1; m <= nrows; m++) {
15332  char *typename = rowp[m * ncols + k];
15333  int sqltype, mm, dd, ir;
15334  char buf[256];
15335 
15336  if (cname[0] &&
15337  !namematch(rowp[m * ncols + namec], cname, 1)) {
15338  continue;
15339  }
15340  ir = asize * (roffs + mr);
15341  s->rows[ir + 5] = xstrdup(typename);
15342  sqltype = mapsqltype(typename, NULL, *s->ov3,
15343  s->nowchar[0], s->dobigint);
15344  getmd(typename, sqltype, &mm, &dd);
15345 #ifdef SQL_LONGVARCHAR
15346  if (sqltype == SQL_VARCHAR && mm > 255) {
15347  sqltype = SQL_LONGVARCHAR;
15348  }
15349 #endif
15350 #ifdef WINTERFACE
15351 #ifdef SQL_WLONGVARCHAR
15352  if (sqltype == SQL_WVARCHAR && mm > 255) {
15353  sqltype = SQL_WLONGVARCHAR;
15354  }
15355 #endif
15356 #endif
15357  if (sqltype == SQL_VARBINARY && mm > 255) {
15358  sqltype = SQL_LONGVARBINARY;
15359  }
15360  sprintf(buf, "%d", sqltype);
15361  s->rows[ir + 4] = xstrdup(buf);
15362  s->rows[ir + 13] = xstrdup(buf);
15363  sprintf(buf, "%d", mm);
15364  s->rows[ir + 7] = xstrdup(buf);
15365  sprintf(buf, "%d", dd);
15366  s->rows[ir + 6] = xstrdup(buf);
15367  ++mr;
15368  }
15369  }
15370  }
15371  roffs += nr;
15372  }
15373  sqlite3_free_table(rowp);
15374  }
15375  sqlite3_free_table(trows);
15376  return SQL_SUCCESS;
15377 }
15378 
15379 #ifndef WINTERFACE
15380 
15394 SQLRETURN SQL_API
15395 SQLColumns(SQLHSTMT stmt,
15396  SQLCHAR *cat, SQLSMALLINT catLen,
15397  SQLCHAR *schema, SQLSMALLINT schemaLen,
15398  SQLCHAR *table, SQLSMALLINT tableLen,
15399  SQLCHAR *col, SQLSMALLINT colLen)
15400 {
15401 #if defined(_WIN32) || defined(_WIN64)
15402  char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15403 #endif
15404  SQLRETURN ret;
15405 
15406  HSTMT_LOCK(stmt);
15407 #if defined(_WIN32) || defined(_WIN64)
15408  if (!((STMT *) stmt)->oemcp[0]) {
15409  ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15410  table, tableLen, col, colLen);
15411  goto done2;
15412  }
15413  if (cat) {
15414  c = wmb_to_utf_c((char *) cat, catLen);
15415  if (!c) {
15416  ret = nomem((STMT *) stmt);
15417  goto done;
15418  }
15419  }
15420  if (schema) {
15421  s = wmb_to_utf_c((char *) schema, schemaLen);
15422  if (!s) {
15423  ret = nomem((STMT *) stmt);
15424  goto done;
15425  }
15426  }
15427  if (table) {
15428  t = wmb_to_utf_c((char *) table, tableLen);
15429  if (!t) {
15430  ret = nomem((STMT *) stmt);
15431  goto done;
15432  }
15433  }
15434  if (col) {
15435  k = wmb_to_utf_c((char *) col, colLen);
15436  if (!k) {
15437  ret = nomem((STMT *) stmt);
15438  goto done;
15439  }
15440  }
15441  ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15442  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15443 #else
15444  ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15445  table, tableLen, col, colLen);
15446 #endif
15447 #if defined(_WIN32) || defined(_WIN64)
15448 done:
15449  uc_free(k);
15450  uc_free(t);
15451  uc_free(s);
15452  uc_free(c);
15453 done2:
15454  ;
15455 #endif
15456  HSTMT_UNLOCK(stmt);
15457  return ret;
15458 }
15459 #endif
15460 
15461 #ifdef WINTERFACE
15462 
15476 SQLRETURN SQL_API
15478  SQLWCHAR *cat, SQLSMALLINT catLen,
15479  SQLWCHAR *schema, SQLSMALLINT schemaLen,
15480  SQLWCHAR *table, SQLSMALLINT tableLen,
15481  SQLWCHAR *col, SQLSMALLINT colLen)
15482 {
15483  char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15484  SQLRETURN ret;
15485 
15486  HSTMT_LOCK(stmt);
15487  if (cat) {
15488  c = uc_to_utf_c(cat, catLen);
15489  if (!c) {
15490  ret = nomem((STMT *) stmt);
15491  goto done;
15492  }
15493  }
15494  if (schema) {
15495  s = uc_to_utf_c(schema, schemaLen);
15496  if (!s) {
15497  ret = nomem((STMT *) stmt);
15498  goto done;
15499  }
15500  }
15501  if (table) {
15502  t = uc_to_utf_c(table, tableLen);
15503  if (!t) {
15504  ret = nomem((STMT *) stmt);
15505  goto done;
15506  }
15507  }
15508  if (col) {
15509  k = uc_to_utf_c(col, colLen);
15510  if (!k) {
15511  ret = nomem((STMT *) stmt);
15512  goto done;
15513  }
15514  }
15515  ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15516  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15517 done:
15518  uc_free(k);
15519  uc_free(t);
15520  uc_free(s);
15521  uc_free(c);
15522  HSTMT_UNLOCK(stmt);
15523  return ret;
15524 
15525 }
15526 #endif
15527 
15532 static COL typeSpec2[] = {
15533  { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15534  { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15535  { "SYSTEM", "TYPE", "PRECISION", SQL_INTEGER, 9 },
15536  { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15537  { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15538  { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15539  { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15540  { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15541  { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15542  { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15543  { "SYSTEM", "TYPE", "MONEY", SQL_SMALLINT, 2 },
15544  { "SYSTEM", "TYPE", "AUTO_INCREMENT", SQL_SMALLINT, 2 },
15545  { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15546  { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15547  { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 }
15548 };
15549 
15550 static COL typeSpec3[] = {
15551  { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15552  { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15553  { "SYSTEM", "TYPE", "COLUMN_SIZE", SQL_INTEGER, 9 },
15554  { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15555  { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15556  { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15557  { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15558  { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15559  { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15560  { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15561  { "SYSTEM", "TYPE", "FIXED_PREC_SCALE", SQL_SMALLINT, 2 },
15562  { "SYSTEM", "TYPE", "AUTO_UNIQUE_VALUE", SQL_SMALLINT, 2 },
15563  { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15564  { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15565  { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 },
15566  { "SYSTEM", "TYPE", "SQL_DATA_TYPE", SQL_SMALLINT, 2 },
15567  { "SYSTEM", "TYPE", "SQL_DATETIME_SUB", SQL_SMALLINT, 2 },
15568  { "SYSTEM", "TYPE", "NUM_PREC_RADIX", SQL_INTEGER, 4 },
15569  { "SYSTEM", "TYPE", "INTERVAL_PRECISION", SQL_SMALLINT, 2 }
15570 };
15571 
15582 static void
15583 mktypeinfo(STMT *s, int row, int asize, char *typename, int type, int tind)
15584 {
15585  int offs = row * asize;
15586  char *tcode, *crpar = NULL, *sign = stringify(SQL_FALSE);
15587  char *quote[2] = { NULL, NULL };
15588  static char tcodes[32 * 32];
15589 
15590  if (tind <= 0) {
15591  tind = row;
15592  }
15593  tcode = tcodes + tind * 32;
15594  sprintf(tcode, "%d", type);
15595  s->rows[offs + 0] = typename;
15596  s->rows[offs + 1] = tcode;
15597  if (asize >= 17) {
15598  s->rows[offs + 15] = tcode;
15599  s->rows[offs + 16] = "0";
15600  }
15601  switch (type) {
15602  default:
15603 #ifdef SQL_LONGVARCHAR
15604  case SQL_LONGVARCHAR:
15605 #ifdef WINTERFACE
15606  case SQL_WLONGVARCHAR:
15607 #endif
15608  crpar = "length";
15609  quote[0] = quote[1] = "'";
15610  sign = NULL;
15611  s->rows[offs + 2] = "65536";
15612  break;
15613 #endif
15614 #ifdef SQL_BIT
15615  case SQL_BIT:
15616  sign = NULL;
15617  s->rows[offs + 2] = "1";
15618  break;
15619 #endif
15620  case SQL_CHAR:
15621  case SQL_VARCHAR:
15622 #ifdef WINTERFACE
15623  case SQL_WCHAR:
15624  case SQL_WVARCHAR:
15625 #endif
15626  s->rows[offs + 2] = "255";
15627  crpar = "length";
15628  quote[0] = quote[1] = "'";
15629  sign = NULL;
15630  break;
15631  case SQL_TINYINT:
15632  s->rows[offs + 2] = "3";
15633  break;
15634  case SQL_SMALLINT:
15635  s->rows[offs + 2] = "5";
15636  break;
15637  case SQL_INTEGER:
15638  s->rows[offs + 2] = "9";
15639  break;
15640 #ifdef SQL_BIGINT
15641  case SQL_BIGINT:
15642  s->rows[offs + 2] = "19";
15643  break;
15644 #endif
15645  case SQL_FLOAT:
15646  s->rows[offs + 2] = "7";
15647  break;
15648  case SQL_DOUBLE:
15649  s->rows[offs + 2] = "15";
15650  break;
15651 #ifdef SQL_TYPE_DATE
15652  case SQL_TYPE_DATE:
15653 #endif
15654  case SQL_DATE:
15655  s->rows[offs + 2] = "10";
15656  quote[0] = quote[1] = "'";
15657  sign = NULL;
15658  break;
15659 #ifdef SQL_TYPE_TIME
15660  case SQL_TYPE_TIME:
15661 #endif
15662  case SQL_TIME:
15663  s->rows[offs + 2] = "8";
15664  quote[0] = quote[1] = "'";
15665  sign = NULL;
15666  break;
15667 #ifdef SQL_TYPE_TIMESTAMP
15668  case SQL_TYPE_TIMESTAMP:
15669 #endif
15670  case SQL_TIMESTAMP:
15671  s->rows[offs + 2] = "32";
15672  quote[0] = quote[1] = "'";
15673  sign = NULL;
15674  break;
15675  case SQL_VARBINARY:
15676  quote[0] = "0x";
15677  sign = NULL;
15678  s->rows[offs + 2] = "255";
15679  break;
15680  case SQL_LONGVARBINARY:
15681  quote[0] = "0x";
15682  sign = NULL;
15683  s->rows[offs + 2] = "65536";
15684  break;
15685  }
15686  s->rows[offs + 3] = quote[0];
15687  s->rows[offs + 4] = quote[1];
15688  s->rows[offs + 5] = crpar;
15689  s->rows[offs + 6] = stringify(SQL_NULLABLE);
15690  s->rows[offs + 7] = stringify(SQL_FALSE);
15691  s->rows[offs + 8] = stringify(SQL_SEARCHABLE);
15692  s->rows[offs + 9] = sign;
15693  s->rows[offs + 10] = stringify(SQL_FALSE);
15694  s->rows[offs + 11] = stringify(SQL_FALSE);
15695  s->rows[offs + 12] = typename;
15696  switch (type) {
15697  case SQL_DATE:
15698  case SQL_TIME:
15699  s->rows[offs + 13] = "0";
15700  s->rows[offs + 14] = "0";
15701  break;
15702 #ifdef SQL_TYPE_TIMESTAMP
15703  case SQL_TYPE_TIMESTAMP:
15704 #endif
15705  case SQL_TIMESTAMP:
15706  s->rows[offs + 13] = "0";
15707  s->rows[offs + 14] = "3";
15708  break;
15709  default:
15710  s->rows[offs + 13] = NULL;
15711  s->rows[offs + 14] = NULL;
15712  break;
15713  }
15714 }
15715 
15724 static int
15725 typeinfosort(const void *a, const void *b)
15726 {
15727  char **pa = (char **) a;
15728  char **pb = (char **) b;
15729  int na, nb;
15730 
15731  na = strtol(pa[1], NULL, 0);
15732  nb = strtol(pb[1], NULL, 0);
15733  return na - nb;
15734 }
15735 
15743 static SQLRETURN
15744 drvgettypeinfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
15745 {
15746  SQLRETURN ret;
15747  STMT *s;
15748  int asize;
15749 
15751  typeSpec3, array_size(typeSpec3), &asize);
15752  if (ret != SQL_SUCCESS) {
15753  return ret;
15754  }
15755  s = (STMT *) stmt;
15756 #ifdef SQL_LONGVARCHAR
15757  s->nrows = (sqltype == SQL_ALL_TYPES) ? 13 : 1;
15758 #else
15759  s->nrows = (sqltype == SQL_ALL_TYPES) ? 12 : 1;
15760 #endif
15761  if (sqltype == SQL_ALL_TYPES) {
15762 #ifdef WINTERFACE
15763  s->nrows += 2;
15764 #ifdef SQL_WLONGVARCHAR
15765  s->nrows += 2;
15766 #endif
15767 #endif
15768  }
15769  if (sqltype == SQL_ALL_TYPES) {
15770  s->nrows += 2;
15771 #ifdef SQL_BIT
15772  s->nrows += 1;
15773 #endif
15774 #ifdef SQL_BIGINT
15775  s->nrows += 1;
15776 #endif
15777  }
15778  s->rows = (char **) xmalloc(sizeof (char *) * (s->nrows + 1) * asize);
15779  if (!s->rows) {
15780  s->nrows = 0;
15781  return nomem(s);
15782  }
15783 #ifdef MEMORY_DEBUG
15784  s->rowfree = xfree__;
15785 #else
15786  s->rowfree = sqlite3_free;
15787 #endif
15788  memset(s->rows, 0, sizeof (char *) * (s->nrows + 1) * asize);
15789  if (sqltype == SQL_ALL_TYPES) {
15790  int cc = 1;
15791 
15792  mktypeinfo(s, cc++, asize, "varchar", SQL_VARCHAR, 0);
15793  mktypeinfo(s, cc++, asize, "tinyint", SQL_TINYINT, 0);
15794  mktypeinfo(s, cc++, asize, "smallint", SQL_SMALLINT, 0);
15795  mktypeinfo(s, cc++, asize, "integer", SQL_INTEGER, 0);
15796  mktypeinfo(s, cc++, asize, "float", SQL_FLOAT, 0);
15797  mktypeinfo(s, cc++, asize, "double", SQL_DOUBLE, 0);
15798 #ifdef SQL_TYPE_DATE
15799  mktypeinfo(s, cc++, asize, "date",
15800  (*s->ov3) ? SQL_TYPE_DATE : SQL_DATE, 0);
15801 #else
15802  mktypeinfo(s, cc++, asize, "date", SQL_DATE, 0);
15803 #endif
15804 #ifdef SQL_TYPE_TIME
15805  mktypeinfo(s, cc++, asize, "time",
15806  (*s->ov3) ? SQL_TYPE_TIME : SQL_TIME, 0);
15807 #else
15808  mktypeinfo(s, cc++, asize, "time", SQL_TIME, 0);
15809 #endif
15810 #ifdef SQL_TYPE_TIMESTAMP
15811  mktypeinfo(s, cc++, asize, "timestamp",
15812  (*s->ov3) ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP, 0);
15813 #else
15814  mktypeinfo(s, cc++, asize, "timestamp", SQL_TIMESTAMP, 0);
15815 #endif
15816  mktypeinfo(s, cc++, asize, "char", SQL_CHAR, 0);
15817  mktypeinfo(s, cc++, asize, "numeric", SQL_DOUBLE, 0);
15818 #ifdef SQL_LONGVARCHAR
15819  mktypeinfo(s, cc++, asize, "text", SQL_LONGVARCHAR, 0);
15820  mktypeinfo(s, cc++, asize, "longvarchar", SQL_LONGVARCHAR, 0);
15821 #else
15822  mktypeinfo(s, cc++, asize, "text", SQL_VARCHAR, 0);
15823 #endif
15824  mktypeinfo(s, cc++, asize, "varbinary", SQL_VARBINARY, 0);
15825  mktypeinfo(s, cc++, asize, "longvarbinary", SQL_LONGVARBINARY, 0);
15826 #ifdef SQL_BIT
15827  mktypeinfo(s, cc++, asize, "bit", SQL_BIT, 0);
15828 #endif
15829 #ifdef SQL_BIGINT
15830  mktypeinfo(s, cc++, asize, "bigint", SQL_BIGINT, 0);
15831 #endif
15832 #ifdef WINTERFACE
15833  mktypeinfo(s, cc++, asize, "wvarchar", SQL_WVARCHAR, 0);
15834  mktypeinfo(s, cc++, asize, "wchar", SQL_WCHAR, 0);
15835 #ifdef SQL_WLONGVARCHAR
15836  mktypeinfo(s, cc++, asize, "wtext", SQL_WLONGVARCHAR, 0);
15837  mktypeinfo(s, cc++, asize, "longwvarchar", SQL_WLONGVARCHAR, 0);
15838 #endif
15839 #endif
15840  qsort(s->rows + asize, s->nrows, sizeof (char *) * asize,
15841  typeinfosort);
15842  } else {
15843  switch (sqltype) {
15844  case SQL_CHAR:
15845  mktypeinfo(s, 1, asize, "char", SQL_CHAR, 10);
15846  break;
15847  case SQL_VARCHAR:
15848  mktypeinfo(s, 1, asize, "varchar", SQL_VARCHAR, 1);
15849  break;
15850  case SQL_TINYINT:
15851  mktypeinfo(s, 1, asize, "tinyint", SQL_TINYINT, 2);
15852  break;
15853  case SQL_SMALLINT:
15854  mktypeinfo(s, 1, asize, "smallint", SQL_SMALLINT, 3);
15855  break;
15856  case SQL_INTEGER:
15857  mktypeinfo(s, 1, asize, "integer", SQL_INTEGER, 4);
15858  break;
15859  case SQL_FLOAT:
15860  mktypeinfo(s, 1, asize, "float", SQL_FLOAT, 5);
15861  break;
15862  case SQL_DOUBLE:
15863  mktypeinfo(s, 1, asize, "double", SQL_DOUBLE, 6);
15864  break;
15865 #ifdef SQL_TYPE_DATE
15866  case SQL_TYPE_DATE:
15867  mktypeinfo(s, 1, asize, "date", SQL_TYPE_DATE, 25);
15868  break;
15869 #endif
15870  case SQL_DATE:
15871  mktypeinfo(s, 1, asize, "date", SQL_DATE, 7);
15872  break;
15873 #ifdef SQL_TYPE_TIME
15874  case SQL_TYPE_TIME:
15875  mktypeinfo(s, 1, asize, "time", SQL_TYPE_TIME, 26);
15876  break;
15877 #endif
15878  case SQL_TIME:
15879  mktypeinfo(s, 1, asize, "time", SQL_TIME, 8);
15880  break;
15881 #ifdef SQL_TYPE_TIMESTAMP
15882  case SQL_TYPE_TIMESTAMP:
15883  mktypeinfo(s, 1, asize, "timestamp", SQL_TYPE_TIMESTAMP, 27);
15884  break;
15885 #endif
15886  case SQL_TIMESTAMP:
15887  mktypeinfo(s, 1, asize, "timestamp", SQL_TIMESTAMP, 9);
15888  break;
15889 #ifdef SQL_LONGVARCHAR
15890  case SQL_LONGVARCHAR:
15891  mktypeinfo(s, 1, asize, "longvarchar", SQL_LONGVARCHAR, 12);
15892  break;
15893 #endif
15894  case SQL_VARBINARY:
15895  mktypeinfo(s, 1, asize, "varbinary", SQL_VARBINARY, 30);
15896  break;
15897  case SQL_LONGVARBINARY:
15898  mktypeinfo(s, 1, asize, "longvarbinary", SQL_LONGVARBINARY, 31);
15899  break;
15900 #ifdef SQL_BIT
15901  case SQL_BIT:
15902  mktypeinfo(s, 1, asize, "bit", SQL_BIT, 29);
15903  break;
15904 #endif
15905 #ifdef SQL_BIGINT
15906  case SQL_BIGINT:
15907  mktypeinfo(s, 1, asize, "bigint", SQL_BIGINT, 28);
15908  break;
15909 #endif
15910 #ifdef WINTERFACE
15911 #ifdef SQL_WCHAR
15912  case SQL_WCHAR:
15913  mktypeinfo(s, 1, asize, "wchar", SQL_WCHAR, 18);
15914  break;
15915 #endif
15916 #ifdef SQL_WVARCHAR
15917  case SQL_WVARCHAR:
15918  mktypeinfo(s, 1, asize, "wvarchar", SQL_WVARCHAR, 19);
15919  break;
15920 #endif
15921 #ifdef SQL_WLONGVARCHAR
15922  case SQL_WLONGVARCHAR:
15923  mktypeinfo(s, 1, asize, "longwvarchar", SQL_WLONGVARCHAR, 20);
15924  break;
15925 #endif
15926 #endif
15927  default:
15928  s->nrows = 0;
15929  }
15930  }
15931  return SQL_SUCCESS;
15932 }
15933 
15934 #ifndef WINTERFACE
15935 
15942 SQLRETURN SQL_API
15943 SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
15944 {
15945  SQLRETURN ret;
15946 
15947  HSTMT_LOCK(stmt);
15948  ret = drvgettypeinfo(stmt, sqltype);
15949  HSTMT_UNLOCK(stmt);
15950  return ret;
15951 }
15952 #endif
15953 
15954 #ifdef WINTERFACE
15955 
15962 SQLRETURN SQL_API
15963 SQLGetTypeInfoW(SQLHSTMT stmt, SQLSMALLINT sqltype)
15964 {
15965  SQLRETURN ret;
15966 
15967  HSTMT_LOCK(stmt);
15968  ret = drvgettypeinfo(stmt, sqltype);
15969  HSTMT_UNLOCK(stmt);
15970  return ret;
15971 }
15972 #endif
15973 
15978 static COL statSpec2[] = {
15979  { "SYSTEM", "STATISTICS", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
15980  { "SYSTEM", "STATISTICS", "TABLE_OWNER", SCOL_VARCHAR, 50 },
15981  { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
15982  { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
15983  { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
15984  { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
15985  { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
15986  { "SYSTEM", "STATISTICS", "SEQ_IN_INDEX", SQL_SMALLINT, 50 },
15987  { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15988  { "SYSTEM", "STATISTICS", "COLLATION", SCOL_CHAR, 1 },
15989  { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
15990  { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
15991  { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
15992 };
15993 
15994 static COL statSpec3[] = {
15995  { "SYSTEM", "STATISTICS", "TABLE_CAT", SCOL_VARCHAR, 50 },
15996  { "SYSTEM", "STATISTICS", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
15997  { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
15998  { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
15999  { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
16000  { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
16001  { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
16002  { "SYSTEM", "STATISTICS", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
16003  { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
16004  { "SYSTEM", "STATISTICS", "ASC_OR_DESC", SCOL_CHAR, 1 },
16005  { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
16006  { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
16007  { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
16008 };
16009 
16024 static SQLRETURN
16025 drvstatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
16026  SQLCHAR *schema, SQLSMALLINT schemaLen,
16027  SQLCHAR *table, SQLSMALLINT tableLen,
16028  SQLUSMALLINT itype, SQLUSMALLINT resv)
16029 {
16030  SQLRETURN sret;
16031  STMT *s;
16032  DBC *d;
16033  int i, asize, ret, nrows, ncols, offs, namec, uniquec, addipk = 0;
16034  PTRDIFF_T size;
16035  char **rowp, *errp = NULL, *sql, tname[512];
16036 
16038  statSpec3, array_size(statSpec3), &asize);
16039  if (sret != SQL_SUCCESS) {
16040  return sret;
16041  }
16042  s = (STMT *) stmt;
16043  d = (DBC *) s->dbc;
16044  if (!table || table[0] == '\0' || table[0] == '%') {
16045  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
16046  return SQL_ERROR;
16047  }
16048  if (tableLen == SQL_NTS) {
16049  size = sizeof (tname) - 1;
16050  } else {
16051  size = min(sizeof (tname) - 1, tableLen);
16052  }
16053  strncpy(tname, (char *) table, size);
16054  tname[size] = '\0';
16055  unescpat(tname);
16056  sret = starttran(s);
16057  if (sret != SQL_SUCCESS) {
16058  return sret;
16059  }
16060  /*
16061  * Try integer primary key (autoincrement) first
16062  */
16063  if (itype == SQL_INDEX_UNIQUE || itype == SQL_INDEX_ALL) {
16064  rowp = 0;
16065  ret = SQLITE_ERROR;
16066  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
16067  if (sql) {
16068  dbtraceapi(d, "sqlite3_get_table", sql);
16069  ret = sqlite3_get_table(d->sqlite, sql, &rowp,
16070  &nrows, &ncols, NULL);
16071  sqlite3_free(sql);
16072  }
16073  if (ret == SQLITE_OK) {
16074  int colid, typec, npk = 0, npkint = 0;
16075 
16076  namec = findcol(rowp, ncols, "name");
16077  uniquec = findcol(rowp, ncols, "pk");
16078  typec = findcol(rowp, ncols, "type");
16079  colid = findcol(rowp, ncols, "cid");
16080  if (namec < 0 || uniquec < 0 || typec < 0 || colid < 0) {
16081  goto noipk;
16082  }
16083  for (i = 1; i <= nrows; i++) {
16084  if (*rowp[i * ncols + uniquec] != '0') {
16085  npk++;
16086  if (strlen(rowp[i * ncols + typec]) == 7 &&
16087  strncasecmp(rowp[i * ncols + typec], "integer", 7)
16088  == 0) {
16089  npkint++;
16090  }
16091  }
16092  }
16093  if (npkint == 1 && npk == npkint) {
16094  addipk = 1;
16095  }
16096  }
16097 noipk:
16098  sqlite3_free_table(rowp);
16099  }
16100  sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
16101  if (!sql) {
16102  return nomem(s);
16103  }
16104  dbtraceapi(d, "sqlite3_get_table", sql);
16105  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
16106  sqlite3_free(sql);
16107  if (ret != SQLITE_OK) {
16108  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
16109  errp ? errp : "unknown error", ret);
16110  if (errp) {
16111  sqlite3_free(errp);
16112  errp = NULL;
16113  }
16114  return SQL_ERROR;
16115  }
16116  if (errp) {
16117  sqlite3_free(errp);
16118  errp = NULL;
16119  }
16120  size = 0;
16121  namec = findcol(rowp, ncols, "name");
16122  uniquec = findcol(rowp, ncols, "unique");
16123  if (namec < 0 || uniquec < 0) {
16124  goto nodata;
16125  }
16126  for (i = 1; i <= nrows; i++) {
16127  int nnrows, nncols;
16128  char **rowpp;
16129  int isuniq;
16130 
16131  isuniq = *rowp[i * ncols + uniquec] != '0';
16132  if (isuniq || itype == SQL_INDEX_ALL) {
16133  ret = SQLITE_ERROR;
16134  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
16135  rowp[i * ncols + namec]);
16136  if (sql) {
16137  dbtraceapi(d, "sqlite3_get_table", sql);
16138  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16139  &nnrows, &nncols, NULL);
16140  sqlite3_free(sql);
16141  }
16142  if (ret == SQLITE_OK) {
16143  size += nnrows;
16144  sqlite3_free_table(rowpp);
16145  }
16146  }
16147  }
16148 nodata:
16149  if (addipk) {
16150  size++;
16151  }
16152  if (size == 0) {
16153  sqlite3_free_table(rowp);
16154  return SQL_SUCCESS;
16155  }
16156  s->nrows = size;
16157  size = (size + 1) * asize;
16158  s->rows = xmalloc((size + 1) * sizeof (char *));
16159  if (!s->rows) {
16160  s->nrows = 0;
16161  return nomem(s);
16162  }
16163  s->rows[0] = (char *) size;
16164  s->rows += 1;
16165  memset(s->rows, 0, sizeof (char *) * size);
16166  s->rowfree = freerows;
16167  offs = 0;
16168  if (addipk) {
16169  char **rowpp = 0;
16170  int nrows2, ncols2;
16171 
16172  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
16173  if (sql) {
16174  dbtraceapi(d, "sqlite3_get_table", sql);
16175  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16176  &nrows2, &ncols2, NULL);
16177  sqlite3_free(sql);
16178  }
16179  if (ret == SQLITE_OK) {
16180  int colid, typec, roffs, namecc, uniquecc;
16181 
16182  namecc = findcol(rowpp, ncols2, "name");
16183  uniquecc = findcol(rowpp, ncols2, "pk");
16184  typec = findcol(rowpp, ncols2, "type");
16185  colid = findcol(rowpp, ncols2, "cid");
16186  if (namecc < 0 || uniquecc < 0 || typec < 0 || colid < 0) {
16187  addipk = 0;
16188  s->nrows--;
16189  goto nodata2;
16190  }
16191  for (i = 1; i <= nrows2; i++) {
16192  if (*rowpp[i * ncols2 + uniquecc] != '0' &&
16193  strlen(rowpp[i * ncols2 + typec]) == 7 &&
16194  strncasecmp(rowpp[i * ncols2 + typec], "integer", 7)
16195  == 0) {
16196  break;
16197  }
16198  }
16199  if (i > nrows2) {
16200  addipk = 0;
16201  s->nrows--;
16202  goto nodata2;
16203  }
16204  roffs = s->ncols;
16205 #if defined(_WIN32) || defined(_WIN64)
16206  s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
16207  s->rows[roffs + 1] = xstrdup("");
16208 #else
16209  s->rows[roffs + 0] = xstrdup("");
16210  s->rows[roffs + 1] = xstrdup("");
16211 #endif
16212  s->rows[roffs + 2] = xstrdup(tname);
16213  s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16214  s->rows[roffs + 5] = xstrdup("sqlite_autoindex_0");
16215  s->rows[roffs + 6] = xstrdup(stringify(SQL_INDEX_OTHER));
16216  s->rows[roffs + 7] = xstrdup("1");
16217  s->rows[roffs + 8] = xstrdup(rowpp[i * ncols2 + namecc]);
16218  s->rows[roffs + 9] = xstrdup("A");
16219  }
16220 nodata2:
16221  sqlite3_free_table(rowpp);
16222  }
16223  for (i = 1; i <= nrows; i++) {
16224  int nnrows, nncols;
16225  char **rowpp = 0;
16226 
16227  if (*rowp[i * ncols + uniquec] != '0' || itype == SQL_INDEX_ALL) {
16228  int k;
16229 
16230  ret = SQLITE_ERROR;
16231  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
16232  rowp[i * ncols + namec]);
16233  if (sql) {
16234  dbtraceapi(d, "sqlite3_get_table", sql);
16235  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16236  &nnrows, &nncols, NULL);
16237  sqlite3_free(sql);
16238  }
16239  if (ret != SQLITE_OK) {
16240  continue;
16241  }
16242  for (k = 0; nnrows && k < nncols; k++) {
16243  if (strcmp(rowpp[k], "name") == 0) {
16244  int m;
16245 
16246  for (m = 1; m <= nnrows; m++) {
16247  int roffs = (offs + addipk + m) * s->ncols;
16248  int isuniq;
16249 
16250  isuniq = *rowp[i * ncols + uniquec] != '0';
16251  s->rows[roffs + 0] = xstrdup("");
16252  s->rows[roffs + 1] = xstrdup("");
16253  s->rows[roffs + 2] = xstrdup(tname);
16254  if (isuniq) {
16255  s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16256  } else {
16257  s->rows[roffs + 3] = xstrdup(stringify(SQL_TRUE));
16258  }
16259  s->rows[roffs + 5] = xstrdup(rowp[i * ncols + namec]);
16260  s->rows[roffs + 6] =
16261  xstrdup(stringify(SQL_INDEX_OTHER));
16262  s->rows[roffs + 8] = xstrdup(rowpp[m * nncols + k]);
16263  s->rows[roffs + 9] = xstrdup("A");
16264  }
16265  } else if (strcmp(rowpp[k], "seqno") == 0) {
16266  int m;
16267 
16268  for (m = 1; m <= nnrows; m++) {
16269  int roffs = (offs + addipk + m) * s->ncols;
16270  int pos = m - 1;
16271  char buf[32];
16272 
16273  sscanf(rowpp[m * nncols + k], "%d", &pos);
16274  sprintf(buf, "%d", pos + 1);
16275  s->rows[roffs + 7] = xstrdup(buf);
16276  }
16277  }
16278  }
16279  offs += nnrows;
16280  sqlite3_free_table(rowpp);
16281  }
16282  }
16283  sqlite3_free_table(rowp);
16284  return SQL_SUCCESS;
16285 }
16286 
16287 #ifndef WINTERFACE
16288 
16302 SQLRETURN SQL_API
16303 SQLStatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
16304  SQLCHAR *schema, SQLSMALLINT schemaLen,
16305  SQLCHAR *table, SQLSMALLINT tableLen,
16306  SQLUSMALLINT itype, SQLUSMALLINT resv)
16307 {
16308 #if defined(_WIN32) || defined(_WIN64)
16309  char *c = NULL, *s = NULL, *t = NULL;
16310 #endif
16311  SQLRETURN ret;
16312 
16313  HSTMT_LOCK(stmt);
16314 #if defined(_WIN32) || defined(_WIN64)
16315  if (!((STMT *) stmt)->oemcp[0]) {
16316  ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16317  table, tableLen, itype, resv);
16318  goto done2;
16319  }
16320  if (cat) {
16321  c = wmb_to_utf_c((char *) cat, catLen);
16322  if (!c) {
16323  ret = nomem((STMT *) stmt);
16324  goto done;
16325  }
16326  }
16327  if (schema) {
16328  s = wmb_to_utf_c((char *) schema, schemaLen);
16329  if (!s) {
16330  ret = nomem((STMT *) stmt);
16331  goto done;
16332  }
16333  }
16334  if (table) {
16335  t = wmb_to_utf_c((char *) table, tableLen);
16336  if (!t) {
16337  ret = nomem((STMT *) stmt);
16338  goto done;
16339  }
16340  }
16341  ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16342  (SQLCHAR *) t, SQL_NTS, itype, resv);
16343 #else
16344  ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16345  table, tableLen, itype, resv);
16346 #endif
16347 #if defined(_WIN32) || defined(_WIN64)
16348 done:
16349  uc_free(t);
16350  uc_free(s);
16351  uc_free(c);
16352 done2:
16353  ;
16354 #endif
16355  HSTMT_UNLOCK(stmt);
16356  return ret;
16357 }
16358 #endif
16359 
16360 #ifdef WINTERFACE
16361 
16375 SQLRETURN SQL_API
16376 SQLStatisticsW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen,
16377  SQLWCHAR *schema, SQLSMALLINT schemaLen,
16378  SQLWCHAR *table, SQLSMALLINT tableLen,
16379  SQLUSMALLINT itype, SQLUSMALLINT resv)
16380 {
16381  char *c = NULL, *s = NULL, *t = NULL;
16382  SQLRETURN ret;
16383 
16384  HSTMT_LOCK(stmt);
16385  if (cat) {
16386  c = uc_to_utf_c(cat, catLen);
16387  if (!c) {
16388  ret = nomem((STMT *) stmt);
16389  goto done;
16390  }
16391  }
16392  if (schema) {
16393  s = uc_to_utf_c(schema, schemaLen);
16394  if (!s) {
16395  ret = nomem((STMT *) stmt);
16396  goto done;
16397  }
16398  }
16399  if (table) {
16400  t = uc_to_utf_c(table, tableLen);
16401  if (!t) {
16402  ret = nomem((STMT *) stmt);
16403  goto done;
16404  }
16405  }
16406  ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16407  (SQLCHAR *) t, SQL_NTS, itype, resv);
16408 done:
16409  uc_free(t);
16410  uc_free(s);
16411  uc_free(c);
16412  HSTMT_UNLOCK(stmt);
16413  return ret;
16414 }
16415 #endif
16416 
16428 SQLRETURN SQL_API
16429 SQLGetData(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
16430  SQLPOINTER val, SQLLEN len, SQLLEN *lenp)
16431 {
16432  STMT *s;
16433  SQLRETURN ret = SQL_ERROR;
16434 
16435  HSTMT_LOCK(stmt);
16436  if (stmt == SQL_NULL_HSTMT) {
16437  return SQL_INVALID_HANDLE;
16438  }
16439  s = (STMT *) stmt;
16440  if (col == 0 && s->bkmrk != SQL_UB_OFF) {
16441  if (s->bkmrk == SQL_UB_ON && type == SQL_C_BOOKMARK) {
16442  *((SQLINTEGER *) val) = s->rowp;
16443  if (lenp) {
16444  *lenp = sizeof (SQLINTEGER);
16445  }
16446  ret = SQL_SUCCESS;
16447  goto done;
16448  } else if (s->bkmrk == SQL_UB_VARIABLE && type == SQL_C_VARBOOKMARK) {
16449  if (s->has_rowid >= 0) {
16450  char **data, *endp = 0;
16451 
16452  data = s->rows + s->ncols + (s->rowp * s->ncols)
16453  + s->has_rowid;
16454 #ifdef __osf__
16455  *((sqlite_int64 *) val) = strtol(*data, &endp, 0);
16456 #else
16457  *((sqlite_int64 *) val) = strtoll(*data, &endp, 0);
16458 #endif
16459  } else {
16460  *((sqlite_int64 *) val) = s->rowp;
16461  }
16462  if (lenp) {
16463  *lenp = sizeof (sqlite_int64);
16464  }
16465  ret = SQL_SUCCESS;
16466  goto done;
16467  }
16468  }
16469  if (col < 1 || col > s->ncols) {
16470  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
16471  goto done;
16472  }
16473  --col;
16474  ret = getrowdata(s, col, type, val, len, lenp, 1);
16475 done:
16476  HSTMT_UNLOCK(stmt);
16477  return ret;
16478 }
16479 
16487 static SQLRETURN
16488 dofetchbind(STMT *s, int rsi)
16489 {
16490  int ret, i, withinfo = 0;
16491 
16492  s->row_status0[rsi] = SQL_ROW_SUCCESS;
16493  if (s->bkmrk != SQL_UB_OFF && s->bkmrkcol.valp) {
16494  int bsize = sizeof (SQLINTEGER);
16495 
16496  if (s->bkmrkcol.type == SQL_C_VARBOOKMARK) {
16497  SQLPOINTER *val;
16498 
16499  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16500  val = (SQLPOINTER)
16501  ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16502  } else {
16503  val = (SQLPOINTER)
16504  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * rsi);
16505  }
16506  if (s->bind_offs) {
16507  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
16508  }
16509  if (s->has_rowid >= 0) {
16510  char **data, *endp = 0;
16511 
16512  data = s->rows + s->ncols + (s->rowp * s->ncols)
16513  + s->has_rowid;
16514 #ifdef __osf__
16515  *(sqlite_int64 *) val = strtol(*data, &endp, 0);
16516 #else
16517  *(sqlite_int64 *) val = strtoll(*data, &endp, 0);
16518 #endif
16519  } else {
16520  *(sqlite_int64 *) val = s->rowp;
16521  }
16522  bsize = sizeof (sqlite_int64);
16523  } else {
16524  SQLINTEGER *val;
16525 
16526  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16527  val = (SQLINTEGER *)
16528  ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16529  } else {
16530  val = (SQLINTEGER *) s->bkmrkcol.valp + rsi;
16531  }
16532  if (s->bind_offs) {
16533  val = (SQLINTEGER *) ((char *) val + *s->bind_offs);
16534  }
16535  *val = s->rowp;
16536  }
16537  if (s->bkmrkcol.lenp) {
16538  SQLLEN *ival;
16539 
16540  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16541  ival = (SQLLEN *)
16542  ((char *) s->bkmrkcol.lenp + s->bind_type * rsi);
16543  } else {
16544  ival = &s->bkmrkcol.lenp[rsi];
16545  }
16546  if (s->bind_offs) {
16547  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
16548  }
16549  *ival = bsize;
16550  }
16551  }
16552  ret = SQL_SUCCESS;
16553  for (i = 0; s->bindcols && i < s->ncols; i++) {
16554  BINDCOL *b = &s->bindcols[i];
16555  SQLPOINTER dp = 0;
16556  SQLLEN *lp = 0;
16557 
16558  b->offs = 0;
16559  if (b->valp) {
16560  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16561  dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
16562  } else {
16563  dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
16564  }
16565  if (s->bind_offs) {
16566  dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
16567  }
16568  }
16569  if (b->lenp) {
16570  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16571  lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
16572  } else {
16573  lp = b->lenp + rsi;
16574  }
16575  if (s->bind_offs) {
16576  lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
16577  }
16578  }
16579  if (dp || lp) {
16580  ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp, b->max, lp, 0);
16581  if (!SQL_SUCCEEDED(ret)) {
16582  s->row_status0[rsi] = SQL_ROW_ERROR;
16583  break;
16584  }
16585  if (ret != SQL_SUCCESS) {
16586  withinfo = 1;
16587 #ifdef SQL_ROW_SUCCESS_WITH_INFO
16588  s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
16589 #endif
16590  }
16591  }
16592  }
16593  if (SQL_SUCCEEDED(ret)) {
16594  ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16595  }
16596  return ret;
16597 }
16598 
16607 static SQLRETURN
16608 drvfetchscroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLINTEGER offset)
16609 {
16610  STMT *s;
16611  int i, withinfo = 0;
16612  SQLRETURN ret;
16613 
16614  if (stmt == SQL_NULL_HSTMT) {
16615  return SQL_INVALID_HANDLE;
16616  }
16617  s = (STMT *) stmt;
16618  for (i = 0; i < s->rowset_size; i++) {
16619  s->row_status0[i] = SQL_ROW_NOROW;
16620  }
16621  if (s->row_status) {
16622  memcpy(s->row_status, s->row_status0,
16623  sizeof (SQLUSMALLINT) * s->rowset_size);
16624  }
16625  s->row_count0 = 0;
16626  if (s->row_count) {
16627  *s->row_count = s->row_count0;
16628  }
16629  if (!s->bindcols) {
16630  for (i = 0; i < s->rowset_size; i++) {
16631  s->row_status0[i] = SQL_ROW_ERROR;
16632  }
16633  ret = SQL_ERROR;
16634  i = 0;
16635  goto done2;
16636  }
16637  if (s->isselect != 1 && s->isselect != -1) {
16638  setstat(s, -1, "no result set available", "24000");
16639  ret = SQL_ERROR;
16640  i = s->nrows;
16641  goto done2;
16642  }
16643  if (s->curtype == SQL_CURSOR_FORWARD_ONLY && orient != SQL_FETCH_NEXT) {
16644  setstat(s, -1, "wrong fetch direction", "01000");
16645  ret = SQL_ERROR;
16646  i = 0;
16647  goto done2;
16648  }
16649  ret = SQL_SUCCESS;
16650  i = 0;
16651  if (((DBC *) (s->dbc))->cur_s3stmt == s && s->s3stmt) {
16652  s->rowp = s->rowprs = 0;
16653  for (; i < s->rowset_size; i++) {
16654  if (s->max_rows && s->s3stmt_rownum + 1 >= s->max_rows) {
16655  ret = (i == 0) ? SQL_NO_DATA : SQL_SUCCESS;
16656  break;
16657  }
16658  ret = s3stmt_step(s);
16659  if (ret != SQL_SUCCESS) {
16660  s->row_status0[i] = SQL_ROW_ERROR;
16661  break;
16662  }
16663  if (s->nrows < 1) {
16664  break;
16665  }
16666  ret = dofetchbind(s, i);
16667  if (!SQL_SUCCEEDED(ret)) {
16668  break;
16669  } else if (ret == SQL_SUCCESS_WITH_INFO) {
16670  withinfo = 1;
16671  }
16672  }
16673  } else if (s->rows) {
16674  switch (orient) {
16675  case SQL_FETCH_NEXT:
16676  if (s->nrows < 1) {
16677  return SQL_NO_DATA;
16678  }
16679  if (s->rowp < 0) {
16680  s->rowp = -1;
16681  }
16682  if (s->rowp >= s->nrows) {
16683  s->rowp = s->rowprs = s->nrows;
16684  return SQL_NO_DATA;
16685  }
16686  break;
16687  case SQL_FETCH_PRIOR:
16688  if (s->nrows < 1 || s->rowp <= 0) {
16689  s->rowp = s->rowprs = -1;
16690  return SQL_NO_DATA;
16691  }
16692  s->rowp -= s->rowset_size + 1;
16693  if (s->rowp < -1) {
16694  s->rowp = s->rowprs = -1;
16695  return SQL_NO_DATA;
16696  }
16697  break;
16698  case SQL_FETCH_FIRST:
16699  if (s->nrows < 1) {
16700  return SQL_NO_DATA;
16701  }
16702  s->rowp = -1;
16703  break;
16704  case SQL_FETCH_LAST:
16705  if (s->nrows < 1) {
16706  return SQL_NO_DATA;
16707  }
16708  s->rowp = s->nrows - s->rowset_size;
16709  if (--s->rowp < -1) {
16710  s->rowp = -1;
16711  }
16712  break;
16713  case SQL_FETCH_ABSOLUTE:
16714  if (offset == 0) {
16715  s->rowp = s->rowprs = -1;
16716  return SQL_NO_DATA;
16717  } else if (offset < 0) {
16718  if (0 - offset <= s->nrows) {
16719  s->rowp = s->nrows + offset - 1;
16720  break;
16721  }
16722  s->rowp = s->rowprs = -1;
16723  return SQL_NO_DATA;
16724  } else if (offset > s->nrows) {
16725  s->rowp = s->rowprs = s->nrows;
16726  return SQL_NO_DATA;
16727  }
16728  s->rowp = offset - 1 - 1;
16729  break;
16730  case SQL_FETCH_RELATIVE:
16731  if (offset >= 0) {
16732  s->rowp += offset * s->rowset_size - 1;
16733  if (s->rowp >= s->nrows) {
16734  s->rowp = s->rowprs = s->nrows;
16735  return SQL_NO_DATA;
16736  }
16737  } else {
16738  s->rowp += offset * s->rowset_size - 1;
16739  if (s->rowp < -1) {
16740  s->rowp = s->rowprs = -1;
16741  return SQL_NO_DATA;
16742  }
16743  }
16744  break;
16745  case SQL_FETCH_BOOKMARK:
16746  if (s->bkmrk == SQL_UB_ON && !s->bkmrkptr) {
16747  if (offset < 0 || offset >= s->nrows) {
16748  return SQL_NO_DATA;
16749  }
16750  s->rowp = offset - 1;
16751  break;
16752  }
16753  if (s->bkmrk != SQL_UB_OFF && s->bkmrkptr) {
16754  int rowp;
16755 
16756  if (s->bkmrk == SQL_UB_VARIABLE) {
16757  if (s->has_rowid >= 0) {
16758  sqlite_int64 bkmrk, rowid;
16759 
16760  bkmrk = *(sqlite_int64 *) s->bkmrkptr;
16761  for (rowp = 0; rowp < s->nrows; rowp++) {
16762  char **data, *endp = 0;
16763 
16764  data = s->rows + s->ncols + (rowp * s->ncols)
16765  + s->has_rowid;
16766 #ifdef __osf__
16767  rowid = strtol(*data, &endp, 0);
16768 #else
16769  rowid = strtoll(*data, &endp, 0);
16770 #endif
16771  if (rowid == bkmrk) {
16772  break;
16773  }
16774  }
16775  } else {
16776  rowp = *(sqlite_int64 *) s->bkmrkptr;
16777  }
16778  } else {
16779  rowp = *(int *) s->bkmrkptr;
16780  }
16781  if (rowp + offset < 0 || rowp + offset >= s->nrows) {
16782  return SQL_NO_DATA;
16783  }
16784  s->rowp = rowp + offset - 1;
16785  break;
16786  }
16787  /* fall through */
16788  default:
16789  s->row_status0[0] = SQL_ROW_ERROR;
16790  ret = SQL_ERROR;
16791  goto done;
16792  }
16793  s->rowprs = s->rowp + 1;
16794  for (; i < s->rowset_size; i++) {
16795  ++s->rowp;
16796  if (s->rowp < 0 || s->rowp >= s->nrows) {
16797  break;
16798  }
16799  ret = dofetchbind(s, i);
16800  if (!SQL_SUCCEEDED(ret)) {
16801  break;
16802  } else if (ret == SQL_SUCCESS_WITH_INFO) {
16803  withinfo = 1;
16804  }
16805  }
16806  }
16807 done:
16808  if (i == 0) {
16809  if (SQL_SUCCEEDED(ret)) {
16810  return SQL_NO_DATA;
16811  }
16812  return ret;
16813  }
16814  if (SQL_SUCCEEDED(ret)) {
16815  ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16816  }
16817 done2:
16818  if (s->row_status) {
16819  memcpy(s->row_status, s->row_status0,
16820  sizeof (SQLUSMALLINT) * s->rowset_size);
16821  }
16822  s->row_count0 = i;
16823  if (s->row_count) {
16824  *s->row_count = s->row_count0;
16825  }
16826  return ret;
16827 }
16828 
16835 SQLRETURN SQL_API
16836 SQLFetch(SQLHSTMT stmt)
16837 {
16838  SQLRETURN ret;
16839 
16840  HSTMT_LOCK(stmt);
16841  ret = drvfetchscroll(stmt, SQL_FETCH_NEXT, 0);
16842  HSTMT_UNLOCK(stmt);
16843  return ret;
16844 }
16845 
16854 SQLRETURN SQL_API
16855 SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLLEN offset)
16856 {
16857  SQLRETURN ret;
16858 
16859  HSTMT_LOCK(stmt);
16860  ret = drvfetchscroll(stmt, orient, offset);
16861  HSTMT_UNLOCK(stmt);
16862  return ret;
16863 }
16864 
16875 SQLRETURN SQL_API
16876 SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT orient, SQLROWOFFSET offset,
16877  SQLROWSETSIZE *rowcount, SQLUSMALLINT *rowstatus)
16878 {
16879  STMT *s;
16880  SQLRETURN ret;
16881  SQLUSMALLINT *rst;
16882  SQLINTEGER *bkmrkptr;
16883 
16884  HSTMT_LOCK(stmt);
16885  if (stmt == SQL_NULL_HSTMT) {
16886  return SQL_INVALID_HANDLE;
16887  }
16888  s = (STMT *) stmt;
16889  /* temporarily turn off SQL_ATTR_ROW_STATUS_PTR */
16890  rst = s->row_status;
16891  s->row_status = 0;
16892  bkmrkptr = s->bkmrkptr;
16893  s->bkmrkptr = 0;
16894  ret = drvfetchscroll(stmt, orient, offset);
16895  s->row_status = rst;
16896  s->bkmrkptr = bkmrkptr;
16897  if (rowstatus) {
16898  memcpy(rowstatus, s->row_status0,
16899  sizeof (SQLUSMALLINT) * s->rowset_size);
16900  }
16901  if (rowcount) {
16902  *rowcount = s->row_count0;
16903  }
16904  HSTMT_UNLOCK(stmt);
16905  return ret;
16906 }
16907 
16915 SQLRETURN SQL_API
16916 SQLRowCount(SQLHSTMT stmt, SQLLEN *nrows)
16917 {
16918  STMT *s;
16919 
16920  HSTMT_LOCK(stmt);
16921  if (stmt == SQL_NULL_HSTMT) {
16922  return SQL_INVALID_HANDLE;
16923  }
16924  s = (STMT *) stmt;
16925  if (nrows) {
16926  *nrows = s->isselect ? 0 : s->nrows;
16927  }
16928  HSTMT_UNLOCK(stmt);
16929  return SQL_SUCCESS;
16930 }
16931 
16939 SQLRETURN SQL_API
16940 SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *ncols)
16941 {
16942  STMT *s;
16943 
16944  HSTMT_LOCK(stmt);
16945  if (stmt == SQL_NULL_HSTMT) {
16946  return SQL_INVALID_HANDLE;
16947  }
16948  s = (STMT *) stmt;
16949  if (ncols) {
16950  *ncols = s->ncols;
16951  }
16952  HSTMT_UNLOCK(stmt);
16953  return SQL_SUCCESS;
16954 }
16955 
16970 static SQLRETURN
16971 drvdescribecol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
16972  SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
16973  SQLSMALLINT *type, SQLULEN *size,
16974  SQLSMALLINT *digits, SQLSMALLINT *nullable)
16975 {
16976  STMT *s;
16977  COL *c;
16978  int didname = 0;
16979 
16980  if (stmt == SQL_NULL_HSTMT) {
16981  return SQL_INVALID_HANDLE;
16982  }
16983  s = (STMT *) stmt;
16984  if (!s->cols) {
16985  setstat(s, -1, "no columns", (*s->ov3) ? "07009" : "S1002");
16986  return SQL_ERROR;
16987  }
16988  if (col < 1 || col > s->ncols) {
16989  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
16990  return SQL_ERROR;
16991  }
16992  c = s->cols + col - 1;
16993  if (name && nameMax > 0) {
16994  strncpy((char *) name, c->column, nameMax);
16995  name[nameMax - 1] = '\0';
16996  didname = 1;
16997  }
16998  if (nameLen) {
16999  if (didname) {
17000  *nameLen = strlen((char *) name);
17001  } else {
17002  *nameLen = strlen(c->column);
17003  }
17004  }
17005  if (type) {
17006  *type = c->type;
17007 #ifdef WINTERFACE
17008  if (s->nowchar[0] || s->nowchar[1]) {
17009  switch (c->type) {
17010  case SQL_WCHAR:
17011  *type = SQL_CHAR;
17012  break;
17013  case SQL_WVARCHAR:
17014  *type = SQL_VARCHAR;
17015  break;
17016 #ifdef SQL_LONGVARCHAR
17017  case SQL_WLONGVARCHAR:
17018  *type = SQL_LONGVARCHAR;
17019  break;
17020 #endif
17021  }
17022  }
17023 #endif
17024  }
17025  if (size) {
17026  *size = c->size;
17027  }
17028  if (digits) {
17029  *digits = 0;
17030  }
17031  if (nullable) {
17032  *nullable = 1;
17033  }
17034  return SQL_SUCCESS;
17035 }
17036 
17037 #ifndef WINTERFACE
17038 
17052 SQLRETURN SQL_API
17053 SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
17054  SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
17055  SQLSMALLINT *type, SQLULEN *size,
17056  SQLSMALLINT *digits, SQLSMALLINT *nullable)
17057 {
17058 #if defined(_WIN32) || defined(_WIN64)
17059  SQLSMALLINT len = 0;
17060 #endif
17061  SQLRETURN ret;
17062 
17063  HSTMT_LOCK(stmt);
17064 #if defined(_WIN32) || defined(_WIN64)
17065  if (!((STMT *) stmt)->oemcp[0]) {
17066  ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
17067  type, size, digits, nullable);
17068  goto done;
17069  }
17070  ret = drvdescribecol(stmt, col, name, nameMax,
17071  &len, type, size, digits, nullable);
17072  if (ret == SQL_SUCCESS) {
17073  if (name) {
17074  if (len > 0) {
17075  SQLCHAR *n = NULL;
17076 
17077  n = (SQLCHAR *) utf_to_wmb((char *) name, len);
17078  if (n) {
17079  strncpy((char *) name, (char *) n, nameMax);
17080  n[len] = 0;
17081  len = min(nameMax, strlen((char *) n));
17082  uc_free(n);
17083  } else {
17084  len = 0;
17085  }
17086  }
17087  if (len <= 0) {
17088  len = 0;
17089  if (nameMax > 0) {
17090  name[0] = 0;
17091  }
17092  }
17093  } else {
17094  STMT *s = (STMT *) stmt;
17095  COL *c = s->cols + col - 1;
17096 
17097  len = 0;
17098  if (c->column) {
17099  len = strlen(c->column);
17100  }
17101  }
17102  if (nameLen) {
17103  *nameLen = len;
17104  }
17105  }
17106 done:
17107  ;
17108 #else
17109  ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
17110  type, size, digits, nullable);
17111 #endif
17112  HSTMT_UNLOCK(stmt);
17113  return ret;
17114 }
17115 #endif
17116 
17117 #ifdef WINTERFACE
17118 
17132 SQLRETURN SQL_API
17133 SQLDescribeColW(SQLHSTMT stmt, SQLUSMALLINT col, SQLWCHAR *name,
17134  SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
17135  SQLSMALLINT *type, SQLULEN *size,
17136  SQLSMALLINT *digits, SQLSMALLINT *nullable)
17137 {
17138  SQLRETURN ret;
17139  SQLSMALLINT len = 0;
17140 
17141  HSTMT_LOCK(stmt);
17142  ret = drvdescribecol(stmt, col, (SQLCHAR *) name,
17143  (SQLSMALLINT) (nameMax * sizeof (SQLWCHAR)),
17144  &len, type, size, digits, nullable);
17145  if (ret == SQL_SUCCESS) {
17146  if (name) {
17147  if (len > 0) {
17148  SQLWCHAR *n = NULL;
17149 
17150  n = uc_from_utf((SQLCHAR *) name, len);
17151  if (n) {
17152  uc_strncpy(name, n, nameMax);
17153  n[len] = 0;
17154  len = min(nameMax, uc_strlen(n));
17155  uc_free(n);
17156  } else {
17157  len = 0;
17158  }
17159  }
17160  if (len <= 0) {
17161  len = 0;
17162  if (nameMax > 0) {
17163  name[0] = 0;
17164  }
17165  }
17166  } else {
17167  STMT *s = (STMT *) stmt;
17168  COL *c = s->cols + col - 1;
17169 
17170  len = 0;
17171  if (c->column) {
17172  len = strlen(c->column);
17173  }
17174  }
17175  if (nameLen) {
17176  *nameLen = len;
17177  }
17178  }
17179  HSTMT_UNLOCK(stmt);
17180  return ret;
17181 }
17182 #endif
17183 
17196 static SQLRETURN
17197 drvcolattributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17198  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17199  SQLLEN *val2)
17200 {
17201  STMT *s;
17202  COL *c;
17203  SQLSMALLINT dummy;
17204  char *valc = (char *) val;
17205 
17206  if (stmt == SQL_NULL_HSTMT) {
17207  return SQL_INVALID_HANDLE;
17208  }
17209  s = (STMT *) stmt;
17210  if (!s->cols) {
17211  return SQL_ERROR;
17212  }
17213  if (!valLen) {
17214  valLen = &dummy;
17215  }
17216  if (id == SQL_COLUMN_COUNT) {
17217  if (val2) {
17218  *val2 = s->ncols;
17219  }
17220  *valLen = sizeof (int);
17221  return SQL_SUCCESS;
17222  }
17223  if (id == SQL_COLUMN_TYPE && col == 0) {
17224  if (val2) {
17225  *val2 = SQL_INTEGER;
17226  }
17227  *valLen = sizeof (int);
17228  return SQL_SUCCESS;
17229  }
17230 #ifdef SQL_DESC_OCTET_LENGTH
17231  if (id == SQL_DESC_OCTET_LENGTH && col == 0) {
17232  if (val2) {
17233  *val2 = 4;
17234  }
17235  *valLen = sizeof (int);
17236  return SQL_SUCCESS;
17237  }
17238 #endif
17239  if (col < 1 || col > s->ncols) {
17240  setstat(s, -1, "invalid column", (*s->ov3) ? "07009": "S1002");
17241  return SQL_ERROR;
17242  }
17243  c = s->cols + col - 1;
17244 
17245  switch (id) {
17246  case SQL_COLUMN_LABEL:
17247  if (c->label) {
17248  if (valc && valMax > 0) {
17249  strncpy(valc, c->label, valMax);
17250  valc[valMax - 1] = '\0';
17251  }
17252  *valLen = strlen(c->label);
17253  goto checkLen;
17254  }
17255  /* fall through */
17256  case SQL_COLUMN_NAME:
17257  case SQL_DESC_NAME:
17258  if (valc && valMax > 0) {
17259  strncpy(valc, c->column, valMax);
17260  valc[valMax - 1] = '\0';
17261  }
17262  *valLen = strlen(c->column);
17263 checkLen:
17264  if (*valLen >= valMax) {
17265  setstat(s, -1, "data right truncated", "01004");
17266  return SQL_SUCCESS_WITH_INFO;
17267  }
17268  return SQL_SUCCESS;
17269 #ifdef SQL_DESC_BASE_COLUMN_NAME
17270  case SQL_DESC_BASE_COLUMN_NAME:
17271  if (strchr(c->column, '(') || strchr(c->column, ')')) {
17272  if (valc && valMax > 0) {
17273  valc[0] = '\0';
17274  }
17275  *valLen = 0;
17276  } else if (valc && valMax > 0) {
17277  strncpy(valc, c->column, valMax);
17278  valc[valMax - 1] = '\0';
17279  *valLen = strlen(c->column);
17280  }
17281  goto checkLen;
17282 #endif
17283  case SQL_COLUMN_TYPE:
17284  case SQL_DESC_TYPE:
17285 #ifdef WINTERFACE
17286  {
17287  int type = c->type;
17288 
17289  if (s->nowchar[0] || s->nowchar[1]) {
17290  switch (type) {
17291  case SQL_WCHAR:
17292  type = SQL_CHAR;
17293  break;
17294  case SQL_WVARCHAR:
17295  type = SQL_VARCHAR;
17296  break;
17297 #ifdef SQL_LONGVARCHAR
17298  case SQL_WLONGVARCHAR:
17299  type = SQL_LONGVARCHAR;
17300  break;
17301  }
17302  }
17303  if (val2) {
17304  *val2 = type;
17305  }
17306 #endif
17307  }
17308 #else
17309  if (val2) {
17310  *val2 = c->type;
17311  }
17312 #endif
17313  *valLen = sizeof (int);
17314  return SQL_SUCCESS;
17315  case SQL_COLUMN_DISPLAY_SIZE:
17316  if (val2) {
17317  *val2 = c->size;
17318  }
17319  *valLen = sizeof (int);
17320  return SQL_SUCCESS;
17321  case SQL_COLUMN_UNSIGNED:
17322  if (val2) {
17323  *val2 = c->nosign ? SQL_TRUE : SQL_FALSE;
17324  }
17325  *valLen = sizeof (int);
17326  return SQL_SUCCESS;
17327  case SQL_COLUMN_SCALE:
17328  case SQL_DESC_SCALE:
17329  if (val2) {
17330  *val2 = c->scale;
17331  }
17332  *valLen = sizeof (int);
17333  return SQL_SUCCESS;
17334  case SQL_COLUMN_PRECISION:
17335  case SQL_DESC_PRECISION:
17336  if (val2) {
17337  switch (c->type) {
17338  case SQL_SMALLINT:
17339  *val2 = 5;
17340  break;
17341  case SQL_INTEGER:
17342  *val2 = 10;
17343  break;
17344  case SQL_FLOAT:
17345  case SQL_REAL:
17346  case SQL_DOUBLE:
17347  *val2 = 15;
17348  break;
17349  case SQL_DATE:
17350  *val2 = 0;
17351  break;
17352  case SQL_TIME:
17353  *val2 = 0;
17354  break;
17355 #ifdef SQL_TYPE_TIMESTAMP
17356  case SQL_TYPE_TIMESTAMP:
17357 #endif
17358  case SQL_TIMESTAMP:
17359  *val2 = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
17360  break;
17361  default:
17362  *val2 = c->prec;
17363  break;
17364  }
17365  }
17366  *valLen = sizeof (int);
17367  return SQL_SUCCESS;
17368  case SQL_COLUMN_MONEY:
17369  if (val2) {
17370  *val2 = SQL_FALSE;
17371  }
17372  *valLen = sizeof (int);
17373  return SQL_SUCCESS;
17374  case SQL_COLUMN_AUTO_INCREMENT:
17375  if (val2) {
17376  *val2 = c->autoinc;
17377  }
17378  *valLen = sizeof (int);
17379  return SQL_SUCCESS;
17380  case SQL_COLUMN_LENGTH:
17381  case SQL_DESC_LENGTH:
17382  if (val2) {
17383  *val2 = c->size;
17384  }
17385  *valLen = sizeof (int);
17386  return SQL_SUCCESS;
17387  case SQL_COLUMN_NULLABLE:
17388  case SQL_DESC_NULLABLE:
17389  if (val2) {
17390  *val2 = c->notnull;
17391  }
17392  *valLen = sizeof (int);
17393  return SQL_SUCCESS;
17394  case SQL_COLUMN_SEARCHABLE:
17395  if (val2) {
17396  *val2 = SQL_SEARCHABLE;
17397  }
17398  *valLen = sizeof (int);
17399  return SQL_SUCCESS;
17400  case SQL_COLUMN_CASE_SENSITIVE:
17401  if (val2) {
17402  *val2 = SQL_TRUE;
17403  }
17404  *valLen = sizeof (int);
17405  return SQL_SUCCESS;
17406  case SQL_COLUMN_UPDATABLE:
17407  if (val2) {
17408  *val2 = SQL_TRUE;
17409  }
17410  *valLen = sizeof (int);
17411  return SQL_SUCCESS;
17412  case SQL_DESC_COUNT:
17413  if (val2) {
17414  *val2 = s->ncols;
17415  }
17416  *valLen = sizeof (int);
17417  return SQL_SUCCESS;
17418  case SQL_COLUMN_TYPE_NAME: {
17419  char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17420 
17421 #ifdef WINTERFACE
17422  if (c->type == SQL_WCHAR ||
17423  c->type == SQL_WVARCHAR ||
17424  c->type == SQL_WLONGVARCHAR) {
17425  if (!(s->nowchar[0] || s->nowchar[1])) {
17426  if (strcasecmp(tn, "varchar") == 0) {
17427  tn = "wvarchar";
17428  }
17429  }
17430  }
17431 #endif
17432  if (valc && valMax > 0) {
17433  strncpy(valc, tn, valMax);
17434  valc[valMax - 1] = '\0';
17435  p = strchr(valc, '(');
17436  if (p) {
17437  *p = '\0';
17438  while (p > valc && ISSPACE(p[-1])) {
17439  --p;
17440  *p = '\0';
17441  }
17442  }
17443  *valLen = strlen(valc);
17444  } else {
17445  *valLen = strlen(tn);
17446  p = strchr(tn, '(');
17447  if (p) {
17448  *valLen = p - tn;
17449  while (p > tn && ISSPACE(p[-1])) {
17450  --p;
17451  *valLen -= 1;
17452  }
17453  }
17454  }
17455  goto checkLen;
17456  }
17457  case SQL_COLUMN_OWNER_NAME:
17458  case SQL_COLUMN_QUALIFIER_NAME: {
17459  char *z = "";
17460 
17461  if (valc && valMax > 0) {
17462  strncpy(valc, z, valMax);
17463  valc[valMax - 1] = '\0';
17464  }
17465  *valLen = strlen(z);
17466  goto checkLen;
17467  }
17468  case SQL_COLUMN_TABLE_NAME:
17469 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17470  case SQL_DESC_TABLE_NAME:
17471 #endif
17472 #ifdef SQL_DESC_BASE_TABLE_NAME
17473  case SQL_DESC_BASE_TABLE_NAME:
17474 #endif
17475  if (valc && valMax > 0) {
17476  strncpy(valc, c->table, valMax);
17477  valc[valMax - 1] = '\0';
17478  }
17479  *valLen = strlen(c->table);
17480  goto checkLen;
17481 #ifdef SQL_DESC_NUM_PREC_RADIX
17482  case SQL_DESC_NUM_PREC_RADIX:
17483  if (val2) {
17484  switch (c->type) {
17485 #ifdef WINTERFACE
17486  case SQL_WCHAR:
17487  case SQL_WVARCHAR:
17488 #ifdef SQL_LONGVARCHAR
17489  case SQL_WLONGVARCHAR:
17490 #endif
17491 #endif
17492  case SQL_CHAR:
17493  case SQL_VARCHAR:
17494 #ifdef SQL_LONGVARCHAR
17495  case SQL_LONGVARCHAR:
17496 #endif
17497  case SQL_BINARY:
17498  case SQL_VARBINARY:
17499  case SQL_LONGVARBINARY:
17500  *val2 = 0;
17501  break;
17502  default:
17503  *val2 = 2;
17504  }
17505  }
17506  *valLen = sizeof (int);
17507  return SQL_SUCCESS;
17508 #endif
17509  }
17510  setstat(s, -1, "unsupported column attributes %d", "HY091", id);
17511  return SQL_ERROR;
17512 }
17513 
17514 #ifndef WINTERFACE
17515 
17527 SQLRETURN SQL_API
17528 SQLColAttributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17529  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17530  SQLLEN *val2)
17531 {
17532 #if defined(_WIN32) || defined(_WIN64)
17533  SQLSMALLINT len = 0;
17534 #endif
17535  SQLRETURN ret;
17536 
17537  HSTMT_LOCK(stmt);
17538 #if defined(_WIN32) || defined(_WIN64)
17539  if (!((STMT *) stmt)->oemcp[0]) {
17540  ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17541  goto done;
17542  }
17543  ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17544  if (SQL_SUCCEEDED(ret)) {
17545  char *v = NULL;
17546 
17547  switch (id) {
17548  case SQL_COLUMN_LABEL:
17549  case SQL_COLUMN_NAME:
17550  case SQL_DESC_NAME:
17551  case SQL_COLUMN_TYPE_NAME:
17552  case SQL_COLUMN_OWNER_NAME:
17553  case SQL_COLUMN_QUALIFIER_NAME:
17554  case SQL_COLUMN_TABLE_NAME:
17555 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17556  case SQL_DESC_TABLE_NAME:
17557 #endif
17558 #ifdef SQL_DESC_BASE_COLUMN_NAME
17559  case SQL_DESC_BASE_COLUMN_NAME:
17560 #endif
17561 #ifdef SQL_DESC_BASE_TABLE_NAME
17562  case SQL_DESC_BASE_TABLE_NAME:
17563 #endif
17564  if (val && valMax > 0) {
17565  int vmax = valMax;
17566 
17567  v = utf_to_wmb((char *) val, SQL_NTS);
17568  if (v) {
17569  strncpy(val, v, vmax);
17570  len = min(vmax, strlen(v));
17571  uc_free(v);
17572  }
17573  if (vmax > 0) {
17574  v = (char *) val;
17575  v[vmax - 1] = '\0';
17576  }
17577  }
17578  if (len <= 0) {
17579  len = 0;
17580  }
17581  break;
17582  }
17583  if (valLen) {
17584  *valLen = len;
17585  }
17586  }
17587 done:
17588  ;
17589 #else
17590  ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17591 #endif
17592  HSTMT_UNLOCK(stmt);
17593  return ret;
17594 }
17595 #endif
17596 
17597 #ifdef WINTERFACE
17598 
17610 SQLRETURN SQL_API
17611 SQLColAttributesW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17612  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17613  SQLLEN *val2)
17614 {
17615  SQLRETURN ret;
17616  SQLSMALLINT len = 0;
17617 
17618  HSTMT_LOCK(stmt);
17619  ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17620  if (SQL_SUCCEEDED(ret)) {
17621  SQLWCHAR *v = NULL;
17622 
17623  switch (id) {
17624  case SQL_COLUMN_LABEL:
17625  case SQL_COLUMN_NAME:
17626  case SQL_DESC_NAME:
17627  case SQL_COLUMN_TYPE_NAME:
17628  case SQL_COLUMN_OWNER_NAME:
17629  case SQL_COLUMN_QUALIFIER_NAME:
17630  case SQL_COLUMN_TABLE_NAME:
17631 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17632  case SQL_DESC_TABLE_NAME:
17633 #endif
17634 #ifdef SQL_DESC_BASE_COLUMN_NAME
17635  case SQL_DESC_BASE_COLUMN_NAME:
17636 #endif
17637 #ifdef SQL_DESC_BASE_TABLE_NAME
17638  case SQL_DESC_BASE_TABLE_NAME:
17639 #endif
17640  if (val && valMax > 0) {
17641  int vmax = valMax / sizeof (SQLWCHAR);
17642 
17643  v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
17644  if (v) {
17645  uc_strncpy(val, v, vmax);
17646  len = min(vmax, uc_strlen(v));
17647  uc_free(v);
17648  len *= sizeof (SQLWCHAR);
17649  }
17650  if (vmax > 0) {
17651  v = (SQLWCHAR *) val;
17652  v[vmax - 1] = '\0';
17653  }
17654  }
17655  if (len <= 0) {
17656  len = 0;
17657  }
17658  break;
17659  }
17660  if (valLen) {
17661  *valLen = len;
17662  }
17663  }
17664  HSTMT_UNLOCK(stmt);
17665  return ret;
17666 }
17667 #endif
17668 
17681 static SQLRETURN
17682 drvcolattribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17683  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17684  SQLPOINTER val2)
17685 {
17686  STMT *s;
17687  COL *c;
17688  int v = 0;
17689  char *valc = (char *) val;
17690  SQLSMALLINT dummy;
17691 
17692  if (stmt == SQL_NULL_HSTMT) {
17693  return SQL_INVALID_HANDLE;
17694  }
17695  s = (STMT *) stmt;
17696  if (!s->cols) {
17697  return SQL_ERROR;
17698  }
17699  if (col < 1 || col > s->ncols) {
17700  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
17701  return SQL_ERROR;
17702  }
17703  if (!valLen) {
17704  valLen = &dummy;
17705  }
17706  c = s->cols + col - 1;
17707  switch (id) {
17708  case SQL_DESC_COUNT:
17709  v = s->ncols;
17710  break;
17711  case SQL_DESC_CATALOG_NAME:
17712  if (valc && valMax > 0) {
17713  strncpy(valc, c->db, valMax);
17714  valc[valMax - 1] = '\0';
17715  }
17716  *valLen = strlen(c->db);
17717 checkLen:
17718  if (*valLen >= valMax) {
17719  setstat(s, -1, "data right truncated", "01004");
17720  return SQL_SUCCESS_WITH_INFO;
17721  }
17722  break;
17723  case SQL_COLUMN_LENGTH:
17724  case SQL_DESC_LENGTH:
17725  v = c->size;
17726  break;
17727  case SQL_COLUMN_LABEL:
17728  if (c->label) {
17729  if (valc && valMax > 0) {
17730  strncpy(valc, c->label, valMax);
17731  valc[valMax - 1] = '\0';
17732  }
17733  *valLen = strlen(c->label);
17734  goto checkLen;
17735  }
17736  /* fall through */
17737  case SQL_COLUMN_NAME:
17738  case SQL_DESC_NAME:
17739  if (valc && valMax > 0) {
17740  strncpy(valc, c->column, valMax);
17741  valc[valMax - 1] = '\0';
17742  }
17743  *valLen = strlen(c->column);
17744  goto checkLen;
17745  case SQL_DESC_SCHEMA_NAME: {
17746  char *z = "";
17747 
17748  if (valc && valMax > 0) {
17749  strncpy(valc, z, valMax);
17750  valc[valMax - 1] = '\0';
17751  }
17752  *valLen = strlen(z);
17753  goto checkLen;
17754  }
17755 #ifdef SQL_DESC_BASE_COLUMN_NAME
17756  case SQL_DESC_BASE_COLUMN_NAME:
17757  if (strchr(c->column, '(') || strchr(c->column, ')')) {
17758  valc[0] = '\0';
17759  *valLen = 0;
17760  } else if (valc && valMax > 0) {
17761  strncpy(valc, c->column, valMax);
17762  valc[valMax - 1] = '\0';
17763  *valLen = strlen(c->column);
17764  }
17765  goto checkLen;
17766 #endif
17767  case SQL_DESC_TYPE_NAME: {
17768  char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17769 
17770 #ifdef WINTERFACE
17771  if (c->type == SQL_WCHAR ||
17772  c->type == SQL_WVARCHAR ||
17773  c->type == SQL_WLONGVARCHAR) {
17774  if (!(s->nowchar[0] || s->nowchar[1])) {
17775  if (strcasecmp(tn, "varchar") == 0) {
17776  tn = "wvarchar";
17777  }
17778  }
17779  }
17780 #endif
17781  if (valc && valMax > 0) {
17782  strncpy(valc, tn, valMax);
17783  valc[valMax - 1] = '\0';
17784  p = strchr(valc, '(');
17785  if (p) {
17786  *p = '\0';
17787  while (p > valc && ISSPACE(p[-1])) {
17788  --p;
17789  *p = '\0';
17790  }
17791  }
17792  *valLen = strlen(valc);
17793  } else {
17794  *valLen = strlen(tn);
17795  p = strchr(tn, '(');
17796  if (p) {
17797  *valLen = p - tn;
17798  while (p > tn && ISSPACE(p[-1])) {
17799  --p;
17800  *valLen -= 1;
17801  }
17802  }
17803  }
17804  goto checkLen;
17805  }
17806  case SQL_DESC_OCTET_LENGTH:
17807  v = c->size;
17808 #ifdef WINTERFACE
17809  if (c->type == SQL_WCHAR ||
17810  c->type == SQL_WVARCHAR ||
17811  c->type == SQL_WLONGVARCHAR) {
17812  if (!(s->nowchar[0] || s->nowchar[1])) {
17813  v *= sizeof (SQLWCHAR);
17814  }
17815  }
17816 #endif
17817  break;
17818 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17819  case SQL_COLUMN_TABLE_NAME:
17820 #endif
17821 #ifdef SQL_DESC_BASE_TABLE_NAME
17822  case SQL_DESC_BASE_TABLE_NAME:
17823 #endif
17824  case SQL_DESC_TABLE_NAME:
17825  if (valc && valMax > 0) {
17826  strncpy(valc, c->table, valMax);
17827  valc[valMax - 1] = '\0';
17828  }
17829  *valLen = strlen(c->table);
17830  goto checkLen;
17831  case SQL_DESC_TYPE:
17832  v = c->type;
17833 #ifdef WINTERFACE
17834  if (s->nowchar[0] || s->nowchar[1]) {
17835  switch (v) {
17836  case SQL_WCHAR:
17837  v = SQL_CHAR;
17838  break;
17839  case SQL_WVARCHAR:
17840  v = SQL_VARCHAR;
17841  break;
17842 #ifdef SQL_LONGVARCHAR
17843  case SQL_WLONGVARCHAR:
17844  v = SQL_LONGVARCHAR;
17845  break;
17846 #endif
17847  }
17848  }
17849 #endif
17850  break;
17851  case SQL_DESC_CONCISE_TYPE:
17852  switch (c->type) {
17853  case SQL_INTEGER:
17854  v = SQL_C_LONG;
17855  break;
17856  case SQL_TINYINT:
17857  v = SQL_C_TINYINT;
17858  break;
17859  case SQL_SMALLINT:
17860  v = SQL_C_SHORT;
17861  break;
17862  case SQL_FLOAT:
17863  v = SQL_C_FLOAT;
17864  break;
17865  case SQL_DOUBLE:
17866  v = SQL_C_DOUBLE;
17867  break;
17868  case SQL_TIMESTAMP:
17869  v = SQL_C_TIMESTAMP;
17870  break;
17871  case SQL_TIME:
17872  v = SQL_C_TIME;
17873  break;
17874  case SQL_DATE:
17875  v = SQL_C_DATE;
17876  break;
17877 #ifdef SQL_C_TYPE_TIMESTAMP
17878  case SQL_TYPE_TIMESTAMP:
17879  v = SQL_C_TYPE_TIMESTAMP;
17880  break;
17881 #endif
17882 #ifdef SQL_C_TYPE_TIME
17883  case SQL_TYPE_TIME:
17884  v = SQL_C_TYPE_TIME;
17885  break;
17886 #endif
17887 #ifdef SQL_C_TYPE_DATE
17888  case SQL_TYPE_DATE:
17889  v = SQL_C_TYPE_DATE;
17890  break;
17891 #endif
17892 #ifdef SQL_BIT
17893  case SQL_BIT:
17894  v = SQL_C_BIT;
17895  break;
17896 #endif
17897 #ifdef SQL_BIGINT
17898  case SQL_BIGINT:
17899  v = SQL_C_SBIGINT;
17900  break;
17901 #endif
17902  default:
17903 #ifdef WINTERFACE
17904  v = (s->nowchar[0] || s->nowchar[1]) ? SQL_C_CHAR : SQL_C_WCHAR;
17905 #else
17906  v = SQL_C_CHAR;
17907 #endif
17908  break;
17909  }
17910  break;
17911  case SQL_DESC_UPDATABLE:
17912  v = SQL_TRUE;
17913  break;
17914  case SQL_COLUMN_DISPLAY_SIZE:
17915  v = c->size;
17916  break;
17917  case SQL_COLUMN_UNSIGNED:
17918  v = c->nosign ? SQL_TRUE : SQL_FALSE;
17919  break;
17920  case SQL_COLUMN_SEARCHABLE:
17921  v = SQL_SEARCHABLE;
17922  break;
17923  case SQL_COLUMN_SCALE:
17924  case SQL_DESC_SCALE:
17925  v = c->scale;
17926  break;
17927  case SQL_COLUMN_PRECISION:
17928  case SQL_DESC_PRECISION:
17929  switch (c->type) {
17930  case SQL_SMALLINT:
17931  v = 5;
17932  break;
17933  case SQL_INTEGER:
17934  v = 10;
17935  break;
17936  case SQL_FLOAT:
17937  case SQL_REAL:
17938  case SQL_DOUBLE:
17939  v = 15;
17940  break;
17941  case SQL_DATE:
17942  v = 0;
17943  break;
17944  case SQL_TIME:
17945  v = 0;
17946  break;
17947 #ifdef SQL_TYPE_TIMESTAMP
17948  case SQL_TYPE_TIMESTAMP:
17949 #endif
17950  case SQL_TIMESTAMP:
17951  v = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
17952  break;
17953  default:
17954  v = c->prec;
17955  break;
17956  }
17957  break;
17958  case SQL_COLUMN_MONEY:
17959  v = SQL_FALSE;
17960  break;
17961  case SQL_COLUMN_AUTO_INCREMENT:
17962  v = c->autoinc;
17963  break;
17964  case SQL_DESC_NULLABLE:
17965  v = c->notnull;
17966  break;
17967 #ifdef SQL_DESC_NUM_PREC_RADIX
17968  case SQL_DESC_NUM_PREC_RADIX:
17969  switch (c->type) {
17970 #ifdef WINTERFACE
17971  case SQL_WCHAR:
17972  case SQL_WVARCHAR:
17973 #ifdef SQL_LONGVARCHAR
17974  case SQL_WLONGVARCHAR:
17975 #endif
17976 #endif
17977  case SQL_CHAR:
17978  case SQL_VARCHAR:
17979 #ifdef SQL_LONGVARCHAR
17980  case SQL_LONGVARCHAR:
17981 #endif
17982  case SQL_BINARY:
17983  case SQL_VARBINARY:
17984  case SQL_LONGVARBINARY:
17985  v = 0;
17986  break;
17987  default:
17988  v = 2;
17989  }
17990  break;
17991 #endif
17992  default:
17993  setstat(s, -1, "unsupported column attribute %d", "HY091", id);
17994  return SQL_ERROR;
17995  }
17996  if (val2) {
17997  *(SQLLEN *) val2 = v;
17998  }
17999  return SQL_SUCCESS;
18000 }
18001 
18002 #ifndef WINTERFACE
18003 
18015 SQLRETURN SQL_API
18016 SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
18017  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
18019 {
18020 #if defined(_WIN32) || defined(_WIN64)
18021  SQLSMALLINT len = 0;
18022 #endif
18023  SQLRETURN ret;
18024 
18025  HSTMT_LOCK(stmt);
18026 #if defined(_WIN32) || defined(_WIN64)
18027  if (!((STMT *) stmt)->oemcp[0]) {
18028  ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
18029  (SQLPOINTER) val2);
18030  goto done;
18031  }
18032  ret = drvcolattribute(stmt, col, id, val, valMax, &len,
18033  (SQLPOINTER) val2);
18034  if (SQL_SUCCEEDED(ret)) {
18035  char *v = NULL;
18036 
18037  switch (id) {
18038  case SQL_DESC_SCHEMA_NAME:
18039  case SQL_DESC_CATALOG_NAME:
18040  case SQL_COLUMN_LABEL:
18041  case SQL_DESC_NAME:
18042  case SQL_DESC_TABLE_NAME:
18043 #ifdef SQL_DESC_BASE_TABLE_NAME
18044  case SQL_DESC_BASE_TABLE_NAME:
18045 #endif
18046 #ifdef SQL_DESC_BASE_COLUMN_NAME
18047  case SQL_DESC_BASE_COLUMN_NAME:
18048 #endif
18049  case SQL_DESC_TYPE_NAME:
18050  if (val && valMax > 0) {
18051  int vmax = valMax;
18052 
18053  v = utf_to_wmb((char *) val, SQL_NTS);
18054  if (v) {
18055  strncpy(val, v, vmax);
18056  len = min(vmax, strlen(v));
18057  uc_free(v);
18058  }
18059  if (vmax > 0) {
18060  v = (char *) val;
18061  v[vmax - 1] = '\0';
18062  }
18063  }
18064  if (len <= 0) {
18065  len = 0;
18066  }
18067  break;
18068  }
18069  if (valLen) {
18070  *valLen = len;
18071  }
18072  }
18073 done:
18074  ;
18075 #else
18076  ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
18077  (SQLPOINTER) val2);
18078 #endif
18079  HSTMT_UNLOCK(stmt);
18080  return ret;
18081 }
18082 #endif
18083 
18084 #ifdef WINTERFACE
18085 
18097 SQLRETURN SQL_API
18098 SQLColAttributeW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
18099  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
18101 {
18102  SQLRETURN ret;
18103  SQLSMALLINT len = 0;
18104 
18105  HSTMT_LOCK(stmt);
18106  ret = drvcolattribute(stmt, col, id, val, valMax, &len,
18107  (SQLPOINTER) val2);
18108  if (SQL_SUCCEEDED(ret)) {
18109  SQLWCHAR *v = NULL;
18110 
18111  switch (id) {
18112  case SQL_DESC_SCHEMA_NAME:
18113  case SQL_DESC_CATALOG_NAME:
18114  case SQL_COLUMN_LABEL:
18115  case SQL_DESC_NAME:
18116  case SQL_DESC_TABLE_NAME:
18117 #ifdef SQL_DESC_BASE_TABLE_NAME
18118  case SQL_DESC_BASE_TABLE_NAME:
18119 #endif
18120 #ifdef SQL_DESC_BASE_COLUMN_NAME
18121  case SQL_DESC_BASE_COLUMN_NAME:
18122 #endif
18123  case SQL_DESC_TYPE_NAME:
18124  if (val && valMax > 0) {
18125  int vmax = valMax / sizeof (SQLWCHAR);
18126 
18127  v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
18128  if (v) {
18129  uc_strncpy(val, v, vmax);
18130  len = min(vmax, uc_strlen(v));
18131  uc_free(v);
18132  len *= sizeof (SQLWCHAR);
18133  }
18134  if (vmax > 0) {
18135  v = (SQLWCHAR *) val;
18136  v[vmax - 1] = '\0';
18137  }
18138  }
18139  if (len <= 0) {
18140  len = 0;
18141  }
18142  break;
18143  }
18144  if (valLen) {
18145  *valLen = len;
18146  }
18147  }
18148  HSTMT_UNLOCK(stmt);
18149  return ret;
18150 }
18151 #endif
18152 
18166 static SQLRETURN
18167 drverror(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18168  SQLCHAR *sqlState, SQLINTEGER *nativeErr,
18169  SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18170 {
18171  SQLCHAR dummy0[6];
18172  SQLINTEGER dummy1;
18173  SQLSMALLINT dummy2;
18174 
18175  if (env == SQL_NULL_HENV &&
18176  dbc == SQL_NULL_HDBC &&
18177  stmt == SQL_NULL_HSTMT) {
18178  return SQL_INVALID_HANDLE;
18179  }
18180  if (sqlState) {
18181  sqlState[0] = '\0';
18182  } else {
18183  sqlState = dummy0;
18184  }
18185  if (!nativeErr) {
18186  nativeErr = &dummy1;
18187  }
18188  *nativeErr = 0;
18189  if (!errlen) {
18190  errlen = &dummy2;
18191  }
18192  *errlen = 0;
18193  if (errmsg) {
18194  if (errmax > 0) {
18195  errmsg[0] = '\0';
18196  }
18197  } else {
18198  errmsg = dummy0;
18199  errmax = 0;
18200  }
18201  if (stmt) {
18202  STMT *s = (STMT *) stmt;
18203 
18204  HSTMT_LOCK(stmt);
18205  if (s->logmsg[0] == '\0') {
18206  HSTMT_UNLOCK(stmt);
18207  goto noerr;
18208  }
18209  *nativeErr = s->naterr;
18210  strcpy((char *) sqlState, s->sqlstate);
18211  if (errmax == SQL_NTS) {
18212  strcpy((char *) errmsg, "[SQLite]");
18213  strcat((char *) errmsg, (char *) s->logmsg);
18214  *errlen = strlen((char *) errmsg);
18215  } else {
18216  strncpy((char *) errmsg, "[SQLite]", errmax);
18217  if (errmax - 8 > 0) {
18218  strncpy((char *) errmsg + 8, (char *) s->logmsg, errmax - 8);
18219  }
18220  *errlen = min(strlen((char *) s->logmsg) + 8, errmax);
18221  }
18222  s->logmsg[0] = '\0';
18223  HSTMT_UNLOCK(stmt);
18224  return SQL_SUCCESS;
18225  }
18226  if (dbc) {
18227  DBC *d = (DBC *) dbc;
18228 
18229  HDBC_LOCK(dbc);
18230  if (d->magic != DBC_MAGIC || d->logmsg[0] == '\0') {
18231  HDBC_UNLOCK(dbc);
18232  goto noerr;
18233  }
18234  *nativeErr = d->naterr;
18235  strcpy((char *) sqlState, d->sqlstate);
18236  if (errmax == SQL_NTS) {
18237  strcpy((char *) errmsg, "[SQLite]");
18238  strcat((char *) errmsg, (char *) d->logmsg);
18239  *errlen = strlen((char *) errmsg);
18240  } else {
18241  strncpy((char *) errmsg, "[SQLite]", errmax);
18242  if (errmax - 8 > 0) {
18243  strncpy((char *) errmsg + 8, (char *) d->logmsg, errmax - 8);
18244  }
18245  *errlen = min(strlen((char *) d->logmsg) + 8, errmax);
18246  }
18247  d->logmsg[0] = '\0';
18248  HDBC_UNLOCK(dbc);
18249  return SQL_SUCCESS;
18250  }
18251 noerr:
18252  sqlState[0] = '\0';
18253  errmsg[0] = '\0';
18254  *nativeErr = 0;
18255  *errlen = 0;
18256  return SQL_NO_DATA;
18257 }
18258 
18259 #ifndef WINTERFACE
18260 
18273 SQLRETURN SQL_API
18274 SQLError(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18275  SQLCHAR *sqlState, SQLINTEGER *nativeErr,
18276  SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18277 {
18278  return drverror(env, dbc, stmt, sqlState, nativeErr,
18279  errmsg, errmax, errlen);
18280 }
18281 #endif
18282 
18283 #ifdef WINTERFACE
18284 
18297 SQLRETURN SQL_API
18298 SQLErrorW(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18299  SQLWCHAR *sqlState, SQLINTEGER *nativeErr,
18300  SQLWCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18301 {
18302  char state[16];
18303  SQLSMALLINT len = 0;
18304  SQLRETURN ret;
18305 
18306  ret = drverror(env, dbc, stmt, (SQLCHAR *) state, nativeErr,
18307  (SQLCHAR *) errmsg, errmax, &len);
18308  if (ret == SQL_SUCCESS) {
18309  if (sqlState) {
18310  uc_from_utf_buf((SQLCHAR *) state, -1, sqlState,
18311  6 * sizeof (SQLWCHAR));
18312  }
18313  if (errmsg) {
18314  if (len > 0) {
18315  SQLWCHAR *e = NULL;
18316 
18317  e = uc_from_utf((SQLCHAR *) errmsg, len);
18318  if (e) {
18319  if (errmax > 0) {
18320  uc_strncpy(errmsg, e, errmax);
18321  e[len] = 0;
18322  len = min(errmax, uc_strlen(e));
18323  } else {
18324  len = uc_strlen(e);
18325  }
18326  uc_free(e);
18327  } else {
18328  len = 0;
18329  }
18330  }
18331  if (len <= 0) {
18332  len = 0;
18333  if (errmax > 0) {
18334  errmsg[0] = 0;
18335  }
18336  }
18337  } else {
18338  len = 0;
18339  }
18340  if (errlen) {
18341  *errlen = len;
18342  }
18343  } else if (ret == SQL_NO_DATA) {
18344  if (sqlState) {
18345  sqlState[0] = 0;
18346  }
18347  if (errmsg) {
18348  if (errmax > 0) {
18349  errmsg[0] = 0;
18350  }
18351  }
18352  if (errlen) {
18353  *errlen = 0;
18354  }
18355  }
18356  return ret;
18357 }
18358 #endif
18359 
18366 SQLRETURN SQL_API
18367 SQLMoreResults(SQLHSTMT stmt)
18368 {
18369  HSTMT_LOCK(stmt);
18370  if (stmt == SQL_NULL_HSTMT) {
18371  return SQL_INVALID_HANDLE;
18372  }
18373  HSTMT_UNLOCK(stmt);
18374  return SQL_NO_DATA;
18375 }
18376 
18385 static SQLRETURN
18386 setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp)
18387 {
18388  int ncols = *ncolsp, guessed_types = 0;
18389  SQLRETURN ret = SQL_SUCCESS;
18390 
18391  if (ncols > 0) {
18392  int i;
18393  PTRDIFF_T size;
18394  char *p;
18395  COL *dyncols;
18396  DBC *d = (DBC *) s->dbc;
18397  const char *colname, *typename;
18398 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18399  char *tblname;
18400 #endif
18401 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18402  char *dbname;
18403 #endif
18404 
18405  for (i = size = 0; i < ncols; i++) {
18406  colname = sqlite3_column_name(s3stmt, i);
18407  size += 3 + 3 * strlen(colname);
18408  }
18409 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18410  tblname = (char *) size;
18411  for (i = 0; i < ncols; i++) {
18412  p = (char *) sqlite3_column_table_name(s3stmt, i);
18413  size += 2 + (p ? strlen(p) : 0);
18414  }
18415 #endif
18416 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18417  dbname = (char *) size;
18418  for (i = 0; i < ncols; i++) {
18419  p = (char *) sqlite3_column_database_name(s3stmt, i);
18420  size += 2 + (p ? strlen(p) : 0);
18421  }
18422 #endif
18423  dyncols = xmalloc(ncols * sizeof (COL) + size);
18424  if (!dyncols) {
18425  freedyncols(s);
18426  *ncolsp = 0;
18427  ret = SQL_ERROR;
18428  } else {
18429  p = (char *) (dyncols + ncols);
18430 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18431  tblname = p + (PTRDIFF_T) tblname;
18432 #endif
18433 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18434  dbname = p + (PTRDIFF_T) dbname;
18435 #endif
18436  for (i = 0; i < ncols; i++) {
18437  char *q;
18438 
18439  colname = sqlite3_column_name(s3stmt, i);
18440  if (d->trace) {
18441  fprintf(d->trace, "-- column %d name: '%s'\n",
18442  i + 1, colname);
18443  fflush(d->trace);
18444  }
18445 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18446  q = (char *) sqlite3_column_table_name(s3stmt, i);
18447  strcpy(tblname, q ? q : "");
18448  if (d->trace) {
18449  fprintf(d->trace, "-- table %d name: '%s'\n",
18450  i + 1, tblname);
18451  fflush(d->trace);
18452  }
18453  dyncols[i].table = tblname;
18454  tblname += strlen(tblname) + 1;
18455 #endif
18456 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18457  q = (char *) sqlite3_column_database_name(s3stmt, i);
18458  strcpy(dbname, q ? q : "");
18459  if (d->trace) {
18460  fprintf(d->trace, "-- database %d name: '%s'\n",
18461  i + 1, dbname);
18462  fflush(d->trace);
18463  }
18464  dyncols[i].db = dbname;
18465  dbname += strlen(dbname) + 1;
18466 #else
18467  dyncols[i].db = ((DBC *) (s->dbc))->dbname;
18468 #endif
18469  typename = s3stmt_coltype(s3stmt, i, d, &guessed_types);
18470  strcpy(p, colname);
18471  dyncols[i].label = p;
18472  p += strlen(p) + 1;
18473  q = strchr(colname, '.');
18474  if (q) {
18475  char *q2 = strchr(q + 1, '.');
18476 
18477  /* SQLite 3.3.4 produces view.table.column sometimes */
18478  if (q2) {
18479  q = q2;
18480  }
18481  }
18482  if (q) {
18483 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18484  dyncols[i].table = p;
18485 #endif
18486  strncpy(p, colname, q - colname);
18487  p[q - colname] = '\0';
18488  p += strlen(p) + 1;
18489  strcpy(p, q + 1);
18490  dyncols[i].column = p;
18491  p += strlen(p) + 1;
18492  } else {
18493 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18494  dyncols[i].table = "";
18495 #endif
18496  strcpy(p, colname);
18497  dyncols[i].column = p;
18498  p += strlen(p) + 1;
18499  }
18500  if (s->longnames) {
18501  dyncols[i].column = dyncols[i].label;
18502  }
18503 #ifdef SQL_LONGVARCHAR
18504  dyncols[i].type = SQL_LONGVARCHAR;
18505  dyncols[i].size = 65535;
18506 #else
18507  dyncols[i].type = SQL_VARCHAR;
18508  dyncols[i].size = 255;
18509 #endif
18510  dyncols[i].index = i;
18511  dyncols[i].scale = 0;
18512  dyncols[i].prec = 0;
18513  dyncols[i].nosign = 1;
18514  dyncols[i].autoinc = SQL_FALSE;
18515  dyncols[i].notnull = SQL_NULLABLE;
18516  dyncols[i].ispk = -1;
18517  dyncols[i].isrowid = -1;
18518 #ifdef FULL_METADATA
18519  s3stmt_addmeta(s3stmt, i, d, &dyncols[i]);
18520 #endif
18521  dyncols[i].typename = xstrdup(typename);
18522  }
18523  freedyncols(s);
18524  s->dyncols = s->cols = dyncols;
18525  s->dcols = ncols;
18526  fixupdyncols(s, d);
18527  s->guessed_types = guessed_types;
18528  }
18529  }
18530  return ret;
18531 }
18532 
18541 static SQLRETURN
18542 drvprepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18543 {
18544  STMT *s;
18545  DBC *d;
18546  char *errp = NULL;
18547  SQLRETURN sret;
18548 
18549  if (stmt == SQL_NULL_HSTMT) {
18550  return SQL_INVALID_HANDLE;
18551  }
18552  s = (STMT *) stmt;
18553  if (s->dbc == SQL_NULL_HDBC) {
18554 noconn:
18555  return noconn(s);
18556  }
18557  d = s->dbc;
18558  if (!d->sqlite) {
18559  goto noconn;
18560  }
18561  s3stmt_end(s);
18562  s3stmt_drop(s);
18563  sret = starttran(s);
18564  if (sret != SQL_SUCCESS) {
18565  return sret;
18566  }
18567  freep(&s->query);
18568  s->query = (SQLCHAR *) fixupsql((char *) query, queryLen,
18569  (d->version >= 0x030805),
18570  &s->nparams, &s->isselect, &errp);
18571  if (!s->query) {
18572  if (errp) {
18573  setstat(s, -1, "%s", (*s->ov3) ? "HY000" : "S1000", errp);
18574  return SQL_ERROR;
18575  }
18576  return nomem(s);
18577  }
18578  errp = NULL;
18579  freeresult(s, -1);
18580  if (s->isselect == 1) {
18581  int ret, ncols, nretry = 0;
18582  const char *rest;
18583  sqlite3_stmt *s3stmt = NULL;
18584 
18585 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18586  dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
18587 #else
18588  dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
18589 #endif
18590  do {
18591  s3stmt = NULL;
18592 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18593  ret = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
18594  &s3stmt, &rest);
18595 #else
18596  ret = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
18597  &s3stmt, &rest);
18598 #endif
18599  if (ret != SQLITE_OK) {
18600  if (s3stmt) {
18601  sqlite3_finalize(s3stmt);
18602  s3stmt = NULL;
18603  }
18604  }
18605  } while (ret == SQLITE_SCHEMA && (++nretry) < 2);
18606  dbtracerc(d, ret, NULL);
18607  if (ret != SQLITE_OK) {
18608  if (s3stmt) {
18609  dbtraceapi(d, "sqlite3_finalize", 0);
18610  sqlite3_finalize(s3stmt);
18611  }
18612  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18613  sqlite3_errmsg(d->sqlite), ret);
18614  return SQL_ERROR;
18615  }
18616  if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
18617  dbtraceapi(d, "sqlite3_finalize", 0);
18618  sqlite3_finalize(s3stmt);
18619  setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
18620  (*s->ov3) ? "HY000" : "S1000");
18621  return SQL_ERROR;
18622  }
18623  ncols = sqlite3_column_count(s3stmt);
18624  s->guessed_types = 0;
18625  setupdyncols(s, s3stmt, &ncols);
18626  s->ncols = ncols;
18627  s->s3stmt = s3stmt;
18628  }
18629  mkbindcols(s, s->ncols);
18630  s->paramset_count = 0;
18631  return SQL_SUCCESS;
18632 }
18633 
18641 static SQLRETURN
18642 drvexecute(SQLHSTMT stmt, int initial)
18643 {
18644  STMT *s;
18645  DBC *d;
18646  char *errp = NULL;
18647  int rc, i, ncols = 0, nrows = 0, busy_count;
18648  SQLRETURN ret;
18649 
18650  if (stmt == SQL_NULL_HSTMT) {
18651  return SQL_INVALID_HANDLE;
18652  }
18653  s = (STMT *) stmt;
18654  if (s->dbc == SQL_NULL_HDBC) {
18655 noconn:
18656  return noconn(s);
18657  }
18658  d = (DBC *) s->dbc;
18659  if (!d->sqlite) {
18660  goto noconn;
18661  }
18662  if (!s->query) {
18663  setstat(s, -1, "no query prepared", (*s->ov3) ? "HY000" : "S1000");
18664  return SQL_ERROR;
18665  }
18666  if (s->nbindparms < s->nparams) {
18667 unbound:
18668  setstat(s, -1, "unbound parameters in query",
18669  (*s->ov3) ? "HY000" : "S1000");
18670  return SQL_ERROR;
18671  }
18672  for (i = 0; i < s->nparams; i++) {
18673  BINDPARM *p = &s->bindparms[i];
18674 
18675  if (!p->bound) {
18676  goto unbound;
18677  }
18678  if (initial) {
18679  SQLLEN *lenp = p->lenp;
18680 
18681  if (lenp && *lenp < 0 && *lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18682  *lenp != SQL_NTS && *lenp != SQL_NULL_DATA &&
18683  *lenp != SQL_DATA_AT_EXEC) {
18684  setstat(s, -1, "invalid length reference", "HY009");
18685  return SQL_ERROR;
18686  }
18687  if (lenp && (*lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18688  *lenp == SQL_DATA_AT_EXEC)) {
18689  p->need = 1;
18690  p->offs = 0;
18691  p->len = 0;
18692  }
18693  }
18694  }
18695  ret = starttran(s);
18696  if (ret != SQL_SUCCESS) {
18697  goto cleanup;
18698  }
18699  busy_count = 0;
18700 again:
18701  s3stmt_end(s);
18702  if (initial) {
18703  /* fixup data-at-execution parameters and alloc'ed blobs */
18704  s->pdcount = -1;
18705  for (i = 0; i < s->nparams; i++) {
18706  BINDPARM *p = &s->bindparms[i];
18707 
18708  if (p->param == p->parbuf) {
18709  p->param = NULL;
18710  }
18711  freep(&p->parbuf);
18712  if (p->need <= 0 &&
18713  p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18714  *p->lenp == SQL_DATA_AT_EXEC)) {
18715  p->need = 1;
18716  p->offs = 0;
18717  p->len = 0;
18718  }
18719  }
18720  }
18721  if (s->nparams) {
18722  for (i = 0; i < s->nparams; i++) {
18723  ret = setupparam(s, (char *) s->query, i);
18724  if (ret != SQL_SUCCESS) {
18725  goto cleanup;
18726  }
18727  }
18728  }
18729  freeresult(s, 0);
18730  if (s->isselect == 1 && !d->intrans &&
18731  s->curtype == SQL_CURSOR_FORWARD_ONLY &&
18732  d->step_enable && s->nparams == 0 && d->cur_s3stmt == NULL) {
18733  s->nrows = -1;
18734  ret = s3stmt_start(s);
18735  if (ret == SQL_SUCCESS) {
18736  goto done2;
18737  }
18738  }
18739  rc = drvgettable(s, s->s3stmt ? NULL : (char *) s->query, &s->rows,
18740  &s->nrows, &ncols, &errp, s->nparams, s->bindparms);
18741  dbtracerc(d, rc, errp);
18742  if (rc == SQLITE_BUSY) {
18743  if (busy_handler((void *) d, ++busy_count)) {
18744  if (errp) {
18745  sqlite3_free(errp);
18746  errp = NULL;
18747  }
18748  for (i = 0; i < s->nparams; i++) {
18749  BINDPARM *p = &s->bindparms[i];
18750 
18751  if (p->param == p->parbuf) {
18752  p->param = NULL;
18753  }
18754  freep(&p->parbuf);
18755  if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18756  *p->lenp != SQL_DATA_AT_EXEC)) {
18757  p->param = p->param0;
18758  }
18759  p->lenp = p->lenp0;
18760  }
18761  s->nrows = 0;
18762  goto again;
18763  }
18764  }
18765  if (rc != SQLITE_OK) {
18766  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18767  errp ? errp : "unknown error", rc);
18768  if (errp) {
18769  sqlite3_free(errp);
18770  errp = NULL;
18771  }
18772  ret = SQL_ERROR;
18773  goto cleanup;
18774  }
18775  if (errp) {
18776  sqlite3_free(errp);
18777  errp = NULL;
18778  }
18779  s->rowfree = freerows;
18780  if (s->isselect <= 0 || s->isselect > 1) {
18781  /*
18782  * INSERT/UPDATE/DELETE or DDL results are immediately released.
18783  */
18784  freeresult(s, -1);
18785  nrows += sqlite3_changes(d->sqlite);
18786  s->nrows = nrows;
18787  goto done;
18788  }
18789  if (s->ncols != ncols) {
18790  /*
18791  * Weird result.
18792  */
18793  setstat(s, -1, "broken result set %d/%d",
18794  (*s->ov3) ? "HY000" : "S1000", s->ncols, ncols);
18795  ret = SQL_ERROR;
18796  goto cleanup;
18797  }
18798 done:
18799  mkbindcols(s, s->ncols);
18800 done2:
18801  ret = SQL_SUCCESS;
18802  s->rowp = s->rowprs = -1;
18803  s->paramset_count++;
18804  s->paramset_nrows = s->nrows;
18805  if (s->paramset_count < s->paramset_size) {
18806  for (i = 0; i < s->nparams; i++) {
18807  BINDPARM *p = &s->bindparms[i];
18808 
18809  if (p->param == p->parbuf) {
18810  p->param = NULL;
18811  }
18812  freep(&p->parbuf);
18813  if (p->lenp0 &&
18814  s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18815  p->lenp = (SQLLEN *) ((char *) p->lenp0 +
18816  s->paramset_count * s->parm_bind_type);
18817  } else if (p->lenp0 && p->inc > 0) {
18818  p->lenp = p->lenp0 + s->paramset_count;
18819  }
18820  if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18821  *p->lenp != SQL_DATA_AT_EXEC)) {
18822  if (p->param0 &&
18823  s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18824  p->param = (char *) p->param0 +
18826  } else if (p->param0 && p->inc > 0) {
18827  p->param = (char *) p->param0 +
18828  s->paramset_count * p->inc;
18829  }
18830  } else if (p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18831  *p->lenp == SQL_DATA_AT_EXEC)) {
18832  p->need = 1;
18833  p->offs = 0;
18834  p->len = 0;
18835  }
18836  }
18837  goto again;
18838  }
18839 cleanup:
18840  if (ret != SQL_NEED_DATA) {
18841  for (i = 0; i < s->nparams; i++) {
18842  BINDPARM *p = &s->bindparms[i];
18843 
18844  if (p->param == p->parbuf) {
18845  p->param = NULL;
18846  }
18847  freep(&p->parbuf);
18848  if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18849  *p->lenp != SQL_DATA_AT_EXEC)) {
18850  p->param = p->param0;
18851  }
18852  p->lenp = p->lenp0;
18853  }
18854  s->nrows = s->paramset_nrows;
18855  if (s->parm_proc) {
18856  *s->parm_proc = s->paramset_count;
18857  }
18858  s->paramset_count = 0;
18859  s->paramset_nrows = 0;
18860  }
18861  /*
18862  * For INSERT/UPDATE/DELETE statements change the return code
18863  * to SQL_NO_DATA if the number of rows affected was 0.
18864  */
18865  if (*s->ov3 && s->isselect == 0 &&
18866  ret == SQL_SUCCESS && nrows == 0) {
18867  ret = SQL_NO_DATA;
18868  }
18869  return ret;
18870 }
18871 
18872 #ifndef WINTERFACE
18873 
18881 SQLRETURN SQL_API
18882 SQLPrepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18883 {
18884  SQLRETURN ret;
18885 #if defined(_WIN32) || defined(_WIN64)
18886  char *q;
18887 #endif
18888 
18889  HSTMT_LOCK(stmt);
18890 #if defined(_WIN32) || defined(_WIN64)
18891  if (!((STMT *) stmt)->oemcp[0]) {
18892  ret = drvprepare(stmt, query, queryLen);
18893  goto done;
18894  }
18895  q = wmb_to_utf_c((char *) query, queryLen);
18896  if (!q) {
18897  ret = nomem((STMT *) stmt);
18898  goto done;
18899  }
18900  query = (SQLCHAR *) q;
18901  queryLen = SQL_NTS;
18902 #endif
18903  ret = drvprepare(stmt, query, queryLen);
18904 #if defined(_WIN32) || defined(_WIN64)
18905  uc_free(q);
18906 done:
18907  ;
18908 #endif
18909  HSTMT_UNLOCK(stmt);
18910  return ret;
18911 }
18912 #endif
18913 
18914 #ifdef WINTERFACE
18915 
18923 SQLRETURN SQL_API
18924 SQLPrepareW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
18925 {
18926  SQLRETURN ret;
18927  char *q = uc_to_utf_c(query, queryLen);
18928 
18929  HSTMT_LOCK(stmt);
18930  if (!q) {
18931  ret = nomem((STMT *) stmt);
18932  goto done;
18933  }
18934  ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
18935  uc_free(q);
18936 done:
18937  HSTMT_UNLOCK(stmt);
18938  return ret;
18939 }
18940 #endif
18941 
18948 SQLRETURN SQL_API
18949 SQLExecute(SQLHSTMT stmt)
18950 {
18951  SQLRETURN ret;
18952 
18953  HSTMT_LOCK(stmt);
18954  ret = drvexecute(stmt, 1);
18955  HSTMT_UNLOCK(stmt);
18956  return ret;
18957 }
18958 
18959 #ifndef WINTERFACE
18960 
18968 SQLRETURN SQL_API
18969 SQLExecDirect(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18970 {
18971  SQLRETURN ret;
18972 #if defined(_WIN32) || defined(_WIN64)
18973  char *q;
18974 #endif
18975 
18976  HSTMT_LOCK(stmt);
18977 #if defined(_WIN32) || defined(_WIN64)
18978  if (!((STMT *) stmt)->oemcp[0]) {
18979  ret = drvprepare(stmt, query, queryLen);
18980  if (ret == SQL_SUCCESS) {
18981  ret = drvexecute(stmt, 1);
18982  }
18983  goto done;
18984  }
18985  q = wmb_to_utf_c((char *) query, queryLen);
18986  if (!q) {
18987  ret = nomem((STMT *) stmt);
18988  goto done;
18989  }
18990  query = (SQLCHAR *) q;
18991  queryLen = SQL_NTS;
18992 #endif
18993  ret = drvprepare(stmt, query, queryLen);
18994  if (ret == SQL_SUCCESS) {
18995  ret = drvexecute(stmt, 1);
18996  }
18997 #if defined(_WIN32) || defined(_WIN64)
18998  uc_free(q);
18999 done:
19000  ;
19001 #endif
19002  HSTMT_UNLOCK(stmt);
19003  return ret;
19004 }
19005 #endif
19006 
19007 #ifdef WINTERFACE
19008 
19016 SQLRETURN SQL_API
19017 SQLExecDirectW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
19018 {
19019  SQLRETURN ret;
19020  char *q = uc_to_utf_c(query, queryLen);
19021 
19022  HSTMT_LOCK(stmt);
19023  if (!q) {
19024  ret = nomem((STMT *) stmt);
19025  goto done;
19026  }
19027  ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
19028  uc_free(q);
19029  if (ret == SQL_SUCCESS) {
19030  ret = drvexecute(stmt, 1);
19031  }
19032 done:
19033  HSTMT_UNLOCK(stmt);
19034  return ret;
19035 }
19036 #endif
19037 
19038 
19039 #if defined(_WIN32) || defined(_WIN64)
19040 #ifndef WITHOUT_DRIVERMGR
19041 
19042 /*
19043  * Windows configuration dialog stuff.
19044  */
19045 
19046 #include <windowsx.h>
19047 #include <winuser.h>
19048 
19049 #define MAXPATHLEN (259+1) /* Max path length */
19050 #define MAXKEYLEN (15+1) /* Max keyword length */
19051 #define MAXDESC (255+1) /* Max description length */
19052 #define MAXDSNAME (255+1) /* Max data source name length */
19053 #define MAXTONAME (32+1) /* Max timeout length */
19054 #define MAXDBNAME MAXPATHLEN
19055 
19056 /* Attribute key indexes into an array of Attr structs, see below */
19057 
19058 #define KEY_DSN 0
19059 #define KEY_DESC 1
19060 #define KEY_DBNAME 2
19061 #define KEY_BUSY 3
19062 #define KEY_DRIVER 4
19063 #define KEY_STEPAPI 5
19064 #define KEY_SYNCP 6
19065 #define KEY_NOTXN 7
19066 #define KEY_SHORTNAM 8
19067 #define KEY_LONGNAM 9
19068 #define KEY_NOCREAT 10
19069 #define KEY_NOWCHAR 11
19070 #define KEY_LOADEXT 12
19071 #define KEY_JMODE 13
19072 #define KEY_FKSUPPORT 14
19073 #define KEY_OEMCP 15
19074 #define KEY_BIGINT 16
19075 #define KEY_PASSWD 17
19076 #define KEY_JDCONV 18
19077 #define NUMOFKEYS 19
19078 
19079 typedef struct {
19080  BOOL supplied;
19081  char attr[MAXPATHLEN*4];
19082 } ATTR;
19083 
19084 typedef struct {
19085  SQLHWND parent;
19086  LPCSTR driver;
19087  ATTR attr[NUMOFKEYS];
19088  char DSN[MAXDSNAME];
19089  BOOL newDSN;
19090  BOOL defDSN;
19091 } SETUPDLG;
19092 
19093 static struct {
19094  char *key;
19095  int ikey;
19096 } attrLookup[] = {
19097  { "DSN", KEY_DSN },
19098  { "DESC", KEY_DESC },
19099  { "Description", KEY_DESC},
19100  { "Database", KEY_DBNAME },
19101  { "Timeout", KEY_BUSY },
19102  { "Driver", KEY_DRIVER },
19103  { "StepAPI", KEY_STEPAPI },
19104  { "SyncPragma", KEY_SYNCP },
19105  { "NoTXN", KEY_NOTXN },
19106  { "ShortNames", KEY_SHORTNAM },
19107  { "LongNames", KEY_LONGNAM },
19108  { "NoCreat", KEY_NOCREAT },
19109  { "NoWCHAR", KEY_NOWCHAR },
19110  { "LoadExt", KEY_LOADEXT },
19111  { "JournalMode", KEY_JMODE },
19112  { "FKSupport", KEY_FKSUPPORT },
19113  { "OEMCP", KEY_OEMCP },
19114  { "BigInt", KEY_BIGINT },
19115  { "PWD", KEY_PASSWD },
19116  { "JDConv", KEY_JDCONV },
19117  { NULL, 0 }
19118 };
19119 
19126 static void
19127 ParseAttributes(LPCSTR attribs, SETUPDLG *setupdlg)
19128 {
19129  char *str = (char *) attribs, *start, key[MAXKEYLEN];
19130  int elem, nkey;
19131 
19132  while (*str) {
19133  start = str;
19134  if ((str = strchr(str, '=')) == NULL) {
19135  return;
19136  }
19137  elem = -1;
19138  nkey = str - start;
19139  if (nkey < sizeof (key)) {
19140  int i;
19141 
19142  memcpy(key, start, nkey);
19143  key[nkey] = '\0';
19144  for (i = 0; attrLookup[i].key; i++) {
19145  if (strcasecmp(attrLookup[i].key, key) == 0) {
19146  elem = attrLookup[i].ikey;
19147  break;
19148  }
19149  }
19150  }
19151  start = ++str;
19152  while (*str && *str != ';') {
19153  ++str;
19154  }
19155  if (elem >= 0) {
19156  int end = min(str - start, sizeof (setupdlg->attr[elem].attr) - 1);
19157 
19158  setupdlg->attr[elem].supplied = TRUE;
19159  memcpy(setupdlg->attr[elem].attr, start, end);
19160  setupdlg->attr[elem].attr[end] = '\0';
19161  }
19162  ++str;
19163  }
19164 }
19165 
19173 static BOOL
19174 SetDSNAttributes(HWND parent, SETUPDLG *setupdlg)
19175 {
19176  char *dsn = setupdlg->attr[KEY_DSN].attr;
19177 
19178  if (setupdlg->newDSN && strlen(dsn) == 0) {
19179  return FALSE;
19180  }
19181  if (!SQLWriteDSNToIni(dsn, setupdlg->driver)) {
19182  if (parent) {
19183  char buf[MAXPATHLEN], msg[MAXPATHLEN];
19184 
19185  LoadString(hModule, IDS_BADDSN, buf, sizeof (buf));
19186  wsprintf(msg, buf, dsn);
19187  LoadString(hModule, IDS_MSGTITLE, buf, sizeof (buf));
19188  MessageBox(parent, msg, buf,
19189  MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
19190  MB_SETFOREGROUND);
19191  }
19192  return FALSE;
19193  }
19194  if (parent || setupdlg->attr[KEY_DESC].supplied) {
19195  SQLWritePrivateProfileString(dsn, "Description",
19196  setupdlg->attr[KEY_DESC].attr,
19197  ODBC_INI);
19198  }
19199  if (parent || setupdlg->attr[KEY_DBNAME].supplied) {
19200  SQLWritePrivateProfileString(dsn, "Database",
19201  setupdlg->attr[KEY_DBNAME].attr,
19202  ODBC_INI);
19203  }
19204  if (parent || setupdlg->attr[KEY_BUSY].supplied) {
19205  SQLWritePrivateProfileString(dsn, "Timeout",
19206  setupdlg->attr[KEY_BUSY].attr,
19207  ODBC_INI);
19208  }
19209  if (parent || setupdlg->attr[KEY_STEPAPI].supplied) {
19210  SQLWritePrivateProfileString(dsn, "StepAPI",
19211  setupdlg->attr[KEY_STEPAPI].attr,
19212  ODBC_INI);
19213  }
19214  if (parent || setupdlg->attr[KEY_SYNCP].supplied) {
19215  SQLWritePrivateProfileString(dsn, "SyncPragma",
19216  setupdlg->attr[KEY_SYNCP].attr,
19217  ODBC_INI);
19218  }
19219  if (parent || setupdlg->attr[KEY_NOTXN].supplied) {
19220  SQLWritePrivateProfileString(dsn, "NoTXN",
19221  setupdlg->attr[KEY_NOTXN].attr,
19222  ODBC_INI);
19223  }
19224  if (parent || setupdlg->attr[KEY_SHORTNAM].supplied) {
19225  SQLWritePrivateProfileString(dsn, "ShortNames",
19226  setupdlg->attr[KEY_SHORTNAM].attr,
19227  ODBC_INI);
19228  }
19229  if (parent || setupdlg->attr[KEY_LONGNAM].supplied) {
19230  SQLWritePrivateProfileString(dsn, "LongNames",
19231  setupdlg->attr[KEY_LONGNAM].attr,
19232  ODBC_INI);
19233  }
19234  if (parent || setupdlg->attr[KEY_NOCREAT].supplied) {
19235  SQLWritePrivateProfileString(dsn, "NoCreat",
19236  setupdlg->attr[KEY_NOCREAT].attr,
19237  ODBC_INI);
19238  }
19239  if (parent || setupdlg->attr[KEY_NOWCHAR].supplied) {
19240  SQLWritePrivateProfileString(dsn, "NoWCHAR",
19241  setupdlg->attr[KEY_NOWCHAR].attr,
19242  ODBC_INI);
19243  }
19244  if (parent || setupdlg->attr[KEY_FKSUPPORT].supplied) {
19245  SQLWritePrivateProfileString(dsn, "FKSupport",
19246  setupdlg->attr[KEY_FKSUPPORT].attr,
19247  ODBC_INI);
19248  }
19249  if (parent || setupdlg->attr[KEY_OEMCP].supplied) {
19250  SQLWritePrivateProfileString(dsn, "OEMCP",
19251  setupdlg->attr[KEY_OEMCP].attr,
19252  ODBC_INI);
19253  }
19254  if (parent || setupdlg->attr[KEY_LOADEXT].supplied) {
19255  SQLWritePrivateProfileString(dsn, "LoadExt",
19256  setupdlg->attr[KEY_LOADEXT].attr,
19257  ODBC_INI);
19258  }
19259  if (parent || setupdlg->attr[KEY_BIGINT].supplied) {
19260  SQLWritePrivateProfileString(dsn, "BigInt",
19261  setupdlg->attr[KEY_BIGINT].attr,
19262  ODBC_INI);
19263  }
19264  if (parent || setupdlg->attr[KEY_JDCONV].supplied) {
19265  SQLWritePrivateProfileString(dsn, "JDConv",
19266  setupdlg->attr[KEY_JDCONV].attr,
19267  ODBC_INI);
19268  }
19269  if (parent || setupdlg->attr[KEY_PASSWD].supplied) {
19270  SQLWritePrivateProfileString(dsn, "PWD",
19271  setupdlg->attr[KEY_PASSWD].attr,
19272  ODBC_INI);
19273  }
19274  if (setupdlg->attr[KEY_DSN].supplied &&
19275  strcasecmp(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr)) {
19276  SQLRemoveDSNFromIni(setupdlg->DSN);
19277  }
19278  return TRUE;
19279 }
19280 
19286 static void
19287 GetAttributes(SETUPDLG *setupdlg)
19288 {
19289  char *dsn = setupdlg->attr[KEY_DSN].attr;
19290 
19291  if (!setupdlg->attr[KEY_DESC].supplied) {
19292  SQLGetPrivateProfileString(dsn, "Description", "",
19293  setupdlg->attr[KEY_DESC].attr,
19294  sizeof (setupdlg->attr[KEY_DESC].attr),
19295  ODBC_INI);
19296  }
19297  if (!setupdlg->attr[KEY_DBNAME].supplied) {
19298  SQLGetPrivateProfileString(dsn, "Database", "",
19299  setupdlg->attr[KEY_DBNAME].attr,
19300  sizeof (setupdlg->attr[KEY_DBNAME].attr),
19301  ODBC_INI);
19302  }
19303  if (!setupdlg->attr[KEY_BUSY].supplied) {
19304  SQLGetPrivateProfileString(dsn, "Timeout", "100000",
19305  setupdlg->attr[KEY_BUSY].attr,
19306  sizeof (setupdlg->attr[KEY_BUSY].attr),
19307  ODBC_INI);
19308  }
19309  if (!setupdlg->attr[KEY_STEPAPI].supplied) {
19310  SQLGetPrivateProfileString(dsn, "StepAPI", "0",
19311  setupdlg->attr[KEY_STEPAPI].attr,
19312  sizeof (setupdlg->attr[KEY_STEPAPI].attr),
19313  ODBC_INI);
19314  }
19315  if (!setupdlg->attr[KEY_SYNCP].supplied) {
19316  SQLGetPrivateProfileString(dsn, "SyncPragma", "NORMAL",
19317  setupdlg->attr[KEY_SYNCP].attr,
19318  sizeof (setupdlg->attr[KEY_SYNCP].attr),
19319  ODBC_INI);
19320  }
19321  if (!setupdlg->attr[KEY_NOTXN].supplied) {
19322  SQLGetPrivateProfileString(dsn, "NoTXN", "",
19323  setupdlg->attr[KEY_NOTXN].attr,
19324  sizeof (setupdlg->attr[KEY_NOTXN].attr),
19325  ODBC_INI);
19326  }
19327  if (!setupdlg->attr[KEY_SHORTNAM].supplied) {
19328  SQLGetPrivateProfileString(dsn, "ShortNames", "",
19329  setupdlg->attr[KEY_SHORTNAM].attr,
19330  sizeof (setupdlg->attr[KEY_SHORTNAM].attr),
19331  ODBC_INI);
19332  }
19333  if (!setupdlg->attr[KEY_LONGNAM].supplied) {
19334  SQLGetPrivateProfileString(dsn, "LongNames", "",
19335  setupdlg->attr[KEY_LONGNAM].attr,
19336  sizeof (setupdlg->attr[KEY_LONGNAM].attr),
19337  ODBC_INI);
19338  }
19339  if (!setupdlg->attr[KEY_NOCREAT].supplied) {
19340  SQLGetPrivateProfileString(dsn, "NoCreat", "",
19341  setupdlg->attr[KEY_NOCREAT].attr,
19342  sizeof (setupdlg->attr[KEY_NOCREAT].attr),
19343  ODBC_INI);
19344  }
19345  if (!setupdlg->attr[KEY_NOWCHAR].supplied) {
19346  SQLGetPrivateProfileString(dsn, "NoWCHAR", "",
19347  setupdlg->attr[KEY_NOWCHAR].attr,
19348  sizeof (setupdlg->attr[KEY_NOWCHAR].attr),
19349  ODBC_INI);
19350  }
19351  if (!setupdlg->attr[KEY_FKSUPPORT].supplied) {
19352  SQLGetPrivateProfileString(dsn, "FKSupport", "",
19353  setupdlg->attr[KEY_FKSUPPORT].attr,
19354  sizeof (setupdlg->attr[KEY_FKSUPPORT].attr),
19355  ODBC_INI);
19356  }
19357  if (!setupdlg->attr[KEY_OEMCP].supplied) {
19358  SQLGetPrivateProfileString(dsn, "OEMCP", "",
19359  setupdlg->attr[KEY_OEMCP].attr,
19360  sizeof (setupdlg->attr[KEY_OEMCP].attr),
19361  ODBC_INI);
19362  }
19363  if (!setupdlg->attr[KEY_LOADEXT].supplied) {
19364  SQLGetPrivateProfileString(dsn, "LoadExt", "",
19365  setupdlg->attr[KEY_LOADEXT].attr,
19366  sizeof (setupdlg->attr[KEY_LOADEXT].attr),
19367  ODBC_INI);
19368  }
19369  if (!setupdlg->attr[KEY_JMODE].supplied) {
19370  SQLGetPrivateProfileString(dsn, "JournalMode", "",
19371  setupdlg->attr[KEY_JMODE].attr,
19372  sizeof (setupdlg->attr[KEY_JMODE].attr),
19373  ODBC_INI);
19374  }
19375  if (!setupdlg->attr[KEY_BIGINT].supplied) {
19376  SQLGetPrivateProfileString(dsn, "BigInt", "",
19377  setupdlg->attr[KEY_BIGINT].attr,
19378  sizeof (setupdlg->attr[KEY_BIGINT].attr),
19379  ODBC_INI);
19380  }
19381  if (!setupdlg->attr[KEY_PASSWD].supplied) {
19382  SQLGetPrivateProfileString(dsn, "PWD", "",
19383  setupdlg->attr[KEY_PASSWD].attr,
19384  sizeof (setupdlg->attr[KEY_PASSWD].attr),
19385  ODBC_INI);
19386  }
19387  if (!setupdlg->attr[KEY_JDCONV].supplied) {
19388  SQLGetPrivateProfileString(dsn, "JDConv", "",
19389  setupdlg->attr[KEY_JDCONV].attr,
19390  sizeof (setupdlg->attr[KEY_JDCONV].attr),
19391  ODBC_INI);
19392  }
19393 }
19394 
19400 static void
19401 GetDBFile(HWND hdlg)
19402 {
19403 #ifdef _WIN64
19404  SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19405 #else
19406  SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19407 #endif
19408  OPENFILENAME ofn;
19409 
19410  memset(&ofn, 0, sizeof (ofn));
19411  ofn.lStructSize = sizeof (ofn);
19412  ofn.hwndOwner = hdlg;
19413 #ifdef _WIN64
19414  ofn.hInstance = (HINSTANCE) GetWindowLongPtr(hdlg, GWLP_HINSTANCE);
19415 #else
19416  ofn.hInstance = (HINSTANCE) GetWindowLong(hdlg, GWL_HINSTANCE);
19417 #endif
19418  ofn.lpstrFile = (LPTSTR) setupdlg->attr[KEY_DBNAME].attr;
19419  ofn.nMaxFile = MAXPATHLEN;
19420  ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST |
19421  OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_FILEMUSTEXIST;
19422  if (GetOpenFileName(&ofn)) {
19423  SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19424  setupdlg->attr[KEY_DBNAME].supplied = TRUE;
19425  }
19426 }
19427 
19437 static BOOL CALLBACK
19438 ConfigDlgProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19439 {
19440  SETUPDLG *setupdlg = NULL;
19441  WORD index;
19442 
19443  switch (wmsg) {
19444  case WM_INITDIALOG:
19445 #ifdef _WIN64
19446  SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19447 #else
19448  SetWindowLong(hdlg, DWL_USER, lparam);
19449 #endif
19450  setupdlg = (SETUPDLG *) lparam;
19451  GetAttributes(setupdlg);
19452  SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19453  SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19454  SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19455  SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19456  SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19457  SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19458  (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19459  SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19460  (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19461  SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19462  (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19463  SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19464  (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19465  SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19466  (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19467  CheckDlgButton(hdlg, IDC_STEPAPI,
19468  getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19469  BST_CHECKED : BST_UNCHECKED);
19470  CheckDlgButton(hdlg, IDC_NOTXN,
19471  getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19472  BST_CHECKED : BST_UNCHECKED);
19473  CheckDlgButton(hdlg, IDC_SHORTNAM,
19474  getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19475  BST_CHECKED : BST_UNCHECKED);
19476  CheckDlgButton(hdlg, IDC_LONGNAM,
19477  getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19478  BST_CHECKED : BST_UNCHECKED);
19479  CheckDlgButton(hdlg, IDC_NOCREAT,
19480  getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19481  BST_CHECKED : BST_UNCHECKED);
19482  CheckDlgButton(hdlg, IDC_NOWCHAR,
19483  getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19484  BST_CHECKED : BST_UNCHECKED);
19485  CheckDlgButton(hdlg, IDC_FKSUPPORT,
19486  getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19487  BST_CHECKED : BST_UNCHECKED);
19488  CheckDlgButton(hdlg, IDC_OEMCP,
19489  getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19490  BST_CHECKED : BST_UNCHECKED);
19491  CheckDlgButton(hdlg, IDC_BIGINT,
19492  getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19493  BST_CHECKED : BST_UNCHECKED);
19494  CheckDlgButton(hdlg, IDC_JDCONV,
19495  getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19496  BST_CHECKED : BST_UNCHECKED);
19497  SendDlgItemMessage(hdlg, IDC_SYNCP,
19498  CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19499  SendDlgItemMessage(hdlg, IDC_SYNCP,
19500  CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19501  SendDlgItemMessage(hdlg, IDC_SYNCP,
19502  CB_ADDSTRING, 0, (LPARAM) "OFF");
19503  SendDlgItemMessage(hdlg, IDC_SYNCP,
19504  CB_ADDSTRING, 0, (LPARAM) "FULL");
19505  SendDlgItemMessage(hdlg, IDC_SYNCP,
19506  CB_SELECTSTRING, (WPARAM) -1,
19507  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19508  if (setupdlg->defDSN) {
19509  EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19510  EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19511  }
19512  return TRUE;
19513  case WM_COMMAND:
19514  switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19515  case IDC_DSNAME:
19516  if (GET_WM_COMMAND_CMD(wparam, lparam) == EN_CHANGE) {
19517  char item[MAXDSNAME];
19518 
19519  EnableWindow(GetDlgItem(hdlg, IDOK),
19520  GetDlgItemText(hdlg, IDC_DSNAME,
19521  item, sizeof (item)));
19522  return TRUE;
19523  }
19524  break;
19525  case IDC_BROWSE:
19526  GetDBFile(hdlg);
19527  break;
19528  case IDOK:
19529 #ifdef _WIN64
19530  setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19531 #else
19532  setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19533 #endif
19534  if (!setupdlg->defDSN) {
19535  GetDlgItemText(hdlg, IDC_DSNAME,
19536  setupdlg->attr[KEY_DSN].attr,
19537  sizeof (setupdlg->attr[KEY_DSN].attr));
19538  }
19539  GetDlgItemText(hdlg, IDC_DESC,
19540  setupdlg->attr[KEY_DESC].attr,
19541  sizeof (setupdlg->attr[KEY_DESC].attr));
19542  GetDlgItemText(hdlg, IDC_DBNAME,
19543  setupdlg->attr[KEY_DBNAME].attr,
19544  sizeof (setupdlg->attr[KEY_DBNAME].attr));
19545  GetDlgItemText(hdlg, IDC_TONAME,
19546  setupdlg->attr[KEY_BUSY].attr,
19547  sizeof (setupdlg->attr[KEY_BUSY].attr));
19548  GetDlgItemText(hdlg, IDC_LOADEXT,
19549  setupdlg->attr[KEY_LOADEXT].attr,
19550  sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19551  index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19552  CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19553  if (index != (WORD) CB_ERR) {
19554  SendDlgItemMessage(hdlg, IDC_SYNCP,
19555  CB_GETLBTEXT, index,
19556  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19557  }
19558  strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19559  (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19560  "1" : "0");
19561  strcpy(setupdlg->attr[KEY_NOTXN].attr,
19562  (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19563  "1" : "0");
19564  strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19565  (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19566  "1" : "0");
19567  strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19568  (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19569  "1" : "0");
19570  strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19571  (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19572  "1" : "0");
19573  strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19574  (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19575  "1" : "0");
19576  strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19577  (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19578  "1" : "0");
19579  strcpy(setupdlg->attr[KEY_OEMCP].attr,
19580  (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19581  "1" : "0");
19582  strcpy(setupdlg->attr[KEY_BIGINT].attr,
19583  (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19584  "1" : "0");
19585  strcpy(setupdlg->attr[KEY_JDCONV].attr,
19586  (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19587  "1" : "0");
19588  SetDSNAttributes(hdlg, setupdlg);
19589  /* FALL THROUGH */
19590  case IDCANCEL:
19591  EndDialog(hdlg, wparam);
19592  return TRUE;
19593  }
19594  break;
19595  }
19596  return FALSE;
19597 }
19598 
19608 BOOL INSTAPI
19609 ConfigDSN(HWND hwnd, WORD request, LPCSTR driver, LPCSTR attribs)
19610 {
19611  BOOL success;
19612  SETUPDLG *setupdlg;
19613 
19614  setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
19615  if (setupdlg == NULL) {
19616  return FALSE;
19617  }
19618  memset(setupdlg, 0, sizeof (SETUPDLG));
19619  if (attribs) {
19620  ParseAttributes(attribs, setupdlg);
19621  }
19622  if (setupdlg->attr[KEY_DSN].supplied) {
19623  strcpy(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr);
19624  } else {
19625  setupdlg->DSN[0] = '\0';
19626  }
19627  if (request == ODBC_REMOVE_DSN) {
19628  if (!setupdlg->attr[KEY_DSN].supplied) {
19629  success = FALSE;
19630  } else {
19631  success = SQLRemoveDSNFromIni(setupdlg->attr[KEY_DSN].attr);
19632  }
19633  } else {
19634  setupdlg->parent = hwnd;
19635  setupdlg->driver = driver;
19636  setupdlg->newDSN = request == ODBC_ADD_DSN;
19637  setupdlg->defDSN = strcasecmp(setupdlg->attr[KEY_DSN].attr,
19638  "Default") == 0;
19639  if (hwnd) {
19640  success = DialogBoxParam(hModule, MAKEINTRESOURCE(CONFIGDSN),
19641  hwnd, (DLGPROC) ConfigDlgProc,
19642  (LPARAM) setupdlg) == IDOK;
19643  } else if (setupdlg->attr[KEY_DSN].supplied) {
19644  success = SetDSNAttributes(hwnd, setupdlg);
19645  } else {
19646  success = FALSE;
19647  }
19648  }
19649  xfree(setupdlg);
19650  return success;
19651 }
19652 
19662 static BOOL CALLBACK
19663 DriverConnectProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19664 {
19665  SETUPDLG *setupdlg;
19666  WORD index;
19667 
19668  switch (wmsg) {
19669  case WM_INITDIALOG:
19670 #ifdef _WIN64
19671  SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19672 #else
19673  SetWindowLong(hdlg, DWL_USER, lparam);
19674 #endif
19675  setupdlg = (SETUPDLG *) lparam;
19676  SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19677  SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19678  SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19679  SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19680  SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19681  SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19682  (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19683  SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19684  (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19685  SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19686  (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19687  SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19688  (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19689  SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19690  (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19691  CheckDlgButton(hdlg, IDC_STEPAPI,
19692  getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19693  BST_CHECKED : BST_UNCHECKED);
19694  CheckDlgButton(hdlg, IDC_NOTXN,
19695  getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19696  BST_CHECKED : BST_UNCHECKED);
19697  CheckDlgButton(hdlg, IDC_SHORTNAM,
19698  getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19699  BST_CHECKED : BST_UNCHECKED);
19700  CheckDlgButton(hdlg, IDC_LONGNAM,
19701  getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19702  BST_CHECKED : BST_UNCHECKED);
19703  CheckDlgButton(hdlg, IDC_NOCREAT,
19704  getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19705  BST_CHECKED : BST_UNCHECKED);
19706  CheckDlgButton(hdlg, IDC_NOWCHAR,
19707  getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19708  BST_CHECKED : BST_UNCHECKED);
19709  CheckDlgButton(hdlg, IDC_FKSUPPORT,
19710  getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19711  BST_CHECKED : BST_UNCHECKED);
19712  CheckDlgButton(hdlg, IDC_OEMCP,
19713  getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19714  BST_CHECKED : BST_UNCHECKED);
19715  CheckDlgButton(hdlg, IDC_BIGINT,
19716  getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19717  BST_CHECKED : BST_UNCHECKED);
19718  CheckDlgButton(hdlg, IDC_JDCONV,
19719  getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19720  BST_CHECKED : BST_UNCHECKED);
19721  SendDlgItemMessage(hdlg, IDC_SYNCP,
19722  CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19723  SendDlgItemMessage(hdlg, IDC_SYNCP,
19724  CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19725  SendDlgItemMessage(hdlg, IDC_SYNCP,
19726  CB_ADDSTRING, 0, (LPARAM) "OFF");
19727  SendDlgItemMessage(hdlg, IDC_SYNCP,
19728  CB_ADDSTRING, 0, (LPARAM) "FULL");
19729  SendDlgItemMessage(hdlg, IDC_SYNCP,
19730  CB_SELECTSTRING, (WORD) -1,
19731  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19732  if (setupdlg->defDSN) {
19733  EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19734  EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19735  }
19736  return TRUE;
19737  case WM_COMMAND:
19738  switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19739  case IDC_BROWSE:
19740  GetDBFile(hdlg);
19741  break;
19742  case IDOK:
19743 #ifdef _WIN64
19744  setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19745 #else
19746  setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19747 #endif
19748  GetDlgItemText(hdlg, IDC_DSNAME,
19749  setupdlg->attr[KEY_DSN].attr,
19750  sizeof (setupdlg->attr[KEY_DSN].attr));
19751  GetDlgItemText(hdlg, IDC_DBNAME,
19752  setupdlg->attr[KEY_DBNAME].attr,
19753  sizeof (setupdlg->attr[KEY_DBNAME].attr));
19754  GetDlgItemText(hdlg, IDC_TONAME,
19755  setupdlg->attr[KEY_BUSY].attr,
19756  sizeof (setupdlg->attr[KEY_BUSY].attr));
19757  GetDlgItemText(hdlg, IDC_LOADEXT,
19758  setupdlg->attr[KEY_LOADEXT].attr,
19759  sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19760  index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19761  CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19762  if (index != (WORD) CB_ERR) {
19763  SendDlgItemMessage(hdlg, IDC_SYNCP,
19764  CB_GETLBTEXT, index,
19765  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19766  }
19767  strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19768  (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19769  "1" : "0");
19770  strcpy(setupdlg->attr[KEY_NOTXN].attr,
19771  (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19772  "1" : "0");
19773  strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19774  (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19775  "1" : "0");
19776  strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19777  (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19778  "1" : "0");
19779  strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19780  (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19781  "1" : "0");
19782  strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19783  (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19784  "1" : "0");
19785  strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19786  (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19787  "1" : "0");
19788  strcpy(setupdlg->attr[KEY_OEMCP].attr,
19789  (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19790  "1" : "0");
19791  strcpy(setupdlg->attr[KEY_BIGINT].attr,
19792  (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19793  "1" : "0");
19794  strcpy(setupdlg->attr[KEY_JDCONV].attr,
19795  (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19796  "1" : "0");
19797  /* FALL THROUGH */
19798  case IDCANCEL:
19799  EndDialog(hdlg, GET_WM_COMMAND_ID(wparam, lparam) == IDOK);
19800  return TRUE;
19801  }
19802  }
19803  return FALSE;
19804 }
19805 
19819 static SQLRETURN
19820 drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
19821  SQLCHAR *connIn, SQLSMALLINT connInLen,
19822  SQLCHAR *connOut, SQLSMALLINT connOutMax,
19823  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19824 {
19825  BOOL maybeprompt, prompt = FALSE, defaultdsn = FALSE;
19826  DBC *d;
19827  SETUPDLG *setupdlg;
19828  SQLRETURN ret;
19829  char *dsn = NULL, *driver = NULL, *dbname = NULL;
19830 
19831  if (dbc == SQL_NULL_HDBC) {
19832  return SQL_INVALID_HANDLE;
19833  }
19834  d = (DBC *) dbc;
19835  if (d->sqlite) {
19836  setstatd(d, -1, "connection already established", "08002");
19837  return SQL_ERROR;
19838  }
19839  setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
19840  if (setupdlg == NULL) {
19841  return SQL_ERROR;
19842  }
19843  memset(setupdlg, 0, sizeof (SETUPDLG));
19844  maybeprompt = drvcompl == SQL_DRIVER_COMPLETE ||
19845  drvcompl == SQL_DRIVER_COMPLETE_REQUIRED;
19846  if (connIn == NULL || !connInLen ||
19847  (connInLen == SQL_NTS && !connIn[0])) {
19848  prompt = TRUE;
19849  } else {
19850  ParseAttributes((LPCSTR) connIn, setupdlg);
19851  if (!setupdlg->attr[KEY_DSN].attr[0] &&
19852  drvcompl == SQL_DRIVER_COMPLETE_REQUIRED) {
19853  strcpy(setupdlg->attr[KEY_DSN].attr, "DEFAULT");
19854  defaultdsn = TRUE;
19855  }
19856  GetAttributes(setupdlg);
19857  if (drvcompl == SQL_DRIVER_PROMPT ||
19858  (maybeprompt &&
19859  !setupdlg->attr[KEY_DBNAME].attr[0])) {
19860  prompt = TRUE;
19861  }
19862  }
19863 retry:
19864  if (prompt) {
19865  short dlgret;
19866 
19867  setupdlg->defDSN = setupdlg->attr[KEY_DRIVER].attr[0] != '\0';
19868  dlgret = DialogBoxParam(hModule, MAKEINTRESOURCE(DRIVERCONNECT),
19869  hwnd, (DLGPROC) DriverConnectProc,
19870  (LPARAM) setupdlg);
19871 
19872  if (!dlgret || dlgret == -1) {
19873  xfree(setupdlg);
19874  return SQL_NO_DATA;
19875  }
19876  }
19877  dsn = setupdlg->attr[KEY_DSN].attr;
19878  driver = setupdlg->attr[KEY_DRIVER].attr;
19879  dbname = setupdlg->attr[KEY_DBNAME].attr;
19880  if (connOut || connOutLen) {
19881  char buf[SQL_MAX_MESSAGE_LENGTH * 8];
19882  int len, count;
19883  char dsn_0 = (dsn && !defaultdsn) ? dsn[0] : '\0';
19884  char drv_0 = driver ? driver[0] : '\0';
19885 
19886  buf[0] = '\0';
19887  count = snprintf(buf, sizeof (buf),
19888  "%s%s%s%s%s%sDatabase=%s;StepAPI=%s;"
19889  "SyncPragma=%s;NoTXN=%s;Timeout=%s;"
19890  "ShortNames=%s;LongNames=%s;"
19891  "NoCreat=%s;NoWCHAR=%s;"
19892  "FKSupport=%s;JournalMode=%s;OEMCP=%s;LoadExt=%s;"
19893  "BigInt=%s;JDConv=%s;PWD=%s",
19894  dsn_0 ? "DSN=" : "",
19895  dsn_0 ? dsn : "",
19896  dsn_0 ? ";" : "",
19897  drv_0 ? "Driver=" : "",
19898  drv_0 ? driver : "",
19899  drv_0 ? ";" : "",
19900  dbname ? dbname : "",
19901  setupdlg->attr[KEY_STEPAPI].attr,
19902  setupdlg->attr[KEY_SYNCP].attr,
19903  setupdlg->attr[KEY_NOTXN].attr,
19904  setupdlg->attr[KEY_BUSY].attr,
19905  setupdlg->attr[KEY_SHORTNAM].attr,
19906  setupdlg->attr[KEY_LONGNAM].attr,
19907  setupdlg->attr[KEY_NOCREAT].attr,
19908  setupdlg->attr[KEY_NOWCHAR].attr,
19909  setupdlg->attr[KEY_FKSUPPORT].attr,
19910  setupdlg->attr[KEY_JMODE].attr,
19911  setupdlg->attr[KEY_OEMCP].attr,
19912  setupdlg->attr[KEY_LOADEXT].attr,
19913  setupdlg->attr[KEY_BIGINT].attr,
19914  setupdlg->attr[KEY_JDCONV].attr,
19915  setupdlg->attr[KEY_PASSWD].attr);
19916  if (count < 0) {
19917  buf[sizeof (buf) - 1] = '\0';
19918  }
19919  len = min(connOutMax - 1, strlen(buf));
19920  if (connOut) {
19921  strncpy((char *) connOut, buf, len);
19922  connOut[len] = '\0';
19923  }
19924  if (connOutLen) {
19925  *connOutLen = len;
19926  }
19927  }
19928  if (dsn[0]) {
19929  char tracef[SQL_MAX_MESSAGE_LENGTH];
19930 
19931  tracef[0] = '\0';
19932  SQLGetPrivateProfileString(setupdlg->attr[KEY_DSN].attr,
19933  "tracefile", "", tracef,
19934  sizeof (tracef), ODBC_INI);
19935  if (tracef[0] != '\0') {
19936  d->trace = fopen(tracef, "a");
19937  }
19938  }
19939  d->nowchar = getbool(setupdlg->attr[KEY_NOWCHAR].attr);
19940  d->shortnames = getbool(setupdlg->attr[KEY_SHORTNAM].attr);
19941  d->longnames = getbool(setupdlg->attr[KEY_LONGNAM].attr);
19942  d->nocreat = getbool(setupdlg->attr[KEY_NOCREAT].attr);
19943  d->fksupport = getbool(setupdlg->attr[KEY_FKSUPPORT].attr);
19944  d->oemcp = getbool(setupdlg->attr[KEY_OEMCP].attr);
19945  d->dobigint = getbool(setupdlg->attr[KEY_BIGINT].attr);
19946  d->jdconv = getbool(setupdlg->attr[KEY_JDCONV].attr);
19947  d->pwdLen = strlen(setupdlg->attr[KEY_PASSWD].attr);
19948  d->pwd = (d->pwdLen > 0) ? setupdlg->attr[KEY_PASSWD].attr : NULL;
19949  ret = dbopen(d, dbname ? dbname : "", 0,
19950  dsn ? dsn : "",
19951  setupdlg->attr[KEY_STEPAPI].attr,
19952  setupdlg->attr[KEY_SYNCP].attr,
19953  setupdlg->attr[KEY_NOTXN].attr,
19954  setupdlg->attr[KEY_JMODE].attr,
19955  setupdlg->attr[KEY_BUSY].attr);
19956  if (ret != SQL_SUCCESS) {
19957  if (maybeprompt && !prompt) {
19958  prompt = TRUE;
19959  goto retry;
19960  }
19961  }
19962  memset(setupdlg->attr[KEY_PASSWD].attr, 0,
19963  sizeof (setupdlg->attr[KEY_PASSWD].attr));
19964  if (ret == SQL_SUCCESS) {
19965  dbloadext(d, setupdlg->attr[KEY_LOADEXT].attr);
19966  }
19967  xfree(setupdlg);
19968  return ret;
19969 }
19970 
19971 #endif /* WITHOUT_DRIVERMGR */
19972 #endif /* _WIN32 || _WIN64 */
19973 
19974 #ifndef WINTERFACE
19975 
19988 SQLRETURN SQL_API
19989 SQLDriverConnect(SQLHDBC dbc, SQLHWND hwnd,
19990  SQLCHAR *connIn, SQLSMALLINT connInLen,
19991  SQLCHAR *connOut, SQLSMALLINT connOutMax,
19992  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19993 {
19994  SQLRETURN ret;
19995 
19996  HDBC_LOCK(dbc);
19997  ret = drvdriverconnect(dbc, hwnd, connIn, connInLen,
19998  connOut, connOutMax, connOutLen, drvcompl);
19999  HDBC_UNLOCK(dbc);
20000  return ret;
20001 }
20002 #endif
20003 
20004 #ifdef WINTERFACE
20005 
20018 SQLRETURN SQL_API
20019 SQLDriverConnectW(SQLHDBC dbc, SQLHWND hwnd,
20020  SQLWCHAR *connIn, SQLSMALLINT connInLen,
20021  SQLWCHAR *connOut, SQLSMALLINT connOutMax,
20022  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
20023 {
20024  SQLRETURN ret;
20025  char *ci = NULL;
20026  SQLSMALLINT len = 0;
20027 
20028  HDBC_LOCK(dbc);
20029  if (connIn) {
20030 #if defined(_WIN32) || defined(_WIN64)
20031  if (connInLen == SQL_NTS) {
20032  connInLen = -1;
20033  }
20034  ci = uc_to_wmb(connIn, connInLen);
20035 #else
20036  ci = uc_to_utf(connIn, connInLen);
20037 #endif
20038  if (!ci) {
20039  DBC *d = (DBC *) dbc;
20040 
20041  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
20042  HDBC_UNLOCK(dbc);
20043  return SQL_ERROR;
20044  }
20045  }
20046  ret = drvdriverconnect(dbc, hwnd, (SQLCHAR *) ci, SQL_NTS,
20047  (SQLCHAR *) connOut, connOutMax, &len, drvcompl);
20048  HDBC_UNLOCK(dbc);
20049  uc_free(ci);
20050  if (ret == SQL_SUCCESS) {
20051  SQLWCHAR *co = NULL;
20052 
20053  if (connOut) {
20054  if (len > 0) {
20055 #if defined(_WIN32) || defined(_WIN64)
20056  co = wmb_to_uc((char *) connOut, len);
20057 #else
20058  co = uc_from_utf((SQLCHAR *) connOut, len);
20059 #endif
20060  if (co) {
20061  uc_strncpy(connOut, co, connOutMax / sizeof (SQLWCHAR));
20062  len = min(connOutMax / sizeof (SQLWCHAR), uc_strlen(co));
20063  uc_free(co);
20064  } else {
20065  len = 0;
20066  }
20067  }
20068  if (len <= 0) {
20069  len = 0;
20070  connOut[0] = 0;
20071  }
20072  } else {
20073  len = 0;
20074  }
20075  if (connOutLen) {
20076  *connOutLen = len;
20077  }
20078  }
20079  return ret;
20080 }
20081 #endif
20082 
20083 #if defined(_WIN32) || defined(_WIN64)
20084 
20093 BOOL APIENTRY
20094 LibMain(HANDLE hinst, DWORD reason, LPVOID reserved)
20095 {
20096  static int initialized = 0;
20097 
20098  switch (reason) {
20099  case DLL_PROCESS_ATTACH:
20100  if (!initialized++) {
20101  hModule = hinst;
20102 #ifdef WINTERFACE
20103  /* MS Access hack part 1 (reserved error -7748) */
20104  statSpec2P = statSpec2;
20105  statSpec3P = statSpec3;
20106 #endif
20107 #ifdef SQLITE_DYNLOAD
20108  dls_init();
20109 #endif
20110 #ifdef SQLITE_HAS_CODEC
20111  sqlite3_activate_see(SQLITE_ACTIVATION_KEY);
20112 #endif
20113  }
20114 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
20115  nvfs_init();
20116 #endif
20117  break;
20118  case DLL_THREAD_ATTACH:
20119  break;
20120  case DLL_PROCESS_DETACH:
20121  if (--initialized <= 0) {
20122 #ifdef SQLITE_DYNLOAD
20123  dls_fini();
20124 #endif
20125  }
20126  break;
20127  case DLL_THREAD_DETACH:
20128  break;
20129  default:
20130  break;
20131  }
20132  return TRUE;
20133 }
20134 
20143 int __stdcall
20144 DllMain(HANDLE hinst, DWORD reason, LPVOID reserved)
20145 {
20146  return LibMain(hinst, reason, reserved);
20147 }
20148 
20149 #ifndef WITHOUT_INSTALLER
20150 
20157 static BOOL
20158 InUnError(char *name)
20159 {
20160  WORD err = 1;
20161  DWORD code;
20162  char errmsg[301];
20163  WORD errlen, errmax = sizeof (errmsg) - 1;
20164  int sqlret;
20165  BOOL ret = FALSE;
20166 
20167  do {
20168  errmsg[0] = '\0';
20169  sqlret = SQLInstallerError(err, &code, errmsg, errmax, &errlen);
20170  if (SQL_SUCCEEDED(sqlret)) {
20171  MessageBox(NULL, errmsg, name,
20172  MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
20173  ret = TRUE;
20174  }
20175  err++;
20176  } while (sqlret != SQL_NO_DATA);
20177  return ret;
20178 }
20179 
20186 static BOOL
20187 InUn(int remove, char *cmdline)
20188 {
20189 #ifdef SQLITE_HAS_CODEC
20190  static char *drivername = "SQLite3 ODBC Driver (SEE)";
20191  static char *dsname = "SQLite3 SEE Datasource";
20192 #else
20193  static char *drivername = "SQLite3 ODBC Driver";
20194  static char *dsname = "SQLite3 Datasource";
20195 #endif
20196  char *dllname, *p;
20197  char dllbuf[301], path[301], driver[300], attr[300], inst[400];
20198  WORD pathmax = sizeof (path) - 1, pathlen;
20199  DWORD usecnt, mincnt;
20200  int quiet = 0;
20201 
20202  dllbuf[0] = '\0';
20203  GetModuleFileName(hModule, dllbuf, sizeof (dllbuf));
20204  p = strrchr(dllbuf, '\\');
20205  dllname = p ? (p + 1) : dllbuf;
20206  quiet = cmdline && strstr(cmdline, "quiet");
20207  if (SQLInstallDriverManager(path, pathmax, &pathlen)) {
20208  sprintf(driver, "%s;Driver=%s;Setup=%s;",
20209  drivername, dllname, dllname);
20210  p = driver;
20211  while (*p) {
20212  if (*p == ';') {
20213  *p = '\0';
20214  }
20215  ++p;
20216  }
20217  usecnt = 0;
20218  path[0] = '\0';
20219  SQLInstallDriverEx(driver, NULL, path, pathmax, NULL,
20220  ODBC_INSTALL_INQUIRY, &usecnt);
20221  pathlen = strlen(path);
20222  while (pathlen > 0 && path[pathlen - 1] == '\\') {
20223  --pathlen;
20224  path[pathlen] = '\0';
20225  }
20226  sprintf(driver, "%s;Driver=%s\\%s;Setup=%s\\%s;",
20227  drivername, path, dllname, path, dllname);
20228  p = driver;
20229  while (*p) {
20230  if (*p == ';') {
20231  *p = '\0';
20232  }
20233  ++p;
20234  }
20235  sprintf(inst, "%s\\%s", path, dllname);
20236  if (!remove && usecnt > 0) {
20237  /* first install try: copy over driver dll, keeping DSNs */
20238  if (GetFileAttributesA(dllbuf) != INVALID_FILE_ATTRIBUTES &&
20239  CopyFile(dllbuf, inst, 0)) {
20240  if (!quiet) {
20241  char buf[512];
20242 
20243  sprintf(buf, "%s replaced.", drivername);
20244  MessageBox(NULL, buf, "Info",
20245  MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20246  MB_SETFOREGROUND);
20247  }
20248  return TRUE;
20249  }
20250  }
20251  mincnt = remove ? 1 : 0;
20252  while (usecnt != mincnt) {
20253  if (!SQLRemoveDriver(driver, TRUE, &usecnt)) {
20254  break;
20255  }
20256  }
20257  if (remove) {
20258  if (usecnt && !SQLRemoveDriver(driver, TRUE, &usecnt)) {
20259  InUnError("SQLRemoveDriver");
20260  return FALSE;
20261  }
20262  if (!usecnt) {
20263  char buf[512];
20264 
20265  DeleteFile(inst);
20266  if (!quiet) {
20267  sprintf(buf, "%s uninstalled.", drivername);
20268  MessageBox(NULL, buf, "Info",
20269  MB_ICONINFORMATION |MB_OK | MB_TASKMODAL |
20270  MB_SETFOREGROUND);
20271  }
20272  }
20273  sprintf(attr, "DSN=%s;Database=;", dsname);
20274  p = attr;
20275  while (*p) {
20276  if (*p == ';') {
20277  *p = '\0';
20278  }
20279  ++p;
20280  }
20281  SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20282  return TRUE;
20283  }
20284  if (GetFileAttributesA(dllbuf) == INVALID_FILE_ATTRIBUTES) {
20285  return FALSE;
20286  }
20287  if (strcasecmp(dllbuf, inst) != 0 && !CopyFile(dllbuf, inst, 0)) {
20288  char buf[512];
20289 
20290  sprintf(buf, "Copy %s to %s failed.", dllbuf, inst);
20291  MessageBox(NULL, buf, "CopyFile",
20292  MB_ICONSTOP |MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
20293  return FALSE;
20294  }
20295  if (!SQLInstallDriverEx(driver, path, path, pathmax, &pathlen,
20296  ODBC_INSTALL_COMPLETE, &usecnt)) {
20297  InUnError("SQLInstallDriverEx");
20298  return FALSE;
20299  }
20300  sprintf(attr, "DSN=%s;Database=;", dsname);
20301  p = attr;
20302  while (*p) {
20303  if (*p == ';') {
20304  *p = '\0';
20305  }
20306  ++p;
20307  }
20308  SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20309  if (!SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN, drivername, attr)) {
20310  InUnError("SQLConfigDataSource");
20311  return FALSE;
20312  }
20313  if (!quiet) {
20314  char buf[512];
20315 
20316  sprintf(buf, "%s installed.", drivername);
20317  MessageBox(NULL, buf, "Info",
20318  MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20319  MB_SETFOREGROUND);
20320  }
20321  } else {
20322  InUnError("SQLInstallDriverManager");
20323  return FALSE;
20324  }
20325  return TRUE;
20326 }
20327 
20336 void CALLBACK
20337 install(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20338 {
20339  InUn(0, lpszCmdLine);
20340 }
20341 
20350 void CALLBACK
20351 uninstall(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20352 {
20353  InUn(1, lpszCmdLine);
20354 }
20355 
20356 #endif /* WITHOUT_INSTALLER */
20357 
20358 #ifndef WITHOUT_SHELL
20359 
20368 static void
20369 setargv(int *argcp, char ***argvp, char *cmdline, char *argv0)
20370 {
20371  char *p, *arg, *argspace, **argv;
20372  int argc, size, inquote, copy, slashes;
20373 
20374  size = 2 + (argv0 ? 1 : 0);
20375  for (p = cmdline; *p != '\0'; p++) {
20376  if (ISSPACE(*p)) {
20377  size++;
20378  while (ISSPACE(*p)) {
20379  p++;
20380  }
20381  if (*p == '\0') {
20382  break;
20383  }
20384  }
20385  }
20386  argspace = malloc(size * sizeof (char *) + strlen(cmdline) + 1);
20387  argv = (char **) argspace;
20388  argspace += size * sizeof (char *);
20389  size--;
20390  argc = 0;
20391  if (argv0) {
20392  argv[argc++] = argv0;
20393  }
20394  p = cmdline;
20395  for (; argc < size; argc++) {
20396  argv[argc] = arg = argspace;
20397  while (ISSPACE(*p)) {
20398  p++;
20399  }
20400  if (*p == '\0') {
20401  break;
20402  }
20403  inquote = 0;
20404  slashes = 0;
20405  while (1) {
20406  copy = 1;
20407  while (*p == '\\') {
20408  slashes++;
20409  p++;
20410  }
20411  if (*p == '"') {
20412  if ((slashes & 1) == 0) {
20413  copy = 0;
20414  if (inquote && p[1] == '"') {
20415  p++;
20416  copy = 1;
20417  } else {
20418  inquote = !inquote;
20419  }
20420  }
20421  slashes >>= 1;
20422  }
20423  while (slashes) {
20424  *arg = '\\';
20425  arg++;
20426  slashes--;
20427  }
20428  if (*p == '\0' || (!inquote && ISSPACE(*p))) {
20429  break;
20430  }
20431  if (copy != 0) {
20432  *arg = *p;
20433  arg++;
20434  }
20435  p++;
20436  }
20437  *arg = '\0';
20438  argspace = arg + 1;
20439  }
20440  argv[argc] = 0;
20441  *argcp = argc;
20442  *argvp = argv;
20443 }
20444 
20453 void CALLBACK
20454 shell(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20455 {
20456  int argc, needcon = 0;
20457  char **argv;
20458  extern int sqlite3_main(int, char **);
20459  static const char *name = "SQLite3 Shell";
20460  DWORD ftype0, ftype1, ftype2;
20461 
20462  ftype0 = GetFileType(GetStdHandle(STD_INPUT_HANDLE));
20463  ftype1 = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
20464  ftype2 = GetFileType(GetStdHandle(STD_ERROR_HANDLE));
20465  if (ftype0 != FILE_TYPE_DISK && ftype0 != FILE_TYPE_CHAR &&
20466  ftype0 != FILE_TYPE_PIPE) {
20467  fclose(stdin);
20468  ++needcon;
20469  ftype0 = FILE_TYPE_UNKNOWN;
20470  }
20471  if (ftype1 != FILE_TYPE_DISK && ftype1 != FILE_TYPE_CHAR &&
20472  ftype1 != FILE_TYPE_PIPE) {
20473  fclose(stdout);
20474  ++needcon;
20475  ftype1 = FILE_TYPE_UNKNOWN;
20476  }
20477  if (ftype2 != FILE_TYPE_DISK && ftype2 != FILE_TYPE_CHAR &&
20478  ftype2 != FILE_TYPE_PIPE) {
20479  fclose(stderr);
20480  ++needcon;
20481  ftype2 = FILE_TYPE_UNKNOWN;
20482  }
20483  if (needcon > 0) {
20484  AllocConsole();
20485  SetConsoleTitle(name);
20486  }
20487  if (ftype0 == FILE_TYPE_UNKNOWN) {
20488  freopen("CONIN$", "r", stdin);
20489  }
20490  if (ftype1 == FILE_TYPE_UNKNOWN) {
20491  freopen("CONOUT$", "w", stdout);
20492  }
20493  if (ftype2 == FILE_TYPE_UNKNOWN) {
20494  freopen("CONOUT$", "w", stderr);
20495  }
20496  setargv(&argc, &argv, lpszCmdLine, (char *) name);
20497 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
20498  nvfs_init();
20499 #endif
20500  sqlite3_main(argc, argv);
20501 }
20502 
20503 #endif /* WITHOUT_SHELL */
20504 
20505 #endif /* _WIN32 || _WIN64 */
20506 
20507 #if defined(HAVE_ODBCINSTEXT_H) && (HAVE_ODBCINSTEXT_H)
20508 
20509 /*
20510  * unixODBC property page for this driver,
20511  * may or may not work depending on unixODBC version.
20512  */
20513 
20514 #include <odbcinstext.h>
20515 
20516 int
20517 ODBCINSTGetProperties(HODBCINSTPROPERTY prop)
20518 {
20519  static const char *instYN[] = { "No", "Yes", NULL };
20520  static const char *syncPragma[] = { "NORMAL", "OFF", "FULL", NULL };
20521  static const char *jmPragma[] = {
20522  "DELETE", "PERSIST", "OFF", "TRUNCATE", "MEMORY", "WAL", NULL
20523  };
20524 
20525  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20526  prop = prop->pNext;
20527  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20528  prop->nPromptType = ODBCINST_PROMPTTYPE_FILENAME;
20529  strncpy(prop->szName, "Database", INI_MAX_PROPERTY_NAME);
20530  strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20531  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20532  prop = prop->pNext;
20533  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20534  prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20535  strncpy(prop->szName, "Timeout", INI_MAX_PROPERTY_NAME);
20536  strncpy(prop->szValue, "100000", INI_MAX_PROPERTY_VALUE);
20537  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20538  prop = prop->pNext;
20539  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20540  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20541  prop->aPromptData = malloc(sizeof (instYN));
20542  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20543  strncpy(prop->szName, "StepAPI", INI_MAX_PROPERTY_NAME);
20544  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20545  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20546  prop = prop->pNext;
20547  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20548  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20549  prop->aPromptData = malloc(sizeof (instYN));
20550  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20551  strncpy(prop->szName, "ShortNames", INI_MAX_PROPERTY_NAME);
20552  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20553  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20554  prop = prop->pNext;
20555  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20556  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20557  prop->aPromptData = malloc(sizeof (instYN));
20558  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20559  strncpy(prop->szName, "LongNames", INI_MAX_PROPERTY_NAME);
20560  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20561  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20562  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20563  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20564  prop->aPromptData = malloc(sizeof (instYN));
20565  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20566  strncpy(prop->szName, "NoCreat", INI_MAX_PROPERTY_NAME);
20567  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20568 #ifdef WINTERFACE
20569  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20570  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20571  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20572  prop->aPromptData = malloc(sizeof (instYN));
20573  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20574  strncpy(prop->szName, "NoWCHAR", INI_MAX_PROPERTY_NAME);
20575  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20576 #endif
20577  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20578  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20579  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20580  prop->aPromptData = malloc(sizeof (instYN));
20581  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20582  strncpy(prop->szName, "FKSupport", INI_MAX_PROPERTY_NAME);
20583  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20584  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20585  prop = prop->pNext;
20586  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20587  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20588  prop->aPromptData = malloc(sizeof (syncPragma));
20589  memcpy(prop->aPromptData, syncPragma, sizeof (syncPragma));
20590  strncpy(prop->szName, "SyncPragma", INI_MAX_PROPERTY_NAME);
20591  strncpy(prop->szValue, "NORMAL", INI_MAX_PROPERTY_VALUE);
20592  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20593  prop = prop->pNext;
20594  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20595  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20596  prop->aPromptData = malloc(sizeof (jmPragma));
20597  memcpy(prop->aPromptData, jmPragma, sizeof (jmPragma));
20598  strncpy(prop->szName, "JournalMode", INI_MAX_PROPERTY_NAME);
20599  strncpy(prop->szValue, "DELETE", INI_MAX_PROPERTY_VALUE);
20600  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20601  prop = prop->pNext;
20602  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20603  prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20604  strncpy(prop->szName, "LoadExt", INI_MAX_PROPERTY_NAME);
20605  strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20606  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20607  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20608  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20609  prop->aPromptData = malloc(sizeof (instYN));
20610  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20611  strncpy(prop->szName, "BigInt", INI_MAX_PROPERTY_NAME);
20612  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20613  return 1;
20614 }
20615 
20616 #endif /* HAVE_ODBCINSTEXT_H */
20617 
20618 #ifdef SQLITE_DYNLOAD
20619 
20620 /*
20621  * SQLite3 shared library/DLL stubs.
20622  */
20623 
20624 static void
20625 dls_void(void)
20626 {
20627 }
20628 
20629 static int
20630 dls_error(void)
20631 {
20632  return SQLITE_ERROR;
20633 }
20634 
20635 static int
20636 dls_0(void)
20637 {
20638  return 0;
20639 }
20640 
20641 static sqlite_int64
20642 dls_0LL(void)
20643 {
20644  return 0;
20645 }
20646 
20647 static double
20648 dls_00(void)
20649 {
20650  return 0;
20651 }
20652 
20653 static void *
20654 dls_null(void)
20655 {
20656  return NULL;
20657 }
20658 
20659 static const char *
20660 dls_empty(void)
20661 {
20662  return "";
20663 }
20664 
20665 static int
20666 dls_snull(void)
20667 {
20668  return SQLITE_NULL;
20669 }
20670 
20671 #define DLS_ENT(name, func) \
20672  { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, name), \
20673  (void *) func }
20674 
20675 #define DLS_ENT3(name, off, func) \
20676  { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, off), \
20677  (void *) func }
20678 
20679 #define DLS_END { NULL, 0, NULL }
20680 
20681 static struct {
20682  const char *name;
20683  int offset;
20684  void *func;
20685 } dls_nametab[] = {
20686  DLS_ENT(activate_see, dls_void),
20687  DLS_ENT(bind_blob, dls_error),
20688  DLS_ENT(bind_double, dls_error),
20689  DLS_ENT(bind_int, dls_error),
20690  DLS_ENT(bind_int64, dls_error),
20691  DLS_ENT(bind_null, dls_error),
20692  DLS_ENT(bind_parameter_count, dls_0),
20693  DLS_ENT(bind_text, dls_error),
20694  DLS_ENT(busy_handler, dls_error),
20695  DLS_ENT(changes, dls_0),
20696  DLS_ENT(close, dls_error),
20697  DLS_ENT(column_blob, dls_null),
20698  DLS_ENT(column_bytes, dls_0),
20699  DLS_ENT(column_count, dls_0),
20700  DLS_ENT(column_database_name, dls_empty),
20701  DLS_ENT(column_decltype, dls_empty),
20702  DLS_ENT(column_double, dls_00),
20703  DLS_ENT(column_name, dls_empty),
20704  DLS_ENT(column_origin_name, dls_null),
20705  DLS_ENT(column_table_name, dls_null),
20706  DLS_ENT(column_text, dls_null),
20707  DLS_ENT(column_type, dls_snull),
20708  DLS_ENT(create_function, dls_error),
20709  DLS_ENT(enable_load_extension, dls_error),
20710  DLS_ENT(errcode, dls_error),
20711  DLS_ENT(errmsg, dls_empty),
20712  DLS_ENT(exec, dls_error),
20713  DLS_ENT(finalize, dls_error),
20714  DLS_ENT(free, free),
20715  DLS_ENT(free_table, dls_void),
20716  DLS_ENT(get_table, dls_error),
20717  DLS_ENT(interrupt, dls_void),
20718  DLS_ENT(key, dls_error),
20719  DLS_ENT(last_insert_rowid, dls_0LL),
20720  DLS_ENT(libversion, dls_empty),
20721  DLS_ENT(load_extension, dls_error),
20722  DLS_ENT(malloc, malloc),
20723  DLS_ENT(mprintf, dls_null),
20724  DLS_ENT(open, dls_error),
20725  DLS_ENT(open16, dls_error),
20726  DLS_ENT(open_v2, dls_error),
20727  DLS_ENT(prepare, dls_error),
20728  DLS_ENT(prepare_v2, dls_error),
20729  DLS_ENT(profile, dls_null),
20730  DLS_ENT(realloc, realloc),
20731  DLS_ENT(rekey, dls_error),
20732  DLS_ENT(reset, dls_error),
20733  DLS_ENT(result_blob, dls_void),
20734  DLS_ENT(result_error, dls_void),
20735  DLS_ENT(result_int, dls_void),
20736  DLS_ENT(result_null, dls_void),
20737  DLS_ENT(step, dls_error),
20738 #if defined(_WIN32) || defined(_WIN64)
20739  DLS_ENT3(strnicmp, xstrnicmp, _strnicmp),
20740 #else
20741  DLS_ENT3(strnicmp, xstrnicmp, strncasecmp),
20742 #endif
20743  DLS_ENT(table_column_metadata, dls_error),
20744  DLS_ENT(trace, dls_null),
20745  DLS_ENT(user_data, dls_null),
20746  DLS_ENT(value_blob, dls_null),
20747  DLS_ENT(value_bytes, dls_0),
20748  DLS_ENT(value_text, dls_empty),
20749  DLS_ENT(value_type, dls_snull),
20750  DLS_END
20751 };
20752 
20753 #if defined(_WIN32) || defined(_WIN64)
20754 
20755 static HMODULE sqlite3_dll = 0;
20756 
20757 static void
20758 dls_init(void)
20759 {
20760  int i;
20761  static const char *dll_names[] = {
20762  "System.Data.SQLite.dll",
20763  "sqlite3.dll",
20764  NULL,
20765  };
20766 
20767  i = 0;
20768  while (dll_names[i]) {
20769  sqlite3_dll = LoadLibrary(dll_names[i]);
20770  if (sqlite3_dll) {
20771  break;
20772  }
20773  ++i;
20774  }
20775  i = 0;
20776  while (dls_nametab[i].name) {
20777  void *func = 0, **loc;
20778 
20779  if (sqlite3_dll) {
20780  func = (void *) GetProcAddress(sqlite3_dll, dls_nametab[i].name);
20781  }
20782  if (!func) {
20783  func = dls_nametab[i].func;
20784  }
20785  loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
20786  *loc = func;
20787  ++i;
20788  }
20789  if (!sqlite3_dll) {
20790  char buf[MAXPATHLEN], msg[MAXPATHLEN];
20791 
20792  LoadString(hModule, IDS_DRVTITLE, buf, sizeof (buf));
20793  LoadString(hModule, IDS_DLLERR, msg, sizeof (msg));
20794  MessageBox(NULL, msg, buf,
20795  MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
20796  MB_SETFOREGROUND);
20797  }
20798 }
20799 
20800 static void
20801 dls_fini(void)
20802 {
20803  if (sqlite3_dll) {
20804  FreeLibrary(sqlite3_dll);
20805  sqlite3_dll = 0;
20806  }
20807 }
20808 
20809 #else
20810 
20811 #include <dlfcn.h>
20812 
20813 static void *libsqlite3_so = 0;
20814 
20815 void
20816 dls_init(void)
20817 {
20818  int i;
20819 
20820  libsqlite3_so = dlopen("libsqlite3.so.0", RTLD_NOW | RTLD_GLOBAL);
20821  i = 0;
20822  while (dls_nametab[i].name) {
20823  void *func = 0, **loc;
20824 
20825  if (libsqlite3_so) {
20826  func = dlsym(libsqlite3_so, dls_nametab[i].name);
20827  }
20828  if (!func) {
20829  func = dls_nametab[i].func;
20830  }
20831  loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
20832  *loc = func;
20833  ++i;
20834  }
20835  if (!libsqlite3_so) {
20836  const char errmsg[] = "SQLite3 shared library not found.\n";
20837 
20838  write(2, errmsg, sizeof (errmsg) - 1);
20839  }
20840 }
20841 
20842 void
20843 dls_fini(void)
20844 {
20845  if (libsqlite3_so) {
20846  dlclose(libsqlite3_so);
20847  libsqlite3_so = 0;
20848  }
20849 }
20850 
20851 #endif
20852 
20853 #endif
20854 
20855 /*
20856  * Local Variables:
20857  * mode: c
20858  * c-basic-offset: 4
20859  * fill-column: 78
20860  * tab-width: 8
20861  * End:
20862  */
stmt::nrows
int nrows
Number of result rows.
Definition: sqlite3odbc.h:253
stmt::query
SQLCHAR * query
Current query, raw string.
Definition: sqlite3odbc.h:235
SQLBindParam
SQLRETURN SQL_API SQLBindParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT vtype, SQLSMALLINT ptype, SQLULEN lenprec, SQLSMALLINT scale, SQLPOINTER val, SQLLEN *lenp)
Bind parameter on HSTMT.
Definition: sqlite3odbc.c:5567
s3stmt_step
static int s3stmt_step(STMT *s)
Do one sqlite statement step gathering one result row.
Definition: sqlite3odbc.c:4285
dbc::timeout
int timeout
Lock timeout value.
Definition: sqlite3odbc.h:120
BINDPARM::s3dval
double s3dval
SQLite3 float value.
Definition: sqlite3odbc.h:222
ENV::dbcs
struct dbc * dbcs
Pointer to first DBC.
Definition: sqlite3odbc.h:103
dstr::max
int max
Maximum length of buffer.
Definition: sqlite3odbc.c:274
stmt::paramset_size
SQLULEN paramset_size
SQL_ATTR_PARAMSET_SIZE.
Definition: sqlite3odbc.h:271
colPrivSpec3
static COL colPrivSpec3[]
Definition: sqlite3odbc.c:6466
convJD2HMS
static void convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
Convert julian day to hour/minute/second.
Definition: sqlite3odbc.c:3033
HSTMT_UNLOCK
#define HSTMT_UNLOCK(hdbc)
Definition: sqlite3odbc.c:533
tblres::rc
int rc
SQLite return code.
Definition: sqlite3odbc.c:1383
drvcolattributes
static SQLRETURN drvcolattributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id, SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen, SQLLEN *val2)
Internal retrieve column attributes.
Definition: sqlite3odbc.c:17197
stmt::rows
char ** rows
2-dim array, result set
Definition: sqlite3odbc.h:256
drvsetstmtoption
static SQLRETURN drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
Internal set option on HSTMT.
Definition: sqlite3odbc.c:9630
stmt::pdcount
int pdcount
SQLParamData() counter.
Definition: sqlite3odbc.h:252
dbloadext
static void dbloadext(DBC *d, char *exts)
Load SQLite extension modules, if any.
Definition: sqlite3odbc.c:4111
digit_chars
static const char digit_chars[]
Definition: sqlite3odbc.c:566
tablePrivSpec2
static COL tablePrivSpec2[]
Columns for result set of SQLTablePrivileges().
Definition: sqlite3odbc.c:5956
drvspecialcolumns
static SQLRETURN drvspecialcolumns(SQLHSTMT stmt, SQLUSMALLINT id, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen, SQLUSMALLINT scope, SQLUSMALLINT nullable)
Internal retrieve information about indexed columns.
Definition: sqlite3odbc.c:6990
verinfo
#define verinfo(maj, min, lev)
Definition: sqlite3odbc.c:238
setstat
static void setstat(STMT *s, int naterr, char *msg, char *st,...)
Set error message and SQL state on statement.
Definition: sqlite3odbc.c:1727
WCHARSUPPORT
#define WCHARSUPPORT
Definition: sqlite3odbc.c:185
getdsnattr
static int getdsnattr(char *dsn, char *attr, char *out, int outLen)
Handling of SQLConnect() connection attributes for standalone operation without driver manager.
Definition: sqlite3odbc.c:12644
stmt::has_pk
int has_pk
Flag for primary key (> 0)
Definition: sqlite3odbc.h:292
statSpec2
static COL statSpec2[]
Columns for result set of SQLStatistics().
Definition: sqlite3odbc.c:15978
scolSpec3
static COL scolSpec3[]
Definition: sqlite3odbc.c:6962
strbuf
Definition: blobtoxy.c:1212
COL::column
char * column
Column name.
Definition: sqlite3odbc.h:167
SQLFetch
SQLRETURN SQL_API SQLFetch(SQLHSTMT stmt)
Fetch next result row.
Definition: sqlite3odbc.c:16836
TOLOWER
static int TOLOWER(int c)
Definition: sqlite3odbc.c:550
procSpec3
static COL procSpec3[]
Definition: sqlite3odbc.c:8323
dbtrace
static void dbtrace(void *arg, const char *msg, sqlite_uint64 et)
SQLite trace or profile callback.
Definition: sqlite3odbc.c:3815
findcol
static int findcol(char **cols, int ncols, char *name)
Find column given name in string array.
Definition: sqlite3odbc.c:2754
SQLGetStmtOptionW
SQLRETURN SQL_API SQLGetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
Get option of HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9610
mapsqltype
static int mapsqltype(const char *typename, int *nosign, int ov3, int nowchar, int dobigint)
Map SQL field type from string to ODBC integer type code.
Definition: sqlite3odbc.c:2176
setposbind
static SQLRETURN setposbind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
Internal handler to setup parameters for positional updates from bound user buffers.
Definition: sqlite3odbc.c:9779
scolSpec2
static COL scolSpec2[]
Columns for result set of SQLSpecialColumns().
Definition: sqlite3odbc.c:6950
dbc::trace
FILE * trace
sqlite3_trace() file pointer or NULL
Definition: sqlite3odbc.h:144
SQLGetTypeInfoW
SQLRETURN SQL_API SQLGetTypeInfoW(SQLHSTMT stmt, SQLSMALLINT sqltype)
Return data type information (UNICODE version).
Definition: sqlite3odbc.c:15963
lower_chars
static const char lower_chars[]
Definition: sqlite3odbc.c:547
typeSpec2
static COL typeSpec2[]
Columns for result set of SQLGetTypeInfo().
Definition: sqlite3odbc.c:15532
drvexecute
static SQLRETURN drvexecute(SQLHSTMT stmt, int initial)
drvsetconnectattr
static SQLRETURN drvsetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
Internal set connect attribute of HDBC.
Definition: sqlite3odbc.c:12335
SQLBulkOperations
SQLRETURN SQL_API SQLBulkOperations(SQLHSTMT stmt, SQLSMALLINT oper)
Perform bulk operation on HSTMT.
Definition: sqlite3odbc.c:11010
uc_from_utf
static SQLWCHAR * uc_from_utf(unsigned char *str, int len)
Make UNICODE string from UTF8 string.
Definition: sqlite3odbc.c:932
tblres::ndata
PTRDIFF_T ndata
index into result array
Definition: sqlite3odbc.c:1382
COL::table
char * table
Table name.
Definition: sqlite3odbc.h:166
stmt::guessed_types
int guessed_types
Flag for drvprepare()/drvexecute()
Definition: sqlite3odbc.h:290
getrowdata
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().
Definition: sqlite3odbc.c:13921
sqlite3odbc.h
stmt::dobigint
int dobigint
Force SQL_BIGINT for INTEGER columns.
Definition: sqlite3odbc.h:262
stmt::naterr
int naterr
Native error code.
Definition: sqlite3odbc.h:258
SQLSetScrollOptions
SQLRETURN SQL_API SQLSetScrollOptions(SQLHSTMT stmt, SQLUSMALLINT concur, SQLLEN rowkeyset, SQLUSMALLINT rowset)
Function not implemented.
Definition: sqlite3odbc.c:11026
drvprimarykeys
static SQLRETURN drvprimarykeys(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen)
Internal retrieve information about indexed columns.
Definition: sqlite3odbc.c:6577
setupdyncols
static SQLRETURN setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp)
tblres::ncol
int ncol
number of columns in result array
Definition: sqlite3odbc.c:1381
str2date
static int str2date(int jdconv, char *str, DATE_STRUCT *ds)
Convert string to ODBC DATE_STRUCT.
Definition: sqlite3odbc.c:3096
SQLPrimaryKeysW
SQLRETURN SQL_API SQLPrimaryKeysW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen)
Retrieve information about indexed columns (UNICODE version).
Definition: sqlite3odbc.c:6905
stmt::row_count
SQLULEN * row_count
Row count pointer.
Definition: sqlite3odbc.h:269
fixupsql
static char * fixupsql(char *sql, int sqlLen, int cte, int *nparam, int *isselect, char **errmsg)
Fixup query string with optional parameter markers.
Definition: sqlite3odbc.c:2524
SQLDataSourcesW
SQLRETURN SQL_API SQLDataSourcesW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *srvname, SQLSMALLINT buflen1, SQLSMALLINT *lenp1, SQLWCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
Function not implemented.
Definition: sqlite3odbc.c:4704
drvconnect
static SQLRETURN drvconnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen, char *pwd, int pwdLen, int isu)
Internal connect to SQLite database.
Definition: sqlite3odbc.c:12687
BINDPARM::strbuf
char strbuf[64]
String buffer for scalar data.
Definition: sqlite3odbc.h:216
stmt::sqlstate
char sqlstate[6]
SQL state for SQLError()
Definition: sqlite3odbc.h:259
drvgettable_row
static int drvgettable_row(TBLRES *t, int ncol, int rc)
Definition: sqlite3odbc.c:1392
SQLColumnPrivilegesW
SQLRETURN SQL_API SQLColumnPrivilegesW(SQLHSTMT stmt, SQLWCHAR *catalog, SQLSMALLINT catalogLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen, SQLWCHAR *column, SQLSMALLINT columnLen)
Retrieve privileges on columns (UNICODE version).
Definition: sqlite3odbc.c:6525
pkeySpec2
static COL pkeySpec2[]
Columns for result set of SQLPrimaryKeys().
Definition: sqlite3odbc.c:6546
mkresultset
static SQLRETURN mkresultset(HSTMT stmt, COL *colspec, int ncols, COL *colspec3, int ncols3, int *nret)
Setup empty result set from constant column specification.
Definition: sqlite3odbc.c:5914
SQLConnectW
SQLRETURN SQL_API SQLConnectW(SQLHDBC dbc, SQLWCHAR *dsn, SQLSMALLINT dsnLen, SQLWCHAR *uid, SQLSMALLINT uidLen, SQLWCHAR *pwd, SQLSMALLINT pwdLen)
Connect to SQLite database.
Definition: sqlite3odbc.c:12895
dbc::pwd
char * pwd
Password or NULL.
Definition: sqlite3odbc.h:145
BINDPARM::s3type
int s3type
SQLite3 type.
Definition: sqlite3odbc.h:217
SQLSetEnvAttr
SQLRETURN SQL_API SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
Set information in HENV.
Definition: sqlite3odbc.c:8585
SQLForeignKeysW
SQLRETURN SQL_API SQLForeignKeysW(SQLHSTMT stmt, SQLWCHAR *PKcatalog, SQLSMALLINT PKcatalogLen, SQLWCHAR *PKschema, SQLSMALLINT PKschemaLen, SQLWCHAR *PKtable, SQLSMALLINT PKtableLen, SQLWCHAR *FKcatalog, SQLSMALLINT FKcatalogLen, SQLWCHAR *FKschema, SQLSMALLINT FKschemaLen, SQLWCHAR *FKtable, SQLSMALLINT FKtableLen)
Retrieve information about primary/foreign keys (UNICODE version).
Definition: sqlite3odbc.c:7951
drvgetinfo
static SQLRETURN drvgetinfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen)
Internal return information about what this ODBC driver supports.
Definition: sqlite3odbc.c:11055
DRIVER_VER_INFO
#define DRIVER_VER_INFO
Definition: sqlite3odbc.c:209
drvgetgpps
#define drvgetgpps(d)
Definition: sqlite3odbc.c:1291
ENV::pool
int pool
True for SQL_CP_ONE_PER_DRIVER.
Definition: sqlite3odbc.h:99
PTRDIFF_T
#define PTRDIFF_T
Definition: sqlite3odbc.c:230
BINDCOL
Definition: sqlite3odbc.h:188
stmt::bind_type
SQLULEN bind_type
SQL_ATTR_ROW_BIND_TYPE.
Definition: sqlite3odbc.h:275
drvsetstmtattr
static SQLRETURN drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER buflen)
Internal set option on HSTMT.
Definition: sqlite3odbc.c:9330
SQLPutData
SQLRETURN SQL_API SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
Put (partial) parameter data into executing statement.
Definition: sqlite3odbc.c:5015
ENV_MAGIC
#define ENV_MAGIC
Definition: sqlite3odbc.c:262
COL::typename
char * typename
Column type name or NULL.
Definition: sqlite3odbc.h:178
COL
Definition: sqlite3odbc.h:164
SQLParamData
SQLRETURN SQL_API SQLParamData(SQLHSTMT stmt, SQLPOINTER *pind)
Retrieve next parameter for sending data to executing query.
Definition: sqlite3odbc.c:5650
drvgetconnectattr
static SQLRETURN drvgetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Internal get connect attribute of HDBC.
Definition: sqlite3odbc.c:12099
SQLGetDiagFieldW
SQLRETURN SQL_API SQLGetDiagFieldW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno, SQLSMALLINT id, SQLPOINTER info, SQLSMALLINT buflen, SQLSMALLINT *stringlen)
Get error record given handle (HDBC or HSTMT).
Definition: sqlite3odbc.c:9059
COLATTRIBUTE_LAST_ARG_TYPE
#define COLATTRIBUTE_LAST_ARG_TYPE
Definition: sqlite3odbc.c:216
SQLGetInfoW
SQLRETURN SQL_API SQLGetInfoW(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen)
Return information about what this ODBC driver supports.
Definition: sqlite3odbc.c:11579
drvforeignkeys
static SQLRETURN SQL_API drvforeignkeys(SQLHSTMT stmt, SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen, SQLCHAR *PKschema, SQLSMALLINT PKschemaLen, SQLCHAR *PKtable, SQLSMALLINT PKtableLen, SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen, SQLCHAR *FKschema, SQLSMALLINT FKschemaLen, SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
Internal retrieve information about primary/foreign keys.
Definition: sqlite3odbc.c:7443
procColSpec3
static COL procColSpec3[]
Definition: sqlite3odbc.c:8418
fkeySpec3
static COL fkeySpec3[]
Definition: sqlite3odbc.c:7407
pkeySpec3
static COL pkeySpec3[]
Definition: sqlite3odbc.c:6555
uc_strlen
static int uc_strlen(SQLWCHAR *str)
Return length of UNICODE string.
Definition: sqlite3odbc.c:800
dbtraceapi
static void dbtraceapi(DBC *d, char *fn, const char *sql)
Trace function for SQLite API calls.
Definition: sqlite3odbc.c:3853
SQLDisconnect
SQLRETURN SQL_API SQLDisconnect(SQLHDBC dbc)
Disconnect given HDBC.
Definition: sqlite3odbc.c:12984
dbc::sqlstate
char sqlstate[6]
SQL state for SQLError()
Definition: sqlite3odbc.h:129
SQLGetDescRecW
SQLRETURN SQL_API SQLGetDescRecW(SQLHDESC handle, SQLSMALLINT recno, SQLWCHAR *name, SQLSMALLINT buflen, SQLSMALLINT *strlen, SQLSMALLINT *type, SQLSMALLINT *subtype, SQLLEN *len, SQLSMALLINT *prec, SQLSMALLINT *scale, SQLSMALLINT *nullable)
Function not implemented.
Definition: sqlite3odbc.c:5877
stmt::logmsg
SQLCHAR logmsg[1024]
Message for SQLError()
Definition: sqlite3odbc.h:260
dbc::naterr
int naterr
Native error code.
Definition: sqlite3odbc.h:128
s3stmt_drop
static void s3stmt_drop(STMT *s)
Drop running sqlite statement in STMT.
Definition: sqlite3odbc.c:4603
SQLSetConnectOptionW
SQLRETURN SQL_API SQLSetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
Set option on HDBC (UNICODE version).
Definition: sqlite3odbc.c:12620
stmt::parm_bind_type
SQLULEN parm_bind_type
SQL_ATTR_PARAM_BIND_TYPE.
Definition: sqlite3odbc.h:282
dbc::t0
long t0
Start time for SQLITE busy handler.
Definition: sqlite3odbc.h:121
SQLGetStmtAttrW
SQLRETURN SQL_API SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Get option of HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9308
drvdescribecol
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.
Definition: sqlite3odbc.c:16971
SQLAllocStmt
SQLRETURN SQL_API SQLAllocStmt(SQLHDBC dbc, SQLHSTMT *stmt)
Allocate HSTMT given HDBC.
Definition: sqlite3odbc.c:13372
tblres::errmsg
char * errmsg
error message or NULL
Definition: sqlite3odbc.c:1376
drvunimpldbc
static SQLRETURN drvunimpldbc(HDBC dbc)
Report IM001 (not implemented) SQL error code for HDBC.
Definition: sqlite3odbc.c:1760
drvallocconnect
static SQLRETURN drvallocconnect(SQLHENV env, SQLHDBC *dbc)
Internal allocate HDBC.
Definition: sqlite3odbc.c:11926
s3stmt_coltype
static char * s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
Find out column type.
Definition: sqlite3odbc.c:4192
array_size
#define array_size(x)
Definition: sqlite3odbc.c:233
SQLNumParams
SQLRETURN SQL_API SQLNumParams(SQLHSTMT stmt, SQLSMALLINT *nparam)
Return number of parameters.
Definition: sqlite3odbc.c:5590
freep
static void freep(void *x)
Free memory given pointer to memory pointer.
Definition: sqlite3odbc.c:1797
stmt::parm_bind_offs
SQLULEN * parm_bind_offs
SQL_ATTR_PARAM_BIND_OFFSET_PTR.
Definition: sqlite3odbc.h:278
s3stmt_end_if
static void s3stmt_end_if(STMT *s)
Conditionally stop running sqlite statement.
Definition: sqlite3odbc.c:4585
stmt::bindparms
BINDPARM * bindparms
Array of bound parameters.
Definition: sqlite3odbc.h:250
BINDPARM::s3lival
sqlite_int64 s3lival
SQLite3 64bit integer value.
Definition: sqlite3odbc.h:221
stmt::dbc
HDBC dbc
Pointer to DBC.
Definition: sqlite3odbc.h:233
stmt::longnames
int longnames
Don't shorten column names.
Definition: sqlite3odbc.h:263
tablePrivSpec3
static COL tablePrivSpec3[]
Definition: sqlite3odbc.c:5966
SQLGetDescFieldW
SQLRETURN SQL_API SQLGetDescFieldW(SQLHDESC handle, SQLSMALLINT recno, SQLSMALLINT fieldid, SQLPOINTER value, SQLINTEGER buflen, SQLINTEGER *strlen)
Function not implemented.
Definition: sqlite3odbc.c:5818
drvgetstmtattr
static SQLRETURN drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Internal get option of HSTMT.
Definition: sqlite3odbc.c:9135
dserr
static int dserr(dstr *dsp)
Check error on dynamic string.
Definition: sqlite3odbc.c:773
SQLSetParam
SQLRETURN SQL_API SQLSetParam(SQLHSTMT stmt, SQLUSMALLINT par, SQLSMALLINT type, SQLSMALLINT sqltype, SQLULEN coldef, SQLSMALLINT scale, SQLPOINTER val, SQLLEN *nval)
Set information on parameter.
Definition: sqlite3odbc.c:5769
str2timestamp
static int str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
Convert string to ODBC TIMESTAMP_STRUCT.
Definition: sqlite3odbc.c:3332
endtran
static SQLRETURN endtran(DBC *d, SQLSMALLINT comptype, int force)
Internal commit or rollback transaction.
Definition: sqlite3odbc.c:8072
SQLFreeConnect
SQLRETURN SQL_API SQLFreeConnect(SQLHDBC dbc)
Free connection (HDBC).
Definition: sqlite3odbc.c:12083
fixupdyncols
static void fixupdyncols(STMT *s, DBC *d)
Fixup column information for a running statement.
Definition: sqlite3odbc.c:2785
setsqliteopts
static int setsqliteopts(sqlite3 *x, DBC *d)
Set SQLite options (PRAGMAs) given SQLite handle.
Definition: sqlite3odbc.c:2093
dbc::dobigint
int dobigint
Force SQL_BIGINT for INTEGER columns.
Definition: sqlite3odbc.h:132
SQLAllocHandle
SQLRETURN SQL_API SQLAllocHandle(SQLSMALLINT type, SQLHANDLE input, SQLHANDLE *output)
Allocate a HENV, HDBC, or HSTMT handle.
Definition: sqlite3odbc.c:13736
strdup_
static char * strdup_(const char *str)
Duplicate string using xmalloc().
Definition: sqlite3odbc.c:616
dbc::magic
int magic
Magic cookie.
Definition: sqlite3odbc.h:113
stmt::ncols
int ncols
Number of result columns.
Definition: sqlite3odbc.h:240
xrealloc
#define xrealloc(x, y)
Definition: sqlite3odbc.c:404
dbc::oemcp
int oemcp
True for Win32 OEM CP translation.
Definition: sqlite3odbc.h:140
SQLTablesW
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.
Definition: sqlite3odbc.c:14953
stmt::s3stmt_rownum
int s3stmt_rownum
Current row number.
Definition: sqlite3odbc.h:286
SQLBrowseConnectW
SQLRETURN SQL_API SQLBrowseConnectW(SQLHDBC dbc, SQLWCHAR *connin, SQLSMALLINT conninLen, SQLWCHAR *connout, SQLSMALLINT connoutMax, SQLSMALLINT *connoutLen)
Function not implemented.
Definition: sqlite3odbc.c:4774
SQLAllocEnv
SQLRETURN SQL_API SQLAllocEnv(SQLHENV *env)
Allocate HENV.
Definition: sqlite3odbc.c:11865
BINDPARM::bound
int bound
True when SQLBindParameter() called.
Definition: sqlite3odbc.h:213
stmt::jdconv
int * jdconv
True for julian day conversion.
Definition: sqlite3odbc.h:238
SQLGetFunctions
SQLRETURN SQL_API SQLGetFunctions(SQLHDBC dbc, SQLUSMALLINT func, SQLUSMALLINT *flags)
Return information about supported ODBC API functions.
Definition: sqlite3odbc.c:11682
nomem
static SQLRETURN nomem(STMT *s)
Report S1000 (out of memory) SQL error given STMT.
Definition: sqlite3odbc.c:1812
tableSpec3
static COL tableSpec3[]
Definition: sqlite3odbc.c:14639
BINDPARM::param
void * param
Parameter buffer.
Definition: sqlite3odbc.h:209
busy_handler
static int busy_handler(void *udata, int count)
Busy callback for SQLite.
Definition: sqlite3odbc.c:2018
dbc
Definition: sqlite3odbc.h:112
BINDPARM::coldef
int coldef
Definition: sqlite3odbc.h:205
SQLProcedureColumnsW
SQLRETURN SQL_API SQLProcedureColumnsW(SQLHSTMT stmt, SQLWCHAR *catalog, SQLSMALLINT catalogLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *proc, SQLSMALLINT procLen, SQLWCHAR *column, SQLSMALLINT columnLen)
Retrieve information about columns in result set of stored procedures (UNICODE version).
Definition: sqlite3odbc.c:8489
dbopen
static SQLRETURN dbopen(DBC *d, char *name, int isu, char *dsn, char *sflag, char *spflag, char *ntflag, char *jmode, char *busy)
Open SQLite database file given file name and flags.
Definition: sqlite3odbc.c:3897
BINDPARM::offs
int offs
Definition: sqlite3odbc.h:214
noconn
static SQLRETURN noconn(STMT *s)
Report S1000 (not connected) SQL error given STMT.
Definition: sqlite3odbc.c:1825
xstrdup
#define xstrdup(x)
Definition: sqlite3odbc.c:406
dbc::stmt
struct stmt * stmt
STMT list of this DBC.
Definition: sqlite3odbc.h:127
dbc::ov3val
int ov3val
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:124
dbc::jdconv
int jdconv
True for julian day conversion.
Definition: sqlite3odbc.h:141
drvgetcursorname
static SQLRETURN drvgetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen, SQLSMALLINT *lenp)
Internal function to get cursor name of STMT.
Definition: sqlite3odbc.c:13478
freeparams
static SQLRETURN freeparams(STMT *s)
Clear out parameter bindings, if any.
Definition: sqlite3odbc.c:5031
SQLRowCount
SQLRETURN SQL_API SQLRowCount(SQLHSTMT stmt, SQLLEN *nrows)
Return number of affected rows of HSTMT.
Definition: sqlite3odbc.c:16916
COL::prec
int prec
Precision of column.
Definition: sqlite3odbc.h:173
stmt::paramset_nrows
SQLUINTEGER paramset_nrows
Row count for paramset handling.
Definition: sqlite3odbc.h:273
SQLGetDiagRecW
SQLRETURN SQL_API SQLGetDiagRecW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno, SQLWCHAR *sqlstate, SQLINTEGER *nativeerr, SQLWCHAR *msg, SQLSMALLINT buflen, SQLSMALLINT *msglen)
Get error message given handle (HENV, HDBC, or HSTMT) (UNICODE version).
Definition: sqlite3odbc.c:8782
SQLStatisticsW
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).
Definition: sqlite3odbc.c:16376
statSpec3
static COL statSpec3[]
Definition: sqlite3odbc.c:15994
quiet
static int quiet
Definition: inst.c:60
tblres::nalloc
int nalloc
alloc'ed size of result array
Definition: sqlite3odbc.c:1379
dbc::trans_disable
int trans_disable
True for no transaction support.
Definition: sqlite3odbc.h:139
COL::autoinc
int autoinc
AUTO_INCREMENT column.
Definition: sqlite3odbc.h:174
SQLSetPos
SQLRETURN SQL_API SQLSetPos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
Set position on result in HSTMT.
Definition: sqlite3odbc.c:10567
TBLRES
struct tblres TBLRES
stmt::bkmrkptr
SQLINTEGER * bkmrkptr
SQL_ATTR_FETCH_BOOKMARK_PTR.
Definition: sqlite3odbc.h:245
BINDCOL::lenp
SQLLEN * lenp
Value return, actual size of value buffer.
Definition: sqlite3odbc.h:191
SQLGetConnectOptionW
SQLRETURN SQL_API SQLGetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
Get connect option of HDBC (UNICODE version).
Definition: sqlite3odbc.c:12534
BINDPARM::lenp0
SQLLEN * lenp0
Actual size of parameter buffer, initial value.
Definition: sqlite3odbc.h:208
dstr::buffer
char buffer[1]
String buffer.
Definition: sqlite3odbc.c:276
freestmt
static SQLRETURN freestmt(HSTMT stmt)
SETSTMTOPTION_LAST_ARG_TYPE
#define SETSTMTOPTION_LAST_ARG_TYPE
Definition: sqlite3odbc.c:221
mkbindcols
static SQLRETURN mkbindcols(STMT *s, int ncols)
Reallocate space for bound columns.
Definition: sqlite3odbc.c:13874
stringify
#define stringify(s)
Definition: sqlite3odbc.c:236
BINDPARM::lenp
SQLLEN * lenp
Actual size of parameter buffer.
Definition: sqlite3odbc.h:207
drvfreeconnect
static SQLRETURN drvfreeconnect(SQLHDBC dbc)
Internal free connection (HDBC).
Definition: sqlite3odbc.c:12005
tableSpec2
static COL tableSpec2[]
Columns for result set of SQLTables().
Definition: sqlite3odbc.c:14631
stmt::row_status1
SQLUSMALLINT row_status1
Internal status array for 1 row rowsets.
Definition: sqlite3odbc.h:268
stmt::cols
COL * cols
Result column array.
Definition: sqlite3odbc.h:241
SQLSetStmtAttrW
SQLRETURN SQL_API SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER buflen)
Set option on HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9517
s3bind
static void s3bind(DBC *d, sqlite3_stmt *stmt, int nparams, BINDPARM *p)
Definition: sqlite3odbc.c:1300
dbc::busyint
int busyint
Interrupt busy handler from SQLCancel()
Definition: sqlite3odbc.h:122
stmt::cursorname
SQLCHAR cursorname[32]
Cursor name.
Definition: sqlite3odbc.h:234
dbc::longnames
int longnames
Don't shorten column names.
Definition: sqlite3odbc.h:134
tblres::stmt
sqlite3_stmt * stmt
SQLite3 statement pointer.
Definition: sqlite3odbc.c:1377
BINDPARM::s3val
void * s3val
SQLite3 value buffer.
Definition: sqlite3odbc.h:219
colPrivSpec2
static COL colPrivSpec2[]
Columns for result set of SQLColumnPrivileges().
Definition: sqlite3odbc.c:6456
drvfetchscroll
static SQLRETURN drvfetchscroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLINTEGER offset)
Internal fetch function for SQLFetchScroll() and SQLExtendedFetch().
Definition: sqlite3odbc.c:16608
stmt::parm_oper
SQLUSMALLINT * parm_oper
SQL_ATTR_PARAM_OPERATION_PTR.
Definition: sqlite3odbc.h:279
max
#define max(a, b)
Definition: sqlite3odbc.c:227
SQLEndTran
SQLRETURN SQL_API SQLEndTran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
Commit or rollback transaction.
Definition: sqlite3odbc.c:8188
SQLBindParameter
SQLRETURN SQL_API SQLBindParameter(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype, SQLSMALLINT buftype, SQLSMALLINT ptype, SQLULEN coldef, SQLSMALLINT scale, SQLPOINTER data, SQLLEN buflen, SQLLEN *len)
Bind parameter on HSTMT.
Definition: sqlite3odbc.c:5538
namematch
static int namematch(char *str, char *pat, int esc)
SQL LIKE string match with optional backslash escape handling.
Definition: sqlite3odbc.c:1945
drvallocenv
static SQLRETURN drvallocenv(SQLHENV *env)
Internal allocate HENV.
Definition: sqlite3odbc.c:11831
freedyncols
static void freedyncols(STMT *s)
Free dynamically allocated column descriptions of STMT.
Definition: sqlite3odbc.c:13789
SQLFreeEnv
SQLRETURN SQL_API SQLFreeEnv(SQLHENV env)
Free HENV.
Definition: sqlite3odbc.c:11913
getmd
static void getmd(const char *typename, int sqltype, int *mp, int *dp)
Get maximum display size and number of digits after decimal point from field type specification.
Definition: sqlite3odbc.c:2300
uc_from_utf_buf
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
dbc::sqlite
sqlite3 * sqlite
SQLITE database handle.
Definition: sqlite3odbc.h:116
stmt::oemcp
int * oemcp
True for Win32 OEM CP translation.
Definition: sqlite3odbc.h:237
typeinfosort
static int typeinfosort(const void *a, const void *b)
Helper function to sort type information.
Definition: sqlite3odbc.c:15725
drvfreestmt
static SQLRETURN drvfreestmt(SQLHSTMT stmt, SQLUSMALLINT opt)
Internal function to perform certain kinds of free/close on STMT.
Definition: sqlite3odbc.c:13390
stmt::rowprs
int rowprs
Current start row of rowset.
Definition: sqlite3odbc.h:255
drvsetcursorname
static SQLRETURN drvsetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
Internal function to set cursor name on STMT.
Definition: sqlite3odbc.c:13615
COL::notnull
int notnull
NOT NULL constraint on column.
Definition: sqlite3odbc.h:175
drvsetpos
static SQLRETURN drvsetpos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
Internal set position on result in HSTMT.
Definition: sqlite3odbc.c:10222
BINDCOL::index
int index
Index of column in result.
Definition: sqlite3odbc.h:193
setupparbuf
static SQLRETURN setupparbuf(STMT *s, BINDPARM *p)
Setup parameter buffer for deferred parameter.
Definition: sqlite3odbc.c:5616
uc_free
static void uc_free(void *str)
Free converted UTF8 or UNICODE string.
Definition: sqlite3odbc.c:1046
stmt::isselect
int isselect
0 if query is a SELECT statement
Definition: sqlite3odbc.h:239
blob_export
static void blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function to export a BLOB to a file.
Definition: sqlite3odbc.c:3750
dbc::shortnames
int shortnames
Always use short column names.
Definition: sqlite3odbc.h:133
ODBC_INI
#define ODBC_INI
Definition: sqlite3odbc.c:205
SQLNumResultCols
SQLRETURN SQL_API SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *ncols)
Return number of columns of result set given HSTMT.
Definition: sqlite3odbc.c:16940
COL::nosign
int nosign
Unsigned type.
Definition: sqlite3odbc.h:171
chkunbound
static SQLRETURN chkunbound(STMT *s)
Check for unbound result columns.
Definition: sqlite3odbc.c:9748
dbc::nocreat
int nocreat
Don't auto create database file.
Definition: sqlite3odbc.h:135
SQLSetConnectAttrW
SQLRETURN SQL_API SQLSetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
Set connect attribute of HDBC (UNICODE version).
Definition: sqlite3odbc.c:12402
drvtables
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.
Definition: sqlite3odbc.c:14662
SQLExtendedFetch
SQLRETURN SQL_API SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT orient, SQLROWOFFSET offset, SQLROWSETSIZE *rowcount, SQLUSMALLINT *rowstatus)
Fetch result row with scrolling and row status.
Definition: sqlite3odbc.c:16876
stmt::rowfree
void(* rowfree)()
Free function for rows.
Definition: sqlite3odbc.h:257
stmt::retr_data
SQLULEN retr_data
SQL_ATTR_RETRIEVE_DATA.
Definition: sqlite3odbc.h:264
stmt::next
struct stmt * next
Linkage for STMT list in DBC.
Definition: sqlite3odbc.h:232
getmdays
static int getmdays(int year, int month)
Return number of month days.
Definition: sqlite3odbc.c:3062
colSpec2
static COL colSpec2[]
Columns for result set of SQLColumns().
Definition: sqlite3odbc.c:15007
BINDCOL::offs
int offs
Byte offset for SQLGetData()
Definition: sqlite3odbc.h:194
stmt::bincache
char * bincache
Cache for blob data.
Definition: sqlite3odbc.h:288
ENV::ov3
int ov3
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:98
SQLGetConnectAttrW
SQLRETURN SQL_API SQLGetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Get connect attribute of HDBC (UNICODE version).
Definition: sqlite3odbc.c:12271
drvsetconnectoption
static SQLRETURN drvsetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
Internal set option on HDBC.
Definition: sqlite3odbc.c:12565
min
#define min(a, b)
Definition: sqlite3odbc.c:225
stmt
Definition: sqlite3odbc.h:231
mapdeftype
static int mapdeftype(int type, int stype, int nosign, int nowchar)
Map SQL_C_DEFAULT to proper C type.
Definition: sqlite3odbc.c:2385
SQLSetStmtOptionW
SQLRETURN SQL_API SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SETSTMTOPTION_LAST_ARG_TYPE param)
Set option on HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9729
COL::label
char * label
Column label or NULL.
Definition: sqlite3odbc.h:179
drvgettable
static int drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp, int *ncolp, char **errp, int nparam, BINDPARM *p)
Definition: sqlite3odbc.c:1509
BINDPARM::stype
int stype
ODBC and SQL types.
Definition: sqlite3odbc.h:204
dbc::ov3
int * ov3
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:123
dbc::step_enable
int step_enable
True for sqlite_compile/step/finalize.
Definition: sqlite3odbc.h:138
SQLProceduresW
SQLRETURN SQL_API SQLProceduresW(SQLHSTMT stmt, SQLWCHAR *catalog, SQLSMALLINT catalogLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *proc, SQLSMALLINT procLen)
Retrieve information about stored procedures (UNICODE version).
Definition: sqlite3odbc.c:8377
drvgettypeinfo
static SQLRETURN drvgettypeinfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
Internal return data type information.
Definition: sqlite3odbc.c:15744
SQLSetDescRec
SQLRETURN SQL_API SQLSetDescRec(SQLHDESC handle, SQLSMALLINT recno, SQLSMALLINT type, SQLSMALLINT subtype, SQLLEN len, SQLSMALLINT prec, SQLSMALLINT scale, SQLPOINTER data, SQLLEN *strlen, SQLLEN *indicator)
Function not implemented.
Definition: sqlite3odbc.c:5893
typeSpec3
static COL typeSpec3[]
Definition: sqlite3odbc.c:15550
mktypeinfo
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.
Definition: sqlite3odbc.c:15583
BINDPARM::len
int len
Offset/length for SQLParamData()/SQLPutData()
Definition: sqlite3odbc.h:214
SQLFreeHandle
SQLRETURN SQL_API SQLFreeHandle(SQLSMALLINT type, SQLHANDLE h)
Free a HENV, HDBC, or HSTMT handle.
Definition: sqlite3odbc.c:13770
dbc::intrans
int intrans
True when transaction started.
Definition: sqlite3odbc.h:126
drvbindcol
static SQLRETURN drvbindcol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type, SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
Internal bind C variable to column of result set.
Definition: sqlite3odbc.c:14461
drvgetconnectoption
static SQLRETURN drvgetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
Internal get connect option of HDBC.
Definition: sqlite3odbc.c:12423
drvgetdiagfield
static SQLRETURN drvgetdiagfield(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno, SQLSMALLINT id, SQLPOINTER info, SQLSMALLINT buflen, SQLSMALLINT *stringlen)
Get error record given handle (HDBC or HSTMT).
Definition: sqlite3odbc.c:8860
stmt::row_status0
SQLUSMALLINT * row_status0
Internal status array.
Definition: sqlite3odbc.h:267
convJD2YMD
static void convJD2YMD(double jd, DATE_STRUCT *ds)
Convert julian day to year/month/day.
Definition: sqlite3odbc.c:3005
dbc::version
int version
SQLITE version number.
Definition: sqlite3odbc.h:117
tblres::nrow
int nrow
number of rows in result array
Definition: sqlite3odbc.c:1380
BINDPARM::scale
int scale
from SQLBindParameter()
Definition: sqlite3odbc.h:205
stmt::row_status
SQLUSMALLINT * row_status
Row status pointer.
Definition: sqlite3odbc.h:266
setupparam
static SQLRETURN setupparam(STMT *s, char *sql, int pnum)
Setup SQLite3 parameter for statement parameter.
Definition: sqlite3odbc.c:5056
DBC_MAGIC
#define DBC_MAGIC
Definition: sqlite3odbc.c:263
DEAD_MAGIC
#define DEAD_MAGIC
Definition: sqlite3odbc.c:264
SQLLEN
#define SQLLEN
Definition: sqlite3odbc.h:62
ISSPACE
#define ISSPACE(c)
Definition: sqlite3odbc.c:577
SQLAllocConnect
SQLRETURN SQL_API SQLAllocConnect(SQLHENV env, SQLHDBC *dbc)
Allocate HDBC.
Definition: sqlite3odbc.c:11993
stmt::nowchar
int nowchar[2]
Don't try to use WCHAR.
Definition: sqlite3odbc.h:261
SQLROWSETSIZE
#define SQLROWSETSIZE
Definition: sqlite3odbc.h:84
drvbindparam
static SQLRETURN drvbindparam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype, SQLSMALLINT buftype, SQLSMALLINT ptype, SQLUINTEGER coldef, SQLSMALLINT scale, SQLPOINTER data, SQLINTEGER buflen, SQLLEN *len)
Internal bind parameter on HSTMT.
Definition: sqlite3odbc.c:5399
SQLNativeSqlW
SQLRETURN SQL_API SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen, SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
Translate SQL string (UNICODE version).
Definition: sqlite3odbc.c:8277
drvcolumns
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.
Definition: sqlite3odbc.c:15064
xfree
#define xfree(x)
Definition: sqlite3odbc.c:405
dstr
struct dstr dstr
tblres
Definition: sqlite3odbc.c:1374
stmt::curtype
int curtype
Cursor type.
Definition: sqlite3odbc.h:283
setstatd
static void setstatd(DBC *d, int naterr, char *msg, char *st,...)
Set error message and SQL state on DBC.
Definition: sqlite3odbc.c:1687
setposrefr
static SQLRETURN setposrefr(STMT *s, int rsi)
Internal handler to refresh user buffers from driver side result set.
Definition: sqlite3odbc.c:10156
SCOL_VARCHAR
#define SCOL_VARCHAR
Definition: sqlite3odbc.c:255
SQLDriversW
SQLRETURN SQL_API SQLDriversW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *drvdesc, SQLSMALLINT descmax, SQLSMALLINT *desclenp, SQLWCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
Function not implemented.
Definition: sqlite3odbc.c:4738
strmak
#define strmak(dst, src, max, lenp)
Definition: sqlite3odbc.c:11037
dbc::cur_s3stmt
struct stmt * cur_s3stmt
Current STMT executing sqlite statement.
Definition: sqlite3odbc.h:142
SCOL_CHAR
#define SCOL_CHAR
Definition: sqlite3odbc.c:256
HDBC_UNLOCK
#define HDBC_UNLOCK(hdbc)
Definition: sqlite3odbc.c:531
SQLParamOptions
SQLRETURN SQL_API SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
Function not implemented.
Definition: sqlite3odbc.c:5788
drvstatistics
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.
Definition: sqlite3odbc.c:16025
BINDPARM::parbuf
void * parbuf
Buffer for SQL_LEN_DATA_AT_EXEC etc.
Definition: sqlite3odbc.h:215
COL::scale
int scale
Scale of column.
Definition: sqlite3odbc.h:172
SQLDescribeParam
SQLRETURN SQL_API SQLDescribeParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT *dtype, SQLULEN *size, SQLSMALLINT *decdigits, SQLSMALLINT *nullable)
Return information about parameter.
Definition: sqlite3odbc.c:5704
blob_import
static void blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function to import a BLOB from a file.
Definition: sqlite3odbc.c:3680
drvdriverconnect
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.
Definition: sqlite3odbc.c:13010
COL::db
char * db
Database name.
Definition: sqlite3odbc.h:165
BINDPARM::max
SQLLEN max
Max.
Definition: sqlite3odbc.h:206
stmt::nbindparms
int nbindparms
Number bound parameters.
Definition: sqlite3odbc.h:249
SQLCloseCursor
SQLRETURN SQL_API SQLCloseCursor(SQLHSTMT stmt)
Close open cursor.
Definition: sqlite3odbc.c:13722
stmt::max_rows
SQLULEN max_rows
SQL_ATTR_MAX_ROWS.
Definition: sqlite3odbc.h:274
COL::index
int index
Index of column in result.
Definition: sqlite3odbc.h:170
SQLColumnsW
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).
Definition: sqlite3odbc.c:15477
stmt::bindcols
BINDCOL * bindcols
Array of bound columns.
Definition: sqlite3odbc.h:247
COL::ispk
int ispk
Flag for primary key (> 0)
Definition: sqlite3odbc.h:176
freeresult
static void freeresult(STMT *s, int clrcols)
Free statement's result.
Definition: sqlite3odbc.c:13818
xdigits
static const char * xdigits
Definition: sqlite3odbc.c:279
SQLULEN
#define SQLULEN
Definition: sqlite3odbc.h:68
SQLGetStmtOption
SQLRETURN SQL_API SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
Get option of HSTMT.
Definition: sqlite3odbc.c:9590
SQLTablePrivilegesW
SQLRETURN SQL_API SQLTablePrivilegesW(SQLHSTMT stmt, SQLWCHAR *catalog, SQLSMALLINT catalogLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen)
Retrieve privileges on tables and/or views (UNICODE version).
Definition: sqlite3odbc.c:6409
SQLBindCol
SQLRETURN SQL_API SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type, SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
Bind C variable to column of result set.
Definition: sqlite3odbc.c:14616
upper_chars
static const char upper_chars[]
Definition: sqlite3odbc.c:546
dbc::dsn
char * dsn
ODBC data source name.
Definition: sqlite3odbc.h:119
stmt::binlen
int binlen
Length of blob data.
Definition: sqlite3odbc.h:289
drvgetstmtoption
static SQLRETURN drvgetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
Internal get option of HSTMT.
Definition: sqlite3odbc.c:9538
stmt::rowp
int rowp
Current result row.
Definition: sqlite3odbc.h:254
unquote
static char * unquote(char *str)
Strip quotes from quoted string in-place.
Definition: sqlite3odbc.c:1880
dbc::curtype
int curtype
Default cursor type.
Definition: sqlite3odbc.h:137
BINDPARM::type
int type
Definition: sqlite3odbc.h:204
SQLTransact
SQLRETURN SQL_API SQLTransact(SQLHENV env, SQLHDBC dbc, SQLUSMALLINT type)
Commit or rollback transaction.
Definition: sqlite3odbc.c:8202
HSTMT_LOCK
#define HSTMT_LOCK(hdbc)
Definition: sqlite3odbc.c:532
SQLGetEnvAttr
SQLRETURN SQL_API SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len, SQLINTEGER *lenp)
Get information of HENV.
Definition: sqlite3odbc.c:8516
drvdisconnect
static SQLRETURN drvdisconnect(SQLHDBC dbc)
Internal disconnect given HDBC.
Definition: sqlite3odbc.c:12940
SQLCancel
SQLRETURN SQL_API SQLCancel(SQLHSTMT stmt)
Cancel HSTMT closing cursor.
Definition: sqlite3odbc.c:13446
drvtableprivileges
static SQLRETURN drvtableprivileges(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen)
Retrieve privileges on tables and/or views.
Definition: sqlite3odbc.c:5989
procSpec2
static COL procSpec2[]
Columns for result set of SQLProcedures().
Definition: sqlite3odbc.c:8312
SQLSpecialColumnsW
SQLRETURN SQL_API SQLSpecialColumnsW(SQLHSTMT stmt, SQLUSMALLINT id, SQLWCHAR *cat, SQLSMALLINT catLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen, SQLUSMALLINT scope, SQLUSMALLINT nullable)
Retrieve information about indexed columns (UNICODE version).
Definition: sqlite3odbc.c:7343
stmt::nbindcols
int nbindcols
Number of entries in bindcols.
Definition: sqlite3odbc.h:248
dbc::autocommit
int autocommit
Auto commit state.
Definition: sqlite3odbc.h:125
stmt::bkmrk
int bkmrk
True when bookmarks used.
Definition: sqlite3odbc.h:244
dbc::logmsg
SQLCHAR logmsg[1024]
Message for SQLError()
Definition: sqlite3odbc.h:130
dsval
static const char * dsval(dstr *dsp)
Return dynamic string's value.
Definition: sqlite3odbc.c:758
dbc::dbname
char * dbname
SQLITE database name.
Definition: sqlite3odbc.h:118
SQLROWOFFSET
#define SQLROWOFFSET
Definition: sqlite3odbc.h:80
ISDIGIT
#define ISDIGIT(c)
Definition: sqlite3odbc.c:568
stmt::dyncols
COL * dyncols
Column array, but malloc()ed.
Definition: sqlite3odbc.h:242
BINDCOL::valp
SQLPOINTER valp
Value buffer.
Definition: sqlite3odbc.h:192
drvendtran
static SQLRETURN drvendtran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
Internal commit or rollback transaction.
Definition: sqlite3odbc.c:8131
uc_to_utf_c
static char * uc_to_utf_c(SQLWCHAR *str, int len)
Make UTF8 string from UNICODE string.
Definition: sqlite3odbc.c:1028
SQLGetData
SQLRETURN SQL_API SQLGetData(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type, SQLPOINTER val, SQLLEN len, SQLLEN *lenp)
Retrieve row data after fetch.
Definition: sqlite3odbc.c:16429
stmt::rowset_size
SQLULEN rowset_size
Size of rowset.
Definition: sqlite3odbc.h:265
fkeySpec2
static COL fkeySpec2[]
Columns for result set of SQLForeignKeys().
Definition: sqlite3odbc.c:7390
dbc::env
ENV * env
Pointer to environment.
Definition: sqlite3odbc.h:114
dbtracerc
static void dbtracerc(DBC *d, int rc, char *err)
Trace function for SQLite return codes.
Definition: sqlite3odbc.c:3873
BINDPARM
Definition: sqlite3odbc.h:203
unbindcols
static void unbindcols(STMT *s)
Reset bound columns to unbound state.
Definition: sqlite3odbc.c:13852
SQLSETPOSIROW
#define SQLSETPOSIROW
Definition: sqlite3odbc.h:76
dbc::fksupport
int fksupport
Foreign keys on or off.
Definition: sqlite3odbc.h:136
dbc::s3stmt_needmeta
int s3stmt_needmeta
True to get meta data in s3stmt_step().
Definition: sqlite3odbc.h:143
stmt::nparams
int nparams
Number of parameters in query.
Definition: sqlite3odbc.h:251
drvunimplstmt
static SQLRETURN drvunimplstmt(HSTMT stmt)
Report IM001 (not implemented) SQL error code for HSTMT.
Definition: sqlite3odbc.c:1779
SQLSetCursorNameW
SQLRETURN SQL_API SQLSetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT len)
Set cursor name on STMT (UNICODE version).
Definition: sqlite3odbc.c:13694
dstr::oom
int oom
True when out of memory.
Definition: sqlite3odbc.c:275
SQL_API
#define SQL_API
Definition: sqlite3odbc.h:58
HDBC_LOCK
#define HDBC_LOCK(hdbc)
Definition: sqlite3odbc.c:530
BINDCOL::max
SQLINTEGER max
Max.
Definition: sqlite3odbc.h:190
stmt::one_tbl
int one_tbl
Flag for single table (> 0)
Definition: sqlite3odbc.h:291
SQLSetDescFieldW
SQLRETURN SQL_API SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno, SQLSMALLINT fieldid, SQLPOINTER value, SQLINTEGER buflen)
Function not implemented.
Definition: sqlite3odbc.c:5846
SQLDescribeColW
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).
Definition: sqlite3odbc.c:17133
SQLSetStmtOption
SQLRETURN SQL_API SQLSetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SETSTMTOPTION_LAST_ARG_TYPE param)
Set option on HSTMT.
Definition: sqlite3odbc.c:9708
dstr
Definition: sqlite3odbc.c:272
s3stmt_end
static void s3stmt_end(STMT *s)
Stop running sqlite statement.
Definition: sqlite3odbc.c:4557
stmt::paramset_count
SQLULEN paramset_count
Internal for paramset.
Definition: sqlite3odbc.h:272
procColSpec2
static COL procColSpec2[]
Columns for result set of SQLProcedureColumns().
Definition: sqlite3odbc.c:8396
drvbulkoperations
static SQLRETURN drvbulkoperations(SQLHSTMT stmt, SQLSMALLINT op)
Internal perform bulk operation on HSTMT.
Definition: sqlite3odbc.c:10585
BINDPARM::s3ival
int s3ival
SQLite3 integer value.
Definition: sqlite3odbc.h:220
SQLGetCursorNameW
SQLRETURN SQL_API SQLGetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT buflen, SQLSMALLINT *lenp)
Get cursor name of STMT (UNICODE version).
Definition: sqlite3odbc.c:13571
starttran
static SQLRETURN starttran(STMT *s)
Start transaction when autocommit off.
Definition: sqlite3odbc.c:8029
COL::isrowid
int isrowid
Flag for ROWID column (> 0)
Definition: sqlite3odbc.h:177
stmt::ov3
int * ov3
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:236
stmt::bkmrkcol
BINDCOL bkmrkcol
Bookmark bound column.
Definition: sqlite3odbc.h:246
space_chars
static const char space_chars[]
Definition: sqlite3odbc.c:575
BINDPARM::need
int need
True when SQL_LEN_DATA_AT_EXEC.
Definition: sqlite3odbc.h:212
getbool
static int getbool(char *string)
Get boolean flag from string.
Definition: sqlite3odbc.c:3664
SET_EXISTS
#define SET_EXISTS(x)
uc_strncpy
static SQLWCHAR * uc_strncpy(SQLWCHAR *dest, SQLWCHAR *src, int len)
Copy UNICODE string like strncpy().
Definition: sqlite3odbc.c:822
dbc::next
struct dbc * next
Pointer to next DBC.
Definition: sqlite3odbc.h:115
dsfree
static void dsfree(dstr *dsp)
Free dynamic string.
Definition: sqlite3odbc.c:784
setposibind
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.
Definition: sqlite3odbc.c:10119
COL::size
int size
Size of column.
Definition: sqlite3odbc.h:169
xmalloc
#define xmalloc(x)
Definition: sqlite3odbc.c:403
stmt::bind_offs
SQLULEN * bind_offs
SQL_ATTR_ROW_BIND_OFFSET_PTR.
Definition: sqlite3odbc.h:276
drvgetdiagrec
static SQLRETURN drvgetdiagrec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno, SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg, SQLSMALLINT buflen, SQLSMALLINT *msglen)
Internal get error message given handle (HENV, HDBC, or HSTMT).
Definition: sqlite3odbc.c:8651
unescpat
static int unescpat(char *str)
Unescape search pattern for e.g.
Definition: sqlite3odbc.c:1907
dbc::nowchar
int nowchar
Don't try to use WCHAR.
Definition: sqlite3odbc.h:131
stmt::s3stmt_noreset
int s3stmt_noreset
False when sqlite3_reset() needed.
Definition: sqlite3odbc.h:285
stmt::dcols
int dcols
Number of entries in dyncols.
Definition: sqlite3odbc.h:243
drvputdata
static SQLRETURN drvputdata(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
Internal put (partial) parameter data into executing statement.
Definition: sqlite3odbc.c:4796
ENV::magic
int magic
Magic cookie.
Definition: sqlite3odbc.h:97
freerows
static void freerows(char **rowp)
Free counted array of char pointers.
Definition: sqlite3odbc.c:2150
drvrelgpps
#define drvrelgpps(d)
Definition: sqlite3odbc.c:1292
stmt::parm_proc
SQLULEN * parm_proc
SQL_ATTR_PARAMS_PROCESSED_PTR.
Definition: sqlite3odbc.h:281
tblres::s
STMT * s
Driver statement pointer.
Definition: sqlite3odbc.c:1378
drvallocstmt
static SQLRETURN drvallocstmt(SQLHDBC dbc, SQLHSTMT *stmt)
Allocate HSTMT given HDBC (driver internal version).
Definition: sqlite3odbc.c:13304
stmt::s3stmt
sqlite3_stmt * s3stmt
SQLite statement handle or NULL.
Definition: sqlite3odbc.h:284
SQLCopyDesc
SQLRETURN SQL_API SQLCopyDesc(SQLHDESC source, SQLHDESC target)
Function not implemented.
Definition: sqlite3odbc.c:8215
checkddl
static int checkddl(char *sql)
Check if query is a DDL statement.
Definition: sqlite3odbc.c:2471
COL::type
int type
Data type of column.
Definition: sqlite3odbc.h:168
dbc::pwdLen
int pwdLen
Length of password.
Definition: sqlite3odbc.h:146
BINDPARM::inc
int inc
Increment for paramset size > 1.
Definition: sqlite3odbc.h:211
ENV
Definition: sqlite3odbc.h:96
stmt::bincell
char * bincell
Cache for blob data.
Definition: sqlite3odbc.h:287
initialized
static int initialized
Definition: xpath.c:66
SQLFetchScroll
SQLRETURN SQL_API SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLLEN offset)
Fetch result row with scrolling.
Definition: sqlite3odbc.c:16855
dsappendq
static dstr * dsappendq(dstr *dsp, const char *str)
Append a string double quoted to dynamic string.
Definition: sqlite3odbc.c:690
BINDPARM::param0
void * param0
Parameter buffer, initial value.
Definition: sqlite3odbc.h:210
uc_to_utf
static char * uc_to_utf(SQLWCHAR *str, int len)
Make UTF8 string from UNICODE string.
Definition: sqlite3odbc.c:958
BINDPARM::s3size
int s3size
SQLite3 size.
Definition: sqlite3odbc.h:218
SQLFreeStmt
SQLRETURN SQL_API SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT opt)
Free HSTMT.
Definition: sqlite3odbc.c:13434
tblres::resarr
char ** resarr
result array
Definition: sqlite3odbc.c:1375
InUn
static BOOL InUn(int remove, char *drivername, char *dllname, char *dll2name, char *dsname)
Driver installer/uninstaller.
Definition: inst.c:153
s3stmt_start
static SQLRETURN s3stmt_start(STMT *s)
Start sqlite statement for execution of SELECT statement.
Definition: sqlite3odbc.c:4624
stmt::has_rowid
int has_rowid
Flag for ROWID (>= 0 or -1)
Definition: sqlite3odbc.h:293
dsappend
static dstr * dsappend(dstr *dsp, const char *str)
Append string to dynamic string.
Definition: sqlite3odbc.c:638
colSpec3
static COL colSpec3[]
Definition: sqlite3odbc.c:15028
drvfreeenv
static SQLRETURN drvfreeenv(SQLHENV env)
Internal free HENV.
Definition: sqlite3odbc.c:11877
str2time
static int str2time(int jdconv, char *str, TIME_STRUCT *ts)
Convert string to ODBC TIME_STRUCT.
Definition: sqlite3odbc.c:3211
ln_strtod
static double ln_strtod(const char *data, char **endp)
Internal locale neutral strtod function.
Definition: sqlite3odbc.c:1841
stmt::parm_status
SQLUSMALLINT * parm_status
SQL_ATTR_PARAMS_STATUS_PTR.
Definition: sqlite3odbc.h:280
BINDCOL::type
SQLSMALLINT type
ODBC type.
Definition: sqlite3odbc.h:189
stmt::row_count0
SQLULEN row_count0
Row count.
Definition: sqlite3odbc.h:270
dofetchbind
static SQLRETURN dofetchbind(STMT *s, int rsi)
Internal: fetch and bind from statement's current row.
Definition: sqlite3odbc.c:16488
dstr::len
int len
Current length.
Definition: sqlite3odbc.c:273

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