sqlite3odbc.c
Go to the documentation of this file.
1 
14 #if defined(SQLITE_HAS_CODEC) && defined(SQLITE_API)
15 #undef WITH_SQLITE_DLLS
16 #undef SQLITE_DYNLOAD
17 #include "sqlite3.c"
18 #endif
19 
20 #if defined(WITH_SQLITE_DLLS) && (WITH_SQLITE_DLLS > 1)
21 #define SQLITE_DYNLOAD 1
22 #undef HAVE_SQLITE3CLOSEV2
23 #endif
24 
25 #include "sqlite3odbc.h"
26 
27 #ifdef SQLITE_DYNLOAD
28 
29 #undef MEMORY_DEBUG
30 
31 #if defined(_WIN32) || defined(_WIN64)
32 static void dls_init(void);
33 static void dls_fini(void);
34 #else
35 void dls_init(void);
36 void dls_fini(void);
37 #endif
38 
39 static struct dl_sqlite3_funcs {
40  void (*activate_see)(const char *p0);
41  int (*bind_blob)(sqlite3_stmt *p0, int p1, const void *p2, int p3,
42  void (*p4)(void *));
43  int (*bind_double)(sqlite3_stmt *p0, int p1, double p2);
44  int (*bind_int)(sqlite3_stmt *p0, int p1, int p2);
45  int (*bind_int64)(sqlite3_stmt *p0, int p1, sqlite_int64 p2);
46  int (*bind_null)(sqlite3_stmt *p0, int p1);
47  int (*bind_parameter_count)(sqlite3_stmt *p0);
48  int (*bind_text)(sqlite3_stmt *p0, int p1, const char *p2, int p3,
49  void (*p4)(void *));
50  int (*busy_handler)(sqlite3 *p0, int (*p2)(void *, int), void *p3);
51  int (*changes)(sqlite3 *p0);
52  int (*close)(sqlite3 *p0);
53  const void * (*column_blob)(sqlite3_stmt *p0, int p1);
54  int (*column_bytes)(sqlite3_stmt *p0, int p1);
55  int (*column_count)(sqlite3_stmt *p0);
56  const char * (*column_database_name)(sqlite3_stmt *p0, int p1);
57  const char * (*column_decltype)(sqlite3_stmt *p0, int p1);
58  double (*column_double)(sqlite3_stmt *p0, int p1);
59  const char * (*column_name)(sqlite3_stmt *p0, int p1);
60  const char * (*column_origin_name)(sqlite3_stmt *p0, int p1);
61  const char * (*column_table_name)(sqlite3_stmt *p0, int p1);
62  const unsigned char * (*column_text)(sqlite3_stmt *p0, int p1);
63  int (*column_type)(sqlite3_stmt *p0, int p1);
64  int (*create_function)(sqlite3 *p0, const char *p1, int p2, int p3,
65  void *p4,
66  void (*p5)(sqlite3_context *, int, sqlite3_value **),
67  void (*p6)(sqlite3_context *, int, sqlite3_value **),
68  void (*p7)(sqlite3_context *));
69  int (*enable_load_extension)(sqlite3 *p0, int p1);
70  int (*errcode)(sqlite3 *p0);
71  const char * (*errmsg)(sqlite3 *p0);
72  int (*exec)(sqlite3 *p0, const char *p1,
73  int (*p2)(void *, int, char **, char **),
74  void *p3, char **p4);
75  int (*finalize)(sqlite3_stmt *p0);
76  void (*free)(void *p0);
77  void (*free_table)(char **p0);
78  int (*get_table)(sqlite3 *p0, const char *p1, char ***p2,
79  int *p3, int *p4, char **p5);
80  void (*interrupt)(sqlite3 *p0);
81  int (*key)(sqlite3 *p0, const void *p1, int p2);
82  sqlite_int64 (*last_insert_rowid)(sqlite3 *p0);
83  const char * (*libversion)(void);
84  int (*load_extension)(sqlite3 *p0, const char *p1, const char *p2,
85  char **p3);
86  void * (*malloc)(int p0);
87  char * (*mprintf)(const char *p0, ...);
88  int (*open)(const char *p0, sqlite3 **p1);
89  int (*open16)(const void *p0, sqlite3 **p1);
90  int (*open_v2)(const char *p0, sqlite3 **p1, int p2, const char *p3);
91  int (*prepare)(sqlite3 *p0, const char *p1, int p2, sqlite3_stmt **p3,
92  const char **p4);
93  int (*prepare_v2)(sqlite3 *p0, const char *p1, int p2, sqlite3_stmt **p3,
94  const char **p4);
95  void * (*profile)(sqlite3 *p0,
96  void (*p1)(void *, const char *, sqlite3_uint64),
97  void *p2);
98  void * (*realloc)(void *p0, int p1);
99  int (*rekey)(sqlite3 *p0, const void *p1, int p2);
100  int (*reset)(sqlite3_stmt *p0);
101  void (*result_blob)(sqlite3_context *p0, const void *p1,
102  int p2, void (*p3)(void *));
103  void (*result_error)(sqlite3_context *p0, const char *p1, int p2);
104  void (*result_int)(sqlite3_context *p0, int p1);
105  void (*result_null)(sqlite3_context *p0);
106  int (*step)(sqlite3_stmt *p0);
107  int (*xstrnicmp)(const char *p0, const char *p1, int p2);
108  int (*table_column_metadata)(sqlite3 *p0, const char *p1,
109  const char *p2, const char *p3,
110  char const **p4, char const **p5,
111  int *p6, int *p7, int *p8);
112  void * (*trace)(sqlite3 *p0, void (*p1)(void *, const char *), void *p2);
113  void * (*user_data)(sqlite3_context *p0);
114  const void * (*value_blob)(sqlite3_value *p0);
115  int (*value_bytes)(sqlite3_value *p0);
116  const unsigned char * (*value_text)(sqlite3_value *p0);
117  int (*value_type)(sqlite3_value *p0);
118 } dls_funcs;
119 
120 #define sqlite3_activate_see dls_funcs.activate_see
121 #define sqlite3_bind_blob dls_funcs.bind_blob
122 #define sqlite3_bind_double dls_funcs.bind_double
123 #define sqlite3_bind_int dls_funcs.bind_int
124 #define sqlite3_bind_int64 dls_funcs.bind_int64
125 #define sqlite3_bind_null dls_funcs.bind_null
126 #define sqlite3_bind_parameter_count dls_funcs.bind_parameter_count
127 #define sqlite3_bind_text dls_funcs.bind_text
128 #define sqlite3_busy_handler dls_funcs.busy_handler
129 #define sqlite3_changes dls_funcs.changes
130 #define sqlite3_close dls_funcs.close
131 #define sqlite3_column_blob dls_funcs.column_blob
132 #define sqlite3_column_bytes dls_funcs.column_bytes
133 #define sqlite3_column_count dls_funcs.column_count
134 #define sqlite3_column_database_name dls_funcs.column_database_name
135 #define sqlite3_column_decltype dls_funcs.column_decltype
136 #define sqlite3_column_double dls_funcs.column_double
137 #define sqlite3_column_name dls_funcs.column_name
138 #define sqlite3_column_origin_name dls_funcs.column_origin_name
139 #define sqlite3_column_table_name dls_funcs.column_table_name
140 #define sqlite3_column_text dls_funcs.column_text
141 #define sqlite3_column_type dls_funcs.column_type
142 #define sqlite3_create_function dls_funcs.create_function
143 #define sqlite3_enable_load_extension dls_funcs.enable_load_extension
144 #define sqlite3_errcode dls_funcs.errcode
145 #define sqlite3_errmsg dls_funcs.errmsg
146 #define sqlite3_exec dls_funcs.exec
147 #define sqlite3_finalize dls_funcs.finalize
148 #define sqlite3_free dls_funcs.free
149 #define sqlite3_free_table dls_funcs.free_table
150 #define sqlite3_get_table dls_funcs.get_table
151 #define sqlite3_interrupt dls_funcs.interrupt
152 #define sqlite3_key dls_funcs.key
153 #define sqlite3_last_insert_rowid dls_funcs.last_insert_rowid
154 #define sqlite3_libversion dls_funcs.libversion
155 #define sqlite3_load_extension dls_funcs.load_extension
156 #define sqlite3_malloc dls_funcs.malloc
157 #define sqlite3_mprintf dls_funcs.mprintf
158 #define sqlite3_open dls_funcs.open
159 #define sqlite3_open16 dls_funcs.open16
160 #define sqlite3_open_v2 dls_funcs.open_v2
161 #define sqlite3_prepare dls_funcs.prepare
162 #define sqlite3_prepare_v2 dls_funcs.prepare_v2
163 #define sqlite3_profile dls_funcs.profile
164 #define sqlite3_realloc dls_funcs.realloc
165 #define sqlite3_rekey dls_funcs.rekey
166 #define sqlite3_reset dls_funcs.reset
167 #define sqlite3_result_blob dls_funcs.result_blob
168 #define sqlite3_result_error dls_funcs.result_error
169 #define sqlite3_result_int dls_funcs.result_int
170 #define sqlite3_result_null dls_funcs.result_null
171 #define sqlite3_step dls_funcs.step
172 #define sqlite3_strnicmp dls_funcs.xstrnicmp
173 #define sqlite3_table_column_metadata dls_funcs.table_column_metadata
174 #define sqlite3_trace dls_funcs.trace
175 #define sqlite3_user_data dls_funcs.user_data
176 #define sqlite3_value_blob dls_funcs.value_blob
177 #define sqlite3_value_bytes dls_funcs.value_bytes
178 #define sqlite3_value_text dls_funcs.value_text
179 #define sqlite3_value_type dls_funcs.value_type
180 
181 #endif
182 
183 #ifndef WITHOUT_WINTERFACE
184 #define WINTERFACE
185 #define WCHARSUPPORT
186 #endif
187 
188 #if !defined(_WIN32) && !defined(_WIN64)
189 #if !defined(WCHARSUPPORT) && defined(HAVE_SQLWCHAR) && (HAVE_SQLWCHAR)
190 #define WCHARSUPPORT
191 #endif
192 #endif
193 
194 #if defined(WINTERFACE)
195 #include <sqlucode.h>
196 #endif
197 
198 #if defined(_WIN32) || defined(_WIN64)
199 #include "resource3.h"
200 #define ODBC_INI "ODBC.INI"
201 #ifndef DRIVER_VER_INFO
202 #define DRIVER_VER_INFO VERSION
203 #endif
204 #else
205 #define ODBC_INI ".odbc.ini"
206 #endif
207 
208 #ifndef DRIVER_VER_INFO
209 #define DRIVER_VER_INFO "0.0"
210 #endif
211 
212 #ifndef COLATTRIBUTE_LAST_ARG_TYPE
213 #ifdef _WIN64
214 #define COLATTRIBUTE_LAST_ARG_TYPE SQLLEN *
215 #else
216 #define COLATTRIBUTE_LAST_ARG_TYPE SQLPOINTER
217 #endif
218 #endif
219 
220 #ifndef SETSTMTOPTION_LAST_ARG_TYPE
221 #define SETSTMTOPTION_LAST_ARG_TYPE SQLROWCOUNT
222 #endif
223 
224 #undef min
225 #define min(a, b) ((a) < (b) ? (a) : (b))
226 #undef max
227 #define max(a, b) ((a) < (b) ? (b) : (a))
228 
229 #ifndef PTRDIFF_T
230 #define PTRDIFF_T int
231 #endif
232 
233 #define array_size(x) (sizeof (x) / sizeof (x[0]))
234 
235 #define stringify1(s) #s
236 #define stringify(s) stringify1(s)
237 
238 #define verinfo(maj, min, lev) ((maj) << 16 | (min) << 8 | (lev))
239 
240 /* Column meta data from SQLite support */
241 #undef FULL_METADATA
242 #if defined(HAVE_SQLITE3TABLECOLUMNMETADATA) && (HAVE_SQLITE3TABLECOLUMNMETADATA)
243 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
244 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
245 #if defined(HAVE_SQLITE3COLUMNORIGINNAME) && (HAVE_SQLITE3COLUMNORIGINNAME)
246 #define FULL_METADATA 1
247 #endif
248 #endif
249 #endif
250 #endif
251 
252 /* Column types for static string column descriptions (SQLTables etc.) */
253 
254 #if defined(WINTERFACE) && !defined(_WIN32) && !defined(_WIN64)
255 #define SCOL_VARCHAR SQL_WVARCHAR
256 #define SCOL_CHAR SQL_WCHAR
257 #else
258 #define SCOL_VARCHAR SQL_VARCHAR
259 #define SCOL_CHAR SQL_CHAR
260 #endif
261 
262 #define ENV_MAGIC 0x53544145
263 #define DBC_MAGIC 0x53544144
264 #define DEAD_MAGIC 0xdeadbeef
265 
272 typedef struct dstr {
273  int len;
274  int max;
275  int oom;
276  char buffer[1];
277 } dstr;
278 
279 static const char *xdigits = "0123456789ABCDEFabcdef";
280 
281 #ifdef MEMORY_DEBUG
282 
283 static void *
284 xmalloc_(int n, char *file, int line)
285 {
286  int nn = n + 4 * sizeof (long);
287  long *p;
288 
289  p = malloc(nn);
290  if (!p) {
291 #if (MEMORY_DEBUG > 1)
292  fprintf(stderr, "malloc\t%d\tNULL\t%s:%d\n", n, file, line);
293 #endif
294  return NULL;
295  }
296  p[0] = 0xdead1234;
297  nn = nn / sizeof (long) - 1;
298  p[1] = n;
299  p[nn] = 0xdead5678;
300 #if (MEMORY_DEBUG > 1)
301  fprintf(stderr, "malloc\t%d\t%p\t%s:%d\n", n, &p[2], file, line);
302 #endif
303  return (void *) &p[2];
304 }
305 
306 static void *
307 xrealloc_(void *old, int n, char *file, int line)
308 {
309  int nn = n + 4 * sizeof (long), nnn;
310  long *p, *pp;
311 
312  if (n == 0 || !old) {
313  return xmalloc_(n, file, line);
314  }
315  p = &((long *) old)[-2];
316  if (p[0] != 0xdead1234) {
317  fprintf(stderr, "*** low end corruption @ %p\n", old);
318  abort();
319  }
320  nnn = p[1] + 4 * sizeof (long);
321  nnn = nnn / sizeof (long) - 1;
322  if (p[nnn] != 0xdead5678) {
323  fprintf(stderr, "*** high end corruption @ %p\n", old);
324  abort();
325  }
326  pp = realloc(p, nn);
327  if (!pp) {
328 #if (MEMORY_DEBUG > 1)
329  fprintf(stderr, "realloc\t%p,%d\tNULL\t%s:%d\n", old, n, file, line);
330 #endif
331  return NULL;
332  }
333 #if (MEMORY_DEBUG > 1)
334  fprintf(stderr, "realloc\t%p,%d\t%p\t%s:%d\n", old, n, &pp[2], file, line);
335 #endif
336  p = pp;
337  p[1] = n;
338  nn = nn / sizeof (long) - 1;
339  p[nn] = 0xdead5678;
340  return (void *) &p[2];
341 }
342 
343 static void
344 xfree_(void *x, char *file, int line)
345 {
346  long *p;
347  int n;
348 
349  if (!x) {
350  return;
351  }
352  p = &((long *) x)[-2];
353  if (p[0] != 0xdead1234) {
354  fprintf(stderr, "*** low end corruption @ %p\n", x);
355  abort();
356  }
357  n = p[1] + 4 * sizeof (long);
358  n = n / sizeof (long) - 1;
359  if (p[n] != 0xdead5678) {
360  fprintf(stderr, "*** high end corruption @ %p\n", x);
361  abort();
362  }
363 #if (MEMORY_DEBUG > 1)
364  fprintf(stderr, "free\t%p\t\t%s:%d\n", x, file, line);
365 #endif
366  free(p);
367 }
368 
369 static void
370 xfree__(void *x)
371 {
372  xfree_(x, "unknown location", 0);
373 }
374 
375 static char *
376 xstrdup_(const char *str, char *file, int line)
377 {
378  char *p;
379 
380  if (!str) {
381 #if (MEMORY_DEBUG > 1)
382  fprintf(stderr, "strdup\tNULL\tNULL\t%s:%d\n", file, line);
383 #endif
384  return NULL;
385  }
386  p = xmalloc_(strlen(str) + 1, file, line);
387  if (p) {
388  strcpy(p, str);
389  }
390 #if (MEMORY_DEBUG > 1)
391  fprintf(stderr, "strdup\t%p\t%p\t%s:%d\n", str, p, file, line);
392 #endif
393  return p;
394 }
395 
396 #define xmalloc(x) xmalloc_(x, __FILE__, __LINE__)
397 #define xrealloc(x,y) xrealloc_(x, y, __FILE__, __LINE__)
398 #define xfree(x) xfree_(x, __FILE__, __LINE__)
399 #define xstrdup(x) xstrdup_(x, __FILE__, __LINE__)
400 
401 #else
402 
403 #define xmalloc(x) sqlite3_malloc(x)
404 #define xrealloc(x,y) sqlite3_realloc(x, y)
405 #define xfree(x) sqlite3_free(x)
406 #define xstrdup(x) strdup_(x)
407 
408 #endif
409 
410 #if defined(_WIN32) || defined(_WIN64)
411 
412 #define vsnprintf _vsnprintf
413 #define snprintf _snprintf
414 #define strcasecmp _stricmp
415 #define strncasecmp _strnicmp
416 
417 #ifdef _MSC_VER
418 #define strtoll _strtoi64
419 #define strtoull _strtoui64
420 #endif
421 
422 static HINSTANCE NEAR hModule; /* Saved module handle for resources */
423 
424 #endif
425 
426 #ifdef HAVE_SQLITE3STRNICMP
427 #undef strncasecmp
428 #define strncasecmp(A,B,C) sqlite3_strnicmp(A,B,C)
429 #undef strcasecmp
430 #define strcasecmp(A,B) strcasecmp_(A,B)
431 
432 #if defined(__GNUC__) && (__GNUC__ >= 2)
433 static int strcasecmp_(const char *a, const char *b)
434  __attribute__((__unused__));
435 #endif
436 
437 static int strcasecmp_(const char *a, const char *b)
438 {
439  int c = strlen(a), d = strlen(b);
440 
441  if (c > d) {
442  return strncasecmp(a, b, c);
443  }
444  return strncasecmp(a, b, d);
445 }
446 #endif
447 
448 #if defined(_WIN32) || defined(_WIN64)
449 
450 /*
451  * SQLHENV, SQLHDBC, and SQLHSTMT synchronization
452  * is done using a critical section in ENV and DBC
453  * structures.
454  */
455 
456 #define HDBC_LOCK(hdbc) \
457 { \
458  DBC *d; \
459  \
460  if ((hdbc) == SQL_NULL_HDBC) { \
461  return SQL_INVALID_HANDLE; \
462  } \
463  d = (DBC *) (hdbc); \
464  if (d->magic != DBC_MAGIC) { \
465  return SQL_INVALID_HANDLE; \
466  } \
467  EnterCriticalSection(&d->cs); \
468  d->owner = GetCurrentThreadId(); \
469 }
470 
471 #define HDBC_UNLOCK(hdbc) \
472  if ((hdbc) != SQL_NULL_HDBC) { \
473  DBC *d; \
474  \
475  d = (DBC *) (hdbc); \
476  if (d->magic == DBC_MAGIC) { \
477  d->owner = 0; \
478  LeaveCriticalSection(&d->cs); \
479  } \
480  }
481 
482 #define HSTMT_LOCK(hstmt) \
483 { \
484  DBC *d; \
485  \
486  if ((hstmt) == SQL_NULL_HSTMT) { \
487  return SQL_INVALID_HANDLE; \
488  } \
489  d = (DBC *) ((STMT *) (hstmt))->dbc; \
490  if (d->magic != DBC_MAGIC) { \
491  return SQL_INVALID_HANDLE; \
492  } \
493  EnterCriticalSection(&d->cs); \
494  d->owner = GetCurrentThreadId(); \
495 }
496 
497 #define HSTMT_UNLOCK(hstmt) \
498  if ((hstmt) != SQL_NULL_HSTMT) { \
499  DBC *d; \
500  \
501  d = (DBC *) ((STMT *) (hstmt))->dbc; \
502  if (d->magic == DBC_MAGIC) { \
503  d->owner = 0; \
504  LeaveCriticalSection(&d->cs); \
505  } \
506  }
507 
508 #else
509 
510 /*
511  * On UN*X assume that we are single-threaded or
512  * the driver manager provides serialization for us.
513  *
514  * In iODBC (3.52.x) serialization can be turned
515  * on using the DSN property "ThreadManager=yes".
516  *
517  * In unixODBC that property is named
518  * "Threading=0-3" and takes one of these values:
519  *
520  * 0 - no protection
521  * 1 - statement level protection
522  * 2 - connection level protection
523  * 3 - environment level protection
524  *
525  * unixODBC 2.2.11 uses environment level protection
526  * by default when it has been built with pthread
527  * support.
528  */
529 
530 #define HDBC_LOCK(hdbc)
531 #define HDBC_UNLOCK(hdbc)
532 #define HSTMT_LOCK(hdbc)
533 #define HSTMT_UNLOCK(hdbc)
534 
535 #endif
536 
537 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
538 extern void nvfs_init(void);
539 extern const char *nvfs_makevfs(const char *);
540 #endif
541 
542 /*
543  * tolower() replacement w/o locale
544  */
545 
546 static const char upper_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
547 static const char lower_chars[] = "abcdefghijklmnopqrstuvwxyz";
548 
549 static int
550 TOLOWER(int c)
551 {
552  if (c) {
553  char *p = strchr(upper_chars, c);
554 
555  if (p) {
556  c = lower_chars[p - upper_chars];
557  }
558  }
559  return c;
560 }
561 
562 /*
563  * isdigit() replacement w/o ctype.h
564  */
565 
566 static const char digit_chars[] = "0123456789";
567 
568 #define ISDIGIT(c) \
569  ((c) && strchr(digit_chars, (c)) != NULL)
570 
571 /*
572  * isspace() replacement w/o ctype.h
573  */
574 
575 static const char space_chars[] = " \f\n\r\t\v";
576 
577 #define ISSPACE(c) \
578  ((c) && strchr(space_chars, (c)) != NULL)
579 
580 
581 /*
582  * Forward declarations of static functions.
583  */
584 
585 static void dbtraceapi(DBC *d, char *fn, const char *sql);
586 static void freedyncols(STMT *s);
587 static void freeresult(STMT *s, int clrcols);
588 static void freerows(char **rowp);
589 static void unbindcols(STMT *s);
590 static void s3stmt_drop(STMT *s);
591 
592 static SQLRETURN drvexecute(SQLHSTMT stmt, int initial);
593 static SQLRETURN freestmt(HSTMT stmt);
594 static SQLRETURN mkbindcols(STMT *s, int ncols);
595 static SQLRETURN setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp);
596 static SQLRETURN setupparbuf(STMT *s, BINDPARM *p);
597 static SQLRETURN starttran(STMT *s);
598 static SQLRETURN setupparam(STMT *s, char *sql, int pnum);
599 static SQLRETURN getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype,
600  SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp,
601  int partial);
602 
603 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
604 /* MS Access hack part 1 (reserved error -7748) */
605 static COL *statSpec2P, *statSpec3P;
606 #endif
607 
608 #if (MEMORY_DEBUG < 1)
609 
615 static char *
616 strdup_(const char *str)
617 {
618  char *p = NULL;
619 
620  if (str) {
621  p = xmalloc(strlen(str) + 1);
622  if (p) {
623  strcpy(p, str);
624  }
625  }
626  return p;
627 }
628 #endif
629 
637 static dstr *
638 dsappend(dstr *dsp, const char *str)
639 {
640  int len;
641 
642  if (!str) {
643  return dsp;
644  }
645  len = strlen(str);
646  if (!dsp) {
647  int max = 256;
648 
649  if (max < len) {
650  max += len;
651  }
652  dsp = xmalloc(max);
653  if (dsp) {
654  dsp->max = max;
655  dsp->len = dsp->oom = 0;
656  goto copy;
657  }
658  return dsp;
659  }
660  if (dsp->oom) {
661  return dsp;
662  }
663  if (dsp->len + len > dsp->max) {
664  int max = dsp->max + len + 256;
665  dstr *ndsp = xrealloc(dsp, max);
666 
667  if (!ndsp) {
668  strcpy(dsp->buffer, "OUT OF MEMORY");
669  dsp->max = dsp->len = 13;
670  dsp->oom = 1;
671  return dsp;
672  }
673  dsp = ndsp;
674  dsp->max = max;
675  }
676 copy:
677  strcpy(dsp->buffer + dsp->len, str);
678  dsp->len += len;
679  return dsp;
680 }
681 
689 static dstr *
690 dsappendq(dstr *dsp, const char *str)
691 {
692  int len;
693  const char *p;
694  char *q;
695 
696  if (!str) {
697  return dsp;
698  }
699  len = strlen(str);
700  for (p = str; *p; ++p) {
701  if (p[0] == '"') {
702  ++len;
703  }
704  }
705  len += 2;
706  if (!dsp) {
707  int max = 256;
708 
709  if (max < len) {
710  max += len;
711  }
712  dsp = xmalloc(max);
713  if (dsp) {
714  dsp->max = max;
715  dsp->len = dsp->oom = 0;
716  goto copy;
717  }
718  return dsp;
719  }
720  if (dsp->oom) {
721  return dsp;
722  }
723  if (dsp->len + len > dsp->max) {
724  int max = dsp->max + len + 256;
725  dstr *ndsp = xrealloc(dsp, max);
726 
727  if (!ndsp) {
728  strcpy(dsp->buffer, "OUT OF MEMORY");
729  dsp->max = dsp->len = 13;
730  dsp->oom = 1;
731  return dsp;
732  }
733  dsp = ndsp;
734  dsp->max = max;
735  }
736 copy:
737  q = dsp->buffer + dsp->len;
738  *q++ = '"';
739  for (p = str; *p; ++p) {
740  *q++ = *p;
741  if (p[0] == '"') {
742  *q++ = '"';
743  }
744  }
745  *q++ = '"';
746  *q = '\0';
747  dsp->len += len;
748  return dsp;
749 }
750 
757 static const char *
758 dsval(dstr *dsp)
759 {
760  if (dsp) {
761  return (const char *) dsp->buffer;
762  }
763  return "ERROR";
764 }
765 
772 static int
773 dserr(dstr *dsp)
774 {
775  return !dsp || dsp->oom;
776 }
777 
783 static void
785 {
786  if (dsp) {
787  xfree(dsp);
788  }
789 }
790 
791 #ifdef WCHARSUPPORT
792 
799 static int
800 uc_strlen(SQLWCHAR *str)
801 {
802  int len = 0;
803 
804  if (str) {
805  while (*str) {
806  ++len;
807  ++str;
808  }
809  }
810  return len;
811 }
812 
821 static SQLWCHAR *
822 uc_strncpy(SQLWCHAR *dest, SQLWCHAR *src, int len)
823 {
824  int i = 0;
825 
826  while (i < len) {
827  if (!src[i]) {
828  break;
829  }
830  dest[i] = src[i];
831  ++i;
832  }
833  if (i < len) {
834  dest[i] = 0;
835  }
836  return dest;
837 }
838 
847 static void
848 uc_from_utf_buf(unsigned char *str, int len, SQLWCHAR *uc, int ucLen)
849 {
850  ucLen = ucLen / sizeof (SQLWCHAR);
851  if (!uc || ucLen < 0) {
852  return;
853  }
854  if (len < 0) {
855  len = ucLen * 5;
856  }
857  uc[0] = 0;
858  if (str) {
859  int i = 0;
860 
861  while (i < len && *str && i < ucLen) {
862  unsigned char c = str[0];
863 
864  if (c < 0x80) {
865  uc[i++] = c;
866  ++str;
867  } else if (c <= 0xc1 || c >= 0xf5) {
868  /* illegal, ignored */
869  ++str;
870  } else if (c < 0xe0) {
871  if ((str[1] & 0xc0) == 0x80) {
872  unsigned long t = ((c & 0x1f) << 6) | (str[1] & 0x3f);
873 
874  uc[i++] = t;
875  str += 2;
876  } else {
877  uc[i++] = c;
878  ++str;
879  }
880  } else if (c < 0xf0) {
881  if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80) {
882  unsigned long t = ((c & 0x0f) << 12) |
883  ((str[1] & 0x3f) << 6) | (str[2] & 0x3f);
884 
885  uc[i++] = t;
886  str += 3;
887  } else {
888  uc[i++] = c;
889  ++str;
890  }
891  } else if (c < 0xf8) {
892  if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 &&
893  (str[3] & 0xc0) == 0x80) {
894  unsigned long t = ((c & 0x03) << 18) |
895  ((str[1] & 0x3f) << 12) | ((str[2] & 0x3f) << 6) |
896  (str[3] & 0x3f);
897 
898  if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
899  t >= 0x10000) {
900  t -= 0x10000;
901  uc[i++] = 0xd800 | ((t >> 10) & 0x3ff);
902  if (i >= ucLen) {
903  break;
904  }
905  t = 0xdc00 | (t & 0x3ff);
906  }
907  uc[i++] = t;
908  str += 4;
909  } else {
910  uc[i++] = c;
911  ++str;
912  }
913  } else {
914  /* ignore */
915  ++str;
916  }
917  }
918  if (i < ucLen) {
919  uc[i] = 0;
920  }
921  }
922 }
923 
931 static SQLWCHAR *
932 uc_from_utf(unsigned char *str, int len)
933 {
934  SQLWCHAR *uc = NULL;
935  int ucLen;
936 
937  if (str) {
938  if (len == SQL_NTS) {
939  len = strlen((char *) str);
940  }
941  ucLen = sizeof (SQLWCHAR) * (len + 1);
942  uc = xmalloc(ucLen);
943  if (uc) {
944  uc_from_utf_buf(str, len, uc, ucLen);
945  }
946  }
947  return uc;
948 }
949 
957 static char *
958 uc_to_utf(SQLWCHAR *str, int len)
959 {
960  int i;
961  char *cp, *ret = NULL;
962 
963  if (!str) {
964  return ret;
965  }
966  if (len == SQL_NTS) {
967  len = uc_strlen(str);
968  } else {
969  len = len / sizeof (SQLWCHAR);
970  }
971  cp = xmalloc(len * 6 + 1);
972  if (!cp) {
973  return ret;
974  }
975  ret = cp;
976  for (i = 0; i < len; i++) {
977  unsigned long c = str[i];
978 
979  if (sizeof (SQLWCHAR) == 2 * sizeof (char)) {
980  c &= 0xffff;
981  }
982  if (c < 0x80) {
983  *cp++ = c;
984  } else if (c < 0x800) {
985  *cp++ = 0xc0 | ((c >> 6) & 0x1f);
986  *cp++ = 0x80 | (c & 0x3f);
987  } else if (c < 0x10000) {
988  if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
989  c >= 0xd800 && c <= 0xdbff && i + 1 < len) {
990  unsigned long c2 = str[i + 1] & 0xffff;
991 
992  if (c2 >= 0xdc00 && c2 <= 0xdfff) {
993  c = (((c & 0x3ff) << 10) | (c2 & 0x3ff)) + 0x10000;
994  *cp++ = 0xf0 | ((c >> 18) & 0x07);
995  *cp++ = 0x80 | ((c >> 12) & 0x3f);
996  *cp++ = 0x80 | ((c >> 6) & 0x3f);
997  *cp++ = 0x80 | (c & 0x3f);
998  ++i;
999  continue;
1000  }
1001  }
1002  *cp++ = 0xe0 | ((c >> 12) & 0x0f);
1003  *cp++ = 0x80 | ((c >> 6) & 0x3f);
1004  *cp++ = 0x80 | (c & 0x3f);
1005  } else if (c <= 0x10ffff) {
1006  *cp++ = 0xf0 | ((c >> 18) & 0x07);
1007  *cp++ = 0x80 | ((c >> 12) & 0x3f);
1008  *cp++ = 0x80 | ((c >> 6) & 0x3f);
1009  *cp++ = 0x80 | (c & 0x3f);
1010  }
1011  }
1012  *cp = '\0';
1013  return ret;
1014 }
1015 
1016 #endif
1017 
1018 #ifdef WINTERFACE
1019 
1027 static char *
1028 uc_to_utf_c(SQLWCHAR *str, int len)
1029 {
1030  if (len != SQL_NTS) {
1031  len = len * sizeof (SQLWCHAR);
1032  }
1033  return uc_to_utf(str, len);
1034 }
1035 
1036 #endif
1037 
1038 #if defined(WCHARSUPPORT) || defined(_WIN32) || defined(_WIN64)
1039 
1045 static void
1046 uc_free(void *str)
1047 {
1048  if (str) {
1049  xfree(str);
1050  }
1051 }
1052 
1053 #endif
1054 
1055 #if defined(_WIN32) || defined(_WIN64)
1056 
1064 static char *
1065 wmb_to_utf(char *str, int len)
1066 {
1067  WCHAR *wstr;
1068  OSVERSIONINFO ovi;
1069  int nchar, is2k, cp = CP_OEMCP;
1070 
1071  ovi.dwOSVersionInfoSize = sizeof (ovi);
1072  GetVersionEx(&ovi);
1073  is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1074  if (AreFileApisANSI()) {
1075  cp = is2k ? CP_THREAD_ACP : CP_ACP;
1076  }
1077  nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
1078  wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
1079  if (!wstr) {
1080  return NULL;
1081  }
1082  wstr[0] = 0;
1083  nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
1084  wstr[nchar] = 0;
1085  str = xmalloc((nchar + 1) * 7);
1086  if (!str) {
1087  xfree(wstr);
1088  return NULL;
1089  }
1090  str[0] = '\0';
1091  nchar = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, nchar * 7, 0, 0);
1092  str[nchar] = '\0';
1093  xfree(wstr);
1094  return str;
1095 }
1096 
1097 #ifndef WINTERFACE
1098 
1106 static char *
1107 wmb_to_utf_c(char *str, int len)
1108 {
1109  if (len == SQL_NTS) {
1110  len = strlen(str);
1111  }
1112  return wmb_to_utf(str, len);
1113 }
1114 
1115 #endif
1116 
1124 static char *
1125 utf_to_wmb(char *str, int len)
1126 {
1127  WCHAR *wstr;
1128  OSVERSIONINFO ovi;
1129  int nchar, is2k, cp = CP_OEMCP;
1130 
1131  ovi.dwOSVersionInfoSize = sizeof (ovi);
1132  GetVersionEx(&ovi);
1133  is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1134  if (AreFileApisANSI()) {
1135  cp = is2k ? CP_THREAD_ACP : CP_ACP;
1136  }
1137  nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
1138  wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
1139  if (!wstr) {
1140  return NULL;
1141  }
1142  wstr[0] = 0;
1143  nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, wstr, nchar);
1144  wstr[nchar] = 0;
1145  str = xmalloc((nchar + 1) * 7);
1146  if (!str) {
1147  xfree(wstr);
1148  return NULL;
1149  }
1150  str[0] = '\0';
1151  nchar = WideCharToMultiByte(cp, 0, wstr, -1, str, nchar * 7, 0, 0);
1152  str[nchar] = '\0';
1153  xfree(wstr);
1154  return str;
1155 }
1156 
1157 #ifdef WINTERFACE
1158 
1166 static WCHAR *
1167 wmb_to_uc(char *str, int len)
1168 {
1169  WCHAR *wstr;
1170  OSVERSIONINFO ovi;
1171  int nchar, is2k, cp = CP_OEMCP;
1172 
1173  ovi.dwOSVersionInfoSize = sizeof (ovi);
1174  GetVersionEx(&ovi);
1175  is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1176  if (AreFileApisANSI()) {
1177  cp = is2k ? CP_THREAD_ACP : CP_ACP;
1178  }
1179  nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
1180  wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
1181  if (!wstr) {
1182  return NULL;
1183  }
1184  wstr[0] = 0;
1185  nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
1186  wstr[nchar] = 0;
1187  return wstr;
1188 }
1189 
1197 static char *
1198 uc_to_wmb(WCHAR *wstr, int len)
1199 {
1200  char *str;
1201  OSVERSIONINFO ovi;
1202  int nchar, is2k, cp = CP_OEMCP;
1203 
1204  ovi.dwOSVersionInfoSize = sizeof (ovi);
1205  GetVersionEx(&ovi);
1206  is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1207  if (AreFileApisANSI()) {
1208  cp = is2k ? CP_THREAD_ACP : CP_ACP;
1209  }
1210  nchar = WideCharToMultiByte(cp, 0, wstr, len, NULL, 0, 0, 0);
1211  str = xmalloc((nchar + 1) * 2);
1212  if (!str) {
1213  return NULL;
1214  }
1215  str[0] = '\0';
1216  nchar = WideCharToMultiByte(cp, 0, wstr, len, str, nchar * 2, 0, 0);
1217  str[nchar] = '\0';
1218  return str;
1219 }
1220 
1221 #endif /* WINTERFACE */
1222 
1223 #endif /* _WIN32 || _WIN64 */
1224 
1225 
1226 #ifdef USE_DLOPEN_FOR_GPPS
1227 
1228 #include <dlfcn.h>
1229 
1230 #define SQLGetPrivateProfileString(A,B,C,D,E,F) drvgpps(d,A,B,C,D,E,F)
1231 
1232 /*
1233  * EXPERIMENTAL: SQLGetPrivateProfileString infrastructure using
1234  * dlopen(), in theory this makes the driver independent from the
1235  * driver manager, i.e. the same driver binary can run with iODBC
1236  * and unixODBC.
1237  */
1238 
1239 static void
1240 drvgetgpps(DBC *d)
1241 {
1242  void *lib;
1243  int (*gpps)();
1244 
1245  lib = dlopen("libodbcinst.so.2", RTLD_LAZY);
1246  if (!lib) {
1247  lib = dlopen("libodbcinst.so.1", RTLD_LAZY);
1248  }
1249  if (!lib) {
1250  lib = dlopen("libodbcinst.so", RTLD_LAZY);
1251  }
1252  if (!lib) {
1253  lib = dlopen("libiodbcinst.so.2", RTLD_LAZY);
1254  }
1255  if (!lib) {
1256  lib = dlopen("libiodbcinst.so", RTLD_LAZY);
1257  }
1258  if (lib) {
1259  gpps = (int (*)()) dlsym(lib, "SQLGetPrivateProfileString");
1260  if (!gpps) {
1261  dlclose(lib);
1262  return;
1263  }
1264  d->instlib = lib;
1265  d->gpps = gpps;
1266  }
1267 }
1268 
1269 static void
1270 drvrelgpps(DBC *d)
1271 {
1272  if (d->instlib) {
1273  dlclose(d->instlib);
1274  d->instlib = 0;
1275  }
1276 }
1277 
1278 static int
1279 drvgpps(DBC *d, char *sect, char *ent, char *def, char *buf,
1280  int bufsiz, char *fname)
1281 {
1282  if (d->gpps) {
1283  return d->gpps(sect, ent, def, buf, bufsiz, fname);
1284  }
1285  strncpy(buf, def, bufsiz);
1286  buf[bufsiz - 1] = '\0';
1287  return 1;
1288 }
1289 #else
1290 #include <odbcinst.h>
1291 #define drvgetgpps(d)
1292 #define drvrelgpps(d)
1293 #endif
1294 
1295 /*
1296  * Internal function to bind SQLite3 parameters.
1297  */
1298 
1299 static void
1300 s3bind(DBC *d, sqlite3_stmt *stmt, int nparams, BINDPARM *p)
1301 {
1302  int i;
1303 
1304  if (stmt && p && nparams > 0) {
1305  for (i = 0; i < nparams; i++, p++) {
1306  switch (p->s3type) {
1307  default:
1308  case SQLITE_NULL:
1309  sqlite3_bind_null(stmt, i + 1);
1310  if (d->trace) {
1311  fprintf(d->trace, "-- parameter %d: NULL\n", i + 1);
1312  fflush(d->trace);
1313  }
1314  break;
1315  case SQLITE_TEXT:
1316  sqlite3_bind_text(stmt, i + 1, p->s3val, p->s3size,
1317  SQLITE_STATIC);
1318  if (d->trace) {
1319  fprintf(d->trace, "-- parameter %d: '%*s'\n", i + 1,
1320  p->s3size, (char *) p->s3val);
1321  fflush(d->trace);
1322  }
1323  break;
1324  case SQLITE_BLOB:
1325  sqlite3_bind_blob(stmt, i + 1, p->s3val, p->s3size,
1326  SQLITE_STATIC);
1327  if (d->trace) {
1328  fprintf(d->trace, "-- parameter %d: [BLOB]'\n", i + 1);
1329  fflush(d->trace);
1330  }
1331  break;
1332  case SQLITE_FLOAT:
1333  sqlite3_bind_double(stmt, i + 1, p->s3dval);
1334  if (d->trace) {
1335  fprintf(d->trace, "-- parameter %d: %g\n",
1336  i + 1, p->s3dval);
1337  fflush(d->trace);
1338  }
1339  break;
1340  case SQLITE_INTEGER:
1341  if (p->s3size > sizeof (int)) {
1342  sqlite3_bind_int64(stmt, i + 1, p->s3lival);
1343  if (d->trace) {
1344  fprintf(d->trace,
1345 #ifdef _WIN32
1346  "-- parameter %d: %I64d\n",
1347 #else
1348  "-- parameter %d: %lld\n",
1349 #endif
1350  i + 1, p->s3lival);
1351  fflush(d->trace);
1352  }
1353  } else {
1354  sqlite3_bind_int(stmt, i + 1, p->s3ival);
1355  if (d->trace) {
1356  fprintf(d->trace, "-- parameter %d: %d\n",
1357  i + 1, p->s3ival);
1358  fflush(d->trace);
1359  }
1360  }
1361  break;
1362  }
1363  }
1364  }
1365 }
1366 
1374 typedef struct tblres {
1375  char **resarr;
1376  char *errmsg;
1377  sqlite3_stmt *stmt;
1378  STMT *s;
1379  int nalloc;
1380  int nrow;
1381  int ncol;
1383  int rc;
1384 } TBLRES;
1385 
1386 /*
1387  * Driver's version of sqlite3_get_table() and friends which are
1388  * capable of dealing with blobs.
1389  */
1390 
1391 static int
1392 drvgettable_row(TBLRES *t, int ncol, int rc)
1393 {
1394  int need;
1395  int i;
1396  char *p;
1397 
1398  if (t->nrow == 0 && rc == SQLITE_ROW) {
1399  need = ncol * 2;
1400  } else {
1401  need = ncol;
1402  }
1403  if (t->ndata + need >= t->nalloc) {
1404  char **resnew;
1405  int nalloc = t->nalloc * 2 + need + 1;
1406 
1407  resnew = xrealloc(t->resarr, sizeof (char *) * nalloc);
1408  if (!resnew) {
1409 nomem:
1410  t->rc = SQLITE_NOMEM;
1411  return 1;
1412  }
1413  t->nalloc = nalloc;
1414  t->resarr = resnew;
1415  }
1416  /* column names when first row */
1417  if (t->nrow == 0) {
1418  t->ncol = ncol;
1419  for (i = 0; i < ncol; i++) {
1420  p = (char *) sqlite3_column_name(t->stmt, i);
1421  if (p) {
1422  char *q = xmalloc(strlen(p) + 1);
1423 
1424  if (!q) {
1425  goto nomem;
1426  }
1427  strcpy(q, p);
1428  p = q;
1429  }
1430  t->resarr[t->ndata++] = p;
1431  }
1432  if (t->s && t->s->guessed_types) {
1433  int ncol2 = ncol;
1434 
1435  setupdyncols(t->s, t->stmt, &ncol2);
1436  t->s->guessed_types = 0;
1437  t->s->ncols = ncol;
1438  }
1439  } else if (t->ncol != ncol) {
1440  t->errmsg = sqlite3_mprintf("drvgettable() called with two or"
1441  " more incompatible queries");
1442  t->rc = SQLITE_ERROR;
1443  return 1;
1444  }
1445  /* copy row data */
1446  if (rc == SQLITE_ROW) {
1447  for (i = 0; i < ncol; i++) {
1448  int coltype = sqlite3_column_type(t->stmt, i);
1449 
1450  p = NULL;
1451  if (coltype == SQLITE_BLOB) {
1452  int k, nbytes = sqlite3_column_bytes(t->stmt, i);
1453  char *qp;
1454  unsigned const char *bp;
1455 
1456  bp = sqlite3_column_blob(t->stmt, i);
1457  qp = xmalloc(nbytes * 2 + 4);
1458  if (!qp) {
1459  goto nomem;
1460  }
1461  p = qp;
1462  *qp++ = 'X';
1463  *qp++ = '\'';
1464  for (k = 0; k < nbytes; k++) {
1465  *qp++ = xdigits[(bp[k] >> 4)];
1466  *qp++ = xdigits[(bp[k] & 0xF)];
1467  }
1468  *qp++ = '\'';
1469  *qp = '\0';
1470 #ifdef _MSC_VER
1471  } else if (coltype == SQLITE_FLOAT) {
1472  struct lconv *lc = 0;
1473  double val = sqlite3_column_double(t->stmt, i);
1474  char buffer[128];
1475 
1476  /*
1477  * This avoids floating point rounding
1478  * and formatting problems of some SQLite
1479  * versions in conjunction with MSVC 2010.
1480  */
1481  snprintf(buffer, sizeof (buffer), "%.15g", val);
1482  lc = localeconv();
1483  if (lc && lc->decimal_point && lc->decimal_point[0] &&
1484  lc->decimal_point[0] != '.') {
1485  p = strchr(buffer, lc->decimal_point[0]);
1486  if (p) {
1487  *p = '.';
1488  }
1489  }
1490  p = xstrdup(buffer);
1491  if (!p) {
1492  goto nomem;
1493  }
1494 #endif
1495  } else if (coltype != SQLITE_NULL) {
1496  p = xstrdup((char *) sqlite3_column_text(t->stmt, i));
1497  if (!p) {
1498  goto nomem;
1499  }
1500  }
1501  t->resarr[t->ndata++] = p;
1502  }
1503  t->nrow++;
1504  }
1505  return 0;
1506 }
1507 
1508 static int
1509 drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp,
1510  int *ncolp, char **errp, int nparam, BINDPARM *p)
1511 {
1512  DBC *d = (DBC *) s->dbc;
1513  int rc = SQLITE_OK, keep = sql == NULL;
1514  TBLRES tres;
1515  const char *sqlleft = 0;
1516  int nretry = 0, haveerr = 0;
1517 
1518  if (!resp) {
1519  return SQLITE_ERROR;
1520  }
1521  *resp = NULL;
1522  if (nrowp) {
1523  *nrowp = 0;
1524  }
1525  if (ncolp) {
1526  *ncolp = 0;
1527  }
1528  tres.errmsg = NULL;
1529  tres.nrow = 0;
1530  tres.ncol = 0;
1531  tres.ndata = 1;
1532  tres.nalloc = 20;
1533  tres.rc = SQLITE_OK;
1534  tres.resarr = xmalloc(sizeof (char *) * tres.nalloc);
1535  tres.stmt = NULL;
1536  tres.s = s;
1537  if (!tres.resarr) {
1538  return SQLITE_NOMEM;
1539  }
1540  tres.resarr[0] = 0;
1541  if (sql == NULL) {
1542  tres.stmt = s->s3stmt;
1543  if (tres.stmt == NULL) {
1544  return SQLITE_NOMEM;
1545  }
1546  goto retrieve;
1547  }
1548  while (sql && *sql && (rc == SQLITE_OK ||
1549  (rc == SQLITE_SCHEMA && (++nretry) < 2))) {
1550  int ncol;
1551 
1552  tres.stmt = NULL;
1553 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
1554  dbtraceapi(d, "sqlite3_prepare_v2", sql);
1555  rc = sqlite3_prepare_v2(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
1556 #else
1557  dbtraceapi(d, "sqlite3_prepare", sql);
1558  rc = sqlite3_prepare(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
1559 #endif
1560  if (rc != SQLITE_OK) {
1561  if (tres.stmt) {
1562  dbtraceapi(d, "sqlite3_finalize", 0);
1563  sqlite3_finalize(tres.stmt);
1564  tres.stmt = NULL;
1565  }
1566  continue;
1567  }
1568  if (!tres.stmt) {
1569  /* this happens for a comment or white-space */
1570  sql = sqlleft;
1571  continue;
1572  }
1573 retrieve:
1574  if (sqlite3_bind_parameter_count(tres.stmt) != nparam) {
1575  if (errp) {
1576  *errp =
1577  sqlite3_mprintf("%s", "parameter marker count incorrect");
1578  }
1579  haveerr = 1;
1580  rc = SQLITE_ERROR;
1581  goto tbldone;
1582  }
1583  s3bind(d, tres.stmt, nparam, p);
1584  ncol = sqlite3_column_count(tres.stmt);
1585  while (1) {
1586  if (s->max_rows && tres.nrow >= s->max_rows) {
1587  rc = SQLITE_OK;
1588  break;
1589  }
1590  rc = sqlite3_step(tres.stmt);
1591  if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
1592  if (drvgettable_row(&tres, ncol, rc)) {
1593  rc = SQLITE_ABORT;
1594  goto tbldone;
1595  }
1596  }
1597  if (rc != SQLITE_ROW) {
1598  if (keep) {
1599  dbtraceapi(d, "sqlite3_reset", 0);
1600  rc = sqlite3_reset(tres.stmt);
1601  s->s3stmt_noreset = 1;
1602  } else {
1603  dbtraceapi(d, "sqlite3_finalize", 0);
1604  rc = sqlite3_finalize(tres.stmt);
1605  }
1606  tres.stmt = 0;
1607  if (rc != SQLITE_SCHEMA) {
1608  nretry = 0;
1609  sql = sqlleft;
1610  while (sql && ISSPACE(*sql)) {
1611  sql++;
1612  }
1613  }
1614  if (rc == SQLITE_DONE) {
1615  rc = SQLITE_OK;
1616  }
1617  break;
1618  }
1619  }
1620  }
1621 tbldone:
1622  if (tres.stmt) {
1623  if (keep) {
1624  if (!s->s3stmt_noreset) {
1625  dbtraceapi(d, "sqlite3_reset", 0);
1626  sqlite3_reset(tres.stmt);
1627  s->s3stmt_noreset = 1;
1628  }
1629  } else {
1630  dbtraceapi(d, "sqlite3_finalize", 0);
1631  sqlite3_finalize(tres.stmt);
1632  }
1633  }
1634  if (haveerr) {
1635  /* message already in *errp if any */
1636  } else if (rc != SQLITE_OK && rc == sqlite3_errcode(d->sqlite) && errp) {
1637  *errp = sqlite3_mprintf("%s", sqlite3_errmsg(d->sqlite));
1638  } else if (errp) {
1639  *errp = NULL;
1640  }
1641  if (tres.resarr) {
1642  tres.resarr[0] = (char *) (tres.ndata - 1);
1643  }
1644  if (rc == SQLITE_ABORT) {
1645  freerows(&tres.resarr[1]);
1646  if (tres.errmsg) {
1647  if (errp) {
1648  if (*errp) {
1649  sqlite3_free(*errp);
1650  }
1651  *errp = tres.errmsg;
1652  } else {
1653  sqlite3_free(tres.errmsg);
1654  }
1655  }
1656  return tres.rc;
1657  }
1658  sqlite3_free(tres.errmsg);
1659  if (rc != SQLITE_OK) {
1660  freerows(&tres.resarr[1]);
1661  return rc;
1662  }
1663  *resp = &tres.resarr[1];
1664  if (ncolp) {
1665  *ncolp = tres.ncol;
1666  }
1667  if (nrowp) {
1668  *nrowp = tres.nrow;
1669  }
1670  return rc;
1671 }
1672 
1681 #if defined(__GNUC__) && (__GNUC__ >= 2)
1682 static void setstatd(DBC *, int, char *, char *, ...)
1683  __attribute__((format (printf, 3, 5)));
1684 #endif
1685 
1686 static void
1687 setstatd(DBC *d, int naterr, char *msg, char *st, ...)
1688 {
1689  va_list ap;
1690 
1691  if (!d) {
1692  return;
1693  }
1694  d->naterr = naterr;
1695  d->logmsg[0] = '\0';
1696  if (msg) {
1697  int count;
1698 
1699  va_start(ap, st);
1700  count = vsnprintf((char *) d->logmsg, sizeof (d->logmsg), msg, ap);
1701  va_end(ap);
1702  if (count < 0) {
1703  d->logmsg[sizeof (d->logmsg) - 1] = '\0';
1704  }
1705  }
1706  if (!st) {
1707  st = "?????";
1708  }
1709  strncpy(d->sqlstate, st, 5);
1710  d->sqlstate[5] = '\0';
1711 }
1712 
1721 #if defined(__GNUC__) && (__GNUC__ >= 2)
1722 static void setstat(STMT *, int, char *, char *, ...)
1723  __attribute__((format (printf, 3, 5)));
1724 #endif
1725 
1726 static void
1727 setstat(STMT *s, int naterr, char *msg, char *st, ...)
1728 {
1729  va_list ap;
1730 
1731  if (!s) {
1732  return;
1733  }
1734  s->naterr = naterr;
1735  s->logmsg[0] = '\0';
1736  if (msg) {
1737  int count;
1738 
1739  va_start(ap, st);
1740  count = vsnprintf((char *) s->logmsg, sizeof (s->logmsg), msg, ap);
1741  va_end(ap);
1742  if (count < 0) {
1743  s->logmsg[sizeof (s->logmsg) - 1] = '\0';
1744  }
1745  }
1746  if (!st) {
1747  st = "?????";
1748  }
1749  strncpy(s->sqlstate, st, 5);
1750  s->sqlstate[5] = '\0';
1751 }
1752 
1759 static SQLRETURN
1761 {
1762  DBC *d;
1763 
1764  if (dbc == SQL_NULL_HDBC) {
1765  return SQL_INVALID_HANDLE;
1766  }
1767  d = (DBC *) dbc;
1768  setstatd(d, -1, "not supported", "IM001");
1769  return SQL_ERROR;
1770 }
1771 
1778 static SQLRETURN
1780 {
1781  STMT *s;
1782 
1783  if (stmt == SQL_NULL_HSTMT) {
1784  return SQL_INVALID_HANDLE;
1785  }
1786  s = (STMT *) stmt;
1787  setstat(s, -1, "not supported", "IM001");
1788  return SQL_ERROR;
1789 }
1790 
1796 static void
1797 freep(void *x)
1798 {
1799  if (x && ((char **) x)[0]) {
1800  xfree(((char **) x)[0]);
1801  ((char **) x)[0] = NULL;
1802  }
1803 }
1804 
1811 static SQLRETURN
1813 {
1814  setstat(s, -1, "out of memory", (*s->ov3) ? "HY000" : "S1000");
1815  return SQL_ERROR;
1816 }
1817 
1824 static SQLRETURN
1826 {
1827  setstat(s, -1, "not connected", (*s->ov3) ? "HY000" : "S1000");
1828  return SQL_ERROR;
1829 }
1830 
1838 #if defined(HAVE_LOCALECONV) || defined(_WIN32) || defined(_WIN64)
1839 
1840 static double
1841 ln_strtod(const char *data, char **endp)
1842 {
1843  struct lconv *lc = 0;
1844  char buf[128], *p, *end;
1845  double value;
1846 
1847  lc = localeconv();
1848  if (lc && lc->decimal_point && lc->decimal_point[0] &&
1849  lc->decimal_point[0] != '.') {
1850  strncpy(buf, data, sizeof (buf) - 1);
1851  buf[sizeof (buf) - 1] = '\0';
1852  p = strchr(buf, '.');
1853  if (p) {
1854  *p = lc->decimal_point[0];
1855  }
1856  p = buf;
1857  } else {
1858  p = (char *) data;
1859  }
1860  value = strtod(p, &end);
1861  end = (char *) data + (end - p);
1862  if (endp) {
1863  *endp = end;
1864  }
1865  return value;
1866 }
1867 
1868 #else
1869 
1870 #define ln_strtod(A,B) strtod(A,B)
1871 
1872 #endif
1873 
1879 static char *
1880 unquote(char *str)
1881 {
1882  if (str) {
1883  int len = strlen(str);
1884 
1885  if (len > 1) {
1886  int end = len - 1;
1887 
1888  if ((str[0] == '\'' && str[end] == '\'') ||
1889  (str[0] == '"' && str[end] == '"') ||
1890  (str[0] == '[' && str[end] == ']')) {
1891  memmove(str, str + 1, end - 1);
1892  str[end - 1] = '\0';
1893  }
1894  }
1895  }
1896  return str;
1897 }
1898 
1906 static int
1907 unescpat(char *str)
1908 {
1909  char *p, *q;
1910  int count = 0;
1911 
1912  p = str;
1913  while ((q = strchr(p, '_')) != NULL) {
1914  if (q == str || q[-1] != '\\') {
1915  count++;
1916  }
1917  p = q + 1;
1918  }
1919  p = str;
1920  while ((q = strchr(p, '%')) != NULL) {
1921  if (q == str || q[-1] != '\\') {
1922  count++;
1923  }
1924  p = q + 1;
1925  }
1926  p = str;
1927  while ((q = strchr(p, '\\')) != NULL) {
1928  if (q[1] == '\\' || q[1] == '_' || q[1] == '%') {
1929  memmove(q, q + 1, strlen(q));
1930  }
1931  p = q + 1;
1932  }
1933  return count;
1934 }
1935 
1944 static int
1945 namematch(char *str, char *pat, int esc)
1946 {
1947  int cp, ch;
1948 
1949  while (1) {
1950  cp = TOLOWER(*pat);
1951  if (cp == '\0') {
1952  if (*str != '\0') {
1953  goto nomatch;
1954  }
1955  break;
1956  }
1957  if (*str == '\0' && cp != '%') {
1958  goto nomatch;
1959  }
1960  if (cp == '%') {
1961  while (*pat == '%') {
1962  ++pat;
1963  }
1964  cp = TOLOWER(*pat);
1965  if (cp == '\0') {
1966  break;
1967  }
1968  while (1) {
1969  if (cp != '_' && cp != '\\') {
1970  while (*str) {
1971  ch = TOLOWER(*str);
1972  if (ch == cp) {
1973  break;
1974  }
1975  ++str;
1976  }
1977  }
1978  if (namematch(str, pat, esc)) {
1979  goto match;
1980  }
1981  if (*str == '\0') {
1982  goto nomatch;
1983  }
1984  ch = TOLOWER(*str);
1985  ++str;
1986  }
1987  }
1988  if (cp == '_') {
1989  pat++;
1990  str++;
1991  continue;
1992  }
1993  if (esc && cp == '\\' &&
1994  (pat[1] == '\\' || pat[1] == '%' || pat[1] == '_')) {
1995  ++pat;
1996  cp = TOLOWER(*pat);
1997  }
1998  ch = TOLOWER(*str++);
1999  ++pat;
2000  if (ch != cp) {
2001  goto nomatch;
2002  }
2003  }
2004 match:
2005  return 1;
2006 nomatch:
2007  return 0;
2008 }
2009 
2017 static int
2018 busy_handler(void *udata, int count)
2019 {
2020  DBC *d = (DBC *) udata;
2021  long t1;
2022  int ret = 0;
2023 #if !defined(_WIN32) && !defined(_WIN64)
2024  struct timeval tv;
2025 #ifdef HAVE_NANOSLEEP
2026  struct timespec ts;
2027 #endif
2028 #endif
2029 
2030  if (d->busyint) {
2031  d->busyint = 0;
2032  return ret;
2033  }
2034  if (d->timeout <= 0) {
2035  return ret;
2036  }
2037  if (count <= 1) {
2038 #if defined(_WIN32) || defined(_WIN64)
2039  d->t0 = GetTickCount();
2040 #else
2041  gettimeofday(&tv, NULL);
2042  d->t0 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
2043 #endif
2044  }
2045 #if defined(_WIN32) || defined(_WIN64)
2046  t1 = GetTickCount();
2047 #else
2048  gettimeofday(&tv, NULL);
2049  t1 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
2050 #endif
2051  if (t1 - d->t0 > d->timeout) {
2052  goto done;
2053  }
2054 #if defined(_WIN32) || defined(_WIN64)
2055  Sleep(10);
2056 #else
2057 #ifdef HAVE_NANOSLEEP
2058  ts.tv_sec = 0;
2059  ts.tv_nsec = 10000000;
2060  do {
2061  ret = nanosleep(&ts, &ts);
2062  if (ret < 0 && errno != EINTR) {
2063  ret = 0;
2064  }
2065  } while (ret);
2066 #else
2067 #ifdef HAVE_USLEEP
2068  usleep(10000);
2069 #else
2070  tv.tv_sec = 0;
2071  tv.tv_usec = 10000;
2072  select(0, NULL, NULL, NULL, &tv);
2073 #endif
2074 #endif
2075 #endif
2076  ret = 1;
2077 done:
2078  return ret;
2079 }
2080 
2092 static int
2093 setsqliteopts(sqlite3 *x, DBC *d)
2094 {
2095  int count = 0, step = 0, max, rc = SQLITE_ERROR;
2096 
2097 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
2098  max = d->longnames ? 3 : 1;
2099 #else
2100  max = 3;
2101 #endif
2102  if (d->shortnames) {
2103  max = 3;
2104  }
2105  while (step < max) {
2106  if (step < 1) {
2107  rc = sqlite3_exec(x, "PRAGMA empty_result_callbacks = on;",
2108  NULL, NULL, NULL);
2109  if (rc == SQLITE_OK) {
2110  rc = sqlite3_exec(x, d->fksupport ?
2111  "PRAGMA foreign_keys = on;" :
2112  "PRAGMA foreign_keys = off;",
2113  NULL, NULL, NULL);
2114  }
2115  } else if (step < 2) {
2116  rc = sqlite3_exec(x, d->shortnames ?
2117  "PRAGMA full_column_names = off;" :
2118  "PRAGMA full_column_names = on;",
2119  NULL, NULL, NULL);
2120  } else if (step < 3) {
2121  rc = sqlite3_exec(x, d->shortnames ?
2122  "PRAGMA short_column_names = on;" :
2123  "PRAGMA short_column_names = off;",
2124  NULL, NULL, NULL);
2125  }
2126  if (rc != SQLITE_OK) {
2127  if (rc != SQLITE_BUSY ||
2128  !busy_handler((void *) d, ++count)) {
2129  return rc;
2130  }
2131  continue;
2132  }
2133  count = 0;
2134  ++step;
2135  }
2136  sqlite3_busy_handler(x, busy_handler, (void *) d);
2137  return SQLITE_OK;
2138 }
2139 
2149 static void
2150 freerows(char **rowp)
2151 {
2152  PTRDIFF_T size, i;
2153 
2154  if (!rowp) {
2155  return;
2156  }
2157  --rowp;
2158  size = (PTRDIFF_T) rowp[0];
2159  for (i = 1; i <= size; i++) {
2160  freep(&rowp[i]);
2161  }
2162  freep(&rowp);
2163 }
2164 
2175 static int
2176 mapsqltype(const char *typename, int *nosign, int ov3, int nowchar,
2177  int dobigint)
2178 {
2179  char *p, *q;
2180  int testsign = 0, result;
2181 
2182 #ifdef WINTERFACE
2183  result = nowchar ? SQL_VARCHAR : SQL_WVARCHAR;
2184 #else
2185  result = SQL_VARCHAR;
2186 #endif
2187  if (!typename) {
2188  return result;
2189  }
2190  q = p = xmalloc(strlen(typename) + 1);
2191  if (!p) {
2192  return result;
2193  }
2194  strcpy(p, typename);
2195  while (*q) {
2196  *q = TOLOWER(*q);
2197  ++q;
2198  }
2199  if (strncmp(p, "inter", 5) == 0) {
2200  } else if (strncmp(p, "int", 3) == 0 ||
2201  strncmp(p, "mediumint", 9) == 0) {
2202  testsign = 1;
2203  result = SQL_INTEGER;
2204  } else if (strncmp(p, "numeric", 7) == 0) {
2205  result = SQL_DOUBLE;
2206  } else if (strncmp(p, "tinyint", 7) == 0) {
2207  testsign = 1;
2208  result = SQL_TINYINT;
2209  } else if (strncmp(p, "smallint", 8) == 0) {
2210  testsign = 1;
2211  result = SQL_SMALLINT;
2212  } else if (strncmp(p, "float", 5) == 0) {
2213  result = SQL_DOUBLE;
2214  } else if (strncmp(p, "double", 6) == 0 ||
2215  strncmp(p, "real", 4) == 0) {
2216  result = SQL_DOUBLE;
2217  } else if (strncmp(p, "timestamp", 9) == 0) {
2218 #ifdef SQL_TYPE_TIMESTAMP
2219  result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
2220 #else
2221  result = SQL_TIMESTAMP;
2222 #endif
2223  } else if (strncmp(p, "datetime", 8) == 0) {
2224 #ifdef SQL_TYPE_TIMESTAMP
2225  result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
2226 #else
2227  result = SQL_TIMESTAMP;
2228 #endif
2229  } else if (strncmp(p, "time", 4) == 0) {
2230 #ifdef SQL_TYPE_TIME
2231  result = ov3 ? SQL_TYPE_TIME : SQL_TIME;
2232 #else
2233  result = SQL_TIME;
2234 #endif
2235  } else if (strncmp(p, "date", 4) == 0) {
2236 #ifdef SQL_TYPE_DATE
2237  result = ov3 ? SQL_TYPE_DATE : SQL_DATE;
2238 #else
2239  result = SQL_DATE;
2240 #endif
2241 #ifdef SQL_LONGVARCHAR
2242  } else if (strncmp(p, "text", 4) == 0 ||
2243  strncmp(p, "memo", 4) == 0 ||
2244  strncmp(p, "longvarchar", 11) == 0) {
2245 #ifdef WINTERFACE
2246  result = nowchar ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
2247 #else
2248  result = SQL_LONGVARCHAR;
2249 #endif
2250 #ifdef WINTERFACE
2251  } else if (strncmp(p, "wtext", 5) == 0 ||
2252  strncmp(p, "wvarchar", 8) == 0 ||
2253  strncmp(p, "longwvarchar", 12) == 0) {
2254  result = SQL_WLONGVARCHAR;
2255 #endif
2256 #endif
2257 #ifdef SQL_BIT
2258  } else if (strncmp(p, "bool", 4) == 0 ||
2259  strncmp(p, "bit", 3) == 0) {
2260  result = SQL_BIT;
2261 #endif
2262 #ifdef SQL_BIGINT
2263  } else if (strncmp(p, "bigint", 6) == 0) {
2264  testsign = 1;
2265  result = SQL_BIGINT;
2266 #endif
2267  } else if (strncmp(p, "blob", 4) == 0) {
2268  result = SQL_BINARY;
2269  } else if (strncmp(p, "varbinary", 9) == 0) {
2270  result = SQL_VARBINARY;
2271  } else if (strncmp(p, "longvarbinary", 13) == 0) {
2272  result = SQL_LONGVARBINARY;
2273  }
2274  if (nosign) {
2275  if (testsign) {
2276  *nosign = strstr(p, "unsigned") != NULL;
2277  } else {
2278  *nosign = 1;
2279  }
2280  }
2281 #ifdef SQL_BIGINT
2282  if (dobigint && result == SQL_INTEGER) {
2283  result = SQL_BIGINT;
2284  }
2285 #endif
2286  xfree(p);
2287  return result;
2288 }
2289 
2299 static void
2300 getmd(const char *typename, int sqltype, int *mp, int *dp)
2301 {
2302  int m = 0, d = 0;
2303 
2304  switch (sqltype) {
2305  case SQL_INTEGER: m = 10; d = 9; break;
2306  case SQL_TINYINT: m = 4; d = 3; break;
2307  case SQL_SMALLINT: m = 6; d = 5; break;
2308  case SQL_FLOAT: m = 25; d = 24; break;
2309  case SQL_DOUBLE: m = 54; d = 53; break;
2310  case SQL_VARCHAR: m = 255; d = 0; break;
2311 #ifdef WINTERFACE
2312 #ifdef SQL_WVARCHAR
2313  case SQL_WVARCHAR: m = 255; d = 0; break;
2314 #endif
2315 #endif
2316 #ifdef SQL_TYPE_DATE
2317  case SQL_TYPE_DATE:
2318 #endif
2319  case SQL_DATE: m = 10; d = 0; break;
2320 #ifdef SQL_TYPE_TIME
2321  case SQL_TYPE_TIME:
2322 #endif
2323  case SQL_TIME: m = 8; d = 0; break;
2324 #ifdef SQL_TYPE_TIMESTAMP
2325  case SQL_TYPE_TIMESTAMP:
2326 #endif
2327  case SQL_TIMESTAMP: m = 32; d = 3; break;
2328 #ifdef SQL_LONGVARCHAR
2329  case SQL_LONGVARCHAR : m = 65536; d = 0; break;
2330 #endif
2331 #ifdef WINTERFACE
2332 #ifdef SQL_WLONGVARCHAR
2333  case SQL_WLONGVARCHAR: m = 65536; d = 0; break;
2334 #endif
2335 #endif
2336  case SQL_BINARY:
2337  case SQL_VARBINARY: m = 255; d = 0; break;
2338  case SQL_LONGVARBINARY: m = 65536; d = 0; break;
2339 #ifdef SQL_BIGINT
2340  case SQL_BIGINT: m = 20; d = 19; break;
2341 #endif
2342 #ifdef SQL_BIT
2343  case SQL_BIT: m = 1; d = 1; break;
2344 #endif
2345  }
2346  if (m && typename) {
2347  int mm, dd;
2348  char clbr[4];
2349 
2350  if (sscanf(typename, "%*[^(](%d,%d %1[)]", &mm, &dd, clbr) == 3) {
2351  m = mm;
2352  d = dd;
2353  } else if (sscanf(typename, "%*[^(](%d %1[)]", &mm, clbr) == 2) {
2354  if (sqltype == SQL_TIMESTAMP) {
2355  d = mm;
2356  }
2357 #ifdef SQL_TYPE_TIMESTAMP
2358  else if (sqltype == SQL_TYPE_TIMESTAMP) {
2359  d = mm;
2360  }
2361 #endif
2362  else {
2363  m = d = mm;
2364  }
2365  }
2366  }
2367  if (mp) {
2368  *mp = m;
2369  }
2370  if (dp) {
2371  *dp = d;
2372  }
2373 }
2374 
2384 static int
2385 mapdeftype(int type, int stype, int nosign, int nowchar)
2386 {
2387  if (type == SQL_C_DEFAULT) {
2388  switch (stype) {
2389  case SQL_INTEGER:
2390  type = (nosign > 0) ? SQL_C_ULONG : SQL_C_LONG;
2391  break;
2392  case SQL_TINYINT:
2393  type = (nosign > 0) ? SQL_C_UTINYINT : SQL_C_TINYINT;
2394  break;
2395  case SQL_SMALLINT:
2396  type = (nosign > 0) ? SQL_C_USHORT : SQL_C_SHORT;
2397  break;
2398  case SQL_FLOAT:
2399  type = SQL_C_FLOAT;
2400  break;
2401  case SQL_DOUBLE:
2402  type = SQL_C_DOUBLE;
2403  break;
2404  case SQL_TIMESTAMP:
2405  type = SQL_C_TIMESTAMP;
2406  break;
2407  case SQL_TIME:
2408  type = SQL_C_TIME;
2409  break;
2410  case SQL_DATE:
2411  type = SQL_C_DATE;
2412  break;
2413 #ifdef SQL_C_TYPE_TIMESTAMP
2414  case SQL_TYPE_TIMESTAMP:
2415  type = SQL_C_TYPE_TIMESTAMP;
2416  break;
2417 #endif
2418 #ifdef SQL_C_TYPE_TIME
2419  case SQL_TYPE_TIME:
2420  type = SQL_C_TYPE_TIME;
2421  break;
2422 #endif
2423 #ifdef SQL_C_TYPE_DATE
2424  case SQL_TYPE_DATE:
2425  type = SQL_C_TYPE_DATE;
2426  break;
2427 #endif
2428 #ifdef WINTERFACE
2429  case SQL_WVARCHAR:
2430  case SQL_WCHAR:
2431 #ifdef SQL_WLONGVARCHAR
2432  case SQL_WLONGVARCHAR:
2433 #endif
2434  type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
2435  break;
2436 #endif
2437  case SQL_BINARY:
2438  case SQL_VARBINARY:
2439  case SQL_LONGVARBINARY:
2440  type = SQL_C_BINARY;
2441  break;
2442 #ifdef SQL_BIT
2443  case SQL_BIT:
2444  type = SQL_C_BIT;
2445  break;
2446 #endif
2447 #ifdef SQL_BIGINT
2448  case SQL_BIGINT:
2449  type = SQL_C_CHAR;
2450  break;
2451 #endif
2452  default:
2453 #ifdef WINTERFACE
2454  type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
2455 #else
2456  type = SQL_C_CHAR;
2457 #endif
2458  break;
2459  }
2460  }
2461  return type;
2462 }
2463 
2470 static int
2471 checkddl(char *sql)
2472 {
2473  int isddl = 0;
2474 
2475  while (*sql && ISSPACE(*sql)) {
2476  ++sql;
2477  }
2478  if (*sql && *sql != ';') {
2479  int i, size;
2480  static const struct {
2481  int len;
2482  const char *str;
2483  } ddlstr[] = {
2484  { 5, "alter" },
2485  { 7, "analyze" },
2486  { 6, "attach" },
2487  { 5, "begin" },
2488  { 6, "commit" },
2489  { 6, "create" },
2490  { 6, "detach" },
2491  { 4, "drop" },
2492  { 3, "end" },
2493  { 7, "reindex" },
2494  { 7, "release" },
2495  { 8, "rollback" },
2496  { 9, "savepoint" },
2497  { 6, "vacuum" }
2498  };
2499 
2500  size = strlen(sql);
2501  for (i = 0; i < array_size(ddlstr); i++) {
2502  if (size >= ddlstr[i].len &&
2503  strncasecmp(sql, ddlstr[i].str, ddlstr[i].len) == 0) {
2504  isddl = 1;
2505  break;
2506  }
2507  }
2508  }
2509  return isddl;
2510 }
2511 
2523 static char *
2524 fixupsql(char *sql, int sqlLen, int cte, int *nparam, int *isselect,
2525  char **errmsg)
2526 {
2527  char *q = sql, *qz = NULL, *p, *inq = NULL, *out;
2528  int np = 0, isddl = -1, size;
2529 
2530  if (errmsg) {
2531  *errmsg = NULL;
2532  }
2533  if (sqlLen != SQL_NTS) {
2534  qz = q = xmalloc(sqlLen + 1);
2535  if (!qz) {
2536  return NULL;
2537  }
2538  memcpy(q, sql, sqlLen);
2539  q[sqlLen] = '\0';
2540  size = sqlLen * 4;
2541  } else {
2542  size = strlen(sql) * 4;
2543  }
2544  size += sizeof (char *) - 1;
2545  size &= ~(sizeof (char *) - 1);
2546  p = xmalloc(size);
2547  if (!p) {
2548 errout:
2549  freep(&qz);
2550  return NULL;
2551  }
2552  memset(p, 0, size);
2553  out = p;
2554  while (*q) {
2555  switch (*q) {
2556  case '\'':
2557  case '\"':
2558  if (q == inq) {
2559  inq = NULL;
2560  } else if (!inq) {
2561  inq = q + 1;
2562 
2563  while (*inq) {
2564  if (*inq == *q) {
2565  if (inq[1] == *q) {
2566  inq++;
2567  } else {
2568  break;
2569  }
2570  }
2571  inq++;
2572  }
2573  }
2574  *p++ = *q;
2575  break;
2576  case '?':
2577  *p++ = *q;
2578  if (!inq) {
2579  np++;
2580  }
2581  break;
2582  case ';':
2583  if (!inq) {
2584  if (isddl < 0) {
2585  isddl = checkddl(out);
2586  }
2587  if (isddl == 0) {
2588  char *qq = q;
2589 
2590  do {
2591  ++qq;
2592  } while (*qq && ISSPACE(*qq));
2593  if (*qq && *qq != ';') {
2594  freep(&out);
2595  if (errmsg) {
2596  *errmsg = "only one SQL statement allowed";
2597  }
2598  goto errout;
2599  }
2600  }
2601  }
2602  *p++ = *q;
2603  break;
2604  case '{':
2605  /*
2606  * Deal with escape sequences:
2607  * {d 'YYYY-MM-DD'}, {t ...}, {ts ...}
2608  * {oj ...}, {fn ...} etc.
2609  */
2610  if (!inq) {
2611  int ojfn = 0, brc = 0;
2612  char *inq2 = NULL, *end = q + 1, *start;
2613 
2614  while (*end && ISSPACE(*end)) {
2615  ++end;
2616  }
2617  if (*end != 'd' && *end != 'D' &&
2618  *end != 't' && *end != 'T') {
2619  ojfn = 1;
2620  }
2621  start = end;
2622  while (*end) {
2623  if (inq2 && *end == *inq2) {
2624  inq2 = NULL;
2625  } else if (inq2 == NULL && *end == '{') {
2626  char *nerr = 0, *nsql;
2627 
2628  nsql = fixupsql(end, SQL_NTS, cte, 0, 0, &nerr);
2629  if (nsql && !nerr) {
2630  strcpy(end, nsql);
2631  } else {
2632  brc++;
2633  }
2634  freep(&nsql);
2635  } else if (inq2 == NULL && *end == '}') {
2636  if (brc-- <= 0) {
2637  break;
2638  }
2639  } else if (inq2 == NULL && (*end == '\'' || *end == '"')) {
2640  inq2 = end;
2641  } else if (inq2 == NULL && *end == '?') {
2642  np++;
2643  }
2644  ++end;
2645  }
2646  if (*end == '}') {
2647  char *end2 = end - 1;
2648 
2649  if (ojfn) {
2650  while (start < end) {
2651  if (ISSPACE(*start)) {
2652  break;
2653  }
2654  ++start;
2655  }
2656  while (start < end) {
2657  *p++ = *start;
2658  ++start;
2659  }
2660  q = end;
2661  break;
2662  } else {
2663  while (start < end2 && *start != '\'') {
2664  ++start;
2665  }
2666  while (end2 > start && *end2 != '\'') {
2667  --end2;
2668  }
2669  if (*start == '\'' && *end2 == '\'') {
2670  while (start <= end2) {
2671  *p++ = *start;
2672  ++start;
2673  }
2674  q = end;
2675  break;
2676  }
2677  }
2678  }
2679  }
2680  /* FALL THROUGH */
2681  default:
2682  *p++ = *q;
2683  }
2684  ++q;
2685  }
2686  freep(&qz);
2687  *p = '\0';
2688  if (nparam) {
2689  *nparam = np;
2690  }
2691  if (isselect) {
2692  if (isddl < 0) {
2693  isddl = checkddl(out);
2694  }
2695  if (isddl > 0) {
2696  *isselect = 2;
2697  } else {
2698  int incom = 0;
2699 
2700  p = out;
2701  while (*p) {
2702  switch (*p) {
2703  case '-':
2704  if (!incom && p[1] == '-') {
2705  incom = -1;
2706  }
2707  break;
2708  case '\n':
2709  if (incom < 0) {
2710  incom = 0;
2711  }
2712  break;
2713  case '/':
2714  if (incom > 0 && p[-1] == '*') {
2715  incom = 0;
2716  p++;
2717  continue;
2718  } else if (!incom && p[1] == '*') {
2719  incom = 1;
2720  }
2721  break;
2722  }
2723  if (!incom && !ISSPACE(*p)) {
2724  break;
2725  }
2726  p++;
2727  }
2728  size = strlen(p);
2729  if (size >= 6 &&
2730  (strncasecmp(p, "select", 6) == 0 ||
2731  strncasecmp(p, "pragma", 6) == 0)) {
2732  *isselect = 1;
2733  } else if (cte && size >= 4 && strncasecmp(p, "with", 4) == 0) {
2734  *isselect = 1;
2735  } else if (size >= 7 && strncasecmp(p, "explain", 7) == 0) {
2736  *isselect = 1;
2737  } else {
2738  *isselect = 0;
2739  }
2740  }
2741  }
2742  return out;
2743 }
2744 
2753 static int
2754 findcol(char **cols, int ncols, char *name)
2755 {
2756  int i;
2757 
2758  if (cols) {
2759  for (i = 0; i < ncols; i++) {
2760  if (strcmp(cols[i], name) == 0) {
2761  return i;
2762  }
2763  }
2764  }
2765  return -1;
2766 }
2767 
2784 static void
2786 {
2787  int i, k;
2788 #ifndef FULL_METADATA
2789  int pk, nn, t, r, nrows, ncols;
2790  char **rowp, *flagp, flags[128];
2791 #endif
2792 
2793  if (!s->dyncols) {
2794  return;
2795  }
2796  /* fixup labels */
2797  if (!s->longnames) {
2798  if (s->dcols > 1) {
2799  char *table = s->dyncols[0].table;
2800 
2801  for (i = 1; table[0] && i < s->dcols; i++) {
2802  if (strcmp(s->dyncols[i].table, table)) {
2803  break;
2804  }
2805  }
2806  if (i >= s->dcols) {
2807  for (i = 0; i < s->dcols; i++) {
2808  s->dyncols[i].label = s->dyncols[i].column;
2809  }
2810  }
2811  } else if (s->dcols == 1) {
2812  s->dyncols[0].label = s->dyncols[0].column;
2813  }
2814  }
2815  for (i = 0; i < s->dcols; i++) {
2816  s->dyncols[i].type =
2817  mapsqltype(s->dyncols[i].typename, &s->dyncols[i].nosign, *s->ov3,
2818  s->nowchar[0] || s->nowchar[1], s->dobigint);
2819  getmd(s->dyncols[i].typename, s->dyncols[i].type,
2820  &s->dyncols[i].size, &s->dyncols[i].prec);
2821 #ifdef SQL_LONGVARCHAR
2822  if (s->dyncols[i].type == SQL_VARCHAR &&
2823  s->dyncols[i].size > 255) {
2824  s->dyncols[i].type = SQL_LONGVARCHAR;
2825  }
2826 #endif
2827 #ifdef WINTERFACE
2828 #ifdef SQL_WLONGVARCHAR
2829  if (s->dyncols[i].type == SQL_WVARCHAR &&
2830  s->dyncols[i].size > 255) {
2831  s->dyncols[i].type = SQL_WLONGVARCHAR;
2832  }
2833 #endif
2834 #endif
2835  if (s->dyncols[i].type == SQL_VARBINARY &&
2836  s->dyncols[i].size > 255) {
2837  s->dyncols[i].type = SQL_LONGVARBINARY;
2838  }
2839  }
2840 #ifndef FULL_METADATA
2841  if (s->dcols > array_size(flags)) {
2842  flagp = xmalloc(sizeof (flags[0]) * s->dcols);
2843  if (flagp == NULL) {
2844  return;
2845  }
2846  } else {
2847  flagp = flags;
2848  }
2849  memset(flagp, 0, sizeof (flags[0]) * s->dcols);
2850  for (i = 0; i < s->dcols; i++) {
2851  s->dyncols[i].autoinc = SQL_FALSE;
2852  s->dyncols[i].notnull = SQL_NULLABLE;
2853  }
2854  for (i = 0; i < s->dcols; i++) {
2855  int ret, lastpk = -1, autoinccount = 0;
2856  char *sql;
2857 
2858  if (!s->dyncols[i].table[0]) {
2859  continue;
2860  }
2861  if (flagp[i]) {
2862  continue;
2863  }
2864  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", s->dyncols[i].table);
2865  if (!sql) {
2866  continue;
2867  }
2868  dbtraceapi(d, "sqlite3_get_table", sql);
2869  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, NULL);
2870  sqlite3_free(sql);
2871  if (ret != SQLITE_OK) {
2872  continue;
2873  }
2874  k = findcol(rowp, ncols, "name");
2875  t = findcol(rowp, ncols, "type");
2876  pk = findcol(rowp, ncols, "pk");
2877  nn = findcol(rowp, ncols, "notnull");
2878  if (k < 0 || t < 0) {
2879  goto freet;
2880  }
2881  for (r = 1; r <= nrows; r++) {
2882  int m;
2883 
2884  for (m = i; m < s->dcols; m++) {
2885  char *colname = s->dyncols[m].column;
2886 
2887  if (s->longnames) {
2888  char *dotp = strchr(colname, '.');
2889 
2890  if (dotp) {
2891  colname = dotp + 1;
2892  }
2893  }
2894  if (!flagp[m] &&
2895  strcmp(colname, rowp[r * ncols + k]) == 0 &&
2896  strcmp(s->dyncols[m].table, s->dyncols[i].table) == 0) {
2897  char *typename = rowp[r * ncols + t];
2898 
2899  flagp[m] = i + 1;
2900  freep(&s->dyncols[m].typename);
2901  s->dyncols[m].typename = xstrdup(typename);
2902  s->dyncols[m].type =
2903  mapsqltype(typename, &s->dyncols[m].nosign, *s->ov3,
2904  s->nowchar[0] || s->nowchar[1],
2905  s->dobigint);
2906  getmd(typename, s->dyncols[m].type, &s->dyncols[m].size,
2907  &s->dyncols[m].prec);
2908 #ifdef SQL_LONGVARCHAR
2909  if (s->dyncols[m].type == SQL_VARCHAR &&
2910  s->dyncols[m].size > 255) {
2911  s->dyncols[m].type = SQL_LONGVARCHAR;
2912  }
2913 #endif
2914 #ifdef WINTERFACE
2915 #ifdef SQL_WLONGVARCHAR
2916  if (s->dyncols[i].type == SQL_WVARCHAR &&
2917  s->dyncols[i].size > 255) {
2918  s->dyncols[i].type = SQL_WLONGVARCHAR;
2919  }
2920 #endif
2921 #endif
2922  if (s->dyncols[i].type == SQL_VARBINARY &&
2923  s->dyncols[i].size > 255) {
2924  s->dyncols[i].type = SQL_LONGVARBINARY;
2925  }
2926  if (pk >= 0 && strcmp(rowp[r * ncols + pk], "1") == 0) {
2927  s->dyncols[m].ispk = 1;
2928  if (++autoinccount > 1) {
2929  if (lastpk >= 0) {
2930  s->dyncols[lastpk].autoinc = SQL_FALSE;
2931  lastpk = -1;
2932  }
2933  } else {
2934  lastpk = m;
2935  if (strlen(typename) == 7 &&
2936  strncasecmp(typename, "integer", 7) == 0) {
2937  s->dyncols[m].autoinc = SQL_TRUE;
2938  }
2939  }
2940  } else {
2941  s->dyncols[m].ispk = 0;
2942  }
2943  if (nn >= 0 && rowp[r * ncols + nn][0] != '0') {
2944  s->dyncols[m].notnull = SQL_NO_NULLS;
2945  }
2946  }
2947  }
2948  }
2949 freet:
2950  sqlite3_free_table(rowp);
2951  }
2952  for (i = k = 0; i < s->dcols; i++) {
2953  if (flagp[i] == 0) {
2954  break;
2955  }
2956  if (k == 0) {
2957  k = flagp[i];
2958  } else if (flagp[i] != k) {
2959  k = 0;
2960  break;
2961  }
2962  }
2963  s->one_tbl = k ? 1 : 0;
2964  k = 0;
2965  if (s->one_tbl) {
2966  for (i = 0; i < s->dcols; i++) {
2967  if (s->dyncols[i].ispk > 0) {
2968  ++k;
2969  }
2970  }
2971  }
2972  s->has_pk = k;
2973  if (flagp != flags) {
2974  freep(&flagp);
2975  }
2976 #else
2977  for (i = 1, k = 0; i < s->dcols; i++) {
2978  if (strcmp(s->dyncols[i].table, s->dyncols[0].table) == 0) {
2979  k++;
2980  }
2981  }
2982  s->one_tbl = (k && k + 1 == s->dcols) ? 1 : 0;
2983  k = 0;
2984  if (s->one_tbl) {
2985  for (i = 0; i < s->dcols; i++) {
2986  if (s->dyncols[i].ispk > 0) {
2987  ++k;
2988  if (s->has_rowid < 0 && s->dyncols[i].isrowid > 0) {
2989  s->has_rowid = i;
2990  }
2991  }
2992  }
2993  }
2994  s->has_pk = k;
2995 #endif
2996 }
2997 
3004 static void
3005 convJD2YMD(double jd, DATE_STRUCT *ds)
3006 {
3007  int z, a, b, c, d, e, x1;
3008  sqlite_int64 ijd;
3009 
3010  ijd = jd * 86400000.0 + 0.5;
3011  z = (int) ((ijd + 43200000) / 86400000);
3012  a = (int) ((z - 1867216.25) / 36524.25);
3013  a = z + 1 + a - (a / 4);
3014  b = a + 1524;
3015  c = (int) ((b - 122.1) / 365.25);
3016  d = (36525 * c) / 100;
3017  e = (int) ((b - d) / 30.6001);
3018  x1 = (int) (30.6001 * e);
3019  ds->day = b - d - x1;
3020  ds->month = (e < 14) ? (e - 1) : (e - 13);
3021  ds->year = (ds->month > 2) ? (c - 4716) : (c - 4715);
3022 }
3023 
3024 
3032 static void
3033 convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
3034 {
3035  int s;
3036  double ds;
3037  sqlite_int64 ijd;
3038 
3039  ijd = jd * 86400000.0 + 0.5;
3040  s = (int)((ijd + 43200000) % 86400000);
3041  ds = s / 1000.0;
3042  if (fp) {
3043  *fp = (s % 1000) * 1000000;
3044  }
3045  s = (int) ds;
3046  ds -= s;
3047  ts->hour = s / 3600;
3048  s -= ts->hour * 3600;
3049  ts->minute = s / 60;
3050  ds += s - ts->minute *60;
3051  ts->second = (int) ds;
3052 }
3053 
3061 static int
3062 getmdays(int year, int month)
3063 {
3064  static const int mdays[] = {
3065  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
3066  };
3067  int mday;
3068 
3069  if (month < 1) {
3070  return 0;
3071  }
3072  mday = mdays[(month - 1) % 12];
3073  if (mday == 28 && year % 4 == 0 &&
3074  (!(year % 100 == 0) || year % 400 == 0)) {
3075  mday++;
3076  }
3077  return mday;
3078 }
3079 
3095 static int
3096 str2date(int jdconv, char *str, DATE_STRUCT *ds)
3097 {
3098  int i, err = 0;
3099  double jd;
3100  char *p, *q, sepc = '\0';
3101 
3102  ds->year = ds->month = ds->day = 0;
3103  if (jdconv) {
3104  p = strchr(str, '.');
3105  if (p) {
3106  /* julian day format */
3107  p = 0;
3108  jd = ln_strtod(str, &p);
3109  if (p && p > str) {
3110  convJD2YMD(jd, ds);
3111  return 0;
3112  }
3113  }
3114  }
3115  p = str;
3116  while (*p && !ISDIGIT(*p)) {
3117  ++p;
3118  }
3119  q = p;
3120  i = 0;
3121  while (*q && !ISDIGIT(*q)) {
3122  ++i;
3123  ++q;
3124  }
3125  if (i >= 8) {
3126  char buf[8];
3127 
3128  strncpy(buf, p + 0, 4); buf[4] = '\0';
3129  ds->year = strtol(buf, NULL, 10);
3130  strncpy(buf, p + 4, 2); buf[2] = '\0';
3131  ds->month = strtol(buf, NULL, 10);
3132  strncpy(buf, p + 6, 2); buf[2] = '\0';
3133  ds->day = strtol(buf, NULL, 10);
3134  goto done;
3135  }
3136  i = 0;
3137  while (i < 3) {
3138  int n;
3139 
3140  q = NULL;
3141  n = strtol(p, &q, 10);
3142  if (!q || q == p) {
3143  if (*q == '\0') {
3144  if (i == 0) {
3145  err = 1;
3146  }
3147  goto done;
3148  }
3149  }
3150  if (!sepc) {
3151  sepc = *q;
3152  }
3153  if (*q == '-' || *q == '/' || *q == '\0' || i == 2) {
3154  switch (i) {
3155  case 0: ds->year = n; break;
3156  case 1: ds->month = n; break;
3157  case 2: ds->day = n; break;
3158  }
3159  ++i;
3160  if (*q) {
3161  ++q;
3162  }
3163  } else {
3164  i = 0;
3165  while (*q && !ISDIGIT(*q)) {
3166  ++q;
3167  }
3168  }
3169  p = q;
3170  }
3171 done:
3172  /* final check for overflow */
3173  if (err ||
3174  ds->month < 1 || ds->month > 12 ||
3175  ds->day < 1 || ds->day > getmdays(ds->year, ds->month)) {
3176  if (sepc == '/') {
3177  /* Try MM/DD/YYYY format */
3178  int t[3];
3179 
3180  t[0] = ds->year;
3181  t[1] = ds->month;
3182  t[2] = ds->day;
3183  ds->year = t[2];
3184  ds->day = t[1];
3185  ds->month = t[0];
3186  if (ds->month >= 1 && ds->month <= 12 &&
3187  (ds->day >= 1 || ds->day <= getmdays(ds->year, ds->month))) {
3188  return 0;
3189  }
3190  }
3191  return -1;
3192  }
3193  return 0;
3194 }
3195 
3210 static int
3211 str2time(int jdconv, char *str, TIME_STRUCT *ts)
3212 {
3213  int i, err = 0, ampm = -1;
3214  double jd;
3215  char *p, *q;
3216 
3217  ts->hour = ts->minute = ts->second = 0;
3218  if (jdconv) {
3219  p = strchr(str, '.');
3220  if (p) {
3221  /* julian day format */
3222  p = 0;
3223  jd = ln_strtod(str, &p);
3224  if (p && p > str) {
3225  convJD2HMS(jd, ts, 0);
3226  return 0;
3227  }
3228  }
3229  }
3230  p = str;
3231  while (*p && !ISDIGIT(*p)) {
3232  ++p;
3233  }
3234  q = p;
3235  i = 0;
3236  while (*q && ISDIGIT(*q)) {
3237  ++i;
3238  ++q;
3239  }
3240  if (i >= 6) {
3241  char buf[4];
3242 
3243  strncpy(buf, p + 0, 2); buf[2] = '\0';
3244  ts->hour = strtol(buf, NULL, 10);
3245  strncpy(buf, p + 2, 2); buf[2] = '\0';
3246  ts->minute = strtol(buf, NULL, 10);
3247  strncpy(buf, p + 4, 2); buf[2] = '\0';
3248  ts->second = strtol(buf, NULL, 10);
3249  goto done;
3250  }
3251  i = 0;
3252  while (i < 3) {
3253  int n;
3254 
3255  q = NULL;
3256  n = strtol(p, &q, 10);
3257  if (!q || q == p) {
3258  if (*q == '\0') {
3259  if (i == 0) {
3260  err = 1;
3261  }
3262  goto done;
3263  }
3264  }
3265  if (*q == ':' || *q == '\0' || i == 2) {
3266  switch (i) {
3267  case 0: ts->hour = n; break;
3268  case 1: ts->minute = n; break;
3269  case 2: ts->second = n; break;
3270  }
3271  ++i;
3272  if (*q) {
3273  ++q;
3274  }
3275  } else {
3276  i = 0;
3277  while (*q && !ISDIGIT(*q)) {
3278  ++q;
3279  }
3280  }
3281  p = q;
3282  }
3283  if (!err) {
3284  while (*p) {
3285  if ((p[0] == 'p' || p[0] == 'P') &&
3286  (p[1] == 'm' || p[1] == 'M')) {
3287  ampm = 1;
3288  } else if ((p[0] == 'a' || p[0] == 'A') &&
3289  (p[1] == 'm' || p[1] == 'M')) {
3290  ampm = 0;
3291  }
3292  ++p;
3293  }
3294  if (ampm > 0) {
3295  if (ts->hour < 12) {
3296  ts->hour += 12;
3297  }
3298  } else if (ampm == 0) {
3299  if (ts->hour == 12) {
3300  ts->hour = 0;
3301  }
3302  }
3303  }
3304 done:
3305  /* final check for overflow */
3306  if (err || ts->hour > 23 || ts->minute > 59 || ts->second > 59) {
3307  return -1;
3308  }
3309  return 0;
3310 }
3311 
3331 static int
3332 str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
3333 {
3334  int i, m, n, err = 0, ampm = -1;
3335  double jd;
3336  char *p, *q, in = '\0', sepc = '\0';
3337 
3338  tss->year = tss->month = tss->day = 0;
3339  tss->hour = tss->minute = tss->second = 0;
3340  tss->fraction = 0;
3341  if (jdconv) {
3342  p = strchr(str, '.');
3343  if (p) {
3344  q = strchr(str, '-');
3345  if (q == str) {
3346  q = 0;
3347  }
3348  if (!q) {
3349  q = strchr(str, '/');
3350  if (!q) {
3351  q = strchr(str, ':');
3352  }
3353  }
3354  if (!q || q > p) {
3355  /* julian day format */
3356  p = 0;
3357  jd = ln_strtod(str, &p);
3358  if (p && p > str) {
3359  DATE_STRUCT ds;
3360  TIME_STRUCT ts;
3361 
3362  convJD2YMD(jd, &ds);
3363  convJD2HMS(jd, &ts, &n);
3364  tss->year = ds.year;
3365  tss->month = ds.month;
3366  tss->day = ds.day;
3367  tss->hour = ts.hour;
3368  tss->minute = ts.minute;
3369  tss->second = ts.second;
3370  tss->fraction = n;
3371  return 0;
3372  }
3373  }
3374  }
3375  }
3376  p = str;
3377  while (*p && !ISDIGIT(*p)) {
3378  ++p;
3379  }
3380  q = p;
3381  i = 0;
3382  while (*q && ISDIGIT(*q)) {
3383  ++i;
3384  ++q;
3385  }
3386  if (i >= 14) {
3387  char buf[16];
3388 
3389  strncpy(buf, p + 0, 4); buf[4] = '\0';
3390  tss->year = strtol(buf, NULL, 10);
3391  strncpy(buf, p + 4, 2); buf[2] = '\0';
3392  tss->month = strtol(buf, NULL, 10);
3393  strncpy(buf, p + 6, 2); buf[2] = '\0';
3394  tss->day = strtol(buf, NULL, 10);
3395  strncpy(buf, p + 8, 2); buf[2] = '\0';
3396  tss->hour = strtol(buf, NULL, 10);
3397  strncpy(buf, p + 10, 2); buf[2] = '\0';
3398  tss->minute = strtol(buf, NULL, 10);
3399  strncpy(buf, p + 12, 2); buf[2] = '\0';
3400  tss->second = strtol(buf, NULL, 10);
3401  if (i > 14) {
3402  m = i - 14;
3403  strncpy(buf, p + 14, m);
3404  while (m < 9) {
3405  buf[m] = '0';
3406  ++m;
3407  }
3408  buf[m] = '\0';
3409  tss->fraction = strtol(buf, NULL, 10);
3410  }
3411  m = 7;
3412  goto done;
3413  }
3414  m = i = 0;
3415  while ((m & 7) != 7) {
3416  q = NULL;
3417  n = strtol(p, &q, 10);
3418  if (!q || q == p) {
3419  if (*q == '\0') {
3420  if (m < 1) {
3421  err = 1;
3422  }
3423  goto done;
3424  }
3425  }
3426  if (in == '\0') {
3427  switch (*q) {
3428  case '-':
3429  case '/':
3430  if ((m & 1) == 0) {
3431  in = *q;
3432  i = 0;
3433  }
3434  break;
3435  case ':':
3436  if ((m & 2) == 0) {
3437  in = *q;
3438  i = 0;
3439  }
3440  break;
3441  case ' ':
3442  case '.':
3443  break;
3444  default:
3445  in = '\0';
3446  i = 0;
3447  break;
3448  }
3449  }
3450  switch (in) {
3451  case '-':
3452  case '/':
3453  if (!sepc) {
3454  sepc = in;
3455  }
3456  switch (i) {
3457  case 0: tss->year = n; break;
3458  case 1: tss->month = n; break;
3459  case 2: tss->day = n; break;
3460  }
3461  if (++i >= 3) {
3462  i = 0;
3463  m |= 1;
3464  if (!(m & 2)) {
3465  m |= 8;
3466  }
3467  goto skip;
3468  } else {
3469  ++q;
3470  }
3471  break;
3472  case ':':
3473  switch (i) {
3474  case 0: tss->hour = n; break;
3475  case 1: tss->minute = n; break;
3476  case 2: tss->second = n; break;
3477  }
3478  if (++i >= 3) {
3479  i = 0;
3480  m |= 2;
3481  if (*q == '.') {
3482  in = '.';
3483  goto skip2;
3484  }
3485  if (*q == ' ') {
3486  if ((m & 1) == 0) {
3487  char *e = NULL;
3488 
3489  (void) strtol(q + 1, &e, 10);
3490  if (e && *e == '-') {
3491  goto skip;
3492  }
3493  }
3494  in = '.';
3495  goto skip2;
3496  }
3497  goto skip;
3498  } else {
3499  ++q;
3500  }
3501  break;
3502  case '.':
3503  if (++i >= 1) {
3504  int ndig = q - p;
3505 
3506  if (p[0] == '+' || p[0] == '-') {
3507  ndig--;
3508  }
3509  while (ndig < 9) {
3510  n = n * 10;
3511  ++ndig;
3512  }
3513  tss->fraction = n;
3514  m |= 4;
3515  i = 0;
3516  }
3517  default:
3518  skip:
3519  in = '\0';
3520  skip2:
3521  while (*q && !ISDIGIT(*q)) {
3522  if ((q[0] == 'a' || q[0] == 'A') &&
3523  (q[1] == 'm' || q[1] == 'M')) {
3524  ampm = 0;
3525  ++q;
3526  } else if ((q[0] == 'p' || q[0] == 'P') &&
3527  (q[1] == 'm' || q[1] == 'M')) {
3528  ampm = 1;
3529  ++q;
3530  }
3531  ++q;
3532  }
3533  }
3534  p = q;
3535  }
3536  if ((m & 7) > 1 && (m & 8)) {
3537  /* ISO8601 timezone */
3538  if (p > str && ISDIGIT(*p)) {
3539  int nn, sign;
3540 
3541  q = p - 1;
3542  if (*q != '+' && *q != '-') {
3543  goto done;
3544  }
3545  sign = (*q == '+') ? -1 : 1;
3546  q = NULL;
3547  n = strtol(p, &q, 10);
3548  if (!q || *q++ != ':' || !ISDIGIT(*q)) {
3549  goto done;
3550  }
3551  p = q;
3552  q = NULL;
3553  nn = strtol(p, &q, 10);
3554  tss->minute += nn * sign;
3555  if ((SQLSMALLINT) tss->minute < 0) {
3556  tss->hour -= 1;
3557  tss->minute += 60;
3558  } else if (tss->minute >= 60) {
3559  tss->hour += 1;
3560  tss->minute -= 60;
3561  }
3562  tss->hour += n * sign;
3563  if ((SQLSMALLINT) tss->hour < 0) {
3564  tss->day -= 1;
3565  tss->hour += 24;
3566  } else if (tss->hour >= 24) {
3567  tss->day += 1;
3568  tss->hour -= 24;
3569  }
3570  if ((short) tss->day < 1 || tss->day >= 28) {
3571  int mday, pday, pmon;
3572 
3573  mday = getmdays(tss->year, tss->month);
3574  pmon = tss->month - 1;
3575  if (pmon < 1) {
3576  pmon = 12;
3577  }
3578  pday = getmdays(tss->year, pmon);
3579  if ((SQLSMALLINT) tss->day < 1) {
3580  tss->month -= 1;
3581  tss->day = pday;
3582  } else if (tss->day > mday) {
3583  tss->month += 1;
3584  tss->day = 1;
3585  }
3586  if ((SQLSMALLINT) tss->month < 1) {
3587  tss->year -= 1;
3588  tss->month = 12;
3589  } else if (tss->month > 12) {
3590  tss->year += 1;
3591  tss->month = 1;
3592  }
3593  }
3594  }
3595  }
3596 done:
3597  if ((m & 1) &&
3598  (tss->month < 1 || tss->month > 12 ||
3599  tss->day < 1 || tss->day > getmdays(tss->year, tss->month))) {
3600  if (sepc == '/') {
3601  /* Try MM/DD/YYYY format */
3602  int t[3];
3603 
3604  t[0] = tss->year;
3605  t[1] = tss->month;
3606  t[2] = tss->day;
3607  tss->year = t[2];
3608  tss->day = t[1];
3609  tss->month = t[0];
3610  }
3611  }
3612  /* Replace missing year/month/day with current date */
3613  if (!err && (m & 1) == 0) {
3614 #ifdef _WIN32
3615  SYSTEMTIME t;
3616 
3617  GetLocalTime(&t);
3618  tss->year = t.wYear;
3619  tss->month = t.wMonth;
3620  tss->day = t.wDay;
3621 #else
3622  struct timeval tv;
3623  struct tm tm;
3624 
3625  gettimeofday(&tv, NULL);
3626  tm = *localtime(&tv.tv_sec);
3627  tss->year = tm.tm_year + 1900;
3628  tss->month = tm.tm_mon + 1;
3629  tss->day = tm.tm_mday;
3630 #endif
3631  }
3632  /* Normalize fraction */
3633  if (tss->fraction < 0) {
3634  tss->fraction = 0;
3635  }
3636  /* Final check for overflow */
3637  if (err ||
3638  tss->month < 1 || tss->month > 12 ||
3639  tss->day < 1 || tss->day > getmdays(tss->year, tss->month) ||
3640  tss->hour > 23 || tss->minute > 59 || tss->second > 59) {
3641  return -1;
3642  }
3643  if ((m & 7) > 1) {
3644  if (ampm > 0) {
3645  if (tss->hour < 12) {
3646  tss->hour += 12;
3647  }
3648  } else if (ampm == 0) {
3649  if (tss->hour == 12) {
3650  tss->hour = 0;
3651  }
3652  }
3653  }
3654  return ((m & 7) < 1) ? -1 : 0;
3655 }
3656 
3663 static int
3664 getbool(char *string)
3665 {
3666  if (string) {
3667  return string[0] && strchr("Yy123456789Tt", string[0]) != NULL;
3668  }
3669  return 0;
3670 }
3671 
3679 static void
3680 blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
3681 {
3682 #if 0
3683  DBC *d = (DBC *) sqlite3_user_data(ctx);
3684 #endif
3685  char *filename = 0;
3686 
3687  if (nargs > 0) {
3688  if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
3689  filename = (char *) sqlite3_value_text(args[0]);
3690  }
3691  }
3692  if (filename) {
3693 #ifdef _WIN32
3694  char *wname = utf_to_wmb(filename, -1);
3695  FILE *f;
3696 #else
3697  FILE *f = fopen(filename, "r");
3698 #endif
3699  char *p;
3700  long n, nn;
3701 
3702 #ifdef _WIN32
3703  if (wname) {
3704  f = fopen(wname, "rb");
3705  } else {
3706  sqlite3_result_error(ctx, "out of memory", -1);
3707  return;
3708  }
3709  uc_free(wname);
3710 #endif
3711  if (f) {
3712  if (fseek(f, 0, SEEK_END) == 0) {
3713  n = ftell(f);
3714  if (fseek(f, 0, SEEK_SET) == 0) {
3715  p = sqlite3_malloc(n);
3716  if (p) {
3717  nn = fread(p, 1, n, f);
3718  if (nn != n) {
3719  sqlite3_result_error(ctx, "read error", -1);
3720  sqlite3_free(p);
3721  } else {
3722  sqlite3_result_blob(ctx, p, n, sqlite3_free);
3723  }
3724  } else {
3725  sqlite3_result_error(ctx, "out of memory", -1);
3726  }
3727  } else {
3728  sqlite3_result_error(ctx, "seek error", -1);
3729  }
3730  } else {
3731  sqlite3_result_error(ctx, "seek error", -1);
3732  }
3733  fclose(f);
3734  } else {
3735  sqlite3_result_error(ctx, "cannot open file", -1);
3736  }
3737  } else {
3738  sqlite3_result_error(ctx, "no filename given", -1);
3739  }
3740 }
3741 
3749 static void
3750 blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
3751 {
3752 #if 0
3753  DBC *d = (DBC *) sqlite3_user_data(ctx);
3754 #endif
3755  char *filename = 0;
3756  char *p = 0;
3757  int n = 0;
3758 
3759  if (nargs > 0) {
3760  p = (char *) sqlite3_value_blob(args[0]);
3761  n = sqlite3_value_bytes(args[0]);
3762  }
3763  if (nargs > 1) {
3764  if (sqlite3_value_type(args[1]) != SQLITE_NULL) {
3765  filename = (char *) sqlite3_value_text(args[1]);
3766  }
3767  }
3768  if (p) {
3769  if (filename) {
3770 #ifdef _WIN32
3771  char *wname = utf_to_wmb(filename, -1);
3772  FILE *f;
3773 #else
3774  FILE *f = fopen(filename, "w");
3775 #endif
3776  int nn;
3777 
3778 #ifdef _WIN32
3779  if (wname) {
3780  f = fopen(wname, "wb");
3781  } else {
3782  sqlite3_result_error(ctx, "out of memory", -1);
3783  return;
3784  }
3785  uc_free(wname);
3786 #endif
3787  if (f) {
3788  nn = fwrite(p, 1, n, f);
3789  fclose(f);
3790  if (nn != n) {
3791  sqlite3_result_error(ctx, "write error", -1);
3792  } else {
3793  sqlite3_result_int(ctx, nn);
3794  }
3795  } else {
3796  sqlite3_result_error(ctx, "cannot open file", -1);
3797  }
3798  } else {
3799  sqlite3_result_error(ctx, "no filename given", -1);
3800  }
3801  } else {
3802  sqlite3_result_null(ctx);
3803  }
3804 }
3805 
3813 static void
3814 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3815 dbtrace(void *arg, const char *msg, sqlite_uint64 et)
3816 #else
3817 dbtrace(void *arg, const char *msg)
3818 #endif
3819 {
3820  DBC *d = (DBC *) arg;
3821 
3822  if (msg && d->trace) {
3823  int len = strlen(msg);
3824 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3825  unsigned long s, f;
3826 #endif
3827 
3828  if (len > 0) {
3829  char *end = "\n";
3830 
3831  if (msg[len - 1] != ';') {
3832  end = ";\n";
3833  }
3834  fprintf(d->trace, "%s%s", msg, end);
3835 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3836  s = et / 1000000000LL;
3837  f = et % 1000000000LL;
3838  fprintf(d->trace, "-- took %lu.%09lu seconds\n", s, f);
3839 #endif
3840  fflush(d->trace);
3841  }
3842  }
3843 }
3844 
3852 static void
3853 dbtraceapi(DBC *d, char *fn, const char *sql)
3854 {
3855  if (fn && d->trace) {
3856  if (sql) {
3857  fprintf(d->trace, "-- %s: %s\n", fn, sql);
3858  } else {
3859  fprintf(d->trace, "-- %s\n", fn);
3860  }
3861  fflush(d->trace);
3862  }
3863 }
3864 
3872 static void
3873 dbtracerc(DBC *d, int rc, char *err)
3874 {
3875  if (rc != SQLITE_OK && d->trace) {
3876  fprintf(d->trace, "-- SQLITE ERROR CODE %d", rc);
3877  fprintf(d->trace, err ? ": %s\n" : "\n", err);
3878  fflush(d->trace);
3879  }
3880 }
3881 
3896 static SQLRETURN
3897 dbopen(DBC *d, char *name, int isu, char *dsn, char *sflag,
3898  char *spflag, char *ntflag, char *jmode, char *busy)
3899 {
3900  char *endp = NULL;
3901  int rc, tmp, busyto = 100000;
3902 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
3903  int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
3904  char *uname = name;
3905  const char *vfs_name = NULL;
3906 #endif
3907 
3908  if (d->sqlite) {
3909  if (d->trace) {
3910  fprintf(d->trace, "-- sqlite3_close (deferred): '%s'\n",
3911  d->dbname);
3912  fflush(d->trace);
3913  }
3914 #if defined(HAVE_SQLITE3CLOSEV2) && (HAVE_SQLITE3CLOSEV2)
3915  sqlite3_close_v2(d->sqlite);
3916 #else
3917  sqlite3_close(d->sqlite);
3918 #endif
3919  d->sqlite = NULL;
3920  }
3921 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
3922  if (d->nocreat) {
3923  flags &= ~ SQLITE_OPEN_CREATE;
3924  }
3925 #if defined(_WIN32) || defined(_WIN64)
3926  if (!isu) {
3927  char expname[SQL_MAX_MESSAGE_LENGTH * 2];
3928 
3929  expname[0] = '\0';
3930  rc = ExpandEnvironmentStrings(name, expname, sizeof (expname));
3931  if (rc <= sizeof (expname)) {
3932  uname = wmb_to_utf(expname, rc - 1);
3933  } else {
3934  uname = wmb_to_utf(name, -1);
3935  }
3936  if (!uname) {
3937  rc = SQLITE_NOMEM;
3938  setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
3939  return SQL_ERROR;
3940  }
3941  }
3942 #endif
3943 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
3944  vfs_name = nvfs_makevfs(uname);
3945 #endif
3946 #ifdef SQLITE_OPEN_URI
3947  flags |= SQLITE_OPEN_URI;
3948 #endif
3949  rc = sqlite3_open_v2(uname, &d->sqlite, flags, vfs_name);
3950 #if defined(WINTERFACE) || defined(_WIN32) || defined(_WIN64)
3951  if (uname != name) {
3952  uc_free(uname);
3953  }
3954 #endif
3955 #else
3956 #if defined(_WIN32) || defined(_WIN64)
3957  if (d->nocreat) {
3958  char *cname = NULL;
3959 
3960  if (isu) {
3961  cname = utf_to_wmb(name, -1);
3962  }
3963  if (GetFileAttributesA(cname ? cname : name) ==
3964  INVALID_FILE_ATTRIBUTES) {
3965  uc_free(cname);
3966  rc = SQLITE_CANTOPEN;
3967  setstatd(d, rc, "cannot open database",
3968  (*d->ov3) ? "HY000" : "S1000");
3969  return SQL_ERROR;
3970  }
3971  uc_free(cname);
3972  }
3973 #else
3974  if (d->nocreat && access(name, 004) < 0) {
3975  rc = SQLITE_CANTOPEN;
3976  setstatd(d, rc, "cannot open database", (*d->ov3) ? "HY000" : "S1000");
3977  return SQL_ERROR;
3978  }
3979 #endif
3980 #if defined(_WIN32) || defined(_WIN64)
3981  if (!isu) {
3982  WCHAR *wname = wmb_to_uc(name, -1);
3983 
3984  if (!wname) {
3985  rc = SQLITE_NOMEM;
3986  setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
3987  return SQL_ERROR;
3988  }
3989  rc = sqlite3_open16(wname, &d->sqlite);
3990  uc_free(wname);
3991  } else
3992 #endif
3993  rc = sqlite3_open(name, &d->sqlite);
3994 #endif /* !HAVE_SQLITE3VFS */
3995  if (rc != SQLITE_OK) {
3996 connfail:
3997  setstatd(d, rc, "connect failed", (*d->ov3) ? "HY000" : "S1000");
3998  if (d->sqlite) {
3999  sqlite3_close(d->sqlite);
4000  d->sqlite = NULL;
4001  }
4002  return SQL_ERROR;
4003  }
4004 #if defined(SQLITE_DYNLOAD) || defined(SQLITE_HAS_CODEC)
4005  if (d->pwd) {
4006  sqlite3_key(d->sqlite, d->pwd, d->pwdLen);
4007  }
4008 #endif
4009  d->pwd = NULL;
4010  d->pwdLen = 0;
4011  if (d->trace) {
4012 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
4013  sqlite3_profile(d->sqlite, dbtrace, d);
4014 #else
4015  sqlite3_trace(d->sqlite, dbtrace, d);
4016 #endif
4017  }
4018  d->step_enable = getbool(sflag);
4019  d->trans_disable = getbool(ntflag);
4020  d->curtype = d->step_enable ?
4021  SQL_CURSOR_FORWARD_ONLY : SQL_CURSOR_STATIC;
4022  tmp = strtol(busy, &endp, 0);
4023  if (endp && *endp == '\0' && endp != busy) {
4024  busyto = tmp;
4025  }
4026  if (busyto < 1 || busyto > 1000000) {
4027  busyto = 1000000;
4028  }
4029  d->timeout = busyto;
4030  freep(&d->dbname);
4031  d->dbname = xstrdup(name);
4032  freep(&d->dsn);
4033  d->dsn = xstrdup(dsn);
4034  if ((rc = setsqliteopts(d->sqlite, d)) != SQLITE_OK) {
4035  if (d->trace) {
4036  fprintf(d->trace, "-- sqlite3_close: '%s'\n",
4037  d->dbname);
4038  fflush(d->trace);
4039  }
4040  sqlite3_close(d->sqlite);
4041  d->sqlite = NULL;
4042  goto connfail;
4043  }
4044  if (!spflag || spflag[0] == '\0') {
4045  spflag = "NORMAL";
4046  }
4047  if (spflag[0] != '\0') {
4048  char syncp[128];
4049 
4050  sprintf(syncp, "PRAGMA synchronous = %8.8s;", spflag);
4051  sqlite3_exec(d->sqlite, syncp, NULL, NULL, NULL);
4052  }
4053  if (jmode[0] != '\0') {
4054  char jourp[128];
4055 
4056  sprintf(jourp, "PRAGMA journal_mode = %16.16s;", jmode);
4057  sqlite3_exec(d->sqlite, jourp, NULL, NULL, NULL);
4058  }
4059  if (d->trace) {
4060  fprintf(d->trace, "-- sqlite3_open: '%s'\n", d->dbname);
4061  fflush(d->trace);
4062  }
4063 #if defined(_WIN32) || defined(_WIN64)
4064  {
4065  char pname[MAX_PATH];
4066  HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
4067  FALSE, GetCurrentProcessId());
4068 
4069  pname[0] = '\0';
4070  if (h) {
4071  HMODULE m = NULL, l = LoadLibrary("psapi.dll");
4072  DWORD need;
4073  typedef BOOL (WINAPI *epmfunc)(HANDLE, HMODULE *, DWORD, LPDWORD);
4074  typedef BOOL (WINAPI *gmbfunc)(HANDLE, HMODULE, LPSTR, DWORD);
4075  epmfunc epm;
4076  gmbfunc gmb;
4077 
4078  if (l) {
4079  epm = (epmfunc) GetProcAddress(l, "EnumProcessModules");
4080  gmb = (gmbfunc) GetProcAddress(l, "GetModuleBaseNameA");
4081  if (epm && gmb && epm(h, &m, sizeof (m), &need)) {
4082  gmb(h, m, pname, sizeof (pname));
4083  }
4084  FreeLibrary(l);
4085  }
4086  CloseHandle(h);
4087  }
4088  d->xcelqrx = strncasecmp(pname, "EXCEL", 5) == 0 ||
4089  strncasecmp(pname, "MSQRY", 5) == 0;
4090  if (d->trace && d->xcelqrx) {
4091 
4092  fprintf(d->trace, "-- enabled EXCEL quirks\n");
4093  fflush(d->trace);
4094  }
4095  }
4096 #endif
4097  sqlite3_create_function(d->sqlite, "blob_import", 1, SQLITE_UTF8,
4098  d, blob_import, 0, 0);
4099  sqlite3_create_function(d->sqlite, "blob_export", 2, SQLITE_UTF8,
4100  d, blob_export, 0, 0);
4101  return SQL_SUCCESS;
4102 }
4103 
4110 static void
4111 dbloadext(DBC *d, char *exts)
4112 {
4113 #if defined(HAVE_SQLITE3LOADEXTENSION) && (HAVE_SQLITE3LOADEXTENSION)
4114  char *p;
4115  char path[SQL_MAX_MESSAGE_LENGTH];
4116  int plen = 0;
4117 
4118  if (!d->sqlite) {
4119  return;
4120  }
4121  sqlite3_enable_load_extension(d->sqlite, 1);
4122 #if defined(_WIN32) || defined(_WIN64)
4123  GetModuleFileName(hModule, path, sizeof (path));
4124  p = strrchr(path, '\\');
4125  plen = p ? ((p + 1) - path) : 0;
4126 #endif
4127  do {
4128  p = strchr(exts, ',');
4129  if (p) {
4130  strncpy(path + plen, exts, p - exts);
4131  path[plen + (p - exts)] = '\0';
4132  } else {
4133  strcpy(path + plen, exts);
4134  }
4135  if (exts[0]) {
4136  char *errmsg = NULL;
4137  int rc;
4138 #if defined(_WIN32) || defined(_WIN64)
4139  int i;
4140  char *q;
4141 
4142  q = path + plen;
4143  if (!(q[0] &&
4144  ((q[1] == ':' && (q[2] == '\\' || q[2] == '/')) ||
4145  q[0] == '\\' || q[0] == '/' || q[0] == '.'))) {
4146  q = path;
4147  }
4148  /* sqlite3_load_extension() dislikes backslashes */
4149  for (i = 0; q[i] != '\0'; i++) {
4150  if (q[i] == '\\') {
4151  q[i] = '/';
4152  }
4153  }
4154  rc = sqlite3_load_extension(d->sqlite, q, 0, &errmsg);
4155 #else
4156  rc = sqlite3_load_extension(d->sqlite, path, 0, &errmsg);
4157 #endif
4158  if (rc != SQLITE_OK) {
4159 #if defined(_WIN32) || defined(_WIN64)
4160  char buf[512], msg[512];
4161 
4162  LoadString(hModule, IDS_EXTERR, buf, sizeof (buf));
4163  wsprintf(msg, buf, q, errmsg ?
4164  errmsg : "no error info available");
4165  LoadString(hModule, IDS_EXTTITLE, buf, sizeof (buf));
4166  MessageBox(NULL, msg, buf,
4167  MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
4168  MB_SETFOREGROUND);
4169 #else
4170  fprintf(stderr, "extension '%s' did not load%s%s\n",
4171  path, errmsg ? ": " : "", errmsg ? errmsg : "");
4172 #endif
4173  }
4174  }
4175  if (p) {
4176  exts = p + 1;
4177  }
4178  } while (p);
4179 #endif /* HAVE_SQLITE3LOADEXTENSION */
4180 }
4181 
4191 static char *
4192 s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
4193 {
4194  char *typename = (char *) sqlite3_column_decltype(s3stmt, col);
4195  char guess[64];
4196 
4197  guess[0] = '\0';
4198  if (!typename) {
4199  int coltype = sqlite3_column_type(s3stmt, col);
4200 
4201  if (guessed_types) {
4202  guessed_types[0]++;
4203  }
4204  if (d->trace) {
4205  sprintf(guess, " (guessed from %d)", coltype);
4206  }
4207  switch (coltype) {
4208  case SQLITE_INTEGER: typename = "integer"; break;
4209  case SQLITE_FLOAT: typename = "double"; break;
4210  default:
4211  case SQLITE_TEXT: typename = "varchar"; break;
4212  case SQLITE_BLOB: typename = "blob"; break;
4213 #if 0
4214  case SQLITE_NULL: typename = "null"; break;
4215 #endif
4216  }
4217  }
4218  if (d->trace) {
4219  fprintf(d->trace, "-- column %d type%s: '%s'\n", col + 1,
4220  guess, typename);
4221  fflush(d->trace);
4222  }
4223  return typename;
4224 }
4225 
4226 #ifdef FULL_METADATA
4227 
4236 static void
4237 s3stmt_addmeta(sqlite3_stmt *s3stmt, int col, DBC *d, COL *ci)
4238 {
4239  int nn = 0, pk = 0, ai = 0;
4240  const char *dn = NULL, *tn = NULL, *cn = NULL, *dummy[4];
4241 
4242  dn = sqlite3_column_database_name(s3stmt, col);
4243  tn = sqlite3_column_table_name(s3stmt, col);
4244  cn = sqlite3_column_origin_name(s3stmt, col);
4245  dummy[0] = dummy[1] = 0;
4246  if (tn && cn) {
4247  sqlite3_table_column_metadata(d->sqlite, dn, tn, cn,
4248  dummy, dummy + 1,
4249  &nn, &pk, &ai);
4250  }
4251  ci->autoinc = ai ? SQL_TRUE: SQL_FALSE;
4252  ci->notnull = nn ? SQL_NO_NULLS : SQL_NULLABLE;
4253  ci->ispk = pk ? 1 : 0;
4254  if (d->trace) {
4255  fprintf(d->trace, "-- column %d %s\n",
4256  col + 1, nn ? "notnull" : "nullable");
4257  if (ai) {
4258  fprintf(d->trace, "-- column %d autoincrement\n", col + 1);
4259  }
4260  fflush(d->trace);
4261  }
4262  ci->isrowid = 0;
4263  if (ci->ispk && tn) {
4264  nn = pk = ai = 0;
4265  dummy[2] = dummy[3] = 0;
4266 
4267  sqlite3_table_column_metadata(d->sqlite, dn, tn, "rowid",
4268  dummy + 2, dummy + 3,
4269  &nn, &pk, &ai);
4270  if (pk && dummy[0] && dummy[0] == dummy[2]) {
4271  ci->isrowid = 1;
4272  }
4273  }
4274 }
4275 
4276 #endif
4277 
4284 static int
4286 {
4287  DBC *d = (DBC *) s->dbc;
4288  char **rowd = NULL;
4289  const char *errp = NULL;
4290  int i, ncols, rc;
4291 
4292  if (s != d->cur_s3stmt || !s->s3stmt) {
4293  setstat(s, -1, "stale statement", (*s->ov3) ? "HY000" : "S1000");
4294  return SQL_ERROR;
4295  }
4296  rc = sqlite3_step(s->s3stmt);
4297  if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
4298  ++s->s3stmt_rownum;
4299  ncols = sqlite3_column_count(s->s3stmt);
4300  if (d->s3stmt_needmeta && s->s3stmt_rownum == 0 && ncols > 0) {
4301  PTRDIFF_T size;
4302  char *p;
4303  COL *dyncols;
4304  const char *colname, *typename;
4305 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4306  char *tblname;
4307 #endif
4308 
4309  for (i = size = 0; i < ncols; i++) {
4310  colname = sqlite3_column_name(s->s3stmt, i);
4311  size += 3 + 3 * strlen(colname);
4312  }
4313 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4314  tblname = (char *) size;
4315  for (i = 0; i < ncols; i++) {
4316  p = (char *) sqlite3_column_table_name(s->s3stmt, i);
4317  size += 2 + (p ? strlen(p) : 0);
4318  }
4319 #endif
4320  dyncols = xmalloc(ncols * sizeof (COL) + size);
4321  if (!dyncols) {
4322  freedyncols(s);
4323  s->ncols = 0;
4324  dbtraceapi(d, "sqlite3_finalize", 0);
4325  sqlite3_finalize(s->s3stmt);
4326  s->s3stmt = NULL;
4327  d->cur_s3stmt = NULL;
4328  return nomem(s);
4329  }
4330  p = (char *) (dyncols + ncols);
4331 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4332  tblname = p + (PTRDIFF_T) tblname;
4333 #endif
4334  for (i = 0; i < ncols; i++) {
4335  char *q;
4336 
4337  colname = sqlite3_column_name(s->s3stmt, i);
4338  if (d->trace) {
4339  fprintf(d->trace, "-- column %d name: '%s'\n",
4340  i + 1, colname);
4341  fflush(d->trace);
4342  }
4343 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4344  q = (char *) sqlite3_column_table_name(s->s3stmt, i);
4345  strcpy(tblname, q ? q : "");
4346  if (d->trace) {
4347  fprintf(d->trace, "-- table %d name: '%s'\n",
4348  i + 1, tblname);
4349  fflush(d->trace);
4350  }
4351  dyncols[i].table = tblname;
4352  tblname += strlen(tblname) + 1;
4353 #endif
4354  typename = s3stmt_coltype(s->s3stmt, i, d, 0);
4355  dyncols[i].db = ((DBC *) (s->dbc))->dbname;
4356  strcpy(p, colname);
4357  dyncols[i].label = p;
4358  p += strlen(p) + 1;
4359  q = strchr(colname, '.');
4360  if (q) {
4361  char *q2 = strchr(q + 1, '.');
4362 
4363  /* SQLite 3.3.4 produces view.table.column sometimes */
4364  if (q2) {
4365  q = q2;
4366  }
4367  }
4368  if (q) {
4369 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
4370  dyncols[i].table = p;
4371 #endif
4372  strncpy(p, colname, q - colname);
4373  p[q - colname] = '\0';
4374  p += strlen(p) + 1;
4375  strcpy(p, q + 1);
4376  dyncols[i].column = p;
4377  p += strlen(p) + 1;
4378  } else {
4379 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
4380  dyncols[i].table = "";
4381 #endif
4382  strcpy(p, colname);
4383  dyncols[i].column = p;
4384  p += strlen(p) + 1;
4385  }
4386  if (s->longnames) {
4387  dyncols[i].column = dyncols[i].label;
4388  }
4389 #ifdef SQL_LONGVARCHAR
4390  dyncols[i].type = SQL_LONGVARCHAR;
4391  dyncols[i].size = 65535;
4392 #else
4393  dyncols[i].type = SQL_VARCHAR;
4394  dyncols[i].size = 255;
4395 #endif
4396  dyncols[i].index = i;
4397  dyncols[i].scale = 0;
4398  dyncols[i].prec = 0;
4399  dyncols[i].nosign = 1;
4400  dyncols[i].autoinc = SQL_FALSE;
4401  dyncols[i].notnull = SQL_NULLABLE;
4402  dyncols[i].ispk = -1;
4403  dyncols[i].isrowid = -1;
4404 #ifdef FULL_METADATA
4405  s3stmt_addmeta(s->s3stmt, i, d, &dyncols[i]);
4406 #endif
4407  dyncols[i].typename = xstrdup(typename);
4408  }
4409  freedyncols(s);
4410  s->ncols = s->dcols = ncols;
4411  s->dyncols = s->cols = dyncols;
4412  fixupdyncols(s, d);
4413  mkbindcols(s, s->ncols);
4414  d->s3stmt_needmeta = 0;
4415  }
4416  if (ncols <= 0) {
4417  goto killstmt;
4418  }
4419  if (rc == SQLITE_DONE) {
4420  freeresult(s, 0);
4421  s->nrows = 0;
4422  dbtraceapi(d, "sqlite3_finalize", 0);
4423  sqlite3_finalize(s->s3stmt);
4424  s->s3stmt = NULL;
4425  d->cur_s3stmt = NULL;
4426  return SQL_SUCCESS;
4427  }
4428  rowd = xmalloc((1 + 2 * ncols) * sizeof (char *));
4429  if (rowd) {
4430  const unsigned char *value;
4431 
4432  rowd[0] = (char *) ((PTRDIFF_T) (ncols * 2));
4433  ++rowd;
4434  for (i = 0; i < ncols; i++) {
4435  int coltype = sqlite3_column_type(s->s3stmt, i);
4436 
4437  rowd[i] = rowd[i + ncols] = NULL;
4438  if (coltype == SQLITE_BLOB) {
4439  int k, nbytes = sqlite3_column_bytes(s->s3stmt, i);
4440  char *qp;
4441  unsigned const char *bp;
4442 
4443  bp = sqlite3_column_blob(s->s3stmt, i);
4444  qp = xmalloc(nbytes * 2 + 4);
4445  if (qp) {
4446  rowd[i + ncols] = qp;
4447  *qp++ = 'X';
4448  *qp++ = '\'';
4449  for (k = 0; k < nbytes; k++) {
4450  *qp++ = xdigits[(bp[k] >> 4)];
4451  *qp++ = xdigits[(bp[k] & 0xF)];
4452  }
4453  *qp++ = '\'';
4454  *qp = '\0';
4455  }
4456 #ifdef _MSC_VER
4457  } else if (coltype == SQLITE_FLOAT) {
4458  struct lconv *lc = 0;
4459  double d = sqlite3_column_double(s->s3stmt, i);
4460  char *p, buffer[128];
4461 
4462  /*
4463  * This avoids floating point rounding
4464  * and formatting problems of some SQLite
4465  * versions in conjunction with MSVC 2010.
4466  */
4467  snprintf(buffer, sizeof (buffer), "%.15g", d);
4468  lc = localeconv();
4469  if (lc && lc->decimal_point && lc->decimal_point[0] &&
4470  lc->decimal_point[0] != '.') {
4471  p = strchr(buffer, lc->decimal_point[0]);
4472  if (p) {
4473  *p = '.';
4474  }
4475  }
4476  rowd[i + ncols] = xstrdup(buffer);
4477 #endif
4478  } else if (coltype != SQLITE_NULL) {
4479  value = sqlite3_column_text(s->s3stmt, i);
4480  rowd[i + ncols] = xstrdup((char *) value);
4481  }
4482  }
4483  for (i = 0; i < ncols; i++) {
4484  int coltype = sqlite3_column_type(s->s3stmt, i);
4485 
4486  value = NULL;
4487  if (coltype == SQLITE_BLOB) {
4488  value = sqlite3_column_blob(s->s3stmt, i);
4489  } else if (coltype != SQLITE_NULL) {
4490  value = sqlite3_column_text(s->s3stmt, i);
4491  }
4492  if (value && !rowd[i + ncols]) {
4493  freerows(rowd);
4494  rowd = 0;
4495  break;
4496  }
4497  }
4498  }
4499  if (rowd) {
4500  freeresult(s, 0);
4501  s->nrows = 1;
4502  s->rows = rowd;
4503  s->rowfree = freerows;
4504  if (rc == SQLITE_DONE) {
4505  dbtraceapi(d, "sqlite3_finalize", 0);
4506  sqlite3_finalize(s->s3stmt);
4507  s->s3stmt = NULL;
4508  d->cur_s3stmt = NULL;
4509  }
4510  return SQL_SUCCESS;
4511  }
4512  }
4513 killstmt:
4514  dbtraceapi(d, "sqlite3_reset", 0);
4515  rc = sqlite3_reset(s->s3stmt);
4516  s->s3stmt_noreset = 1;
4517  errp = sqlite3_errmsg(d->sqlite);
4518  if (d->cur_s3stmt == s) {
4519  d->cur_s3stmt = NULL;
4520  }
4521  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
4522  errp ? errp : "unknown error", rc);
4523  return SQL_ERROR;
4524 }
4525 
4531 static void
4533 {
4534  DBC *d;
4535 
4536  if (!s || !s->s3stmt) {
4537  return;
4538  }
4539  d = (DBC *) s->dbc;
4540  if (d) {
4541  d->busyint = 0;
4542  }
4543  if (!s->s3stmt_noreset) {
4544  dbtraceapi(d, "sqlite3_reset", 0);
4545  sqlite3_reset(s->s3stmt);
4546  s->s3stmt_noreset = 1;
4547  s->s3stmt_rownum = -1;
4548  }
4549  if (d->cur_s3stmt == s) {
4550  d->cur_s3stmt = NULL;
4551  }
4552 }
4553 
4559 static void
4561 {
4562  DBC *d = (DBC *) s->dbc;
4563 
4564  if (d) {
4565  d->busyint = 0;
4566  }
4567  if (d && d->cur_s3stmt == s) {
4568  s3stmt_end(s);
4569  }
4570 }
4571 
4577 static void
4579 {
4580  if (s->s3stmt) {
4581  DBC *d = (DBC *) s->dbc;
4582 
4583  if (d) {
4584  dbtraceapi(d, "sqlite3_finalize", 0);
4585  }
4586  sqlite3_finalize(s->s3stmt);
4587  s->s3stmt = NULL;
4588  s->s3stmt_rownum = 0;
4589  }
4590 }
4591 
4598 static SQLRETURN
4600 {
4601  DBC *d = (DBC *) s->dbc;
4602  const char *endp;
4603  sqlite3_stmt *s3stmt = NULL;
4604  int rc, nretry = 0;
4605 
4606  d->s3stmt_needmeta = 0;
4607  if (!s->s3stmt) {
4608 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
4609  dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
4610 #else
4611  dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
4612 #endif
4613  do {
4614  s3stmt = NULL;
4615 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
4616  rc = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
4617  &s3stmt, &endp);
4618 #else
4619  rc = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
4620  &s3stmt, &endp);
4621 #endif
4622  if (rc != SQLITE_OK) {
4623  if (s3stmt) {
4624  sqlite3_finalize(s3stmt);
4625  s3stmt = NULL;
4626  }
4627  }
4628  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
4629  dbtracerc(d, rc, NULL);
4630  if (rc != SQLITE_OK) {
4631  if (s3stmt) {
4632  dbtraceapi(d, "sqlite3_finalize", NULL);
4633  sqlite3_finalize(s3stmt);
4634  }
4635  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
4636  sqlite3_errmsg(d->sqlite), rc);
4637  return SQL_ERROR;
4638  }
4639  if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
4640  dbtraceapi(d, "sqlite3_finalize", 0);
4641  sqlite3_finalize(s3stmt);
4642  setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
4643  (*s->ov3) ? "HY000" : "S1000");
4644  return SQL_ERROR;
4645  }
4646  s->s3stmt = s3stmt;
4647  s->s3stmt_noreset = 1;
4648  d->s3stmt_needmeta = 1;
4649  }
4650  d->cur_s3stmt = s;
4651  s->s3stmt_rownum = -1;
4652  s3bind(d, s->s3stmt, s->nparams, s->bindparms);
4653  return SQL_SUCCESS;
4654 }
4655 
4656 #ifndef WINTERFACE
4657 
4661 SQLRETURN SQL_API
4662 SQLDataSources(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *srvname,
4663  SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
4664  SQLCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
4665 {
4666  if (env == SQL_NULL_HENV) {
4667  return SQL_INVALID_HANDLE;
4668  }
4669  return SQL_ERROR;
4670 }
4671 #endif
4672 
4673 #ifdef WINTERFACE
4674 
4678 SQLRETURN SQL_API
4679 SQLDataSourcesW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *srvname,
4680  SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
4681  SQLWCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
4682 {
4683  if (env == SQL_NULL_HENV) {
4684  return SQL_INVALID_HANDLE;
4685  }
4686  return SQL_ERROR;
4687 }
4688 #endif
4689 
4690 #ifndef WINTERFACE
4691 
4695 SQLRETURN SQL_API
4696 SQLDrivers(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *drvdesc,
4697  SQLSMALLINT descmax, SQLSMALLINT *desclenp,
4698  SQLCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
4699 {
4700  if (env == SQL_NULL_HENV) {
4701  return SQL_INVALID_HANDLE;
4702  }
4703  return SQL_ERROR;
4704 }
4705 #endif
4706 
4707 #ifdef WINTERFACE
4708 
4712 SQLRETURN SQL_API
4713 SQLDriversW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *drvdesc,
4714  SQLSMALLINT descmax, SQLSMALLINT *desclenp,
4715  SQLWCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
4716 {
4717  if (env == SQL_NULL_HENV) {
4718  return SQL_INVALID_HANDLE;
4719  }
4720  return SQL_ERROR;
4721 }
4722 #endif
4723 
4724 #ifndef WINTERFACE
4725 
4729 SQLRETURN SQL_API
4730 SQLBrowseConnect(SQLHDBC dbc, SQLCHAR *connin, SQLSMALLINT conninLen,
4731  SQLCHAR *connout, SQLSMALLINT connoutMax,
4732  SQLSMALLINT *connoutLen)
4733 {
4734  SQLRETURN ret;
4735 
4736  HDBC_LOCK(dbc);
4737  ret = drvunimpldbc(dbc);
4738  HDBC_UNLOCK(dbc);
4739  return ret;
4740 }
4741 #endif
4742 
4743 #ifdef WINTERFACE
4744 
4748 SQLRETURN SQL_API
4749 SQLBrowseConnectW(SQLHDBC dbc, SQLWCHAR *connin, SQLSMALLINT conninLen,
4750  SQLWCHAR *connout, SQLSMALLINT connoutMax,
4751  SQLSMALLINT *connoutLen)
4752 {
4753  SQLRETURN ret;
4754 
4755  HDBC_LOCK(dbc);
4756  ret = drvunimpldbc(dbc);
4757  HDBC_UNLOCK(dbc);
4758  return ret;
4759 }
4760 #endif
4761 
4770 static SQLRETURN
4771 drvputdata(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
4772 {
4773  STMT *s;
4774  int i, dlen, done = 0;
4775  BINDPARM *p;
4776 
4777  if (stmt == SQL_NULL_HSTMT) {
4778  return SQL_INVALID_HANDLE;
4779  }
4780  s = (STMT *) stmt;
4781  if (!s->query || s->nparams <= 0) {
4782 seqerr:
4783  setstat(s, -1, "sequence error", "HY010");
4784  return SQL_ERROR;
4785  }
4786  for (i = (s->pdcount < 0) ? 0 : s->pdcount; i < s->nparams; i++) {
4787  p = &s->bindparms[i];
4788  if (p->need > 0) {
4789  int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
4790 
4791  if (len == SQL_NULL_DATA) {
4792  freep(&p->parbuf);
4793  p->param = NULL;
4794  p->len = SQL_NULL_DATA;
4795  p->need = -1;
4796  } else if (type != SQL_C_CHAR
4797 #ifdef WCHARSUPPORT
4798  && type != SQL_C_WCHAR
4799 #endif
4800  && type != SQL_C_BINARY) {
4801  int size = 0;
4802 
4803  switch (type) {
4804  case SQL_C_TINYINT:
4805  case SQL_C_UTINYINT:
4806  case SQL_C_STINYINT:
4807 #ifdef SQL_BIT
4808  case SQL_C_BIT:
4809 #endif
4810  size = sizeof (SQLCHAR);
4811  break;
4812  case SQL_C_SHORT:
4813  case SQL_C_USHORT:
4814  case SQL_C_SSHORT:
4815  size = sizeof (SQLSMALLINT);
4816  break;
4817  case SQL_C_LONG:
4818  case SQL_C_ULONG:
4819  case SQL_C_SLONG:
4820  size = sizeof (SQLINTEGER);
4821  break;
4822 #ifdef SQL_BIGINT
4823  case SQL_C_UBIGINT:
4824  case SQL_C_SBIGINT:
4825  size = sizeof (SQLBIGINT);
4826  break;
4827 #endif
4828  case SQL_C_FLOAT:
4829  size = sizeof (float);
4830  break;
4831  case SQL_C_DOUBLE:
4832  size = sizeof (double);
4833  break;
4834 #ifdef SQL_C_TYPE_DATE
4835  case SQL_C_TYPE_DATE:
4836 #endif
4837  case SQL_C_DATE:
4838  size = sizeof (DATE_STRUCT);
4839  break;
4840 #ifdef SQL_C_TYPE_DATE
4841  case SQL_C_TYPE_TIME:
4842 #endif
4843  case SQL_C_TIME:
4844  size = sizeof (TIME_STRUCT);
4845  break;
4846 #ifdef SQL_C_TYPE_DATE
4847  case SQL_C_TYPE_TIMESTAMP:
4848 #endif
4849  case SQL_C_TIMESTAMP:
4850  size = sizeof (TIMESTAMP_STRUCT);
4851  break;
4852  }
4853  freep(&p->parbuf);
4854  p->parbuf = xmalloc(size);
4855  if (!p->parbuf) {
4856  return nomem(s);
4857  }
4858  p->param = p->parbuf;
4859  memcpy(p->param, data, size);
4860  p->len = size;
4861  p->need = -1;
4862  } else if (len == SQL_NTS && (
4863  type == SQL_C_CHAR
4864 #ifdef WCHARSUPPORT
4865  || type == SQL_C_WCHAR
4866 #endif
4867  )) {
4868  char *dp = data;
4869 
4870 #ifdef WCHARSUPPORT
4871  if (type == SQL_C_WCHAR) {
4872  dp = uc_to_utf(data, len);
4873  if (!dp) {
4874  return nomem(s);
4875  }
4876  }
4877 #endif
4878 #if defined(_WIN32) || defined(_WIN64)
4879  if (*s->oemcp) {
4880  dp = wmb_to_utf(data, strlen (data));
4881  if (!dp) {
4882  return nomem(s);
4883  }
4884  }
4885 #endif
4886  dlen = strlen(dp);
4887  freep(&p->parbuf);
4888  p->parbuf = xmalloc(dlen + 1);
4889  if (!p->parbuf) {
4890  if (dp != data) {
4891  uc_free(dp);
4892  }
4893  return nomem(s);
4894  }
4895  p->param = p->parbuf;
4896  strcpy(p->param, dp);
4897  if (dp != data) {
4898  uc_free(dp);
4899  }
4900  p->len = dlen;
4901  p->need = -1;
4902  } else if (len < 0) {
4903  setstat(s, -1, "invalid length", "HY090");
4904  return SQL_ERROR;
4905  } else {
4906  dlen = min(p->len - p->offs, len);
4907  if (!p->param) {
4908  setstat(s, -1, "no memory for parameter", "HY013");
4909  return SQL_ERROR;
4910  }
4911  memcpy((char *) p->param + p->offs, data, dlen);
4912  p->offs += dlen;
4913  if (p->offs >= p->len) {
4914 #ifdef WCHARSUPPORT
4915  if (type == SQL_C_WCHAR) {
4916  char *dp = uc_to_utf(p->param, p->len);
4917  char *np;
4918  int nlen;
4919 
4920  if (!dp) {
4921  return nomem(s);
4922  }
4923  nlen = strlen(dp);
4924  np = xmalloc(nlen + 1);
4925  if (!np) {
4926  uc_free(dp);
4927  return nomem(s);
4928  }
4929  strcpy(np, dp);
4930  uc_free(dp);
4931  if (p->param == p->parbuf) {
4932  freep(&p->parbuf);
4933  }
4934  p->parbuf = p->param = np;
4935  p->len = nlen;
4936  } else {
4937  *((char *) p->param + p->len) = '\0';
4938  }
4939  p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR)
4940  ? -1 : 0;
4941 #else
4942  *((char *) p->param + p->len) = '\0';
4943  p->need = (type == SQL_C_CHAR) ? -1 : 0;
4944 #endif
4945 #if defined(_WIN32) || defined(_WIN64)
4946  if (type == SQL_C_CHAR && *s->oemcp &&
4947  !(p->stype == SQL_BINARY ||
4948  p->stype == SQL_VARBINARY ||
4949  p->stype == SQL_LONGVARBINARY)) {
4950  char *dp = wmb_to_utf(p->param, p->len);
4951 
4952  if (!dp) {
4953  return nomem(s);
4954  }
4955  if (p->param == p->parbuf) {
4956  freep(&p->parbuf);
4957  }
4958  p->parbuf = p->param = dp;
4959  p->len = strlen(dp);
4960  }
4961  if (p->type == SQL_C_WCHAR &&
4962  (p->stype == SQL_VARCHAR ||
4963  p->stype == SQL_LONGVARCHAR) &&
4964  p->len == p->coldef * sizeof (SQLWCHAR)) {
4965  /* fix for MS-Access */
4966  p->len = p->coldef;
4967  }
4968 #endif
4969  }
4970  }
4971  done = 1;
4972  break;
4973  }
4974  }
4975  if (!done) {
4976  goto seqerr;
4977  }
4978  return SQL_SUCCESS;
4979 }
4980 
4989 SQLRETURN SQL_API
4990 SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
4991 {
4992  SQLRETURN ret;
4993 
4994  HSTMT_LOCK(stmt);
4995  ret = drvputdata(stmt, data, len);
4996  HSTMT_UNLOCK(stmt);
4997  return ret;
4998 }
4999 
5005 static SQLRETURN
5007 {
5008  if (s->bindparms) {
5009  int n;
5010 
5011  for (n = 0; n < s->nbindparms; n++) {
5012  freep(&s->bindparms[n].parbuf);
5013  memset(&s->bindparms[n], 0, sizeof (BINDPARM));
5014  }
5015  }
5016  return SQL_SUCCESS;
5017 }
5018 
5030 static SQLRETURN
5031 setupparam(STMT *s, char *sql, int pnum)
5032 {
5033  int type, len = 0, needalloc = 0;
5034  BINDPARM *p;
5035 
5036  if (!s->bindparms || pnum < 0 || pnum >= s->nbindparms) {
5037  goto error;
5038  }
5039  p = &s->bindparms[pnum];
5040  type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
5041 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
5042  /* MS Access hack part 4 (map SQL_C_DEFAULT to SQL_C_CHAR) */
5043  if (type == SQL_C_WCHAR && p->type == SQL_C_DEFAULT) {
5044  type = SQL_C_CHAR;
5045  }
5046 #endif
5047  if (p->need > 0) {
5048  return setupparbuf(s, p);
5049  }
5050  p->strbuf[0] = '\0';
5051  if (!p->param || (p->lenp && *p->lenp == SQL_NULL_DATA)) {
5052  p->s3type = SQLITE_NULL;
5053  p->s3size = 0;
5054  return SQL_SUCCESS;
5055  }
5056  if (type == SQL_C_CHAR &&
5057  (p->stype == SQL_BINARY ||
5058  p->stype == SQL_VARBINARY ||
5059  p->stype == SQL_LONGVARBINARY)) {
5060  type = SQL_C_BINARY;
5061  }
5062  switch (type) {
5063  case SQL_C_BINARY:
5064  p->s3type = SQLITE_BLOB;
5065  p->s3size = p->len;
5066  p->s3val = p->param;
5067  if (p->need < 0) {
5068  break;
5069  }
5070  if (!p->lenp) {
5071  len = p->len;
5072  } else if (*p->lenp == SQL_DATA_AT_EXEC) {
5073  len = p->len;
5074  } else {
5075  len = *p->lenp;
5076  if (len <= SQL_LEN_DATA_AT_EXEC_OFFSET) {
5077  len = SQL_LEN_DATA_AT_EXEC(len);
5078  }
5079  }
5080  if (len < 0) {
5081  setstat(s, -1, "invalid length", "HY009");
5082  return SQL_ERROR;
5083  }
5084  p->len = len;
5085  p->max = p->len;
5086  p->need = -1;
5087  p->s3size = len;
5088  break;
5089 #ifdef WCHARSUPPORT
5090  case SQL_C_WCHAR:
5091 #endif
5092  case SQL_C_CHAR:
5093  p->s3type = SQLITE_TEXT;
5094  p->s3size = -1;
5095  p->s3val = p->param;
5096  if (!p->parbuf) {
5097 #ifdef WCHARSUPPORT
5098  if (type == SQL_C_WCHAR) {
5099  if (!p->lenp || *p->lenp == SQL_NTS) {
5100  p->max = uc_strlen(p->param) * sizeof (SQLWCHAR);
5101  } else if (*p->lenp >= 0) {
5102  p->max = *p->lenp;
5103  }
5104  } else
5105 #endif
5106  if (type == SQL_C_CHAR) {
5107  if (!p->lenp || *p->lenp == SQL_NTS) {
5108  p->len = p->max = strlen(p->param);
5109 #if defined(_WIN32) || defined(_WIN64)
5110  needalloc = 1;
5111 #endif
5112  } else if (*p->lenp >= 0) {
5113  p->len = p->max = *p->lenp;
5114  needalloc = 1;
5115  }
5116  }
5117  }
5118  if (p->need < 0 && p->parbuf == p->param) {
5119  break;
5120  }
5121 #ifdef WCHARSUPPORT
5122  if (type == SQL_C_WCHAR) {
5123  char *dp = uc_to_utf(p->param, p->max);
5124 
5125  if (!dp) {
5126  return nomem(s);
5127  }
5128  if (p->param == p->parbuf) {
5129  freep(&p->parbuf);
5130  }
5131  p->parbuf = p->param = dp;
5132  p->need = -1;
5133  p->len = strlen(p->param);
5134  p->s3val = p->param;
5135  p->s3size = p->len;
5136  } else
5137 #endif
5138  if (type == SQL_C_CHAR) {
5139  p->s3val = p->param;
5140  if (needalloc) {
5141  char *dp;
5142 
5143 #if defined(_WIN32) || defined(_WIN64)
5144  if (*s->oemcp) {
5145  dp = wmb_to_utf(p->param, p->len);
5146  } else {
5147  dp = xmalloc(p->len + 1);
5148  }
5149 #else
5150  dp = xmalloc(p->len + 1);
5151 #endif
5152  if (!dp) {
5153  return nomem(s);
5154  }
5155 #if defined(_WIN32) || defined(_WIN64)
5156  if (*s->oemcp) {
5157  p->len = strlen(dp);
5158  } else {
5159  memcpy(dp, p->param, p->len);
5160  dp[p->len] = '\0';
5161  }
5162 #else
5163  memcpy(dp, p->param, p->len);
5164  dp[p->len] = '\0';
5165 #endif
5166  if (p->param == p->parbuf) {
5167  freep(&p->parbuf);
5168  }
5169  p->parbuf = p->param = dp;
5170  p->need = -1;
5171  p->s3val = p->param;
5172  p->s3size = p->len;
5173  }
5174  }
5175  break;
5176  case SQL_C_UTINYINT:
5177  case SQL_C_TINYINT:
5178  case SQL_C_STINYINT:
5179  p->s3type = SQLITE_INTEGER;
5180  p->s3size = sizeof (int);
5181  p->s3ival = *((SQLCHAR *) p->param);
5182  break;
5183  case SQL_C_USHORT:
5184  p->s3type = SQLITE_INTEGER;
5185  p->s3size = sizeof (int);
5186  p->s3ival = *((SQLUSMALLINT *) p->param);
5187  break;
5188  case SQL_C_SHORT:
5189  case SQL_C_SSHORT:
5190  p->s3type = SQLITE_INTEGER;
5191  p->s3size = sizeof (int);
5192  p->s3ival = *((SQLSMALLINT *) p->param);
5193  break;
5194  case SQL_C_ULONG:
5195  p->s3type = SQLITE_INTEGER;
5196  p->s3size = sizeof (int);
5197  p->s3ival = *((SQLUINTEGER *) p->param);
5198  break;
5199  case SQL_C_LONG:
5200  case SQL_C_SLONG:
5201  p->s3type = SQLITE_INTEGER;
5202  p->s3size = sizeof (int);
5203  p->s3ival = *((SQLINTEGER *) p->param);
5204  break;
5205 #ifdef SQL_BIT
5206  case SQL_C_BIT:
5207  p->s3type = SQLITE_INTEGER;
5208  p->s3size = sizeof (int);
5209  p->s3ival = (*((SQLCHAR *) p->param)) ? 1 : 0;
5210  break;
5211 #endif
5212 #ifdef SQL_BIGINT
5213  case SQL_C_SBIGINT:
5214  p->s3type = SQLITE_INTEGER;
5215  p->s3size = sizeof (sqlite_int64);
5216  p->s3lival = *((sqlite_int64 *) p->param);
5217  break;
5218  case SQL_C_UBIGINT:
5219  p->s3type = SQLITE_INTEGER;
5220  p->s3size = sizeof (sqlite_int64);
5221  p->s3lival = *((sqlite_uint64 *) p->param);
5222  break;
5223 #endif
5224  case SQL_C_FLOAT:
5225  p->s3type = SQLITE_FLOAT;
5226  p->s3size = sizeof (double);
5227  p->s3dval = *((float *) p->param);
5228  break;
5229  case SQL_C_DOUBLE:
5230  p->s3type = SQLITE_FLOAT;
5231  p->s3size = sizeof (double);
5232  p->s3dval = *((double *) p->param);
5233  break;
5234 #ifdef SQL_C_TYPE_DATE
5235  case SQL_C_TYPE_DATE:
5236 #endif
5237  case SQL_C_DATE:
5238  if (*s->jdconv) {
5239  int a, b, x1, x2, y, m, d;
5240 
5241  p->s3type = SQLITE_FLOAT;
5242  p->s3size = sizeof (double);
5243  y = ((DATE_STRUCT *) p->param)->year;
5244  m = ((DATE_STRUCT *) p->param)->month;
5245  d = ((DATE_STRUCT *) p->param)->day;
5246  if (m <= 2) {
5247  y--;
5248  m += 12;
5249  }
5250  a = y / 100;
5251  b = 2 - a + (a / 4);
5252  x1 = 36525 * (y + 4716) / 100;
5253  x2 = 306001 * (m + 1) / 10000;
5254  p->s3dval = x1 + x2 + d + b - 1524.5;
5255  break;
5256  }
5257  sprintf(p->strbuf, "%04d-%02d-%02d",
5258  ((DATE_STRUCT *) p->param)->year,
5259  ((DATE_STRUCT *) p->param)->month,
5260  ((DATE_STRUCT *) p->param)->day);
5261  p->s3type = SQLITE_TEXT;
5262  p->s3size = -1;
5263  p->s3val = p->strbuf;
5264  break;
5265 #ifdef SQL_C_TYPE_TIME
5266  case SQL_C_TYPE_TIME:
5267 #endif
5268  case SQL_C_TIME:
5269  if (*s->jdconv) {
5270  p->s3type = SQLITE_FLOAT;
5271  p->s3size = sizeof (double);
5272  p->s3dval = 2451544.5 +
5273  (((TIME_STRUCT *) p->param)->hour * 3600000.0 +
5274  ((TIME_STRUCT *) p->param)->minute * 60000.0 +
5275  ((TIME_STRUCT *) p->param)->second * 1000.0) / 86400000.0;
5276  break;
5277  }
5278  sprintf(p->strbuf, "%02d:%02d:%02d",
5279  ((TIME_STRUCT *) p->param)->hour,
5280  ((TIME_STRUCT *) p->param)->minute,
5281  ((TIME_STRUCT *) p->param)->second);
5282  p->s3type = SQLITE_TEXT;
5283  p->s3size = -1;
5284  p->s3val = p->strbuf;
5285  break;
5286 #ifdef SQL_C_TYPE_TIMESTAMP
5287  case SQL_C_TYPE_TIMESTAMP:
5288 #endif
5289  case SQL_C_TIMESTAMP:
5290  if (*s->jdconv) {
5291  int a, b, x1, x2, y, m, d;
5292 
5293  p->s3type = SQLITE_FLOAT;
5294  p->s3size = sizeof (double);
5295  y = ((TIMESTAMP_STRUCT *) p->param)->year;
5296  m = ((TIMESTAMP_STRUCT *) p->param)->month;
5297  d = ((TIMESTAMP_STRUCT *) p->param)->day;
5298  if (m <= 2) {
5299  y--;
5300  m += 12;
5301  }
5302  a = y / 100;
5303  b = 2 - a + (a / 4);
5304  x1 = 36525 * (y + 4716) / 100;
5305  x2 = 306001 * (m + 1) / 10000;
5306  p->s3dval = x1 + x2 + d + b - 1524.5 +
5307  (((TIMESTAMP_STRUCT *) p->param)->hour * 3600000.0 +
5308  ((TIMESTAMP_STRUCT *) p->param)->minute * 60000.0 +
5309  ((TIMESTAMP_STRUCT *) p->param)->second * 1000.0 +
5310  ((TIMESTAMP_STRUCT *) p->param)->fraction / 1.0E6)
5311  / 86400000.0;
5312  break;
5313  }
5314  len = (int) ((TIMESTAMP_STRUCT *) p->param)->fraction;
5315  len /= 1000000;
5316  len = len % 1000;
5317  if (len < 0) {
5318  len = 0;
5319  }
5320  if (p->coldef && p->coldef <= 16) {
5321  sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
5322  ((TIMESTAMP_STRUCT *) p->param)->year,
5323  ((TIMESTAMP_STRUCT *) p->param)->month,
5324  ((TIMESTAMP_STRUCT *) p->param)->day,
5325  ((TIMESTAMP_STRUCT *) p->param)->hour,
5326  ((TIMESTAMP_STRUCT *) p->param)->minute);
5327  } else if (p->coldef && p->coldef <= 19) {
5328  sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
5329  ((TIMESTAMP_STRUCT *) p->param)->year,
5330  ((TIMESTAMP_STRUCT *) p->param)->month,
5331  ((TIMESTAMP_STRUCT *) p->param)->day,
5332  ((TIMESTAMP_STRUCT *) p->param)->hour,
5333  ((TIMESTAMP_STRUCT *) p->param)->minute,
5334  ((TIMESTAMP_STRUCT *) p->param)->second);
5335  } else {
5336  sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
5337  ((TIMESTAMP_STRUCT *) p->param)->year,
5338  ((TIMESTAMP_STRUCT *) p->param)->month,
5339  ((TIMESTAMP_STRUCT *) p->param)->day,
5340  ((TIMESTAMP_STRUCT *) p->param)->hour,
5341  ((TIMESTAMP_STRUCT *) p->param)->minute,
5342  ((TIMESTAMP_STRUCT *) p->param)->second,
5343  len);
5344  }
5345  p->s3type = SQLITE_TEXT;
5346  p->s3size = -1;
5347  p->s3val = p->strbuf;
5348  break;
5349  default:
5350  error:
5351  setstat(s, -1, "unsupported parameter type",
5352  (*s->ov3) ? "07009" : "S1093");
5353  return SQL_ERROR;
5354  }
5355  return SQL_SUCCESS;
5356 }
5357 
5373 static SQLRETURN
5374 drvbindparam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
5375  SQLSMALLINT buftype, SQLSMALLINT ptype, SQLUINTEGER coldef,
5376  SQLSMALLINT scale,
5377  SQLPOINTER data, SQLINTEGER buflen, SQLLEN *len)
5378 {
5379  STMT *s;
5380  BINDPARM *p;
5381 
5382  if (stmt == SQL_NULL_HSTMT) {
5383  return SQL_INVALID_HANDLE;
5384  }
5385  s = (STMT *) stmt;
5386  if (pnum == 0) {
5387  setstat(s, -1, "invalid parameter", (*s->ov3) ? "07009" : "S1093");
5388  return SQL_ERROR;
5389  }
5390  if (!data && !len) {
5391  setstat(s, -1, "invalid buffer", "HY003");
5392  return SQL_ERROR;
5393  }
5394  --pnum;
5395  if (s->bindparms) {
5396  if (pnum >= s->nbindparms) {
5397  BINDPARM *newparms;
5398 
5399  newparms = xrealloc(s->bindparms,
5400  (pnum + 1) * sizeof (BINDPARM));
5401  if (!newparms) {
5402 outofmem:
5403  return nomem(s);
5404  }
5405  s->bindparms = newparms;
5406  memset(&s->bindparms[s->nbindparms], 0,
5407  (pnum + 1 - s->nbindparms) * sizeof (BINDPARM));
5408  s->nbindparms = pnum + 1;
5409  }
5410  } else {
5411  int npar = max(10, pnum + 1);
5412 
5413  s->bindparms = xmalloc(npar * sizeof (BINDPARM));
5414  if (!s->bindparms) {
5415  goto outofmem;
5416  }
5417  memset(s->bindparms, 0, npar * sizeof (BINDPARM));
5418  s->nbindparms = npar;
5419  }
5420  switch (buftype) {
5421  case SQL_C_STINYINT:
5422  case SQL_C_UTINYINT:
5423  case SQL_C_TINYINT:
5424 #ifdef SQL_C_BIT
5425  case SQL_C_BIT:
5426 #endif
5427  buflen = sizeof (SQLCHAR);
5428  break;
5429  case SQL_C_SHORT:
5430  case SQL_C_USHORT:
5431  case SQL_C_SSHORT:
5432  buflen = sizeof (SQLSMALLINT);
5433  break;
5434  case SQL_C_SLONG:
5435  case SQL_C_ULONG:
5436  case SQL_C_LONG:
5437  buflen = sizeof (SQLINTEGER);
5438  break;
5439  case SQL_C_FLOAT:
5440  buflen = sizeof (float);
5441  break;
5442  case SQL_C_DOUBLE:
5443  buflen = sizeof (double);
5444  break;
5445  case SQL_C_TIMESTAMP:
5446 #ifdef SQL_C_TYPE_TIMESTAMP
5447  case SQL_C_TYPE_TIMESTAMP:
5448 #endif
5449  buflen = sizeof (TIMESTAMP_STRUCT);
5450  break;
5451  case SQL_C_TIME:
5452 #ifdef SQL_C_TYPE_TIME
5453  case SQL_C_TYPE_TIME:
5454 #endif
5455  buflen = sizeof (TIME_STRUCT);
5456  break;
5457  case SQL_C_DATE:
5458 #ifdef SQL_C_TYPE_DATE
5459  case SQL_C_TYPE_DATE:
5460 #endif
5461  buflen = sizeof (DATE_STRUCT);
5462  break;
5463 #ifdef SQL_C_UBIGINT
5464  case SQL_C_UBIGINT:
5465  buflen = sizeof (SQLBIGINT);
5466  break;
5467 #endif
5468 #ifdef SQL_C_SBIGINT
5469  case SQL_C_SBIGINT:
5470  buflen = sizeof (SQLBIGINT);
5471  break;
5472 #endif
5473 #ifdef SQL_C_BIGINT
5474  case SQL_C_BIGINT:
5475  buflen = sizeof (SQLBIGINT);
5476  break;
5477 #endif
5478  }
5479  p = &s->bindparms[pnum];
5480  p->type = buftype;
5481  p->stype = ptype;
5482  p->coldef = coldef;
5483  p->scale = scale;
5484  p->max = buflen;
5485  p->inc = buflen;
5486  p->lenp = p->lenp0 = len;
5487  p->offs = 0;
5488  p->len = 0;
5489  p->param0 = data;
5490  freep(&p->parbuf);
5491  p->param = p->param0;
5492  p->bound = 1;
5493  p->need = 0;
5494  return SQL_SUCCESS;
5495 }
5496 
5512 SQLRETURN SQL_API
5513 SQLBindParameter(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
5514  SQLSMALLINT buftype, SQLSMALLINT ptype, SQLULEN coldef,
5515  SQLSMALLINT scale,
5516  SQLPOINTER data, SQLLEN buflen, SQLLEN *len)
5517 {
5518  SQLRETURN ret;
5519 
5520  HSTMT_LOCK(stmt);
5521  ret = drvbindparam(stmt, pnum, iotype, buftype, ptype, coldef,
5522  scale, data, buflen, len);
5523  HSTMT_UNLOCK(stmt);
5524  return ret;
5525 }
5526 
5527 #ifndef HAVE_IODBC
5528 
5541 SQLRETURN SQL_API
5542 SQLBindParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT vtype,
5543  SQLSMALLINT ptype, SQLULEN lenprec,
5544  SQLSMALLINT scale, SQLPOINTER val,
5545  SQLLEN *lenp)
5546 {
5547  SQLRETURN ret;
5548 
5549  HSTMT_LOCK(stmt);
5550  ret = drvbindparam(stmt, pnum, SQL_PARAM_INPUT, vtype, ptype,
5551  lenprec, scale, val, 0, lenp);
5552  HSTMT_UNLOCK(stmt);
5553  return ret;
5554 }
5555 #endif
5556 
5564 SQLRETURN SQL_API
5565 SQLNumParams(SQLHSTMT stmt, SQLSMALLINT *nparam)
5566 {
5567  STMT *s;
5568  SQLSMALLINT dummy;
5569 
5570  HSTMT_LOCK(stmt);
5571  if (stmt == SQL_NULL_HSTMT) {
5572  return SQL_INVALID_HANDLE;
5573  }
5574  s = (STMT *) stmt;
5575  if (!nparam) {
5576  nparam = &dummy;
5577  }
5578  *nparam = s->nparams;
5579  HSTMT_UNLOCK(stmt);
5580  return SQL_SUCCESS;
5581 }
5582 
5590 static SQLRETURN
5592 {
5593  if (!p->parbuf) {
5594  if (*p->lenp == SQL_DATA_AT_EXEC) {
5595  p->len = p->max;
5596  } else {
5597  p->len = SQL_LEN_DATA_AT_EXEC(*p->lenp);
5598  }
5599  if (p->len < 0 && p->len != SQL_NTS &&
5600  p->len != SQL_NULL_DATA) {
5601  setstat(s, -1, "invalid length", "HY009");
5602  return SQL_ERROR;
5603  }
5604  if (p->len >= 0) {
5605  p->parbuf = xmalloc(p->len + 2);
5606  if (!p->parbuf) {
5607  return nomem(s);
5608  }
5609  p->param = p->parbuf;
5610  } else {
5611  p->param = NULL;
5612  }
5613  }
5614  return SQL_NEED_DATA;
5615 }
5616 
5624 SQLRETURN SQL_API
5625 SQLParamData(SQLHSTMT stmt, SQLPOINTER *pind)
5626 {
5627  STMT *s;
5628  int i;
5629  SQLPOINTER dummy;
5630  SQLRETURN ret;
5631  BINDPARM *p;
5632 
5633  HSTMT_LOCK(stmt);
5634  if (stmt == SQL_NULL_HSTMT) {
5635  return SQL_INVALID_HANDLE;
5636  }
5637  s = (STMT *) stmt;
5638  if (!pind) {
5639  pind = &dummy;
5640  }
5641  if (s->pdcount < s->nparams) {
5642  s->pdcount++;
5643  }
5644  for (i = 0; i < s->pdcount; i++) {
5645  p = &s->bindparms[i];
5646  if (p->need > 0) {
5647  int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
5648 
5649  p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR) ? -1 : 0;
5650  }
5651  }
5652  for (; i < s->nparams; i++) {
5653  p = &s->bindparms[i];
5654  if (p->need > 0) {
5655  *pind = (SQLPOINTER) p->param0;
5656  ret = setupparbuf(s, p);
5657  s->pdcount = i;
5658  goto done;
5659  }
5660  }
5661  ret = drvexecute(stmt, 0);
5662 done:
5663  HSTMT_UNLOCK(stmt);
5664  return ret;
5665 }
5666 
5678 SQLRETURN SQL_API
5679 SQLDescribeParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT *dtype,
5680  SQLULEN *size, SQLSMALLINT *decdigits, SQLSMALLINT *nullable)
5681 {
5682  STMT *s;
5683  SQLRETURN ret = SQL_ERROR;
5684 
5685  HSTMT_LOCK(stmt);
5686  if (stmt == SQL_NULL_HSTMT) {
5687  return SQL_INVALID_HANDLE;
5688  }
5689  s = (STMT *) stmt;
5690  --pnum;
5691  if (pnum >= s->nparams) {
5692  setstat(s, -1, "invalid parameter index",
5693  (*s->ov3) ? "HY000" : "S1000");
5694  goto done;
5695  }
5696  if (dtype) {
5697 #ifdef SQL_LONGVARCHAR
5698 #ifdef WINTERFACE
5699  *dtype = s->nowchar[0] ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
5700 #else
5701  *dtype = SQL_LONGVARCHAR;
5702 #endif
5703 #else
5704 #ifdef WINTERFACE
5705  *dtype = s->nowchar[0] ? SQL_VARCHAR : SQL_WVARCHAR;
5706 #else
5707  *dtype = SQL_VARCHAR;
5708 #endif
5709 #endif
5710  }
5711  if (size) {
5712 #ifdef SQL_LONGVARCHAR
5713  *size = 65536;
5714 #else
5715  *size = 255;
5716 #endif
5717  }
5718  if (decdigits) {
5719  *decdigits = 0;
5720  }
5721  if (nullable) {
5722  *nullable = SQL_NULLABLE;
5723  }
5724  ret = SQL_SUCCESS;
5725 done:
5726  HSTMT_UNLOCK(stmt);
5727  return ret;
5728 }
5729 
5743 SQLRETURN SQL_API
5744 SQLSetParam(SQLHSTMT stmt, SQLUSMALLINT par, SQLSMALLINT type,
5745  SQLSMALLINT sqltype, SQLULEN coldef,
5746  SQLSMALLINT scale, SQLPOINTER val, SQLLEN *nval)
5747 {
5748  SQLRETURN ret;
5749 
5750  HSTMT_LOCK(stmt);
5751  ret = drvbindparam(stmt, par, SQL_PARAM_INPUT,
5752  type, sqltype, coldef, scale, val,
5753  SQL_SETPARAM_VALUE_MAX, nval);
5754  HSTMT_UNLOCK(stmt);
5755  return ret;
5756 }
5757 
5762 SQLRETURN SQL_API
5763 SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
5764 {
5765  SQLRETURN ret;
5766 
5767  HSTMT_LOCK(stmt);
5768  ret = drvunimplstmt(stmt);
5769  HSTMT_UNLOCK(stmt);
5770  return ret;
5771 }
5772 
5773 #ifndef WINTERFACE
5774 
5778 SQLRETURN SQL_API
5779 SQLGetDescField(SQLHDESC handle, SQLSMALLINT recno,
5780  SQLSMALLINT fieldid, SQLPOINTER value,
5781  SQLINTEGER buflen, SQLINTEGER *strlen)
5782 {
5783  return SQL_ERROR;
5784 }
5785 #endif
5786 
5787 #ifdef WINTERFACE
5788 
5792 SQLRETURN SQL_API
5793 SQLGetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
5794  SQLSMALLINT fieldid, SQLPOINTER value,
5795  SQLINTEGER buflen, SQLINTEGER *strlen)
5796 {
5797  return SQL_ERROR;
5798 }
5799 #endif
5800 
5801 #ifndef WINTERFACE
5802 
5806 SQLRETURN SQL_API
5807 SQLSetDescField(SQLHDESC handle, SQLSMALLINT recno,
5808  SQLSMALLINT fieldid, SQLPOINTER value,
5809  SQLINTEGER buflen)
5810 {
5811  return SQL_ERROR;
5812 }
5813 #endif
5814 
5815 #ifdef WINTERFACE
5816 
5820 SQLRETURN SQL_API
5821 SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
5822  SQLSMALLINT fieldid, SQLPOINTER value,
5823  SQLINTEGER buflen)
5824 {
5825  return SQL_ERROR;
5826 }
5827 #endif
5828 
5829 #ifndef WINTERFACE
5830 
5834 SQLRETURN SQL_API
5835 SQLGetDescRec(SQLHDESC handle, SQLSMALLINT recno,
5836  SQLCHAR *name, SQLSMALLINT buflen,
5837  SQLSMALLINT *strlen, SQLSMALLINT *type,
5838  SQLSMALLINT *subtype, SQLLEN *len,
5839  SQLSMALLINT *prec, SQLSMALLINT *scale,
5840  SQLSMALLINT *nullable)
5841 {
5842  return SQL_ERROR;
5843 }
5844 #endif
5845 
5846 #ifdef WINTERFACE
5847 
5851 SQLRETURN SQL_API
5852 SQLGetDescRecW(SQLHDESC handle, SQLSMALLINT recno,
5853  SQLWCHAR *name, SQLSMALLINT buflen,
5854  SQLSMALLINT *strlen, SQLSMALLINT *type,
5855  SQLSMALLINT *subtype, SQLLEN *len,
5856  SQLSMALLINT *prec, SQLSMALLINT *scale,
5857  SQLSMALLINT *nullable)
5858 {
5859  return SQL_ERROR;
5860 }
5861 #endif
5862 
5867 SQLRETURN SQL_API
5868 SQLSetDescRec(SQLHDESC handle, SQLSMALLINT recno,
5869  SQLSMALLINT type, SQLSMALLINT subtype,
5870  SQLLEN len, SQLSMALLINT prec,
5871  SQLSMALLINT scale, SQLPOINTER data,
5872  SQLLEN *strlen, SQLLEN *indicator)
5873 {
5874  return SQL_ERROR;
5875 }
5876 
5888 static SQLRETURN
5889 mkresultset(HSTMT stmt, COL *colspec, int ncols, COL *colspec3,
5890  int ncols3, int *nret)
5891 {
5892  STMT *s;
5893  DBC *d;
5894 
5895  if (stmt == SQL_NULL_HSTMT) {
5896  return SQL_INVALID_HANDLE;
5897  }
5898  s = (STMT *) stmt;
5899  if (s->dbc == SQL_NULL_HDBC) {
5900 noconn:
5901  return noconn(s);
5902  }
5903  d = (DBC *) s->dbc;
5904  if (!d->sqlite) {
5905  goto noconn;
5906  }
5907  s3stmt_end_if(s);
5908  freeresult(s, 0);
5909  if (colspec3 && *s->ov3) {
5910  s->ncols = ncols3;
5911  s->cols = colspec3;
5912  } else {
5913  s->ncols = ncols;
5914  s->cols = colspec;
5915  }
5916  mkbindcols(s, s->ncols);
5917  s->nowchar[1] = 1;
5918  s->nrows = 0;
5919  s->rowp = s->rowprs = -1;
5920  s->isselect = -1;
5921  if (nret) {
5922  *nret = s->ncols;
5923  }
5924  return SQL_SUCCESS;
5925 }
5926 
5931 static COL tablePrivSpec2[] = {
5932  { "SYSTEM", "TABLEPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
5933  { "SYSTEM", "TABLEPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
5934  { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
5935  { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
5936  { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
5937  { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
5938  { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
5939 };
5940 
5941 static COL tablePrivSpec3[] = {
5942  { "SYSTEM", "TABLEPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
5943  { "SYSTEM", "TABLEPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
5944  { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
5945  { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
5946  { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
5947  { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
5948  { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
5949 };
5950 
5963 static SQLRETURN
5965  SQLCHAR *cat, SQLSMALLINT catLen,
5966  SQLCHAR *schema, SQLSMALLINT schemaLen,
5967  SQLCHAR *table, SQLSMALLINT tableLen)
5968 {
5969  SQLRETURN ret;
5970  STMT *s;
5971  DBC *d;
5972  int ncols, rc, size, npatt;
5973  char *errp = NULL, *sql, tname[512];
5974 
5977  if (ret != SQL_SUCCESS) {
5978  return ret;
5979  }
5980  s = (STMT *) stmt;
5981  d = (DBC *) s->dbc;
5982  if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
5983  table = NULL;
5984  goto doit;
5985  }
5986  if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
5987  schema[0] == '%') {
5988  if ((!cat || catLen == 0 || !cat[0]) &&
5989  (!table || tableLen == 0 || !table[0])) {
5990  table = NULL;
5991  goto doit;
5992  }
5993  }
5994 doit:
5995  if (!table) {
5996  size = 1;
5997  tname[0] = '%';
5998  } else {
5999  if (tableLen == SQL_NTS) {
6000  size = sizeof (tname) - 1;
6001  } else {
6002  size = min(sizeof (tname) - 1, tableLen);
6003  }
6004  strncpy(tname, (char *) table, size);
6005  }
6006  tname[size] = '\0';
6007  npatt = unescpat(tname);
6008 #if defined(_WIN32) || defined(_WIN64)
6009  sql = sqlite3_mprintf("select %s as 'TABLE_QUALIFIER', "
6010  "%s as 'TABLE_OWNER', "
6011  "tbl_name as 'TABLE_NAME', "
6012  "'' as 'GRANTOR', "
6013  "'' as 'GRANTEE', "
6014  "'SELECT' AS 'PRIVILEGE', "
6015  "NULL as 'IS_GRANTABLE' "
6016  "from sqlite_master where "
6017  "(type = 'table' or type = 'view') "
6018  "and tbl_name %s %Q "
6019  "UNION "
6020  "select %s as 'TABLE_QUALIFIER', "
6021  "%s as 'TABLE_OWNER', "
6022  "tbl_name as 'TABLE_NAME', "
6023  "'' as 'GRANTOR', "
6024  "'' as 'GRANTEE', "
6025  "'UPDATE' AS 'PRIVILEGE', "
6026  "NULL as 'IS_GRANTABLE' "
6027  "from sqlite_master where "
6028  "(type = 'table' or type = 'view') "
6029  "and tbl_name %s %Q "
6030  "UNION "
6031  "select %s as 'TABLE_QUALIFIER', "
6032  "%s as 'TABLE_OWNER', "
6033  "tbl_name as 'TABLE_NAME', "
6034  "'' as 'GRANTOR', "
6035  "'' as 'GRANTEE', "
6036  "'DELETE' AS 'PRIVILEGE', "
6037  "NULL as 'IS_GRANTABLE' "
6038  "from sqlite_master where "
6039  "(type = 'table' or type = 'view') "
6040  "and tbl_name %s %Q "
6041  "UNION "
6042  "select %s as 'TABLE_QUALIFIER', "
6043  "%s as 'TABLE_OWNER', "
6044  "tbl_name as 'TABLE_NAME', "
6045  "'' as 'GRANTOR', "
6046  "'' as 'GRANTEE', "
6047  "'INSERT' AS 'PRIVILEGE', "
6048  "NULL as 'IS_GRANTABLE' "
6049  "from sqlite_master where "
6050  "(type = 'table' or type = 'view') "
6051  "and tbl_name %s %Q "
6052  "UNION "
6053  "select %s as 'TABLE_QUALIFIER', "
6054  "%s as 'TABLE_OWNER', "
6055  "tbl_name as 'TABLE_NAME', "
6056  "'' as 'GRANTOR', "
6057  "'' as 'GRANTEE', "
6058  "'REFERENCES' AS 'PRIVILEGE', "
6059  "NULL as 'IS_GRANTABLE' "
6060  "from sqlite_master where "
6061  "(type = 'table' or type = 'view') "
6062  "and tbl_name %s %Q",
6063  d->xcelqrx ? "'main'" : "NULL",
6064  d->xcelqrx ? "''" : "NULL",
6065  npatt ? "like" : "=", tname,
6066  d->xcelqrx ? "'main'" : "NULL",
6067  d->xcelqrx ? "''" : "NULL",
6068  npatt ? "like" : "=", tname,
6069  d->xcelqrx ? "'main'" : "NULL",
6070  d->xcelqrx ? "''" : "NULL",
6071  npatt ? "like" : "=", tname,
6072  d->xcelqrx ? "'main'" : "NULL",
6073  d->xcelqrx ? "''" : "NULL",
6074  npatt ? "like" : "=", tname,
6075  d->xcelqrx ? "'main'" : "NULL",
6076  d->xcelqrx ? "''" : "NULL",
6077  npatt ? "like" : "=", tname);
6078 #else
6079  sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
6080  "NULL as 'TABLE_OWNER', "
6081  "tbl_name as 'TABLE_NAME', "
6082  "'' as 'GRANTOR', "
6083  "'' as 'GRANTEE', "
6084  "'SELECT' AS 'PRIVILEGE', "
6085  "NULL as 'IS_GRANTABLE' "
6086  "from sqlite_master where "
6087  "(type = 'table' or type = 'view') "
6088  "and tbl_name %s %Q "
6089  "UNION "
6090  "select NULL as 'TABLE_QUALIFIER', "
6091  "NULL as 'TABLE_OWNER', "
6092  "tbl_name as 'TABLE_NAME', "
6093  "'' as 'GRANTOR', "
6094  "'' as 'GRANTEE', "
6095  "'UPDATE' AS 'PRIVILEGE', "
6096  "NULL as 'IS_GRANTABLE' "
6097  "from sqlite_master where "
6098  "(type = 'table' or type = 'view') "
6099  "and tbl_name %s %Q "
6100  "UNION "
6101  "select NULL as 'TABLE_QUALIFIER', "
6102  "NULL as 'TABLE_OWNER', "
6103  "tbl_name as 'TABLE_NAME', "
6104  "'' as 'GRANTOR', "
6105  "'' as 'GRANTEE', "
6106  "'DELETE' AS 'PRIVILEGE', "
6107  "NULL as 'IS_GRANTABLE' "
6108  "from sqlite_master where "
6109  "(type = 'table' or type = 'view') "
6110  "and tbl_name %s %Q "
6111  "UNION "
6112  "select NULL as 'TABLE_QUALIFIER', "
6113  "NULL as 'TABLE_OWNER', "
6114  "tbl_name as 'TABLE_NAME', "
6115  "'' as 'GRANTOR', "
6116  "'' as 'GRANTEE', "
6117  "'INSERT' AS 'PRIVILEGE', "
6118  "NULL as 'IS_GRANTABLE' "
6119  "from sqlite_master where "
6120  "(type = 'table' or type = 'view') "
6121  "and tbl_name %s %Q "
6122  "UNION "
6123  "select NULL as 'TABLE_QUALIFIER', "
6124  "NULL as 'TABLE_OWNER', "
6125  "tbl_name as 'TABLE_NAME', "
6126  "'' as 'GRANTOR', "
6127  "'' as 'GRANTEE', "
6128  "'REFERENCES' AS 'PRIVILEGE', "
6129  "NULL as 'IS_GRANTABLE' "
6130  "from sqlite_master where "
6131  "(type = 'table' or type = 'view') "
6132  "and tbl_name %s %Q",
6133  npatt ? "like" : "=", tname,
6134  npatt ? "like" : "=", tname,
6135  npatt ? "like" : "=", tname,
6136  npatt ? "like" : "=", tname,
6137  npatt ? "like" : "=", tname);
6138 #endif
6139  if (!sql) {
6140  return nomem(s);
6141  }
6142  ret = starttran(s);
6143  if (ret != SQL_SUCCESS) {
6144  sqlite3_free(sql);
6145  return ret;
6146  }
6147  dbtraceapi(d, "sqlite3_get_table", sql);
6148  rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
6149  sqlite3_free(sql);
6150  if (rc == SQLITE_OK) {
6151  if (ncols != s->ncols) {
6152  freeresult(s, 0);
6153  s->nrows = 0;
6154  } else {
6155  s->rowfree = sqlite3_free_table;
6156  }
6157  } else {
6158  s->nrows = 0;
6159  s->rows = NULL;
6160  s->rowfree = NULL;
6161  }
6162  if (errp) {
6163  sqlite3_free(errp);
6164  errp = NULL;
6165  }
6166  s->rowp = s->rowprs = -1;
6167  return SQL_SUCCESS;
6168 }
6169 
6170 
6171 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
6172 
6184 SQLRETURN SQL_API
6185 SQLTablePrivileges(SQLHSTMT stmt,
6186  SQLCHAR *catalog, SQLSMALLINT catalogLen,
6187  SQLCHAR *schema, SQLSMALLINT schemaLen,
6188  SQLCHAR *table, SQLSMALLINT tableLen)
6189 {
6190 #if defined(_WIN32) || defined(_WIN64)
6191  char *c = NULL, *s = NULL, *t = NULL;
6192 #endif
6193  SQLRETURN ret;
6194 
6195  HSTMT_LOCK(stmt);
6196 #if defined(_WIN32) || defined(_WIN64)
6197  if (!((STMT *) stmt)->oemcp[0]) {
6198  ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
6199  table, tableLen);
6200  goto done2;
6201  }
6202  if (catalog) {
6203  c = wmb_to_utf_c((char *) catalog, catalogLen);
6204  if (!c) {
6205  ret = nomem((STMT *) stmt);
6206  goto done;
6207  }
6208  }
6209  if (schema) {
6210  s = wmb_to_utf_c((char *) schema, schemaLen);
6211  if (!s) {
6212  ret = nomem((STMT *) stmt);
6213  goto done;
6214  }
6215  }
6216  if (table) {
6217  t = wmb_to_utf_c((char *) table, tableLen);
6218  if (!t) {
6219  ret = nomem((STMT *) stmt);
6220  goto done;
6221  }
6222  }
6223  ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
6224  (SQLCHAR *) s, SQL_NTS,
6225  (SQLCHAR *) t, SQL_NTS);
6226 #else
6227  ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
6228  table, tableLen);
6229 #endif
6230 #if defined(_WIN32) || defined(_WIN64)
6231 done:
6232  uc_free(t);
6233  uc_free(s);
6234  uc_free(c);
6235 done2:
6236  ;
6237 #endif
6238  HSTMT_UNLOCK(stmt);
6239  return ret;
6240 }
6241 #endif
6242 
6243 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
6244 #ifdef WINTERFACE
6245 
6257 SQLRETURN SQL_API
6259  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
6260  SQLWCHAR *schema, SQLSMALLINT schemaLen,
6261  SQLWCHAR *table, SQLSMALLINT tableLen)
6262 {
6263  char *c = NULL, *s = NULL, *t = NULL;
6264  SQLRETURN ret;
6265 
6266  HSTMT_LOCK(stmt);
6267  if (catalog) {
6268  c = uc_to_utf_c(catalog, catalogLen);
6269  if (!c) {
6270  ret = nomem((STMT *) stmt);
6271  goto done;
6272  }
6273  }
6274  if (schema) {
6275  s = uc_to_utf_c(schema, schemaLen);
6276  if (!s) {
6277  ret = nomem((STMT *) stmt);
6278  goto done;
6279  }
6280  }
6281  if (table) {
6282  t = uc_to_utf_c(table, tableLen);
6283  if (!t) {
6284  ret = nomem((STMT *) stmt);
6285  goto done;
6286  }
6287  }
6288  ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
6289  (SQLCHAR *) s, SQL_NTS,
6290  (SQLCHAR *) t, SQL_NTS);
6291 done:
6292  uc_free(t);
6293  uc_free(s);
6294  uc_free(c);
6295  HSTMT_UNLOCK(stmt);
6296  return ret;
6297 }
6298 #endif
6299 #endif
6300 
6305 static COL colPrivSpec2[] = {
6306  { "SYSTEM", "COLPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
6307  { "SYSTEM", "COLPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
6308  { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6309  { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6310  { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6311  { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6312  { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
6313 };
6314 
6315 static COL colPrivSpec3[] = {
6316  { "SYSTEM", "COLPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
6317  { "SYSTEM", "COLPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
6318  { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6319  { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6320  { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6321  { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6322  { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
6323 };
6324 
6325 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
6326 
6340 SQLRETURN SQL_API
6341 SQLColumnPrivileges(SQLHSTMT stmt,
6342  SQLCHAR *catalog, SQLSMALLINT catalogLen,
6343  SQLCHAR *schema, SQLSMALLINT schemaLen,
6344  SQLCHAR *table, SQLSMALLINT tableLen,
6345  SQLCHAR *column, SQLSMALLINT columnLen)
6346 {
6347  SQLRETURN ret;
6348 
6349  HSTMT_LOCK(stmt);
6352  HSTMT_UNLOCK(stmt);
6353  return ret;
6354 }
6355 #endif
6356 
6357 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
6358 #ifdef WINTERFACE
6359 
6373 SQLRETURN SQL_API
6375  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
6376  SQLWCHAR *schema, SQLSMALLINT schemaLen,
6377  SQLWCHAR *table, SQLSMALLINT tableLen,
6378  SQLWCHAR *column, SQLSMALLINT columnLen)
6379 {
6380  SQLRETURN ret;
6381 
6382  HSTMT_LOCK(stmt);
6385  HSTMT_UNLOCK(stmt);
6386  return ret;
6387 }
6388 #endif
6389 #endif
6390 
6395 static COL pkeySpec2[] = {
6396  { "SYSTEM", "PRIMARYKEY", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
6397  { "SYSTEM", "PRIMARYKEY", "TABLE_OWNER", SCOL_VARCHAR, 50 },
6398  { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
6399  { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6400  { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
6401  { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
6402 };
6403 
6404 static COL pkeySpec3[] = {
6405  { "SYSTEM", "PRIMARYKEY", "TABLE_CAT", SCOL_VARCHAR, 50 },
6406  { "SYSTEM", "PRIMARYKEY", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
6407  { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
6408  { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6409  { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
6410  { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
6411 };
6412 
6425 static SQLRETURN
6427  SQLCHAR *cat, SQLSMALLINT catLen,
6428  SQLCHAR *schema, SQLSMALLINT schemaLen,
6429  SQLCHAR *table, SQLSMALLINT tableLen)
6430 {
6431  STMT *s;
6432  DBC *d;
6433  SQLRETURN sret;
6434  int i, asize, ret, nrows, ncols, nrows2 = 0, ncols2 = 0;
6435  int namec = -1, uniquec = -1, namec2 = -1, uniquec2 = -1, offs, seq = 1;
6436  PTRDIFF_T size;
6437  char **rowp = NULL, **rowp2 = NULL, *errp = NULL, *sql, tname[512];
6438 
6440  pkeySpec3, array_size(pkeySpec3), &asize);
6441  if (sret != SQL_SUCCESS) {
6442  return sret;
6443  }
6444  s = (STMT *) stmt;
6445  d = (DBC *) s->dbc;
6446  if (!table || table[0] == '\0' || table[0] == '%') {
6447  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
6448  return SQL_ERROR;
6449  }
6450  if (tableLen == SQL_NTS) {
6451  size = sizeof (tname) - 1;
6452  } else {
6453  size = min(sizeof (tname) - 1, tableLen);
6454  }
6455  strncpy(tname, (char *) table, size);
6456  tname[size] = '\0';
6457  unescpat(tname);
6458  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
6459  if (!sql) {
6460  return nomem(s);
6461  }
6462  sret = starttran(s);
6463  if (sret != SQL_SUCCESS) {
6464  sqlite3_free(sql);
6465  return sret;
6466  }
6467  dbtraceapi(d, "sqlite3_get_table", sql);
6468  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
6469  sqlite3_free(sql);
6470  if (ret != SQLITE_OK) {
6471  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6472  errp ? errp : "unknown error", ret);
6473  if (errp) {
6474  sqlite3_free(errp);
6475  errp = NULL;
6476  }
6477  return SQL_ERROR;
6478  }
6479  if (errp) {
6480  sqlite3_free(errp);
6481  errp = NULL;
6482  }
6483  size = 0;
6484  if (ncols * nrows > 0) {
6485  int typec;
6486 
6487  namec = findcol(rowp, ncols, "name");
6488  uniquec = findcol(rowp, ncols, "pk");
6489  typec = findcol(rowp, ncols, "type");
6490  if (namec >= 0 && uniquec >= 0 && typec >= 0) {
6491  for (i = 1; i <= nrows; i++) {
6492  if (*rowp[i * ncols + uniquec] != '0') {
6493  size++;
6494  }
6495  }
6496  }
6497  }
6498  if (size == 0) {
6499  sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
6500  if (!sql) {
6501  sqlite3_free_table(rowp);
6502  return nomem(s);
6503  }
6504  dbtraceapi(d, "sqlite3_get_table", sql);
6505  ret = sqlite3_get_table(d->sqlite, sql, &rowp2, &nrows2, &ncols2,
6506  &errp);
6507  sqlite3_free(sql);
6508  if (ret != SQLITE_OK) {
6509  sqlite3_free_table(rowp);
6510  sqlite3_free_table(rowp2);
6511  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6512  errp ? errp : "unknown error", ret);
6513  if (errp) {
6514  sqlite3_free(errp);
6515  errp = NULL;
6516  }
6517  return SQL_ERROR;
6518  }
6519  if (errp) {
6520  sqlite3_free(errp);
6521  errp = NULL;
6522  }
6523  }
6524  if (ncols2 * nrows2 > 0) {
6525  namec2 = findcol(rowp2, ncols2, "name");
6526  uniquec2 = findcol(rowp2, ncols2, "unique");
6527  if (namec2 >= 0 && uniquec2 >= 0) {
6528  for (i = 1; i <= nrows2; i++) {
6529  int nnrows, nncols, nlen = 0;
6530  char **rowpp;
6531 
6532  if (rowp2[i * ncols2 + namec2]) {
6533  nlen = strlen(rowp2[i * ncols2 + namec2]);
6534  }
6535  if (nlen < 17 ||
6536  strncmp(rowp2[i * ncols2 + namec2],
6537  "sqlite_autoindex_", 17)) {
6538  continue;
6539  }
6540  if (*rowp2[i * ncols2 + uniquec2] != '0') {
6541  ret = SQLITE_ERROR;
6542  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6543  rowp2[i * ncols2 + namec2]);
6544  if (sql) {
6545  dbtraceapi(d, "sqlite3_get_table", sql);
6546  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6547  &nnrows, &nncols, NULL);
6548  sqlite3_free(sql);
6549  }
6550  if (ret == SQLITE_OK) {
6551  size += nnrows;
6552  sqlite3_free_table(rowpp);
6553  }
6554  }
6555  }
6556  }
6557  }
6558  if (size == 0) {
6559  sqlite3_free_table(rowp);
6560  sqlite3_free_table(rowp2);
6561  return SQL_SUCCESS;
6562  }
6563  s->nrows = size;
6564  size = (size + 1) * asize;
6565  s->rows = xmalloc((size + 1) * sizeof (char *));
6566  if (!s->rows) {
6567  s->nrows = 0;
6568  sqlite3_free_table(rowp);
6569  sqlite3_free_table(rowp2);
6570  return nomem(s);
6571  }
6572  s->rows[0] = (char *) size;
6573  s->rows += 1;
6574  memset(s->rows, 0, sizeof (char *) * size);
6575  s->rowfree = freerows;
6576  offs = s->ncols;
6577  if (rowp) {
6578  for (i = 1; i <= nrows; i++) {
6579  if (*rowp[i * ncols + uniquec] != '0') {
6580  char buf[32];
6581 
6582 #if defined(_WIN32) || defined(_WIN64)
6583  s->rows[offs + 0] = xstrdup(d->xcelqrx ? "main" : "");
6584  s->rows[offs + 1] = xstrdup("");
6585 #else
6586  s->rows[offs + 0] = xstrdup("");
6587  s->rows[offs + 1] = xstrdup("");
6588 #endif
6589  s->rows[offs + 2] = xstrdup(tname);
6590  s->rows[offs + 3] = xstrdup(rowp[i * ncols + namec]);
6591  sprintf(buf, "%d", seq++);
6592  s->rows[offs + 4] = xstrdup(buf);
6593  offs += s->ncols;
6594  }
6595  }
6596  }
6597  if (rowp2) {
6598  for (i = 1; i <= nrows2; i++) {
6599  int nnrows, nncols, nlen = 0;
6600  char **rowpp;
6601 
6602  if (rowp2[i * ncols2 + namec2]) {
6603  nlen = strlen(rowp2[i * ncols2 + namec2]);
6604  }
6605  if (nlen < 17 ||
6606  strncmp(rowp2[i * ncols2 + namec2], "sqlite_autoindex_", 17)) {
6607  continue;
6608  }
6609  if (*rowp2[i * ncols2 + uniquec2] != '0') {
6610  int k;
6611 
6612  ret = SQLITE_ERROR;
6613  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6614  rowp2[i * ncols2 + namec2]);
6615  if (sql) {
6616  dbtraceapi(d, "sqlite3_get_table", sql);
6617  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6618  &nnrows, &nncols, NULL);
6619  sqlite3_free(sql);
6620  }
6621  if (ret != SQLITE_OK) {
6622  continue;
6623  }
6624  for (k = 0; nnrows && k < nncols; k++) {
6625  if (strcmp(rowpp[k], "name") == 0) {
6626  int m;
6627 
6628  for (m = 1; m <= nnrows; m++) {
6629  int roffs = offs + (m - 1) * s->ncols;
6630 
6631 #if defined(_WIN32) || defined(_WIN64)
6632  s->rows[roffs + 0] =
6633  xstrdup(d->xcelqrx ? "main" : "");
6634  s->rows[roffs + 1] = xstrdup("");
6635 #else
6636  s->rows[roffs + 0] = xstrdup("");
6637  s->rows[roffs + 1] = xstrdup("");
6638 #endif
6639  s->rows[roffs + 2] = xstrdup(tname);
6640  s->rows[roffs + 3] =
6641  xstrdup(rowpp[m * nncols + k]);
6642  s->rows[roffs + 5] =
6643  xstrdup(rowp2[i * ncols2 + namec2]);
6644  }
6645  } else if (strcmp(rowpp[k], "seqno") == 0) {
6646  int m;
6647 
6648  for (m = 1; m <= nnrows; m++) {
6649  int roffs = offs + (m - 1) * s->ncols;
6650  int pos = m - 1;
6651  char buf[32];
6652 
6653  sscanf(rowpp[m * nncols + k], "%d", &pos);
6654  sprintf(buf, "%d", pos + 1);
6655  s->rows[roffs + 4] = xstrdup(buf);
6656  }
6657  }
6658  }
6659  offs += nnrows * s->ncols;
6660  sqlite3_free_table(rowpp);
6661  }
6662  }
6663  }
6664  sqlite3_free_table(rowp);
6665  sqlite3_free_table(rowp2);
6666  return SQL_SUCCESS;
6667 }
6668 
6669 #ifndef WINTERFACE
6670 
6682 SQLRETURN SQL_API
6683 SQLPrimaryKeys(SQLHSTMT stmt,
6684  SQLCHAR *cat, SQLSMALLINT catLen,
6685  SQLCHAR *schema, SQLSMALLINT schemaLen,
6686  SQLCHAR *table, SQLSMALLINT tableLen)
6687 {
6688 #if defined(_WIN32) || defined(_WIN64)
6689  char *c = NULL, *s = NULL, *t = NULL;
6690 #endif
6691  SQLRETURN ret;
6692 
6693  HSTMT_LOCK(stmt);
6694 #if defined(_WIN32) || defined(_WIN64)
6695  if (!((STMT *) stmt)->oemcp[0]) {
6696  ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
6697  table, tableLen);
6698  goto done2;
6699  }
6700  if (cat) {
6701  c = wmb_to_utf_c((char *) cat, catLen);
6702  if (!c) {
6703  ret = nomem((STMT *) stmt);
6704  goto done;
6705  }
6706  }
6707  if (schema) {
6708  s = wmb_to_utf_c((char *) schema, schemaLen);
6709  if (!s) {
6710  ret = nomem((STMT *) stmt);
6711  goto done;
6712  }
6713  }
6714  if (table) {
6715  t = wmb_to_utf_c((char *) table, tableLen);
6716  if (!t) {
6717  ret = nomem((STMT *) stmt);
6718  goto done;
6719  }
6720  }
6721  ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
6722  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
6723 #else
6724  ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
6725  table, tableLen);
6726 #endif
6727 #if defined(_WIN32) || defined(_WIN64)
6728 done:
6729  uc_free(t);
6730  uc_free(s);
6731  uc_free(c);
6732 done2:
6733  ;
6734 #endif
6735  HSTMT_UNLOCK(stmt);
6736  return ret;
6737 }
6738 #endif
6739 
6740 #ifdef WINTERFACE
6741 
6753 SQLRETURN SQL_API
6755  SQLWCHAR *cat, SQLSMALLINT catLen,
6756  SQLWCHAR *schema, SQLSMALLINT schemaLen,
6757  SQLWCHAR *table, SQLSMALLINT tableLen)
6758 {
6759  char *c = NULL, *s = NULL, *t = NULL;
6760  SQLRETURN ret;
6761 
6762  HSTMT_LOCK(stmt);
6763  if (cat) {
6764  c = uc_to_utf_c(cat, catLen);
6765  if (!c) {
6766  ret = nomem((STMT *) stmt);
6767  goto done;
6768  }
6769  }
6770  if (schema) {
6771  s = uc_to_utf_c(schema, schemaLen);
6772  if (!s) {
6773  ret = nomem((STMT *) stmt);
6774  goto done;
6775  }
6776  }
6777  if (table) {
6778  t = uc_to_utf_c(table, tableLen);
6779  if (!t) {
6780  ret = nomem((STMT *) stmt);
6781  goto done;
6782  }
6783  }
6784  ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
6785  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
6786 done:
6787  uc_free(t);
6788  uc_free(s);
6789  uc_free(c);
6790  HSTMT_UNLOCK(stmt);
6791  return ret;
6792 }
6793 #endif
6794 
6799 static COL scolSpec2[] = {
6800  { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
6801  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6802  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
6803  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
6804  { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
6805  { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
6806  { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
6807  { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
6808  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
6809 };
6810 
6811 static COL scolSpec3[] = {
6812  { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
6813  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6814  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
6815  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
6816  { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
6817  { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
6818  { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
6819  { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
6820  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
6821 };
6822 
6838 static SQLRETURN
6839 drvspecialcolumns(SQLHSTMT stmt, SQLUSMALLINT id,
6840  SQLCHAR *cat, SQLSMALLINT catLen,
6841  SQLCHAR *schema, SQLSMALLINT schemaLen,
6842  SQLCHAR *table, SQLSMALLINT tableLen,
6843  SQLUSMALLINT scope, SQLUSMALLINT nullable)
6844 {
6845  STMT *s;
6846  DBC *d;
6847  SQLRETURN sret;
6848  int i, asize, ret, nrows, ncols, nnnrows, nnncols, offs;
6849  PTRDIFF_T size;
6850  int namec = -1, uniquec = -1, namecc = -1, typecc = -1;
6851  int notnullcc = -1, mkrowid = 0;
6852  char *errp = NULL, *sql, tname[512];
6853  char **rowp = NULL, **rowppp = NULL;
6854 
6856  scolSpec3, array_size(scolSpec3), &asize);
6857  if (sret != SQL_SUCCESS) {
6858  return sret;
6859  }
6860  s = (STMT *) stmt;
6861  d = (DBC *) s->dbc;
6862  if (!table || table[0] == '\0' || table[0] == '%') {
6863  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
6864  return SQL_ERROR;
6865  }
6866  if (tableLen == SQL_NTS) {
6867  size = sizeof (tname) - 1;
6868  } else {
6869  size = min(sizeof (tname) - 1, tableLen);
6870  }
6871  strncpy(tname, (char *) table, size);
6872  tname[size] = '\0';
6873  unescpat(tname);
6874  if (id != SQL_BEST_ROWID) {
6875  return SQL_SUCCESS;
6876  }
6877  sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
6878  if (!sql) {
6879  return nomem(s);
6880  }
6881  sret = starttran(s);
6882  if (sret != SQL_SUCCESS) {
6883  sqlite3_free(sql);
6884  return sret;
6885  }
6886  dbtraceapi(d, "sqlite3_get_table", sql);
6887  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
6888  sqlite3_free(sql);
6889  if (ret != SQLITE_OK) {
6890 doerr:
6891  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6892  errp ? errp : "unknown error", ret);
6893  if (errp) {
6894  sqlite3_free(errp);
6895  errp = NULL;
6896  }
6897  return SQL_ERROR;
6898  }
6899  if (errp) {
6900  sqlite3_free(errp);
6901  errp = NULL;
6902  }
6903  size = 0; /* number result rows */
6904  if (ncols * nrows <= 0) {
6905  goto nodata_but_rowid;
6906  }
6907  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
6908  if (!sql) {
6909  return nomem(s);
6910  }
6911  dbtraceapi(d, "sqlite3_get_table", sql);
6912  ret = sqlite3_get_table(d->sqlite, sql, &rowppp, &nnnrows, &nnncols,
6913  &errp);
6914  sqlite3_free(sql);
6915  if (ret != SQLITE_OK) {
6916  sqlite3_free_table(rowp);
6917  goto doerr;
6918  }
6919  if (errp) {
6920  sqlite3_free(errp);
6921  errp = NULL;
6922  }
6923  namec = findcol(rowp, ncols, "name");
6924  uniquec = findcol(rowp, ncols, "unique");
6925  if (namec < 0 || uniquec < 0) {
6926  goto nodata_but_rowid;
6927  }
6928  namecc = findcol(rowppp, nnncols, "name");
6929  typecc = findcol(rowppp, nnncols, "type");
6930  notnullcc = findcol(rowppp, nnncols, "notnull");
6931  for (i = 1; i <= nrows; i++) {
6932  int nnrows, nncols;
6933  char **rowpp = NULL;
6934 
6935  if (*rowp[i * ncols + uniquec] != '0') {
6936  ret = SQLITE_ERROR;
6937  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6938  rowp[i * ncols + namec]);
6939  if (sql) {
6940  dbtraceapi(d, "sqlite3_get_table", sql);
6941  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6942  &nnrows, &nncols, NULL);
6943  sqlite3_free(sql);
6944  }
6945  if (ret == SQLITE_OK) {
6946  size += nnrows;
6947  sqlite3_free_table(rowpp);
6948  }
6949  }
6950  }
6951 nodata_but_rowid:
6952  if (size == 0) {
6953  size = 1;
6954  mkrowid = 1;
6955  }
6956  s->nrows = size;
6957  size = (size + 1) * asize;
6958  s->rows = xmalloc((size + 1) * sizeof (char *));
6959  if (!s->rows) {
6960  s->nrows = 0;
6961  sqlite3_free_table(rowp);
6962  sqlite3_free_table(rowppp);
6963  return nomem(s);
6964  }
6965  s->rows[0] = (char *) size;
6966  s->rows += 1;
6967  memset(s->rows, 0, sizeof (char *) * size);
6968  s->rowfree = freerows;
6969  if (mkrowid) {
6970  s->nrows = 0;
6971  goto mkrowid;
6972  }
6973  offs = 0;
6974  for (i = 1; i <= nrows; i++) {
6975  int nnrows, nncols;
6976  char **rowpp = NULL;
6977 
6978  if (*rowp[i * ncols + uniquec] != '0') {
6979  int k;
6980 
6981  ret = SQLITE_ERROR;
6982  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6983  rowp[i * ncols + namec]);
6984  if (sql) {
6985  dbtraceapi(d, "sqlite3_get_table", sql);
6986  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6987  &nnrows, &nncols, NULL);
6988  sqlite3_free(sql);
6989  }
6990  if (ret != SQLITE_OK) {
6991  continue;
6992  }
6993  for (k = 0; nnrows && k < nncols; k++) {
6994  if (strcmp(rowpp[k], "name") == 0) {
6995  int m;
6996 
6997  for (m = 1; m <= nnrows; m++) {
6998  int roffs = (offs + m) * s->ncols;
6999 
7000  s->rows[roffs + 0] =
7001  xstrdup(stringify(SQL_SCOPE_SESSION));
7002  s->rows[roffs + 1] = xstrdup(rowpp[m * nncols + k]);
7003  s->rows[roffs + 4] = xstrdup("0");
7004  s->rows[roffs + 7] =
7005  xstrdup(stringify(SQL_PC_NOT_PSEUDO));
7006  if (namecc >= 0 && typecc >= 0) {
7007  int ii;
7008 
7009  for (ii = 1; ii <= nnnrows; ii++) {
7010  if (strcmp(rowppp[ii * nnncols + namecc],
7011  rowpp[m * nncols + k]) == 0) {
7012  char *typen = rowppp[ii * nnncols + typecc];
7013  int sqltype, mm, dd, isnullable = 0;
7014  char buf[32];
7015 
7016  s->rows[roffs + 3] = xstrdup(typen);
7017  sqltype = mapsqltype(typen, NULL, *s->ov3,
7018  s->nowchar[0],
7019  s->dobigint);
7020  getmd(typen, sqltype, &mm, &dd);
7021 #ifdef SQL_LONGVARCHAR
7022  if (sqltype == SQL_VARCHAR && mm > 255) {
7023  sqltype = SQL_LONGVARCHAR;
7024  }
7025 #endif
7026 #ifdef WINTERFACE
7027 #ifdef SQL_WLONGVARCHAR
7028  if (sqltype == SQL_WVARCHAR && mm > 255) {
7029  sqltype = SQL_WLONGVARCHAR;
7030  }
7031 #endif
7032 #endif
7033  if (sqltype == SQL_VARBINARY && mm > 255) {
7034  sqltype = SQL_LONGVARBINARY;
7035  }
7036  sprintf(buf, "%d", sqltype);
7037  s->rows[roffs + 2] = xstrdup(buf);
7038  sprintf(buf, "%d", mm);
7039  s->rows[roffs + 5] = xstrdup(buf);
7040  sprintf(buf, "%d", dd);
7041  s->rows[roffs + 6] = xstrdup(buf);
7042  if (notnullcc >= 0) {
7043  char *inp =
7044  rowppp[ii * nnncols + notnullcc];
7045 
7046  isnullable = inp[0] != '0';
7047  }
7048  sprintf(buf, "%d", isnullable);
7049  s->rows[roffs + 8] = xstrdup(buf);
7050  }
7051  }
7052  }
7053  }
7054  }
7055  }
7056  offs += nnrows;
7057  sqlite3_free_table(rowpp);
7058  }
7059  }
7060  if (nullable == SQL_NO_NULLS) {
7061  for (i = 1; i < s->nrows; i++) {
7062  if (s->rows[i * s->ncols + 8][0] == '0') {
7063  int m, i1 = i + 1;
7064 
7065  for (m = 0; m < s->ncols; m++) {
7066  freep(&s->rows[i * s->ncols + m]);
7067  }
7068  size = s->ncols * sizeof (char *) * (s->nrows - i1);
7069  if (size > 0) {
7070  memmove(s->rows + i * s->ncols,
7071  s->rows + i1 * s->ncols,
7072  size);
7073  memset(s->rows + s->nrows * s->ncols, 0,
7074  s->ncols * sizeof (char *));
7075  }
7076  s->nrows--;
7077  --i;
7078  }
7079  }
7080  }
7081 mkrowid:
7082  sqlite3_free_table(rowp);
7083  sqlite3_free_table(rowppp);
7084  if (s->nrows == 0) {
7085  s->rows[s->ncols + 0] = xstrdup(stringify(SQL_SCOPE_SESSION));
7086  s->rows[s->ncols + 1] = xstrdup("_ROWID_");
7087  s->rows[s->ncols + 2] = xstrdup(stringify(SQL_INTEGER));
7088  s->rows[s->ncols + 3] = xstrdup("integer");
7089  s->rows[s->ncols + 4] = xstrdup("0");
7090  s->rows[s->ncols + 5] = xstrdup("10");
7091  s->rows[s->ncols + 6] = xstrdup("9");
7092  s->rows[s->ncols + 7] = xstrdup(stringify(SQL_PC_PSEUDO));
7093  s->rows[s->ncols + 8] = xstrdup(stringify(SQL_FALSE));
7094  s->nrows = 1;
7095  }
7096  return SQL_SUCCESS;
7097 }
7098 
7099 #ifndef WINTERFACE
7100 
7115 SQLRETURN SQL_API
7116 SQLSpecialColumns(SQLHSTMT stmt, SQLUSMALLINT id,
7117  SQLCHAR *cat, SQLSMALLINT catLen,
7118  SQLCHAR *schema, SQLSMALLINT schemaLen,
7119  SQLCHAR *table, SQLSMALLINT tableLen,
7120  SQLUSMALLINT scope, SQLUSMALLINT nullable)
7121 {
7122 #if defined(_WIN32) || defined(_WIN64)
7123  char *c = NULL, *s = NULL, *t = NULL;
7124 #endif
7125  SQLRETURN ret;
7126 
7127  HSTMT_LOCK(stmt);
7128 #if defined(_WIN32) || defined(_WIN64)
7129  if (!((STMT *) stmt)->oemcp[0]) {
7130  ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
7131  table, tableLen, scope, nullable);
7132  goto done2;
7133  }
7134  if (cat) {
7135  c = wmb_to_utf_c((char *) cat, catLen);
7136  if (!c) {
7137  ret = nomem((STMT *) stmt);
7138  goto done;
7139  }
7140  }
7141  if (schema) {
7142  s = wmb_to_utf_c((char *) schema, schemaLen);
7143  if (!s) {
7144  ret = nomem((STMT *) stmt);
7145  goto done;
7146  }
7147  }
7148  if (table) {
7149  t = wmb_to_utf_c((char *) table, tableLen);
7150  if (!t) {
7151  ret = nomem((STMT *) stmt);
7152  goto done;
7153  }
7154  }
7155  ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
7156  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
7157  scope, nullable);
7158 #else
7159  ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
7160  table, tableLen, scope, nullable);
7161 #endif
7162 #if defined(_WIN32) || defined(_WIN64)
7163 done:
7164  uc_free(t);
7165  uc_free(s);
7166  uc_free(c);
7167 done2:
7168  ;
7169 #endif
7170  HSTMT_UNLOCK(stmt);
7171  return ret;
7172 }
7173 #endif
7174 
7175 #ifdef WINTERFACE
7176 
7191 SQLRETURN SQL_API
7192 SQLSpecialColumnsW(SQLHSTMT stmt, SQLUSMALLINT id,
7193  SQLWCHAR *cat, SQLSMALLINT catLen,
7194  SQLWCHAR *schema, SQLSMALLINT schemaLen,
7195  SQLWCHAR *table, SQLSMALLINT tableLen,
7196  SQLUSMALLINT scope, SQLUSMALLINT nullable)
7197 {
7198  char *c = NULL, *s = NULL, *t = NULL;
7199  SQLRETURN ret;
7200 
7201  HSTMT_LOCK(stmt);
7202  if (cat) {
7203  c = uc_to_utf_c(cat, catLen);
7204  if (!c) {
7205  ret = nomem((STMT *) stmt);
7206  goto done;
7207  }
7208  }
7209  if (schema) {
7210  s = uc_to_utf_c(schema, schemaLen);
7211  if (!s) {
7212  ret = nomem((STMT *) stmt);
7213  goto done;
7214  }
7215  }
7216  if (table) {
7217  t = uc_to_utf_c(table, tableLen);
7218  if (!t) {
7219  ret = nomem((STMT *) stmt);
7220  goto done;
7221  }
7222  }
7223  ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
7224  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
7225  scope, nullable);
7226 done:
7227  uc_free(t);
7228  uc_free(s);
7229  uc_free(c);
7230  HSTMT_UNLOCK(stmt);
7231  return ret;
7232 }
7233 #endif
7234 
7239 static COL fkeySpec2[] = {
7240  { "SYSTEM", "FOREIGNKEY", "PKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
7241  { "SYSTEM", "FOREIGNKEY", "PKTABLE_OWNER", SCOL_VARCHAR, 50 },
7242  { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
7243  { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7244  { "SYSTEM", "FOREIGNKEY", "FKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
7245  { "SYSTEM", "FOREIGNKEY", "FKTABLE_OWNER", SCOL_VARCHAR, 50 },
7246  { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
7247  { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7248  { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
7249  { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
7250  { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
7251  { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
7252  { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
7253  { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
7254 };
7255 
7256 static COL fkeySpec3[] = {
7257  { "SYSTEM", "FOREIGNKEY", "PKTABLE_CAT", SCOL_VARCHAR, 50 },
7258  { "SYSTEM", "FOREIGNKEY", "PKTABLE_SCHEM", SCOL_VARCHAR, 50 },
7259  { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
7260  { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7261  { "SYSTEM", "FOREIGNKEY", "FKTABLE_CAT", SCOL_VARCHAR, 50 },
7262  { "SYSTEM", "FOREIGNKEY", "FKTABLE_SCHEM", SCOL_VARCHAR, 50 },
7263  { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
7264  { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7265  { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
7266  { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
7267  { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
7268  { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
7269  { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
7270  { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
7271 };
7272 
7291 static SQLRETURN SQL_API
7293  SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7294  SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
7295  SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
7296  SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7297  SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
7298  SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
7299 {
7300  STMT *s;
7301  DBC *d;
7302  SQLRETURN sret;
7303  int i, asize, ret, nrows, ncols, offs, namec, seqc, fromc, toc;
7304  int onu, ond;
7305  PTRDIFF_T size;
7306  char **rowp, *errp = NULL, *sql, pname[512], fname[512];
7307 
7309  fkeySpec3, array_size(fkeySpec3), &asize);
7310  if (sret != SQL_SUCCESS) {
7311  return sret;
7312  }
7313  s = (STMT *) stmt;
7314  sret = starttran(s);
7315  if (sret != SQL_SUCCESS) {
7316  return sret;
7317  }
7318  d = (DBC *) s->dbc;
7319  if ((!PKtable || PKtable[0] == '\0' || PKtable[0] == '%') &&
7320  (!FKtable || FKtable[0] == '\0' || FKtable[0] == '%')) {
7321  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
7322  return SQL_ERROR;
7323  }
7324  size = 0;
7325  if (PKtable) {
7326  if (PKtableLen == SQL_NTS) {
7327  size = sizeof (pname) - 1;
7328  } else {
7329  size = min(sizeof (pname) - 1, PKtableLen);
7330  }
7331  strncpy(pname, (char *) PKtable, size);
7332  }
7333  pname[size] = '\0';
7334  size = 0;
7335  if (FKtable) {
7336 
7337  if (FKtableLen == SQL_NTS) {
7338  size = sizeof (fname) - 1;
7339  } else {
7340  size = min(sizeof (fname) - 1, FKtableLen);
7341  }
7342  strncpy(fname, (char *) FKtable, size);
7343  }
7344  fname[size] = '\0';
7345  if (fname[0] != '\0') {
7346  int plen;
7347 
7348  ret = SQLITE_ERROR;
7349  sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", fname);
7350  if (sql) {
7351  dbtraceapi(d, "sqlite3_get_table", sql);
7352  ret = sqlite3_get_table(d->sqlite, sql, &rowp,
7353  &nrows, &ncols, &errp);
7354  sqlite3_free(sql);
7355  }
7356  if (ret != SQLITE_OK) {
7357  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7358  errp ? errp : "unknown error", ret);
7359  if (errp) {
7360  sqlite3_free(errp);
7361  errp = NULL;
7362  }
7363  return SQL_ERROR;
7364  }
7365  if (errp) {
7366  sqlite3_free(errp);
7367  errp = NULL;
7368  }
7369  if (ncols * nrows <= 0) {
7370 nodata:
7371  sqlite3_free_table(rowp);
7372  return SQL_SUCCESS;
7373  }
7374  size = 0;
7375  namec = findcol(rowp, ncols, "table");
7376  seqc = findcol(rowp, ncols, "seq");
7377  fromc = findcol(rowp, ncols, "from");
7378  toc = findcol(rowp, ncols, "to");
7379  onu = findcol(rowp, ncols, "on_update");
7380  ond = findcol(rowp, ncols, "on_delete");
7381  if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7382  goto nodata;
7383  }
7384  plen = strlen(pname);
7385  for (i = 1; i <= nrows; i++) {
7386  char *ptab = unquote(rowp[i * ncols + namec]);
7387 
7388  if (plen && ptab) {
7389  int len = strlen(ptab);
7390 
7391  if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
7392  continue;
7393  }
7394  }
7395  size++;
7396  }
7397  if (size == 0) {
7398  goto nodata;
7399  }
7400  s->nrows = size;
7401  size = (size + 1) * asize;
7402  s->rows = xmalloc((size + 1) * sizeof (char *));
7403  if (!s->rows) {
7404  s->nrows = 0;
7405  return nomem(s);
7406  }
7407  s->rows[0] = (char *) size;
7408  s->rows += 1;
7409  memset(s->rows, 0, sizeof (char *) * size);
7410  s->rowfree = freerows;
7411  offs = 0;
7412  for (i = 1; i <= nrows; i++) {
7413  int pos = 0, roffs = (offs + 1) * s->ncols;
7414  char *ptab = rowp[i * ncols + namec];
7415  char buf[32];
7416 
7417  if (plen && ptab) {
7418  int len = strlen(ptab);
7419 
7420  if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
7421  continue;
7422  }
7423  }
7424 #if defined(_WIN32) || defined(_WIN64)
7425  s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
7426  s->rows[roffs + 1] = xstrdup("");
7427 #else
7428  s->rows[roffs + 0] = xstrdup("");
7429  s->rows[roffs + 1] = xstrdup("");
7430 #endif
7431  s->rows[roffs + 2] = xstrdup(ptab);
7432  s->rows[roffs + 3] = xstrdup(rowp[i * ncols + toc]);
7433  s->rows[roffs + 4] = xstrdup("");
7434  s->rows[roffs + 5] = xstrdup("");
7435  s->rows[roffs + 6] = xstrdup(fname);
7436  s->rows[roffs + 7] = xstrdup(rowp[i * ncols + fromc]);
7437  sscanf(rowp[i * ncols + seqc], "%d", &pos);
7438  sprintf(buf, "%d", pos + 1);
7439  s->rows[roffs + 8] = xstrdup(buf);
7440  if (onu < 0) {
7441  s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7442  } else {
7443  if (strcmp(rowp[i * ncols + onu], "SET NULL") == 0) {
7444  s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
7445  } else if (strcmp(rowp[i * ncols + onu], "SET DEFAULT") == 0) {
7446  s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_DEFAULT));
7447  } else if (strcmp(rowp[i * ncols + onu], "CASCADE") == 0) {
7448  s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
7449  } else if (strcmp(rowp[i * ncols + onu], "RESTRICT") == 0) {
7450  s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
7451  } else {
7452  s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7453  }
7454  }
7455  if (ond < 0) {
7456  s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7457  } else {
7458  if (strcmp(rowp[i * ncols + ond], "SET NULL") == 0) {
7459  s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
7460  } else if (strcmp(rowp[i * ncols + ond], "SET DEFAULT") == 0) {
7461  s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_DEFAULT));
7462  } else if (strcmp(rowp[i * ncols + ond], "CASCADE") == 0) {
7463  s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
7464  } else if (strcmp(rowp[i * ncols + ond], "RESTRICT") == 0) {
7465  s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
7466  } else {
7467  s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7468  }
7469  }
7470  s->rows[roffs + 11] = NULL;
7471  s->rows[roffs + 12] = NULL;
7472  s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
7473  offs++;
7474  }
7475  sqlite3_free_table(rowp);
7476  } else {
7477  int nnrows, nncols, plen = strlen(pname);
7478  char **rowpp;
7479 
7480  sql = "select name from sqlite_master where type='table'";
7481  dbtraceapi(d, "sqlite3_get_table", sql);
7482  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
7483  if (ret != SQLITE_OK) {
7484  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7485  errp ? errp : "unknown error", ret);
7486  if (errp) {
7487  sqlite3_free(errp);
7488  errp = NULL;
7489  }
7490  return SQL_ERROR;
7491  }
7492  if (errp) {
7493  sqlite3_free(errp);
7494  errp = NULL;
7495  }
7496  if (ncols * nrows <= 0) {
7497  goto nodata;
7498  }
7499  size = 0;
7500  for (i = 1; i <= nrows; i++) {
7501  int k;
7502 
7503  if (!rowp[i]) {
7504  continue;
7505  }
7506  rowpp = NULL;
7507  ret = SQLITE_ERROR;
7508  sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
7509  if (sql) {
7510  dbtraceapi(d, "sqlite3_get_table", sql);
7511  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7512  &nnrows, &nncols, NULL);
7513  sqlite3_free(sql);
7514  }
7515  if (ret != SQLITE_OK || nncols * nnrows <= 0) {
7516  sqlite3_free_table(rowpp);
7517  continue;
7518  }
7519  namec = findcol(rowpp, nncols, "table");
7520  seqc = findcol(rowpp, nncols, "seq");
7521  fromc = findcol(rowpp, nncols, "from");
7522  toc = findcol(rowpp, nncols, "to");
7523  if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7524  sqlite3_free_table(rowpp);
7525  continue;
7526  }
7527  for (k = 1; k <= nnrows; k++) {
7528  char *ptab = unquote(rowpp[k * nncols + namec]);
7529 
7530  if (plen && ptab) {
7531  int len = strlen(ptab);
7532 
7533  if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
7534  continue;
7535  }
7536  }
7537  size++;
7538  }
7539  sqlite3_free_table(rowpp);
7540  }
7541  if (size == 0) {
7542  goto nodata;
7543  }
7544  s->nrows = size;
7545  size = (size + 1) * asize;
7546  s->rows = xmalloc((size + 1) * sizeof (char *));
7547  if (!s->rows) {
7548  s->nrows = 0;
7549  return nomem(s);
7550  }
7551  s->rows[0] = (char *) size;
7552  s->rows += 1;
7553  memset(s->rows, 0, sizeof (char *) * size);
7554  s->rowfree = freerows;
7555  offs = 0;
7556  for (i = 1; i <= nrows; i++) {
7557  int k;
7558 
7559  if (!rowp[i]) {
7560  continue;
7561  }
7562  rowpp = NULL;
7563  ret = SQLITE_ERROR;
7564  sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
7565  if (sql) {
7566  dbtraceapi(d, "sqlite3_get_table", sql);
7567  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7568  &nnrows, &nncols, NULL);
7569  sqlite3_free(sql);
7570  }
7571  if (ret != SQLITE_OK || nncols * nnrows <= 0) {
7572  sqlite3_free_table(rowpp);
7573  continue;
7574  }
7575  namec = findcol(rowpp, nncols, "table");
7576  seqc = findcol(rowpp, nncols, "seq");
7577  fromc = findcol(rowpp, nncols, "from");
7578  toc = findcol(rowpp, nncols, "to");
7579  onu = findcol(rowpp, nncols, "on_update");
7580  ond = findcol(rowpp, nncols, "on_delete");
7581  if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7582  sqlite3_free_table(rowpp);
7583  continue;
7584  }
7585  for (k = 1; k <= nnrows; k++) {
7586  int pos = 0, roffs = (offs + 1) * s->ncols;
7587  char *ptab = unquote(rowpp[k * nncols + namec]);
7588  char buf[32];
7589 
7590  if (plen && ptab) {
7591  int len = strlen(ptab);
7592 
7593  if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
7594  continue;
7595  }
7596  }
7597 #if defined(_WIN32) || defined(_WIN64)
7598  s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
7599  s->rows[roffs + 1] = xstrdup("");
7600 #else
7601  s->rows[roffs + 0] = xstrdup("");
7602  s->rows[roffs + 1] = xstrdup("");
7603 #endif
7604  s->rows[roffs + 2] = xstrdup(ptab);
7605  s->rows[roffs + 3] = xstrdup(rowpp[k * nncols + toc]);
7606  s->rows[roffs + 4] = xstrdup("");
7607  s->rows[roffs + 5] = xstrdup("");
7608  s->rows[roffs + 6] = xstrdup(rowp[i]);
7609  s->rows[roffs + 7] = xstrdup(rowpp[k * nncols + fromc]);
7610  sscanf(rowpp[k * nncols + seqc], "%d", &pos);
7611  sprintf(buf, "%d", pos + 1);
7612  s->rows[roffs + 8] = xstrdup(buf);
7613  if (onu < 0) {
7614  s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7615  } else {
7616  if (strcmp(rowpp[k * nncols + onu], "SET NULL") == 0) {
7617  s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
7618  } else if (strcmp(rowpp[k * nncols + onu], "SET DEFAULT")
7619  == 0) {
7620  s->rows[roffs + 9] =
7621  xstrdup(stringify(SQL_SET_DEFAULT));
7622  } else if (strcmp(rowpp[k * nncols + onu], "CASCADE")
7623  == 0) {
7624  s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
7625  } else if (strcmp(rowpp[k * nncols + onu], "RESTRICT")
7626  == 0) {
7627  s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
7628  } else {
7629  s->rows[roffs + 9] =
7630  xstrdup(stringify(SQL_NO_ACTION));
7631  }
7632  }
7633  if (ond < 0) {
7634  s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7635  } else {
7636  if (strcmp(rowpp[k * nncols + ond], "SET NULL") == 0) {
7637  s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
7638  } else if (strcmp(rowpp[k * nncols + ond], "SET DEFAULT")
7639  == 0) {
7640  s->rows[roffs + 10] =
7641  xstrdup(stringify(SQL_SET_DEFAULT));
7642  } else if (strcmp(rowpp[k * nncols + ond], "CASCADE")
7643  == 0) {
7644  s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
7645  } else if (strcmp(rowpp[k * nncols + ond], "RESTRICT")
7646  == 0) {
7647  s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
7648  } else {
7649  s->rows[roffs + 10] =
7650  xstrdup(stringify(SQL_NO_ACTION));
7651  }
7652  }
7653  s->rows[roffs + 11] = NULL;
7654  s->rows[roffs + 12] = NULL;
7655  s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
7656  offs++;
7657  }
7658  sqlite3_free_table(rowpp);
7659  }
7660  sqlite3_free_table(rowp);
7661  }
7662  return SQL_SUCCESS;
7663 }
7664 
7665 #ifndef WINTERFACE
7666 
7684 SQLRETURN SQL_API
7685 SQLForeignKeys(SQLHSTMT stmt,
7686  SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7687  SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
7688  SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
7689  SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7690  SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
7691  SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
7692 {
7693 #if defined(_WIN32) || defined(_WIN64)
7694  char *pc = NULL, *ps = NULL, *pt = NULL;
7695  char *fc = NULL, *fs = NULL, *ft = NULL;
7696 #endif
7697  SQLRETURN ret;
7698 
7699  HSTMT_LOCK(stmt);
7700 #if defined(_WIN32) || defined(_WIN64)
7701  if (!((STMT *) stmt)->oemcp[0]) {
7702  ret = drvforeignkeys(stmt,
7703  PKcatalog, PKcatalogLen,
7704  PKschema, PKschemaLen, PKtable, PKtableLen,
7705  FKcatalog, FKcatalogLen,
7706  FKschema, FKschemaLen,
7707  FKtable, FKtableLen);
7708  goto done2;
7709  }
7710  if (PKcatalog) {
7711  pc = wmb_to_utf_c((char *) PKcatalog, PKcatalogLen);
7712  if (!pc) {
7713  ret = nomem((STMT *) stmt);
7714  goto done;
7715  }
7716  }
7717  if (PKschema) {
7718  ps = wmb_to_utf_c((char *) PKschema, PKschemaLen);
7719  if (!ps) {
7720  ret = nomem((STMT *) stmt);
7721  goto done;
7722  }
7723  }
7724  if (PKtable) {
7725  pt = wmb_to_utf_c((char *) PKtable, PKtableLen);
7726  if (!pt) {
7727  ret = nomem((STMT *) stmt);
7728  goto done;
7729  }
7730  }
7731  if (FKcatalog) {
7732  fc = wmb_to_utf_c((char *) FKcatalog, FKcatalogLen);
7733  if (!fc) {
7734  ret = nomem((STMT *) stmt);
7735  goto done;
7736  }
7737  }
7738  if (FKschema) {
7739  fs = wmb_to_utf_c((char *) FKschema, FKschemaLen);
7740  if (!fs) {
7741  ret = nomem((STMT *) stmt);
7742  goto done;
7743  }
7744  }
7745  if (FKtable) {
7746  ft = wmb_to_utf_c((char *) FKtable, FKtableLen);
7747  if (!ft) {
7748  ret = nomem((STMT *) stmt);
7749  goto done;
7750  }
7751  }
7752  ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
7753  (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
7754  (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
7755  (SQLCHAR *) ft, SQL_NTS);
7756 #else
7757  ret = drvforeignkeys(stmt,
7758  PKcatalog, PKcatalogLen,
7759  PKschema, PKschemaLen, PKtable, PKtableLen,
7760  FKcatalog, FKcatalogLen,
7761  FKschema, FKschemaLen,
7762  FKtable, FKtableLen);
7763 #endif
7764 #if defined(_WIN32) || defined(_WIN64)
7765 done:
7766  uc_free(ft);
7767  uc_free(fs);
7768  uc_free(fc);
7769  uc_free(pt);
7770  uc_free(ps);
7771  uc_free(pc);
7772 done2:
7773  ;
7774 #endif
7775  HSTMT_UNLOCK(stmt);
7776  return ret;
7777 }
7778 #endif
7779 
7780 #ifdef WINTERFACE
7781 
7799 SQLRETURN SQL_API
7801  SQLWCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7802  SQLWCHAR *PKschema, SQLSMALLINT PKschemaLen,
7803  SQLWCHAR *PKtable, SQLSMALLINT PKtableLen,
7804  SQLWCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7805  SQLWCHAR *FKschema, SQLSMALLINT FKschemaLen,
7806  SQLWCHAR *FKtable, SQLSMALLINT FKtableLen)
7807 {
7808  char *pc = NULL, *ps = NULL, *pt = NULL;
7809  char *fc = NULL, *fs = NULL, *ft = NULL;
7810  SQLRETURN ret;
7811 
7812  HSTMT_LOCK(stmt);
7813  if (PKcatalog) {
7814  pc = uc_to_utf_c(PKcatalog, PKcatalogLen);
7815  if (!pc) {
7816  ret = nomem((STMT *) stmt);
7817  goto done;
7818  }
7819  }
7820  if (PKschema) {
7821  ps = uc_to_utf_c(PKschema, PKschemaLen);
7822  if (!ps) {
7823  ret = nomem((STMT *) stmt);
7824  goto done;
7825  }
7826  }
7827  if (PKtable) {
7828  pt = uc_to_utf_c(PKtable, PKtableLen);
7829  if (!pt) {
7830  ret = nomem((STMT *) stmt);
7831  goto done;
7832  }
7833  }
7834  if (FKcatalog) {
7835  fc = uc_to_utf_c(FKcatalog, FKcatalogLen);
7836  if (!fc) {
7837  ret = nomem((STMT *) stmt);
7838  goto done;
7839  }
7840  }
7841  if (FKschema) {
7842  fs = uc_to_utf_c(FKschema, FKschemaLen);
7843  if (!fs) {
7844  ret = nomem((STMT *) stmt);
7845  goto done;
7846  }
7847  }
7848  if (FKtable) {
7849  ft = uc_to_utf_c(FKtable, FKtableLen);
7850  if (!ft) {
7851  ret = nomem((STMT *) stmt);
7852  goto done;
7853  }
7854  }
7855  ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
7856  (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
7857  (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
7858  (SQLCHAR *) ft, SQL_NTS);
7859 done:
7860  uc_free(ft);
7861  uc_free(fs);
7862  uc_free(fc);
7863  uc_free(pt);
7864  uc_free(ps);
7865  uc_free(pc);
7866  HSTMT_UNLOCK(stmt);
7867  return ret;
7868 }
7869 #endif
7870 
7877 static SQLRETURN
7879 {
7880  int ret = SQL_SUCCESS, rc, busy_count = 0;
7881  char *errp = NULL;
7882  DBC *d = (DBC *) s->dbc;
7883 
7884  if (!d->autocommit && !d->intrans && !d->trans_disable) {
7885 begin_again:
7886  rc = sqlite3_exec(d->sqlite, "BEGIN TRANSACTION", NULL, NULL, &errp);
7887  if (rc == SQLITE_BUSY) {
7888  if (busy_handler((void *) d, ++busy_count)) {
7889  if (errp) {
7890  sqlite3_free(errp);
7891  errp = NULL;
7892  }
7893  goto begin_again;
7894  }
7895  }
7896  dbtracerc(d, rc, errp);
7897  if (rc != SQLITE_OK) {
7898  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7899  errp ? errp : "unknown error", rc);
7900  ret = SQL_ERROR;
7901  } else {
7902  d->intrans = 1;
7903  }
7904  if (errp) {
7905  sqlite3_free(errp);
7906  errp = NULL;
7907  }
7908  }
7909  return ret;
7910 }
7911 
7920 static SQLRETURN
7921 endtran(DBC *d, SQLSMALLINT comptype, int force)
7922 {
7923  int ret, busy_count = 0;
7924  char *sql, *errp = NULL;
7925 
7926  if (!d->sqlite) {
7927  setstatd(d, -1, "not connected", (*d->ov3) ? "HY000" : "S1000");
7928  return SQL_ERROR;
7929  }
7930  if ((!force && d->autocommit) || !d->intrans) {
7931  return SQL_SUCCESS;
7932  }
7933  switch (comptype) {
7934  case SQL_COMMIT:
7935  sql = "COMMIT TRANSACTION";
7936  goto doit;
7937  case SQL_ROLLBACK:
7938  sql = "ROLLBACK TRANSACTION";
7939  doit:
7940  ret = sqlite3_exec(d->sqlite, sql, NULL, NULL, &errp);
7941  dbtracerc(d, ret, errp);
7942  if (ret == SQLITE_BUSY && busy_count < 10) {
7943  if (busy_handler((void *) d, ++busy_count)) {
7944  if (errp) {
7945  sqlite3_free(errp);
7946  errp = NULL;
7947  }
7948  goto doit;
7949  }
7950  }
7951  if (ret != SQLITE_OK) {
7952  setstatd(d, ret, "%s", (*d->ov3) ? "HY000" : "S1000",
7953  errp ? errp : "transaction failed");
7954  if (errp) {
7955  sqlite3_free(errp);
7956  errp = NULL;
7957  }
7958  return SQL_ERROR;
7959  }
7960  if (errp) {
7961  sqlite3_free(errp);
7962  errp = NULL;
7963  }
7964  d->intrans = 0;
7965  return SQL_SUCCESS;
7966  }
7967  setstatd(d, -1, "invalid completion type", (*d->ov3) ? "HY000" : "S1000");
7968  return SQL_ERROR;
7969 }
7970 
7979 static SQLRETURN
7980 drvendtran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
7981 {
7982  DBC *dbc = NULL;
7983  int fail = 0;
7984  SQLRETURN ret;
7985 #if defined(_WIN32) || defined(_WIN64)
7986  ENV *env;
7987 #endif
7988 
7989  switch (type) {
7990  case SQL_HANDLE_DBC:
7991  HDBC_LOCK((SQLHDBC) handle);
7992  if (handle == SQL_NULL_HDBC) {
7993  return SQL_INVALID_HANDLE;
7994  }
7995  dbc = (DBC *) handle;
7996  ret = endtran(dbc, comptype, 0);
7997  HDBC_UNLOCK((SQLHDBC) handle);
7998  return ret;
7999  case SQL_HANDLE_ENV:
8000  if (handle == SQL_NULL_HENV) {
8001  return SQL_INVALID_HANDLE;
8002  }
8003 #if defined(_WIN32) || defined(_WIN64)
8004  env = (ENV *) handle;
8005  if (env->magic != ENV_MAGIC) {
8006  return SQL_INVALID_HANDLE;
8007  }
8008  EnterCriticalSection(&env->cs);
8009 #endif
8010  dbc = ((ENV *) handle)->dbcs;
8011  while (dbc) {
8012  HDBC_LOCK((SQLHDBC) dbc);
8013  ret = endtran(dbc, comptype, 0);
8014  HDBC_UNLOCK((SQLHDBC) dbc);
8015  if (ret != SQL_SUCCESS) {
8016  fail++;
8017  }
8018  dbc = dbc->next;
8019  }
8020 #if defined(_WIN32) || defined(_WIN64)
8021  LeaveCriticalSection(&env->cs);
8022 #endif
8023  return fail ? SQL_ERROR : SQL_SUCCESS;
8024  }
8025  return SQL_INVALID_HANDLE;
8026 }
8027 
8036 SQLRETURN SQL_API
8037 SQLEndTran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
8038 {
8039  return drvendtran(type, handle, comptype);
8040 }
8041 
8050 SQLRETURN SQL_API
8051 SQLTransact(SQLHENV env, SQLHDBC dbc, SQLUSMALLINT type)
8052 {
8053  if (dbc != SQL_NULL_HDBC) {
8054  return drvendtran(SQL_HANDLE_DBC, (SQLHANDLE) dbc, type);
8055  }
8056  return drvendtran(SQL_HANDLE_ENV, (SQLHANDLE) env, type);
8057 }
8058 
8063 SQLRETURN SQL_API
8064 SQLCopyDesc(SQLHDESC source, SQLHDESC target)
8065 {
8066  return SQL_ERROR;
8067 }
8068 
8069 #ifndef WINTERFACE
8070 
8081 SQLRETURN SQL_API
8082 SQLNativeSql(SQLHSTMT stmt, SQLCHAR *sqlin, SQLINTEGER sqlinLen,
8083  SQLCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
8084 {
8085  int outLen = 0;
8086  SQLRETURN ret = SQL_SUCCESS;
8087 
8088  HSTMT_LOCK(stmt);
8089  if (sqlinLen == SQL_NTS) {
8090  sqlinLen = strlen((char *) sqlin);
8091  }
8092  if (sql) {
8093  if (sqlMax > 0) {
8094  strncpy((char *) sql, (char *) sqlin, sqlMax - 1);
8095  sqlin[sqlMax - 1] = '\0';
8096  outLen = min(sqlMax - 1, sqlinLen);
8097  }
8098  } else {
8099  outLen = sqlinLen;
8100  }
8101  if (sqlLen) {
8102  *sqlLen = outLen;
8103  }
8104  if (sql && outLen < sqlinLen) {
8105  setstat((STMT *) stmt, -1, "data right truncated", "01004");
8106  ret = SQL_SUCCESS_WITH_INFO;
8107  }
8108  HSTMT_UNLOCK(stmt);
8109  return ret;
8110 }
8111 #endif
8112 
8113 #ifdef WINTERFACE
8114 
8125 SQLRETURN SQL_API
8126 SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen,
8127  SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
8128 {
8129  int outLen = 0;
8130  SQLRETURN ret = SQL_SUCCESS;
8131 
8132  HSTMT_LOCK(stmt);
8133  if (sqlinLen == SQL_NTS) {
8134  sqlinLen = uc_strlen(sqlin);
8135  }
8136  if (sql) {
8137  if (sqlMax > 0) {
8138  uc_strncpy(sql, sqlin, sqlMax - 1);
8139  sqlin[sqlMax - 1] = 0;
8140  outLen = min(sqlMax - 1, sqlinLen);
8141  }
8142  } else {
8143  outLen = sqlinLen;
8144  }
8145  if (sqlLen) {
8146  *sqlLen = outLen;
8147  }
8148  if (sql && outLen < sqlinLen) {
8149  setstat((STMT *) stmt, -1, "data right truncated", "01004");
8150  ret = SQL_SUCCESS_WITH_INFO;
8151  }
8152  HSTMT_UNLOCK(stmt);
8153  return ret;
8154 }
8155 #endif
8156 
8161 static COL procSpec2[] = {
8162  { "SYSTEM", "PROCEDURE", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
8163  { "SYSTEM", "PROCEDURE", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
8164  { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8165  { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
8166  { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
8167  { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
8168  { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
8169  { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
8170 };
8171 
8172 static COL procSpec3[] = {
8173  { "SYSTEM", "PROCEDURE", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
8174  { "SYSTEM", "PROCEDURE", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
8175  { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8176  { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
8177  { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
8178  { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
8179  { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
8180  { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
8181 };
8182 
8183 #ifndef WINTERFACE
8184 
8196 SQLRETURN SQL_API
8197 SQLProcedures(SQLHSTMT stmt,
8198  SQLCHAR *catalog, SQLSMALLINT catalogLen,
8199  SQLCHAR *schema, SQLSMALLINT schemaLen,
8200  SQLCHAR *proc, SQLSMALLINT procLen)
8201 {
8202  SQLRETURN ret;
8203 
8204  HSTMT_LOCK(stmt);
8206  procSpec3, array_size(procSpec3), NULL);
8207  HSTMT_UNLOCK(stmt);
8208  return ret;
8209 }
8210 #endif
8211 
8212 #ifdef WINTERFACE
8213 
8225 SQLRETURN SQL_API
8227  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
8228  SQLWCHAR *schema, SQLSMALLINT schemaLen,
8229  SQLWCHAR *proc, SQLSMALLINT procLen)
8230 {
8231  SQLRETURN ret;
8232 
8233  HSTMT_LOCK(stmt);
8235  procSpec3, array_size(procSpec3), NULL);
8236  HSTMT_UNLOCK(stmt);
8237  return ret;
8238 }
8239 #endif
8240 
8245 static COL procColSpec2[] = {
8246  { "SYSTEM", "PROCCOL", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
8247  { "SYSTEM", "PROCCOL", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
8248  { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8249  { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
8250  { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
8251  { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
8252  { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
8253  { "SYSTEM", "PROCCOL", "PRECISION", SQL_INTEGER, 10 },
8254  { "SYSTEM", "PROCCOL", "LENGTH", SQL_INTEGER, 10 },
8255  { "SYSTEM", "PROCCOL", "SCALE", SQL_SMALLINT, 5 },
8256  { "SYSTEM", "PROCCOL", "RADIX", SQL_SMALLINT, 5 },
8257  { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
8258  { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
8259  { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
8260  { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
8261  { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
8262  { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
8263  { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
8264  { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
8265 };
8266 
8267 static COL procColSpec3[] = {
8268  { "SYSTEM", "PROCCOL", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
8269  { "SYSTEM", "PROCCOL", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
8270  { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8271  { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
8272  { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
8273  { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
8274  { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
8275  { "SYSTEM", "PROCCOL", "COLUMN_SIZE", SQL_INTEGER, 10 },
8276  { "SYSTEM", "PROCCOL", "BUFFER_LENGTH", SQL_INTEGER, 10 },
8277  { "SYSTEM", "PROCCOL", "DECIMAL_DIGITS", SQL_SMALLINT, 5 },
8278  { "SYSTEM", "PROCCOL", "NUM_PREC_RADIX", SQL_SMALLINT, 5 },
8279  { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
8280  { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
8281  { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
8282  { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
8283  { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
8284  { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
8285  { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
8286  { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
8287 };
8288 
8289 #ifndef WINTERFACE
8290 
8304 SQLRETURN SQL_API
8305 SQLProcedureColumns(SQLHSTMT stmt,
8306  SQLCHAR *catalog, SQLSMALLINT catalogLen,
8307  SQLCHAR *schema, SQLSMALLINT schemaLen,
8308  SQLCHAR *proc, SQLSMALLINT procLen,
8309  SQLCHAR *column, SQLSMALLINT columnLen)
8310 {
8311  SQLRETURN ret;
8312 
8313  HSTMT_LOCK(stmt);
8316  HSTMT_UNLOCK(stmt);
8317  return ret;
8318 }
8319 #endif
8320 
8321 #ifdef WINTERFACE
8322 
8337 SQLRETURN SQL_API
8339  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
8340  SQLWCHAR *schema, SQLSMALLINT schemaLen,
8341  SQLWCHAR *proc, SQLSMALLINT procLen,
8342  SQLWCHAR *column, SQLSMALLINT columnLen)
8343 {
8344  SQLRETURN ret;
8345 
8346  HSTMT_LOCK(stmt);
8349  HSTMT_UNLOCK(stmt);
8350  return ret;
8351 }
8352 #endif
8353 
8364 SQLRETURN SQL_API
8365 SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val,
8366  SQLINTEGER len, SQLINTEGER *lenp)
8367 {
8368  ENV *e;
8369  SQLRETURN ret = SQL_ERROR;
8370 
8371  if (env == SQL_NULL_HENV) {
8372  return SQL_INVALID_HANDLE;
8373  }
8374  e = (ENV *) env;
8375  if (!e || e->magic != ENV_MAGIC) {
8376  return SQL_INVALID_HANDLE;
8377  }
8378 #if defined(_WIN32) || defined(_WIN64)
8379  EnterCriticalSection(&e->cs);
8380 #endif
8381  switch (attr) {
8382  case SQL_ATTR_CONNECTION_POOLING:
8383  if (val) {
8384  *((SQLINTEGER *) val) = e->pool ?
8385  SQL_CP_ONE_PER_DRIVER : SQL_CP_OFF;
8386  }
8387  if (lenp) {
8388  *lenp = sizeof (SQLINTEGER);
8389  }
8390  ret = SQL_SUCCESS;
8391  break;
8392  case SQL_ATTR_CP_MATCH:
8393  *((SQLINTEGER *) val) = SQL_CP_RELAXED_MATCH;
8394  if (lenp) {
8395  *lenp = sizeof (SQLINTEGER);
8396  }
8397  ret = SQL_SUCCESS;
8398  break;
8399  case SQL_ATTR_OUTPUT_NTS:
8400  if (val) {
8401  *((SQLINTEGER *) val) = SQL_TRUE;
8402  }
8403  if (lenp) {
8404  *lenp = sizeof (SQLINTEGER);
8405  }
8406  ret = SQL_SUCCESS;
8407  break;
8408  case SQL_ATTR_ODBC_VERSION:
8409  if (val) {
8410  *((SQLINTEGER *) val) = e->ov3 ? SQL_OV_ODBC3 : SQL_OV_ODBC2;
8411  }
8412  if (lenp) {
8413  *lenp = sizeof (SQLINTEGER);
8414  }
8415  ret = SQL_SUCCESS;
8416  break;
8417  }
8418 #if defined(_WIN32) || defined(_WIN64)
8419  LeaveCriticalSection(&e->cs);
8420 #endif
8421  return ret;
8422 }
8423 
8433 SQLRETURN SQL_API
8434 SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
8435 {
8436  ENV *e;
8437  SQLRETURN ret = SQL_ERROR;
8438 
8439  if (env == SQL_NULL_HENV) {
8440  return SQL_INVALID_HANDLE;
8441  }
8442  e = (ENV *) env;
8443  if (!e || e->magic != ENV_MAGIC) {
8444  return SQL_INVALID_HANDLE;
8445  }
8446 #if defined(_WIN32) || defined(_WIN64)
8447  EnterCriticalSection(&e->cs);
8448 #endif
8449  switch (attr) {
8450  case SQL_ATTR_CONNECTION_POOLING:
8451  if (val == (SQLPOINTER) SQL_CP_ONE_PER_DRIVER) {
8452  e->pool = 1;
8453  ret = SQL_SUCCESS;
8454  } else if (val == (SQLPOINTER) SQL_CP_OFF) {
8455  e->pool = 0;
8456  ret = SQL_SUCCESS;
8457  }
8458  break;
8459  case SQL_ATTR_CP_MATCH:
8460  ret = SQL_SUCCESS;
8461  break;
8462  case SQL_ATTR_OUTPUT_NTS:
8463  if (val == (SQLPOINTER) SQL_TRUE) {
8464  ret = SQL_SUCCESS;
8465  }
8466  break;
8467  case SQL_ATTR_ODBC_VERSION:
8468  if (!val) {
8469  break;
8470  }
8471  if (val == (SQLPOINTER) SQL_OV_ODBC2) {
8472  e->ov3 = 0;
8473  ret = SQL_SUCCESS;
8474  } else if (val == (SQLPOINTER) SQL_OV_ODBC3) {
8475  e->ov3 = 1;
8476  ret = SQL_SUCCESS;
8477  }
8478  break;
8479  }
8480 #if defined(_WIN32) || defined(_WIN64)
8481  LeaveCriticalSection(&e->cs);
8482 #endif
8483  return ret;
8484 }
8485 
8499 static SQLRETURN
8500 drvgetdiagrec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8501  SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
8502  SQLSMALLINT buflen, SQLSMALLINT *msglen)
8503 {
8504  DBC *d = NULL;
8505  STMT *s = NULL;
8506  int len, naterr;
8507  char *logmsg, *sqlst;
8508  SQLRETURN ret = SQL_ERROR;
8509 
8510  if (handle == SQL_NULL_HANDLE) {
8511  return SQL_INVALID_HANDLE;
8512  }
8513  if (sqlstate) {
8514  sqlstate[0] = '\0';
8515  }
8516  if (msg && buflen > 0) {
8517  msg[0] = '\0';
8518  }
8519  if (msglen) {
8520  *msglen = 0;
8521  }
8522  if (nativeerr) {
8523  *nativeerr = 0;
8524  }
8525  switch (htype) {
8526  case SQL_HANDLE_ENV:
8527  case SQL_HANDLE_DESC:
8528  return SQL_NO_DATA;
8529  case SQL_HANDLE_DBC:
8530  HDBC_LOCK((SQLHDBC) handle);
8531  d = (DBC *) handle;
8532  logmsg = (char *) d->logmsg;
8533  sqlst = d->sqlstate;
8534  naterr = d->naterr;
8535  break;
8536  case SQL_HANDLE_STMT:
8537  HSTMT_LOCK((SQLHSTMT) handle);
8538  s = (STMT *) handle;
8539  logmsg = (char *) s->logmsg;
8540  sqlst = s->sqlstate;
8541  naterr = s->naterr;
8542  break;
8543  default:
8544  return SQL_INVALID_HANDLE;
8545  }
8546  if (buflen < 0) {
8547  goto done;
8548  }
8549  if (recno > 1) {
8550  ret = SQL_NO_DATA;
8551  goto done;
8552  }
8553  len = strlen(logmsg);
8554  if (len == 0) {
8555  ret = SQL_NO_DATA;
8556  goto done;
8557  }
8558  if (nativeerr) {
8559  *nativeerr = naterr;
8560  }
8561  if (sqlstate) {
8562  strcpy((char *) sqlstate, sqlst);
8563  }
8564  if (msglen) {
8565  *msglen = len;
8566  }
8567  if (len >= buflen) {
8568  if (msg && buflen > 0) {
8569  strncpy((char *) msg, logmsg, buflen);
8570  msg[buflen - 1] = '\0';
8571  logmsg[0] = '\0';
8572  }
8573  } else if (msg) {
8574  strcpy((char *) msg, logmsg);
8575  logmsg[0] = '\0';
8576  }
8577  ret = SQL_SUCCESS;
8578 done:
8579  switch (htype) {
8580  case SQL_HANDLE_DBC:
8581  HDBC_UNLOCK((SQLHDBC) handle);
8582  break;
8583  case SQL_HANDLE_STMT:
8584  HSTMT_UNLOCK((SQLHSTMT) handle);
8585  break;
8586  }
8587  return ret;
8588 }
8589 
8590 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
8591 
8604 SQLRETURN SQL_API
8605 SQLGetDiagRec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8606  SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
8607  SQLSMALLINT buflen, SQLSMALLINT *msglen)
8608 {
8609  return drvgetdiagrec(htype, handle, recno, sqlstate,
8610  nativeerr, msg, buflen, msglen);
8611 }
8612 #endif
8613 
8614 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
8615 #ifdef WINTERFACE
8616 
8630 SQLRETURN SQL_API
8631 SQLGetDiagRecW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8632  SQLWCHAR *sqlstate, SQLINTEGER *nativeerr, SQLWCHAR *msg,
8633  SQLSMALLINT buflen, SQLSMALLINT *msglen)
8634 {
8635  char state[16];
8636  SQLSMALLINT len;
8637  SQLRETURN ret;
8638 
8639  ret = drvgetdiagrec(htype, handle, recno, (SQLCHAR *) state,
8640  nativeerr, (SQLCHAR *) msg, buflen, &len);
8641  if (ret == SQL_SUCCESS) {
8642  if (sqlstate) {
8643  uc_from_utf_buf((SQLCHAR *) state, -1, sqlstate,
8644  6 * sizeof (SQLWCHAR));
8645  }
8646  if (msg) {
8647  if (len > 0) {
8648  SQLWCHAR *m = NULL;
8649 
8650  m = uc_from_utf((unsigned char *) msg, len);
8651  if (m) {
8652  if (buflen) {
8653  buflen /= sizeof (SQLWCHAR);
8654  uc_strncpy(msg, m, buflen);
8655  m[len] = 0;
8656  len = min(buflen, uc_strlen(m));
8657  } else {
8658  len = uc_strlen(m);
8659  }
8660  uc_free(m);
8661  } else {
8662  len = 0;
8663  }
8664  }
8665  if (len <= 0) {
8666  len = 0;
8667  if (buflen > 0) {
8668  msg[0] = 0;
8669  }
8670  }
8671  } else {
8672  /* estimated length !!! */
8673  len *= sizeof (SQLWCHAR);
8674  }
8675  if (msglen) {
8676  *msglen = len;
8677  }
8678  } else if (ret == SQL_NO_DATA) {
8679  if (sqlstate) {
8680  sqlstate[0] = 0;
8681  }
8682  if (msg) {
8683  if (buflen > 0) {
8684  msg[0] = 0;
8685  }
8686  }
8687  if (msglen) {
8688  *msglen = 0;
8689  }
8690  }
8691  return ret;
8692 }
8693 #endif
8694 #endif
8695 
8708 static SQLRETURN
8709 drvgetdiagfield(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8710  SQLSMALLINT id, SQLPOINTER info,
8711  SQLSMALLINT buflen, SQLSMALLINT *stringlen)
8712 {
8713  DBC *d = NULL;
8714  STMT *s = NULL;
8715  int len, naterr, strbuf = 1;
8716  char *logmsg, *sqlst, *clrmsg = NULL;
8717  SQLRETURN ret = SQL_ERROR;
8718 
8719  if (handle == SQL_NULL_HANDLE) {
8720  return SQL_INVALID_HANDLE;
8721  }
8722  if (stringlen) {
8723  *stringlen = 0;
8724  }
8725  switch (htype) {
8726  case SQL_HANDLE_ENV:
8727  case SQL_HANDLE_DESC:
8728  return SQL_NO_DATA;
8729  case SQL_HANDLE_DBC:
8730  HDBC_LOCK((SQLHDBC) handle);
8731  d = (DBC *) handle;
8732  logmsg = (char *) d->logmsg;
8733  sqlst = d->sqlstate;
8734  naterr = d->naterr;
8735  break;
8736  case SQL_HANDLE_STMT:
8737  HSTMT_LOCK((SQLHSTMT) handle);
8738  s = (STMT *) handle;
8739  d = (DBC *) s->dbc;
8740  logmsg = (char *) s->logmsg;
8741  sqlst = s->sqlstate;
8742  naterr = s->naterr;
8743  break;
8744  default:
8745  return SQL_INVALID_HANDLE;
8746  }
8747  if (buflen < 0) {
8748  switch (buflen) {
8749  case SQL_IS_POINTER:
8750  case SQL_IS_UINTEGER:
8751  case SQL_IS_INTEGER:
8752  case SQL_IS_USMALLINT:
8753  case SQL_IS_SMALLINT:
8754  strbuf = 0;
8755  break;
8756  default:
8757  ret = SQL_ERROR;
8758  goto done;
8759  }
8760  }
8761  if (recno > 1) {
8762  ret = SQL_NO_DATA;
8763  goto done;
8764  }
8765  switch (id) {
8766  case SQL_DIAG_CLASS_ORIGIN:
8767  logmsg = "ISO 9075";
8768  if (sqlst[0] == 'I' && sqlst[1] == 'M') {
8769  logmsg = "ODBC 3.0";
8770  }
8771  break;
8772  case SQL_DIAG_SUBCLASS_ORIGIN:
8773  logmsg = "ISO 9075";
8774  if (sqlst[0] == 'I' && sqlst[1] == 'M') {
8775  logmsg = "ODBC 3.0";
8776  } else if (sqlst[0] == 'H' && sqlst[1] == 'Y') {
8777  logmsg = "ODBC 3.0";
8778  } else if (sqlst[0] == '2' || sqlst[0] == '0' || sqlst[0] == '4') {
8779  logmsg = "ODBC 3.0";
8780  }
8781  break;
8782  case SQL_DIAG_CONNECTION_NAME:
8783  case SQL_DIAG_SERVER_NAME:
8784  logmsg = d->dsn ? d->dsn : "No DSN";
8785  break;
8786  case SQL_DIAG_SQLSTATE:
8787  logmsg = sqlst;
8788  break;
8789  case SQL_DIAG_MESSAGE_TEXT:
8790  if (info) {
8791  clrmsg = logmsg;
8792  }
8793  break;
8794  case SQL_DIAG_NUMBER:
8795  naterr = 1;
8796  /* fall through */
8797  case SQL_DIAG_NATIVE:
8798  len = strlen(logmsg);
8799  if (len == 0) {
8800  ret = SQL_NO_DATA;
8801  goto done;
8802  }
8803  if (info) {
8804  *((SQLINTEGER *) info) = naterr;
8805  }
8806  ret = SQL_SUCCESS;
8807  goto done;
8808  case SQL_DIAG_DYNAMIC_FUNCTION:
8809  logmsg = "";
8810  break;
8811  case SQL_DIAG_CURSOR_ROW_COUNT:
8812  if (htype == SQL_HANDLE_STMT) {
8813  SQLULEN count;
8814 
8815  count = (s->isselect == 1 || s->isselect == -1) ? s->nrows : 0;
8816  *((SQLULEN *) info) = count;
8817  ret = SQL_SUCCESS;
8818  }
8819  goto done;
8820  case SQL_DIAG_ROW_COUNT:
8821  if (htype == SQL_HANDLE_STMT) {
8822  SQLULEN count;
8823 
8824  count = s->isselect ? 0 : s->nrows;
8825  *((SQLULEN *) info) = count;
8826  ret = SQL_SUCCESS;
8827  }
8828  goto done;
8829  default:
8830  goto done;
8831  }
8832  if (info && buflen > 0) {
8833  ((char *) info)[0] = '\0';
8834  }
8835  len = strlen(logmsg);
8836  if (len == 0) {
8837  ret = SQL_NO_DATA;
8838  goto done;
8839  }
8840  if (stringlen) {
8841  *stringlen = len;
8842  }
8843  if (strbuf) {
8844  if (len >= buflen) {
8845  if (info && buflen > 0) {
8846  if (stringlen) {
8847  *stringlen = buflen - 1;
8848  }
8849  strncpy((char *) info, logmsg, buflen);
8850  ((char *) info)[buflen - 1] = '\0';
8851  }
8852  } else if (info) {
8853  strcpy((char *) info, logmsg);
8854  }
8855  }
8856  if (clrmsg) {
8857  *clrmsg = '\0';
8858  }
8859  ret = SQL_SUCCESS;
8860 done:
8861  switch (htype) {
8862  case SQL_HANDLE_DBC:
8863  HDBC_UNLOCK((SQLHDBC) handle);
8864  break;
8865  case SQL_HANDLE_STMT:
8866  HSTMT_UNLOCK((SQLHSTMT) handle);
8867  break;
8868  }
8869  return ret;
8870 }
8871 
8872 #ifndef WINTERFACE
8873 
8885 SQLRETURN SQL_API
8886 SQLGetDiagField(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8887  SQLSMALLINT id, SQLPOINTER info,
8888  SQLSMALLINT buflen, SQLSMALLINT *stringlen)
8889 {
8890  return drvgetdiagfield(htype, handle, recno, id, info, buflen, stringlen);
8891 }
8892 #endif
8893 
8894 #ifdef WINTERFACE
8895 
8907 SQLRETURN SQL_API
8908 SQLGetDiagFieldW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8909  SQLSMALLINT id, SQLPOINTER info,
8910  SQLSMALLINT buflen, SQLSMALLINT *stringlen)
8911 {
8912  SQLSMALLINT len;
8913  SQLRETURN ret;
8914 
8915  ret = drvgetdiagfield(htype, handle, recno, id, info, buflen, &len);
8916  if (ret == SQL_SUCCESS) {
8917  if (info) {
8918  switch (id) {
8919  case SQL_DIAG_CLASS_ORIGIN:
8920  case SQL_DIAG_SUBCLASS_ORIGIN:
8921  case SQL_DIAG_CONNECTION_NAME:
8922  case SQL_DIAG_SERVER_NAME:
8923  case SQL_DIAG_SQLSTATE:
8924  case SQL_DIAG_MESSAGE_TEXT:
8925  case SQL_DIAG_DYNAMIC_FUNCTION:
8926  if (len > 0) {
8927  SQLWCHAR *m = NULL;
8928 
8929  m = uc_from_utf((unsigned char *) info, len);
8930  if (m) {
8931  if (buflen) {
8932  buflen /= sizeof (SQLWCHAR);
8933  uc_strncpy(info, m, buflen);
8934  m[len] = 0;
8935  len = min(buflen, uc_strlen(m));
8936  } else {
8937  len = uc_strlen(m);
8938  }
8939  uc_free(m);
8940  len *= sizeof (SQLWCHAR);
8941  } else {
8942  len = 0;
8943  }
8944  }
8945  if (len <= 0) {
8946  len = 0;
8947  if (buflen > 0) {
8948  ((SQLWCHAR *) info)[0] = 0;
8949  }
8950  }
8951  }
8952  } else {
8953  switch (id) {
8954  case SQL_DIAG_CLASS_ORIGIN:
8955  case SQL_DIAG_SUBCLASS_ORIGIN:
8956  case SQL_DIAG_CONNECTION_NAME:
8957  case SQL_DIAG_SERVER_NAME:
8958  case SQL_DIAG_SQLSTATE:
8959  case SQL_DIAG_MESSAGE_TEXT:
8960  case SQL_DIAG_DYNAMIC_FUNCTION:
8961  len *= sizeof (SQLWCHAR);
8962  break;
8963  }
8964  }
8965  if (stringlen) {
8966  *stringlen = len;
8967  }
8968  }
8969  return ret;
8970 }
8971 #endif
8972 
8983 static SQLRETURN
8984 drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
8985  SQLINTEGER bufmax, SQLINTEGER *buflen)
8986 {
8987  STMT *s = (STMT *) stmt;
8988  SQLULEN *uval = (SQLULEN *) val;
8989  SQLINTEGER dummy;
8990  char dummybuf[16];
8991 
8992  if (!buflen) {
8993  buflen = &dummy;
8994  }
8995  if (!uval) {
8996  uval = (SQLPOINTER) dummybuf;
8997  }
8998  switch (attr) {
8999  case SQL_QUERY_TIMEOUT:
9000  *uval = 0;
9001  *buflen = sizeof (SQLULEN);
9002  return SQL_SUCCESS;
9003  case SQL_ATTR_CURSOR_TYPE:
9004  *uval = s->curtype;
9005  *buflen = sizeof (SQLULEN);
9006  return SQL_SUCCESS;
9007  case SQL_ATTR_CURSOR_SCROLLABLE:
9008  *uval = (s->curtype != SQL_CURSOR_FORWARD_ONLY) ?
9009  SQL_SCROLLABLE : SQL_NONSCROLLABLE;
9010  *buflen = sizeof (SQLULEN);
9011  return SQL_SUCCESS;
9012 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
9013  case SQL_ATTR_CURSOR_SENSITIVITY:
9014  *uval = SQL_UNSPECIFIED;
9015  *buflen = sizeof (SQLULEN);
9016  return SQL_SUCCESS;
9017 #endif
9018  case SQL_ATTR_ROW_NUMBER:
9019  if (s->s3stmt) {
9020  *uval = (s->s3stmt_rownum < 0) ?
9021  SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
9022  } else {
9023  *uval = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
9024  }
9025  *buflen = sizeof (SQLULEN);
9026  return SQL_SUCCESS;
9027  case SQL_ATTR_ASYNC_ENABLE:
9028  *uval = SQL_ASYNC_ENABLE_OFF;
9029  *buflen = sizeof (SQLULEN);
9030  return SQL_SUCCESS;
9031  case SQL_CONCURRENCY:
9032  *uval = SQL_CONCUR_LOCK;
9033  *buflen = sizeof (SQLULEN);
9034  return SQL_SUCCESS;
9035  case SQL_ATTR_RETRIEVE_DATA:
9036  *uval = s->retr_data;
9037  *buflen = sizeof (SQLULEN);
9038  return SQL_SUCCESS;
9039  case SQL_ROWSET_SIZE:
9040  case SQL_ATTR_ROW_ARRAY_SIZE:
9041  *uval = s->rowset_size;
9042  *buflen = sizeof (SQLULEN);
9043  return SQL_SUCCESS;
9044  /* Needed for some driver managers, but dummies for now */
9045  case SQL_ATTR_IMP_ROW_DESC:
9046  case SQL_ATTR_APP_ROW_DESC:
9047  case SQL_ATTR_IMP_PARAM_DESC:
9048  case SQL_ATTR_APP_PARAM_DESC:
9049  *((SQLHDESC *) uval) = (SQLHDESC) DEAD_MAGIC;
9050  *buflen = sizeof (SQLHDESC);
9051  return SQL_SUCCESS;
9052  case SQL_ATTR_ROW_STATUS_PTR:
9053  *((SQLUSMALLINT **) uval) = s->row_status;
9054  *buflen = sizeof (SQLUSMALLINT *);
9055  return SQL_SUCCESS;
9056  case SQL_ATTR_ROWS_FETCHED_PTR:
9057  *((SQLULEN **) uval) = s->row_count;
9058  *buflen = sizeof (SQLULEN *);
9059  return SQL_SUCCESS;
9060  case SQL_ATTR_USE_BOOKMARKS: {
9061  STMT *s = (STMT *) stmt;
9062 
9063  *(SQLUINTEGER *) uval = s->bkmrk;
9064  *buflen = sizeof (SQLUINTEGER);
9065  return SQL_SUCCESS;
9066  }
9067  case SQL_ATTR_FETCH_BOOKMARK_PTR:
9068  *(SQLPOINTER *) uval = s->bkmrkptr;
9069  *buflen = sizeof (SQLPOINTER);
9070  return SQL_SUCCESS;
9071  case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
9072  *((SQLULEN **) uval) = s->parm_bind_offs;
9073  *buflen = sizeof (SQLULEN *);
9074  return SQL_SUCCESS;
9075  case SQL_ATTR_PARAM_BIND_TYPE:
9076  *((SQLULEN *) uval) = s->parm_bind_type;
9077  *buflen = sizeof (SQLULEN);
9078  return SQL_SUCCESS;
9079  case SQL_ATTR_PARAM_OPERATION_PTR:
9080  *((SQLUSMALLINT **) uval) = s->parm_oper;
9081  *buflen = sizeof (SQLUSMALLINT *);
9082  return SQL_SUCCESS;
9083  case SQL_ATTR_PARAM_STATUS_PTR:
9084  *((SQLUSMALLINT **) uval) = s->parm_status;
9085  *buflen = sizeof (SQLUSMALLINT *);
9086  return SQL_SUCCESS;
9087  case SQL_ATTR_PARAMS_PROCESSED_PTR:
9088  *((SQLULEN **) uval) = s->parm_proc;
9089  *buflen = sizeof (SQLULEN *);
9090  return SQL_SUCCESS;
9091  case SQL_ATTR_PARAMSET_SIZE:
9092  *((SQLULEN *) uval) = s->paramset_size;
9093  *buflen = sizeof (SQLULEN);
9094  return SQL_SUCCESS;
9095  case SQL_ATTR_ROW_BIND_TYPE:
9096  *(SQLULEN *) uval = s->bind_type;
9097  *buflen = sizeof (SQLULEN);
9098  return SQL_SUCCESS;
9099  case SQL_ATTR_ROW_BIND_OFFSET_PTR:
9100  *((SQLULEN **) uval) = s->bind_offs;
9101  *buflen = sizeof (SQLULEN *);
9102  return SQL_SUCCESS;
9103  case SQL_ATTR_MAX_ROWS:
9104  *((SQLULEN *) uval) = s->max_rows;
9105  *buflen = sizeof (SQLULEN);
9106  return SQL_SUCCESS;
9107  case SQL_ATTR_MAX_LENGTH:
9108  *((SQLULEN *) uval) = 1000000000;
9109  *buflen = sizeof (SQLULEN);
9110  return SQL_SUCCESS;
9111 #ifdef SQL_ATTR_METADATA_ID
9112  case SQL_ATTR_METADATA_ID:
9113  *((SQLULEN *) uval) = SQL_FALSE;
9114  *buflen = sizeof (SQLULEN);
9115  return SQL_SUCCESS;
9116 #endif
9117  }
9118  return drvunimplstmt(stmt);
9119 }
9120 
9121 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
9122 
9132 SQLRETURN SQL_API
9133 SQLGetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9134  SQLINTEGER bufmax, SQLINTEGER *buflen)
9135 {
9136  SQLRETURN ret;
9137 
9138  HSTMT_LOCK(stmt);
9139  ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
9140  HSTMT_UNLOCK(stmt);
9141  return ret;
9142 }
9143 #endif
9144 
9145 #ifdef WINTERFACE
9146 
9156 SQLRETURN SQL_API
9157 SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9158  SQLINTEGER bufmax, SQLINTEGER *buflen)
9159 {
9160  SQLRETURN ret;
9161 
9162  HSTMT_LOCK(stmt);
9163  ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
9164  HSTMT_UNLOCK(stmt);
9165  return ret;
9166 }
9167 #endif
9168 
9178 static SQLRETURN
9179 drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9180  SQLINTEGER buflen)
9181 {
9182  STMT *s = (STMT *) stmt;
9183 #if defined(SQL_BIGINT) && defined(__WORDSIZE) && (__WORDSIZE == 64)
9184  SQLBIGINT uval;
9185 
9186  uval = (SQLBIGINT) val;
9187 #else
9188  SQLULEN uval;
9189 
9190  uval = (SQLULEN) val;
9191 #endif
9192  switch (attr) {
9193  case SQL_ATTR_CURSOR_TYPE:
9194  if (val == (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY) {
9195  s->curtype = SQL_CURSOR_FORWARD_ONLY;
9196  } else {
9197  s->curtype = SQL_CURSOR_STATIC;
9198  }
9199  if (val != (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY &&
9200  val != (SQLPOINTER) SQL_CURSOR_STATIC) {
9201  goto e01s02;
9202  }
9203  return SQL_SUCCESS;
9204  case SQL_ATTR_CURSOR_SCROLLABLE:
9205  if (val == (SQLPOINTER) SQL_NONSCROLLABLE) {
9206  s->curtype = SQL_CURSOR_FORWARD_ONLY;
9207  } else {
9208  s->curtype = SQL_CURSOR_STATIC;
9209  }
9210  return SQL_SUCCESS;
9211  case SQL_ATTR_ASYNC_ENABLE:
9212  if (val != (SQLPOINTER) SQL_ASYNC_ENABLE_OFF) {
9213  e01s02:
9214  setstat(s, -1, "option value changed", "01S02");
9215  return SQL_SUCCESS_WITH_INFO;
9216  }
9217  return SQL_SUCCESS;
9218  case SQL_CONCURRENCY:
9219  if (val != (SQLPOINTER) SQL_CONCUR_LOCK) {
9220  goto e01s02;
9221  }
9222  return SQL_SUCCESS;
9223 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
9224  case SQL_ATTR_CURSOR_SENSITIVITY:
9225  if (val != (SQLPOINTER) SQL_UNSPECIFIED) {
9226  goto e01s02;
9227  }
9228  return SQL_SUCCESS;
9229 #endif
9230  case SQL_ATTR_QUERY_TIMEOUT:
9231  return SQL_SUCCESS;
9232  case SQL_ATTR_RETRIEVE_DATA:
9233  if (val != (SQLPOINTER) SQL_RD_ON &&
9234  val != (SQLPOINTER) SQL_RD_OFF) {
9235  goto e01s02;
9236  }
9237  s->retr_data = uval;
9238  return SQL_SUCCESS;
9239  case SQL_ROWSET_SIZE:
9240  case SQL_ATTR_ROW_ARRAY_SIZE:
9241  if (uval < 1) {
9242  setstat(s, -1, "invalid rowset size", "HY000");
9243  return SQL_ERROR;
9244  } else {
9245  SQLUSMALLINT *rst = &s->row_status1;
9246 
9247  if (uval > 1) {
9248  rst = xmalloc(sizeof (SQLUSMALLINT) * uval);
9249  if (!rst) {
9250  return nomem(s);
9251  }
9252  }
9253  if (s->row_status0 != &s->row_status1) {
9254  freep(&s->row_status0);
9255  }
9256  s->row_status0 = rst;
9257  s->rowset_size = uval;
9258  }
9259  return SQL_SUCCESS;
9260  case SQL_ATTR_ROW_STATUS_PTR:
9261  s->row_status = (SQLUSMALLINT *) val;
9262  return SQL_SUCCESS;
9263  case SQL_ATTR_ROWS_FETCHED_PTR:
9264  s->row_count = (SQLULEN *) val;
9265  return SQL_SUCCESS;
9266  case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
9267  s->parm_bind_offs = (SQLULEN *) val;
9268  return SQL_SUCCESS;
9269  case SQL_ATTR_PARAM_BIND_TYPE:
9270  s->parm_bind_type = uval;
9271  return SQL_SUCCESS;
9272  case SQL_ATTR_PARAM_OPERATION_PTR:
9273  s->parm_oper = (SQLUSMALLINT *) val;
9274  return SQL_SUCCESS;
9275  case SQL_ATTR_PARAM_STATUS_PTR:
9276  s->parm_status = (SQLUSMALLINT *) val;
9277  return SQL_SUCCESS;
9278  case SQL_ATTR_PARAMS_PROCESSED_PTR:
9279  s->parm_proc = (SQLULEN *) val;
9280  return SQL_SUCCESS;
9281  case SQL_ATTR_PARAMSET_SIZE:
9282  if (uval < 1) {
9283  goto e01s02;
9284  }
9285  s->paramset_size = uval;
9286  s->paramset_count = 0;
9287  return SQL_SUCCESS;
9288  case SQL_ATTR_ROW_BIND_TYPE:
9289  s->bind_type = uval;
9290  return SQL_SUCCESS;
9291  case SQL_ATTR_ROW_BIND_OFFSET_PTR:
9292  s->bind_offs = (SQLULEN *) val;
9293  return SQL_SUCCESS;
9294  case SQL_ATTR_USE_BOOKMARKS:
9295  if (val != (SQLPOINTER) SQL_UB_OFF &&
9296  val != (SQLPOINTER) SQL_UB_ON &&
9297  val != (SQLPOINTER) SQL_UB_VARIABLE) {
9298  goto e01s02;
9299  }
9300  if (*s->ov3 && val == (SQLPOINTER) SQL_UB_VARIABLE) {
9301  s->bkmrk = SQL_UB_VARIABLE;
9302  return SQL_SUCCESS;
9303  }
9304  if (val == (SQLPOINTER) SQL_UB_VARIABLE) {
9305  s->bkmrk = SQL_UB_ON;
9306  goto e01s02;
9307  }
9308  s->bkmrk = (val == (SQLPOINTER) SQL_UB_ON) ? SQL_UB_ON : SQL_UB_OFF;
9309  return SQL_SUCCESS;
9310  case SQL_ATTR_FETCH_BOOKMARK_PTR:
9311  s->bkmrkptr = (SQLINTEGER *) val;
9312  return SQL_SUCCESS;
9313  case SQL_ATTR_MAX_ROWS:
9314  s->max_rows = uval;
9315  return SQL_SUCCESS;
9316  case SQL_ATTR_MAX_LENGTH:
9317  if (val != (SQLPOINTER) 1000000000) {
9318  goto e01s02;
9319  }
9320  return SQL_SUCCESS;
9321 #ifdef SQL_ATTR_METADATA_ID
9322  case SQL_ATTR_METADATA_ID:
9323  if (val != (SQLPOINTER) SQL_FALSE) {
9324  goto e01s02;
9325  }
9326  return SQL_SUCCESS;
9327 #endif
9328  }
9329  return drvunimplstmt(stmt);
9330 }
9331 
9332 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
9333 
9342 SQLRETURN SQL_API
9343 SQLSetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9344  SQLINTEGER buflen)
9345 {
9346  SQLRETURN ret;
9347 
9348  HSTMT_LOCK(stmt);
9349  ret = drvsetstmtattr(stmt, attr, val, buflen);
9350  HSTMT_UNLOCK(stmt);
9351  return ret;
9352 }
9353 #endif
9354 
9355 #ifdef WINTERFACE
9356 
9365 SQLRETURN SQL_API
9366 SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9367  SQLINTEGER buflen)
9368 {
9369  SQLRETURN ret;
9370 
9371  HSTMT_LOCK(stmt);
9372  ret = drvsetstmtattr(stmt, attr, val, buflen);
9373  HSTMT_UNLOCK(stmt);
9374  return ret;
9375 }
9376 #endif
9377 
9386 static SQLRETURN
9387 drvgetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9388 {
9389  STMT *s = (STMT *) stmt;
9390  SQLUINTEGER *ret = (SQLUINTEGER *) param;
9391 
9392  switch (opt) {
9393  case SQL_QUERY_TIMEOUT:
9394  *ret = 0;
9395  return SQL_SUCCESS;
9396  case SQL_CURSOR_TYPE:
9397  *ret = s->curtype;
9398  return SQL_SUCCESS;
9399  case SQL_ROW_NUMBER:
9400  if (s->s3stmt) {
9401  *ret = (s->s3stmt_rownum < 0) ?
9402  SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
9403  } else {
9404  *ret = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
9405  }
9406  return SQL_SUCCESS;
9407  case SQL_ASYNC_ENABLE:
9408  *ret = SQL_ASYNC_ENABLE_OFF;
9409  return SQL_SUCCESS;
9410  case SQL_CONCURRENCY:
9411  *ret = SQL_CONCUR_LOCK;
9412  return SQL_SUCCESS;
9413  case SQL_ATTR_RETRIEVE_DATA:
9414  *ret = s->retr_data;
9415  return SQL_SUCCESS;
9416  case SQL_ROWSET_SIZE:
9417  case SQL_ATTR_ROW_ARRAY_SIZE:
9418  *ret = s->rowset_size;
9419  return SQL_SUCCESS;
9420  case SQL_ATTR_MAX_ROWS:
9421  *ret = s->max_rows;
9422  return SQL_SUCCESS;
9423  case SQL_ATTR_MAX_LENGTH:
9424  *ret = 1000000000;
9425  return SQL_SUCCESS;
9426  }
9427  return drvunimplstmt(stmt);
9428 }
9429 
9438 SQLRETURN SQL_API
9439 SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9440 {
9441  SQLRETURN ret;
9442 
9443  HSTMT_LOCK(stmt);
9444  ret = drvgetstmtoption(stmt, opt, param);
9445  HSTMT_UNLOCK(stmt);
9446  return ret;
9447 }
9448 
9449 #ifdef WINTERFACE
9450 
9458 SQLRETURN SQL_API
9459 SQLGetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9460 {
9461  SQLRETURN ret;
9462 
9463  HSTMT_LOCK(stmt);
9464  ret = drvgetstmtoption(stmt, opt, param);
9465  HSTMT_UNLOCK(stmt);
9466  return ret;
9467 }
9468 #endif
9469 
9478 static SQLRETURN
9479 drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
9480 {
9481  STMT *s = (STMT *) stmt;
9482 
9483  switch (opt) {
9484  case SQL_CURSOR_TYPE:
9485  if (param == SQL_CURSOR_FORWARD_ONLY) {
9486  s->curtype = param;
9487  } else {
9488  s->curtype = SQL_CURSOR_STATIC;
9489  }
9490  if (param != SQL_CURSOR_FORWARD_ONLY &&
9491  param != SQL_CURSOR_STATIC) {
9492  goto e01s02;
9493  }
9494  return SQL_SUCCESS;
9495  case SQL_ASYNC_ENABLE:
9496  if (param != SQL_ASYNC_ENABLE_OFF) {
9497  goto e01s02;
9498  }
9499  return SQL_SUCCESS;
9500  case SQL_CONCURRENCY:
9501  if (param != SQL_CONCUR_LOCK) {
9502  goto e01s02;
9503  }
9504  return SQL_SUCCESS;
9505  case SQL_QUERY_TIMEOUT:
9506  return SQL_SUCCESS;
9507  case SQL_RETRIEVE_DATA:
9508  if (param != SQL_RD_ON && param != SQL_RD_OFF) {
9509  e01s02:
9510  setstat(s, -1, "option value changed", "01S02");
9511  return SQL_SUCCESS_WITH_INFO;
9512  }
9513  s->retr_data = (int) param;
9514  return SQL_SUCCESS;
9515  case SQL_ROWSET_SIZE:
9516  case SQL_ATTR_ROW_ARRAY_SIZE:
9517  if (param < 1) {
9518  setstat(s, -1, "invalid rowset size", "HY000");
9519  return SQL_ERROR;
9520  } else {
9521  SQLUSMALLINT *rst = &s->row_status1;
9522 
9523  if (param > 1) {
9524  rst = xmalloc(sizeof (SQLUSMALLINT) * param);
9525  if (!rst) {
9526  return nomem(s);
9527  }
9528  }
9529  if (s->row_status0 != &s->row_status1) {
9530  freep(&s->row_status0);
9531  }
9532  s->row_status0 = rst;
9533  s->rowset_size = param;
9534  }
9535  return SQL_SUCCESS;
9536  case SQL_ATTR_MAX_ROWS:
9537  s->max_rows = param;
9538  return SQL_SUCCESS;
9539  case SQL_ATTR_MAX_LENGTH:
9540  if (param != 1000000000) {
9541  goto e01s02;
9542  }
9543  return SQL_SUCCESS;
9544  }
9545  return drvunimplstmt(stmt);
9546 }
9547 
9556 SQLRETURN SQL_API
9557 SQLSetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt,
9559 {
9560  SQLRETURN ret;
9561 
9562  HSTMT_LOCK(stmt);
9563  ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
9564  HSTMT_UNLOCK(stmt);
9565  return ret;
9566 }
9567 
9568 #ifdef WINTERFACE
9569 
9577 SQLRETURN SQL_API
9578 SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt,
9580 {
9581  SQLRETURN ret;
9582 
9583  HSTMT_LOCK(stmt);
9584  ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
9585  HSTMT_UNLOCK(stmt);
9586  return ret;
9587 }
9588 #endif
9589 
9596 static SQLRETURN
9598 {
9599  int i;
9600 
9601  if (!s->bindcols || s->nbindcols < s->ncols) {
9602 unbound:
9603  setstat(s, -1, "unbound columns", (*s->ov3) ? "HY000" : "S1000");
9604  return SQL_ERROR;
9605  }
9606  for (i = 0; i < s->ncols; i++) {
9607  BINDCOL *b = &s->bindcols[i];
9608 
9609  if (b->type == SQL_UNKNOWN_TYPE || !b->valp) {
9610  goto unbound;
9611  }
9612  }
9613  return SQL_SUCCESS;
9614 }
9615 
9627 static SQLRETURN
9628 setposbind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
9629 {
9630  DBC *d = (DBC *) s->dbc;
9631  SQLPOINTER dp = 0;
9632  SQLLEN *lp = 0;
9633  BINDCOL *b = &s->bindcols[i];
9634  COL *c = &s->cols[i];
9635  char strbuf[128], *cp;
9636 
9637  if (b->valp) {
9638  if (s->bind_type != SQL_BIND_BY_COLUMN) {
9639  dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
9640  } else {
9641  dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
9642  }
9643  if (s->bind_offs) {
9644  dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
9645  }
9646  }
9647  if (b->lenp) {
9648  if (s->bind_type != SQL_BIND_BY_COLUMN) {
9649  lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
9650  } else {
9651  lp = b->lenp + rsi;
9652  }
9653  if (s->bind_offs) {
9654  lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
9655  }
9656  }
9657  if (!dp || !lp) {
9658  setstat(s, -1, "unbound column in positional update",
9659  (*s->ov3) ? "HY000" : "S1000");
9660  return SQL_ERROR;
9661  }
9662  if (*lp == SQL_NULL_DATA) {
9663  sqlite3_bind_null(stmt, si);
9664  if (d->trace) {
9665  fprintf(d->trace, "-- parameter %d: NULL\n", si);
9666  fflush(d->trace);
9667  }
9668  return SQL_SUCCESS;
9669  }
9670  switch (b->type) {
9671  case SQL_C_UTINYINT:
9672  case SQL_C_TINYINT:
9673  case SQL_C_STINYINT:
9674  sqlite3_bind_int(stmt, si, *(SQLCHAR *) dp);
9675  if (d->trace) {
9676  fprintf(d->trace, "-- parameter %d: %d\n", si, *(SQLCHAR *) dp);
9677  fflush(d->trace);
9678  }
9679  break;
9680 #ifdef SQL_BIT
9681  case SQL_C_BIT:
9682  sqlite3_bind_int(stmt, si, (*(SQLCHAR *) dp) ? 1 : 0);
9683  if (d->trace) {
9684  fprintf(d->trace, "-- parameter %d: %d\n", si,
9685  (*(SQLCHAR *) dp) ? 1 : 0);
9686  fflush(d->trace);
9687  }
9688  break;
9689 #endif
9690  case SQL_C_USHORT:
9691  sqlite3_bind_int(stmt, si, *(SQLUSMALLINT *) dp);
9692  if (d->trace) {
9693  fprintf(d->trace, "-- parameter %d: %d\n", si,
9694  *(SQLUSMALLINT *) dp);
9695  fflush(d->trace);
9696  }
9697  break;
9698  case SQL_C_SHORT:
9699  case SQL_C_SSHORT:
9700  sqlite3_bind_int(stmt, si, *(SQLSMALLINT *) dp);
9701  if (d->trace) {
9702  fprintf(d->trace, "-- parameter %d: %d\n", si,
9703  *(SQLSMALLINT *) dp);
9704  fflush(d->trace);
9705  }
9706  break;
9707  case SQL_C_ULONG:
9708  sqlite3_bind_int(stmt, si, *(SQLUINTEGER *) dp);
9709  if (d->trace) {
9710  fprintf(d->trace, "-- parameter %d: %ld\n", si,
9711  (long) *(SQLUINTEGER *) dp);
9712  fflush(d->trace);
9713  }
9714  break;
9715  case SQL_C_LONG:
9716  case SQL_C_SLONG:
9717  sqlite3_bind_int(stmt, si, *(SQLINTEGER *) dp);
9718  if (d->trace) {
9719  fprintf(d->trace, "-- parameter %d: %ld\n", si,
9720  (long) *(SQLINTEGER *) dp);
9721  fflush(d->trace);
9722  }
9723  break;
9724 #ifdef SQL_BIGINT
9725  case SQL_C_UBIGINT:
9726  case SQL_C_SBIGINT:
9727  sqlite3_bind_int64(stmt, si, *(SQLBIGINT *) dp);
9728  if (d->trace) {
9729  fprintf(d->trace,
9730 #ifdef _WIN32
9731  "-- parameter %d: %I64d\n",
9732 #else
9733  "-- parameter %d: %lld\n",
9734 #endif
9735  si, (sqlite_int64) *(SQLBIGINT *) dp);
9736  fflush(d->trace);
9737  }
9738  break;
9739 #endif
9740  case SQL_C_FLOAT:
9741  sqlite3_bind_double(stmt, si, *(float *) dp);
9742  if (d->trace) {
9743  fprintf(d->trace, "-- parameter %d: %g\n", si,
9744  *(float *) dp);
9745  fflush(d->trace);
9746  }
9747  break;
9748  case SQL_C_DOUBLE:
9749  sqlite3_bind_double(stmt, si, *(double *) dp);
9750  if (d->trace) {
9751  fprintf(d->trace, "-- parameter %d: %g\n", si,
9752  *(double *) dp);
9753  fflush(d->trace);
9754  }
9755  break;
9756  case SQL_C_BINARY:
9757  sqlite3_bind_blob(stmt, si, (char *) dp, *lp, SQLITE_STATIC);
9758  if (d->trace) {
9759  fprintf(d->trace, "-- parameter %d: [BLOB]\n", si);
9760  fflush(d->trace);
9761  }
9762  break;
9763 #ifdef WCHARSUPPORT
9764  case SQL_C_WCHAR:
9765  cp = uc_to_utf((SQLWCHAR *) dp, *lp);
9766  if (!cp) {
9767  return nomem(s);
9768  }
9769  sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
9770  if (d->trace) {
9771  fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
9772  fflush(d->trace);
9773  }
9774  uc_free(cp);
9775  break;
9776 #endif
9777  case SQL_C_CHAR:
9778 #if defined(_WIN32) || defined(_WIN64)
9779  if (*s->oemcp) {
9780  cp = wmb_to_utf((char *) dp, *lp);
9781  if (!cp) {
9782  return nomem(s);
9783  }
9784  sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
9785  if (d->trace) {
9786  fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
9787  fflush(d->trace);
9788  }
9789  uc_free(cp);
9790  } else
9791 #endif
9792  {
9793  if (*lp == SQL_NTS) {
9794  sqlite3_bind_text(stmt, si, (char *) dp, -1,
9795  SQLITE_STATIC);
9796  if (d->trace) {
9797  fprintf(d->trace, "-- parameter %d: '%s'\n", si,
9798  (char *) dp);
9799  fflush(d->trace);
9800  }
9801  } else {
9802  sqlite3_bind_text(stmt, si, (char *) dp, *lp,
9803  SQLITE_STATIC);
9804  if (d->trace) {
9805  fprintf(d->trace, "-- parameter %d: '%*s'\n", si,
9806  (int) *lp, (char *) dp);
9807  fflush(d->trace);
9808  }
9809  }
9810  }
9811  break;
9812 #ifdef SQL_C_TYPE_DATE
9813  case SQL_C_TYPE_DATE:
9814 #endif
9815  case SQL_C_DATE:
9816  if (*s->jdconv) {
9817  int a, b, x1, x2, y, m, dd;
9818  double v;
9819 
9820  y = ((DATE_STRUCT *) dp)->year;
9821  m = ((DATE_STRUCT *) dp)->month;
9822  dd = ((DATE_STRUCT *) dp)->day;
9823  if (m <= 2) {
9824  y--;
9825  m += 12;
9826  }
9827  a = y / 100;
9828  b = 2 - a + (a / 4);
9829  x1 = 36525 * (y + 4716) / 100;
9830  x2 = 306001 * (m + 1) / 10000;
9831  v = x1 + x2 + dd + b - 1524.5;
9832  sqlite3_bind_double(stmt, si, v);
9833  if (d->trace) {
9834  fprintf(d->trace, "-- parameter %d: %g\n", si, v);
9835  fflush(d->trace);
9836  }
9837  } else {
9838  sprintf(strbuf, "%04d-%02d-%02d",
9839  ((DATE_STRUCT *) dp)->year,
9840  ((DATE_STRUCT *) dp)->month,
9841  ((DATE_STRUCT *) dp)->day);
9842  sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
9843  if (d->trace) {
9844  fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
9845  fflush(d->trace);
9846  }
9847  }
9848  break;
9849 #ifdef SQL_C_TYPE_TIME
9850  case SQL_C_TYPE_TIME:
9851 #endif
9852  case SQL_C_TIME:
9853  if (*s->jdconv) {
9854  double v;
9855 
9856  v = 2451544.5 +
9857  (((TIME_STRUCT *) dp)->hour * 3600000.0 +
9858  ((TIME_STRUCT *) dp)->minute * 60000.0 +
9859  ((TIME_STRUCT *) dp)->second * 1000.0) / 86400000.0;
9860  sqlite3_bind_double(stmt, si, v);
9861  if (d->trace) {
9862  fprintf(d->trace, "-- parameter %d: %g\n", si, v);
9863  fflush(d->trace);
9864  }
9865  } else {
9866  sprintf(strbuf, "%02d:%02d:%02d",
9867  ((TIME_STRUCT *) dp)->hour,
9868  ((TIME_STRUCT *) dp)->minute,
9869  ((TIME_STRUCT *) dp)->second);
9870  sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
9871  if (d->trace) {
9872  fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
9873  fflush(d->trace);
9874  }
9875  }
9876  break;
9877 #ifdef SQL_C_TYPE_TIMESTAMP
9878  case SQL_C_TYPE_TIMESTAMP:
9879 #endif
9880  case SQL_C_TIMESTAMP:
9881  if (*s->jdconv) {
9882  int a, b, x1, x2, y, m, dd;
9883  double v;
9884 
9885  y = ((TIMESTAMP_STRUCT *) dp)->year;
9886  m = ((TIMESTAMP_STRUCT *) dp)->month;
9887  dd = ((TIMESTAMP_STRUCT *) dp)->day;
9888  if (m <= 2) {
9889  y--;
9890  m += 12;
9891  }
9892  a = y / 100;
9893  b = 2 - a + (a / 4);
9894  x1 = 36525 * (y + 4716) / 100;
9895  x2 = 306001 * (m + 1) / 10000;
9896  v = x1 + x2 + dd + b - 1524.5 +
9897  (((TIMESTAMP_STRUCT *) dp)->hour * 3600000.0 +
9898  ((TIMESTAMP_STRUCT *) dp)->minute * 60000.0 +
9899  ((TIMESTAMP_STRUCT *) dp)->second * 1000.0 +
9900  ((TIMESTAMP_STRUCT *) dp)->fraction / 1.0E6)
9901  / 86400000.0;
9902  sqlite3_bind_double(stmt, si, v);
9903  if (d->trace) {
9904  fprintf(d->trace, "-- parameter %d: %g\n", si, v);
9905  fflush(d->trace);
9906  }
9907  } else {
9908  int frac;
9909 
9910  frac = (int) ((TIMESTAMP_STRUCT *) dp)->fraction;
9911  frac /= 1000000;
9912  frac = frac % 1000;
9913  if (frac < 0) {
9914  frac = 0;
9915  }
9916  if (c->prec && c->prec <= 16) {
9917  sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
9918  ((TIMESTAMP_STRUCT *) dp)->year,
9919  ((TIMESTAMP_STRUCT *) dp)->month,
9920  ((TIMESTAMP_STRUCT *) dp)->day,
9921  ((TIMESTAMP_STRUCT *) dp)->hour,
9922  ((TIMESTAMP_STRUCT *) dp)->minute);
9923  } else if (c->prec && c->prec <= 19) {
9924  sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
9925  ((TIMESTAMP_STRUCT *) dp)->year,
9926  ((TIMESTAMP_STRUCT *) dp)->month,
9927  ((TIMESTAMP_STRUCT *) dp)->day,
9928  ((TIMESTAMP_STRUCT *) dp)->hour,
9929  ((TIMESTAMP_STRUCT *) dp)->minute,
9930  ((TIMESTAMP_STRUCT *) dp)->second);
9931  } else {
9932  sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
9933  ((TIMESTAMP_STRUCT *) dp)->year,
9934  ((TIMESTAMP_STRUCT *) dp)->month,
9935  ((TIMESTAMP_STRUCT *) dp)->day,
9936  ((TIMESTAMP_STRUCT *) dp)->hour,
9937  ((TIMESTAMP_STRUCT *) dp)->minute,
9938  ((TIMESTAMP_STRUCT *) dp)->second,
9939  frac);
9940  }
9941  sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
9942  if (d->trace) {
9943  fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
9944  fflush(d->trace);
9945  }
9946  }
9947  break;
9948  default:
9949  setstat(s, -1, "unsupported column type in positional update",
9950  (*s->ov3) ? "HY000" : "S1000");
9951  return SQL_ERROR;
9952  }
9953  return SQL_SUCCESS;
9954 }
9955 
9967 static SQLRETURN
9968 setposibind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
9969 {
9970  DBC *d = (DBC *) s->dbc;
9971  char **data;
9972  int pos;
9973 
9974  pos = s->rowprs;
9975  if (pos < 0) {
9976  setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
9977  return SQL_ERROR;
9978  }
9979  pos += rsi;
9980  data = s->rows + s->ncols + (pos * s->ncols) + i;
9981  if (*data == NULL) {
9982  sqlite3_bind_null(stmt, si);
9983  if (d->trace) {
9984  fprintf(d->trace, "-- parameter %d: NULL\n", si);
9985  fflush(d->trace);
9986  }
9987  } else {
9988  sqlite3_bind_text(stmt, si, *data, -1, SQLITE_STATIC);
9989  if (d->trace) {
9990  fprintf(d->trace, "-- parameter %d: '%s'\n", si, *data);
9991  fflush(d->trace);
9992  }
9993  }
9994  return SQL_SUCCESS;
9995 }
9996 
10004 static SQLRETURN
10005 setposrefr(STMT *s, int rsi)
10006 {
10007  int i, withinfo = 0;
10008  SQLRETURN ret = SQL_SUCCESS;
10009 
10010  for (i = 0; s->bindcols && i < s->ncols; i++) {
10011  BINDCOL *b = &s->bindcols[i];
10012  SQLPOINTER dp = 0;
10013  SQLLEN *lp = 0;
10014 
10015  b->offs = 0;
10016  if (b->valp) {
10017  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10018  dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
10019  } else {
10020  dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
10021  }
10022  if (s->bind_offs) {
10023  dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
10024  }
10025  }
10026  if (b->lenp) {
10027  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10028  lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
10029  } else {
10030  lp = b->lenp + rsi;
10031  }
10032  if (s->bind_offs) {
10033  lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
10034  }
10035  }
10036  if (dp || lp) {
10037  int rowp = s->rowp;
10038 
10039  s->rowp = s->rowprs + rsi;
10040  ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp,
10041  b->max, lp, 0);
10042  s->rowp = rowp;
10043  if (!SQL_SUCCEEDED(ret)) {
10044  s->row_status0[rsi] = SQL_ROW_ERROR;
10045  break;
10046  }
10047  if (ret != SQL_SUCCESS) {
10048  withinfo = 1;
10049 #ifdef SQL_ROW_SUCCESS_WITH_INFO
10050  s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
10051 #endif
10052  }
10053  }
10054  }
10055  if (SQL_SUCCEEDED(ret)) {
10056  ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
10057  }
10058  return ret;
10059 }
10060 
10070 static SQLRETURN
10071 drvsetpos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10072 {
10073  STMT *s = (STMT *) stmt;
10074  DBC *d = (DBC *) s->dbc;
10075  int rowp, i, k, rc, nretry = 0;
10076  dstr *sql = 0;
10077  const char *endp;
10078  sqlite3_stmt *s3stmt = NULL;
10079  SQLRETURN ret;
10080 
10081  if (lock != SQL_LOCK_NO_CHANGE) {
10082  setstat(s, -1, "unsupported locking mode",
10083  (*s->ov3) ? "HY000" : "S1000");
10084  return SQL_ERROR;
10085  }
10086  if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10087  setstat(s, -1, "incompatible statement",
10088  (*s->ov3) ? "HY000" : "S1000");
10089  return SQL_ERROR;
10090  }
10091  if (op == SQL_ADD) {
10092  if (s->one_tbl <= 0) {
10093  setstat(s, -1, "incompatible rowset",
10094  (*s->ov3) ? "HY000" : "S1000");
10095  return SQL_ERROR;
10096  }
10097  if (row == 0 || row > s->rowset_size + 1) {
10098  goto rowoor;
10099  }
10100  ret = chkunbound(s);
10101  if (ret != SQL_SUCCESS) {
10102  return ret;
10103  }
10104  sql = dsappend(sql, "INSERT INTO ");
10105  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10106  sql = dsappendq(sql, s->dyncols[0].db);
10107  sql = dsappend(sql, ".");
10108  }
10109  sql = dsappendq(sql, s->dyncols[0].table);
10110  for (i = 0; i < s->ncols; i++) {
10111  sql = dsappend(sql, (i > 0) ? "," : "(");
10112  sql = dsappendq(sql, s->dyncols[i].column);
10113  }
10114  sql = dsappend(sql, ") VALUES ");
10115  for (i = 0; i < s->ncols; i++) {
10116  sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10117  }
10118  sql = dsappend(sql, ")");
10119  if (dserr(sql)) {
10120  dsfree(sql);
10121  return nomem(s);
10122  }
10123 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10124  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10125 #else
10126  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10127 #endif
10128  do {
10129  s3stmt = NULL;
10130 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10131  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10132  &s3stmt, &endp);
10133 #else
10134  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10135  &s3stmt, &endp);
10136 #endif
10137  if (rc != SQLITE_OK) {
10138  if (s3stmt) {
10139  sqlite3_finalize(s3stmt);
10140  s3stmt = NULL;
10141  }
10142  }
10143  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10144  dbtracerc(d, rc, NULL);
10145  dsfree(sql);
10146  if (rc != SQLITE_OK) {
10147 istmterr:
10148  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10149  sqlite3_errmsg(d->sqlite), rc);
10150  if (s3stmt) {
10151  dbtraceapi(d, "sqlite3_finalize", NULL);
10152  sqlite3_finalize(s3stmt);
10153  }
10154  return SQL_ERROR;
10155  }
10156  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10157  ret = setposbind(s, s3stmt, i, k, row - 1);
10158  if (ret != SQL_SUCCESS) {
10159  dbtraceapi(d, "sqlite3_finalize", NULL);
10160  sqlite3_finalize(s3stmt);
10161  return ret;
10162  }
10163  k++;
10164  }
10165  rc = sqlite3_step(s3stmt);
10166  if (rc != SQLITE_DONE) {
10167  goto istmterr;
10168  }
10169  sqlite3_finalize(s3stmt);
10170  if (sqlite3_changes(d->sqlite) > 0 && row <= s->rowset_size) {
10171  if (s->row_status0) {
10172  s->row_status0[row - 1] = SQL_ROW_ADDED;
10173  }
10174  if (s->row_status) {
10175  s->row_status[row - 1] = SQL_ROW_ADDED;
10176  }
10177  }
10178  return SQL_SUCCESS;
10179  } else if (op == SQL_UPDATE || op == SQL_DELETE) {
10180  if (s->one_tbl <= 0 || s->has_pk <= 0) {
10181  setstat(s, -1, "incompatible rowset",
10182  (*s->ov3) ? "HY000" : "S1000");
10183  return SQL_ERROR;
10184  }
10185  if (row == 0) {
10186  ret = SQL_SUCCESS;
10187  for (i = 1; i <= s->rowset_size; i++) {
10188  ret = drvsetpos(stmt, i, op, lock);
10189  if (!SQL_SUCCEEDED(ret)) {
10190  break;
10191  }
10192  }
10193  return ret;
10194  }
10195  if (row > s->rowset_size) {
10196  goto rowoor;
10197  }
10198  }
10199  if (op != SQL_POSITION && op != SQL_REFRESH &&
10200  op != SQL_DELETE && op != SQL_UPDATE) {
10201  return drvunimplstmt(stmt);
10202  }
10203  if (op == SQL_POSITION) {
10204  rowp = s->rowp + row - 1;
10205  if (!s->rows || row == 0 || rowp < -1 || rowp >= s->nrows) {
10206 rowoor:
10207  setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
10208  return SQL_ERROR;
10209  }
10210  s->rowp = rowp;
10211  } else if (op == SQL_REFRESH) {
10212  if (row > s->rowset_size) {
10213  goto rowoor;
10214  }
10215  if (row == 0) {
10216  ret = SQL_SUCCESS;
10217  for (i = 0; i < s->rowset_size; i++) {
10218  ret = setposrefr(s, i);
10219  if (!SQL_SUCCEEDED(ret)) {
10220  break;
10221  }
10222  }
10223  return ret;
10224  }
10225  return setposrefr(s, row - 1);
10226  } else if (op == SQL_DELETE) {
10227  sql = dsappend(sql, "DELETE FROM ");
10228  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10229  sql = dsappendq(sql, s->dyncols[0].db);
10230  sql = dsappend(sql, ".");
10231  }
10232  sql = dsappendq(sql, s->dyncols[0].table);
10233  for (i = k = 0; i < s->ncols; i++) {
10234  if (s->dyncols[i].ispk <= 0) {
10235  continue;
10236  }
10237  sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10238  sql = dsappendq(sql, s->dyncols[i].column);
10239  sql = dsappend(sql, " = ?");
10240  k++;
10241  }
10242  if (dserr(sql)) {
10243  dsfree(sql);
10244  return nomem(s);
10245  }
10246 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10247  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10248 #else
10249  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10250 #endif
10251  do {
10252  s3stmt = NULL;
10253 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10254  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10255  &s3stmt, &endp);
10256 #else
10257  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10258  &s3stmt, &endp);
10259 #endif
10260  if (rc != SQLITE_OK) {
10261  if (s3stmt) {
10262  sqlite3_finalize(s3stmt);
10263  s3stmt = NULL;
10264  }
10265  }
10266  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10267  dbtracerc(d, rc, NULL);
10268  dsfree(sql);
10269  if (rc != SQLITE_OK) {
10270 dstmterr:
10271  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10272  sqlite3_errmsg(d->sqlite), rc);
10273  if (s3stmt) {
10274  dbtraceapi(d, "sqlite3_finalize", NULL);
10275  sqlite3_finalize(s3stmt);
10276  }
10277  return SQL_ERROR;
10278  }
10279  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10280  if (s->dyncols[i].ispk <= 0) {
10281  continue;
10282  }
10283  ret = setposibind(s, s3stmt, i, k, row - 1);
10284  if (ret != SQL_SUCCESS) {
10285  dbtraceapi(d, "sqlite3_finalize", NULL);
10286  sqlite3_finalize(s3stmt);
10287  return ret;
10288  }
10289  k++;
10290  }
10291  rc = sqlite3_step(s3stmt);
10292  if (rc != SQLITE_DONE) {
10293  goto dstmterr;
10294  }
10295  sqlite3_finalize(s3stmt);
10296  if (sqlite3_changes(d->sqlite) > 0) {
10297  if (s->row_status0) {
10298  s->row_status0[row - 1] = SQL_ROW_DELETED;
10299  }
10300  if (s->row_status) {
10301  s->row_status[row - 1] = SQL_ROW_DELETED;
10302  }
10303  }
10304  return SQL_SUCCESS;
10305  } else if (op == SQL_UPDATE) {
10306  ret = chkunbound(s);
10307  if (ret != SQL_SUCCESS) {
10308  return ret;
10309  }
10310  sql = dsappend(sql, "UPDATE ");
10311  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10312  sql = dsappendq(sql, s->dyncols[0].db);
10313  sql = dsappend(sql, ".");
10314  }
10315  sql = dsappendq(sql, s->dyncols[0].table);
10316  for (i = 0; i < s->ncols; i++) {
10317  sql = dsappend(sql, (i > 0) ? ", " : " SET ");
10318  sql = dsappendq(sql, s->dyncols[i].column);
10319  sql = dsappend(sql, " = ?");
10320  }
10321  for (i = k = 0; i < s->ncols; i++) {
10322  if (s->dyncols[i].ispk <= 0) {
10323  continue;
10324  }
10325  sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10326  sql = dsappendq(sql, s->dyncols[i].column);
10327  sql = dsappend(sql, " = ?");
10328  k++;
10329  }
10330  if (dserr(sql)) {
10331  dsfree(sql);
10332  return nomem(s);
10333  }
10334 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10335  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10336 #else
10337  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10338 #endif
10339  do {
10340  s3stmt = NULL;
10341 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10342  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10343  &s3stmt, &endp);
10344 #else
10345  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10346  &s3stmt, &endp);
10347 #endif
10348  if (rc != SQLITE_OK) {
10349  if (s3stmt) {
10350  sqlite3_finalize(s3stmt);
10351  s3stmt = NULL;
10352  }
10353  }
10354  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10355  dbtracerc(d, rc, NULL);
10356  dsfree(sql);
10357  if (rc != SQLITE_OK) {
10358 ustmterr:
10359  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10360  sqlite3_errmsg(d->sqlite), rc);
10361  if (s3stmt) {
10362  dbtraceapi(d, "sqlite3_finalize", NULL);
10363  sqlite3_finalize(s3stmt);
10364  }
10365  return SQL_ERROR;
10366  }
10367  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10368  ret = setposbind(s, s3stmt, i, k, row - 1);
10369  if (ret != SQL_SUCCESS) {
10370  dbtraceapi(d, "sqlite3_finalize", NULL);
10371  sqlite3_finalize(s3stmt);
10372  return ret;
10373  }
10374  k++;
10375  }
10376  for (i = 0; s->bindcols && i < s->ncols; i++) {
10377  if (s->dyncols[i].ispk <= 0) {
10378  continue;
10379  }
10380  ret = setposibind(s, s3stmt, i, k, row - 1);
10381  if (ret != SQL_SUCCESS) {
10382  dbtraceapi(d, "sqlite3_finalize", NULL);
10383  sqlite3_finalize(s3stmt);
10384  return ret;
10385  }
10386  k++;
10387  }
10388  rc = sqlite3_step(s3stmt);
10389  if (rc != SQLITE_DONE) {
10390  goto ustmterr;
10391  }
10392  sqlite3_finalize(s3stmt);
10393  if (sqlite3_changes(d->sqlite) > 0) {
10394  if (s->row_status0) {
10395  s->row_status0[row - 1] = SQL_ROW_UPDATED;
10396  }
10397  if (s->row_status) {
10398  s->row_status[row - 1] = SQL_ROW_UPDATED;
10399  }
10400  }
10401  return SQL_SUCCESS;
10402  }
10403  return SQL_SUCCESS;
10404 }
10405 
10415 SQLRETURN SQL_API
10416 SQLSetPos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10417 {
10418  SQLRETURN ret;
10419 
10420  HSTMT_LOCK(stmt);
10421  ret = drvsetpos(stmt, row, op, lock);
10422  HSTMT_UNLOCK(stmt);
10423  return ret;
10424 }
10425 
10433 static SQLRETURN
10434 drvbulkoperations(SQLHSTMT stmt, SQLSMALLINT op)
10435 {
10436  STMT *s = (STMT *) stmt;
10437  DBC *d = (DBC *) s->dbc;
10438  int row, i, k, rc, nretry = 0;
10439  dstr *sql = 0;
10440  const char *endp;
10441  sqlite3_stmt *s3stmt = NULL;
10442  SQLRETURN ret;
10443 
10444  if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10445  setstat(s, -1, "incompatible statement",
10446  (*s->ov3) ? "HY000" : "S1000");
10447  return SQL_ERROR;
10448  }
10449  if (op == SQL_ADD) {
10450  if (s->one_tbl <= 0) {
10451  setstat(s, -1, "incompatible rowset",
10452  (*s->ov3) ? "HY000" : "S1000");
10453  return SQL_ERROR;
10454  }
10455  ret = chkunbound(s);
10456  if (ret != SQL_SUCCESS) {
10457  return ret;
10458  }
10459  sql = dsappend(sql, "INSERT INTO ");
10460  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10461  sql = dsappendq(sql, s->dyncols[0].db);
10462  sql = dsappend(sql, ".");
10463  }
10464  sql = dsappendq(sql, s->dyncols[0].table);
10465  for (i = 0; i < s->ncols; i++) {
10466  sql = dsappend(sql, (i > 0) ? "," : "(");
10467  sql = dsappendq(sql, s->dyncols[i].column);
10468  }
10469  sql = dsappend(sql, ") VALUES ");
10470  for (i = 0; i < s->ncols; i++) {
10471  sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10472  }
10473  sql = dsappend(sql, ")");
10474  if (dserr(sql)) {
10475  dsfree(sql);
10476  return nomem(s);
10477  }
10478 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10479  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10480 #else
10481  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10482 #endif
10483  do {
10484  s3stmt = NULL;
10485 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10486  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10487  &s3stmt, &endp);
10488 #else
10489  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10490  &s3stmt, &endp);
10491 #endif
10492  if (rc != SQLITE_OK) {
10493  if (s3stmt) {
10494  sqlite3_finalize(s3stmt);
10495  s3stmt = NULL;
10496  }
10497  }
10498  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10499  dbtracerc(d, rc, NULL);
10500  dsfree(sql);
10501  if (rc != SQLITE_OK) {
10502  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10503  sqlite3_errmsg(d->sqlite), rc);
10504  if (s3stmt) {
10505  dbtraceapi(d, "sqlite3_finalize", NULL);
10506  sqlite3_finalize(s3stmt);
10507  }
10508  return SQL_ERROR;
10509  }
10510  for (row = 0; row < s->rowset_size; row++) {
10511  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10512  ret = setposbind(s, s3stmt, i, k, row);
10513  if (ret != SQL_SUCCESS) {
10514 istmterr:
10515  if (s->row_status0) {
10516  s->row_status0[row] = SQL_ROW_ERROR;
10517  }
10518  if (s->row_status) {
10519  s->row_status[row] = SQL_ROW_ERROR;
10520  }
10521  dbtraceapi(d, "sqlite3_finalize", NULL);
10522  sqlite3_finalize(s3stmt);
10523  return ret;
10524  }
10525  k++;
10526  }
10527  rc = sqlite3_step(s3stmt);
10528  if (rc != SQLITE_DONE) {
10529  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10530  sqlite3_errmsg(d->sqlite), rc);
10531  ret = SQL_ERROR;
10532  goto istmterr;
10533  }
10534  if (sqlite3_changes(d->sqlite) > 0) {
10535  if (s->row_status0) {
10536  s->row_status0[row] = SQL_ROW_ADDED;
10537  }
10538  if (s->row_status) {
10539  s->row_status[row] = SQL_ROW_ADDED;
10540  }
10541  }
10542  if (s->bkmrk == SQL_UB_VARIABLE &&
10543  s->bkmrkcol.type == SQL_C_VARBOOKMARK &&
10544  s->bkmrkcol.valp) {
10545  SQLPOINTER *val;
10546 
10547  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10548  val = (SQLPOINTER)
10549  ((char *) s->bkmrkcol.valp + s->bind_type * row);
10550  } else {
10551  val = (SQLPOINTER)
10552  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10553  }
10554  if (s->bind_offs) {
10555  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10556  }
10557  *(sqlite_int64 *) val = sqlite3_last_insert_rowid(d->sqlite);
10558  if (s->bkmrkcol.lenp) {
10559  SQLLEN *ival;
10560 
10561  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10562  ival = (SQLLEN *)
10563  ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10564  } else {
10565  ival = &s->bkmrkcol.lenp[row];
10566  }
10567  if (s->bind_offs) {
10568  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10569  }
10570  *ival = sizeof (sqlite_int64);
10571  }
10572  }
10573  dbtraceapi(d, "sqlite3_reset", NULL);
10574  sqlite3_reset(s3stmt);
10575  }
10576  dbtraceapi(d, "sqlite3_finalize", NULL);
10577  sqlite3_finalize(s3stmt);
10578  return SQL_SUCCESS;
10579  } else if (op == SQL_DELETE_BY_BOOKMARK) {
10580  if (s->has_rowid < 0 ||
10581  s->bkmrk != SQL_UB_VARIABLE ||
10582  s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10583  !s->bkmrkcol.valp) {
10584  setstat(s, -1, "incompatible rowset",
10585  (*s->ov3) ? "HY000" : "S1000");
10586  return SQL_ERROR;
10587  }
10588  sql = dsappend(sql, "DELETE FROM ");
10589  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10590  sql = dsappendq(sql, s->dyncols[0].db);
10591  sql = dsappend(sql, ".");
10592  }
10593  sql = dsappendq(sql, s->dyncols[0].table);
10594  sql = dsappend(sql, " WHERE ");
10595  sql = dsappendq(sql, s->dyncols[0].column);
10596  sql = dsappend(sql, " = ?");
10597  if (dserr(sql)) {
10598  dsfree(sql);
10599  return nomem(s);
10600  }
10601 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10602  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10603 #else
10604  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10605 #endif
10606  do {
10607  s3stmt = NULL;
10608 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10609  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10610  &s3stmt, &endp);
10611 #else
10612  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10613  &s3stmt, &endp);
10614 #endif
10615  if (rc != SQLITE_OK) {
10616  if (s3stmt) {
10617  sqlite3_finalize(s3stmt);
10618  s3stmt = NULL;
10619  }
10620  }
10621  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10622  dbtracerc(d, rc, NULL);
10623  dsfree(sql);
10624  if (rc != SQLITE_OK) {
10625  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10626  sqlite3_errmsg(d->sqlite), rc);
10627  if (s3stmt) {
10628  dbtraceapi(d, "sqlite3_finalize", NULL);
10629  sqlite3_finalize(s3stmt);
10630  }
10631  return SQL_ERROR;
10632  }
10633  for (row = 0; row < s->rowset_size; row++) {
10634  SQLPOINTER *val;
10635  sqlite_int64 rowid;
10636 
10637  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10638  val = (SQLPOINTER)
10639  ((char *) s->bkmrkcol.valp + s->bind_type * row);
10640  } else {
10641  val = (SQLPOINTER)
10642  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10643  }
10644  if (s->bind_offs) {
10645  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10646  }
10647  if (s->bkmrkcol.lenp) {
10648  SQLLEN *ival;
10649 
10650  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10651  ival = (SQLLEN *)
10652  ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10653  } else {
10654  ival = &s->bkmrkcol.lenp[row];
10655  }
10656  if (s->bind_offs) {
10657  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10658  }
10659  if (*ival != sizeof (sqlite_int64)) {
10660  continue;
10661  }
10662  }
10663  rowid = *(sqlite_int64 *) val;
10664  sqlite3_bind_int64(s3stmt, 1, rowid);
10665  if (d->trace) {
10666  fprintf(d->trace,
10667 #ifdef _WIN32
10668  "-- parameter 1: %I64d\n",
10669 #else
10670  "-- parameter 1: %lld\n",
10671 #endif
10672  rowid);
10673  fflush(d->trace);
10674  }
10675  rc = sqlite3_step(s3stmt);
10676  if (rc != SQLITE_DONE) {
10677  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10678  sqlite3_errmsg(d->sqlite), rc);
10679  if (s->row_status0) {
10680  s->row_status0[row] = SQL_ROW_ERROR;
10681  }
10682  if (s->row_status) {
10683  s->row_status[row] = SQL_ROW_ERROR;
10684  }
10685  dbtraceapi(d, "sqlite3_finalize", NULL);
10686  sqlite3_finalize(s3stmt);
10687  return SQL_ERROR;
10688  }
10689  if (sqlite3_changes(d->sqlite) > 0) {
10690  if (s->row_status0) {
10691  s->row_status0[row] = SQL_ROW_DELETED;
10692  }
10693  if (s->row_status) {
10694  s->row_status[row] = SQL_ROW_DELETED;
10695  }
10696  }
10697  dbtraceapi(d, "sqlite3_reset", NULL);
10698  sqlite3_reset(s3stmt);
10699  }
10700  dbtraceapi(d, "sqlite3_finalize", NULL);
10701  sqlite3_finalize(s3stmt);
10702  return SQL_SUCCESS;
10703  } else if (op == SQL_UPDATE_BY_BOOKMARK) {
10704  if (s->has_rowid < 0 ||
10705  s->bkmrk != SQL_UB_VARIABLE ||
10706  s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10707  !s->bkmrkcol.valp) {
10708  setstat(s, -1, "incompatible rowset",
10709  (*s->ov3) ? "HY000" : "S1000");
10710  return SQL_ERROR;
10711  }
10712  ret = chkunbound(s);
10713  if (ret != SQL_SUCCESS) {
10714  return ret;
10715  }
10716  sql = dsappend(sql, "UPDATE ");
10717  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10718  sql = dsappendq(sql, s->dyncols[0].db);
10719  sql = dsappend(sql, ".");
10720  }
10721  sql = dsappendq(sql, s->dyncols[0].table);
10722  for (i = 0, k = 0; i < s->ncols; i++) {
10723  if (i == s->has_rowid) {
10724  continue;
10725  }
10726  sql = dsappend(sql, (k > 0) ? ", " : " SET ");
10727  sql = dsappendq(sql, s->dyncols[i].column);
10728  sql = dsappend(sql, " = ?");
10729  k++;
10730  }
10731  sql = dsappend(sql, " WHERE ");
10732  sql = dsappendq(sql, s->dyncols[s->has_rowid].column);
10733  sql = dsappend(sql, " = ?");
10734  if (dserr(sql)) {
10735  dsfree(sql);
10736  return nomem(s);
10737  }
10738 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10739  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10740 #else
10741  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10742 #endif
10743  do {
10744  s3stmt = NULL;
10745 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10746  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10747  &s3stmt, &endp);
10748 #else
10749  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10750  &s3stmt, &endp);
10751 #endif
10752  if (rc != SQLITE_OK) {
10753  if (s3stmt) {
10754  sqlite3_finalize(s3stmt);
10755  s3stmt = NULL;
10756  }
10757  }
10758  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10759  dbtracerc(d, rc, NULL);
10760  dsfree(sql);
10761  if (rc != SQLITE_OK) {
10762  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10763  sqlite3_errmsg(d->sqlite), rc);
10764  if (s3stmt) {
10765  dbtraceapi(d, "sqlite3_finalize", NULL);
10766  sqlite3_finalize(s3stmt);
10767  }
10768  return SQL_ERROR;
10769  }
10770  for (row = 0; row < s->rowset_size; row++) {
10771  SQLPOINTER *val;
10772  sqlite_int64 rowid;
10773 
10774  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10775  val = (SQLPOINTER)
10776  ((char *) s->bkmrkcol.valp + s->bind_type * row);
10777  } else {
10778  val = (SQLPOINTER)
10779  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10780  }
10781  if (s->bind_offs) {
10782  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10783  }
10784  if (s->bkmrkcol.lenp) {
10785  SQLLEN *ival;
10786 
10787  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10788  ival = (SQLLEN *)
10789  ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10790  } else {
10791  ival = &s->bkmrkcol.lenp[row];
10792  }
10793  if (s->bind_offs) {
10794  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10795  }
10796  if (*ival != sizeof (sqlite_int64)) {
10797  continue;
10798  }
10799  }
10800  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10801  if (i == s->has_rowid) {
10802  continue;
10803  }
10804  ret = setposbind(s, s3stmt, i, k, row);
10805  if (ret != SQL_SUCCESS) {
10806 ustmterr:
10807  if (s->row_status0) {
10808  s->row_status0[row] = SQL_ROW_ERROR;
10809  }
10810  if (s->row_status) {
10811  s->row_status[row] = SQL_ROW_ERROR;
10812  }
10813  dbtraceapi(d, "sqlite3_finalize", NULL);
10814  sqlite3_finalize(s3stmt);
10815  return ret;
10816  }
10817  k++;
10818  }
10819  rowid = *(sqlite_int64 *) val;
10820  sqlite3_bind_int64(s3stmt, k, rowid);
10821  if (d->trace) {
10822  fprintf(d->trace,
10823 #ifdef _WIN32
10824  "-- parameter %d: %I64d\n",
10825 #else
10826  "-- parameter %d: %lld\n",
10827 #endif
10828  k, rowid);
10829  fflush(d->trace);
10830  }
10831  rc = sqlite3_step(s3stmt);
10832  if (rc != SQLITE_DONE) {
10833  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10834  sqlite3_errmsg(d->sqlite), rc);
10835  ret = SQL_ERROR;
10836  goto ustmterr;
10837  }
10838  if (sqlite3_changes(d->sqlite) > 0) {
10839  if (s->row_status0) {
10840  s->row_status0[row] = SQL_ROW_UPDATED;
10841  }
10842  if (s->row_status) {
10843  s->row_status[row] = SQL_ROW_UPDATED;
10844  }
10845  }
10846  dbtraceapi(d, "sqlite3_reset", NULL);
10847  sqlite3_reset(s3stmt);
10848  }
10849  dbtraceapi(d, "sqlite3_finalize", NULL);
10850  sqlite3_finalize(s3stmt);
10851  return SQL_SUCCESS;
10852  }
10853  setstat(s, -1, "unsupported operation", (*s->ov3) ? "HY000" : "S1000");
10854  return SQL_ERROR;
10855 }
10856 
10864 SQLRETURN SQL_API
10865 SQLBulkOperations(SQLHSTMT stmt, SQLSMALLINT oper)
10866 {
10867  SQLRETURN ret;
10868 
10869  HSTMT_LOCK(stmt);
10870  ret = drvbulkoperations(stmt, oper);
10871  HSTMT_UNLOCK(stmt);
10872  return ret;
10873 }
10874 
10875 
10880 SQLRETURN SQL_API
10881 SQLSetScrollOptions(SQLHSTMT stmt, SQLUSMALLINT concur, SQLLEN rowkeyset,
10882  SQLUSMALLINT rowset)
10883 {
10884  SQLRETURN ret;
10885 
10886  HSTMT_LOCK(stmt);
10887  ret = drvunimplstmt(stmt);
10888  HSTMT_UNLOCK(stmt);
10889  return ret;
10890 }
10891 
10892 #define strmak(dst, src, max, lenp) { \
10893  int len = strlen(src); \
10894  int cnt = min(len + 1, max); \
10895  strncpy(dst, src, cnt); \
10896  *lenp = (cnt > len) ? len : cnt; \
10897 }
10898 
10909 static SQLRETURN
10910 drvgetinfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
10911  SQLSMALLINT *valLen)
10912 {
10913  DBC *d;
10914  char dummyc[16];
10915  SQLSMALLINT dummy;
10916 #if defined(_WIN32) || defined(_WIN64)
10917  char pathbuf[301], *drvname;
10918 #else
10919  static char drvname[] = "sqlite3odbc.so";
10920 #endif
10921 
10922  if (dbc == SQL_NULL_HDBC) {
10923  return SQL_INVALID_HANDLE;
10924  }
10925  d = (DBC *) dbc;
10926  if (valMax) {
10927  valMax--;
10928  }
10929  if (!valLen) {
10930  valLen = &dummy;
10931  }
10932  if (!val) {
10933  val = dummyc;
10934  valMax = sizeof (dummyc) - 1;
10935  }
10936  switch (type) {
10937  case SQL_MAX_USER_NAME_LEN:
10938  *((SQLSMALLINT *) val) = 16;
10939  *valLen = sizeof (SQLSMALLINT);
10940  break;
10941  case SQL_USER_NAME:
10942  strmak(val, "", valMax, valLen);
10943  break;
10944  case SQL_DRIVER_ODBC_VER:
10945 #if 0
10946  strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
10947 #else
10948  strmak(val, "03.00", valMax, valLen);
10949 #endif
10950  break;
10951  case SQL_ACTIVE_CONNECTIONS:
10952  case SQL_ACTIVE_STATEMENTS:
10953  *((SQLSMALLINT *) val) = 0;
10954  *valLen = sizeof (SQLSMALLINT);
10955  break;
10956 #ifdef SQL_ASYNC_MODE
10957  case SQL_ASYNC_MODE:
10958  *((SQLUINTEGER *) val) = SQL_AM_NONE;
10959  *valLen = sizeof (SQLUINTEGER);
10960  break;
10961 #endif
10962 #ifdef SQL_CREATE_TABLE
10963  case SQL_CREATE_TABLE:
10964  *((SQLUINTEGER *) val) = SQL_CT_CREATE_TABLE |
10965  SQL_CT_COLUMN_DEFAULT |
10966  SQL_CT_COLUMN_CONSTRAINT |
10967  SQL_CT_CONSTRAINT_NON_DEFERRABLE;
10968  *valLen = sizeof (SQLUINTEGER);
10969  break;
10970 #endif
10971 #ifdef SQL_CREATE_VIEW
10972  case SQL_CREATE_VIEW:
10973  *((SQLUINTEGER *) val) = SQL_CV_CREATE_VIEW;
10974  *valLen = sizeof (SQLUINTEGER);
10975  break;
10976 #endif
10977 #ifdef SQL_DDL_INDEX
10978  case SQL_DDL_INDEX:
10979  *((SQLUINTEGER *) val) = SQL_DI_CREATE_INDEX | SQL_DI_DROP_INDEX;
10980  *valLen = sizeof (SQLUINTEGER);
10981  break;
10982 #endif
10983 #ifdef SQL_DROP_TABLE
10984  case SQL_DROP_TABLE:
10985  *((SQLUINTEGER *) val) = SQL_DT_DROP_TABLE;
10986  *valLen = sizeof (SQLUINTEGER);
10987  break;
10988 #endif
10989 #ifdef SQL_DROP_VIEW
10990  case SQL_DROP_VIEW:
10991  *((SQLUINTEGER *) val) = SQL_DV_DROP_VIEW;
10992  *valLen = sizeof (SQLUINTEGER);
10993  break;
10994 #endif
10995 #ifdef SQL_INDEX_KEYWORDS
10996  case SQL_INDEX_KEYWORDS:
10997  *((SQLUINTEGER *) val) = SQL_IK_ALL;
10998  *valLen = sizeof (SQLUINTEGER);
10999  break;
11000 #endif
11001  case SQL_DATA_SOURCE_NAME:
11002  strmak(val, d->dsn ? d->dsn : "", valMax, valLen);
11003  break;
11004  case SQL_DRIVER_NAME:
11005 #if defined(_WIN32) || defined(_WIN64)
11006  GetModuleFileName(hModule, pathbuf, sizeof (pathbuf));
11007  drvname = strrchr(pathbuf, '\\');
11008  if (drvname == NULL) {
11009  drvname = strrchr(pathbuf, '/');
11010  }
11011  if (drvname == NULL) {
11012  drvname = pathbuf;
11013  } else {
11014  drvname++;
11015  }
11016 #endif
11017  strmak(val, drvname, valMax, valLen);
11018  break;
11019  case SQL_DRIVER_VER:
11020  strmak(val, DRIVER_VER_INFO, valMax, valLen);
11021  break;
11022  case SQL_FETCH_DIRECTION:
11023  *((SQLUINTEGER *) val) = SQL_FD_FETCH_NEXT | SQL_FD_FETCH_FIRST |
11024  SQL_FD_FETCH_LAST | SQL_FD_FETCH_PRIOR | SQL_FD_FETCH_ABSOLUTE;
11025  *valLen = sizeof (SQLUINTEGER);
11026  break;
11027  case SQL_ODBC_VER:
11028  strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
11029  break;
11030  case SQL_ODBC_SAG_CLI_CONFORMANCE:
11031  *((SQLSMALLINT *) val) = SQL_OSCC_NOT_COMPLIANT;
11032  *valLen = sizeof (SQLSMALLINT);
11033  break;
11034  case SQL_STANDARD_CLI_CONFORMANCE:
11035  *((SQLUINTEGER *) val) = SQL_SCC_XOPEN_CLI_VERSION1;
11036  *valLen = sizeof (SQLUINTEGER);
11037  break;
11038  case SQL_SQL_CONFORMANCE:
11039  *((SQLUINTEGER *) val) = SQL_SC_SQL92_ENTRY;
11040  *valLen = sizeof (SQLUINTEGER);
11041  break;
11042  case SQL_SERVER_NAME:
11043  case SQL_DATABASE_NAME:
11044  strmak(val, d->dbname ? d->dbname : "", valMax, valLen);
11045  break;
11046  case SQL_SEARCH_PATTERN_ESCAPE:
11047  strmak(val, "\\", valMax, valLen);
11048  break;
11049  case SQL_ODBC_SQL_CONFORMANCE:
11050  *((SQLSMALLINT *) val) = SQL_OSC_MINIMUM;
11051  *valLen = sizeof (SQLSMALLINT);
11052  break;
11053  case SQL_ODBC_API_CONFORMANCE:
11054  *((SQLSMALLINT *) val) = SQL_OAC_LEVEL1;
11055  *valLen = sizeof (SQLSMALLINT);
11056  break;
11057  case SQL_DBMS_NAME:
11058  strmak(val, "SQLite", valMax, valLen);
11059  break;
11060  case SQL_DBMS_VER:
11061  strmak(val, SQLITE_VERSION, valMax, valLen);
11062  break;
11063  case SQL_COLUMN_ALIAS:
11064  case SQL_NEED_LONG_DATA_LEN:
11065  strmak(val, "Y", valMax, valLen);
11066  break;
11067  case SQL_ROW_UPDATES:
11068  case SQL_ACCESSIBLE_PROCEDURES:
11069  case SQL_PROCEDURES:
11070  case SQL_EXPRESSIONS_IN_ORDERBY:
11071  case SQL_ODBC_SQL_OPT_IEF:
11072  case SQL_LIKE_ESCAPE_CLAUSE:
11073  case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11074  case SQL_OUTER_JOINS:
11075  case SQL_ACCESSIBLE_TABLES:
11076  case SQL_MULT_RESULT_SETS:
11077  case SQL_MULTIPLE_ACTIVE_TXN:
11078  case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11079  strmak(val, "N", valMax, valLen);
11080  break;
11081 #ifdef SQL_CATALOG_NAME
11082  case SQL_CATALOG_NAME:
11083 #if defined(_WIN32) || defined(_WIN64)
11084  strmak(val, d->xcelqrx ? "Y" : "N", valMax, valLen);
11085 #else
11086  strmak(val, "N", valMax, valLen);
11087 #endif
11088  break;
11089 #endif
11090  case SQL_DATA_SOURCE_READ_ONLY:
11091  strmak(val, "N", valMax, valLen);
11092  break;
11093 #ifdef SQL_OJ_CAPABILITIES
11094  case SQL_OJ_CAPABILITIES:
11095  *((SQLUINTEGER *) val) = 0;
11096  *valLen = sizeof (SQLUINTEGER);
11097  break;
11098 #endif
11099 #ifdef SQL_MAX_IDENTIFIER_LEN
11100  case SQL_MAX_IDENTIFIER_LEN:
11101  *((SQLUSMALLINT *) val) = 255;
11102  *valLen = sizeof (SQLUSMALLINT);
11103  break;
11104 #endif
11105  case SQL_CONCAT_NULL_BEHAVIOR:
11106  *((SQLSMALLINT *) val) = SQL_CB_NULL;
11107  *valLen = sizeof (SQLSMALLINT);
11108  break;
11109  case SQL_CURSOR_COMMIT_BEHAVIOR:
11110  case SQL_CURSOR_ROLLBACK_BEHAVIOR:
11111  *((SQLSMALLINT *) val) = SQL_CB_PRESERVE;
11112  *valLen = sizeof (SQLSMALLINT);
11113  break;
11114 #ifdef SQL_CURSOR_SENSITIVITY
11115  case SQL_CURSOR_SENSITIVITY:
11116  *((SQLUINTEGER *) val) = SQL_UNSPECIFIED;
11117  *valLen = sizeof (SQLUINTEGER);
11118  break;
11119 #endif
11120  case SQL_DEFAULT_TXN_ISOLATION:
11121  *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11122  *valLen = sizeof (SQLUINTEGER);
11123  break;
11124 #ifdef SQL_DESCRIBE_PARAMETER
11125  case SQL_DESCRIBE_PARAMETER:
11126  strmak(val, "Y", valMax, valLen);
11127  break;
11128 #endif
11129  case SQL_TXN_ISOLATION_OPTION:
11130  *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11131  *valLen = sizeof (SQLUINTEGER);
11132  break;
11133  case SQL_IDENTIFIER_CASE:
11134  *((SQLSMALLINT *) val) = SQL_IC_SENSITIVE;
11135  *valLen = sizeof (SQLSMALLINT);
11136  break;
11137  case SQL_IDENTIFIER_QUOTE_CHAR:
11138  strmak(val, "\"", valMax, valLen);
11139  break;
11140  case SQL_MAX_TABLE_NAME_LEN:
11141  case SQL_MAX_COLUMN_NAME_LEN:
11142  *((SQLSMALLINT *) val) = 255;
11143  *valLen = sizeof (SQLSMALLINT);
11144  break;
11145  case SQL_MAX_CURSOR_NAME_LEN:
11146  *((SQLSMALLINT *) val) = 255;
11147  *valLen = sizeof (SQLSMALLINT);
11148  break;
11149  case SQL_MAX_PROCEDURE_NAME_LEN:
11150  *((SQLSMALLINT *) val) = 0;
11151  break;
11152  case SQL_MAX_QUALIFIER_NAME_LEN:
11153  case SQL_MAX_OWNER_NAME_LEN:
11154  *((SQLSMALLINT *) val) = 255;
11155  break;
11156  case SQL_OWNER_TERM:
11157  strmak(val, "", valMax, valLen);
11158  break;
11159  case SQL_PROCEDURE_TERM:
11160  strmak(val, "PROCEDURE", valMax, valLen);
11161  break;
11162  case SQL_QUALIFIER_NAME_SEPARATOR:
11163  strmak(val, ".", valMax, valLen);
11164  break;
11165  case SQL_QUALIFIER_TERM:
11166 #if defined(_WIN32) || defined(_WIN64)
11167  strmak(val, d->xcelqrx ? "catalog" : "", valMax, valLen);
11168 #else
11169  strmak(val, "", valMax, valLen);
11170 #endif
11171  break;
11172  case SQL_QUALIFIER_USAGE:
11173 #if defined(_WIN32) || defined(_WIN64)
11174  *((SQLUINTEGER *) val) = d->xcelqrx ?
11175  (SQL_CU_DML_STATEMENTS | SQL_CU_INDEX_DEFINITION |
11176  SQL_CU_TABLE_DEFINITION) : 0;
11177 #else
11178  *((SQLUINTEGER *) val) = 0;
11179 #endif
11180  *valLen = sizeof (SQLUINTEGER);
11181  break;
11182  case SQL_SCROLL_CONCURRENCY:
11183  *((SQLUINTEGER *) val) = SQL_SCCO_LOCK;
11184  *valLen = sizeof (SQLUINTEGER);
11185  break;
11186  case SQL_SCROLL_OPTIONS:
11187  *((SQLUINTEGER *) val) = SQL_SO_STATIC | SQL_SO_FORWARD_ONLY;
11188  *valLen = sizeof (SQLUINTEGER);
11189  break;
11190  case SQL_TABLE_TERM:
11191  strmak(val, "TABLE", valMax, valLen);
11192  break;
11193  case SQL_TXN_CAPABLE:
11194  *((SQLSMALLINT *) val) = SQL_TC_ALL;
11195  *valLen = sizeof (SQLSMALLINT);
11196  break;
11197  case SQL_CONVERT_FUNCTIONS:
11198  *((SQLUINTEGER *) val) = 0;
11199  *valLen = sizeof (SQLUINTEGER);
11200  break;
11201  case SQL_SYSTEM_FUNCTIONS:
11202  case SQL_NUMERIC_FUNCTIONS:
11203  case SQL_STRING_FUNCTIONS:
11204  case SQL_TIMEDATE_FUNCTIONS:
11205  *((SQLUINTEGER *) val) = 0;
11206  *valLen = sizeof (SQLUINTEGER);
11207  break;
11208  case SQL_CONVERT_BIGINT:
11209  case SQL_CONVERT_BIT:
11210  case SQL_CONVERT_CHAR:
11211  case SQL_CONVERT_DATE:
11212  case SQL_CONVERT_DECIMAL:
11213  case SQL_CONVERT_DOUBLE:
11214  case SQL_CONVERT_FLOAT:
11215  case SQL_CONVERT_INTEGER:
11216  case SQL_CONVERT_LONGVARCHAR:
11217  case SQL_CONVERT_NUMERIC:
11218  case SQL_CONVERT_REAL:
11219  case SQL_CONVERT_SMALLINT:
11220  case SQL_CONVERT_TIME:
11221  case SQL_CONVERT_TIMESTAMP:
11222  case SQL_CONVERT_TINYINT:
11223  case SQL_CONVERT_VARCHAR:
11224  *((SQLUINTEGER *) val) =
11225  SQL_CVT_CHAR | SQL_CVT_NUMERIC | SQL_CVT_DECIMAL |
11226  SQL_CVT_INTEGER | SQL_CVT_SMALLINT | SQL_CVT_FLOAT | SQL_CVT_REAL |
11227  SQL_CVT_DOUBLE | SQL_CVT_VARCHAR | SQL_CVT_LONGVARCHAR |
11228  SQL_CVT_BIT | SQL_CVT_TINYINT | SQL_CVT_BIGINT |
11229  SQL_CVT_DATE | SQL_CVT_TIME | SQL_CVT_TIMESTAMP;
11230  *valLen = sizeof (SQLUINTEGER);
11231  break;
11232  case SQL_CONVERT_BINARY:
11233  case SQL_CONVERT_VARBINARY:
11234  case SQL_CONVERT_LONGVARBINARY:
11235  *((SQLUINTEGER *) val) = 0;
11236  *valLen = sizeof (SQLUINTEGER);
11237  break;
11238  case SQL_POSITIONED_STATEMENTS:
11239  *((SQLUINTEGER *) val) = 0;
11240  *valLen = sizeof (SQLUINTEGER);
11241  break;
11242  case SQL_LOCK_TYPES:
11243  *((SQLUINTEGER *) val) = SQL_LCK_NO_CHANGE;
11244  *valLen = sizeof (SQLUINTEGER);
11245  break;
11246  case SQL_BOOKMARK_PERSISTENCE:
11247  *((SQLUINTEGER *) val) = SQL_BP_SCROLL;
11248  *valLen = sizeof (SQLUINTEGER);
11249  break;
11250  case SQL_UNION:
11251  *((SQLUINTEGER *) val) = SQL_U_UNION | SQL_U_UNION_ALL;
11252  *valLen = sizeof (SQLUINTEGER);
11253  break;
11254  case SQL_OWNER_USAGE:
11255  case SQL_SUBQUERIES:
11256  case SQL_TIMEDATE_ADD_INTERVALS:
11257  case SQL_TIMEDATE_DIFF_INTERVALS:
11258  *((SQLUINTEGER *) val) = 0;
11259  *valLen = sizeof (SQLUINTEGER);
11260  break;
11261  case SQL_QUOTED_IDENTIFIER_CASE:
11262  *((SQLUSMALLINT *) val) = SQL_IC_SENSITIVE;
11263  *valLen = sizeof (SQLUSMALLINT);
11264  break;
11265  case SQL_POS_OPERATIONS:
11266  *((SQLUINTEGER *) val) = SQL_POS_POSITION | SQL_POS_UPDATE |
11267  SQL_POS_DELETE | SQL_POS_ADD | SQL_POS_REFRESH;
11268  *valLen = sizeof (SQLUINTEGER);
11269  break;
11270  case SQL_ALTER_TABLE:
11271  *((SQLUINTEGER *) val) = 0;
11272  *valLen = sizeof (SQLUINTEGER);
11273  break;
11274  case SQL_CORRELATION_NAME:
11275  *((SQLSMALLINT *) val) = SQL_CN_DIFFERENT;
11276  *valLen = sizeof (SQLSMALLINT);
11277  break;
11278  case SQL_NON_NULLABLE_COLUMNS:
11279  *((SQLSMALLINT *) val) = SQL_NNC_NON_NULL;
11280  *valLen = sizeof (SQLSMALLINT);
11281  break;
11282  case SQL_NULL_COLLATION:
11283  *((SQLSMALLINT *) val) = SQL_NC_START;
11284  *valLen = sizeof (SQLSMALLINT);
11285  break;
11286  case SQL_MAX_COLUMNS_IN_GROUP_BY:
11287  case SQL_MAX_COLUMNS_IN_ORDER_BY:
11288  case SQL_MAX_COLUMNS_IN_SELECT:
11289  case SQL_MAX_COLUMNS_IN_TABLE:
11290  case SQL_MAX_ROW_SIZE:
11291  case SQL_MAX_TABLES_IN_SELECT:
11292  *((SQLSMALLINT *) val) = 0;
11293  *valLen = sizeof (SQLSMALLINT);
11294  break;
11295  case SQL_MAX_BINARY_LITERAL_LEN:
11296  case SQL_MAX_CHAR_LITERAL_LEN:
11297  *((SQLUINTEGER *) val) = 0;
11298  *valLen = sizeof (SQLUINTEGER);
11299  break;
11300  case SQL_MAX_COLUMNS_IN_INDEX:
11301  *((SQLSMALLINT *) val) = 0;
11302  *valLen = sizeof (SQLSMALLINT);
11303  break;
11304  case SQL_MAX_INDEX_SIZE:
11305  *((SQLUINTEGER *) val) = 0;
11306  *valLen = sizeof (SQLUINTEGER);
11307  break;
11308 #ifdef SQL_MAX_IDENTIFIER_LENGTH
11309  case SQL_MAX_IDENTIFIER_LENGTH:
11310  *((SQLUINTEGER *) val) = 255;
11311  *valLen = sizeof (SQLUINTEGER);
11312  break;
11313 #endif
11314  case SQL_MAX_STATEMENT_LEN:
11315  *((SQLUINTEGER *) val) = 16384;
11316  *valLen = sizeof (SQLUINTEGER);
11317  break;
11318  case SQL_QUALIFIER_LOCATION:
11319  *((SQLSMALLINT *) val) = SQL_QL_START;
11320  *valLen = sizeof (SQLSMALLINT);
11321  break;
11322  case SQL_GETDATA_EXTENSIONS:
11323  *((SQLUINTEGER *) val) =
11324  SQL_GD_ANY_COLUMN | SQL_GD_ANY_ORDER | SQL_GD_BOUND;
11325  *valLen = sizeof (SQLUINTEGER);
11326  break;
11327  case SQL_STATIC_SENSITIVITY:
11328  *((SQLUINTEGER *) val) = 0;
11329  *valLen = sizeof (SQLUINTEGER);
11330  break;
11331  case SQL_FILE_USAGE:
11332 #if defined(_WIN32) || defined(_WIN64)
11333  *((SQLSMALLINT *) val) =
11334  d->xcelqrx ? SQL_FILE_CATALOG : SQL_FILE_NOT_SUPPORTED;
11335 #else
11336  *((SQLSMALLINT *) val) = SQL_FILE_NOT_SUPPORTED;
11337 #endif
11338  *valLen = sizeof (SQLSMALLINT);
11339  break;
11340  case SQL_GROUP_BY:
11341  *((SQLSMALLINT *) val) = SQL_GB_GROUP_BY_EQUALS_SELECT;
11342  *valLen = sizeof (SQLSMALLINT);
11343  break;
11344  case SQL_KEYWORDS:
11345  strmak(val, "CREATE,SELECT,DROP,DELETE,UPDATE,INSERT,"
11346  "INTO,VALUES,TABLE,INDEX,FROM,SET,WHERE,AND,CURRENT,OF",
11347  valMax, valLen);
11348  break;
11349  case SQL_SPECIAL_CHARACTERS:
11350 #ifdef SQL_COLLATION_SEQ
11351  case SQL_COLLATION_SEQ:
11352 #endif
11353  strmak(val, "", valMax, valLen);
11354  break;
11355  case SQL_BATCH_SUPPORT:
11356  case SQL_BATCH_ROW_COUNT:
11357  case SQL_PARAM_ARRAY_ROW_COUNTS:
11358  *((SQLUINTEGER *) val) = 0;
11359  *valLen = sizeof (SQLUINTEGER);
11360  break;
11361  case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1:
11362  *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_BOOKMARK;
11363  *valLen = sizeof (SQLUINTEGER);
11364  break;
11365  case SQL_STATIC_CURSOR_ATTRIBUTES1:
11366  *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE |
11367  SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK | SQL_CA1_POS_POSITION |
11368  SQL_CA1_POS_DELETE | SQL_CA1_POS_UPDATE | SQL_CA1_POS_REFRESH |
11369  SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_BULK_ADD |
11370  SQL_CA1_BULK_UPDATE_BY_BOOKMARK | SQL_CA1_BULK_DELETE_BY_BOOKMARK;
11371  *valLen = sizeof (SQLUINTEGER);
11372  break;
11373  case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2:
11374  case SQL_STATIC_CURSOR_ATTRIBUTES2:
11375  *((SQLUINTEGER *) val) = SQL_CA2_READ_ONLY_CONCURRENCY |
11376  SQL_CA2_LOCK_CONCURRENCY;
11377  *valLen = sizeof (SQLUINTEGER);
11378  break;
11379  case SQL_KEYSET_CURSOR_ATTRIBUTES1:
11380  case SQL_KEYSET_CURSOR_ATTRIBUTES2:
11381  case SQL_DYNAMIC_CURSOR_ATTRIBUTES1:
11382  case SQL_DYNAMIC_CURSOR_ATTRIBUTES2:
11383  *((SQLUINTEGER *) val) = 0;
11384  *valLen = sizeof (SQLUINTEGER);
11385  break;
11386  case SQL_ODBC_INTERFACE_CONFORMANCE:
11387  *((SQLUINTEGER *) val) = SQL_OIC_CORE;
11388  *valLen = sizeof (SQLUINTEGER);
11389  break;
11390  default:
11391  setstatd(d, -1, "unsupported info option %d",
11392  (*d->ov3) ? "HYC00" : "S1C00", type);
11393  return SQL_ERROR;
11394  }
11395  return SQL_SUCCESS;
11396 }
11397 
11398 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
11399 
11409 SQLRETURN SQL_API
11410 SQLGetInfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11411  SQLSMALLINT *valLen)
11412 {
11413  SQLRETURN ret;
11414 
11415  HDBC_LOCK(dbc);
11416  ret = drvgetinfo(dbc, type, val, valMax, valLen);
11417  HDBC_UNLOCK(dbc);
11418  return ret;
11419 }
11420 #endif
11421 
11422 #ifdef WINTERFACE
11423 
11433 SQLRETURN SQL_API
11434 SQLGetInfoW(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11435  SQLSMALLINT *valLen)
11436 {
11437  SQLRETURN ret;
11438  SQLSMALLINT len = 0;
11439 
11440  HDBC_LOCK(dbc);
11441  ret = drvgetinfo(dbc, type, val, valMax, &len);
11442  HDBC_UNLOCK(dbc);
11443  if (ret == SQL_SUCCESS) {
11444  SQLWCHAR *v = NULL;
11445 
11446  switch (type) {
11447  case SQL_USER_NAME:
11448  case SQL_DRIVER_ODBC_VER:
11449  case SQL_DATA_SOURCE_NAME:
11450  case SQL_DRIVER_NAME:
11451  case SQL_DRIVER_VER:
11452  case SQL_ODBC_VER:
11453  case SQL_SERVER_NAME:
11454  case SQL_DATABASE_NAME:
11455  case SQL_SEARCH_PATTERN_ESCAPE:
11456  case SQL_DBMS_NAME:
11457  case SQL_DBMS_VER:
11458  case SQL_NEED_LONG_DATA_LEN:
11459  case SQL_ROW_UPDATES:
11460  case SQL_ACCESSIBLE_PROCEDURES:
11461  case SQL_PROCEDURES:
11462  case SQL_EXPRESSIONS_IN_ORDERBY:
11463  case SQL_ODBC_SQL_OPT_IEF:
11464  case SQL_LIKE_ESCAPE_CLAUSE:
11465  case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11466  case SQL_OUTER_JOINS:
11467  case SQL_COLUMN_ALIAS:
11468  case SQL_ACCESSIBLE_TABLES:
11469  case SQL_MULT_RESULT_SETS:
11470  case SQL_MULTIPLE_ACTIVE_TXN:
11471  case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11472  case SQL_DATA_SOURCE_READ_ONLY:
11473 #ifdef SQL_DESCRIBE_PARAMETER
11474  case SQL_DESCRIBE_PARAMETER:
11475 #endif
11476  case SQL_IDENTIFIER_QUOTE_CHAR:
11477  case SQL_OWNER_TERM:
11478  case SQL_PROCEDURE_TERM:
11479  case SQL_QUALIFIER_NAME_SEPARATOR:
11480  case SQL_QUALIFIER_TERM:
11481  case SQL_TABLE_TERM:
11482  case SQL_KEYWORDS:
11483  case SQL_SPECIAL_CHARACTERS:
11484 #ifdef SQL_CATALOG_NAME
11485  case SQL_CATALOG_NAME:
11486 #endif
11487 #ifdef SQL_COLLATION_SEQ
11488  case SQL_COLLATION_SEQ:
11489 #endif
11490  if (val) {
11491  if (len > 0) {
11492  v = uc_from_utf((SQLCHAR *) val, len);
11493  if (v) {
11494  int vmax = valMax / sizeof (SQLWCHAR);
11495 
11496  uc_strncpy(val, v, vmax);
11497  if (len < vmax) {
11498  len = min(vmax, uc_strlen(v));
11499  v[len] = 0;
11500  } else {
11501  len = vmax;
11502  }
11503  uc_free(v);
11504  len *= sizeof (SQLWCHAR);
11505  } else {
11506  len = 0;
11507  }
11508  }
11509  if (len <= 0) {
11510  len = 0;
11511  if (valMax >= sizeof (SQLWCHAR)) {
11512  *((SQLWCHAR *)val) = 0;
11513  }
11514  }
11515  } else {
11516  len *= sizeof (SQLWCHAR);
11517  }
11518  break;
11519  }
11520  if (valLen) {
11521  *valLen = len;
11522  }
11523  }
11524  return ret;
11525 }
11526 #endif
11527 
11536 SQLRETURN SQL_API
11537 SQLGetFunctions(SQLHDBC dbc, SQLUSMALLINT func,
11538  SQLUSMALLINT *flags)
11539 {
11540  int i;
11541  SQLUSMALLINT exists[100];
11542 
11543  if (dbc == SQL_NULL_HDBC) {
11544  return SQL_INVALID_HANDLE;
11545  }
11546  for (i = 0; i < array_size(exists); i++) {
11547  exists[i] = SQL_FALSE;
11548  }
11549  exists[SQL_API_SQLALLOCCONNECT] = SQL_TRUE;
11550  exists[SQL_API_SQLFETCH] = SQL_TRUE;
11551  exists[SQL_API_SQLALLOCENV] = SQL_TRUE;
11552  exists[SQL_API_SQLFREECONNECT] = SQL_TRUE;
11553  exists[SQL_API_SQLALLOCSTMT] = SQL_TRUE;
11554  exists[SQL_API_SQLFREEENV] = SQL_TRUE;
11555  exists[SQL_API_SQLBINDCOL] = SQL_TRUE;
11556  exists[SQL_API_SQLFREESTMT] = SQL_TRUE;
11557  exists[SQL_API_SQLCANCEL] = SQL_TRUE;
11558  exists[SQL_API_SQLGETCURSORNAME] = SQL_TRUE;
11559  exists[SQL_API_SQLCOLATTRIBUTES] = SQL_TRUE;
11560  exists[SQL_API_SQLNUMRESULTCOLS] = SQL_TRUE;
11561  exists[SQL_API_SQLCONNECT] = SQL_TRUE;
11562  exists[SQL_API_SQLPREPARE] = SQL_TRUE;
11563  exists[SQL_API_SQLDESCRIBECOL] = SQL_TRUE;
11564  exists[SQL_API_SQLROWCOUNT] = SQL_TRUE;
11565  exists[SQL_API_SQLDISCONNECT] = SQL_TRUE;
11566  exists[SQL_API_SQLSETCURSORNAME] = SQL_FALSE;
11567  exists[SQL_API_SQLERROR] = SQL_TRUE;
11568  exists[SQL_API_SQLSETPARAM] = SQL_TRUE;
11569  exists[SQL_API_SQLEXECDIRECT] = SQL_TRUE;
11570  exists[SQL_API_SQLTRANSACT] = SQL_TRUE;
11571  exists[SQL_API_SQLBULKOPERATIONS] = SQL_TRUE;
11572  exists[SQL_API_SQLEXECUTE] = SQL_TRUE;
11573  exists[SQL_API_SQLBINDPARAMETER] = SQL_TRUE;
11574  exists[SQL_API_SQLGETTYPEINFO] = SQL_TRUE;
11575  exists[SQL_API_SQLCOLUMNS] = SQL_TRUE;
11576  exists[SQL_API_SQLPARAMDATA] = SQL_TRUE;
11577  exists[SQL_API_SQLDRIVERCONNECT] = SQL_TRUE;
11578  exists[SQL_API_SQLPUTDATA] = SQL_TRUE;
11579  exists[SQL_API_SQLGETCONNECTOPTION] = SQL_TRUE;
11580  exists[SQL_API_SQLSETCONNECTOPTION] = SQL_TRUE;
11581  exists[SQL_API_SQLGETDATA] = SQL_TRUE;
11582  exists[SQL_API_SQLSETSTMTOPTION] = SQL_TRUE;
11583  exists[SQL_API_SQLGETFUNCTIONS] = SQL_TRUE;
11584  exists[SQL_API_SQLSPECIALCOLUMNS] = SQL_TRUE;
11585  exists[SQL_API_SQLGETINFO] = SQL_TRUE;
11586  exists[SQL_API_SQLSTATISTICS] = SQL_TRUE;
11587  exists[SQL_API_SQLGETSTMTOPTION] = SQL_TRUE;
11588  exists[SQL_API_SQLTABLES] = SQL_TRUE;
11589  exists[SQL_API_SQLBROWSECONNECT] = SQL_FALSE;
11590  exists[SQL_API_SQLNUMPARAMS] = SQL_TRUE;
11591  exists[SQL_API_SQLCOLUMNPRIVILEGES] = SQL_FALSE;
11592  exists[SQL_API_SQLPARAMOPTIONS] = SQL_FALSE;
11593  exists[SQL_API_SQLDATASOURCES] = SQL_TRUE;
11594  exists[SQL_API_SQLPRIMARYKEYS] = SQL_TRUE;
11595  exists[SQL_API_SQLDESCRIBEPARAM] = SQL_TRUE;
11596  exists[SQL_API_SQLPROCEDURECOLUMNS] = SQL_TRUE;
11597  exists[SQL_API_SQLDRIVERS] = SQL_FALSE;
11598  exists[SQL_API_SQLPROCEDURES] = SQL_TRUE;
11599  exists[SQL_API_SQLEXTENDEDFETCH] = SQL_TRUE;
11600  exists[SQL_API_SQLSETPOS] = SQL_TRUE;
11601  exists[SQL_API_SQLFOREIGNKEYS] = SQL_TRUE;
11602  exists[SQL_API_SQLSETSCROLLOPTIONS] = SQL_TRUE;
11603  exists[SQL_API_SQLMORERESULTS] = SQL_TRUE;
11604  exists[SQL_API_SQLTABLEPRIVILEGES] = SQL_TRUE;
11605  exists[SQL_API_SQLNATIVESQL] = SQL_TRUE;
11606  if (func == SQL_API_ALL_FUNCTIONS) {
11607  memcpy(flags, exists, sizeof (exists));
11608  } else if (func == SQL_API_ODBC3_ALL_FUNCTIONS) {
11609  int i;
11610 #define SET_EXISTS(x) \
11611  flags[(x) >> 4] |= (1 << ((x) & 0xF))
11612 #define CLR_EXISTS(x) \
11613  flags[(x) >> 4] &= ~(1 << ((x) & 0xF))
11614 
11615  memset(flags, 0,
11616  sizeof (SQLUSMALLINT) * SQL_API_ODBC3_ALL_FUNCTIONS_SIZE);
11617  for (i = 0; i < array_size(exists); i++) {
11618  if (exists[i]) {
11619  flags[i >> 4] |= (1 << (i & 0xF));
11620  }
11621  }
11622  SET_EXISTS(SQL_API_SQLALLOCHANDLE);
11623  SET_EXISTS(SQL_API_SQLFREEHANDLE);
11624  SET_EXISTS(SQL_API_SQLGETSTMTATTR);
11625  SET_EXISTS(SQL_API_SQLSETSTMTATTR);
11626  SET_EXISTS(SQL_API_SQLGETCONNECTATTR);
11627  SET_EXISTS(SQL_API_SQLSETCONNECTATTR);
11628  SET_EXISTS(SQL_API_SQLGETENVATTR);
11629  SET_EXISTS(SQL_API_SQLSETENVATTR);
11630  SET_EXISTS(SQL_API_SQLCLOSECURSOR);
11631  SET_EXISTS(SQL_API_SQLBINDPARAM);
11632 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11633  /*
11634  * Some unixODBC versions have problems with
11635  * SQLError() vs. SQLGetDiagRec() with loss
11636  * of error/warning messages.
11637  */
11638  SET_EXISTS(SQL_API_SQLGETDIAGREC);
11639 #endif
11640  SET_EXISTS(SQL_API_SQLGETDIAGFIELD);
11641  SET_EXISTS(SQL_API_SQLFETCHSCROLL);
11642  SET_EXISTS(SQL_API_SQLENDTRAN);
11643  } else {
11644  if (func < array_size(exists)) {
11645  *flags = exists[func];
11646  } else {
11647  switch (func) {
11648  case SQL_API_SQLALLOCHANDLE:
11649  case SQL_API_SQLFREEHANDLE:
11650  case SQL_API_SQLGETSTMTATTR:
11651  case SQL_API_SQLSETSTMTATTR:
11652  case SQL_API_SQLGETCONNECTATTR:
11653  case SQL_API_SQLSETCONNECTATTR:
11654  case SQL_API_SQLGETENVATTR:
11655  case SQL_API_SQLSETENVATTR:
11656  case SQL_API_SQLCLOSECURSOR:
11657  case SQL_API_SQLBINDPARAM:
11658 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11659  /*
11660  * Some unixODBC versions have problems with
11661  * SQLError() vs. SQLGetDiagRec() with loss
11662  * of error/warning messages.
11663  */
11664  case SQL_API_SQLGETDIAGREC:
11665 #endif
11666  case SQL_API_SQLGETDIAGFIELD:
11667  case SQL_API_SQLFETCHSCROLL:
11668  case SQL_API_SQLENDTRAN:
11669  *flags = SQL_TRUE;
11670  break;
11671  default:
11672  *flags = SQL_FALSE;
11673  }
11674  }
11675  }
11676  return SQL_SUCCESS;
11677 }
11678 
11685 static SQLRETURN
11686 drvallocenv(SQLHENV *env)
11687 {
11688  ENV *e;
11689 
11690  if (env == NULL) {
11691  return SQL_INVALID_HANDLE;
11692  }
11693  e = (ENV *) xmalloc(sizeof (ENV));
11694  if (e == NULL) {
11695  *env = SQL_NULL_HENV;
11696  return SQL_ERROR;
11697  }
11698  e->magic = ENV_MAGIC;
11699  e->ov3 = 0;
11700  e->pool = 0;
11701 #if defined(_WIN32) || defined(_WIN64)
11702  InitializeCriticalSection(&e->cs);
11703 #else
11704 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
11705  nvfs_init();
11706 #endif
11707 #endif
11708  e->dbcs = NULL;
11709  *env = (SQLHENV) e;
11710  return SQL_SUCCESS;
11711 }
11712 
11719 SQLRETURN SQL_API
11720 SQLAllocEnv(SQLHENV *env)
11721 {
11722  return drvallocenv(env);
11723 }
11724 
11731 static SQLRETURN
11732 drvfreeenv(SQLHENV env)
11733 {
11734  ENV *e;
11735 
11736  if (env == SQL_NULL_HENV) {
11737  return SQL_INVALID_HANDLE;
11738  }
11739  e = (ENV *) env;
11740  if (e->magic != ENV_MAGIC) {
11741  return SQL_SUCCESS;
11742  }
11743 #if defined(_WIN32) || defined(_WIN64)
11744  EnterCriticalSection(&e->cs);
11745 #endif
11746  if (e->dbcs) {
11747 #if defined(_WIN32) || defined(_WIN64)
11748  LeaveCriticalSection(&e->cs);
11749 #endif
11750  return SQL_ERROR;
11751  }
11752  e->magic = DEAD_MAGIC;
11753 #if defined(_WIN32) || defined(_WIN64)
11754  LeaveCriticalSection(&e->cs);
11755  DeleteCriticalSection(&e->cs);
11756 #endif
11757  xfree(e);
11758  return SQL_SUCCESS;
11759 }
11760 
11767 SQLRETURN SQL_API
11768 SQLFreeEnv(SQLHENV env)
11769 {
11770  return drvfreeenv(env);
11771 }
11772 
11780 static SQLRETURN
11781 drvallocconnect(SQLHENV env, SQLHDBC *dbc)
11782 {
11783  DBC *d;
11784  ENV *e;
11785  const char *verstr;
11786  int maj = 0, min = 0, lev = 0;
11787 
11788  if (dbc == NULL) {
11789  return SQL_ERROR;
11790  }
11791  d = (DBC *) xmalloc(sizeof (DBC));
11792  if (d == NULL) {
11793  *dbc = SQL_NULL_HDBC;
11794  return SQL_ERROR;
11795  }
11796  memset(d, 0, sizeof (DBC));
11797  d->curtype = SQL_CURSOR_STATIC;
11798  d->ov3 = &d->ov3val;
11799  verstr = sqlite3_libversion();
11800  sscanf(verstr, "%d.%d.%d", &maj, &min, &lev);
11801  d->version = verinfo(maj & 0xFF, min & 0xFF, lev & 0xFF);
11802  e = (ENV *) env;
11803 #if defined(_WIN32) || defined(_WIN64)
11804  if (e->magic == ENV_MAGIC) {
11805  EnterCriticalSection(&e->cs);
11806  }
11807 #endif
11808  if (e->magic == ENV_MAGIC) {
11809  DBC *n, *p;
11810 
11811  d->env = e;
11812  d->ov3 = &e->ov3;
11813  p = NULL;
11814  n = e->dbcs;
11815  while (n) {
11816  p = n;
11817  n = n->next;
11818  }
11819  if (p) {
11820  p->next = d;
11821  } else {
11822  e->dbcs = d;
11823  }
11824  }
11825 #if defined(_WIN32) || defined(_WIN64)
11826  InitializeCriticalSection(&d->cs);
11827  d->owner = 0;
11828  if (e->magic == ENV_MAGIC) {
11829  LeaveCriticalSection(&e->cs);
11830  }
11831  d->oemcp = 1;
11832 #endif
11833  d->autocommit = 1;
11834  d->magic = DBC_MAGIC;
11835  *dbc = (SQLHDBC) d;
11836  drvgetgpps(d);
11837  return SQL_SUCCESS;
11838 }
11839 
11847 SQLRETURN SQL_API
11848 SQLAllocConnect(SQLHENV env, SQLHDBC *dbc)
11849 {
11850  return drvallocconnect(env, dbc);
11851 }
11852 
11859 static SQLRETURN
11861 {
11862  DBC *d;
11863  ENV *e;
11864  SQLRETURN ret = SQL_ERROR;
11865 
11866  if (dbc == SQL_NULL_HDBC) {
11867  return SQL_INVALID_HANDLE;
11868  }
11869  d = (DBC *) dbc;
11870  if (d->magic != DBC_MAGIC) {
11871  return SQL_INVALID_HANDLE;
11872  }
11873  e = d->env;
11874  if (e && e->magic == ENV_MAGIC) {
11875 #if defined(_WIN32) || defined(_WIN64)
11876  EnterCriticalSection(&e->cs);
11877 #endif
11878  } else {
11879  e = NULL;
11880  }
11881  HDBC_LOCK(dbc);
11882  if (d->sqlite) {
11883  setstatd(d, -1, "not disconnected", (*d->ov3) ? "HY000" : "S1000");
11884  HDBC_UNLOCK(dbc);
11885  goto done;
11886  }
11887  while (d->stmt) {
11888  freestmt((HSTMT) d->stmt);
11889  }
11890  if (e && e->magic == ENV_MAGIC) {
11891  DBC *n, *p;
11892 
11893  p = NULL;
11894  n = e->dbcs;
11895  while (n) {
11896  if (n == d) {
11897  break;
11898  }
11899  p = n;
11900  n = n->next;
11901  }
11902  if (n) {
11903  if (p) {
11904  p->next = d->next;
11905  } else {
11906  e->dbcs = d->next;
11907  }
11908  }
11909  }
11910  drvrelgpps(d);
11911  d->magic = DEAD_MAGIC;
11912  if (d->trace) {
11913  fclose(d->trace);
11914  }
11915 #if defined(_WIN32) || defined(_WIN64)
11916  d->owner = 0;
11917  LeaveCriticalSection(&d->cs);
11918  DeleteCriticalSection(&d->cs);
11919 #endif
11920  xfree(d);
11921  ret = SQL_SUCCESS;
11922 done:
11923 #if defined(_WIN32) || defined(_WIN64)
11924  if (e) {
11925  LeaveCriticalSection(&e->cs);
11926  }
11927 #endif
11928  return ret;
11929 }
11930 
11937 SQLRETURN SQL_API
11939 {
11940  return drvfreeconnect(dbc);
11941 }
11942 
11953 static SQLRETURN
11954 drvgetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
11955  SQLINTEGER bufmax, SQLINTEGER *buflen)
11956 {
11957  DBC *d;
11958  SQLINTEGER dummy;
11959 
11960  if (dbc == SQL_NULL_HDBC) {
11961  return SQL_INVALID_HANDLE;
11962  }
11963  d = (DBC *) dbc;
11964  if (!val) {
11965  val = (SQLPOINTER) &dummy;
11966  }
11967  if (!buflen) {
11968  buflen = &dummy;
11969  }
11970  switch (attr) {
11971  case SQL_ATTR_CONNECTION_DEAD:
11972  *((SQLINTEGER *) val) = d->sqlite ? SQL_CD_FALSE : SQL_CD_TRUE;
11973  *buflen = sizeof (SQLINTEGER);
11974  break;
11975  case SQL_ATTR_ACCESS_MODE:
11976  *((SQLINTEGER *) val) = SQL_MODE_READ_WRITE;
11977  *buflen = sizeof (SQLINTEGER);
11978  break;
11979  case SQL_ATTR_AUTOCOMMIT:
11980  *((SQLINTEGER *) val) =
11981  d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
11982  *buflen = sizeof (SQLINTEGER);
11983  break;
11984  case SQL_ATTR_LOGIN_TIMEOUT:
11985  *((SQLINTEGER *) val) = 100;
11986  *buflen = sizeof (SQLINTEGER);
11987  break;
11988  case SQL_ATTR_ODBC_CURSORS:
11989  *((SQLINTEGER *) val) = SQL_CUR_USE_DRIVER;
11990  *buflen = sizeof (SQLINTEGER);
11991  break;
11992  case SQL_ATTR_PACKET_SIZE:
11993  *((SQLINTEGER *) val) = 16384;
11994  *buflen = sizeof (SQLINTEGER);
11995  break;
11996  case SQL_ATTR_TXN_ISOLATION:
11997  *((SQLINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11998  *buflen = sizeof (SQLINTEGER);
11999  break;
12000  case SQL_ATTR_TRACEFILE:
12001  case SQL_ATTR_TRANSLATE_LIB:
12002  *((SQLCHAR *) val) = 0;
12003  *buflen = 0;
12004  break;
12005  case SQL_ATTR_CURRENT_CATALOG:
12006 #if defined(_WIN32) || defined(_WIN64)
12007  if (d->xcelqrx) {
12008  if ((bufmax > 4) && (val != (SQLPOINTER) &dummy)) {
12009  strcpy((char *) val, "main");
12010  *buflen = 4;
12011  break;
12012  }
12013  }
12014 #endif
12015  *((SQLCHAR *) val) = 0;
12016  *buflen = 0;
12017  break;
12018  case SQL_ATTR_TRACE:
12019  case SQL_ATTR_QUIET_MODE:
12020  case SQL_ATTR_TRANSLATE_OPTION:
12021  case SQL_ATTR_KEYSET_SIZE:
12022  case SQL_ATTR_QUERY_TIMEOUT:
12023  *((SQLINTEGER *) val) = 0;
12024  *buflen = sizeof (SQLINTEGER);
12025  break;
12026  case SQL_ATTR_PARAM_BIND_TYPE:
12027  *((SQLULEN *) val) = SQL_PARAM_BIND_BY_COLUMN;
12028  *buflen = sizeof (SQLUINTEGER);
12029  break;
12030  case SQL_ATTR_ROW_BIND_TYPE:
12031  *((SQLULEN *) val) = SQL_BIND_BY_COLUMN;
12032  *buflen = sizeof (SQLULEN);
12033  break;
12034  case SQL_ATTR_USE_BOOKMARKS:
12035  *((SQLINTEGER *) val) = SQL_UB_OFF;
12036  *buflen = sizeof (SQLINTEGER);
12037  break;
12038  case SQL_ATTR_ASYNC_ENABLE:
12039  *((SQLINTEGER *) val) = SQL_ASYNC_ENABLE_OFF;
12040  *buflen = sizeof (SQLINTEGER);
12041  break;
12042  case SQL_ATTR_NOSCAN:
12043  *((SQLINTEGER *) val) = SQL_NOSCAN_ON;
12044  *buflen = sizeof (SQLINTEGER);
12045  break;
12046  case SQL_ATTR_CONCURRENCY:
12047  *((SQLINTEGER *) val) = SQL_CONCUR_LOCK;
12048  *buflen = sizeof (SQLINTEGER);
12049  break;
12050 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
12051  case SQL_ATTR_CURSOR_SENSITIVITY:
12052  *((SQLINTEGER *) val) = SQL_UNSPECIFIED;
12053  *buflen = sizeof (SQLINTEGER);
12054  break;
12055 #endif
12056  case SQL_ATTR_SIMULATE_CURSOR:
12057  *((SQLINTEGER *) val) = SQL_SC_NON_UNIQUE;
12058  *buflen = sizeof (SQLINTEGER);
12059  break;
12060  case SQL_ATTR_MAX_ROWS:
12061  *((SQLINTEGER *) val) = 0;
12062  *buflen = sizeof (SQLINTEGER);
12063  case SQL_ATTR_MAX_LENGTH:
12064  *((SQLINTEGER *) val) = 1000000000;
12065  *buflen = sizeof (SQLINTEGER);
12066  break;
12067  case SQL_ATTR_CURSOR_TYPE:
12068  *((SQLINTEGER *) val) = d->curtype;
12069  *buflen = sizeof (SQLINTEGER);
12070  break;
12071  case SQL_ATTR_RETRIEVE_DATA:
12072  *((SQLINTEGER *) val) = SQL_RD_ON;
12073  *buflen = sizeof (SQLINTEGER);
12074  break;
12075 #ifdef SQL_ATTR_METADATA_ID
12076  case SQL_ATTR_METADATA_ID:
12077  *((SQLULEN *) val) = SQL_FALSE;
12078  return SQL_SUCCESS;
12079 #endif
12080  default:
12081  *((SQLINTEGER *) val) = 0;
12082  *buflen = sizeof (SQLINTEGER);
12083  setstatd(d, -1, "unsupported connect attribute %d",
12084  (*d->ov3) ? "HYC00" : "S1C00", (int) attr);
12085  return SQL_ERROR;
12086  }
12087  return SQL_SUCCESS;
12088 }
12089 
12090 #ifndef WINTERFACE
12091 
12101 SQLRETURN SQL_API
12102 SQLGetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12103  SQLINTEGER bufmax, SQLINTEGER *buflen)
12104 {
12105  SQLRETURN ret;
12106 
12107  HDBC_LOCK(dbc);
12108  ret = drvgetconnectattr(dbc, attr, val, bufmax, buflen);
12109  HDBC_UNLOCK(dbc);
12110  return ret;
12111 }
12112 #endif
12113 
12114 #ifdef WINTERFACE
12115 
12125 SQLRETURN SQL_API
12126 SQLGetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12127  SQLINTEGER bufmax, SQLINTEGER *buflen)
12128 {
12129  SQLRETURN ret;
12130  SQLINTEGER len = 0;
12131 
12132  HDBC_LOCK(dbc);
12133  ret = drvgetconnectattr(dbc, attr, val, bufmax, &len);
12134  if (ret == SQL_SUCCESS) {
12135  SQLWCHAR *v = NULL;
12136 
12137  switch (attr) {
12138  case SQL_ATTR_TRACEFILE:
12139  case SQL_ATTR_CURRENT_CATALOG:
12140  case SQL_ATTR_TRANSLATE_LIB:
12141  if (val) {
12142  if (len > 0) {
12143  v = uc_from_utf((SQLCHAR *) val, len);
12144  if (v) {
12145  int vmax = bufmax / sizeof (SQLWCHAR);
12146 
12147  uc_strncpy(val, v, vmax);
12148  if (len < vmax) {
12149  len = min(vmax, uc_strlen(v));
12150  v[len] = 0;
12151  } else {
12152  len = vmax;
12153  }
12154  uc_free(v);
12155  len *= sizeof (SQLWCHAR);
12156  } else {
12157  len = 0;
12158  }
12159  }
12160  if (len <= 0) {
12161  len = 0;
12162  if (bufmax >= sizeof (SQLWCHAR)) {
12163  *((SQLWCHAR *)val) = 0;
12164  }
12165  }
12166  } else {
12167  len *= sizeof (SQLWCHAR);
12168  }
12169  break;
12170  }
12171  if (buflen) {
12172  *buflen = len;
12173  }
12174  }
12175  HDBC_UNLOCK(dbc);
12176  return ret;
12177 }
12178 #endif
12179 
12189 static SQLRETURN
12190 drvsetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12191  SQLINTEGER len)
12192 {
12193  DBC *d;
12194 
12195  if (dbc == SQL_NULL_HDBC) {
12196  return SQL_INVALID_HANDLE;
12197  }
12198  d = (DBC *) dbc;
12199  switch (attr) {
12200  case SQL_AUTOCOMMIT:
12201  d->autocommit = val == (SQLPOINTER) SQL_AUTOCOMMIT_ON;
12202  if (d->autocommit && d->intrans) {
12203  return endtran(d, SQL_COMMIT, 1);
12204  } else if (!d->autocommit) {
12205  s3stmt_end(d->cur_s3stmt);
12206  }
12207  break;
12208  return SQL_SUCCESS;
12209 #ifdef SQL_ATTR_METADATA_ID
12210  case SQL_ATTR_METADATA_ID:
12211  if (val == (SQLPOINTER) SQL_FALSE) {
12212  break;
12213  }
12214  /* fall through */
12215 #endif
12216  default:
12217  setstatd(d, -1, "option value changed", "01S02");
12218  return SQL_SUCCESS_WITH_INFO;
12219  }
12220  return SQL_SUCCESS;
12221 }
12222 
12223 #ifndef WINTERFACE
12224 
12233 SQLRETURN SQL_API
12234 SQLSetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12235  SQLINTEGER len)
12236 {
12237  SQLRETURN ret;
12238 
12239  HDBC_LOCK(dbc);
12240  ret = drvsetconnectattr(dbc, attr, val, len);
12241  HDBC_UNLOCK(dbc);
12242  return ret;
12243 }
12244 #endif
12245 
12246 #ifdef WINTERFACE
12247 
12256 SQLRETURN SQL_API
12257 SQLSetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12258  SQLINTEGER len)
12259 {
12260  SQLRETURN ret;
12261 
12262  HDBC_LOCK(dbc);
12263  ret = drvsetconnectattr(dbc, attr, val, len);
12264  HDBC_UNLOCK(dbc);
12265  return ret;
12266 }
12267 #endif
12268 
12277 static SQLRETURN
12278 drvgetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12279 {
12280  DBC *d;
12281  SQLINTEGER dummy;
12282 
12283  if (dbc == SQL_NULL_HDBC) {
12284  return SQL_INVALID_HANDLE;
12285  }
12286  d = (DBC *) dbc;
12287  if (!param) {
12288  param = (SQLPOINTER) &dummy;
12289  }
12290  switch (opt) {
12291  case SQL_ACCESS_MODE:
12292  *((SQLINTEGER *) param) = SQL_MODE_READ_WRITE;
12293  break;
12294  case SQL_AUTOCOMMIT:
12295  *((SQLINTEGER *) param) =
12296  d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
12297  break;
12298  case SQL_LOGIN_TIMEOUT:
12299  *((SQLINTEGER *) param) = 100;
12300  break;
12301  case SQL_ODBC_CURSORS:
12302  *((SQLINTEGER *) param) = SQL_CUR_USE_DRIVER;
12303  break;
12304  case SQL_PACKET_SIZE:
12305  *((SQLINTEGER *) param) = 16384;
12306  break;
12307  case SQL_TXN_ISOLATION:
12308  *((SQLINTEGER *) param) = SQL_TXN_SERIALIZABLE;
12309  break;
12310  case SQL_OPT_TRACE:
12311  case SQL_OPT_TRACEFILE:
12312  case SQL_QUIET_MODE:
12313  case SQL_TRANSLATE_DLL:
12314  case SQL_TRANSLATE_OPTION:
12315  case SQL_KEYSET_SIZE:
12316  case SQL_QUERY_TIMEOUT:
12317  case SQL_BIND_TYPE:
12318  case SQL_CURRENT_QUALIFIER:
12319  *((SQLINTEGER *) param) = 0;
12320  break;
12321  case SQL_USE_BOOKMARKS:
12322  *((SQLINTEGER *) param) = SQL_UB_OFF;
12323  break;
12324  case SQL_ASYNC_ENABLE:
12325  *((SQLINTEGER *) param) = SQL_ASYNC_ENABLE_OFF;
12326  break;
12327  case SQL_NOSCAN:
12328  *((SQLINTEGER *) param) = SQL_NOSCAN_ON;
12329  break;
12330  case SQL_CONCURRENCY:
12331  *((SQLINTEGER *) param) = SQL_CONCUR_LOCK;
12332  break;
12333  case SQL_SIMULATE_CURSOR:
12334  *((SQLINTEGER *) param) = SQL_SC_NON_UNIQUE;
12335  break;
12336  case SQL_MAX_ROWS:
12337  *((SQLINTEGER *) param) = 0;
12338  break;
12339  case SQL_ROWSET_SIZE:
12340  case SQL_MAX_LENGTH:
12341  *((SQLINTEGER *) param) = 1000000000;
12342  break;
12343  case SQL_CURSOR_TYPE:
12344  *((SQLINTEGER *) param) = d->curtype;
12345  break;
12346  case SQL_RETRIEVE_DATA:
12347  *((SQLINTEGER *) param) = SQL_RD_ON;
12348  break;
12349  default:
12350  *((SQLINTEGER *) param) = 0;
12351  setstatd(d, -1, "unsupported connect option %d",
12352  (*d->ov3) ? "HYC00" : "S1C00", opt);
12353  return SQL_ERROR;
12354  }
12355  return SQL_SUCCESS;
12356 }
12357 
12358 #ifndef WINTERFACE
12359 
12367 SQLRETURN SQL_API
12368 SQLGetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12369 {
12370  SQLRETURN ret;
12371 
12372  HDBC_LOCK(dbc);
12373  ret = drvgetconnectoption(dbc, opt, param);
12374  HDBC_UNLOCK(dbc);
12375  return ret;
12376 }
12377 #endif
12378 
12379 #ifdef WINTERFACE
12380 
12388 SQLRETURN SQL_API
12389 SQLGetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12390 {
12391  SQLRETURN ret;
12392 
12393  HDBC_LOCK(dbc);
12394  ret = drvgetconnectoption(dbc, opt, param);
12395  if (SQL_SUCCEEDED(ret)) {
12396  switch (opt) {
12397  case SQL_OPT_TRACEFILE:
12398  case SQL_CURRENT_QUALIFIER:
12399  case SQL_TRANSLATE_DLL:
12400  if (param) {
12401  *(SQLWCHAR *) param = 0;
12402  }
12403  break;
12404  }
12405  }
12406  HDBC_UNLOCK(dbc);
12407  return ret;
12408 }
12409 #endif
12410 
12419 static SQLRETURN
12420 drvsetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
12421 {
12422  DBC *d;
12423 
12424  if (dbc == SQL_NULL_HDBC) {
12425  return SQL_INVALID_HANDLE;
12426  }
12427  d = (DBC *) dbc;
12428  switch (opt) {
12429  case SQL_AUTOCOMMIT:
12430  d->autocommit = param == SQL_AUTOCOMMIT_ON;
12431  if (d->autocommit && d->intrans) {
12432  return endtran(d, SQL_COMMIT, 1);
12433  } else if (!d->autocommit) {
12434  s3stmt_end(d->cur_s3stmt);
12435  }
12436  break;
12437  default:
12438  setstatd(d, -1, "option value changed", "01S02");
12439  return SQL_SUCCESS_WITH_INFO;
12440  }
12441  return SQL_SUCCESS;
12442 }
12443 
12444 #ifndef WINTERFACE
12445 
12453 SQLRETURN SQL_API
12454 SQLSetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12455 {
12456  SQLRETURN ret;
12457 
12458  HDBC_LOCK(dbc);
12459  ret = drvsetconnectoption(dbc, opt, param);
12460  HDBC_UNLOCK(dbc);
12461  return ret;
12462 }
12463 #endif
12464 
12465 #ifdef WINTERFACE
12466 
12474 SQLRETURN SQL_API
12475 SQLSetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12476 {
12477  SQLRETURN ret;
12478 
12479  HDBC_LOCK(dbc);
12480  ret = drvsetconnectoption(dbc, opt, param);
12481  HDBC_UNLOCK(dbc);
12482  return ret;
12483 }
12484 #endif
12485 
12486 #if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
12487 
12498 static int
12499 getdsnattr(char *dsn, char *attr, char *out, int outLen)
12500 {
12501  char *str = dsn, *start;
12502  int len = strlen(attr);
12503 
12504  while (*str) {
12505  while (*str && *str == ';') {
12506  ++str;
12507  }
12508  start = str;
12509  if ((str = strchr(str, '=')) == NULL) {
12510  return 0;
12511  }
12512  if (str - start == len && strncasecmp(start, attr, len) == 0) {
12513  start = ++str;
12514  while (*str && *str != ';') {
12515  ++str;
12516  }
12517  len = min(outLen - 1, str - start);
12518  strncpy(out, start, len);
12519  out[len] = '\0';
12520  return 1;
12521  }
12522  while (*str && *str != ';') {
12523  ++str;
12524  }
12525  }
12526  return 0;
12527 }
12528 #endif
12529 
12541 static SQLRETURN
12542 drvconnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen, char *pwd,
12543  int pwdLen, int isu)
12544 {
12545  DBC *d;
12546  int len;
12547  SQLRETURN ret;
12548  char buf[SQL_MAX_MESSAGE_LENGTH * 6], dbname[SQL_MAX_MESSAGE_LENGTH];
12549  char busy[SQL_MAX_MESSAGE_LENGTH / 4], tracef[SQL_MAX_MESSAGE_LENGTH];
12550  char loadext[SQL_MAX_MESSAGE_LENGTH];
12551  char sflag[32], spflag[32], ntflag[32], nwflag[32], biflag[32];
12552  char snflag[32], lnflag[32], ncflag[32], fkflag[32], jmode[32];
12553  char jdflag[32];
12554 #if defined(_WIN32) || defined(_WIN64)
12555  char oemcp[32];
12556 #endif
12557 
12558  if (dbc == SQL_NULL_HDBC) {
12559  return SQL_INVALID_HANDLE;
12560  }
12561  d = (DBC *) dbc;
12562  if (d->magic != DBC_MAGIC) {
12563  return SQL_INVALID_HANDLE;
12564  }
12565  if (d->sqlite != NULL) {
12566  setstatd(d, -1, "connection already established", "08002");
12567  return SQL_ERROR;
12568  }
12569  buf[0] = '\0';
12570  if (dsnLen == SQL_NTS) {
12571  len = sizeof (buf) - 1;
12572  } else {
12573  len = min(sizeof (buf) - 1, dsnLen);
12574  }
12575  if (dsn != NULL) {
12576  strncpy(buf, (char *) dsn, len);
12577  }
12578  buf[len] = '\0';
12579  if (buf[0] == '\0') {
12580  setstatd(d, -1, "invalid DSN", (*d->ov3) ? "HY090" : "S1090");
12581  return SQL_ERROR;
12582  }
12583 #if defined(_WIN32) || defined(_WIN64)
12584  /*
12585  * When DSN is in UTF it must be converted to ANSI
12586  * here for ANSI SQLGetPrivateProfileString()
12587  */
12588  if (isu) {
12589  char *cdsn = utf_to_wmb(buf, len);
12590 
12591  if (!cdsn) {
12592  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12593  return SQL_ERROR;
12594  }
12595  strcpy(buf, cdsn);
12596  uc_free(cdsn);
12597  }
12598 #endif
12599  busy[0] = '\0';
12600  dbname[0] = '\0';
12601 #ifdef WITHOUT_DRIVERMGR
12602  getdsnattr(buf, "database", dbname, sizeof (dbname));
12603  if (dbname[0] == '\0') {
12604  strncpy(dbname, buf, sizeof (dbname));
12605  dbname[sizeof (dbname) - 1] = '\0';
12606  }
12607  getdsnattr(buf, "timeout", busy, sizeof (busy));
12608  sflag[0] = '\0';
12609  getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
12610  spflag[0] = '\0';
12611  getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
12612  ntflag[0] = '\0';
12613  getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
12614  nwflag[0] = '\0';
12615  getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
12616  snflag[0] = '\0';
12617  getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
12618  lnflag[0] = '\0';
12619  getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
12620  ncflag[0] = '\0';
12621  getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
12622  fkflag[0] = '\0';
12623  getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
12624  loadext[0] = '\0';
12625  getdsnattr(buf, "loadext", loadext, sizeof (loadext));
12626  jmode[0] = '\0';
12627  getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
12628  jdflag[0] = '\0';
12629  getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
12630 #if defined(_WIN32) || defined(_WIN64)
12631  oemcp[0] = '\0';
12632  getdsnattr(buf, "oemcp", oemcp, sizeof (oemcp));
12633 #endif
12634  biflag[0] = '\0';
12635  getdsnattr(buf, "bigint", biflag, sizeof (biflag));
12636 #else
12637  SQLGetPrivateProfileString(buf, "timeout", "100000",
12638  busy, sizeof (busy), ODBC_INI);
12639  SQLGetPrivateProfileString(buf, "database", "",
12640  dbname, sizeof (dbname), ODBC_INI);
12641 #if defined(_WIN32) || defined(_WIN64)
12642  /* database name read from registry is not UTF8 !!! */
12643  isu = 0;
12644 #endif
12645  SQLGetPrivateProfileString(buf, "stepapi", "",
12646  sflag, sizeof (sflag), ODBC_INI);
12647  SQLGetPrivateProfileString(buf, "syncpragma", "NORMAL",
12648  spflag, sizeof (spflag), ODBC_INI);
12649  SQLGetPrivateProfileString(buf, "notxn", "",
12650  ntflag, sizeof (ntflag), ODBC_INI);
12651  SQLGetPrivateProfileString(buf, "nowchar", "",
12652  nwflag, sizeof (nwflag), ODBC_INI);
12653  SQLGetPrivateProfileString(buf, "shortnames", "",
12654  snflag, sizeof (snflag), ODBC_INI);
12655  SQLGetPrivateProfileString(buf, "longnames", "",
12656  lnflag, sizeof (lnflag), ODBC_INI);
12657  SQLGetPrivateProfileString(buf, "nocreat", "",
12658  ncflag, sizeof (ncflag), ODBC_INI);
12659  SQLGetPrivateProfileString(buf, "fksupport", "",
12660  fkflag, sizeof (fkflag), ODBC_INI);
12661  SQLGetPrivateProfileString(buf, "loadext", "",
12662  loadext, sizeof (loadext), ODBC_INI);
12663  SQLGetPrivateProfileString(buf, "journalmode", "",
12664  jmode, sizeof (jmode), ODBC_INI);
12665  SQLGetPrivateProfileString(buf, "jdconv", "",
12666  jdflag, sizeof (jdflag), ODBC_INI);
12667 #if defined(_WIN32) || defined(_WIN64)
12668  SQLGetPrivateProfileString(buf, "oemcp", "1",
12669  oemcp, sizeof (oemcp), ODBC_INI);
12670 #endif
12671  SQLGetPrivateProfileString(buf, "bigint", "",
12672  biflag, sizeof (biflag), ODBC_INI);
12673 #endif
12674  tracef[0] = '\0';
12675 #ifdef WITHOUT_DRIVERMGR
12676  getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
12677 #else
12678  SQLGetPrivateProfileString(buf, "tracefile", "",
12679  tracef, sizeof (tracef), ODBC_INI);
12680 #endif
12681  if (tracef[0] != '\0') {
12682  d->trace = fopen(tracef, "a");
12683  }
12684  d->nowchar = getbool(nwflag);
12685  d->shortnames = getbool(snflag);
12686  d->longnames = getbool(lnflag);
12687  d->nocreat = getbool(ncflag);
12688  d->fksupport = getbool(fkflag);
12689  d->jdconv = getbool(jdflag);
12690 #if defined(_WIN32) || defined(_WIN64)
12691  d->oemcp = getbool(oemcp);
12692 #else
12693  d->oemcp = 0;
12694 #endif
12695  d->dobigint = getbool(biflag);
12696  d->pwd = pwd;
12697  d->pwdLen = 0;
12698  if (d->pwd) {
12699  d->pwdLen = (pwdLen == SQL_NTS) ? strlen(d->pwd) : pwdLen;
12700  }
12701  ret = dbopen(d, dbname, isu, (char *) dsn, sflag, spflag, ntflag,
12702  jmode, busy);
12703  if (ret == SQL_SUCCESS) {
12704  dbloadext(d, loadext);
12705  }
12706  return ret;
12707 }
12708 
12709 #ifndef WINTERFACE
12710 
12722 SQLRETURN SQL_API
12723 SQLConnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen,
12724  SQLCHAR *uid, SQLSMALLINT uidLen,
12725  SQLCHAR *pwd, SQLSMALLINT pwdLen)
12726 {
12727  SQLRETURN ret;
12728 
12729  HDBC_LOCK(dbc);
12730  ret = drvconnect(dbc, dsn, dsnLen, (char *) pwd, pwdLen, 0);
12731  HDBC_UNLOCK(dbc);
12732  return ret;
12733 }
12734 #endif
12735 
12736 #ifdef WINTERFACE
12737 
12749 SQLRETURN SQL_API
12750 SQLConnectW(SQLHDBC dbc, SQLWCHAR *dsn, SQLSMALLINT dsnLen,
12751  SQLWCHAR *uid, SQLSMALLINT uidLen,
12752  SQLWCHAR *pwd, SQLSMALLINT pwdLen)
12753 {
12754  char *dsna = NULL;
12755  char *pwda = NULL;
12756  SQLRETURN ret;
12757 
12758  HDBC_LOCK(dbc);
12759  if (dsn) {
12760  dsna = uc_to_utf_c(dsn, dsnLen);
12761  if (!dsna) {
12762  DBC *d = (DBC *) dbc;
12763 
12764  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12765  ret = SQL_ERROR;
12766  goto done;
12767  }
12768  }
12769  if (pwd) {
12770  pwda = uc_to_utf_c(pwd, pwdLen);
12771  if (!pwda) {
12772  DBC *d = (DBC *) dbc;
12773 
12774  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12775  ret = SQL_ERROR;
12776  goto done;
12777  }
12778  }
12779  ret = drvconnect(dbc, (SQLCHAR *) dsna, SQL_NTS, pwda, SQL_NTS, 1);
12780 done:
12781  HDBC_UNLOCK(dbc);
12782  uc_free(dsna);
12783  uc_free(pwda);
12784  return ret;
12785 }
12786 #endif
12787 
12794 static SQLRETURN
12796 {
12797  DBC *d;
12798  int rc;
12799 
12800  if (dbc == SQL_NULL_HDBC) {
12801  return SQL_INVALID_HANDLE;
12802  }
12803  d = (DBC *) dbc;
12804  if (d->magic != DBC_MAGIC) {
12805  return SQL_INVALID_HANDLE;
12806  }
12807  if (d->intrans) {
12808  setstatd(d, -1, "incomplete transaction", "25000");
12809  return SQL_ERROR;
12810  }
12811  if (d->cur_s3stmt) {
12812  s3stmt_end(d->cur_s3stmt);
12813  }
12814  if (d->sqlite) {
12815  if (d->trace) {
12816  fprintf(d->trace, "-- sqlite3_close: '%s'\n",
12817  d->dbname);
12818  fflush(d->trace);
12819  }
12820  rc = sqlite3_close(d->sqlite);
12821  if (rc == SQLITE_BUSY) {
12822  setstatd(d, -1, "unfinished statements", "25000");
12823  return SQL_ERROR;
12824  }
12825  d->sqlite = NULL;
12826  }
12827  freep(&d->dbname);
12828  freep(&d->dsn);
12829  return SQL_SUCCESS;
12830 }
12831 
12838 SQLRETURN SQL_API
12840 {
12841  SQLRETURN ret;
12842 
12843  HDBC_LOCK(dbc);
12844  ret = drvdisconnect(dbc);
12845  HDBC_UNLOCK(dbc);
12846  return ret;
12847 }
12848 
12849 #if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
12850 
12864 static SQLRETURN
12865 drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
12866  SQLCHAR *connIn, SQLSMALLINT connInLen,
12867  SQLCHAR *connOut, SQLSMALLINT connOutMax,
12868  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
12869 {
12870  DBC *d;
12871  int len;
12872  SQLRETURN ret;
12873  char buf[SQL_MAX_MESSAGE_LENGTH * 8], dbname[SQL_MAX_MESSAGE_LENGTH];
12874  char dsn[SQL_MAX_MESSAGE_LENGTH], busy[SQL_MAX_MESSAGE_LENGTH / 4];
12875  char tracef[SQL_MAX_MESSAGE_LENGTH], loadext[SQL_MAX_MESSAGE_LENGTH];
12876  char pwd[SQL_MAX_MESSAGE_LENGTH];
12877  char sflag[32], spflag[32], ntflag[32], snflag[32], lnflag[32];
12878  char ncflag[32], nwflag[32], fkflag[32], jmode[32], biflag[32];
12879  char jdflag[32];
12880 
12881  if (dbc == SQL_NULL_HDBC) {
12882  return SQL_INVALID_HANDLE;
12883  }
12884  if (drvcompl != SQL_DRIVER_COMPLETE &&
12885  drvcompl != SQL_DRIVER_COMPLETE_REQUIRED &&
12886  drvcompl != SQL_DRIVER_PROMPT &&
12887  drvcompl != SQL_DRIVER_NOPROMPT) {
12888  return SQL_NO_DATA;
12889  }
12890  d = (DBC *) dbc;
12891  if (d->sqlite) {
12892  setstatd(d, -1, "connection already established", "08002");
12893  return SQL_ERROR;
12894  }
12895  buf[0] = '\0';
12896  if (connInLen == SQL_NTS) {
12897  len = sizeof (buf) - 1;
12898  } else {
12899  len = min(connInLen, sizeof (buf) - 1);
12900  }
12901  if (connIn != NULL) {
12902  strncpy(buf, (char *) connIn, len);
12903  }
12904  buf[len] = '\0';
12905  if (!buf[0]) {
12906  setstatd(d, -1, "invalid connect attributes",
12907  (*d->ov3) ? "HY090" : "S1090");
12908  return SQL_ERROR;
12909  }
12910  dsn[0] = '\0';
12911  getdsnattr(buf, "DSN", dsn, sizeof (dsn));
12912 
12913  /* special case: connIn is sole DSN value without keywords */
12914  if (!dsn[0] && !strchr(buf, ';') && !strchr(buf, '=')) {
12915  strncpy(dsn, buf, sizeof (dsn) - 1);
12916  dsn[sizeof (dsn) - 1] = '\0';
12917  }
12918 
12919  busy[0] = '\0';
12920  getdsnattr(buf, "timeout", busy, sizeof (busy));
12921 #ifndef WITHOUT_DRIVERMGR
12922  if (dsn[0] && !busy[0]) {
12923  SQLGetPrivateProfileString(dsn, "timeout", "100000",
12924  busy, sizeof (busy), ODBC_INI);
12925  }
12926 #endif
12927  dbname[0] = '\0';
12928  getdsnattr(buf, "database", dbname, sizeof (dbname));
12929 #ifndef WITHOUT_DRIVERMGR
12930  if (dsn[0] && !dbname[0]) {
12931  SQLGetPrivateProfileString(dsn, "database", "",
12932  dbname, sizeof (dbname), ODBC_INI);
12933  }
12934 #endif
12935  sflag[0] = '\0';
12936  getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
12937 #ifndef WITHOUT_DRIVERMGR
12938  if (dsn[0] && !sflag[0]) {
12939  SQLGetPrivateProfileString(dsn, "stepapi", "",
12940  sflag, sizeof (sflag), ODBC_INI);
12941  }
12942 #endif
12943  spflag[0] = '\0';
12944  getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
12945 #ifndef WITHOUT_DRIVERMGR
12946  if (dsn[0] && !spflag[0]) {
12947  SQLGetPrivateProfileString(dsn, "syncpragma", "NORMAL",
12948  spflag, sizeof (spflag), ODBC_INI);
12949  }
12950 #endif
12951  ntflag[0] = '\0';
12952  getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
12953 #ifndef WITHOUT_DRIVERMGR
12954  if (dsn[0] && !ntflag[0]) {
12955  SQLGetPrivateProfileString(dsn, "notxn", "",
12956  ntflag, sizeof (ntflag), ODBC_INI);
12957  }
12958 #endif
12959  snflag[0] = '\0';
12960  getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
12961 #ifndef WITHOUT_DRIVERMGR
12962  if (dsn[0] && !snflag[0]) {
12963  SQLGetPrivateProfileString(dsn, "shortnames", "",
12964  snflag, sizeof (snflag), ODBC_INI);
12965  }
12966 #endif
12967  lnflag[0] = '\0';
12968  getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
12969 #ifndef WITHOUT_DRIVERMGR
12970  if (dsn[0] && !lnflag[0]) {
12971  SQLGetPrivateProfileString(dsn, "longnames", "",
12972  lnflag, sizeof (lnflag), ODBC_INI);
12973  }
12974 #endif
12975  ncflag[0] = '\0';
12976  getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
12977 #ifndef WITHOUT_DRIVERMGR
12978  if (dsn[0] && !ncflag[0]) {
12979  SQLGetPrivateProfileString(dsn, "nocreat", "",
12980  ncflag, sizeof (ncflag), ODBC_INI);
12981  }
12982 #endif
12983  nwflag[0] = '\0';
12984  getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
12985 #ifndef WITHOUT_DRIVERMGR
12986  if (dsn[0] && !nwflag[0]) {
12987  SQLGetPrivateProfileString(dsn, "nowchar", "",
12988  nwflag, sizeof (nwflag), ODBC_INI);
12989  }
12990 #endif
12991  fkflag[0] = '\0';
12992  getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
12993 #ifndef WITHOUT_DRIVERMGR
12994  if (dsn[0] && !fkflag[0]) {
12995  SQLGetPrivateProfileString(dsn, "fksupport", "",
12996  fkflag, sizeof (fkflag), ODBC_INI);
12997  }
12998 #endif
12999  loadext[0] = '\0';
13000  getdsnattr(buf, "loadext", loadext, sizeof (loadext));
13001 #ifndef WITHOUT_DRIVERMGR
13002  if (dsn[0] && !loadext[0]) {
13003  SQLGetPrivateProfileString(dsn, "loadext", "",
13004  loadext, sizeof (loadext), ODBC_INI);
13005  }
13006 #endif
13007  jmode[0] = '\0';
13008  getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
13009 #ifndef WITHOUT_DRIVERMGR
13010  if (dsn[0] && !jmode[0]) {
13011  SQLGetPrivateProfileString(dsn, "journalmode", "",
13012  jmode, sizeof (jmode), ODBC_INI);
13013  }
13014 #endif
13015  biflag[0] = '\0';
13016  getdsnattr(buf, "bigint", biflag, sizeof (biflag));
13017 #ifndef WITHOUT_DRIVERMGR
13018  if (dsn[0] && !biflag[0]) {
13019  SQLGetPrivateProfileString(dsn, "bigint", "",
13020  biflag, sizeof (biflag), ODBC_INI);
13021  }
13022 #endif
13023  jdflag[0] = '\0';
13024  getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
13025 #ifndef WITHOUT_DRIVERMGR
13026  if (dsn[0] && !jdflag[0]) {
13027  SQLGetPrivateProfileString(dsn, "jdconv", "",
13028  jdflag, sizeof (jdflag), ODBC_INI);
13029  }
13030 #endif
13031  pwd[0] = '\0';
13032  getdsnattr(buf, "pwd", pwd, sizeof (pwd));
13033 #ifndef WITHOUT_DRIVERMGR
13034  if (dsn[0] && !pwd[0]) {
13035  SQLGetPrivateProfileString(dsn, "pwd", "",
13036  pwd, sizeof (pwd), ODBC_INI);
13037  }
13038 #endif
13039 
13040  if (!dbname[0] && !dsn[0]) {
13041  strcpy(dsn, "SQLite");
13042  strncpy(dbname, buf, sizeof (dbname));
13043  dbname[sizeof (dbname) - 1] = '\0';
13044  }
13045  tracef[0] = '\0';
13046  getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
13047 #ifndef WITHOUT_DRIVERMGR
13048  if (dsn[0] && !tracef[0]) {
13049  SQLGetPrivateProfileString(dsn, "tracefile", "",
13050  tracef, sizeof (tracef), ODBC_INI);
13051  }
13052 #endif
13053  if (connOut || connOutLen) {
13054  int count;
13055 
13056  buf[0] = '\0';
13057  count = snprintf(buf, sizeof (buf),
13058  "DSN=%s;Database=%s;StepAPI=%s;Timeout=%s;"
13059  "SyncPragma=%s;NoTXN=%s;ShortNames=%s;LongNames=%s;"
13060  "NoCreat=%s;NoWCHAR=%s;FKSupport=%s;Tracefile=%s;"
13061  "JournalMode=%s;LoadExt=%s;BigInt=%s;JDConv=%s;"
13062  "PWD=%s",
13063  dsn, dbname, sflag, busy, spflag, ntflag,
13064  snflag, lnflag, ncflag, nwflag, fkflag, tracef,
13065  jmode, loadext, biflag, jdflag, pwd);
13066  if (count < 0) {
13067  buf[sizeof (buf) - 1] = '\0';
13068  }
13069  len = min(connOutMax - 1, strlen(buf));
13070  if (connOut) {
13071  strncpy((char *) connOut, buf, len);
13072  connOut[len] = '\0';
13073  }
13074  if (connOutLen) {
13075  *connOutLen = len;
13076  }
13077  }
13078  if (tracef[0] != '\0') {
13079  d->trace = fopen(tracef, "a");
13080  }
13081  d->shortnames = getbool(snflag);
13082  d->longnames = getbool(lnflag);
13083  d->nocreat = getbool(ncflag);
13084  d->nowchar = getbool(nwflag);
13085  d->fksupport = getbool(fkflag);
13086  d->dobigint = getbool(biflag);
13087  d->jdconv = getbool(jdflag);
13088  d->oemcp = 0;
13089  d->pwdLen = strlen(pwd);
13090  d->pwd = (d->pwdLen > 0) ? pwd : NULL;
13091  ret = dbopen(d, dbname, 0, dsn, sflag, spflag, ntflag, jmode, busy);
13092  memset(pwd, 0, sizeof (pwd));
13093  if (ret == SQL_SUCCESS) {
13094  dbloadext(d, loadext);
13095  }
13096  return ret;
13097 }
13098 #endif
13099 
13106 static SQLRETURN
13107 freestmt(SQLHSTMT stmt)
13108 {
13109  STMT *s;
13110  DBC *d;
13111 
13112  if (stmt == SQL_NULL_HSTMT) {
13113  return SQL_INVALID_HANDLE;
13114  }
13115  s = (STMT *) stmt;
13116  s3stmt_drop(s);
13117  freeresult(s, 1);
13118  freep(&s->query);
13119  d = (DBC *) s->dbc;
13120  if (d && d->magic == DBC_MAGIC) {
13121  STMT *p, *n;
13122 
13123  p = NULL;
13124  n = d->stmt;
13125  while (n) {
13126  if (n == s) {
13127  break;
13128  }
13129  p = n;
13130  n = n->next;
13131  }
13132  if (n) {
13133  if (p) {
13134  p->next = s->next;
13135  } else {
13136  d->stmt = s->next;
13137  }
13138  }
13139  }
13140  freeparams(s);
13141  freep(&s->bindparms);
13142  if (s->row_status0 != &s->row_status1) {
13143  freep(&s->row_status0);
13144  s->rowset_size = 1;
13145  s->row_status0 = &s->row_status1;
13146  }
13147  xfree(s);
13148  return SQL_SUCCESS;
13149 }
13150 
13158 static SQLRETURN
13159 drvallocstmt(SQLHDBC dbc, SQLHSTMT *stmt)
13160 {
13161  DBC *d;
13162  STMT *s, *sl, *pl;
13163 
13164  if (dbc == SQL_NULL_HDBC) {
13165  return SQL_INVALID_HANDLE;
13166  }
13167  d = (DBC *) dbc;
13168  if (d->magic != DBC_MAGIC || stmt == NULL) {
13169  return SQL_INVALID_HANDLE;
13170  }
13171  s = (STMT *) xmalloc(sizeof (STMT));
13172  if (s == NULL) {
13173  *stmt = SQL_NULL_HSTMT;
13174  return SQL_ERROR;
13175  }
13176  *stmt = (SQLHSTMT) s;
13177  memset(s, 0, sizeof (STMT));
13178  s->dbc = dbc;
13179  s->ov3 = d->ov3;
13180  s->bkmrk = SQL_UB_OFF;
13181  s->bkmrkptr = 0;
13182  s->oemcp = &d->oemcp;
13183  s->jdconv = &d->jdconv;
13184  s->nowchar[0] = d->nowchar;
13185  s->nowchar[1] = 0;
13186  s->dobigint = d->dobigint;
13187  s->curtype = d->curtype;
13188  s->row_status0 = &s->row_status1;
13189  s->rowset_size = 1;
13190  s->longnames = d->longnames;
13191  s->retr_data = SQL_RD_ON;
13192  s->max_rows = 0;
13193  s->bind_type = SQL_BIND_BY_COLUMN;
13194  s->bind_offs = NULL;
13195  s->paramset_size = 1;
13196  s->parm_bind_type = SQL_PARAM_BIND_BY_COLUMN;
13197  s->one_tbl = -1;
13198  s->has_pk = -1;
13199  s->has_rowid = -1;
13200 #ifdef _WIN64
13201  sprintf((char *) s->cursorname, "CUR_%I64X", (SQLUBIGINT) *stmt);
13202 #else
13203  sprintf((char *) s->cursorname, "CUR_%016lX", (long) *stmt);
13204 #endif
13205  sl = d->stmt;
13206  pl = NULL;
13207  while (sl) {
13208  pl = sl;
13209  sl = sl->next;
13210  }
13211  if (pl) {
13212  pl->next = s;
13213  } else {
13214  d->stmt = s;
13215  }
13216  return SQL_SUCCESS;
13217 }
13218 
13226 SQLRETURN SQL_API
13227 SQLAllocStmt(SQLHDBC dbc, SQLHSTMT *stmt)
13228 {
13229  SQLRETURN ret;
13230 
13231  HDBC_LOCK(dbc);
13232  ret = drvallocstmt(dbc, stmt);
13233  HDBC_UNLOCK(dbc);
13234  return ret;
13235 }
13236 
13244 static SQLRETURN
13245 drvfreestmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13246 {
13247  STMT *s;
13248  SQLRETURN ret = SQL_SUCCESS;
13249  SQLHDBC dbc;
13250 
13251  if (stmt == SQL_NULL_HSTMT) {
13252  return SQL_INVALID_HANDLE;
13253  }
13254  HSTMT_LOCK(stmt);
13255  s = (STMT *) stmt;
13256  dbc = s->dbc;
13257  switch (opt) {
13258  case SQL_RESET_PARAMS:
13259  freeparams(s);
13260  break;
13261  case SQL_UNBIND:
13262  unbindcols(s);
13263  break;
13264  case SQL_CLOSE:
13265  s3stmt_end_if(s);
13266  freeresult(s, 0);
13267  break;
13268  case SQL_DROP:
13269  s3stmt_end_if(s);
13270  ret = freestmt(stmt);
13271  break;
13272  default:
13273  setstat(s, -1, "unsupported option", (*s->ov3) ? "HYC00" : "S1C00");
13274  ret = SQL_ERROR;
13275  break;
13276  }
13277  HDBC_UNLOCK(dbc);
13278  return ret;
13279 }
13280 
13288 SQLRETURN SQL_API
13289 SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13290 {
13291  return drvfreestmt(stmt, opt);
13292 }
13293 
13300 SQLRETURN SQL_API
13301 SQLCancel(SQLHSTMT stmt)
13302 {
13303  if (stmt != SQL_NULL_HSTMT) {
13304  DBC *d = (DBC *) ((STMT *) stmt)->dbc;
13305 #if defined(_WIN32) || defined(_WIN64)
13306  /* interrupt when other thread owns critical section */
13307  if (d->magic == DBC_MAGIC && d->owner != GetCurrentThreadId() &&
13308  d->owner != 0) {
13309  d->busyint = 1;
13310  sqlite3_interrupt(d->sqlite);
13311  return SQL_SUCCESS;
13312  }
13313 #else
13314  if (d->magic == DBC_MAGIC) {
13315  d->busyint = 1;
13316  sqlite3_interrupt(d->sqlite);
13317  }
13318 #endif
13319  }
13320  return drvfreestmt(stmt, SQL_CLOSE);
13321 }
13322 
13332 static SQLRETURN
13333 drvgetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13334  SQLSMALLINT *lenp)
13335 {
13336  STMT *s;
13337 
13338  if (stmt == SQL_NULL_HSTMT) {
13339  return SQL_INVALID_HANDLE;
13340  }
13341  s = (STMT *) stmt;
13342  if (lenp && !cursor) {
13343  *lenp = strlen((char *) s->cursorname);
13344  return SQL_SUCCESS;
13345  }
13346  if (cursor) {
13347  if (buflen > 0) {
13348  strncpy((char *) cursor, (char *) s->cursorname, buflen - 1);
13349  cursor[buflen - 1] = '\0';
13350  }
13351  if (lenp) {
13352  *lenp = min(strlen((char *) s->cursorname), buflen - 1);
13353  }
13354  }
13355  return SQL_SUCCESS;
13356 }
13357 
13358 #ifndef WINTERFACE
13359 
13368 SQLRETURN SQL_API
13369 SQLGetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13370  SQLSMALLINT *lenp)
13371 {
13372  SQLRETURN ret;
13373 #if defined(_WIN32) || defined(_WIN64)
13374  SQLSMALLINT len = 0;
13375 #endif
13376 
13377  HSTMT_LOCK(stmt);
13378 #if defined(_WIN32) || defined(_WIN64)
13379  if (!((STMT *) stmt)->oemcp[0]) {
13380  ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13381  goto done;
13382  }
13383  ret = drvgetcursorname(stmt, cursor, buflen, &len);
13384  if (ret == SQL_SUCCESS) {
13385  char *c = NULL;
13386 
13387  if (cursor) {
13388  c = utf_to_wmb((char *) cursor, len);
13389  if (!c) {
13390  ret = nomem((STMT *) stmt);
13391  goto done;
13392  }
13393  c[len] = 0;
13394  len = strlen(c);
13395  if (buflen > 0) {
13396  strncpy((char *) cursor, c, buflen - 1);
13397  cursor[buflen - 1] = 0;
13398  }
13399  uc_free(c);
13400  }
13401  if (lenp) {
13402  *lenp = min(len, buflen - 1);
13403  }
13404  }
13405 done:
13406  ;
13407 #else
13408  ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13409 #endif
13410  HSTMT_UNLOCK(stmt);
13411  return ret;
13412 }
13413 #endif
13414 
13415 #ifdef WINTERFACE
13416 
13425 SQLRETURN SQL_API
13426 SQLGetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT buflen,
13427  SQLSMALLINT *lenp)
13428 {
13429  SQLRETURN ret;
13430  SQLSMALLINT len = 0;
13431 
13432  HSTMT_LOCK(stmt);
13433  ret = drvgetcursorname(stmt, (SQLCHAR *) cursor, buflen, &len);
13434  if (ret == SQL_SUCCESS) {
13435  SQLWCHAR *c = NULL;
13436 
13437  if (cursor) {
13438  c = uc_from_utf((SQLCHAR *) cursor, len);
13439  if (!c) {
13440  ret = nomem((STMT *) stmt);
13441  goto done;
13442  }
13443  c[len] = 0;
13444  len = uc_strlen(c);
13445  if (buflen > 0) {
13446  uc_strncpy(cursor, c, buflen - 1);
13447  cursor[buflen - 1] = 0;
13448  }
13449  uc_free(c);
13450  }
13451  if (lenp) {
13452  *lenp = min(len, buflen - 1);
13453  }
13454  }
13455 done:
13456  HSTMT_UNLOCK(stmt);
13457  return ret;
13458 }
13459 #endif
13460 
13469 static SQLRETURN
13470 drvsetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13471 {
13472  STMT *s;
13473 
13474  if (stmt == SQL_NULL_HSTMT) {
13475  return SQL_INVALID_HANDLE;
13476  }
13477  s = (STMT *) stmt;
13478  if (!cursor ||
13479  !((cursor[0] >= 'A' && cursor[0] <= 'Z') ||
13480  (cursor[0] >= 'a' && cursor[0] <= 'z'))) {
13481  setstat(s, -1, "invalid cursor name", (*s->ov3) ? "HYC00" : "S1C00");
13482  return SQL_ERROR;
13483  }
13484  if (len == SQL_NTS) {
13485  len = sizeof (s->cursorname) - 1;
13486  } else {
13487  len = min(sizeof (s->cursorname) - 1, len);
13488  }
13489  strncpy((char *) s->cursorname, (char *) cursor, len);
13490  s->cursorname[len] = '\0';
13491  return SQL_SUCCESS;
13492 }
13493 
13494 #ifndef WINTERFACE
13495 
13503 SQLRETURN SQL_API
13504 SQLSetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13505 {
13506 #if defined(_WIN32) || defined(_WIN64)
13507  char *c = NULL;
13508 #endif
13509  SQLRETURN ret;
13510 
13511  HSTMT_LOCK(stmt);
13512 #if defined(_WIN32) || defined(_WIN64)
13513  if (!((STMT *) stmt)->oemcp[0]) {
13514  ret = drvsetcursorname(stmt, cursor, len);
13515  goto done2;
13516  }
13517  if (cursor) {
13518  c = wmb_to_utf_c((char *) cursor, len);
13519  if (!c) {
13520  ret = nomem((STMT *) stmt);
13521  goto done;
13522  }
13523  }
13524  ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13525 #else
13526  ret = drvsetcursorname(stmt, cursor, len);
13527 #endif
13528 #if defined(_WIN32) || defined(_WIN64)
13529 done:
13530  uc_free(c);
13531 done2:
13532  ;
13533 #endif
13534  HSTMT_UNLOCK(stmt);
13535  return ret;
13536 }
13537 #endif
13538 
13539 #ifdef WINTERFACE
13540 
13548 SQLRETURN SQL_API
13549 SQLSetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT len)
13550 {
13551  char *c = NULL;
13552  SQLRETURN ret;
13553 
13554  HSTMT_LOCK(stmt);
13555  if (cursor) {
13556  c = uc_to_utf_c(cursor, len);
13557  if (!c) {
13558  ret = nomem((STMT *) stmt);
13559  goto done;
13560  }
13561  }
13562  ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13563 done:
13564  uc_free(c);
13565  HSTMT_UNLOCK(stmt);
13566  return ret;
13567 }
13568 #endif
13569 
13576 SQLRETURN SQL_API
13578 {
13579  return drvfreestmt(stmt, SQL_CLOSE);
13580 }
13581 
13590 SQLRETURN SQL_API
13591 SQLAllocHandle(SQLSMALLINT type, SQLHANDLE input, SQLHANDLE *output)
13592 {
13593  SQLRETURN ret;
13594 
13595  switch (type) {
13596  case SQL_HANDLE_ENV:
13597  ret = drvallocenv((SQLHENV *) output);
13598  if (ret == SQL_SUCCESS) {
13599  ENV *e = (ENV *) *output;
13600 
13601  if (e && e->magic == ENV_MAGIC) {
13602  e->ov3 = 1;
13603  }
13604  }
13605  return ret;
13606  case SQL_HANDLE_DBC:
13607  return drvallocconnect((SQLHENV) input, (SQLHDBC *) output);
13608  case SQL_HANDLE_STMT:
13609  HDBC_LOCK((SQLHDBC) input);
13610  ret = drvallocstmt((SQLHDBC) input, (SQLHSTMT *) output);
13611  HDBC_UNLOCK((SQLHDBC) input);
13612  return ret;
13613  }
13614  return SQL_ERROR;
13615 }
13616 
13624 SQLRETURN SQL_API
13625 SQLFreeHandle(SQLSMALLINT type, SQLHANDLE h)
13626 {
13627  switch (type) {
13628  case SQL_HANDLE_ENV:
13629  return drvfreeenv((SQLHENV) h);
13630  case SQL_HANDLE_DBC:
13631  return drvfreeconnect((SQLHDBC) h);
13632  case SQL_HANDLE_STMT:
13633  return drvfreestmt((SQLHSTMT) h, SQL_DROP);
13634  }
13635  return SQL_ERROR;
13636 }
13637 
13643 static void
13645 {
13646  if (s->dyncols) {
13647  int i;
13648 
13649  for (i = 0; i < s->dcols; i++) {
13650  freep(&s->dyncols[i].typename);
13651  }
13652  if (s->cols == s->dyncols) {
13653  s->cols = NULL;
13654  s->ncols = 0;
13655  }
13656  freep(&s->dyncols);
13657  }
13658  s->dcols = 0;
13659 }
13660 
13672 static void
13673 freeresult(STMT *s, int clrcols)
13674 {
13675  freep(&s->bincache);
13676  s->bincell = NULL;
13677  s->binlen = 0;
13678  if (s->rows) {
13679  if (s->rowfree) {
13680  s->rowfree(s->rows);
13681  s->rowfree = NULL;
13682  }
13683  s->rows = NULL;
13684  }
13685  s->nrows = -1;
13686  if (clrcols > 0) {
13687  freep(&s->bindcols);
13688  s->nbindcols = 0;
13689  }
13690  if (clrcols) {
13691  freedyncols(s);
13692  s->cols = NULL;
13693  s->ncols = 0;
13694  s->nowchar[1] = 0;
13695  s->one_tbl = -1;
13696  s->has_pk = -1;
13697  s->has_rowid = -1;
13698  }
13699 }
13700 
13706 static void
13708 {
13709  int i;
13710 
13711  for (i = 0; s->bindcols && i < s->nbindcols; i++) {
13712  s->bindcols[i].type = SQL_UNKNOWN_TYPE;
13713  s->bindcols[i].max = 0;
13714  s->bindcols[i].lenp = NULL;
13715  s->bindcols[i].valp = NULL;
13716  s->bindcols[i].index = i;
13717  s->bindcols[i].offs = 0;
13718  }
13719 }
13720 
13728 static SQLRETURN
13729 mkbindcols(STMT *s, int ncols)
13730 {
13731  if (s->bindcols) {
13732  if (s->nbindcols < ncols) {
13733  int i;
13734  BINDCOL *bindcols =
13735  xrealloc(s->bindcols, ncols * sizeof (BINDCOL));
13736 
13737  if (!bindcols) {
13738  return nomem(s);
13739  }
13740  for (i = s->nbindcols; i < ncols; i++) {
13741  bindcols[i].type = SQL_UNKNOWN_TYPE;
13742  bindcols[i].max = 0;
13743  bindcols[i].lenp = NULL;
13744  bindcols[i].valp = NULL;
13745  bindcols[i].index = i;
13746  bindcols[i].offs = 0;
13747  }
13748  s->bindcols = bindcols;
13749  s->nbindcols = ncols;
13750  }
13751  } else if (ncols > 0) {
13752  s->bindcols = (BINDCOL *) xmalloc(ncols * sizeof (BINDCOL));
13753  if (!s->bindcols) {
13754  return nomem(s);
13755  }
13756  s->nbindcols = ncols;
13757  unbindcols(s);
13758  }
13759  return SQL_SUCCESS;
13760 }
13761 
13775 static SQLRETURN
13776 getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype,
13777  SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp, int partial)
13778 {
13779  char **data, valdummy[16];
13780  SQLLEN dummy;
13781  SQLINTEGER *ilenp = NULL;
13782  int valnull = 0;
13783  int type = otype;
13784  SQLRETURN sret = SQL_NO_DATA;
13785 
13786  if (!lenp) {
13787  lenp = &dummy;
13788  }
13789  /* workaround for JDK 1.7.0 on x86_64 */
13790  if (((SQLINTEGER *) lenp) + 1 == (SQLINTEGER *) val) {
13791  ilenp = (SQLINTEGER *) lenp;
13792  lenp = &dummy;
13793  }
13794  if (col >= s->ncols) {
13795  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
13796  return SQL_ERROR;
13797  }
13798  if (s->retr_data != SQL_RD_ON) {
13799  return SQL_SUCCESS;
13800  }
13801  if (!s->rows) {
13802  *lenp = SQL_NULL_DATA;
13803  goto done;
13804  }
13805  if (s->rowp < 0 || s->rowp >= s->nrows) {
13806  *lenp = SQL_NULL_DATA;
13807  goto done;
13808  }
13809  type = mapdeftype(type, s->cols[col].type, s->cols[col].nosign ? 1 : 0,
13810  s->nowchar[0]);
13811 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
13812  /* MS Access hack part 3 (map SQL_C_DEFAULT to SQL_C_CHAR) */
13813  if (type == SQL_C_WCHAR && otype == SQL_C_DEFAULT) {
13814  type = SQL_C_CHAR;
13815  }
13816 #endif
13817  data = s->rows + s->ncols + (s->rowp * s->ncols) + col;
13818  if (!val) {
13819  valnull = 1;
13820  val = (SQLPOINTER) valdummy;
13821  }
13822  if (*data == NULL) {
13823  *lenp = SQL_NULL_DATA;
13824  switch (type) {
13825  case SQL_C_UTINYINT:
13826  case SQL_C_TINYINT:
13827  case SQL_C_STINYINT:
13828 #ifdef SQL_BIT
13829  case SQL_C_BIT:
13830 #endif
13831  *((SQLCHAR *) val) = 0;
13832  break;
13833  case SQL_C_USHORT:
13834  case SQL_C_SHORT:
13835  case SQL_C_SSHORT:
13836  *((SQLSMALLINT *) val) = 0;
13837  break;
13838  case SQL_C_ULONG:
13839  case SQL_C_LONG:
13840  case SQL_C_SLONG:
13841  *((SQLINTEGER *) val) = 0;
13842  break;
13843 #ifdef SQL_BIGINT
13844  case SQL_C_SBIGINT:
13845  case SQL_C_UBIGINT:
13846  *((SQLBIGINT *) val) = 0;
13847  break;
13848 #endif
13849  case SQL_C_FLOAT:
13850  *((float *) val) = 0;
13851  break;
13852  case SQL_C_DOUBLE:
13853  *((double *) val) = 0;
13854  break;
13855  case SQL_C_BINARY:
13856  case SQL_C_CHAR:
13857  if (len > 0) {
13858  *((SQLCHAR *) val) = '\0';
13859  }
13860  break;
13861 #ifdef WCHARSUPPORT
13862  case SQL_C_WCHAR:
13863  if (len > 0) {
13864  *((SQLWCHAR *) val) = '\0';
13865  }
13866  break;
13867 #endif
13868 #ifdef SQL_C_TYPE_DATE
13869  case SQL_C_TYPE_DATE:
13870 #endif
13871  case SQL_C_DATE:
13872  memset((DATE_STRUCT *) val, 0, sizeof (DATE_STRUCT));
13873  break;
13874 #ifdef SQL_C_TYPE_TIME
13875  case SQL_C_TYPE_TIME:
13876 #endif
13877  case SQL_C_TIME:
13878  memset((TIME_STRUCT *) val, 0, sizeof (TIME_STRUCT));
13879  break;
13880 #ifdef SQL_C_TYPE_TIMESTAMP
13881  case SQL_C_TYPE_TIMESTAMP:
13882 #endif
13883  case SQL_C_TIMESTAMP:
13884  memset((TIMESTAMP_STRUCT *) val, 0, sizeof (TIMESTAMP_STRUCT));
13885  break;
13886  default:
13887  return SQL_ERROR;
13888  }
13889  } else {
13890  char *endp = NULL;
13891 #if defined(_WIN32) || defined(_WIN64)
13892 #ifdef SQL_BIGINT
13893  char endc;
13894 #endif
13895 #endif
13896 
13897  switch (type) {
13898  case SQL_C_UTINYINT:
13899  case SQL_C_TINYINT:
13900  case SQL_C_STINYINT:
13901  *((SQLCHAR *) val) = strtol(*data, &endp, 0);
13902  if (endp && endp == *data) {
13903  *lenp = SQL_NULL_DATA;
13904  } else {
13905  *lenp = sizeof (SQLCHAR);
13906  }
13907  break;
13908 #ifdef SQL_BIT
13909  case SQL_C_BIT:
13910  *((SQLCHAR *) val) = getbool(*data);
13911  *lenp = sizeof (SQLCHAR);
13912  break;
13913 #endif
13914  case SQL_C_USHORT:
13915  case SQL_C_SHORT:
13916  case SQL_C_SSHORT:
13917  *((SQLSMALLINT *) val) = strtol(*data, &endp, 0);
13918  if (endp && endp == *data) {
13919  *lenp = SQL_NULL_DATA;
13920  } else {
13921  *lenp = sizeof (SQLSMALLINT);
13922  }
13923  break;
13924  case SQL_C_ULONG:
13925  case SQL_C_LONG:
13926  case SQL_C_SLONG:
13927  *((SQLINTEGER *) val) = strtol(*data, &endp, 0);
13928  if (endp && endp == *data) {
13929  *lenp = SQL_NULL_DATA;
13930  } else {
13931  *lenp = sizeof (SQLINTEGER);
13932  }
13933  break;
13934 #ifdef SQL_BIGINT
13935  case SQL_C_UBIGINT:
13936 #if defined(_WIN32) || defined(_WIN64)
13937  if (sscanf(*data, "%I64u%c", (SQLUBIGINT *) val, &endc) != 1) {
13938  *lenp = SQL_NULL_DATA;
13939  } else {
13940  *lenp = sizeof (SQLUBIGINT);
13941  }
13942 #else
13943 #ifdef __osf__
13944  *((SQLUBIGINT *) val) = strtoul(*data, &endp, 0);
13945 #else
13946  *((SQLUBIGINT *) val) = strtoull(*data, &endp, 0);
13947 #endif
13948  if (endp && endp == *data) {
13949  *lenp = SQL_NULL_DATA;
13950  } else {
13951  *lenp = sizeof (SQLUBIGINT);
13952  }
13953 #endif
13954  break;
13955  case SQL_C_SBIGINT:
13956 #if defined(_WIN32) || defined(_WIN64)
13957  if (sscanf(*data, "%I64d%c", (SQLBIGINT *) val, &endc) != 1) {
13958  *lenp = SQL_NULL_DATA;
13959  } else {
13960  *lenp = sizeof (SQLBIGINT);
13961  }
13962 #else
13963 #ifdef __osf__
13964  *((SQLBIGINT *) val) = strtol(*data, &endp, 0);
13965 #else
13966  *((SQLBIGINT *) val) = strtoll(*data, &endp, 0);
13967 #endif
13968  if (endp && endp == *data) {
13969  *lenp = SQL_NULL_DATA;
13970  } else {
13971  *lenp = sizeof (SQLBIGINT);
13972  }
13973 #endif
13974  break;
13975 #endif
13976  case SQL_C_FLOAT:
13977  *((float *) val) = ln_strtod(*data, &endp);
13978  if (endp && endp == *data) {
13979  *lenp = SQL_NULL_DATA;
13980  } else {
13981  *lenp = sizeof (float);
13982  }
13983  break;
13984  case SQL_C_DOUBLE:
13985  *((double *) val) = ln_strtod(*data, &endp);
13986  if (endp && endp == *data) {
13987  *lenp = SQL_NULL_DATA;
13988  } else {
13989  *lenp = sizeof (double);
13990  }
13991  break;
13992  case SQL_C_BINARY: {
13993  int dlen, offs = 0;
13994  char *bin;
13995 
13996  if (valnull) {
13997  freep(&s->bincache);
13998  s->binlen = 0;
13999  goto doCHAR;
14000  }
14001  if (*data == s->bincell) {
14002  if (s->bincache) {
14003  bin = s->bincache;
14004  dlen = s->binlen;
14005  } else {
14006  goto doCHAR;
14007  }
14008  } else {
14009  char *dp;
14010  int i;
14011 
14012  freep(&s->bincache);
14013  dp = *data;
14014  dlen = strlen(dp);
14015  s->bincell = dp;
14016  s->binlen = 0;
14017  if (!(dp[0] == 'x' || dp[0] == 'X') || dp[1] != '\'' ||
14018  dp[dlen - 1] != '\'') {
14019  goto doCHAR;
14020  }
14021  dlen -= 2;
14022  dp += 2;
14023  dlen = dlen / 2;
14024  s->bincache = bin = xmalloc(dlen + 1);
14025  if (!bin) {
14026  return nomem(s);
14027  }
14028  s->binlen = dlen;
14029  memset(bin, 0, dlen);
14030  bin[dlen] = '\0'; /* terminator, just in case */
14031  for (i = 0; i < dlen; i++) {
14032  char *x;
14033  int v;
14034 
14035  if (!*dp || !(x = strchr(xdigits, *dp))) {
14036  goto converr;
14037  }
14038  v = x - xdigits;
14039  bin[i] = (v >= 16) ? ((v - 6) << 4) : (v << 4);
14040  ++dp;
14041  if (!*dp || !(x = strchr(xdigits, *dp))) {
14042 converr:
14043  freep(&s->bincache);
14044  s->binlen = 0;
14045  setstat(s, -1, "conversion error",
14046  (*s->ov3) ? "HY000" : "S1000");
14047  return SQL_ERROR;
14048  }
14049  v = x - xdigits;
14050  bin[i] |= (v >= 16) ? (v - 6) : v;
14051  ++dp;
14052  }
14053  bin = s->bincache;
14054  }
14055  if (partial && len && s->bindcols) {
14056  if (s->bindcols[col].offs >= dlen) {
14057  *lenp = 0;
14058  if (!dlen && s->bindcols[col].offs == dlen) {
14059  s->bindcols[col].offs = 1;
14060  sret = SQL_SUCCESS;
14061  goto done;
14062  }
14063  s->bindcols[col].offs = 0;
14064  sret = SQL_NO_DATA;
14065  goto done;
14066  }
14067  offs = s->bindcols[col].offs;
14068  dlen -= offs;
14069  }
14070  if (val && len) {
14071  memcpy(val, bin + offs, min(len, dlen));
14072  }
14073  if (len < 1) {
14074  *lenp = dlen;
14075  } else {
14076  *lenp = min(len, dlen);
14077  if (*lenp == len && *lenp != dlen) {
14078  *lenp = SQL_NO_TOTAL;
14079  }
14080  }
14081  if (partial && len && s->bindcols) {
14082  if (*lenp == SQL_NO_TOTAL) {
14083  *lenp = dlen;
14084  s->bindcols[col].offs += len;
14085  setstat(s, -1, "data right truncated", "01004");
14086  if (s->bindcols[col].lenp) {
14087  *s->bindcols[col].lenp = dlen;
14088  }
14089  sret = SQL_SUCCESS_WITH_INFO;
14090  goto done;
14091  }
14092  s->bindcols[col].offs += *lenp;
14093  }
14094  if (*lenp == SQL_NO_TOTAL) {
14095  *lenp = dlen;
14096  setstat(s, -1, "data right truncated", "01004");
14097  sret = SQL_SUCCESS_WITH_INFO;
14098  goto done;
14099  }
14100  break;
14101  }
14102  doCHAR:
14103 #ifdef WCHARSUPPORT
14104  case SQL_C_WCHAR:
14105 #endif
14106  case SQL_C_CHAR: {
14107  int doz, zlen = len - 1;
14108  int dlen = strlen(*data);
14109  int offs = 0;
14110 #ifdef WCHARSUPPORT
14111  SQLWCHAR *ucdata = NULL;
14112  SQLCHAR *cdata = (SQLCHAR *) *data;
14113 #endif
14114 
14115 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
14116  /* MS Access hack part 2 (reserved error -7748) */
14117  if (!valnull &&
14118  (s->cols == statSpec2P || s->cols == statSpec3P) &&
14119  type == SQL_C_WCHAR) {
14120  if (len > 0 && len <= sizeof (SQLWCHAR)) {
14121  ((char *) val)[0] = data[0][0];
14122  memset((char *) val + 1, 0, len - 1);
14123  *lenp = 1;
14124  sret = SQL_SUCCESS;
14125  goto done;
14126  }
14127  }
14128 #endif
14129 
14130 #ifdef WCHARSUPPORT
14131  switch (type) {
14132  case SQL_C_CHAR:
14133  doz = 1;
14134  break;
14135  case SQL_C_WCHAR:
14136  doz = sizeof (SQLWCHAR);
14137  break;
14138  default:
14139  doz = 0;
14140  break;
14141  }
14142  if (type == SQL_C_WCHAR) {
14143  ucdata = uc_from_utf(cdata, dlen);
14144  if (!ucdata) {
14145  return nomem(s);
14146  }
14147  dlen = uc_strlen(ucdata) * sizeof (SQLWCHAR);
14148  }
14149 #if defined(_WIN32) || defined(_WIN64)
14150  else if (*s->oemcp && type == SQL_C_CHAR) {
14151  ucdata = (SQLWCHAR *) utf_to_wmb((char *) cdata, dlen);
14152  if (!ucdata) {
14153  return nomem(s);
14154  }
14155  cdata = (SQLCHAR *) ucdata;
14156  dlen = strlen((char *) cdata);
14157  }
14158 #endif
14159 #else
14160  doz = (type == SQL_C_CHAR) ? 1 : 0;
14161 #endif
14162  if (partial && len && s->bindcols) {
14163  if (s->bindcols[col].offs >= dlen) {
14164 #ifdef WCHARSUPPORT
14165  uc_free(ucdata);
14166 #endif
14167  *lenp = 0;
14168  if (doz && val) {
14169 #ifdef WCHARSUPPORT
14170  if (type == SQL_C_WCHAR) {
14171  ((SQLWCHAR *) val)[0] = 0;
14172  } else {
14173  ((char *) val)[0] = '\0';
14174  }
14175 #else
14176  ((char *) val)[0] = '\0';
14177 #endif
14178  }
14179  if (!dlen && s->bindcols[col].offs == dlen) {
14180  s->bindcols[col].offs = 1;
14181  sret = SQL_SUCCESS;
14182  goto done;
14183  }
14184  s->bindcols[col].offs = 0;
14185  sret = SQL_NO_DATA;
14186  goto done;
14187  }
14188  offs = s->bindcols[col].offs;
14189  dlen -= offs;
14190  }
14191  if (val && !valnull && len) {
14192 #ifdef WCHARSUPPORT
14193  if (type == SQL_C_WCHAR) {
14194  uc_strncpy(val, ucdata + offs / sizeof (SQLWCHAR),
14195  (len - doz) / sizeof (SQLWCHAR));
14196  } else {
14197  strncpy(val, (char *) cdata + offs, len - doz);
14198  }
14199 #else
14200  strncpy(val, *data + offs, len - doz);
14201 #endif
14202  }
14203  if (valnull || len < 1) {
14204  *lenp = dlen;
14205  } else {
14206  *lenp = min(len - doz, dlen);
14207  if (*lenp == len - doz && *lenp != dlen) {
14208  *lenp = SQL_NO_TOTAL;
14209  } else if (*lenp < zlen) {
14210  zlen = *lenp;
14211  }
14212  }
14213  if (len && !valnull && doz) {
14214 #ifdef WCHARSUPPORT
14215  if (type == SQL_C_WCHAR) {
14216  ((SQLWCHAR *) val)[zlen / sizeof (SQLWCHAR)] = 0;
14217  } else {
14218  ((char *) val)[zlen] = '\0';
14219  }
14220 #else
14221  ((char *) val)[zlen] = '\0';
14222 #endif
14223  }
14224 #ifdef WCHARSUPPORT
14225  uc_free(ucdata);
14226 #endif
14227  if (partial && len && s->bindcols) {
14228  if (*lenp == SQL_NO_TOTAL) {
14229  *lenp = dlen;
14230  s->bindcols[col].offs += len - doz;
14231  setstat(s, -1, "data right truncated", "01004");
14232  if (s->bindcols[col].lenp) {
14233  *s->bindcols[col].lenp = dlen;
14234  }
14235  sret = SQL_SUCCESS_WITH_INFO;
14236  goto done;
14237  }
14238  s->bindcols[col].offs += *lenp;
14239  }
14240  if (*lenp == SQL_NO_TOTAL) {
14241  *lenp = dlen;
14242  setstat(s, -1, "data right truncated", "01004");
14243  sret = SQL_SUCCESS_WITH_INFO;
14244  goto done;
14245  }
14246  break;
14247  }
14248 #ifdef SQL_C_TYPE_DATE
14249  case SQL_C_TYPE_DATE:
14250 #endif
14251  case SQL_C_DATE:
14252  if (str2date(*s->jdconv, *data, (DATE_STRUCT *) val) < 0) {
14253  *lenp = SQL_NULL_DATA;
14254  } else {
14255  *lenp = sizeof (DATE_STRUCT);
14256  }
14257  break;
14258 #ifdef SQL_C_TYPE_TIME
14259  case SQL_C_TYPE_TIME:
14260 #endif
14261  case SQL_C_TIME:
14262  if (str2time(*s->jdconv, *data, (TIME_STRUCT *) val) < 0) {
14263  *lenp = SQL_NULL_DATA;
14264  } else {
14265  *lenp = sizeof (TIME_STRUCT);
14266  }
14267  break;
14268 #ifdef SQL_C_TYPE_TIMESTAMP
14269  case SQL_C_TYPE_TIMESTAMP:
14270 #endif
14271  case SQL_C_TIMESTAMP:
14272  if (str2timestamp(*s->jdconv, *data,
14273  (TIMESTAMP_STRUCT *) val) < 0) {
14274  *lenp = SQL_NULL_DATA;
14275  } else {
14276  *lenp = sizeof (TIMESTAMP_STRUCT);
14277  }
14278  switch (s->cols[col].prec) {
14279  case 0:
14280  ((TIMESTAMP_STRUCT *) val)->fraction = 0;
14281  break;
14282  case 1:
14283  ((TIMESTAMP_STRUCT *) val)->fraction /= 100000000;
14284  ((TIMESTAMP_STRUCT *) val)->fraction *= 100000000;
14285  break;
14286  case 2:
14287  ((TIMESTAMP_STRUCT *) val)->fraction /= 10000000;
14288  ((TIMESTAMP_STRUCT *) val)->fraction *= 10000000;
14289  break;
14290  }
14291  break;
14292  default:
14293  return SQL_ERROR;
14294  }
14295  }
14296  sret = SQL_SUCCESS;
14297 done:
14298  if (ilenp) {
14299  *ilenp = *lenp;
14300  }
14301  return sret;
14302 }
14303 
14315 static SQLRETURN
14316 drvbindcol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14317  SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14318 {
14319  STMT *s;
14320  int sz = 0;
14321 
14322  if (stmt == SQL_NULL_HSTMT) {
14323  return SQL_INVALID_HANDLE;
14324  }
14325  s = (STMT *) stmt;
14326  if (col < 1) {
14327  if (col == 0 && s->bkmrk == SQL_UB_ON &&
14328  type == SQL_C_BOOKMARK) {
14329  s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14330  s->bkmrkcol.max = val ? sizeof (SQLINTEGER) : 0;
14331  s->bkmrkcol.lenp = val ? lenp : 0;
14332  s->bkmrkcol.valp = val;
14333  s->bkmrkcol.offs = 0;
14334  if (val && lenp) {
14335  *lenp = 0;
14336  }
14337  return SQL_SUCCESS;
14338  } else if (col == 0 && s->bkmrk == SQL_UB_VARIABLE &&
14339  type == SQL_C_VARBOOKMARK &&
14340  max >= sizeof (sqlite_int64)) {
14341  s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14342  s->bkmrkcol.max = val ? max : 0;
14343  s->bkmrkcol.lenp = val ? lenp : 0;
14344  s->bkmrkcol.valp = val;
14345  s->bkmrkcol.offs = 0;
14346  if (val && lenp) {
14347  *lenp = 0;
14348  }
14349  return SQL_SUCCESS;
14350  }
14351  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
14352  return SQL_ERROR;
14353  }
14354  if (mkbindcols(s, col) != SQL_SUCCESS) {
14355  return SQL_ERROR;
14356  }
14357  --col;
14358  if (type == SQL_C_DEFAULT) {
14359  type = mapdeftype(type, s->cols[col].type, 0,
14360  s->nowchar[0] || s->nowchar[1]);
14361  }
14362  switch (type) {
14363  case SQL_C_LONG:
14364  case SQL_C_ULONG:
14365  case SQL_C_SLONG:
14366  sz = sizeof (SQLINTEGER);
14367  break;
14368  case SQL_C_TINYINT:
14369  case SQL_C_UTINYINT:
14370  case SQL_C_STINYINT:
14371  sz = sizeof (SQLCHAR);
14372  break;
14373  case SQL_C_SHORT:
14374  case SQL_C_USHORT:
14375  case SQL_C_SSHORT:
14376  sz = sizeof (SQLSMALLINT);
14377  break;
14378  case SQL_C_FLOAT:
14379  sz = sizeof (SQLFLOAT);
14380  break;
14381  case SQL_C_DOUBLE:
14382  sz = sizeof (SQLDOUBLE);
14383  break;
14384  case SQL_C_TIMESTAMP:
14385  sz = sizeof (SQL_TIMESTAMP_STRUCT);
14386  break;
14387  case SQL_C_TIME:
14388  sz = sizeof (SQL_TIME_STRUCT);
14389  break;
14390  case SQL_C_DATE:
14391  sz = sizeof (SQL_DATE_STRUCT);
14392  break;
14393  case SQL_C_CHAR:
14394  break;
14395 #ifdef WCHARSUPPORT
14396  case SQL_C_WCHAR:
14397  break;
14398 #endif
14399 #ifdef SQL_C_TYPE_DATE
14400  case SQL_C_TYPE_DATE:
14401  sz = sizeof (SQL_DATE_STRUCT);
14402  break;
14403 #endif
14404 #ifdef SQL_C_TYPE_TIME
14405  case SQL_C_TYPE_TIME:
14406  sz = sizeof (SQL_TIME_STRUCT);
14407  break;
14408 #endif
14409 #ifdef SQL_C_TYPE_TIMESTAMP
14410  case SQL_C_TYPE_TIMESTAMP:
14411  sz = sizeof (SQL_TIMESTAMP_STRUCT);
14412  break;
14413 #endif
14414 #ifdef SQL_BIT
14415  case SQL_C_BIT:
14416  sz = sizeof (SQLCHAR);
14417  break;
14418 #endif
14419  case SQL_C_BINARY:
14420  break;
14421 #ifdef SQL_BIGINT
14422  case SQL_C_SBIGINT:
14423  case SQL_C_UBIGINT:
14424  sz = sizeof (SQLBIGINT);
14425  break;
14426 #endif
14427  default:
14428  if (val == NULL) {
14429  /* fall through, unbinding column */
14430  break;
14431  }
14432  setstat(s, -1, "invalid type %d", "HY003", type);
14433  return SQL_ERROR;
14434  }
14435  if (val == NULL) {
14436  /* unbind column */
14437  s->bindcols[col].type = SQL_UNKNOWN_TYPE;
14438  s->bindcols[col].max = 0;
14439  s->bindcols[col].lenp = NULL;
14440  s->bindcols[col].valp = NULL;
14441  s->bindcols[col].offs = 0;
14442  } else {
14443  if (sz == 0 && max < 0) {
14444  setstat(s, -1, "invalid length", "HY090");
14445  return SQL_ERROR;
14446  }
14447  s->bindcols[col].type = type;
14448  s->bindcols[col].max = (sz == 0) ? max : sz;
14449  s->bindcols[col].lenp = lenp;
14450  s->bindcols[col].valp = val;
14451  s->bindcols[col].offs = 0;
14452  if (lenp) {
14453  *lenp = 0;
14454  }
14455  }
14456  return SQL_SUCCESS;
14457 }
14458 
14470 SQLRETURN SQL_API
14471 SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14472  SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14473 {
14474  SQLRETURN ret;
14475 
14476  HSTMT_LOCK(stmt);
14477  ret = drvbindcol(stmt, col, type, val, max, lenp);
14478  HSTMT_UNLOCK(stmt);
14479  return ret;
14480 }
14481 
14486 static COL tableSpec2[] = {
14487  { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
14488  { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
14489  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14490  { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14491  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14492 };
14493 
14494 static COL tableSpec3[] = {
14495  { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
14496  { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
14497  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14498  { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14499  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14500 };
14501 
14516 static SQLRETURN
14517 drvtables(SQLHSTMT stmt,
14518  SQLCHAR *cat, SQLSMALLINT catLen,
14519  SQLCHAR *schema, SQLSMALLINT schemaLen,
14520  SQLCHAR *table, SQLSMALLINT tableLen,
14521  SQLCHAR *type, SQLSMALLINT typeLen)
14522 {
14523  SQLRETURN ret;
14524  STMT *s;
14525  DBC *d;
14526  int ncols, asize, rc, size, npatt;
14527  char *errp = NULL, *sql, tname[512];
14528  char *where = "(type = 'table' or type = 'view')";
14529 
14531  tableSpec3, array_size(tableSpec3), &asize);
14532  if (ret != SQL_SUCCESS) {
14533  return ret;
14534  }
14535  s = (STMT *) stmt;
14536  d = (DBC *) s->dbc;
14537  if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] == '%') {
14538  int size = 3 * asize;
14539 
14540  s->rows = xmalloc(size * sizeof (char *));
14541  if (!s->rows) {
14542  s->nrows = 0;
14543  return nomem(s);
14544  }
14545  memset(s->rows, 0, sizeof (char *) * size);
14546  s->ncols = asize;
14547  s->rows[s->ncols + 0] = "";
14548  s->rows[s->ncols + 1] = "";
14549  s->rows[s->ncols + 2] = "";
14550  s->rows[s->ncols + 3] = "TABLE";
14551  s->rows[s->ncols + 5] = "";
14552  s->rows[s->ncols + 6] = "";
14553  s->rows[s->ncols + 7] = "";
14554  s->rows[s->ncols + 8] = "VIEW";
14555 #ifdef MEMORY_DEBUG
14556  s->rowfree = xfree__;
14557 #else
14558  s->rowfree = sqlite3_free;
14559 #endif
14560  s->nrows = 2;
14561  s->rowp = s->rowprs = -1;
14562  return SQL_SUCCESS;
14563  }
14564  if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
14565  table = NULL;
14566  goto doit;
14567  }
14568  if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
14569  schema[0] == '%') {
14570  if ((!cat || catLen == 0 || !cat[0]) &&
14571  (!table || tableLen == 0 || !table[0])) {
14572  table = NULL;
14573  goto doit;
14574  }
14575  }
14576  if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] != '\0') {
14577  char tmp[256], *t;
14578  int with_view = 0, with_table = 0;
14579 
14580  if (typeLen == SQL_NTS) {
14581  strncpy(tmp, (char *) type, sizeof (tmp));
14582  tmp[sizeof (tmp) - 1] = '\0';
14583  } else {
14584  int len = min(sizeof (tmp) - 1, typeLen);
14585 
14586  strncpy(tmp, (char *) type, len);
14587  tmp[len] = '\0';
14588  }
14589  t = tmp;
14590  while (*t) {
14591  *t = TOLOWER(*t);
14592  t++;
14593  }
14594  t = tmp;
14595  unescpat(t);
14596  while (t) {
14597  if (t[0] == '\'') {
14598  ++t;
14599  }
14600  if (strncmp(t, "table", 5) == 0) {
14601  with_table++;
14602  } else if (strncmp(t, "view", 4) == 0) {
14603  with_view++;
14604  }
14605  t = strchr(t, ',');
14606  if (t) {
14607  ++t;
14608  }
14609  }
14610  if (with_view && with_table) {
14611  /* where is already preset */
14612  } else if (with_view && !with_table) {
14613  where = "type = 'view'";
14614  } else if (!with_view && with_table) {
14615  where = "type = 'table'";
14616  } else {
14617  return SQL_SUCCESS;
14618  }
14619  }
14620 doit:
14621  if (!table) {
14622  size = 1;
14623  tname[0] = '%';
14624  } else {
14625  if (tableLen == SQL_NTS) {
14626  size = sizeof (tname) - 1;
14627  } else {
14628  size = min(sizeof (tname) - 1, tableLen);
14629  }
14630  strncpy(tname, (char *) table, size);
14631  }
14632  tname[size] = '\0';
14633  npatt = unescpat(tname);
14634 #if defined(_WIN32) || defined(_WIN64)
14635  sql = sqlite3_mprintf("select %s as 'TABLE_CAT', "
14636  "%s as 'TABLE_SCHEM', "
14637  "tbl_name as 'TABLE_NAME', "
14638  "upper(type) as 'TABLE_TYPE', "
14639  "NULL as 'REMARKS' "
14640  "from sqlite_master where %s "
14641  "and tbl_name %s %Q",
14642  d->xcelqrx ? "'main'" : "NULL",
14643  d->xcelqrx ? "''" : "NULL",
14644  where,
14645  npatt ? "like" : "=", tname);
14646 #else
14647  sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
14648  "NULL as 'TABLE_OWNER', "
14649  "tbl_name as 'TABLE_NAME', "
14650  "upper(type) as 'TABLE_TYPE', "
14651  "NULL as 'REMARKS' "
14652  "from sqlite_master where %s "
14653  "and tbl_name %s %Q", where,
14654  npatt ? "like" : "=", tname);
14655 #endif
14656  if (!sql) {
14657  return nomem(s);
14658  }
14659  ret = starttran(s);
14660  if (ret != SQL_SUCCESS) {
14661  sqlite3_free(sql);
14662  return ret;
14663  }
14664  dbtraceapi(d, "sqlite3_get_table", sql);
14665  rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
14666  sqlite3_free(sql);
14667  if (rc == SQLITE_OK) {
14668  if (ncols != s->ncols) {
14669  freeresult(s, 0);
14670  s->nrows = 0;
14671  } else {
14672  s->rowfree = sqlite3_free_table;
14673  }
14674  } else {
14675  s->nrows = 0;
14676  s->rows = NULL;
14677  s->rowfree = NULL;
14678  }
14679  if (errp) {
14680  sqlite3_free(errp);
14681  errp = NULL;
14682  }
14683  s->rowp = s->rowprs = -1;
14684  return SQL_SUCCESS;
14685 }
14686 
14687 #ifndef WINTERFACE
14688 
14702 SQLRETURN SQL_API
14703 SQLTables(SQLHSTMT stmt,
14704  SQLCHAR *cat, SQLSMALLINT catLen,
14705  SQLCHAR *schema, SQLSMALLINT schemaLen,
14706  SQLCHAR *table, SQLSMALLINT tableLen,
14707  SQLCHAR *type, SQLSMALLINT typeLen)
14708 {
14709 #if defined(_WIN32) || defined(_WIN64)
14710  char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
14711 #endif
14712  SQLRETURN ret;
14713 
14714  HSTMT_LOCK(stmt);
14715 #if defined(_WIN32) || defined(_WIN64)
14716  if (!((STMT *) stmt)->oemcp[0]) {
14717  ret = drvtables(stmt, cat, catLen, schema, schemaLen,
14718  table, tableLen, type, typeLen);
14719  goto done2;
14720  }
14721  if (cat) {
14722  c = wmb_to_utf_c((char *) cat, catLen);
14723  if (!c) {
14724  ret = nomem((STMT *) stmt);
14725  goto done;
14726  }
14727  }
14728  if (schema) {
14729  s = wmb_to_utf_c((char *) schema, schemaLen);
14730  if (!s) {
14731  ret = nomem((STMT *) stmt);
14732  goto done;
14733  }
14734  }
14735  if (table) {
14736  t = wmb_to_utf_c((char *) table, tableLen);
14737  if (!t) {
14738  ret = nomem((STMT *) stmt);
14739  goto done;
14740  }
14741  }
14742  if (type) {
14743  y = wmb_to_utf_c((char *) type, typeLen);
14744  if (!y) {
14745  ret = nomem((STMT *) stmt);
14746  goto done;
14747  }
14748  }
14749  ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
14750  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
14751 #else
14752  ret = drvtables(stmt, cat, catLen, schema, schemaLen,
14753  table, tableLen, type, typeLen);
14754 #endif
14755 #if defined(_WIN32) || defined(_WIN64)
14756 done:
14757  uc_free(y);
14758  uc_free(t);
14759  uc_free(s);
14760  uc_free(c);
14761 done2:
14762  ;
14763 #endif
14764  HSTMT_UNLOCK(stmt);
14765  return ret;
14766 }
14767 #endif
14768 
14769 #ifdef WINTERFACE
14770 
14784 SQLRETURN SQL_API
14785 SQLTablesW(SQLHSTMT stmt,
14786  SQLWCHAR *cat, SQLSMALLINT catLen,
14787  SQLWCHAR *schema, SQLSMALLINT schemaLen,
14788  SQLWCHAR *table, SQLSMALLINT tableLen,
14789  SQLWCHAR *type, SQLSMALLINT typeLen)
14790 {
14791  char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
14792  SQLRETURN ret;
14793 
14794  HSTMT_LOCK(stmt);
14795  if (cat) {
14796  c = uc_to_utf_c(cat, catLen);
14797  if (!c) {
14798  ret = nomem((STMT *) stmt);
14799  goto done;
14800  }
14801  }
14802  if (schema) {
14803  s = uc_to_utf_c(schema, schemaLen);
14804  if (!s) {
14805  ret = nomem((STMT *) stmt);
14806  goto done;
14807  }
14808  }
14809  if (table) {
14810  t = uc_to_utf_c(table, tableLen);
14811  if (!t) {
14812  ret = nomem((STMT *) stmt);
14813  goto done;
14814  }
14815  }
14816  if (type) {
14817  y = uc_to_utf_c(type, typeLen);
14818  if (!y) {
14819  ret = nomem((STMT *) stmt);
14820  goto done;
14821  }
14822  }
14823  ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
14824  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
14825 done:
14826  uc_free(y);
14827  uc_free(t);
14828  uc_free(s);
14829  uc_free(c);
14830  HSTMT_UNLOCK(stmt);
14831  return ret;
14832 }
14833 #endif
14834 
14839 static COL colSpec2[] = {
14840  { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
14841  { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
14842  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14843  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
14844  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
14845  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
14846  { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
14847  { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
14848  { "SYSTEM", "COLUMN", "SCALE", SQL_SMALLINT, 50 },
14849  { "SYSTEM", "COLUMN", "RADIX", SQL_SMALLINT, 50 },
14850  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
14851  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
14852  { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
14853  { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
14854  { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
14855  { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
14856  { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
14857  { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
14858 };
14859 
14860 static COL colSpec3[] = {
14861  { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
14862  { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
14863  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14864  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
14865  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
14866  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
14867  { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
14868  { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
14869  { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_SMALLINT, 50 },
14870  { "SYSTEM", "COLUMN", "NUM_PREC_RADIX", SQL_SMALLINT, 50 },
14871  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
14872  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
14873  { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
14874  { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
14875  { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
14876  { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
14877  { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
14878  { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
14879 };
14880 
14895 static SQLRETURN
14896 drvcolumns(SQLHSTMT stmt,
14897  SQLCHAR *cat, SQLSMALLINT catLen,
14898  SQLCHAR *schema, SQLSMALLINT schemaLen,
14899  SQLCHAR *table, SQLSMALLINT tableLen,
14900  SQLCHAR *col, SQLSMALLINT colLen)
14901 {
14902  SQLRETURN sret;
14903  STMT *s;
14904  DBC *d;
14905  int ret, nrows, ncols, asize, i, k, roffs, namec;
14906  int tnrows, tncols, npatt;
14907  PTRDIFF_T size;
14908  char *errp = NULL, *sql, tname[512], cname[512], **rowp, **trows;
14909 
14911  colSpec3, array_size(colSpec3), &asize);
14912  if (sret != SQL_SUCCESS) {
14913  return sret;
14914  }
14915  s = (STMT *) stmt;
14916  d = (DBC *) s->dbc;
14917  if (!table) {
14918  size = 1;
14919  tname[0] = '%';
14920  } else {
14921  if (tableLen == SQL_NTS) {
14922  size = sizeof (tname) - 1;
14923  } else {
14924  size = min(sizeof (tname) - 1, tableLen);
14925  }
14926  strncpy(tname, (char *) table, size);
14927  }
14928  tname[size] = '\0';
14929  npatt = unescpat(tname);
14930  size = 0;
14931  if (col) {
14932  if (colLen == SQL_NTS) {
14933  size = sizeof (cname) - 1;
14934  } else {
14935  size = min(sizeof (cname) - 1, colLen);
14936  }
14937  strncpy(cname, (char *) col, size);
14938  }
14939  cname[size] = '\0';
14940  if (!strcmp(cname, "%")) {
14941  cname[0] = '\0';
14942  }
14943  sql = sqlite3_mprintf("select tbl_name from sqlite_master where "
14944  "(type = 'table' or type = 'view') "
14945  "and tbl_name %s %Q", npatt ? "like" : "=", tname);
14946  if (!sql) {
14947  return nomem(s);
14948  }
14949  sret = starttran(s);
14950  if (sret != SQL_SUCCESS) {
14951  sqlite3_free(sql);
14952  return sret;
14953  }
14954  dbtraceapi(d, "sqlite3_get_table", sql);
14955  ret = sqlite3_get_table(d->sqlite, sql, &trows, &tnrows, &tncols, &errp);
14956  sqlite3_free(sql);
14957  if (ret != SQLITE_OK) {
14958  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
14959  errp ? errp : "unknown error", ret);
14960  if (errp) {
14961  sqlite3_free(errp);
14962  errp = NULL;
14963  }
14964  return SQL_ERROR;
14965  }
14966  if (errp) {
14967  sqlite3_free(errp);
14968  errp = NULL;
14969  }
14970  /* pass 1: compute number of rows of result set */
14971  if (tncols * tnrows <= 0) {
14972  sqlite3_free_table(trows);
14973  return SQL_SUCCESS;
14974  }
14975  size = 0;
14976  for (i = 1; i <= tnrows; i++) {
14977  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
14978  if (!sql) {
14979  sqlite3_free_table(trows);
14980  return nomem(s);
14981  }
14982  dbtraceapi(d, "sqlite3_get_table", sql);
14983  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
14984  sqlite3_free(sql);
14985  if (ret != SQLITE_OK) {
14986  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
14987  errp ? errp : "unknown error", ret);
14988  if (errp) {
14989  sqlite3_free(errp);
14990  errp = NULL;
14991  }
14992  sqlite3_free_table(trows);
14993  return SQL_ERROR;
14994  }
14995  if (errp) {
14996  sqlite3_free(errp);
14997  errp = NULL;
14998  }
14999  if (ncols * nrows > 0) {
15000  namec = -1;
15001  for (k = 0; k < ncols; k++) {
15002  if (strcmp(rowp[k], "name") == 0) {
15003  namec = k;
15004  break;
15005  }
15006  }
15007  if (cname[0]) {
15008  if (namec >= 0) {
15009  for (k = 1; k <= nrows; k++) {
15010  if (namematch(rowp[k * ncols + namec], cname, 1)) {
15011  size++;
15012  }
15013  }
15014  }
15015  } else {
15016  size += nrows;
15017  }
15018  }
15019  sqlite3_free_table(rowp);
15020  }
15021  /* pass 2: fill result set */
15022  if (size <= 0) {
15023  sqlite3_free_table(trows);
15024  return SQL_SUCCESS;
15025  }
15026  s->nrows = size;
15027  size = (size + 1) * asize;
15028  s->rows = xmalloc((size + 1) * sizeof (char *));
15029  if (!s->rows) {
15030  s->nrows = 0;
15031  sqlite3_free_table(trows);
15032  return nomem(s);
15033  }
15034  s->rows[0] = (char *) size;
15035  s->rows += 1;
15036  memset(s->rows, 0, sizeof (char *) * size);
15037  s->rowfree = freerows;
15038  roffs = 1;
15039  for (i = 1; i <= tnrows; i++) {
15040  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
15041  if (!sql) {
15042  sqlite3_free_table(trows);
15043  return nomem(s);
15044  }
15045  dbtraceapi(d, "sqlite3_get_table", sql);
15046  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15047  sqlite3_free(sql);
15048  if (ret != SQLITE_OK) {
15049  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15050  errp ? errp : "unknown error", ret);
15051  if (errp) {
15052  sqlite3_free(errp);
15053  errp = NULL;
15054  }
15055  sqlite3_free_table(trows);
15056  return SQL_ERROR;
15057  }
15058  if (errp) {
15059  sqlite3_free(errp);
15060  errp = NULL;
15061  }
15062  if (ncols * nrows > 0) {
15063  int m, mr, nr = nrows;
15064 
15065  namec = -1;
15066  for (k = 0; k < ncols; k++) {
15067  if (strcmp(rowp[k], "name") == 0) {
15068  namec = k;
15069  break;
15070  }
15071  }
15072  if (cname[0]) {
15073  nr = 0;
15074  if (namec >= 0) {
15075  for (k = 1; k <= nrows; k++) {
15076  if (namematch(rowp[k * ncols + namec], cname, 1)) {
15077  nr++;
15078  }
15079  }
15080  }
15081  }
15082  for (k = 0; k < nr; k++) {
15083  m = asize * (roffs + k);
15084 #if defined(_WIN32) || defined(_WIN64)
15085  s->rows[m + 0] = xstrdup(d->xcelqrx ? "main" : "");
15086  s->rows[m + 1] = xstrdup("");
15087 #else
15088  s->rows[m + 0] = xstrdup("");
15089  s->rows[m + 1] = xstrdup("");
15090 #endif
15091  s->rows[m + 2] = xstrdup(trows[i]);
15092  s->rows[m + 8] = xstrdup("10");
15093  s->rows[m + 9] = xstrdup("0");
15094  s->rows[m + 15] = xstrdup("16384");
15095  }
15096  for (k = 0; nr && k < ncols; k++) {
15097  if (strcmp(rowp[k], "cid") == 0) {
15098  for (mr = 0, m = 1; m <= nrows; m++) {
15099  char buf[256];
15100  int ir, coln = k;
15101 
15102  if (cname[0] &&
15103  !namematch(rowp[m * ncols + namec], cname, 1)) {
15104  continue;
15105  }
15106  ir = asize * (roffs + mr);
15107  sscanf(rowp[m * ncols + k], "%d", &coln);
15108  sprintf(buf, "%d", coln + 1);
15109  s->rows[ir + 16] = xstrdup(buf);
15110  ++mr;
15111  }
15112  } else if (k == namec) {
15113  for (mr = 0, m = 1; m <= nrows; m++) {
15114  int ir;
15115 
15116  if (cname[0] &&
15117  !namematch(rowp[m * ncols + namec], cname, 1)) {
15118  continue;
15119  }
15120  ir = asize * (roffs + mr);
15121  s->rows[ir + 3] = xstrdup(rowp[m * ncols + k]);
15122  ++mr;
15123  }
15124  } else if (strcmp(rowp[k], "notnull") == 0) {
15125  for (mr = 0, m = 1; m <= nrows; m++) {
15126  int ir;
15127 
15128  if (cname[0] &&
15129  !namematch(rowp[m * ncols + namec], cname, 1)) {
15130  continue;
15131  }
15132  ir = asize * (roffs + mr);
15133  if (*rowp[m * ncols + k] != '0') {
15134  s->rows[ir + 10] = xstrdup(stringify(SQL_FALSE));
15135  } else {
15136  s->rows[ir + 10] = xstrdup(stringify(SQL_TRUE));
15137  }
15138  s->rows[ir + 17] =
15139  xstrdup((*rowp[m * ncols + k] != '0') ?
15140  "NO" : "YES");
15141  ++mr;
15142  }
15143  } else if (strcmp(rowp[k], "dflt_value") == 0) {
15144  for (mr = 0, m = 1; m <= nrows; m++) {
15145  char *dflt = unquote(rowp[m * ncols + k]);
15146  int ir;
15147 
15148  if (cname[0] &&
15149  !namematch(rowp[m * ncols + namec], cname, 1)) {
15150  continue;
15151  }
15152  ir = asize * (roffs + mr);
15153  s->rows[ir + 12] = xstrdup(dflt ? dflt : "NULL");
15154  ++mr;
15155  }
15156  } else if (strcmp(rowp[k], "type") == 0) {
15157  for (mr = 0, m = 1; m <= nrows; m++) {
15158  char *typename = rowp[m * ncols + k];
15159  int sqltype, mm, dd, ir;
15160  char buf[256];
15161 
15162  if (cname[0] &&
15163  !namematch(rowp[m * ncols + namec], cname, 1)) {
15164  continue;
15165  }
15166  ir = asize * (roffs + mr);
15167  s->rows[ir + 5] = xstrdup(typename);
15168  sqltype = mapsqltype(typename, NULL, *s->ov3,
15169  s->nowchar[0], s->dobigint);
15170  getmd(typename, sqltype, &mm, &dd);
15171 #ifdef SQL_LONGVARCHAR
15172  if (sqltype == SQL_VARCHAR && mm > 255) {
15173  sqltype = SQL_LONGVARCHAR;
15174  }
15175 #endif
15176 #ifdef WINTERFACE
15177 #ifdef SQL_WLONGVARCHAR
15178  if (sqltype == SQL_WVARCHAR && mm > 255) {
15179  sqltype = SQL_WLONGVARCHAR;
15180  }
15181 #endif
15182 #endif
15183  if (sqltype == SQL_VARBINARY && mm > 255) {
15184  sqltype = SQL_LONGVARBINARY;
15185  }
15186  sprintf(buf, "%d", sqltype);
15187  s->rows[ir + 4] = xstrdup(buf);
15188  s->rows[ir + 13] = xstrdup(buf);
15189  sprintf(buf, "%d", mm);
15190  s->rows[ir + 7] = xstrdup(buf);
15191  sprintf(buf, "%d", dd);
15192  s->rows[ir + 6] = xstrdup(buf);
15193  ++mr;
15194  }
15195  }
15196  }
15197  roffs += nr;
15198  }
15199  sqlite3_free_table(rowp);
15200  }
15201  sqlite3_free_table(trows);
15202  return SQL_SUCCESS;
15203 }
15204 
15205 #ifndef WINTERFACE
15206 
15220 SQLRETURN SQL_API
15221 SQLColumns(SQLHSTMT stmt,
15222  SQLCHAR *cat, SQLSMALLINT catLen,
15223  SQLCHAR *schema, SQLSMALLINT schemaLen,
15224  SQLCHAR *table, SQLSMALLINT tableLen,
15225  SQLCHAR *col, SQLSMALLINT colLen)
15226 {
15227 #if defined(_WIN32) || defined(_WIN64)
15228  char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15229 #endif
15230  SQLRETURN ret;
15231 
15232  HSTMT_LOCK(stmt);
15233 #if defined(_WIN32) || defined(_WIN64)
15234  if (!((STMT *) stmt)->oemcp[0]) {
15235  ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15236  table, tableLen, col, colLen);
15237  goto done2;
15238  }
15239  if (cat) {
15240  c = wmb_to_utf_c((char *) cat, catLen);
15241  if (!c) {
15242  ret = nomem((STMT *) stmt);
15243  goto done;
15244  }
15245  }
15246  if (schema) {
15247  s = wmb_to_utf_c((char *) schema, schemaLen);
15248  if (!s) {
15249  ret = nomem((STMT *) stmt);
15250  goto done;
15251  }
15252  }
15253  if (table) {
15254  t = wmb_to_utf_c((char *) table, tableLen);
15255  if (!t) {
15256  ret = nomem((STMT *) stmt);
15257  goto done;
15258  }
15259  }
15260  if (col) {
15261  k = wmb_to_utf_c((char *) col, colLen);
15262  if (!k) {
15263  ret = nomem((STMT *) stmt);
15264  goto done;
15265  }
15266  }
15267  ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15268  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15269 #else
15270  ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15271  table, tableLen, col, colLen);
15272 #endif
15273 #if defined(_WIN32) || defined(_WIN64)
15274 done:
15275  uc_free(k);
15276  uc_free(t);
15277  uc_free(s);
15278  uc_free(c);
15279 done2:
15280  ;
15281 #endif
15282  HSTMT_UNLOCK(stmt);
15283  return ret;
15284 }
15285 #endif
15286 
15287 #ifdef WINTERFACE
15288 
15302 SQLRETURN SQL_API
15304  SQLWCHAR *cat, SQLSMALLINT catLen,
15305  SQLWCHAR *schema, SQLSMALLINT schemaLen,
15306  SQLWCHAR *table, SQLSMALLINT tableLen,
15307  SQLWCHAR *col, SQLSMALLINT colLen)
15308 {
15309  char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15310  SQLRETURN ret;
15311 
15312  HSTMT_LOCK(stmt);
15313  if (cat) {
15314  c = uc_to_utf_c(cat, catLen);
15315  if (!c) {
15316  ret = nomem((STMT *) stmt);
15317  goto done;
15318  }
15319  }
15320  if (schema) {
15321  s = uc_to_utf_c(schema, schemaLen);
15322  if (!s) {
15323  ret = nomem((STMT *) stmt);
15324  goto done;
15325  }
15326  }
15327  if (table) {
15328  t = uc_to_utf_c(table, tableLen);
15329  if (!t) {
15330  ret = nomem((STMT *) stmt);
15331  goto done;
15332  }
15333  }
15334  if (col) {
15335  k = uc_to_utf_c(col, colLen);
15336  if (!k) {
15337  ret = nomem((STMT *) stmt);
15338  goto done;
15339  }
15340  }
15341  ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15342  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15343 done:
15344  uc_free(k);
15345  uc_free(t);
15346  uc_free(s);
15347  uc_free(c);
15348  HSTMT_UNLOCK(stmt);
15349  return ret;
15350 
15351 }
15352 #endif
15353 
15358 static COL typeSpec2[] = {
15359  { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15360  { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15361  { "SYSTEM", "TYPE", "PRECISION", SQL_INTEGER, 9 },
15362  { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15363  { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15364  { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15365  { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15366  { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15367  { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15368  { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15369  { "SYSTEM", "TYPE", "MONEY", SQL_SMALLINT, 2 },
15370  { "SYSTEM", "TYPE", "AUTO_INCREMENT", SQL_SMALLINT, 2 },
15371  { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15372  { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15373  { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 }
15374 };
15375 
15376 static COL typeSpec3[] = {
15377  { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15378  { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15379  { "SYSTEM", "TYPE", "COLUMN_SIZE", SQL_INTEGER, 9 },
15380  { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15381  { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15382  { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15383  { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15384  { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15385  { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15386  { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15387  { "SYSTEM", "TYPE", "FIXED_PREC_SCALE", SQL_SMALLINT, 2 },
15388  { "SYSTEM", "TYPE", "AUTO_UNIQUE_VALUE", SQL_SMALLINT, 2 },
15389  { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15390  { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15391  { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 },
15392  { "SYSTEM", "TYPE", "SQL_DATA_TYPE", SQL_SMALLINT, 2 },
15393  { "SYSTEM", "TYPE", "SQL_DATETIME_SUB", SQL_SMALLINT, 2 },
15394  { "SYSTEM", "TYPE", "NUM_PREC_RADIX", SQL_INTEGER, 4 },
15395  { "SYSTEM", "TYPE", "INTERVAL_PRECISION", SQL_SMALLINT, 2 }
15396 };
15397 
15408 static void
15409 mktypeinfo(STMT *s, int row, int asize, char *typename, int type, int tind)
15410 {
15411  int offs = row * asize;
15412  char *tcode, *crpar = NULL, *quote = NULL, *sign = stringify(SQL_FALSE);
15413  static char tcodes[32 * 32];
15414 
15415  if (tind <= 0) {
15416  tind = row;
15417  }
15418  tcode = tcodes + tind * 32;
15419  sprintf(tcode, "%d", type);
15420  s->rows[offs + 0] = typename;
15421  s->rows[offs + 1] = tcode;
15422  if (asize >= 17) {
15423  s->rows[offs + 15] = tcode;
15424  s->rows[offs + 16] = "0";
15425  }
15426  switch (type) {
15427  default:
15428 #ifdef SQL_LONGVARCHAR
15429  case SQL_LONGVARCHAR:
15430 #ifdef WINTERFACE
15431  case SQL_WLONGVARCHAR:
15432 #endif
15433  crpar = "length";
15434  quote = "'";
15435  sign = NULL;
15436  s->rows[offs + 2] = "65536";
15437  break;
15438 #endif
15439 #ifdef SQL_BIT
15440  case SQL_BIT:
15441  sign = NULL;
15442  s->rows[offs + 2] = "1";
15443  break;
15444 #endif
15445  case SQL_CHAR:
15446  case SQL_VARCHAR:
15447 #ifdef WINTERFACE
15448  case SQL_WCHAR:
15449  case SQL_WVARCHAR:
15450 #endif
15451  s->rows[offs + 2] = "255";
15452  crpar = "length";
15453  quote = "'";
15454  sign = NULL;
15455  break;
15456  case SQL_TINYINT:
15457  s->rows[offs + 2] = "3";
15458  break;
15459  case SQL_SMALLINT:
15460  s->rows[offs + 2] = "5";
15461  break;
15462  case SQL_INTEGER:
15463  s->rows[offs + 2] = "9";
15464  break;
15465 #ifdef SQL_BIGINT
15466  case SQL_BIGINT:
15467  s->rows[offs + 2] = "19";
15468  break;
15469 #endif
15470  case SQL_FLOAT:
15471  s->rows[offs + 2] = "7";
15472  break;
15473  case SQL_DOUBLE:
15474  s->rows[offs + 2] = "15";
15475  break;
15476 #ifdef SQL_TYPE_DATE
15477  case SQL_TYPE_DATE:
15478 #endif
15479  case SQL_DATE:
15480  s->rows[offs + 2] = "10";
15481  quote = "'";
15482  sign = NULL;
15483  break;
15484 #ifdef SQL_TYPE_TIME
15485  case SQL_TYPE_TIME:
15486 #endif
15487  case SQL_TIME:
15488  s->rows[offs + 2] = "8";
15489  quote = "'";
15490  sign = NULL;
15491  break;
15492 #ifdef SQL_TYPE_TIMESTAMP
15493  case SQL_TYPE_TIMESTAMP:
15494 #endif
15495  case SQL_TIMESTAMP:
15496  s->rows[offs + 2] = "32";
15497  quote = "'";
15498  sign = NULL;
15499  break;
15500  case SQL_VARBINARY:
15501  sign = NULL;
15502  s->rows[offs + 2] = "255";
15503  break;
15504  case SQL_LONGVARBINARY:
15505  sign = NULL;
15506  s->rows[offs + 2] = "65536";
15507  break;
15508  }
15509  s->rows[offs + 3] = s->rows[offs + 4] = quote;
15510  s->rows[offs + 5] = crpar;
15511  s->rows[offs + 6] = stringify(SQL_NULLABLE);
15512  s->rows[offs + 7] = stringify(SQL_FALSE);
15513  s->rows[offs + 8] = stringify(SQL_SEARCHABLE);
15514  s->rows[offs + 9] = sign;
15515  s->rows[offs + 10] = stringify(SQL_FALSE);
15516  s->rows[offs + 11] = stringify(SQL_FALSE);
15517  s->rows[offs + 12] = typename;
15518  switch (type) {
15519  case SQL_DATE:
15520  case SQL_TIME:
15521  s->rows[offs + 13] = "0";
15522  s->rows[offs + 14] = "0";
15523  break;
15524 #ifdef SQL_TYPE_TIMESTAMP
15525  case SQL_TYPE_TIMESTAMP:
15526 #endif
15527  case SQL_TIMESTAMP:
15528  s->rows[offs + 13] = "0";
15529  s->rows[offs + 14] = "3";
15530  break;
15531  default:
15532  s->rows[offs + 13] = NULL;
15533  s->rows[offs + 14] = NULL;
15534  break;
15535  }
15536 }
15537 
15546 static int
15547 typeinfosort(const void *a, const void *b)
15548 {
15549  char **pa = (char **) a;
15550  char **pb = (char **) b;
15551  int na, nb;
15552 
15553  na = strtol(pa[1], NULL, 0);
15554  nb = strtol(pb[1], NULL, 0);
15555  return na - nb;
15556 }
15557 
15565 static SQLRETURN
15566 drvgettypeinfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
15567 {
15568  SQLRETURN ret;
15569  STMT *s;
15570  int asize;
15571 
15573  typeSpec3, array_size(typeSpec3), &asize);
15574  if (ret != SQL_SUCCESS) {
15575  return ret;
15576  }
15577  s = (STMT *) stmt;
15578 #ifdef SQL_LONGVARCHAR
15579  s->nrows = (sqltype == SQL_ALL_TYPES) ? 13 : 1;
15580 #else
15581  s->nrows = (sqltype == SQL_ALL_TYPES) ? 12 : 1;
15582 #endif
15583  if (sqltype == SQL_ALL_TYPES) {
15584 #ifdef WINTERFACE
15585  s->nrows += 2;
15586 #ifdef SQL_WLONGVARCHAR
15587  s->nrows += 2;
15588 #endif
15589 #endif
15590  }
15591  if (sqltype == SQL_ALL_TYPES) {
15592  s->nrows += 2;
15593 #ifdef SQL_BIT
15594  s->nrows += 1;
15595 #endif
15596 #ifdef SQL_BIGINT
15597  s->nrows += 1;
15598 #endif
15599  }
15600  s->rows = (char **) xmalloc(sizeof (char *) * (s->nrows + 1) * asize);
15601  if (!s->rows) {
15602  s->nrows = 0;
15603  return nomem(s);
15604  }
15605 #ifdef MEMORY_DEBUG
15606  s->rowfree = xfree__;
15607 #else
15608  s->rowfree = sqlite3_free;
15609 #endif
15610  memset(s->rows, 0, sizeof (char *) * (s->nrows + 1) * asize);
15611  if (sqltype == SQL_ALL_TYPES) {
15612  int cc = 1;
15613 
15614  mktypeinfo(s, cc++, asize, "varchar", SQL_VARCHAR, 0);
15615  mktypeinfo(s, cc++, asize, "tinyint", SQL_TINYINT, 0);
15616  mktypeinfo(s, cc++, asize, "smallint", SQL_SMALLINT, 0);
15617  mktypeinfo(s, cc++, asize, "integer", SQL_INTEGER, 0);
15618  mktypeinfo(s, cc++, asize, "float", SQL_FLOAT, 0);
15619  mktypeinfo(s, cc++, asize, "double", SQL_DOUBLE, 0);
15620 #ifdef SQL_TYPE_DATE
15621  mktypeinfo(s, cc++, asize, "date",
15622  (*s->ov3) ? SQL_TYPE_DATE : SQL_DATE, 0);
15623 #else
15624  mktypeinfo(s, cc++, asize, "date", SQL_DATE, 0);
15625 #endif
15626 #ifdef SQL_TYPE_TIME
15627  mktypeinfo(s, cc++, asize, "time",
15628  (*s->ov3) ? SQL_TYPE_TIME : SQL_TIME, 0);
15629 #else
15630  mktypeinfo(s, cc++, asize, "time", SQL_TIME, 0);
15631 #endif
15632 #ifdef SQL_TYPE_TIMESTAMP
15633  mktypeinfo(s, cc++, asize, "timestamp",
15634  (*s->ov3) ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP, 0);
15635 #else
15636  mktypeinfo(s, cc++, asize, "timestamp", SQL_TIMESTAMP, 0);
15637 #endif
15638  mktypeinfo(s, cc++, asize, "char", SQL_CHAR, 0);
15639  mktypeinfo(s, cc++, asize, "numeric", SQL_DOUBLE, 0);
15640 #ifdef SQL_LONGVARCHAR
15641  mktypeinfo(s, cc++, asize, "text", SQL_LONGVARCHAR, 0);
15642  mktypeinfo(s, cc++, asize, "longvarchar", SQL_LONGVARCHAR, 0);
15643 #else
15644  mktypeinfo(s, cc++, asize, "text", SQL_VARCHAR, 0);
15645 #endif
15646  mktypeinfo(s, cc++, asize, "varbinary", SQL_VARBINARY, 0);
15647  mktypeinfo(s, cc++, asize, "longvarbinary", SQL_LONGVARBINARY, 0);
15648 #ifdef SQL_BIT
15649  mktypeinfo(s, cc++, asize, "bit", SQL_BIT, 0);
15650 #endif
15651 #ifdef SQL_BIGINT
15652  mktypeinfo(s, cc++, asize, "bigint", SQL_BIGINT, 0);
15653 #endif
15654 #ifdef WINTERFACE
15655  mktypeinfo(s, cc++, asize, "wvarchar", SQL_WVARCHAR, 0);
15656  mktypeinfo(s, cc++, asize, "wchar", SQL_WCHAR, 0);
15657 #ifdef SQL_WLONGVARCHAR
15658  mktypeinfo(s, cc++, asize, "wtext", SQL_WLONGVARCHAR, 0);
15659  mktypeinfo(s, cc++, asize, "longwvarchar", SQL_WLONGVARCHAR, 0);
15660 #endif
15661 #endif
15662  qsort(s->rows + asize, s->nrows, sizeof (char *) * asize,
15663  typeinfosort);
15664  } else {
15665  switch (sqltype) {
15666  case SQL_CHAR:
15667  mktypeinfo(s, 1, asize, "char", SQL_CHAR, 10);
15668  break;
15669  case SQL_VARCHAR:
15670  mktypeinfo(s, 1, asize, "varchar", SQL_VARCHAR, 1);
15671  break;
15672  case SQL_TINYINT:
15673  mktypeinfo(s, 1, asize, "tinyint", SQL_TINYINT, 2);
15674  break;
15675  case SQL_SMALLINT:
15676  mktypeinfo(s, 1, asize, "smallint", SQL_SMALLINT, 3);
15677  break;
15678  case SQL_INTEGER:
15679  mktypeinfo(s, 1, asize, "integer", SQL_INTEGER, 4);
15680  break;
15681  case SQL_FLOAT:
15682  mktypeinfo(s, 1, asize, "float", SQL_FLOAT, 5);
15683  break;
15684  case SQL_DOUBLE:
15685  mktypeinfo(s, 1, asize, "double", SQL_DOUBLE, 6);
15686  break;
15687 #ifdef SQL_TYPE_DATE
15688  case SQL_TYPE_DATE:
15689  mktypeinfo(s, 1, asize, "date", SQL_TYPE_DATE, 25);
15690  break;
15691 #endif
15692  case SQL_DATE:
15693  mktypeinfo(s, 1, asize, "date", SQL_DATE, 7);
15694  break;
15695 #ifdef SQL_TYPE_TIME
15696  case SQL_TYPE_TIME:
15697  mktypeinfo(s, 1, asize, "time", SQL_TYPE_TIME, 26);
15698  break;
15699 #endif
15700  case SQL_TIME:
15701  mktypeinfo(s, 1, asize, "time", SQL_TIME, 8);
15702  break;
15703 #ifdef SQL_TYPE_TIMESTAMP
15704  case SQL_TYPE_TIMESTAMP:
15705  mktypeinfo(s, 1, asize, "timestamp", SQL_TYPE_TIMESTAMP, 27);
15706  break;
15707 #endif
15708  case SQL_TIMESTAMP:
15709  mktypeinfo(s, 1, asize, "timestamp", SQL_TIMESTAMP, 9);
15710  break;
15711 #ifdef SQL_LONGVARCHAR
15712  case SQL_LONGVARCHAR:
15713  mktypeinfo(s, 1, asize, "longvarchar", SQL_LONGVARCHAR, 12);
15714  break;
15715 #endif
15716  case SQL_VARBINARY:
15717  mktypeinfo(s, 1, asize, "varbinary", SQL_VARBINARY, 30);
15718  break;
15719  case SQL_LONGVARBINARY:
15720  mktypeinfo(s, 1, asize, "longvarbinary", SQL_LONGVARBINARY, 31);
15721  break;
15722 #ifdef SQL_BIT
15723  case SQL_BIT:
15724  mktypeinfo(s, 1, asize, "bit", SQL_BIT, 29);
15725  break;
15726 #endif
15727 #ifdef SQL_BIGINT
15728  case SQL_BIGINT:
15729  mktypeinfo(s, 1, asize, "bigint", SQL_BIGINT, 28);
15730  break;
15731 #endif
15732 #ifdef WINTERFACE
15733 #ifdef SQL_WCHAR
15734  case SQL_WCHAR:
15735  mktypeinfo(s, 1, asize, "wchar", SQL_WCHAR, 18);
15736  break;
15737 #endif
15738 #ifdef SQL_WVARCHAR
15739  case SQL_WVARCHAR:
15740  mktypeinfo(s, 1, asize, "wvarchar", SQL_WVARCHAR, 19);
15741  break;
15742 #endif
15743 #ifdef SQL_WLONGVARCHAR
15744  case SQL_WLONGVARCHAR:
15745  mktypeinfo(s, 1, asize, "longwvarchar", SQL_WLONGVARCHAR, 20);
15746  break;
15747 #endif
15748 #endif
15749  default:
15750  s->nrows = 0;
15751  }
15752  }
15753  return SQL_SUCCESS;
15754 }
15755 
15756 #ifndef WINTERFACE
15757 
15764 SQLRETURN SQL_API
15765 SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
15766 {
15767  SQLRETURN ret;
15768 
15769  HSTMT_LOCK(stmt);
15770  ret = drvgettypeinfo(stmt, sqltype);
15771  HSTMT_UNLOCK(stmt);
15772  return ret;
15773 }
15774 #endif
15775 
15776 #ifdef WINTERFACE
15777 
15784 SQLRETURN SQL_API
15785 SQLGetTypeInfoW(SQLHSTMT stmt, SQLSMALLINT sqltype)
15786 {
15787  SQLRETURN ret;
15788 
15789  HSTMT_LOCK(stmt);
15790  ret = drvgettypeinfo(stmt, sqltype);
15791  HSTMT_UNLOCK(stmt);
15792  return ret;
15793 }
15794 #endif
15795 
15800 static COL statSpec2[] = {
15801  { "SYSTEM", "STATISTICS", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
15802  { "SYSTEM", "STATISTICS", "TABLE_OWNER", SCOL_VARCHAR, 50 },
15803  { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
15804  { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
15805  { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
15806  { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
15807  { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
15808  { "SYSTEM", "STATISTICS", "SEQ_IN_INDEX", SQL_SMALLINT, 50 },
15809  { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15810  { "SYSTEM", "STATISTICS", "COLLATION", SCOL_CHAR, 1 },
15811  { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
15812  { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
15813  { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
15814 };
15815 
15816 static COL statSpec3[] = {
15817  { "SYSTEM", "STATISTICS", "TABLE_CAT", SCOL_VARCHAR, 50 },
15818  { "SYSTEM", "STATISTICS", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
15819  { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
15820  { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
15821  { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
15822  { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
15823  { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
15824  { "SYSTEM", "STATISTICS", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
15825  { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15826  { "SYSTEM", "STATISTICS", "ASC_OR_DESC", SCOL_CHAR, 1 },
15827  { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
15828  { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
15829  { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
15830 };
15831 
15846 static SQLRETURN
15847 drvstatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
15848  SQLCHAR *schema, SQLSMALLINT schemaLen,
15849  SQLCHAR *table, SQLSMALLINT tableLen,
15850  SQLUSMALLINT itype, SQLUSMALLINT resv)
15851 {
15852  SQLRETURN sret;
15853  STMT *s;
15854  DBC *d;
15855  int i, asize, ret, nrows, ncols, offs, namec, uniquec, addipk = 0;
15856  PTRDIFF_T size;
15857  char **rowp, *errp = NULL, *sql, tname[512];
15858 
15860  statSpec3, array_size(statSpec3), &asize);
15861  if (sret != SQL_SUCCESS) {
15862  return sret;
15863  }
15864  s = (STMT *) stmt;
15865  d = (DBC *) s->dbc;
15866  if (!table || table[0] == '\0' || table[0] == '%') {
15867  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
15868  return SQL_ERROR;
15869  }
15870  if (tableLen == SQL_NTS) {
15871  size = sizeof (tname) - 1;
15872  } else {
15873  size = min(sizeof (tname) - 1, tableLen);
15874  }
15875  strncpy(tname, (char *) table, size);
15876  tname[size] = '\0';
15877  unescpat(tname);
15878  sret = starttran(s);
15879  if (sret != SQL_SUCCESS) {
15880  return sret;
15881  }
15882  /*
15883  * Try integer primary key (autoincrement) first
15884  */
15885  if (itype == SQL_INDEX_UNIQUE || itype == SQL_INDEX_ALL) {
15886  rowp = 0;
15887  ret = SQLITE_ERROR;
15888  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
15889  if (sql) {
15890  dbtraceapi(d, "sqlite3_get_table", sql);
15891  ret = sqlite3_get_table(d->sqlite, sql, &rowp,
15892  &nrows, &ncols, NULL);
15893  sqlite3_free(sql);
15894  }
15895  if (ret == SQLITE_OK) {
15896  int colid, typec, npk = 0, npkint = 0;
15897 
15898  namec = findcol(rowp, ncols, "name");
15899  uniquec = findcol(rowp, ncols, "pk");
15900  typec = findcol(rowp, ncols, "type");
15901  colid = findcol(rowp, ncols, "cid");
15902  if (namec < 0 || uniquec < 0 || typec < 0 || colid < 0) {
15903  goto noipk;
15904  }
15905  for (i = 1; i <= nrows; i++) {
15906  if (*rowp[i * ncols + uniquec] != '0') {
15907  npk++;
15908  if (strlen(rowp[i * ncols + typec]) == 7 &&
15909  strncasecmp(rowp[i * ncols + typec], "integer", 7)
15910  == 0) {
15911  npkint++;
15912  }
15913  }
15914  }
15915  if (npkint == 1 && npk == npkint) {
15916  addipk = 1;
15917  }
15918  }
15919 noipk:
15920  sqlite3_free_table(rowp);
15921  }
15922  sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
15923  if (!sql) {
15924  return nomem(s);
15925  }
15926  dbtraceapi(d, "sqlite3_get_table", sql);
15927  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15928  sqlite3_free(sql);
15929  if (ret != SQLITE_OK) {
15930  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15931  errp ? errp : "unknown error", ret);
15932  if (errp) {
15933  sqlite3_free(errp);
15934  errp = NULL;
15935  }
15936  return SQL_ERROR;
15937  }
15938  if (errp) {
15939  sqlite3_free(errp);
15940  errp = NULL;
15941  }
15942  size = 0;
15943  namec = findcol(rowp, ncols, "name");
15944  uniquec = findcol(rowp, ncols, "unique");
15945  if (namec < 0 || uniquec < 0) {
15946  goto nodata;
15947  }
15948  for (i = 1; i <= nrows; i++) {
15949  int nnrows, nncols;
15950  char **rowpp;
15951  int isuniq;
15952 
15953  isuniq = *rowp[i * ncols + uniquec] != '0';
15954  if (isuniq || itype == SQL_INDEX_ALL) {
15955  ret = SQLITE_ERROR;
15956  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
15957  rowp[i * ncols + namec]);
15958  if (sql) {
15959  dbtraceapi(d, "sqlite3_get_table", sql);
15960  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
15961  &nnrows, &nncols, NULL);
15962  sqlite3_free(sql);
15963  }
15964  if (ret == SQLITE_OK) {
15965  size += nnrows;
15966  sqlite3_free_table(rowpp);
15967  }
15968  }
15969  }
15970 nodata:
15971  if (addipk) {
15972  size++;
15973  }
15974  if (size == 0) {
15975  sqlite3_free_table(rowp);
15976  return SQL_SUCCESS;
15977  }
15978  s->nrows = size;
15979  size = (size + 1) * asize;
15980  s->rows = xmalloc((size + 1) * sizeof (char *));
15981  if (!s->rows) {
15982  s->nrows = 0;
15983  return nomem(s);
15984  }
15985  s->rows[0] = (char *) size;
15986  s->rows += 1;
15987  memset(s->rows, 0, sizeof (char *) * size);
15988  s->rowfree = freerows;
15989  offs = 0;
15990  if (addipk) {
15991  char **rowpp = 0;
15992  int nrows2, ncols2;
15993 
15994  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
15995  if (sql) {
15996  dbtraceapi(d, "sqlite3_get_table", sql);
15997  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
15998  &nrows2, &ncols2, NULL);
15999  sqlite3_free(sql);
16000  }
16001  if (ret == SQLITE_OK) {
16002  int colid, typec, roffs, namecc, uniquecc;
16003 
16004  namecc = findcol(rowpp, ncols2, "name");
16005  uniquecc = findcol(rowpp, ncols2, "pk");
16006  typec = findcol(rowpp, ncols2, "type");
16007  colid = findcol(rowpp, ncols2, "cid");
16008  if (namecc < 0 || uniquecc < 0 || typec < 0 || colid < 0) {
16009  addipk = 0;
16010  s->nrows--;
16011  goto nodata2;
16012  }
16013  for (i = 1; i <= nrows2; i++) {
16014  if (*rowpp[i * ncols2 + uniquecc] != '0' &&
16015  strlen(rowpp[i * ncols2 + typec]) == 7 &&
16016  strncasecmp(rowpp[i * ncols2 + typec], "integer", 7)
16017  == 0) {
16018  break;
16019  }
16020  }
16021  if (i > nrows2) {
16022  addipk = 0;
16023  s->nrows--;
16024  goto nodata2;
16025  }
16026  roffs = s->ncols;
16027 #if defined(_WIN32) || defined(_WIN64)
16028  s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
16029  s->rows[roffs + 1] = xstrdup("");
16030 #else
16031  s->rows[roffs + 0] = xstrdup("");
16032  s->rows[roffs + 1] = xstrdup("");
16033 #endif
16034  s->rows[roffs + 2] = xstrdup(tname);
16035  s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16036  s->rows[roffs + 5] = xstrdup("sqlite_autoindex_0");
16037  s->rows[roffs + 6] = xstrdup(stringify(SQL_INDEX_OTHER));
16038  s->rows[roffs + 7] = xstrdup("1");
16039  s->rows[roffs + 8] = xstrdup(rowpp[i * ncols2 + namecc]);
16040  s->rows[roffs + 9] = xstrdup("A");
16041  }
16042 nodata2:
16043  sqlite3_free_table(rowpp);
16044  }
16045  for (i = 1; i <= nrows; i++) {
16046  int nnrows, nncols;
16047  char **rowpp = 0;
16048 
16049  if (*rowp[i * ncols + uniquec] != '0' || itype == SQL_INDEX_ALL) {
16050  int k;
16051 
16052  ret = SQLITE_ERROR;
16053  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
16054  rowp[i * ncols + namec]);
16055  if (sql) {
16056  dbtraceapi(d, "sqlite3_get_table", sql);
16057  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16058  &nnrows, &nncols, NULL);
16059  sqlite3_free(sql);
16060  }
16061  if (ret != SQLITE_OK) {
16062  continue;
16063  }
16064  for (k = 0; nnrows && k < nncols; k++) {
16065  if (strcmp(rowpp[k], "name") == 0) {
16066  int m;
16067 
16068  for (m = 1; m <= nnrows; m++) {
16069  int roffs = (offs + addipk + m) * s->ncols;
16070  int isuniq;
16071 
16072  isuniq = *rowp[i * ncols + uniquec] != '0';
16073  s->rows[roffs + 0] = xstrdup("");
16074  s->rows[roffs + 1] = xstrdup("");
16075  s->rows[roffs + 2] = xstrdup(tname);
16076  if (isuniq) {
16077  s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16078  } else {
16079  s->rows[roffs + 3] = xstrdup(stringify(SQL_TRUE));
16080  }
16081  s->rows[roffs + 5] = xstrdup(rowp[i * ncols + namec]);
16082  s->rows[roffs + 6] =
16083  xstrdup(stringify(SQL_INDEX_OTHER));
16084  s->rows[roffs + 8] = xstrdup(rowpp[m * nncols + k]);
16085  s->rows[roffs + 9] = xstrdup("A");
16086  }
16087  } else if (strcmp(rowpp[k], "seqno") == 0) {
16088  int m;
16089 
16090  for (m = 1; m <= nnrows; m++) {
16091  int roffs = (offs + addipk + m) * s->ncols;
16092  int pos = m - 1;
16093  char buf[32];
16094 
16095  sscanf(rowpp[m * nncols + k], "%d", &pos);
16096  sprintf(buf, "%d", pos + 1);
16097  s->rows[roffs + 7] = xstrdup(buf);
16098  }
16099  }
16100  }
16101  offs += nnrows;
16102  sqlite3_free_table(rowpp);
16103  }
16104  }
16105  sqlite3_free_table(rowp);
16106  return SQL_SUCCESS;
16107 }
16108 
16109 #ifndef WINTERFACE
16110 
16124 SQLRETURN SQL_API
16125 SQLStatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
16126  SQLCHAR *schema, SQLSMALLINT schemaLen,
16127  SQLCHAR *table, SQLSMALLINT tableLen,
16128  SQLUSMALLINT itype, SQLUSMALLINT resv)
16129 {
16130 #if defined(_WIN32) || defined(_WIN64)
16131  char *c = NULL, *s = NULL, *t = NULL;
16132 #endif
16133  SQLRETURN ret;
16134 
16135  HSTMT_LOCK(stmt);
16136 #if defined(_WIN32) || defined(_WIN64)
16137  if (!((STMT *) stmt)->oemcp[0]) {
16138  ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16139  table, tableLen, itype, resv);
16140  goto done2;
16141  }
16142  if (cat) {
16143  c = wmb_to_utf_c((char *) cat, catLen);
16144  if (!c) {
16145  ret = nomem((STMT *) stmt);
16146  goto done;
16147  }
16148  }
16149  if (schema) {
16150  s = wmb_to_utf_c((char *) schema, schemaLen);
16151  if (!s) {
16152  ret = nomem((STMT *) stmt);
16153  goto done;
16154  }
16155  }
16156  if (table) {
16157  t = wmb_to_utf_c((char *) table, tableLen);
16158  if (!t) {
16159  ret = nomem((STMT *) stmt);
16160  goto done;
16161  }
16162  }
16163  ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16164  (SQLCHAR *) t, SQL_NTS, itype, resv);
16165 #else
16166  ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16167  table, tableLen, itype, resv);
16168 #endif
16169 #if defined(_WIN32) || defined(_WIN64)
16170 done:
16171  uc_free(t);
16172  uc_free(s);
16173  uc_free(c);
16174 done2:
16175  ;
16176 #endif
16177  HSTMT_UNLOCK(stmt);
16178  return ret;
16179 }
16180 #endif
16181 
16182 #ifdef WINTERFACE
16183 
16197 SQLRETURN SQL_API
16198 SQLStatisticsW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen,
16199  SQLWCHAR *schema, SQLSMALLINT schemaLen,
16200  SQLWCHAR *table, SQLSMALLINT tableLen,
16201  SQLUSMALLINT itype, SQLUSMALLINT resv)
16202 {
16203  char *c = NULL, *s = NULL, *t = NULL;
16204  SQLRETURN ret;
16205 
16206  HSTMT_LOCK(stmt);
16207  if (cat) {
16208  c = uc_to_utf_c(cat, catLen);
16209  if (!c) {
16210  ret = nomem((STMT *) stmt);
16211  goto done;
16212  }
16213  }
16214  if (schema) {
16215  s = uc_to_utf_c(schema, schemaLen);
16216  if (!s) {
16217  ret = nomem((STMT *) stmt);
16218  goto done;
16219  }
16220  }
16221  if (table) {
16222  t = uc_to_utf_c(table, tableLen);
16223  if (!t) {
16224  ret = nomem((STMT *) stmt);
16225  goto done;
16226  }
16227  }
16228  ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16229  (SQLCHAR *) t, SQL_NTS, itype, resv);
16230 done:
16231  uc_free(t);
16232  uc_free(s);
16233  uc_free(c);
16234  HSTMT_UNLOCK(stmt);
16235  return ret;
16236 }
16237 #endif
16238 
16250 SQLRETURN SQL_API
16251 SQLGetData(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
16252  SQLPOINTER val, SQLLEN len, SQLLEN *lenp)
16253 {
16254  STMT *s;
16255  SQLRETURN ret = SQL_ERROR;
16256 
16257  HSTMT_LOCK(stmt);
16258  if (stmt == SQL_NULL_HSTMT) {
16259  return SQL_INVALID_HANDLE;
16260  }
16261  s = (STMT *) stmt;
16262  if (col == 0 && s->bkmrk != SQL_UB_OFF) {
16263  if (s->bkmrk == SQL_UB_ON && type == SQL_C_BOOKMARK) {
16264  *((SQLINTEGER *) val) = s->rowp;
16265  if (lenp) {
16266  *lenp = sizeof (SQLINTEGER);
16267  }
16268  ret = SQL_SUCCESS;
16269  goto done;
16270  } else if (s->bkmrk == SQL_UB_VARIABLE && type == SQL_C_VARBOOKMARK) {
16271  if (s->has_rowid >= 0) {
16272  char **data, *endp = 0;
16273 
16274  data = s->rows + s->ncols + (s->rowp * s->ncols)
16275  + s->has_rowid;
16276 #ifdef __osf__
16277  *((sqlite_int64 *) val) = strtol(*data, &endp, 0);
16278 #else
16279  *((sqlite_int64 *) val) = strtoll(*data, &endp, 0);
16280 #endif
16281  } else {
16282  *((sqlite_int64 *) val) = s->rowp;
16283  }
16284  if (lenp) {
16285  *lenp = sizeof (sqlite_int64);
16286  }
16287  ret = SQL_SUCCESS;
16288  goto done;
16289  }
16290  }
16291  if (col < 1 || col > s->ncols) {
16292  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
16293  goto done;
16294  }
16295  --col;
16296  ret = getrowdata(s, col, type, val, len, lenp, 1);
16297 done:
16298  HSTMT_UNLOCK(stmt);
16299  return ret;
16300 }
16301 
16309 static SQLRETURN
16310 dofetchbind(STMT *s, int rsi)
16311 {
16312  int ret, i, withinfo = 0;
16313 
16314  s->row_status0[rsi] = SQL_ROW_SUCCESS;
16315  if (s->bkmrk != SQL_UB_OFF && s->bkmrkcol.valp) {
16316  int bsize = sizeof (SQLINTEGER);
16317 
16318  if (s->bkmrkcol.type == SQL_C_VARBOOKMARK) {
16319  SQLPOINTER *val;
16320 
16321  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16322  val = (SQLPOINTER)
16323  ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16324  } else {
16325  val = (SQLPOINTER)
16326  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * rsi);
16327  }
16328  if (s->bind_offs) {
16329  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
16330  }
16331  if (s->has_rowid >= 0) {
16332  char **data, *endp = 0;
16333 
16334  data = s->rows + s->ncols + (s->rowp * s->ncols)
16335  + s->has_rowid;
16336 #ifdef __osf__
16337  *(sqlite_int64 *) val = strtol(*data, &endp, 0);
16338 #else
16339  *(sqlite_int64 *) val = strtoll(*data, &endp, 0);
16340 #endif
16341  } else {
16342  *(sqlite_int64 *) val = s->rowp;
16343  }
16344  bsize = sizeof (sqlite_int64);
16345  } else {
16346  SQLINTEGER *val;
16347 
16348  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16349  val = (SQLINTEGER *)
16350  ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16351  } else {
16352  val = (SQLINTEGER *) s->bkmrkcol.valp + rsi;
16353  }
16354  if (s->bind_offs) {
16355  val = (SQLINTEGER *) ((char *) val + *s->bind_offs);
16356  }
16357  *val = s->rowp;
16358  }
16359  if (s->bkmrkcol.lenp) {
16360  SQLLEN *ival;
16361 
16362  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16363  ival = (SQLLEN *)
16364  ((char *) s->bkmrkcol.lenp + s->bind_type * rsi);
16365  } else {
16366  ival = &s->bkmrkcol.lenp[rsi];
16367  }
16368  if (s->bind_offs) {
16369  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
16370  }
16371  *ival = bsize;
16372  }
16373  }
16374  ret = SQL_SUCCESS;
16375  for (i = 0; s->bindcols && i < s->ncols; i++) {
16376  BINDCOL *b = &s->bindcols[i];
16377  SQLPOINTER dp = 0;
16378  SQLLEN *lp = 0;
16379 
16380  b->offs = 0;
16381  if (b->valp) {
16382  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16383  dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
16384  } else {
16385  dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
16386  }
16387  if (s->bind_offs) {
16388  dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
16389  }
16390  }
16391  if (b->lenp) {
16392  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16393  lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
16394  } else {
16395  lp = b->lenp + rsi;
16396  }
16397  if (s->bind_offs) {
16398  lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
16399  }
16400  }
16401  if (dp || lp) {
16402  ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp, b->max, lp, 0);
16403  if (!SQL_SUCCEEDED(ret)) {
16404  s->row_status0[rsi] = SQL_ROW_ERROR;
16405  break;
16406  }
16407  if (ret != SQL_SUCCESS) {
16408  withinfo = 1;
16409 #ifdef SQL_ROW_SUCCESS_WITH_INFO
16410  s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
16411 #endif
16412  }
16413  }
16414  }
16415  if (SQL_SUCCEEDED(ret)) {
16416  ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16417  }
16418  return ret;
16419 }
16420 
16429 static SQLRETURN
16430 drvfetchscroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLINTEGER offset)
16431 {
16432  STMT *s;
16433  int i, withinfo = 0;
16434  SQLRETURN ret;
16435 
16436  if (stmt == SQL_NULL_HSTMT) {
16437  return SQL_INVALID_HANDLE;
16438  }
16439  s = (STMT *) stmt;
16440  for (i = 0; i < s->rowset_size; i++) {
16441  s->row_status0[i] = SQL_ROW_NOROW;
16442  }
16443  if (s->row_status) {
16444  memcpy(s->row_status, s->row_status0,
16445  sizeof (SQLUSMALLINT) * s->rowset_size);
16446  }
16447  s->row_count0 = 0;
16448  if (s->row_count) {
16449  *s->row_count = s->row_count0;
16450  }
16451  if (!s->bindcols) {
16452  for (i = 0; i < s->rowset_size; i++) {
16453  s->row_status0[i] = SQL_ROW_ERROR;
16454  }
16455  ret = SQL_ERROR;
16456  i = 0;
16457  goto done2;
16458  }
16459  if (s->isselect != 1 && s->isselect != -1) {
16460  setstat(s, -1, "no result set available", "24000");
16461  ret = SQL_ERROR;
16462  i = s->nrows;
16463  goto done2;
16464  }
16465  if (s->curtype == SQL_CURSOR_FORWARD_ONLY && orient != SQL_FETCH_NEXT) {
16466  setstat(s, -1, "wrong fetch direction", "01000");
16467  ret = SQL_ERROR;
16468  i = 0;
16469  goto done2;
16470  }
16471  ret = SQL_SUCCESS;
16472  i = 0;
16473  if (((DBC *) (s->dbc))->cur_s3stmt == s && s->s3stmt) {
16474  s->rowp = s->rowprs = 0;
16475  for (; i < s->rowset_size; i++) {
16476  if (s->max_rows && s->s3stmt_rownum + 1 >= s->max_rows) {
16477  ret = (i == 0) ? SQL_NO_DATA : SQL_SUCCESS;
16478  break;
16479  }
16480  ret = s3stmt_step(s);
16481  if (ret != SQL_SUCCESS) {
16482  s->row_status0[i] = SQL_ROW_ERROR;
16483  break;
16484  }
16485  if (s->nrows < 1) {
16486  break;
16487  }
16488  ret = dofetchbind(s, i);
16489  if (!SQL_SUCCEEDED(ret)) {
16490  break;
16491  } else if (ret == SQL_SUCCESS_WITH_INFO) {
16492  withinfo = 1;
16493  }
16494  }
16495  } else if (s->rows) {
16496  switch (orient) {
16497  case SQL_FETCH_NEXT:
16498  if (s->nrows < 1) {
16499  return SQL_NO_DATA;
16500  }
16501  if (s->rowp < 0) {
16502  s->rowp = -1;
16503  }
16504  if (s->rowp >= s->nrows) {
16505  s->rowp = s->rowprs = s->nrows;
16506  return SQL_NO_DATA;
16507  }
16508  break;
16509  case SQL_FETCH_PRIOR:
16510  if (s->nrows < 1 || s->rowp <= 0) {
16511  s->rowp = s->rowprs = -1;
16512  return SQL_NO_DATA;
16513  }
16514  s->rowp -= s->rowset_size + 1;
16515  if (s->rowp < -1) {
16516  s->rowp = s->rowprs = -1;
16517  return SQL_NO_DATA;
16518  }
16519  break;
16520  case SQL_FETCH_FIRST:
16521  if (s->nrows < 1) {
16522  return SQL_NO_DATA;
16523  }
16524  s->rowp = -1;
16525  break;
16526  case SQL_FETCH_LAST:
16527  if (s->nrows < 1) {
16528  return SQL_NO_DATA;
16529  }
16530  s->rowp = s->nrows - s->rowset_size;
16531  if (--s->rowp < -1) {
16532  s->rowp = -1;
16533  }
16534  break;
16535  case SQL_FETCH_ABSOLUTE:
16536  if (offset == 0) {
16537  s->rowp = s->rowprs = -1;
16538  return SQL_NO_DATA;
16539  } else if (offset < 0) {
16540  if (0 - offset <= s->nrows) {
16541  s->rowp = s->nrows + offset - 1;
16542  break;
16543  }
16544  s->rowp = s->rowprs = -1;
16545  return SQL_NO_DATA;
16546  } else if (offset > s->nrows) {
16547  s->rowp = s->rowprs = s->nrows;
16548  return SQL_NO_DATA;
16549  }
16550  s->rowp = offset - 1 - 1;
16551  break;
16552  case SQL_FETCH_RELATIVE:
16553  if (offset >= 0) {
16554  s->rowp += offset * s->rowset_size - 1;
16555  if (s->rowp >= s->nrows) {
16556  s->rowp = s->rowprs = s->nrows;
16557  return SQL_NO_DATA;
16558  }
16559  } else {
16560  s->rowp += offset * s->rowset_size - 1;
16561  if (s->rowp < -1) {
16562  s->rowp = s->rowprs = -1;
16563  return SQL_NO_DATA;
16564  }
16565  }
16566  break;
16567  case SQL_FETCH_BOOKMARK:
16568  if (s->bkmrk == SQL_UB_ON && !s->bkmrkptr) {
16569  if (offset < 0 || offset >= s->nrows) {
16570  return SQL_NO_DATA;
16571  }
16572  s->rowp = offset - 1;
16573  break;
16574  }
16575  if (s->bkmrk != SQL_UB_OFF && s->bkmrkptr) {
16576  int rowp;
16577 
16578  if (s->bkmrk == SQL_UB_VARIABLE) {
16579  if (s->has_rowid >= 0) {
16580  sqlite_int64 bkmrk, rowid;
16581 
16582  bkmrk = *(sqlite_int64 *) s->bkmrkptr;
16583  for (rowp = 0; rowp < s->nrows; rowp++) {
16584  char **data, *endp = 0;
16585 
16586  data = s->rows + s->ncols + (rowp * s->ncols)
16587  + s->has_rowid;
16588 #ifdef __osf__
16589  rowid = strtol(*data, &endp, 0);
16590 #else
16591  rowid = strtoll(*data, &endp, 0);
16592 #endif
16593  if (rowid == bkmrk) {
16594  break;
16595  }
16596  }
16597  } else {
16598  rowp = *(sqlite_int64 *) s->bkmrkptr;
16599  }
16600  } else {
16601  rowp = *(int *) s->bkmrkptr;
16602  }
16603  if (rowp + offset < 0 || rowp + offset >= s->nrows) {
16604  return SQL_NO_DATA;
16605  }
16606  s->rowp = rowp + offset - 1;
16607  break;
16608  }
16609  /* fall through */
16610  default:
16611  s->row_status0[0] = SQL_ROW_ERROR;
16612  ret = SQL_ERROR;
16613  goto done;
16614  }
16615  s->rowprs = s->rowp + 1;
16616  for (; i < s->rowset_size; i++) {
16617  ++s->rowp;
16618  if (s->rowp < 0 || s->rowp >= s->nrows) {
16619  break;
16620  }
16621  ret = dofetchbind(s, i);
16622  if (!SQL_SUCCEEDED(ret)) {
16623  break;
16624  } else if (ret == SQL_SUCCESS_WITH_INFO) {
16625  withinfo = 1;
16626  }
16627  }
16628  }
16629 done:
16630  if (i == 0) {
16631  if (SQL_SUCCEEDED(ret)) {
16632  return SQL_NO_DATA;
16633  }
16634  return ret;
16635  }
16636  if (SQL_SUCCEEDED(ret)) {
16637  ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16638  }
16639 done2:
16640  if (s->row_status) {
16641  memcpy(s->row_status, s->row_status0,
16642  sizeof (SQLUSMALLINT) * s->rowset_size);
16643  }
16644  s->row_count0 = i;
16645  if (s->row_count) {
16646  *s->row_count = s->row_count0;
16647  }
16648  return ret;
16649 }
16650 
16657 SQLRETURN SQL_API
16658 SQLFetch(SQLHSTMT stmt)
16659 {
16660  SQLRETURN ret;
16661 
16662  HSTMT_LOCK(stmt);
16663  ret = drvfetchscroll(stmt, SQL_FETCH_NEXT, 0);
16664  HSTMT_UNLOCK(stmt);
16665  return ret;
16666 }
16667 
16676 SQLRETURN SQL_API
16677 SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLLEN offset)
16678 {
16679  SQLRETURN ret;
16680 
16681  HSTMT_LOCK(stmt);
16682  ret = drvfetchscroll(stmt, orient, offset);
16683  HSTMT_UNLOCK(stmt);
16684  return ret;
16685 }
16686 
16697 SQLRETURN SQL_API
16698 SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT orient, SQLROWOFFSET offset,
16699  SQLROWSETSIZE *rowcount, SQLUSMALLINT *rowstatus)
16700 {
16701  STMT *s;
16702  SQLRETURN ret;
16703  SQLUSMALLINT *rst;
16704  SQLINTEGER *bkmrkptr;
16705 
16706  HSTMT_LOCK(stmt);
16707  if (stmt == SQL_NULL_HSTMT) {
16708  return SQL_INVALID_HANDLE;
16709  }
16710  s = (STMT *) stmt;
16711  /* temporarily turn off SQL_ATTR_ROW_STATUS_PTR */
16712  rst = s->row_status;
16713  s->row_status = 0;
16714  bkmrkptr = s->bkmrkptr;
16715  s->bkmrkptr = 0;
16716  ret = drvfetchscroll(stmt, orient, offset);
16717  s->row_status = rst;
16718  s->bkmrkptr = bkmrkptr;
16719  if (rowstatus) {
16720  memcpy(rowstatus, s->row_status0,
16721  sizeof (SQLUSMALLINT) * s->rowset_size);
16722  }
16723  if (rowcount) {
16724  *rowcount = s->row_count0;
16725  }
16726  HSTMT_UNLOCK(stmt);
16727  return ret;
16728 }
16729 
16737 SQLRETURN SQL_API
16738 SQLRowCount(SQLHSTMT stmt, SQLLEN *nrows)
16739 {
16740  STMT *s;
16741 
16742  HSTMT_LOCK(stmt);
16743  if (stmt == SQL_NULL_HSTMT) {
16744  return SQL_INVALID_HANDLE;
16745  }
16746  s = (STMT *) stmt;
16747  if (nrows) {
16748  *nrows = s->isselect ? 0 : s->nrows;
16749  }
16750  HSTMT_UNLOCK(stmt);
16751  return SQL_SUCCESS;
16752 }
16753 
16761 SQLRETURN SQL_API
16762 SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *ncols)
16763 {
16764  STMT *s;
16765 
16766  HSTMT_LOCK(stmt);
16767  if (stmt == SQL_NULL_HSTMT) {
16768  return SQL_INVALID_HANDLE;
16769  }
16770  s = (STMT *) stmt;
16771  if (ncols) {
16772  *ncols = s->ncols;
16773  }
16774  HSTMT_UNLOCK(stmt);
16775  return SQL_SUCCESS;
16776 }
16777 
16792 static SQLRETURN
16793 drvdescribecol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
16794  SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
16795  SQLSMALLINT *type, SQLULEN *size,
16796  SQLSMALLINT *digits, SQLSMALLINT *nullable)
16797 {
16798  STMT *s;
16799  COL *c;
16800  int didname = 0;
16801 
16802  if (stmt == SQL_NULL_HSTMT) {
16803  return SQL_INVALID_HANDLE;
16804  }
16805  s = (STMT *) stmt;
16806  if (!s->cols) {
16807  setstat(s, -1, "no columns", (*s->ov3) ? "07009" : "S1002");
16808  return SQL_ERROR;
16809  }
16810  if (col < 1 || col > s->ncols) {
16811  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
16812  return SQL_ERROR;
16813  }
16814  c = s->cols + col - 1;
16815  if (name && nameMax > 0) {
16816  strncpy((char *) name, c->column, nameMax);
16817  name[nameMax - 1] = '\0';
16818  didname = 1;
16819  }
16820  if (nameLen) {
16821  if (didname) {
16822  *nameLen = strlen((char *) name);
16823  } else {
16824  *nameLen = strlen(c->column);
16825  }
16826  }
16827  if (type) {
16828  *type = c->type;
16829 #ifdef WINTERFACE
16830  if (s->nowchar[0] || s->nowchar[1]) {
16831  switch (c->type) {
16832  case SQL_WCHAR:
16833  *type = SQL_CHAR;
16834  break;
16835  case SQL_WVARCHAR:
16836  *type = SQL_VARCHAR;
16837  break;
16838 #ifdef SQL_LONGVARCHAR
16839  case SQL_WLONGVARCHAR:
16840  *type = SQL_LONGVARCHAR;
16841  break;
16842 #endif
16843  }
16844  }
16845 #endif
16846  }
16847  if (size) {
16848  *size = c->size;
16849  }
16850  if (digits) {
16851  *digits = 0;
16852  }
16853  if (nullable) {
16854  *nullable = 1;
16855  }
16856  return SQL_SUCCESS;
16857 }
16858 
16859 #ifndef WINTERFACE
16860 
16874 SQLRETURN SQL_API
16875 SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
16876  SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
16877  SQLSMALLINT *type, SQLULEN *size,
16878  SQLSMALLINT *digits, SQLSMALLINT *nullable)
16879 {
16880 #if defined(_WIN32) || defined(_WIN64)
16881  SQLSMALLINT len = 0;
16882 #endif
16883  SQLRETURN ret;
16884 
16885  HSTMT_LOCK(stmt);
16886 #if defined(_WIN32) || defined(_WIN64)
16887  if (!((STMT *) stmt)->oemcp[0]) {
16888  ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
16889  type, size, digits, nullable);
16890  goto done;
16891  }
16892  ret = drvdescribecol(stmt, col, name, nameMax,
16893  &len, type, size, digits, nullable);
16894  if (ret == SQL_SUCCESS) {
16895  if (name) {
16896  if (len > 0) {
16897  SQLCHAR *n = NULL;
16898 
16899  n = (SQLCHAR *) utf_to_wmb((char *) name, len);
16900  if (n) {
16901  strncpy((char *) name, (char *) n, nameMax);
16902  n[len] = 0;
16903  len = min(nameMax, strlen((char *) n));
16904  uc_free(n);
16905  } else {
16906  len = 0;
16907  }
16908  }
16909  if (len <= 0) {
16910  len = 0;
16911  if (nameMax > 0) {
16912  name[0] = 0;
16913  }
16914  }
16915  } else {
16916  STMT *s = (STMT *) stmt;
16917  COL *c = s->cols + col - 1;
16918 
16919  len = 0;
16920  if (c->column) {
16921  len = strlen(c->column);
16922  }
16923  }
16924  if (nameLen) {
16925  *nameLen = len;
16926  }
16927  }
16928 done:
16929  ;
16930 #else
16931  ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
16932  type, size, digits, nullable);
16933 #endif
16934  HSTMT_UNLOCK(stmt);
16935  return ret;
16936 }
16937 #endif
16938 
16939 #ifdef WINTERFACE
16940 
16954 SQLRETURN SQL_API
16955 SQLDescribeColW(SQLHSTMT stmt, SQLUSMALLINT col, SQLWCHAR *name,
16956  SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
16957  SQLSMALLINT *type, SQLULEN *size,
16958  SQLSMALLINT *digits, SQLSMALLINT *nullable)
16959 {
16960  SQLRETURN ret;
16961  SQLSMALLINT len = 0;
16962 
16963  HSTMT_LOCK(stmt);
16964  ret = drvdescribecol(stmt, col, (SQLCHAR *) name,
16965  (SQLSMALLINT) (nameMax * sizeof (SQLWCHAR)),
16966  &len, type, size, digits, nullable);
16967  if (ret == SQL_SUCCESS) {
16968  if (name) {
16969  if (len > 0) {
16970  SQLWCHAR *n = NULL;
16971 
16972  n = uc_from_utf((SQLCHAR *) name, len);
16973  if (n) {
16974  uc_strncpy(name, n, nameMax);
16975  n[len] = 0;
16976  len = min(nameMax, uc_strlen(n));
16977  uc_free(n);
16978  } else {
16979  len = 0;
16980  }
16981  }
16982  if (len <= 0) {
16983  len = 0;
16984  if (nameMax > 0) {
16985  name[0] = 0;
16986  }
16987  }
16988  } else {
16989  STMT *s = (STMT *) stmt;
16990  COL *c = s->cols + col - 1;
16991 
16992  len = 0;
16993  if (c->column) {
16994  len = strlen(c->column);
16995  }
16996  }
16997  if (nameLen) {
16998  *nameLen = len;
16999  }
17000  }
17001  HSTMT_UNLOCK(stmt);
17002  return ret;
17003 }
17004 #endif
17005 
17018 static SQLRETURN
17019 drvcolattributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17020  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17021  SQLLEN *val2)
17022 {
17023  STMT *s;
17024  COL *c;
17025  SQLSMALLINT dummy;
17026  char *valc = (char *) val;
17027 
17028  if (stmt == SQL_NULL_HSTMT) {
17029  return SQL_INVALID_HANDLE;
17030  }
17031  s = (STMT *) stmt;
17032  if (!s->cols) {
17033  return SQL_ERROR;
17034  }
17035  if (!valLen) {
17036  valLen = &dummy;
17037  }
17038  if (id == SQL_COLUMN_COUNT) {
17039  if (val2) {
17040  *val2 = s->ncols;
17041  }
17042  *valLen = sizeof (int);
17043  return SQL_SUCCESS;
17044  }
17045  if (id == SQL_COLUMN_TYPE && col == 0) {
17046  if (val2) {
17047  *val2 = SQL_INTEGER;
17048  }
17049  *valLen = sizeof (int);
17050  return SQL_SUCCESS;
17051  }
17052 #ifdef SQL_DESC_OCTET_LENGTH
17053  if (id == SQL_DESC_OCTET_LENGTH && col == 0) {
17054  if (val2) {
17055  *val2 = 4;
17056  }
17057  *valLen = sizeof (int);
17058  return SQL_SUCCESS;
17059  }
17060 #endif
17061  if (col < 1 || col > s->ncols) {
17062  setstat(s, -1, "invalid column", (*s->ov3) ? "07009": "S1002");
17063  return SQL_ERROR;
17064  }
17065  c = s->cols + col - 1;
17066 
17067  switch (id) {
17068  case SQL_COLUMN_LABEL:
17069  if (c->label) {
17070  if (valc && valMax > 0) {
17071  strncpy(valc, c->label, valMax);
17072  valc[valMax - 1] = '\0';
17073  }
17074  *valLen = strlen(c->label);
17075  goto checkLen;
17076  }
17077  /* fall through */
17078  case SQL_COLUMN_NAME:
17079  case SQL_DESC_NAME:
17080  if (valc && valMax > 0) {
17081  strncpy(valc, c->column, valMax);
17082  valc[valMax - 1] = '\0';
17083  }
17084  *valLen = strlen(c->column);
17085 checkLen:
17086  if (*valLen >= valMax) {
17087  setstat(s, -1, "data right truncated", "01004");
17088  return SQL_SUCCESS_WITH_INFO;
17089  }
17090  return SQL_SUCCESS;
17091 #ifdef SQL_DESC_BASE_COLUMN_NAME
17092  case SQL_DESC_BASE_COLUMN_NAME:
17093  if (strchr(c->column, '(') || strchr(c->column, ')')) {
17094  if (valc && valMax > 0) {
17095  valc[0] = '\0';
17096  }
17097  *valLen = 0;
17098  } else if (valc && valMax > 0) {
17099  strncpy(valc, c->column, valMax);
17100  valc[valMax - 1] = '\0';
17101  *valLen = strlen(c->column);
17102  }
17103  goto checkLen;
17104 #endif
17105  case SQL_COLUMN_TYPE:
17106  case SQL_DESC_TYPE:
17107 #ifdef WINTERFACE
17108  {
17109  int type = c->type;
17110 
17111  if (s->nowchar[0] || s->nowchar[1]) {
17112  switch (type) {
17113  case SQL_WCHAR:
17114  type = SQL_CHAR;
17115  break;
17116  case SQL_WVARCHAR:
17117  type = SQL_VARCHAR;
17118  break;
17119 #ifdef SQL_LONGVARCHAR
17120  case SQL_WLONGVARCHAR:
17121  type = SQL_LONGVARCHAR;
17122  break;
17123  }
17124  }
17125  if (val2) {
17126  *val2 = type;
17127  }
17128 #endif
17129  }
17130 #else
17131  if (val2) {
17132  *val2 = c->type;
17133  }
17134 #endif
17135  *valLen = sizeof (int);
17136  return SQL_SUCCESS;
17137  case SQL_COLUMN_DISPLAY_SIZE:
17138  if (val2) {
17139  *val2 = c->size;
17140  }
17141  *valLen = sizeof (int);
17142  return SQL_SUCCESS;
17143  case SQL_COLUMN_UNSIGNED:
17144  if (val2) {
17145  *val2 = c->nosign ? SQL_TRUE : SQL_FALSE;
17146  }
17147  *valLen = sizeof (int);
17148  return SQL_SUCCESS;
17149  case SQL_COLUMN_SCALE:
17150  case SQL_DESC_SCALE:
17151  if (val2) {
17152  *val2 = c->scale;
17153  }
17154  *valLen = sizeof (int);
17155  return SQL_SUCCESS;
17156  case SQL_COLUMN_PRECISION:
17157  case SQL_DESC_PRECISION:
17158  if (val2) {
17159  switch (c->type) {
17160  case SQL_SMALLINT:
17161  *val2 = 5;
17162  break;
17163  case SQL_INTEGER:
17164  *val2 = 10;
17165  break;
17166  case SQL_FLOAT:
17167  case SQL_REAL:
17168  case SQL_DOUBLE:
17169  *val2 = 15;
17170  break;
17171  case SQL_DATE:
17172  *val2 = 0;
17173  break;
17174  case SQL_TIME:
17175  *val2 = 0;
17176  break;
17177 #ifdef SQL_TYPE_TIMESTAMP
17178  case SQL_TYPE_TIMESTAMP:
17179 #endif
17180  case SQL_TIMESTAMP:
17181  *val2 = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
17182  break;
17183  default:
17184  *val2 = c->prec;
17185  break;
17186  }
17187  }
17188  *valLen = sizeof (int);
17189  return SQL_SUCCESS;
17190  case SQL_COLUMN_MONEY:
17191  if (val2) {
17192  *val2 = SQL_FALSE;
17193  }
17194  *valLen = sizeof (int);
17195  return SQL_SUCCESS;
17196  case SQL_COLUMN_AUTO_INCREMENT:
17197  if (val2) {
17198  *val2 = c->autoinc;
17199  }
17200  *valLen = sizeof (int);
17201  return SQL_SUCCESS;
17202  case SQL_COLUMN_LENGTH:
17203  case SQL_DESC_LENGTH:
17204  if (val2) {
17205  *val2 = c->size;
17206  }
17207  *valLen = sizeof (int);
17208  return SQL_SUCCESS;
17209  case SQL_COLUMN_NULLABLE:
17210  case SQL_DESC_NULLABLE:
17211  if (val2) {
17212  *val2 = c->notnull;
17213  }
17214  *valLen = sizeof (int);
17215  return SQL_SUCCESS;
17216  case SQL_COLUMN_SEARCHABLE:
17217  if (val2) {
17218  *val2 = SQL_SEARCHABLE;
17219  }
17220  *valLen = sizeof (int);
17221  return SQL_SUCCESS;
17222  case SQL_COLUMN_CASE_SENSITIVE:
17223  if (val2) {
17224  *val2 = SQL_TRUE;
17225  }
17226  *valLen = sizeof (int);
17227  return SQL_SUCCESS;
17228  case SQL_COLUMN_UPDATABLE:
17229  if (val2) {
17230  *val2 = SQL_TRUE;
17231  }
17232  *valLen = sizeof (int);
17233  return SQL_SUCCESS;
17234  case SQL_DESC_COUNT:
17235  if (val2) {
17236  *val2 = s->ncols;
17237  }
17238  *valLen = sizeof (int);
17239  return SQL_SUCCESS;
17240  case SQL_COLUMN_TYPE_NAME: {
17241  char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17242 
17243 #ifdef WINTERFACE
17244  if (c->type == SQL_WCHAR ||
17245  c->type == SQL_WVARCHAR ||
17246  c->type == SQL_WLONGVARCHAR) {
17247  if (!(s->nowchar[0] || s->nowchar[1])) {
17248  if (strcasecmp(tn, "varchar") == 0) {
17249  tn = "wvarchar";
17250  }
17251  }
17252  }
17253 #endif
17254  if (valc && valMax > 0) {
17255  strncpy(valc, tn, valMax);
17256  valc[valMax - 1] = '\0';
17257  p = strchr(valc, '(');
17258  if (p) {
17259  *p = '\0';
17260  while (p > valc && ISSPACE(p[-1])) {
17261  --p;
17262  *p = '\0';
17263  }
17264  }
17265  *valLen = strlen(valc);
17266  } else {
17267  *valLen = strlen(tn);
17268  p = strchr(tn, '(');
17269  if (p) {
17270  *valLen = p - tn;
17271  while (p > tn && ISSPACE(p[-1])) {
17272  --p;
17273  *valLen -= 1;
17274  }
17275  }
17276  }
17277  goto checkLen;
17278  }
17279  case SQL_COLUMN_OWNER_NAME:
17280  case SQL_COLUMN_QUALIFIER_NAME: {
17281  char *z = "";
17282 
17283  if (valc && valMax > 0) {
17284  strncpy(valc, z, valMax);
17285  valc[valMax - 1] = '\0';
17286  }
17287  *valLen = strlen(z);
17288  goto checkLen;
17289  }
17290  case SQL_COLUMN_TABLE_NAME:
17291 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17292  case SQL_DESC_TABLE_NAME:
17293 #endif
17294 #ifdef SQL_DESC_BASE_TABLE_NAME
17295  case SQL_DESC_BASE_TABLE_NAME:
17296 #endif
17297  if (valc && valMax > 0) {
17298  strncpy(valc, c->table, valMax);
17299  valc[valMax - 1] = '\0';
17300  }
17301  *valLen = strlen(c->table);
17302  goto checkLen;
17303 #ifdef SQL_DESC_NUM_PREC_RADIX
17304  case SQL_DESC_NUM_PREC_RADIX:
17305  if (val2) {
17306  switch (c->type) {
17307 #ifdef WINTERFACE
17308  case SQL_WCHAR:
17309  case SQL_WVARCHAR:
17310 #ifdef SQL_LONGVARCHAR
17311  case SQL_WLONGVARCHAR:
17312 #endif
17313 #endif
17314  case SQL_CHAR:
17315  case SQL_VARCHAR:
17316 #ifdef SQL_LONGVARCHAR
17317  case SQL_LONGVARCHAR:
17318 #endif
17319  case SQL_BINARY:
17320  case SQL_VARBINARY:
17321  case SQL_LONGVARBINARY:
17322  *val2 = 0;
17323  break;
17324  default:
17325  *val2 = 2;
17326  }
17327  }
17328  *valLen = sizeof (int);
17329  return SQL_SUCCESS;
17330 #endif
17331  }
17332  setstat(s, -1, "unsupported column attributes %d", "HY091", id);
17333  return SQL_ERROR;
17334 }
17335 
17336 #ifndef WINTERFACE
17337 
17349 SQLRETURN SQL_API
17350 SQLColAttributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17351  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17352  SQLLEN *val2)
17353 {
17354 #if defined(_WIN32) || defined(_WIN64)
17355  SQLSMALLINT len = 0;
17356 #endif
17357  SQLRETURN ret;
17358 
17359  HSTMT_LOCK(stmt);
17360 #if defined(_WIN32) || defined(_WIN64)
17361  if (!((STMT *) stmt)->oemcp[0]) {
17362  ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17363  goto done;
17364  }
17365  ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17366  if (SQL_SUCCEEDED(ret)) {
17367  char *v = NULL;
17368 
17369  switch (id) {
17370  case SQL_COLUMN_LABEL:
17371  case SQL_COLUMN_NAME:
17372  case SQL_DESC_NAME:
17373  case SQL_COLUMN_TYPE_NAME:
17374  case SQL_COLUMN_OWNER_NAME:
17375  case SQL_COLUMN_QUALIFIER_NAME:
17376  case SQL_COLUMN_TABLE_NAME:
17377 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17378  case SQL_DESC_TABLE_NAME:
17379 #endif
17380 #ifdef SQL_DESC_BASE_COLUMN_NAME
17381  case SQL_DESC_BASE_COLUMN_NAME:
17382 #endif
17383 #ifdef SQL_DESC_BASE_TABLE_NAME
17384  case SQL_DESC_BASE_TABLE_NAME:
17385 #endif
17386  if (val && valMax > 0) {
17387  int vmax = valMax;
17388 
17389  v = utf_to_wmb((char *) val, SQL_NTS);
17390  if (v) {
17391  strncpy(val, v, vmax);
17392  len = min(vmax, strlen(v));
17393  uc_free(v);
17394  }
17395  if (vmax > 0) {
17396  v = (char *) val;
17397  v[vmax - 1] = '\0';
17398  }
17399  }
17400  if (len <= 0) {
17401  len = 0;
17402  }
17403  break;
17404  }
17405  if (valLen) {
17406  *valLen = len;
17407  }
17408  }
17409 done:
17410  ;
17411 #else
17412  ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17413 #endif
17414  HSTMT_UNLOCK(stmt);
17415  return ret;
17416 }
17417 #endif
17418 
17419 #ifdef WINTERFACE
17420 
17432 SQLRETURN SQL_API
17433 SQLColAttributesW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17434  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17435  SQLLEN *val2)
17436 {
17437  SQLRETURN ret;
17438  SQLSMALLINT len = 0;
17439 
17440  HSTMT_LOCK(stmt);
17441  ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17442  if (SQL_SUCCEEDED(ret)) {
17443  SQLWCHAR *v = NULL;
17444 
17445  switch (id) {
17446  case SQL_COLUMN_LABEL:
17447  case SQL_COLUMN_NAME:
17448  case SQL_DESC_NAME:
17449  case SQL_COLUMN_TYPE_NAME:
17450  case SQL_COLUMN_OWNER_NAME:
17451  case SQL_COLUMN_QUALIFIER_NAME:
17452  case SQL_COLUMN_TABLE_NAME:
17453 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17454  case SQL_DESC_TABLE_NAME:
17455 #endif
17456 #ifdef SQL_DESC_BASE_COLUMN_NAME
17457  case SQL_DESC_BASE_COLUMN_NAME:
17458 #endif
17459 #ifdef SQL_DESC_BASE_TABLE_NAME
17460  case SQL_DESC_BASE_TABLE_NAME:
17461 #endif
17462  if (val && valMax > 0) {
17463  int vmax = valMax / sizeof (SQLWCHAR);
17464 
17465  v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
17466  if (v) {
17467  uc_strncpy(val, v, vmax);
17468  len = min(vmax, uc_strlen(v));
17469  uc_free(v);
17470  len *= sizeof (SQLWCHAR);
17471  }
17472  if (vmax > 0) {
17473  v = (SQLWCHAR *) val;
17474  v[vmax - 1] = '\0';
17475  }
17476  }
17477  if (len <= 0) {
17478  len = 0;
17479  }
17480  break;
17481  }
17482  if (valLen) {
17483  *valLen = len;
17484  }
17485  }
17486  HSTMT_UNLOCK(stmt);
17487  return ret;
17488 }
17489 #endif
17490 
17503 static SQLRETURN
17504 drvcolattribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17505  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17506  SQLPOINTER val2)
17507 {
17508  STMT *s;
17509  COL *c;
17510  int v = 0;
17511  char *valc = (char *) val;
17512  SQLSMALLINT dummy;
17513 
17514  if (stmt == SQL_NULL_HSTMT) {
17515  return SQL_INVALID_HANDLE;
17516  }
17517  s = (STMT *) stmt;
17518  if (!s->cols) {
17519  return SQL_ERROR;
17520  }
17521  if (col < 1 || col > s->ncols) {
17522  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
17523  return SQL_ERROR;
17524  }
17525  if (!valLen) {
17526  valLen = &dummy;
17527  }
17528  c = s->cols + col - 1;
17529  switch (id) {
17530  case SQL_DESC_COUNT:
17531  v = s->ncols;
17532  break;
17533  case SQL_DESC_CATALOG_NAME:
17534  if (valc && valMax > 0) {
17535  strncpy(valc, c->db, valMax);
17536  valc[valMax - 1] = '\0';
17537  }
17538  *valLen = strlen(c->db);
17539 checkLen:
17540  if (*valLen >= valMax) {
17541  setstat(s, -1, "data right truncated", "01004");
17542  return SQL_SUCCESS_WITH_INFO;
17543  }
17544  break;
17545  case SQL_COLUMN_LENGTH:
17546  case SQL_DESC_LENGTH:
17547  v = c->size;
17548  break;
17549  case SQL_COLUMN_LABEL:
17550  if (c->label) {
17551  if (valc && valMax > 0) {
17552  strncpy(valc, c->label, valMax);
17553  valc[valMax - 1] = '\0';
17554  }
17555  *valLen = strlen(c->label);
17556  goto checkLen;
17557  }
17558  /* fall through */
17559  case SQL_COLUMN_NAME:
17560  case SQL_DESC_NAME:
17561  if (valc && valMax > 0) {
17562  strncpy(valc, c->column, valMax);
17563  valc[valMax - 1] = '\0';
17564  }
17565  *valLen = strlen(c->column);
17566  goto checkLen;
17567  case SQL_DESC_SCHEMA_NAME: {
17568  char *z = "";
17569 
17570  if (valc && valMax > 0) {
17571  strncpy(valc, z, valMax);
17572  valc[valMax - 1] = '\0';
17573  }
17574  *valLen = strlen(z);
17575  goto checkLen;
17576  }
17577 #ifdef SQL_DESC_BASE_COLUMN_NAME
17578  case SQL_DESC_BASE_COLUMN_NAME:
17579  if (strchr(c->column, '(') || strchr(c->column, ')')) {
17580  valc[0] = '\0';
17581  *valLen = 0;
17582  } else if (valc && valMax > 0) {
17583  strncpy(valc, c->column, valMax);
17584  valc[valMax - 1] = '\0';
17585  *valLen = strlen(c->column);
17586  }
17587  goto checkLen;
17588 #endif
17589  case SQL_DESC_TYPE_NAME: {
17590  char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17591 
17592 #ifdef WINTERFACE
17593  if (c->type == SQL_WCHAR ||
17594  c->type == SQL_WVARCHAR ||
17595  c->type == SQL_WLONGVARCHAR) {
17596  if (!(s->nowchar[0] || s->nowchar[1])) {
17597  if (strcasecmp(tn, "varchar") == 0) {
17598  tn = "wvarchar";
17599  }
17600  }
17601  }
17602 #endif
17603  if (valc && valMax > 0) {
17604  strncpy(valc, tn, valMax);
17605  valc[valMax - 1] = '\0';
17606  p = strchr(valc, '(');
17607  if (p) {
17608  *p = '\0';
17609  while (p > valc && ISSPACE(p[-1])) {
17610  --p;
17611  *p = '\0';
17612  }
17613  }
17614  *valLen = strlen(valc);
17615  } else {
17616  *valLen = strlen(tn);
17617  p = strchr(tn, '(');
17618  if (p) {
17619  *valLen = p - tn;
17620  while (p > tn && ISSPACE(p[-1])) {
17621  --p;
17622  *valLen -= 1;
17623  }
17624  }
17625  }
17626  goto checkLen;
17627  }
17628  case SQL_DESC_OCTET_LENGTH:
17629  v = c->size;
17630 #ifdef WINTERFACE
17631  if (c->type == SQL_WCHAR ||
17632  c->type == SQL_WVARCHAR ||
17633  c->type == SQL_WLONGVARCHAR) {
17634  if (!(s->nowchar[0] || s->nowchar[1])) {
17635  v *= sizeof (SQLWCHAR);
17636  }
17637  }
17638 #endif
17639  break;
17640 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17641  case SQL_COLUMN_TABLE_NAME:
17642 #endif
17643 #ifdef SQL_DESC_BASE_TABLE_NAME
17644  case SQL_DESC_BASE_TABLE_NAME:
17645 #endif
17646  case SQL_DESC_TABLE_NAME:
17647  if (valc && valMax > 0) {
17648  strncpy(valc, c->table, valMax);
17649  valc[valMax - 1] = '\0';
17650  }
17651  *valLen = strlen(c->table);
17652  goto checkLen;
17653  case SQL_DESC_TYPE:
17654  v = c->type;
17655 #ifdef WINTERFACE
17656  if (s->nowchar[0] || s->nowchar[1]) {
17657  switch (v) {
17658  case SQL_WCHAR:
17659  v = SQL_CHAR;
17660  break;
17661  case SQL_WVARCHAR:
17662  v = SQL_VARCHAR;
17663  break;
17664 #ifdef SQL_LONGVARCHAR
17665  case SQL_WLONGVARCHAR:
17666  v = SQL_LONGVARCHAR;
17667  break;
17668 #endif
17669  }
17670  }
17671 #endif
17672  break;
17673  case SQL_DESC_CONCISE_TYPE:
17674  switch (c->type) {
17675  case SQL_INTEGER:
17676  v = SQL_C_LONG;
17677  break;
17678  case SQL_TINYINT:
17679  v = SQL_C_TINYINT;
17680  break;
17681  case SQL_SMALLINT:
17682  v = SQL_C_SHORT;
17683  break;
17684  case SQL_FLOAT:
17685  v = SQL_C_FLOAT;
17686  break;
17687  case SQL_DOUBLE:
17688  v = SQL_C_DOUBLE;
17689  break;
17690  case SQL_TIMESTAMP:
17691  v = SQL_C_TIMESTAMP;
17692  break;
17693  case SQL_TIME:
17694  v = SQL_C_TIME;
17695  break;
17696  case SQL_DATE:
17697  v = SQL_C_DATE;
17698  break;
17699 #ifdef SQL_C_TYPE_TIMESTAMP
17700  case SQL_TYPE_TIMESTAMP:
17701  v = SQL_C_TYPE_TIMESTAMP;
17702  break;
17703 #endif
17704 #ifdef SQL_C_TYPE_TIME
17705  case SQL_TYPE_TIME:
17706  v = SQL_C_TYPE_TIME;
17707  break;
17708 #endif
17709 #ifdef SQL_C_TYPE_DATE
17710  case SQL_TYPE_DATE:
17711  v = SQL_C_TYPE_DATE;
17712  break;
17713 #endif
17714 #ifdef SQL_BIT
17715  case SQL_BIT:
17716  v = SQL_C_BIT;
17717  break;
17718 #endif
17719 #ifdef SQL_BIGINT
17720  case SQL_BIGINT:
17721  v = SQL_C_SBIGINT;
17722  break;
17723 #endif
17724  default:
17725 #ifdef WINTERFACE
17726  v = (s->nowchar[0] || s->nowchar[1]) ? SQL_C_CHAR : SQL_C_WCHAR;
17727 #else
17728  v = SQL_C_CHAR;
17729 #endif
17730  break;
17731  }
17732  break;
17733  case SQL_DESC_UPDATABLE:
17734  v = SQL_TRUE;
17735  break;
17736  case SQL_COLUMN_DISPLAY_SIZE:
17737  v = c->size;
17738  break;
17739  case SQL_COLUMN_UNSIGNED:
17740  v = c->nosign ? SQL_TRUE : SQL_FALSE;
17741  break;
17742  case SQL_COLUMN_SEARCHABLE:
17743  v = SQL_SEARCHABLE;
17744  break;
17745  case SQL_COLUMN_SCALE:
17746  case SQL_DESC_SCALE:
17747  v = c->scale;
17748  break;
17749  case SQL_COLUMN_PRECISION:
17750  case SQL_DESC_PRECISION:
17751  switch (c->type) {
17752  case SQL_SMALLINT:
17753  v = 5;
17754  break;
17755  case SQL_INTEGER:
17756  v = 10;
17757  break;
17758  case SQL_FLOAT:
17759  case SQL_REAL:
17760  case SQL_DOUBLE:
17761  v = 15;
17762  break;
17763  case SQL_DATE:
17764  v = 0;
17765  break;
17766  case SQL_TIME:
17767  v = 0;
17768  break;
17769 #ifdef SQL_TYPE_TIMESTAMP
17770  case SQL_TYPE_TIMESTAMP:
17771 #endif
17772  case SQL_TIMESTAMP:
17773  v = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
17774  break;
17775  default:
17776  v = c->prec;
17777  break;
17778  }
17779  break;
17780  case SQL_COLUMN_MONEY:
17781  v = SQL_FALSE;
17782  break;
17783  case SQL_COLUMN_AUTO_INCREMENT:
17784  v = c->autoinc;
17785  break;
17786  case SQL_DESC_NULLABLE:
17787  v = c->notnull;
17788  break;
17789 #ifdef SQL_DESC_NUM_PREC_RADIX
17790  case SQL_DESC_NUM_PREC_RADIX:
17791  switch (c->type) {
17792 #ifdef WINTERFACE
17793  case SQL_WCHAR:
17794  case SQL_WVARCHAR:
17795 #ifdef SQL_LONGVARCHAR
17796  case SQL_WLONGVARCHAR:
17797 #endif
17798 #endif
17799  case SQL_CHAR:
17800  case SQL_VARCHAR:
17801 #ifdef SQL_LONGVARCHAR
17802  case SQL_LONGVARCHAR:
17803 #endif
17804  case SQL_BINARY:
17805  case SQL_VARBINARY:
17806  case SQL_LONGVARBINARY:
17807  v = 0;
17808  break;
17809  default:
17810  v = 2;
17811  }
17812  break;
17813 #endif
17814  default:
17815  setstat(s, -1, "unsupported column attribute %d", "HY091", id);
17816  return SQL_ERROR;
17817  }
17818  if (val2) {
17819  *(SQLLEN *) val2 = v;
17820  }
17821  return SQL_SUCCESS;
17822 }
17823 
17824 #ifndef WINTERFACE
17825 
17837 SQLRETURN SQL_API
17838 SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17839  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17841 {
17842 #if defined(_WIN32) || defined(_WIN64)
17843  SQLSMALLINT len = 0;
17844 #endif
17845  SQLRETURN ret;
17846 
17847  HSTMT_LOCK(stmt);
17848 #if defined(_WIN32) || defined(_WIN64)
17849  if (!((STMT *) stmt)->oemcp[0]) {
17850  ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
17851  (SQLPOINTER) val2);
17852  goto done;
17853  }
17854  ret = drvcolattribute(stmt, col, id, val, valMax, &len,
17855  (SQLPOINTER) val2);
17856  if (SQL_SUCCEEDED(ret)) {
17857  char *v = NULL;
17858 
17859  switch (id) {
17860  case SQL_DESC_SCHEMA_NAME:
17861  case SQL_DESC_CATALOG_NAME:
17862  case SQL_COLUMN_LABEL:
17863  case SQL_DESC_NAME:
17864  case SQL_DESC_TABLE_NAME:
17865 #ifdef SQL_DESC_BASE_TABLE_NAME
17866  case SQL_DESC_BASE_TABLE_NAME:
17867 #endif
17868 #ifdef SQL_DESC_BASE_COLUMN_NAME
17869  case SQL_DESC_BASE_COLUMN_NAME:
17870 #endif
17871  case SQL_DESC_TYPE_NAME:
17872  if (val && valMax > 0) {
17873  int vmax = valMax;
17874 
17875  v = utf_to_wmb((char *) val, SQL_NTS);
17876  if (v) {
17877  strncpy(val, v, vmax);
17878  len = min(vmax, strlen(v));
17879  uc_free(v);
17880  }
17881  if (vmax > 0) {
17882  v = (char *) val;
17883  v[vmax - 1] = '\0';
17884  }
17885  }
17886  if (len <= 0) {
17887  len = 0;
17888  }
17889  break;
17890  }
17891  if (valLen) {
17892  *valLen = len;
17893  }
17894  }
17895 done:
17896  ;
17897 #else
17898  ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
17899  (SQLPOINTER) val2);
17900 #endif
17901  HSTMT_UNLOCK(stmt);
17902  return ret;
17903 }
17904 #endif
17905 
17906 #ifdef WINTERFACE
17907 
17919 SQLRETURN SQL_API
17920 SQLColAttributeW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17921  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17923 {
17924  SQLRETURN ret;
17925  SQLSMALLINT len = 0;
17926 
17927  HSTMT_LOCK(stmt);
17928  ret = drvcolattribute(stmt, col, id, val, valMax, &len,
17929  (SQLPOINTER) val2);
17930  if (SQL_SUCCEEDED(ret)) {
17931  SQLWCHAR *v = NULL;
17932 
17933  switch (id) {
17934  case SQL_DESC_SCHEMA_NAME:
17935  case SQL_DESC_CATALOG_NAME:
17936  case SQL_COLUMN_LABEL:
17937  case SQL_DESC_NAME:
17938  case SQL_DESC_TABLE_NAME:
17939 #ifdef SQL_DESC_BASE_TABLE_NAME
17940  case SQL_DESC_BASE_TABLE_NAME:
17941 #endif
17942 #ifdef SQL_DESC_BASE_COLUMN_NAME
17943  case SQL_DESC_BASE_COLUMN_NAME:
17944 #endif
17945  case SQL_DESC_TYPE_NAME:
17946  if (val && valMax > 0) {
17947  int vmax = valMax / sizeof (SQLWCHAR);
17948 
17949  v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
17950  if (v) {
17951  uc_strncpy(val, v, vmax);
17952  len = min(vmax, uc_strlen(v));
17953  uc_free(v);
17954  len *= sizeof (SQLWCHAR);
17955  }
17956  if (vmax > 0) {
17957  v = (SQLWCHAR *) val;
17958  v[vmax - 1] = '\0';
17959  }
17960  }
17961  if (len <= 0) {
17962  len = 0;
17963  }
17964  break;
17965  }
17966  if (valLen) {
17967  *valLen = len;
17968  }
17969  }
17970  HSTMT_UNLOCK(stmt);
17971  return ret;
17972 }
17973 #endif
17974 
17988 static SQLRETURN
17989 drverror(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
17990  SQLCHAR *sqlState, SQLINTEGER *nativeErr,
17991  SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
17992 {
17993  SQLCHAR dummy0[6];
17994  SQLINTEGER dummy1;
17995  SQLSMALLINT dummy2;
17996 
17997  if (env == SQL_NULL_HENV &&
17998  dbc == SQL_NULL_HDBC &&
17999  stmt == SQL_NULL_HSTMT) {
18000  return SQL_INVALID_HANDLE;
18001  }
18002  if (sqlState) {
18003  sqlState[0] = '\0';
18004  } else {
18005  sqlState = dummy0;
18006  }
18007  if (!nativeErr) {
18008  nativeErr = &dummy1;
18009  }
18010  *nativeErr = 0;
18011  if (!errlen) {
18012  errlen = &dummy2;
18013  }
18014  *errlen = 0;
18015  if (errmsg) {
18016  if (errmax > 0) {
18017  errmsg[0] = '\0';
18018  }
18019  } else {
18020  errmsg = dummy0;
18021  errmax = 0;
18022  }
18023  if (stmt) {
18024  STMT *s = (STMT *) stmt;
18025 
18026  HSTMT_LOCK(stmt);
18027  if (s->logmsg[0] == '\0') {
18028  HSTMT_UNLOCK(stmt);
18029  goto noerr;
18030  }
18031  *nativeErr = s->naterr;
18032  strcpy((char *) sqlState, s->sqlstate);
18033  if (errmax == SQL_NTS) {
18034  strcpy((char *) errmsg, "[SQLite]");
18035  strcat((char *) errmsg, (char *) s->logmsg);
18036  *errlen = strlen((char *) errmsg);
18037  } else {
18038  strncpy((char *) errmsg, "[SQLite]", errmax);
18039  if (errmax - 8 > 0) {
18040  strncpy((char *) errmsg + 8, (char *) s->logmsg, errmax - 8);
18041  }
18042  *errlen = min(strlen((char *) s->logmsg) + 8, errmax);
18043  }
18044  s->logmsg[0] = '\0';
18045  HSTMT_UNLOCK(stmt);
18046  return SQL_SUCCESS;
18047  }
18048  if (dbc) {
18049  DBC *d = (DBC *) dbc;
18050 
18051  HDBC_LOCK(dbc);
18052  if (d->magic != DBC_MAGIC || d->logmsg[0] == '\0') {
18053  HDBC_UNLOCK(dbc);
18054  goto noerr;
18055  }
18056  *nativeErr = d->naterr;
18057  strcpy((char *) sqlState, d->sqlstate);
18058  if (errmax == SQL_NTS) {
18059  strcpy((char *) errmsg, "[SQLite]");
18060  strcat((char *) errmsg, (char *) d->logmsg);
18061  *errlen = strlen((char *) errmsg);
18062  } else {
18063  strncpy((char *) errmsg, "[SQLite]", errmax);
18064  if (errmax - 8 > 0) {
18065  strncpy((char *) errmsg + 8, (char *) d->logmsg, errmax - 8);
18066  }
18067  *errlen = min(strlen((char *) d->logmsg) + 8, errmax);
18068  }
18069  d->logmsg[0] = '\0';
18070  HDBC_UNLOCK(dbc);
18071  return SQL_SUCCESS;
18072  }
18073 noerr:
18074  sqlState[0] = '\0';
18075  errmsg[0] = '\0';
18076  *nativeErr = 0;
18077  *errlen = 0;
18078  return SQL_NO_DATA;
18079 }
18080 
18081 #ifndef WINTERFACE
18082 
18095 SQLRETURN SQL_API
18096 SQLError(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18097  SQLCHAR *sqlState, SQLINTEGER *nativeErr,
18098  SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18099 {
18100  return drverror(env, dbc, stmt, sqlState, nativeErr,
18101  errmsg, errmax, errlen);
18102 }
18103 #endif
18104 
18105 #ifdef WINTERFACE
18106 
18119 SQLRETURN SQL_API
18120 SQLErrorW(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18121  SQLWCHAR *sqlState, SQLINTEGER *nativeErr,
18122  SQLWCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18123 {
18124  char state[16];
18125  SQLSMALLINT len = 0;
18126  SQLRETURN ret;
18127 
18128  ret = drverror(env, dbc, stmt, (SQLCHAR *) state, nativeErr,
18129  (SQLCHAR *) errmsg, errmax, &len);
18130  if (ret == SQL_SUCCESS) {
18131  if (sqlState) {
18132  uc_from_utf_buf((SQLCHAR *) state, -1, sqlState,
18133  6 * sizeof (SQLWCHAR));
18134  }
18135  if (errmsg) {
18136  if (len > 0) {
18137  SQLWCHAR *e = NULL;
18138 
18139  e = uc_from_utf((SQLCHAR *) errmsg, len);
18140  if (e) {
18141  if (errmax > 0) {
18142  uc_strncpy(errmsg, e, errmax);
18143  e[len] = 0;
18144  len = min(errmax, uc_strlen(e));
18145  } else {
18146  len = uc_strlen(e);
18147  }
18148  uc_free(e);
18149  } else {
18150  len = 0;
18151  }
18152  }
18153  if (len <= 0) {
18154  len = 0;
18155  if (errmax > 0) {
18156  errmsg[0] = 0;
18157  }
18158  }
18159  } else {
18160  len = 0;
18161  }
18162  if (errlen) {
18163  *errlen = len;
18164  }
18165  } else if (ret == SQL_NO_DATA) {
18166  if (sqlState) {
18167  sqlState[0] = 0;
18168  }
18169  if (errmsg) {
18170  if (errmax > 0) {
18171  errmsg[0] = 0;
18172  }
18173  }
18174  if (errlen) {
18175  *errlen = 0;
18176  }
18177  }
18178  return ret;
18179 }
18180 #endif
18181 
18188 SQLRETURN SQL_API
18189 SQLMoreResults(SQLHSTMT stmt)
18190 {
18191  HSTMT_LOCK(stmt);
18192  if (stmt == SQL_NULL_HSTMT) {
18193  return SQL_INVALID_HANDLE;
18194  }
18195  HSTMT_UNLOCK(stmt);
18196  return SQL_NO_DATA;
18197 }
18198 
18207 static SQLRETURN
18208 setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp)
18209 {
18210  int ncols = *ncolsp, guessed_types = 0;
18211  SQLRETURN ret = SQL_SUCCESS;
18212 
18213  if (ncols > 0) {
18214  int i;
18215  PTRDIFF_T size;
18216  char *p;
18217  COL *dyncols;
18218  DBC *d = (DBC *) s->dbc;
18219  const char *colname, *typename;
18220 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18221  char *tblname;
18222 #endif
18223 
18224  for (i = size = 0; i < ncols; i++) {
18225  colname = sqlite3_column_name(s3stmt, i);
18226  size += 3 + 3 * strlen(colname);
18227  }
18228 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18229  tblname = (char *) size;
18230  for (i = 0; i < ncols; i++) {
18231  p = (char *) sqlite3_column_table_name(s3stmt, i);
18232  size += 2 + (p ? strlen(p) : 0);
18233  }
18234 #endif
18235  dyncols = xmalloc(ncols * sizeof (COL) + size);
18236  if (!dyncols) {
18237  freedyncols(s);
18238  *ncolsp = 0;
18239  ret = SQL_ERROR;
18240  } else {
18241  p = (char *) (dyncols + ncols);
18242 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18243  tblname = p + (PTRDIFF_T) tblname;
18244 #endif
18245  for (i = 0; i < ncols; i++) {
18246  char *q;
18247 
18248  colname = sqlite3_column_name(s3stmt, i);
18249  if (d->trace) {
18250  fprintf(d->trace, "-- column %d name: '%s'\n",
18251  i + 1, colname);
18252  fflush(d->trace);
18253  }
18254 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18255  q = (char *) sqlite3_column_table_name(s3stmt, i);
18256  strcpy(tblname, q ? q : "");
18257  if (d->trace) {
18258  fprintf(d->trace, "-- table %d name: '%s'\n",
18259  i + 1, tblname);
18260  fflush(d->trace);
18261  }
18262  dyncols[i].table = tblname;
18263  tblname += strlen(tblname) + 1;
18264 #endif
18265  typename = s3stmt_coltype(s3stmt, i, d, &guessed_types);
18266  dyncols[i].db = ((DBC *) (s->dbc))->dbname;
18267  strcpy(p, colname);
18268  dyncols[i].label = p;
18269  p += strlen(p) + 1;
18270  q = strchr(colname, '.');
18271  if (q) {
18272  char *q2 = strchr(q + 1, '.');
18273 
18274  /* SQLite 3.3.4 produces view.table.column sometimes */
18275  if (q2) {
18276  q = q2;
18277  }
18278  }
18279  if (q) {
18280 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18281  dyncols[i].table = p;
18282 #endif
18283  strncpy(p, colname, q - colname);
18284  p[q - colname] = '\0';
18285  p += strlen(p) + 1;
18286  strcpy(p, q + 1);
18287  dyncols[i].column = p;
18288  p += strlen(p) + 1;
18289  } else {
18290 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18291  dyncols[i].table = "";
18292 #endif
18293  strcpy(p, colname);
18294  dyncols[i].column = p;
18295  p += strlen(p) + 1;
18296  }
18297  if (s->longnames) {
18298  dyncols[i].column = dyncols[i].label;
18299  }
18300 #ifdef SQL_LONGVARCHAR
18301  dyncols[i].type = SQL_LONGVARCHAR;
18302  dyncols[i].size = 65535;
18303 #else
18304  dyncols[i].type = SQL_VARCHAR;
18305  dyncols[i].size = 255;
18306 #endif
18307  dyncols[i].index = i;
18308  dyncols[i].scale = 0;
18309  dyncols[i].prec = 0;
18310  dyncols[i].nosign = 1;
18311  dyncols[i].autoinc = SQL_FALSE;
18312  dyncols[i].notnull = SQL_NULLABLE;
18313  dyncols[i].ispk = -1;
18314  dyncols[i].isrowid = -1;
18315 #ifdef FULL_METADATA
18316  s3stmt_addmeta(s3stmt, i, d, &dyncols[i]);
18317 #endif
18318  dyncols[i].typename = xstrdup(typename);
18319  }
18320  freedyncols(s);
18321  s->dyncols = s->cols = dyncols;
18322  s->dcols = ncols;
18323  fixupdyncols(s, d);
18324  s->guessed_types = guessed_types;
18325  }
18326  }
18327  return ret;
18328 }
18329 
18338 static SQLRETURN
18339 drvprepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18340 {
18341  STMT *s;
18342  DBC *d;
18343  char *errp = NULL;
18344  SQLRETURN sret;
18345 
18346  if (stmt == SQL_NULL_HSTMT) {
18347  return SQL_INVALID_HANDLE;
18348  }
18349  s = (STMT *) stmt;
18350  if (s->dbc == SQL_NULL_HDBC) {
18351 noconn:
18352  return noconn(s);
18353  }
18354  d = s->dbc;
18355  if (!d->sqlite) {
18356  goto noconn;
18357  }
18358  s3stmt_end(s);
18359  s3stmt_drop(s);
18360  sret = starttran(s);
18361  if (sret != SQL_SUCCESS) {
18362  return sret;
18363  }
18364  freep(&s->query);
18365  s->query = (SQLCHAR *) fixupsql((char *) query, queryLen,
18366  (d->version >= 0x030805),
18367  &s->nparams, &s->isselect, &errp);
18368  if (!s->query) {
18369  if (errp) {
18370  setstat(s, -1, "%s", (*s->ov3) ? "HY000" : "S1000", errp);
18371  return SQL_ERROR;
18372  }
18373  return nomem(s);
18374  }
18375  errp = NULL;
18376  freeresult(s, -1);
18377  if (s->isselect == 1) {
18378  int ret, ncols, nretry = 0;
18379  const char *rest;
18380  sqlite3_stmt *s3stmt = NULL;
18381 
18382 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18383  dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
18384 #else
18385  dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
18386 #endif
18387  do {
18388  s3stmt = NULL;
18389 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18390  ret = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
18391  &s3stmt, &rest);
18392 #else
18393  ret = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
18394  &s3stmt, &rest);
18395 #endif
18396  if (ret != SQLITE_OK) {
18397  if (s3stmt) {
18398  sqlite3_finalize(s3stmt);
18399  s3stmt = NULL;
18400  }
18401  }
18402  } while (ret == SQLITE_SCHEMA && (++nretry) < 2);
18403  dbtracerc(d, ret, NULL);
18404  if (ret != SQLITE_OK) {
18405  if (s3stmt) {
18406  dbtraceapi(d, "sqlite3_finalize", 0);
18407  sqlite3_finalize(s3stmt);
18408  }
18409  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18410  sqlite3_errmsg(d->sqlite), ret);
18411  return SQL_ERROR;
18412  }
18413  if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
18414  dbtraceapi(d, "sqlite3_finalize", 0);
18415  sqlite3_finalize(s3stmt);
18416  setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
18417  (*s->ov3) ? "HY000" : "S1000");
18418  return SQL_ERROR;
18419  }
18420  ncols = sqlite3_column_count(s3stmt);
18421  s->guessed_types = 0;
18422  setupdyncols(s, s3stmt, &ncols);
18423  s->ncols = ncols;
18424  s->s3stmt = s3stmt;
18425  }
18426  mkbindcols(s, s->ncols);
18427  s->paramset_count = 0;
18428  return SQL_SUCCESS;
18429 }
18430 
18438 static SQLRETURN
18439 drvexecute(SQLHSTMT stmt, int initial)
18440 {
18441  STMT *s;
18442  DBC *d;
18443  char *errp = NULL;
18444  int rc, i, ncols = 0, nrows = 0, busy_count;
18445  SQLRETURN ret;
18446 
18447  if (stmt == SQL_NULL_HSTMT) {
18448  return SQL_INVALID_HANDLE;
18449  }
18450  s = (STMT *) stmt;
18451  if (s->dbc == SQL_NULL_HDBC) {
18452 noconn:
18453  return noconn(s);
18454  }
18455  d = (DBC *) s->dbc;
18456  if (!d->sqlite) {
18457  goto noconn;
18458  }
18459  if (!s->query) {
18460  setstat(s, -1, "no query prepared", (*s->ov3) ? "HY000" : "S1000");
18461  return SQL_ERROR;
18462  }
18463  if (s->nbindparms < s->nparams) {
18464 unbound:
18465  setstat(s, -1, "unbound parameters in query",
18466  (*s->ov3) ? "HY000" : "S1000");
18467  return SQL_ERROR;
18468  }
18469  for (i = 0; i < s->nparams; i++) {
18470  BINDPARM *p = &s->bindparms[i];
18471 
18472  if (!p->bound) {
18473  goto unbound;
18474  }
18475  if (initial) {
18476  SQLLEN *lenp = p->lenp;
18477 
18478  if (lenp && *lenp < 0 && *lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18479  *lenp != SQL_NTS && *lenp != SQL_NULL_DATA &&
18480  *lenp != SQL_DATA_AT_EXEC) {
18481  setstat(s, -1, "invalid length reference", "HY009");
18482  return SQL_ERROR;
18483  }
18484  if (lenp && (*lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18485  *lenp == SQL_DATA_AT_EXEC)) {
18486  p->need = 1;
18487  p->offs = 0;
18488  p->len = 0;
18489  }
18490  }
18491  }
18492  ret = starttran(s);
18493  if (ret != SQL_SUCCESS) {
18494  goto cleanup;
18495  }
18496  busy_count = 0;
18497 again:
18498  s3stmt_end(s);
18499  if (initial) {
18500  /* fixup data-at-execution parameters and alloc'ed blobs */
18501  s->pdcount = -1;
18502  for (i = 0; i < s->nparams; i++) {
18503  BINDPARM *p = &s->bindparms[i];
18504 
18505  if (p->param == p->parbuf) {
18506  p->param = NULL;
18507  }
18508  freep(&p->parbuf);
18509  if (p->need <= 0 &&
18510  p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18511  *p->lenp == SQL_DATA_AT_EXEC)) {
18512  p->need = 1;
18513  p->offs = 0;
18514  p->len = 0;
18515  }
18516  }
18517  }
18518  if (s->nparams) {
18519  for (i = 0; i < s->nparams; i++) {
18520  ret = setupparam(s, (char *) s->query, i);
18521  if (ret != SQL_SUCCESS) {
18522  goto cleanup;
18523  }
18524  }
18525  }
18526  freeresult(s, 0);
18527  if (s->isselect == 1 && !d->intrans &&
18528  s->curtype == SQL_CURSOR_FORWARD_ONLY &&
18529  d->step_enable && s->nparams == 0 && d->cur_s3stmt == NULL) {
18530  s->nrows = -1;
18531  ret = s3stmt_start(s);
18532  if (ret == SQL_SUCCESS) {
18533  goto done2;
18534  }
18535  }
18536  rc = drvgettable(s, s->s3stmt ? NULL : (char *) s->query, &s->rows,
18537  &s->nrows, &ncols, &errp, s->nparams, s->bindparms);
18538  dbtracerc(d, rc, errp);
18539  if (rc == SQLITE_BUSY) {
18540  if (busy_handler((void *) d, ++busy_count)) {
18541  if (errp) {
18542  sqlite3_free(errp);
18543  errp = NULL;
18544  }
18545  for (i = 0; i < s->nparams; i++) {
18546  BINDPARM *p = &s->bindparms[i];
18547 
18548  if (p->param == p->parbuf) {
18549  p->param = NULL;
18550  }
18551  freep(&p->parbuf);
18552  if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18553  *p->lenp != SQL_DATA_AT_EXEC)) {
18554  p->param = p->param0;
18555  }
18556  p->lenp = p->lenp0;
18557  }
18558  s->nrows = 0;
18559  goto again;
18560  }
18561  }
18562  if (rc != SQLITE_OK) {
18563  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18564  errp ? errp : "unknown error", rc);
18565  if (errp) {
18566  sqlite3_free(errp);
18567  errp = NULL;
18568  }
18569  ret = SQL_ERROR;
18570  goto cleanup;
18571  }
18572  if (errp) {
18573  sqlite3_free(errp);
18574  errp = NULL;
18575  }
18576  s->rowfree = freerows;
18577  if (s->isselect <= 0 || s->isselect > 1) {
18578  /*
18579  * INSERT/UPDATE/DELETE or DDL results are immediately released.
18580  */
18581  freeresult(s, -1);
18582  nrows += sqlite3_changes(d->sqlite);
18583  s->nrows = nrows;
18584  goto done;
18585  }
18586  if (s->ncols != ncols) {
18587  /*
18588  * Weird result.
18589  */
18590  setstat(s, -1, "broken result set %d/%d",
18591  (*s->ov3) ? "HY000" : "S1000", s->ncols, ncols);
18592  ret = SQL_ERROR;
18593  goto cleanup;
18594  }
18595 done:
18596  mkbindcols(s, s->ncols);
18597 done2:
18598  ret = SQL_SUCCESS;
18599  s->rowp = s->rowprs = -1;
18600  s->paramset_count++;
18601  s->paramset_nrows = s->nrows;
18602  if (s->paramset_count < s->paramset_size) {
18603  for (i = 0; i < s->nparams; i++) {
18604  BINDPARM *p = &s->bindparms[i];
18605 
18606  if (p->param == p->parbuf) {
18607  p->param = NULL;
18608  }
18609  freep(&p->parbuf);
18610  if (p->lenp0 &&
18611  s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18612  p->lenp = (SQLLEN *) ((char *) p->lenp0 +
18613  s->paramset_count * s->parm_bind_type);
18614  } else if (p->lenp0 && p->inc > 0) {
18615  p->lenp = p->lenp0 + s->paramset_count;
18616  }
18617  if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18618  *p->lenp != SQL_DATA_AT_EXEC)) {
18619  if (p->param0 &&
18620  s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18621  p->param = (char *) p->param0 +
18623  } else if (p->param0 && p->inc > 0) {
18624  p->param = (char *) p->param0 +
18625  s->paramset_count * p->inc;
18626  }
18627  } else if (p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18628  *p->lenp == SQL_DATA_AT_EXEC)) {
18629  p->need = 1;
18630  p->offs = 0;
18631  p->len = 0;
18632  }
18633  }
18634  goto again;
18635  }
18636 cleanup:
18637  if (ret != SQL_NEED_DATA) {
18638  for (i = 0; i < s->nparams; i++) {
18639  BINDPARM *p = &s->bindparms[i];
18640 
18641  if (p->param == p->parbuf) {
18642  p->param = NULL;
18643  }
18644  freep(&p->parbuf);
18645  if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18646  *p->lenp != SQL_DATA_AT_EXEC)) {
18647  p->param = p->param0;
18648  }
18649  p->lenp = p->lenp0;
18650  }
18651  s->nrows = s->paramset_nrows;
18652  if (s->parm_proc) {
18653  *s->parm_proc = s->paramset_count;
18654  }
18655  s->paramset_count = 0;
18656  s->paramset_nrows = 0;
18657  }
18658  /*
18659  * For INSERT/UPDATE/DELETE statements change the return code
18660  * to SQL_NO_DATA if the number of rows affected was 0.
18661  */
18662  if (*s->ov3 && s->isselect == 0 &&
18663  ret == SQL_SUCCESS && nrows == 0) {
18664  ret = SQL_NO_DATA;
18665  }
18666  return ret;
18667 }
18668 
18669 #ifndef WINTERFACE
18670 
18678 SQLRETURN SQL_API
18679 SQLPrepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18680 {
18681  SQLRETURN ret;
18682 #if defined(_WIN32) || defined(_WIN64)
18683  char *q;
18684 #endif
18685 
18686  HSTMT_LOCK(stmt);
18687 #if defined(_WIN32) || defined(_WIN64)
18688  if (!((STMT *) stmt)->oemcp[0]) {
18689  ret = drvprepare(stmt, query, queryLen);
18690  goto done;
18691  }
18692  q = wmb_to_utf_c((char *) query, queryLen);
18693  if (!q) {
18694  ret = nomem((STMT *) stmt);
18695  goto done;
18696  }
18697  query = (SQLCHAR *) q;
18698  queryLen = SQL_NTS;
18699 #endif
18700  ret = drvprepare(stmt, query, queryLen);
18701 #if defined(_WIN32) || defined(_WIN64)
18702  uc_free(q);
18703 done:
18704  ;
18705 #endif
18706  HSTMT_UNLOCK(stmt);
18707  return ret;
18708 }
18709 #endif
18710 
18711 #ifdef WINTERFACE
18712 
18720 SQLRETURN SQL_API
18721 SQLPrepareW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
18722 {
18723  SQLRETURN ret;
18724  char *q = uc_to_utf_c(query, queryLen);
18725 
18726  HSTMT_LOCK(stmt);
18727  if (!q) {
18728  ret = nomem((STMT *) stmt);
18729  goto done;
18730  }
18731  ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
18732  uc_free(q);
18733 done:
18734  HSTMT_UNLOCK(stmt);
18735  return ret;
18736 }
18737 #endif
18738 
18745 SQLRETURN SQL_API
18746 SQLExecute(SQLHSTMT stmt)
18747 {
18748  SQLRETURN ret;
18749 
18750  HSTMT_LOCK(stmt);
18751  ret = drvexecute(stmt, 1);
18752  HSTMT_UNLOCK(stmt);
18753  return ret;
18754 }
18755 
18756 #ifndef WINTERFACE
18757 
18765 SQLRETURN SQL_API
18766 SQLExecDirect(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18767 {
18768  SQLRETURN ret;
18769 #if defined(_WIN32) || defined(_WIN64)
18770  char *q;
18771 #endif
18772 
18773  HSTMT_LOCK(stmt);
18774 #if defined(_WIN32) || defined(_WIN64)
18775  if (!((STMT *) stmt)->oemcp[0]) {
18776  ret = drvprepare(stmt, query, queryLen);
18777  if (ret == SQL_SUCCESS) {
18778  ret = drvexecute(stmt, 1);
18779  }
18780  goto done;
18781  }
18782  q = wmb_to_utf_c((char *) query, queryLen);
18783  if (!q) {
18784  ret = nomem((STMT *) stmt);
18785  goto done;
18786  }
18787  query = (SQLCHAR *) q;
18788  queryLen = SQL_NTS;
18789 #endif
18790  ret = drvprepare(stmt, query, queryLen);
18791  if (ret == SQL_SUCCESS) {
18792  ret = drvexecute(stmt, 1);
18793  }
18794 #if defined(_WIN32) || defined(_WIN64)
18795  uc_free(q);
18796 done:
18797  ;
18798 #endif
18799  HSTMT_UNLOCK(stmt);
18800  return ret;
18801 }
18802 #endif
18803 
18804 #ifdef WINTERFACE
18805 
18813 SQLRETURN SQL_API
18814 SQLExecDirectW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
18815 {
18816  SQLRETURN ret;
18817  char *q = uc_to_utf_c(query, queryLen);
18818 
18819  HSTMT_LOCK(stmt);
18820  if (!q) {
18821  ret = nomem((STMT *) stmt);
18822  goto done;
18823  }
18824  ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
18825  uc_free(q);
18826  if (ret == SQL_SUCCESS) {
18827  ret = drvexecute(stmt, 1);
18828  }
18829 done:
18830  HSTMT_UNLOCK(stmt);
18831  return ret;
18832 }
18833 #endif
18834 
18835 
18836 #if defined(_WIN32) || defined(_WIN64)
18837 #ifndef WITHOUT_DRIVERMGR
18838 
18839 /*
18840  * Windows configuration dialog stuff.
18841  */
18842 
18843 #include <windowsx.h>
18844 #include <winuser.h>
18845 
18846 #define MAXPATHLEN (259+1) /* Max path length */
18847 #define MAXKEYLEN (15+1) /* Max keyword length */
18848 #define MAXDESC (255+1) /* Max description length */
18849 #define MAXDSNAME (255+1) /* Max data source name length */
18850 #define MAXTONAME (32+1) /* Max timeout length */
18851 #define MAXDBNAME MAXPATHLEN
18852 
18853 /* Attribute key indexes into an array of Attr structs, see below */
18854 
18855 #define KEY_DSN 0
18856 #define KEY_DESC 1
18857 #define KEY_DBNAME 2
18858 #define KEY_BUSY 3
18859 #define KEY_DRIVER 4
18860 #define KEY_STEPAPI 5
18861 #define KEY_SYNCP 6
18862 #define KEY_NOTXN 7
18863 #define KEY_SHORTNAM 8
18864 #define KEY_LONGNAM 9
18865 #define KEY_NOCREAT 10
18866 #define KEY_NOWCHAR 11
18867 #define KEY_LOADEXT 12
18868 #define KEY_JMODE 13
18869 #define KEY_FKSUPPORT 14
18870 #define KEY_OEMCP 15
18871 #define KEY_BIGINT 16
18872 #define KEY_PASSWD 17
18873 #define KEY_JDCONV 18
18874 #define NUMOFKEYS 19
18875 
18876 typedef struct {
18877  BOOL supplied;
18878  char attr[MAXPATHLEN*4];
18879 } ATTR;
18880 
18881 typedef struct {
18882  SQLHWND parent;
18883  LPCSTR driver;
18884  ATTR attr[NUMOFKEYS];
18885  char DSN[MAXDSNAME];
18886  BOOL newDSN;
18887  BOOL defDSN;
18888 } SETUPDLG;
18889 
18890 static struct {
18891  char *key;
18892  int ikey;
18893 } attrLookup[] = {
18894  { "DSN", KEY_DSN },
18895  { "DESC", KEY_DESC },
18896  { "Description", KEY_DESC},
18897  { "Database", KEY_DBNAME },
18898  { "Timeout", KEY_BUSY },
18899  { "Driver", KEY_DRIVER },
18900  { "StepAPI", KEY_STEPAPI },
18901  { "SyncPragma", KEY_SYNCP },
18902  { "NoTXN", KEY_NOTXN },
18903  { "ShortNames", KEY_SHORTNAM },
18904  { "LongNames", KEY_LONGNAM },
18905  { "NoCreat", KEY_NOCREAT },
18906  { "NoWCHAR", KEY_NOWCHAR },
18907  { "LoadExt", KEY_LOADEXT },
18908  { "JournalMode", KEY_JMODE },
18909  { "FKSupport", KEY_FKSUPPORT },
18910  { "OEMCP", KEY_OEMCP },
18911  { "BigInt", KEY_BIGINT },
18912  { "PWD", KEY_PASSWD },
18913  { "JDConv", KEY_JDCONV },
18914  { NULL, 0 }
18915 };
18916 
18923 static void
18924 ParseAttributes(LPCSTR attribs, SETUPDLG *setupdlg)
18925 {
18926  char *str = (char *) attribs, *start, key[MAXKEYLEN];
18927  int elem, nkey;
18928 
18929  while (*str) {
18930  start = str;
18931  if ((str = strchr(str, '=')) == NULL) {
18932  return;
18933  }
18934  elem = -1;
18935  nkey = str - start;
18936  if (nkey < sizeof (key)) {
18937  int i;
18938 
18939  memcpy(key, start, nkey);
18940  key[nkey] = '\0';
18941  for (i = 0; attrLookup[i].key; i++) {
18942  if (strcasecmp(attrLookup[i].key, key) == 0) {
18943  elem = attrLookup[i].ikey;
18944  break;
18945  }
18946  }
18947  }
18948  start = ++str;
18949  while (*str && *str != ';') {
18950  ++str;
18951  }
18952  if (elem >= 0) {
18953  int end = min(str - start, sizeof (setupdlg->attr[elem].attr) - 1);
18954 
18955  setupdlg->attr[elem].supplied = TRUE;
18956  memcpy(setupdlg->attr[elem].attr, start, end);
18957  setupdlg->attr[elem].attr[end] = '\0';
18958  }
18959  ++str;
18960  }
18961 }
18962 
18970 static BOOL
18971 SetDSNAttributes(HWND parent, SETUPDLG *setupdlg)
18972 {
18973  char *dsn = setupdlg->attr[KEY_DSN].attr;
18974 
18975  if (setupdlg->newDSN && strlen(dsn) == 0) {
18976  return FALSE;
18977  }
18978  if (!SQLWriteDSNToIni(dsn, setupdlg->driver)) {
18979  if (parent) {
18980  char buf[MAXPATHLEN], msg[MAXPATHLEN];
18981 
18982  LoadString(hModule, IDS_BADDSN, buf, sizeof (buf));
18983  wsprintf(msg, buf, dsn);
18984  LoadString(hModule, IDS_MSGTITLE, buf, sizeof (buf));
18985  MessageBox(parent, msg, buf,
18986  MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
18987  MB_SETFOREGROUND);
18988  }
18989  return FALSE;
18990  }
18991  if (parent || setupdlg->attr[KEY_DESC].supplied) {
18992  SQLWritePrivateProfileString(dsn, "Description",
18993  setupdlg->attr[KEY_DESC].attr,
18994  ODBC_INI);
18995  }
18996  if (parent || setupdlg->attr[KEY_DBNAME].supplied) {
18997  SQLWritePrivateProfileString(dsn, "Database",
18998  setupdlg->attr[KEY_DBNAME].attr,
18999  ODBC_INI);
19000  }
19001  if (parent || setupdlg->attr[KEY_BUSY].supplied) {
19002  SQLWritePrivateProfileString(dsn, "Timeout",
19003  setupdlg->attr[KEY_BUSY].attr,
19004  ODBC_INI);
19005  }
19006  if (parent || setupdlg->attr[KEY_STEPAPI].supplied) {
19007  SQLWritePrivateProfileString(dsn, "StepAPI",
19008  setupdlg->attr[KEY_STEPAPI].attr,
19009  ODBC_INI);
19010  }
19011  if (parent || setupdlg->attr[KEY_SYNCP].supplied) {
19012  SQLWritePrivateProfileString(dsn, "SyncPragma",
19013  setupdlg->attr[KEY_SYNCP].attr,
19014  ODBC_INI);
19015  }
19016  if (parent || setupdlg->attr[KEY_NOTXN].supplied) {
19017  SQLWritePrivateProfileString(dsn, "NoTXN",
19018  setupdlg->attr[KEY_NOTXN].attr,
19019  ODBC_INI);
19020  }
19021  if (parent || setupdlg->attr[KEY_SHORTNAM].supplied) {
19022  SQLWritePrivateProfileString(dsn, "ShortNames",
19023  setupdlg->attr[KEY_SHORTNAM].attr,
19024  ODBC_INI);
19025  }
19026  if (parent || setupdlg->attr[KEY_LONGNAM].supplied) {
19027  SQLWritePrivateProfileString(dsn, "LongNames",
19028  setupdlg->attr[KEY_LONGNAM].attr,
19029  ODBC_INI);
19030  }
19031  if (parent || setupdlg->attr[KEY_NOCREAT].supplied) {
19032  SQLWritePrivateProfileString(dsn, "NoCreat",
19033  setupdlg->attr[KEY_NOCREAT].attr,
19034  ODBC_INI);
19035  }
19036  if (parent || setupdlg->attr[KEY_NOWCHAR].supplied) {
19037  SQLWritePrivateProfileString(dsn, "NoWCHAR",
19038  setupdlg->attr[KEY_NOWCHAR].attr,
19039  ODBC_INI);
19040  }
19041  if (parent || setupdlg->attr[KEY_FKSUPPORT].supplied) {
19042  SQLWritePrivateProfileString(dsn, "FKSupport",
19043  setupdlg->attr[KEY_FKSUPPORT].attr,
19044  ODBC_INI);
19045  }
19046  if (parent || setupdlg->attr[KEY_OEMCP].supplied) {
19047  SQLWritePrivateProfileString(dsn, "OEMCP",
19048  setupdlg->attr[KEY_OEMCP].attr,
19049  ODBC_INI);
19050  }
19051  if (parent || setupdlg->attr[KEY_LOADEXT].supplied) {
19052  SQLWritePrivateProfileString(dsn, "LoadExt",
19053  setupdlg->attr[KEY_LOADEXT].attr,
19054  ODBC_INI);
19055  }
19056  if (parent || setupdlg->attr[KEY_BIGINT].supplied) {
19057  SQLWritePrivateProfileString(dsn, "BigInt",
19058  setupdlg->attr[KEY_BIGINT].attr,
19059  ODBC_INI);
19060  }
19061  if (parent || setupdlg->attr[KEY_JDCONV].supplied) {
19062  SQLWritePrivateProfileString(dsn, "JDConv",
19063  setupdlg->attr[KEY_JDCONV].attr,
19064  ODBC_INI);
19065  }
19066  if (parent || setupdlg->attr[KEY_PASSWD].supplied) {
19067  SQLWritePrivateProfileString(dsn, "PWD",
19068  setupdlg->attr[KEY_PASSWD].attr,
19069  ODBC_INI);
19070  }
19071  if (setupdlg->attr[KEY_DSN].supplied &&
19072  strcasecmp(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr)) {
19073  SQLRemoveDSNFromIni(setupdlg->DSN);
19074  }
19075  return TRUE;
19076 }
19077 
19083 static void
19084 GetAttributes(SETUPDLG *setupdlg)
19085 {
19086  char *dsn = setupdlg->attr[KEY_DSN].attr;
19087 
19088  if (!setupdlg->attr[KEY_DESC].supplied) {
19089  SQLGetPrivateProfileString(dsn, "Description", "",
19090  setupdlg->attr[KEY_DESC].attr,
19091  sizeof (setupdlg->attr[KEY_DESC].attr),
19092  ODBC_INI);
19093  }
19094  if (!setupdlg->attr[KEY_DBNAME].supplied) {
19095  SQLGetPrivateProfileString(dsn, "Database", "",
19096  setupdlg->attr[KEY_DBNAME].attr,
19097  sizeof (setupdlg->attr[KEY_DBNAME].attr),
19098  ODBC_INI);
19099  }
19100  if (!setupdlg->attr[KEY_BUSY].supplied) {
19101  SQLGetPrivateProfileString(dsn, "Timeout", "100000",
19102  setupdlg->attr[KEY_BUSY].attr,
19103  sizeof (setupdlg->attr[KEY_BUSY].attr),
19104  ODBC_INI);
19105  }
19106  if (!setupdlg->attr[KEY_STEPAPI].supplied) {
19107  SQLGetPrivateProfileString(dsn, "StepAPI", "0",
19108  setupdlg->attr[KEY_STEPAPI].attr,
19109  sizeof (setupdlg->attr[KEY_STEPAPI].attr),
19110  ODBC_INI);
19111  }
19112  if (!setupdlg->attr[KEY_SYNCP].supplied) {
19113  SQLGetPrivateProfileString(dsn, "SyncPragma", "NORMAL",
19114  setupdlg->attr[KEY_SYNCP].attr,
19115  sizeof (setupdlg->attr[KEY_SYNCP].attr),
19116  ODBC_INI);
19117  }
19118  if (!setupdlg->attr[KEY_NOTXN].supplied) {
19119  SQLGetPrivateProfileString(dsn, "NoTXN", "",
19120  setupdlg->attr[KEY_NOTXN].attr,
19121  sizeof (setupdlg->attr[KEY_NOTXN].attr),
19122  ODBC_INI);
19123  }
19124  if (!setupdlg->attr[KEY_SHORTNAM].supplied) {
19125  SQLGetPrivateProfileString(dsn, "ShortNames", "",
19126  setupdlg->attr[KEY_SHORTNAM].attr,
19127  sizeof (setupdlg->attr[KEY_SHORTNAM].attr),
19128  ODBC_INI);
19129  }
19130  if (!setupdlg->attr[KEY_LONGNAM].supplied) {
19131  SQLGetPrivateProfileString(dsn, "LongNames", "",
19132  setupdlg->attr[KEY_LONGNAM].attr,
19133  sizeof (setupdlg->attr[KEY_LONGNAM].attr),
19134  ODBC_INI);
19135  }
19136  if (!setupdlg->attr[KEY_NOCREAT].supplied) {
19137  SQLGetPrivateProfileString(dsn, "NoCreat", "",
19138  setupdlg->attr[KEY_NOCREAT].attr,
19139  sizeof (setupdlg->attr[KEY_NOCREAT].attr),
19140  ODBC_INI);
19141  }
19142  if (!setupdlg->attr[KEY_NOWCHAR].supplied) {
19143  SQLGetPrivateProfileString(dsn, "NoWCHAR", "",
19144  setupdlg->attr[KEY_NOWCHAR].attr,
19145  sizeof (setupdlg->attr[KEY_NOWCHAR].attr),
19146  ODBC_INI);
19147  }
19148  if (!setupdlg->attr[KEY_FKSUPPORT].supplied) {
19149  SQLGetPrivateProfileString(dsn, "FKSupport", "",
19150  setupdlg->attr[KEY_FKSUPPORT].attr,
19151  sizeof (setupdlg->attr[KEY_FKSUPPORT].attr),
19152  ODBC_INI);
19153  }
19154  if (!setupdlg->attr[KEY_OEMCP].supplied) {
19155  SQLGetPrivateProfileString(dsn, "OEMCP", "",
19156  setupdlg->attr[KEY_OEMCP].attr,
19157  sizeof (setupdlg->attr[KEY_OEMCP].attr),
19158  ODBC_INI);
19159  }
19160  if (!setupdlg->attr[KEY_LOADEXT].supplied) {
19161  SQLGetPrivateProfileString(dsn, "LoadExt", "",
19162  setupdlg->attr[KEY_LOADEXT].attr,
19163  sizeof (setupdlg->attr[KEY_LOADEXT].attr),
19164  ODBC_INI);
19165  }
19166  if (!setupdlg->attr[KEY_JMODE].supplied) {
19167  SQLGetPrivateProfileString(dsn, "JournalMode", "",
19168  setupdlg->attr[KEY_JMODE].attr,
19169  sizeof (setupdlg->attr[KEY_JMODE].attr),
19170  ODBC_INI);
19171  }
19172  if (!setupdlg->attr[KEY_BIGINT].supplied) {
19173  SQLGetPrivateProfileString(dsn, "BigInt", "",
19174  setupdlg->attr[KEY_BIGINT].attr,
19175  sizeof (setupdlg->attr[KEY_BIGINT].attr),
19176  ODBC_INI);
19177  }
19178  if (!setupdlg->attr[KEY_PASSWD].supplied) {
19179  SQLGetPrivateProfileString(dsn, "PWD", "",
19180  setupdlg->attr[KEY_PASSWD].attr,
19181  sizeof (setupdlg->attr[KEY_PASSWD].attr),
19182  ODBC_INI);
19183  }
19184  if (!setupdlg->attr[KEY_JDCONV].supplied) {
19185  SQLGetPrivateProfileString(dsn, "JDConv", "",
19186  setupdlg->attr[KEY_JDCONV].attr,
19187  sizeof (setupdlg->attr[KEY_JDCONV].attr),
19188  ODBC_INI);
19189  }
19190 }
19191 
19197 static void
19198 GetDBFile(HWND hdlg)
19199 {
19200 #ifdef _WIN64
19201  SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19202 #else
19203  SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19204 #endif
19205  OPENFILENAME ofn;
19206 
19207  memset(&ofn, 0, sizeof (ofn));
19208  ofn.lStructSize = sizeof (ofn);
19209  ofn.hwndOwner = hdlg;
19210 #ifdef _WIN64
19211  ofn.hInstance = (HINSTANCE) GetWindowLongPtr(hdlg, GWLP_HINSTANCE);
19212 #else
19213  ofn.hInstance = (HINSTANCE) GetWindowLong(hdlg, GWL_HINSTANCE);
19214 #endif
19215  ofn.lpstrFile = (LPTSTR) setupdlg->attr[KEY_DBNAME].attr;
19216  ofn.nMaxFile = MAXPATHLEN;
19217  ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST |
19218  OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_FILEMUSTEXIST;
19219  if (GetOpenFileName(&ofn)) {
19220  SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19221  setupdlg->attr[KEY_DBNAME].supplied = TRUE;
19222  }
19223 }
19224 
19234 static BOOL CALLBACK
19235 ConfigDlgProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19236 {
19237  SETUPDLG *setupdlg = NULL;
19238  WORD index;
19239 
19240  switch (wmsg) {
19241  case WM_INITDIALOG:
19242 #ifdef _WIN64
19243  SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19244 #else
19245  SetWindowLong(hdlg, DWL_USER, lparam);
19246 #endif
19247  setupdlg = (SETUPDLG *) lparam;
19248  GetAttributes(setupdlg);
19249  SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19250  SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19251  SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19252  SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19253  SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19254  SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19255  (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19256  SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19257  (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19258  SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19259  (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19260  SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19261  (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19262  SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19263  (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19264  CheckDlgButton(hdlg, IDC_STEPAPI,
19265  getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19266  BST_CHECKED : BST_UNCHECKED);
19267  CheckDlgButton(hdlg, IDC_NOTXN,
19268  getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19269  BST_CHECKED : BST_UNCHECKED);
19270  CheckDlgButton(hdlg, IDC_SHORTNAM,
19271  getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19272  BST_CHECKED : BST_UNCHECKED);
19273  CheckDlgButton(hdlg, IDC_LONGNAM,
19274  getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19275  BST_CHECKED : BST_UNCHECKED);
19276  CheckDlgButton(hdlg, IDC_NOCREAT,
19277  getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19278  BST_CHECKED : BST_UNCHECKED);
19279  CheckDlgButton(hdlg, IDC_NOWCHAR,
19280  getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19281  BST_CHECKED : BST_UNCHECKED);
19282  CheckDlgButton(hdlg, IDC_FKSUPPORT,
19283  getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19284  BST_CHECKED : BST_UNCHECKED);
19285  CheckDlgButton(hdlg, IDC_OEMCP,
19286  getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19287  BST_CHECKED : BST_UNCHECKED);
19288  CheckDlgButton(hdlg, IDC_BIGINT,
19289  getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19290  BST_CHECKED : BST_UNCHECKED);
19291  CheckDlgButton(hdlg, IDC_JDCONV,
19292  getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19293  BST_CHECKED : BST_UNCHECKED);
19294  SendDlgItemMessage(hdlg, IDC_SYNCP,
19295  CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19296  SendDlgItemMessage(hdlg, IDC_SYNCP,
19297  CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19298  SendDlgItemMessage(hdlg, IDC_SYNCP,
19299  CB_ADDSTRING, 0, (LPARAM) "OFF");
19300  SendDlgItemMessage(hdlg, IDC_SYNCP,
19301  CB_ADDSTRING, 0, (LPARAM) "FULL");
19302  SendDlgItemMessage(hdlg, IDC_SYNCP,
19303  CB_SELECTSTRING, (WPARAM) -1,
19304  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19305  if (setupdlg->defDSN) {
19306  EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19307  EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19308  }
19309  return TRUE;
19310  case WM_COMMAND:
19311  switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19312  case IDC_DSNAME:
19313  if (GET_WM_COMMAND_CMD(wparam, lparam) == EN_CHANGE) {
19314  char item[MAXDSNAME];
19315 
19316  EnableWindow(GetDlgItem(hdlg, IDOK),
19317  GetDlgItemText(hdlg, IDC_DSNAME,
19318  item, sizeof (item)));
19319  return TRUE;
19320  }
19321  break;
19322  case IDC_BROWSE:
19323  GetDBFile(hdlg);
19324  break;
19325  case IDOK:
19326 #ifdef _WIN64
19327  setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19328 #else
19329  setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19330 #endif
19331  if (!setupdlg->defDSN) {
19332  GetDlgItemText(hdlg, IDC_DSNAME,
19333  setupdlg->attr[KEY_DSN].attr,
19334  sizeof (setupdlg->attr[KEY_DSN].attr));
19335  }
19336  GetDlgItemText(hdlg, IDC_DESC,
19337  setupdlg->attr[KEY_DESC].attr,
19338  sizeof (setupdlg->attr[KEY_DESC].attr));
19339  GetDlgItemText(hdlg, IDC_DBNAME,
19340  setupdlg->attr[KEY_DBNAME].attr,
19341  sizeof (setupdlg->attr[KEY_DBNAME].attr));
19342  GetDlgItemText(hdlg, IDC_TONAME,
19343  setupdlg->attr[KEY_BUSY].attr,
19344  sizeof (setupdlg->attr[KEY_BUSY].attr));
19345  GetDlgItemText(hdlg, IDC_LOADEXT,
19346  setupdlg->attr[KEY_LOADEXT].attr,
19347  sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19348  index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19349  CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19350  if (index != (WORD) CB_ERR) {
19351  SendDlgItemMessage(hdlg, IDC_SYNCP,
19352  CB_GETLBTEXT, index,
19353  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19354  }
19355  strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19356  (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19357  "1" : "0");
19358  strcpy(setupdlg->attr[KEY_NOTXN].attr,
19359  (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19360  "1" : "0");
19361  strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19362  (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19363  "1" : "0");
19364  strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19365  (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19366  "1" : "0");
19367  strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19368  (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19369  "1" : "0");
19370  strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19371  (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19372  "1" : "0");
19373  strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19374  (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19375  "1" : "0");
19376  strcpy(setupdlg->attr[KEY_OEMCP].attr,
19377  (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19378  "1" : "0");
19379  strcpy(setupdlg->attr[KEY_BIGINT].attr,
19380  (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19381  "1" : "0");
19382  strcpy(setupdlg->attr[KEY_JDCONV].attr,
19383  (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19384  "1" : "0");
19385  SetDSNAttributes(hdlg, setupdlg);
19386  /* FALL THROUGH */
19387  case IDCANCEL:
19388  EndDialog(hdlg, wparam);
19389  return TRUE;
19390  }
19391  break;
19392  }
19393  return FALSE;
19394 }
19395 
19405 BOOL INSTAPI
19406 ConfigDSN(HWND hwnd, WORD request, LPCSTR driver, LPCSTR attribs)
19407 {
19408  BOOL success;
19409  SETUPDLG *setupdlg;
19410 
19411  setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
19412  if (setupdlg == NULL) {
19413  return FALSE;
19414  }
19415  memset(setupdlg, 0, sizeof (SETUPDLG));
19416  if (attribs) {
19417  ParseAttributes(attribs, setupdlg);
19418  }
19419  if (setupdlg->attr[KEY_DSN].supplied) {
19420  strcpy(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr);
19421  } else {
19422  setupdlg->DSN[0] = '\0';
19423  }
19424  if (request == ODBC_REMOVE_DSN) {
19425  if (!setupdlg->attr[KEY_DSN].supplied) {
19426  success = FALSE;
19427  } else {
19428  success = SQLRemoveDSNFromIni(setupdlg->attr[KEY_DSN].attr);
19429  }
19430  } else {
19431  setupdlg->parent = hwnd;
19432  setupdlg->driver = driver;
19433  setupdlg->newDSN = request == ODBC_ADD_DSN;
19434  setupdlg->defDSN = strcasecmp(setupdlg->attr[KEY_DSN].attr,
19435  "Default") == 0;
19436  if (hwnd) {
19437  success = DialogBoxParam(hModule, MAKEINTRESOURCE(CONFIGDSN),
19438  hwnd, (DLGPROC) ConfigDlgProc,
19439  (LPARAM) setupdlg) == IDOK;
19440  } else if (setupdlg->attr[KEY_DSN].supplied) {
19441  success = SetDSNAttributes(hwnd, setupdlg);
19442  } else {
19443  success = FALSE;
19444  }
19445  }
19446  xfree(setupdlg);
19447  return success;
19448 }
19449 
19459 static BOOL CALLBACK
19460 DriverConnectProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19461 {
19462  SETUPDLG *setupdlg;
19463  WORD index;
19464 
19465  switch (wmsg) {
19466  case WM_INITDIALOG:
19467 #ifdef _WIN64
19468  SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19469 #else
19470  SetWindowLong(hdlg, DWL_USER, lparam);
19471 #endif
19472  setupdlg = (SETUPDLG *) lparam;
19473  SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19474  SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19475  SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19476  SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19477  SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19478  SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19479  (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19480  SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19481  (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19482  SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19483  (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19484  SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19485  (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19486  SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19487  (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19488  CheckDlgButton(hdlg, IDC_STEPAPI,
19489  getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19490  BST_CHECKED : BST_UNCHECKED);
19491  CheckDlgButton(hdlg, IDC_NOTXN,
19492  getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19493  BST_CHECKED : BST_UNCHECKED);
19494  CheckDlgButton(hdlg, IDC_SHORTNAM,
19495  getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19496  BST_CHECKED : BST_UNCHECKED);
19497  CheckDlgButton(hdlg, IDC_LONGNAM,
19498  getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19499  BST_CHECKED : BST_UNCHECKED);
19500  CheckDlgButton(hdlg, IDC_NOCREAT,
19501  getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19502  BST_CHECKED : BST_UNCHECKED);
19503  CheckDlgButton(hdlg, IDC_NOWCHAR,
19504  getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19505  BST_CHECKED : BST_UNCHECKED);
19506  CheckDlgButton(hdlg, IDC_FKSUPPORT,
19507  getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19508  BST_CHECKED : BST_UNCHECKED);
19509  CheckDlgButton(hdlg, IDC_OEMCP,
19510  getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19511  BST_CHECKED : BST_UNCHECKED);
19512  CheckDlgButton(hdlg, IDC_BIGINT,
19513  getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19514  BST_CHECKED : BST_UNCHECKED);
19515  CheckDlgButton(hdlg, IDC_JDCONV,
19516  getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19517  BST_CHECKED : BST_UNCHECKED);
19518  SendDlgItemMessage(hdlg, IDC_SYNCP,
19519  CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19520  SendDlgItemMessage(hdlg, IDC_SYNCP,
19521  CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19522  SendDlgItemMessage(hdlg, IDC_SYNCP,
19523  CB_ADDSTRING, 0, (LPARAM) "OFF");
19524  SendDlgItemMessage(hdlg, IDC_SYNCP,
19525  CB_ADDSTRING, 0, (LPARAM) "FULL");
19526  SendDlgItemMessage(hdlg, IDC_SYNCP,
19527  CB_SELECTSTRING, (WORD) -1,
19528  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19529  if (setupdlg->defDSN) {
19530  EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19531  EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19532  }
19533  return TRUE;
19534  case WM_COMMAND:
19535  switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19536  case IDC_BROWSE:
19537  GetDBFile(hdlg);
19538  break;
19539  case IDOK:
19540 #ifdef _WIN64
19541  setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19542 #else
19543  setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19544 #endif
19545  GetDlgItemText(hdlg, IDC_DSNAME,
19546  setupdlg->attr[KEY_DSN].attr,
19547  sizeof (setupdlg->attr[KEY_DSN].attr));
19548  GetDlgItemText(hdlg, IDC_DBNAME,
19549  setupdlg->attr[KEY_DBNAME].attr,
19550  sizeof (setupdlg->attr[KEY_DBNAME].attr));
19551  GetDlgItemText(hdlg, IDC_TONAME,
19552  setupdlg->attr[KEY_BUSY].attr,
19553  sizeof (setupdlg->attr[KEY_BUSY].attr));
19554  GetDlgItemText(hdlg, IDC_LOADEXT,
19555  setupdlg->attr[KEY_LOADEXT].attr,
19556  sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19557  index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19558  CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19559  if (index != (WORD) CB_ERR) {
19560  SendDlgItemMessage(hdlg, IDC_SYNCP,
19561  CB_GETLBTEXT, index,
19562  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19563  }
19564  strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19565  (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19566  "1" : "0");
19567  strcpy(setupdlg->attr[KEY_NOTXN].attr,
19568  (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19569  "1" : "0");
19570  strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19571  (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19572  "1" : "0");
19573  strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19574  (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19575  "1" : "0");
19576  strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19577  (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19578  "1" : "0");
19579  strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19580  (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19581  "1" : "0");
19582  strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19583  (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19584  "1" : "0");
19585  strcpy(setupdlg->attr[KEY_OEMCP].attr,
19586  (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19587  "1" : "0");
19588  strcpy(setupdlg->attr[KEY_BIGINT].attr,
19589  (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19590  "1" : "0");
19591  strcpy(setupdlg->attr[KEY_JDCONV].attr,
19592  (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19593  "1" : "0");
19594  /* FALL THROUGH */
19595  case IDCANCEL:
19596  EndDialog(hdlg, GET_WM_COMMAND_ID(wparam, lparam) == IDOK);
19597  return TRUE;
19598  }
19599  }
19600  return FALSE;
19601 }
19602 
19616 static SQLRETURN
19617 drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
19618  SQLCHAR *connIn, SQLSMALLINT connInLen,
19619  SQLCHAR *connOut, SQLSMALLINT connOutMax,
19620  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19621 {
19622  BOOL maybeprompt, prompt = FALSE, defaultdsn = FALSE;
19623  DBC *d;
19624  SETUPDLG *setupdlg;
19625  SQLRETURN ret;
19626  char *dsn = NULL, *driver = NULL, *dbname = NULL;
19627 
19628  if (dbc == SQL_NULL_HDBC) {
19629  return SQL_INVALID_HANDLE;
19630  }
19631  d = (DBC *) dbc;
19632  if (d->sqlite) {
19633  setstatd(d, -1, "connection already established", "08002");
19634  return SQL_ERROR;
19635  }
19636  setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
19637  if (setupdlg == NULL) {
19638  return SQL_ERROR;
19639  }
19640  memset(setupdlg, 0, sizeof (SETUPDLG));
19641  maybeprompt = drvcompl == SQL_DRIVER_COMPLETE ||
19642  drvcompl == SQL_DRIVER_COMPLETE_REQUIRED;
19643  if (connIn == NULL || !connInLen ||
19644  (connInLen == SQL_NTS && !connIn[0])) {
19645  prompt = TRUE;
19646  } else {
19647  ParseAttributes((LPCSTR) connIn, setupdlg);
19648  if (!setupdlg->attr[KEY_DSN].attr[0] &&
19649  drvcompl == SQL_DRIVER_COMPLETE_REQUIRED) {
19650  strcpy(setupdlg->attr[KEY_DSN].attr, "DEFAULT");
19651  defaultdsn = TRUE;
19652  }
19653  GetAttributes(setupdlg);
19654  if (drvcompl == SQL_DRIVER_PROMPT ||
19655  (maybeprompt &&
19656  !setupdlg->attr[KEY_DBNAME].attr[0])) {
19657  prompt = TRUE;
19658  }
19659  }
19660 retry:
19661  if (prompt) {
19662  short dlgret;
19663 
19664  setupdlg->defDSN = setupdlg->attr[KEY_DRIVER].attr[0] != '\0';
19665  dlgret = DialogBoxParam(hModule, MAKEINTRESOURCE(DRIVERCONNECT),
19666  hwnd, (DLGPROC) DriverConnectProc,
19667  (LPARAM) setupdlg);
19668 
19669  if (!dlgret || dlgret == -1) {
19670  xfree(setupdlg);
19671  return SQL_NO_DATA;
19672  }
19673  }
19674  dsn = setupdlg->attr[KEY_DSN].attr;
19675  driver = setupdlg->attr[KEY_DRIVER].attr;
19676  dbname = setupdlg->attr[KEY_DBNAME].attr;
19677  if (connOut || connOutLen) {
19678  char buf[SQL_MAX_MESSAGE_LENGTH * 8];
19679  int len, count;
19680  char dsn_0 = (dsn && !defaultdsn) ? dsn[0] : '\0';
19681  char drv_0 = driver ? driver[0] : '\0';
19682 
19683  buf[0] = '\0';
19684  count = snprintf(buf, sizeof (buf),
19685  "%s%s%s%s%s%sDatabase=%s;StepAPI=%s;"
19686  "SyncPragma=%s;NoTXN=%s;Timeout=%s;"
19687  "ShortNames=%s;LongNames=%s;"
19688  "NoCreat=%s;NoWCHAR=%s;"
19689  "FKSupport=%s;JournalMode=%s;OEMCP=%s;LoadExt=%s;"
19690  "BigInt=%s;JDConv=%s;PWD=%s",
19691  dsn_0 ? "DSN=" : "",
19692  dsn_0 ? dsn : "",
19693  dsn_0 ? ";" : "",
19694  drv_0 ? "Driver=" : "",
19695  drv_0 ? driver : "",
19696  drv_0 ? ";" : "",
19697  dbname ? dbname : "",
19698  setupdlg->attr[KEY_STEPAPI].attr,
19699  setupdlg->attr[KEY_SYNCP].attr,
19700  setupdlg->attr[KEY_NOTXN].attr,
19701  setupdlg->attr[KEY_BUSY].attr,
19702  setupdlg->attr[KEY_SHORTNAM].attr,
19703  setupdlg->attr[KEY_LONGNAM].attr,
19704  setupdlg->attr[KEY_NOCREAT].attr,
19705  setupdlg->attr[KEY_NOWCHAR].attr,
19706  setupdlg->attr[KEY_FKSUPPORT].attr,
19707  setupdlg->attr[KEY_JMODE].attr,
19708  setupdlg->attr[KEY_OEMCP].attr,
19709  setupdlg->attr[KEY_LOADEXT].attr,
19710  setupdlg->attr[KEY_BIGINT].attr,
19711  setupdlg->attr[KEY_JDCONV].attr,
19712  setupdlg->attr[KEY_PASSWD].attr);
19713  if (count < 0) {
19714  buf[sizeof (buf) - 1] = '\0';
19715  }
19716  len = min(connOutMax - 1, strlen(buf));
19717  if (connOut) {
19718  strncpy((char *) connOut, buf, len);
19719  connOut[len] = '\0';
19720  }
19721  if (connOutLen) {
19722  *connOutLen = len;
19723  }
19724  }
19725  if (dsn[0]) {
19726  char tracef[SQL_MAX_MESSAGE_LENGTH];
19727 
19728  tracef[0] = '\0';
19729  SQLGetPrivateProfileString(setupdlg->attr[KEY_DSN].attr,
19730  "tracefile", "", tracef,
19731  sizeof (tracef), ODBC_INI);
19732  if (tracef[0] != '\0') {
19733  d->trace = fopen(tracef, "a");
19734  }
19735  }
19736  d->nowchar = getbool(setupdlg->attr[KEY_NOWCHAR].attr);
19737  d->shortnames = getbool(setupdlg->attr[KEY_SHORTNAM].attr);
19738  d->longnames = getbool(setupdlg->attr[KEY_LONGNAM].attr);
19739  d->nocreat = getbool(setupdlg->attr[KEY_NOCREAT].attr);
19740  d->fksupport = getbool(setupdlg->attr[KEY_FKSUPPORT].attr);
19741  d->oemcp = getbool(setupdlg->attr[KEY_OEMCP].attr);
19742  d->dobigint = getbool(setupdlg->attr[KEY_BIGINT].attr);
19743  d->jdconv = getbool(setupdlg->attr[KEY_JDCONV].attr);
19744  d->pwdLen = strlen(setupdlg->attr[KEY_PASSWD].attr);
19745  d->pwd = (d->pwdLen > 0) ? setupdlg->attr[KEY_PASSWD].attr : NULL;
19746  ret = dbopen(d, dbname ? dbname : "", 0,
19747  dsn ? dsn : "",
19748  setupdlg->attr[KEY_STEPAPI].attr,
19749  setupdlg->attr[KEY_SYNCP].attr,
19750  setupdlg->attr[KEY_NOTXN].attr,
19751  setupdlg->attr[KEY_JMODE].attr,
19752  setupdlg->attr[KEY_BUSY].attr);
19753  if (ret != SQL_SUCCESS) {
19754  if (maybeprompt && !prompt) {
19755  prompt = TRUE;
19756  goto retry;
19757  }
19758  }
19759  memset(setupdlg->attr[KEY_PASSWD].attr, 0,
19760  sizeof (setupdlg->attr[KEY_PASSWD].attr));
19761  if (ret == SQL_SUCCESS) {
19762  dbloadext(d, setupdlg->attr[KEY_LOADEXT].attr);
19763  }
19764  xfree(setupdlg);
19765  return ret;
19766 }
19767 
19768 #endif /* WITHOUT_DRIVERMGR */
19769 #endif /* _WIN32 || _WIN64 */
19770 
19771 #ifndef WINTERFACE
19772 
19785 SQLRETURN SQL_API
19786 SQLDriverConnect(SQLHDBC dbc, SQLHWND hwnd,
19787  SQLCHAR *connIn, SQLSMALLINT connInLen,
19788  SQLCHAR *connOut, SQLSMALLINT connOutMax,
19789  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19790 {
19791  SQLRETURN ret;
19792 
19793  HDBC_LOCK(dbc);
19794  ret = drvdriverconnect(dbc, hwnd, connIn, connInLen,
19795  connOut, connOutMax, connOutLen, drvcompl);
19796  HDBC_UNLOCK(dbc);
19797  return ret;
19798 }
19799 #endif
19800 
19801 #ifdef WINTERFACE
19802 
19815 SQLRETURN SQL_API
19816 SQLDriverConnectW(SQLHDBC dbc, SQLHWND hwnd,
19817  SQLWCHAR *connIn, SQLSMALLINT connInLen,
19818  SQLWCHAR *connOut, SQLSMALLINT connOutMax,
19819  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19820 {
19821  SQLRETURN ret;
19822  char *ci = NULL;
19823  SQLSMALLINT len = 0;
19824 
19825  HDBC_LOCK(dbc);
19826  if (connIn) {
19827 #if defined(_WIN32) || defined(_WIN64)
19828  if (connInLen == SQL_NTS) {
19829  connInLen = -1;
19830  }
19831  ci = uc_to_wmb(connIn, connInLen);
19832 #else
19833  ci = uc_to_utf(connIn, connInLen);
19834 #endif
19835  if (!ci) {
19836  DBC *d = (DBC *) dbc;
19837 
19838  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
19839  HDBC_UNLOCK(dbc);
19840  return SQL_ERROR;
19841  }
19842  }
19843  ret = drvdriverconnect(dbc, hwnd, (SQLCHAR *) ci, SQL_NTS,
19844  (SQLCHAR *) connOut, connOutMax, &len, drvcompl);
19845  HDBC_UNLOCK(dbc);
19846  uc_free(ci);
19847  if (ret == SQL_SUCCESS) {
19848  SQLWCHAR *co = NULL;
19849 
19850  if (connOut) {
19851  if (len > 0) {
19852 #if defined(_WIN32) || defined(_WIN64)
19853  co = wmb_to_uc((char *) connOut, len);
19854 #else
19855  co = uc_from_utf((SQLCHAR *) connOut, len);
19856 #endif
19857  if (co) {
19858  uc_strncpy(connOut, co, connOutMax / sizeof (SQLWCHAR));
19859  len = min(connOutMax / sizeof (SQLWCHAR), uc_strlen(co));
19860  uc_free(co);
19861  } else {
19862  len = 0;
19863  }
19864  }
19865  if (len <= 0) {
19866  len = 0;
19867  connOut[0] = 0;
19868  }
19869  } else {
19870  len = 0;
19871  }
19872  if (connOutLen) {
19873  *connOutLen = len;
19874  }
19875  }
19876  return ret;
19877 }
19878 #endif
19879 
19880 #if defined(_WIN32) || defined(_WIN64)
19881 
19890 BOOL APIENTRY
19891 LibMain(HANDLE hinst, DWORD reason, LPVOID reserved)
19892 {
19893  static int initialized = 0;
19894 
19895  switch (reason) {
19896  case DLL_PROCESS_ATTACH:
19897  if (!initialized++) {
19898  hModule = hinst;
19899 #ifdef WINTERFACE
19900  /* MS Access hack part 1 (reserved error -7748) */
19901  statSpec2P = statSpec2;
19902  statSpec3P = statSpec3;
19903 #endif
19904 #ifdef SQLITE_DYNLOAD
19905  dls_init();
19906 #endif
19907 #ifdef SQLITE_HAS_CODEC
19908  sqlite3_activate_see(SQLITE_ACTIVATION_KEY);
19909 #endif
19910  }
19911 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
19912  nvfs_init();
19913 #endif
19914  break;
19915  case DLL_THREAD_ATTACH:
19916  break;
19917  case DLL_PROCESS_DETACH:
19918  if (--initialized <= 0) {
19919 #ifdef SQLITE_DYNLOAD
19920  dls_fini();
19921 #endif
19922  }
19923  break;
19924  case DLL_THREAD_DETACH:
19925  break;
19926  default:
19927  break;
19928  }
19929  return TRUE;
19930 }
19931 
19940 int __stdcall
19941 DllMain(HANDLE hinst, DWORD reason, LPVOID reserved)
19942 {
19943  return LibMain(hinst, reason, reserved);
19944 }
19945 
19946 #ifndef WITHOUT_INSTALLER
19947 
19954 static BOOL
19955 InUnError(char *name)
19956 {
19957  WORD err = 1;
19958  DWORD code;
19959  char errmsg[301];
19960  WORD errlen, errmax = sizeof (errmsg) - 1;
19961  int sqlret;
19962  BOOL ret = FALSE;
19963 
19964  do {
19965  errmsg[0] = '\0';
19966  sqlret = SQLInstallerError(err, &code, errmsg, errmax, &errlen);
19967  if (SQL_SUCCEEDED(sqlret)) {
19968  MessageBox(NULL, errmsg, name,
19969  MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
19970  ret = TRUE;
19971  }
19972  err++;
19973  } while (sqlret != SQL_NO_DATA);
19974  return ret;
19975 }
19976 
19983 static BOOL
19984 InUn(int remove, char *cmdline)
19985 {
19986 #ifdef SQLITE_HAS_CODEC
19987  static char *drivername = "SQLite3 ODBC Driver (SEE)";
19988  static char *dsname = "SQLite3 SEE Datasource";
19989 #else
19990  static char *drivername = "SQLite3 ODBC Driver";
19991  static char *dsname = "SQLite3 Datasource";
19992 #endif
19993  char *dllname, *p;
19994  char dllbuf[301], path[301], driver[300], attr[300], inst[400];
19995  WORD pathmax = sizeof (path) - 1, pathlen;
19996  DWORD usecnt, mincnt;
19997  int quiet = 0;
19998 
19999  dllbuf[0] = '\0';
20000  GetModuleFileName(hModule, dllbuf, sizeof (dllbuf));
20001  p = strrchr(dllbuf, '\\');
20002  dllname = p ? (p + 1) : dllbuf;
20003  quiet = cmdline && strstr(cmdline, "quiet");
20004  if (SQLInstallDriverManager(path, pathmax, &pathlen)) {
20005  sprintf(driver, "%s;Driver=%s;Setup=%s;",
20006  drivername, dllname, dllname);
20007  p = driver;
20008  while (*p) {
20009  if (*p == ';') {
20010  *p = '\0';
20011  }
20012  ++p;
20013  }
20014  usecnt = 0;
20015  path[0] = '\0';
20016  SQLInstallDriverEx(driver, NULL, path, pathmax, NULL,
20017  ODBC_INSTALL_INQUIRY, &usecnt);
20018  pathlen = strlen(path);
20019  while (pathlen > 0 && path[pathlen - 1] == '\\') {
20020  --pathlen;
20021  path[pathlen] = '\0';
20022  }
20023  sprintf(driver, "%s;Driver=%s\\%s;Setup=%s\\%s;",
20024  drivername, path, dllname, path, dllname);
20025  p = driver;
20026  while (*p) {
20027  if (*p == ';') {
20028  *p = '\0';
20029  }
20030  ++p;
20031  }
20032  sprintf(inst, "%s\\%s", path, dllname);
20033  if (!remove && usecnt > 0) {
20034  /* first install try: copy over driver dll, keeping DSNs */
20035  if (GetFileAttributesA(dllbuf) != INVALID_FILE_ATTRIBUTES &&
20036  CopyFile(dllbuf, inst, 0)) {
20037  if (!quiet) {
20038  char buf[512];
20039 
20040  sprintf(buf, "%s replaced.", drivername);
20041  MessageBox(NULL, buf, "Info",
20042  MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20043  MB_SETFOREGROUND);
20044  }
20045  return TRUE;
20046  }
20047  }
20048  mincnt = remove ? 1 : 0;
20049  while (usecnt != mincnt) {
20050  if (!SQLRemoveDriver(driver, TRUE, &usecnt)) {
20051  break;
20052  }
20053  }
20054  if (remove) {
20055  if (usecnt && !SQLRemoveDriver(driver, TRUE, &usecnt)) {
20056  InUnError("SQLRemoveDriver");
20057  return FALSE;
20058  }
20059  if (!usecnt) {
20060  char buf[512];
20061 
20062  DeleteFile(inst);
20063  if (!quiet) {
20064  sprintf(buf, "%s uninstalled.", drivername);
20065  MessageBox(NULL, buf, "Info",
20066  MB_ICONINFORMATION |MB_OK | MB_TASKMODAL |
20067  MB_SETFOREGROUND);
20068  }
20069  }
20070  sprintf(attr, "DSN=%s;Database=;", dsname);
20071  p = attr;
20072  while (*p) {
20073  if (*p == ';') {
20074  *p = '\0';
20075  }
20076  ++p;
20077  }
20078  SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20079  return TRUE;
20080  }
20081  if (GetFileAttributesA(dllbuf) == INVALID_FILE_ATTRIBUTES) {
20082  return FALSE;
20083  }
20084  if (strcasecmp(dllbuf, inst) != 0 && !CopyFile(dllbuf, inst, 0)) {
20085  char buf[512];
20086 
20087  sprintf(buf, "Copy %s to %s failed.", dllbuf, inst);
20088  MessageBox(NULL, buf, "CopyFile",
20089  MB_ICONSTOP |MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
20090  return FALSE;
20091  }
20092  if (!SQLInstallDriverEx(driver, path, path, pathmax, &pathlen,
20093  ODBC_INSTALL_COMPLETE, &usecnt)) {
20094  InUnError("SQLInstallDriverEx");
20095  return FALSE;
20096  }
20097  sprintf(attr, "DSN=%s;Database=;", dsname);
20098  p = attr;
20099  while (*p) {
20100  if (*p == ';') {
20101  *p = '\0';
20102  }
20103  ++p;
20104  }
20105  SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20106  if (!SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN, drivername, attr)) {
20107  InUnError("SQLConfigDataSource");
20108  return FALSE;
20109  }
20110  if (!quiet) {
20111  char buf[512];
20112 
20113  sprintf(buf, "%s installed.", drivername);
20114  MessageBox(NULL, buf, "Info",
20115  MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20116  MB_SETFOREGROUND);
20117  }
20118  } else {
20119  InUnError("SQLInstallDriverManager");
20120  return FALSE;
20121  }
20122  return TRUE;
20123 }
20124 
20133 void CALLBACK
20134 install(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20135 {
20136  InUn(0, lpszCmdLine);
20137 }
20138 
20147 void CALLBACK
20148 uninstall(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20149 {
20150  InUn(1, lpszCmdLine);
20151 }
20152 
20153 #endif /* WITHOUT_INSTALLER */
20154 
20155 #ifndef WITHOUT_SHELL
20156 
20165 static void
20166 setargv(int *argcp, char ***argvp, char *cmdline, char *argv0)
20167 {
20168  char *p, *arg, *argspace, **argv;
20169  int argc, size, inquote, copy, slashes;
20170 
20171  size = 2 + (argv0 ? 1 : 0);
20172  for (p = cmdline; *p != '\0'; p++) {
20173  if (ISSPACE(*p)) {
20174  size++;
20175  while (ISSPACE(*p)) {
20176  p++;
20177  }
20178  if (*p == '\0') {
20179  break;
20180  }
20181  }
20182  }
20183  argspace = malloc(size * sizeof (char *) + strlen(cmdline) + 1);
20184  argv = (char **) argspace;
20185  argspace += size * sizeof (char *);
20186  size--;
20187  argc = 0;
20188  if (argv0) {
20189  argv[argc++] = argv0;
20190  }
20191  p = cmdline;
20192  for (; argc < size; argc++) {
20193  argv[argc] = arg = argspace;
20194  while (ISSPACE(*p)) {
20195  p++;
20196  }
20197  if (*p == '\0') {
20198  break;
20199  }
20200  inquote = 0;
20201  slashes = 0;
20202  while (1) {
20203  copy = 1;
20204  while (*p == '\\') {
20205  slashes++;
20206  p++;
20207  }
20208  if (*p == '"') {
20209  if ((slashes & 1) == 0) {
20210  copy = 0;
20211  if (inquote && p[1] == '"') {
20212  p++;
20213  copy = 1;
20214  } else {
20215  inquote = !inquote;
20216  }
20217  }
20218  slashes >>= 1;
20219  }
20220  while (slashes) {
20221  *arg = '\\';
20222  arg++;
20223  slashes--;
20224  }
20225  if (*p == '\0' || (!inquote && ISSPACE(*p))) {
20226  break;
20227  }
20228  if (copy != 0) {
20229  *arg = *p;
20230  arg++;
20231  }
20232  p++;
20233  }
20234  *arg = '\0';
20235  argspace = arg + 1;
20236  }
20237  argv[argc] = 0;
20238  *argcp = argc;
20239  *argvp = argv;
20240 }
20241 
20250 void CALLBACK
20251 shell(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20252 {
20253  int argc, needcon = 0;
20254  char **argv;
20255  extern int sqlite3_main(int, char **);
20256  static const char *name = "SQLite3 Shell";
20257  DWORD ftype0, ftype1, ftype2;
20258 
20259  ftype0 = GetFileType(GetStdHandle(STD_INPUT_HANDLE));
20260  ftype1 = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
20261  ftype2 = GetFileType(GetStdHandle(STD_ERROR_HANDLE));
20262  if (ftype0 != FILE_TYPE_DISK && ftype0 != FILE_TYPE_CHAR &&
20263  ftype0 != FILE_TYPE_PIPE) {
20264  fclose(stdin);
20265  ++needcon;
20266  ftype0 = FILE_TYPE_UNKNOWN;
20267  }
20268  if (ftype1 != FILE_TYPE_DISK && ftype1 != FILE_TYPE_CHAR &&
20269  ftype1 != FILE_TYPE_PIPE) {
20270  fclose(stdout);
20271  ++needcon;
20272  ftype1 = FILE_TYPE_UNKNOWN;
20273  }
20274  if (ftype2 != FILE_TYPE_DISK && ftype2 != FILE_TYPE_CHAR &&
20275  ftype2 != FILE_TYPE_PIPE) {
20276  fclose(stderr);
20277  ++needcon;
20278  ftype2 = FILE_TYPE_UNKNOWN;
20279  }
20280  if (needcon > 0) {
20281  AllocConsole();
20282  SetConsoleTitle(name);
20283  }
20284  if (ftype0 == FILE_TYPE_UNKNOWN) {
20285  freopen("CONIN$", "r", stdin);
20286  }
20287  if (ftype1 == FILE_TYPE_UNKNOWN) {
20288  freopen("CONOUT$", "w", stdout);
20289  }
20290  if (ftype2 == FILE_TYPE_UNKNOWN) {
20291  freopen("CONOUT$", "w", stderr);
20292  }
20293  setargv(&argc, &argv, lpszCmdLine, (char *) name);
20294 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
20295  nvfs_init();
20296 #endif
20297  sqlite3_main(argc, argv);
20298 }
20299 
20300 #endif /* WITHOUT_SHELL */
20301 
20302 #endif /* _WIN32 || _WIN64 */
20303 
20304 #if defined(HAVE_ODBCINSTEXT_H) && (HAVE_ODBCINSTEXT_H)
20305 
20306 /*
20307  * unixODBC property page for this driver,
20308  * may or may not work depending on unixODBC version.
20309  */
20310 
20311 #include <odbcinstext.h>
20312 
20313 int
20314 ODBCINSTGetProperties(HODBCINSTPROPERTY prop)
20315 {
20316  static const char *instYN[] = { "No", "Yes", NULL };
20317  static const char *syncPragma[] = { "NORMAL", "OFF", "FULL", NULL };
20318  static const char *jmPragma[] = {
20319  "DELETE", "PERSIST", "OFF", "TRUNCATE", "MEMORY", "WAL", NULL
20320  };
20321 
20322  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20323  prop = prop->pNext;
20324  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20325  prop->nPromptType = ODBCINST_PROMPTTYPE_FILENAME;
20326  strncpy(prop->szName, "Database", INI_MAX_PROPERTY_NAME);
20327  strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20328  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20329  prop = prop->pNext;
20330  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20331  prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20332  strncpy(prop->szName, "Timeout", INI_MAX_PROPERTY_NAME);
20333  strncpy(prop->szValue, "100000", INI_MAX_PROPERTY_VALUE);
20334  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20335  prop = prop->pNext;
20336  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20337  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20338  prop->aPromptData = malloc(sizeof (instYN));
20339  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20340  strncpy(prop->szName, "StepAPI", INI_MAX_PROPERTY_NAME);
20341  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20342  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20343  prop = prop->pNext;
20344  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20345  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20346  prop->aPromptData = malloc(sizeof (instYN));
20347  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20348  strncpy(prop->szName, "ShortNames", INI_MAX_PROPERTY_NAME);
20349  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20350  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20351  prop = prop->pNext;
20352  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20353  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20354  prop->aPromptData = malloc(sizeof (instYN));
20355  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20356  strncpy(prop->szName, "LongNames", INI_MAX_PROPERTY_NAME);
20357  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20358  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20359  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20360  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20361  prop->aPromptData = malloc(sizeof (instYN));
20362  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20363  strncpy(prop->szName, "NoCreat", INI_MAX_PROPERTY_NAME);
20364  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20365 #ifdef WINTERFACE
20366  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20367  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20368  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20369  prop->aPromptData = malloc(sizeof (instYN));
20370  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20371  strncpy(prop->szName, "NoWCHAR", INI_MAX_PROPERTY_NAME);
20372  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20373 #endif
20374  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20375  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20376  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20377  prop->aPromptData = malloc(sizeof (instYN));
20378  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20379  strncpy(prop->szName, "FKSupport", INI_MAX_PROPERTY_NAME);
20380  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20381  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20382  prop = prop->pNext;
20383  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20384  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20385  prop->aPromptData = malloc(sizeof (syncPragma));
20386  memcpy(prop->aPromptData, syncPragma, sizeof (syncPragma));
20387  strncpy(prop->szName, "SyncPragma", INI_MAX_PROPERTY_NAME);
20388  strncpy(prop->szValue, "NORMAL", INI_MAX_PROPERTY_VALUE);
20389  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20390  prop = prop->pNext;
20391  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20392  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20393  prop->aPromptData = malloc(sizeof (jmPragma));
20394  memcpy(prop->aPromptData, jmPragma, sizeof (jmPragma));
20395  strncpy(prop->szName, "JournalMode", INI_MAX_PROPERTY_NAME);
20396  strncpy(prop->szValue, "DELETE", INI_MAX_PROPERTY_VALUE);
20397  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20398  prop = prop->pNext;
20399  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20400  prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20401  strncpy(prop->szName, "LoadExt", INI_MAX_PROPERTY_NAME);
20402  strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20403  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20404  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20405  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20406  prop->aPromptData = malloc(sizeof (instYN));
20407  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20408  strncpy(prop->szName, "BigInt", INI_MAX_PROPERTY_NAME);
20409  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20410  return 1;
20411 }
20412 
20413 #endif /* HAVE_ODBCINSTEXT_H */
20414 
20415 #ifdef SQLITE_DYNLOAD
20416 
20417 /*
20418  * SQLite3 shared library/DLL stubs.
20419  */
20420 
20421 static void
20422 dls_void(void)
20423 {
20424 }
20425 
20426 static int
20427 dls_error(void)
20428 {
20429  return SQLITE_ERROR;
20430 }
20431 
20432 static int
20433 dls_0(void)
20434 {
20435  return 0;
20436 }
20437 
20438 static sqlite_int64
20439 dls_0LL(void)
20440 {
20441  return 0;
20442 }
20443 
20444 static double
20445 dls_00(void)
20446 {
20447  return 0;
20448 }
20449 
20450 static void *
20451 dls_null(void)
20452 {
20453  return NULL;
20454 }
20455 
20456 static const char *
20457 dls_empty(void)
20458 {
20459  return "";
20460 }
20461 
20462 static int
20463 dls_snull(void)
20464 {
20465  return SQLITE_NULL;
20466 }
20467 
20468 #define DLS_ENT(name, func) \
20469  { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, name), \
20470  (void *) func }
20471 
20472 #define DLS_ENT3(name, off, func) \
20473  { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, off), \
20474  (void *) func }
20475 
20476 #define DLS_END { NULL, 0, NULL }
20477 
20478 static struct {
20479  const char *name;
20480  int offset;
20481  void *func;
20482 } dls_nametab[] = {
20483  DLS_ENT(activate_see, dls_void),
20484  DLS_ENT(bind_blob, dls_error),
20485  DLS_ENT(bind_double, dls_error),
20486  DLS_ENT(bind_int, dls_error),
20487  DLS_ENT(bind_int64, dls_error),
20488  DLS_ENT(bind_null, dls_error),
20489  DLS_ENT(bind_parameter_count, dls_0),
20490  DLS_ENT(bind_text, dls_error),
20491  DLS_ENT(busy_handler, dls_error),
20492  DLS_ENT(changes, dls_0),
20493  DLS_ENT(close, dls_error),
20494  DLS_ENT(column_blob, dls_null),
20495  DLS_ENT(column_bytes, dls_0),
20496  DLS_ENT(column_count, dls_0),
20497  DLS_ENT(column_database_name, dls_empty),
20498  DLS_ENT(column_decltype, dls_empty),
20499  DLS_ENT(column_double, dls_00),
20500  DLS_ENT(column_name, dls_empty),
20501  DLS_ENT(column_origin_name, dls_null),
20502  DLS_ENT(column_table_name, dls_null),
20503  DLS_ENT(column_text, dls_null),
20504  DLS_ENT(column_type, dls_snull),
20505  DLS_ENT(create_function, dls_error),
20506  DLS_ENT(enable_load_extension, dls_error),
20507  DLS_ENT(errcode, dls_error),
20508  DLS_ENT(errmsg, dls_empty),
20509  DLS_ENT(exec, dls_error),
20510  DLS_ENT(finalize, dls_error),
20511  DLS_ENT(free, free),
20512  DLS_ENT(free_table, dls_void),
20513  DLS_ENT(get_table, dls_error),
20514  DLS_ENT(interrupt, dls_void),
20515  DLS_ENT(key, dls_error),
20516  DLS_ENT(last_insert_rowid, dls_0LL),
20517  DLS_ENT(libversion, dls_empty),
20518  DLS_ENT(load_extension, dls_error),
20519  DLS_ENT(malloc, malloc),
20520  DLS_ENT(mprintf, dls_null),
20521  DLS_ENT(open, dls_error),
20522  DLS_ENT(open16, dls_error),
20523  DLS_ENT(open_v2, dls_error),
20524  DLS_ENT(prepare, dls_error),
20525  DLS_ENT(prepare_v2, dls_error),
20526  DLS_ENT(profile, dls_null),
20527  DLS_ENT(realloc, realloc),
20528  DLS_ENT(rekey, dls_error),
20529  DLS_ENT(reset, dls_error),
20530  DLS_ENT(result_blob, dls_void),
20531  DLS_ENT(result_error, dls_void),
20532  DLS_ENT(result_int, dls_void),
20533  DLS_ENT(result_null, dls_void),
20534  DLS_ENT(step, dls_error),
20535 #if defined(_WIN32) || defined(_WIN64)
20536  DLS_ENT3(strnicmp, xstrnicmp, _strnicmp),
20537 #else
20538  DLS_ENT3(strnicmp, xstrnicmp, strncasecmp),
20539 #endif
20540  DLS_ENT(table_column_metadata, dls_error),
20541  DLS_ENT(trace, dls_null),
20542  DLS_ENT(user_data, dls_null),
20543  DLS_ENT(value_blob, dls_null),
20544  DLS_ENT(value_bytes, dls_0),
20545  DLS_ENT(value_text, dls_empty),
20546  DLS_ENT(value_type, dls_snull),
20547  DLS_END
20548 };
20549 
20550 #if defined(_WIN32) || defined(_WIN64)
20551 
20552 static HMODULE sqlite3_dll = 0;
20553 
20554 static void
20555 dls_init(void)
20556 {
20557  int i;
20558  static const char *dll_names[] = {
20559  "System.Data.SQLite.dll",
20560  "sqlite3.dll",
20561  NULL,
20562  };
20563 
20564  i = 0;
20565  while (dll_names[i]) {
20566  sqlite3_dll = LoadLibrary(dll_names[i]);
20567  if (sqlite3_dll) {
20568  break;
20569  }
20570  ++i;
20571  }
20572  i = 0;
20573  while (dls_nametab[i].name) {
20574  void *func = 0, **loc;
20575 
20576  if (sqlite3_dll) {
20577  func = (void *) GetProcAddress(sqlite3_dll, dls_nametab[i].name);
20578  }
20579  if (!func) {
20580  func = dls_nametab[i].func;
20581  }
20582  loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
20583  *loc = func;
20584  ++i;
20585  }
20586  if (!sqlite3_dll) {
20587  char buf[MAXPATHLEN], msg[MAXPATHLEN];
20588 
20589  LoadString(hModule, IDS_DRVTITLE, buf, sizeof (buf));
20590  LoadString(hModule, IDS_DLLERR, msg, sizeof (msg));
20591  MessageBox(NULL, msg, buf,
20592  MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
20593  MB_SETFOREGROUND);
20594  }
20595 }
20596 
20597 static void
20598 dls_fini(void)
20599 {
20600  if (sqlite3_dll) {
20601  FreeLibrary(sqlite3_dll);
20602  sqlite3_dll = 0;
20603  }
20604 }
20605 
20606 #else
20607 
20608 #include <dlfcn.h>
20609 
20610 static void *libsqlite3_so = 0;
20611 
20612 void
20613 dls_init(void)
20614 {
20615  int i;
20616 
20617  libsqlite3_so = dlopen("libsqlite3.so.0", RTLD_NOW | RTLD_GLOBAL);
20618  i = 0;
20619  while (dls_nametab[i].name) {
20620  void *func = 0, **loc;
20621 
20622  if (libsqlite3_so) {
20623  func = dlsym(libsqlite3_so, dls_nametab[i].name);
20624  }
20625  if (!func) {
20626  func = dls_nametab[i].func;
20627  }
20628  loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
20629  *loc = func;
20630  ++i;
20631  }
20632  if (!libsqlite3_so) {
20633  const char errmsg[] = "SQLite3 shared library not found.\n";
20634 
20635  write(2, errmsg, sizeof (errmsg) - 1);
20636  }
20637 }
20638 
20639 void
20640 dls_fini(void)
20641 {
20642  if (libsqlite3_so) {
20643  dlclose(libsqlite3_so);
20644  libsqlite3_so = 0;
20645  }
20646 }
20647 
20648 #endif
20649 
20650 #endif
20651 
20652 /*
20653  * Local Variables:
20654  * mode: c
20655  * c-basic-offset: 4
20656  * fill-column: 78
20657  * tab-width: 8
20658  * End:
20659  */
sqlite3_stmt * s3stmt
SQLite statement handle or NULL.
Definition: sqlite3odbc.h:284
SQLULEN paramset_size
SQL_ATTR_PARAMSET_SIZE.
Definition: sqlite3odbc.h:271
sqlite_int64 s3lival
SQLite3 64bit integer value.
Definition: sqlite3odbc.h:221
int busyint
Interrupt busy handler from SQLCancel()
Definition: sqlite3odbc.h:122
static SQLRETURN setupparbuf(STMT *s, BINDPARM *p)
Setup parameter buffer for deferred parameter.
Definition: sqlite3odbc.c:5591
void * parbuf
Buffer for SQL_LEN_DATA_AT_EXEC etc.
Definition: sqlite3odbc.h:215
SQLRETURN SQL_API SQLSetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
Set connect attribute of HDBC (UNICODE version).
Internal dynamic string buffer.
Definition: blobtoxy.c:1212
SQLRETURN SQL_API SQLSetDescRec(SQLHDESC handle, SQLSMALLINT recno, SQLSMALLINT type, SQLSMALLINT subtype, SQLLEN len, SQLSMALLINT prec, SQLSMALLINT scale, SQLPOINTER data, SQLLEN *strlen, SQLLEN *indicator)
Function not implemented.
Definition: sqlite3odbc.c:5868
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:9628
static SQLRETURN nomem(STMT *s)
Report S1000 (out of memory) SQL error given STMT.
Definition: sqlite3odbc.c:1812
static const char lower_chars[]
Definition: sqlite3odbc.c:547
static int findcol(char **cols, int ncols, char *name)
Find column given name in string array.
Definition: sqlite3odbc.c:2754
int longnames
Don&#39;t shorten column names.
Definition: sqlite3odbc.h:134
int nocreat
Don&#39;t auto create database file.
Definition: sqlite3odbc.h:135
#define xstrdup(x)
Definition: sqlite3odbc.c:406
#define SQLLEN
Definition: sqlite3odbc.h:62
#define SQLULEN
Definition: sqlite3odbc.h:68
static void freerows(char **rowp)
Free counted array of char pointers.
Definition: sqlite3odbc.c:2150
SQLRETURN SQL_API SQLDisconnect(SQLHDBC dbc)
Disconnect given HDBC.
static void setstatd(DBC *d, int naterr, char *msg, char *st,...)
Set error message and SQL state on DBC.
Definition: sqlite3odbc.c:1687
struct dbc * dbcs
Pointer to first DBC.
Definition: sqlite3odbc.h:103
void * param0
Parameter buffer, initial value.
Definition: sqlite3odbc.h:210
int * ov3
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:236
static SQLRETURN freeparams(STMT *s)
Clear out parameter bindings, if any.
Definition: sqlite3odbc.c:5006
int dobigint
Force SQL_BIGINT for INTEGER columns.
Definition: sqlite3odbc.h:262
SQLCHAR * query
Current query, raw string.
Definition: sqlite3odbc.h:235
sqlite3 * sqlite
SQLITE database handle.
Definition: sqlite3odbc.h:116
static SQLRETURN drvgettypeinfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
Internal return data type information.
SQLRETURN SQL_API SQLConnectW(SQLHDBC dbc, SQLWCHAR *dsn, SQLSMALLINT dsnLen, SQLWCHAR *uid, SQLSMALLINT uidLen, SQLWCHAR *pwd, SQLSMALLINT pwdLen)
Connect to SQLite database.
int guessed_types
Flag for drvprepare()/drvexecute()
Definition: sqlite3odbc.h:290
SQLRETURN SQL_API SQLForeignKeysW(SQLHSTMT stmt, SQLWCHAR *PKcatalog, SQLSMALLINT PKcatalogLen, SQLWCHAR *PKschema, SQLSMALLINT PKschemaLen, SQLWCHAR *PKtable, SQLSMALLINT PKtableLen, SQLWCHAR *FKcatalog, SQLSMALLINT FKcatalogLen, SQLWCHAR *FKschema, SQLSMALLINT FKschemaLen, SQLWCHAR *FKtable, SQLSMALLINT FKtableLen)
Retrieve information about primary/foreign keys (UNICODE version).
Definition: sqlite3odbc.c:7800
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:5625
static SQLRETURN drvfreeconnect(SQLHDBC dbc)
Internal free connection (HDBC).
SQLCHAR logmsg[1024]
Message for SQLError()
Definition: sqlite3odbc.h:260
static dstr * dsappend(dstr *dsp, const char *str)
Append string to dynamic string.
Definition: sqlite3odbc.c:638
static SQLRETURN drvgetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen, SQLSMALLINT *lenp)
Internal function to get cursor name of STMT.
char ** rows
2-dim array, result set
Definition: sqlite3odbc.h:256
int step_enable
True for sqlite_compile/step/finalize.
Definition: sqlite3odbc.h:138
#define drvgetgpps(d)
Definition: sqlite3odbc.c:1291
SQLRETURN SQL_API SQLColumnsW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen, SQLWCHAR *col, SQLSMALLINT colLen)
Retrieve column information on table (UNICODE version).
static COL colSpec3[]
static int drvgettable_row(TBLRES *t, int ncol, int rc)
Definition: sqlite3odbc.c:1392
static void blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function to import a BLOB from a file.
Definition: sqlite3odbc.c:3680
SQLRETURN SQL_API SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLLEN offset)
Fetch result row with scrolling.
static void s3bind(DBC *d, sqlite3_stmt *stmt, int nparams, BINDPARM *p)
Definition: sqlite3odbc.c:1300
int ispk
Flag for primary key (> 0)
Definition: sqlite3odbc.h:176
static SQLRETURN dofetchbind(STMT *s, int rsi)
Internal: fetch and bind from statement&#39;s current row.
PTRDIFF_T ndata
index into result array
Definition: sqlite3odbc.c:1382
SQLRETURN SQL_API SQLSetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
Set option on HDBC (UNICODE version).
#define SQLROWSETSIZE
Definition: sqlite3odbc.h:84
int intrans
True when transaction started.
Definition: sqlite3odbc.h:126
int shortnames
Always use short column names.
Definition: sqlite3odbc.h:133
static SQLRETURN drvgetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
Internal get connect option of HDBC.
static SQLRETURN drvallocconnect(SQLHENV env, SQLHDBC *dbc)
Internal allocate HDBC.
SQLULEN * parm_bind_offs
SQL_ATTR_PARAM_BIND_OFFSET_PTR.
Definition: sqlite3odbc.h:278
void * s3val
SQLite3 value buffer.
Definition: sqlite3odbc.h:219
static int str2time(int jdconv, char *str, TIME_STRUCT *ts)
Convert string to ODBC TIME_STRUCT.
Definition: sqlite3odbc.c:3211
Internal structure for bound column (SQLBindCol).
Definition: sqlite3odbc.h:188
static COL pkeySpec2[]
Columns for result set of SQLPrimaryKeys().
Definition: sqlite3odbc.c:6395
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:7239
static void freedyncols(STMT *s)
Free dynamically allocated column descriptions of STMT.
int nrows
Number of result rows.
Definition: sqlite3odbc.h:253
static int mapsqltype(const char *typename, int *nosign, int ov3, int nowchar, int dobigint)
Map SQL field type from string to ODBC integer type code.
Definition: sqlite3odbc.c:2176
SQLRETURN SQL_API SQLCancel(SQLHSTMT stmt)
Cancel HSTMT closing cursor.
static int quiet
Definition: inst.c:60
static void getmd(const char *typename, int sqltype, int *mp, int *dp)
Get maximum display size and number of digits after decimal point from field type specification...
Definition: sqlite3odbc.c:2300
SQLRETURN SQL_API SQLAllocEnv(SQLHENV *env)
Allocate HENV.
#define ISDIGIT(c)
Definition: sqlite3odbc.c:568
Driver internal structure for database connection (HDBC).
Definition: sqlite3odbc.h:112
SQLRETURN SQL_API SQLFreeConnect(SQLHDBC dbc)
Free connection (HDBC).
SQLRETURN SQL_API SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT orient, SQLROWOFFSET offset, SQLROWSETSIZE *rowcount, SQLUSMALLINT *rowstatus)
Fetch result row with scrolling and row status.
SQLULEN row_count0
Row count.
Definition: sqlite3odbc.h:270
int s3ival
SQLite3 integer value.
Definition: sqlite3odbc.h:220
struct stmt * cur_s3stmt
Current STMT executing sqlite statement.
Definition: sqlite3odbc.h:142
int need
True when SQL_LEN_DATA_AT_EXEC.
Definition: sqlite3odbc.h:212
static int checkddl(char *sql)
Check if query is a DDL statement.
Definition: sqlite3odbc.c:2471
static const char digit_chars[]
Definition: sqlite3odbc.c:566
static SQLRETURN drvgetdiagfield(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno, SQLSMALLINT id, SQLPOINTER info, SQLSMALLINT buflen, SQLSMALLINT *stringlen)
Get error record given handle (HDBC or HSTMT).
Definition: sqlite3odbc.c:8709
SQLULEN parm_bind_type
SQL_ATTR_PARAM_BIND_TYPE.
Definition: sqlite3odbc.h:282
int * ov3
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:123
static SQLRETURN drvfreestmt(SQLHSTMT stmt, SQLUSMALLINT opt)
Internal function to perform certain kinds of free/close on STMT.
SQLULEN * row_count
Row count pointer.
Definition: sqlite3odbc.h:269
SQLRETURN SQL_API SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen, SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
Translate SQL string (UNICODE version).
Definition: sqlite3odbc.c:8126
static SQLRETURN drvallocenv(SQLHENV *env)
Internal allocate HENV.
static COL procSpec2[]
Columns for result set of SQLProcedures().
Definition: sqlite3odbc.c:8161
char sqlstate[6]
SQL state for SQLError()
Definition: sqlite3odbc.h:259
static SQLRETURN drvprimarykeys(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen)
Internal retrieve information about indexed columns.
Definition: sqlite3odbc.c:6426
int inc
Increment for paramset size > 1.
Definition: sqlite3odbc.h:211
SQLLEN max
Max.
Definition: sqlite3odbc.h:206
static int getdsnattr(char *dsn, char *attr, char *out, int outLen)
Handling of SQLConnect() connection attributes for standalone operation without driver manager...
static void s3stmt_end(STMT *s)
Stop running sqlite statement.
Definition: sqlite3odbc.c:4532
SQLRETURN SQL_API SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno, SQLSMALLINT fieldid, SQLPOINTER value, SQLINTEGER buflen)
Function not implemented.
Definition: sqlite3odbc.c:5821
#define SQL_API
Definition: sqlite3odbc.h:58
char * column
Column name.
Definition: sqlite3odbc.h:167
int version
SQLITE version number.
Definition: sqlite3odbc.h:117
char * dsn
ODBC data source name.
Definition: sqlite3odbc.h:119
HDBC dbc
Pointer to DBC.
Definition: sqlite3odbc.h:233
static const char space_chars[]
Definition: sqlite3odbc.c:575
SQLRETURN SQL_API SQLDescribeColW(SQLHSTMT stmt, SQLUSMALLINT col, SQLWCHAR *name, SQLSMALLINT nameMax, SQLSMALLINT *nameLen, SQLSMALLINT *type, SQLULEN *size, SQLSMALLINT *digits, SQLSMALLINT *nullable)
Describe column information (UNICODE version).
static SQLRETURN drvdisconnect(SQLHDBC dbc)
Internal disconnect given HDBC.
static SQLRETURN drvsetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
Internal set option on HDBC.
#define SQLROWOFFSET
Definition: sqlite3odbc.h:80
int curtype
Default cursor type.
Definition: sqlite3odbc.h:137
#define xfree(x)
Definition: sqlite3odbc.c:405
Driver internal structure representing SQL statement (HSTMT).
Definition: sqlite3odbc.h:231
SQLRETURN SQL_API SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len, SQLINTEGER *lenp)
Get information of HENV.
Definition: sqlite3odbc.c:8365
SQLUINTEGER paramset_nrows
Row count for paramset handling.
Definition: sqlite3odbc.h:273
static int typeinfosort(const void *a, const void *b)
Helper function to sort type information.
int autocommit
Auto commit state.
Definition: sqlite3odbc.h:125
SQLCHAR logmsg[1024]
Message for SQLError()
Definition: sqlite3odbc.h:130
static SQLRETURN drvsetpos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
Internal set position on result in HSTMT.
static SQLRETURN drvgetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
Internal get option of HSTMT.
Definition: sqlite3odbc.c:9387
int isrowid
Flag for ROWID column (> 0)
Definition: sqlite3odbc.h:177
SQLRETURN SQL_API SQLGetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
Get option of HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9459
int prec
Precision of column.
Definition: sqlite3odbc.h:173
int magic
Magic cookie.
Definition: sqlite3odbc.h:97
ENV * env
Pointer to environment.
Definition: sqlite3odbc.h:114
char buffer[1]
String buffer.
Definition: sqlite3odbc.c:276
SQLRETURN SQL_API SQLProcedureColumnsW(SQLHSTMT stmt, SQLWCHAR *catalog, SQLSMALLINT catalogLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *proc, SQLSMALLINT procLen, SQLWCHAR *column, SQLSMALLINT columnLen)
Retrieve information about columns in result set of stored procedures (UNICODE version).
Definition: sqlite3odbc.c:8338
static void dbtrace(void *arg, const char *msg, sqlite_uint64 et)
SQLite trace or profile callback.
Definition: sqlite3odbc.c:3815
static void mktypeinfo(STMT *s, int row, int asize, char *typename, int type, int tind)
Internal function to build up data type information as row in result set.
#define HSTMT_LOCK(hdbc)
Definition: sqlite3odbc.c:532
SQLRETURN SQL_API SQLGetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
Get connect option of HDBC (UNICODE version).
SQLRETURN SQL_API SQLTransact(SQLHENV env, SQLHDBC dbc, SQLUSMALLINT type)
Commit or rollback transaction.
Definition: sqlite3odbc.c:8051
static void blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function to export a BLOB to a file.
Definition: sqlite3odbc.c:3750
static SQLRETURN drvgetinfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen)
Internal return information about what this ODBC driver supports.
int nrow
number of rows in result array
Definition: sqlite3odbc.c:1380
static COL procColSpec3[]
Definition: sqlite3odbc.c:8267
static double ln_strtod(const char *data, char **endp)
Internal locale neutral strtod function.
Definition: sqlite3odbc.c:1841
static SQLRETURN drvcolumns(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen, SQLCHAR *col, SQLSMALLINT colLen)
Internal retrieve column information on table.
static SQLRETURN drvputdata(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
Internal put (partial) parameter data into executing statement.
Definition: sqlite3odbc.c:4771
#define SET_EXISTS(x)
static int mapdeftype(int type, int stype, int nosign, int nowchar)
Map SQL_C_DEFAULT to proper C type.
Definition: sqlite3odbc.c:2385
static SQLRETURN SQL_API drvforeignkeys(SQLHSTMT stmt, SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen, SQLCHAR *PKschema, SQLSMALLINT PKschemaLen, SQLCHAR *PKtable, SQLSMALLINT PKtableLen, SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen, SQLCHAR *FKschema, SQLSMALLINT FKschemaLen, SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
Internal retrieve information about primary/foreign keys.
Definition: sqlite3odbc.c:7292
int pool
True for SQL_CP_ONE_PER_DRIVER.
Definition: sqlite3odbc.h:99
BINDPARM * bindparms
Array of bound parameters.
Definition: sqlite3odbc.h:250
#define SETSTMTOPTION_LAST_ARG_TYPE
Definition: sqlite3odbc.c:221
COL * cols
Result column array.
Definition: sqlite3odbc.h:241
#define DBC_MAGIC
Definition: sqlite3odbc.c:263
static SQLRETURN noconn(STMT *s)
Report S1000 (not connected) SQL error given STMT.
Definition: sqlite3odbc.c:1825
SQLULEN bind_type
SQL_ATTR_ROW_BIND_TYPE.
Definition: sqlite3odbc.h:275
SQLRETURN SQL_API SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
Put (partial) parameter data into executing statement.
Definition: sqlite3odbc.c:4990
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:5542
SQLRETURN SQL_API SQLCopyDesc(SQLHDESC source, SQLHDESC target)
Function not implemented.
Definition: sqlite3odbc.c:8064
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:5889
SQLPOINTER valp
Value buffer.
Definition: sqlite3odbc.h:192
SQLRETURN SQL_API SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT opt)
Free HSTMT.
SQLRETURN SQL_API SQLBulkOperations(SQLHSTMT stmt, SQLSMALLINT oper)
Perform bulk operation on HSTMT.
int ov3
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:98
SQLRETURN SQL_API SQLGetDiagFieldW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno, SQLSMALLINT id, SQLPOINTER info, SQLSMALLINT buflen, SQLSMALLINT *stringlen)
Get error record given handle (HDBC or HSTMT).
Definition: sqlite3odbc.c:8908
static int namematch(char *str, char *pat, int esc)
SQL LIKE string match with optional backslash escape handling.
Definition: sqlite3odbc.c:1945
SQLUSMALLINT * parm_oper
SQL_ATTR_PARAM_OPERATION_PTR.
Definition: sqlite3odbc.h:279
static SQLWCHAR * uc_strncpy(SQLWCHAR *dest, SQLWCHAR *src, int len)
Copy UNICODE string like strncpy().
Definition: sqlite3odbc.c:822
static SQLWCHAR * uc_from_utf(unsigned char *str, int len)
Make UNICODE string from UTF8 string.
Definition: sqlite3odbc.c:932
char * dbname
SQLITE database name.
Definition: sqlite3odbc.h:118
SQLRETURN SQL_API SQLEndTran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
Commit or rollback transaction.
Definition: sqlite3odbc.c:8037
SQLRETURN SQL_API SQLFetch(SQLHSTMT stmt)
Fetch next result row.
static SQLRETURN mkbindcols(STMT *s, int ncols)
Reallocate space for bound columns.
int fksupport
Foreign keys on or off.
Definition: sqlite3odbc.h:136
SQLRETURN SQL_API SQLSetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT len)
Set cursor name on STMT (UNICODE version).
int s3stmt_needmeta
True to get meta data in s3stmt_step().
Definition: sqlite3odbc.h:143
int rowprs
Current start row of rowset.
Definition: sqlite3odbc.h:255
char * table
Table name.
Definition: sqlite3odbc.h:166
SQLRETURN SQL_API SQLDescribeParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT *dtype, SQLULEN *size, SQLSMALLINT *decdigits, SQLSMALLINT *nullable)
Return information about parameter.
Definition: sqlite3odbc.c:5679
static SQLRETURN drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd, SQLCHAR *connIn, SQLSMALLINT connInLen, SQLCHAR *connOut, SQLSMALLINT connOutMax, SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
Internal standalone (w/o driver manager) database connect.
static SQLRETURN drvallocstmt(SQLHDBC dbc, SQLHSTMT *stmt)
Allocate HSTMT given HDBC (driver internal version).
static int initialized
Definition: xpath.c:66
#define strmak(dst, src, max, lenp)
int rc
SQLite return code.
Definition: sqlite3odbc.c:1383
SQLRETURN SQL_API SQLCloseCursor(SQLHSTMT stmt)
Close open cursor.
int s3stmt_rownum
Current row number.
Definition: sqlite3odbc.h:286
static COL tablePrivSpec2[]
Columns for result set of SQLTablePrivileges().
Definition: sqlite3odbc.c:5931
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:5964
int * jdconv
True for julian day conversion.
Definition: sqlite3odbc.h:238
SQLRETURN SQL_API SQLFreeHandle(SQLSMALLINT type, SQLHANDLE h)
Free a HENV, HDBC, or HSTMT handle.
static SQLRETURN drvsetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
Internal function to set cursor name on STMT.
SQLRETURN SQL_API SQLTablePrivilegesW(SQLHSTMT stmt, SQLWCHAR *catalog, SQLSMALLINT catalogLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen)
Retrieve privileges on tables and/or views (UNICODE version).
Definition: sqlite3odbc.c:6258
SQLUSMALLINT row_status1
Internal status array for 1 row rowsets.
Definition: sqlite3odbc.h:268
SQLLEN * lenp
Value return, actual size of value buffer.
Definition: sqlite3odbc.h:191
SQLULEN retr_data
SQL_ATTR_RETRIEVE_DATA.
Definition: sqlite3odbc.h:264
int longnames
Don&#39;t shorten column names.
Definition: sqlite3odbc.h:263
int index
Index of column in result.
Definition: sqlite3odbc.h:193
static SQLRETURN chkunbound(STMT *s)
Check for unbound result columns.
Definition: sqlite3odbc.c:9597
static void freep(void *x)
Free memory given pointer to memory pointer.
Definition: sqlite3odbc.c:1797
static void fixupdyncols(STMT *s, DBC *d)
Fixup column information for a running statement.
Definition: sqlite3odbc.c:2785
static char * uc_to_utf(SQLWCHAR *str, int len)
Make UTF8 string from UNICODE string.
Definition: sqlite3odbc.c:958
int nosign
Unsigned type.
Definition: sqlite3odbc.h:171
static int getmdays(int year, int month)
Return number of month days.
Definition: sqlite3odbc.c:3062
static COL tablePrivSpec3[]
Definition: sqlite3odbc.c:5941
SQLSMALLINT type
ODBC type.
Definition: sqlite3odbc.h:189
SQLRETURN SQL_API SQLPrimaryKeysW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen)
Retrieve information about indexed columns (UNICODE version).
Definition: sqlite3odbc.c:6754
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:7192
static int str2date(int jdconv, char *str, DATE_STRUCT *ds)
Convert string to ODBC DATE_STRUCT.
Definition: sqlite3odbc.c:3096
static COL procSpec3[]
Definition: sqlite3odbc.c:8172
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...
Definition: sqlite3odbc.c:9968
static COL colPrivSpec3[]
Definition: sqlite3odbc.c:6315
#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:9557
SQLRETURN SQL_API SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SETSTMTOPTION_LAST_ARG_TYPE param)
Set option on HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9578
double s3dval
SQLite3 float value.
Definition: sqlite3odbc.h:222
static int drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp, int *ncolp, char **errp, int nparam, BINDPARM *p)
Definition: sqlite3odbc.c:1509
Internal structure for managing driver&#39;s sqlite3_get_table() implementation.
Definition: sqlite3odbc.c:1374
int pwdLen
Length of password.
Definition: sqlite3odbc.h:146
static void unbindcols(STMT *s)
Reset bound columns to unbound state.
static COL scolSpec2[]
Columns for result set of SQLSpecialColumns().
Definition: sqlite3odbc.c:6799
SQLRETURN SQL_API SQLGetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Get connect attribute of HDBC (UNICODE version).
int ncols
Number of result columns.
Definition: sqlite3odbc.h:240
#define WCHARSUPPORT
Definition: sqlite3odbc.c:185
SQLUSMALLINT * row_status
Row status pointer.
Definition: sqlite3odbc.h:266
SQLRETURN SQL_API SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *ncols)
Return number of columns of result set given HSTMT.
static COL pkeySpec3[]
Definition: sqlite3odbc.c:6404
static int busy_handler(void *udata, int count)
Busy callback for SQLite.
Definition: sqlite3odbc.c:2018
static char * uc_to_utf_c(SQLWCHAR *str, int len)
Make UTF8 string from UNICODE string.
Definition: sqlite3odbc.c:1028
#define SQLSETPOSIROW
Definition: sqlite3odbc.h:76
SQLCHAR cursorname[32]
Cursor name.
Definition: sqlite3odbc.h:234
static int str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
Convert string to ODBC TIMESTAMP_STRUCT.
Definition: sqlite3odbc.c:3332
static SQLRETURN starttran(STMT *s)
Start transaction when autocommit off.
Definition: sqlite3odbc.c:7878
static int s3stmt_step(STMT *s)
Do one sqlite statement step gathering one result row.
Definition: sqlite3odbc.c:4285
static COL tableSpec2[]
Columns for result set of SQLTables().
static SQLRETURN drvexecute(SQLHSTMT stmt, int initial)
struct stmt * next
Linkage for STMT list in DBC.
Definition: sqlite3odbc.h:232
static SQLRETURN drvbulkoperations(SQLHSTMT stmt, SQLSMALLINT op)
Internal perform bulk operation on HSTMT.
SQLRETURN SQL_API SQLSetPos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
Set position on result in HSTMT.
#define COLATTRIBUTE_LAST_ARG_TYPE
Definition: sqlite3odbc.c:216
char * bincache
Cache for blob data.
Definition: sqlite3odbc.h:288
static SQLRETURN setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp)
static COL procColSpec2[]
Columns for result set of SQLProcedureColumns().
Definition: sqlite3odbc.c:8245
static SQLRETURN drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER buflen)
Internal set option on HSTMT.
Definition: sqlite3odbc.c:9179
SQLINTEGER * bkmrkptr
SQL_ATTR_FETCH_BOOKMARK_PTR.
Definition: sqlite3odbc.h:245
int notnull
NOT NULL constraint on column.
Definition: sqlite3odbc.h:175
int timeout
Lock timeout value.
Definition: sqlite3odbc.h:120
SQLULEN max_rows
SQL_ATTR_MAX_ROWS.
Definition: sqlite3odbc.h:274
int nalloc
alloc&#39;ed size of result array
Definition: sqlite3odbc.c:1379
static void dbtraceapi(DBC *d, char *fn, const char *sql)
Trace function for SQLite API calls.
Definition: sqlite3odbc.c:3853
SQLRETURN SQL_API SQLDriversW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *drvdesc, SQLSMALLINT descmax, SQLSMALLINT *desclenp, SQLWCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
Function not implemented.
Definition: sqlite3odbc.c:4713
int coldef
Definition: sqlite3odbc.h:205
static int getbool(char *string)
Get boolean flag from string.
Definition: sqlite3odbc.c:3664
SQLRETURN SQL_API SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Get option of HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9157
char * label
Column label or NULL.
Definition: sqlite3odbc.h:179
SQLRETURN SQL_API SQLFreeEnv(SQLHENV env)
Free HENV.
int type
Data type of column.
Definition: sqlite3odbc.h:168
SQLRETURN SQL_API SQLGetDescRecW(SQLHDESC handle, SQLSMALLINT recno, SQLWCHAR *name, SQLSMALLINT buflen, SQLSMALLINT *strlen, SQLSMALLINT *type, SQLSMALLINT *subtype, SQLLEN *len, SQLSMALLINT *prec, SQLSMALLINT *scale, SQLSMALLINT *nullable)
Function not implemented.
Definition: sqlite3odbc.c:5852
int nowchar[2]
Don&#39;t try to use WCHAR.
Definition: sqlite3odbc.h:261
static const char upper_chars[]
Definition: sqlite3odbc.c:546
int s3size
SQLite3 size.
Definition: sqlite3odbc.h:218
static SQLRETURN setupparam(STMT *s, char *sql, int pnum)
Setup SQLite3 parameter for statement parameter.
Definition: sqlite3odbc.c:5031
#define stringify(s)
Definition: sqlite3odbc.c:236
int binlen
Length of blob data.
Definition: sqlite3odbc.h:289
#define SCOL_VARCHAR
Definition: sqlite3odbc.c:255
SQLLEN * lenp0
Actual size of parameter buffer, initial value.
Definition: sqlite3odbc.h:208
int * oemcp
True for Win32 OEM CP translation.
Definition: sqlite3odbc.h:237
static SQLRETURN drvunimpldbc(HDBC dbc)
Report IM001 (not implemented) SQL error code for HDBC.
Definition: sqlite3odbc.c:1760
SQLUSMALLINT * row_status0
Internal status array.
Definition: sqlite3odbc.h:267
#define SCOL_CHAR
Definition: sqlite3odbc.c:256
static void s3stmt_end_if(STMT *s)
Conditionally stop running sqlite statement.
Definition: sqlite3odbc.c:4560
SQLRETURN SQL_API SQLStatisticsW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen, SQLUSMALLINT itype, SQLUSMALLINT resv)
Return statistic information on table indices (UNICODE version).
SQLINTEGER max
Max.
Definition: sqlite3odbc.h:190
static int setsqliteopts(sqlite3 *x, DBC *d)
Set SQLite options (PRAGMAs) given SQLite handle.
Definition: sqlite3odbc.c:2093
int nbindcols
Number of entries in bindcols.
Definition: sqlite3odbc.h:248
int isselect
0 if query is a SELECT statement
Definition: sqlite3odbc.h:239
SQLLEN * lenp
Actual size of parameter buffer.
Definition: sqlite3odbc.h:207
SQLRETURN SQL_API SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
Get option of HSTMT.
Definition: sqlite3odbc.c:9439
static SQLRETURN drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
Internal set option on HSTMT.
Definition: sqlite3odbc.c:9479
char * pwd
Password or NULL.
Definition: sqlite3odbc.h:145
Driver internal structure for environment (HENV).
Definition: sqlite3odbc.h:96
static SQLRETURN drvfreeenv(SQLHENV env)
Internal free HENV.
static char * strdup_(const char *str)
Duplicate string using xmalloc().
Definition: sqlite3odbc.c:616
FILE * trace
sqlite3_trace() file pointer or NULL
Definition: sqlite3odbc.h:144
Internal structure representing dynamic strings.
Definition: sqlite3odbc.c:272
static void freeresult(STMT *s, int clrcols)
Free statement&#39;s result.
SQLRETURN SQL_API SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER buflen)
Set option on HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9366
static void uc_from_utf_buf(unsigned char *str, int len, SQLWCHAR *uc, int ucLen)
Make UNICODE string from UTF8 string into buffer.
Definition: sqlite3odbc.c:848
sqlite3_stmt * stmt
SQLite3 statement pointer.
Definition: sqlite3odbc.c:1377
static void uc_free(void *str)
Free converted UTF8 or UNICODE string.
Definition: sqlite3odbc.c:1046
int autoinc
AUTO_INCREMENT column.
Definition: sqlite3odbc.h:174
SQLRETURN SQL_API SQLSetScrollOptions(SQLHSTMT stmt, SQLUSMALLINT concur, SQLLEN rowkeyset, SQLUSMALLINT rowset)
Function not implemented.
static SQLRETURN endtran(DBC *d, SQLSMALLINT comptype, int force)
Internal commit or rollback transaction.
Definition: sqlite3odbc.c:7921
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:4749
char * db
Database name.
Definition: sqlite3odbc.h:165
static const char * xdigits
Definition: sqlite3odbc.c:279
long t0
Start time for SQLITE busy handler.
Definition: sqlite3odbc.h:121
int naterr
Native error code.
Definition: sqlite3odbc.h:128
SQLRETURN SQL_API SQLGetDiagRecW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno, SQLWCHAR *sqlstate, SQLINTEGER *nativeerr, SQLWCHAR *msg, SQLSMALLINT buflen, SQLSMALLINT *msglen)
Get error message given handle (HENV, HDBC, or HSTMT) (UNICODE version).
Definition: sqlite3odbc.c:8631
char sqlstate[6]
SQL state for SQLError()
Definition: sqlite3odbc.h:129
int bound
True when SQLBindParameter() called.
Definition: sqlite3odbc.h:213
static void dbloadext(DBC *d, char *exts)
Load SQLite extension modules, if any.
Definition: sqlite3odbc.c:4111
static BOOL InUn(int remove, char *drivername, char *dllname, char *dll2name, char *dsname)
Driver installer/uninstaller.
Definition: inst.c:153
void * param
Parameter buffer.
Definition: sqlite3odbc.h:209
int one_tbl
Flag for single table (> 0)
Definition: sqlite3odbc.h:291
SQLRETURN SQL_API SQLGetData(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type, SQLPOINTER val, SQLLEN len, SQLLEN *lenp)
Retrieve row data after fetch.
void(* rowfree)()
Free function for rows.
Definition: sqlite3odbc.h:257
static int TOLOWER(int c)
Definition: sqlite3odbc.c:550
static COL tableSpec3[]
static SQLRETURN drvgetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Internal get connect attribute of HDBC.
int curtype
Cursor type.
Definition: sqlite3odbc.h:283
#define array_size(x)
Definition: sqlite3odbc.c:233
STMT * s
Driver statement pointer.
Definition: sqlite3odbc.c:1378
static COL colSpec2[]
Columns for result set of SQLColumns().
int ncol
number of columns in result array
Definition: sqlite3odbc.c:1381
int scale
from SQLBindParameter()
Definition: sqlite3odbc.h:205
COL * dyncols
Column array, but malloc()ed.
Definition: sqlite3odbc.h:242
int dobigint
Force SQL_BIGINT for INTEGER columns.
Definition: sqlite3odbc.h:132
SQLRETURN SQL_API SQLBindParameter(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype, SQLSMALLINT buftype, SQLSMALLINT ptype, SQLULEN coldef, SQLSMALLINT scale, SQLPOINTER data, SQLLEN buflen, SQLLEN *len)
Bind parameter on HSTMT.
Definition: sqlite3odbc.c:5513
int index
Index of column in result.
Definition: sqlite3odbc.h:170
int bkmrk
True when bookmarks used.
Definition: sqlite3odbc.h:244
SQLULEN * parm_proc
SQL_ATTR_PARAMS_PROCESSED_PTR.
Definition: sqlite3odbc.h:281
SQLULEN * bind_offs
SQL_ATTR_ROW_BIND_OFFSET_PTR.
Definition: sqlite3odbc.h:276
int magic
Magic cookie.
Definition: sqlite3odbc.h:113
static SQLRETURN getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype, SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp, int partial)
Internal function to retrieve row data, used by SQLFetch() and friends and SQLGetData().
static SQLRETURN setposrefr(STMT *s, int rsi)
Internal handler to refresh user buffers from driver side result set.
static int dserr(dstr *dsp)
Check error on dynamic string.
Definition: sqlite3odbc.c:773
static SQLRETURN drvconnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen, char *pwd, int pwdLen, int isu)
Internal connect to SQLite database.
static void convJD2YMD(double jd, DATE_STRUCT *ds)
Convert julian day to year/month/day.
Definition: sqlite3odbc.c:3005
static dstr * dsappendq(dstr *dsp, const char *str)
Append a string double quoted to dynamic string.
Definition: sqlite3odbc.c:690
SQLRETURN SQL_API SQLSetParam(SQLHSTMT stmt, SQLUSMALLINT par, SQLSMALLINT type, SQLSMALLINT sqltype, SQLULEN coldef, SQLSMALLINT scale, SQLPOINTER val, SQLLEN *nval)
Set information on parameter.
Definition: sqlite3odbc.c:5744
static COL colPrivSpec2[]
Columns for result set of SQLColumnPrivileges().
Definition: sqlite3odbc.c:6305
int size
Size of column.
Definition: sqlite3odbc.h:169
static COL scolSpec3[]
Definition: sqlite3odbc.c:6811
static SQLRETURN drvunimplstmt(HSTMT stmt)
Report IM001 (not implemented) SQL error code for HSTMT.
Definition: sqlite3odbc.c:1779
struct dstr dstr
SQLRETURN SQL_API SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
Set information in HENV.
Definition: sqlite3odbc.c:8434
static char * s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
Find out column type.
Definition: sqlite3odbc.c:4192
SQLRETURN SQL_API SQLDataSourcesW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *srvname, SQLSMALLINT buflen1, SQLSMALLINT *lenp1, SQLWCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
Function not implemented.
Definition: sqlite3odbc.c:4679
#define max(a, b)
Definition: sqlite3odbc.c:227
BINDCOL * bindcols
Array of bound columns.
Definition: sqlite3odbc.h:247
int rowp
Current result row.
Definition: sqlite3odbc.h:254
#define DRIVER_VER_INFO
Definition: sqlite3odbc.c:209
SQLRETURN SQL_API SQLGetDescFieldW(SQLHDESC handle, SQLSMALLINT recno, SQLSMALLINT fieldid, SQLPOINTER value, SQLINTEGER buflen, SQLINTEGER *strlen)
Function not implemented.
Definition: sqlite3odbc.c:5793
int ov3val
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:124
int scale
Scale of column.
Definition: sqlite3odbc.h:172
static void dsfree(dstr *dsp)
Free dynamic string.
Definition: sqlite3odbc.c:784
SQLRETURN SQL_API SQLAllocConnect(SQLHENV env, SQLHDBC *dbc)
Allocate HDBC.
static SQLRETURN freestmt(HSTMT stmt)
char * typename
Column type name or NULL.
Definition: sqlite3odbc.h:178
SQLUSMALLINT * parm_status
SQL_ATTR_PARAMS_STATUS_PTR.
Definition: sqlite3odbc.h:280
static SQLRETURN s3stmt_start(STMT *s)
Start sqlite statement for execution of SELECT statement.
Definition: sqlite3odbc.c:4599
int jdconv
True for julian day conversion.
Definition: sqlite3odbc.h:141
int has_rowid
Flag for ROWID (>= 0 or -1)
Definition: sqlite3odbc.h:293
BINDCOL bkmrkcol
Bookmark bound column.
Definition: sqlite3odbc.h:246
SQLULEN rowset_size
Size of rowset.
Definition: sqlite3odbc.h:265
static SQLRETURN drvstatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen, SQLUSMALLINT itype, SQLUSMALLINT resv)
Internal return statistic information on table indices.
#define ISSPACE(c)
Definition: sqlite3odbc.c:577
#define drvrelgpps(d)
Definition: sqlite3odbc.c:1292
static SQLRETURN drvcolattributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id, SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen, SQLLEN *val2)
Internal retrieve column attributes.
SQLRETURN SQL_API SQLNumParams(SQLHSTMT stmt, SQLSMALLINT *nparam)
Return number of parameters.
Definition: sqlite3odbc.c:5565
char strbuf[64]
String buffer for scalar data.
Definition: sqlite3odbc.h:216
static COL fkeySpec3[]
Definition: sqlite3odbc.c:7256
int oemcp
True for Win32 OEM CP translation.
Definition: sqlite3odbc.h:140
SQLRETURN SQL_API SQLGetTypeInfoW(SQLHSTMT stmt, SQLSMALLINT sqltype)
Return data type information (UNICODE version).
static SQLRETURN drvendtran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
Internal commit or rollback transaction.
Definition: sqlite3odbc.c:7980
char * bincell
Cache for blob data.
Definition: sqlite3odbc.h:287
int nparams
Number of parameters in query.
Definition: sqlite3odbc.h:251
static void setstat(STMT *s, int naterr, char *msg, char *st,...)
Set error message and SQL state on statement.
Definition: sqlite3odbc.c:1727
int stype
ODBC and SQL types.
Definition: sqlite3odbc.h:204
Internal structure for bound parameter (SQLBindParameter).
Definition: sqlite3odbc.h:203
static void s3stmt_drop(STMT *s)
Drop running sqlite statement in STMT.
Definition: sqlite3odbc.c:4578
int nbindparms
Number bound parameters.
Definition: sqlite3odbc.h:249
static COL typeSpec2[]
Columns for result set of SQLGetTypeInfo().
SQLRETURN SQL_API SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type, SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
Bind C variable to column of result set.
Internal structure to describe a column in a result set.
Definition: sqlite3odbc.h:164
char * errmsg
error message or NULL
Definition: sqlite3odbc.c:1376
SQLRETURN SQL_API SQLAllocStmt(SQLHDBC dbc, SQLHSTMT *stmt)
Allocate HSTMT given HDBC.
int has_pk
Flag for primary key (> 0)
Definition: sqlite3odbc.h:292
static SQLRETURN drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Internal get option of HSTMT.
Definition: sqlite3odbc.c:8984
static SQLRETURN dbopen(DBC *d, char *name, int isu, char *dsn, char *sflag, char *spflag, char *ntflag, char *jmode, char *busy)
Open SQLite database file given file name and flags.
Definition: sqlite3odbc.c:3897
static int uc_strlen(SQLWCHAR *str)
Return length of UNICODE string.
Definition: sqlite3odbc.c:800
int offs
Byte offset for SQLGetData()
Definition: sqlite3odbc.h:194
struct tblres TBLRES
SQLULEN paramset_count
Internal for paramset.
Definition: sqlite3odbc.h:272
int pdcount
SQLParamData() counter.
Definition: sqlite3odbc.h:252
struct stmt * stmt
STMT list of this DBC.
Definition: sqlite3odbc.h:127
#define HDBC_UNLOCK(hdbc)
Definition: sqlite3odbc.c:531
static SQLRETURN drvdescribecol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name, SQLSMALLINT nameMax, SQLSMALLINT *nameLen, SQLSMALLINT *type, SQLULEN *size, SQLSMALLINT *digits, SQLSMALLINT *nullable)
Internal describe column information.
static char * unquote(char *str)
Strip quotes from quoted string in-place.
Definition: sqlite3odbc.c:1880
static SQLRETURN drvbindcol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type, SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
Internal bind C variable to column of result set.
SQLRETURN SQL_API SQLAllocHandle(SQLSMALLINT type, SQLHANDLE input, SQLHANDLE *output)
Allocate a HENV, HDBC, or HSTMT handle.
static COL statSpec3[]
SQLRETURN SQL_API SQLColumnPrivilegesW(SQLHSTMT stmt, SQLWCHAR *catalog, SQLSMALLINT catalogLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen, SQLWCHAR *column, SQLSMALLINT columnLen)
Retrieve privileges on columns (UNICODE version).
Definition: sqlite3odbc.c:6374
static void convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
Convert julian day to hour/minute/second.
Definition: sqlite3odbc.c:3033
char ** resarr
result array
Definition: sqlite3odbc.c:1375
#define verinfo(maj, min, lev)
Definition: sqlite3odbc.c:238
int s3stmt_noreset
False when sqlite3_reset() needed.
Definition: sqlite3odbc.h:285
static void dbtracerc(DBC *d, int rc, char *err)
Trace function for SQLite return codes.
Definition: sqlite3odbc.c:3873
int trans_disable
True for no transaction support.
Definition: sqlite3odbc.h:139
static SQLRETURN drvspecialcolumns(SQLHSTMT stmt, SQLUSMALLINT id, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen, SQLUSMALLINT scope, SQLUSMALLINT nullable)
Internal retrieve information about indexed columns.
Definition: sqlite3odbc.c:6839
int len
Current length.
Definition: sqlite3odbc.c:273
#define DEAD_MAGIC
Definition: sqlite3odbc.c:264
static const char * dsval(dstr *dsp)
Return dynamic string&#39;s value.
Definition: sqlite3odbc.c:758
int dcols
Number of entries in dyncols.
Definition: sqlite3odbc.h:243
int s3type
SQLite3 type.
Definition: sqlite3odbc.h:217
static SQLRETURN drvbindparam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype, SQLSMALLINT buftype, SQLSMALLINT ptype, SQLUINTEGER coldef, SQLSMALLINT scale, SQLPOINTER data, SQLINTEGER buflen, SQLLEN *len)
Internal bind parameter on HSTMT.
Definition: sqlite3odbc.c:5374
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:8226
static char * fixupsql(char *sql, int sqlLen, int cte, int *nparam, int *isselect, char **errmsg)
Fixup query string with optional parameter markers.
Definition: sqlite3odbc.c:2524
SQLRETURN SQL_API SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
Function not implemented.
Definition: sqlite3odbc.c:5763
#define xmalloc(x)
Definition: sqlite3odbc.c:403
#define ODBC_INI
Definition: sqlite3odbc.c:205
#define xrealloc(x, y)
Definition: sqlite3odbc.c:404
#define HDBC_LOCK(hdbc)
Definition: sqlite3odbc.c:530
int naterr
Native error code.
Definition: sqlite3odbc.h:258
int len
Offset/length for SQLParamData()/SQLPutData()
Definition: sqlite3odbc.h:214
static SQLRETURN drvgetdiagrec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno, SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg, SQLSMALLINT buflen, SQLSMALLINT *msglen)
Internal get error message given handle (HENV, HDBC, or HSTMT).
Definition: sqlite3odbc.c:8500
Header file for SQLite3 ODBC driver.
int max
Maximum length of buffer.
Definition: sqlite3odbc.c:274
static int unescpat(char *str)
Unescape search pattern for e.g.
Definition: sqlite3odbc.c:1907

Generated on Mon May 4 2020 by doxygen.
Contact: chw@ch-werner.de