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 if (c < 0xfc) {
914  if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 &&
915  (str[3] & 0xc0) == 0x80 && (str[4] & 0xc0) == 0x80) {
916  unsigned long t = ((c & 0x01) << 24) |
917  ((str[1] & 0x3f) << 18) | ((str[2] & 0x3f) << 12) |
918  ((str[3] & 0x3f) << 6) | (str[4] & 0x3f);
919 
920  if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
921  t >= 0x10000) {
922  t -= 0x10000;
923  uc[i++] = 0xd800 | ((t >> 10) & 0x3ff);
924  if (i >= ucLen) {
925  break;
926  }
927  t = 0xdc00 | (t & 0x3ff);
928  }
929  uc[i++] = t;
930  str += 5;
931  } else {
932  uc[i++] = c;
933  ++str;
934  }
935  } else {
936  /* ignore */
937  ++str;
938  }
939  }
940  if (i < ucLen) {
941  uc[i] = 0;
942  }
943  }
944 }
945 
953 static SQLWCHAR *
954 uc_from_utf(unsigned char *str, int len)
955 {
956  SQLWCHAR *uc = NULL;
957  int ucLen;
958 
959  if (str) {
960  if (len == SQL_NTS) {
961  len = strlen((char *) str);
962  }
963  ucLen = sizeof (SQLWCHAR) * (len + 1);
964  uc = xmalloc(ucLen);
965  if (uc) {
966  uc_from_utf_buf(str, len, uc, ucLen);
967  }
968  }
969  return uc;
970 }
971 
979 static char *
980 uc_to_utf(SQLWCHAR *str, int len)
981 {
982  int i;
983  char *cp, *ret = NULL;
984 
985  if (!str) {
986  return ret;
987  }
988  if (len == SQL_NTS) {
989  len = uc_strlen(str);
990  } else {
991  len = len / sizeof (SQLWCHAR);
992  }
993  cp = xmalloc(len * 6 + 1);
994  if (!cp) {
995  return ret;
996  }
997  ret = cp;
998  for (i = 0; i < len; i++) {
999  unsigned long c = str[i];
1000 
1001  if (sizeof (SQLWCHAR) == 2 * sizeof (char)) {
1002  c &= 0xffff;
1003  }
1004  if (c < 0x80) {
1005  *cp++ = c;
1006  } else if (c < 0x800) {
1007  *cp++ = 0xc0 | ((c >> 6) & 0x1f);
1008  *cp++ = 0x80 | (c & 0x3f);
1009  } else if (c < 0x10000) {
1010  if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
1011  c >= 0xd800 && c <= 0xdbff && i + 1 < len) {
1012  unsigned long c2 = str[i + 1] & 0xffff;
1013 
1014  if (c2 >= 0xdc00 && c2 <= 0xdfff) {
1015  c = (((c & 0x3ff) << 10) | (c2 & 0x3ff)) + 0x10000;
1016  *cp++ = 0xf0 | ((c >> 18) & 0x07);
1017  *cp++ = 0x80 | ((c >> 12) & 0x3f);
1018  *cp++ = 0x80 | ((c >> 6) & 0x3f);
1019  *cp++ = 0x80 | (c & 0x3f);
1020  ++i;
1021  continue;
1022  }
1023  }
1024  *cp++ = 0xe0 | ((c >> 12) & 0x0f);
1025  *cp++ = 0x80 | ((c >> 6) & 0x3f);
1026  *cp++ = 0x80 | (c & 0x3f);
1027  } else if (c < 0x200000) {
1028  *cp++ = 0xf0 | ((c >> 18) & 0x07);
1029  *cp++ = 0x80 | ((c >> 12) & 0x3f);
1030  *cp++ = 0x80 | ((c >> 6) & 0x3f);
1031  *cp++ = 0x80 | (c & 0x3f);
1032  } else if (c < 0x4000000) {
1033  *cp++ = 0xf8 | ((c >> 24) & 0x03);
1034  *cp++ = 0x80 | ((c >> 18) & 0x3f);
1035  *cp++ = 0x80 | ((c >> 12) & 0x3f);
1036  *cp++ = 0x80 | ((c >> 6) & 0x3f);
1037  *cp++ = 0x80 | (c & 0x3f);
1038  } else if (c < 0x80000000) {
1039  *cp++ = 0xfc | ((c >> 31) & 0x01);
1040  *cp++ = 0x80 | ((c >> 24) & 0x3f);
1041  *cp++ = 0x80 | ((c >> 18) & 0x3f);
1042  *cp++ = 0x80 | ((c >> 12) & 0x3f);
1043  *cp++ = 0x80 | ((c >> 6) & 0x3f);
1044  *cp++ = 0x80 | (c & 0x3f);
1045  }
1046  }
1047  *cp = '\0';
1048  return ret;
1049 }
1050 
1051 #endif
1052 
1053 #ifdef WINTERFACE
1054 
1062 static char *
1063 uc_to_utf_c(SQLWCHAR *str, int len)
1064 {
1065  if (len != SQL_NTS) {
1066  len = len * sizeof (SQLWCHAR);
1067  }
1068  return uc_to_utf(str, len);
1069 }
1070 
1071 #endif
1072 
1073 #if defined(WCHARSUPPORT) || defined(_WIN32) || defined(_WIN64)
1074 
1080 static void
1081 uc_free(void *str)
1082 {
1083  if (str) {
1084  xfree(str);
1085  }
1086 }
1087 
1088 #endif
1089 
1090 #if defined(_WIN32) || defined(_WIN64)
1091 
1099 static char *
1100 wmb_to_utf(char *str, int len)
1101 {
1102  WCHAR *wstr;
1103  OSVERSIONINFO ovi;
1104  int nchar, is2k, cp = CP_OEMCP;
1105 
1106  ovi.dwOSVersionInfoSize = sizeof (ovi);
1107  GetVersionEx(&ovi);
1108  is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1109  if (AreFileApisANSI()) {
1110  cp = is2k ? CP_THREAD_ACP : CP_ACP;
1111  }
1112  nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
1113  wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
1114  if (!wstr) {
1115  return NULL;
1116  }
1117  wstr[0] = 0;
1118  nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
1119  wstr[nchar] = 0;
1120  str = xmalloc((nchar + 1) * 7);
1121  if (!str) {
1122  xfree(wstr);
1123  return NULL;
1124  }
1125  str[0] = '\0';
1126  nchar = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, nchar * 7, 0, 0);
1127  str[nchar] = '\0';
1128  xfree(wstr);
1129  return str;
1130 }
1131 
1132 #ifndef WINTERFACE
1133 
1141 static char *
1142 wmb_to_utf_c(char *str, int len)
1143 {
1144  if (len == SQL_NTS) {
1145  len = strlen(str);
1146  }
1147  return wmb_to_utf(str, len);
1148 }
1149 
1150 #endif
1151 
1159 static char *
1160 utf_to_wmb(char *str, int len)
1161 {
1162  WCHAR *wstr;
1163  OSVERSIONINFO ovi;
1164  int nchar, is2k, cp = CP_OEMCP;
1165 
1166  ovi.dwOSVersionInfoSize = sizeof (ovi);
1167  GetVersionEx(&ovi);
1168  is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1169  if (AreFileApisANSI()) {
1170  cp = is2k ? CP_THREAD_ACP : CP_ACP;
1171  }
1172  nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
1173  wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
1174  if (!wstr) {
1175  return NULL;
1176  }
1177  wstr[0] = 0;
1178  nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, wstr, nchar);
1179  wstr[nchar] = 0;
1180  str = xmalloc((nchar + 1) * 7);
1181  if (!str) {
1182  xfree(wstr);
1183  return NULL;
1184  }
1185  str[0] = '\0';
1186  nchar = WideCharToMultiByte(cp, 0, wstr, -1, str, nchar * 7, 0, 0);
1187  str[nchar] = '\0';
1188  xfree(wstr);
1189  return str;
1190 }
1191 
1192 #ifdef WINTERFACE
1193 
1201 static WCHAR *
1202 wmb_to_uc(char *str, int len)
1203 {
1204  WCHAR *wstr;
1205  OSVERSIONINFO ovi;
1206  int nchar, is2k, cp = CP_OEMCP;
1207 
1208  ovi.dwOSVersionInfoSize = sizeof (ovi);
1209  GetVersionEx(&ovi);
1210  is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1211  if (AreFileApisANSI()) {
1212  cp = is2k ? CP_THREAD_ACP : CP_ACP;
1213  }
1214  nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
1215  wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
1216  if (!wstr) {
1217  return NULL;
1218  }
1219  wstr[0] = 0;
1220  nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
1221  wstr[nchar] = 0;
1222  return wstr;
1223 }
1224 
1232 static char *
1233 uc_to_wmb(WCHAR *wstr, int len)
1234 {
1235  char *str;
1236  OSVERSIONINFO ovi;
1237  int nchar, is2k, cp = CP_OEMCP;
1238 
1239  ovi.dwOSVersionInfoSize = sizeof (ovi);
1240  GetVersionEx(&ovi);
1241  is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1242  if (AreFileApisANSI()) {
1243  cp = is2k ? CP_THREAD_ACP : CP_ACP;
1244  }
1245  nchar = WideCharToMultiByte(cp, 0, wstr, len, NULL, 0, 0, 0);
1246  str = xmalloc((nchar + 1) * 2);
1247  if (!str) {
1248  return NULL;
1249  }
1250  str[0] = '\0';
1251  nchar = WideCharToMultiByte(cp, 0, wstr, len, str, nchar * 2, 0, 0);
1252  str[nchar] = '\0';
1253  return str;
1254 }
1255 
1256 #endif /* WINTERFACE */
1257 
1258 #endif /* _WIN32 || _WIN64 */
1259 
1260 
1261 #ifdef USE_DLOPEN_FOR_GPPS
1262 
1263 #include <dlfcn.h>
1264 
1265 #define SQLGetPrivateProfileString(A,B,C,D,E,F) drvgpps(d,A,B,C,D,E,F)
1266 
1267 /*
1268  * EXPERIMENTAL: SQLGetPrivateProfileString infrastructure using
1269  * dlopen(), in theory this makes the driver independent from the
1270  * driver manager, i.e. the same driver binary can run with iODBC
1271  * and unixODBC.
1272  */
1273 
1274 static void
1275 drvgetgpps(DBC *d)
1276 {
1277  void *lib;
1278  int (*gpps)();
1279 
1280  lib = dlopen("libodbcinst.so.2", RTLD_LAZY);
1281  if (!lib) {
1282  lib = dlopen("libodbcinst.so.1", RTLD_LAZY);
1283  }
1284  if (!lib) {
1285  lib = dlopen("libodbcinst.so", RTLD_LAZY);
1286  }
1287  if (!lib) {
1288  lib = dlopen("libiodbcinst.so.2", RTLD_LAZY);
1289  }
1290  if (!lib) {
1291  lib = dlopen("libiodbcinst.so", RTLD_LAZY);
1292  }
1293  if (lib) {
1294  gpps = (int (*)()) dlsym(lib, "SQLGetPrivateProfileString");
1295  if (!gpps) {
1296  dlclose(lib);
1297  return;
1298  }
1299  d->instlib = lib;
1300  d->gpps = gpps;
1301  }
1302 }
1303 
1304 static void
1305 drvrelgpps(DBC *d)
1306 {
1307  if (d->instlib) {
1308  dlclose(d->instlib);
1309  d->instlib = 0;
1310  }
1311 }
1312 
1313 static int
1314 drvgpps(DBC *d, char *sect, char *ent, char *def, char *buf,
1315  int bufsiz, char *fname)
1316 {
1317  if (d->gpps) {
1318  return d->gpps(sect, ent, def, buf, bufsiz, fname);
1319  }
1320  strncpy(buf, def, bufsiz);
1321  buf[bufsiz - 1] = '\0';
1322  return 1;
1323 }
1324 #else
1325 #include <odbcinst.h>
1326 #define drvgetgpps(d)
1327 #define drvrelgpps(d)
1328 #endif
1329 
1330 /*
1331  * Internal function to bind SQLite3 parameters.
1332  */
1333 
1334 static void
1335 s3bind(DBC *d, sqlite3_stmt *stmt, int nparams, BINDPARM *p)
1336 {
1337  int i;
1338 
1339  if (stmt && p && nparams > 0) {
1340  for (i = 0; i < nparams; i++, p++) {
1341  switch (p->s3type) {
1342  default:
1343  case SQLITE_NULL:
1344  sqlite3_bind_null(stmt, i + 1);
1345  if (d->trace) {
1346  fprintf(d->trace, "-- parameter %d: NULL\n", i + 1);
1347  fflush(d->trace);
1348  }
1349  break;
1350  case SQLITE_TEXT:
1351  sqlite3_bind_text(stmt, i + 1, p->s3val, p->s3size,
1352  SQLITE_STATIC);
1353  if (d->trace) {
1354  fprintf(d->trace, "-- parameter %d: '%*s'\n", i + 1,
1355  p->s3size, (char *) p->s3val);
1356  fflush(d->trace);
1357  }
1358  break;
1359  case SQLITE_BLOB:
1360  sqlite3_bind_blob(stmt, i + 1, p->s3val, p->s3size,
1361  SQLITE_STATIC);
1362  if (d->trace) {
1363  fprintf(d->trace, "-- parameter %d: [BLOB]'\n", i + 1);
1364  fflush(d->trace);
1365  }
1366  break;
1367  case SQLITE_FLOAT:
1368  sqlite3_bind_double(stmt, i + 1, p->s3dval);
1369  if (d->trace) {
1370  fprintf(d->trace, "-- parameter %d: %g\n",
1371  i + 1, p->s3dval);
1372  fflush(d->trace);
1373  }
1374  break;
1375  case SQLITE_INTEGER:
1376  if (p->s3size > sizeof (int)) {
1377  sqlite3_bind_int64(stmt, i + 1, p->s3lival);
1378  if (d->trace) {
1379  fprintf(d->trace,
1380 #ifdef _WIN32
1381  "-- parameter %d: %I64d\n",
1382 #else
1383  "-- parameter %d: %lld\n",
1384 #endif
1385  i + 1, p->s3lival);
1386  fflush(d->trace);
1387  }
1388  } else {
1389  sqlite3_bind_int(stmt, i + 1, p->s3ival);
1390  if (d->trace) {
1391  fprintf(d->trace, "-- parameter %d: %d\n",
1392  i + 1, p->s3ival);
1393  fflush(d->trace);
1394  }
1395  }
1396  break;
1397  }
1398  }
1399  }
1400 }
1401 
1409 typedef struct tblres {
1410  char **resarr;
1411  char *errmsg;
1412  sqlite3_stmt *stmt;
1413  STMT *s;
1414  int nalloc;
1415  int nrow;
1416  int ncol;
1418  int rc;
1419 } TBLRES;
1420 
1421 /*
1422  * Driver's version of sqlite3_get_table() and friends which are
1423  * capable of dealing with blobs.
1424  */
1425 
1426 static int
1427 drvgettable_row(TBLRES *t, int ncol, int rc)
1428 {
1429  int need;
1430  int i;
1431  char *p;
1432 
1433  if (t->nrow == 0 && rc == SQLITE_ROW) {
1434  need = ncol * 2;
1435  } else {
1436  need = ncol;
1437  }
1438  if (t->ndata + need >= t->nalloc) {
1439  char **resnew;
1440  int nalloc = t->nalloc * 2 + need + 1;
1441 
1442  resnew = xrealloc(t->resarr, sizeof (char *) * nalloc);
1443  if (!resnew) {
1444 nomem:
1445  t->rc = SQLITE_NOMEM;
1446  return 1;
1447  }
1448  t->nalloc = nalloc;
1449  t->resarr = resnew;
1450  }
1451  /* column names when first row */
1452  if (t->nrow == 0) {
1453  t->ncol = ncol;
1454  for (i = 0; i < ncol; i++) {
1455  p = (char *) sqlite3_column_name(t->stmt, i);
1456  if (p) {
1457  char *q = xmalloc(strlen(p) + 1);
1458 
1459  if (!q) {
1460  goto nomem;
1461  }
1462  strcpy(q, p);
1463  p = q;
1464  }
1465  t->resarr[t->ndata++] = p;
1466  }
1467  if (t->s && t->s->guessed_types) {
1468  int ncol2 = ncol;
1469 
1470  setupdyncols(t->s, t->stmt, &ncol2);
1471  t->s->guessed_types = 0;
1472  t->s->ncols = ncol;
1473  }
1474  } else if (t->ncol != ncol) {
1475  t->errmsg = sqlite3_mprintf("drvgettable() called with two or"
1476  " more incompatible queries");
1477  t->rc = SQLITE_ERROR;
1478  return 1;
1479  }
1480  /* copy row data */
1481  if (rc == SQLITE_ROW) {
1482  for (i = 0; i < ncol; i++) {
1483  int coltype = sqlite3_column_type(t->stmt, i);
1484 
1485  p = NULL;
1486  if (coltype == SQLITE_BLOB) {
1487  int k, nbytes = sqlite3_column_bytes(t->stmt, i);
1488  char *qp;
1489  unsigned const char *bp;
1490 
1491  bp = sqlite3_column_blob(t->stmt, i);
1492  qp = xmalloc(nbytes * 2 + 4);
1493  if (!qp) {
1494  goto nomem;
1495  }
1496  p = qp;
1497  *qp++ = 'X';
1498  *qp++ = '\'';
1499  for (k = 0; k < nbytes; k++) {
1500  *qp++ = xdigits[(bp[k] >> 4)];
1501  *qp++ = xdigits[(bp[k] & 0xF)];
1502  }
1503  *qp++ = '\'';
1504  *qp = '\0';
1505 #ifdef _MSC_VER
1506  } else if (coltype == SQLITE_FLOAT) {
1507  struct lconv *lc = 0;
1508  double val = sqlite3_column_double(t->stmt, i);
1509  char buffer[128];
1510 
1511  /*
1512  * This avoids floating point rounding
1513  * and formatting problems of some SQLite
1514  * versions in conjunction with MSVC 2010.
1515  */
1516  snprintf(buffer, sizeof (buffer), "%.15g", val);
1517  lc = localeconv();
1518  if (lc && lc->decimal_point && lc->decimal_point[0] &&
1519  lc->decimal_point[0] != '.') {
1520  p = strchr(buffer, lc->decimal_point[0]);
1521  if (p) {
1522  *p = '.';
1523  }
1524  }
1525  p = xstrdup(buffer);
1526  if (!p) {
1527  goto nomem;
1528  }
1529 #endif
1530  } else if (coltype != SQLITE_NULL) {
1531  p = xstrdup((char *) sqlite3_column_text(t->stmt, i));
1532  if (!p) {
1533  goto nomem;
1534  }
1535  }
1536  t->resarr[t->ndata++] = p;
1537  }
1538  t->nrow++;
1539  }
1540  return 0;
1541 }
1542 
1543 static int
1544 drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp,
1545  int *ncolp, char **errp, int nparam, BINDPARM *p)
1546 {
1547  DBC *d = (DBC *) s->dbc;
1548  int rc = SQLITE_OK, keep = sql == NULL;
1549  TBLRES tres;
1550  const char *sqlleft = 0;
1551  int nretry = 0, haveerr = 0;
1552 
1553  if (!resp) {
1554  return SQLITE_ERROR;
1555  }
1556  *resp = NULL;
1557  if (nrowp) {
1558  *nrowp = 0;
1559  }
1560  if (ncolp) {
1561  *ncolp = 0;
1562  }
1563  tres.errmsg = NULL;
1564  tres.nrow = 0;
1565  tres.ncol = 0;
1566  tres.ndata = 1;
1567  tres.nalloc = 20;
1568  tres.rc = SQLITE_OK;
1569  tres.resarr = xmalloc(sizeof (char *) * tres.nalloc);
1570  tres.stmt = NULL;
1571  tres.s = s;
1572  if (!tres.resarr) {
1573  return SQLITE_NOMEM;
1574  }
1575  tres.resarr[0] = 0;
1576  if (sql == NULL) {
1577  tres.stmt = s->s3stmt;
1578  if (tres.stmt == NULL) {
1579  return SQLITE_NOMEM;
1580  }
1581  goto retrieve;
1582  }
1583  while (sql && *sql && (rc == SQLITE_OK ||
1584  (rc == SQLITE_SCHEMA && (++nretry) < 2))) {
1585  int ncol;
1586 
1587  tres.stmt = NULL;
1588 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
1589  dbtraceapi(d, "sqlite3_prepare_v2", sql);
1590  rc = sqlite3_prepare_v2(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
1591 #else
1592  dbtraceapi(d, "sqlite3_prepare", sql);
1593  rc = sqlite3_prepare(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
1594 #endif
1595  if (rc != SQLITE_OK) {
1596  if (tres.stmt) {
1597  dbtraceapi(d, "sqlite3_finalize", 0);
1598  sqlite3_finalize(tres.stmt);
1599  tres.stmt = NULL;
1600  }
1601  continue;
1602  }
1603  if (!tres.stmt) {
1604  /* this happens for a comment or white-space */
1605  sql = sqlleft;
1606  continue;
1607  }
1608 retrieve:
1609  if (sqlite3_bind_parameter_count(tres.stmt) != nparam) {
1610  if (errp) {
1611  *errp =
1612  sqlite3_mprintf("%s", "parameter marker count incorrect");
1613  }
1614  haveerr = 1;
1615  rc = SQLITE_ERROR;
1616  goto tbldone;
1617  }
1618  s3bind(d, tres.stmt, nparam, p);
1619  ncol = sqlite3_column_count(tres.stmt);
1620  while (1) {
1621  if (s->max_rows && tres.nrow >= s->max_rows) {
1622  rc = SQLITE_OK;
1623  break;
1624  }
1625  rc = sqlite3_step(tres.stmt);
1626  if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
1627  if (drvgettable_row(&tres, ncol, rc)) {
1628  rc = SQLITE_ABORT;
1629  goto tbldone;
1630  }
1631  }
1632  if (rc != SQLITE_ROW) {
1633  if (keep) {
1634  dbtraceapi(d, "sqlite3_reset", 0);
1635  rc = sqlite3_reset(tres.stmt);
1636  s->s3stmt_noreset = 1;
1637  } else {
1638  dbtraceapi(d, "sqlite3_finalize", 0);
1639  rc = sqlite3_finalize(tres.stmt);
1640  }
1641  tres.stmt = 0;
1642  if (rc != SQLITE_SCHEMA) {
1643  nretry = 0;
1644  sql = sqlleft;
1645  while (sql && ISSPACE(*sql)) {
1646  sql++;
1647  }
1648  }
1649  if (rc == SQLITE_DONE) {
1650  rc = SQLITE_OK;
1651  }
1652  break;
1653  }
1654  }
1655  }
1656 tbldone:
1657  if (tres.stmt) {
1658  if (keep) {
1659  if (!s->s3stmt_noreset) {
1660  dbtraceapi(d, "sqlite3_reset", 0);
1661  sqlite3_reset(tres.stmt);
1662  s->s3stmt_noreset = 1;
1663  }
1664  } else {
1665  dbtraceapi(d, "sqlite3_finalize", 0);
1666  sqlite3_finalize(tres.stmt);
1667  }
1668  }
1669  if (haveerr) {
1670  /* message already in *errp if any */
1671  } else if (rc != SQLITE_OK && rc == sqlite3_errcode(d->sqlite) && errp) {
1672  *errp = sqlite3_mprintf("%s", sqlite3_errmsg(d->sqlite));
1673  } else if (errp) {
1674  *errp = NULL;
1675  }
1676  if (tres.resarr) {
1677  tres.resarr[0] = (char *) (tres.ndata - 1);
1678  }
1679  if (rc == SQLITE_ABORT) {
1680  freerows(&tres.resarr[1]);
1681  if (tres.errmsg) {
1682  if (errp) {
1683  if (*errp) {
1684  sqlite3_free(*errp);
1685  }
1686  *errp = tres.errmsg;
1687  } else {
1688  sqlite3_free(tres.errmsg);
1689  }
1690  }
1691  return tres.rc;
1692  }
1693  sqlite3_free(tres.errmsg);
1694  if (rc != SQLITE_OK) {
1695  freerows(&tres.resarr[1]);
1696  return rc;
1697  }
1698  *resp = &tres.resarr[1];
1699  if (ncolp) {
1700  *ncolp = tres.ncol;
1701  }
1702  if (nrowp) {
1703  *nrowp = tres.nrow;
1704  }
1705  return rc;
1706 }
1707 
1716 #if defined(__GNUC__) && (__GNUC__ >= 2)
1717 static void setstatd(DBC *, int, char *, char *, ...)
1718  __attribute__((format (printf, 3, 5)));
1719 #endif
1720 
1721 static void
1722 setstatd(DBC *d, int naterr, char *msg, char *st, ...)
1723 {
1724  va_list ap;
1725 
1726  if (!d) {
1727  return;
1728  }
1729  d->naterr = naterr;
1730  d->logmsg[0] = '\0';
1731  if (msg) {
1732  int count;
1733 
1734  va_start(ap, st);
1735  count = vsnprintf((char *) d->logmsg, sizeof (d->logmsg), msg, ap);
1736  va_end(ap);
1737  if (count < 0) {
1738  d->logmsg[sizeof (d->logmsg) - 1] = '\0';
1739  }
1740  }
1741  if (!st) {
1742  st = "?????";
1743  }
1744  strncpy(d->sqlstate, st, 5);
1745  d->sqlstate[5] = '\0';
1746 }
1747 
1756 #if defined(__GNUC__) && (__GNUC__ >= 2)
1757 static void setstat(STMT *, int, char *, char *, ...)
1758  __attribute__((format (printf, 3, 5)));
1759 #endif
1760 
1761 static void
1762 setstat(STMT *s, int naterr, char *msg, char *st, ...)
1763 {
1764  va_list ap;
1765 
1766  if (!s) {
1767  return;
1768  }
1769  s->naterr = naterr;
1770  s->logmsg[0] = '\0';
1771  if (msg) {
1772  int count;
1773 
1774  va_start(ap, st);
1775  count = vsnprintf((char *) s->logmsg, sizeof (s->logmsg), msg, ap);
1776  va_end(ap);
1777  if (count < 0) {
1778  s->logmsg[sizeof (s->logmsg) - 1] = '\0';
1779  }
1780  }
1781  if (!st) {
1782  st = "?????";
1783  }
1784  strncpy(s->sqlstate, st, 5);
1785  s->sqlstate[5] = '\0';
1786 }
1787 
1794 static SQLRETURN
1796 {
1797  DBC *d;
1798 
1799  if (dbc == SQL_NULL_HDBC) {
1800  return SQL_INVALID_HANDLE;
1801  }
1802  d = (DBC *) dbc;
1803  setstatd(d, -1, "not supported", "IM001");
1804  return SQL_ERROR;
1805 }
1806 
1813 static SQLRETURN
1815 {
1816  STMT *s;
1817 
1818  if (stmt == SQL_NULL_HSTMT) {
1819  return SQL_INVALID_HANDLE;
1820  }
1821  s = (STMT *) stmt;
1822  setstat(s, -1, "not supported", "IM001");
1823  return SQL_ERROR;
1824 }
1825 
1831 static void
1832 freep(void *x)
1833 {
1834  if (x && ((char **) x)[0]) {
1835  xfree(((char **) x)[0]);
1836  ((char **) x)[0] = NULL;
1837  }
1838 }
1839 
1846 static SQLRETURN
1848 {
1849  setstat(s, -1, "out of memory", (*s->ov3) ? "HY000" : "S1000");
1850  return SQL_ERROR;
1851 }
1852 
1859 static SQLRETURN
1861 {
1862  setstat(s, -1, "not connected", (*s->ov3) ? "HY000" : "S1000");
1863  return SQL_ERROR;
1864 }
1865 
1873 #if defined(HAVE_LOCALECONV) || defined(_WIN32) || defined(_WIN64)
1874 
1875 static double
1876 ln_strtod(const char *data, char **endp)
1877 {
1878  struct lconv *lc = 0;
1879  char buf[128], *p, *end;
1880  double value;
1881 
1882  lc = localeconv();
1883  if (lc && lc->decimal_point && lc->decimal_point[0] &&
1884  lc->decimal_point[0] != '.') {
1885  strncpy(buf, data, sizeof (buf) - 1);
1886  buf[sizeof (buf) - 1] = '\0';
1887  p = strchr(buf, '.');
1888  if (p) {
1889  *p = lc->decimal_point[0];
1890  }
1891  p = buf;
1892  } else {
1893  p = (char *) data;
1894  }
1895  value = strtod(p, &end);
1896  end = (char *) data + (end - p);
1897  if (endp) {
1898  *endp = end;
1899  }
1900  return value;
1901 }
1902 
1903 #else
1904 
1905 #define ln_strtod(A,B) strtod(A,B)
1906 
1907 #endif
1908 
1914 static char *
1915 unquote(char *str)
1916 {
1917  if (str) {
1918  int len = strlen(str);
1919 
1920  if (len > 1) {
1921  int end = len - 1;
1922 
1923  if ((str[0] == '\'' && str[end] == '\'') ||
1924  (str[0] == '"' && str[end] == '"') ||
1925  (str[0] == '[' && str[end] == ']')) {
1926  memmove(str, str + 1, end - 1);
1927  str[end - 1] = '\0';
1928  }
1929  }
1930  }
1931  return str;
1932 }
1933 
1941 static int
1942 unescpat(char *str)
1943 {
1944  char *p, *q;
1945  int count = 0;
1946 
1947  p = str;
1948  while ((q = strchr(p, '_')) != NULL) {
1949  if (q == str || q[-1] != '\\') {
1950  count++;
1951  }
1952  p = q + 1;
1953  }
1954  p = str;
1955  while ((q = strchr(p, '%')) != NULL) {
1956  if (q == str || q[-1] != '\\') {
1957  count++;
1958  }
1959  p = q + 1;
1960  }
1961  p = str;
1962  while ((q = strchr(p, '\\')) != NULL) {
1963  if (q[1] == '\\' || q[1] == '_' || q[1] == '%') {
1964  memmove(q, q + 1, strlen(q));
1965  }
1966  p = q + 1;
1967  }
1968  return count;
1969 }
1970 
1979 static int
1980 namematch(char *str, char *pat, int esc)
1981 {
1982  int cp, ch;
1983 
1984  while (1) {
1985  cp = TOLOWER(*pat);
1986  if (cp == '\0') {
1987  if (*str != '\0') {
1988  goto nomatch;
1989  }
1990  break;
1991  }
1992  if (*str == '\0' && cp != '%') {
1993  goto nomatch;
1994  }
1995  if (cp == '%') {
1996  while (*pat == '%') {
1997  ++pat;
1998  }
1999  cp = TOLOWER(*pat);
2000  if (cp == '\0') {
2001  break;
2002  }
2003  while (1) {
2004  if (cp != '_' && cp != '\\') {
2005  while (*str) {
2006  ch = TOLOWER(*str);
2007  if (ch == cp) {
2008  break;
2009  }
2010  ++str;
2011  }
2012  }
2013  if (namematch(str, pat, esc)) {
2014  goto match;
2015  }
2016  if (*str == '\0') {
2017  goto nomatch;
2018  }
2019  ch = TOLOWER(*str);
2020  ++str;
2021  }
2022  }
2023  if (cp == '_') {
2024  pat++;
2025  str++;
2026  continue;
2027  }
2028  if (esc && cp == '\\' &&
2029  (pat[1] == '\\' || pat[1] == '%' || pat[1] == '_')) {
2030  ++pat;
2031  cp = TOLOWER(*pat);
2032  }
2033  ch = TOLOWER(*str++);
2034  ++pat;
2035  if (ch != cp) {
2036  goto nomatch;
2037  }
2038  }
2039 match:
2040  return 1;
2041 nomatch:
2042  return 0;
2043 }
2044 
2052 static int
2053 busy_handler(void *udata, int count)
2054 {
2055  DBC *d = (DBC *) udata;
2056  long t1;
2057  int ret = 0;
2058 #if !defined(_WIN32) && !defined(_WIN64)
2059  struct timeval tv;
2060 #ifdef HAVE_NANOSLEEP
2061  struct timespec ts;
2062 #endif
2063 #endif
2064 
2065  if (d->busyint) {
2066  d->busyint = 0;
2067  return ret;
2068  }
2069  if (d->timeout <= 0) {
2070  return ret;
2071  }
2072  if (count <= 1) {
2073 #if defined(_WIN32) || defined(_WIN64)
2074  d->t0 = GetTickCount();
2075 #else
2076  gettimeofday(&tv, NULL);
2077  d->t0 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
2078 #endif
2079  }
2080 #if defined(_WIN32) || defined(_WIN64)
2081  t1 = GetTickCount();
2082 #else
2083  gettimeofday(&tv, NULL);
2084  t1 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
2085 #endif
2086  if (t1 - d->t0 > d->timeout) {
2087  goto done;
2088  }
2089 #if defined(_WIN32) || defined(_WIN64)
2090  Sleep(10);
2091 #else
2092 #ifdef HAVE_NANOSLEEP
2093  ts.tv_sec = 0;
2094  ts.tv_nsec = 10000000;
2095  do {
2096  ret = nanosleep(&ts, &ts);
2097  if (ret < 0 && errno != EINTR) {
2098  ret = 0;
2099  }
2100  } while (ret);
2101 #else
2102 #ifdef HAVE_USLEEP
2103  usleep(10000);
2104 #else
2105  tv.tv_sec = 0;
2106  tv.tv_usec = 10000;
2107  select(0, NULL, NULL, NULL, &tv);
2108 #endif
2109 #endif
2110 #endif
2111  ret = 1;
2112 done:
2113  return ret;
2114 }
2115 
2127 static int
2128 setsqliteopts(sqlite3 *x, DBC *d)
2129 {
2130  int count = 0, step = 0, max, rc = SQLITE_ERROR;
2131 
2132 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
2133  max = d->longnames ? 3 : 1;
2134 #else
2135  max = 3;
2136 #endif
2137  if (d->shortnames) {
2138  max = 3;
2139  }
2140  while (step < max) {
2141  if (step < 1) {
2142  rc = sqlite3_exec(x, "PRAGMA empty_result_callbacks = on;",
2143  NULL, NULL, NULL);
2144  if (rc == SQLITE_OK) {
2145  rc = sqlite3_exec(x, d->fksupport ?
2146  "PRAGMA foreign_keys = on;" :
2147  "PRAGMA foreign_keys = off;",
2148  NULL, NULL, NULL);
2149  }
2150  } else if (step < 2) {
2151  rc = sqlite3_exec(x, d->shortnames ?
2152  "PRAGMA full_column_names = off;" :
2153  "PRAGMA full_column_names = on;",
2154  NULL, NULL, NULL);
2155  } else if (step < 3) {
2156  rc = sqlite3_exec(x, d->shortnames ?
2157  "PRAGMA short_column_names = on;" :
2158  "PRAGMA short_column_names = off;",
2159  NULL, NULL, NULL);
2160  }
2161  if (rc != SQLITE_OK) {
2162  if (rc != SQLITE_BUSY ||
2163  !busy_handler((void *) d, ++count)) {
2164  return rc;
2165  }
2166  continue;
2167  }
2168  count = 0;
2169  ++step;
2170  }
2171  sqlite3_busy_handler(x, busy_handler, (void *) d);
2172  return SQLITE_OK;
2173 }
2174 
2184 static void
2185 freerows(char **rowp)
2186 {
2187  PTRDIFF_T size, i;
2188 
2189  if (!rowp) {
2190  return;
2191  }
2192  --rowp;
2193  size = (PTRDIFF_T) rowp[0];
2194  for (i = 1; i <= size; i++) {
2195  freep(&rowp[i]);
2196  }
2197  freep(&rowp);
2198 }
2199 
2210 static int
2211 mapsqltype(const char *typename, int *nosign, int ov3, int nowchar,
2212  int dobigint)
2213 {
2214  char *p, *q;
2215  int testsign = 0, result;
2216 
2217 #ifdef WINTERFACE
2218  result = nowchar ? SQL_VARCHAR : SQL_WVARCHAR;
2219 #else
2220  result = SQL_VARCHAR;
2221 #endif
2222  if (!typename) {
2223  return result;
2224  }
2225  q = p = xmalloc(strlen(typename) + 1);
2226  if (!p) {
2227  return result;
2228  }
2229  strcpy(p, typename);
2230  while (*q) {
2231  *q = TOLOWER(*q);
2232  ++q;
2233  }
2234  if (strncmp(p, "inter", 5) == 0) {
2235  } else if (strncmp(p, "int", 3) == 0 ||
2236  strncmp(p, "mediumint", 9) == 0) {
2237  testsign = 1;
2238  result = SQL_INTEGER;
2239  } else if (strncmp(p, "numeric", 7) == 0) {
2240  result = SQL_DOUBLE;
2241  } else if (strncmp(p, "tinyint", 7) == 0) {
2242  testsign = 1;
2243  result = SQL_TINYINT;
2244  } else if (strncmp(p, "smallint", 8) == 0) {
2245  testsign = 1;
2246  result = SQL_SMALLINT;
2247  } else if (strncmp(p, "float", 5) == 0) {
2248  result = SQL_DOUBLE;
2249  } else if (strncmp(p, "double", 6) == 0 ||
2250  strncmp(p, "real", 4) == 0) {
2251  result = SQL_DOUBLE;
2252  } else if (strncmp(p, "timestamp", 9) == 0) {
2253 #ifdef SQL_TYPE_TIMESTAMP
2254  result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
2255 #else
2256  result = SQL_TIMESTAMP;
2257 #endif
2258  } else if (strncmp(p, "datetime", 8) == 0) {
2259 #ifdef SQL_TYPE_TIMESTAMP
2260  result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
2261 #else
2262  result = SQL_TIMESTAMP;
2263 #endif
2264  } else if (strncmp(p, "time", 4) == 0) {
2265 #ifdef SQL_TYPE_TIME
2266  result = ov3 ? SQL_TYPE_TIME : SQL_TIME;
2267 #else
2268  result = SQL_TIME;
2269 #endif
2270  } else if (strncmp(p, "date", 4) == 0) {
2271 #ifdef SQL_TYPE_DATE
2272  result = ov3 ? SQL_TYPE_DATE : SQL_DATE;
2273 #else
2274  result = SQL_DATE;
2275 #endif
2276 #ifdef SQL_LONGVARCHAR
2277  } else if (strncmp(p, "text", 4) == 0 ||
2278  strncmp(p, "memo", 4) == 0 ||
2279  strncmp(p, "longvarchar", 11) == 0) {
2280 #ifdef WINTERFACE
2281  result = nowchar ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
2282 #else
2283  result = SQL_LONGVARCHAR;
2284 #endif
2285 #ifdef WINTERFACE
2286  } else if (strncmp(p, "wtext", 5) == 0 ||
2287  strncmp(p, "wvarchar", 8) == 0 ||
2288  strncmp(p, "longwvarchar", 12) == 0) {
2289  result = SQL_WLONGVARCHAR;
2290 #endif
2291 #endif
2292 #ifdef SQL_BIT
2293  } else if (strncmp(p, "bool", 4) == 0 ||
2294  strncmp(p, "bit", 3) == 0) {
2295  result = SQL_BIT;
2296 #endif
2297 #ifdef SQL_BIGINT
2298  } else if (strncmp(p, "bigint", 6) == 0) {
2299  testsign = 1;
2300  result = SQL_BIGINT;
2301 #endif
2302  } else if (strncmp(p, "blob", 4) == 0) {
2303  result = SQL_BINARY;
2304  } else if (strncmp(p, "varbinary", 9) == 0) {
2305  result = SQL_VARBINARY;
2306  } else if (strncmp(p, "longvarbinary", 13) == 0) {
2307  result = SQL_LONGVARBINARY;
2308  }
2309  if (nosign) {
2310  if (testsign) {
2311  *nosign = strstr(p, "unsigned") != NULL;
2312  } else {
2313  *nosign = 1;
2314  }
2315  }
2316 #ifdef SQL_BIGINT
2317  if (dobigint && result == SQL_INTEGER) {
2318  result = SQL_BIGINT;
2319  }
2320 #endif
2321  xfree(p);
2322  return result;
2323 }
2324 
2334 static void
2335 getmd(const char *typename, int sqltype, int *mp, int *dp)
2336 {
2337  int m = 0, d = 0;
2338 
2339  switch (sqltype) {
2340  case SQL_INTEGER: m = 10; d = 9; break;
2341  case SQL_TINYINT: m = 4; d = 3; break;
2342  case SQL_SMALLINT: m = 6; d = 5; break;
2343  case SQL_FLOAT: m = 25; d = 24; break;
2344  case SQL_DOUBLE: m = 54; d = 53; break;
2345  case SQL_VARCHAR: m = 255; d = 0; break;
2346 #ifdef WINTERFACE
2347 #ifdef SQL_WVARCHAR
2348  case SQL_WVARCHAR: m = 255; d = 0; break;
2349 #endif
2350 #endif
2351 #ifdef SQL_TYPE_DATE
2352  case SQL_TYPE_DATE:
2353 #endif
2354  case SQL_DATE: m = 10; d = 0; break;
2355 #ifdef SQL_TYPE_TIME
2356  case SQL_TYPE_TIME:
2357 #endif
2358  case SQL_TIME: m = 8; d = 0; break;
2359 #ifdef SQL_TYPE_TIMESTAMP
2360  case SQL_TYPE_TIMESTAMP:
2361 #endif
2362  case SQL_TIMESTAMP: m = 32; d = 3; break;
2363 #ifdef SQL_LONGVARCHAR
2364  case SQL_LONGVARCHAR : m = 65536; d = 0; break;
2365 #endif
2366 #ifdef WINTERFACE
2367 #ifdef SQL_WLONGVARCHAR
2368  case SQL_WLONGVARCHAR: m = 65536; d = 0; break;
2369 #endif
2370 #endif
2371  case SQL_BINARY:
2372  case SQL_VARBINARY: m = 255; d = 0; break;
2373  case SQL_LONGVARBINARY: m = 65536; d = 0; break;
2374 #ifdef SQL_BIGINT
2375  case SQL_BIGINT: m = 20; d = 19; break;
2376 #endif
2377 #ifdef SQL_BIT
2378  case SQL_BIT: m = 1; d = 1; break;
2379 #endif
2380  }
2381  if (m && typename) {
2382  int mm, dd;
2383  char clbr[4];
2384 
2385  if (sscanf(typename, "%*[^(](%d,%d %1[)]", &mm, &dd, clbr) == 3) {
2386  m = mm;
2387  d = dd;
2388  } else if (sscanf(typename, "%*[^(](%d %1[)]", &mm, clbr) == 2) {
2389  if (sqltype == SQL_TIMESTAMP) {
2390  d = mm;
2391  }
2392 #ifdef SQL_TYPE_TIMESTAMP
2393  else if (sqltype == SQL_TYPE_TIMESTAMP) {
2394  d = mm;
2395  }
2396 #endif
2397  else {
2398  m = d = mm;
2399  }
2400  }
2401  }
2402  if (mp) {
2403  *mp = m;
2404  }
2405  if (dp) {
2406  *dp = d;
2407  }
2408 }
2409 
2419 static int
2420 mapdeftype(int type, int stype, int nosign, int nowchar)
2421 {
2422  if (type == SQL_C_DEFAULT) {
2423  switch (stype) {
2424  case SQL_INTEGER:
2425  type = (nosign > 0) ? SQL_C_ULONG : SQL_C_LONG;
2426  break;
2427  case SQL_TINYINT:
2428  type = (nosign > 0) ? SQL_C_UTINYINT : SQL_C_TINYINT;
2429  break;
2430  case SQL_SMALLINT:
2431  type = (nosign > 0) ? SQL_C_USHORT : SQL_C_SHORT;
2432  break;
2433  case SQL_FLOAT:
2434  type = SQL_C_FLOAT;
2435  break;
2436  case SQL_DOUBLE:
2437  type = SQL_C_DOUBLE;
2438  break;
2439  case SQL_TIMESTAMP:
2440  type = SQL_C_TIMESTAMP;
2441  break;
2442  case SQL_TIME:
2443  type = SQL_C_TIME;
2444  break;
2445  case SQL_DATE:
2446  type = SQL_C_DATE;
2447  break;
2448 #ifdef SQL_C_TYPE_TIMESTAMP
2449  case SQL_TYPE_TIMESTAMP:
2450  type = SQL_C_TYPE_TIMESTAMP;
2451  break;
2452 #endif
2453 #ifdef SQL_C_TYPE_TIME
2454  case SQL_TYPE_TIME:
2455  type = SQL_C_TYPE_TIME;
2456  break;
2457 #endif
2458 #ifdef SQL_C_TYPE_DATE
2459  case SQL_TYPE_DATE:
2460  type = SQL_C_TYPE_DATE;
2461  break;
2462 #endif
2463 #ifdef WINTERFACE
2464  case SQL_WVARCHAR:
2465  case SQL_WCHAR:
2466 #ifdef SQL_WLONGVARCHAR
2467  case SQL_WLONGVARCHAR:
2468 #endif
2469  type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
2470  break;
2471 #endif
2472  case SQL_BINARY:
2473  case SQL_VARBINARY:
2474  case SQL_LONGVARBINARY:
2475  type = SQL_C_BINARY;
2476  break;
2477 #ifdef SQL_BIT
2478  case SQL_BIT:
2479  type = SQL_C_BIT;
2480  break;
2481 #endif
2482 #ifdef SQL_BIGINT
2483  case SQL_BIGINT:
2484  type = SQL_C_CHAR;
2485  break;
2486 #endif
2487  default:
2488 #ifdef WINTERFACE
2489  type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
2490 #else
2491  type = SQL_C_CHAR;
2492 #endif
2493  break;
2494  }
2495  }
2496  return type;
2497 }
2498 
2510 static char *
2511 fixupsql(char *sql, int sqlLen, int cte, int *nparam, int *isselect,
2512  char **errmsg)
2513 {
2514  char *q = sql, *qz = NULL, *p, *inq = NULL, *out;
2515  int np = 0, isddl = -1, size;
2516 
2517  if (errmsg) {
2518  *errmsg = NULL;
2519  }
2520  if (sqlLen != SQL_NTS) {
2521  qz = q = xmalloc(sqlLen + 1);
2522  if (!qz) {
2523  return NULL;
2524  }
2525  memcpy(q, sql, sqlLen);
2526  q[sqlLen] = '\0';
2527  size = sqlLen * 4;
2528  } else {
2529  size = strlen(sql) * 4;
2530  }
2531  size += sizeof (char *) - 1;
2532  size &= ~(sizeof (char *) - 1);
2533  p = xmalloc(size);
2534  if (!p) {
2535 errout:
2536  freep(&qz);
2537  return NULL;
2538  }
2539  memset(p, 0, size);
2540  out = p;
2541  while (*q) {
2542  switch (*q) {
2543  case '\'':
2544  case '\"':
2545  if (q == inq) {
2546  inq = NULL;
2547  } else if (!inq) {
2548  inq = q + 1;
2549 
2550  while (*inq) {
2551  if (*inq == *q) {
2552  if (inq[1] == *q) {
2553  inq++;
2554  } else {
2555  break;
2556  }
2557  }
2558  inq++;
2559  }
2560  }
2561  *p++ = *q;
2562  break;
2563  case '?':
2564  *p++ = *q;
2565  if (!inq) {
2566  np++;
2567  }
2568  break;
2569  case ';':
2570  if (!inq) {
2571  if (isddl < 0) {
2572  char *qq = out;
2573 
2574  while (*qq && ISSPACE(*qq)) {
2575  ++qq;
2576  }
2577  if (*qq && *qq != ';') {
2578  int i;
2579  static const struct {
2580  int len;
2581  const char *str;
2582  } ddlstr[] = {
2583  { 5, "alter" },
2584  { 7, "analyze" },
2585  { 6, "attach" },
2586  { 5, "begin" },
2587  { 6, "commit" },
2588  { 6, "create" },
2589  { 6, "detach" },
2590  { 4, "drop" },
2591  { 3, "end" },
2592  { 7, "reindex" },
2593  { 7, "release" },
2594  { 8, "rollback" },
2595  { 9, "savepoint" },
2596  { 6, "vacuum" }
2597  };
2598 
2599  size = strlen(qq);
2600  for (i = 0; i < array_size(ddlstr); i++) {
2601  if (size >= ddlstr[i].len &&
2602  strncasecmp(qq, ddlstr[i].str, ddlstr[i].len)
2603  == 0) {
2604  isddl = 1;
2605  break;
2606  }
2607  }
2608  if (isddl != 1) {
2609  isddl = 0;
2610  }
2611  }
2612  }
2613  if (isddl == 0) {
2614  char *qq = q;
2615 
2616  do {
2617  ++qq;
2618  } while (*qq && ISSPACE(*qq));
2619  if (*qq && *qq != ';') {
2620  freep(&out);
2621  if (errmsg) {
2622  *errmsg = "only one SQL statement allowed";
2623  }
2624  goto errout;
2625  }
2626  }
2627  }
2628  *p++ = *q;
2629  break;
2630  case '{':
2631  /*
2632  * Deal with escape sequences:
2633  * {d 'YYYY-MM-DD'}, {t ...}, {ts ...}
2634  * {oj ...}, {fn ...} etc.
2635  */
2636  if (!inq) {
2637  int ojfn = 0, brc = 0;
2638  char *inq2 = NULL, *end = q + 1, *start;
2639 
2640  while (*end && ISSPACE(*end)) {
2641  ++end;
2642  }
2643  if (*end != 'd' && *end != 'D' &&
2644  *end != 't' && *end != 'T') {
2645  ojfn = 1;
2646  }
2647  start = end;
2648  while (*end) {
2649  if (inq2 && *end == *inq2) {
2650  inq2 = NULL;
2651  } else if (inq2 == NULL && *end == '{') {
2652  char *nerr = 0, *nsql;
2653 
2654  nsql = fixupsql(end, SQL_NTS, cte, 0, 0, &nerr);
2655  if (nsql && !nerr) {
2656  strcpy(end, nsql);
2657  } else {
2658  brc++;
2659  }
2660  freep(&nsql);
2661  } else if (inq2 == NULL && *end == '}') {
2662  if (brc-- <= 0) {
2663  break;
2664  }
2665  } else if (inq2 == NULL && (*end == '\'' || *end == '"')) {
2666  inq2 = end;
2667  } else if (inq2 == NULL && *end == '?') {
2668  np++;
2669  }
2670  ++end;
2671  }
2672  if (*end == '}') {
2673  char *end2 = end - 1;
2674 
2675  if (ojfn) {
2676  while (start < end) {
2677  if (ISSPACE(*start)) {
2678  break;
2679  }
2680  ++start;
2681  }
2682  while (start < end) {
2683  *p++ = *start;
2684  ++start;
2685  }
2686  q = end;
2687  break;
2688  } else {
2689  while (start < end2 && *start != '\'') {
2690  ++start;
2691  }
2692  while (end2 > start && *end2 != '\'') {
2693  --end2;
2694  }
2695  if (*start == '\'' && *end2 == '\'') {
2696  while (start <= end2) {
2697  *p++ = *start;
2698  ++start;
2699  }
2700  q = end;
2701  break;
2702  }
2703  }
2704  }
2705  }
2706  /* FALL THROUGH */
2707  default:
2708  *p++ = *q;
2709  }
2710  ++q;
2711  }
2712  freep(&qz);
2713  *p = '\0';
2714  if (nparam) {
2715  *nparam = np;
2716  }
2717  if (isselect) {
2718  if (isddl > 0) {
2719  *isselect = 2;
2720  } else {
2721  int incom = 0;
2722 
2723  p = out;
2724  while (*p) {
2725  switch (*p) {
2726  case '-':
2727  if (!incom && p[1] == '-') {
2728  incom = -1;
2729  }
2730  break;
2731  case '\n':
2732  if (incom < 0) {
2733  incom = 0;
2734  }
2735  break;
2736  case '/':
2737  if (incom > 0 && p[-1] == '*') {
2738  incom = 0;
2739  p++;
2740  continue;
2741  } else if (!incom && p[1] == '*') {
2742  incom = 1;
2743  }
2744  break;
2745  }
2746  if (!incom && !ISSPACE(*p)) {
2747  break;
2748  }
2749  p++;
2750  }
2751  size = strlen(p);
2752  if (size >= 6 &&
2753  (strncasecmp(p, "select", 6) == 0 ||
2754  strncasecmp(p, "pragma", 6) == 0)) {
2755  *isselect = 1;
2756  } else if (cte && size >= 4 && strncasecmp(p, "with", 4) == 0) {
2757  *isselect = 1;
2758  } else if (size >= 7 && strncasecmp(p, "explain", 7) == 0) {
2759  *isselect = 1;
2760  } else {
2761  *isselect = 0;
2762  }
2763  }
2764  }
2765  return out;
2766 }
2767 
2776 static int
2777 findcol(char **cols, int ncols, char *name)
2778 {
2779  int i;
2780 
2781  if (cols) {
2782  for (i = 0; i < ncols; i++) {
2783  if (strcmp(cols[i], name) == 0) {
2784  return i;
2785  }
2786  }
2787  }
2788  return -1;
2789 }
2790 
2807 static void
2809 {
2810  int i, k;
2811 #ifndef FULL_METADATA
2812  int pk, nn, t, r, nrows, ncols;
2813  char **rowp, *flagp, flags[128];
2814 #endif
2815 
2816  if (!s->dyncols) {
2817  return;
2818  }
2819  /* fixup labels */
2820  if (!s->longnames) {
2821  if (s->dcols > 1) {
2822  char *table = s->dyncols[0].table;
2823 
2824  for (i = 1; table[0] && i < s->dcols; i++) {
2825  if (strcmp(s->dyncols[i].table, table)) {
2826  break;
2827  }
2828  }
2829  if (i >= s->dcols) {
2830  for (i = 0; i < s->dcols; i++) {
2831  s->dyncols[i].label = s->dyncols[i].column;
2832  }
2833  }
2834  } else if (s->dcols == 1) {
2835  s->dyncols[0].label = s->dyncols[0].column;
2836  }
2837  }
2838  for (i = 0; i < s->dcols; i++) {
2839  s->dyncols[i].type =
2840  mapsqltype(s->dyncols[i].typename, &s->dyncols[i].nosign, *s->ov3,
2841  s->nowchar[0] || s->nowchar[1], s->dobigint);
2842  getmd(s->dyncols[i].typename, s->dyncols[i].type,
2843  &s->dyncols[i].size, &s->dyncols[i].prec);
2844 #ifdef SQL_LONGVARCHAR
2845  if (s->dyncols[i].type == SQL_VARCHAR &&
2846  s->dyncols[i].size > 255) {
2847  s->dyncols[i].type = SQL_LONGVARCHAR;
2848  }
2849 #endif
2850 #ifdef WINTERFACE
2851 #ifdef SQL_WLONGVARCHAR
2852  if (s->dyncols[i].type == SQL_WVARCHAR &&
2853  s->dyncols[i].size > 255) {
2854  s->dyncols[i].type = SQL_WLONGVARCHAR;
2855  }
2856 #endif
2857 #endif
2858  if (s->dyncols[i].type == SQL_VARBINARY &&
2859  s->dyncols[i].size > 255) {
2860  s->dyncols[i].type = SQL_LONGVARBINARY;
2861  }
2862  }
2863 #ifndef FULL_METADATA
2864  if (s->dcols > array_size(flags)) {
2865  flagp = xmalloc(sizeof (flags[0]) * s->dcols);
2866  if (flagp == NULL) {
2867  return;
2868  }
2869  } else {
2870  flagp = flags;
2871  }
2872  memset(flagp, 0, sizeof (flags[0]) * s->dcols);
2873  for (i = 0; i < s->dcols; i++) {
2874  s->dyncols[i].autoinc = SQL_FALSE;
2875  s->dyncols[i].notnull = SQL_NULLABLE;
2876  }
2877  for (i = 0; i < s->dcols; i++) {
2878  int ret, lastpk = -1, autoinccount = 0;
2879  char *sql;
2880 
2881  if (!s->dyncols[i].table[0]) {
2882  continue;
2883  }
2884  if (flagp[i]) {
2885  continue;
2886  }
2887  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", s->dyncols[i].table);
2888  if (!sql) {
2889  continue;
2890  }
2891  dbtraceapi(d, "sqlite3_get_table", sql);
2892  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, NULL);
2893  sqlite3_free(sql);
2894  if (ret != SQLITE_OK) {
2895  continue;
2896  }
2897  k = findcol(rowp, ncols, "name");
2898  t = findcol(rowp, ncols, "type");
2899  pk = findcol(rowp, ncols, "pk");
2900  nn = findcol(rowp, ncols, "notnull");
2901  if (k < 0 || t < 0) {
2902  goto freet;
2903  }
2904  for (r = 1; r <= nrows; r++) {
2905  int m;
2906 
2907  for (m = i; m < s->dcols; m++) {
2908  char *colname = s->dyncols[m].column;
2909 
2910  if (s->longnames) {
2911  char *dotp = strchr(colname, '.');
2912 
2913  if (dotp) {
2914  colname = dotp + 1;
2915  }
2916  }
2917  if (!flagp[m] &&
2918  strcmp(colname, rowp[r * ncols + k]) == 0 &&
2919  strcmp(s->dyncols[m].table, s->dyncols[i].table) == 0) {
2920  char *typename = rowp[r * ncols + t];
2921 
2922  flagp[m] = i + 1;
2923  freep(&s->dyncols[m].typename);
2924  s->dyncols[m].typename = xstrdup(typename);
2925  s->dyncols[m].type =
2926  mapsqltype(typename, &s->dyncols[m].nosign, *s->ov3,
2927  s->nowchar[0] || s->nowchar[1],
2928  s->dobigint);
2929  getmd(typename, s->dyncols[m].type, &s->dyncols[m].size,
2930  &s->dyncols[m].prec);
2931 #ifdef SQL_LONGVARCHAR
2932  if (s->dyncols[m].type == SQL_VARCHAR &&
2933  s->dyncols[m].size > 255) {
2934  s->dyncols[m].type = SQL_LONGVARCHAR;
2935  }
2936 #endif
2937 #ifdef WINTERFACE
2938 #ifdef SQL_WLONGVARCHAR
2939  if (s->dyncols[i].type == SQL_WVARCHAR &&
2940  s->dyncols[i].size > 255) {
2941  s->dyncols[i].type = SQL_WLONGVARCHAR;
2942  }
2943 #endif
2944 #endif
2945  if (s->dyncols[i].type == SQL_VARBINARY &&
2946  s->dyncols[i].size > 255) {
2947  s->dyncols[i].type = SQL_LONGVARBINARY;
2948  }
2949  if (pk >= 0 && strcmp(rowp[r * ncols + pk], "1") == 0) {
2950  s->dyncols[m].ispk = 1;
2951  if (++autoinccount > 1) {
2952  if (lastpk >= 0) {
2953  s->dyncols[lastpk].autoinc = SQL_FALSE;
2954  lastpk = -1;
2955  }
2956  } else {
2957  lastpk = m;
2958  if (strlen(typename) == 7 &&
2959  strncasecmp(typename, "integer", 7) == 0) {
2960  s->dyncols[m].autoinc = SQL_TRUE;
2961  }
2962  }
2963  } else {
2964  s->dyncols[m].ispk = 0;
2965  }
2966  if (nn >= 0 && rowp[r * ncols + nn][0] != '0') {
2967  s->dyncols[m].notnull = SQL_NO_NULLS;
2968  }
2969  }
2970  }
2971  }
2972 freet:
2973  sqlite3_free_table(rowp);
2974  }
2975  for (i = k = 0; i < s->dcols; i++) {
2976  if (flagp[i] == 0) {
2977  break;
2978  }
2979  if (k == 0) {
2980  k = flagp[i];
2981  } else if (flagp[i] != k) {
2982  k = 0;
2983  break;
2984  }
2985  }
2986  s->one_tbl = k ? 1 : 0;
2987  k = 0;
2988  if (s->one_tbl) {
2989  for (i = 0; i < s->dcols; i++) {
2990  if (s->dyncols[i].ispk > 0) {
2991  ++k;
2992  }
2993  }
2994  }
2995  s->has_pk = k;
2996  if (flagp != flags) {
2997  freep(&flagp);
2998  }
2999 #else
3000  for (i = 1, k = 0; i < s->dcols; i++) {
3001  if (strcmp(s->dyncols[i].table, s->dyncols[0].table) == 0) {
3002  k++;
3003  }
3004  }
3005  s->one_tbl = (k && k + 1 == s->dcols) ? 1 : 0;
3006  k = 0;
3007  if (s->one_tbl) {
3008  for (i = 0; i < s->dcols; i++) {
3009  if (s->dyncols[i].ispk > 0) {
3010  ++k;
3011  if (s->has_rowid < 0 && s->dyncols[i].isrowid > 0) {
3012  s->has_rowid = i;
3013  }
3014  }
3015  }
3016  }
3017  s->has_pk = k;
3018 #endif
3019 }
3020 
3027 static void
3028 convJD2YMD(double jd, DATE_STRUCT *ds)
3029 {
3030  int z, a, b, c, d, e, x1;
3031  sqlite_int64 ijd;
3032 
3033  ijd = jd * 86400000.0 + 0.5;
3034  z = (int) ((ijd + 43200000) / 86400000);
3035  a = (int) ((z - 1867216.25) / 36524.25);
3036  a = z + 1 + a - (a / 4);
3037  b = a + 1524;
3038  c = (int) ((b - 122.1) / 365.25);
3039  d = (36525 * c) / 100;
3040  e = (int) ((b - d) / 30.6001);
3041  x1 = (int) (30.6001 * e);
3042  ds->day = b - d - x1;
3043  ds->month = (e < 14) ? (e - 1) : (e - 13);
3044  ds->year = (ds->month > 2) ? (c - 4716) : (c - 4715);
3045 }
3046 
3047 
3055 static void
3056 convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
3057 {
3058  int s;
3059  double ds;
3060  sqlite_int64 ijd;
3061 
3062  ijd = jd * 86400000.0 + 0.5;
3063  s = (int)((ijd + 43200000) % 86400000);
3064  ds = s / 1000.0;
3065  if (fp) {
3066  *fp = (s % 1000) * 1000000;
3067  }
3068  s = (int) ds;
3069  ds -= s;
3070  ts->hour = s / 3600;
3071  s -= ts->hour * 3600;
3072  ts->minute = s / 60;
3073  ds += s - ts->minute *60;
3074  ts->second = (int) ds;
3075 }
3076 
3084 static int
3085 getmdays(int year, int month)
3086 {
3087  static const int mdays[] = {
3088  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
3089  };
3090  int mday;
3091 
3092  if (month < 1) {
3093  return 0;
3094  }
3095  mday = mdays[(month - 1) % 12];
3096  if (mday == 28 && year % 4 == 0 &&
3097  (!(year % 100 == 0) || year % 400 == 0)) {
3098  mday++;
3099  }
3100  return mday;
3101 }
3102 
3118 static int
3119 str2date(int jdconv, char *str, DATE_STRUCT *ds)
3120 {
3121  int i, err = 0;
3122  double jd;
3123  char *p, *q, sepc = '\0';
3124 
3125  ds->year = ds->month = ds->day = 0;
3126  if (jdconv) {
3127  p = strchr(str, '.');
3128  if (p) {
3129  /* julian day format */
3130  p = 0;
3131  jd = ln_strtod(str, &p);
3132  if (p && p > str) {
3133  convJD2YMD(jd, ds);
3134  return 0;
3135  }
3136  }
3137  }
3138  p = str;
3139  while (*p && !ISDIGIT(*p)) {
3140  ++p;
3141  }
3142  q = p;
3143  i = 0;
3144  while (*q && !ISDIGIT(*q)) {
3145  ++i;
3146  ++q;
3147  }
3148  if (i >= 8) {
3149  char buf[8];
3150 
3151  strncpy(buf, p + 0, 4); buf[4] = '\0';
3152  ds->year = strtol(buf, NULL, 10);
3153  strncpy(buf, p + 4, 2); buf[2] = '\0';
3154  ds->month = strtol(buf, NULL, 10);
3155  strncpy(buf, p + 6, 2); buf[2] = '\0';
3156  ds->day = strtol(buf, NULL, 10);
3157  goto done;
3158  }
3159  i = 0;
3160  while (i < 3) {
3161  int n;
3162 
3163  q = NULL;
3164  n = strtol(p, &q, 10);
3165  if (!q || q == p) {
3166  if (*q == '\0') {
3167  if (i == 0) {
3168  err = 1;
3169  }
3170  goto done;
3171  }
3172  }
3173  if (!sepc) {
3174  sepc = *q;
3175  }
3176  if (*q == '-' || *q == '/' || *q == '\0' || i == 2) {
3177  switch (i) {
3178  case 0: ds->year = n; break;
3179  case 1: ds->month = n; break;
3180  case 2: ds->day = n; break;
3181  }
3182  ++i;
3183  if (*q) {
3184  ++q;
3185  }
3186  } else {
3187  i = 0;
3188  while (*q && !ISDIGIT(*q)) {
3189  ++q;
3190  }
3191  }
3192  p = q;
3193  }
3194 done:
3195  /* final check for overflow */
3196  if (err ||
3197  ds->month < 1 || ds->month > 12 ||
3198  ds->day < 1 || ds->day > getmdays(ds->year, ds->month)) {
3199  if (sepc == '/') {
3200  /* Try MM/DD/YYYY format */
3201  int t[3];
3202 
3203  t[0] = ds->year;
3204  t[1] = ds->month;
3205  t[2] = ds->day;
3206  ds->year = t[2];
3207  ds->day = t[1];
3208  ds->month = t[0];
3209  if (ds->month >= 1 && ds->month <= 12 &&
3210  (ds->day >= 1 || ds->day <= getmdays(ds->year, ds->month))) {
3211  return 0;
3212  }
3213  }
3214  return -1;
3215  }
3216  return 0;
3217 }
3218 
3233 static int
3234 str2time(int jdconv, char *str, TIME_STRUCT *ts)
3235 {
3236  int i, err = 0, ampm = -1;
3237  double jd;
3238  char *p, *q;
3239 
3240  ts->hour = ts->minute = ts->second = 0;
3241  if (jdconv) {
3242  p = strchr(str, '.');
3243  if (p) {
3244  /* julian day format */
3245  p = 0;
3246  jd = ln_strtod(str, &p);
3247  if (p && p > str) {
3248  convJD2HMS(jd, ts, 0);
3249  return 0;
3250  }
3251  }
3252  }
3253  p = str;
3254  while (*p && !ISDIGIT(*p)) {
3255  ++p;
3256  }
3257  q = p;
3258  i = 0;
3259  while (*q && ISDIGIT(*q)) {
3260  ++i;
3261  ++q;
3262  }
3263  if (i >= 6) {
3264  char buf[4];
3265 
3266  strncpy(buf, p + 0, 2); buf[2] = '\0';
3267  ts->hour = strtol(buf, NULL, 10);
3268  strncpy(buf, p + 2, 2); buf[2] = '\0';
3269  ts->minute = strtol(buf, NULL, 10);
3270  strncpy(buf, p + 4, 2); buf[2] = '\0';
3271  ts->second = strtol(buf, NULL, 10);
3272  goto done;
3273  }
3274  i = 0;
3275  while (i < 3) {
3276  int n;
3277 
3278  q = NULL;
3279  n = strtol(p, &q, 10);
3280  if (!q || q == p) {
3281  if (*q == '\0') {
3282  if (i == 0) {
3283  err = 1;
3284  }
3285  goto done;
3286  }
3287  }
3288  if (*q == ':' || *q == '\0' || i == 2) {
3289  switch (i) {
3290  case 0: ts->hour = n; break;
3291  case 1: ts->minute = n; break;
3292  case 2: ts->second = n; break;
3293  }
3294  ++i;
3295  if (*q) {
3296  ++q;
3297  }
3298  } else {
3299  i = 0;
3300  while (*q && !ISDIGIT(*q)) {
3301  ++q;
3302  }
3303  }
3304  p = q;
3305  }
3306  if (!err) {
3307  while (*p) {
3308  if ((p[0] == 'p' || p[0] == 'P') &&
3309  (p[1] == 'm' || p[1] == 'M')) {
3310  ampm = 1;
3311  } else if ((p[0] == 'a' || p[0] == 'A') &&
3312  (p[1] == 'm' || p[1] == 'M')) {
3313  ampm = 0;
3314  }
3315  ++p;
3316  }
3317  if (ampm > 0) {
3318  if (ts->hour < 12) {
3319  ts->hour += 12;
3320  }
3321  } else if (ampm == 0) {
3322  if (ts->hour == 12) {
3323  ts->hour = 0;
3324  }
3325  }
3326  }
3327 done:
3328  /* final check for overflow */
3329  if (err || ts->hour > 23 || ts->minute > 59 || ts->second > 59) {
3330  return -1;
3331  }
3332  return 0;
3333 }
3334 
3354 static int
3355 str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
3356 {
3357  int i, m, n, err = 0, ampm = -1;
3358  double jd;
3359  char *p, *q, in = '\0', sepc = '\0';
3360 
3361  tss->year = tss->month = tss->day = 0;
3362  tss->hour = tss->minute = tss->second = 0;
3363  tss->fraction = 0;
3364  if (jdconv) {
3365  p = strchr(str, '.');
3366  if (p) {
3367  q = strchr(str, '-');
3368  if (q == str) {
3369  q = 0;
3370  }
3371  if (!q) {
3372  q = strchr(str, '/');
3373  if (!q) {
3374  q = strchr(str, ':');
3375  }
3376  }
3377  if (!q || q > p) {
3378  /* julian day format */
3379  p = 0;
3380  jd = ln_strtod(str, &p);
3381  if (p && p > str) {
3382  DATE_STRUCT ds;
3383  TIME_STRUCT ts;
3384 
3385  convJD2YMD(jd, &ds);
3386  convJD2HMS(jd, &ts, &n);
3387  tss->year = ds.year;
3388  tss->month = ds.month;
3389  tss->day = ds.day;
3390  tss->hour = ts.hour;
3391  tss->minute = ts.minute;
3392  tss->second = ts.second;
3393  tss->fraction = n;
3394  return 0;
3395  }
3396  }
3397  }
3398  }
3399  p = str;
3400  while (*p && !ISDIGIT(*p)) {
3401  ++p;
3402  }
3403  q = p;
3404  i = 0;
3405  while (*q && ISDIGIT(*q)) {
3406  ++i;
3407  ++q;
3408  }
3409  if (i >= 14) {
3410  char buf[16];
3411 
3412  strncpy(buf, p + 0, 4); buf[4] = '\0';
3413  tss->year = strtol(buf, NULL, 10);
3414  strncpy(buf, p + 4, 2); buf[2] = '\0';
3415  tss->month = strtol(buf, NULL, 10);
3416  strncpy(buf, p + 6, 2); buf[2] = '\0';
3417  tss->day = strtol(buf, NULL, 10);
3418  strncpy(buf, p + 8, 2); buf[2] = '\0';
3419  tss->hour = strtol(buf, NULL, 10);
3420  strncpy(buf, p + 10, 2); buf[2] = '\0';
3421  tss->minute = strtol(buf, NULL, 10);
3422  strncpy(buf, p + 12, 2); buf[2] = '\0';
3423  tss->second = strtol(buf, NULL, 10);
3424  if (i > 14) {
3425  m = i - 14;
3426  strncpy(buf, p + 14, m);
3427  while (m < 9) {
3428  buf[m] = '0';
3429  ++m;
3430  }
3431  buf[m] = '\0';
3432  tss->fraction = strtol(buf, NULL, 10);
3433  }
3434  m = 7;
3435  goto done;
3436  }
3437  m = i = 0;
3438  while ((m & 7) != 7) {
3439  q = NULL;
3440  n = strtol(p, &q, 10);
3441  if (!q || q == p) {
3442  if (*q == '\0') {
3443  if (m < 1) {
3444  err = 1;
3445  }
3446  goto done;
3447  }
3448  }
3449  if (in == '\0') {
3450  switch (*q) {
3451  case '-':
3452  case '/':
3453  if ((m & 1) == 0) {
3454  in = *q;
3455  i = 0;
3456  }
3457  break;
3458  case ':':
3459  if ((m & 2) == 0) {
3460  in = *q;
3461  i = 0;
3462  }
3463  break;
3464  case ' ':
3465  case '.':
3466  break;
3467  default:
3468  in = '\0';
3469  i = 0;
3470  break;
3471  }
3472  }
3473  switch (in) {
3474  case '-':
3475  case '/':
3476  if (!sepc) {
3477  sepc = in;
3478  }
3479  switch (i) {
3480  case 0: tss->year = n; break;
3481  case 1: tss->month = n; break;
3482  case 2: tss->day = n; break;
3483  }
3484  if (++i >= 3) {
3485  i = 0;
3486  m |= 1;
3487  if (!(m & 2)) {
3488  m |= 8;
3489  }
3490  goto skip;
3491  } else {
3492  ++q;
3493  }
3494  break;
3495  case ':':
3496  switch (i) {
3497  case 0: tss->hour = n; break;
3498  case 1: tss->minute = n; break;
3499  case 2: tss->second = n; break;
3500  }
3501  if (++i >= 3) {
3502  i = 0;
3503  m |= 2;
3504  if (*q == '.') {
3505  in = '.';
3506  goto skip2;
3507  }
3508  if (*q == ' ') {
3509  if ((m & 1) == 0) {
3510  char *e = NULL;
3511 
3512  (void) strtol(q + 1, &e, 10);
3513  if (e && *e == '-') {
3514  goto skip;
3515  }
3516  }
3517  in = '.';
3518  goto skip2;
3519  }
3520  goto skip;
3521  } else {
3522  ++q;
3523  }
3524  break;
3525  case '.':
3526  if (++i >= 1) {
3527  int ndig = q - p;
3528 
3529  if (p[0] == '+' || p[0] == '-') {
3530  ndig--;
3531  }
3532  while (ndig < 9) {
3533  n = n * 10;
3534  ++ndig;
3535  }
3536  tss->fraction = n;
3537  m |= 4;
3538  i = 0;
3539  }
3540  default:
3541  skip:
3542  in = '\0';
3543  skip2:
3544  while (*q && !ISDIGIT(*q)) {
3545  if ((q[0] == 'a' || q[0] == 'A') &&
3546  (q[1] == 'm' || q[1] == 'M')) {
3547  ampm = 0;
3548  ++q;
3549  } else if ((q[0] == 'p' || q[0] == 'P') &&
3550  (q[1] == 'm' || q[1] == 'M')) {
3551  ampm = 1;
3552  ++q;
3553  }
3554  ++q;
3555  }
3556  }
3557  p = q;
3558  }
3559  if ((m & 7) > 1 && (m & 8)) {
3560  /* ISO8601 timezone */
3561  if (p > str && ISDIGIT(*p)) {
3562  int nn, sign;
3563 
3564  q = p - 1;
3565  if (*q != '+' && *q != '-') {
3566  goto done;
3567  }
3568  sign = (*q == '+') ? -1 : 1;
3569  q = NULL;
3570  n = strtol(p, &q, 10);
3571  if (!q || *q++ != ':' || !ISDIGIT(*q)) {
3572  goto done;
3573  }
3574  p = q;
3575  q = NULL;
3576  nn = strtol(p, &q, 10);
3577  tss->minute += nn * sign;
3578  if ((SQLSMALLINT) tss->minute < 0) {
3579  tss->hour -= 1;
3580  tss->minute += 60;
3581  } else if (tss->minute >= 60) {
3582  tss->hour += 1;
3583  tss->minute -= 60;
3584  }
3585  tss->hour += n * sign;
3586  if ((SQLSMALLINT) tss->hour < 0) {
3587  tss->day -= 1;
3588  tss->hour += 24;
3589  } else if (tss->hour >= 24) {
3590  tss->day += 1;
3591  tss->hour -= 24;
3592  }
3593  if ((short) tss->day < 1 || tss->day >= 28) {
3594  int mday, pday, pmon;
3595 
3596  mday = getmdays(tss->year, tss->month);
3597  pmon = tss->month - 1;
3598  if (pmon < 1) {
3599  pmon = 12;
3600  }
3601  pday = getmdays(tss->year, pmon);
3602  if ((SQLSMALLINT) tss->day < 1) {
3603  tss->month -= 1;
3604  tss->day = pday;
3605  } else if (tss->day > mday) {
3606  tss->month += 1;
3607  tss->day = 1;
3608  }
3609  if ((SQLSMALLINT) tss->month < 1) {
3610  tss->year -= 1;
3611  tss->month = 12;
3612  } else if (tss->month > 12) {
3613  tss->year += 1;
3614  tss->month = 1;
3615  }
3616  }
3617  }
3618  }
3619 done:
3620  if ((m & 1) &&
3621  (tss->month < 1 || tss->month > 12 ||
3622  tss->day < 1 || tss->day > getmdays(tss->year, tss->month))) {
3623  if (sepc == '/') {
3624  /* Try MM/DD/YYYY format */
3625  int t[3];
3626 
3627  t[0] = tss->year;
3628  t[1] = tss->month;
3629  t[2] = tss->day;
3630  tss->year = t[2];
3631  tss->day = t[1];
3632  tss->month = t[0];
3633  }
3634  }
3635  /* Replace missing year/month/day with current date */
3636  if (!err && (m & 1) == 0) {
3637 #ifdef _WIN32
3638  SYSTEMTIME t;
3639 
3640  GetLocalTime(&t);
3641  tss->year = t.wYear;
3642  tss->month = t.wMonth;
3643  tss->day = t.wDay;
3644 #else
3645  struct timeval tv;
3646  struct tm tm;
3647 
3648  gettimeofday(&tv, NULL);
3649  tm = *localtime(&tv.tv_sec);
3650  tss->year = tm.tm_year + 1900;
3651  tss->month = tm.tm_mon + 1;
3652  tss->day = tm.tm_mday;
3653 #endif
3654  }
3655  /* Normalize fraction */
3656  if (tss->fraction < 0) {
3657  tss->fraction = 0;
3658  }
3659  /* Final check for overflow */
3660  if (err ||
3661  tss->month < 1 || tss->month > 12 ||
3662  tss->day < 1 || tss->day > getmdays(tss->year, tss->month) ||
3663  tss->hour > 23 || tss->minute > 59 || tss->second > 59) {
3664  return -1;
3665  }
3666  if ((m & 7) > 1) {
3667  if (ampm > 0) {
3668  if (tss->hour < 12) {
3669  tss->hour += 12;
3670  }
3671  } else if (ampm == 0) {
3672  if (tss->hour == 12) {
3673  tss->hour = 0;
3674  }
3675  }
3676  }
3677  return ((m & 7) < 1) ? -1 : 0;
3678 }
3679 
3686 static int
3687 getbool(char *string)
3688 {
3689  if (string) {
3690  return string[0] && strchr("Yy123456789Tt", string[0]) != NULL;
3691  }
3692  return 0;
3693 }
3694 
3702 static void
3703 blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
3704 {
3705 #if 0
3706  DBC *d = (DBC *) sqlite3_user_data(ctx);
3707 #endif
3708  char *filename = 0;
3709 
3710  if (nargs > 0) {
3711  if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
3712  filename = (char *) sqlite3_value_text(args[0]);
3713  }
3714  }
3715  if (filename) {
3716 #ifdef _WIN32
3717  char *wname = utf_to_wmb(filename, -1);
3718  FILE *f;
3719 #else
3720  FILE *f = fopen(filename, "r");
3721 #endif
3722  char *p;
3723  long n, nn;
3724 
3725 #ifdef _WIN32
3726  if (wname) {
3727  f = fopen(wname, "rb");
3728  } else {
3729  sqlite3_result_error(ctx, "out of memory", -1);
3730  return;
3731  }
3732  uc_free(wname);
3733 #endif
3734  if (f) {
3735  if (fseek(f, 0, SEEK_END) == 0) {
3736  n = ftell(f);
3737  if (fseek(f, 0, SEEK_SET) == 0) {
3738  p = sqlite3_malloc(n);
3739  if (p) {
3740  nn = fread(p, 1, n, f);
3741  if (nn != n) {
3742  sqlite3_result_error(ctx, "read error", -1);
3743  sqlite3_free(p);
3744  } else {
3745  sqlite3_result_blob(ctx, p, n, sqlite3_free);
3746  }
3747  } else {
3748  sqlite3_result_error(ctx, "out of memory", -1);
3749  }
3750  } else {
3751  sqlite3_result_error(ctx, "seek error", -1);
3752  }
3753  } else {
3754  sqlite3_result_error(ctx, "seek error", -1);
3755  }
3756  fclose(f);
3757  } else {
3758  sqlite3_result_error(ctx, "cannot open file", -1);
3759  }
3760  } else {
3761  sqlite3_result_error(ctx, "no filename given", -1);
3762  }
3763 }
3764 
3772 static void
3773 blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
3774 {
3775 #if 0
3776  DBC *d = (DBC *) sqlite3_user_data(ctx);
3777 #endif
3778  char *filename = 0;
3779  char *p = 0;
3780  int n = 0;
3781 
3782  if (nargs > 0) {
3783  p = (char *) sqlite3_value_blob(args[0]);
3784  n = sqlite3_value_bytes(args[0]);
3785  }
3786  if (nargs > 1) {
3787  if (sqlite3_value_type(args[1]) != SQLITE_NULL) {
3788  filename = (char *) sqlite3_value_text(args[1]);
3789  }
3790  }
3791  if (p) {
3792  if (filename) {
3793 #ifdef _WIN32
3794  char *wname = utf_to_wmb(filename, -1);
3795  FILE *f;
3796 #else
3797  FILE *f = fopen(filename, "w");
3798 #endif
3799  int nn;
3800 
3801 #ifdef _WIN32
3802  if (wname) {
3803  f = fopen(wname, "wb");
3804  } else {
3805  sqlite3_result_error(ctx, "out of memory", -1);
3806  return;
3807  }
3808  uc_free(wname);
3809 #endif
3810  if (f) {
3811  nn = fwrite(p, 1, n, f);
3812  fclose(f);
3813  if (nn != n) {
3814  sqlite3_result_error(ctx, "write error", -1);
3815  } else {
3816  sqlite3_result_int(ctx, nn);
3817  }
3818  } else {
3819  sqlite3_result_error(ctx, "cannot open file", -1);
3820  }
3821  } else {
3822  sqlite3_result_error(ctx, "no filename given", -1);
3823  }
3824  } else {
3825  sqlite3_result_null(ctx);
3826  }
3827 }
3828 
3836 static void
3837 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3838 dbtrace(void *arg, const char *msg, sqlite_uint64 et)
3839 #else
3840 dbtrace(void *arg, const char *msg)
3841 #endif
3842 {
3843  DBC *d = (DBC *) arg;
3844 
3845  if (msg && d->trace) {
3846  int len = strlen(msg);
3847 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3848  unsigned long s, f;
3849 #endif
3850 
3851  if (len > 0) {
3852  char *end = "\n";
3853 
3854  if (msg[len - 1] != ';') {
3855  end = ";\n";
3856  }
3857  fprintf(d->trace, "%s%s", msg, end);
3858 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3859  s = et / 1000000000LL;
3860  f = et % 1000000000LL;
3861  fprintf(d->trace, "-- took %lu.%09lu seconds\n", s, f);
3862 #endif
3863  fflush(d->trace);
3864  }
3865  }
3866 }
3867 
3875 static void
3876 dbtraceapi(DBC *d, char *fn, const char *sql)
3877 {
3878  if (fn && d->trace) {
3879  if (sql) {
3880  fprintf(d->trace, "-- %s: %s\n", fn, sql);
3881  } else {
3882  fprintf(d->trace, "-- %s\n", fn);
3883  }
3884  fflush(d->trace);
3885  }
3886 }
3887 
3895 static void
3896 dbtracerc(DBC *d, int rc, char *err)
3897 {
3898  if (rc != SQLITE_OK && d->trace) {
3899  fprintf(d->trace, "-- SQLITE ERROR CODE %d", rc);
3900  fprintf(d->trace, err ? ": %s\n" : "\n", err);
3901  fflush(d->trace);
3902  }
3903 }
3904 
3919 static SQLRETURN
3920 dbopen(DBC *d, char *name, int isu, char *dsn, char *sflag,
3921  char *spflag, char *ntflag, char *jmode, char *busy)
3922 {
3923  char *endp = NULL;
3924  int rc, tmp, busyto = 100000;
3925 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
3926  int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
3927  char *uname = name;
3928  const char *vfs_name = NULL;
3929 #endif
3930 
3931  if (d->sqlite) {
3932  if (d->trace) {
3933  fprintf(d->trace, "-- sqlite3_close (deferred): '%s'\n",
3934  d->dbname);
3935  fflush(d->trace);
3936  }
3937 #if defined(HAVE_SQLITE3CLOSEV2) && (HAVE_SQLITE3CLOSEV2)
3938  sqlite3_close_v2(d->sqlite);
3939 #else
3940  sqlite3_close(d->sqlite);
3941 #endif
3942  d->sqlite = NULL;
3943  }
3944 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
3945  if (d->nocreat) {
3946  flags &= ~ SQLITE_OPEN_CREATE;
3947  }
3948 #if defined(_WIN32) || defined(_WIN64)
3949  if (!isu) {
3950  char expname[SQL_MAX_MESSAGE_LENGTH * 2];
3951 
3952  expname[0] = '\0';
3953  rc = ExpandEnvironmentStrings(name, expname, sizeof (expname));
3954  if (rc <= sizeof (expname)) {
3955  uname = wmb_to_utf(expname, rc - 1);
3956  } else {
3957  uname = wmb_to_utf(name, -1);
3958  }
3959  if (!uname) {
3960  rc = SQLITE_NOMEM;
3961  setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
3962  return SQL_ERROR;
3963  }
3964  }
3965 #endif
3966 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
3967  vfs_name = nvfs_makevfs(uname);
3968 #endif
3969 #ifdef SQLITE_OPEN_URI
3970  flags |= SQLITE_OPEN_URI;
3971 #endif
3972  rc = sqlite3_open_v2(uname, &d->sqlite, flags, vfs_name);
3973 #if defined(WINTERFACE) || defined(_WIN32) || defined(_WIN64)
3974  if (uname != name) {
3975  uc_free(uname);
3976  }
3977 #endif
3978 #else
3979 #if defined(_WIN32) || defined(_WIN64)
3980  if (d->nocreat) {
3981  char *cname = NULL;
3982 
3983  if (isu) {
3984  cname = utf_to_wmb(name, -1);
3985  }
3986  if (GetFileAttributesA(cname ? cname : name) ==
3987  INVALID_FILE_ATTRIBUTES) {
3988  uc_free(cname);
3989  rc = SQLITE_CANTOPEN;
3990  setstatd(d, rc, "cannot open database",
3991  (*d->ov3) ? "HY000" : "S1000");
3992  return SQL_ERROR;
3993  }
3994  uc_free(cname);
3995  }
3996 #else
3997  if (d->nocreat && access(name, 004) < 0) {
3998  rc = SQLITE_CANTOPEN;
3999  setstatd(d, rc, "cannot open database", (*d->ov3) ? "HY000" : "S1000");
4000  return SQL_ERROR;
4001  }
4002 #endif
4003 #if defined(_WIN32) || defined(_WIN64)
4004  if (!isu) {
4005  WCHAR *wname = wmb_to_uc(name, -1);
4006 
4007  if (!wname) {
4008  rc = SQLITE_NOMEM;
4009  setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
4010  return SQL_ERROR;
4011  }
4012  rc = sqlite3_open16(wname, &d->sqlite);
4013  uc_free(wname);
4014  } else
4015 #endif
4016  rc = sqlite3_open(name, &d->sqlite);
4017 #endif /* !HAVE_SQLITE3VFS */
4018  if (rc != SQLITE_OK) {
4019 connfail:
4020  setstatd(d, rc, "connect failed", (*d->ov3) ? "HY000" : "S1000");
4021  if (d->sqlite) {
4022  sqlite3_close(d->sqlite);
4023  d->sqlite = NULL;
4024  }
4025  return SQL_ERROR;
4026  }
4027 #if defined(SQLITE_DYNLOAD) || defined(SQLITE_HAS_CODEC)
4028  if (d->pwd) {
4029  sqlite3_key(d->sqlite, d->pwd, d->pwdLen);
4030  }
4031 #endif
4032  d->pwd = NULL;
4033  d->pwdLen = 0;
4034  if (d->trace) {
4035 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
4036  sqlite3_profile(d->sqlite, dbtrace, d);
4037 #else
4038  sqlite3_trace(d->sqlite, dbtrace, d);
4039 #endif
4040  }
4041  d->step_enable = getbool(sflag);
4042  d->trans_disable = getbool(ntflag);
4043  d->curtype = d->step_enable ?
4044  SQL_CURSOR_FORWARD_ONLY : SQL_CURSOR_STATIC;
4045  tmp = strtol(busy, &endp, 0);
4046  if (endp && *endp == '\0' && endp != busy) {
4047  busyto = tmp;
4048  }
4049  if (busyto < 1 || busyto > 1000000) {
4050  busyto = 1000000;
4051  }
4052  d->timeout = busyto;
4053  freep(&d->dbname);
4054  d->dbname = xstrdup(name);
4055  freep(&d->dsn);
4056  d->dsn = xstrdup(dsn);
4057  if ((rc = setsqliteopts(d->sqlite, d)) != SQLITE_OK) {
4058  if (d->trace) {
4059  fprintf(d->trace, "-- sqlite3_close: '%s'\n",
4060  d->dbname);
4061  fflush(d->trace);
4062  }
4063  sqlite3_close(d->sqlite);
4064  d->sqlite = NULL;
4065  goto connfail;
4066  }
4067  if (!spflag || spflag[0] == '\0') {
4068  spflag = "NORMAL";
4069  }
4070  if (spflag[0] != '\0') {
4071  char syncp[128];
4072 
4073  sprintf(syncp, "PRAGMA synchronous = %8.8s;", spflag);
4074  sqlite3_exec(d->sqlite, syncp, NULL, NULL, NULL);
4075  }
4076  if (jmode[0] != '\0') {
4077  char jourp[128];
4078 
4079  sprintf(jourp, "PRAGMA journal_mode = %16.16s;", jmode);
4080  sqlite3_exec(d->sqlite, jourp, NULL, NULL, NULL);
4081  }
4082  if (d->trace) {
4083  fprintf(d->trace, "-- sqlite3_open: '%s'\n", d->dbname);
4084  fflush(d->trace);
4085  }
4086 #if defined(_WIN32) || defined(_WIN64)
4087  {
4088  char pname[MAX_PATH];
4089  HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
4090  FALSE, GetCurrentProcessId());
4091 
4092  pname[0] = '\0';
4093  if (h) {
4094  HMODULE m = NULL, l = LoadLibrary("psapi.dll");
4095  DWORD need;
4096  typedef BOOL (WINAPI *epmfunc)(HANDLE, HMODULE *, DWORD, LPDWORD);
4097  typedef BOOL (WINAPI *gmbfunc)(HANDLE, HMODULE, LPSTR, DWORD);
4098  epmfunc epm;
4099  gmbfunc gmb;
4100 
4101  if (l) {
4102  epm = (epmfunc) GetProcAddress(l, "EnumProcessModules");
4103  gmb = (gmbfunc) GetProcAddress(l, "GetModuleBaseNameA");
4104  if (epm && gmb && epm(h, &m, sizeof (m), &need)) {
4105  gmb(h, m, pname, sizeof (pname));
4106  }
4107  FreeLibrary(l);
4108  }
4109  CloseHandle(h);
4110  }
4111  d->xcelqrx = strncasecmp(pname, "EXCEL", 5) == 0 ||
4112  strncasecmp(pname, "MSQRY", 5) == 0;
4113  if (d->trace && d->xcelqrx) {
4114 
4115  fprintf(d->trace, "-- enabled EXCEL quirks\n");
4116  fflush(d->trace);
4117  }
4118  }
4119 #endif
4120  sqlite3_create_function(d->sqlite, "blob_import", 1, SQLITE_UTF8,
4121  d, blob_import, 0, 0);
4122  sqlite3_create_function(d->sqlite, "blob_export", 2, SQLITE_UTF8,
4123  d, blob_export, 0, 0);
4124  return SQL_SUCCESS;
4125 }
4126 
4133 static void
4134 dbloadext(DBC *d, char *exts)
4135 {
4136 #if defined(HAVE_SQLITE3LOADEXTENSION) && (HAVE_SQLITE3LOADEXTENSION)
4137  char *p;
4138  char path[SQL_MAX_MESSAGE_LENGTH];
4139  int plen = 0;
4140 
4141  if (!d->sqlite) {
4142  return;
4143  }
4144  sqlite3_enable_load_extension(d->sqlite, 1);
4145 #if defined(_WIN32) || defined(_WIN64)
4146  GetModuleFileName(hModule, path, sizeof (path));
4147  p = strrchr(path, '\\');
4148  plen = p ? ((p + 1) - path) : 0;
4149 #endif
4150  do {
4151  p = strchr(exts, ',');
4152  if (p) {
4153  strncpy(path + plen, exts, p - exts);
4154  path[plen + (p - exts)] = '\0';
4155  } else {
4156  strcpy(path + plen, exts);
4157  }
4158  if (exts[0]) {
4159  char *errmsg = NULL;
4160  int rc;
4161 #if defined(_WIN32) || defined(_WIN64)
4162  int i;
4163  char *q;
4164 
4165  q = path + plen;
4166  if (!(q[0] &&
4167  ((q[1] == ':' && (q[2] == '\\' || q[2] == '/')) ||
4168  q[0] == '\\' || q[0] == '/' || q[0] == '.'))) {
4169  q = path;
4170  }
4171  /* sqlite3_load_extension() dislikes backslashes */
4172  for (i = 0; q[i] != '\0'; i++) {
4173  if (q[i] == '\\') {
4174  q[i] = '/';
4175  }
4176  }
4177  rc = sqlite3_load_extension(d->sqlite, q, 0, &errmsg);
4178 #else
4179  rc = sqlite3_load_extension(d->sqlite, path, 0, &errmsg);
4180 #endif
4181  if (rc != SQLITE_OK) {
4182 #if defined(_WIN32) || defined(_WIN64)
4183  char buf[512], msg[512];
4184 
4185  LoadString(hModule, IDS_EXTERR, buf, sizeof (buf));
4186  wsprintf(msg, buf, q, errmsg ?
4187  errmsg : "no error info available");
4188  LoadString(hModule, IDS_EXTTITLE, buf, sizeof (buf));
4189  MessageBox(NULL, msg, buf,
4190  MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
4191  MB_SETFOREGROUND);
4192 #else
4193  fprintf(stderr, "extension '%s' did not load%s%s\n",
4194  path, errmsg ? ": " : "", errmsg ? errmsg : "");
4195 #endif
4196  }
4197  }
4198  if (p) {
4199  exts = p + 1;
4200  }
4201  } while (p);
4202 #endif /* HAVE_SQLITE3LOADEXTENSION */
4203 }
4204 
4214 static char *
4215 s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
4216 {
4217  char *typename = (char *) sqlite3_column_decltype(s3stmt, col);
4218  char guess[64];
4219 
4220  guess[0] = '\0';
4221  if (!typename) {
4222  int coltype = sqlite3_column_type(s3stmt, col);
4223 
4224  if (guessed_types) {
4225  guessed_types[0]++;
4226  }
4227  if (d->trace) {
4228  sprintf(guess, " (guessed from %d)", coltype);
4229  }
4230  switch (coltype) {
4231  case SQLITE_INTEGER: typename = "integer"; break;
4232  case SQLITE_FLOAT: typename = "double"; break;
4233  default:
4234  case SQLITE_TEXT: typename = "varchar"; break;
4235  case SQLITE_BLOB: typename = "blob"; break;
4236 #if 0
4237  case SQLITE_NULL: typename = "null"; break;
4238 #endif
4239  }
4240  }
4241  if (d->trace) {
4242  fprintf(d->trace, "-- column %d type%s: '%s'\n", col + 1,
4243  guess, typename);
4244  fflush(d->trace);
4245  }
4246  return typename;
4247 }
4248 
4249 #ifdef FULL_METADATA
4250 
4259 static void
4260 s3stmt_addmeta(sqlite3_stmt *s3stmt, int col, DBC *d, COL *ci)
4261 {
4262  int nn = 0, pk = 0, ai = 0;
4263  const char *dn = NULL, *tn = NULL, *cn = NULL, *dummy[4];
4264 
4265  dn = sqlite3_column_database_name(s3stmt, col);
4266  tn = sqlite3_column_table_name(s3stmt, col);
4267  cn = sqlite3_column_origin_name(s3stmt, col);
4268  dummy[0] = dummy[1] = 0;
4269  if (tn && cn) {
4270  sqlite3_table_column_metadata(d->sqlite, dn, tn, cn,
4271  dummy, dummy + 1,
4272  &nn, &pk, &ai);
4273  }
4274  ci->autoinc = ai ? SQL_TRUE: SQL_FALSE;
4275  ci->notnull = nn ? SQL_NO_NULLS : SQL_NULLABLE;
4276  ci->ispk = pk ? 1 : 0;
4277  if (d->trace) {
4278  fprintf(d->trace, "-- column %d %s\n",
4279  col + 1, nn ? "notnull" : "nullable");
4280  if (ai) {
4281  fprintf(d->trace, "-- column %d autoincrement\n", col + 1);
4282  }
4283  fflush(d->trace);
4284  }
4285  ci->isrowid = 0;
4286  if (ci->ispk && tn) {
4287  nn = pk = ai = 0;
4288  dummy[2] = dummy[3] = 0;
4289 
4290  sqlite3_table_column_metadata(d->sqlite, dn, tn, "rowid",
4291  dummy + 2, dummy + 3,
4292  &nn, &pk, &ai);
4293  if (pk && dummy[0] && dummy[0] == dummy[2]) {
4294  ci->isrowid = 1;
4295  }
4296  }
4297 }
4298 
4299 #endif
4300 
4307 static int
4309 {
4310  DBC *d = (DBC *) s->dbc;
4311  char **rowd = NULL;
4312  const char *errp = NULL;
4313  int i, ncols, rc;
4314 
4315  if (s != d->cur_s3stmt || !s->s3stmt) {
4316  setstat(s, -1, "stale statement", (*s->ov3) ? "HY000" : "S1000");
4317  return SQL_ERROR;
4318  }
4319  rc = sqlite3_step(s->s3stmt);
4320  if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
4321  ++s->s3stmt_rownum;
4322  ncols = sqlite3_column_count(s->s3stmt);
4323  if (d->s3stmt_needmeta && s->s3stmt_rownum == 0 && ncols > 0) {
4324  PTRDIFF_T size;
4325  char *p;
4326  COL *dyncols;
4327  const char *colname, *typename;
4328 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4329  char *tblname;
4330 #endif
4331 
4332  for (i = size = 0; i < ncols; i++) {
4333  colname = sqlite3_column_name(s->s3stmt, i);
4334  size += 3 + 3 * strlen(colname);
4335  }
4336 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4337  tblname = (char *) size;
4338  for (i = 0; i < ncols; i++) {
4339  p = (char *) sqlite3_column_table_name(s->s3stmt, i);
4340  size += 2 + (p ? strlen(p) : 0);
4341  }
4342 #endif
4343  dyncols = xmalloc(ncols * sizeof (COL) + size);
4344  if (!dyncols) {
4345  freedyncols(s);
4346  s->ncols = 0;
4347  dbtraceapi(d, "sqlite3_finalize", 0);
4348  sqlite3_finalize(s->s3stmt);
4349  s->s3stmt = NULL;
4350  d->cur_s3stmt = NULL;
4351  return nomem(s);
4352  }
4353  p = (char *) (dyncols + ncols);
4354 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4355  tblname = p + (PTRDIFF_T) tblname;
4356 #endif
4357  for (i = 0; i < ncols; i++) {
4358  char *q;
4359 
4360  colname = sqlite3_column_name(s->s3stmt, i);
4361  if (d->trace) {
4362  fprintf(d->trace, "-- column %d name: '%s'\n",
4363  i + 1, colname);
4364  fflush(d->trace);
4365  }
4366 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4367  q = (char *) sqlite3_column_table_name(s->s3stmt, i);
4368  strcpy(tblname, q ? q : "");
4369  if (d->trace) {
4370  fprintf(d->trace, "-- table %d name: '%s'\n",
4371  i + 1, tblname);
4372  fflush(d->trace);
4373  }
4374  dyncols[i].table = tblname;
4375  tblname += strlen(tblname) + 1;
4376 #endif
4377  typename = s3stmt_coltype(s->s3stmt, i, d, 0);
4378  dyncols[i].db = ((DBC *) (s->dbc))->dbname;
4379  strcpy(p, colname);
4380  dyncols[i].label = p;
4381  p += strlen(p) + 1;
4382  q = strchr(colname, '.');
4383  if (q) {
4384  char *q2 = strchr(q + 1, '.');
4385 
4386  /* SQLite 3.3.4 produces view.table.column sometimes */
4387  if (q2) {
4388  q = q2;
4389  }
4390  }
4391  if (q) {
4392 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
4393  dyncols[i].table = p;
4394 #endif
4395  strncpy(p, colname, q - colname);
4396  p[q - colname] = '\0';
4397  p += strlen(p) + 1;
4398  strcpy(p, q + 1);
4399  dyncols[i].column = p;
4400  p += strlen(p) + 1;
4401  } else {
4402 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
4403  dyncols[i].table = "";
4404 #endif
4405  strcpy(p, colname);
4406  dyncols[i].column = p;
4407  p += strlen(p) + 1;
4408  }
4409  if (s->longnames) {
4410  dyncols[i].column = dyncols[i].label;
4411  }
4412 #ifdef SQL_LONGVARCHAR
4413  dyncols[i].type = SQL_LONGVARCHAR;
4414  dyncols[i].size = 65535;
4415 #else
4416  dyncols[i].type = SQL_VARCHAR;
4417  dyncols[i].size = 255;
4418 #endif
4419  dyncols[i].index = i;
4420  dyncols[i].scale = 0;
4421  dyncols[i].prec = 0;
4422  dyncols[i].nosign = 1;
4423  dyncols[i].autoinc = SQL_FALSE;
4424  dyncols[i].notnull = SQL_NULLABLE;
4425  dyncols[i].ispk = -1;
4426  dyncols[i].isrowid = -1;
4427 #ifdef FULL_METADATA
4428  s3stmt_addmeta(s->s3stmt, i, d, &dyncols[i]);
4429 #endif
4430  dyncols[i].typename = xstrdup(typename);
4431  }
4432  freedyncols(s);
4433  s->ncols = s->dcols = ncols;
4434  s->dyncols = s->cols = dyncols;
4435  fixupdyncols(s, d);
4436  mkbindcols(s, s->ncols);
4437  d->s3stmt_needmeta = 0;
4438  }
4439  if (ncols <= 0) {
4440  goto killstmt;
4441  }
4442  if (rc == SQLITE_DONE) {
4443  freeresult(s, 0);
4444  s->nrows = 0;
4445  dbtraceapi(d, "sqlite3_finalize", 0);
4446  sqlite3_finalize(s->s3stmt);
4447  s->s3stmt = NULL;
4448  d->cur_s3stmt = NULL;
4449  return SQL_SUCCESS;
4450  }
4451  rowd = xmalloc((1 + 2 * ncols) * sizeof (char *));
4452  if (rowd) {
4453  const unsigned char *value;
4454 
4455  rowd[0] = (char *) ((PTRDIFF_T) (ncols * 2));
4456  ++rowd;
4457  for (i = 0; i < ncols; i++) {
4458  int coltype = sqlite3_column_type(s->s3stmt, i);
4459 
4460  rowd[i] = rowd[i + ncols] = NULL;
4461  if (coltype == SQLITE_BLOB) {
4462  int k, nbytes = sqlite3_column_bytes(s->s3stmt, i);
4463  char *qp;
4464  unsigned const char *bp;
4465 
4466  bp = sqlite3_column_blob(s->s3stmt, i);
4467  qp = xmalloc(nbytes * 2 + 4);
4468  if (qp) {
4469  rowd[i + ncols] = qp;
4470  *qp++ = 'X';
4471  *qp++ = '\'';
4472  for (k = 0; k < nbytes; k++) {
4473  *qp++ = xdigits[(bp[k] >> 4)];
4474  *qp++ = xdigits[(bp[k] & 0xF)];
4475  }
4476  *qp++ = '\'';
4477  *qp = '\0';
4478  }
4479 #ifdef _MSC_VER
4480  } else if (coltype == SQLITE_FLOAT) {
4481  struct lconv *lc = 0;
4482  double d = sqlite3_column_double(s->s3stmt, i);
4483  char *p, buffer[128];
4484 
4485  /*
4486  * This avoids floating point rounding
4487  * and formatting problems of some SQLite
4488  * versions in conjunction with MSVC 2010.
4489  */
4490  snprintf(buffer, sizeof (buffer), "%.15g", d);
4491  lc = localeconv();
4492  if (lc && lc->decimal_point && lc->decimal_point[0] &&
4493  lc->decimal_point[0] != '.') {
4494  p = strchr(buffer, lc->decimal_point[0]);
4495  if (p) {
4496  *p = '.';
4497  }
4498  }
4499  rowd[i + ncols] = xstrdup(buffer);
4500 #endif
4501  } else if (coltype != SQLITE_NULL) {
4502  value = sqlite3_column_text(s->s3stmt, i);
4503  rowd[i + ncols] = xstrdup((char *) value);
4504  }
4505  }
4506  for (i = 0; i < ncols; i++) {
4507  int coltype = sqlite3_column_type(s->s3stmt, i);
4508 
4509  value = NULL;
4510  if (coltype == SQLITE_BLOB) {
4511  value = sqlite3_column_blob(s->s3stmt, i);
4512  } else if (coltype != SQLITE_NULL) {
4513  value = sqlite3_column_text(s->s3stmt, i);
4514  }
4515  if (value && !rowd[i + ncols]) {
4516  freerows(rowd);
4517  rowd = 0;
4518  break;
4519  }
4520  }
4521  }
4522  if (rowd) {
4523  freeresult(s, 0);
4524  s->nrows = 1;
4525  s->rows = rowd;
4526  s->rowfree = freerows;
4527  if (rc == SQLITE_DONE) {
4528  dbtraceapi(d, "sqlite3_finalize", 0);
4529  sqlite3_finalize(s->s3stmt);
4530  s->s3stmt = NULL;
4531  d->cur_s3stmt = NULL;
4532  }
4533  return SQL_SUCCESS;
4534  }
4535  }
4536 killstmt:
4537  dbtraceapi(d, "sqlite3_reset", 0);
4538  rc = sqlite3_reset(s->s3stmt);
4539  s->s3stmt_noreset = 1;
4540  errp = sqlite3_errmsg(d->sqlite);
4541  if (d->cur_s3stmt == s) {
4542  d->cur_s3stmt = NULL;
4543  }
4544  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
4545  errp ? errp : "unknown error", rc);
4546  return SQL_ERROR;
4547 }
4548 
4554 static void
4556 {
4557  DBC *d;
4558 
4559  if (!s || !s->s3stmt) {
4560  return;
4561  }
4562  d = (DBC *) s->dbc;
4563  if (d) {
4564  d->busyint = 0;
4565  }
4566  if (!s->s3stmt_noreset) {
4567  dbtraceapi(d, "sqlite3_reset", 0);
4568  sqlite3_reset(s->s3stmt);
4569  s->s3stmt_noreset = 1;
4570  s->s3stmt_rownum = -1;
4571  }
4572  if (d->cur_s3stmt == s) {
4573  d->cur_s3stmt = NULL;
4574  }
4575 }
4576 
4582 static void
4584 {
4585  DBC *d = (DBC *) s->dbc;
4586 
4587  if (d) {
4588  d->busyint = 0;
4589  }
4590  if (d && d->cur_s3stmt == s) {
4591  s3stmt_end(s);
4592  }
4593 }
4594 
4600 static void
4602 {
4603  if (s->s3stmt) {
4604  DBC *d = (DBC *) s->dbc;
4605 
4606  if (d) {
4607  dbtraceapi(d, "sqlite3_finalize", 0);
4608  }
4609  sqlite3_finalize(s->s3stmt);
4610  s->s3stmt = NULL;
4611  s->s3stmt_rownum = 0;
4612  }
4613 }
4614 
4621 static SQLRETURN
4623 {
4624  DBC *d = (DBC *) s->dbc;
4625  const char *endp;
4626  sqlite3_stmt *s3stmt = NULL;
4627  int rc, nretry = 0;
4628 
4629  d->s3stmt_needmeta = 0;
4630  if (!s->s3stmt) {
4631 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
4632  dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
4633 #else
4634  dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
4635 #endif
4636  do {
4637  s3stmt = NULL;
4638 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
4639  rc = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
4640  &s3stmt, &endp);
4641 #else
4642  rc = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
4643  &s3stmt, &endp);
4644 #endif
4645  if (rc != SQLITE_OK) {
4646  if (s3stmt) {
4647  sqlite3_finalize(s3stmt);
4648  s3stmt = NULL;
4649  }
4650  }
4651  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
4652  dbtracerc(d, rc, NULL);
4653  if (rc != SQLITE_OK) {
4654  if (s3stmt) {
4655  dbtraceapi(d, "sqlite3_finalize", NULL);
4656  sqlite3_finalize(s3stmt);
4657  }
4658  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
4659  sqlite3_errmsg(d->sqlite), rc);
4660  return SQL_ERROR;
4661  }
4662  if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
4663  dbtraceapi(d, "sqlite3_finalize", 0);
4664  sqlite3_finalize(s3stmt);
4665  setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
4666  (*s->ov3) ? "HY000" : "S1000");
4667  return SQL_ERROR;
4668  }
4669  s->s3stmt = s3stmt;
4670  s->s3stmt_noreset = 1;
4671  d->s3stmt_needmeta = 1;
4672  }
4673  d->cur_s3stmt = s;
4674  s->s3stmt_rownum = -1;
4675  s3bind(d, s->s3stmt, s->nparams, s->bindparms);
4676  return SQL_SUCCESS;
4677 }
4678 
4679 #ifndef WINTERFACE
4680 
4684 SQLRETURN SQL_API
4685 SQLDataSources(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *srvname,
4686  SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
4687  SQLCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
4688 {
4689  if (env == SQL_NULL_HENV) {
4690  return SQL_INVALID_HANDLE;
4691  }
4692  return SQL_ERROR;
4693 }
4694 #endif
4695 
4696 #ifdef WINTERFACE
4697 
4701 SQLRETURN SQL_API
4702 SQLDataSourcesW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *srvname,
4703  SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
4704  SQLWCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
4705 {
4706  if (env == SQL_NULL_HENV) {
4707  return SQL_INVALID_HANDLE;
4708  }
4709  return SQL_ERROR;
4710 }
4711 #endif
4712 
4713 #ifndef WINTERFACE
4714 
4718 SQLRETURN SQL_API
4719 SQLDrivers(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *drvdesc,
4720  SQLSMALLINT descmax, SQLSMALLINT *desclenp,
4721  SQLCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
4722 {
4723  if (env == SQL_NULL_HENV) {
4724  return SQL_INVALID_HANDLE;
4725  }
4726  return SQL_ERROR;
4727 }
4728 #endif
4729 
4730 #ifdef WINTERFACE
4731 
4735 SQLRETURN SQL_API
4736 SQLDriversW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *drvdesc,
4737  SQLSMALLINT descmax, SQLSMALLINT *desclenp,
4738  SQLWCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
4739 {
4740  if (env == SQL_NULL_HENV) {
4741  return SQL_INVALID_HANDLE;
4742  }
4743  return SQL_ERROR;
4744 }
4745 #endif
4746 
4747 #ifndef WINTERFACE
4748 
4752 SQLRETURN SQL_API
4753 SQLBrowseConnect(SQLHDBC dbc, SQLCHAR *connin, SQLSMALLINT conninLen,
4754  SQLCHAR *connout, SQLSMALLINT connoutMax,
4755  SQLSMALLINT *connoutLen)
4756 {
4757  SQLRETURN ret;
4758 
4759  HDBC_LOCK(dbc);
4760  ret = drvunimpldbc(dbc);
4761  HDBC_UNLOCK(dbc);
4762  return ret;
4763 }
4764 #endif
4765 
4766 #ifdef WINTERFACE
4767 
4771 SQLRETURN SQL_API
4772 SQLBrowseConnectW(SQLHDBC dbc, SQLWCHAR *connin, SQLSMALLINT conninLen,
4773  SQLWCHAR *connout, SQLSMALLINT connoutMax,
4774  SQLSMALLINT *connoutLen)
4775 {
4776  SQLRETURN ret;
4777 
4778  HDBC_LOCK(dbc);
4779  ret = drvunimpldbc(dbc);
4780  HDBC_UNLOCK(dbc);
4781  return ret;
4782 }
4783 #endif
4784 
4793 static SQLRETURN
4794 drvputdata(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
4795 {
4796  STMT *s;
4797  int i, dlen, done = 0;
4798  BINDPARM *p;
4799 
4800  if (stmt == SQL_NULL_HSTMT) {
4801  return SQL_INVALID_HANDLE;
4802  }
4803  s = (STMT *) stmt;
4804  if (!s->query || s->nparams <= 0) {
4805 seqerr:
4806  setstat(s, -1, "sequence error", "HY010");
4807  return SQL_ERROR;
4808  }
4809  for (i = (s->pdcount < 0) ? 0 : s->pdcount; i < s->nparams; i++) {
4810  p = &s->bindparms[i];
4811  if (p->need > 0) {
4812  int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
4813 
4814  if (len == SQL_NULL_DATA) {
4815  freep(&p->parbuf);
4816  p->param = NULL;
4817  p->len = SQL_NULL_DATA;
4818  p->need = -1;
4819  } else if (type != SQL_C_CHAR
4820 #ifdef WCHARSUPPORT
4821  && type != SQL_C_WCHAR
4822 #endif
4823  && type != SQL_C_BINARY) {
4824  int size = 0;
4825 
4826  switch (type) {
4827  case SQL_C_TINYINT:
4828  case SQL_C_UTINYINT:
4829  case SQL_C_STINYINT:
4830 #ifdef SQL_BIT
4831  case SQL_C_BIT:
4832 #endif
4833  size = sizeof (SQLCHAR);
4834  break;
4835  case SQL_C_SHORT:
4836  case SQL_C_USHORT:
4837  case SQL_C_SSHORT:
4838  size = sizeof (SQLSMALLINT);
4839  break;
4840  case SQL_C_LONG:
4841  case SQL_C_ULONG:
4842  case SQL_C_SLONG:
4843  size = sizeof (SQLINTEGER);
4844  break;
4845 #ifdef SQL_BIGINT
4846  case SQL_C_UBIGINT:
4847  case SQL_C_SBIGINT:
4848  size = sizeof (SQLBIGINT);
4849  break;
4850 #endif
4851  case SQL_C_FLOAT:
4852  size = sizeof (float);
4853  break;
4854  case SQL_C_DOUBLE:
4855  size = sizeof (double);
4856  break;
4857 #ifdef SQL_C_TYPE_DATE
4858  case SQL_C_TYPE_DATE:
4859 #endif
4860  case SQL_C_DATE:
4861  size = sizeof (DATE_STRUCT);
4862  break;
4863 #ifdef SQL_C_TYPE_DATE
4864  case SQL_C_TYPE_TIME:
4865 #endif
4866  case SQL_C_TIME:
4867  size = sizeof (TIME_STRUCT);
4868  break;
4869 #ifdef SQL_C_TYPE_DATE
4870  case SQL_C_TYPE_TIMESTAMP:
4871 #endif
4872  case SQL_C_TIMESTAMP:
4873  size = sizeof (TIMESTAMP_STRUCT);
4874  break;
4875  }
4876  freep(&p->parbuf);
4877  p->parbuf = xmalloc(size);
4878  if (!p->parbuf) {
4879  return nomem(s);
4880  }
4881  p->param = p->parbuf;
4882  memcpy(p->param, data, size);
4883  p->len = size;
4884  p->need = -1;
4885  } else if (len == SQL_NTS && (
4886  type == SQL_C_CHAR
4887 #ifdef WCHARSUPPORT
4888  || type == SQL_C_WCHAR
4889 #endif
4890  )) {
4891  char *dp = data;
4892 
4893 #ifdef WCHARSUPPORT
4894  if (type == SQL_C_WCHAR) {
4895  dp = uc_to_utf(data, len);
4896  if (!dp) {
4897  return nomem(s);
4898  }
4899  }
4900 #endif
4901 #if defined(_WIN32) || defined(_WIN64)
4902  if (*s->oemcp) {
4903  dp = wmb_to_utf(data, strlen (data));
4904  if (!dp) {
4905  return nomem(s);
4906  }
4907  }
4908 #endif
4909  dlen = strlen(dp);
4910  freep(&p->parbuf);
4911  p->parbuf = xmalloc(dlen + 1);
4912  if (!p->parbuf) {
4913  if (dp != data) {
4914  uc_free(dp);
4915  }
4916  return nomem(s);
4917  }
4918  p->param = p->parbuf;
4919  strcpy(p->param, dp);
4920  if (dp != data) {
4921  uc_free(dp);
4922  }
4923  p->len = dlen;
4924  p->need = -1;
4925  } else if (len < 0) {
4926  setstat(s, -1, "invalid length", "HY090");
4927  return SQL_ERROR;
4928  } else {
4929  dlen = min(p->len - p->offs, len);
4930  if (!p->param) {
4931  setstat(s, -1, "no memory for parameter", "HY013");
4932  return SQL_ERROR;
4933  }
4934  memcpy((char *) p->param + p->offs, data, dlen);
4935  p->offs += dlen;
4936  if (p->offs >= p->len) {
4937 #ifdef WCHARSUPPORT
4938  if (type == SQL_C_WCHAR) {
4939  char *dp = uc_to_utf(p->param, p->len);
4940  char *np;
4941  int nlen;
4942 
4943  if (!dp) {
4944  return nomem(s);
4945  }
4946  nlen = strlen(dp);
4947  np = xmalloc(nlen + 1);
4948  if (!np) {
4949  uc_free(dp);
4950  return nomem(s);
4951  }
4952  strcpy(np, dp);
4953  uc_free(dp);
4954  if (p->param == p->parbuf) {
4955  freep(&p->parbuf);
4956  }
4957  p->parbuf = p->param = np;
4958  p->len = nlen;
4959  } else {
4960  *((char *) p->param + p->len) = '\0';
4961  }
4962  p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR)
4963  ? -1 : 0;
4964 #else
4965  *((char *) p->param + p->len) = '\0';
4966  p->need = (type == SQL_C_CHAR) ? -1 : 0;
4967 #endif
4968 #if defined(_WIN32) || defined(_WIN64)
4969  if (type == SQL_C_CHAR && *s->oemcp &&
4970  !(p->stype == SQL_BINARY ||
4971  p->stype == SQL_VARBINARY ||
4972  p->stype == SQL_LONGVARBINARY)) {
4973  char *dp = wmb_to_utf(p->param, p->len);
4974 
4975  if (!dp) {
4976  return nomem(s);
4977  }
4978  if (p->param == p->parbuf) {
4979  freep(&p->parbuf);
4980  }
4981  p->parbuf = p->param = dp;
4982  p->len = strlen(dp);
4983  }
4984  if (p->type == SQL_C_WCHAR &&
4985  (p->stype == SQL_VARCHAR ||
4986  p->stype == SQL_LONGVARCHAR) &&
4987  p->len == p->coldef * sizeof (SQLWCHAR)) {
4988  /* fix for MS-Access */
4989  p->len = p->coldef;
4990  }
4991 #endif
4992  }
4993  }
4994  done = 1;
4995  break;
4996  }
4997  }
4998  if (!done) {
4999  goto seqerr;
5000  }
5001  return SQL_SUCCESS;
5002 }
5003 
5012 SQLRETURN SQL_API
5013 SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
5014 {
5015  SQLRETURN ret;
5016 
5017  HSTMT_LOCK(stmt);
5018  ret = drvputdata(stmt, data, len);
5019  HSTMT_UNLOCK(stmt);
5020  return ret;
5021 }
5022 
5028 static SQLRETURN
5030 {
5031  if (s->bindparms) {
5032  int n;
5033 
5034  for (n = 0; n < s->nbindparms; n++) {
5035  freep(&s->bindparms[n].parbuf);
5036  memset(&s->bindparms[n], 0, sizeof (BINDPARM));
5037  }
5038  }
5039  return SQL_SUCCESS;
5040 }
5041 
5053 static SQLRETURN
5054 setupparam(STMT *s, char *sql, int pnum)
5055 {
5056  int type, len = 0, needalloc = 0;
5057  BINDPARM *p;
5058 
5059  if (!s->bindparms || pnum < 0 || pnum >= s->nbindparms) {
5060  goto error;
5061  }
5062  p = &s->bindparms[pnum];
5063  type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
5064 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
5065  /* MS Access hack part 4 (map SQL_C_DEFAULT to SQL_C_CHAR) */
5066  if (type == SQL_C_WCHAR && p->type == SQL_C_DEFAULT) {
5067  type = SQL_C_CHAR;
5068  }
5069 #endif
5070  if (p->need > 0) {
5071  return setupparbuf(s, p);
5072  }
5073  p->strbuf[0] = '\0';
5074  if (!p->param || (p->lenp && *p->lenp == SQL_NULL_DATA)) {
5075  p->s3type = SQLITE_NULL;
5076  p->s3size = 0;
5077  return SQL_SUCCESS;
5078  }
5079  if (type == SQL_C_CHAR &&
5080  (p->stype == SQL_BINARY ||
5081  p->stype == SQL_VARBINARY ||
5082  p->stype == SQL_LONGVARBINARY)) {
5083  type = SQL_C_BINARY;
5084  }
5085  switch (type) {
5086  case SQL_C_BINARY:
5087  p->s3type = SQLITE_BLOB;
5088  p->s3size = p->len;
5089  p->s3val = p->param;
5090  if (p->need < 0) {
5091  break;
5092  }
5093  if (!p->lenp) {
5094  len = p->len;
5095  } else if (*p->lenp == SQL_DATA_AT_EXEC) {
5096  len = p->len;
5097  } else {
5098  len = *p->lenp;
5099  if (len <= SQL_LEN_DATA_AT_EXEC_OFFSET) {
5100  len = SQL_LEN_DATA_AT_EXEC(len);
5101  }
5102  }
5103  if (len < 0) {
5104  setstat(s, -1, "invalid length", "HY009");
5105  return SQL_ERROR;
5106  }
5107  p->len = len;
5108  p->max = p->len;
5109  p->need = -1;
5110  p->s3size = len;
5111  break;
5112 #ifdef WCHARSUPPORT
5113  case SQL_C_WCHAR:
5114 #endif
5115  case SQL_C_CHAR:
5116  p->s3type = SQLITE_TEXT;
5117  p->s3size = -1;
5118  p->s3val = p->param;
5119  if (!p->parbuf) {
5120 #ifdef WCHARSUPPORT
5121  if (type == SQL_C_WCHAR) {
5122  if (!p->lenp || *p->lenp == SQL_NTS) {
5123  p->max = uc_strlen(p->param) * sizeof (SQLWCHAR);
5124  } else if (*p->lenp >= 0) {
5125  p->max = *p->lenp;
5126  }
5127  } else
5128 #endif
5129  if (type == SQL_C_CHAR) {
5130  if (!p->lenp || *p->lenp == SQL_NTS) {
5131  p->len = p->max = strlen(p->param);
5132 #if defined(_WIN32) || defined(_WIN64)
5133  needalloc = 1;
5134 #endif
5135  } else if (*p->lenp >= 0) {
5136  p->len = p->max = *p->lenp;
5137  needalloc = 1;
5138  }
5139  }
5140  }
5141  if (p->need < 0 && p->parbuf == p->param) {
5142  break;
5143  }
5144 #ifdef WCHARSUPPORT
5145  if (type == SQL_C_WCHAR) {
5146  char *dp = uc_to_utf(p->param, p->max);
5147 
5148  if (!dp) {
5149  return nomem(s);
5150  }
5151  if (p->param == p->parbuf) {
5152  freep(&p->parbuf);
5153  }
5154  p->parbuf = p->param = dp;
5155  p->need = -1;
5156  p->len = strlen(p->param);
5157  p->s3val = p->param;
5158  p->s3size = p->len;
5159  } else
5160 #endif
5161  if (type == SQL_C_CHAR) {
5162  p->s3val = p->param;
5163  if (needalloc) {
5164  char *dp;
5165 
5166 #if defined(_WIN32) || defined(_WIN64)
5167  if (*s->oemcp) {
5168  dp = wmb_to_utf(p->param, p->len);
5169  } else {
5170  dp = xmalloc(p->len + 1);
5171  }
5172 #else
5173  dp = xmalloc(p->len + 1);
5174 #endif
5175  if (!dp) {
5176  return nomem(s);
5177  }
5178 #if defined(_WIN32) || defined(_WIN64)
5179  if (*s->oemcp) {
5180  p->len = strlen(dp);
5181  } else {
5182  memcpy(dp, p->param, p->len);
5183  dp[p->len] = '\0';
5184  }
5185 #else
5186  memcpy(dp, p->param, p->len);
5187  dp[p->len] = '\0';
5188 #endif
5189  if (p->param == p->parbuf) {
5190  freep(&p->parbuf);
5191  }
5192  p->parbuf = p->param = dp;
5193  p->need = -1;
5194  p->s3val = p->param;
5195  p->s3size = p->len;
5196  }
5197  }
5198  break;
5199  case SQL_C_UTINYINT:
5200  case SQL_C_TINYINT:
5201  case SQL_C_STINYINT:
5202  p->s3type = SQLITE_INTEGER;
5203  p->s3size = sizeof (int);
5204  p->s3ival = *((SQLCHAR *) p->param);
5205  break;
5206  case SQL_C_USHORT:
5207  p->s3type = SQLITE_INTEGER;
5208  p->s3size = sizeof (int);
5209  p->s3ival = *((SQLUSMALLINT *) p->param);
5210  break;
5211  case SQL_C_SHORT:
5212  case SQL_C_SSHORT:
5213  p->s3type = SQLITE_INTEGER;
5214  p->s3size = sizeof (int);
5215  p->s3ival = *((SQLSMALLINT *) p->param);
5216  break;
5217  case SQL_C_ULONG:
5218  p->s3type = SQLITE_INTEGER;
5219  p->s3size = sizeof (int);
5220  p->s3ival = *((SQLUINTEGER *) p->param);
5221  break;
5222  case SQL_C_LONG:
5223  case SQL_C_SLONG:
5224  p->s3type = SQLITE_INTEGER;
5225  p->s3size = sizeof (int);
5226  p->s3ival = *((SQLINTEGER *) p->param);
5227  break;
5228 #ifdef SQL_BIT
5229  case SQL_C_BIT:
5230  p->s3type = SQLITE_INTEGER;
5231  p->s3size = sizeof (int);
5232  p->s3ival = (*((SQLCHAR *) p->param)) ? 1 : 0;
5233  break;
5234 #endif
5235 #ifdef SQL_BIGINT
5236  case SQL_C_SBIGINT:
5237  p->s3type = SQLITE_INTEGER;
5238  p->s3size = sizeof (sqlite_int64);
5239  p->s3lival = *((sqlite_int64 *) p->param);
5240  break;
5241  case SQL_C_UBIGINT:
5242  p->s3type = SQLITE_INTEGER;
5243  p->s3size = sizeof (sqlite_int64);
5244  p->s3lival = *((sqlite_uint64 *) p->param);
5245  break;
5246 #endif
5247  case SQL_C_FLOAT:
5248  p->s3type = SQLITE_FLOAT;
5249  p->s3size = sizeof (double);
5250  p->s3dval = *((float *) p->param);
5251  break;
5252  case SQL_C_DOUBLE:
5253  p->s3type = SQLITE_FLOAT;
5254  p->s3size = sizeof (double);
5255  p->s3dval = *((double *) p->param);
5256  break;
5257 #ifdef SQL_C_TYPE_DATE
5258  case SQL_C_TYPE_DATE:
5259 #endif
5260  case SQL_C_DATE:
5261  if (*s->jdconv) {
5262  int a, b, x1, x2, y, m, d;
5263 
5264  p->s3type = SQLITE_FLOAT;
5265  p->s3size = sizeof (double);
5266  y = ((DATE_STRUCT *) p->param)->year;
5267  m = ((DATE_STRUCT *) p->param)->month;
5268  d = ((DATE_STRUCT *) p->param)->day;
5269  if (m <= 2) {
5270  y--;
5271  m += 12;
5272  }
5273  a = y / 100;
5274  b = 2 - a + (a / 4);
5275  x1 = 36525 * (y + 4716) / 100;
5276  x2 = 306001 * (m + 1) / 10000;
5277  p->s3dval = x1 + x2 + d + b - 1524.5;
5278  break;
5279  }
5280  sprintf(p->strbuf, "%04d-%02d-%02d",
5281  ((DATE_STRUCT *) p->param)->year,
5282  ((DATE_STRUCT *) p->param)->month,
5283  ((DATE_STRUCT *) p->param)->day);
5284  p->s3type = SQLITE_TEXT;
5285  p->s3size = -1;
5286  p->s3val = p->strbuf;
5287  break;
5288 #ifdef SQL_C_TYPE_TIME
5289  case SQL_C_TYPE_TIME:
5290 #endif
5291  case SQL_C_TIME:
5292  if (*s->jdconv) {
5293  p->s3type = SQLITE_FLOAT;
5294  p->s3size = sizeof (double);
5295  p->s3dval = 2451544.5 +
5296  (((TIME_STRUCT *) p->param)->hour * 3600000.0 +
5297  ((TIME_STRUCT *) p->param)->minute * 60000.0 +
5298  ((TIME_STRUCT *) p->param)->second * 1000.0) / 86400000.0;
5299  break;
5300  }
5301  sprintf(p->strbuf, "%02d:%02d:%02d",
5302  ((TIME_STRUCT *) p->param)->hour,
5303  ((TIME_STRUCT *) p->param)->minute,
5304  ((TIME_STRUCT *) p->param)->second);
5305  p->s3type = SQLITE_TEXT;
5306  p->s3size = -1;
5307  p->s3val = p->strbuf;
5308  break;
5309 #ifdef SQL_C_TYPE_TIMESTAMP
5310  case SQL_C_TYPE_TIMESTAMP:
5311 #endif
5312  case SQL_C_TIMESTAMP:
5313  if (*s->jdconv) {
5314  int a, b, x1, x2, y, m, d;
5315 
5316  p->s3type = SQLITE_FLOAT;
5317  p->s3size = sizeof (double);
5318  y = ((TIMESTAMP_STRUCT *) p->param)->year;
5319  m = ((TIMESTAMP_STRUCT *) p->param)->month;
5320  d = ((TIMESTAMP_STRUCT *) p->param)->day;
5321  if (m <= 2) {
5322  y--;
5323  m += 12;
5324  }
5325  a = y / 100;
5326  b = 2 - a + (a / 4);
5327  x1 = 36525 * (y + 4716) / 100;
5328  x2 = 306001 * (m + 1) / 10000;
5329  p->s3dval = x1 + x2 + d + b - 1524.5 +
5330  (((TIMESTAMP_STRUCT *) p->param)->hour * 3600000.0 +
5331  ((TIMESTAMP_STRUCT *) p->param)->minute * 60000.0 +
5332  ((TIMESTAMP_STRUCT *) p->param)->second * 1000.0 +
5333  ((TIMESTAMP_STRUCT *) p->param)->fraction / 1.0E6)
5334  / 86400000.0;
5335  break;
5336  }
5337  len = (int) ((TIMESTAMP_STRUCT *) p->param)->fraction;
5338  len /= 1000000;
5339  len = len % 1000;
5340  if (len < 0) {
5341  len = 0;
5342  }
5343  if (p->coldef && p->coldef <= 16) {
5344  sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
5345  ((TIMESTAMP_STRUCT *) p->param)->year,
5346  ((TIMESTAMP_STRUCT *) p->param)->month,
5347  ((TIMESTAMP_STRUCT *) p->param)->day,
5348  ((TIMESTAMP_STRUCT *) p->param)->hour,
5349  ((TIMESTAMP_STRUCT *) p->param)->minute);
5350  } else if (p->coldef && p->coldef <= 19) {
5351  sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
5352  ((TIMESTAMP_STRUCT *) p->param)->year,
5353  ((TIMESTAMP_STRUCT *) p->param)->month,
5354  ((TIMESTAMP_STRUCT *) p->param)->day,
5355  ((TIMESTAMP_STRUCT *) p->param)->hour,
5356  ((TIMESTAMP_STRUCT *) p->param)->minute,
5357  ((TIMESTAMP_STRUCT *) p->param)->second);
5358  } else {
5359  sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
5360  ((TIMESTAMP_STRUCT *) p->param)->year,
5361  ((TIMESTAMP_STRUCT *) p->param)->month,
5362  ((TIMESTAMP_STRUCT *) p->param)->day,
5363  ((TIMESTAMP_STRUCT *) p->param)->hour,
5364  ((TIMESTAMP_STRUCT *) p->param)->minute,
5365  ((TIMESTAMP_STRUCT *) p->param)->second,
5366  len);
5367  }
5368  p->s3type = SQLITE_TEXT;
5369  p->s3size = -1;
5370  p->s3val = p->strbuf;
5371  break;
5372  default:
5373  error:
5374  setstat(s, -1, "unsupported parameter type",
5375  (*s->ov3) ? "07009" : "S1093");
5376  return SQL_ERROR;
5377  }
5378  return SQL_SUCCESS;
5379 }
5380 
5396 static SQLRETURN
5397 drvbindparam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
5398  SQLSMALLINT buftype, SQLSMALLINT ptype, SQLUINTEGER coldef,
5399  SQLSMALLINT scale,
5400  SQLPOINTER data, SQLINTEGER buflen, SQLLEN *len)
5401 {
5402  STMT *s;
5403  BINDPARM *p;
5404 
5405  if (stmt == SQL_NULL_HSTMT) {
5406  return SQL_INVALID_HANDLE;
5407  }
5408  s = (STMT *) stmt;
5409  if (pnum == 0) {
5410  setstat(s, -1, "invalid parameter", (*s->ov3) ? "07009" : "S1093");
5411  return SQL_ERROR;
5412  }
5413  if (!data && !len) {
5414  setstat(s, -1, "invalid buffer", "HY003");
5415  return SQL_ERROR;
5416  }
5417  --pnum;
5418  if (s->bindparms) {
5419  if (pnum >= s->nbindparms) {
5420  BINDPARM *newparms;
5421 
5422  newparms = xrealloc(s->bindparms,
5423  (pnum + 1) * sizeof (BINDPARM));
5424  if (!newparms) {
5425 outofmem:
5426  return nomem(s);
5427  }
5428  s->bindparms = newparms;
5429  memset(&s->bindparms[s->nbindparms], 0,
5430  (pnum + 1 - s->nbindparms) * sizeof (BINDPARM));
5431  s->nbindparms = pnum + 1;
5432  }
5433  } else {
5434  int npar = max(10, pnum + 1);
5435 
5436  s->bindparms = xmalloc(npar * sizeof (BINDPARM));
5437  if (!s->bindparms) {
5438  goto outofmem;
5439  }
5440  memset(s->bindparms, 0, npar * sizeof (BINDPARM));
5441  s->nbindparms = npar;
5442  }
5443  switch (buftype) {
5444  case SQL_C_STINYINT:
5445  case SQL_C_UTINYINT:
5446  case SQL_C_TINYINT:
5447 #ifdef SQL_C_BIT
5448  case SQL_C_BIT:
5449 #endif
5450  buflen = sizeof (SQLCHAR);
5451  break;
5452  case SQL_C_SHORT:
5453  case SQL_C_USHORT:
5454  case SQL_C_SSHORT:
5455  buflen = sizeof (SQLSMALLINT);
5456  break;
5457  case SQL_C_SLONG:
5458  case SQL_C_ULONG:
5459  case SQL_C_LONG:
5460  buflen = sizeof (SQLINTEGER);
5461  break;
5462  case SQL_C_FLOAT:
5463  buflen = sizeof (float);
5464  break;
5465  case SQL_C_DOUBLE:
5466  buflen = sizeof (double);
5467  break;
5468  case SQL_C_TIMESTAMP:
5469 #ifdef SQL_C_TYPE_TIMESTAMP
5470  case SQL_C_TYPE_TIMESTAMP:
5471 #endif
5472  buflen = sizeof (TIMESTAMP_STRUCT);
5473  break;
5474  case SQL_C_TIME:
5475 #ifdef SQL_C_TYPE_TIME
5476  case SQL_C_TYPE_TIME:
5477 #endif
5478  buflen = sizeof (TIME_STRUCT);
5479  break;
5480  case SQL_C_DATE:
5481 #ifdef SQL_C_TYPE_DATE
5482  case SQL_C_TYPE_DATE:
5483 #endif
5484  buflen = sizeof (DATE_STRUCT);
5485  break;
5486 #ifdef SQL_C_UBIGINT
5487  case SQL_C_UBIGINT:
5488  buflen = sizeof (SQLBIGINT);
5489  break;
5490 #endif
5491 #ifdef SQL_C_SBIGINT
5492  case SQL_C_SBIGINT:
5493  buflen = sizeof (SQLBIGINT);
5494  break;
5495 #endif
5496 #ifdef SQL_C_BIGINT
5497  case SQL_C_BIGINT:
5498  buflen = sizeof (SQLBIGINT);
5499  break;
5500 #endif
5501  }
5502  p = &s->bindparms[pnum];
5503  p->type = buftype;
5504  p->stype = ptype;
5505  p->coldef = coldef;
5506  p->scale = scale;
5507  p->max = buflen;
5508  p->inc = buflen;
5509  p->lenp = p->lenp0 = len;
5510  p->offs = 0;
5511  p->len = 0;
5512  p->param0 = data;
5513  freep(&p->parbuf);
5514  p->param = p->param0;
5515  p->bound = 1;
5516  p->need = 0;
5517  return SQL_SUCCESS;
5518 }
5519 
5535 SQLRETURN SQL_API
5536 SQLBindParameter(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
5537  SQLSMALLINT buftype, SQLSMALLINT ptype, SQLULEN coldef,
5538  SQLSMALLINT scale,
5539  SQLPOINTER data, SQLLEN buflen, SQLLEN *len)
5540 {
5541  SQLRETURN ret;
5542 
5543  HSTMT_LOCK(stmt);
5544  ret = drvbindparam(stmt, pnum, iotype, buftype, ptype, coldef,
5545  scale, data, buflen, len);
5546  HSTMT_UNLOCK(stmt);
5547  return ret;
5548 }
5549 
5550 #ifndef HAVE_IODBC
5551 
5564 SQLRETURN SQL_API
5565 SQLBindParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT vtype,
5566  SQLSMALLINT ptype, SQLULEN lenprec,
5567  SQLSMALLINT scale, SQLPOINTER val,
5568  SQLLEN *lenp)
5569 {
5570  SQLRETURN ret;
5571 
5572  HSTMT_LOCK(stmt);
5573  ret = drvbindparam(stmt, pnum, SQL_PARAM_INPUT, vtype, ptype,
5574  lenprec, scale, val, 0, lenp);
5575  HSTMT_UNLOCK(stmt);
5576  return ret;
5577 }
5578 #endif
5579 
5587 SQLRETURN SQL_API
5588 SQLNumParams(SQLHSTMT stmt, SQLSMALLINT *nparam)
5589 {
5590  STMT *s;
5591  SQLSMALLINT dummy;
5592 
5593  HSTMT_LOCK(stmt);
5594  if (stmt == SQL_NULL_HSTMT) {
5595  return SQL_INVALID_HANDLE;
5596  }
5597  s = (STMT *) stmt;
5598  if (!nparam) {
5599  nparam = &dummy;
5600  }
5601  *nparam = s->nparams;
5602  HSTMT_UNLOCK(stmt);
5603  return SQL_SUCCESS;
5604 }
5605 
5613 static SQLRETURN
5615 {
5616  if (!p->parbuf) {
5617  if (*p->lenp == SQL_DATA_AT_EXEC) {
5618  p->len = p->max;
5619  } else {
5620  p->len = SQL_LEN_DATA_AT_EXEC(*p->lenp);
5621  }
5622  if (p->len < 0 && p->len != SQL_NTS &&
5623  p->len != SQL_NULL_DATA) {
5624  setstat(s, -1, "invalid length", "HY009");
5625  return SQL_ERROR;
5626  }
5627  if (p->len >= 0) {
5628  p->parbuf = xmalloc(p->len + 2);
5629  if (!p->parbuf) {
5630  return nomem(s);
5631  }
5632  p->param = p->parbuf;
5633  } else {
5634  p->param = NULL;
5635  }
5636  }
5637  return SQL_NEED_DATA;
5638 }
5639 
5647 SQLRETURN SQL_API
5648 SQLParamData(SQLHSTMT stmt, SQLPOINTER *pind)
5649 {
5650  STMT *s;
5651  int i;
5652  SQLPOINTER dummy;
5653  SQLRETURN ret;
5654  BINDPARM *p;
5655 
5656  HSTMT_LOCK(stmt);
5657  if (stmt == SQL_NULL_HSTMT) {
5658  return SQL_INVALID_HANDLE;
5659  }
5660  s = (STMT *) stmt;
5661  if (!pind) {
5662  pind = &dummy;
5663  }
5664  if (s->pdcount < s->nparams) {
5665  s->pdcount++;
5666  }
5667  for (i = 0; i < s->pdcount; i++) {
5668  p = &s->bindparms[i];
5669  if (p->need > 0) {
5670  int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
5671 
5672  p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR) ? -1 : 0;
5673  }
5674  }
5675  for (; i < s->nparams; i++) {
5676  p = &s->bindparms[i];
5677  if (p->need > 0) {
5678  *pind = (SQLPOINTER) p->param0;
5679  ret = setupparbuf(s, p);
5680  s->pdcount = i;
5681  goto done;
5682  }
5683  }
5684  ret = drvexecute(stmt, 0);
5685 done:
5686  HSTMT_UNLOCK(stmt);
5687  return ret;
5688 }
5689 
5701 SQLRETURN SQL_API
5702 SQLDescribeParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT *dtype,
5703  SQLULEN *size, SQLSMALLINT *decdigits, SQLSMALLINT *nullable)
5704 {
5705  STMT *s;
5706  SQLRETURN ret = SQL_ERROR;
5707 
5708  HSTMT_LOCK(stmt);
5709  if (stmt == SQL_NULL_HSTMT) {
5710  return SQL_INVALID_HANDLE;
5711  }
5712  s = (STMT *) stmt;
5713  --pnum;
5714  if (pnum >= s->nparams) {
5715  setstat(s, -1, "invalid parameter index",
5716  (*s->ov3) ? "HY000" : "S1000");
5717  goto done;
5718  }
5719  if (dtype) {
5720 #ifdef SQL_LONGVARCHAR
5721 #ifdef WINTERFACE
5722  *dtype = s->nowchar[0] ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
5723 #else
5724  *dtype = SQL_LONGVARCHAR;
5725 #endif
5726 #else
5727 #ifdef WINTERFACE
5728  *dtype = s->nowchar[0] ? SQL_VARCHAR : SQL_WVARCHAR;
5729 #else
5730  *dtype = SQL_VARCHAR;
5731 #endif
5732 #endif
5733  }
5734  if (size) {
5735 #ifdef SQL_LONGVARCHAR
5736  *size = 65536;
5737 #else
5738  *size = 255;
5739 #endif
5740  }
5741  if (decdigits) {
5742  *decdigits = 0;
5743  }
5744  if (nullable) {
5745  *nullable = SQL_NULLABLE;
5746  }
5747  ret = SQL_SUCCESS;
5748 done:
5749  HSTMT_UNLOCK(stmt);
5750  return ret;
5751 }
5752 
5766 SQLRETURN SQL_API
5767 SQLSetParam(SQLHSTMT stmt, SQLUSMALLINT par, SQLSMALLINT type,
5768  SQLSMALLINT sqltype, SQLULEN coldef,
5769  SQLSMALLINT scale, SQLPOINTER val, SQLLEN *nval)
5770 {
5771  SQLRETURN ret;
5772 
5773  HSTMT_LOCK(stmt);
5774  ret = drvbindparam(stmt, par, SQL_PARAM_INPUT,
5775  type, sqltype, coldef, scale, val,
5776  SQL_SETPARAM_VALUE_MAX, nval);
5777  HSTMT_UNLOCK(stmt);
5778  return ret;
5779 }
5780 
5785 SQLRETURN SQL_API
5786 SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
5787 {
5788  SQLRETURN ret;
5789 
5790  HSTMT_LOCK(stmt);
5791  ret = drvunimplstmt(stmt);
5792  HSTMT_UNLOCK(stmt);
5793  return ret;
5794 }
5795 
5796 #ifndef WINTERFACE
5797 
5801 SQLRETURN SQL_API
5802 SQLGetDescField(SQLHDESC handle, SQLSMALLINT recno,
5803  SQLSMALLINT fieldid, SQLPOINTER value,
5804  SQLINTEGER buflen, SQLINTEGER *strlen)
5805 {
5806  return SQL_ERROR;
5807 }
5808 #endif
5809 
5810 #ifdef WINTERFACE
5811 
5815 SQLRETURN SQL_API
5816 SQLGetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
5817  SQLSMALLINT fieldid, SQLPOINTER value,
5818  SQLINTEGER buflen, SQLINTEGER *strlen)
5819 {
5820  return SQL_ERROR;
5821 }
5822 #endif
5823 
5824 #ifndef WINTERFACE
5825 
5829 SQLRETURN SQL_API
5830 SQLSetDescField(SQLHDESC handle, SQLSMALLINT recno,
5831  SQLSMALLINT fieldid, SQLPOINTER value,
5832  SQLINTEGER buflen)
5833 {
5834  return SQL_ERROR;
5835 }
5836 #endif
5837 
5838 #ifdef WINTERFACE
5839 
5843 SQLRETURN SQL_API
5844 SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
5845  SQLSMALLINT fieldid, SQLPOINTER value,
5846  SQLINTEGER buflen)
5847 {
5848  return SQL_ERROR;
5849 }
5850 #endif
5851 
5852 #ifndef WINTERFACE
5853 
5857 SQLRETURN SQL_API
5858 SQLGetDescRec(SQLHDESC handle, SQLSMALLINT recno,
5859  SQLCHAR *name, SQLSMALLINT buflen,
5860  SQLSMALLINT *strlen, SQLSMALLINT *type,
5861  SQLSMALLINT *subtype, SQLLEN *len,
5862  SQLSMALLINT *prec, SQLSMALLINT *scale,
5863  SQLSMALLINT *nullable)
5864 {
5865  return SQL_ERROR;
5866 }
5867 #endif
5868 
5869 #ifdef WINTERFACE
5870 
5874 SQLRETURN SQL_API
5875 SQLGetDescRecW(SQLHDESC handle, SQLSMALLINT recno,
5876  SQLWCHAR *name, SQLSMALLINT buflen,
5877  SQLSMALLINT *strlen, SQLSMALLINT *type,
5878  SQLSMALLINT *subtype, SQLLEN *len,
5879  SQLSMALLINT *prec, SQLSMALLINT *scale,
5880  SQLSMALLINT *nullable)
5881 {
5882  return SQL_ERROR;
5883 }
5884 #endif
5885 
5890 SQLRETURN SQL_API
5891 SQLSetDescRec(SQLHDESC handle, SQLSMALLINT recno,
5892  SQLSMALLINT type, SQLSMALLINT subtype,
5893  SQLLEN len, SQLSMALLINT prec,
5894  SQLSMALLINT scale, SQLPOINTER data,
5895  SQLLEN *strlen, SQLLEN *indicator)
5896 {
5897  return SQL_ERROR;
5898 }
5899 
5911 static SQLRETURN
5912 mkresultset(HSTMT stmt, COL *colspec, int ncols, COL *colspec3,
5913  int ncols3, int *nret)
5914 {
5915  STMT *s;
5916  DBC *d;
5917 
5918  if (stmt == SQL_NULL_HSTMT) {
5919  return SQL_INVALID_HANDLE;
5920  }
5921  s = (STMT *) stmt;
5922  if (s->dbc == SQL_NULL_HDBC) {
5923 noconn:
5924  return noconn(s);
5925  }
5926  d = (DBC *) s->dbc;
5927  if (!d->sqlite) {
5928  goto noconn;
5929  }
5930  s3stmt_end_if(s);
5931  freeresult(s, 0);
5932  if (colspec3 && *s->ov3) {
5933  s->ncols = ncols3;
5934  s->cols = colspec3;
5935  } else {
5936  s->ncols = ncols;
5937  s->cols = colspec;
5938  }
5939  mkbindcols(s, s->ncols);
5940  s->nowchar[1] = 1;
5941  s->nrows = 0;
5942  s->rowp = s->rowprs = -1;
5943  s->isselect = -1;
5944  if (nret) {
5945  *nret = s->ncols;
5946  }
5947  return SQL_SUCCESS;
5948 }
5949 
5954 static COL tablePrivSpec2[] = {
5955  { "SYSTEM", "TABLEPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
5956  { "SYSTEM", "TABLEPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
5957  { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
5958  { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
5959  { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
5960  { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
5961  { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
5962 };
5963 
5964 static COL tablePrivSpec3[] = {
5965  { "SYSTEM", "TABLEPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
5966  { "SYSTEM", "TABLEPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
5967  { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
5968  { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
5969  { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
5970  { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
5971  { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
5972 };
5973 
5986 static SQLRETURN
5988  SQLCHAR *cat, SQLSMALLINT catLen,
5989  SQLCHAR *schema, SQLSMALLINT schemaLen,
5990  SQLCHAR *table, SQLSMALLINT tableLen)
5991 {
5992  SQLRETURN ret;
5993  STMT *s;
5994  DBC *d;
5995  int ncols, rc, size, npatt;
5996  char *errp = NULL, *sql, tname[512];
5997 
6000  if (ret != SQL_SUCCESS) {
6001  return ret;
6002  }
6003  s = (STMT *) stmt;
6004  d = (DBC *) s->dbc;
6005  if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
6006  table = NULL;
6007  goto doit;
6008  }
6009  if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
6010  schema[0] == '%') {
6011  if ((!cat || catLen == 0 || !cat[0]) &&
6012  (!table || tableLen == 0 || !table[0])) {
6013  table = NULL;
6014  goto doit;
6015  }
6016  }
6017 doit:
6018  if (!table) {
6019  size = 1;
6020  tname[0] = '%';
6021  } else {
6022  if (tableLen == SQL_NTS) {
6023  size = sizeof (tname) - 1;
6024  } else {
6025  size = min(sizeof (tname) - 1, tableLen);
6026  }
6027  strncpy(tname, (char *) table, size);
6028  }
6029  tname[size] = '\0';
6030  npatt = unescpat(tname);
6031 #if defined(_WIN32) || defined(_WIN64)
6032  sql = sqlite3_mprintf("select %s as 'TABLE_QUALIFIER', "
6033  "%s as 'TABLE_OWNER', "
6034  "tbl_name as 'TABLE_NAME', "
6035  "'' as 'GRANTOR', "
6036  "'' as 'GRANTEE', "
6037  "'SELECT' AS 'PRIVILEGE', "
6038  "NULL as 'IS_GRANTABLE' "
6039  "from sqlite_master where "
6040  "(type = 'table' or type = 'view') "
6041  "and tbl_name %s %Q "
6042  "UNION "
6043  "select %s as 'TABLE_QUALIFIER', "
6044  "%s as 'TABLE_OWNER', "
6045  "tbl_name as 'TABLE_NAME', "
6046  "'' as 'GRANTOR', "
6047  "'' as 'GRANTEE', "
6048  "'UPDATE' AS 'PRIVILEGE', "
6049  "NULL as 'IS_GRANTABLE' "
6050  "from sqlite_master where "
6051  "(type = 'table' or type = 'view') "
6052  "and tbl_name %s %Q "
6053  "UNION "
6054  "select %s as 'TABLE_QUALIFIER', "
6055  "%s as 'TABLE_OWNER', "
6056  "tbl_name as 'TABLE_NAME', "
6057  "'' as 'GRANTOR', "
6058  "'' as 'GRANTEE', "
6059  "'DELETE' AS 'PRIVILEGE', "
6060  "NULL as 'IS_GRANTABLE' "
6061  "from sqlite_master where "
6062  "(type = 'table' or type = 'view') "
6063  "and tbl_name %s %Q "
6064  "UNION "
6065  "select %s as 'TABLE_QUALIFIER', "
6066  "%s as 'TABLE_OWNER', "
6067  "tbl_name as 'TABLE_NAME', "
6068  "'' as 'GRANTOR', "
6069  "'' as 'GRANTEE', "
6070  "'INSERT' AS 'PRIVILEGE', "
6071  "NULL as 'IS_GRANTABLE' "
6072  "from sqlite_master where "
6073  "(type = 'table' or type = 'view') "
6074  "and tbl_name %s %Q "
6075  "UNION "
6076  "select %s as 'TABLE_QUALIFIER', "
6077  "%s as 'TABLE_OWNER', "
6078  "tbl_name as 'TABLE_NAME', "
6079  "'' as 'GRANTOR', "
6080  "'' as 'GRANTEE', "
6081  "'REFERENCES' AS 'PRIVILEGE', "
6082  "NULL as 'IS_GRANTABLE' "
6083  "from sqlite_master where "
6084  "(type = 'table' or type = 'view') "
6085  "and tbl_name %s %Q",
6086  d->xcelqrx ? "'main'" : "NULL",
6087  d->xcelqrx ? "''" : "NULL",
6088  npatt ? "like" : "=", tname,
6089  d->xcelqrx ? "'main'" : "NULL",
6090  d->xcelqrx ? "''" : "NULL",
6091  npatt ? "like" : "=", tname,
6092  d->xcelqrx ? "'main'" : "NULL",
6093  d->xcelqrx ? "''" : "NULL",
6094  npatt ? "like" : "=", tname,
6095  d->xcelqrx ? "'main'" : "NULL",
6096  d->xcelqrx ? "''" : "NULL",
6097  npatt ? "like" : "=", tname,
6098  d->xcelqrx ? "'main'" : "NULL",
6099  d->xcelqrx ? "''" : "NULL",
6100  npatt ? "like" : "=", tname);
6101 #else
6102  sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
6103  "NULL as 'TABLE_OWNER', "
6104  "tbl_name as 'TABLE_NAME', "
6105  "'' as 'GRANTOR', "
6106  "'' as 'GRANTEE', "
6107  "'SELECT' AS 'PRIVILEGE', "
6108  "NULL as 'IS_GRANTABLE' "
6109  "from sqlite_master where "
6110  "(type = 'table' or type = 'view') "
6111  "and tbl_name %s %Q "
6112  "UNION "
6113  "select NULL as 'TABLE_QUALIFIER', "
6114  "NULL as 'TABLE_OWNER', "
6115  "tbl_name as 'TABLE_NAME', "
6116  "'' as 'GRANTOR', "
6117  "'' as 'GRANTEE', "
6118  "'UPDATE' AS 'PRIVILEGE', "
6119  "NULL as 'IS_GRANTABLE' "
6120  "from sqlite_master where "
6121  "(type = 'table' or type = 'view') "
6122  "and tbl_name %s %Q "
6123  "UNION "
6124  "select NULL as 'TABLE_QUALIFIER', "
6125  "NULL as 'TABLE_OWNER', "
6126  "tbl_name as 'TABLE_NAME', "
6127  "'' as 'GRANTOR', "
6128  "'' as 'GRANTEE', "
6129  "'DELETE' AS 'PRIVILEGE', "
6130  "NULL as 'IS_GRANTABLE' "
6131  "from sqlite_master where "
6132  "(type = 'table' or type = 'view') "
6133  "and tbl_name %s %Q "
6134  "UNION "
6135  "select NULL as 'TABLE_QUALIFIER', "
6136  "NULL as 'TABLE_OWNER', "
6137  "tbl_name as 'TABLE_NAME', "
6138  "'' as 'GRANTOR', "
6139  "'' as 'GRANTEE', "
6140  "'INSERT' AS 'PRIVILEGE', "
6141  "NULL as 'IS_GRANTABLE' "
6142  "from sqlite_master where "
6143  "(type = 'table' or type = 'view') "
6144  "and tbl_name %s %Q "
6145  "UNION "
6146  "select NULL as 'TABLE_QUALIFIER', "
6147  "NULL as 'TABLE_OWNER', "
6148  "tbl_name as 'TABLE_NAME', "
6149  "'' as 'GRANTOR', "
6150  "'' as 'GRANTEE', "
6151  "'REFERENCES' AS 'PRIVILEGE', "
6152  "NULL as 'IS_GRANTABLE' "
6153  "from sqlite_master where "
6154  "(type = 'table' or type = 'view') "
6155  "and tbl_name %s %Q",
6156  npatt ? "like" : "=", tname,
6157  npatt ? "like" : "=", tname,
6158  npatt ? "like" : "=", tname,
6159  npatt ? "like" : "=", tname,
6160  npatt ? "like" : "=", tname);
6161 #endif
6162  if (!sql) {
6163  return nomem(s);
6164  }
6165  ret = starttran(s);
6166  if (ret != SQL_SUCCESS) {
6167  sqlite3_free(sql);
6168  return ret;
6169  }
6170  dbtraceapi(d, "sqlite3_get_table", sql);
6171  rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
6172  sqlite3_free(sql);
6173  if (rc == SQLITE_OK) {
6174  if (ncols != s->ncols) {
6175  freeresult(s, 0);
6176  s->nrows = 0;
6177  } else {
6178  s->rowfree = sqlite3_free_table;
6179  }
6180  } else {
6181  s->nrows = 0;
6182  s->rows = NULL;
6183  s->rowfree = NULL;
6184  }
6185  if (errp) {
6186  sqlite3_free(errp);
6187  errp = NULL;
6188  }
6189  s->rowp = s->rowprs = -1;
6190  return SQL_SUCCESS;
6191 }
6192 
6193 
6194 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
6195 
6207 SQLRETURN SQL_API
6208 SQLTablePrivileges(SQLHSTMT stmt,
6209  SQLCHAR *catalog, SQLSMALLINT catalogLen,
6210  SQLCHAR *schema, SQLSMALLINT schemaLen,
6211  SQLCHAR *table, SQLSMALLINT tableLen)
6212 {
6213 #if defined(_WIN32) || defined(_WIN64)
6214  char *c = NULL, *s = NULL, *t = NULL;
6215 #endif
6216  SQLRETURN ret;
6217 
6218  HSTMT_LOCK(stmt);
6219 #if defined(_WIN32) || defined(_WIN64)
6220  if (!((STMT *) stmt)->oemcp[0]) {
6221  ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
6222  table, tableLen);
6223  goto done2;
6224  }
6225  if (catalog) {
6226  c = wmb_to_utf_c((char *) catalog, catalogLen);
6227  if (!c) {
6228  ret = nomem((STMT *) stmt);
6229  goto done;
6230  }
6231  }
6232  if (schema) {
6233  s = wmb_to_utf_c((char *) schema, schemaLen);
6234  if (!s) {
6235  ret = nomem((STMT *) stmt);
6236  goto done;
6237  }
6238  }
6239  if (table) {
6240  t = wmb_to_utf_c((char *) table, tableLen);
6241  if (!t) {
6242  ret = nomem((STMT *) stmt);
6243  goto done;
6244  }
6245  }
6246  ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
6247  (SQLCHAR *) s, SQL_NTS,
6248  (SQLCHAR *) t, SQL_NTS);
6249 #else
6250  ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
6251  table, tableLen);
6252 #endif
6253 #if defined(_WIN32) || defined(_WIN64)
6254 done:
6255  uc_free(t);
6256  uc_free(s);
6257  uc_free(c);
6258 done2:
6259  ;
6260 #endif
6261  HSTMT_UNLOCK(stmt);
6262  return ret;
6263 }
6264 #endif
6265 
6266 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
6267 #ifdef WINTERFACE
6268 
6280 SQLRETURN SQL_API
6282  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
6283  SQLWCHAR *schema, SQLSMALLINT schemaLen,
6284  SQLWCHAR *table, SQLSMALLINT tableLen)
6285 {
6286  char *c = NULL, *s = NULL, *t = NULL;
6287  SQLRETURN ret;
6288 
6289  HSTMT_LOCK(stmt);
6290  if (catalog) {
6291  c = uc_to_utf_c(catalog, catalogLen);
6292  if (!c) {
6293  ret = nomem((STMT *) stmt);
6294  goto done;
6295  }
6296  }
6297  if (schema) {
6298  s = uc_to_utf_c(schema, schemaLen);
6299  if (!s) {
6300  ret = nomem((STMT *) stmt);
6301  goto done;
6302  }
6303  }
6304  if (table) {
6305  t = uc_to_utf_c(table, tableLen);
6306  if (!t) {
6307  ret = nomem((STMT *) stmt);
6308  goto done;
6309  }
6310  }
6311  ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
6312  (SQLCHAR *) s, SQL_NTS,
6313  (SQLCHAR *) t, SQL_NTS);
6314 done:
6315  uc_free(t);
6316  uc_free(s);
6317  uc_free(c);
6318  HSTMT_UNLOCK(stmt);
6319  return ret;
6320 }
6321 #endif
6322 #endif
6323 
6328 static COL colPrivSpec2[] = {
6329  { "SYSTEM", "COLPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
6330  { "SYSTEM", "COLPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
6331  { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6332  { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6333  { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6334  { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6335  { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
6336 };
6337 
6338 static COL colPrivSpec3[] = {
6339  { "SYSTEM", "COLPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
6340  { "SYSTEM", "COLPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
6341  { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6342  { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6343  { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6344  { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6345  { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
6346 };
6347 
6348 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
6349 
6363 SQLRETURN SQL_API
6364 SQLColumnPrivileges(SQLHSTMT stmt,
6365  SQLCHAR *catalog, SQLSMALLINT catalogLen,
6366  SQLCHAR *schema, SQLSMALLINT schemaLen,
6367  SQLCHAR *table, SQLSMALLINT tableLen,
6368  SQLCHAR *column, SQLSMALLINT columnLen)
6369 {
6370  SQLRETURN ret;
6371 
6372  HSTMT_LOCK(stmt);
6375  HSTMT_UNLOCK(stmt);
6376  return ret;
6377 }
6378 #endif
6379 
6380 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
6381 #ifdef WINTERFACE
6382 
6396 SQLRETURN SQL_API
6398  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
6399  SQLWCHAR *schema, SQLSMALLINT schemaLen,
6400  SQLWCHAR *table, SQLSMALLINT tableLen,
6401  SQLWCHAR *column, SQLSMALLINT columnLen)
6402 {
6403  SQLRETURN ret;
6404 
6405  HSTMT_LOCK(stmt);
6408  HSTMT_UNLOCK(stmt);
6409  return ret;
6410 }
6411 #endif
6412 #endif
6413 
6418 static COL pkeySpec2[] = {
6419  { "SYSTEM", "PRIMARYKEY", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
6420  { "SYSTEM", "PRIMARYKEY", "TABLE_OWNER", SCOL_VARCHAR, 50 },
6421  { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
6422  { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6423  { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
6424  { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
6425 };
6426 
6427 static COL pkeySpec3[] = {
6428  { "SYSTEM", "PRIMARYKEY", "TABLE_CAT", SCOL_VARCHAR, 50 },
6429  { "SYSTEM", "PRIMARYKEY", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
6430  { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
6431  { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6432  { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
6433  { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
6434 };
6435 
6448 static SQLRETURN
6450  SQLCHAR *cat, SQLSMALLINT catLen,
6451  SQLCHAR *schema, SQLSMALLINT schemaLen,
6452  SQLCHAR *table, SQLSMALLINT tableLen)
6453 {
6454  STMT *s;
6455  DBC *d;
6456  SQLRETURN sret;
6457  int i, asize, ret, nrows, ncols, nrows2 = 0, ncols2 = 0;
6458  int namec = -1, uniquec = -1, namec2 = -1, uniquec2 = -1, offs, seq = 1;
6459  PTRDIFF_T size;
6460  char **rowp = NULL, **rowp2 = NULL, *errp = NULL, *sql, tname[512];
6461 
6463  pkeySpec3, array_size(pkeySpec3), &asize);
6464  if (sret != SQL_SUCCESS) {
6465  return sret;
6466  }
6467  s = (STMT *) stmt;
6468  d = (DBC *) s->dbc;
6469  if (!table || table[0] == '\0' || table[0] == '%') {
6470  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
6471  return SQL_ERROR;
6472  }
6473  if (tableLen == SQL_NTS) {
6474  size = sizeof (tname) - 1;
6475  } else {
6476  size = min(sizeof (tname) - 1, tableLen);
6477  }
6478  strncpy(tname, (char *) table, size);
6479  tname[size] = '\0';
6480  unescpat(tname);
6481  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
6482  if (!sql) {
6483  return nomem(s);
6484  }
6485  sret = starttran(s);
6486  if (sret != SQL_SUCCESS) {
6487  sqlite3_free(sql);
6488  return sret;
6489  }
6490  dbtraceapi(d, "sqlite3_get_table", sql);
6491  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
6492  sqlite3_free(sql);
6493  if (ret != SQLITE_OK) {
6494  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6495  errp ? errp : "unknown error", ret);
6496  if (errp) {
6497  sqlite3_free(errp);
6498  errp = NULL;
6499  }
6500  return SQL_ERROR;
6501  }
6502  if (errp) {
6503  sqlite3_free(errp);
6504  errp = NULL;
6505  }
6506  size = 0;
6507  if (ncols * nrows > 0) {
6508  int typec;
6509 
6510  namec = findcol(rowp, ncols, "name");
6511  uniquec = findcol(rowp, ncols, "pk");
6512  typec = findcol(rowp, ncols, "type");
6513  if (namec >= 0 && uniquec >= 0 && typec >= 0) {
6514  for (i = 1; i <= nrows; i++) {
6515  if (*rowp[i * ncols + uniquec] != '0') {
6516  size++;
6517  }
6518  }
6519  }
6520  }
6521  if (size == 0) {
6522  sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
6523  if (!sql) {
6524  sqlite3_free_table(rowp);
6525  return nomem(s);
6526  }
6527  dbtraceapi(d, "sqlite3_get_table", sql);
6528  ret = sqlite3_get_table(d->sqlite, sql, &rowp2, &nrows2, &ncols2,
6529  &errp);
6530  sqlite3_free(sql);
6531  if (ret != SQLITE_OK) {
6532  sqlite3_free_table(rowp);
6533  sqlite3_free_table(rowp2);
6534  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6535  errp ? errp : "unknown error", ret);
6536  if (errp) {
6537  sqlite3_free(errp);
6538  errp = NULL;
6539  }
6540  return SQL_ERROR;
6541  }
6542  if (errp) {
6543  sqlite3_free(errp);
6544  errp = NULL;
6545  }
6546  }
6547  if (ncols2 * nrows2 > 0) {
6548  namec2 = findcol(rowp2, ncols2, "name");
6549  uniquec2 = findcol(rowp2, ncols2, "unique");
6550  if (namec2 >= 0 && uniquec2 >= 0) {
6551  for (i = 1; i <= nrows2; i++) {
6552  int nnrows, nncols, nlen = 0;
6553  char **rowpp;
6554 
6555  if (rowp2[i * ncols2 + namec2]) {
6556  nlen = strlen(rowp2[i * ncols2 + namec2]);
6557  }
6558  if (nlen < 17 ||
6559  strncmp(rowp2[i * ncols2 + namec2],
6560  "sqlite_autoindex_", 17)) {
6561  continue;
6562  }
6563  if (*rowp2[i * ncols2 + uniquec2] != '0') {
6564  ret = SQLITE_ERROR;
6565  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6566  rowp2[i * ncols2 + namec2]);
6567  if (sql) {
6568  dbtraceapi(d, "sqlite3_get_table", sql);
6569  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6570  &nnrows, &nncols, NULL);
6571  sqlite3_free(sql);
6572  }
6573  if (ret == SQLITE_OK) {
6574  size += nnrows;
6575  sqlite3_free_table(rowpp);
6576  }
6577  }
6578  }
6579  }
6580  }
6581  if (size == 0) {
6582  sqlite3_free_table(rowp);
6583  sqlite3_free_table(rowp2);
6584  return SQL_SUCCESS;
6585  }
6586  s->nrows = size;
6587  size = (size + 1) * asize;
6588  s->rows = xmalloc((size + 1) * sizeof (char *));
6589  if (!s->rows) {
6590  s->nrows = 0;
6591  sqlite3_free_table(rowp);
6592  sqlite3_free_table(rowp2);
6593  return nomem(s);
6594  }
6595  s->rows[0] = (char *) size;
6596  s->rows += 1;
6597  memset(s->rows, 0, sizeof (char *) * size);
6598  s->rowfree = freerows;
6599  offs = s->ncols;
6600  if (rowp) {
6601  for (i = 1; i <= nrows; i++) {
6602  if (*rowp[i * ncols + uniquec] != '0') {
6603  char buf[32];
6604 
6605 #if defined(_WIN32) || defined(_WIN64)
6606  s->rows[offs + 0] = xstrdup(d->xcelqrx ? "main" : "");
6607  s->rows[offs + 1] = xstrdup("");
6608 #else
6609  s->rows[offs + 0] = xstrdup("");
6610  s->rows[offs + 1] = xstrdup("");
6611 #endif
6612  s->rows[offs + 2] = xstrdup(tname);
6613  s->rows[offs + 3] = xstrdup(rowp[i * ncols + namec]);
6614  sprintf(buf, "%d", seq++);
6615  s->rows[offs + 4] = xstrdup(buf);
6616  offs += s->ncols;
6617  }
6618  }
6619  }
6620  if (rowp2) {
6621  for (i = 1; i <= nrows2; i++) {
6622  int nnrows, nncols, nlen = 0;
6623  char **rowpp;
6624 
6625  if (rowp2[i * ncols2 + namec2]) {
6626  nlen = strlen(rowp2[i * ncols2 + namec2]);
6627  }
6628  if (nlen < 17 ||
6629  strncmp(rowp2[i * ncols2 + namec2], "sqlite_autoindex_", 17)) {
6630  continue;
6631  }
6632  if (*rowp2[i * ncols2 + uniquec2] != '0') {
6633  int k;
6634 
6635  ret = SQLITE_ERROR;
6636  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6637  rowp2[i * ncols2 + namec2]);
6638  if (sql) {
6639  dbtraceapi(d, "sqlite3_get_table", sql);
6640  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6641  &nnrows, &nncols, NULL);
6642  sqlite3_free(sql);
6643  }
6644  if (ret != SQLITE_OK) {
6645  continue;
6646  }
6647  for (k = 0; nnrows && k < nncols; k++) {
6648  if (strcmp(rowpp[k], "name") == 0) {
6649  int m;
6650 
6651  for (m = 1; m <= nnrows; m++) {
6652  int roffs = offs + (m - 1) * s->ncols;
6653 
6654 #if defined(_WIN32) || defined(_WIN64)
6655  s->rows[roffs + 0] =
6656  xstrdup(d->xcelqrx ? "main" : "");
6657  s->rows[roffs + 1] = xstrdup("");
6658 #else
6659  s->rows[roffs + 0] = xstrdup("");
6660  s->rows[roffs + 1] = xstrdup("");
6661 #endif
6662  s->rows[roffs + 2] = xstrdup(tname);
6663  s->rows[roffs + 3] =
6664  xstrdup(rowpp[m * nncols + k]);
6665  s->rows[roffs + 5] =
6666  xstrdup(rowp2[i * ncols2 + namec2]);
6667  }
6668  } else if (strcmp(rowpp[k], "seqno") == 0) {
6669  int m;
6670 
6671  for (m = 1; m <= nnrows; m++) {
6672  int roffs = offs + (m - 1) * s->ncols;
6673  int pos = m - 1;
6674  char buf[32];
6675 
6676  sscanf(rowpp[m * nncols + k], "%d", &pos);
6677  sprintf(buf, "%d", pos + 1);
6678  s->rows[roffs + 4] = xstrdup(buf);
6679  }
6680  }
6681  }
6682  offs += nnrows * s->ncols;
6683  sqlite3_free_table(rowpp);
6684  }
6685  }
6686  }
6687  sqlite3_free_table(rowp);
6688  sqlite3_free_table(rowp2);
6689  return SQL_SUCCESS;
6690 }
6691 
6692 #ifndef WINTERFACE
6693 
6705 SQLRETURN SQL_API
6706 SQLPrimaryKeys(SQLHSTMT stmt,
6707  SQLCHAR *cat, SQLSMALLINT catLen,
6708  SQLCHAR *schema, SQLSMALLINT schemaLen,
6709  SQLCHAR *table, SQLSMALLINT tableLen)
6710 {
6711 #if defined(_WIN32) || defined(_WIN64)
6712  char *c = NULL, *s = NULL, *t = NULL;
6713 #endif
6714  SQLRETURN ret;
6715 
6716  HSTMT_LOCK(stmt);
6717 #if defined(_WIN32) || defined(_WIN64)
6718  if (!((STMT *) stmt)->oemcp[0]) {
6719  ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
6720  table, tableLen);
6721  goto done2;
6722  }
6723  if (cat) {
6724  c = wmb_to_utf_c((char *) cat, catLen);
6725  if (!c) {
6726  ret = nomem((STMT *) stmt);
6727  goto done;
6728  }
6729  }
6730  if (schema) {
6731  s = wmb_to_utf_c((char *) schema, schemaLen);
6732  if (!s) {
6733  ret = nomem((STMT *) stmt);
6734  goto done;
6735  }
6736  }
6737  if (table) {
6738  t = wmb_to_utf_c((char *) table, tableLen);
6739  if (!t) {
6740  ret = nomem((STMT *) stmt);
6741  goto done;
6742  }
6743  }
6744  ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
6745  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
6746 #else
6747  ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
6748  table, tableLen);
6749 #endif
6750 #if defined(_WIN32) || defined(_WIN64)
6751 done:
6752  uc_free(t);
6753  uc_free(s);
6754  uc_free(c);
6755 done2:
6756  ;
6757 #endif
6758  HSTMT_UNLOCK(stmt);
6759  return ret;
6760 }
6761 #endif
6762 
6763 #ifdef WINTERFACE
6764 
6776 SQLRETURN SQL_API
6778  SQLWCHAR *cat, SQLSMALLINT catLen,
6779  SQLWCHAR *schema, SQLSMALLINT schemaLen,
6780  SQLWCHAR *table, SQLSMALLINT tableLen)
6781 {
6782  char *c = NULL, *s = NULL, *t = NULL;
6783  SQLRETURN ret;
6784 
6785  HSTMT_LOCK(stmt);
6786  if (cat) {
6787  c = uc_to_utf_c(cat, catLen);
6788  if (!c) {
6789  ret = nomem((STMT *) stmt);
6790  goto done;
6791  }
6792  }
6793  if (schema) {
6794  s = uc_to_utf_c(schema, schemaLen);
6795  if (!s) {
6796  ret = nomem((STMT *) stmt);
6797  goto done;
6798  }
6799  }
6800  if (table) {
6801  t = uc_to_utf_c(table, tableLen);
6802  if (!t) {
6803  ret = nomem((STMT *) stmt);
6804  goto done;
6805  }
6806  }
6807  ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
6808  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
6809 done:
6810  uc_free(t);
6811  uc_free(s);
6812  uc_free(c);
6813  HSTMT_UNLOCK(stmt);
6814  return ret;
6815 }
6816 #endif
6817 
6822 static COL scolSpec2[] = {
6823  { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
6824  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6825  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
6826  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
6827  { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
6828  { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
6829  { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
6830  { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
6831  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
6832 };
6833 
6834 static COL scolSpec3[] = {
6835  { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
6836  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6837  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
6838  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
6839  { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
6840  { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
6841  { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
6842  { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
6843  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
6844 };
6845 
6861 static SQLRETURN
6862 drvspecialcolumns(SQLHSTMT stmt, SQLUSMALLINT id,
6863  SQLCHAR *cat, SQLSMALLINT catLen,
6864  SQLCHAR *schema, SQLSMALLINT schemaLen,
6865  SQLCHAR *table, SQLSMALLINT tableLen,
6866  SQLUSMALLINT scope, SQLUSMALLINT nullable)
6867 {
6868  STMT *s;
6869  DBC *d;
6870  SQLRETURN sret;
6871  int i, asize, ret, nrows, ncols, nnnrows, nnncols, offs;
6872  PTRDIFF_T size;
6873  int namec = -1, uniquec = -1, namecc = -1, typecc = -1;
6874  int notnullcc = -1, mkrowid = 0;
6875  char *errp = NULL, *sql, tname[512];
6876  char **rowp = NULL, **rowppp = NULL;
6877 
6879  scolSpec3, array_size(scolSpec3), &asize);
6880  if (sret != SQL_SUCCESS) {
6881  return sret;
6882  }
6883  s = (STMT *) stmt;
6884  d = (DBC *) s->dbc;
6885  if (!table || table[0] == '\0' || table[0] == '%') {
6886  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
6887  return SQL_ERROR;
6888  }
6889  if (tableLen == SQL_NTS) {
6890  size = sizeof (tname) - 1;
6891  } else {
6892  size = min(sizeof (tname) - 1, tableLen);
6893  }
6894  strncpy(tname, (char *) table, size);
6895  tname[size] = '\0';
6896  unescpat(tname);
6897  if (id != SQL_BEST_ROWID) {
6898  return SQL_SUCCESS;
6899  }
6900  sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
6901  if (!sql) {
6902  return nomem(s);
6903  }
6904  sret = starttran(s);
6905  if (sret != SQL_SUCCESS) {
6906  sqlite3_free(sql);
6907  return sret;
6908  }
6909  dbtraceapi(d, "sqlite3_get_table", sql);
6910  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
6911  sqlite3_free(sql);
6912  if (ret != SQLITE_OK) {
6913 doerr:
6914  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6915  errp ? errp : "unknown error", ret);
6916  if (errp) {
6917  sqlite3_free(errp);
6918  errp = NULL;
6919  }
6920  return SQL_ERROR;
6921  }
6922  if (errp) {
6923  sqlite3_free(errp);
6924  errp = NULL;
6925  }
6926  size = 0; /* number result rows */
6927  if (ncols * nrows <= 0) {
6928  goto nodata_but_rowid;
6929  }
6930  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
6931  if (!sql) {
6932  return nomem(s);
6933  }
6934  dbtraceapi(d, "sqlite3_get_table", sql);
6935  ret = sqlite3_get_table(d->sqlite, sql, &rowppp, &nnnrows, &nnncols,
6936  &errp);
6937  sqlite3_free(sql);
6938  if (ret != SQLITE_OK) {
6939  sqlite3_free_table(rowp);
6940  goto doerr;
6941  }
6942  if (errp) {
6943  sqlite3_free(errp);
6944  errp = NULL;
6945  }
6946  namec = findcol(rowp, ncols, "name");
6947  uniquec = findcol(rowp, ncols, "unique");
6948  if (namec < 0 || uniquec < 0) {
6949  goto nodata_but_rowid;
6950  }
6951  namecc = findcol(rowppp, nnncols, "name");
6952  typecc = findcol(rowppp, nnncols, "type");
6953  notnullcc = findcol(rowppp, nnncols, "notnull");
6954  for (i = 1; i <= nrows; i++) {
6955  int nnrows, nncols;
6956  char **rowpp = NULL;
6957 
6958  if (*rowp[i * ncols + uniquec] != '0') {
6959  ret = SQLITE_ERROR;
6960  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6961  rowp[i * ncols + namec]);
6962  if (sql) {
6963  dbtraceapi(d, "sqlite3_get_table", sql);
6964  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6965  &nnrows, &nncols, NULL);
6966  sqlite3_free(sql);
6967  }
6968  if (ret == SQLITE_OK) {
6969  size += nnrows;
6970  sqlite3_free_table(rowpp);
6971  }
6972  }
6973  }
6974 nodata_but_rowid:
6975  if (size == 0) {
6976  size = 1;
6977  mkrowid = 1;
6978  }
6979  s->nrows = size;
6980  size = (size + 1) * asize;
6981  s->rows = xmalloc((size + 1) * sizeof (char *));
6982  if (!s->rows) {
6983  s->nrows = 0;
6984  sqlite3_free_table(rowp);
6985  sqlite3_free_table(rowppp);
6986  return nomem(s);
6987  }
6988  s->rows[0] = (char *) size;
6989  s->rows += 1;
6990  memset(s->rows, 0, sizeof (char *) * size);
6991  s->rowfree = freerows;
6992  if (mkrowid) {
6993  s->nrows = 0;
6994  goto mkrowid;
6995  }
6996  offs = 0;
6997  for (i = 1; i <= nrows; i++) {
6998  int nnrows, nncols;
6999  char **rowpp = NULL;
7000 
7001  if (*rowp[i * ncols + uniquec] != '0') {
7002  int k;
7003 
7004  ret = SQLITE_ERROR;
7005  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
7006  rowp[i * ncols + namec]);
7007  if (sql) {
7008  dbtraceapi(d, "sqlite3_get_table", sql);
7009  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7010  &nnrows, &nncols, NULL);
7011  sqlite3_free(sql);
7012  }
7013  if (ret != SQLITE_OK) {
7014  continue;
7015  }
7016  for (k = 0; nnrows && k < nncols; k++) {
7017  if (strcmp(rowpp[k], "name") == 0) {
7018  int m;
7019 
7020  for (m = 1; m <= nnrows; m++) {
7021  int roffs = (offs + m) * s->ncols;
7022 
7023  s->rows[roffs + 0] =
7024  xstrdup(stringify(SQL_SCOPE_SESSION));
7025  s->rows[roffs + 1] = xstrdup(rowpp[m * nncols + k]);
7026  s->rows[roffs + 4] = xstrdup("0");
7027  s->rows[roffs + 7] =
7028  xstrdup(stringify(SQL_PC_NOT_PSEUDO));
7029  if (namecc >= 0 && typecc >= 0) {
7030  int ii;
7031 
7032  for (ii = 1; ii <= nnnrows; ii++) {
7033  if (strcmp(rowppp[ii * nnncols + namecc],
7034  rowpp[m * nncols + k]) == 0) {
7035  char *typen = rowppp[ii * nnncols + typecc];
7036  int sqltype, mm, dd, isnullable = 0;
7037  char buf[32];
7038 
7039  s->rows[roffs + 3] = xstrdup(typen);
7040  sqltype = mapsqltype(typen, NULL, *s->ov3,
7041  s->nowchar[0],
7042  s->dobigint);
7043  getmd(typen, sqltype, &mm, &dd);
7044 #ifdef SQL_LONGVARCHAR
7045  if (sqltype == SQL_VARCHAR && mm > 255) {
7046  sqltype = SQL_LONGVARCHAR;
7047  }
7048 #endif
7049 #ifdef WINTERFACE
7050 #ifdef SQL_WLONGVARCHAR
7051  if (sqltype == SQL_WVARCHAR && mm > 255) {
7052  sqltype = SQL_WLONGVARCHAR;
7053  }
7054 #endif
7055 #endif
7056  if (sqltype == SQL_VARBINARY && mm > 255) {
7057  sqltype = SQL_LONGVARBINARY;
7058  }
7059  sprintf(buf, "%d", sqltype);
7060  s->rows[roffs + 2] = xstrdup(buf);
7061  sprintf(buf, "%d", mm);
7062  s->rows[roffs + 5] = xstrdup(buf);
7063  sprintf(buf, "%d", dd);
7064  s->rows[roffs + 6] = xstrdup(buf);
7065  if (notnullcc >= 0) {
7066  char *inp =
7067  rowppp[ii * nnncols + notnullcc];
7068 
7069  isnullable = inp[0] != '0';
7070  }
7071  sprintf(buf, "%d", isnullable);
7072  s->rows[roffs + 8] = xstrdup(buf);
7073  }
7074  }
7075  }
7076  }
7077  }
7078  }
7079  offs += nnrows;
7080  sqlite3_free_table(rowpp);
7081  }
7082  }
7083  if (nullable == SQL_NO_NULLS) {
7084  for (i = 1; i < s->nrows; i++) {
7085  if (s->rows[i * s->ncols + 8][0] == '0') {
7086  int m, i1 = i + 1;
7087 
7088  for (m = 0; m < s->ncols; m++) {
7089  freep(&s->rows[i * s->ncols + m]);
7090  }
7091  size = s->ncols * sizeof (char *) * (s->nrows - i1);
7092  if (size > 0) {
7093  memmove(s->rows + i * s->ncols,
7094  s->rows + i1 * s->ncols,
7095  size);
7096  memset(s->rows + s->nrows * s->ncols, 0,
7097  s->ncols * sizeof (char *));
7098  }
7099  s->nrows--;
7100  --i;
7101  }
7102  }
7103  }
7104 mkrowid:
7105  sqlite3_free_table(rowp);
7106  sqlite3_free_table(rowppp);
7107  if (s->nrows == 0) {
7108  s->rows[s->ncols + 0] = xstrdup(stringify(SQL_SCOPE_SESSION));
7109  s->rows[s->ncols + 1] = xstrdup("_ROWID_");
7110  s->rows[s->ncols + 2] = xstrdup(stringify(SQL_INTEGER));
7111  s->rows[s->ncols + 3] = xstrdup("integer");
7112  s->rows[s->ncols + 4] = xstrdup("0");
7113  s->rows[s->ncols + 5] = xstrdup("10");
7114  s->rows[s->ncols + 6] = xstrdup("9");
7115  s->rows[s->ncols + 7] = xstrdup(stringify(SQL_PC_PSEUDO));
7116  s->rows[s->ncols + 8] = xstrdup(stringify(SQL_FALSE));
7117  s->nrows = 1;
7118  }
7119  return SQL_SUCCESS;
7120 }
7121 
7122 #ifndef WINTERFACE
7123 
7138 SQLRETURN SQL_API
7139 SQLSpecialColumns(SQLHSTMT stmt, SQLUSMALLINT id,
7140  SQLCHAR *cat, SQLSMALLINT catLen,
7141  SQLCHAR *schema, SQLSMALLINT schemaLen,
7142  SQLCHAR *table, SQLSMALLINT tableLen,
7143  SQLUSMALLINT scope, SQLUSMALLINT nullable)
7144 {
7145 #if defined(_WIN32) || defined(_WIN64)
7146  char *c = NULL, *s = NULL, *t = NULL;
7147 #endif
7148  SQLRETURN ret;
7149 
7150  HSTMT_LOCK(stmt);
7151 #if defined(_WIN32) || defined(_WIN64)
7152  if (!((STMT *) stmt)->oemcp[0]) {
7153  ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
7154  table, tableLen, scope, nullable);
7155  goto done2;
7156  }
7157  if (cat) {
7158  c = wmb_to_utf_c((char *) cat, catLen);
7159  if (!c) {
7160  ret = nomem((STMT *) stmt);
7161  goto done;
7162  }
7163  }
7164  if (schema) {
7165  s = wmb_to_utf_c((char *) schema, schemaLen);
7166  if (!s) {
7167  ret = nomem((STMT *) stmt);
7168  goto done;
7169  }
7170  }
7171  if (table) {
7172  t = wmb_to_utf_c((char *) table, tableLen);
7173  if (!t) {
7174  ret = nomem((STMT *) stmt);
7175  goto done;
7176  }
7177  }
7178  ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
7179  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
7180  scope, nullable);
7181 #else
7182  ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
7183  table, tableLen, scope, nullable);
7184 #endif
7185 #if defined(_WIN32) || defined(_WIN64)
7186 done:
7187  uc_free(t);
7188  uc_free(s);
7189  uc_free(c);
7190 done2:
7191  ;
7192 #endif
7193  HSTMT_UNLOCK(stmt);
7194  return ret;
7195 }
7196 #endif
7197 
7198 #ifdef WINTERFACE
7199 
7214 SQLRETURN SQL_API
7215 SQLSpecialColumnsW(SQLHSTMT stmt, SQLUSMALLINT id,
7216  SQLWCHAR *cat, SQLSMALLINT catLen,
7217  SQLWCHAR *schema, SQLSMALLINT schemaLen,
7218  SQLWCHAR *table, SQLSMALLINT tableLen,
7219  SQLUSMALLINT scope, SQLUSMALLINT nullable)
7220 {
7221  char *c = NULL, *s = NULL, *t = NULL;
7222  SQLRETURN ret;
7223 
7224  HSTMT_LOCK(stmt);
7225  if (cat) {
7226  c = uc_to_utf_c(cat, catLen);
7227  if (!c) {
7228  ret = nomem((STMT *) stmt);
7229  goto done;
7230  }
7231  }
7232  if (schema) {
7233  s = uc_to_utf_c(schema, schemaLen);
7234  if (!s) {
7235  ret = nomem((STMT *) stmt);
7236  goto done;
7237  }
7238  }
7239  if (table) {
7240  t = uc_to_utf_c(table, tableLen);
7241  if (!t) {
7242  ret = nomem((STMT *) stmt);
7243  goto done;
7244  }
7245  }
7246  ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
7247  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
7248  scope, nullable);
7249 done:
7250  uc_free(t);
7251  uc_free(s);
7252  uc_free(c);
7253  HSTMT_UNLOCK(stmt);
7254  return ret;
7255 }
7256 #endif
7257 
7262 static COL fkeySpec2[] = {
7263  { "SYSTEM", "FOREIGNKEY", "PKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
7264  { "SYSTEM", "FOREIGNKEY", "PKTABLE_OWNER", SCOL_VARCHAR, 50 },
7265  { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
7266  { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7267  { "SYSTEM", "FOREIGNKEY", "FKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
7268  { "SYSTEM", "FOREIGNKEY", "FKTABLE_OWNER", SCOL_VARCHAR, 50 },
7269  { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
7270  { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7271  { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
7272  { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
7273  { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
7274  { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
7275  { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
7276  { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
7277 };
7278 
7279 static COL fkeySpec3[] = {
7280  { "SYSTEM", "FOREIGNKEY", "PKTABLE_CAT", SCOL_VARCHAR, 50 },
7281  { "SYSTEM", "FOREIGNKEY", "PKTABLE_SCHEM", SCOL_VARCHAR, 50 },
7282  { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
7283  { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7284  { "SYSTEM", "FOREIGNKEY", "FKTABLE_CAT", SCOL_VARCHAR, 50 },
7285  { "SYSTEM", "FOREIGNKEY", "FKTABLE_SCHEM", SCOL_VARCHAR, 50 },
7286  { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
7287  { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7288  { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
7289  { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
7290  { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
7291  { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
7292  { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
7293  { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
7294 };
7295 
7314 static SQLRETURN SQL_API
7316  SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7317  SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
7318  SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
7319  SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7320  SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
7321  SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
7322 {
7323  STMT *s;
7324  DBC *d;
7325  SQLRETURN sret;
7326  int i, asize, ret, nrows, ncols, offs, namec, seqc, fromc, toc;
7327  int onu, ond;
7328  PTRDIFF_T size;
7329  char **rowp, *errp = NULL, *sql, pname[512], fname[512];
7330 
7332  fkeySpec3, array_size(fkeySpec3), &asize);
7333  if (sret != SQL_SUCCESS) {
7334  return sret;
7335  }
7336  s = (STMT *) stmt;
7337  sret = starttran(s);
7338  if (sret != SQL_SUCCESS) {
7339  return sret;
7340  }
7341  d = (DBC *) s->dbc;
7342  if ((!PKtable || PKtable[0] == '\0' || PKtable[0] == '%') &&
7343  (!FKtable || FKtable[0] == '\0' || FKtable[0] == '%')) {
7344  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
7345  return SQL_ERROR;
7346  }
7347  size = 0;
7348  if (PKtable) {
7349  if (PKtableLen == SQL_NTS) {
7350  size = sizeof (pname) - 1;
7351  } else {
7352  size = min(sizeof (pname) - 1, PKtableLen);
7353  }
7354  strncpy(pname, (char *) PKtable, size);
7355  }
7356  pname[size] = '\0';
7357  size = 0;
7358  if (FKtable) {
7359 
7360  if (FKtableLen == SQL_NTS) {
7361  size = sizeof (fname) - 1;
7362  } else {
7363  size = min(sizeof (fname) - 1, FKtableLen);
7364  }
7365  strncpy(fname, (char *) FKtable, size);
7366  }
7367  fname[size] = '\0';
7368  if (fname[0] != '\0') {
7369  int plen;
7370 
7371  ret = SQLITE_ERROR;
7372  sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", fname);
7373  if (sql) {
7374  dbtraceapi(d, "sqlite3_get_table", sql);
7375  ret = sqlite3_get_table(d->sqlite, sql, &rowp,
7376  &nrows, &ncols, &errp);
7377  sqlite3_free(sql);
7378  }
7379  if (ret != SQLITE_OK) {
7380  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7381  errp ? errp : "unknown error", ret);
7382  if (errp) {
7383  sqlite3_free(errp);
7384  errp = NULL;
7385  }
7386  return SQL_ERROR;
7387  }
7388  if (errp) {
7389  sqlite3_free(errp);
7390  errp = NULL;
7391  }
7392  if (ncols * nrows <= 0) {
7393 nodata:
7394  sqlite3_free_table(rowp);
7395  return SQL_SUCCESS;
7396  }
7397  size = 0;
7398  namec = findcol(rowp, ncols, "table");
7399  seqc = findcol(rowp, ncols, "seq");
7400  fromc = findcol(rowp, ncols, "from");
7401  toc = findcol(rowp, ncols, "to");
7402  onu = findcol(rowp, ncols, "on_update");
7403  ond = findcol(rowp, ncols, "on_delete");
7404  if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7405  goto nodata;
7406  }
7407  plen = strlen(pname);
7408  for (i = 1; i <= nrows; i++) {
7409  char *ptab = unquote(rowp[i * ncols + namec]);
7410 
7411  if (plen && ptab) {
7412  int len = strlen(ptab);
7413 
7414  if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
7415  continue;
7416  }
7417  }
7418  size++;
7419  }
7420  if (size == 0) {
7421  goto nodata;
7422  }
7423  s->nrows = size;
7424  size = (size + 1) * asize;
7425  s->rows = xmalloc((size + 1) * sizeof (char *));
7426  if (!s->rows) {
7427  s->nrows = 0;
7428  return nomem(s);
7429  }
7430  s->rows[0] = (char *) size;
7431  s->rows += 1;
7432  memset(s->rows, 0, sizeof (char *) * size);
7433  s->rowfree = freerows;
7434  offs = 0;
7435  for (i = 1; i <= nrows; i++) {
7436  int pos = 0, roffs = (offs + 1) * s->ncols;
7437  char *ptab = rowp[i * ncols + namec];
7438  char buf[32];
7439 
7440  if (plen && ptab) {
7441  int len = strlen(ptab);
7442 
7443  if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
7444  continue;
7445  }
7446  }
7447 #if defined(_WIN32) || defined(_WIN64)
7448  s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
7449  s->rows[roffs + 1] = xstrdup("");
7450 #else
7451  s->rows[roffs + 0] = xstrdup("");
7452  s->rows[roffs + 1] = xstrdup("");
7453 #endif
7454  s->rows[roffs + 2] = xstrdup(ptab);
7455  s->rows[roffs + 3] = xstrdup(rowp[i * ncols + toc]);
7456  s->rows[roffs + 4] = xstrdup("");
7457  s->rows[roffs + 5] = xstrdup("");
7458  s->rows[roffs + 6] = xstrdup(fname);
7459  s->rows[roffs + 7] = xstrdup(rowp[i * ncols + fromc]);
7460  sscanf(rowp[i * ncols + seqc], "%d", &pos);
7461  sprintf(buf, "%d", pos + 1);
7462  s->rows[roffs + 8] = xstrdup(buf);
7463  if (onu < 0) {
7464  s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7465  } else {
7466  if (strcmp(rowp[i * ncols + onu], "SET NULL") == 0) {
7467  s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
7468  } else if (strcmp(rowp[i * ncols + onu], "SET DEFAULT") == 0) {
7469  s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_DEFAULT));
7470  } else if (strcmp(rowp[i * ncols + onu], "CASCADE") == 0) {
7471  s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
7472  } else if (strcmp(rowp[i * ncols + onu], "RESTRICT") == 0) {
7473  s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
7474  } else {
7475  s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7476  }
7477  }
7478  if (ond < 0) {
7479  s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7480  } else {
7481  if (strcmp(rowp[i * ncols + ond], "SET NULL") == 0) {
7482  s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
7483  } else if (strcmp(rowp[i * ncols + ond], "SET DEFAULT") == 0) {
7484  s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_DEFAULT));
7485  } else if (strcmp(rowp[i * ncols + ond], "CASCADE") == 0) {
7486  s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
7487  } else if (strcmp(rowp[i * ncols + ond], "RESTRICT") == 0) {
7488  s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
7489  } else {
7490  s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7491  }
7492  }
7493  s->rows[roffs + 11] = NULL;
7494  s->rows[roffs + 12] = NULL;
7495  s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
7496  offs++;
7497  }
7498  sqlite3_free_table(rowp);
7499  } else {
7500  int nnrows, nncols, plen = strlen(pname);
7501  char **rowpp;
7502 
7503  sql = "select name from sqlite_master where type='table'";
7504  dbtraceapi(d, "sqlite3_get_table", sql);
7505  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
7506  if (ret != SQLITE_OK) {
7507  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7508  errp ? errp : "unknown error", ret);
7509  if (errp) {
7510  sqlite3_free(errp);
7511  errp = NULL;
7512  }
7513  return SQL_ERROR;
7514  }
7515  if (errp) {
7516  sqlite3_free(errp);
7517  errp = NULL;
7518  }
7519  if (ncols * nrows <= 0) {
7520  goto nodata;
7521  }
7522  size = 0;
7523  for (i = 1; i <= nrows; i++) {
7524  int k;
7525 
7526  if (!rowp[i]) {
7527  continue;
7528  }
7529  rowpp = NULL;
7530  ret = SQLITE_ERROR;
7531  sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
7532  if (sql) {
7533  dbtraceapi(d, "sqlite3_get_table", sql);
7534  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7535  &nnrows, &nncols, NULL);
7536  sqlite3_free(sql);
7537  }
7538  if (ret != SQLITE_OK || nncols * nnrows <= 0) {
7539  sqlite3_free_table(rowpp);
7540  continue;
7541  }
7542  namec = findcol(rowpp, nncols, "table");
7543  seqc = findcol(rowpp, nncols, "seq");
7544  fromc = findcol(rowpp, nncols, "from");
7545  toc = findcol(rowpp, nncols, "to");
7546  if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7547  sqlite3_free_table(rowpp);
7548  continue;
7549  }
7550  for (k = 1; k <= nnrows; k++) {
7551  char *ptab = unquote(rowpp[k * nncols + namec]);
7552 
7553  if (plen && ptab) {
7554  int len = strlen(ptab);
7555 
7556  if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
7557  continue;
7558  }
7559  }
7560  size++;
7561  }
7562  sqlite3_free_table(rowpp);
7563  }
7564  if (size == 0) {
7565  goto nodata;
7566  }
7567  s->nrows = size;
7568  size = (size + 1) * asize;
7569  s->rows = xmalloc((size + 1) * sizeof (char *));
7570  if (!s->rows) {
7571  s->nrows = 0;
7572  return nomem(s);
7573  }
7574  s->rows[0] = (char *) size;
7575  s->rows += 1;
7576  memset(s->rows, 0, sizeof (char *) * size);
7577  s->rowfree = freerows;
7578  offs = 0;
7579  for (i = 1; i <= nrows; i++) {
7580  int k;
7581 
7582  if (!rowp[i]) {
7583  continue;
7584  }
7585  rowpp = NULL;
7586  ret = SQLITE_ERROR;
7587  sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
7588  if (sql) {
7589  dbtraceapi(d, "sqlite3_get_table", sql);
7590  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7591  &nnrows, &nncols, NULL);
7592  sqlite3_free(sql);
7593  }
7594  if (ret != SQLITE_OK || nncols * nnrows <= 0) {
7595  sqlite3_free_table(rowpp);
7596  continue;
7597  }
7598  namec = findcol(rowpp, nncols, "table");
7599  seqc = findcol(rowpp, nncols, "seq");
7600  fromc = findcol(rowpp, nncols, "from");
7601  toc = findcol(rowpp, nncols, "to");
7602  onu = findcol(rowpp, nncols, "on_update");
7603  ond = findcol(rowpp, nncols, "on_delete");
7604  if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7605  sqlite3_free_table(rowpp);
7606  continue;
7607  }
7608  for (k = 1; k <= nnrows; k++) {
7609  int pos = 0, roffs = (offs + 1) * s->ncols;
7610  char *ptab = unquote(rowpp[k * nncols + namec]);
7611  char buf[32];
7612 
7613  if (plen && ptab) {
7614  int len = strlen(ptab);
7615 
7616  if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
7617  continue;
7618  }
7619  }
7620 #if defined(_WIN32) || defined(_WIN64)
7621  s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
7622  s->rows[roffs + 1] = xstrdup("");
7623 #else
7624  s->rows[roffs + 0] = xstrdup("");
7625  s->rows[roffs + 1] = xstrdup("");
7626 #endif
7627  s->rows[roffs + 2] = xstrdup(ptab);
7628  s->rows[roffs + 3] = xstrdup(rowpp[k * nncols + toc]);
7629  s->rows[roffs + 4] = xstrdup("");
7630  s->rows[roffs + 5] = xstrdup("");
7631  s->rows[roffs + 6] = xstrdup(rowp[i]);
7632  s->rows[roffs + 7] = xstrdup(rowpp[k * nncols + fromc]);
7633  sscanf(rowpp[k * nncols + seqc], "%d", &pos);
7634  sprintf(buf, "%d", pos + 1);
7635  s->rows[roffs + 8] = xstrdup(buf);
7636  if (onu < 0) {
7637  s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7638  } else {
7639  if (strcmp(rowpp[k * nncols + onu], "SET NULL") == 0) {
7640  s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
7641  } else if (strcmp(rowpp[k * nncols + onu], "SET DEFAULT")
7642  == 0) {
7643  s->rows[roffs + 9] =
7644  xstrdup(stringify(SQL_SET_DEFAULT));
7645  } else if (strcmp(rowpp[k * nncols + onu], "CASCADE")
7646  == 0) {
7647  s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
7648  } else if (strcmp(rowpp[k * nncols + onu], "RESTRICT")
7649  == 0) {
7650  s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
7651  } else {
7652  s->rows[roffs + 9] =
7653  xstrdup(stringify(SQL_NO_ACTION));
7654  }
7655  }
7656  if (ond < 0) {
7657  s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7658  } else {
7659  if (strcmp(rowpp[k * nncols + ond], "SET NULL") == 0) {
7660  s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
7661  } else if (strcmp(rowpp[k * nncols + ond], "SET DEFAULT")
7662  == 0) {
7663  s->rows[roffs + 10] =
7664  xstrdup(stringify(SQL_SET_DEFAULT));
7665  } else if (strcmp(rowpp[k * nncols + ond], "CASCADE")
7666  == 0) {
7667  s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
7668  } else if (strcmp(rowpp[k * nncols + ond], "RESTRICT")
7669  == 0) {
7670  s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
7671  } else {
7672  s->rows[roffs + 10] =
7673  xstrdup(stringify(SQL_NO_ACTION));
7674  }
7675  }
7676  s->rows[roffs + 11] = NULL;
7677  s->rows[roffs + 12] = NULL;
7678  s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
7679  offs++;
7680  }
7681  sqlite3_free_table(rowpp);
7682  }
7683  sqlite3_free_table(rowp);
7684  }
7685  return SQL_SUCCESS;
7686 }
7687 
7688 #ifndef WINTERFACE
7689 
7707 SQLRETURN SQL_API
7708 SQLForeignKeys(SQLHSTMT stmt,
7709  SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7710  SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
7711  SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
7712  SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7713  SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
7714  SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
7715 {
7716 #if defined(_WIN32) || defined(_WIN64)
7717  char *pc = NULL, *ps = NULL, *pt = NULL;
7718  char *fc = NULL, *fs = NULL, *ft = NULL;
7719 #endif
7720  SQLRETURN ret;
7721 
7722  HSTMT_LOCK(stmt);
7723 #if defined(_WIN32) || defined(_WIN64)
7724  if (!((STMT *) stmt)->oemcp[0]) {
7725  ret = drvforeignkeys(stmt,
7726  PKcatalog, PKcatalogLen,
7727  PKschema, PKschemaLen, PKtable, PKtableLen,
7728  FKcatalog, FKcatalogLen,
7729  FKschema, FKschemaLen,
7730  FKtable, FKtableLen);
7731  goto done2;
7732  }
7733  if (PKcatalog) {
7734  pc = wmb_to_utf_c((char *) PKcatalog, PKcatalogLen);
7735  if (!pc) {
7736  ret = nomem((STMT *) stmt);
7737  goto done;
7738  }
7739  }
7740  if (PKschema) {
7741  ps = wmb_to_utf_c((char *) PKschema, PKschemaLen);
7742  if (!ps) {
7743  ret = nomem((STMT *) stmt);
7744  goto done;
7745  }
7746  }
7747  if (PKtable) {
7748  pt = wmb_to_utf_c((char *) PKtable, PKtableLen);
7749  if (!pt) {
7750  ret = nomem((STMT *) stmt);
7751  goto done;
7752  }
7753  }
7754  if (FKcatalog) {
7755  fc = wmb_to_utf_c((char *) FKcatalog, FKcatalogLen);
7756  if (!fc) {
7757  ret = nomem((STMT *) stmt);
7758  goto done;
7759  }
7760  }
7761  if (FKschema) {
7762  fs = wmb_to_utf_c((char *) FKschema, FKschemaLen);
7763  if (!fs) {
7764  ret = nomem((STMT *) stmt);
7765  goto done;
7766  }
7767  }
7768  if (FKtable) {
7769  ft = wmb_to_utf_c((char *) FKtable, FKtableLen);
7770  if (!ft) {
7771  ret = nomem((STMT *) stmt);
7772  goto done;
7773  }
7774  }
7775  ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
7776  (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
7777  (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
7778  (SQLCHAR *) ft, SQL_NTS);
7779 #else
7780  ret = drvforeignkeys(stmt,
7781  PKcatalog, PKcatalogLen,
7782  PKschema, PKschemaLen, PKtable, PKtableLen,
7783  FKcatalog, FKcatalogLen,
7784  FKschema, FKschemaLen,
7785  FKtable, FKtableLen);
7786 #endif
7787 #if defined(_WIN32) || defined(_WIN64)
7788 done:
7789  uc_free(ft);
7790  uc_free(fs);
7791  uc_free(fc);
7792  uc_free(pt);
7793  uc_free(ps);
7794  uc_free(pc);
7795 done2:
7796  ;
7797 #endif
7798  HSTMT_UNLOCK(stmt);
7799  return ret;
7800 }
7801 #endif
7802 
7803 #ifdef WINTERFACE
7804 
7822 SQLRETURN SQL_API
7824  SQLWCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7825  SQLWCHAR *PKschema, SQLSMALLINT PKschemaLen,
7826  SQLWCHAR *PKtable, SQLSMALLINT PKtableLen,
7827  SQLWCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7828  SQLWCHAR *FKschema, SQLSMALLINT FKschemaLen,
7829  SQLWCHAR *FKtable, SQLSMALLINT FKtableLen)
7830 {
7831  char *pc = NULL, *ps = NULL, *pt = NULL;
7832  char *fc = NULL, *fs = NULL, *ft = NULL;
7833  SQLRETURN ret;
7834 
7835  HSTMT_LOCK(stmt);
7836  if (PKcatalog) {
7837  pc = uc_to_utf_c(PKcatalog, PKcatalogLen);
7838  if (!pc) {
7839  ret = nomem((STMT *) stmt);
7840  goto done;
7841  }
7842  }
7843  if (PKschema) {
7844  ps = uc_to_utf_c(PKschema, PKschemaLen);
7845  if (!ps) {
7846  ret = nomem((STMT *) stmt);
7847  goto done;
7848  }
7849  }
7850  if (PKtable) {
7851  pt = uc_to_utf_c(PKtable, PKtableLen);
7852  if (!pt) {
7853  ret = nomem((STMT *) stmt);
7854  goto done;
7855  }
7856  }
7857  if (FKcatalog) {
7858  fc = uc_to_utf_c(FKcatalog, FKcatalogLen);
7859  if (!fc) {
7860  ret = nomem((STMT *) stmt);
7861  goto done;
7862  }
7863  }
7864  if (FKschema) {
7865  fs = uc_to_utf_c(FKschema, FKschemaLen);
7866  if (!fs) {
7867  ret = nomem((STMT *) stmt);
7868  goto done;
7869  }
7870  }
7871  if (FKtable) {
7872  ft = uc_to_utf_c(FKtable, FKtableLen);
7873  if (!ft) {
7874  ret = nomem((STMT *) stmt);
7875  goto done;
7876  }
7877  }
7878  ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
7879  (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
7880  (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
7881  (SQLCHAR *) ft, SQL_NTS);
7882 done:
7883  uc_free(ft);
7884  uc_free(fs);
7885  uc_free(fc);
7886  uc_free(pt);
7887  uc_free(ps);
7888  uc_free(pc);
7889  HSTMT_UNLOCK(stmt);
7890  return ret;
7891 }
7892 #endif
7893 
7900 static SQLRETURN
7902 {
7903  int ret = SQL_SUCCESS, rc, busy_count = 0;
7904  char *errp = NULL;
7905  DBC *d = (DBC *) s->dbc;
7906 
7907  if (!d->autocommit && !d->intrans && !d->trans_disable) {
7908 begin_again:
7909  rc = sqlite3_exec(d->sqlite, "BEGIN TRANSACTION", NULL, NULL, &errp);
7910  if (rc == SQLITE_BUSY) {
7911  if (busy_handler((void *) d, ++busy_count)) {
7912  if (errp) {
7913  sqlite3_free(errp);
7914  errp = NULL;
7915  }
7916  goto begin_again;
7917  }
7918  }
7919  dbtracerc(d, rc, errp);
7920  if (rc != SQLITE_OK) {
7921  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7922  errp ? errp : "unknown error", rc);
7923  ret = SQL_ERROR;
7924  } else {
7925  d->intrans = 1;
7926  }
7927  if (errp) {
7928  sqlite3_free(errp);
7929  errp = NULL;
7930  }
7931  }
7932  return ret;
7933 }
7934 
7943 static SQLRETURN
7944 endtran(DBC *d, SQLSMALLINT comptype, int force)
7945 {
7946  int ret, busy_count = 0;
7947  char *sql, *errp = NULL;
7948 
7949  if (!d->sqlite) {
7950  setstatd(d, -1, "not connected", (*d->ov3) ? "HY000" : "S1000");
7951  return SQL_ERROR;
7952  }
7953  if ((!force && d->autocommit) || !d->intrans) {
7954  return SQL_SUCCESS;
7955  }
7956  switch (comptype) {
7957  case SQL_COMMIT:
7958  sql = "COMMIT TRANSACTION";
7959  goto doit;
7960  case SQL_ROLLBACK:
7961  sql = "ROLLBACK TRANSACTION";
7962  doit:
7963  ret = sqlite3_exec(d->sqlite, sql, NULL, NULL, &errp);
7964  dbtracerc(d, ret, errp);
7965  if (ret == SQLITE_BUSY && busy_count < 10) {
7966  if (busy_handler((void *) d, ++busy_count)) {
7967  if (errp) {
7968  sqlite3_free(errp);
7969  errp = NULL;
7970  }
7971  goto doit;
7972  }
7973  }
7974  if (ret != SQLITE_OK) {
7975  setstatd(d, ret, "%s", (*d->ov3) ? "HY000" : "S1000",
7976  errp ? errp : "transaction failed");
7977  if (errp) {
7978  sqlite3_free(errp);
7979  errp = NULL;
7980  }
7981  return SQL_ERROR;
7982  }
7983  if (errp) {
7984  sqlite3_free(errp);
7985  errp = NULL;
7986  }
7987  d->intrans = 0;
7988  return SQL_SUCCESS;
7989  }
7990  setstatd(d, -1, "invalid completion type", (*d->ov3) ? "HY000" : "S1000");
7991  return SQL_ERROR;
7992 }
7993 
8002 static SQLRETURN
8003 drvendtran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
8004 {
8005  DBC *dbc = NULL;
8006  int fail = 0;
8007  SQLRETURN ret;
8008 #if defined(_WIN32) || defined(_WIN64)
8009  ENV *env;
8010 #endif
8011 
8012  switch (type) {
8013  case SQL_HANDLE_DBC:
8014  HDBC_LOCK((SQLHDBC) handle);
8015  if (handle == SQL_NULL_HDBC) {
8016  return SQL_INVALID_HANDLE;
8017  }
8018  dbc = (DBC *) handle;
8019  ret = endtran(dbc, comptype, 0);
8020  HDBC_UNLOCK((SQLHDBC) handle);
8021  return ret;
8022  case SQL_HANDLE_ENV:
8023  if (handle == SQL_NULL_HENV) {
8024  return SQL_INVALID_HANDLE;
8025  }
8026 #if defined(_WIN32) || defined(_WIN64)
8027  env = (ENV *) handle;
8028  if (env->magic != ENV_MAGIC) {
8029  return SQL_INVALID_HANDLE;
8030  }
8031  EnterCriticalSection(&env->cs);
8032 #endif
8033  dbc = ((ENV *) handle)->dbcs;
8034  while (dbc) {
8035  HDBC_LOCK((SQLHDBC) dbc);
8036  ret = endtran(dbc, comptype, 0);
8037  HDBC_UNLOCK((SQLHDBC) dbc);
8038  if (ret != SQL_SUCCESS) {
8039  fail++;
8040  }
8041  dbc = dbc->next;
8042  }
8043 #if defined(_WIN32) || defined(_WIN64)
8044  LeaveCriticalSection(&env->cs);
8045 #endif
8046  return fail ? SQL_ERROR : SQL_SUCCESS;
8047  }
8048  return SQL_INVALID_HANDLE;
8049 }
8050 
8059 SQLRETURN SQL_API
8060 SQLEndTran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
8061 {
8062  return drvendtran(type, handle, comptype);
8063 }
8064 
8073 SQLRETURN SQL_API
8074 SQLTransact(SQLHENV env, SQLHDBC dbc, SQLUSMALLINT type)
8075 {
8076  if (dbc != SQL_NULL_HDBC) {
8077  return drvendtran(SQL_HANDLE_DBC, (SQLHANDLE) dbc, type);
8078  }
8079  return drvendtran(SQL_HANDLE_ENV, (SQLHANDLE) env, type);
8080 }
8081 
8086 SQLRETURN SQL_API
8087 SQLCopyDesc(SQLHDESC source, SQLHDESC target)
8088 {
8089  return SQL_ERROR;
8090 }
8091 
8092 #ifndef WINTERFACE
8093 
8104 SQLRETURN SQL_API
8105 SQLNativeSql(SQLHSTMT stmt, SQLCHAR *sqlin, SQLINTEGER sqlinLen,
8106  SQLCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
8107 {
8108  int outLen = 0;
8109  SQLRETURN ret = SQL_SUCCESS;
8110 
8111  HSTMT_LOCK(stmt);
8112  if (sqlinLen == SQL_NTS) {
8113  sqlinLen = strlen((char *) sqlin);
8114  }
8115  if (sql) {
8116  if (sqlMax > 0) {
8117  strncpy((char *) sql, (char *) sqlin, sqlMax - 1);
8118  sqlin[sqlMax - 1] = '\0';
8119  outLen = min(sqlMax - 1, sqlinLen);
8120  }
8121  } else {
8122  outLen = sqlinLen;
8123  }
8124  if (sqlLen) {
8125  *sqlLen = outLen;
8126  }
8127  if (sql && outLen < sqlinLen) {
8128  setstat((STMT *) stmt, -1, "data right truncated", "01004");
8129  ret = SQL_SUCCESS_WITH_INFO;
8130  }
8131  HSTMT_UNLOCK(stmt);
8132  return ret;
8133 }
8134 #endif
8135 
8136 #ifdef WINTERFACE
8137 
8148 SQLRETURN SQL_API
8149 SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen,
8150  SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
8151 {
8152  int outLen = 0;
8153  SQLRETURN ret = SQL_SUCCESS;
8154 
8155  HSTMT_LOCK(stmt);
8156  if (sqlinLen == SQL_NTS) {
8157  sqlinLen = uc_strlen(sqlin);
8158  }
8159  if (sql) {
8160  if (sqlMax > 0) {
8161  uc_strncpy(sql, sqlin, sqlMax - 1);
8162  sqlin[sqlMax - 1] = 0;
8163  outLen = min(sqlMax - 1, sqlinLen);
8164  }
8165  } else {
8166  outLen = sqlinLen;
8167  }
8168  if (sqlLen) {
8169  *sqlLen = outLen;
8170  }
8171  if (sql && outLen < sqlinLen) {
8172  setstat((STMT *) stmt, -1, "data right truncated", "01004");
8173  ret = SQL_SUCCESS_WITH_INFO;
8174  }
8175  HSTMT_UNLOCK(stmt);
8176  return ret;
8177 }
8178 #endif
8179 
8184 static COL procSpec2[] = {
8185  { "SYSTEM", "PROCEDURE", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
8186  { "SYSTEM", "PROCEDURE", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
8187  { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8188  { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
8189  { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
8190  { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
8191  { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
8192  { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
8193 };
8194 
8195 static COL procSpec3[] = {
8196  { "SYSTEM", "PROCEDURE", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
8197  { "SYSTEM", "PROCEDURE", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
8198  { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8199  { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
8200  { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
8201  { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
8202  { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
8203  { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
8204 };
8205 
8206 #ifndef WINTERFACE
8207 
8219 SQLRETURN SQL_API
8220 SQLProcedures(SQLHSTMT stmt,
8221  SQLCHAR *catalog, SQLSMALLINT catalogLen,
8222  SQLCHAR *schema, SQLSMALLINT schemaLen,
8223  SQLCHAR *proc, SQLSMALLINT procLen)
8224 {
8225  SQLRETURN ret;
8226 
8227  HSTMT_LOCK(stmt);
8229  procSpec3, array_size(procSpec3), NULL);
8230  HSTMT_UNLOCK(stmt);
8231  return ret;
8232 }
8233 #endif
8234 
8235 #ifdef WINTERFACE
8236 
8248 SQLRETURN SQL_API
8250  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
8251  SQLWCHAR *schema, SQLSMALLINT schemaLen,
8252  SQLWCHAR *proc, SQLSMALLINT procLen)
8253 {
8254  SQLRETURN ret;
8255 
8256  HSTMT_LOCK(stmt);
8258  procSpec3, array_size(procSpec3), NULL);
8259  HSTMT_UNLOCK(stmt);
8260  return ret;
8261 }
8262 #endif
8263 
8268 static COL procColSpec2[] = {
8269  { "SYSTEM", "PROCCOL", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
8270  { "SYSTEM", "PROCCOL", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
8271  { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8272  { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
8273  { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
8274  { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
8275  { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
8276  { "SYSTEM", "PROCCOL", "PRECISION", SQL_INTEGER, 10 },
8277  { "SYSTEM", "PROCCOL", "LENGTH", SQL_INTEGER, 10 },
8278  { "SYSTEM", "PROCCOL", "SCALE", SQL_SMALLINT, 5 },
8279  { "SYSTEM", "PROCCOL", "RADIX", SQL_SMALLINT, 5 },
8280  { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
8281  { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
8282  { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
8283  { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
8284  { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
8285  { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
8286  { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
8287  { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
8288 };
8289 
8290 static COL procColSpec3[] = {
8291  { "SYSTEM", "PROCCOL", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
8292  { "SYSTEM", "PROCCOL", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
8293  { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8294  { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
8295  { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
8296  { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
8297  { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
8298  { "SYSTEM", "PROCCOL", "COLUMN_SIZE", SQL_INTEGER, 10 },
8299  { "SYSTEM", "PROCCOL", "BUFFER_LENGTH", SQL_INTEGER, 10 },
8300  { "SYSTEM", "PROCCOL", "DECIMAL_DIGITS", SQL_SMALLINT, 5 },
8301  { "SYSTEM", "PROCCOL", "NUM_PREC_RADIX", SQL_SMALLINT, 5 },
8302  { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
8303  { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
8304  { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
8305  { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
8306  { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
8307  { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
8308  { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
8309  { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
8310 };
8311 
8312 #ifndef WINTERFACE
8313 
8327 SQLRETURN SQL_API
8328 SQLProcedureColumns(SQLHSTMT stmt,
8329  SQLCHAR *catalog, SQLSMALLINT catalogLen,
8330  SQLCHAR *schema, SQLSMALLINT schemaLen,
8331  SQLCHAR *proc, SQLSMALLINT procLen,
8332  SQLCHAR *column, SQLSMALLINT columnLen)
8333 {
8334  SQLRETURN ret;
8335 
8336  HSTMT_LOCK(stmt);
8339  HSTMT_UNLOCK(stmt);
8340  return ret;
8341 }
8342 #endif
8343 
8344 #ifdef WINTERFACE
8345 
8360 SQLRETURN SQL_API
8362  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
8363  SQLWCHAR *schema, SQLSMALLINT schemaLen,
8364  SQLWCHAR *proc, SQLSMALLINT procLen,
8365  SQLWCHAR *column, SQLSMALLINT columnLen)
8366 {
8367  SQLRETURN ret;
8368 
8369  HSTMT_LOCK(stmt);
8372  HSTMT_UNLOCK(stmt);
8373  return ret;
8374 }
8375 #endif
8376 
8387 SQLRETURN SQL_API
8388 SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val,
8389  SQLINTEGER len, SQLINTEGER *lenp)
8390 {
8391  ENV *e;
8392  SQLRETURN ret = SQL_ERROR;
8393 
8394  if (env == SQL_NULL_HENV) {
8395  return SQL_INVALID_HANDLE;
8396  }
8397  e = (ENV *) env;
8398  if (!e || e->magic != ENV_MAGIC) {
8399  return SQL_INVALID_HANDLE;
8400  }
8401 #if defined(_WIN32) || defined(_WIN64)
8402  EnterCriticalSection(&e->cs);
8403 #endif
8404  switch (attr) {
8405  case SQL_ATTR_CONNECTION_POOLING:
8406  ret = SQL_ERROR;
8407  break;
8408  case SQL_ATTR_CP_MATCH:
8409  ret = SQL_NO_DATA;
8410  break;
8411  case SQL_ATTR_OUTPUT_NTS:
8412  if (val) {
8413  *((SQLINTEGER *) val) = SQL_TRUE;
8414  }
8415  if (lenp) {
8416  *lenp = sizeof (SQLINTEGER);
8417  }
8418  ret = SQL_SUCCESS;
8419  break;
8420  case SQL_ATTR_ODBC_VERSION:
8421  if (val) {
8422  *((SQLINTEGER *) val) = e->ov3 ? SQL_OV_ODBC3 : SQL_OV_ODBC2;
8423  }
8424  if (lenp) {
8425  *lenp = sizeof (SQLINTEGER);
8426  }
8427  ret = SQL_SUCCESS;
8428  break;
8429  }
8430 #if defined(_WIN32) || defined(_WIN64)
8431  LeaveCriticalSection(&e->cs);
8432 #endif
8433  return ret;
8434 }
8435 
8445 SQLRETURN SQL_API
8446 SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
8447 {
8448  ENV *e;
8449  SQLRETURN ret = SQL_ERROR;
8450 
8451  if (env == SQL_NULL_HENV) {
8452  return SQL_INVALID_HANDLE;
8453  }
8454  e = (ENV *) env;
8455  if (!e || e->magic != ENV_MAGIC) {
8456  return SQL_INVALID_HANDLE;
8457  }
8458 #if defined(_WIN32) || defined(_WIN64)
8459  EnterCriticalSection(&e->cs);
8460 #endif
8461  switch (attr) {
8462  case SQL_ATTR_CONNECTION_POOLING:
8463  ret = SQL_SUCCESS;
8464  break;
8465  case SQL_ATTR_CP_MATCH:
8466  ret = SQL_NO_DATA;
8467  break;
8468  case SQL_ATTR_OUTPUT_NTS:
8469  if (val == (SQLPOINTER) SQL_TRUE) {
8470  ret = SQL_SUCCESS;
8471  }
8472  break;
8473  case SQL_ATTR_ODBC_VERSION:
8474  if (!val) {
8475  break;
8476  }
8477  if (val == (SQLPOINTER) SQL_OV_ODBC2) {
8478  e->ov3 = 0;
8479  ret = SQL_SUCCESS;
8480  }
8481  if (val == (SQLPOINTER) SQL_OV_ODBC3) {
8482  e->ov3 = 1;
8483  ret = SQL_SUCCESS;
8484  }
8485  break;
8486  }
8487 #if defined(_WIN32) || defined(_WIN64)
8488  LeaveCriticalSection(&e->cs);
8489 #endif
8490  return ret;
8491 }
8492 
8506 static SQLRETURN
8507 drvgetdiagrec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8508  SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
8509  SQLSMALLINT buflen, SQLSMALLINT *msglen)
8510 {
8511  DBC *d = NULL;
8512  STMT *s = NULL;
8513  int len, naterr;
8514  char *logmsg, *sqlst;
8515  SQLRETURN ret = SQL_ERROR;
8516 
8517  if (handle == SQL_NULL_HANDLE) {
8518  return SQL_INVALID_HANDLE;
8519  }
8520  if (sqlstate) {
8521  sqlstate[0] = '\0';
8522  }
8523  if (msg && buflen > 0) {
8524  msg[0] = '\0';
8525  }
8526  if (msglen) {
8527  *msglen = 0;
8528  }
8529  if (nativeerr) {
8530  *nativeerr = 0;
8531  }
8532  switch (htype) {
8533  case SQL_HANDLE_ENV:
8534  case SQL_HANDLE_DESC:
8535  return SQL_NO_DATA;
8536  case SQL_HANDLE_DBC:
8537  HDBC_LOCK((SQLHDBC) handle);
8538  d = (DBC *) handle;
8539  logmsg = (char *) d->logmsg;
8540  sqlst = d->sqlstate;
8541  naterr = d->naterr;
8542  break;
8543  case SQL_HANDLE_STMT:
8544  HSTMT_LOCK((SQLHSTMT) handle);
8545  s = (STMT *) handle;
8546  logmsg = (char *) s->logmsg;
8547  sqlst = s->sqlstate;
8548  naterr = s->naterr;
8549  break;
8550  default:
8551  return SQL_INVALID_HANDLE;
8552  }
8553  if (buflen < 0) {
8554  goto done;
8555  }
8556  if (recno > 1) {
8557  ret = SQL_NO_DATA;
8558  goto done;
8559  }
8560  len = strlen(logmsg);
8561  if (len == 0) {
8562  ret = SQL_NO_DATA;
8563  goto done;
8564  }
8565  if (nativeerr) {
8566  *nativeerr = naterr;
8567  }
8568  if (sqlstate) {
8569  strcpy((char *) sqlstate, sqlst);
8570  }
8571  if (msglen) {
8572  *msglen = len;
8573  }
8574  if (len >= buflen) {
8575  if (msg && buflen > 0) {
8576  strncpy((char *) msg, logmsg, buflen);
8577  msg[buflen - 1] = '\0';
8578  logmsg[0] = '\0';
8579  }
8580  } else if (msg) {
8581  strcpy((char *) msg, logmsg);
8582  logmsg[0] = '\0';
8583  }
8584  ret = SQL_SUCCESS;
8585 done:
8586  switch (htype) {
8587  case SQL_HANDLE_DBC:
8588  HDBC_UNLOCK((SQLHDBC) handle);
8589  break;
8590  case SQL_HANDLE_STMT:
8591  HSTMT_UNLOCK((SQLHSTMT) handle);
8592  break;
8593  }
8594  return ret;
8595 }
8596 
8597 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
8598 
8611 SQLRETURN SQL_API
8612 SQLGetDiagRec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8613  SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
8614  SQLSMALLINT buflen, SQLSMALLINT *msglen)
8615 {
8616  return drvgetdiagrec(htype, handle, recno, sqlstate,
8617  nativeerr, msg, buflen, msglen);
8618 }
8619 #endif
8620 
8621 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
8622 #ifdef WINTERFACE
8623 
8637 SQLRETURN SQL_API
8638 SQLGetDiagRecW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8639  SQLWCHAR *sqlstate, SQLINTEGER *nativeerr, SQLWCHAR *msg,
8640  SQLSMALLINT buflen, SQLSMALLINT *msglen)
8641 {
8642  char state[16];
8643  SQLSMALLINT len;
8644  SQLRETURN ret;
8645 
8646  ret = drvgetdiagrec(htype, handle, recno, (SQLCHAR *) state,
8647  nativeerr, (SQLCHAR *) msg, buflen, &len);
8648  if (ret == SQL_SUCCESS) {
8649  if (sqlstate) {
8650  uc_from_utf_buf((SQLCHAR *) state, -1, sqlstate,
8651  6 * sizeof (SQLWCHAR));
8652  }
8653  if (msg) {
8654  if (len > 0) {
8655  SQLWCHAR *m = NULL;
8656 
8657  m = uc_from_utf((unsigned char *) msg, len);
8658  if (m) {
8659  if (buflen) {
8660  buflen /= sizeof (SQLWCHAR);
8661  uc_strncpy(msg, m, buflen);
8662  m[len] = 0;
8663  len = min(buflen, uc_strlen(m));
8664  } else {
8665  len = uc_strlen(m);
8666  }
8667  uc_free(m);
8668  } else {
8669  len = 0;
8670  }
8671  }
8672  if (len <= 0) {
8673  len = 0;
8674  if (buflen > 0) {
8675  msg[0] = 0;
8676  }
8677  }
8678  } else {
8679  /* estimated length !!! */
8680  len *= sizeof (SQLWCHAR);
8681  }
8682  if (msglen) {
8683  *msglen = len;
8684  }
8685  } else if (ret == SQL_NO_DATA) {
8686  if (sqlstate) {
8687  sqlstate[0] = 0;
8688  }
8689  if (msg) {
8690  if (buflen > 0) {
8691  msg[0] = 0;
8692  }
8693  }
8694  if (msglen) {
8695  *msglen = 0;
8696  }
8697  }
8698  return ret;
8699 }
8700 #endif
8701 #endif
8702 
8715 static SQLRETURN
8716 drvgetdiagfield(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8717  SQLSMALLINT id, SQLPOINTER info,
8718  SQLSMALLINT buflen, SQLSMALLINT *stringlen)
8719 {
8720  DBC *d = NULL;
8721  STMT *s = NULL;
8722  int len, naterr, strbuf = 1;
8723  char *logmsg, *sqlst, *clrmsg = NULL;
8724  SQLRETURN ret = SQL_ERROR;
8725 
8726  if (handle == SQL_NULL_HANDLE) {
8727  return SQL_INVALID_HANDLE;
8728  }
8729  if (stringlen) {
8730  *stringlen = 0;
8731  }
8732  switch (htype) {
8733  case SQL_HANDLE_ENV:
8734  case SQL_HANDLE_DESC:
8735  return SQL_NO_DATA;
8736  case SQL_HANDLE_DBC:
8737  HDBC_LOCK((SQLHDBC) handle);
8738  d = (DBC *) handle;
8739  logmsg = (char *) d->logmsg;
8740  sqlst = d->sqlstate;
8741  naterr = d->naterr;
8742  break;
8743  case SQL_HANDLE_STMT:
8744  HSTMT_LOCK((SQLHSTMT) handle);
8745  s = (STMT *) handle;
8746  d = (DBC *) s->dbc;
8747  logmsg = (char *) s->logmsg;
8748  sqlst = s->sqlstate;
8749  naterr = s->naterr;
8750  break;
8751  default:
8752  return SQL_INVALID_HANDLE;
8753  }
8754  if (buflen < 0) {
8755  switch (buflen) {
8756  case SQL_IS_POINTER:
8757  case SQL_IS_UINTEGER:
8758  case SQL_IS_INTEGER:
8759  case SQL_IS_USMALLINT:
8760  case SQL_IS_SMALLINT:
8761  strbuf = 0;
8762  break;
8763  default:
8764  ret = SQL_ERROR;
8765  goto done;
8766  }
8767  }
8768  if (recno > 1) {
8769  ret = SQL_NO_DATA;
8770  goto done;
8771  }
8772  switch (id) {
8773  case SQL_DIAG_CLASS_ORIGIN:
8774  logmsg = "ISO 9075";
8775  if (sqlst[0] == 'I' && sqlst[1] == 'M') {
8776  logmsg = "ODBC 3.0";
8777  }
8778  break;
8779  case SQL_DIAG_SUBCLASS_ORIGIN:
8780  logmsg = "ISO 9075";
8781  if (sqlst[0] == 'I' && sqlst[1] == 'M') {
8782  logmsg = "ODBC 3.0";
8783  } else if (sqlst[0] == 'H' && sqlst[1] == 'Y') {
8784  logmsg = "ODBC 3.0";
8785  } else if (sqlst[0] == '2' || sqlst[0] == '0' || sqlst[0] == '4') {
8786  logmsg = "ODBC 3.0";
8787  }
8788  break;
8789  case SQL_DIAG_CONNECTION_NAME:
8790  case SQL_DIAG_SERVER_NAME:
8791  logmsg = d->dsn ? d->dsn : "No DSN";
8792  break;
8793  case SQL_DIAG_SQLSTATE:
8794  logmsg = sqlst;
8795  break;
8796  case SQL_DIAG_MESSAGE_TEXT:
8797  if (info) {
8798  clrmsg = logmsg;
8799  }
8800  break;
8801  case SQL_DIAG_NUMBER:
8802  naterr = 1;
8803  /* fall through */
8804  case SQL_DIAG_NATIVE:
8805  len = strlen(logmsg);
8806  if (len == 0) {
8807  ret = SQL_NO_DATA;
8808  goto done;
8809  }
8810  if (info) {
8811  *((SQLINTEGER *) info) = naterr;
8812  }
8813  ret = SQL_SUCCESS;
8814  goto done;
8815  case SQL_DIAG_DYNAMIC_FUNCTION:
8816  logmsg = "";
8817  break;
8818  case SQL_DIAG_CURSOR_ROW_COUNT:
8819  if (htype == SQL_HANDLE_STMT) {
8820  SQLULEN count;
8821 
8822  count = (s->isselect == 1 || s->isselect == -1) ? s->nrows : 0;
8823  *((SQLULEN *) info) = count;
8824  ret = SQL_SUCCESS;
8825  }
8826  goto done;
8827  case SQL_DIAG_ROW_COUNT:
8828  if (htype == SQL_HANDLE_STMT) {
8829  SQLULEN count;
8830 
8831  count = s->isselect ? 0 : s->nrows;
8832  *((SQLULEN *) info) = count;
8833  ret = SQL_SUCCESS;
8834  }
8835  goto done;
8836  default:
8837  goto done;
8838  }
8839  if (info && buflen > 0) {
8840  ((char *) info)[0] = '\0';
8841  }
8842  len = strlen(logmsg);
8843  if (len == 0) {
8844  ret = SQL_NO_DATA;
8845  goto done;
8846  }
8847  if (stringlen) {
8848  *stringlen = len;
8849  }
8850  if (strbuf) {
8851  if (len >= buflen) {
8852  if (info && buflen > 0) {
8853  if (stringlen) {
8854  *stringlen = buflen - 1;
8855  }
8856  strncpy((char *) info, logmsg, buflen);
8857  ((char *) info)[buflen - 1] = '\0';
8858  }
8859  } else if (info) {
8860  strcpy((char *) info, logmsg);
8861  }
8862  }
8863  if (clrmsg) {
8864  *clrmsg = '\0';
8865  }
8866  ret = SQL_SUCCESS;
8867 done:
8868  switch (htype) {
8869  case SQL_HANDLE_DBC:
8870  HDBC_UNLOCK((SQLHDBC) handle);
8871  break;
8872  case SQL_HANDLE_STMT:
8873  HSTMT_UNLOCK((SQLHSTMT) handle);
8874  break;
8875  }
8876  return ret;
8877 }
8878 
8879 #ifndef WINTERFACE
8880 
8892 SQLRETURN SQL_API
8893 SQLGetDiagField(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8894  SQLSMALLINT id, SQLPOINTER info,
8895  SQLSMALLINT buflen, SQLSMALLINT *stringlen)
8896 {
8897  return drvgetdiagfield(htype, handle, recno, id, info, buflen, stringlen);
8898 }
8899 #endif
8900 
8901 #ifdef WINTERFACE
8902 
8914 SQLRETURN SQL_API
8915 SQLGetDiagFieldW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8916  SQLSMALLINT id, SQLPOINTER info,
8917  SQLSMALLINT buflen, SQLSMALLINT *stringlen)
8918 {
8919  SQLSMALLINT len;
8920  SQLRETURN ret;
8921 
8922  ret = drvgetdiagfield(htype, handle, recno, id, info, buflen, &len);
8923  if (ret == SQL_SUCCESS) {
8924  if (info) {
8925  switch (id) {
8926  case SQL_DIAG_CLASS_ORIGIN:
8927  case SQL_DIAG_SUBCLASS_ORIGIN:
8928  case SQL_DIAG_CONNECTION_NAME:
8929  case SQL_DIAG_SERVER_NAME:
8930  case SQL_DIAG_SQLSTATE:
8931  case SQL_DIAG_MESSAGE_TEXT:
8932  case SQL_DIAG_DYNAMIC_FUNCTION:
8933  if (len > 0) {
8934  SQLWCHAR *m = NULL;
8935 
8936  m = uc_from_utf((unsigned char *) info, len);
8937  if (m) {
8938  if (buflen) {
8939  buflen /= sizeof (SQLWCHAR);
8940  uc_strncpy(info, m, buflen);
8941  m[len] = 0;
8942  len = min(buflen, uc_strlen(m));
8943  } else {
8944  len = uc_strlen(m);
8945  }
8946  uc_free(m);
8947  len *= sizeof (SQLWCHAR);
8948  } else {
8949  len = 0;
8950  }
8951  }
8952  if (len <= 0) {
8953  len = 0;
8954  if (buflen > 0) {
8955  ((SQLWCHAR *) info)[0] = 0;
8956  }
8957  }
8958  }
8959  } else {
8960  switch (id) {
8961  case SQL_DIAG_CLASS_ORIGIN:
8962  case SQL_DIAG_SUBCLASS_ORIGIN:
8963  case SQL_DIAG_CONNECTION_NAME:
8964  case SQL_DIAG_SERVER_NAME:
8965  case SQL_DIAG_SQLSTATE:
8966  case SQL_DIAG_MESSAGE_TEXT:
8967  case SQL_DIAG_DYNAMIC_FUNCTION:
8968  len *= sizeof (SQLWCHAR);
8969  break;
8970  }
8971  }
8972  if (stringlen) {
8973  *stringlen = len;
8974  }
8975  }
8976  return ret;
8977 }
8978 #endif
8979 
8990 static SQLRETURN
8991 drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
8992  SQLINTEGER bufmax, SQLINTEGER *buflen)
8993 {
8994  STMT *s = (STMT *) stmt;
8995  SQLULEN *uval = (SQLULEN *) val;
8996  SQLINTEGER dummy;
8997  char dummybuf[16];
8998 
8999  if (!buflen) {
9000  buflen = &dummy;
9001  }
9002  if (!uval) {
9003  uval = (SQLPOINTER) dummybuf;
9004  }
9005  switch (attr) {
9006  case SQL_QUERY_TIMEOUT:
9007  *uval = 0;
9008  *buflen = sizeof (SQLULEN);
9009  return SQL_SUCCESS;
9010  case SQL_ATTR_CURSOR_TYPE:
9011  *uval = s->curtype;
9012  *buflen = sizeof (SQLULEN);
9013  return SQL_SUCCESS;
9014  case SQL_ATTR_CURSOR_SCROLLABLE:
9015  *uval = (s->curtype != SQL_CURSOR_FORWARD_ONLY) ?
9016  SQL_SCROLLABLE : SQL_NONSCROLLABLE;
9017  *buflen = sizeof (SQLULEN);
9018  return SQL_SUCCESS;
9019 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
9020  case SQL_ATTR_CURSOR_SENSITIVITY:
9021  *uval = SQL_UNSPECIFIED;
9022  *buflen = sizeof (SQLULEN);
9023  return SQL_SUCCESS;
9024 #endif
9025  case SQL_ATTR_ROW_NUMBER:
9026  if (s->s3stmt) {
9027  *uval = (s->s3stmt_rownum < 0) ?
9028  SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
9029  } else {
9030  *uval = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
9031  }
9032  *buflen = sizeof (SQLULEN);
9033  return SQL_SUCCESS;
9034  case SQL_ATTR_ASYNC_ENABLE:
9035  *uval = SQL_ASYNC_ENABLE_OFF;
9036  *buflen = sizeof (SQLULEN);
9037  return SQL_SUCCESS;
9038  case SQL_CONCURRENCY:
9039  *uval = SQL_CONCUR_LOCK;
9040  *buflen = sizeof (SQLULEN);
9041  return SQL_SUCCESS;
9042  case SQL_ATTR_RETRIEVE_DATA:
9043  *uval = s->retr_data;
9044  *buflen = sizeof (SQLULEN);
9045  return SQL_SUCCESS;
9046  case SQL_ROWSET_SIZE:
9047  case SQL_ATTR_ROW_ARRAY_SIZE:
9048  *uval = s->rowset_size;
9049  *buflen = sizeof (SQLULEN);
9050  return SQL_SUCCESS;
9051  /* Needed for some driver managers, but dummies for now */
9052  case SQL_ATTR_IMP_ROW_DESC:
9053  case SQL_ATTR_APP_ROW_DESC:
9054  case SQL_ATTR_IMP_PARAM_DESC:
9055  case SQL_ATTR_APP_PARAM_DESC:
9056  *((SQLHDESC *) uval) = (SQLHDESC) DEAD_MAGIC;
9057  *buflen = sizeof (SQLHDESC);
9058  return SQL_SUCCESS;
9059  case SQL_ATTR_ROW_STATUS_PTR:
9060  *((SQLUSMALLINT **) uval) = s->row_status;
9061  *buflen = sizeof (SQLUSMALLINT *);
9062  return SQL_SUCCESS;
9063  case SQL_ATTR_ROWS_FETCHED_PTR:
9064  *((SQLULEN **) uval) = s->row_count;
9065  *buflen = sizeof (SQLULEN *);
9066  return SQL_SUCCESS;
9067  case SQL_ATTR_USE_BOOKMARKS: {
9068  STMT *s = (STMT *) stmt;
9069 
9070  *(SQLUINTEGER *) uval = s->bkmrk;
9071  *buflen = sizeof (SQLUINTEGER);
9072  return SQL_SUCCESS;
9073  }
9074  case SQL_ATTR_FETCH_BOOKMARK_PTR:
9075  *(SQLPOINTER *) uval = s->bkmrkptr;
9076  *buflen = sizeof (SQLPOINTER);
9077  return SQL_SUCCESS;
9078  case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
9079  *((SQLULEN **) uval) = s->parm_bind_offs;
9080  *buflen = sizeof (SQLULEN *);
9081  return SQL_SUCCESS;
9082  case SQL_ATTR_PARAM_BIND_TYPE:
9083  *((SQLULEN *) uval) = s->parm_bind_type;
9084  *buflen = sizeof (SQLULEN);
9085  return SQL_SUCCESS;
9086  case SQL_ATTR_PARAM_OPERATION_PTR:
9087  *((SQLUSMALLINT **) uval) = s->parm_oper;
9088  *buflen = sizeof (SQLUSMALLINT *);
9089  return SQL_SUCCESS;
9090  case SQL_ATTR_PARAM_STATUS_PTR:
9091  *((SQLUSMALLINT **) uval) = s->parm_status;
9092  *buflen = sizeof (SQLUSMALLINT *);
9093  return SQL_SUCCESS;
9094  case SQL_ATTR_PARAMS_PROCESSED_PTR:
9095  *((SQLULEN **) uval) = s->parm_proc;
9096  *buflen = sizeof (SQLULEN *);
9097  return SQL_SUCCESS;
9098  case SQL_ATTR_PARAMSET_SIZE:
9099  *((SQLULEN *) uval) = s->paramset_size;
9100  *buflen = sizeof (SQLULEN);
9101  return SQL_SUCCESS;
9102  case SQL_ATTR_ROW_BIND_TYPE:
9103  *(SQLULEN *) uval = s->bind_type;
9104  *buflen = sizeof (SQLULEN);
9105  return SQL_SUCCESS;
9106  case SQL_ATTR_ROW_BIND_OFFSET_PTR:
9107  *((SQLULEN **) uval) = s->bind_offs;
9108  *buflen = sizeof (SQLULEN *);
9109  return SQL_SUCCESS;
9110  case SQL_ATTR_MAX_ROWS:
9111  *((SQLULEN *) uval) = s->max_rows;
9112  *buflen = sizeof (SQLULEN);
9113  return SQL_SUCCESS;
9114  case SQL_ATTR_MAX_LENGTH:
9115  *((SQLULEN *) uval) = 1000000000;
9116  *buflen = sizeof (SQLULEN);
9117  return SQL_SUCCESS;
9118 #ifdef SQL_ATTR_METADATA_ID
9119  case SQL_ATTR_METADATA_ID:
9120  *((SQLULEN *) uval) = SQL_FALSE;
9121  *buflen = sizeof (SQLULEN);
9122  return SQL_SUCCESS;
9123 #endif
9124  }
9125  return drvunimplstmt(stmt);
9126 }
9127 
9128 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
9129 
9139 SQLRETURN SQL_API
9140 SQLGetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9141  SQLINTEGER bufmax, SQLINTEGER *buflen)
9142 {
9143  SQLRETURN ret;
9144 
9145  HSTMT_LOCK(stmt);
9146  ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
9147  HSTMT_UNLOCK(stmt);
9148  return ret;
9149 }
9150 #endif
9151 
9152 #ifdef WINTERFACE
9153 
9163 SQLRETURN SQL_API
9164 SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9165  SQLINTEGER bufmax, SQLINTEGER *buflen)
9166 {
9167  SQLRETURN ret;
9168 
9169  HSTMT_LOCK(stmt);
9170  ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
9171  HSTMT_UNLOCK(stmt);
9172  return ret;
9173 }
9174 #endif
9175 
9185 static SQLRETURN
9186 drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9187  SQLINTEGER buflen)
9188 {
9189  STMT *s = (STMT *) stmt;
9190 #if defined(SQL_BIGINT) && defined(__WORDSIZE) && (__WORDSIZE == 64)
9191  SQLBIGINT uval;
9192 
9193  uval = (SQLBIGINT) val;
9194 #else
9195  SQLULEN uval;
9196 
9197  uval = (SQLULEN) val;
9198 #endif
9199  switch (attr) {
9200  case SQL_ATTR_CURSOR_TYPE:
9201  if (val == (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY) {
9202  s->curtype = SQL_CURSOR_FORWARD_ONLY;
9203  } else {
9204  s->curtype = SQL_CURSOR_STATIC;
9205  }
9206  if (val != (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY &&
9207  val != (SQLPOINTER) SQL_CURSOR_STATIC) {
9208  goto e01s02;
9209  }
9210  return SQL_SUCCESS;
9211  case SQL_ATTR_CURSOR_SCROLLABLE:
9212  if (val == (SQLPOINTER) SQL_NONSCROLLABLE) {
9213  s->curtype = SQL_CURSOR_FORWARD_ONLY;
9214  } else {
9215  s->curtype = SQL_CURSOR_STATIC;
9216  }
9217  return SQL_SUCCESS;
9218  case SQL_ATTR_ASYNC_ENABLE:
9219  if (val != (SQLPOINTER) SQL_ASYNC_ENABLE_OFF) {
9220  e01s02:
9221  setstat(s, -1, "option value changed", "01S02");
9222  return SQL_SUCCESS_WITH_INFO;
9223  }
9224  return SQL_SUCCESS;
9225  case SQL_CONCURRENCY:
9226  if (val != (SQLPOINTER) SQL_CONCUR_LOCK) {
9227  goto e01s02;
9228  }
9229  return SQL_SUCCESS;
9230 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
9231  case SQL_ATTR_CURSOR_SENSITIVITY:
9232  if (val != (SQLPOINTER) SQL_UNSPECIFIED) {
9233  goto e01s02;
9234  }
9235  return SQL_SUCCESS;
9236 #endif
9237  case SQL_ATTR_QUERY_TIMEOUT:
9238  return SQL_SUCCESS;
9239  case SQL_ATTR_RETRIEVE_DATA:
9240  if (val != (SQLPOINTER) SQL_RD_ON &&
9241  val != (SQLPOINTER) SQL_RD_OFF) {
9242  goto e01s02;
9243  }
9244  s->retr_data = uval;
9245  return SQL_SUCCESS;
9246  case SQL_ROWSET_SIZE:
9247  case SQL_ATTR_ROW_ARRAY_SIZE:
9248  if (uval < 1) {
9249  setstat(s, -1, "invalid rowset size", "HY000");
9250  return SQL_ERROR;
9251  } else {
9252  SQLUSMALLINT *rst = &s->row_status1;
9253 
9254  if (uval > 1) {
9255  rst = xmalloc(sizeof (SQLUSMALLINT) * uval);
9256  if (!rst) {
9257  return nomem(s);
9258  }
9259  }
9260  if (s->row_status0 != &s->row_status1) {
9261  freep(&s->row_status0);
9262  }
9263  s->row_status0 = rst;
9264  s->rowset_size = uval;
9265  }
9266  return SQL_SUCCESS;
9267  case SQL_ATTR_ROW_STATUS_PTR:
9268  s->row_status = (SQLUSMALLINT *) val;
9269  return SQL_SUCCESS;
9270  case SQL_ATTR_ROWS_FETCHED_PTR:
9271  s->row_count = (SQLULEN *) val;
9272  return SQL_SUCCESS;
9273  case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
9274  s->parm_bind_offs = (SQLULEN *) val;
9275  return SQL_SUCCESS;
9276  case SQL_ATTR_PARAM_BIND_TYPE:
9277  s->parm_bind_type = uval;
9278  return SQL_SUCCESS;
9279  case SQL_ATTR_PARAM_OPERATION_PTR:
9280  s->parm_oper = (SQLUSMALLINT *) val;
9281  return SQL_SUCCESS;
9282  case SQL_ATTR_PARAM_STATUS_PTR:
9283  s->parm_status = (SQLUSMALLINT *) val;
9284  return SQL_SUCCESS;
9285  case SQL_ATTR_PARAMS_PROCESSED_PTR:
9286  s->parm_proc = (SQLULEN *) val;
9287  return SQL_SUCCESS;
9288  case SQL_ATTR_PARAMSET_SIZE:
9289  if (uval < 1) {
9290  goto e01s02;
9291  }
9292  s->paramset_size = uval;
9293  s->paramset_count = 0;
9294  return SQL_SUCCESS;
9295  case SQL_ATTR_ROW_BIND_TYPE:
9296  s->bind_type = uval;
9297  return SQL_SUCCESS;
9298  case SQL_ATTR_ROW_BIND_OFFSET_PTR:
9299  s->bind_offs = (SQLULEN *) val;
9300  return SQL_SUCCESS;
9301  case SQL_ATTR_USE_BOOKMARKS:
9302  if (val != (SQLPOINTER) SQL_UB_OFF &&
9303  val != (SQLPOINTER) SQL_UB_ON &&
9304  val != (SQLPOINTER) SQL_UB_VARIABLE) {
9305  goto e01s02;
9306  }
9307  if (*s->ov3 && val == (SQLPOINTER) SQL_UB_VARIABLE) {
9308  s->bkmrk = SQL_UB_VARIABLE;
9309  return SQL_SUCCESS;
9310  }
9311  if (val == (SQLPOINTER) SQL_UB_VARIABLE) {
9312  s->bkmrk = SQL_UB_ON;
9313  goto e01s02;
9314  }
9315  s->bkmrk = (val == (SQLPOINTER) SQL_UB_ON) ? SQL_UB_ON : SQL_UB_OFF;
9316  return SQL_SUCCESS;
9317  case SQL_ATTR_FETCH_BOOKMARK_PTR:
9318  s->bkmrkptr = (SQLINTEGER *) val;
9319  return SQL_SUCCESS;
9320  case SQL_ATTR_MAX_ROWS:
9321  s->max_rows = uval;
9322  return SQL_SUCCESS;
9323  case SQL_ATTR_MAX_LENGTH:
9324  if (val != (SQLPOINTER) 1000000000) {
9325  goto e01s02;
9326  }
9327  return SQL_SUCCESS;
9328 #ifdef SQL_ATTR_METADATA_ID
9329  case SQL_ATTR_METADATA_ID:
9330  if (val != (SQLPOINTER) SQL_FALSE) {
9331  goto e01s02;
9332  }
9333  return SQL_SUCCESS;
9334 #endif
9335  }
9336  return drvunimplstmt(stmt);
9337 }
9338 
9339 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
9340 
9349 SQLRETURN SQL_API
9350 SQLSetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9351  SQLINTEGER buflen)
9352 {
9353  SQLRETURN ret;
9354 
9355  HSTMT_LOCK(stmt);
9356  ret = drvsetstmtattr(stmt, attr, val, buflen);
9357  HSTMT_UNLOCK(stmt);
9358  return ret;
9359 }
9360 #endif
9361 
9362 #ifdef WINTERFACE
9363 
9372 SQLRETURN SQL_API
9373 SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9374  SQLINTEGER buflen)
9375 {
9376  SQLRETURN ret;
9377 
9378  HSTMT_LOCK(stmt);
9379  ret = drvsetstmtattr(stmt, attr, val, buflen);
9380  HSTMT_UNLOCK(stmt);
9381  return ret;
9382 }
9383 #endif
9384 
9393 static SQLRETURN
9394 drvgetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9395 {
9396  STMT *s = (STMT *) stmt;
9397  SQLUINTEGER *ret = (SQLUINTEGER *) param;
9398 
9399  switch (opt) {
9400  case SQL_QUERY_TIMEOUT:
9401  *ret = 0;
9402  return SQL_SUCCESS;
9403  case SQL_CURSOR_TYPE:
9404  *ret = s->curtype;
9405  return SQL_SUCCESS;
9406  case SQL_ROW_NUMBER:
9407  if (s->s3stmt) {
9408  *ret = (s->s3stmt_rownum < 0) ?
9409  SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
9410  } else {
9411  *ret = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
9412  }
9413  return SQL_SUCCESS;
9414  case SQL_ASYNC_ENABLE:
9415  *ret = SQL_ASYNC_ENABLE_OFF;
9416  return SQL_SUCCESS;
9417  case SQL_CONCURRENCY:
9418  *ret = SQL_CONCUR_LOCK;
9419  return SQL_SUCCESS;
9420  case SQL_ATTR_RETRIEVE_DATA:
9421  *ret = s->retr_data;
9422  return SQL_SUCCESS;
9423  case SQL_ROWSET_SIZE:
9424  case SQL_ATTR_ROW_ARRAY_SIZE:
9425  *ret = s->rowset_size;
9426  return SQL_SUCCESS;
9427  case SQL_ATTR_MAX_ROWS:
9428  *ret = s->max_rows;
9429  return SQL_SUCCESS;
9430  case SQL_ATTR_MAX_LENGTH:
9431  *ret = 1000000000;
9432  return SQL_SUCCESS;
9433  }
9434  return drvunimplstmt(stmt);
9435 }
9436 
9445 SQLRETURN SQL_API
9446 SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9447 {
9448  SQLRETURN ret;
9449 
9450  HSTMT_LOCK(stmt);
9451  ret = drvgetstmtoption(stmt, opt, param);
9452  HSTMT_UNLOCK(stmt);
9453  return ret;
9454 }
9455 
9456 #ifdef WINTERFACE
9457 
9465 SQLRETURN SQL_API
9466 SQLGetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9467 {
9468  SQLRETURN ret;
9469 
9470  HSTMT_LOCK(stmt);
9471  ret = drvgetstmtoption(stmt, opt, param);
9472  HSTMT_UNLOCK(stmt);
9473  return ret;
9474 }
9475 #endif
9476 
9485 static SQLRETURN
9486 drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
9487 {
9488  STMT *s = (STMT *) stmt;
9489 
9490  switch (opt) {
9491  case SQL_CURSOR_TYPE:
9492  if (param == SQL_CURSOR_FORWARD_ONLY) {
9493  s->curtype = param;
9494  } else {
9495  s->curtype = SQL_CURSOR_STATIC;
9496  }
9497  if (param != SQL_CURSOR_FORWARD_ONLY &&
9498  param != SQL_CURSOR_STATIC) {
9499  goto e01s02;
9500  }
9501  return SQL_SUCCESS;
9502  case SQL_ASYNC_ENABLE:
9503  if (param != SQL_ASYNC_ENABLE_OFF) {
9504  goto e01s02;
9505  }
9506  return SQL_SUCCESS;
9507  case SQL_CONCURRENCY:
9508  if (param != SQL_CONCUR_LOCK) {
9509  goto e01s02;
9510  }
9511  return SQL_SUCCESS;
9512  case SQL_QUERY_TIMEOUT:
9513  return SQL_SUCCESS;
9514  case SQL_RETRIEVE_DATA:
9515  if (param != SQL_RD_ON && param != SQL_RD_OFF) {
9516  e01s02:
9517  setstat(s, -1, "option value changed", "01S02");
9518  return SQL_SUCCESS_WITH_INFO;
9519  }
9520  s->retr_data = (int) param;
9521  return SQL_SUCCESS;
9522  case SQL_ROWSET_SIZE:
9523  case SQL_ATTR_ROW_ARRAY_SIZE:
9524  if (param < 1) {
9525  setstat(s, -1, "invalid rowset size", "HY000");
9526  return SQL_ERROR;
9527  } else {
9528  SQLUSMALLINT *rst = &s->row_status1;
9529 
9530  if (param > 1) {
9531  rst = xmalloc(sizeof (SQLUSMALLINT) * param);
9532  if (!rst) {
9533  return nomem(s);
9534  }
9535  }
9536  if (s->row_status0 != &s->row_status1) {
9537  freep(&s->row_status0);
9538  }
9539  s->row_status0 = rst;
9540  s->rowset_size = param;
9541  }
9542  return SQL_SUCCESS;
9543  case SQL_ATTR_MAX_ROWS:
9544  s->max_rows = param;
9545  return SQL_SUCCESS;
9546  case SQL_ATTR_MAX_LENGTH:
9547  if (param != 1000000000) {
9548  goto e01s02;
9549  }
9550  return SQL_SUCCESS;
9551  }
9552  return drvunimplstmt(stmt);
9553 }
9554 
9563 SQLRETURN SQL_API
9564 SQLSetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt,
9566 {
9567  SQLRETURN ret;
9568 
9569  HSTMT_LOCK(stmt);
9570  ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
9571  HSTMT_UNLOCK(stmt);
9572  return ret;
9573 }
9574 
9575 #ifdef WINTERFACE
9576 
9584 SQLRETURN SQL_API
9585 SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt,
9587 {
9588  SQLRETURN ret;
9589 
9590  HSTMT_LOCK(stmt);
9591  ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
9592  HSTMT_UNLOCK(stmt);
9593  return ret;
9594 }
9595 #endif
9596 
9603 static SQLRETURN
9605 {
9606  int i;
9607 
9608  if (!s->bindcols || s->nbindcols < s->ncols) {
9609 unbound:
9610  setstat(s, -1, "unbound columns", (*s->ov3) ? "HY000" : "S1000");
9611  return SQL_ERROR;
9612  }
9613  for (i = 0; i < s->ncols; i++) {
9614  BINDCOL *b = &s->bindcols[i];
9615 
9616  if (b->type == SQL_UNKNOWN_TYPE || !b->valp) {
9617  goto unbound;
9618  }
9619  }
9620  return SQL_SUCCESS;
9621 }
9622 
9634 static SQLRETURN
9635 setposbind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
9636 {
9637  DBC *d = (DBC *) s->dbc;
9638  SQLPOINTER dp = 0;
9639  SQLLEN *lp = 0;
9640  BINDCOL *b = &s->bindcols[i];
9641  COL *c = &s->cols[i];
9642  char strbuf[128], *cp;
9643 
9644  if (b->valp) {
9645  if (s->bind_type != SQL_BIND_BY_COLUMN) {
9646  dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
9647  } else {
9648  dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
9649  }
9650  if (s->bind_offs) {
9651  dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
9652  }
9653  }
9654  if (b->lenp) {
9655  if (s->bind_type != SQL_BIND_BY_COLUMN) {
9656  lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
9657  } else {
9658  lp = b->lenp + rsi;
9659  }
9660  if (s->bind_offs) {
9661  lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
9662  }
9663  }
9664  if (!dp || !lp) {
9665  setstat(s, -1, "unbound column in positional update",
9666  (*s->ov3) ? "HY000" : "S1000");
9667  return SQL_ERROR;
9668  }
9669  if (*lp == SQL_NULL_DATA) {
9670  sqlite3_bind_null(stmt, si);
9671  if (d->trace) {
9672  fprintf(d->trace, "-- parameter %d: NULL\n", si);
9673  fflush(d->trace);
9674  }
9675  return SQL_SUCCESS;
9676  }
9677  switch (b->type) {
9678  case SQL_C_UTINYINT:
9679  case SQL_C_TINYINT:
9680  case SQL_C_STINYINT:
9681  sqlite3_bind_int(stmt, si, *(SQLCHAR *) dp);
9682  if (d->trace) {
9683  fprintf(d->trace, "-- parameter %d: %d\n", si, *(SQLCHAR *) dp);
9684  fflush(d->trace);
9685  }
9686  break;
9687 #ifdef SQL_BIT
9688  case SQL_C_BIT:
9689  sqlite3_bind_int(stmt, si, (*(SQLCHAR *) dp) ? 1 : 0);
9690  if (d->trace) {
9691  fprintf(d->trace, "-- parameter %d: %d\n", si,
9692  (*(SQLCHAR *) dp) ? 1 : 0);
9693  fflush(d->trace);
9694  }
9695  break;
9696 #endif
9697  case SQL_C_USHORT:
9698  sqlite3_bind_int(stmt, si, *(SQLUSMALLINT *) dp);
9699  if (d->trace) {
9700  fprintf(d->trace, "-- parameter %d: %d\n", si,
9701  *(SQLUSMALLINT *) dp);
9702  fflush(d->trace);
9703  }
9704  break;
9705  case SQL_C_SHORT:
9706  case SQL_C_SSHORT:
9707  sqlite3_bind_int(stmt, si, *(SQLSMALLINT *) dp);
9708  if (d->trace) {
9709  fprintf(d->trace, "-- parameter %d: %d\n", si,
9710  *(SQLSMALLINT *) dp);
9711  fflush(d->trace);
9712  }
9713  break;
9714  case SQL_C_ULONG:
9715  sqlite3_bind_int(stmt, si, *(SQLUINTEGER *) dp);
9716  if (d->trace) {
9717  fprintf(d->trace, "-- parameter %d: %ld\n", si,
9718  (long) *(SQLUINTEGER *) dp);
9719  fflush(d->trace);
9720  }
9721  break;
9722  case SQL_C_LONG:
9723  case SQL_C_SLONG:
9724  sqlite3_bind_int(stmt, si, *(SQLINTEGER *) dp);
9725  if (d->trace) {
9726  fprintf(d->trace, "-- parameter %d: %ld\n", si,
9727  (long) *(SQLINTEGER *) dp);
9728  fflush(d->trace);
9729  }
9730  break;
9731 #ifdef SQL_BIGINT
9732  case SQL_C_UBIGINT:
9733  case SQL_C_SBIGINT:
9734  sqlite3_bind_int64(stmt, si, *(SQLBIGINT *) dp);
9735  if (d->trace) {
9736  fprintf(d->trace,
9737 #ifdef _WIN32
9738  "-- parameter %d: %I64d\n",
9739 #else
9740  "-- parameter %d: %lld\n",
9741 #endif
9742  si, (sqlite_int64) *(SQLBIGINT *) dp);
9743  fflush(d->trace);
9744  }
9745  break;
9746 #endif
9747  case SQL_C_FLOAT:
9748  sqlite3_bind_double(stmt, si, *(float *) dp);
9749  if (d->trace) {
9750  fprintf(d->trace, "-- parameter %d: %g\n", si,
9751  *(float *) dp);
9752  fflush(d->trace);
9753  }
9754  break;
9755  case SQL_C_DOUBLE:
9756  sqlite3_bind_double(stmt, si, *(double *) dp);
9757  if (d->trace) {
9758  fprintf(d->trace, "-- parameter %d: %g\n", si,
9759  *(double *) dp);
9760  fflush(d->trace);
9761  }
9762  break;
9763  case SQL_C_BINARY:
9764  sqlite3_bind_blob(stmt, si, (char *) dp, *lp, SQLITE_STATIC);
9765  if (d->trace) {
9766  fprintf(d->trace, "-- parameter %d: [BLOB]\n", si);
9767  fflush(d->trace);
9768  }
9769  break;
9770 #ifdef WCHARSUPPORT
9771  case SQL_C_WCHAR:
9772  cp = uc_to_utf((SQLWCHAR *) dp, *lp);
9773  if (!cp) {
9774  return nomem(s);
9775  }
9776  sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
9777  if (d->trace) {
9778  fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
9779  fflush(d->trace);
9780  }
9781  uc_free(cp);
9782  break;
9783 #endif
9784  case SQL_C_CHAR:
9785 #if defined(_WIN32) || defined(_WIN64)
9786  if (*s->oemcp) {
9787  cp = wmb_to_utf((char *) dp, *lp);
9788  if (!cp) {
9789  return nomem(s);
9790  }
9791  sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
9792  if (d->trace) {
9793  fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
9794  fflush(d->trace);
9795  }
9796  uc_free(cp);
9797  } else
9798 #endif
9799  {
9800  if (*lp == SQL_NTS) {
9801  sqlite3_bind_text(stmt, si, (char *) dp, -1,
9802  SQLITE_STATIC);
9803  if (d->trace) {
9804  fprintf(d->trace, "-- parameter %d: '%s'\n", si,
9805  (char *) dp);
9806  fflush(d->trace);
9807  }
9808  } else {
9809  sqlite3_bind_text(stmt, si, (char *) dp, *lp,
9810  SQLITE_STATIC);
9811  if (d->trace) {
9812  fprintf(d->trace, "-- parameter %d: '%*s'\n", si,
9813  (int) *lp, (char *) dp);
9814  fflush(d->trace);
9815  }
9816  }
9817  }
9818  break;
9819 #ifdef SQL_C_TYPE_DATE
9820  case SQL_C_TYPE_DATE:
9821 #endif
9822  case SQL_C_DATE:
9823  if (*s->jdconv) {
9824  int a, b, x1, x2, y, m, dd;
9825  double v;
9826 
9827  y = ((DATE_STRUCT *) dp)->year;
9828  m = ((DATE_STRUCT *) dp)->month;
9829  dd = ((DATE_STRUCT *) dp)->day;
9830  if (m <= 2) {
9831  y--;
9832  m += 12;
9833  }
9834  a = y / 100;
9835  b = 2 - a + (a / 4);
9836  x1 = 36525 * (y + 4716) / 100;
9837  x2 = 306001 * (m + 1) / 10000;
9838  v = x1 + x2 + dd + b - 1524.5;
9839  sqlite3_bind_double(stmt, si, v);
9840  if (d->trace) {
9841  fprintf(d->trace, "-- parameter %d: %g\n", si, v);
9842  fflush(d->trace);
9843  }
9844  } else {
9845  sprintf(strbuf, "%04d-%02d-%02d",
9846  ((DATE_STRUCT *) dp)->year,
9847  ((DATE_STRUCT *) dp)->month,
9848  ((DATE_STRUCT *) dp)->day);
9849  sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
9850  if (d->trace) {
9851  fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
9852  fflush(d->trace);
9853  }
9854  }
9855  break;
9856 #ifdef SQL_C_TYPE_TIME
9857  case SQL_C_TYPE_TIME:
9858 #endif
9859  case SQL_C_TIME:
9860  if (*s->jdconv) {
9861  double v;
9862 
9863  v = 2451544.5 +
9864  (((TIME_STRUCT *) dp)->hour * 3600000.0 +
9865  ((TIME_STRUCT *) dp)->minute * 60000.0 +
9866  ((TIME_STRUCT *) dp)->second * 1000.0) / 86400000.0;
9867  sqlite3_bind_double(stmt, si, v);
9868  if (d->trace) {
9869  fprintf(d->trace, "-- parameter %d: %g\n", si, v);
9870  fflush(d->trace);
9871  }
9872  } else {
9873  sprintf(strbuf, "%02d:%02d:%02d",
9874  ((TIME_STRUCT *) dp)->hour,
9875  ((TIME_STRUCT *) dp)->minute,
9876  ((TIME_STRUCT *) dp)->second);
9877  sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
9878  if (d->trace) {
9879  fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
9880  fflush(d->trace);
9881  }
9882  }
9883  break;
9884 #ifdef SQL_C_TYPE_TIMESTAMP
9885  case SQL_C_TYPE_TIMESTAMP:
9886 #endif
9887  case SQL_C_TIMESTAMP:
9888  if (*s->jdconv) {
9889  int a, b, x1, x2, y, m, dd;
9890  double v;
9891 
9892  y = ((TIMESTAMP_STRUCT *) dp)->year;
9893  m = ((TIMESTAMP_STRUCT *) dp)->month;
9894  dd = ((TIMESTAMP_STRUCT *) dp)->day;
9895  if (m <= 2) {
9896  y--;
9897  m += 12;
9898  }
9899  a = y / 100;
9900  b = 2 - a + (a / 4);
9901  x1 = 36525 * (y + 4716) / 100;
9902  x2 = 306001 * (m + 1) / 10000;
9903  v = x1 + x2 + dd + b - 1524.5 +
9904  (((TIMESTAMP_STRUCT *) dp)->hour * 3600000.0 +
9905  ((TIMESTAMP_STRUCT *) dp)->minute * 60000.0 +
9906  ((TIMESTAMP_STRUCT *) dp)->second * 1000.0 +
9907  ((TIMESTAMP_STRUCT *) dp)->fraction / 1.0E6)
9908  / 86400000.0;
9909  sqlite3_bind_double(stmt, si, v);
9910  if (d->trace) {
9911  fprintf(d->trace, "-- parameter %d: %g\n", si, v);
9912  fflush(d->trace);
9913  }
9914  } else {
9915  int frac;
9916 
9917  frac = (int) ((TIMESTAMP_STRUCT *) dp)->fraction;
9918  frac /= 1000000;
9919  frac = frac % 1000;
9920  if (frac < 0) {
9921  frac = 0;
9922  }
9923  if (c->prec && c->prec <= 16) {
9924  sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:00.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  } else if (c->prec && c->prec <= 19) {
9931  sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
9932  ((TIMESTAMP_STRUCT *) dp)->year,
9933  ((TIMESTAMP_STRUCT *) dp)->month,
9934  ((TIMESTAMP_STRUCT *) dp)->day,
9935  ((TIMESTAMP_STRUCT *) dp)->hour,
9936  ((TIMESTAMP_STRUCT *) dp)->minute,
9937  ((TIMESTAMP_STRUCT *) dp)->second);
9938  } else {
9939  sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
9940  ((TIMESTAMP_STRUCT *) dp)->year,
9941  ((TIMESTAMP_STRUCT *) dp)->month,
9942  ((TIMESTAMP_STRUCT *) dp)->day,
9943  ((TIMESTAMP_STRUCT *) dp)->hour,
9944  ((TIMESTAMP_STRUCT *) dp)->minute,
9945  ((TIMESTAMP_STRUCT *) dp)->second,
9946  frac);
9947  }
9948  sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
9949  if (d->trace) {
9950  fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
9951  fflush(d->trace);
9952  }
9953  }
9954  break;
9955  default:
9956  setstat(s, -1, "unsupported column type in positional update",
9957  (*s->ov3) ? "HY000" : "S1000");
9958  return SQL_ERROR;
9959  }
9960  return SQL_SUCCESS;
9961 }
9962 
9974 static SQLRETURN
9975 setposibind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
9976 {
9977  DBC *d = (DBC *) s->dbc;
9978  char **data;
9979  int pos;
9980 
9981  pos = s->rowprs;
9982  if (pos < 0) {
9983  setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
9984  return SQL_ERROR;
9985  }
9986  pos += rsi;
9987  data = s->rows + s->ncols + (pos * s->ncols) + i;
9988  if (*data == NULL) {
9989  sqlite3_bind_null(stmt, si);
9990  if (d->trace) {
9991  fprintf(d->trace, "-- parameter %d: NULL\n", si);
9992  fflush(d->trace);
9993  }
9994  } else {
9995  sqlite3_bind_text(stmt, si, *data, -1, SQLITE_STATIC);
9996  if (d->trace) {
9997  fprintf(d->trace, "-- parameter %d: '%s'\n", si, *data);
9998  fflush(d->trace);
9999  }
10000  }
10001  return SQL_SUCCESS;
10002 }
10003 
10011 static SQLRETURN
10012 setposrefr(STMT *s, int rsi)
10013 {
10014  int i, withinfo = 0;
10015  SQLRETURN ret = SQL_SUCCESS;
10016 
10017  for (i = 0; s->bindcols && i < s->ncols; i++) {
10018  BINDCOL *b = &s->bindcols[i];
10019  SQLPOINTER dp = 0;
10020  SQLLEN *lp = 0;
10021 
10022  b->offs = 0;
10023  if (b->valp) {
10024  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10025  dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
10026  } else {
10027  dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
10028  }
10029  if (s->bind_offs) {
10030  dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
10031  }
10032  }
10033  if (b->lenp) {
10034  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10035  lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
10036  } else {
10037  lp = b->lenp + rsi;
10038  }
10039  if (s->bind_offs) {
10040  lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
10041  }
10042  }
10043  if (dp || lp) {
10044  int rowp = s->rowp;
10045 
10046  s->rowp = s->rowprs + rsi;
10047  ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp,
10048  b->max, lp, 0);
10049  s->rowp = rowp;
10050  if (!SQL_SUCCEEDED(ret)) {
10051  s->row_status0[rsi] = SQL_ROW_ERROR;
10052  break;
10053  }
10054  if (ret != SQL_SUCCESS) {
10055  withinfo = 1;
10056 #ifdef SQL_ROW_SUCCESS_WITH_INFO
10057  s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
10058 #endif
10059  }
10060  }
10061  }
10062  if (SQL_SUCCEEDED(ret)) {
10063  ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
10064  }
10065  return ret;
10066 }
10067 
10077 static SQLRETURN
10078 drvsetpos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10079 {
10080  STMT *s = (STMT *) stmt;
10081  DBC *d = (DBC *) s->dbc;
10082  int rowp, i, k, rc, nretry = 0;
10083  dstr *sql = 0;
10084  const char *endp;
10085  sqlite3_stmt *s3stmt = NULL;
10086  SQLRETURN ret;
10087 
10088  if (lock != SQL_LOCK_NO_CHANGE) {
10089  setstat(s, -1, "unsupported locking mode",
10090  (*s->ov3) ? "HY000" : "S1000");
10091  return SQL_ERROR;
10092  }
10093  if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10094  setstat(s, -1, "incompatible statement",
10095  (*s->ov3) ? "HY000" : "S1000");
10096  return SQL_ERROR;
10097  }
10098  if (op == SQL_ADD) {
10099  if (s->one_tbl <= 0) {
10100  setstat(s, -1, "incompatible rowset",
10101  (*s->ov3) ? "HY000" : "S1000");
10102  return SQL_ERROR;
10103  }
10104  if (row == 0 || row > s->rowset_size + 1) {
10105  goto rowoor;
10106  }
10107  ret = chkunbound(s);
10108  if (ret != SQL_SUCCESS) {
10109  return ret;
10110  }
10111  sql = dsappend(sql, "INSERT INTO ");
10112  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10113  sql = dsappendq(sql, s->dyncols[0].db);
10114  sql = dsappend(sql, ".");
10115  }
10116  sql = dsappendq(sql, s->dyncols[0].table);
10117  for (i = 0; i < s->ncols; i++) {
10118  sql = dsappend(sql, (i > 0) ? "," : "(");
10119  sql = dsappendq(sql, s->dyncols[i].column);
10120  }
10121  sql = dsappend(sql, ") VALUES ");
10122  for (i = 0; i < s->ncols; i++) {
10123  sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10124  }
10125  sql = dsappend(sql, ")");
10126  if (dserr(sql)) {
10127  dsfree(sql);
10128  return nomem(s);
10129  }
10130 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10131  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10132 #else
10133  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10134 #endif
10135  do {
10136  s3stmt = NULL;
10137 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10138  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10139  &s3stmt, &endp);
10140 #else
10141  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10142  &s3stmt, &endp);
10143 #endif
10144  if (rc != SQLITE_OK) {
10145  if (s3stmt) {
10146  sqlite3_finalize(s3stmt);
10147  s3stmt = NULL;
10148  }
10149  }
10150  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10151  dbtracerc(d, rc, NULL);
10152  dsfree(sql);
10153  if (rc != SQLITE_OK) {
10154 istmterr:
10155  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10156  sqlite3_errmsg(d->sqlite), rc);
10157  if (s3stmt) {
10158  dbtraceapi(d, "sqlite3_finalize", NULL);
10159  sqlite3_finalize(s3stmt);
10160  }
10161  return SQL_ERROR;
10162  }
10163  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10164  ret = setposbind(s, s3stmt, i, k, row - 1);
10165  if (ret != SQL_SUCCESS) {
10166  dbtraceapi(d, "sqlite3_finalize", NULL);
10167  sqlite3_finalize(s3stmt);
10168  return ret;
10169  }
10170  k++;
10171  }
10172  rc = sqlite3_step(s3stmt);
10173  if (rc != SQLITE_DONE) {
10174  goto istmterr;
10175  }
10176  sqlite3_finalize(s3stmt);
10177  if (sqlite3_changes(d->sqlite) > 0 && row <= s->rowset_size) {
10178  if (s->row_status0) {
10179  s->row_status0[row - 1] = SQL_ROW_ADDED;
10180  }
10181  if (s->row_status) {
10182  s->row_status[row - 1] = SQL_ROW_ADDED;
10183  }
10184  }
10185  return SQL_SUCCESS;
10186  } else if (op == SQL_UPDATE || op == SQL_DELETE) {
10187  if (s->one_tbl <= 0 || s->has_pk <= 0) {
10188  setstat(s, -1, "incompatible rowset",
10189  (*s->ov3) ? "HY000" : "S1000");
10190  return SQL_ERROR;
10191  }
10192  if (row == 0) {
10193  ret = SQL_SUCCESS;
10194  for (i = 1; i <= s->rowset_size; i++) {
10195  ret = drvsetpos(stmt, i, op, lock);
10196  if (!SQL_SUCCEEDED(ret)) {
10197  break;
10198  }
10199  }
10200  return ret;
10201  }
10202  if (row > s->rowset_size) {
10203  goto rowoor;
10204  }
10205  }
10206  if (op != SQL_POSITION && op != SQL_REFRESH &&
10207  op != SQL_DELETE && op != SQL_UPDATE) {
10208  return drvunimplstmt(stmt);
10209  }
10210  if (op == SQL_POSITION) {
10211  rowp = s->rowp + row - 1;
10212  if (!s->rows || row == 0 || rowp < -1 || rowp >= s->nrows) {
10213 rowoor:
10214  setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
10215  return SQL_ERROR;
10216  }
10217  s->rowp = rowp;
10218  } else if (op == SQL_REFRESH) {
10219  if (row > s->rowset_size) {
10220  goto rowoor;
10221  }
10222  if (row == 0) {
10223  ret = SQL_SUCCESS;
10224  for (i = 0; i < s->rowset_size; i++) {
10225  ret = setposrefr(s, i);
10226  if (!SQL_SUCCEEDED(ret)) {
10227  break;
10228  }
10229  }
10230  return ret;
10231  }
10232  return setposrefr(s, row - 1);
10233  } else if (op == SQL_DELETE) {
10234  sql = dsappend(sql, "DELETE FROM ");
10235  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10236  sql = dsappendq(sql, s->dyncols[0].db);
10237  sql = dsappend(sql, ".");
10238  }
10239  sql = dsappendq(sql, s->dyncols[0].table);
10240  for (i = k = 0; i < s->ncols; i++) {
10241  if (s->dyncols[i].ispk <= 0) {
10242  continue;
10243  }
10244  sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10245  sql = dsappendq(sql, s->dyncols[i].column);
10246  sql = dsappend(sql, " = ?");
10247  k++;
10248  }
10249  if (dserr(sql)) {
10250  dsfree(sql);
10251  return nomem(s);
10252  }
10253 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10254  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10255 #else
10256  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10257 #endif
10258  do {
10259  s3stmt = NULL;
10260 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10261  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10262  &s3stmt, &endp);
10263 #else
10264  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10265  &s3stmt, &endp);
10266 #endif
10267  if (rc != SQLITE_OK) {
10268  if (s3stmt) {
10269  sqlite3_finalize(s3stmt);
10270  s3stmt = NULL;
10271  }
10272  }
10273  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10274  dbtracerc(d, rc, NULL);
10275  dsfree(sql);
10276  if (rc != SQLITE_OK) {
10277 dstmterr:
10278  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10279  sqlite3_errmsg(d->sqlite), rc);
10280  if (s3stmt) {
10281  dbtraceapi(d, "sqlite3_finalize", NULL);
10282  sqlite3_finalize(s3stmt);
10283  }
10284  return SQL_ERROR;
10285  }
10286  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10287  if (s->dyncols[i].ispk <= 0) {
10288  continue;
10289  }
10290  ret = setposibind(s, s3stmt, i, k, row - 1);
10291  if (ret != SQL_SUCCESS) {
10292  dbtraceapi(d, "sqlite3_finalize", NULL);
10293  sqlite3_finalize(s3stmt);
10294  return ret;
10295  }
10296  k++;
10297  }
10298  rc = sqlite3_step(s3stmt);
10299  if (rc != SQLITE_DONE) {
10300  goto dstmterr;
10301  }
10302  sqlite3_finalize(s3stmt);
10303  if (sqlite3_changes(d->sqlite) > 0) {
10304  if (s->row_status0) {
10305  s->row_status0[row - 1] = SQL_ROW_DELETED;
10306  }
10307  if (s->row_status) {
10308  s->row_status[row - 1] = SQL_ROW_DELETED;
10309  }
10310  }
10311  return SQL_SUCCESS;
10312  } else if (op == SQL_UPDATE) {
10313  ret = chkunbound(s);
10314  if (ret != SQL_SUCCESS) {
10315  return ret;
10316  }
10317  sql = dsappend(sql, "UPDATE ");
10318  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10319  sql = dsappendq(sql, s->dyncols[0].db);
10320  sql = dsappend(sql, ".");
10321  }
10322  sql = dsappendq(sql, s->dyncols[0].table);
10323  for (i = 0; i < s->ncols; i++) {
10324  sql = dsappend(sql, (i > 0) ? ", " : " SET ");
10325  sql = dsappendq(sql, s->dyncols[i].column);
10326  sql = dsappend(sql, " = ?");
10327  }
10328  for (i = k = 0; i < s->ncols; i++) {
10329  if (s->dyncols[i].ispk <= 0) {
10330  continue;
10331  }
10332  sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10333  sql = dsappendq(sql, s->dyncols[i].column);
10334  sql = dsappend(sql, " = ?");
10335  k++;
10336  }
10337  if (dserr(sql)) {
10338  dsfree(sql);
10339  return nomem(s);
10340  }
10341 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10342  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10343 #else
10344  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10345 #endif
10346  do {
10347  s3stmt = NULL;
10348 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10349  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10350  &s3stmt, &endp);
10351 #else
10352  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10353  &s3stmt, &endp);
10354 #endif
10355  if (rc != SQLITE_OK) {
10356  if (s3stmt) {
10357  sqlite3_finalize(s3stmt);
10358  s3stmt = NULL;
10359  }
10360  }
10361  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10362  dbtracerc(d, rc, NULL);
10363  dsfree(sql);
10364  if (rc != SQLITE_OK) {
10365 ustmterr:
10366  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10367  sqlite3_errmsg(d->sqlite), rc);
10368  if (s3stmt) {
10369  dbtraceapi(d, "sqlite3_finalize", NULL);
10370  sqlite3_finalize(s3stmt);
10371  }
10372  return SQL_ERROR;
10373  }
10374  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10375  ret = setposbind(s, s3stmt, i, k, row - 1);
10376  if (ret != SQL_SUCCESS) {
10377  dbtraceapi(d, "sqlite3_finalize", NULL);
10378  sqlite3_finalize(s3stmt);
10379  return ret;
10380  }
10381  k++;
10382  }
10383  for (i = 0; s->bindcols && i < s->ncols; i++) {
10384  if (s->dyncols[i].ispk <= 0) {
10385  continue;
10386  }
10387  ret = setposibind(s, s3stmt, i, k, row - 1);
10388  if (ret != SQL_SUCCESS) {
10389  dbtraceapi(d, "sqlite3_finalize", NULL);
10390  sqlite3_finalize(s3stmt);
10391  return ret;
10392  }
10393  k++;
10394  }
10395  rc = sqlite3_step(s3stmt);
10396  if (rc != SQLITE_DONE) {
10397  goto ustmterr;
10398  }
10399  sqlite3_finalize(s3stmt);
10400  if (sqlite3_changes(d->sqlite) > 0) {
10401  if (s->row_status0) {
10402  s->row_status0[row - 1] = SQL_ROW_UPDATED;
10403  }
10404  if (s->row_status) {
10405  s->row_status[row - 1] = SQL_ROW_UPDATED;
10406  }
10407  }
10408  return SQL_SUCCESS;
10409  }
10410  return SQL_SUCCESS;
10411 }
10412 
10422 SQLRETURN SQL_API
10423 SQLSetPos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10424 {
10425  SQLRETURN ret;
10426 
10427  HSTMT_LOCK(stmt);
10428  ret = drvsetpos(stmt, row, op, lock);
10429  HSTMT_UNLOCK(stmt);
10430  return ret;
10431 }
10432 
10440 static SQLRETURN
10441 drvbulkoperations(SQLHSTMT stmt, SQLSMALLINT op)
10442 {
10443  STMT *s = (STMT *) stmt;
10444  DBC *d = (DBC *) s->dbc;
10445  int row, i, k, rc, nretry = 0;
10446  dstr *sql = 0;
10447  const char *endp;
10448  sqlite3_stmt *s3stmt = NULL;
10449  SQLRETURN ret;
10450 
10451  if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10452  setstat(s, -1, "incompatible statement",
10453  (*s->ov3) ? "HY000" : "S1000");
10454  return SQL_ERROR;
10455  }
10456  if (op == SQL_ADD) {
10457  if (s->one_tbl <= 0) {
10458  setstat(s, -1, "incompatible rowset",
10459  (*s->ov3) ? "HY000" : "S1000");
10460  return SQL_ERROR;
10461  }
10462  ret = chkunbound(s);
10463  if (ret != SQL_SUCCESS) {
10464  return ret;
10465  }
10466  sql = dsappend(sql, "INSERT INTO ");
10467  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10468  sql = dsappendq(sql, s->dyncols[0].db);
10469  sql = dsappend(sql, ".");
10470  }
10471  sql = dsappendq(sql, s->dyncols[0].table);
10472  for (i = 0; i < s->ncols; i++) {
10473  sql = dsappend(sql, (i > 0) ? "," : "(");
10474  sql = dsappendq(sql, s->dyncols[i].column);
10475  }
10476  sql = dsappend(sql, ") VALUES ");
10477  for (i = 0; i < s->ncols; i++) {
10478  sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10479  }
10480  sql = dsappend(sql, ")");
10481  if (dserr(sql)) {
10482  dsfree(sql);
10483  return nomem(s);
10484  }
10485 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10486  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10487 #else
10488  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10489 #endif
10490  do {
10491  s3stmt = NULL;
10492 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10493  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10494  &s3stmt, &endp);
10495 #else
10496  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10497  &s3stmt, &endp);
10498 #endif
10499  if (rc != SQLITE_OK) {
10500  if (s3stmt) {
10501  sqlite3_finalize(s3stmt);
10502  s3stmt = NULL;
10503  }
10504  }
10505  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10506  dbtracerc(d, rc, NULL);
10507  dsfree(sql);
10508  if (rc != SQLITE_OK) {
10509  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10510  sqlite3_errmsg(d->sqlite), rc);
10511  if (s3stmt) {
10512  dbtraceapi(d, "sqlite3_finalize", NULL);
10513  sqlite3_finalize(s3stmt);
10514  }
10515  return SQL_ERROR;
10516  }
10517  for (row = 0; row < s->rowset_size; row++) {
10518  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10519  ret = setposbind(s, s3stmt, i, k, row);
10520  if (ret != SQL_SUCCESS) {
10521 istmterr:
10522  if (s->row_status0) {
10523  s->row_status0[row] = SQL_ROW_ERROR;
10524  }
10525  if (s->row_status) {
10526  s->row_status[row] = SQL_ROW_ERROR;
10527  }
10528  dbtraceapi(d, "sqlite3_finalize", NULL);
10529  sqlite3_finalize(s3stmt);
10530  return ret;
10531  }
10532  k++;
10533  }
10534  rc = sqlite3_step(s3stmt);
10535  if (rc != SQLITE_DONE) {
10536  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10537  sqlite3_errmsg(d->sqlite), rc);
10538  ret = SQL_ERROR;
10539  goto istmterr;
10540  }
10541  if (sqlite3_changes(d->sqlite) > 0) {
10542  if (s->row_status0) {
10543  s->row_status0[row] = SQL_ROW_ADDED;
10544  }
10545  if (s->row_status) {
10546  s->row_status[row] = SQL_ROW_ADDED;
10547  }
10548  }
10549  if (s->bkmrk == SQL_UB_VARIABLE &&
10550  s->bkmrkcol.type == SQL_C_VARBOOKMARK &&
10551  s->bkmrkcol.valp) {
10552  SQLPOINTER *val;
10553 
10554  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10555  val = (SQLPOINTER)
10556  ((char *) s->bkmrkcol.valp + s->bind_type * row);
10557  } else {
10558  val = (SQLPOINTER)
10559  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10560  }
10561  if (s->bind_offs) {
10562  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10563  }
10564  *(sqlite_int64 *) val = sqlite3_last_insert_rowid(d->sqlite);
10565  if (s->bkmrkcol.lenp) {
10566  SQLLEN *ival;
10567 
10568  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10569  ival = (SQLLEN *)
10570  ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10571  } else {
10572  ival = &s->bkmrkcol.lenp[row];
10573  }
10574  if (s->bind_offs) {
10575  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10576  }
10577  *ival = sizeof (sqlite_int64);
10578  }
10579  }
10580  dbtraceapi(d, "sqlite3_reset", NULL);
10581  sqlite3_reset(s3stmt);
10582  }
10583  dbtraceapi(d, "sqlite3_finalize", NULL);
10584  sqlite3_finalize(s3stmt);
10585  return SQL_SUCCESS;
10586  } else if (op == SQL_DELETE_BY_BOOKMARK) {
10587  if (s->has_rowid < 0 ||
10588  s->bkmrk != SQL_UB_VARIABLE ||
10589  s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10590  !s->bkmrkcol.valp) {
10591  setstat(s, -1, "incompatible rowset",
10592  (*s->ov3) ? "HY000" : "S1000");
10593  return SQL_ERROR;
10594  }
10595  sql = dsappend(sql, "DELETE FROM ");
10596  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10597  sql = dsappendq(sql, s->dyncols[0].db);
10598  sql = dsappend(sql, ".");
10599  }
10600  sql = dsappendq(sql, s->dyncols[0].table);
10601  sql = dsappend(sql, " WHERE ");
10602  sql = dsappendq(sql, s->dyncols[0].column);
10603  sql = dsappend(sql, " = ?");
10604  if (dserr(sql)) {
10605  dsfree(sql);
10606  return nomem(s);
10607  }
10608 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10609  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10610 #else
10611  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10612 #endif
10613  do {
10614  s3stmt = NULL;
10615 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10616  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10617  &s3stmt, &endp);
10618 #else
10619  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10620  &s3stmt, &endp);
10621 #endif
10622  if (rc != SQLITE_OK) {
10623  if (s3stmt) {
10624  sqlite3_finalize(s3stmt);
10625  s3stmt = NULL;
10626  }
10627  }
10628  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10629  dbtracerc(d, rc, NULL);
10630  dsfree(sql);
10631  if (rc != SQLITE_OK) {
10632  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10633  sqlite3_errmsg(d->sqlite), rc);
10634  if (s3stmt) {
10635  dbtraceapi(d, "sqlite3_finalize", NULL);
10636  sqlite3_finalize(s3stmt);
10637  }
10638  return SQL_ERROR;
10639  }
10640  for (row = 0; row < s->rowset_size; row++) {
10641  SQLPOINTER *val;
10642  sqlite_int64 rowid;
10643 
10644  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10645  val = (SQLPOINTER)
10646  ((char *) s->bkmrkcol.valp + s->bind_type * row);
10647  } else {
10648  val = (SQLPOINTER)
10649  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10650  }
10651  if (s->bind_offs) {
10652  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10653  }
10654  if (s->bkmrkcol.lenp) {
10655  SQLLEN *ival;
10656 
10657  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10658  ival = (SQLLEN *)
10659  ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10660  } else {
10661  ival = &s->bkmrkcol.lenp[row];
10662  }
10663  if (s->bind_offs) {
10664  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10665  }
10666  if (*ival != sizeof (sqlite_int64)) {
10667  continue;
10668  }
10669  }
10670  rowid = *(sqlite_int64 *) val;
10671  sqlite3_bind_int64(s3stmt, 1, rowid);
10672  if (d->trace) {
10673  fprintf(d->trace,
10674 #ifdef _WIN32
10675  "-- parameter 1: %I64d\n",
10676 #else
10677  "-- parameter 1: %lld\n",
10678 #endif
10679  rowid);
10680  fflush(d->trace);
10681  }
10682  rc = sqlite3_step(s3stmt);
10683  if (rc != SQLITE_DONE) {
10684  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10685  sqlite3_errmsg(d->sqlite), rc);
10686  if (s->row_status0) {
10687  s->row_status0[row] = SQL_ROW_ERROR;
10688  }
10689  if (s->row_status) {
10690  s->row_status[row] = SQL_ROW_ERROR;
10691  }
10692  dbtraceapi(d, "sqlite3_finalize", NULL);
10693  sqlite3_finalize(s3stmt);
10694  return SQL_ERROR;
10695  }
10696  if (sqlite3_changes(d->sqlite) > 0) {
10697  if (s->row_status0) {
10698  s->row_status0[row] = SQL_ROW_DELETED;
10699  }
10700  if (s->row_status) {
10701  s->row_status[row] = SQL_ROW_DELETED;
10702  }
10703  }
10704  dbtraceapi(d, "sqlite3_reset", NULL);
10705  sqlite3_reset(s3stmt);
10706  }
10707  dbtraceapi(d, "sqlite3_finalize", NULL);
10708  sqlite3_finalize(s3stmt);
10709  return SQL_SUCCESS;
10710  } else if (op == SQL_UPDATE_BY_BOOKMARK) {
10711  if (s->has_rowid < 0 ||
10712  s->bkmrk != SQL_UB_VARIABLE ||
10713  s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10714  !s->bkmrkcol.valp) {
10715  setstat(s, -1, "incompatible rowset",
10716  (*s->ov3) ? "HY000" : "S1000");
10717  return SQL_ERROR;
10718  }
10719  ret = chkunbound(s);
10720  if (ret != SQL_SUCCESS) {
10721  return ret;
10722  }
10723  sql = dsappend(sql, "UPDATE ");
10724  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10725  sql = dsappendq(sql, s->dyncols[0].db);
10726  sql = dsappend(sql, ".");
10727  }
10728  sql = dsappendq(sql, s->dyncols[0].table);
10729  for (i = 0, k = 0; i < s->ncols; i++) {
10730  if (i == s->has_rowid) {
10731  continue;
10732  }
10733  sql = dsappend(sql, (k > 0) ? ", " : " SET ");
10734  sql = dsappendq(sql, s->dyncols[i].column);
10735  sql = dsappend(sql, " = ?");
10736  k++;
10737  }
10738  sql = dsappend(sql, " WHERE ");
10739  sql = dsappendq(sql, s->dyncols[s->has_rowid].column);
10740  sql = dsappend(sql, " = ?");
10741  if (dserr(sql)) {
10742  dsfree(sql);
10743  return nomem(s);
10744  }
10745 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10746  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10747 #else
10748  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10749 #endif
10750  do {
10751  s3stmt = NULL;
10752 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10753  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10754  &s3stmt, &endp);
10755 #else
10756  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10757  &s3stmt, &endp);
10758 #endif
10759  if (rc != SQLITE_OK) {
10760  if (s3stmt) {
10761  sqlite3_finalize(s3stmt);
10762  s3stmt = NULL;
10763  }
10764  }
10765  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10766  dbtracerc(d, rc, NULL);
10767  dsfree(sql);
10768  if (rc != SQLITE_OK) {
10769  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10770  sqlite3_errmsg(d->sqlite), rc);
10771  if (s3stmt) {
10772  dbtraceapi(d, "sqlite3_finalize", NULL);
10773  sqlite3_finalize(s3stmt);
10774  }
10775  return SQL_ERROR;
10776  }
10777  for (row = 0; row < s->rowset_size; row++) {
10778  SQLPOINTER *val;
10779  sqlite_int64 rowid;
10780 
10781  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10782  val = (SQLPOINTER)
10783  ((char *) s->bkmrkcol.valp + s->bind_type * row);
10784  } else {
10785  val = (SQLPOINTER)
10786  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10787  }
10788  if (s->bind_offs) {
10789  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10790  }
10791  if (s->bkmrkcol.lenp) {
10792  SQLLEN *ival;
10793 
10794  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10795  ival = (SQLLEN *)
10796  ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10797  } else {
10798  ival = &s->bkmrkcol.lenp[row];
10799  }
10800  if (s->bind_offs) {
10801  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10802  }
10803  if (*ival != sizeof (sqlite_int64)) {
10804  continue;
10805  }
10806  }
10807  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10808  if (i == s->has_rowid) {
10809  continue;
10810  }
10811  ret = setposbind(s, s3stmt, i, k, row);
10812  if (ret != SQL_SUCCESS) {
10813 ustmterr:
10814  if (s->row_status0) {
10815  s->row_status0[row] = SQL_ROW_ERROR;
10816  }
10817  if (s->row_status) {
10818  s->row_status[row] = SQL_ROW_ERROR;
10819  }
10820  dbtraceapi(d, "sqlite3_finalize", NULL);
10821  sqlite3_finalize(s3stmt);
10822  return ret;
10823  }
10824  k++;
10825  }
10826  rowid = *(sqlite_int64 *) val;
10827  sqlite3_bind_int64(s3stmt, k, rowid);
10828  if (d->trace) {
10829  fprintf(d->trace,
10830 #ifdef _WIN32
10831  "-- parameter %d: %I64d\n",
10832 #else
10833  "-- parameter %d: %lld\n",
10834 #endif
10835  k, rowid);
10836  fflush(d->trace);
10837  }
10838  rc = sqlite3_step(s3stmt);
10839  if (rc != SQLITE_DONE) {
10840  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10841  sqlite3_errmsg(d->sqlite), rc);
10842  ret = SQL_ERROR;
10843  goto ustmterr;
10844  }
10845  if (sqlite3_changes(d->sqlite) > 0) {
10846  if (s->row_status0) {
10847  s->row_status0[row] = SQL_ROW_UPDATED;
10848  }
10849  if (s->row_status) {
10850  s->row_status[row] = SQL_ROW_UPDATED;
10851  }
10852  }
10853  dbtraceapi(d, "sqlite3_reset", NULL);
10854  sqlite3_reset(s3stmt);
10855  }
10856  dbtraceapi(d, "sqlite3_finalize", NULL);
10857  sqlite3_finalize(s3stmt);
10858  return SQL_SUCCESS;
10859  }
10860  setstat(s, -1, "unsupported operation", (*s->ov3) ? "HY000" : "S1000");
10861  return SQL_ERROR;
10862 }
10863 
10871 SQLRETURN SQL_API
10872 SQLBulkOperations(SQLHSTMT stmt, SQLSMALLINT oper)
10873 {
10874  SQLRETURN ret;
10875 
10876  HSTMT_LOCK(stmt);
10877  ret = drvbulkoperations(stmt, oper);
10878  HSTMT_UNLOCK(stmt);
10879  return ret;
10880 }
10881 
10882 
10887 SQLRETURN SQL_API
10888 SQLSetScrollOptions(SQLHSTMT stmt, SQLUSMALLINT concur, SQLLEN rowkeyset,
10889  SQLUSMALLINT rowset)
10890 {
10891  SQLRETURN ret;
10892 
10893  HSTMT_LOCK(stmt);
10894  ret = drvunimplstmt(stmt);
10895  HSTMT_UNLOCK(stmt);
10896  return ret;
10897 }
10898 
10899 #define strmak(dst, src, max, lenp) { \
10900  int len = strlen(src); \
10901  int cnt = min(len + 1, max); \
10902  strncpy(dst, src, cnt); \
10903  *lenp = (cnt > len) ? len : cnt; \
10904 }
10905 
10916 static SQLRETURN
10917 drvgetinfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
10918  SQLSMALLINT *valLen)
10919 {
10920  DBC *d;
10921  char dummyc[16];
10922  SQLSMALLINT dummy;
10923 #if defined(_WIN32) || defined(_WIN64)
10924  char pathbuf[301], *drvname;
10925 #else
10926  static char drvname[] = "sqlite3odbc.so";
10927 #endif
10928 
10929  if (dbc == SQL_NULL_HDBC) {
10930  return SQL_INVALID_HANDLE;
10931  }
10932  d = (DBC *) dbc;
10933  if (valMax) {
10934  valMax--;
10935  }
10936  if (!valLen) {
10937  valLen = &dummy;
10938  }
10939  if (!val) {
10940  val = dummyc;
10941  valMax = sizeof (dummyc) - 1;
10942  }
10943  switch (type) {
10944  case SQL_MAX_USER_NAME_LEN:
10945  *((SQLSMALLINT *) val) = 16;
10946  *valLen = sizeof (SQLSMALLINT);
10947  break;
10948  case SQL_USER_NAME:
10949  strmak(val, "", valMax, valLen);
10950  break;
10951  case SQL_DRIVER_ODBC_VER:
10952 #if 0
10953  strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
10954 #else
10955  strmak(val, "03.00", valMax, valLen);
10956 #endif
10957  break;
10958  case SQL_ACTIVE_CONNECTIONS:
10959  case SQL_ACTIVE_STATEMENTS:
10960  *((SQLSMALLINT *) val) = 0;
10961  *valLen = sizeof (SQLSMALLINT);
10962  break;
10963 #ifdef SQL_ASYNC_MODE
10964  case SQL_ASYNC_MODE:
10965  *((SQLUINTEGER *) val) = SQL_AM_NONE;
10966  *valLen = sizeof (SQLUINTEGER);
10967  break;
10968 #endif
10969 #ifdef SQL_CREATE_TABLE
10970  case SQL_CREATE_TABLE:
10971  *((SQLUINTEGER *) val) = SQL_CT_CREATE_TABLE |
10972  SQL_CT_COLUMN_DEFAULT |
10973  SQL_CT_COLUMN_CONSTRAINT |
10974  SQL_CT_CONSTRAINT_NON_DEFERRABLE;
10975  *valLen = sizeof (SQLUINTEGER);
10976  break;
10977 #endif
10978 #ifdef SQL_CREATE_VIEW
10979  case SQL_CREATE_VIEW:
10980  *((SQLUINTEGER *) val) = SQL_CV_CREATE_VIEW;
10981  *valLen = sizeof (SQLUINTEGER);
10982  break;
10983 #endif
10984 #ifdef SQL_DDL_INDEX
10985  case SQL_DDL_INDEX:
10986  *((SQLUINTEGER *) val) = SQL_DI_CREATE_INDEX | SQL_DI_DROP_INDEX;
10987  *valLen = sizeof (SQLUINTEGER);
10988  break;
10989 #endif
10990 #ifdef SQL_DROP_TABLE
10991  case SQL_DROP_TABLE:
10992  *((SQLUINTEGER *) val) = SQL_DT_DROP_TABLE;
10993  *valLen = sizeof (SQLUINTEGER);
10994  break;
10995 #endif
10996 #ifdef SQL_DROP_VIEW
10997  case SQL_DROP_VIEW:
10998  *((SQLUINTEGER *) val) = SQL_DV_DROP_VIEW;
10999  *valLen = sizeof (SQLUINTEGER);
11000  break;
11001 #endif
11002 #ifdef SQL_INDEX_KEYWORDS
11003  case SQL_INDEX_KEYWORDS:
11004  *((SQLUINTEGER *) val) = SQL_IK_ALL;
11005  *valLen = sizeof (SQLUINTEGER);
11006  break;
11007 #endif
11008  case SQL_DATA_SOURCE_NAME:
11009  strmak(val, d->dsn ? d->dsn : "", valMax, valLen);
11010  break;
11011  case SQL_DRIVER_NAME:
11012 #if defined(_WIN32) || defined(_WIN64)
11013  GetModuleFileName(hModule, pathbuf, sizeof (pathbuf));
11014  drvname = strrchr(pathbuf, '\\');
11015  if (drvname == NULL) {
11016  drvname = strrchr(pathbuf, '/');
11017  }
11018  if (drvname == NULL) {
11019  drvname = pathbuf;
11020  } else {
11021  drvname++;
11022  }
11023 #endif
11024  strmak(val, drvname, valMax, valLen);
11025  break;
11026  case SQL_DRIVER_VER:
11027  strmak(val, DRIVER_VER_INFO, valMax, valLen);
11028  break;
11029  case SQL_FETCH_DIRECTION:
11030  *((SQLUINTEGER *) val) = SQL_FD_FETCH_NEXT | SQL_FD_FETCH_FIRST |
11031  SQL_FD_FETCH_LAST | SQL_FD_FETCH_PRIOR | SQL_FD_FETCH_ABSOLUTE;
11032  *valLen = sizeof (SQLUINTEGER);
11033  break;
11034  case SQL_ODBC_VER:
11035  strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
11036  break;
11037  case SQL_ODBC_SAG_CLI_CONFORMANCE:
11038  *((SQLSMALLINT *) val) = SQL_OSCC_NOT_COMPLIANT;
11039  *valLen = sizeof (SQLSMALLINT);
11040  break;
11041  case SQL_STANDARD_CLI_CONFORMANCE:
11042  *((SQLUINTEGER *) val) = SQL_SCC_XOPEN_CLI_VERSION1;
11043  *valLen = sizeof (SQLUINTEGER);
11044  break;
11045  case SQL_SQL_CONFORMANCE:
11046  *((SQLUINTEGER *) val) = SQL_SC_SQL92_ENTRY;
11047  *valLen = sizeof (SQLUINTEGER);
11048  break;
11049  case SQL_SERVER_NAME:
11050  case SQL_DATABASE_NAME:
11051  strmak(val, d->dbname ? d->dbname : "", valMax, valLen);
11052  break;
11053  case SQL_SEARCH_PATTERN_ESCAPE:
11054  strmak(val, "\\", valMax, valLen);
11055  break;
11056  case SQL_ODBC_SQL_CONFORMANCE:
11057  *((SQLSMALLINT *) val) = SQL_OSC_MINIMUM;
11058  *valLen = sizeof (SQLSMALLINT);
11059  break;
11060  case SQL_ODBC_API_CONFORMANCE:
11061  *((SQLSMALLINT *) val) = SQL_OAC_LEVEL1;
11062  *valLen = sizeof (SQLSMALLINT);
11063  break;
11064  case SQL_DBMS_NAME:
11065  strmak(val, "SQLite", valMax, valLen);
11066  break;
11067  case SQL_DBMS_VER:
11068  strmak(val, SQLITE_VERSION, valMax, valLen);
11069  break;
11070  case SQL_COLUMN_ALIAS:
11071  case SQL_NEED_LONG_DATA_LEN:
11072  strmak(val, "Y", valMax, valLen);
11073  break;
11074  case SQL_ROW_UPDATES:
11075  case SQL_ACCESSIBLE_PROCEDURES:
11076  case SQL_PROCEDURES:
11077  case SQL_EXPRESSIONS_IN_ORDERBY:
11078  case SQL_ODBC_SQL_OPT_IEF:
11079  case SQL_LIKE_ESCAPE_CLAUSE:
11080  case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11081  case SQL_OUTER_JOINS:
11082  case SQL_ACCESSIBLE_TABLES:
11083  case SQL_MULT_RESULT_SETS:
11084  case SQL_MULTIPLE_ACTIVE_TXN:
11085  case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11086  strmak(val, "N", valMax, valLen);
11087  break;
11088 #ifdef SQL_CATALOG_NAME
11089  case SQL_CATALOG_NAME:
11090 #if defined(_WIN32) || defined(_WIN64)
11091  strmak(val, d->xcelqrx ? "Y" : "N", valMax, valLen);
11092 #else
11093  strmak(val, "N", valMax, valLen);
11094 #endif
11095  break;
11096 #endif
11097  case SQL_DATA_SOURCE_READ_ONLY:
11098  strmak(val, "N", valMax, valLen);
11099  break;
11100 #ifdef SQL_OJ_CAPABILITIES
11101  case SQL_OJ_CAPABILITIES:
11102  *((SQLUINTEGER *) val) = 0;
11103  *valLen = sizeof (SQLUINTEGER);
11104  break;
11105 #endif
11106 #ifdef SQL_MAX_IDENTIFIER_LEN
11107  case SQL_MAX_IDENTIFIER_LEN:
11108  *((SQLUSMALLINT *) val) = 255;
11109  *valLen = sizeof (SQLUSMALLINT);
11110  break;
11111 #endif
11112  case SQL_CONCAT_NULL_BEHAVIOR:
11113  *((SQLSMALLINT *) val) = SQL_CB_NULL;
11114  *valLen = sizeof (SQLSMALLINT);
11115  break;
11116  case SQL_CURSOR_COMMIT_BEHAVIOR:
11117  case SQL_CURSOR_ROLLBACK_BEHAVIOR:
11118  *((SQLSMALLINT *) val) = SQL_CB_PRESERVE;
11119  *valLen = sizeof (SQLSMALLINT);
11120  break;
11121 #ifdef SQL_CURSOR_SENSITIVITY
11122  case SQL_CURSOR_SENSITIVITY:
11123  *((SQLUINTEGER *) val) = SQL_UNSPECIFIED;
11124  *valLen = sizeof (SQLUINTEGER);
11125  break;
11126 #endif
11127  case SQL_DEFAULT_TXN_ISOLATION:
11128  *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11129  *valLen = sizeof (SQLUINTEGER);
11130  break;
11131 #ifdef SQL_DESCRIBE_PARAMETER
11132  case SQL_DESCRIBE_PARAMETER:
11133  strmak(val, "Y", valMax, valLen);
11134  break;
11135 #endif
11136  case SQL_TXN_ISOLATION_OPTION:
11137  *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11138  *valLen = sizeof (SQLUINTEGER);
11139  break;
11140  case SQL_IDENTIFIER_CASE:
11141  *((SQLSMALLINT *) val) = SQL_IC_SENSITIVE;
11142  *valLen = sizeof (SQLSMALLINT);
11143  break;
11144  case SQL_IDENTIFIER_QUOTE_CHAR:
11145  strmak(val, "\"", valMax, valLen);
11146  break;
11147  case SQL_MAX_TABLE_NAME_LEN:
11148  case SQL_MAX_COLUMN_NAME_LEN:
11149  *((SQLSMALLINT *) val) = 255;
11150  *valLen = sizeof (SQLSMALLINT);
11151  break;
11152  case SQL_MAX_CURSOR_NAME_LEN:
11153  *((SQLSMALLINT *) val) = 255;
11154  *valLen = sizeof (SQLSMALLINT);
11155  break;
11156  case SQL_MAX_PROCEDURE_NAME_LEN:
11157  *((SQLSMALLINT *) val) = 0;
11158  break;
11159  case SQL_MAX_QUALIFIER_NAME_LEN:
11160  case SQL_MAX_OWNER_NAME_LEN:
11161  *((SQLSMALLINT *) val) = 255;
11162  break;
11163  case SQL_OWNER_TERM:
11164  strmak(val, "", valMax, valLen);
11165  break;
11166  case SQL_PROCEDURE_TERM:
11167  strmak(val, "PROCEDURE", valMax, valLen);
11168  break;
11169  case SQL_QUALIFIER_NAME_SEPARATOR:
11170  strmak(val, ".", valMax, valLen);
11171  break;
11172  case SQL_QUALIFIER_TERM:
11173 #if defined(_WIN32) || defined(_WIN64)
11174  strmak(val, d->xcelqrx ? "catalog" : "", valMax, valLen);
11175 #else
11176  strmak(val, "", valMax, valLen);
11177 #endif
11178  break;
11179  case SQL_QUALIFIER_USAGE:
11180 #if defined(_WIN32) || defined(_WIN64)
11181  *((SQLUINTEGER *) val) = d->xcelqrx ?
11182  (SQL_CU_DML_STATEMENTS | SQL_CU_INDEX_DEFINITION |
11183  SQL_CU_TABLE_DEFINITION) : 0;
11184 #else
11185  *((SQLUINTEGER *) val) = 0;
11186 #endif
11187  *valLen = sizeof (SQLUINTEGER);
11188  break;
11189  case SQL_SCROLL_CONCURRENCY:
11190  *((SQLUINTEGER *) val) = SQL_SCCO_LOCK;
11191  *valLen = sizeof (SQLUINTEGER);
11192  break;
11193  case SQL_SCROLL_OPTIONS:
11194  *((SQLUINTEGER *) val) = SQL_SO_STATIC | SQL_SO_FORWARD_ONLY;
11195  *valLen = sizeof (SQLUINTEGER);
11196  break;
11197  case SQL_TABLE_TERM:
11198  strmak(val, "TABLE", valMax, valLen);
11199  break;
11200  case SQL_TXN_CAPABLE:
11201  *((SQLSMALLINT *) val) = SQL_TC_ALL;
11202  *valLen = sizeof (SQLSMALLINT);
11203  break;
11204  case SQL_CONVERT_FUNCTIONS:
11205  *((SQLUINTEGER *) val) = 0;
11206  *valLen = sizeof (SQLUINTEGER);
11207  break;
11208  case SQL_SYSTEM_FUNCTIONS:
11209  case SQL_NUMERIC_FUNCTIONS:
11210  case SQL_STRING_FUNCTIONS:
11211  case SQL_TIMEDATE_FUNCTIONS:
11212  *((SQLUINTEGER *) val) = 0;
11213  *valLen = sizeof (SQLUINTEGER);
11214  break;
11215  case SQL_CONVERT_BIGINT:
11216  case SQL_CONVERT_BIT:
11217  case SQL_CONVERT_CHAR:
11218  case SQL_CONVERT_DATE:
11219  case SQL_CONVERT_DECIMAL:
11220  case SQL_CONVERT_DOUBLE:
11221  case SQL_CONVERT_FLOAT:
11222  case SQL_CONVERT_INTEGER:
11223  case SQL_CONVERT_LONGVARCHAR:
11224  case SQL_CONVERT_NUMERIC:
11225  case SQL_CONVERT_REAL:
11226  case SQL_CONVERT_SMALLINT:
11227  case SQL_CONVERT_TIME:
11228  case SQL_CONVERT_TIMESTAMP:
11229  case SQL_CONVERT_TINYINT:
11230  case SQL_CONVERT_VARCHAR:
11231  *((SQLUINTEGER *) val) =
11232  SQL_CVT_CHAR | SQL_CVT_NUMERIC | SQL_CVT_DECIMAL |
11233  SQL_CVT_INTEGER | SQL_CVT_SMALLINT | SQL_CVT_FLOAT | SQL_CVT_REAL |
11234  SQL_CVT_DOUBLE | SQL_CVT_VARCHAR | SQL_CVT_LONGVARCHAR |
11235  SQL_CVT_BIT | SQL_CVT_TINYINT | SQL_CVT_BIGINT |
11236  SQL_CVT_DATE | SQL_CVT_TIME | SQL_CVT_TIMESTAMP;
11237  *valLen = sizeof (SQLUINTEGER);
11238  break;
11239  case SQL_CONVERT_BINARY:
11240  case SQL_CONVERT_VARBINARY:
11241  case SQL_CONVERT_LONGVARBINARY:
11242  *((SQLUINTEGER *) val) = 0;
11243  *valLen = sizeof (SQLUINTEGER);
11244  break;
11245  case SQL_POSITIONED_STATEMENTS:
11246  *((SQLUINTEGER *) val) = 0;
11247  *valLen = sizeof (SQLUINTEGER);
11248  break;
11249  case SQL_LOCK_TYPES:
11250  *((SQLUINTEGER *) val) = SQL_LCK_NO_CHANGE;
11251  *valLen = sizeof (SQLUINTEGER);
11252  break;
11253  case SQL_BOOKMARK_PERSISTENCE:
11254  *((SQLUINTEGER *) val) = SQL_BP_SCROLL;
11255  *valLen = sizeof (SQLUINTEGER);
11256  break;
11257  case SQL_UNION:
11258  *((SQLUINTEGER *) val) = SQL_U_UNION | SQL_U_UNION_ALL;
11259  *valLen = sizeof (SQLUINTEGER);
11260  break;
11261  case SQL_OWNER_USAGE:
11262  case SQL_SUBQUERIES:
11263  case SQL_TIMEDATE_ADD_INTERVALS:
11264  case SQL_TIMEDATE_DIFF_INTERVALS:
11265  *((SQLUINTEGER *) val) = 0;
11266  *valLen = sizeof (SQLUINTEGER);
11267  break;
11268  case SQL_QUOTED_IDENTIFIER_CASE:
11269  *((SQLUSMALLINT *) val) = SQL_IC_SENSITIVE;
11270  *valLen = sizeof (SQLUSMALLINT);
11271  break;
11272  case SQL_POS_OPERATIONS:
11273  *((SQLUINTEGER *) val) = SQL_POS_POSITION | SQL_POS_UPDATE |
11274  SQL_POS_DELETE | SQL_POS_ADD | SQL_POS_REFRESH;
11275  *valLen = sizeof (SQLUINTEGER);
11276  break;
11277  case SQL_ALTER_TABLE:
11278  *((SQLUINTEGER *) val) = 0;
11279  *valLen = sizeof (SQLUINTEGER);
11280  break;
11281  case SQL_CORRELATION_NAME:
11282  *((SQLSMALLINT *) val) = SQL_CN_DIFFERENT;
11283  *valLen = sizeof (SQLSMALLINT);
11284  break;
11285  case SQL_NON_NULLABLE_COLUMNS:
11286  *((SQLSMALLINT *) val) = SQL_NNC_NON_NULL;
11287  *valLen = sizeof (SQLSMALLINT);
11288  break;
11289  case SQL_NULL_COLLATION:
11290  *((SQLSMALLINT *) val) = SQL_NC_START;
11291  *valLen = sizeof (SQLSMALLINT);
11292  break;
11293  case SQL_MAX_COLUMNS_IN_GROUP_BY:
11294  case SQL_MAX_COLUMNS_IN_ORDER_BY:
11295  case SQL_MAX_COLUMNS_IN_SELECT:
11296  case SQL_MAX_COLUMNS_IN_TABLE:
11297  case SQL_MAX_ROW_SIZE:
11298  case SQL_MAX_TABLES_IN_SELECT:
11299  *((SQLSMALLINT *) val) = 0;
11300  *valLen = sizeof (SQLSMALLINT);
11301  break;
11302  case SQL_MAX_BINARY_LITERAL_LEN:
11303  case SQL_MAX_CHAR_LITERAL_LEN:
11304  *((SQLUINTEGER *) val) = 0;
11305  *valLen = sizeof (SQLUINTEGER);
11306  break;
11307  case SQL_MAX_COLUMNS_IN_INDEX:
11308  *((SQLSMALLINT *) val) = 0;
11309  *valLen = sizeof (SQLSMALLINT);
11310  break;
11311  case SQL_MAX_INDEX_SIZE:
11312  *((SQLUINTEGER *) val) = 0;
11313  *valLen = sizeof (SQLUINTEGER);
11314  break;
11315 #ifdef SQL_MAX_IDENTIFIER_LENGTH
11316  case SQL_MAX_IDENTIFIER_LENGTH:
11317  *((SQLUINTEGER *) val) = 255;
11318  *valLen = sizeof (SQLUINTEGER);
11319  break;
11320 #endif
11321  case SQL_MAX_STATEMENT_LEN:
11322  *((SQLUINTEGER *) val) = 16384;
11323  *valLen = sizeof (SQLUINTEGER);
11324  break;
11325  case SQL_QUALIFIER_LOCATION:
11326  *((SQLSMALLINT *) val) = SQL_QL_START;
11327  *valLen = sizeof (SQLSMALLINT);
11328  break;
11329  case SQL_GETDATA_EXTENSIONS:
11330  *((SQLUINTEGER *) val) =
11331  SQL_GD_ANY_COLUMN | SQL_GD_ANY_ORDER | SQL_GD_BOUND;
11332  *valLen = sizeof (SQLUINTEGER);
11333  break;
11334  case SQL_STATIC_SENSITIVITY:
11335  *((SQLUINTEGER *) val) = 0;
11336  *valLen = sizeof (SQLUINTEGER);
11337  break;
11338  case SQL_FILE_USAGE:
11339 #if defined(_WIN32) || defined(_WIN64)
11340  *((SQLSMALLINT *) val) =
11341  d->xcelqrx ? SQL_FILE_CATALOG : SQL_FILE_NOT_SUPPORTED;
11342 #else
11343  *((SQLSMALLINT *) val) = SQL_FILE_NOT_SUPPORTED;
11344 #endif
11345  *valLen = sizeof (SQLSMALLINT);
11346  break;
11347  case SQL_GROUP_BY:
11348  *((SQLSMALLINT *) val) = SQL_GB_GROUP_BY_EQUALS_SELECT;
11349  *valLen = sizeof (SQLSMALLINT);
11350  break;
11351  case SQL_KEYWORDS:
11352  strmak(val, "CREATE,SELECT,DROP,DELETE,UPDATE,INSERT,"
11353  "INTO,VALUES,TABLE,INDEX,FROM,SET,WHERE,AND,CURRENT,OF",
11354  valMax, valLen);
11355  break;
11356  case SQL_SPECIAL_CHARACTERS:
11357 #ifdef SQL_COLLATION_SEQ
11358  case SQL_COLLATION_SEQ:
11359 #endif
11360  strmak(val, "", valMax, valLen);
11361  break;
11362  case SQL_BATCH_SUPPORT:
11363  case SQL_BATCH_ROW_COUNT:
11364  case SQL_PARAM_ARRAY_ROW_COUNTS:
11365  *((SQLUINTEGER *) val) = 0;
11366  *valLen = sizeof (SQLUINTEGER);
11367  break;
11368  case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1:
11369  *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_BOOKMARK;
11370  *valLen = sizeof (SQLUINTEGER);
11371  break;
11372  case SQL_STATIC_CURSOR_ATTRIBUTES1:
11373  *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE |
11374  SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK | SQL_CA1_POS_POSITION |
11375  SQL_CA1_POS_DELETE | SQL_CA1_POS_UPDATE | SQL_CA1_POS_REFRESH |
11376  SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_BULK_ADD |
11377  SQL_CA1_BULK_UPDATE_BY_BOOKMARK | SQL_CA1_BULK_DELETE_BY_BOOKMARK;
11378  *valLen = sizeof (SQLUINTEGER);
11379  break;
11380  case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2:
11381  case SQL_STATIC_CURSOR_ATTRIBUTES2:
11382  *((SQLUINTEGER *) val) = SQL_CA2_READ_ONLY_CONCURRENCY |
11383  SQL_CA2_LOCK_CONCURRENCY;
11384  *valLen = sizeof (SQLUINTEGER);
11385  break;
11386  case SQL_KEYSET_CURSOR_ATTRIBUTES1:
11387  case SQL_KEYSET_CURSOR_ATTRIBUTES2:
11388  case SQL_DYNAMIC_CURSOR_ATTRIBUTES1:
11389  case SQL_DYNAMIC_CURSOR_ATTRIBUTES2:
11390  *((SQLUINTEGER *) val) = 0;
11391  *valLen = sizeof (SQLUINTEGER);
11392  break;
11393  case SQL_ODBC_INTERFACE_CONFORMANCE:
11394  *((SQLUINTEGER *) val) = SQL_OIC_CORE;
11395  *valLen = sizeof (SQLUINTEGER);
11396  break;
11397  default:
11398  setstatd(d, -1, "unsupported info option %d",
11399  (*d->ov3) ? "HYC00" : "S1C00", type);
11400  return SQL_ERROR;
11401  }
11402  return SQL_SUCCESS;
11403 }
11404 
11405 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
11406 
11416 SQLRETURN SQL_API
11417 SQLGetInfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11418  SQLSMALLINT *valLen)
11419 {
11420  SQLRETURN ret;
11421 
11422  HDBC_LOCK(dbc);
11423  ret = drvgetinfo(dbc, type, val, valMax, valLen);
11424  HDBC_UNLOCK(dbc);
11425  return ret;
11426 }
11427 #endif
11428 
11429 #ifdef WINTERFACE
11430 
11440 SQLRETURN SQL_API
11441 SQLGetInfoW(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11442  SQLSMALLINT *valLen)
11443 {
11444  SQLRETURN ret;
11445  SQLSMALLINT len = 0;
11446 
11447  HDBC_LOCK(dbc);
11448  ret = drvgetinfo(dbc, type, val, valMax, &len);
11449  HDBC_UNLOCK(dbc);
11450  if (ret == SQL_SUCCESS) {
11451  SQLWCHAR *v = NULL;
11452 
11453  switch (type) {
11454  case SQL_USER_NAME:
11455  case SQL_DRIVER_ODBC_VER:
11456  case SQL_DATA_SOURCE_NAME:
11457  case SQL_DRIVER_NAME:
11458  case SQL_DRIVER_VER:
11459  case SQL_ODBC_VER:
11460  case SQL_SERVER_NAME:
11461  case SQL_DATABASE_NAME:
11462  case SQL_SEARCH_PATTERN_ESCAPE:
11463  case SQL_DBMS_NAME:
11464  case SQL_DBMS_VER:
11465  case SQL_NEED_LONG_DATA_LEN:
11466  case SQL_ROW_UPDATES:
11467  case SQL_ACCESSIBLE_PROCEDURES:
11468  case SQL_PROCEDURES:
11469  case SQL_EXPRESSIONS_IN_ORDERBY:
11470  case SQL_ODBC_SQL_OPT_IEF:
11471  case SQL_LIKE_ESCAPE_CLAUSE:
11472  case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11473  case SQL_OUTER_JOINS:
11474  case SQL_COLUMN_ALIAS:
11475  case SQL_ACCESSIBLE_TABLES:
11476  case SQL_MULT_RESULT_SETS:
11477  case SQL_MULTIPLE_ACTIVE_TXN:
11478  case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11479  case SQL_DATA_SOURCE_READ_ONLY:
11480 #ifdef SQL_DESCRIBE_PARAMETER
11481  case SQL_DESCRIBE_PARAMETER:
11482 #endif
11483  case SQL_IDENTIFIER_QUOTE_CHAR:
11484  case SQL_OWNER_TERM:
11485  case SQL_PROCEDURE_TERM:
11486  case SQL_QUALIFIER_NAME_SEPARATOR:
11487  case SQL_QUALIFIER_TERM:
11488  case SQL_TABLE_TERM:
11489  case SQL_KEYWORDS:
11490  case SQL_SPECIAL_CHARACTERS:
11491 #ifdef SQL_CATALOG_NAME
11492  case SQL_CATALOG_NAME:
11493 #endif
11494 #ifdef SQL_COLLATION_SEQ
11495  case SQL_COLLATION_SEQ:
11496 #endif
11497  if (val) {
11498  if (len > 0) {
11499  v = uc_from_utf((SQLCHAR *) val, len);
11500  if (v) {
11501  int vmax = valMax / sizeof (SQLWCHAR);
11502 
11503  uc_strncpy(val, v, vmax);
11504  if (len < vmax) {
11505  len = min(vmax, uc_strlen(v));
11506  v[len] = 0;
11507  } else {
11508  len = vmax;
11509  }
11510  uc_free(v);
11511  len *= sizeof (SQLWCHAR);
11512  } else {
11513  len = 0;
11514  }
11515  }
11516  if (len <= 0) {
11517  len = 0;
11518  if (valMax >= sizeof (SQLWCHAR)) {
11519  *((SQLWCHAR *)val) = 0;
11520  }
11521  }
11522  } else {
11523  len *= sizeof (SQLWCHAR);
11524  }
11525  break;
11526  }
11527  if (valLen) {
11528  *valLen = len;
11529  }
11530  }
11531  return ret;
11532 }
11533 #endif
11534 
11543 SQLRETURN SQL_API
11544 SQLGetFunctions(SQLHDBC dbc, SQLUSMALLINT func,
11545  SQLUSMALLINT *flags)
11546 {
11547  int i;
11548  SQLUSMALLINT exists[100];
11549 
11550  if (dbc == SQL_NULL_HDBC) {
11551  return SQL_INVALID_HANDLE;
11552  }
11553  for (i = 0; i < array_size(exists); i++) {
11554  exists[i] = SQL_FALSE;
11555  }
11556  exists[SQL_API_SQLALLOCCONNECT] = SQL_TRUE;
11557  exists[SQL_API_SQLFETCH] = SQL_TRUE;
11558  exists[SQL_API_SQLALLOCENV] = SQL_TRUE;
11559  exists[SQL_API_SQLFREECONNECT] = SQL_TRUE;
11560  exists[SQL_API_SQLALLOCSTMT] = SQL_TRUE;
11561  exists[SQL_API_SQLFREEENV] = SQL_TRUE;
11562  exists[SQL_API_SQLBINDCOL] = SQL_TRUE;
11563  exists[SQL_API_SQLFREESTMT] = SQL_TRUE;
11564  exists[SQL_API_SQLCANCEL] = SQL_TRUE;
11565  exists[SQL_API_SQLGETCURSORNAME] = SQL_TRUE;
11566  exists[SQL_API_SQLCOLATTRIBUTES] = SQL_TRUE;
11567  exists[SQL_API_SQLNUMRESULTCOLS] = SQL_TRUE;
11568  exists[SQL_API_SQLCONNECT] = SQL_TRUE;
11569  exists[SQL_API_SQLPREPARE] = SQL_TRUE;
11570  exists[SQL_API_SQLDESCRIBECOL] = SQL_TRUE;
11571  exists[SQL_API_SQLROWCOUNT] = SQL_TRUE;
11572  exists[SQL_API_SQLDISCONNECT] = SQL_TRUE;
11573  exists[SQL_API_SQLSETCURSORNAME] = SQL_FALSE;
11574  exists[SQL_API_SQLERROR] = SQL_TRUE;
11575  exists[SQL_API_SQLSETPARAM] = SQL_TRUE;
11576  exists[SQL_API_SQLEXECDIRECT] = SQL_TRUE;
11577  exists[SQL_API_SQLTRANSACT] = SQL_TRUE;
11578  exists[SQL_API_SQLBULKOPERATIONS] = SQL_TRUE;
11579  exists[SQL_API_SQLEXECUTE] = SQL_TRUE;
11580  exists[SQL_API_SQLBINDPARAMETER] = SQL_TRUE;
11581  exists[SQL_API_SQLGETTYPEINFO] = SQL_TRUE;
11582  exists[SQL_API_SQLCOLUMNS] = SQL_TRUE;
11583  exists[SQL_API_SQLPARAMDATA] = SQL_TRUE;
11584  exists[SQL_API_SQLDRIVERCONNECT] = SQL_TRUE;
11585  exists[SQL_API_SQLPUTDATA] = SQL_TRUE;
11586  exists[SQL_API_SQLGETCONNECTOPTION] = SQL_TRUE;
11587  exists[SQL_API_SQLSETCONNECTOPTION] = SQL_TRUE;
11588  exists[SQL_API_SQLGETDATA] = SQL_TRUE;
11589  exists[SQL_API_SQLSETSTMTOPTION] = SQL_TRUE;
11590  exists[SQL_API_SQLGETFUNCTIONS] = SQL_TRUE;
11591  exists[SQL_API_SQLSPECIALCOLUMNS] = SQL_TRUE;
11592  exists[SQL_API_SQLGETINFO] = SQL_TRUE;
11593  exists[SQL_API_SQLSTATISTICS] = SQL_TRUE;
11594  exists[SQL_API_SQLGETSTMTOPTION] = SQL_TRUE;
11595  exists[SQL_API_SQLTABLES] = SQL_TRUE;
11596  exists[SQL_API_SQLBROWSECONNECT] = SQL_FALSE;
11597  exists[SQL_API_SQLNUMPARAMS] = SQL_TRUE;
11598  exists[SQL_API_SQLCOLUMNPRIVILEGES] = SQL_FALSE;
11599  exists[SQL_API_SQLPARAMOPTIONS] = SQL_FALSE;
11600  exists[SQL_API_SQLDATASOURCES] = SQL_TRUE;
11601  exists[SQL_API_SQLPRIMARYKEYS] = SQL_TRUE;
11602  exists[SQL_API_SQLDESCRIBEPARAM] = SQL_TRUE;
11603  exists[SQL_API_SQLPROCEDURECOLUMNS] = SQL_TRUE;
11604  exists[SQL_API_SQLDRIVERS] = SQL_FALSE;
11605  exists[SQL_API_SQLPROCEDURES] = SQL_TRUE;
11606  exists[SQL_API_SQLEXTENDEDFETCH] = SQL_TRUE;
11607  exists[SQL_API_SQLSETPOS] = SQL_TRUE;
11608  exists[SQL_API_SQLFOREIGNKEYS] = SQL_TRUE;
11609  exists[SQL_API_SQLSETSCROLLOPTIONS] = SQL_TRUE;
11610  exists[SQL_API_SQLMORERESULTS] = SQL_TRUE;
11611  exists[SQL_API_SQLTABLEPRIVILEGES] = SQL_TRUE;
11612  exists[SQL_API_SQLNATIVESQL] = SQL_TRUE;
11613  if (func == SQL_API_ALL_FUNCTIONS) {
11614  memcpy(flags, exists, sizeof (exists));
11615  } else if (func == SQL_API_ODBC3_ALL_FUNCTIONS) {
11616  int i;
11617 #define SET_EXISTS(x) \
11618  flags[(x) >> 4] |= (1 << ((x) & 0xF))
11619 #define CLR_EXISTS(x) \
11620  flags[(x) >> 4] &= ~(1 << ((x) & 0xF))
11621 
11622  memset(flags, 0,
11623  sizeof (SQLUSMALLINT) * SQL_API_ODBC3_ALL_FUNCTIONS_SIZE);
11624  for (i = 0; i < array_size(exists); i++) {
11625  if (exists[i]) {
11626  flags[i >> 4] |= (1 << (i & 0xF));
11627  }
11628  }
11629  SET_EXISTS(SQL_API_SQLALLOCHANDLE);
11630  SET_EXISTS(SQL_API_SQLFREEHANDLE);
11631  SET_EXISTS(SQL_API_SQLGETSTMTATTR);
11632  SET_EXISTS(SQL_API_SQLSETSTMTATTR);
11633  SET_EXISTS(SQL_API_SQLGETCONNECTATTR);
11634  SET_EXISTS(SQL_API_SQLSETCONNECTATTR);
11635  SET_EXISTS(SQL_API_SQLGETENVATTR);
11636  SET_EXISTS(SQL_API_SQLSETENVATTR);
11637  SET_EXISTS(SQL_API_SQLCLOSECURSOR);
11638  SET_EXISTS(SQL_API_SQLBINDPARAM);
11639 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11640  /*
11641  * Some unixODBC versions have problems with
11642  * SQLError() vs. SQLGetDiagRec() with loss
11643  * of error/warning messages.
11644  */
11645  SET_EXISTS(SQL_API_SQLGETDIAGREC);
11646 #endif
11647  SET_EXISTS(SQL_API_SQLGETDIAGFIELD);
11648  SET_EXISTS(SQL_API_SQLFETCHSCROLL);
11649  SET_EXISTS(SQL_API_SQLENDTRAN);
11650  } else {
11651  if (func < array_size(exists)) {
11652  *flags = exists[func];
11653  } else {
11654  switch (func) {
11655  case SQL_API_SQLALLOCHANDLE:
11656  case SQL_API_SQLFREEHANDLE:
11657  case SQL_API_SQLGETSTMTATTR:
11658  case SQL_API_SQLSETSTMTATTR:
11659  case SQL_API_SQLGETCONNECTATTR:
11660  case SQL_API_SQLSETCONNECTATTR:
11661  case SQL_API_SQLGETENVATTR:
11662  case SQL_API_SQLSETENVATTR:
11663  case SQL_API_SQLCLOSECURSOR:
11664  case SQL_API_SQLBINDPARAM:
11665 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11666  /*
11667  * Some unixODBC versions have problems with
11668  * SQLError() vs. SQLGetDiagRec() with loss
11669  * of error/warning messages.
11670  */
11671  case SQL_API_SQLGETDIAGREC:
11672 #endif
11673  case SQL_API_SQLGETDIAGFIELD:
11674  case SQL_API_SQLFETCHSCROLL:
11675  case SQL_API_SQLENDTRAN:
11676  *flags = SQL_TRUE;
11677  break;
11678  default:
11679  *flags = SQL_FALSE;
11680  }
11681  }
11682  }
11683  return SQL_SUCCESS;
11684 }
11685 
11692 static SQLRETURN
11693 drvallocenv(SQLHENV *env)
11694 {
11695  ENV *e;
11696 
11697  if (env == NULL) {
11698  return SQL_INVALID_HANDLE;
11699  }
11700  e = (ENV *) xmalloc(sizeof (ENV));
11701  if (e == NULL) {
11702  *env = SQL_NULL_HENV;
11703  return SQL_ERROR;
11704  }
11705  e->magic = ENV_MAGIC;
11706  e->ov3 = 0;
11707 #if defined(_WIN32) || defined(_WIN64)
11708  InitializeCriticalSection(&e->cs);
11709 #else
11710 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
11711  nvfs_init();
11712 #endif
11713 #endif
11714  e->dbcs = NULL;
11715  *env = (SQLHENV) e;
11716  return SQL_SUCCESS;
11717 }
11718 
11725 SQLRETURN SQL_API
11726 SQLAllocEnv(SQLHENV *env)
11727 {
11728  return drvallocenv(env);
11729 }
11730 
11737 static SQLRETURN
11738 drvfreeenv(SQLHENV env)
11739 {
11740  ENV *e;
11741 
11742  if (env == SQL_NULL_HENV) {
11743  return SQL_INVALID_HANDLE;
11744  }
11745  e = (ENV *) env;
11746  if (e->magic != ENV_MAGIC) {
11747  return SQL_SUCCESS;
11748  }
11749 #if defined(_WIN32) || defined(_WIN64)
11750  EnterCriticalSection(&e->cs);
11751 #endif
11752  if (e->dbcs) {
11753 #if defined(_WIN32) || defined(_WIN64)
11754  LeaveCriticalSection(&e->cs);
11755 #endif
11756  return SQL_ERROR;
11757  }
11758  e->magic = DEAD_MAGIC;
11759 #if defined(_WIN32) || defined(_WIN64)
11760  LeaveCriticalSection(&e->cs);
11761  DeleteCriticalSection(&e->cs);
11762 #endif
11763  xfree(e);
11764  return SQL_SUCCESS;
11765 }
11766 
11773 SQLRETURN SQL_API
11774 SQLFreeEnv(SQLHENV env)
11775 {
11776  return drvfreeenv(env);
11777 }
11778 
11786 static SQLRETURN
11787 drvallocconnect(SQLHENV env, SQLHDBC *dbc)
11788 {
11789  DBC *d;
11790  ENV *e;
11791  const char *verstr;
11792  int maj = 0, min = 0, lev = 0;
11793 
11794  if (dbc == NULL) {
11795  return SQL_ERROR;
11796  }
11797  d = (DBC *) xmalloc(sizeof (DBC));
11798  if (d == NULL) {
11799  *dbc = SQL_NULL_HDBC;
11800  return SQL_ERROR;
11801  }
11802  memset(d, 0, sizeof (DBC));
11803  d->curtype = SQL_CURSOR_STATIC;
11804  d->ov3 = &d->ov3val;
11805  verstr = sqlite3_libversion();
11806  sscanf(verstr, "%d.%d.%d", &maj, &min, &lev);
11807  d->version = verinfo(maj & 0xFF, min & 0xFF, lev & 0xFF);
11808  e = (ENV *) env;
11809 #if defined(_WIN32) || defined(_WIN64)
11810  if (e->magic == ENV_MAGIC) {
11811  EnterCriticalSection(&e->cs);
11812  }
11813 #endif
11814  if (e->magic == ENV_MAGIC) {
11815  DBC *n, *p;
11816 
11817  d->env = e;
11818  d->ov3 = &e->ov3;
11819  p = NULL;
11820  n = e->dbcs;
11821  while (n) {
11822  p = n;
11823  n = n->next;
11824  }
11825  if (p) {
11826  p->next = d;
11827  } else {
11828  e->dbcs = d;
11829  }
11830  }
11831 #if defined(_WIN32) || defined(_WIN64)
11832  InitializeCriticalSection(&d->cs);
11833  d->owner = 0;
11834  if (e->magic == ENV_MAGIC) {
11835  LeaveCriticalSection(&e->cs);
11836  }
11837  d->oemcp = 1;
11838 #endif
11839  d->autocommit = 1;
11840  d->magic = DBC_MAGIC;
11841  *dbc = (SQLHDBC) d;
11842  drvgetgpps(d);
11843  return SQL_SUCCESS;
11844 }
11845 
11853 SQLRETURN SQL_API
11854 SQLAllocConnect(SQLHENV env, SQLHDBC *dbc)
11855 {
11856  return drvallocconnect(env, dbc);
11857 }
11858 
11865 static SQLRETURN
11867 {
11868  DBC *d;
11869  ENV *e;
11870  SQLRETURN ret = SQL_ERROR;
11871 
11872  if (dbc == SQL_NULL_HDBC) {
11873  return SQL_INVALID_HANDLE;
11874  }
11875  d = (DBC *) dbc;
11876  if (d->magic != DBC_MAGIC) {
11877  return SQL_INVALID_HANDLE;
11878  }
11879  e = d->env;
11880  if (e && e->magic == ENV_MAGIC) {
11881 #if defined(_WIN32) || defined(_WIN64)
11882  EnterCriticalSection(&e->cs);
11883 #endif
11884  } else {
11885  e = NULL;
11886  }
11887  HDBC_LOCK(dbc);
11888  if (d->sqlite) {
11889  setstatd(d, -1, "not disconnected", (*d->ov3) ? "HY000" : "S1000");
11890  HDBC_UNLOCK(dbc);
11891  goto done;
11892  }
11893  while (d->stmt) {
11894  freestmt((HSTMT) d->stmt);
11895  }
11896  if (e && e->magic == ENV_MAGIC) {
11897  DBC *n, *p;
11898 
11899  p = NULL;
11900  n = e->dbcs;
11901  while (n) {
11902  if (n == d) {
11903  break;
11904  }
11905  p = n;
11906  n = n->next;
11907  }
11908  if (n) {
11909  if (p) {
11910  p->next = d->next;
11911  } else {
11912  e->dbcs = d->next;
11913  }
11914  }
11915  }
11916  drvrelgpps(d);
11917  d->magic = DEAD_MAGIC;
11918  if (d->trace) {
11919  fclose(d->trace);
11920  }
11921 #if defined(_WIN32) || defined(_WIN64)
11922  d->owner = 0;
11923  LeaveCriticalSection(&d->cs);
11924  DeleteCriticalSection(&d->cs);
11925 #endif
11926  xfree(d);
11927  ret = SQL_SUCCESS;
11928 done:
11929 #if defined(_WIN32) || defined(_WIN64)
11930  if (e) {
11931  LeaveCriticalSection(&e->cs);
11932  }
11933 #endif
11934  return ret;
11935 }
11936 
11943 SQLRETURN SQL_API
11945 {
11946  return drvfreeconnect(dbc);
11947 }
11948 
11959 static SQLRETURN
11960 drvgetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
11961  SQLINTEGER bufmax, SQLINTEGER *buflen)
11962 {
11963  DBC *d;
11964  SQLINTEGER dummy;
11965 
11966  if (dbc == SQL_NULL_HDBC) {
11967  return SQL_INVALID_HANDLE;
11968  }
11969  d = (DBC *) dbc;
11970  if (!val) {
11971  val = (SQLPOINTER) &dummy;
11972  }
11973  if (!buflen) {
11974  buflen = &dummy;
11975  }
11976  switch (attr) {
11977  case SQL_ATTR_CONNECTION_DEAD:
11978  *((SQLINTEGER *) val) = d->sqlite ? SQL_CD_FALSE : SQL_CD_TRUE;
11979  *buflen = sizeof (SQLINTEGER);
11980  break;
11981  case SQL_ATTR_ACCESS_MODE:
11982  *((SQLINTEGER *) val) = SQL_MODE_READ_WRITE;
11983  *buflen = sizeof (SQLINTEGER);
11984  break;
11985  case SQL_ATTR_AUTOCOMMIT:
11986  *((SQLINTEGER *) val) =
11987  d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
11988  *buflen = sizeof (SQLINTEGER);
11989  break;
11990  case SQL_ATTR_LOGIN_TIMEOUT:
11991  *((SQLINTEGER *) val) = 100;
11992  *buflen = sizeof (SQLINTEGER);
11993  break;
11994  case SQL_ATTR_ODBC_CURSORS:
11995  *((SQLINTEGER *) val) = SQL_CUR_USE_DRIVER;
11996  *buflen = sizeof (SQLINTEGER);
11997  break;
11998  case SQL_ATTR_PACKET_SIZE:
11999  *((SQLINTEGER *) val) = 16384;
12000  *buflen = sizeof (SQLINTEGER);
12001  break;
12002  case SQL_ATTR_TXN_ISOLATION:
12003  *((SQLINTEGER *) val) = SQL_TXN_SERIALIZABLE;
12004  *buflen = sizeof (SQLINTEGER);
12005  break;
12006  case SQL_ATTR_TRACEFILE:
12007  case SQL_ATTR_TRANSLATE_LIB:
12008  *((SQLCHAR *) val) = 0;
12009  *buflen = 0;
12010  break;
12011  case SQL_ATTR_CURRENT_CATALOG:
12012 #if defined(_WIN32) || defined(_WIN64)
12013  if (d->xcelqrx) {
12014  if ((bufmax > 4) && (val != (SQLPOINTER) &dummy)) {
12015  strcpy((char *) val, "main");
12016  *buflen = 4;
12017  break;
12018  }
12019  }
12020 #endif
12021  *((SQLCHAR *) val) = 0;
12022  *buflen = 0;
12023  break;
12024  case SQL_ATTR_TRACE:
12025  case SQL_ATTR_QUIET_MODE:
12026  case SQL_ATTR_TRANSLATE_OPTION:
12027  case SQL_ATTR_KEYSET_SIZE:
12028  case SQL_ATTR_QUERY_TIMEOUT:
12029  *((SQLINTEGER *) val) = 0;
12030  *buflen = sizeof (SQLINTEGER);
12031  break;
12032  case SQL_ATTR_PARAM_BIND_TYPE:
12033  *((SQLULEN *) val) = SQL_PARAM_BIND_BY_COLUMN;
12034  *buflen = sizeof (SQLUINTEGER);
12035  break;
12036  case SQL_ATTR_ROW_BIND_TYPE:
12037  *((SQLULEN *) val) = SQL_BIND_BY_COLUMN;
12038  *buflen = sizeof (SQLULEN);
12039  break;
12040  case SQL_ATTR_USE_BOOKMARKS:
12041  *((SQLINTEGER *) val) = SQL_UB_OFF;
12042  *buflen = sizeof (SQLINTEGER);
12043  break;
12044  case SQL_ATTR_ASYNC_ENABLE:
12045  *((SQLINTEGER *) val) = SQL_ASYNC_ENABLE_OFF;
12046  *buflen = sizeof (SQLINTEGER);
12047  break;
12048  case SQL_ATTR_NOSCAN:
12049  *((SQLINTEGER *) val) = SQL_NOSCAN_ON;
12050  *buflen = sizeof (SQLINTEGER);
12051  break;
12052  case SQL_ATTR_CONCURRENCY:
12053  *((SQLINTEGER *) val) = SQL_CONCUR_LOCK;
12054  *buflen = sizeof (SQLINTEGER);
12055  break;
12056 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
12057  case SQL_ATTR_CURSOR_SENSITIVITY:
12058  *((SQLINTEGER *) val) = SQL_UNSPECIFIED;
12059  *buflen = sizeof (SQLINTEGER);
12060  break;
12061 #endif
12062  case SQL_ATTR_SIMULATE_CURSOR:
12063  *((SQLINTEGER *) val) = SQL_SC_NON_UNIQUE;
12064  *buflen = sizeof (SQLINTEGER);
12065  break;
12066  case SQL_ATTR_MAX_ROWS:
12067  *((SQLINTEGER *) val) = 0;
12068  *buflen = sizeof (SQLINTEGER);
12069  case SQL_ATTR_MAX_LENGTH:
12070  *((SQLINTEGER *) val) = 1000000000;
12071  *buflen = sizeof (SQLINTEGER);
12072  break;
12073  case SQL_ATTR_CURSOR_TYPE:
12074  *((SQLINTEGER *) val) = d->curtype;
12075  *buflen = sizeof (SQLINTEGER);
12076  break;
12077  case SQL_ATTR_RETRIEVE_DATA:
12078  *((SQLINTEGER *) val) = SQL_RD_ON;
12079  *buflen = sizeof (SQLINTEGER);
12080  break;
12081 #ifdef SQL_ATTR_METADATA_ID
12082  case SQL_ATTR_METADATA_ID:
12083  *((SQLULEN *) val) = SQL_FALSE;
12084  return SQL_SUCCESS;
12085 #endif
12086  default:
12087  *((SQLINTEGER *) val) = 0;
12088  *buflen = sizeof (SQLINTEGER);
12089  setstatd(d, -1, "unsupported connect attribute %d",
12090  (*d->ov3) ? "HYC00" : "S1C00", (int) attr);
12091  return SQL_ERROR;
12092  }
12093  return SQL_SUCCESS;
12094 }
12095 
12096 #ifndef WINTERFACE
12097 
12107 SQLRETURN SQL_API
12108 SQLGetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12109  SQLINTEGER bufmax, SQLINTEGER *buflen)
12110 {
12111  SQLRETURN ret;
12112 
12113  HDBC_LOCK(dbc);
12114  ret = drvgetconnectattr(dbc, attr, val, bufmax, buflen);
12115  HDBC_UNLOCK(dbc);
12116  return ret;
12117 }
12118 #endif
12119 
12120 #ifdef WINTERFACE
12121 
12131 SQLRETURN SQL_API
12132 SQLGetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12133  SQLINTEGER bufmax, SQLINTEGER *buflen)
12134 {
12135  SQLRETURN ret;
12136  SQLINTEGER len = 0;
12137 
12138  HDBC_LOCK(dbc);
12139  ret = drvgetconnectattr(dbc, attr, val, bufmax, &len);
12140  if (ret == SQL_SUCCESS) {
12141  SQLWCHAR *v = NULL;
12142 
12143  switch (attr) {
12144  case SQL_ATTR_TRACEFILE:
12145  case SQL_ATTR_CURRENT_CATALOG:
12146  case SQL_ATTR_TRANSLATE_LIB:
12147  if (val) {
12148  if (len > 0) {
12149  v = uc_from_utf((SQLCHAR *) val, len);
12150  if (v) {
12151  int vmax = bufmax / sizeof (SQLWCHAR);
12152 
12153  uc_strncpy(val, v, vmax);
12154  if (len < vmax) {
12155  len = min(vmax, uc_strlen(v));
12156  v[len] = 0;
12157  } else {
12158  len = vmax;
12159  }
12160  uc_free(v);
12161  len *= sizeof (SQLWCHAR);
12162  } else {
12163  len = 0;
12164  }
12165  }
12166  if (len <= 0) {
12167  len = 0;
12168  if (bufmax >= sizeof (SQLWCHAR)) {
12169  *((SQLWCHAR *)val) = 0;
12170  }
12171  }
12172  } else {
12173  len *= sizeof (SQLWCHAR);
12174  }
12175  break;
12176  }
12177  if (buflen) {
12178  *buflen = len;
12179  }
12180  }
12181  HDBC_UNLOCK(dbc);
12182  return ret;
12183 }
12184 #endif
12185 
12195 static SQLRETURN
12196 drvsetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12197  SQLINTEGER len)
12198 {
12199  DBC *d;
12200 
12201  if (dbc == SQL_NULL_HDBC) {
12202  return SQL_INVALID_HANDLE;
12203  }
12204  d = (DBC *) dbc;
12205  switch (attr) {
12206  case SQL_AUTOCOMMIT:
12207  d->autocommit = val == (SQLPOINTER) SQL_AUTOCOMMIT_ON;
12208  if (d->autocommit && d->intrans) {
12209  return endtran(d, SQL_COMMIT, 1);
12210  } else if (!d->autocommit) {
12211  s3stmt_end(d->cur_s3stmt);
12212  }
12213  break;
12214  return SQL_SUCCESS;
12215 #ifdef SQL_ATTR_METADATA_ID
12216  case SQL_ATTR_METADATA_ID:
12217  if (val == (SQLPOINTER) SQL_FALSE) {
12218  break;
12219  }
12220  /* fall through */
12221 #endif
12222  default:
12223  setstatd(d, -1, "option value changed", "01S02");
12224  return SQL_SUCCESS_WITH_INFO;
12225  }
12226  return SQL_SUCCESS;
12227 }
12228 
12229 #ifndef WINTERFACE
12230 
12239 SQLRETURN SQL_API
12240 SQLSetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12241  SQLINTEGER len)
12242 {
12243  SQLRETURN ret;
12244 
12245  HDBC_LOCK(dbc);
12246  ret = drvsetconnectattr(dbc, attr, val, len);
12247  HDBC_UNLOCK(dbc);
12248  return ret;
12249 }
12250 #endif
12251 
12252 #ifdef WINTERFACE
12253 
12262 SQLRETURN SQL_API
12263 SQLSetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12264  SQLINTEGER len)
12265 {
12266  SQLRETURN ret;
12267 
12268  HDBC_LOCK(dbc);
12269  ret = drvsetconnectattr(dbc, attr, val, len);
12270  HDBC_UNLOCK(dbc);
12271  return ret;
12272 }
12273 #endif
12274 
12283 static SQLRETURN
12284 drvgetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12285 {
12286  DBC *d;
12287  SQLINTEGER dummy;
12288 
12289  if (dbc == SQL_NULL_HDBC) {
12290  return SQL_INVALID_HANDLE;
12291  }
12292  d = (DBC *) dbc;
12293  if (!param) {
12294  param = (SQLPOINTER) &dummy;
12295  }
12296  switch (opt) {
12297  case SQL_ACCESS_MODE:
12298  *((SQLINTEGER *) param) = SQL_MODE_READ_WRITE;
12299  break;
12300  case SQL_AUTOCOMMIT:
12301  *((SQLINTEGER *) param) =
12302  d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
12303  break;
12304  case SQL_LOGIN_TIMEOUT:
12305  *((SQLINTEGER *) param) = 100;
12306  break;
12307  case SQL_ODBC_CURSORS:
12308  *((SQLINTEGER *) param) = SQL_CUR_USE_DRIVER;
12309  break;
12310  case SQL_PACKET_SIZE:
12311  *((SQLINTEGER *) param) = 16384;
12312  break;
12313  case SQL_TXN_ISOLATION:
12314  *((SQLINTEGER *) param) = SQL_TXN_SERIALIZABLE;
12315  break;
12316  case SQL_OPT_TRACE:
12317  case SQL_OPT_TRACEFILE:
12318  case SQL_QUIET_MODE:
12319  case SQL_TRANSLATE_DLL:
12320  case SQL_TRANSLATE_OPTION:
12321  case SQL_KEYSET_SIZE:
12322  case SQL_QUERY_TIMEOUT:
12323  case SQL_BIND_TYPE:
12324  case SQL_CURRENT_QUALIFIER:
12325  *((SQLINTEGER *) param) = 0;
12326  break;
12327  case SQL_USE_BOOKMARKS:
12328  *((SQLINTEGER *) param) = SQL_UB_OFF;
12329  break;
12330  case SQL_ASYNC_ENABLE:
12331  *((SQLINTEGER *) param) = SQL_ASYNC_ENABLE_OFF;
12332  break;
12333  case SQL_NOSCAN:
12334  *((SQLINTEGER *) param) = SQL_NOSCAN_ON;
12335  break;
12336  case SQL_CONCURRENCY:
12337  *((SQLINTEGER *) param) = SQL_CONCUR_LOCK;
12338  break;
12339  case SQL_SIMULATE_CURSOR:
12340  *((SQLINTEGER *) param) = SQL_SC_NON_UNIQUE;
12341  break;
12342  case SQL_MAX_ROWS:
12343  *((SQLINTEGER *) param) = 0;
12344  break;
12345  case SQL_ROWSET_SIZE:
12346  case SQL_MAX_LENGTH:
12347  *((SQLINTEGER *) param) = 1000000000;
12348  break;
12349  case SQL_CURSOR_TYPE:
12350  *((SQLINTEGER *) param) = d->curtype;
12351  break;
12352  case SQL_RETRIEVE_DATA:
12353  *((SQLINTEGER *) param) = SQL_RD_ON;
12354  break;
12355  default:
12356  *((SQLINTEGER *) param) = 0;
12357  setstatd(d, -1, "unsupported connect option %d",
12358  (*d->ov3) ? "HYC00" : "S1C00", opt);
12359  return SQL_ERROR;
12360  }
12361  return SQL_SUCCESS;
12362 }
12363 
12364 #ifndef WINTERFACE
12365 
12373 SQLRETURN SQL_API
12374 SQLGetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12375 {
12376  SQLRETURN ret;
12377 
12378  HDBC_LOCK(dbc);
12379  ret = drvgetconnectoption(dbc, opt, param);
12380  HDBC_UNLOCK(dbc);
12381  return ret;
12382 }
12383 #endif
12384 
12385 #ifdef WINTERFACE
12386 
12394 SQLRETURN SQL_API
12395 SQLGetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12396 {
12397  SQLRETURN ret;
12398 
12399  HDBC_LOCK(dbc);
12400  ret = drvgetconnectoption(dbc, opt, param);
12401  if (SQL_SUCCEEDED(ret)) {
12402  switch (opt) {
12403  case SQL_OPT_TRACEFILE:
12404  case SQL_CURRENT_QUALIFIER:
12405  case SQL_TRANSLATE_DLL:
12406  if (param) {
12407  *(SQLWCHAR *) param = 0;
12408  }
12409  break;
12410  }
12411  }
12412  HDBC_UNLOCK(dbc);
12413  return ret;
12414 }
12415 #endif
12416 
12425 static SQLRETURN
12426 drvsetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
12427 {
12428  DBC *d;
12429 
12430  if (dbc == SQL_NULL_HDBC) {
12431  return SQL_INVALID_HANDLE;
12432  }
12433  d = (DBC *) dbc;
12434  switch (opt) {
12435  case SQL_AUTOCOMMIT:
12436  d->autocommit = param == SQL_AUTOCOMMIT_ON;
12437  if (d->autocommit && d->intrans) {
12438  return endtran(d, SQL_COMMIT, 1);
12439  } else if (!d->autocommit) {
12440  s3stmt_end(d->cur_s3stmt);
12441  }
12442  break;
12443  default:
12444  setstatd(d, -1, "option value changed", "01S02");
12445  return SQL_SUCCESS_WITH_INFO;
12446  }
12447  return SQL_SUCCESS;
12448 }
12449 
12450 #ifndef WINTERFACE
12451 
12459 SQLRETURN SQL_API
12460 SQLSetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12461 {
12462  SQLRETURN ret;
12463 
12464  HDBC_LOCK(dbc);
12465  ret = drvsetconnectoption(dbc, opt, param);
12466  HDBC_UNLOCK(dbc);
12467  return ret;
12468 }
12469 #endif
12470 
12471 #ifdef WINTERFACE
12472 
12480 SQLRETURN SQL_API
12481 SQLSetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12482 {
12483  SQLRETURN ret;
12484 
12485  HDBC_LOCK(dbc);
12486  ret = drvsetconnectoption(dbc, opt, param);
12487  HDBC_UNLOCK(dbc);
12488  return ret;
12489 }
12490 #endif
12491 
12492 #if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
12493 
12504 static int
12505 getdsnattr(char *dsn, char *attr, char *out, int outLen)
12506 {
12507  char *str = dsn, *start;
12508  int len = strlen(attr);
12509 
12510  while (*str) {
12511  while (*str && *str == ';') {
12512  ++str;
12513  }
12514  start = str;
12515  if ((str = strchr(str, '=')) == NULL) {
12516  return 0;
12517  }
12518  if (str - start == len && strncasecmp(start, attr, len) == 0) {
12519  start = ++str;
12520  while (*str && *str != ';') {
12521  ++str;
12522  }
12523  len = min(outLen - 1, str - start);
12524  strncpy(out, start, len);
12525  out[len] = '\0';
12526  return 1;
12527  }
12528  while (*str && *str != ';') {
12529  ++str;
12530  }
12531  }
12532  return 0;
12533 }
12534 #endif
12535 
12547 static SQLRETURN
12548 drvconnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen, char *pwd,
12549  int pwdLen, int isu)
12550 {
12551  DBC *d;
12552  int len;
12553  SQLRETURN ret;
12554  char buf[SQL_MAX_MESSAGE_LENGTH * 6], dbname[SQL_MAX_MESSAGE_LENGTH];
12555  char busy[SQL_MAX_MESSAGE_LENGTH / 4], tracef[SQL_MAX_MESSAGE_LENGTH];
12556  char loadext[SQL_MAX_MESSAGE_LENGTH];
12557  char sflag[32], spflag[32], ntflag[32], nwflag[32], biflag[32];
12558  char snflag[32], lnflag[32], ncflag[32], fkflag[32], jmode[32];
12559  char jdflag[32];
12560 #if defined(_WIN32) || defined(_WIN64)
12561  char oemcp[32];
12562 #endif
12563 
12564  if (dbc == SQL_NULL_HDBC) {
12565  return SQL_INVALID_HANDLE;
12566  }
12567  d = (DBC *) dbc;
12568  if (d->magic != DBC_MAGIC) {
12569  return SQL_INVALID_HANDLE;
12570  }
12571  if (d->sqlite != NULL) {
12572  setstatd(d, -1, "connection already established", "08002");
12573  return SQL_ERROR;
12574  }
12575  buf[0] = '\0';
12576  if (dsnLen == SQL_NTS) {
12577  len = sizeof (buf) - 1;
12578  } else {
12579  len = min(sizeof (buf) - 1, dsnLen);
12580  }
12581  if (dsn != NULL) {
12582  strncpy(buf, (char *) dsn, len);
12583  }
12584  buf[len] = '\0';
12585  if (buf[0] == '\0') {
12586  setstatd(d, -1, "invalid DSN", (*d->ov3) ? "HY090" : "S1090");
12587  return SQL_ERROR;
12588  }
12589 #if defined(_WIN32) || defined(_WIN64)
12590  /*
12591  * When DSN is in UTF it must be converted to ANSI
12592  * here for ANSI SQLGetPrivateProfileString()
12593  */
12594  if (isu) {
12595  char *cdsn = utf_to_wmb(buf, len);
12596 
12597  if (!cdsn) {
12598  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12599  return SQL_ERROR;
12600  }
12601  strcpy(buf, cdsn);
12602  uc_free(cdsn);
12603  }
12604 #endif
12605  busy[0] = '\0';
12606  dbname[0] = '\0';
12607 #ifdef WITHOUT_DRIVERMGR
12608  getdsnattr(buf, "database", dbname, sizeof (dbname));
12609  if (dbname[0] == '\0') {
12610  strncpy(dbname, buf, sizeof (dbname));
12611  dbname[sizeof (dbname) - 1] = '\0';
12612  }
12613  getdsnattr(buf, "timeout", busy, sizeof (busy));
12614  sflag[0] = '\0';
12615  getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
12616  spflag[0] = '\0';
12617  getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
12618  ntflag[0] = '\0';
12619  getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
12620  nwflag[0] = '\0';
12621  getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
12622  snflag[0] = '\0';
12623  getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
12624  lnflag[0] = '\0';
12625  getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
12626  ncflag[0] = '\0';
12627  getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
12628  fkflag[0] = '\0';
12629  getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
12630  loadext[0] = '\0';
12631  getdsnattr(buf, "loadext", loadext, sizeof (loadext));
12632  jmode[0] = '\0';
12633  getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
12634  jdflag[0] = '\0';
12635  getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
12636 #if defined(_WIN32) || defined(_WIN64)
12637  oemcp[0] = '\0';
12638  getdsnattr(buf, "oemcp", oemcp, sizeof (oemcp));
12639 #endif
12640  biflag[0] = '\0';
12641  getdsnattr(buf, "bigint", biflag, sizeof (biflag));
12642 #else
12643  SQLGetPrivateProfileString(buf, "timeout", "100000",
12644  busy, sizeof (busy), ODBC_INI);
12645  SQLGetPrivateProfileString(buf, "database", "",
12646  dbname, sizeof (dbname), ODBC_INI);
12647 #if defined(_WIN32) || defined(_WIN64)
12648  /* database name read from registry is not UTF8 !!! */
12649  isu = 0;
12650 #endif
12651  SQLGetPrivateProfileString(buf, "stepapi", "",
12652  sflag, sizeof (sflag), ODBC_INI);
12653  SQLGetPrivateProfileString(buf, "syncpragma", "NORMAL",
12654  spflag, sizeof (spflag), ODBC_INI);
12655  SQLGetPrivateProfileString(buf, "notxn", "",
12656  ntflag, sizeof (ntflag), ODBC_INI);
12657  SQLGetPrivateProfileString(buf, "nowchar", "",
12658  nwflag, sizeof (nwflag), ODBC_INI);
12659  SQLGetPrivateProfileString(buf, "shortnames", "",
12660  snflag, sizeof (snflag), ODBC_INI);
12661  SQLGetPrivateProfileString(buf, "longnames", "",
12662  lnflag, sizeof (lnflag), ODBC_INI);
12663  SQLGetPrivateProfileString(buf, "nocreat", "",
12664  ncflag, sizeof (ncflag), ODBC_INI);
12665  SQLGetPrivateProfileString(buf, "fksupport", "",
12666  fkflag, sizeof (fkflag), ODBC_INI);
12667  SQLGetPrivateProfileString(buf, "loadext", "",
12668  loadext, sizeof (loadext), ODBC_INI);
12669  SQLGetPrivateProfileString(buf, "journalmode", "",
12670  jmode, sizeof (jmode), ODBC_INI);
12671  SQLGetPrivateProfileString(buf, "jdconv", "",
12672  jdflag, sizeof (jdflag), ODBC_INI);
12673 #if defined(_WIN32) || defined(_WIN64)
12674  SQLGetPrivateProfileString(buf, "oemcp", "1",
12675  oemcp, sizeof (oemcp), ODBC_INI);
12676 #endif
12677  SQLGetPrivateProfileString(buf, "bigint", "",
12678  biflag, sizeof (biflag), ODBC_INI);
12679 #endif
12680  tracef[0] = '\0';
12681 #ifdef WITHOUT_DRIVERMGR
12682  getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
12683 #else
12684  SQLGetPrivateProfileString(buf, "tracefile", "",
12685  tracef, sizeof (tracef), ODBC_INI);
12686 #endif
12687  if (tracef[0] != '\0') {
12688  d->trace = fopen(tracef, "a");
12689  }
12690  d->nowchar = getbool(nwflag);
12691  d->shortnames = getbool(snflag);
12692  d->longnames = getbool(lnflag);
12693  d->nocreat = getbool(ncflag);
12694  d->fksupport = getbool(fkflag);
12695  d->jdconv = getbool(jdflag);
12696 #if defined(_WIN32) || defined(_WIN64)
12697  d->oemcp = getbool(oemcp);
12698 #else
12699  d->oemcp = 0;
12700 #endif
12701  d->dobigint = getbool(biflag);
12702  d->pwd = pwd;
12703  d->pwdLen = 0;
12704  if (d->pwd) {
12705  d->pwdLen = (pwdLen == SQL_NTS) ? strlen(d->pwd) : pwdLen;
12706  }
12707  ret = dbopen(d, dbname, isu, (char *) dsn, sflag, spflag, ntflag,
12708  jmode, busy);
12709  if (ret == SQL_SUCCESS) {
12710  dbloadext(d, loadext);
12711  }
12712  return ret;
12713 }
12714 
12715 #ifndef WINTERFACE
12716 
12728 SQLRETURN SQL_API
12729 SQLConnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen,
12730  SQLCHAR *uid, SQLSMALLINT uidLen,
12731  SQLCHAR *pwd, SQLSMALLINT pwdLen)
12732 {
12733  SQLRETURN ret;
12734 
12735  HDBC_LOCK(dbc);
12736  ret = drvconnect(dbc, dsn, dsnLen, (char *) pwd, pwdLen, 0);
12737  HDBC_UNLOCK(dbc);
12738  return ret;
12739 }
12740 #endif
12741 
12742 #ifdef WINTERFACE
12743 
12755 SQLRETURN SQL_API
12756 SQLConnectW(SQLHDBC dbc, SQLWCHAR *dsn, SQLSMALLINT dsnLen,
12757  SQLWCHAR *uid, SQLSMALLINT uidLen,
12758  SQLWCHAR *pwd, SQLSMALLINT pwdLen)
12759 {
12760  char *dsna = NULL;
12761  char *pwda = NULL;
12762  SQLRETURN ret;
12763 
12764  HDBC_LOCK(dbc);
12765  if (dsn) {
12766  dsna = uc_to_utf_c(dsn, dsnLen);
12767  if (!dsna) {
12768  DBC *d = (DBC *) dbc;
12769 
12770  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12771  ret = SQL_ERROR;
12772  goto done;
12773  }
12774  }
12775  if (pwd) {
12776  pwda = uc_to_utf_c(pwd, pwdLen);
12777  if (!pwda) {
12778  DBC *d = (DBC *) dbc;
12779 
12780  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12781  ret = SQL_ERROR;
12782  goto done;
12783  }
12784  }
12785  ret = drvconnect(dbc, (SQLCHAR *) dsna, SQL_NTS, pwda, SQL_NTS, 1);
12786 done:
12787  HDBC_UNLOCK(dbc);
12788  uc_free(dsna);
12789  uc_free(pwda);
12790  return ret;
12791 }
12792 #endif
12793 
12800 static SQLRETURN
12802 {
12803  DBC *d;
12804  int rc;
12805 
12806  if (dbc == SQL_NULL_HDBC) {
12807  return SQL_INVALID_HANDLE;
12808  }
12809  d = (DBC *) dbc;
12810  if (d->magic != DBC_MAGIC) {
12811  return SQL_INVALID_HANDLE;
12812  }
12813  if (d->intrans) {
12814  setstatd(d, -1, "incomplete transaction", "25000");
12815  return SQL_ERROR;
12816  }
12817  if (d->cur_s3stmt) {
12818  s3stmt_end(d->cur_s3stmt);
12819  }
12820  if (d->sqlite) {
12821  if (d->trace) {
12822  fprintf(d->trace, "-- sqlite3_close: '%s'\n",
12823  d->dbname);
12824  fflush(d->trace);
12825  }
12826  rc = sqlite3_close(d->sqlite);
12827  if (rc == SQLITE_BUSY) {
12828  setstatd(d, -1, "unfinished statements", "25000");
12829  return SQL_ERROR;
12830  }
12831  d->sqlite = NULL;
12832  }
12833  freep(&d->dbname);
12834  freep(&d->dsn);
12835  return SQL_SUCCESS;
12836 }
12837 
12844 SQLRETURN SQL_API
12846 {
12847  SQLRETURN ret;
12848 
12849  HDBC_LOCK(dbc);
12850  ret = drvdisconnect(dbc);
12851  HDBC_UNLOCK(dbc);
12852  return ret;
12853 }
12854 
12855 #if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
12856 
12870 static SQLRETURN
12871 drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
12872  SQLCHAR *connIn, SQLSMALLINT connInLen,
12873  SQLCHAR *connOut, SQLSMALLINT connOutMax,
12874  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
12875 {
12876  DBC *d;
12877  int len;
12878  SQLRETURN ret;
12879  char buf[SQL_MAX_MESSAGE_LENGTH * 8], dbname[SQL_MAX_MESSAGE_LENGTH];
12880  char dsn[SQL_MAX_MESSAGE_LENGTH], busy[SQL_MAX_MESSAGE_LENGTH / 4];
12881  char tracef[SQL_MAX_MESSAGE_LENGTH], loadext[SQL_MAX_MESSAGE_LENGTH];
12882  char pwd[SQL_MAX_MESSAGE_LENGTH];
12883  char sflag[32], spflag[32], ntflag[32], snflag[32], lnflag[32];
12884  char ncflag[32], nwflag[32], fkflag[32], jmode[32], biflag[32];
12885  char jdflag[32];
12886 
12887  if (dbc == SQL_NULL_HDBC) {
12888  return SQL_INVALID_HANDLE;
12889  }
12890  if (drvcompl != SQL_DRIVER_COMPLETE &&
12891  drvcompl != SQL_DRIVER_COMPLETE_REQUIRED &&
12892  drvcompl != SQL_DRIVER_PROMPT &&
12893  drvcompl != SQL_DRIVER_NOPROMPT) {
12894  return SQL_NO_DATA;
12895  }
12896  d = (DBC *) dbc;
12897  if (d->sqlite) {
12898  setstatd(d, -1, "connection already established", "08002");
12899  return SQL_ERROR;
12900  }
12901  buf[0] = '\0';
12902  if (connInLen == SQL_NTS) {
12903  len = sizeof (buf) - 1;
12904  } else {
12905  len = min(connInLen, sizeof (buf) - 1);
12906  }
12907  if (connIn != NULL) {
12908  strncpy(buf, (char *) connIn, len);
12909  }
12910  buf[len] = '\0';
12911  if (!buf[0]) {
12912  setstatd(d, -1, "invalid connect attributes",
12913  (*d->ov3) ? "HY090" : "S1090");
12914  return SQL_ERROR;
12915  }
12916  dsn[0] = '\0';
12917  getdsnattr(buf, "DSN", dsn, sizeof (dsn));
12918 
12919  /* special case: connIn is sole DSN value without keywords */
12920  if (!dsn[0] && !strchr(buf, ';') && !strchr(buf, '=')) {
12921  strncpy(dsn, buf, sizeof (dsn) - 1);
12922  dsn[sizeof (dsn) - 1] = '\0';
12923  }
12924 
12925  busy[0] = '\0';
12926  getdsnattr(buf, "timeout", busy, sizeof (busy));
12927 #ifndef WITHOUT_DRIVERMGR
12928  if (dsn[0] && !busy[0]) {
12929  SQLGetPrivateProfileString(dsn, "timeout", "100000",
12930  busy, sizeof (busy), ODBC_INI);
12931  }
12932 #endif
12933  dbname[0] = '\0';
12934  getdsnattr(buf, "database", dbname, sizeof (dbname));
12935 #ifndef WITHOUT_DRIVERMGR
12936  if (dsn[0] && !dbname[0]) {
12937  SQLGetPrivateProfileString(dsn, "database", "",
12938  dbname, sizeof (dbname), ODBC_INI);
12939  }
12940 #endif
12941  sflag[0] = '\0';
12942  getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
12943 #ifndef WITHOUT_DRIVERMGR
12944  if (dsn[0] && !sflag[0]) {
12945  SQLGetPrivateProfileString(dsn, "stepapi", "",
12946  sflag, sizeof (sflag), ODBC_INI);
12947  }
12948 #endif
12949  spflag[0] = '\0';
12950  getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
12951 #ifndef WITHOUT_DRIVERMGR
12952  if (dsn[0] && !spflag[0]) {
12953  SQLGetPrivateProfileString(dsn, "syncpragma", "NORMAL",
12954  spflag, sizeof (spflag), ODBC_INI);
12955  }
12956 #endif
12957  ntflag[0] = '\0';
12958  getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
12959 #ifndef WITHOUT_DRIVERMGR
12960  if (dsn[0] && !ntflag[0]) {
12961  SQLGetPrivateProfileString(dsn, "notxn", "",
12962  ntflag, sizeof (ntflag), ODBC_INI);
12963  }
12964 #endif
12965  snflag[0] = '\0';
12966  getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
12967 #ifndef WITHOUT_DRIVERMGR
12968  if (dsn[0] && !snflag[0]) {
12969  SQLGetPrivateProfileString(dsn, "shortnames", "",
12970  snflag, sizeof (snflag), ODBC_INI);
12971  }
12972 #endif
12973  lnflag[0] = '\0';
12974  getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
12975 #ifndef WITHOUT_DRIVERMGR
12976  if (dsn[0] && !lnflag[0]) {
12977  SQLGetPrivateProfileString(dsn, "longnames", "",
12978  lnflag, sizeof (lnflag), ODBC_INI);
12979  }
12980 #endif
12981  ncflag[0] = '\0';
12982  getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
12983 #ifndef WITHOUT_DRIVERMGR
12984  if (dsn[0] && !ncflag[0]) {
12985  SQLGetPrivateProfileString(dsn, "nocreat", "",
12986  ncflag, sizeof (ncflag), ODBC_INI);
12987  }
12988 #endif
12989  nwflag[0] = '\0';
12990  getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
12991 #ifndef WITHOUT_DRIVERMGR
12992  if (dsn[0] && !nwflag[0]) {
12993  SQLGetPrivateProfileString(dsn, "nowchar", "",
12994  nwflag, sizeof (nwflag), ODBC_INI);
12995  }
12996 #endif
12997  fkflag[0] = '\0';
12998  getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
12999 #ifndef WITHOUT_DRIVERMGR
13000  if (dsn[0] && !fkflag[0]) {
13001  SQLGetPrivateProfileString(dsn, "fksupport", "",
13002  fkflag, sizeof (fkflag), ODBC_INI);
13003  }
13004 #endif
13005  loadext[0] = '\0';
13006  getdsnattr(buf, "loadext", loadext, sizeof (loadext));
13007 #ifndef WITHOUT_DRIVERMGR
13008  if (dsn[0] && !loadext[0]) {
13009  SQLGetPrivateProfileString(dsn, "loadext", "",
13010  loadext, sizeof (loadext), ODBC_INI);
13011  }
13012 #endif
13013  jmode[0] = '\0';
13014  getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
13015 #ifndef WITHOUT_DRIVERMGR
13016  if (dsn[0] && !jmode[0]) {
13017  SQLGetPrivateProfileString(dsn, "journalmode", "",
13018  jmode, sizeof (jmode), ODBC_INI);
13019  }
13020 #endif
13021  biflag[0] = '\0';
13022  getdsnattr(buf, "bigint", biflag, sizeof (biflag));
13023 #ifndef WITHOUT_DRIVERMGR
13024  if (dsn[0] && !biflag[0]) {
13025  SQLGetPrivateProfileString(dsn, "bigint", "",
13026  biflag, sizeof (biflag), ODBC_INI);
13027  }
13028 #endif
13029  jdflag[0] = '\0';
13030  getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
13031 #ifndef WITHOUT_DRIVERMGR
13032  if (dsn[0] && !jdflag[0]) {
13033  SQLGetPrivateProfileString(dsn, "jdconv", "",
13034  jdflag, sizeof (jdflag), ODBC_INI);
13035  }
13036 #endif
13037  pwd[0] = '\0';
13038  getdsnattr(buf, "pwd", pwd, sizeof (pwd));
13039 #ifndef WITHOUT_DRIVERMGR
13040  if (dsn[0] && !pwd[0]) {
13041  SQLGetPrivateProfileString(dsn, "pwd", "",
13042  pwd, sizeof (pwd), ODBC_INI);
13043  }
13044 #endif
13045 
13046  if (!dbname[0] && !dsn[0]) {
13047  strcpy(dsn, "SQLite");
13048  strncpy(dbname, buf, sizeof (dbname));
13049  dbname[sizeof (dbname) - 1] = '\0';
13050  }
13051  tracef[0] = '\0';
13052  getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
13053 #ifndef WITHOUT_DRIVERMGR
13054  if (dsn[0] && !tracef[0]) {
13055  SQLGetPrivateProfileString(dsn, "tracefile", "",
13056  tracef, sizeof (tracef), ODBC_INI);
13057  }
13058 #endif
13059  if (connOut || connOutLen) {
13060  int count;
13061 
13062  buf[0] = '\0';
13063  count = snprintf(buf, sizeof (buf),
13064  "DSN=%s;Database=%s;StepAPI=%s;Timeout=%s;"
13065  "SyncPragma=%s;NoTXN=%s;ShortNames=%s;LongNames=%s;"
13066  "NoCreat=%s;NoWCHAR=%s;FKSupport=%s;Tracefile=%s;"
13067  "JournalMode=%s;LoadExt=%s;BigInt=%s;JDConv=%s;"
13068  "PWD=%s",
13069  dsn, dbname, sflag, busy, spflag, ntflag,
13070  snflag, lnflag, ncflag, nwflag, fkflag, tracef,
13071  jmode, loadext, biflag, jdflag, pwd);
13072  if (count < 0) {
13073  buf[sizeof (buf) - 1] = '\0';
13074  }
13075  len = min(connOutMax - 1, strlen(buf));
13076  if (connOut) {
13077  strncpy((char *) connOut, buf, len);
13078  connOut[len] = '\0';
13079  }
13080  if (connOutLen) {
13081  *connOutLen = len;
13082  }
13083  }
13084  if (tracef[0] != '\0') {
13085  d->trace = fopen(tracef, "a");
13086  }
13087  d->shortnames = getbool(snflag);
13088  d->longnames = getbool(lnflag);
13089  d->nocreat = getbool(ncflag);
13090  d->nowchar = getbool(nwflag);
13091  d->fksupport = getbool(fkflag);
13092  d->dobigint = getbool(biflag);
13093  d->jdconv = getbool(jdflag);
13094  d->oemcp = 0;
13095  d->pwdLen = strlen(pwd);
13096  d->pwd = (d->pwdLen > 0) ? pwd : NULL;
13097  ret = dbopen(d, dbname, 0, dsn, sflag, spflag, ntflag, jmode, busy);
13098  memset(pwd, 0, sizeof (pwd));
13099  if (ret == SQL_SUCCESS) {
13100  dbloadext(d, loadext);
13101  }
13102  return ret;
13103 }
13104 #endif
13105 
13112 static SQLRETURN
13113 freestmt(SQLHSTMT stmt)
13114 {
13115  STMT *s;
13116  DBC *d;
13117 
13118  if (stmt == SQL_NULL_HSTMT) {
13119  return SQL_INVALID_HANDLE;
13120  }
13121  s = (STMT *) stmt;
13122  s3stmt_drop(s);
13123  freeresult(s, 1);
13124  freep(&s->query);
13125  d = (DBC *) s->dbc;
13126  if (d && d->magic == DBC_MAGIC) {
13127  STMT *p, *n;
13128 
13129  p = NULL;
13130  n = d->stmt;
13131  while (n) {
13132  if (n == s) {
13133  break;
13134  }
13135  p = n;
13136  n = n->next;
13137  }
13138  if (n) {
13139  if (p) {
13140  p->next = s->next;
13141  } else {
13142  d->stmt = s->next;
13143  }
13144  }
13145  }
13146  freeparams(s);
13147  freep(&s->bindparms);
13148  if (s->row_status0 != &s->row_status1) {
13149  freep(&s->row_status0);
13150  s->rowset_size = 1;
13151  s->row_status0 = &s->row_status1;
13152  }
13153  xfree(s);
13154  return SQL_SUCCESS;
13155 }
13156 
13164 static SQLRETURN
13165 drvallocstmt(SQLHDBC dbc, SQLHSTMT *stmt)
13166 {
13167  DBC *d;
13168  STMT *s, *sl, *pl;
13169 
13170  if (dbc == SQL_NULL_HDBC) {
13171  return SQL_INVALID_HANDLE;
13172  }
13173  d = (DBC *) dbc;
13174  if (d->magic != DBC_MAGIC || stmt == NULL) {
13175  return SQL_INVALID_HANDLE;
13176  }
13177  s = (STMT *) xmalloc(sizeof (STMT));
13178  if (s == NULL) {
13179  *stmt = SQL_NULL_HSTMT;
13180  return SQL_ERROR;
13181  }
13182  *stmt = (SQLHSTMT) s;
13183  memset(s, 0, sizeof (STMT));
13184  s->dbc = dbc;
13185  s->ov3 = d->ov3;
13186  s->bkmrk = SQL_UB_OFF;
13187  s->bkmrkptr = 0;
13188  s->oemcp = &d->oemcp;
13189  s->jdconv = &d->jdconv;
13190  s->nowchar[0] = d->nowchar;
13191  s->nowchar[1] = 0;
13192  s->dobigint = d->dobigint;
13193  s->curtype = d->curtype;
13194  s->row_status0 = &s->row_status1;
13195  s->rowset_size = 1;
13196  s->longnames = d->longnames;
13197  s->retr_data = SQL_RD_ON;
13198  s->max_rows = 0;
13199  s->bind_type = SQL_BIND_BY_COLUMN;
13200  s->bind_offs = NULL;
13201  s->paramset_size = 1;
13202  s->parm_bind_type = SQL_PARAM_BIND_BY_COLUMN;
13203  s->one_tbl = -1;
13204  s->has_pk = -1;
13205  s->has_rowid = -1;
13206 #ifdef _WIN64
13207  sprintf((char *) s->cursorname, "CUR_%I64X", (SQLUBIGINT) *stmt);
13208 #else
13209  sprintf((char *) s->cursorname, "CUR_%016lX", (long) *stmt);
13210 #endif
13211  sl = d->stmt;
13212  pl = NULL;
13213  while (sl) {
13214  pl = sl;
13215  sl = sl->next;
13216  }
13217  if (pl) {
13218  pl->next = s;
13219  } else {
13220  d->stmt = s;
13221  }
13222  return SQL_SUCCESS;
13223 }
13224 
13232 SQLRETURN SQL_API
13233 SQLAllocStmt(SQLHDBC dbc, SQLHSTMT *stmt)
13234 {
13235  SQLRETURN ret;
13236 
13237  HDBC_LOCK(dbc);
13238  ret = drvallocstmt(dbc, stmt);
13239  HDBC_UNLOCK(dbc);
13240  return ret;
13241 }
13242 
13250 static SQLRETURN
13251 drvfreestmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13252 {
13253  STMT *s;
13254  SQLRETURN ret = SQL_SUCCESS;
13255  SQLHDBC dbc;
13256 
13257  if (stmt == SQL_NULL_HSTMT) {
13258  return SQL_INVALID_HANDLE;
13259  }
13260  HSTMT_LOCK(stmt);
13261  s = (STMT *) stmt;
13262  dbc = s->dbc;
13263  switch (opt) {
13264  case SQL_RESET_PARAMS:
13265  freeparams(s);
13266  break;
13267  case SQL_UNBIND:
13268  unbindcols(s);
13269  break;
13270  case SQL_CLOSE:
13271  s3stmt_end_if(s);
13272  freeresult(s, 0);
13273  break;
13274  case SQL_DROP:
13275  s3stmt_end_if(s);
13276  ret = freestmt(stmt);
13277  break;
13278  default:
13279  setstat(s, -1, "unsupported option", (*s->ov3) ? "HYC00" : "S1C00");
13280  ret = SQL_ERROR;
13281  break;
13282  }
13283  HDBC_UNLOCK(dbc);
13284  return ret;
13285 }
13286 
13294 SQLRETURN SQL_API
13295 SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13296 {
13297  return drvfreestmt(stmt, opt);
13298 }
13299 
13306 SQLRETURN SQL_API
13307 SQLCancel(SQLHSTMT stmt)
13308 {
13309  if (stmt != SQL_NULL_HSTMT) {
13310  DBC *d = (DBC *) ((STMT *) stmt)->dbc;
13311 #if defined(_WIN32) || defined(_WIN64)
13312  /* interrupt when other thread owns critical section */
13313  if (d->magic == DBC_MAGIC && d->owner != GetCurrentThreadId() &&
13314  d->owner != 0) {
13315  d->busyint = 1;
13316  sqlite3_interrupt(d->sqlite);
13317  return SQL_SUCCESS;
13318  }
13319 #else
13320  if (d->magic == DBC_MAGIC) {
13321  d->busyint = 1;
13322  sqlite3_interrupt(d->sqlite);
13323  }
13324 #endif
13325  }
13326  return drvfreestmt(stmt, SQL_CLOSE);
13327 }
13328 
13338 static SQLRETURN
13339 drvgetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13340  SQLSMALLINT *lenp)
13341 {
13342  STMT *s;
13343 
13344  if (stmt == SQL_NULL_HSTMT) {
13345  return SQL_INVALID_HANDLE;
13346  }
13347  s = (STMT *) stmt;
13348  if (lenp && !cursor) {
13349  *lenp = strlen((char *) s->cursorname);
13350  return SQL_SUCCESS;
13351  }
13352  if (cursor) {
13353  if (buflen > 0) {
13354  strncpy((char *) cursor, (char *) s->cursorname, buflen - 1);
13355  cursor[buflen - 1] = '\0';
13356  }
13357  if (lenp) {
13358  *lenp = min(strlen((char *) s->cursorname), buflen - 1);
13359  }
13360  }
13361  return SQL_SUCCESS;
13362 }
13363 
13364 #ifndef WINTERFACE
13365 
13374 SQLRETURN SQL_API
13375 SQLGetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13376  SQLSMALLINT *lenp)
13377 {
13378  SQLRETURN ret;
13379 #if defined(_WIN32) || defined(_WIN64)
13380  SQLSMALLINT len = 0;
13381 #endif
13382 
13383  HSTMT_LOCK(stmt);
13384 #if defined(_WIN32) || defined(_WIN64)
13385  if (!((STMT *) stmt)->oemcp[0]) {
13386  ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13387  goto done;
13388  }
13389  ret = drvgetcursorname(stmt, cursor, buflen, &len);
13390  if (ret == SQL_SUCCESS) {
13391  char *c = NULL;
13392 
13393  if (cursor) {
13394  c = utf_to_wmb((char *) cursor, len);
13395  if (!c) {
13396  ret = nomem((STMT *) stmt);
13397  goto done;
13398  }
13399  c[len] = 0;
13400  len = strlen(c);
13401  if (buflen > 0) {
13402  strncpy((char *) cursor, c, buflen - 1);
13403  cursor[buflen - 1] = 0;
13404  }
13405  uc_free(c);
13406  }
13407  if (lenp) {
13408  *lenp = min(len, buflen - 1);
13409  }
13410  }
13411 done:
13412  ;
13413 #else
13414  ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13415 #endif
13416  HSTMT_UNLOCK(stmt);
13417  return ret;
13418 }
13419 #endif
13420 
13421 #ifdef WINTERFACE
13422 
13431 SQLRETURN SQL_API
13432 SQLGetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT buflen,
13433  SQLSMALLINT *lenp)
13434 {
13435  SQLRETURN ret;
13436  SQLSMALLINT len = 0;
13437 
13438  HSTMT_LOCK(stmt);
13439  ret = drvgetcursorname(stmt, (SQLCHAR *) cursor, buflen, &len);
13440  if (ret == SQL_SUCCESS) {
13441  SQLWCHAR *c = NULL;
13442 
13443  if (cursor) {
13444  c = uc_from_utf((SQLCHAR *) cursor, len);
13445  if (!c) {
13446  ret = nomem((STMT *) stmt);
13447  goto done;
13448  }
13449  c[len] = 0;
13450  len = uc_strlen(c);
13451  if (buflen > 0) {
13452  uc_strncpy(cursor, c, buflen - 1);
13453  cursor[buflen - 1] = 0;
13454  }
13455  uc_free(c);
13456  }
13457  if (lenp) {
13458  *lenp = min(len, buflen - 1);
13459  }
13460  }
13461 done:
13462  HSTMT_UNLOCK(stmt);
13463  return ret;
13464 }
13465 #endif
13466 
13475 static SQLRETURN
13476 drvsetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13477 {
13478  STMT *s;
13479 
13480  if (stmt == SQL_NULL_HSTMT) {
13481  return SQL_INVALID_HANDLE;
13482  }
13483  s = (STMT *) stmt;
13484  if (!cursor ||
13485  !((cursor[0] >= 'A' && cursor[0] <= 'Z') ||
13486  (cursor[0] >= 'a' && cursor[0] <= 'z'))) {
13487  setstat(s, -1, "invalid cursor name", (*s->ov3) ? "HYC00" : "S1C00");
13488  return SQL_ERROR;
13489  }
13490  if (len == SQL_NTS) {
13491  len = sizeof (s->cursorname) - 1;
13492  } else {
13493  len = min(sizeof (s->cursorname) - 1, len);
13494  }
13495  strncpy((char *) s->cursorname, (char *) cursor, len);
13496  s->cursorname[len] = '\0';
13497  return SQL_SUCCESS;
13498 }
13499 
13500 #ifndef WINTERFACE
13501 
13509 SQLRETURN SQL_API
13510 SQLSetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13511 {
13512 #if defined(_WIN32) || defined(_WIN64)
13513  char *c = NULL;
13514 #endif
13515  SQLRETURN ret;
13516 
13517  HSTMT_LOCK(stmt);
13518 #if defined(_WIN32) || defined(_WIN64)
13519  if (!((STMT *) stmt)->oemcp[0]) {
13520  ret = drvsetcursorname(stmt, cursor, len);
13521  goto done2;
13522  }
13523  if (cursor) {
13524  c = wmb_to_utf_c((char *) cursor, len);
13525  if (!c) {
13526  ret = nomem((STMT *) stmt);
13527  goto done;
13528  }
13529  }
13530  ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13531 #else
13532  ret = drvsetcursorname(stmt, cursor, len);
13533 #endif
13534 #if defined(_WIN32) || defined(_WIN64)
13535 done:
13536  uc_free(c);
13537 done2:
13538  ;
13539 #endif
13540  HSTMT_UNLOCK(stmt);
13541  return ret;
13542 }
13543 #endif
13544 
13545 #ifdef WINTERFACE
13546 
13554 SQLRETURN SQL_API
13555 SQLSetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT len)
13556 {
13557  char *c = NULL;
13558  SQLRETURN ret;
13559 
13560  HSTMT_LOCK(stmt);
13561  if (cursor) {
13562  c = uc_to_utf_c(cursor, len);
13563  if (!c) {
13564  ret = nomem((STMT *) stmt);
13565  goto done;
13566  }
13567  }
13568  ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13569 done:
13570  uc_free(c);
13571  HSTMT_UNLOCK(stmt);
13572  return ret;
13573 }
13574 #endif
13575 
13582 SQLRETURN SQL_API
13584 {
13585  return drvfreestmt(stmt, SQL_CLOSE);
13586 }
13587 
13596 SQLRETURN SQL_API
13597 SQLAllocHandle(SQLSMALLINT type, SQLHANDLE input, SQLHANDLE *output)
13598 {
13599  SQLRETURN ret;
13600 
13601  switch (type) {
13602  case SQL_HANDLE_ENV:
13603  ret = drvallocenv((SQLHENV *) output);
13604  if (ret == SQL_SUCCESS) {
13605  ENV *e = (ENV *) *output;
13606 
13607  if (e && e->magic == ENV_MAGIC) {
13608  e->ov3 = 1;
13609  }
13610  }
13611  return ret;
13612  case SQL_HANDLE_DBC:
13613  return drvallocconnect((SQLHENV) input, (SQLHDBC *) output);
13614  case SQL_HANDLE_STMT:
13615  HDBC_LOCK((SQLHDBC) input);
13616  ret = drvallocstmt((SQLHDBC) input, (SQLHSTMT *) output);
13617  HDBC_UNLOCK((SQLHDBC) input);
13618  return ret;
13619  }
13620  return SQL_ERROR;
13621 }
13622 
13630 SQLRETURN SQL_API
13631 SQLFreeHandle(SQLSMALLINT type, SQLHANDLE h)
13632 {
13633  switch (type) {
13634  case SQL_HANDLE_ENV:
13635  return drvfreeenv((SQLHENV) h);
13636  case SQL_HANDLE_DBC:
13637  return drvfreeconnect((SQLHDBC) h);
13638  case SQL_HANDLE_STMT:
13639  return drvfreestmt((SQLHSTMT) h, SQL_DROP);
13640  }
13641  return SQL_ERROR;
13642 }
13643 
13649 static void
13651 {
13652  if (s->dyncols) {
13653  int i;
13654 
13655  for (i = 0; i < s->dcols; i++) {
13656  freep(&s->dyncols[i].typename);
13657  }
13658  if (s->cols == s->dyncols) {
13659  s->cols = NULL;
13660  s->ncols = 0;
13661  }
13662  freep(&s->dyncols);
13663  }
13664  s->dcols = 0;
13665 }
13666 
13678 static void
13679 freeresult(STMT *s, int clrcols)
13680 {
13681  freep(&s->bincache);
13682  s->bincell = NULL;
13683  s->binlen = 0;
13684  if (s->rows) {
13685  if (s->rowfree) {
13686  s->rowfree(s->rows);
13687  s->rowfree = NULL;
13688  }
13689  s->rows = NULL;
13690  }
13691  s->nrows = -1;
13692  if (clrcols > 0) {
13693  freep(&s->bindcols);
13694  s->nbindcols = 0;
13695  }
13696  if (clrcols) {
13697  freedyncols(s);
13698  s->cols = NULL;
13699  s->ncols = 0;
13700  s->nowchar[1] = 0;
13701  s->one_tbl = -1;
13702  s->has_pk = -1;
13703  s->has_rowid = -1;
13704  }
13705 }
13706 
13712 static void
13714 {
13715  int i;
13716 
13717  for (i = 0; s->bindcols && i < s->nbindcols; i++) {
13718  s->bindcols[i].type = SQL_UNKNOWN_TYPE;
13719  s->bindcols[i].max = 0;
13720  s->bindcols[i].lenp = NULL;
13721  s->bindcols[i].valp = NULL;
13722  s->bindcols[i].index = i;
13723  s->bindcols[i].offs = 0;
13724  }
13725 }
13726 
13734 static SQLRETURN
13735 mkbindcols(STMT *s, int ncols)
13736 {
13737  if (s->bindcols) {
13738  if (s->nbindcols < ncols) {
13739  int i;
13740  BINDCOL *bindcols =
13741  xrealloc(s->bindcols, ncols * sizeof (BINDCOL));
13742 
13743  if (!bindcols) {
13744  return nomem(s);
13745  }
13746  for (i = s->nbindcols; i < ncols; i++) {
13747  bindcols[i].type = SQL_UNKNOWN_TYPE;
13748  bindcols[i].max = 0;
13749  bindcols[i].lenp = NULL;
13750  bindcols[i].valp = NULL;
13751  bindcols[i].index = i;
13752  bindcols[i].offs = 0;
13753  }
13754  s->bindcols = bindcols;
13755  s->nbindcols = ncols;
13756  }
13757  } else if (ncols > 0) {
13758  s->bindcols = (BINDCOL *) xmalloc(ncols * sizeof (BINDCOL));
13759  if (!s->bindcols) {
13760  return nomem(s);
13761  }
13762  s->nbindcols = ncols;
13763  unbindcols(s);
13764  }
13765  return SQL_SUCCESS;
13766 }
13767 
13781 static SQLRETURN
13782 getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype,
13783  SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp, int partial)
13784 {
13785  char **data, valdummy[16];
13786  SQLLEN dummy;
13787  SQLINTEGER *ilenp = NULL;
13788  int valnull = 0;
13789  int type = otype;
13790  SQLRETURN sret = SQL_NO_DATA;
13791 
13792  if (!lenp) {
13793  lenp = &dummy;
13794  }
13795  /* workaround for JDK 1.7.0 on x86_64 */
13796  if (((SQLINTEGER *) lenp) + 1 == (SQLINTEGER *) val) {
13797  ilenp = (SQLINTEGER *) lenp;
13798  lenp = &dummy;
13799  }
13800  if (col >= s->ncols) {
13801  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
13802  return SQL_ERROR;
13803  }
13804  if (s->retr_data != SQL_RD_ON) {
13805  return SQL_SUCCESS;
13806  }
13807  if (!s->rows) {
13808  *lenp = SQL_NULL_DATA;
13809  goto done;
13810  }
13811  if (s->rowp < 0 || s->rowp >= s->nrows) {
13812  *lenp = SQL_NULL_DATA;
13813  goto done;
13814  }
13815  type = mapdeftype(type, s->cols[col].type, s->cols[col].nosign ? 1 : 0,
13816  s->nowchar[0]);
13817 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
13818  /* MS Access hack part 3 (map SQL_C_DEFAULT to SQL_C_CHAR) */
13819  if (type == SQL_C_WCHAR && otype == SQL_C_DEFAULT) {
13820  type = SQL_C_CHAR;
13821  }
13822 #endif
13823  data = s->rows + s->ncols + (s->rowp * s->ncols) + col;
13824  if (!val) {
13825  valnull = 1;
13826  val = (SQLPOINTER) valdummy;
13827  }
13828  if (*data == NULL) {
13829  *lenp = SQL_NULL_DATA;
13830  switch (type) {
13831  case SQL_C_UTINYINT:
13832  case SQL_C_TINYINT:
13833  case SQL_C_STINYINT:
13834 #ifdef SQL_BIT
13835  case SQL_C_BIT:
13836 #endif
13837  *((SQLCHAR *) val) = 0;
13838  break;
13839  case SQL_C_USHORT:
13840  case SQL_C_SHORT:
13841  case SQL_C_SSHORT:
13842  *((SQLSMALLINT *) val) = 0;
13843  break;
13844  case SQL_C_ULONG:
13845  case SQL_C_LONG:
13846  case SQL_C_SLONG:
13847  *((SQLINTEGER *) val) = 0;
13848  break;
13849 #ifdef SQL_BIGINT
13850  case SQL_C_SBIGINT:
13851  case SQL_C_UBIGINT:
13852  *((SQLBIGINT *) val) = 0;
13853  break;
13854 #endif
13855  case SQL_C_FLOAT:
13856  *((float *) val) = 0;
13857  break;
13858  case SQL_C_DOUBLE:
13859  *((double *) val) = 0;
13860  break;
13861  case SQL_C_BINARY:
13862  case SQL_C_CHAR:
13863  if (len > 0) {
13864  *((SQLCHAR *) val) = '\0';
13865  }
13866  break;
13867 #ifdef WCHARSUPPORT
13868  case SQL_C_WCHAR:
13869  if (len > 0) {
13870  *((SQLWCHAR *) val) = '\0';
13871  }
13872  break;
13873 #endif
13874 #ifdef SQL_C_TYPE_DATE
13875  case SQL_C_TYPE_DATE:
13876 #endif
13877  case SQL_C_DATE:
13878  memset((DATE_STRUCT *) val, 0, sizeof (DATE_STRUCT));
13879  break;
13880 #ifdef SQL_C_TYPE_TIME
13881  case SQL_C_TYPE_TIME:
13882 #endif
13883  case SQL_C_TIME:
13884  memset((TIME_STRUCT *) val, 0, sizeof (TIME_STRUCT));
13885  break;
13886 #ifdef SQL_C_TYPE_TIMESTAMP
13887  case SQL_C_TYPE_TIMESTAMP:
13888 #endif
13889  case SQL_C_TIMESTAMP:
13890  memset((TIMESTAMP_STRUCT *) val, 0, sizeof (TIMESTAMP_STRUCT));
13891  break;
13892  default:
13893  return SQL_ERROR;
13894  }
13895  } else {
13896  char *endp = NULL;
13897 #if defined(_WIN32) || defined(_WIN64)
13898 #ifdef SQL_BIGINT
13899  char endc;
13900 #endif
13901 #endif
13902 
13903  switch (type) {
13904  case SQL_C_UTINYINT:
13905  case SQL_C_TINYINT:
13906  case SQL_C_STINYINT:
13907  *((SQLCHAR *) val) = strtol(*data, &endp, 0);
13908  if (endp && endp == *data) {
13909  *lenp = SQL_NULL_DATA;
13910  } else {
13911  *lenp = sizeof (SQLCHAR);
13912  }
13913  break;
13914 #ifdef SQL_BIT
13915  case SQL_C_BIT:
13916  *((SQLCHAR *) val) = getbool(*data);
13917  *lenp = sizeof (SQLCHAR);
13918  break;
13919 #endif
13920  case SQL_C_USHORT:
13921  case SQL_C_SHORT:
13922  case SQL_C_SSHORT:
13923  *((SQLSMALLINT *) val) = strtol(*data, &endp, 0);
13924  if (endp && endp == *data) {
13925  *lenp = SQL_NULL_DATA;
13926  } else {
13927  *lenp = sizeof (SQLSMALLINT);
13928  }
13929  break;
13930  case SQL_C_ULONG:
13931  case SQL_C_LONG:
13932  case SQL_C_SLONG:
13933  *((SQLINTEGER *) val) = strtol(*data, &endp, 0);
13934  if (endp && endp == *data) {
13935  *lenp = SQL_NULL_DATA;
13936  } else {
13937  *lenp = sizeof (SQLINTEGER);
13938  }
13939  break;
13940 #ifdef SQL_BIGINT
13941  case SQL_C_UBIGINT:
13942 #if defined(_WIN32) || defined(_WIN64)
13943  if (sscanf(*data, "%I64u%c", (SQLUBIGINT *) val, &endc) != 1) {
13944  *lenp = SQL_NULL_DATA;
13945  } else {
13946  *lenp = sizeof (SQLUBIGINT);
13947  }
13948 #else
13949 #ifdef __osf__
13950  *((SQLUBIGINT *) val) = strtoul(*data, &endp, 0);
13951 #else
13952  *((SQLUBIGINT *) val) = strtoull(*data, &endp, 0);
13953 #endif
13954  if (endp && endp == *data) {
13955  *lenp = SQL_NULL_DATA;
13956  } else {
13957  *lenp = sizeof (SQLUBIGINT);
13958  }
13959 #endif
13960  break;
13961  case SQL_C_SBIGINT:
13962 #if defined(_WIN32) || defined(_WIN64)
13963  if (sscanf(*data, "%I64d%c", (SQLBIGINT *) val, &endc) != 1) {
13964  *lenp = SQL_NULL_DATA;
13965  } else {
13966  *lenp = sizeof (SQLBIGINT);
13967  }
13968 #else
13969 #ifdef __osf__
13970  *((SQLBIGINT *) val) = strtol(*data, &endp, 0);
13971 #else
13972  *((SQLBIGINT *) val) = strtoll(*data, &endp, 0);
13973 #endif
13974  if (endp && endp == *data) {
13975  *lenp = SQL_NULL_DATA;
13976  } else {
13977  *lenp = sizeof (SQLBIGINT);
13978  }
13979 #endif
13980  break;
13981 #endif
13982  case SQL_C_FLOAT:
13983  *((float *) val) = ln_strtod(*data, &endp);
13984  if (endp && endp == *data) {
13985  *lenp = SQL_NULL_DATA;
13986  } else {
13987  *lenp = sizeof (float);
13988  }
13989  break;
13990  case SQL_C_DOUBLE:
13991  *((double *) val) = ln_strtod(*data, &endp);
13992  if (endp && endp == *data) {
13993  *lenp = SQL_NULL_DATA;
13994  } else {
13995  *lenp = sizeof (double);
13996  }
13997  break;
13998  case SQL_C_BINARY: {
13999  int dlen, offs = 0;
14000  char *bin;
14001 
14002  if (valnull) {
14003  freep(&s->bincache);
14004  s->binlen = 0;
14005  goto doCHAR;
14006  }
14007  if (*data == s->bincell) {
14008  if (s->bincache) {
14009  bin = s->bincache;
14010  dlen = s->binlen;
14011  } else {
14012  goto doCHAR;
14013  }
14014  } else {
14015  char *dp;
14016  int i;
14017 
14018  freep(&s->bincache);
14019  dp = *data;
14020  dlen = strlen(dp);
14021  s->bincell = dp;
14022  s->binlen = 0;
14023  if (!(dp[0] == 'x' || dp[0] == 'X') || dp[1] != '\'' ||
14024  dp[dlen - 1] != '\'') {
14025  goto doCHAR;
14026  }
14027  dlen -= 2;
14028  dp += 2;
14029  dlen = dlen / 2;
14030  s->bincache = bin = xmalloc(dlen + 1);
14031  if (!bin) {
14032  return nomem(s);
14033  }
14034  s->binlen = dlen;
14035  memset(bin, 0, dlen);
14036  bin[dlen] = '\0'; /* terminator, just in case */
14037  for (i = 0; i < dlen; i++) {
14038  char *x;
14039  int v;
14040 
14041  if (!*dp || !(x = strchr(xdigits, *dp))) {
14042  goto converr;
14043  }
14044  v = x - xdigits;
14045  bin[i] = (v >= 16) ? ((v - 6) << 4) : (v << 4);
14046  ++dp;
14047  if (!*dp || !(x = strchr(xdigits, *dp))) {
14048 converr:
14049  freep(&s->bincache);
14050  s->binlen = 0;
14051  setstat(s, -1, "conversion error",
14052  (*s->ov3) ? "HY000" : "S1000");
14053  return SQL_ERROR;
14054  }
14055  v = x - xdigits;
14056  bin[i] |= (v >= 16) ? (v - 6) : v;
14057  ++dp;
14058  }
14059  bin = s->bincache;
14060  }
14061  if (partial && len && s->bindcols) {
14062  if (s->bindcols[col].offs >= dlen) {
14063  *lenp = 0;
14064  if (!dlen && s->bindcols[col].offs == dlen) {
14065  s->bindcols[col].offs = 1;
14066  sret = SQL_SUCCESS;
14067  goto done;
14068  }
14069  s->bindcols[col].offs = 0;
14070  sret = SQL_NO_DATA;
14071  goto done;
14072  }
14073  offs = s->bindcols[col].offs;
14074  dlen -= offs;
14075  }
14076  if (val && len) {
14077  memcpy(val, bin + offs, min(len, dlen));
14078  }
14079  if (len < 1) {
14080  *lenp = dlen;
14081  } else {
14082  *lenp = min(len, dlen);
14083  if (*lenp == len && *lenp != dlen) {
14084  *lenp = SQL_NO_TOTAL;
14085  }
14086  }
14087  if (partial && len && s->bindcols) {
14088  if (*lenp == SQL_NO_TOTAL) {
14089  *lenp = dlen;
14090  s->bindcols[col].offs += len;
14091  setstat(s, -1, "data right truncated", "01004");
14092  if (s->bindcols[col].lenp) {
14093  *s->bindcols[col].lenp = dlen;
14094  }
14095  sret = SQL_SUCCESS_WITH_INFO;
14096  goto done;
14097  }
14098  s->bindcols[col].offs += *lenp;
14099  }
14100  if (*lenp == SQL_NO_TOTAL) {
14101  *lenp = dlen;
14102  setstat(s, -1, "data right truncated", "01004");
14103  sret = SQL_SUCCESS_WITH_INFO;
14104  goto done;
14105  }
14106  break;
14107  }
14108  doCHAR:
14109 #ifdef WCHARSUPPORT
14110  case SQL_C_WCHAR:
14111 #endif
14112  case SQL_C_CHAR: {
14113  int doz, zlen = len - 1;
14114  int dlen = strlen(*data);
14115  int offs = 0;
14116 #ifdef WCHARSUPPORT
14117  SQLWCHAR *ucdata = NULL;
14118  SQLCHAR *cdata = (SQLCHAR *) *data;
14119 #endif
14120 
14121 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
14122  /* MS Access hack part 2 (reserved error -7748) */
14123  if (!valnull &&
14124  (s->cols == statSpec2P || s->cols == statSpec3P) &&
14125  type == SQL_C_WCHAR) {
14126  if (len > 0 && len <= sizeof (SQLWCHAR)) {
14127  ((char *) val)[0] = data[0][0];
14128  memset((char *) val + 1, 0, len - 1);
14129  *lenp = 1;
14130  sret = SQL_SUCCESS;
14131  goto done;
14132  }
14133  }
14134 #endif
14135 
14136 #ifdef WCHARSUPPORT
14137  switch (type) {
14138  case SQL_C_CHAR:
14139  doz = 1;
14140  break;
14141  case SQL_C_WCHAR:
14142  doz = sizeof (SQLWCHAR);
14143  break;
14144  default:
14145  doz = 0;
14146  break;
14147  }
14148  if (type == SQL_C_WCHAR) {
14149  ucdata = uc_from_utf(cdata, dlen);
14150  if (!ucdata) {
14151  return nomem(s);
14152  }
14153  dlen = uc_strlen(ucdata) * sizeof (SQLWCHAR);
14154  }
14155 #if defined(_WIN32) || defined(_WIN64)
14156  else if (*s->oemcp && type == SQL_C_CHAR) {
14157  ucdata = (SQLWCHAR *) utf_to_wmb((char *) cdata, dlen);
14158  if (!ucdata) {
14159  return nomem(s);
14160  }
14161  cdata = (SQLCHAR *) ucdata;
14162  dlen = strlen((char *) cdata);
14163  }
14164 #endif
14165 #else
14166  doz = (type == SQL_C_CHAR) ? 1 : 0;
14167 #endif
14168  if (partial && len && s->bindcols) {
14169  if (s->bindcols[col].offs >= dlen) {
14170 #ifdef WCHARSUPPORT
14171  uc_free(ucdata);
14172 #endif
14173  *lenp = 0;
14174  if (doz && val) {
14175 #ifdef WCHARSUPPORT
14176  if (type == SQL_C_WCHAR) {
14177  ((SQLWCHAR *) val)[0] = 0;
14178  } else {
14179  ((char *) val)[0] = '\0';
14180  }
14181 #else
14182  ((char *) val)[0] = '\0';
14183 #endif
14184  }
14185  if (!dlen && s->bindcols[col].offs == dlen) {
14186  s->bindcols[col].offs = 1;
14187  sret = SQL_SUCCESS;
14188  goto done;
14189  }
14190  s->bindcols[col].offs = 0;
14191  sret = SQL_NO_DATA;
14192  goto done;
14193  }
14194  offs = s->bindcols[col].offs;
14195  dlen -= offs;
14196  }
14197  if (val && !valnull && len) {
14198 #ifdef WCHARSUPPORT
14199  if (type == SQL_C_WCHAR) {
14200  uc_strncpy(val, ucdata + offs / sizeof (SQLWCHAR),
14201  (len - doz) / sizeof (SQLWCHAR));
14202  } else {
14203  strncpy(val, (char *) cdata + offs, len - doz);
14204  }
14205 #else
14206  strncpy(val, *data + offs, len - doz);
14207 #endif
14208  }
14209  if (valnull || len < 1) {
14210  *lenp = dlen;
14211  } else {
14212  *lenp = min(len - doz, dlen);
14213  if (*lenp == len - doz && *lenp != dlen) {
14214  *lenp = SQL_NO_TOTAL;
14215  } else if (*lenp < zlen) {
14216  zlen = *lenp;
14217  }
14218  }
14219  if (len && !valnull && doz) {
14220 #ifdef WCHARSUPPORT
14221  if (type == SQL_C_WCHAR) {
14222  ((SQLWCHAR *) val)[zlen / sizeof (SQLWCHAR)] = 0;
14223  } else {
14224  ((char *) val)[zlen] = '\0';
14225  }
14226 #else
14227  ((char *) val)[zlen] = '\0';
14228 #endif
14229  }
14230 #ifdef WCHARSUPPORT
14231  uc_free(ucdata);
14232 #endif
14233  if (partial && len && s->bindcols) {
14234  if (*lenp == SQL_NO_TOTAL) {
14235  *lenp = dlen;
14236  s->bindcols[col].offs += len - doz;
14237  setstat(s, -1, "data right truncated", "01004");
14238  if (s->bindcols[col].lenp) {
14239  *s->bindcols[col].lenp = dlen;
14240  }
14241  sret = SQL_SUCCESS_WITH_INFO;
14242  goto done;
14243  }
14244  s->bindcols[col].offs += *lenp;
14245  }
14246  if (*lenp == SQL_NO_TOTAL) {
14247  *lenp = dlen;
14248  setstat(s, -1, "data right truncated", "01004");
14249  sret = SQL_SUCCESS_WITH_INFO;
14250  goto done;
14251  }
14252  break;
14253  }
14254 #ifdef SQL_C_TYPE_DATE
14255  case SQL_C_TYPE_DATE:
14256 #endif
14257  case SQL_C_DATE:
14258  if (str2date(*s->jdconv, *data, (DATE_STRUCT *) val) < 0) {
14259  *lenp = SQL_NULL_DATA;
14260  } else {
14261  *lenp = sizeof (DATE_STRUCT);
14262  }
14263  break;
14264 #ifdef SQL_C_TYPE_TIME
14265  case SQL_C_TYPE_TIME:
14266 #endif
14267  case SQL_C_TIME:
14268  if (str2time(*s->jdconv, *data, (TIME_STRUCT *) val) < 0) {
14269  *lenp = SQL_NULL_DATA;
14270  } else {
14271  *lenp = sizeof (TIME_STRUCT);
14272  }
14273  break;
14274 #ifdef SQL_C_TYPE_TIMESTAMP
14275  case SQL_C_TYPE_TIMESTAMP:
14276 #endif
14277  case SQL_C_TIMESTAMP:
14278  if (str2timestamp(*s->jdconv, *data,
14279  (TIMESTAMP_STRUCT *) val) < 0) {
14280  *lenp = SQL_NULL_DATA;
14281  } else {
14282  *lenp = sizeof (TIMESTAMP_STRUCT);
14283  }
14284  switch (s->cols[col].prec) {
14285  case 0:
14286  ((TIMESTAMP_STRUCT *) val)->fraction = 0;
14287  break;
14288  case 1:
14289  ((TIMESTAMP_STRUCT *) val)->fraction /= 100000000;
14290  ((TIMESTAMP_STRUCT *) val)->fraction *= 100000000;
14291  break;
14292  case 2:
14293  ((TIMESTAMP_STRUCT *) val)->fraction /= 10000000;
14294  ((TIMESTAMP_STRUCT *) val)->fraction *= 10000000;
14295  break;
14296  }
14297  break;
14298  default:
14299  return SQL_ERROR;
14300  }
14301  }
14302  sret = SQL_SUCCESS;
14303 done:
14304  if (ilenp) {
14305  *ilenp = *lenp;
14306  }
14307  return sret;
14308 }
14309 
14321 static SQLRETURN
14322 drvbindcol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14323  SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14324 {
14325  STMT *s;
14326  int sz = 0;
14327 
14328  if (stmt == SQL_NULL_HSTMT) {
14329  return SQL_INVALID_HANDLE;
14330  }
14331  s = (STMT *) stmt;
14332  if (col < 1) {
14333  if (col == 0 && s->bkmrk == SQL_UB_ON &&
14334  type == SQL_C_BOOKMARK) {
14335  s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14336  s->bkmrkcol.max = val ? sizeof (SQLINTEGER) : 0;
14337  s->bkmrkcol.lenp = val ? lenp : 0;
14338  s->bkmrkcol.valp = val;
14339  s->bkmrkcol.offs = 0;
14340  if (val && lenp) {
14341  *lenp = 0;
14342  }
14343  return SQL_SUCCESS;
14344  } else if (col == 0 && s->bkmrk == SQL_UB_VARIABLE &&
14345  type == SQL_C_VARBOOKMARK &&
14346  max >= sizeof (sqlite_int64)) {
14347  s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14348  s->bkmrkcol.max = val ? max : 0;
14349  s->bkmrkcol.lenp = val ? lenp : 0;
14350  s->bkmrkcol.valp = val;
14351  s->bkmrkcol.offs = 0;
14352  if (val && lenp) {
14353  *lenp = 0;
14354  }
14355  return SQL_SUCCESS;
14356  }
14357  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
14358  return SQL_ERROR;
14359  }
14360  if (mkbindcols(s, col) != SQL_SUCCESS) {
14361  return SQL_ERROR;
14362  }
14363  --col;
14364  if (type == SQL_C_DEFAULT) {
14365  type = mapdeftype(type, s->cols[col].type, 0,
14366  s->nowchar[0] || s->nowchar[1]);
14367  }
14368  switch (type) {
14369  case SQL_C_LONG:
14370  case SQL_C_ULONG:
14371  case SQL_C_SLONG:
14372  sz = sizeof (SQLINTEGER);
14373  break;
14374  case SQL_C_TINYINT:
14375  case SQL_C_UTINYINT:
14376  case SQL_C_STINYINT:
14377  sz = sizeof (SQLCHAR);
14378  break;
14379  case SQL_C_SHORT:
14380  case SQL_C_USHORT:
14381  case SQL_C_SSHORT:
14382  sz = sizeof (SQLSMALLINT);
14383  break;
14384  case SQL_C_FLOAT:
14385  sz = sizeof (SQLFLOAT);
14386  break;
14387  case SQL_C_DOUBLE:
14388  sz = sizeof (SQLDOUBLE);
14389  break;
14390  case SQL_C_TIMESTAMP:
14391  sz = sizeof (SQL_TIMESTAMP_STRUCT);
14392  break;
14393  case SQL_C_TIME:
14394  sz = sizeof (SQL_TIME_STRUCT);
14395  break;
14396  case SQL_C_DATE:
14397  sz = sizeof (SQL_DATE_STRUCT);
14398  break;
14399  case SQL_C_CHAR:
14400  break;
14401 #ifdef WCHARSUPPORT
14402  case SQL_C_WCHAR:
14403  break;
14404 #endif
14405 #ifdef SQL_C_TYPE_DATE
14406  case SQL_C_TYPE_DATE:
14407  sz = sizeof (SQL_DATE_STRUCT);
14408  break;
14409 #endif
14410 #ifdef SQL_C_TYPE_TIME
14411  case SQL_C_TYPE_TIME:
14412  sz = sizeof (SQL_TIME_STRUCT);
14413  break;
14414 #endif
14415 #ifdef SQL_C_TYPE_TIMESTAMP
14416  case SQL_C_TYPE_TIMESTAMP:
14417  sz = sizeof (SQL_TIMESTAMP_STRUCT);
14418  break;
14419 #endif
14420 #ifdef SQL_BIT
14421  case SQL_C_BIT:
14422  sz = sizeof (SQLCHAR);
14423  break;
14424 #endif
14425  case SQL_C_BINARY:
14426  break;
14427 #ifdef SQL_BIGINT
14428  case SQL_C_SBIGINT:
14429  case SQL_C_UBIGINT:
14430  sz = sizeof (SQLBIGINT);
14431  break;
14432 #endif
14433  default:
14434  if (val == NULL) {
14435  /* fall through, unbinding column */
14436  break;
14437  }
14438  setstat(s, -1, "invalid type %d", "HY003", type);
14439  return SQL_ERROR;
14440  }
14441  if (val == NULL) {
14442  /* unbind column */
14443  s->bindcols[col].type = SQL_UNKNOWN_TYPE;
14444  s->bindcols[col].max = 0;
14445  s->bindcols[col].lenp = NULL;
14446  s->bindcols[col].valp = NULL;
14447  s->bindcols[col].offs = 0;
14448  } else {
14449  if (sz == 0 && max < 0) {
14450  setstat(s, -1, "invalid length", "HY090");
14451  return SQL_ERROR;
14452  }
14453  s->bindcols[col].type = type;
14454  s->bindcols[col].max = (sz == 0) ? max : sz;
14455  s->bindcols[col].lenp = lenp;
14456  s->bindcols[col].valp = val;
14457  s->bindcols[col].offs = 0;
14458  if (lenp) {
14459  *lenp = 0;
14460  }
14461  }
14462  return SQL_SUCCESS;
14463 }
14464 
14476 SQLRETURN SQL_API
14477 SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14478  SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14479 {
14480  SQLRETURN ret;
14481 
14482  HSTMT_LOCK(stmt);
14483  ret = drvbindcol(stmt, col, type, val, max, lenp);
14484  HSTMT_UNLOCK(stmt);
14485  return ret;
14486 }
14487 
14492 static COL tableSpec2[] = {
14493  { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
14494  { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
14495  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14496  { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14497  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14498 };
14499 
14500 static COL tableSpec3[] = {
14501  { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
14502  { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
14503  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14504  { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14505  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14506 };
14507 
14522 static SQLRETURN
14523 drvtables(SQLHSTMT stmt,
14524  SQLCHAR *cat, SQLSMALLINT catLen,
14525  SQLCHAR *schema, SQLSMALLINT schemaLen,
14526  SQLCHAR *table, SQLSMALLINT tableLen,
14527  SQLCHAR *type, SQLSMALLINT typeLen)
14528 {
14529  SQLRETURN ret;
14530  STMT *s;
14531  DBC *d;
14532  int ncols, asize, rc, size, npatt;
14533  char *errp = NULL, *sql, tname[512];
14534  char *where = "(type = 'table' or type = 'view')";
14535 
14537  tableSpec3, array_size(tableSpec3), &asize);
14538  if (ret != SQL_SUCCESS) {
14539  return ret;
14540  }
14541  s = (STMT *) stmt;
14542  d = (DBC *) s->dbc;
14543  if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] == '%') {
14544  int size = 3 * asize;
14545 
14546  s->rows = xmalloc(size * sizeof (char *));
14547  if (!s->rows) {
14548  s->nrows = 0;
14549  return nomem(s);
14550  }
14551  memset(s->rows, 0, sizeof (char *) * size);
14552  s->ncols = asize;
14553  s->rows[s->ncols + 0] = "";
14554  s->rows[s->ncols + 1] = "";
14555  s->rows[s->ncols + 2] = "";
14556  s->rows[s->ncols + 3] = "TABLE";
14557  s->rows[s->ncols + 5] = "";
14558  s->rows[s->ncols + 6] = "";
14559  s->rows[s->ncols + 7] = "";
14560  s->rows[s->ncols + 8] = "VIEW";
14561 #ifdef MEMORY_DEBUG
14562  s->rowfree = xfree__;
14563 #else
14564  s->rowfree = sqlite3_free;
14565 #endif
14566  s->nrows = 2;
14567  s->rowp = s->rowprs = -1;
14568  return SQL_SUCCESS;
14569  }
14570  if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
14571  table = NULL;
14572  goto doit;
14573  }
14574  if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
14575  schema[0] == '%') {
14576  if ((!cat || catLen == 0 || !cat[0]) &&
14577  (!table || tableLen == 0 || !table[0])) {
14578  table = NULL;
14579  goto doit;
14580  }
14581  }
14582  if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] != '\0') {
14583  char tmp[256], *t;
14584  int with_view = 0, with_table = 0;
14585 
14586  if (typeLen == SQL_NTS) {
14587  strncpy(tmp, (char *) type, sizeof (tmp));
14588  tmp[sizeof (tmp) - 1] = '\0';
14589  } else {
14590  int len = min(sizeof (tmp) - 1, typeLen);
14591 
14592  strncpy(tmp, (char *) type, len);
14593  tmp[len] = '\0';
14594  }
14595  t = tmp;
14596  while (*t) {
14597  *t = TOLOWER(*t);
14598  t++;
14599  }
14600  t = tmp;
14601  unescpat(t);
14602  while (t) {
14603  if (t[0] == '\'') {
14604  ++t;
14605  }
14606  if (strncmp(t, "table", 5) == 0) {
14607  with_table++;
14608  } else if (strncmp(t, "view", 4) == 0) {
14609  with_view++;
14610  }
14611  t = strchr(t, ',');
14612  if (t) {
14613  ++t;
14614  }
14615  }
14616  if (with_view && with_table) {
14617  /* where is already preset */
14618  } else if (with_view && !with_table) {
14619  where = "type = 'view'";
14620  } else if (!with_view && with_table) {
14621  where = "type = 'table'";
14622  } else {
14623  return SQL_SUCCESS;
14624  }
14625  }
14626 doit:
14627  if (!table) {
14628  size = 1;
14629  tname[0] = '%';
14630  } else {
14631  if (tableLen == SQL_NTS) {
14632  size = sizeof (tname) - 1;
14633  } else {
14634  size = min(sizeof (tname) - 1, tableLen);
14635  }
14636  strncpy(tname, (char *) table, size);
14637  }
14638  tname[size] = '\0';
14639  npatt = unescpat(tname);
14640 #if defined(_WIN32) || defined(_WIN64)
14641  sql = sqlite3_mprintf("select %s as 'TABLE_CAT', "
14642  "%s as 'TABLE_SCHEM', "
14643  "tbl_name as 'TABLE_NAME', "
14644  "upper(type) as 'TABLE_TYPE', "
14645  "NULL as 'REMARKS' "
14646  "from sqlite_master where %s "
14647  "and tbl_name %s %Q",
14648  d->xcelqrx ? "'main'" : "NULL",
14649  d->xcelqrx ? "''" : "NULL",
14650  where,
14651  npatt ? "like" : "=", tname);
14652 #else
14653  sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
14654  "NULL as 'TABLE_OWNER', "
14655  "tbl_name as 'TABLE_NAME', "
14656  "upper(type) as 'TABLE_TYPE', "
14657  "NULL as 'REMARKS' "
14658  "from sqlite_master where %s "
14659  "and tbl_name %s %Q", where,
14660  npatt ? "like" : "=", tname);
14661 #endif
14662  if (!sql) {
14663  return nomem(s);
14664  }
14665  ret = starttran(s);
14666  if (ret != SQL_SUCCESS) {
14667  sqlite3_free(sql);
14668  return ret;
14669  }
14670  dbtraceapi(d, "sqlite3_get_table", sql);
14671  rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
14672  sqlite3_free(sql);
14673  if (rc == SQLITE_OK) {
14674  if (ncols != s->ncols) {
14675  freeresult(s, 0);
14676  s->nrows = 0;
14677  } else {
14678  s->rowfree = sqlite3_free_table;
14679  }
14680  } else {
14681  s->nrows = 0;
14682  s->rows = NULL;
14683  s->rowfree = NULL;
14684  }
14685  if (errp) {
14686  sqlite3_free(errp);
14687  errp = NULL;
14688  }
14689  s->rowp = s->rowprs = -1;
14690  return SQL_SUCCESS;
14691 }
14692 
14693 #ifndef WINTERFACE
14694 
14708 SQLRETURN SQL_API
14709 SQLTables(SQLHSTMT stmt,
14710  SQLCHAR *cat, SQLSMALLINT catLen,
14711  SQLCHAR *schema, SQLSMALLINT schemaLen,
14712  SQLCHAR *table, SQLSMALLINT tableLen,
14713  SQLCHAR *type, SQLSMALLINT typeLen)
14714 {
14715 #if defined(_WIN32) || defined(_WIN64)
14716  char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
14717 #endif
14718  SQLRETURN ret;
14719 
14720  HSTMT_LOCK(stmt);
14721 #if defined(_WIN32) || defined(_WIN64)
14722  if (!((STMT *) stmt)->oemcp[0]) {
14723  ret = drvtables(stmt, cat, catLen, schema, schemaLen,
14724  table, tableLen, type, typeLen);
14725  goto done2;
14726  }
14727  if (cat) {
14728  c = wmb_to_utf_c((char *) cat, catLen);
14729  if (!c) {
14730  ret = nomem((STMT *) stmt);
14731  goto done;
14732  }
14733  }
14734  if (schema) {
14735  s = wmb_to_utf_c((char *) schema, schemaLen);
14736  if (!s) {
14737  ret = nomem((STMT *) stmt);
14738  goto done;
14739  }
14740  }
14741  if (table) {
14742  t = wmb_to_utf_c((char *) table, tableLen);
14743  if (!t) {
14744  ret = nomem((STMT *) stmt);
14745  goto done;
14746  }
14747  }
14748  if (type) {
14749  y = wmb_to_utf_c((char *) type, typeLen);
14750  if (!y) {
14751  ret = nomem((STMT *) stmt);
14752  goto done;
14753  }
14754  }
14755  ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
14756  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
14757 #else
14758  ret = drvtables(stmt, cat, catLen, schema, schemaLen,
14759  table, tableLen, type, typeLen);
14760 #endif
14761 #if defined(_WIN32) || defined(_WIN64)
14762 done:
14763  uc_free(y);
14764  uc_free(t);
14765  uc_free(s);
14766  uc_free(c);
14767 done2:
14768  ;
14769 #endif
14770  HSTMT_UNLOCK(stmt);
14771  return ret;
14772 }
14773 #endif
14774 
14775 #ifdef WINTERFACE
14776 
14790 SQLRETURN SQL_API
14791 SQLTablesW(SQLHSTMT stmt,
14792  SQLWCHAR *cat, SQLSMALLINT catLen,
14793  SQLWCHAR *schema, SQLSMALLINT schemaLen,
14794  SQLWCHAR *table, SQLSMALLINT tableLen,
14795  SQLWCHAR *type, SQLSMALLINT typeLen)
14796 {
14797  char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
14798  SQLRETURN ret;
14799 
14800  HSTMT_LOCK(stmt);
14801  if (cat) {
14802  c = uc_to_utf_c(cat, catLen);
14803  if (!c) {
14804  ret = nomem((STMT *) stmt);
14805  goto done;
14806  }
14807  }
14808  if (schema) {
14809  s = uc_to_utf_c(schema, schemaLen);
14810  if (!s) {
14811  ret = nomem((STMT *) stmt);
14812  goto done;
14813  }
14814  }
14815  if (table) {
14816  t = uc_to_utf_c(table, tableLen);
14817  if (!t) {
14818  ret = nomem((STMT *) stmt);
14819  goto done;
14820  }
14821  }
14822  if (type) {
14823  y = uc_to_utf_c(type, typeLen);
14824  if (!y) {
14825  ret = nomem((STMT *) stmt);
14826  goto done;
14827  }
14828  }
14829  ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
14830  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
14831 done:
14832  uc_free(y);
14833  uc_free(t);
14834  uc_free(s);
14835  uc_free(c);
14836  HSTMT_UNLOCK(stmt);
14837  return ret;
14838 }
14839 #endif
14840 
14845 static COL colSpec2[] = {
14846  { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
14847  { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
14848  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14849  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
14850  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
14851  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
14852  { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
14853  { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
14854  { "SYSTEM", "COLUMN", "SCALE", SQL_SMALLINT, 50 },
14855  { "SYSTEM", "COLUMN", "RADIX", SQL_SMALLINT, 50 },
14856  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
14857  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
14858  { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
14859  { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
14860  { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
14861  { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
14862  { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
14863  { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
14864 };
14865 
14866 static COL colSpec3[] = {
14867  { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
14868  { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
14869  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14870  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
14871  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
14872  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
14873  { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
14874  { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
14875  { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_SMALLINT, 50 },
14876  { "SYSTEM", "COLUMN", "NUM_PREC_RADIX", SQL_SMALLINT, 50 },
14877  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
14878  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
14879  { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
14880  { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
14881  { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
14882  { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
14883  { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
14884  { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
14885 };
14886 
14901 static SQLRETURN
14902 drvcolumns(SQLHSTMT stmt,
14903  SQLCHAR *cat, SQLSMALLINT catLen,
14904  SQLCHAR *schema, SQLSMALLINT schemaLen,
14905  SQLCHAR *table, SQLSMALLINT tableLen,
14906  SQLCHAR *col, SQLSMALLINT colLen)
14907 {
14908  SQLRETURN sret;
14909  STMT *s;
14910  DBC *d;
14911  int ret, nrows, ncols, asize, i, k, roffs, namec;
14912  int tnrows, tncols, npatt;
14913  PTRDIFF_T size;
14914  char *errp = NULL, *sql, tname[512], cname[512], **rowp, **trows;
14915 
14917  colSpec3, array_size(colSpec3), &asize);
14918  if (sret != SQL_SUCCESS) {
14919  return sret;
14920  }
14921  s = (STMT *) stmt;
14922  d = (DBC *) s->dbc;
14923  if (!table) {
14924  size = 1;
14925  tname[0] = '%';
14926  } else {
14927  if (tableLen == SQL_NTS) {
14928  size = sizeof (tname) - 1;
14929  } else {
14930  size = min(sizeof (tname) - 1, tableLen);
14931  }
14932  strncpy(tname, (char *) table, size);
14933  }
14934  tname[size] = '\0';
14935  npatt = unescpat(tname);
14936  size = 0;
14937  if (col) {
14938  if (colLen == SQL_NTS) {
14939  size = sizeof (cname) - 1;
14940  } else {
14941  size = min(sizeof (cname) - 1, colLen);
14942  }
14943  strncpy(cname, (char *) col, size);
14944  }
14945  cname[size] = '\0';
14946  if (!strcmp(cname, "%")) {
14947  cname[0] = '\0';
14948  }
14949  sql = sqlite3_mprintf("select tbl_name from sqlite_master where "
14950  "(type = 'table' or type = 'view') "
14951  "and tbl_name %s %Q", npatt ? "like" : "=", tname);
14952  if (!sql) {
14953  return nomem(s);
14954  }
14955  sret = starttran(s);
14956  if (sret != SQL_SUCCESS) {
14957  sqlite3_free(sql);
14958  return sret;
14959  }
14960  dbtraceapi(d, "sqlite3_get_table", sql);
14961  ret = sqlite3_get_table(d->sqlite, sql, &trows, &tnrows, &tncols, &errp);
14962  sqlite3_free(sql);
14963  if (ret != SQLITE_OK) {
14964  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
14965  errp ? errp : "unknown error", ret);
14966  if (errp) {
14967  sqlite3_free(errp);
14968  errp = NULL;
14969  }
14970  return SQL_ERROR;
14971  }
14972  if (errp) {
14973  sqlite3_free(errp);
14974  errp = NULL;
14975  }
14976  /* pass 1: compute number of rows of result set */
14977  if (tncols * tnrows <= 0) {
14978  sqlite3_free_table(trows);
14979  return SQL_SUCCESS;
14980  }
14981  size = 0;
14982  for (i = 1; i <= tnrows; i++) {
14983  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
14984  if (!sql) {
14985  sqlite3_free_table(trows);
14986  return nomem(s);
14987  }
14988  dbtraceapi(d, "sqlite3_get_table", sql);
14989  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
14990  sqlite3_free(sql);
14991  if (ret != SQLITE_OK) {
14992  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
14993  errp ? errp : "unknown error", ret);
14994  if (errp) {
14995  sqlite3_free(errp);
14996  errp = NULL;
14997  }
14998  sqlite3_free_table(trows);
14999  return SQL_ERROR;
15000  }
15001  if (errp) {
15002  sqlite3_free(errp);
15003  errp = NULL;
15004  }
15005  if (ncols * nrows > 0) {
15006  namec = -1;
15007  for (k = 0; k < ncols; k++) {
15008  if (strcmp(rowp[k], "name") == 0) {
15009  namec = k;
15010  break;
15011  }
15012  }
15013  if (cname[0]) {
15014  if (namec >= 0) {
15015  for (k = 1; k <= nrows; k++) {
15016  if (namematch(rowp[k * ncols + namec], cname, 1)) {
15017  size++;
15018  }
15019  }
15020  }
15021  } else {
15022  size += nrows;
15023  }
15024  }
15025  sqlite3_free_table(rowp);
15026  }
15027  /* pass 2: fill result set */
15028  if (size <= 0) {
15029  sqlite3_free_table(trows);
15030  return SQL_SUCCESS;
15031  }
15032  s->nrows = size;
15033  size = (size + 1) * asize;
15034  s->rows = xmalloc((size + 1) * sizeof (char *));
15035  if (!s->rows) {
15036  s->nrows = 0;
15037  sqlite3_free_table(trows);
15038  return nomem(s);
15039  }
15040  s->rows[0] = (char *) size;
15041  s->rows += 1;
15042  memset(s->rows, 0, sizeof (char *) * size);
15043  s->rowfree = freerows;
15044  roffs = 1;
15045  for (i = 1; i <= tnrows; i++) {
15046  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
15047  if (!sql) {
15048  sqlite3_free_table(trows);
15049  return nomem(s);
15050  }
15051  dbtraceapi(d, "sqlite3_get_table", sql);
15052  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15053  sqlite3_free(sql);
15054  if (ret != SQLITE_OK) {
15055  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15056  errp ? errp : "unknown error", ret);
15057  if (errp) {
15058  sqlite3_free(errp);
15059  errp = NULL;
15060  }
15061  sqlite3_free_table(trows);
15062  return SQL_ERROR;
15063  }
15064  if (errp) {
15065  sqlite3_free(errp);
15066  errp = NULL;
15067  }
15068  if (ncols * nrows > 0) {
15069  int m, mr, nr = nrows;
15070 
15071  namec = -1;
15072  for (k = 0; k < ncols; k++) {
15073  if (strcmp(rowp[k], "name") == 0) {
15074  namec = k;
15075  break;
15076  }
15077  }
15078  if (cname[0]) {
15079  nr = 0;
15080  if (namec >= 0) {
15081  for (k = 1; k <= nrows; k++) {
15082  if (namematch(rowp[k * ncols + namec], cname, 1)) {
15083  nr++;
15084  }
15085  }
15086  }
15087  }
15088  for (k = 0; k < nr; k++) {
15089  m = asize * (roffs + k);
15090 #if defined(_WIN32) || defined(_WIN64)
15091  s->rows[m + 0] = xstrdup(d->xcelqrx ? "main" : "");
15092  s->rows[m + 1] = xstrdup("");
15093 #else
15094  s->rows[m + 0] = xstrdup("");
15095  s->rows[m + 1] = xstrdup("");
15096 #endif
15097  s->rows[m + 2] = xstrdup(trows[i]);
15098  s->rows[m + 8] = xstrdup("10");
15099  s->rows[m + 9] = xstrdup("0");
15100  s->rows[m + 15] = xstrdup("16384");
15101  }
15102  for (k = 0; nr && k < ncols; k++) {
15103  if (strcmp(rowp[k], "cid") == 0) {
15104  for (mr = 0, m = 1; m <= nrows; m++) {
15105  char buf[256];
15106  int ir, coln = k;
15107 
15108  if (cname[0] &&
15109  !namematch(rowp[m * ncols + namec], cname, 1)) {
15110  continue;
15111  }
15112  ir = asize * (roffs + mr);
15113  sscanf(rowp[m * ncols + k], "%d", &coln);
15114  sprintf(buf, "%d", coln + 1);
15115  s->rows[ir + 16] = xstrdup(buf);
15116  ++mr;
15117  }
15118  } else if (k == namec) {
15119  for (mr = 0, m = 1; m <= nrows; m++) {
15120  int ir;
15121 
15122  if (cname[0] &&
15123  !namematch(rowp[m * ncols + namec], cname, 1)) {
15124  continue;
15125  }
15126  ir = asize * (roffs + mr);
15127  s->rows[ir + 3] = xstrdup(rowp[m * ncols + k]);
15128  ++mr;
15129  }
15130  } else if (strcmp(rowp[k], "notnull") == 0) {
15131  for (mr = 0, m = 1; m <= nrows; m++) {
15132  int ir;
15133 
15134  if (cname[0] &&
15135  !namematch(rowp[m * ncols + namec], cname, 1)) {
15136  continue;
15137  }
15138  ir = asize * (roffs + mr);
15139  if (*rowp[m * ncols + k] != '0') {
15140  s->rows[ir + 10] = xstrdup(stringify(SQL_FALSE));
15141  } else {
15142  s->rows[ir + 10] = xstrdup(stringify(SQL_TRUE));
15143  }
15144  s->rows[ir + 17] =
15145  xstrdup((*rowp[m * ncols + k] != '0') ?
15146  "NO" : "YES");
15147  ++mr;
15148  }
15149  } else if (strcmp(rowp[k], "dflt_value") == 0) {
15150  for (mr = 0, m = 1; m <= nrows; m++) {
15151  char *dflt = unquote(rowp[m * ncols + k]);
15152  int ir;
15153 
15154  if (cname[0] &&
15155  !namematch(rowp[m * ncols + namec], cname, 1)) {
15156  continue;
15157  }
15158  ir = asize * (roffs + mr);
15159  s->rows[ir + 12] = xstrdup(dflt ? dflt : "NULL");
15160  ++mr;
15161  }
15162  } else if (strcmp(rowp[k], "type") == 0) {
15163  for (mr = 0, m = 1; m <= nrows; m++) {
15164  char *typename = rowp[m * ncols + k];
15165  int sqltype, mm, dd, ir;
15166  char buf[256];
15167 
15168  if (cname[0] &&
15169  !namematch(rowp[m * ncols + namec], cname, 1)) {
15170  continue;
15171  }
15172  ir = asize * (roffs + mr);
15173  s->rows[ir + 5] = xstrdup(typename);
15174  sqltype = mapsqltype(typename, NULL, *s->ov3,
15175  s->nowchar[0], s->dobigint);
15176  getmd(typename, sqltype, &mm, &dd);
15177 #ifdef SQL_LONGVARCHAR
15178  if (sqltype == SQL_VARCHAR && mm > 255) {
15179  sqltype = SQL_LONGVARCHAR;
15180  }
15181 #endif
15182 #ifdef WINTERFACE
15183 #ifdef SQL_WLONGVARCHAR
15184  if (sqltype == SQL_WVARCHAR && mm > 255) {
15185  sqltype = SQL_WLONGVARCHAR;
15186  }
15187 #endif
15188 #endif
15189  if (sqltype == SQL_VARBINARY && mm > 255) {
15190  sqltype = SQL_LONGVARBINARY;
15191  }
15192  sprintf(buf, "%d", sqltype);
15193  s->rows[ir + 4] = xstrdup(buf);
15194  s->rows[ir + 13] = xstrdup(buf);
15195  sprintf(buf, "%d", mm);
15196  s->rows[ir + 7] = xstrdup(buf);
15197  sprintf(buf, "%d", dd);
15198  s->rows[ir + 6] = xstrdup(buf);
15199  ++mr;
15200  }
15201  }
15202  }
15203  roffs += nr;
15204  }
15205  sqlite3_free_table(rowp);
15206  }
15207  sqlite3_free_table(trows);
15208  return SQL_SUCCESS;
15209 }
15210 
15211 #ifndef WINTERFACE
15212 
15226 SQLRETURN SQL_API
15227 SQLColumns(SQLHSTMT stmt,
15228  SQLCHAR *cat, SQLSMALLINT catLen,
15229  SQLCHAR *schema, SQLSMALLINT schemaLen,
15230  SQLCHAR *table, SQLSMALLINT tableLen,
15231  SQLCHAR *col, SQLSMALLINT colLen)
15232 {
15233 #if defined(_WIN32) || defined(_WIN64)
15234  char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15235 #endif
15236  SQLRETURN ret;
15237 
15238  HSTMT_LOCK(stmt);
15239 #if defined(_WIN32) || defined(_WIN64)
15240  if (!((STMT *) stmt)->oemcp[0]) {
15241  ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15242  table, tableLen, col, colLen);
15243  goto done2;
15244  }
15245  if (cat) {
15246  c = wmb_to_utf_c((char *) cat, catLen);
15247  if (!c) {
15248  ret = nomem((STMT *) stmt);
15249  goto done;
15250  }
15251  }
15252  if (schema) {
15253  s = wmb_to_utf_c((char *) schema, schemaLen);
15254  if (!s) {
15255  ret = nomem((STMT *) stmt);
15256  goto done;
15257  }
15258  }
15259  if (table) {
15260  t = wmb_to_utf_c((char *) table, tableLen);
15261  if (!t) {
15262  ret = nomem((STMT *) stmt);
15263  goto done;
15264  }
15265  }
15266  if (col) {
15267  k = wmb_to_utf_c((char *) col, colLen);
15268  if (!k) {
15269  ret = nomem((STMT *) stmt);
15270  goto done;
15271  }
15272  }
15273  ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15274  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15275 #else
15276  ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15277  table, tableLen, col, colLen);
15278 #endif
15279 #if defined(_WIN32) || defined(_WIN64)
15280 done:
15281  uc_free(k);
15282  uc_free(t);
15283  uc_free(s);
15284  uc_free(c);
15285 done2:
15286  ;
15287 #endif
15288  HSTMT_UNLOCK(stmt);
15289  return ret;
15290 }
15291 #endif
15292 
15293 #ifdef WINTERFACE
15294 
15308 SQLRETURN SQL_API
15310  SQLWCHAR *cat, SQLSMALLINT catLen,
15311  SQLWCHAR *schema, SQLSMALLINT schemaLen,
15312  SQLWCHAR *table, SQLSMALLINT tableLen,
15313  SQLWCHAR *col, SQLSMALLINT colLen)
15314 {
15315  char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15316  SQLRETURN ret;
15317 
15318  HSTMT_LOCK(stmt);
15319  if (cat) {
15320  c = uc_to_utf_c(cat, catLen);
15321  if (!c) {
15322  ret = nomem((STMT *) stmt);
15323  goto done;
15324  }
15325  }
15326  if (schema) {
15327  s = uc_to_utf_c(schema, schemaLen);
15328  if (!s) {
15329  ret = nomem((STMT *) stmt);
15330  goto done;
15331  }
15332  }
15333  if (table) {
15334  t = uc_to_utf_c(table, tableLen);
15335  if (!t) {
15336  ret = nomem((STMT *) stmt);
15337  goto done;
15338  }
15339  }
15340  if (col) {
15341  k = uc_to_utf_c(col, colLen);
15342  if (!k) {
15343  ret = nomem((STMT *) stmt);
15344  goto done;
15345  }
15346  }
15347  ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15348  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15349 done:
15350  uc_free(k);
15351  uc_free(t);
15352  uc_free(s);
15353  uc_free(c);
15354  HSTMT_UNLOCK(stmt);
15355  return ret;
15356 
15357 }
15358 #endif
15359 
15364 static COL typeSpec2[] = {
15365  { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15366  { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15367  { "SYSTEM", "TYPE", "PRECISION", SQL_INTEGER, 9 },
15368  { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15369  { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15370  { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15371  { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15372  { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15373  { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15374  { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15375  { "SYSTEM", "TYPE", "MONEY", SQL_SMALLINT, 2 },
15376  { "SYSTEM", "TYPE", "AUTO_INCREMENT", SQL_SMALLINT, 2 },
15377  { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15378  { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15379  { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 }
15380 };
15381 
15382 static COL typeSpec3[] = {
15383  { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15384  { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15385  { "SYSTEM", "TYPE", "COLUMN_SIZE", SQL_INTEGER, 9 },
15386  { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15387  { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15388  { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15389  { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15390  { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15391  { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15392  { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15393  { "SYSTEM", "TYPE", "FIXED_PREC_SCALE", SQL_SMALLINT, 2 },
15394  { "SYSTEM", "TYPE", "AUTO_UNIQUE_VALUE", SQL_SMALLINT, 2 },
15395  { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15396  { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15397  { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 },
15398  { "SYSTEM", "TYPE", "SQL_DATA_TYPE", SQL_SMALLINT, 2 },
15399  { "SYSTEM", "TYPE", "SQL_DATETIME_SUB", SQL_SMALLINT, 2 },
15400  { "SYSTEM", "TYPE", "NUM_PREC_RADIX", SQL_INTEGER, 4 },
15401  { "SYSTEM", "TYPE", "INTERVAL_PRECISION", SQL_SMALLINT, 2 }
15402 };
15403 
15414 static void
15415 mktypeinfo(STMT *s, int row, int asize, char *typename, int type, int tind)
15416 {
15417  int offs = row * asize;
15418  char *tcode, *crpar = NULL, *quote = NULL, *sign = stringify(SQL_FALSE);
15419  static char tcodes[32 * 32];
15420 
15421  if (tind <= 0) {
15422  tind = row;
15423  }
15424  tcode = tcodes + tind * 32;
15425  sprintf(tcode, "%d", type);
15426  s->rows[offs + 0] = typename;
15427  s->rows[offs + 1] = tcode;
15428  if (asize >= 17) {
15429  s->rows[offs + 15] = tcode;
15430  s->rows[offs + 16] = "0";
15431  }
15432  switch (type) {
15433  default:
15434 #ifdef SQL_LONGVARCHAR
15435  case SQL_LONGVARCHAR:
15436 #ifdef WINTERFACE
15437  case SQL_WLONGVARCHAR:
15438 #endif
15439  crpar = "length";
15440  quote = "'";
15441  sign = NULL;
15442  s->rows[offs + 2] = "65536";
15443  break;
15444 #endif
15445 #ifdef SQL_BIT
15446  case SQL_BIT:
15447  sign = NULL;
15448  s->rows[offs + 2] = "1";
15449  break;
15450 #endif
15451  case SQL_CHAR:
15452  case SQL_VARCHAR:
15453 #ifdef WINTERFACE
15454  case SQL_WCHAR:
15455  case SQL_WVARCHAR:
15456 #endif
15457  s->rows[offs + 2] = "255";
15458  crpar = "length";
15459  quote = "'";
15460  sign = NULL;
15461  break;
15462  case SQL_TINYINT:
15463  s->rows[offs + 2] = "3";
15464  break;
15465  case SQL_SMALLINT:
15466  s->rows[offs + 2] = "5";
15467  break;
15468  case SQL_INTEGER:
15469  s->rows[offs + 2] = "9";
15470  break;
15471 #ifdef SQL_BIGINT
15472  case SQL_BIGINT:
15473  s->rows[offs + 2] = "19";
15474  break;
15475 #endif
15476  case SQL_FLOAT:
15477  s->rows[offs + 2] = "7";
15478  break;
15479  case SQL_DOUBLE:
15480  s->rows[offs + 2] = "15";
15481  break;
15482 #ifdef SQL_TYPE_DATE
15483  case SQL_TYPE_DATE:
15484 #endif
15485  case SQL_DATE:
15486  s->rows[offs + 2] = "10";
15487  quote = "'";
15488  sign = NULL;
15489  break;
15490 #ifdef SQL_TYPE_TIME
15491  case SQL_TYPE_TIME:
15492 #endif
15493  case SQL_TIME:
15494  s->rows[offs + 2] = "8";
15495  quote = "'";
15496  sign = NULL;
15497  break;
15498 #ifdef SQL_TYPE_TIMESTAMP
15499  case SQL_TYPE_TIMESTAMP:
15500 #endif
15501  case SQL_TIMESTAMP:
15502  s->rows[offs + 2] = "32";
15503  quote = "'";
15504  sign = NULL;
15505  break;
15506  case SQL_VARBINARY:
15507  sign = NULL;
15508  s->rows[offs + 2] = "255";
15509  break;
15510  case SQL_LONGVARBINARY:
15511  sign = NULL;
15512  s->rows[offs + 2] = "65536";
15513  break;
15514  }
15515  s->rows[offs + 3] = s->rows[offs + 4] = quote;
15516  s->rows[offs + 5] = crpar;
15517  s->rows[offs + 6] = stringify(SQL_NULLABLE);
15518  s->rows[offs + 7] = stringify(SQL_FALSE);
15519  s->rows[offs + 8] = stringify(SQL_SEARCHABLE);
15520  s->rows[offs + 9] = sign;
15521  s->rows[offs + 10] = stringify(SQL_FALSE);
15522  s->rows[offs + 11] = stringify(SQL_FALSE);
15523  s->rows[offs + 12] = typename;
15524  switch (type) {
15525  case SQL_DATE:
15526  case SQL_TIME:
15527  s->rows[offs + 13] = "0";
15528  s->rows[offs + 14] = "0";
15529  break;
15530 #ifdef SQL_TYPE_TIMESTAMP
15531  case SQL_TYPE_TIMESTAMP:
15532 #endif
15533  case SQL_TIMESTAMP:
15534  s->rows[offs + 13] = "0";
15535  s->rows[offs + 14] = "3";
15536  break;
15537  default:
15538  s->rows[offs + 13] = NULL;
15539  s->rows[offs + 14] = NULL;
15540  break;
15541  }
15542 }
15543 
15552 static int
15553 typeinfosort(const void *a, const void *b)
15554 {
15555  char **pa = (char **) a;
15556  char **pb = (char **) b;
15557  int na, nb;
15558 
15559  na = strtol(pa[1], NULL, 0);
15560  nb = strtol(pb[1], NULL, 0);
15561  return na - nb;
15562 }
15563 
15571 static SQLRETURN
15572 drvgettypeinfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
15573 {
15574  SQLRETURN ret;
15575  STMT *s;
15576  int asize;
15577 
15579  typeSpec3, array_size(typeSpec3), &asize);
15580  if (ret != SQL_SUCCESS) {
15581  return ret;
15582  }
15583  s = (STMT *) stmt;
15584 #ifdef SQL_LONGVARCHAR
15585  s->nrows = (sqltype == SQL_ALL_TYPES) ? 13 : 1;
15586 #else
15587  s->nrows = (sqltype == SQL_ALL_TYPES) ? 12 : 1;
15588 #endif
15589  if (sqltype == SQL_ALL_TYPES) {
15590 #ifdef WINTERFACE
15591  s->nrows += 2;
15592 #ifdef SQL_WLONGVARCHAR
15593  s->nrows += 2;
15594 #endif
15595 #endif
15596  }
15597  if (sqltype == SQL_ALL_TYPES) {
15598  s->nrows += 2;
15599 #ifdef SQL_BIT
15600  s->nrows += 1;
15601 #endif
15602 #ifdef SQL_BIGINT
15603  s->nrows += 1;
15604 #endif
15605  }
15606  s->rows = (char **) xmalloc(sizeof (char *) * (s->nrows + 1) * asize);
15607  if (!s->rows) {
15608  s->nrows = 0;
15609  return nomem(s);
15610  }
15611 #ifdef MEMORY_DEBUG
15612  s->rowfree = xfree__;
15613 #else
15614  s->rowfree = sqlite3_free;
15615 #endif
15616  memset(s->rows, 0, sizeof (char *) * (s->nrows + 1) * asize);
15617  if (sqltype == SQL_ALL_TYPES) {
15618  int cc = 1;
15619 
15620  mktypeinfo(s, cc++, asize, "varchar", SQL_VARCHAR, 0);
15621  mktypeinfo(s, cc++, asize, "tinyint", SQL_TINYINT, 0);
15622  mktypeinfo(s, cc++, asize, "smallint", SQL_SMALLINT, 0);
15623  mktypeinfo(s, cc++, asize, "integer", SQL_INTEGER, 0);
15624  mktypeinfo(s, cc++, asize, "float", SQL_FLOAT, 0);
15625  mktypeinfo(s, cc++, asize, "double", SQL_DOUBLE, 0);
15626 #ifdef SQL_TYPE_DATE
15627  mktypeinfo(s, cc++, asize, "date",
15628  (*s->ov3) ? SQL_TYPE_DATE : SQL_DATE, 0);
15629 #else
15630  mktypeinfo(s, cc++, asize, "date", SQL_DATE, 0);
15631 #endif
15632 #ifdef SQL_TYPE_TIME
15633  mktypeinfo(s, cc++, asize, "time",
15634  (*s->ov3) ? SQL_TYPE_TIME : SQL_TIME, 0);
15635 #else
15636  mktypeinfo(s, cc++, asize, "time", SQL_TIME, 0);
15637 #endif
15638 #ifdef SQL_TYPE_TIMESTAMP
15639  mktypeinfo(s, cc++, asize, "timestamp",
15640  (*s->ov3) ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP, 0);
15641 #else
15642  mktypeinfo(s, cc++, asize, "timestamp", SQL_TIMESTAMP, 0);
15643 #endif
15644  mktypeinfo(s, cc++, asize, "char", SQL_CHAR, 0);
15645  mktypeinfo(s, cc++, asize, "numeric", SQL_DOUBLE, 0);
15646 #ifdef SQL_LONGVARCHAR
15647  mktypeinfo(s, cc++, asize, "text", SQL_LONGVARCHAR, 0);
15648  mktypeinfo(s, cc++, asize, "longvarchar", SQL_LONGVARCHAR, 0);
15649 #else
15650  mktypeinfo(s, cc++, asize, "text", SQL_VARCHAR, 0);
15651 #endif
15652  mktypeinfo(s, cc++, asize, "varbinary", SQL_VARBINARY, 0);
15653  mktypeinfo(s, cc++, asize, "longvarbinary", SQL_LONGVARBINARY, 0);
15654 #ifdef SQL_BIT
15655  mktypeinfo(s, cc++, asize, "bit", SQL_BIT, 0);
15656 #endif
15657 #ifdef SQL_BIGINT
15658  mktypeinfo(s, cc++, asize, "bigint", SQL_BIGINT, 0);
15659 #endif
15660 #ifdef WINTERFACE
15661  mktypeinfo(s, cc++, asize, "wvarchar", SQL_WVARCHAR, 0);
15662  mktypeinfo(s, cc++, asize, "wchar", SQL_WCHAR, 0);
15663 #ifdef SQL_WLONGVARCHAR
15664  mktypeinfo(s, cc++, asize, "wtext", SQL_WLONGVARCHAR, 0);
15665  mktypeinfo(s, cc++, asize, "longwvarchar", SQL_WLONGVARCHAR, 0);
15666 #endif
15667 #endif
15668  qsort(s->rows + asize, s->nrows, sizeof (char *) * asize,
15669  typeinfosort);
15670  } else {
15671  switch (sqltype) {
15672  case SQL_CHAR:
15673  mktypeinfo(s, 1, asize, "char", SQL_CHAR, 10);
15674  break;
15675  case SQL_VARCHAR:
15676  mktypeinfo(s, 1, asize, "varchar", SQL_VARCHAR, 1);
15677  break;
15678  case SQL_TINYINT:
15679  mktypeinfo(s, 1, asize, "tinyint", SQL_TINYINT, 2);
15680  break;
15681  case SQL_SMALLINT:
15682  mktypeinfo(s, 1, asize, "smallint", SQL_SMALLINT, 3);
15683  break;
15684  case SQL_INTEGER:
15685  mktypeinfo(s, 1, asize, "integer", SQL_INTEGER, 4);
15686  break;
15687  case SQL_FLOAT:
15688  mktypeinfo(s, 1, asize, "float", SQL_FLOAT, 5);
15689  break;
15690  case SQL_DOUBLE:
15691  mktypeinfo(s, 1, asize, "double", SQL_DOUBLE, 6);
15692  break;
15693 #ifdef SQL_TYPE_DATE
15694  case SQL_TYPE_DATE:
15695  mktypeinfo(s, 1, asize, "date", SQL_TYPE_DATE, 25);
15696  break;
15697 #endif
15698  case SQL_DATE:
15699  mktypeinfo(s, 1, asize, "date", SQL_DATE, 7);
15700  break;
15701 #ifdef SQL_TYPE_TIME
15702  case SQL_TYPE_TIME:
15703  mktypeinfo(s, 1, asize, "time", SQL_TYPE_TIME, 26);
15704  break;
15705 #endif
15706  case SQL_TIME:
15707  mktypeinfo(s, 1, asize, "time", SQL_TIME, 8);
15708  break;
15709 #ifdef SQL_TYPE_TIMESTAMP
15710  case SQL_TYPE_TIMESTAMP:
15711  mktypeinfo(s, 1, asize, "timestamp", SQL_TYPE_TIMESTAMP, 27);
15712  break;
15713 #endif
15714  case SQL_TIMESTAMP:
15715  mktypeinfo(s, 1, asize, "timestamp", SQL_TIMESTAMP, 9);
15716  break;
15717 #ifdef SQL_LONGVARCHAR
15718  case SQL_LONGVARCHAR:
15719  mktypeinfo(s, 1, asize, "longvarchar", SQL_LONGVARCHAR, 12);
15720  break;
15721 #endif
15722  case SQL_VARBINARY:
15723  mktypeinfo(s, 1, asize, "varbinary", SQL_VARBINARY, 30);
15724  break;
15725  case SQL_LONGVARBINARY:
15726  mktypeinfo(s, 1, asize, "longvarbinary", SQL_LONGVARBINARY, 31);
15727  break;
15728 #ifdef SQL_BIT
15729  case SQL_BIT:
15730  mktypeinfo(s, 1, asize, "bit", SQL_BIT, 29);
15731  break;
15732 #endif
15733 #ifdef SQL_BIGINT
15734  case SQL_BIGINT:
15735  mktypeinfo(s, 1, asize, "bigint", SQL_BIGINT, 28);
15736  break;
15737 #endif
15738 #ifdef WINTERFACE
15739 #ifdef SQL_WCHAR
15740  case SQL_WCHAR:
15741  mktypeinfo(s, 1, asize, "wchar", SQL_WCHAR, 18);
15742  break;
15743 #endif
15744 #ifdef SQL_WVARCHAR
15745  case SQL_WVARCHAR:
15746  mktypeinfo(s, 1, asize, "wvarchar", SQL_WVARCHAR, 19);
15747  break;
15748 #endif
15749 #ifdef SQL_WLONGVARCHAR
15750  case SQL_WLONGVARCHAR:
15751  mktypeinfo(s, 1, asize, "longwvarchar", SQL_WLONGVARCHAR, 20);
15752  break;
15753 #endif
15754 #endif
15755  default:
15756  s->nrows = 0;
15757  }
15758  }
15759  return SQL_SUCCESS;
15760 }
15761 
15762 #ifndef WINTERFACE
15763 
15770 SQLRETURN SQL_API
15771 SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
15772 {
15773  SQLRETURN ret;
15774 
15775  HSTMT_LOCK(stmt);
15776  ret = drvgettypeinfo(stmt, sqltype);
15777  HSTMT_UNLOCK(stmt);
15778  return ret;
15779 }
15780 #endif
15781 
15782 #ifdef WINTERFACE
15783 
15790 SQLRETURN SQL_API
15791 SQLGetTypeInfoW(SQLHSTMT stmt, SQLSMALLINT sqltype)
15792 {
15793  SQLRETURN ret;
15794 
15795  HSTMT_LOCK(stmt);
15796  ret = drvgettypeinfo(stmt, sqltype);
15797  HSTMT_UNLOCK(stmt);
15798  return ret;
15799 }
15800 #endif
15801 
15806 static COL statSpec2[] = {
15807  { "SYSTEM", "STATISTICS", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
15808  { "SYSTEM", "STATISTICS", "TABLE_OWNER", SCOL_VARCHAR, 50 },
15809  { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
15810  { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
15811  { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
15812  { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
15813  { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
15814  { "SYSTEM", "STATISTICS", "SEQ_IN_INDEX", SQL_SMALLINT, 50 },
15815  { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15816  { "SYSTEM", "STATISTICS", "COLLATION", SCOL_CHAR, 1 },
15817  { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
15818  { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
15819  { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
15820 };
15821 
15822 static COL statSpec3[] = {
15823  { "SYSTEM", "STATISTICS", "TABLE_CAT", SCOL_VARCHAR, 50 },
15824  { "SYSTEM", "STATISTICS", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
15825  { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
15826  { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
15827  { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
15828  { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
15829  { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
15830  { "SYSTEM", "STATISTICS", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
15831  { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15832  { "SYSTEM", "STATISTICS", "ASC_OR_DESC", SCOL_CHAR, 1 },
15833  { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
15834  { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
15835  { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
15836 };
15837 
15852 static SQLRETURN
15853 drvstatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
15854  SQLCHAR *schema, SQLSMALLINT schemaLen,
15855  SQLCHAR *table, SQLSMALLINT tableLen,
15856  SQLUSMALLINT itype, SQLUSMALLINT resv)
15857 {
15858  SQLRETURN sret;
15859  STMT *s;
15860  DBC *d;
15861  int i, asize, ret, nrows, ncols, offs, namec, uniquec, addipk = 0;
15862  PTRDIFF_T size;
15863  char **rowp, *errp = NULL, *sql, tname[512];
15864 
15866  statSpec3, array_size(statSpec3), &asize);
15867  if (sret != SQL_SUCCESS) {
15868  return sret;
15869  }
15870  s = (STMT *) stmt;
15871  d = (DBC *) s->dbc;
15872  if (!table || table[0] == '\0' || table[0] == '%') {
15873  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
15874  return SQL_ERROR;
15875  }
15876  if (tableLen == SQL_NTS) {
15877  size = sizeof (tname) - 1;
15878  } else {
15879  size = min(sizeof (tname) - 1, tableLen);
15880  }
15881  strncpy(tname, (char *) table, size);
15882  tname[size] = '\0';
15883  unescpat(tname);
15884  sret = starttran(s);
15885  if (sret != SQL_SUCCESS) {
15886  return sret;
15887  }
15888  /*
15889  * Try integer primary key (autoincrement) first
15890  */
15891  if (itype == SQL_INDEX_UNIQUE || itype == SQL_INDEX_ALL) {
15892  rowp = 0;
15893  ret = SQLITE_ERROR;
15894  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
15895  if (sql) {
15896  dbtraceapi(d, "sqlite3_get_table", sql);
15897  ret = sqlite3_get_table(d->sqlite, sql, &rowp,
15898  &nrows, &ncols, NULL);
15899  sqlite3_free(sql);
15900  }
15901  if (ret == SQLITE_OK) {
15902  int colid, typec, npk = 0, npkint = 0;
15903 
15904  namec = findcol(rowp, ncols, "name");
15905  uniquec = findcol(rowp, ncols, "pk");
15906  typec = findcol(rowp, ncols, "type");
15907  colid = findcol(rowp, ncols, "cid");
15908  if (namec < 0 || uniquec < 0 || typec < 0 || colid < 0) {
15909  goto noipk;
15910  }
15911  for (i = 1; i <= nrows; i++) {
15912  if (*rowp[i * ncols + uniquec] != '0') {
15913  npk++;
15914  if (strlen(rowp[i * ncols + typec]) == 7 &&
15915  strncasecmp(rowp[i * ncols + typec], "integer", 7)
15916  == 0) {
15917  npkint++;
15918  }
15919  }
15920  }
15921  if (npkint == 1 && npk == npkint) {
15922  addipk = 1;
15923  }
15924  }
15925 noipk:
15926  sqlite3_free_table(rowp);
15927  }
15928  sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
15929  if (!sql) {
15930  return nomem(s);
15931  }
15932  dbtraceapi(d, "sqlite3_get_table", sql);
15933  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15934  sqlite3_free(sql);
15935  if (ret != SQLITE_OK) {
15936  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15937  errp ? errp : "unknown error", ret);
15938  if (errp) {
15939  sqlite3_free(errp);
15940  errp = NULL;
15941  }
15942  return SQL_ERROR;
15943  }
15944  if (errp) {
15945  sqlite3_free(errp);
15946  errp = NULL;
15947  }
15948  size = 0;
15949  namec = findcol(rowp, ncols, "name");
15950  uniquec = findcol(rowp, ncols, "unique");
15951  if (namec < 0 || uniquec < 0) {
15952  goto nodata;
15953  }
15954  for (i = 1; i <= nrows; i++) {
15955  int nnrows, nncols;
15956  char **rowpp;
15957  int isuniq;
15958 
15959  isuniq = *rowp[i * ncols + uniquec] != '0';
15960  if (isuniq || itype == SQL_INDEX_ALL) {
15961  ret = SQLITE_ERROR;
15962  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
15963  rowp[i * ncols + namec]);
15964  if (sql) {
15965  dbtraceapi(d, "sqlite3_get_table", sql);
15966  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
15967  &nnrows, &nncols, NULL);
15968  sqlite3_free(sql);
15969  }
15970  if (ret == SQLITE_OK) {
15971  size += nnrows;
15972  sqlite3_free_table(rowpp);
15973  }
15974  }
15975  }
15976 nodata:
15977  if (addipk) {
15978  size++;
15979  }
15980  if (size == 0) {
15981  sqlite3_free_table(rowp);
15982  return SQL_SUCCESS;
15983  }
15984  s->nrows = size;
15985  size = (size + 1) * asize;
15986  s->rows = xmalloc((size + 1) * sizeof (char *));
15987  if (!s->rows) {
15988  s->nrows = 0;
15989  return nomem(s);
15990  }
15991  s->rows[0] = (char *) size;
15992  s->rows += 1;
15993  memset(s->rows, 0, sizeof (char *) * size);
15994  s->rowfree = freerows;
15995  offs = 0;
15996  if (addipk) {
15997  char **rowpp = 0;
15998  int nrows2, ncols2;
15999 
16000  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
16001  if (sql) {
16002  dbtraceapi(d, "sqlite3_get_table", sql);
16003  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16004  &nrows2, &ncols2, NULL);
16005  sqlite3_free(sql);
16006  }
16007  if (ret == SQLITE_OK) {
16008  int colid, typec, roffs, namecc, uniquecc;
16009 
16010  namecc = findcol(rowpp, ncols2, "name");
16011  uniquecc = findcol(rowpp, ncols2, "pk");
16012  typec = findcol(rowpp, ncols2, "type");
16013  colid = findcol(rowpp, ncols2, "cid");
16014  if (namecc < 0 || uniquecc < 0 || typec < 0 || colid < 0) {
16015  addipk = 0;
16016  s->nrows--;
16017  goto nodata2;
16018  }
16019  for (i = 1; i <= nrows2; i++) {
16020  if (*rowpp[i * ncols2 + uniquecc] != '0' &&
16021  strlen(rowpp[i * ncols2 + typec]) == 7 &&
16022  strncasecmp(rowpp[i * ncols2 + typec], "integer", 7)
16023  == 0) {
16024  break;
16025  }
16026  }
16027  if (i > nrows2) {
16028  addipk = 0;
16029  s->nrows--;
16030  goto nodata2;
16031  }
16032  roffs = s->ncols;
16033 #if defined(_WIN32) || defined(_WIN64)
16034  s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
16035  s->rows[roffs + 1] = xstrdup("");
16036 #else
16037  s->rows[roffs + 0] = xstrdup("");
16038  s->rows[roffs + 1] = xstrdup("");
16039 #endif
16040  s->rows[roffs + 2] = xstrdup(tname);
16041  s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16042  s->rows[roffs + 5] = xstrdup("sqlite_autoindex_0");
16043  s->rows[roffs + 6] = xstrdup(stringify(SQL_INDEX_OTHER));
16044  s->rows[roffs + 7] = xstrdup("1");
16045  s->rows[roffs + 8] = xstrdup(rowpp[i * ncols2 + namecc]);
16046  s->rows[roffs + 9] = xstrdup("A");
16047  }
16048 nodata2:
16049  sqlite3_free_table(rowpp);
16050  }
16051  for (i = 1; i <= nrows; i++) {
16052  int nnrows, nncols;
16053  char **rowpp = 0;
16054 
16055  if (*rowp[i * ncols + uniquec] != '0' || itype == SQL_INDEX_ALL) {
16056  int k;
16057 
16058  ret = SQLITE_ERROR;
16059  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
16060  rowp[i * ncols + namec]);
16061  if (sql) {
16062  dbtraceapi(d, "sqlite3_get_table", sql);
16063  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16064  &nnrows, &nncols, NULL);
16065  sqlite3_free(sql);
16066  }
16067  if (ret != SQLITE_OK) {
16068  continue;
16069  }
16070  for (k = 0; nnrows && k < nncols; k++) {
16071  if (strcmp(rowpp[k], "name") == 0) {
16072  int m;
16073 
16074  for (m = 1; m <= nnrows; m++) {
16075  int roffs = (offs + addipk + m) * s->ncols;
16076  int isuniq;
16077 
16078  isuniq = *rowp[i * ncols + uniquec] != '0';
16079  s->rows[roffs + 0] = xstrdup("");
16080  s->rows[roffs + 1] = xstrdup("");
16081  s->rows[roffs + 2] = xstrdup(tname);
16082  if (isuniq) {
16083  s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16084  } else {
16085  s->rows[roffs + 3] = xstrdup(stringify(SQL_TRUE));
16086  }
16087  s->rows[roffs + 5] = xstrdup(rowp[i * ncols + namec]);
16088  s->rows[roffs + 6] =
16089  xstrdup(stringify(SQL_INDEX_OTHER));
16090  s->rows[roffs + 8] = xstrdup(rowpp[m * nncols + k]);
16091  s->rows[roffs + 9] = xstrdup("A");
16092  }
16093  } else if (strcmp(rowpp[k], "seqno") == 0) {
16094  int m;
16095 
16096  for (m = 1; m <= nnrows; m++) {
16097  int roffs = (offs + addipk + m) * s->ncols;
16098  int pos = m - 1;
16099  char buf[32];
16100 
16101  sscanf(rowpp[m * nncols + k], "%d", &pos);
16102  sprintf(buf, "%d", pos + 1);
16103  s->rows[roffs + 7] = xstrdup(buf);
16104  }
16105  }
16106  }
16107  offs += nnrows;
16108  sqlite3_free_table(rowpp);
16109  }
16110  }
16111  sqlite3_free_table(rowp);
16112  return SQL_SUCCESS;
16113 }
16114 
16115 #ifndef WINTERFACE
16116 
16130 SQLRETURN SQL_API
16131 SQLStatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
16132  SQLCHAR *schema, SQLSMALLINT schemaLen,
16133  SQLCHAR *table, SQLSMALLINT tableLen,
16134  SQLUSMALLINT itype, SQLUSMALLINT resv)
16135 {
16136 #if defined(_WIN32) || defined(_WIN64)
16137  char *c = NULL, *s = NULL, *t = NULL;
16138 #endif
16139  SQLRETURN ret;
16140 
16141  HSTMT_LOCK(stmt);
16142 #if defined(_WIN32) || defined(_WIN64)
16143  if (!((STMT *) stmt)->oemcp[0]) {
16144  ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16145  table, tableLen, itype, resv);
16146  goto done2;
16147  }
16148  if (cat) {
16149  c = wmb_to_utf_c((char *) cat, catLen);
16150  if (!c) {
16151  ret = nomem((STMT *) stmt);
16152  goto done;
16153  }
16154  }
16155  if (schema) {
16156  s = wmb_to_utf_c((char *) schema, schemaLen);
16157  if (!s) {
16158  ret = nomem((STMT *) stmt);
16159  goto done;
16160  }
16161  }
16162  if (table) {
16163  t = wmb_to_utf_c((char *) table, tableLen);
16164  if (!t) {
16165  ret = nomem((STMT *) stmt);
16166  goto done;
16167  }
16168  }
16169  ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16170  (SQLCHAR *) t, SQL_NTS, itype, resv);
16171 #else
16172  ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16173  table, tableLen, itype, resv);
16174 #endif
16175 #if defined(_WIN32) || defined(_WIN64)
16176 done:
16177  uc_free(t);
16178  uc_free(s);
16179  uc_free(c);
16180 done2:
16181  ;
16182 #endif
16183  HSTMT_UNLOCK(stmt);
16184  return ret;
16185 }
16186 #endif
16187 
16188 #ifdef WINTERFACE
16189 
16203 SQLRETURN SQL_API
16204 SQLStatisticsW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen,
16205  SQLWCHAR *schema, SQLSMALLINT schemaLen,
16206  SQLWCHAR *table, SQLSMALLINT tableLen,
16207  SQLUSMALLINT itype, SQLUSMALLINT resv)
16208 {
16209  char *c = NULL, *s = NULL, *t = NULL;
16210  SQLRETURN ret;
16211 
16212  HSTMT_LOCK(stmt);
16213  if (cat) {
16214  c = uc_to_utf_c(cat, catLen);
16215  if (!c) {
16216  ret = nomem((STMT *) stmt);
16217  goto done;
16218  }
16219  }
16220  if (schema) {
16221  s = uc_to_utf_c(schema, schemaLen);
16222  if (!s) {
16223  ret = nomem((STMT *) stmt);
16224  goto done;
16225  }
16226  }
16227  if (table) {
16228  t = uc_to_utf_c(table, tableLen);
16229  if (!t) {
16230  ret = nomem((STMT *) stmt);
16231  goto done;
16232  }
16233  }
16234  ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16235  (SQLCHAR *) t, SQL_NTS, itype, resv);
16236 done:
16237  uc_free(t);
16238  uc_free(s);
16239  uc_free(c);
16240  HSTMT_UNLOCK(stmt);
16241  return ret;
16242 }
16243 #endif
16244 
16256 SQLRETURN SQL_API
16257 SQLGetData(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
16258  SQLPOINTER val, SQLLEN len, SQLLEN *lenp)
16259 {
16260  STMT *s;
16261  SQLRETURN ret = SQL_ERROR;
16262 
16263  HSTMT_LOCK(stmt);
16264  if (stmt == SQL_NULL_HSTMT) {
16265  return SQL_INVALID_HANDLE;
16266  }
16267  s = (STMT *) stmt;
16268  if (col == 0 && s->bkmrk != SQL_UB_OFF) {
16269  if (s->bkmrk == SQL_UB_ON && type == SQL_C_BOOKMARK) {
16270  *((SQLINTEGER *) val) = s->rowp;
16271  if (lenp) {
16272  *lenp = sizeof (SQLINTEGER);
16273  }
16274  ret = SQL_SUCCESS;
16275  goto done;
16276  } else if (s->bkmrk == SQL_UB_VARIABLE && type == SQL_C_VARBOOKMARK) {
16277  if (s->has_rowid >= 0) {
16278  char **data, *endp = 0;
16279 
16280  data = s->rows + s->ncols + (s->rowp * s->ncols)
16281  + s->has_rowid;
16282 #ifdef __osf__
16283  *((sqlite_int64 *) val) = strtol(*data, &endp, 0);
16284 #else
16285  *((sqlite_int64 *) val) = strtoll(*data, &endp, 0);
16286 #endif
16287  } else {
16288  *((sqlite_int64 *) val) = s->rowp;
16289  }
16290  if (lenp) {
16291  *lenp = sizeof (sqlite_int64);
16292  }
16293  ret = SQL_SUCCESS;
16294  goto done;
16295  }
16296  }
16297  if (col < 1 || col > s->ncols) {
16298  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
16299  goto done;
16300  }
16301  --col;
16302  ret = getrowdata(s, col, type, val, len, lenp, 1);
16303 done:
16304  HSTMT_UNLOCK(stmt);
16305  return ret;
16306 }
16307 
16315 static SQLRETURN
16316 dofetchbind(STMT *s, int rsi)
16317 {
16318  int ret, i, withinfo = 0;
16319 
16320  s->row_status0[rsi] = SQL_ROW_SUCCESS;
16321  if (s->bkmrk != SQL_UB_OFF && s->bkmrkcol.valp) {
16322  int bsize = sizeof (SQLINTEGER);
16323 
16324  if (s->bkmrkcol.type == SQL_C_VARBOOKMARK) {
16325  SQLPOINTER *val;
16326 
16327  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16328  val = (SQLPOINTER)
16329  ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16330  } else {
16331  val = (SQLPOINTER)
16332  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * rsi);
16333  }
16334  if (s->bind_offs) {
16335  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
16336  }
16337  if (s->has_rowid >= 0) {
16338  char **data, *endp = 0;
16339 
16340  data = s->rows + s->ncols + (s->rowp * s->ncols)
16341  + s->has_rowid;
16342 #ifdef __osf__
16343  *(sqlite_int64 *) val = strtol(*data, &endp, 0);
16344 #else
16345  *(sqlite_int64 *) val = strtoll(*data, &endp, 0);
16346 #endif
16347  } else {
16348  *(sqlite_int64 *) val = s->rowp;
16349  }
16350  bsize = sizeof (sqlite_int64);
16351  } else {
16352  SQLINTEGER *val;
16353 
16354  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16355  val = (SQLINTEGER *)
16356  ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16357  } else {
16358  val = (SQLINTEGER *) s->bkmrkcol.valp + rsi;
16359  }
16360  if (s->bind_offs) {
16361  val = (SQLINTEGER *) ((char *) val + *s->bind_offs);
16362  }
16363  *val = s->rowp;
16364  }
16365  if (s->bkmrkcol.lenp) {
16366  SQLLEN *ival;
16367 
16368  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16369  ival = (SQLLEN *)
16370  ((char *) s->bkmrkcol.lenp + s->bind_type * rsi);
16371  } else {
16372  ival = &s->bkmrkcol.lenp[rsi];
16373  }
16374  if (s->bind_offs) {
16375  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
16376  }
16377  *ival = bsize;
16378  }
16379  }
16380  ret = SQL_SUCCESS;
16381  for (i = 0; s->bindcols && i < s->ncols; i++) {
16382  BINDCOL *b = &s->bindcols[i];
16383  SQLPOINTER dp = 0;
16384  SQLLEN *lp = 0;
16385 
16386  b->offs = 0;
16387  if (b->valp) {
16388  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16389  dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
16390  } else {
16391  dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
16392  }
16393  if (s->bind_offs) {
16394  dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
16395  }
16396  }
16397  if (b->lenp) {
16398  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16399  lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
16400  } else {
16401  lp = b->lenp + rsi;
16402  }
16403  if (s->bind_offs) {
16404  lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
16405  }
16406  }
16407  if (dp || lp) {
16408  ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp, b->max, lp, 0);
16409  if (!SQL_SUCCEEDED(ret)) {
16410  s->row_status0[rsi] = SQL_ROW_ERROR;
16411  break;
16412  }
16413  if (ret != SQL_SUCCESS) {
16414  withinfo = 1;
16415 #ifdef SQL_ROW_SUCCESS_WITH_INFO
16416  s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
16417 #endif
16418  }
16419  }
16420  }
16421  if (SQL_SUCCEEDED(ret)) {
16422  ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16423  }
16424  return ret;
16425 }
16426 
16435 static SQLRETURN
16436 drvfetchscroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLINTEGER offset)
16437 {
16438  STMT *s;
16439  int i, withinfo = 0;
16440  SQLRETURN ret;
16441 
16442  if (stmt == SQL_NULL_HSTMT) {
16443  return SQL_INVALID_HANDLE;
16444  }
16445  s = (STMT *) stmt;
16446  for (i = 0; i < s->rowset_size; i++) {
16447  s->row_status0[i] = SQL_ROW_NOROW;
16448  }
16449  if (s->row_status) {
16450  memcpy(s->row_status, s->row_status0,
16451  sizeof (SQLUSMALLINT) * s->rowset_size);
16452  }
16453  s->row_count0 = 0;
16454  if (s->row_count) {
16455  *s->row_count = s->row_count0;
16456  }
16457  if (!s->bindcols) {
16458  for (i = 0; i < s->rowset_size; i++) {
16459  s->row_status0[i] = SQL_ROW_ERROR;
16460  }
16461  ret = SQL_ERROR;
16462  i = 0;
16463  goto done2;
16464  }
16465  if (s->isselect != 1 && s->isselect != -1) {
16466  setstat(s, -1, "no result set available", "24000");
16467  ret = SQL_ERROR;
16468  i = s->nrows;
16469  goto done2;
16470  }
16471  if (s->curtype == SQL_CURSOR_FORWARD_ONLY && orient != SQL_FETCH_NEXT) {
16472  setstat(s, -1, "wrong fetch direction", "01000");
16473  ret = SQL_ERROR;
16474  i = 0;
16475  goto done2;
16476  }
16477  ret = SQL_SUCCESS;
16478  i = 0;
16479  if (((DBC *) (s->dbc))->cur_s3stmt == s && s->s3stmt) {
16480  s->rowp = s->rowprs = 0;
16481  for (; i < s->rowset_size; i++) {
16482  if (s->max_rows && s->s3stmt_rownum + 1 >= s->max_rows) {
16483  ret = (i == 0) ? SQL_NO_DATA : SQL_SUCCESS;
16484  break;
16485  }
16486  ret = s3stmt_step(s);
16487  if (ret != SQL_SUCCESS) {
16488  s->row_status0[i] = SQL_ROW_ERROR;
16489  break;
16490  }
16491  if (s->nrows < 1) {
16492  break;
16493  }
16494  ret = dofetchbind(s, i);
16495  if (!SQL_SUCCEEDED(ret)) {
16496  break;
16497  } else if (ret == SQL_SUCCESS_WITH_INFO) {
16498  withinfo = 1;
16499  }
16500  }
16501  } else if (s->rows) {
16502  switch (orient) {
16503  case SQL_FETCH_NEXT:
16504  if (s->nrows < 1) {
16505  return SQL_NO_DATA;
16506  }
16507  if (s->rowp < 0) {
16508  s->rowp = -1;
16509  }
16510  if (s->rowp >= s->nrows) {
16511  s->rowp = s->rowprs = s->nrows;
16512  return SQL_NO_DATA;
16513  }
16514  break;
16515  case SQL_FETCH_PRIOR:
16516  if (s->nrows < 1 || s->rowp <= 0) {
16517  s->rowp = s->rowprs = -1;
16518  return SQL_NO_DATA;
16519  }
16520  s->rowp -= s->rowset_size + 1;
16521  if (s->rowp < -1) {
16522  s->rowp = s->rowprs = -1;
16523  return SQL_NO_DATA;
16524  }
16525  break;
16526  case SQL_FETCH_FIRST:
16527  if (s->nrows < 1) {
16528  return SQL_NO_DATA;
16529  }
16530  s->rowp = -1;
16531  break;
16532  case SQL_FETCH_LAST:
16533  if (s->nrows < 1) {
16534  return SQL_NO_DATA;
16535  }
16536  s->rowp = s->nrows - s->rowset_size;
16537  if (--s->rowp < -1) {
16538  s->rowp = -1;
16539  }
16540  break;
16541  case SQL_FETCH_ABSOLUTE:
16542  if (offset == 0) {
16543  s->rowp = s->rowprs = -1;
16544  return SQL_NO_DATA;
16545  } else if (offset < 0) {
16546  if (0 - offset <= s->nrows) {
16547  s->rowp = s->nrows + offset - 1;
16548  break;
16549  }
16550  s->rowp = s->rowprs = -1;
16551  return SQL_NO_DATA;
16552  } else if (offset > s->nrows) {
16553  s->rowp = s->rowprs = s->nrows;
16554  return SQL_NO_DATA;
16555  }
16556  s->rowp = offset - 1 - 1;
16557  break;
16558  case SQL_FETCH_RELATIVE:
16559  if (offset >= 0) {
16560  s->rowp += offset * s->rowset_size - 1;
16561  if (s->rowp >= s->nrows) {
16562  s->rowp = s->rowprs = s->nrows;
16563  return SQL_NO_DATA;
16564  }
16565  } else {
16566  s->rowp += offset * s->rowset_size - 1;
16567  if (s->rowp < -1) {
16568  s->rowp = s->rowprs = -1;
16569  return SQL_NO_DATA;
16570  }
16571  }
16572  break;
16573  case SQL_FETCH_BOOKMARK:
16574  if (s->bkmrk == SQL_UB_ON && !s->bkmrkptr) {
16575  if (offset < 0 || offset >= s->nrows) {
16576  return SQL_NO_DATA;
16577  }
16578  s->rowp = offset - 1;
16579  break;
16580  }
16581  if (s->bkmrk != SQL_UB_OFF && s->bkmrkptr) {
16582  int rowp;
16583 
16584  if (s->bkmrk == SQL_UB_VARIABLE) {
16585  if (s->has_rowid >= 0) {
16586  sqlite_int64 bkmrk, rowid;
16587 
16588  bkmrk = *(sqlite_int64 *) s->bkmrkptr;
16589  for (rowp = 0; rowp < s->nrows; rowp++) {
16590  char **data, *endp = 0;
16591 
16592  data = s->rows + s->ncols + (rowp * s->ncols)
16593  + s->has_rowid;
16594 #ifdef __osf__
16595  rowid = strtol(*data, &endp, 0);
16596 #else
16597  rowid = strtoll(*data, &endp, 0);
16598 #endif
16599  if (rowid == bkmrk) {
16600  break;
16601  }
16602  }
16603  } else {
16604  rowp = *(sqlite_int64 *) s->bkmrkptr;
16605  }
16606  } else {
16607  rowp = *(int *) s->bkmrkptr;
16608  }
16609  if (rowp + offset < 0 || rowp + offset >= s->nrows) {
16610  return SQL_NO_DATA;
16611  }
16612  s->rowp = rowp + offset - 1;
16613  break;
16614  }
16615  /* fall through */
16616  default:
16617  s->row_status0[0] = SQL_ROW_ERROR;
16618  ret = SQL_ERROR;
16619  goto done;
16620  }
16621  s->rowprs = s->rowp + 1;
16622  for (; i < s->rowset_size; i++) {
16623  ++s->rowp;
16624  if (s->rowp < 0 || s->rowp >= s->nrows) {
16625  break;
16626  }
16627  ret = dofetchbind(s, i);
16628  if (!SQL_SUCCEEDED(ret)) {
16629  break;
16630  } else if (ret == SQL_SUCCESS_WITH_INFO) {
16631  withinfo = 1;
16632  }
16633  }
16634  }
16635 done:
16636  if (i == 0) {
16637  if (SQL_SUCCEEDED(ret)) {
16638  return SQL_NO_DATA;
16639  }
16640  return ret;
16641  }
16642  if (SQL_SUCCEEDED(ret)) {
16643  ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16644  }
16645 done2:
16646  if (s->row_status) {
16647  memcpy(s->row_status, s->row_status0,
16648  sizeof (SQLUSMALLINT) * s->rowset_size);
16649  }
16650  s->row_count0 = i;
16651  if (s->row_count) {
16652  *s->row_count = s->row_count0;
16653  }
16654  return ret;
16655 }
16656 
16663 SQLRETURN SQL_API
16664 SQLFetch(SQLHSTMT stmt)
16665 {
16666  SQLRETURN ret;
16667 
16668  HSTMT_LOCK(stmt);
16669  ret = drvfetchscroll(stmt, SQL_FETCH_NEXT, 0);
16670  HSTMT_UNLOCK(stmt);
16671  return ret;
16672 }
16673 
16682 SQLRETURN SQL_API
16683 SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLLEN offset)
16684 {
16685  SQLRETURN ret;
16686 
16687  HSTMT_LOCK(stmt);
16688  ret = drvfetchscroll(stmt, orient, offset);
16689  HSTMT_UNLOCK(stmt);
16690  return ret;
16691 }
16692 
16703 SQLRETURN SQL_API
16704 SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT orient, SQLROWOFFSET offset,
16705  SQLROWSETSIZE *rowcount, SQLUSMALLINT *rowstatus)
16706 {
16707  STMT *s;
16708  SQLRETURN ret;
16709  SQLUSMALLINT *rst;
16710  SQLINTEGER *bkmrkptr;
16711 
16712  HSTMT_LOCK(stmt);
16713  if (stmt == SQL_NULL_HSTMT) {
16714  return SQL_INVALID_HANDLE;
16715  }
16716  s = (STMT *) stmt;
16717  /* temporarily turn off SQL_ATTR_ROW_STATUS_PTR */
16718  rst = s->row_status;
16719  s->row_status = 0;
16720  bkmrkptr = s->bkmrkptr;
16721  s->bkmrkptr = 0;
16722  ret = drvfetchscroll(stmt, orient, offset);
16723  s->row_status = rst;
16724  s->bkmrkptr = bkmrkptr;
16725  if (rowstatus) {
16726  memcpy(rowstatus, s->row_status0,
16727  sizeof (SQLUSMALLINT) * s->rowset_size);
16728  }
16729  if (rowcount) {
16730  *rowcount = s->row_count0;
16731  }
16732  HSTMT_UNLOCK(stmt);
16733  return ret;
16734 }
16735 
16743 SQLRETURN SQL_API
16744 SQLRowCount(SQLHSTMT stmt, SQLLEN *nrows)
16745 {
16746  STMT *s;
16747 
16748  HSTMT_LOCK(stmt);
16749  if (stmt == SQL_NULL_HSTMT) {
16750  return SQL_INVALID_HANDLE;
16751  }
16752  s = (STMT *) stmt;
16753  if (nrows) {
16754  *nrows = s->isselect ? 0 : s->nrows;
16755  }
16756  HSTMT_UNLOCK(stmt);
16757  return SQL_SUCCESS;
16758 }
16759 
16767 SQLRETURN SQL_API
16768 SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *ncols)
16769 {
16770  STMT *s;
16771 
16772  HSTMT_LOCK(stmt);
16773  if (stmt == SQL_NULL_HSTMT) {
16774  return SQL_INVALID_HANDLE;
16775  }
16776  s = (STMT *) stmt;
16777  if (ncols) {
16778  *ncols = s->ncols;
16779  }
16780  HSTMT_UNLOCK(stmt);
16781  return SQL_SUCCESS;
16782 }
16783 
16798 static SQLRETURN
16799 drvdescribecol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
16800  SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
16801  SQLSMALLINT *type, SQLULEN *size,
16802  SQLSMALLINT *digits, SQLSMALLINT *nullable)
16803 {
16804  STMT *s;
16805  COL *c;
16806  int didname = 0;
16807 
16808  if (stmt == SQL_NULL_HSTMT) {
16809  return SQL_INVALID_HANDLE;
16810  }
16811  s = (STMT *) stmt;
16812  if (!s->cols) {
16813  setstat(s, -1, "no columns", (*s->ov3) ? "07009" : "S1002");
16814  return SQL_ERROR;
16815  }
16816  if (col < 1 || col > s->ncols) {
16817  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
16818  return SQL_ERROR;
16819  }
16820  c = s->cols + col - 1;
16821  if (name && nameMax > 0) {
16822  strncpy((char *) name, c->column, nameMax);
16823  name[nameMax - 1] = '\0';
16824  didname = 1;
16825  }
16826  if (nameLen) {
16827  if (didname) {
16828  *nameLen = strlen((char *) name);
16829  } else {
16830  *nameLen = strlen(c->column);
16831  }
16832  }
16833  if (type) {
16834  *type = c->type;
16835 #ifdef WINTERFACE
16836  if (s->nowchar[0] || s->nowchar[1]) {
16837  switch (c->type) {
16838  case SQL_WCHAR:
16839  *type = SQL_CHAR;
16840  break;
16841  case SQL_WVARCHAR:
16842  *type = SQL_VARCHAR;
16843  break;
16844 #ifdef SQL_LONGVARCHAR
16845  case SQL_WLONGVARCHAR:
16846  *type = SQL_LONGVARCHAR;
16847  break;
16848 #endif
16849  }
16850  }
16851 #endif
16852  }
16853  if (size) {
16854  *size = c->size;
16855  }
16856  if (digits) {
16857  *digits = 0;
16858  }
16859  if (nullable) {
16860  *nullable = 1;
16861  }
16862  return SQL_SUCCESS;
16863 }
16864 
16865 #ifndef WINTERFACE
16866 
16880 SQLRETURN SQL_API
16881 SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
16882  SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
16883  SQLSMALLINT *type, SQLULEN *size,
16884  SQLSMALLINT *digits, SQLSMALLINT *nullable)
16885 {
16886 #if defined(_WIN32) || defined(_WIN64)
16887  SQLSMALLINT len = 0;
16888 #endif
16889  SQLRETURN ret;
16890 
16891  HSTMT_LOCK(stmt);
16892 #if defined(_WIN32) || defined(_WIN64)
16893  if (!((STMT *) stmt)->oemcp[0]) {
16894  ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
16895  type, size, digits, nullable);
16896  goto done;
16897  }
16898  ret = drvdescribecol(stmt, col, name, nameMax,
16899  &len, type, size, digits, nullable);
16900  if (ret == SQL_SUCCESS) {
16901  if (name) {
16902  if (len > 0) {
16903  SQLCHAR *n = NULL;
16904 
16905  n = (SQLCHAR *) utf_to_wmb((char *) name, len);
16906  if (n) {
16907  strncpy((char *) name, (char *) n, nameMax);
16908  n[len] = 0;
16909  len = min(nameMax, strlen((char *) n));
16910  uc_free(n);
16911  } else {
16912  len = 0;
16913  }
16914  }
16915  if (len <= 0) {
16916  len = 0;
16917  if (nameMax > 0) {
16918  name[0] = 0;
16919  }
16920  }
16921  } else {
16922  STMT *s = (STMT *) stmt;
16923  COL *c = s->cols + col - 1;
16924 
16925  len = 0;
16926  if (c->column) {
16927  len = strlen(c->column);
16928  }
16929  }
16930  if (nameLen) {
16931  *nameLen = len;
16932  }
16933  }
16934 done:
16935  ;
16936 #else
16937  ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
16938  type, size, digits, nullable);
16939 #endif
16940  HSTMT_UNLOCK(stmt);
16941  return ret;
16942 }
16943 #endif
16944 
16945 #ifdef WINTERFACE
16946 
16960 SQLRETURN SQL_API
16961 SQLDescribeColW(SQLHSTMT stmt, SQLUSMALLINT col, SQLWCHAR *name,
16962  SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
16963  SQLSMALLINT *type, SQLULEN *size,
16964  SQLSMALLINT *digits, SQLSMALLINT *nullable)
16965 {
16966  SQLRETURN ret;
16967  SQLSMALLINT len = 0;
16968 
16969  HSTMT_LOCK(stmt);
16970  ret = drvdescribecol(stmt, col, (SQLCHAR *) name,
16971  (SQLSMALLINT) (nameMax * sizeof (SQLWCHAR)),
16972  &len, type, size, digits, nullable);
16973  if (ret == SQL_SUCCESS) {
16974  if (name) {
16975  if (len > 0) {
16976  SQLWCHAR *n = NULL;
16977 
16978  n = uc_from_utf((SQLCHAR *) name, len);
16979  if (n) {
16980  uc_strncpy(name, n, nameMax);
16981  n[len] = 0;
16982  len = min(nameMax, uc_strlen(n));
16983  uc_free(n);
16984  } else {
16985  len = 0;
16986  }
16987  }
16988  if (len <= 0) {
16989  len = 0;
16990  if (nameMax > 0) {
16991  name[0] = 0;
16992  }
16993  }
16994  } else {
16995  STMT *s = (STMT *) stmt;
16996  COL *c = s->cols + col - 1;
16997 
16998  len = 0;
16999  if (c->column) {
17000  len = strlen(c->column);
17001  }
17002  }
17003  if (nameLen) {
17004  *nameLen = len;
17005  }
17006  }
17007  HSTMT_UNLOCK(stmt);
17008  return ret;
17009 }
17010 #endif
17011 
17024 static SQLRETURN
17025 drvcolattributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17026  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17027  SQLLEN *val2)
17028 {
17029  STMT *s;
17030  COL *c;
17031  SQLSMALLINT dummy;
17032  char *valc = (char *) val;
17033 
17034  if (stmt == SQL_NULL_HSTMT) {
17035  return SQL_INVALID_HANDLE;
17036  }
17037  s = (STMT *) stmt;
17038  if (!s->cols) {
17039  return SQL_ERROR;
17040  }
17041  if (!valLen) {
17042  valLen = &dummy;
17043  }
17044  if (id == SQL_COLUMN_COUNT) {
17045  if (val2) {
17046  *val2 = s->ncols;
17047  }
17048  *valLen = sizeof (int);
17049  return SQL_SUCCESS;
17050  }
17051  if (id == SQL_COLUMN_TYPE && col == 0) {
17052  if (val2) {
17053  *val2 = SQL_INTEGER;
17054  }
17055  *valLen = sizeof (int);
17056  return SQL_SUCCESS;
17057  }
17058 #ifdef SQL_DESC_OCTET_LENGTH
17059  if (id == SQL_DESC_OCTET_LENGTH && col == 0) {
17060  if (val2) {
17061  *val2 = 4;
17062  }
17063  *valLen = sizeof (int);
17064  return SQL_SUCCESS;
17065  }
17066 #endif
17067  if (col < 1 || col > s->ncols) {
17068  setstat(s, -1, "invalid column", (*s->ov3) ? "07009": "S1002");
17069  return SQL_ERROR;
17070  }
17071  c = s->cols + col - 1;
17072 
17073  switch (id) {
17074  case SQL_COLUMN_LABEL:
17075  if (c->label) {
17076  if (valc && valMax > 0) {
17077  strncpy(valc, c->label, valMax);
17078  valc[valMax - 1] = '\0';
17079  }
17080  *valLen = strlen(c->label);
17081  goto checkLen;
17082  }
17083  /* fall through */
17084  case SQL_COLUMN_NAME:
17085  case SQL_DESC_NAME:
17086  if (valc && valMax > 0) {
17087  strncpy(valc, c->column, valMax);
17088  valc[valMax - 1] = '\0';
17089  }
17090  *valLen = strlen(c->column);
17091 checkLen:
17092  if (*valLen >= valMax) {
17093  setstat(s, -1, "data right truncated", "01004");
17094  return SQL_SUCCESS_WITH_INFO;
17095  }
17096  return SQL_SUCCESS;
17097 #ifdef SQL_DESC_BASE_COLUMN_NAME
17098  case SQL_DESC_BASE_COLUMN_NAME:
17099  if (strchr(c->column, '(') || strchr(c->column, ')')) {
17100  if (valc && valMax > 0) {
17101  valc[0] = '\0';
17102  }
17103  *valLen = 0;
17104  } else if (valc && valMax > 0) {
17105  strncpy(valc, c->column, valMax);
17106  valc[valMax - 1] = '\0';
17107  *valLen = strlen(c->column);
17108  }
17109  goto checkLen;
17110 #endif
17111  case SQL_COLUMN_TYPE:
17112  case SQL_DESC_TYPE:
17113 #ifdef WINTERFACE
17114  {
17115  int type = c->type;
17116 
17117  if (s->nowchar[0] || s->nowchar[1]) {
17118  switch (type) {
17119  case SQL_WCHAR:
17120  type = SQL_CHAR;
17121  break;
17122  case SQL_WVARCHAR:
17123  type = SQL_VARCHAR;
17124  break;
17125 #ifdef SQL_LONGVARCHAR
17126  case SQL_WLONGVARCHAR:
17127  type = SQL_LONGVARCHAR;
17128  break;
17129  }
17130  }
17131  if (val2) {
17132  *val2 = type;
17133  }
17134 #endif
17135  }
17136 #else
17137  if (val2) {
17138  *val2 = c->type;
17139  }
17140 #endif
17141  *valLen = sizeof (int);
17142  return SQL_SUCCESS;
17143  case SQL_COLUMN_DISPLAY_SIZE:
17144  if (val2) {
17145  *val2 = c->size;
17146  }
17147  *valLen = sizeof (int);
17148  return SQL_SUCCESS;
17149  case SQL_COLUMN_UNSIGNED:
17150  if (val2) {
17151  *val2 = c->nosign ? SQL_TRUE : SQL_FALSE;
17152  }
17153  *valLen = sizeof (int);
17154  return SQL_SUCCESS;
17155  case SQL_COLUMN_SCALE:
17156  case SQL_DESC_SCALE:
17157  if (val2) {
17158  *val2 = c->scale;
17159  }
17160  *valLen = sizeof (int);
17161  return SQL_SUCCESS;
17162  case SQL_COLUMN_PRECISION:
17163  case SQL_DESC_PRECISION:
17164  if (val2) {
17165  switch (c->type) {
17166  case SQL_SMALLINT:
17167  *val2 = 5;
17168  break;
17169  case SQL_INTEGER:
17170  *val2 = 10;
17171  break;
17172  case SQL_FLOAT:
17173  case SQL_REAL:
17174  case SQL_DOUBLE:
17175  *val2 = 15;
17176  break;
17177  case SQL_DATE:
17178  *val2 = 0;
17179  break;
17180  case SQL_TIME:
17181  *val2 = 0;
17182  break;
17183 #ifdef SQL_TYPE_TIMESTAMP
17184  case SQL_TYPE_TIMESTAMP:
17185 #endif
17186  case SQL_TIMESTAMP:
17187  *val2 = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
17188  break;
17189  default:
17190  *val2 = c->prec;
17191  break;
17192  }
17193  }
17194  *valLen = sizeof (int);
17195  return SQL_SUCCESS;
17196  case SQL_COLUMN_MONEY:
17197  if (val2) {
17198  *val2 = SQL_FALSE;
17199  }
17200  *valLen = sizeof (int);
17201  return SQL_SUCCESS;
17202  case SQL_COLUMN_AUTO_INCREMENT:
17203  if (val2) {
17204  *val2 = c->autoinc;
17205  }
17206  *valLen = sizeof (int);
17207  return SQL_SUCCESS;
17208  case SQL_COLUMN_LENGTH:
17209  case SQL_DESC_LENGTH:
17210  if (val2) {
17211  *val2 = c->size;
17212  }
17213  *valLen = sizeof (int);
17214  return SQL_SUCCESS;
17215  case SQL_COLUMN_NULLABLE:
17216  case SQL_DESC_NULLABLE:
17217  if (val2) {
17218  *val2 = c->notnull;
17219  }
17220  *valLen = sizeof (int);
17221  return SQL_SUCCESS;
17222  case SQL_COLUMN_SEARCHABLE:
17223  if (val2) {
17224  *val2 = SQL_SEARCHABLE;
17225  }
17226  *valLen = sizeof (int);
17227  return SQL_SUCCESS;
17228  case SQL_COLUMN_CASE_SENSITIVE:
17229  if (val2) {
17230  *val2 = SQL_TRUE;
17231  }
17232  *valLen = sizeof (int);
17233  return SQL_SUCCESS;
17234  case SQL_COLUMN_UPDATABLE:
17235  if (val2) {
17236  *val2 = SQL_TRUE;
17237  }
17238  *valLen = sizeof (int);
17239  return SQL_SUCCESS;
17240  case SQL_DESC_COUNT:
17241  if (val2) {
17242  *val2 = s->ncols;
17243  }
17244  *valLen = sizeof (int);
17245  return SQL_SUCCESS;
17246  case SQL_COLUMN_TYPE_NAME: {
17247  char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17248 
17249 #ifdef WINTERFACE
17250  if (c->type == SQL_WCHAR ||
17251  c->type == SQL_WVARCHAR ||
17252  c->type == SQL_WLONGVARCHAR) {
17253  if (!(s->nowchar[0] || s->nowchar[1])) {
17254  if (strcasecmp(tn, "varchar") == 0) {
17255  tn = "wvarchar";
17256  }
17257  }
17258  }
17259 #endif
17260  if (valc && valMax > 0) {
17261  strncpy(valc, tn, valMax);
17262  valc[valMax - 1] = '\0';
17263  p = strchr(valc, '(');
17264  if (p) {
17265  *p = '\0';
17266  while (p > valc && ISSPACE(p[-1])) {
17267  --p;
17268  *p = '\0';
17269  }
17270  }
17271  *valLen = strlen(valc);
17272  } else {
17273  *valLen = strlen(tn);
17274  p = strchr(tn, '(');
17275  if (p) {
17276  *valLen = p - tn;
17277  while (p > tn && ISSPACE(p[-1])) {
17278  --p;
17279  *valLen -= 1;
17280  }
17281  }
17282  }
17283  goto checkLen;
17284  }
17285  case SQL_COLUMN_OWNER_NAME:
17286  case SQL_COLUMN_QUALIFIER_NAME: {
17287  char *z = "";
17288 
17289  if (valc && valMax > 0) {
17290  strncpy(valc, z, valMax);
17291  valc[valMax - 1] = '\0';
17292  }
17293  *valLen = strlen(z);
17294  goto checkLen;
17295  }
17296  case SQL_COLUMN_TABLE_NAME:
17297 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17298  case SQL_DESC_TABLE_NAME:
17299 #endif
17300 #ifdef SQL_DESC_BASE_TABLE_NAME
17301  case SQL_DESC_BASE_TABLE_NAME:
17302 #endif
17303  if (valc && valMax > 0) {
17304  strncpy(valc, c->table, valMax);
17305  valc[valMax - 1] = '\0';
17306  }
17307  *valLen = strlen(c->table);
17308  goto checkLen;
17309 #ifdef SQL_DESC_NUM_PREC_RADIX
17310  case SQL_DESC_NUM_PREC_RADIX:
17311  if (val2) {
17312  switch (c->type) {
17313 #ifdef WINTERFACE
17314  case SQL_WCHAR:
17315  case SQL_WVARCHAR:
17316 #ifdef SQL_LONGVARCHAR
17317  case SQL_WLONGVARCHAR:
17318 #endif
17319 #endif
17320  case SQL_CHAR:
17321  case SQL_VARCHAR:
17322 #ifdef SQL_LONGVARCHAR
17323  case SQL_LONGVARCHAR:
17324 #endif
17325  case SQL_BINARY:
17326  case SQL_VARBINARY:
17327  case SQL_LONGVARBINARY:
17328  *val2 = 0;
17329  break;
17330  default:
17331  *val2 = 2;
17332  }
17333  }
17334  *valLen = sizeof (int);
17335  return SQL_SUCCESS;
17336 #endif
17337  }
17338  setstat(s, -1, "unsupported column attributes %d", "HY091", id);
17339  return SQL_ERROR;
17340 }
17341 
17342 #ifndef WINTERFACE
17343 
17355 SQLRETURN SQL_API
17356 SQLColAttributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17357  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17358  SQLLEN *val2)
17359 {
17360 #if defined(_WIN32) || defined(_WIN64)
17361  SQLSMALLINT len = 0;
17362 #endif
17363  SQLRETURN ret;
17364 
17365  HSTMT_LOCK(stmt);
17366 #if defined(_WIN32) || defined(_WIN64)
17367  if (!((STMT *) stmt)->oemcp[0]) {
17368  ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17369  goto done;
17370  }
17371  ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17372  if (SQL_SUCCEEDED(ret)) {
17373  char *v = NULL;
17374 
17375  switch (id) {
17376  case SQL_COLUMN_LABEL:
17377  case SQL_COLUMN_NAME:
17378  case SQL_DESC_NAME:
17379  case SQL_COLUMN_TYPE_NAME:
17380  case SQL_COLUMN_OWNER_NAME:
17381  case SQL_COLUMN_QUALIFIER_NAME:
17382  case SQL_COLUMN_TABLE_NAME:
17383 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17384  case SQL_DESC_TABLE_NAME:
17385 #endif
17386 #ifdef SQL_DESC_BASE_COLUMN_NAME
17387  case SQL_DESC_BASE_COLUMN_NAME:
17388 #endif
17389 #ifdef SQL_DESC_BASE_TABLE_NAME
17390  case SQL_DESC_BASE_TABLE_NAME:
17391 #endif
17392  if (val && valMax > 0) {
17393  int vmax = valMax;
17394 
17395  v = utf_to_wmb((char *) val, SQL_NTS);
17396  if (v) {
17397  strncpy(val, v, vmax);
17398  len = min(vmax, strlen(v));
17399  uc_free(v);
17400  }
17401  if (vmax > 0) {
17402  v = (char *) val;
17403  v[vmax - 1] = '\0';
17404  }
17405  }
17406  if (len <= 0) {
17407  len = 0;
17408  }
17409  break;
17410  }
17411  if (valLen) {
17412  *valLen = len;
17413  }
17414  }
17415 done:
17416  ;
17417 #else
17418  ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17419 #endif
17420  HSTMT_UNLOCK(stmt);
17421  return ret;
17422 }
17423 #endif
17424 
17425 #ifdef WINTERFACE
17426 
17438 SQLRETURN SQL_API
17439 SQLColAttributesW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17440  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17441  SQLLEN *val2)
17442 {
17443  SQLRETURN ret;
17444  SQLSMALLINT len = 0;
17445 
17446  HSTMT_LOCK(stmt);
17447  ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17448  if (SQL_SUCCEEDED(ret)) {
17449  SQLWCHAR *v = NULL;
17450 
17451  switch (id) {
17452  case SQL_COLUMN_LABEL:
17453  case SQL_COLUMN_NAME:
17454  case SQL_DESC_NAME:
17455  case SQL_COLUMN_TYPE_NAME:
17456  case SQL_COLUMN_OWNER_NAME:
17457  case SQL_COLUMN_QUALIFIER_NAME:
17458  case SQL_COLUMN_TABLE_NAME:
17459 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17460  case SQL_DESC_TABLE_NAME:
17461 #endif
17462 #ifdef SQL_DESC_BASE_COLUMN_NAME
17463  case SQL_DESC_BASE_COLUMN_NAME:
17464 #endif
17465 #ifdef SQL_DESC_BASE_TABLE_NAME
17466  case SQL_DESC_BASE_TABLE_NAME:
17467 #endif
17468  if (val && valMax > 0) {
17469  int vmax = valMax / sizeof (SQLWCHAR);
17470 
17471  v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
17472  if (v) {
17473  uc_strncpy(val, v, vmax);
17474  len = min(vmax, uc_strlen(v));
17475  uc_free(v);
17476  len *= sizeof (SQLWCHAR);
17477  }
17478  if (vmax > 0) {
17479  v = (SQLWCHAR *) val;
17480  v[vmax - 1] = '\0';
17481  }
17482  }
17483  if (len <= 0) {
17484  len = 0;
17485  }
17486  break;
17487  }
17488  if (valLen) {
17489  *valLen = len;
17490  }
17491  }
17492  HSTMT_UNLOCK(stmt);
17493  return ret;
17494 }
17495 #endif
17496 
17509 static SQLRETURN
17510 drvcolattribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17511  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17512  SQLPOINTER val2)
17513 {
17514  STMT *s;
17515  COL *c;
17516  int v = 0;
17517  char *valc = (char *) val;
17518  SQLSMALLINT dummy;
17519 
17520  if (stmt == SQL_NULL_HSTMT) {
17521  return SQL_INVALID_HANDLE;
17522  }
17523  s = (STMT *) stmt;
17524  if (!s->cols) {
17525  return SQL_ERROR;
17526  }
17527  if (col < 1 || col > s->ncols) {
17528  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
17529  return SQL_ERROR;
17530  }
17531  if (!valLen) {
17532  valLen = &dummy;
17533  }
17534  c = s->cols + col - 1;
17535  switch (id) {
17536  case SQL_DESC_COUNT:
17537  v = s->ncols;
17538  break;
17539  case SQL_DESC_CATALOG_NAME:
17540  if (valc && valMax > 0) {
17541  strncpy(valc, c->db, valMax);
17542  valc[valMax - 1] = '\0';
17543  }
17544  *valLen = strlen(c->db);
17545 checkLen:
17546  if (*valLen >= valMax) {
17547  setstat(s, -1, "data right truncated", "01004");
17548  return SQL_SUCCESS_WITH_INFO;
17549  }
17550  break;
17551  case SQL_COLUMN_LENGTH:
17552  case SQL_DESC_LENGTH:
17553  v = c->size;
17554  break;
17555  case SQL_COLUMN_LABEL:
17556  if (c->label) {
17557  if (valc && valMax > 0) {
17558  strncpy(valc, c->label, valMax);
17559  valc[valMax - 1] = '\0';
17560  }
17561  *valLen = strlen(c->label);
17562  goto checkLen;
17563  }
17564  /* fall through */
17565  case SQL_COLUMN_NAME:
17566  case SQL_DESC_NAME:
17567  if (valc && valMax > 0) {
17568  strncpy(valc, c->column, valMax);
17569  valc[valMax - 1] = '\0';
17570  }
17571  *valLen = strlen(c->column);
17572  goto checkLen;
17573  case SQL_DESC_SCHEMA_NAME: {
17574  char *z = "";
17575 
17576  if (valc && valMax > 0) {
17577  strncpy(valc, z, valMax);
17578  valc[valMax - 1] = '\0';
17579  }
17580  *valLen = strlen(z);
17581  goto checkLen;
17582  }
17583 #ifdef SQL_DESC_BASE_COLUMN_NAME
17584  case SQL_DESC_BASE_COLUMN_NAME:
17585  if (strchr(c->column, '(') || strchr(c->column, ')')) {
17586  valc[0] = '\0';
17587  *valLen = 0;
17588  } else if (valc && valMax > 0) {
17589  strncpy(valc, c->column, valMax);
17590  valc[valMax - 1] = '\0';
17591  *valLen = strlen(c->column);
17592  }
17593  goto checkLen;
17594 #endif
17595  case SQL_DESC_TYPE_NAME: {
17596  char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17597 
17598 #ifdef WINTERFACE
17599  if (c->type == SQL_WCHAR ||
17600  c->type == SQL_WVARCHAR ||
17601  c->type == SQL_WLONGVARCHAR) {
17602  if (!(s->nowchar[0] || s->nowchar[1])) {
17603  if (strcasecmp(tn, "varchar") == 0) {
17604  tn = "wvarchar";
17605  }
17606  }
17607  }
17608 #endif
17609  if (valc && valMax > 0) {
17610  strncpy(valc, tn, valMax);
17611  valc[valMax - 1] = '\0';
17612  p = strchr(valc, '(');
17613  if (p) {
17614  *p = '\0';
17615  while (p > valc && ISSPACE(p[-1])) {
17616  --p;
17617  *p = '\0';
17618  }
17619  }
17620  *valLen = strlen(valc);
17621  } else {
17622  *valLen = strlen(tn);
17623  p = strchr(tn, '(');
17624  if (p) {
17625  *valLen = p - tn;
17626  while (p > tn && ISSPACE(p[-1])) {
17627  --p;
17628  *valLen -= 1;
17629  }
17630  }
17631  }
17632  goto checkLen;
17633  }
17634  case SQL_DESC_OCTET_LENGTH:
17635  v = c->size;
17636 #ifdef WINTERFACE
17637  if (c->type == SQL_WCHAR ||
17638  c->type == SQL_WVARCHAR ||
17639  c->type == SQL_WLONGVARCHAR) {
17640  if (!(s->nowchar[0] || s->nowchar[1])) {
17641  v *= sizeof (SQLWCHAR);
17642  }
17643  }
17644 #endif
17645  break;
17646 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17647  case SQL_COLUMN_TABLE_NAME:
17648 #endif
17649 #ifdef SQL_DESC_BASE_TABLE_NAME
17650  case SQL_DESC_BASE_TABLE_NAME:
17651 #endif
17652  case SQL_DESC_TABLE_NAME:
17653  if (valc && valMax > 0) {
17654  strncpy(valc, c->table, valMax);
17655  valc[valMax - 1] = '\0';
17656  }
17657  *valLen = strlen(c->table);
17658  goto checkLen;
17659  case SQL_DESC_TYPE:
17660  v = c->type;
17661 #ifdef WINTERFACE
17662  if (s->nowchar[0] || s->nowchar[1]) {
17663  switch (v) {
17664  case SQL_WCHAR:
17665  v = SQL_CHAR;
17666  break;
17667  case SQL_WVARCHAR:
17668  v = SQL_VARCHAR;
17669  break;
17670 #ifdef SQL_LONGVARCHAR
17671  case SQL_WLONGVARCHAR:
17672  v = SQL_LONGVARCHAR;
17673  break;
17674 #endif
17675  }
17676  }
17677 #endif
17678  break;
17679  case SQL_DESC_CONCISE_TYPE:
17680  switch (c->type) {
17681  case SQL_INTEGER:
17682  v = SQL_C_LONG;
17683  break;
17684  case SQL_TINYINT:
17685  v = SQL_C_TINYINT;
17686  break;
17687  case SQL_SMALLINT:
17688  v = SQL_C_SHORT;
17689  break;
17690  case SQL_FLOAT:
17691  v = SQL_C_FLOAT;
17692  break;
17693  case SQL_DOUBLE:
17694  v = SQL_C_DOUBLE;
17695  break;
17696  case SQL_TIMESTAMP:
17697  v = SQL_C_TIMESTAMP;
17698  break;
17699  case SQL_TIME:
17700  v = SQL_C_TIME;
17701  break;
17702  case SQL_DATE:
17703  v = SQL_C_DATE;
17704  break;
17705 #ifdef SQL_C_TYPE_TIMESTAMP
17706  case SQL_TYPE_TIMESTAMP:
17707  v = SQL_C_TYPE_TIMESTAMP;
17708  break;
17709 #endif
17710 #ifdef SQL_C_TYPE_TIME
17711  case SQL_TYPE_TIME:
17712  v = SQL_C_TYPE_TIME;
17713  break;
17714 #endif
17715 #ifdef SQL_C_TYPE_DATE
17716  case SQL_TYPE_DATE:
17717  v = SQL_C_TYPE_DATE;
17718  break;
17719 #endif
17720 #ifdef SQL_BIT
17721  case SQL_BIT:
17722  v = SQL_C_BIT;
17723  break;
17724 #endif
17725 #ifdef SQL_BIGINT
17726  case SQL_BIGINT:
17727  v = SQL_C_SBIGINT;
17728  break;
17729 #endif
17730  default:
17731 #ifdef WINTERFACE
17732  v = (s->nowchar[0] || s->nowchar[1]) ? SQL_C_CHAR : SQL_C_WCHAR;
17733 #else
17734  v = SQL_C_CHAR;
17735 #endif
17736  break;
17737  }
17738  break;
17739  case SQL_DESC_UPDATABLE:
17740  v = SQL_TRUE;
17741  break;
17742  case SQL_COLUMN_DISPLAY_SIZE:
17743  v = c->size;
17744  break;
17745  case SQL_COLUMN_UNSIGNED:
17746  v = c->nosign ? SQL_TRUE : SQL_FALSE;
17747  break;
17748  case SQL_COLUMN_SEARCHABLE:
17749  v = SQL_SEARCHABLE;
17750  break;
17751  case SQL_COLUMN_SCALE:
17752  case SQL_DESC_SCALE:
17753  v = c->scale;
17754  break;
17755  case SQL_COLUMN_PRECISION:
17756  case SQL_DESC_PRECISION:
17757  switch (c->type) {
17758  case SQL_SMALLINT:
17759  v = 5;
17760  break;
17761  case SQL_INTEGER:
17762  v = 10;
17763  break;
17764  case SQL_FLOAT:
17765  case SQL_REAL:
17766  case SQL_DOUBLE:
17767  v = 15;
17768  break;
17769  case SQL_DATE:
17770  v = 0;
17771  break;
17772  case SQL_TIME:
17773  v = 0;
17774  break;
17775 #ifdef SQL_TYPE_TIMESTAMP
17776  case SQL_TYPE_TIMESTAMP:
17777 #endif
17778  case SQL_TIMESTAMP:
17779  v = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
17780  break;
17781  default:
17782  v = c->prec;
17783  break;
17784  }
17785  break;
17786  case SQL_COLUMN_MONEY:
17787  v = SQL_FALSE;
17788  break;
17789  case SQL_COLUMN_AUTO_INCREMENT:
17790  v = c->autoinc;
17791  break;
17792  case SQL_DESC_NULLABLE:
17793  v = c->notnull;
17794  break;
17795 #ifdef SQL_DESC_NUM_PREC_RADIX
17796  case SQL_DESC_NUM_PREC_RADIX:
17797  switch (c->type) {
17798 #ifdef WINTERFACE
17799  case SQL_WCHAR:
17800  case SQL_WVARCHAR:
17801 #ifdef SQL_LONGVARCHAR
17802  case SQL_WLONGVARCHAR:
17803 #endif
17804 #endif
17805  case SQL_CHAR:
17806  case SQL_VARCHAR:
17807 #ifdef SQL_LONGVARCHAR
17808  case SQL_LONGVARCHAR:
17809 #endif
17810  case SQL_BINARY:
17811  case SQL_VARBINARY:
17812  case SQL_LONGVARBINARY:
17813  v = 0;
17814  break;
17815  default:
17816  v = 2;
17817  }
17818  break;
17819 #endif
17820  default:
17821  setstat(s, -1, "unsupported column attribute %d", "HY091", id);
17822  return SQL_ERROR;
17823  }
17824  if (val2) {
17825  *(SQLLEN *) val2 = v;
17826  }
17827  return SQL_SUCCESS;
17828 }
17829 
17830 #ifndef WINTERFACE
17831 
17843 SQLRETURN SQL_API
17844 SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17845  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17847 {
17848 #if defined(_WIN32) || defined(_WIN64)
17849  SQLSMALLINT len = 0;
17850 #endif
17851  SQLRETURN ret;
17852 
17853  HSTMT_LOCK(stmt);
17854 #if defined(_WIN32) || defined(_WIN64)
17855  if (!((STMT *) stmt)->oemcp[0]) {
17856  ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
17857  (SQLPOINTER) val2);
17858  goto done;
17859  }
17860  ret = drvcolattribute(stmt, col, id, val, valMax, &len,
17861  (SQLPOINTER) val2);
17862  if (SQL_SUCCEEDED(ret)) {
17863  char *v = NULL;
17864 
17865  switch (id) {
17866  case SQL_DESC_SCHEMA_NAME:
17867  case SQL_DESC_CATALOG_NAME:
17868  case SQL_COLUMN_LABEL:
17869  case SQL_DESC_NAME:
17870  case SQL_DESC_TABLE_NAME:
17871 #ifdef SQL_DESC_BASE_TABLE_NAME
17872  case SQL_DESC_BASE_TABLE_NAME:
17873 #endif
17874 #ifdef SQL_DESC_BASE_COLUMN_NAME
17875  case SQL_DESC_BASE_COLUMN_NAME:
17876 #endif
17877  case SQL_DESC_TYPE_NAME:
17878  if (val && valMax > 0) {
17879  int vmax = valMax;
17880 
17881  v = utf_to_wmb((char *) val, SQL_NTS);
17882  if (v) {
17883  strncpy(val, v, vmax);
17884  len = min(vmax, strlen(v));
17885  uc_free(v);
17886  }
17887  if (vmax > 0) {
17888  v = (char *) val;
17889  v[vmax - 1] = '\0';
17890  }
17891  }
17892  if (len <= 0) {
17893  len = 0;
17894  }
17895  break;
17896  }
17897  if (valLen) {
17898  *valLen = len;
17899  }
17900  }
17901 done:
17902  ;
17903 #else
17904  ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
17905  (SQLPOINTER) val2);
17906 #endif
17907  HSTMT_UNLOCK(stmt);
17908  return ret;
17909 }
17910 #endif
17911 
17912 #ifdef WINTERFACE
17913 
17925 SQLRETURN SQL_API
17926 SQLColAttributeW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17927  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17929 {
17930  SQLRETURN ret;
17931  SQLSMALLINT len = 0;
17932 
17933  HSTMT_LOCK(stmt);
17934  ret = drvcolattribute(stmt, col, id, val, valMax, &len,
17935  (SQLPOINTER) val2);
17936  if (SQL_SUCCEEDED(ret)) {
17937  SQLWCHAR *v = NULL;
17938 
17939  switch (id) {
17940  case SQL_DESC_SCHEMA_NAME:
17941  case SQL_DESC_CATALOG_NAME:
17942  case SQL_COLUMN_LABEL:
17943  case SQL_DESC_NAME:
17944  case SQL_DESC_TABLE_NAME:
17945 #ifdef SQL_DESC_BASE_TABLE_NAME
17946  case SQL_DESC_BASE_TABLE_NAME:
17947 #endif
17948 #ifdef SQL_DESC_BASE_COLUMN_NAME
17949  case SQL_DESC_BASE_COLUMN_NAME:
17950 #endif
17951  case SQL_DESC_TYPE_NAME:
17952  if (val && valMax > 0) {
17953  int vmax = valMax / sizeof (SQLWCHAR);
17954 
17955  v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
17956  if (v) {
17957  uc_strncpy(val, v, vmax);
17958  len = min(vmax, uc_strlen(v));
17959  uc_free(v);
17960  len *= sizeof (SQLWCHAR);
17961  }
17962  if (vmax > 0) {
17963  v = (SQLWCHAR *) val;
17964  v[vmax - 1] = '\0';
17965  }
17966  }
17967  if (len <= 0) {
17968  len = 0;
17969  }
17970  break;
17971  }
17972  if (valLen) {
17973  *valLen = len;
17974  }
17975  }
17976  HSTMT_UNLOCK(stmt);
17977  return ret;
17978 }
17979 #endif
17980 
17994 static SQLRETURN
17995 drverror(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
17996  SQLCHAR *sqlState, SQLINTEGER *nativeErr,
17997  SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
17998 {
17999  SQLCHAR dummy0[6];
18000  SQLINTEGER dummy1;
18001  SQLSMALLINT dummy2;
18002 
18003  if (env == SQL_NULL_HENV &&
18004  dbc == SQL_NULL_HDBC &&
18005  stmt == SQL_NULL_HSTMT) {
18006  return SQL_INVALID_HANDLE;
18007  }
18008  if (sqlState) {
18009  sqlState[0] = '\0';
18010  } else {
18011  sqlState = dummy0;
18012  }
18013  if (!nativeErr) {
18014  nativeErr = &dummy1;
18015  }
18016  *nativeErr = 0;
18017  if (!errlen) {
18018  errlen = &dummy2;
18019  }
18020  *errlen = 0;
18021  if (errmsg) {
18022  if (errmax > 0) {
18023  errmsg[0] = '\0';
18024  }
18025  } else {
18026  errmsg = dummy0;
18027  errmax = 0;
18028  }
18029  if (stmt) {
18030  STMT *s = (STMT *) stmt;
18031 
18032  HSTMT_LOCK(stmt);
18033  if (s->logmsg[0] == '\0') {
18034  HSTMT_UNLOCK(stmt);
18035  goto noerr;
18036  }
18037  *nativeErr = s->naterr;
18038  strcpy((char *) sqlState, s->sqlstate);
18039  if (errmax == SQL_NTS) {
18040  strcpy((char *) errmsg, "[SQLite]");
18041  strcat((char *) errmsg, (char *) s->logmsg);
18042  *errlen = strlen((char *) errmsg);
18043  } else {
18044  strncpy((char *) errmsg, "[SQLite]", errmax);
18045  if (errmax - 8 > 0) {
18046  strncpy((char *) errmsg + 8, (char *) s->logmsg, errmax - 8);
18047  }
18048  *errlen = min(strlen((char *) s->logmsg) + 8, errmax);
18049  }
18050  s->logmsg[0] = '\0';
18051  HSTMT_UNLOCK(stmt);
18052  return SQL_SUCCESS;
18053  }
18054  if (dbc) {
18055  DBC *d = (DBC *) dbc;
18056 
18057  HDBC_LOCK(dbc);
18058  if (d->magic != DBC_MAGIC || d->logmsg[0] == '\0') {
18059  HDBC_UNLOCK(dbc);
18060  goto noerr;
18061  }
18062  *nativeErr = d->naterr;
18063  strcpy((char *) sqlState, d->sqlstate);
18064  if (errmax == SQL_NTS) {
18065  strcpy((char *) errmsg, "[SQLite]");
18066  strcat((char *) errmsg, (char *) d->logmsg);
18067  *errlen = strlen((char *) errmsg);
18068  } else {
18069  strncpy((char *) errmsg, "[SQLite]", errmax);
18070  if (errmax - 8 > 0) {
18071  strncpy((char *) errmsg + 8, (char *) d->logmsg, errmax - 8);
18072  }
18073  *errlen = min(strlen((char *) d->logmsg) + 8, errmax);
18074  }
18075  d->logmsg[0] = '\0';
18076  HDBC_UNLOCK(dbc);
18077  return SQL_SUCCESS;
18078  }
18079 noerr:
18080  sqlState[0] = '\0';
18081  errmsg[0] = '\0';
18082  *nativeErr = 0;
18083  *errlen = 0;
18084  return SQL_NO_DATA;
18085 }
18086 
18087 #ifndef WINTERFACE
18088 
18101 SQLRETURN SQL_API
18102 SQLError(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18103  SQLCHAR *sqlState, SQLINTEGER *nativeErr,
18104  SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18105 {
18106  return drverror(env, dbc, stmt, sqlState, nativeErr,
18107  errmsg, errmax, errlen);
18108 }
18109 #endif
18110 
18111 #ifdef WINTERFACE
18112 
18125 SQLRETURN SQL_API
18126 SQLErrorW(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18127  SQLWCHAR *sqlState, SQLINTEGER *nativeErr,
18128  SQLWCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18129 {
18130  char state[16];
18131  SQLSMALLINT len = 0;
18132  SQLRETURN ret;
18133 
18134  ret = drverror(env, dbc, stmt, (SQLCHAR *) state, nativeErr,
18135  (SQLCHAR *) errmsg, errmax, &len);
18136  if (ret == SQL_SUCCESS) {
18137  if (sqlState) {
18138  uc_from_utf_buf((SQLCHAR *) state, -1, sqlState,
18139  6 * sizeof (SQLWCHAR));
18140  }
18141  if (errmsg) {
18142  if (len > 0) {
18143  SQLWCHAR *e = NULL;
18144 
18145  e = uc_from_utf((SQLCHAR *) errmsg, len);
18146  if (e) {
18147  if (errmax > 0) {
18148  uc_strncpy(errmsg, e, errmax);
18149  e[len] = 0;
18150  len = min(errmax, uc_strlen(e));
18151  } else {
18152  len = uc_strlen(e);
18153  }
18154  uc_free(e);
18155  } else {
18156  len = 0;
18157  }
18158  }
18159  if (len <= 0) {
18160  len = 0;
18161  if (errmax > 0) {
18162  errmsg[0] = 0;
18163  }
18164  }
18165  } else {
18166  len = 0;
18167  }
18168  if (errlen) {
18169  *errlen = len;
18170  }
18171  } else if (ret == SQL_NO_DATA) {
18172  if (sqlState) {
18173  sqlState[0] = 0;
18174  }
18175  if (errmsg) {
18176  if (errmax > 0) {
18177  errmsg[0] = 0;
18178  }
18179  }
18180  if (errlen) {
18181  *errlen = 0;
18182  }
18183  }
18184  return ret;
18185 }
18186 #endif
18187 
18194 SQLRETURN SQL_API
18195 SQLMoreResults(SQLHSTMT stmt)
18196 {
18197  HSTMT_LOCK(stmt);
18198  if (stmt == SQL_NULL_HSTMT) {
18199  return SQL_INVALID_HANDLE;
18200  }
18201  HSTMT_UNLOCK(stmt);
18202  return SQL_NO_DATA;
18203 }
18204 
18213 static SQLRETURN
18214 setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp)
18215 {
18216  int ncols = *ncolsp, guessed_types = 0;
18217  SQLRETURN ret = SQL_SUCCESS;
18218 
18219  if (ncols > 0) {
18220  int i;
18221  PTRDIFF_T size;
18222  char *p;
18223  COL *dyncols;
18224  DBC *d = (DBC *) s->dbc;
18225  const char *colname, *typename;
18226 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18227  char *tblname;
18228 #endif
18229 
18230  for (i = size = 0; i < ncols; i++) {
18231  colname = sqlite3_column_name(s3stmt, i);
18232  size += 3 + 3 * strlen(colname);
18233  }
18234 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18235  tblname = (char *) size;
18236  for (i = 0; i < ncols; i++) {
18237  p = (char *) sqlite3_column_table_name(s3stmt, i);
18238  size += 2 + (p ? strlen(p) : 0);
18239  }
18240 #endif
18241  dyncols = xmalloc(ncols * sizeof (COL) + size);
18242  if (!dyncols) {
18243  freedyncols(s);
18244  *ncolsp = 0;
18245  ret = SQL_ERROR;
18246  } else {
18247  p = (char *) (dyncols + ncols);
18248 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18249  tblname = p + (PTRDIFF_T) tblname;
18250 #endif
18251  for (i = 0; i < ncols; i++) {
18252  char *q;
18253 
18254  colname = sqlite3_column_name(s3stmt, i);
18255  if (d->trace) {
18256  fprintf(d->trace, "-- column %d name: '%s'\n",
18257  i + 1, colname);
18258  fflush(d->trace);
18259  }
18260 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18261  q = (char *) sqlite3_column_table_name(s3stmt, i);
18262  strcpy(tblname, q ? q : "");
18263  if (d->trace) {
18264  fprintf(d->trace, "-- table %d name: '%s'\n",
18265  i + 1, tblname);
18266  fflush(d->trace);
18267  }
18268  dyncols[i].table = tblname;
18269  tblname += strlen(tblname) + 1;
18270 #endif
18271  typename = s3stmt_coltype(s3stmt, i, d, &guessed_types);
18272  dyncols[i].db = ((DBC *) (s->dbc))->dbname;
18273  strcpy(p, colname);
18274  dyncols[i].label = p;
18275  p += strlen(p) + 1;
18276  q = strchr(colname, '.');
18277  if (q) {
18278  char *q2 = strchr(q + 1, '.');
18279 
18280  /* SQLite 3.3.4 produces view.table.column sometimes */
18281  if (q2) {
18282  q = q2;
18283  }
18284  }
18285  if (q) {
18286 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18287  dyncols[i].table = p;
18288 #endif
18289  strncpy(p, colname, q - colname);
18290  p[q - colname] = '\0';
18291  p += strlen(p) + 1;
18292  strcpy(p, q + 1);
18293  dyncols[i].column = p;
18294  p += strlen(p) + 1;
18295  } else {
18296 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18297  dyncols[i].table = "";
18298 #endif
18299  strcpy(p, colname);
18300  dyncols[i].column = p;
18301  p += strlen(p) + 1;
18302  }
18303  if (s->longnames) {
18304  dyncols[i].column = dyncols[i].label;
18305  }
18306 #ifdef SQL_LONGVARCHAR
18307  dyncols[i].type = SQL_LONGVARCHAR;
18308  dyncols[i].size = 65535;
18309 #else
18310  dyncols[i].type = SQL_VARCHAR;
18311  dyncols[i].size = 255;
18312 #endif
18313  dyncols[i].index = i;
18314  dyncols[i].scale = 0;
18315  dyncols[i].prec = 0;
18316  dyncols[i].nosign = 1;
18317  dyncols[i].autoinc = SQL_FALSE;
18318  dyncols[i].notnull = SQL_NULLABLE;
18319  dyncols[i].ispk = -1;
18320  dyncols[i].isrowid = -1;
18321 #ifdef FULL_METADATA
18322  s3stmt_addmeta(s3stmt, i, d, &dyncols[i]);
18323 #endif
18324  dyncols[i].typename = xstrdup(typename);
18325  }
18326  freedyncols(s);
18327  s->dyncols = s->cols = dyncols;
18328  s->dcols = ncols;
18329  fixupdyncols(s, d);
18330  s->guessed_types = guessed_types;
18331  }
18332  }
18333  return ret;
18334 }
18335 
18344 static SQLRETURN
18345 drvprepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18346 {
18347  STMT *s;
18348  DBC *d;
18349  char *errp = NULL;
18350  SQLRETURN sret;
18351 
18352  if (stmt == SQL_NULL_HSTMT) {
18353  return SQL_INVALID_HANDLE;
18354  }
18355  s = (STMT *) stmt;
18356  if (s->dbc == SQL_NULL_HDBC) {
18357 noconn:
18358  return noconn(s);
18359  }
18360  d = s->dbc;
18361  if (!d->sqlite) {
18362  goto noconn;
18363  }
18364  s3stmt_end(s);
18365  s3stmt_drop(s);
18366  sret = starttran(s);
18367  if (sret != SQL_SUCCESS) {
18368  return sret;
18369  }
18370  freep(&s->query);
18371  s->query = (SQLCHAR *) fixupsql((char *) query, queryLen,
18372  (d->version >= 0x030805),
18373  &s->nparams, &s->isselect, &errp);
18374  if (!s->query) {
18375  if (errp) {
18376  setstat(s, -1, "%s", (*s->ov3) ? "HY000" : "S1000", errp);
18377  return SQL_ERROR;
18378  }
18379  return nomem(s);
18380  }
18381  errp = NULL;
18382  freeresult(s, -1);
18383  if (s->isselect == 1) {
18384  int ret, ncols, nretry = 0;
18385  const char *rest;
18386  sqlite3_stmt *s3stmt = NULL;
18387 
18388 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18389  dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
18390 #else
18391  dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
18392 #endif
18393  do {
18394  s3stmt = NULL;
18395 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18396  ret = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
18397  &s3stmt, &rest);
18398 #else
18399  ret = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
18400  &s3stmt, &rest);
18401 #endif
18402  if (ret != SQLITE_OK) {
18403  if (s3stmt) {
18404  sqlite3_finalize(s3stmt);
18405  s3stmt = NULL;
18406  }
18407  }
18408  } while (ret == SQLITE_SCHEMA && (++nretry) < 2);
18409  dbtracerc(d, ret, NULL);
18410  if (ret != SQLITE_OK) {
18411  if (s3stmt) {
18412  dbtraceapi(d, "sqlite3_finalize", 0);
18413  sqlite3_finalize(s3stmt);
18414  }
18415  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18416  sqlite3_errmsg(d->sqlite), ret);
18417  return SQL_ERROR;
18418  }
18419  if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
18420  dbtraceapi(d, "sqlite3_finalize", 0);
18421  sqlite3_finalize(s3stmt);
18422  setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
18423  (*s->ov3) ? "HY000" : "S1000");
18424  return SQL_ERROR;
18425  }
18426  ncols = sqlite3_column_count(s3stmt);
18427  s->guessed_types = 0;
18428  setupdyncols(s, s3stmt, &ncols);
18429  s->ncols = ncols;
18430  s->s3stmt = s3stmt;
18431  }
18432  mkbindcols(s, s->ncols);
18433  s->paramset_count = 0;
18434  return SQL_SUCCESS;
18435 }
18436 
18444 static SQLRETURN
18445 drvexecute(SQLHSTMT stmt, int initial)
18446 {
18447  STMT *s;
18448  DBC *d;
18449  char *errp = NULL;
18450  int rc, i, ncols = 0, nrows = 0, busy_count;
18451  SQLRETURN ret;
18452 
18453  if (stmt == SQL_NULL_HSTMT) {
18454  return SQL_INVALID_HANDLE;
18455  }
18456  s = (STMT *) stmt;
18457  if (s->dbc == SQL_NULL_HDBC) {
18458 noconn:
18459  return noconn(s);
18460  }
18461  d = (DBC *) s->dbc;
18462  if (!d->sqlite) {
18463  goto noconn;
18464  }
18465  if (!s->query) {
18466  setstat(s, -1, "no query prepared", (*s->ov3) ? "HY000" : "S1000");
18467  return SQL_ERROR;
18468  }
18469  if (s->nbindparms < s->nparams) {
18470 unbound:
18471  setstat(s, -1, "unbound parameters in query",
18472  (*s->ov3) ? "HY000" : "S1000");
18473  return SQL_ERROR;
18474  }
18475  for (i = 0; i < s->nparams; i++) {
18476  BINDPARM *p = &s->bindparms[i];
18477 
18478  if (!p->bound) {
18479  goto unbound;
18480  }
18481  if (initial) {
18482  SQLLEN *lenp = p->lenp;
18483 
18484  if (lenp && *lenp < 0 && *lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18485  *lenp != SQL_NTS && *lenp != SQL_NULL_DATA &&
18486  *lenp != SQL_DATA_AT_EXEC) {
18487  setstat(s, -1, "invalid length reference", "HY009");
18488  return SQL_ERROR;
18489  }
18490  if (lenp && (*lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18491  *lenp == SQL_DATA_AT_EXEC)) {
18492  p->need = 1;
18493  p->offs = 0;
18494  p->len = 0;
18495  }
18496  }
18497  }
18498  ret = starttran(s);
18499  if (ret != SQL_SUCCESS) {
18500  goto cleanup;
18501  }
18502  busy_count = 0;
18503 again:
18504  s3stmt_end(s);
18505  if (initial) {
18506  /* fixup data-at-execution parameters and alloc'ed blobs */
18507  s->pdcount = -1;
18508  for (i = 0; i < s->nparams; i++) {
18509  BINDPARM *p = &s->bindparms[i];
18510 
18511  if (p->param == p->parbuf) {
18512  p->param = NULL;
18513  }
18514  freep(&p->parbuf);
18515  if (p->need <= 0 &&
18516  p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18517  *p->lenp == SQL_DATA_AT_EXEC)) {
18518  p->need = 1;
18519  p->offs = 0;
18520  p->len = 0;
18521  }
18522  }
18523  }
18524  if (s->nparams) {
18525  for (i = 0; i < s->nparams; i++) {
18526  ret = setupparam(s, (char *) s->query, i);
18527  if (ret != SQL_SUCCESS) {
18528  goto cleanup;
18529  }
18530  }
18531  }
18532  freeresult(s, 0);
18533  if (s->isselect == 1 && !d->intrans &&
18534  s->curtype == SQL_CURSOR_FORWARD_ONLY &&
18535  d->step_enable && s->nparams == 0 && d->cur_s3stmt == NULL) {
18536  s->nrows = -1;
18537  ret = s3stmt_start(s);
18538  if (ret == SQL_SUCCESS) {
18539  goto done2;
18540  }
18541  }
18542  rc = drvgettable(s, s->s3stmt ? NULL : (char *) s->query, &s->rows,
18543  &s->nrows, &ncols, &errp, s->nparams, s->bindparms);
18544  dbtracerc(d, rc, errp);
18545  if (rc == SQLITE_BUSY) {
18546  if (busy_handler((void *) d, ++busy_count)) {
18547  if (errp) {
18548  sqlite3_free(errp);
18549  errp = NULL;
18550  }
18551  for (i = 0; i < s->nparams; i++) {
18552  BINDPARM *p = &s->bindparms[i];
18553 
18554  if (p->param == p->parbuf) {
18555  p->param = NULL;
18556  }
18557  freep(&p->parbuf);
18558  if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18559  *p->lenp != SQL_DATA_AT_EXEC)) {
18560  p->param = p->param0;
18561  }
18562  p->lenp = p->lenp0;
18563  }
18564  s->nrows = 0;
18565  goto again;
18566  }
18567  }
18568  if (rc != SQLITE_OK) {
18569  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18570  errp ? errp : "unknown error", rc);
18571  if (errp) {
18572  sqlite3_free(errp);
18573  errp = NULL;
18574  }
18575  ret = SQL_ERROR;
18576  goto cleanup;
18577  }
18578  if (errp) {
18579  sqlite3_free(errp);
18580  errp = NULL;
18581  }
18582  s->rowfree = freerows;
18583  if (s->isselect <= 0 || s->isselect > 1) {
18584  /*
18585  * INSERT/UPDATE/DELETE or DDL results are immediately released.
18586  */
18587  freeresult(s, -1);
18588  nrows += sqlite3_changes(d->sqlite);
18589  s->nrows = nrows;
18590  goto done;
18591  }
18592  if (s->ncols != ncols) {
18593  /*
18594  * Weird result.
18595  */
18596  setstat(s, -1, "broken result set %d/%d",
18597  (*s->ov3) ? "HY000" : "S1000", s->ncols, ncols);
18598  ret = SQL_ERROR;
18599  goto cleanup;
18600  }
18601 done:
18602  mkbindcols(s, s->ncols);
18603 done2:
18604  ret = SQL_SUCCESS;
18605  s->rowp = s->rowprs = -1;
18606  s->paramset_count++;
18607  s->paramset_nrows = s->nrows;
18608  if (s->paramset_count < s->paramset_size) {
18609  for (i = 0; i < s->nparams; i++) {
18610  BINDPARM *p = &s->bindparms[i];
18611 
18612  if (p->param == p->parbuf) {
18613  p->param = NULL;
18614  }
18615  freep(&p->parbuf);
18616  if (p->lenp0 &&
18617  s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18618  p->lenp = (SQLLEN *) ((char *) p->lenp0 +
18619  s->paramset_count * s->parm_bind_type);
18620  } else if (p->lenp0 && p->inc > 0) {
18621  p->lenp = p->lenp0 + s->paramset_count;
18622  }
18623  if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18624  *p->lenp != SQL_DATA_AT_EXEC)) {
18625  if (p->param0 &&
18626  s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18627  p->param = (char *) p->param0 +
18629  } else if (p->param0 && p->inc > 0) {
18630  p->param = (char *) p->param0 +
18631  s->paramset_count * p->inc;
18632  }
18633  } else if (p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18634  *p->lenp == SQL_DATA_AT_EXEC)) {
18635  p->need = 1;
18636  p->offs = 0;
18637  p->len = 0;
18638  }
18639  }
18640  goto again;
18641  }
18642 cleanup:
18643  if (ret != SQL_NEED_DATA) {
18644  for (i = 0; i < s->nparams; i++) {
18645  BINDPARM *p = &s->bindparms[i];
18646 
18647  if (p->param == p->parbuf) {
18648  p->param = NULL;
18649  }
18650  freep(&p->parbuf);
18651  if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18652  *p->lenp != SQL_DATA_AT_EXEC)) {
18653  p->param = p->param0;
18654  }
18655  p->lenp = p->lenp0;
18656  }
18657  s->nrows = s->paramset_nrows;
18658  if (s->parm_proc) {
18659  *s->parm_proc = s->paramset_count;
18660  }
18661  s->paramset_count = 0;
18662  s->paramset_nrows = 0;
18663  }
18664  /*
18665  * For INSERT/UPDATE/DELETE statements change the return code
18666  * to SQL_NO_DATA if the number of rows affected was 0.
18667  */
18668  if (*s->ov3 && s->isselect == 0 &&
18669  ret == SQL_SUCCESS && nrows == 0) {
18670  ret = SQL_NO_DATA;
18671  }
18672  return ret;
18673 }
18674 
18675 #ifndef WINTERFACE
18676 
18684 SQLRETURN SQL_API
18685 SQLPrepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18686 {
18687  SQLRETURN ret;
18688 #if defined(_WIN32) || defined(_WIN64)
18689  char *q;
18690 #endif
18691 
18692  HSTMT_LOCK(stmt);
18693 #if defined(_WIN32) || defined(_WIN64)
18694  if (!((STMT *) stmt)->oemcp[0]) {
18695  ret = drvprepare(stmt, query, queryLen);
18696  goto done;
18697  }
18698  q = wmb_to_utf_c((char *) query, queryLen);
18699  if (!q) {
18700  ret = nomem((STMT *) stmt);
18701  goto done;
18702  }
18703  query = (SQLCHAR *) q;
18704  queryLen = SQL_NTS;
18705 #endif
18706  ret = drvprepare(stmt, query, queryLen);
18707 #if defined(_WIN32) || defined(_WIN64)
18708  uc_free(q);
18709 done:
18710  ;
18711 #endif
18712  HSTMT_UNLOCK(stmt);
18713  return ret;
18714 }
18715 #endif
18716 
18717 #ifdef WINTERFACE
18718 
18726 SQLRETURN SQL_API
18727 SQLPrepareW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
18728 {
18729  SQLRETURN ret;
18730  char *q = uc_to_utf_c(query, queryLen);
18731 
18732  HSTMT_LOCK(stmt);
18733  if (!q) {
18734  ret = nomem((STMT *) stmt);
18735  goto done;
18736  }
18737  ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
18738  uc_free(q);
18739 done:
18740  HSTMT_UNLOCK(stmt);
18741  return ret;
18742 }
18743 #endif
18744 
18751 SQLRETURN SQL_API
18752 SQLExecute(SQLHSTMT stmt)
18753 {
18754  SQLRETURN ret;
18755 
18756  HSTMT_LOCK(stmt);
18757  ret = drvexecute(stmt, 1);
18758  HSTMT_UNLOCK(stmt);
18759  return ret;
18760 }
18761 
18762 #ifndef WINTERFACE
18763 
18771 SQLRETURN SQL_API
18772 SQLExecDirect(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18773 {
18774  SQLRETURN ret;
18775 #if defined(_WIN32) || defined(_WIN64)
18776  char *q;
18777 #endif
18778 
18779  HSTMT_LOCK(stmt);
18780 #if defined(_WIN32) || defined(_WIN64)
18781  if (!((STMT *) stmt)->oemcp[0]) {
18782  ret = drvprepare(stmt, query, queryLen);
18783  if (ret == SQL_SUCCESS) {
18784  ret = drvexecute(stmt, 1);
18785  }
18786  goto done;
18787  }
18788  q = wmb_to_utf_c((char *) query, queryLen);
18789  if (!q) {
18790  ret = nomem((STMT *) stmt);
18791  goto done;
18792  }
18793  query = (SQLCHAR *) q;
18794  queryLen = SQL_NTS;
18795 #endif
18796  ret = drvprepare(stmt, query, queryLen);
18797  if (ret == SQL_SUCCESS) {
18798  ret = drvexecute(stmt, 1);
18799  }
18800 #if defined(_WIN32) || defined(_WIN64)
18801  uc_free(q);
18802 done:
18803  ;
18804 #endif
18805  HSTMT_UNLOCK(stmt);
18806  return ret;
18807 }
18808 #endif
18809 
18810 #ifdef WINTERFACE
18811 
18819 SQLRETURN SQL_API
18820 SQLExecDirectW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
18821 {
18822  SQLRETURN ret;
18823  char *q = uc_to_utf_c(query, queryLen);
18824 
18825  HSTMT_LOCK(stmt);
18826  if (!q) {
18827  ret = nomem((STMT *) stmt);
18828  goto done;
18829  }
18830  ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
18831  uc_free(q);
18832  if (ret == SQL_SUCCESS) {
18833  ret = drvexecute(stmt, 1);
18834  }
18835 done:
18836  HSTMT_UNLOCK(stmt);
18837  return ret;
18838 }
18839 #endif
18840 
18841 
18842 #if defined(_WIN32) || defined(_WIN64)
18843 #ifndef WITHOUT_DRIVERMGR
18844 
18845 /*
18846  * Windows configuration dialog stuff.
18847  */
18848 
18849 #include <windowsx.h>
18850 #include <winuser.h>
18851 
18852 #define MAXPATHLEN (259+1) /* Max path length */
18853 #define MAXKEYLEN (15+1) /* Max keyword length */
18854 #define MAXDESC (255+1) /* Max description length */
18855 #define MAXDSNAME (255+1) /* Max data source name length */
18856 #define MAXTONAME (32+1) /* Max timeout length */
18857 #define MAXDBNAME MAXPATHLEN
18858 
18859 /* Attribute key indexes into an array of Attr structs, see below */
18860 
18861 #define KEY_DSN 0
18862 #define KEY_DESC 1
18863 #define KEY_DBNAME 2
18864 #define KEY_BUSY 3
18865 #define KEY_DRIVER 4
18866 #define KEY_STEPAPI 5
18867 #define KEY_SYNCP 6
18868 #define KEY_NOTXN 7
18869 #define KEY_SHORTNAM 8
18870 #define KEY_LONGNAM 9
18871 #define KEY_NOCREAT 10
18872 #define KEY_NOWCHAR 11
18873 #define KEY_LOADEXT 12
18874 #define KEY_JMODE 13
18875 #define KEY_FKSUPPORT 14
18876 #define KEY_OEMCP 15
18877 #define KEY_BIGINT 16
18878 #define KEY_PASSWD 17
18879 #define KEY_JDCONV 18
18880 #define NUMOFKEYS 19
18881 
18882 typedef struct {
18883  BOOL supplied;
18884  char attr[MAXPATHLEN*4];
18885 } ATTR;
18886 
18887 typedef struct {
18888  SQLHWND parent;
18889  LPCSTR driver;
18890  ATTR attr[NUMOFKEYS];
18891  char DSN[MAXDSNAME];
18892  BOOL newDSN;
18893  BOOL defDSN;
18894 } SETUPDLG;
18895 
18896 static struct {
18897  char *key;
18898  int ikey;
18899 } attrLookup[] = {
18900  { "DSN", KEY_DSN },
18901  { "DESC", KEY_DESC },
18902  { "Description", KEY_DESC},
18903  { "Database", KEY_DBNAME },
18904  { "Timeout", KEY_BUSY },
18905  { "Driver", KEY_DRIVER },
18906  { "StepAPI", KEY_STEPAPI },
18907  { "SyncPragma", KEY_SYNCP },
18908  { "NoTXN", KEY_NOTXN },
18909  { "ShortNames", KEY_SHORTNAM },
18910  { "LongNames", KEY_LONGNAM },
18911  { "NoCreat", KEY_NOCREAT },
18912  { "NoWCHAR", KEY_NOWCHAR },
18913  { "LoadExt", KEY_LOADEXT },
18914  { "JournalMode", KEY_JMODE },
18915  { "FKSupport", KEY_FKSUPPORT },
18916  { "OEMCP", KEY_OEMCP },
18917  { "BigInt", KEY_BIGINT },
18918  { "PWD", KEY_PASSWD },
18919  { "JDConv", KEY_JDCONV },
18920  { NULL, 0 }
18921 };
18922 
18929 static void
18930 ParseAttributes(LPCSTR attribs, SETUPDLG *setupdlg)
18931 {
18932  char *str = (char *) attribs, *start, key[MAXKEYLEN];
18933  int elem, nkey;
18934 
18935  while (*str) {
18936  start = str;
18937  if ((str = strchr(str, '=')) == NULL) {
18938  return;
18939  }
18940  elem = -1;
18941  nkey = str - start;
18942  if (nkey < sizeof (key)) {
18943  int i;
18944 
18945  memcpy(key, start, nkey);
18946  key[nkey] = '\0';
18947  for (i = 0; attrLookup[i].key; i++) {
18948  if (strcasecmp(attrLookup[i].key, key) == 0) {
18949  elem = attrLookup[i].ikey;
18950  break;
18951  }
18952  }
18953  }
18954  start = ++str;
18955  while (*str && *str != ';') {
18956  ++str;
18957  }
18958  if (elem >= 0) {
18959  int end = min(str - start, sizeof (setupdlg->attr[elem].attr) - 1);
18960 
18961  setupdlg->attr[elem].supplied = TRUE;
18962  memcpy(setupdlg->attr[elem].attr, start, end);
18963  setupdlg->attr[elem].attr[end] = '\0';
18964  }
18965  ++str;
18966  }
18967 }
18968 
18976 static BOOL
18977 SetDSNAttributes(HWND parent, SETUPDLG *setupdlg)
18978 {
18979  char *dsn = setupdlg->attr[KEY_DSN].attr;
18980 
18981  if (setupdlg->newDSN && strlen(dsn) == 0) {
18982  return FALSE;
18983  }
18984  if (!SQLWriteDSNToIni(dsn, setupdlg->driver)) {
18985  if (parent) {
18986  char buf[MAXPATHLEN], msg[MAXPATHLEN];
18987 
18988  LoadString(hModule, IDS_BADDSN, buf, sizeof (buf));
18989  wsprintf(msg, buf, dsn);
18990  LoadString(hModule, IDS_MSGTITLE, buf, sizeof (buf));
18991  MessageBox(parent, msg, buf,
18992  MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
18993  MB_SETFOREGROUND);
18994  }
18995  return FALSE;
18996  }
18997  if (parent || setupdlg->attr[KEY_DESC].supplied) {
18998  SQLWritePrivateProfileString(dsn, "Description",
18999  setupdlg->attr[KEY_DESC].attr,
19000  ODBC_INI);
19001  }
19002  if (parent || setupdlg->attr[KEY_DBNAME].supplied) {
19003  SQLWritePrivateProfileString(dsn, "Database",
19004  setupdlg->attr[KEY_DBNAME].attr,
19005  ODBC_INI);
19006  }
19007  if (parent || setupdlg->attr[KEY_BUSY].supplied) {
19008  SQLWritePrivateProfileString(dsn, "Timeout",
19009  setupdlg->attr[KEY_BUSY].attr,
19010  ODBC_INI);
19011  }
19012  if (parent || setupdlg->attr[KEY_STEPAPI].supplied) {
19013  SQLWritePrivateProfileString(dsn, "StepAPI",
19014  setupdlg->attr[KEY_STEPAPI].attr,
19015  ODBC_INI);
19016  }
19017  if (parent || setupdlg->attr[KEY_SYNCP].supplied) {
19018  SQLWritePrivateProfileString(dsn, "SyncPragma",
19019  setupdlg->attr[KEY_SYNCP].attr,
19020  ODBC_INI);
19021  }
19022  if (parent || setupdlg->attr[KEY_NOTXN].supplied) {
19023  SQLWritePrivateProfileString(dsn, "NoTXN",
19024  setupdlg->attr[KEY_NOTXN].attr,
19025  ODBC_INI);
19026  }
19027  if (parent || setupdlg->attr[KEY_SHORTNAM].supplied) {
19028  SQLWritePrivateProfileString(dsn, "ShortNames",
19029  setupdlg->attr[KEY_SHORTNAM].attr,
19030  ODBC_INI);
19031  }
19032  if (parent || setupdlg->attr[KEY_LONGNAM].supplied) {
19033  SQLWritePrivateProfileString(dsn, "LongNames",
19034  setupdlg->attr[KEY_LONGNAM].attr,
19035  ODBC_INI);
19036  }
19037  if (parent || setupdlg->attr[KEY_NOCREAT].supplied) {
19038  SQLWritePrivateProfileString(dsn, "NoCreat",
19039  setupdlg->attr[KEY_NOCREAT].attr,
19040  ODBC_INI);
19041  }
19042  if (parent || setupdlg->attr[KEY_NOWCHAR].supplied) {
19043  SQLWritePrivateProfileString(dsn, "NoWCHAR",
19044  setupdlg->attr[KEY_NOWCHAR].attr,
19045  ODBC_INI);
19046  }
19047  if (parent || setupdlg->attr[KEY_FKSUPPORT].supplied) {
19048  SQLWritePrivateProfileString(dsn, "FKSupport",
19049  setupdlg->attr[KEY_FKSUPPORT].attr,
19050  ODBC_INI);
19051  }
19052  if (parent || setupdlg->attr[KEY_OEMCP].supplied) {
19053  SQLWritePrivateProfileString(dsn, "OEMCP",
19054  setupdlg->attr[KEY_OEMCP].attr,
19055  ODBC_INI);
19056  }
19057  if (parent || setupdlg->attr[KEY_LOADEXT].supplied) {
19058  SQLWritePrivateProfileString(dsn, "LoadExt",
19059  setupdlg->attr[KEY_LOADEXT].attr,
19060  ODBC_INI);
19061  }
19062  if (parent || setupdlg->attr[KEY_BIGINT].supplied) {
19063  SQLWritePrivateProfileString(dsn, "BigInt",
19064  setupdlg->attr[KEY_BIGINT].attr,
19065  ODBC_INI);
19066  }
19067  if (parent || setupdlg->attr[KEY_JDCONV].supplied) {
19068  SQLWritePrivateProfileString(dsn, "JDConv",
19069  setupdlg->attr[KEY_JDCONV].attr,
19070  ODBC_INI);
19071  }
19072  if (parent || setupdlg->attr[KEY_PASSWD].supplied) {
19073  SQLWritePrivateProfileString(dsn, "PWD",
19074  setupdlg->attr[KEY_PASSWD].attr,
19075  ODBC_INI);
19076  }
19077  if (setupdlg->attr[KEY_DSN].supplied &&
19078  strcasecmp(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr)) {
19079  SQLRemoveDSNFromIni(setupdlg->DSN);
19080  }
19081  return TRUE;
19082 }
19083 
19089 static void
19090 GetAttributes(SETUPDLG *setupdlg)
19091 {
19092  char *dsn = setupdlg->attr[KEY_DSN].attr;
19093 
19094  if (!setupdlg->attr[KEY_DESC].supplied) {
19095  SQLGetPrivateProfileString(dsn, "Description", "",
19096  setupdlg->attr[KEY_DESC].attr,
19097  sizeof (setupdlg->attr[KEY_DESC].attr),
19098  ODBC_INI);
19099  }
19100  if (!setupdlg->attr[KEY_DBNAME].supplied) {
19101  SQLGetPrivateProfileString(dsn, "Database", "",
19102  setupdlg->attr[KEY_DBNAME].attr,
19103  sizeof (setupdlg->attr[KEY_DBNAME].attr),
19104  ODBC_INI);
19105  }
19106  if (!setupdlg->attr[KEY_BUSY].supplied) {
19107  SQLGetPrivateProfileString(dsn, "Timeout", "100000",
19108  setupdlg->attr[KEY_BUSY].attr,
19109  sizeof (setupdlg->attr[KEY_BUSY].attr),
19110  ODBC_INI);
19111  }
19112  if (!setupdlg->attr[KEY_STEPAPI].supplied) {
19113  SQLGetPrivateProfileString(dsn, "StepAPI", "0",
19114  setupdlg->attr[KEY_STEPAPI].attr,
19115  sizeof (setupdlg->attr[KEY_STEPAPI].attr),
19116  ODBC_INI);
19117  }
19118  if (!setupdlg->attr[KEY_SYNCP].supplied) {
19119  SQLGetPrivateProfileString(dsn, "SyncPragma", "NORMAL",
19120  setupdlg->attr[KEY_SYNCP].attr,
19121  sizeof (setupdlg->attr[KEY_SYNCP].attr),
19122  ODBC_INI);
19123  }
19124  if (!setupdlg->attr[KEY_NOTXN].supplied) {
19125  SQLGetPrivateProfileString(dsn, "NoTXN", "",
19126  setupdlg->attr[KEY_NOTXN].attr,
19127  sizeof (setupdlg->attr[KEY_NOTXN].attr),
19128  ODBC_INI);
19129  }
19130  if (!setupdlg->attr[KEY_SHORTNAM].supplied) {
19131  SQLGetPrivateProfileString(dsn, "ShortNames", "",
19132  setupdlg->attr[KEY_SHORTNAM].attr,
19133  sizeof (setupdlg->attr[KEY_SHORTNAM].attr),
19134  ODBC_INI);
19135  }
19136  if (!setupdlg->attr[KEY_LONGNAM].supplied) {
19137  SQLGetPrivateProfileString(dsn, "LongNames", "",
19138  setupdlg->attr[KEY_LONGNAM].attr,
19139  sizeof (setupdlg->attr[KEY_LONGNAM].attr),
19140  ODBC_INI);
19141  }
19142  if (!setupdlg->attr[KEY_NOCREAT].supplied) {
19143  SQLGetPrivateProfileString(dsn, "NoCreat", "",
19144  setupdlg->attr[KEY_NOCREAT].attr,
19145  sizeof (setupdlg->attr[KEY_NOCREAT].attr),
19146  ODBC_INI);
19147  }
19148  if (!setupdlg->attr[KEY_NOWCHAR].supplied) {
19149  SQLGetPrivateProfileString(dsn, "NoWCHAR", "",
19150  setupdlg->attr[KEY_NOWCHAR].attr,
19151  sizeof (setupdlg->attr[KEY_NOWCHAR].attr),
19152  ODBC_INI);
19153  }
19154  if (!setupdlg->attr[KEY_FKSUPPORT].supplied) {
19155  SQLGetPrivateProfileString(dsn, "FKSupport", "",
19156  setupdlg->attr[KEY_FKSUPPORT].attr,
19157  sizeof (setupdlg->attr[KEY_FKSUPPORT].attr),
19158  ODBC_INI);
19159  }
19160  if (!setupdlg->attr[KEY_OEMCP].supplied) {
19161  SQLGetPrivateProfileString(dsn, "OEMCP", "",
19162  setupdlg->attr[KEY_OEMCP].attr,
19163  sizeof (setupdlg->attr[KEY_OEMCP].attr),
19164  ODBC_INI);
19165  }
19166  if (!setupdlg->attr[KEY_LOADEXT].supplied) {
19167  SQLGetPrivateProfileString(dsn, "LoadExt", "",
19168  setupdlg->attr[KEY_LOADEXT].attr,
19169  sizeof (setupdlg->attr[KEY_LOADEXT].attr),
19170  ODBC_INI);
19171  }
19172  if (!setupdlg->attr[KEY_JMODE].supplied) {
19173  SQLGetPrivateProfileString(dsn, "JournalMode", "",
19174  setupdlg->attr[KEY_JMODE].attr,
19175  sizeof (setupdlg->attr[KEY_JMODE].attr),
19176  ODBC_INI);
19177  }
19178  if (!setupdlg->attr[KEY_BIGINT].supplied) {
19179  SQLGetPrivateProfileString(dsn, "BigInt", "",
19180  setupdlg->attr[KEY_BIGINT].attr,
19181  sizeof (setupdlg->attr[KEY_BIGINT].attr),
19182  ODBC_INI);
19183  }
19184  if (!setupdlg->attr[KEY_PASSWD].supplied) {
19185  SQLGetPrivateProfileString(dsn, "PWD", "",
19186  setupdlg->attr[KEY_PASSWD].attr,
19187  sizeof (setupdlg->attr[KEY_PASSWD].attr),
19188  ODBC_INI);
19189  }
19190  if (!setupdlg->attr[KEY_JDCONV].supplied) {
19191  SQLGetPrivateProfileString(dsn, "JDConv", "",
19192  setupdlg->attr[KEY_JDCONV].attr,
19193  sizeof (setupdlg->attr[KEY_JDCONV].attr),
19194  ODBC_INI);
19195  }
19196 }
19197 
19203 static void
19204 GetDBFile(HWND hdlg)
19205 {
19206 #ifdef _WIN64
19207  SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19208 #else
19209  SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19210 #endif
19211  OPENFILENAME ofn;
19212 
19213  memset(&ofn, 0, sizeof (ofn));
19214  ofn.lStructSize = sizeof (ofn);
19215  ofn.hwndOwner = hdlg;
19216 #ifdef _WIN64
19217  ofn.hInstance = (HINSTANCE) GetWindowLongPtr(hdlg, GWLP_HINSTANCE);
19218 #else
19219  ofn.hInstance = (HINSTANCE) GetWindowLong(hdlg, GWL_HINSTANCE);
19220 #endif
19221  ofn.lpstrFile = (LPTSTR) setupdlg->attr[KEY_DBNAME].attr;
19222  ofn.nMaxFile = MAXPATHLEN;
19223  ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST |
19224  OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_FILEMUSTEXIST;
19225  if (GetOpenFileName(&ofn)) {
19226  SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19227  setupdlg->attr[KEY_DBNAME].supplied = TRUE;
19228  }
19229 }
19230 
19240 static BOOL CALLBACK
19241 ConfigDlgProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19242 {
19243  SETUPDLG *setupdlg = NULL;
19244  WORD index;
19245 
19246  switch (wmsg) {
19247  case WM_INITDIALOG:
19248 #ifdef _WIN64
19249  SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19250 #else
19251  SetWindowLong(hdlg, DWL_USER, lparam);
19252 #endif
19253  setupdlg = (SETUPDLG *) lparam;
19254  GetAttributes(setupdlg);
19255  SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19256  SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19257  SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19258  SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19259  SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19260  SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19261  (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19262  SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19263  (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19264  SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19265  (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19266  SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19267  (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19268  SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19269  (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19270  CheckDlgButton(hdlg, IDC_STEPAPI,
19271  getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19272  BST_CHECKED : BST_UNCHECKED);
19273  CheckDlgButton(hdlg, IDC_NOTXN,
19274  getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19275  BST_CHECKED : BST_UNCHECKED);
19276  CheckDlgButton(hdlg, IDC_SHORTNAM,
19277  getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19278  BST_CHECKED : BST_UNCHECKED);
19279  CheckDlgButton(hdlg, IDC_LONGNAM,
19280  getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19281  BST_CHECKED : BST_UNCHECKED);
19282  CheckDlgButton(hdlg, IDC_NOCREAT,
19283  getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19284  BST_CHECKED : BST_UNCHECKED);
19285  CheckDlgButton(hdlg, IDC_NOWCHAR,
19286  getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19287  BST_CHECKED : BST_UNCHECKED);
19288  CheckDlgButton(hdlg, IDC_FKSUPPORT,
19289  getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19290  BST_CHECKED : BST_UNCHECKED);
19291  CheckDlgButton(hdlg, IDC_OEMCP,
19292  getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19293  BST_CHECKED : BST_UNCHECKED);
19294  CheckDlgButton(hdlg, IDC_BIGINT,
19295  getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19296  BST_CHECKED : BST_UNCHECKED);
19297  CheckDlgButton(hdlg, IDC_JDCONV,
19298  getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19299  BST_CHECKED : BST_UNCHECKED);
19300  SendDlgItemMessage(hdlg, IDC_SYNCP,
19301  CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19302  SendDlgItemMessage(hdlg, IDC_SYNCP,
19303  CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19304  SendDlgItemMessage(hdlg, IDC_SYNCP,
19305  CB_ADDSTRING, 0, (LPARAM) "OFF");
19306  SendDlgItemMessage(hdlg, IDC_SYNCP,
19307  CB_ADDSTRING, 0, (LPARAM) "FULL");
19308  SendDlgItemMessage(hdlg, IDC_SYNCP,
19309  CB_SELECTSTRING, (WPARAM) -1,
19310  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19311  if (setupdlg->defDSN) {
19312  EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19313  EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19314  }
19315  return TRUE;
19316  case WM_COMMAND:
19317  switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19318  case IDC_DSNAME:
19319  if (GET_WM_COMMAND_CMD(wparam, lparam) == EN_CHANGE) {
19320  char item[MAXDSNAME];
19321 
19322  EnableWindow(GetDlgItem(hdlg, IDOK),
19323  GetDlgItemText(hdlg, IDC_DSNAME,
19324  item, sizeof (item)));
19325  return TRUE;
19326  }
19327  break;
19328  case IDC_BROWSE:
19329  GetDBFile(hdlg);
19330  break;
19331  case IDOK:
19332 #ifdef _WIN64
19333  setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19334 #else
19335  setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19336 #endif
19337  if (!setupdlg->defDSN) {
19338  GetDlgItemText(hdlg, IDC_DSNAME,
19339  setupdlg->attr[KEY_DSN].attr,
19340  sizeof (setupdlg->attr[KEY_DSN].attr));
19341  }
19342  GetDlgItemText(hdlg, IDC_DESC,
19343  setupdlg->attr[KEY_DESC].attr,
19344  sizeof (setupdlg->attr[KEY_DESC].attr));
19345  GetDlgItemText(hdlg, IDC_DBNAME,
19346  setupdlg->attr[KEY_DBNAME].attr,
19347  sizeof (setupdlg->attr[KEY_DBNAME].attr));
19348  GetDlgItemText(hdlg, IDC_TONAME,
19349  setupdlg->attr[KEY_BUSY].attr,
19350  sizeof (setupdlg->attr[KEY_BUSY].attr));
19351  GetDlgItemText(hdlg, IDC_LOADEXT,
19352  setupdlg->attr[KEY_LOADEXT].attr,
19353  sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19354  index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19355  CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19356  if (index != (WORD) CB_ERR) {
19357  SendDlgItemMessage(hdlg, IDC_SYNCP,
19358  CB_GETLBTEXT, index,
19359  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19360  }
19361  strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19362  (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19363  "1" : "0");
19364  strcpy(setupdlg->attr[KEY_NOTXN].attr,
19365  (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19366  "1" : "0");
19367  strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19368  (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19369  "1" : "0");
19370  strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19371  (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19372  "1" : "0");
19373  strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19374  (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19375  "1" : "0");
19376  strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19377  (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19378  "1" : "0");
19379  strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19380  (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19381  "1" : "0");
19382  strcpy(setupdlg->attr[KEY_OEMCP].attr,
19383  (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19384  "1" : "0");
19385  strcpy(setupdlg->attr[KEY_BIGINT].attr,
19386  (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19387  "1" : "0");
19388  strcpy(setupdlg->attr[KEY_JDCONV].attr,
19389  (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19390  "1" : "0");
19391  SetDSNAttributes(hdlg, setupdlg);
19392  /* FALL THROUGH */
19393  case IDCANCEL:
19394  EndDialog(hdlg, wparam);
19395  return TRUE;
19396  }
19397  break;
19398  }
19399  return FALSE;
19400 }
19401 
19411 BOOL INSTAPI
19412 ConfigDSN(HWND hwnd, WORD request, LPCSTR driver, LPCSTR attribs)
19413 {
19414  BOOL success;
19415  SETUPDLG *setupdlg;
19416 
19417  setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
19418  if (setupdlg == NULL) {
19419  return FALSE;
19420  }
19421  memset(setupdlg, 0, sizeof (SETUPDLG));
19422  if (attribs) {
19423  ParseAttributes(attribs, setupdlg);
19424  }
19425  if (setupdlg->attr[KEY_DSN].supplied) {
19426  strcpy(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr);
19427  } else {
19428  setupdlg->DSN[0] = '\0';
19429  }
19430  if (request == ODBC_REMOVE_DSN) {
19431  if (!setupdlg->attr[KEY_DSN].supplied) {
19432  success = FALSE;
19433  } else {
19434  success = SQLRemoveDSNFromIni(setupdlg->attr[KEY_DSN].attr);
19435  }
19436  } else {
19437  setupdlg->parent = hwnd;
19438  setupdlg->driver = driver;
19439  setupdlg->newDSN = request == ODBC_ADD_DSN;
19440  setupdlg->defDSN = strcasecmp(setupdlg->attr[KEY_DSN].attr,
19441  "Default") == 0;
19442  if (hwnd) {
19443  success = DialogBoxParam(hModule, MAKEINTRESOURCE(CONFIGDSN),
19444  hwnd, (DLGPROC) ConfigDlgProc,
19445  (LPARAM) setupdlg) == IDOK;
19446  } else if (setupdlg->attr[KEY_DSN].supplied) {
19447  success = SetDSNAttributes(hwnd, setupdlg);
19448  } else {
19449  success = FALSE;
19450  }
19451  }
19452  xfree(setupdlg);
19453  return success;
19454 }
19455 
19465 static BOOL CALLBACK
19466 DriverConnectProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19467 {
19468  SETUPDLG *setupdlg;
19469  WORD index;
19470 
19471  switch (wmsg) {
19472  case WM_INITDIALOG:
19473 #ifdef _WIN64
19474  SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19475 #else
19476  SetWindowLong(hdlg, DWL_USER, lparam);
19477 #endif
19478  setupdlg = (SETUPDLG *) lparam;
19479  SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19480  SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19481  SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19482  SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19483  SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19484  SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19485  (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19486  SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19487  (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19488  SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19489  (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19490  SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19491  (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19492  SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19493  (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19494  CheckDlgButton(hdlg, IDC_STEPAPI,
19495  getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19496  BST_CHECKED : BST_UNCHECKED);
19497  CheckDlgButton(hdlg, IDC_NOTXN,
19498  getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19499  BST_CHECKED : BST_UNCHECKED);
19500  CheckDlgButton(hdlg, IDC_SHORTNAM,
19501  getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19502  BST_CHECKED : BST_UNCHECKED);
19503  CheckDlgButton(hdlg, IDC_LONGNAM,
19504  getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19505  BST_CHECKED : BST_UNCHECKED);
19506  CheckDlgButton(hdlg, IDC_NOCREAT,
19507  getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19508  BST_CHECKED : BST_UNCHECKED);
19509  CheckDlgButton(hdlg, IDC_NOWCHAR,
19510  getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19511  BST_CHECKED : BST_UNCHECKED);
19512  CheckDlgButton(hdlg, IDC_FKSUPPORT,
19513  getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19514  BST_CHECKED : BST_UNCHECKED);
19515  CheckDlgButton(hdlg, IDC_OEMCP,
19516  getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19517  BST_CHECKED : BST_UNCHECKED);
19518  CheckDlgButton(hdlg, IDC_BIGINT,
19519  getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19520  BST_CHECKED : BST_UNCHECKED);
19521  CheckDlgButton(hdlg, IDC_JDCONV,
19522  getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19523  BST_CHECKED : BST_UNCHECKED);
19524  SendDlgItemMessage(hdlg, IDC_SYNCP,
19525  CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19526  SendDlgItemMessage(hdlg, IDC_SYNCP,
19527  CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19528  SendDlgItemMessage(hdlg, IDC_SYNCP,
19529  CB_ADDSTRING, 0, (LPARAM) "OFF");
19530  SendDlgItemMessage(hdlg, IDC_SYNCP,
19531  CB_ADDSTRING, 0, (LPARAM) "FULL");
19532  SendDlgItemMessage(hdlg, IDC_SYNCP,
19533  CB_SELECTSTRING, (WORD) -1,
19534  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19535  if (setupdlg->defDSN) {
19536  EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19537  EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19538  }
19539  return TRUE;
19540  case WM_COMMAND:
19541  switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19542  case IDC_BROWSE:
19543  GetDBFile(hdlg);
19544  break;
19545  case IDOK:
19546 #ifdef _WIN64
19547  setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19548 #else
19549  setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19550 #endif
19551  GetDlgItemText(hdlg, IDC_DSNAME,
19552  setupdlg->attr[KEY_DSN].attr,
19553  sizeof (setupdlg->attr[KEY_DSN].attr));
19554  GetDlgItemText(hdlg, IDC_DBNAME,
19555  setupdlg->attr[KEY_DBNAME].attr,
19556  sizeof (setupdlg->attr[KEY_DBNAME].attr));
19557  GetDlgItemText(hdlg, IDC_TONAME,
19558  setupdlg->attr[KEY_BUSY].attr,
19559  sizeof (setupdlg->attr[KEY_BUSY].attr));
19560  GetDlgItemText(hdlg, IDC_LOADEXT,
19561  setupdlg->attr[KEY_LOADEXT].attr,
19562  sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19563  index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19564  CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19565  if (index != (WORD) CB_ERR) {
19566  SendDlgItemMessage(hdlg, IDC_SYNCP,
19567  CB_GETLBTEXT, index,
19568  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19569  }
19570  strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19571  (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19572  "1" : "0");
19573  strcpy(setupdlg->attr[KEY_NOTXN].attr,
19574  (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19575  "1" : "0");
19576  strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19577  (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19578  "1" : "0");
19579  strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19580  (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19581  "1" : "0");
19582  strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19583  (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19584  "1" : "0");
19585  strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19586  (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19587  "1" : "0");
19588  strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19589  (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19590  "1" : "0");
19591  strcpy(setupdlg->attr[KEY_OEMCP].attr,
19592  (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19593  "1" : "0");
19594  strcpy(setupdlg->attr[KEY_BIGINT].attr,
19595  (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19596  "1" : "0");
19597  strcpy(setupdlg->attr[KEY_JDCONV].attr,
19598  (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19599  "1" : "0");
19600  /* FALL THROUGH */
19601  case IDCANCEL:
19602  EndDialog(hdlg, GET_WM_COMMAND_ID(wparam, lparam) == IDOK);
19603  return TRUE;
19604  }
19605  }
19606  return FALSE;
19607 }
19608 
19622 static SQLRETURN
19623 drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
19624  SQLCHAR *connIn, SQLSMALLINT connInLen,
19625  SQLCHAR *connOut, SQLSMALLINT connOutMax,
19626  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19627 {
19628  BOOL maybeprompt, prompt = FALSE, defaultdsn = FALSE;
19629  DBC *d;
19630  SETUPDLG *setupdlg;
19631  SQLRETURN ret;
19632  char *dsn = NULL, *driver = NULL, *dbname = NULL;
19633 
19634  if (dbc == SQL_NULL_HDBC) {
19635  return SQL_INVALID_HANDLE;
19636  }
19637  d = (DBC *) dbc;
19638  if (d->sqlite) {
19639  setstatd(d, -1, "connection already established", "08002");
19640  return SQL_ERROR;
19641  }
19642  setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
19643  if (setupdlg == NULL) {
19644  return SQL_ERROR;
19645  }
19646  memset(setupdlg, 0, sizeof (SETUPDLG));
19647  maybeprompt = drvcompl == SQL_DRIVER_COMPLETE ||
19648  drvcompl == SQL_DRIVER_COMPLETE_REQUIRED;
19649  if (connIn == NULL || !connInLen ||
19650  (connInLen == SQL_NTS && !connIn[0])) {
19651  prompt = TRUE;
19652  } else {
19653  ParseAttributes((LPCSTR) connIn, setupdlg);
19654  if (!setupdlg->attr[KEY_DSN].attr[0] &&
19655  drvcompl == SQL_DRIVER_COMPLETE_REQUIRED) {
19656  strcpy(setupdlg->attr[KEY_DSN].attr, "DEFAULT");
19657  defaultdsn = TRUE;
19658  }
19659  GetAttributes(setupdlg);
19660  if (drvcompl == SQL_DRIVER_PROMPT ||
19661  (maybeprompt &&
19662  !setupdlg->attr[KEY_DBNAME].attr[0])) {
19663  prompt = TRUE;
19664  }
19665  }
19666 retry:
19667  if (prompt) {
19668  short dlgret;
19669 
19670  setupdlg->defDSN = setupdlg->attr[KEY_DRIVER].attr[0] != '\0';
19671  dlgret = DialogBoxParam(hModule, MAKEINTRESOURCE(DRIVERCONNECT),
19672  hwnd, (DLGPROC) DriverConnectProc,
19673  (LPARAM) setupdlg);
19674 
19675  if (!dlgret || dlgret == -1) {
19676  xfree(setupdlg);
19677  return SQL_NO_DATA;
19678  }
19679  }
19680  dsn = setupdlg->attr[KEY_DSN].attr;
19681  driver = setupdlg->attr[KEY_DRIVER].attr;
19682  dbname = setupdlg->attr[KEY_DBNAME].attr;
19683  if (connOut || connOutLen) {
19684  char buf[SQL_MAX_MESSAGE_LENGTH * 8];
19685  int len, count;
19686  char dsn_0 = (dsn && !defaultdsn) ? dsn[0] : '\0';
19687  char drv_0 = driver ? driver[0] : '\0';
19688 
19689  buf[0] = '\0';
19690  count = snprintf(buf, sizeof (buf),
19691  "%s%s%s%s%s%sDatabase=%s;StepAPI=%s;"
19692  "SyncPragma=%s;NoTXN=%s;Timeout=%s;"
19693  "ShortNames=%s;LongNames=%s;"
19694  "NoCreat=%s;NoWCHAR=%s;"
19695  "FKSupport=%s;JournalMode=%s;OEMCP=%s;LoadExt=%s;"
19696  "BigInt=%s;JDConv=%s;PWD=%s",
19697  dsn_0 ? "DSN=" : "",
19698  dsn_0 ? dsn : "",
19699  dsn_0 ? ";" : "",
19700  drv_0 ? "Driver=" : "",
19701  drv_0 ? driver : "",
19702  drv_0 ? ";" : "",
19703  dbname ? dbname : "",
19704  setupdlg->attr[KEY_STEPAPI].attr,
19705  setupdlg->attr[KEY_SYNCP].attr,
19706  setupdlg->attr[KEY_NOTXN].attr,
19707  setupdlg->attr[KEY_BUSY].attr,
19708  setupdlg->attr[KEY_SHORTNAM].attr,
19709  setupdlg->attr[KEY_LONGNAM].attr,
19710  setupdlg->attr[KEY_NOCREAT].attr,
19711  setupdlg->attr[KEY_NOWCHAR].attr,
19712  setupdlg->attr[KEY_FKSUPPORT].attr,
19713  setupdlg->attr[KEY_JMODE].attr,
19714  setupdlg->attr[KEY_OEMCP].attr,
19715  setupdlg->attr[KEY_LOADEXT].attr,
19716  setupdlg->attr[KEY_BIGINT].attr,
19717  setupdlg->attr[KEY_JDCONV].attr,
19718  setupdlg->attr[KEY_PASSWD].attr);
19719  if (count < 0) {
19720  buf[sizeof (buf) - 1] = '\0';
19721  }
19722  len = min(connOutMax - 1, strlen(buf));
19723  if (connOut) {
19724  strncpy((char *) connOut, buf, len);
19725  connOut[len] = '\0';
19726  }
19727  if (connOutLen) {
19728  *connOutLen = len;
19729  }
19730  }
19731  if (dsn[0]) {
19732  char tracef[SQL_MAX_MESSAGE_LENGTH];
19733 
19734  tracef[0] = '\0';
19735  SQLGetPrivateProfileString(setupdlg->attr[KEY_DSN].attr,
19736  "tracefile", "", tracef,
19737  sizeof (tracef), ODBC_INI);
19738  if (tracef[0] != '\0') {
19739  d->trace = fopen(tracef, "a");
19740  }
19741  }
19742  d->nowchar = getbool(setupdlg->attr[KEY_NOWCHAR].attr);
19743  d->shortnames = getbool(setupdlg->attr[KEY_SHORTNAM].attr);
19744  d->longnames = getbool(setupdlg->attr[KEY_LONGNAM].attr);
19745  d->nocreat = getbool(setupdlg->attr[KEY_NOCREAT].attr);
19746  d->fksupport = getbool(setupdlg->attr[KEY_FKSUPPORT].attr);
19747  d->oemcp = getbool(setupdlg->attr[KEY_OEMCP].attr);
19748  d->dobigint = getbool(setupdlg->attr[KEY_BIGINT].attr);
19749  d->jdconv = getbool(setupdlg->attr[KEY_JDCONV].attr);
19750  d->pwdLen = strlen(setupdlg->attr[KEY_PASSWD].attr);
19751  d->pwd = (d->pwdLen > 0) ? setupdlg->attr[KEY_PASSWD].attr : NULL;
19752  ret = dbopen(d, dbname ? dbname : "", 0,
19753  dsn ? dsn : "",
19754  setupdlg->attr[KEY_STEPAPI].attr,
19755  setupdlg->attr[KEY_SYNCP].attr,
19756  setupdlg->attr[KEY_NOTXN].attr,
19757  setupdlg->attr[KEY_JMODE].attr,
19758  setupdlg->attr[KEY_BUSY].attr);
19759  if (ret != SQL_SUCCESS) {
19760  if (maybeprompt && !prompt) {
19761  prompt = TRUE;
19762  goto retry;
19763  }
19764  }
19765  memset(setupdlg->attr[KEY_PASSWD].attr, 0,
19766  sizeof (setupdlg->attr[KEY_PASSWD].attr));
19767  if (ret == SQL_SUCCESS) {
19768  dbloadext(d, setupdlg->attr[KEY_LOADEXT].attr);
19769  }
19770  xfree(setupdlg);
19771  return ret;
19772 }
19773 
19774 #endif /* WITHOUT_DRIVERMGR */
19775 #endif /* _WIN32 || _WIN64 */
19776 
19777 #ifndef WINTERFACE
19778 
19791 SQLRETURN SQL_API
19792 SQLDriverConnect(SQLHDBC dbc, SQLHWND hwnd,
19793  SQLCHAR *connIn, SQLSMALLINT connInLen,
19794  SQLCHAR *connOut, SQLSMALLINT connOutMax,
19795  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19796 {
19797  SQLRETURN ret;
19798 
19799  HDBC_LOCK(dbc);
19800  ret = drvdriverconnect(dbc, hwnd, connIn, connInLen,
19801  connOut, connOutMax, connOutLen, drvcompl);
19802  HDBC_UNLOCK(dbc);
19803  return ret;
19804 }
19805 #endif
19806 
19807 #ifdef WINTERFACE
19808 
19821 SQLRETURN SQL_API
19822 SQLDriverConnectW(SQLHDBC dbc, SQLHWND hwnd,
19823  SQLWCHAR *connIn, SQLSMALLINT connInLen,
19824  SQLWCHAR *connOut, SQLSMALLINT connOutMax,
19825  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19826 {
19827  SQLRETURN ret;
19828  char *ci = NULL;
19829  SQLSMALLINT len = 0;
19830 
19831  HDBC_LOCK(dbc);
19832  if (connIn) {
19833 #if defined(_WIN32) || defined(_WIN64)
19834  if (connInLen == SQL_NTS) {
19835  connInLen = -1;
19836  }
19837  ci = uc_to_wmb(connIn, connInLen);
19838 #else
19839  ci = uc_to_utf(connIn, connInLen);
19840 #endif
19841  if (!ci) {
19842  DBC *d = (DBC *) dbc;
19843 
19844  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
19845  HDBC_UNLOCK(dbc);
19846  return SQL_ERROR;
19847  }
19848  }
19849  ret = drvdriverconnect(dbc, hwnd, (SQLCHAR *) ci, SQL_NTS,
19850  (SQLCHAR *) connOut, connOutMax, &len, drvcompl);
19851  HDBC_UNLOCK(dbc);
19852  uc_free(ci);
19853  if (ret == SQL_SUCCESS) {
19854  SQLWCHAR *co = NULL;
19855 
19856  if (connOut) {
19857  if (len > 0) {
19858 #if defined(_WIN32) || defined(_WIN64)
19859  co = wmb_to_uc((char *) connOut, len);
19860 #else
19861  co = uc_from_utf((SQLCHAR *) connOut, len);
19862 #endif
19863  if (co) {
19864  uc_strncpy(connOut, co, connOutMax / sizeof (SQLWCHAR));
19865  len = min(connOutMax / sizeof (SQLWCHAR), uc_strlen(co));
19866  uc_free(co);
19867  } else {
19868  len = 0;
19869  }
19870  }
19871  if (len <= 0) {
19872  len = 0;
19873  connOut[0] = 0;
19874  }
19875  } else {
19876  len = 0;
19877  }
19878  if (connOutLen) {
19879  *connOutLen = len;
19880  }
19881  }
19882  return ret;
19883 }
19884 #endif
19885 
19886 #if defined(_WIN32) || defined(_WIN64)
19887 
19896 BOOL APIENTRY
19897 LibMain(HANDLE hinst, DWORD reason, LPVOID reserved)
19898 {
19899  static int initialized = 0;
19900 
19901  switch (reason) {
19902  case DLL_PROCESS_ATTACH:
19903  if (!initialized++) {
19904  hModule = hinst;
19905 #ifdef WINTERFACE
19906  /* MS Access hack part 1 (reserved error -7748) */
19907  statSpec2P = statSpec2;
19908  statSpec3P = statSpec3;
19909 #endif
19910 #ifdef SQLITE_DYNLOAD
19911  dls_init();
19912 #endif
19913 #ifdef SQLITE_HAS_CODEC
19914  sqlite3_activate_see(SQLITE_ACTIVATION_KEY);
19915 #endif
19916  }
19917 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
19918  nvfs_init();
19919 #endif
19920  break;
19921  case DLL_THREAD_ATTACH:
19922  break;
19923  case DLL_PROCESS_DETACH:
19924  if (--initialized <= 0) {
19925 #ifdef SQLITE_DYNLOAD
19926  dls_fini();
19927 #endif
19928  }
19929  break;
19930  case DLL_THREAD_DETACH:
19931  break;
19932  default:
19933  break;
19934  }
19935  return TRUE;
19936 }
19937 
19946 int __stdcall
19947 DllMain(HANDLE hinst, DWORD reason, LPVOID reserved)
19948 {
19949  return LibMain(hinst, reason, reserved);
19950 }
19951 
19952 #ifndef WITHOUT_INSTALLER
19953 
19960 static BOOL
19961 InUnError(char *name)
19962 {
19963  WORD err = 1;
19964  DWORD code;
19965  char errmsg[301];
19966  WORD errlen, errmax = sizeof (errmsg) - 1;
19967  int sqlret;
19968  BOOL ret = FALSE;
19969 
19970  do {
19971  errmsg[0] = '\0';
19972  sqlret = SQLInstallerError(err, &code, errmsg, errmax, &errlen);
19973  if (SQL_SUCCEEDED(sqlret)) {
19974  MessageBox(NULL, errmsg, name,
19975  MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
19976  ret = TRUE;
19977  }
19978  err++;
19979  } while (sqlret != SQL_NO_DATA);
19980  return ret;
19981 }
19982 
19989 static BOOL
19990 InUn(int remove, char *cmdline)
19991 {
19992 #ifdef SQLITE_HAS_CODEC
19993  static char *drivername = "SQLite3 ODBC Driver (SEE)";
19994  static char *dsname = "SQLite3 SEE Datasource";
19995 #else
19996  static char *drivername = "SQLite3 ODBC Driver";
19997  static char *dsname = "SQLite3 Datasource";
19998 #endif
19999  char *dllname, *p;
20000  char dllbuf[301], path[301], driver[300], attr[300], inst[400];
20001  WORD pathmax = sizeof (path) - 1, pathlen;
20002  DWORD usecnt, mincnt;
20003  int quiet = 0;
20004 
20005  dllbuf[0] = '\0';
20006  GetModuleFileName(hModule, dllbuf, sizeof (dllbuf));
20007  p = strrchr(dllbuf, '\\');
20008  dllname = p ? (p + 1) : dllbuf;
20009  quiet = cmdline && strstr(cmdline, "quiet");
20010  if (SQLInstallDriverManager(path, pathmax, &pathlen)) {
20011  sprintf(driver, "%s;Driver=%s;Setup=%s;",
20012  drivername, dllname, dllname);
20013  p = driver;
20014  while (*p) {
20015  if (*p == ';') {
20016  *p = '\0';
20017  }
20018  ++p;
20019  }
20020  usecnt = 0;
20021  path[0] = '\0';
20022  SQLInstallDriverEx(driver, NULL, path, pathmax, NULL,
20023  ODBC_INSTALL_INQUIRY, &usecnt);
20024  pathlen = strlen(path);
20025  while (pathlen > 0 && path[pathlen - 1] == '\\') {
20026  --pathlen;
20027  path[pathlen] = '\0';
20028  }
20029  sprintf(driver, "%s;Driver=%s\\%s;Setup=%s\\%s;",
20030  drivername, path, dllname, path, dllname);
20031  p = driver;
20032  while (*p) {
20033  if (*p == ';') {
20034  *p = '\0';
20035  }
20036  ++p;
20037  }
20038  sprintf(inst, "%s\\%s", path, dllname);
20039  if (!remove && usecnt > 0) {
20040  /* first install try: copy over driver dll, keeping DSNs */
20041  if (GetFileAttributesA(dllbuf) != INVALID_FILE_ATTRIBUTES &&
20042  CopyFile(dllbuf, inst, 0)) {
20043  if (!quiet) {
20044  char buf[512];
20045 
20046  sprintf(buf, "%s replaced.", drivername);
20047  MessageBox(NULL, buf, "Info",
20048  MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20049  MB_SETFOREGROUND);
20050  }
20051  return TRUE;
20052  }
20053  }
20054  mincnt = remove ? 1 : 0;
20055  while (usecnt != mincnt) {
20056  if (!SQLRemoveDriver(driver, TRUE, &usecnt)) {
20057  break;
20058  }
20059  }
20060  if (remove) {
20061  if (usecnt && !SQLRemoveDriver(driver, TRUE, &usecnt)) {
20062  InUnError("SQLRemoveDriver");
20063  return FALSE;
20064  }
20065  if (!usecnt) {
20066  char buf[512];
20067 
20068  DeleteFile(inst);
20069  if (!quiet) {
20070  sprintf(buf, "%s uninstalled.", drivername);
20071  MessageBox(NULL, buf, "Info",
20072  MB_ICONINFORMATION |MB_OK | MB_TASKMODAL |
20073  MB_SETFOREGROUND);
20074  }
20075  }
20076  sprintf(attr, "DSN=%s;Database=;", dsname);
20077  p = attr;
20078  while (*p) {
20079  if (*p == ';') {
20080  *p = '\0';
20081  }
20082  ++p;
20083  }
20084  SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20085  return TRUE;
20086  }
20087  if (GetFileAttributesA(dllbuf) == INVALID_FILE_ATTRIBUTES) {
20088  return FALSE;
20089  }
20090  if (strcasecmp(dllbuf, inst) != 0 && !CopyFile(dllbuf, inst, 0)) {
20091  char buf[512];
20092 
20093  sprintf(buf, "Copy %s to %s failed.", dllbuf, inst);
20094  MessageBox(NULL, buf, "CopyFile",
20095  MB_ICONSTOP |MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
20096  return FALSE;
20097  }
20098  if (!SQLInstallDriverEx(driver, path, path, pathmax, &pathlen,
20099  ODBC_INSTALL_COMPLETE, &usecnt)) {
20100  InUnError("SQLInstallDriverEx");
20101  return FALSE;
20102  }
20103  sprintf(attr, "DSN=%s;Database=;", dsname);
20104  p = attr;
20105  while (*p) {
20106  if (*p == ';') {
20107  *p = '\0';
20108  }
20109  ++p;
20110  }
20111  SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20112  if (!SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN, drivername, attr)) {
20113  InUnError("SQLConfigDataSource");
20114  return FALSE;
20115  }
20116  if (!quiet) {
20117  char buf[512];
20118 
20119  sprintf(buf, "%s installed.", drivername);
20120  MessageBox(NULL, buf, "Info",
20121  MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20122  MB_SETFOREGROUND);
20123  }
20124  } else {
20125  InUnError("SQLInstallDriverManager");
20126  return FALSE;
20127  }
20128  return TRUE;
20129 }
20130 
20139 void CALLBACK
20140 install(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20141 {
20142  InUn(0, lpszCmdLine);
20143 }
20144 
20153 void CALLBACK
20154 uninstall(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20155 {
20156  InUn(1, lpszCmdLine);
20157 }
20158 
20159 #endif /* WITHOUT_INSTALLER */
20160 
20161 #ifndef WITHOUT_SHELL
20162 
20171 static void
20172 setargv(int *argcp, char ***argvp, char *cmdline, char *argv0)
20173 {
20174  char *p, *arg, *argspace, **argv;
20175  int argc, size, inquote, copy, slashes;
20176 
20177  size = 2 + (argv0 ? 1 : 0);
20178  for (p = cmdline; *p != '\0'; p++) {
20179  if (ISSPACE(*p)) {
20180  size++;
20181  while (ISSPACE(*p)) {
20182  p++;
20183  }
20184  if (*p == '\0') {
20185  break;
20186  }
20187  }
20188  }
20189  argspace = malloc(size * sizeof (char *) + strlen(cmdline) + 1);
20190  argv = (char **) argspace;
20191  argspace += size * sizeof (char *);
20192  size--;
20193  argc = 0;
20194  if (argv0) {
20195  argv[argc++] = argv0;
20196  }
20197  p = cmdline;
20198  for (; argc < size; argc++) {
20199  argv[argc] = arg = argspace;
20200  while (ISSPACE(*p)) {
20201  p++;
20202  }
20203  if (*p == '\0') {
20204  break;
20205  }
20206  inquote = 0;
20207  slashes = 0;
20208  while (1) {
20209  copy = 1;
20210  while (*p == '\\') {
20211  slashes++;
20212  p++;
20213  }
20214  if (*p == '"') {
20215  if ((slashes & 1) == 0) {
20216  copy = 0;
20217  if (inquote && p[1] == '"') {
20218  p++;
20219  copy = 1;
20220  } else {
20221  inquote = !inquote;
20222  }
20223  }
20224  slashes >>= 1;
20225  }
20226  while (slashes) {
20227  *arg = '\\';
20228  arg++;
20229  slashes--;
20230  }
20231  if (*p == '\0' || (!inquote && ISSPACE(*p))) {
20232  break;
20233  }
20234  if (copy != 0) {
20235  *arg = *p;
20236  arg++;
20237  }
20238  p++;
20239  }
20240  *arg = '\0';
20241  argspace = arg + 1;
20242  }
20243  argv[argc] = 0;
20244  *argcp = argc;
20245  *argvp = argv;
20246 }
20247 
20256 void CALLBACK
20257 shell(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20258 {
20259  int argc, needcon = 0;
20260  char **argv;
20261  extern int sqlite3_main(int, char **);
20262  static const char *name = "SQLite3 Shell";
20263  DWORD ftype0, ftype1, ftype2;
20264 
20265  ftype0 = GetFileType(GetStdHandle(STD_INPUT_HANDLE));
20266  ftype1 = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
20267  ftype2 = GetFileType(GetStdHandle(STD_ERROR_HANDLE));
20268  if (ftype0 != FILE_TYPE_DISK && ftype0 != FILE_TYPE_CHAR &&
20269  ftype0 != FILE_TYPE_PIPE) {
20270  fclose(stdin);
20271  ++needcon;
20272  ftype0 = FILE_TYPE_UNKNOWN;
20273  }
20274  if (ftype1 != FILE_TYPE_DISK && ftype1 != FILE_TYPE_CHAR &&
20275  ftype1 != FILE_TYPE_PIPE) {
20276  fclose(stdout);
20277  ++needcon;
20278  ftype1 = FILE_TYPE_UNKNOWN;
20279  }
20280  if (ftype2 != FILE_TYPE_DISK && ftype2 != FILE_TYPE_CHAR &&
20281  ftype2 != FILE_TYPE_PIPE) {
20282  fclose(stderr);
20283  ++needcon;
20284  ftype2 = FILE_TYPE_UNKNOWN;
20285  }
20286  if (needcon > 0) {
20287  AllocConsole();
20288  SetConsoleTitle(name);
20289  }
20290  if (ftype0 == FILE_TYPE_UNKNOWN) {
20291  freopen("CONIN$", "r", stdin);
20292  }
20293  if (ftype1 == FILE_TYPE_UNKNOWN) {
20294  freopen("CONOUT$", "w", stdout);
20295  }
20296  if (ftype2 == FILE_TYPE_UNKNOWN) {
20297  freopen("CONOUT$", "w", stderr);
20298  }
20299  setargv(&argc, &argv, lpszCmdLine, (char *) name);
20300 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
20301  nvfs_init();
20302 #endif
20303  sqlite3_main(argc, argv);
20304 }
20305 
20306 #endif /* WITHOUT_SHELL */
20307 
20308 #endif /* _WIN32 || _WIN64 */
20309 
20310 #if defined(HAVE_ODBCINSTEXT_H) && (HAVE_ODBCINSTEXT_H)
20311 
20312 /*
20313  * unixODBC property page for this driver,
20314  * may or may not work depending on unixODBC version.
20315  */
20316 
20317 #include <odbcinstext.h>
20318 
20319 int
20320 ODBCINSTGetProperties(HODBCINSTPROPERTY prop)
20321 {
20322  static const char *instYN[] = { "No", "Yes", NULL };
20323  static const char *syncPragma[] = { "NORMAL", "OFF", "FULL", NULL };
20324  static const char *jmPragma[] = {
20325  "DELETE", "PERSIST", "OFF", "TRUNCATE", "MEMORY", "WAL", NULL
20326  };
20327 
20328  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20329  prop = prop->pNext;
20330  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20331  prop->nPromptType = ODBCINST_PROMPTTYPE_FILENAME;
20332  strncpy(prop->szName, "Database", INI_MAX_PROPERTY_NAME);
20333  strncpy(prop->szValue, "", 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_TEXTEDIT;
20338  strncpy(prop->szName, "Timeout", INI_MAX_PROPERTY_NAME);
20339  strncpy(prop->szValue, "100000", INI_MAX_PROPERTY_VALUE);
20340  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20341  prop = prop->pNext;
20342  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20343  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20344  prop->aPromptData = malloc(sizeof (instYN));
20345  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20346  strncpy(prop->szName, "StepAPI", INI_MAX_PROPERTY_NAME);
20347  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20348  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20349  prop = prop->pNext;
20350  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20351  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20352  prop->aPromptData = malloc(sizeof (instYN));
20353  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20354  strncpy(prop->szName, "ShortNames", INI_MAX_PROPERTY_NAME);
20355  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20356  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20357  prop = prop->pNext;
20358  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20359  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20360  prop->aPromptData = malloc(sizeof (instYN));
20361  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20362  strncpy(prop->szName, "LongNames", INI_MAX_PROPERTY_NAME);
20363  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20364  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20365  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20366  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20367  prop->aPromptData = malloc(sizeof (instYN));
20368  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20369  strncpy(prop->szName, "NoCreat", INI_MAX_PROPERTY_NAME);
20370  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20371 #ifdef WINTERFACE
20372  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20373  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20374  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20375  prop->aPromptData = malloc(sizeof (instYN));
20376  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20377  strncpy(prop->szName, "NoWCHAR", INI_MAX_PROPERTY_NAME);
20378  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20379 #endif
20380  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20381  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20382  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20383  prop->aPromptData = malloc(sizeof (instYN));
20384  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20385  strncpy(prop->szName, "FKSupport", INI_MAX_PROPERTY_NAME);
20386  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20387  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20388  prop = prop->pNext;
20389  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20390  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20391  prop->aPromptData = malloc(sizeof (syncPragma));
20392  memcpy(prop->aPromptData, syncPragma, sizeof (syncPragma));
20393  strncpy(prop->szName, "SyncPragma", INI_MAX_PROPERTY_NAME);
20394  strncpy(prop->szValue, "NORMAL", INI_MAX_PROPERTY_VALUE);
20395  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20396  prop = prop->pNext;
20397  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20398  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20399  prop->aPromptData = malloc(sizeof (jmPragma));
20400  memcpy(prop->aPromptData, jmPragma, sizeof (jmPragma));
20401  strncpy(prop->szName, "JournalMode", INI_MAX_PROPERTY_NAME);
20402  strncpy(prop->szValue, "DELETE", INI_MAX_PROPERTY_VALUE);
20403  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20404  prop = prop->pNext;
20405  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20406  prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20407  strncpy(prop->szName, "LoadExt", INI_MAX_PROPERTY_NAME);
20408  strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20409  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20410  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20411  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20412  prop->aPromptData = malloc(sizeof (instYN));
20413  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20414  strncpy(prop->szName, "BigInt", INI_MAX_PROPERTY_NAME);
20415  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20416  return 1;
20417 }
20418 
20419 #endif /* HAVE_ODBCINSTEXT_H */
20420 
20421 #ifdef SQLITE_DYNLOAD
20422 
20423 /*
20424  * SQLite3 shared library/DLL stubs.
20425  */
20426 
20427 static void
20428 dls_void(void)
20429 {
20430 }
20431 
20432 static int
20433 dls_error(void)
20434 {
20435  return SQLITE_ERROR;
20436 }
20437 
20438 static int
20439 dls_0(void)
20440 {
20441  return 0;
20442 }
20443 
20444 static sqlite_int64
20445 dls_0LL(void)
20446 {
20447  return 0;
20448 }
20449 
20450 static double
20451 dls_00(void)
20452 {
20453  return 0;
20454 }
20455 
20456 static void *
20457 dls_null(void)
20458 {
20459  return NULL;
20460 }
20461 
20462 static const char *
20463 dls_empty(void)
20464 {
20465  return "";
20466 }
20467 
20468 static int
20469 dls_snull(void)
20470 {
20471  return SQLITE_NULL;
20472 }
20473 
20474 #define DLS_ENT(name, func) \
20475  { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, name), \
20476  (void *) func }
20477 
20478 #define DLS_ENT3(name, off, func) \
20479  { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, off), \
20480  (void *) func }
20481 
20482 #define DLS_END { NULL, 0, NULL }
20483 
20484 static struct {
20485  const char *name;
20486  int offset;
20487  void *func;
20488 } dls_nametab[] = {
20489  DLS_ENT(activate_see, dls_void),
20490  DLS_ENT(bind_blob, dls_error),
20491  DLS_ENT(bind_double, dls_error),
20492  DLS_ENT(bind_int, dls_error),
20493  DLS_ENT(bind_int64, dls_error),
20494  DLS_ENT(bind_null, dls_error),
20495  DLS_ENT(bind_parameter_count, dls_0),
20496  DLS_ENT(bind_text, dls_error),
20497  DLS_ENT(busy_handler, dls_error),
20498  DLS_ENT(changes, dls_0),
20499  DLS_ENT(close, dls_error),
20500  DLS_ENT(column_blob, dls_null),
20501  DLS_ENT(column_bytes, dls_0),
20502  DLS_ENT(column_count, dls_0),
20503  DLS_ENT(column_database_name, dls_empty),
20504  DLS_ENT(column_decltype, dls_empty),
20505  DLS_ENT(column_double, dls_00),
20506  DLS_ENT(column_name, dls_empty),
20507  DLS_ENT(column_origin_name, dls_null),
20508  DLS_ENT(column_table_name, dls_null),
20509  DLS_ENT(column_text, dls_null),
20510  DLS_ENT(column_type, dls_snull),
20511  DLS_ENT(create_function, dls_error),
20512  DLS_ENT(enable_load_extension, dls_error),
20513  DLS_ENT(errcode, dls_error),
20514  DLS_ENT(errmsg, dls_empty),
20515  DLS_ENT(exec, dls_error),
20516  DLS_ENT(finalize, dls_error),
20517  DLS_ENT(free, free),
20518  DLS_ENT(free_table, dls_void),
20519  DLS_ENT(get_table, dls_error),
20520  DLS_ENT(interrupt, dls_void),
20521  DLS_ENT(key, dls_error),
20522  DLS_ENT(last_insert_rowid, dls_0LL),
20523  DLS_ENT(libversion, dls_empty),
20524  DLS_ENT(load_extension, dls_error),
20525  DLS_ENT(malloc, malloc),
20526  DLS_ENT(mprintf, dls_null),
20527  DLS_ENT(open, dls_error),
20528  DLS_ENT(open16, dls_error),
20529  DLS_ENT(open_v2, dls_error),
20530  DLS_ENT(prepare, dls_error),
20531  DLS_ENT(prepare_v2, dls_error),
20532  DLS_ENT(profile, dls_null),
20533  DLS_ENT(realloc, realloc),
20534  DLS_ENT(rekey, dls_error),
20535  DLS_ENT(reset, dls_error),
20536  DLS_ENT(result_blob, dls_void),
20537  DLS_ENT(result_error, dls_void),
20538  DLS_ENT(result_int, dls_void),
20539  DLS_ENT(result_null, dls_void),
20540  DLS_ENT(step, dls_error),
20541 #if defined(_WIN32) || defined(_WIN64)
20542  DLS_ENT3(strnicmp, xstrnicmp, _strnicmp),
20543 #else
20544  DLS_ENT3(strnicmp, xstrnicmp, strncasecmp),
20545 #endif
20546  DLS_ENT(table_column_metadata, dls_error),
20547  DLS_ENT(trace, dls_null),
20548  DLS_ENT(user_data, dls_null),
20549  DLS_ENT(value_blob, dls_null),
20550  DLS_ENT(value_bytes, dls_0),
20551  DLS_ENT(value_text, dls_empty),
20552  DLS_ENT(value_type, dls_snull),
20553  DLS_END
20554 };
20555 
20556 #if defined(_WIN32) || defined(_WIN64)
20557 
20558 static HMODULE sqlite3_dll = 0;
20559 
20560 static void
20561 dls_init(void)
20562 {
20563  int i;
20564  static const char *dll_names[] = {
20565  "System.Data.SQLite.dll",
20566  "sqlite3.dll",
20567  NULL,
20568  };
20569 
20570  i = 0;
20571  while (dll_names[i]) {
20572  sqlite3_dll = LoadLibrary(dll_names[i]);
20573  if (sqlite3_dll) {
20574  break;
20575  }
20576  ++i;
20577  }
20578  i = 0;
20579  while (dls_nametab[i].name) {
20580  void *func = 0, **loc;
20581 
20582  if (sqlite3_dll) {
20583  func = (void *) GetProcAddress(sqlite3_dll, dls_nametab[i].name);
20584  }
20585  if (!func) {
20586  func = dls_nametab[i].func;
20587  }
20588  loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
20589  *loc = func;
20590  ++i;
20591  }
20592  if (!sqlite3_dll) {
20593  char buf[MAXPATHLEN], msg[MAXPATHLEN];
20594 
20595  LoadString(hModule, IDS_DRVTITLE, buf, sizeof (buf));
20596  LoadString(hModule, IDS_DLLERR, msg, sizeof (msg));
20597  MessageBox(NULL, msg, buf,
20598  MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
20599  MB_SETFOREGROUND);
20600  }
20601 }
20602 
20603 static void
20604 dls_fini(void)
20605 {
20606  if (sqlite3_dll) {
20607  FreeLibrary(sqlite3_dll);
20608  sqlite3_dll = 0;
20609  }
20610 }
20611 
20612 #else
20613 
20614 #include <dlfcn.h>
20615 
20616 static void *libsqlite3_so = 0;
20617 
20618 void
20619 dls_init(void)
20620 {
20621  int i;
20622 
20623  libsqlite3_so = dlopen("libsqlite3.so.0", RTLD_NOW | RTLD_GLOBAL);
20624  i = 0;
20625  while (dls_nametab[i].name) {
20626  void *func = 0, **loc;
20627 
20628  if (libsqlite3_so) {
20629  func = dlsym(libsqlite3_so, dls_nametab[i].name);
20630  }
20631  if (!func) {
20632  func = dls_nametab[i].func;
20633  }
20634  loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
20635  *loc = func;
20636  ++i;
20637  }
20638  if (!libsqlite3_so) {
20639  const char errmsg[] = "SQLite3 shared library not found.\n";
20640 
20641  write(2, errmsg, sizeof (errmsg) - 1);
20642  }
20643 }
20644 
20645 void
20646 dls_fini(void)
20647 {
20648  if (libsqlite3_so) {
20649  dlclose(libsqlite3_so);
20650  libsqlite3_so = 0;
20651  }
20652 }
20653 
20654 #endif
20655 
20656 #endif
20657 
20658 /*
20659  * Local Variables:
20660  * mode: c
20661  * c-basic-offset: 4
20662  * fill-column: 78
20663  * tab-width: 8
20664  * End:
20665  */
sqlite3_stmt * s3stmt
SQLite statement handle or NULL.
Definition: sqlite3odbc.h:283
SQLULEN paramset_size
SQL_ATTR_PARAMSET_SIZE.
Definition: sqlite3odbc.h:270
sqlite_int64 s3lival
SQLite3 64bit integer value.
Definition: sqlite3odbc.h:220
int busyint
Interrupt busy handler from SQLCancel()
Definition: sqlite3odbc.h:121
static SQLRETURN setupparbuf(STMT *s, BINDPARM *p)
Setup parameter buffer for deferred parameter.
Definition: sqlite3odbc.c:5614
void * parbuf
Buffer for SQL_LEN_DATA_AT_EXEC etc.
Definition: sqlite3odbc.h:214
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:5891
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:9635
static SQLRETURN nomem(STMT *s)
Report S1000 (out of memory) SQL error given STMT.
Definition: sqlite3odbc.c:1847
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:2777
int longnames
Don&#39;t shorten column names.
Definition: sqlite3odbc.h:133
int nocreat
Don&#39;t auto create database file.
Definition: sqlite3odbc.h:134
#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:2185
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:1722
struct dbc * dbcs
Pointer to first DBC.
Definition: sqlite3odbc.h:102
void * param0
Parameter buffer, initial value.
Definition: sqlite3odbc.h:209
int * ov3
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:235
static SQLRETURN freeparams(STMT *s)
Clear out parameter bindings, if any.
Definition: sqlite3odbc.c:5029
int dobigint
Force SQL_BIGINT for INTEGER columns.
Definition: sqlite3odbc.h:261
SQLCHAR * query
Current query, raw string.
Definition: sqlite3odbc.h:234
sqlite3 * sqlite
SQLITE database handle.
Definition: sqlite3odbc.h:115
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:289
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:7823
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:5648
static SQLRETURN drvfreeconnect(SQLHDBC dbc)
Internal free connection (HDBC).
SQLCHAR logmsg[1024]
Message for SQLError()
Definition: sqlite3odbc.h:259
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:255
int step_enable
True for sqlite_compile/step/finalize.
Definition: sqlite3odbc.h:137
#define drvgetgpps(d)
Definition: sqlite3odbc.c:1326
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:1427
static void blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function to import a BLOB from a file.
Definition: sqlite3odbc.c:3703
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:1335
int ispk
Flag for primary key (> 0)
Definition: sqlite3odbc.h:175
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:1417
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:125
int shortnames
Always use short column names.
Definition: sqlite3odbc.h:132
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:277
void * s3val
SQLite3 value buffer.
Definition: sqlite3odbc.h:218
static int str2time(int jdconv, char *str, TIME_STRUCT *ts)
Convert string to ODBC TIME_STRUCT.
Definition: sqlite3odbc.c:3234
Internal structure for bound column (SQLBindCol).
Definition: sqlite3odbc.h:187
static COL pkeySpec2[]
Columns for result set of SQLPrimaryKeys().
Definition: sqlite3odbc.c:6418
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:7262
static void freedyncols(STMT *s)
Free dynamically allocated column descriptions of STMT.
int nrows
Number of result rows.
Definition: sqlite3odbc.h:252
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:2211
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:2335
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:111
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:269
int s3ival
SQLite3 integer value.
Definition: sqlite3odbc.h:219
struct stmt * cur_s3stmt
Current STMT executing sqlite statement.
Definition: sqlite3odbc.h:141
int need
True when SQL_LEN_DATA_AT_EXEC.
Definition: sqlite3odbc.h:211
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:8716
SQLULEN parm_bind_type
SQL_ATTR_PARAM_BIND_TYPE.
Definition: sqlite3odbc.h:281
int * ov3
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:122
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:268
SQLRETURN SQL_API SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen, SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
Translate SQL string (UNICODE version).
Definition: sqlite3odbc.c:8149
static SQLRETURN drvallocenv(SQLHENV *env)
Internal allocate HENV.
static COL procSpec2[]
Columns for result set of SQLProcedures().
Definition: sqlite3odbc.c:8184
char sqlstate[6]
SQL state for SQLError()
Definition: sqlite3odbc.h:258
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:6449
int inc
Increment for paramset size > 1.
Definition: sqlite3odbc.h:210
SQLLEN max
Max.
Definition: sqlite3odbc.h:205
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:4555
SQLRETURN SQL_API SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno, SQLSMALLINT fieldid, SQLPOINTER value, SQLINTEGER buflen)
Function not implemented.
Definition: sqlite3odbc.c:5844
#define SQL_API
Definition: sqlite3odbc.h:58
char * column
Column name.
Definition: sqlite3odbc.h:166
int version
SQLITE version number.
Definition: sqlite3odbc.h:116
char * dsn
ODBC data source name.
Definition: sqlite3odbc.h:118
HDBC dbc
Pointer to DBC.
Definition: sqlite3odbc.h:232
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:136
#define xfree(x)
Definition: sqlite3odbc.c:405
Driver internal structure representing SQL statement (HSTMT).
Definition: sqlite3odbc.h:230
SQLRETURN SQL_API SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len, SQLINTEGER *lenp)
Get information of HENV.
Definition: sqlite3odbc.c:8388
SQLUINTEGER paramset_nrows
Row count for paramset handling.
Definition: sqlite3odbc.h:272
static int typeinfosort(const void *a, const void *b)
Helper function to sort type information.
int autocommit
Auto commit state.
Definition: sqlite3odbc.h:124
SQLCHAR logmsg[1024]
Message for SQLError()
Definition: sqlite3odbc.h:129
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:9394
int isrowid
Flag for ROWID column (> 0)
Definition: sqlite3odbc.h:176
SQLRETURN SQL_API SQLGetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
Get option of HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9466
int prec
Precision of column.
Definition: sqlite3odbc.h:172
int magic
Magic cookie.
Definition: sqlite3odbc.h:97
ENV * env
Pointer to environment.
Definition: sqlite3odbc.h:113
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:8361
static void dbtrace(void *arg, const char *msg, sqlite_uint64 et)
SQLite trace or profile callback.
Definition: sqlite3odbc.c:3838
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:8074
static void blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function to export a BLOB to a file.
Definition: sqlite3odbc.c:3773
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:1415
static COL procColSpec3[]
Definition: sqlite3odbc.c:8290
static double ln_strtod(const char *data, char **endp)
Internal locale neutral strtod function.
Definition: sqlite3odbc.c:1876
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:4794
#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:2420
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:7315
BINDPARM * bindparms
Array of bound parameters.
Definition: sqlite3odbc.h:249
#define SETSTMTOPTION_LAST_ARG_TYPE
Definition: sqlite3odbc.c:221
COL * cols
Result column array.
Definition: sqlite3odbc.h:240
#define DBC_MAGIC
Definition: sqlite3odbc.c:263
static SQLRETURN noconn(STMT *s)
Report S1000 (not connected) SQL error given STMT.
Definition: sqlite3odbc.c:1860
SQLULEN bind_type
SQL_ATTR_ROW_BIND_TYPE.
Definition: sqlite3odbc.h:274
SQLRETURN SQL_API SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
Put (partial) parameter data into executing statement.
Definition: sqlite3odbc.c:5013
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:5565
SQLRETURN SQL_API SQLCopyDesc(SQLHDESC source, SQLHDESC target)
Function not implemented.
Definition: sqlite3odbc.c:8087
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:5912
SQLPOINTER valp
Value buffer.
Definition: sqlite3odbc.h:191
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:8915
static int namematch(char *str, char *pat, int esc)
SQL LIKE string match with optional backslash escape handling.
Definition: sqlite3odbc.c:1980
SQLUSMALLINT * parm_oper
SQL_ATTR_PARAM_OPERATION_PTR.
Definition: sqlite3odbc.h:278
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:954
char * dbname
SQLITE database name.
Definition: sqlite3odbc.h:117
SQLRETURN SQL_API SQLEndTran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
Commit or rollback transaction.
Definition: sqlite3odbc.c:8060
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:135
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:142
int rowprs
Current start row of rowset.
Definition: sqlite3odbc.h:254
char * table
Table name.
Definition: sqlite3odbc.h:165
SQLRETURN SQL_API SQLDescribeParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT *dtype, SQLULEN *size, SQLSMALLINT *decdigits, SQLSMALLINT *nullable)
Return information about parameter.
Definition: sqlite3odbc.c:5702
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:1418
SQLRETURN SQL_API SQLCloseCursor(SQLHSTMT stmt)
Close open cursor.
int s3stmt_rownum
Current row number.
Definition: sqlite3odbc.h:285
static COL tablePrivSpec2[]
Columns for result set of SQLTablePrivileges().
Definition: sqlite3odbc.c:5954
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:5987
int * jdconv
True for julian day conversion.
Definition: sqlite3odbc.h:237
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:6281
SQLUSMALLINT row_status1
Internal status array for 1 row rowsets.
Definition: sqlite3odbc.h:267
SQLLEN * lenp
Value return, actual size of value buffer.
Definition: sqlite3odbc.h:190
SQLULEN retr_data
SQL_ATTR_RETRIEVE_DATA.
Definition: sqlite3odbc.h:263
int longnames
Don&#39;t shorten column names.
Definition: sqlite3odbc.h:262
int index
Index of column in result.
Definition: sqlite3odbc.h:192
static SQLRETURN chkunbound(STMT *s)
Check for unbound result columns.
Definition: sqlite3odbc.c:9604
static void freep(void *x)
Free memory given pointer to memory pointer.
Definition: sqlite3odbc.c:1832
static void fixupdyncols(STMT *s, DBC *d)
Fixup column information for a running statement.
Definition: sqlite3odbc.c:2808
static char * uc_to_utf(SQLWCHAR *str, int len)
Make UTF8 string from UNICODE string.
Definition: sqlite3odbc.c:980
int nosign
Unsigned type.
Definition: sqlite3odbc.h:170
static int getmdays(int year, int month)
Return number of month days.
Definition: sqlite3odbc.c:3085
static COL tablePrivSpec3[]
Definition: sqlite3odbc.c:5964
SQLSMALLINT type
ODBC type.
Definition: sqlite3odbc.h:188
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:6777
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:7215
static int str2date(int jdconv, char *str, DATE_STRUCT *ds)
Convert string to ODBC DATE_STRUCT.
Definition: sqlite3odbc.c:3119
static COL procSpec3[]
Definition: sqlite3odbc.c:8195
struct dbc * next
Pointer to next DBC.
Definition: sqlite3odbc.h:114
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:9975
static COL colPrivSpec3[]
Definition: sqlite3odbc.c:6338
#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:130
#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:9564
SQLRETURN SQL_API SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SETSTMTOPTION_LAST_ARG_TYPE param)
Set option on HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9585
double s3dval
SQLite3 float value.
Definition: sqlite3odbc.h:221
static int drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp, int *ncolp, char **errp, int nparam, BINDPARM *p)
Definition: sqlite3odbc.c:1544
Internal structure for managing driver&#39;s sqlite3_get_table() implementation.
Definition: sqlite3odbc.c:1409
int pwdLen
Length of password.
Definition: sqlite3odbc.h:145
static void unbindcols(STMT *s)
Reset bound columns to unbound state.
static COL scolSpec2[]
Columns for result set of SQLSpecialColumns().
Definition: sqlite3odbc.c:6822
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:239
#define WCHARSUPPORT
Definition: sqlite3odbc.c:185
SQLUSMALLINT * row_status
Row status pointer.
Definition: sqlite3odbc.h:265
SQLRETURN SQL_API SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *ncols)
Return number of columns of result set given HSTMT.
static COL pkeySpec3[]
Definition: sqlite3odbc.c:6427
static int busy_handler(void *udata, int count)
Busy callback for SQLite.
Definition: sqlite3odbc.c:2053
static char * uc_to_utf_c(SQLWCHAR *str, int len)
Make UTF8 string from UNICODE string.
Definition: sqlite3odbc.c:1063
#define SQLSETPOSIROW
Definition: sqlite3odbc.h:76
SQLCHAR cursorname[32]
Cursor name.
Definition: sqlite3odbc.h:233
static int str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
Convert string to ODBC TIMESTAMP_STRUCT.
Definition: sqlite3odbc.c:3355
static SQLRETURN starttran(STMT *s)
Start transaction when autocommit off.
Definition: sqlite3odbc.c:7901
static int s3stmt_step(STMT *s)
Do one sqlite statement step gathering one result row.
Definition: sqlite3odbc.c:4308
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:231
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:287
static SQLRETURN setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp)
static COL procColSpec2[]
Columns for result set of SQLProcedureColumns().
Definition: sqlite3odbc.c:8268
static SQLRETURN drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER buflen)
Internal set option on HSTMT.
Definition: sqlite3odbc.c:9186
SQLINTEGER * bkmrkptr
SQL_ATTR_FETCH_BOOKMARK_PTR.
Definition: sqlite3odbc.h:244
int notnull
NOT NULL constraint on column.
Definition: sqlite3odbc.h:174
int timeout
Lock timeout value.
Definition: sqlite3odbc.h:119
SQLULEN max_rows
SQL_ATTR_MAX_ROWS.
Definition: sqlite3odbc.h:273
int nalloc
alloc&#39;ed size of result array
Definition: sqlite3odbc.c:1414
static void dbtraceapi(DBC *d, char *fn, const char *sql)
Trace function for SQLite API calls.
Definition: sqlite3odbc.c:3876
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:4736
int coldef
Definition: sqlite3odbc.h:204
static int getbool(char *string)
Get boolean flag from string.
Definition: sqlite3odbc.c:3687
SQLRETURN SQL_API SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Get option of HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9164
char * label
Column label or NULL.
Definition: sqlite3odbc.h:178
SQLRETURN SQL_API SQLFreeEnv(SQLHENV env)
Free HENV.
int type
Data type of column.
Definition: sqlite3odbc.h:167
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:5875
int nowchar[2]
Don&#39;t try to use WCHAR.
Definition: sqlite3odbc.h:260
static const char upper_chars[]
Definition: sqlite3odbc.c:546
int s3size
SQLite3 size.
Definition: sqlite3odbc.h:217
static SQLRETURN setupparam(STMT *s, char *sql, int pnum)
Setup SQLite3 parameter for statement parameter.
Definition: sqlite3odbc.c:5054
#define stringify(s)
Definition: sqlite3odbc.c:236
int binlen
Length of blob data.
Definition: sqlite3odbc.h:288
#define SCOL_VARCHAR
Definition: sqlite3odbc.c:255
SQLLEN * lenp0
Actual size of parameter buffer, initial value.
Definition: sqlite3odbc.h:207
int * oemcp
True for Win32 OEM CP translation.
Definition: sqlite3odbc.h:236
static SQLRETURN drvunimpldbc(HDBC dbc)
Report IM001 (not implemented) SQL error code for HDBC.
Definition: sqlite3odbc.c:1795
SQLUSMALLINT * row_status0
Internal status array.
Definition: sqlite3odbc.h:266
#define SCOL_CHAR
Definition: sqlite3odbc.c:256
static void s3stmt_end_if(STMT *s)
Conditionally stop running sqlite statement.
Definition: sqlite3odbc.c:4583
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:189
static int setsqliteopts(sqlite3 *x, DBC *d)
Set SQLite options (PRAGMAs) given SQLite handle.
Definition: sqlite3odbc.c:2128
int nbindcols
Number of entries in bindcols.
Definition: sqlite3odbc.h:247
int isselect
0 if query is a SELECT statement
Definition: sqlite3odbc.h:238
SQLLEN * lenp
Actual size of parameter buffer.
Definition: sqlite3odbc.h:206
SQLRETURN SQL_API SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
Get option of HSTMT.
Definition: sqlite3odbc.c:9446
static SQLRETURN drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
Internal set option on HSTMT.
Definition: sqlite3odbc.c:9486
char * pwd
Password or NULL.
Definition: sqlite3odbc.h:144
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:143
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:9373
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:1412
static void uc_free(void *str)
Free converted UTF8 or UNICODE string.
Definition: sqlite3odbc.c:1081
int autoinc
AUTO_INCREMENT column.
Definition: sqlite3odbc.h:173
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:7944
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:4772
char * db
Database name.
Definition: sqlite3odbc.h:164
static const char * xdigits
Definition: sqlite3odbc.c:279
long t0
Start time for SQLITE busy handler.
Definition: sqlite3odbc.h:120
int naterr
Native error code.
Definition: sqlite3odbc.h:127
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:8638
char sqlstate[6]
SQL state for SQLError()
Definition: sqlite3odbc.h:128
int bound
True when SQLBindParameter() called.
Definition: sqlite3odbc.h:212
static void dbloadext(DBC *d, char *exts)
Load SQLite extension modules, if any.
Definition: sqlite3odbc.c:4134
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:208
int one_tbl
Flag for single table (> 0)
Definition: sqlite3odbc.h:290
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:256
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:282
#define array_size(x)
Definition: sqlite3odbc.c:233
STMT * s
Driver statement pointer.
Definition: sqlite3odbc.c:1413
static COL colSpec2[]
Columns for result set of SQLColumns().
int ncol
number of columns in result array
Definition: sqlite3odbc.c:1416
int scale
from SQLBindParameter()
Definition: sqlite3odbc.h:204
COL * dyncols
Column array, but malloc()ed.
Definition: sqlite3odbc.h:241
int dobigint
Force SQL_BIGINT for INTEGER columns.
Definition: sqlite3odbc.h:131
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:5536
int index
Index of column in result.
Definition: sqlite3odbc.h:169
int bkmrk
True when bookmarks used.
Definition: sqlite3odbc.h:243
SQLULEN * parm_proc
SQL_ATTR_PARAMS_PROCESSED_PTR.
Definition: sqlite3odbc.h:280
SQLULEN * bind_offs
SQL_ATTR_ROW_BIND_OFFSET_PTR.
Definition: sqlite3odbc.h:275
int magic
Magic cookie.
Definition: sqlite3odbc.h:112
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:3028
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:5767
static COL colPrivSpec2[]
Columns for result set of SQLColumnPrivileges().
Definition: sqlite3odbc.c:6328
int size
Size of column.
Definition: sqlite3odbc.h:168
static COL scolSpec3[]
Definition: sqlite3odbc.c:6834
static SQLRETURN drvunimplstmt(HSTMT stmt)
Report IM001 (not implemented) SQL error code for HSTMT.
Definition: sqlite3odbc.c:1814
struct dstr dstr
SQLRETURN SQL_API SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
Set information in HENV.
Definition: sqlite3odbc.c:8446
static char * s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
Find out column type.
Definition: sqlite3odbc.c:4215
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:4702
#define max(a, b)
Definition: sqlite3odbc.c:227
BINDCOL * bindcols
Array of bound columns.
Definition: sqlite3odbc.h:246
int rowp
Current result row.
Definition: sqlite3odbc.h:253
#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:5816
int ov3val
True for SQL_OV_ODBC3.
Definition: sqlite3odbc.h:123
int scale
Scale of column.
Definition: sqlite3odbc.h:171
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:177
SQLUSMALLINT * parm_status
SQL_ATTR_PARAMS_STATUS_PTR.
Definition: sqlite3odbc.h:279
static SQLRETURN s3stmt_start(STMT *s)
Start sqlite statement for execution of SELECT statement.
Definition: sqlite3odbc.c:4622
int jdconv
True for julian day conversion.
Definition: sqlite3odbc.h:140
int has_rowid
Flag for ROWID (>= 0 or -1)
Definition: sqlite3odbc.h:292
BINDCOL bkmrkcol
Bookmark bound column.
Definition: sqlite3odbc.h:245
SQLULEN rowset_size
Size of rowset.
Definition: sqlite3odbc.h:264
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:1327
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:5588
char strbuf[64]
String buffer for scalar data.
Definition: sqlite3odbc.h:215
static COL fkeySpec3[]
Definition: sqlite3odbc.c:7279
int oemcp
True for Win32 OEM CP translation.
Definition: sqlite3odbc.h:139
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:8003
char * bincell
Cache for blob data.
Definition: sqlite3odbc.h:286
int nparams
Number of parameters in query.
Definition: sqlite3odbc.h:250
static void setstat(STMT *s, int naterr, char *msg, char *st,...)
Set error message and SQL state on statement.
Definition: sqlite3odbc.c:1762
int stype
ODBC and SQL types.
Definition: sqlite3odbc.h:203
Internal structure for bound parameter (SQLBindParameter).
Definition: sqlite3odbc.h:202
static void s3stmt_drop(STMT *s)
Drop running sqlite statement in STMT.
Definition: sqlite3odbc.c:4601
int nbindparms
Number bound parameters.
Definition: sqlite3odbc.h:248
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:163
char * errmsg
error message or NULL
Definition: sqlite3odbc.c:1411
SQLRETURN SQL_API SQLAllocStmt(SQLHDBC dbc, SQLHSTMT *stmt)
Allocate HSTMT given HDBC.
int has_pk
Flag for primary key (> 0)
Definition: sqlite3odbc.h:291
static SQLRETURN drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Internal get option of HSTMT.
Definition: sqlite3odbc.c:8991
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:3920
static int uc_strlen(SQLWCHAR *str)
Return length of UNICODE string.
Definition: sqlite3odbc.c:800
int offs
Byte offset for SQLGetData()
Definition: sqlite3odbc.h:193
struct tblres TBLRES
SQLULEN paramset_count
Internal for paramset.
Definition: sqlite3odbc.h:271
int pdcount
SQLParamData() counter.
Definition: sqlite3odbc.h:251
struct stmt * stmt
STMT list of this DBC.
Definition: sqlite3odbc.h:126
#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:1915
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:6397
static void convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
Convert julian day to hour/minute/second.
Definition: sqlite3odbc.c:3056
char ** resarr
result array
Definition: sqlite3odbc.c:1410
#define verinfo(maj, min, lev)
Definition: sqlite3odbc.c:238
int s3stmt_noreset
False when sqlite3_reset() needed.
Definition: sqlite3odbc.h:284
static void dbtracerc(DBC *d, int rc, char *err)
Trace function for SQLite return codes.
Definition: sqlite3odbc.c:3896
int trans_disable
True for no transaction support.
Definition: sqlite3odbc.h:138
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:6862
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:242
int s3type
SQLite3 type.
Definition: sqlite3odbc.h:216
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:5397
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:8249
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:2511
SQLRETURN SQL_API SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
Function not implemented.
Definition: sqlite3odbc.c:5786
#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:257
int len
Offset/length for SQLParamData()/SQLPutData()
Definition: sqlite3odbc.h:213
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:8507
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:1942

Generated on Fri Dec 9 2016 by doxygen.
Contact: chw@ch-werner.de