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 + sizeof (*dsp));
653  if (dsp) {
654  dsp->max = max;
655  dsp->len = dsp->oom = 0;
656  goto copy;
657  }
658  return dsp;
659  }
660  if (dsp->oom) {
661  return dsp;
662  }
663  if (dsp->len + len > dsp->max) {
664  int max = dsp->max + len + 256;
665  dstr *ndsp = xrealloc(dsp, max + sizeof (*dsp));
666 
667  if (!ndsp) {
668  strcpy(dsp->buffer, "OUT OF MEMORY");
669  dsp->max = dsp->len = 13;
670  dsp->oom = 1;
671  return dsp;
672  }
673  dsp = ndsp;
674  dsp->max = max;
675  }
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 + sizeof (*dsp));
713  if (dsp) {
714  dsp->max = max;
715  dsp->len = dsp->oom = 0;
716  goto copy;
717  }
718  return dsp;
719  }
720  if (dsp->oom) {
721  return dsp;
722  }
723  if (dsp->len + len > dsp->max) {
724  int max = dsp->max + len + 256;
725  dstr *ndsp = xrealloc(dsp, max + sizeof (*dsp));
726 
727  if (!ndsp) {
728  strcpy(dsp->buffer, "OUT OF MEMORY");
729  dsp->max = dsp->len = 13;
730  dsp->oom = 1;
731  return dsp;
732  }
733  dsp = ndsp;
734  dsp->max = max;
735  }
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)(char *, char *, char *, char *, int, char *);
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 (*)(char *, char *, char *, char *, int, char *)) 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  if (nalloc < t->nalloc) {
1408  goto nomem;
1409  }
1410  resnew = xrealloc(t->resarr, sizeof (char *) * nalloc);
1411  if (!resnew) {
1412 nomem:
1413  t->rc = SQLITE_NOMEM;
1414  return 1;
1415  }
1416  t->nalloc = nalloc;
1417  t->resarr = resnew;
1418  }
1419  /* column names when first row */
1420  if (t->nrow == 0) {
1421  t->ncol = ncol;
1422  for (i = 0; i < ncol; i++) {
1423  p = (char *) sqlite3_column_name(t->stmt, i);
1424  if (p) {
1425  char *q = xmalloc(strlen(p) + 1);
1426 
1427  if (!q) {
1428  goto nomem;
1429  }
1430  strcpy(q, p);
1431  p = q;
1432  }
1433  t->resarr[t->ndata++] = p;
1434  }
1435  if (t->s && t->s->guessed_types) {
1436  int ncol2 = ncol;
1437 
1438  setupdyncols(t->s, t->stmt, &ncol2);
1439  t->s->guessed_types = 0;
1440  t->s->ncols = ncol;
1441  }
1442  } else if (t->ncol != ncol) {
1443  t->errmsg = sqlite3_mprintf("drvgettable() called with two or"
1444  " more incompatible queries");
1445  t->rc = SQLITE_ERROR;
1446  return 1;
1447  }
1448  /* copy row data */
1449  if (rc == SQLITE_ROW) {
1450  for (i = 0; i < ncol; i++) {
1451  int coltype = sqlite3_column_type(t->stmt, i);
1452 
1453  p = NULL;
1454  if (coltype == SQLITE_BLOB) {
1455  int k, nbytes = sqlite3_column_bytes(t->stmt, i);
1456  char *qp;
1457  unsigned const char *bp;
1458 
1459  bp = sqlite3_column_blob(t->stmt, i);
1460  qp = xmalloc(nbytes * 2 + 4);
1461  if (!qp) {
1462  goto nomem;
1463  }
1464  p = qp;
1465  *qp++ = 'X';
1466  *qp++ = '\'';
1467  for (k = 0; k < nbytes; k++) {
1468  *qp++ = xdigits[(bp[k] >> 4)];
1469  *qp++ = xdigits[(bp[k] & 0xF)];
1470  }
1471  *qp++ = '\'';
1472  *qp = '\0';
1473 #ifdef _MSC_VER
1474  } else if (coltype == SQLITE_FLOAT) {
1475  struct lconv *lc = 0;
1476  double val = sqlite3_column_double(t->stmt, i);
1477  char buffer[128];
1478 
1479  /*
1480  * This avoids floating point rounding
1481  * and formatting problems of some SQLite
1482  * versions in conjunction with MSVC 2010.
1483  */
1484  snprintf(buffer, sizeof (buffer), "%.15g", val);
1485  lc = localeconv();
1486  if (lc && lc->decimal_point && lc->decimal_point[0] &&
1487  lc->decimal_point[0] != '.') {
1488  p = strchr(buffer, lc->decimal_point[0]);
1489  if (p) {
1490  *p = '.';
1491  }
1492  }
1493  p = xstrdup(buffer);
1494  if (!p) {
1495  goto nomem;
1496  }
1497 #endif
1498  } else if (coltype != SQLITE_NULL) {
1499  p = xstrdup((char *) sqlite3_column_text(t->stmt, i));
1500  if (!p) {
1501  goto nomem;
1502  }
1503  }
1504  t->resarr[t->ndata++] = p;
1505  }
1506  t->nrow++;
1507  }
1508  return 0;
1509 }
1510 
1511 static int
1512 drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp,
1513  int *ncolp, char **errp, int nparam, BINDPARM *p)
1514 {
1515  DBC *d = (DBC *) s->dbc;
1516  int rc = SQLITE_OK, keep = sql == NULL;
1517  TBLRES tres;
1518  const char *sqlleft = 0;
1519  int nretry = 0, haveerr = 0;
1520 
1521  if (!resp) {
1522  return SQLITE_ERROR;
1523  }
1524  *resp = NULL;
1525  if (nrowp) {
1526  *nrowp = 0;
1527  }
1528  if (ncolp) {
1529  *ncolp = 0;
1530  }
1531  tres.errmsg = NULL;
1532  tres.nrow = 0;
1533  tres.ncol = 0;
1534  tres.ndata = 1;
1535  tres.nalloc = 20;
1536  tres.rc = SQLITE_OK;
1537  tres.resarr = xmalloc(sizeof (char *) * tres.nalloc);
1538  tres.stmt = NULL;
1539  tres.s = s;
1540  if (!tres.resarr) {
1541  return SQLITE_NOMEM;
1542  }
1543  tres.resarr[0] = 0;
1544  if (sql == NULL) {
1545  tres.stmt = s->s3stmt;
1546  if (tres.stmt == NULL) {
1547  return SQLITE_NOMEM;
1548  }
1549  goto retrieve;
1550  }
1551  while (sql && *sql && (rc == SQLITE_OK ||
1552  (rc == SQLITE_SCHEMA && (++nretry) < 2))) {
1553  int ncol;
1554 
1555  tres.stmt = NULL;
1556 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
1557  dbtraceapi(d, "sqlite3_prepare_v2", sql);
1558  rc = sqlite3_prepare_v2(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
1559 #else
1560  dbtraceapi(d, "sqlite3_prepare", sql);
1561  rc = sqlite3_prepare(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
1562 #endif
1563  if (rc != SQLITE_OK) {
1564  if (tres.stmt) {
1565  dbtraceapi(d, "sqlite3_finalize", 0);
1566  sqlite3_finalize(tres.stmt);
1567  tres.stmt = NULL;
1568  }
1569  continue;
1570  }
1571  if (!tres.stmt) {
1572  /* this happens for a comment or white-space */
1573  sql = sqlleft;
1574  continue;
1575  }
1576 retrieve:
1577  if (sqlite3_bind_parameter_count(tres.stmt) != nparam) {
1578  if (errp) {
1579  *errp =
1580  sqlite3_mprintf("%s", "parameter marker count incorrect");
1581  }
1582  haveerr = 1;
1583  rc = SQLITE_ERROR;
1584  goto tbldone;
1585  }
1586  s3bind(d, tres.stmt, nparam, p);
1587  ncol = sqlite3_column_count(tres.stmt);
1588  while (1) {
1589  if (s->max_rows && tres.nrow >= s->max_rows) {
1590  rc = SQLITE_OK;
1591  break;
1592  }
1593  rc = sqlite3_step(tres.stmt);
1594  if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
1595  if (drvgettable_row(&tres, ncol, rc)) {
1596  rc = SQLITE_ABORT;
1597  goto tbldone;
1598  }
1599  }
1600  if (rc != SQLITE_ROW) {
1601  if (keep) {
1602  dbtraceapi(d, "sqlite3_reset", 0);
1603  rc = sqlite3_reset(tres.stmt);
1604  s->s3stmt_noreset = 1;
1605  } else {
1606  dbtraceapi(d, "sqlite3_finalize", 0);
1607  rc = sqlite3_finalize(tres.stmt);
1608  }
1609  tres.stmt = 0;
1610  if (rc != SQLITE_SCHEMA) {
1611  nretry = 0;
1612  sql = sqlleft;
1613  while (sql && ISSPACE(*sql)) {
1614  sql++;
1615  }
1616  }
1617  if (rc == SQLITE_DONE) {
1618  rc = SQLITE_OK;
1619  }
1620  break;
1621  }
1622  }
1623  }
1624 tbldone:
1625  if (tres.stmt) {
1626  if (keep) {
1627  if (!s->s3stmt_noreset) {
1628  dbtraceapi(d, "sqlite3_reset", 0);
1629  sqlite3_reset(tres.stmt);
1630  s->s3stmt_noreset = 1;
1631  }
1632  } else {
1633  dbtraceapi(d, "sqlite3_finalize", 0);
1634  sqlite3_finalize(tres.stmt);
1635  }
1636  }
1637  if (haveerr) {
1638  /* message already in *errp if any */
1639  } else if (rc != SQLITE_OK && rc == sqlite3_errcode(d->sqlite) && errp) {
1640  *errp = sqlite3_mprintf("%s", sqlite3_errmsg(d->sqlite));
1641  } else if (errp) {
1642  *errp = NULL;
1643  }
1644  if (tres.resarr) {
1645  tres.resarr[0] = (char *) (tres.ndata - 1);
1646  }
1647  if (rc == SQLITE_ABORT) {
1648  freerows(&tres.resarr[1]);
1649  if (tres.errmsg) {
1650  if (errp) {
1651  if (*errp) {
1652  sqlite3_free(*errp);
1653  }
1654  *errp = tres.errmsg;
1655  } else {
1656  sqlite3_free(tres.errmsg);
1657  }
1658  }
1659  return tres.rc;
1660  }
1661  sqlite3_free(tres.errmsg);
1662  if (rc != SQLITE_OK) {
1663  freerows(&tres.resarr[1]);
1664  return rc;
1665  }
1666  *resp = &tres.resarr[1];
1667  if (ncolp) {
1668  *ncolp = tres.ncol;
1669  }
1670  if (nrowp) {
1671  *nrowp = tres.nrow;
1672  }
1673  return rc;
1674 }
1675 
1684 #if defined(__GNUC__) && (__GNUC__ >= 2)
1685 static void setstatd(DBC *, int, char *, char *, ...)
1686  __attribute__((format (printf, 3, 5)));
1687 #endif
1688 
1689 static void
1690 setstatd(DBC *d, int naterr, char *msg, char *st, ...)
1691 {
1692  va_list ap;
1693 
1694  if (!d) {
1695  return;
1696  }
1697  d->naterr = naterr;
1698  d->logmsg[0] = '\0';
1699  if (msg) {
1700  int count;
1701 
1702  va_start(ap, st);
1703  count = vsnprintf((char *) d->logmsg, sizeof (d->logmsg), msg, ap);
1704  va_end(ap);
1705  if (count < 0) {
1706  d->logmsg[sizeof (d->logmsg) - 1] = '\0';
1707  }
1708  }
1709  if (!st) {
1710  st = "?????";
1711  }
1712  strncpy(d->sqlstate, st, 5);
1713  d->sqlstate[5] = '\0';
1714 }
1715 
1724 #if defined(__GNUC__) && (__GNUC__ >= 2)
1725 static void setstat(STMT *, int, char *, char *, ...)
1726  __attribute__((format (printf, 3, 5)));
1727 #endif
1728 
1729 static void
1730 setstat(STMT *s, int naterr, char *msg, char *st, ...)
1731 {
1732  va_list ap;
1733 
1734  if (!s) {
1735  return;
1736  }
1737  s->naterr = naterr;
1738  s->logmsg[0] = '\0';
1739  if (msg) {
1740  int count;
1741 
1742  va_start(ap, st);
1743  count = vsnprintf((char *) s->logmsg, sizeof (s->logmsg), msg, ap);
1744  va_end(ap);
1745  if (count < 0) {
1746  s->logmsg[sizeof (s->logmsg) - 1] = '\0';
1747  }
1748  }
1749  if (!st) {
1750  st = "?????";
1751  }
1752  strncpy(s->sqlstate, st, 5);
1753  s->sqlstate[5] = '\0';
1754 }
1755 
1762 static SQLRETURN
1764 {
1765  DBC *d;
1766 
1767  if (dbc == SQL_NULL_HDBC) {
1768  return SQL_INVALID_HANDLE;
1769  }
1770  d = (DBC *) dbc;
1771  setstatd(d, -1, "not supported", "IM001");
1772  return SQL_ERROR;
1773 }
1774 
1781 static SQLRETURN
1783 {
1784  STMT *s;
1785 
1786  if (stmt == SQL_NULL_HSTMT) {
1787  return SQL_INVALID_HANDLE;
1788  }
1789  s = (STMT *) stmt;
1790  setstat(s, -1, "not supported", "IM001");
1791  return SQL_ERROR;
1792 }
1793 
1799 static void
1800 freep(void *x)
1801 {
1802  if (x && ((char **) x)[0]) {
1803  xfree(((char **) x)[0]);
1804  ((char **) x)[0] = NULL;
1805  }
1806 }
1807 
1814 static SQLRETURN
1816 {
1817  setstat(s, -1, "out of memory", (*s->ov3) ? "HY000" : "S1000");
1818  return SQL_ERROR;
1819 }
1820 
1827 static SQLRETURN
1829 {
1830  setstat(s, -1, "not connected", (*s->ov3) ? "HY000" : "S1000");
1831  return SQL_ERROR;
1832 }
1833 
1841 #if defined(HAVE_LOCALECONV) || defined(_WIN32) || defined(_WIN64)
1842 
1843 static double
1844 ln_strtod(const char *data, char **endp)
1845 {
1846  struct lconv *lc = 0;
1847  char buf[128], *p, *end;
1848  double value;
1849 
1850  lc = localeconv();
1851  if (lc && lc->decimal_point && lc->decimal_point[0] &&
1852  lc->decimal_point[0] != '.') {
1853  strncpy(buf, data, sizeof (buf) - 1);
1854  buf[sizeof (buf) - 1] = '\0';
1855  p = strchr(buf, '.');
1856  if (p) {
1857  *p = lc->decimal_point[0];
1858  }
1859  p = buf;
1860  } else {
1861  p = (char *) data;
1862  }
1863  value = strtod(p, &end);
1864  end = (char *) data + (end - p);
1865  if (endp) {
1866  *endp = end;
1867  }
1868  return value;
1869 }
1870 
1871 #else
1872 
1873 #define ln_strtod(A,B) strtod(A,B)
1874 
1875 #endif
1876 
1882 static char *
1883 unquote(char *str)
1884 {
1885  if (str) {
1886  int len = strlen(str);
1887 
1888  if (len > 1) {
1889  int end = len - 1;
1890 
1891  if ((str[0] == '\'' && str[end] == '\'') ||
1892  (str[0] == '"' && str[end] == '"') ||
1893  (str[0] == '[' && str[end] == ']')) {
1894  memmove(str, str + 1, end - 1);
1895  str[end - 1] = '\0';
1896  }
1897  }
1898  }
1899  return str;
1900 }
1901 
1909 static int
1910 unescpat(char *str)
1911 {
1912  char *p, *q;
1913  int count = 0;
1914 
1915  p = str;
1916  while ((q = strchr(p, '_')) != NULL) {
1917  if (q == str || q[-1] != '\\') {
1918  count++;
1919  }
1920  p = q + 1;
1921  }
1922  p = str;
1923  while ((q = strchr(p, '%')) != NULL) {
1924  if (q == str || q[-1] != '\\') {
1925  count++;
1926  }
1927  p = q + 1;
1928  }
1929  p = str;
1930  while ((q = strchr(p, '\\')) != NULL) {
1931  if (q[1] == '\\' || q[1] == '_' || q[1] == '%') {
1932  memmove(q, q + 1, strlen(q));
1933  }
1934  p = q + 1;
1935  }
1936  return count;
1937 }
1938 
1947 static int
1948 namematch(char *str, char *pat, int esc)
1949 {
1950  int cp, ch;
1951 
1952  while (1) {
1953  cp = TOLOWER(*pat);
1954  if (cp == '\0') {
1955  if (*str != '\0') {
1956  goto nomatch;
1957  }
1958  break;
1959  }
1960  if (*str == '\0' && cp != '%') {
1961  goto nomatch;
1962  }
1963  if (cp == '%') {
1964  while (*pat == '%') {
1965  ++pat;
1966  }
1967  cp = TOLOWER(*pat);
1968  if (cp == '\0') {
1969  break;
1970  }
1971  while (1) {
1972  if (cp != '_' && cp != '\\') {
1973  while (*str) {
1974  ch = TOLOWER(*str);
1975  if (ch == cp) {
1976  break;
1977  }
1978  ++str;
1979  }
1980  }
1981  if (namematch(str, pat, esc)) {
1982  goto match;
1983  }
1984  if (*str == '\0') {
1985  goto nomatch;
1986  }
1987  ch = TOLOWER(*str);
1988  ++str;
1989  }
1990  }
1991  if (cp == '_') {
1992  pat++;
1993  str++;
1994  continue;
1995  }
1996  if (esc && cp == '\\' &&
1997  (pat[1] == '\\' || pat[1] == '%' || pat[1] == '_')) {
1998  ++pat;
1999  cp = TOLOWER(*pat);
2000  }
2001  ch = TOLOWER(*str++);
2002  ++pat;
2003  if (ch != cp) {
2004  goto nomatch;
2005  }
2006  }
2007 match:
2008  return 1;
2009 nomatch:
2010  return 0;
2011 }
2012 
2020 static int
2021 busy_handler(void *udata, int count)
2022 {
2023  DBC *d = (DBC *) udata;
2024  long t1;
2025  int ret = 0;
2026 #if !defined(_WIN32) && !defined(_WIN64)
2027  struct timeval tv;
2028 #ifdef HAVE_NANOSLEEP
2029  struct timespec ts;
2030 #endif
2031 #endif
2032 
2033  if (d->busyint) {
2034  d->busyint = 0;
2035  return ret;
2036  }
2037  if (d->timeout <= 0) {
2038  return ret;
2039  }
2040  if (count <= 1) {
2041 #if defined(_WIN32) || defined(_WIN64)
2042  d->t0 = GetTickCount();
2043 #else
2044  gettimeofday(&tv, NULL);
2045  d->t0 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
2046 #endif
2047  }
2048 #if defined(_WIN32) || defined(_WIN64)
2049  t1 = GetTickCount();
2050 #else
2051  gettimeofday(&tv, NULL);
2052  t1 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
2053 #endif
2054  if (t1 - d->t0 > d->timeout) {
2055  goto done;
2056  }
2057 #if defined(_WIN32) || defined(_WIN64)
2058  Sleep(10);
2059 #else
2060 #ifdef HAVE_NANOSLEEP
2061  ts.tv_sec = 0;
2062  ts.tv_nsec = 10000000;
2063  do {
2064  ret = nanosleep(&ts, &ts);
2065  if (ret < 0 && errno != EINTR) {
2066  ret = 0;
2067  }
2068  } while (ret);
2069 #else
2070 #ifdef HAVE_USLEEP
2071  usleep(10000);
2072 #else
2073  tv.tv_sec = 0;
2074  tv.tv_usec = 10000;
2075  select(0, NULL, NULL, NULL, &tv);
2076 #endif
2077 #endif
2078 #endif
2079  ret = 1;
2080 done:
2081  return ret;
2082 }
2083 
2095 static int
2096 setsqliteopts(sqlite3 *x, DBC *d)
2097 {
2098  int count = 0, step = 0, max, rc = SQLITE_ERROR;
2099 
2100 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
2101  max = d->longnames ? 3 : 1;
2102 #else
2103  max = 3;
2104 #endif
2105  if (d->shortnames) {
2106  max = 3;
2107  }
2108  while (step < max) {
2109  if (step < 1) {
2110  rc = sqlite3_exec(x, "PRAGMA empty_result_callbacks = on;",
2111  NULL, NULL, NULL);
2112  if (rc == SQLITE_OK) {
2113  rc = sqlite3_exec(x, d->fksupport ?
2114  "PRAGMA foreign_keys = on;" :
2115  "PRAGMA foreign_keys = off;",
2116  NULL, NULL, NULL);
2117  }
2118  } else if (step < 2) {
2119  rc = sqlite3_exec(x, d->shortnames ?
2120  "PRAGMA full_column_names = off;" :
2121  "PRAGMA full_column_names = on;",
2122  NULL, NULL, NULL);
2123  } else if (step < 3) {
2124  rc = sqlite3_exec(x, d->shortnames ?
2125  "PRAGMA short_column_names = on;" :
2126  "PRAGMA short_column_names = off;",
2127  NULL, NULL, NULL);
2128  }
2129  if (rc != SQLITE_OK) {
2130  if (rc != SQLITE_BUSY ||
2131  !busy_handler((void *) d, ++count)) {
2132  return rc;
2133  }
2134  continue;
2135  }
2136  count = 0;
2137  ++step;
2138  }
2139  sqlite3_busy_handler(x, busy_handler, (void *) d);
2140  return SQLITE_OK;
2141 }
2142 
2152 static void
2153 freerows(char **rowp)
2154 {
2155  PTRDIFF_T size, i;
2156 
2157  if (!rowp) {
2158  return;
2159  }
2160  --rowp;
2161  size = (PTRDIFF_T) rowp[0];
2162  for (i = 1; i <= size; i++) {
2163  freep(&rowp[i]);
2164  }
2165  freep(&rowp);
2166 }
2167 
2178 static int
2179 mapsqltype(const char *typename, int *nosign, int ov3, int nowchar,
2180  int dobigint)
2181 {
2182  char *p, *q;
2183  int testsign = 0, result;
2184 
2185 #ifdef WINTERFACE
2186  result = nowchar ? SQL_VARCHAR : SQL_WVARCHAR;
2187 #else
2188  result = SQL_VARCHAR;
2189 #endif
2190  if (!typename) {
2191  return result;
2192  }
2193  q = p = xmalloc(strlen(typename) + 1);
2194  if (!p) {
2195  return result;
2196  }
2197  strcpy(p, typename);
2198  while (*q) {
2199  *q = TOLOWER(*q);
2200  ++q;
2201  }
2202  if (strncmp(p, "inter", 5) == 0) {
2203  } else if (strncmp(p, "int", 3) == 0 ||
2204  strncmp(p, "mediumint", 9) == 0) {
2205  testsign = 1;
2206  result = SQL_INTEGER;
2207  } else if (strncmp(p, "numeric", 7) == 0) {
2208  result = SQL_DOUBLE;
2209  } else if (strncmp(p, "tinyint", 7) == 0) {
2210  testsign = 1;
2211  result = SQL_TINYINT;
2212  } else if (strncmp(p, "smallint", 8) == 0) {
2213  testsign = 1;
2214  result = SQL_SMALLINT;
2215  } else if (strncmp(p, "float", 5) == 0) {
2216  result = SQL_DOUBLE;
2217  } else if (strncmp(p, "double", 6) == 0 ||
2218  strncmp(p, "real", 4) == 0) {
2219  result = SQL_DOUBLE;
2220  } else if (strncmp(p, "timestamp", 9) == 0) {
2221 #ifdef SQL_TYPE_TIMESTAMP
2222  result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
2223 #else
2224  result = SQL_TIMESTAMP;
2225 #endif
2226  } else if (strncmp(p, "datetime", 8) == 0) {
2227 #ifdef SQL_TYPE_TIMESTAMP
2228  result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
2229 #else
2230  result = SQL_TIMESTAMP;
2231 #endif
2232  } else if (strncmp(p, "time", 4) == 0) {
2233 #ifdef SQL_TYPE_TIME
2234  result = ov3 ? SQL_TYPE_TIME : SQL_TIME;
2235 #else
2236  result = SQL_TIME;
2237 #endif
2238  } else if (strncmp(p, "date", 4) == 0) {
2239 #ifdef SQL_TYPE_DATE
2240  result = ov3 ? SQL_TYPE_DATE : SQL_DATE;
2241 #else
2242  result = SQL_DATE;
2243 #endif
2244 #ifdef SQL_LONGVARCHAR
2245  } else if (strncmp(p, "text", 4) == 0 ||
2246  strncmp(p, "memo", 4) == 0 ||
2247  strncmp(p, "longvarchar", 11) == 0) {
2248 #ifdef WINTERFACE
2249  result = nowchar ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
2250 #else
2251  result = SQL_LONGVARCHAR;
2252 #endif
2253 #ifdef WINTERFACE
2254  } else if (strncmp(p, "wtext", 5) == 0 ||
2255  strncmp(p, "wvarchar", 8) == 0 ||
2256  strncmp(p, "longwvarchar", 12) == 0) {
2257  result = SQL_WLONGVARCHAR;
2258 #endif
2259 #endif
2260 #ifdef SQL_BIT
2261  } else if (strncmp(p, "bool", 4) == 0 ||
2262  strncmp(p, "bit", 3) == 0) {
2263  result = SQL_BIT;
2264 #endif
2265 #ifdef SQL_BIGINT
2266  } else if (strncmp(p, "bigint", 6) == 0) {
2267  testsign = 1;
2268  result = SQL_BIGINT;
2269 #endif
2270  } else if (strncmp(p, "blob", 4) == 0) {
2271  result = SQL_BINARY;
2272  } else if (strncmp(p, "varbinary", 9) == 0) {
2273  result = SQL_VARBINARY;
2274  } else if (strncmp(p, "longvarbinary", 13) == 0) {
2275  result = SQL_LONGVARBINARY;
2276  }
2277  if (nosign) {
2278  if (testsign) {
2279  *nosign = strstr(p, "unsigned") != NULL;
2280  } else {
2281  *nosign = 1;
2282  }
2283  }
2284 #ifdef SQL_BIGINT
2285  if (dobigint && result == SQL_INTEGER) {
2286  result = SQL_BIGINT;
2287  }
2288 #endif
2289  xfree(p);
2290  return result;
2291 }
2292 
2302 static void
2303 getmd(const char *typename, int sqltype, int *mp, int *dp)
2304 {
2305  int m = 0, d = 0;
2306 
2307  switch (sqltype) {
2308  case SQL_INTEGER: m = 10; d = 9; break;
2309  case SQL_TINYINT: m = 4; d = 3; break;
2310  case SQL_SMALLINT: m = 6; d = 5; break;
2311  case SQL_FLOAT: m = 25; d = 24; break;
2312  case SQL_DOUBLE: m = 54; d = 53; break;
2313  case SQL_VARCHAR: m = 255; d = 0; break;
2314 #ifdef WINTERFACE
2315 #ifdef SQL_WVARCHAR
2316  case SQL_WVARCHAR: m = 255; d = 0; break;
2317 #endif
2318 #endif
2319 #ifdef SQL_TYPE_DATE
2320  case SQL_TYPE_DATE:
2321 #endif
2322  case SQL_DATE: m = 10; d = 0; break;
2323 #ifdef SQL_TYPE_TIME
2324  case SQL_TYPE_TIME:
2325 #endif
2326  case SQL_TIME: m = 8; d = 0; break;
2327 #ifdef SQL_TYPE_TIMESTAMP
2328  case SQL_TYPE_TIMESTAMP:
2329 #endif
2330  case SQL_TIMESTAMP: m = 32; d = 3; break;
2331 #ifdef SQL_LONGVARCHAR
2332  case SQL_LONGVARCHAR : m = 65536; d = 0; break;
2333 #endif
2334 #ifdef WINTERFACE
2335 #ifdef SQL_WLONGVARCHAR
2336  case SQL_WLONGVARCHAR: m = 65536; d = 0; break;
2337 #endif
2338 #endif
2339  case SQL_BINARY:
2340  case SQL_VARBINARY: m = 255; d = 0; break;
2341  case SQL_LONGVARBINARY: m = 65536; d = 0; break;
2342 #ifdef SQL_BIGINT
2343  case SQL_BIGINT: m = 20; d = 19; break;
2344 #endif
2345 #ifdef SQL_BIT
2346  case SQL_BIT: m = 1; d = 1; break;
2347 #endif
2348  }
2349  if (m && typename) {
2350  int mm, dd;
2351  char clbr[4];
2352 
2353  if (sscanf(typename, "%*[^(](%d,%d %1[)]", &mm, &dd, clbr) == 3) {
2354  m = mm;
2355  d = dd;
2356  } else if (sscanf(typename, "%*[^(](%d %1[)]", &mm, clbr) == 2) {
2357  if (sqltype == SQL_TIMESTAMP) {
2358  d = mm;
2359  }
2360 #ifdef SQL_TYPE_TIMESTAMP
2361  else if (sqltype == SQL_TYPE_TIMESTAMP) {
2362  d = mm;
2363  }
2364 #endif
2365  else {
2366  m = d = mm;
2367  }
2368  }
2369  }
2370  if (mp) {
2371  *mp = m;
2372  }
2373  if (dp) {
2374  *dp = d;
2375  }
2376 }
2377 
2387 static int
2388 mapdeftype(int type, int stype, int nosign, int nowchar)
2389 {
2390  if (type == SQL_C_DEFAULT) {
2391  switch (stype) {
2392  case SQL_INTEGER:
2393  type = (nosign > 0) ? SQL_C_ULONG : SQL_C_LONG;
2394  break;
2395  case SQL_TINYINT:
2396  type = (nosign > 0) ? SQL_C_UTINYINT : SQL_C_TINYINT;
2397  break;
2398  case SQL_SMALLINT:
2399  type = (nosign > 0) ? SQL_C_USHORT : SQL_C_SHORT;
2400  break;
2401  case SQL_FLOAT:
2402  type = SQL_C_FLOAT;
2403  break;
2404  case SQL_DOUBLE:
2405  type = SQL_C_DOUBLE;
2406  break;
2407  case SQL_TIMESTAMP:
2408  type = SQL_C_TIMESTAMP;
2409  break;
2410  case SQL_TIME:
2411  type = SQL_C_TIME;
2412  break;
2413  case SQL_DATE:
2414  type = SQL_C_DATE;
2415  break;
2416 #ifdef SQL_C_TYPE_TIMESTAMP
2417  case SQL_TYPE_TIMESTAMP:
2418  type = SQL_C_TYPE_TIMESTAMP;
2419  break;
2420 #endif
2421 #ifdef SQL_C_TYPE_TIME
2422  case SQL_TYPE_TIME:
2423  type = SQL_C_TYPE_TIME;
2424  break;
2425 #endif
2426 #ifdef SQL_C_TYPE_DATE
2427  case SQL_TYPE_DATE:
2428  type = SQL_C_TYPE_DATE;
2429  break;
2430 #endif
2431 #ifdef WINTERFACE
2432  case SQL_WVARCHAR:
2433  case SQL_WCHAR:
2434 #ifdef SQL_WLONGVARCHAR
2435  case SQL_WLONGVARCHAR:
2436 #endif
2437  type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
2438  break;
2439 #endif
2440  case SQL_BINARY:
2441  case SQL_VARBINARY:
2442  case SQL_LONGVARBINARY:
2443  type = SQL_C_BINARY;
2444  break;
2445 #ifdef SQL_BIT
2446  case SQL_BIT:
2447  type = SQL_C_BIT;
2448  break;
2449 #endif
2450 #ifdef SQL_BIGINT
2451  case SQL_BIGINT:
2452  type = SQL_C_CHAR;
2453  break;
2454 #endif
2455  default:
2456 #ifdef WINTERFACE
2457  type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
2458 #else
2459  type = SQL_C_CHAR;
2460 #endif
2461  break;
2462  }
2463  }
2464  return type;
2465 }
2466 
2473 static int
2474 checkddl(char *sql)
2475 {
2476  int isddl = 0;
2477 
2478  while (*sql && ISSPACE(*sql)) {
2479  ++sql;
2480  }
2481  if (*sql && *sql != ';') {
2482  int i, size;
2483  static const struct {
2484  int len;
2485  const char *str;
2486  } ddlstr[] = {
2487  { 5, "alter" },
2488  { 7, "analyze" },
2489  { 6, "attach" },
2490  { 5, "begin" },
2491  { 6, "commit" },
2492  { 6, "create" },
2493  { 6, "detach" },
2494  { 4, "drop" },
2495  { 3, "end" },
2496  { 7, "reindex" },
2497  { 7, "release" },
2498  { 8, "rollback" },
2499  { 9, "savepoint" },
2500  { 6, "vacuum" }
2501  };
2502 
2503  size = strlen(sql);
2504  for (i = 0; i < array_size(ddlstr); i++) {
2505  if (size >= ddlstr[i].len &&
2506  strncasecmp(sql, ddlstr[i].str, ddlstr[i].len) == 0) {
2507  isddl = 1;
2508  break;
2509  }
2510  }
2511  }
2512  return isddl;
2513 }
2514 
2526 static char *
2527 fixupsql(char *sql, int sqlLen, int cte, int *nparam, int *isselect,
2528  char **errmsg)
2529 {
2530  char *q = sql, *qz = NULL, *p, *inq = NULL, *out;
2531  int np = 0, isddl = -1, size;
2532 
2533  if (errmsg) {
2534  *errmsg = NULL;
2535  }
2536  if (sqlLen != SQL_NTS) {
2537  qz = q = xmalloc(sqlLen + 1);
2538  if (!qz) {
2539  return NULL;
2540  }
2541  memcpy(q, sql, sqlLen);
2542  q[sqlLen] = '\0';
2543  size = sqlLen * 4;
2544  } else {
2545  size = strlen(sql) * 4;
2546  }
2547  size += sizeof (char *) - 1;
2548  size &= ~(sizeof (char *) - 1);
2549  p = xmalloc(size);
2550  if (!p) {
2551 errout:
2552  freep(&qz);
2553  return NULL;
2554  }
2555  memset(p, 0, size);
2556  out = p;
2557  while (*q) {
2558  switch (*q) {
2559  case '\'':
2560  case '\"':
2561  if (q == inq) {
2562  inq = NULL;
2563  } else if (!inq) {
2564  inq = q + 1;
2565 
2566  while (*inq) {
2567  if (*inq == *q) {
2568  if (inq[1] == *q) {
2569  inq++;
2570  } else {
2571  break;
2572  }
2573  }
2574  inq++;
2575  }
2576  }
2577  *p++ = *q;
2578  break;
2579  case '-':
2580  *p++ = *q;
2581  if (!inq && q[1] == '-') {
2582  ++q;
2583  while (*q) {
2584  *p++ = *q++;
2585  if (*q == '\n') {
2586  break;
2587  }
2588  }
2589  }
2590  break;
2591  case '?':
2592  *p++ = *q;
2593  if (!inq) {
2594  np++;
2595  }
2596  break;
2597  case ';':
2598  if (!inq) {
2599  if (isddl < 0) {
2600  isddl = checkddl(out);
2601  }
2602  if (isddl == 0) {
2603  char *qq = q;
2604 
2605  do {
2606  ++qq;
2607  } while (*qq && ISSPACE(*qq));
2608  if (*qq && *qq != ';') {
2609  freep(&out);
2610  if (errmsg) {
2611  *errmsg = "only one SQL statement allowed";
2612  }
2613  goto errout;
2614  }
2615  }
2616  }
2617  *p++ = *q;
2618  break;
2619  case '{':
2620  /*
2621  * Deal with escape sequences:
2622  * {d 'YYYY-MM-DD'}, {t ...}, {ts ...}
2623  * {oj ...}, {fn ...} etc.
2624  */
2625  if (!inq) {
2626  int ojfn = 0, brc = 0;
2627  char *inq2 = NULL, *end = q + 1, *start;
2628 
2629  while (*end && ISSPACE(*end)) {
2630  ++end;
2631  }
2632  if (*end != 'd' && *end != 'D' &&
2633  *end != 't' && *end != 'T') {
2634  ojfn = 1;
2635  }
2636  start = end;
2637  while (*end) {
2638  if (inq2 && *end == *inq2) {
2639  inq2 = NULL;
2640  } else if (inq2 == NULL && *end == '{') {
2641  char *nerr = 0, *nsql;
2642 
2643  nsql = fixupsql(end, SQL_NTS, cte, 0, 0, &nerr);
2644  if (nsql && !nerr) {
2645  strcpy(end, nsql);
2646  } else {
2647  brc++;
2648  }
2649  freep(&nsql);
2650  } else if (inq2 == NULL && *end == '}') {
2651  if (brc-- <= 0) {
2652  break;
2653  }
2654  } else if (inq2 == NULL && (*end == '\'' || *end == '"')) {
2655  inq2 = end;
2656  } else if (inq2 == NULL && *end == '?') {
2657  np++;
2658  }
2659  ++end;
2660  }
2661  if (*end == '}') {
2662  char *end2 = end - 1;
2663 
2664  if (ojfn) {
2665  while (start < end) {
2666  if (ISSPACE(*start)) {
2667  break;
2668  }
2669  ++start;
2670  }
2671  while (start < end) {
2672  *p++ = *start;
2673  ++start;
2674  }
2675  q = end;
2676  break;
2677  } else {
2678  while (start < end2 && *start != '\'') {
2679  ++start;
2680  }
2681  while (end2 > start && *end2 != '\'') {
2682  --end2;
2683  }
2684  if (*start == '\'' && *end2 == '\'') {
2685  while (start <= end2) {
2686  *p++ = *start;
2687  ++start;
2688  }
2689  q = end;
2690  break;
2691  }
2692  }
2693  }
2694  }
2695  /* FALL THROUGH */
2696  default:
2697  *p++ = *q;
2698  }
2699  ++q;
2700  }
2701  freep(&qz);
2702  *p = '\0';
2703  if (nparam) {
2704  *nparam = np;
2705  }
2706  if (isselect) {
2707  if (isddl < 0) {
2708  isddl = checkddl(out);
2709  }
2710  if (isddl > 0) {
2711  *isselect = 2;
2712  } else {
2713  int incom = 0;
2714 
2715  p = out;
2716  while (*p) {
2717  switch (*p) {
2718  case '-':
2719  if (!incom && p[1] == '-') {
2720  incom = -1;
2721  }
2722  break;
2723  case '\n':
2724  if (incom < 0) {
2725  incom = 0;
2726  }
2727  break;
2728  case '/':
2729  if (incom > 0 && p[-1] == '*') {
2730  incom = 0;
2731  p++;
2732  continue;
2733  } else if (!incom && p[1] == '*') {
2734  incom = 1;
2735  }
2736  break;
2737  }
2738  if (!incom && !ISSPACE(*p)) {
2739  break;
2740  }
2741  p++;
2742  }
2743  size = strlen(p);
2744  if (size >= 6 &&
2745  (strncasecmp(p, "select", 6) == 0 ||
2746  strncasecmp(p, "pragma", 6) == 0)) {
2747  *isselect = 1;
2748  } else if (cte && size >= 4 && strncasecmp(p, "with", 4) == 0) {
2749  *isselect = 1;
2750  } else if (size >= 7 && strncasecmp(p, "explain", 7) == 0) {
2751  *isselect = 1;
2752  } else {
2753  *isselect = 0;
2754  }
2755  }
2756  }
2757  return out;
2758 }
2759 
2765 static void
2766 replilike(char *sql)
2767 {
2768  char *q = sql, *inq = NULL;
2769 
2770  while (*q) {
2771  switch (*q) {
2772  case '\'':
2773  case '\"':
2774  if (q == inq) {
2775  inq = NULL;
2776  } else if (!inq) {
2777  inq = q + 1;
2778 
2779  while (*inq) {
2780  if (*inq == *q) {
2781  if (inq[1] == *q) {
2782  inq++;
2783  } else {
2784  break;
2785  }
2786  }
2787  inq++;
2788  }
2789  }
2790  break;
2791  case '-':
2792  if (!inq && q[1] == '-') {
2793  ++q;
2794  while (*q) {
2795  if (*q == '\n') {
2796  break;
2797  }
2798  }
2799  }
2800  break;
2801  default:
2802  if (!inq && ISSPACE(*q) && q[1]) {
2803  if (strncasecmp(q + 1, "ilike", 5) == 0) {
2804  if ((q[2] != '\0') && (q[3] != '\0') &&
2805  (q[4] != '\0') && (q[5] != '\0') &&
2806  ((q[6] == '\0') || ISSPACE(q[6]))) {
2807  q++;
2808  memmove(q, q + 1, strlen(q));
2809  q += 3;
2810  }
2811  }
2812  }
2813  break;
2814  }
2815  ++q;
2816  }
2817 }
2818 
2827 static int
2828 findcol(char **cols, int ncols, char *name)
2829 {
2830  int i;
2831 
2832  if (cols) {
2833  for (i = 0; i < ncols; i++) {
2834  if (strcmp(cols[i], name) == 0) {
2835  return i;
2836  }
2837  }
2838  }
2839  return -1;
2840 }
2841 
2858 static void
2860 {
2861  int i, k;
2862 #ifndef FULL_METADATA
2863  int pk, nn, t, r, nrows, ncols;
2864  char **rowp, *flagp, flags[128];
2865 #endif
2866 
2867  if (!s->dyncols) {
2868  return;
2869  }
2870  /* fixup labels */
2871  if (!s->longnames) {
2872  if (s->dcols > 1) {
2873  char *table = s->dyncols[0].table;
2874 
2875  for (i = 1; table[0] && i < s->dcols; i++) {
2876  if (strcmp(s->dyncols[i].table, table)) {
2877  break;
2878  }
2879  }
2880  if (i >= s->dcols) {
2881  for (i = 0; i < s->dcols; i++) {
2882  s->dyncols[i].label = s->dyncols[i].column;
2883  }
2884  }
2885  } else if (s->dcols == 1) {
2886  s->dyncols[0].label = s->dyncols[0].column;
2887  }
2888  }
2889  for (i = 0; i < s->dcols; i++) {
2890  s->dyncols[i].type =
2891  mapsqltype(s->dyncols[i].typename, &s->dyncols[i].nosign, *s->ov3,
2892  s->nowchar[0] || s->nowchar[1], s->dobigint);
2893  getmd(s->dyncols[i].typename, s->dyncols[i].type,
2894  &s->dyncols[i].size, &s->dyncols[i].prec);
2895 #ifdef SQL_LONGVARCHAR
2896  if (s->dyncols[i].type == SQL_VARCHAR &&
2897  s->dyncols[i].size > 255) {
2898  s->dyncols[i].type = SQL_LONGVARCHAR;
2899  }
2900 #endif
2901 #ifdef WINTERFACE
2902 #ifdef SQL_WLONGVARCHAR
2903  if (s->dyncols[i].type == SQL_WVARCHAR &&
2904  s->dyncols[i].size > 255) {
2905  s->dyncols[i].type = SQL_WLONGVARCHAR;
2906  }
2907 #endif
2908 #endif
2909  if (s->dyncols[i].type == SQL_VARBINARY &&
2910  s->dyncols[i].size > 255) {
2911  s->dyncols[i].type = SQL_LONGVARBINARY;
2912  }
2913  }
2914 #ifndef FULL_METADATA
2915  if (s->dcols > array_size(flags)) {
2916  flagp = xmalloc(sizeof (flags[0]) * s->dcols);
2917  if (flagp == NULL) {
2918  return;
2919  }
2920  } else {
2921  flagp = flags;
2922  }
2923  memset(flagp, 0, sizeof (flags[0]) * s->dcols);
2924  for (i = 0; i < s->dcols; i++) {
2925  s->dyncols[i].autoinc = SQL_FALSE;
2926  s->dyncols[i].notnull = SQL_NULLABLE;
2927  }
2928  for (i = 0; i < s->dcols; i++) {
2929  int ret, lastpk = -1, autoinccount = 0;
2930  char *sql;
2931 
2932  if (!s->dyncols[i].table[0]) {
2933  continue;
2934  }
2935  if (flagp[i]) {
2936  continue;
2937  }
2938  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", s->dyncols[i].table);
2939  if (!sql) {
2940  continue;
2941  }
2942  dbtraceapi(d, "sqlite3_get_table", sql);
2943  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, NULL);
2944  sqlite3_free(sql);
2945  if (ret != SQLITE_OK) {
2946  continue;
2947  }
2948  k = findcol(rowp, ncols, "name");
2949  t = findcol(rowp, ncols, "type");
2950  pk = findcol(rowp, ncols, "pk");
2951  nn = findcol(rowp, ncols, "notnull");
2952  if (k < 0 || t < 0) {
2953  goto freet;
2954  }
2955  for (r = 1; r <= nrows; r++) {
2956  int m;
2957 
2958  for (m = i; m < s->dcols; m++) {
2959  char *colname = s->dyncols[m].column;
2960 
2961  if (s->longnames) {
2962  char *dotp = strchr(colname, '.');
2963 
2964  if (dotp) {
2965  colname = dotp + 1;
2966  }
2967  }
2968  if (!flagp[m] &&
2969  strcmp(colname, rowp[r * ncols + k]) == 0 &&
2970  strcmp(s->dyncols[m].table, s->dyncols[i].table) == 0) {
2971  char *typename = rowp[r * ncols + t];
2972 
2973  flagp[m] = i + 1;
2974  freep(&s->dyncols[m].typename);
2975  s->dyncols[m].typename = xstrdup(typename);
2976  s->dyncols[m].type =
2977  mapsqltype(typename, &s->dyncols[m].nosign, *s->ov3,
2978  s->nowchar[0] || s->nowchar[1],
2979  s->dobigint);
2980  getmd(typename, s->dyncols[m].type, &s->dyncols[m].size,
2981  &s->dyncols[m].prec);
2982 #ifdef SQL_LONGVARCHAR
2983  if (s->dyncols[m].type == SQL_VARCHAR &&
2984  s->dyncols[m].size > 255) {
2985  s->dyncols[m].type = SQL_LONGVARCHAR;
2986  }
2987 #endif
2988 #ifdef WINTERFACE
2989 #ifdef SQL_WLONGVARCHAR
2990  if (s->dyncols[i].type == SQL_WVARCHAR &&
2991  s->dyncols[i].size > 255) {
2992  s->dyncols[i].type = SQL_WLONGVARCHAR;
2993  }
2994 #endif
2995 #endif
2996  if (s->dyncols[i].type == SQL_VARBINARY &&
2997  s->dyncols[i].size > 255) {
2998  s->dyncols[i].type = SQL_LONGVARBINARY;
2999  }
3000  if (pk >= 0 && strcmp(rowp[r * ncols + pk], "1") == 0) {
3001  s->dyncols[m].ispk = 1;
3002  if (++autoinccount > 1) {
3003  if (lastpk >= 0) {
3004  s->dyncols[lastpk].autoinc = SQL_FALSE;
3005  lastpk = -1;
3006  }
3007  } else {
3008  lastpk = m;
3009  if (strlen(typename) == 7 &&
3010  strncasecmp(typename, "integer", 7) == 0) {
3011  s->dyncols[m].autoinc = SQL_TRUE;
3012  }
3013  }
3014  } else {
3015  s->dyncols[m].ispk = 0;
3016  }
3017  if (nn >= 0 && rowp[r * ncols + nn][0] != '0') {
3018  s->dyncols[m].notnull = SQL_NO_NULLS;
3019  }
3020  }
3021  }
3022  }
3023 freet:
3024  sqlite3_free_table(rowp);
3025  }
3026  for (i = k = 0; i < s->dcols; i++) {
3027  if (flagp[i] == 0) {
3028  break;
3029  }
3030  if (k == 0) {
3031  k = flagp[i];
3032  } else if (flagp[i] != k) {
3033  k = 0;
3034  break;
3035  }
3036  }
3037  s->one_tbl = k ? 1 : 0;
3038  k = 0;
3039  if (s->one_tbl) {
3040  for (i = 0; i < s->dcols; i++) {
3041  if (s->dyncols[i].ispk > 0) {
3042  ++k;
3043  }
3044  }
3045  }
3046  s->has_pk = k;
3047  if (flagp != flags) {
3048  freep(&flagp);
3049  }
3050 #else
3051  for (i = 1, k = 0; i < s->dcols; i++) {
3052  if (strcmp(s->dyncols[i].table, s->dyncols[0].table) == 0) {
3053  k++;
3054  }
3055  }
3056  s->one_tbl = (k && k + 1 == s->dcols) ? 1 : 0;
3057  k = 0;
3058  if (s->one_tbl) {
3059  for (i = 0; i < s->dcols; i++) {
3060  if (s->dyncols[i].ispk > 0) {
3061  ++k;
3062  if (s->has_rowid < 0 && s->dyncols[i].isrowid > 0) {
3063  s->has_rowid = i;
3064  }
3065  }
3066  }
3067  }
3068  s->has_pk = k;
3069 #endif
3070 }
3071 
3078 static void
3079 convJD2YMD(double jd, DATE_STRUCT *ds)
3080 {
3081  int z, a, b, c, d, e, x1;
3082  sqlite_int64 ijd;
3083 
3084  ijd = jd * 86400000.0 + 0.5;
3085  z = (int) ((ijd + 43200000) / 86400000);
3086  a = (int) ((z - 1867216.25) / 36524.25);
3087  a = z + 1 + a - (a / 4);
3088  b = a + 1524;
3089  c = (int) ((b - 122.1) / 365.25);
3090  d = (36525 * c) / 100;
3091  e = (int) ((b - d) / 30.6001);
3092  x1 = (int) (30.6001 * e);
3093  ds->day = b - d - x1;
3094  ds->month = (e < 14) ? (e - 1) : (e - 13);
3095  ds->year = (ds->month > 2) ? (c - 4716) : (c - 4715);
3096 }
3097 
3098 
3106 static void
3107 convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
3108 {
3109  int s;
3110  double ds;
3111  sqlite_int64 ijd;
3112 
3113  ijd = jd * 86400000.0 + 0.5;
3114  s = (int)((ijd + 43200000) % 86400000);
3115  ds = s / 1000.0;
3116  if (fp) {
3117  *fp = (s % 1000) * 1000000;
3118  }
3119  s = (int) ds;
3120  ds -= s;
3121  ts->hour = s / 3600;
3122  s -= ts->hour * 3600;
3123  ts->minute = s / 60;
3124  ds += s - ts->minute *60;
3125  ts->second = (int) ds;
3126 }
3127 
3135 static int
3136 getmdays(int year, int month)
3137 {
3138  static const int mdays[] = {
3139  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
3140  };
3141  int mday;
3142 
3143  if (month < 1) {
3144  return 0;
3145  }
3146  mday = mdays[(month - 1) % 12];
3147  if (mday == 28 && year % 4 == 0 &&
3148  (!(year % 100 == 0) || year % 400 == 0)) {
3149  mday++;
3150  }
3151  return mday;
3152 }
3153 
3169 static int
3170 str2date(int jdconv, char *str, DATE_STRUCT *ds)
3171 {
3172  int i, err = 0;
3173  double jd;
3174  char *p, *q, sepc = '\0';
3175 
3176  ds->year = ds->month = ds->day = 0;
3177  if (jdconv) {
3178  p = strchr(str, '.');
3179  if (p) {
3180  /* julian day format */
3181  p = 0;
3182  jd = ln_strtod(str, &p);
3183  if (p && p > str) {
3184  convJD2YMD(jd, ds);
3185  return 0;
3186  }
3187  }
3188  }
3189  p = str;
3190  while (*p && !ISDIGIT(*p)) {
3191  ++p;
3192  }
3193  q = p;
3194  i = 0;
3195  while (*q && !ISDIGIT(*q)) {
3196  ++i;
3197  ++q;
3198  }
3199  if (i >= 8) {
3200  char buf[8];
3201 
3202  strncpy(buf, p + 0, 4); buf[4] = '\0';
3203  ds->year = strtol(buf, NULL, 10);
3204  strncpy(buf, p + 4, 2); buf[2] = '\0';
3205  ds->month = strtol(buf, NULL, 10);
3206  strncpy(buf, p + 6, 2); buf[2] = '\0';
3207  ds->day = strtol(buf, NULL, 10);
3208  goto done;
3209  }
3210  i = 0;
3211  while (i < 3) {
3212  int n;
3213 
3214  q = NULL;
3215  n = strtol(p, &q, 10);
3216  if (!q || q == p) {
3217  if (*q == '\0') {
3218  if (i == 0) {
3219  err = 1;
3220  }
3221  goto done;
3222  }
3223  }
3224  if (!sepc) {
3225  sepc = *q;
3226  }
3227  if (*q == '-' || *q == '/' || *q == '\0' || i == 2) {
3228  switch (i) {
3229  case 0: ds->year = n; break;
3230  case 1: ds->month = n; break;
3231  case 2: ds->day = n; break;
3232  }
3233  ++i;
3234  if (*q) {
3235  ++q;
3236  }
3237  } else {
3238  i = 0;
3239  while (*q && !ISDIGIT(*q)) {
3240  ++q;
3241  }
3242  }
3243  p = q;
3244  }
3245 done:
3246  /* final check for overflow */
3247  if (err ||
3248  ds->month < 1 || ds->month > 12 ||
3249  ds->day < 1 || ds->day > getmdays(ds->year, ds->month)) {
3250  if (sepc == '/') {
3251  /* Try MM/DD/YYYY format */
3252  int t[3];
3253 
3254  t[0] = ds->year;
3255  t[1] = ds->month;
3256  t[2] = ds->day;
3257  ds->year = t[2];
3258  ds->day = t[1];
3259  ds->month = t[0];
3260  if (ds->month >= 1 && ds->month <= 12 &&
3261  (ds->day >= 1 || ds->day <= getmdays(ds->year, ds->month))) {
3262  return 0;
3263  }
3264  }
3265  return -1;
3266  }
3267  return 0;
3268 }
3269 
3284 static int
3285 str2time(int jdconv, char *str, TIME_STRUCT *ts)
3286 {
3287  int i, err = 0, ampm = -1;
3288  double jd;
3289  char *p, *q;
3290 
3291  ts->hour = ts->minute = ts->second = 0;
3292  if (jdconv) {
3293  p = strchr(str, '.');
3294  if (p) {
3295  /* julian day format */
3296  p = 0;
3297  jd = ln_strtod(str, &p);
3298  if (p && p > str) {
3299  convJD2HMS(jd, ts, 0);
3300  return 0;
3301  }
3302  }
3303  }
3304  p = str;
3305  while (*p && !ISDIGIT(*p)) {
3306  ++p;
3307  }
3308  q = p;
3309  i = 0;
3310  while (*q && ISDIGIT(*q)) {
3311  ++i;
3312  ++q;
3313  }
3314  if (i >= 6) {
3315  char buf[4];
3316 
3317  strncpy(buf, p + 0, 2); buf[2] = '\0';
3318  ts->hour = strtol(buf, NULL, 10);
3319  strncpy(buf, p + 2, 2); buf[2] = '\0';
3320  ts->minute = strtol(buf, NULL, 10);
3321  strncpy(buf, p + 4, 2); buf[2] = '\0';
3322  ts->second = strtol(buf, NULL, 10);
3323  goto done;
3324  }
3325  i = 0;
3326  while (i < 3) {
3327  int n;
3328 
3329  q = NULL;
3330  n = strtol(p, &q, 10);
3331  if (!q || q == p) {
3332  if (*q == '\0') {
3333  if (i == 0) {
3334  err = 1;
3335  }
3336  goto done;
3337  }
3338  }
3339  if (*q == ':' || *q == '\0' || i == 2) {
3340  switch (i) {
3341  case 0: ts->hour = n; break;
3342  case 1: ts->minute = n; break;
3343  case 2: ts->second = n; break;
3344  }
3345  ++i;
3346  if (*q) {
3347  ++q;
3348  }
3349  } else {
3350  i = 0;
3351  while (*q && !ISDIGIT(*q)) {
3352  ++q;
3353  }
3354  }
3355  p = q;
3356  }
3357  if (!err) {
3358  while (*p) {
3359  if ((p[0] == 'p' || p[0] == 'P') &&
3360  (p[1] == 'm' || p[1] == 'M')) {
3361  ampm = 1;
3362  } else if ((p[0] == 'a' || p[0] == 'A') &&
3363  (p[1] == 'm' || p[1] == 'M')) {
3364  ampm = 0;
3365  }
3366  ++p;
3367  }
3368  if (ampm > 0) {
3369  if (ts->hour < 12) {
3370  ts->hour += 12;
3371  }
3372  } else if (ampm == 0) {
3373  if (ts->hour == 12) {
3374  ts->hour = 0;
3375  }
3376  }
3377  }
3378 done:
3379  /* final check for overflow */
3380  if (err || ts->hour > 23 || ts->minute > 59 || ts->second > 59) {
3381  return -1;
3382  }
3383  return 0;
3384 }
3385 
3405 static int
3406 str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
3407 {
3408  int i, m, n, err = 0, ampm = -1;
3409  double jd;
3410  char *p, *q, in = '\0', sepc = '\0';
3411 
3412  tss->year = tss->month = tss->day = 0;
3413  tss->hour = tss->minute = tss->second = 0;
3414  tss->fraction = 0;
3415  if (jdconv) {
3416  p = strchr(str, '.');
3417  if (p) {
3418  q = strchr(str, '-');
3419  if (q == str) {
3420  q = 0;
3421  }
3422  if (!q) {
3423  q = strchr(str, '/');
3424  if (!q) {
3425  q = strchr(str, ':');
3426  }
3427  }
3428  if (!q || q > p) {
3429  /* julian day format */
3430  p = 0;
3431  jd = ln_strtod(str, &p);
3432  if (p && p > str) {
3433  DATE_STRUCT ds;
3434  TIME_STRUCT ts;
3435 
3436  convJD2YMD(jd, &ds);
3437  convJD2HMS(jd, &ts, &n);
3438  tss->year = ds.year;
3439  tss->month = ds.month;
3440  tss->day = ds.day;
3441  tss->hour = ts.hour;
3442  tss->minute = ts.minute;
3443  tss->second = ts.second;
3444  tss->fraction = n;
3445  return 0;
3446  }
3447  }
3448  }
3449  }
3450  p = str;
3451  while (*p && !ISDIGIT(*p)) {
3452  ++p;
3453  }
3454  q = p;
3455  i = 0;
3456  while (*q && ISDIGIT(*q)) {
3457  ++i;
3458  ++q;
3459  }
3460  if (i >= 14) {
3461  char buf[16];
3462 
3463  strncpy(buf, p + 0, 4); buf[4] = '\0';
3464  tss->year = strtol(buf, NULL, 10);
3465  strncpy(buf, p + 4, 2); buf[2] = '\0';
3466  tss->month = strtol(buf, NULL, 10);
3467  strncpy(buf, p + 6, 2); buf[2] = '\0';
3468  tss->day = strtol(buf, NULL, 10);
3469  strncpy(buf, p + 8, 2); buf[2] = '\0';
3470  tss->hour = strtol(buf, NULL, 10);
3471  strncpy(buf, p + 10, 2); buf[2] = '\0';
3472  tss->minute = strtol(buf, NULL, 10);
3473  strncpy(buf, p + 12, 2); buf[2] = '\0';
3474  tss->second = strtol(buf, NULL, 10);
3475  if (i > 14) {
3476  m = i - 14;
3477  strncpy(buf, p + 14, m);
3478  while (m < 9) {
3479  buf[m] = '0';
3480  ++m;
3481  }
3482  buf[m] = '\0';
3483  tss->fraction = strtol(buf, NULL, 10);
3484  }
3485  m = 7;
3486  goto done;
3487  }
3488  m = i = 0;
3489  while ((m & 7) != 7) {
3490  q = NULL;
3491  n = strtol(p, &q, 10);
3492  if (!q || q == p) {
3493  if (*q == '\0') {
3494  if (m < 1) {
3495  err = 1;
3496  }
3497  goto done;
3498  }
3499  }
3500  if (in == '\0') {
3501  switch (*q) {
3502  case '-':
3503  case '/':
3504  if ((m & 1) == 0) {
3505  in = *q;
3506  i = 0;
3507  }
3508  break;
3509  case ':':
3510  if ((m & 2) == 0) {
3511  in = *q;
3512  i = 0;
3513  }
3514  break;
3515  case ' ':
3516  case '.':
3517  break;
3518  default:
3519  in = '\0';
3520  i = 0;
3521  break;
3522  }
3523  }
3524  switch (in) {
3525  case '-':
3526  case '/':
3527  if (!sepc) {
3528  sepc = in;
3529  }
3530  switch (i) {
3531  case 0: tss->year = n; break;
3532  case 1: tss->month = n; break;
3533  case 2: tss->day = n; break;
3534  }
3535  if (++i >= 3) {
3536  i = 0;
3537  m |= 1;
3538  if (!(m & 2)) {
3539  m |= 8;
3540  }
3541  goto skip;
3542  } else {
3543  ++q;
3544  }
3545  break;
3546  case ':':
3547  switch (i) {
3548  case 0: tss->hour = n; break;
3549  case 1: tss->minute = n; break;
3550  case 2: tss->second = n; break;
3551  }
3552  if (++i >= 3) {
3553  i = 0;
3554  m |= 2;
3555  if (*q == '.') {
3556  in = '.';
3557  goto skip2;
3558  }
3559  if (*q == ' ') {
3560  if ((m & 1) == 0) {
3561  char *e = NULL;
3562 
3563  (void) strtol(q + 1, &e, 10);
3564  if (e && *e == '-') {
3565  goto skip;
3566  }
3567  }
3568  in = '.';
3569  goto skip2;
3570  }
3571  goto skip;
3572  } else {
3573  ++q;
3574  }
3575  break;
3576  case '.':
3577  if (++i >= 1) {
3578  int ndig = q - p;
3579 
3580  if (p[0] == '+' || p[0] == '-') {
3581  ndig--;
3582  }
3583  while (ndig < 9) {
3584  n = n * 10;
3585  ++ndig;
3586  }
3587  tss->fraction = n;
3588  m |= 4;
3589  i = 0;
3590  }
3591  default:
3592  skip:
3593  in = '\0';
3594  skip2:
3595  while (*q && !ISDIGIT(*q)) {
3596  if ((q[0] == 'a' || q[0] == 'A') &&
3597  (q[1] == 'm' || q[1] == 'M')) {
3598  ampm = 0;
3599  ++q;
3600  } else if ((q[0] == 'p' || q[0] == 'P') &&
3601  (q[1] == 'm' || q[1] == 'M')) {
3602  ampm = 1;
3603  ++q;
3604  }
3605  ++q;
3606  }
3607  }
3608  p = q;
3609  }
3610  if ((m & 7) > 1 && (m & 8)) {
3611  /* ISO8601 timezone */
3612  if (p > str && ISDIGIT(*p)) {
3613  int nn, sign;
3614 
3615  q = p - 1;
3616  if (*q != '+' && *q != '-') {
3617  goto done;
3618  }
3619  sign = (*q == '+') ? -1 : 1;
3620  q = NULL;
3621  n = strtol(p, &q, 10);
3622  if (!q || *q++ != ':' || !ISDIGIT(*q)) {
3623  goto done;
3624  }
3625  p = q;
3626  q = NULL;
3627  nn = strtol(p, &q, 10);
3628  tss->minute += nn * sign;
3629  if ((SQLSMALLINT) tss->minute < 0) {
3630  tss->hour -= 1;
3631  tss->minute += 60;
3632  } else if (tss->minute >= 60) {
3633  tss->hour += 1;
3634  tss->minute -= 60;
3635  }
3636  tss->hour += n * sign;
3637  if ((SQLSMALLINT) tss->hour < 0) {
3638  tss->day -= 1;
3639  tss->hour += 24;
3640  } else if (tss->hour >= 24) {
3641  tss->day += 1;
3642  tss->hour -= 24;
3643  }
3644  if ((short) tss->day < 1 || tss->day >= 28) {
3645  int mday, pday, pmon;
3646 
3647  mday = getmdays(tss->year, tss->month);
3648  pmon = tss->month - 1;
3649  if (pmon < 1) {
3650  pmon = 12;
3651  }
3652  pday = getmdays(tss->year, pmon);
3653  if ((SQLSMALLINT) tss->day < 1) {
3654  tss->month -= 1;
3655  tss->day = pday;
3656  } else if (tss->day > mday) {
3657  tss->month += 1;
3658  tss->day = 1;
3659  }
3660  if ((SQLSMALLINT) tss->month < 1) {
3661  tss->year -= 1;
3662  tss->month = 12;
3663  } else if (tss->month > 12) {
3664  tss->year += 1;
3665  tss->month = 1;
3666  }
3667  }
3668  }
3669  }
3670 done:
3671  if ((m & 1) &&
3672  (tss->month < 1 || tss->month > 12 ||
3673  tss->day < 1 || tss->day > getmdays(tss->year, tss->month))) {
3674  if (sepc == '/') {
3675  /* Try MM/DD/YYYY format */
3676  int t[3];
3677 
3678  t[0] = tss->year;
3679  t[1] = tss->month;
3680  t[2] = tss->day;
3681  tss->year = t[2];
3682  tss->day = t[1];
3683  tss->month = t[0];
3684  }
3685  }
3686  /* Replace missing year/month/day with current date */
3687  if (!err && (m & 1) == 0) {
3688 #ifdef _WIN32
3689  SYSTEMTIME t;
3690 
3691  GetLocalTime(&t);
3692  tss->year = t.wYear;
3693  tss->month = t.wMonth;
3694  tss->day = t.wDay;
3695 #else
3696  struct timeval tv;
3697  struct tm tm;
3698 
3699  gettimeofday(&tv, NULL);
3700  tm = *localtime(&tv.tv_sec);
3701  tss->year = tm.tm_year + 1900;
3702  tss->month = tm.tm_mon + 1;
3703  tss->day = tm.tm_mday;
3704 #endif
3705  }
3706  /* Normalize fraction */
3707  if (tss->fraction < 0) {
3708  tss->fraction = 0;
3709  }
3710  /* Final check for overflow */
3711  if (err ||
3712  tss->month < 1 || tss->month > 12 ||
3713  tss->day < 1 || tss->day > getmdays(tss->year, tss->month) ||
3714  tss->hour > 23 || tss->minute > 59 || tss->second > 59) {
3715  return -1;
3716  }
3717  if ((m & 7) > 1) {
3718  if (ampm > 0) {
3719  if (tss->hour < 12) {
3720  tss->hour += 12;
3721  }
3722  } else if (ampm == 0) {
3723  if (tss->hour == 12) {
3724  tss->hour = 0;
3725  }
3726  }
3727  }
3728  return ((m & 7) < 1) ? -1 : 0;
3729 }
3730 
3737 static int
3738 getbool(char *string)
3739 {
3740  if (string) {
3741  return string[0] && strchr("Yy123456789Tt", string[0]) != NULL;
3742  }
3743  return 0;
3744 }
3745 
3753 static void
3754 blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
3755 {
3756 #if 0
3757  DBC *d = (DBC *) sqlite3_user_data(ctx);
3758 #endif
3759  char *filename = 0;
3760 
3761  if (nargs > 0) {
3762  if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
3763  filename = (char *) sqlite3_value_text(args[0]);
3764  }
3765  }
3766  if (filename) {
3767 #ifdef _WIN32
3768  char *wname = utf_to_wmb(filename, -1);
3769  FILE *f;
3770 #else
3771  FILE *f = fopen(filename, "r");
3772 #endif
3773  char *p;
3774  long n, nn;
3775 
3776 #ifdef _WIN32
3777  if (wname) {
3778  f = fopen(wname, "rb");
3779  } else {
3780  sqlite3_result_error(ctx, "out of memory", -1);
3781  return;
3782  }
3783  uc_free(wname);
3784 #endif
3785  if (f) {
3786  if (fseek(f, 0, SEEK_END) == 0) {
3787  n = ftell(f);
3788  if (fseek(f, 0, SEEK_SET) == 0) {
3789  p = sqlite3_malloc(n);
3790  if (p) {
3791  nn = fread(p, 1, n, f);
3792  if (nn != n) {
3793  sqlite3_result_error(ctx, "read error", -1);
3794  sqlite3_free(p);
3795  } else {
3796  sqlite3_result_blob(ctx, p, n, sqlite3_free);
3797  }
3798  } else {
3799  sqlite3_result_error(ctx, "out of memory", -1);
3800  }
3801  } else {
3802  sqlite3_result_error(ctx, "seek error", -1);
3803  }
3804  } else {
3805  sqlite3_result_error(ctx, "seek error", -1);
3806  }
3807  fclose(f);
3808  } else {
3809  sqlite3_result_error(ctx, "cannot open file", -1);
3810  }
3811  } else {
3812  sqlite3_result_error(ctx, "no filename given", -1);
3813  }
3814 }
3815 
3823 static void
3824 blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
3825 {
3826 #if 0
3827  DBC *d = (DBC *) sqlite3_user_data(ctx);
3828 #endif
3829  char *filename = 0;
3830  char *p = 0;
3831  int n = 0;
3832 
3833  if (nargs > 0) {
3834  p = (char *) sqlite3_value_blob(args[0]);
3835  n = sqlite3_value_bytes(args[0]);
3836  }
3837  if (nargs > 1) {
3838  if (sqlite3_value_type(args[1]) != SQLITE_NULL) {
3839  filename = (char *) sqlite3_value_text(args[1]);
3840  }
3841  }
3842  if (p) {
3843  if (filename) {
3844 #ifdef _WIN32
3845  char *wname = utf_to_wmb(filename, -1);
3846  FILE *f;
3847 #else
3848  FILE *f = fopen(filename, "w");
3849 #endif
3850  int nn;
3851 
3852 #ifdef _WIN32
3853  if (wname) {
3854  f = fopen(wname, "wb");
3855  } else {
3856  sqlite3_result_error(ctx, "out of memory", -1);
3857  return;
3858  }
3859  uc_free(wname);
3860 #endif
3861  if (f) {
3862  nn = fwrite(p, 1, n, f);
3863  fclose(f);
3864  if (nn != n) {
3865  sqlite3_result_error(ctx, "write error", -1);
3866  } else {
3867  sqlite3_result_int(ctx, nn);
3868  }
3869  } else {
3870  sqlite3_result_error(ctx, "cannot open file", -1);
3871  }
3872  } else {
3873  sqlite3_result_error(ctx, "no filename given", -1);
3874  }
3875  } else {
3876  sqlite3_result_null(ctx);
3877  }
3878 }
3879 
3887 static void
3888 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3889 dbtrace(void *arg, const char *msg, sqlite_uint64 et)
3890 #else
3891 dbtrace(void *arg, const char *msg)
3892 #endif
3893 {
3894  DBC *d = (DBC *) arg;
3895 
3896  if (msg && d->trace) {
3897  int len = strlen(msg);
3898 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3899  unsigned long s, f;
3900 #endif
3901 
3902  if (len > 0) {
3903  char *end = "\n";
3904 
3905  if (msg[len - 1] != ';') {
3906  end = ";\n";
3907  }
3908  fprintf(d->trace, "%s%s", msg, end);
3909 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3910  s = et / 1000000000LL;
3911  f = et % 1000000000LL;
3912  fprintf(d->trace, "-- took %lu.%09lu seconds\n", s, f);
3913 #endif
3914  fflush(d->trace);
3915  }
3916  }
3917 }
3918 
3926 static void
3927 dbtraceapi(DBC *d, char *fn, const char *sql)
3928 {
3929  if (fn && d->trace) {
3930  if (sql) {
3931  fprintf(d->trace, "-- %s: %s\n", fn, sql);
3932  } else {
3933  fprintf(d->trace, "-- %s\n", fn);
3934  }
3935  fflush(d->trace);
3936  }
3937 }
3938 
3946 static void
3947 dbtracerc(DBC *d, int rc, char *err)
3948 {
3949  if (rc != SQLITE_OK && d->trace) {
3950  fprintf(d->trace, "-- SQLITE ERROR CODE %d", rc);
3951  fprintf(d->trace, err ? ": %s\n" : "\n", err);
3952  fflush(d->trace);
3953  }
3954 }
3955 
3970 static SQLRETURN
3971 dbopen(DBC *d, char *name, int isu, char *dsn, char *sflag,
3972  char *spflag, char *ntflag, char *jmode, char *busy)
3973 {
3974  char *endp = NULL;
3975  int rc, tmp, busyto = 100000;
3976 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
3977  int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
3978  char *uname = name;
3979  const char *vfs_name = NULL;
3980 #endif
3981 
3982  if (d->sqlite) {
3983  if (d->trace) {
3984  fprintf(d->trace, "-- sqlite3_close (deferred): '%s'\n",
3985  d->dbname);
3986  fflush(d->trace);
3987  }
3988 #if defined(HAVE_SQLITE3CLOSEV2) && (HAVE_SQLITE3CLOSEV2)
3989  sqlite3_close_v2(d->sqlite);
3990 #else
3991  sqlite3_close(d->sqlite);
3992 #endif
3993  d->sqlite = NULL;
3994  }
3995 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
3996  if (d->nocreat) {
3997  flags &= ~ SQLITE_OPEN_CREATE;
3998  }
3999 #if defined(_WIN32) || defined(_WIN64)
4000  if (!isu) {
4001  char expname[SQL_MAX_MESSAGE_LENGTH * 2];
4002 
4003  expname[0] = '\0';
4004  rc = ExpandEnvironmentStrings(name, expname, sizeof (expname));
4005  if (rc <= sizeof (expname)) {
4006  uname = wmb_to_utf(expname, rc - 1);
4007  } else {
4008  uname = wmb_to_utf(name, -1);
4009  }
4010  if (!uname) {
4011  rc = SQLITE_NOMEM;
4012  setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
4013  return SQL_ERROR;
4014  }
4015  }
4016 #endif
4017 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
4018  vfs_name = nvfs_makevfs(uname);
4019 #endif
4020 #ifdef SQLITE_OPEN_URI
4021  flags |= SQLITE_OPEN_URI;
4022 #endif
4023  rc = sqlite3_open_v2(uname, &d->sqlite, flags, vfs_name);
4024 #if defined(WINTERFACE) || defined(_WIN32) || defined(_WIN64)
4025  if (uname != name) {
4026  uc_free(uname);
4027  }
4028 #endif
4029 #else
4030 #if defined(_WIN32) || defined(_WIN64)
4031  if (d->nocreat) {
4032  char *cname = NULL;
4033 
4034  if (isu) {
4035  cname = utf_to_wmb(name, -1);
4036  }
4037  if (GetFileAttributesA(cname ? cname : name) ==
4038  INVALID_FILE_ATTRIBUTES) {
4039  uc_free(cname);
4040  rc = SQLITE_CANTOPEN;
4041  setstatd(d, rc, "cannot open database",
4042  (*d->ov3) ? "HY000" : "S1000");
4043  return SQL_ERROR;
4044  }
4045  uc_free(cname);
4046  }
4047 #else
4048  if (d->nocreat && access(name, 004) < 0) {
4049  rc = SQLITE_CANTOPEN;
4050  setstatd(d, rc, "cannot open database", (*d->ov3) ? "HY000" : "S1000");
4051  return SQL_ERROR;
4052  }
4053 #endif
4054 #if defined(_WIN32) || defined(_WIN64)
4055  if (!isu) {
4056  WCHAR *wname = wmb_to_uc(name, -1);
4057 
4058  if (!wname) {
4059  rc = SQLITE_NOMEM;
4060  setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
4061  return SQL_ERROR;
4062  }
4063  rc = sqlite3_open16(wname, &d->sqlite);
4064  uc_free(wname);
4065  } else
4066 #endif
4067  rc = sqlite3_open(name, &d->sqlite);
4068 #endif /* !HAVE_SQLITE3VFS */
4069  if (rc != SQLITE_OK) {
4070 connfail:
4071  setstatd(d, rc, "connect failed", (*d->ov3) ? "HY000" : "S1000");
4072  if (d->sqlite) {
4073  sqlite3_close(d->sqlite);
4074  d->sqlite = NULL;
4075  }
4076  return SQL_ERROR;
4077  }
4078 #if defined(SQLITE_DYNLOAD) || defined(SQLITE_HAS_CODEC)
4079  if (d->pwd) {
4080  sqlite3_key(d->sqlite, d->pwd, d->pwdLen);
4081  }
4082 #endif
4083  d->pwd = NULL;
4084  d->pwdLen = 0;
4085  if (d->trace) {
4086 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
4087  sqlite3_profile(d->sqlite, dbtrace, d);
4088 #else
4089  sqlite3_trace(d->sqlite, dbtrace, d);
4090 #endif
4091  }
4092  d->step_enable = getbool(sflag);
4093  d->trans_disable = getbool(ntflag);
4094  d->curtype = d->step_enable ?
4095  SQL_CURSOR_FORWARD_ONLY : SQL_CURSOR_STATIC;
4096  tmp = strtol(busy, &endp, 0);
4097  if (endp && *endp == '\0' && endp != busy) {
4098  busyto = tmp;
4099  }
4100  if (busyto < 1 || busyto > 1000000) {
4101  busyto = 1000000;
4102  }
4103  d->timeout = busyto;
4104  freep(&d->dbname);
4105  d->dbname = xstrdup(name);
4106  freep(&d->dsn);
4107  d->dsn = xstrdup(dsn);
4108  if ((rc = setsqliteopts(d->sqlite, d)) != SQLITE_OK) {
4109  if (d->trace) {
4110  fprintf(d->trace, "-- sqlite3_close: '%s'\n",
4111  d->dbname);
4112  fflush(d->trace);
4113  }
4114  sqlite3_close(d->sqlite);
4115  d->sqlite = NULL;
4116  goto connfail;
4117  }
4118  if (!spflag || spflag[0] == '\0') {
4119  spflag = "NORMAL";
4120  }
4121  if (spflag[0] != '\0') {
4122  char syncp[128];
4123 
4124  sprintf(syncp, "PRAGMA synchronous = %8.8s;", spflag);
4125  sqlite3_exec(d->sqlite, syncp, NULL, NULL, NULL);
4126  }
4127  if (jmode[0] != '\0') {
4128  char jourp[128];
4129 
4130  sprintf(jourp, "PRAGMA journal_mode = %16.16s;", jmode);
4131  sqlite3_exec(d->sqlite, jourp, NULL, NULL, NULL);
4132  }
4133  if (d->trace) {
4134  fprintf(d->trace, "-- sqlite3_open: '%s'\n", d->dbname);
4135  fflush(d->trace);
4136  }
4137 #if defined(_WIN32) || defined(_WIN64)
4138  {
4139  char pname[MAX_PATH];
4140  HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
4141  FALSE, GetCurrentProcessId());
4142 
4143  pname[0] = '\0';
4144  if (h) {
4145  HMODULE m = NULL, l = LoadLibrary("psapi.dll");
4146  DWORD need;
4147  typedef BOOL (WINAPI *epmfunc)(HANDLE, HMODULE *, DWORD, LPDWORD);
4148  typedef BOOL (WINAPI *gmbfunc)(HANDLE, HMODULE, LPSTR, DWORD);
4149  epmfunc epm;
4150  gmbfunc gmb;
4151 
4152  if (l) {
4153  epm = (epmfunc) GetProcAddress(l, "EnumProcessModules");
4154  gmb = (gmbfunc) GetProcAddress(l, "GetModuleBaseNameA");
4155  if (epm && gmb && epm(h, &m, sizeof (m), &need)) {
4156  gmb(h, m, pname, sizeof (pname));
4157  }
4158  FreeLibrary(l);
4159  }
4160  CloseHandle(h);
4161  }
4162  d->xcelqrx = strncasecmp(pname, "EXCEL", 5) == 0 ||
4163  strncasecmp(pname, "MSQRY", 5) == 0;
4164  if (d->trace && d->xcelqrx) {
4165 
4166  fprintf(d->trace, "-- enabled EXCEL quirks\n");
4167  fflush(d->trace);
4168  }
4169  }
4170 #endif
4171  sqlite3_create_function(d->sqlite, "blob_import", 1, SQLITE_UTF8,
4172  d, blob_import, 0, 0);
4173  sqlite3_create_function(d->sqlite, "blob_export", 2, SQLITE_UTF8,
4174  d, blob_export, 0, 0);
4175  return SQL_SUCCESS;
4176 }
4177 
4184 static void
4185 dbloadext(DBC *d, char *exts)
4186 {
4187 #if defined(HAVE_SQLITE3LOADEXTENSION) && (HAVE_SQLITE3LOADEXTENSION)
4188  char *p;
4189  char path[SQL_MAX_MESSAGE_LENGTH];
4190  int plen = 0;
4191 
4192  if (!d->sqlite) {
4193  return;
4194  }
4195  sqlite3_enable_load_extension(d->sqlite, 1);
4196 #if defined(_WIN32) || defined(_WIN64)
4197  GetModuleFileName(hModule, path, sizeof (path));
4198  p = strrchr(path, '\\');
4199  plen = p ? ((p + 1) - path) : 0;
4200 #endif
4201  do {
4202  p = strchr(exts, ',');
4203  if (p) {
4204  strncpy(path + plen, exts, p - exts);
4205  path[plen + (p - exts)] = '\0';
4206  } else {
4207  strcpy(path + plen, exts);
4208  }
4209  if (exts[0]) {
4210  char *errmsg = NULL;
4211  int rc;
4212 #if defined(_WIN32) || defined(_WIN64)
4213  int i;
4214  char *q;
4215 
4216  q = path + plen;
4217  if (!(q[0] &&
4218  ((q[1] == ':' && (q[2] == '\\' || q[2] == '/')) ||
4219  q[0] == '\\' || q[0] == '/' || q[0] == '.'))) {
4220  q = path;
4221  }
4222  /* sqlite3_load_extension() dislikes backslashes */
4223  for (i = 0; q[i] != '\0'; i++) {
4224  if (q[i] == '\\') {
4225  q[i] = '/';
4226  }
4227  }
4228  rc = sqlite3_load_extension(d->sqlite, q, 0, &errmsg);
4229 #else
4230  rc = sqlite3_load_extension(d->sqlite, path, 0, &errmsg);
4231 #endif
4232  if (rc != SQLITE_OK) {
4233 #if defined(_WIN32) || defined(_WIN64)
4234  char buf[512], msg[512];
4235 
4236  LoadString(hModule, IDS_EXTERR, buf, sizeof (buf));
4237  wsprintf(msg, buf, q, errmsg ?
4238  errmsg : "no error info available");
4239  LoadString(hModule, IDS_EXTTITLE, buf, sizeof (buf));
4240  MessageBox(NULL, msg, buf,
4241  MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
4242  MB_SETFOREGROUND);
4243 #else
4244  fprintf(stderr, "extension '%s' did not load%s%s\n",
4245  path, errmsg ? ": " : "", errmsg ? errmsg : "");
4246 #endif
4247  }
4248  }
4249  if (p) {
4250  exts = p + 1;
4251  }
4252  } while (p);
4253 #endif /* HAVE_SQLITE3LOADEXTENSION */
4254 }
4255 
4262 static void
4263 dbattas(DBC *d, char *attas)
4264 {
4265  char *p;
4266  char as[SQL_MAX_MESSAGE_LENGTH];
4267 
4268  if (!d->sqlite) {
4269  return;
4270  }
4271  do {
4272  p = strchr(attas, ',');
4273  if (p) {
4274  strncpy(as, attas, p - attas);
4275  as[p - attas] = '\0';
4276  } else {
4277  strcpy(as, attas);
4278  }
4279  if (attas[0]) {
4280  char *sql;
4281 
4282  sql = sqlite3_mprintf("ATTACH %Q AS %s", d->dbname, as);
4283  if (sql != NULL) {
4284  sqlite3_exec(d->sqlite, sql, NULL, NULL, NULL);
4285  sqlite3_free(sql);
4286  }
4287  }
4288  if (p) {
4289  attas = p + 1;
4290  }
4291  } while (p);
4292 }
4293 
4303 static char *
4304 s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
4305 {
4306  char *typename = (char *) sqlite3_column_decltype(s3stmt, col);
4307  char guess[64];
4308 
4309  guess[0] = '\0';
4310  if (!typename) {
4311  int coltype = sqlite3_column_type(s3stmt, col);
4312 
4313  if (guessed_types) {
4314  guessed_types[0]++;
4315  }
4316  if (d->trace) {
4317  sprintf(guess, " (guessed from %d)", coltype);
4318  }
4319  switch (coltype) {
4320  case SQLITE_INTEGER: typename = "integer"; break;
4321  case SQLITE_FLOAT: typename = "double"; break;
4322  default:
4323  case SQLITE_TEXT: typename = "varchar"; break;
4324  case SQLITE_BLOB: typename = "blob"; break;
4325 #if 0
4326  case SQLITE_NULL: typename = "null"; break;
4327 #endif
4328  }
4329  }
4330  if (d->trace) {
4331  fprintf(d->trace, "-- column %d type%s: '%s'\n", col + 1,
4332  guess, typename);
4333  fflush(d->trace);
4334  }
4335  return typename;
4336 }
4337 
4338 #ifdef FULL_METADATA
4339 
4348 static void
4349 s3stmt_addmeta(sqlite3_stmt *s3stmt, int col, DBC *d, COL *ci)
4350 {
4351  int nn = 0, pk = 0, ai = 0;
4352  const char *dn = NULL, *tn = NULL, *cn = NULL, *dummy[4];
4353 
4354  dn = sqlite3_column_database_name(s3stmt, col);
4355  tn = sqlite3_column_table_name(s3stmt, col);
4356  cn = sqlite3_column_origin_name(s3stmt, col);
4357  dummy[0] = dummy[1] = 0;
4358  if (tn && cn) {
4359  sqlite3_table_column_metadata(d->sqlite, dn, tn, cn,
4360  dummy, dummy + 1,
4361  &nn, &pk, &ai);
4362  }
4363  ci->autoinc = ai ? SQL_TRUE: SQL_FALSE;
4364  ci->notnull = nn ? SQL_NO_NULLS : SQL_NULLABLE;
4365  ci->ispk = pk ? 1 : 0;
4366  if (d->trace) {
4367  fprintf(d->trace, "-- column %d %s\n",
4368  col + 1, nn ? "notnull" : "nullable");
4369  if (ai) {
4370  fprintf(d->trace, "-- column %d autoincrement\n", col + 1);
4371  }
4372  fflush(d->trace);
4373  }
4374  ci->isrowid = 0;
4375  if (ci->ispk && tn) {
4376  nn = pk = ai = 0;
4377  dummy[2] = dummy[3] = 0;
4378 
4379  sqlite3_table_column_metadata(d->sqlite, dn, tn, "rowid",
4380  dummy + 2, dummy + 3,
4381  &nn, &pk, &ai);
4382  if (pk && dummy[0] && dummy[0] == dummy[2]) {
4383  ci->isrowid = 1;
4384  }
4385  }
4386 }
4387 
4388 #endif
4389 
4396 static int
4398 {
4399  DBC *d = (DBC *) s->dbc;
4400  char **rowd = NULL;
4401  const char *errp = NULL;
4402  int i, ncols, rc;
4403 
4404  if (s != d->cur_s3stmt || !s->s3stmt) {
4405  setstat(s, -1, "stale statement", (*s->ov3) ? "HY000" : "S1000");
4406  return SQL_ERROR;
4407  }
4408  rc = sqlite3_step(s->s3stmt);
4409  if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
4410  ++s->s3stmt_rownum;
4411  ncols = sqlite3_column_count(s->s3stmt);
4412  if (d->s3stmt_needmeta && s->s3stmt_rownum == 0 && ncols > 0) {
4413  PTRDIFF_T size;
4414  char *p;
4415  COL *dyncols;
4416  const char *colname, *typename;
4417 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4418  char *tblname;
4419 #endif
4420 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
4421  char *dbname;
4422 #endif
4423 
4424  for (i = size = 0; i < ncols; i++) {
4425  colname = sqlite3_column_name(s->s3stmt, i);
4426  size += 3 + 3 * strlen(colname);
4427  }
4428 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4429  tblname = (char *) size;
4430  for (i = 0; i < ncols; i++) {
4431  p = (char *) sqlite3_column_table_name(s->s3stmt, i);
4432  size += 2 + (p ? strlen(p) : 0);
4433  }
4434 #endif
4435 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
4436  dbname = (char *) size;
4437  for (i = 0; i < ncols; i++) {
4438  p = (char *) sqlite3_column_database_name(s->s3stmt, i);
4439  size += 2 + (p ? strlen(p) : 0);
4440  }
4441 #endif
4442  dyncols = xmalloc(ncols * sizeof (COL) + size);
4443  if (!dyncols) {
4444  freedyncols(s);
4445  s->ncols = 0;
4446  dbtraceapi(d, "sqlite3_finalize", 0);
4447  sqlite3_finalize(s->s3stmt);
4448  s->s3stmt = NULL;
4449  d->cur_s3stmt = NULL;
4450  return nomem(s);
4451  }
4452  p = (char *) (dyncols + ncols);
4453 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4454  tblname = p + (PTRDIFF_T) tblname;
4455 #endif
4456 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
4457  dbname = p + (PTRDIFF_T) dbname;
4458 #endif
4459  for (i = 0; i < ncols; i++) {
4460  char *q;
4461 
4462  colname = sqlite3_column_name(s->s3stmt, i);
4463  if (d->trace) {
4464  fprintf(d->trace, "-- column %d name: '%s'\n",
4465  i + 1, colname);
4466  fflush(d->trace);
4467  }
4468 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4469  q = (char *) sqlite3_column_table_name(s->s3stmt, i);
4470  strcpy(tblname, q ? q : "");
4471  if (d->trace) {
4472  fprintf(d->trace, "-- table %d name: '%s'\n",
4473  i + 1, tblname);
4474  fflush(d->trace);
4475  }
4476  dyncols[i].table = tblname;
4477  tblname += strlen(tblname) + 1;
4478 #endif
4479 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
4480  q = (char *) sqlite3_column_database_name(s->s3stmt, i);
4481  strcpy(dbname, q ? q : "");
4482  if (d->trace) {
4483  fprintf(d->trace, "-- database %d name: '%s'\n",
4484  i + 1, dbname);
4485  fflush(d->trace);
4486  }
4487  dyncols[i].db = dbname;
4488  dbname += strlen(dbname) + 1;
4489 #else
4490  dyncols[i].db = ((DBC *) (s->dbc))->dbname;
4491 #endif
4492  typename = s3stmt_coltype(s->s3stmt, i, d, 0);
4493  strcpy(p, colname);
4494  dyncols[i].label = p;
4495  p += strlen(p) + 1;
4496  q = strchr(colname, '.');
4497  if (q) {
4498  char *q2 = strchr(q + 1, '.');
4499 
4500  /* SQLite 3.3.4 produces view.table.column sometimes */
4501  if (q2) {
4502  q = q2;
4503  }
4504  }
4505  if (q) {
4506 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
4507  dyncols[i].table = p;
4508 #endif
4509  strncpy(p, colname, q - colname);
4510  p[q - colname] = '\0';
4511  p += strlen(p) + 1;
4512  strcpy(p, q + 1);
4513  dyncols[i].column = p;
4514  p += strlen(p) + 1;
4515  } else {
4516 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
4517  dyncols[i].table = "";
4518 #endif
4519  strcpy(p, colname);
4520  dyncols[i].column = p;
4521  p += strlen(p) + 1;
4522  }
4523  if (s->longnames) {
4524  dyncols[i].column = dyncols[i].label;
4525  }
4526 #ifdef SQL_LONGVARCHAR
4527  dyncols[i].type = SQL_LONGVARCHAR;
4528  dyncols[i].size = 65535;
4529 #else
4530  dyncols[i].type = SQL_VARCHAR;
4531  dyncols[i].size = 255;
4532 #endif
4533  dyncols[i].index = i;
4534  dyncols[i].scale = 0;
4535  dyncols[i].prec = 0;
4536  dyncols[i].nosign = 1;
4537  dyncols[i].autoinc = SQL_FALSE;
4538  dyncols[i].notnull = SQL_NULLABLE;
4539  dyncols[i].ispk = -1;
4540  dyncols[i].isrowid = -1;
4541 #ifdef FULL_METADATA
4542  s3stmt_addmeta(s->s3stmt, i, d, &dyncols[i]);
4543 #endif
4544  dyncols[i].typename = xstrdup(typename);
4545  }
4546  freedyncols(s);
4547  s->ncols = s->dcols = ncols;
4548  s->dyncols = s->cols = dyncols;
4549  fixupdyncols(s, d);
4550  mkbindcols(s, s->ncols);
4551  d->s3stmt_needmeta = 0;
4552  }
4553  if (ncols <= 0) {
4554  goto killstmt;
4555  }
4556  if (rc == SQLITE_DONE) {
4557  freeresult(s, 0);
4558  s->nrows = 0;
4559  dbtraceapi(d, "sqlite3_finalize", 0);
4560  sqlite3_finalize(s->s3stmt);
4561  s->s3stmt = NULL;
4562  d->cur_s3stmt = NULL;
4563  return SQL_SUCCESS;
4564  }
4565  rowd = xmalloc((1 + 2 * ncols) * sizeof (char *));
4566  if (rowd) {
4567  const unsigned char *value;
4568 
4569  rowd[0] = (char *) ((PTRDIFF_T) (ncols * 2));
4570  ++rowd;
4571  for (i = 0; i < ncols; i++) {
4572  int coltype = sqlite3_column_type(s->s3stmt, i);
4573 
4574  rowd[i] = rowd[i + ncols] = NULL;
4575  if (coltype == SQLITE_BLOB) {
4576  int k, nbytes = sqlite3_column_bytes(s->s3stmt, i);
4577  char *qp;
4578  unsigned const char *bp;
4579 
4580  bp = sqlite3_column_blob(s->s3stmt, i);
4581  qp = xmalloc(nbytes * 2 + 4);
4582  if (qp) {
4583  rowd[i + ncols] = qp;
4584  *qp++ = 'X';
4585  *qp++ = '\'';
4586  for (k = 0; k < nbytes; k++) {
4587  *qp++ = xdigits[(bp[k] >> 4)];
4588  *qp++ = xdigits[(bp[k] & 0xF)];
4589  }
4590  *qp++ = '\'';
4591  *qp = '\0';
4592  }
4593 #ifdef _MSC_VER
4594  } else if (coltype == SQLITE_FLOAT) {
4595  struct lconv *lc = 0;
4596  double d = sqlite3_column_double(s->s3stmt, i);
4597  char *p, buffer[128];
4598 
4599  /*
4600  * This avoids floating point rounding
4601  * and formatting problems of some SQLite
4602  * versions in conjunction with MSVC 2010.
4603  */
4604  snprintf(buffer, sizeof (buffer), "%.15g", d);
4605  lc = localeconv();
4606  if (lc && lc->decimal_point && lc->decimal_point[0] &&
4607  lc->decimal_point[0] != '.') {
4608  p = strchr(buffer, lc->decimal_point[0]);
4609  if (p) {
4610  *p = '.';
4611  }
4612  }
4613  rowd[i + ncols] = xstrdup(buffer);
4614 #endif
4615  } else if (coltype != SQLITE_NULL) {
4616  value = sqlite3_column_text(s->s3stmt, i);
4617  rowd[i + ncols] = xstrdup((char *) value);
4618  }
4619  }
4620  for (i = 0; i < ncols; i++) {
4621  int coltype = sqlite3_column_type(s->s3stmt, i);
4622 
4623  value = NULL;
4624  if (coltype == SQLITE_BLOB) {
4625  value = sqlite3_column_blob(s->s3stmt, i);
4626  } else if (coltype != SQLITE_NULL) {
4627  value = sqlite3_column_text(s->s3stmt, i);
4628  }
4629  if (value && !rowd[i + ncols]) {
4630  freerows(rowd);
4631  rowd = 0;
4632  break;
4633  }
4634  }
4635  }
4636  if (rowd) {
4637  freeresult(s, 0);
4638  s->nrows = 1;
4639  s->rows = rowd;
4640  s->rowfree = freerows;
4641  if (rc == SQLITE_DONE) {
4642  dbtraceapi(d, "sqlite3_finalize", 0);
4643  sqlite3_finalize(s->s3stmt);
4644  s->s3stmt = NULL;
4645  d->cur_s3stmt = NULL;
4646  }
4647  return SQL_SUCCESS;
4648  }
4649  }
4650 killstmt:
4651  dbtraceapi(d, "sqlite3_reset", 0);
4652  rc = sqlite3_reset(s->s3stmt);
4653  s->s3stmt_noreset = 1;
4654  errp = sqlite3_errmsg(d->sqlite);
4655  if (d->cur_s3stmt == s) {
4656  d->cur_s3stmt = NULL;
4657  }
4658  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
4659  errp ? errp : "unknown error", rc);
4660  return SQL_ERROR;
4661 }
4662 
4668 static void
4670 {
4671  DBC *d;
4672 
4673  if (!s || !s->s3stmt) {
4674  return;
4675  }
4676  d = (DBC *) s->dbc;
4677  if (d) {
4678  d->busyint = 0;
4679  }
4680  if (!s->s3stmt_noreset) {
4681  dbtraceapi(d, "sqlite3_reset", 0);
4682  sqlite3_reset(s->s3stmt);
4683  s->s3stmt_noreset = 1;
4684  s->s3stmt_rownum = -1;
4685  }
4686  if (d->cur_s3stmt == s) {
4687  d->cur_s3stmt = NULL;
4688  }
4689 }
4690 
4696 static void
4698 {
4699  DBC *d = (DBC *) s->dbc;
4700 
4701  if (d) {
4702  d->busyint = 0;
4703  }
4704  if (d && d->cur_s3stmt == s) {
4705  s3stmt_end(s);
4706  }
4707 }
4708 
4714 static void
4716 {
4717  if (s->s3stmt) {
4718  DBC *d = (DBC *) s->dbc;
4719 
4720  if (d) {
4721  dbtraceapi(d, "sqlite3_finalize", 0);
4722  }
4723  sqlite3_finalize(s->s3stmt);
4724  s->s3stmt = NULL;
4725  s->s3stmt_rownum = 0;
4726  }
4727 }
4728 
4735 static SQLRETURN
4737 {
4738  DBC *d = (DBC *) s->dbc;
4739  const char *endp;
4740  sqlite3_stmt *s3stmt = NULL;
4741  int rc, nretry = 0;
4742 
4743  d->s3stmt_needmeta = 0;
4744  if (!s->s3stmt) {
4745 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
4746  dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
4747 #else
4748  dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
4749 #endif
4750  do {
4751  s3stmt = NULL;
4752 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
4753  rc = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
4754  &s3stmt, &endp);
4755 #else
4756  rc = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
4757  &s3stmt, &endp);
4758 #endif
4759  if (rc != SQLITE_OK) {
4760  if (s3stmt) {
4761  sqlite3_finalize(s3stmt);
4762  s3stmt = NULL;
4763  }
4764  }
4765  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
4766  dbtracerc(d, rc, NULL);
4767  if (rc != SQLITE_OK) {
4768  if (s3stmt) {
4769  dbtraceapi(d, "sqlite3_finalize", NULL);
4770  sqlite3_finalize(s3stmt);
4771  }
4772  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
4773  sqlite3_errmsg(d->sqlite), rc);
4774  return SQL_ERROR;
4775  }
4776  if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
4777  dbtraceapi(d, "sqlite3_finalize", 0);
4778  sqlite3_finalize(s3stmt);
4779  setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
4780  (*s->ov3) ? "HY000" : "S1000");
4781  return SQL_ERROR;
4782  }
4783  s->s3stmt = s3stmt;
4784  s->s3stmt_noreset = 1;
4785  d->s3stmt_needmeta = 1;
4786  }
4787  d->cur_s3stmt = s;
4788  s->s3stmt_rownum = -1;
4789  s3bind(d, s->s3stmt, s->nparams, s->bindparms);
4790  return SQL_SUCCESS;
4791 }
4792 
4793 #ifndef WINTERFACE
4794 
4798 SQLRETURN SQL_API
4799 SQLDataSources(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *srvname,
4800  SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
4801  SQLCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
4802 {
4803  if (env == SQL_NULL_HENV) {
4804  return SQL_INVALID_HANDLE;
4805  }
4806  return SQL_ERROR;
4807 }
4808 #endif
4809 
4810 #ifdef WINTERFACE
4811 
4815 SQLRETURN SQL_API
4816 SQLDataSourcesW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *srvname,
4817  SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
4818  SQLWCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
4819 {
4820  if (env == SQL_NULL_HENV) {
4821  return SQL_INVALID_HANDLE;
4822  }
4823  return SQL_ERROR;
4824 }
4825 #endif
4826 
4827 #ifndef WINTERFACE
4828 
4832 SQLRETURN SQL_API
4833 SQLDrivers(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *drvdesc,
4834  SQLSMALLINT descmax, SQLSMALLINT *desclenp,
4835  SQLCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
4836 {
4837  if (env == SQL_NULL_HENV) {
4838  return SQL_INVALID_HANDLE;
4839  }
4840  return SQL_ERROR;
4841 }
4842 #endif
4843 
4844 #ifdef WINTERFACE
4845 
4849 SQLRETURN SQL_API
4850 SQLDriversW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *drvdesc,
4851  SQLSMALLINT descmax, SQLSMALLINT *desclenp,
4852  SQLWCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
4853 {
4854  if (env == SQL_NULL_HENV) {
4855  return SQL_INVALID_HANDLE;
4856  }
4857  return SQL_ERROR;
4858 }
4859 #endif
4860 
4861 #ifndef WINTERFACE
4862 
4866 SQLRETURN SQL_API
4867 SQLBrowseConnect(SQLHDBC dbc, SQLCHAR *connin, SQLSMALLINT conninLen,
4868  SQLCHAR *connout, SQLSMALLINT connoutMax,
4869  SQLSMALLINT *connoutLen)
4870 {
4871  SQLRETURN ret;
4872 
4873  HDBC_LOCK(dbc);
4874  ret = drvunimpldbc(dbc);
4875  HDBC_UNLOCK(dbc);
4876  return ret;
4877 }
4878 #endif
4879 
4880 #ifdef WINTERFACE
4881 
4885 SQLRETURN SQL_API
4886 SQLBrowseConnectW(SQLHDBC dbc, SQLWCHAR *connin, SQLSMALLINT conninLen,
4887  SQLWCHAR *connout, SQLSMALLINT connoutMax,
4888  SQLSMALLINT *connoutLen)
4889 {
4890  SQLRETURN ret;
4891 
4892  HDBC_LOCK(dbc);
4893  ret = drvunimpldbc(dbc);
4894  HDBC_UNLOCK(dbc);
4895  return ret;
4896 }
4897 #endif
4898 
4907 static SQLRETURN
4908 drvputdata(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
4909 {
4910  STMT *s;
4911  int i, dlen, done = 0;
4912  BINDPARM *p;
4913 
4914  if (stmt == SQL_NULL_HSTMT) {
4915  return SQL_INVALID_HANDLE;
4916  }
4917  s = (STMT *) stmt;
4918  if (!s->query || s->nparams <= 0) {
4919 seqerr:
4920  setstat(s, -1, "sequence error", "HY010");
4921  return SQL_ERROR;
4922  }
4923  for (i = (s->pdcount < 0) ? 0 : s->pdcount; i < s->nparams; i++) {
4924  p = &s->bindparms[i];
4925  if (p->need > 0) {
4926  int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
4927 
4928  if (len == SQL_NULL_DATA) {
4929  freep(&p->parbuf);
4930  p->param = NULL;
4931  p->len = SQL_NULL_DATA;
4932  p->need = -1;
4933  } else if (type != SQL_C_CHAR
4934 #ifdef WCHARSUPPORT
4935  && type != SQL_C_WCHAR
4936 #endif
4937  && type != SQL_C_BINARY) {
4938  int size = 0;
4939 
4940  switch (type) {
4941  case SQL_C_TINYINT:
4942  case SQL_C_UTINYINT:
4943  case SQL_C_STINYINT:
4944 #ifdef SQL_BIT
4945  case SQL_C_BIT:
4946 #endif
4947  size = sizeof (SQLCHAR);
4948  break;
4949  case SQL_C_SHORT:
4950  case SQL_C_USHORT:
4951  case SQL_C_SSHORT:
4952  size = sizeof (SQLSMALLINT);
4953  break;
4954  case SQL_C_LONG:
4955  case SQL_C_ULONG:
4956  case SQL_C_SLONG:
4957  size = sizeof (SQLINTEGER);
4958  break;
4959 #ifdef SQL_BIGINT
4960  case SQL_C_UBIGINT:
4961  case SQL_C_SBIGINT:
4962  size = sizeof (SQLBIGINT);
4963  break;
4964 #endif
4965  case SQL_C_FLOAT:
4966  size = sizeof (float);
4967  break;
4968  case SQL_C_DOUBLE:
4969  size = sizeof (double);
4970  break;
4971 #ifdef SQL_C_TYPE_DATE
4972  case SQL_C_TYPE_DATE:
4973 #endif
4974  case SQL_C_DATE:
4975  size = sizeof (DATE_STRUCT);
4976  break;
4977 #ifdef SQL_C_TYPE_DATE
4978  case SQL_C_TYPE_TIME:
4979 #endif
4980  case SQL_C_TIME:
4981  size = sizeof (TIME_STRUCT);
4982  break;
4983 #ifdef SQL_C_TYPE_DATE
4984  case SQL_C_TYPE_TIMESTAMP:
4985 #endif
4986  case SQL_C_TIMESTAMP:
4987  size = sizeof (TIMESTAMP_STRUCT);
4988  break;
4989  }
4990  freep(&p->parbuf);
4991  p->parbuf = xmalloc(size);
4992  if (!p->parbuf) {
4993  return nomem(s);
4994  }
4995  p->param = p->parbuf;
4996  memcpy(p->param, data, size);
4997  p->len = size;
4998  p->need = -1;
4999  } else if (len == SQL_NTS && (
5000  type == SQL_C_CHAR
5001 #ifdef WCHARSUPPORT
5002  || type == SQL_C_WCHAR
5003 #endif
5004  )) {
5005  char *dp = data;
5006 
5007 #ifdef WCHARSUPPORT
5008  if (type == SQL_C_WCHAR) {
5009  dp = uc_to_utf(data, len);
5010  if (!dp) {
5011  return nomem(s);
5012  }
5013  }
5014 #endif
5015 #if defined(_WIN32) || defined(_WIN64)
5016  if (*s->oemcp) {
5017  dp = wmb_to_utf(data, strlen (data));
5018  if (!dp) {
5019  return nomem(s);
5020  }
5021  }
5022 #endif
5023  dlen = strlen(dp);
5024  freep(&p->parbuf);
5025  p->parbuf = xmalloc(dlen + 1);
5026  if (!p->parbuf) {
5027  if (dp != data) {
5028  uc_free(dp);
5029  }
5030  return nomem(s);
5031  }
5032  p->param = p->parbuf;
5033  strcpy(p->param, dp);
5034  if (dp != data) {
5035  uc_free(dp);
5036  }
5037  p->len = dlen;
5038  p->need = -1;
5039  } else if (len < 0) {
5040  setstat(s, -1, "invalid length", "HY090");
5041  return SQL_ERROR;
5042  } else {
5043  dlen = min(p->len - p->offs, len);
5044  if (!p->param) {
5045  setstat(s, -1, "no memory for parameter", "HY013");
5046  return SQL_ERROR;
5047  }
5048  memcpy((char *) p->param + p->offs, data, dlen);
5049  p->offs += dlen;
5050  if (p->offs >= p->len) {
5051 #ifdef WCHARSUPPORT
5052  if (type == SQL_C_WCHAR) {
5053  char *dp = uc_to_utf(p->param, p->len);
5054  char *np;
5055  int nlen;
5056 
5057  if (!dp) {
5058  return nomem(s);
5059  }
5060  nlen = strlen(dp);
5061  np = xmalloc(nlen + 1);
5062  if (!np) {
5063  uc_free(dp);
5064  return nomem(s);
5065  }
5066  strcpy(np, dp);
5067  uc_free(dp);
5068  if (p->param == p->parbuf) {
5069  freep(&p->parbuf);
5070  }
5071  p->parbuf = p->param = np;
5072  p->len = nlen;
5073  } else {
5074  *((char *) p->param + p->len) = '\0';
5075  }
5076  p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR)
5077  ? -1 : 0;
5078 #else
5079  *((char *) p->param + p->len) = '\0';
5080  p->need = (type == SQL_C_CHAR) ? -1 : 0;
5081 #endif
5082 #if defined(_WIN32) || defined(_WIN64)
5083  if (type == SQL_C_CHAR && *s->oemcp &&
5084  !(p->stype == SQL_BINARY ||
5085  p->stype == SQL_VARBINARY ||
5086  p->stype == SQL_LONGVARBINARY)) {
5087  char *dp = wmb_to_utf(p->param, p->len);
5088 
5089  if (!dp) {
5090  return nomem(s);
5091  }
5092  if (p->param == p->parbuf) {
5093  freep(&p->parbuf);
5094  }
5095  p->parbuf = p->param = dp;
5096  p->len = strlen(dp);
5097  }
5098  if (p->type == SQL_C_WCHAR &&
5099  (p->stype == SQL_VARCHAR ||
5100  p->stype == SQL_LONGVARCHAR) &&
5101  p->len == p->coldef * sizeof (SQLWCHAR)) {
5102  /* fix for MS-Access */
5103  p->len = p->coldef;
5104  }
5105 #endif
5106  }
5107  }
5108  done = 1;
5109  break;
5110  }
5111  }
5112  if (!done) {
5113  goto seqerr;
5114  }
5115  return SQL_SUCCESS;
5116 }
5117 
5126 SQLRETURN SQL_API
5127 SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
5128 {
5129  SQLRETURN ret;
5130 
5131  HSTMT_LOCK(stmt);
5132  ret = drvputdata(stmt, data, len);
5133  HSTMT_UNLOCK(stmt);
5134  return ret;
5135 }
5136 
5142 static SQLRETURN
5144 {
5145  if (s->bindparms) {
5146  int n;
5147 
5148  for (n = 0; n < s->nbindparms; n++) {
5149  freep(&s->bindparms[n].parbuf);
5150  memset(&s->bindparms[n], 0, sizeof (BINDPARM));
5151  }
5152  }
5153  return SQL_SUCCESS;
5154 }
5155 
5167 static SQLRETURN
5168 setupparam(STMT *s, char *sql, int pnum)
5169 {
5170  int type, len = 0, needalloc = 0;
5171  BINDPARM *p;
5172 
5173  if (!s->bindparms || pnum < 0 || pnum >= s->nbindparms) {
5174  goto error;
5175  }
5176  p = &s->bindparms[pnum];
5177  type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
5178 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
5179  /* MS Access hack part 4 (map SQL_C_DEFAULT to SQL_C_CHAR) */
5180  if (type == SQL_C_WCHAR && p->type == SQL_C_DEFAULT) {
5181  type = SQL_C_CHAR;
5182  }
5183 #endif
5184  if (p->need > 0) {
5185  return setupparbuf(s, p);
5186  }
5187  p->strbuf[0] = '\0';
5188  if (!p->param || (p->lenp && *p->lenp == SQL_NULL_DATA)) {
5189  p->s3type = SQLITE_NULL;
5190  p->s3size = 0;
5191  return SQL_SUCCESS;
5192  }
5193  if (type == SQL_C_CHAR &&
5194  (p->stype == SQL_BINARY ||
5195  p->stype == SQL_VARBINARY ||
5196  p->stype == SQL_LONGVARBINARY)) {
5197  type = SQL_C_BINARY;
5198  }
5199  switch (type) {
5200  case SQL_C_BINARY:
5201  p->s3type = SQLITE_BLOB;
5202  p->s3val = p->param;
5203  if (!p->lenp) {
5204  len = p->len;
5205  } else if (*p->lenp == SQL_DATA_AT_EXEC) {
5206  len = p->len;
5207  } else {
5208  len = *p->lenp;
5209  if (len <= SQL_LEN_DATA_AT_EXEC_OFFSET) {
5210  len = SQL_LEN_DATA_AT_EXEC(len);
5211  }
5212  }
5213  if (len < 0) {
5214  setstat(s, -1, "invalid length", "HY009");
5215  return SQL_ERROR;
5216  }
5217  p->len = len;
5218  p->max = p->len;
5219  p->s3size = len;
5220  break;
5221 #ifdef WCHARSUPPORT
5222  case SQL_C_WCHAR:
5223 #endif
5224  case SQL_C_CHAR:
5225  p->s3type = SQLITE_TEXT;
5226  p->s3size = -1;
5227  p->s3val = p->param;
5228  if (!p->parbuf) {
5229 #ifdef WCHARSUPPORT
5230  if (type == SQL_C_WCHAR) {
5231  if (!p->lenp || *p->lenp == SQL_NTS) {
5232  p->max = uc_strlen(p->param) * sizeof (SQLWCHAR);
5233  } else if (*p->lenp >= 0) {
5234  p->max = *p->lenp;
5235  }
5236  } else
5237 #endif
5238  if (type == SQL_C_CHAR) {
5239  if (!p->lenp || *p->lenp == SQL_NTS) {
5240  p->len = p->max = strlen(p->param);
5241 #if defined(_WIN32) || defined(_WIN64)
5242  needalloc = 1;
5243 #endif
5244  } else if (*p->lenp >= 0) {
5245  p->len = p->max = *p->lenp;
5246  needalloc = 1;
5247  }
5248  }
5249  }
5250  if (p->need < 0 && p->parbuf == p->param) {
5251  break;
5252  }
5253 #ifdef WCHARSUPPORT
5254  if (type == SQL_C_WCHAR) {
5255  char *dp = uc_to_utf(p->param, p->max);
5256 
5257  if (!dp) {
5258  return nomem(s);
5259  }
5260  if (p->param == p->parbuf) {
5261  freep(&p->parbuf);
5262  }
5263  p->parbuf = p->param = dp;
5264  p->need = -1;
5265  p->len = strlen(p->param);
5266  p->s3val = p->param;
5267  p->s3size = p->len;
5268  } else
5269 #endif
5270  if (type == SQL_C_CHAR) {
5271  p->s3val = p->param;
5272  if (needalloc) {
5273  char *dp;
5274 
5275 #if defined(_WIN32) || defined(_WIN64)
5276  if (*s->oemcp) {
5277  dp = wmb_to_utf(p->param, p->len);
5278  } else {
5279  dp = xmalloc(p->len + 1);
5280  }
5281 #else
5282  dp = xmalloc(p->len + 1);
5283 #endif
5284  if (!dp) {
5285  return nomem(s);
5286  }
5287 #if defined(_WIN32) || defined(_WIN64)
5288  if (*s->oemcp) {
5289  p->len = strlen(dp);
5290  } else {
5291  memcpy(dp, p->param, p->len);
5292  dp[p->len] = '\0';
5293  }
5294 #else
5295  memcpy(dp, p->param, p->len);
5296  dp[p->len] = '\0';
5297 #endif
5298  if (p->param == p->parbuf) {
5299  freep(&p->parbuf);
5300  }
5301  p->parbuf = p->param = dp;
5302  p->need = -1;
5303  p->s3val = p->param;
5304  p->s3size = p->len;
5305  }
5306  }
5307  break;
5308  case SQL_C_UTINYINT:
5309  case SQL_C_TINYINT:
5310  case SQL_C_STINYINT:
5311  p->s3type = SQLITE_INTEGER;
5312  p->s3size = sizeof (int);
5313  p->s3ival = *((SQLCHAR *) p->param);
5314  break;
5315  case SQL_C_USHORT:
5316  p->s3type = SQLITE_INTEGER;
5317  p->s3size = sizeof (int);
5318  p->s3ival = *((SQLUSMALLINT *) p->param);
5319  break;
5320  case SQL_C_SHORT:
5321  case SQL_C_SSHORT:
5322  p->s3type = SQLITE_INTEGER;
5323  p->s3size = sizeof (int);
5324  p->s3ival = *((SQLSMALLINT *) p->param);
5325  break;
5326  case SQL_C_ULONG:
5327  p->s3type = SQLITE_INTEGER;
5328  p->s3size = sizeof (int);
5329  p->s3ival = *((SQLUINTEGER *) p->param);
5330  break;
5331  case SQL_C_LONG:
5332  case SQL_C_SLONG:
5333  p->s3type = SQLITE_INTEGER;
5334  p->s3size = sizeof (int);
5335  p->s3ival = *((SQLINTEGER *) p->param);
5336  break;
5337 #ifdef SQL_BIT
5338  case SQL_C_BIT:
5339  p->s3type = SQLITE_INTEGER;
5340  p->s3size = sizeof (int);
5341  p->s3ival = (*((SQLCHAR *) p->param)) ? 1 : 0;
5342  break;
5343 #endif
5344 #ifdef SQL_BIGINT
5345  case SQL_C_SBIGINT:
5346  p->s3type = SQLITE_INTEGER;
5347  p->s3size = sizeof (sqlite_int64);
5348  p->s3lival = *((sqlite_int64 *) p->param);
5349  break;
5350  case SQL_C_UBIGINT:
5351  p->s3type = SQLITE_INTEGER;
5352  p->s3size = sizeof (sqlite_int64);
5353  p->s3lival = *((sqlite_uint64 *) p->param);
5354  break;
5355 #endif
5356  case SQL_C_FLOAT:
5357  p->s3type = SQLITE_FLOAT;
5358  p->s3size = sizeof (double);
5359  p->s3dval = *((float *) p->param);
5360  break;
5361  case SQL_C_DOUBLE:
5362  p->s3type = SQLITE_FLOAT;
5363  p->s3size = sizeof (double);
5364  p->s3dval = *((double *) p->param);
5365  break;
5366 #ifdef SQL_C_TYPE_DATE
5367  case SQL_C_TYPE_DATE:
5368 #endif
5369  case SQL_C_DATE:
5370  if (*s->jdconv) {
5371  int a, b, x1, x2, y, m, d;
5372 
5373  p->s3type = SQLITE_FLOAT;
5374  p->s3size = sizeof (double);
5375  y = ((DATE_STRUCT *) p->param)->year;
5376  m = ((DATE_STRUCT *) p->param)->month;
5377  d = ((DATE_STRUCT *) p->param)->day;
5378  if (m <= 2) {
5379  y--;
5380  m += 12;
5381  }
5382  a = y / 100;
5383  b = 2 - a + (a / 4);
5384  x1 = 36525 * (y + 4716) / 100;
5385  x2 = 306001 * (m + 1) / 10000;
5386  p->s3dval = x1 + x2 + d + b - 1524.5;
5387  break;
5388  }
5389  sprintf(p->strbuf, "%04d-%02d-%02d",
5390  ((DATE_STRUCT *) p->param)->year,
5391  ((DATE_STRUCT *) p->param)->month,
5392  ((DATE_STRUCT *) p->param)->day);
5393  p->s3type = SQLITE_TEXT;
5394  p->s3size = -1;
5395  p->s3val = p->strbuf;
5396  break;
5397 #ifdef SQL_C_TYPE_TIME
5398  case SQL_C_TYPE_TIME:
5399 #endif
5400  case SQL_C_TIME:
5401  if (*s->jdconv) {
5402  p->s3type = SQLITE_FLOAT;
5403  p->s3size = sizeof (double);
5404  p->s3dval = 2451544.5 +
5405  (((TIME_STRUCT *) p->param)->hour * 3600000.0 +
5406  ((TIME_STRUCT *) p->param)->minute * 60000.0 +
5407  ((TIME_STRUCT *) p->param)->second * 1000.0) / 86400000.0;
5408  break;
5409  }
5410  sprintf(p->strbuf, "%02d:%02d:%02d",
5411  ((TIME_STRUCT *) p->param)->hour,
5412  ((TIME_STRUCT *) p->param)->minute,
5413  ((TIME_STRUCT *) p->param)->second);
5414  p->s3type = SQLITE_TEXT;
5415  p->s3size = -1;
5416  p->s3val = p->strbuf;
5417  break;
5418 #ifdef SQL_C_TYPE_TIMESTAMP
5419  case SQL_C_TYPE_TIMESTAMP:
5420 #endif
5421  case SQL_C_TIMESTAMP:
5422  if (*s->jdconv) {
5423  int a, b, x1, x2, y, m, d;
5424 
5425  p->s3type = SQLITE_FLOAT;
5426  p->s3size = sizeof (double);
5427  y = ((TIMESTAMP_STRUCT *) p->param)->year;
5428  m = ((TIMESTAMP_STRUCT *) p->param)->month;
5429  d = ((TIMESTAMP_STRUCT *) p->param)->day;
5430  if (m <= 2) {
5431  y--;
5432  m += 12;
5433  }
5434  a = y / 100;
5435  b = 2 - a + (a / 4);
5436  x1 = 36525 * (y + 4716) / 100;
5437  x2 = 306001 * (m + 1) / 10000;
5438  p->s3dval = x1 + x2 + d + b - 1524.5 +
5439  (((TIMESTAMP_STRUCT *) p->param)->hour * 3600000.0 +
5440  ((TIMESTAMP_STRUCT *) p->param)->minute * 60000.0 +
5441  ((TIMESTAMP_STRUCT *) p->param)->second * 1000.0 +
5442  ((TIMESTAMP_STRUCT *) p->param)->fraction / 1.0E6)
5443  / 86400000.0;
5444  break;
5445  }
5446  len = (int) ((TIMESTAMP_STRUCT *) p->param)->fraction;
5447  len /= 1000000;
5448  len = len % 1000;
5449  if (len < 0) {
5450  len = 0;
5451  }
5452  if (p->coldef && p->coldef <= 16) {
5453  sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
5454  ((TIMESTAMP_STRUCT *) p->param)->year,
5455  ((TIMESTAMP_STRUCT *) p->param)->month,
5456  ((TIMESTAMP_STRUCT *) p->param)->day,
5457  ((TIMESTAMP_STRUCT *) p->param)->hour,
5458  ((TIMESTAMP_STRUCT *) p->param)->minute);
5459  } else if (p->coldef && p->coldef <= 19) {
5460  sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
5461  ((TIMESTAMP_STRUCT *) p->param)->year,
5462  ((TIMESTAMP_STRUCT *) p->param)->month,
5463  ((TIMESTAMP_STRUCT *) p->param)->day,
5464  ((TIMESTAMP_STRUCT *) p->param)->hour,
5465  ((TIMESTAMP_STRUCT *) p->param)->minute,
5466  ((TIMESTAMP_STRUCT *) p->param)->second);
5467  } else {
5468  sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
5469  ((TIMESTAMP_STRUCT *) p->param)->year,
5470  ((TIMESTAMP_STRUCT *) p->param)->month,
5471  ((TIMESTAMP_STRUCT *) p->param)->day,
5472  ((TIMESTAMP_STRUCT *) p->param)->hour,
5473  ((TIMESTAMP_STRUCT *) p->param)->minute,
5474  ((TIMESTAMP_STRUCT *) p->param)->second,
5475  len);
5476  }
5477  p->s3type = SQLITE_TEXT;
5478  p->s3size = -1;
5479  p->s3val = p->strbuf;
5480  break;
5481  default:
5482  error:
5483  setstat(s, -1, "unsupported parameter type",
5484  (*s->ov3) ? "07009" : "S1093");
5485  return SQL_ERROR;
5486  }
5487  return SQL_SUCCESS;
5488 }
5489 
5505 static SQLRETURN
5506 drvbindparam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
5507  SQLSMALLINT buftype, SQLSMALLINT ptype, SQLUINTEGER coldef,
5508  SQLSMALLINT scale,
5509  SQLPOINTER data, SQLINTEGER buflen, SQLLEN *len)
5510 {
5511  STMT *s;
5512  BINDPARM *p;
5513 
5514  if (stmt == SQL_NULL_HSTMT) {
5515  return SQL_INVALID_HANDLE;
5516  }
5517  s = (STMT *) stmt;
5518  if (pnum == 0) {
5519  setstat(s, -1, "invalid parameter", (*s->ov3) ? "07009" : "S1093");
5520  return SQL_ERROR;
5521  }
5522  if (!data && !len) {
5523  setstat(s, -1, "invalid buffer", "HY003");
5524  return SQL_ERROR;
5525  }
5526  --pnum;
5527  if (s->bindparms) {
5528  if (pnum >= s->nbindparms) {
5529  BINDPARM *newparms;
5530 
5531  newparms = xrealloc(s->bindparms,
5532  (pnum + 1) * sizeof (BINDPARM));
5533  if (!newparms) {
5534 outofmem:
5535  return nomem(s);
5536  }
5537  s->bindparms = newparms;
5538  memset(&s->bindparms[s->nbindparms], 0,
5539  (pnum + 1 - s->nbindparms) * sizeof (BINDPARM));
5540  s->nbindparms = pnum + 1;
5541  }
5542  } else {
5543  int npar = max(10, pnum + 1);
5544 
5545  s->bindparms = xmalloc(npar * sizeof (BINDPARM));
5546  if (!s->bindparms) {
5547  goto outofmem;
5548  }
5549  memset(s->bindparms, 0, npar * sizeof (BINDPARM));
5550  s->nbindparms = npar;
5551  }
5552  switch (buftype) {
5553  case SQL_C_STINYINT:
5554  case SQL_C_UTINYINT:
5555  case SQL_C_TINYINT:
5556 #ifdef SQL_C_BIT
5557  case SQL_C_BIT:
5558 #endif
5559  buflen = sizeof (SQLCHAR);
5560  break;
5561  case SQL_C_SHORT:
5562  case SQL_C_USHORT:
5563  case SQL_C_SSHORT:
5564  buflen = sizeof (SQLSMALLINT);
5565  break;
5566  case SQL_C_SLONG:
5567  case SQL_C_ULONG:
5568  case SQL_C_LONG:
5569  buflen = sizeof (SQLINTEGER);
5570  break;
5571  case SQL_C_FLOAT:
5572  buflen = sizeof (float);
5573  break;
5574  case SQL_C_DOUBLE:
5575  buflen = sizeof (double);
5576  break;
5577  case SQL_C_TIMESTAMP:
5578 #ifdef SQL_C_TYPE_TIMESTAMP
5579  case SQL_C_TYPE_TIMESTAMP:
5580 #endif
5581  buflen = sizeof (TIMESTAMP_STRUCT);
5582  break;
5583  case SQL_C_TIME:
5584 #ifdef SQL_C_TYPE_TIME
5585  case SQL_C_TYPE_TIME:
5586 #endif
5587  buflen = sizeof (TIME_STRUCT);
5588  break;
5589  case SQL_C_DATE:
5590 #ifdef SQL_C_TYPE_DATE
5591  case SQL_C_TYPE_DATE:
5592 #endif
5593  buflen = sizeof (DATE_STRUCT);
5594  break;
5595 #ifdef SQL_C_UBIGINT
5596  case SQL_C_UBIGINT:
5597  buflen = sizeof (SQLBIGINT);
5598  break;
5599 #endif
5600 #ifdef SQL_C_SBIGINT
5601  case SQL_C_SBIGINT:
5602  buflen = sizeof (SQLBIGINT);
5603  break;
5604 #endif
5605 #ifdef SQL_C_BIGINT
5606  case SQL_C_BIGINT:
5607  buflen = sizeof (SQLBIGINT);
5608  break;
5609 #endif
5610  }
5611  p = &s->bindparms[pnum];
5612  p->type = buftype;
5613  p->stype = ptype;
5614  p->coldef = coldef;
5615  p->scale = scale;
5616  p->max = buflen;
5617  p->inc = buflen;
5618  p->lenp = p->lenp0 = len;
5619  p->offs = 0;
5620  p->len = 0;
5621  p->param0 = data;
5622  freep(&p->parbuf);
5623  p->param = p->param0;
5624  p->bound = 1;
5625  p->need = 0;
5626  return SQL_SUCCESS;
5627 }
5628 
5644 SQLRETURN SQL_API
5645 SQLBindParameter(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
5646  SQLSMALLINT buftype, SQLSMALLINT ptype, SQLULEN coldef,
5647  SQLSMALLINT scale,
5648  SQLPOINTER data, SQLLEN buflen, SQLLEN *len)
5649 {
5650  SQLRETURN ret;
5651 
5652  HSTMT_LOCK(stmt);
5653  ret = drvbindparam(stmt, pnum, iotype, buftype, ptype, coldef,
5654  scale, data, buflen, len);
5655  HSTMT_UNLOCK(stmt);
5656  return ret;
5657 }
5658 
5659 #ifndef HAVE_IODBC
5660 
5673 SQLRETURN SQL_API
5674 SQLBindParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT vtype,
5675  SQLSMALLINT ptype, SQLULEN lenprec,
5676  SQLSMALLINT scale, SQLPOINTER val,
5677  SQLLEN *lenp)
5678 {
5679  SQLRETURN ret;
5680 
5681  HSTMT_LOCK(stmt);
5682  ret = drvbindparam(stmt, pnum, SQL_PARAM_INPUT, vtype, ptype,
5683  lenprec, scale, val, 0, lenp);
5684  HSTMT_UNLOCK(stmt);
5685  return ret;
5686 }
5687 #endif
5688 
5696 SQLRETURN SQL_API
5697 SQLNumParams(SQLHSTMT stmt, SQLSMALLINT *nparam)
5698 {
5699  STMT *s;
5700  SQLSMALLINT dummy;
5701 
5702  HSTMT_LOCK(stmt);
5703  if (stmt == SQL_NULL_HSTMT) {
5704  return SQL_INVALID_HANDLE;
5705  }
5706  s = (STMT *) stmt;
5707  if (!nparam) {
5708  nparam = &dummy;
5709  }
5710  *nparam = s->nparams;
5711  HSTMT_UNLOCK(stmt);
5712  return SQL_SUCCESS;
5713 }
5714 
5722 static SQLRETURN
5724 {
5725  if (!p->parbuf) {
5726  if (*p->lenp == SQL_DATA_AT_EXEC) {
5727  p->len = p->max;
5728  } else {
5729  p->len = SQL_LEN_DATA_AT_EXEC(*p->lenp);
5730  }
5731  if (p->len < 0 && p->len != SQL_NTS &&
5732  p->len != SQL_NULL_DATA) {
5733  setstat(s, -1, "invalid length", "HY009");
5734  return SQL_ERROR;
5735  }
5736  if (p->len >= 0) {
5737  p->parbuf = xmalloc(p->len + 2);
5738  if (!p->parbuf) {
5739  return nomem(s);
5740  }
5741  p->param = p->parbuf;
5742  } else {
5743  p->param = NULL;
5744  }
5745  }
5746  return SQL_NEED_DATA;
5747 }
5748 
5756 SQLRETURN SQL_API
5757 SQLParamData(SQLHSTMT stmt, SQLPOINTER *pind)
5758 {
5759  STMT *s;
5760  int i;
5761  SQLPOINTER dummy;
5762  SQLRETURN ret;
5763  BINDPARM *p;
5764 
5765  HSTMT_LOCK(stmt);
5766  if (stmt == SQL_NULL_HSTMT) {
5767  return SQL_INVALID_HANDLE;
5768  }
5769  s = (STMT *) stmt;
5770  if (!pind) {
5771  pind = &dummy;
5772  }
5773  if (s->pdcount < s->nparams) {
5774  s->pdcount++;
5775  }
5776  for (i = 0; i < s->pdcount; i++) {
5777  p = &s->bindparms[i];
5778  if (p->need > 0) {
5779  int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
5780 
5781  p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR) ? -1 : 0;
5782  }
5783  }
5784  for (; i < s->nparams; i++) {
5785  p = &s->bindparms[i];
5786  if (p->need > 0) {
5787  *pind = (SQLPOINTER) p->param0;
5788  ret = setupparbuf(s, p);
5789  s->pdcount = i;
5790  goto done;
5791  }
5792  }
5793  ret = drvexecute(stmt, 0);
5794 done:
5795  HSTMT_UNLOCK(stmt);
5796  return ret;
5797 }
5798 
5810 SQLRETURN SQL_API
5811 SQLDescribeParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT *dtype,
5812  SQLULEN *size, SQLSMALLINT *decdigits, SQLSMALLINT *nullable)
5813 {
5814  STMT *s;
5815  SQLRETURN ret = SQL_ERROR;
5816 
5817  HSTMT_LOCK(stmt);
5818  if (stmt == SQL_NULL_HSTMT) {
5819  return SQL_INVALID_HANDLE;
5820  }
5821  s = (STMT *) stmt;
5822  --pnum;
5823  if (pnum >= s->nparams) {
5824  setstat(s, -1, "invalid parameter index",
5825  (*s->ov3) ? "HY000" : "S1000");
5826  goto done;
5827  }
5828  if (dtype) {
5829 #ifdef SQL_LONGVARCHAR
5830 #ifdef WINTERFACE
5831  *dtype = s->nowchar[0] ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
5832 #else
5833  *dtype = SQL_LONGVARCHAR;
5834 #endif
5835 #else
5836 #ifdef WINTERFACE
5837  *dtype = s->nowchar[0] ? SQL_VARCHAR : SQL_WVARCHAR;
5838 #else
5839  *dtype = SQL_VARCHAR;
5840 #endif
5841 #endif
5842  }
5843  if (size) {
5844 #ifdef SQL_LONGVARCHAR
5845  *size = 65536;
5846 #else
5847  *size = 255;
5848 #endif
5849  }
5850  if (decdigits) {
5851  *decdigits = 0;
5852  }
5853  if (nullable) {
5854  *nullable = SQL_NULLABLE;
5855  }
5856  ret = SQL_SUCCESS;
5857 done:
5858  HSTMT_UNLOCK(stmt);
5859  return ret;
5860 }
5861 
5875 SQLRETURN SQL_API
5876 SQLSetParam(SQLHSTMT stmt, SQLUSMALLINT par, SQLSMALLINT type,
5877  SQLSMALLINT sqltype, SQLULEN coldef,
5878  SQLSMALLINT scale, SQLPOINTER val, SQLLEN *nval)
5879 {
5880  SQLRETURN ret;
5881 
5882  HSTMT_LOCK(stmt);
5883  ret = drvbindparam(stmt, par, SQL_PARAM_INPUT,
5884  type, sqltype, coldef, scale, val,
5885  SQL_SETPARAM_VALUE_MAX, nval);
5886  HSTMT_UNLOCK(stmt);
5887  return ret;
5888 }
5889 
5894 SQLRETURN SQL_API
5895 SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
5896 {
5897  SQLRETURN ret;
5898 
5899  HSTMT_LOCK(stmt);
5900  ret = drvunimplstmt(stmt);
5901  HSTMT_UNLOCK(stmt);
5902  return ret;
5903 }
5904 
5905 #ifndef WINTERFACE
5906 
5910 SQLRETURN SQL_API
5911 SQLGetDescField(SQLHDESC handle, SQLSMALLINT recno,
5912  SQLSMALLINT fieldid, SQLPOINTER value,
5913  SQLINTEGER buflen, SQLINTEGER *strlen)
5914 {
5915  return SQL_ERROR;
5916 }
5917 #endif
5918 
5919 #ifdef WINTERFACE
5920 
5924 SQLRETURN SQL_API
5925 SQLGetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
5926  SQLSMALLINT fieldid, SQLPOINTER value,
5927  SQLINTEGER buflen, SQLINTEGER *strlen)
5928 {
5929  return SQL_ERROR;
5930 }
5931 #endif
5932 
5933 #ifndef WINTERFACE
5934 
5938 SQLRETURN SQL_API
5939 SQLSetDescField(SQLHDESC handle, SQLSMALLINT recno,
5940  SQLSMALLINT fieldid, SQLPOINTER value,
5941  SQLINTEGER buflen)
5942 {
5943  return SQL_ERROR;
5944 }
5945 #endif
5946 
5947 #ifdef WINTERFACE
5948 
5952 SQLRETURN SQL_API
5953 SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
5954  SQLSMALLINT fieldid, SQLPOINTER value,
5955  SQLINTEGER buflen)
5956 {
5957  return SQL_ERROR;
5958 }
5959 #endif
5960 
5961 #ifndef WINTERFACE
5962 
5966 SQLRETURN SQL_API
5967 SQLGetDescRec(SQLHDESC handle, SQLSMALLINT recno,
5968  SQLCHAR *name, SQLSMALLINT buflen,
5969  SQLSMALLINT *strlen, SQLSMALLINT *type,
5970  SQLSMALLINT *subtype, SQLLEN *len,
5971  SQLSMALLINT *prec, SQLSMALLINT *scale,
5972  SQLSMALLINT *nullable)
5973 {
5974  return SQL_ERROR;
5975 }
5976 #endif
5977 
5978 #ifdef WINTERFACE
5979 
5983 SQLRETURN SQL_API
5984 SQLGetDescRecW(SQLHDESC handle, SQLSMALLINT recno,
5985  SQLWCHAR *name, SQLSMALLINT buflen,
5986  SQLSMALLINT *strlen, SQLSMALLINT *type,
5987  SQLSMALLINT *subtype, SQLLEN *len,
5988  SQLSMALLINT *prec, SQLSMALLINT *scale,
5989  SQLSMALLINT *nullable)
5990 {
5991  return SQL_ERROR;
5992 }
5993 #endif
5994 
5999 SQLRETURN SQL_API
6000 SQLSetDescRec(SQLHDESC handle, SQLSMALLINT recno,
6001  SQLSMALLINT type, SQLSMALLINT subtype,
6002  SQLLEN len, SQLSMALLINT prec,
6003  SQLSMALLINT scale, SQLPOINTER data,
6004  SQLLEN *strlen, SQLLEN *indicator)
6005 {
6006  return SQL_ERROR;
6007 }
6008 
6020 static SQLRETURN
6021 mkresultset(HSTMT stmt, COL *colspec, int ncols, COL *colspec3,
6022  int ncols3, int *nret)
6023 {
6024  STMT *s;
6025  DBC *d;
6026 
6027  if (stmt == SQL_NULL_HSTMT) {
6028  return SQL_INVALID_HANDLE;
6029  }
6030  s = (STMT *) stmt;
6031  if (s->dbc == SQL_NULL_HDBC) {
6032 noconn:
6033  return noconn(s);
6034  }
6035  d = (DBC *) s->dbc;
6036  if (!d->sqlite) {
6037  goto noconn;
6038  }
6039  s3stmt_end_if(s);
6040  freeresult(s, 0);
6041  if (colspec3 && *s->ov3) {
6042  s->ncols = ncols3;
6043  s->cols = colspec3;
6044  } else {
6045  s->ncols = ncols;
6046  s->cols = colspec;
6047  }
6048  mkbindcols(s, s->ncols);
6049  s->nowchar[1] = 1;
6050  s->nrows = 0;
6051  s->rowp = s->rowprs = -1;
6052  s->isselect = -1;
6053  if (nret) {
6054  *nret = s->ncols;
6055  }
6056  return SQL_SUCCESS;
6057 }
6058 
6063 static COL tablePrivSpec2[] = {
6064  { "SYSTEM", "TABLEPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
6065  { "SYSTEM", "TABLEPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
6066  { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6067  { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6068  { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6069  { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
6070  { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
6071 };
6072 
6073 static COL tablePrivSpec3[] = {
6074  { "SYSTEM", "TABLEPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
6075  { "SYSTEM", "TABLEPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
6076  { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6077  { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6078  { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6079  { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
6080  { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
6081 };
6082 
6095 static SQLRETURN
6097  SQLCHAR *cat, SQLSMALLINT catLen,
6098  SQLCHAR *schema, SQLSMALLINT schemaLen,
6099  SQLCHAR *table, SQLSMALLINT tableLen)
6100 {
6101  SQLRETURN ret;
6102  STMT *s;
6103  DBC *d;
6104  int ncols, rc, size, npatt;
6105  char *errp = NULL, *sql, tname[512];
6106 
6109  if (ret != SQL_SUCCESS) {
6110  return ret;
6111  }
6112  s = (STMT *) stmt;
6113  d = (DBC *) s->dbc;
6114  if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
6115  table = NULL;
6116  goto doit;
6117  }
6118  if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
6119  schema[0] == '%') {
6120  if ((!cat || catLen == 0 || !cat[0]) &&
6121  (!table || tableLen == 0 || !table[0])) {
6122  table = NULL;
6123  goto doit;
6124  }
6125  }
6126 doit:
6127  if (!table) {
6128  size = 1;
6129  tname[0] = '%';
6130  } else {
6131  if (tableLen == SQL_NTS) {
6132  size = sizeof (tname) - 1;
6133  } else {
6134  size = min(sizeof (tname) - 1, tableLen);
6135  }
6136  strncpy(tname, (char *) table, size);
6137  }
6138  tname[size] = '\0';
6139  npatt = unescpat(tname);
6140 #if defined(_WIN32) || defined(_WIN64)
6141  if (npatt) {
6142  sql = sqlite3_mprintf("select %s as 'TABLE_QUALIFIER', "
6143  "%s as 'TABLE_OWNER', "
6144  "tbl_name as 'TABLE_NAME', "
6145  "'' as 'GRANTOR', "
6146  "'' as 'GRANTEE', "
6147  "'SELECT' AS 'PRIVILEGE', "
6148  "NULL as 'IS_GRANTABLE' "
6149  "from sqlite_master where "
6150  "(type = 'table' or type = 'view') "
6151  "and tbl_name like %Q "
6152  "UNION "
6153  "select %s as 'TABLE_QUALIFIER', "
6154  "%s as 'TABLE_OWNER', "
6155  "tbl_name as 'TABLE_NAME', "
6156  "'' as 'GRANTOR', "
6157  "'' as 'GRANTEE', "
6158  "'UPDATE' AS 'PRIVILEGE', "
6159  "NULL as 'IS_GRANTABLE' "
6160  "from sqlite_master where "
6161  "(type = 'table' or type = 'view') "
6162  "and tbl_name like %Q "
6163  "UNION "
6164  "select %s as 'TABLE_QUALIFIER', "
6165  "%s as 'TABLE_OWNER', "
6166  "tbl_name as 'TABLE_NAME', "
6167  "'' as 'GRANTOR', "
6168  "'' as 'GRANTEE', "
6169  "'DELETE' AS 'PRIVILEGE', "
6170  "NULL as 'IS_GRANTABLE' "
6171  "from sqlite_master where "
6172  "(type = 'table' or type = 'view') "
6173  "and tbl_name like %Q "
6174  "UNION "
6175  "select %s as 'TABLE_QUALIFIER', "
6176  "%s as 'TABLE_OWNER', "
6177  "tbl_name as 'TABLE_NAME', "
6178  "'' as 'GRANTOR', "
6179  "'' as 'GRANTEE', "
6180  "'INSERT' AS 'PRIVILEGE', "
6181  "NULL as 'IS_GRANTABLE' "
6182  "from sqlite_master where "
6183  "(type = 'table' or type = 'view') "
6184  "and tbl_name like %Q "
6185  "UNION "
6186  "select %s as 'TABLE_QUALIFIER', "
6187  "%s as 'TABLE_OWNER', "
6188  "tbl_name as 'TABLE_NAME', "
6189  "'' as 'GRANTOR', "
6190  "'' as 'GRANTEE', "
6191  "'REFERENCES' AS 'PRIVILEGE', "
6192  "NULL as 'IS_GRANTABLE' "
6193  "from sqlite_master where "
6194  "(type = 'table' or type = 'view') "
6195  "and tbl_name like %Q",
6196  d->xcelqrx ? "'main'" : "NULL",
6197  d->xcelqrx ? "''" : "NULL",
6198  tname,
6199  d->xcelqrx ? "'main'" : "NULL",
6200  d->xcelqrx ? "''" : "NULL",
6201  tname,
6202  d->xcelqrx ? "'main'" : "NULL",
6203  d->xcelqrx ? "''" : "NULL",
6204  tname,
6205  d->xcelqrx ? "'main'" : "NULL",
6206  d->xcelqrx ? "''" : "NULL",
6207  tname,
6208  d->xcelqrx ? "'main'" : "NULL",
6209  d->xcelqrx ? "''" : "NULL",
6210  tname);
6211  } else {
6212  sql = sqlite3_mprintf("select %s as 'TABLE_QUALIFIER', "
6213  "%s as 'TABLE_OWNER', "
6214  "tbl_name as 'TABLE_NAME', "
6215  "'' as 'GRANTOR', "
6216  "'' as 'GRANTEE', "
6217  "'SELECT' AS 'PRIVILEGE', "
6218  "NULL as 'IS_GRANTABLE' "
6219  "from sqlite_master where "
6220  "(type = 'table' or type = 'view') "
6221  "and lower(tbl_name) = lower(%Q) "
6222  "UNION "
6223  "select %s as 'TABLE_QUALIFIER', "
6224  "%s as 'TABLE_OWNER', "
6225  "tbl_name as 'TABLE_NAME', "
6226  "'' as 'GRANTOR', "
6227  "'' as 'GRANTEE', "
6228  "'UPDATE' AS 'PRIVILEGE', "
6229  "NULL as 'IS_GRANTABLE' "
6230  "from sqlite_master where "
6231  "(type = 'table' or type = 'view') "
6232  "and lower(tbl_name) = lower(%Q) "
6233  "UNION "
6234  "select %s as 'TABLE_QUALIFIER', "
6235  "%s as 'TABLE_OWNER', "
6236  "tbl_name as 'TABLE_NAME', "
6237  "'' as 'GRANTOR', "
6238  "'' as 'GRANTEE', "
6239  "'DELETE' AS 'PRIVILEGE', "
6240  "NULL as 'IS_GRANTABLE' "
6241  "from sqlite_master where "
6242  "(type = 'table' or type = 'view') "
6243  "and lower(tbl_name) = lower(%Q) "
6244  "UNION "
6245  "select %s as 'TABLE_QUALIFIER', "
6246  "%s as 'TABLE_OWNER', "
6247  "tbl_name as 'TABLE_NAME', "
6248  "'' as 'GRANTOR', "
6249  "'' as 'GRANTEE', "
6250  "'INSERT' AS 'PRIVILEGE', "
6251  "NULL as 'IS_GRANTABLE' "
6252  "from sqlite_master where "
6253  "(type = 'table' or type = 'view') "
6254  "and lower(tbl_name) = lower(%Q) "
6255  "UNION "
6256  "select %s as 'TABLE_QUALIFIER', "
6257  "%s as 'TABLE_OWNER', "
6258  "tbl_name as 'TABLE_NAME', "
6259  "'' as 'GRANTOR', "
6260  "'' as 'GRANTEE', "
6261  "'REFERENCES' AS 'PRIVILEGE', "
6262  "NULL as 'IS_GRANTABLE' "
6263  "from sqlite_master where "
6264  "(type = 'table' or type = 'view') "
6265  "and lower(tbl_name) = lower(%Q)",
6266  d->xcelqrx ? "'main'" : "NULL",
6267  d->xcelqrx ? "''" : "NULL",
6268  tname,
6269  d->xcelqrx ? "'main'" : "NULL",
6270  d->xcelqrx ? "''" : "NULL",
6271  tname,
6272  d->xcelqrx ? "'main'" : "NULL",
6273  d->xcelqrx ? "''" : "NULL",
6274  tname,
6275  d->xcelqrx ? "'main'" : "NULL",
6276  d->xcelqrx ? "''" : "NULL",
6277  tname,
6278  d->xcelqrx ? "'main'" : "NULL",
6279  d->xcelqrx ? "''" : "NULL",
6280  tname);
6281  }
6282 #else
6283  if (npatt) {
6284  sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
6285  "NULL as 'TABLE_OWNER', "
6286  "tbl_name as 'TABLE_NAME', "
6287  "'' as 'GRANTOR', "
6288  "'' as 'GRANTEE', "
6289  "'SELECT' AS 'PRIVILEGE', "
6290  "NULL as 'IS_GRANTABLE' "
6291  "from sqlite_master where "
6292  "(type = 'table' or type = 'view') "
6293  "and tbl_name like %Q "
6294  "UNION "
6295  "select NULL as 'TABLE_QUALIFIER', "
6296  "NULL as 'TABLE_OWNER', "
6297  "tbl_name as 'TABLE_NAME', "
6298  "'' as 'GRANTOR', "
6299  "'' as 'GRANTEE', "
6300  "'UPDATE' AS 'PRIVILEGE', "
6301  "NULL as 'IS_GRANTABLE' "
6302  "from sqlite_master where "
6303  "(type = 'table' or type = 'view') "
6304  "and tbl_name like %Q "
6305  "UNION "
6306  "select NULL as 'TABLE_QUALIFIER', "
6307  "NULL as 'TABLE_OWNER', "
6308  "tbl_name as 'TABLE_NAME', "
6309  "'' as 'GRANTOR', "
6310  "'' as 'GRANTEE', "
6311  "'DELETE' AS 'PRIVILEGE', "
6312  "NULL as 'IS_GRANTABLE' "
6313  "from sqlite_master where "
6314  "(type = 'table' or type = 'view') "
6315  "and tbl_name like %Q "
6316  "UNION "
6317  "select NULL as 'TABLE_QUALIFIER', "
6318  "NULL as 'TABLE_OWNER', "
6319  "tbl_name as 'TABLE_NAME', "
6320  "'' as 'GRANTOR', "
6321  "'' as 'GRANTEE', "
6322  "'INSERT' AS 'PRIVILEGE', "
6323  "NULL as 'IS_GRANTABLE' "
6324  "from sqlite_master where "
6325  "(type = 'table' or type = 'view') "
6326  "and tbl_name like %Q "
6327  "UNION "
6328  "select NULL as 'TABLE_QUALIFIER', "
6329  "NULL as 'TABLE_OWNER', "
6330  "tbl_name as 'TABLE_NAME', "
6331  "'' as 'GRANTOR', "
6332  "'' as 'GRANTEE', "
6333  "'REFERENCES' AS 'PRIVILEGE', "
6334  "NULL as 'IS_GRANTABLE' "
6335  "from sqlite_master where "
6336  "(type = 'table' or type = 'view') "
6337  "and tbl_name like %Q",
6338  tname, tname, tname, tname, tname);
6339  } else {
6340  sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
6341  "NULL as 'TABLE_OWNER', "
6342  "tbl_name as 'TABLE_NAME', "
6343  "'' as 'GRANTOR', "
6344  "'' as 'GRANTEE', "
6345  "'SELECT' AS 'PRIVILEGE', "
6346  "NULL as 'IS_GRANTABLE' "
6347  "from sqlite_master where "
6348  "(type = 'table' or type = 'view') "
6349  "and lower(tbl_name) = lower(%Q) "
6350  "UNION "
6351  "select NULL as 'TABLE_QUALIFIER', "
6352  "NULL as 'TABLE_OWNER', "
6353  "tbl_name as 'TABLE_NAME', "
6354  "'' as 'GRANTOR', "
6355  "'' as 'GRANTEE', "
6356  "'UPDATE' AS 'PRIVILEGE', "
6357  "NULL as 'IS_GRANTABLE' "
6358  "from sqlite_master where "
6359  "(type = 'table' or type = 'view') "
6360  "and lower(tbl_name) = lower(%Q) "
6361  "UNION "
6362  "select NULL as 'TABLE_QUALIFIER', "
6363  "NULL as 'TABLE_OWNER', "
6364  "tbl_name as 'TABLE_NAME', "
6365  "'' as 'GRANTOR', "
6366  "'' as 'GRANTEE', "
6367  "'DELETE' AS 'PRIVILEGE', "
6368  "NULL as 'IS_GRANTABLE' "
6369  "from sqlite_master where "
6370  "(type = 'table' or type = 'view') "
6371  "and lower(tbl_name) = lower(%Q) "
6372  "UNION "
6373  "select NULL as 'TABLE_QUALIFIER', "
6374  "NULL as 'TABLE_OWNER', "
6375  "tbl_name as 'TABLE_NAME', "
6376  "'' as 'GRANTOR', "
6377  "'' as 'GRANTEE', "
6378  "'INSERT' AS 'PRIVILEGE', "
6379  "NULL as 'IS_GRANTABLE' "
6380  "from sqlite_master where "
6381  "(type = 'table' or type = 'view') "
6382  "and lower(tbl_name) = lower(%Q) "
6383  "UNION "
6384  "select NULL as 'TABLE_QUALIFIER', "
6385  "NULL as 'TABLE_OWNER', "
6386  "tbl_name as 'TABLE_NAME', "
6387  "'' as 'GRANTOR', "
6388  "'' as 'GRANTEE', "
6389  "'REFERENCES' AS 'PRIVILEGE', "
6390  "NULL as 'IS_GRANTABLE' "
6391  "from sqlite_master where "
6392  "(type = 'table' or type = 'view') "
6393  "and lower(tbl_name) = lower(%Q)",
6394  tname, tname, tname, tname, tname);
6395  }
6396 #endif
6397  if (!sql) {
6398  return nomem(s);
6399  }
6400  ret = starttran(s);
6401  if (ret != SQL_SUCCESS) {
6402  sqlite3_free(sql);
6403  return ret;
6404  }
6405  dbtraceapi(d, "sqlite3_get_table", sql);
6406  rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
6407  sqlite3_free(sql);
6408  if (rc == SQLITE_OK) {
6409  if (ncols != s->ncols) {
6410  freeresult(s, 0);
6411  s->nrows = 0;
6412  } else {
6413  s->rowfree = sqlite3_free_table;
6414  }
6415  } else {
6416  s->nrows = 0;
6417  s->rows = NULL;
6418  s->rowfree = NULL;
6419  }
6420  if (errp) {
6421  sqlite3_free(errp);
6422  errp = NULL;
6423  }
6424  s->rowp = s->rowprs = -1;
6425  return SQL_SUCCESS;
6426 }
6427 
6428 
6429 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
6430 
6442 SQLRETURN SQL_API
6443 SQLTablePrivileges(SQLHSTMT stmt,
6444  SQLCHAR *catalog, SQLSMALLINT catalogLen,
6445  SQLCHAR *schema, SQLSMALLINT schemaLen,
6446  SQLCHAR *table, SQLSMALLINT tableLen)
6447 {
6448 #if defined(_WIN32) || defined(_WIN64)
6449  char *c = NULL, *s = NULL, *t = NULL;
6450 #endif
6451  SQLRETURN ret;
6452 
6453  HSTMT_LOCK(stmt);
6454 #if defined(_WIN32) || defined(_WIN64)
6455  if (!((STMT *) stmt)->oemcp[0]) {
6456  ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
6457  table, tableLen);
6458  goto done2;
6459  }
6460  if (catalog) {
6461  c = wmb_to_utf_c((char *) catalog, catalogLen);
6462  if (!c) {
6463  ret = nomem((STMT *) stmt);
6464  goto done;
6465  }
6466  }
6467  if (schema) {
6468  s = wmb_to_utf_c((char *) schema, schemaLen);
6469  if (!s) {
6470  ret = nomem((STMT *) stmt);
6471  goto done;
6472  }
6473  }
6474  if (table) {
6475  t = wmb_to_utf_c((char *) table, tableLen);
6476  if (!t) {
6477  ret = nomem((STMT *) stmt);
6478  goto done;
6479  }
6480  }
6481  ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
6482  (SQLCHAR *) s, SQL_NTS,
6483  (SQLCHAR *) t, SQL_NTS);
6484 #else
6485  ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
6486  table, tableLen);
6487 #endif
6488 #if defined(_WIN32) || defined(_WIN64)
6489 done:
6490  uc_free(t);
6491  uc_free(s);
6492  uc_free(c);
6493 done2:
6494  ;
6495 #endif
6496  HSTMT_UNLOCK(stmt);
6497  return ret;
6498 }
6499 #endif
6500 
6501 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
6502 #ifdef WINTERFACE
6503 
6515 SQLRETURN SQL_API
6517  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
6518  SQLWCHAR *schema, SQLSMALLINT schemaLen,
6519  SQLWCHAR *table, SQLSMALLINT tableLen)
6520 {
6521  char *c = NULL, *s = NULL, *t = NULL;
6522  SQLRETURN ret;
6523 
6524  HSTMT_LOCK(stmt);
6525  if (catalog) {
6526  c = uc_to_utf_c(catalog, catalogLen);
6527  if (!c) {
6528  ret = nomem((STMT *) stmt);
6529  goto done;
6530  }
6531  }
6532  if (schema) {
6533  s = uc_to_utf_c(schema, schemaLen);
6534  if (!s) {
6535  ret = nomem((STMT *) stmt);
6536  goto done;
6537  }
6538  }
6539  if (table) {
6540  t = uc_to_utf_c(table, tableLen);
6541  if (!t) {
6542  ret = nomem((STMT *) stmt);
6543  goto done;
6544  }
6545  }
6546  ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
6547  (SQLCHAR *) s, SQL_NTS,
6548  (SQLCHAR *) t, SQL_NTS);
6549 done:
6550  uc_free(t);
6551  uc_free(s);
6552  uc_free(c);
6553  HSTMT_UNLOCK(stmt);
6554  return ret;
6555 }
6556 #endif
6557 #endif
6558 
6563 static COL colPrivSpec2[] = {
6564  { "SYSTEM", "COLPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
6565  { "SYSTEM", "COLPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
6566  { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6567  { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6568  { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6569  { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6570  { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
6571 };
6572 
6573 static COL colPrivSpec3[] = {
6574  { "SYSTEM", "COLPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
6575  { "SYSTEM", "COLPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
6576  { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6577  { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6578  { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6579  { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6580  { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
6581 };
6582 
6583 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
6584 
6598 SQLRETURN SQL_API
6599 SQLColumnPrivileges(SQLHSTMT stmt,
6600  SQLCHAR *catalog, SQLSMALLINT catalogLen,
6601  SQLCHAR *schema, SQLSMALLINT schemaLen,
6602  SQLCHAR *table, SQLSMALLINT tableLen,
6603  SQLCHAR *column, SQLSMALLINT columnLen)
6604 {
6605  SQLRETURN ret;
6606 
6607  HSTMT_LOCK(stmt);
6610  HSTMT_UNLOCK(stmt);
6611  return ret;
6612 }
6613 #endif
6614 
6615 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
6616 #ifdef WINTERFACE
6617 
6631 SQLRETURN SQL_API
6633  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
6634  SQLWCHAR *schema, SQLSMALLINT schemaLen,
6635  SQLWCHAR *table, SQLSMALLINT tableLen,
6636  SQLWCHAR *column, SQLSMALLINT columnLen)
6637 {
6638  SQLRETURN ret;
6639 
6640  HSTMT_LOCK(stmt);
6643  HSTMT_UNLOCK(stmt);
6644  return ret;
6645 }
6646 #endif
6647 #endif
6648 
6653 static COL pkeySpec2[] = {
6654  { "SYSTEM", "PRIMARYKEY", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
6655  { "SYSTEM", "PRIMARYKEY", "TABLE_OWNER", SCOL_VARCHAR, 50 },
6656  { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
6657  { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6658  { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
6659  { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
6660 };
6661 
6662 static COL pkeySpec3[] = {
6663  { "SYSTEM", "PRIMARYKEY", "TABLE_CAT", SCOL_VARCHAR, 50 },
6664  { "SYSTEM", "PRIMARYKEY", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
6665  { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
6666  { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6667  { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
6668  { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
6669 };
6670 
6683 static SQLRETURN
6685  SQLCHAR *cat, SQLSMALLINT catLen,
6686  SQLCHAR *schema, SQLSMALLINT schemaLen,
6687  SQLCHAR *table, SQLSMALLINT tableLen)
6688 {
6689  STMT *s;
6690  DBC *d;
6691  SQLRETURN sret;
6692  int i, asize, ret, nrows, ncols, nrows2 = 0, ncols2 = 0;
6693  int namec = -1, uniquec = -1, namec2 = -1, uniquec2 = -1, offs, seq = 1;
6694  PTRDIFF_T size;
6695  char **rowp = NULL, **rowp2 = NULL, *errp = NULL, *sql, tname[512];
6696 
6698  pkeySpec3, array_size(pkeySpec3), &asize);
6699  if (sret != SQL_SUCCESS) {
6700  return sret;
6701  }
6702  s = (STMT *) stmt;
6703  d = (DBC *) s->dbc;
6704  if (!table || table[0] == '\0' || table[0] == '%') {
6705  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
6706  return SQL_ERROR;
6707  }
6708  if (tableLen == SQL_NTS) {
6709  size = sizeof (tname) - 1;
6710  } else {
6711  size = min(sizeof (tname) - 1, tableLen);
6712  }
6713  strncpy(tname, (char *) table, size);
6714  tname[size] = '\0';
6715  unescpat(tname);
6716  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
6717  if (!sql) {
6718  return nomem(s);
6719  }
6720  sret = starttran(s);
6721  if (sret != SQL_SUCCESS) {
6722  sqlite3_free(sql);
6723  return sret;
6724  }
6725  dbtraceapi(d, "sqlite3_get_table", sql);
6726  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
6727  sqlite3_free(sql);
6728  if (ret != SQLITE_OK) {
6729  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6730  errp ? errp : "unknown error", ret);
6731  if (errp) {
6732  sqlite3_free(errp);
6733  errp = NULL;
6734  }
6735  return SQL_ERROR;
6736  }
6737  if (errp) {
6738  sqlite3_free(errp);
6739  errp = NULL;
6740  }
6741  size = 0;
6742  if (ncols * nrows > 0) {
6743  int typec;
6744 
6745  namec = findcol(rowp, ncols, "name");
6746  uniquec = findcol(rowp, ncols, "pk");
6747  typec = findcol(rowp, ncols, "type");
6748  if (namec >= 0 && uniquec >= 0 && typec >= 0) {
6749  for (i = 1; i <= nrows; i++) {
6750  if (*rowp[i * ncols + uniquec] != '0') {
6751  size++;
6752  }
6753  }
6754  }
6755  }
6756  if (size == 0) {
6757  sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
6758  if (!sql) {
6759  sqlite3_free_table(rowp);
6760  return nomem(s);
6761  }
6762  dbtraceapi(d, "sqlite3_get_table", sql);
6763  ret = sqlite3_get_table(d->sqlite, sql, &rowp2, &nrows2, &ncols2,
6764  &errp);
6765  sqlite3_free(sql);
6766  if (ret != SQLITE_OK) {
6767  sqlite3_free_table(rowp);
6768  sqlite3_free_table(rowp2);
6769  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6770  errp ? errp : "unknown error", ret);
6771  if (errp) {
6772  sqlite3_free(errp);
6773  errp = NULL;
6774  }
6775  return SQL_ERROR;
6776  }
6777  if (errp) {
6778  sqlite3_free(errp);
6779  errp = NULL;
6780  }
6781  }
6782  if (ncols2 * nrows2 > 0) {
6783  namec2 = findcol(rowp2, ncols2, "name");
6784  uniquec2 = findcol(rowp2, ncols2, "unique");
6785  if (namec2 >= 0 && uniquec2 >= 0) {
6786  for (i = 1; i <= nrows2; i++) {
6787  int nnrows, nncols, nlen = 0;
6788  char **rowpp;
6789 
6790  if (rowp2[i * ncols2 + namec2]) {
6791  nlen = strlen(rowp2[i * ncols2 + namec2]);
6792  }
6793  if (nlen < 17 ||
6794  strncmp(rowp2[i * ncols2 + namec2],
6795  "sqlite_autoindex_", 17)) {
6796  continue;
6797  }
6798  if (*rowp2[i * ncols2 + uniquec2] != '0') {
6799  ret = SQLITE_ERROR;
6800  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6801  rowp2[i * ncols2 + namec2]);
6802  if (sql) {
6803  dbtraceapi(d, "sqlite3_get_table", sql);
6804  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6805  &nnrows, &nncols, NULL);
6806  sqlite3_free(sql);
6807  }
6808  if (ret == SQLITE_OK) {
6809  size += nnrows;
6810  sqlite3_free_table(rowpp);
6811  }
6812  }
6813  }
6814  }
6815  }
6816  if (size == 0) {
6817  sqlite3_free_table(rowp);
6818  sqlite3_free_table(rowp2);
6819  return SQL_SUCCESS;
6820  }
6821  s->nrows = size;
6822  size = (size + 1) * asize;
6823  s->rows = xmalloc((size + 1) * sizeof (char *));
6824  if (!s->rows) {
6825  s->nrows = 0;
6826  sqlite3_free_table(rowp);
6827  sqlite3_free_table(rowp2);
6828  return nomem(s);
6829  }
6830  s->rows[0] = (char *) size;
6831  s->rows += 1;
6832  memset(s->rows, 0, sizeof (char *) * size);
6833  s->rowfree = freerows;
6834  offs = s->ncols;
6835  if (rowp) {
6836  for (i = 1; i <= nrows; i++) {
6837  if (*rowp[i * ncols + uniquec] != '0') {
6838  char buf[32];
6839 
6840 #if defined(_WIN32) || defined(_WIN64)
6841  s->rows[offs + 0] = xstrdup(d->xcelqrx ? "main" : "");
6842  s->rows[offs + 1] = xstrdup("");
6843 #else
6844  s->rows[offs + 0] = xstrdup("");
6845  s->rows[offs + 1] = xstrdup("");
6846 #endif
6847  s->rows[offs + 2] = xstrdup(tname);
6848  s->rows[offs + 3] = xstrdup(rowp[i * ncols + namec]);
6849  sprintf(buf, "%d", seq++);
6850  s->rows[offs + 4] = xstrdup(buf);
6851  offs += s->ncols;
6852  }
6853  }
6854  }
6855  if (rowp2) {
6856  for (i = 1; i <= nrows2; i++) {
6857  int nnrows, nncols, nlen = 0;
6858  char **rowpp;
6859 
6860  if (rowp2[i * ncols2 + namec2]) {
6861  nlen = strlen(rowp2[i * ncols2 + namec2]);
6862  }
6863  if (nlen < 17 ||
6864  strncmp(rowp2[i * ncols2 + namec2], "sqlite_autoindex_", 17)) {
6865  continue;
6866  }
6867  if (*rowp2[i * ncols2 + uniquec2] != '0') {
6868  int k;
6869 
6870  ret = SQLITE_ERROR;
6871  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6872  rowp2[i * ncols2 + namec2]);
6873  if (sql) {
6874  dbtraceapi(d, "sqlite3_get_table", sql);
6875  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6876  &nnrows, &nncols, NULL);
6877  sqlite3_free(sql);
6878  }
6879  if (ret != SQLITE_OK) {
6880  continue;
6881  }
6882  for (k = 0; nnrows && k < nncols; k++) {
6883  if (strcmp(rowpp[k], "name") == 0) {
6884  int m;
6885 
6886  for (m = 1; m <= nnrows; m++) {
6887  int roffs = offs + (m - 1) * s->ncols;
6888 
6889 #if defined(_WIN32) || defined(_WIN64)
6890  s->rows[roffs + 0] =
6891  xstrdup(d->xcelqrx ? "main" : "");
6892  s->rows[roffs + 1] = xstrdup("");
6893 #else
6894  s->rows[roffs + 0] = xstrdup("");
6895  s->rows[roffs + 1] = xstrdup("");
6896 #endif
6897  s->rows[roffs + 2] = xstrdup(tname);
6898  s->rows[roffs + 3] =
6899  xstrdup(rowpp[m * nncols + k]);
6900  s->rows[roffs + 5] =
6901  xstrdup(rowp2[i * ncols2 + namec2]);
6902  }
6903  } else if (strcmp(rowpp[k], "seqno") == 0) {
6904  int m;
6905 
6906  for (m = 1; m <= nnrows; m++) {
6907  int roffs = offs + (m - 1) * s->ncols;
6908  int pos = m - 1;
6909  char buf[32];
6910 
6911  sscanf(rowpp[m * nncols + k], "%d", &pos);
6912  sprintf(buf, "%d", pos + 1);
6913  s->rows[roffs + 4] = xstrdup(buf);
6914  }
6915  }
6916  }
6917  offs += nnrows * s->ncols;
6918  sqlite3_free_table(rowpp);
6919  }
6920  }
6921  }
6922  sqlite3_free_table(rowp);
6923  sqlite3_free_table(rowp2);
6924  return SQL_SUCCESS;
6925 }
6926 
6927 #ifndef WINTERFACE
6928 
6940 SQLRETURN SQL_API
6941 SQLPrimaryKeys(SQLHSTMT stmt,
6942  SQLCHAR *cat, SQLSMALLINT catLen,
6943  SQLCHAR *schema, SQLSMALLINT schemaLen,
6944  SQLCHAR *table, SQLSMALLINT tableLen)
6945 {
6946 #if defined(_WIN32) || defined(_WIN64)
6947  char *c = NULL, *s = NULL, *t = NULL;
6948 #endif
6949  SQLRETURN ret;
6950 
6951  HSTMT_LOCK(stmt);
6952 #if defined(_WIN32) || defined(_WIN64)
6953  if (!((STMT *) stmt)->oemcp[0]) {
6954  ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
6955  table, tableLen);
6956  goto done2;
6957  }
6958  if (cat) {
6959  c = wmb_to_utf_c((char *) cat, catLen);
6960  if (!c) {
6961  ret = nomem((STMT *) stmt);
6962  goto done;
6963  }
6964  }
6965  if (schema) {
6966  s = wmb_to_utf_c((char *) schema, schemaLen);
6967  if (!s) {
6968  ret = nomem((STMT *) stmt);
6969  goto done;
6970  }
6971  }
6972  if (table) {
6973  t = wmb_to_utf_c((char *) table, tableLen);
6974  if (!t) {
6975  ret = nomem((STMT *) stmt);
6976  goto done;
6977  }
6978  }
6979  ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
6980  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
6981 #else
6982  ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
6983  table, tableLen);
6984 #endif
6985 #if defined(_WIN32) || defined(_WIN64)
6986 done:
6987  uc_free(t);
6988  uc_free(s);
6989  uc_free(c);
6990 done2:
6991  ;
6992 #endif
6993  HSTMT_UNLOCK(stmt);
6994  return ret;
6995 }
6996 #endif
6997 
6998 #ifdef WINTERFACE
6999 
7011 SQLRETURN SQL_API
7013  SQLWCHAR *cat, SQLSMALLINT catLen,
7014  SQLWCHAR *schema, SQLSMALLINT schemaLen,
7015  SQLWCHAR *table, SQLSMALLINT tableLen)
7016 {
7017  char *c = NULL, *s = NULL, *t = NULL;
7018  SQLRETURN ret;
7019 
7020  HSTMT_LOCK(stmt);
7021  if (cat) {
7022  c = uc_to_utf_c(cat, catLen);
7023  if (!c) {
7024  ret = nomem((STMT *) stmt);
7025  goto done;
7026  }
7027  }
7028  if (schema) {
7029  s = uc_to_utf_c(schema, schemaLen);
7030  if (!s) {
7031  ret = nomem((STMT *) stmt);
7032  goto done;
7033  }
7034  }
7035  if (table) {
7036  t = uc_to_utf_c(table, tableLen);
7037  if (!t) {
7038  ret = nomem((STMT *) stmt);
7039  goto done;
7040  }
7041  }
7042  ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
7043  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
7044 done:
7045  uc_free(t);
7046  uc_free(s);
7047  uc_free(c);
7048  HSTMT_UNLOCK(stmt);
7049  return ret;
7050 }
7051 #endif
7052 
7057 static COL scolSpec2[] = {
7058  { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
7059  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
7060  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
7061  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
7062  { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
7063  { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
7064  { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
7065  { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
7066  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
7067 };
7068 
7069 static COL scolSpec3[] = {
7070  { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
7071  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
7072  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
7073  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
7074  { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
7075  { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
7076  { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
7077  { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
7078  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
7079 };
7080 
7096 static SQLRETURN
7097 drvspecialcolumns(SQLHSTMT stmt, SQLUSMALLINT id,
7098  SQLCHAR *cat, SQLSMALLINT catLen,
7099  SQLCHAR *schema, SQLSMALLINT schemaLen,
7100  SQLCHAR *table, SQLSMALLINT tableLen,
7101  SQLUSMALLINT scope, SQLUSMALLINT nullable)
7102 {
7103  STMT *s;
7104  DBC *d;
7105  SQLRETURN sret;
7106  int i, asize, ret, nrows, ncols, nnnrows, nnncols, offs;
7107  PTRDIFF_T size;
7108  int namec = -1, uniquec = -1, namecc = -1, typecc = -1;
7109  int notnullcc = -1, mkrowid = 0;
7110  char *errp = NULL, *sql, tname[512];
7111  char **rowp = NULL, **rowppp = NULL;
7112 
7114  scolSpec3, array_size(scolSpec3), &asize);
7115  if (sret != SQL_SUCCESS) {
7116  return sret;
7117  }
7118  s = (STMT *) stmt;
7119  d = (DBC *) s->dbc;
7120  if (!table || table[0] == '\0' || table[0] == '%') {
7121  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
7122  return SQL_ERROR;
7123  }
7124  if (tableLen == SQL_NTS) {
7125  size = sizeof (tname) - 1;
7126  } else {
7127  size = min(sizeof (tname) - 1, tableLen);
7128  }
7129  strncpy(tname, (char *) table, size);
7130  tname[size] = '\0';
7131  unescpat(tname);
7132  if (id != SQL_BEST_ROWID) {
7133  return SQL_SUCCESS;
7134  }
7135  sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
7136  if (!sql) {
7137  return nomem(s);
7138  }
7139  sret = starttran(s);
7140  if (sret != SQL_SUCCESS) {
7141  sqlite3_free(sql);
7142  return sret;
7143  }
7144  dbtraceapi(d, "sqlite3_get_table", sql);
7145  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
7146  sqlite3_free(sql);
7147  if (ret != SQLITE_OK) {
7148 doerr:
7149  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7150  errp ? errp : "unknown error", ret);
7151  if (errp) {
7152  sqlite3_free(errp);
7153  errp = NULL;
7154  }
7155  return SQL_ERROR;
7156  }
7157  if (errp) {
7158  sqlite3_free(errp);
7159  errp = NULL;
7160  }
7161  size = 0; /* number result rows */
7162  if (ncols * nrows <= 0) {
7163  goto nodata_but_rowid;
7164  }
7165  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
7166  if (!sql) {
7167  return nomem(s);
7168  }
7169  dbtraceapi(d, "sqlite3_get_table", sql);
7170  ret = sqlite3_get_table(d->sqlite, sql, &rowppp, &nnnrows, &nnncols,
7171  &errp);
7172  sqlite3_free(sql);
7173  if (ret != SQLITE_OK) {
7174  sqlite3_free_table(rowp);
7175  goto doerr;
7176  }
7177  if (errp) {
7178  sqlite3_free(errp);
7179  errp = NULL;
7180  }
7181  namec = findcol(rowp, ncols, "name");
7182  uniquec = findcol(rowp, ncols, "unique");
7183  if (namec < 0 || uniquec < 0) {
7184  goto nodata_but_rowid;
7185  }
7186  namecc = findcol(rowppp, nnncols, "name");
7187  typecc = findcol(rowppp, nnncols, "type");
7188  notnullcc = findcol(rowppp, nnncols, "notnull");
7189  for (i = 1; i <= nrows; i++) {
7190  int nnrows, nncols;
7191  char **rowpp = NULL;
7192 
7193  if (*rowp[i * ncols + uniquec] != '0') {
7194  ret = SQLITE_ERROR;
7195  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
7196  rowp[i * ncols + namec]);
7197  if (sql) {
7198  dbtraceapi(d, "sqlite3_get_table", sql);
7199  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7200  &nnrows, &nncols, NULL);
7201  sqlite3_free(sql);
7202  }
7203  if (ret == SQLITE_OK) {
7204  size += nnrows;
7205  sqlite3_free_table(rowpp);
7206  }
7207  }
7208  }
7209 nodata_but_rowid:
7210  if (size == 0) {
7211  size = 1;
7212  mkrowid = 1;
7213  }
7214  s->nrows = size;
7215  size = (size + 1) * asize;
7216  s->rows = xmalloc((size + 1) * sizeof (char *));
7217  if (!s->rows) {
7218  s->nrows = 0;
7219  sqlite3_free_table(rowp);
7220  sqlite3_free_table(rowppp);
7221  return nomem(s);
7222  }
7223  s->rows[0] = (char *) size;
7224  s->rows += 1;
7225  memset(s->rows, 0, sizeof (char *) * size);
7226  s->rowfree = freerows;
7227  if (mkrowid) {
7228  s->nrows = 0;
7229  goto mkrowid;
7230  }
7231  offs = 0;
7232  for (i = 1; i <= nrows; i++) {
7233  int nnrows, nncols;
7234  char **rowpp = NULL;
7235 
7236  if (*rowp[i * ncols + uniquec] != '0') {
7237  int k;
7238 
7239  ret = SQLITE_ERROR;
7240  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
7241  rowp[i * ncols + namec]);
7242  if (sql) {
7243  dbtraceapi(d, "sqlite3_get_table", sql);
7244  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7245  &nnrows, &nncols, NULL);
7246  sqlite3_free(sql);
7247  }
7248  if (ret != SQLITE_OK) {
7249  continue;
7250  }
7251  for (k = 0; nnrows && k < nncols; k++) {
7252  if (strcmp(rowpp[k], "name") == 0) {
7253  int m;
7254 
7255  for (m = 1; m <= nnrows; m++) {
7256  int roffs = (offs + m) * s->ncols;
7257 
7258  s->rows[roffs + 0] =
7259  xstrdup(stringify(SQL_SCOPE_SESSION));
7260  s->rows[roffs + 1] = xstrdup(rowpp[m * nncols + k]);
7261  s->rows[roffs + 4] = xstrdup("0");
7262  s->rows[roffs + 7] =
7263  xstrdup(stringify(SQL_PC_NOT_PSEUDO));
7264  if (namecc >= 0 && typecc >= 0) {
7265  int ii;
7266 
7267  for (ii = 1; ii <= nnnrows; ii++) {
7268  if (strcmp(rowppp[ii * nnncols + namecc],
7269  rowpp[m * nncols + k]) == 0) {
7270  char *typen = rowppp[ii * nnncols + typecc];
7271  int sqltype, mm, dd, isnullable = 0;
7272  char buf[32];
7273 
7274  s->rows[roffs + 3] = xstrdup(typen);
7275  sqltype = mapsqltype(typen, NULL, *s->ov3,
7276  s->nowchar[0],
7277  s->dobigint);
7278  getmd(typen, sqltype, &mm, &dd);
7279 #ifdef SQL_LONGVARCHAR
7280  if (sqltype == SQL_VARCHAR && mm > 255) {
7281  sqltype = SQL_LONGVARCHAR;
7282  }
7283 #endif
7284 #ifdef WINTERFACE
7285 #ifdef SQL_WLONGVARCHAR
7286  if (sqltype == SQL_WVARCHAR && mm > 255) {
7287  sqltype = SQL_WLONGVARCHAR;
7288  }
7289 #endif
7290 #endif
7291  if (sqltype == SQL_VARBINARY && mm > 255) {
7292  sqltype = SQL_LONGVARBINARY;
7293  }
7294  sprintf(buf, "%d", sqltype);
7295  s->rows[roffs + 2] = xstrdup(buf);
7296  sprintf(buf, "%d", mm);
7297  s->rows[roffs + 5] = xstrdup(buf);
7298  sprintf(buf, "%d", dd);
7299  s->rows[roffs + 6] = xstrdup(buf);
7300  if (notnullcc >= 0) {
7301  char *inp =
7302  rowppp[ii * nnncols + notnullcc];
7303 
7304  isnullable = inp[0] != '0';
7305  }
7306  sprintf(buf, "%d", isnullable);
7307  s->rows[roffs + 8] = xstrdup(buf);
7308  }
7309  }
7310  }
7311  }
7312  }
7313  }
7314  offs += nnrows;
7315  sqlite3_free_table(rowpp);
7316  }
7317  }
7318  if (nullable == SQL_NO_NULLS) {
7319  for (i = 1; i < s->nrows; i++) {
7320  if (s->rows[i * s->ncols + 8][0] == '0') {
7321  int m, i1 = i + 1;
7322 
7323  for (m = 0; m < s->ncols; m++) {
7324  freep(&s->rows[i * s->ncols + m]);
7325  }
7326  size = s->ncols * sizeof (char *) * (s->nrows - i1);
7327  if (size > 0) {
7328  memmove(s->rows + i * s->ncols,
7329  s->rows + i1 * s->ncols,
7330  size);
7331  memset(s->rows + s->nrows * s->ncols, 0,
7332  s->ncols * sizeof (char *));
7333  }
7334  s->nrows--;
7335  --i;
7336  }
7337  }
7338  }
7339 mkrowid:
7340  sqlite3_free_table(rowp);
7341  sqlite3_free_table(rowppp);
7342  if (s->nrows == 0) {
7343  s->rows[s->ncols + 0] = xstrdup(stringify(SQL_SCOPE_SESSION));
7344  s->rows[s->ncols + 1] = xstrdup("_ROWID_");
7345  s->rows[s->ncols + 2] = xstrdup(stringify(SQL_INTEGER));
7346  s->rows[s->ncols + 3] = xstrdup("integer");
7347  s->rows[s->ncols + 4] = xstrdup("0");
7348  s->rows[s->ncols + 5] = xstrdup("10");
7349  s->rows[s->ncols + 6] = xstrdup("9");
7350  s->rows[s->ncols + 7] = xstrdup(stringify(SQL_PC_PSEUDO));
7351  s->rows[s->ncols + 8] = xstrdup(stringify(SQL_FALSE));
7352  s->nrows = 1;
7353  }
7354  return SQL_SUCCESS;
7355 }
7356 
7357 #ifndef WINTERFACE
7358 
7373 SQLRETURN SQL_API
7374 SQLSpecialColumns(SQLHSTMT stmt, SQLUSMALLINT id,
7375  SQLCHAR *cat, SQLSMALLINT catLen,
7376  SQLCHAR *schema, SQLSMALLINT schemaLen,
7377  SQLCHAR *table, SQLSMALLINT tableLen,
7378  SQLUSMALLINT scope, SQLUSMALLINT nullable)
7379 {
7380 #if defined(_WIN32) || defined(_WIN64)
7381  char *c = NULL, *s = NULL, *t = NULL;
7382 #endif
7383  SQLRETURN ret;
7384 
7385  HSTMT_LOCK(stmt);
7386 #if defined(_WIN32) || defined(_WIN64)
7387  if (!((STMT *) stmt)->oemcp[0]) {
7388  ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
7389  table, tableLen, scope, nullable);
7390  goto done2;
7391  }
7392  if (cat) {
7393  c = wmb_to_utf_c((char *) cat, catLen);
7394  if (!c) {
7395  ret = nomem((STMT *) stmt);
7396  goto done;
7397  }
7398  }
7399  if (schema) {
7400  s = wmb_to_utf_c((char *) schema, schemaLen);
7401  if (!s) {
7402  ret = nomem((STMT *) stmt);
7403  goto done;
7404  }
7405  }
7406  if (table) {
7407  t = wmb_to_utf_c((char *) table, tableLen);
7408  if (!t) {
7409  ret = nomem((STMT *) stmt);
7410  goto done;
7411  }
7412  }
7413  ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
7414  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
7415  scope, nullable);
7416 #else
7417  ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
7418  table, tableLen, scope, nullable);
7419 #endif
7420 #if defined(_WIN32) || defined(_WIN64)
7421 done:
7422  uc_free(t);
7423  uc_free(s);
7424  uc_free(c);
7425 done2:
7426  ;
7427 #endif
7428  HSTMT_UNLOCK(stmt);
7429  return ret;
7430 }
7431 #endif
7432 
7433 #ifdef WINTERFACE
7434 
7449 SQLRETURN SQL_API
7450 SQLSpecialColumnsW(SQLHSTMT stmt, SQLUSMALLINT id,
7451  SQLWCHAR *cat, SQLSMALLINT catLen,
7452  SQLWCHAR *schema, SQLSMALLINT schemaLen,
7453  SQLWCHAR *table, SQLSMALLINT tableLen,
7454  SQLUSMALLINT scope, SQLUSMALLINT nullable)
7455 {
7456  char *c = NULL, *s = NULL, *t = NULL;
7457  SQLRETURN ret;
7458 
7459  HSTMT_LOCK(stmt);
7460  if (cat) {
7461  c = uc_to_utf_c(cat, catLen);
7462  if (!c) {
7463  ret = nomem((STMT *) stmt);
7464  goto done;
7465  }
7466  }
7467  if (schema) {
7468  s = uc_to_utf_c(schema, schemaLen);
7469  if (!s) {
7470  ret = nomem((STMT *) stmt);
7471  goto done;
7472  }
7473  }
7474  if (table) {
7475  t = uc_to_utf_c(table, tableLen);
7476  if (!t) {
7477  ret = nomem((STMT *) stmt);
7478  goto done;
7479  }
7480  }
7481  ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
7482  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
7483  scope, nullable);
7484 done:
7485  uc_free(t);
7486  uc_free(s);
7487  uc_free(c);
7488  HSTMT_UNLOCK(stmt);
7489  return ret;
7490 }
7491 #endif
7492 
7497 static COL fkeySpec2[] = {
7498  { "SYSTEM", "FOREIGNKEY", "PKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
7499  { "SYSTEM", "FOREIGNKEY", "PKTABLE_OWNER", SCOL_VARCHAR, 50 },
7500  { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
7501  { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7502  { "SYSTEM", "FOREIGNKEY", "FKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
7503  { "SYSTEM", "FOREIGNKEY", "FKTABLE_OWNER", SCOL_VARCHAR, 50 },
7504  { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
7505  { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7506  { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
7507  { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
7508  { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
7509  { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
7510  { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
7511  { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
7512 };
7513 
7514 static COL fkeySpec3[] = {
7515  { "SYSTEM", "FOREIGNKEY", "PKTABLE_CAT", SCOL_VARCHAR, 50 },
7516  { "SYSTEM", "FOREIGNKEY", "PKTABLE_SCHEM", SCOL_VARCHAR, 50 },
7517  { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
7518  { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7519  { "SYSTEM", "FOREIGNKEY", "FKTABLE_CAT", SCOL_VARCHAR, 50 },
7520  { "SYSTEM", "FOREIGNKEY", "FKTABLE_SCHEM", SCOL_VARCHAR, 50 },
7521  { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
7522  { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7523  { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
7524  { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
7525  { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
7526  { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
7527  { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
7528  { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
7529 };
7530 
7549 static SQLRETURN SQL_API
7551  SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7552  SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
7553  SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
7554  SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7555  SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
7556  SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
7557 {
7558  STMT *s;
7559  DBC *d;
7560  SQLRETURN sret;
7561  int i, asize, ret, nrows, ncols, offs, namec, seqc, fromc, toc;
7562  int onu, ond;
7563  PTRDIFF_T size;
7564  char **rowp, *errp = NULL, *sql, pname[512], fname[512];
7565 
7567  fkeySpec3, array_size(fkeySpec3), &asize);
7568  if (sret != SQL_SUCCESS) {
7569  return sret;
7570  }
7571  s = (STMT *) stmt;
7572  sret = starttran(s);
7573  if (sret != SQL_SUCCESS) {
7574  return sret;
7575  }
7576  d = (DBC *) s->dbc;
7577  if ((!PKtable || PKtable[0] == '\0' || PKtable[0] == '%') &&
7578  (!FKtable || FKtable[0] == '\0' || FKtable[0] == '%')) {
7579  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
7580  return SQL_ERROR;
7581  }
7582  size = 0;
7583  if (PKtable) {
7584  if (PKtableLen == SQL_NTS) {
7585  size = sizeof (pname) - 1;
7586  } else {
7587  size = min(sizeof (pname) - 1, PKtableLen);
7588  }
7589  strncpy(pname, (char *) PKtable, size);
7590  }
7591  pname[size] = '\0';
7592  size = 0;
7593  if (FKtable) {
7594 
7595  if (FKtableLen == SQL_NTS) {
7596  size = sizeof (fname) - 1;
7597  } else {
7598  size = min(sizeof (fname) - 1, FKtableLen);
7599  }
7600  strncpy(fname, (char *) FKtable, size);
7601  }
7602  fname[size] = '\0';
7603  if (fname[0] != '\0') {
7604  int plen;
7605 
7606  ret = SQLITE_ERROR;
7607  sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", fname);
7608  if (sql) {
7609  dbtraceapi(d, "sqlite3_get_table", sql);
7610  ret = sqlite3_get_table(d->sqlite, sql, &rowp,
7611  &nrows, &ncols, &errp);
7612  sqlite3_free(sql);
7613  }
7614  if (ret != SQLITE_OK) {
7615  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7616  errp ? errp : "unknown error", ret);
7617  if (errp) {
7618  sqlite3_free(errp);
7619  errp = NULL;
7620  }
7621  return SQL_ERROR;
7622  }
7623  if (errp) {
7624  sqlite3_free(errp);
7625  errp = NULL;
7626  }
7627  if (ncols * nrows <= 0) {
7628 nodata:
7629  sqlite3_free_table(rowp);
7630  return SQL_SUCCESS;
7631  }
7632  size = 0;
7633  namec = findcol(rowp, ncols, "table");
7634  seqc = findcol(rowp, ncols, "seq");
7635  fromc = findcol(rowp, ncols, "from");
7636  toc = findcol(rowp, ncols, "to");
7637  onu = findcol(rowp, ncols, "on_update");
7638  ond = findcol(rowp, ncols, "on_delete");
7639  if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7640  goto nodata;
7641  }
7642  plen = strlen(pname);
7643  for (i = 1; i <= nrows; i++) {
7644  char *ptab = unquote(rowp[i * ncols + namec]);
7645 
7646  if (plen && ptab) {
7647  int len = strlen(ptab);
7648 
7649  if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
7650  continue;
7651  }
7652  }
7653  size++;
7654  }
7655  if (size == 0) {
7656  goto nodata;
7657  }
7658  s->nrows = size;
7659  size = (size + 1) * asize;
7660  s->rows = xmalloc((size + 1) * sizeof (char *));
7661  if (!s->rows) {
7662  s->nrows = 0;
7663  return nomem(s);
7664  }
7665  s->rows[0] = (char *) size;
7666  s->rows += 1;
7667  memset(s->rows, 0, sizeof (char *) * size);
7668  s->rowfree = freerows;
7669  offs = 0;
7670  for (i = 1; i <= nrows; i++) {
7671  int pos = 0, roffs = (offs + 1) * s->ncols;
7672  char *ptab = rowp[i * ncols + namec];
7673  char buf[32];
7674 
7675  if (plen && ptab) {
7676  int len = strlen(ptab);
7677 
7678  if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
7679  continue;
7680  }
7681  }
7682 #if defined(_WIN32) || defined(_WIN64)
7683  s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
7684  s->rows[roffs + 1] = xstrdup("");
7685 #else
7686  s->rows[roffs + 0] = xstrdup("");
7687  s->rows[roffs + 1] = xstrdup("");
7688 #endif
7689  s->rows[roffs + 2] = xstrdup(ptab);
7690  s->rows[roffs + 3] = xstrdup(rowp[i * ncols + toc]);
7691  s->rows[roffs + 4] = xstrdup("");
7692  s->rows[roffs + 5] = xstrdup("");
7693  s->rows[roffs + 6] = xstrdup(fname);
7694  s->rows[roffs + 7] = xstrdup(rowp[i * ncols + fromc]);
7695  sscanf(rowp[i * ncols + seqc], "%d", &pos);
7696  sprintf(buf, "%d", pos + 1);
7697  s->rows[roffs + 8] = xstrdup(buf);
7698  if (onu < 0) {
7699  s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7700  } else {
7701  if (strcmp(rowp[i * ncols + onu], "SET NULL") == 0) {
7702  s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
7703  } else if (strcmp(rowp[i * ncols + onu], "SET DEFAULT") == 0) {
7704  s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_DEFAULT));
7705  } else if (strcmp(rowp[i * ncols + onu], "CASCADE") == 0) {
7706  s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
7707  } else if (strcmp(rowp[i * ncols + onu], "RESTRICT") == 0) {
7708  s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
7709  } else {
7710  s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7711  }
7712  }
7713  if (ond < 0) {
7714  s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7715  } else {
7716  if (strcmp(rowp[i * ncols + ond], "SET NULL") == 0) {
7717  s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
7718  } else if (strcmp(rowp[i * ncols + ond], "SET DEFAULT") == 0) {
7719  s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_DEFAULT));
7720  } else if (strcmp(rowp[i * ncols + ond], "CASCADE") == 0) {
7721  s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
7722  } else if (strcmp(rowp[i * ncols + ond], "RESTRICT") == 0) {
7723  s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
7724  } else {
7725  s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7726  }
7727  }
7728  s->rows[roffs + 11] = NULL;
7729  s->rows[roffs + 12] = NULL;
7730  s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
7731  offs++;
7732  }
7733  sqlite3_free_table(rowp);
7734  } else {
7735  int nnrows, nncols, plen = strlen(pname);
7736  char **rowpp;
7737 
7738  sql = "select name from sqlite_master where type='table'";
7739  dbtraceapi(d, "sqlite3_get_table", sql);
7740  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
7741  if (ret != SQLITE_OK) {
7742  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7743  errp ? errp : "unknown error", ret);
7744  if (errp) {
7745  sqlite3_free(errp);
7746  errp = NULL;
7747  }
7748  return SQL_ERROR;
7749  }
7750  if (errp) {
7751  sqlite3_free(errp);
7752  errp = NULL;
7753  }
7754  if (ncols * nrows <= 0) {
7755  goto nodata;
7756  }
7757  size = 0;
7758  for (i = 1; i <= nrows; i++) {
7759  int k;
7760 
7761  if (!rowp[i]) {
7762  continue;
7763  }
7764  rowpp = NULL;
7765  ret = SQLITE_ERROR;
7766  sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
7767  if (sql) {
7768  dbtraceapi(d, "sqlite3_get_table", sql);
7769  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7770  &nnrows, &nncols, NULL);
7771  sqlite3_free(sql);
7772  }
7773  if (ret != SQLITE_OK || nncols * nnrows <= 0) {
7774  sqlite3_free_table(rowpp);
7775  continue;
7776  }
7777  namec = findcol(rowpp, nncols, "table");
7778  seqc = findcol(rowpp, nncols, "seq");
7779  fromc = findcol(rowpp, nncols, "from");
7780  toc = findcol(rowpp, nncols, "to");
7781  if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7782  sqlite3_free_table(rowpp);
7783  continue;
7784  }
7785  for (k = 1; k <= nnrows; k++) {
7786  char *ptab = unquote(rowpp[k * nncols + namec]);
7787 
7788  if (plen && ptab) {
7789  int len = strlen(ptab);
7790 
7791  if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
7792  continue;
7793  }
7794  }
7795  size++;
7796  }
7797  sqlite3_free_table(rowpp);
7798  }
7799  if (size == 0) {
7800  goto nodata;
7801  }
7802  s->nrows = size;
7803  size = (size + 1) * asize;
7804  s->rows = xmalloc((size + 1) * sizeof (char *));
7805  if (!s->rows) {
7806  s->nrows = 0;
7807  return nomem(s);
7808  }
7809  s->rows[0] = (char *) size;
7810  s->rows += 1;
7811  memset(s->rows, 0, sizeof (char *) * size);
7812  s->rowfree = freerows;
7813  offs = 0;
7814  for (i = 1; i <= nrows; i++) {
7815  int k;
7816 
7817  if (!rowp[i]) {
7818  continue;
7819  }
7820  rowpp = NULL;
7821  ret = SQLITE_ERROR;
7822  sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
7823  if (sql) {
7824  dbtraceapi(d, "sqlite3_get_table", sql);
7825  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7826  &nnrows, &nncols, NULL);
7827  sqlite3_free(sql);
7828  }
7829  if (ret != SQLITE_OK || nncols * nnrows <= 0) {
7830  sqlite3_free_table(rowpp);
7831  continue;
7832  }
7833  namec = findcol(rowpp, nncols, "table");
7834  seqc = findcol(rowpp, nncols, "seq");
7835  fromc = findcol(rowpp, nncols, "from");
7836  toc = findcol(rowpp, nncols, "to");
7837  onu = findcol(rowpp, nncols, "on_update");
7838  ond = findcol(rowpp, nncols, "on_delete");
7839  if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7840  sqlite3_free_table(rowpp);
7841  continue;
7842  }
7843  for (k = 1; k <= nnrows; k++) {
7844  int pos = 0, roffs = (offs + 1) * s->ncols;
7845  char *ptab = unquote(rowpp[k * nncols + namec]);
7846  char buf[32];
7847 
7848  if (plen && ptab) {
7849  int len = strlen(ptab);
7850 
7851  if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
7852  continue;
7853  }
7854  }
7855 #if defined(_WIN32) || defined(_WIN64)
7856  s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
7857  s->rows[roffs + 1] = xstrdup("");
7858 #else
7859  s->rows[roffs + 0] = xstrdup("");
7860  s->rows[roffs + 1] = xstrdup("");
7861 #endif
7862  s->rows[roffs + 2] = xstrdup(ptab);
7863  s->rows[roffs + 3] = xstrdup(rowpp[k * nncols + toc]);
7864  s->rows[roffs + 4] = xstrdup("");
7865  s->rows[roffs + 5] = xstrdup("");
7866  s->rows[roffs + 6] = xstrdup(rowp[i]);
7867  s->rows[roffs + 7] = xstrdup(rowpp[k * nncols + fromc]);
7868  sscanf(rowpp[k * nncols + seqc], "%d", &pos);
7869  sprintf(buf, "%d", pos + 1);
7870  s->rows[roffs + 8] = xstrdup(buf);
7871  if (onu < 0) {
7872  s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7873  } else {
7874  if (strcmp(rowpp[k * nncols + onu], "SET NULL") == 0) {
7875  s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
7876  } else if (strcmp(rowpp[k * nncols + onu], "SET DEFAULT")
7877  == 0) {
7878  s->rows[roffs + 9] =
7879  xstrdup(stringify(SQL_SET_DEFAULT));
7880  } else if (strcmp(rowpp[k * nncols + onu], "CASCADE")
7881  == 0) {
7882  s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
7883  } else if (strcmp(rowpp[k * nncols + onu], "RESTRICT")
7884  == 0) {
7885  s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
7886  } else {
7887  s->rows[roffs + 9] =
7888  xstrdup(stringify(SQL_NO_ACTION));
7889  }
7890  }
7891  if (ond < 0) {
7892  s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7893  } else {
7894  if (strcmp(rowpp[k * nncols + ond], "SET NULL") == 0) {
7895  s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
7896  } else if (strcmp(rowpp[k * nncols + ond], "SET DEFAULT")
7897  == 0) {
7898  s->rows[roffs + 10] =
7899  xstrdup(stringify(SQL_SET_DEFAULT));
7900  } else if (strcmp(rowpp[k * nncols + ond], "CASCADE")
7901  == 0) {
7902  s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
7903  } else if (strcmp(rowpp[k * nncols + ond], "RESTRICT")
7904  == 0) {
7905  s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
7906  } else {
7907  s->rows[roffs + 10] =
7908  xstrdup(stringify(SQL_NO_ACTION));
7909  }
7910  }
7911  s->rows[roffs + 11] = NULL;
7912  s->rows[roffs + 12] = NULL;
7913  s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
7914  offs++;
7915  }
7916  sqlite3_free_table(rowpp);
7917  }
7918  sqlite3_free_table(rowp);
7919  }
7920  return SQL_SUCCESS;
7921 }
7922 
7923 #ifndef WINTERFACE
7924 
7942 SQLRETURN SQL_API
7943 SQLForeignKeys(SQLHSTMT stmt,
7944  SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7945  SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
7946  SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
7947  SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7948  SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
7949  SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
7950 {
7951 #if defined(_WIN32) || defined(_WIN64)
7952  char *pc = NULL, *ps = NULL, *pt = NULL;
7953  char *fc = NULL, *fs = NULL, *ft = NULL;
7954 #endif
7955  SQLRETURN ret;
7956 
7957  HSTMT_LOCK(stmt);
7958 #if defined(_WIN32) || defined(_WIN64)
7959  if (!((STMT *) stmt)->oemcp[0]) {
7960  ret = drvforeignkeys(stmt,
7961  PKcatalog, PKcatalogLen,
7962  PKschema, PKschemaLen, PKtable, PKtableLen,
7963  FKcatalog, FKcatalogLen,
7964  FKschema, FKschemaLen,
7965  FKtable, FKtableLen);
7966  goto done2;
7967  }
7968  if (PKcatalog) {
7969  pc = wmb_to_utf_c((char *) PKcatalog, PKcatalogLen);
7970  if (!pc) {
7971  ret = nomem((STMT *) stmt);
7972  goto done;
7973  }
7974  }
7975  if (PKschema) {
7976  ps = wmb_to_utf_c((char *) PKschema, PKschemaLen);
7977  if (!ps) {
7978  ret = nomem((STMT *) stmt);
7979  goto done;
7980  }
7981  }
7982  if (PKtable) {
7983  pt = wmb_to_utf_c((char *) PKtable, PKtableLen);
7984  if (!pt) {
7985  ret = nomem((STMT *) stmt);
7986  goto done;
7987  }
7988  }
7989  if (FKcatalog) {
7990  fc = wmb_to_utf_c((char *) FKcatalog, FKcatalogLen);
7991  if (!fc) {
7992  ret = nomem((STMT *) stmt);
7993  goto done;
7994  }
7995  }
7996  if (FKschema) {
7997  fs = wmb_to_utf_c((char *) FKschema, FKschemaLen);
7998  if (!fs) {
7999  ret = nomem((STMT *) stmt);
8000  goto done;
8001  }
8002  }
8003  if (FKtable) {
8004  ft = wmb_to_utf_c((char *) FKtable, FKtableLen);
8005  if (!ft) {
8006  ret = nomem((STMT *) stmt);
8007  goto done;
8008  }
8009  }
8010  ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
8011  (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
8012  (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
8013  (SQLCHAR *) ft, SQL_NTS);
8014 #else
8015  ret = drvforeignkeys(stmt,
8016  PKcatalog, PKcatalogLen,
8017  PKschema, PKschemaLen, PKtable, PKtableLen,
8018  FKcatalog, FKcatalogLen,
8019  FKschema, FKschemaLen,
8020  FKtable, FKtableLen);
8021 #endif
8022 #if defined(_WIN32) || defined(_WIN64)
8023 done:
8024  uc_free(ft);
8025  uc_free(fs);
8026  uc_free(fc);
8027  uc_free(pt);
8028  uc_free(ps);
8029  uc_free(pc);
8030 done2:
8031  ;
8032 #endif
8033  HSTMT_UNLOCK(stmt);
8034  return ret;
8035 }
8036 #endif
8037 
8038 #ifdef WINTERFACE
8039 
8057 SQLRETURN SQL_API
8059  SQLWCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
8060  SQLWCHAR *PKschema, SQLSMALLINT PKschemaLen,
8061  SQLWCHAR *PKtable, SQLSMALLINT PKtableLen,
8062  SQLWCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
8063  SQLWCHAR *FKschema, SQLSMALLINT FKschemaLen,
8064  SQLWCHAR *FKtable, SQLSMALLINT FKtableLen)
8065 {
8066  char *pc = NULL, *ps = NULL, *pt = NULL;
8067  char *fc = NULL, *fs = NULL, *ft = NULL;
8068  SQLRETURN ret;
8069 
8070  HSTMT_LOCK(stmt);
8071  if (PKcatalog) {
8072  pc = uc_to_utf_c(PKcatalog, PKcatalogLen);
8073  if (!pc) {
8074  ret = nomem((STMT *) stmt);
8075  goto done;
8076  }
8077  }
8078  if (PKschema) {
8079  ps = uc_to_utf_c(PKschema, PKschemaLen);
8080  if (!ps) {
8081  ret = nomem((STMT *) stmt);
8082  goto done;
8083  }
8084  }
8085  if (PKtable) {
8086  pt = uc_to_utf_c(PKtable, PKtableLen);
8087  if (!pt) {
8088  ret = nomem((STMT *) stmt);
8089  goto done;
8090  }
8091  }
8092  if (FKcatalog) {
8093  fc = uc_to_utf_c(FKcatalog, FKcatalogLen);
8094  if (!fc) {
8095  ret = nomem((STMT *) stmt);
8096  goto done;
8097  }
8098  }
8099  if (FKschema) {
8100  fs = uc_to_utf_c(FKschema, FKschemaLen);
8101  if (!fs) {
8102  ret = nomem((STMT *) stmt);
8103  goto done;
8104  }
8105  }
8106  if (FKtable) {
8107  ft = uc_to_utf_c(FKtable, FKtableLen);
8108  if (!ft) {
8109  ret = nomem((STMT *) stmt);
8110  goto done;
8111  }
8112  }
8113  ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
8114  (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
8115  (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
8116  (SQLCHAR *) ft, SQL_NTS);
8117 done:
8118  uc_free(ft);
8119  uc_free(fs);
8120  uc_free(fc);
8121  uc_free(pt);
8122  uc_free(ps);
8123  uc_free(pc);
8124  HSTMT_UNLOCK(stmt);
8125  return ret;
8126 }
8127 #endif
8128 
8135 static SQLRETURN
8137 {
8138  int ret = SQL_SUCCESS, rc, busy_count = 0;
8139  char *errp = NULL;
8140  DBC *d = (DBC *) s->dbc;
8141 
8142  if (!d->autocommit && !d->intrans && !d->trans_disable) {
8143 begin_again:
8144  rc = sqlite3_exec(d->sqlite, "BEGIN TRANSACTION", NULL, NULL, &errp);
8145  if (rc == SQLITE_BUSY) {
8146  if (busy_handler((void *) d, ++busy_count)) {
8147  if (errp) {
8148  sqlite3_free(errp);
8149  errp = NULL;
8150  }
8151  goto begin_again;
8152  }
8153  }
8154  dbtracerc(d, rc, errp);
8155  if (rc != SQLITE_OK) {
8156  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
8157  errp ? errp : "unknown error", rc);
8158  ret = SQL_ERROR;
8159  } else {
8160  d->intrans = 1;
8161  }
8162  if (errp) {
8163  sqlite3_free(errp);
8164  errp = NULL;
8165  }
8166  }
8167  return ret;
8168 }
8169 
8178 static SQLRETURN
8179 endtran(DBC *d, SQLSMALLINT comptype, int force)
8180 {
8181  int ret, busy_count = 0;
8182  char *sql, *errp = NULL;
8183 
8184  if (!d->sqlite) {
8185  setstatd(d, -1, "not connected", (*d->ov3) ? "HY000" : "S1000");
8186  return SQL_ERROR;
8187  }
8188  if ((!force && d->autocommit) || !d->intrans) {
8189  return SQL_SUCCESS;
8190  }
8191  switch (comptype) {
8192  case SQL_COMMIT:
8193  sql = "COMMIT TRANSACTION";
8194  goto doit;
8195  case SQL_ROLLBACK:
8196  sql = "ROLLBACK TRANSACTION";
8197  doit:
8198  ret = sqlite3_exec(d->sqlite, sql, NULL, NULL, &errp);
8199  dbtracerc(d, ret, errp);
8200  if (ret == SQLITE_BUSY && busy_count < 10) {
8201  if (busy_handler((void *) d, ++busy_count)) {
8202  if (errp) {
8203  sqlite3_free(errp);
8204  errp = NULL;
8205  }
8206  goto doit;
8207  }
8208  }
8209  if (ret != SQLITE_OK) {
8210  setstatd(d, ret, "%s", (*d->ov3) ? "HY000" : "S1000",
8211  errp ? errp : "transaction failed");
8212  if (errp) {
8213  sqlite3_free(errp);
8214  errp = NULL;
8215  }
8216  return SQL_ERROR;
8217  }
8218  if (errp) {
8219  sqlite3_free(errp);
8220  errp = NULL;
8221  }
8222  d->intrans = 0;
8223  return SQL_SUCCESS;
8224  }
8225  setstatd(d, -1, "invalid completion type", (*d->ov3) ? "HY000" : "S1000");
8226  return SQL_ERROR;
8227 }
8228 
8237 static SQLRETURN
8238 drvendtran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
8239 {
8240  DBC *dbc = NULL;
8241  int fail = 0;
8242  SQLRETURN ret;
8243 #if defined(_WIN32) || defined(_WIN64)
8244  ENV *env;
8245 #endif
8246 
8247  switch (type) {
8248  case SQL_HANDLE_DBC:
8249  HDBC_LOCK((SQLHDBC) handle);
8250  if (handle == SQL_NULL_HDBC) {
8251  return SQL_INVALID_HANDLE;
8252  }
8253  dbc = (DBC *) handle;
8254  ret = endtran(dbc, comptype, 0);
8255  HDBC_UNLOCK((SQLHDBC) handle);
8256  return ret;
8257  case SQL_HANDLE_ENV:
8258  if (handle == SQL_NULL_HENV) {
8259  return SQL_INVALID_HANDLE;
8260  }
8261 #if defined(_WIN32) || defined(_WIN64)
8262  env = (ENV *) handle;
8263  if (env->magic != ENV_MAGIC) {
8264  return SQL_INVALID_HANDLE;
8265  }
8266  EnterCriticalSection(&env->cs);
8267 #endif
8268  dbc = ((ENV *) handle)->dbcs;
8269  while (dbc) {
8270  HDBC_LOCK((SQLHDBC) dbc);
8271  ret = endtran(dbc, comptype, 0);
8272  HDBC_UNLOCK((SQLHDBC) dbc);
8273  if (ret != SQL_SUCCESS) {
8274  fail++;
8275  }
8276  dbc = dbc->next;
8277  }
8278 #if defined(_WIN32) || defined(_WIN64)
8279  LeaveCriticalSection(&env->cs);
8280 #endif
8281  return fail ? SQL_ERROR : SQL_SUCCESS;
8282  }
8283  return SQL_INVALID_HANDLE;
8284 }
8285 
8294 SQLRETURN SQL_API
8295 SQLEndTran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
8296 {
8297  return drvendtran(type, handle, comptype);
8298 }
8299 
8308 SQLRETURN SQL_API
8309 SQLTransact(SQLHENV env, SQLHDBC dbc, SQLUSMALLINT type)
8310 {
8311  if (dbc != SQL_NULL_HDBC) {
8312  return drvendtran(SQL_HANDLE_DBC, (SQLHANDLE) dbc, type);
8313  }
8314  return drvendtran(SQL_HANDLE_ENV, (SQLHANDLE) env, type);
8315 }
8316 
8321 SQLRETURN SQL_API
8322 SQLCopyDesc(SQLHDESC source, SQLHDESC target)
8323 {
8324  return SQL_ERROR;
8325 }
8326 
8327 #ifndef WINTERFACE
8328 
8339 SQLRETURN SQL_API
8340 SQLNativeSql(SQLHSTMT stmt, SQLCHAR *sqlin, SQLINTEGER sqlinLen,
8341  SQLCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
8342 {
8343  int outLen = 0;
8344  SQLRETURN ret = SQL_SUCCESS;
8345 
8346  HSTMT_LOCK(stmt);
8347  if (sqlinLen == SQL_NTS) {
8348  sqlinLen = strlen((char *) sqlin);
8349  }
8350  if (sql) {
8351  if (sqlMax > 0) {
8352  strncpy((char *) sql, (char *) sqlin, sqlMax - 1);
8353  sqlin[sqlMax - 1] = '\0';
8354  outLen = min(sqlMax - 1, sqlinLen);
8355  }
8356  } else {
8357  outLen = sqlinLen;
8358  }
8359  if (sqlLen) {
8360  *sqlLen = outLen;
8361  }
8362  if (sql && outLen < sqlinLen) {
8363  setstat((STMT *) stmt, -1, "data right truncated", "01004");
8364  ret = SQL_SUCCESS_WITH_INFO;
8365  }
8366  HSTMT_UNLOCK(stmt);
8367  return ret;
8368 }
8369 #endif
8370 
8371 #ifdef WINTERFACE
8372 
8383 SQLRETURN SQL_API
8384 SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen,
8385  SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
8386 {
8387  int outLen = 0;
8388  SQLRETURN ret = SQL_SUCCESS;
8389 
8390  HSTMT_LOCK(stmt);
8391  if (sqlinLen == SQL_NTS) {
8392  sqlinLen = uc_strlen(sqlin);
8393  }
8394  if (sql) {
8395  if (sqlMax > 0) {
8396  uc_strncpy(sql, sqlin, sqlMax - 1);
8397  sqlin[sqlMax - 1] = 0;
8398  outLen = min(sqlMax - 1, sqlinLen);
8399  }
8400  } else {
8401  outLen = sqlinLen;
8402  }
8403  if (sqlLen) {
8404  *sqlLen = outLen;
8405  }
8406  if (sql && outLen < sqlinLen) {
8407  setstat((STMT *) stmt, -1, "data right truncated", "01004");
8408  ret = SQL_SUCCESS_WITH_INFO;
8409  }
8410  HSTMT_UNLOCK(stmt);
8411  return ret;
8412 }
8413 #endif
8414 
8419 static COL procSpec2[] = {
8420  { "SYSTEM", "PROCEDURE", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
8421  { "SYSTEM", "PROCEDURE", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
8422  { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8423  { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
8424  { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
8425  { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
8426  { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
8427  { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
8428 };
8429 
8430 static COL procSpec3[] = {
8431  { "SYSTEM", "PROCEDURE", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
8432  { "SYSTEM", "PROCEDURE", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
8433  { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8434  { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
8435  { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
8436  { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
8437  { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
8438  { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
8439 };
8440 
8441 #ifndef WINTERFACE
8442 
8454 SQLRETURN SQL_API
8455 SQLProcedures(SQLHSTMT stmt,
8456  SQLCHAR *catalog, SQLSMALLINT catalogLen,
8457  SQLCHAR *schema, SQLSMALLINT schemaLen,
8458  SQLCHAR *proc, SQLSMALLINT procLen)
8459 {
8460  SQLRETURN ret;
8461 
8462  HSTMT_LOCK(stmt);
8464  procSpec3, array_size(procSpec3), NULL);
8465  HSTMT_UNLOCK(stmt);
8466  return ret;
8467 }
8468 #endif
8469 
8470 #ifdef WINTERFACE
8471 
8483 SQLRETURN SQL_API
8485  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
8486  SQLWCHAR *schema, SQLSMALLINT schemaLen,
8487  SQLWCHAR *proc, SQLSMALLINT procLen)
8488 {
8489  SQLRETURN ret;
8490 
8491  HSTMT_LOCK(stmt);
8493  procSpec3, array_size(procSpec3), NULL);
8494  HSTMT_UNLOCK(stmt);
8495  return ret;
8496 }
8497 #endif
8498 
8503 static COL procColSpec2[] = {
8504  { "SYSTEM", "PROCCOL", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
8505  { "SYSTEM", "PROCCOL", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
8506  { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8507  { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
8508  { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
8509  { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
8510  { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
8511  { "SYSTEM", "PROCCOL", "PRECISION", SQL_INTEGER, 10 },
8512  { "SYSTEM", "PROCCOL", "LENGTH", SQL_INTEGER, 10 },
8513  { "SYSTEM", "PROCCOL", "SCALE", SQL_SMALLINT, 5 },
8514  { "SYSTEM", "PROCCOL", "RADIX", SQL_SMALLINT, 5 },
8515  { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
8516  { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
8517  { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
8518  { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
8519  { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
8520  { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
8521  { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
8522  { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
8523 };
8524 
8525 static COL procColSpec3[] = {
8526  { "SYSTEM", "PROCCOL", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
8527  { "SYSTEM", "PROCCOL", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
8528  { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8529  { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
8530  { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
8531  { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
8532  { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
8533  { "SYSTEM", "PROCCOL", "COLUMN_SIZE", SQL_INTEGER, 10 },
8534  { "SYSTEM", "PROCCOL", "BUFFER_LENGTH", SQL_INTEGER, 10 },
8535  { "SYSTEM", "PROCCOL", "DECIMAL_DIGITS", SQL_SMALLINT, 5 },
8536  { "SYSTEM", "PROCCOL", "NUM_PREC_RADIX", SQL_SMALLINT, 5 },
8537  { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
8538  { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
8539  { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
8540  { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
8541  { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
8542  { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
8543  { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
8544  { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
8545 };
8546 
8547 #ifndef WINTERFACE
8548 
8562 SQLRETURN SQL_API
8563 SQLProcedureColumns(SQLHSTMT stmt,
8564  SQLCHAR *catalog, SQLSMALLINT catalogLen,
8565  SQLCHAR *schema, SQLSMALLINT schemaLen,
8566  SQLCHAR *proc, SQLSMALLINT procLen,
8567  SQLCHAR *column, SQLSMALLINT columnLen)
8568 {
8569  SQLRETURN ret;
8570 
8571  HSTMT_LOCK(stmt);
8574  HSTMT_UNLOCK(stmt);
8575  return ret;
8576 }
8577 #endif
8578 
8579 #ifdef WINTERFACE
8580 
8595 SQLRETURN SQL_API
8597  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
8598  SQLWCHAR *schema, SQLSMALLINT schemaLen,
8599  SQLWCHAR *proc, SQLSMALLINT procLen,
8600  SQLWCHAR *column, SQLSMALLINT columnLen)
8601 {
8602  SQLRETURN ret;
8603 
8604  HSTMT_LOCK(stmt);
8607  HSTMT_UNLOCK(stmt);
8608  return ret;
8609 }
8610 #endif
8611 
8622 SQLRETURN SQL_API
8623 SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val,
8624  SQLINTEGER len, SQLINTEGER *lenp)
8625 {
8626  ENV *e;
8627  SQLRETURN ret = SQL_ERROR;
8628 
8629  if (env == SQL_NULL_HENV) {
8630  return SQL_INVALID_HANDLE;
8631  }
8632  e = (ENV *) env;
8633  if (!e || e->magic != ENV_MAGIC) {
8634  return SQL_INVALID_HANDLE;
8635  }
8636 #if defined(_WIN32) || defined(_WIN64)
8637  EnterCriticalSection(&e->cs);
8638 #endif
8639  switch (attr) {
8640  case SQL_ATTR_CONNECTION_POOLING:
8641  if (val) {
8642  *((SQLINTEGER *) val) = e->pool ?
8643  SQL_CP_ONE_PER_DRIVER : SQL_CP_OFF;
8644  }
8645  if (lenp) {
8646  *lenp = sizeof (SQLINTEGER);
8647  }
8648  ret = SQL_SUCCESS;
8649  break;
8650  case SQL_ATTR_CP_MATCH:
8651  *((SQLINTEGER *) val) = SQL_CP_RELAXED_MATCH;
8652  if (lenp) {
8653  *lenp = sizeof (SQLINTEGER);
8654  }
8655  ret = SQL_SUCCESS;
8656  break;
8657  case SQL_ATTR_OUTPUT_NTS:
8658  if (val) {
8659  *((SQLINTEGER *) val) = SQL_TRUE;
8660  }
8661  if (lenp) {
8662  *lenp = sizeof (SQLINTEGER);
8663  }
8664  ret = SQL_SUCCESS;
8665  break;
8666  case SQL_ATTR_ODBC_VERSION:
8667  if (val) {
8668  *((SQLINTEGER *) val) = e->ov3 ? SQL_OV_ODBC3 : SQL_OV_ODBC2;
8669  }
8670  if (lenp) {
8671  *lenp = sizeof (SQLINTEGER);
8672  }
8673  ret = SQL_SUCCESS;
8674  break;
8675  }
8676 #if defined(_WIN32) || defined(_WIN64)
8677  LeaveCriticalSection(&e->cs);
8678 #endif
8679  return ret;
8680 }
8681 
8691 SQLRETURN SQL_API
8692 SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
8693 {
8694  ENV *e;
8695  SQLRETURN ret = SQL_ERROR;
8696 
8697  if (env == SQL_NULL_HENV) {
8698  return SQL_INVALID_HANDLE;
8699  }
8700  e = (ENV *) env;
8701  if (!e || e->magic != ENV_MAGIC) {
8702  return SQL_INVALID_HANDLE;
8703  }
8704 #if defined(_WIN32) || defined(_WIN64)
8705  EnterCriticalSection(&e->cs);
8706 #endif
8707  switch (attr) {
8708  case SQL_ATTR_CONNECTION_POOLING:
8709  if (val == (SQLPOINTER) SQL_CP_ONE_PER_DRIVER) {
8710  e->pool = 1;
8711  ret = SQL_SUCCESS;
8712  } else if (val == (SQLPOINTER) SQL_CP_OFF) {
8713  e->pool = 0;
8714  ret = SQL_SUCCESS;
8715  }
8716  break;
8717  case SQL_ATTR_CP_MATCH:
8718  ret = SQL_SUCCESS;
8719  break;
8720  case SQL_ATTR_OUTPUT_NTS:
8721  if (val == (SQLPOINTER) SQL_TRUE) {
8722  ret = SQL_SUCCESS;
8723  }
8724  break;
8725  case SQL_ATTR_ODBC_VERSION:
8726  if (!val) {
8727  break;
8728  }
8729  if (val == (SQLPOINTER) SQL_OV_ODBC2) {
8730  e->ov3 = 0;
8731  ret = SQL_SUCCESS;
8732  } else if (val == (SQLPOINTER) SQL_OV_ODBC3) {
8733  e->ov3 = 1;
8734  ret = SQL_SUCCESS;
8735  }
8736  break;
8737  }
8738 #if defined(_WIN32) || defined(_WIN64)
8739  LeaveCriticalSection(&e->cs);
8740 #endif
8741  return ret;
8742 }
8743 
8757 static SQLRETURN
8758 drvgetdiagrec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8759  SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
8760  SQLSMALLINT buflen, SQLSMALLINT *msglen)
8761 {
8762  DBC *d = NULL;
8763  STMT *s = NULL;
8764  int len, naterr;
8765  char *logmsg, *sqlst;
8766  SQLRETURN ret = SQL_ERROR;
8767 
8768  if (handle == SQL_NULL_HANDLE) {
8769  return SQL_INVALID_HANDLE;
8770  }
8771  if (sqlstate) {
8772  sqlstate[0] = '\0';
8773  }
8774  if (msg && buflen > 0) {
8775  msg[0] = '\0';
8776  }
8777  if (msglen) {
8778  *msglen = 0;
8779  }
8780  if (nativeerr) {
8781  *nativeerr = 0;
8782  }
8783  switch (htype) {
8784  case SQL_HANDLE_ENV:
8785  case SQL_HANDLE_DESC:
8786  return SQL_NO_DATA;
8787  case SQL_HANDLE_DBC:
8788  HDBC_LOCK((SQLHDBC) handle);
8789  d = (DBC *) handle;
8790  logmsg = (char *) d->logmsg;
8791  sqlst = d->sqlstate;
8792  naterr = d->naterr;
8793  break;
8794  case SQL_HANDLE_STMT:
8795  HSTMT_LOCK((SQLHSTMT) handle);
8796  s = (STMT *) handle;
8797  logmsg = (char *) s->logmsg;
8798  sqlst = s->sqlstate;
8799  naterr = s->naterr;
8800  break;
8801  default:
8802  return SQL_INVALID_HANDLE;
8803  }
8804  if (buflen < 0) {
8805  goto done;
8806  }
8807  if (recno > 1) {
8808  ret = SQL_NO_DATA;
8809  goto done;
8810  }
8811  len = strlen(logmsg);
8812  if (len == 0) {
8813  ret = SQL_NO_DATA;
8814  goto done;
8815  }
8816  if (nativeerr) {
8817  *nativeerr = naterr;
8818  }
8819  if (sqlstate) {
8820  strcpy((char *) sqlstate, sqlst);
8821  }
8822  if (msglen) {
8823  *msglen = len;
8824  }
8825  if (len >= buflen) {
8826  if (msg && buflen > 0) {
8827  strncpy((char *) msg, logmsg, buflen);
8828  msg[buflen - 1] = '\0';
8829  logmsg[0] = '\0';
8830  }
8831  } else if (msg) {
8832  strcpy((char *) msg, logmsg);
8833  logmsg[0] = '\0';
8834  }
8835  ret = SQL_SUCCESS;
8836 done:
8837  switch (htype) {
8838  case SQL_HANDLE_DBC:
8839  HDBC_UNLOCK((SQLHDBC) handle);
8840  break;
8841  case SQL_HANDLE_STMT:
8842  HSTMT_UNLOCK((SQLHSTMT) handle);
8843  break;
8844  }
8845  return ret;
8846 }
8847 
8848 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
8849 
8862 SQLRETURN SQL_API
8863 SQLGetDiagRec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8864  SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
8865  SQLSMALLINT buflen, SQLSMALLINT *msglen)
8866 {
8867  return drvgetdiagrec(htype, handle, recno, sqlstate,
8868  nativeerr, msg, buflen, msglen);
8869 }
8870 #endif
8871 
8872 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
8873 #ifdef WINTERFACE
8874 
8888 SQLRETURN SQL_API
8889 SQLGetDiagRecW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8890  SQLWCHAR *sqlstate, SQLINTEGER *nativeerr, SQLWCHAR *msg,
8891  SQLSMALLINT buflen, SQLSMALLINT *msglen)
8892 {
8893  char state[16];
8894  SQLSMALLINT len;
8895  SQLRETURN ret;
8896 
8897  ret = drvgetdiagrec(htype, handle, recno, (SQLCHAR *) state,
8898  nativeerr, (SQLCHAR *) msg, buflen, &len);
8899  if (ret == SQL_SUCCESS) {
8900  if (sqlstate) {
8901  uc_from_utf_buf((SQLCHAR *) state, -1, sqlstate,
8902  6 * sizeof (SQLWCHAR));
8903  }
8904  if (msg) {
8905  if (len > 0) {
8906  SQLWCHAR *m = NULL;
8907 
8908  m = uc_from_utf((unsigned char *) msg, len);
8909  if (m) {
8910  if (buflen) {
8911  buflen /= sizeof (SQLWCHAR);
8912  uc_strncpy(msg, m, buflen);
8913  m[len] = 0;
8914  len = min(buflen, uc_strlen(m));
8915  } else {
8916  len = uc_strlen(m);
8917  }
8918  uc_free(m);
8919  } else {
8920  len = 0;
8921  }
8922  }
8923  if (len <= 0) {
8924  len = 0;
8925  if (buflen > 0) {
8926  msg[0] = 0;
8927  }
8928  }
8929  } else {
8930  /* estimated length !!! */
8931  len *= sizeof (SQLWCHAR);
8932  }
8933  if (msglen) {
8934  *msglen = len;
8935  }
8936  } else if (ret == SQL_NO_DATA) {
8937  if (sqlstate) {
8938  sqlstate[0] = 0;
8939  }
8940  if (msg) {
8941  if (buflen > 0) {
8942  msg[0] = 0;
8943  }
8944  }
8945  if (msglen) {
8946  *msglen = 0;
8947  }
8948  }
8949  return ret;
8950 }
8951 #endif
8952 #endif
8953 
8966 static SQLRETURN
8967 drvgetdiagfield(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8968  SQLSMALLINT id, SQLPOINTER info,
8969  SQLSMALLINT buflen, SQLSMALLINT *stringlen)
8970 {
8971  DBC *d = NULL;
8972  STMT *s = NULL;
8973  int len, naterr, strbuf = 1;
8974  char *logmsg, *sqlst, *clrmsg = NULL;
8975  SQLRETURN ret = SQL_ERROR;
8976 
8977  if (handle == SQL_NULL_HANDLE) {
8978  return SQL_INVALID_HANDLE;
8979  }
8980  if (stringlen) {
8981  *stringlen = 0;
8982  }
8983  switch (htype) {
8984  case SQL_HANDLE_ENV:
8985  case SQL_HANDLE_DESC:
8986  return SQL_NO_DATA;
8987  case SQL_HANDLE_DBC:
8988  HDBC_LOCK((SQLHDBC) handle);
8989  d = (DBC *) handle;
8990  logmsg = (char *) d->logmsg;
8991  sqlst = d->sqlstate;
8992  naterr = d->naterr;
8993  break;
8994  case SQL_HANDLE_STMT:
8995  HSTMT_LOCK((SQLHSTMT) handle);
8996  s = (STMT *) handle;
8997  d = (DBC *) s->dbc;
8998  logmsg = (char *) s->logmsg;
8999  sqlst = s->sqlstate;
9000  naterr = s->naterr;
9001  break;
9002  default:
9003  return SQL_INVALID_HANDLE;
9004  }
9005  if (buflen < 0) {
9006  switch (buflen) {
9007  case SQL_IS_POINTER:
9008  case SQL_IS_UINTEGER:
9009  case SQL_IS_INTEGER:
9010  case SQL_IS_USMALLINT:
9011  case SQL_IS_SMALLINT:
9012  strbuf = 0;
9013  break;
9014  default:
9015  ret = SQL_ERROR;
9016  goto done;
9017  }
9018  }
9019  if (recno > 1) {
9020  ret = SQL_NO_DATA;
9021  goto done;
9022  }
9023  switch (id) {
9024  case SQL_DIAG_CLASS_ORIGIN:
9025  logmsg = "ISO 9075";
9026  if (sqlst[0] == 'I' && sqlst[1] == 'M') {
9027  logmsg = "ODBC 3.0";
9028  }
9029  break;
9030  case SQL_DIAG_SUBCLASS_ORIGIN:
9031  logmsg = "ISO 9075";
9032  if (sqlst[0] == 'I' && sqlst[1] == 'M') {
9033  logmsg = "ODBC 3.0";
9034  } else if (sqlst[0] == 'H' && sqlst[1] == 'Y') {
9035  logmsg = "ODBC 3.0";
9036  } else if (sqlst[0] == '2' || sqlst[0] == '0' || sqlst[0] == '4') {
9037  logmsg = "ODBC 3.0";
9038  }
9039  break;
9040  case SQL_DIAG_CONNECTION_NAME:
9041  case SQL_DIAG_SERVER_NAME:
9042  logmsg = d->dsn ? d->dsn : "No DSN";
9043  break;
9044  case SQL_DIAG_SQLSTATE:
9045  logmsg = sqlst;
9046  break;
9047  case SQL_DIAG_MESSAGE_TEXT:
9048  if (info) {
9049  clrmsg = logmsg;
9050  }
9051  break;
9052  case SQL_DIAG_NUMBER:
9053  naterr = 1;
9054  /* fall through */
9055  case SQL_DIAG_NATIVE:
9056  len = strlen(logmsg);
9057  if (len == 0) {
9058  ret = SQL_NO_DATA;
9059  goto done;
9060  }
9061  if (info) {
9062  *((SQLINTEGER *) info) = naterr;
9063  }
9064  ret = SQL_SUCCESS;
9065  goto done;
9066  case SQL_DIAG_DYNAMIC_FUNCTION:
9067  logmsg = "";
9068  break;
9069  case SQL_DIAG_CURSOR_ROW_COUNT:
9070  if (htype == SQL_HANDLE_STMT) {
9071  SQLULEN count;
9072 
9073  count = (s->isselect == 1 || s->isselect == -1) ? s->nrows : 0;
9074  *((SQLULEN *) info) = count;
9075  ret = SQL_SUCCESS;
9076  }
9077  goto done;
9078  case SQL_DIAG_ROW_COUNT:
9079  if (htype == SQL_HANDLE_STMT) {
9080  SQLULEN count;
9081 
9082  count = s->isselect ? 0 : s->nrows;
9083  *((SQLULEN *) info) = count;
9084  ret = SQL_SUCCESS;
9085  }
9086  goto done;
9087  default:
9088  goto done;
9089  }
9090  if (info && buflen > 0) {
9091  ((char *) info)[0] = '\0';
9092  }
9093  len = strlen(logmsg);
9094  if (len == 0) {
9095  ret = SQL_NO_DATA;
9096  goto done;
9097  }
9098  if (stringlen) {
9099  *stringlen = len;
9100  }
9101  if (strbuf) {
9102  if (len >= buflen) {
9103  if (info && buflen > 0) {
9104  if (stringlen) {
9105  *stringlen = buflen - 1;
9106  }
9107  strncpy((char *) info, logmsg, buflen);
9108  ((char *) info)[buflen - 1] = '\0';
9109  }
9110  } else if (info) {
9111  strcpy((char *) info, logmsg);
9112  }
9113  }
9114  if (clrmsg) {
9115  *clrmsg = '\0';
9116  }
9117  ret = SQL_SUCCESS;
9118 done:
9119  switch (htype) {
9120  case SQL_HANDLE_DBC:
9121  HDBC_UNLOCK((SQLHDBC) handle);
9122  break;
9123  case SQL_HANDLE_STMT:
9124  HSTMT_UNLOCK((SQLHSTMT) handle);
9125  break;
9126  }
9127  return ret;
9128 }
9129 
9130 #ifndef WINTERFACE
9131 
9143 SQLRETURN SQL_API
9144 SQLGetDiagField(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
9145  SQLSMALLINT id, SQLPOINTER info,
9146  SQLSMALLINT buflen, SQLSMALLINT *stringlen)
9147 {
9148  return drvgetdiagfield(htype, handle, recno, id, info, buflen, stringlen);
9149 }
9150 #endif
9151 
9152 #ifdef WINTERFACE
9153 
9165 SQLRETURN SQL_API
9166 SQLGetDiagFieldW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
9167  SQLSMALLINT id, SQLPOINTER info,
9168  SQLSMALLINT buflen, SQLSMALLINT *stringlen)
9169 {
9170  SQLSMALLINT len;
9171  SQLRETURN ret;
9172 
9173  ret = drvgetdiagfield(htype, handle, recno, id, info, buflen, &len);
9174  if (ret == SQL_SUCCESS) {
9175  if (info) {
9176  switch (id) {
9177  case SQL_DIAG_CLASS_ORIGIN:
9178  case SQL_DIAG_SUBCLASS_ORIGIN:
9179  case SQL_DIAG_CONNECTION_NAME:
9180  case SQL_DIAG_SERVER_NAME:
9181  case SQL_DIAG_SQLSTATE:
9182  case SQL_DIAG_MESSAGE_TEXT:
9183  case SQL_DIAG_DYNAMIC_FUNCTION:
9184  if (len > 0) {
9185  SQLWCHAR *m = NULL;
9186 
9187  m = uc_from_utf((unsigned char *) info, len);
9188  if (m) {
9189  if (buflen) {
9190  buflen /= sizeof (SQLWCHAR);
9191  uc_strncpy(info, m, buflen);
9192  m[len] = 0;
9193  len = min(buflen, uc_strlen(m));
9194  } else {
9195  len = uc_strlen(m);
9196  }
9197  uc_free(m);
9198  len *= sizeof (SQLWCHAR);
9199  } else {
9200  len = 0;
9201  }
9202  }
9203  if (len <= 0) {
9204  len = 0;
9205  if (buflen > 0) {
9206  ((SQLWCHAR *) info)[0] = 0;
9207  }
9208  }
9209  }
9210  } else {
9211  switch (id) {
9212  case SQL_DIAG_CLASS_ORIGIN:
9213  case SQL_DIAG_SUBCLASS_ORIGIN:
9214  case SQL_DIAG_CONNECTION_NAME:
9215  case SQL_DIAG_SERVER_NAME:
9216  case SQL_DIAG_SQLSTATE:
9217  case SQL_DIAG_MESSAGE_TEXT:
9218  case SQL_DIAG_DYNAMIC_FUNCTION:
9219  len *= sizeof (SQLWCHAR);
9220  break;
9221  }
9222  }
9223  if (stringlen) {
9224  *stringlen = len;
9225  }
9226  }
9227  return ret;
9228 }
9229 #endif
9230 
9241 static SQLRETURN
9242 drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9243  SQLINTEGER bufmax, SQLINTEGER *buflen)
9244 {
9245  STMT *s = (STMT *) stmt;
9246  SQLULEN *uval = (SQLULEN *) val;
9247  SQLINTEGER dummy;
9248  char dummybuf[16];
9249 
9250  if (!buflen) {
9251  buflen = &dummy;
9252  }
9253  if (!uval) {
9254  uval = (SQLPOINTER) dummybuf;
9255  }
9256  switch (attr) {
9257  case SQL_QUERY_TIMEOUT:
9258  *uval = 0;
9259  *buflen = sizeof (SQLULEN);
9260  return SQL_SUCCESS;
9261  case SQL_ATTR_CURSOR_TYPE:
9262  *uval = s->curtype;
9263  *buflen = sizeof (SQLULEN);
9264  return SQL_SUCCESS;
9265  case SQL_ATTR_CURSOR_SCROLLABLE:
9266  *uval = (s->curtype != SQL_CURSOR_FORWARD_ONLY) ?
9267  SQL_SCROLLABLE : SQL_NONSCROLLABLE;
9268  *buflen = sizeof (SQLULEN);
9269  return SQL_SUCCESS;
9270 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
9271  case SQL_ATTR_CURSOR_SENSITIVITY:
9272  *uval = SQL_UNSPECIFIED;
9273  *buflen = sizeof (SQLULEN);
9274  return SQL_SUCCESS;
9275 #endif
9276  case SQL_ATTR_ROW_NUMBER:
9277  if (s->s3stmt) {
9278  *uval = (s->s3stmt_rownum < 0) ?
9279  SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
9280  } else {
9281  *uval = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
9282  }
9283  *buflen = sizeof (SQLULEN);
9284  return SQL_SUCCESS;
9285  case SQL_ATTR_ASYNC_ENABLE:
9286  *uval = SQL_ASYNC_ENABLE_OFF;
9287  *buflen = sizeof (SQLULEN);
9288  return SQL_SUCCESS;
9289  case SQL_CONCURRENCY:
9290  *uval = SQL_CONCUR_LOCK;
9291  *buflen = sizeof (SQLULEN);
9292  return SQL_SUCCESS;
9293  case SQL_ATTR_RETRIEVE_DATA:
9294  *uval = s->retr_data;
9295  *buflen = sizeof (SQLULEN);
9296  return SQL_SUCCESS;
9297  case SQL_ROWSET_SIZE:
9298  case SQL_ATTR_ROW_ARRAY_SIZE:
9299  *uval = s->rowset_size;
9300  *buflen = sizeof (SQLULEN);
9301  return SQL_SUCCESS;
9302  /* Needed for some driver managers, but dummies for now */
9303  case SQL_ATTR_IMP_ROW_DESC:
9304  case SQL_ATTR_APP_ROW_DESC:
9305  case SQL_ATTR_IMP_PARAM_DESC:
9306  case SQL_ATTR_APP_PARAM_DESC:
9307  *((SQLHDESC *) uval) = (SQLHDESC) DEAD_MAGIC;
9308  *buflen = sizeof (SQLHDESC);
9309  return SQL_SUCCESS;
9310  case SQL_ATTR_ROW_STATUS_PTR:
9311  *((SQLUSMALLINT **) uval) = s->row_status;
9312  *buflen = sizeof (SQLUSMALLINT *);
9313  return SQL_SUCCESS;
9314  case SQL_ATTR_ROWS_FETCHED_PTR:
9315  *((SQLULEN **) uval) = s->row_count;
9316  *buflen = sizeof (SQLULEN *);
9317  return SQL_SUCCESS;
9318  case SQL_ATTR_USE_BOOKMARKS: {
9319  STMT *s = (STMT *) stmt;
9320 
9321  *(SQLUINTEGER *) uval = s->bkmrk;
9322  *buflen = sizeof (SQLUINTEGER);
9323  return SQL_SUCCESS;
9324  }
9325  case SQL_ATTR_FETCH_BOOKMARK_PTR:
9326  *(SQLPOINTER *) uval = s->bkmrkptr;
9327  *buflen = sizeof (SQLPOINTER);
9328  return SQL_SUCCESS;
9329  case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
9330  *((SQLULEN **) uval) = s->parm_bind_offs;
9331  *buflen = sizeof (SQLULEN *);
9332  return SQL_SUCCESS;
9333  case SQL_ATTR_PARAM_BIND_TYPE:
9334  *((SQLULEN *) uval) = s->parm_bind_type;
9335  *buflen = sizeof (SQLULEN);
9336  return SQL_SUCCESS;
9337  case SQL_ATTR_PARAM_OPERATION_PTR:
9338  *((SQLUSMALLINT **) uval) = s->parm_oper;
9339  *buflen = sizeof (SQLUSMALLINT *);
9340  return SQL_SUCCESS;
9341  case SQL_ATTR_PARAM_STATUS_PTR:
9342  *((SQLUSMALLINT **) uval) = s->parm_status;
9343  *buflen = sizeof (SQLUSMALLINT *);
9344  return SQL_SUCCESS;
9345  case SQL_ATTR_PARAMS_PROCESSED_PTR:
9346  *((SQLULEN **) uval) = s->parm_proc;
9347  *buflen = sizeof (SQLULEN *);
9348  return SQL_SUCCESS;
9349  case SQL_ATTR_PARAMSET_SIZE:
9350  *((SQLULEN *) uval) = s->paramset_size;
9351  *buflen = sizeof (SQLULEN);
9352  return SQL_SUCCESS;
9353  case SQL_ATTR_ROW_BIND_TYPE:
9354  *(SQLULEN *) uval = s->bind_type;
9355  *buflen = sizeof (SQLULEN);
9356  return SQL_SUCCESS;
9357  case SQL_ATTR_ROW_BIND_OFFSET_PTR:
9358  *((SQLULEN **) uval) = s->bind_offs;
9359  *buflen = sizeof (SQLULEN *);
9360  return SQL_SUCCESS;
9361  case SQL_ATTR_MAX_ROWS:
9362  *((SQLULEN *) uval) = s->max_rows;
9363  *buflen = sizeof (SQLULEN);
9364  return SQL_SUCCESS;
9365  case SQL_ATTR_MAX_LENGTH:
9366  *((SQLULEN *) uval) = 1000000000;
9367  *buflen = sizeof (SQLULEN);
9368  return SQL_SUCCESS;
9369 #ifdef SQL_ATTR_METADATA_ID
9370  case SQL_ATTR_METADATA_ID:
9371  *((SQLULEN *) uval) = SQL_FALSE;
9372  *buflen = sizeof (SQLULEN);
9373  return SQL_SUCCESS;
9374 #endif
9375  }
9376  return drvunimplstmt(stmt);
9377 }
9378 
9379 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
9380 
9390 SQLRETURN SQL_API
9391 SQLGetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9392  SQLINTEGER bufmax, SQLINTEGER *buflen)
9393 {
9394  SQLRETURN ret;
9395 
9396  HSTMT_LOCK(stmt);
9397  ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
9398  HSTMT_UNLOCK(stmt);
9399  return ret;
9400 }
9401 #endif
9402 
9403 #ifdef WINTERFACE
9404 
9414 SQLRETURN SQL_API
9415 SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9416  SQLINTEGER bufmax, SQLINTEGER *buflen)
9417 {
9418  SQLRETURN ret;
9419 
9420  HSTMT_LOCK(stmt);
9421  ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
9422  HSTMT_UNLOCK(stmt);
9423  return ret;
9424 }
9425 #endif
9426 
9436 static SQLRETURN
9437 drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9438  SQLINTEGER buflen)
9439 {
9440  STMT *s = (STMT *) stmt;
9441 #if defined(SQL_BIGINT) && defined(__WORDSIZE) && (__WORDSIZE == 64)
9442  SQLBIGINT uval;
9443 
9444  uval = (SQLBIGINT) val;
9445 #else
9446  SQLULEN uval;
9447 
9448  uval = (SQLULEN) val;
9449 #endif
9450  switch (attr) {
9451  case SQL_ATTR_CURSOR_TYPE:
9452  if (val == (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY) {
9453  s->curtype = SQL_CURSOR_FORWARD_ONLY;
9454  } else {
9455  s->curtype = SQL_CURSOR_STATIC;
9456  }
9457  if (val != (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY &&
9458  val != (SQLPOINTER) SQL_CURSOR_STATIC) {
9459  goto e01s02;
9460  }
9461  return SQL_SUCCESS;
9462  case SQL_ATTR_CURSOR_SCROLLABLE:
9463  if (val == (SQLPOINTER) SQL_NONSCROLLABLE) {
9464  s->curtype = SQL_CURSOR_FORWARD_ONLY;
9465  } else {
9466  s->curtype = SQL_CURSOR_STATIC;
9467  }
9468  return SQL_SUCCESS;
9469  case SQL_ATTR_ASYNC_ENABLE:
9470  if (val != (SQLPOINTER) SQL_ASYNC_ENABLE_OFF) {
9471  e01s02:
9472  setstat(s, -1, "option value changed", "01S02");
9473  return SQL_SUCCESS_WITH_INFO;
9474  }
9475  return SQL_SUCCESS;
9476  case SQL_CONCURRENCY:
9477  if (val != (SQLPOINTER) SQL_CONCUR_LOCK) {
9478  goto e01s02;
9479  }
9480  return SQL_SUCCESS;
9481 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
9482  case SQL_ATTR_CURSOR_SENSITIVITY:
9483  if (val != (SQLPOINTER) SQL_UNSPECIFIED) {
9484  goto e01s02;
9485  }
9486  return SQL_SUCCESS;
9487 #endif
9488  case SQL_ATTR_QUERY_TIMEOUT:
9489  return SQL_SUCCESS;
9490  case SQL_ATTR_RETRIEVE_DATA:
9491  if (val != (SQLPOINTER) SQL_RD_ON &&
9492  val != (SQLPOINTER) SQL_RD_OFF) {
9493  goto e01s02;
9494  }
9495  s->retr_data = uval;
9496  return SQL_SUCCESS;
9497  case SQL_ROWSET_SIZE:
9498  case SQL_ATTR_ROW_ARRAY_SIZE:
9499  if (uval < 1) {
9500  setstat(s, -1, "invalid rowset size", "HY000");
9501  return SQL_ERROR;
9502  } else {
9503  SQLUSMALLINT *rst = &s->row_status1;
9504 
9505  if (uval > 1) {
9506  rst = xmalloc(sizeof (SQLUSMALLINT) * uval);
9507  if (!rst) {
9508  return nomem(s);
9509  }
9510  }
9511  if (s->row_status0 != &s->row_status1) {
9512  freep(&s->row_status0);
9513  }
9514  s->row_status0 = rst;
9515  s->rowset_size = uval;
9516  }
9517  return SQL_SUCCESS;
9518  case SQL_ATTR_ROW_STATUS_PTR:
9519  s->row_status = (SQLUSMALLINT *) val;
9520  return SQL_SUCCESS;
9521  case SQL_ATTR_ROWS_FETCHED_PTR:
9522  s->row_count = (SQLULEN *) val;
9523  return SQL_SUCCESS;
9524  case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
9525  s->parm_bind_offs = (SQLULEN *) val;
9526  return SQL_SUCCESS;
9527  case SQL_ATTR_PARAM_BIND_TYPE:
9528  s->parm_bind_type = uval;
9529  return SQL_SUCCESS;
9530  case SQL_ATTR_PARAM_OPERATION_PTR:
9531  s->parm_oper = (SQLUSMALLINT *) val;
9532  return SQL_SUCCESS;
9533  case SQL_ATTR_PARAM_STATUS_PTR:
9534  s->parm_status = (SQLUSMALLINT *) val;
9535  return SQL_SUCCESS;
9536  case SQL_ATTR_PARAMS_PROCESSED_PTR:
9537  s->parm_proc = (SQLULEN *) val;
9538  return SQL_SUCCESS;
9539  case SQL_ATTR_PARAMSET_SIZE:
9540  if (uval < 1) {
9541  goto e01s02;
9542  }
9543  s->paramset_size = uval;
9544  s->paramset_count = 0;
9545  return SQL_SUCCESS;
9546  case SQL_ATTR_ROW_BIND_TYPE:
9547  s->bind_type = uval;
9548  return SQL_SUCCESS;
9549  case SQL_ATTR_ROW_BIND_OFFSET_PTR:
9550  s->bind_offs = (SQLULEN *) val;
9551  return SQL_SUCCESS;
9552  case SQL_ATTR_USE_BOOKMARKS:
9553  if (val != (SQLPOINTER) SQL_UB_OFF &&
9554  val != (SQLPOINTER) SQL_UB_ON &&
9555  val != (SQLPOINTER) SQL_UB_VARIABLE) {
9556  goto e01s02;
9557  }
9558  if (*s->ov3 && val == (SQLPOINTER) SQL_UB_VARIABLE) {
9559  s->bkmrk = SQL_UB_VARIABLE;
9560  return SQL_SUCCESS;
9561  }
9562  if (val == (SQLPOINTER) SQL_UB_VARIABLE) {
9563  s->bkmrk = SQL_UB_ON;
9564  goto e01s02;
9565  }
9566  s->bkmrk = (val == (SQLPOINTER) SQL_UB_ON) ? SQL_UB_ON : SQL_UB_OFF;
9567  return SQL_SUCCESS;
9568  case SQL_ATTR_FETCH_BOOKMARK_PTR:
9569  s->bkmrkptr = (SQLINTEGER *) val;
9570  return SQL_SUCCESS;
9571  case SQL_ATTR_MAX_ROWS:
9572  s->max_rows = uval;
9573  return SQL_SUCCESS;
9574  case SQL_ATTR_MAX_LENGTH:
9575  if (val != (SQLPOINTER) 1000000000) {
9576  goto e01s02;
9577  }
9578  return SQL_SUCCESS;
9579 #ifdef SQL_ATTR_METADATA_ID
9580  case SQL_ATTR_METADATA_ID:
9581  if (val != (SQLPOINTER) SQL_FALSE) {
9582  goto e01s02;
9583  }
9584  return SQL_SUCCESS;
9585 #endif
9586  }
9587  return drvunimplstmt(stmt);
9588 }
9589 
9590 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
9591 
9600 SQLRETURN SQL_API
9601 SQLSetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9602  SQLINTEGER buflen)
9603 {
9604  SQLRETURN ret;
9605 
9606  HSTMT_LOCK(stmt);
9607  ret = drvsetstmtattr(stmt, attr, val, buflen);
9608  HSTMT_UNLOCK(stmt);
9609  return ret;
9610 }
9611 #endif
9612 
9613 #ifdef WINTERFACE
9614 
9623 SQLRETURN SQL_API
9624 SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9625  SQLINTEGER buflen)
9626 {
9627  SQLRETURN ret;
9628 
9629  HSTMT_LOCK(stmt);
9630  ret = drvsetstmtattr(stmt, attr, val, buflen);
9631  HSTMT_UNLOCK(stmt);
9632  return ret;
9633 }
9634 #endif
9635 
9644 static SQLRETURN
9645 drvgetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9646 {
9647  STMT *s = (STMT *) stmt;
9648  SQLUINTEGER *ret = (SQLUINTEGER *) param;
9649 
9650  switch (opt) {
9651  case SQL_QUERY_TIMEOUT:
9652  *ret = 0;
9653  return SQL_SUCCESS;
9654  case SQL_CURSOR_TYPE:
9655  *ret = s->curtype;
9656  return SQL_SUCCESS;
9657  case SQL_ROW_NUMBER:
9658  if (s->s3stmt) {
9659  *ret = (s->s3stmt_rownum < 0) ?
9660  SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
9661  } else {
9662  *ret = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
9663  }
9664  return SQL_SUCCESS;
9665  case SQL_ASYNC_ENABLE:
9666  *ret = SQL_ASYNC_ENABLE_OFF;
9667  return SQL_SUCCESS;
9668  case SQL_CONCURRENCY:
9669  *ret = SQL_CONCUR_LOCK;
9670  return SQL_SUCCESS;
9671  case SQL_ATTR_RETRIEVE_DATA:
9672  *ret = s->retr_data;
9673  return SQL_SUCCESS;
9674  case SQL_ROWSET_SIZE:
9675  case SQL_ATTR_ROW_ARRAY_SIZE:
9676  *ret = s->rowset_size;
9677  return SQL_SUCCESS;
9678  case SQL_ATTR_MAX_ROWS:
9679  *ret = s->max_rows;
9680  return SQL_SUCCESS;
9681  case SQL_ATTR_MAX_LENGTH:
9682  *ret = 1000000000;
9683  return SQL_SUCCESS;
9684  }
9685  return drvunimplstmt(stmt);
9686 }
9687 
9696 SQLRETURN SQL_API
9697 SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9698 {
9699  SQLRETURN ret;
9700 
9701  HSTMT_LOCK(stmt);
9702  ret = drvgetstmtoption(stmt, opt, param);
9703  HSTMT_UNLOCK(stmt);
9704  return ret;
9705 }
9706 
9707 #ifdef WINTERFACE
9708 
9716 SQLRETURN SQL_API
9717 SQLGetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9718 {
9719  SQLRETURN ret;
9720 
9721  HSTMT_LOCK(stmt);
9722  ret = drvgetstmtoption(stmt, opt, param);
9723  HSTMT_UNLOCK(stmt);
9724  return ret;
9725 }
9726 #endif
9727 
9736 static SQLRETURN
9737 drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
9738 {
9739  STMT *s = (STMT *) stmt;
9740 
9741  switch (opt) {
9742  case SQL_CURSOR_TYPE:
9743  if (param == SQL_CURSOR_FORWARD_ONLY) {
9744  s->curtype = param;
9745  } else {
9746  s->curtype = SQL_CURSOR_STATIC;
9747  }
9748  if (param != SQL_CURSOR_FORWARD_ONLY &&
9749  param != SQL_CURSOR_STATIC) {
9750  goto e01s02;
9751  }
9752  return SQL_SUCCESS;
9753  case SQL_ASYNC_ENABLE:
9754  if (param != SQL_ASYNC_ENABLE_OFF) {
9755  goto e01s02;
9756  }
9757  return SQL_SUCCESS;
9758  case SQL_CONCURRENCY:
9759  if (param != SQL_CONCUR_LOCK) {
9760  goto e01s02;
9761  }
9762  return SQL_SUCCESS;
9763  case SQL_QUERY_TIMEOUT:
9764  return SQL_SUCCESS;
9765  case SQL_RETRIEVE_DATA:
9766  if (param != SQL_RD_ON && param != SQL_RD_OFF) {
9767  e01s02:
9768  setstat(s, -1, "option value changed", "01S02");
9769  return SQL_SUCCESS_WITH_INFO;
9770  }
9771  s->retr_data = (int) param;
9772  return SQL_SUCCESS;
9773  case SQL_ROWSET_SIZE:
9774  case SQL_ATTR_ROW_ARRAY_SIZE:
9775  if (param < 1) {
9776  setstat(s, -1, "invalid rowset size", "HY000");
9777  return SQL_ERROR;
9778  } else {
9779  SQLUSMALLINT *rst = &s->row_status1;
9780 
9781  if (param > 1) {
9782  rst = xmalloc(sizeof (SQLUSMALLINT) * param);
9783  if (!rst) {
9784  return nomem(s);
9785  }
9786  }
9787  if (s->row_status0 != &s->row_status1) {
9788  freep(&s->row_status0);
9789  }
9790  s->row_status0 = rst;
9791  s->rowset_size = param;
9792  }
9793  return SQL_SUCCESS;
9794  case SQL_ATTR_MAX_ROWS:
9795  s->max_rows = param;
9796  return SQL_SUCCESS;
9797  case SQL_ATTR_MAX_LENGTH:
9798  if (param != 1000000000) {
9799  goto e01s02;
9800  }
9801  return SQL_SUCCESS;
9802  }
9803  return drvunimplstmt(stmt);
9804 }
9805 
9814 SQLRETURN SQL_API
9815 SQLSetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt,
9817 {
9818  SQLRETURN ret;
9819 
9820  HSTMT_LOCK(stmt);
9821  ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
9822  HSTMT_UNLOCK(stmt);
9823  return ret;
9824 }
9825 
9826 #ifdef WINTERFACE
9827 
9835 SQLRETURN SQL_API
9836 SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt,
9838 {
9839  SQLRETURN ret;
9840 
9841  HSTMT_LOCK(stmt);
9842  ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
9843  HSTMT_UNLOCK(stmt);
9844  return ret;
9845 }
9846 #endif
9847 
9854 static SQLRETURN
9856 {
9857  int i;
9858 
9859  if (!s->bindcols || s->nbindcols < s->ncols) {
9860 unbound:
9861  setstat(s, -1, "unbound columns", (*s->ov3) ? "HY000" : "S1000");
9862  return SQL_ERROR;
9863  }
9864  for (i = 0; i < s->ncols; i++) {
9865  BINDCOL *b = &s->bindcols[i];
9866 
9867  if (b->type == SQL_UNKNOWN_TYPE || !b->valp) {
9868  goto unbound;
9869  }
9870  }
9871  return SQL_SUCCESS;
9872 }
9873 
9885 static SQLRETURN
9886 setposbind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
9887 {
9888  DBC *d = (DBC *) s->dbc;
9889  SQLPOINTER dp = 0;
9890  SQLLEN *lp = 0;
9891  BINDCOL *b = &s->bindcols[i];
9892  COL *c = &s->cols[i];
9893  char strbuf[128], *cp;
9894 
9895  if (b->valp) {
9896  if (s->bind_type != SQL_BIND_BY_COLUMN) {
9897  dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
9898  } else {
9899  dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
9900  }
9901  if (s->bind_offs) {
9902  dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
9903  }
9904  }
9905  if (b->lenp) {
9906  if (s->bind_type != SQL_BIND_BY_COLUMN) {
9907  lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
9908  } else {
9909  lp = b->lenp + rsi;
9910  }
9911  if (s->bind_offs) {
9912  lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
9913  }
9914  }
9915  if (!dp || !lp) {
9916  setstat(s, -1, "unbound column in positional update",
9917  (*s->ov3) ? "HY000" : "S1000");
9918  return SQL_ERROR;
9919  }
9920  if (*lp == SQL_NULL_DATA) {
9921  sqlite3_bind_null(stmt, si);
9922  if (d->trace) {
9923  fprintf(d->trace, "-- parameter %d: NULL\n", si);
9924  fflush(d->trace);
9925  }
9926  return SQL_SUCCESS;
9927  }
9928  switch (b->type) {
9929  case SQL_C_UTINYINT:
9930  case SQL_C_TINYINT:
9931  case SQL_C_STINYINT:
9932  sqlite3_bind_int(stmt, si, *(SQLCHAR *) dp);
9933  if (d->trace) {
9934  fprintf(d->trace, "-- parameter %d: %d\n", si, *(SQLCHAR *) dp);
9935  fflush(d->trace);
9936  }
9937  break;
9938 #ifdef SQL_BIT
9939  case SQL_C_BIT:
9940  sqlite3_bind_int(stmt, si, (*(SQLCHAR *) dp) ? 1 : 0);
9941  if (d->trace) {
9942  fprintf(d->trace, "-- parameter %d: %d\n", si,
9943  (*(SQLCHAR *) dp) ? 1 : 0);
9944  fflush(d->trace);
9945  }
9946  break;
9947 #endif
9948  case SQL_C_USHORT:
9949  sqlite3_bind_int(stmt, si, *(SQLUSMALLINT *) dp);
9950  if (d->trace) {
9951  fprintf(d->trace, "-- parameter %d: %d\n", si,
9952  *(SQLUSMALLINT *) dp);
9953  fflush(d->trace);
9954  }
9955  break;
9956  case SQL_C_SHORT:
9957  case SQL_C_SSHORT:
9958  sqlite3_bind_int(stmt, si, *(SQLSMALLINT *) dp);
9959  if (d->trace) {
9960  fprintf(d->trace, "-- parameter %d: %d\n", si,
9961  *(SQLSMALLINT *) dp);
9962  fflush(d->trace);
9963  }
9964  break;
9965  case SQL_C_ULONG:
9966  sqlite3_bind_int(stmt, si, *(SQLUINTEGER *) dp);
9967  if (d->trace) {
9968  fprintf(d->trace, "-- parameter %d: %ld\n", si,
9969  (long) *(SQLUINTEGER *) dp);
9970  fflush(d->trace);
9971  }
9972  break;
9973  case SQL_C_LONG:
9974  case SQL_C_SLONG:
9975  sqlite3_bind_int(stmt, si, *(SQLINTEGER *) dp);
9976  if (d->trace) {
9977  fprintf(d->trace, "-- parameter %d: %ld\n", si,
9978  (long) *(SQLINTEGER *) dp);
9979  fflush(d->trace);
9980  }
9981  break;
9982 #ifdef SQL_BIGINT
9983  case SQL_C_UBIGINT:
9984  case SQL_C_SBIGINT:
9985  sqlite3_bind_int64(stmt, si, *(SQLBIGINT *) dp);
9986  if (d->trace) {
9987  fprintf(d->trace,
9988 #ifdef _WIN32
9989  "-- parameter %d: %I64d\n",
9990 #else
9991  "-- parameter %d: %lld\n",
9992 #endif
9993  si, (sqlite_int64) *(SQLBIGINT *) dp);
9994  fflush(d->trace);
9995  }
9996  break;
9997 #endif
9998  case SQL_C_FLOAT:
9999  sqlite3_bind_double(stmt, si, *(float *) dp);
10000  if (d->trace) {
10001  fprintf(d->trace, "-- parameter %d: %g\n", si,
10002  *(float *) dp);
10003  fflush(d->trace);
10004  }
10005  break;
10006  case SQL_C_DOUBLE:
10007  sqlite3_bind_double(stmt, si, *(double *) dp);
10008  if (d->trace) {
10009  fprintf(d->trace, "-- parameter %d: %g\n", si,
10010  *(double *) dp);
10011  fflush(d->trace);
10012  }
10013  break;
10014  case SQL_C_BINARY:
10015  sqlite3_bind_blob(stmt, si, (char *) dp, *lp, SQLITE_STATIC);
10016  if (d->trace) {
10017  fprintf(d->trace, "-- parameter %d: [BLOB]\n", si);
10018  fflush(d->trace);
10019  }
10020  break;
10021 #ifdef WCHARSUPPORT
10022  case SQL_C_WCHAR:
10023  cp = uc_to_utf((SQLWCHAR *) dp, *lp);
10024  if (!cp) {
10025  return nomem(s);
10026  }
10027  sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
10028  if (d->trace) {
10029  fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
10030  fflush(d->trace);
10031  }
10032  uc_free(cp);
10033  break;
10034 #endif
10035  case SQL_C_CHAR:
10036 #if defined(_WIN32) || defined(_WIN64)
10037  if (*s->oemcp) {
10038  cp = wmb_to_utf((char *) dp, *lp);
10039  if (!cp) {
10040  return nomem(s);
10041  }
10042  sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
10043  if (d->trace) {
10044  fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
10045  fflush(d->trace);
10046  }
10047  uc_free(cp);
10048  } else
10049 #endif
10050  {
10051  if (*lp == SQL_NTS) {
10052  sqlite3_bind_text(stmt, si, (char *) dp, -1,
10053  SQLITE_STATIC);
10054  if (d->trace) {
10055  fprintf(d->trace, "-- parameter %d: '%s'\n", si,
10056  (char *) dp);
10057  fflush(d->trace);
10058  }
10059  } else {
10060  sqlite3_bind_text(stmt, si, (char *) dp, *lp,
10061  SQLITE_STATIC);
10062  if (d->trace) {
10063  fprintf(d->trace, "-- parameter %d: '%*s'\n", si,
10064  (int) *lp, (char *) dp);
10065  fflush(d->trace);
10066  }
10067  }
10068  }
10069  break;
10070 #ifdef SQL_C_TYPE_DATE
10071  case SQL_C_TYPE_DATE:
10072 #endif
10073  case SQL_C_DATE:
10074  if (*s->jdconv) {
10075  int a, b, x1, x2, y, m, dd;
10076  double v;
10077 
10078  y = ((DATE_STRUCT *) dp)->year;
10079  m = ((DATE_STRUCT *) dp)->month;
10080  dd = ((DATE_STRUCT *) dp)->day;
10081  if (m <= 2) {
10082  y--;
10083  m += 12;
10084  }
10085  a = y / 100;
10086  b = 2 - a + (a / 4);
10087  x1 = 36525 * (y + 4716) / 100;
10088  x2 = 306001 * (m + 1) / 10000;
10089  v = x1 + x2 + dd + b - 1524.5;
10090  sqlite3_bind_double(stmt, si, v);
10091  if (d->trace) {
10092  fprintf(d->trace, "-- parameter %d: %g\n", si, v);
10093  fflush(d->trace);
10094  }
10095  } else {
10096  sprintf(strbuf, "%04d-%02d-%02d",
10097  ((DATE_STRUCT *) dp)->year,
10098  ((DATE_STRUCT *) dp)->month,
10099  ((DATE_STRUCT *) dp)->day);
10100  sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
10101  if (d->trace) {
10102  fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
10103  fflush(d->trace);
10104  }
10105  }
10106  break;
10107 #ifdef SQL_C_TYPE_TIME
10108  case SQL_C_TYPE_TIME:
10109 #endif
10110  case SQL_C_TIME:
10111  if (*s->jdconv) {
10112  double v;
10113 
10114  v = 2451544.5 +
10115  (((TIME_STRUCT *) dp)->hour * 3600000.0 +
10116  ((TIME_STRUCT *) dp)->minute * 60000.0 +
10117  ((TIME_STRUCT *) dp)->second * 1000.0) / 86400000.0;
10118  sqlite3_bind_double(stmt, si, v);
10119  if (d->trace) {
10120  fprintf(d->trace, "-- parameter %d: %g\n", si, v);
10121  fflush(d->trace);
10122  }
10123  } else {
10124  sprintf(strbuf, "%02d:%02d:%02d",
10125  ((TIME_STRUCT *) dp)->hour,
10126  ((TIME_STRUCT *) dp)->minute,
10127  ((TIME_STRUCT *) dp)->second);
10128  sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
10129  if (d->trace) {
10130  fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
10131  fflush(d->trace);
10132  }
10133  }
10134  break;
10135 #ifdef SQL_C_TYPE_TIMESTAMP
10136  case SQL_C_TYPE_TIMESTAMP:
10137 #endif
10138  case SQL_C_TIMESTAMP:
10139  if (*s->jdconv) {
10140  int a, b, x1, x2, y, m, dd;
10141  double v;
10142 
10143  y = ((TIMESTAMP_STRUCT *) dp)->year;
10144  m = ((TIMESTAMP_STRUCT *) dp)->month;
10145  dd = ((TIMESTAMP_STRUCT *) dp)->day;
10146  if (m <= 2) {
10147  y--;
10148  m += 12;
10149  }
10150  a = y / 100;
10151  b = 2 - a + (a / 4);
10152  x1 = 36525 * (y + 4716) / 100;
10153  x2 = 306001 * (m + 1) / 10000;
10154  v = x1 + x2 + dd + b - 1524.5 +
10155  (((TIMESTAMP_STRUCT *) dp)->hour * 3600000.0 +
10156  ((TIMESTAMP_STRUCT *) dp)->minute * 60000.0 +
10157  ((TIMESTAMP_STRUCT *) dp)->second * 1000.0 +
10158  ((TIMESTAMP_STRUCT *) dp)->fraction / 1.0E6)
10159  / 86400000.0;
10160  sqlite3_bind_double(stmt, si, v);
10161  if (d->trace) {
10162  fprintf(d->trace, "-- parameter %d: %g\n", si, v);
10163  fflush(d->trace);
10164  }
10165  } else {
10166  int frac;
10167 
10168  frac = (int) ((TIMESTAMP_STRUCT *) dp)->fraction;
10169  frac /= 1000000;
10170  frac = frac % 1000;
10171  if (frac < 0) {
10172  frac = 0;
10173  }
10174  if (c->prec && c->prec <= 16) {
10175  sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
10176  ((TIMESTAMP_STRUCT *) dp)->year,
10177  ((TIMESTAMP_STRUCT *) dp)->month,
10178  ((TIMESTAMP_STRUCT *) dp)->day,
10179  ((TIMESTAMP_STRUCT *) dp)->hour,
10180  ((TIMESTAMP_STRUCT *) dp)->minute);
10181  } else if (c->prec && c->prec <= 19) {
10182  sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
10183  ((TIMESTAMP_STRUCT *) dp)->year,
10184  ((TIMESTAMP_STRUCT *) dp)->month,
10185  ((TIMESTAMP_STRUCT *) dp)->day,
10186  ((TIMESTAMP_STRUCT *) dp)->hour,
10187  ((TIMESTAMP_STRUCT *) dp)->minute,
10188  ((TIMESTAMP_STRUCT *) dp)->second);
10189  } else {
10190  sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
10191  ((TIMESTAMP_STRUCT *) dp)->year,
10192  ((TIMESTAMP_STRUCT *) dp)->month,
10193  ((TIMESTAMP_STRUCT *) dp)->day,
10194  ((TIMESTAMP_STRUCT *) dp)->hour,
10195  ((TIMESTAMP_STRUCT *) dp)->minute,
10196  ((TIMESTAMP_STRUCT *) dp)->second,
10197  frac);
10198  }
10199  sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
10200  if (d->trace) {
10201  fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
10202  fflush(d->trace);
10203  }
10204  }
10205  break;
10206  default:
10207  setstat(s, -1, "unsupported column type in positional update",
10208  (*s->ov3) ? "HY000" : "S1000");
10209  return SQL_ERROR;
10210  }
10211  return SQL_SUCCESS;
10212 }
10213 
10225 static SQLRETURN
10226 setposibind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
10227 {
10228  DBC *d = (DBC *) s->dbc;
10229  char **data;
10230  int pos;
10231 
10232  pos = s->rowprs;
10233  if (pos < 0) {
10234  setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
10235  return SQL_ERROR;
10236  }
10237  pos += rsi;
10238  data = s->rows + s->ncols + (pos * s->ncols) + i;
10239  if (*data == NULL) {
10240  sqlite3_bind_null(stmt, si);
10241  if (d->trace) {
10242  fprintf(d->trace, "-- parameter %d: NULL\n", si);
10243  fflush(d->trace);
10244  }
10245  } else {
10246  sqlite3_bind_text(stmt, si, *data, -1, SQLITE_STATIC);
10247  if (d->trace) {
10248  fprintf(d->trace, "-- parameter %d: '%s'\n", si, *data);
10249  fflush(d->trace);
10250  }
10251  }
10252  return SQL_SUCCESS;
10253 }
10254 
10262 static SQLRETURN
10263 setposrefr(STMT *s, int rsi)
10264 {
10265  int i, withinfo = 0;
10266  SQLRETURN ret = SQL_SUCCESS;
10267 
10268  for (i = 0; s->bindcols && i < s->ncols; i++) {
10269  BINDCOL *b = &s->bindcols[i];
10270  SQLPOINTER dp = 0;
10271  SQLLEN *lp = 0;
10272 
10273  b->offs = 0;
10274  if (b->valp) {
10275  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10276  dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
10277  } else {
10278  dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
10279  }
10280  if (s->bind_offs) {
10281  dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
10282  }
10283  }
10284  if (b->lenp) {
10285  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10286  lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
10287  } else {
10288  lp = b->lenp + rsi;
10289  }
10290  if (s->bind_offs) {
10291  lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
10292  }
10293  }
10294  if (dp || lp) {
10295  int rowp = s->rowp;
10296 
10297  s->rowp = s->rowprs + rsi;
10298  ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp,
10299  b->max, lp, 0);
10300  s->rowp = rowp;
10301  if (!SQL_SUCCEEDED(ret)) {
10302  s->row_status0[rsi] = SQL_ROW_ERROR;
10303  break;
10304  }
10305  if (ret != SQL_SUCCESS) {
10306  withinfo = 1;
10307 #ifdef SQL_ROW_SUCCESS_WITH_INFO
10308  s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
10309 #endif
10310  }
10311  }
10312  }
10313  if (SQL_SUCCEEDED(ret)) {
10314  ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
10315  }
10316  return ret;
10317 }
10318 
10328 static SQLRETURN
10329 drvsetpos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10330 {
10331  STMT *s = (STMT *) stmt;
10332  DBC *d = (DBC *) s->dbc;
10333  int rowp, i, k, rc, nretry = 0;
10334  dstr *sql = 0;
10335  const char *endp;
10336  sqlite3_stmt *s3stmt = NULL;
10337  SQLRETURN ret;
10338 
10339  if (lock != SQL_LOCK_NO_CHANGE) {
10340  setstat(s, -1, "unsupported locking mode",
10341  (*s->ov3) ? "HY000" : "S1000");
10342  return SQL_ERROR;
10343  }
10344  if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10345  setstat(s, -1, "incompatible statement",
10346  (*s->ov3) ? "HY000" : "S1000");
10347  return SQL_ERROR;
10348  }
10349  if (op == SQL_ADD) {
10350  if (s->one_tbl <= 0) {
10351  setstat(s, -1, "incompatible rowset",
10352  (*s->ov3) ? "HY000" : "S1000");
10353  return SQL_ERROR;
10354  }
10355  if (row == 0 || row > s->rowset_size + 1) {
10356  goto rowoor;
10357  }
10358  ret = chkunbound(s);
10359  if (ret != SQL_SUCCESS) {
10360  return ret;
10361  }
10362  sql = dsappend(sql, "INSERT INTO ");
10363  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10364  sql = dsappendq(sql, s->dyncols[0].db);
10365  sql = dsappend(sql, ".");
10366  }
10367  sql = dsappendq(sql, s->dyncols[0].table);
10368  for (i = 0; i < s->ncols; i++) {
10369  sql = dsappend(sql, (i > 0) ? "," : "(");
10370  sql = dsappendq(sql, s->dyncols[i].column);
10371  }
10372  sql = dsappend(sql, ") VALUES ");
10373  for (i = 0; i < s->ncols; i++) {
10374  sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10375  }
10376  sql = dsappend(sql, ")");
10377  if (dserr(sql)) {
10378  dsfree(sql);
10379  return nomem(s);
10380  }
10381 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10382  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10383 #else
10384  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10385 #endif
10386  do {
10387  s3stmt = NULL;
10388 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10389  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10390  &s3stmt, &endp);
10391 #else
10392  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10393  &s3stmt, &endp);
10394 #endif
10395  if (rc != SQLITE_OK) {
10396  if (s3stmt) {
10397  sqlite3_finalize(s3stmt);
10398  s3stmt = NULL;
10399  }
10400  }
10401  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10402  dbtracerc(d, rc, NULL);
10403  dsfree(sql);
10404  if (rc != SQLITE_OK) {
10405 istmterr:
10406  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10407  sqlite3_errmsg(d->sqlite), rc);
10408  if (s3stmt) {
10409  dbtraceapi(d, "sqlite3_finalize", NULL);
10410  sqlite3_finalize(s3stmt);
10411  }
10412  return SQL_ERROR;
10413  }
10414  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10415  ret = setposbind(s, s3stmt, i, k, row - 1);
10416  if (ret != SQL_SUCCESS) {
10417  dbtraceapi(d, "sqlite3_finalize", NULL);
10418  sqlite3_finalize(s3stmt);
10419  return ret;
10420  }
10421  k++;
10422  }
10423  rc = sqlite3_step(s3stmt);
10424  if (rc != SQLITE_DONE) {
10425  goto istmterr;
10426  }
10427  sqlite3_finalize(s3stmt);
10428  if (sqlite3_changes(d->sqlite) > 0 && row <= s->rowset_size) {
10429  if (s->row_status0) {
10430  s->row_status0[row - 1] = SQL_ROW_ADDED;
10431  }
10432  if (s->row_status) {
10433  s->row_status[row - 1] = SQL_ROW_ADDED;
10434  }
10435  }
10436  return SQL_SUCCESS;
10437  } else if (op == SQL_UPDATE || op == SQL_DELETE) {
10438  if (s->one_tbl <= 0 || s->has_pk <= 0) {
10439  setstat(s, -1, "incompatible rowset",
10440  (*s->ov3) ? "HY000" : "S1000");
10441  return SQL_ERROR;
10442  }
10443  if (row == 0) {
10444  ret = SQL_SUCCESS;
10445  for (i = 1; i <= s->rowset_size; i++) {
10446  ret = drvsetpos(stmt, i, op, lock);
10447  if (!SQL_SUCCEEDED(ret)) {
10448  break;
10449  }
10450  }
10451  return ret;
10452  }
10453  if (row > s->rowset_size) {
10454  goto rowoor;
10455  }
10456  }
10457  if (op != SQL_POSITION && op != SQL_REFRESH &&
10458  op != SQL_DELETE && op != SQL_UPDATE) {
10459  return drvunimplstmt(stmt);
10460  }
10461  if (op == SQL_POSITION) {
10462  rowp = s->rowp + row - 1;
10463  if (!s->rows || row == 0 || rowp < -1 || rowp >= s->nrows) {
10464 rowoor:
10465  setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
10466  return SQL_ERROR;
10467  }
10468  s->rowp = rowp;
10469  } else if (op == SQL_REFRESH) {
10470  if (row > s->rowset_size) {
10471  goto rowoor;
10472  }
10473  if (row == 0) {
10474  ret = SQL_SUCCESS;
10475  for (i = 0; i < s->rowset_size; i++) {
10476  ret = setposrefr(s, i);
10477  if (!SQL_SUCCEEDED(ret)) {
10478  break;
10479  }
10480  }
10481  return ret;
10482  }
10483  return setposrefr(s, row - 1);
10484  } else if (op == SQL_DELETE) {
10485  sql = dsappend(sql, "DELETE FROM ");
10486  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10487  sql = dsappendq(sql, s->dyncols[0].db);
10488  sql = dsappend(sql, ".");
10489  }
10490  sql = dsappendq(sql, s->dyncols[0].table);
10491  for (i = k = 0; i < s->ncols; i++) {
10492  if (s->dyncols[i].ispk <= 0) {
10493  continue;
10494  }
10495  sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10496  sql = dsappendq(sql, s->dyncols[i].column);
10497  sql = dsappend(sql, " = ?");
10498  k++;
10499  }
10500  if (dserr(sql)) {
10501  dsfree(sql);
10502  return nomem(s);
10503  }
10504 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10505  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10506 #else
10507  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10508 #endif
10509  do {
10510  s3stmt = NULL;
10511 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10512  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10513  &s3stmt, &endp);
10514 #else
10515  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10516  &s3stmt, &endp);
10517 #endif
10518  if (rc != SQLITE_OK) {
10519  if (s3stmt) {
10520  sqlite3_finalize(s3stmt);
10521  s3stmt = NULL;
10522  }
10523  }
10524  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10525  dbtracerc(d, rc, NULL);
10526  dsfree(sql);
10527  if (rc != SQLITE_OK) {
10528 dstmterr:
10529  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10530  sqlite3_errmsg(d->sqlite), rc);
10531  if (s3stmt) {
10532  dbtraceapi(d, "sqlite3_finalize", NULL);
10533  sqlite3_finalize(s3stmt);
10534  }
10535  return SQL_ERROR;
10536  }
10537  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10538  if (s->dyncols[i].ispk <= 0) {
10539  continue;
10540  }
10541  ret = setposibind(s, s3stmt, i, k, row - 1);
10542  if (ret != SQL_SUCCESS) {
10543  dbtraceapi(d, "sqlite3_finalize", NULL);
10544  sqlite3_finalize(s3stmt);
10545  return ret;
10546  }
10547  k++;
10548  }
10549  rc = sqlite3_step(s3stmt);
10550  if (rc != SQLITE_DONE) {
10551  goto dstmterr;
10552  }
10553  sqlite3_finalize(s3stmt);
10554  if (sqlite3_changes(d->sqlite) > 0) {
10555  if (s->row_status0) {
10556  s->row_status0[row - 1] = SQL_ROW_DELETED;
10557  }
10558  if (s->row_status) {
10559  s->row_status[row - 1] = SQL_ROW_DELETED;
10560  }
10561  }
10562  return SQL_SUCCESS;
10563  } else if (op == SQL_UPDATE) {
10564  ret = chkunbound(s);
10565  if (ret != SQL_SUCCESS) {
10566  return ret;
10567  }
10568  sql = dsappend(sql, "UPDATE ");
10569  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10570  sql = dsappendq(sql, s->dyncols[0].db);
10571  sql = dsappend(sql, ".");
10572  }
10573  sql = dsappendq(sql, s->dyncols[0].table);
10574  for (i = 0; i < s->ncols; i++) {
10575  sql = dsappend(sql, (i > 0) ? ", " : " SET ");
10576  sql = dsappendq(sql, s->dyncols[i].column);
10577  sql = dsappend(sql, " = ?");
10578  }
10579  for (i = k = 0; i < s->ncols; i++) {
10580  if (s->dyncols[i].ispk <= 0) {
10581  continue;
10582  }
10583  sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10584  sql = dsappendq(sql, s->dyncols[i].column);
10585  sql = dsappend(sql, " = ?");
10586  k++;
10587  }
10588  if (dserr(sql)) {
10589  dsfree(sql);
10590  return nomem(s);
10591  }
10592 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10593  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10594 #else
10595  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10596 #endif
10597  do {
10598  s3stmt = NULL;
10599 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10600  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10601  &s3stmt, &endp);
10602 #else
10603  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10604  &s3stmt, &endp);
10605 #endif
10606  if (rc != SQLITE_OK) {
10607  if (s3stmt) {
10608  sqlite3_finalize(s3stmt);
10609  s3stmt = NULL;
10610  }
10611  }
10612  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10613  dbtracerc(d, rc, NULL);
10614  dsfree(sql);
10615  if (rc != SQLITE_OK) {
10616 ustmterr:
10617  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10618  sqlite3_errmsg(d->sqlite), rc);
10619  if (s3stmt) {
10620  dbtraceapi(d, "sqlite3_finalize", NULL);
10621  sqlite3_finalize(s3stmt);
10622  }
10623  return SQL_ERROR;
10624  }
10625  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10626  ret = setposbind(s, s3stmt, i, k, row - 1);
10627  if (ret != SQL_SUCCESS) {
10628  dbtraceapi(d, "sqlite3_finalize", NULL);
10629  sqlite3_finalize(s3stmt);
10630  return ret;
10631  }
10632  k++;
10633  }
10634  for (i = 0; s->bindcols && i < s->ncols; i++) {
10635  if (s->dyncols[i].ispk <= 0) {
10636  continue;
10637  }
10638  ret = setposibind(s, s3stmt, i, k, row - 1);
10639  if (ret != SQL_SUCCESS) {
10640  dbtraceapi(d, "sqlite3_finalize", NULL);
10641  sqlite3_finalize(s3stmt);
10642  return ret;
10643  }
10644  k++;
10645  }
10646  rc = sqlite3_step(s3stmt);
10647  if (rc != SQLITE_DONE) {
10648  goto ustmterr;
10649  }
10650  sqlite3_finalize(s3stmt);
10651  if (sqlite3_changes(d->sqlite) > 0) {
10652  if (s->row_status0) {
10653  s->row_status0[row - 1] = SQL_ROW_UPDATED;
10654  }
10655  if (s->row_status) {
10656  s->row_status[row - 1] = SQL_ROW_UPDATED;
10657  }
10658  }
10659  return SQL_SUCCESS;
10660  }
10661  return SQL_SUCCESS;
10662 }
10663 
10673 SQLRETURN SQL_API
10674 SQLSetPos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10675 {
10676  SQLRETURN ret;
10677 
10678  HSTMT_LOCK(stmt);
10679  ret = drvsetpos(stmt, row, op, lock);
10680  HSTMT_UNLOCK(stmt);
10681  return ret;
10682 }
10683 
10691 static SQLRETURN
10692 drvbulkoperations(SQLHSTMT stmt, SQLSMALLINT op)
10693 {
10694  STMT *s = (STMT *) stmt;
10695  DBC *d = (DBC *) s->dbc;
10696  int row, i, k, rc, nretry = 0;
10697  dstr *sql = 0;
10698  const char *endp;
10699  sqlite3_stmt *s3stmt = NULL;
10700  SQLRETURN ret;
10701 
10702  if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10703  setstat(s, -1, "incompatible statement",
10704  (*s->ov3) ? "HY000" : "S1000");
10705  return SQL_ERROR;
10706  }
10707  if (op == SQL_ADD) {
10708  if (s->one_tbl <= 0) {
10709  setstat(s, -1, "incompatible rowset",
10710  (*s->ov3) ? "HY000" : "S1000");
10711  return SQL_ERROR;
10712  }
10713  ret = chkunbound(s);
10714  if (ret != SQL_SUCCESS) {
10715  return ret;
10716  }
10717  sql = dsappend(sql, "INSERT INTO ");
10718  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10719  sql = dsappendq(sql, s->dyncols[0].db);
10720  sql = dsappend(sql, ".");
10721  }
10722  sql = dsappendq(sql, s->dyncols[0].table);
10723  for (i = 0; i < s->ncols; i++) {
10724  sql = dsappend(sql, (i > 0) ? "," : "(");
10725  sql = dsappendq(sql, s->dyncols[i].column);
10726  }
10727  sql = dsappend(sql, ") VALUES ");
10728  for (i = 0; i < s->ncols; i++) {
10729  sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10730  }
10731  sql = dsappend(sql, ")");
10732  if (dserr(sql)) {
10733  dsfree(sql);
10734  return nomem(s);
10735  }
10736 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10737  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10738 #else
10739  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10740 #endif
10741  do {
10742  s3stmt = NULL;
10743 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10744  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10745  &s3stmt, &endp);
10746 #else
10747  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10748  &s3stmt, &endp);
10749 #endif
10750  if (rc != SQLITE_OK) {
10751  if (s3stmt) {
10752  sqlite3_finalize(s3stmt);
10753  s3stmt = NULL;
10754  }
10755  }
10756  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10757  dbtracerc(d, rc, NULL);
10758  dsfree(sql);
10759  if (rc != SQLITE_OK) {
10760  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10761  sqlite3_errmsg(d->sqlite), rc);
10762  if (s3stmt) {
10763  dbtraceapi(d, "sqlite3_finalize", NULL);
10764  sqlite3_finalize(s3stmt);
10765  }
10766  return SQL_ERROR;
10767  }
10768  for (row = 0; row < s->rowset_size; row++) {
10769  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10770  ret = setposbind(s, s3stmt, i, k, row);
10771  if (ret != SQL_SUCCESS) {
10772 istmterr:
10773  if (s->row_status0) {
10774  s->row_status0[row] = SQL_ROW_ERROR;
10775  }
10776  if (s->row_status) {
10777  s->row_status[row] = SQL_ROW_ERROR;
10778  }
10779  dbtraceapi(d, "sqlite3_finalize", NULL);
10780  sqlite3_finalize(s3stmt);
10781  return ret;
10782  }
10783  k++;
10784  }
10785  rc = sqlite3_step(s3stmt);
10786  if (rc != SQLITE_DONE) {
10787  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10788  sqlite3_errmsg(d->sqlite), rc);
10789  ret = SQL_ERROR;
10790  goto istmterr;
10791  }
10792  if (sqlite3_changes(d->sqlite) > 0) {
10793  if (s->row_status0) {
10794  s->row_status0[row] = SQL_ROW_ADDED;
10795  }
10796  if (s->row_status) {
10797  s->row_status[row] = SQL_ROW_ADDED;
10798  }
10799  }
10800  if (s->bkmrk == SQL_UB_VARIABLE &&
10801  s->bkmrkcol.type == SQL_C_VARBOOKMARK &&
10802  s->bkmrkcol.valp) {
10803  SQLPOINTER *val;
10804 
10805  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10806  val = (SQLPOINTER)
10807  ((char *) s->bkmrkcol.valp + s->bind_type * row);
10808  } else {
10809  val = (SQLPOINTER)
10810  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10811  }
10812  if (s->bind_offs) {
10813  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10814  }
10815  *(sqlite_int64 *) val = sqlite3_last_insert_rowid(d->sqlite);
10816  if (s->bkmrkcol.lenp) {
10817  SQLLEN *ival;
10818 
10819  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10820  ival = (SQLLEN *)
10821  ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10822  } else {
10823  ival = &s->bkmrkcol.lenp[row];
10824  }
10825  if (s->bind_offs) {
10826  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10827  }
10828  *ival = sizeof (sqlite_int64);
10829  }
10830  }
10831  dbtraceapi(d, "sqlite3_reset", NULL);
10832  sqlite3_reset(s3stmt);
10833  }
10834  dbtraceapi(d, "sqlite3_finalize", NULL);
10835  sqlite3_finalize(s3stmt);
10836  return SQL_SUCCESS;
10837  } else if (op == SQL_DELETE_BY_BOOKMARK) {
10838  if (s->has_rowid < 0 ||
10839  s->bkmrk != SQL_UB_VARIABLE ||
10840  s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10841  !s->bkmrkcol.valp) {
10842  setstat(s, -1, "incompatible rowset",
10843  (*s->ov3) ? "HY000" : "S1000");
10844  return SQL_ERROR;
10845  }
10846  sql = dsappend(sql, "DELETE FROM ");
10847  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10848  sql = dsappendq(sql, s->dyncols[0].db);
10849  sql = dsappend(sql, ".");
10850  }
10851  sql = dsappendq(sql, s->dyncols[0].table);
10852  sql = dsappend(sql, " WHERE ");
10853  sql = dsappendq(sql, s->dyncols[0].column);
10854  sql = dsappend(sql, " = ?");
10855  if (dserr(sql)) {
10856  dsfree(sql);
10857  return nomem(s);
10858  }
10859 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10860  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10861 #else
10862  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10863 #endif
10864  do {
10865  s3stmt = NULL;
10866 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10867  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10868  &s3stmt, &endp);
10869 #else
10870  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10871  &s3stmt, &endp);
10872 #endif
10873  if (rc != SQLITE_OK) {
10874  if (s3stmt) {
10875  sqlite3_finalize(s3stmt);
10876  s3stmt = NULL;
10877  }
10878  }
10879  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10880  dbtracerc(d, rc, NULL);
10881  dsfree(sql);
10882  if (rc != SQLITE_OK) {
10883  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10884  sqlite3_errmsg(d->sqlite), rc);
10885  if (s3stmt) {
10886  dbtraceapi(d, "sqlite3_finalize", NULL);
10887  sqlite3_finalize(s3stmt);
10888  }
10889  return SQL_ERROR;
10890  }
10891  for (row = 0; row < s->rowset_size; row++) {
10892  SQLPOINTER *val;
10893  sqlite_int64 rowid;
10894 
10895  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10896  val = (SQLPOINTER)
10897  ((char *) s->bkmrkcol.valp + s->bind_type * row);
10898  } else {
10899  val = (SQLPOINTER)
10900  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10901  }
10902  if (s->bind_offs) {
10903  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10904  }
10905  if (s->bkmrkcol.lenp) {
10906  SQLLEN *ival;
10907 
10908  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10909  ival = (SQLLEN *)
10910  ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10911  } else {
10912  ival = &s->bkmrkcol.lenp[row];
10913  }
10914  if (s->bind_offs) {
10915  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10916  }
10917  if (*ival != sizeof (sqlite_int64)) {
10918  continue;
10919  }
10920  }
10921  rowid = *(sqlite_int64 *) val;
10922  sqlite3_bind_int64(s3stmt, 1, rowid);
10923  if (d->trace) {
10924  fprintf(d->trace,
10925 #ifdef _WIN32
10926  "-- parameter 1: %I64d\n",
10927 #else
10928  "-- parameter 1: %lld\n",
10929 #endif
10930  rowid);
10931  fflush(d->trace);
10932  }
10933  rc = sqlite3_step(s3stmt);
10934  if (rc != SQLITE_DONE) {
10935  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10936  sqlite3_errmsg(d->sqlite), rc);
10937  if (s->row_status0) {
10938  s->row_status0[row] = SQL_ROW_ERROR;
10939  }
10940  if (s->row_status) {
10941  s->row_status[row] = SQL_ROW_ERROR;
10942  }
10943  dbtraceapi(d, "sqlite3_finalize", NULL);
10944  sqlite3_finalize(s3stmt);
10945  return SQL_ERROR;
10946  }
10947  if (sqlite3_changes(d->sqlite) > 0) {
10948  if (s->row_status0) {
10949  s->row_status0[row] = SQL_ROW_DELETED;
10950  }
10951  if (s->row_status) {
10952  s->row_status[row] = SQL_ROW_DELETED;
10953  }
10954  }
10955  dbtraceapi(d, "sqlite3_reset", NULL);
10956  sqlite3_reset(s3stmt);
10957  }
10958  dbtraceapi(d, "sqlite3_finalize", NULL);
10959  sqlite3_finalize(s3stmt);
10960  return SQL_SUCCESS;
10961  } else if (op == SQL_UPDATE_BY_BOOKMARK) {
10962  if (s->has_rowid < 0 ||
10963  s->bkmrk != SQL_UB_VARIABLE ||
10964  s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10965  !s->bkmrkcol.valp) {
10966  setstat(s, -1, "incompatible rowset",
10967  (*s->ov3) ? "HY000" : "S1000");
10968  return SQL_ERROR;
10969  }
10970  ret = chkunbound(s);
10971  if (ret != SQL_SUCCESS) {
10972  return ret;
10973  }
10974  sql = dsappend(sql, "UPDATE ");
10975  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10976  sql = dsappendq(sql, s->dyncols[0].db);
10977  sql = dsappend(sql, ".");
10978  }
10979  sql = dsappendq(sql, s->dyncols[0].table);
10980  for (i = 0, k = 0; i < s->ncols; i++) {
10981  sql = dsappend(sql, (k > 0) ? ", " : " SET ");
10982  sql = dsappendq(sql, s->dyncols[i].column);
10983  sql = dsappend(sql, " = ?");
10984  k++;
10985  }
10986  sql = dsappend(sql, " WHERE ");
10987  sql = dsappendq(sql, s->dyncols[s->has_rowid].column);
10988  sql = dsappend(sql, " = ?");
10989  if (dserr(sql)) {
10990  dsfree(sql);
10991  return nomem(s);
10992  }
10993 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10994  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10995 #else
10996  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10997 #endif
10998  do {
10999  s3stmt = NULL;
11000 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
11001  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
11002  &s3stmt, &endp);
11003 #else
11004  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
11005  &s3stmt, &endp);
11006 #endif
11007  if (rc != SQLITE_OK) {
11008  if (s3stmt) {
11009  sqlite3_finalize(s3stmt);
11010  s3stmt = NULL;
11011  }
11012  }
11013  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
11014  dbtracerc(d, rc, NULL);
11015  dsfree(sql);
11016  if (rc != SQLITE_OK) {
11017  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
11018  sqlite3_errmsg(d->sqlite), rc);
11019  if (s3stmt) {
11020  dbtraceapi(d, "sqlite3_finalize", NULL);
11021  sqlite3_finalize(s3stmt);
11022  }
11023  return SQL_ERROR;
11024  }
11025  for (row = 0; row < s->rowset_size; row++) {
11026  SQLPOINTER *val;
11027  sqlite_int64 rowid;
11028 
11029  if (s->bind_type != SQL_BIND_BY_COLUMN) {
11030  val = (SQLPOINTER)
11031  ((char *) s->bkmrkcol.valp + s->bind_type * row);
11032  } else {
11033  val = (SQLPOINTER)
11034  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
11035  }
11036  if (s->bind_offs) {
11037  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
11038  }
11039  if (s->bkmrkcol.lenp) {
11040  SQLLEN *ival;
11041 
11042  if (s->bind_type != SQL_BIND_BY_COLUMN) {
11043  ival = (SQLLEN *)
11044  ((char *) s->bkmrkcol.lenp + s->bind_type * row);
11045  } else {
11046  ival = &s->bkmrkcol.lenp[row];
11047  }
11048  if (s->bind_offs) {
11049  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
11050  }
11051  if (*ival != sizeof (sqlite_int64)) {
11052  continue;
11053  }
11054  }
11055  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
11056  ret = setposbind(s, s3stmt, i, k, row);
11057  if (ret != SQL_SUCCESS) {
11058 ustmterr:
11059  if (s->row_status0) {
11060  s->row_status0[row] = SQL_ROW_ERROR;
11061  }
11062  if (s->row_status) {
11063  s->row_status[row] = SQL_ROW_ERROR;
11064  }
11065  dbtraceapi(d, "sqlite3_finalize", NULL);
11066  sqlite3_finalize(s3stmt);
11067  return ret;
11068  }
11069  k++;
11070  }
11071  rowid = *(sqlite_int64 *) val;
11072  sqlite3_bind_int64(s3stmt, k, rowid);
11073  if (d->trace) {
11074  fprintf(d->trace,
11075 #ifdef _WIN32
11076  "-- parameter %d: %I64d\n",
11077 #else
11078  "-- parameter %d: %lld\n",
11079 #endif
11080  k, rowid);
11081  fflush(d->trace);
11082  }
11083  rc = sqlite3_step(s3stmt);
11084  if (rc != SQLITE_DONE) {
11085  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
11086  sqlite3_errmsg(d->sqlite), rc);
11087  ret = SQL_ERROR;
11088  goto ustmterr;
11089  }
11090  if (sqlite3_changes(d->sqlite) > 0) {
11091  if (s->row_status0) {
11092  s->row_status0[row] = SQL_ROW_UPDATED;
11093  }
11094  if (s->row_status) {
11095  s->row_status[row] = SQL_ROW_UPDATED;
11096  }
11097  }
11098  dbtraceapi(d, "sqlite3_reset", NULL);
11099  sqlite3_reset(s3stmt);
11100  }
11101  dbtraceapi(d, "sqlite3_finalize", NULL);
11102  sqlite3_finalize(s3stmt);
11103  return SQL_SUCCESS;
11104  }
11105  setstat(s, -1, "unsupported operation", (*s->ov3) ? "HY000" : "S1000");
11106  return SQL_ERROR;
11107 }
11108 
11116 SQLRETURN SQL_API
11117 SQLBulkOperations(SQLHSTMT stmt, SQLSMALLINT oper)
11118 {
11119  SQLRETURN ret;
11120 
11121  HSTMT_LOCK(stmt);
11122  ret = drvbulkoperations(stmt, oper);
11123  HSTMT_UNLOCK(stmt);
11124  return ret;
11125 }
11126 
11127 
11132 SQLRETURN SQL_API
11133 SQLSetScrollOptions(SQLHSTMT stmt, SQLUSMALLINT concur, SQLLEN rowkeyset,
11134  SQLUSMALLINT rowset)
11135 {
11136  SQLRETURN ret;
11137 
11138  HSTMT_LOCK(stmt);
11139  ret = drvunimplstmt(stmt);
11140  HSTMT_UNLOCK(stmt);
11141  return ret;
11142 }
11143 
11144 #define strmak(dst, src, max, lenp) { \
11145  int len = strlen(src); \
11146  int cnt = min(len + 1, max); \
11147  strncpy(dst, src, cnt); \
11148  *lenp = (cnt > len) ? len : cnt; \
11149 }
11150 
11161 static SQLRETURN
11162 drvgetinfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11163  SQLSMALLINT *valLen)
11164 {
11165  DBC *d;
11166  char dummyc[301];
11167  SQLSMALLINT dummy;
11168 #if defined(_WIN32) || defined(_WIN64)
11169  char pathbuf[301], *drvname;
11170 #else
11171  static char drvname[] = "sqlite3odbc.so";
11172 #endif
11173 
11174  if (dbc == SQL_NULL_HDBC) {
11175  return SQL_INVALID_HANDLE;
11176  }
11177  d = (DBC *) dbc;
11178  if (valMax) {
11179  valMax--;
11180  }
11181  if (!valLen) {
11182  valLen = &dummy;
11183  }
11184  if (!val) {
11185  val = dummyc;
11186  valMax = sizeof (dummyc) - 1;
11187  }
11188  switch (type) {
11189  case SQL_MAX_USER_NAME_LEN:
11190  *((SQLSMALLINT *) val) = 16;
11191  *valLen = sizeof (SQLSMALLINT);
11192  break;
11193  case SQL_USER_NAME:
11194  strmak(val, "", valMax, valLen);
11195  break;
11196  case SQL_DRIVER_ODBC_VER:
11197 #if 0
11198  strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
11199 #else
11200  strmak(val, "03.00", valMax, valLen);
11201 #endif
11202  break;
11203  case SQL_ACTIVE_CONNECTIONS:
11204  case SQL_ACTIVE_STATEMENTS:
11205  *((SQLSMALLINT *) val) = 0;
11206  *valLen = sizeof (SQLSMALLINT);
11207  break;
11208 #ifdef SQL_ASYNC_MODE
11209  case SQL_ASYNC_MODE:
11210  *((SQLUINTEGER *) val) = SQL_AM_NONE;
11211  *valLen = sizeof (SQLUINTEGER);
11212  break;
11213 #endif
11214 #ifdef SQL_CREATE_TABLE
11215  case SQL_CREATE_TABLE:
11216  *((SQLUINTEGER *) val) = SQL_CT_CREATE_TABLE |
11217  SQL_CT_COLUMN_DEFAULT |
11218  SQL_CT_COLUMN_CONSTRAINT |
11219  SQL_CT_CONSTRAINT_NON_DEFERRABLE;
11220  *valLen = sizeof (SQLUINTEGER);
11221  break;
11222 #endif
11223 #ifdef SQL_CREATE_VIEW
11224  case SQL_CREATE_VIEW:
11225  *((SQLUINTEGER *) val) = SQL_CV_CREATE_VIEW;
11226  *valLen = sizeof (SQLUINTEGER);
11227  break;
11228 #endif
11229 #ifdef SQL_DDL_INDEX
11230  case SQL_DDL_INDEX:
11231  *((SQLUINTEGER *) val) = SQL_DI_CREATE_INDEX | SQL_DI_DROP_INDEX;
11232  *valLen = sizeof (SQLUINTEGER);
11233  break;
11234 #endif
11235 #ifdef SQL_DROP_TABLE
11236  case SQL_DROP_TABLE:
11237  *((SQLUINTEGER *) val) = SQL_DT_DROP_TABLE;
11238  *valLen = sizeof (SQLUINTEGER);
11239  break;
11240 #endif
11241 #ifdef SQL_DROP_VIEW
11242  case SQL_DROP_VIEW:
11243  *((SQLUINTEGER *) val) = SQL_DV_DROP_VIEW;
11244  *valLen = sizeof (SQLUINTEGER);
11245  break;
11246 #endif
11247 #ifdef SQL_INDEX_KEYWORDS
11248  case SQL_INDEX_KEYWORDS:
11249  *((SQLUINTEGER *) val) = SQL_IK_ALL;
11250  *valLen = sizeof (SQLUINTEGER);
11251  break;
11252 #endif
11253  case SQL_DATA_SOURCE_NAME:
11254  strmak(val, d->dsn ? d->dsn : "", valMax, valLen);
11255  break;
11256  case SQL_DRIVER_NAME:
11257 #if defined(_WIN32) || defined(_WIN64)
11258  GetModuleFileName(hModule, pathbuf, sizeof (pathbuf));
11259  drvname = strrchr(pathbuf, '\\');
11260  if (drvname == NULL) {
11261  drvname = strrchr(pathbuf, '/');
11262  }
11263  if (drvname == NULL) {
11264  drvname = pathbuf;
11265  } else {
11266  drvname++;
11267  }
11268 #endif
11269  strmak(val, drvname, valMax, valLen);
11270  break;
11271  case SQL_DRIVER_VER:
11272  strmak(val, DRIVER_VER_INFO, valMax, valLen);
11273  break;
11274  case SQL_FETCH_DIRECTION:
11275  *((SQLUINTEGER *) val) = SQL_FD_FETCH_NEXT | SQL_FD_FETCH_FIRST |
11276  SQL_FD_FETCH_LAST | SQL_FD_FETCH_PRIOR | SQL_FD_FETCH_ABSOLUTE;
11277  *valLen = sizeof (SQLUINTEGER);
11278  break;
11279  case SQL_ODBC_VER:
11280  strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
11281  break;
11282  case SQL_ODBC_SAG_CLI_CONFORMANCE:
11283  *((SQLSMALLINT *) val) = SQL_OSCC_NOT_COMPLIANT;
11284  *valLen = sizeof (SQLSMALLINT);
11285  break;
11286  case SQL_STANDARD_CLI_CONFORMANCE:
11287  *((SQLUINTEGER *) val) = SQL_SCC_XOPEN_CLI_VERSION1;
11288  *valLen = sizeof (SQLUINTEGER);
11289  break;
11290  case SQL_SQL_CONFORMANCE:
11291  *((SQLUINTEGER *) val) = SQL_SC_SQL92_ENTRY;
11292  *valLen = sizeof (SQLUINTEGER);
11293  break;
11294  case SQL_SERVER_NAME:
11295  case SQL_DATABASE_NAME:
11296  strmak(val, d->dbname ? d->dbname : "", valMax, valLen);
11297  break;
11298  case SQL_SEARCH_PATTERN_ESCAPE:
11299  strmak(val, "\\", valMax, valLen);
11300  break;
11301  case SQL_ODBC_SQL_CONFORMANCE:
11302  *((SQLSMALLINT *) val) = SQL_OSC_MINIMUM;
11303  *valLen = sizeof (SQLSMALLINT);
11304  break;
11305  case SQL_ODBC_API_CONFORMANCE:
11306  *((SQLSMALLINT *) val) = SQL_OAC_LEVEL1;
11307  *valLen = sizeof (SQLSMALLINT);
11308  break;
11309  case SQL_DBMS_NAME:
11310  strmak(val, "SQLite", valMax, valLen);
11311  break;
11312  case SQL_DBMS_VER:
11313  strmak(val, SQLITE_VERSION, valMax, valLen);
11314  break;
11315  case SQL_COLUMN_ALIAS:
11316  case SQL_NEED_LONG_DATA_LEN:
11317  case SQL_OUTER_JOINS:
11318  strmak(val, "Y", valMax, valLen);
11319  break;
11320  case SQL_ROW_UPDATES:
11321  case SQL_ACCESSIBLE_PROCEDURES:
11322  case SQL_PROCEDURES:
11323  case SQL_EXPRESSIONS_IN_ORDERBY:
11324  case SQL_ODBC_SQL_OPT_IEF:
11325  case SQL_LIKE_ESCAPE_CLAUSE:
11326  case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11327  case SQL_ACCESSIBLE_TABLES:
11328  case SQL_MULT_RESULT_SETS:
11329  case SQL_MULTIPLE_ACTIVE_TXN:
11330  case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11331  strmak(val, "N", valMax, valLen);
11332  break;
11333 #ifdef SQL_CATALOG_NAME
11334  case SQL_CATALOG_NAME:
11335 #if defined(_WIN32) || defined(_WIN64)
11336  strmak(val, d->xcelqrx ? "Y" : "N", valMax, valLen);
11337 #else
11338  strmak(val, "N", valMax, valLen);
11339 #endif
11340  break;
11341 #endif
11342  case SQL_DATA_SOURCE_READ_ONLY:
11343  strmak(val, "N", valMax, valLen);
11344  break;
11345 #ifdef SQL_OJ_CAPABILITIES
11346  case SQL_OJ_CAPABILITIES:
11347  *((SQLUINTEGER *) val) = SQL_OJ_LEFT;
11348  *valLen = sizeof (SQLUINTEGER);
11349  break;
11350 #endif
11351 #ifdef SQL_MAX_IDENTIFIER_LEN
11352  case SQL_MAX_IDENTIFIER_LEN:
11353  *((SQLUSMALLINT *) val) = 255;
11354  *valLen = sizeof (SQLUSMALLINT);
11355  break;
11356 #endif
11357  case SQL_CONCAT_NULL_BEHAVIOR:
11358  *((SQLSMALLINT *) val) = SQL_CB_NULL;
11359  *valLen = sizeof (SQLSMALLINT);
11360  break;
11361  case SQL_CURSOR_COMMIT_BEHAVIOR:
11362  case SQL_CURSOR_ROLLBACK_BEHAVIOR:
11363  *((SQLSMALLINT *) val) = SQL_CB_PRESERVE;
11364  *valLen = sizeof (SQLSMALLINT);
11365  break;
11366 #ifdef SQL_CURSOR_SENSITIVITY
11367  case SQL_CURSOR_SENSITIVITY:
11368  *((SQLUINTEGER *) val) = SQL_UNSPECIFIED;
11369  *valLen = sizeof (SQLUINTEGER);
11370  break;
11371 #endif
11372  case SQL_DEFAULT_TXN_ISOLATION:
11373  *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11374  *valLen = sizeof (SQLUINTEGER);
11375  break;
11376 #ifdef SQL_DESCRIBE_PARAMETER
11377  case SQL_DESCRIBE_PARAMETER:
11378  strmak(val, "Y", valMax, valLen);
11379  break;
11380 #endif
11381  case SQL_TXN_ISOLATION_OPTION:
11382  *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11383  *valLen = sizeof (SQLUINTEGER);
11384  break;
11385  case SQL_IDENTIFIER_CASE:
11386  *((SQLSMALLINT *) val) = SQL_IC_SENSITIVE;
11387  *valLen = sizeof (SQLSMALLINT);
11388  break;
11389  case SQL_IDENTIFIER_QUOTE_CHAR:
11390  strmak(val, "\"", valMax, valLen);
11391  break;
11392  case SQL_MAX_TABLE_NAME_LEN:
11393  case SQL_MAX_COLUMN_NAME_LEN:
11394  *((SQLSMALLINT *) val) = 255;
11395  *valLen = sizeof (SQLSMALLINT);
11396  break;
11397  case SQL_MAX_CURSOR_NAME_LEN:
11398  *((SQLSMALLINT *) val) = 255;
11399  *valLen = sizeof (SQLSMALLINT);
11400  break;
11401  case SQL_MAX_PROCEDURE_NAME_LEN:
11402  *((SQLSMALLINT *) val) = 0;
11403  break;
11404  case SQL_MAX_QUALIFIER_NAME_LEN:
11405  case SQL_MAX_OWNER_NAME_LEN:
11406  *((SQLSMALLINT *) val) = 255;
11407  break;
11408  case SQL_OWNER_TERM:
11409  strmak(val, "", valMax, valLen);
11410  break;
11411  case SQL_PROCEDURE_TERM:
11412  strmak(val, "PROCEDURE", valMax, valLen);
11413  break;
11414  case SQL_QUALIFIER_NAME_SEPARATOR:
11415  strmak(val, ".", valMax, valLen);
11416  break;
11417  case SQL_QUALIFIER_TERM:
11418 #if defined(_WIN32) || defined(_WIN64)
11419  strmak(val, d->xcelqrx ? "catalog" : "", valMax, valLen);
11420 #else
11421  strmak(val, "", valMax, valLen);
11422 #endif
11423  break;
11424  case SQL_QUALIFIER_USAGE:
11425 #if defined(_WIN32) || defined(_WIN64)
11426  *((SQLUINTEGER *) val) = d->xcelqrx ?
11427  (SQL_CU_DML_STATEMENTS | SQL_CU_INDEX_DEFINITION |
11428  SQL_CU_TABLE_DEFINITION) : 0;
11429 #else
11430  *((SQLUINTEGER *) val) = 0;
11431 #endif
11432  *valLen = sizeof (SQLUINTEGER);
11433  break;
11434  case SQL_SCROLL_CONCURRENCY:
11435  *((SQLUINTEGER *) val) = SQL_SCCO_LOCK;
11436  *valLen = sizeof (SQLUINTEGER);
11437  break;
11438  case SQL_SCROLL_OPTIONS:
11439  *((SQLUINTEGER *) val) = SQL_SO_STATIC | SQL_SO_FORWARD_ONLY;
11440  *valLen = sizeof (SQLUINTEGER);
11441  break;
11442  case SQL_TABLE_TERM:
11443  strmak(val, "TABLE", valMax, valLen);
11444  break;
11445  case SQL_TXN_CAPABLE:
11446  *((SQLSMALLINT *) val) = SQL_TC_ALL;
11447  *valLen = sizeof (SQLSMALLINT);
11448  break;
11449  case SQL_CONVERT_FUNCTIONS:
11450  *((SQLUINTEGER *) val) = 0;
11451  *valLen = sizeof (SQLUINTEGER);
11452  break;
11453  case SQL_SYSTEM_FUNCTIONS:
11454  case SQL_NUMERIC_FUNCTIONS:
11455  case SQL_STRING_FUNCTIONS:
11456  case SQL_TIMEDATE_FUNCTIONS:
11457  *((SQLUINTEGER *) val) = 0;
11458  *valLen = sizeof (SQLUINTEGER);
11459  break;
11460  case SQL_CONVERT_BIGINT:
11461  case SQL_CONVERT_BIT:
11462  case SQL_CONVERT_CHAR:
11463  case SQL_CONVERT_DATE:
11464  case SQL_CONVERT_DECIMAL:
11465  case SQL_CONVERT_DOUBLE:
11466  case SQL_CONVERT_FLOAT:
11467  case SQL_CONVERT_INTEGER:
11468  case SQL_CONVERT_LONGVARCHAR:
11469  case SQL_CONVERT_NUMERIC:
11470  case SQL_CONVERT_REAL:
11471  case SQL_CONVERT_SMALLINT:
11472  case SQL_CONVERT_TIME:
11473  case SQL_CONVERT_TIMESTAMP:
11474  case SQL_CONVERT_TINYINT:
11475  case SQL_CONVERT_VARCHAR:
11476  *((SQLUINTEGER *) val) =
11477  SQL_CVT_CHAR | SQL_CVT_NUMERIC | SQL_CVT_DECIMAL |
11478  SQL_CVT_INTEGER | SQL_CVT_SMALLINT | SQL_CVT_FLOAT | SQL_CVT_REAL |
11479  SQL_CVT_DOUBLE | SQL_CVT_VARCHAR | SQL_CVT_LONGVARCHAR |
11480  SQL_CVT_BIT | SQL_CVT_TINYINT | SQL_CVT_BIGINT |
11481  SQL_CVT_DATE | SQL_CVT_TIME | SQL_CVT_TIMESTAMP;
11482  *valLen = sizeof (SQLUINTEGER);
11483  break;
11484  case SQL_CONVERT_BINARY:
11485  case SQL_CONVERT_VARBINARY:
11486  case SQL_CONVERT_LONGVARBINARY:
11487  *((SQLUINTEGER *) val) = 0;
11488  *valLen = sizeof (SQLUINTEGER);
11489  break;
11490  case SQL_POSITIONED_STATEMENTS:
11491  *((SQLUINTEGER *) val) = 0;
11492  *valLen = sizeof (SQLUINTEGER);
11493  break;
11494  case SQL_LOCK_TYPES:
11495  *((SQLUINTEGER *) val) = SQL_LCK_NO_CHANGE;
11496  *valLen = sizeof (SQLUINTEGER);
11497  break;
11498  case SQL_BOOKMARK_PERSISTENCE:
11499  *((SQLUINTEGER *) val) = SQL_BP_SCROLL;
11500  *valLen = sizeof (SQLUINTEGER);
11501  break;
11502  case SQL_UNION:
11503  *((SQLUINTEGER *) val) = SQL_U_UNION | SQL_U_UNION_ALL;
11504  *valLen = sizeof (SQLUINTEGER);
11505  break;
11506  case SQL_OWNER_USAGE:
11507  case SQL_SUBQUERIES:
11508  case SQL_TIMEDATE_ADD_INTERVALS:
11509  case SQL_TIMEDATE_DIFF_INTERVALS:
11510  *((SQLUINTEGER *) val) = 0;
11511  *valLen = sizeof (SQLUINTEGER);
11512  break;
11513  case SQL_QUOTED_IDENTIFIER_CASE:
11514  *((SQLUSMALLINT *) val) = SQL_IC_SENSITIVE;
11515  *valLen = sizeof (SQLUSMALLINT);
11516  break;
11517  case SQL_POS_OPERATIONS:
11518  *((SQLUINTEGER *) val) = SQL_POS_POSITION | SQL_POS_UPDATE |
11519  SQL_POS_DELETE | SQL_POS_ADD | SQL_POS_REFRESH;
11520  *valLen = sizeof (SQLUINTEGER);
11521  break;
11522  case SQL_ALTER_TABLE:
11523  *((SQLUINTEGER *) val) = 0;
11524  *valLen = sizeof (SQLUINTEGER);
11525  break;
11526  case SQL_CORRELATION_NAME:
11527  *((SQLSMALLINT *) val) = SQL_CN_ANY;
11528  *valLen = sizeof (SQLSMALLINT);
11529  break;
11530  case SQL_NON_NULLABLE_COLUMNS:
11531  *((SQLSMALLINT *) val) = SQL_NNC_NON_NULL;
11532  *valLen = sizeof (SQLSMALLINT);
11533  break;
11534  case SQL_NULL_COLLATION:
11535  *((SQLSMALLINT *) val) = SQL_NC_START;
11536  *valLen = sizeof (SQLSMALLINT);
11537  break;
11538  case SQL_MAX_COLUMNS_IN_GROUP_BY:
11539  case SQL_MAX_COLUMNS_IN_ORDER_BY:
11540  case SQL_MAX_COLUMNS_IN_SELECT:
11541  case SQL_MAX_COLUMNS_IN_TABLE:
11542  case SQL_MAX_ROW_SIZE:
11543  case SQL_MAX_TABLES_IN_SELECT:
11544  *((SQLSMALLINT *) val) = 0;
11545  *valLen = sizeof (SQLSMALLINT);
11546  break;
11547  case SQL_MAX_BINARY_LITERAL_LEN:
11548  case SQL_MAX_CHAR_LITERAL_LEN:
11549  *((SQLUINTEGER *) val) = 0;
11550  *valLen = sizeof (SQLUINTEGER);
11551  break;
11552  case SQL_MAX_COLUMNS_IN_INDEX:
11553  *((SQLSMALLINT *) val) = 0;
11554  *valLen = sizeof (SQLSMALLINT);
11555  break;
11556  case SQL_MAX_INDEX_SIZE:
11557  *((SQLUINTEGER *) val) = 0;
11558  *valLen = sizeof (SQLUINTEGER);
11559  break;
11560 #ifdef SQL_MAX_IDENTIFIER_LENGTH
11561  case SQL_MAX_IDENTIFIER_LENGTH:
11562  *((SQLUINTEGER *) val) = 255;
11563  *valLen = sizeof (SQLUINTEGER);
11564  break;
11565 #endif
11566  case SQL_MAX_STATEMENT_LEN:
11567  *((SQLUINTEGER *) val) = 16384;
11568  *valLen = sizeof (SQLUINTEGER);
11569  break;
11570  case SQL_QUALIFIER_LOCATION:
11571  *((SQLSMALLINT *) val) = SQL_QL_START;
11572  *valLen = sizeof (SQLSMALLINT);
11573  break;
11574  case SQL_GETDATA_EXTENSIONS:
11575  *((SQLUINTEGER *) val) =
11576  SQL_GD_ANY_COLUMN | SQL_GD_ANY_ORDER | SQL_GD_BOUND;
11577  *valLen = sizeof (SQLUINTEGER);
11578  break;
11579  case SQL_STATIC_SENSITIVITY:
11580  *((SQLUINTEGER *) val) = 0;
11581  *valLen = sizeof (SQLUINTEGER);
11582  break;
11583  case SQL_FILE_USAGE:
11584 #if defined(_WIN32) || defined(_WIN64)
11585  *((SQLSMALLINT *) val) =
11586  d->xcelqrx ? SQL_FILE_CATALOG : SQL_FILE_NOT_SUPPORTED;
11587 #else
11588  *((SQLSMALLINT *) val) = SQL_FILE_NOT_SUPPORTED;
11589 #endif
11590  *valLen = sizeof (SQLSMALLINT);
11591  break;
11592  case SQL_GROUP_BY:
11593  *((SQLSMALLINT *) val) = SQL_GB_GROUP_BY_EQUALS_SELECT;
11594  *valLen = sizeof (SQLSMALLINT);
11595  break;
11596  case SQL_KEYWORDS:
11597  strmak(val, "CREATE,SELECT,DROP,DELETE,UPDATE,INSERT,"
11598  "INTO,VALUES,TABLE,INDEX,FROM,SET,WHERE,AND,CURRENT,OF",
11599  valMax, valLen);
11600  break;
11601  case SQL_SPECIAL_CHARACTERS:
11602 #ifdef SQL_COLLATION_SEQ
11603  case SQL_COLLATION_SEQ:
11604 #endif
11605  strmak(val, "", valMax, valLen);
11606  break;
11607  case SQL_BATCH_SUPPORT:
11608  case SQL_BATCH_ROW_COUNT:
11609  case SQL_PARAM_ARRAY_ROW_COUNTS:
11610  *((SQLUINTEGER *) val) = 0;
11611  *valLen = sizeof (SQLUINTEGER);
11612  break;
11613  case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1:
11614  *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_BOOKMARK;
11615  *valLen = sizeof (SQLUINTEGER);
11616  break;
11617  case SQL_STATIC_CURSOR_ATTRIBUTES1:
11618  *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE |
11619  SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK | SQL_CA1_POS_POSITION |
11620  SQL_CA1_POS_DELETE | SQL_CA1_POS_UPDATE | SQL_CA1_POS_REFRESH |
11621  SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_BULK_ADD |
11622  SQL_CA1_BULK_UPDATE_BY_BOOKMARK | SQL_CA1_BULK_DELETE_BY_BOOKMARK;
11623  *valLen = sizeof (SQLUINTEGER);
11624  break;
11625  case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2:
11626  case SQL_STATIC_CURSOR_ATTRIBUTES2:
11627  *((SQLUINTEGER *) val) = SQL_CA2_READ_ONLY_CONCURRENCY |
11628  SQL_CA2_LOCK_CONCURRENCY;
11629  *valLen = sizeof (SQLUINTEGER);
11630  break;
11631  case SQL_KEYSET_CURSOR_ATTRIBUTES1:
11632  case SQL_KEYSET_CURSOR_ATTRIBUTES2:
11633  case SQL_DYNAMIC_CURSOR_ATTRIBUTES1:
11634  case SQL_DYNAMIC_CURSOR_ATTRIBUTES2:
11635  *((SQLUINTEGER *) val) = 0;
11636  *valLen = sizeof (SQLUINTEGER);
11637  break;
11638  case SQL_ODBC_INTERFACE_CONFORMANCE:
11639  *((SQLUINTEGER *) val) = SQL_OIC_CORE;
11640  *valLen = sizeof (SQLUINTEGER);
11641  break;
11642  default:
11643  setstatd(d, -1, "unsupported info option %d",
11644  (*d->ov3) ? "HYC00" : "S1C00", type);
11645  return SQL_ERROR;
11646  }
11647  return SQL_SUCCESS;
11648 }
11649 
11650 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
11651 
11661 SQLRETURN SQL_API
11662 SQLGetInfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11663  SQLSMALLINT *valLen)
11664 {
11665  SQLRETURN ret;
11666 
11667  HDBC_LOCK(dbc);
11668  ret = drvgetinfo(dbc, type, val, valMax, valLen);
11669  HDBC_UNLOCK(dbc);
11670  return ret;
11671 }
11672 #endif
11673 
11674 #ifdef WINTERFACE
11675 
11685 SQLRETURN SQL_API
11686 SQLGetInfoW(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11687  SQLSMALLINT *valLen)
11688 {
11689  SQLRETURN ret;
11690  SQLSMALLINT len = 0;
11691 
11692  HDBC_LOCK(dbc);
11693  ret = drvgetinfo(dbc, type, val, valMax, &len);
11694  HDBC_UNLOCK(dbc);
11695  if (ret == SQL_SUCCESS) {
11696  SQLWCHAR *v = NULL;
11697 
11698  switch (type) {
11699  case SQL_USER_NAME:
11700  case SQL_DRIVER_ODBC_VER:
11701  case SQL_DATA_SOURCE_NAME:
11702  case SQL_DRIVER_NAME:
11703  case SQL_DRIVER_VER:
11704  case SQL_ODBC_VER:
11705  case SQL_SERVER_NAME:
11706  case SQL_DATABASE_NAME:
11707  case SQL_SEARCH_PATTERN_ESCAPE:
11708  case SQL_DBMS_NAME:
11709  case SQL_DBMS_VER:
11710  case SQL_NEED_LONG_DATA_LEN:
11711  case SQL_ROW_UPDATES:
11712  case SQL_ACCESSIBLE_PROCEDURES:
11713  case SQL_PROCEDURES:
11714  case SQL_EXPRESSIONS_IN_ORDERBY:
11715  case SQL_ODBC_SQL_OPT_IEF:
11716  case SQL_LIKE_ESCAPE_CLAUSE:
11717  case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11718  case SQL_OUTER_JOINS:
11719  case SQL_COLUMN_ALIAS:
11720  case SQL_ACCESSIBLE_TABLES:
11721  case SQL_MULT_RESULT_SETS:
11722  case SQL_MULTIPLE_ACTIVE_TXN:
11723  case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11724  case SQL_DATA_SOURCE_READ_ONLY:
11725 #ifdef SQL_DESCRIBE_PARAMETER
11726  case SQL_DESCRIBE_PARAMETER:
11727 #endif
11728  case SQL_IDENTIFIER_QUOTE_CHAR:
11729  case SQL_OWNER_TERM:
11730  case SQL_PROCEDURE_TERM:
11731  case SQL_QUALIFIER_NAME_SEPARATOR:
11732  case SQL_QUALIFIER_TERM:
11733  case SQL_TABLE_TERM:
11734  case SQL_KEYWORDS:
11735  case SQL_SPECIAL_CHARACTERS:
11736 #ifdef SQL_CATALOG_NAME
11737  case SQL_CATALOG_NAME:
11738 #endif
11739 #ifdef SQL_COLLATION_SEQ
11740  case SQL_COLLATION_SEQ:
11741 #endif
11742  if (val) {
11743  if (len > 0) {
11744  v = uc_from_utf((SQLCHAR *) val, len);
11745  if (v) {
11746  int vmax = valMax / sizeof (SQLWCHAR);
11747 
11748  uc_strncpy(val, v, vmax);
11749  if (len < vmax) {
11750  len = min(vmax, uc_strlen(v));
11751  v[len] = 0;
11752  } else {
11753  len = vmax;
11754  }
11755  uc_free(v);
11756  len *= sizeof (SQLWCHAR);
11757  } else {
11758  len = 0;
11759  }
11760  }
11761  if (len <= 0) {
11762  len = 0;
11763  if (valMax >= sizeof (SQLWCHAR)) {
11764  *((SQLWCHAR *)val) = 0;
11765  }
11766  }
11767  } else {
11768  len *= sizeof (SQLWCHAR);
11769  }
11770  break;
11771  }
11772  if (valLen) {
11773  *valLen = len;
11774  }
11775  }
11776  return ret;
11777 }
11778 #endif
11779 
11788 SQLRETURN SQL_API
11789 SQLGetFunctions(SQLHDBC dbc, SQLUSMALLINT func,
11790  SQLUSMALLINT *flags)
11791 {
11792  int i;
11793  SQLUSMALLINT exists[100];
11794 
11795  if (dbc == SQL_NULL_HDBC) {
11796  return SQL_INVALID_HANDLE;
11797  }
11798  for (i = 0; i < array_size(exists); i++) {
11799  exists[i] = SQL_FALSE;
11800  }
11801  exists[SQL_API_SQLALLOCCONNECT] = SQL_TRUE;
11802  exists[SQL_API_SQLFETCH] = SQL_TRUE;
11803  exists[SQL_API_SQLALLOCENV] = SQL_TRUE;
11804  exists[SQL_API_SQLFREECONNECT] = SQL_TRUE;
11805  exists[SQL_API_SQLALLOCSTMT] = SQL_TRUE;
11806  exists[SQL_API_SQLFREEENV] = SQL_TRUE;
11807  exists[SQL_API_SQLBINDCOL] = SQL_TRUE;
11808  exists[SQL_API_SQLFREESTMT] = SQL_TRUE;
11809  exists[SQL_API_SQLCANCEL] = SQL_TRUE;
11810  exists[SQL_API_SQLGETCURSORNAME] = SQL_TRUE;
11811  exists[SQL_API_SQLCOLATTRIBUTES] = SQL_TRUE;
11812  exists[SQL_API_SQLNUMRESULTCOLS] = SQL_TRUE;
11813  exists[SQL_API_SQLCONNECT] = SQL_TRUE;
11814  exists[SQL_API_SQLPREPARE] = SQL_TRUE;
11815  exists[SQL_API_SQLDESCRIBECOL] = SQL_TRUE;
11816  exists[SQL_API_SQLROWCOUNT] = SQL_TRUE;
11817  exists[SQL_API_SQLDISCONNECT] = SQL_TRUE;
11818  exists[SQL_API_SQLSETCURSORNAME] = SQL_FALSE;
11819  exists[SQL_API_SQLERROR] = SQL_TRUE;
11820  exists[SQL_API_SQLSETPARAM] = SQL_TRUE;
11821  exists[SQL_API_SQLEXECDIRECT] = SQL_TRUE;
11822  exists[SQL_API_SQLTRANSACT] = SQL_TRUE;
11823  exists[SQL_API_SQLBULKOPERATIONS] = SQL_TRUE;
11824  exists[SQL_API_SQLEXECUTE] = SQL_TRUE;
11825  exists[SQL_API_SQLBINDPARAMETER] = SQL_TRUE;
11826  exists[SQL_API_SQLGETTYPEINFO] = SQL_TRUE;
11827  exists[SQL_API_SQLCOLUMNS] = SQL_TRUE;
11828  exists[SQL_API_SQLPARAMDATA] = SQL_TRUE;
11829  exists[SQL_API_SQLDRIVERCONNECT] = SQL_TRUE;
11830  exists[SQL_API_SQLPUTDATA] = SQL_TRUE;
11831  exists[SQL_API_SQLGETCONNECTOPTION] = SQL_TRUE;
11832  exists[SQL_API_SQLSETCONNECTOPTION] = SQL_TRUE;
11833  exists[SQL_API_SQLGETDATA] = SQL_TRUE;
11834  exists[SQL_API_SQLSETSTMTOPTION] = SQL_TRUE;
11835  exists[SQL_API_SQLGETFUNCTIONS] = SQL_TRUE;
11836  exists[SQL_API_SQLSPECIALCOLUMNS] = SQL_TRUE;
11837  exists[SQL_API_SQLGETINFO] = SQL_TRUE;
11838  exists[SQL_API_SQLSTATISTICS] = SQL_TRUE;
11839  exists[SQL_API_SQLGETSTMTOPTION] = SQL_TRUE;
11840  exists[SQL_API_SQLTABLES] = SQL_TRUE;
11841  exists[SQL_API_SQLBROWSECONNECT] = SQL_FALSE;
11842  exists[SQL_API_SQLNUMPARAMS] = SQL_TRUE;
11843  exists[SQL_API_SQLCOLUMNPRIVILEGES] = SQL_FALSE;
11844  exists[SQL_API_SQLPARAMOPTIONS] = SQL_FALSE;
11845  exists[SQL_API_SQLDATASOURCES] = SQL_TRUE;
11846  exists[SQL_API_SQLPRIMARYKEYS] = SQL_TRUE;
11847  exists[SQL_API_SQLDESCRIBEPARAM] = SQL_TRUE;
11848  exists[SQL_API_SQLPROCEDURECOLUMNS] = SQL_TRUE;
11849  exists[SQL_API_SQLDRIVERS] = SQL_FALSE;
11850  exists[SQL_API_SQLPROCEDURES] = SQL_TRUE;
11851  exists[SQL_API_SQLEXTENDEDFETCH] = SQL_TRUE;
11852  exists[SQL_API_SQLSETPOS] = SQL_TRUE;
11853  exists[SQL_API_SQLFOREIGNKEYS] = SQL_TRUE;
11854  exists[SQL_API_SQLSETSCROLLOPTIONS] = SQL_TRUE;
11855  exists[SQL_API_SQLMORERESULTS] = SQL_TRUE;
11856  exists[SQL_API_SQLTABLEPRIVILEGES] = SQL_TRUE;
11857  exists[SQL_API_SQLNATIVESQL] = SQL_TRUE;
11858  if (func == SQL_API_ALL_FUNCTIONS) {
11859  memcpy(flags, exists, sizeof (exists));
11860  } else if (func == SQL_API_ODBC3_ALL_FUNCTIONS) {
11861  int i;
11862 #define SET_EXISTS(x) \
11863  flags[(x) >> 4] |= (1 << ((x) & 0xF))
11864 #define CLR_EXISTS(x) \
11865  flags[(x) >> 4] &= ~(1 << ((x) & 0xF))
11866 
11867  memset(flags, 0,
11868  sizeof (SQLUSMALLINT) * SQL_API_ODBC3_ALL_FUNCTIONS_SIZE);
11869  for (i = 0; i < array_size(exists); i++) {
11870  if (exists[i]) {
11871  flags[i >> 4] |= (1 << (i & 0xF));
11872  }
11873  }
11874  SET_EXISTS(SQL_API_SQLALLOCHANDLE);
11875  SET_EXISTS(SQL_API_SQLFREEHANDLE);
11876  SET_EXISTS(SQL_API_SQLGETSTMTATTR);
11877  SET_EXISTS(SQL_API_SQLSETSTMTATTR);
11878  SET_EXISTS(SQL_API_SQLGETCONNECTATTR);
11879  SET_EXISTS(SQL_API_SQLSETCONNECTATTR);
11880  SET_EXISTS(SQL_API_SQLGETENVATTR);
11881  SET_EXISTS(SQL_API_SQLSETENVATTR);
11882  SET_EXISTS(SQL_API_SQLCLOSECURSOR);
11883  SET_EXISTS(SQL_API_SQLBINDPARAM);
11884 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11885  /*
11886  * Some unixODBC versions have problems with
11887  * SQLError() vs. SQLGetDiagRec() with loss
11888  * of error/warning messages.
11889  */
11890  SET_EXISTS(SQL_API_SQLGETDIAGREC);
11891 #endif
11892  SET_EXISTS(SQL_API_SQLGETDIAGFIELD);
11893  SET_EXISTS(SQL_API_SQLFETCHSCROLL);
11894  SET_EXISTS(SQL_API_SQLENDTRAN);
11895  } else {
11896  if (func < array_size(exists)) {
11897  *flags = exists[func];
11898  } else {
11899  switch (func) {
11900  case SQL_API_SQLALLOCHANDLE:
11901  case SQL_API_SQLFREEHANDLE:
11902  case SQL_API_SQLGETSTMTATTR:
11903  case SQL_API_SQLSETSTMTATTR:
11904  case SQL_API_SQLGETCONNECTATTR:
11905  case SQL_API_SQLSETCONNECTATTR:
11906  case SQL_API_SQLGETENVATTR:
11907  case SQL_API_SQLSETENVATTR:
11908  case SQL_API_SQLCLOSECURSOR:
11909  case SQL_API_SQLBINDPARAM:
11910 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11911  /*
11912  * Some unixODBC versions have problems with
11913  * SQLError() vs. SQLGetDiagRec() with loss
11914  * of error/warning messages.
11915  */
11916  case SQL_API_SQLGETDIAGREC:
11917 #endif
11918  case SQL_API_SQLGETDIAGFIELD:
11919  case SQL_API_SQLFETCHSCROLL:
11920  case SQL_API_SQLENDTRAN:
11921  *flags = SQL_TRUE;
11922  break;
11923  default:
11924  *flags = SQL_FALSE;
11925  }
11926  }
11927  }
11928  return SQL_SUCCESS;
11929 }
11930 
11937 static SQLRETURN
11938 drvallocenv(SQLHENV *env)
11939 {
11940  ENV *e;
11941 
11942  if (env == NULL) {
11943  return SQL_INVALID_HANDLE;
11944  }
11945  e = (ENV *) xmalloc(sizeof (ENV));
11946  if (e == NULL) {
11947  *env = SQL_NULL_HENV;
11948  return SQL_ERROR;
11949  }
11950  e->magic = ENV_MAGIC;
11951  e->ov3 = 0;
11952  e->pool = 0;
11953 #if defined(_WIN32) || defined(_WIN64)
11954  InitializeCriticalSection(&e->cs);
11955 #else
11956 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
11957  nvfs_init();
11958 #endif
11959 #endif
11960  e->dbcs = NULL;
11961  *env = (SQLHENV) e;
11962  return SQL_SUCCESS;
11963 }
11964 
11971 SQLRETURN SQL_API
11972 SQLAllocEnv(SQLHENV *env)
11973 {
11974  return drvallocenv(env);
11975 }
11976 
11983 static SQLRETURN
11984 drvfreeenv(SQLHENV env)
11985 {
11986  ENV *e;
11987 
11988  if (env == SQL_NULL_HENV) {
11989  return SQL_INVALID_HANDLE;
11990  }
11991  e = (ENV *) env;
11992  if (e->magic != ENV_MAGIC) {
11993  return SQL_SUCCESS;
11994  }
11995 #if defined(_WIN32) || defined(_WIN64)
11996  EnterCriticalSection(&e->cs);
11997 #endif
11998  if (e->dbcs) {
11999 #if defined(_WIN32) || defined(_WIN64)
12000  LeaveCriticalSection(&e->cs);
12001 #endif
12002  return SQL_ERROR;
12003  }
12004  e->magic = DEAD_MAGIC;
12005 #if defined(_WIN32) || defined(_WIN64)
12006  LeaveCriticalSection(&e->cs);
12007  DeleteCriticalSection(&e->cs);
12008 #endif
12009  xfree(e);
12010  return SQL_SUCCESS;
12011 }
12012 
12019 SQLRETURN SQL_API
12020 SQLFreeEnv(SQLHENV env)
12021 {
12022  return drvfreeenv(env);
12023 }
12024 
12032 static SQLRETURN
12033 drvallocconnect(SQLHENV env, SQLHDBC *dbc)
12034 {
12035  DBC *d;
12036  ENV *e;
12037  const char *verstr;
12038  int maj = 0, min = 0, lev = 0;
12039 
12040  if (dbc == NULL) {
12041  return SQL_ERROR;
12042  }
12043  d = (DBC *) xmalloc(sizeof (DBC));
12044  if (d == NULL) {
12045  *dbc = SQL_NULL_HDBC;
12046  return SQL_ERROR;
12047  }
12048  memset(d, 0, sizeof (DBC));
12049  d->curtype = SQL_CURSOR_STATIC;
12050  d->ov3 = &d->ov3val;
12051  verstr = sqlite3_libversion();
12052  sscanf(verstr, "%d.%d.%d", &maj, &min, &lev);
12053  d->version = verinfo(maj & 0xFF, min & 0xFF, lev & 0xFF);
12054  e = (ENV *) env;
12055 #if defined(_WIN32) || defined(_WIN64)
12056  if (e->magic == ENV_MAGIC) {
12057  EnterCriticalSection(&e->cs);
12058  }
12059 #endif
12060  if (e->magic == ENV_MAGIC) {
12061  DBC *n, *p;
12062 
12063  d->env = e;
12064  d->ov3 = &e->ov3;
12065  p = NULL;
12066  n = e->dbcs;
12067  while (n) {
12068  p = n;
12069  n = n->next;
12070  }
12071  if (p) {
12072  p->next = d;
12073  } else {
12074  e->dbcs = d;
12075  }
12076  }
12077 #if defined(_WIN32) || defined(_WIN64)
12078  InitializeCriticalSection(&d->cs);
12079  d->owner = 0;
12080  if (e->magic == ENV_MAGIC) {
12081  LeaveCriticalSection(&e->cs);
12082  }
12083  d->oemcp = 1;
12084 #endif
12085  d->autocommit = 1;
12086  d->magic = DBC_MAGIC;
12087  *dbc = (SQLHDBC) d;
12088  drvgetgpps(d);
12089  return SQL_SUCCESS;
12090 }
12091 
12099 SQLRETURN SQL_API
12100 SQLAllocConnect(SQLHENV env, SQLHDBC *dbc)
12101 {
12102  return drvallocconnect(env, dbc);
12103 }
12104 
12111 static SQLRETURN
12113 {
12114  DBC *d;
12115  ENV *e;
12116  SQLRETURN ret = SQL_ERROR;
12117 
12118  if (dbc == SQL_NULL_HDBC) {
12119  return SQL_INVALID_HANDLE;
12120  }
12121  d = (DBC *) dbc;
12122  if (d->magic != DBC_MAGIC) {
12123  return SQL_INVALID_HANDLE;
12124  }
12125  e = d->env;
12126  if (e && e->magic == ENV_MAGIC) {
12127 #if defined(_WIN32) || defined(_WIN64)
12128  EnterCriticalSection(&e->cs);
12129 #endif
12130  } else {
12131  e = NULL;
12132  }
12133  HDBC_LOCK(dbc);
12134  if (d->sqlite) {
12135  setstatd(d, -1, "not disconnected", (*d->ov3) ? "HY000" : "S1000");
12136  HDBC_UNLOCK(dbc);
12137  goto done;
12138  }
12139  while (d->stmt) {
12140  freestmt((HSTMT) d->stmt);
12141  }
12142  if (e && e->magic == ENV_MAGIC) {
12143  DBC *n, *p;
12144 
12145  p = NULL;
12146  n = e->dbcs;
12147  while (n) {
12148  if (n == d) {
12149  break;
12150  }
12151  p = n;
12152  n = n->next;
12153  }
12154  if (n) {
12155  if (p) {
12156  p->next = d->next;
12157  } else {
12158  e->dbcs = d->next;
12159  }
12160  }
12161  }
12162  drvrelgpps(d);
12163  d->magic = DEAD_MAGIC;
12164  if (d->trace) {
12165  fclose(d->trace);
12166  }
12167 #if defined(_WIN32) || defined(_WIN64)
12168  d->owner = 0;
12169  LeaveCriticalSection(&d->cs);
12170  DeleteCriticalSection(&d->cs);
12171 #endif
12172  xfree(d);
12173  ret = SQL_SUCCESS;
12174 done:
12175 #if defined(_WIN32) || defined(_WIN64)
12176  if (e) {
12177  LeaveCriticalSection(&e->cs);
12178  }
12179 #endif
12180  return ret;
12181 }
12182 
12189 SQLRETURN SQL_API
12191 {
12192  return drvfreeconnect(dbc);
12193 }
12194 
12205 static SQLRETURN
12206 drvgetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12207  SQLINTEGER bufmax, SQLINTEGER *buflen)
12208 {
12209  DBC *d;
12210  SQLINTEGER dummy;
12211 
12212  if (dbc == SQL_NULL_HDBC) {
12213  return SQL_INVALID_HANDLE;
12214  }
12215  d = (DBC *) dbc;
12216  if (!val) {
12217  val = (SQLPOINTER) &dummy;
12218  }
12219  if (!buflen) {
12220  buflen = &dummy;
12221  }
12222  switch (attr) {
12223  case SQL_ATTR_CONNECTION_DEAD:
12224  *((SQLINTEGER *) val) = d->sqlite ? SQL_CD_FALSE : SQL_CD_TRUE;
12225  *buflen = sizeof (SQLINTEGER);
12226  break;
12227  case SQL_ATTR_ACCESS_MODE:
12228  *((SQLINTEGER *) val) = SQL_MODE_READ_WRITE;
12229  *buflen = sizeof (SQLINTEGER);
12230  break;
12231  case SQL_ATTR_AUTOCOMMIT:
12232  *((SQLINTEGER *) val) =
12233  d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
12234  *buflen = sizeof (SQLINTEGER);
12235  break;
12236  case SQL_ATTR_LOGIN_TIMEOUT:
12237  *((SQLINTEGER *) val) = 100;
12238  *buflen = sizeof (SQLINTEGER);
12239  break;
12240  case SQL_ATTR_ODBC_CURSORS:
12241  *((SQLINTEGER *) val) = SQL_CUR_USE_DRIVER;
12242  *buflen = sizeof (SQLINTEGER);
12243  break;
12244  case SQL_ATTR_PACKET_SIZE:
12245  *((SQLINTEGER *) val) = 16384;
12246  *buflen = sizeof (SQLINTEGER);
12247  break;
12248  case SQL_ATTR_TXN_ISOLATION:
12249  *((SQLINTEGER *) val) = SQL_TXN_SERIALIZABLE;
12250  *buflen = sizeof (SQLINTEGER);
12251  break;
12252  case SQL_ATTR_TRACEFILE:
12253  case SQL_ATTR_TRANSLATE_LIB:
12254  *((SQLCHAR *) val) = 0;
12255  *buflen = 0;
12256  break;
12257  case SQL_ATTR_CURRENT_CATALOG:
12258 #if defined(_WIN32) || defined(_WIN64)
12259  if (d->xcelqrx) {
12260  if ((bufmax > 4) && (val != (SQLPOINTER) &dummy)) {
12261  strcpy((char *) val, "main");
12262  *buflen = 4;
12263  break;
12264  }
12265  }
12266 #endif
12267  *((SQLCHAR *) val) = 0;
12268  *buflen = 0;
12269  break;
12270  case SQL_ATTR_TRACE:
12271  case SQL_ATTR_QUIET_MODE:
12272  case SQL_ATTR_TRANSLATE_OPTION:
12273  case SQL_ATTR_KEYSET_SIZE:
12274  case SQL_ATTR_QUERY_TIMEOUT:
12275  *((SQLINTEGER *) val) = 0;
12276  *buflen = sizeof (SQLINTEGER);
12277  break;
12278  case SQL_ATTR_PARAM_BIND_TYPE:
12279  *((SQLULEN *) val) = SQL_PARAM_BIND_BY_COLUMN;
12280  *buflen = sizeof (SQLUINTEGER);
12281  break;
12282  case SQL_ATTR_ROW_BIND_TYPE:
12283  *((SQLULEN *) val) = SQL_BIND_BY_COLUMN;
12284  *buflen = sizeof (SQLULEN);
12285  break;
12286  case SQL_ATTR_USE_BOOKMARKS:
12287  *((SQLINTEGER *) val) = SQL_UB_OFF;
12288  *buflen = sizeof (SQLINTEGER);
12289  break;
12290  case SQL_ATTR_ASYNC_ENABLE:
12291  *((SQLINTEGER *) val) = SQL_ASYNC_ENABLE_OFF;
12292  *buflen = sizeof (SQLINTEGER);
12293  break;
12294  case SQL_ATTR_NOSCAN:
12295  *((SQLINTEGER *) val) = SQL_NOSCAN_ON;
12296  *buflen = sizeof (SQLINTEGER);
12297  break;
12298  case SQL_ATTR_CONCURRENCY:
12299  *((SQLINTEGER *) val) = SQL_CONCUR_LOCK;
12300  *buflen = sizeof (SQLINTEGER);
12301  break;
12302 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
12303  case SQL_ATTR_CURSOR_SENSITIVITY:
12304  *((SQLINTEGER *) val) = SQL_UNSPECIFIED;
12305  *buflen = sizeof (SQLINTEGER);
12306  break;
12307 #endif
12308  case SQL_ATTR_SIMULATE_CURSOR:
12309  *((SQLINTEGER *) val) = SQL_SC_NON_UNIQUE;
12310  *buflen = sizeof (SQLINTEGER);
12311  break;
12312  case SQL_ATTR_MAX_ROWS:
12313  *((SQLINTEGER *) val) = 0;
12314  *buflen = sizeof (SQLINTEGER);
12315  case SQL_ATTR_MAX_LENGTH:
12316  *((SQLINTEGER *) val) = 1000000000;
12317  *buflen = sizeof (SQLINTEGER);
12318  break;
12319  case SQL_ATTR_CURSOR_TYPE:
12320  *((SQLINTEGER *) val) = d->curtype;
12321  *buflen = sizeof (SQLINTEGER);
12322  break;
12323  case SQL_ATTR_RETRIEVE_DATA:
12324  *((SQLINTEGER *) val) = SQL_RD_ON;
12325  *buflen = sizeof (SQLINTEGER);
12326  break;
12327 #ifdef SQL_ATTR_METADATA_ID
12328  case SQL_ATTR_METADATA_ID:
12329  *((SQLULEN *) val) = SQL_FALSE;
12330  return SQL_SUCCESS;
12331 #endif
12332  default:
12333  *((SQLINTEGER *) val) = 0;
12334  *buflen = sizeof (SQLINTEGER);
12335  setstatd(d, -1, "unsupported connect attribute %d",
12336  (*d->ov3) ? "HYC00" : "S1C00", (int) attr);
12337  return SQL_ERROR;
12338  }
12339  return SQL_SUCCESS;
12340 }
12341 
12342 #ifndef WINTERFACE
12343 
12353 SQLRETURN SQL_API
12354 SQLGetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12355  SQLINTEGER bufmax, SQLINTEGER *buflen)
12356 {
12357  SQLRETURN ret;
12358 
12359  HDBC_LOCK(dbc);
12360  ret = drvgetconnectattr(dbc, attr, val, bufmax, buflen);
12361  HDBC_UNLOCK(dbc);
12362  return ret;
12363 }
12364 #endif
12365 
12366 #ifdef WINTERFACE
12367 
12377 SQLRETURN SQL_API
12378 SQLGetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12379  SQLINTEGER bufmax, SQLINTEGER *buflen)
12380 {
12381  SQLRETURN ret;
12382  SQLINTEGER len = 0;
12383 
12384  HDBC_LOCK(dbc);
12385  ret = drvgetconnectattr(dbc, attr, val, bufmax, &len);
12386  if (ret == SQL_SUCCESS) {
12387  SQLWCHAR *v = NULL;
12388 
12389  switch (attr) {
12390  case SQL_ATTR_TRACEFILE:
12391  case SQL_ATTR_CURRENT_CATALOG:
12392  case SQL_ATTR_TRANSLATE_LIB:
12393  if (val) {
12394  if (len > 0) {
12395  v = uc_from_utf((SQLCHAR *) val, len);
12396  if (v) {
12397  int vmax = bufmax / sizeof (SQLWCHAR);
12398 
12399  uc_strncpy(val, v, vmax);
12400  if (len < vmax) {
12401  len = min(vmax, uc_strlen(v));
12402  v[len] = 0;
12403  } else {
12404  len = vmax;
12405  }
12406  uc_free(v);
12407  len *= sizeof (SQLWCHAR);
12408  } else {
12409  len = 0;
12410  }
12411  }
12412  if (len <= 0) {
12413  len = 0;
12414  if (bufmax >= sizeof (SQLWCHAR)) {
12415  *((SQLWCHAR *)val) = 0;
12416  }
12417  }
12418  } else {
12419  len *= sizeof (SQLWCHAR);
12420  }
12421  break;
12422  }
12423  if (buflen) {
12424  *buflen = len;
12425  }
12426  }
12427  HDBC_UNLOCK(dbc);
12428  return ret;
12429 }
12430 #endif
12431 
12441 static SQLRETURN
12442 drvsetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12443  SQLINTEGER len)
12444 {
12445  DBC *d;
12446 
12447  if (dbc == SQL_NULL_HDBC) {
12448  return SQL_INVALID_HANDLE;
12449  }
12450  d = (DBC *) dbc;
12451  switch (attr) {
12452  case SQL_AUTOCOMMIT:
12453  d->autocommit = val == (SQLPOINTER) SQL_AUTOCOMMIT_ON;
12454  if (d->autocommit && d->intrans) {
12455  return endtran(d, SQL_COMMIT, 1);
12456  } else if (!d->autocommit) {
12457  s3stmt_end(d->cur_s3stmt);
12458  }
12459  break;
12460 #ifdef SQL_ATTR_METADATA_ID
12461  case SQL_ATTR_METADATA_ID:
12462  if (val == (SQLPOINTER) SQL_FALSE) {
12463  break;
12464  }
12465  /* fall through */
12466 #endif
12467  default:
12468  setstatd(d, -1, "option value changed", "01S02");
12469  return SQL_SUCCESS_WITH_INFO;
12470  }
12471  return SQL_SUCCESS;
12472 }
12473 
12474 #ifndef WINTERFACE
12475 
12484 SQLRETURN SQL_API
12485 SQLSetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12486  SQLINTEGER len)
12487 {
12488  SQLRETURN ret;
12489 
12490  HDBC_LOCK(dbc);
12491  ret = drvsetconnectattr(dbc, attr, val, len);
12492  HDBC_UNLOCK(dbc);
12493  return ret;
12494 }
12495 #endif
12496 
12497 #ifdef WINTERFACE
12498 
12507 SQLRETURN SQL_API
12508 SQLSetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12509  SQLINTEGER len)
12510 {
12511  SQLRETURN ret;
12512 
12513  HDBC_LOCK(dbc);
12514  ret = drvsetconnectattr(dbc, attr, val, len);
12515  HDBC_UNLOCK(dbc);
12516  return ret;
12517 }
12518 #endif
12519 
12528 static SQLRETURN
12529 drvgetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12530 {
12531  DBC *d;
12532  SQLINTEGER dummy;
12533 
12534  if (dbc == SQL_NULL_HDBC) {
12535  return SQL_INVALID_HANDLE;
12536  }
12537  d = (DBC *) dbc;
12538  if (!param) {
12539  param = (SQLPOINTER) &dummy;
12540  }
12541  switch (opt) {
12542  case SQL_ACCESS_MODE:
12543  *((SQLINTEGER *) param) = SQL_MODE_READ_WRITE;
12544  break;
12545  case SQL_AUTOCOMMIT:
12546  *((SQLINTEGER *) param) =
12547  d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
12548  break;
12549  case SQL_LOGIN_TIMEOUT:
12550  *((SQLINTEGER *) param) = 100;
12551  break;
12552  case SQL_ODBC_CURSORS:
12553  *((SQLINTEGER *) param) = SQL_CUR_USE_DRIVER;
12554  break;
12555  case SQL_PACKET_SIZE:
12556  *((SQLINTEGER *) param) = 16384;
12557  break;
12558  case SQL_TXN_ISOLATION:
12559  *((SQLINTEGER *) param) = SQL_TXN_SERIALIZABLE;
12560  break;
12561  case SQL_OPT_TRACE:
12562  case SQL_OPT_TRACEFILE:
12563  case SQL_QUIET_MODE:
12564  case SQL_TRANSLATE_DLL:
12565  case SQL_TRANSLATE_OPTION:
12566  case SQL_KEYSET_SIZE:
12567  case SQL_QUERY_TIMEOUT:
12568  case SQL_BIND_TYPE:
12569  case SQL_CURRENT_QUALIFIER:
12570  *((SQLINTEGER *) param) = 0;
12571  break;
12572  case SQL_USE_BOOKMARKS:
12573  *((SQLINTEGER *) param) = SQL_UB_OFF;
12574  break;
12575  case SQL_ASYNC_ENABLE:
12576  *((SQLINTEGER *) param) = SQL_ASYNC_ENABLE_OFF;
12577  break;
12578  case SQL_NOSCAN:
12579  *((SQLINTEGER *) param) = SQL_NOSCAN_ON;
12580  break;
12581  case SQL_CONCURRENCY:
12582  *((SQLINTEGER *) param) = SQL_CONCUR_LOCK;
12583  break;
12584  case SQL_SIMULATE_CURSOR:
12585  *((SQLINTEGER *) param) = SQL_SC_NON_UNIQUE;
12586  break;
12587  case SQL_MAX_ROWS:
12588  *((SQLINTEGER *) param) = 0;
12589  break;
12590  case SQL_ROWSET_SIZE:
12591  case SQL_MAX_LENGTH:
12592  *((SQLINTEGER *) param) = 1000000000;
12593  break;
12594  case SQL_CURSOR_TYPE:
12595  *((SQLINTEGER *) param) = d->curtype;
12596  break;
12597  case SQL_RETRIEVE_DATA:
12598  *((SQLINTEGER *) param) = SQL_RD_ON;
12599  break;
12600  default:
12601  *((SQLINTEGER *) param) = 0;
12602  setstatd(d, -1, "unsupported connect option %d",
12603  (*d->ov3) ? "HYC00" : "S1C00", opt);
12604  return SQL_ERROR;
12605  }
12606  return SQL_SUCCESS;
12607 }
12608 
12609 #ifndef WINTERFACE
12610 
12618 SQLRETURN SQL_API
12619 SQLGetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12620 {
12621  SQLRETURN ret;
12622 
12623  HDBC_LOCK(dbc);
12624  ret = drvgetconnectoption(dbc, opt, param);
12625  HDBC_UNLOCK(dbc);
12626  return ret;
12627 }
12628 #endif
12629 
12630 #ifdef WINTERFACE
12631 
12639 SQLRETURN SQL_API
12640 SQLGetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12641 {
12642  SQLRETURN ret;
12643 
12644  HDBC_LOCK(dbc);
12645  ret = drvgetconnectoption(dbc, opt, param);
12646  if (SQL_SUCCEEDED(ret)) {
12647  switch (opt) {
12648  case SQL_OPT_TRACEFILE:
12649  case SQL_CURRENT_QUALIFIER:
12650  case SQL_TRANSLATE_DLL:
12651  if (param) {
12652  *(SQLWCHAR *) param = 0;
12653  }
12654  break;
12655  }
12656  }
12657  HDBC_UNLOCK(dbc);
12658  return ret;
12659 }
12660 #endif
12661 
12670 static SQLRETURN
12671 drvsetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
12672 {
12673  DBC *d;
12674 
12675  if (dbc == SQL_NULL_HDBC) {
12676  return SQL_INVALID_HANDLE;
12677  }
12678  d = (DBC *) dbc;
12679  switch (opt) {
12680  case SQL_AUTOCOMMIT:
12681  d->autocommit = param == SQL_AUTOCOMMIT_ON;
12682  if (d->autocommit && d->intrans) {
12683  return endtran(d, SQL_COMMIT, 1);
12684  } else if (!d->autocommit) {
12685  s3stmt_end(d->cur_s3stmt);
12686  }
12687  break;
12688  default:
12689  setstatd(d, -1, "option value changed", "01S02");
12690  return SQL_SUCCESS_WITH_INFO;
12691  }
12692  return SQL_SUCCESS;
12693 }
12694 
12695 #ifndef WINTERFACE
12696 
12704 SQLRETURN SQL_API
12705 SQLSetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12706 {
12707  SQLRETURN ret;
12708 
12709  HDBC_LOCK(dbc);
12710  ret = drvsetconnectoption(dbc, opt, param);
12711  HDBC_UNLOCK(dbc);
12712  return ret;
12713 }
12714 #endif
12715 
12716 #ifdef WINTERFACE
12717 
12725 SQLRETURN SQL_API
12726 SQLSetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12727 {
12728  SQLRETURN ret;
12729 
12730  HDBC_LOCK(dbc);
12731  ret = drvsetconnectoption(dbc, opt, param);
12732  HDBC_UNLOCK(dbc);
12733  return ret;
12734 }
12735 #endif
12736 
12737 #if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
12738 
12749 static int
12750 getdsnattr(char *dsn, char *attr, char *out, int outLen)
12751 {
12752  char *str = dsn, *start;
12753  int len = strlen(attr);
12754 
12755  while (*str) {
12756  while (*str && *str == ';') {
12757  ++str;
12758  }
12759  start = str;
12760  if ((str = strchr(str, '=')) == NULL) {
12761  return 0;
12762  }
12763  if (str - start == len && strncasecmp(start, attr, len) == 0) {
12764  start = ++str;
12765  while (*str && *str != ';') {
12766  ++str;
12767  }
12768  len = min(outLen - 1, str - start);
12769  strncpy(out, start, len);
12770  out[len] = '\0';
12771  return 1;
12772  }
12773  while (*str && *str != ';') {
12774  ++str;
12775  }
12776  }
12777  return 0;
12778 }
12779 #endif
12780 
12792 static SQLRETURN
12793 drvconnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen, char *pwd,
12794  int pwdLen, int isu)
12795 {
12796  DBC *d;
12797  int len;
12798  SQLRETURN ret;
12799  char buf[SQL_MAX_MESSAGE_LENGTH * 6], dbname[SQL_MAX_MESSAGE_LENGTH];
12800  char busy[SQL_MAX_MESSAGE_LENGTH / 4], tracef[SQL_MAX_MESSAGE_LENGTH];
12801  char loadext[SQL_MAX_MESSAGE_LENGTH], attas[SQL_MAX_MESSAGE_LENGTH];
12802  char sflag[32], spflag[32], ntflag[32], nwflag[32], biflag[32];
12803  char snflag[32], lnflag[32], ncflag[32], fkflag[32], jmode[32];
12804  char jdflag[32], ilflag[32];
12805 #if defined(_WIN32) || defined(_WIN64)
12806  char oemcp[32];
12807 #endif
12808 
12809  if (dbc == SQL_NULL_HDBC) {
12810  return SQL_INVALID_HANDLE;
12811  }
12812  d = (DBC *) dbc;
12813  if (d->magic != DBC_MAGIC) {
12814  return SQL_INVALID_HANDLE;
12815  }
12816  if (d->sqlite != NULL) {
12817  setstatd(d, -1, "connection already established", "08002");
12818  return SQL_ERROR;
12819  }
12820  buf[0] = '\0';
12821  if (dsnLen == SQL_NTS) {
12822  len = sizeof (buf) - 1;
12823  } else {
12824  len = min(sizeof (buf) - 1, dsnLen);
12825  }
12826  if (dsn != NULL) {
12827  strncpy(buf, (char *) dsn, len);
12828  }
12829  buf[len] = '\0';
12830  if (buf[0] == '\0') {
12831  setstatd(d, -1, "invalid DSN", (*d->ov3) ? "HY090" : "S1090");
12832  return SQL_ERROR;
12833  }
12834 #if defined(_WIN32) || defined(_WIN64)
12835  /*
12836  * When DSN is in UTF it must be converted to ANSI
12837  * here for ANSI SQLGetPrivateProfileString()
12838  */
12839  if (isu) {
12840  char *cdsn = utf_to_wmb(buf, len);
12841 
12842  if (!cdsn) {
12843  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12844  return SQL_ERROR;
12845  }
12846  strcpy(buf, cdsn);
12847  uc_free(cdsn);
12848  }
12849 #endif
12850  busy[0] = '\0';
12851  dbname[0] = '\0';
12852 #ifdef WITHOUT_DRIVERMGR
12853  getdsnattr(buf, "database", dbname, sizeof (dbname));
12854  if (dbname[0] == '\0') {
12855  strncpy(dbname, buf, sizeof (dbname));
12856  dbname[sizeof (dbname) - 1] = '\0';
12857  }
12858  getdsnattr(buf, "timeout", busy, sizeof (busy));
12859  sflag[0] = '\0';
12860  getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
12861  spflag[0] = '\0';
12862  getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
12863  ntflag[0] = '\0';
12864  getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
12865  nwflag[0] = '\0';
12866  getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
12867  snflag[0] = '\0';
12868  getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
12869  lnflag[0] = '\0';
12870  getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
12871  ncflag[0] = '\0';
12872  getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
12873  fkflag[0] = '\0';
12874  getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
12875  loadext[0] = '\0';
12876  getdsnattr(buf, "loadext", loadext, sizeof (loadext));
12877  jmode[0] = '\0';
12878  getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
12879  jdflag[0] = '\0';
12880  getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
12881 #if defined(_WIN32) || defined(_WIN64)
12882  oemcp[0] = '\0';
12883  getdsnattr(buf, "oemcp", oemcp, sizeof (oemcp));
12884 #endif
12885  biflag[0] = '\0';
12886  getdsnattr(buf, "bigint", biflag, sizeof (biflag));
12887  attas[0] = '\0';
12888  getdsnattr(buf, "attachas", attas, sizeof (attas));
12889  ilflag[0] = '\0';
12890  getdsnattr(buf, "ilike", ilflag, sizeof (ilflag));
12891 #else
12892  SQLGetPrivateProfileString(buf, "timeout", "100000",
12893  busy, sizeof (busy), ODBC_INI);
12894  SQLGetPrivateProfileString(buf, "database", "",
12895  dbname, sizeof (dbname), ODBC_INI);
12896 #if defined(_WIN32) || defined(_WIN64)
12897  /* database name read from registry is not UTF8 !!! */
12898  isu = 0;
12899 #endif
12900  SQLGetPrivateProfileString(buf, "stepapi", "",
12901  sflag, sizeof (sflag), ODBC_INI);
12902  SQLGetPrivateProfileString(buf, "syncpragma", "NORMAL",
12903  spflag, sizeof (spflag), ODBC_INI);
12904  SQLGetPrivateProfileString(buf, "notxn", "",
12905  ntflag, sizeof (ntflag), ODBC_INI);
12906  SQLGetPrivateProfileString(buf, "nowchar", "",
12907  nwflag, sizeof (nwflag), ODBC_INI);
12908  SQLGetPrivateProfileString(buf, "shortnames", "",
12909  snflag, sizeof (snflag), ODBC_INI);
12910  SQLGetPrivateProfileString(buf, "longnames", "",
12911  lnflag, sizeof (lnflag), ODBC_INI);
12912  SQLGetPrivateProfileString(buf, "nocreat", "",
12913  ncflag, sizeof (ncflag), ODBC_INI);
12914  SQLGetPrivateProfileString(buf, "fksupport", "",
12915  fkflag, sizeof (fkflag), ODBC_INI);
12916  SQLGetPrivateProfileString(buf, "loadext", "",
12917  loadext, sizeof (loadext), ODBC_INI);
12918  SQLGetPrivateProfileString(buf, "journalmode", "",
12919  jmode, sizeof (jmode), ODBC_INI);
12920  SQLGetPrivateProfileString(buf, "jdconv", "",
12921  jdflag, sizeof (jdflag), ODBC_INI);
12922 #if defined(_WIN32) || defined(_WIN64)
12923  SQLGetPrivateProfileString(buf, "oemcp", "1",
12924  oemcp, sizeof (oemcp), ODBC_INI);
12925 #endif
12926  SQLGetPrivateProfileString(buf, "bigint", "",
12927  biflag, sizeof (biflag), ODBC_INI);
12928  SQLGetPrivateProfileString(buf, "attachas", "",
12929  attas, sizeof (attas), ODBC_INI);
12930  SQLGetPrivateProfileString(buf, "ilike", "",
12931  ilflag, sizeof (ilflag), ODBC_INI);
12932 #endif
12933  tracef[0] = '\0';
12934 #ifdef WITHOUT_DRIVERMGR
12935  getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
12936 #else
12937  SQLGetPrivateProfileString(buf, "tracefile", "",
12938  tracef, sizeof (tracef), ODBC_INI);
12939 #endif
12940  if (tracef[0] != '\0') {
12941  d->trace = fopen(tracef, "a");
12942  }
12943  d->nowchar = getbool(nwflag);
12944  d->shortnames = getbool(snflag);
12945  d->longnames = getbool(lnflag);
12946  d->nocreat = getbool(ncflag);
12947  d->fksupport = getbool(fkflag);
12948  d->jdconv = getbool(jdflag);
12949  d->ilike = getbool(ilflag);
12950 #if defined(_WIN32) || defined(_WIN64)
12951  d->oemcp = getbool(oemcp);
12952 #else
12953  d->oemcp = 0;
12954 #endif
12955  d->dobigint = getbool(biflag);
12956  d->pwd = pwd;
12957  d->pwdLen = 0;
12958  if (d->pwd) {
12959  d->pwdLen = (pwdLen == SQL_NTS) ? strlen(d->pwd) : pwdLen;
12960  }
12961  ret = dbopen(d, dbname, isu, (char *) dsn, sflag, spflag, ntflag,
12962  jmode, busy);
12963  if (ret == SQL_SUCCESS) {
12964  dbloadext(d, loadext);
12965  dbattas(d, attas);
12966  }
12967  return ret;
12968 }
12969 
12970 #ifndef WINTERFACE
12971 
12983 SQLRETURN SQL_API
12984 SQLConnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen,
12985  SQLCHAR *uid, SQLSMALLINT uidLen,
12986  SQLCHAR *pwd, SQLSMALLINT pwdLen)
12987 {
12988  SQLRETURN ret;
12989 
12990  HDBC_LOCK(dbc);
12991  ret = drvconnect(dbc, dsn, dsnLen, (char *) pwd, pwdLen, 0);
12992  HDBC_UNLOCK(dbc);
12993  return ret;
12994 }
12995 #endif
12996 
12997 #ifdef WINTERFACE
12998 
13010 SQLRETURN SQL_API
13011 SQLConnectW(SQLHDBC dbc, SQLWCHAR *dsn, SQLSMALLINT dsnLen,
13012  SQLWCHAR *uid, SQLSMALLINT uidLen,
13013  SQLWCHAR *pwd, SQLSMALLINT pwdLen)
13014 {
13015  char *dsna = NULL;
13016  char *pwda = NULL;
13017  SQLRETURN ret;
13018 
13019  HDBC_LOCK(dbc);
13020  if (dsn) {
13021  dsna = uc_to_utf_c(dsn, dsnLen);
13022  if (!dsna) {
13023  DBC *d = (DBC *) dbc;
13024 
13025  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
13026  ret = SQL_ERROR;
13027  goto done;
13028  }
13029  }
13030  if (pwd) {
13031  pwda = uc_to_utf_c(pwd, pwdLen);
13032  if (!pwda) {
13033  DBC *d = (DBC *) dbc;
13034 
13035  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
13036  ret = SQL_ERROR;
13037  goto done;
13038  }
13039  }
13040  ret = drvconnect(dbc, (SQLCHAR *) dsna, SQL_NTS, pwda, SQL_NTS, 1);
13041 done:
13042  HDBC_UNLOCK(dbc);
13043  uc_free(dsna);
13044  uc_free(pwda);
13045  return ret;
13046 }
13047 #endif
13048 
13055 static SQLRETURN
13057 {
13058  DBC *d;
13059  int rc;
13060 
13061  if (dbc == SQL_NULL_HDBC) {
13062  return SQL_INVALID_HANDLE;
13063  }
13064  d = (DBC *) dbc;
13065  if (d->magic != DBC_MAGIC) {
13066  return SQL_INVALID_HANDLE;
13067  }
13068  if (d->intrans) {
13069  setstatd(d, -1, "incomplete transaction", "25000");
13070  return SQL_ERROR;
13071  }
13072  if (d->cur_s3stmt) {
13073  s3stmt_end(d->cur_s3stmt);
13074  }
13075  if (d->sqlite) {
13076  if (d->trace) {
13077  fprintf(d->trace, "-- sqlite3_close: '%s'\n",
13078  d->dbname);
13079  fflush(d->trace);
13080  }
13081  rc = sqlite3_close(d->sqlite);
13082  if (rc == SQLITE_BUSY) {
13083  setstatd(d, -1, "unfinished statements", "25000");
13084  return SQL_ERROR;
13085  }
13086  d->sqlite = NULL;
13087  }
13088  freep(&d->dbname);
13089  freep(&d->dsn);
13090  return SQL_SUCCESS;
13091 }
13092 
13099 SQLRETURN SQL_API
13101 {
13102  SQLRETURN ret;
13103 
13104  HDBC_LOCK(dbc);
13105  ret = drvdisconnect(dbc);
13106  HDBC_UNLOCK(dbc);
13107  return ret;
13108 }
13109 
13110 #if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
13111 
13125 static SQLRETURN
13126 drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
13127  SQLCHAR *connIn, SQLSMALLINT connInLen,
13128  SQLCHAR *connOut, SQLSMALLINT connOutMax,
13129  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
13130 {
13131  DBC *d;
13132  int len;
13133  SQLRETURN ret;
13134  char buf[SQL_MAX_MESSAGE_LENGTH * 8], dbname[SQL_MAX_MESSAGE_LENGTH];
13135  char dsn[SQL_MAX_MESSAGE_LENGTH], busy[SQL_MAX_MESSAGE_LENGTH / 4];
13136  char tracef[SQL_MAX_MESSAGE_LENGTH], loadext[SQL_MAX_MESSAGE_LENGTH];
13137  char pwd[SQL_MAX_MESSAGE_LENGTH], attas[SQL_MAX_MESSAGE_LENGTH];
13138  char sflag[32], spflag[32], ntflag[32], snflag[32], lnflag[32];
13139  char ncflag[32], nwflag[32], fkflag[32], jmode[32], biflag[32];
13140  char jdflag[32], ilflag[32];
13141 
13142  if (dbc == SQL_NULL_HDBC) {
13143  return SQL_INVALID_HANDLE;
13144  }
13145  if (drvcompl != SQL_DRIVER_COMPLETE &&
13146  drvcompl != SQL_DRIVER_COMPLETE_REQUIRED &&
13147  drvcompl != SQL_DRIVER_PROMPT &&
13148  drvcompl != SQL_DRIVER_NOPROMPT) {
13149  return SQL_NO_DATA;
13150  }
13151  d = (DBC *) dbc;
13152  if (d->sqlite) {
13153  setstatd(d, -1, "connection already established", "08002");
13154  return SQL_ERROR;
13155  }
13156  buf[0] = '\0';
13157  if (connInLen == SQL_NTS) {
13158  len = sizeof (buf) - 1;
13159  } else {
13160  len = min(connInLen, sizeof (buf) - 1);
13161  }
13162  if (connIn != NULL) {
13163  strncpy(buf, (char *) connIn, len);
13164  }
13165  buf[len] = '\0';
13166  if (!buf[0]) {
13167  setstatd(d, -1, "invalid connect attributes",
13168  (*d->ov3) ? "HY090" : "S1090");
13169  return SQL_ERROR;
13170  }
13171  dsn[0] = '\0';
13172  getdsnattr(buf, "DSN", dsn, sizeof (dsn));
13173 
13174  /* special case: connIn is sole DSN value without keywords */
13175  if (!dsn[0] && !strchr(buf, ';') && !strchr(buf, '=')) {
13176  strncpy(dsn, buf, sizeof (dsn) - 1);
13177  dsn[sizeof (dsn) - 1] = '\0';
13178  }
13179 
13180  busy[0] = '\0';
13181  getdsnattr(buf, "timeout", busy, sizeof (busy));
13182 #ifndef WITHOUT_DRIVERMGR
13183  if (dsn[0] && !busy[0]) {
13184  SQLGetPrivateProfileString(dsn, "timeout", "100000",
13185  busy, sizeof (busy), ODBC_INI);
13186  }
13187 #endif
13188  dbname[0] = '\0';
13189  getdsnattr(buf, "database", dbname, sizeof (dbname));
13190 #ifndef WITHOUT_DRIVERMGR
13191  if (dsn[0] && !dbname[0]) {
13192  SQLGetPrivateProfileString(dsn, "database", "",
13193  dbname, sizeof (dbname), ODBC_INI);
13194  }
13195 #endif
13196  sflag[0] = '\0';
13197  getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
13198 #ifndef WITHOUT_DRIVERMGR
13199  if (dsn[0] && !sflag[0]) {
13200  SQLGetPrivateProfileString(dsn, "stepapi", "",
13201  sflag, sizeof (sflag), ODBC_INI);
13202  }
13203 #endif
13204  spflag[0] = '\0';
13205  getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
13206 #ifndef WITHOUT_DRIVERMGR
13207  if (dsn[0] && !spflag[0]) {
13208  SQLGetPrivateProfileString(dsn, "syncpragma", "NORMAL",
13209  spflag, sizeof (spflag), ODBC_INI);
13210  }
13211 #endif
13212  ntflag[0] = '\0';
13213  getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
13214 #ifndef WITHOUT_DRIVERMGR
13215  if (dsn[0] && !ntflag[0]) {
13216  SQLGetPrivateProfileString(dsn, "notxn", "",
13217  ntflag, sizeof (ntflag), ODBC_INI);
13218  }
13219 #endif
13220  snflag[0] = '\0';
13221  getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
13222 #ifndef WITHOUT_DRIVERMGR
13223  if (dsn[0] && !snflag[0]) {
13224  SQLGetPrivateProfileString(dsn, "shortnames", "",
13225  snflag, sizeof (snflag), ODBC_INI);
13226  }
13227 #endif
13228  lnflag[0] = '\0';
13229  getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
13230 #ifndef WITHOUT_DRIVERMGR
13231  if (dsn[0] && !lnflag[0]) {
13232  SQLGetPrivateProfileString(dsn, "longnames", "",
13233  lnflag, sizeof (lnflag), ODBC_INI);
13234  }
13235 #endif
13236  ncflag[0] = '\0';
13237  getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
13238 #ifndef WITHOUT_DRIVERMGR
13239  if (dsn[0] && !ncflag[0]) {
13240  SQLGetPrivateProfileString(dsn, "nocreat", "",
13241  ncflag, sizeof (ncflag), ODBC_INI);
13242  }
13243 #endif
13244  nwflag[0] = '\0';
13245  getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
13246 #ifndef WITHOUT_DRIVERMGR
13247  if (dsn[0] && !nwflag[0]) {
13248  SQLGetPrivateProfileString(dsn, "nowchar", "",
13249  nwflag, sizeof (nwflag), ODBC_INI);
13250  }
13251 #endif
13252  fkflag[0] = '\0';
13253  getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
13254 #ifndef WITHOUT_DRIVERMGR
13255  if (dsn[0] && !fkflag[0]) {
13256  SQLGetPrivateProfileString(dsn, "fksupport", "",
13257  fkflag, sizeof (fkflag), ODBC_INI);
13258  }
13259 #endif
13260  loadext[0] = '\0';
13261  getdsnattr(buf, "loadext", loadext, sizeof (loadext));
13262 #ifndef WITHOUT_DRIVERMGR
13263  if (dsn[0] && !loadext[0]) {
13264  SQLGetPrivateProfileString(dsn, "loadext", "",
13265  loadext, sizeof (loadext), ODBC_INI);
13266  }
13267 #endif
13268  jmode[0] = '\0';
13269  getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
13270 #ifndef WITHOUT_DRIVERMGR
13271  if (dsn[0] && !jmode[0]) {
13272  SQLGetPrivateProfileString(dsn, "journalmode", "",
13273  jmode, sizeof (jmode), ODBC_INI);
13274  }
13275 #endif
13276  biflag[0] = '\0';
13277  getdsnattr(buf, "bigint", biflag, sizeof (biflag));
13278 #ifndef WITHOUT_DRIVERMGR
13279  if (dsn[0] && !biflag[0]) {
13280  SQLGetPrivateProfileString(dsn, "bigint", "",
13281  biflag, sizeof (biflag), ODBC_INI);
13282  }
13283 #endif
13284  jdflag[0] = '\0';
13285  getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
13286 #ifndef WITHOUT_DRIVERMGR
13287  if (dsn[0] && !jdflag[0]) {
13288  SQLGetPrivateProfileString(dsn, "jdconv", "",
13289  jdflag, sizeof (jdflag), ODBC_INI);
13290  }
13291 #endif
13292  pwd[0] = '\0';
13293  getdsnattr(buf, "pwd", pwd, sizeof (pwd));
13294 #ifndef WITHOUT_DRIVERMGR
13295  if (dsn[0] && !pwd[0]) {
13296  SQLGetPrivateProfileString(dsn, "pwd", "",
13297  pwd, sizeof (pwd), ODBC_INI);
13298  }
13299 #endif
13300  attas[0] = '\0';
13301  getdsnattr(buf, "attachas", attas, sizeof (attas));
13302 #ifndef WITHOUT_DRIVERMGR
13303  if (dsn[0] && !attas[0]) {
13304  SQLGetPrivateProfileString(dsn, "attachas", "",
13305  attas, sizeof (attas), ODBC_INI);
13306  }
13307 #endif
13308  ilflag[0] = '\0';
13309  getdsnattr(buf, "ilike", ilflag, sizeof (ilflag));
13310 #ifndef WITHOUT_DRIVERMGR
13311  if (dsn[0] && !ilflag[0]) {
13312  SQLGetPrivateProfileString(dsn, "ilike", "",
13313  ilflag, sizeof (ilflag), ODBC_INI);
13314  }
13315 #endif
13316 
13317  if (!dbname[0] && !dsn[0]) {
13318  strcpy(dsn, "SQLite");
13319  strncpy(dbname, buf, sizeof (dbname));
13320  dbname[sizeof (dbname) - 1] = '\0';
13321  }
13322  tracef[0] = '\0';
13323  getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
13324 #ifndef WITHOUT_DRIVERMGR
13325  if (dsn[0] && !tracef[0]) {
13326  SQLGetPrivateProfileString(dsn, "tracefile", "",
13327  tracef, sizeof (tracef), ODBC_INI);
13328  }
13329 #endif
13330  if (connOut || connOutLen) {
13331  int count;
13332 
13333  buf[0] = '\0';
13334  count = snprintf(buf, sizeof (buf),
13335  "DSN=%s;Database=%s;StepAPI=%s;Timeout=%s;"
13336  "SyncPragma=%s;NoTXN=%s;ShortNames=%s;LongNames=%s;"
13337  "NoCreat=%s;NoWCHAR=%s;FKSupport=%s;Tracefile=%s;"
13338  "JournalMode=%s;LoadExt=%s;BigInt=%s;JDConv=%s;"
13339  "PWD=%s;AttachAs=%s;ILike=%s",
13340  dsn, dbname, sflag, busy, spflag, ntflag,
13341  snflag, lnflag, ncflag, nwflag, fkflag, tracef,
13342  jmode, loadext, biflag, jdflag, pwd, attas, ilflag);
13343  if (count < 0) {
13344  buf[sizeof (buf) - 1] = '\0';
13345  }
13346  len = min(connOutMax - 1, strlen(buf));
13347  if (connOut) {
13348  strncpy((char *) connOut, buf, len);
13349  connOut[len] = '\0';
13350  }
13351  if (connOutLen) {
13352  *connOutLen = len;
13353  }
13354  }
13355  if (tracef[0] != '\0') {
13356  d->trace = fopen(tracef, "a");
13357  }
13358  d->shortnames = getbool(snflag);
13359  d->longnames = getbool(lnflag);
13360  d->nocreat = getbool(ncflag);
13361  d->nowchar = getbool(nwflag);
13362  d->fksupport = getbool(fkflag);
13363  d->dobigint = getbool(biflag);
13364  d->jdconv = getbool(jdflag);
13365  d->ilike = getbool(ilflag);
13366  d->oemcp = 0;
13367  d->pwdLen = strlen(pwd);
13368  d->pwd = (d->pwdLen > 0) ? pwd : NULL;
13369  ret = dbopen(d, dbname, 0, dsn, sflag, spflag, ntflag, jmode, busy);
13370  memset(pwd, 0, sizeof (pwd));
13371  if (ret == SQL_SUCCESS) {
13372  dbloadext(d, loadext);
13373  dbattas(d, attas);
13374  }
13375  return ret;
13376 }
13377 #endif
13378 
13385 static SQLRETURN
13386 freestmt(SQLHSTMT stmt)
13387 {
13388  STMT *s;
13389  DBC *d;
13390 
13391  if (stmt == SQL_NULL_HSTMT) {
13392  return SQL_INVALID_HANDLE;
13393  }
13394  s = (STMT *) stmt;
13395  s3stmt_drop(s);
13396  freeresult(s, 1);
13397  freep(&s->query);
13398  d = (DBC *) s->dbc;
13399  if (d && d->magic == DBC_MAGIC) {
13400  STMT *p, *n;
13401 
13402  p = NULL;
13403  n = d->stmt;
13404  while (n) {
13405  if (n == s) {
13406  break;
13407  }
13408  p = n;
13409  n = n->next;
13410  }
13411  if (n) {
13412  if (p) {
13413  p->next = s->next;
13414  } else {
13415  d->stmt = s->next;
13416  }
13417  }
13418  }
13419  freeparams(s);
13420  freep(&s->bindparms);
13421  if (s->row_status0 != &s->row_status1) {
13422  freep(&s->row_status0);
13423  s->rowset_size = 1;
13424  s->row_status0 = &s->row_status1;
13425  }
13426  xfree(s);
13427  return SQL_SUCCESS;
13428 }
13429 
13437 static SQLRETURN
13438 drvallocstmt(SQLHDBC dbc, SQLHSTMT *stmt)
13439 {
13440  DBC *d;
13441  STMT *s, *sl, *pl;
13442 
13443  if (dbc == SQL_NULL_HDBC) {
13444  return SQL_INVALID_HANDLE;
13445  }
13446  d = (DBC *) dbc;
13447  if (d->magic != DBC_MAGIC || stmt == NULL) {
13448  return SQL_INVALID_HANDLE;
13449  }
13450  s = (STMT *) xmalloc(sizeof (STMT));
13451  if (s == NULL) {
13452  *stmt = SQL_NULL_HSTMT;
13453  return SQL_ERROR;
13454  }
13455  *stmt = (SQLHSTMT) s;
13456  memset(s, 0, sizeof (STMT));
13457  s->dbc = dbc;
13458  s->ov3 = d->ov3;
13459  s->bkmrk = SQL_UB_OFF;
13460  s->bkmrkptr = 0;
13461  s->oemcp = &d->oemcp;
13462  s->jdconv = &d->jdconv;
13463  s->ilike = &d->ilike;
13464  s->nowchar[0] = d->nowchar;
13465  s->nowchar[1] = 0;
13466  s->dobigint = d->dobigint;
13467  s->curtype = d->curtype;
13468  s->row_status0 = &s->row_status1;
13469  s->rowset_size = 1;
13470  s->longnames = d->longnames;
13471  s->retr_data = SQL_RD_ON;
13472  s->max_rows = 0;
13473  s->bind_type = SQL_BIND_BY_COLUMN;
13474  s->bind_offs = NULL;
13475  s->paramset_size = 1;
13476  s->parm_bind_type = SQL_PARAM_BIND_BY_COLUMN;
13477  s->one_tbl = -1;
13478  s->has_pk = -1;
13479  s->has_rowid = -1;
13480 #ifdef _WIN64
13481  sprintf((char *) s->cursorname, "CUR_%I64X", (SQLUBIGINT) *stmt);
13482 #else
13483  sprintf((char *) s->cursorname, "CUR_%016lX", (long) *stmt);
13484 #endif
13485  sl = d->stmt;
13486  pl = NULL;
13487  while (sl) {
13488  pl = sl;
13489  sl = sl->next;
13490  }
13491  if (pl) {
13492  pl->next = s;
13493  } else {
13494  d->stmt = s;
13495  }
13496  return SQL_SUCCESS;
13497 }
13498 
13506 SQLRETURN SQL_API
13507 SQLAllocStmt(SQLHDBC dbc, SQLHSTMT *stmt)
13508 {
13509  SQLRETURN ret;
13510 
13511  HDBC_LOCK(dbc);
13512  ret = drvallocstmt(dbc, stmt);
13513  HDBC_UNLOCK(dbc);
13514  return ret;
13515 }
13516 
13524 static SQLRETURN
13525 drvfreestmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13526 {
13527  STMT *s;
13528  SQLRETURN ret = SQL_SUCCESS;
13529  SQLHDBC dbc;
13530 
13531  if (stmt == SQL_NULL_HSTMT) {
13532  return SQL_INVALID_HANDLE;
13533  }
13534  HSTMT_LOCK(stmt);
13535  s = (STMT *) stmt;
13536  dbc = s->dbc;
13537  switch (opt) {
13538  case SQL_RESET_PARAMS:
13539  freeparams(s);
13540  break;
13541  case SQL_UNBIND:
13542  unbindcols(s);
13543  break;
13544  case SQL_CLOSE:
13545  s3stmt_end_if(s);
13546  freeresult(s, 0);
13547  break;
13548  case SQL_DROP:
13549  s3stmt_end_if(s);
13550  ret = freestmt(stmt);
13551  break;
13552  default:
13553  setstat(s, -1, "unsupported option", (*s->ov3) ? "HYC00" : "S1C00");
13554  ret = SQL_ERROR;
13555  break;
13556  }
13557  HDBC_UNLOCK(dbc);
13558  return ret;
13559 }
13560 
13568 SQLRETURN SQL_API
13569 SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13570 {
13571  return drvfreestmt(stmt, opt);
13572 }
13573 
13580 SQLRETURN SQL_API
13581 SQLCancel(SQLHSTMT stmt)
13582 {
13583  if (stmt != SQL_NULL_HSTMT) {
13584  DBC *d = (DBC *) ((STMT *) stmt)->dbc;
13585 #if defined(_WIN32) || defined(_WIN64)
13586  /* interrupt when other thread owns critical section */
13587  if (d->magic == DBC_MAGIC && d->owner != GetCurrentThreadId() &&
13588  d->owner != 0) {
13589  d->busyint = 1;
13590  sqlite3_interrupt(d->sqlite);
13591  return SQL_SUCCESS;
13592  }
13593 #else
13594  if (d->magic == DBC_MAGIC) {
13595  d->busyint = 1;
13596  sqlite3_interrupt(d->sqlite);
13597  }
13598 #endif
13599  }
13600  return drvfreestmt(stmt, SQL_CLOSE);
13601 }
13602 
13612 static SQLRETURN
13613 drvgetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13614  SQLSMALLINT *lenp)
13615 {
13616  STMT *s;
13617 
13618  if (stmt == SQL_NULL_HSTMT) {
13619  return SQL_INVALID_HANDLE;
13620  }
13621  s = (STMT *) stmt;
13622  if (lenp && !cursor) {
13623  *lenp = strlen((char *) s->cursorname);
13624  return SQL_SUCCESS;
13625  }
13626  if (cursor) {
13627  if (buflen > 0) {
13628  strncpy((char *) cursor, (char *) s->cursorname, buflen - 1);
13629  cursor[buflen - 1] = '\0';
13630  }
13631  if (lenp) {
13632  *lenp = min(strlen((char *) s->cursorname), buflen - 1);
13633  }
13634  }
13635  return SQL_SUCCESS;
13636 }
13637 
13638 #ifndef WINTERFACE
13639 
13648 SQLRETURN SQL_API
13649 SQLGetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13650  SQLSMALLINT *lenp)
13651 {
13652  SQLRETURN ret;
13653 #if defined(_WIN32) || defined(_WIN64)
13654  SQLSMALLINT len = 0;
13655 #endif
13656 
13657  HSTMT_LOCK(stmt);
13658 #if defined(_WIN32) || defined(_WIN64)
13659  if (!((STMT *) stmt)->oemcp[0]) {
13660  ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13661  goto done;
13662  }
13663  ret = drvgetcursorname(stmt, cursor, buflen, &len);
13664  if (ret == SQL_SUCCESS) {
13665  char *c = NULL;
13666 
13667  if (cursor) {
13668  c = utf_to_wmb((char *) cursor, len);
13669  if (!c) {
13670  ret = nomem((STMT *) stmt);
13671  goto done;
13672  }
13673  c[len] = 0;
13674  len = strlen(c);
13675  if (buflen > 0) {
13676  strncpy((char *) cursor, c, buflen - 1);
13677  cursor[buflen - 1] = 0;
13678  }
13679  uc_free(c);
13680  }
13681  if (lenp) {
13682  *lenp = min(len, buflen - 1);
13683  }
13684  }
13685 done:
13686  ;
13687 #else
13688  ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13689 #endif
13690  HSTMT_UNLOCK(stmt);
13691  return ret;
13692 }
13693 #endif
13694 
13695 #ifdef WINTERFACE
13696 
13705 SQLRETURN SQL_API
13706 SQLGetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT buflen,
13707  SQLSMALLINT *lenp)
13708 {
13709  SQLRETURN ret;
13710  SQLSMALLINT len = 0;
13711 
13712  HSTMT_LOCK(stmt);
13713  ret = drvgetcursorname(stmt, (SQLCHAR *) cursor, buflen, &len);
13714  if (ret == SQL_SUCCESS) {
13715  SQLWCHAR *c = NULL;
13716 
13717  if (cursor) {
13718  c = uc_from_utf((SQLCHAR *) cursor, len);
13719  if (!c) {
13720  ret = nomem((STMT *) stmt);
13721  goto done;
13722  }
13723  c[len] = 0;
13724  len = uc_strlen(c);
13725  if (buflen > 0) {
13726  uc_strncpy(cursor, c, buflen - 1);
13727  cursor[buflen - 1] = 0;
13728  }
13729  uc_free(c);
13730  }
13731  if (lenp) {
13732  *lenp = min(len, buflen - 1);
13733  }
13734  }
13735 done:
13736  HSTMT_UNLOCK(stmt);
13737  return ret;
13738 }
13739 #endif
13740 
13749 static SQLRETURN
13750 drvsetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13751 {
13752  STMT *s;
13753 
13754  if (stmt == SQL_NULL_HSTMT) {
13755  return SQL_INVALID_HANDLE;
13756  }
13757  s = (STMT *) stmt;
13758  if (!cursor ||
13759  !((cursor[0] >= 'A' && cursor[0] <= 'Z') ||
13760  (cursor[0] >= 'a' && cursor[0] <= 'z'))) {
13761  setstat(s, -1, "invalid cursor name", (*s->ov3) ? "HYC00" : "S1C00");
13762  return SQL_ERROR;
13763  }
13764  if (len == SQL_NTS) {
13765  len = sizeof (s->cursorname) - 1;
13766  } else {
13767  len = min(sizeof (s->cursorname) - 1, len);
13768  }
13769  strncpy((char *) s->cursorname, (char *) cursor, len);
13770  s->cursorname[len] = '\0';
13771  return SQL_SUCCESS;
13772 }
13773 
13774 #ifndef WINTERFACE
13775 
13783 SQLRETURN SQL_API
13784 SQLSetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13785 {
13786 #if defined(_WIN32) || defined(_WIN64)
13787  char *c = NULL;
13788 #endif
13789  SQLRETURN ret;
13790 
13791  HSTMT_LOCK(stmt);
13792 #if defined(_WIN32) || defined(_WIN64)
13793  if (!((STMT *) stmt)->oemcp[0]) {
13794  ret = drvsetcursorname(stmt, cursor, len);
13795  goto done2;
13796  }
13797  if (cursor) {
13798  c = wmb_to_utf_c((char *) cursor, len);
13799  if (!c) {
13800  ret = nomem((STMT *) stmt);
13801  goto done;
13802  }
13803  }
13804  ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13805 #else
13806  ret = drvsetcursorname(stmt, cursor, len);
13807 #endif
13808 #if defined(_WIN32) || defined(_WIN64)
13809 done:
13810  uc_free(c);
13811 done2:
13812  ;
13813 #endif
13814  HSTMT_UNLOCK(stmt);
13815  return ret;
13816 }
13817 #endif
13818 
13819 #ifdef WINTERFACE
13820 
13828 SQLRETURN SQL_API
13829 SQLSetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT len)
13830 {
13831  char *c = NULL;
13832  SQLRETURN ret;
13833 
13834  HSTMT_LOCK(stmt);
13835  if (cursor) {
13836  c = uc_to_utf_c(cursor, len);
13837  if (!c) {
13838  ret = nomem((STMT *) stmt);
13839  goto done;
13840  }
13841  }
13842  ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13843 done:
13844  uc_free(c);
13845  HSTMT_UNLOCK(stmt);
13846  return ret;
13847 }
13848 #endif
13849 
13856 SQLRETURN SQL_API
13858 {
13859  return drvfreestmt(stmt, SQL_CLOSE);
13860 }
13861 
13870 SQLRETURN SQL_API
13871 SQLAllocHandle(SQLSMALLINT type, SQLHANDLE input, SQLHANDLE *output)
13872 {
13873  SQLRETURN ret;
13874 
13875  switch (type) {
13876  case SQL_HANDLE_ENV:
13877  ret = drvallocenv((SQLHENV *) output);
13878  if (ret == SQL_SUCCESS) {
13879  ENV *e = (ENV *) *output;
13880 
13881  if (e && e->magic == ENV_MAGIC) {
13882  e->ov3 = 1;
13883  }
13884  }
13885  return ret;
13886  case SQL_HANDLE_DBC:
13887  return drvallocconnect((SQLHENV) input, (SQLHDBC *) output);
13888  case SQL_HANDLE_STMT:
13889  HDBC_LOCK((SQLHDBC) input);
13890  ret = drvallocstmt((SQLHDBC) input, (SQLHSTMT *) output);
13891  HDBC_UNLOCK((SQLHDBC) input);
13892  return ret;
13893  }
13894  return SQL_ERROR;
13895 }
13896 
13904 SQLRETURN SQL_API
13905 SQLFreeHandle(SQLSMALLINT type, SQLHANDLE h)
13906 {
13907  switch (type) {
13908  case SQL_HANDLE_ENV:
13909  return drvfreeenv((SQLHENV) h);
13910  case SQL_HANDLE_DBC:
13911  return drvfreeconnect((SQLHDBC) h);
13912  case SQL_HANDLE_STMT:
13913  return drvfreestmt((SQLHSTMT) h, SQL_DROP);
13914  }
13915  return SQL_ERROR;
13916 }
13917 
13923 static void
13925 {
13926  if (s->dyncols) {
13927  int i;
13928 
13929  for (i = 0; i < s->dcols; i++) {
13930  freep(&s->dyncols[i].typename);
13931  }
13932  if (s->cols == s->dyncols) {
13933  s->cols = NULL;
13934  s->ncols = 0;
13935  }
13936  freep(&s->dyncols);
13937  }
13938  s->dcols = 0;
13939 }
13940 
13952 static void
13953 freeresult(STMT *s, int clrcols)
13954 {
13955  freep(&s->bincache);
13956  s->bincell = NULL;
13957  s->binlen = 0;
13958  if (s->rows) {
13959  if (s->rowfree) {
13960  s->rowfree(s->rows);
13961  s->rowfree = NULL;
13962  }
13963  s->rows = NULL;
13964  }
13965  s->nrows = -1;
13966  if (clrcols > 0) {
13967  freep(&s->bindcols);
13968  s->nbindcols = 0;
13969  }
13970  if (clrcols) {
13971  freedyncols(s);
13972  s->cols = NULL;
13973  s->ncols = 0;
13974  s->nowchar[1] = 0;
13975  s->one_tbl = -1;
13976  s->has_pk = -1;
13977  s->has_rowid = -1;
13978  }
13979 }
13980 
13986 static void
13988 {
13989  int i;
13990 
13991  for (i = 0; s->bindcols && i < s->nbindcols; i++) {
13992  s->bindcols[i].type = SQL_UNKNOWN_TYPE;
13993  s->bindcols[i].max = 0;
13994  s->bindcols[i].lenp = NULL;
13995  s->bindcols[i].valp = NULL;
13996  s->bindcols[i].index = i;
13997  s->bindcols[i].offs = 0;
13998  }
13999 }
14000 
14008 static SQLRETURN
14009 mkbindcols(STMT *s, int ncols)
14010 {
14011  if (s->bindcols) {
14012  if (s->nbindcols < ncols) {
14013  int i;
14014  BINDCOL *bindcols =
14015  xrealloc(s->bindcols, ncols * sizeof (BINDCOL));
14016 
14017  if (!bindcols) {
14018  return nomem(s);
14019  }
14020  for (i = s->nbindcols; i < ncols; i++) {
14021  bindcols[i].type = SQL_UNKNOWN_TYPE;
14022  bindcols[i].max = 0;
14023  bindcols[i].lenp = NULL;
14024  bindcols[i].valp = NULL;
14025  bindcols[i].index = i;
14026  bindcols[i].offs = 0;
14027  }
14028  s->bindcols = bindcols;
14029  s->nbindcols = ncols;
14030  }
14031  } else if (ncols > 0) {
14032  s->bindcols = (BINDCOL *) xmalloc(ncols * sizeof (BINDCOL));
14033  if (!s->bindcols) {
14034  return nomem(s);
14035  }
14036  s->nbindcols = ncols;
14037  unbindcols(s);
14038  }
14039  return SQL_SUCCESS;
14040 }
14041 
14055 static SQLRETURN
14056 getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype,
14057  SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp, int partial)
14058 {
14059  char **data, valdummy[16];
14060  SQLLEN dummy;
14061  SQLINTEGER *ilenp = NULL;
14062  int valnull = 0;
14063  int type = otype;
14064  SQLRETURN sret = SQL_NO_DATA;
14065 
14066  if (!lenp) {
14067  lenp = &dummy;
14068  }
14069  /* workaround for JDK 1.7.0 on x86_64 */
14070  if (((SQLINTEGER *) lenp) + 1 == (SQLINTEGER *) val) {
14071  ilenp = (SQLINTEGER *) lenp;
14072  lenp = &dummy;
14073  }
14074  if (col >= s->ncols) {
14075  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
14076  return SQL_ERROR;
14077  }
14078  if (s->retr_data != SQL_RD_ON) {
14079  return SQL_SUCCESS;
14080  }
14081  if (!s->rows) {
14082  *lenp = SQL_NULL_DATA;
14083  goto done;
14084  }
14085  if (s->rowp < 0 || s->rowp >= s->nrows) {
14086  *lenp = SQL_NULL_DATA;
14087  goto done;
14088  }
14089  type = mapdeftype(type, s->cols[col].type, s->cols[col].nosign ? 1 : 0,
14090  s->nowchar[0]);
14091 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
14092  /* MS Access hack part 3 (map SQL_C_DEFAULT to SQL_C_CHAR) */
14093  if (type == SQL_C_WCHAR && otype == SQL_C_DEFAULT) {
14094  type = SQL_C_CHAR;
14095  }
14096 #endif
14097  data = s->rows + s->ncols + (s->rowp * s->ncols) + col;
14098  if (!val) {
14099  valnull = 1;
14100  val = (SQLPOINTER) valdummy;
14101  }
14102  if (*data == NULL) {
14103  *lenp = SQL_NULL_DATA;
14104  switch (type) {
14105  case SQL_C_UTINYINT:
14106  case SQL_C_TINYINT:
14107  case SQL_C_STINYINT:
14108 #ifdef SQL_BIT
14109  case SQL_C_BIT:
14110 #endif
14111  *((SQLCHAR *) val) = 0;
14112  break;
14113  case SQL_C_USHORT:
14114  case SQL_C_SHORT:
14115  case SQL_C_SSHORT:
14116  *((SQLSMALLINT *) val) = 0;
14117  break;
14118  case SQL_C_ULONG:
14119  case SQL_C_LONG:
14120  case SQL_C_SLONG:
14121  *((SQLINTEGER *) val) = 0;
14122  break;
14123 #ifdef SQL_BIGINT
14124  case SQL_C_SBIGINT:
14125  case SQL_C_UBIGINT:
14126  *((SQLBIGINT *) val) = 0;
14127  break;
14128 #endif
14129  case SQL_C_FLOAT:
14130  *((float *) val) = 0;
14131  break;
14132  case SQL_C_DOUBLE:
14133  *((double *) val) = 0;
14134  break;
14135  case SQL_C_BINARY:
14136  case SQL_C_CHAR:
14137  if (len > 0) {
14138  *((SQLCHAR *) val) = '\0';
14139  }
14140  break;
14141 #ifdef WCHARSUPPORT
14142  case SQL_C_WCHAR:
14143  if (len > 0) {
14144  *((SQLWCHAR *) val) = '\0';
14145  }
14146  break;
14147 #endif
14148 #ifdef SQL_C_TYPE_DATE
14149  case SQL_C_TYPE_DATE:
14150 #endif
14151  case SQL_C_DATE:
14152  memset((DATE_STRUCT *) val, 0, sizeof (DATE_STRUCT));
14153  break;
14154 #ifdef SQL_C_TYPE_TIME
14155  case SQL_C_TYPE_TIME:
14156 #endif
14157  case SQL_C_TIME:
14158  memset((TIME_STRUCT *) val, 0, sizeof (TIME_STRUCT));
14159  break;
14160 #ifdef SQL_C_TYPE_TIMESTAMP
14161  case SQL_C_TYPE_TIMESTAMP:
14162 #endif
14163  case SQL_C_TIMESTAMP:
14164  memset((TIMESTAMP_STRUCT *) val, 0, sizeof (TIMESTAMP_STRUCT));
14165  break;
14166  default:
14167  return SQL_ERROR;
14168  }
14169  } else {
14170  char *endp = NULL;
14171 #if defined(_WIN32) || defined(_WIN64)
14172 #ifdef SQL_BIGINT
14173  char endc;
14174 #endif
14175 #endif
14176 
14177  switch (type) {
14178  case SQL_C_UTINYINT:
14179  case SQL_C_TINYINT:
14180  case SQL_C_STINYINT:
14181  *((SQLCHAR *) val) = strtol(*data, &endp, 0);
14182  if (endp && endp == *data) {
14183  *lenp = SQL_NULL_DATA;
14184  } else {
14185  *lenp = sizeof (SQLCHAR);
14186  }
14187  break;
14188 #ifdef SQL_BIT
14189  case SQL_C_BIT:
14190  *((SQLCHAR *) val) = getbool(*data);
14191  *lenp = sizeof (SQLCHAR);
14192  break;
14193 #endif
14194  case SQL_C_USHORT:
14195  case SQL_C_SHORT:
14196  case SQL_C_SSHORT:
14197  *((SQLSMALLINT *) val) = strtol(*data, &endp, 0);
14198  if (endp && endp == *data) {
14199  *lenp = SQL_NULL_DATA;
14200  } else {
14201  *lenp = sizeof (SQLSMALLINT);
14202  }
14203  break;
14204  case SQL_C_ULONG:
14205  case SQL_C_LONG:
14206  case SQL_C_SLONG:
14207  *((SQLINTEGER *) val) = strtol(*data, &endp, 0);
14208  if (endp && endp == *data) {
14209  *lenp = SQL_NULL_DATA;
14210  } else {
14211  *lenp = sizeof (SQLINTEGER);
14212  }
14213  break;
14214 #ifdef SQL_BIGINT
14215  case SQL_C_UBIGINT:
14216 #if defined(_WIN32) || defined(_WIN64)
14217  if (sscanf(*data, "%I64u%c", (SQLUBIGINT *) val, &endc) != 1) {
14218  *lenp = SQL_NULL_DATA;
14219  } else {
14220  *lenp = sizeof (SQLUBIGINT);
14221  }
14222 #else
14223 #ifdef __osf__
14224  *((SQLUBIGINT *) val) = strtoul(*data, &endp, 0);
14225 #else
14226  *((SQLUBIGINT *) val) = strtoull(*data, &endp, 0);
14227 #endif
14228  if (endp && endp == *data) {
14229  *lenp = SQL_NULL_DATA;
14230  } else {
14231  *lenp = sizeof (SQLUBIGINT);
14232  }
14233 #endif
14234  break;
14235  case SQL_C_SBIGINT:
14236 #if defined(_WIN32) || defined(_WIN64)
14237  if (sscanf(*data, "%I64d%c", (SQLBIGINT *) val, &endc) != 1) {
14238  *lenp = SQL_NULL_DATA;
14239  } else {
14240  *lenp = sizeof (SQLBIGINT);
14241  }
14242 #else
14243 #ifdef __osf__
14244  *((SQLBIGINT *) val) = strtol(*data, &endp, 0);
14245 #else
14246  *((SQLBIGINT *) val) = strtoll(*data, &endp, 0);
14247 #endif
14248  if (endp && endp == *data) {
14249  *lenp = SQL_NULL_DATA;
14250  } else {
14251  *lenp = sizeof (SQLBIGINT);
14252  }
14253 #endif
14254  break;
14255 #endif
14256  case SQL_C_FLOAT:
14257  *((float *) val) = ln_strtod(*data, &endp);
14258  if (endp && endp == *data) {
14259  *lenp = SQL_NULL_DATA;
14260  } else {
14261  *lenp = sizeof (float);
14262  }
14263  break;
14264  case SQL_C_DOUBLE:
14265  *((double *) val) = ln_strtod(*data, &endp);
14266  if (endp && endp == *data) {
14267  *lenp = SQL_NULL_DATA;
14268  } else {
14269  *lenp = sizeof (double);
14270  }
14271  break;
14272  case SQL_C_BINARY: {
14273  int dlen, offs = 0;
14274  char *bin;
14275 
14276  if (valnull) {
14277  freep(&s->bincache);
14278  s->binlen = 0;
14279  goto doCHAR;
14280  }
14281  if (*data == s->bincell) {
14282  if (s->bincache) {
14283  bin = s->bincache;
14284  dlen = s->binlen;
14285  } else {
14286  goto doCHAR;
14287  }
14288  } else {
14289  char *dp;
14290  int i;
14291 
14292  freep(&s->bincache);
14293  dp = *data;
14294  dlen = strlen(dp);
14295  s->bincell = dp;
14296  s->binlen = 0;
14297  if (!(dp[0] == 'x' || dp[0] == 'X') || dp[1] != '\'' ||
14298  dp[dlen - 1] != '\'') {
14299  goto doCHAR;
14300  }
14301  dlen -= 2;
14302  dp += 2;
14303  dlen = dlen / 2;
14304  s->bincache = bin = xmalloc(dlen + 1);
14305  if (!bin) {
14306  return nomem(s);
14307  }
14308  s->binlen = dlen;
14309  memset(bin, 0, dlen);
14310  bin[dlen] = '\0'; /* terminator, just in case */
14311  for (i = 0; i < dlen; i++) {
14312  char *x;
14313  int v;
14314 
14315  if (!*dp || !(x = strchr(xdigits, *dp))) {
14316  goto converr;
14317  }
14318  v = x - xdigits;
14319  bin[i] = (v >= 16) ? ((v - 6) << 4) : (v << 4);
14320  ++dp;
14321  if (!*dp || !(x = strchr(xdigits, *dp))) {
14322 converr:
14323  freep(&s->bincache);
14324  s->binlen = 0;
14325  setstat(s, -1, "conversion error",
14326  (*s->ov3) ? "HY000" : "S1000");
14327  return SQL_ERROR;
14328  }
14329  v = x - xdigits;
14330  bin[i] |= (v >= 16) ? (v - 6) : v;
14331  ++dp;
14332  }
14333  bin = s->bincache;
14334  }
14335  if (partial && len && s->bindcols) {
14336  if (s->bindcols[col].offs >= dlen) {
14337  *lenp = 0;
14338  if (!dlen && s->bindcols[col].offs == dlen) {
14339  s->bindcols[col].offs = 1;
14340  sret = SQL_SUCCESS;
14341  goto done;
14342  }
14343  s->bindcols[col].offs = 0;
14344  sret = SQL_NO_DATA;
14345  goto done;
14346  }
14347  offs = s->bindcols[col].offs;
14348  dlen -= offs;
14349  }
14350  if (val && len) {
14351  memcpy(val, bin + offs, min(len, dlen));
14352  }
14353  if (len < 1) {
14354  *lenp = dlen;
14355  } else {
14356  *lenp = min(len, dlen);
14357  if (*lenp == len && *lenp != dlen) {
14358  *lenp = SQL_NO_TOTAL;
14359  }
14360  }
14361  if (partial && len && s->bindcols) {
14362  if (*lenp == SQL_NO_TOTAL) {
14363  *lenp = dlen;
14364  s->bindcols[col].offs += len;
14365  setstat(s, -1, "data right truncated", "01004");
14366  if (s->bindcols[col].lenp) {
14367  *s->bindcols[col].lenp = dlen;
14368  }
14369  sret = SQL_SUCCESS_WITH_INFO;
14370  goto done;
14371  }
14372  s->bindcols[col].offs += *lenp;
14373  }
14374  if (*lenp == SQL_NO_TOTAL) {
14375  *lenp = dlen;
14376  setstat(s, -1, "data right truncated", "01004");
14377  sret = SQL_SUCCESS_WITH_INFO;
14378  goto done;
14379  }
14380  break;
14381  }
14382  doCHAR:
14383 #ifdef WCHARSUPPORT
14384  case SQL_C_WCHAR:
14385 #endif
14386  case SQL_C_CHAR: {
14387  int doz, zlen = len - 1;
14388  int dlen = strlen(*data);
14389  int offs = 0;
14390 #ifdef WCHARSUPPORT
14391  SQLWCHAR *ucdata = NULL;
14392  SQLCHAR *cdata = (SQLCHAR *) *data;
14393 #endif
14394 
14395 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
14396  /* MS Access hack part 2 (reserved error -7748) */
14397  if (!valnull &&
14398  (s->cols == statSpec2P || s->cols == statSpec3P) &&
14399  type == SQL_C_WCHAR) {
14400  if (len > 0 && len <= sizeof (SQLWCHAR)) {
14401  ((char *) val)[0] = data[0][0];
14402  memset((char *) val + 1, 0, len - 1);
14403  *lenp = 1;
14404  sret = SQL_SUCCESS;
14405  goto done;
14406  }
14407  }
14408 #endif
14409 
14410 #ifdef WCHARSUPPORT
14411  switch (type) {
14412  case SQL_C_CHAR:
14413  doz = 1;
14414  break;
14415  case SQL_C_WCHAR:
14416  doz = sizeof (SQLWCHAR);
14417  break;
14418  default:
14419  doz = 0;
14420  break;
14421  }
14422  if (type == SQL_C_WCHAR) {
14423  ucdata = uc_from_utf(cdata, dlen);
14424  if (!ucdata) {
14425  return nomem(s);
14426  }
14427  dlen = uc_strlen(ucdata) * sizeof (SQLWCHAR);
14428  }
14429 #if defined(_WIN32) || defined(_WIN64)
14430  else if (*s->oemcp && type == SQL_C_CHAR) {
14431  ucdata = (SQLWCHAR *) utf_to_wmb((char *) cdata, dlen);
14432  if (!ucdata) {
14433  return nomem(s);
14434  }
14435  cdata = (SQLCHAR *) ucdata;
14436  dlen = strlen((char *) cdata);
14437  }
14438 #endif
14439 #else
14440  doz = (type == SQL_C_CHAR) ? 1 : 0;
14441 #endif
14442  if (partial && len && s->bindcols) {
14443  if (s->bindcols[col].offs >= dlen) {
14444 #ifdef WCHARSUPPORT
14445  uc_free(ucdata);
14446 #endif
14447  *lenp = 0;
14448  if (doz && val) {
14449 #ifdef WCHARSUPPORT
14450  if (type == SQL_C_WCHAR) {
14451  ((SQLWCHAR *) val)[0] = 0;
14452  } else {
14453  ((char *) val)[0] = '\0';
14454  }
14455 #else
14456  ((char *) val)[0] = '\0';
14457 #endif
14458  }
14459  if (!dlen && s->bindcols[col].offs == dlen) {
14460  s->bindcols[col].offs = 1;
14461  sret = SQL_SUCCESS;
14462  goto done;
14463  }
14464  s->bindcols[col].offs = 0;
14465  sret = SQL_NO_DATA;
14466  goto done;
14467  }
14468  offs = s->bindcols[col].offs;
14469  dlen -= offs;
14470  }
14471  if (val && !valnull && len) {
14472 #ifdef WCHARSUPPORT
14473  if (type == SQL_C_WCHAR) {
14474  uc_strncpy(val, ucdata + offs / sizeof (SQLWCHAR),
14475  (len - doz) / sizeof (SQLWCHAR));
14476  } else {
14477  strncpy(val, (char *) cdata + offs, len - doz);
14478  }
14479 #else
14480  strncpy(val, *data + offs, len - doz);
14481 #endif
14482  }
14483  if (valnull || len < 1) {
14484  *lenp = dlen;
14485  } else {
14486  *lenp = min(len - doz, dlen);
14487  if (*lenp == len - doz && *lenp != dlen) {
14488  *lenp = SQL_NO_TOTAL;
14489  } else if (*lenp < zlen) {
14490  zlen = *lenp;
14491  }
14492  }
14493  if (len && !valnull && doz) {
14494 #ifdef WCHARSUPPORT
14495  if (type == SQL_C_WCHAR) {
14496  ((SQLWCHAR *) val)[zlen / sizeof (SQLWCHAR)] = 0;
14497  } else {
14498  ((char *) val)[zlen] = '\0';
14499  }
14500 #else
14501  ((char *) val)[zlen] = '\0';
14502 #endif
14503  }
14504 #ifdef WCHARSUPPORT
14505  uc_free(ucdata);
14506 #endif
14507  if (partial && len && s->bindcols) {
14508  if (*lenp == SQL_NO_TOTAL) {
14509  *lenp = dlen;
14510  s->bindcols[col].offs += len - doz;
14511  setstat(s, -1, "data right truncated", "01004");
14512  if (s->bindcols[col].lenp) {
14513  *s->bindcols[col].lenp = dlen;
14514  }
14515  sret = SQL_SUCCESS_WITH_INFO;
14516  goto done;
14517  }
14518  s->bindcols[col].offs += *lenp;
14519  }
14520  if (*lenp == SQL_NO_TOTAL) {
14521  *lenp = dlen;
14522  setstat(s, -1, "data right truncated", "01004");
14523  sret = SQL_SUCCESS_WITH_INFO;
14524  goto done;
14525  }
14526  break;
14527  }
14528 #ifdef SQL_C_TYPE_DATE
14529  case SQL_C_TYPE_DATE:
14530 #endif
14531  case SQL_C_DATE:
14532  if (str2date(*s->jdconv, *data, (DATE_STRUCT *) val) < 0) {
14533  *lenp = SQL_NULL_DATA;
14534  } else {
14535  *lenp = sizeof (DATE_STRUCT);
14536  }
14537  break;
14538 #ifdef SQL_C_TYPE_TIME
14539  case SQL_C_TYPE_TIME:
14540 #endif
14541  case SQL_C_TIME:
14542  if (str2time(*s->jdconv, *data, (TIME_STRUCT *) val) < 0) {
14543  *lenp = SQL_NULL_DATA;
14544  } else {
14545  *lenp = sizeof (TIME_STRUCT);
14546  }
14547  break;
14548 #ifdef SQL_C_TYPE_TIMESTAMP
14549  case SQL_C_TYPE_TIMESTAMP:
14550 #endif
14551  case SQL_C_TIMESTAMP:
14552  if (str2timestamp(*s->jdconv, *data,
14553  (TIMESTAMP_STRUCT *) val) < 0) {
14554  *lenp = SQL_NULL_DATA;
14555  } else {
14556  *lenp = sizeof (TIMESTAMP_STRUCT);
14557  }
14558  switch (s->cols[col].prec) {
14559  case 0:
14560  ((TIMESTAMP_STRUCT *) val)->fraction = 0;
14561  break;
14562  case 1:
14563  ((TIMESTAMP_STRUCT *) val)->fraction /= 100000000;
14564  ((TIMESTAMP_STRUCT *) val)->fraction *= 100000000;
14565  break;
14566  case 2:
14567  ((TIMESTAMP_STRUCT *) val)->fraction /= 10000000;
14568  ((TIMESTAMP_STRUCT *) val)->fraction *= 10000000;
14569  break;
14570  }
14571  break;
14572  default:
14573  return SQL_ERROR;
14574  }
14575  }
14576  sret = SQL_SUCCESS;
14577 done:
14578  if (ilenp) {
14579  *ilenp = *lenp;
14580  }
14581  return sret;
14582 }
14583 
14595 static SQLRETURN
14596 drvbindcol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14597  SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14598 {
14599  STMT *s;
14600  int sz = 0;
14601 
14602  if (stmt == SQL_NULL_HSTMT) {
14603  return SQL_INVALID_HANDLE;
14604  }
14605  s = (STMT *) stmt;
14606  if (col < 1) {
14607  if (col == 0 && s->bkmrk == SQL_UB_ON &&
14608  type == SQL_C_BOOKMARK) {
14609  s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14610  s->bkmrkcol.max = val ? sizeof (SQLINTEGER) : 0;
14611  s->bkmrkcol.lenp = val ? lenp : 0;
14612  s->bkmrkcol.valp = val;
14613  s->bkmrkcol.offs = 0;
14614  if (val && lenp) {
14615  *lenp = 0;
14616  }
14617  return SQL_SUCCESS;
14618  } else if (col == 0 && s->bkmrk == SQL_UB_VARIABLE &&
14619  type == SQL_C_VARBOOKMARK &&
14620  max >= sizeof (sqlite_int64)) {
14621  s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14622  s->bkmrkcol.max = val ? max : 0;
14623  s->bkmrkcol.lenp = val ? lenp : 0;
14624  s->bkmrkcol.valp = val;
14625  s->bkmrkcol.offs = 0;
14626  if (val && lenp) {
14627  *lenp = 0;
14628  }
14629  return SQL_SUCCESS;
14630  }
14631  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
14632  return SQL_ERROR;
14633  }
14634  if (mkbindcols(s, col) != SQL_SUCCESS) {
14635  return SQL_ERROR;
14636  }
14637  --col;
14638  if (type == SQL_C_DEFAULT) {
14639  type = mapdeftype(type, s->cols[col].type, 0,
14640  s->nowchar[0] || s->nowchar[1]);
14641  }
14642  switch (type) {
14643  case SQL_C_LONG:
14644  case SQL_C_ULONG:
14645  case SQL_C_SLONG:
14646  sz = sizeof (SQLINTEGER);
14647  break;
14648  case SQL_C_TINYINT:
14649  case SQL_C_UTINYINT:
14650  case SQL_C_STINYINT:
14651  sz = sizeof (SQLCHAR);
14652  break;
14653  case SQL_C_SHORT:
14654  case SQL_C_USHORT:
14655  case SQL_C_SSHORT:
14656  sz = sizeof (SQLSMALLINT);
14657  break;
14658  case SQL_C_FLOAT:
14659  sz = sizeof (SQLFLOAT);
14660  break;
14661  case SQL_C_DOUBLE:
14662  sz = sizeof (SQLDOUBLE);
14663  break;
14664  case SQL_C_TIMESTAMP:
14665  sz = sizeof (SQL_TIMESTAMP_STRUCT);
14666  break;
14667  case SQL_C_TIME:
14668  sz = sizeof (SQL_TIME_STRUCT);
14669  break;
14670  case SQL_C_DATE:
14671  sz = sizeof (SQL_DATE_STRUCT);
14672  break;
14673  case SQL_C_CHAR:
14674  break;
14675 #ifdef WCHARSUPPORT
14676  case SQL_C_WCHAR:
14677  break;
14678 #endif
14679 #ifdef SQL_C_TYPE_DATE
14680  case SQL_C_TYPE_DATE:
14681  sz = sizeof (SQL_DATE_STRUCT);
14682  break;
14683 #endif
14684 #ifdef SQL_C_TYPE_TIME
14685  case SQL_C_TYPE_TIME:
14686  sz = sizeof (SQL_TIME_STRUCT);
14687  break;
14688 #endif
14689 #ifdef SQL_C_TYPE_TIMESTAMP
14690  case SQL_C_TYPE_TIMESTAMP:
14691  sz = sizeof (SQL_TIMESTAMP_STRUCT);
14692  break;
14693 #endif
14694 #ifdef SQL_BIT
14695  case SQL_C_BIT:
14696  sz = sizeof (SQLCHAR);
14697  break;
14698 #endif
14699  case SQL_C_BINARY:
14700  break;
14701 #ifdef SQL_BIGINT
14702  case SQL_C_SBIGINT:
14703  case SQL_C_UBIGINT:
14704  sz = sizeof (SQLBIGINT);
14705  break;
14706 #endif
14707  default:
14708  if (val == NULL) {
14709  /* fall through, unbinding column */
14710  break;
14711  }
14712  setstat(s, -1, "invalid type %d", "HY003", type);
14713  return SQL_ERROR;
14714  }
14715  if (val == NULL) {
14716  /* unbind column */
14717  s->bindcols[col].type = SQL_UNKNOWN_TYPE;
14718  s->bindcols[col].max = 0;
14719  s->bindcols[col].lenp = NULL;
14720  s->bindcols[col].valp = NULL;
14721  s->bindcols[col].offs = 0;
14722  } else {
14723  if (sz == 0 && max < 0) {
14724  setstat(s, -1, "invalid length", "HY090");
14725  return SQL_ERROR;
14726  }
14727  s->bindcols[col].type = type;
14728  s->bindcols[col].max = (sz == 0) ? max : sz;
14729  s->bindcols[col].lenp = lenp;
14730  s->bindcols[col].valp = val;
14731  s->bindcols[col].offs = 0;
14732  if (lenp) {
14733  *lenp = 0;
14734  }
14735  }
14736  return SQL_SUCCESS;
14737 }
14738 
14750 SQLRETURN SQL_API
14751 SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14752  SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14753 {
14754  SQLRETURN ret;
14755 
14756  HSTMT_LOCK(stmt);
14757  ret = drvbindcol(stmt, col, type, val, max, lenp);
14758  HSTMT_UNLOCK(stmt);
14759  return ret;
14760 }
14761 
14766 static COL tableSpec2[] = {
14767  { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
14768  { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
14769  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14770  { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14771  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14772 };
14773 
14774 static COL tableSpec3[] = {
14775  { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
14776  { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
14777  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14778  { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14779  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14780 };
14781 
14796 static SQLRETURN
14797 drvtables(SQLHSTMT stmt,
14798  SQLCHAR *cat, SQLSMALLINT catLen,
14799  SQLCHAR *schema, SQLSMALLINT schemaLen,
14800  SQLCHAR *table, SQLSMALLINT tableLen,
14801  SQLCHAR *type, SQLSMALLINT typeLen)
14802 {
14803  SQLRETURN ret;
14804  STMT *s;
14805  DBC *d;
14806  int ncols, asize, rc, size, npatt;
14807  char *errp = NULL, *sql, tname[512];
14808  char *where = "(type = 'table' or type = 'view')";
14809 
14811  tableSpec3, array_size(tableSpec3), &asize);
14812  if (ret != SQL_SUCCESS) {
14813  return ret;
14814  }
14815  s = (STMT *) stmt;
14816  d = (DBC *) s->dbc;
14817  if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] == '%') {
14818  int size = 3 * asize;
14819 
14820  s->rows = xmalloc(size * sizeof (char *));
14821  if (!s->rows) {
14822  s->nrows = 0;
14823  return nomem(s);
14824  }
14825  memset(s->rows, 0, sizeof (char *) * size);
14826  s->ncols = asize;
14827  s->rows[s->ncols + 0] = "";
14828  s->rows[s->ncols + 1] = "";
14829  s->rows[s->ncols + 2] = "";
14830  s->rows[s->ncols + 3] = "TABLE";
14831  s->rows[s->ncols + 5] = "";
14832  s->rows[s->ncols + 6] = "";
14833  s->rows[s->ncols + 7] = "";
14834  s->rows[s->ncols + 8] = "VIEW";
14835 #ifdef MEMORY_DEBUG
14836  s->rowfree = xfree__;
14837 #else
14838  s->rowfree = (void (*)(char **))sqlite3_free;
14839 #endif
14840  s->nrows = 2;
14841  s->rowp = s->rowprs = -1;
14842  return SQL_SUCCESS;
14843  }
14844  if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
14845  table = NULL;
14846  goto doit;
14847  }
14848  if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
14849  schema[0] == '%') {
14850  if ((!cat || catLen == 0 || !cat[0]) &&
14851  (!table || tableLen == 0 || !table[0])) {
14852  table = NULL;
14853  goto doit;
14854  }
14855  }
14856  if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] != '\0') {
14857  char tmp[256], *t;
14858  int with_view = 0, with_table = 0;
14859 
14860  if (typeLen == SQL_NTS) {
14861  strncpy(tmp, (char *) type, sizeof (tmp));
14862  tmp[sizeof (tmp) - 1] = '\0';
14863  } else {
14864  int len = min(sizeof (tmp) - 1, typeLen);
14865 
14866  strncpy(tmp, (char *) type, len);
14867  tmp[len] = '\0';
14868  }
14869  t = tmp;
14870  while (*t) {
14871  *t = TOLOWER(*t);
14872  t++;
14873  }
14874  t = tmp;
14875  unescpat(t);
14876  while (t) {
14877  if (t[0] == '\'') {
14878  ++t;
14879  }
14880  if (strncmp(t, "table", 5) == 0) {
14881  with_table++;
14882  } else if (strncmp(t, "view", 4) == 0) {
14883  with_view++;
14884  }
14885  t = strchr(t, ',');
14886  if (t) {
14887  ++t;
14888  }
14889  }
14890  if (with_view && with_table) {
14891  /* where is already preset */
14892  } else if (with_view && !with_table) {
14893  where = "type = 'view'";
14894  } else if (!with_view && with_table) {
14895  where = "type = 'table'";
14896  } else {
14897  return SQL_SUCCESS;
14898  }
14899  }
14900 doit:
14901  if (!table) {
14902  size = 1;
14903  tname[0] = '%';
14904  } else {
14905  if (tableLen == SQL_NTS) {
14906  size = sizeof (tname) - 1;
14907  } else {
14908  size = min(sizeof (tname) - 1, tableLen);
14909  }
14910  strncpy(tname, (char *) table, size);
14911  }
14912  tname[size] = '\0';
14913  npatt = unescpat(tname);
14914 #if defined(_WIN32) || defined(_WIN64)
14915  if (npatt) {
14916  sql = sqlite3_mprintf("select %s as 'TABLE_CAT', "
14917  "%s as 'TABLE_SCHEM', "
14918  "tbl_name as 'TABLE_NAME', "
14919  "upper(type) as 'TABLE_TYPE', "
14920  "NULL as 'REMARKS' "
14921  "from sqlite_master where %s "
14922  "and tbl_name like %Q",
14923  d->xcelqrx ? "'main'" : "NULL",
14924  d->xcelqrx ? "''" : "NULL",
14925  where, tname);
14926  } else {
14927  sql = sqlite3_mprintf("select %s as 'TABLE_CAT', "
14928  "%s as 'TABLE_SCHEM', "
14929  "tbl_name as 'TABLE_NAME', "
14930  "upper(type) as 'TABLE_TYPE', "
14931  "NULL as 'REMARKS' "
14932  "from sqlite_master where %s "
14933  "and lower(tbl_name) = lower(%Q)",
14934  d->xcelqrx ? "'main'" : "NULL",
14935  d->xcelqrx ? "''" : "NULL",
14936  where, tname);
14937  }
14938 #else
14939  if (npatt) {
14940  sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
14941  "NULL as 'TABLE_OWNER', "
14942  "tbl_name as 'TABLE_NAME', "
14943  "upper(type) as 'TABLE_TYPE', "
14944  "NULL as 'REMARKS' "
14945  "from sqlite_master where %s "
14946  "and tbl_name like %Q",
14947  where, tname);
14948  } else {
14949  sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
14950  "NULL as 'TABLE_OWNER', "
14951  "tbl_name as 'TABLE_NAME', "
14952  "upper(type) as 'TABLE_TYPE', "
14953  "NULL as 'REMARKS' "
14954  "from sqlite_master where %s "
14955  "and lower(tbl_name) = lower(%Q)",
14956  where, tname);
14957  }
14958 #endif
14959  if (!sql) {
14960  return nomem(s);
14961  }
14962  ret = starttran(s);
14963  if (ret != SQL_SUCCESS) {
14964  sqlite3_free(sql);
14965  return ret;
14966  }
14967  dbtraceapi(d, "sqlite3_get_table", sql);
14968  rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
14969  sqlite3_free(sql);
14970  if (rc == SQLITE_OK) {
14971  if (ncols != s->ncols) {
14972  freeresult(s, 0);
14973  s->nrows = 0;
14974  } else {
14975  s->rowfree = sqlite3_free_table;
14976  }
14977  } else {
14978  s->nrows = 0;
14979  s->rows = NULL;
14980  s->rowfree = NULL;
14981  }
14982  if (errp) {
14983  sqlite3_free(errp);
14984  errp = NULL;
14985  }
14986  s->rowp = s->rowprs = -1;
14987  return SQL_SUCCESS;
14988 }
14989 
14990 #ifndef WINTERFACE
14991 
15005 SQLRETURN SQL_API
15006 SQLTables(SQLHSTMT stmt,
15007  SQLCHAR *cat, SQLSMALLINT catLen,
15008  SQLCHAR *schema, SQLSMALLINT schemaLen,
15009  SQLCHAR *table, SQLSMALLINT tableLen,
15010  SQLCHAR *type, SQLSMALLINT typeLen)
15011 {
15012 #if defined(_WIN32) || defined(_WIN64)
15013  char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
15014 #endif
15015  SQLRETURN ret;
15016 
15017  HSTMT_LOCK(stmt);
15018 #if defined(_WIN32) || defined(_WIN64)
15019  if (!((STMT *) stmt)->oemcp[0]) {
15020  ret = drvtables(stmt, cat, catLen, schema, schemaLen,
15021  table, tableLen, type, typeLen);
15022  goto done2;
15023  }
15024  if (cat) {
15025  c = wmb_to_utf_c((char *) cat, catLen);
15026  if (!c) {
15027  ret = nomem((STMT *) stmt);
15028  goto done;
15029  }
15030  }
15031  if (schema) {
15032  s = wmb_to_utf_c((char *) schema, schemaLen);
15033  if (!s) {
15034  ret = nomem((STMT *) stmt);
15035  goto done;
15036  }
15037  }
15038  if (table) {
15039  t = wmb_to_utf_c((char *) table, tableLen);
15040  if (!t) {
15041  ret = nomem((STMT *) stmt);
15042  goto done;
15043  }
15044  }
15045  if (type) {
15046  y = wmb_to_utf_c((char *) type, typeLen);
15047  if (!y) {
15048  ret = nomem((STMT *) stmt);
15049  goto done;
15050  }
15051  }
15052  ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15053  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
15054 #else
15055  ret = drvtables(stmt, cat, catLen, schema, schemaLen,
15056  table, tableLen, type, typeLen);
15057 #endif
15058 #if defined(_WIN32) || defined(_WIN64)
15059 done:
15060  uc_free(y);
15061  uc_free(t);
15062  uc_free(s);
15063  uc_free(c);
15064 done2:
15065  ;
15066 #endif
15067  HSTMT_UNLOCK(stmt);
15068  return ret;
15069 }
15070 #endif
15071 
15072 #ifdef WINTERFACE
15073 
15087 SQLRETURN SQL_API
15088 SQLTablesW(SQLHSTMT stmt,
15089  SQLWCHAR *cat, SQLSMALLINT catLen,
15090  SQLWCHAR *schema, SQLSMALLINT schemaLen,
15091  SQLWCHAR *table, SQLSMALLINT tableLen,
15092  SQLWCHAR *type, SQLSMALLINT typeLen)
15093 {
15094  char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
15095  SQLRETURN ret;
15096 
15097  HSTMT_LOCK(stmt);
15098  if (cat) {
15099  c = uc_to_utf_c(cat, catLen);
15100  if (!c) {
15101  ret = nomem((STMT *) stmt);
15102  goto done;
15103  }
15104  }
15105  if (schema) {
15106  s = uc_to_utf_c(schema, schemaLen);
15107  if (!s) {
15108  ret = nomem((STMT *) stmt);
15109  goto done;
15110  }
15111  }
15112  if (table) {
15113  t = uc_to_utf_c(table, tableLen);
15114  if (!t) {
15115  ret = nomem((STMT *) stmt);
15116  goto done;
15117  }
15118  }
15119  if (type) {
15120  y = uc_to_utf_c(type, typeLen);
15121  if (!y) {
15122  ret = nomem((STMT *) stmt);
15123  goto done;
15124  }
15125  }
15126  ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15127  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
15128 done:
15129  uc_free(y);
15130  uc_free(t);
15131  uc_free(s);
15132  uc_free(c);
15133  HSTMT_UNLOCK(stmt);
15134  return ret;
15135 }
15136 #endif
15137 
15142 static COL colSpec2[] = {
15143  { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
15144  { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
15145  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
15146  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15147  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
15148  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
15149  { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
15150  { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
15151  { "SYSTEM", "COLUMN", "SCALE", SQL_SMALLINT, 50 },
15152  { "SYSTEM", "COLUMN", "RADIX", SQL_SMALLINT, 50 },
15153  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
15154  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
15155  { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
15156  { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
15157  { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
15158  { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
15159  { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
15160  { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
15161 };
15162 
15163 static COL colSpec3[] = {
15164  { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
15165  { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
15166  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
15167  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15168  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
15169  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
15170  { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
15171  { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
15172  { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_SMALLINT, 50 },
15173  { "SYSTEM", "COLUMN", "NUM_PREC_RADIX", SQL_SMALLINT, 50 },
15174  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
15175  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
15176  { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
15177  { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
15178  { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
15179  { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
15180  { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
15181  { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
15182 };
15183 
15198 static SQLRETURN
15199 drvcolumns(SQLHSTMT stmt,
15200  SQLCHAR *cat, SQLSMALLINT catLen,
15201  SQLCHAR *schema, SQLSMALLINT schemaLen,
15202  SQLCHAR *table, SQLSMALLINT tableLen,
15203  SQLCHAR *col, SQLSMALLINT colLen)
15204 {
15205  SQLRETURN sret;
15206  STMT *s;
15207  DBC *d;
15208  int ret, nrows, ncols, asize, i, k, roffs, namec;
15209  int tnrows, tncols, npatt;
15210  PTRDIFF_T size;
15211  char *errp = NULL, *sql, tname[512], cname[512], **rowp, **trows;
15212 
15214  colSpec3, array_size(colSpec3), &asize);
15215  if (sret != SQL_SUCCESS) {
15216  return sret;
15217  }
15218  s = (STMT *) stmt;
15219  d = (DBC *) s->dbc;
15220  if (!table) {
15221  size = 1;
15222  tname[0] = '%';
15223  } else {
15224  if (tableLen == SQL_NTS) {
15225  size = sizeof (tname) - 1;
15226  } else {
15227  size = min(sizeof (tname) - 1, tableLen);
15228  }
15229  strncpy(tname, (char *) table, size);
15230  }
15231  tname[size] = '\0';
15232  npatt = unescpat(tname);
15233  size = 0;
15234  if (col) {
15235  if (colLen == SQL_NTS) {
15236  size = sizeof (cname) - 1;
15237  } else {
15238  size = min(sizeof (cname) - 1, colLen);
15239  }
15240  strncpy(cname, (char *) col, size);
15241  }
15242  cname[size] = '\0';
15243  if (!strcmp(cname, "%")) {
15244  cname[0] = '\0';
15245  }
15246  if (npatt) {
15247  sql = sqlite3_mprintf("select tbl_name from sqlite_master where "
15248  "(type = 'table' or type = 'view') "
15249  "and tbl_name like %Q", tname);
15250  } else {
15251  sql = sqlite3_mprintf("select tbl_name from sqlite_master where "
15252  "(type = 'table' or type = 'view') "
15253  "and lower(tbl_name) = lower(%Q)", tname);
15254  }
15255  if (!sql) {
15256  return nomem(s);
15257  }
15258  sret = starttran(s);
15259  if (sret != SQL_SUCCESS) {
15260  sqlite3_free(sql);
15261  return sret;
15262  }
15263  dbtraceapi(d, "sqlite3_get_table", sql);
15264  ret = sqlite3_get_table(d->sqlite, sql, &trows, &tnrows, &tncols, &errp);
15265  sqlite3_free(sql);
15266  if (ret != SQLITE_OK) {
15267  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15268  errp ? errp : "unknown error", ret);
15269  if (errp) {
15270  sqlite3_free(errp);
15271  errp = NULL;
15272  }
15273  return SQL_ERROR;
15274  }
15275  if (errp) {
15276  sqlite3_free(errp);
15277  errp = NULL;
15278  }
15279  /* pass 1: compute number of rows of result set */
15280  if (tncols * tnrows <= 0) {
15281  sqlite3_free_table(trows);
15282  return SQL_SUCCESS;
15283  }
15284  size = 0;
15285  for (i = 1; i <= tnrows; i++) {
15286  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
15287  if (!sql) {
15288  sqlite3_free_table(trows);
15289  return nomem(s);
15290  }
15291  dbtraceapi(d, "sqlite3_get_table", sql);
15292  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15293  sqlite3_free(sql);
15294  if (ret != SQLITE_OK) {
15295  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15296  errp ? errp : "unknown error", ret);
15297  if (errp) {
15298  sqlite3_free(errp);
15299  errp = NULL;
15300  }
15301  sqlite3_free_table(trows);
15302  return SQL_ERROR;
15303  }
15304  if (errp) {
15305  sqlite3_free(errp);
15306  errp = NULL;
15307  }
15308  if (ncols * nrows > 0) {
15309  namec = -1;
15310  for (k = 0; k < ncols; k++) {
15311  if (strcmp(rowp[k], "name") == 0) {
15312  namec = k;
15313  break;
15314  }
15315  }
15316  if (cname[0]) {
15317  if (namec >= 0) {
15318  for (k = 1; k <= nrows; k++) {
15319  if (namematch(rowp[k * ncols + namec], cname, 1)) {
15320  size++;
15321  }
15322  }
15323  }
15324  } else {
15325  size += nrows;
15326  }
15327  }
15328  sqlite3_free_table(rowp);
15329  }
15330  /* pass 2: fill result set */
15331  if (size <= 0) {
15332  sqlite3_free_table(trows);
15333  return SQL_SUCCESS;
15334  }
15335  s->nrows = size;
15336  size = (size + 1) * asize;
15337  s->rows = xmalloc((size + 1) * sizeof (char *));
15338  if (!s->rows) {
15339  s->nrows = 0;
15340  sqlite3_free_table(trows);
15341  return nomem(s);
15342  }
15343  s->rows[0] = (char *) size;
15344  s->rows += 1;
15345  memset(s->rows, 0, sizeof (char *) * size);
15346  s->rowfree = freerows;
15347  roffs = 1;
15348  for (i = 1; i <= tnrows; i++) {
15349  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
15350  if (!sql) {
15351  sqlite3_free_table(trows);
15352  return nomem(s);
15353  }
15354  dbtraceapi(d, "sqlite3_get_table", sql);
15355  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15356  sqlite3_free(sql);
15357  if (ret != SQLITE_OK) {
15358  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15359  errp ? errp : "unknown error", ret);
15360  if (errp) {
15361  sqlite3_free(errp);
15362  errp = NULL;
15363  }
15364  sqlite3_free_table(trows);
15365  return SQL_ERROR;
15366  }
15367  if (errp) {
15368  sqlite3_free(errp);
15369  errp = NULL;
15370  }
15371  if (ncols * nrows > 0) {
15372  int m, mr, nr = nrows;
15373 
15374  namec = -1;
15375  for (k = 0; k < ncols; k++) {
15376  if (strcmp(rowp[k], "name") == 0) {
15377  namec = k;
15378  break;
15379  }
15380  }
15381  if (cname[0]) {
15382  nr = 0;
15383  if (namec >= 0) {
15384  for (k = 1; k <= nrows; k++) {
15385  if (namematch(rowp[k * ncols + namec], cname, 1)) {
15386  nr++;
15387  }
15388  }
15389  }
15390  }
15391  for (k = 0; k < nr; k++) {
15392  m = asize * (roffs + k);
15393 #if defined(_WIN32) || defined(_WIN64)
15394  s->rows[m + 0] = xstrdup(d->xcelqrx ? "main" : "");
15395  s->rows[m + 1] = xstrdup("");
15396 #else
15397  s->rows[m + 0] = xstrdup("");
15398  s->rows[m + 1] = xstrdup("");
15399 #endif
15400  s->rows[m + 2] = xstrdup(trows[i]);
15401  s->rows[m + 8] = xstrdup("10");
15402  s->rows[m + 9] = xstrdup("0");
15403  s->rows[m + 15] = xstrdup("16384");
15404  }
15405  for (k = 0; nr && k < ncols; k++) {
15406  if (strcmp(rowp[k], "cid") == 0) {
15407  for (mr = 0, m = 1; m <= nrows; m++) {
15408  char buf[256];
15409  int ir, coln = k;
15410 
15411  if (cname[0] &&
15412  !namematch(rowp[m * ncols + namec], cname, 1)) {
15413  continue;
15414  }
15415  ir = asize * (roffs + mr);
15416  sscanf(rowp[m * ncols + k], "%d", &coln);
15417  sprintf(buf, "%d", coln + 1);
15418  s->rows[ir + 16] = xstrdup(buf);
15419  ++mr;
15420  }
15421  } else if (k == namec) {
15422  for (mr = 0, m = 1; m <= nrows; m++) {
15423  int ir;
15424 
15425  if (cname[0] &&
15426  !namematch(rowp[m * ncols + namec], cname, 1)) {
15427  continue;
15428  }
15429  ir = asize * (roffs + mr);
15430  s->rows[ir + 3] = xstrdup(rowp[m * ncols + k]);
15431  ++mr;
15432  }
15433  } else if (strcmp(rowp[k], "notnull") == 0) {
15434  for (mr = 0, m = 1; m <= nrows; m++) {
15435  int ir;
15436 
15437  if (cname[0] &&
15438  !namematch(rowp[m * ncols + namec], cname, 1)) {
15439  continue;
15440  }
15441  ir = asize * (roffs + mr);
15442  if (*rowp[m * ncols + k] != '0') {
15443  s->rows[ir + 10] = xstrdup(stringify(SQL_FALSE));
15444  } else {
15445  s->rows[ir + 10] = xstrdup(stringify(SQL_TRUE));
15446  }
15447  s->rows[ir + 17] =
15448  xstrdup((*rowp[m * ncols + k] != '0') ?
15449  "NO" : "YES");
15450  ++mr;
15451  }
15452  } else if (strcmp(rowp[k], "dflt_value") == 0) {
15453  for (mr = 0, m = 1; m <= nrows; m++) {
15454  char *dflt = unquote(rowp[m * ncols + k]);
15455  int ir;
15456 
15457  if (cname[0] &&
15458  !namematch(rowp[m * ncols + namec], cname, 1)) {
15459  continue;
15460  }
15461  ir = asize * (roffs + mr);
15462  s->rows[ir + 12] = xstrdup(dflt ? dflt : "NULL");
15463  ++mr;
15464  }
15465  } else if (strcmp(rowp[k], "type") == 0) {
15466  for (mr = 0, m = 1; m <= nrows; m++) {
15467  char *typename = rowp[m * ncols + k];
15468  int sqltype, mm, dd, ir;
15469  char buf[256];
15470 
15471  if (cname[0] &&
15472  !namematch(rowp[m * ncols + namec], cname, 1)) {
15473  continue;
15474  }
15475  ir = asize * (roffs + mr);
15476  s->rows[ir + 5] = xstrdup(typename);
15477  sqltype = mapsqltype(typename, NULL, *s->ov3,
15478  s->nowchar[0], s->dobigint);
15479  getmd(typename, sqltype, &mm, &dd);
15480 #ifdef SQL_LONGVARCHAR
15481  if (sqltype == SQL_VARCHAR && mm > 255) {
15482  sqltype = SQL_LONGVARCHAR;
15483  }
15484 #endif
15485 #ifdef WINTERFACE
15486 #ifdef SQL_WLONGVARCHAR
15487  if (sqltype == SQL_WVARCHAR && mm > 255) {
15488  sqltype = SQL_WLONGVARCHAR;
15489  }
15490 #endif
15491 #endif
15492  if (sqltype == SQL_VARBINARY && mm > 255) {
15493  sqltype = SQL_LONGVARBINARY;
15494  }
15495  sprintf(buf, "%d", sqltype);
15496  s->rows[ir + 4] = xstrdup(buf);
15497  s->rows[ir + 13] = xstrdup(buf);
15498  sprintf(buf, "%d", mm);
15499  s->rows[ir + 7] = xstrdup(buf);
15500  sprintf(buf, "%d", dd);
15501  s->rows[ir + 6] = xstrdup(buf);
15502  ++mr;
15503  }
15504  }
15505  }
15506  roffs += nr;
15507  }
15508  sqlite3_free_table(rowp);
15509  }
15510  sqlite3_free_table(trows);
15511  return SQL_SUCCESS;
15512 }
15513 
15514 #ifndef WINTERFACE
15515 
15529 SQLRETURN SQL_API
15530 SQLColumns(SQLHSTMT stmt,
15531  SQLCHAR *cat, SQLSMALLINT catLen,
15532  SQLCHAR *schema, SQLSMALLINT schemaLen,
15533  SQLCHAR *table, SQLSMALLINT tableLen,
15534  SQLCHAR *col, SQLSMALLINT colLen)
15535 {
15536 #if defined(_WIN32) || defined(_WIN64)
15537  char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15538 #endif
15539  SQLRETURN ret;
15540 
15541  HSTMT_LOCK(stmt);
15542 #if defined(_WIN32) || defined(_WIN64)
15543  if (!((STMT *) stmt)->oemcp[0]) {
15544  ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15545  table, tableLen, col, colLen);
15546  goto done2;
15547  }
15548  if (cat) {
15549  c = wmb_to_utf_c((char *) cat, catLen);
15550  if (!c) {
15551  ret = nomem((STMT *) stmt);
15552  goto done;
15553  }
15554  }
15555  if (schema) {
15556  s = wmb_to_utf_c((char *) schema, schemaLen);
15557  if (!s) {
15558  ret = nomem((STMT *) stmt);
15559  goto done;
15560  }
15561  }
15562  if (table) {
15563  t = wmb_to_utf_c((char *) table, tableLen);
15564  if (!t) {
15565  ret = nomem((STMT *) stmt);
15566  goto done;
15567  }
15568  }
15569  if (col) {
15570  k = wmb_to_utf_c((char *) col, colLen);
15571  if (!k) {
15572  ret = nomem((STMT *) stmt);
15573  goto done;
15574  }
15575  }
15576  ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15577  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15578 #else
15579  ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15580  table, tableLen, col, colLen);
15581 #endif
15582 #if defined(_WIN32) || defined(_WIN64)
15583 done:
15584  uc_free(k);
15585  uc_free(t);
15586  uc_free(s);
15587  uc_free(c);
15588 done2:
15589  ;
15590 #endif
15591  HSTMT_UNLOCK(stmt);
15592  return ret;
15593 }
15594 #endif
15595 
15596 #ifdef WINTERFACE
15597 
15611 SQLRETURN SQL_API
15613  SQLWCHAR *cat, SQLSMALLINT catLen,
15614  SQLWCHAR *schema, SQLSMALLINT schemaLen,
15615  SQLWCHAR *table, SQLSMALLINT tableLen,
15616  SQLWCHAR *col, SQLSMALLINT colLen)
15617 {
15618  char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15619  SQLRETURN ret;
15620 
15621  HSTMT_LOCK(stmt);
15622  if (cat) {
15623  c = uc_to_utf_c(cat, catLen);
15624  if (!c) {
15625  ret = nomem((STMT *) stmt);
15626  goto done;
15627  }
15628  }
15629  if (schema) {
15630  s = uc_to_utf_c(schema, schemaLen);
15631  if (!s) {
15632  ret = nomem((STMT *) stmt);
15633  goto done;
15634  }
15635  }
15636  if (table) {
15637  t = uc_to_utf_c(table, tableLen);
15638  if (!t) {
15639  ret = nomem((STMT *) stmt);
15640  goto done;
15641  }
15642  }
15643  if (col) {
15644  k = uc_to_utf_c(col, colLen);
15645  if (!k) {
15646  ret = nomem((STMT *) stmt);
15647  goto done;
15648  }
15649  }
15650  ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15651  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15652 done:
15653  uc_free(k);
15654  uc_free(t);
15655  uc_free(s);
15656  uc_free(c);
15657  HSTMT_UNLOCK(stmt);
15658  return ret;
15659 
15660 }
15661 #endif
15662 
15667 static COL typeSpec2[] = {
15668  { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15669  { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15670  { "SYSTEM", "TYPE", "PRECISION", SQL_INTEGER, 9 },
15671  { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15672  { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15673  { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15674  { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15675  { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15676  { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15677  { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15678  { "SYSTEM", "TYPE", "MONEY", SQL_SMALLINT, 2 },
15679  { "SYSTEM", "TYPE", "AUTO_INCREMENT", SQL_SMALLINT, 2 },
15680  { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15681  { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15682  { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 }
15683 };
15684 
15685 static COL typeSpec3[] = {
15686  { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15687  { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15688  { "SYSTEM", "TYPE", "COLUMN_SIZE", SQL_INTEGER, 9 },
15689  { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15690  { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15691  { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15692  { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15693  { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15694  { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15695  { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15696  { "SYSTEM", "TYPE", "FIXED_PREC_SCALE", SQL_SMALLINT, 2 },
15697  { "SYSTEM", "TYPE", "AUTO_UNIQUE_VALUE", SQL_SMALLINT, 2 },
15698  { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15699  { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15700  { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 },
15701  { "SYSTEM", "TYPE", "SQL_DATA_TYPE", SQL_SMALLINT, 2 },
15702  { "SYSTEM", "TYPE", "SQL_DATETIME_SUB", SQL_SMALLINT, 2 },
15703  { "SYSTEM", "TYPE", "NUM_PREC_RADIX", SQL_INTEGER, 4 },
15704  { "SYSTEM", "TYPE", "INTERVAL_PRECISION", SQL_SMALLINT, 2 }
15705 };
15706 
15717 static void
15718 mktypeinfo(STMT *s, int row, int asize, char *typename, int type, int tind)
15719 {
15720  int offs = row * asize;
15721  char *tcode, *crpar = NULL, *sign = stringify(SQL_FALSE);
15722  char *quote[2] = { NULL, NULL };
15723  static char tcodes[32 * 32];
15724 
15725  if (tind <= 0) {
15726  tind = row;
15727  }
15728  tcode = tcodes + tind * 32;
15729  sprintf(tcode, "%d", type);
15730  s->rows[offs + 0] = typename;
15731  s->rows[offs + 1] = tcode;
15732  if (asize >= 17) {
15733  s->rows[offs + 15] = tcode;
15734  s->rows[offs + 16] = "0";
15735  }
15736  switch (type) {
15737  default:
15738 #ifdef SQL_LONGVARCHAR
15739  case SQL_LONGVARCHAR:
15740 #ifdef WINTERFACE
15741  case SQL_WLONGVARCHAR:
15742 #endif
15743  crpar = "length";
15744  quote[0] = quote[1] = "'";
15745  sign = NULL;
15746  s->rows[offs + 2] = "65536";
15747  break;
15748 #endif
15749 #ifdef SQL_BIT
15750  case SQL_BIT:
15751  sign = NULL;
15752  s->rows[offs + 2] = "1";
15753  break;
15754 #endif
15755  case SQL_CHAR:
15756  case SQL_VARCHAR:
15757 #ifdef WINTERFACE
15758  case SQL_WCHAR:
15759  case SQL_WVARCHAR:
15760 #endif
15761  s->rows[offs + 2] = "255";
15762  crpar = "length";
15763  quote[0] = quote[1] = "'";
15764  sign = NULL;
15765  break;
15766  case SQL_TINYINT:
15767  s->rows[offs + 2] = "3";
15768  break;
15769  case SQL_SMALLINT:
15770  s->rows[offs + 2] = "5";
15771  break;
15772  case SQL_INTEGER:
15773  s->rows[offs + 2] = "9";
15774  break;
15775 #ifdef SQL_BIGINT
15776  case SQL_BIGINT:
15777  s->rows[offs + 2] = "19";
15778  break;
15779 #endif
15780  case SQL_FLOAT:
15781  s->rows[offs + 2] = "7";
15782  break;
15783  case SQL_DOUBLE:
15784  s->rows[offs + 2] = "15";
15785  break;
15786 #ifdef SQL_TYPE_DATE
15787  case SQL_TYPE_DATE:
15788 #endif
15789  case SQL_DATE:
15790  s->rows[offs + 2] = "10";
15791  quote[0] = quote[1] = "'";
15792  sign = NULL;
15793  break;
15794 #ifdef SQL_TYPE_TIME
15795  case SQL_TYPE_TIME:
15796 #endif
15797  case SQL_TIME:
15798  s->rows[offs + 2] = "8";
15799  quote[0] = quote[1] = "'";
15800  sign = NULL;
15801  break;
15802 #ifdef SQL_TYPE_TIMESTAMP
15803  case SQL_TYPE_TIMESTAMP:
15804 #endif
15805  case SQL_TIMESTAMP:
15806  s->rows[offs + 2] = "32";
15807  quote[0] = quote[1] = "'";
15808  sign = NULL;
15809  break;
15810  case SQL_VARBINARY:
15811  quote[0] = "0x";
15812  sign = NULL;
15813  s->rows[offs + 2] = "255";
15814  break;
15815  case SQL_LONGVARBINARY:
15816  quote[0] = "0x";
15817  sign = NULL;
15818  s->rows[offs + 2] = "65536";
15819  break;
15820  }
15821  s->rows[offs + 3] = quote[0];
15822  s->rows[offs + 4] = quote[1];
15823  s->rows[offs + 5] = crpar;
15824  s->rows[offs + 6] = stringify(SQL_NULLABLE);
15825  s->rows[offs + 7] = stringify(SQL_FALSE);
15826  s->rows[offs + 8] = stringify(SQL_SEARCHABLE);
15827  s->rows[offs + 9] = sign;
15828  s->rows[offs + 10] = stringify(SQL_FALSE);
15829  s->rows[offs + 11] = stringify(SQL_FALSE);
15830  s->rows[offs + 12] = typename;
15831  switch (type) {
15832  case SQL_DATE:
15833  case SQL_TIME:
15834  s->rows[offs + 13] = "0";
15835  s->rows[offs + 14] = "0";
15836  break;
15837 #ifdef SQL_TYPE_TIMESTAMP
15838  case SQL_TYPE_TIMESTAMP:
15839 #endif
15840  case SQL_TIMESTAMP:
15841  s->rows[offs + 13] = "0";
15842  s->rows[offs + 14] = "3";
15843  break;
15844  default:
15845  s->rows[offs + 13] = NULL;
15846  s->rows[offs + 14] = NULL;
15847  break;
15848  }
15849 }
15850 
15859 static int
15860 typeinfosort(const void *a, const void *b)
15861 {
15862  char **pa = (char **) a;
15863  char **pb = (char **) b;
15864  int na, nb;
15865 
15866  na = strtol(pa[1], NULL, 0);
15867  nb = strtol(pb[1], NULL, 0);
15868  return na - nb;
15869 }
15870 
15878 static SQLRETURN
15879 drvgettypeinfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
15880 {
15881  SQLRETURN ret;
15882  STMT *s;
15883  int asize;
15884 
15886  typeSpec3, array_size(typeSpec3), &asize);
15887  if (ret != SQL_SUCCESS) {
15888  return ret;
15889  }
15890  s = (STMT *) stmt;
15891 #ifdef SQL_LONGVARCHAR
15892  s->nrows = (sqltype == SQL_ALL_TYPES) ? 13 : 1;
15893 #else
15894  s->nrows = (sqltype == SQL_ALL_TYPES) ? 12 : 1;
15895 #endif
15896  if (sqltype == SQL_ALL_TYPES) {
15897 #ifdef WINTERFACE
15898  s->nrows += 2;
15899 #ifdef SQL_WLONGVARCHAR
15900  s->nrows += 2;
15901 #endif
15902 #endif
15903  }
15904  if (sqltype == SQL_ALL_TYPES) {
15905  s->nrows += 2;
15906 #ifdef SQL_BIT
15907  s->nrows += 1;
15908 #endif
15909 #ifdef SQL_BIGINT
15910  s->nrows += 1;
15911 #endif
15912  }
15913  s->rows = (char **) xmalloc(sizeof (char *) * (s->nrows + 1) * asize);
15914  if (!s->rows) {
15915  s->nrows = 0;
15916  return nomem(s);
15917  }
15918 #ifdef MEMORY_DEBUG
15919  s->rowfree = xfree__;
15920 #else
15921  s->rowfree = (void (*)(char **))sqlite3_free;
15922 #endif
15923  memset(s->rows, 0, sizeof (char *) * (s->nrows + 1) * asize);
15924  if (sqltype == SQL_ALL_TYPES) {
15925  int cc = 1;
15926 
15927  mktypeinfo(s, cc++, asize, "varchar", SQL_VARCHAR, 0);
15928  mktypeinfo(s, cc++, asize, "tinyint", SQL_TINYINT, 0);
15929  mktypeinfo(s, cc++, asize, "smallint", SQL_SMALLINT, 0);
15930  mktypeinfo(s, cc++, asize, "integer", SQL_INTEGER, 0);
15931  mktypeinfo(s, cc++, asize, "float", SQL_FLOAT, 0);
15932  mktypeinfo(s, cc++, asize, "double", SQL_DOUBLE, 0);
15933 #ifdef SQL_TYPE_DATE
15934  mktypeinfo(s, cc++, asize, "date",
15935  (*s->ov3) ? SQL_TYPE_DATE : SQL_DATE, 0);
15936 #else
15937  mktypeinfo(s, cc++, asize, "date", SQL_DATE, 0);
15938 #endif
15939 #ifdef SQL_TYPE_TIME
15940  mktypeinfo(s, cc++, asize, "time",
15941  (*s->ov3) ? SQL_TYPE_TIME : SQL_TIME, 0);
15942 #else
15943  mktypeinfo(s, cc++, asize, "time", SQL_TIME, 0);
15944 #endif
15945 #ifdef SQL_TYPE_TIMESTAMP
15946  mktypeinfo(s, cc++, asize, "timestamp",
15947  (*s->ov3) ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP, 0);
15948 #else
15949  mktypeinfo(s, cc++, asize, "timestamp", SQL_TIMESTAMP, 0);
15950 #endif
15951  mktypeinfo(s, cc++, asize, "char", SQL_CHAR, 0);
15952  mktypeinfo(s, cc++, asize, "numeric", SQL_DOUBLE, 0);
15953 #ifdef SQL_LONGVARCHAR
15954  mktypeinfo(s, cc++, asize, "text", SQL_LONGVARCHAR, 0);
15955  mktypeinfo(s, cc++, asize, "longvarchar", SQL_LONGVARCHAR, 0);
15956 #else
15957  mktypeinfo(s, cc++, asize, "text", SQL_VARCHAR, 0);
15958 #endif
15959  mktypeinfo(s, cc++, asize, "varbinary", SQL_VARBINARY, 0);
15960  mktypeinfo(s, cc++, asize, "longvarbinary", SQL_LONGVARBINARY, 0);
15961 #ifdef SQL_BIT
15962  mktypeinfo(s, cc++, asize, "bit", SQL_BIT, 0);
15963 #endif
15964 #ifdef SQL_BIGINT
15965  mktypeinfo(s, cc++, asize, "bigint", SQL_BIGINT, 0);
15966 #endif
15967 #ifdef WINTERFACE
15968  mktypeinfo(s, cc++, asize, "wvarchar", SQL_WVARCHAR, 0);
15969  mktypeinfo(s, cc++, asize, "wchar", SQL_WCHAR, 0);
15970 #ifdef SQL_WLONGVARCHAR
15971  mktypeinfo(s, cc++, asize, "wtext", SQL_WLONGVARCHAR, 0);
15972  mktypeinfo(s, cc++, asize, "longwvarchar", SQL_WLONGVARCHAR, 0);
15973 #endif
15974 #endif
15975  qsort(s->rows + asize, s->nrows, sizeof (char *) * asize,
15976  typeinfosort);
15977  } else {
15978  switch (sqltype) {
15979  case SQL_CHAR:
15980  mktypeinfo(s, 1, asize, "char", SQL_CHAR, 10);
15981  break;
15982  case SQL_VARCHAR:
15983  mktypeinfo(s, 1, asize, "varchar", SQL_VARCHAR, 1);
15984  break;
15985  case SQL_TINYINT:
15986  mktypeinfo(s, 1, asize, "tinyint", SQL_TINYINT, 2);
15987  break;
15988  case SQL_SMALLINT:
15989  mktypeinfo(s, 1, asize, "smallint", SQL_SMALLINT, 3);
15990  break;
15991  case SQL_INTEGER:
15992  mktypeinfo(s, 1, asize, "integer", SQL_INTEGER, 4);
15993  break;
15994  case SQL_FLOAT:
15995  mktypeinfo(s, 1, asize, "float", SQL_FLOAT, 5);
15996  break;
15997  case SQL_DOUBLE:
15998  mktypeinfo(s, 1, asize, "double", SQL_DOUBLE, 6);
15999  break;
16000 #ifdef SQL_TYPE_DATE
16001  case SQL_TYPE_DATE:
16002  mktypeinfo(s, 1, asize, "date", SQL_TYPE_DATE, 25);
16003  break;
16004 #endif
16005  case SQL_DATE:
16006  mktypeinfo(s, 1, asize, "date", SQL_DATE, 7);
16007  break;
16008 #ifdef SQL_TYPE_TIME
16009  case SQL_TYPE_TIME:
16010  mktypeinfo(s, 1, asize, "time", SQL_TYPE_TIME, 26);
16011  break;
16012 #endif
16013  case SQL_TIME:
16014  mktypeinfo(s, 1, asize, "time", SQL_TIME, 8);
16015  break;
16016 #ifdef SQL_TYPE_TIMESTAMP
16017  case SQL_TYPE_TIMESTAMP:
16018  mktypeinfo(s, 1, asize, "timestamp", SQL_TYPE_TIMESTAMP, 27);
16019  break;
16020 #endif
16021  case SQL_TIMESTAMP:
16022  mktypeinfo(s, 1, asize, "timestamp", SQL_TIMESTAMP, 9);
16023  break;
16024 #ifdef SQL_LONGVARCHAR
16025  case SQL_LONGVARCHAR:
16026  mktypeinfo(s, 1, asize, "longvarchar", SQL_LONGVARCHAR, 12);
16027  break;
16028 #endif
16029  case SQL_VARBINARY:
16030  mktypeinfo(s, 1, asize, "varbinary", SQL_VARBINARY, 30);
16031  break;
16032  case SQL_LONGVARBINARY:
16033  mktypeinfo(s, 1, asize, "longvarbinary", SQL_LONGVARBINARY, 31);
16034  break;
16035 #ifdef SQL_BIT
16036  case SQL_BIT:
16037  mktypeinfo(s, 1, asize, "bit", SQL_BIT, 29);
16038  break;
16039 #endif
16040 #ifdef SQL_BIGINT
16041  case SQL_BIGINT:
16042  mktypeinfo(s, 1, asize, "bigint", SQL_BIGINT, 28);
16043  break;
16044 #endif
16045 #ifdef WINTERFACE
16046 #ifdef SQL_WCHAR
16047  case SQL_WCHAR:
16048  mktypeinfo(s, 1, asize, "wchar", SQL_WCHAR, 18);
16049  break;
16050 #endif
16051 #ifdef SQL_WVARCHAR
16052  case SQL_WVARCHAR:
16053  mktypeinfo(s, 1, asize, "wvarchar", SQL_WVARCHAR, 19);
16054  break;
16055 #endif
16056 #ifdef SQL_WLONGVARCHAR
16057  case SQL_WLONGVARCHAR:
16058  mktypeinfo(s, 1, asize, "longwvarchar", SQL_WLONGVARCHAR, 20);
16059  break;
16060 #endif
16061 #endif
16062  default:
16063  s->nrows = 0;
16064  }
16065  }
16066  return SQL_SUCCESS;
16067 }
16068 
16069 #ifndef WINTERFACE
16070 
16077 SQLRETURN SQL_API
16078 SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
16079 {
16080  SQLRETURN ret;
16081 
16082  HSTMT_LOCK(stmt);
16083  ret = drvgettypeinfo(stmt, sqltype);
16084  HSTMT_UNLOCK(stmt);
16085  return ret;
16086 }
16087 #endif
16088 
16089 #ifdef WINTERFACE
16090 
16097 SQLRETURN SQL_API
16098 SQLGetTypeInfoW(SQLHSTMT stmt, SQLSMALLINT sqltype)
16099 {
16100  SQLRETURN ret;
16101 
16102  HSTMT_LOCK(stmt);
16103  ret = drvgettypeinfo(stmt, sqltype);
16104  HSTMT_UNLOCK(stmt);
16105  return ret;
16106 }
16107 #endif
16108 
16113 static COL statSpec2[] = {
16114  { "SYSTEM", "STATISTICS", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
16115  { "SYSTEM", "STATISTICS", "TABLE_OWNER", SCOL_VARCHAR, 50 },
16116  { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
16117  { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
16118  { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
16119  { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
16120  { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
16121  { "SYSTEM", "STATISTICS", "SEQ_IN_INDEX", SQL_SMALLINT, 50 },
16122  { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
16123  { "SYSTEM", "STATISTICS", "COLLATION", SCOL_CHAR, 1 },
16124  { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
16125  { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
16126  { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
16127 };
16128 
16129 static COL statSpec3[] = {
16130  { "SYSTEM", "STATISTICS", "TABLE_CAT", SCOL_VARCHAR, 50 },
16131  { "SYSTEM", "STATISTICS", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
16132  { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
16133  { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
16134  { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
16135  { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
16136  { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
16137  { "SYSTEM", "STATISTICS", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
16138  { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
16139  { "SYSTEM", "STATISTICS", "ASC_OR_DESC", SCOL_CHAR, 1 },
16140  { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
16141  { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
16142  { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
16143 };
16144 
16159 static SQLRETURN
16160 drvstatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
16161  SQLCHAR *schema, SQLSMALLINT schemaLen,
16162  SQLCHAR *table, SQLSMALLINT tableLen,
16163  SQLUSMALLINT itype, SQLUSMALLINT resv)
16164 {
16165  SQLRETURN sret;
16166  STMT *s;
16167  DBC *d;
16168  int i, asize, ret, nrows, ncols, offs, namec, uniquec, addipk = 0;
16169  PTRDIFF_T size;
16170  char **rowp, *errp = NULL, *sql, tname[512];
16171 
16173  statSpec3, array_size(statSpec3), &asize);
16174  if (sret != SQL_SUCCESS) {
16175  return sret;
16176  }
16177  s = (STMT *) stmt;
16178  d = (DBC *) s->dbc;
16179  if (!table || table[0] == '\0' || table[0] == '%') {
16180  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
16181  return SQL_ERROR;
16182  }
16183  if (tableLen == SQL_NTS) {
16184  size = sizeof (tname) - 1;
16185  } else {
16186  size = min(sizeof (tname) - 1, tableLen);
16187  }
16188  strncpy(tname, (char *) table, size);
16189  tname[size] = '\0';
16190  unescpat(tname);
16191  sret = starttran(s);
16192  if (sret != SQL_SUCCESS) {
16193  return sret;
16194  }
16195  /*
16196  * Try integer primary key (autoincrement) first
16197  */
16198  if (itype == SQL_INDEX_UNIQUE || itype == SQL_INDEX_ALL) {
16199  rowp = 0;
16200  ret = SQLITE_ERROR;
16201  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
16202  if (sql) {
16203  dbtraceapi(d, "sqlite3_get_table", sql);
16204  ret = sqlite3_get_table(d->sqlite, sql, &rowp,
16205  &nrows, &ncols, NULL);
16206  sqlite3_free(sql);
16207  }
16208  if (ret == SQLITE_OK) {
16209  int colid, typec, npk = 0, npkint = 0;
16210 
16211  namec = findcol(rowp, ncols, "name");
16212  uniquec = findcol(rowp, ncols, "pk");
16213  typec = findcol(rowp, ncols, "type");
16214  colid = findcol(rowp, ncols, "cid");
16215  if (namec < 0 || uniquec < 0 || typec < 0 || colid < 0) {
16216  goto noipk;
16217  }
16218  for (i = 1; i <= nrows; i++) {
16219  if (*rowp[i * ncols + uniquec] != '0') {
16220  npk++;
16221  if (strlen(rowp[i * ncols + typec]) == 7 &&
16222  strncasecmp(rowp[i * ncols + typec], "integer", 7)
16223  == 0) {
16224  npkint++;
16225  }
16226  }
16227  }
16228  if (npkint == 1 && npk == npkint) {
16229  addipk = 1;
16230  }
16231  }
16232 noipk:
16233  sqlite3_free_table(rowp);
16234  }
16235  sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
16236  if (!sql) {
16237  return nomem(s);
16238  }
16239  dbtraceapi(d, "sqlite3_get_table", sql);
16240  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
16241  sqlite3_free(sql);
16242  if (ret != SQLITE_OK) {
16243  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
16244  errp ? errp : "unknown error", ret);
16245  if (errp) {
16246  sqlite3_free(errp);
16247  errp = NULL;
16248  }
16249  return SQL_ERROR;
16250  }
16251  if (errp) {
16252  sqlite3_free(errp);
16253  errp = NULL;
16254  }
16255  size = 0;
16256  namec = findcol(rowp, ncols, "name");
16257  uniquec = findcol(rowp, ncols, "unique");
16258  if (namec < 0 || uniquec < 0) {
16259  goto nodata;
16260  }
16261  for (i = 1; i <= nrows; i++) {
16262  int nnrows, nncols;
16263  char **rowpp;
16264  int isuniq;
16265 
16266  isuniq = *rowp[i * ncols + uniquec] != '0';
16267  if (isuniq || itype == SQL_INDEX_ALL) {
16268  ret = SQLITE_ERROR;
16269  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
16270  rowp[i * ncols + namec]);
16271  if (sql) {
16272  dbtraceapi(d, "sqlite3_get_table", sql);
16273  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16274  &nnrows, &nncols, NULL);
16275  sqlite3_free(sql);
16276  }
16277  if (ret == SQLITE_OK) {
16278  size += nnrows;
16279  sqlite3_free_table(rowpp);
16280  }
16281  }
16282  }
16283 nodata:
16284  if (addipk) {
16285  size++;
16286  }
16287  if (size == 0) {
16288  sqlite3_free_table(rowp);
16289  return SQL_SUCCESS;
16290  }
16291  s->nrows = size;
16292  size = (size + 1) * asize;
16293  s->rows = xmalloc((size + 1) * sizeof (char *));
16294  if (!s->rows) {
16295  s->nrows = 0;
16296  return nomem(s);
16297  }
16298  s->rows[0] = (char *) size;
16299  s->rows += 1;
16300  memset(s->rows, 0, sizeof (char *) * size);
16301  s->rowfree = freerows;
16302  offs = 0;
16303  if (addipk) {
16304  char **rowpp = 0;
16305  int nrows2, ncols2;
16306 
16307  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
16308  if (sql) {
16309  dbtraceapi(d, "sqlite3_get_table", sql);
16310  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16311  &nrows2, &ncols2, NULL);
16312  sqlite3_free(sql);
16313  }
16314  if (ret == SQLITE_OK) {
16315  int colid, typec, roffs, namecc, uniquecc;
16316 
16317  namecc = findcol(rowpp, ncols2, "name");
16318  uniquecc = findcol(rowpp, ncols2, "pk");
16319  typec = findcol(rowpp, ncols2, "type");
16320  colid = findcol(rowpp, ncols2, "cid");
16321  if (namecc < 0 || uniquecc < 0 || typec < 0 || colid < 0) {
16322  addipk = 0;
16323  s->nrows--;
16324  goto nodata2;
16325  }
16326  for (i = 1; i <= nrows2; i++) {
16327  if (*rowpp[i * ncols2 + uniquecc] != '0' &&
16328  strlen(rowpp[i * ncols2 + typec]) == 7 &&
16329  strncasecmp(rowpp[i * ncols2 + typec], "integer", 7)
16330  == 0) {
16331  break;
16332  }
16333  }
16334  if (i > nrows2) {
16335  addipk = 0;
16336  s->nrows--;
16337  goto nodata2;
16338  }
16339  roffs = s->ncols;
16340 #if defined(_WIN32) || defined(_WIN64)
16341  s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
16342  s->rows[roffs + 1] = xstrdup("");
16343 #else
16344  s->rows[roffs + 0] = xstrdup("");
16345  s->rows[roffs + 1] = xstrdup("");
16346 #endif
16347  s->rows[roffs + 2] = xstrdup(tname);
16348  s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16349  s->rows[roffs + 5] = xstrdup("sqlite_autoindex_0");
16350  s->rows[roffs + 6] = xstrdup(stringify(SQL_INDEX_OTHER));
16351  s->rows[roffs + 7] = xstrdup("1");
16352  s->rows[roffs + 8] = xstrdup(rowpp[i * ncols2 + namecc]);
16353  s->rows[roffs + 9] = xstrdup("A");
16354  }
16355 nodata2:
16356  sqlite3_free_table(rowpp);
16357  }
16358  for (i = 1; i <= nrows; i++) {
16359  int nnrows, nncols;
16360  char **rowpp = 0;
16361 
16362  if (*rowp[i * ncols + uniquec] != '0' || itype == SQL_INDEX_ALL) {
16363  int k;
16364 
16365  ret = SQLITE_ERROR;
16366  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
16367  rowp[i * ncols + namec]);
16368  if (sql) {
16369  dbtraceapi(d, "sqlite3_get_table", sql);
16370  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16371  &nnrows, &nncols, NULL);
16372  sqlite3_free(sql);
16373  }
16374  if (ret != SQLITE_OK) {
16375  continue;
16376  }
16377  for (k = 0; nnrows && k < nncols; k++) {
16378  if (strcmp(rowpp[k], "name") == 0) {
16379  int m;
16380 
16381  for (m = 1; m <= nnrows; m++) {
16382  int roffs = (offs + addipk + m) * s->ncols;
16383  int isuniq;
16384 
16385  isuniq = *rowp[i * ncols + uniquec] != '0';
16386  s->rows[roffs + 0] = xstrdup("");
16387  s->rows[roffs + 1] = xstrdup("");
16388  s->rows[roffs + 2] = xstrdup(tname);
16389  if (isuniq) {
16390  s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16391  } else {
16392  s->rows[roffs + 3] = xstrdup(stringify(SQL_TRUE));
16393  }
16394  s->rows[roffs + 5] = xstrdup(rowp[i * ncols + namec]);
16395  s->rows[roffs + 6] =
16396  xstrdup(stringify(SQL_INDEX_OTHER));
16397  s->rows[roffs + 8] = xstrdup(rowpp[m * nncols + k]);
16398  s->rows[roffs + 9] = xstrdup("A");
16399  }
16400  } else if (strcmp(rowpp[k], "seqno") == 0) {
16401  int m;
16402 
16403  for (m = 1; m <= nnrows; m++) {
16404  int roffs = (offs + addipk + m) * s->ncols;
16405  int pos = m - 1;
16406  char buf[32];
16407 
16408  sscanf(rowpp[m * nncols + k], "%d", &pos);
16409  sprintf(buf, "%d", pos + 1);
16410  s->rows[roffs + 7] = xstrdup(buf);
16411  }
16412  }
16413  }
16414  offs += nnrows;
16415  sqlite3_free_table(rowpp);
16416  }
16417  }
16418  sqlite3_free_table(rowp);
16419  return SQL_SUCCESS;
16420 }
16421 
16422 #ifndef WINTERFACE
16423 
16437 SQLRETURN SQL_API
16438 SQLStatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
16439  SQLCHAR *schema, SQLSMALLINT schemaLen,
16440  SQLCHAR *table, SQLSMALLINT tableLen,
16441  SQLUSMALLINT itype, SQLUSMALLINT resv)
16442 {
16443 #if defined(_WIN32) || defined(_WIN64)
16444  char *c = NULL, *s = NULL, *t = NULL;
16445 #endif
16446  SQLRETURN ret;
16447 
16448  HSTMT_LOCK(stmt);
16449 #if defined(_WIN32) || defined(_WIN64)
16450  if (!((STMT *) stmt)->oemcp[0]) {
16451  ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16452  table, tableLen, itype, resv);
16453  goto done2;
16454  }
16455  if (cat) {
16456  c = wmb_to_utf_c((char *) cat, catLen);
16457  if (!c) {
16458  ret = nomem((STMT *) stmt);
16459  goto done;
16460  }
16461  }
16462  if (schema) {
16463  s = wmb_to_utf_c((char *) schema, schemaLen);
16464  if (!s) {
16465  ret = nomem((STMT *) stmt);
16466  goto done;
16467  }
16468  }
16469  if (table) {
16470  t = wmb_to_utf_c((char *) table, tableLen);
16471  if (!t) {
16472  ret = nomem((STMT *) stmt);
16473  goto done;
16474  }
16475  }
16476  ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16477  (SQLCHAR *) t, SQL_NTS, itype, resv);
16478 #else
16479  ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16480  table, tableLen, itype, resv);
16481 #endif
16482 #if defined(_WIN32) || defined(_WIN64)
16483 done:
16484  uc_free(t);
16485  uc_free(s);
16486  uc_free(c);
16487 done2:
16488  ;
16489 #endif
16490  HSTMT_UNLOCK(stmt);
16491  return ret;
16492 }
16493 #endif
16494 
16495 #ifdef WINTERFACE
16496 
16510 SQLRETURN SQL_API
16511 SQLStatisticsW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen,
16512  SQLWCHAR *schema, SQLSMALLINT schemaLen,
16513  SQLWCHAR *table, SQLSMALLINT tableLen,
16514  SQLUSMALLINT itype, SQLUSMALLINT resv)
16515 {
16516  char *c = NULL, *s = NULL, *t = NULL;
16517  SQLRETURN ret;
16518 
16519  HSTMT_LOCK(stmt);
16520  if (cat) {
16521  c = uc_to_utf_c(cat, catLen);
16522  if (!c) {
16523  ret = nomem((STMT *) stmt);
16524  goto done;
16525  }
16526  }
16527  if (schema) {
16528  s = uc_to_utf_c(schema, schemaLen);
16529  if (!s) {
16530  ret = nomem((STMT *) stmt);
16531  goto done;
16532  }
16533  }
16534  if (table) {
16535  t = uc_to_utf_c(table, tableLen);
16536  if (!t) {
16537  ret = nomem((STMT *) stmt);
16538  goto done;
16539  }
16540  }
16541  ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16542  (SQLCHAR *) t, SQL_NTS, itype, resv);
16543 done:
16544  uc_free(t);
16545  uc_free(s);
16546  uc_free(c);
16547  HSTMT_UNLOCK(stmt);
16548  return ret;
16549 }
16550 #endif
16551 
16563 SQLRETURN SQL_API
16564 SQLGetData(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
16565  SQLPOINTER val, SQLLEN len, SQLLEN *lenp)
16566 {
16567  STMT *s;
16568  SQLRETURN ret = SQL_ERROR;
16569 
16570  HSTMT_LOCK(stmt);
16571  if (stmt == SQL_NULL_HSTMT) {
16572  return SQL_INVALID_HANDLE;
16573  }
16574  s = (STMT *) stmt;
16575  if (col == 0 && s->bkmrk != SQL_UB_OFF) {
16576  if (s->bkmrk == SQL_UB_ON && type == SQL_C_BOOKMARK) {
16577  *((SQLINTEGER *) val) = s->rowp;
16578  if (lenp) {
16579  *lenp = sizeof (SQLINTEGER);
16580  }
16581  ret = SQL_SUCCESS;
16582  goto done;
16583  } else if (s->bkmrk == SQL_UB_VARIABLE && type == SQL_C_VARBOOKMARK) {
16584  if (s->has_rowid >= 0) {
16585  char **data, *endp = 0;
16586 
16587  data = s->rows + s->ncols + (s->rowp * s->ncols)
16588  + s->has_rowid;
16589 #ifdef __osf__
16590  *((sqlite_int64 *) val) = strtol(*data, &endp, 0);
16591 #else
16592  *((sqlite_int64 *) val) = strtoll(*data, &endp, 0);
16593 #endif
16594  } else {
16595  *((sqlite_int64 *) val) = s->rowp;
16596  }
16597  if (lenp) {
16598  *lenp = sizeof (sqlite_int64);
16599  }
16600  ret = SQL_SUCCESS;
16601  goto done;
16602  }
16603  }
16604  if (col < 1 || col > s->ncols) {
16605  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
16606  goto done;
16607  }
16608  --col;
16609  ret = getrowdata(s, col, type, val, len, lenp, 1);
16610 done:
16611  HSTMT_UNLOCK(stmt);
16612  return ret;
16613 }
16614 
16622 static SQLRETURN
16623 dofetchbind(STMT *s, int rsi)
16624 {
16625  int ret, i, withinfo = 0;
16626 
16627  s->row_status0[rsi] = SQL_ROW_SUCCESS;
16628  if (s->bkmrk != SQL_UB_OFF && s->bkmrkcol.valp) {
16629  int bsize = sizeof (SQLINTEGER);
16630 
16631  if (s->bkmrkcol.type == SQL_C_VARBOOKMARK) {
16632  SQLPOINTER *val;
16633 
16634  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16635  val = (SQLPOINTER)
16636  ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16637  } else {
16638  val = (SQLPOINTER)
16639  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * rsi);
16640  }
16641  if (s->bind_offs) {
16642  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
16643  }
16644  if (s->has_rowid >= 0) {
16645  char **data, *endp = 0;
16646 
16647  data = s->rows + s->ncols + (s->rowp * s->ncols)
16648  + s->has_rowid;
16649 #ifdef __osf__
16650  *(sqlite_int64 *) val = strtol(*data, &endp, 0);
16651 #else
16652  *(sqlite_int64 *) val = strtoll(*data, &endp, 0);
16653 #endif
16654  } else {
16655  *(sqlite_int64 *) val = s->rowp;
16656  }
16657  bsize = sizeof (sqlite_int64);
16658  } else {
16659  SQLINTEGER *val;
16660 
16661  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16662  val = (SQLINTEGER *)
16663  ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16664  } else {
16665  val = (SQLINTEGER *) s->bkmrkcol.valp + rsi;
16666  }
16667  if (s->bind_offs) {
16668  val = (SQLINTEGER *) ((char *) val + *s->bind_offs);
16669  }
16670  *val = s->rowp;
16671  }
16672  if (s->bkmrkcol.lenp) {
16673  SQLLEN *ival;
16674 
16675  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16676  ival = (SQLLEN *)
16677  ((char *) s->bkmrkcol.lenp + s->bind_type * rsi);
16678  } else {
16679  ival = &s->bkmrkcol.lenp[rsi];
16680  }
16681  if (s->bind_offs) {
16682  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
16683  }
16684  *ival = bsize;
16685  }
16686  }
16687  ret = SQL_SUCCESS;
16688  for (i = 0; s->bindcols && i < s->ncols; i++) {
16689  BINDCOL *b = &s->bindcols[i];
16690  SQLPOINTER dp = 0;
16691  SQLLEN *lp = 0;
16692 
16693  b->offs = 0;
16694  if (b->valp) {
16695  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16696  dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
16697  } else {
16698  dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
16699  }
16700  if (s->bind_offs) {
16701  dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
16702  }
16703  }
16704  if (b->lenp) {
16705  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16706  lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
16707  } else {
16708  lp = b->lenp + rsi;
16709  }
16710  if (s->bind_offs) {
16711  lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
16712  }
16713  }
16714  if (dp || lp) {
16715  ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp, b->max, lp, 0);
16716  if (!SQL_SUCCEEDED(ret)) {
16717  s->row_status0[rsi] = SQL_ROW_ERROR;
16718  break;
16719  }
16720  if (ret != SQL_SUCCESS) {
16721  withinfo = 1;
16722 #ifdef SQL_ROW_SUCCESS_WITH_INFO
16723  s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
16724 #endif
16725  }
16726  }
16727  }
16728  if (SQL_SUCCEEDED(ret)) {
16729  ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16730  }
16731  return ret;
16732 }
16733 
16742 static SQLRETURN
16743 drvfetchscroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLINTEGER offset)
16744 {
16745  STMT *s;
16746  int i, withinfo = 0;
16747  SQLRETURN ret;
16748 
16749  if (stmt == SQL_NULL_HSTMT) {
16750  return SQL_INVALID_HANDLE;
16751  }
16752  s = (STMT *) stmt;
16753  for (i = 0; i < s->rowset_size; i++) {
16754  s->row_status0[i] = SQL_ROW_NOROW;
16755  }
16756  if (s->row_status) {
16757  memcpy(s->row_status, s->row_status0,
16758  sizeof (SQLUSMALLINT) * s->rowset_size);
16759  }
16760  s->row_count0 = 0;
16761  if (s->row_count) {
16762  *s->row_count = s->row_count0;
16763  }
16764  if (!s->bindcols) {
16765  for (i = 0; i < s->rowset_size; i++) {
16766  s->row_status0[i] = SQL_ROW_ERROR;
16767  }
16768  ret = SQL_ERROR;
16769  i = 0;
16770  goto done2;
16771  }
16772  if (s->isselect != 1 && s->isselect != -1) {
16773  if (s->isselect != 0 || s->ncols <= 0) {
16774  setstat(s, -1, "no result set available", "24000");
16775  ret = SQL_ERROR;
16776  i = s->nrows;
16777  goto done2;
16778  } else {
16779  /* INSERT/UPDATE/DELETE ... RETURNING ... has columns */
16780  }
16781  }
16782  if (s->curtype == SQL_CURSOR_FORWARD_ONLY && orient != SQL_FETCH_NEXT) {
16783  setstat(s, -1, "wrong fetch direction", "01000");
16784  ret = SQL_ERROR;
16785  i = 0;
16786  goto done2;
16787  }
16788  ret = SQL_SUCCESS;
16789  i = 0;
16790  if (((DBC *) (s->dbc))->cur_s3stmt == s && s->s3stmt) {
16791  s->rowp = s->rowprs = 0;
16792  for (; i < s->rowset_size; i++) {
16793  if (s->max_rows && s->s3stmt_rownum + 1 >= s->max_rows) {
16794  ret = (i == 0) ? SQL_NO_DATA : SQL_SUCCESS;
16795  break;
16796  }
16797  ret = s3stmt_step(s);
16798  if (ret != SQL_SUCCESS) {
16799  s->row_status0[i] = SQL_ROW_ERROR;
16800  break;
16801  }
16802  if (s->nrows < 1) {
16803  break;
16804  }
16805  ret = dofetchbind(s, i);
16806  if (!SQL_SUCCEEDED(ret)) {
16807  break;
16808  } else if (ret == SQL_SUCCESS_WITH_INFO) {
16809  withinfo = 1;
16810  }
16811  }
16812  } else if (s->rows) {
16813  switch (orient) {
16814  case SQL_FETCH_NEXT:
16815  if (s->nrows < 1) {
16816  return SQL_NO_DATA;
16817  }
16818  if (s->rowp < 0) {
16819  s->rowp = -1;
16820  }
16821  if (s->rowp >= s->nrows) {
16822  s->rowp = s->rowprs = s->nrows;
16823  return SQL_NO_DATA;
16824  }
16825  break;
16826  case SQL_FETCH_PRIOR:
16827  if (s->nrows < 1 || s->rowp <= 0) {
16828  s->rowp = s->rowprs = -1;
16829  return SQL_NO_DATA;
16830  }
16831  s->rowp -= s->rowset_size + 1;
16832  if (s->rowp < -1) {
16833  s->rowp = s->rowprs = -1;
16834  return SQL_NO_DATA;
16835  }
16836  break;
16837  case SQL_FETCH_FIRST:
16838  if (s->nrows < 1) {
16839  return SQL_NO_DATA;
16840  }
16841  s->rowp = -1;
16842  break;
16843  case SQL_FETCH_LAST:
16844  if (s->nrows < 1) {
16845  return SQL_NO_DATA;
16846  }
16847  s->rowp = s->nrows - s->rowset_size;
16848  if (--s->rowp < -1) {
16849  s->rowp = -1;
16850  }
16851  break;
16852  case SQL_FETCH_ABSOLUTE:
16853  if (offset == 0) {
16854  s->rowp = s->rowprs = -1;
16855  return SQL_NO_DATA;
16856  } else if (offset < 0) {
16857  if (0 - offset <= s->nrows) {
16858  s->rowp = s->nrows + offset - 1;
16859  break;
16860  }
16861  s->rowp = s->rowprs = -1;
16862  return SQL_NO_DATA;
16863  } else if (offset > s->nrows) {
16864  s->rowp = s->rowprs = s->nrows;
16865  return SQL_NO_DATA;
16866  }
16867  s->rowp = offset - 1 - 1;
16868  break;
16869  case SQL_FETCH_RELATIVE:
16870  if (offset >= 0) {
16871  s->rowp += offset * s->rowset_size - 1;
16872  if (s->rowp >= s->nrows) {
16873  s->rowp = s->rowprs = s->nrows;
16874  return SQL_NO_DATA;
16875  }
16876  } else {
16877  s->rowp += offset * s->rowset_size - 1;
16878  if (s->rowp < -1) {
16879  s->rowp = s->rowprs = -1;
16880  return SQL_NO_DATA;
16881  }
16882  }
16883  break;
16884  case SQL_FETCH_BOOKMARK:
16885  if (s->bkmrk == SQL_UB_ON && !s->bkmrkptr) {
16886  if (offset < 0 || offset >= s->nrows) {
16887  return SQL_NO_DATA;
16888  }
16889  s->rowp = offset - 1;
16890  break;
16891  }
16892  if (s->bkmrk != SQL_UB_OFF && s->bkmrkptr) {
16893  int rowp;
16894 
16895  if (s->bkmrk == SQL_UB_VARIABLE) {
16896  if (s->has_rowid >= 0) {
16897  sqlite_int64 bkmrk, rowid;
16898 
16899  bkmrk = *(sqlite_int64 *) s->bkmrkptr;
16900  for (rowp = 0; rowp < s->nrows; rowp++) {
16901  char **data, *endp = 0;
16902 
16903  data = s->rows + s->ncols + (rowp * s->ncols)
16904  + s->has_rowid;
16905 #ifdef __osf__
16906  rowid = strtol(*data, &endp, 0);
16907 #else
16908  rowid = strtoll(*data, &endp, 0);
16909 #endif
16910  if (rowid == bkmrk) {
16911  break;
16912  }
16913  }
16914  } else {
16915  rowp = *(sqlite_int64 *) s->bkmrkptr;
16916  }
16917  } else {
16918  rowp = *(int *) s->bkmrkptr;
16919  }
16920  if (rowp + offset < 0 || rowp + offset >= s->nrows) {
16921  return SQL_NO_DATA;
16922  }
16923  s->rowp = rowp + offset - 1;
16924  break;
16925  }
16926  /* fall through */
16927  default:
16928  s->row_status0[0] = SQL_ROW_ERROR;
16929  ret = SQL_ERROR;
16930  goto done;
16931  }
16932  s->rowprs = s->rowp + 1;
16933  for (; i < s->rowset_size; i++) {
16934  ++s->rowp;
16935  if (s->rowp < 0 || s->rowp >= s->nrows) {
16936  break;
16937  }
16938  ret = dofetchbind(s, i);
16939  if (!SQL_SUCCEEDED(ret)) {
16940  break;
16941  } else if (ret == SQL_SUCCESS_WITH_INFO) {
16942  withinfo = 1;
16943  }
16944  }
16945  }
16946 done:
16947  if (i == 0) {
16948  if (SQL_SUCCEEDED(ret)) {
16949  return SQL_NO_DATA;
16950  }
16951  return ret;
16952  }
16953  if (SQL_SUCCEEDED(ret)) {
16954  ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16955  }
16956 done2:
16957  if (s->row_status) {
16958  memcpy(s->row_status, s->row_status0,
16959  sizeof (SQLUSMALLINT) * s->rowset_size);
16960  }
16961  s->row_count0 = i;
16962  if (s->row_count) {
16963  *s->row_count = s->row_count0;
16964  }
16965  return ret;
16966 }
16967 
16974 SQLRETURN SQL_API
16975 SQLFetch(SQLHSTMT stmt)
16976 {
16977  SQLRETURN ret;
16978 
16979  HSTMT_LOCK(stmt);
16980  ret = drvfetchscroll(stmt, SQL_FETCH_NEXT, 0);
16981  HSTMT_UNLOCK(stmt);
16982  return ret;
16983 }
16984 
16993 SQLRETURN SQL_API
16994 SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLLEN offset)
16995 {
16996  SQLRETURN ret;
16997 
16998  HSTMT_LOCK(stmt);
16999  ret = drvfetchscroll(stmt, orient, offset);
17000  HSTMT_UNLOCK(stmt);
17001  return ret;
17002 }
17003 
17014 SQLRETURN SQL_API
17015 SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT orient, SQLROWOFFSET offset,
17016  SQLROWSETSIZE *rowcount, SQLUSMALLINT *rowstatus)
17017 {
17018  STMT *s;
17019  SQLRETURN ret;
17020  SQLUSMALLINT *rst;
17021  SQLINTEGER *bkmrkptr;
17022 
17023  HSTMT_LOCK(stmt);
17024  if (stmt == SQL_NULL_HSTMT) {
17025  return SQL_INVALID_HANDLE;
17026  }
17027  s = (STMT *) stmt;
17028  /* temporarily turn off SQL_ATTR_ROW_STATUS_PTR */
17029  rst = s->row_status;
17030  s->row_status = 0;
17031  bkmrkptr = s->bkmrkptr;
17032  s->bkmrkptr = 0;
17033  ret = drvfetchscroll(stmt, orient, offset);
17034  s->row_status = rst;
17035  s->bkmrkptr = bkmrkptr;
17036  if (rowstatus) {
17037  memcpy(rowstatus, s->row_status0,
17038  sizeof (SQLUSMALLINT) * s->rowset_size);
17039  }
17040  if (rowcount) {
17041  *rowcount = s->row_count0;
17042  }
17043  HSTMT_UNLOCK(stmt);
17044  return ret;
17045 }
17046 
17054 SQLRETURN SQL_API
17055 SQLRowCount(SQLHSTMT stmt, SQLLEN *nrows)
17056 {
17057  STMT *s;
17058 
17059  HSTMT_LOCK(stmt);
17060  if (stmt == SQL_NULL_HSTMT) {
17061  return SQL_INVALID_HANDLE;
17062  }
17063  s = (STMT *) stmt;
17064  if (nrows) {
17065  *nrows = s->isselect ? 0 : s->nrows;
17066  }
17067  HSTMT_UNLOCK(stmt);
17068  return SQL_SUCCESS;
17069 }
17070 
17078 SQLRETURN SQL_API
17079 SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *ncols)
17080 {
17081  STMT *s;
17082 
17083  HSTMT_LOCK(stmt);
17084  if (stmt == SQL_NULL_HSTMT) {
17085  return SQL_INVALID_HANDLE;
17086  }
17087  s = (STMT *) stmt;
17088  if (ncols) {
17089  *ncols = s->ncols;
17090  }
17091  HSTMT_UNLOCK(stmt);
17092  return SQL_SUCCESS;
17093 }
17094 
17109 static SQLRETURN
17110 drvdescribecol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
17111  SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
17112  SQLSMALLINT *type, SQLULEN *size,
17113  SQLSMALLINT *digits, SQLSMALLINT *nullable)
17114 {
17115  STMT *s;
17116  COL *c;
17117  int didname = 0;
17118 
17119  if (stmt == SQL_NULL_HSTMT) {
17120  return SQL_INVALID_HANDLE;
17121  }
17122  s = (STMT *) stmt;
17123  if (!s->cols) {
17124  setstat(s, -1, "no columns", (*s->ov3) ? "07009" : "S1002");
17125  return SQL_ERROR;
17126  }
17127  if (col < 1 || col > s->ncols) {
17128  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
17129  return SQL_ERROR;
17130  }
17131  c = s->cols + col - 1;
17132  if (name && nameMax > 0) {
17133  strncpy((char *) name, c->column, nameMax);
17134  name[nameMax - 1] = '\0';
17135  didname = 1;
17136  }
17137  if (nameLen) {
17138  if (didname) {
17139  *nameLen = strlen((char *) name);
17140  } else {
17141  *nameLen = strlen(c->column);
17142  }
17143  }
17144  if (type) {
17145  *type = c->type;
17146 #ifdef WINTERFACE
17147  if (s->nowchar[0] || s->nowchar[1]) {
17148  switch (c->type) {
17149  case SQL_WCHAR:
17150  *type = SQL_CHAR;
17151  break;
17152  case SQL_WVARCHAR:
17153  *type = SQL_VARCHAR;
17154  break;
17155 #ifdef SQL_LONGVARCHAR
17156  case SQL_WLONGVARCHAR:
17157  *type = SQL_LONGVARCHAR;
17158  break;
17159 #endif
17160  }
17161  }
17162 #endif
17163  }
17164  if (size) {
17165  *size = c->size;
17166  }
17167  if (digits) {
17168  *digits = 0;
17169  }
17170  if (nullable) {
17171  *nullable = 1;
17172  }
17173  return SQL_SUCCESS;
17174 }
17175 
17176 #ifndef WINTERFACE
17177 
17191 SQLRETURN SQL_API
17192 SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
17193  SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
17194  SQLSMALLINT *type, SQLULEN *size,
17195  SQLSMALLINT *digits, SQLSMALLINT *nullable)
17196 {
17197 #if defined(_WIN32) || defined(_WIN64)
17198  SQLSMALLINT len = 0;
17199 #endif
17200  SQLRETURN ret;
17201 
17202  HSTMT_LOCK(stmt);
17203 #if defined(_WIN32) || defined(_WIN64)
17204  if (!((STMT *) stmt)->oemcp[0]) {
17205  ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
17206  type, size, digits, nullable);
17207  goto done;
17208  }
17209  ret = drvdescribecol(stmt, col, name, nameMax,
17210  &len, type, size, digits, nullable);
17211  if (ret == SQL_SUCCESS) {
17212  if (name) {
17213  if (len > 0) {
17214  SQLCHAR *n = NULL;
17215 
17216  n = (SQLCHAR *) utf_to_wmb((char *) name, len);
17217  if (n) {
17218  strncpy((char *) name, (char *) n, nameMax);
17219  n[len] = 0;
17220  len = min(nameMax, strlen((char *) n));
17221  uc_free(n);
17222  } else {
17223  len = 0;
17224  }
17225  }
17226  if (len <= 0) {
17227  len = 0;
17228  if (nameMax > 0) {
17229  name[0] = 0;
17230  }
17231  }
17232  } else {
17233  STMT *s = (STMT *) stmt;
17234  COL *c = s->cols + col - 1;
17235 
17236  len = 0;
17237  if (c->column) {
17238  len = strlen(c->column);
17239  }
17240  }
17241  if (nameLen) {
17242  *nameLen = len;
17243  }
17244  }
17245 done:
17246  ;
17247 #else
17248  ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
17249  type, size, digits, nullable);
17250 #endif
17251  HSTMT_UNLOCK(stmt);
17252  return ret;
17253 }
17254 #endif
17255 
17256 #ifdef WINTERFACE
17257 
17271 SQLRETURN SQL_API
17272 SQLDescribeColW(SQLHSTMT stmt, SQLUSMALLINT col, SQLWCHAR *name,
17273  SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
17274  SQLSMALLINT *type, SQLULEN *size,
17275  SQLSMALLINT *digits, SQLSMALLINT *nullable)
17276 {
17277  SQLRETURN ret;
17278  SQLSMALLINT len = 0;
17279 
17280  HSTMT_LOCK(stmt);
17281  ret = drvdescribecol(stmt, col, (SQLCHAR *) name,
17282  (SQLSMALLINT) (nameMax * sizeof (SQLWCHAR)),
17283  &len, type, size, digits, nullable);
17284  if (ret == SQL_SUCCESS) {
17285  if (name) {
17286  if (len > 0) {
17287  SQLWCHAR *n = NULL;
17288 
17289  n = uc_from_utf((SQLCHAR *) name, len);
17290  if (n) {
17291  uc_strncpy(name, n, nameMax);
17292  n[len] = 0;
17293  len = min(nameMax, uc_strlen(n));
17294  uc_free(n);
17295  } else {
17296  len = 0;
17297  }
17298  }
17299  if (len <= 0) {
17300  len = 0;
17301  if (nameMax > 0) {
17302  name[0] = 0;
17303  }
17304  }
17305  } else {
17306  STMT *s = (STMT *) stmt;
17307  COL *c = s->cols + col - 1;
17308 
17309  len = 0;
17310  if (c->column) {
17311  len = strlen(c->column);
17312  }
17313  }
17314  if (nameLen) {
17315  *nameLen = len;
17316  }
17317  }
17318  HSTMT_UNLOCK(stmt);
17319  return ret;
17320 }
17321 #endif
17322 
17335 static SQLRETURN
17336 drvcolattributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17337  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17338  SQLLEN *val2)
17339 {
17340  STMT *s;
17341  COL *c;
17342  SQLSMALLINT dummy;
17343  char *valc = (char *) val;
17344 
17345  if (stmt == SQL_NULL_HSTMT) {
17346  return SQL_INVALID_HANDLE;
17347  }
17348  s = (STMT *) stmt;
17349  if (!s->cols) {
17350  return SQL_ERROR;
17351  }
17352  if (!valLen) {
17353  valLen = &dummy;
17354  }
17355  if (id == SQL_COLUMN_COUNT) {
17356  if (val2) {
17357  *val2 = s->ncols;
17358  }
17359  *valLen = sizeof (int);
17360  return SQL_SUCCESS;
17361  }
17362  if (id == SQL_COLUMN_TYPE && col == 0) {
17363  if (val2) {
17364  *val2 = SQL_INTEGER;
17365  }
17366  *valLen = sizeof (int);
17367  return SQL_SUCCESS;
17368  }
17369 #ifdef SQL_DESC_OCTET_LENGTH
17370  if (id == SQL_DESC_OCTET_LENGTH && col == 0) {
17371  if (val2) {
17372  *val2 = 4;
17373  }
17374  *valLen = sizeof (int);
17375  return SQL_SUCCESS;
17376  }
17377 #endif
17378  if (col < 1 || col > s->ncols) {
17379  setstat(s, -1, "invalid column", (*s->ov3) ? "07009": "S1002");
17380  return SQL_ERROR;
17381  }
17382  c = s->cols + col - 1;
17383 
17384  switch (id) {
17385  case SQL_COLUMN_LABEL:
17386  if (c->label) {
17387  if (valc && valMax > 0) {
17388  strncpy(valc, c->label, valMax);
17389  valc[valMax - 1] = '\0';
17390  }
17391  *valLen = strlen(c->label);
17392  goto checkLen;
17393  }
17394  /* fall through */
17395  case SQL_COLUMN_NAME:
17396  case SQL_DESC_NAME:
17397  if (valc && valMax > 0) {
17398  strncpy(valc, c->column, valMax);
17399  valc[valMax - 1] = '\0';
17400  }
17401  *valLen = strlen(c->column);
17402 checkLen:
17403  if (*valLen >= valMax) {
17404  setstat(s, -1, "data right truncated", "01004");
17405  return SQL_SUCCESS_WITH_INFO;
17406  }
17407  return SQL_SUCCESS;
17408 #ifdef SQL_DESC_BASE_COLUMN_NAME
17409  case SQL_DESC_BASE_COLUMN_NAME:
17410  if (strchr(c->column, '(') || strchr(c->column, ')')) {
17411  if (valc && valMax > 0) {
17412  valc[0] = '\0';
17413  }
17414  *valLen = 0;
17415  } else if (valc && valMax > 0) {
17416  strncpy(valc, c->column, valMax);
17417  valc[valMax - 1] = '\0';
17418  *valLen = strlen(c->column);
17419  }
17420  goto checkLen;
17421 #endif
17422  case SQL_COLUMN_TYPE:
17423  case SQL_DESC_TYPE:
17424 #ifdef WINTERFACE
17425  {
17426  int type = c->type;
17427 
17428  if (s->nowchar[0] || s->nowchar[1]) {
17429  switch (type) {
17430  case SQL_WCHAR:
17431  type = SQL_CHAR;
17432  break;
17433  case SQL_WVARCHAR:
17434  type = SQL_VARCHAR;
17435  break;
17436 #ifdef SQL_LONGVARCHAR
17437  case SQL_WLONGVARCHAR:
17438  type = SQL_LONGVARCHAR;
17439  break;
17440  }
17441  }
17442  if (val2) {
17443  *val2 = type;
17444  }
17445 #endif
17446  }
17447 #else
17448  if (val2) {
17449  *val2 = c->type;
17450  }
17451 #endif
17452  *valLen = sizeof (int);
17453  return SQL_SUCCESS;
17454  case SQL_COLUMN_DISPLAY_SIZE:
17455  if (val2) {
17456  *val2 = c->size;
17457  }
17458  *valLen = sizeof (int);
17459  return SQL_SUCCESS;
17460  case SQL_COLUMN_UNSIGNED:
17461  if (val2) {
17462  *val2 = c->nosign ? SQL_TRUE : SQL_FALSE;
17463  }
17464  *valLen = sizeof (int);
17465  return SQL_SUCCESS;
17466  case SQL_COLUMN_SCALE:
17467  case SQL_DESC_SCALE:
17468  if (val2) {
17469  *val2 = c->scale;
17470  }
17471  *valLen = sizeof (int);
17472  return SQL_SUCCESS;
17473  case SQL_COLUMN_PRECISION:
17474  case SQL_DESC_PRECISION:
17475  if (val2) {
17476  switch (c->type) {
17477  case SQL_SMALLINT:
17478  *val2 = 5;
17479  break;
17480  case SQL_INTEGER:
17481  *val2 = 10;
17482  break;
17483  case SQL_FLOAT:
17484  case SQL_REAL:
17485  case SQL_DOUBLE:
17486  *val2 = 15;
17487  break;
17488  case SQL_DATE:
17489  *val2 = 0;
17490  break;
17491  case SQL_TIME:
17492  *val2 = 0;
17493  break;
17494 #ifdef SQL_TYPE_TIMESTAMP
17495  case SQL_TYPE_TIMESTAMP:
17496 #endif
17497  case SQL_TIMESTAMP:
17498  *val2 = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
17499  break;
17500  default:
17501  *val2 = c->prec;
17502  break;
17503  }
17504  }
17505  *valLen = sizeof (int);
17506  return SQL_SUCCESS;
17507  case SQL_COLUMN_MONEY:
17508  if (val2) {
17509  *val2 = SQL_FALSE;
17510  }
17511  *valLen = sizeof (int);
17512  return SQL_SUCCESS;
17513  case SQL_COLUMN_AUTO_INCREMENT:
17514  if (val2) {
17515  *val2 = c->autoinc;
17516  }
17517  *valLen = sizeof (int);
17518  return SQL_SUCCESS;
17519  case SQL_COLUMN_LENGTH:
17520  case SQL_DESC_LENGTH:
17521  if (val2) {
17522  *val2 = c->size;
17523  }
17524  *valLen = sizeof (int);
17525  return SQL_SUCCESS;
17526  case SQL_COLUMN_NULLABLE:
17527  case SQL_DESC_NULLABLE:
17528  if (val2) {
17529  *val2 = c->notnull;
17530  }
17531  *valLen = sizeof (int);
17532  return SQL_SUCCESS;
17533  case SQL_COLUMN_SEARCHABLE:
17534  if (val2) {
17535  *val2 = SQL_SEARCHABLE;
17536  }
17537  *valLen = sizeof (int);
17538  return SQL_SUCCESS;
17539  case SQL_COLUMN_CASE_SENSITIVE:
17540  if (val2) {
17541  *val2 = SQL_TRUE;
17542  }
17543  *valLen = sizeof (int);
17544  return SQL_SUCCESS;
17545  case SQL_COLUMN_UPDATABLE:
17546  if (val2) {
17547  *val2 = SQL_TRUE;
17548  }
17549  *valLen = sizeof (int);
17550  return SQL_SUCCESS;
17551  case SQL_DESC_COUNT:
17552  if (val2) {
17553  *val2 = s->ncols;
17554  }
17555  *valLen = sizeof (int);
17556  return SQL_SUCCESS;
17557  case SQL_COLUMN_TYPE_NAME: {
17558  char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17559 
17560 #ifdef WINTERFACE
17561  if (c->type == SQL_WCHAR ||
17562  c->type == SQL_WVARCHAR ||
17563  c->type == SQL_WLONGVARCHAR) {
17564  if (!(s->nowchar[0] || s->nowchar[1])) {
17565  if (strcasecmp(tn, "varchar") == 0) {
17566  tn = "wvarchar";
17567  }
17568  }
17569  }
17570 #endif
17571  if (valc && valMax > 0) {
17572  strncpy(valc, tn, valMax);
17573  valc[valMax - 1] = '\0';
17574  p = strchr(valc, '(');
17575  if (p) {
17576  *p = '\0';
17577  while (p > valc && ISSPACE(p[-1])) {
17578  --p;
17579  *p = '\0';
17580  }
17581  }
17582  *valLen = strlen(valc);
17583  } else {
17584  *valLen = strlen(tn);
17585  p = strchr(tn, '(');
17586  if (p) {
17587  *valLen = p - tn;
17588  while (p > tn && ISSPACE(p[-1])) {
17589  --p;
17590  *valLen -= 1;
17591  }
17592  }
17593  }
17594  goto checkLen;
17595  }
17596  case SQL_COLUMN_OWNER_NAME:
17597  case SQL_COLUMN_QUALIFIER_NAME: {
17598  char *z = "";
17599 
17600  if (valc && valMax > 0) {
17601  strncpy(valc, z, valMax);
17602  valc[valMax - 1] = '\0';
17603  }
17604  *valLen = strlen(z);
17605  goto checkLen;
17606  }
17607  case SQL_COLUMN_TABLE_NAME:
17608 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17609  case SQL_DESC_TABLE_NAME:
17610 #endif
17611 #ifdef SQL_DESC_BASE_TABLE_NAME
17612  case SQL_DESC_BASE_TABLE_NAME:
17613 #endif
17614  if (valc && valMax > 0) {
17615  strncpy(valc, c->table, valMax);
17616  valc[valMax - 1] = '\0';
17617  }
17618  *valLen = strlen(c->table);
17619  goto checkLen;
17620 #ifdef SQL_DESC_NUM_PREC_RADIX
17621  case SQL_DESC_NUM_PREC_RADIX:
17622  if (val2) {
17623  switch (c->type) {
17624 #ifdef WINTERFACE
17625  case SQL_WCHAR:
17626  case SQL_WVARCHAR:
17627 #ifdef SQL_LONGVARCHAR
17628  case SQL_WLONGVARCHAR:
17629 #endif
17630 #endif
17631  case SQL_CHAR:
17632  case SQL_VARCHAR:
17633 #ifdef SQL_LONGVARCHAR
17634  case SQL_LONGVARCHAR:
17635 #endif
17636  case SQL_BINARY:
17637  case SQL_VARBINARY:
17638  case SQL_LONGVARBINARY:
17639  *val2 = 0;
17640  break;
17641  default:
17642  *val2 = 2;
17643  }
17644  }
17645  *valLen = sizeof (int);
17646  return SQL_SUCCESS;
17647 #endif
17648  }
17649  setstat(s, -1, "unsupported column attributes %d", "HY091", id);
17650  return SQL_ERROR;
17651 }
17652 
17653 #ifndef WINTERFACE
17654 
17666 SQLRETURN SQL_API
17667 SQLColAttributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17668  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17669  SQLLEN *val2)
17670 {
17671 #if defined(_WIN32) || defined(_WIN64)
17672  SQLSMALLINT len = 0;
17673 #endif
17674  SQLRETURN ret;
17675 
17676  HSTMT_LOCK(stmt);
17677 #if defined(_WIN32) || defined(_WIN64)
17678  if (!((STMT *) stmt)->oemcp[0]) {
17679  ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17680  goto done;
17681  }
17682  ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17683  if (SQL_SUCCEEDED(ret)) {
17684  char *v = NULL;
17685 
17686  switch (id) {
17687  case SQL_COLUMN_LABEL:
17688  case SQL_COLUMN_NAME:
17689  case SQL_DESC_NAME:
17690  case SQL_COLUMN_TYPE_NAME:
17691  case SQL_COLUMN_OWNER_NAME:
17692  case SQL_COLUMN_QUALIFIER_NAME:
17693  case SQL_COLUMN_TABLE_NAME:
17694 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17695  case SQL_DESC_TABLE_NAME:
17696 #endif
17697 #ifdef SQL_DESC_BASE_COLUMN_NAME
17698  case SQL_DESC_BASE_COLUMN_NAME:
17699 #endif
17700 #ifdef SQL_DESC_BASE_TABLE_NAME
17701  case SQL_DESC_BASE_TABLE_NAME:
17702 #endif
17703  if (val && valMax > 0) {
17704  int vmax = valMax;
17705 
17706  v = utf_to_wmb((char *) val, SQL_NTS);
17707  if (v) {
17708  strncpy(val, v, vmax);
17709  len = min(vmax, strlen(v));
17710  uc_free(v);
17711  }
17712  if (vmax > 0) {
17713  v = (char *) val;
17714  v[vmax - 1] = '\0';
17715  }
17716  }
17717  if (len <= 0) {
17718  len = 0;
17719  }
17720  break;
17721  }
17722  if (valLen) {
17723  *valLen = len;
17724  }
17725  }
17726 done:
17727  ;
17728 #else
17729  ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17730 #endif
17731  HSTMT_UNLOCK(stmt);
17732  return ret;
17733 }
17734 #endif
17735 
17736 #ifdef WINTERFACE
17737 
17749 SQLRETURN SQL_API
17750 SQLColAttributesW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17751  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17752  SQLLEN *val2)
17753 {
17754  SQLRETURN ret;
17755  SQLSMALLINT len = 0;
17756 
17757  HSTMT_LOCK(stmt);
17758  ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17759  if (SQL_SUCCEEDED(ret)) {
17760  SQLWCHAR *v = NULL;
17761 
17762  switch (id) {
17763  case SQL_COLUMN_LABEL:
17764  case SQL_COLUMN_NAME:
17765  case SQL_DESC_NAME:
17766  case SQL_COLUMN_TYPE_NAME:
17767  case SQL_COLUMN_OWNER_NAME:
17768  case SQL_COLUMN_QUALIFIER_NAME:
17769  case SQL_COLUMN_TABLE_NAME:
17770 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17771  case SQL_DESC_TABLE_NAME:
17772 #endif
17773 #ifdef SQL_DESC_BASE_COLUMN_NAME
17774  case SQL_DESC_BASE_COLUMN_NAME:
17775 #endif
17776 #ifdef SQL_DESC_BASE_TABLE_NAME
17777  case SQL_DESC_BASE_TABLE_NAME:
17778 #endif
17779  if (val && valMax > 0) {
17780  int vmax = valMax / sizeof (SQLWCHAR);
17781 
17782  v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
17783  if (v) {
17784  uc_strncpy(val, v, vmax);
17785  len = min(vmax, uc_strlen(v));
17786  uc_free(v);
17787  len *= sizeof (SQLWCHAR);
17788  }
17789  if (vmax > 0) {
17790  v = (SQLWCHAR *) val;
17791  v[vmax - 1] = '\0';
17792  }
17793  }
17794  if (len <= 0) {
17795  len = 0;
17796  }
17797  break;
17798  }
17799  if (valLen) {
17800  *valLen = len;
17801  }
17802  }
17803  HSTMT_UNLOCK(stmt);
17804  return ret;
17805 }
17806 #endif
17807 
17820 static SQLRETURN
17821 drvcolattribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17822  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17823  SQLPOINTER val2)
17824 {
17825  STMT *s;
17826  COL *c;
17827  int v = 0;
17828  char *valc = (char *) val;
17829  SQLSMALLINT dummy;
17830 
17831  if (stmt == SQL_NULL_HSTMT) {
17832  return SQL_INVALID_HANDLE;
17833  }
17834  s = (STMT *) stmt;
17835  if (!s->cols) {
17836  return SQL_ERROR;
17837  }
17838  if (col < 1 || col > s->ncols) {
17839  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
17840  return SQL_ERROR;
17841  }
17842  if (!valLen) {
17843  valLen = &dummy;
17844  }
17845  c = s->cols + col - 1;
17846  switch (id) {
17847  case SQL_DESC_COUNT:
17848  v = s->ncols;
17849  break;
17850  case SQL_DESC_CATALOG_NAME:
17851  if (valc && valMax > 0) {
17852  strncpy(valc, c->db, valMax);
17853  valc[valMax - 1] = '\0';
17854  }
17855  *valLen = strlen(c->db);
17856 checkLen:
17857  if (*valLen >= valMax) {
17858  setstat(s, -1, "data right truncated", "01004");
17859  return SQL_SUCCESS_WITH_INFO;
17860  }
17861  break;
17862  case SQL_COLUMN_LENGTH:
17863  case SQL_DESC_LENGTH:
17864  v = c->size;
17865  break;
17866  case SQL_COLUMN_LABEL:
17867  if (c->label) {
17868  if (valc && valMax > 0) {
17869  strncpy(valc, c->label, valMax);
17870  valc[valMax - 1] = '\0';
17871  }
17872  *valLen = strlen(c->label);
17873  goto checkLen;
17874  }
17875  /* fall through */
17876  case SQL_COLUMN_NAME:
17877  case SQL_DESC_NAME:
17878  if (valc && valMax > 0) {
17879  strncpy(valc, c->column, valMax);
17880  valc[valMax - 1] = '\0';
17881  }
17882  *valLen = strlen(c->column);
17883  goto checkLen;
17884  case SQL_DESC_SCHEMA_NAME: {
17885  char *z = "";
17886 
17887  if (valc && valMax > 0) {
17888  strncpy(valc, z, valMax);
17889  valc[valMax - 1] = '\0';
17890  }
17891  *valLen = strlen(z);
17892  goto checkLen;
17893  }
17894 #ifdef SQL_DESC_BASE_COLUMN_NAME
17895  case SQL_DESC_BASE_COLUMN_NAME:
17896  if (strchr(c->column, '(') || strchr(c->column, ')')) {
17897  valc[0] = '\0';
17898  *valLen = 0;
17899  } else if (valc && valMax > 0) {
17900  strncpy(valc, c->column, valMax);
17901  valc[valMax - 1] = '\0';
17902  *valLen = strlen(c->column);
17903  }
17904  goto checkLen;
17905 #endif
17906  case SQL_DESC_TYPE_NAME: {
17907  char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17908 
17909 #ifdef WINTERFACE
17910  if (c->type == SQL_WCHAR ||
17911  c->type == SQL_WVARCHAR ||
17912  c->type == SQL_WLONGVARCHAR) {
17913  if (!(s->nowchar[0] || s->nowchar[1])) {
17914  if (strcasecmp(tn, "varchar") == 0) {
17915  tn = "wvarchar";
17916  }
17917  }
17918  }
17919 #endif
17920  if (valc && valMax > 0) {
17921  strncpy(valc, tn, valMax);
17922  valc[valMax - 1] = '\0';
17923  p = strchr(valc, '(');
17924  if (p) {
17925  *p = '\0';
17926  while (p > valc && ISSPACE(p[-1])) {
17927  --p;
17928  *p = '\0';
17929  }
17930  }
17931  *valLen = strlen(valc);
17932  } else {
17933  *valLen = strlen(tn);
17934  p = strchr(tn, '(');
17935  if (p) {
17936  *valLen = p - tn;
17937  while (p > tn && ISSPACE(p[-1])) {
17938  --p;
17939  *valLen -= 1;
17940  }
17941  }
17942  }
17943  goto checkLen;
17944  }
17945  case SQL_DESC_OCTET_LENGTH:
17946  v = c->size;
17947 #ifdef WINTERFACE
17948  if (c->type == SQL_WCHAR ||
17949  c->type == SQL_WVARCHAR ||
17950  c->type == SQL_WLONGVARCHAR) {
17951  if (!(s->nowchar[0] || s->nowchar[1])) {
17952  v *= sizeof (SQLWCHAR);
17953  }
17954  }
17955 #endif
17956  break;
17957 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17958  case SQL_COLUMN_TABLE_NAME:
17959 #endif
17960 #ifdef SQL_DESC_BASE_TABLE_NAME
17961  case SQL_DESC_BASE_TABLE_NAME:
17962 #endif
17963  case SQL_DESC_TABLE_NAME:
17964  if (valc && valMax > 0) {
17965  strncpy(valc, c->table, valMax);
17966  valc[valMax - 1] = '\0';
17967  }
17968  *valLen = strlen(c->table);
17969  goto checkLen;
17970  case SQL_DESC_TYPE:
17971  v = c->type;
17972 #ifdef WINTERFACE
17973  if (s->nowchar[0] || s->nowchar[1]) {
17974  switch (v) {
17975  case SQL_WCHAR:
17976  v = SQL_CHAR;
17977  break;
17978  case SQL_WVARCHAR:
17979  v = SQL_VARCHAR;
17980  break;
17981 #ifdef SQL_LONGVARCHAR
17982  case SQL_WLONGVARCHAR:
17983  v = SQL_LONGVARCHAR;
17984  break;
17985 #endif
17986  }
17987  }
17988 #endif
17989  break;
17990  case SQL_DESC_CONCISE_TYPE:
17991  switch (c->type) {
17992  case SQL_INTEGER:
17993  v = SQL_C_LONG;
17994  break;
17995  case SQL_TINYINT:
17996  v = SQL_C_TINYINT;
17997  break;
17998  case SQL_SMALLINT:
17999  v = SQL_C_SHORT;
18000  break;
18001  case SQL_FLOAT:
18002  v = SQL_C_FLOAT;
18003  break;
18004  case SQL_DOUBLE:
18005  v = SQL_C_DOUBLE;
18006  break;
18007  case SQL_TIMESTAMP:
18008  v = SQL_C_TIMESTAMP;
18009  break;
18010  case SQL_TIME:
18011  v = SQL_C_TIME;
18012  break;
18013  case SQL_DATE:
18014  v = SQL_C_DATE;
18015  break;
18016 #ifdef SQL_C_TYPE_TIMESTAMP
18017  case SQL_TYPE_TIMESTAMP:
18018  v = SQL_C_TYPE_TIMESTAMP;
18019  break;
18020 #endif
18021 #ifdef SQL_C_TYPE_TIME
18022  case SQL_TYPE_TIME:
18023  v = SQL_C_TYPE_TIME;
18024  break;
18025 #endif
18026 #ifdef SQL_C_TYPE_DATE
18027  case SQL_TYPE_DATE:
18028  v = SQL_C_TYPE_DATE;
18029  break;
18030 #endif
18031 #ifdef SQL_BIT
18032  case SQL_BIT:
18033  v = SQL_C_BIT;
18034  break;
18035 #endif
18036 #ifdef SQL_BIGINT
18037  case SQL_BIGINT:
18038  v = SQL_C_SBIGINT;
18039  break;
18040 #endif
18041  default:
18042 #ifdef WINTERFACE
18043  v = (s->nowchar[0] || s->nowchar[1]) ? SQL_C_CHAR : SQL_C_WCHAR;
18044 #else
18045  v = SQL_C_CHAR;
18046 #endif
18047  break;
18048  }
18049  break;
18050  case SQL_DESC_UPDATABLE:
18051  v = SQL_TRUE;
18052  break;
18053  case SQL_COLUMN_DISPLAY_SIZE:
18054  v = c->size;
18055  break;
18056  case SQL_COLUMN_UNSIGNED:
18057  v = c->nosign ? SQL_TRUE : SQL_FALSE;
18058  break;
18059  case SQL_COLUMN_SEARCHABLE:
18060  v = SQL_SEARCHABLE;
18061  break;
18062  case SQL_COLUMN_SCALE:
18063  case SQL_DESC_SCALE:
18064  v = c->scale;
18065  break;
18066  case SQL_COLUMN_PRECISION:
18067  case SQL_DESC_PRECISION:
18068  switch (c->type) {
18069  case SQL_SMALLINT:
18070  v = 5;
18071  break;
18072  case SQL_INTEGER:
18073  v = 10;
18074  break;
18075  case SQL_FLOAT:
18076  case SQL_REAL:
18077  case SQL_DOUBLE:
18078  v = 15;
18079  break;
18080  case SQL_DATE:
18081  v = 0;
18082  break;
18083  case SQL_TIME:
18084  v = 0;
18085  break;
18086 #ifdef SQL_TYPE_TIMESTAMP
18087  case SQL_TYPE_TIMESTAMP:
18088 #endif
18089  case SQL_TIMESTAMP:
18090  v = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
18091  break;
18092  default:
18093  v = c->prec;
18094  break;
18095  }
18096  break;
18097  case SQL_COLUMN_MONEY:
18098  v = SQL_FALSE;
18099  break;
18100  case SQL_COLUMN_AUTO_INCREMENT:
18101  v = c->autoinc;
18102  break;
18103  case SQL_DESC_NULLABLE:
18104  v = c->notnull;
18105  break;
18106 #ifdef SQL_DESC_NUM_PREC_RADIX
18107  case SQL_DESC_NUM_PREC_RADIX:
18108  switch (c->type) {
18109 #ifdef WINTERFACE
18110  case SQL_WCHAR:
18111  case SQL_WVARCHAR:
18112 #ifdef SQL_LONGVARCHAR
18113  case SQL_WLONGVARCHAR:
18114 #endif
18115 #endif
18116  case SQL_CHAR:
18117  case SQL_VARCHAR:
18118 #ifdef SQL_LONGVARCHAR
18119  case SQL_LONGVARCHAR:
18120 #endif
18121  case SQL_BINARY:
18122  case SQL_VARBINARY:
18123  case SQL_LONGVARBINARY:
18124  v = 0;
18125  break;
18126  default:
18127  v = 2;
18128  }
18129  break;
18130 #endif
18131  default:
18132  setstat(s, -1, "unsupported column attribute %d", "HY091", id);
18133  return SQL_ERROR;
18134  }
18135  if (val2) {
18136  *(SQLLEN *) val2 = v;
18137  }
18138  return SQL_SUCCESS;
18139 }
18140 
18141 #ifndef WINTERFACE
18142 
18154 SQLRETURN SQL_API
18155 SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
18156  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
18158 {
18159 #if defined(_WIN32) || defined(_WIN64)
18160  SQLSMALLINT len = 0;
18161 #endif
18162  SQLRETURN ret;
18163 
18164  HSTMT_LOCK(stmt);
18165 #if defined(_WIN32) || defined(_WIN64)
18166  if (!((STMT *) stmt)->oemcp[0]) {
18167  ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
18168  (SQLPOINTER) val2);
18169  goto done;
18170  }
18171  ret = drvcolattribute(stmt, col, id, val, valMax, &len,
18172  (SQLPOINTER) val2);
18173  if (SQL_SUCCEEDED(ret)) {
18174  char *v = NULL;
18175 
18176  switch (id) {
18177  case SQL_DESC_SCHEMA_NAME:
18178  case SQL_DESC_CATALOG_NAME:
18179  case SQL_COLUMN_LABEL:
18180  case SQL_DESC_NAME:
18181  case SQL_DESC_TABLE_NAME:
18182 #ifdef SQL_DESC_BASE_TABLE_NAME
18183  case SQL_DESC_BASE_TABLE_NAME:
18184 #endif
18185 #ifdef SQL_DESC_BASE_COLUMN_NAME
18186  case SQL_DESC_BASE_COLUMN_NAME:
18187 #endif
18188  case SQL_DESC_TYPE_NAME:
18189  if (val && valMax > 0) {
18190  int vmax = valMax;
18191 
18192  v = utf_to_wmb((char *) val, SQL_NTS);
18193  if (v) {
18194  strncpy(val, v, vmax);
18195  len = min(vmax, strlen(v));
18196  uc_free(v);
18197  }
18198  if (vmax > 0) {
18199  v = (char *) val;
18200  v[vmax - 1] = '\0';
18201  }
18202  }
18203  if (len <= 0) {
18204  len = 0;
18205  }
18206  break;
18207  }
18208  if (valLen) {
18209  *valLen = len;
18210  }
18211  }
18212 done:
18213  ;
18214 #else
18215  ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
18216  (SQLPOINTER) val2);
18217 #endif
18218  HSTMT_UNLOCK(stmt);
18219  return ret;
18220 }
18221 #endif
18222 
18223 #ifdef WINTERFACE
18224 
18236 SQLRETURN SQL_API
18237 SQLColAttributeW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
18238  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
18240 {
18241  SQLRETURN ret;
18242  SQLSMALLINT len = 0;
18243 
18244  HSTMT_LOCK(stmt);
18245  ret = drvcolattribute(stmt, col, id, val, valMax, &len,
18246  (SQLPOINTER) val2);
18247  if (SQL_SUCCEEDED(ret)) {
18248  SQLWCHAR *v = NULL;
18249 
18250  switch (id) {
18251  case SQL_DESC_SCHEMA_NAME:
18252  case SQL_DESC_CATALOG_NAME:
18253  case SQL_COLUMN_LABEL:
18254  case SQL_DESC_NAME:
18255  case SQL_DESC_TABLE_NAME:
18256 #ifdef SQL_DESC_BASE_TABLE_NAME
18257  case SQL_DESC_BASE_TABLE_NAME:
18258 #endif
18259 #ifdef SQL_DESC_BASE_COLUMN_NAME
18260  case SQL_DESC_BASE_COLUMN_NAME:
18261 #endif
18262  case SQL_DESC_TYPE_NAME:
18263  if (val && valMax > 0) {
18264  int vmax = valMax / sizeof (SQLWCHAR);
18265 
18266  v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
18267  if (v) {
18268  uc_strncpy(val, v, vmax);
18269  len = min(vmax, uc_strlen(v));
18270  uc_free(v);
18271  len *= sizeof (SQLWCHAR);
18272  }
18273  if (vmax > 0) {
18274  v = (SQLWCHAR *) val;
18275  v[vmax - 1] = '\0';
18276  }
18277  }
18278  if (len <= 0) {
18279  len = 0;
18280  }
18281  break;
18282  }
18283  if (valLen) {
18284  *valLen = len;
18285  }
18286  }
18287  HSTMT_UNLOCK(stmt);
18288  return ret;
18289 }
18290 #endif
18291 
18305 static SQLRETURN
18306 drverror(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18307  SQLCHAR *sqlState, SQLINTEGER *nativeErr,
18308  SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18309 {
18310  SQLCHAR dummy0[6];
18311  SQLINTEGER dummy1;
18312  SQLSMALLINT dummy2;
18313 
18314  if (env == SQL_NULL_HENV &&
18315  dbc == SQL_NULL_HDBC &&
18316  stmt == SQL_NULL_HSTMT) {
18317  return SQL_INVALID_HANDLE;
18318  }
18319  if (sqlState) {
18320  sqlState[0] = '\0';
18321  } else {
18322  sqlState = dummy0;
18323  }
18324  if (!nativeErr) {
18325  nativeErr = &dummy1;
18326  }
18327  *nativeErr = 0;
18328  if (!errlen) {
18329  errlen = &dummy2;
18330  }
18331  *errlen = 0;
18332  if (errmsg) {
18333  if (errmax > 0) {
18334  errmsg[0] = '\0';
18335  }
18336  } else {
18337  errmsg = dummy0;
18338  errmax = 0;
18339  }
18340  if (stmt) {
18341  STMT *s = (STMT *) stmt;
18342 
18343  HSTMT_LOCK(stmt);
18344  if (s->logmsg[0] == '\0') {
18345  HSTMT_UNLOCK(stmt);
18346  goto noerr;
18347  }
18348  *nativeErr = s->naterr;
18349  strcpy((char *) sqlState, s->sqlstate);
18350  if (errmax == SQL_NTS) {
18351  strcpy((char *) errmsg, "[SQLite]");
18352  strcat((char *) errmsg, (char *) s->logmsg);
18353  *errlen = strlen((char *) errmsg);
18354  } else {
18355  strncpy((char *) errmsg, "[SQLite]", errmax);
18356  if (errmax - 8 > 0) {
18357  strncpy((char *) errmsg + 8, (char *) s->logmsg, errmax - 8);
18358  }
18359  *errlen = min(strlen((char *) s->logmsg) + 8, errmax);
18360  }
18361  s->logmsg[0] = '\0';
18362  HSTMT_UNLOCK(stmt);
18363  return SQL_SUCCESS;
18364  }
18365  if (dbc) {
18366  DBC *d = (DBC *) dbc;
18367 
18368  HDBC_LOCK(dbc);
18369  if (d->magic != DBC_MAGIC || d->logmsg[0] == '\0') {
18370  HDBC_UNLOCK(dbc);
18371  goto noerr;
18372  }
18373  *nativeErr = d->naterr;
18374  strcpy((char *) sqlState, d->sqlstate);
18375  if (errmax == SQL_NTS) {
18376  strcpy((char *) errmsg, "[SQLite]");
18377  strcat((char *) errmsg, (char *) d->logmsg);
18378  *errlen = strlen((char *) errmsg);
18379  } else {
18380  strncpy((char *) errmsg, "[SQLite]", errmax);
18381  if (errmax - 8 > 0) {
18382  strncpy((char *) errmsg + 8, (char *) d->logmsg, errmax - 8);
18383  }
18384  *errlen = min(strlen((char *) d->logmsg) + 8, errmax);
18385  }
18386  d->logmsg[0] = '\0';
18387  HDBC_UNLOCK(dbc);
18388  return SQL_SUCCESS;
18389  }
18390 noerr:
18391  sqlState[0] = '\0';
18392  errmsg[0] = '\0';
18393  *nativeErr = 0;
18394  *errlen = 0;
18395  return SQL_NO_DATA;
18396 }
18397 
18398 #ifndef WINTERFACE
18399 
18412 SQLRETURN SQL_API
18413 SQLError(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18414  SQLCHAR *sqlState, SQLINTEGER *nativeErr,
18415  SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18416 {
18417  return drverror(env, dbc, stmt, sqlState, nativeErr,
18418  errmsg, errmax, errlen);
18419 }
18420 #endif
18421 
18422 #ifdef WINTERFACE
18423 
18436 SQLRETURN SQL_API
18437 SQLErrorW(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18438  SQLWCHAR *sqlState, SQLINTEGER *nativeErr,
18439  SQLWCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18440 {
18441  char state[16];
18442  SQLSMALLINT len = 0;
18443  SQLRETURN ret;
18444 
18445  ret = drverror(env, dbc, stmt, (SQLCHAR *) state, nativeErr,
18446  (SQLCHAR *) errmsg, errmax, &len);
18447  if (ret == SQL_SUCCESS) {
18448  if (sqlState) {
18449  uc_from_utf_buf((SQLCHAR *) state, -1, sqlState,
18450  6 * sizeof (SQLWCHAR));
18451  }
18452  if (errmsg) {
18453  if (len > 0) {
18454  SQLWCHAR *e = NULL;
18455 
18456  e = uc_from_utf((SQLCHAR *) errmsg, len);
18457  if (e) {
18458  if (errmax > 0) {
18459  uc_strncpy(errmsg, e, errmax);
18460  e[len] = 0;
18461  len = min(errmax, uc_strlen(e));
18462  } else {
18463  len = uc_strlen(e);
18464  }
18465  uc_free(e);
18466  } else {
18467  len = 0;
18468  }
18469  }
18470  if (len <= 0) {
18471  len = 0;
18472  if (errmax > 0) {
18473  errmsg[0] = 0;
18474  }
18475  }
18476  } else {
18477  len = 0;
18478  }
18479  if (errlen) {
18480  *errlen = len;
18481  }
18482  } else if (ret == SQL_NO_DATA) {
18483  if (sqlState) {
18484  sqlState[0] = 0;
18485  }
18486  if (errmsg) {
18487  if (errmax > 0) {
18488  errmsg[0] = 0;
18489  }
18490  }
18491  if (errlen) {
18492  *errlen = 0;
18493  }
18494  }
18495  return ret;
18496 }
18497 #endif
18498 
18505 SQLRETURN SQL_API
18506 SQLMoreResults(SQLHSTMT stmt)
18507 {
18508  HSTMT_LOCK(stmt);
18509  if (stmt == SQL_NULL_HSTMT) {
18510  return SQL_INVALID_HANDLE;
18511  }
18512  HSTMT_UNLOCK(stmt);
18513  return SQL_NO_DATA;
18514 }
18515 
18524 static SQLRETURN
18525 setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp)
18526 {
18527  int ncols = *ncolsp, guessed_types = 0;
18528  SQLRETURN ret = SQL_SUCCESS;
18529 
18530  if (ncols > 0) {
18531  int i;
18532  PTRDIFF_T size;
18533  char *p;
18534  COL *dyncols;
18535  DBC *d = (DBC *) s->dbc;
18536  const char *colname, *typename;
18537 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18538  char *tblname;
18539 #endif
18540 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18541  char *dbname;
18542 #endif
18543 
18544  for (i = size = 0; i < ncols; i++) {
18545  colname = sqlite3_column_name(s3stmt, i);
18546  size += 3 + 3 * strlen(colname);
18547  }
18548 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18549  tblname = (char *) size;
18550  for (i = 0; i < ncols; i++) {
18551  p = (char *) sqlite3_column_table_name(s3stmt, i);
18552  size += 2 + (p ? strlen(p) : 0);
18553  }
18554 #endif
18555 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18556  dbname = (char *) size;
18557  for (i = 0; i < ncols; i++) {
18558  p = (char *) sqlite3_column_database_name(s3stmt, i);
18559  size += 2 + (p ? strlen(p) : 0);
18560  }
18561 #endif
18562  dyncols = xmalloc(ncols * sizeof (COL) + size);
18563  if (!dyncols) {
18564  freedyncols(s);
18565  *ncolsp = 0;
18566  ret = SQL_ERROR;
18567  } else {
18568  p = (char *) (dyncols + ncols);
18569 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18570  tblname = p + (PTRDIFF_T) tblname;
18571 #endif
18572 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18573  dbname = p + (PTRDIFF_T) dbname;
18574 #endif
18575  for (i = 0; i < ncols; i++) {
18576  char *q;
18577 
18578  colname = sqlite3_column_name(s3stmt, i);
18579  if (d->trace) {
18580  fprintf(d->trace, "-- column %d name: '%s'\n",
18581  i + 1, colname);
18582  fflush(d->trace);
18583  }
18584 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18585  q = (char *) sqlite3_column_table_name(s3stmt, i);
18586  strcpy(tblname, q ? q : "");
18587  if (d->trace) {
18588  fprintf(d->trace, "-- table %d name: '%s'\n",
18589  i + 1, tblname);
18590  fflush(d->trace);
18591  }
18592  dyncols[i].table = tblname;
18593  tblname += strlen(tblname) + 1;
18594 #endif
18595 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18596  q = (char *) sqlite3_column_database_name(s3stmt, i);
18597  strcpy(dbname, q ? q : "");
18598  if (d->trace) {
18599  fprintf(d->trace, "-- database %d name: '%s'\n",
18600  i + 1, dbname);
18601  fflush(d->trace);
18602  }
18603  dyncols[i].db = dbname;
18604  dbname += strlen(dbname) + 1;
18605 #else
18606  dyncols[i].db = ((DBC *) (s->dbc))->dbname;
18607 #endif
18608  typename = s3stmt_coltype(s3stmt, i, d, &guessed_types);
18609  strcpy(p, colname);
18610  dyncols[i].label = p;
18611  p += strlen(p) + 1;
18612  q = strchr(colname, '.');
18613  if (q) {
18614  char *q2 = strchr(q + 1, '.');
18615 
18616  /* SQLite 3.3.4 produces view.table.column sometimes */
18617  if (q2) {
18618  q = q2;
18619  }
18620  }
18621  if (q) {
18622 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18623  dyncols[i].table = p;
18624 #endif
18625  strncpy(p, colname, q - colname);
18626  p[q - colname] = '\0';
18627  p += strlen(p) + 1;
18628  strcpy(p, q + 1);
18629  dyncols[i].column = p;
18630  p += strlen(p) + 1;
18631  } else {
18632 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18633  dyncols[i].table = "";
18634 #endif
18635  strcpy(p, colname);
18636  dyncols[i].column = p;
18637  p += strlen(p) + 1;
18638  }
18639  if (s->longnames) {
18640  dyncols[i].column = dyncols[i].label;
18641  }
18642 #ifdef SQL_LONGVARCHAR
18643  dyncols[i].type = SQL_LONGVARCHAR;
18644  dyncols[i].size = 65535;
18645 #else
18646  dyncols[i].type = SQL_VARCHAR;
18647  dyncols[i].size = 255;
18648 #endif
18649  dyncols[i].index = i;
18650  dyncols[i].scale = 0;
18651  dyncols[i].prec = 0;
18652  dyncols[i].nosign = 1;
18653  dyncols[i].autoinc = SQL_FALSE;
18654  dyncols[i].notnull = SQL_NULLABLE;
18655  dyncols[i].ispk = -1;
18656  dyncols[i].isrowid = -1;
18657 #ifdef FULL_METADATA
18658  s3stmt_addmeta(s3stmt, i, d, &dyncols[i]);
18659 #endif
18660  dyncols[i].typename = xstrdup(typename);
18661  }
18662  freedyncols(s);
18663  s->dyncols = s->cols = dyncols;
18664  s->dcols = ncols;
18665  fixupdyncols(s, d);
18666  s->guessed_types = guessed_types;
18667  }
18668  }
18669  return ret;
18670 }
18671 
18680 static SQLRETURN
18681 drvprepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18682 {
18683  STMT *s;
18684  DBC *d;
18685  char *errp = NULL;
18686  SQLRETURN sret;
18687 
18688  if (stmt == SQL_NULL_HSTMT) {
18689  return SQL_INVALID_HANDLE;
18690  }
18691  s = (STMT *) stmt;
18692  if (s->dbc == SQL_NULL_HDBC) {
18693 noconn:
18694  return noconn(s);
18695  }
18696  d = s->dbc;
18697  if (!d->sqlite) {
18698  goto noconn;
18699  }
18700  s3stmt_end(s);
18701  s3stmt_drop(s);
18702  sret = starttran(s);
18703  if (sret != SQL_SUCCESS) {
18704  return sret;
18705  }
18706  freep(&s->query);
18707  s->query = (SQLCHAR *) fixupsql((char *) query, queryLen,
18708  (d->version >= 0x030805),
18709  &s->nparams, &s->isselect, &errp);
18710  if (!s->query) {
18711  if (errp) {
18712  setstat(s, -1, "%s", (*s->ov3) ? "HY000" : "S1000", errp);
18713  return SQL_ERROR;
18714  }
18715  return nomem(s);
18716  }
18717  if (*s->ilike) {
18718  replilike((char *) s->query);
18719  }
18720  errp = NULL;
18721  freeresult(s, -1);
18722  if (s->isselect == 1) {
18723  int ret, ncols, nretry = 0;
18724  const char *rest;
18725  sqlite3_stmt *s3stmt = NULL;
18726 
18727 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18728  dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
18729 #else
18730  dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
18731 #endif
18732  do {
18733  s3stmt = NULL;
18734 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18735  ret = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
18736  &s3stmt, &rest);
18737 #else
18738  ret = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
18739  &s3stmt, &rest);
18740 #endif
18741  if (ret != SQLITE_OK) {
18742  if (s3stmt) {
18743  sqlite3_finalize(s3stmt);
18744  s3stmt = NULL;
18745  }
18746  }
18747  } while (ret == SQLITE_SCHEMA && (++nretry) < 2);
18748  dbtracerc(d, ret, NULL);
18749  if (ret != SQLITE_OK) {
18750  if (s3stmt) {
18751  dbtraceapi(d, "sqlite3_finalize", 0);
18752  sqlite3_finalize(s3stmt);
18753  }
18754  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18755  sqlite3_errmsg(d->sqlite), ret);
18756  return SQL_ERROR;
18757  }
18758  if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
18759  dbtraceapi(d, "sqlite3_finalize", 0);
18760  sqlite3_finalize(s3stmt);
18761  setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
18762  (*s->ov3) ? "HY000" : "S1000");
18763  return SQL_ERROR;
18764  }
18765  ncols = sqlite3_column_count(s3stmt);
18766  s->guessed_types = 0;
18767  setupdyncols(s, s3stmt, &ncols);
18768  s->ncols = ncols;
18769  s->s3stmt = s3stmt;
18770  } else {
18771  s->guessed_types = 1;
18772  }
18773  mkbindcols(s, s->ncols);
18774  s->paramset_count = 0;
18775  return SQL_SUCCESS;
18776 }
18777 
18785 static SQLRETURN
18786 drvexecute(SQLHSTMT stmt, int initial)
18787 {
18788  STMT *s;
18789  DBC *d;
18790  char *errp = NULL;
18791  int rc, i, ncols = 0, nrows = 0, busy_count;
18792  SQLRETURN ret;
18793 
18794  if (stmt == SQL_NULL_HSTMT) {
18795  return SQL_INVALID_HANDLE;
18796  }
18797  s = (STMT *) stmt;
18798  if (s->dbc == SQL_NULL_HDBC) {
18799 noconn:
18800  return noconn(s);
18801  }
18802  d = (DBC *) s->dbc;
18803  if (!d->sqlite) {
18804  goto noconn;
18805  }
18806  if (!s->query) {
18807  setstat(s, -1, "no query prepared", (*s->ov3) ? "HY000" : "S1000");
18808  return SQL_ERROR;
18809  }
18810  if (s->nbindparms < s->nparams) {
18811 unbound:
18812  setstat(s, -1, "unbound parameters in query",
18813  (*s->ov3) ? "HY000" : "S1000");
18814  return SQL_ERROR;
18815  }
18816  for (i = 0; i < s->nparams; i++) {
18817  BINDPARM *p = &s->bindparms[i];
18818 
18819  if (!p->bound) {
18820  goto unbound;
18821  }
18822  if (initial) {
18823  SQLLEN *lenp = p->lenp;
18824 
18825  if (lenp && *lenp < 0 && *lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18826  *lenp != SQL_NTS && *lenp != SQL_NULL_DATA &&
18827  *lenp != SQL_DATA_AT_EXEC) {
18828  setstat(s, -1, "invalid length reference", "HY009");
18829  return SQL_ERROR;
18830  }
18831  if (lenp && (*lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18832  *lenp == SQL_DATA_AT_EXEC)) {
18833  p->need = 1;
18834  p->offs = 0;
18835  p->len = 0;
18836  }
18837  }
18838  }
18839  ret = starttran(s);
18840  if (ret != SQL_SUCCESS) {
18841  goto cleanup;
18842  }
18843  busy_count = 0;
18844 again:
18845  s3stmt_end(s);
18846  if (initial) {
18847  /* fixup data-at-execution parameters and alloc'ed blobs */
18848  s->pdcount = -1;
18849  for (i = 0; i < s->nparams; i++) {
18850  BINDPARM *p = &s->bindparms[i];
18851 
18852  if (p->param == p->parbuf) {
18853  p->param = NULL;
18854  }
18855  freep(&p->parbuf);
18856  if (p->need <= 0 &&
18857  p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18858  *p->lenp == SQL_DATA_AT_EXEC)) {
18859  p->need = 1;
18860  p->offs = 0;
18861  p->len = 0;
18862  }
18863  }
18864  }
18865  if (s->nparams) {
18866  for (i = 0; i < s->nparams; i++) {
18867  ret = setupparam(s, (char *) s->query, i);
18868  if (ret != SQL_SUCCESS) {
18869  goto cleanup;
18870  }
18871  }
18872  }
18873  freeresult(s, 0);
18874  if (s->isselect == 1 && !d->intrans &&
18875  s->curtype == SQL_CURSOR_FORWARD_ONLY &&
18876  d->step_enable && s->nparams == 0 && d->cur_s3stmt == NULL) {
18877  s->nrows = -1;
18878  ret = s3stmt_start(s);
18879  if (ret == SQL_SUCCESS) {
18880  goto done2;
18881  }
18882  }
18883  rc = drvgettable(s, s->s3stmt ? NULL : (char *) s->query, &s->rows,
18884  &s->nrows, &ncols, &errp, s->nparams, s->bindparms);
18885  dbtracerc(d, rc, errp);
18886  if (rc == SQLITE_BUSY) {
18887  if (busy_handler((void *) d, ++busy_count)) {
18888  if (errp) {
18889  sqlite3_free(errp);
18890  errp = NULL;
18891  }
18892  for (i = 0; i < s->nparams; i++) {
18893  BINDPARM *p = &s->bindparms[i];
18894 
18895  if (p->param == p->parbuf) {
18896  p->param = NULL;
18897  }
18898  freep(&p->parbuf);
18899  if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18900  *p->lenp != SQL_DATA_AT_EXEC)) {
18901  p->param = p->param0;
18902  }
18903  p->lenp = p->lenp0;
18904  }
18905  s->nrows = 0;
18906  goto again;
18907  }
18908  }
18909  if (rc != SQLITE_OK) {
18910  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18911  errp ? errp : "unknown error", rc);
18912  if (errp) {
18913  sqlite3_free(errp);
18914  errp = NULL;
18915  }
18916  ret = SQL_ERROR;
18917  goto cleanup;
18918  }
18919  if (errp) {
18920  sqlite3_free(errp);
18921  errp = NULL;
18922  }
18923  s->rowfree = freerows;
18924  if (s->isselect <= 0 || s->isselect > 1) {
18925  /*
18926  * DDL results are immediately released.
18927  * INSERT/UPDATE/DELETE depends on number of columns in
18928  * result set, if zero, result is immediately released.
18929  */
18930  if (s->isselect != 0 || ncols == 0) {
18931  freeresult(s, -1);
18932  nrows += sqlite3_changes(d->sqlite);
18933  s->nrows = nrows;
18934  } else {
18935  s->ncols = ncols;
18936  }
18937  goto done;
18938  }
18939  if (s->ncols != ncols) {
18940  /*
18941  * Weird result.
18942  */
18943  setstat(s, -1, "broken result set %d/%d",
18944  (*s->ov3) ? "HY000" : "S1000", s->ncols, ncols);
18945  ret = SQL_ERROR;
18946  goto cleanup;
18947  }
18948 done:
18949  mkbindcols(s, s->ncols);
18950 done2:
18951  ret = SQL_SUCCESS;
18952  s->rowp = s->rowprs = -1;
18953  s->paramset_count++;
18954  s->paramset_nrows = s->nrows;
18955  if (s->paramset_count < s->paramset_size) {
18956  for (i = 0; i < s->nparams; i++) {
18957  BINDPARM *p = &s->bindparms[i];
18958 
18959  if (p->param == p->parbuf) {
18960  p->param = NULL;
18961  }
18962  freep(&p->parbuf);
18963  if (p->lenp0 &&
18964  s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18965  p->lenp = (SQLLEN *) ((char *) p->lenp0 +
18966  s->paramset_count * s->parm_bind_type);
18967  } else if (p->lenp0 && p->inc > 0) {
18968  p->lenp = p->lenp0 + s->paramset_count;
18969  }
18970  if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18971  *p->lenp != SQL_DATA_AT_EXEC)) {
18972  if (p->param0 &&
18973  s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18974  p->param = (char *) p->param0 +
18976  } else if (p->param0 && p->inc > 0) {
18977  p->param = (char *) p->param0 +
18978  s->paramset_count * p->inc;
18979  }
18980  } else if (p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18981  *p->lenp == SQL_DATA_AT_EXEC)) {
18982  p->need = 1;
18983  p->offs = 0;
18984  p->len = 0;
18985  }
18986  }
18987  goto again;
18988  }
18989 cleanup:
18990  if (ret != SQL_NEED_DATA) {
18991  for (i = 0; i < s->nparams; i++) {
18992  BINDPARM *p = &s->bindparms[i];
18993 
18994  if (p->param == p->parbuf) {
18995  p->param = NULL;
18996  }
18997  freep(&p->parbuf);
18998  if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18999  *p->lenp != SQL_DATA_AT_EXEC)) {
19000  p->param = p->param0;
19001  }
19002  p->lenp = p->lenp0;
19003  }
19004  s->nrows = s->paramset_nrows;
19005  if (s->parm_proc) {
19006  *s->parm_proc = s->paramset_count;
19007  }
19008  s->paramset_count = 0;
19009  s->paramset_nrows = 0;
19010  }
19011  /*
19012  * For INSERT/UPDATE/DELETE statements change the return code
19013  * to SQL_NO_DATA if the number of rows affected was 0.
19014  */
19015  if (*s->ov3 && s->isselect == 0 &&
19016  ret == SQL_SUCCESS && nrows == 0) {
19017  ret = SQL_NO_DATA;
19018  }
19019  return ret;
19020 }
19021 
19022 #ifndef WINTERFACE
19023 
19031 SQLRETURN SQL_API
19032 SQLPrepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
19033 {
19034  SQLRETURN ret;
19035 #if defined(_WIN32) || defined(_WIN64)
19036  char *q;
19037 #endif
19038 
19039  HSTMT_LOCK(stmt);
19040 #if defined(_WIN32) || defined(_WIN64)
19041  if (!((STMT *) stmt)->oemcp[0]) {
19042  ret = drvprepare(stmt, query, queryLen);
19043  goto done;
19044  }
19045  q = wmb_to_utf_c((char *) query, queryLen);
19046  if (!q) {
19047  ret = nomem((STMT *) stmt);
19048  goto done;
19049  }
19050  query = (SQLCHAR *) q;
19051  queryLen = SQL_NTS;
19052 #endif
19053  ret = drvprepare(stmt, query, queryLen);
19054 #if defined(_WIN32) || defined(_WIN64)
19055  uc_free(q);
19056 done:
19057  ;
19058 #endif
19059  HSTMT_UNLOCK(stmt);
19060  return ret;
19061 }
19062 #endif
19063 
19064 #ifdef WINTERFACE
19065 
19073 SQLRETURN SQL_API
19074 SQLPrepareW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
19075 {
19076  SQLRETURN ret;
19077  char *q = uc_to_utf_c(query, queryLen);
19078 
19079  HSTMT_LOCK(stmt);
19080  if (!q) {
19081  ret = nomem((STMT *) stmt);
19082  goto done;
19083  }
19084  ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
19085  uc_free(q);
19086 done:
19087  HSTMT_UNLOCK(stmt);
19088  return ret;
19089 }
19090 #endif
19091 
19098 SQLRETURN SQL_API
19099 SQLExecute(SQLHSTMT stmt)
19100 {
19101  SQLRETURN ret;
19102 
19103  HSTMT_LOCK(stmt);
19104  ret = drvexecute(stmt, 1);
19105  HSTMT_UNLOCK(stmt);
19106  return ret;
19107 }
19108 
19109 #ifndef WINTERFACE
19110 
19118 SQLRETURN SQL_API
19119 SQLExecDirect(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
19120 {
19121  SQLRETURN ret;
19122 #if defined(_WIN32) || defined(_WIN64)
19123  char *q;
19124 #endif
19125 
19126  HSTMT_LOCK(stmt);
19127 #if defined(_WIN32) || defined(_WIN64)
19128  if (!((STMT *) stmt)->oemcp[0]) {
19129  ret = drvprepare(stmt, query, queryLen);
19130  if (ret == SQL_SUCCESS) {
19131  ret = drvexecute(stmt, 1);
19132  }
19133  goto done;
19134  }
19135  q = wmb_to_utf_c((char *) query, queryLen);
19136  if (!q) {
19137  ret = nomem((STMT *) stmt);
19138  goto done;
19139  }
19140  query = (SQLCHAR *) q;
19141  queryLen = SQL_NTS;
19142 #endif
19143  ret = drvprepare(stmt, query, queryLen);
19144  if (ret == SQL_SUCCESS) {
19145  ret = drvexecute(stmt, 1);
19146  }
19147 #if defined(_WIN32) || defined(_WIN64)
19148  uc_free(q);
19149 done:
19150  ;
19151 #endif
19152  HSTMT_UNLOCK(stmt);
19153  return ret;
19154 }
19155 #endif
19156 
19157 #ifdef WINTERFACE
19158 
19166 SQLRETURN SQL_API
19167 SQLExecDirectW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
19168 {
19169  SQLRETURN ret;
19170  char *q = uc_to_utf_c(query, queryLen);
19171 
19172  HSTMT_LOCK(stmt);
19173  if (!q) {
19174  ret = nomem((STMT *) stmt);
19175  goto done;
19176  }
19177  ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
19178  uc_free(q);
19179  if (ret == SQL_SUCCESS) {
19180  ret = drvexecute(stmt, 1);
19181  }
19182 done:
19183  HSTMT_UNLOCK(stmt);
19184  return ret;
19185 }
19186 #endif
19187 
19188 
19189 #if defined(_WIN32) || defined(_WIN64)
19190 #ifndef WITHOUT_DRIVERMGR
19191 
19192 /*
19193  * Windows configuration dialog stuff.
19194  */
19195 
19196 #include <windowsx.h>
19197 #include <winuser.h>
19198 
19199 #define MAXPATHLEN (259+1) /* Max path length */
19200 #define MAXKEYLEN (15+1) /* Max keyword length */
19201 #define MAXDESC (255+1) /* Max description length */
19202 #define MAXDSNAME (255+1) /* Max data source name length */
19203 #define MAXTONAME (32+1) /* Max timeout length */
19204 #define MAXDBNAME MAXPATHLEN
19205 
19206 /* Attribute key indexes into an array of Attr structs, see below */
19207 
19208 #define KEY_DSN 0
19209 #define KEY_DESC 1
19210 #define KEY_DBNAME 2
19211 #define KEY_BUSY 3
19212 #define KEY_DRIVER 4
19213 #define KEY_STEPAPI 5
19214 #define KEY_SYNCP 6
19215 #define KEY_NOTXN 7
19216 #define KEY_SHORTNAM 8
19217 #define KEY_LONGNAM 9
19218 #define KEY_NOCREAT 10
19219 #define KEY_NOWCHAR 11
19220 #define KEY_LOADEXT 12
19221 #define KEY_JMODE 13
19222 #define KEY_FKSUPPORT 14
19223 #define KEY_OEMCP 15
19224 #define KEY_BIGINT 16
19225 #define KEY_PASSWD 17
19226 #define KEY_JDCONV 18
19227 #define KEY_ATTAS 19
19228 #define KEY_ILIKE 20
19229 #define NUMOFKEYS 21
19230 
19231 typedef struct {
19232  BOOL supplied;
19233  char attr[MAXPATHLEN*4];
19234 } ATTR;
19235 
19236 typedef struct {
19237  SQLHWND parent;
19238  LPCSTR driver;
19239  ATTR attr[NUMOFKEYS];
19240  char DSN[MAXDSNAME];
19241  BOOL newDSN;
19242  BOOL defDSN;
19243 } SETUPDLG;
19244 
19245 static struct {
19246  char *key;
19247  int ikey;
19248 } attrLookup[] = {
19249  { "DSN", KEY_DSN },
19250  { "DESC", KEY_DESC },
19251  { "Description", KEY_DESC},
19252  { "Database", KEY_DBNAME },
19253  { "Timeout", KEY_BUSY },
19254  { "Driver", KEY_DRIVER },
19255  { "StepAPI", KEY_STEPAPI },
19256  { "SyncPragma", KEY_SYNCP },
19257  { "NoTXN", KEY_NOTXN },
19258  { "ShortNames", KEY_SHORTNAM },
19259  { "LongNames", KEY_LONGNAM },
19260  { "NoCreat", KEY_NOCREAT },
19261  { "NoWCHAR", KEY_NOWCHAR },
19262  { "LoadExt", KEY_LOADEXT },
19263  { "JournalMode", KEY_JMODE },
19264  { "FKSupport", KEY_FKSUPPORT },
19265  { "OEMCP", KEY_OEMCP },
19266  { "BigInt", KEY_BIGINT },
19267  { "PWD", KEY_PASSWD },
19268  { "JDConv", KEY_JDCONV },
19269  { "AttachAs", KEY_ATTAS },
19270  { "ILike", KEY_ILIKE },
19271  { NULL, 0 }
19272 };
19273 
19280 static void
19281 ParseAttributes(LPCSTR attribs, SETUPDLG *setupdlg)
19282 {
19283  char *str = (char *) attribs, *start, key[MAXKEYLEN];
19284  int elem, nkey;
19285 
19286  while (*str) {
19287  start = str;
19288  if ((str = strchr(str, '=')) == NULL) {
19289  return;
19290  }
19291  elem = -1;
19292  nkey = str - start;
19293  if (nkey < sizeof (key)) {
19294  int i;
19295 
19296  memcpy(key, start, nkey);
19297  key[nkey] = '\0';
19298  for (i = 0; attrLookup[i].key; i++) {
19299  if (strcasecmp(attrLookup[i].key, key) == 0) {
19300  elem = attrLookup[i].ikey;
19301  break;
19302  }
19303  }
19304  }
19305  start = ++str;
19306  while (*str && *str != ';') {
19307  ++str;
19308  }
19309  if (elem >= 0) {
19310  int end = min(str - start, sizeof (setupdlg->attr[elem].attr) - 1);
19311 
19312  setupdlg->attr[elem].supplied = TRUE;
19313  memcpy(setupdlg->attr[elem].attr, start, end);
19314  setupdlg->attr[elem].attr[end] = '\0';
19315  }
19316  ++str;
19317  }
19318 }
19319 
19327 static BOOL
19328 SetDSNAttributes(HWND parent, SETUPDLG *setupdlg)
19329 {
19330  char *dsn = setupdlg->attr[KEY_DSN].attr;
19331 
19332  if (setupdlg->newDSN && strlen(dsn) == 0) {
19333  return FALSE;
19334  }
19335  if (!SQLWriteDSNToIni(dsn, setupdlg->driver)) {
19336  if (parent) {
19337  char buf[MAXPATHLEN], msg[MAXPATHLEN];
19338 
19339  LoadString(hModule, IDS_BADDSN, buf, sizeof (buf));
19340  wsprintf(msg, buf, dsn);
19341  LoadString(hModule, IDS_MSGTITLE, buf, sizeof (buf));
19342  MessageBox(parent, msg, buf,
19343  MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
19344  MB_SETFOREGROUND);
19345  }
19346  return FALSE;
19347  }
19348  if (parent || setupdlg->attr[KEY_DESC].supplied) {
19349  SQLWritePrivateProfileString(dsn, "Description",
19350  setupdlg->attr[KEY_DESC].attr,
19351  ODBC_INI);
19352  }
19353  if (parent || setupdlg->attr[KEY_DBNAME].supplied) {
19354  SQLWritePrivateProfileString(dsn, "Database",
19355  setupdlg->attr[KEY_DBNAME].attr,
19356  ODBC_INI);
19357  }
19358  if (parent || setupdlg->attr[KEY_BUSY].supplied) {
19359  SQLWritePrivateProfileString(dsn, "Timeout",
19360  setupdlg->attr[KEY_BUSY].attr,
19361  ODBC_INI);
19362  }
19363  if (parent || setupdlg->attr[KEY_STEPAPI].supplied) {
19364  SQLWritePrivateProfileString(dsn, "StepAPI",
19365  setupdlg->attr[KEY_STEPAPI].attr,
19366  ODBC_INI);
19367  }
19368  if (parent || setupdlg->attr[KEY_SYNCP].supplied) {
19369  SQLWritePrivateProfileString(dsn, "SyncPragma",
19370  setupdlg->attr[KEY_SYNCP].attr,
19371  ODBC_INI);
19372  }
19373  if (parent || setupdlg->attr[KEY_NOTXN].supplied) {
19374  SQLWritePrivateProfileString(dsn, "NoTXN",
19375  setupdlg->attr[KEY_NOTXN].attr,
19376  ODBC_INI);
19377  }
19378  if (parent || setupdlg->attr[KEY_SHORTNAM].supplied) {
19379  SQLWritePrivateProfileString(dsn, "ShortNames",
19380  setupdlg->attr[KEY_SHORTNAM].attr,
19381  ODBC_INI);
19382  }
19383  if (parent || setupdlg->attr[KEY_LONGNAM].supplied) {
19384  SQLWritePrivateProfileString(dsn, "LongNames",
19385  setupdlg->attr[KEY_LONGNAM].attr,
19386  ODBC_INI);
19387  }
19388  if (parent || setupdlg->attr[KEY_NOCREAT].supplied) {
19389  SQLWritePrivateProfileString(dsn, "NoCreat",
19390  setupdlg->attr[KEY_NOCREAT].attr,
19391  ODBC_INI);
19392  }
19393  if (parent || setupdlg->attr[KEY_NOWCHAR].supplied) {
19394  SQLWritePrivateProfileString(dsn, "NoWCHAR",
19395  setupdlg->attr[KEY_NOWCHAR].attr,
19396  ODBC_INI);
19397  }
19398  if (parent || setupdlg->attr[KEY_FKSUPPORT].supplied) {
19399  SQLWritePrivateProfileString(dsn, "FKSupport",
19400  setupdlg->attr[KEY_FKSUPPORT].attr,
19401  ODBC_INI);
19402  }
19403  if (parent || setupdlg->attr[KEY_OEMCP].supplied) {
19404  SQLWritePrivateProfileString(dsn, "OEMCP",
19405  setupdlg->attr[KEY_OEMCP].attr,
19406  ODBC_INI);
19407  }
19408  if (parent || setupdlg->attr[KEY_LOADEXT].supplied) {
19409  SQLWritePrivateProfileString(dsn, "LoadExt",
19410  setupdlg->attr[KEY_LOADEXT].attr,
19411  ODBC_INI);
19412  }
19413  if (parent || setupdlg->attr[KEY_BIGINT].supplied) {
19414  SQLWritePrivateProfileString(dsn, "BigInt",
19415  setupdlg->attr[KEY_BIGINT].attr,
19416  ODBC_INI);
19417  }
19418  if (parent || setupdlg->attr[KEY_JDCONV].supplied) {
19419  SQLWritePrivateProfileString(dsn, "JDConv",
19420  setupdlg->attr[KEY_JDCONV].attr,
19421  ODBC_INI);
19422  }
19423  if (parent || setupdlg->attr[KEY_ATTAS].supplied) {
19424  SQLWritePrivateProfileString(dsn, "AttachAs",
19425  setupdlg->attr[KEY_ATTAS].attr,
19426  ODBC_INI);
19427  }
19428  if (parent || setupdlg->attr[KEY_ILIKE].supplied) {
19429  SQLWritePrivateProfileString(dsn, "ILike",
19430  setupdlg->attr[KEY_ILIKE].attr,
19431  ODBC_INI);
19432  }
19433  if (parent || setupdlg->attr[KEY_PASSWD].supplied) {
19434  SQLWritePrivateProfileString(dsn, "PWD",
19435  setupdlg->attr[KEY_PASSWD].attr,
19436  ODBC_INI);
19437  }
19438  if (setupdlg->attr[KEY_DSN].supplied &&
19439  strcasecmp(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr)) {
19440  SQLRemoveDSNFromIni(setupdlg->DSN);
19441  }
19442  return TRUE;
19443 }
19444 
19450 static void
19451 GetAttributes(SETUPDLG *setupdlg)
19452 {
19453  char *dsn = setupdlg->attr[KEY_DSN].attr;
19454 
19455  if (!setupdlg->attr[KEY_DESC].supplied) {
19456  SQLGetPrivateProfileString(dsn, "Description", "",
19457  setupdlg->attr[KEY_DESC].attr,
19458  sizeof (setupdlg->attr[KEY_DESC].attr),
19459  ODBC_INI);
19460  }
19461  if (!setupdlg->attr[KEY_DBNAME].supplied) {
19462  SQLGetPrivateProfileString(dsn, "Database", "",
19463  setupdlg->attr[KEY_DBNAME].attr,
19464  sizeof (setupdlg->attr[KEY_DBNAME].attr),
19465  ODBC_INI);
19466  }
19467  if (!setupdlg->attr[KEY_BUSY].supplied) {
19468  SQLGetPrivateProfileString(dsn, "Timeout", "100000",
19469  setupdlg->attr[KEY_BUSY].attr,
19470  sizeof (setupdlg->attr[KEY_BUSY].attr),
19471  ODBC_INI);
19472  }
19473  if (!setupdlg->attr[KEY_STEPAPI].supplied) {
19474  SQLGetPrivateProfileString(dsn, "StepAPI", "0",
19475  setupdlg->attr[KEY_STEPAPI].attr,
19476  sizeof (setupdlg->attr[KEY_STEPAPI].attr),
19477  ODBC_INI);
19478  }
19479  if (!setupdlg->attr[KEY_SYNCP].supplied) {
19480  SQLGetPrivateProfileString(dsn, "SyncPragma", "NORMAL",
19481  setupdlg->attr[KEY_SYNCP].attr,
19482  sizeof (setupdlg->attr[KEY_SYNCP].attr),
19483  ODBC_INI);
19484  }
19485  if (!setupdlg->attr[KEY_NOTXN].supplied) {
19486  SQLGetPrivateProfileString(dsn, "NoTXN", "",
19487  setupdlg->attr[KEY_NOTXN].attr,
19488  sizeof (setupdlg->attr[KEY_NOTXN].attr),
19489  ODBC_INI);
19490  }
19491  if (!setupdlg->attr[KEY_SHORTNAM].supplied) {
19492  SQLGetPrivateProfileString(dsn, "ShortNames", "",
19493  setupdlg->attr[KEY_SHORTNAM].attr,
19494  sizeof (setupdlg->attr[KEY_SHORTNAM].attr),
19495  ODBC_INI);
19496  }
19497  if (!setupdlg->attr[KEY_LONGNAM].supplied) {
19498  SQLGetPrivateProfileString(dsn, "LongNames", "",
19499  setupdlg->attr[KEY_LONGNAM].attr,
19500  sizeof (setupdlg->attr[KEY_LONGNAM].attr),
19501  ODBC_INI);
19502  }
19503  if (!setupdlg->attr[KEY_NOCREAT].supplied) {
19504  SQLGetPrivateProfileString(dsn, "NoCreat", "",
19505  setupdlg->attr[KEY_NOCREAT].attr,
19506  sizeof (setupdlg->attr[KEY_NOCREAT].attr),
19507  ODBC_INI);
19508  }
19509  if (!setupdlg->attr[KEY_NOWCHAR].supplied) {
19510  SQLGetPrivateProfileString(dsn, "NoWCHAR", "",
19511  setupdlg->attr[KEY_NOWCHAR].attr,
19512  sizeof (setupdlg->attr[KEY_NOWCHAR].attr),
19513  ODBC_INI);
19514  }
19515  if (!setupdlg->attr[KEY_FKSUPPORT].supplied) {
19516  SQLGetPrivateProfileString(dsn, "FKSupport", "",
19517  setupdlg->attr[KEY_FKSUPPORT].attr,
19518  sizeof (setupdlg->attr[KEY_FKSUPPORT].attr),
19519  ODBC_INI);
19520  }
19521  if (!setupdlg->attr[KEY_OEMCP].supplied) {
19522  SQLGetPrivateProfileString(dsn, "OEMCP", "",
19523  setupdlg->attr[KEY_OEMCP].attr,
19524  sizeof (setupdlg->attr[KEY_OEMCP].attr),
19525  ODBC_INI);
19526  }
19527  if (!setupdlg->attr[KEY_LOADEXT].supplied) {
19528  SQLGetPrivateProfileString(dsn, "LoadExt", "",
19529  setupdlg->attr[KEY_LOADEXT].attr,
19530  sizeof (setupdlg->attr[KEY_LOADEXT].attr),
19531  ODBC_INI);
19532  }
19533  if (!setupdlg->attr[KEY_JMODE].supplied) {
19534  SQLGetPrivateProfileString(dsn, "JournalMode", "",
19535  setupdlg->attr[KEY_JMODE].attr,
19536  sizeof (setupdlg->attr[KEY_JMODE].attr),
19537  ODBC_INI);
19538  }
19539  if (!setupdlg->attr[KEY_BIGINT].supplied) {
19540  SQLGetPrivateProfileString(dsn, "BigInt", "",
19541  setupdlg->attr[KEY_BIGINT].attr,
19542  sizeof (setupdlg->attr[KEY_BIGINT].attr),
19543  ODBC_INI);
19544  }
19545  if (!setupdlg->attr[KEY_PASSWD].supplied) {
19546  SQLGetPrivateProfileString(dsn, "PWD", "",
19547  setupdlg->attr[KEY_PASSWD].attr,
19548  sizeof (setupdlg->attr[KEY_PASSWD].attr),
19549  ODBC_INI);
19550  }
19551  if (!setupdlg->attr[KEY_JDCONV].supplied) {
19552  SQLGetPrivateProfileString(dsn, "JDConv", "",
19553  setupdlg->attr[KEY_JDCONV].attr,
19554  sizeof (setupdlg->attr[KEY_JDCONV].attr),
19555  ODBC_INI);
19556  }
19557  if (!setupdlg->attr[KEY_ATTAS].supplied) {
19558  SQLGetPrivateProfileString(dsn, "AttachAs", "",
19559  setupdlg->attr[KEY_ATTAS].attr,
19560  sizeof (setupdlg->attr[KEY_ATTAS].attr),
19561  ODBC_INI);
19562  }
19563  if (!setupdlg->attr[KEY_ILIKE].supplied) {
19564  SQLGetPrivateProfileString(dsn, "ILike", "",
19565  setupdlg->attr[KEY_ILIKE].attr,
19566  sizeof (setupdlg->attr[KEY_ILIKE].attr),
19567  ODBC_INI);
19568  }
19569 }
19570 
19576 static void
19577 GetDBFile(HWND hdlg)
19578 {
19579 #ifdef _WIN64
19580  SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19581 #else
19582  SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19583 #endif
19584  OPENFILENAME ofn;
19585 
19586  memset(&ofn, 0, sizeof (ofn));
19587  ofn.lStructSize = sizeof (ofn);
19588  ofn.hwndOwner = hdlg;
19589 #ifdef _WIN64
19590  ofn.hInstance = (HINSTANCE) GetWindowLongPtr(hdlg, GWLP_HINSTANCE);
19591 #else
19592  ofn.hInstance = (HINSTANCE) GetWindowLong(hdlg, GWL_HINSTANCE);
19593 #endif
19594  ofn.lpstrFile = (LPTSTR) setupdlg->attr[KEY_DBNAME].attr;
19595  ofn.nMaxFile = MAXPATHLEN;
19596  ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST |
19597  OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_FILEMUSTEXIST;
19598  if (GetOpenFileName(&ofn)) {
19599  SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19600  setupdlg->attr[KEY_DBNAME].supplied = TRUE;
19601  }
19602 }
19603 
19613 static BOOL CALLBACK
19614 ConfigDlgProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19615 {
19616  SETUPDLG *setupdlg = NULL;
19617  WORD index;
19618 
19619  switch (wmsg) {
19620  case WM_INITDIALOG:
19621 #ifdef _WIN64
19622  SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19623 #else
19624  SetWindowLong(hdlg, DWL_USER, lparam);
19625 #endif
19626  setupdlg = (SETUPDLG *) lparam;
19627  GetAttributes(setupdlg);
19628  SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19629  SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19630  SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19631  SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19632  SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19633  SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19634  (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19635  SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19636  (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19637  SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19638  (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19639  SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19640  (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19641  SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19642  (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19643  CheckDlgButton(hdlg, IDC_STEPAPI,
19644  getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19645  BST_CHECKED : BST_UNCHECKED);
19646  CheckDlgButton(hdlg, IDC_NOTXN,
19647  getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19648  BST_CHECKED : BST_UNCHECKED);
19649  CheckDlgButton(hdlg, IDC_SHORTNAM,
19650  getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19651  BST_CHECKED : BST_UNCHECKED);
19652  CheckDlgButton(hdlg, IDC_LONGNAM,
19653  getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19654  BST_CHECKED : BST_UNCHECKED);
19655  CheckDlgButton(hdlg, IDC_NOCREAT,
19656  getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19657  BST_CHECKED : BST_UNCHECKED);
19658  CheckDlgButton(hdlg, IDC_NOWCHAR,
19659  getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19660  BST_CHECKED : BST_UNCHECKED);
19661  CheckDlgButton(hdlg, IDC_FKSUPPORT,
19662  getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19663  BST_CHECKED : BST_UNCHECKED);
19664  CheckDlgButton(hdlg, IDC_OEMCP,
19665  getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19666  BST_CHECKED : BST_UNCHECKED);
19667  CheckDlgButton(hdlg, IDC_BIGINT,
19668  getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19669  BST_CHECKED : BST_UNCHECKED);
19670  CheckDlgButton(hdlg, IDC_JDCONV,
19671  getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19672  BST_CHECKED : BST_UNCHECKED);
19673  SetDlgItemText(hdlg, IDC_ATTAS, setupdlg->attr[KEY_ATTAS].attr);
19674  CheckDlgButton(hdlg, IDC_ILIKE,
19675  getbool(setupdlg->attr[KEY_ILIKE].attr) ?
19676  BST_CHECKED : BST_UNCHECKED);
19677  SendDlgItemMessage(hdlg, IDC_SYNCP,
19678  CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19679  SendDlgItemMessage(hdlg, IDC_SYNCP,
19680  CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19681  SendDlgItemMessage(hdlg, IDC_SYNCP,
19682  CB_ADDSTRING, 0, (LPARAM) "OFF");
19683  SendDlgItemMessage(hdlg, IDC_SYNCP,
19684  CB_ADDSTRING, 0, (LPARAM) "FULL");
19685  SendDlgItemMessage(hdlg, IDC_SYNCP,
19686  CB_SELECTSTRING, (WPARAM) -1,
19687  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19688  if (setupdlg->defDSN) {
19689  EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19690  EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19691  }
19692  return TRUE;
19693  case WM_COMMAND:
19694  switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19695  case IDC_DSNAME:
19696  if (GET_WM_COMMAND_CMD(wparam, lparam) == EN_CHANGE) {
19697  char item[MAXDSNAME];
19698 
19699  EnableWindow(GetDlgItem(hdlg, IDOK),
19700  GetDlgItemText(hdlg, IDC_DSNAME,
19701  item, sizeof (item)));
19702  return TRUE;
19703  }
19704  break;
19705  case IDC_BROWSE:
19706  GetDBFile(hdlg);
19707  break;
19708  case IDOK:
19709 #ifdef _WIN64
19710  setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19711 #else
19712  setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19713 #endif
19714  if (!setupdlg->defDSN) {
19715  GetDlgItemText(hdlg, IDC_DSNAME,
19716  setupdlg->attr[KEY_DSN].attr,
19717  sizeof (setupdlg->attr[KEY_DSN].attr));
19718  }
19719  GetDlgItemText(hdlg, IDC_DESC,
19720  setupdlg->attr[KEY_DESC].attr,
19721  sizeof (setupdlg->attr[KEY_DESC].attr));
19722  GetDlgItemText(hdlg, IDC_DBNAME,
19723  setupdlg->attr[KEY_DBNAME].attr,
19724  sizeof (setupdlg->attr[KEY_DBNAME].attr));
19725  GetDlgItemText(hdlg, IDC_TONAME,
19726  setupdlg->attr[KEY_BUSY].attr,
19727  sizeof (setupdlg->attr[KEY_BUSY].attr));
19728  GetDlgItemText(hdlg, IDC_LOADEXT,
19729  setupdlg->attr[KEY_LOADEXT].attr,
19730  sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19731  index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19732  CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19733  if (index != (WORD) CB_ERR) {
19734  SendDlgItemMessage(hdlg, IDC_SYNCP,
19735  CB_GETLBTEXT, index,
19736  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19737  }
19738  strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19739  (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19740  "1" : "0");
19741  strcpy(setupdlg->attr[KEY_NOTXN].attr,
19742  (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19743  "1" : "0");
19744  strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19745  (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19746  "1" : "0");
19747  strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19748  (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19749  "1" : "0");
19750  strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19751  (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19752  "1" : "0");
19753  strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19754  (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19755  "1" : "0");
19756  strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19757  (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19758  "1" : "0");
19759  strcpy(setupdlg->attr[KEY_OEMCP].attr,
19760  (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19761  "1" : "0");
19762  strcpy(setupdlg->attr[KEY_BIGINT].attr,
19763  (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19764  "1" : "0");
19765  strcpy(setupdlg->attr[KEY_JDCONV].attr,
19766  (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19767  "1" : "0");
19768  GetDlgItemText(hdlg, IDC_ATTAS,
19769  setupdlg->attr[KEY_ATTAS].attr,
19770  sizeof (setupdlg->attr[KEY_ATTAS].attr));
19771  strcpy(setupdlg->attr[KEY_ILIKE].attr,
19772  (IsDlgButtonChecked(hdlg, IDC_ILIKE) == BST_CHECKED) ?
19773  "1" : "0");
19774  SetDSNAttributes(hdlg, setupdlg);
19775  /* FALL THROUGH */
19776  case IDCANCEL:
19777  EndDialog(hdlg, wparam);
19778  return TRUE;
19779  }
19780  break;
19781  }
19782  return FALSE;
19783 }
19784 
19794 BOOL INSTAPI
19795 ConfigDSN(HWND hwnd, WORD request, LPCSTR driver, LPCSTR attribs)
19796 {
19797  BOOL success;
19798  SETUPDLG *setupdlg;
19799 
19800  setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
19801  if (setupdlg == NULL) {
19802  return FALSE;
19803  }
19804  memset(setupdlg, 0, sizeof (SETUPDLG));
19805  if (attribs) {
19806  ParseAttributes(attribs, setupdlg);
19807  }
19808  if (setupdlg->attr[KEY_DSN].supplied) {
19809  strcpy(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr);
19810  } else {
19811  setupdlg->DSN[0] = '\0';
19812  }
19813  if (request == ODBC_REMOVE_DSN) {
19814  if (!setupdlg->attr[KEY_DSN].supplied) {
19815  success = FALSE;
19816  } else {
19817  success = SQLRemoveDSNFromIni(setupdlg->attr[KEY_DSN].attr);
19818  }
19819  } else {
19820  setupdlg->parent = hwnd;
19821  setupdlg->driver = driver;
19822  setupdlg->newDSN = request == ODBC_ADD_DSN;
19823  setupdlg->defDSN = strcasecmp(setupdlg->attr[KEY_DSN].attr,
19824  "Default") == 0;
19825  if (hwnd) {
19826  success = DialogBoxParam(hModule, MAKEINTRESOURCE(CONFIGDSN),
19827  hwnd, (DLGPROC) ConfigDlgProc,
19828  (LPARAM) setupdlg) == IDOK;
19829  } else if (setupdlg->attr[KEY_DSN].supplied) {
19830  success = SetDSNAttributes(hwnd, setupdlg);
19831  } else {
19832  success = FALSE;
19833  }
19834  }
19835  xfree(setupdlg);
19836  return success;
19837 }
19838 
19848 static BOOL CALLBACK
19849 DriverConnectProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19850 {
19851  SETUPDLG *setupdlg;
19852  WORD index;
19853 
19854  switch (wmsg) {
19855  case WM_INITDIALOG:
19856 #ifdef _WIN64
19857  SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19858 #else
19859  SetWindowLong(hdlg, DWL_USER, lparam);
19860 #endif
19861  setupdlg = (SETUPDLG *) lparam;
19862  SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19863  SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19864  SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19865  SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19866  SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19867  SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19868  (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19869  SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19870  (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19871  SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19872  (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19873  SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19874  (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19875  SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19876  (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19877  CheckDlgButton(hdlg, IDC_STEPAPI,
19878  getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19879  BST_CHECKED : BST_UNCHECKED);
19880  CheckDlgButton(hdlg, IDC_NOTXN,
19881  getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19882  BST_CHECKED : BST_UNCHECKED);
19883  CheckDlgButton(hdlg, IDC_SHORTNAM,
19884  getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19885  BST_CHECKED : BST_UNCHECKED);
19886  CheckDlgButton(hdlg, IDC_LONGNAM,
19887  getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19888  BST_CHECKED : BST_UNCHECKED);
19889  CheckDlgButton(hdlg, IDC_NOCREAT,
19890  getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19891  BST_CHECKED : BST_UNCHECKED);
19892  CheckDlgButton(hdlg, IDC_NOWCHAR,
19893  getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19894  BST_CHECKED : BST_UNCHECKED);
19895  CheckDlgButton(hdlg, IDC_FKSUPPORT,
19896  getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19897  BST_CHECKED : BST_UNCHECKED);
19898  CheckDlgButton(hdlg, IDC_OEMCP,
19899  getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19900  BST_CHECKED : BST_UNCHECKED);
19901  CheckDlgButton(hdlg, IDC_BIGINT,
19902  getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19903  BST_CHECKED : BST_UNCHECKED);
19904  CheckDlgButton(hdlg, IDC_JDCONV,
19905  getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19906  BST_CHECKED : BST_UNCHECKED);
19907  SendDlgItemMessage(hdlg, IDC_SYNCP,
19908  CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19909  SendDlgItemMessage(hdlg, IDC_SYNCP,
19910  CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19911  SendDlgItemMessage(hdlg, IDC_SYNCP,
19912  CB_ADDSTRING, 0, (LPARAM) "OFF");
19913  SendDlgItemMessage(hdlg, IDC_SYNCP,
19914  CB_ADDSTRING, 0, (LPARAM) "FULL");
19915  SendDlgItemMessage(hdlg, IDC_SYNCP,
19916  CB_SELECTSTRING, (WORD) -1,
19917  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19918  if (setupdlg->defDSN) {
19919  EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19920  EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19921  }
19922  SetDlgItemText(hdlg, IDC_ATTAS, setupdlg->attr[KEY_ATTAS].attr);
19923  CheckDlgButton(hdlg, IDC_ILIKE,
19924  getbool(setupdlg->attr[KEY_ILIKE].attr) ?
19925  BST_CHECKED : BST_UNCHECKED);
19926  return TRUE;
19927  case WM_COMMAND:
19928  switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19929  case IDC_BROWSE:
19930  GetDBFile(hdlg);
19931  break;
19932  case IDOK:
19933 #ifdef _WIN64
19934  setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19935 #else
19936  setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19937 #endif
19938  GetDlgItemText(hdlg, IDC_DSNAME,
19939  setupdlg->attr[KEY_DSN].attr,
19940  sizeof (setupdlg->attr[KEY_DSN].attr));
19941  GetDlgItemText(hdlg, IDC_DBNAME,
19942  setupdlg->attr[KEY_DBNAME].attr,
19943  sizeof (setupdlg->attr[KEY_DBNAME].attr));
19944  GetDlgItemText(hdlg, IDC_TONAME,
19945  setupdlg->attr[KEY_BUSY].attr,
19946  sizeof (setupdlg->attr[KEY_BUSY].attr));
19947  GetDlgItemText(hdlg, IDC_LOADEXT,
19948  setupdlg->attr[KEY_LOADEXT].attr,
19949  sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19950  index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19951  CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19952  if (index != (WORD) CB_ERR) {
19953  SendDlgItemMessage(hdlg, IDC_SYNCP,
19954  CB_GETLBTEXT, index,
19955  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19956  }
19957  strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19958  (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19959  "1" : "0");
19960  strcpy(setupdlg->attr[KEY_NOTXN].attr,
19961  (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19962  "1" : "0");
19963  strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19964  (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19965  "1" : "0");
19966  strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19967  (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19968  "1" : "0");
19969  strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19970  (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19971  "1" : "0");
19972  strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19973  (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19974  "1" : "0");
19975  strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19976  (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19977  "1" : "0");
19978  strcpy(setupdlg->attr[KEY_OEMCP].attr,
19979  (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19980  "1" : "0");
19981  strcpy(setupdlg->attr[KEY_BIGINT].attr,
19982  (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19983  "1" : "0");
19984  strcpy(setupdlg->attr[KEY_JDCONV].attr,
19985  (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19986  "1" : "0");
19987  GetDlgItemText(hdlg, IDC_ATTAS,
19988  setupdlg->attr[KEY_ATTAS].attr,
19989  sizeof (setupdlg->attr[KEY_ATTAS].attr));
19990  strcpy(setupdlg->attr[KEY_ILIKE].attr,
19991  (IsDlgButtonChecked(hdlg, IDC_ILIKE) == BST_CHECKED) ?
19992  "1" : "0");
19993  /* FALL THROUGH */
19994  case IDCANCEL:
19995  EndDialog(hdlg, GET_WM_COMMAND_ID(wparam, lparam) == IDOK);
19996  return TRUE;
19997  }
19998  }
19999  return FALSE;
20000 }
20001 
20015 static SQLRETURN
20016 drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
20017  SQLCHAR *connIn, SQLSMALLINT connInLen,
20018  SQLCHAR *connOut, SQLSMALLINT connOutMax,
20019  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
20020 {
20021  BOOL maybeprompt, prompt = FALSE, defaultdsn = FALSE;
20022  DBC *d;
20023  SETUPDLG *setupdlg;
20024  SQLRETURN ret;
20025  char *dsn = NULL, *driver = NULL, *dbname = NULL;
20026 
20027  if (dbc == SQL_NULL_HDBC) {
20028  return SQL_INVALID_HANDLE;
20029  }
20030  d = (DBC *) dbc;
20031  if (d->sqlite) {
20032  setstatd(d, -1, "connection already established", "08002");
20033  return SQL_ERROR;
20034  }
20035  setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
20036  if (setupdlg == NULL) {
20037  return SQL_ERROR;
20038  }
20039  memset(setupdlg, 0, sizeof (SETUPDLG));
20040  maybeprompt = drvcompl == SQL_DRIVER_COMPLETE ||
20041  drvcompl == SQL_DRIVER_COMPLETE_REQUIRED;
20042  if (connIn == NULL || !connInLen ||
20043  (connInLen == SQL_NTS && !connIn[0])) {
20044  prompt = TRUE;
20045  } else {
20046  ParseAttributes((LPCSTR) connIn, setupdlg);
20047  if (!setupdlg->attr[KEY_DSN].attr[0] &&
20048  drvcompl == SQL_DRIVER_COMPLETE_REQUIRED) {
20049  strcpy(setupdlg->attr[KEY_DSN].attr, "DEFAULT");
20050  defaultdsn = TRUE;
20051  }
20052  GetAttributes(setupdlg);
20053  if (drvcompl == SQL_DRIVER_PROMPT ||
20054  (maybeprompt &&
20055  !setupdlg->attr[KEY_DBNAME].attr[0])) {
20056  prompt = TRUE;
20057  }
20058  }
20059 retry:
20060  if (prompt) {
20061  short dlgret;
20062 
20063  setupdlg->defDSN = setupdlg->attr[KEY_DRIVER].attr[0] != '\0';
20064  dlgret = DialogBoxParam(hModule, MAKEINTRESOURCE(DRIVERCONNECT),
20065  hwnd, (DLGPROC) DriverConnectProc,
20066  (LPARAM) setupdlg);
20067 
20068  if (!dlgret || dlgret == -1) {
20069  xfree(setupdlg);
20070  return SQL_NO_DATA;
20071  }
20072  }
20073  dsn = setupdlg->attr[KEY_DSN].attr;
20074  driver = setupdlg->attr[KEY_DRIVER].attr;
20075  dbname = setupdlg->attr[KEY_DBNAME].attr;
20076  if (connOut || connOutLen) {
20077  char buf[SQL_MAX_MESSAGE_LENGTH * 8];
20078  int len, count;
20079  char dsn_0 = (dsn && !defaultdsn) ? dsn[0] : '\0';
20080  char drv_0 = driver ? driver[0] : '\0';
20081 
20082  buf[0] = '\0';
20083  count = snprintf(buf, sizeof (buf),
20084  "%s%s%s%s%s%sDatabase=%s;StepAPI=%s;"
20085  "SyncPragma=%s;NoTXN=%s;Timeout=%s;"
20086  "ShortNames=%s;LongNames=%s;"
20087  "NoCreat=%s;NoWCHAR=%s;"
20088  "FKSupport=%s;JournalMode=%s;OEMCP=%s;LoadExt=%s;"
20089  "BigInt=%s;JDConv=%s;PWD=%s;AttachAs=%s;ILike=%s",
20090  dsn_0 ? "DSN=" : "",
20091  dsn_0 ? dsn : "",
20092  dsn_0 ? ";" : "",
20093  drv_0 ? "Driver=" : "",
20094  drv_0 ? driver : "",
20095  drv_0 ? ";" : "",
20096  dbname ? dbname : "",
20097  setupdlg->attr[KEY_STEPAPI].attr,
20098  setupdlg->attr[KEY_SYNCP].attr,
20099  setupdlg->attr[KEY_NOTXN].attr,
20100  setupdlg->attr[KEY_BUSY].attr,
20101  setupdlg->attr[KEY_SHORTNAM].attr,
20102  setupdlg->attr[KEY_LONGNAM].attr,
20103  setupdlg->attr[KEY_NOCREAT].attr,
20104  setupdlg->attr[KEY_NOWCHAR].attr,
20105  setupdlg->attr[KEY_FKSUPPORT].attr,
20106  setupdlg->attr[KEY_JMODE].attr,
20107  setupdlg->attr[KEY_OEMCP].attr,
20108  setupdlg->attr[KEY_LOADEXT].attr,
20109  setupdlg->attr[KEY_BIGINT].attr,
20110  setupdlg->attr[KEY_JDCONV].attr,
20111  setupdlg->attr[KEY_PASSWD].attr,
20112  setupdlg->attr[KEY_ATTAS].attr,
20113  setupdlg->attr[KEY_ILIKE].attr);
20114  if (count < 0) {
20115  buf[sizeof (buf) - 1] = '\0';
20116  }
20117  len = min(connOutMax - 1, strlen(buf));
20118  if (connOut) {
20119  strncpy((char *) connOut, buf, len);
20120  connOut[len] = '\0';
20121  }
20122  if (connOutLen) {
20123  *connOutLen = len;
20124  }
20125  }
20126  if (dsn[0]) {
20127  char tracef[SQL_MAX_MESSAGE_LENGTH];
20128 
20129  tracef[0] = '\0';
20130  SQLGetPrivateProfileString(setupdlg->attr[KEY_DSN].attr,
20131  "tracefile", "", tracef,
20132  sizeof (tracef), ODBC_INI);
20133  if (tracef[0] != '\0') {
20134  d->trace = fopen(tracef, "a");
20135  }
20136  }
20137  d->nowchar = getbool(setupdlg->attr[KEY_NOWCHAR].attr);
20138  d->shortnames = getbool(setupdlg->attr[KEY_SHORTNAM].attr);
20139  d->longnames = getbool(setupdlg->attr[KEY_LONGNAM].attr);
20140  d->nocreat = getbool(setupdlg->attr[KEY_NOCREAT].attr);
20141  d->fksupport = getbool(setupdlg->attr[KEY_FKSUPPORT].attr);
20142  d->oemcp = getbool(setupdlg->attr[KEY_OEMCP].attr);
20143  d->dobigint = getbool(setupdlg->attr[KEY_BIGINT].attr);
20144  d->jdconv = getbool(setupdlg->attr[KEY_JDCONV].attr);
20145  d->ilike = getbool(setupdlg->attr[KEY_ILIKE].attr);
20146  d->pwdLen = strlen(setupdlg->attr[KEY_PASSWD].attr);
20147  d->pwd = (d->pwdLen > 0) ? setupdlg->attr[KEY_PASSWD].attr : NULL;
20148  ret = dbopen(d, dbname ? dbname : "", 0,
20149  dsn ? dsn : "",
20150  setupdlg->attr[KEY_STEPAPI].attr,
20151  setupdlg->attr[KEY_SYNCP].attr,
20152  setupdlg->attr[KEY_NOTXN].attr,
20153  setupdlg->attr[KEY_JMODE].attr,
20154  setupdlg->attr[KEY_BUSY].attr);
20155  if (ret != SQL_SUCCESS) {
20156  if (maybeprompt && !prompt) {
20157  prompt = TRUE;
20158  goto retry;
20159  }
20160  }
20161  memset(setupdlg->attr[KEY_PASSWD].attr, 0,
20162  sizeof (setupdlg->attr[KEY_PASSWD].attr));
20163  if (ret == SQL_SUCCESS) {
20164  dbloadext(d, setupdlg->attr[KEY_LOADEXT].attr);
20165  dbattas(d, setupdlg->attr[KEY_ATTAS].attr);
20166  }
20167  xfree(setupdlg);
20168  return ret;
20169 }
20170 
20171 #endif /* WITHOUT_DRIVERMGR */
20172 #endif /* _WIN32 || _WIN64 */
20173 
20174 #ifndef WINTERFACE
20175 
20188 SQLRETURN SQL_API
20189 SQLDriverConnect(SQLHDBC dbc, SQLHWND hwnd,
20190  SQLCHAR *connIn, SQLSMALLINT connInLen,
20191  SQLCHAR *connOut, SQLSMALLINT connOutMax,
20192  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
20193 {
20194  SQLRETURN ret;
20195 
20196  HDBC_LOCK(dbc);
20197  ret = drvdriverconnect(dbc, hwnd, connIn, connInLen,
20198  connOut, connOutMax, connOutLen, drvcompl);
20199  HDBC_UNLOCK(dbc);
20200  return ret;
20201 }
20202 #endif
20203 
20204 #ifdef WINTERFACE
20205 
20218 SQLRETURN SQL_API
20219 SQLDriverConnectW(SQLHDBC dbc, SQLHWND hwnd,
20220  SQLWCHAR *connIn, SQLSMALLINT connInLen,
20221  SQLWCHAR *connOut, SQLSMALLINT connOutMax,
20222  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
20223 {
20224  SQLRETURN ret;
20225  char *ci = NULL;
20226  SQLSMALLINT len = 0;
20227 
20228  HDBC_LOCK(dbc);
20229  if (connIn) {
20230 #if defined(_WIN32) || defined(_WIN64)
20231  if (connInLen == SQL_NTS) {
20232  connInLen = -1;
20233  }
20234  ci = uc_to_wmb(connIn, connInLen);
20235 #else
20236  ci = uc_to_utf(connIn, connInLen);
20237 #endif
20238  if (!ci) {
20239  DBC *d = (DBC *) dbc;
20240 
20241  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
20242  HDBC_UNLOCK(dbc);
20243  return SQL_ERROR;
20244  }
20245  }
20246  ret = drvdriverconnect(dbc, hwnd, (SQLCHAR *) ci, SQL_NTS,
20247  (SQLCHAR *) connOut, connOutMax, &len, drvcompl);
20248  HDBC_UNLOCK(dbc);
20249  uc_free(ci);
20250  if (ret == SQL_SUCCESS) {
20251  SQLWCHAR *co = NULL;
20252 
20253  if (connOut) {
20254  if (len > 0) {
20255 #if defined(_WIN32) || defined(_WIN64)
20256  co = wmb_to_uc((char *) connOut, len);
20257 #else
20258  co = uc_from_utf((SQLCHAR *) connOut, len);
20259 #endif
20260  if (co) {
20261  uc_strncpy(connOut, co, connOutMax / sizeof (SQLWCHAR));
20262  len = min(connOutMax / sizeof (SQLWCHAR), uc_strlen(co));
20263  uc_free(co);
20264  } else {
20265  len = 0;
20266  }
20267  }
20268  if (len <= 0) {
20269  len = 0;
20270  connOut[0] = 0;
20271  }
20272  } else {
20273  len = 0;
20274  }
20275  if (connOutLen) {
20276  *connOutLen = len;
20277  }
20278  }
20279  return ret;
20280 }
20281 #endif
20282 
20283 #if defined(_WIN32) || defined(_WIN64)
20284 
20293 BOOL APIENTRY
20294 LibMain(HANDLE hinst, DWORD reason, LPVOID reserved)
20295 {
20296  static int initialized = 0;
20297 
20298  switch (reason) {
20299  case DLL_PROCESS_ATTACH:
20300  if (!initialized++) {
20301  hModule = hinst;
20302 #ifdef WINTERFACE
20303  /* MS Access hack part 1 (reserved error -7748) */
20304  statSpec2P = statSpec2;
20305  statSpec3P = statSpec3;
20306 #endif
20307 #ifdef SQLITE_DYNLOAD
20308  dls_init();
20309 #endif
20310 #ifdef SQLITE_HAS_CODEC
20311  sqlite3_activate_see(SQLITE_ACTIVATION_KEY);
20312 #endif
20313  }
20314 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
20315  nvfs_init();
20316 #endif
20317  break;
20318  case DLL_THREAD_ATTACH:
20319  break;
20320  case DLL_PROCESS_DETACH:
20321  if (--initialized <= 0) {
20322 #ifdef SQLITE_DYNLOAD
20323  dls_fini();
20324 #endif
20325  }
20326  break;
20327  case DLL_THREAD_DETACH:
20328  break;
20329  default:
20330  break;
20331  }
20332  return TRUE;
20333 }
20334 
20343 int __stdcall
20344 DllMain(HANDLE hinst, DWORD reason, LPVOID reserved)
20345 {
20346  return LibMain(hinst, reason, reserved);
20347 }
20348 
20349 #ifndef WITHOUT_INSTALLER
20350 
20357 static BOOL
20358 InUnError(char *name)
20359 {
20360  WORD err = 1;
20361  DWORD code;
20362  char errmsg[301];
20363  WORD errlen, errmax = sizeof (errmsg) - 1;
20364  int sqlret;
20365  BOOL ret = FALSE;
20366 
20367  do {
20368  errmsg[0] = '\0';
20369  sqlret = SQLInstallerError(err, &code, errmsg, errmax, &errlen);
20370  if (SQL_SUCCEEDED(sqlret)) {
20371  MessageBox(NULL, errmsg, name,
20372  MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
20373  ret = TRUE;
20374  }
20375  err++;
20376  } while (sqlret != SQL_NO_DATA);
20377  return ret;
20378 }
20379 
20386 static BOOL
20387 InUn(int remove, char *cmdline)
20388 {
20389 #ifdef SQLITE_HAS_CODEC
20390  static char *drivername = "SQLite3 ODBC Driver (SEE)";
20391  static char *dsname = "SQLite3 SEE Datasource";
20392 #else
20393  static char *drivername = "SQLite3 ODBC Driver";
20394  static char *dsname = "SQLite3 Datasource";
20395 #endif
20396  char *dllname, *p;
20397  char dllbuf[301], path[301], driver[300], attr[300], inst[400];
20398  WORD pathmax = sizeof (path) - 1, pathlen;
20399  DWORD usecnt, mincnt;
20400  int quiet = 0;
20401 
20402  dllbuf[0] = '\0';
20403  GetModuleFileName(hModule, dllbuf, sizeof (dllbuf));
20404  p = strrchr(dllbuf, '\\');
20405  dllname = p ? (p + 1) : dllbuf;
20406  quiet = cmdline && strstr(cmdline, "quiet");
20407  if (SQLInstallDriverManager(path, pathmax, &pathlen)) {
20408  sprintf(driver, "%s;Driver=%s;Setup=%s;",
20409  drivername, dllname, dllname);
20410  p = driver;
20411  while (*p) {
20412  if (*p == ';') {
20413  *p = '\0';
20414  }
20415  ++p;
20416  }
20417  usecnt = 0;
20418  path[0] = '\0';
20419  SQLInstallDriverEx(driver, NULL, path, pathmax, NULL,
20420  ODBC_INSTALL_INQUIRY, &usecnt);
20421  pathlen = strlen(path);
20422  while (pathlen > 0 && path[pathlen - 1] == '\\') {
20423  --pathlen;
20424  path[pathlen] = '\0';
20425  }
20426  sprintf(driver, "%s;Driver=%s\\%s;Setup=%s\\%s;",
20427  drivername, path, dllname, path, dllname);
20428  p = driver;
20429  while (*p) {
20430  if (*p == ';') {
20431  *p = '\0';
20432  }
20433  ++p;
20434  }
20435  sprintf(inst, "%s\\%s", path, dllname);
20436  if (!remove && usecnt > 0) {
20437  /* first install try: copy over driver dll, keeping DSNs */
20438  if (GetFileAttributesA(dllbuf) != INVALID_FILE_ATTRIBUTES &&
20439  CopyFile(dllbuf, inst, 0)) {
20440  if (!quiet) {
20441  char buf[512];
20442 
20443  sprintf(buf, "%s replaced.", drivername);
20444  MessageBox(NULL, buf, "Info",
20445  MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20446  MB_SETFOREGROUND);
20447  }
20448  return TRUE;
20449  }
20450  }
20451  mincnt = remove ? 1 : 0;
20452  while (usecnt != mincnt) {
20453  if (!SQLRemoveDriver(driver, TRUE, &usecnt)) {
20454  break;
20455  }
20456  }
20457  if (remove) {
20458  if (usecnt && !SQLRemoveDriver(driver, TRUE, &usecnt)) {
20459  InUnError("SQLRemoveDriver");
20460  return FALSE;
20461  }
20462  if (!usecnt) {
20463  char buf[512];
20464 
20465  DeleteFile(inst);
20466  if (!quiet) {
20467  sprintf(buf, "%s uninstalled.", drivername);
20468  MessageBox(NULL, buf, "Info",
20469  MB_ICONINFORMATION |MB_OK | MB_TASKMODAL |
20470  MB_SETFOREGROUND);
20471  }
20472  }
20473  sprintf(attr, "DSN=%s;Database=;", dsname);
20474  p = attr;
20475  while (*p) {
20476  if (*p == ';') {
20477  *p = '\0';
20478  }
20479  ++p;
20480  }
20481  SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20482  return TRUE;
20483  }
20484  if (GetFileAttributesA(dllbuf) == INVALID_FILE_ATTRIBUTES) {
20485  return FALSE;
20486  }
20487  if (strcasecmp(dllbuf, inst) != 0 && !CopyFile(dllbuf, inst, 0)) {
20488  char buf[512];
20489 
20490  sprintf(buf, "Copy %s to %s failed.", dllbuf, inst);
20491  MessageBox(NULL, buf, "CopyFile",
20492  MB_ICONSTOP |MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
20493  return FALSE;
20494  }
20495  if (!SQLInstallDriverEx(driver, path, path, pathmax, &pathlen,
20496  ODBC_INSTALL_COMPLETE, &usecnt)) {
20497  InUnError("SQLInstallDriverEx");
20498  return FALSE;
20499  }
20500  sprintf(attr, "DSN=%s;Database=;", dsname);
20501  p = attr;
20502  while (*p) {
20503  if (*p == ';') {
20504  *p = '\0';
20505  }
20506  ++p;
20507  }
20508  SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20509  if (!SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN, drivername, attr)) {
20510  InUnError("SQLConfigDataSource");
20511  return FALSE;
20512  }
20513  if (!quiet) {
20514  char buf[512];
20515 
20516  sprintf(buf, "%s installed.", drivername);
20517  MessageBox(NULL, buf, "Info",
20518  MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20519  MB_SETFOREGROUND);
20520  }
20521  } else {
20522  InUnError("SQLInstallDriverManager");
20523  return FALSE;
20524  }
20525  return TRUE;
20526 }
20527 
20536 void CALLBACK
20537 install(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20538 {
20539  InUn(0, lpszCmdLine);
20540 }
20541 
20550 void CALLBACK
20551 uninstall(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20552 {
20553  InUn(1, lpszCmdLine);
20554 }
20555 
20556 #endif /* WITHOUT_INSTALLER */
20557 
20558 #ifndef WITHOUT_SHELL
20559 
20568 static void
20569 setargv(int *argcp, char ***argvp, char *cmdline, char *argv0)
20570 {
20571  char *p, *arg, *argspace, **argv;
20572  int argc, size, inquote, copy, slashes;
20573 
20574  size = 2 + (argv0 ? 1 : 0);
20575  for (p = cmdline; *p != '\0'; p++) {
20576  if (ISSPACE(*p)) {
20577  size++;
20578  while (ISSPACE(*p)) {
20579  p++;
20580  }
20581  if (*p == '\0') {
20582  break;
20583  }
20584  }
20585  }
20586  argspace = malloc(size * sizeof (char *) + strlen(cmdline) + 1);
20587  argv = (char **) argspace;
20588  argspace += size * sizeof (char *);
20589  size--;
20590  argc = 0;
20591  if (argv0) {
20592  argv[argc++] = argv0;
20593  }
20594  p = cmdline;
20595  for (; argc < size; argc++) {
20596  argv[argc] = arg = argspace;
20597  while (ISSPACE(*p)) {
20598  p++;
20599  }
20600  if (*p == '\0') {
20601  break;
20602  }
20603  inquote = 0;
20604  slashes = 0;
20605  while (1) {
20606  copy = 1;
20607  while (*p == '\\') {
20608  slashes++;
20609  p++;
20610  }
20611  if (*p == '"') {
20612  if ((slashes & 1) == 0) {
20613  copy = 0;
20614  if (inquote && p[1] == '"') {
20615  p++;
20616  copy = 1;
20617  } else {
20618  inquote = !inquote;
20619  }
20620  }
20621  slashes >>= 1;
20622  }
20623  while (slashes) {
20624  *arg = '\\';
20625  arg++;
20626  slashes--;
20627  }
20628  if (*p == '\0' || (!inquote && ISSPACE(*p))) {
20629  break;
20630  }
20631  if (copy != 0) {
20632  *arg = *p;
20633  arg++;
20634  }
20635  p++;
20636  }
20637  *arg = '\0';
20638  argspace = arg + 1;
20639  }
20640  argv[argc] = 0;
20641  *argcp = argc;
20642  *argvp = argv;
20643 }
20644 
20653 void CALLBACK
20654 shell(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20655 {
20656  int argc, needcon = 0;
20657  char **argv;
20658  extern int sqlite3_main(int, char **);
20659  static const char *name = "SQLite3 Shell";
20660  DWORD ftype0, ftype1, ftype2;
20661 
20662  ftype0 = GetFileType(GetStdHandle(STD_INPUT_HANDLE));
20663  ftype1 = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
20664  ftype2 = GetFileType(GetStdHandle(STD_ERROR_HANDLE));
20665  if (ftype0 != FILE_TYPE_DISK && ftype0 != FILE_TYPE_CHAR &&
20666  ftype0 != FILE_TYPE_PIPE) {
20667  fclose(stdin);
20668  ++needcon;
20669  ftype0 = FILE_TYPE_UNKNOWN;
20670  }
20671  if (ftype1 != FILE_TYPE_DISK && ftype1 != FILE_TYPE_CHAR &&
20672  ftype1 != FILE_TYPE_PIPE) {
20673  fclose(stdout);
20674  ++needcon;
20675  ftype1 = FILE_TYPE_UNKNOWN;
20676  }
20677  if (ftype2 != FILE_TYPE_DISK && ftype2 != FILE_TYPE_CHAR &&
20678  ftype2 != FILE_TYPE_PIPE) {
20679  fclose(stderr);
20680  ++needcon;
20681  ftype2 = FILE_TYPE_UNKNOWN;
20682  }
20683  if (needcon > 0) {
20684  AllocConsole();
20685  SetConsoleTitle(name);
20686  }
20687  if (ftype0 == FILE_TYPE_UNKNOWN) {
20688  freopen("CONIN$", "r", stdin);
20689  }
20690  if (ftype1 == FILE_TYPE_UNKNOWN) {
20691  freopen("CONOUT$", "w", stdout);
20692  }
20693  if (ftype2 == FILE_TYPE_UNKNOWN) {
20694  freopen("CONOUT$", "w", stderr);
20695  }
20696  setargv(&argc, &argv, lpszCmdLine, (char *) name);
20697 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
20698  nvfs_init();
20699 #endif
20700  sqlite3_main(argc, argv);
20701 }
20702 
20703 #endif /* WITHOUT_SHELL */
20704 
20705 #endif /* _WIN32 || _WIN64 */
20706 
20707 #if defined(HAVE_ODBCINSTEXT_H) && (HAVE_ODBCINSTEXT_H)
20708 
20709 /*
20710  * unixODBC property page for this driver,
20711  * may or may not work depending on unixODBC version.
20712  */
20713 
20714 #include <odbcinstext.h>
20715 
20716 int
20717 ODBCINSTGetProperties(HODBCINSTPROPERTY prop)
20718 {
20719  static const char *instYN[] = { "No", "Yes", NULL };
20720  static const char *syncPragma[] = { "NORMAL", "OFF", "FULL", NULL };
20721  static const char *jmPragma[] = {
20722  "DELETE", "PERSIST", "OFF", "TRUNCATE", "MEMORY", "WAL", NULL
20723  };
20724 
20725  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20726  prop = prop->pNext;
20727  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20728  prop->nPromptType = ODBCINST_PROMPTTYPE_FILENAME;
20729  strncpy(prop->szName, "Database", INI_MAX_PROPERTY_NAME);
20730  strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20731  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20732  prop = prop->pNext;
20733  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20734  prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20735  strncpy(prop->szName, "Timeout", INI_MAX_PROPERTY_NAME);
20736  strncpy(prop->szValue, "100000", INI_MAX_PROPERTY_VALUE);
20737  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20738  prop = prop->pNext;
20739  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20740  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20741  prop->aPromptData = malloc(sizeof (instYN));
20742  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20743  strncpy(prop->szName, "StepAPI", INI_MAX_PROPERTY_NAME);
20744  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20745  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20746  prop = prop->pNext;
20747  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20748  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20749  prop->aPromptData = malloc(sizeof (instYN));
20750  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20751  strncpy(prop->szName, "ShortNames", INI_MAX_PROPERTY_NAME);
20752  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20753  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20754  prop = prop->pNext;
20755  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20756  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20757  prop->aPromptData = malloc(sizeof (instYN));
20758  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20759  strncpy(prop->szName, "LongNames", INI_MAX_PROPERTY_NAME);
20760  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20761  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20762  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20763  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20764  prop->aPromptData = malloc(sizeof (instYN));
20765  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20766  strncpy(prop->szName, "NoCreat", INI_MAX_PROPERTY_NAME);
20767  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20768 #ifdef WINTERFACE
20769  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20770  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20771  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20772  prop->aPromptData = malloc(sizeof (instYN));
20773  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20774  strncpy(prop->szName, "NoWCHAR", INI_MAX_PROPERTY_NAME);
20775  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20776 #endif
20777  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20778  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20779  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20780  prop->aPromptData = malloc(sizeof (instYN));
20781  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20782  strncpy(prop->szName, "FKSupport", INI_MAX_PROPERTY_NAME);
20783  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20784  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20785  prop = prop->pNext;
20786  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20787  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20788  prop->aPromptData = malloc(sizeof (syncPragma));
20789  memcpy(prop->aPromptData, syncPragma, sizeof (syncPragma));
20790  strncpy(prop->szName, "SyncPragma", INI_MAX_PROPERTY_NAME);
20791  strncpy(prop->szValue, "NORMAL", INI_MAX_PROPERTY_VALUE);
20792  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20793  prop = prop->pNext;
20794  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20795  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20796  prop->aPromptData = malloc(sizeof (jmPragma));
20797  memcpy(prop->aPromptData, jmPragma, sizeof (jmPragma));
20798  strncpy(prop->szName, "JournalMode", INI_MAX_PROPERTY_NAME);
20799  strncpy(prop->szValue, "DELETE", INI_MAX_PROPERTY_VALUE);
20800  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20801  prop = prop->pNext;
20802  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20803  prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20804  strncpy(prop->szName, "LoadExt", INI_MAX_PROPERTY_NAME);
20805  strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20806  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20807  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20808  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20809  prop->aPromptData = malloc(sizeof (instYN));
20810  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20811  strncpy(prop->szName, "BigInt", INI_MAX_PROPERTY_NAME);
20812  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20813  return 1;
20814 }
20815 
20816 #endif /* HAVE_ODBCINSTEXT_H */
20817 
20818 #ifdef SQLITE_DYNLOAD
20819 
20820 /*
20821  * SQLite3 shared library/DLL stubs.
20822  */
20823 
20824 static void
20825 dls_void(void)
20826 {
20827 }
20828 
20829 static int
20830 dls_error(void)
20831 {
20832  return SQLITE_ERROR;
20833 }
20834 
20835 static int
20836 dls_0(void)
20837 {
20838  return 0;
20839 }
20840 
20841 static sqlite_int64
20842 dls_0LL(void)
20843 {
20844  return 0;
20845 }
20846 
20847 static double
20848 dls_00(void)
20849 {
20850  return 0;
20851 }
20852 
20853 static void *
20854 dls_null(void)
20855 {
20856  return NULL;
20857 }
20858 
20859 static const char *
20860 dls_empty(void)
20861 {
20862  return "";
20863 }
20864 
20865 static int
20866 dls_snull(void)
20867 {
20868  return SQLITE_NULL;
20869 }
20870 
20871 #define DLS_ENT(name, func) \
20872  { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, name), \
20873  (void *) func }
20874 
20875 #define DLS_ENT3(name, off, func) \
20876  { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, off), \
20877  (void *) func }
20878 
20879 #define DLS_END { NULL, 0, NULL }
20880 
20881 static struct {
20882  const char *name;
20883  int offset;
20884  void *func;
20885 } dls_nametab[] = {
20886  DLS_ENT(activate_see, dls_void),
20887  DLS_ENT(bind_blob, dls_error),
20888  DLS_ENT(bind_double, dls_error),
20889  DLS_ENT(bind_int, dls_error),
20890  DLS_ENT(bind_int64, dls_error),
20891  DLS_ENT(bind_null, dls_error),
20892  DLS_ENT(bind_parameter_count, dls_0),
20893  DLS_ENT(bind_text, dls_error),
20894  DLS_ENT(busy_handler, dls_error),
20895  DLS_ENT(changes, dls_0),
20896  DLS_ENT(close, dls_error),
20897  DLS_ENT(column_blob, dls_null),
20898  DLS_ENT(column_bytes, dls_0),
20899  DLS_ENT(column_count, dls_0),
20900  DLS_ENT(column_database_name, dls_empty),
20901  DLS_ENT(column_decltype, dls_empty),
20902  DLS_ENT(column_double, dls_00),
20903  DLS_ENT(column_name, dls_empty),
20904  DLS_ENT(column_origin_name, dls_null),
20905  DLS_ENT(column_table_name, dls_null),
20906  DLS_ENT(column_text, dls_null),
20907  DLS_ENT(column_type, dls_snull),
20908  DLS_ENT(create_function, dls_error),
20909  DLS_ENT(enable_load_extension, dls_error),
20910  DLS_ENT(errcode, dls_error),
20911  DLS_ENT(errmsg, dls_empty),
20912  DLS_ENT(exec, dls_error),
20913  DLS_ENT(finalize, dls_error),
20914  DLS_ENT(free, free),
20915  DLS_ENT(free_table, dls_void),
20916  DLS_ENT(get_table, dls_error),
20917  DLS_ENT(interrupt, dls_void),
20918  DLS_ENT(key, dls_error),
20919  DLS_ENT(last_insert_rowid, dls_0LL),
20920  DLS_ENT(libversion, dls_empty),
20921  DLS_ENT(load_extension, dls_error),
20922  DLS_ENT(malloc, malloc),
20923  DLS_ENT(mprintf, dls_null),
20924  DLS_ENT(open, dls_error),
20925  DLS_ENT(open16, dls_error),
20926  DLS_ENT(open_v2, dls_error),
20927  DLS_ENT(prepare, dls_error),
20928  DLS_ENT(prepare_v2, dls_error),
20929  DLS_ENT(profile, dls_null),
20930  DLS_ENT(realloc, realloc),
20931  DLS_ENT(rekey, dls_error),
20932  DLS_ENT(reset, dls_error),
20933  DLS_ENT(result_blob, dls_void),
20934  DLS_ENT(result_error, dls_void),
20935  DLS_ENT(result_int, dls_void),
20936  DLS_ENT(result_null, dls_void),
20937  DLS_ENT(step, dls_error),
20938 #if defined(_WIN32) || defined(_WIN64)
20939  DLS_ENT3(strnicmp, xstrnicmp, _strnicmp),
20940 #else
20941  DLS_ENT3(strnicmp, xstrnicmp, strncasecmp),
20942 #endif
20943  DLS_ENT(table_column_metadata, dls_error),
20944  DLS_ENT(trace, dls_null),
20945  DLS_ENT(user_data, dls_null),
20946  DLS_ENT(value_blob, dls_null),
20947  DLS_ENT(value_bytes, dls_0),
20948  DLS_ENT(value_text, dls_empty),
20949  DLS_ENT(value_type, dls_snull),
20950  DLS_END
20951 };
20952 
20953 #if defined(_WIN32) || defined(_WIN64)
20954 
20955 static HMODULE sqlite3_dll = 0;
20956 
20957 static void
20958 dls_init(void)
20959 {
20960  int i;
20961  static const char *dll_names[] = {
20962  "System.Data.SQLite.dll",
20963  "sqlite3.dll",
20964  NULL,
20965  };
20966 
20967  i = 0;
20968  while (dll_names[i]) {
20969  sqlite3_dll = LoadLibrary(dll_names[i]);
20970  if (sqlite3_dll) {
20971  break;
20972  }
20973  ++i;
20974  }
20975  i = 0;
20976  while (dls_nametab[i].name) {
20977  void *func = 0, **loc;
20978 
20979  if (sqlite3_dll) {
20980  func = (void *) GetProcAddress(sqlite3_dll, dls_nametab[i].name);
20981  }
20982  if (!func) {
20983  func = dls_nametab[i].func;
20984  }
20985  loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
20986  *loc = func;
20987  ++i;
20988  }
20989  if (!sqlite3_dll) {
20990  char buf[MAXPATHLEN], msg[MAXPATHLEN];
20991 
20992  LoadString(hModule, IDS_DRVTITLE, buf, sizeof (buf));
20993  LoadString(hModule, IDS_DLLERR, msg, sizeof (msg));
20994  MessageBox(NULL, msg, buf,
20995  MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
20996  MB_SETFOREGROUND);
20997  }
20998 }
20999 
21000 static void
21001 dls_fini(void)
21002 {
21003  if (sqlite3_dll) {
21004  FreeLibrary(sqlite3_dll);
21005  sqlite3_dll = 0;
21006  }
21007 }
21008 
21009 #else
21010 
21011 #include <dlfcn.h>
21012 
21013 static void *libsqlite3_so = 0;
21014 
21015 void
21016 dls_init(void)
21017 {
21018  int i;
21019 
21020  libsqlite3_so = dlopen("libsqlite3.so.0", RTLD_NOW | RTLD_GLOBAL);
21021  i = 0;
21022  while (dls_nametab[i].name) {
21023  void *func = 0, **loc;
21024 
21025  if (libsqlite3_so) {
21026  func = dlsym(libsqlite3_so, dls_nametab[i].name);
21027  }
21028  if (!func) {
21029  func = dls_nametab[i].func;
21030  }
21031  loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
21032  *loc = func;
21033  ++i;
21034  }
21035  if (!libsqlite3_so) {
21036  const char errmsg[] = "SQLite3 shared library not found.\n";
21037 
21038  write(2, errmsg, sizeof (errmsg) - 1);
21039  }
21040 }
21041 
21042 void
21043 dls_fini(void)
21044 {
21045  if (libsqlite3_so) {
21046  dlclose(libsqlite3_so);
21047  libsqlite3_so = 0;
21048  }
21049 }
21050 
21051 #endif
21052 
21053 #endif
21054 
21055 /*
21056  * Local Variables:
21057  * mode: c
21058  * c-basic-offset: 4
21059  * fill-column: 78
21060  * tab-width: 8
21061  * End:
21062  */
sqlite3_stmt * s3stmt
SQLite statement handle or NULL.
Definition: sqlite3odbc.h:286
SQLULEN paramset_size
SQL_ATTR_PARAMSET_SIZE.
Definition: sqlite3odbc.h:273
sqlite_int64 s3lival
SQLite3 64bit integer value.
Definition: sqlite3odbc.h:222
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:5723
void * parbuf
Buffer for SQL_LEN_DATA_AT_EXEC etc.
Definition: sqlite3odbc.h:216
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:6000
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:9886
static SQLRETURN nomem(STMT *s)
Report S1000 (out of memory) SQL error given STMT.
Definition: sqlite3odbc.c:1815
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:2828
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:2153
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:1690
struct dbc * dbcs
Pointer to first DBC.
Definition: sqlite3odbc.h:103
void * param0
Parameter buffer, initial value.
Definition: sqlite3odbc.h:211
int * ov3
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:237
static SQLRETURN freeparams(STMT *s)
Clear out parameter bindings, if any.
Definition: sqlite3odbc.c:5143
int dobigint
Force SQL_BIGINT for INTEGER columns.
Definition: sqlite3odbc.h:264
SQLCHAR * query
Current query, raw string.
Definition: sqlite3odbc.h:236
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:292
SQLRETURN SQL_API SQLForeignKeysW(SQLHSTMT stmt, SQLWCHAR *PKcatalog, SQLSMALLINT PKcatalogLen, SQLWCHAR *PKschema, SQLSMALLINT PKschemaLen, SQLWCHAR *PKtable, SQLSMALLINT PKtableLen, SQLWCHAR *FKcatalog, SQLSMALLINT FKcatalogLen, SQLWCHAR *FKschema, SQLSMALLINT FKschemaLen, SQLWCHAR *FKtable, SQLSMALLINT FKtableLen)
Retrieve information about primary/foreign keys (UNICODE version).
Definition: sqlite3odbc.c:8058
static 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:5757
static SQLRETURN drvfreeconnect(SQLHDBC dbc)
Internal free connection (HDBC).
SQLCHAR logmsg[1024]
Message for SQLError()
Definition: sqlite3odbc.h:262
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:258
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:3754
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:177
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:280
void * s3val
SQLite3 value buffer.
Definition: sqlite3odbc.h:220
static int str2time(int jdconv, char *str, TIME_STRUCT *ts)
Convert string to ODBC TIME_STRUCT.
Definition: sqlite3odbc.c:3285
Internal structure for bound column (SQLBindCol).
Definition: sqlite3odbc.h:189
static COL pkeySpec2[]
Columns for result set of SQLPrimaryKeys().
Definition: sqlite3odbc.c:6653
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:7497
static void freedyncols(STMT *s)
Free dynamically allocated column descriptions of STMT.
int nrows
Number of result rows.
Definition: sqlite3odbc.h:255
static int mapsqltype(const char *typename, int *nosign, int ov3, int nowchar, int dobigint)
Map SQL field type from string to ODBC integer type code.
Definition: sqlite3odbc.c:2179
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:2303
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:272
int s3ival
SQLite3 integer value.
Definition: sqlite3odbc.h:221
struct stmt * cur_s3stmt
Current STMT executing sqlite statement.
Definition: sqlite3odbc.h:143
int need
True when SQL_LEN_DATA_AT_EXEC.
Definition: sqlite3odbc.h:213
static int checkddl(char *sql)
Check if query is a DDL statement.
Definition: sqlite3odbc.c:2474
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:8967
SQLULEN parm_bind_type
SQL_ATTR_PARAM_BIND_TYPE.
Definition: sqlite3odbc.h:284
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:271
SQLRETURN SQL_API SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen, SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
Translate SQL string (UNICODE version).
Definition: sqlite3odbc.c:8384
static SQLRETURN drvallocenv(SQLHENV *env)
Internal allocate HENV.
static COL procSpec2[]
Columns for result set of SQLProcedures().
Definition: sqlite3odbc.c:8419
char sqlstate[6]
SQL state for SQLError()
Definition: sqlite3odbc.h:261
static SQLRETURN drvprimarykeys(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen)
Internal retrieve information about indexed columns.
Definition: sqlite3odbc.c:6684
int inc
Increment for paramset size > 1.
Definition: sqlite3odbc.h:212
SQLLEN max
Max.
Definition: sqlite3odbc.h:207
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:4669
SQLRETURN SQL_API SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno, SQLSMALLINT fieldid, SQLPOINTER value, SQLINTEGER buflen)
Function not implemented.
Definition: sqlite3odbc.c:5953
#define SQL_API
Definition: sqlite3odbc.h:58
char * column
Column name.
Definition: sqlite3odbc.h:168
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:234
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:232
SQLRETURN SQL_API SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len, SQLINTEGER *lenp)
Get information of HENV.
Definition: sqlite3odbc.c:8623
SQLUINTEGER paramset_nrows
Row count for paramset handling.
Definition: sqlite3odbc.h:275
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:9645
int isrowid
Flag for ROWID column (> 0)
Definition: sqlite3odbc.h:178
SQLRETURN SQL_API SQLGetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
Get option of HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9717
int prec
Precision of column.
Definition: sqlite3odbc.h:174
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:8596
static void dbtrace(void *arg, const char *msg, sqlite_uint64 et)
SQLite trace or profile callback.
Definition: sqlite3odbc.c:3889
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:8309
static void blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function to export a BLOB to a file.
Definition: sqlite3odbc.c:3824
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:8525
static double ln_strtod(const char *data, char **endp)
Internal locale neutral strtod function.
Definition: sqlite3odbc.c:1844
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:4908
#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:2388
static SQLRETURN SQL_API drvforeignkeys(SQLHSTMT stmt, SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen, SQLCHAR *PKschema, SQLSMALLINT PKschemaLen, SQLCHAR *PKtable, SQLSMALLINT PKtableLen, SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen, SQLCHAR *FKschema, SQLSMALLINT FKschemaLen, SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
Internal retrieve information about primary/foreign keys.
Definition: sqlite3odbc.c:7550
int pool
True for SQL_CP_ONE_PER_DRIVER.
Definition: sqlite3odbc.h:99
BINDPARM * bindparms
Array of bound parameters.
Definition: sqlite3odbc.h:252
#define SETSTMTOPTION_LAST_ARG_TYPE
Definition: sqlite3odbc.c:221
int ilike
True for ILIKE fixup.
Definition: sqlite3odbc.h:142
COL * cols
Result column array.
Definition: sqlite3odbc.h:243
#define DBC_MAGIC
Definition: sqlite3odbc.c:263
static SQLRETURN noconn(STMT *s)
Report S1000 (not connected) SQL error given STMT.
Definition: sqlite3odbc.c:1828
SQLULEN bind_type
SQL_ATTR_ROW_BIND_TYPE.
Definition: sqlite3odbc.h:277
SQLRETURN SQL_API SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
Put (partial) parameter data into executing statement.
Definition: sqlite3odbc.c:5127
SQLRETURN SQL_API SQLBindParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT vtype, SQLSMALLINT ptype, SQLULEN lenprec, SQLSMALLINT scale, SQLPOINTER val, SQLLEN *lenp)
Bind parameter on HSTMT.
Definition: sqlite3odbc.c:5674
SQLRETURN SQL_API SQLCopyDesc(SQLHDESC source, SQLHDESC target)
Function not implemented.
Definition: sqlite3odbc.c:8322
static SQLRETURN mkresultset(HSTMT stmt, COL *colspec, int ncols, COL *colspec3, int ncols3, int *nret)
Setup empty result set from constant column specification.
Definition: sqlite3odbc.c:6021
SQLPOINTER valp
Value buffer.
Definition: sqlite3odbc.h:193
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:9166
static int namematch(char *str, char *pat, int esc)
SQL LIKE string match with optional backslash escape handling.
Definition: sqlite3odbc.c:1948
static void replilike(char *sql)
Replace ILIKE with LIKE in-place given query string.
Definition: sqlite3odbc.c:2766
SQLUSMALLINT * parm_oper
SQL_ATTR_PARAM_OPERATION_PTR.
Definition: sqlite3odbc.h:281
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:8295
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).
static void dbattas(DBC *d, char *attas)
Perform ATTACH commands to same database file.
Definition: sqlite3odbc.c:4263
int s3stmt_needmeta
True to get meta data in s3stmt_step().
Definition: sqlite3odbc.h:144
int rowprs
Current start row of rowset.
Definition: sqlite3odbc.h:257
char * table
Table name.
Definition: sqlite3odbc.h:167
SQLRETURN SQL_API SQLDescribeParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT *dtype, SQLULEN *size, SQLSMALLINT *decdigits, SQLSMALLINT *nullable)
Return information about parameter.
Definition: sqlite3odbc.c:5811
static SQLRETURN 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:288
static COL tablePrivSpec2[]
Columns for result set of SQLTablePrivileges().
Definition: sqlite3odbc.c:6063
static SQLRETURN drvtableprivileges(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen)
Retrieve privileges on tables and/or views.
Definition: sqlite3odbc.c:6096
int * jdconv
True for julian day conversion.
Definition: sqlite3odbc.h:239
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:6516
SQLUSMALLINT row_status1
Internal status array for 1 row rowsets.
Definition: sqlite3odbc.h:270
SQLLEN * lenp
Value return, actual size of value buffer.
Definition: sqlite3odbc.h:192
SQLULEN retr_data
SQL_ATTR_RETRIEVE_DATA.
Definition: sqlite3odbc.h:266
int longnames
Don&#39;t shorten column names.
Definition: sqlite3odbc.h:265
int index
Index of column in result.
Definition: sqlite3odbc.h:194
static SQLRETURN chkunbound(STMT *s)
Check for unbound result columns.
Definition: sqlite3odbc.c:9855
static void freep(void *x)
Free memory given pointer to memory pointer.
Definition: sqlite3odbc.c:1800
static void fixupdyncols(STMT *s, DBC *d)
Fixup column information for a running statement.
Definition: sqlite3odbc.c:2859
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:172
static int getmdays(int year, int month)
Return number of month days.
Definition: sqlite3odbc.c:3136
static COL tablePrivSpec3[]
Definition: sqlite3odbc.c:6073
SQLSMALLINT type
ODBC type.
Definition: sqlite3odbc.h:190
SQLRETURN SQL_API SQLPrimaryKeysW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen)
Retrieve information about indexed columns (UNICODE version).
Definition: sqlite3odbc.c:7012
SQLRETURN SQL_API SQLSpecialColumnsW(SQLHSTMT stmt, SQLUSMALLINT id, SQLWCHAR *cat, SQLSMALLINT catLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen, SQLUSMALLINT scope, SQLUSMALLINT nullable)
Retrieve information about indexed columns (UNICODE version).
Definition: sqlite3odbc.c:7450
static int str2date(int jdconv, char *str, DATE_STRUCT *ds)
Convert string to ODBC DATE_STRUCT.
Definition: sqlite3odbc.c:3170
static COL procSpec3[]
Definition: sqlite3odbc.c:8430
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:6573
#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:9815
SQLRETURN SQL_API SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SETSTMTOPTION_LAST_ARG_TYPE param)
Set option on HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9836
double s3dval
SQLite3 float value.
Definition: sqlite3odbc.h:223
static int drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp, int *ncolp, char **errp, int nparam, BINDPARM *p)
Definition: sqlite3odbc.c:1512
Internal structure for managing driver&#39;s sqlite3_get_table() implementation.
Definition: sqlite3odbc.c:1374
int pwdLen
Length of password.
Definition: sqlite3odbc.h:147
static void unbindcols(STMT *s)
Reset bound columns to unbound state.
static COL scolSpec2[]
Columns for result set of SQLSpecialColumns().
Definition: sqlite3odbc.c:7057
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:242
#define WCHARSUPPORT
Definition: sqlite3odbc.c:185
SQLUSMALLINT * row_status
Row status pointer.
Definition: sqlite3odbc.h:268
SQLRETURN SQL_API SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *ncols)
Return number of columns of result set given HSTMT.
static COL pkeySpec3[]
Definition: sqlite3odbc.c:6662
static int busy_handler(void *udata, int count)
Busy callback for SQLite.
Definition: sqlite3odbc.c:2021
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:235
static int str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
Convert string to ODBC TIMESTAMP_STRUCT.
Definition: sqlite3odbc.c:3406
static SQLRETURN starttran(STMT *s)
Start transaction when autocommit off.
Definition: sqlite3odbc.c:8136
static int s3stmt_step(STMT *s)
Do one sqlite statement step gathering one result row.
Definition: sqlite3odbc.c:4397
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:233
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:290
static SQLRETURN setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp)
static COL procColSpec2[]
Columns for result set of SQLProcedureColumns().
Definition: sqlite3odbc.c:8503
static SQLRETURN drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER buflen)
Internal set option on HSTMT.
Definition: sqlite3odbc.c:9437
SQLINTEGER * bkmrkptr
SQL_ATTR_FETCH_BOOKMARK_PTR.
Definition: sqlite3odbc.h:247
int notnull
NOT NULL constraint on column.
Definition: sqlite3odbc.h:176
int timeout
Lock timeout value.
Definition: sqlite3odbc.h:120
SQLULEN max_rows
SQL_ATTR_MAX_ROWS.
Definition: sqlite3odbc.h:276
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:3927
SQLRETURN SQL_API SQLDriversW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *drvdesc, SQLSMALLINT descmax, SQLSMALLINT *desclenp, SQLWCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
Function not implemented.
Definition: sqlite3odbc.c:4850
int coldef
Definition: sqlite3odbc.h:206
static int getbool(char *string)
Get boolean flag from string.
Definition: sqlite3odbc.c:3738
SQLRETURN SQL_API SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Get option of HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9415
char * label
Column label or NULL.
Definition: sqlite3odbc.h:180
SQLRETURN SQL_API SQLFreeEnv(SQLHENV env)
Free HENV.
int type
Data type of column.
Definition: sqlite3odbc.h:169
SQLRETURN SQL_API SQLGetDescRecW(SQLHDESC handle, SQLSMALLINT recno, SQLWCHAR *name, SQLSMALLINT buflen, SQLSMALLINT *strlen, SQLSMALLINT *type, SQLSMALLINT *subtype, SQLLEN *len, SQLSMALLINT *prec, SQLSMALLINT *scale, SQLSMALLINT *nullable)
Function not implemented.
Definition: sqlite3odbc.c:5984
int nowchar[2]
Don&#39;t try to use WCHAR.
Definition: sqlite3odbc.h:263
static const char upper_chars[]
Definition: sqlite3odbc.c:546
int s3size
SQLite3 size.
Definition: sqlite3odbc.h:219
static SQLRETURN setupparam(STMT *s, char *sql, int pnum)
Setup SQLite3 parameter for statement parameter.
Definition: sqlite3odbc.c:5168
#define stringify(s)
Definition: sqlite3odbc.c:236
int binlen
Length of blob data.
Definition: sqlite3odbc.h:291
#define SCOL_VARCHAR
Definition: sqlite3odbc.c:255
SQLLEN * lenp0
Actual size of parameter buffer, initial value.
Definition: sqlite3odbc.h:209
int * oemcp
True for Win32 OEM CP translation.
Definition: sqlite3odbc.h:238
static SQLRETURN drvunimpldbc(HDBC dbc)
Report IM001 (not implemented) SQL error code for HDBC.
Definition: sqlite3odbc.c:1763
SQLUSMALLINT * row_status0
Internal status array.
Definition: sqlite3odbc.h:269
#define SCOL_CHAR
Definition: sqlite3odbc.c:256
static void s3stmt_end_if(STMT *s)
Conditionally stop running sqlite statement.
Definition: sqlite3odbc.c:4697
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:191
static int setsqliteopts(sqlite3 *x, DBC *d)
Set SQLite options (PRAGMAs) given SQLite handle.
Definition: sqlite3odbc.c:2096
int nbindcols
Number of entries in bindcols.
Definition: sqlite3odbc.h:250
int isselect
0 if query is a SELECT statement
Definition: sqlite3odbc.h:241
SQLLEN * lenp
Actual size of parameter buffer.
Definition: sqlite3odbc.h:208
SQLRETURN SQL_API SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
Get option of HSTMT.
Definition: sqlite3odbc.c:9697
static SQLRETURN drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
Internal set option on HSTMT.
Definition: sqlite3odbc.c:9737
char * pwd
Password or NULL.
Definition: sqlite3odbc.h:146
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:145
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:9624
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:175
SQLRETURN SQL_API SQLSetScrollOptions(SQLHSTMT stmt, SQLUSMALLINT concur, SQLLEN rowkeyset, SQLUSMALLINT rowset)
Function not implemented.
static SQLRETURN endtran(DBC *d, SQLSMALLINT comptype, int force)
Internal commit or rollback transaction.
Definition: sqlite3odbc.c:8179
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:4886
char * db
Database name.
Definition: sqlite3odbc.h:166
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:8889
char sqlstate[6]
SQL state for SQLError()
Definition: sqlite3odbc.h:129
int bound
True when SQLBindParameter() called.
Definition: sqlite3odbc.h:214
static void dbloadext(DBC *d, char *exts)
Load SQLite extension modules, if any.
Definition: sqlite3odbc.c:4185
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:210
int one_tbl
Flag for single table (> 0)
Definition: sqlite3odbc.h:293
SQLRETURN SQL_API SQLGetData(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type, SQLPOINTER val, SQLLEN len, SQLLEN *lenp)
Retrieve row data after fetch.
static int TOLOWER(int c)
Definition: sqlite3odbc.c:550
static COL tableSpec3[]
int * ilike
True for ILIKE fixup.
Definition: sqlite3odbc.h:240
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:285
#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:206
COL * dyncols
Column array, but malloc()ed.
Definition: sqlite3odbc.h:244
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:5645
int index
Index of column in result.
Definition: sqlite3odbc.h:171
int bkmrk
True when bookmarks used.
Definition: sqlite3odbc.h:246
SQLULEN * parm_proc
SQL_ATTR_PARAMS_PROCESSED_PTR.
Definition: sqlite3odbc.h:283
SQLULEN * bind_offs
SQL_ATTR_ROW_BIND_OFFSET_PTR.
Definition: sqlite3odbc.h:278
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:3079
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:5876
static COL colPrivSpec2[]
Columns for result set of SQLColumnPrivileges().
Definition: sqlite3odbc.c:6563
int size
Size of column.
Definition: sqlite3odbc.h:170
static COL scolSpec3[]
Definition: sqlite3odbc.c:7069
static SQLRETURN drvunimplstmt(HSTMT stmt)
Report IM001 (not implemented) SQL error code for HSTMT.
Definition: sqlite3odbc.c:1782
struct dstr dstr
SQLRETURN SQL_API SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
Set information in HENV.
Definition: sqlite3odbc.c:8692
static char * s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
Find out column type.
Definition: sqlite3odbc.c:4304
SQLRETURN SQL_API SQLDataSourcesW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *srvname, SQLSMALLINT buflen1, SQLSMALLINT *lenp1, SQLWCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
Function not implemented.
Definition: sqlite3odbc.c:4816
#define max(a, b)
Definition: sqlite3odbc.c:227
BINDCOL * bindcols
Array of bound columns.
Definition: sqlite3odbc.h:249
int rowp
Current result row.
Definition: sqlite3odbc.h:256
#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:5925
int ov3val
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:124
int scale
Scale of column.
Definition: sqlite3odbc.h:173
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:179
SQLUSMALLINT * parm_status
SQL_ATTR_PARAMS_STATUS_PTR.
Definition: sqlite3odbc.h:282
static SQLRETURN s3stmt_start(STMT *s)
Start sqlite statement for execution of SELECT statement.
Definition: sqlite3odbc.c:4736
int jdconv
True for julian day conversion.
Definition: sqlite3odbc.h:141
int has_rowid
Flag for ROWID (>= 0 or -1)
Definition: sqlite3odbc.h:295
BINDCOL bkmrkcol
Bookmark bound column.
Definition: sqlite3odbc.h:248
SQLULEN rowset_size
Size of rowset.
Definition: sqlite3odbc.h:267
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:5697
char strbuf[64]
String buffer for scalar data.
Definition: sqlite3odbc.h:217
static COL fkeySpec3[]
Definition: sqlite3odbc.c:7514
int oemcp
True for Win32 OEM CP translation.
Definition: sqlite3odbc.h:140
void(* rowfree)(char **)
Free function for rows.
Definition: sqlite3odbc.h:259
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:8238
char * bincell
Cache for blob data.
Definition: sqlite3odbc.h:289
int nparams
Number of parameters in query.
Definition: sqlite3odbc.h:253
static void setstat(STMT *s, int naterr, char *msg, char *st,...)
Set error message and SQL state on statement.
Definition: sqlite3odbc.c:1730
int stype
ODBC and SQL types.
Definition: sqlite3odbc.h:205
Internal structure for bound parameter (SQLBindParameter).
Definition: sqlite3odbc.h:204
static void s3stmt_drop(STMT *s)
Drop running sqlite statement in STMT.
Definition: sqlite3odbc.c:4715
int nbindparms
Number bound parameters.
Definition: sqlite3odbc.h:251
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:165
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:294
static SQLRETURN drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Internal get option of HSTMT.
Definition: sqlite3odbc.c:9242
static SQLRETURN dbopen(DBC *d, char *name, int isu, char *dsn, char *sflag, char *spflag, char *ntflag, char *jmode, char *busy)
Open SQLite database file given file name and flags.
Definition: sqlite3odbc.c:3971
static int uc_strlen(SQLWCHAR *str)
Return length of UNICODE string.
Definition: sqlite3odbc.c:800
int offs
Byte offset for SQLGetData()
Definition: sqlite3odbc.h:195
struct tblres TBLRES
SQLULEN paramset_count
Internal for paramset.
Definition: sqlite3odbc.h:274
int pdcount
SQLParamData() counter.
Definition: sqlite3odbc.h:254
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:1883
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:6632
static void convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
Convert julian day to hour/minute/second.
Definition: sqlite3odbc.c:3107
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:287
static void dbtracerc(DBC *d, int rc, char *err)
Trace function for SQLite return codes.
Definition: sqlite3odbc.c:3947
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:7097
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:245
int s3type
SQLite3 type.
Definition: sqlite3odbc.h:218
static SQLRETURN drvbindparam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype, SQLSMALLINT buftype, SQLSMALLINT ptype, SQLUINTEGER coldef, SQLSMALLINT scale, SQLPOINTER data, SQLINTEGER buflen, SQLLEN *len)
Internal bind parameter on HSTMT.
Definition: sqlite3odbc.c:5506
SQLRETURN SQL_API SQLProceduresW(SQLHSTMT stmt, SQLWCHAR *catalog, SQLSMALLINT catalogLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *proc, SQLSMALLINT procLen)
Retrieve information about stored procedures (UNICODE version).
Definition: sqlite3odbc.c:8484
static char * fixupsql(char *sql, int sqlLen, int cte, int *nparam, int *isselect, char **errmsg)
Fixup query string with optional parameter markers.
Definition: sqlite3odbc.c:2527
SQLRETURN SQL_API SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
Function not implemented.
Definition: sqlite3odbc.c:5895
#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:260
int len
Offset/length for SQLParamData()/SQLPutData()
Definition: sqlite3odbc.h:215
static SQLRETURN drvgetdiagrec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno, SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg, SQLSMALLINT buflen, SQLSMALLINT *msglen)
Internal get error message given handle (HENV, HDBC, or HSTMT).
Definition: sqlite3odbc.c:8758
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:1910

Generated on Thu Jun 26 2025 by doxygen.
Contact: chw@ch-werner.de