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];
277 } dstr;
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;
1384 } TBLRES;
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  */
sqlite3_stmt * s3stmt
SQLite statement handle or NULL.
Definition: sqlite3odbc.h:284
SQLULEN paramset_size
SQL_ATTR_PARAMSET_SIZE.
Definition: sqlite3odbc.h:271
sqlite_int64 s3lival
SQLite3 64bit integer value.
Definition: sqlite3odbc.h:221
int busyint
Interrupt busy handler from SQLCancel()
Definition: sqlite3odbc.h:122
static SQLRETURN setupparbuf(STMT *s, BINDPARM *p)
Setup parameter buffer for deferred parameter.
Definition: sqlite3odbc.c:5616
void * parbuf
Buffer for SQL_LEN_DATA_AT_EXEC etc.
Definition: sqlite3odbc.h:215
SQLRETURN SQL_API SQLSetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
Set connect attribute of HDBC (UNICODE version).
Internal dynamic string buffer.
Definition: blobtoxy.c:1212
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
SQLRETURN SQL_API SQLRowCount(SQLHSTMT stmt, SQLLEN *nrows)
Return number of affected rows of HSTMT.
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
static SQLRETURN nomem(STMT *s)
Report S1000 (out of memory) SQL error given STMT.
Definition: sqlite3odbc.c:1812
static const char lower_chars[]
Definition: sqlite3odbc.c:547
static int findcol(char **cols, int ncols, char *name)
Find column given name in string array.
Definition: sqlite3odbc.c:2754
int longnames
Don&#39;t shorten column names.
Definition: sqlite3odbc.h:134
int nocreat
Don&#39;t auto create database file.
Definition: sqlite3odbc.h:135
#define xstrdup(x)
Definition: sqlite3odbc.c:406
#define SQLLEN
Definition: sqlite3odbc.h:62
#define SQLULEN
Definition: sqlite3odbc.h:68
static void freerows(char **rowp)
Free counted array of char pointers.
Definition: sqlite3odbc.c:2150
SQLRETURN SQL_API SQLDisconnect(SQLHDBC dbc)
Disconnect given HDBC.
static void setstatd(DBC *d, int naterr, char *msg, char *st,...)
Set error message and SQL state on DBC.
Definition: sqlite3odbc.c:1687
struct dbc * dbcs
Pointer to first DBC.
Definition: sqlite3odbc.h:103
void * param0
Parameter buffer, initial value.
Definition: sqlite3odbc.h:210
int * ov3
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:236
static SQLRETURN freeparams(STMT *s)
Clear out parameter bindings, if any.
Definition: sqlite3odbc.c:5031
int dobigint
Force SQL_BIGINT for INTEGER columns.
Definition: sqlite3odbc.h:262
SQLCHAR * query
Current query, raw string.
Definition: sqlite3odbc.h:235
sqlite3 * sqlite
SQLITE database handle.
Definition: sqlite3odbc.h:116
static SQLRETURN drvgettypeinfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
Internal return data type information.
SQLRETURN SQL_API SQLConnectW(SQLHDBC dbc, SQLWCHAR *dsn, SQLSMALLINT dsnLen, SQLWCHAR *uid, SQLSMALLINT uidLen, SQLWCHAR *pwd, SQLSMALLINT pwdLen)
Connect to SQLite database.
int guessed_types
Flag for drvprepare()/drvexecute()
Definition: sqlite3odbc.h:290
SQLRETURN SQL_API SQLForeignKeysW(SQLHSTMT stmt, SQLWCHAR *PKcatalog, SQLSMALLINT PKcatalogLen, SQLWCHAR *PKschema, SQLSMALLINT PKschemaLen, SQLWCHAR *PKtable, SQLSMALLINT PKtableLen, SQLWCHAR *FKcatalog, SQLSMALLINT FKcatalogLen, SQLWCHAR *FKschema, SQLSMALLINT FKschemaLen, SQLWCHAR *FKtable, SQLSMALLINT FKtableLen)
Retrieve information about primary/foreign keys (UNICODE version).
Definition: sqlite3odbc.c:7951
static SQLRETURN drvfetchscroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLINTEGER offset)
Internal fetch function for SQLFetchScroll() and SQLExtendedFetch().
SQLRETURN SQL_API SQLParamData(SQLHSTMT stmt, SQLPOINTER *pind)
Retrieve next parameter for sending data to executing query.
Definition: sqlite3odbc.c:5650
static SQLRETURN drvfreeconnect(SQLHDBC dbc)
Internal free connection (HDBC).
SQLCHAR logmsg[1024]
Message for SQLError()
Definition: sqlite3odbc.h:260
static dstr * dsappend(dstr *dsp, const char *str)
Append string to dynamic string.
Definition: sqlite3odbc.c:638
static SQLRETURN drvgetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen, SQLSMALLINT *lenp)
Internal function to get cursor name of STMT.
char ** rows
2-dim array, result set
Definition: sqlite3odbc.h:256
int step_enable
True for sqlite_compile/step/finalize.
Definition: sqlite3odbc.h:138
#define drvgetgpps(d)
Definition: sqlite3odbc.c:1291
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).
static COL colSpec3[]
static int drvgettable_row(TBLRES *t, int ncol, int rc)
Definition: sqlite3odbc.c:1392
static void blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function to import a BLOB from a file.
Definition: sqlite3odbc.c:3680
SQLRETURN SQL_API SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLLEN offset)
Fetch result row with scrolling.
static void s3bind(DBC *d, sqlite3_stmt *stmt, int nparams, BINDPARM *p)
Definition: sqlite3odbc.c:1300
int ispk
Flag for primary key (> 0)
Definition: sqlite3odbc.h:176
static SQLRETURN dofetchbind(STMT *s, int rsi)
Internal: fetch and bind from statement&#39;s current row.
PTRDIFF_T ndata
index into result array
Definition: sqlite3odbc.c:1382
SQLRETURN SQL_API SQLSetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
Set option on HDBC (UNICODE version).
#define SQLROWSETSIZE
Definition: sqlite3odbc.h:84
int intrans
True when transaction started.
Definition: sqlite3odbc.h:126
int shortnames
Always use short column names.
Definition: sqlite3odbc.h:133
static SQLRETURN drvgetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
Internal get connect option of HDBC.
static SQLRETURN drvallocconnect(SQLHENV env, SQLHDBC *dbc)
Internal allocate HDBC.
SQLULEN * parm_bind_offs
SQL_ATTR_PARAM_BIND_OFFSET_PTR.
Definition: sqlite3odbc.h:278
void * s3val
SQLite3 value buffer.
Definition: sqlite3odbc.h:219
static int str2time(int jdconv, char *str, TIME_STRUCT *ts)
Convert string to ODBC TIME_STRUCT.
Definition: sqlite3odbc.c:3211
Internal structure for bound column (SQLBindCol).
Definition: sqlite3odbc.h:188
static COL pkeySpec2[]
Columns for result set of SQLPrimaryKeys().
Definition: sqlite3odbc.c:6546
SQLRETURN SQL_API SQLGetInfoW(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen)
Return information about what this ODBC driver supports.
#define ENV_MAGIC
Definition: sqlite3odbc.c:262
static COL fkeySpec2[]
Columns for result set of SQLForeignKeys().
Definition: sqlite3odbc.c:7390
static void freedyncols(STMT *s)
Free dynamically allocated column descriptions of STMT.
int nrows
Number of result rows.
Definition: sqlite3odbc.h:253
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
SQLRETURN SQL_API SQLCancel(SQLHSTMT stmt)
Cancel HSTMT closing cursor.
static int quiet
Definition: inst.c:60
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
SQLRETURN SQL_API SQLAllocEnv(SQLHENV *env)
Allocate HENV.
#define ISDIGIT(c)
Definition: sqlite3odbc.c:568
Driver internal structure for database connection (HDBC).
Definition: sqlite3odbc.h:112
SQLRETURN SQL_API SQLFreeConnect(SQLHDBC dbc)
Free connection (HDBC).
SQLRETURN SQL_API SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT orient, SQLROWOFFSET offset, SQLROWSETSIZE *rowcount, SQLUSMALLINT *rowstatus)
Fetch result row with scrolling and row status.
SQLULEN row_count0
Row count.
Definition: sqlite3odbc.h:270
int s3ival
SQLite3 integer value.
Definition: sqlite3odbc.h:220
struct stmt * cur_s3stmt
Current STMT executing sqlite statement.
Definition: sqlite3odbc.h:142
int need
True when SQL_LEN_DATA_AT_EXEC.
Definition: sqlite3odbc.h:212
static int checkddl(char *sql)
Check if query is a DDL statement.
Definition: sqlite3odbc.c:2471
static const char digit_chars[]
Definition: sqlite3odbc.c:566
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
SQLULEN parm_bind_type
SQL_ATTR_PARAM_BIND_TYPE.
Definition: sqlite3odbc.h:282
int * ov3
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:123
static SQLRETURN drvfreestmt(SQLHSTMT stmt, SQLUSMALLINT opt)
Internal function to perform certain kinds of free/close on STMT.
SQLULEN * row_count
Row count pointer.
Definition: sqlite3odbc.h:269
SQLRETURN SQL_API SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen, SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
Translate SQL string (UNICODE version).
Definition: sqlite3odbc.c:8277
static SQLRETURN drvallocenv(SQLHENV *env)
Internal allocate HENV.
static COL procSpec2[]
Columns for result set of SQLProcedures().
Definition: sqlite3odbc.c:8312
char sqlstate[6]
SQL state for SQLError()
Definition: sqlite3odbc.h:259
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
int inc
Increment for paramset size > 1.
Definition: sqlite3odbc.h:211
SQLLEN max
Max.
Definition: sqlite3odbc.h:206
static int getdsnattr(char *dsn, char *attr, char *out, int outLen)
Handling of SQLConnect() connection attributes for standalone operation without driver manager...
static void s3stmt_end(STMT *s)
Stop running sqlite statement.
Definition: sqlite3odbc.c:4557
SQLRETURN SQL_API SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno, SQLSMALLINT fieldid, SQLPOINTER value, SQLINTEGER buflen)
Function not implemented.
Definition: sqlite3odbc.c:5846
#define SQL_API
Definition: sqlite3odbc.h:58
char * column
Column name.
Definition: sqlite3odbc.h:167
int version
SQLITE version number.
Definition: sqlite3odbc.h:117
char * dsn
ODBC data source name.
Definition: sqlite3odbc.h:119
HDBC dbc
Pointer to DBC.
Definition: sqlite3odbc.h:233
static const char space_chars[]
Definition: sqlite3odbc.c:575
SQLRETURN SQL_API SQLDescribeColW(SQLHSTMT stmt, SQLUSMALLINT col, SQLWCHAR *name, SQLSMALLINT nameMax, SQLSMALLINT *nameLen, SQLSMALLINT *type, SQLULEN *size, SQLSMALLINT *digits, SQLSMALLINT *nullable)
Describe column information (UNICODE version).
static SQLRETURN drvdisconnect(SQLHDBC dbc)
Internal disconnect given HDBC.
static SQLRETURN drvsetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
Internal set option on HDBC.
#define SQLROWOFFSET
Definition: sqlite3odbc.h:80
int curtype
Default cursor type.
Definition: sqlite3odbc.h:137
#define xfree(x)
Definition: sqlite3odbc.c:405
Driver internal structure representing SQL statement (HSTMT).
Definition: sqlite3odbc.h:231
SQLRETURN SQL_API SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len, SQLINTEGER *lenp)
Get information of HENV.
Definition: sqlite3odbc.c:8516
SQLUINTEGER paramset_nrows
Row count for paramset handling.
Definition: sqlite3odbc.h:273
static int typeinfosort(const void *a, const void *b)
Helper function to sort type information.
int autocommit
Auto commit state.
Definition: sqlite3odbc.h:125
SQLCHAR logmsg[1024]
Message for SQLError()
Definition: sqlite3odbc.h:130
static SQLRETURN drvsetpos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
Internal set position on result in HSTMT.
static SQLRETURN drvgetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
Internal get option of HSTMT.
Definition: sqlite3odbc.c:9538
int isrowid
Flag for ROWID column (> 0)
Definition: sqlite3odbc.h:177
SQLRETURN SQL_API SQLGetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
Get option of HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9610
int prec
Precision of column.
Definition: sqlite3odbc.h:173
int magic
Magic cookie.
Definition: sqlite3odbc.h:97
ENV * env
Pointer to environment.
Definition: sqlite3odbc.h:114
char buffer[1]
String buffer.
Definition: sqlite3odbc.c:276
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
static void dbtrace(void *arg, const char *msg, sqlite_uint64 et)
SQLite trace or profile callback.
Definition: sqlite3odbc.c:3815
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.
#define HSTMT_LOCK(hdbc)
Definition: sqlite3odbc.c:532
SQLRETURN SQL_API SQLGetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
Get connect option of HDBC (UNICODE version).
SQLRETURN SQL_API SQLTransact(SQLHENV env, SQLHDBC dbc, SQLUSMALLINT type)
Commit or rollback transaction.
Definition: sqlite3odbc.c:8202
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
static SQLRETURN drvgetinfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen)
Internal return information about what this ODBC driver supports.
int nrow
number of rows in result array
Definition: sqlite3odbc.c:1380
static COL procColSpec3[]
Definition: sqlite3odbc.c:8418
static double ln_strtod(const char *data, char **endp)
Internal locale neutral strtod function.
Definition: sqlite3odbc.c:1841
static SQLRETURN drvcolumns(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen, SQLCHAR *col, SQLSMALLINT colLen)
Internal retrieve column information on table.
static SQLRETURN drvputdata(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
Internal put (partial) parameter data into executing statement.
Definition: sqlite3odbc.c:4796
#define SET_EXISTS(x)
static int mapdeftype(int type, int stype, int nosign, int nowchar)
Map SQL_C_DEFAULT to proper C type.
Definition: sqlite3odbc.c:2385
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
int pool
True for SQL_CP_ONE_PER_DRIVER.
Definition: sqlite3odbc.h:99
BINDPARM * bindparms
Array of bound parameters.
Definition: sqlite3odbc.h:250
#define SETSTMTOPTION_LAST_ARG_TYPE
Definition: sqlite3odbc.c:221
COL * cols
Result column array.
Definition: sqlite3odbc.h:241
#define DBC_MAGIC
Definition: sqlite3odbc.c:263
static SQLRETURN noconn(STMT *s)
Report S1000 (not connected) SQL error given STMT.
Definition: sqlite3odbc.c:1825
SQLULEN bind_type
SQL_ATTR_ROW_BIND_TYPE.
Definition: sqlite3odbc.h:275
SQLRETURN SQL_API SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
Put (partial) parameter data into executing statement.
Definition: sqlite3odbc.c:5015
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
SQLRETURN SQL_API SQLCopyDesc(SQLHDESC source, SQLHDESC target)
Function not implemented.
Definition: sqlite3odbc.c:8215
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
SQLPOINTER valp
Value buffer.
Definition: sqlite3odbc.h:192
SQLRETURN SQL_API SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT opt)
Free HSTMT.
SQLRETURN SQL_API SQLBulkOperations(SQLHSTMT stmt, SQLSMALLINT oper)
Perform bulk operation on HSTMT.
int ov3
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:98
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
static int namematch(char *str, char *pat, int esc)
SQL LIKE string match with optional backslash escape handling.
Definition: sqlite3odbc.c:1945
SQLUSMALLINT * parm_oper
SQL_ATTR_PARAM_OPERATION_PTR.
Definition: sqlite3odbc.h:279
static SQLWCHAR * uc_strncpy(SQLWCHAR *dest, SQLWCHAR *src, int len)
Copy UNICODE string like strncpy().
Definition: sqlite3odbc.c:822
static SQLWCHAR * uc_from_utf(unsigned char *str, int len)
Make UNICODE string from UTF8 string.
Definition: sqlite3odbc.c:932
char * dbname
SQLITE database name.
Definition: sqlite3odbc.h:118
SQLRETURN SQL_API SQLEndTran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
Commit or rollback transaction.
Definition: sqlite3odbc.c:8188
SQLRETURN SQL_API SQLFetch(SQLHSTMT stmt)
Fetch next result row.
static SQLRETURN mkbindcols(STMT *s, int ncols)
Reallocate space for bound columns.
int fksupport
Foreign keys on or off.
Definition: sqlite3odbc.h:136
SQLRETURN SQL_API SQLSetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT len)
Set cursor name on STMT (UNICODE version).
int s3stmt_needmeta
True to get meta data in s3stmt_step().
Definition: sqlite3odbc.h:143
int rowprs
Current start row of rowset.
Definition: sqlite3odbc.h:255
char * table
Table name.
Definition: sqlite3odbc.h:166
SQLRETURN SQL_API SQLDescribeParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT *dtype, SQLULEN *size, SQLSMALLINT *decdigits, SQLSMALLINT *nullable)
Return information about parameter.
Definition: sqlite3odbc.c:5704
static SQLRETURN drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd, SQLCHAR *connIn, SQLSMALLINT connInLen, SQLCHAR *connOut, SQLSMALLINT connOutMax, SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
Internal standalone (w/o driver manager) database connect.
static SQLRETURN drvallocstmt(SQLHDBC dbc, SQLHSTMT *stmt)
Allocate HSTMT given HDBC (driver internal version).
static int initialized
Definition: xpath.c:66
#define strmak(dst, src, max, lenp)
int rc
SQLite return code.
Definition: sqlite3odbc.c:1383
SQLRETURN SQL_API SQLCloseCursor(SQLHSTMT stmt)
Close open cursor.
int s3stmt_rownum
Current row number.
Definition: sqlite3odbc.h:286
static COL tablePrivSpec2[]
Columns for result set of SQLTablePrivileges().
Definition: sqlite3odbc.c:5956
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
int * jdconv
True for julian day conversion.
Definition: sqlite3odbc.h:238
SQLRETURN SQL_API SQLFreeHandle(SQLSMALLINT type, SQLHANDLE h)
Free a HENV, HDBC, or HSTMT handle.
static SQLRETURN drvsetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
Internal function to set cursor name on STMT.
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
SQLUSMALLINT row_status1
Internal status array for 1 row rowsets.
Definition: sqlite3odbc.h:268
SQLLEN * lenp
Value return, actual size of value buffer.
Definition: sqlite3odbc.h:191
SQLULEN retr_data
SQL_ATTR_RETRIEVE_DATA.
Definition: sqlite3odbc.h:264
int longnames
Don&#39;t shorten column names.
Definition: sqlite3odbc.h:263
int index
Index of column in result.
Definition: sqlite3odbc.h:193
static SQLRETURN chkunbound(STMT *s)
Check for unbound result columns.
Definition: sqlite3odbc.c:9748
static void freep(void *x)
Free memory given pointer to memory pointer.
Definition: sqlite3odbc.c:1797
static void fixupdyncols(STMT *s, DBC *d)
Fixup column information for a running statement.
Definition: sqlite3odbc.c:2785
static char * uc_to_utf(SQLWCHAR *str, int len)
Make UTF8 string from UNICODE string.
Definition: sqlite3odbc.c:958
int nosign
Unsigned type.
Definition: sqlite3odbc.h:171
static int getmdays(int year, int month)
Return number of month days.
Definition: sqlite3odbc.c:3062
static COL tablePrivSpec3[]
Definition: sqlite3odbc.c:5966
SQLSMALLINT type
ODBC type.
Definition: sqlite3odbc.h:189
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
SQLRETURN SQL_API SQLSpecialColumnsW(SQLHSTMT stmt, SQLUSMALLINT id, SQLWCHAR *cat, SQLSMALLINT catLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen, SQLUSMALLINT scope, SQLUSMALLINT nullable)
Retrieve information about indexed columns (UNICODE version).
Definition: sqlite3odbc.c:7343
static int str2date(int jdconv, char *str, DATE_STRUCT *ds)
Convert string to ODBC DATE_STRUCT.
Definition: sqlite3odbc.c:3096
static COL procSpec3[]
Definition: sqlite3odbc.c:8323
struct dbc * next
Pointer to next DBC.
Definition: sqlite3odbc.h:115
static COL typeSpec3[]
static SQLRETURN setposibind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
Internal handler to setup parameters for positional updates from driver side result set...
static COL colPrivSpec3[]
Definition: sqlite3odbc.c:6466
#define PTRDIFF_T
Definition: sqlite3odbc.c:230
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.
static COL statSpec2[]
Columns for result set of SQLStatistics().
int nowchar
Don&#39;t try to use WCHAR.
Definition: sqlite3odbc.h:131
#define HSTMT_UNLOCK(hdbc)
Definition: sqlite3odbc.c:533
SQLRETURN SQL_API SQLGetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT buflen, SQLSMALLINT *lenp)
Get cursor name of STMT (UNICODE version).
SQLRETURN SQL_API SQLSetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SETSTMTOPTION_LAST_ARG_TYPE param)
Set option on HSTMT.
Definition: sqlite3odbc.c:9708
SQLRETURN SQL_API SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SETSTMTOPTION_LAST_ARG_TYPE param)
Set option on HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9729
double s3dval
SQLite3 float value.
Definition: sqlite3odbc.h:222
static int drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp, int *ncolp, char **errp, int nparam, BINDPARM *p)
Definition: sqlite3odbc.c:1509
Internal structure for managing driver&#39;s sqlite3_get_table() implementation.
Definition: sqlite3odbc.c:1374
int pwdLen
Length of password.
Definition: sqlite3odbc.h:146
static void unbindcols(STMT *s)
Reset bound columns to unbound state.
static COL scolSpec2[]
Columns for result set of SQLSpecialColumns().
Definition: sqlite3odbc.c:6950
SQLRETURN SQL_API SQLGetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Get connect attribute of HDBC (UNICODE version).
int ncols
Number of result columns.
Definition: sqlite3odbc.h:240
#define WCHARSUPPORT
Definition: sqlite3odbc.c:185
SQLUSMALLINT * row_status
Row status pointer.
Definition: sqlite3odbc.h:266
SQLRETURN SQL_API SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *ncols)
Return number of columns of result set given HSTMT.
static COL pkeySpec3[]
Definition: sqlite3odbc.c:6555
static int busy_handler(void *udata, int count)
Busy callback for SQLite.
Definition: sqlite3odbc.c:2018
static char * uc_to_utf_c(SQLWCHAR *str, int len)
Make UTF8 string from UNICODE string.
Definition: sqlite3odbc.c:1028
#define SQLSETPOSIROW
Definition: sqlite3odbc.h:76
SQLCHAR cursorname[32]
Cursor name.
Definition: sqlite3odbc.h:234
static int str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
Convert string to ODBC TIMESTAMP_STRUCT.
Definition: sqlite3odbc.c:3332
static SQLRETURN starttran(STMT *s)
Start transaction when autocommit off.
Definition: sqlite3odbc.c:8029
static int s3stmt_step(STMT *s)
Do one sqlite statement step gathering one result row.
Definition: sqlite3odbc.c:4285
static COL tableSpec2[]
Columns for result set of SQLTables().
static SQLRETURN drvexecute(SQLHSTMT stmt, int initial)
struct stmt * next
Linkage for STMT list in DBC.
Definition: sqlite3odbc.h:232
static SQLRETURN drvbulkoperations(SQLHSTMT stmt, SQLSMALLINT op)
Internal perform bulk operation on HSTMT.
SQLRETURN SQL_API SQLSetPos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
Set position on result in HSTMT.
#define COLATTRIBUTE_LAST_ARG_TYPE
Definition: sqlite3odbc.c:216
char * bincache
Cache for blob data.
Definition: sqlite3odbc.h:288
static SQLRETURN setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp)
static COL procColSpec2[]
Columns for result set of SQLProcedureColumns().
Definition: sqlite3odbc.c:8396
static SQLRETURN drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER buflen)
Internal set option on HSTMT.
Definition: sqlite3odbc.c:9330
SQLINTEGER * bkmrkptr
SQL_ATTR_FETCH_BOOKMARK_PTR.
Definition: sqlite3odbc.h:245
int notnull
NOT NULL constraint on column.
Definition: sqlite3odbc.h:175
int timeout
Lock timeout value.
Definition: sqlite3odbc.h:120
SQLULEN max_rows
SQL_ATTR_MAX_ROWS.
Definition: sqlite3odbc.h:274
int nalloc
alloc&#39;ed size of result array
Definition: sqlite3odbc.c:1379
static void dbtraceapi(DBC *d, char *fn, const char *sql)
Trace function for SQLite API calls.
Definition: sqlite3odbc.c:3853
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
int coldef
Definition: sqlite3odbc.h:205
static int getbool(char *string)
Get boolean flag from string.
Definition: sqlite3odbc.c:3664
SQLRETURN SQL_API SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Get option of HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9308
char * label
Column label or NULL.
Definition: sqlite3odbc.h:179
SQLRETURN SQL_API SQLFreeEnv(SQLHENV env)
Free HENV.
int type
Data type of column.
Definition: sqlite3odbc.h:168
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
int nowchar[2]
Don&#39;t try to use WCHAR.
Definition: sqlite3odbc.h:261
static const char upper_chars[]
Definition: sqlite3odbc.c:546
int s3size
SQLite3 size.
Definition: sqlite3odbc.h:218
static SQLRETURN setupparam(STMT *s, char *sql, int pnum)
Setup SQLite3 parameter for statement parameter.
Definition: sqlite3odbc.c:5056
#define stringify(s)
Definition: sqlite3odbc.c:236
int binlen
Length of blob data.
Definition: sqlite3odbc.h:289
#define SCOL_VARCHAR
Definition: sqlite3odbc.c:255
SQLLEN * lenp0
Actual size of parameter buffer, initial value.
Definition: sqlite3odbc.h:208
int * oemcp
True for Win32 OEM CP translation.
Definition: sqlite3odbc.h:237
static SQLRETURN drvunimpldbc(HDBC dbc)
Report IM001 (not implemented) SQL error code for HDBC.
Definition: sqlite3odbc.c:1760
SQLUSMALLINT * row_status0
Internal status array.
Definition: sqlite3odbc.h:267
#define SCOL_CHAR
Definition: sqlite3odbc.c:256
static void s3stmt_end_if(STMT *s)
Conditionally stop running sqlite statement.
Definition: sqlite3odbc.c:4585
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).
SQLINTEGER max
Max.
Definition: sqlite3odbc.h:190
static int setsqliteopts(sqlite3 *x, DBC *d)
Set SQLite options (PRAGMAs) given SQLite handle.
Definition: sqlite3odbc.c:2093
int nbindcols
Number of entries in bindcols.
Definition: sqlite3odbc.h:248
int isselect
0 if query is a SELECT statement
Definition: sqlite3odbc.h:239
SQLLEN * lenp
Actual size of parameter buffer.
Definition: sqlite3odbc.h:207
SQLRETURN SQL_API SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
Get option of HSTMT.
Definition: sqlite3odbc.c:9590
static SQLRETURN drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
Internal set option on HSTMT.
Definition: sqlite3odbc.c:9630
char * pwd
Password or NULL.
Definition: sqlite3odbc.h:145
Driver internal structure for environment (HENV).
Definition: sqlite3odbc.h:96
static SQLRETURN drvfreeenv(SQLHENV env)
Internal free HENV.
static char * strdup_(const char *str)
Duplicate string using xmalloc().
Definition: sqlite3odbc.c:616
FILE * trace
sqlite3_trace() file pointer or NULL
Definition: sqlite3odbc.h:144
Internal structure representing dynamic strings.
Definition: sqlite3odbc.c:272
static void freeresult(STMT *s, int clrcols)
Free statement&#39;s result.
SQLRETURN SQL_API SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER buflen)
Set option on HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9517
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
sqlite3_stmt * stmt
SQLite3 statement pointer.
Definition: sqlite3odbc.c:1377
static void uc_free(void *str)
Free converted UTF8 or UNICODE string.
Definition: sqlite3odbc.c:1046
int autoinc
AUTO_INCREMENT column.
Definition: sqlite3odbc.h:174
SQLRETURN SQL_API SQLSetScrollOptions(SQLHSTMT stmt, SQLUSMALLINT concur, SQLLEN rowkeyset, SQLUSMALLINT rowset)
Function not implemented.
static SQLRETURN endtran(DBC *d, SQLSMALLINT comptype, int force)
Internal commit or rollback transaction.
Definition: sqlite3odbc.c:8072
int oom
True when out of memory.
Definition: sqlite3odbc.c:275
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.
static SQLRETURN drvsetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
Internal set connect attribute of HDBC.
SQLRETURN SQL_API SQLGetFunctions(SQLHDBC dbc, SQLUSMALLINT func, SQLUSMALLINT *flags)
Return information about supported ODBC API functions.
#define min(a, b)
Definition: sqlite3odbc.c:225
SQLRETURN SQL_API SQLBrowseConnectW(SQLHDBC dbc, SQLWCHAR *connin, SQLSMALLINT conninLen, SQLWCHAR *connout, SQLSMALLINT connoutMax, SQLSMALLINT *connoutLen)
Function not implemented.
Definition: sqlite3odbc.c:4774
char * db
Database name.
Definition: sqlite3odbc.h:165
static const char * xdigits
Definition: sqlite3odbc.c:279
long t0
Start time for SQLITE busy handler.
Definition: sqlite3odbc.h:121
int naterr
Native error code.
Definition: sqlite3odbc.h:128
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
char sqlstate[6]
SQL state for SQLError()
Definition: sqlite3odbc.h:129
int bound
True when SQLBindParameter() called.
Definition: sqlite3odbc.h:213
static void dbloadext(DBC *d, char *exts)
Load SQLite extension modules, if any.
Definition: sqlite3odbc.c:4111
static BOOL InUn(int remove, char *drivername, char *dllname, char *dll2name, char *dsname)
Driver installer/uninstaller.
Definition: inst.c:153
void * param
Parameter buffer.
Definition: sqlite3odbc.h:209
int one_tbl
Flag for single table (> 0)
Definition: sqlite3odbc.h:291
SQLRETURN SQL_API SQLGetData(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type, SQLPOINTER val, SQLLEN len, SQLLEN *lenp)
Retrieve row data after fetch.
void(* rowfree)()
Free function for rows.
Definition: sqlite3odbc.h:257
static int TOLOWER(int c)
Definition: sqlite3odbc.c:550
static COL tableSpec3[]
static SQLRETURN drvgetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Internal get connect attribute of HDBC.
int curtype
Cursor type.
Definition: sqlite3odbc.h:283
#define array_size(x)
Definition: sqlite3odbc.c:233
STMT * s
Driver statement pointer.
Definition: sqlite3odbc.c:1378
static COL colSpec2[]
Columns for result set of SQLColumns().
int ncol
number of columns in result array
Definition: sqlite3odbc.c:1381
int scale
from SQLBindParameter()
Definition: sqlite3odbc.h:205
COL * dyncols
Column array, but malloc()ed.
Definition: sqlite3odbc.h:242
int dobigint
Force SQL_BIGINT for INTEGER columns.
Definition: sqlite3odbc.h:132
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
int index
Index of column in result.
Definition: sqlite3odbc.h:170
int bkmrk
True when bookmarks used.
Definition: sqlite3odbc.h:244
SQLULEN * parm_proc
SQL_ATTR_PARAMS_PROCESSED_PTR.
Definition: sqlite3odbc.h:281
SQLULEN * bind_offs
SQL_ATTR_ROW_BIND_OFFSET_PTR.
Definition: sqlite3odbc.h:276
int magic
Magic cookie.
Definition: sqlite3odbc.h:113
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().
static SQLRETURN setposrefr(STMT *s, int rsi)
Internal handler to refresh user buffers from driver side result set.
static int dserr(dstr *dsp)
Check error on dynamic string.
Definition: sqlite3odbc.c:773
static SQLRETURN drvconnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen, char *pwd, int pwdLen, int isu)
Internal connect to SQLite database.
static void convJD2YMD(double jd, DATE_STRUCT *ds)
Convert julian day to year/month/day.
Definition: sqlite3odbc.c:3005
static dstr * dsappendq(dstr *dsp, const char *str)
Append a string double quoted to dynamic string.
Definition: sqlite3odbc.c:690
SQLRETURN SQL_API SQLSetParam(SQLHSTMT stmt, SQLUSMALLINT par, SQLSMALLINT type, SQLSMALLINT sqltype, SQLULEN coldef, SQLSMALLINT scale, SQLPOINTER val, SQLLEN *nval)
Set information on parameter.
Definition: sqlite3odbc.c:5769
static COL colPrivSpec2[]
Columns for result set of SQLColumnPrivileges().
Definition: sqlite3odbc.c:6456
int size
Size of column.
Definition: sqlite3odbc.h:169
static COL scolSpec3[]
Definition: sqlite3odbc.c:6962
static SQLRETURN drvunimplstmt(HSTMT stmt)
Report IM001 (not implemented) SQL error code for HSTMT.
Definition: sqlite3odbc.c:1779
struct dstr dstr
SQLRETURN SQL_API SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
Set information in HENV.
Definition: sqlite3odbc.c:8585
static char * s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
Find out column type.
Definition: sqlite3odbc.c:4192
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
#define max(a, b)
Definition: sqlite3odbc.c:227
BINDCOL * bindcols
Array of bound columns.
Definition: sqlite3odbc.h:247
int rowp
Current result row.
Definition: sqlite3odbc.h:254
#define DRIVER_VER_INFO
Definition: sqlite3odbc.c:209
SQLRETURN SQL_API SQLGetDescFieldW(SQLHDESC handle, SQLSMALLINT recno, SQLSMALLINT fieldid, SQLPOINTER value, SQLINTEGER buflen, SQLINTEGER *strlen)
Function not implemented.
Definition: sqlite3odbc.c:5818
int ov3val
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:124
int scale
Scale of column.
Definition: sqlite3odbc.h:172
static void dsfree(dstr *dsp)
Free dynamic string.
Definition: sqlite3odbc.c:784
SQLRETURN SQL_API SQLAllocConnect(SQLHENV env, SQLHDBC *dbc)
Allocate HDBC.
static SQLRETURN freestmt(HSTMT stmt)
char * typename
Column type name or NULL.
Definition: sqlite3odbc.h:178
SQLUSMALLINT * parm_status
SQL_ATTR_PARAMS_STATUS_PTR.
Definition: sqlite3odbc.h:280
static SQLRETURN s3stmt_start(STMT *s)
Start sqlite statement for execution of SELECT statement.
Definition: sqlite3odbc.c:4624
int jdconv
True for julian day conversion.
Definition: sqlite3odbc.h:141
int has_rowid
Flag for ROWID (>= 0 or -1)
Definition: sqlite3odbc.h:293
BINDCOL bkmrkcol
Bookmark bound column.
Definition: sqlite3odbc.h:246
SQLULEN rowset_size
Size of rowset.
Definition: sqlite3odbc.h:265
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.
#define ISSPACE(c)
Definition: sqlite3odbc.c:577
#define drvrelgpps(d)
Definition: sqlite3odbc.c:1292
static SQLRETURN drvcolattributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id, SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen, SQLLEN *val2)
Internal retrieve column attributes.
SQLRETURN SQL_API SQLNumParams(SQLHSTMT stmt, SQLSMALLINT *nparam)
Return number of parameters.
Definition: sqlite3odbc.c:5590
char strbuf[64]
String buffer for scalar data.
Definition: sqlite3odbc.h:216
static COL fkeySpec3[]
Definition: sqlite3odbc.c:7407
int oemcp
True for Win32 OEM CP translation.
Definition: sqlite3odbc.h:140
SQLRETURN SQL_API SQLGetTypeInfoW(SQLHSTMT stmt, SQLSMALLINT sqltype)
Return data type information (UNICODE version).
static SQLRETURN drvendtran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
Internal commit or rollback transaction.
Definition: sqlite3odbc.c:8131
char * bincell
Cache for blob data.
Definition: sqlite3odbc.h:287
int nparams
Number of parameters in query.
Definition: sqlite3odbc.h:251
static void setstat(STMT *s, int naterr, char *msg, char *st,...)
Set error message and SQL state on statement.
Definition: sqlite3odbc.c:1727
int stype
ODBC and SQL types.
Definition: sqlite3odbc.h:204
Internal structure for bound parameter (SQLBindParameter).
Definition: sqlite3odbc.h:203
static void s3stmt_drop(STMT *s)
Drop running sqlite statement in STMT.
Definition: sqlite3odbc.c:4603
int nbindparms
Number bound parameters.
Definition: sqlite3odbc.h:249
static COL typeSpec2[]
Columns for result set of SQLGetTypeInfo().
SQLRETURN SQL_API SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type, SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
Bind C variable to column of result set.
Internal structure to describe a column in a result set.
Definition: sqlite3odbc.h:164
char * errmsg
error message or NULL
Definition: sqlite3odbc.c:1376
SQLRETURN SQL_API SQLAllocStmt(SQLHDBC dbc, SQLHSTMT *stmt)
Allocate HSTMT given HDBC.
int has_pk
Flag for primary key (> 0)
Definition: sqlite3odbc.h:292
static SQLRETURN drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Internal get option of HSTMT.
Definition: sqlite3odbc.c:9135
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
static int uc_strlen(SQLWCHAR *str)
Return length of UNICODE string.
Definition: sqlite3odbc.c:800
int offs
Byte offset for SQLGetData()
Definition: sqlite3odbc.h:194
struct tblres TBLRES
SQLULEN paramset_count
Internal for paramset.
Definition: sqlite3odbc.h:272
int pdcount
SQLParamData() counter.
Definition: sqlite3odbc.h:252
struct stmt * stmt
STMT list of this DBC.
Definition: sqlite3odbc.h:127
#define HDBC_UNLOCK(hdbc)
Definition: sqlite3odbc.c:531
static SQLRETURN drvdescribecol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name, SQLSMALLINT nameMax, SQLSMALLINT *nameLen, SQLSMALLINT *type, SQLULEN *size, SQLSMALLINT *digits, SQLSMALLINT *nullable)
Internal describe column information.
static char * unquote(char *str)
Strip quotes from quoted string in-place.
Definition: sqlite3odbc.c:1880
static SQLRETURN drvbindcol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type, SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
Internal bind C variable to column of result set.
SQLRETURN SQL_API SQLAllocHandle(SQLSMALLINT type, SQLHANDLE input, SQLHANDLE *output)
Allocate a HENV, HDBC, or HSTMT handle.
static COL statSpec3[]
SQLRETURN SQL_API SQLColumnPrivilegesW(SQLHSTMT stmt, SQLWCHAR *catalog, SQLSMALLINT catalogLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen, SQLWCHAR *column, SQLSMALLINT columnLen)
Retrieve privileges on columns (UNICODE version).
Definition: sqlite3odbc.c:6525
static void convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
Convert julian day to hour/minute/second.
Definition: sqlite3odbc.c:3033
char ** resarr
result array
Definition: sqlite3odbc.c:1375
#define verinfo(maj, min, lev)
Definition: sqlite3odbc.c:238
int s3stmt_noreset
False when sqlite3_reset() needed.
Definition: sqlite3odbc.h:285
static void dbtracerc(DBC *d, int rc, char *err)
Trace function for SQLite return codes.
Definition: sqlite3odbc.c:3873
int trans_disable
True for no transaction support.
Definition: sqlite3odbc.h:139
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
int len
Current length.
Definition: sqlite3odbc.c:273
#define DEAD_MAGIC
Definition: sqlite3odbc.c:264
static const char * dsval(dstr *dsp)
Return dynamic string&#39;s value.
Definition: sqlite3odbc.c:758
int dcols
Number of entries in dyncols.
Definition: sqlite3odbc.h:243
int s3type
SQLite3 type.
Definition: sqlite3odbc.h:217
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
SQLRETURN SQL_API SQLProceduresW(SQLHSTMT stmt, SQLWCHAR *catalog, SQLSMALLINT catalogLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *proc, SQLSMALLINT procLen)
Retrieve information about stored procedures (UNICODE version).
Definition: sqlite3odbc.c:8377
static 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
SQLRETURN SQL_API SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
Function not implemented.
Definition: sqlite3odbc.c:5788
#define xmalloc(x)
Definition: sqlite3odbc.c:403
#define ODBC_INI
Definition: sqlite3odbc.c:205
#define xrealloc(x, y)
Definition: sqlite3odbc.c:404
#define HDBC_LOCK(hdbc)
Definition: sqlite3odbc.c:530
int naterr
Native error code.
Definition: sqlite3odbc.h:258
int len
Offset/length for SQLParamData()/SQLPutData()
Definition: sqlite3odbc.h:214
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
Header file for SQLite3 ODBC driver.
int max
Maximum length of buffer.
Definition: sqlite3odbc.c:274
static int unescpat(char *str)
Unescape search pattern for e.g.
Definition: sqlite3odbc.c:1907

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