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 types for static string column descriptions (SQLTables etc.) */
241 
242 #if defined(WINTERFACE) && !defined(_WIN32) && !defined(_WIN64)
243 #define SCOL_VARCHAR SQL_WVARCHAR
244 #define SCOL_CHAR SQL_WCHAR
245 #else
246 #define SCOL_VARCHAR SQL_VARCHAR
247 #define SCOL_CHAR SQL_CHAR
248 #endif
249 
250 #define ENV_MAGIC 0x53544145
251 #define DBC_MAGIC 0x53544144
252 #define DEAD_MAGIC 0xdeadbeef
253 
260 typedef struct dstr {
261  int len;
262  int max;
263  int oom;
264  char buffer[1];
265 } dstr;
266 
267 static const char *xdigits = "0123456789ABCDEFabcdef";
268 
269 #ifdef MEMORY_DEBUG
270 
271 static void *
272 xmalloc_(int n, char *file, int line)
273 {
274  int nn = n + 4 * sizeof (long);
275  long *p;
276 
277  p = malloc(nn);
278  if (!p) {
279 #if (MEMORY_DEBUG > 1)
280  fprintf(stderr, "malloc\t%d\tNULL\t%s:%d\n", n, file, line);
281 #endif
282  return NULL;
283  }
284  p[0] = 0xdead1234;
285  nn = nn / sizeof (long) - 1;
286  p[1] = n;
287  p[nn] = 0xdead5678;
288 #if (MEMORY_DEBUG > 1)
289  fprintf(stderr, "malloc\t%d\t%p\t%s:%d\n", n, &p[2], file, line);
290 #endif
291  return (void *) &p[2];
292 }
293 
294 static void *
295 xrealloc_(void *old, int n, char *file, int line)
296 {
297  int nn = n + 4 * sizeof (long), nnn;
298  long *p, *pp;
299 
300  if (n == 0 || !old) {
301  return xmalloc_(n, file, line);
302  }
303  p = &((long *) old)[-2];
304  if (p[0] != 0xdead1234) {
305  fprintf(stderr, "*** low end corruption @ %p\n", old);
306  abort();
307  }
308  nnn = p[1] + 4 * sizeof (long);
309  nnn = nnn / sizeof (long) - 1;
310  if (p[nnn] != 0xdead5678) {
311  fprintf(stderr, "*** high end corruption @ %p\n", old);
312  abort();
313  }
314  pp = realloc(p, nn);
315  if (!pp) {
316 #if (MEMORY_DEBUG > 1)
317  fprintf(stderr, "realloc\t%p,%d\tNULL\t%s:%d\n", old, n, file, line);
318 #endif
319  return NULL;
320  }
321 #if (MEMORY_DEBUG > 1)
322  fprintf(stderr, "realloc\t%p,%d\t%p\t%s:%d\n", old, n, &pp[2], file, line);
323 #endif
324  p = pp;
325  p[1] = n;
326  nn = nn / sizeof (long) - 1;
327  p[nn] = 0xdead5678;
328  return (void *) &p[2];
329 }
330 
331 static void
332 xfree_(void *x, char *file, int line)
333 {
334  long *p;
335  int n;
336 
337  if (!x) {
338  return;
339  }
340  p = &((long *) x)[-2];
341  if (p[0] != 0xdead1234) {
342  fprintf(stderr, "*** low end corruption @ %p\n", x);
343  abort();
344  }
345  n = p[1] + 4 * sizeof (long);
346  n = n / sizeof (long) - 1;
347  if (p[n] != 0xdead5678) {
348  fprintf(stderr, "*** high end corruption @ %p\n", x);
349  abort();
350  }
351 #if (MEMORY_DEBUG > 1)
352  fprintf(stderr, "free\t%p\t\t%s:%d\n", x, file, line);
353 #endif
354  free(p);
355 }
356 
357 static void
358 xfree__(void *x)
359 {
360  xfree_(x, "unknown location", 0);
361 }
362 
363 static char *
364 xstrdup_(const char *str, char *file, int line)
365 {
366  char *p;
367 
368  if (!str) {
369 #if (MEMORY_DEBUG > 1)
370  fprintf(stderr, "strdup\tNULL\tNULL\t%s:%d\n", file, line);
371 #endif
372  return NULL;
373  }
374  p = xmalloc_(strlen(str) + 1, file, line);
375  if (p) {
376  strcpy(p, str);
377  }
378 #if (MEMORY_DEBUG > 1)
379  fprintf(stderr, "strdup\t%p\t%p\t%s:%d\n", str, p, file, line);
380 #endif
381  return p;
382 }
383 
384 #define xmalloc(x) xmalloc_(x, __FILE__, __LINE__)
385 #define xrealloc(x,y) xrealloc_(x, y, __FILE__, __LINE__)
386 #define xfree(x) xfree_(x, __FILE__, __LINE__)
387 #define xstrdup(x) xstrdup_(x, __FILE__, __LINE__)
388 
389 #else
390 
391 #define xmalloc(x) sqlite3_malloc(x)
392 #define xrealloc(x,y) sqlite3_realloc(x, y)
393 #define xfree(x) sqlite3_free(x)
394 #define xstrdup(x) strdup_(x)
395 
396 #endif
397 
398 #if defined(_WIN32) || defined(_WIN64)
399 
400 #define vsnprintf _vsnprintf
401 #define snprintf _snprintf
402 #define strcasecmp _stricmp
403 #define strncasecmp _strnicmp
404 
405 #ifdef _MSC_VER
406 #define strtoll _strtoi64
407 #define strtoull _strtoui64
408 #endif
409 
410 static HINSTANCE NEAR hModule; /* Saved module handle for resources */
411 
412 #endif
413 
414 #ifdef HAVE_SQLITE3STRNICMP
415 #undef strncasecmp
416 #define strncasecmp(A,B,C) sqlite3_strnicmp(A,B,C)
417 #undef strcasecmp
418 #define strcasecmp(A,B) strcasecmp_(A,B)
419 
420 #if defined(__GNUC__) && (__GNUC__ >= 2)
421 static int strcasecmp_(const char *a, const char *b)
422  __attribute__((__unused__));
423 #endif
424 
425 static int strcasecmp_(const char *a, const char *b)
426 {
427  int c = strlen(a), d = strlen(b);
428 
429  if (c > d) {
430  return strncasecmp(a, b, c);
431  }
432  return strncasecmp(a, b, d);
433 }
434 #endif
435 
436 #if defined(_WIN32) || defined(_WIN64)
437 
438 /*
439  * SQLHENV, SQLHDBC, and SQLHSTMT synchronization
440  * is done using a critical section in ENV and DBC
441  * structures.
442  */
443 
444 #define HDBC_LOCK(hdbc) \
445 { \
446  DBC *d; \
447  \
448  if ((hdbc) == SQL_NULL_HDBC) { \
449  return SQL_INVALID_HANDLE; \
450  } \
451  d = (DBC *) (hdbc); \
452  if (d->magic != DBC_MAGIC) { \
453  return SQL_INVALID_HANDLE; \
454  } \
455  EnterCriticalSection(&d->cs); \
456  d->owner = GetCurrentThreadId(); \
457 }
458 
459 #define HDBC_UNLOCK(hdbc) \
460  if ((hdbc) != SQL_NULL_HDBC) { \
461  DBC *d; \
462  \
463  d = (DBC *) (hdbc); \
464  if (d->magic == DBC_MAGIC) { \
465  d->owner = 0; \
466  LeaveCriticalSection(&d->cs); \
467  } \
468  }
469 
470 #define HSTMT_LOCK(hstmt) \
471 { \
472  DBC *d; \
473  \
474  if ((hstmt) == SQL_NULL_HSTMT) { \
475  return SQL_INVALID_HANDLE; \
476  } \
477  d = (DBC *) ((STMT *) (hstmt))->dbc; \
478  if (d->magic != DBC_MAGIC) { \
479  return SQL_INVALID_HANDLE; \
480  } \
481  EnterCriticalSection(&d->cs); \
482  d->owner = GetCurrentThreadId(); \
483 }
484 
485 #define HSTMT_UNLOCK(hstmt) \
486  if ((hstmt) != SQL_NULL_HSTMT) { \
487  DBC *d; \
488  \
489  d = (DBC *) ((STMT *) (hstmt))->dbc; \
490  if (d->magic == DBC_MAGIC) { \
491  d->owner = 0; \
492  LeaveCriticalSection(&d->cs); \
493  } \
494  }
495 
496 #else
497 
498 /*
499  * On UN*X assume that we are single-threaded or
500  * the driver manager provides serialization for us.
501  *
502  * In iODBC (3.52.x) serialization can be turned
503  * on using the DSN property "ThreadManager=yes".
504  *
505  * In unixODBC that property is named
506  * "Threading=0-3" and takes one of these values:
507  *
508  * 0 - no protection
509  * 1 - statement level protection
510  * 2 - connection level protection
511  * 3 - environment level protection
512  *
513  * unixODBC 2.2.11 uses environment level protection
514  * by default when it has been built with pthread
515  * support.
516  */
517 
518 #define HDBC_LOCK(hdbc)
519 #define HDBC_UNLOCK(hdbc)
520 #define HSTMT_LOCK(hdbc)
521 #define HSTMT_UNLOCK(hdbc)
522 
523 #endif
524 
525 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
526 extern void nvfs_init(void);
527 extern const char *nvfs_makevfs(const char *);
528 #endif
529 
530 /*
531  * tolower() replacement w/o locale
532  */
533 
534 static const char upper_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
535 static const char lower_chars[] = "abcdefghijklmnopqrstuvwxyz";
536 
537 static int
538 TOLOWER(int c)
539 {
540  if (c) {
541  char *p = strchr(upper_chars, c);
542 
543  if (p) {
544  c = lower_chars[p - upper_chars];
545  }
546  }
547  return c;
548 }
549 
550 /*
551  * isdigit() replacement w/o ctype.h
552  */
553 
554 static const char digit_chars[] = "0123456789";
555 
556 #define ISDIGIT(c) \
557  ((c) && strchr(digit_chars, (c)) != NULL)
558 
559 /*
560  * isspace() replacement w/o ctype.h
561  */
562 
563 static const char space_chars[] = " \f\n\r\t\v";
564 
565 #define ISSPACE(c) \
566  ((c) && strchr(space_chars, (c)) != NULL)
567 
568 
569 /*
570  * Forward declarations of static functions.
571  */
572 
573 static void dbtraceapi(DBC *d, char *fn, const char *sql);
574 static void freedyncols(STMT *s);
575 static void freeresult(STMT *s, int clrcols);
576 static void freerows(char **rowp);
577 static void unbindcols(STMT *s);
578 static void s3stmt_drop(STMT *s);
579 
580 static SQLRETURN drvexecute(SQLHSTMT stmt, int initial);
581 static SQLRETURN freestmt(HSTMT stmt);
582 static SQLRETURN mkbindcols(STMT *s, int ncols);
583 static SQLRETURN setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp);
584 static SQLRETURN setupparbuf(STMT *s, BINDPARM *p);
585 static SQLRETURN starttran(STMT *s);
586 static SQLRETURN setupparam(STMT *s, char *sql, int pnum);
587 static SQLRETURN getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype,
588  SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp,
589  int partial);
590 
591 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
592 /* MS Access hack part 1 (reserved error -7748) */
593 static COL *statSpec2P, *statSpec3P;
594 #endif
595 
596 #if (MEMORY_DEBUG < 1)
597 
603 static char *
604 strdup_(const char *str)
605 {
606  char *p = NULL;
607 
608  if (str) {
609  p = xmalloc(strlen(str) + 1);
610  if (p) {
611  strcpy(p, str);
612  }
613  }
614  return p;
615 }
616 #endif
617 
625 static dstr *
626 dsappend(dstr *dsp, const char *str)
627 {
628  int len;
629 
630  if (!str) {
631  return dsp;
632  }
633  len = strlen(str);
634  if (!dsp) {
635  int max = 256;
636 
637  if (max < len) {
638  max += len;
639  }
640  dsp = xmalloc(max);
641  if (dsp) {
642  dsp->max = max;
643  dsp->len = dsp->oom = 0;
644  goto copy;
645  }
646  return dsp;
647  }
648  if (dsp->oom) {
649  return dsp;
650  }
651  if (dsp->len + len > dsp->max) {
652  int max = dsp->max + len + 256;
653  dstr *ndsp = xrealloc(dsp, max);
654 
655  if (!ndsp) {
656  strcpy(dsp->buffer, "OUT OF MEMORY");
657  dsp->max = dsp->len = 13;
658  dsp->oom = 1;
659  return dsp;
660  }
661  dsp = ndsp;
662  dsp->max = max;
663  }
664 copy:
665  strcpy(dsp->buffer + dsp->len, str);
666  dsp->len += len;
667  return dsp;
668 }
669 
677 static dstr *
678 dsappendq(dstr *dsp, const char *str)
679 {
680  int len;
681  const char *p;
682  char *q;
683 
684  if (!str) {
685  return dsp;
686  }
687  len = strlen(str);
688  for (p = str; *p; ++p) {
689  if (p[0] == '"') {
690  ++len;
691  }
692  }
693  if (!dsp) {
694  int max = 256;
695 
696  if (max < len) {
697  max += len;
698  }
699  dsp = xmalloc(max);
700  if (dsp) {
701  dsp->max = max;
702  dsp->len = dsp->oom = 0;
703  goto copy;
704  }
705  return dsp;
706  }
707  if (dsp->oom) {
708  return dsp;
709  }
710  if (dsp->len + len > dsp->max) {
711  int max = dsp->max + len + 256;
712  dstr *ndsp = xrealloc(dsp, max);
713 
714  if (!ndsp) {
715  strcpy(dsp->buffer, "OUT OF MEMORY");
716  dsp->max = dsp->len = 13;
717  dsp->oom = 1;
718  return dsp;
719  }
720  dsp = ndsp;
721  dsp->max = max;
722  }
723 copy:
724  for (p = str, q = dsp->buffer + dsp->len; *p; ++p) {
725  *q++ = *p;
726  if (p[0] == '"') {
727  *q++ = '"';
728  }
729  }
730  *q = '\0';
731  dsp->len += len;
732  return dsp;
733 }
734 
741 static const char *
742 dsval(dstr *dsp)
743 {
744  if (dsp) {
745  return (const char *) dsp->buffer;
746  }
747  return "ERROR";
748 }
749 
756 static int
757 dserr(dstr *dsp)
758 {
759  return !dsp || dsp->oom;
760 }
761 
767 static void
769 {
770  if (dsp) {
771  xfree(dsp);
772  }
773 }
774 
775 #ifdef WCHARSUPPORT
776 
783 static int
784 uc_strlen(SQLWCHAR *str)
785 {
786  int len = 0;
787 
788  if (str) {
789  while (*str) {
790  ++len;
791  ++str;
792  }
793  }
794  return len;
795 }
796 
805 static SQLWCHAR *
806 uc_strncpy(SQLWCHAR *dest, SQLWCHAR *src, int len)
807 {
808  int i = 0;
809 
810  while (i < len) {
811  if (!src[i]) {
812  break;
813  }
814  dest[i] = src[i];
815  ++i;
816  }
817  if (i < len) {
818  dest[i] = 0;
819  }
820  return dest;
821 }
822 
831 static void
832 uc_from_utf_buf(unsigned char *str, int len, SQLWCHAR *uc, int ucLen)
833 {
834  ucLen = ucLen / sizeof (SQLWCHAR);
835  if (!uc || ucLen < 0) {
836  return;
837  }
838  if (len < 0) {
839  len = ucLen * 5;
840  }
841  uc[0] = 0;
842  if (str) {
843  int i = 0;
844 
845  while (i < len && *str && i < ucLen) {
846  unsigned char c = str[0];
847 
848  if (c < 0x80) {
849  uc[i++] = c;
850  ++str;
851  } else if (c <= 0xc1 || c >= 0xf5) {
852  /* illegal, ignored */
853  ++str;
854  } else if (c < 0xe0) {
855  if ((str[1] & 0xc0) == 0x80) {
856  unsigned long t = ((c & 0x1f) << 6) | (str[1] & 0x3f);
857 
858  uc[i++] = t;
859  str += 2;
860  } else {
861  uc[i++] = c;
862  ++str;
863  }
864  } else if (c < 0xf0) {
865  if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80) {
866  unsigned long t = ((c & 0x0f) << 12) |
867  ((str[1] & 0x3f) << 6) | (str[2] & 0x3f);
868 
869  uc[i++] = t;
870  str += 3;
871  } else {
872  uc[i++] = c;
873  ++str;
874  }
875  } else if (c < 0xf8) {
876  if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 &&
877  (str[3] & 0xc0) == 0x80) {
878  unsigned long t = ((c & 0x03) << 18) |
879  ((str[1] & 0x3f) << 12) | ((str[2] & 0x3f) << 6) |
880  (str[3] & 0x3f);
881 
882  if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
883  t >= 0x10000) {
884  t -= 0x10000;
885  uc[i++] = 0xd800 | ((t >> 10) & 0x3ff);
886  if (i >= ucLen) {
887  break;
888  }
889  t = 0xdc00 | (t & 0x3ff);
890  }
891  uc[i++] = t;
892  str += 4;
893  } else {
894  uc[i++] = c;
895  ++str;
896  }
897  } else if (c < 0xfc) {
898  if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 &&
899  (str[3] & 0xc0) == 0x80 && (str[4] & 0xc0) == 0x80) {
900  unsigned long t = ((c & 0x01) << 24) |
901  ((str[1] & 0x3f) << 18) | ((str[2] & 0x3f) << 12) |
902  ((str[3] & 0x3f) << 6) | (str[4] & 0x3f);
903 
904  if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
905  t >= 0x10000) {
906  t -= 0x10000;
907  uc[i++] = 0xd800 | ((t >> 10) & 0x3ff);
908  if (i >= ucLen) {
909  break;
910  }
911  t = 0xdc00 | (t & 0x3ff);
912  }
913  uc[i++] = t;
914  str += 5;
915  } else {
916  uc[i++] = c;
917  ++str;
918  }
919  } else {
920  /* ignore */
921  ++str;
922  }
923  }
924  if (i < ucLen) {
925  uc[i] = 0;
926  }
927  }
928 }
929 
937 static SQLWCHAR *
938 uc_from_utf(unsigned char *str, int len)
939 {
940  SQLWCHAR *uc = NULL;
941  int ucLen;
942 
943  if (str) {
944  if (len == SQL_NTS) {
945  len = strlen((char *) str);
946  }
947  ucLen = sizeof (SQLWCHAR) * (len + 1);
948  uc = xmalloc(ucLen);
949  if (uc) {
950  uc_from_utf_buf(str, len, uc, ucLen);
951  }
952  }
953  return uc;
954 }
955 
963 static char *
964 uc_to_utf(SQLWCHAR *str, int len)
965 {
966  int i;
967  char *cp, *ret = NULL;
968 
969  if (!str) {
970  return ret;
971  }
972  if (len == SQL_NTS) {
973  len = uc_strlen(str);
974  } else {
975  len = len / sizeof (SQLWCHAR);
976  }
977  cp = xmalloc(len * 6 + 1);
978  if (!cp) {
979  return ret;
980  }
981  ret = cp;
982  for (i = 0; i < len; i++) {
983  unsigned long c = str[i];
984 
985  if (sizeof (SQLWCHAR) == 2 * sizeof (char)) {
986  c &= 0xffff;
987  }
988  if (c < 0x80) {
989  *cp++ = c;
990  } else if (c < 0x800) {
991  *cp++ = 0xc0 | ((c >> 6) & 0x1f);
992  *cp++ = 0x80 | (c & 0x3f);
993  } else if (c < 0x10000) {
994  if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
995  c >= 0xd800 && c <= 0xdbff && i + 1 < len) {
996  unsigned long c2 = str[i + 1] & 0xffff;
997 
998  if (c2 >= 0xdc00 && c2 <= 0xdfff) {
999  c = (((c & 0x3ff) << 10) | (c2 & 0x3ff)) + 0x10000;
1000  *cp++ = 0xf0 | ((c >> 18) & 0x07);
1001  *cp++ = 0x80 | ((c >> 12) & 0x3f);
1002  *cp++ = 0x80 | ((c >> 6) & 0x3f);
1003  *cp++ = 0x80 | (c & 0x3f);
1004  ++i;
1005  continue;
1006  }
1007  }
1008  *cp++ = 0xe0 | ((c >> 12) & 0x0f);
1009  *cp++ = 0x80 | ((c >> 6) & 0x3f);
1010  *cp++ = 0x80 | (c & 0x3f);
1011  } else if (c < 0x200000) {
1012  *cp++ = 0xf0 | ((c >> 18) & 0x07);
1013  *cp++ = 0x80 | ((c >> 12) & 0x3f);
1014  *cp++ = 0x80 | ((c >> 6) & 0x3f);
1015  *cp++ = 0x80 | (c & 0x3f);
1016  } else if (c < 0x4000000) {
1017  *cp++ = 0xf8 | ((c >> 24) & 0x03);
1018  *cp++ = 0x80 | ((c >> 18) & 0x3f);
1019  *cp++ = 0x80 | ((c >> 12) & 0x3f);
1020  *cp++ = 0x80 | ((c >> 6) & 0x3f);
1021  *cp++ = 0x80 | (c & 0x3f);
1022  } else if (c < 0x80000000) {
1023  *cp++ = 0xfc | ((c >> 31) & 0x01);
1024  *cp++ = 0x80 | ((c >> 24) & 0x3f);
1025  *cp++ = 0x80 | ((c >> 18) & 0x3f);
1026  *cp++ = 0x80 | ((c >> 12) & 0x3f);
1027  *cp++ = 0x80 | ((c >> 6) & 0x3f);
1028  *cp++ = 0x80 | (c & 0x3f);
1029  }
1030  }
1031  *cp = '\0';
1032  return ret;
1033 }
1034 
1035 #endif
1036 
1037 #ifdef WINTERFACE
1038 
1046 static char *
1047 uc_to_utf_c(SQLWCHAR *str, int len)
1048 {
1049  if (len != SQL_NTS) {
1050  len = len * sizeof (SQLWCHAR);
1051  }
1052  return uc_to_utf(str, len);
1053 }
1054 
1055 #endif
1056 
1057 #if defined(WCHARSUPPORT) || defined(_WIN32) || defined(_WIN64)
1058 
1064 static void
1065 uc_free(void *str)
1066 {
1067  if (str) {
1068  xfree(str);
1069  }
1070 }
1071 
1072 #endif
1073 
1074 #if defined(_WIN32) || defined(_WIN64)
1075 
1083 static char *
1084 wmb_to_utf(char *str, int len)
1085 {
1086  WCHAR *wstr;
1087  OSVERSIONINFO ovi;
1088  int nchar, is2k, cp = CP_OEMCP;
1089 
1090  ovi.dwOSVersionInfoSize = sizeof (ovi);
1091  GetVersionEx(&ovi);
1092  is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1093  if (AreFileApisANSI()) {
1094  cp = is2k ? CP_THREAD_ACP : CP_ACP;
1095  }
1096  nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
1097  wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
1098  if (!wstr) {
1099  return NULL;
1100  }
1101  wstr[0] = 0;
1102  nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
1103  wstr[nchar] = 0;
1104  str = xmalloc((nchar + 1) * 7);
1105  if (!str) {
1106  xfree(wstr);
1107  return NULL;
1108  }
1109  str[0] = '\0';
1110  nchar = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, nchar * 7, 0, 0);
1111  str[nchar] = '\0';
1112  xfree(wstr);
1113  return str;
1114 }
1115 
1116 #ifndef WINTERFACE
1117 
1125 static char *
1126 wmb_to_utf_c(char *str, int len)
1127 {
1128  if (len == SQL_NTS) {
1129  len = strlen(str);
1130  }
1131  return wmb_to_utf(str, len);
1132 }
1133 
1134 #endif
1135 
1143 static char *
1144 utf_to_wmb(char *str, int len)
1145 {
1146  WCHAR *wstr;
1147  OSVERSIONINFO ovi;
1148  int nchar, is2k, cp = CP_OEMCP;
1149 
1150  ovi.dwOSVersionInfoSize = sizeof (ovi);
1151  GetVersionEx(&ovi);
1152  is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1153  if (AreFileApisANSI()) {
1154  cp = is2k ? CP_THREAD_ACP : CP_ACP;
1155  }
1156  nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
1157  wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
1158  if (!wstr) {
1159  return NULL;
1160  }
1161  wstr[0] = 0;
1162  nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, wstr, nchar);
1163  wstr[nchar] = 0;
1164  str = xmalloc((nchar + 1) * 7);
1165  if (!str) {
1166  xfree(wstr);
1167  return NULL;
1168  }
1169  str[0] = '\0';
1170  nchar = WideCharToMultiByte(cp, 0, wstr, -1, str, nchar * 7, 0, 0);
1171  str[nchar] = '\0';
1172  xfree(wstr);
1173  return str;
1174 }
1175 
1176 #ifdef WINTERFACE
1177 
1185 static WCHAR *
1186 wmb_to_uc(char *str, int len)
1187 {
1188  WCHAR *wstr;
1189  OSVERSIONINFO ovi;
1190  int nchar, is2k, cp = CP_OEMCP;
1191 
1192  ovi.dwOSVersionInfoSize = sizeof (ovi);
1193  GetVersionEx(&ovi);
1194  is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1195  if (AreFileApisANSI()) {
1196  cp = is2k ? CP_THREAD_ACP : CP_ACP;
1197  }
1198  nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
1199  wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
1200  if (!wstr) {
1201  return NULL;
1202  }
1203  wstr[0] = 0;
1204  nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
1205  wstr[nchar] = 0;
1206  return wstr;
1207 }
1208 
1216 static char *
1217 uc_to_wmb(WCHAR *wstr, int len)
1218 {
1219  char *str;
1220  OSVERSIONINFO ovi;
1221  int nchar, is2k, cp = CP_OEMCP;
1222 
1223  ovi.dwOSVersionInfoSize = sizeof (ovi);
1224  GetVersionEx(&ovi);
1225  is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1226  if (AreFileApisANSI()) {
1227  cp = is2k ? CP_THREAD_ACP : CP_ACP;
1228  }
1229  nchar = WideCharToMultiByte(cp, 0, wstr, len, NULL, 0, 0, 0);
1230  str = xmalloc((nchar + 1) * 2);
1231  if (!str) {
1232  return NULL;
1233  }
1234  str[0] = '\0';
1235  nchar = WideCharToMultiByte(cp, 0, wstr, len, str, nchar * 2, 0, 0);
1236  str[nchar] = '\0';
1237  return str;
1238 }
1239 
1240 #endif /* WINTERFACE */
1241 
1242 #endif /* _WIN32 || _WIN64 */
1243 
1244 
1245 #ifdef USE_DLOPEN_FOR_GPPS
1246 
1247 #include <dlfcn.h>
1248 
1249 #define SQLGetPrivateProfileString(A,B,C,D,E,F) drvgpps(d,A,B,C,D,E,F)
1250 
1251 /*
1252  * EXPERIMENTAL: SQLGetPrivateProfileString infrastructure using
1253  * dlopen(), in theory this makes the driver independent from the
1254  * driver manager, i.e. the same driver binary can run with iODBC
1255  * and unixODBC.
1256  */
1257 
1258 static void
1259 drvgetgpps(DBC *d)
1260 {
1261  void *lib;
1262  int (*gpps)();
1263 
1264  lib = dlopen("libodbcinst.so.1", RTLD_LAZY);
1265  if (!lib) {
1266  lib = dlopen("libodbcinst.so", RTLD_LAZY);
1267  }
1268  if (!lib) {
1269  lib = dlopen("libiodbcinst.so.2", RTLD_LAZY);
1270  }
1271  if (!lib) {
1272  lib = dlopen("libiodbcinst.so", RTLD_LAZY);
1273  }
1274  if (lib) {
1275  gpps = (int (*)()) dlsym(lib, "SQLGetPrivateProfileString");
1276  if (!gpps) {
1277  dlclose(lib);
1278  return;
1279  }
1280  d->instlib = lib;
1281  d->gpps = gpps;
1282  }
1283 }
1284 
1285 static void
1286 drvrelgpps(DBC *d)
1287 {
1288  if (d->instlib) {
1289  dlclose(d->instlib);
1290  d->instlib = 0;
1291  }
1292 }
1293 
1294 static int
1295 drvgpps(DBC *d, char *sect, char *ent, char *def, char *buf,
1296  int bufsiz, char *fname)
1297 {
1298  if (d->gpps) {
1299  return d->gpps(sect, ent, def, buf, bufsiz, fname);
1300  }
1301  strncpy(buf, def, bufsiz);
1302  buf[bufsiz - 1] = '\0';
1303  return 1;
1304 }
1305 #else
1306 #include <odbcinst.h>
1307 #define drvgetgpps(d)
1308 #define drvrelgpps(d)
1309 #endif
1310 
1311 /*
1312  * Internal function to bind SQLite3 parameters.
1313  */
1314 
1315 static void
1316 s3bind(DBC *d, sqlite3_stmt *stmt, int nparams, BINDPARM *p)
1317 {
1318  int i;
1319 
1320  if (stmt && p && nparams > 0) {
1321  for (i = 0; i < nparams; i++, p++) {
1322  switch (p->s3type) {
1323  default:
1324  case SQLITE_NULL:
1325  sqlite3_bind_null(stmt, i + 1);
1326  if (d->trace) {
1327  fprintf(d->trace, "-- parameter %d: NULL\n", i + 1);
1328  fflush(d->trace);
1329  }
1330  break;
1331  case SQLITE_TEXT:
1332  sqlite3_bind_text(stmt, i + 1, p->s3val, p->s3size,
1333  SQLITE_STATIC);
1334  if (d->trace) {
1335  fprintf(d->trace, "-- parameter %d: '%*s'\n", i + 1,
1336  p->s3size, (char *) p->s3val);
1337  fflush(d->trace);
1338  }
1339  break;
1340  case SQLITE_BLOB:
1341  sqlite3_bind_blob(stmt, i + 1, p->s3val, p->s3size,
1342  SQLITE_STATIC);
1343  if (d->trace) {
1344  fprintf(d->trace, "-- parameter %d: [BLOB]'\n", i + 1);
1345  fflush(d->trace);
1346  }
1347  break;
1348  case SQLITE_FLOAT:
1349  sqlite3_bind_double(stmt, i + 1, p->s3dval);
1350  if (d->trace) {
1351  fprintf(d->trace, "-- parameter %d: %g\n",
1352  i + 1, p->s3dval);
1353  fflush(d->trace);
1354  }
1355  break;
1356  case SQLITE_INTEGER:
1357  if (p->s3size > sizeof (int)) {
1358  sqlite3_bind_int64(stmt, i + 1, p->s3lival);
1359  if (d->trace) {
1360  fprintf(d->trace,
1361 #ifdef _WIN32
1362  "-- parameter %d: %I64d\n",
1363 #else
1364  "-- parameter %d: %lld\n",
1365 #endif
1366  i + 1, p->s3lival);
1367  fflush(d->trace);
1368  }
1369  } else {
1370  sqlite3_bind_int(stmt, i + 1, p->s3ival);
1371  if (d->trace) {
1372  fprintf(d->trace, "-- parameter %d: %d\n",
1373  i + 1, p->s3ival);
1374  fflush(d->trace);
1375  }
1376  }
1377  break;
1378  }
1379  }
1380  }
1381 }
1382 
1390 typedef struct tblres {
1391  char **resarr;
1392  char *errmsg;
1393  sqlite3_stmt *stmt;
1394  STMT *s;
1395  int nalloc;
1396  int nrow;
1397  int ncol;
1399  int rc;
1400 } TBLRES;
1401 
1402 /*
1403  * Driver's version of sqlite3_get_table() and friends which are
1404  * capable of dealing with blobs.
1405  */
1406 
1407 static int
1408 drvgettable_row(TBLRES *t, int ncol, int rc)
1409 {
1410  int need;
1411  int i;
1412  char *p;
1413 
1414  if (t->nrow == 0 && rc == SQLITE_ROW) {
1415  need = ncol * 2;
1416  } else {
1417  need = ncol;
1418  }
1419  if (t->ndata + need >= t->nalloc) {
1420  char **resnew;
1421  int nalloc = t->nalloc * 2 + need + 1;
1422 
1423  resnew = xrealloc(t->resarr, sizeof (char *) * nalloc);
1424  if (!resnew) {
1425 nomem:
1426  t->rc = SQLITE_NOMEM;
1427  return 1;
1428  }
1429  t->nalloc = nalloc;
1430  t->resarr = resnew;
1431  }
1432  /* column names when first row */
1433  if (t->nrow == 0) {
1434  t->ncol = ncol;
1435  for (i = 0; i < ncol; i++) {
1436  p = (char *) sqlite3_column_name(t->stmt, i);
1437  if (p) {
1438  char *q = xmalloc(strlen(p) + 1);
1439 
1440  if (!q) {
1441  goto nomem;
1442  }
1443  strcpy(q, p);
1444  p = q;
1445  }
1446  t->resarr[t->ndata++] = p;
1447  }
1448  if (t->s && t->s->guessed_types) {
1449  int ncol2 = ncol;
1450 
1451  setupdyncols(t->s, t->stmt, &ncol2);
1452  t->s->guessed_types = 0;
1453  t->s->ncols = ncol;
1454  }
1455  } else if (t->ncol != ncol) {
1456  t->errmsg = sqlite3_mprintf("drvgettable() called with two or"
1457  " more incompatible queries");
1458  t->rc = SQLITE_ERROR;
1459  return 1;
1460  }
1461  /* copy row data */
1462  if (rc == SQLITE_ROW) {
1463  for (i = 0; i < ncol; i++) {
1464  int coltype = sqlite3_column_type(t->stmt, i);
1465 
1466  p = NULL;
1467  if (coltype == SQLITE_BLOB) {
1468  int k, nbytes = sqlite3_column_bytes(t->stmt, i);
1469  char *qp;
1470  unsigned const char *bp;
1471 
1472  bp = sqlite3_column_blob(t->stmt, i);
1473  qp = xmalloc(nbytes * 2 + 4);
1474  if (!qp) {
1475  goto nomem;
1476  }
1477  p = qp;
1478  *qp++ = 'X';
1479  *qp++ = '\'';
1480  for (k = 0; k < nbytes; k++) {
1481  *qp++ = xdigits[(bp[k] >> 4)];
1482  *qp++ = xdigits[(bp[k] & 0xF)];
1483  }
1484  *qp++ = '\'';
1485  *qp = '\0';
1486 #ifdef _MSC_VER
1487  } else if (coltype == SQLITE_FLOAT) {
1488  static struct lconv *lc = 0;
1489  double val = sqlite3_column_double(t->stmt, i);
1490  char buffer[128];
1491 
1492  /*
1493  * This avoids floating point rounding
1494  * and formatting problems of some SQLite
1495  * versions in conjunction with MSVC 2010.
1496  */
1497  snprintf(buffer, sizeof (buffer), "%.15g", val);
1498  if (!lc) {
1499  lc = localeconv();
1500  }
1501  if (lc && lc->decimal_point && lc->decimal_point[0] &&
1502  lc->decimal_point[0] != '.') {
1503  p = strchr(buffer, lc->decimal_point[0]);
1504  if (p) {
1505  *p = '.';
1506  }
1507  }
1508  p = xstrdup(buffer);
1509  if (!p) {
1510  goto nomem;
1511  }
1512 #endif
1513  } else if (coltype != SQLITE_NULL) {
1514  p = xstrdup((char *) sqlite3_column_text(t->stmt, i));
1515  if (!p) {
1516  goto nomem;
1517  }
1518  }
1519  t->resarr[t->ndata++] = p;
1520  }
1521  t->nrow++;
1522  }
1523  return 0;
1524 }
1525 
1526 static int
1527 drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp,
1528  int *ncolp, char **errp, int nparam, BINDPARM *p)
1529 {
1530  DBC *d = (DBC *) s->dbc;
1531  int rc = SQLITE_OK, keep = sql == NULL;
1532  TBLRES tres;
1533  const char *sqlleft = 0;
1534  int nretry = 0, haveerr = 0;
1535 
1536  if (!resp) {
1537  return SQLITE_ERROR;
1538  }
1539  *resp = NULL;
1540  if (nrowp) {
1541  *nrowp = 0;
1542  }
1543  if (ncolp) {
1544  *ncolp = 0;
1545  }
1546  tres.errmsg = NULL;
1547  tres.nrow = 0;
1548  tres.ncol = 0;
1549  tres.ndata = 1;
1550  tres.nalloc = 20;
1551  tres.rc = SQLITE_OK;
1552  tres.resarr = xmalloc(sizeof (char *) * tres.nalloc);
1553  tres.stmt = NULL;
1554  tres.s = s;
1555  if (!tres.resarr) {
1556  return SQLITE_NOMEM;
1557  }
1558  tres.resarr[0] = 0;
1559  if (sql == NULL) {
1560  tres.stmt = s->s3stmt;
1561  if (tres.stmt == NULL) {
1562  return SQLITE_NOMEM;
1563  }
1564  goto retrieve;
1565  }
1566  while (sql && *sql && (rc == SQLITE_OK ||
1567  (rc == SQLITE_SCHEMA && (++nretry) < 2))) {
1568  int ncol;
1569 
1570  tres.stmt = NULL;
1571 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
1572  dbtraceapi(d, "sqlite3_prepare_v2", sql);
1573  rc = sqlite3_prepare_v2(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
1574 #else
1575  dbtraceapi(d, "sqlite3_prepare", sql);
1576  rc = sqlite3_prepare(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
1577 #endif
1578  if (rc != SQLITE_OK) {
1579  if (tres.stmt) {
1580  dbtraceapi(d, "sqlite3_finalize", 0);
1581  sqlite3_finalize(tres.stmt);
1582  tres.stmt = NULL;
1583  }
1584  continue;
1585  }
1586  if (!tres.stmt) {
1587  /* this happens for a comment or white-space */
1588  sql = sqlleft;
1589  continue;
1590  }
1591 retrieve:
1592  if (sqlite3_bind_parameter_count(tres.stmt) != nparam) {
1593  if (errp) {
1594  *errp =
1595  sqlite3_mprintf("%s", "parameter marker count incorrect");
1596  }
1597  haveerr = 1;
1598  rc = SQLITE_ERROR;
1599  goto tbldone;
1600  }
1601  s3bind(d, tres.stmt, nparam, p);
1602  ncol = sqlite3_column_count(tres.stmt);
1603  while (1) {
1604  if (s->max_rows && tres.nrow >= s->max_rows) {
1605  rc = SQLITE_OK;
1606  break;
1607  }
1608  rc = sqlite3_step(tres.stmt);
1609  if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
1610  if (drvgettable_row(&tres, ncol, rc)) {
1611  rc = SQLITE_ABORT;
1612  goto tbldone;
1613  }
1614  }
1615  if (rc != SQLITE_ROW) {
1616  if (keep) {
1617  dbtraceapi(d, "sqlite3_reset", 0);
1618  rc = sqlite3_reset(tres.stmt);
1619  s->s3stmt_noreset = 1;
1620  } else {
1621  dbtraceapi(d, "sqlite3_finalize", 0);
1622  rc = sqlite3_finalize(tres.stmt);
1623  }
1624  tres.stmt = 0;
1625  if (rc != SQLITE_SCHEMA) {
1626  nretry = 0;
1627  sql = sqlleft;
1628  while (sql && ISSPACE(*sql)) {
1629  sql++;
1630  }
1631  }
1632  if (rc == SQLITE_DONE) {
1633  rc = SQLITE_OK;
1634  }
1635  break;
1636  }
1637  }
1638  }
1639 tbldone:
1640  if (tres.stmt) {
1641  if (keep) {
1642  if (!s->s3stmt_noreset) {
1643  dbtraceapi(d, "sqlite3_reset", 0);
1644  sqlite3_reset(tres.stmt);
1645  s->s3stmt_noreset = 1;
1646  }
1647  } else {
1648  dbtraceapi(d, "sqlite3_finalize", 0);
1649  sqlite3_finalize(tres.stmt);
1650  }
1651  }
1652  if (haveerr) {
1653  /* message already in *errp if any */
1654  } else if (rc != SQLITE_OK && rc == sqlite3_errcode(d->sqlite) && errp) {
1655  *errp = sqlite3_mprintf("%s", sqlite3_errmsg(d->sqlite));
1656  } else if (errp) {
1657  *errp = NULL;
1658  }
1659  if (tres.resarr) {
1660  tres.resarr[0] = (char *) (tres.ndata - 1);
1661  }
1662  if (rc == SQLITE_ABORT) {
1663  freerows(&tres.resarr[1]);
1664  if (tres.errmsg) {
1665  if (errp) {
1666  if (*errp) {
1667  sqlite3_free(*errp);
1668  }
1669  *errp = tres.errmsg;
1670  } else {
1671  sqlite3_free(tres.errmsg);
1672  }
1673  }
1674  return tres.rc;
1675  }
1676  sqlite3_free(tres.errmsg);
1677  if (rc != SQLITE_OK) {
1678  freerows(&tres.resarr[1]);
1679  return rc;
1680  }
1681  *resp = &tres.resarr[1];
1682  if (ncolp) {
1683  *ncolp = tres.ncol;
1684  }
1685  if (nrowp) {
1686  *nrowp = tres.nrow;
1687  }
1688  return rc;
1689 }
1690 
1699 #if defined(__GNUC__) && (__GNUC__ >= 2)
1700 static void setstatd(DBC *, int, char *, char *, ...)
1701  __attribute__((format (printf, 3, 5)));
1702 #endif
1703 
1704 static void
1705 setstatd(DBC *d, int naterr, char *msg, char *st, ...)
1706 {
1707  va_list ap;
1708 
1709  if (!d) {
1710  return;
1711  }
1712  d->naterr = naterr;
1713  d->logmsg[0] = '\0';
1714  if (msg) {
1715  int count;
1716 
1717  va_start(ap, st);
1718  count = vsnprintf((char *) d->logmsg, sizeof (d->logmsg), msg, ap);
1719  va_end(ap);
1720  if (count < 0) {
1721  d->logmsg[sizeof (d->logmsg) - 1] = '\0';
1722  }
1723  }
1724  if (!st) {
1725  st = "?????";
1726  }
1727  strncpy(d->sqlstate, st, 5);
1728  d->sqlstate[5] = '\0';
1729 }
1730 
1739 #if defined(__GNUC__) && (__GNUC__ >= 2)
1740 static void setstat(STMT *, int, char *, char *, ...)
1741  __attribute__((format (printf, 3, 5)));
1742 #endif
1743 
1744 static void
1745 setstat(STMT *s, int naterr, char *msg, char *st, ...)
1746 {
1747  va_list ap;
1748 
1749  if (!s) {
1750  return;
1751  }
1752  s->naterr = naterr;
1753  s->logmsg[0] = '\0';
1754  if (msg) {
1755  int count;
1756 
1757  va_start(ap, st);
1758  count = vsnprintf((char *) s->logmsg, sizeof (s->logmsg), msg, ap);
1759  va_end(ap);
1760  if (count < 0) {
1761  s->logmsg[sizeof (s->logmsg) - 1] = '\0';
1762  }
1763  }
1764  if (!st) {
1765  st = "?????";
1766  }
1767  strncpy(s->sqlstate, st, 5);
1768  s->sqlstate[5] = '\0';
1769 }
1770 
1777 static SQLRETURN
1779 {
1780  DBC *d;
1781 
1782  if (dbc == SQL_NULL_HDBC) {
1783  return SQL_INVALID_HANDLE;
1784  }
1785  d = (DBC *) dbc;
1786  setstatd(d, -1, "not supported", "IM001");
1787  return SQL_ERROR;
1788 }
1789 
1796 static SQLRETURN
1798 {
1799  STMT *s;
1800 
1801  if (stmt == SQL_NULL_HSTMT) {
1802  return SQL_INVALID_HANDLE;
1803  }
1804  s = (STMT *) stmt;
1805  setstat(s, -1, "not supported", "IM001");
1806  return SQL_ERROR;
1807 }
1808 
1814 static void
1815 freep(void *x)
1816 {
1817  if (x && ((char **) x)[0]) {
1818  xfree(((char **) x)[0]);
1819  ((char **) x)[0] = NULL;
1820  }
1821 }
1822 
1829 static SQLRETURN
1831 {
1832  setstat(s, -1, "out of memory", (*s->ov3) ? "HY000" : "S1000");
1833  return SQL_ERROR;
1834 }
1835 
1842 static SQLRETURN
1844 {
1845  setstat(s, -1, "not connected", (*s->ov3) ? "HY000" : "S1000");
1846  return SQL_ERROR;
1847 }
1848 
1856 #if defined(HAVE_LOCALECONV) || defined(_WIN32) || defined(_WIN64)
1857 
1858 static double
1859 ln_strtod(const char *data, char **endp)
1860 {
1861  static struct lconv *lc = 0;
1862  char buf[128], *p, *end;
1863  double value;
1864 
1865  if (!lc) {
1866  lc = localeconv();
1867  }
1868  if (lc && lc->decimal_point && lc->decimal_point[0] &&
1869  lc->decimal_point[0] != '.') {
1870  strncpy(buf, data, sizeof (buf) - 1);
1871  buf[sizeof (buf) - 1] = '\0';
1872  p = strchr(buf, '.');
1873  if (p) {
1874  *p = lc->decimal_point[0];
1875  }
1876  p = buf;
1877  } else {
1878  p = (char *) data;
1879  }
1880  value = strtod(p, &end);
1881  end = (char *) data + (end - p);
1882  if (endp) {
1883  *endp = end;
1884  }
1885  return value;
1886 }
1887 
1888 #else
1889 
1890 #define ln_strtod(A,B) strtod(A,B)
1891 
1892 #endif
1893 
1899 static char *
1900 unquote(char *str)
1901 {
1902  if (str) {
1903  int len = strlen(str);
1904 
1905  if (len > 1) {
1906  if ((str[0] == '\'' && str[len - 1] == '\'') ||
1907  (str[0] == '"' && str[len - 1] == '"') ||
1908  (str[0] == '[' && str[len - 1] == ']')) {
1909  str[len - 1] = '\0';
1910  strcpy(str, str + 1);
1911  }
1912  }
1913  }
1914  return str;
1915 }
1916 
1924 static int
1925 unescpat(char *str)
1926 {
1927  char *p, *q;
1928  int count = 0;
1929 
1930  p = str;
1931  while ((q = strchr(p, '_')) != NULL) {
1932  if (q == str || q[-1] != '\\') {
1933  count++;
1934  }
1935  p = q + 1;
1936  }
1937  p = str;
1938  while ((q = strchr(p, '%')) != NULL) {
1939  if (q == str || q[-1] != '\\') {
1940  count++;
1941  }
1942  p = q + 1;
1943  }
1944  p = str;
1945  while ((q = strchr(p, '\\')) != NULL) {
1946  if (q[1] == '\\' || q[1] == '_' || q[1] == '%') {
1947  strcpy(q, q + 1);
1948  }
1949  p = q + 1;
1950  }
1951  return count;
1952 }
1953 
1962 static int
1963 namematch(char *str, char *pat, int esc)
1964 {
1965  int cp, ch;
1966 
1967  while (1) {
1968  cp = TOLOWER(*pat);
1969  if (cp == '\0') {
1970  if (*str != '\0') {
1971  goto nomatch;
1972  }
1973  break;
1974  }
1975  if (*str == '\0' && cp != '%') {
1976  goto nomatch;
1977  }
1978  if (cp == '%') {
1979  while (*pat == '%') {
1980  ++pat;
1981  }
1982  cp = TOLOWER(*pat);
1983  if (cp == '\0') {
1984  break;
1985  }
1986  while (1) {
1987  if (cp != '_' && cp != '\\') {
1988  while (*str) {
1989  ch = TOLOWER(*str);
1990  if (ch == cp) {
1991  break;
1992  }
1993  ++str;
1994  }
1995  }
1996  if (namematch(str, pat, esc)) {
1997  goto match;
1998  }
1999  if (*str == '\0') {
2000  goto nomatch;
2001  }
2002  ch = TOLOWER(*str);
2003  ++str;
2004  }
2005  }
2006  if (cp == '_') {
2007  pat++;
2008  str++;
2009  continue;
2010  }
2011  if (esc && cp == '\\' &&
2012  (pat[1] == '\\' || pat[1] == '%' || pat[1] == '_')) {
2013  ++pat;
2014  cp = TOLOWER(*pat);
2015  }
2016  ch = TOLOWER(*str++);
2017  ++pat;
2018  if (ch != cp) {
2019  goto nomatch;
2020  }
2021  }
2022 match:
2023  return 1;
2024 nomatch:
2025  return 0;
2026 }
2027 
2035 static int
2036 busy_handler(void *udata, int count)
2037 {
2038  DBC *d = (DBC *) udata;
2039  long t1;
2040  int ret = 0;
2041 #if !defined(_WIN32) && !defined(_WIN64)
2042  struct timeval tv;
2043 #ifdef HAVE_NANOSLEEP
2044  struct timespec ts;
2045 #endif
2046 #endif
2047 
2048  if (d->busyint) {
2049  d->busyint = 0;
2050  return ret;
2051  }
2052  if (d->timeout <= 0) {
2053  return ret;
2054  }
2055  if (count <= 1) {
2056 #if defined(_WIN32) || defined(_WIN64)
2057  d->t0 = GetTickCount();
2058 #else
2059  gettimeofday(&tv, NULL);
2060  d->t0 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
2061 #endif
2062  }
2063 #if defined(_WIN32) || defined(_WIN64)
2064  t1 = GetTickCount();
2065 #else
2066  gettimeofday(&tv, NULL);
2067  t1 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
2068 #endif
2069  if (t1 - d->t0 > d->timeout) {
2070  goto done;
2071  }
2072 #if defined(_WIN32) || defined(_WIN64)
2073  Sleep(10);
2074 #else
2075 #ifdef HAVE_NANOSLEEP
2076  ts.tv_sec = 0;
2077  ts.tv_nsec = 10000000;
2078  do {
2079  ret = nanosleep(&ts, &ts);
2080  if (ret < 0 && errno != EINTR) {
2081  ret = 0;
2082  }
2083  } while (ret);
2084 #else
2085 #ifdef HAVE_USLEEP
2086  usleep(10000);
2087 #else
2088  tv.tv_sec = 0;
2089  tv.tv_usec = 10000;
2090  select(0, NULL, NULL, NULL, &tv);
2091 #endif
2092 #endif
2093 #endif
2094  ret = 1;
2095 done:
2096  return ret;
2097 }
2098 
2110 static int
2111 setsqliteopts(sqlite3 *x, DBC *d)
2112 {
2113  int count = 0, step = 0, max, rc = SQLITE_ERROR;
2114 
2115 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
2116  max = d->longnames ? 3 : 1;
2117 #else
2118  max = 3;
2119 #endif
2120  if (d->shortnames) {
2121  max = 3;
2122  }
2123  while (step < max) {
2124  if (step < 1) {
2125  rc = sqlite3_exec(x, "PRAGMA empty_result_callbacks = on;",
2126  NULL, NULL, NULL);
2127  if (rc == SQLITE_OK) {
2128  rc = sqlite3_exec(x, d->fksupport ?
2129  "PRAGMA foreign_keys = on;" :
2130  "PRAGMA foreign_keys = off;",
2131  NULL, NULL, NULL);
2132  }
2133  } else if (step < 2) {
2134  rc = sqlite3_exec(x, d->shortnames ?
2135  "PRAGMA full_column_names = off;" :
2136  "PRAGMA full_column_names = on;",
2137  NULL, NULL, NULL);
2138  } else if (step < 3) {
2139  rc = sqlite3_exec(x, d->shortnames ?
2140  "PRAGMA short_column_names = on;" :
2141  "PRAGMA short_column_names = off;",
2142  NULL, NULL, NULL);
2143  }
2144  if (rc != SQLITE_OK) {
2145  if (rc != SQLITE_BUSY ||
2146  !busy_handler((void *) d, ++count)) {
2147  return rc;
2148  }
2149  continue;
2150  }
2151  count = 0;
2152  ++step;
2153  }
2154  sqlite3_busy_handler(x, busy_handler, (void *) d);
2155  return SQLITE_OK;
2156 }
2157 
2167 static void
2168 freerows(char **rowp)
2169 {
2170  PTRDIFF_T size, i;
2171 
2172  if (!rowp) {
2173  return;
2174  }
2175  --rowp;
2176  size = (PTRDIFF_T) rowp[0];
2177  for (i = 1; i <= size; i++) {
2178  freep(&rowp[i]);
2179  }
2180  freep(&rowp);
2181 }
2182 
2193 static int
2194 mapsqltype(const char *typename, int *nosign, int ov3, int nowchar,
2195  int dobigint)
2196 {
2197  char *p, *q;
2198  int testsign = 0, result;
2199 
2200 #ifdef WINTERFACE
2201  result = nowchar ? SQL_VARCHAR : SQL_WVARCHAR;
2202 #else
2203  result = SQL_VARCHAR;
2204 #endif
2205  if (!typename) {
2206  return result;
2207  }
2208  q = p = xmalloc(strlen(typename) + 1);
2209  if (!p) {
2210  return result;
2211  }
2212  strcpy(p, typename);
2213  while (*q) {
2214  *q = TOLOWER(*q);
2215  ++q;
2216  }
2217  if (strncmp(p, "inter", 5) == 0) {
2218  } else if (strncmp(p, "int", 3) == 0 ||
2219  strncmp(p, "mediumint", 9) == 0) {
2220  testsign = 1;
2221  result = SQL_INTEGER;
2222  } else if (strncmp(p, "numeric", 7) == 0) {
2223  result = SQL_DOUBLE;
2224  } else if (strncmp(p, "tinyint", 7) == 0) {
2225  testsign = 1;
2226  result = SQL_TINYINT;
2227  } else if (strncmp(p, "smallint", 8) == 0) {
2228  testsign = 1;
2229  result = SQL_SMALLINT;
2230  } else if (strncmp(p, "float", 5) == 0) {
2231  result = SQL_DOUBLE;
2232  } else if (strncmp(p, "double", 6) == 0 ||
2233  strncmp(p, "real", 4) == 0) {
2234  result = SQL_DOUBLE;
2235  } else if (strncmp(p, "timestamp", 9) == 0) {
2236 #ifdef SQL_TYPE_TIMESTAMP
2237  result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
2238 #else
2239  result = SQL_TIMESTAMP;
2240 #endif
2241  } else if (strncmp(p, "datetime", 8) == 0) {
2242 #ifdef SQL_TYPE_TIMESTAMP
2243  result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
2244 #else
2245  result = SQL_TIMESTAMP;
2246 #endif
2247  } else if (strncmp(p, "time", 4) == 0) {
2248 #ifdef SQL_TYPE_TIME
2249  result = ov3 ? SQL_TYPE_TIME : SQL_TIME;
2250 #else
2251  result = SQL_TIME;
2252 #endif
2253  } else if (strncmp(p, "date", 4) == 0) {
2254 #ifdef SQL_TYPE_DATE
2255  result = ov3 ? SQL_TYPE_DATE : SQL_DATE;
2256 #else
2257  result = SQL_DATE;
2258 #endif
2259 #ifdef SQL_LONGVARCHAR
2260  } else if (strncmp(p, "text", 4) == 0 ||
2261  strncmp(p, "memo", 4) == 0 ||
2262  strncmp(p, "longvarchar", 11) == 0) {
2263 #ifdef WINTERFACE
2264  result = nowchar ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
2265 #else
2266  result = SQL_LONGVARCHAR;
2267 #endif
2268 #ifdef WINTERFACE
2269  } else if (strncmp(p, "wtext", 5) == 0 ||
2270  strncmp(p, "wvarchar", 8) == 0 ||
2271  strncmp(p, "longwvarchar", 12) == 0) {
2272  result = SQL_WLONGVARCHAR;
2273 #endif
2274 #endif
2275 #ifdef SQL_BIT
2276  } else if (strncmp(p, "bool", 4) == 0 ||
2277  strncmp(p, "bit", 3) == 0) {
2278  result = SQL_BIT;
2279 #endif
2280 #ifdef SQL_BIGINT
2281  } else if (strncmp(p, "bigint", 6) == 0) {
2282  testsign = 1;
2283  result = SQL_BIGINT;
2284 #endif
2285  } else if (strncmp(p, "blob", 4) == 0) {
2286  result = SQL_BINARY;
2287  } else if (strncmp(p, "varbinary", 9) == 0) {
2288  result = SQL_VARBINARY;
2289  } else if (strncmp(p, "longvarbinary", 13) == 0) {
2290  result = SQL_LONGVARBINARY;
2291  }
2292  if (nosign) {
2293  if (testsign) {
2294  *nosign = strstr(p, "unsigned") != NULL;
2295  } else {
2296  *nosign = 1;
2297  }
2298  }
2299 #ifdef SQL_BIGINT
2300  if (dobigint && result == SQL_INTEGER) {
2301  result = SQL_BIGINT;
2302  }
2303 #endif
2304  xfree(p);
2305  return result;
2306 }
2307 
2317 static void
2318 getmd(const char *typename, int sqltype, int *mp, int *dp)
2319 {
2320  int m = 0, d = 0;
2321 
2322  switch (sqltype) {
2323  case SQL_INTEGER: m = 10; d = 9; break;
2324  case SQL_TINYINT: m = 4; d = 3; break;
2325  case SQL_SMALLINT: m = 6; d = 5; break;
2326  case SQL_FLOAT: m = 25; d = 24; break;
2327  case SQL_DOUBLE: m = 54; d = 53; break;
2328  case SQL_VARCHAR: m = 255; d = 0; break;
2329 #ifdef WINTERFACE
2330 #ifdef SQL_WVARCHAR
2331  case SQL_WVARCHAR: m = 255; d = 0; break;
2332 #endif
2333 #endif
2334 #ifdef SQL_TYPE_DATE
2335  case SQL_TYPE_DATE:
2336 #endif
2337  case SQL_DATE: m = 10; d = 0; break;
2338 #ifdef SQL_TYPE_TIME
2339  case SQL_TYPE_TIME:
2340 #endif
2341  case SQL_TIME: m = 8; d = 0; break;
2342 #ifdef SQL_TYPE_TIMESTAMP
2343  case SQL_TYPE_TIMESTAMP:
2344 #endif
2345  case SQL_TIMESTAMP: m = 32; d = 3; break;
2346 #ifdef SQL_LONGVARCHAR
2347  case SQL_LONGVARCHAR : m = 65536; d = 0; break;
2348 #endif
2349 #ifdef WINTERFACE
2350 #ifdef SQL_WLONGVARCHAR
2351  case SQL_WLONGVARCHAR: m = 65536; d = 0; break;
2352 #endif
2353 #endif
2354  case SQL_BINARY:
2355  case SQL_VARBINARY: m = 255; d = 0; break;
2356  case SQL_LONGVARBINARY: m = 65536; d = 0; break;
2357 #ifdef SQL_BIGINT
2358  case SQL_BIGINT: m = 20; d = 19; break;
2359 #endif
2360 #ifdef SQL_BIT
2361  case SQL_BIT: m = 1; d = 1; break;
2362 #endif
2363  }
2364  if (m && typename) {
2365  int mm, dd;
2366  char clbr[4];
2367 
2368  if (sscanf(typename, "%*[^(](%d,%d %1[)]", &mm, &dd, clbr) == 3) {
2369  m = mm;
2370  d = dd;
2371  } else if (sscanf(typename, "%*[^(](%d %1[)]", &mm, clbr) == 2) {
2372  if (sqltype == SQL_TIMESTAMP) {
2373  d = mm;
2374  }
2375 #ifdef SQL_TYPE_TIMESTAMP
2376  else if (sqltype == SQL_TYPE_TIMESTAMP) {
2377  d = mm;
2378  }
2379 #endif
2380  else {
2381  m = d = mm;
2382  }
2383  }
2384  }
2385  if (mp) {
2386  *mp = m;
2387  }
2388  if (dp) {
2389  *dp = d;
2390  }
2391 }
2392 
2402 static int
2403 mapdeftype(int type, int stype, int nosign, int nowchar)
2404 {
2405  if (type == SQL_C_DEFAULT) {
2406  switch (stype) {
2407  case SQL_INTEGER:
2408  type = (nosign > 0) ? SQL_C_ULONG : SQL_C_LONG;
2409  break;
2410  case SQL_TINYINT:
2411  type = (nosign > 0) ? SQL_C_UTINYINT : SQL_C_TINYINT;
2412  break;
2413  case SQL_SMALLINT:
2414  type = (nosign > 0) ? SQL_C_USHORT : SQL_C_SHORT;
2415  break;
2416  case SQL_FLOAT:
2417  type = SQL_C_FLOAT;
2418  break;
2419  case SQL_DOUBLE:
2420  type = SQL_C_DOUBLE;
2421  break;
2422  case SQL_TIMESTAMP:
2423  type = SQL_C_TIMESTAMP;
2424  break;
2425  case SQL_TIME:
2426  type = SQL_C_TIME;
2427  break;
2428  case SQL_DATE:
2429  type = SQL_C_DATE;
2430  break;
2431 #ifdef SQL_C_TYPE_TIMESTAMP
2432  case SQL_TYPE_TIMESTAMP:
2433  type = SQL_C_TYPE_TIMESTAMP;
2434  break;
2435 #endif
2436 #ifdef SQL_C_TYPE_TIME
2437  case SQL_TYPE_TIME:
2438  type = SQL_C_TYPE_TIME;
2439  break;
2440 #endif
2441 #ifdef SQL_C_TYPE_DATE
2442  case SQL_TYPE_DATE:
2443  type = SQL_C_TYPE_DATE;
2444  break;
2445 #endif
2446 #ifdef WINTERFACE
2447  case SQL_WVARCHAR:
2448  case SQL_WCHAR:
2449 #ifdef SQL_WLONGVARCHAR
2450  case SQL_WLONGVARCHAR:
2451 #endif
2452  type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
2453  break;
2454 #endif
2455  case SQL_BINARY:
2456  case SQL_VARBINARY:
2457  case SQL_LONGVARBINARY:
2458  type = SQL_C_BINARY;
2459  break;
2460 #ifdef SQL_BIT
2461  case SQL_BIT:
2462  type = SQL_C_BIT;
2463  break;
2464 #endif
2465 #ifdef SQL_BIGINT
2466  case SQL_BIGINT:
2467  type = SQL_C_CHAR;
2468  break;
2469 #endif
2470  default:
2471 #ifdef WINTERFACE
2472  type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
2473 #else
2474  type = SQL_C_CHAR;
2475 #endif
2476  break;
2477  }
2478  }
2479  return type;
2480 }
2481 
2493 static char *
2494 fixupsql(char *sql, int sqlLen, int cte, int *nparam, int *isselect,
2495  char **errmsg)
2496 {
2497  char *q = sql, *qz = NULL, *p, *inq = NULL, *out;
2498  int np = 0, isddl = -1, size;
2499 
2500  if (errmsg) {
2501  *errmsg = NULL;
2502  }
2503  if (sqlLen != SQL_NTS) {
2504  qz = q = xmalloc(sqlLen + 1);
2505  if (!qz) {
2506  return NULL;
2507  }
2508  memcpy(q, sql, sqlLen);
2509  q[sqlLen] = '\0';
2510  size = sqlLen * 4;
2511  } else {
2512  size = strlen(sql) * 4;
2513  }
2514  size += sizeof (char *) - 1;
2515  size &= ~(sizeof (char *) - 1);
2516  p = xmalloc(size);
2517  if (!p) {
2518 errout:
2519  freep(&qz);
2520  return NULL;
2521  }
2522  memset(p, 0, size);
2523  out = p;
2524  while (*q) {
2525  switch (*q) {
2526  case '\'':
2527  case '\"':
2528  if (q == inq) {
2529  inq = NULL;
2530  } else if (!inq) {
2531  inq = q + 1;
2532 
2533  while (*inq) {
2534  if (*inq == *q) {
2535  if (inq[1] == *q) {
2536  inq++;
2537  } else {
2538  break;
2539  }
2540  }
2541  inq++;
2542  }
2543  }
2544  *p++ = *q;
2545  break;
2546  case '?':
2547  *p++ = *q;
2548  if (!inq) {
2549  np++;
2550  }
2551  break;
2552  case ';':
2553  if (!inq) {
2554  if (isddl < 0) {
2555  char *qq = out;
2556 
2557  while (*qq && ISSPACE(*qq)) {
2558  ++qq;
2559  }
2560  if (*qq && *qq != ';') {
2561  int i;
2562  static const struct {
2563  int len;
2564  const char *str;
2565  } ddlstr[] = {
2566  { 5, "alter" },
2567  { 7, "analyze" },
2568  { 6, "attach" },
2569  { 5, "begin" },
2570  { 6, "commit" },
2571  { 6, "create" },
2572  { 6, "detach" },
2573  { 4, "drop" },
2574  { 3, "end" },
2575  { 7, "reindex" },
2576  { 7, "release" },
2577  { 8, "rollback" },
2578  { 9, "savepoint" },
2579  { 6, "vacuum" }
2580  };
2581 
2582  size = strlen(qq);
2583  for (i = 0; i < array_size(ddlstr); i++) {
2584  if (size >= ddlstr[i].len &&
2585  strncasecmp(qq, ddlstr[i].str, ddlstr[i].len)
2586  == 0) {
2587  isddl = 1;
2588  break;
2589  }
2590  }
2591  if (isddl != 1) {
2592  isddl = 0;
2593  }
2594  }
2595  }
2596  if (isddl == 0) {
2597  char *qq = q;
2598 
2599  do {
2600  ++qq;
2601  } while (*qq && ISSPACE(*qq));
2602  if (*qq && *qq != ';') {
2603  freep(&out);
2604  if (errmsg) {
2605  *errmsg = "only one SQL statement allowed";
2606  }
2607  goto errout;
2608  }
2609  }
2610  }
2611  *p++ = *q;
2612  break;
2613  case '{':
2614  /*
2615  * Deal with escape sequences:
2616  * {d 'YYYY-MM-DD'}, {t ...}, {ts ...}
2617  * {oj ...}, {fn ...} etc.
2618  */
2619  if (!inq) {
2620  int ojfn = 0, brc = 0;
2621  char *inq2 = NULL, *end = q + 1, *start;
2622 
2623  while (*end && ISSPACE(*end)) {
2624  ++end;
2625  }
2626  if (*end != 'd' && *end != 'D' &&
2627  *end != 't' && *end != 'T') {
2628  ojfn = 1;
2629  }
2630  start = end;
2631  while (*end) {
2632  if (inq2 && *end == *inq2) {
2633  inq2 = NULL;
2634  } else if (inq2 == NULL && *end == '{') {
2635  char *nerr = 0, *nsql;
2636 
2637  nsql = fixupsql(end, SQL_NTS, cte, 0, 0, &nerr);
2638  if (nsql && !nerr) {
2639  strcpy(end, nsql);
2640  } else {
2641  brc++;
2642  }
2643  freep(&nsql);
2644  } else if (inq2 == NULL && *end == '}') {
2645  if (brc-- <= 0) {
2646  break;
2647  }
2648  } else if (inq2 == NULL && (*end == '\'' || *end == '"')) {
2649  inq2 = end;
2650  } else if (inq2 == NULL && *end == '?') {
2651  np++;
2652  }
2653  ++end;
2654  }
2655  if (*end == '}') {
2656  char *end2 = end - 1;
2657 
2658  if (ojfn) {
2659  while (start < end) {
2660  if (ISSPACE(*start)) {
2661  break;
2662  }
2663  ++start;
2664  }
2665  while (start < end) {
2666  *p++ = *start;
2667  ++start;
2668  }
2669  q = end;
2670  break;
2671  } else {
2672  while (start < end2 && *start != '\'') {
2673  ++start;
2674  }
2675  while (end2 > start && *end2 != '\'') {
2676  --end2;
2677  }
2678  if (*start == '\'' && *end2 == '\'') {
2679  while (start <= end2) {
2680  *p++ = *start;
2681  ++start;
2682  }
2683  q = end;
2684  break;
2685  }
2686  }
2687  }
2688  }
2689  /* FALL THROUGH */
2690  default:
2691  *p++ = *q;
2692  }
2693  ++q;
2694  }
2695  freep(&qz);
2696  *p = '\0';
2697  if (nparam) {
2698  *nparam = np;
2699  }
2700  if (isselect) {
2701  if (isddl > 0) {
2702  *isselect = 2;
2703  } else {
2704  int incom = 0;
2705 
2706  p = out;
2707  while (*p) {
2708  switch (*p) {
2709  case '-':
2710  if (!incom && p[1] == '-') {
2711  incom = -1;
2712  }
2713  break;
2714  case '\n':
2715  if (incom < 0) {
2716  incom = 0;
2717  }
2718  break;
2719  case '/':
2720  if (incom > 0 && p[-1] == '*') {
2721  incom = 0;
2722  p++;
2723  continue;
2724  } else if (!incom && p[1] == '*') {
2725  incom = 1;
2726  }
2727  break;
2728  }
2729  if (!incom && !ISSPACE(*p)) {
2730  break;
2731  }
2732  p++;
2733  }
2734  size = strlen(p);
2735  if (size >= 6 &&
2736  (strncasecmp(p, "select", 6) == 0 ||
2737  strncasecmp(p, "pragma", 6) == 0)) {
2738  *isselect = 1;
2739  } else if (cte && size >= 4 && strncasecmp(p, "with", 4) == 0) {
2740  *isselect = 1;
2741  } else if (size >= 7 && strncasecmp(p, "explain", 7) == 0) {
2742  *isselect = 1;
2743  } else {
2744  *isselect = 0;
2745  }
2746  }
2747  }
2748  return out;
2749 }
2750 
2759 static int
2760 findcol(char **cols, int ncols, char *name)
2761 {
2762  int i;
2763 
2764  if (cols) {
2765  for (i = 0; i < ncols; i++) {
2766  if (strcmp(cols[i], name) == 0) {
2767  return i;
2768  }
2769  }
2770  }
2771  return -1;
2772 }
2773 
2790 static void
2792 {
2793  int i, k;
2794 #if !defined(HAVE_SQLITE3TABLECOLUMNMETADATA) || !(HAVE_SQLITE3TABLECOLUMNMETADATA)
2795  int pk, nn, t, r, nrows, ncols;
2796  char **rowp, *flagp, flags[128];
2797 #endif
2798 
2799  if (!s->dyncols) {
2800  return;
2801  }
2802  /* fixup labels */
2803  if (!s->longnames) {
2804  if (s->dcols > 1) {
2805  char *table = s->dyncols[0].table;
2806 
2807  for (i = 1; table[0] && i < s->dcols; i++) {
2808  if (strcmp(s->dyncols[i].table, table)) {
2809  break;
2810  }
2811  }
2812  if (i >= s->dcols) {
2813  for (i = 0; i < s->dcols; i++) {
2814  s->dyncols[i].label = s->dyncols[i].column;
2815  }
2816  }
2817  } else if (s->dcols == 1) {
2818  s->dyncols[0].label = s->dyncols[0].column;
2819  }
2820  }
2821  for (i = 0; i < s->dcols; i++) {
2822  s->dyncols[i].type =
2823  mapsqltype(s->dyncols[i].typename, &s->dyncols[i].nosign, *s->ov3,
2824  s->nowchar[0] || s->nowchar[1], s->dobigint);
2825  getmd(s->dyncols[i].typename, s->dyncols[i].type,
2826  &s->dyncols[i].size, &s->dyncols[i].prec);
2827 #ifdef SQL_LONGVARCHAR
2828  if (s->dyncols[i].type == SQL_VARCHAR &&
2829  s->dyncols[i].size > 255) {
2830  s->dyncols[i].type = SQL_LONGVARCHAR;
2831  }
2832 #endif
2833 #ifdef WINTERFACE
2834 #ifdef SQL_WLONGVARCHAR
2835  if (s->dyncols[i].type == SQL_WVARCHAR &&
2836  s->dyncols[i].size > 255) {
2837  s->dyncols[i].type = SQL_WLONGVARCHAR;
2838  }
2839 #endif
2840 #endif
2841  if (s->dyncols[i].type == SQL_VARBINARY &&
2842  s->dyncols[i].size > 255) {
2843  s->dyncols[i].type = SQL_LONGVARBINARY;
2844  }
2845  }
2846 #if !defined(HAVE_SQLITE3TABLECOLUMNMETADATA) || !(HAVE_SQLITE3TABLECOLUMNMETADATA)
2847  if (s->dcols > array_size(flags)) {
2848  flagp = xmalloc(sizeof (flags[0]) * s->dcols);
2849  if (flagp == NULL) {
2850  return;
2851  }
2852  } else {
2853  flagp = flags;
2854  }
2855  memset(flagp, 0, sizeof (flags[0]) * s->dcols);
2856  for (i = 0; i < s->dcols; i++) {
2857  s->dyncols[i].autoinc = SQL_FALSE;
2858  s->dyncols[i].notnull = SQL_NULLABLE;
2859  }
2860  for (i = 0; i < s->dcols; i++) {
2861  int ret, lastpk = -1, autoinccount = 0;
2862  char *sql;
2863 
2864  if (!s->dyncols[i].table[0]) {
2865  continue;
2866  }
2867  if (flagp[i]) {
2868  continue;
2869  }
2870  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", s->dyncols[i].table);
2871  if (!sql) {
2872  continue;
2873  }
2874  dbtraceapi(d, "sqlite3_get_table", sql);
2875  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, NULL);
2876  sqlite3_free(sql);
2877  if (ret != SQLITE_OK) {
2878  continue;
2879  }
2880  k = findcol(rowp, ncols, "name");
2881  t = findcol(rowp, ncols, "type");
2882  pk = findcol(rowp, ncols, "pk");
2883  nn = findcol(rowp, ncols, "notnull");
2884  if (k < 0 || t < 0) {
2885  goto freet;
2886  }
2887  for (r = 1; r <= nrows; r++) {
2888  int m;
2889 
2890  for (m = i; m < s->dcols; m++) {
2891  char *colname = s->dyncols[m].column;
2892 
2893  if (s->longnames) {
2894  char *dotp = strchr(colname, '.');
2895 
2896  if (dotp) {
2897  colname = dotp + 1;
2898  }
2899  }
2900  if (!flagp[m] &&
2901  strcmp(colname, rowp[r * ncols + k]) == 0 &&
2902  strcmp(s->dyncols[m].table, s->dyncols[i].table) == 0) {
2903  char *typename = rowp[r * ncols + t];
2904 
2905  flagp[m] = i + 1;
2906  freep(&s->dyncols[m].typename);
2907  s->dyncols[m].typename = xstrdup(typename);
2908  s->dyncols[m].type =
2909  mapsqltype(typename, &s->dyncols[m].nosign, *s->ov3,
2910  s->nowchar[0] || s->nowchar[1],
2911  s->dobigint);
2912  getmd(typename, s->dyncols[m].type, &s->dyncols[m].size,
2913  &s->dyncols[m].prec);
2914 #ifdef SQL_LONGVARCHAR
2915  if (s->dyncols[m].type == SQL_VARCHAR &&
2916  s->dyncols[m].size > 255) {
2917  s->dyncols[m].type = SQL_LONGVARCHAR;
2918  }
2919 #endif
2920 #ifdef WINTERFACE
2921 #ifdef SQL_WLONGVARCHAR
2922  if (s->dyncols[i].type == SQL_WVARCHAR &&
2923  s->dyncols[i].size > 255) {
2924  s->dyncols[i].type = SQL_WLONGVARCHAR;
2925  }
2926 #endif
2927 #endif
2928  if (s->dyncols[i].type == SQL_VARBINARY &&
2929  s->dyncols[i].size > 255) {
2930  s->dyncols[i].type = SQL_LONGVARBINARY;
2931  }
2932  if (pk >= 0 && strcmp(rowp[r * ncols + pk], "1") == 0) {
2933  s->dyncols[m].ispk = 1;
2934  if (++autoinccount > 1) {
2935  if (lastpk >= 0) {
2936  s->dyncols[lastpk].autoinc = SQL_FALSE;
2937  lastpk = -1;
2938  }
2939  } else {
2940  lastpk = m;
2941  if (strlen(typename) == 7 &&
2942  strncasecmp(typename, "integer", 7) == 0) {
2943  s->dyncols[m].autoinc = SQL_TRUE;
2944  }
2945  }
2946  } else {
2947  s->dyncols[m].ispk = 0;
2948  }
2949  if (nn >= 0 && rowp[r * ncols + nn][0] != '0') {
2950  s->dyncols[m].notnull = SQL_NO_NULLS;
2951  }
2952  }
2953  }
2954  }
2955 freet:
2956  sqlite3_free_table(rowp);
2957  }
2958  for (i = k = 0; i < s->dcols; i++) {
2959  if (flagp[i] == 0) {
2960  break;
2961  }
2962  if (k == 0) {
2963  k = flagp[i];
2964  } else if (flagp[i] != k) {
2965  k = 0;
2966  break;
2967  }
2968  }
2969  s->one_tbl = k ? 1 : 0;
2970  k = 0;
2971  if (s->one_tbl) {
2972  for (i = 0; i < s->dcols; i++) {
2973  if (s->dyncols[i].ispk > 0) {
2974  ++k;
2975  }
2976  }
2977  }
2978  s->has_pk = k;
2979  if (flagp != flags) {
2980  freep(&flagp);
2981  }
2982 #else
2983  for (i = 1, k = 0; i < s->dcols; i++) {
2984  if (strcmp(s->dyncols[i].table, s->dyncols[0].table) == 0) {
2985  k++;
2986  }
2987  }
2988  s->one_tbl = (k && k + 1 == s->dcols) ? 1 : 0;
2989  k = 0;
2990  if (s->one_tbl) {
2991  for (i = 0; i < s->dcols; i++) {
2992  if (s->dyncols[i].ispk > 0) {
2993  ++k;
2994  if (s->has_rowid < 0 && s->dyncols[i].isrowid > 0) {
2995  s->has_rowid = i;
2996  }
2997  }
2998  }
2999  }
3000  s->has_pk = k;
3001 #endif
3002 }
3003 
3010 static void
3011 convJD2YMD(double jd, DATE_STRUCT *ds)
3012 {
3013  int z, a, b, c, d, e, x1;
3014  sqlite_int64 ijd;
3015 
3016  ijd = jd * 86400000.0 + 0.5;
3017  z = (int) ((ijd + 43200000) / 86400000);
3018  a = (int) ((z - 1867216.25) / 36524.25);
3019  a = z + 1 + a - (a / 4);
3020  b = a + 1524;
3021  c = (int) ((b - 122.1) / 365.25);
3022  d = (36525 * c) / 100;
3023  e = (int) ((b - d) / 30.6001);
3024  x1 = (int) (30.6001 * e);
3025  ds->day = b - d - x1;
3026  ds->month = (e < 14) ? (e - 1) : (e - 13);
3027  ds->year = (ds->month > 2) ? (c - 4716) : (c - 4715);
3028 }
3029 
3030 
3038 static void
3039 convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
3040 {
3041  int s;
3042  double ds;
3043  sqlite_int64 ijd;
3044 
3045  ijd = jd * 86400000.0 + 0.5;
3046  s = (int)((ijd + 43200000) % 86400000);
3047  ds = s / 1000.0;
3048  if (fp) {
3049  *fp = (s % 1000) * 1000000;
3050  }
3051  s = (int) ds;
3052  ds -= s;
3053  ts->hour = s / 3600;
3054  s -= ts->hour * 3600;
3055  ts->minute = s / 60;
3056  ds += s - ts->minute *60;
3057  ts->second = (int) ds;
3058 }
3059 
3067 static int
3068 getmdays(int year, int month)
3069 {
3070  static const int mdays[] = {
3071  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
3072  };
3073  int mday;
3074 
3075  if (month < 1) {
3076  return 0;
3077  }
3078  mday = mdays[(month - 1) % 12];
3079  if (mday == 28 && year % 4 == 0 &&
3080  (!(year % 100 == 0) || year % 400 == 0)) {
3081  mday++;
3082  }
3083  return mday;
3084 }
3085 
3101 static int
3102 str2date(int jdconv, char *str, DATE_STRUCT *ds)
3103 {
3104  int i, err = 0;
3105  double jd;
3106  char *p, *q, sepc = '\0';
3107 
3108  ds->year = ds->month = ds->day = 0;
3109  if (jdconv) {
3110  p = strchr(str, '.');
3111  if (p) {
3112  /* julian day format */
3113  p = 0;
3114  jd = ln_strtod(str, &p);
3115  if (p && p > str) {
3116  convJD2YMD(jd, ds);
3117  return 0;
3118  }
3119  }
3120  }
3121  p = str;
3122  while (*p && !ISDIGIT(*p)) {
3123  ++p;
3124  }
3125  q = p;
3126  i = 0;
3127  while (*q && !ISDIGIT(*q)) {
3128  ++i;
3129  ++q;
3130  }
3131  if (i >= 8) {
3132  char buf[8];
3133 
3134  strncpy(buf, p + 0, 4); buf[4] = '\0';
3135  ds->year = strtol(buf, NULL, 10);
3136  strncpy(buf, p + 4, 2); buf[2] = '\0';
3137  ds->month = strtol(buf, NULL, 10);
3138  strncpy(buf, p + 6, 2); buf[2] = '\0';
3139  ds->day = strtol(buf, NULL, 10);
3140  goto done;
3141  }
3142  i = 0;
3143  while (i < 3) {
3144  int n;
3145 
3146  q = NULL;
3147  n = strtol(p, &q, 10);
3148  if (!q || q == p) {
3149  if (*q == '\0') {
3150  if (i == 0) {
3151  err = 1;
3152  }
3153  goto done;
3154  }
3155  }
3156  if (!sepc) {
3157  sepc = *q;
3158  }
3159  if (*q == '-' || *q == '/' || *q == '\0' || i == 2) {
3160  switch (i) {
3161  case 0: ds->year = n; break;
3162  case 1: ds->month = n; break;
3163  case 2: ds->day = n; break;
3164  }
3165  ++i;
3166  if (*q) {
3167  ++q;
3168  }
3169  } else {
3170  i = 0;
3171  while (*q && !ISDIGIT(*q)) {
3172  ++q;
3173  }
3174  }
3175  p = q;
3176  }
3177 done:
3178  /* final check for overflow */
3179  if (err ||
3180  ds->month < 1 || ds->month > 12 ||
3181  ds->day < 1 || ds->day > getmdays(ds->year, ds->month)) {
3182  if (sepc == '/') {
3183  /* Try MM/DD/YYYY format */
3184  int t[3];
3185 
3186  t[0] = ds->year;
3187  t[1] = ds->month;
3188  t[2] = ds->day;
3189  ds->year = t[2];
3190  ds->day = t[1];
3191  ds->month = t[0];
3192  if (ds->month >= 1 && ds->month <= 12 &&
3193  (ds->day >= 1 || ds->day <= getmdays(ds->year, ds->month))) {
3194  return 0;
3195  }
3196  }
3197  return -1;
3198  }
3199  return 0;
3200 }
3201 
3216 static int
3217 str2time(int jdconv, char *str, TIME_STRUCT *ts)
3218 {
3219  int i, err = 0, ampm = -1;
3220  double jd;
3221  char *p, *q;
3222 
3223  ts->hour = ts->minute = ts->second = 0;
3224  if (jdconv) {
3225  p = strchr(str, '.');
3226  if (p) {
3227  /* julian day format */
3228  p = 0;
3229  jd = ln_strtod(str, &p);
3230  if (p && p > str) {
3231  convJD2HMS(jd, ts, 0);
3232  return 0;
3233  }
3234  }
3235  }
3236  p = str;
3237  while (*p && !ISDIGIT(*p)) {
3238  ++p;
3239  }
3240  q = p;
3241  i = 0;
3242  while (*q && ISDIGIT(*q)) {
3243  ++i;
3244  ++q;
3245  }
3246  if (i >= 6) {
3247  char buf[4];
3248 
3249  strncpy(buf, p + 0, 2); buf[2] = '\0';
3250  ts->hour = strtol(buf, NULL, 10);
3251  strncpy(buf, p + 2, 2); buf[2] = '\0';
3252  ts->minute = strtol(buf, NULL, 10);
3253  strncpy(buf, p + 4, 2); buf[2] = '\0';
3254  ts->second = strtol(buf, NULL, 10);
3255  goto done;
3256  }
3257  i = 0;
3258  while (i < 3) {
3259  int n;
3260 
3261  q = NULL;
3262  n = strtol(p, &q, 10);
3263  if (!q || q == p) {
3264  if (*q == '\0') {
3265  if (i == 0) {
3266  err = 1;
3267  }
3268  goto done;
3269  }
3270  }
3271  if (*q == ':' || *q == '\0' || i == 2) {
3272  switch (i) {
3273  case 0: ts->hour = n; break;
3274  case 1: ts->minute = n; break;
3275  case 2: ts->second = n; break;
3276  }
3277  ++i;
3278  if (*q) {
3279  ++q;
3280  }
3281  } else {
3282  i = 0;
3283  while (*q && !ISDIGIT(*q)) {
3284  ++q;
3285  }
3286  }
3287  p = q;
3288  }
3289  if (!err) {
3290  while (*p) {
3291  if ((p[0] == 'p' || p[0] == 'P') &&
3292  (p[1] == 'm' || p[1] == 'M')) {
3293  ampm = 1;
3294  } else if ((p[0] == 'a' || p[0] == 'A') &&
3295  (p[1] == 'm' || p[1] == 'M')) {
3296  ampm = 0;
3297  }
3298  ++p;
3299  }
3300  if (ampm > 0) {
3301  if (ts->hour < 12) {
3302  ts->hour += 12;
3303  }
3304  } else if (ampm == 0) {
3305  if (ts->hour == 12) {
3306  ts->hour = 0;
3307  }
3308  }
3309  }
3310 done:
3311  /* final check for overflow */
3312  if (err || ts->hour > 23 || ts->minute > 59 || ts->second > 59) {
3313  return -1;
3314  }
3315  return 0;
3316 }
3317 
3337 static int
3338 str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
3339 {
3340  int i, m, n, err = 0, ampm = -1;
3341  double jd;
3342  char *p, *q, in = '\0', sepc = '\0';
3343 
3344  tss->year = tss->month = tss->day = 0;
3345  tss->hour = tss->minute = tss->second = 0;
3346  tss->fraction = 0;
3347  if (jdconv) {
3348  p = strchr(str, '.');
3349  if (p) {
3350  q = strchr(str, '-');
3351  if (q == str) {
3352  q = 0;
3353  }
3354  if (!q) {
3355  q = strchr(str, '/');
3356  if (!q) {
3357  q = strchr(str, ':');
3358  }
3359  }
3360  if (!q || q > p) {
3361  /* julian day format */
3362  p = 0;
3363  jd = ln_strtod(str, &p);
3364  if (p && p > str) {
3365  DATE_STRUCT ds;
3366  TIME_STRUCT ts;
3367 
3368  convJD2YMD(jd, &ds);
3369  convJD2HMS(jd, &ts, &n);
3370  tss->year = ds.year;
3371  tss->month = ds.month;
3372  tss->day = ds.day;
3373  tss->hour = ts.hour;
3374  tss->minute = ts.minute;
3375  tss->second = ts.second;
3376  tss->fraction = n;
3377  return 0;
3378  }
3379  }
3380  }
3381  }
3382  p = str;
3383  while (*p && !ISDIGIT(*p)) {
3384  ++p;
3385  }
3386  q = p;
3387  i = 0;
3388  while (*q && ISDIGIT(*q)) {
3389  ++i;
3390  ++q;
3391  }
3392  if (i >= 14) {
3393  char buf[16];
3394 
3395  strncpy(buf, p + 0, 4); buf[4] = '\0';
3396  tss->year = strtol(buf, NULL, 10);
3397  strncpy(buf, p + 4, 2); buf[2] = '\0';
3398  tss->month = strtol(buf, NULL, 10);
3399  strncpy(buf, p + 6, 2); buf[2] = '\0';
3400  tss->day = strtol(buf, NULL, 10);
3401  strncpy(buf, p + 8, 2); buf[2] = '\0';
3402  tss->hour = strtol(buf, NULL, 10);
3403  strncpy(buf, p + 10, 2); buf[2] = '\0';
3404  tss->minute = strtol(buf, NULL, 10);
3405  strncpy(buf, p + 12, 2); buf[2] = '\0';
3406  tss->second = strtol(buf, NULL, 10);
3407  if (i > 14) {
3408  m = i - 14;
3409  strncpy(buf, p + 14, m);
3410  while (m < 9) {
3411  buf[m] = '0';
3412  ++m;
3413  }
3414  buf[m] = '\0';
3415  tss->fraction = strtol(buf, NULL, 10);
3416  }
3417  m = 7;
3418  goto done;
3419  }
3420  m = i = 0;
3421  while ((m & 7) != 7) {
3422  q = NULL;
3423  n = strtol(p, &q, 10);
3424  if (!q || q == p) {
3425  if (*q == '\0') {
3426  if (m < 1) {
3427  err = 1;
3428  }
3429  goto done;
3430  }
3431  }
3432  if (in == '\0') {
3433  switch (*q) {
3434  case '-':
3435  case '/':
3436  if ((m & 1) == 0) {
3437  in = *q;
3438  i = 0;
3439  }
3440  break;
3441  case ':':
3442  if ((m & 2) == 0) {
3443  in = *q;
3444  i = 0;
3445  }
3446  break;
3447  case ' ':
3448  case '.':
3449  break;
3450  default:
3451  in = '\0';
3452  i = 0;
3453  break;
3454  }
3455  }
3456  switch (in) {
3457  case '-':
3458  case '/':
3459  if (!sepc) {
3460  sepc = in;
3461  }
3462  switch (i) {
3463  case 0: tss->year = n; break;
3464  case 1: tss->month = n; break;
3465  case 2: tss->day = n; break;
3466  }
3467  if (++i >= 3) {
3468  i = 0;
3469  m |= 1;
3470  if (!(m & 2)) {
3471  m |= 8;
3472  }
3473  goto skip;
3474  } else {
3475  ++q;
3476  }
3477  break;
3478  case ':':
3479  switch (i) {
3480  case 0: tss->hour = n; break;
3481  case 1: tss->minute = n; break;
3482  case 2: tss->second = n; break;
3483  }
3484  if (++i >= 3) {
3485  i = 0;
3486  m |= 2;
3487  if (*q == '.') {
3488  in = '.';
3489  goto skip2;
3490  }
3491  if (*q == ' ') {
3492  if ((m & 1) == 0) {
3493  char *e = NULL;
3494 
3495  (void) strtol(q + 1, &e, 10);
3496  if (e && *e == '-') {
3497  goto skip;
3498  }
3499  }
3500  in = '.';
3501  goto skip2;
3502  }
3503  goto skip;
3504  } else {
3505  ++q;
3506  }
3507  break;
3508  case '.':
3509  if (++i >= 1) {
3510  int ndig = q - p;
3511 
3512  if (p[0] == '+' || p[0] == '-') {
3513  ndig--;
3514  }
3515  while (ndig < 9) {
3516  n = n * 10;
3517  ++ndig;
3518  }
3519  tss->fraction = n;
3520  m |= 4;
3521  i = 0;
3522  }
3523  default:
3524  skip:
3525  in = '\0';
3526  skip2:
3527  while (*q && !ISDIGIT(*q)) {
3528  if ((q[0] == 'a' || q[0] == 'A') &&
3529  (q[1] == 'm' || q[1] == 'M')) {
3530  ampm = 0;
3531  ++q;
3532  } else if ((q[0] == 'p' || q[0] == 'P') &&
3533  (q[1] == 'm' || q[1] == 'M')) {
3534  ampm = 1;
3535  ++q;
3536  }
3537  ++q;
3538  }
3539  }
3540  p = q;
3541  }
3542  if ((m & 7) > 1 && (m & 8)) {
3543  /* ISO8601 timezone */
3544  if (p > str && ISDIGIT(*p)) {
3545  int nn, sign;
3546 
3547  q = p - 1;
3548  if (*q != '+' && *q != '-') {
3549  goto done;
3550  }
3551  sign = (*q == '+') ? -1 : 1;
3552  q = NULL;
3553  n = strtol(p, &q, 10);
3554  if (!q || *q++ != ':' || !ISDIGIT(*q)) {
3555  goto done;
3556  }
3557  p = q;
3558  q = NULL;
3559  nn = strtol(p, &q, 10);
3560  tss->minute += nn * sign;
3561  if ((SQLSMALLINT) tss->minute < 0) {
3562  tss->hour -= 1;
3563  tss->minute += 60;
3564  } else if (tss->minute >= 60) {
3565  tss->hour += 1;
3566  tss->minute -= 60;
3567  }
3568  tss->hour += n * sign;
3569  if ((SQLSMALLINT) tss->hour < 0) {
3570  tss->day -= 1;
3571  tss->hour += 24;
3572  } else if (tss->hour >= 24) {
3573  tss->day += 1;
3574  tss->hour -= 24;
3575  }
3576  if ((short) tss->day < 1 || tss->day >= 28) {
3577  int mday, pday, pmon;
3578 
3579  mday = getmdays(tss->year, tss->month);
3580  pmon = tss->month - 1;
3581  if (pmon < 1) {
3582  pmon = 12;
3583  }
3584  pday = getmdays(tss->year, pmon);
3585  if ((SQLSMALLINT) tss->day < 1) {
3586  tss->month -= 1;
3587  tss->day = pday;
3588  } else if (tss->day > mday) {
3589  tss->month += 1;
3590  tss->day = 1;
3591  }
3592  if ((SQLSMALLINT) tss->month < 1) {
3593  tss->year -= 1;
3594  tss->month = 12;
3595  } else if (tss->month > 12) {
3596  tss->year += 1;
3597  tss->month = 1;
3598  }
3599  }
3600  }
3601  }
3602 done:
3603  if ((m & 1) &&
3604  (tss->month < 1 || tss->month > 12 ||
3605  tss->day < 1 || tss->day > getmdays(tss->year, tss->month))) {
3606  if (sepc == '/') {
3607  /* Try MM/DD/YYYY format */
3608  int t[3];
3609 
3610  t[0] = tss->year;
3611  t[1] = tss->month;
3612  t[2] = tss->day;
3613  tss->year = t[2];
3614  tss->day = t[1];
3615  tss->month = t[0];
3616  }
3617  }
3618  /* Replace missing year/month/day with current date */
3619  if (!err && (m & 1) == 0) {
3620 #ifdef _WIN32
3621  SYSTEMTIME t;
3622 
3623  GetLocalTime(&t);
3624  tss->year = t.wYear;
3625  tss->month = t.wMonth;
3626  tss->day = t.wDay;
3627 #else
3628  struct timeval tv;
3629  struct tm tm;
3630 
3631  gettimeofday(&tv, NULL);
3632  tm = *localtime(&tv.tv_sec);
3633  tss->year = tm.tm_year + 1900;
3634  tss->month = tm.tm_mon + 1;
3635  tss->day = tm.tm_mday;
3636 #endif
3637  }
3638  /* Normalize fraction */
3639  if (tss->fraction < 0) {
3640  tss->fraction = 0;
3641  }
3642  /* Final check for overflow */
3643  if (err ||
3644  tss->month < 1 || tss->month > 12 ||
3645  tss->day < 1 || tss->day > getmdays(tss->year, tss->month) ||
3646  tss->hour > 23 || tss->minute > 59 || tss->second > 59) {
3647  return -1;
3648  }
3649  if ((m & 7) > 1) {
3650  if (ampm > 0) {
3651  if (tss->hour < 12) {
3652  tss->hour += 12;
3653  }
3654  } else if (ampm == 0) {
3655  if (tss->hour == 12) {
3656  tss->hour = 0;
3657  }
3658  }
3659  }
3660  return ((m & 7) < 1) ? -1 : 0;
3661 }
3662 
3669 static int
3670 getbool(char *string)
3671 {
3672  if (string) {
3673  return string[0] && strchr("Yy123456789Tt", string[0]) != NULL;
3674  }
3675  return 0;
3676 }
3677 
3685 static void
3686 blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
3687 {
3688 #if 0
3689  DBC *d = (DBC *) sqlite3_user_data(ctx);
3690 #endif
3691  char *filename = 0;
3692 
3693  if (nargs > 0) {
3694  if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
3695  filename = (char *) sqlite3_value_text(args[0]);
3696  }
3697  }
3698  if (filename) {
3699 #ifdef _WIN32
3700  char *wname = utf_to_wmb(filename, -1);
3701  FILE *f;
3702 #else
3703  FILE *f = fopen(filename, "r");
3704 #endif
3705  char *p;
3706  long n, nn;
3707 
3708 #ifdef _WIN32
3709  if (wname) {
3710  f = fopen(wname, "rb");
3711  } else {
3712  sqlite3_result_error(ctx, "out of memory", -1);
3713  return;
3714  }
3715  uc_free(wname);
3716 #endif
3717  if (f) {
3718  if (fseek(f, 0, SEEK_END) == 0) {
3719  n = ftell(f);
3720  if (fseek(f, 0, SEEK_SET) == 0) {
3721  p = sqlite3_malloc(n);
3722  if (p) {
3723  nn = fread(p, 1, n, f);
3724  if (nn != n) {
3725  sqlite3_result_error(ctx, "read error", -1);
3726  sqlite3_free(p);
3727  } else {
3728  sqlite3_result_blob(ctx, p, n, sqlite3_free);
3729  }
3730  } else {
3731  sqlite3_result_error(ctx, "out of memory", -1);
3732  }
3733  } else {
3734  sqlite3_result_error(ctx, "seek error", -1);
3735  }
3736  } else {
3737  sqlite3_result_error(ctx, "seek error", -1);
3738  }
3739  fclose(f);
3740  } else {
3741  sqlite3_result_error(ctx, "cannot open file", -1);
3742  }
3743  } else {
3744  sqlite3_result_error(ctx, "no filename given", -1);
3745  }
3746 }
3747 
3755 static void
3756 blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
3757 {
3758 #if 0
3759  DBC *d = (DBC *) sqlite3_user_data(ctx);
3760 #endif
3761  char *filename = 0;
3762  char *p = 0;
3763  int n = 0;
3764 
3765  if (nargs > 0) {
3766  p = (char *) sqlite3_value_blob(args[0]);
3767  n = sqlite3_value_bytes(args[0]);
3768  }
3769  if (nargs > 1) {
3770  if (sqlite3_value_type(args[1]) != SQLITE_NULL) {
3771  filename = (char *) sqlite3_value_text(args[1]);
3772  }
3773  }
3774  if (p) {
3775  if (filename) {
3776 #ifdef _WIN32
3777  char *wname = utf_to_wmb(filename, -1);
3778  FILE *f;
3779 #else
3780  FILE *f = fopen(filename, "w");
3781 #endif
3782  int nn;
3783 
3784 #ifdef _WIN32
3785  if (wname) {
3786  f = fopen(wname, "wb");
3787  } else {
3788  sqlite3_result_error(ctx, "out of memory", -1);
3789  return;
3790  }
3791  uc_free(wname);
3792 #endif
3793  if (f) {
3794  nn = fwrite(p, 1, n, f);
3795  fclose(f);
3796  if (nn != n) {
3797  sqlite3_result_error(ctx, "write error", -1);
3798  } else {
3799  sqlite3_result_int(ctx, nn);
3800  }
3801  } else {
3802  sqlite3_result_error(ctx, "cannot open file", -1);
3803  }
3804  } else {
3805  sqlite3_result_error(ctx, "no filename given", -1);
3806  }
3807  } else {
3808  sqlite3_result_null(ctx);
3809  }
3810 }
3811 
3819 static void
3820 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3821 dbtrace(void *arg, const char *msg, sqlite_uint64 et)
3822 #else
3823 dbtrace(void *arg, const char *msg)
3824 #endif
3825 {
3826  DBC *d = (DBC *) arg;
3827 
3828  if (msg && d->trace) {
3829  int len = strlen(msg);
3830 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3831  unsigned long s, f;
3832 #endif
3833 
3834  if (len > 0) {
3835  char *end = "\n";
3836 
3837  if (msg[len - 1] != ';') {
3838  end = ";\n";
3839  }
3840  fprintf(d->trace, "%s%s", msg, end);
3841 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3842  s = et / 1000000000LL;
3843  f = et % 1000000000LL;
3844  fprintf(d->trace, "-- took %lu.%09lu seconds\n", s, f);
3845 #endif
3846  fflush(d->trace);
3847  }
3848  }
3849 }
3850 
3858 static void
3859 dbtraceapi(DBC *d, char *fn, const char *sql)
3860 {
3861  if (fn && d->trace) {
3862  if (sql) {
3863  fprintf(d->trace, "-- %s: %s\n", fn, sql);
3864  } else {
3865  fprintf(d->trace, "-- %s\n", fn);
3866  }
3867  fflush(d->trace);
3868  }
3869 }
3870 
3878 static void
3879 dbtracerc(DBC *d, int rc, char *err)
3880 {
3881  if (rc != SQLITE_OK && d->trace) {
3882  fprintf(d->trace, "-- SQLITE ERROR CODE %d", rc);
3883  fprintf(d->trace, err ? ": %s\n" : "\n", err);
3884  fflush(d->trace);
3885  }
3886 }
3887 
3902 static SQLRETURN
3903 dbopen(DBC *d, char *name, int isu, char *dsn, char *sflag,
3904  char *spflag, char *ntflag, char *jmode, char *busy)
3905 {
3906  char *endp = NULL;
3907  int rc, tmp, busyto = 100000;
3908 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
3909  int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
3910  char *uname = name;
3911  const char *vfs_name = NULL;
3912 #endif
3913 
3914  if (d->sqlite) {
3915  if (d->trace) {
3916  fprintf(d->trace, "-- sqlite3_close (deferred): '%s'\n",
3917  d->dbname);
3918  fflush(d->trace);
3919  }
3920 #if defined(HAVE_SQLITE3CLOSEV2) && (HAVE_SQLITE3CLOSEV2)
3921  sqlite3_close_v2(d->sqlite);
3922 #else
3923  sqlite3_close(d->sqlite);
3924 #endif
3925  d->sqlite = NULL;
3926  }
3927 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
3928  if (d->nocreat) {
3929  flags &= ~ SQLITE_OPEN_CREATE;
3930  }
3931 #if defined(_WIN32) || defined(_WIN64)
3932  if (!isu) {
3933  char expname[MAX_PATH];
3934 
3935  expname[0] = '\0';
3936  rc = ExpandEnvironmentStrings(name, expname, sizeof (expname));
3937  if (rc <= sizeof (expname)) {
3938  uname = wmb_to_utf(expname, rc - 1);
3939  } else {
3940  uname = wmb_to_utf(name, -1);
3941  }
3942  if (!uname) {
3943  rc = SQLITE_NOMEM;
3944  setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
3945  return SQL_ERROR;
3946  }
3947  }
3948 #endif
3949 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
3950  vfs_name = nvfs_makevfs(uname);
3951 #endif
3952 #ifdef SQLITE_OPEN_URI
3953  flags |= SQLITE_OPEN_URI;
3954 #endif
3955  rc = sqlite3_open_v2(uname, &d->sqlite, flags, vfs_name);
3956 #if defined(WINTERFACE) || defined(_WIN32) || defined(_WIN64)
3957  if (uname != name) {
3958  uc_free(uname);
3959  }
3960 #endif
3961 #else
3962 #if defined(_WIN32) || defined(_WIN64)
3963  if (d->nocreat) {
3964  char *cname = NULL;
3965 
3966  if (isu) {
3967  cname = utf_to_wmb(name, -1);
3968  }
3969  if (GetFileAttributesA(cname ? cname : name) ==
3970  INVALID_FILE_ATTRIBUTES) {
3971  uc_free(cname);
3972  rc = SQLITE_CANTOPEN;
3973  setstatd(d, rc, "cannot open database",
3974  (*d->ov3) ? "HY000" : "S1000");
3975  return SQL_ERROR;
3976  }
3977  uc_free(cname);
3978  }
3979 #else
3980  if (d->nocreat && access(name, 004) < 0) {
3981  rc = SQLITE_CANTOPEN;
3982  setstatd(d, rc, "cannot open database", (*d->ov3) ? "HY000" : "S1000");
3983  return SQL_ERROR;
3984  }
3985 #endif
3986 #if defined(_WIN32) || defined(_WIN64)
3987  if (!isu) {
3988  WCHAR *wname = wmb_to_uc(name, -1);
3989 
3990  if (!wname) {
3991  rc = SQLITE_NOMEM;
3992  setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
3993  return SQL_ERROR;
3994  }
3995  rc = sqlite3_open16(wname, &d->sqlite);
3996  uc_free(wname);
3997  } else
3998 #endif
3999  rc = sqlite3_open(name, &d->sqlite);
4000 #endif /* !HAVE_SQLITE3VFS */
4001  if (rc != SQLITE_OK) {
4002 connfail:
4003  setstatd(d, rc, "connect failed", (*d->ov3) ? "HY000" : "S1000");
4004  if (d->sqlite) {
4005  sqlite3_close(d->sqlite);
4006  d->sqlite = NULL;
4007  }
4008  return SQL_ERROR;
4009  }
4010 #if defined(SQLITE_DYNLOAD) || defined(SQLITE_HAS_CODEC)
4011  if (d->pwd) {
4012  sqlite3_key(d->sqlite, d->pwd, d->pwdLen);
4013  }
4014 #endif
4015  d->pwd = NULL;
4016  d->pwdLen = 0;
4017  if (d->trace) {
4018 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
4019  sqlite3_profile(d->sqlite, dbtrace, d);
4020 #else
4021  sqlite3_trace(d->sqlite, dbtrace, d);
4022 #endif
4023  }
4024  d->step_enable = getbool(sflag);
4025  d->trans_disable = getbool(ntflag);
4026  d->curtype = d->step_enable ?
4027  SQL_CURSOR_FORWARD_ONLY : SQL_CURSOR_STATIC;
4028  tmp = strtol(busy, &endp, 0);
4029  if (endp && *endp == '\0' && endp != busy) {
4030  busyto = tmp;
4031  }
4032  if (busyto < 1 || busyto > 1000000) {
4033  busyto = 1000000;
4034  }
4035  d->timeout = busyto;
4036  freep(&d->dbname);
4037  d->dbname = xstrdup(name);
4038  freep(&d->dsn);
4039  d->dsn = xstrdup(dsn);
4040  if ((rc = setsqliteopts(d->sqlite, d)) != SQLITE_OK) {
4041  if (d->trace) {
4042  fprintf(d->trace, "-- sqlite3_close: '%s'\n",
4043  d->dbname);
4044  fflush(d->trace);
4045  }
4046  sqlite3_close(d->sqlite);
4047  d->sqlite = NULL;
4048  goto connfail;
4049  }
4050  if (!spflag || spflag[0] == '\0') {
4051  spflag = "NORMAL";
4052  }
4053  if (spflag[0] != '\0') {
4054  char syncp[128];
4055 
4056  sprintf(syncp, "PRAGMA synchronous = %8.8s;", spflag);
4057  sqlite3_exec(d->sqlite, syncp, NULL, NULL, NULL);
4058  }
4059  if (jmode[0] != '\0') {
4060  char jourp[128];
4061 
4062  sprintf(jourp, "PRAGMA journal_mode = %16.16s;", jmode);
4063  sqlite3_exec(d->sqlite, jourp, NULL, NULL, NULL);
4064  }
4065  if (d->trace) {
4066  fprintf(d->trace, "-- sqlite3_open: '%s'\n", d->dbname);
4067  fflush(d->trace);
4068  }
4069 #if defined(_WIN32) || defined(_WIN64)
4070  {
4071  char pname[MAX_PATH];
4072  HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
4073  FALSE, GetCurrentProcessId());
4074 
4075  pname[0] = '\0';
4076  if (h) {
4077  HMODULE m = NULL, l = LoadLibrary("psapi.dll");
4078  DWORD need;
4079  typedef BOOL (WINAPI *epmfunc)(HANDLE, HMODULE *, DWORD, LPDWORD);
4080  typedef BOOL (WINAPI *gmbfunc)(HANDLE, HMODULE, LPSTR, DWORD);
4081  epmfunc epm;
4082  gmbfunc gmb;
4083 
4084  if (l) {
4085  epm = (epmfunc) GetProcAddress(l, "EnumProcessModules");
4086  gmb = (gmbfunc) GetProcAddress(l, "GetModuleBaseNameA");
4087  if (epm && gmb && epm(h, &m, sizeof (m), &need)) {
4088  gmb(h, m, pname, sizeof (pname));
4089  }
4090  FreeLibrary(l);
4091  }
4092  CloseHandle(h);
4093  }
4094  d->xcelqrx = strncasecmp(pname, "EXCEL", 5) == 0 ||
4095  strncasecmp(pname, "MSQRY", 5) == 0;
4096  if (d->trace && d->xcelqrx) {
4097 
4098  fprintf(d->trace, "-- enabled EXCEL quirks\n");
4099  fflush(d->trace);
4100  }
4101  }
4102 #endif
4103  sqlite3_create_function(d->sqlite, "blob_import", 1, SQLITE_UTF8,
4104  d, blob_import, 0, 0);
4105  sqlite3_create_function(d->sqlite, "blob_export", 2, SQLITE_UTF8,
4106  d, blob_export, 0, 0);
4107  return SQL_SUCCESS;
4108 }
4109 
4116 static void
4117 dbloadext(DBC *d, char *exts)
4118 {
4119 #if defined(HAVE_SQLITE3LOADEXTENSION) && (HAVE_SQLITE3LOADEXTENSION)
4120  char *p;
4121  char path[SQL_MAX_MESSAGE_LENGTH];
4122  int plen = 0;
4123 
4124  if (!d->sqlite) {
4125  return;
4126  }
4127  sqlite3_enable_load_extension(d->sqlite, 1);
4128 #if defined(_WIN32) || defined(_WIN64)
4129  GetModuleFileName(hModule, path, sizeof (path));
4130  p = strrchr(path, '\\');
4131  plen = p ? ((p + 1) - path) : 0;
4132 #endif
4133  do {
4134  p = strchr(exts, ',');
4135  if (p) {
4136  strncpy(path + plen, exts, p - exts);
4137  path[plen + (p - exts)] = '\0';
4138  } else {
4139  strcpy(path + plen, exts);
4140  }
4141  if (exts[0]) {
4142  char *errmsg = NULL;
4143  int rc;
4144 #if defined(_WIN32) || defined(_WIN64)
4145  char *q;
4146 
4147  q = path + plen;
4148  if (!(q[0] &&
4149  ((q[1] == ':' && (q[2] == '\\' || q[2] == '/')) ||
4150  q[0] == '\\' || q[0] == '/' || q[0] == '.'))) {
4151  q = path;
4152  }
4153  rc = sqlite3_load_extension(d->sqlite, q, 0, &errmsg);
4154 #else
4155  rc = sqlite3_load_extension(d->sqlite, path, 0, &errmsg);
4156 #endif
4157  if (rc != SQLITE_OK) {
4158 #if defined(_WIN32) || defined(_WIN64)
4159  char buf[512], msg[512];
4160 
4161  LoadString(hModule, IDS_EXTERR, buf, sizeof (buf));
4162  wsprintf(msg, buf, q, errmsg ?
4163  errmsg : "no error info available");
4164  LoadString(hModule, IDS_EXTTITLE, buf, sizeof (buf));
4165  MessageBox(NULL, msg, buf,
4166  MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
4167  MB_SETFOREGROUND);
4168 #else
4169  fprintf(stderr, "extension '%s' did not load%s%s\n",
4170  path, errmsg ? ": " : "", errmsg ? errmsg : "");
4171 #endif
4172  }
4173  }
4174  if (p) {
4175  exts = p + 1;
4176  }
4177  } while (p);
4178 #endif /* HAVE_SQLITE3LOADEXTENSION */
4179 }
4180 
4190 static char *
4191 s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
4192 {
4193  char *typename = (char *) sqlite3_column_decltype(s3stmt, col);
4194  char guess[64];
4195 
4196  guess[0] = '\0';
4197  if (!typename) {
4198  int coltype = sqlite3_column_type(s3stmt, col);
4199 
4200  if (guessed_types) {
4201  guessed_types[0]++;
4202  }
4203  if (d->trace) {
4204  sprintf(guess, " (guessed from %d)", coltype);
4205  }
4206  switch (coltype) {
4207  case SQLITE_INTEGER: typename = "integer"; break;
4208  case SQLITE_FLOAT: typename = "double"; break;
4209  default:
4210  case SQLITE_TEXT: typename = "varchar"; break;
4211  case SQLITE_BLOB: typename = "blob"; break;
4212 #if 0
4213  case SQLITE_NULL: typename = "null"; break;
4214 #endif
4215  }
4216  }
4217  if (d->trace) {
4218  fprintf(d->trace, "-- column %d type%s: '%s'\n", col + 1,
4219  guess, typename);
4220  fflush(d->trace);
4221  }
4222  return typename;
4223 }
4224 
4225 #if defined(HAVE_SQLITE3TABLECOLUMNMETADATA) && (HAVE_SQLITE3TABLECOLUMNMETADATA)
4226 
4235 static void
4236 s3stmt_addmeta(sqlite3_stmt *s3stmt, int col, DBC *d, COL *ci)
4237 {
4238  int nn = 0, pk = 0, ai = 0;
4239  const char *dn, *tn, *cn, *dummy[4];
4240 
4241  dn = sqlite3_column_database_name(s3stmt, col);
4242  tn = sqlite3_column_table_name(s3stmt, col);
4243  cn = sqlite3_column_origin_name(s3stmt, col);
4244  dummy[0] = dummy[1] = 0;
4245  if (tn && cn) {
4246  sqlite3_table_column_metadata(d->sqlite, dn, tn, cn,
4247  dummy, dummy + 1,
4248  &nn, &pk, &ai);
4249  }
4250  ci->autoinc = ai ? SQL_TRUE: SQL_FALSE;
4251  ci->notnull = nn ? SQL_NO_NULLS : SQL_NULLABLE;
4252  ci->ispk = pk ? 1 : 0;
4253  if (d->trace) {
4254  fprintf(d->trace, "-- column %d %s\n",
4255  col + 1, nn ? "notnull" : "nullable");
4256  if (ai) {
4257  fprintf(d->trace, "-- column %d autoincrement\n", col + 1);
4258  }
4259  fflush(d->trace);
4260  }
4261  ci->isrowid = 0;
4262  if (ci->ispk && tn) {
4263  nn = pk = ai = 0;
4264  dummy[2] = dummy[3] = 0;
4265 
4266  sqlite3_table_column_metadata(d->sqlite, dn, tn, "rowid",
4267  dummy + 2, dummy + 3,
4268  &nn, &pk, &ai);
4269  if (pk && dummy[0] && dummy[0] == dummy[2]) {
4270  ci->isrowid = 1;
4271  }
4272  }
4273 }
4274 
4275 #endif
4276 
4283 static int
4285 {
4286  DBC *d = (DBC *) s->dbc;
4287  char **rowd = NULL;
4288  const char *errp = NULL;
4289  int i, ncols, rc;
4290 
4291  if (s != d->cur_s3stmt || !s->s3stmt) {
4292  setstat(s, -1, "stale statement", (*s->ov3) ? "HY000" : "S1000");
4293  return SQL_ERROR;
4294  }
4295  rc = sqlite3_step(s->s3stmt);
4296  if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
4297  ++s->s3stmt_rownum;
4298  ncols = sqlite3_column_count(s->s3stmt);
4299  if (d->s3stmt_needmeta && s->s3stmt_rownum == 0 && ncols > 0) {
4300  PTRDIFF_T size;
4301  char *p;
4302  COL *dyncols;
4303  const char *colname, *typename;
4304 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4305  char *tblname;
4306 #endif
4307 
4308  for (i = size = 0; i < ncols; i++) {
4309  colname = sqlite3_column_name(s->s3stmt, i);
4310  size += 3 + 3 * strlen(colname);
4311  }
4312 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4313  tblname = (char *) size;
4314  for (i = 0; i < ncols; i++) {
4315  p = (char *) sqlite3_column_table_name(s->s3stmt, i);
4316  size += 2 + (p ? strlen(p) : 0);
4317  }
4318 #endif
4319  dyncols = xmalloc(ncols * sizeof (COL) + size);
4320  if (!dyncols) {
4321  freedyncols(s);
4322  s->ncols = 0;
4323  dbtraceapi(d, "sqlite3_finalize", 0);
4324  sqlite3_finalize(s->s3stmt);
4325  s->s3stmt = NULL;
4326  d->cur_s3stmt = NULL;
4327  return nomem(s);
4328  }
4329  p = (char *) (dyncols + ncols);
4330 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4331  tblname = p + (PTRDIFF_T) tblname;
4332 #endif
4333  for (i = 0; i < ncols; i++) {
4334  char *q;
4335 
4336  colname = sqlite3_column_name(s->s3stmt, i);
4337  if (d->trace) {
4338  fprintf(d->trace, "-- column %d name: '%s'\n",
4339  i + 1, colname);
4340  fflush(d->trace);
4341  }
4342 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4343  q = (char *) sqlite3_column_table_name(s->s3stmt, i);
4344  strcpy(tblname, q ? q : "");
4345  if (d->trace) {
4346  fprintf(d->trace, "-- table %d name: '%s'\n",
4347  i + 1, tblname);
4348  fflush(d->trace);
4349  }
4350  dyncols[i].table = tblname;
4351  tblname += strlen(tblname) + 1;
4352 #endif
4353  typename = s3stmt_coltype(s->s3stmt, i, d, 0);
4354  dyncols[i].db = ((DBC *) (s->dbc))->dbname;
4355  strcpy(p, colname);
4356  dyncols[i].label = p;
4357  p += strlen(p) + 1;
4358  q = strchr(colname, '.');
4359  if (q) {
4360  char *q2 = strchr(q + 1, '.');
4361 
4362  /* SQLite 3.3.4 produces view.table.column sometimes */
4363  if (q2) {
4364  q = q2;
4365  }
4366  }
4367  if (q) {
4368 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
4369  dyncols[i].table = p;
4370 #endif
4371  strncpy(p, colname, q - colname);
4372  p[q - colname] = '\0';
4373  p += strlen(p) + 1;
4374  strcpy(p, q + 1);
4375  dyncols[i].column = p;
4376  p += strlen(p) + 1;
4377  } else {
4378 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
4379  dyncols[i].table = "";
4380 #endif
4381  strcpy(p, colname);
4382  dyncols[i].column = p;
4383  p += strlen(p) + 1;
4384  }
4385  if (s->longnames) {
4386  dyncols[i].column = dyncols[i].label;
4387  }
4388 #ifdef SQL_LONGVARCHAR
4389  dyncols[i].type = SQL_LONGVARCHAR;
4390  dyncols[i].size = 65535;
4391 #else
4392  dyncols[i].type = SQL_VARCHAR;
4393  dyncols[i].size = 255;
4394 #endif
4395  dyncols[i].index = i;
4396  dyncols[i].scale = 0;
4397  dyncols[i].prec = 0;
4398  dyncols[i].nosign = 1;
4399 #if defined(HAVE_SQLITE3TABLECOLUMNMETADATA) && (HAVE_SQLITE3TABLECOLUMNMETADATA)
4400  s3stmt_addmeta(s->s3stmt, i, d, &dyncols[i]);
4401 #else
4402  dyncols[i].autoinc = SQL_FALSE;
4403  dyncols[i].notnull = SQL_NULLABLE;
4404  dyncols[i].ispk = -1;
4405  dyncols[i].isrowid = -1;
4406 #endif
4407  dyncols[i].typename = xstrdup(typename);
4408  }
4409  freedyncols(s);
4410  s->ncols = s->dcols = ncols;
4411  s->dyncols = s->cols = dyncols;
4412  fixupdyncols(s, d);
4413  mkbindcols(s, s->ncols);
4414  d->s3stmt_needmeta = 0;
4415  }
4416  if (ncols <= 0) {
4417  goto killstmt;
4418  }
4419  if (rc == SQLITE_DONE) {
4420  freeresult(s, 0);
4421  s->nrows = 0;
4422  dbtraceapi(d, "sqlite3_finalize", 0);
4423  sqlite3_finalize(s->s3stmt);
4424  s->s3stmt = NULL;
4425  d->cur_s3stmt = NULL;
4426  return SQL_SUCCESS;
4427  }
4428  rowd = xmalloc((1 + 2 * ncols) * sizeof (char *));
4429  if (rowd) {
4430  const unsigned char *value;
4431 
4432  rowd[0] = (char *) ((PTRDIFF_T) (ncols * 2));
4433  ++rowd;
4434  for (i = 0; i < ncols; i++) {
4435  int coltype = sqlite3_column_type(s->s3stmt, i);
4436 
4437  rowd[i] = rowd[i + ncols] = NULL;
4438  if (coltype == SQLITE_BLOB) {
4439  int k, nbytes = sqlite3_column_bytes(s->s3stmt, i);
4440  char *qp;
4441  unsigned const char *bp;
4442 
4443  bp = sqlite3_column_blob(s->s3stmt, i);
4444  qp = xmalloc(nbytes * 2 + 4);
4445  if (qp) {
4446  rowd[i + ncols] = qp;
4447  *qp++ = 'X';
4448  *qp++ = '\'';
4449  for (k = 0; k < nbytes; k++) {
4450  *qp++ = xdigits[(bp[k] >> 4)];
4451  *qp++ = xdigits[(bp[k] & 0xF)];
4452  }
4453  *qp++ = '\'';
4454  *qp = '\0';
4455  }
4456 #ifdef _MSC_VER
4457  } else if (coltype == SQLITE_FLOAT) {
4458  static struct lconv *lc = 0;
4459  double d = sqlite3_column_double(s->s3stmt, i);
4460  char *p, buffer[128];
4461 
4462  /*
4463  * This avoids floating point rounding
4464  * and formatting problems of some SQLite
4465  * versions in conjunction with MSVC 2010.
4466  */
4467  snprintf(buffer, sizeof (buffer), "%.15g", d);
4468  if (!lc) {
4469  lc = localeconv();
4470  }
4471  if (lc && lc->decimal_point && lc->decimal_point[0] &&
4472  lc->decimal_point[0] != '.') {
4473  p = strchr(buffer, lc->decimal_point[0]);
4474  if (p) {
4475  *p = '.';
4476  }
4477  }
4478  rowd[i + ncols] = xstrdup(buffer);
4479 #endif
4480  } else if (coltype != SQLITE_NULL) {
4481  value = sqlite3_column_text(s->s3stmt, i);
4482  rowd[i + ncols] = xstrdup((char *) value);
4483  }
4484  }
4485  for (i = 0; i < ncols; i++) {
4486  int coltype = sqlite3_column_type(s->s3stmt, i);
4487 
4488  value = NULL;
4489  if (coltype == SQLITE_BLOB) {
4490  value = sqlite3_column_blob(s->s3stmt, i);
4491  } else if (coltype != SQLITE_NULL) {
4492  value = sqlite3_column_text(s->s3stmt, i);
4493  }
4494  if (value && !rowd[i + ncols]) {
4495  freerows(rowd);
4496  rowd = 0;
4497  break;
4498  }
4499  }
4500  }
4501  if (rowd) {
4502  freeresult(s, 0);
4503  s->nrows = 1;
4504  s->rows = rowd;
4505  s->rowfree = freerows;
4506  if (rc == SQLITE_DONE) {
4507  dbtraceapi(d, "sqlite3_finalize", 0);
4508  sqlite3_finalize(s->s3stmt);
4509  s->s3stmt = NULL;
4510  d->cur_s3stmt = NULL;
4511  }
4512  return SQL_SUCCESS;
4513  }
4514  }
4515 killstmt:
4516  dbtraceapi(d, "sqlite3_reset", 0);
4517  rc = sqlite3_reset(s->s3stmt);
4518  s->s3stmt_noreset = 1;
4519  errp = sqlite3_errmsg(d->sqlite);
4520  if (d->cur_s3stmt == s) {
4521  d->cur_s3stmt = NULL;
4522  }
4523  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
4524  errp ? errp : "unknown error", rc);
4525  return SQL_ERROR;
4526 }
4527 
4533 static void
4535 {
4536  DBC *d;
4537 
4538  if (!s || !s->s3stmt) {
4539  return;
4540  }
4541  d = (DBC *) s->dbc;
4542  if (d) {
4543  d->busyint = 0;
4544  }
4545  if (!s->s3stmt_noreset) {
4546  dbtraceapi(d, "sqlite3_reset", 0);
4547  sqlite3_reset(s->s3stmt);
4548  s->s3stmt_noreset = 1;
4549  s->s3stmt_rownum = -1;
4550  }
4551  if (d->cur_s3stmt == s) {
4552  d->cur_s3stmt = NULL;
4553  }
4554 }
4555 
4561 static void
4563 {
4564  DBC *d = (DBC *) s->dbc;
4565 
4566  if (d) {
4567  d->busyint = 0;
4568  }
4569  if (d && d->cur_s3stmt == s) {
4570  s3stmt_end(s);
4571  }
4572 }
4573 
4579 static void
4581 {
4582  if (s->s3stmt) {
4583  DBC *d = (DBC *) s->dbc;
4584 
4585  if (d) {
4586  dbtraceapi(d, "sqlite3_finalize", 0);
4587  }
4588  sqlite3_finalize(s->s3stmt);
4589  s->s3stmt = NULL;
4590  s->s3stmt_rownum = 0;
4591  }
4592 }
4593 
4600 static SQLRETURN
4602 {
4603  DBC *d = (DBC *) s->dbc;
4604  const char *endp;
4605  sqlite3_stmt *s3stmt = NULL;
4606  int rc, nretry = 0;
4607 
4608  d->s3stmt_needmeta = 0;
4609  if (!s->s3stmt) {
4610 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
4611  dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
4612 #else
4613  dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
4614 #endif
4615  do {
4616  s3stmt = NULL;
4617 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
4618  rc = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
4619  &s3stmt, &endp);
4620 #else
4621  rc = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
4622  &s3stmt, &endp);
4623 #endif
4624  if (rc != SQLITE_OK) {
4625  if (s3stmt) {
4626  sqlite3_finalize(s3stmt);
4627  s3stmt = NULL;
4628  }
4629  }
4630  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
4631  dbtracerc(d, rc, NULL);
4632  if (rc != SQLITE_OK) {
4633  if (s3stmt) {
4634  dbtraceapi(d, "sqlite3_finalize", NULL);
4635  sqlite3_finalize(s3stmt);
4636  }
4637  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
4638  sqlite3_errmsg(d->sqlite), rc);
4639  return SQL_ERROR;
4640  }
4641  if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
4642  dbtraceapi(d, "sqlite3_finalize", 0);
4643  sqlite3_finalize(s3stmt);
4644  setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
4645  (*s->ov3) ? "HY000" : "S1000");
4646  return SQL_ERROR;
4647  }
4648  s->s3stmt = s3stmt;
4649  s->s3stmt_noreset = 1;
4650  d->s3stmt_needmeta = 1;
4651  }
4652  d->cur_s3stmt = s;
4653  s->s3stmt_rownum = -1;
4654  s3bind(d, s->s3stmt, s->nparams, s->bindparms);
4655  return SQL_SUCCESS;
4656 }
4657 
4658 #ifndef WINTERFACE
4659 
4663 SQLRETURN SQL_API
4664 SQLDataSources(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *srvname,
4665  SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
4666  SQLCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
4667 {
4668  if (env == SQL_NULL_HENV) {
4669  return SQL_INVALID_HANDLE;
4670  }
4671  return SQL_ERROR;
4672 }
4673 #endif
4674 
4675 #ifdef WINTERFACE
4676 
4680 SQLRETURN SQL_API
4681 SQLDataSourcesW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *srvname,
4682  SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
4683  SQLWCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
4684 {
4685  if (env == SQL_NULL_HENV) {
4686  return SQL_INVALID_HANDLE;
4687  }
4688  return SQL_ERROR;
4689 }
4690 #endif
4691 
4692 #ifndef WINTERFACE
4693 
4697 SQLRETURN SQL_API
4698 SQLDrivers(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *drvdesc,
4699  SQLSMALLINT descmax, SQLSMALLINT *desclenp,
4700  SQLCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
4701 {
4702  if (env == SQL_NULL_HENV) {
4703  return SQL_INVALID_HANDLE;
4704  }
4705  return SQL_ERROR;
4706 }
4707 #endif
4708 
4709 #ifdef WINTERFACE
4710 
4714 SQLRETURN SQL_API
4715 SQLDriversW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *drvdesc,
4716  SQLSMALLINT descmax, SQLSMALLINT *desclenp,
4717  SQLWCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
4718 {
4719  if (env == SQL_NULL_HENV) {
4720  return SQL_INVALID_HANDLE;
4721  }
4722  return SQL_ERROR;
4723 }
4724 #endif
4725 
4726 #ifndef WINTERFACE
4727 
4731 SQLRETURN SQL_API
4732 SQLBrowseConnect(SQLHDBC dbc, SQLCHAR *connin, SQLSMALLINT conninLen,
4733  SQLCHAR *connout, SQLSMALLINT connoutMax,
4734  SQLSMALLINT *connoutLen)
4735 {
4736  SQLRETURN ret;
4737 
4738  HDBC_LOCK(dbc);
4739  ret = drvunimpldbc(dbc);
4740  HDBC_UNLOCK(dbc);
4741  return ret;
4742 }
4743 #endif
4744 
4745 #ifdef WINTERFACE
4746 
4750 SQLRETURN SQL_API
4751 SQLBrowseConnectW(SQLHDBC dbc, SQLWCHAR *connin, SQLSMALLINT conninLen,
4752  SQLWCHAR *connout, SQLSMALLINT connoutMax,
4753  SQLSMALLINT *connoutLen)
4754 {
4755  SQLRETURN ret;
4756 
4757  HDBC_LOCK(dbc);
4758  ret = drvunimpldbc(dbc);
4759  HDBC_UNLOCK(dbc);
4760  return ret;
4761 }
4762 #endif
4763 
4772 static SQLRETURN
4773 drvputdata(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
4774 {
4775  STMT *s;
4776  int i, dlen, done = 0;
4777  BINDPARM *p;
4778 
4779  if (stmt == SQL_NULL_HSTMT) {
4780  return SQL_INVALID_HANDLE;
4781  }
4782  s = (STMT *) stmt;
4783  if (!s->query || s->nparams <= 0) {
4784 seqerr:
4785  setstat(s, -1, "sequence error", "HY010");
4786  return SQL_ERROR;
4787  }
4788  for (i = (s->pdcount < 0) ? 0 : s->pdcount; i < s->nparams; i++) {
4789  p = &s->bindparms[i];
4790  if (p->need > 0) {
4791  int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
4792 
4793  if (len == SQL_NULL_DATA) {
4794  freep(&p->parbuf);
4795  p->param = NULL;
4796  p->len = SQL_NULL_DATA;
4797  p->need = -1;
4798  } else if (type != SQL_C_CHAR
4799 #ifdef WCHARSUPPORT
4800  && type != SQL_C_WCHAR
4801 #endif
4802  && type != SQL_C_BINARY) {
4803  int size = 0;
4804 
4805  switch (type) {
4806  case SQL_C_TINYINT:
4807  case SQL_C_UTINYINT:
4808  case SQL_C_STINYINT:
4809 #ifdef SQL_BIT
4810  case SQL_C_BIT:
4811 #endif
4812  size = sizeof (SQLCHAR);
4813  break;
4814  case SQL_C_SHORT:
4815  case SQL_C_USHORT:
4816  case SQL_C_SSHORT:
4817  size = sizeof (SQLSMALLINT);
4818  break;
4819  case SQL_C_LONG:
4820  case SQL_C_ULONG:
4821  case SQL_C_SLONG:
4822  size = sizeof (SQLINTEGER);
4823  break;
4824 #ifdef SQL_BIGINT
4825  case SQL_C_UBIGINT:
4826  case SQL_C_SBIGINT:
4827  size = sizeof (SQLBIGINT);
4828  break;
4829 #endif
4830  case SQL_C_FLOAT:
4831  size = sizeof (float);
4832  break;
4833  case SQL_C_DOUBLE:
4834  size = sizeof (double);
4835  break;
4836 #ifdef SQL_C_TYPE_DATE
4837  case SQL_C_TYPE_DATE:
4838 #endif
4839  case SQL_C_DATE:
4840  size = sizeof (DATE_STRUCT);
4841  break;
4842 #ifdef SQL_C_TYPE_DATE
4843  case SQL_C_TYPE_TIME:
4844 #endif
4845  case SQL_C_TIME:
4846  size = sizeof (TIME_STRUCT);
4847  break;
4848 #ifdef SQL_C_TYPE_DATE
4849  case SQL_C_TYPE_TIMESTAMP:
4850 #endif
4851  case SQL_C_TIMESTAMP:
4852  size = sizeof (TIMESTAMP_STRUCT);
4853  break;
4854  }
4855  freep(&p->parbuf);
4856  p->parbuf = xmalloc(size);
4857  if (!p->parbuf) {
4858  return nomem(s);
4859  }
4860  p->param = p->parbuf;
4861  memcpy(p->param, data, size);
4862  p->len = size;
4863  p->need = -1;
4864  } else if (len == SQL_NTS && (
4865  type == SQL_C_CHAR
4866 #ifdef WCHARSUPPORT
4867  || type == SQL_C_WCHAR
4868 #endif
4869  )) {
4870  char *dp = data;
4871 
4872 #ifdef WCHARSUPPORT
4873  if (type == SQL_C_WCHAR) {
4874  dp = uc_to_utf(data, len);
4875  if (!dp) {
4876  return nomem(s);
4877  }
4878  }
4879 #endif
4880 #if defined(_WIN32) || defined(_WIN64)
4881  if (*s->oemcp) {
4882  dp = wmb_to_utf(data, strlen (data));
4883  if (!dp) {
4884  return nomem(s);
4885  }
4886  }
4887 #endif
4888  dlen = strlen(dp);
4889  freep(&p->parbuf);
4890  p->parbuf = xmalloc(dlen + 1);
4891  if (!p->parbuf) {
4892  if (dp != data) {
4893  uc_free(dp);
4894  }
4895  return nomem(s);
4896  }
4897  p->param = p->parbuf;
4898  strcpy(p->param, dp);
4899  if (dp != data) {
4900  uc_free(dp);
4901  }
4902  p->len = dlen;
4903  p->need = -1;
4904  } else if (len < 0) {
4905  setstat(s, -1, "invalid length", "HY090");
4906  return SQL_ERROR;
4907  } else {
4908  dlen = min(p->len - p->offs, len);
4909  if (!p->param) {
4910  setstat(s, -1, "no memory for parameter", "HY013");
4911  return SQL_ERROR;
4912  }
4913  memcpy((char *) p->param + p->offs, data, dlen);
4914  p->offs += dlen;
4915  if (p->offs >= p->len) {
4916 #ifdef WCHARSUPPORT
4917  if (type == SQL_C_WCHAR) {
4918  char *dp = uc_to_utf(p->param, p->len);
4919  char *np;
4920  int nlen;
4921 
4922  if (!dp) {
4923  return nomem(s);
4924  }
4925  nlen = strlen(dp);
4926  np = xmalloc(nlen + 1);
4927  if (!np) {
4928  uc_free(dp);
4929  return nomem(s);
4930  }
4931  strcpy(np, dp);
4932  uc_free(dp);
4933  if (p->param == p->parbuf) {
4934  freep(&p->parbuf);
4935  }
4936  p->parbuf = p->param = np;
4937  p->len = nlen;
4938  } else {
4939  *((char *) p->param + p->len) = '\0';
4940  }
4941  p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR)
4942  ? -1 : 0;
4943 #else
4944  *((char *) p->param + p->len) = '\0';
4945  p->need = (type == SQL_C_CHAR) ? -1 : 0;
4946 #endif
4947 #if defined(_WIN32) || defined(_WIN64)
4948  if (type == SQL_C_CHAR && *s->oemcp &&
4949  !(p->stype == SQL_BINARY ||
4950  p->stype == SQL_VARBINARY ||
4951  p->stype == SQL_LONGVARBINARY)) {
4952  char *dp = wmb_to_utf(p->param, p->len);
4953 
4954  if (!dp) {
4955  return nomem(s);
4956  }
4957  if (p->param == p->parbuf) {
4958  freep(&p->parbuf);
4959  }
4960  p->parbuf = p->param = dp;
4961  p->len = strlen(dp);
4962  }
4963  if (p->type == SQL_C_WCHAR &&
4964  (p->stype == SQL_VARCHAR ||
4965  p->stype == SQL_LONGVARCHAR) &&
4966  p->len == p->coldef * sizeof (SQLWCHAR)) {
4967  /* fix for MS-Access */
4968  p->len = p->coldef;
4969  }
4970 #endif
4971  }
4972  }
4973  done = 1;
4974  break;
4975  }
4976  }
4977  if (!done) {
4978  goto seqerr;
4979  }
4980  return SQL_SUCCESS;
4981 }
4982 
4991 SQLRETURN SQL_API
4992 SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
4993 {
4994  SQLRETURN ret;
4995 
4996  HSTMT_LOCK(stmt);
4997  ret = drvputdata(stmt, data, len);
4998  HSTMT_UNLOCK(stmt);
4999  return ret;
5000 }
5001 
5007 static SQLRETURN
5009 {
5010  if (s->bindparms) {
5011  int n;
5012 
5013  for (n = 0; n < s->nbindparms; n++) {
5014  freep(&s->bindparms[n].parbuf);
5015  memset(&s->bindparms[n], 0, sizeof (BINDPARM));
5016  }
5017  }
5018  return SQL_SUCCESS;
5019 }
5020 
5032 static SQLRETURN
5033 setupparam(STMT *s, char *sql, int pnum)
5034 {
5035  int type, len = 0, needalloc = 0;
5036  BINDPARM *p;
5037 
5038  if (!s->bindparms || pnum < 0 || pnum >= s->nbindparms) {
5039  goto error;
5040  }
5041  p = &s->bindparms[pnum];
5042  type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
5043 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
5044  /* MS Access hack part 4 (map SQL_C_DEFAULT to SQL_C_CHAR) */
5045  if (type == SQL_C_WCHAR && p->type == SQL_C_DEFAULT) {
5046  type = SQL_C_CHAR;
5047  }
5048 #endif
5049  if (p->need > 0) {
5050  return setupparbuf(s, p);
5051  }
5052  p->strbuf[0] = '\0';
5053  if (!p->param || (p->lenp && *p->lenp == SQL_NULL_DATA)) {
5054  p->s3type = SQLITE_NULL;
5055  p->s3size = 0;
5056  return SQL_SUCCESS;
5057  }
5058  if (type == SQL_C_CHAR &&
5059  (p->stype == SQL_BINARY ||
5060  p->stype == SQL_VARBINARY ||
5061  p->stype == SQL_LONGVARBINARY)) {
5062  type = SQL_C_BINARY;
5063  }
5064  switch (type) {
5065  case SQL_C_BINARY:
5066  p->s3type = SQLITE_BLOB;
5067  p->s3size = p->len;
5068  p->s3val = p->param;
5069  if (p->need < 0) {
5070  break;
5071  }
5072  if (!p->lenp) {
5073  len = p->len;
5074  } else if (*p->lenp == SQL_DATA_AT_EXEC) {
5075  len = p->len;
5076  } else {
5077  len = *p->lenp;
5078  if (len <= SQL_LEN_DATA_AT_EXEC_OFFSET) {
5079  len = SQL_LEN_DATA_AT_EXEC(len);
5080  }
5081  }
5082  if (len < 0) {
5083  setstat(s, -1, "invalid length", "HY009");
5084  return SQL_ERROR;
5085  }
5086  p->len = len;
5087  p->max = p->len;
5088  p->need = -1;
5089  p->s3size = len;
5090  break;
5091 #ifdef WCHARSUPPORT
5092  case SQL_C_WCHAR:
5093 #endif
5094  case SQL_C_CHAR:
5095  p->s3type = SQLITE_TEXT;
5096  p->s3size = -1;
5097  p->s3val = p->param;
5098  if (!p->parbuf) {
5099 #ifdef WCHARSUPPORT
5100  if (type == SQL_C_WCHAR) {
5101  if (!p->lenp || *p->lenp == SQL_NTS) {
5102  p->max = uc_strlen(p->param) * sizeof (SQLWCHAR);
5103  } else if (*p->lenp >= 0) {
5104  p->max = *p->lenp;
5105  }
5106  } else
5107 #endif
5108  if (type == SQL_C_CHAR) {
5109  if (!p->lenp || *p->lenp == SQL_NTS) {
5110  p->len = p->max = strlen(p->param);
5111 #if defined(_WIN32) || defined(_WIN64)
5112  needalloc = 1;
5113 #endif
5114  } else if (*p->lenp >= 0) {
5115  p->len = p->max = *p->lenp;
5116  needalloc = 1;
5117  }
5118  }
5119  }
5120  if (p->need < 0 && p->parbuf == p->param) {
5121  break;
5122  }
5123 #ifdef WCHARSUPPORT
5124  if (type == SQL_C_WCHAR) {
5125  char *dp = uc_to_utf(p->param, p->max);
5126 
5127  if (!dp) {
5128  return nomem(s);
5129  }
5130  if (p->param == p->parbuf) {
5131  freep(&p->parbuf);
5132  }
5133  p->parbuf = p->param = dp;
5134  p->need = -1;
5135  p->len = strlen(p->param);
5136  p->s3val = p->param;
5137  p->s3size = p->len;
5138  } else
5139 #endif
5140  if (type == SQL_C_CHAR) {
5141  p->s3val = p->param;
5142  if (needalloc) {
5143  char *dp;
5144 
5145 #if defined(_WIN32) || defined(_WIN64)
5146  if (*s->oemcp) {
5147  dp = wmb_to_utf(p->param, p->len);
5148  } else {
5149  dp = xmalloc(p->len + 1);
5150  }
5151 #else
5152  dp = xmalloc(p->len + 1);
5153 #endif
5154  if (!dp) {
5155  return nomem(s);
5156  }
5157 #if defined(_WIN32) || defined(_WIN64)
5158  if (*s->oemcp) {
5159  p->len = strlen(dp);
5160  } else {
5161  memcpy(dp, p->param, p->len);
5162  dp[p->len] = '\0';
5163  }
5164 #else
5165  memcpy(dp, p->param, p->len);
5166  dp[p->len] = '\0';
5167 #endif
5168  if (p->param == p->parbuf) {
5169  freep(&p->parbuf);
5170  }
5171  p->parbuf = p->param = dp;
5172  p->need = -1;
5173  p->s3val = p->param;
5174  p->s3size = p->len;
5175  }
5176  }
5177  break;
5178  case SQL_C_UTINYINT:
5179  case SQL_C_TINYINT:
5180  case SQL_C_STINYINT:
5181  p->s3type = SQLITE_INTEGER;
5182  p->s3size = sizeof (int);
5183  p->s3ival = *((SQLCHAR *) p->param);
5184  break;
5185  case SQL_C_USHORT:
5186  p->s3type = SQLITE_INTEGER;
5187  p->s3size = sizeof (int);
5188  p->s3ival = *((SQLUSMALLINT *) p->param);
5189  break;
5190  case SQL_C_SHORT:
5191  case SQL_C_SSHORT:
5192  p->s3type = SQLITE_INTEGER;
5193  p->s3size = sizeof (int);
5194  p->s3ival = *((SQLSMALLINT *) p->param);
5195  break;
5196  case SQL_C_ULONG:
5197  p->s3type = SQLITE_INTEGER;
5198  p->s3size = sizeof (int);
5199  p->s3ival = *((SQLUINTEGER *) p->param);
5200  break;
5201  case SQL_C_LONG:
5202  case SQL_C_SLONG:
5203  p->s3type = SQLITE_INTEGER;
5204  p->s3size = sizeof (int);
5205  p->s3ival = *((SQLINTEGER *) p->param);
5206  break;
5207 #ifdef SQL_BIT
5208  case SQL_C_BIT:
5209  p->s3type = SQLITE_INTEGER;
5210  p->s3size = sizeof (int);
5211  p->s3ival = (*((SQLCHAR *) p->param)) ? 1 : 0;
5212  break;
5213 #endif
5214 #ifdef SQL_BIGINT
5215  case SQL_C_SBIGINT:
5216  p->s3type = SQLITE_INTEGER;
5217  p->s3size = sizeof (sqlite_int64);
5218  p->s3lival = *((sqlite_int64 *) p->param);
5219  break;
5220  case SQL_C_UBIGINT:
5221  p->s3type = SQLITE_INTEGER;
5222  p->s3size = sizeof (sqlite_int64);
5223  p->s3lival = *((sqlite_uint64 *) p->param);
5224  break;
5225 #endif
5226  case SQL_C_FLOAT:
5227  p->s3type = SQLITE_FLOAT;
5228  p->s3size = sizeof (double);
5229  p->s3dval = *((float *) p->param);
5230  break;
5231  case SQL_C_DOUBLE:
5232  p->s3type = SQLITE_FLOAT;
5233  p->s3size = sizeof (double);
5234  p->s3dval = *((double *) p->param);
5235  break;
5236 #ifdef SQL_C_TYPE_DATE
5237  case SQL_C_TYPE_DATE:
5238 #endif
5239  case SQL_C_DATE:
5240  if (*s->jdconv) {
5241  int a, b, x1, x2, y, m, d;
5242 
5243  p->s3type = SQLITE_FLOAT;
5244  p->s3size = sizeof (double);
5245  y = ((DATE_STRUCT *) p->param)->year;
5246  m = ((DATE_STRUCT *) p->param)->month;
5247  d = ((DATE_STRUCT *) p->param)->day;
5248  if (m <= 2) {
5249  y--;
5250  m += 12;
5251  }
5252  a = y / 100;
5253  b = 2 - a + (a / 4);
5254  x1 = 36525 * (y + 4716) / 100;
5255  x2 = 306001 * (m + 1) / 10000;
5256  p->s3dval = x1 + x2 + d + b - 1524.5;
5257  break;
5258  }
5259  sprintf(p->strbuf, "%04d-%02d-%02d",
5260  ((DATE_STRUCT *) p->param)->year,
5261  ((DATE_STRUCT *) p->param)->month,
5262  ((DATE_STRUCT *) p->param)->day);
5263  p->s3type = SQLITE_TEXT;
5264  p->s3size = -1;
5265  p->s3val = p->strbuf;
5266  break;
5267 #ifdef SQL_C_TYPE_TIME
5268  case SQL_C_TYPE_TIME:
5269 #endif
5270  case SQL_C_TIME:
5271  if (*s->jdconv) {
5272  p->s3type = SQLITE_FLOAT;
5273  p->s3size = sizeof (double);
5274  p->s3dval = 2451544.5 +
5275  (((TIME_STRUCT *) p->param)->hour * 3600000.0 +
5276  ((TIME_STRUCT *) p->param)->minute * 60000.0 +
5277  ((TIME_STRUCT *) p->param)->second * 1000.0) / 86400000.0;
5278  break;
5279  }
5280  sprintf(p->strbuf, "%02d:%02d:%02d",
5281  ((TIME_STRUCT *) p->param)->hour,
5282  ((TIME_STRUCT *) p->param)->minute,
5283  ((TIME_STRUCT *) p->param)->second);
5284  p->s3type = SQLITE_TEXT;
5285  p->s3size = -1;
5286  p->s3val = p->strbuf;
5287  break;
5288 #ifdef SQL_C_TYPE_TIMESTAMP
5289  case SQL_C_TYPE_TIMESTAMP:
5290 #endif
5291  case SQL_C_TIMESTAMP:
5292  if (*s->jdconv) {
5293  int a, b, x1, x2, y, m, d;
5294 
5295  p->s3type = SQLITE_FLOAT;
5296  p->s3size = sizeof (double);
5297  y = ((TIMESTAMP_STRUCT *) p->param)->year;
5298  m = ((TIMESTAMP_STRUCT *) p->param)->month;
5299  d = ((TIMESTAMP_STRUCT *) p->param)->day;
5300  if (m <= 2) {
5301  y--;
5302  m += 12;
5303  }
5304  a = y / 100;
5305  b = 2 - a + (a / 4);
5306  x1 = 36525 * (y + 4716) / 100;
5307  x2 = 306001 * (m + 1) / 10000;
5308  p->s3dval = x1 + x2 + d + b - 1524.5 +
5309  (((TIMESTAMP_STRUCT *) p->param)->hour * 3600000.0 +
5310  ((TIMESTAMP_STRUCT *) p->param)->minute * 60000.0 +
5311  ((TIMESTAMP_STRUCT *) p->param)->second * 1000.0 +
5312  ((TIMESTAMP_STRUCT *) p->param)->fraction / 1.0E6)
5313  / 86400000.0;
5314  break;
5315  }
5316  len = (int) ((TIMESTAMP_STRUCT *) p->param)->fraction;
5317  len /= 1000000;
5318  len = len % 1000;
5319  if (len < 0) {
5320  len = 0;
5321  }
5322  if (p->coldef && p->coldef <= 16) {
5323  sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
5324  ((TIMESTAMP_STRUCT *) p->param)->year,
5325  ((TIMESTAMP_STRUCT *) p->param)->month,
5326  ((TIMESTAMP_STRUCT *) p->param)->day,
5327  ((TIMESTAMP_STRUCT *) p->param)->hour,
5328  ((TIMESTAMP_STRUCT *) p->param)->minute);
5329  } else if (p->coldef && p->coldef <= 19) {
5330  sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
5331  ((TIMESTAMP_STRUCT *) p->param)->year,
5332  ((TIMESTAMP_STRUCT *) p->param)->month,
5333  ((TIMESTAMP_STRUCT *) p->param)->day,
5334  ((TIMESTAMP_STRUCT *) p->param)->hour,
5335  ((TIMESTAMP_STRUCT *) p->param)->minute,
5336  ((TIMESTAMP_STRUCT *) p->param)->second);
5337  } else {
5338  sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
5339  ((TIMESTAMP_STRUCT *) p->param)->year,
5340  ((TIMESTAMP_STRUCT *) p->param)->month,
5341  ((TIMESTAMP_STRUCT *) p->param)->day,
5342  ((TIMESTAMP_STRUCT *) p->param)->hour,
5343  ((TIMESTAMP_STRUCT *) p->param)->minute,
5344  ((TIMESTAMP_STRUCT *) p->param)->second,
5345  len);
5346  }
5347  p->s3type = SQLITE_TEXT;
5348  p->s3size = -1;
5349  p->s3val = p->strbuf;
5350  break;
5351  default:
5352  error:
5353  setstat(s, -1, "unsupported parameter type",
5354  (*s->ov3) ? "07009" : "S1093");
5355  return SQL_ERROR;
5356  }
5357  return SQL_SUCCESS;
5358 }
5359 
5375 static SQLRETURN
5376 drvbindparam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
5377  SQLSMALLINT buftype, SQLSMALLINT ptype, SQLUINTEGER coldef,
5378  SQLSMALLINT scale,
5379  SQLPOINTER data, SQLINTEGER buflen, SQLLEN *len)
5380 {
5381  STMT *s;
5382  BINDPARM *p;
5383 
5384  if (stmt == SQL_NULL_HSTMT) {
5385  return SQL_INVALID_HANDLE;
5386  }
5387  s = (STMT *) stmt;
5388  if (pnum == 0) {
5389  setstat(s, -1, "invalid parameter", (*s->ov3) ? "07009" : "S1093");
5390  return SQL_ERROR;
5391  }
5392  if (!data && !len) {
5393  setstat(s, -1, "invalid buffer", "HY003");
5394  return SQL_ERROR;
5395  }
5396  --pnum;
5397  if (s->bindparms) {
5398  if (pnum >= s->nbindparms) {
5399  BINDPARM *newparms;
5400 
5401  newparms = xrealloc(s->bindparms,
5402  (pnum + 1) * sizeof (BINDPARM));
5403  if (!newparms) {
5404 outofmem:
5405  return nomem(s);
5406  }
5407  s->bindparms = newparms;
5408  memset(&s->bindparms[s->nbindparms], 0,
5409  (pnum + 1 - s->nbindparms) * sizeof (BINDPARM));
5410  s->nbindparms = pnum + 1;
5411  }
5412  } else {
5413  int npar = max(10, pnum + 1);
5414 
5415  s->bindparms = xmalloc(npar * sizeof (BINDPARM));
5416  if (!s->bindparms) {
5417  goto outofmem;
5418  }
5419  memset(s->bindparms, 0, npar * sizeof (BINDPARM));
5420  s->nbindparms = npar;
5421  }
5422  switch (buftype) {
5423  case SQL_C_STINYINT:
5424  case SQL_C_UTINYINT:
5425  case SQL_C_TINYINT:
5426 #ifdef SQL_C_BIT
5427  case SQL_C_BIT:
5428 #endif
5429  buflen = sizeof (SQLCHAR);
5430  break;
5431  case SQL_C_SHORT:
5432  case SQL_C_USHORT:
5433  case SQL_C_SSHORT:
5434  buflen = sizeof (SQLSMALLINT);
5435  break;
5436  case SQL_C_SLONG:
5437  case SQL_C_ULONG:
5438  case SQL_C_LONG:
5439  buflen = sizeof (SQLINTEGER);
5440  break;
5441  case SQL_C_FLOAT:
5442  buflen = sizeof (float);
5443  break;
5444  case SQL_C_DOUBLE:
5445  buflen = sizeof (double);
5446  break;
5447  case SQL_C_TIMESTAMP:
5448 #ifdef SQL_C_TYPE_TIMESTAMP
5449  case SQL_C_TYPE_TIMESTAMP:
5450 #endif
5451  buflen = sizeof (TIMESTAMP_STRUCT);
5452  break;
5453  case SQL_C_TIME:
5454 #ifdef SQL_C_TYPE_TIME
5455  case SQL_C_TYPE_TIME:
5456 #endif
5457  buflen = sizeof (TIME_STRUCT);
5458  break;
5459  case SQL_C_DATE:
5460 #ifdef SQL_C_TYPE_DATE
5461  case SQL_C_TYPE_DATE:
5462 #endif
5463  buflen = sizeof (DATE_STRUCT);
5464  break;
5465 #ifdef SQL_C_UBIGINT
5466  case SQL_C_UBIGINT:
5467  buflen = sizeof (SQLBIGINT);
5468  break;
5469 #endif
5470 #ifdef SQL_C_SBIGINT
5471  case SQL_C_SBIGINT:
5472  buflen = sizeof (SQLBIGINT);
5473  break;
5474 #endif
5475 #ifdef SQL_C_BIGINT
5476  case SQL_C_BIGINT:
5477  buflen = sizeof (SQLBIGINT);
5478  break;
5479 #endif
5480  }
5481  p = &s->bindparms[pnum];
5482  p->type = buftype;
5483  p->stype = ptype;
5484  p->coldef = coldef;
5485  p->scale = scale;
5486  p->max = buflen;
5487  p->inc = buflen;
5488  p->lenp = p->lenp0 = len;
5489  p->offs = 0;
5490  p->len = 0;
5491  p->param0 = data;
5492  freep(&p->parbuf);
5493  p->param = p->param0;
5494  p->bound = 1;
5495  p->need = 0;
5496  return SQL_SUCCESS;
5497 }
5498 
5514 SQLRETURN SQL_API
5515 SQLBindParameter(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
5516  SQLSMALLINT buftype, SQLSMALLINT ptype, SQLULEN coldef,
5517  SQLSMALLINT scale,
5518  SQLPOINTER data, SQLLEN buflen, SQLLEN *len)
5519 {
5520  SQLRETURN ret;
5521 
5522  HSTMT_LOCK(stmt);
5523  ret = drvbindparam(stmt, pnum, iotype, buftype, ptype, coldef,
5524  scale, data, buflen, len);
5525  HSTMT_UNLOCK(stmt);
5526  return ret;
5527 }
5528 
5529 #ifndef HAVE_IODBC
5530 
5543 SQLRETURN SQL_API
5544 SQLBindParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT vtype,
5545  SQLSMALLINT ptype, SQLULEN lenprec,
5546  SQLSMALLINT scale, SQLPOINTER val,
5547  SQLLEN *lenp)
5548 {
5549  SQLRETURN ret;
5550 
5551  HSTMT_LOCK(stmt);
5552  ret = drvbindparam(stmt, pnum, SQL_PARAM_INPUT, vtype, ptype,
5553  lenprec, scale, val, 0, lenp);
5554  HSTMT_UNLOCK(stmt);
5555  return ret;
5556 }
5557 #endif
5558 
5566 SQLRETURN SQL_API
5567 SQLNumParams(SQLHSTMT stmt, SQLSMALLINT *nparam)
5568 {
5569  STMT *s;
5570  SQLSMALLINT dummy;
5571 
5572  HSTMT_LOCK(stmt);
5573  if (stmt == SQL_NULL_HSTMT) {
5574  return SQL_INVALID_HANDLE;
5575  }
5576  s = (STMT *) stmt;
5577  if (!nparam) {
5578  nparam = &dummy;
5579  }
5580  *nparam = s->nparams;
5581  HSTMT_UNLOCK(stmt);
5582  return SQL_SUCCESS;
5583 }
5584 
5592 static SQLRETURN
5594 {
5595  if (!p->parbuf) {
5596  if (*p->lenp == SQL_DATA_AT_EXEC) {
5597  p->len = p->max;
5598  } else {
5599  p->len = SQL_LEN_DATA_AT_EXEC(*p->lenp);
5600  }
5601  if (p->len < 0 && p->len != SQL_NTS &&
5602  p->len != SQL_NULL_DATA) {
5603  setstat(s, -1, "invalid length", "HY009");
5604  return SQL_ERROR;
5605  }
5606  if (p->len >= 0) {
5607  p->parbuf = xmalloc(p->len + 2);
5608  if (!p->parbuf) {
5609  return nomem(s);
5610  }
5611  p->param = p->parbuf;
5612  } else {
5613  p->param = NULL;
5614  }
5615  }
5616  return SQL_NEED_DATA;
5617 }
5618 
5626 SQLRETURN SQL_API
5627 SQLParamData(SQLHSTMT stmt, SQLPOINTER *pind)
5628 {
5629  STMT *s;
5630  int i;
5631  SQLPOINTER dummy;
5632  SQLRETURN ret;
5633  BINDPARM *p;
5634 
5635  HSTMT_LOCK(stmt);
5636  if (stmt == SQL_NULL_HSTMT) {
5637  return SQL_INVALID_HANDLE;
5638  }
5639  s = (STMT *) stmt;
5640  if (!pind) {
5641  pind = &dummy;
5642  }
5643  if (s->pdcount < s->nparams) {
5644  s->pdcount++;
5645  }
5646  for (i = 0; i < s->pdcount; i++) {
5647  p = &s->bindparms[i];
5648  if (p->need > 0) {
5649  int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
5650 
5651  p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR) ? -1 : 0;
5652  }
5653  }
5654  for (; i < s->nparams; i++) {
5655  p = &s->bindparms[i];
5656  if (p->need > 0) {
5657  *pind = (SQLPOINTER) p->param0;
5658  ret = setupparbuf(s, p);
5659  s->pdcount = i;
5660  goto done;
5661  }
5662  }
5663  ret = drvexecute(stmt, 0);
5664 done:
5665  HSTMT_UNLOCK(stmt);
5666  return ret;
5667 }
5668 
5680 SQLRETURN SQL_API
5681 SQLDescribeParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT *dtype,
5682  SQLULEN *size, SQLSMALLINT *decdigits, SQLSMALLINT *nullable)
5683 {
5684  STMT *s;
5685  SQLRETURN ret = SQL_ERROR;
5686 
5687  HSTMT_LOCK(stmt);
5688  if (stmt == SQL_NULL_HSTMT) {
5689  return SQL_INVALID_HANDLE;
5690  }
5691  s = (STMT *) stmt;
5692  --pnum;
5693  if (pnum >= s->nparams) {
5694  setstat(s, -1, "invalid parameter index",
5695  (*s->ov3) ? "HY000" : "S1000");
5696  goto done;
5697  }
5698  if (dtype) {
5699 #ifdef SQL_LONGVARCHAR
5700 #ifdef WINTERFACE
5701  *dtype = s->nowchar[0] ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
5702 #else
5703  *dtype = SQL_LONGVARCHAR;
5704 #endif
5705 #else
5706 #ifdef WINTERFACE
5707  *dtype = s->nowchar[0] ? SQL_VARCHAR : SQL_WVARCHAR;
5708 #else
5709  *dtype = SQL_VARCHAR;
5710 #endif
5711 #endif
5712  }
5713  if (size) {
5714 #ifdef SQL_LONGVARCHAR
5715  *size = 65536;
5716 #else
5717  *size = 255;
5718 #endif
5719  }
5720  if (decdigits) {
5721  *decdigits = 0;
5722  }
5723  if (nullable) {
5724  *nullable = SQL_NULLABLE;
5725  }
5726  ret = SQL_SUCCESS;
5727 done:
5728  HSTMT_UNLOCK(stmt);
5729  return ret;
5730 }
5731 
5745 SQLRETURN SQL_API
5746 SQLSetParam(SQLHSTMT stmt, SQLUSMALLINT par, SQLSMALLINT type,
5747  SQLSMALLINT sqltype, SQLULEN coldef,
5748  SQLSMALLINT scale, SQLPOINTER val, SQLLEN *nval)
5749 {
5750  SQLRETURN ret;
5751 
5752  HSTMT_LOCK(stmt);
5753  ret = drvbindparam(stmt, par, SQL_PARAM_INPUT,
5754  type, sqltype, coldef, scale, val,
5755  SQL_SETPARAM_VALUE_MAX, nval);
5756  HSTMT_UNLOCK(stmt);
5757  return ret;
5758 }
5759 
5764 SQLRETURN SQL_API
5765 SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
5766 {
5767  SQLRETURN ret;
5768 
5769  HSTMT_LOCK(stmt);
5770  ret = drvunimplstmt(stmt);
5771  HSTMT_UNLOCK(stmt);
5772  return ret;
5773 }
5774 
5775 #ifndef WINTERFACE
5776 
5780 SQLRETURN SQL_API
5781 SQLGetDescField(SQLHDESC handle, SQLSMALLINT recno,
5782  SQLSMALLINT fieldid, SQLPOINTER value,
5783  SQLINTEGER buflen, SQLINTEGER *strlen)
5784 {
5785  return SQL_ERROR;
5786 }
5787 #endif
5788 
5789 #ifdef WINTERFACE
5790 
5794 SQLRETURN SQL_API
5795 SQLGetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
5796  SQLSMALLINT fieldid, SQLPOINTER value,
5797  SQLINTEGER buflen, SQLINTEGER *strlen)
5798 {
5799  return SQL_ERROR;
5800 }
5801 #endif
5802 
5803 #ifndef WINTERFACE
5804 
5808 SQLRETURN SQL_API
5809 SQLSetDescField(SQLHDESC handle, SQLSMALLINT recno,
5810  SQLSMALLINT fieldid, SQLPOINTER value,
5811  SQLINTEGER buflen)
5812 {
5813  return SQL_ERROR;
5814 }
5815 #endif
5816 
5817 #ifdef WINTERFACE
5818 
5822 SQLRETURN SQL_API
5823 SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
5824  SQLSMALLINT fieldid, SQLPOINTER value,
5825  SQLINTEGER buflen)
5826 {
5827  return SQL_ERROR;
5828 }
5829 #endif
5830 
5831 #ifndef WINTERFACE
5832 
5836 SQLRETURN SQL_API
5837 SQLGetDescRec(SQLHDESC handle, SQLSMALLINT recno,
5838  SQLCHAR *name, SQLSMALLINT buflen,
5839  SQLSMALLINT *strlen, SQLSMALLINT *type,
5840  SQLSMALLINT *subtype, SQLLEN *len,
5841  SQLSMALLINT *prec, SQLSMALLINT *scale,
5842  SQLSMALLINT *nullable)
5843 {
5844  return SQL_ERROR;
5845 }
5846 #endif
5847 
5848 #ifdef WINTERFACE
5849 
5853 SQLRETURN SQL_API
5854 SQLGetDescRecW(SQLHDESC handle, SQLSMALLINT recno,
5855  SQLWCHAR *name, SQLSMALLINT buflen,
5856  SQLSMALLINT *strlen, SQLSMALLINT *type,
5857  SQLSMALLINT *subtype, SQLLEN *len,
5858  SQLSMALLINT *prec, SQLSMALLINT *scale,
5859  SQLSMALLINT *nullable)
5860 {
5861  return SQL_ERROR;
5862 }
5863 #endif
5864 
5869 SQLRETURN SQL_API
5870 SQLSetDescRec(SQLHDESC handle, SQLSMALLINT recno,
5871  SQLSMALLINT type, SQLSMALLINT subtype,
5872  SQLLEN len, SQLSMALLINT prec,
5873  SQLSMALLINT scale, SQLPOINTER data,
5874  SQLLEN *strlen, SQLLEN *indicator)
5875 {
5876  return SQL_ERROR;
5877 }
5878 
5890 static SQLRETURN
5891 mkresultset(HSTMT stmt, COL *colspec, int ncols, COL *colspec3,
5892  int ncols3, int *nret)
5893 {
5894  STMT *s;
5895  DBC *d;
5896 
5897  if (stmt == SQL_NULL_HSTMT) {
5898  return SQL_INVALID_HANDLE;
5899  }
5900  s = (STMT *) stmt;
5901  if (s->dbc == SQL_NULL_HDBC) {
5902 noconn:
5903  return noconn(s);
5904  }
5905  d = (DBC *) s->dbc;
5906  if (!d->sqlite) {
5907  goto noconn;
5908  }
5909  s3stmt_end_if(s);
5910  freeresult(s, 0);
5911  if (colspec3 && *s->ov3) {
5912  s->ncols = ncols3;
5913  s->cols = colspec3;
5914  } else {
5915  s->ncols = ncols;
5916  s->cols = colspec;
5917  }
5918  mkbindcols(s, s->ncols);
5919  s->nowchar[1] = 1;
5920  s->nrows = 0;
5921  s->rowp = s->rowprs = -1;
5922  s->isselect = -1;
5923  if (nret) {
5924  *nret = s->ncols;
5925  }
5926  return SQL_SUCCESS;
5927 }
5928 
5933 static COL tablePrivSpec2[] = {
5934  { "SYSTEM", "TABLEPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
5935  { "SYSTEM", "TABLEPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
5936  { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
5937  { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
5938  { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
5939  { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
5940  { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
5941 };
5942 
5943 static COL tablePrivSpec3[] = {
5944  { "SYSTEM", "TABLEPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
5945  { "SYSTEM", "TABLEPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
5946  { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
5947  { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
5948  { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
5949  { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
5950  { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
5951 };
5952 
5965 static SQLRETURN
5967  SQLCHAR *cat, SQLSMALLINT catLen,
5968  SQLCHAR *schema, SQLSMALLINT schemaLen,
5969  SQLCHAR *table, SQLSMALLINT tableLen)
5970 {
5971  SQLRETURN ret;
5972  STMT *s;
5973  DBC *d;
5974  int ncols, rc, size, npatt;
5975  char *errp = NULL, *sql, tname[512];
5976 
5977  ret = mkresultset(stmt, tablePrivSpec2, array_size(tablePrivSpec2),
5978  tablePrivSpec3, array_size(tablePrivSpec3), NULL);
5979  if (ret != SQL_SUCCESS) {
5980  return ret;
5981  }
5982  s = (STMT *) stmt;
5983  d = (DBC *) s->dbc;
5984  if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
5985  table = NULL;
5986  goto doit;
5987  }
5988  if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
5989  schema[0] == '%') {
5990  if ((!cat || catLen == 0 || !cat[0]) &&
5991  (!table || tableLen == 0 || !table[0])) {
5992  table = NULL;
5993  goto doit;
5994  }
5995  }
5996 doit:
5997  if (!table) {
5998  size = 1;
5999  tname[0] = '%';
6000  } else {
6001  if (tableLen == SQL_NTS) {
6002  size = sizeof (tname) - 1;
6003  } else {
6004  size = min(sizeof (tname) - 1, tableLen);
6005  }
6006  strncpy(tname, (char *) table, size);
6007  }
6008  tname[size] = '\0';
6009  npatt = unescpat(tname);
6010 #if defined(_WIN32) || defined(_WIN64)
6011  sql = sqlite3_mprintf("select %s as 'TABLE_QUALIFIER', "
6012  "%s as 'TABLE_OWNER', "
6013  "tbl_name as 'TABLE_NAME', "
6014  "'' as 'GRANTOR', "
6015  "'' as 'GRANTEE', "
6016  "'SELECT' AS 'PRIVILEGE', "
6017  "NULL as 'IS_GRANTABLE' "
6018  "from sqlite_master where "
6019  "(type = 'table' or type = 'view') "
6020  "and tbl_name %s %Q "
6021  "UNION "
6022  "select %s as 'TABLE_QUALIFIER', "
6023  "%s as 'TABLE_OWNER', "
6024  "tbl_name as 'TABLE_NAME', "
6025  "'' as 'GRANTOR', "
6026  "'' as 'GRANTEE', "
6027  "'UPDATE' AS 'PRIVILEGE', "
6028  "NULL as 'IS_GRANTABLE' "
6029  "from sqlite_master where "
6030  "(type = 'table' or type = 'view') "
6031  "and tbl_name %s %Q "
6032  "UNION "
6033  "select %s as 'TABLE_QUALIFIER', "
6034  "%s as 'TABLE_OWNER', "
6035  "tbl_name as 'TABLE_NAME', "
6036  "'' as 'GRANTOR', "
6037  "'' as 'GRANTEE', "
6038  "'DELETE' AS 'PRIVILEGE', "
6039  "NULL as 'IS_GRANTABLE' "
6040  "from sqlite_master where "
6041  "(type = 'table' or type = 'view') "
6042  "and tbl_name %s %Q "
6043  "UNION "
6044  "select %s as 'TABLE_QUALIFIER', "
6045  "%s as 'TABLE_OWNER', "
6046  "tbl_name as 'TABLE_NAME', "
6047  "'' as 'GRANTOR', "
6048  "'' as 'GRANTEE', "
6049  "'INSERT' AS 'PRIVILEGE', "
6050  "NULL as 'IS_GRANTABLE' "
6051  "from sqlite_master where "
6052  "(type = 'table' or type = 'view') "
6053  "and tbl_name %s %Q "
6054  "UNION "
6055  "select %s as 'TABLE_QUALIFIER', "
6056  "%s as 'TABLE_OWNER', "
6057  "tbl_name as 'TABLE_NAME', "
6058  "'' as 'GRANTOR', "
6059  "'' as 'GRANTEE', "
6060  "'REFERENCES' AS 'PRIVILEGE', "
6061  "NULL as 'IS_GRANTABLE' "
6062  "from sqlite_master where "
6063  "(type = 'table' or type = 'view') "
6064  "and tbl_name %s %Q",
6065  d->xcelqrx ? "'main'" : "NULL",
6066  d->xcelqrx ? "''" : "NULL",
6067  npatt ? "like" : "=", tname,
6068  d->xcelqrx ? "'main'" : "NULL",
6069  d->xcelqrx ? "''" : "NULL",
6070  npatt ? "like" : "=", tname,
6071  d->xcelqrx ? "'main'" : "NULL",
6072  d->xcelqrx ? "''" : "NULL",
6073  npatt ? "like" : "=", tname,
6074  d->xcelqrx ? "'main'" : "NULL",
6075  d->xcelqrx ? "''" : "NULL",
6076  npatt ? "like" : "=", tname,
6077  d->xcelqrx ? "'main'" : "NULL",
6078  d->xcelqrx ? "''" : "NULL",
6079  npatt ? "like" : "=", tname);
6080 #else
6081  sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
6082  "NULL as 'TABLE_OWNER', "
6083  "tbl_name as 'TABLE_NAME', "
6084  "'' as 'GRANTOR', "
6085  "'' as 'GRANTEE', "
6086  "'SELECT' AS 'PRIVILEGE', "
6087  "NULL as 'IS_GRANTABLE' "
6088  "from sqlite_master where "
6089  "(type = 'table' or type = 'view') "
6090  "and tbl_name %s %Q "
6091  "UNION "
6092  "select NULL as 'TABLE_QUALIFIER', "
6093  "NULL as 'TABLE_OWNER', "
6094  "tbl_name as 'TABLE_NAME', "
6095  "'' as 'GRANTOR', "
6096  "'' as 'GRANTEE', "
6097  "'UPDATE' AS 'PRIVILEGE', "
6098  "NULL as 'IS_GRANTABLE' "
6099  "from sqlite_master where "
6100  "(type = 'table' or type = 'view') "
6101  "and tbl_name %s %Q "
6102  "UNION "
6103  "select NULL as 'TABLE_QUALIFIER', "
6104  "NULL as 'TABLE_OWNER', "
6105  "tbl_name as 'TABLE_NAME', "
6106  "'' as 'GRANTOR', "
6107  "'' as 'GRANTEE', "
6108  "'DELETE' AS 'PRIVILEGE', "
6109  "NULL as 'IS_GRANTABLE' "
6110  "from sqlite_master where "
6111  "(type = 'table' or type = 'view') "
6112  "and tbl_name %s %Q "
6113  "UNION "
6114  "select NULL as 'TABLE_QUALIFIER', "
6115  "NULL as 'TABLE_OWNER', "
6116  "tbl_name as 'TABLE_NAME', "
6117  "'' as 'GRANTOR', "
6118  "'' as 'GRANTEE', "
6119  "'INSERT' AS 'PRIVILEGE', "
6120  "NULL as 'IS_GRANTABLE' "
6121  "from sqlite_master where "
6122  "(type = 'table' or type = 'view') "
6123  "and tbl_name %s %Q "
6124  "UNION "
6125  "select NULL as 'TABLE_QUALIFIER', "
6126  "NULL as 'TABLE_OWNER', "
6127  "tbl_name as 'TABLE_NAME', "
6128  "'' as 'GRANTOR', "
6129  "'' as 'GRANTEE', "
6130  "'REFERENCES' AS 'PRIVILEGE', "
6131  "NULL as 'IS_GRANTABLE' "
6132  "from sqlite_master where "
6133  "(type = 'table' or type = 'view') "
6134  "and tbl_name %s %Q",
6135  npatt ? "like" : "=", tname,
6136  npatt ? "like" : "=", tname,
6137  npatt ? "like" : "=", tname,
6138  npatt ? "like" : "=", tname,
6139  npatt ? "like" : "=", tname);
6140 #endif
6141  if (!sql) {
6142  return nomem(s);
6143  }
6144  ret = starttran(s);
6145  if (ret != SQL_SUCCESS) {
6146  sqlite3_free(sql);
6147  return ret;
6148  }
6149  dbtraceapi(d, "sqlite3_get_table", sql);
6150  rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
6151  sqlite3_free(sql);
6152  if (rc == SQLITE_OK) {
6153  if (ncols != s->ncols) {
6154  freeresult(s, 0);
6155  s->nrows = 0;
6156  } else {
6157  s->rowfree = sqlite3_free_table;
6158  }
6159  } else {
6160  s->nrows = 0;
6161  s->rows = NULL;
6162  s->rowfree = NULL;
6163  }
6164  if (errp) {
6165  sqlite3_free(errp);
6166  errp = NULL;
6167  }
6168  s->rowp = s->rowprs = -1;
6169  return SQL_SUCCESS;
6170 }
6171 
6172 
6173 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
6174 
6186 SQLRETURN SQL_API
6187 SQLTablePrivileges(SQLHSTMT stmt,
6188  SQLCHAR *catalog, SQLSMALLINT catalogLen,
6189  SQLCHAR *schema, SQLSMALLINT schemaLen,
6190  SQLCHAR *table, SQLSMALLINT tableLen)
6191 {
6192 #if defined(_WIN32) || defined(_WIN64)
6193  char *c = NULL, *s = NULL, *t = NULL;
6194 #endif
6195  SQLRETURN ret;
6196 
6197  HSTMT_LOCK(stmt);
6198 #if defined(_WIN32) || defined(_WIN64)
6199  if (!((STMT *) stmt)->oemcp[0]) {
6200  ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
6201  table, tableLen);
6202  goto done2;
6203  }
6204  if (catalog) {
6205  c = wmb_to_utf_c((char *) catalog, catalogLen);
6206  if (!c) {
6207  ret = nomem((STMT *) stmt);
6208  goto done;
6209  }
6210  }
6211  if (schema) {
6212  s = wmb_to_utf_c((char *) schema, schemaLen);
6213  if (!s) {
6214  ret = nomem((STMT *) stmt);
6215  goto done;
6216  }
6217  }
6218  if (table) {
6219  t = wmb_to_utf_c((char *) table, tableLen);
6220  if (!t) {
6221  ret = nomem((STMT *) stmt);
6222  goto done;
6223  }
6224  }
6225  ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
6226  (SQLCHAR *) s, SQL_NTS,
6227  (SQLCHAR *) t, SQL_NTS);
6228 #else
6229  ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
6230  table, tableLen);
6231 #endif
6232 #if defined(_WIN32) || defined(_WIN64)
6233 done:
6234  uc_free(t);
6235  uc_free(s);
6236  uc_free(c);
6237 done2:
6238  ;
6239 #endif
6240  HSTMT_UNLOCK(stmt);
6241  return ret;
6242 }
6243 #endif
6244 
6245 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
6246 #ifdef WINTERFACE
6247 
6259 SQLRETURN SQL_API
6260 SQLTablePrivilegesW(SQLHSTMT stmt,
6261  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
6262  SQLWCHAR *schema, SQLSMALLINT schemaLen,
6263  SQLWCHAR *table, SQLSMALLINT tableLen)
6264 {
6265  char *c = NULL, *s = NULL, *t = NULL;
6266  SQLRETURN ret;
6267 
6268  HSTMT_LOCK(stmt);
6269  if (catalog) {
6270  c = uc_to_utf_c(catalog, catalogLen);
6271  if (!c) {
6272  ret = nomem((STMT *) stmt);
6273  goto done;
6274  }
6275  }
6276  if (schema) {
6277  s = uc_to_utf_c(schema, schemaLen);
6278  if (!s) {
6279  ret = nomem((STMT *) stmt);
6280  goto done;
6281  }
6282  }
6283  if (table) {
6284  t = uc_to_utf_c(table, tableLen);
6285  if (!t) {
6286  ret = nomem((STMT *) stmt);
6287  goto done;
6288  }
6289  }
6290  ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
6291  (SQLCHAR *) s, SQL_NTS,
6292  (SQLCHAR *) t, SQL_NTS);
6293 done:
6294  uc_free(t);
6295  uc_free(s);
6296  uc_free(c);
6297  HSTMT_UNLOCK(stmt);
6298  return ret;
6299 }
6300 #endif
6301 #endif
6302 
6307 static COL colPrivSpec2[] = {
6308  { "SYSTEM", "COLPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
6309  { "SYSTEM", "COLPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
6310  { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6311  { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6312  { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6313  { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6314  { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
6315 };
6316 
6317 static COL colPrivSpec3[] = {
6318  { "SYSTEM", "COLPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
6319  { "SYSTEM", "COLPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
6320  { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6321  { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6322  { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6323  { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6324  { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
6325 };
6326 
6327 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
6328 
6342 SQLRETURN SQL_API
6343 SQLColumnPrivileges(SQLHSTMT stmt,
6344  SQLCHAR *catalog, SQLSMALLINT catalogLen,
6345  SQLCHAR *schema, SQLSMALLINT schemaLen,
6346  SQLCHAR *table, SQLSMALLINT tableLen,
6347  SQLCHAR *column, SQLSMALLINT columnLen)
6348 {
6349  SQLRETURN ret;
6350 
6351  HSTMT_LOCK(stmt);
6352  ret = mkresultset(stmt, colPrivSpec2, array_size(colPrivSpec2),
6353  colPrivSpec3, array_size(colPrivSpec3), NULL);
6354  HSTMT_UNLOCK(stmt);
6355  return ret;
6356 }
6357 #endif
6358 
6359 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
6360 #ifdef WINTERFACE
6361 
6375 SQLRETURN SQL_API
6376 SQLColumnPrivilegesW(SQLHSTMT stmt,
6377  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
6378  SQLWCHAR *schema, SQLSMALLINT schemaLen,
6379  SQLWCHAR *table, SQLSMALLINT tableLen,
6380  SQLWCHAR *column, SQLSMALLINT columnLen)
6381 {
6382  SQLRETURN ret;
6383 
6384  HSTMT_LOCK(stmt);
6385  ret = mkresultset(stmt, colPrivSpec2, array_size(colPrivSpec2),
6386  colPrivSpec3, array_size(colPrivSpec3), NULL);
6387  HSTMT_UNLOCK(stmt);
6388  return ret;
6389 }
6390 #endif
6391 #endif
6392 
6397 static COL pkeySpec2[] = {
6398  { "SYSTEM", "PRIMARYKEY", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
6399  { "SYSTEM", "PRIMARYKEY", "TABLE_OWNER", SCOL_VARCHAR, 50 },
6400  { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
6401  { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6402  { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
6403  { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
6404 };
6405 
6406 static COL pkeySpec3[] = {
6407  { "SYSTEM", "PRIMARYKEY", "TABLE_CAT", SCOL_VARCHAR, 50 },
6408  { "SYSTEM", "PRIMARYKEY", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
6409  { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
6410  { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6411  { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
6412  { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
6413 };
6414 
6427 static SQLRETURN
6428 drvprimarykeys(SQLHSTMT stmt,
6429  SQLCHAR *cat, SQLSMALLINT catLen,
6430  SQLCHAR *schema, SQLSMALLINT schemaLen,
6431  SQLCHAR *table, SQLSMALLINT tableLen)
6432 {
6433  STMT *s;
6434  DBC *d;
6435  SQLRETURN sret;
6436  int i, asize, ret, nrows, ncols, nrows2 = 0, ncols2 = 0;
6437  int namec = -1, uniquec = -1, namec2 = -1, uniquec2 = -1, offs, seq = 1;
6438  PTRDIFF_T size;
6439  char **rowp = NULL, **rowp2 = NULL, *errp = NULL, *sql, tname[512];
6440 
6441  sret = mkresultset(stmt, pkeySpec2, array_size(pkeySpec2),
6442  pkeySpec3, array_size(pkeySpec3), &asize);
6443  if (sret != SQL_SUCCESS) {
6444  return sret;
6445  }
6446  s = (STMT *) stmt;
6447  d = (DBC *) s->dbc;
6448  if (!table || table[0] == '\0' || table[0] == '%') {
6449  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
6450  return SQL_ERROR;
6451  }
6452  if (tableLen == SQL_NTS) {
6453  size = sizeof (tname) - 1;
6454  } else {
6455  size = min(sizeof (tname) - 1, tableLen);
6456  }
6457  strncpy(tname, (char *) table, size);
6458  tname[size] = '\0';
6459  unescpat(tname);
6460  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
6461  if (!sql) {
6462  return nomem(s);
6463  }
6464  sret = starttran(s);
6465  if (sret != SQL_SUCCESS) {
6466  sqlite3_free(sql);
6467  return sret;
6468  }
6469  dbtraceapi(d, "sqlite3_get_table", sql);
6470  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
6471  sqlite3_free(sql);
6472  if (ret != SQLITE_OK) {
6473  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6474  errp ? errp : "unknown error", ret);
6475  if (errp) {
6476  sqlite3_free(errp);
6477  errp = NULL;
6478  }
6479  return SQL_ERROR;
6480  }
6481  if (errp) {
6482  sqlite3_free(errp);
6483  errp = NULL;
6484  }
6485  size = 0;
6486  if (ncols * nrows > 0) {
6487  int typec;
6488 
6489  namec = findcol(rowp, ncols, "name");
6490  uniquec = findcol(rowp, ncols, "pk");
6491  typec = findcol(rowp, ncols, "type");
6492  if (namec >= 0 && uniquec >= 0 && typec >= 0) {
6493  for (i = 1; i <= nrows; i++) {
6494  if (*rowp[i * ncols + uniquec] != '0') {
6495  size++;
6496  }
6497  }
6498  }
6499  }
6500  if (size == 0) {
6501  sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
6502  if (!sql) {
6503  sqlite3_free_table(rowp);
6504  return nomem(s);
6505  }
6506  dbtraceapi(d, "sqlite3_get_table", sql);
6507  ret = sqlite3_get_table(d->sqlite, sql, &rowp2, &nrows2, &ncols2,
6508  &errp);
6509  sqlite3_free(sql);
6510  if (ret != SQLITE_OK) {
6511  sqlite3_free_table(rowp);
6512  sqlite3_free_table(rowp2);
6513  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6514  errp ? errp : "unknown error", ret);
6515  if (errp) {
6516  sqlite3_free(errp);
6517  errp = NULL;
6518  }
6519  return SQL_ERROR;
6520  }
6521  if (errp) {
6522  sqlite3_free(errp);
6523  errp = NULL;
6524  }
6525  }
6526  if (ncols2 * nrows2 > 0) {
6527  namec2 = findcol(rowp2, ncols2, "name");
6528  uniquec2 = findcol(rowp2, ncols2, "unique");
6529  if (namec2 >= 0 && uniquec2 >= 0) {
6530  for (i = 1; i <= nrows2; i++) {
6531  int nnrows, nncols, nlen = 0;
6532  char **rowpp;
6533 
6534  if (rowp2[i * ncols2 + namec2]) {
6535  nlen = strlen(rowp2[i * ncols2 + namec2]);
6536  }
6537  if (nlen < 17 ||
6538  strncmp(rowp2[i * ncols2 + namec2],
6539  "sqlite_autoindex_", 17)) {
6540  continue;
6541  }
6542  if (*rowp2[i * ncols2 + uniquec2] != '0') {
6543  ret = SQLITE_ERROR;
6544  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6545  rowp2[i * ncols2 + namec2]);
6546  if (sql) {
6547  dbtraceapi(d, "sqlite3_get_table", sql);
6548  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6549  &nnrows, &nncols, NULL);
6550  sqlite3_free(sql);
6551  }
6552  if (ret == SQLITE_OK) {
6553  size += nnrows;
6554  sqlite3_free_table(rowpp);
6555  }
6556  }
6557  }
6558  }
6559  }
6560  if (size == 0) {
6561  sqlite3_free_table(rowp);
6562  sqlite3_free_table(rowp2);
6563  return SQL_SUCCESS;
6564  }
6565  s->nrows = size;
6566  size = (size + 1) * asize;
6567  s->rows = xmalloc((size + 1) * sizeof (char *));
6568  if (!s->rows) {
6569  s->nrows = 0;
6570  sqlite3_free_table(rowp);
6571  sqlite3_free_table(rowp2);
6572  return nomem(s);
6573  }
6574  s->rows[0] = (char *) size;
6575  s->rows += 1;
6576  memset(s->rows, 0, sizeof (char *) * size);
6577  s->rowfree = freerows;
6578  offs = s->ncols;
6579  if (rowp) {
6580  for (i = 1; i <= nrows; i++) {
6581  if (*rowp[i * ncols + uniquec] != '0') {
6582  char buf[32];
6583 
6584 #if defined(_WIN32) || defined(_WIN64)
6585  s->rows[offs + 0] = xstrdup(d->xcelqrx ? "main" : "");
6586  s->rows[offs + 1] = xstrdup("");
6587 #else
6588  s->rows[offs + 0] = xstrdup("");
6589  s->rows[offs + 1] = xstrdup("");
6590 #endif
6591  s->rows[offs + 2] = xstrdup(tname);
6592  s->rows[offs + 3] = xstrdup(rowp[i * ncols + namec]);
6593  sprintf(buf, "%d", seq++);
6594  s->rows[offs + 4] = xstrdup(buf);
6595  offs += s->ncols;
6596  }
6597  }
6598  }
6599  if (rowp2) {
6600  for (i = 1; i <= nrows2; i++) {
6601  int nnrows, nncols, nlen = 0;
6602  char **rowpp;
6603 
6604  if (rowp2[i * ncols2 + namec2]) {
6605  nlen = strlen(rowp2[i * ncols2 + namec2]);
6606  }
6607  if (nlen < 17 ||
6608  strncmp(rowp2[i * ncols2 + namec2], "sqlite_autoindex_", 17)) {
6609  continue;
6610  }
6611  if (*rowp2[i * ncols2 + uniquec2] != '0') {
6612  int k;
6613 
6614  ret = SQLITE_ERROR;
6615  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6616  rowp2[i * ncols2 + namec2]);
6617  if (sql) {
6618  dbtraceapi(d, "sqlite3_get_table", sql);
6619  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6620  &nnrows, &nncols, NULL);
6621  sqlite3_free(sql);
6622  }
6623  if (ret != SQLITE_OK) {
6624  continue;
6625  }
6626  for (k = 0; nnrows && k < nncols; k++) {
6627  if (strcmp(rowpp[k], "name") == 0) {
6628  int m;
6629 
6630  for (m = 1; m <= nnrows; m++) {
6631  int roffs = offs + (m - 1) * s->ncols;
6632 
6633 #if defined(_WIN32) || defined(_WIN64)
6634  s->rows[roffs + 0] =
6635  xstrdup(d->xcelqrx ? "main" : "");
6636  s->rows[roffs + 1] = xstrdup("");
6637 #else
6638  s->rows[roffs + 0] = xstrdup("");
6639  s->rows[roffs + 1] = xstrdup("");
6640 #endif
6641  s->rows[roffs + 2] = xstrdup(tname);
6642  s->rows[roffs + 3] =
6643  xstrdup(rowpp[m * nncols + k]);
6644  s->rows[roffs + 5] =
6645  xstrdup(rowp2[i * ncols2 + namec2]);
6646  }
6647  } else if (strcmp(rowpp[k], "seqno") == 0) {
6648  int m;
6649 
6650  for (m = 1; m <= nnrows; m++) {
6651  int roffs = offs + (m - 1) * s->ncols;
6652  int pos = m - 1;
6653  char buf[32];
6654 
6655  sscanf(rowpp[m * nncols + k], "%d", &pos);
6656  sprintf(buf, "%d", pos + 1);
6657  s->rows[roffs + 4] = xstrdup(buf);
6658  }
6659  }
6660  }
6661  offs += nnrows * s->ncols;
6662  sqlite3_free_table(rowpp);
6663  }
6664  }
6665  }
6666  sqlite3_free_table(rowp);
6667  sqlite3_free_table(rowp2);
6668  return SQL_SUCCESS;
6669 }
6670 
6671 #ifndef WINTERFACE
6672 
6684 SQLRETURN SQL_API
6685 SQLPrimaryKeys(SQLHSTMT stmt,
6686  SQLCHAR *cat, SQLSMALLINT catLen,
6687  SQLCHAR *schema, SQLSMALLINT schemaLen,
6688  SQLCHAR *table, SQLSMALLINT tableLen)
6689 {
6690 #if defined(_WIN32) || defined(_WIN64)
6691  char *c = NULL, *s = NULL, *t = NULL;
6692 #endif
6693  SQLRETURN ret;
6694 
6695  HSTMT_LOCK(stmt);
6696 #if defined(_WIN32) || defined(_WIN64)
6697  if (!((STMT *) stmt)->oemcp[0]) {
6698  ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
6699  table, tableLen);
6700  goto done2;
6701  }
6702  if (cat) {
6703  c = wmb_to_utf_c((char *) cat, catLen);
6704  if (!c) {
6705  ret = nomem((STMT *) stmt);
6706  goto done;
6707  }
6708  }
6709  if (schema) {
6710  s = wmb_to_utf_c((char *) schema, schemaLen);
6711  if (!s) {
6712  ret = nomem((STMT *) stmt);
6713  goto done;
6714  }
6715  }
6716  if (table) {
6717  t = wmb_to_utf_c((char *) table, tableLen);
6718  if (!t) {
6719  ret = nomem((STMT *) stmt);
6720  goto done;
6721  }
6722  }
6723  ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
6724  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
6725 #else
6726  ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
6727  table, tableLen);
6728 #endif
6729 #if defined(_WIN32) || defined(_WIN64)
6730 done:
6731  uc_free(t);
6732  uc_free(s);
6733  uc_free(c);
6734 done2:
6735  ;
6736 #endif
6737  HSTMT_UNLOCK(stmt);
6738  return ret;
6739 }
6740 #endif
6741 
6742 #ifdef WINTERFACE
6743 
6755 SQLRETURN SQL_API
6756 SQLPrimaryKeysW(SQLHSTMT stmt,
6757  SQLWCHAR *cat, SQLSMALLINT catLen,
6758  SQLWCHAR *schema, SQLSMALLINT schemaLen,
6759  SQLWCHAR *table, SQLSMALLINT tableLen)
6760 {
6761  char *c = NULL, *s = NULL, *t = NULL;
6762  SQLRETURN ret;
6763 
6764  HSTMT_LOCK(stmt);
6765  if (cat) {
6766  c = uc_to_utf_c(cat, catLen);
6767  if (!c) {
6768  ret = nomem((STMT *) stmt);
6769  goto done;
6770  }
6771  }
6772  if (schema) {
6773  s = uc_to_utf_c(schema, schemaLen);
6774  if (!s) {
6775  ret = nomem((STMT *) stmt);
6776  goto done;
6777  }
6778  }
6779  if (table) {
6780  t = uc_to_utf_c(table, tableLen);
6781  if (!t) {
6782  ret = nomem((STMT *) stmt);
6783  goto done;
6784  }
6785  }
6786  ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
6787  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
6788 done:
6789  uc_free(t);
6790  uc_free(s);
6791  uc_free(c);
6792  HSTMT_UNLOCK(stmt);
6793  return ret;
6794 }
6795 #endif
6796 
6801 static COL scolSpec2[] = {
6802  { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
6803  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6804  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
6805  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
6806  { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
6807  { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
6808  { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
6809  { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
6810  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
6811 };
6812 
6813 static COL scolSpec3[] = {
6814  { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
6815  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6816  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
6817  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
6818  { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
6819  { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
6820  { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
6821  { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
6822  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
6823 };
6824 
6840 static SQLRETURN
6841 drvspecialcolumns(SQLHSTMT stmt, SQLUSMALLINT id,
6842  SQLCHAR *cat, SQLSMALLINT catLen,
6843  SQLCHAR *schema, SQLSMALLINT schemaLen,
6844  SQLCHAR *table, SQLSMALLINT tableLen,
6845  SQLUSMALLINT scope, SQLUSMALLINT nullable)
6846 {
6847  STMT *s;
6848  DBC *d;
6849  SQLRETURN sret;
6850  int i, asize, ret, nrows, ncols, nnnrows, nnncols, offs;
6851  PTRDIFF_T size;
6852  int namec = -1, uniquec = -1, namecc = -1, typecc = -1;
6853  int notnullcc = -1, mkrowid = 0;
6854  char *errp = NULL, *sql, tname[512];
6855  char **rowp = NULL, **rowppp = NULL;
6856 
6857  sret = mkresultset(stmt, scolSpec2, array_size(scolSpec2),
6858  scolSpec3, array_size(scolSpec3), &asize);
6859  if (sret != SQL_SUCCESS) {
6860  return sret;
6861  }
6862  s = (STMT *) stmt;
6863  d = (DBC *) s->dbc;
6864  if (!table || table[0] == '\0' || table[0] == '%') {
6865  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
6866  return SQL_ERROR;
6867  }
6868  if (tableLen == SQL_NTS) {
6869  size = sizeof (tname) - 1;
6870  } else {
6871  size = min(sizeof (tname) - 1, tableLen);
6872  }
6873  strncpy(tname, (char *) table, size);
6874  tname[size] = '\0';
6875  unescpat(tname);
6876  if (id != SQL_BEST_ROWID) {
6877  return SQL_SUCCESS;
6878  }
6879  sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
6880  if (!sql) {
6881  return nomem(s);
6882  }
6883  sret = starttran(s);
6884  if (sret != SQL_SUCCESS) {
6885  sqlite3_free(sql);
6886  return sret;
6887  }
6888  dbtraceapi(d, "sqlite3_get_table", sql);
6889  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
6890  sqlite3_free(sql);
6891  if (ret != SQLITE_OK) {
6892 doerr:
6893  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6894  errp ? errp : "unknown error", ret);
6895  if (errp) {
6896  sqlite3_free(errp);
6897  errp = NULL;
6898  }
6899  return SQL_ERROR;
6900  }
6901  if (errp) {
6902  sqlite3_free(errp);
6903  errp = NULL;
6904  }
6905  size = 0; /* number result rows */
6906  if (ncols * nrows <= 0) {
6907  goto nodata_but_rowid;
6908  }
6909  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
6910  if (!sql) {
6911  return nomem(s);
6912  }
6913  dbtraceapi(d, "sqlite3_get_table", sql);
6914  ret = sqlite3_get_table(d->sqlite, sql, &rowppp, &nnnrows, &nnncols,
6915  &errp);
6916  sqlite3_free(sql);
6917  if (ret != SQLITE_OK) {
6918  sqlite3_free_table(rowp);
6919  goto doerr;
6920  }
6921  if (errp) {
6922  sqlite3_free(errp);
6923  errp = NULL;
6924  }
6925  namec = findcol(rowp, ncols, "name");
6926  uniquec = findcol(rowp, ncols, "unique");
6927  if (namec < 0 || uniquec < 0) {
6928  goto nodata_but_rowid;
6929  }
6930  namecc = findcol(rowppp, nnncols, "name");
6931  typecc = findcol(rowppp, nnncols, "type");
6932  notnullcc = findcol(rowppp, nnncols, "notnull");
6933  for (i = 1; i <= nrows; i++) {
6934  int nnrows, nncols;
6935  char **rowpp = NULL;
6936 
6937  if (*rowp[i * ncols + uniquec] != '0') {
6938  ret = SQLITE_ERROR;
6939  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6940  rowp[i * ncols + namec]);
6941  if (sql) {
6942  dbtraceapi(d, "sqlite3_get_table", sql);
6943  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6944  &nnrows, &nncols, NULL);
6945  sqlite3_free(sql);
6946  }
6947  if (ret == SQLITE_OK) {
6948  size += nnrows;
6949  sqlite3_free_table(rowpp);
6950  }
6951  }
6952  }
6953 nodata_but_rowid:
6954  if (size == 0) {
6955  size = 1;
6956  mkrowid = 1;
6957  }
6958  s->nrows = size;
6959  size = (size + 1) * asize;
6960  s->rows = xmalloc((size + 1) * sizeof (char *));
6961  if (!s->rows) {
6962  s->nrows = 0;
6963  sqlite3_free_table(rowp);
6964  sqlite3_free_table(rowppp);
6965  return nomem(s);
6966  }
6967  s->rows[0] = (char *) size;
6968  s->rows += 1;
6969  memset(s->rows, 0, sizeof (char *) * size);
6970  s->rowfree = freerows;
6971  if (mkrowid) {
6972  s->nrows = 0;
6973  goto mkrowid;
6974  }
6975  offs = 0;
6976  for (i = 1; i <= nrows; i++) {
6977  int nnrows, nncols;
6978  char **rowpp = NULL;
6979 
6980  if (*rowp[i * ncols + uniquec] != '0') {
6981  int k;
6982 
6983  ret = SQLITE_ERROR;
6984  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6985  rowp[i * ncols + namec]);
6986  if (sql) {
6987  dbtraceapi(d, "sqlite3_get_table", sql);
6988  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6989  &nnrows, &nncols, NULL);
6990  sqlite3_free(sql);
6991  }
6992  if (ret != SQLITE_OK) {
6993  continue;
6994  }
6995  for (k = 0; nnrows && k < nncols; k++) {
6996  if (strcmp(rowpp[k], "name") == 0) {
6997  int m;
6998 
6999  for (m = 1; m <= nnrows; m++) {
7000  int roffs = (offs + m) * s->ncols;
7001 
7002  s->rows[roffs + 0] =
7003  xstrdup(stringify(SQL_SCOPE_SESSION));
7004  s->rows[roffs + 1] = xstrdup(rowpp[m * nncols + k]);
7005  s->rows[roffs + 4] = xstrdup("0");
7006  s->rows[roffs + 7] =
7007  xstrdup(stringify(SQL_PC_NOT_PSEUDO));
7008  if (namecc >= 0 && typecc >= 0) {
7009  int ii;
7010 
7011  for (ii = 1; ii <= nnnrows; ii++) {
7012  if (strcmp(rowppp[ii * nnncols + namecc],
7013  rowpp[m * nncols + k]) == 0) {
7014  char *typen = rowppp[ii * nnncols + typecc];
7015  int sqltype, mm, dd, isnullable = 0;
7016  char buf[32];
7017 
7018  s->rows[roffs + 3] = xstrdup(typen);
7019  sqltype = mapsqltype(typen, NULL, *s->ov3,
7020  s->nowchar[0],
7021  s->dobigint);
7022  getmd(typen, sqltype, &mm, &dd);
7023 #ifdef SQL_LONGVARCHAR
7024  if (sqltype == SQL_VARCHAR && mm > 255) {
7025  sqltype = SQL_LONGVARCHAR;
7026  }
7027 #endif
7028 #ifdef WINTERFACE
7029 #ifdef SQL_WLONGVARCHAR
7030  if (sqltype == SQL_WVARCHAR && mm > 255) {
7031  sqltype = SQL_WLONGVARCHAR;
7032  }
7033 #endif
7034 #endif
7035  if (sqltype == SQL_VARBINARY && mm > 255) {
7036  sqltype = SQL_LONGVARBINARY;
7037  }
7038  sprintf(buf, "%d", sqltype);
7039  s->rows[roffs + 2] = xstrdup(buf);
7040  sprintf(buf, "%d", mm);
7041  s->rows[roffs + 5] = xstrdup(buf);
7042  sprintf(buf, "%d", dd);
7043  s->rows[roffs + 6] = xstrdup(buf);
7044  if (notnullcc >= 0) {
7045  char *inp =
7046  rowppp[ii * nnncols + notnullcc];
7047 
7048  isnullable = inp[0] != '0';
7049  }
7050  sprintf(buf, "%d", isnullable);
7051  s->rows[roffs + 8] = xstrdup(buf);
7052  }
7053  }
7054  }
7055  }
7056  }
7057  }
7058  offs += nnrows;
7059  sqlite3_free_table(rowpp);
7060  }
7061  }
7062  if (nullable == SQL_NO_NULLS) {
7063  for (i = 1; i < s->nrows; i++) {
7064  if (s->rows[i * s->ncols + 8][0] == '0') {
7065  int m, i1 = i + 1;
7066 
7067  for (m = 0; m < s->ncols; m++) {
7068  freep(&s->rows[i * s->ncols + m]);
7069  }
7070  size = s->ncols * sizeof (char *) * (s->nrows - i1);
7071  if (size > 0) {
7072  memmove(s->rows + i * s->ncols,
7073  s->rows + i1 * s->ncols,
7074  size);
7075  memset(s->rows + s->nrows * s->ncols, 0,
7076  s->ncols * sizeof (char *));
7077  }
7078  s->nrows--;
7079  --i;
7080  }
7081  }
7082  }
7083 mkrowid:
7084  sqlite3_free_table(rowp);
7085  sqlite3_free_table(rowppp);
7086  if (s->nrows == 0) {
7087  s->rows[s->ncols + 0] = xstrdup(stringify(SQL_SCOPE_SESSION));
7088  s->rows[s->ncols + 1] = xstrdup("_ROWID_");
7089  s->rows[s->ncols + 2] = xstrdup(stringify(SQL_INTEGER));
7090  s->rows[s->ncols + 3] = xstrdup("integer");
7091  s->rows[s->ncols + 4] = xstrdup("0");
7092  s->rows[s->ncols + 5] = xstrdup("10");
7093  s->rows[s->ncols + 6] = xstrdup("9");
7094  s->rows[s->ncols + 7] = xstrdup(stringify(SQL_PC_PSEUDO));
7095  s->rows[s->ncols + 8] = xstrdup(stringify(SQL_FALSE));
7096  s->nrows = 1;
7097  }
7098  return SQL_SUCCESS;
7099 }
7100 
7101 #ifndef WINTERFACE
7102 
7117 SQLRETURN SQL_API
7118 SQLSpecialColumns(SQLHSTMT stmt, SQLUSMALLINT id,
7119  SQLCHAR *cat, SQLSMALLINT catLen,
7120  SQLCHAR *schema, SQLSMALLINT schemaLen,
7121  SQLCHAR *table, SQLSMALLINT tableLen,
7122  SQLUSMALLINT scope, SQLUSMALLINT nullable)
7123 {
7124 #if defined(_WIN32) || defined(_WIN64)
7125  char *c = NULL, *s = NULL, *t = NULL;
7126 #endif
7127  SQLRETURN ret;
7128 
7129  HSTMT_LOCK(stmt);
7130 #if defined(_WIN32) || defined(_WIN64)
7131  if (!((STMT *) stmt)->oemcp[0]) {
7132  ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
7133  table, tableLen, scope, nullable);
7134  goto done2;
7135  }
7136  if (cat) {
7137  c = wmb_to_utf_c((char *) cat, catLen);
7138  if (!c) {
7139  ret = nomem((STMT *) stmt);
7140  goto done;
7141  }
7142  }
7143  if (schema) {
7144  s = wmb_to_utf_c((char *) schema, schemaLen);
7145  if (!s) {
7146  ret = nomem((STMT *) stmt);
7147  goto done;
7148  }
7149  }
7150  if (table) {
7151  t = wmb_to_utf_c((char *) table, tableLen);
7152  if (!t) {
7153  ret = nomem((STMT *) stmt);
7154  goto done;
7155  }
7156  }
7157  ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
7158  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
7159  scope, nullable);
7160 #else
7161  ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
7162  table, tableLen, scope, nullable);
7163 #endif
7164 #if defined(_WIN32) || defined(_WIN64)
7165 done:
7166  uc_free(t);
7167  uc_free(s);
7168  uc_free(c);
7169 done2:
7170  ;
7171 #endif
7172  HSTMT_UNLOCK(stmt);
7173  return ret;
7174 }
7175 #endif
7176 
7177 #ifdef WINTERFACE
7178 
7193 SQLRETURN SQL_API
7194 SQLSpecialColumnsW(SQLHSTMT stmt, SQLUSMALLINT id,
7195  SQLWCHAR *cat, SQLSMALLINT catLen,
7196  SQLWCHAR *schema, SQLSMALLINT schemaLen,
7197  SQLWCHAR *table, SQLSMALLINT tableLen,
7198  SQLUSMALLINT scope, SQLUSMALLINT nullable)
7199 {
7200  char *c = NULL, *s = NULL, *t = NULL;
7201  SQLRETURN ret;
7202 
7203  HSTMT_LOCK(stmt);
7204  if (cat) {
7205  c = uc_to_utf_c(cat, catLen);
7206  if (!c) {
7207  ret = nomem((STMT *) stmt);
7208  goto done;
7209  }
7210  }
7211  if (schema) {
7212  s = uc_to_utf_c(schema, schemaLen);
7213  if (!s) {
7214  ret = nomem((STMT *) stmt);
7215  goto done;
7216  }
7217  }
7218  if (table) {
7219  t = uc_to_utf_c(table, tableLen);
7220  if (!t) {
7221  ret = nomem((STMT *) stmt);
7222  goto done;
7223  }
7224  }
7225  ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
7226  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
7227  scope, nullable);
7228 done:
7229  uc_free(t);
7230  uc_free(s);
7231  uc_free(c);
7232  HSTMT_UNLOCK(stmt);
7233  return ret;
7234 }
7235 #endif
7236 
7241 static COL fkeySpec2[] = {
7242  { "SYSTEM", "FOREIGNKEY", "PKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
7243  { "SYSTEM", "FOREIGNKEY", "PKTABLE_OWNER", SCOL_VARCHAR, 50 },
7244  { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
7245  { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7246  { "SYSTEM", "FOREIGNKEY", "FKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
7247  { "SYSTEM", "FOREIGNKEY", "FKTABLE_OWNER", SCOL_VARCHAR, 50 },
7248  { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
7249  { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7250  { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
7251  { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
7252  { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
7253  { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
7254  { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
7255  { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
7256 };
7257 
7258 static COL fkeySpec3[] = {
7259  { "SYSTEM", "FOREIGNKEY", "PKTABLE_CAT", SCOL_VARCHAR, 50 },
7260  { "SYSTEM", "FOREIGNKEY", "PKTABLE_SCHEM", SCOL_VARCHAR, 50 },
7261  { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
7262  { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7263  { "SYSTEM", "FOREIGNKEY", "FKTABLE_CAT", SCOL_VARCHAR, 50 },
7264  { "SYSTEM", "FOREIGNKEY", "FKTABLE_SCHEM", SCOL_VARCHAR, 50 },
7265  { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
7266  { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7267  { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
7268  { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
7269  { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
7270  { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
7271  { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
7272  { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
7273 };
7274 
7293 static SQLRETURN SQL_API
7294 drvforeignkeys(SQLHSTMT stmt,
7295  SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7296  SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
7297  SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
7298  SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7299  SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
7300  SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
7301 {
7302  STMT *s;
7303  DBC *d;
7304  SQLRETURN sret;
7305  int i, asize, ret, nrows, ncols, offs, namec, seqc, fromc, toc;
7306  int onu, ond;
7307  PTRDIFF_T size;
7308  char **rowp, *errp = NULL, *sql, pname[512], fname[512];
7309 
7310  sret = mkresultset(stmt, fkeySpec2, array_size(fkeySpec2),
7311  fkeySpec3, array_size(fkeySpec3), &asize);
7312  if (sret != SQL_SUCCESS) {
7313  return sret;
7314  }
7315  s = (STMT *) stmt;
7316  sret = starttran(s);
7317  if (sret != SQL_SUCCESS) {
7318  return sret;
7319  }
7320  d = (DBC *) s->dbc;
7321  if ((!PKtable || PKtable[0] == '\0' || PKtable[0] == '%') &&
7322  (!FKtable || FKtable[0] == '\0' || FKtable[0] == '%')) {
7323  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
7324  return SQL_ERROR;
7325  }
7326  size = 0;
7327  if (PKtable) {
7328  if (PKtableLen == SQL_NTS) {
7329  size = sizeof (pname) - 1;
7330  } else {
7331  size = min(sizeof (pname) - 1, PKtableLen);
7332  }
7333  strncpy(pname, (char *) PKtable, size);
7334  }
7335  pname[size] = '\0';
7336  size = 0;
7337  if (FKtable) {
7338 
7339  if (FKtableLen == SQL_NTS) {
7340  size = sizeof (fname) - 1;
7341  } else {
7342  size = min(sizeof (fname) - 1, FKtableLen);
7343  }
7344  strncpy(fname, (char *) FKtable, size);
7345  }
7346  fname[size] = '\0';
7347  if (fname[0] != '\0') {
7348  int plen;
7349 
7350  ret = SQLITE_ERROR;
7351  sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", fname);
7352  if (sql) {
7353  dbtraceapi(d, "sqlite3_get_table", sql);
7354  ret = sqlite3_get_table(d->sqlite, sql, &rowp,
7355  &nrows, &ncols, &errp);
7356  sqlite3_free(sql);
7357  }
7358  if (ret != SQLITE_OK) {
7359  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7360  errp ? errp : "unknown error", ret);
7361  if (errp) {
7362  sqlite3_free(errp);
7363  errp = NULL;
7364  }
7365  return SQL_ERROR;
7366  }
7367  if (errp) {
7368  sqlite3_free(errp);
7369  errp = NULL;
7370  }
7371  if (ncols * nrows <= 0) {
7372 nodata:
7373  sqlite3_free_table(rowp);
7374  return SQL_SUCCESS;
7375  }
7376  size = 0;
7377  namec = findcol(rowp, ncols, "table");
7378  seqc = findcol(rowp, ncols, "seq");
7379  fromc = findcol(rowp, ncols, "from");
7380  toc = findcol(rowp, ncols, "to");
7381  onu = findcol(rowp, ncols, "on_update");
7382  ond = findcol(rowp, ncols, "on_delete");
7383  if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7384  goto nodata;
7385  }
7386  plen = strlen(pname);
7387  for (i = 1; i <= nrows; i++) {
7388  char *ptab = unquote(rowp[i * ncols + namec]);
7389 
7390  if (plen && ptab) {
7391  int len = strlen(ptab);
7392 
7393  if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
7394  continue;
7395  }
7396  }
7397  size++;
7398  }
7399  if (size == 0) {
7400  goto nodata;
7401  }
7402  s->nrows = size;
7403  size = (size + 1) * asize;
7404  s->rows = xmalloc((size + 1) * sizeof (char *));
7405  if (!s->rows) {
7406  s->nrows = 0;
7407  return nomem(s);
7408  }
7409  s->rows[0] = (char *) size;
7410  s->rows += 1;
7411  memset(s->rows, 0, sizeof (char *) * size);
7412  s->rowfree = freerows;
7413  offs = 0;
7414  for (i = 1; i <= nrows; i++) {
7415  int pos = 0, roffs = (offs + 1) * s->ncols;
7416  char *ptab = rowp[i * ncols + namec];
7417  char buf[32];
7418 
7419  if (plen && ptab) {
7420  int len = strlen(ptab);
7421 
7422  if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
7423  continue;
7424  }
7425  }
7426 #if defined(_WIN32) || defined(_WIN64)
7427  s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
7428  s->rows[roffs + 1] = xstrdup("");
7429 #else
7430  s->rows[roffs + 0] = xstrdup("");
7431  s->rows[roffs + 1] = xstrdup("");
7432 #endif
7433  s->rows[roffs + 2] = xstrdup(ptab);
7434  s->rows[roffs + 3] = xstrdup(rowp[i * ncols + toc]);
7435  s->rows[roffs + 4] = xstrdup("");
7436  s->rows[roffs + 5] = xstrdup("");
7437  s->rows[roffs + 6] = xstrdup(fname);
7438  s->rows[roffs + 7] = xstrdup(rowp[i * ncols + fromc]);
7439  sscanf(rowp[i * ncols + seqc], "%d", &pos);
7440  sprintf(buf, "%d", pos + 1);
7441  s->rows[roffs + 8] = xstrdup(buf);
7442  if (onu < 0) {
7443  s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7444  } else {
7445  if (strcmp(rowp[i * ncols + onu], "SET NULL") == 0) {
7446  s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
7447  } else if (strcmp(rowp[i * ncols + onu], "SET DEFAULT") == 0) {
7448  s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_DEFAULT));
7449  } else if (strcmp(rowp[i * ncols + onu], "CASCADE") == 0) {
7450  s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
7451  } else if (strcmp(rowp[i * ncols + onu], "RESTRICT") == 0) {
7452  s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
7453  } else {
7454  s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7455  }
7456  }
7457  if (ond < 0) {
7458  s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7459  } else {
7460  if (strcmp(rowp[i * ncols + ond], "SET NULL") == 0) {
7461  s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
7462  } else if (strcmp(rowp[i * ncols + ond], "SET DEFAULT") == 0) {
7463  s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_DEFAULT));
7464  } else if (strcmp(rowp[i * ncols + ond], "CASCADE") == 0) {
7465  s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
7466  } else if (strcmp(rowp[i * ncols + ond], "RESTRICT") == 0) {
7467  s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
7468  } else {
7469  s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7470  }
7471  }
7472  s->rows[roffs + 11] = NULL;
7473  s->rows[roffs + 12] = NULL;
7474  s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
7475  offs++;
7476  }
7477  sqlite3_free_table(rowp);
7478  } else {
7479  int nnrows, nncols, plen = strlen(pname);
7480  char **rowpp;
7481 
7482  sql = "select name from sqlite_master where type='table'";
7483  dbtraceapi(d, "sqlite3_get_table", sql);
7484  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
7485  if (ret != SQLITE_OK) {
7486  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7487  errp ? errp : "unknown error", ret);
7488  if (errp) {
7489  sqlite3_free(errp);
7490  errp = NULL;
7491  }
7492  return SQL_ERROR;
7493  }
7494  if (errp) {
7495  sqlite3_free(errp);
7496  errp = NULL;
7497  }
7498  if (ncols * nrows <= 0) {
7499  goto nodata;
7500  }
7501  size = 0;
7502  for (i = 1; i <= nrows; i++) {
7503  int k;
7504 
7505  if (!rowp[i]) {
7506  continue;
7507  }
7508  rowpp = NULL;
7509  ret = SQLITE_ERROR;
7510  sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
7511  if (sql) {
7512  dbtraceapi(d, "sqlite3_get_table", sql);
7513  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7514  &nnrows, &nncols, NULL);
7515  sqlite3_free(sql);
7516  }
7517  if (ret != SQLITE_OK || nncols * nnrows <= 0) {
7518  sqlite3_free_table(rowpp);
7519  continue;
7520  }
7521  namec = findcol(rowpp, nncols, "table");
7522  seqc = findcol(rowpp, nncols, "seq");
7523  fromc = findcol(rowpp, nncols, "from");
7524  toc = findcol(rowpp, nncols, "to");
7525  if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7526  sqlite3_free_table(rowpp);
7527  continue;
7528  }
7529  for (k = 1; k <= nnrows; k++) {
7530  char *ptab = unquote(rowpp[k * nncols + namec]);
7531 
7532  if (plen && ptab) {
7533  int len = strlen(ptab);
7534 
7535  if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
7536  continue;
7537  }
7538  }
7539  size++;
7540  }
7541  sqlite3_free_table(rowpp);
7542  }
7543  if (size == 0) {
7544  goto nodata;
7545  }
7546  s->nrows = size;
7547  size = (size + 1) * asize;
7548  s->rows = xmalloc((size + 1) * sizeof (char *));
7549  if (!s->rows) {
7550  s->nrows = 0;
7551  return nomem(s);
7552  }
7553  s->rows[0] = (char *) size;
7554  s->rows += 1;
7555  memset(s->rows, 0, sizeof (char *) * size);
7556  s->rowfree = freerows;
7557  offs = 0;
7558  for (i = 1; i <= nrows; i++) {
7559  int k;
7560 
7561  if (!rowp[i]) {
7562  continue;
7563  }
7564  rowpp = NULL;
7565  ret = SQLITE_ERROR;
7566  sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
7567  if (sql) {
7568  dbtraceapi(d, "sqlite3_get_table", sql);
7569  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7570  &nnrows, &nncols, NULL);
7571  sqlite3_free(sql);
7572  }
7573  if (ret != SQLITE_OK || nncols * nnrows <= 0) {
7574  sqlite3_free_table(rowpp);
7575  continue;
7576  }
7577  namec = findcol(rowpp, nncols, "table");
7578  seqc = findcol(rowpp, nncols, "seq");
7579  fromc = findcol(rowpp, nncols, "from");
7580  toc = findcol(rowpp, nncols, "to");
7581  onu = findcol(rowpp, nncols, "on_update");
7582  ond = findcol(rowpp, nncols, "on_delete");
7583  if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7584  sqlite3_free_table(rowpp);
7585  continue;
7586  }
7587  for (k = 1; k <= nnrows; k++) {
7588  int pos = 0, roffs = (offs + 1) * s->ncols;
7589  char *ptab = unquote(rowpp[k * nncols + namec]);
7590  char buf[32];
7591 
7592  if (plen && ptab) {
7593  int len = strlen(ptab);
7594 
7595  if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
7596  continue;
7597  }
7598  }
7599 #if defined(_WIN32) || defined(_WIN64)
7600  s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
7601  s->rows[roffs + 1] = xstrdup("");
7602 #else
7603  s->rows[roffs + 0] = xstrdup("");
7604  s->rows[roffs + 1] = xstrdup("");
7605 #endif
7606  s->rows[roffs + 2] = xstrdup(ptab);
7607  s->rows[roffs + 3] = xstrdup(rowpp[k * nncols + toc]);
7608  s->rows[roffs + 4] = xstrdup("");
7609  s->rows[roffs + 5] = xstrdup("");
7610  s->rows[roffs + 6] = xstrdup(rowp[i]);
7611  s->rows[roffs + 7] = xstrdup(rowpp[k * nncols + fromc]);
7612  sscanf(rowpp[k * nncols + seqc], "%d", &pos);
7613  sprintf(buf, "%d", pos + 1);
7614  s->rows[roffs + 8] = xstrdup(buf);
7615  if (onu < 0) {
7616  s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7617  } else {
7618  if (strcmp(rowpp[k * nncols + onu], "SET NULL") == 0) {
7619  s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
7620  } else if (strcmp(rowpp[k * nncols + onu], "SET DEFAULT")
7621  == 0) {
7622  s->rows[roffs + 9] =
7623  xstrdup(stringify(SQL_SET_DEFAULT));
7624  } else if (strcmp(rowpp[k * nncols + onu], "CASCADE")
7625  == 0) {
7626  s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
7627  } else if (strcmp(rowpp[k * nncols + onu], "RESTRICT")
7628  == 0) {
7629  s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
7630  } else {
7631  s->rows[roffs + 9] =
7632  xstrdup(stringify(SQL_NO_ACTION));
7633  }
7634  }
7635  if (ond < 0) {
7636  s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7637  } else {
7638  if (strcmp(rowpp[k * nncols + ond], "SET NULL") == 0) {
7639  s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
7640  } else if (strcmp(rowpp[k * nncols + ond], "SET DEFAULT")
7641  == 0) {
7642  s->rows[roffs + 10] =
7643  xstrdup(stringify(SQL_SET_DEFAULT));
7644  } else if (strcmp(rowpp[k * nncols + ond], "CASCADE")
7645  == 0) {
7646  s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
7647  } else if (strcmp(rowpp[k * nncols + ond], "RESTRICT")
7648  == 0) {
7649  s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
7650  } else {
7651  s->rows[roffs + 10] =
7652  xstrdup(stringify(SQL_NO_ACTION));
7653  }
7654  }
7655  s->rows[roffs + 11] = NULL;
7656  s->rows[roffs + 12] = NULL;
7657  s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
7658  offs++;
7659  }
7660  sqlite3_free_table(rowpp);
7661  }
7662  sqlite3_free_table(rowp);
7663  }
7664  return SQL_SUCCESS;
7665 }
7666 
7667 #ifndef WINTERFACE
7668 
7686 SQLRETURN SQL_API
7687 SQLForeignKeys(SQLHSTMT stmt,
7688  SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7689  SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
7690  SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
7691  SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7692  SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
7693  SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
7694 {
7695 #if defined(_WIN32) || defined(_WIN64)
7696  char *pc = NULL, *ps = NULL, *pt = NULL;
7697  char *fc = NULL, *fs = NULL, *ft = NULL;
7698 #endif
7699  SQLRETURN ret;
7700 
7701  HSTMT_LOCK(stmt);
7702 #if defined(_WIN32) || defined(_WIN64)
7703  if (!((STMT *) stmt)->oemcp[0]) {
7704  ret = drvforeignkeys(stmt,
7705  PKcatalog, PKcatalogLen,
7706  PKschema, PKschemaLen, PKtable, PKtableLen,
7707  FKcatalog, FKcatalogLen,
7708  FKschema, FKschemaLen,
7709  FKtable, FKtableLen);
7710  goto done2;
7711  }
7712  if (PKcatalog) {
7713  pc = wmb_to_utf_c((char *) PKcatalog, PKcatalogLen);
7714  if (!pc) {
7715  ret = nomem((STMT *) stmt);
7716  goto done;
7717  }
7718  }
7719  if (PKschema) {
7720  ps = wmb_to_utf_c((char *) PKschema, PKschemaLen);
7721  if (!ps) {
7722  ret = nomem((STMT *) stmt);
7723  goto done;
7724  }
7725  }
7726  if (PKtable) {
7727  pt = wmb_to_utf_c((char *) PKtable, PKtableLen);
7728  if (!pt) {
7729  ret = nomem((STMT *) stmt);
7730  goto done;
7731  }
7732  }
7733  if (FKcatalog) {
7734  fc = wmb_to_utf_c((char *) FKcatalog, FKcatalogLen);
7735  if (!fc) {
7736  ret = nomem((STMT *) stmt);
7737  goto done;
7738  }
7739  }
7740  if (FKschema) {
7741  fs = wmb_to_utf_c((char *) FKschema, FKschemaLen);
7742  if (!fs) {
7743  ret = nomem((STMT *) stmt);
7744  goto done;
7745  }
7746  }
7747  if (FKtable) {
7748  ft = wmb_to_utf_c((char *) FKtable, FKtableLen);
7749  if (!ft) {
7750  ret = nomem((STMT *) stmt);
7751  goto done;
7752  }
7753  }
7754  ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
7755  (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
7756  (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
7757  (SQLCHAR *) ft, SQL_NTS);
7758 #else
7759  ret = drvforeignkeys(stmt,
7760  PKcatalog, PKcatalogLen,
7761  PKschema, PKschemaLen, PKtable, PKtableLen,
7762  FKcatalog, FKcatalogLen,
7763  FKschema, FKschemaLen,
7764  FKtable, FKtableLen);
7765 #endif
7766 #if defined(_WIN32) || defined(_WIN64)
7767 done:
7768  uc_free(ft);
7769  uc_free(fs);
7770  uc_free(fc);
7771  uc_free(pt);
7772  uc_free(ps);
7773  uc_free(pc);
7774 done2:
7775  ;
7776 #endif
7777  HSTMT_UNLOCK(stmt);
7778  return ret;
7779 }
7780 #endif
7781 
7782 #ifdef WINTERFACE
7783 
7801 SQLRETURN SQL_API
7802 SQLForeignKeysW(SQLHSTMT stmt,
7803  SQLWCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7804  SQLWCHAR *PKschema, SQLSMALLINT PKschemaLen,
7805  SQLWCHAR *PKtable, SQLSMALLINT PKtableLen,
7806  SQLWCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7807  SQLWCHAR *FKschema, SQLSMALLINT FKschemaLen,
7808  SQLWCHAR *FKtable, SQLSMALLINT FKtableLen)
7809 {
7810  char *pc = NULL, *ps = NULL, *pt = NULL;
7811  char *fc = NULL, *fs = NULL, *ft = NULL;
7812  SQLRETURN ret;
7813 
7814  HSTMT_LOCK(stmt);
7815  if (PKcatalog) {
7816  pc = uc_to_utf_c(PKcatalog, PKcatalogLen);
7817  if (!pc) {
7818  ret = nomem((STMT *) stmt);
7819  goto done;
7820  }
7821  }
7822  if (PKschema) {
7823  ps = uc_to_utf_c(PKschema, PKschemaLen);
7824  if (!ps) {
7825  ret = nomem((STMT *) stmt);
7826  goto done;
7827  }
7828  }
7829  if (PKtable) {
7830  pt = uc_to_utf_c(PKtable, PKtableLen);
7831  if (!pt) {
7832  ret = nomem((STMT *) stmt);
7833  goto done;
7834  }
7835  }
7836  if (FKcatalog) {
7837  fc = uc_to_utf_c(FKcatalog, FKcatalogLen);
7838  if (!fc) {
7839  ret = nomem((STMT *) stmt);
7840  goto done;
7841  }
7842  }
7843  if (FKschema) {
7844  fs = uc_to_utf_c(FKschema, FKschemaLen);
7845  if (!fs) {
7846  ret = nomem((STMT *) stmt);
7847  goto done;
7848  }
7849  }
7850  if (FKtable) {
7851  ft = uc_to_utf_c(FKtable, FKtableLen);
7852  if (!ft) {
7853  ret = nomem((STMT *) stmt);
7854  goto done;
7855  }
7856  }
7857  ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
7858  (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
7859  (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
7860  (SQLCHAR *) ft, SQL_NTS);
7861 done:
7862  uc_free(ft);
7863  uc_free(fs);
7864  uc_free(fc);
7865  uc_free(pt);
7866  uc_free(ps);
7867  uc_free(pc);
7868  HSTMT_UNLOCK(stmt);
7869  return ret;
7870 }
7871 #endif
7872 
7879 static SQLRETURN
7881 {
7882  int ret = SQL_SUCCESS, rc, busy_count = 0;
7883  char *errp = NULL;
7884  DBC *d = (DBC *) s->dbc;
7885 
7886  if (!d->autocommit && !d->intrans && !d->trans_disable) {
7887 begin_again:
7888  rc = sqlite3_exec(d->sqlite, "BEGIN TRANSACTION", NULL, NULL, &errp);
7889  if (rc == SQLITE_BUSY) {
7890  if (busy_handler((void *) d, ++busy_count)) {
7891  if (errp) {
7892  sqlite3_free(errp);
7893  errp = NULL;
7894  }
7895  goto begin_again;
7896  }
7897  }
7898  dbtracerc(d, rc, errp);
7899  if (rc != SQLITE_OK) {
7900  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7901  errp ? errp : "unknown error", rc);
7902  ret = SQL_ERROR;
7903  } else {
7904  d->intrans = 1;
7905  }
7906  if (errp) {
7907  sqlite3_free(errp);
7908  errp = NULL;
7909  }
7910  }
7911  return ret;
7912 }
7913 
7922 static SQLRETURN
7923 endtran(DBC *d, SQLSMALLINT comptype, int force)
7924 {
7925  int ret, busy_count = 0;
7926  char *sql, *errp = NULL;
7927 
7928  if (!d->sqlite) {
7929  setstatd(d, -1, "not connected", (*d->ov3) ? "HY000" : "S1000");
7930  return SQL_ERROR;
7931  }
7932  if ((!force && d->autocommit) || !d->intrans) {
7933  return SQL_SUCCESS;
7934  }
7935  switch (comptype) {
7936  case SQL_COMMIT:
7937  sql = "COMMIT TRANSACTION";
7938  goto doit;
7939  case SQL_ROLLBACK:
7940  sql = "ROLLBACK TRANSACTION";
7941  doit:
7942  ret = sqlite3_exec(d->sqlite, sql, NULL, NULL, &errp);
7943  dbtracerc(d, ret, errp);
7944  if (ret == SQLITE_BUSY && busy_count < 10) {
7945  if (busy_handler((void *) d, ++busy_count)) {
7946  if (errp) {
7947  sqlite3_free(errp);
7948  errp = NULL;
7949  }
7950  goto doit;
7951  }
7952  }
7953  if (ret != SQLITE_OK) {
7954  setstatd(d, ret, "%s", (*d->ov3) ? "HY000" : "S1000",
7955  errp ? errp : "transaction failed");
7956  if (errp) {
7957  sqlite3_free(errp);
7958  errp = NULL;
7959  }
7960  return SQL_ERROR;
7961  }
7962  if (errp) {
7963  sqlite3_free(errp);
7964  errp = NULL;
7965  }
7966  d->intrans = 0;
7967  return SQL_SUCCESS;
7968  }
7969  setstatd(d, -1, "invalid completion type", (*d->ov3) ? "HY000" : "S1000");
7970  return SQL_ERROR;
7971 }
7972 
7981 static SQLRETURN
7982 drvendtran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
7983 {
7984  DBC *d;
7985  int fail = 0;
7986  SQLRETURN ret;
7987 #if defined(_WIN32) || defined(_WIN64)
7988  ENV *e;
7989 #endif
7990 
7991  switch (type) {
7992  case SQL_HANDLE_DBC:
7993  HDBC_LOCK((SQLHDBC) handle);
7994  if (handle == SQL_NULL_HDBC) {
7995  return SQL_INVALID_HANDLE;
7996  }
7997  d = (DBC *) handle;
7998  ret = endtran(d, comptype, 0);
7999  HDBC_UNLOCK((SQLHDBC) handle);
8000  return ret;
8001  case SQL_HANDLE_ENV:
8002  if (handle == SQL_NULL_HENV) {
8003  return SQL_INVALID_HANDLE;
8004  }
8005 #if defined(_WIN32) || defined(_WIN64)
8006  e = (ENV *) handle;
8007  if (e->magic != ENV_MAGIC) {
8008  return SQL_INVALID_HANDLE;
8009  }
8010  EnterCriticalSection(&e->cs);
8011 #endif
8012  d = ((ENV *) handle)->dbcs;
8013  while (d) {
8014  HDBC_LOCK((SQLHDBC) d);
8015  ret = endtran(d, comptype, 0);
8016  HDBC_UNLOCK((SQLHDBC) d);
8017  if (ret != SQL_SUCCESS) {
8018  fail++;
8019  }
8020  d = d->next;
8021  }
8022 #if defined(_WIN32) || defined(_WIN64)
8023  LeaveCriticalSection(&e->cs);
8024 #endif
8025  return fail ? SQL_ERROR : SQL_SUCCESS;
8026  }
8027  return SQL_INVALID_HANDLE;
8028 }
8029 
8038 SQLRETURN SQL_API
8039 SQLEndTran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
8040 {
8041  return drvendtran(type, handle, comptype);
8042 }
8043 
8052 SQLRETURN SQL_API
8053 SQLTransact(SQLHENV env, SQLHDBC dbc, SQLUSMALLINT type)
8054 {
8055  if (dbc != SQL_NULL_HDBC) {
8056  return drvendtran(SQL_HANDLE_DBC, (SQLHANDLE) dbc, type);
8057  }
8058  return drvendtran(SQL_HANDLE_ENV, (SQLHANDLE) env, type);
8059 }
8060 
8065 SQLRETURN SQL_API
8066 SQLCopyDesc(SQLHDESC source, SQLHDESC target)
8067 {
8068  return SQL_ERROR;
8069 }
8070 
8071 #ifndef WINTERFACE
8072 
8083 SQLRETURN SQL_API
8084 SQLNativeSql(SQLHSTMT stmt, SQLCHAR *sqlin, SQLINTEGER sqlinLen,
8085  SQLCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
8086 {
8087  int outLen = 0;
8088  SQLRETURN ret = SQL_SUCCESS;
8089 
8090  HSTMT_LOCK(stmt);
8091  if (sqlinLen == SQL_NTS) {
8092  sqlinLen = strlen((char *) sqlin);
8093  }
8094  if (sql) {
8095  if (sqlMax > 0) {
8096  strncpy((char *) sql, (char *) sqlin, sqlMax - 1);
8097  sqlin[sqlMax - 1] = '\0';
8098  outLen = min(sqlMax - 1, sqlinLen);
8099  }
8100  } else {
8101  outLen = sqlinLen;
8102  }
8103  if (sqlLen) {
8104  *sqlLen = outLen;
8105  }
8106  if (sql && outLen < sqlinLen) {
8107  setstat((STMT *) stmt, -1, "data right truncated", "01004");
8108  ret = SQL_SUCCESS_WITH_INFO;
8109  }
8110  HSTMT_UNLOCK(stmt);
8111  return ret;
8112 }
8113 #endif
8114 
8115 #ifdef WINTERFACE
8116 
8127 SQLRETURN SQL_API
8128 SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen,
8129  SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
8130 {
8131  int outLen = 0;
8132  SQLRETURN ret = SQL_SUCCESS;
8133 
8134  HSTMT_LOCK(stmt);
8135  if (sqlinLen == SQL_NTS) {
8136  sqlinLen = uc_strlen(sqlin);
8137  }
8138  if (sql) {
8139  if (sqlMax > 0) {
8140  uc_strncpy(sql, sqlin, sqlMax - 1);
8141  sqlin[sqlMax - 1] = 0;
8142  outLen = min(sqlMax - 1, sqlinLen);
8143  }
8144  } else {
8145  outLen = sqlinLen;
8146  }
8147  if (sqlLen) {
8148  *sqlLen = outLen;
8149  }
8150  if (sql && outLen < sqlinLen) {
8151  setstat((STMT *) stmt, -1, "data right truncated", "01004");
8152  ret = SQL_SUCCESS_WITH_INFO;
8153  }
8154  HSTMT_UNLOCK(stmt);
8155  return ret;
8156 }
8157 #endif
8158 
8163 static COL procSpec2[] = {
8164  { "SYSTEM", "PROCEDURE", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
8165  { "SYSTEM", "PROCEDURE", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
8166  { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8167  { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
8168  { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
8169  { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
8170  { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
8171  { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
8172 };
8173 
8174 static COL procSpec3[] = {
8175  { "SYSTEM", "PROCEDURE", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
8176  { "SYSTEM", "PROCEDURE", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
8177  { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8178  { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
8179  { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
8180  { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
8181  { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
8182  { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
8183 };
8184 
8185 #ifndef WINTERFACE
8186 
8198 SQLRETURN SQL_API
8199 SQLProcedures(SQLHSTMT stmt,
8200  SQLCHAR *catalog, SQLSMALLINT catalogLen,
8201  SQLCHAR *schema, SQLSMALLINT schemaLen,
8202  SQLCHAR *proc, SQLSMALLINT procLen)
8203 {
8204  SQLRETURN ret;
8205 
8206  HSTMT_LOCK(stmt);
8207  ret = mkresultset(stmt, procSpec2, array_size(procSpec2),
8208  procSpec3, array_size(procSpec3), NULL);
8209  HSTMT_UNLOCK(stmt);
8210  return ret;
8211 }
8212 #endif
8213 
8214 #ifdef WINTERFACE
8215 
8227 SQLRETURN SQL_API
8228 SQLProceduresW(SQLHSTMT stmt,
8229  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
8230  SQLWCHAR *schema, SQLSMALLINT schemaLen,
8231  SQLWCHAR *proc, SQLSMALLINT procLen)
8232 {
8233  SQLRETURN ret;
8234 
8235  HSTMT_LOCK(stmt);
8236  ret = mkresultset(stmt, procSpec2, array_size(procSpec2),
8237  procSpec3, array_size(procSpec3), NULL);
8238  HSTMT_UNLOCK(stmt);
8239  return ret;
8240 }
8241 #endif
8242 
8247 static COL procColSpec2[] = {
8248  { "SYSTEM", "PROCCOL", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
8249  { "SYSTEM", "PROCCOL", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
8250  { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8251  { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
8252  { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
8253  { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
8254  { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
8255  { "SYSTEM", "PROCCOL", "PRECISION", SQL_INTEGER, 10 },
8256  { "SYSTEM", "PROCCOL", "LENGTH", SQL_INTEGER, 10 },
8257  { "SYSTEM", "PROCCOL", "SCALE", SQL_SMALLINT, 5 },
8258  { "SYSTEM", "PROCCOL", "RADIX", SQL_SMALLINT, 5 },
8259  { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
8260  { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
8261  { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
8262  { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
8263  { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
8264  { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
8265  { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
8266  { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
8267 };
8268 
8269 static COL procColSpec3[] = {
8270  { "SYSTEM", "PROCCOL", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
8271  { "SYSTEM", "PROCCOL", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
8272  { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8273  { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
8274  { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
8275  { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
8276  { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
8277  { "SYSTEM", "PROCCOL", "COLUMN_SIZE", SQL_INTEGER, 10 },
8278  { "SYSTEM", "PROCCOL", "BUFFER_LENGTH", SQL_INTEGER, 10 },
8279  { "SYSTEM", "PROCCOL", "DECIMAL_DIGITS", SQL_SMALLINT, 5 },
8280  { "SYSTEM", "PROCCOL", "NUM_PREC_RADIX", SQL_SMALLINT, 5 },
8281  { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
8282  { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
8283  { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
8284  { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
8285  { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
8286  { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
8287  { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
8288  { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
8289 };
8290 
8291 #ifndef WINTERFACE
8292 
8306 SQLRETURN SQL_API
8307 SQLProcedureColumns(SQLHSTMT stmt,
8308  SQLCHAR *catalog, SQLSMALLINT catalogLen,
8309  SQLCHAR *schema, SQLSMALLINT schemaLen,
8310  SQLCHAR *proc, SQLSMALLINT procLen,
8311  SQLCHAR *column, SQLSMALLINT columnLen)
8312 {
8313  SQLRETURN ret;
8314 
8315  HSTMT_LOCK(stmt);
8316  ret = mkresultset(stmt, procColSpec2, array_size(procColSpec2),
8317  procColSpec3, array_size(procColSpec3), NULL);
8318  HSTMT_UNLOCK(stmt);
8319  return ret;
8320 }
8321 #endif
8322 
8323 #ifdef WINTERFACE
8324 
8339 SQLRETURN SQL_API
8340 SQLProcedureColumnsW(SQLHSTMT stmt,
8341  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
8342  SQLWCHAR *schema, SQLSMALLINT schemaLen,
8343  SQLWCHAR *proc, SQLSMALLINT procLen,
8344  SQLWCHAR *column, SQLSMALLINT columnLen)
8345 {
8346  SQLRETURN ret;
8347 
8348  HSTMT_LOCK(stmt);
8349  ret = mkresultset(stmt, procColSpec2, array_size(procColSpec2),
8350  procColSpec3, array_size(procColSpec3), NULL);
8351  HSTMT_UNLOCK(stmt);
8352  return ret;
8353 }
8354 #endif
8355 
8366 SQLRETURN SQL_API
8367 SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val,
8368  SQLINTEGER len, SQLINTEGER *lenp)
8369 {
8370  ENV *e;
8371  SQLRETURN ret = SQL_ERROR;
8372 
8373  if (env == SQL_NULL_HENV) {
8374  return SQL_INVALID_HANDLE;
8375  }
8376  e = (ENV *) env;
8377  if (!e || e->magic != ENV_MAGIC) {
8378  return SQL_INVALID_HANDLE;
8379  }
8380 #if defined(_WIN32) || defined(_WIN64)
8381  EnterCriticalSection(&e->cs);
8382 #endif
8383  switch (attr) {
8384  case SQL_ATTR_CONNECTION_POOLING:
8385  ret = SQL_ERROR;
8386  break;
8387  case SQL_ATTR_CP_MATCH:
8388  ret = SQL_NO_DATA;
8389  break;
8390  case SQL_ATTR_OUTPUT_NTS:
8391  if (val) {
8392  *((SQLINTEGER *) val) = SQL_TRUE;
8393  }
8394  if (lenp) {
8395  *lenp = sizeof (SQLINTEGER);
8396  }
8397  ret = SQL_SUCCESS;
8398  break;
8399  case SQL_ATTR_ODBC_VERSION:
8400  if (val) {
8401  *((SQLINTEGER *) val) = e->ov3 ? SQL_OV_ODBC3 : SQL_OV_ODBC2;
8402  }
8403  if (lenp) {
8404  *lenp = sizeof (SQLINTEGER);
8405  }
8406  ret = SQL_SUCCESS;
8407  break;
8408  }
8409 #if defined(_WIN32) || defined(_WIN64)
8410  LeaveCriticalSection(&e->cs);
8411 #endif
8412  return ret;
8413 }
8414 
8424 SQLRETURN SQL_API
8425 SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
8426 {
8427  ENV *e;
8428  SQLRETURN ret = SQL_ERROR;
8429 
8430  if (env == SQL_NULL_HENV) {
8431  return SQL_INVALID_HANDLE;
8432  }
8433  e = (ENV *) env;
8434  if (!e || e->magic != ENV_MAGIC) {
8435  return SQL_INVALID_HANDLE;
8436  }
8437 #if defined(_WIN32) || defined(_WIN64)
8438  EnterCriticalSection(&e->cs);
8439 #endif
8440  switch (attr) {
8441  case SQL_ATTR_CONNECTION_POOLING:
8442  ret = SQL_SUCCESS;
8443  break;
8444  case SQL_ATTR_CP_MATCH:
8445  ret = SQL_NO_DATA;
8446  break;
8447  case SQL_ATTR_OUTPUT_NTS:
8448  if (val == (SQLPOINTER) SQL_TRUE) {
8449  ret = SQL_SUCCESS;
8450  }
8451  break;
8452  case SQL_ATTR_ODBC_VERSION:
8453  if (!val) {
8454  break;
8455  }
8456  if (val == (SQLPOINTER) SQL_OV_ODBC2) {
8457  e->ov3 = 0;
8458  ret = SQL_SUCCESS;
8459  }
8460  if (val == (SQLPOINTER) SQL_OV_ODBC3) {
8461  e->ov3 = 1;
8462  ret = SQL_SUCCESS;
8463  }
8464  break;
8465  }
8466 #if defined(_WIN32) || defined(_WIN64)
8467  LeaveCriticalSection(&e->cs);
8468 #endif
8469  return ret;
8470 }
8471 
8485 static SQLRETURN
8486 drvgetdiagrec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8487  SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
8488  SQLSMALLINT buflen, SQLSMALLINT *msglen)
8489 {
8490  DBC *d = NULL;
8491  STMT *s = NULL;
8492  int len, naterr;
8493  char *logmsg, *sqlst;
8494  SQLRETURN ret = SQL_ERROR;
8495 
8496  if (handle == SQL_NULL_HANDLE) {
8497  return SQL_INVALID_HANDLE;
8498  }
8499  if (sqlstate) {
8500  sqlstate[0] = '\0';
8501  }
8502  if (msg && buflen > 0) {
8503  msg[0] = '\0';
8504  }
8505  if (msglen) {
8506  *msglen = 0;
8507  }
8508  if (nativeerr) {
8509  *nativeerr = 0;
8510  }
8511  switch (htype) {
8512  case SQL_HANDLE_ENV:
8513  case SQL_HANDLE_DESC:
8514  return SQL_NO_DATA;
8515  case SQL_HANDLE_DBC:
8516  HDBC_LOCK((SQLHDBC) handle);
8517  d = (DBC *) handle;
8518  logmsg = (char *) d->logmsg;
8519  sqlst = d->sqlstate;
8520  naterr = d->naterr;
8521  break;
8522  case SQL_HANDLE_STMT:
8523  HSTMT_LOCK((SQLHSTMT) handle);
8524  s = (STMT *) handle;
8525  logmsg = (char *) s->logmsg;
8526  sqlst = s->sqlstate;
8527  naterr = s->naterr;
8528  break;
8529  default:
8530  return SQL_INVALID_HANDLE;
8531  }
8532  if (buflen < 0) {
8533  goto done;
8534  }
8535  if (recno > 1) {
8536  ret = SQL_NO_DATA;
8537  goto done;
8538  }
8539  len = strlen(logmsg);
8540  if (len == 0) {
8541  ret = SQL_NO_DATA;
8542  goto done;
8543  }
8544  if (nativeerr) {
8545  *nativeerr = naterr;
8546  }
8547  if (sqlstate) {
8548  strcpy((char *) sqlstate, sqlst);
8549  }
8550  if (msglen) {
8551  *msglen = len;
8552  }
8553  if (len >= buflen) {
8554  if (msg && buflen > 0) {
8555  strncpy((char *) msg, logmsg, buflen);
8556  msg[buflen - 1] = '\0';
8557  logmsg[0] = '\0';
8558  }
8559  } else if (msg) {
8560  strcpy((char *) msg, logmsg);
8561  logmsg[0] = '\0';
8562  }
8563  ret = SQL_SUCCESS;
8564 done:
8565  switch (htype) {
8566  case SQL_HANDLE_DBC:
8567  HDBC_UNLOCK((SQLHDBC) handle);
8568  break;
8569  case SQL_HANDLE_STMT:
8570  HSTMT_UNLOCK((SQLHSTMT) handle);
8571  break;
8572  }
8573  return ret;
8574 }
8575 
8576 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
8577 
8590 SQLRETURN SQL_API
8591 SQLGetDiagRec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8592  SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
8593  SQLSMALLINT buflen, SQLSMALLINT *msglen)
8594 {
8595  return drvgetdiagrec(htype, handle, recno, sqlstate,
8596  nativeerr, msg, buflen, msglen);
8597 }
8598 #endif
8599 
8600 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
8601 #ifdef WINTERFACE
8602 
8616 SQLRETURN SQL_API
8617 SQLGetDiagRecW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8618  SQLWCHAR *sqlstate, SQLINTEGER *nativeerr, SQLWCHAR *msg,
8619  SQLSMALLINT buflen, SQLSMALLINT *msglen)
8620 {
8621  char state[16];
8622  SQLSMALLINT len;
8623  SQLRETURN ret;
8624 
8625  ret = drvgetdiagrec(htype, handle, recno, (SQLCHAR *) state,
8626  nativeerr, (SQLCHAR *) msg, buflen, &len);
8627  if (ret == SQL_SUCCESS) {
8628  if (sqlstate) {
8629  uc_from_utf_buf((SQLCHAR *) state, -1, sqlstate,
8630  6 * sizeof (SQLWCHAR));
8631  }
8632  if (msg) {
8633  if (len > 0) {
8634  SQLWCHAR *m = NULL;
8635 
8636  m = uc_from_utf((unsigned char *) msg, len);
8637  if (m) {
8638  if (buflen) {
8639  buflen /= sizeof (SQLWCHAR);
8640  uc_strncpy(msg, m, buflen);
8641  m[len] = 0;
8642  len = min(buflen, uc_strlen(m));
8643  } else {
8644  len = uc_strlen(m);
8645  }
8646  uc_free(m);
8647  } else {
8648  len = 0;
8649  }
8650  }
8651  if (len <= 0) {
8652  len = 0;
8653  if (buflen > 0) {
8654  msg[0] = 0;
8655  }
8656  }
8657  } else {
8658  /* estimated length !!! */
8659  len *= sizeof (SQLWCHAR);
8660  }
8661  if (msglen) {
8662  *msglen = len;
8663  }
8664  } else if (ret == SQL_NO_DATA) {
8665  if (sqlstate) {
8666  sqlstate[0] = 0;
8667  }
8668  if (msg) {
8669  if (buflen > 0) {
8670  msg[0] = 0;
8671  }
8672  }
8673  if (msglen) {
8674  *msglen = 0;
8675  }
8676  }
8677  return ret;
8678 }
8679 #endif
8680 #endif
8681 
8694 static SQLRETURN
8695 drvgetdiagfield(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8696  SQLSMALLINT id, SQLPOINTER info,
8697  SQLSMALLINT buflen, SQLSMALLINT *stringlen)
8698 {
8699  DBC *d = NULL;
8700  STMT *s = NULL;
8701  int len, naterr, strbuf = 1;
8702  char *logmsg, *sqlst, *clrmsg = NULL;
8703  SQLRETURN ret = SQL_ERROR;
8704 
8705  if (handle == SQL_NULL_HANDLE) {
8706  return SQL_INVALID_HANDLE;
8707  }
8708  if (stringlen) {
8709  *stringlen = 0;
8710  }
8711  switch (htype) {
8712  case SQL_HANDLE_ENV:
8713  case SQL_HANDLE_DESC:
8714  return SQL_NO_DATA;
8715  case SQL_HANDLE_DBC:
8716  HDBC_LOCK((SQLHDBC) handle);
8717  d = (DBC *) handle;
8718  logmsg = (char *) d->logmsg;
8719  sqlst = d->sqlstate;
8720  naterr = d->naterr;
8721  break;
8722  case SQL_HANDLE_STMT:
8723  HSTMT_LOCK((SQLHSTMT) handle);
8724  s = (STMT *) handle;
8725  d = (DBC *) s->dbc;
8726  logmsg = (char *) s->logmsg;
8727  sqlst = s->sqlstate;
8728  naterr = s->naterr;
8729  break;
8730  default:
8731  return SQL_INVALID_HANDLE;
8732  }
8733  if (buflen < 0) {
8734  switch (buflen) {
8735  case SQL_IS_POINTER:
8736  case SQL_IS_UINTEGER:
8737  case SQL_IS_INTEGER:
8738  case SQL_IS_USMALLINT:
8739  case SQL_IS_SMALLINT:
8740  strbuf = 0;
8741  break;
8742  default:
8743  ret = SQL_ERROR;
8744  goto done;
8745  }
8746  }
8747  if (recno > 1) {
8748  ret = SQL_NO_DATA;
8749  goto done;
8750  }
8751  switch (id) {
8752  case SQL_DIAG_CLASS_ORIGIN:
8753  logmsg = "ISO 9075";
8754  if (sqlst[0] == 'I' && sqlst[1] == 'M') {
8755  logmsg = "ODBC 3.0";
8756  }
8757  break;
8758  case SQL_DIAG_SUBCLASS_ORIGIN:
8759  logmsg = "ISO 9075";
8760  if (sqlst[0] == 'I' && sqlst[1] == 'M') {
8761  logmsg = "ODBC 3.0";
8762  } else if (sqlst[0] == 'H' && sqlst[1] == 'Y') {
8763  logmsg = "ODBC 3.0";
8764  } else if (sqlst[0] == '2' || sqlst[0] == '0' || sqlst[0] == '4') {
8765  logmsg = "ODBC 3.0";
8766  }
8767  break;
8768  case SQL_DIAG_CONNECTION_NAME:
8769  case SQL_DIAG_SERVER_NAME:
8770  logmsg = d->dsn ? d->dsn : "No DSN";
8771  break;
8772  case SQL_DIAG_SQLSTATE:
8773  logmsg = sqlst;
8774  break;
8775  case SQL_DIAG_MESSAGE_TEXT:
8776  if (info) {
8777  clrmsg = logmsg;
8778  }
8779  break;
8780  case SQL_DIAG_NUMBER:
8781  naterr = 1;
8782  /* fall through */
8783  case SQL_DIAG_NATIVE:
8784  len = strlen(logmsg);
8785  if (len == 0) {
8786  ret = SQL_NO_DATA;
8787  goto done;
8788  }
8789  if (info) {
8790  *((SQLINTEGER *) info) = naterr;
8791  }
8792  ret = SQL_SUCCESS;
8793  goto done;
8794  case SQL_DIAG_DYNAMIC_FUNCTION:
8795  logmsg = "";
8796  break;
8797  case SQL_DIAG_CURSOR_ROW_COUNT:
8798  if (htype == SQL_HANDLE_STMT) {
8799  SQLULEN count;
8800 
8801  count = (s->isselect == 1 || s->isselect == -1) ? s->nrows : 0;
8802  *((SQLULEN *) info) = count;
8803  ret = SQL_SUCCESS;
8804  }
8805  goto done;
8806  case SQL_DIAG_ROW_COUNT:
8807  if (htype == SQL_HANDLE_STMT) {
8808  SQLULEN count;
8809 
8810  count = s->isselect ? 0 : s->nrows;
8811  *((SQLULEN *) info) = count;
8812  ret = SQL_SUCCESS;
8813  }
8814  goto done;
8815  default:
8816  goto done;
8817  }
8818  if (info && buflen > 0) {
8819  ((char *) info)[0] = '\0';
8820  }
8821  len = strlen(logmsg);
8822  if (len == 0) {
8823  ret = SQL_NO_DATA;
8824  goto done;
8825  }
8826  if (stringlen) {
8827  *stringlen = len;
8828  }
8829  if (strbuf) {
8830  if (len >= buflen) {
8831  if (info && buflen > 0) {
8832  if (stringlen) {
8833  *stringlen = buflen - 1;
8834  }
8835  strncpy((char *) info, logmsg, buflen);
8836  ((char *) info)[buflen - 1] = '\0';
8837  }
8838  } else if (info) {
8839  strcpy((char *) info, logmsg);
8840  }
8841  }
8842  if (clrmsg) {
8843  *clrmsg = '\0';
8844  }
8845  ret = SQL_SUCCESS;
8846 done:
8847  switch (htype) {
8848  case SQL_HANDLE_DBC:
8849  HDBC_UNLOCK((SQLHDBC) handle);
8850  break;
8851  case SQL_HANDLE_STMT:
8852  HSTMT_UNLOCK((SQLHSTMT) handle);
8853  break;
8854  }
8855  return ret;
8856 }
8857 
8858 #ifndef WINTERFACE
8859 
8871 SQLRETURN SQL_API
8872 SQLGetDiagField(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8873  SQLSMALLINT id, SQLPOINTER info,
8874  SQLSMALLINT buflen, SQLSMALLINT *stringlen)
8875 {
8876  return drvgetdiagfield(htype, handle, recno, id, info, buflen, stringlen);
8877 }
8878 #endif
8879 
8880 #ifdef WINTERFACE
8881 
8893 SQLRETURN SQL_API
8894 SQLGetDiagFieldW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8895  SQLSMALLINT id, SQLPOINTER info,
8896  SQLSMALLINT buflen, SQLSMALLINT *stringlen)
8897 {
8898  SQLSMALLINT len;
8899  SQLRETURN ret;
8900 
8901  ret = drvgetdiagfield(htype, handle, recno, id, info, buflen, &len);
8902  if (ret == SQL_SUCCESS) {
8903  if (info) {
8904  switch (id) {
8905  case SQL_DIAG_CLASS_ORIGIN:
8906  case SQL_DIAG_SUBCLASS_ORIGIN:
8907  case SQL_DIAG_CONNECTION_NAME:
8908  case SQL_DIAG_SERVER_NAME:
8909  case SQL_DIAG_SQLSTATE:
8910  case SQL_DIAG_MESSAGE_TEXT:
8911  case SQL_DIAG_DYNAMIC_FUNCTION:
8912  if (len > 0) {
8913  SQLWCHAR *m = NULL;
8914 
8915  m = uc_from_utf((unsigned char *) info, len);
8916  if (m) {
8917  if (buflen) {
8918  buflen /= sizeof (SQLWCHAR);
8919  uc_strncpy(info, m, buflen);
8920  m[len] = 0;
8921  len = min(buflen, uc_strlen(m));
8922  } else {
8923  len = uc_strlen(m);
8924  }
8925  uc_free(m);
8926  len *= sizeof (SQLWCHAR);
8927  } else {
8928  len = 0;
8929  }
8930  }
8931  if (len <= 0) {
8932  len = 0;
8933  if (buflen > 0) {
8934  ((SQLWCHAR *) info)[0] = 0;
8935  }
8936  }
8937  }
8938  } else {
8939  switch (id) {
8940  case SQL_DIAG_CLASS_ORIGIN:
8941  case SQL_DIAG_SUBCLASS_ORIGIN:
8942  case SQL_DIAG_CONNECTION_NAME:
8943  case SQL_DIAG_SERVER_NAME:
8944  case SQL_DIAG_SQLSTATE:
8945  case SQL_DIAG_MESSAGE_TEXT:
8946  case SQL_DIAG_DYNAMIC_FUNCTION:
8947  len *= sizeof (SQLWCHAR);
8948  break;
8949  }
8950  }
8951  if (stringlen) {
8952  *stringlen = len;
8953  }
8954  }
8955  return ret;
8956 }
8957 #endif
8958 
8969 static SQLRETURN
8970 drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
8971  SQLINTEGER bufmax, SQLINTEGER *buflen)
8972 {
8973  STMT *s = (STMT *) stmt;
8974  SQLULEN *uval = (SQLULEN *) val;
8975  SQLINTEGER dummy;
8976  char dummybuf[16];
8977 
8978  if (!buflen) {
8979  buflen = &dummy;
8980  }
8981  if (!uval) {
8982  uval = (SQLPOINTER) dummybuf;
8983  }
8984  switch (attr) {
8985  case SQL_QUERY_TIMEOUT:
8986  *uval = 0;
8987  *buflen = sizeof (SQLULEN);
8988  return SQL_SUCCESS;
8989  case SQL_ATTR_CURSOR_TYPE:
8990  *uval = s->curtype;
8991  *buflen = sizeof (SQLULEN);
8992  return SQL_SUCCESS;
8993  case SQL_ATTR_CURSOR_SCROLLABLE:
8994  *uval = (s->curtype != SQL_CURSOR_FORWARD_ONLY) ?
8995  SQL_SCROLLABLE : SQL_NONSCROLLABLE;
8996  *buflen = sizeof (SQLULEN);
8997  return SQL_SUCCESS;
8998 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
8999  case SQL_ATTR_CURSOR_SENSITIVITY:
9000  *uval = SQL_UNSPECIFIED;
9001  *buflen = sizeof (SQLULEN);
9002  return SQL_SUCCESS;
9003 #endif
9004  case SQL_ATTR_ROW_NUMBER:
9005  if (s->s3stmt) {
9006  *uval = (s->s3stmt_rownum < 0) ?
9007  SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
9008  } else {
9009  *uval = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
9010  }
9011  *buflen = sizeof (SQLULEN);
9012  return SQL_SUCCESS;
9013  case SQL_ATTR_ASYNC_ENABLE:
9014  *uval = SQL_ASYNC_ENABLE_OFF;
9015  *buflen = sizeof (SQLULEN);
9016  return SQL_SUCCESS;
9017  case SQL_CONCURRENCY:
9018  *uval = SQL_CONCUR_LOCK;
9019  *buflen = sizeof (SQLULEN);
9020  return SQL_SUCCESS;
9021  case SQL_ATTR_RETRIEVE_DATA:
9022  *uval = s->retr_data;
9023  *buflen = sizeof (SQLULEN);
9024  return SQL_SUCCESS;
9025  case SQL_ROWSET_SIZE:
9026  case SQL_ATTR_ROW_ARRAY_SIZE:
9027  *uval = s->rowset_size;
9028  *buflen = sizeof (SQLULEN);
9029  return SQL_SUCCESS;
9030  /* Needed for some driver managers, but dummies for now */
9031  case SQL_ATTR_IMP_ROW_DESC:
9032  case SQL_ATTR_APP_ROW_DESC:
9033  case SQL_ATTR_IMP_PARAM_DESC:
9034  case SQL_ATTR_APP_PARAM_DESC:
9035  *((SQLHDESC *) uval) = (SQLHDESC) DEAD_MAGIC;
9036  *buflen = sizeof (SQLHDESC);
9037  return SQL_SUCCESS;
9038  case SQL_ATTR_ROW_STATUS_PTR:
9039  *((SQLUSMALLINT **) uval) = s->row_status;
9040  *buflen = sizeof (SQLUSMALLINT *);
9041  return SQL_SUCCESS;
9042  case SQL_ATTR_ROWS_FETCHED_PTR:
9043  *((SQLULEN **) uval) = s->row_count;
9044  *buflen = sizeof (SQLULEN *);
9045  return SQL_SUCCESS;
9046  case SQL_ATTR_USE_BOOKMARKS: {
9047  STMT *s = (STMT *) stmt;
9048 
9049  *(SQLUINTEGER *) uval = s->bkmrk;
9050  *buflen = sizeof (SQLUINTEGER);
9051  return SQL_SUCCESS;
9052  }
9053  case SQL_ATTR_FETCH_BOOKMARK_PTR:
9054  *(SQLPOINTER *) uval = s->bkmrkptr;
9055  *buflen = sizeof (SQLPOINTER);
9056  return SQL_SUCCESS;
9057  case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
9058  *((SQLULEN **) uval) = s->parm_bind_offs;
9059  *buflen = sizeof (SQLULEN *);
9060  return SQL_SUCCESS;
9061  case SQL_ATTR_PARAM_BIND_TYPE:
9062  *((SQLULEN *) uval) = s->parm_bind_type;
9063  *buflen = sizeof (SQLULEN);
9064  return SQL_SUCCESS;
9065  case SQL_ATTR_PARAM_OPERATION_PTR:
9066  *((SQLUSMALLINT **) uval) = s->parm_oper;
9067  *buflen = sizeof (SQLUSMALLINT *);
9068  return SQL_SUCCESS;
9069  case SQL_ATTR_PARAM_STATUS_PTR:
9070  *((SQLUSMALLINT **) uval) = s->parm_status;
9071  *buflen = sizeof (SQLUSMALLINT *);
9072  return SQL_SUCCESS;
9073  case SQL_ATTR_PARAMS_PROCESSED_PTR:
9074  *((SQLULEN **) uval) = s->parm_proc;
9075  *buflen = sizeof (SQLULEN *);
9076  return SQL_SUCCESS;
9077  case SQL_ATTR_PARAMSET_SIZE:
9078  *((SQLULEN *) uval) = s->paramset_size;
9079  *buflen = sizeof (SQLULEN);
9080  return SQL_SUCCESS;
9081  case SQL_ATTR_ROW_BIND_TYPE:
9082  *(SQLULEN *) uval = s->bind_type;
9083  *buflen = sizeof (SQLULEN);
9084  return SQL_SUCCESS;
9085  case SQL_ATTR_ROW_BIND_OFFSET_PTR:
9086  *((SQLULEN **) uval) = s->bind_offs;
9087  *buflen = sizeof (SQLULEN *);
9088  return SQL_SUCCESS;
9089  case SQL_ATTR_MAX_ROWS:
9090  *((SQLULEN *) uval) = s->max_rows;
9091  *buflen = sizeof (SQLULEN);
9092  return SQL_SUCCESS;
9093  case SQL_ATTR_MAX_LENGTH:
9094  *((SQLULEN *) uval) = 1000000000;
9095  *buflen = sizeof (SQLULEN);
9096  return SQL_SUCCESS;
9097 #ifdef SQL_ATTR_METADATA_ID
9098  case SQL_ATTR_METADATA_ID:
9099  *((SQLULEN *) uval) = SQL_FALSE;
9100  *buflen = sizeof (SQLULEN);
9101  return SQL_SUCCESS;
9102 #endif
9103  }
9104  return drvunimplstmt(stmt);
9105 }
9106 
9107 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
9108 
9118 SQLRETURN SQL_API
9119 SQLGetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9120  SQLINTEGER bufmax, SQLINTEGER *buflen)
9121 {
9122  SQLRETURN ret;
9123 
9124  HSTMT_LOCK(stmt);
9125  ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
9126  HSTMT_UNLOCK(stmt);
9127  return ret;
9128 }
9129 #endif
9130 
9131 #ifdef WINTERFACE
9132 
9142 SQLRETURN SQL_API
9143 SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9144  SQLINTEGER bufmax, SQLINTEGER *buflen)
9145 {
9146  SQLRETURN ret;
9147 
9148  HSTMT_LOCK(stmt);
9149  ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
9150  HSTMT_UNLOCK(stmt);
9151  return ret;
9152 }
9153 #endif
9154 
9164 static SQLRETURN
9165 drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9166  SQLINTEGER buflen)
9167 {
9168  STMT *s = (STMT *) stmt;
9169 #if defined(SQL_BIGINT) && defined(__WORDSIZE) && (__WORDSIZE == 64)
9170  SQLBIGINT uval;
9171 
9172  uval = (SQLBIGINT) val;
9173 #else
9174  SQLULEN uval;
9175 
9176  uval = (SQLULEN) val;
9177 #endif
9178  switch (attr) {
9179  case SQL_ATTR_CURSOR_TYPE:
9180  if (val == (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY) {
9181  s->curtype = SQL_CURSOR_FORWARD_ONLY;
9182  } else {
9183  s->curtype = SQL_CURSOR_STATIC;
9184  }
9185  if (val != (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY &&
9186  val != (SQLPOINTER) SQL_CURSOR_STATIC) {
9187  goto e01s02;
9188  }
9189  return SQL_SUCCESS;
9190  case SQL_ATTR_CURSOR_SCROLLABLE:
9191  if (val == (SQLPOINTER) SQL_NONSCROLLABLE) {
9192  s->curtype = SQL_CURSOR_FORWARD_ONLY;
9193  } else {
9194  s->curtype = SQL_CURSOR_STATIC;
9195  }
9196  return SQL_SUCCESS;
9197  case SQL_ATTR_ASYNC_ENABLE:
9198  if (val != (SQLPOINTER) SQL_ASYNC_ENABLE_OFF) {
9199  e01s02:
9200  setstat(s, -1, "option value changed", "01S02");
9201  return SQL_SUCCESS_WITH_INFO;
9202  }
9203  return SQL_SUCCESS;
9204  case SQL_CONCURRENCY:
9205  if (val != (SQLPOINTER) SQL_CONCUR_LOCK) {
9206  goto e01s02;
9207  }
9208  return SQL_SUCCESS;
9209 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
9210  case SQL_ATTR_CURSOR_SENSITIVITY:
9211  if (val != (SQLPOINTER) SQL_UNSPECIFIED) {
9212  goto e01s02;
9213  }
9214  return SQL_SUCCESS;
9215 #endif
9216  case SQL_ATTR_QUERY_TIMEOUT:
9217  return SQL_SUCCESS;
9218  case SQL_ATTR_RETRIEVE_DATA:
9219  if (val != (SQLPOINTER) SQL_RD_ON &&
9220  val != (SQLPOINTER) SQL_RD_OFF) {
9221  goto e01s02;
9222  }
9223  s->retr_data = uval;
9224  return SQL_SUCCESS;
9225  case SQL_ROWSET_SIZE:
9226  case SQL_ATTR_ROW_ARRAY_SIZE:
9227  if (uval < 1) {
9228  setstat(s, -1, "invalid rowset size", "HY000");
9229  return SQL_ERROR;
9230  } else {
9231  SQLUSMALLINT *rst = &s->row_status1;
9232 
9233  if (uval > 1) {
9234  rst = xmalloc(sizeof (SQLUSMALLINT) * uval);
9235  if (!rst) {
9236  return nomem(s);
9237  }
9238  }
9239  if (s->row_status0 != &s->row_status1) {
9240  freep(&s->row_status0);
9241  }
9242  s->row_status0 = rst;
9243  s->rowset_size = uval;
9244  }
9245  return SQL_SUCCESS;
9246  case SQL_ATTR_ROW_STATUS_PTR:
9247  s->row_status = (SQLUSMALLINT *) val;
9248  return SQL_SUCCESS;
9249  case SQL_ATTR_ROWS_FETCHED_PTR:
9250  s->row_count = (SQLULEN *) val;
9251  return SQL_SUCCESS;
9252  case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
9253  s->parm_bind_offs = (SQLULEN *) val;
9254  return SQL_SUCCESS;
9255  case SQL_ATTR_PARAM_BIND_TYPE:
9256  s->parm_bind_type = uval;
9257  return SQL_SUCCESS;
9258  case SQL_ATTR_PARAM_OPERATION_PTR:
9259  s->parm_oper = (SQLUSMALLINT *) val;
9260  return SQL_SUCCESS;
9261  case SQL_ATTR_PARAM_STATUS_PTR:
9262  s->parm_status = (SQLUSMALLINT *) val;
9263  return SQL_SUCCESS;
9264  case SQL_ATTR_PARAMS_PROCESSED_PTR:
9265  s->parm_proc = (SQLULEN *) val;
9266  return SQL_SUCCESS;
9267  case SQL_ATTR_PARAMSET_SIZE:
9268  if (uval < 1) {
9269  goto e01s02;
9270  }
9271  s->paramset_size = uval;
9272  s->paramset_count = 0;
9273  return SQL_SUCCESS;
9274  case SQL_ATTR_ROW_BIND_TYPE:
9275  s->bind_type = uval;
9276  return SQL_SUCCESS;
9277  case SQL_ATTR_ROW_BIND_OFFSET_PTR:
9278  s->bind_offs = (SQLULEN *) val;
9279  return SQL_SUCCESS;
9280  case SQL_ATTR_USE_BOOKMARKS:
9281  if (val != (SQLPOINTER) SQL_UB_OFF &&
9282  val != (SQLPOINTER) SQL_UB_ON &&
9283  val != (SQLPOINTER) SQL_UB_VARIABLE) {
9284  goto e01s02;
9285  }
9286  if (*s->ov3 && val == (SQLPOINTER) SQL_UB_VARIABLE) {
9287  s->bkmrk = SQL_UB_VARIABLE;
9288  return SQL_SUCCESS;
9289  }
9290  if (val == (SQLPOINTER) SQL_UB_VARIABLE) {
9291  s->bkmrk = SQL_UB_ON;
9292  goto e01s02;
9293  }
9294  s->bkmrk = (val == (SQLPOINTER) SQL_UB_ON) ? SQL_UB_ON : SQL_UB_OFF;
9295  return SQL_SUCCESS;
9296  case SQL_ATTR_FETCH_BOOKMARK_PTR:
9297  s->bkmrkptr = (SQLINTEGER *) val;
9298  return SQL_SUCCESS;
9299  case SQL_ATTR_MAX_ROWS:
9300  s->max_rows = uval;
9301  return SQL_SUCCESS;
9302  case SQL_ATTR_MAX_LENGTH:
9303  if (val != (SQLPOINTER) 1000000000) {
9304  goto e01s02;
9305  }
9306  return SQL_SUCCESS;
9307 #ifdef SQL_ATTR_METADATA_ID
9308  case SQL_ATTR_METADATA_ID:
9309  if (val != (SQLPOINTER) SQL_FALSE) {
9310  goto e01s02;
9311  }
9312  return SQL_SUCCESS;
9313 #endif
9314  }
9315  return drvunimplstmt(stmt);
9316 }
9317 
9318 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
9319 
9328 SQLRETURN SQL_API
9329 SQLSetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9330  SQLINTEGER buflen)
9331 {
9332  SQLRETURN ret;
9333 
9334  HSTMT_LOCK(stmt);
9335  ret = drvsetstmtattr(stmt, attr, val, buflen);
9336  HSTMT_UNLOCK(stmt);
9337  return ret;
9338 }
9339 #endif
9340 
9341 #ifdef WINTERFACE
9342 
9351 SQLRETURN SQL_API
9352 SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9353  SQLINTEGER buflen)
9354 {
9355  SQLRETURN ret;
9356 
9357  HSTMT_LOCK(stmt);
9358  ret = drvsetstmtattr(stmt, attr, val, buflen);
9359  HSTMT_UNLOCK(stmt);
9360  return ret;
9361 }
9362 #endif
9363 
9372 static SQLRETURN
9373 drvgetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9374 {
9375  STMT *s = (STMT *) stmt;
9376  SQLUINTEGER *ret = (SQLUINTEGER *) param;
9377 
9378  switch (opt) {
9379  case SQL_QUERY_TIMEOUT:
9380  *ret = 0;
9381  return SQL_SUCCESS;
9382  case SQL_CURSOR_TYPE:
9383  *ret = s->curtype;
9384  return SQL_SUCCESS;
9385  case SQL_ROW_NUMBER:
9386  if (s->s3stmt) {
9387  *ret = (s->s3stmt_rownum < 0) ?
9388  SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
9389  } else {
9390  *ret = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
9391  }
9392  return SQL_SUCCESS;
9393  case SQL_ASYNC_ENABLE:
9394  *ret = SQL_ASYNC_ENABLE_OFF;
9395  return SQL_SUCCESS;
9396  case SQL_CONCURRENCY:
9397  *ret = SQL_CONCUR_LOCK;
9398  return SQL_SUCCESS;
9399  case SQL_ATTR_RETRIEVE_DATA:
9400  *ret = s->retr_data;
9401  return SQL_SUCCESS;
9402  case SQL_ROWSET_SIZE:
9403  case SQL_ATTR_ROW_ARRAY_SIZE:
9404  *ret = s->rowset_size;
9405  return SQL_SUCCESS;
9406  case SQL_ATTR_MAX_ROWS:
9407  *ret = s->max_rows;
9408  return SQL_SUCCESS;
9409  case SQL_ATTR_MAX_LENGTH:
9410  *ret = 1000000000;
9411  return SQL_SUCCESS;
9412  }
9413  return drvunimplstmt(stmt);
9414 }
9415 
9424 SQLRETURN SQL_API
9425 SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9426 {
9427  SQLRETURN ret;
9428 
9429  HSTMT_LOCK(stmt);
9430  ret = drvgetstmtoption(stmt, opt, param);
9431  HSTMT_UNLOCK(stmt);
9432  return ret;
9433 }
9434 
9435 #ifdef WINTERFACE
9436 
9444 SQLRETURN SQL_API
9445 SQLGetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9446 {
9447  SQLRETURN ret;
9448 
9449  HSTMT_LOCK(stmt);
9450  ret = drvgetstmtoption(stmt, opt, param);
9451  HSTMT_UNLOCK(stmt);
9452  return ret;
9453 }
9454 #endif
9455 
9464 static SQLRETURN
9465 drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
9466 {
9467  STMT *s = (STMT *) stmt;
9468 
9469  switch (opt) {
9470  case SQL_CURSOR_TYPE:
9471  if (param == SQL_CURSOR_FORWARD_ONLY) {
9472  s->curtype = param;
9473  } else {
9474  s->curtype = SQL_CURSOR_STATIC;
9475  }
9476  if (param != SQL_CURSOR_FORWARD_ONLY &&
9477  param != SQL_CURSOR_STATIC) {
9478  goto e01s02;
9479  }
9480  return SQL_SUCCESS;
9481  case SQL_ASYNC_ENABLE:
9482  if (param != SQL_ASYNC_ENABLE_OFF) {
9483  goto e01s02;
9484  }
9485  return SQL_SUCCESS;
9486  case SQL_CONCURRENCY:
9487  if (param != SQL_CONCUR_LOCK) {
9488  goto e01s02;
9489  }
9490  return SQL_SUCCESS;
9491  case SQL_QUERY_TIMEOUT:
9492  return SQL_SUCCESS;
9493  case SQL_RETRIEVE_DATA:
9494  if (param != SQL_RD_ON && param != SQL_RD_OFF) {
9495  e01s02:
9496  setstat(s, -1, "option value changed", "01S02");
9497  return SQL_SUCCESS_WITH_INFO;
9498  }
9499  s->retr_data = (int) param;
9500  return SQL_SUCCESS;
9501  case SQL_ROWSET_SIZE:
9502  case SQL_ATTR_ROW_ARRAY_SIZE:
9503  if (param < 1) {
9504  setstat(s, -1, "invalid rowset size", "HY000");
9505  return SQL_ERROR;
9506  } else {
9507  SQLUSMALLINT *rst = &s->row_status1;
9508 
9509  if (param > 1) {
9510  rst = xmalloc(sizeof (SQLUSMALLINT) * param);
9511  if (!rst) {
9512  return nomem(s);
9513  }
9514  }
9515  if (s->row_status0 != &s->row_status1) {
9516  freep(&s->row_status0);
9517  }
9518  s->row_status0 = rst;
9519  s->rowset_size = param;
9520  }
9521  return SQL_SUCCESS;
9522  case SQL_ATTR_MAX_ROWS:
9523  s->max_rows = param;
9524  return SQL_SUCCESS;
9525  case SQL_ATTR_MAX_LENGTH:
9526  if (param != 1000000000) {
9527  goto e01s02;
9528  }
9529  return SQL_SUCCESS;
9530  }
9531  return drvunimplstmt(stmt);
9532 }
9533 
9542 SQLRETURN SQL_API
9543 SQLSetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt,
9545 {
9546  SQLRETURN ret;
9547 
9548  HSTMT_LOCK(stmt);
9549  ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
9550  HSTMT_UNLOCK(stmt);
9551  return ret;
9552 }
9553 
9554 #ifdef WINTERFACE
9555 
9563 SQLRETURN SQL_API
9564 SQLSetStmtOptionW(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 #endif
9575 
9582 static SQLRETURN
9584 {
9585  int i;
9586 
9587  if (!s->bindcols || s->nbindcols < s->ncols) {
9588 unbound:
9589  setstat(s, -1, "unbound columns", (*s->ov3) ? "HY000" : "S1000");
9590  return SQL_ERROR;
9591  }
9592  for (i = 0; i < s->ncols; i++) {
9593  BINDCOL *b = &s->bindcols[i];
9594 
9595  if (b->type == SQL_UNKNOWN_TYPE || !b->valp) {
9596  goto unbound;
9597  }
9598  }
9599  return SQL_SUCCESS;
9600 }
9601 
9613 static SQLRETURN
9614 setposbind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
9615 {
9616  DBC *d = (DBC *) s->dbc;
9617  SQLPOINTER dp = 0;
9618  SQLLEN *lp = 0;
9619  BINDCOL *b = &s->bindcols[i];
9620  COL *c = &s->cols[i];
9621  char strbuf[128], *cp;
9622 
9623  if (b->valp) {
9624  if (s->bind_type != SQL_BIND_BY_COLUMN) {
9625  dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
9626  } else {
9627  dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
9628  }
9629  if (s->bind_offs) {
9630  dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
9631  }
9632  }
9633  if (b->lenp) {
9634  if (s->bind_type != SQL_BIND_BY_COLUMN) {
9635  lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
9636  } else {
9637  lp = b->lenp + rsi;
9638  }
9639  if (s->bind_offs) {
9640  lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
9641  }
9642  }
9643  if (!dp || !lp) {
9644  setstat(s, -1, "unbound column in positional update",
9645  (*s->ov3) ? "HY000" : "S1000");
9646  return SQL_ERROR;
9647  }
9648  if (*lp == SQL_NULL_DATA) {
9649  sqlite3_bind_null(stmt, si);
9650  if (d->trace) {
9651  fprintf(d->trace, "-- parameter %d: NULL\n", si);
9652  fflush(d->trace);
9653  }
9654  return SQL_SUCCESS;
9655  }
9656  switch (b->type) {
9657  case SQL_C_UTINYINT:
9658  case SQL_C_TINYINT:
9659  case SQL_C_STINYINT:
9660  sqlite3_bind_int(stmt, si, *(SQLCHAR *) dp);
9661  if (d->trace) {
9662  fprintf(d->trace, "-- parameter %d: %d\n", si, *(SQLCHAR *) dp);
9663  fflush(d->trace);
9664  }
9665  break;
9666 #ifdef SQL_BIT
9667  case SQL_C_BIT:
9668  sqlite3_bind_int(stmt, si, (*(SQLCHAR *) dp) ? 1 : 0);
9669  if (d->trace) {
9670  fprintf(d->trace, "-- parameter %d: %d\n", si,
9671  (*(SQLCHAR *) dp) ? 1 : 0);
9672  fflush(d->trace);
9673  }
9674  break;
9675 #endif
9676  case SQL_C_USHORT:
9677  sqlite3_bind_int(stmt, si, *(SQLUSMALLINT *) dp);
9678  if (d->trace) {
9679  fprintf(d->trace, "-- parameter %d: %d\n", si,
9680  *(SQLUSMALLINT *) dp);
9681  fflush(d->trace);
9682  }
9683  break;
9684  case SQL_C_SHORT:
9685  case SQL_C_SSHORT:
9686  sqlite3_bind_int(stmt, si, *(SQLSMALLINT *) dp);
9687  if (d->trace) {
9688  fprintf(d->trace, "-- parameter %d: %d\n", si,
9689  *(SQLSMALLINT *) dp);
9690  fflush(d->trace);
9691  }
9692  break;
9693  case SQL_C_ULONG:
9694  sqlite3_bind_int(stmt, si, *(SQLUINTEGER *) dp);
9695  if (d->trace) {
9696  fprintf(d->trace, "-- parameter %d: %ld\n", si,
9697  (long) *(SQLUINTEGER *) dp);
9698  fflush(d->trace);
9699  }
9700  break;
9701  case SQL_C_LONG:
9702  case SQL_C_SLONG:
9703  sqlite3_bind_int(stmt, si, *(SQLINTEGER *) dp);
9704  if (d->trace) {
9705  fprintf(d->trace, "-- parameter %d: %ld\n", si,
9706  (long) *(SQLINTEGER *) dp);
9707  fflush(d->trace);
9708  }
9709  break;
9710 #ifdef SQL_BIGINT
9711  case SQL_C_UBIGINT:
9712  case SQL_C_SBIGINT:
9713  sqlite3_bind_int64(stmt, si, *(SQLBIGINT *) dp);
9714  if (d->trace) {
9715  fprintf(d->trace,
9716 #ifdef _WIN32
9717  "-- parameter %d: %I64d\n",
9718 #else
9719  "-- parameter %d: %lld\n",
9720 #endif
9721  si, (sqlite_int64) *(SQLBIGINT *) dp);
9722  fflush(d->trace);
9723  }
9724  break;
9725 #endif
9726  case SQL_C_FLOAT:
9727  sqlite3_bind_double(stmt, si, *(float *) dp);
9728  if (d->trace) {
9729  fprintf(d->trace, "-- parameter %d: %g\n", si,
9730  *(float *) dp);
9731  fflush(d->trace);
9732  }
9733  break;
9734  case SQL_C_DOUBLE:
9735  sqlite3_bind_double(stmt, si, *(double *) dp);
9736  if (d->trace) {
9737  fprintf(d->trace, "-- parameter %d: %g\n", si,
9738  *(double *) dp);
9739  fflush(d->trace);
9740  }
9741  break;
9742  case SQL_C_BINARY:
9743  sqlite3_bind_blob(stmt, si, (char *) dp, *lp, SQLITE_STATIC);
9744  if (d->trace) {
9745  fprintf(d->trace, "-- parameter %d: [BLOB]\n", si);
9746  fflush(d->trace);
9747  }
9748  break;
9749 #ifdef WCHARSUPPORT
9750  case SQL_C_WCHAR:
9751  cp = uc_to_utf((SQLWCHAR *) dp, *lp);
9752  if (!cp) {
9753  return nomem(s);
9754  }
9755  sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
9756  if (d->trace) {
9757  fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
9758  fflush(d->trace);
9759  }
9760  uc_free(cp);
9761  break;
9762 #endif
9763  case SQL_C_CHAR:
9764 #if defined(_WIN32) || defined(_WIN64)
9765  if (*s->oemcp) {
9766  cp = wmb_to_utf((char *) dp, *lp);
9767  if (!cp) {
9768  return nomem(s);
9769  }
9770  sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
9771  if (d->trace) {
9772  fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
9773  fflush(d->trace);
9774  }
9775  uc_free(cp);
9776  } else
9777 #endif
9778  {
9779  if (*lp == SQL_NTS) {
9780  sqlite3_bind_text(stmt, si, (char *) dp, -1,
9781  SQLITE_STATIC);
9782  if (d->trace) {
9783  fprintf(d->trace, "-- parameter %d: '%s'\n", si,
9784  (char *) dp);
9785  fflush(d->trace);
9786  }
9787  } else {
9788  sqlite3_bind_text(stmt, si, (char *) dp, *lp,
9789  SQLITE_STATIC);
9790  if (d->trace) {
9791  fprintf(d->trace, "-- parameter %d: '%*s'\n", si,
9792  (int) *lp, (char *) dp);
9793  fflush(d->trace);
9794  }
9795  }
9796  }
9797  break;
9798 #ifdef SQL_C_TYPE_DATE
9799  case SQL_C_TYPE_DATE:
9800 #endif
9801  case SQL_C_DATE:
9802  if (*s->jdconv) {
9803  int a, b, x1, x2, y, m, dd;
9804  double v;
9805 
9806  y = ((DATE_STRUCT *) dp)->year;
9807  m = ((DATE_STRUCT *) dp)->month;
9808  dd = ((DATE_STRUCT *) dp)->day;
9809  if (m <= 2) {
9810  y--;
9811  m += 12;
9812  }
9813  a = y / 100;
9814  b = 2 - a + (a / 4);
9815  x1 = 36525 * (y + 4716) / 100;
9816  x2 = 306001 * (m + 1) / 10000;
9817  v = x1 + x2 + dd + b - 1524.5;
9818  sqlite3_bind_double(stmt, si, v);
9819  if (d->trace) {
9820  fprintf(d->trace, "-- parameter %d: %g\n", si, v);
9821  fflush(d->trace);
9822  }
9823  } else {
9824  sprintf(strbuf, "%04d-%02d-%02d",
9825  ((DATE_STRUCT *) dp)->year,
9826  ((DATE_STRUCT *) dp)->month,
9827  ((DATE_STRUCT *) dp)->day);
9828  sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
9829  if (d->trace) {
9830  fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
9831  fflush(d->trace);
9832  }
9833  }
9834  break;
9835 #ifdef SQL_C_TYPE_TIME
9836  case SQL_C_TYPE_TIME:
9837 #endif
9838  case SQL_C_TIME:
9839  if (*s->jdconv) {
9840  double v;
9841 
9842  v = 2451544.5 +
9843  (((TIME_STRUCT *) dp)->hour * 3600000.0 +
9844  ((TIME_STRUCT *) dp)->minute * 60000.0 +
9845  ((TIME_STRUCT *) dp)->second * 1000.0) / 86400000.0;
9846  sqlite3_bind_double(stmt, si, v);
9847  if (d->trace) {
9848  fprintf(d->trace, "-- parameter %d: %g\n", si, v);
9849  fflush(d->trace);
9850  }
9851  } else {
9852  sprintf(strbuf, "%02d:%02d:%02d",
9853  ((TIME_STRUCT *) dp)->hour,
9854  ((TIME_STRUCT *) dp)->minute,
9855  ((TIME_STRUCT *) dp)->second);
9856  sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
9857  if (d->trace) {
9858  fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
9859  fflush(d->trace);
9860  }
9861  }
9862  break;
9863 #ifdef SQL_C_TYPE_TIMESTAMP
9864  case SQL_C_TYPE_TIMESTAMP:
9865 #endif
9866  case SQL_C_TIMESTAMP:
9867  if (*s->jdconv) {
9868  int a, b, x1, x2, y, m, dd;
9869  double v;
9870 
9871  y = ((TIMESTAMP_STRUCT *) dp)->year;
9872  m = ((TIMESTAMP_STRUCT *) dp)->month;
9873  dd = ((TIMESTAMP_STRUCT *) dp)->day;
9874  if (m <= 2) {
9875  y--;
9876  m += 12;
9877  }
9878  a = y / 100;
9879  b = 2 - a + (a / 4);
9880  x1 = 36525 * (y + 4716) / 100;
9881  x2 = 306001 * (m + 1) / 10000;
9882  v = x1 + x2 + dd + b - 1524.5 +
9883  (((TIMESTAMP_STRUCT *) dp)->hour * 3600000.0 +
9884  ((TIMESTAMP_STRUCT *) dp)->minute * 60000.0 +
9885  ((TIMESTAMP_STRUCT *) dp)->second * 1000.0 +
9886  ((TIMESTAMP_STRUCT *) dp)->fraction / 1.0E6)
9887  / 86400000.0;
9888  sqlite3_bind_double(stmt, si, v);
9889  if (d->trace) {
9890  fprintf(d->trace, "-- parameter %d: %g\n", si, v);
9891  fflush(d->trace);
9892  }
9893  } else {
9894  int frac;
9895 
9896  frac = (int) ((TIMESTAMP_STRUCT *) dp)->fraction;
9897  frac /= 1000000;
9898  frac = frac % 1000;
9899  if (frac < 0) {
9900  frac = 0;
9901  }
9902  if (c->prec && c->prec <= 16) {
9903  sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
9904  ((TIMESTAMP_STRUCT *) dp)->year,
9905  ((TIMESTAMP_STRUCT *) dp)->month,
9906  ((TIMESTAMP_STRUCT *) dp)->day,
9907  ((TIMESTAMP_STRUCT *) dp)->hour,
9908  ((TIMESTAMP_STRUCT *) dp)->minute);
9909  } else if (c->prec && c->prec <= 19) {
9910  sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
9911  ((TIMESTAMP_STRUCT *) dp)->year,
9912  ((TIMESTAMP_STRUCT *) dp)->month,
9913  ((TIMESTAMP_STRUCT *) dp)->day,
9914  ((TIMESTAMP_STRUCT *) dp)->hour,
9915  ((TIMESTAMP_STRUCT *) dp)->minute,
9916  ((TIMESTAMP_STRUCT *) dp)->second);
9917  } else {
9918  sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
9919  ((TIMESTAMP_STRUCT *) dp)->year,
9920  ((TIMESTAMP_STRUCT *) dp)->month,
9921  ((TIMESTAMP_STRUCT *) dp)->day,
9922  ((TIMESTAMP_STRUCT *) dp)->hour,
9923  ((TIMESTAMP_STRUCT *) dp)->minute,
9924  ((TIMESTAMP_STRUCT *) dp)->second,
9925  frac);
9926  }
9927  sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
9928  if (d->trace) {
9929  fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
9930  fflush(d->trace);
9931  }
9932  }
9933  break;
9934  default:
9935  setstat(s, -1, "unsupported column type in positional update",
9936  (*s->ov3) ? "HY000" : "S1000");
9937  return SQL_ERROR;
9938  }
9939  return SQL_SUCCESS;
9940 }
9941 
9953 static SQLRETURN
9954 setposibind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
9955 {
9956  DBC *d = (DBC *) s->dbc;
9957  char **data;
9958  int pos;
9959 
9960  pos = s->rowprs;
9961  if (pos < 0) {
9962  setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
9963  return SQL_ERROR;
9964  }
9965  pos += rsi;
9966  data = s->rows + s->ncols + (pos * s->ncols) + i;
9967  if (*data == NULL) {
9968  sqlite3_bind_null(stmt, si);
9969  if (d->trace) {
9970  fprintf(d->trace, "-- parameter %d: NULL\n", si);
9971  fflush(d->trace);
9972  }
9973  } else {
9974  sqlite3_bind_text(stmt, si, *data, -1, SQLITE_STATIC);
9975  if (d->trace) {
9976  fprintf(d->trace, "-- parameter %d: '%s'\n", si, *data);
9977  fflush(d->trace);
9978  }
9979  }
9980  return SQL_SUCCESS;
9981 }
9982 
9990 static SQLRETURN
9991 setposrefr(STMT *s, int rsi)
9992 {
9993  int i, withinfo = 0;
9994  SQLRETURN ret = SQL_SUCCESS;
9995 
9996  for (i = 0; s->bindcols && i < s->ncols; i++) {
9997  BINDCOL *b = &s->bindcols[i];
9998  SQLPOINTER dp = 0;
9999  SQLLEN *lp = 0;
10000 
10001  b->offs = 0;
10002  if (b->valp) {
10003  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10004  dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
10005  } else {
10006  dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
10007  }
10008  if (s->bind_offs) {
10009  dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
10010  }
10011  }
10012  if (b->lenp) {
10013  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10014  lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
10015  } else {
10016  lp = b->lenp + rsi;
10017  }
10018  if (s->bind_offs) {
10019  lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
10020  }
10021  }
10022  if (dp || lp) {
10023  int rowp = s->rowp;
10024 
10025  s->rowp = s->rowprs + rsi;
10026  ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp,
10027  b->max, lp, 0);
10028  s->rowp = rowp;
10029  if (!SQL_SUCCEEDED(ret)) {
10030  s->row_status0[rsi] = SQL_ROW_ERROR;
10031  break;
10032  }
10033  if (ret != SQL_SUCCESS) {
10034  withinfo = 1;
10035 #ifdef SQL_ROW_SUCCESS_WITH_INFO
10036  s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
10037 #endif
10038  }
10039  }
10040  }
10041  if (SQL_SUCCEEDED(ret)) {
10042  ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
10043  }
10044  return ret;
10045 }
10046 
10056 static SQLRETURN
10057 drvsetpos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10058 {
10059  STMT *s = (STMT *) stmt;
10060  DBC *d = (DBC *) s->dbc;
10061  int rowp, i, k, rc, nretry = 0;
10062  dstr *sql = 0;
10063  const char *endp;
10064  sqlite3_stmt *s3stmt = NULL;
10065  SQLRETURN ret;
10066 
10067  if (lock != SQL_LOCK_NO_CHANGE) {
10068  setstat(s, -1, "unsupported locking mode",
10069  (*s->ov3) ? "HY000" : "S1000");
10070  return SQL_ERROR;
10071  }
10072  if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10073  setstat(s, -1, "incompatible statement",
10074  (*s->ov3) ? "HY000" : "S1000");
10075  return SQL_ERROR;
10076  }
10077  if (op == SQL_ADD) {
10078  if (s->one_tbl <= 0) {
10079  setstat(s, -1, "incompatible rowset",
10080  (*s->ov3) ? "HY000" : "S1000");
10081  return SQL_ERROR;
10082  }
10083  if (row == 0 || row > s->rowset_size + 1) {
10084  goto rowoor;
10085  }
10086  ret = chkunbound(s);
10087  if (ret != SQL_SUCCESS) {
10088  return ret;
10089  }
10090  sql = dsappend(sql, "INSERT INTO ");
10091  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10092  sql = dsappendq(sql, s->dyncols[0].db);
10093  sql = dsappend(sql, ".");
10094  }
10095  sql = dsappendq(sql, s->dyncols[0].table);
10096  for (i = 0; i < s->ncols; i++) {
10097  sql = dsappend(sql, (i > 0) ? "," : "(");
10098  sql = dsappendq(sql, s->dyncols[i].column);
10099  }
10100  sql = dsappend(sql, ") VALUES ");
10101  for (i = 0; i < s->ncols; i++) {
10102  sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10103  }
10104  sql = dsappend(sql, ")");
10105  if (dserr(sql)) {
10106  dsfree(sql);
10107  return nomem(s);
10108  }
10109 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10110  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10111 #else
10112  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10113 #endif
10114  do {
10115  s3stmt = NULL;
10116 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10117  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10118  &s3stmt, &endp);
10119 #else
10120  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10121  &s3stmt, &endp);
10122 #endif
10123  if (rc != SQLITE_OK) {
10124  if (s3stmt) {
10125  sqlite3_finalize(s3stmt);
10126  s3stmt = NULL;
10127  }
10128  }
10129  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10130  dbtracerc(d, rc, NULL);
10131  dsfree(sql);
10132  if (rc != SQLITE_OK) {
10133 istmterr:
10134  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10135  sqlite3_errmsg(d->sqlite), rc);
10136  if (s3stmt) {
10137  dbtraceapi(d, "sqlite3_finalize", NULL);
10138  sqlite3_finalize(s3stmt);
10139  }
10140  return SQL_ERROR;
10141  }
10142  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10143  ret = setposbind(s, s3stmt, i, k, row - 1);
10144  if (ret != SQL_SUCCESS) {
10145  dbtraceapi(d, "sqlite3_finalize", NULL);
10146  sqlite3_finalize(s3stmt);
10147  return ret;
10148  }
10149  k++;
10150  }
10151  rc = sqlite3_step(s3stmt);
10152  if (rc != SQLITE_DONE) {
10153  goto istmterr;
10154  }
10155  sqlite3_finalize(s3stmt);
10156  if (sqlite3_changes(d->sqlite) > 0 && row <= s->rowset_size) {
10157  if (s->row_status0) {
10158  s->row_status0[row - 1] = SQL_ROW_ADDED;
10159  }
10160  if (s->row_status) {
10161  s->row_status[row - 1] = SQL_ROW_ADDED;
10162  }
10163  }
10164  return SQL_SUCCESS;
10165  } else if (op == SQL_UPDATE || op == SQL_DELETE) {
10166  if (s->one_tbl <= 0 || s->has_pk <= 0) {
10167  setstat(s, -1, "incompatible rowset",
10168  (*s->ov3) ? "HY000" : "S1000");
10169  return SQL_ERROR;
10170  }
10171  if (row == 0) {
10172  ret = SQL_SUCCESS;
10173  for (i = 1; i <= s->rowset_size; i++) {
10174  ret = drvsetpos(stmt, i, op, lock);
10175  if (!SQL_SUCCEEDED(ret)) {
10176  break;
10177  }
10178  }
10179  return ret;
10180  }
10181  if (row > s->rowset_size) {
10182  goto rowoor;
10183  }
10184  }
10185  if (op != SQL_POSITION && op != SQL_REFRESH &&
10186  op != SQL_DELETE && op != SQL_UPDATE) {
10187  return drvunimplstmt(stmt);
10188  }
10189  if (op == SQL_POSITION) {
10190  rowp = s->rowp + row - 1;
10191  if (!s->rows || row == 0 || rowp < -1 || rowp >= s->nrows) {
10192 rowoor:
10193  setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
10194  return SQL_ERROR;
10195  }
10196  s->rowp = rowp;
10197  } else if (op == SQL_REFRESH) {
10198  if (row > s->rowset_size) {
10199  goto rowoor;
10200  }
10201  if (row == 0) {
10202  ret = SQL_SUCCESS;
10203  for (i = 0; i < s->rowset_size; i++) {
10204  ret = setposrefr(s, i);
10205  if (!SQL_SUCCEEDED(ret)) {
10206  break;
10207  }
10208  }
10209  return ret;
10210  }
10211  return setposrefr(s, row - 1);
10212  } else if (op == SQL_DELETE) {
10213  sql = dsappend(sql, "DELETE FROM ");
10214  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10215  sql = dsappendq(sql, s->dyncols[0].db);
10216  sql = dsappend(sql, ".");
10217  }
10218  sql = dsappendq(sql, s->dyncols[0].table);
10219  for (i = k = 0; i < s->ncols; i++) {
10220  if (s->dyncols[i].ispk <= 0) {
10221  continue;
10222  }
10223  sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10224  sql = dsappendq(sql, s->dyncols[i].column);
10225  sql = dsappend(sql, " = ?");
10226  k++;
10227  }
10228  if (dserr(sql)) {
10229  dsfree(sql);
10230  return nomem(s);
10231  }
10232 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10233  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10234 #else
10235  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10236 #endif
10237  do {
10238  s3stmt = NULL;
10239 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10240  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10241  &s3stmt, &endp);
10242 #else
10243  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10244  &s3stmt, &endp);
10245 #endif
10246  if (rc != SQLITE_OK) {
10247  if (s3stmt) {
10248  sqlite3_finalize(s3stmt);
10249  s3stmt = NULL;
10250  }
10251  }
10252  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10253  dbtracerc(d, rc, NULL);
10254  dsfree(sql);
10255  if (rc != SQLITE_OK) {
10256 dstmterr:
10257  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10258  sqlite3_errmsg(d->sqlite), rc);
10259  if (s3stmt) {
10260  dbtraceapi(d, "sqlite3_finalize", NULL);
10261  sqlite3_finalize(s3stmt);
10262  }
10263  return SQL_ERROR;
10264  }
10265  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10266  if (s->dyncols[i].ispk <= 0) {
10267  continue;
10268  }
10269  ret = setposibind(s, s3stmt, i, k, row - 1);
10270  if (ret != SQL_SUCCESS) {
10271  dbtraceapi(d, "sqlite3_finalize", NULL);
10272  sqlite3_finalize(s3stmt);
10273  return ret;
10274  }
10275  k++;
10276  }
10277  rc = sqlite3_step(s3stmt);
10278  if (rc != SQLITE_DONE) {
10279  goto dstmterr;
10280  }
10281  sqlite3_finalize(s3stmt);
10282  if (sqlite3_changes(d->sqlite) > 0) {
10283  if (s->row_status0) {
10284  s->row_status0[row - 1] = SQL_ROW_DELETED;
10285  }
10286  if (s->row_status) {
10287  s->row_status[row - 1] = SQL_ROW_DELETED;
10288  }
10289  }
10290  return SQL_SUCCESS;
10291  } else if (op == SQL_UPDATE) {
10292  ret = chkunbound(s);
10293  if (ret != SQL_SUCCESS) {
10294  return ret;
10295  }
10296  sql = dsappend(sql, "UPDATE ");
10297  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10298  sql = dsappendq(sql, s->dyncols[0].db);
10299  sql = dsappend(sql, ".");
10300  }
10301  sql = dsappendq(sql, s->dyncols[0].table);
10302  for (i = 0; i < s->ncols; i++) {
10303  sql = dsappend(sql, (i > 0) ? ", " : " SET ");
10304  sql = dsappendq(sql, s->dyncols[i].column);
10305  sql = dsappend(sql, " = ?");
10306  }
10307  for (i = k = 0; i < s->ncols; i++) {
10308  if (s->dyncols[i].ispk <= 0) {
10309  continue;
10310  }
10311  sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10312  sql = dsappendq(sql, s->dyncols[i].column);
10313  sql = dsappend(sql, " = ?");
10314  k++;
10315  }
10316  if (dserr(sql)) {
10317  dsfree(sql);
10318  return nomem(s);
10319  }
10320 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10321  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10322 #else
10323  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10324 #endif
10325  do {
10326  s3stmt = NULL;
10327 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10328  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10329  &s3stmt, &endp);
10330 #else
10331  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10332  &s3stmt, &endp);
10333 #endif
10334  if (rc != SQLITE_OK) {
10335  if (s3stmt) {
10336  sqlite3_finalize(s3stmt);
10337  s3stmt = NULL;
10338  }
10339  }
10340  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10341  dbtracerc(d, rc, NULL);
10342  dsfree(sql);
10343  if (rc != SQLITE_OK) {
10344 ustmterr:
10345  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10346  sqlite3_errmsg(d->sqlite), rc);
10347  if (s3stmt) {
10348  dbtraceapi(d, "sqlite3_finalize", NULL);
10349  sqlite3_finalize(s3stmt);
10350  }
10351  return SQL_ERROR;
10352  }
10353  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10354  ret = setposbind(s, s3stmt, i, k, row - 1);
10355  if (ret != SQL_SUCCESS) {
10356  dbtraceapi(d, "sqlite3_finalize", NULL);
10357  sqlite3_finalize(s3stmt);
10358  return ret;
10359  }
10360  k++;
10361  }
10362  for (i = 0; s->bindcols && i < s->ncols; i++) {
10363  if (s->dyncols[i].ispk <= 0) {
10364  continue;
10365  }
10366  ret = setposibind(s, s3stmt, i, k, row - 1);
10367  if (ret != SQL_SUCCESS) {
10368  dbtraceapi(d, "sqlite3_finalize", NULL);
10369  sqlite3_finalize(s3stmt);
10370  return ret;
10371  }
10372  k++;
10373  }
10374  rc = sqlite3_step(s3stmt);
10375  if (rc != SQLITE_DONE) {
10376  goto ustmterr;
10377  }
10378  sqlite3_finalize(s3stmt);
10379  if (sqlite3_changes(d->sqlite) > 0) {
10380  if (s->row_status0) {
10381  s->row_status0[row - 1] = SQL_ROW_UPDATED;
10382  }
10383  if (s->row_status) {
10384  s->row_status[row - 1] = SQL_ROW_UPDATED;
10385  }
10386  }
10387  return SQL_SUCCESS;
10388  }
10389  return SQL_SUCCESS;
10390 }
10391 
10401 SQLRETURN SQL_API
10402 SQLSetPos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10403 {
10404  SQLRETURN ret;
10405 
10406  HSTMT_LOCK(stmt);
10407  ret = drvsetpos(stmt, row, op, lock);
10408  HSTMT_UNLOCK(stmt);
10409  return ret;
10410 }
10411 
10419 static SQLRETURN
10420 drvbulkoperations(SQLHSTMT stmt, SQLSMALLINT op)
10421 {
10422  STMT *s = (STMT *) stmt;
10423  DBC *d = (DBC *) s->dbc;
10424  int row, i, k, rc, nretry = 0;
10425  dstr *sql = 0;
10426  const char *endp;
10427  sqlite3_stmt *s3stmt = NULL;
10428  SQLRETURN ret;
10429 
10430  if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10431  setstat(s, -1, "incompatible statement",
10432  (*s->ov3) ? "HY000" : "S1000");
10433  return SQL_ERROR;
10434  }
10435  if (op == SQL_ADD) {
10436  if (s->one_tbl <= 0) {
10437  setstat(s, -1, "incompatible rowset",
10438  (*s->ov3) ? "HY000" : "S1000");
10439  return SQL_ERROR;
10440  }
10441  ret = chkunbound(s);
10442  if (ret != SQL_SUCCESS) {
10443  return ret;
10444  }
10445  sql = dsappend(sql, "INSERT INTO ");
10446  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10447  sql = dsappendq(sql, s->dyncols[0].db);
10448  sql = dsappend(sql, ".");
10449  }
10450  sql = dsappendq(sql, s->dyncols[0].table);
10451  for (i = 0; i < s->ncols; i++) {
10452  sql = dsappend(sql, (i > 0) ? "," : "(");
10453  sql = dsappendq(sql, s->dyncols[i].column);
10454  }
10455  sql = dsappend(sql, ") VALUES ");
10456  for (i = 0; i < s->ncols; i++) {
10457  sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10458  }
10459  sql = dsappend(sql, ")");
10460  if (dserr(sql)) {
10461  dsfree(sql);
10462  return nomem(s);
10463  }
10464 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10465  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10466 #else
10467  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10468 #endif
10469  do {
10470  s3stmt = NULL;
10471 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10472  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10473  &s3stmt, &endp);
10474 #else
10475  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10476  &s3stmt, &endp);
10477 #endif
10478  if (rc != SQLITE_OK) {
10479  if (s3stmt) {
10480  sqlite3_finalize(s3stmt);
10481  s3stmt = NULL;
10482  }
10483  }
10484  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10485  dbtracerc(d, rc, NULL);
10486  dsfree(sql);
10487  if (rc != SQLITE_OK) {
10488  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10489  sqlite3_errmsg(d->sqlite), rc);
10490  if (s3stmt) {
10491  dbtraceapi(d, "sqlite3_finalize", NULL);
10492  sqlite3_finalize(s3stmt);
10493  }
10494  return SQL_ERROR;
10495  }
10496  for (row = 0; row < s->rowset_size; row++) {
10497  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10498  ret = setposbind(s, s3stmt, i, k, row);
10499  if (ret != SQL_SUCCESS) {
10500 istmterr:
10501  if (s->row_status0) {
10502  s->row_status0[row] = SQL_ROW_ERROR;
10503  }
10504  if (s->row_status) {
10505  s->row_status[row] = SQL_ROW_ERROR;
10506  }
10507  dbtraceapi(d, "sqlite3_finalize", NULL);
10508  sqlite3_finalize(s3stmt);
10509  return ret;
10510  }
10511  k++;
10512  }
10513  rc = sqlite3_step(s3stmt);
10514  if (rc != SQLITE_DONE) {
10515  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10516  sqlite3_errmsg(d->sqlite), rc);
10517  ret = SQL_ERROR;
10518  goto istmterr;
10519  }
10520  if (sqlite3_changes(d->sqlite) > 0) {
10521  if (s->row_status0) {
10522  s->row_status0[row] = SQL_ROW_ADDED;
10523  }
10524  if (s->row_status) {
10525  s->row_status[row] = SQL_ROW_ADDED;
10526  }
10527  }
10528  if (s->bkmrk == SQL_UB_VARIABLE &&
10529  s->bkmrkcol.type == SQL_C_VARBOOKMARK &&
10530  s->bkmrkcol.valp) {
10531  SQLPOINTER *val;
10532 
10533  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10534  val = (SQLPOINTER)
10535  ((char *) s->bkmrkcol.valp + s->bind_type * row);
10536  } else {
10537  val = (SQLPOINTER)
10538  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10539  }
10540  if (s->bind_offs) {
10541  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10542  }
10543  *(sqlite_int64 *) val = sqlite3_last_insert_rowid(d->sqlite);
10544  if (s->bkmrkcol.lenp) {
10545  SQLLEN *ival;
10546 
10547  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10548  ival = (SQLLEN *)
10549  ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10550  } else {
10551  ival = &s->bkmrkcol.lenp[row];
10552  }
10553  if (s->bind_offs) {
10554  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10555  }
10556  *ival = sizeof (sqlite_int64);
10557  }
10558  }
10559  dbtraceapi(d, "sqlite3_reset", NULL);
10560  sqlite3_reset(s3stmt);
10561  }
10562  dbtraceapi(d, "sqlite3_finalize", NULL);
10563  sqlite3_finalize(s3stmt);
10564  return SQL_SUCCESS;
10565  } else if (op == SQL_DELETE_BY_BOOKMARK) {
10566  if (s->has_rowid < 0 ||
10567  s->bkmrk != SQL_UB_VARIABLE ||
10568  s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10569  !s->bkmrkcol.valp) {
10570  setstat(s, -1, "incompatible rowset",
10571  (*s->ov3) ? "HY000" : "S1000");
10572  return SQL_ERROR;
10573  }
10574  sql = dsappend(sql, "DELETE FROM ");
10575  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10576  sql = dsappendq(sql, s->dyncols[0].db);
10577  sql = dsappend(sql, ".");
10578  }
10579  sql = dsappendq(sql, s->dyncols[0].table);
10580  sql = dsappend(sql, " WHERE ");
10581  sql = dsappendq(sql, s->dyncols[0].column);
10582  sql = dsappend(sql, " = ?");
10583  if (dserr(sql)) {
10584  dsfree(sql);
10585  return nomem(s);
10586  }
10587 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10588  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10589 #else
10590  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10591 #endif
10592  do {
10593  s3stmt = NULL;
10594 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10595  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10596  &s3stmt, &endp);
10597 #else
10598  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10599  &s3stmt, &endp);
10600 #endif
10601  if (rc != SQLITE_OK) {
10602  if (s3stmt) {
10603  sqlite3_finalize(s3stmt);
10604  s3stmt = NULL;
10605  }
10606  }
10607  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10608  dbtracerc(d, rc, NULL);
10609  dsfree(sql);
10610  if (rc != SQLITE_OK) {
10611  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10612  sqlite3_errmsg(d->sqlite), rc);
10613  if (s3stmt) {
10614  dbtraceapi(d, "sqlite3_finalize", NULL);
10615  sqlite3_finalize(s3stmt);
10616  }
10617  return SQL_ERROR;
10618  }
10619  for (row = 0; row < s->rowset_size; row++) {
10620  SQLPOINTER *val;
10621  sqlite_int64 rowid;
10622 
10623  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10624  val = (SQLPOINTER)
10625  ((char *) s->bkmrkcol.valp + s->bind_type * row);
10626  } else {
10627  val = (SQLPOINTER)
10628  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10629  }
10630  if (s->bind_offs) {
10631  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10632  }
10633  if (s->bkmrkcol.lenp) {
10634  SQLLEN *ival;
10635 
10636  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10637  ival = (SQLLEN *)
10638  ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10639  } else {
10640  ival = &s->bkmrkcol.lenp[row];
10641  }
10642  if (s->bind_offs) {
10643  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10644  }
10645  if (*ival != sizeof (sqlite_int64)) {
10646  continue;
10647  }
10648  }
10649  rowid = *(sqlite_int64 *) val;
10650  sqlite3_bind_int64(s3stmt, 1, rowid);
10651  if (d->trace) {
10652  fprintf(d->trace,
10653 #ifdef _WIN32
10654  "-- parameter 1: %I64d\n",
10655 #else
10656  "-- parameter 1: %lld\n",
10657 #endif
10658  rowid);
10659  fflush(d->trace);
10660  }
10661  rc = sqlite3_step(s3stmt);
10662  if (rc != SQLITE_DONE) {
10663  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10664  sqlite3_errmsg(d->sqlite), rc);
10665  if (s->row_status0) {
10666  s->row_status0[row] = SQL_ROW_ERROR;
10667  }
10668  if (s->row_status) {
10669  s->row_status[row] = SQL_ROW_ERROR;
10670  }
10671  dbtraceapi(d, "sqlite3_finalize", NULL);
10672  sqlite3_finalize(s3stmt);
10673  return SQL_ERROR;
10674  }
10675  if (sqlite3_changes(d->sqlite) > 0) {
10676  if (s->row_status0) {
10677  s->row_status0[row] = SQL_ROW_DELETED;
10678  }
10679  if (s->row_status) {
10680  s->row_status[row] = SQL_ROW_DELETED;
10681  }
10682  }
10683  dbtraceapi(d, "sqlite3_reset", NULL);
10684  sqlite3_reset(s3stmt);
10685  }
10686  dbtraceapi(d, "sqlite3_finalize", NULL);
10687  sqlite3_finalize(s3stmt);
10688  return SQL_SUCCESS;
10689  } else if (op == SQL_UPDATE_BY_BOOKMARK) {
10690  if (s->has_rowid < 0 ||
10691  s->bkmrk != SQL_UB_VARIABLE ||
10692  s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10693  !s->bkmrkcol.valp) {
10694  setstat(s, -1, "incompatible rowset",
10695  (*s->ov3) ? "HY000" : "S1000");
10696  return SQL_ERROR;
10697  }
10698  ret = chkunbound(s);
10699  if (ret != SQL_SUCCESS) {
10700  return ret;
10701  }
10702  sql = dsappend(sql, "UPDATE ");
10703  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10704  sql = dsappendq(sql, s->dyncols[0].db);
10705  sql = dsappend(sql, ".");
10706  }
10707  sql = dsappendq(sql, s->dyncols[0].table);
10708  for (i = 0, k = 0; i < s->ncols; i++) {
10709  if (i == s->has_rowid) {
10710  continue;
10711  }
10712  sql = dsappend(sql, (k > 0) ? ", " : " SET ");
10713  sql = dsappendq(sql, s->dyncols[i].column);
10714  sql = dsappend(sql, " = ?");
10715  k++;
10716  }
10717  sql = dsappend(sql, " WHERE ");
10718  sql = dsappendq(sql, s->dyncols[s->has_rowid].column);
10719  sql = dsappend(sql, " = ?");
10720  if (dserr(sql)) {
10721  dsfree(sql);
10722  return nomem(s);
10723  }
10724 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10725  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10726 #else
10727  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10728 #endif
10729  do {
10730  s3stmt = NULL;
10731 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10732  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10733  &s3stmt, &endp);
10734 #else
10735  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10736  &s3stmt, &endp);
10737 #endif
10738  if (rc != SQLITE_OK) {
10739  if (s3stmt) {
10740  sqlite3_finalize(s3stmt);
10741  s3stmt = NULL;
10742  }
10743  }
10744  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10745  dbtracerc(d, rc, NULL);
10746  dsfree(sql);
10747  if (rc != SQLITE_OK) {
10748  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10749  sqlite3_errmsg(d->sqlite), rc);
10750  if (s3stmt) {
10751  dbtraceapi(d, "sqlite3_finalize", NULL);
10752  sqlite3_finalize(s3stmt);
10753  }
10754  return SQL_ERROR;
10755  }
10756  for (row = 0; row < s->rowset_size; row++) {
10757  SQLPOINTER *val;
10758  sqlite_int64 rowid;
10759 
10760  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10761  val = (SQLPOINTER)
10762  ((char *) s->bkmrkcol.valp + s->bind_type * row);
10763  } else {
10764  val = (SQLPOINTER)
10765  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10766  }
10767  if (s->bind_offs) {
10768  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10769  }
10770  if (s->bkmrkcol.lenp) {
10771  SQLLEN *ival;
10772 
10773  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10774  ival = (SQLLEN *)
10775  ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10776  } else {
10777  ival = &s->bkmrkcol.lenp[row];
10778  }
10779  if (s->bind_offs) {
10780  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10781  }
10782  if (*ival != sizeof (sqlite_int64)) {
10783  continue;
10784  }
10785  }
10786  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10787  if (i == s->has_rowid) {
10788  continue;
10789  }
10790  ret = setposbind(s, s3stmt, i, k, row);
10791  if (ret != SQL_SUCCESS) {
10792 ustmterr:
10793  if (s->row_status0) {
10794  s->row_status0[row] = SQL_ROW_ERROR;
10795  }
10796  if (s->row_status) {
10797  s->row_status[row] = SQL_ROW_ERROR;
10798  }
10799  dbtraceapi(d, "sqlite3_finalize", NULL);
10800  sqlite3_finalize(s3stmt);
10801  return ret;
10802  }
10803  k++;
10804  }
10805  rowid = *(sqlite_int64 *) val;
10806  sqlite3_bind_int64(s3stmt, k, rowid);
10807  if (d->trace) {
10808  fprintf(d->trace,
10809 #ifdef _WIN32
10810  "-- parameter %d: %I64d\n",
10811 #else
10812  "-- parameter %d: %lld\n",
10813 #endif
10814  k, rowid);
10815  fflush(d->trace);
10816  }
10817  rc = sqlite3_step(s3stmt);
10818  if (rc != SQLITE_DONE) {
10819  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10820  sqlite3_errmsg(d->sqlite), rc);
10821  ret = SQL_ERROR;
10822  goto ustmterr;
10823  }
10824  if (sqlite3_changes(d->sqlite) > 0) {
10825  if (s->row_status0) {
10826  s->row_status0[row] = SQL_ROW_UPDATED;
10827  }
10828  if (s->row_status) {
10829  s->row_status[row] = SQL_ROW_UPDATED;
10830  }
10831  }
10832  dbtraceapi(d, "sqlite3_reset", NULL);
10833  sqlite3_reset(s3stmt);
10834  }
10835  dbtraceapi(d, "sqlite3_finalize", NULL);
10836  sqlite3_finalize(s3stmt);
10837  return SQL_SUCCESS;
10838  }
10839  setstat(s, -1, "unsupported operation", (*s->ov3) ? "HY000" : "S1000");
10840  return SQL_ERROR;
10841 }
10842 
10850 SQLRETURN SQL_API
10851 SQLBulkOperations(SQLHSTMT stmt, SQLSMALLINT oper)
10852 {
10853  SQLRETURN ret;
10854 
10855  HSTMT_LOCK(stmt);
10856  ret = drvbulkoperations(stmt, oper);
10857  HSTMT_UNLOCK(stmt);
10858  return ret;
10859 }
10860 
10861 
10866 SQLRETURN SQL_API
10867 SQLSetScrollOptions(SQLHSTMT stmt, SQLUSMALLINT concur, SQLLEN rowkeyset,
10868  SQLUSMALLINT rowset)
10869 {
10870  SQLRETURN ret;
10871 
10872  HSTMT_LOCK(stmt);
10873  ret = drvunimplstmt(stmt);
10874  HSTMT_UNLOCK(stmt);
10875  return ret;
10876 }
10877 
10878 #define strmak(dst, src, max, lenp) { \
10879  int len = strlen(src); \
10880  int cnt = min(len + 1, max); \
10881  strncpy(dst, src, cnt); \
10882  *lenp = (cnt > len) ? len : cnt; \
10883 }
10884 
10895 static SQLRETURN
10896 drvgetinfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
10897  SQLSMALLINT *valLen)
10898 {
10899  DBC *d;
10900  char dummyc[16];
10901  SQLSMALLINT dummy;
10902 #if defined(_WIN32) || defined(_WIN64)
10903  char pathbuf[301], *drvname;
10904 #else
10905  static char drvname[] = "sqlite3odbc.so";
10906 #endif
10907 
10908  if (dbc == SQL_NULL_HDBC) {
10909  return SQL_INVALID_HANDLE;
10910  }
10911  d = (DBC *) dbc;
10912  if (valMax) {
10913  valMax--;
10914  }
10915  if (!valLen) {
10916  valLen = &dummy;
10917  }
10918  if (!val) {
10919  val = dummyc;
10920  valMax = sizeof (dummyc) - 1;
10921  }
10922  switch (type) {
10923  case SQL_MAX_USER_NAME_LEN:
10924  *((SQLSMALLINT *) val) = 16;
10925  *valLen = sizeof (SQLSMALLINT);
10926  break;
10927  case SQL_USER_NAME:
10928  strmak(val, "", valMax, valLen);
10929  break;
10930  case SQL_DRIVER_ODBC_VER:
10931 #if 0
10932  strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
10933 #else
10934  strmak(val, "03.00", valMax, valLen);
10935 #endif
10936  break;
10937  case SQL_ACTIVE_CONNECTIONS:
10938  case SQL_ACTIVE_STATEMENTS:
10939  *((SQLSMALLINT *) val) = 0;
10940  *valLen = sizeof (SQLSMALLINT);
10941  break;
10942 #ifdef SQL_ASYNC_MODE
10943  case SQL_ASYNC_MODE:
10944  *((SQLUINTEGER *) val) = SQL_AM_NONE;
10945  *valLen = sizeof (SQLUINTEGER);
10946  break;
10947 #endif
10948 #ifdef SQL_CREATE_TABLE
10949  case SQL_CREATE_TABLE:
10950  *((SQLUINTEGER *) val) = SQL_CT_CREATE_TABLE |
10951  SQL_CT_COLUMN_DEFAULT |
10952  SQL_CT_COLUMN_CONSTRAINT |
10953  SQL_CT_CONSTRAINT_NON_DEFERRABLE;
10954  *valLen = sizeof (SQLUINTEGER);
10955  break;
10956 #endif
10957 #ifdef SQL_CREATE_VIEW
10958  case SQL_CREATE_VIEW:
10959  *((SQLUINTEGER *) val) = SQL_CV_CREATE_VIEW;
10960  *valLen = sizeof (SQLUINTEGER);
10961  break;
10962 #endif
10963 #ifdef SQL_DDL_INDEX
10964  case SQL_DDL_INDEX:
10965  *((SQLUINTEGER *) val) = SQL_DI_CREATE_INDEX | SQL_DI_DROP_INDEX;
10966  *valLen = sizeof (SQLUINTEGER);
10967  break;
10968 #endif
10969 #ifdef SQL_DROP_TABLE
10970  case SQL_DROP_TABLE:
10971  *((SQLUINTEGER *) val) = SQL_DT_DROP_TABLE;
10972  *valLen = sizeof (SQLUINTEGER);
10973  break;
10974 #endif
10975 #ifdef SQL_DROP_VIEW
10976  case SQL_DROP_VIEW:
10977  *((SQLUINTEGER *) val) = SQL_DV_DROP_VIEW;
10978  *valLen = sizeof (SQLUINTEGER);
10979  break;
10980 #endif
10981 #ifdef SQL_INDEX_KEYWORDS
10982  case SQL_INDEX_KEYWORDS:
10983  *((SQLUINTEGER *) val) = SQL_IK_ALL;
10984  *valLen = sizeof (SQLUINTEGER);
10985  break;
10986 #endif
10987  case SQL_DATA_SOURCE_NAME:
10988  strmak(val, d->dsn ? d->dsn : "", valMax, valLen);
10989  break;
10990  case SQL_DRIVER_NAME:
10991 #if defined(_WIN32) || defined(_WIN64)
10992  GetModuleFileName(hModule, pathbuf, sizeof (pathbuf));
10993  drvname = strrchr(pathbuf, '\\');
10994  if (drvname == NULL) {
10995  drvname = strrchr(pathbuf, '/');
10996  }
10997  if (drvname == NULL) {
10998  drvname = pathbuf;
10999  } else {
11000  drvname++;
11001  }
11002 #endif
11003  strmak(val, drvname, valMax, valLen);
11004  break;
11005  case SQL_DRIVER_VER:
11006  strmak(val, DRIVER_VER_INFO, valMax, valLen);
11007  break;
11008  case SQL_FETCH_DIRECTION:
11009  *((SQLUINTEGER *) val) = SQL_FD_FETCH_NEXT | SQL_FD_FETCH_FIRST |
11010  SQL_FD_FETCH_LAST | SQL_FD_FETCH_PRIOR | SQL_FD_FETCH_ABSOLUTE;
11011  *valLen = sizeof (SQLUINTEGER);
11012  break;
11013  case SQL_ODBC_VER:
11014  strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
11015  break;
11016  case SQL_ODBC_SAG_CLI_CONFORMANCE:
11017  *((SQLSMALLINT *) val) = SQL_OSCC_NOT_COMPLIANT;
11018  *valLen = sizeof (SQLSMALLINT);
11019  break;
11020  case SQL_STANDARD_CLI_CONFORMANCE:
11021  *((SQLUINTEGER *) val) = SQL_SCC_XOPEN_CLI_VERSION1;
11022  *valLen = sizeof (SQLUINTEGER);
11023  break;
11024  case SQL_SQL_CONFORMANCE:
11025  *((SQLUINTEGER *) val) = SQL_SC_SQL92_ENTRY;
11026  *valLen = sizeof (SQLUINTEGER);
11027  break;
11028  case SQL_SERVER_NAME:
11029  case SQL_DATABASE_NAME:
11030  strmak(val, d->dbname ? d->dbname : "", valMax, valLen);
11031  break;
11032  case SQL_SEARCH_PATTERN_ESCAPE:
11033  strmak(val, "\\", valMax, valLen);
11034  break;
11035  case SQL_ODBC_SQL_CONFORMANCE:
11036  *((SQLSMALLINT *) val) = SQL_OSC_MINIMUM;
11037  *valLen = sizeof (SQLSMALLINT);
11038  break;
11039  case SQL_ODBC_API_CONFORMANCE:
11040  *((SQLSMALLINT *) val) = SQL_OAC_LEVEL1;
11041  *valLen = sizeof (SQLSMALLINT);
11042  break;
11043  case SQL_DBMS_NAME:
11044  strmak(val, "SQLite", valMax, valLen);
11045  break;
11046  case SQL_DBMS_VER:
11047  strmak(val, SQLITE_VERSION, valMax, valLen);
11048  break;
11049  case SQL_COLUMN_ALIAS:
11050  case SQL_NEED_LONG_DATA_LEN:
11051  strmak(val, "Y", valMax, valLen);
11052  break;
11053  case SQL_ROW_UPDATES:
11054  case SQL_ACCESSIBLE_PROCEDURES:
11055  case SQL_PROCEDURES:
11056  case SQL_EXPRESSIONS_IN_ORDERBY:
11057  case SQL_ODBC_SQL_OPT_IEF:
11058  case SQL_LIKE_ESCAPE_CLAUSE:
11059  case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11060  case SQL_OUTER_JOINS:
11061  case SQL_ACCESSIBLE_TABLES:
11062  case SQL_MULT_RESULT_SETS:
11063  case SQL_MULTIPLE_ACTIVE_TXN:
11064  case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11065  strmak(val, "N", valMax, valLen);
11066  break;
11067 #ifdef SQL_CATALOG_NAME
11068  case SQL_CATALOG_NAME:
11069 #if defined(_WIN32) || defined(_WIN64)
11070  strmak(val, d->xcelqrx ? "Y" : "N", valMax, valLen);
11071 #else
11072  strmak(val, "N", valMax, valLen);
11073 #endif
11074  break;
11075 #endif
11076  case SQL_DATA_SOURCE_READ_ONLY:
11077  strmak(val, "N", valMax, valLen);
11078  break;
11079 #ifdef SQL_OJ_CAPABILITIES
11080  case SQL_OJ_CAPABILITIES:
11081  *((SQLUINTEGER *) val) = 0;
11082  *valLen = sizeof (SQLUINTEGER);
11083  break;
11084 #endif
11085 #ifdef SQL_MAX_IDENTIFIER_LEN
11086  case SQL_MAX_IDENTIFIER_LEN:
11087  *((SQLUSMALLINT *) val) = 255;
11088  *valLen = sizeof (SQLUSMALLINT);
11089  break;
11090 #endif
11091  case SQL_CONCAT_NULL_BEHAVIOR:
11092  *((SQLSMALLINT *) val) = SQL_CB_NULL;
11093  *valLen = sizeof (SQLSMALLINT);
11094  break;
11095  case SQL_CURSOR_COMMIT_BEHAVIOR:
11096  case SQL_CURSOR_ROLLBACK_BEHAVIOR:
11097  *((SQLSMALLINT *) val) = SQL_CB_PRESERVE;
11098  *valLen = sizeof (SQLSMALLINT);
11099  break;
11100 #ifdef SQL_CURSOR_SENSITIVITY
11101  case SQL_CURSOR_SENSITIVITY:
11102  *((SQLUINTEGER *) val) = SQL_UNSPECIFIED;
11103  *valLen = sizeof (SQLUINTEGER);
11104  break;
11105 #endif
11106  case SQL_DEFAULT_TXN_ISOLATION:
11107  *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11108  *valLen = sizeof (SQLUINTEGER);
11109  break;
11110 #ifdef SQL_DESCRIBE_PARAMETER
11111  case SQL_DESCRIBE_PARAMETER:
11112  strmak(val, "Y", valMax, valLen);
11113  break;
11114 #endif
11115  case SQL_TXN_ISOLATION_OPTION:
11116  *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11117  *valLen = sizeof (SQLUINTEGER);
11118  break;
11119  case SQL_IDENTIFIER_CASE:
11120  *((SQLSMALLINT *) val) = SQL_IC_SENSITIVE;
11121  *valLen = sizeof (SQLSMALLINT);
11122  break;
11123  case SQL_IDENTIFIER_QUOTE_CHAR:
11124  strmak(val, "\"", valMax, valLen);
11125  break;
11126  case SQL_MAX_TABLE_NAME_LEN:
11127  case SQL_MAX_COLUMN_NAME_LEN:
11128  *((SQLSMALLINT *) val) = 255;
11129  *valLen = sizeof (SQLSMALLINT);
11130  break;
11131  case SQL_MAX_CURSOR_NAME_LEN:
11132  *((SQLSMALLINT *) val) = 255;
11133  *valLen = sizeof (SQLSMALLINT);
11134  break;
11135  case SQL_MAX_PROCEDURE_NAME_LEN:
11136  *((SQLSMALLINT *) val) = 0;
11137  break;
11138  case SQL_MAX_QUALIFIER_NAME_LEN:
11139  case SQL_MAX_OWNER_NAME_LEN:
11140  *((SQLSMALLINT *) val) = 255;
11141  break;
11142  case SQL_OWNER_TERM:
11143  strmak(val, "", valMax, valLen);
11144  break;
11145  case SQL_PROCEDURE_TERM:
11146  strmak(val, "PROCEDURE", valMax, valLen);
11147  break;
11148  case SQL_QUALIFIER_NAME_SEPARATOR:
11149  strmak(val, ".", valMax, valLen);
11150  break;
11151  case SQL_QUALIFIER_TERM:
11152 #if defined(_WIN32) || defined(_WIN64)
11153  strmak(val, d->xcelqrx ? "catalog" : "", valMax, valLen);
11154 #else
11155  strmak(val, "", valMax, valLen);
11156 #endif
11157  break;
11158  case SQL_QUALIFIER_USAGE:
11159 #if defined(_WIN32) || defined(_WIN64)
11160  *((SQLUINTEGER *) val) = d->xcelqrx ?
11161  (SQL_CU_DML_STATEMENTS | SQL_CU_INDEX_DEFINITION |
11162  SQL_CU_TABLE_DEFINITION) : 0;
11163 #else
11164  *((SQLUINTEGER *) val) = 0;
11165 #endif
11166  *valLen = sizeof (SQLUINTEGER);
11167  break;
11168  case SQL_SCROLL_CONCURRENCY:
11169  *((SQLUINTEGER *) val) = SQL_SCCO_LOCK;
11170  *valLen = sizeof (SQLUINTEGER);
11171  break;
11172  case SQL_SCROLL_OPTIONS:
11173  *((SQLUINTEGER *) val) = SQL_SO_STATIC | SQL_SO_FORWARD_ONLY;
11174  *valLen = sizeof (SQLUINTEGER);
11175  break;
11176  case SQL_TABLE_TERM:
11177  strmak(val, "TABLE", valMax, valLen);
11178  break;
11179  case SQL_TXN_CAPABLE:
11180  *((SQLSMALLINT *) val) = SQL_TC_ALL;
11181  *valLen = sizeof (SQLSMALLINT);
11182  break;
11183  case SQL_CONVERT_FUNCTIONS:
11184  *((SQLUINTEGER *) val) = 0;
11185  *valLen = sizeof (SQLUINTEGER);
11186  break;
11187  case SQL_SYSTEM_FUNCTIONS:
11188  case SQL_NUMERIC_FUNCTIONS:
11189  case SQL_STRING_FUNCTIONS:
11190  case SQL_TIMEDATE_FUNCTIONS:
11191  *((SQLUINTEGER *) val) = 0;
11192  *valLen = sizeof (SQLUINTEGER);
11193  break;
11194  case SQL_CONVERT_BIGINT:
11195  case SQL_CONVERT_BIT:
11196  case SQL_CONVERT_CHAR:
11197  case SQL_CONVERT_DATE:
11198  case SQL_CONVERT_DECIMAL:
11199  case SQL_CONVERT_DOUBLE:
11200  case SQL_CONVERT_FLOAT:
11201  case SQL_CONVERT_INTEGER:
11202  case SQL_CONVERT_LONGVARCHAR:
11203  case SQL_CONVERT_NUMERIC:
11204  case SQL_CONVERT_REAL:
11205  case SQL_CONVERT_SMALLINT:
11206  case SQL_CONVERT_TIME:
11207  case SQL_CONVERT_TIMESTAMP:
11208  case SQL_CONVERT_TINYINT:
11209  case SQL_CONVERT_VARCHAR:
11210  *((SQLUINTEGER *) val) =
11211  SQL_CVT_CHAR | SQL_CVT_NUMERIC | SQL_CVT_DECIMAL |
11212  SQL_CVT_INTEGER | SQL_CVT_SMALLINT | SQL_CVT_FLOAT | SQL_CVT_REAL |
11213  SQL_CVT_DOUBLE | SQL_CVT_VARCHAR | SQL_CVT_LONGVARCHAR |
11214  SQL_CVT_BIT | SQL_CVT_TINYINT | SQL_CVT_BIGINT |
11215  SQL_CVT_DATE | SQL_CVT_TIME | SQL_CVT_TIMESTAMP;
11216  *valLen = sizeof (SQLUINTEGER);
11217  break;
11218  case SQL_CONVERT_BINARY:
11219  case SQL_CONVERT_VARBINARY:
11220  case SQL_CONVERT_LONGVARBINARY:
11221  *((SQLUINTEGER *) val) = 0;
11222  *valLen = sizeof (SQLUINTEGER);
11223  break;
11224  case SQL_POSITIONED_STATEMENTS:
11225  *((SQLUINTEGER *) val) = 0;
11226  *valLen = sizeof (SQLUINTEGER);
11227  break;
11228  case SQL_LOCK_TYPES:
11229  *((SQLUINTEGER *) val) = SQL_LCK_NO_CHANGE;
11230  *valLen = sizeof (SQLUINTEGER);
11231  break;
11232  case SQL_BOOKMARK_PERSISTENCE:
11233  *((SQLUINTEGER *) val) = SQL_BP_SCROLL;
11234  *valLen = sizeof (SQLUINTEGER);
11235  break;
11236  case SQL_UNION:
11237  *((SQLUINTEGER *) val) = SQL_U_UNION | SQL_U_UNION_ALL;
11238  *valLen = sizeof (SQLUINTEGER);
11239  break;
11240  case SQL_OWNER_USAGE:
11241  case SQL_SUBQUERIES:
11242  case SQL_TIMEDATE_ADD_INTERVALS:
11243  case SQL_TIMEDATE_DIFF_INTERVALS:
11244  *((SQLUINTEGER *) val) = 0;
11245  *valLen = sizeof (SQLUINTEGER);
11246  break;
11247  case SQL_QUOTED_IDENTIFIER_CASE:
11248  *((SQLUSMALLINT *) val) = SQL_IC_SENSITIVE;
11249  *valLen = sizeof (SQLUSMALLINT);
11250  break;
11251  case SQL_POS_OPERATIONS:
11252  *((SQLUINTEGER *) val) = SQL_POS_POSITION | SQL_POS_UPDATE |
11253  SQL_POS_DELETE | SQL_POS_ADD | SQL_POS_REFRESH;
11254  *valLen = sizeof (SQLUINTEGER);
11255  break;
11256  case SQL_ALTER_TABLE:
11257  *((SQLUINTEGER *) val) = 0;
11258  *valLen = sizeof (SQLUINTEGER);
11259  break;
11260  case SQL_CORRELATION_NAME:
11261  *((SQLSMALLINT *) val) = SQL_CN_DIFFERENT;
11262  *valLen = sizeof (SQLSMALLINT);
11263  break;
11264  case SQL_NON_NULLABLE_COLUMNS:
11265  *((SQLSMALLINT *) val) = SQL_NNC_NON_NULL;
11266  *valLen = sizeof (SQLSMALLINT);
11267  break;
11268  case SQL_NULL_COLLATION:
11269  *((SQLSMALLINT *) val) = SQL_NC_START;
11270  *valLen = sizeof (SQLSMALLINT);
11271  break;
11272  case SQL_MAX_COLUMNS_IN_GROUP_BY:
11273  case SQL_MAX_COLUMNS_IN_ORDER_BY:
11274  case SQL_MAX_COLUMNS_IN_SELECT:
11275  case SQL_MAX_COLUMNS_IN_TABLE:
11276  case SQL_MAX_ROW_SIZE:
11277  case SQL_MAX_TABLES_IN_SELECT:
11278  *((SQLSMALLINT *) val) = 0;
11279  *valLen = sizeof (SQLSMALLINT);
11280  break;
11281  case SQL_MAX_BINARY_LITERAL_LEN:
11282  case SQL_MAX_CHAR_LITERAL_LEN:
11283  *((SQLUINTEGER *) val) = 0;
11284  *valLen = sizeof (SQLUINTEGER);
11285  break;
11286  case SQL_MAX_COLUMNS_IN_INDEX:
11287  *((SQLSMALLINT *) val) = 0;
11288  *valLen = sizeof (SQLSMALLINT);
11289  break;
11290  case SQL_MAX_INDEX_SIZE:
11291  *((SQLUINTEGER *) val) = 0;
11292  *valLen = sizeof (SQLUINTEGER);
11293  break;
11294 #ifdef SQL_MAX_IDENTIFIER_LENGTH
11295  case SQL_MAX_IDENTIFIER_LENGTH:
11296  *((SQLUINTEGER *) val) = 255;
11297  *valLen = sizeof (SQLUINTEGER);
11298  break;
11299 #endif
11300  case SQL_MAX_STATEMENT_LEN:
11301  *((SQLUINTEGER *) val) = 16384;
11302  *valLen = sizeof (SQLUINTEGER);
11303  break;
11304  case SQL_QUALIFIER_LOCATION:
11305  *((SQLSMALLINT *) val) = SQL_QL_START;
11306  *valLen = sizeof (SQLSMALLINT);
11307  break;
11308  case SQL_GETDATA_EXTENSIONS:
11309  *((SQLUINTEGER *) val) =
11310  SQL_GD_ANY_COLUMN | SQL_GD_ANY_ORDER | SQL_GD_BOUND;
11311  *valLen = sizeof (SQLUINTEGER);
11312  break;
11313  case SQL_STATIC_SENSITIVITY:
11314  *((SQLUINTEGER *) val) = 0;
11315  *valLen = sizeof (SQLUINTEGER);
11316  break;
11317  case SQL_FILE_USAGE:
11318 #if defined(_WIN32) || defined(_WIN64)
11319  *((SQLSMALLINT *) val) =
11320  d->xcelqrx ? SQL_FILE_CATALOG : SQL_FILE_NOT_SUPPORTED;
11321 #else
11322  *((SQLSMALLINT *) val) = SQL_FILE_NOT_SUPPORTED;
11323 #endif
11324  *valLen = sizeof (SQLSMALLINT);
11325  break;
11326  case SQL_GROUP_BY:
11327  *((SQLSMALLINT *) val) = SQL_GB_GROUP_BY_EQUALS_SELECT;
11328  *valLen = sizeof (SQLSMALLINT);
11329  break;
11330  case SQL_KEYWORDS:
11331  strmak(val, "CREATE,SELECT,DROP,DELETE,UPDATE,INSERT,"
11332  "INTO,VALUES,TABLE,INDEX,FROM,SET,WHERE,AND,CURRENT,OF",
11333  valMax, valLen);
11334  break;
11335  case SQL_SPECIAL_CHARACTERS:
11336 #ifdef SQL_COLLATION_SEQ
11337  case SQL_COLLATION_SEQ:
11338 #endif
11339  strmak(val, "", valMax, valLen);
11340  break;
11341  case SQL_BATCH_SUPPORT:
11342  case SQL_BATCH_ROW_COUNT:
11343  case SQL_PARAM_ARRAY_ROW_COUNTS:
11344  *((SQLUINTEGER *) val) = 0;
11345  *valLen = sizeof (SQLUINTEGER);
11346  break;
11347  case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1:
11348  *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_BOOKMARK;
11349  *valLen = sizeof (SQLUINTEGER);
11350  break;
11351  case SQL_STATIC_CURSOR_ATTRIBUTES1:
11352  *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE |
11353  SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK | SQL_CA1_POS_POSITION |
11354  SQL_CA1_POS_DELETE | SQL_CA1_POS_UPDATE | SQL_CA1_POS_REFRESH |
11355  SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_BULK_ADD |
11356  SQL_CA1_BULK_UPDATE_BY_BOOKMARK | SQL_CA1_BULK_DELETE_BY_BOOKMARK;
11357  *valLen = sizeof (SQLUINTEGER);
11358  break;
11359  case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2:
11360  case SQL_STATIC_CURSOR_ATTRIBUTES2:
11361  *((SQLUINTEGER *) val) = SQL_CA2_READ_ONLY_CONCURRENCY |
11362  SQL_CA2_LOCK_CONCURRENCY;
11363  *valLen = sizeof (SQLUINTEGER);
11364  break;
11365  case SQL_KEYSET_CURSOR_ATTRIBUTES1:
11366  case SQL_KEYSET_CURSOR_ATTRIBUTES2:
11367  case SQL_DYNAMIC_CURSOR_ATTRIBUTES1:
11368  case SQL_DYNAMIC_CURSOR_ATTRIBUTES2:
11369  *((SQLUINTEGER *) val) = 0;
11370  *valLen = sizeof (SQLUINTEGER);
11371  break;
11372  case SQL_ODBC_INTERFACE_CONFORMANCE:
11373  *((SQLUINTEGER *) val) = SQL_OIC_CORE;
11374  *valLen = sizeof (SQLUINTEGER);
11375  break;
11376  default:
11377  setstatd(d, -1, "unsupported info option %d",
11378  (*d->ov3) ? "HYC00" : "S1C00", type);
11379  return SQL_ERROR;
11380  }
11381  return SQL_SUCCESS;
11382 }
11383 
11384 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
11385 
11395 SQLRETURN SQL_API
11396 SQLGetInfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11397  SQLSMALLINT *valLen)
11398 {
11399  SQLRETURN ret;
11400 
11401  HDBC_LOCK(dbc);
11402  ret = drvgetinfo(dbc, type, val, valMax, valLen);
11403  HDBC_UNLOCK(dbc);
11404  return ret;
11405 }
11406 #endif
11407 
11408 #ifdef WINTERFACE
11409 
11419 SQLRETURN SQL_API
11420 SQLGetInfoW(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11421  SQLSMALLINT *valLen)
11422 {
11423  SQLRETURN ret;
11424  SQLSMALLINT len = 0;
11425 
11426  HDBC_LOCK(dbc);
11427  ret = drvgetinfo(dbc, type, val, valMax, &len);
11428  HDBC_UNLOCK(dbc);
11429  if (ret == SQL_SUCCESS) {
11430  SQLWCHAR *v = NULL;
11431 
11432  switch (type) {
11433  case SQL_USER_NAME:
11434  case SQL_DRIVER_ODBC_VER:
11435  case SQL_DATA_SOURCE_NAME:
11436  case SQL_DRIVER_NAME:
11437  case SQL_DRIVER_VER:
11438  case SQL_ODBC_VER:
11439  case SQL_SERVER_NAME:
11440  case SQL_DATABASE_NAME:
11441  case SQL_SEARCH_PATTERN_ESCAPE:
11442  case SQL_DBMS_NAME:
11443  case SQL_DBMS_VER:
11444  case SQL_NEED_LONG_DATA_LEN:
11445  case SQL_ROW_UPDATES:
11446  case SQL_ACCESSIBLE_PROCEDURES:
11447  case SQL_PROCEDURES:
11448  case SQL_EXPRESSIONS_IN_ORDERBY:
11449  case SQL_ODBC_SQL_OPT_IEF:
11450  case SQL_LIKE_ESCAPE_CLAUSE:
11451  case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11452  case SQL_OUTER_JOINS:
11453  case SQL_COLUMN_ALIAS:
11454  case SQL_ACCESSIBLE_TABLES:
11455  case SQL_MULT_RESULT_SETS:
11456  case SQL_MULTIPLE_ACTIVE_TXN:
11457  case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11458  case SQL_DATA_SOURCE_READ_ONLY:
11459 #ifdef SQL_DESCRIBE_PARAMETER
11460  case SQL_DESCRIBE_PARAMETER:
11461 #endif
11462  case SQL_IDENTIFIER_QUOTE_CHAR:
11463  case SQL_OWNER_TERM:
11464  case SQL_PROCEDURE_TERM:
11465  case SQL_QUALIFIER_NAME_SEPARATOR:
11466  case SQL_QUALIFIER_TERM:
11467  case SQL_TABLE_TERM:
11468  case SQL_KEYWORDS:
11469  case SQL_SPECIAL_CHARACTERS:
11470 #ifdef SQL_CATALOG_NAME
11471  case SQL_CATALOG_NAME:
11472 #endif
11473 #ifdef SQL_COLLATION_SEQ
11474  case SQL_COLLATION_SEQ:
11475 #endif
11476  if (val) {
11477  if (len > 0) {
11478  v = uc_from_utf((SQLCHAR *) val, len);
11479  if (v) {
11480  int vmax = valMax / sizeof (SQLWCHAR);
11481 
11482  uc_strncpy(val, v, vmax);
11483  if (len < vmax) {
11484  len = min(vmax, uc_strlen(v));
11485  v[len] = 0;
11486  } else {
11487  len = vmax;
11488  }
11489  uc_free(v);
11490  len *= sizeof (SQLWCHAR);
11491  } else {
11492  len = 0;
11493  }
11494  }
11495  if (len <= 0) {
11496  len = 0;
11497  if (valMax >= sizeof (SQLWCHAR)) {
11498  *((SQLWCHAR *)val) = 0;
11499  }
11500  }
11501  } else {
11502  len *= sizeof (SQLWCHAR);
11503  }
11504  break;
11505  }
11506  if (valLen) {
11507  *valLen = len;
11508  }
11509  }
11510  return ret;
11511 }
11512 #endif
11513 
11522 SQLRETURN SQL_API
11523 SQLGetFunctions(SQLHDBC dbc, SQLUSMALLINT func,
11524  SQLUSMALLINT *flags)
11525 {
11526  int i;
11527  SQLUSMALLINT exists[100];
11528 
11529  if (dbc == SQL_NULL_HDBC) {
11530  return SQL_INVALID_HANDLE;
11531  }
11532  for (i = 0; i < array_size(exists); i++) {
11533  exists[i] = SQL_FALSE;
11534  }
11535  exists[SQL_API_SQLALLOCCONNECT] = SQL_TRUE;
11536  exists[SQL_API_SQLFETCH] = SQL_TRUE;
11537  exists[SQL_API_SQLALLOCENV] = SQL_TRUE;
11538  exists[SQL_API_SQLFREECONNECT] = SQL_TRUE;
11539  exists[SQL_API_SQLALLOCSTMT] = SQL_TRUE;
11540  exists[SQL_API_SQLFREEENV] = SQL_TRUE;
11541  exists[SQL_API_SQLBINDCOL] = SQL_TRUE;
11542  exists[SQL_API_SQLFREESTMT] = SQL_TRUE;
11543  exists[SQL_API_SQLCANCEL] = SQL_TRUE;
11544  exists[SQL_API_SQLGETCURSORNAME] = SQL_TRUE;
11545  exists[SQL_API_SQLCOLATTRIBUTES] = SQL_TRUE;
11546  exists[SQL_API_SQLNUMRESULTCOLS] = SQL_TRUE;
11547  exists[SQL_API_SQLCONNECT] = SQL_TRUE;
11548  exists[SQL_API_SQLPREPARE] = SQL_TRUE;
11549  exists[SQL_API_SQLDESCRIBECOL] = SQL_TRUE;
11550  exists[SQL_API_SQLROWCOUNT] = SQL_TRUE;
11551  exists[SQL_API_SQLDISCONNECT] = SQL_TRUE;
11552  exists[SQL_API_SQLSETCURSORNAME] = SQL_FALSE;
11553  exists[SQL_API_SQLERROR] = SQL_TRUE;
11554  exists[SQL_API_SQLSETPARAM] = SQL_TRUE;
11555  exists[SQL_API_SQLEXECDIRECT] = SQL_TRUE;
11556  exists[SQL_API_SQLTRANSACT] = SQL_TRUE;
11557  exists[SQL_API_SQLBULKOPERATIONS] = SQL_TRUE;
11558  exists[SQL_API_SQLEXECUTE] = SQL_TRUE;
11559  exists[SQL_API_SQLBINDPARAMETER] = SQL_TRUE;
11560  exists[SQL_API_SQLGETTYPEINFO] = SQL_TRUE;
11561  exists[SQL_API_SQLCOLUMNS] = SQL_TRUE;
11562  exists[SQL_API_SQLPARAMDATA] = SQL_TRUE;
11563  exists[SQL_API_SQLDRIVERCONNECT] = SQL_TRUE;
11564  exists[SQL_API_SQLPUTDATA] = SQL_TRUE;
11565  exists[SQL_API_SQLGETCONNECTOPTION] = SQL_TRUE;
11566  exists[SQL_API_SQLSETCONNECTOPTION] = SQL_TRUE;
11567  exists[SQL_API_SQLGETDATA] = SQL_TRUE;
11568  exists[SQL_API_SQLSETSTMTOPTION] = SQL_TRUE;
11569  exists[SQL_API_SQLGETFUNCTIONS] = SQL_TRUE;
11570  exists[SQL_API_SQLSPECIALCOLUMNS] = SQL_TRUE;
11571  exists[SQL_API_SQLGETINFO] = SQL_TRUE;
11572  exists[SQL_API_SQLSTATISTICS] = SQL_TRUE;
11573  exists[SQL_API_SQLGETSTMTOPTION] = SQL_TRUE;
11574  exists[SQL_API_SQLTABLES] = SQL_TRUE;
11575  exists[SQL_API_SQLBROWSECONNECT] = SQL_FALSE;
11576  exists[SQL_API_SQLNUMPARAMS] = SQL_TRUE;
11577  exists[SQL_API_SQLCOLUMNPRIVILEGES] = SQL_FALSE;
11578  exists[SQL_API_SQLPARAMOPTIONS] = SQL_FALSE;
11579  exists[SQL_API_SQLDATASOURCES] = SQL_TRUE;
11580  exists[SQL_API_SQLPRIMARYKEYS] = SQL_TRUE;
11581  exists[SQL_API_SQLDESCRIBEPARAM] = SQL_TRUE;
11582  exists[SQL_API_SQLPROCEDURECOLUMNS] = SQL_TRUE;
11583  exists[SQL_API_SQLDRIVERS] = SQL_FALSE;
11584  exists[SQL_API_SQLPROCEDURES] = SQL_TRUE;
11585  exists[SQL_API_SQLEXTENDEDFETCH] = SQL_TRUE;
11586  exists[SQL_API_SQLSETPOS] = SQL_TRUE;
11587  exists[SQL_API_SQLFOREIGNKEYS] = SQL_TRUE;
11588  exists[SQL_API_SQLSETSCROLLOPTIONS] = SQL_TRUE;
11589  exists[SQL_API_SQLMORERESULTS] = SQL_TRUE;
11590  exists[SQL_API_SQLTABLEPRIVILEGES] = SQL_TRUE;
11591  exists[SQL_API_SQLNATIVESQL] = SQL_TRUE;
11592  if (func == SQL_API_ALL_FUNCTIONS) {
11593  memcpy(flags, exists, sizeof (exists));
11594  } else if (func == SQL_API_ODBC3_ALL_FUNCTIONS) {
11595  int i;
11596 #define SET_EXISTS(x) \
11597  flags[(x) >> 4] |= (1 << ((x) & 0xF))
11598 #define CLR_EXISTS(x) \
11599  flags[(x) >> 4] &= ~(1 << ((x) & 0xF))
11600 
11601  memset(flags, 0,
11602  sizeof (SQLUSMALLINT) * SQL_API_ODBC3_ALL_FUNCTIONS_SIZE);
11603  for (i = 0; i < array_size(exists); i++) {
11604  if (exists[i]) {
11605  flags[i >> 4] |= (1 << (i & 0xF));
11606  }
11607  }
11608  SET_EXISTS(SQL_API_SQLALLOCHANDLE);
11609  SET_EXISTS(SQL_API_SQLFREEHANDLE);
11610  SET_EXISTS(SQL_API_SQLGETSTMTATTR);
11611  SET_EXISTS(SQL_API_SQLSETSTMTATTR);
11612  SET_EXISTS(SQL_API_SQLGETCONNECTATTR);
11613  SET_EXISTS(SQL_API_SQLSETCONNECTATTR);
11614  SET_EXISTS(SQL_API_SQLGETENVATTR);
11615  SET_EXISTS(SQL_API_SQLSETENVATTR);
11616  SET_EXISTS(SQL_API_SQLCLOSECURSOR);
11617  SET_EXISTS(SQL_API_SQLBINDPARAM);
11618 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11619  /*
11620  * Some unixODBC versions have problems with
11621  * SQLError() vs. SQLGetDiagRec() with loss
11622  * of error/warning messages.
11623  */
11624  SET_EXISTS(SQL_API_SQLGETDIAGREC);
11625 #endif
11626  SET_EXISTS(SQL_API_SQLGETDIAGFIELD);
11627  SET_EXISTS(SQL_API_SQLFETCHSCROLL);
11628  SET_EXISTS(SQL_API_SQLENDTRAN);
11629  } else {
11630  if (func < array_size(exists)) {
11631  *flags = exists[func];
11632  } else {
11633  switch (func) {
11634  case SQL_API_SQLALLOCHANDLE:
11635  case SQL_API_SQLFREEHANDLE:
11636  case SQL_API_SQLGETSTMTATTR:
11637  case SQL_API_SQLSETSTMTATTR:
11638  case SQL_API_SQLGETCONNECTATTR:
11639  case SQL_API_SQLSETCONNECTATTR:
11640  case SQL_API_SQLGETENVATTR:
11641  case SQL_API_SQLSETENVATTR:
11642  case SQL_API_SQLCLOSECURSOR:
11643  case SQL_API_SQLBINDPARAM:
11644 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11645  /*
11646  * Some unixODBC versions have problems with
11647  * SQLError() vs. SQLGetDiagRec() with loss
11648  * of error/warning messages.
11649  */
11650  case SQL_API_SQLGETDIAGREC:
11651 #endif
11652  case SQL_API_SQLGETDIAGFIELD:
11653  case SQL_API_SQLFETCHSCROLL:
11654  case SQL_API_SQLENDTRAN:
11655  *flags = SQL_TRUE;
11656  break;
11657  default:
11658  *flags = SQL_FALSE;
11659  }
11660  }
11661  }
11662  return SQL_SUCCESS;
11663 }
11664 
11671 static SQLRETURN
11672 drvallocenv(SQLHENV *env)
11673 {
11674  ENV *e;
11675 
11676  if (env == NULL) {
11677  return SQL_INVALID_HANDLE;
11678  }
11679  e = (ENV *) xmalloc(sizeof (ENV));
11680  if (e == NULL) {
11681  *env = SQL_NULL_HENV;
11682  return SQL_ERROR;
11683  }
11684  e->magic = ENV_MAGIC;
11685  e->ov3 = 0;
11686 #if defined(_WIN32) || defined(_WIN64)
11687  InitializeCriticalSection(&e->cs);
11688 #else
11689 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
11690  nvfs_init();
11691 #endif
11692 #endif
11693  e->dbcs = NULL;
11694  *env = (SQLHENV) e;
11695  return SQL_SUCCESS;
11696 }
11697 
11704 SQLRETURN SQL_API
11705 SQLAllocEnv(SQLHENV *env)
11706 {
11707  return drvallocenv(env);
11708 }
11709 
11716 static SQLRETURN
11717 drvfreeenv(SQLHENV env)
11718 {
11719  ENV *e;
11720 
11721  if (env == SQL_NULL_HENV) {
11722  return SQL_INVALID_HANDLE;
11723  }
11724  e = (ENV *) env;
11725  if (e->magic != ENV_MAGIC) {
11726  return SQL_SUCCESS;
11727  }
11728 #if defined(_WIN32) || defined(_WIN64)
11729  EnterCriticalSection(&e->cs);
11730 #endif
11731  if (e->dbcs) {
11732 #if defined(_WIN32) || defined(_WIN64)
11733  LeaveCriticalSection(&e->cs);
11734 #endif
11735  return SQL_ERROR;
11736  }
11737  e->magic = DEAD_MAGIC;
11738 #if defined(_WIN32) || defined(_WIN64)
11739  LeaveCriticalSection(&e->cs);
11740  DeleteCriticalSection(&e->cs);
11741 #endif
11742  xfree(e);
11743  return SQL_SUCCESS;
11744 }
11745 
11752 SQLRETURN SQL_API
11753 SQLFreeEnv(SQLHENV env)
11754 {
11755  return drvfreeenv(env);
11756 }
11757 
11765 static SQLRETURN
11766 drvallocconnect(SQLHENV env, SQLHDBC *dbc)
11767 {
11768  DBC *d;
11769  ENV *e;
11770  const char *verstr;
11771  int maj = 0, min = 0, lev = 0;
11772 
11773  if (dbc == NULL) {
11774  return SQL_ERROR;
11775  }
11776  d = (DBC *) xmalloc(sizeof (DBC));
11777  if (d == NULL) {
11778  *dbc = SQL_NULL_HDBC;
11779  return SQL_ERROR;
11780  }
11781  memset(d, 0, sizeof (DBC));
11782  d->curtype = SQL_CURSOR_STATIC;
11783  d->ov3 = &d->ov3val;
11784  verstr = sqlite3_libversion();
11785  sscanf(verstr, "%d.%d.%d", &maj, &min, &lev);
11786  d->version = verinfo(maj & 0xFF, min & 0xFF, lev & 0xFF);
11787  e = (ENV *) env;
11788 #if defined(_WIN32) || defined(_WIN64)
11789  if (e->magic == ENV_MAGIC) {
11790  EnterCriticalSection(&e->cs);
11791  }
11792 #endif
11793  if (e->magic == ENV_MAGIC) {
11794  DBC *n, *p;
11795 
11796  d->env = e;
11797  d->ov3 = &e->ov3;
11798  p = NULL;
11799  n = e->dbcs;
11800  while (n) {
11801  p = n;
11802  n = n->next;
11803  }
11804  if (p) {
11805  p->next = d;
11806  } else {
11807  e->dbcs = d;
11808  }
11809  }
11810 #if defined(_WIN32) || defined(_WIN64)
11811  InitializeCriticalSection(&d->cs);
11812  d->owner = 0;
11813  if (e->magic == ENV_MAGIC) {
11814  LeaveCriticalSection(&e->cs);
11815  }
11816  d->oemcp = 1;
11817 #endif
11818  d->autocommit = 1;
11819  d->magic = DBC_MAGIC;
11820  *dbc = (SQLHDBC) d;
11821  drvgetgpps(d);
11822  return SQL_SUCCESS;
11823 }
11824 
11832 SQLRETURN SQL_API
11833 SQLAllocConnect(SQLHENV env, SQLHDBC *dbc)
11834 {
11835  return drvallocconnect(env, dbc);
11836 }
11837 
11844 static SQLRETURN
11846 {
11847  DBC *d;
11848  ENV *e;
11849  SQLRETURN ret = SQL_ERROR;
11850 
11851  if (dbc == SQL_NULL_HDBC) {
11852  return SQL_INVALID_HANDLE;
11853  }
11854  d = (DBC *) dbc;
11855  if (d->magic != DBC_MAGIC) {
11856  return SQL_INVALID_HANDLE;
11857  }
11858  e = d->env;
11859  if (e && e->magic == ENV_MAGIC) {
11860 #if defined(_WIN32) || defined(_WIN64)
11861  EnterCriticalSection(&e->cs);
11862 #endif
11863  } else {
11864  e = NULL;
11865  }
11866  HDBC_LOCK(dbc);
11867  if (d->sqlite) {
11868  setstatd(d, -1, "not disconnected", (*d->ov3) ? "HY000" : "S1000");
11869  HDBC_UNLOCK(dbc);
11870  goto done;
11871  }
11872  while (d->stmt) {
11873  freestmt((HSTMT) d->stmt);
11874  }
11875  if (e && e->magic == ENV_MAGIC) {
11876  DBC *n, *p;
11877 
11878  p = NULL;
11879  n = e->dbcs;
11880  while (n) {
11881  if (n == d) {
11882  break;
11883  }
11884  p = n;
11885  n = n->next;
11886  }
11887  if (n) {
11888  if (p) {
11889  p->next = d->next;
11890  } else {
11891  e->dbcs = d->next;
11892  }
11893  }
11894  }
11895  drvrelgpps(d);
11896  d->magic = DEAD_MAGIC;
11897  if (d->trace) {
11898  fclose(d->trace);
11899  }
11900 #if defined(_WIN32) || defined(_WIN64)
11901  d->owner = 0;
11902  LeaveCriticalSection(&d->cs);
11903  DeleteCriticalSection(&d->cs);
11904 #endif
11905  xfree(d);
11906  ret = SQL_SUCCESS;
11907 done:
11908 #if defined(_WIN32) || defined(_WIN64)
11909  if (e) {
11910  LeaveCriticalSection(&e->cs);
11911  }
11912 #endif
11913  return ret;
11914 }
11915 
11922 SQLRETURN SQL_API
11924 {
11925  return drvfreeconnect(dbc);
11926 }
11927 
11938 static SQLRETURN
11939 drvgetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
11940  SQLINTEGER bufmax, SQLINTEGER *buflen)
11941 {
11942  DBC *d;
11943  SQLINTEGER dummy;
11944 
11945  if (dbc == SQL_NULL_HDBC) {
11946  return SQL_INVALID_HANDLE;
11947  }
11948  d = (DBC *) dbc;
11949  if (!val) {
11950  val = (SQLPOINTER) &dummy;
11951  }
11952  if (!buflen) {
11953  buflen = &dummy;
11954  }
11955  switch (attr) {
11956  case SQL_ATTR_CONNECTION_DEAD:
11957  *((SQLINTEGER *) val) = d->sqlite ? SQL_CD_FALSE : SQL_CD_TRUE;
11958  *buflen = sizeof (SQLINTEGER);
11959  break;
11960  case SQL_ATTR_ACCESS_MODE:
11961  *((SQLINTEGER *) val) = SQL_MODE_READ_WRITE;
11962  *buflen = sizeof (SQLINTEGER);
11963  break;
11964  case SQL_ATTR_AUTOCOMMIT:
11965  *((SQLINTEGER *) val) =
11966  d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
11967  *buflen = sizeof (SQLINTEGER);
11968  break;
11969  case SQL_ATTR_LOGIN_TIMEOUT:
11970  *((SQLINTEGER *) val) = 100;
11971  *buflen = sizeof (SQLINTEGER);
11972  break;
11973  case SQL_ATTR_ODBC_CURSORS:
11974  *((SQLINTEGER *) val) = SQL_CUR_USE_DRIVER;
11975  *buflen = sizeof (SQLINTEGER);
11976  break;
11977  case SQL_ATTR_PACKET_SIZE:
11978  *((SQLINTEGER *) val) = 16384;
11979  *buflen = sizeof (SQLINTEGER);
11980  break;
11981  case SQL_ATTR_TXN_ISOLATION:
11982  *((SQLINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11983  *buflen = sizeof (SQLINTEGER);
11984  break;
11985  case SQL_ATTR_TRACEFILE:
11986  case SQL_ATTR_TRANSLATE_LIB:
11987  *((SQLCHAR *) val) = 0;
11988  *buflen = 0;
11989  break;
11990  case SQL_ATTR_CURRENT_CATALOG:
11991 #if defined(_WIN32) || defined(_WIN64)
11992  if (d->xcelqrx) {
11993  if ((bufmax > 4) && (val != (SQLPOINTER) &dummy)) {
11994  strcpy((char *) val, "main");
11995  *buflen = 4;
11996  break;
11997  }
11998  }
11999 #endif
12000  *((SQLCHAR *) val) = 0;
12001  *buflen = 0;
12002  break;
12003  case SQL_ATTR_TRACE:
12004  case SQL_ATTR_QUIET_MODE:
12005  case SQL_ATTR_TRANSLATE_OPTION:
12006  case SQL_ATTR_KEYSET_SIZE:
12007  case SQL_ATTR_QUERY_TIMEOUT:
12008  *((SQLINTEGER *) val) = 0;
12009  *buflen = sizeof (SQLINTEGER);
12010  break;
12011  case SQL_ATTR_PARAM_BIND_TYPE:
12012  *((SQLULEN *) val) = SQL_PARAM_BIND_BY_COLUMN;
12013  *buflen = sizeof (SQLUINTEGER);
12014  break;
12015  case SQL_ATTR_ROW_BIND_TYPE:
12016  *((SQLULEN *) val) = SQL_BIND_BY_COLUMN;
12017  *buflen = sizeof (SQLULEN);
12018  break;
12019  case SQL_ATTR_USE_BOOKMARKS:
12020  *((SQLINTEGER *) val) = SQL_UB_OFF;
12021  *buflen = sizeof (SQLINTEGER);
12022  break;
12023  case SQL_ATTR_ASYNC_ENABLE:
12024  *((SQLINTEGER *) val) = SQL_ASYNC_ENABLE_OFF;
12025  *buflen = sizeof (SQLINTEGER);
12026  break;
12027  case SQL_ATTR_NOSCAN:
12028  *((SQLINTEGER *) val) = SQL_NOSCAN_ON;
12029  *buflen = sizeof (SQLINTEGER);
12030  break;
12031  case SQL_ATTR_CONCURRENCY:
12032  *((SQLINTEGER *) val) = SQL_CONCUR_LOCK;
12033  *buflen = sizeof (SQLINTEGER);
12034  break;
12035 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
12036  case SQL_ATTR_CURSOR_SENSITIVITY:
12037  *((SQLINTEGER *) val) = SQL_UNSPECIFIED;
12038  *buflen = sizeof (SQLINTEGER);
12039  break;
12040 #endif
12041  case SQL_ATTR_SIMULATE_CURSOR:
12042  *((SQLINTEGER *) val) = SQL_SC_NON_UNIQUE;
12043  *buflen = sizeof (SQLINTEGER);
12044  break;
12045  case SQL_ATTR_MAX_ROWS:
12046  *((SQLINTEGER *) val) = 0;
12047  *buflen = sizeof (SQLINTEGER);
12048  case SQL_ATTR_MAX_LENGTH:
12049  *((SQLINTEGER *) val) = 1000000000;
12050  *buflen = sizeof (SQLINTEGER);
12051  break;
12052  case SQL_ATTR_CURSOR_TYPE:
12053  *((SQLINTEGER *) val) = d->curtype;
12054  *buflen = sizeof (SQLINTEGER);
12055  break;
12056  case SQL_ATTR_RETRIEVE_DATA:
12057  *((SQLINTEGER *) val) = SQL_RD_ON;
12058  *buflen = sizeof (SQLINTEGER);
12059  break;
12060 #ifdef SQL_ATTR_METADATA_ID
12061  case SQL_ATTR_METADATA_ID:
12062  *((SQLULEN *) val) = SQL_FALSE;
12063  return SQL_SUCCESS;
12064 #endif
12065  default:
12066  *((SQLINTEGER *) val) = 0;
12067  *buflen = sizeof (SQLINTEGER);
12068  setstatd(d, -1, "unsupported connect attribute %d",
12069  (*d->ov3) ? "HYC00" : "S1C00", (int) attr);
12070  return SQL_ERROR;
12071  }
12072  return SQL_SUCCESS;
12073 }
12074 
12075 #ifndef WINTERFACE
12076 
12086 SQLRETURN SQL_API
12087 SQLGetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12088  SQLINTEGER bufmax, SQLINTEGER *buflen)
12089 {
12090  SQLRETURN ret;
12091 
12092  HDBC_LOCK(dbc);
12093  ret = drvgetconnectattr(dbc, attr, val, bufmax, buflen);
12094  HDBC_UNLOCK(dbc);
12095  return ret;
12096 }
12097 #endif
12098 
12099 #ifdef WINTERFACE
12100 
12110 SQLRETURN SQL_API
12111 SQLGetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12112  SQLINTEGER bufmax, SQLINTEGER *buflen)
12113 {
12114  SQLRETURN ret;
12115  SQLINTEGER len = 0;
12116 
12117  HDBC_LOCK(dbc);
12118  ret = drvgetconnectattr(dbc, attr, val, bufmax, &len);
12119  if (ret == SQL_SUCCESS) {
12120  SQLWCHAR *v = NULL;
12121 
12122  switch (attr) {
12123  case SQL_ATTR_TRACEFILE:
12124  case SQL_ATTR_CURRENT_CATALOG:
12125  case SQL_ATTR_TRANSLATE_LIB:
12126  if (val) {
12127  if (len > 0) {
12128  v = uc_from_utf((SQLCHAR *) val, len);
12129  if (v) {
12130  int vmax = bufmax / sizeof (SQLWCHAR);
12131 
12132  uc_strncpy(val, v, vmax);
12133  if (len < vmax) {
12134  len = min(vmax, uc_strlen(v));
12135  v[len] = 0;
12136  } else {
12137  len = vmax;
12138  }
12139  uc_free(v);
12140  len *= sizeof (SQLWCHAR);
12141  } else {
12142  len = 0;
12143  }
12144  }
12145  if (len <= 0) {
12146  len = 0;
12147  if (bufmax >= sizeof (SQLWCHAR)) {
12148  *((SQLWCHAR *)val) = 0;
12149  }
12150  }
12151  } else {
12152  len *= sizeof (SQLWCHAR);
12153  }
12154  break;
12155  }
12156  if (buflen) {
12157  *buflen = len;
12158  }
12159  }
12160  HDBC_UNLOCK(dbc);
12161  return ret;
12162 }
12163 #endif
12164 
12174 static SQLRETURN
12175 drvsetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12176  SQLINTEGER len)
12177 {
12178  DBC *d;
12179 
12180  if (dbc == SQL_NULL_HDBC) {
12181  return SQL_INVALID_HANDLE;
12182  }
12183  d = (DBC *) dbc;
12184  switch (attr) {
12185  case SQL_AUTOCOMMIT:
12186  d->autocommit = val == (SQLPOINTER) SQL_AUTOCOMMIT_ON;
12187  if (d->autocommit && d->intrans) {
12188  return endtran(d, SQL_COMMIT, 1);
12189  } else if (!d->autocommit) {
12190  s3stmt_end(d->cur_s3stmt);
12191  }
12192  break;
12193  return SQL_SUCCESS;
12194 #ifdef SQL_ATTR_METADATA_ID
12195  case SQL_ATTR_METADATA_ID:
12196  if (val == (SQLPOINTER) SQL_FALSE) {
12197  break;
12198  }
12199  /* fall through */
12200 #endif
12201  default:
12202  setstatd(d, -1, "option value changed", "01S02");
12203  return SQL_SUCCESS_WITH_INFO;
12204  }
12205  return SQL_SUCCESS;
12206 }
12207 
12208 #ifndef WINTERFACE
12209 
12218 SQLRETURN SQL_API
12219 SQLSetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12220  SQLINTEGER len)
12221 {
12222  SQLRETURN ret;
12223 
12224  HDBC_LOCK(dbc);
12225  ret = drvsetconnectattr(dbc, attr, val, len);
12226  HDBC_UNLOCK(dbc);
12227  return ret;
12228 }
12229 #endif
12230 
12231 #ifdef WINTERFACE
12232 
12241 SQLRETURN SQL_API
12242 SQLSetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12243  SQLINTEGER len)
12244 {
12245  SQLRETURN ret;
12246 
12247  HDBC_LOCK(dbc);
12248  ret = drvsetconnectattr(dbc, attr, val, len);
12249  HDBC_UNLOCK(dbc);
12250  return ret;
12251 }
12252 #endif
12253 
12262 static SQLRETURN
12263 drvgetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12264 {
12265  DBC *d;
12266  SQLINTEGER dummy;
12267 
12268  if (dbc == SQL_NULL_HDBC) {
12269  return SQL_INVALID_HANDLE;
12270  }
12271  d = (DBC *) dbc;
12272  if (!param) {
12273  param = (SQLPOINTER) &dummy;
12274  }
12275  switch (opt) {
12276  case SQL_ACCESS_MODE:
12277  *((SQLINTEGER *) param) = SQL_MODE_READ_WRITE;
12278  break;
12279  case SQL_AUTOCOMMIT:
12280  *((SQLINTEGER *) param) =
12281  d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
12282  break;
12283  case SQL_LOGIN_TIMEOUT:
12284  *((SQLINTEGER *) param) = 100;
12285  break;
12286  case SQL_ODBC_CURSORS:
12287  *((SQLINTEGER *) param) = SQL_CUR_USE_DRIVER;
12288  break;
12289  case SQL_PACKET_SIZE:
12290  *((SQLINTEGER *) param) = 16384;
12291  break;
12292  case SQL_TXN_ISOLATION:
12293  *((SQLINTEGER *) param) = SQL_TXN_SERIALIZABLE;
12294  break;
12295  case SQL_OPT_TRACE:
12296  case SQL_OPT_TRACEFILE:
12297  case SQL_QUIET_MODE:
12298  case SQL_TRANSLATE_DLL:
12299  case SQL_TRANSLATE_OPTION:
12300  case SQL_KEYSET_SIZE:
12301  case SQL_QUERY_TIMEOUT:
12302  case SQL_BIND_TYPE:
12303  case SQL_CURRENT_QUALIFIER:
12304  *((SQLINTEGER *) param) = 0;
12305  break;
12306  case SQL_USE_BOOKMARKS:
12307  *((SQLINTEGER *) param) = SQL_UB_OFF;
12308  break;
12309  case SQL_ASYNC_ENABLE:
12310  *((SQLINTEGER *) param) = SQL_ASYNC_ENABLE_OFF;
12311  break;
12312  case SQL_NOSCAN:
12313  *((SQLINTEGER *) param) = SQL_NOSCAN_ON;
12314  break;
12315  case SQL_CONCURRENCY:
12316  *((SQLINTEGER *) param) = SQL_CONCUR_LOCK;
12317  break;
12318  case SQL_SIMULATE_CURSOR:
12319  *((SQLINTEGER *) param) = SQL_SC_NON_UNIQUE;
12320  break;
12321  case SQL_MAX_ROWS:
12322  *((SQLINTEGER *) param) = 0;
12323  break;
12324  case SQL_ROWSET_SIZE:
12325  case SQL_MAX_LENGTH:
12326  *((SQLINTEGER *) param) = 1000000000;
12327  break;
12328  case SQL_CURSOR_TYPE:
12329  *((SQLINTEGER *) param) = d->curtype;
12330  break;
12331  case SQL_RETRIEVE_DATA:
12332  *((SQLINTEGER *) param) = SQL_RD_ON;
12333  break;
12334  default:
12335  *((SQLINTEGER *) param) = 0;
12336  setstatd(d, -1, "unsupported connect option %d",
12337  (*d->ov3) ? "HYC00" : "S1C00", opt);
12338  return SQL_ERROR;
12339  }
12340  return SQL_SUCCESS;
12341 }
12342 
12343 #ifndef WINTERFACE
12344 
12352 SQLRETURN SQL_API
12353 SQLGetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12354 {
12355  SQLRETURN ret;
12356 
12357  HDBC_LOCK(dbc);
12358  ret = drvgetconnectoption(dbc, opt, param);
12359  HDBC_UNLOCK(dbc);
12360  return ret;
12361 }
12362 #endif
12363 
12364 #ifdef WINTERFACE
12365 
12373 SQLRETURN SQL_API
12374 SQLGetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12375 {
12376  SQLRETURN ret;
12377 
12378  HDBC_LOCK(dbc);
12379  ret = drvgetconnectoption(dbc, opt, param);
12380  if (SQL_SUCCEEDED(ret)) {
12381  switch (opt) {
12382  case SQL_OPT_TRACEFILE:
12383  case SQL_CURRENT_QUALIFIER:
12384  case SQL_TRANSLATE_DLL:
12385  if (param) {
12386  *(SQLWCHAR *) param = 0;
12387  }
12388  break;
12389  }
12390  }
12391  HDBC_UNLOCK(dbc);
12392  return ret;
12393 }
12394 #endif
12395 
12404 static SQLRETURN
12405 drvsetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
12406 {
12407  DBC *d;
12408 
12409  if (dbc == SQL_NULL_HDBC) {
12410  return SQL_INVALID_HANDLE;
12411  }
12412  d = (DBC *) dbc;
12413  switch (opt) {
12414  case SQL_AUTOCOMMIT:
12415  d->autocommit = param == SQL_AUTOCOMMIT_ON;
12416  if (d->autocommit && d->intrans) {
12417  return endtran(d, SQL_COMMIT, 1);
12418  } else if (!d->autocommit) {
12419  s3stmt_end(d->cur_s3stmt);
12420  }
12421  break;
12422  default:
12423  setstatd(d, -1, "option value changed", "01S02");
12424  return SQL_SUCCESS_WITH_INFO;
12425  }
12426  return SQL_SUCCESS;
12427 }
12428 
12429 #ifndef WINTERFACE
12430 
12438 SQLRETURN SQL_API
12439 SQLSetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12440 {
12441  SQLRETURN ret;
12442 
12443  HDBC_LOCK(dbc);
12444  ret = drvsetconnectoption(dbc, opt, param);
12445  HDBC_UNLOCK(dbc);
12446  return ret;
12447 }
12448 #endif
12449 
12450 #ifdef WINTERFACE
12451 
12459 SQLRETURN SQL_API
12460 SQLSetConnectOptionW(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 #if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
12472 
12483 static int
12484 getdsnattr(char *dsn, char *attr, char *out, int outLen)
12485 {
12486  char *str = dsn, *start;
12487  int len = strlen(attr);
12488 
12489  while (*str) {
12490  while (*str && *str == ';') {
12491  ++str;
12492  }
12493  start = str;
12494  if ((str = strchr(str, '=')) == NULL) {
12495  return 0;
12496  }
12497  if (str - start == len && strncasecmp(start, attr, len) == 0) {
12498  start = ++str;
12499  while (*str && *str != ';') {
12500  ++str;
12501  }
12502  len = min(outLen - 1, str - start);
12503  strncpy(out, start, len);
12504  out[len] = '\0';
12505  return 1;
12506  }
12507  while (*str && *str != ';') {
12508  ++str;
12509  }
12510  }
12511  return 0;
12512 }
12513 #endif
12514 
12526 static SQLRETURN
12527 drvconnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen, char *pwd,
12528  int pwdLen, int isu)
12529 {
12530  DBC *d;
12531  int len;
12532  SQLRETURN ret;
12533  char buf[SQL_MAX_MESSAGE_LENGTH], dbname[SQL_MAX_MESSAGE_LENGTH / 4];
12534  char busy[SQL_MAX_MESSAGE_LENGTH / 4], tracef[SQL_MAX_MESSAGE_LENGTH];
12535  char loadext[SQL_MAX_MESSAGE_LENGTH];
12536  char sflag[32], spflag[32], ntflag[32], nwflag[32], biflag[32];
12537  char snflag[32], lnflag[32], ncflag[32], fkflag[32], jmode[32];
12538  char jdflag[32];
12539 #if defined(_WIN32) || defined(_WIN64)
12540  char oemcp[32];
12541 #endif
12542 
12543  if (dbc == SQL_NULL_HDBC) {
12544  return SQL_INVALID_HANDLE;
12545  }
12546  d = (DBC *) dbc;
12547  if (d->magic != DBC_MAGIC) {
12548  return SQL_INVALID_HANDLE;
12549  }
12550  if (d->sqlite != NULL) {
12551  setstatd(d, -1, "connection already established", "08002");
12552  return SQL_ERROR;
12553  }
12554  buf[0] = '\0';
12555  if (dsnLen == SQL_NTS) {
12556  len = sizeof (buf) - 1;
12557  } else {
12558  len = min(sizeof (buf) - 1, dsnLen);
12559  }
12560  if (dsn != NULL) {
12561  strncpy(buf, (char *) dsn, len);
12562  }
12563  buf[len] = '\0';
12564  if (buf[0] == '\0') {
12565  setstatd(d, -1, "invalid DSN", (*d->ov3) ? "HY090" : "S1090");
12566  return SQL_ERROR;
12567  }
12568 #if defined(_WIN32) || defined(_WIN64)
12569  /*
12570  * When DSN is in UTF it must be converted to ANSI
12571  * here for ANSI SQLGetPrivateProfileString()
12572  */
12573  if (isu) {
12574  char *cdsn = utf_to_wmb(buf, len);
12575 
12576  if (!cdsn) {
12577  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12578  return SQL_ERROR;
12579  }
12580  strcpy(buf, cdsn);
12581  uc_free(cdsn);
12582  }
12583 #endif
12584  busy[0] = '\0';
12585  dbname[0] = '\0';
12586 #ifdef WITHOUT_DRIVERMGR
12587  getdsnattr(buf, "database", dbname, sizeof (dbname));
12588  if (dbname[0] == '\0') {
12589  strncpy(dbname, buf, sizeof (dbname));
12590  dbname[sizeof (dbname) - 1] = '\0';
12591  }
12592  getdsnattr(buf, "timeout", busy, sizeof (busy));
12593  sflag[0] = '\0';
12594  getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
12595  spflag[0] = '\0';
12596  getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
12597  ntflag[0] = '\0';
12598  getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
12599  nwflag[0] = '\0';
12600  getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
12601  snflag[0] = '\0';
12602  getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
12603  lnflag[0] = '\0';
12604  getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
12605  ncflag[0] = '\0';
12606  getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
12607  fkflag[0] = '\0';
12608  getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
12609  loadext[0] = '\0';
12610  getdsnattr(buf, "loadext", loadext, sizeof (loadext));
12611  jmode[0] = '\0';
12612  getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
12613  jdflag[0] = '\0';
12614  getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
12615 #if defined(_WIN32) || defined(_WIN64)
12616  oemcp[0] = '\0';
12617  getdsnattr(buf, "oemcp", oemcp, sizeof (oemcp));
12618 #endif
12619  biflag[0] = '\0';
12620  getdsnattr(buf, "bigint", biflag, sizeof (biflag));
12621 #else
12622  SQLGetPrivateProfileString(buf, "timeout", "100000",
12623  busy, sizeof (busy), ODBC_INI);
12624  SQLGetPrivateProfileString(buf, "database", "",
12625  dbname, sizeof (dbname), ODBC_INI);
12626 #if defined(_WIN32) || defined(_WIN64)
12627  /* database name read from registry is not UTF8 !!! */
12628  isu = 0;
12629 #endif
12630  SQLGetPrivateProfileString(buf, "stepapi", "",
12631  sflag, sizeof (sflag), ODBC_INI);
12632  SQLGetPrivateProfileString(buf, "syncpragma", "NORMAL",
12633  spflag, sizeof (spflag), ODBC_INI);
12634  SQLGetPrivateProfileString(buf, "notxn", "",
12635  ntflag, sizeof (ntflag), ODBC_INI);
12636  SQLGetPrivateProfileString(buf, "nowchar", "",
12637  nwflag, sizeof (nwflag), ODBC_INI);
12638  SQLGetPrivateProfileString(buf, "shortnames", "",
12639  snflag, sizeof (snflag), ODBC_INI);
12640  SQLGetPrivateProfileString(buf, "longnames", "",
12641  lnflag, sizeof (lnflag), ODBC_INI);
12642  SQLGetPrivateProfileString(buf, "nocreat", "",
12643  ncflag, sizeof (ncflag), ODBC_INI);
12644  SQLGetPrivateProfileString(buf, "fksupport", "",
12645  fkflag, sizeof (fkflag), ODBC_INI);
12646  SQLGetPrivateProfileString(buf, "loadext", "",
12647  loadext, sizeof (loadext), ODBC_INI);
12648  SQLGetPrivateProfileString(buf, "journalmode", "",
12649  jmode, sizeof (jmode), ODBC_INI);
12650  SQLGetPrivateProfileString(buf, "jdconv", "",
12651  jdflag, sizeof (jdflag), ODBC_INI);
12652 #if defined(_WIN32) || defined(_WIN64)
12653  SQLGetPrivateProfileString(buf, "oemcp", "1",
12654  oemcp, sizeof (oemcp), ODBC_INI);
12655 #endif
12656  SQLGetPrivateProfileString(buf, "bigint", "",
12657  biflag, sizeof (biflag), ODBC_INI);
12658 #endif
12659  tracef[0] = '\0';
12660 #ifdef WITHOUT_DRIVERMGR
12661  getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
12662 #else
12663  SQLGetPrivateProfileString(buf, "tracefile", "",
12664  tracef, sizeof (tracef), ODBC_INI);
12665 #endif
12666  if (tracef[0] != '\0') {
12667  d->trace = fopen(tracef, "a");
12668  }
12669  d->nowchar = getbool(nwflag);
12670  d->shortnames = getbool(snflag);
12671  d->longnames = getbool(lnflag);
12672  d->nocreat = getbool(ncflag);
12673  d->fksupport = getbool(fkflag);
12674  d->jdconv = getbool(jdflag);
12675 #if defined(_WIN32) || defined(_WIN64)
12676  d->oemcp = getbool(oemcp);
12677 #else
12678  d->oemcp = 0;
12679 #endif
12680  d->dobigint = getbool(biflag);
12681  d->pwd = pwd;
12682  d->pwdLen = 0;
12683  if (d->pwd) {
12684  d->pwdLen = (pwdLen == SQL_NTS) ? strlen(d->pwd) : pwdLen;
12685  }
12686  ret = dbopen(d, dbname, isu, (char *) dsn, sflag, spflag, ntflag,
12687  jmode, busy);
12688  if (ret == SQL_SUCCESS) {
12689  dbloadext(d, loadext);
12690  }
12691  return ret;
12692 }
12693 
12694 #ifndef WINTERFACE
12695 
12707 SQLRETURN SQL_API
12708 SQLConnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen,
12709  SQLCHAR *uid, SQLSMALLINT uidLen,
12710  SQLCHAR *pwd, SQLSMALLINT pwdLen)
12711 {
12712  SQLRETURN ret;
12713 
12714  HDBC_LOCK(dbc);
12715  ret = drvconnect(dbc, dsn, dsnLen, (char *) pwd, pwdLen, 0);
12716  HDBC_UNLOCK(dbc);
12717  return ret;
12718 }
12719 #endif
12720 
12721 #ifdef WINTERFACE
12722 
12734 SQLRETURN SQL_API
12735 SQLConnectW(SQLHDBC dbc, SQLWCHAR *dsn, SQLSMALLINT dsnLen,
12736  SQLWCHAR *uid, SQLSMALLINT uidLen,
12737  SQLWCHAR *pwd, SQLSMALLINT pwdLen)
12738 {
12739  char *dsna = NULL;
12740  char *pwda = NULL;
12741  SQLRETURN ret;
12742 
12743  HDBC_LOCK(dbc);
12744  if (dsn) {
12745  dsna = uc_to_utf_c(dsn, dsnLen);
12746  if (!dsna) {
12747  DBC *d = (DBC *) dbc;
12748 
12749  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12750  ret = SQL_ERROR;
12751  goto done;
12752  }
12753  }
12754  if (pwd) {
12755  pwda = uc_to_utf_c(pwd, pwdLen);
12756  if (!pwda) {
12757  DBC *d = (DBC *) dbc;
12758 
12759  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12760  ret = SQL_ERROR;
12761  goto done;
12762  }
12763  }
12764  ret = drvconnect(dbc, (SQLCHAR *) dsna, SQL_NTS, pwda, SQL_NTS, 1);
12765 done:
12766  HDBC_UNLOCK(dbc);
12767  uc_free(dsna);
12768  uc_free(pwda);
12769  return ret;
12770 }
12771 #endif
12772 
12779 static SQLRETURN
12780 drvdisconnect(SQLHDBC dbc)
12781 {
12782  DBC *d;
12783  int rc;
12784 
12785  if (dbc == SQL_NULL_HDBC) {
12786  return SQL_INVALID_HANDLE;
12787  }
12788  d = (DBC *) dbc;
12789  if (d->magic != DBC_MAGIC) {
12790  return SQL_INVALID_HANDLE;
12791  }
12792  if (d->intrans) {
12793  setstatd(d, -1, "incomplete transaction", "25000");
12794  return SQL_ERROR;
12795  }
12796  if (d->cur_s3stmt) {
12797  s3stmt_end(d->cur_s3stmt);
12798  }
12799  if (d->sqlite) {
12800  if (d->trace) {
12801  fprintf(d->trace, "-- sqlite3_close: '%s'\n",
12802  d->dbname);
12803  fflush(d->trace);
12804  }
12805  rc = sqlite3_close(d->sqlite);
12806  if (rc == SQLITE_BUSY) {
12807  setstatd(d, -1, "unfinished statements", "25000");
12808  return SQL_ERROR;
12809  }
12810  d->sqlite = NULL;
12811  }
12812  freep(&d->dbname);
12813  freep(&d->dsn);
12814  return SQL_SUCCESS;
12815 }
12816 
12823 SQLRETURN SQL_API
12824 SQLDisconnect(SQLHDBC dbc)
12825 {
12826  SQLRETURN ret;
12827 
12828  HDBC_LOCK(dbc);
12829  ret = drvdisconnect(dbc);
12830  HDBC_UNLOCK(dbc);
12831  return ret;
12832 }
12833 
12834 #if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
12835 
12849 static SQLRETURN
12850 drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
12851  SQLCHAR *connIn, SQLSMALLINT connInLen,
12852  SQLCHAR *connOut, SQLSMALLINT connOutMax,
12853  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
12854 {
12855  DBC *d;
12856  int len;
12857  SQLRETURN ret;
12858  char buf[SQL_MAX_MESSAGE_LENGTH * 6], dbname[SQL_MAX_MESSAGE_LENGTH];
12859  char dsn[SQL_MAX_MESSAGE_LENGTH / 4], busy[SQL_MAX_MESSAGE_LENGTH / 4];
12860  char tracef[SQL_MAX_MESSAGE_LENGTH], loadext[SQL_MAX_MESSAGE_LENGTH];
12861  char pwd[SQL_MAX_MESSAGE_LENGTH];
12862  char sflag[32], spflag[32], ntflag[32], snflag[32], lnflag[32];
12863  char ncflag[32], nwflag[32], fkflag[32], jmode[32], biflag[32];
12864  char jdflag[32];
12865 
12866  if (dbc == SQL_NULL_HDBC) {
12867  return SQL_INVALID_HANDLE;
12868  }
12869  if (drvcompl != SQL_DRIVER_COMPLETE &&
12870  drvcompl != SQL_DRIVER_COMPLETE_REQUIRED &&
12871  drvcompl != SQL_DRIVER_PROMPT &&
12872  drvcompl != SQL_DRIVER_NOPROMPT) {
12873  return SQL_NO_DATA;
12874  }
12875  d = (DBC *) dbc;
12876  if (d->sqlite) {
12877  setstatd(d, -1, "connection already established", "08002");
12878  return SQL_ERROR;
12879  }
12880  buf[0] = '\0';
12881  if (connInLen == SQL_NTS) {
12882  len = sizeof (buf) - 1;
12883  } else {
12884  len = min(connInLen, sizeof (buf) - 1);
12885  }
12886  if (connIn != NULL) {
12887  strncpy(buf, (char *) connIn, len);
12888  }
12889  buf[len] = '\0';
12890  if (!buf[0]) {
12891  setstatd(d, -1, "invalid connect attributes",
12892  (*d->ov3) ? "HY090" : "S1090");
12893  return SQL_ERROR;
12894  }
12895  dsn[0] = '\0';
12896  getdsnattr(buf, "DSN", dsn, sizeof (dsn));
12897 
12898  /* special case: connIn is sole DSN value without keywords */
12899  if (!dsn[0] && !strchr(buf, ';') && !strchr(buf, '=')) {
12900  strncpy(dsn, buf, sizeof (dsn) - 1);
12901  dsn[sizeof (dsn) - 1] = '\0';
12902  }
12903 
12904  busy[0] = '\0';
12905  getdsnattr(buf, "timeout", busy, sizeof (busy));
12906 #ifndef WITHOUT_DRIVERMGR
12907  if (dsn[0] && !busy[0]) {
12908  SQLGetPrivateProfileString(dsn, "timeout", "100000",
12909  busy, sizeof (busy), ODBC_INI);
12910  }
12911 #endif
12912  dbname[0] = '\0';
12913  getdsnattr(buf, "database", dbname, sizeof (dbname));
12914 #ifndef WITHOUT_DRIVERMGR
12915  if (dsn[0] && !dbname[0]) {
12916  SQLGetPrivateProfileString(dsn, "database", "",
12917  dbname, sizeof (dbname), ODBC_INI);
12918  }
12919 #endif
12920  sflag[0] = '\0';
12921  getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
12922 #ifndef WITHOUT_DRIVERMGR
12923  if (dsn[0] && !sflag[0]) {
12924  SQLGetPrivateProfileString(dsn, "stepapi", "",
12925  sflag, sizeof (sflag), ODBC_INI);
12926  }
12927 #endif
12928  spflag[0] = '\0';
12929  getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
12930 #ifndef WITHOUT_DRIVERMGR
12931  if (dsn[0] && !spflag[0]) {
12932  SQLGetPrivateProfileString(dsn, "syncpragma", "NORMAL",
12933  spflag, sizeof (spflag), ODBC_INI);
12934  }
12935 #endif
12936  ntflag[0] = '\0';
12937  getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
12938 #ifndef WITHOUT_DRIVERMGR
12939  if (dsn[0] && !ntflag[0]) {
12940  SQLGetPrivateProfileString(dsn, "notxn", "",
12941  ntflag, sizeof (ntflag), ODBC_INI);
12942  }
12943 #endif
12944  snflag[0] = '\0';
12945  getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
12946 #ifndef WITHOUT_DRIVERMGR
12947  if (dsn[0] && !snflag[0]) {
12948  SQLGetPrivateProfileString(dsn, "shortnames", "",
12949  snflag, sizeof (snflag), ODBC_INI);
12950  }
12951 #endif
12952  lnflag[0] = '\0';
12953  getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
12954 #ifndef WITHOUT_DRIVERMGR
12955  if (dsn[0] && !lnflag[0]) {
12956  SQLGetPrivateProfileString(dsn, "longnames", "",
12957  lnflag, sizeof (lnflag), ODBC_INI);
12958  }
12959 #endif
12960  ncflag[0] = '\0';
12961  getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
12962 #ifndef WITHOUT_DRIVERMGR
12963  if (dsn[0] && !ncflag[0]) {
12964  SQLGetPrivateProfileString(dsn, "nocreat", "",
12965  ncflag, sizeof (ncflag), ODBC_INI);
12966  }
12967 #endif
12968  nwflag[0] = '\0';
12969  getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
12970 #ifndef WITHOUT_DRIVERMGR
12971  if (dsn[0] && !nwflag[0]) {
12972  SQLGetPrivateProfileString(dsn, "nowchar", "",
12973  nwflag, sizeof (nwflag), ODBC_INI);
12974  }
12975 #endif
12976  fkflag[0] = '\0';
12977  getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
12978 #ifndef WITHOUT_DRIVERMGR
12979  if (dsn[0] && !fkflag[0]) {
12980  SQLGetPrivateProfileString(dsn, "fksupport", "",
12981  fkflag, sizeof (fkflag), ODBC_INI);
12982  }
12983 #endif
12984  loadext[0] = '\0';
12985  getdsnattr(buf, "loadext", loadext, sizeof (loadext));
12986 #ifndef WITHOUT_DRIVERMGR
12987  if (dsn[0] && !loadext[0]) {
12988  SQLGetPrivateProfileString(dsn, "loadext", "",
12989  loadext, sizeof (loadext), ODBC_INI);
12990  }
12991 #endif
12992  jmode[0] = '\0';
12993  getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
12994 #ifndef WITHOUT_DRIVERMGR
12995  if (dsn[0] && !jmode[0]) {
12996  SQLGetPrivateProfileString(dsn, "journalmode", "",
12997  jmode, sizeof (jmode), ODBC_INI);
12998  }
12999 #endif
13000  biflag[0] = '\0';
13001  getdsnattr(buf, "bigint", biflag, sizeof (biflag));
13002 #ifndef WITHOUT_DRIVERMGR
13003  if (dsn[0] && !biflag[0]) {
13004  SQLGetPrivateProfileString(dsn, "bigint", "",
13005  biflag, sizeof (biflag), ODBC_INI);
13006  }
13007 #endif
13008  jdflag[0] = '\0';
13009  getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
13010 #ifndef WITHOUT_DRIVERMGR
13011  if (dsn[0] && !jdflag[0]) {
13012  SQLGetPrivateProfileString(dsn, "jdconv", "",
13013  jdflag, sizeof (jdflag), ODBC_INI);
13014  }
13015 #endif
13016  pwd[0] = '\0';
13017  getdsnattr(buf, "pwd", pwd, sizeof (pwd));
13018 #ifndef WITHOUT_DRIVERMGR
13019  if (dsn[0] && !pwd[0]) {
13020  SQLGetPrivateProfileString(dsn, "pwd", "",
13021  pwd, sizeof (pwd), ODBC_INI);
13022  }
13023 #endif
13024 
13025  if (!dbname[0] && !dsn[0]) {
13026  strcpy(dsn, "SQLite");
13027  strncpy(dbname, buf, sizeof (dbname));
13028  dbname[sizeof (dbname) - 1] = '\0';
13029  }
13030  tracef[0] = '\0';
13031  getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
13032 #ifndef WITHOUT_DRIVERMGR
13033  if (dsn[0] && !tracef[0]) {
13034  SQLGetPrivateProfileString(dsn, "tracefile", "",
13035  tracef, sizeof (tracef), ODBC_INI);
13036  }
13037 #endif
13038  if (connOut || connOutLen) {
13039  int count;
13040 
13041  buf[0] = '\0';
13042  count = snprintf(buf, sizeof (buf),
13043  "DSN=%s;Database=%s;StepAPI=%s;Timeout=%s;"
13044  "SyncPragma=%s;NoTXN=%s;ShortNames=%s;LongNames=%s;"
13045  "NoCreat=%s;NoWCHAR=%s;FKSupport=%s;Tracefile=%s;"
13046  "JournalMode=%s;LoadExt=%s;BigInt=%s;JDConv=%s;"
13047  "PWD=%s",
13048  dsn, dbname, sflag, busy, spflag, ntflag,
13049  snflag, lnflag, ncflag, nwflag, fkflag, tracef,
13050  jmode, loadext, biflag, jdflag, pwd);
13051  if (count < 0) {
13052  buf[sizeof (buf) - 1] = '\0';
13053  }
13054  len = min(connOutMax - 1, strlen(buf));
13055  if (connOut) {
13056  strncpy((char *) connOut, buf, len);
13057  connOut[len] = '\0';
13058  }
13059  if (connOutLen) {
13060  *connOutLen = len;
13061  }
13062  }
13063  if (tracef[0] != '\0') {
13064  d->trace = fopen(tracef, "a");
13065  }
13066  d->shortnames = getbool(snflag);
13067  d->longnames = getbool(lnflag);
13068  d->nocreat = getbool(ncflag);
13069  d->nowchar = getbool(nwflag);
13070  d->fksupport = getbool(fkflag);
13071  d->dobigint = getbool(biflag);
13072  d->jdconv = getbool(jdflag);
13073  d->oemcp = 0;
13074  d->pwdLen = strlen(pwd);
13075  d->pwd = (d->pwdLen > 0) ? pwd : NULL;
13076  ret = dbopen(d, dbname, 0, dsn, sflag, spflag, ntflag, jmode, busy);
13077  memset(pwd, 0, sizeof (pwd));
13078  if (ret == SQL_SUCCESS) {
13079  dbloadext(d, loadext);
13080  }
13081  return ret;
13082 }
13083 #endif
13084 
13091 static SQLRETURN
13092 freestmt(SQLHSTMT stmt)
13093 {
13094  STMT *s;
13095  DBC *d;
13096 
13097  if (stmt == SQL_NULL_HSTMT) {
13098  return SQL_INVALID_HANDLE;
13099  }
13100  s = (STMT *) stmt;
13101  s3stmt_drop(s);
13102  freeresult(s, 1);
13103  freep(&s->query);
13104  d = (DBC *) s->dbc;
13105  if (d && d->magic == DBC_MAGIC) {
13106  STMT *p, *n;
13107 
13108  p = NULL;
13109  n = d->stmt;
13110  while (n) {
13111  if (n == s) {
13112  break;
13113  }
13114  p = n;
13115  n = n->next;
13116  }
13117  if (n) {
13118  if (p) {
13119  p->next = s->next;
13120  } else {
13121  d->stmt = s->next;
13122  }
13123  }
13124  }
13125  freeparams(s);
13126  freep(&s->bindparms);
13127  if (s->row_status0 != &s->row_status1) {
13128  freep(&s->row_status0);
13129  s->rowset_size = 1;
13130  s->row_status0 = &s->row_status1;
13131  }
13132  xfree(s);
13133  return SQL_SUCCESS;
13134 }
13135 
13143 static SQLRETURN
13144 drvallocstmt(SQLHDBC dbc, SQLHSTMT *stmt)
13145 {
13146  DBC *d;
13147  STMT *s, *sl, *pl;
13148 
13149  if (dbc == SQL_NULL_HDBC) {
13150  return SQL_INVALID_HANDLE;
13151  }
13152  d = (DBC *) dbc;
13153  if (d->magic != DBC_MAGIC || stmt == NULL) {
13154  return SQL_INVALID_HANDLE;
13155  }
13156  s = (STMT *) xmalloc(sizeof (STMT));
13157  if (s == NULL) {
13158  *stmt = SQL_NULL_HSTMT;
13159  return SQL_ERROR;
13160  }
13161  *stmt = (SQLHSTMT) s;
13162  memset(s, 0, sizeof (STMT));
13163  s->dbc = dbc;
13164  s->ov3 = d->ov3;
13165  s->bkmrk = SQL_UB_OFF;
13166  s->bkmrkptr = 0;
13167  s->oemcp = &d->oemcp;
13168  s->jdconv = &d->jdconv;
13169  s->nowchar[0] = d->nowchar;
13170  s->nowchar[1] = 0;
13171  s->dobigint = d->dobigint;
13172  s->curtype = d->curtype;
13173  s->row_status0 = &s->row_status1;
13174  s->rowset_size = 1;
13175  s->longnames = d->longnames;
13176  s->retr_data = SQL_RD_ON;
13177  s->max_rows = 0;
13178  s->bind_type = SQL_BIND_BY_COLUMN;
13179  s->bind_offs = NULL;
13180  s->paramset_size = 1;
13181  s->parm_bind_type = SQL_PARAM_BIND_BY_COLUMN;
13182  s->one_tbl = -1;
13183  s->has_pk = -1;
13184  s->has_rowid = -1;
13185 #ifdef _WIN64
13186  sprintf((char *) s->cursorname, "CUR_%I64X", (SQLUBIGINT) *stmt);
13187 #else
13188  sprintf((char *) s->cursorname, "CUR_%016lX", (long) *stmt);
13189 #endif
13190  sl = d->stmt;
13191  pl = NULL;
13192  while (sl) {
13193  pl = sl;
13194  sl = sl->next;
13195  }
13196  if (pl) {
13197  pl->next = s;
13198  } else {
13199  d->stmt = s;
13200  }
13201  return SQL_SUCCESS;
13202 }
13203 
13211 SQLRETURN SQL_API
13212 SQLAllocStmt(SQLHDBC dbc, SQLHSTMT *stmt)
13213 {
13214  SQLRETURN ret;
13215 
13216  HDBC_LOCK(dbc);
13217  ret = drvallocstmt(dbc, stmt);
13218  HDBC_UNLOCK(dbc);
13219  return ret;
13220 }
13221 
13229 static SQLRETURN
13230 drvfreestmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13231 {
13232  STMT *s;
13233  SQLRETURN ret = SQL_SUCCESS;
13234  SQLHDBC dbc;
13235 
13236  if (stmt == SQL_NULL_HSTMT) {
13237  return SQL_INVALID_HANDLE;
13238  }
13239  HSTMT_LOCK(stmt);
13240  s = (STMT *) stmt;
13241  dbc = s->dbc;
13242  switch (opt) {
13243  case SQL_RESET_PARAMS:
13244  freeparams(s);
13245  break;
13246  case SQL_UNBIND:
13247  unbindcols(s);
13248  break;
13249  case SQL_CLOSE:
13250  s3stmt_end_if(s);
13251  freeresult(s, 0);
13252  break;
13253  case SQL_DROP:
13254  s3stmt_end_if(s);
13255  ret = freestmt(stmt);
13256  break;
13257  default:
13258  setstat(s, -1, "unsupported option", (*s->ov3) ? "HYC00" : "S1C00");
13259  ret = SQL_ERROR;
13260  break;
13261  }
13262  HDBC_UNLOCK(dbc);
13263  return ret;
13264 }
13265 
13273 SQLRETURN SQL_API
13274 SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13275 {
13276  return drvfreestmt(stmt, opt);
13277 }
13278 
13285 SQLRETURN SQL_API
13286 SQLCancel(SQLHSTMT stmt)
13287 {
13288  if (stmt != SQL_NULL_HSTMT) {
13289  DBC *d = (DBC *) ((STMT *) stmt)->dbc;
13290 #if defined(_WIN32) || defined(_WIN64)
13291  /* interrupt when other thread owns critical section */
13292  if (d->magic == DBC_MAGIC && d->owner != GetCurrentThreadId() &&
13293  d->owner != 0) {
13294  d->busyint = 1;
13295  sqlite3_interrupt(d->sqlite);
13296  return SQL_SUCCESS;
13297  }
13298 #else
13299  if (d->magic == DBC_MAGIC) {
13300  d->busyint = 1;
13301  sqlite3_interrupt(d->sqlite);
13302  }
13303 #endif
13304  }
13305  return drvfreestmt(stmt, SQL_CLOSE);
13306 }
13307 
13317 static SQLRETURN
13318 drvgetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13319  SQLSMALLINT *lenp)
13320 {
13321  STMT *s;
13322 
13323  if (stmt == SQL_NULL_HSTMT) {
13324  return SQL_INVALID_HANDLE;
13325  }
13326  s = (STMT *) stmt;
13327  if (lenp && !cursor) {
13328  *lenp = strlen((char *) s->cursorname);
13329  return SQL_SUCCESS;
13330  }
13331  if (cursor) {
13332  if (buflen > 0) {
13333  strncpy((char *) cursor, (char *) s->cursorname, buflen - 1);
13334  cursor[buflen - 1] = '\0';
13335  }
13336  if (lenp) {
13337  *lenp = min(strlen((char *) s->cursorname), buflen - 1);
13338  }
13339  }
13340  return SQL_SUCCESS;
13341 }
13342 
13343 #ifndef WINTERFACE
13344 
13353 SQLRETURN SQL_API
13354 SQLGetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13355  SQLSMALLINT *lenp)
13356 {
13357  SQLRETURN ret;
13358 #if defined(_WIN32) || defined(_WIN64)
13359  SQLSMALLINT len = 0;
13360 #endif
13361 
13362  HSTMT_LOCK(stmt);
13363 #if defined(_WIN32) || defined(_WIN64)
13364  if (!((STMT *) stmt)->oemcp[0]) {
13365  ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13366  goto done;
13367  }
13368  ret = drvgetcursorname(stmt, cursor, buflen, &len);
13369  if (ret == SQL_SUCCESS) {
13370  char *c = NULL;
13371 
13372  if (cursor) {
13373  c = utf_to_wmb((char *) cursor, len);
13374  if (!c) {
13375  ret = nomem((STMT *) stmt);
13376  goto done;
13377  }
13378  c[len] = 0;
13379  len = strlen(c);
13380  if (buflen > 0) {
13381  strncpy((char *) cursor, c, buflen - 1);
13382  cursor[buflen - 1] = 0;
13383  }
13384  uc_free(c);
13385  }
13386  if (lenp) {
13387  *lenp = min(len, buflen - 1);
13388  }
13389  }
13390 done:
13391  ;
13392 #else
13393  ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13394 #endif
13395  HSTMT_UNLOCK(stmt);
13396  return ret;
13397 }
13398 #endif
13399 
13400 #ifdef WINTERFACE
13401 
13410 SQLRETURN SQL_API
13411 SQLGetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT buflen,
13412  SQLSMALLINT *lenp)
13413 {
13414  SQLRETURN ret;
13415  SQLSMALLINT len = 0;
13416 
13417  HSTMT_LOCK(stmt);
13418  ret = drvgetcursorname(stmt, (SQLCHAR *) cursor, buflen, &len);
13419  if (ret == SQL_SUCCESS) {
13420  SQLWCHAR *c = NULL;
13421 
13422  if (cursor) {
13423  c = uc_from_utf((SQLCHAR *) cursor, len);
13424  if (!c) {
13425  ret = nomem((STMT *) stmt);
13426  goto done;
13427  }
13428  c[len] = 0;
13429  len = uc_strlen(c);
13430  if (buflen > 0) {
13431  uc_strncpy(cursor, c, buflen - 1);
13432  cursor[buflen - 1] = 0;
13433  }
13434  uc_free(c);
13435  }
13436  if (lenp) {
13437  *lenp = min(len, buflen - 1);
13438  }
13439  }
13440 done:
13441  HSTMT_UNLOCK(stmt);
13442  return ret;
13443 }
13444 #endif
13445 
13454 static SQLRETURN
13455 drvsetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13456 {
13457  STMT *s;
13458 
13459  if (stmt == SQL_NULL_HSTMT) {
13460  return SQL_INVALID_HANDLE;
13461  }
13462  s = (STMT *) stmt;
13463  if (!cursor ||
13464  !((cursor[0] >= 'A' && cursor[0] <= 'Z') ||
13465  (cursor[0] >= 'a' && cursor[0] <= 'z'))) {
13466  setstat(s, -1, "invalid cursor name", (*s->ov3) ? "HYC00" : "S1C00");
13467  return SQL_ERROR;
13468  }
13469  if (len == SQL_NTS) {
13470  len = sizeof (s->cursorname) - 1;
13471  } else {
13472  len = min(sizeof (s->cursorname) - 1, len);
13473  }
13474  strncpy((char *) s->cursorname, (char *) cursor, len);
13475  s->cursorname[len] = '\0';
13476  return SQL_SUCCESS;
13477 }
13478 
13479 #ifndef WINTERFACE
13480 
13488 SQLRETURN SQL_API
13489 SQLSetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13490 {
13491 #if defined(_WIN32) || defined(_WIN64)
13492  char *c = NULL;
13493 #endif
13494  SQLRETURN ret;
13495 
13496  HSTMT_LOCK(stmt);
13497 #if defined(_WIN32) || defined(_WIN64)
13498  if (!((STMT *) stmt)->oemcp[0]) {
13499  ret = drvsetcursorname(stmt, cursor, len);
13500  goto done2;
13501  }
13502  if (cursor) {
13503  c = wmb_to_utf_c((char *) cursor, len);
13504  if (!c) {
13505  ret = nomem((STMT *) stmt);
13506  goto done;
13507  }
13508  }
13509  ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13510 #else
13511  ret = drvsetcursorname(stmt, cursor, len);
13512 #endif
13513 #if defined(_WIN32) || defined(_WIN64)
13514 done:
13515  uc_free(c);
13516 done2:
13517  ;
13518 #endif
13519  HSTMT_UNLOCK(stmt);
13520  return ret;
13521 }
13522 #endif
13523 
13524 #ifdef WINTERFACE
13525 
13533 SQLRETURN SQL_API
13534 SQLSetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT len)
13535 {
13536  char *c = NULL;
13537  SQLRETURN ret;
13538 
13539  HSTMT_LOCK(stmt);
13540  if (cursor) {
13541  c = uc_to_utf_c(cursor, len);
13542  if (!c) {
13543  ret = nomem((STMT *) stmt);
13544  goto done;
13545  }
13546  }
13547  ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13548 done:
13549  uc_free(c);
13550  HSTMT_UNLOCK(stmt);
13551  return ret;
13552 }
13553 #endif
13554 
13561 SQLRETURN SQL_API
13562 SQLCloseCursor(SQLHSTMT stmt)
13563 {
13564  return drvfreestmt(stmt, SQL_CLOSE);
13565 }
13566 
13575 SQLRETURN SQL_API
13576 SQLAllocHandle(SQLSMALLINT type, SQLHANDLE input, SQLHANDLE *output)
13577 {
13578  SQLRETURN ret;
13579 
13580  switch (type) {
13581  case SQL_HANDLE_ENV:
13582  ret = drvallocenv((SQLHENV *) output);
13583  if (ret == SQL_SUCCESS) {
13584  ENV *e = (ENV *) *output;
13585 
13586  if (e && e->magic == ENV_MAGIC) {
13587  e->ov3 = 1;
13588  }
13589  }
13590  return ret;
13591  case SQL_HANDLE_DBC:
13592  return drvallocconnect((SQLHENV) input, (SQLHDBC *) output);
13593  case SQL_HANDLE_STMT:
13594  HDBC_LOCK((SQLHDBC) input);
13595  ret = drvallocstmt((SQLHDBC) input, (SQLHSTMT *) output);
13596  HDBC_UNLOCK((SQLHDBC) input);
13597  return ret;
13598  }
13599  return SQL_ERROR;
13600 }
13601 
13609 SQLRETURN SQL_API
13610 SQLFreeHandle(SQLSMALLINT type, SQLHANDLE h)
13611 {
13612  switch (type) {
13613  case SQL_HANDLE_ENV:
13614  return drvfreeenv((SQLHENV) h);
13615  case SQL_HANDLE_DBC:
13616  return drvfreeconnect((SQLHDBC) h);
13617  case SQL_HANDLE_STMT:
13618  return drvfreestmt((SQLHSTMT) h, SQL_DROP);
13619  }
13620  return SQL_ERROR;
13621 }
13622 
13628 static void
13630 {
13631  if (s->dyncols) {
13632  int i;
13633 
13634  for (i = 0; i < s->dcols; i++) {
13635  freep(&s->dyncols[i].typename);
13636  }
13637  if (s->cols == s->dyncols) {
13638  s->cols = NULL;
13639  s->ncols = 0;
13640  }
13641  freep(&s->dyncols);
13642  }
13643  s->dcols = 0;
13644 }
13645 
13657 static void
13658 freeresult(STMT *s, int clrcols)
13659 {
13660  freep(&s->bincache);
13661  s->bincell = NULL;
13662  s->binlen = 0;
13663  if (s->rows) {
13664  if (s->rowfree) {
13665  s->rowfree(s->rows);
13666  s->rowfree = NULL;
13667  }
13668  s->rows = NULL;
13669  }
13670  s->nrows = -1;
13671  if (clrcols > 0) {
13672  freep(&s->bindcols);
13673  s->nbindcols = 0;
13674  }
13675  if (clrcols) {
13676  freedyncols(s);
13677  s->cols = NULL;
13678  s->ncols = 0;
13679  s->nowchar[1] = 0;
13680  s->one_tbl = -1;
13681  s->has_pk = -1;
13682  s->has_rowid = -1;
13683  }
13684 }
13685 
13691 static void
13693 {
13694  int i;
13695 
13696  for (i = 0; s->bindcols && i < s->nbindcols; i++) {
13697  s->bindcols[i].type = SQL_UNKNOWN_TYPE;
13698  s->bindcols[i].max = 0;
13699  s->bindcols[i].lenp = NULL;
13700  s->bindcols[i].valp = NULL;
13701  s->bindcols[i].index = i;
13702  s->bindcols[i].offs = 0;
13703  }
13704 }
13705 
13713 static SQLRETURN
13714 mkbindcols(STMT *s, int ncols)
13715 {
13716  if (s->bindcols) {
13717  if (s->nbindcols < ncols) {
13718  int i;
13719  BINDCOL *bindcols =
13720  xrealloc(s->bindcols, ncols * sizeof (BINDCOL));
13721 
13722  if (!bindcols) {
13723  return nomem(s);
13724  }
13725  for (i = s->nbindcols; i < ncols; i++) {
13726  bindcols[i].type = SQL_UNKNOWN_TYPE;
13727  bindcols[i].max = 0;
13728  bindcols[i].lenp = NULL;
13729  bindcols[i].valp = NULL;
13730  bindcols[i].index = i;
13731  bindcols[i].offs = 0;
13732  }
13733  s->bindcols = bindcols;
13734  s->nbindcols = ncols;
13735  }
13736  } else if (ncols > 0) {
13737  s->bindcols = (BINDCOL *) xmalloc(ncols * sizeof (BINDCOL));
13738  if (!s->bindcols) {
13739  return nomem(s);
13740  }
13741  s->nbindcols = ncols;
13742  unbindcols(s);
13743  }
13744  return SQL_SUCCESS;
13745 }
13746 
13760 static SQLRETURN
13761 getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype,
13762  SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp, int partial)
13763 {
13764  char **data, valdummy[16];
13765  SQLLEN dummy;
13766  SQLINTEGER *ilenp = NULL;
13767  int valnull = 0;
13768  int type = otype;
13769  SQLRETURN sret = SQL_NO_DATA;
13770 
13771  if (!lenp) {
13772  lenp = &dummy;
13773  }
13774  /* workaround for JDK 1.7.0 on x86_64 */
13775  if (((SQLINTEGER *) lenp) + 1 == (SQLINTEGER *) val) {
13776  ilenp = (SQLINTEGER *) lenp;
13777  lenp = &dummy;
13778  }
13779  if (col >= s->ncols) {
13780  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
13781  return SQL_ERROR;
13782  }
13783  if (s->retr_data != SQL_RD_ON) {
13784  return SQL_SUCCESS;
13785  }
13786  if (!s->rows) {
13787  *lenp = SQL_NULL_DATA;
13788  goto done;
13789  }
13790  if (s->rowp < 0 || s->rowp >= s->nrows) {
13791  *lenp = SQL_NULL_DATA;
13792  goto done;
13793  }
13794  type = mapdeftype(type, s->cols[col].type, s->cols[col].nosign ? 1 : 0,
13795  s->nowchar[0]);
13796 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
13797  /* MS Access hack part 3 (map SQL_C_DEFAULT to SQL_C_CHAR) */
13798  if (type == SQL_C_WCHAR && otype == SQL_C_DEFAULT) {
13799  type = SQL_C_CHAR;
13800  }
13801 #endif
13802  data = s->rows + s->ncols + (s->rowp * s->ncols) + col;
13803  if (!val) {
13804  valnull = 1;
13805  val = (SQLPOINTER) valdummy;
13806  }
13807  if (*data == NULL) {
13808  *lenp = SQL_NULL_DATA;
13809  switch (type) {
13810  case SQL_C_UTINYINT:
13811  case SQL_C_TINYINT:
13812  case SQL_C_STINYINT:
13813 #ifdef SQL_BIT
13814  case SQL_C_BIT:
13815 #endif
13816  *((SQLCHAR *) val) = 0;
13817  break;
13818  case SQL_C_USHORT:
13819  case SQL_C_SHORT:
13820  case SQL_C_SSHORT:
13821  *((SQLSMALLINT *) val) = 0;
13822  break;
13823  case SQL_C_ULONG:
13824  case SQL_C_LONG:
13825  case SQL_C_SLONG:
13826  *((SQLINTEGER *) val) = 0;
13827  break;
13828 #ifdef SQL_BIGINT
13829  case SQL_C_SBIGINT:
13830  case SQL_C_UBIGINT:
13831  *((SQLBIGINT *) val) = 0;
13832  break;
13833 #endif
13834  case SQL_C_FLOAT:
13835  *((float *) val) = 0;
13836  break;
13837  case SQL_C_DOUBLE:
13838  *((double *) val) = 0;
13839  break;
13840  case SQL_C_BINARY:
13841  case SQL_C_CHAR:
13842  if (len > 0) {
13843  *((SQLCHAR *) val) = '\0';
13844  }
13845  break;
13846 #ifdef WCHARSUPPORT
13847  case SQL_C_WCHAR:
13848  if (len > 0) {
13849  *((SQLWCHAR *) val) = '\0';
13850  }
13851  break;
13852 #endif
13853 #ifdef SQL_C_TYPE_DATE
13854  case SQL_C_TYPE_DATE:
13855 #endif
13856  case SQL_C_DATE:
13857  memset((DATE_STRUCT *) val, 0, sizeof (DATE_STRUCT));
13858  break;
13859 #ifdef SQL_C_TYPE_TIME
13860  case SQL_C_TYPE_TIME:
13861 #endif
13862  case SQL_C_TIME:
13863  memset((TIME_STRUCT *) val, 0, sizeof (TIME_STRUCT));
13864  break;
13865 #ifdef SQL_C_TYPE_TIMESTAMP
13866  case SQL_C_TYPE_TIMESTAMP:
13867 #endif
13868  case SQL_C_TIMESTAMP:
13869  memset((TIMESTAMP_STRUCT *) val, 0, sizeof (TIMESTAMP_STRUCT));
13870  break;
13871  default:
13872  return SQL_ERROR;
13873  }
13874  } else {
13875  char *endp = NULL;
13876 #if defined(_WIN32) || defined(_WIN64)
13877 #ifdef SQL_BIGINT
13878  char endc;
13879 #endif
13880 #endif
13881 
13882  switch (type) {
13883  case SQL_C_UTINYINT:
13884  case SQL_C_TINYINT:
13885  case SQL_C_STINYINT:
13886  *((SQLCHAR *) val) = strtol(*data, &endp, 0);
13887  if (endp && endp == *data) {
13888  *lenp = SQL_NULL_DATA;
13889  } else {
13890  *lenp = sizeof (SQLCHAR);
13891  }
13892  break;
13893 #ifdef SQL_BIT
13894  case SQL_C_BIT:
13895  *((SQLCHAR *) val) = getbool(*data);
13896  *lenp = sizeof (SQLCHAR);
13897  break;
13898 #endif
13899  case SQL_C_USHORT:
13900  case SQL_C_SHORT:
13901  case SQL_C_SSHORT:
13902  *((SQLSMALLINT *) val) = strtol(*data, &endp, 0);
13903  if (endp && endp == *data) {
13904  *lenp = SQL_NULL_DATA;
13905  } else {
13906  *lenp = sizeof (SQLSMALLINT);
13907  }
13908  break;
13909  case SQL_C_ULONG:
13910  case SQL_C_LONG:
13911  case SQL_C_SLONG:
13912  *((SQLINTEGER *) val) = strtol(*data, &endp, 0);
13913  if (endp && endp == *data) {
13914  *lenp = SQL_NULL_DATA;
13915  } else {
13916  *lenp = sizeof (SQLINTEGER);
13917  }
13918  break;
13919 #ifdef SQL_BIGINT
13920  case SQL_C_UBIGINT:
13921 #if defined(_WIN32) || defined(_WIN64)
13922  if (sscanf(*data, "%I64u%c", (SQLUBIGINT *) val, &endc) != 1) {
13923  *lenp = SQL_NULL_DATA;
13924  } else {
13925  *lenp = sizeof (SQLUBIGINT);
13926  }
13927 #else
13928 #ifdef __osf__
13929  *((SQLUBIGINT *) val) = strtoul(*data, &endp, 0);
13930 #else
13931  *((SQLUBIGINT *) val) = strtoull(*data, &endp, 0);
13932 #endif
13933  if (endp && endp == *data) {
13934  *lenp = SQL_NULL_DATA;
13935  } else {
13936  *lenp = sizeof (SQLUBIGINT);
13937  }
13938 #endif
13939  break;
13940  case SQL_C_SBIGINT:
13941 #if defined(_WIN32) || defined(_WIN64)
13942  if (sscanf(*data, "%I64d%c", (SQLBIGINT *) val, &endc) != 1) {
13943  *lenp = SQL_NULL_DATA;
13944  } else {
13945  *lenp = sizeof (SQLBIGINT);
13946  }
13947 #else
13948 #ifdef __osf__
13949  *((SQLBIGINT *) val) = strtol(*data, &endp, 0);
13950 #else
13951  *((SQLBIGINT *) val) = strtoll(*data, &endp, 0);
13952 #endif
13953  if (endp && endp == *data) {
13954  *lenp = SQL_NULL_DATA;
13955  } else {
13956  *lenp = sizeof (SQLBIGINT);
13957  }
13958 #endif
13959  break;
13960 #endif
13961  case SQL_C_FLOAT:
13962  *((float *) val) = ln_strtod(*data, &endp);
13963  if (endp && endp == *data) {
13964  *lenp = SQL_NULL_DATA;
13965  } else {
13966  *lenp = sizeof (float);
13967  }
13968  break;
13969  case SQL_C_DOUBLE:
13970  *((double *) val) = ln_strtod(*data, &endp);
13971  if (endp && endp == *data) {
13972  *lenp = SQL_NULL_DATA;
13973  } else {
13974  *lenp = sizeof (double);
13975  }
13976  break;
13977  case SQL_C_BINARY: {
13978  int dlen, offs = 0;
13979  char *bin;
13980 
13981  if (valnull) {
13982  freep(&s->bincache);
13983  s->binlen = 0;
13984  goto doCHAR;
13985  }
13986  if (*data == s->bincell) {
13987  if (s->bincache) {
13988  bin = s->bincache;
13989  dlen = s->binlen;
13990  } else {
13991  goto doCHAR;
13992  }
13993  } else {
13994  char *dp;
13995  int i;
13996 
13997  freep(&s->bincache);
13998  dp = *data;
13999  dlen = strlen(dp);
14000  s->bincell = dp;
14001  s->binlen = 0;
14002  if (!(dp[0] == 'x' || dp[0] == 'X') || dp[1] != '\'' ||
14003  dp[dlen - 1] != '\'') {
14004  goto doCHAR;
14005  }
14006  dlen -= 2;
14007  dp += 2;
14008  dlen = dlen / 2;
14009  s->bincache = bin = xmalloc(dlen + 1);
14010  if (!bin) {
14011  return nomem(s);
14012  }
14013  s->binlen = dlen;
14014  memset(bin, 0, dlen);
14015  bin[dlen] = '\0'; /* terminator, just in case */
14016  for (i = 0; i < dlen; i++) {
14017  char *x;
14018  int v;
14019 
14020  if (!*dp || !(x = strchr(xdigits, *dp))) {
14021  goto converr;
14022  }
14023  v = x - xdigits;
14024  bin[i] = (v >= 16) ? ((v - 6) << 4) : (v << 4);
14025  ++dp;
14026  if (!*dp || !(x = strchr(xdigits, *dp))) {
14027 converr:
14028  freep(&s->bincache);
14029  s->binlen = 0;
14030  setstat(s, -1, "conversion error",
14031  (*s->ov3) ? "HY000" : "S1000");
14032  return SQL_ERROR;
14033  }
14034  v = x - xdigits;
14035  bin[i] |= (v >= 16) ? (v - 6) : v;
14036  ++dp;
14037  }
14038  bin = s->bincache;
14039  }
14040  if (partial && len && s->bindcols) {
14041  if (s->bindcols[col].offs >= dlen) {
14042  *lenp = 0;
14043  if (!dlen && s->bindcols[col].offs == dlen) {
14044  s->bindcols[col].offs = 1;
14045  sret = SQL_SUCCESS;
14046  goto done;
14047  }
14048  s->bindcols[col].offs = 0;
14049  sret = SQL_NO_DATA;
14050  goto done;
14051  }
14052  offs = s->bindcols[col].offs;
14053  dlen -= offs;
14054  }
14055  if (val && len) {
14056  memcpy(val, bin + offs, min(len, dlen));
14057  }
14058  if (len < 1) {
14059  *lenp = dlen;
14060  } else {
14061  *lenp = min(len, dlen);
14062  if (*lenp == len && *lenp != dlen) {
14063  *lenp = SQL_NO_TOTAL;
14064  }
14065  }
14066  if (partial && len && s->bindcols) {
14067  if (*lenp == SQL_NO_TOTAL) {
14068  *lenp = dlen;
14069  s->bindcols[col].offs += len;
14070  setstat(s, -1, "data right truncated", "01004");
14071  if (s->bindcols[col].lenp) {
14072  *s->bindcols[col].lenp = dlen;
14073  }
14074  sret = SQL_SUCCESS_WITH_INFO;
14075  goto done;
14076  }
14077  s->bindcols[col].offs += *lenp;
14078  }
14079  if (*lenp == SQL_NO_TOTAL) {
14080  *lenp = dlen;
14081  setstat(s, -1, "data right truncated", "01004");
14082  sret = SQL_SUCCESS_WITH_INFO;
14083  goto done;
14084  }
14085  break;
14086  }
14087  doCHAR:
14088 #ifdef WCHARSUPPORT
14089  case SQL_C_WCHAR:
14090 #endif
14091  case SQL_C_CHAR: {
14092  int doz, zlen = len - 1;
14093  int dlen = strlen(*data);
14094  int offs = 0;
14095 #ifdef WCHARSUPPORT
14096  SQLWCHAR *ucdata = NULL;
14097  SQLCHAR *cdata = (SQLCHAR *) *data;
14098 #endif
14099 
14100 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
14101  /* MS Access hack part 2 (reserved error -7748) */
14102  if (!valnull &&
14103  (s->cols == statSpec2P || s->cols == statSpec3P) &&
14104  type == SQL_C_WCHAR) {
14105  if (len > 0 && len <= sizeof (SQLWCHAR)) {
14106  ((char *) val)[0] = data[0][0];
14107  memset((char *) val + 1, 0, len - 1);
14108  *lenp = 1;
14109  sret = SQL_SUCCESS;
14110  goto done;
14111  }
14112  }
14113 #endif
14114 
14115 #ifdef WCHARSUPPORT
14116  switch (type) {
14117  case SQL_C_CHAR:
14118  doz = 1;
14119  break;
14120  case SQL_C_WCHAR:
14121  doz = sizeof (SQLWCHAR);
14122  break;
14123  default:
14124  doz = 0;
14125  break;
14126  }
14127  if (type == SQL_C_WCHAR) {
14128  ucdata = uc_from_utf(cdata, dlen);
14129  if (!ucdata) {
14130  return nomem(s);
14131  }
14132  dlen = uc_strlen(ucdata) * sizeof (SQLWCHAR);
14133  }
14134 #if defined(_WIN32) || defined(_WIN64)
14135  else if (*s->oemcp && type == SQL_C_CHAR) {
14136  ucdata = (SQLWCHAR *) utf_to_wmb((char *) cdata, dlen);
14137  if (!ucdata) {
14138  return nomem(s);
14139  }
14140  cdata = (SQLCHAR *) ucdata;
14141  dlen = strlen((char *) cdata);
14142  }
14143 #endif
14144 #else
14145  doz = (type == SQL_C_CHAR) ? 1 : 0;
14146 #endif
14147  if (partial && len && s->bindcols) {
14148  if (s->bindcols[col].offs >= dlen) {
14149 #ifdef WCHARSUPPORT
14150  uc_free(ucdata);
14151 #endif
14152  *lenp = 0;
14153  if (doz && val) {
14154 #ifdef WCHARSUPPORT
14155  if (type == SQL_C_WCHAR) {
14156  ((SQLWCHAR *) val)[0] = 0;
14157  } else {
14158  ((char *) val)[0] = '\0';
14159  }
14160 #else
14161  ((char *) val)[0] = '\0';
14162 #endif
14163  }
14164  if (!dlen && s->bindcols[col].offs == dlen) {
14165  s->bindcols[col].offs = 1;
14166  sret = SQL_SUCCESS;
14167  goto done;
14168  }
14169  s->bindcols[col].offs = 0;
14170  sret = SQL_NO_DATA;
14171  goto done;
14172  }
14173  offs = s->bindcols[col].offs;
14174  dlen -= offs;
14175  }
14176  if (val && !valnull && len) {
14177 #ifdef WCHARSUPPORT
14178  if (type == SQL_C_WCHAR) {
14179  uc_strncpy(val, ucdata + offs / sizeof (SQLWCHAR),
14180  (len - doz) / sizeof (SQLWCHAR));
14181  } else {
14182  strncpy(val, (char *) cdata + offs, len - doz);
14183  }
14184 #else
14185  strncpy(val, *data + offs, len - doz);
14186 #endif
14187  }
14188  if (valnull || len < 1) {
14189  *lenp = dlen;
14190  } else {
14191  *lenp = min(len - doz, dlen);
14192  if (*lenp == len - doz && *lenp != dlen) {
14193  *lenp = SQL_NO_TOTAL;
14194  } else if (*lenp < zlen) {
14195  zlen = *lenp;
14196  }
14197  }
14198  if (len && !valnull && doz) {
14199 #ifdef WCHARSUPPORT
14200  if (type == SQL_C_WCHAR) {
14201  ((SQLWCHAR *) val)[zlen / sizeof (SQLWCHAR)] = 0;
14202  } else {
14203  ((char *) val)[zlen] = '\0';
14204  }
14205 #else
14206  ((char *) val)[zlen] = '\0';
14207 #endif
14208  }
14209 #ifdef WCHARSUPPORT
14210  uc_free(ucdata);
14211 #endif
14212  if (partial && len && s->bindcols) {
14213  if (*lenp == SQL_NO_TOTAL) {
14214  *lenp = dlen;
14215  s->bindcols[col].offs += len - doz;
14216  setstat(s, -1, "data right truncated", "01004");
14217  if (s->bindcols[col].lenp) {
14218  *s->bindcols[col].lenp = dlen;
14219  }
14220  sret = SQL_SUCCESS_WITH_INFO;
14221  goto done;
14222  }
14223  s->bindcols[col].offs += *lenp;
14224  }
14225  if (*lenp == SQL_NO_TOTAL) {
14226  *lenp = dlen;
14227  setstat(s, -1, "data right truncated", "01004");
14228  sret = SQL_SUCCESS_WITH_INFO;
14229  goto done;
14230  }
14231  break;
14232  }
14233 #ifdef SQL_C_TYPE_DATE
14234  case SQL_C_TYPE_DATE:
14235 #endif
14236  case SQL_C_DATE:
14237  if (str2date(*s->jdconv, *data, (DATE_STRUCT *) val) < 0) {
14238  *lenp = SQL_NULL_DATA;
14239  } else {
14240  *lenp = sizeof (DATE_STRUCT);
14241  }
14242  break;
14243 #ifdef SQL_C_TYPE_TIME
14244  case SQL_C_TYPE_TIME:
14245 #endif
14246  case SQL_C_TIME:
14247  if (str2time(*s->jdconv, *data, (TIME_STRUCT *) val) < 0) {
14248  *lenp = SQL_NULL_DATA;
14249  } else {
14250  *lenp = sizeof (TIME_STRUCT);
14251  }
14252  break;
14253 #ifdef SQL_C_TYPE_TIMESTAMP
14254  case SQL_C_TYPE_TIMESTAMP:
14255 #endif
14256  case SQL_C_TIMESTAMP:
14257  if (str2timestamp(*s->jdconv, *data,
14258  (TIMESTAMP_STRUCT *) val) < 0) {
14259  *lenp = SQL_NULL_DATA;
14260  } else {
14261  *lenp = sizeof (TIMESTAMP_STRUCT);
14262  }
14263  switch (s->cols[col].prec) {
14264  case 0:
14265  ((TIMESTAMP_STRUCT *) val)->fraction = 0;
14266  break;
14267  case 1:
14268  ((TIMESTAMP_STRUCT *) val)->fraction /= 100000000;
14269  ((TIMESTAMP_STRUCT *) val)->fraction *= 100000000;
14270  break;
14271  case 2:
14272  ((TIMESTAMP_STRUCT *) val)->fraction /= 10000000;
14273  ((TIMESTAMP_STRUCT *) val)->fraction *= 10000000;
14274  break;
14275  }
14276  break;
14277  default:
14278  return SQL_ERROR;
14279  }
14280  }
14281  sret = SQL_SUCCESS;
14282 done:
14283  if (ilenp) {
14284  *ilenp = *lenp;
14285  }
14286  return sret;
14287 }
14288 
14300 static SQLRETURN
14301 drvbindcol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14302  SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14303 {
14304  STMT *s;
14305  int sz = 0;
14306 
14307  if (stmt == SQL_NULL_HSTMT) {
14308  return SQL_INVALID_HANDLE;
14309  }
14310  s = (STMT *) stmt;
14311  if (col < 1) {
14312  if (col == 0 && s->bkmrk == SQL_UB_ON &&
14313  type == SQL_C_BOOKMARK) {
14314  s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14315  s->bkmrkcol.max = val ? sizeof (SQLINTEGER) : 0;
14316  s->bkmrkcol.lenp = val ? lenp : 0;
14317  s->bkmrkcol.valp = val;
14318  s->bkmrkcol.offs = 0;
14319  if (val && lenp) {
14320  *lenp = 0;
14321  }
14322  return SQL_SUCCESS;
14323  } else if (col == 0 && s->bkmrk == SQL_UB_VARIABLE &&
14324  type == SQL_C_VARBOOKMARK &&
14325  max >= sizeof (sqlite_int64)) {
14326  s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14327  s->bkmrkcol.max = val ? max : 0;
14328  s->bkmrkcol.lenp = val ? lenp : 0;
14329  s->bkmrkcol.valp = val;
14330  s->bkmrkcol.offs = 0;
14331  if (val && lenp) {
14332  *lenp = 0;
14333  }
14334  return SQL_SUCCESS;
14335  }
14336  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
14337  return SQL_ERROR;
14338  }
14339  if (mkbindcols(s, col) != SQL_SUCCESS) {
14340  return SQL_ERROR;
14341  }
14342  --col;
14343  if (type == SQL_C_DEFAULT) {
14344  type = mapdeftype(type, s->cols[col].type, 0,
14345  s->nowchar[0] || s->nowchar[1]);
14346  }
14347  switch (type) {
14348  case SQL_C_LONG:
14349  case SQL_C_ULONG:
14350  case SQL_C_SLONG:
14351  sz = sizeof (SQLINTEGER);
14352  break;
14353  case SQL_C_TINYINT:
14354  case SQL_C_UTINYINT:
14355  case SQL_C_STINYINT:
14356  sz = sizeof (SQLCHAR);
14357  break;
14358  case SQL_C_SHORT:
14359  case SQL_C_USHORT:
14360  case SQL_C_SSHORT:
14361  sz = sizeof (SQLSMALLINT);
14362  break;
14363  case SQL_C_FLOAT:
14364  sz = sizeof (SQLFLOAT);
14365  break;
14366  case SQL_C_DOUBLE:
14367  sz = sizeof (SQLDOUBLE);
14368  break;
14369  case SQL_C_TIMESTAMP:
14370  sz = sizeof (SQL_TIMESTAMP_STRUCT);
14371  break;
14372  case SQL_C_TIME:
14373  sz = sizeof (SQL_TIME_STRUCT);
14374  break;
14375  case SQL_C_DATE:
14376  sz = sizeof (SQL_DATE_STRUCT);
14377  break;
14378  case SQL_C_CHAR:
14379  break;
14380 #ifdef WCHARSUPPORT
14381  case SQL_C_WCHAR:
14382  break;
14383 #endif
14384 #ifdef SQL_C_TYPE_DATE
14385  case SQL_C_TYPE_DATE:
14386  sz = sizeof (SQL_DATE_STRUCT);
14387  break;
14388 #endif
14389 #ifdef SQL_C_TYPE_TIME
14390  case SQL_C_TYPE_TIME:
14391  sz = sizeof (SQL_TIME_STRUCT);
14392  break;
14393 #endif
14394 #ifdef SQL_C_TYPE_TIMESTAMP
14395  case SQL_C_TYPE_TIMESTAMP:
14396  sz = sizeof (SQL_TIMESTAMP_STRUCT);
14397  break;
14398 #endif
14399 #ifdef SQL_BIT
14400  case SQL_C_BIT:
14401  sz = sizeof (SQLCHAR);
14402  break;
14403 #endif
14404  case SQL_C_BINARY:
14405  break;
14406 #ifdef SQL_BIGINT
14407  case SQL_C_SBIGINT:
14408  case SQL_C_UBIGINT:
14409  sz = sizeof (SQLBIGINT);
14410  break;
14411 #endif
14412  default:
14413  if (val == NULL) {
14414  /* fall through, unbinding column */
14415  break;
14416  }
14417  setstat(s, -1, "invalid type %d", "HY003", type);
14418  return SQL_ERROR;
14419  }
14420  if (val == NULL) {
14421  /* unbind column */
14422  s->bindcols[col].type = SQL_UNKNOWN_TYPE;
14423  s->bindcols[col].max = 0;
14424  s->bindcols[col].lenp = NULL;
14425  s->bindcols[col].valp = NULL;
14426  s->bindcols[col].offs = 0;
14427  } else {
14428  if (sz == 0 && max < 0) {
14429  setstat(s, -1, "invalid length", "HY090");
14430  return SQL_ERROR;
14431  }
14432  s->bindcols[col].type = type;
14433  s->bindcols[col].max = (sz == 0) ? max : sz;
14434  s->bindcols[col].lenp = lenp;
14435  s->bindcols[col].valp = val;
14436  s->bindcols[col].offs = 0;
14437  if (lenp) {
14438  *lenp = 0;
14439  }
14440  }
14441  return SQL_SUCCESS;
14442 }
14443 
14455 SQLRETURN SQL_API
14456 SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14457  SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14458 {
14459  SQLRETURN ret;
14460 
14461  HSTMT_LOCK(stmt);
14462  ret = drvbindcol(stmt, col, type, val, max, lenp);
14463  HSTMT_UNLOCK(stmt);
14464  return ret;
14465 }
14466 
14471 static COL tableSpec2[] = {
14472  { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
14473  { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
14474  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14475  { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14476  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14477 };
14478 
14479 static COL tableSpec3[] = {
14480  { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
14481  { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
14482  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14483  { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14484  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14485 };
14486 
14501 static SQLRETURN
14502 drvtables(SQLHSTMT stmt,
14503  SQLCHAR *cat, SQLSMALLINT catLen,
14504  SQLCHAR *schema, SQLSMALLINT schemaLen,
14505  SQLCHAR *table, SQLSMALLINT tableLen,
14506  SQLCHAR *type, SQLSMALLINT typeLen)
14507 {
14508  SQLRETURN ret;
14509  STMT *s;
14510  DBC *d;
14511  int ncols, asize, rc, size, npatt;
14512  char *errp = NULL, *sql, tname[512];
14513  char *where = "(type = 'table' or type = 'view')";
14514 
14515  ret = mkresultset(stmt, tableSpec2, array_size(tableSpec2),
14516  tableSpec3, array_size(tableSpec3), &asize);
14517  if (ret != SQL_SUCCESS) {
14518  return ret;
14519  }
14520  s = (STMT *) stmt;
14521  d = (DBC *) s->dbc;
14522  if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] == '%') {
14523  int size = 3 * asize;
14524 
14525  s->rows = xmalloc(size * sizeof (char *));
14526  if (!s->rows) {
14527  s->nrows = 0;
14528  return nomem(s);
14529  }
14530  memset(s->rows, 0, sizeof (char *) * size);
14531  s->ncols = asize;
14532  s->rows[s->ncols + 0] = "";
14533  s->rows[s->ncols + 1] = "";
14534  s->rows[s->ncols + 2] = "";
14535  s->rows[s->ncols + 3] = "TABLE";
14536  s->rows[s->ncols + 5] = "";
14537  s->rows[s->ncols + 6] = "";
14538  s->rows[s->ncols + 7] = "";
14539  s->rows[s->ncols + 8] = "VIEW";
14540 #ifdef MEMORY_DEBUG
14541  s->rowfree = xfree__;
14542 #else
14543  s->rowfree = sqlite3_free;
14544 #endif
14545  s->nrows = 2;
14546  s->rowp = s->rowprs = -1;
14547  return SQL_SUCCESS;
14548  }
14549  if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
14550  table = NULL;
14551  goto doit;
14552  }
14553  if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
14554  schema[0] == '%') {
14555  if ((!cat || catLen == 0 || !cat[0]) &&
14556  (!table || tableLen == 0 || !table[0])) {
14557  table = NULL;
14558  goto doit;
14559  }
14560  }
14561  if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] != '\0') {
14562  char tmp[256], *t;
14563  int with_view = 0, with_table = 0;
14564 
14565  if (typeLen == SQL_NTS) {
14566  strncpy(tmp, (char *) type, sizeof (tmp));
14567  tmp[sizeof (tmp) - 1] = '\0';
14568  } else {
14569  int len = min(sizeof (tmp) - 1, typeLen);
14570 
14571  strncpy(tmp, (char *) type, len);
14572  tmp[len] = '\0';
14573  }
14574  t = tmp;
14575  while (*t) {
14576  *t = TOLOWER(*t);
14577  t++;
14578  }
14579  t = tmp;
14580  unescpat(t);
14581  while (t) {
14582  if (t[0] == '\'') {
14583  ++t;
14584  }
14585  if (strncmp(t, "table", 5) == 0) {
14586  with_table++;
14587  } else if (strncmp(t, "view", 4) == 0) {
14588  with_view++;
14589  }
14590  t = strchr(t, ',');
14591  if (t) {
14592  ++t;
14593  }
14594  }
14595  if (with_view && with_table) {
14596  /* where is already preset */
14597  } else if (with_view && !with_table) {
14598  where = "type = 'view'";
14599  } else if (!with_view && with_table) {
14600  where = "type = 'table'";
14601  } else {
14602  return SQL_SUCCESS;
14603  }
14604  }
14605 doit:
14606  if (!table) {
14607  size = 1;
14608  tname[0] = '%';
14609  } else {
14610  if (tableLen == SQL_NTS) {
14611  size = sizeof (tname) - 1;
14612  } else {
14613  size = min(sizeof (tname) - 1, tableLen);
14614  }
14615  strncpy(tname, (char *) table, size);
14616  }
14617  tname[size] = '\0';
14618  npatt = unescpat(tname);
14619 #if defined(_WIN32) || defined(_WIN64)
14620  sql = sqlite3_mprintf("select %s as 'TABLE_CAT', "
14621  "%s as 'TABLE_SCHEM', "
14622  "tbl_name as 'TABLE_NAME', "
14623  "upper(type) as 'TABLE_TYPE', "
14624  "NULL as 'REMARKS' "
14625  "from sqlite_master where %s "
14626  "and tbl_name %s %Q",
14627  d->xcelqrx ? "'main'" : "NULL",
14628  d->xcelqrx ? "''" : "NULL",
14629  where,
14630  npatt ? "like" : "=", tname);
14631 #else
14632  sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
14633  "NULL as 'TABLE_OWNER', "
14634  "tbl_name as 'TABLE_NAME', "
14635  "upper(type) as 'TABLE_TYPE', "
14636  "NULL as 'REMARKS' "
14637  "from sqlite_master where %s "
14638  "and tbl_name %s %Q", where,
14639  npatt ? "like" : "=", tname);
14640 #endif
14641  if (!sql) {
14642  return nomem(s);
14643  }
14644  ret = starttran(s);
14645  if (ret != SQL_SUCCESS) {
14646  sqlite3_free(sql);
14647  return ret;
14648  }
14649  dbtraceapi(d, "sqlite3_get_table", sql);
14650  rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
14651  sqlite3_free(sql);
14652  if (rc == SQLITE_OK) {
14653  if (ncols != s->ncols) {
14654  freeresult(s, 0);
14655  s->nrows = 0;
14656  } else {
14657  s->rowfree = sqlite3_free_table;
14658  }
14659  } else {
14660  s->nrows = 0;
14661  s->rows = NULL;
14662  s->rowfree = NULL;
14663  }
14664  if (errp) {
14665  sqlite3_free(errp);
14666  errp = NULL;
14667  }
14668  s->rowp = s->rowprs = -1;
14669  return SQL_SUCCESS;
14670 }
14671 
14672 #ifndef WINTERFACE
14673 
14687 SQLRETURN SQL_API
14688 SQLTables(SQLHSTMT stmt,
14689  SQLCHAR *cat, SQLSMALLINT catLen,
14690  SQLCHAR *schema, SQLSMALLINT schemaLen,
14691  SQLCHAR *table, SQLSMALLINT tableLen,
14692  SQLCHAR *type, SQLSMALLINT typeLen)
14693 {
14694 #if defined(_WIN32) || defined(_WIN64)
14695  char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
14696 #endif
14697  SQLRETURN ret;
14698 
14699  HSTMT_LOCK(stmt);
14700 #if defined(_WIN32) || defined(_WIN64)
14701  if (!((STMT *) stmt)->oemcp[0]) {
14702  ret = drvtables(stmt, cat, catLen, schema, schemaLen,
14703  table, tableLen, type, typeLen);
14704  goto done2;
14705  }
14706  if (cat) {
14707  c = wmb_to_utf_c((char *) cat, catLen);
14708  if (!c) {
14709  ret = nomem((STMT *) stmt);
14710  goto done;
14711  }
14712  }
14713  if (schema) {
14714  s = wmb_to_utf_c((char *) schema, schemaLen);
14715  if (!s) {
14716  ret = nomem((STMT *) stmt);
14717  goto done;
14718  }
14719  }
14720  if (table) {
14721  t = wmb_to_utf_c((char *) table, tableLen);
14722  if (!t) {
14723  ret = nomem((STMT *) stmt);
14724  goto done;
14725  }
14726  }
14727  if (type) {
14728  y = wmb_to_utf_c((char *) type, typeLen);
14729  if (!y) {
14730  ret = nomem((STMT *) stmt);
14731  goto done;
14732  }
14733  }
14734  ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
14735  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
14736 #else
14737  ret = drvtables(stmt, cat, catLen, schema, schemaLen,
14738  table, tableLen, type, typeLen);
14739 #endif
14740 #if defined(_WIN32) || defined(_WIN64)
14741 done:
14742  uc_free(y);
14743  uc_free(t);
14744  uc_free(s);
14745  uc_free(c);
14746 done2:
14747  ;
14748 #endif
14749  HSTMT_UNLOCK(stmt);
14750  return ret;
14751 }
14752 #endif
14753 
14754 #ifdef WINTERFACE
14755 
14769 SQLRETURN SQL_API
14770 SQLTablesW(SQLHSTMT stmt,
14771  SQLWCHAR *cat, SQLSMALLINT catLen,
14772  SQLWCHAR *schema, SQLSMALLINT schemaLen,
14773  SQLWCHAR *table, SQLSMALLINT tableLen,
14774  SQLWCHAR *type, SQLSMALLINT typeLen)
14775 {
14776  char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
14777  SQLRETURN ret;
14778 
14779  HSTMT_LOCK(stmt);
14780  if (cat) {
14781  c = uc_to_utf_c(cat, catLen);
14782  if (!c) {
14783  ret = nomem((STMT *) stmt);
14784  goto done;
14785  }
14786  }
14787  if (schema) {
14788  s = uc_to_utf_c(schema, schemaLen);
14789  if (!s) {
14790  ret = nomem((STMT *) stmt);
14791  goto done;
14792  }
14793  }
14794  if (table) {
14795  t = uc_to_utf_c(table, tableLen);
14796  if (!t) {
14797  ret = nomem((STMT *) stmt);
14798  goto done;
14799  }
14800  }
14801  if (type) {
14802  y = uc_to_utf_c(type, typeLen);
14803  if (!y) {
14804  ret = nomem((STMT *) stmt);
14805  goto done;
14806  }
14807  }
14808  ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
14809  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
14810 done:
14811  uc_free(y);
14812  uc_free(t);
14813  uc_free(s);
14814  uc_free(c);
14815  HSTMT_UNLOCK(stmt);
14816  return ret;
14817 }
14818 #endif
14819 
14824 static COL colSpec2[] = {
14825  { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
14826  { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
14827  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14828  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
14829  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
14830  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
14831  { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
14832  { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
14833  { "SYSTEM", "COLUMN", "SCALE", SQL_SMALLINT, 50 },
14834  { "SYSTEM", "COLUMN", "RADIX", SQL_SMALLINT, 50 },
14835  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
14836  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
14837  { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
14838  { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
14839  { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
14840  { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
14841  { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
14842  { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
14843 };
14844 
14845 static COL colSpec3[] = {
14846  { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
14847  { "SYSTEM", "COLUMN", "TABLE_SCHEM", 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", "COLUMN_SIZE", SQL_INTEGER, 50 },
14853  { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
14854  { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_SMALLINT, 50 },
14855  { "SYSTEM", "COLUMN", "NUM_PREC_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 
14880 static SQLRETURN
14881 drvcolumns(SQLHSTMT stmt,
14882  SQLCHAR *cat, SQLSMALLINT catLen,
14883  SQLCHAR *schema, SQLSMALLINT schemaLen,
14884  SQLCHAR *table, SQLSMALLINT tableLen,
14885  SQLCHAR *col, SQLSMALLINT colLen)
14886 {
14887  SQLRETURN sret;
14888  STMT *s;
14889  DBC *d;
14890  int ret, nrows, ncols, asize, i, k, roffs, namec;
14891  int tnrows, tncols, npatt;
14892  PTRDIFF_T size;
14893  char *errp = NULL, *sql, tname[512], cname[512], **rowp, **trows;
14894 
14895  sret = mkresultset(stmt, colSpec2, array_size(colSpec2),
14896  colSpec3, array_size(colSpec3), &asize);
14897  if (sret != SQL_SUCCESS) {
14898  return sret;
14899  }
14900  s = (STMT *) stmt;
14901  d = (DBC *) s->dbc;
14902  if (!table) {
14903  size = 1;
14904  tname[0] = '%';
14905  } else {
14906  if (tableLen == SQL_NTS) {
14907  size = sizeof (tname) - 1;
14908  } else {
14909  size = min(sizeof (tname) - 1, tableLen);
14910  }
14911  strncpy(tname, (char *) table, size);
14912  }
14913  tname[size] = '\0';
14914  npatt = unescpat(tname);
14915  size = 0;
14916  if (col) {
14917  if (colLen == SQL_NTS) {
14918  size = sizeof (cname) - 1;
14919  } else {
14920  size = min(sizeof (cname) - 1, colLen);
14921  }
14922  strncpy(cname, (char *) col, size);
14923  }
14924  cname[size] = '\0';
14925  if (!strcmp(cname, "%")) {
14926  cname[0] = '\0';
14927  }
14928  sql = sqlite3_mprintf("select tbl_name from sqlite_master where "
14929  "(type = 'table' or type = 'view') "
14930  "and tbl_name %s %Q", npatt ? "like" : "=", tname);
14931  if (!sql) {
14932  return nomem(s);
14933  }
14934  sret = starttran(s);
14935  if (sret != SQL_SUCCESS) {
14936  sqlite3_free(sql);
14937  return sret;
14938  }
14939  dbtraceapi(d, "sqlite3_get_table", sql);
14940  ret = sqlite3_get_table(d->sqlite, sql, &trows, &tnrows, &tncols, &errp);
14941  sqlite3_free(sql);
14942  if (ret != SQLITE_OK) {
14943  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
14944  errp ? errp : "unknown error", ret);
14945  if (errp) {
14946  sqlite3_free(errp);
14947  errp = NULL;
14948  }
14949  return SQL_ERROR;
14950  }
14951  if (errp) {
14952  sqlite3_free(errp);
14953  errp = NULL;
14954  }
14955  /* pass 1: compute number of rows of result set */
14956  if (tncols * tnrows <= 0) {
14957  sqlite3_free_table(trows);
14958  return SQL_SUCCESS;
14959  }
14960  size = 0;
14961  for (i = 1; i <= tnrows; i++) {
14962  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
14963  if (!sql) {
14964  sqlite3_free_table(trows);
14965  return nomem(s);
14966  }
14967  dbtraceapi(d, "sqlite3_get_table", sql);
14968  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
14969  sqlite3_free(sql);
14970  if (ret != SQLITE_OK) {
14971  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
14972  errp ? errp : "unknown error", ret);
14973  if (errp) {
14974  sqlite3_free(errp);
14975  errp = NULL;
14976  }
14977  sqlite3_free_table(trows);
14978  return SQL_ERROR;
14979  }
14980  if (errp) {
14981  sqlite3_free(errp);
14982  errp = NULL;
14983  }
14984  if (ncols * nrows > 0) {
14985  namec = -1;
14986  for (k = 0; k < ncols; k++) {
14987  if (strcmp(rowp[k], "name") == 0) {
14988  namec = k;
14989  break;
14990  }
14991  }
14992  if (cname[0]) {
14993  if (namec >= 0) {
14994  for (k = 1; k <= nrows; k++) {
14995  if (namematch(rowp[k * ncols + namec], cname, 1)) {
14996  size++;
14997  }
14998  }
14999  }
15000  } else {
15001  size += nrows;
15002  }
15003  }
15004  sqlite3_free_table(rowp);
15005  }
15006  /* pass 2: fill result set */
15007  if (size <= 0) {
15008  sqlite3_free_table(trows);
15009  return SQL_SUCCESS;
15010  }
15011  s->nrows = size;
15012  size = (size + 1) * asize;
15013  s->rows = xmalloc((size + 1) * sizeof (char *));
15014  if (!s->rows) {
15015  s->nrows = 0;
15016  sqlite3_free_table(trows);
15017  return nomem(s);
15018  }
15019  s->rows[0] = (char *) size;
15020  s->rows += 1;
15021  memset(s->rows, 0, sizeof (char *) * size);
15022  s->rowfree = freerows;
15023  roffs = 1;
15024  for (i = 1; i <= tnrows; i++) {
15025  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
15026  if (!sql) {
15027  sqlite3_free_table(trows);
15028  return nomem(s);
15029  }
15030  dbtraceapi(d, "sqlite3_get_table", sql);
15031  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15032  sqlite3_free(sql);
15033  if (ret != SQLITE_OK) {
15034  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15035  errp ? errp : "unknown error", ret);
15036  if (errp) {
15037  sqlite3_free(errp);
15038  errp = NULL;
15039  }
15040  sqlite3_free_table(trows);
15041  return SQL_ERROR;
15042  }
15043  if (errp) {
15044  sqlite3_free(errp);
15045  errp = NULL;
15046  }
15047  if (ncols * nrows > 0) {
15048  int m, mr, nr = nrows;
15049 
15050  namec = -1;
15051  for (k = 0; k < ncols; k++) {
15052  if (strcmp(rowp[k], "name") == 0) {
15053  namec = k;
15054  break;
15055  }
15056  }
15057  if (cname[0]) {
15058  nr = 0;
15059  if (namec >= 0) {
15060  for (k = 1; k <= nrows; k++) {
15061  if (namematch(rowp[k * ncols + namec], cname, 1)) {
15062  nr++;
15063  }
15064  }
15065  }
15066  }
15067  for (k = 0; k < nr; k++) {
15068  m = asize * (roffs + k);
15069 #if defined(_WIN32) || defined(_WIN64)
15070  s->rows[m + 0] = xstrdup(d->xcelqrx ? "main" : "");
15071  s->rows[m + 1] = xstrdup("");
15072 #else
15073  s->rows[m + 0] = xstrdup("");
15074  s->rows[m + 1] = xstrdup("");
15075 #endif
15076  s->rows[m + 2] = xstrdup(trows[i]);
15077  s->rows[m + 8] = xstrdup("10");
15078  s->rows[m + 9] = xstrdup("0");
15079  s->rows[m + 15] = xstrdup("16384");
15080  }
15081  for (k = 0; nr && k < ncols; k++) {
15082  if (strcmp(rowp[k], "cid") == 0) {
15083  for (mr = 0, m = 1; m <= nrows; m++) {
15084  char buf[256];
15085  int ir, coln = k;
15086 
15087  if (cname[0] &&
15088  !namematch(rowp[m * ncols + namec], cname, 1)) {
15089  continue;
15090  }
15091  ir = asize * (roffs + mr);
15092  sscanf(rowp[m * ncols + k], "%d", &coln);
15093  sprintf(buf, "%d", coln + 1);
15094  s->rows[ir + 16] = xstrdup(buf);
15095  ++mr;
15096  }
15097  } else if (k == namec) {
15098  for (mr = 0, m = 1; m <= nrows; m++) {
15099  int ir;
15100 
15101  if (cname[0] &&
15102  !namematch(rowp[m * ncols + namec], cname, 1)) {
15103  continue;
15104  }
15105  ir = asize * (roffs + mr);
15106  s->rows[ir + 3] = xstrdup(rowp[m * ncols + k]);
15107  ++mr;
15108  }
15109  } else if (strcmp(rowp[k], "notnull") == 0) {
15110  for (mr = 0, m = 1; m <= nrows; m++) {
15111  int ir;
15112 
15113  if (cname[0] &&
15114  !namematch(rowp[m * ncols + namec], cname, 1)) {
15115  continue;
15116  }
15117  ir = asize * (roffs + mr);
15118  if (*rowp[m * ncols + k] != '0') {
15119  s->rows[ir + 10] = xstrdup(stringify(SQL_FALSE));
15120  } else {
15121  s->rows[ir + 10] = xstrdup(stringify(SQL_TRUE));
15122  }
15123  s->rows[ir + 17] =
15124  xstrdup((*rowp[m * ncols + k] != '0') ?
15125  "NO" : "YES");
15126  ++mr;
15127  }
15128  } else if (strcmp(rowp[k], "dflt_value") == 0) {
15129  for (mr = 0, m = 1; m <= nrows; m++) {
15130  char *dflt = unquote(rowp[m * ncols + k]);
15131  int ir;
15132 
15133  if (cname[0] &&
15134  !namematch(rowp[m * ncols + namec], cname, 1)) {
15135  continue;
15136  }
15137  ir = asize * (roffs + mr);
15138  s->rows[ir + 12] = xstrdup(dflt ? dflt : "NULL");
15139  ++mr;
15140  }
15141  } else if (strcmp(rowp[k], "type") == 0) {
15142  for (mr = 0, m = 1; m <= nrows; m++) {
15143  char *typename = rowp[m * ncols + k];
15144  int sqltype, mm, dd, ir;
15145  char buf[256];
15146 
15147  if (cname[0] &&
15148  !namematch(rowp[m * ncols + namec], cname, 1)) {
15149  continue;
15150  }
15151  ir = asize * (roffs + mr);
15152  s->rows[ir + 5] = xstrdup(typename);
15153  sqltype = mapsqltype(typename, NULL, *s->ov3,
15154  s->nowchar[0], s->dobigint);
15155  getmd(typename, sqltype, &mm, &dd);
15156 #ifdef SQL_LONGVARCHAR
15157  if (sqltype == SQL_VARCHAR && mm > 255) {
15158  sqltype = SQL_LONGVARCHAR;
15159  }
15160 #endif
15161 #ifdef WINTERFACE
15162 #ifdef SQL_WLONGVARCHAR
15163  if (sqltype == SQL_WVARCHAR && mm > 255) {
15164  sqltype = SQL_WLONGVARCHAR;
15165  }
15166 #endif
15167 #endif
15168  if (sqltype == SQL_VARBINARY && mm > 255) {
15169  sqltype = SQL_LONGVARBINARY;
15170  }
15171  sprintf(buf, "%d", sqltype);
15172  s->rows[ir + 4] = xstrdup(buf);
15173  s->rows[ir + 13] = xstrdup(buf);
15174  sprintf(buf, "%d", mm);
15175  s->rows[ir + 7] = xstrdup(buf);
15176  sprintf(buf, "%d", dd);
15177  s->rows[ir + 6] = xstrdup(buf);
15178  ++mr;
15179  }
15180  }
15181  }
15182  roffs += nr;
15183  }
15184  sqlite3_free_table(rowp);
15185  }
15186  sqlite3_free_table(trows);
15187  return SQL_SUCCESS;
15188 }
15189 
15190 #ifndef WINTERFACE
15191 
15205 SQLRETURN SQL_API
15206 SQLColumns(SQLHSTMT stmt,
15207  SQLCHAR *cat, SQLSMALLINT catLen,
15208  SQLCHAR *schema, SQLSMALLINT schemaLen,
15209  SQLCHAR *table, SQLSMALLINT tableLen,
15210  SQLCHAR *col, SQLSMALLINT colLen)
15211 {
15212 #if defined(_WIN32) || defined(_WIN64)
15213  char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15214 #endif
15215  SQLRETURN ret;
15216 
15217  HSTMT_LOCK(stmt);
15218 #if defined(_WIN32) || defined(_WIN64)
15219  if (!((STMT *) stmt)->oemcp[0]) {
15220  ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15221  table, tableLen, col, colLen);
15222  goto done2;
15223  }
15224  if (cat) {
15225  c = wmb_to_utf_c((char *) cat, catLen);
15226  if (!c) {
15227  ret = nomem((STMT *) stmt);
15228  goto done;
15229  }
15230  }
15231  if (schema) {
15232  s = wmb_to_utf_c((char *) schema, schemaLen);
15233  if (!s) {
15234  ret = nomem((STMT *) stmt);
15235  goto done;
15236  }
15237  }
15238  if (table) {
15239  t = wmb_to_utf_c((char *) table, tableLen);
15240  if (!t) {
15241  ret = nomem((STMT *) stmt);
15242  goto done;
15243  }
15244  }
15245  if (col) {
15246  k = wmb_to_utf_c((char *) col, colLen);
15247  if (!k) {
15248  ret = nomem((STMT *) stmt);
15249  goto done;
15250  }
15251  }
15252  ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15253  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15254 #else
15255  ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15256  table, tableLen, col, colLen);
15257 #endif
15258 #if defined(_WIN32) || defined(_WIN64)
15259 done:
15260  uc_free(k);
15261  uc_free(t);
15262  uc_free(s);
15263  uc_free(c);
15264 done2:
15265  ;
15266 #endif
15267  HSTMT_UNLOCK(stmt);
15268  return ret;
15269 }
15270 #endif
15271 
15272 #ifdef WINTERFACE
15273 
15287 SQLRETURN SQL_API
15288 SQLColumnsW(SQLHSTMT stmt,
15289  SQLWCHAR *cat, SQLSMALLINT catLen,
15290  SQLWCHAR *schema, SQLSMALLINT schemaLen,
15291  SQLWCHAR *table, SQLSMALLINT tableLen,
15292  SQLWCHAR *col, SQLSMALLINT colLen)
15293 {
15294  char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15295  SQLRETURN ret;
15296 
15297  HSTMT_LOCK(stmt);
15298  if (cat) {
15299  c = uc_to_utf_c(cat, catLen);
15300  if (!c) {
15301  ret = nomem((STMT *) stmt);
15302  goto done;
15303  }
15304  }
15305  if (schema) {
15306  s = uc_to_utf_c(schema, schemaLen);
15307  if (!s) {
15308  ret = nomem((STMT *) stmt);
15309  goto done;
15310  }
15311  }
15312  if (table) {
15313  t = uc_to_utf_c(table, tableLen);
15314  if (!t) {
15315  ret = nomem((STMT *) stmt);
15316  goto done;
15317  }
15318  }
15319  if (col) {
15320  k = uc_to_utf_c(col, colLen);
15321  if (!k) {
15322  ret = nomem((STMT *) stmt);
15323  goto done;
15324  }
15325  }
15326  ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15327  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15328 done:
15329  uc_free(k);
15330  uc_free(t);
15331  uc_free(s);
15332  uc_free(c);
15333  HSTMT_UNLOCK(stmt);
15334  return ret;
15335 
15336 }
15337 #endif
15338 
15343 static COL typeSpec2[] = {
15344  { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15345  { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15346  { "SYSTEM", "TYPE", "PRECISION", SQL_INTEGER, 9 },
15347  { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15348  { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15349  { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15350  { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15351  { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15352  { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15353  { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15354  { "SYSTEM", "TYPE", "MONEY", SQL_SMALLINT, 2 },
15355  { "SYSTEM", "TYPE", "AUTO_INCREMENT", SQL_SMALLINT, 2 },
15356  { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15357  { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15358  { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 }
15359 };
15360 
15361 static COL typeSpec3[] = {
15362  { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15363  { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15364  { "SYSTEM", "TYPE", "COLUMN_SIZE", SQL_INTEGER, 9 },
15365  { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15366  { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15367  { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15368  { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15369  { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15370  { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15371  { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15372  { "SYSTEM", "TYPE", "FIXED_PREC_SCALE", SQL_SMALLINT, 2 },
15373  { "SYSTEM", "TYPE", "AUTO_UNIQUE_VALUE", SQL_SMALLINT, 2 },
15374  { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15375  { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15376  { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 },
15377  { "SYSTEM", "TYPE", "SQL_DATA_TYPE", SQL_SMALLINT, 2 },
15378  { "SYSTEM", "TYPE", "SQL_DATETIME_SUB", SQL_SMALLINT, 2 },
15379  { "SYSTEM", "TYPE", "NUM_PREC_RADIX", SQL_INTEGER, 4 },
15380  { "SYSTEM", "TYPE", "INTERVAL_PRECISION", SQL_SMALLINT, 2 }
15381 };
15382 
15393 static void
15394 mktypeinfo(STMT *s, int row, int asize, char *typename, int type, int tind)
15395 {
15396  int offs = row * asize;
15397  char *tcode, *crpar = NULL, *quote = NULL, *sign = stringify(SQL_FALSE);
15398  static char tcodes[32 * 32];
15399 
15400  if (tind <= 0) {
15401  tind = row;
15402  }
15403  tcode = tcodes + tind * 32;
15404  sprintf(tcode, "%d", type);
15405  s->rows[offs + 0] = typename;
15406  s->rows[offs + 1] = tcode;
15407  if (asize >= 17) {
15408  s->rows[offs + 15] = tcode;
15409  s->rows[offs + 16] = "0";
15410  }
15411  switch (type) {
15412  default:
15413 #ifdef SQL_LONGVARCHAR
15414  case SQL_LONGVARCHAR:
15415 #ifdef WINTERFACE
15416  case SQL_WLONGVARCHAR:
15417 #endif
15418  crpar = "length";
15419  quote = "'";
15420  sign = NULL;
15421  s->rows[offs + 2] = "65536";
15422  break;
15423 #endif
15424 #ifdef SQL_BIT
15425  case SQL_BIT:
15426  sign = NULL;
15427  s->rows[offs + 2] = "1";
15428  break;
15429 #endif
15430  case SQL_CHAR:
15431  case SQL_VARCHAR:
15432 #ifdef WINTERFACE
15433  case SQL_WCHAR:
15434  case SQL_WVARCHAR:
15435 #endif
15436  s->rows[offs + 2] = "255";
15437  crpar = "length";
15438  quote = "'";
15439  sign = NULL;
15440  break;
15441  case SQL_TINYINT:
15442  s->rows[offs + 2] = "3";
15443  break;
15444  case SQL_SMALLINT:
15445  s->rows[offs + 2] = "5";
15446  break;
15447  case SQL_INTEGER:
15448  s->rows[offs + 2] = "9";
15449  break;
15450 #ifdef SQL_BIGINT
15451  case SQL_BIGINT:
15452  s->rows[offs + 2] = "19";
15453  break;
15454 #endif
15455  case SQL_FLOAT:
15456  s->rows[offs + 2] = "7";
15457  break;
15458  case SQL_DOUBLE:
15459  s->rows[offs + 2] = "15";
15460  break;
15461 #ifdef SQL_TYPE_DATE
15462  case SQL_TYPE_DATE:
15463 #endif
15464  case SQL_DATE:
15465  s->rows[offs + 2] = "10";
15466  quote = "'";
15467  sign = NULL;
15468  break;
15469 #ifdef SQL_TYPE_TIME
15470  case SQL_TYPE_TIME:
15471 #endif
15472  case SQL_TIME:
15473  s->rows[offs + 2] = "8";
15474  quote = "'";
15475  sign = NULL;
15476  break;
15477 #ifdef SQL_TYPE_TIMESTAMP
15478  case SQL_TYPE_TIMESTAMP:
15479 #endif
15480  case SQL_TIMESTAMP:
15481  s->rows[offs + 2] = "32";
15482  quote = "'";
15483  sign = NULL;
15484  break;
15485  case SQL_VARBINARY:
15486  sign = NULL;
15487  s->rows[offs + 2] = "255";
15488  break;
15489  case SQL_LONGVARBINARY:
15490  sign = NULL;
15491  s->rows[offs + 2] = "65536";
15492  break;
15493  }
15494  s->rows[offs + 3] = s->rows[offs + 4] = quote;
15495  s->rows[offs + 5] = crpar;
15496  s->rows[offs + 6] = stringify(SQL_NULLABLE);
15497  s->rows[offs + 7] = stringify(SQL_FALSE);
15498  s->rows[offs + 8] = stringify(SQL_SEARCHABLE);
15499  s->rows[offs + 9] = sign;
15500  s->rows[offs + 10] = stringify(SQL_FALSE);
15501  s->rows[offs + 11] = stringify(SQL_FALSE);
15502  s->rows[offs + 12] = typename;
15503  switch (type) {
15504  case SQL_DATE:
15505  case SQL_TIME:
15506  s->rows[offs + 13] = "0";
15507  s->rows[offs + 14] = "0";
15508  break;
15509 #ifdef SQL_TYPE_TIMESTAMP
15510  case SQL_TYPE_TIMESTAMP:
15511 #endif
15512  case SQL_TIMESTAMP:
15513  s->rows[offs + 13] = "0";
15514  s->rows[offs + 14] = "3";
15515  break;
15516  default:
15517  s->rows[offs + 13] = NULL;
15518  s->rows[offs + 14] = NULL;
15519  break;
15520  }
15521 }
15522 
15531 static int
15532 typeinfosort(const void *a, const void *b)
15533 {
15534  char **pa = (char **) a;
15535  char **pb = (char **) b;
15536  int na, nb;
15537 
15538  na = strtol(pa[1], NULL, 0);
15539  nb = strtol(pb[1], NULL, 0);
15540  return na - nb;
15541 }
15542 
15550 static SQLRETURN
15551 drvgettypeinfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
15552 {
15553  SQLRETURN ret;
15554  STMT *s;
15555  int asize;
15556 
15557  ret = mkresultset(stmt, typeSpec2, array_size(typeSpec2),
15558  typeSpec3, array_size(typeSpec3), &asize);
15559  if (ret != SQL_SUCCESS) {
15560  return ret;
15561  }
15562  s = (STMT *) stmt;
15563 #ifdef SQL_LONGVARCHAR
15564  s->nrows = (sqltype == SQL_ALL_TYPES) ? 13 : 1;
15565 #else
15566  s->nrows = (sqltype == SQL_ALL_TYPES) ? 12 : 1;
15567 #endif
15568  if (sqltype == SQL_ALL_TYPES) {
15569 #ifdef WINTERFACE
15570  s->nrows += 2;
15571 #ifdef SQL_WLONGVARCHAR
15572  s->nrows += 2;
15573 #endif
15574 #endif
15575  }
15576  if (sqltype == SQL_ALL_TYPES) {
15577  s->nrows += 2;
15578 #ifdef SQL_BIT
15579  s->nrows += 1;
15580 #endif
15581 #ifdef SQL_BIGINT
15582  s->nrows += 1;
15583 #endif
15584  }
15585  s->rows = (char **) xmalloc(sizeof (char *) * (s->nrows + 1) * asize);
15586  if (!s->rows) {
15587  s->nrows = 0;
15588  return nomem(s);
15589  }
15590 #ifdef MEMORY_DEBUG
15591  s->rowfree = xfree__;
15592 #else
15593  s->rowfree = sqlite3_free;
15594 #endif
15595  memset(s->rows, 0, sizeof (char *) * (s->nrows + 1) * asize);
15596  if (sqltype == SQL_ALL_TYPES) {
15597  int cc = 1;
15598 
15599  mktypeinfo(s, cc++, asize, "varchar", SQL_VARCHAR, 0);
15600  mktypeinfo(s, cc++, asize, "tinyint", SQL_TINYINT, 0);
15601  mktypeinfo(s, cc++, asize, "smallint", SQL_SMALLINT, 0);
15602  mktypeinfo(s, cc++, asize, "integer", SQL_INTEGER, 0);
15603  mktypeinfo(s, cc++, asize, "float", SQL_FLOAT, 0);
15604  mktypeinfo(s, cc++, asize, "double", SQL_DOUBLE, 0);
15605 #ifdef SQL_TYPE_DATE
15606  mktypeinfo(s, cc++, asize, "date",
15607  (*s->ov3) ? SQL_TYPE_DATE : SQL_DATE, 0);
15608 #else
15609  mktypeinfo(s, cc++, asize, "date", SQL_DATE, 0);
15610 #endif
15611 #ifdef SQL_TYPE_TIME
15612  mktypeinfo(s, cc++, asize, "time",
15613  (*s->ov3) ? SQL_TYPE_TIME : SQL_TIME, 0);
15614 #else
15615  mktypeinfo(s, cc++, asize, "time", SQL_TIME, 0);
15616 #endif
15617 #ifdef SQL_TYPE_TIMESTAMP
15618  mktypeinfo(s, cc++, asize, "timestamp",
15619  (*s->ov3) ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP, 0);
15620 #else
15621  mktypeinfo(s, cc++, asize, "timestamp", SQL_TIMESTAMP, 0);
15622 #endif
15623  mktypeinfo(s, cc++, asize, "char", SQL_CHAR, 0);
15624  mktypeinfo(s, cc++, asize, "numeric", SQL_DOUBLE, 0);
15625 #ifdef SQL_LONGVARCHAR
15626  mktypeinfo(s, cc++, asize, "text", SQL_LONGVARCHAR, 0);
15627  mktypeinfo(s, cc++, asize, "longvarchar", SQL_LONGVARCHAR, 0);
15628 #else
15629  mktypeinfo(s, cc++, asize, "text", SQL_VARCHAR, 0);
15630 #endif
15631  mktypeinfo(s, cc++, asize, "varbinary", SQL_VARBINARY, 0);
15632  mktypeinfo(s, cc++, asize, "longvarbinary", SQL_LONGVARBINARY, 0);
15633 #ifdef SQL_BIT
15634  mktypeinfo(s, cc++, asize, "bit", SQL_BIT, 0);
15635 #endif
15636 #ifdef SQL_BIGINT
15637  mktypeinfo(s, cc++, asize, "bigint", SQL_BIGINT, 0);
15638 #endif
15639 #ifdef WINTERFACE
15640  mktypeinfo(s, cc++, asize, "wvarchar", SQL_WVARCHAR, 0);
15641  mktypeinfo(s, cc++, asize, "wchar", SQL_WCHAR, 0);
15642 #ifdef SQL_WLONGVARCHAR
15643  mktypeinfo(s, cc++, asize, "wtext", SQL_WLONGVARCHAR, 0);
15644  mktypeinfo(s, cc++, asize, "longwvarchar", SQL_WLONGVARCHAR, 0);
15645 #endif
15646 #endif
15647  qsort(s->rows + asize, s->nrows, sizeof (char *) * asize,
15648  typeinfosort);
15649  } else {
15650  switch (sqltype) {
15651  case SQL_CHAR:
15652  mktypeinfo(s, 1, asize, "char", SQL_CHAR, 10);
15653  break;
15654  case SQL_VARCHAR:
15655  mktypeinfo(s, 1, asize, "varchar", SQL_VARCHAR, 1);
15656  break;
15657  case SQL_TINYINT:
15658  mktypeinfo(s, 1, asize, "tinyint", SQL_TINYINT, 2);
15659  break;
15660  case SQL_SMALLINT:
15661  mktypeinfo(s, 1, asize, "smallint", SQL_SMALLINT, 3);
15662  break;
15663  case SQL_INTEGER:
15664  mktypeinfo(s, 1, asize, "integer", SQL_INTEGER, 4);
15665  break;
15666  case SQL_FLOAT:
15667  mktypeinfo(s, 1, asize, "float", SQL_FLOAT, 5);
15668  break;
15669  case SQL_DOUBLE:
15670  mktypeinfo(s, 1, asize, "double", SQL_DOUBLE, 6);
15671  break;
15672 #ifdef SQL_TYPE_DATE
15673  case SQL_TYPE_DATE:
15674  mktypeinfo(s, 1, asize, "date", SQL_TYPE_DATE, 25);
15675  break;
15676 #endif
15677  case SQL_DATE:
15678  mktypeinfo(s, 1, asize, "date", SQL_DATE, 7);
15679  break;
15680 #ifdef SQL_TYPE_TIME
15681  case SQL_TYPE_TIME:
15682  mktypeinfo(s, 1, asize, "time", SQL_TYPE_TIME, 26);
15683  break;
15684 #endif
15685  case SQL_TIME:
15686  mktypeinfo(s, 1, asize, "time", SQL_TIME, 8);
15687  break;
15688 #ifdef SQL_TYPE_TIMESTAMP
15689  case SQL_TYPE_TIMESTAMP:
15690  mktypeinfo(s, 1, asize, "timestamp", SQL_TYPE_TIMESTAMP, 27);
15691  break;
15692 #endif
15693  case SQL_TIMESTAMP:
15694  mktypeinfo(s, 1, asize, "timestamp", SQL_TIMESTAMP, 9);
15695  break;
15696 #ifdef SQL_LONGVARCHAR
15697  case SQL_LONGVARCHAR:
15698  mktypeinfo(s, 1, asize, "longvarchar", SQL_LONGVARCHAR, 12);
15699  break;
15700 #endif
15701  case SQL_VARBINARY:
15702  mktypeinfo(s, 1, asize, "varbinary", SQL_VARBINARY, 30);
15703  break;
15704  case SQL_LONGVARBINARY:
15705  mktypeinfo(s, 1, asize, "longvarbinary", SQL_LONGVARBINARY, 31);
15706  break;
15707 #ifdef SQL_BIT
15708  case SQL_BIT:
15709  mktypeinfo(s, 1, asize, "bit", SQL_BIT, 29);
15710  break;
15711 #endif
15712 #ifdef SQL_BIGINT
15713  case SQL_BIGINT:
15714  mktypeinfo(s, 1, asize, "bigint", SQL_BIGINT, 28);
15715  break;
15716 #endif
15717 #ifdef WINTERFACE
15718 #ifdef SQL_WCHAR
15719  case SQL_WCHAR:
15720  mktypeinfo(s, 1, asize, "wchar", SQL_WCHAR, 18);
15721  break;
15722 #endif
15723 #ifdef SQL_WVARCHAR
15724  case SQL_WVARCHAR:
15725  mktypeinfo(s, 1, asize, "wvarchar", SQL_WVARCHAR, 19);
15726  break;
15727 #endif
15728 #ifdef SQL_WLONGVARCHAR
15729  case SQL_WLONGVARCHAR:
15730  mktypeinfo(s, 1, asize, "longwvarchar", SQL_WLONGVARCHAR, 20);
15731  break;
15732 #endif
15733 #endif
15734  default:
15735  s->nrows = 0;
15736  }
15737  }
15738  return SQL_SUCCESS;
15739 }
15740 
15741 #ifndef WINTERFACE
15742 
15749 SQLRETURN SQL_API
15750 SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
15751 {
15752  SQLRETURN ret;
15753 
15754  HSTMT_LOCK(stmt);
15755  ret = drvgettypeinfo(stmt, sqltype);
15756  HSTMT_UNLOCK(stmt);
15757  return ret;
15758 }
15759 #endif
15760 
15761 #ifdef WINTERFACE
15762 
15769 SQLRETURN SQL_API
15770 SQLGetTypeInfoW(SQLHSTMT stmt, SQLSMALLINT sqltype)
15771 {
15772  SQLRETURN ret;
15773 
15774  HSTMT_LOCK(stmt);
15775  ret = drvgettypeinfo(stmt, sqltype);
15776  HSTMT_UNLOCK(stmt);
15777  return ret;
15778 }
15779 #endif
15780 
15785 static COL statSpec2[] = {
15786  { "SYSTEM", "STATISTICS", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
15787  { "SYSTEM", "STATISTICS", "TABLE_OWNER", SCOL_VARCHAR, 50 },
15788  { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
15789  { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
15790  { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
15791  { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
15792  { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
15793  { "SYSTEM", "STATISTICS", "SEQ_IN_INDEX", SQL_SMALLINT, 50 },
15794  { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15795  { "SYSTEM", "STATISTICS", "COLLATION", SCOL_CHAR, 1 },
15796  { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
15797  { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
15798  { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
15799 };
15800 
15801 static COL statSpec3[] = {
15802  { "SYSTEM", "STATISTICS", "TABLE_CAT", SCOL_VARCHAR, 50 },
15803  { "SYSTEM", "STATISTICS", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
15804  { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
15805  { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
15806  { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
15807  { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
15808  { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
15809  { "SYSTEM", "STATISTICS", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
15810  { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15811  { "SYSTEM", "STATISTICS", "ASC_OR_DESC", SCOL_CHAR, 1 },
15812  { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
15813  { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
15814  { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
15815 };
15816 
15831 static SQLRETURN
15832 drvstatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
15833  SQLCHAR *schema, SQLSMALLINT schemaLen,
15834  SQLCHAR *table, SQLSMALLINT tableLen,
15835  SQLUSMALLINT itype, SQLUSMALLINT resv)
15836 {
15837  SQLRETURN sret;
15838  STMT *s;
15839  DBC *d;
15840  int i, asize, ret, nrows, ncols, offs, namec, uniquec, addipk = 0;
15841  PTRDIFF_T size;
15842  char **rowp, *errp = NULL, *sql, tname[512];
15843 
15844  sret = mkresultset(stmt, statSpec2, array_size(statSpec2),
15845  statSpec3, array_size(statSpec3), &asize);
15846  if (sret != SQL_SUCCESS) {
15847  return sret;
15848  }
15849  s = (STMT *) stmt;
15850  d = (DBC *) s->dbc;
15851  if (!table || table[0] == '\0' || table[0] == '%') {
15852  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
15853  return SQL_ERROR;
15854  }
15855  if (tableLen == SQL_NTS) {
15856  size = sizeof (tname) - 1;
15857  } else {
15858  size = min(sizeof (tname) - 1, tableLen);
15859  }
15860  strncpy(tname, (char *) table, size);
15861  tname[size] = '\0';
15862  unescpat(tname);
15863  sret = starttran(s);
15864  if (sret != SQL_SUCCESS) {
15865  return sret;
15866  }
15867  /*
15868  * Try integer primary key (autoincrement) first
15869  */
15870  if (itype == SQL_INDEX_UNIQUE || itype == SQL_INDEX_ALL) {
15871  rowp = 0;
15872  ret = SQLITE_ERROR;
15873  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
15874  if (sql) {
15875  dbtraceapi(d, "sqlite3_get_table", sql);
15876  ret = sqlite3_get_table(d->sqlite, sql, &rowp,
15877  &nrows, &ncols, NULL);
15878  sqlite3_free(sql);
15879  }
15880  if (ret == SQLITE_OK) {
15881  int colid, typec, npk = 0;
15882 
15883  namec = findcol(rowp, ncols, "name");
15884  uniquec = findcol(rowp, ncols, "pk");
15885  typec = findcol(rowp, ncols, "type");
15886  colid = findcol(rowp, ncols, "cid");
15887  if (namec < 0 || uniquec < 0 || typec < 0 || colid < 0) {
15888  goto noipk;
15889  }
15890  for (i = 1; i <= nrows; i++) {
15891  if (*rowp[i * ncols + uniquec] != '0' &&
15892  strlen(rowp[i * ncols + typec]) == 7 &&
15893  strncasecmp(rowp[i * ncols + typec], "integer", 7)
15894  == 0) {
15895  npk++;
15896  }
15897  }
15898  if (npk == 1) {
15899  addipk = 1;
15900  }
15901  }
15902 noipk:
15903  sqlite3_free_table(rowp);
15904  }
15905  sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
15906  if (!sql) {
15907  return nomem(s);
15908  }
15909  dbtraceapi(d, "sqlite3_get_table", sql);
15910  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15911  sqlite3_free(sql);
15912  if (ret != SQLITE_OK) {
15913  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15914  errp ? errp : "unknown error", ret);
15915  if (errp) {
15916  sqlite3_free(errp);
15917  errp = NULL;
15918  }
15919  return SQL_ERROR;
15920  }
15921  if (errp) {
15922  sqlite3_free(errp);
15923  errp = NULL;
15924  }
15925  size = 0;
15926  namec = findcol(rowp, ncols, "name");
15927  uniquec = findcol(rowp, ncols, "unique");
15928  if (namec < 0 || uniquec < 0) {
15929  goto nodata;
15930  }
15931  for (i = 1; i <= nrows; i++) {
15932  int nnrows, nncols;
15933  char **rowpp;
15934  int isuniq;
15935 
15936  isuniq = *rowp[i * ncols + uniquec] != '0';
15937  if (isuniq || itype == SQL_INDEX_ALL) {
15938  ret = SQLITE_ERROR;
15939  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
15940  rowp[i * ncols + namec]);
15941  if (sql) {
15942  dbtraceapi(d, "sqlite3_get_table", sql);
15943  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
15944  &nnrows, &nncols, NULL);
15945  sqlite3_free(sql);
15946  }
15947  if (ret == SQLITE_OK) {
15948  size += nnrows;
15949  sqlite3_free_table(rowpp);
15950  }
15951  }
15952  }
15953 nodata:
15954  if (addipk) {
15955  size++;
15956  }
15957  if (size == 0) {
15958  sqlite3_free_table(rowp);
15959  return SQL_SUCCESS;
15960  }
15961  s->nrows = size;
15962  size = (size + 1) * asize;
15963  s->rows = xmalloc((size + 1) * sizeof (char *));
15964  if (!s->rows) {
15965  s->nrows = 0;
15966  return nomem(s);
15967  }
15968  s->rows[0] = (char *) size;
15969  s->rows += 1;
15970  memset(s->rows, 0, sizeof (char *) * size);
15971  s->rowfree = freerows;
15972  offs = 0;
15973  if (addipk) {
15974  char **rowpp = 0;
15975  int nrows2, ncols2;
15976 
15977  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
15978  if (sql) {
15979  dbtraceapi(d, "sqlite3_get_table", sql);
15980  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
15981  &nrows2, &ncols2, NULL);
15982  sqlite3_free(sql);
15983  }
15984  if (ret == SQLITE_OK) {
15985  int colid, typec, roffs, namecc, uniquecc;
15986 
15987  namecc = findcol(rowpp, ncols2, "name");
15988  uniquecc = findcol(rowpp, ncols2, "pk");
15989  typec = findcol(rowpp, ncols2, "type");
15990  colid = findcol(rowpp, ncols2, "cid");
15991  if (namecc < 0 || uniquecc < 0 || typec < 0 || colid < 0) {
15992  addipk = 0;
15993  s->nrows--;
15994  goto nodata2;
15995  }
15996  for (i = 1; i <= nrows2; i++) {
15997  if (*rowpp[i * ncols2 + uniquecc] != '0' &&
15998  strlen(rowpp[i * ncols2 + typec]) == 7 &&
15999  strncasecmp(rowpp[i * ncols2 + typec], "integer", 7)
16000  == 0) {
16001  break;
16002  }
16003  }
16004  if (i > nrows2) {
16005  addipk = 0;
16006  s->nrows--;
16007  goto nodata2;
16008  }
16009  roffs = s->ncols;
16010 #if defined(_WIN32) || defined(_WIN64)
16011  s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
16012  s->rows[roffs + 1] = xstrdup("");
16013 #else
16014  s->rows[roffs + 0] = xstrdup("");
16015  s->rows[roffs + 1] = xstrdup("");
16016 #endif
16017  s->rows[roffs + 2] = xstrdup(tname);
16018  s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16019  s->rows[roffs + 5] = xstrdup("sqlite_autoindex_0");
16020  s->rows[roffs + 6] = xstrdup(stringify(SQL_INDEX_OTHER));
16021  s->rows[roffs + 7] = xstrdup("1");
16022  s->rows[roffs + 8] = xstrdup(rowpp[i * ncols2 + namecc]);
16023  s->rows[roffs + 9] = xstrdup("A");
16024  }
16025 nodata2:
16026  sqlite3_free_table(rowpp);
16027  }
16028  for (i = 1; i <= nrows; i++) {
16029  int nnrows, nncols;
16030  char **rowpp = 0;
16031 
16032  if (*rowp[i * ncols + uniquec] != '0' || itype == SQL_INDEX_ALL) {
16033  int k;
16034 
16035  ret = SQLITE_ERROR;
16036  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
16037  rowp[i * ncols + namec]);
16038  if (sql) {
16039  dbtraceapi(d, "sqlite3_get_table", sql);
16040  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16041  &nnrows, &nncols, NULL);
16042  sqlite3_free(sql);
16043  }
16044  if (ret != SQLITE_OK) {
16045  continue;
16046  }
16047  for (k = 0; nnrows && k < nncols; k++) {
16048  if (strcmp(rowpp[k], "name") == 0) {
16049  int m;
16050 
16051  for (m = 1; m <= nnrows; m++) {
16052  int roffs = (offs + addipk + m) * s->ncols;
16053  int isuniq;
16054 
16055  isuniq = *rowp[i * ncols + uniquec] != '0';
16056  s->rows[roffs + 0] = xstrdup("");
16057  s->rows[roffs + 1] = xstrdup("");
16058  s->rows[roffs + 2] = xstrdup(tname);
16059  if (isuniq) {
16060  s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16061  } else {
16062  s->rows[roffs + 3] = xstrdup(stringify(SQL_TRUE));
16063  }
16064  s->rows[roffs + 5] = xstrdup(rowp[i * ncols + namec]);
16065  s->rows[roffs + 6] =
16066  xstrdup(stringify(SQL_INDEX_OTHER));
16067  s->rows[roffs + 8] = xstrdup(rowpp[m * nncols + k]);
16068  s->rows[roffs + 9] = xstrdup("A");
16069  }
16070  } else if (strcmp(rowpp[k], "seqno") == 0) {
16071  int m;
16072 
16073  for (m = 1; m <= nnrows; m++) {
16074  int roffs = (offs + addipk + m) * s->ncols;
16075  int pos = m - 1;
16076  char buf[32];
16077 
16078  sscanf(rowpp[m * nncols + k], "%d", &pos);
16079  sprintf(buf, "%d", pos + 1);
16080  s->rows[roffs + 7] = xstrdup(buf);
16081  }
16082  }
16083  }
16084  offs += nnrows;
16085  sqlite3_free_table(rowpp);
16086  }
16087  }
16088  sqlite3_free_table(rowp);
16089  return SQL_SUCCESS;
16090 }
16091 
16092 #ifndef WINTERFACE
16093 
16107 SQLRETURN SQL_API
16108 SQLStatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
16109  SQLCHAR *schema, SQLSMALLINT schemaLen,
16110  SQLCHAR *table, SQLSMALLINT tableLen,
16111  SQLUSMALLINT itype, SQLUSMALLINT resv)
16112 {
16113 #if defined(_WIN32) || defined(_WIN64)
16114  char *c = NULL, *s = NULL, *t = NULL;
16115 #endif
16116  SQLRETURN ret;
16117 
16118  HSTMT_LOCK(stmt);
16119 #if defined(_WIN32) || defined(_WIN64)
16120  if (!((STMT *) stmt)->oemcp[0]) {
16121  ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16122  table, tableLen, itype, resv);
16123  goto done2;
16124  }
16125  if (cat) {
16126  c = wmb_to_utf_c((char *) cat, catLen);
16127  if (!c) {
16128  ret = nomem((STMT *) stmt);
16129  goto done;
16130  }
16131  }
16132  if (schema) {
16133  s = wmb_to_utf_c((char *) schema, schemaLen);
16134  if (!s) {
16135  ret = nomem((STMT *) stmt);
16136  goto done;
16137  }
16138  }
16139  if (table) {
16140  t = wmb_to_utf_c((char *) table, tableLen);
16141  if (!t) {
16142  ret = nomem((STMT *) stmt);
16143  goto done;
16144  }
16145  }
16146  ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16147  (SQLCHAR *) t, SQL_NTS, itype, resv);
16148 #else
16149  ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16150  table, tableLen, itype, resv);
16151 #endif
16152 #if defined(_WIN32) || defined(_WIN64)
16153 done:
16154  uc_free(t);
16155  uc_free(s);
16156  uc_free(c);
16157 done2:
16158  ;
16159 #endif
16160  HSTMT_UNLOCK(stmt);
16161  return ret;
16162 }
16163 #endif
16164 
16165 #ifdef WINTERFACE
16166 
16180 SQLRETURN SQL_API
16181 SQLStatisticsW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen,
16182  SQLWCHAR *schema, SQLSMALLINT schemaLen,
16183  SQLWCHAR *table, SQLSMALLINT tableLen,
16184  SQLUSMALLINT itype, SQLUSMALLINT resv)
16185 {
16186  char *c = NULL, *s = NULL, *t = NULL;
16187  SQLRETURN ret;
16188 
16189  HSTMT_LOCK(stmt);
16190  if (cat) {
16191  c = uc_to_utf_c(cat, catLen);
16192  if (!c) {
16193  ret = nomem((STMT *) stmt);
16194  goto done;
16195  }
16196  }
16197  if (schema) {
16198  s = uc_to_utf_c(schema, schemaLen);
16199  if (!s) {
16200  ret = nomem((STMT *) stmt);
16201  goto done;
16202  }
16203  }
16204  if (table) {
16205  t = uc_to_utf_c(table, tableLen);
16206  if (!t) {
16207  ret = nomem((STMT *) stmt);
16208  goto done;
16209  }
16210  }
16211  ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16212  (SQLCHAR *) t, SQL_NTS, itype, resv);
16213 done:
16214  uc_free(t);
16215  uc_free(s);
16216  uc_free(c);
16217  HSTMT_UNLOCK(stmt);
16218  return ret;
16219 }
16220 #endif
16221 
16233 SQLRETURN SQL_API
16234 SQLGetData(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
16235  SQLPOINTER val, SQLLEN len, SQLLEN *lenp)
16236 {
16237  STMT *s;
16238  SQLRETURN ret = SQL_ERROR;
16239 
16240  HSTMT_LOCK(stmt);
16241  if (stmt == SQL_NULL_HSTMT) {
16242  return SQL_INVALID_HANDLE;
16243  }
16244  s = (STMT *) stmt;
16245  if (col == 0 && s->bkmrk != SQL_UB_OFF) {
16246  if (s->bkmrk == SQL_UB_ON && type == SQL_C_BOOKMARK) {
16247  *((SQLINTEGER *) val) = s->rowp;
16248  if (lenp) {
16249  *lenp = sizeof (SQLINTEGER);
16250  }
16251  ret = SQL_SUCCESS;
16252  goto done;
16253  } else if (s->bkmrk == SQL_UB_VARIABLE && type == SQL_C_VARBOOKMARK) {
16254  if (s->has_rowid >= 0) {
16255  char **data, *endp = 0;
16256 
16257  data = s->rows + s->ncols + (s->rowp * s->ncols)
16258  + s->has_rowid;
16259 #ifdef __osf__
16260  *((sqlite_int64 *) val) = strtol(*data, &endp, 0);
16261 #else
16262  *((sqlite_int64 *) val) = strtoll(*data, &endp, 0);
16263 #endif
16264  } else {
16265  *((sqlite_int64 *) val) = s->rowp;
16266  }
16267  if (lenp) {
16268  *lenp = sizeof (sqlite_int64);
16269  }
16270  ret = SQL_SUCCESS;
16271  goto done;
16272  }
16273  }
16274  if (col < 1 || col > s->ncols) {
16275  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
16276  goto done;
16277  }
16278  --col;
16279  ret = getrowdata(s, col, type, val, len, lenp, 1);
16280 done:
16281  HSTMT_UNLOCK(stmt);
16282  return ret;
16283 }
16284 
16292 static SQLRETURN
16293 dofetchbind(STMT *s, int rsi)
16294 {
16295  int ret, i, withinfo = 0;
16296 
16297  s->row_status0[rsi] = SQL_ROW_SUCCESS;
16298  if (s->bkmrk != SQL_UB_OFF && s->bkmrkcol.valp) {
16299  int bsize = sizeof (SQLINTEGER);
16300 
16301  if (s->bkmrkcol.type == SQL_C_VARBOOKMARK) {
16302  SQLPOINTER *val;
16303 
16304  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16305  val = (SQLPOINTER)
16306  ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16307  } else {
16308  val = (SQLPOINTER)
16309  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * rsi);
16310  }
16311  if (s->bind_offs) {
16312  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
16313  }
16314  if (s->has_rowid >= 0) {
16315  char **data, *endp = 0;
16316 
16317  data = s->rows + s->ncols + (s->rowp * s->ncols)
16318  + s->has_rowid;
16319 #ifdef __osf__
16320  *(sqlite_int64 *) val = strtol(*data, &endp, 0);
16321 #else
16322  *(sqlite_int64 *) val = strtoll(*data, &endp, 0);
16323 #endif
16324  } else {
16325  *(sqlite_int64 *) val = s->rowp;
16326  }
16327  bsize = sizeof (sqlite_int64);
16328  } else {
16329  SQLINTEGER *val;
16330 
16331  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16332  val = (SQLINTEGER *)
16333  ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16334  } else {
16335  val = (SQLINTEGER *) s->bkmrkcol.valp + rsi;
16336  }
16337  if (s->bind_offs) {
16338  val = (SQLINTEGER *) ((char *) val + *s->bind_offs);
16339  }
16340  *val = s->rowp;
16341  }
16342  if (s->bkmrkcol.lenp) {
16343  SQLLEN *ival;
16344 
16345  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16346  ival = (SQLLEN *)
16347  ((char *) s->bkmrkcol.lenp + s->bind_type * rsi);
16348  } else {
16349  ival = &s->bkmrkcol.lenp[rsi];
16350  }
16351  if (s->bind_offs) {
16352  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
16353  }
16354  *ival = bsize;
16355  }
16356  }
16357  ret = SQL_SUCCESS;
16358  for (i = 0; s->bindcols && i < s->ncols; i++) {
16359  BINDCOL *b = &s->bindcols[i];
16360  SQLPOINTER dp = 0;
16361  SQLLEN *lp = 0;
16362 
16363  b->offs = 0;
16364  if (b->valp) {
16365  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16366  dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
16367  } else {
16368  dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
16369  }
16370  if (s->bind_offs) {
16371  dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
16372  }
16373  }
16374  if (b->lenp) {
16375  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16376  lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
16377  } else {
16378  lp = b->lenp + rsi;
16379  }
16380  if (s->bind_offs) {
16381  lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
16382  }
16383  }
16384  if (dp || lp) {
16385  ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp, b->max, lp, 0);
16386  if (!SQL_SUCCEEDED(ret)) {
16387  s->row_status0[rsi] = SQL_ROW_ERROR;
16388  break;
16389  }
16390  if (ret != SQL_SUCCESS) {
16391  withinfo = 1;
16392 #ifdef SQL_ROW_SUCCESS_WITH_INFO
16393  s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
16394 #endif
16395  }
16396  }
16397  }
16398  if (SQL_SUCCEEDED(ret)) {
16399  ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16400  }
16401  return ret;
16402 }
16403 
16412 static SQLRETURN
16413 drvfetchscroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLINTEGER offset)
16414 {
16415  STMT *s;
16416  int i, withinfo = 0;
16417  SQLRETURN ret;
16418 
16419  if (stmt == SQL_NULL_HSTMT) {
16420  return SQL_INVALID_HANDLE;
16421  }
16422  s = (STMT *) stmt;
16423  for (i = 0; i < s->rowset_size; i++) {
16424  s->row_status0[i] = SQL_ROW_NOROW;
16425  }
16426  if (s->row_status) {
16427  memcpy(s->row_status, s->row_status0,
16428  sizeof (SQLUSMALLINT) * s->rowset_size);
16429  }
16430  s->row_count0 = 0;
16431  if (s->row_count) {
16432  *s->row_count = s->row_count0;
16433  }
16434  if (!s->bindcols) {
16435  for (i = 0; i < s->rowset_size; i++) {
16436  s->row_status0[i] = SQL_ROW_ERROR;
16437  }
16438  ret = SQL_ERROR;
16439  i = 0;
16440  goto done2;
16441  }
16442  if (s->isselect != 1 && s->isselect != -1) {
16443  setstat(s, -1, "no result set available", "24000");
16444  ret = SQL_ERROR;
16445  i = s->nrows;
16446  goto done2;
16447  }
16448  if (s->curtype == SQL_CURSOR_FORWARD_ONLY && orient != SQL_FETCH_NEXT) {
16449  setstat(s, -1, "wrong fetch direction", "01000");
16450  ret = SQL_ERROR;
16451  i = 0;
16452  goto done2;
16453  }
16454  ret = SQL_SUCCESS;
16455  i = 0;
16456  if (((DBC *) (s->dbc))->cur_s3stmt == s && s->s3stmt) {
16457  s->rowp = s->rowprs = 0;
16458  for (; i < s->rowset_size; i++) {
16459  if (s->max_rows && s->s3stmt_rownum + 1 >= s->max_rows) {
16460  ret = (i == 0) ? SQL_NO_DATA : SQL_SUCCESS;
16461  break;
16462  }
16463  ret = s3stmt_step(s);
16464  if (ret != SQL_SUCCESS) {
16465  s->row_status0[i] = SQL_ROW_ERROR;
16466  break;
16467  }
16468  if (s->nrows < 1) {
16469  break;
16470  }
16471  ret = dofetchbind(s, i);
16472  if (!SQL_SUCCEEDED(ret)) {
16473  break;
16474  } else if (ret == SQL_SUCCESS_WITH_INFO) {
16475  withinfo = 1;
16476  }
16477  }
16478  } else if (s->rows) {
16479  switch (orient) {
16480  case SQL_FETCH_NEXT:
16481  if (s->nrows < 1) {
16482  return SQL_NO_DATA;
16483  }
16484  if (s->rowp < 0) {
16485  s->rowp = -1;
16486  }
16487  if (s->rowp >= s->nrows) {
16488  s->rowp = s->rowprs = s->nrows;
16489  return SQL_NO_DATA;
16490  }
16491  break;
16492  case SQL_FETCH_PRIOR:
16493  if (s->nrows < 1 || s->rowp <= 0) {
16494  s->rowp = s->rowprs = -1;
16495  return SQL_NO_DATA;
16496  }
16497  s->rowp -= s->rowset_size + 1;
16498  if (s->rowp < -1) {
16499  s->rowp = s->rowprs = -1;
16500  return SQL_NO_DATA;
16501  }
16502  break;
16503  case SQL_FETCH_FIRST:
16504  if (s->nrows < 1) {
16505  return SQL_NO_DATA;
16506  }
16507  s->rowp = -1;
16508  break;
16509  case SQL_FETCH_LAST:
16510  if (s->nrows < 1) {
16511  return SQL_NO_DATA;
16512  }
16513  s->rowp = s->nrows - s->rowset_size;
16514  if (--s->rowp < -1) {
16515  s->rowp = -1;
16516  }
16517  break;
16518  case SQL_FETCH_ABSOLUTE:
16519  if (offset == 0) {
16520  s->rowp = s->rowprs = -1;
16521  return SQL_NO_DATA;
16522  } else if (offset < 0) {
16523  if (0 - offset <= s->nrows) {
16524  s->rowp = s->nrows + offset - 1;
16525  break;
16526  }
16527  s->rowp = s->rowprs = -1;
16528  return SQL_NO_DATA;
16529  } else if (offset > s->nrows) {
16530  s->rowp = s->rowprs = s->nrows;
16531  return SQL_NO_DATA;
16532  }
16533  s->rowp = offset - 1 - 1;
16534  break;
16535  case SQL_FETCH_RELATIVE:
16536  if (offset >= 0) {
16537  s->rowp += offset * s->rowset_size - 1;
16538  if (s->rowp >= s->nrows) {
16539  s->rowp = s->rowprs = s->nrows;
16540  return SQL_NO_DATA;
16541  }
16542  } else {
16543  s->rowp += offset * s->rowset_size - 1;
16544  if (s->rowp < -1) {
16545  s->rowp = s->rowprs = -1;
16546  return SQL_NO_DATA;
16547  }
16548  }
16549  break;
16550  case SQL_FETCH_BOOKMARK:
16551  if (s->bkmrk == SQL_UB_ON && !s->bkmrkptr) {
16552  if (offset < 0 || offset >= s->nrows) {
16553  return SQL_NO_DATA;
16554  }
16555  s->rowp = offset - 1;
16556  break;
16557  }
16558  if (s->bkmrk != SQL_UB_OFF && s->bkmrkptr) {
16559  int rowp;
16560 
16561  if (s->bkmrk == SQL_UB_VARIABLE) {
16562  if (s->has_rowid >= 0) {
16563  sqlite_int64 bkmrk, rowid;
16564 
16565  bkmrk = *(sqlite_int64 *) s->bkmrkptr;
16566  for (rowp = 0; rowp < s->nrows; rowp++) {
16567  char **data, *endp = 0;
16568 
16569  data = s->rows + s->ncols + (rowp * s->ncols)
16570  + s->has_rowid;
16571 #ifdef __osf__
16572  rowid = strtol(*data, &endp, 0);
16573 #else
16574  rowid = strtoll(*data, &endp, 0);
16575 #endif
16576  if (rowid == bkmrk) {
16577  break;
16578  }
16579  }
16580  } else {
16581  rowp = *(sqlite_int64 *) s->bkmrkptr;
16582  }
16583  } else {
16584  rowp = *(int *) s->bkmrkptr;
16585  }
16586  if (rowp + offset < 0 || rowp + offset >= s->nrows) {
16587  return SQL_NO_DATA;
16588  }
16589  s->rowp = rowp + offset - 1;
16590  break;
16591  }
16592  /* fall through */
16593  default:
16594  s->row_status0[0] = SQL_ROW_ERROR;
16595  ret = SQL_ERROR;
16596  goto done;
16597  }
16598  s->rowprs = s->rowp + 1;
16599  for (; i < s->rowset_size; i++) {
16600  ++s->rowp;
16601  if (s->rowp < 0 || s->rowp >= s->nrows) {
16602  break;
16603  }
16604  ret = dofetchbind(s, i);
16605  if (!SQL_SUCCEEDED(ret)) {
16606  break;
16607  } else if (ret == SQL_SUCCESS_WITH_INFO) {
16608  withinfo = 1;
16609  }
16610  }
16611  }
16612 done:
16613  if (i == 0) {
16614  if (SQL_SUCCEEDED(ret)) {
16615  return SQL_NO_DATA;
16616  }
16617  return ret;
16618  }
16619  if (SQL_SUCCEEDED(ret)) {
16620  ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16621  }
16622 done2:
16623  if (s->row_status) {
16624  memcpy(s->row_status, s->row_status0,
16625  sizeof (SQLUSMALLINT) * s->rowset_size);
16626  }
16627  s->row_count0 = i;
16628  if (s->row_count) {
16629  *s->row_count = s->row_count0;
16630  }
16631  return ret;
16632 }
16633 
16640 SQLRETURN SQL_API
16641 SQLFetch(SQLHSTMT stmt)
16642 {
16643  SQLRETURN ret;
16644 
16645  HSTMT_LOCK(stmt);
16646  ret = drvfetchscroll(stmt, SQL_FETCH_NEXT, 0);
16647  HSTMT_UNLOCK(stmt);
16648  return ret;
16649 }
16650 
16659 SQLRETURN SQL_API
16660 SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLLEN offset)
16661 {
16662  SQLRETURN ret;
16663 
16664  HSTMT_LOCK(stmt);
16665  ret = drvfetchscroll(stmt, orient, offset);
16666  HSTMT_UNLOCK(stmt);
16667  return ret;
16668 }
16669 
16680 SQLRETURN SQL_API
16681 SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT orient, SQLROWOFFSET offset,
16682  SQLROWSETSIZE *rowcount, SQLUSMALLINT *rowstatus)
16683 {
16684  STMT *s;
16685  SQLRETURN ret;
16686  SQLUSMALLINT *rst;
16687  SQLINTEGER *bkmrkptr;
16688 
16689  HSTMT_LOCK(stmt);
16690  if (stmt == SQL_NULL_HSTMT) {
16691  return SQL_INVALID_HANDLE;
16692  }
16693  s = (STMT *) stmt;
16694  /* temporarily turn off SQL_ATTR_ROW_STATUS_PTR */
16695  rst = s->row_status;
16696  s->row_status = 0;
16697  bkmrkptr = s->bkmrkptr;
16698  s->bkmrkptr = 0;
16699  ret = drvfetchscroll(stmt, orient, offset);
16700  s->row_status = rst;
16701  s->bkmrkptr = bkmrkptr;
16702  if (rowstatus) {
16703  memcpy(rowstatus, s->row_status0,
16704  sizeof (SQLUSMALLINT) * s->rowset_size);
16705  }
16706  if (rowcount) {
16707  *rowcount = s->row_count0;
16708  }
16709  HSTMT_UNLOCK(stmt);
16710  return ret;
16711 }
16712 
16720 SQLRETURN SQL_API
16721 SQLRowCount(SQLHSTMT stmt, SQLLEN *nrows)
16722 {
16723  STMT *s;
16724 
16725  HSTMT_LOCK(stmt);
16726  if (stmt == SQL_NULL_HSTMT) {
16727  return SQL_INVALID_HANDLE;
16728  }
16729  s = (STMT *) stmt;
16730  if (nrows) {
16731  *nrows = s->isselect ? 0 : s->nrows;
16732  }
16733  HSTMT_UNLOCK(stmt);
16734  return SQL_SUCCESS;
16735 }
16736 
16744 SQLRETURN SQL_API
16745 SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *ncols)
16746 {
16747  STMT *s;
16748 
16749  HSTMT_LOCK(stmt);
16750  if (stmt == SQL_NULL_HSTMT) {
16751  return SQL_INVALID_HANDLE;
16752  }
16753  s = (STMT *) stmt;
16754  if (ncols) {
16755  *ncols = s->ncols;
16756  }
16757  HSTMT_UNLOCK(stmt);
16758  return SQL_SUCCESS;
16759 }
16760 
16775 static SQLRETURN
16776 drvdescribecol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
16777  SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
16778  SQLSMALLINT *type, SQLULEN *size,
16779  SQLSMALLINT *digits, SQLSMALLINT *nullable)
16780 {
16781  STMT *s;
16782  COL *c;
16783  int didname = 0;
16784 
16785  if (stmt == SQL_NULL_HSTMT) {
16786  return SQL_INVALID_HANDLE;
16787  }
16788  s = (STMT *) stmt;
16789  if (!s->cols) {
16790  setstat(s, -1, "no columns", (*s->ov3) ? "07009" : "S1002");
16791  return SQL_ERROR;
16792  }
16793  if (col < 1 || col > s->ncols) {
16794  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
16795  return SQL_ERROR;
16796  }
16797  c = s->cols + col - 1;
16798  if (name && nameMax > 0) {
16799  strncpy((char *) name, c->column, nameMax);
16800  name[nameMax - 1] = '\0';
16801  didname = 1;
16802  }
16803  if (nameLen) {
16804  if (didname) {
16805  *nameLen = strlen((char *) name);
16806  } else {
16807  *nameLen = strlen(c->column);
16808  }
16809  }
16810  if (type) {
16811  *type = c->type;
16812 #ifdef WINTERFACE
16813  if (s->nowchar[0] || s->nowchar[1]) {
16814  switch (c->type) {
16815  case SQL_WCHAR:
16816  *type = SQL_CHAR;
16817  break;
16818  case SQL_WVARCHAR:
16819  *type = SQL_VARCHAR;
16820  break;
16821 #ifdef SQL_LONGVARCHAR
16822  case SQL_WLONGVARCHAR:
16823  *type = SQL_LONGVARCHAR;
16824  break;
16825 #endif
16826  }
16827  }
16828 #endif
16829  }
16830  if (size) {
16831  *size = c->size;
16832  }
16833  if (digits) {
16834  *digits = 0;
16835  }
16836  if (nullable) {
16837  *nullable = 1;
16838  }
16839  return SQL_SUCCESS;
16840 }
16841 
16842 #ifndef WINTERFACE
16843 
16857 SQLRETURN SQL_API
16858 SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
16859  SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
16860  SQLSMALLINT *type, SQLULEN *size,
16861  SQLSMALLINT *digits, SQLSMALLINT *nullable)
16862 {
16863 #if defined(_WIN32) || defined(_WIN64)
16864  SQLSMALLINT len = 0;
16865 #endif
16866  SQLRETURN ret;
16867 
16868  HSTMT_LOCK(stmt);
16869 #if defined(_WIN32) || defined(_WIN64)
16870  if (!((STMT *) stmt)->oemcp[0]) {
16871  ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
16872  type, size, digits, nullable);
16873  goto done;
16874  }
16875  ret = drvdescribecol(stmt, col, name, nameMax,
16876  &len, type, size, digits, nullable);
16877  if (ret == SQL_SUCCESS) {
16878  if (name) {
16879  if (len > 0) {
16880  SQLCHAR *n = NULL;
16881 
16882  n = (SQLCHAR *) utf_to_wmb((char *) name, len);
16883  if (n) {
16884  strncpy((char *) name, (char *) n, nameMax);
16885  n[len] = 0;
16886  len = min(nameMax, strlen((char *) n));
16887  uc_free(n);
16888  } else {
16889  len = 0;
16890  }
16891  }
16892  if (len <= 0) {
16893  len = 0;
16894  if (nameMax > 0) {
16895  name[0] = 0;
16896  }
16897  }
16898  } else {
16899  STMT *s = (STMT *) stmt;
16900  COL *c = s->cols + col - 1;
16901 
16902  len = 0;
16903  if (c->column) {
16904  len = strlen(c->column);
16905  }
16906  }
16907  if (nameLen) {
16908  *nameLen = len;
16909  }
16910  }
16911 done:
16912  ;
16913 #else
16914  ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
16915  type, size, digits, nullable);
16916 #endif
16917  HSTMT_UNLOCK(stmt);
16918  return ret;
16919 }
16920 #endif
16921 
16922 #ifdef WINTERFACE
16923 
16937 SQLRETURN SQL_API
16938 SQLDescribeColW(SQLHSTMT stmt, SQLUSMALLINT col, SQLWCHAR *name,
16939  SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
16940  SQLSMALLINT *type, SQLULEN *size,
16941  SQLSMALLINT *digits, SQLSMALLINT *nullable)
16942 {
16943  SQLRETURN ret;
16944  SQLSMALLINT len = 0;
16945 
16946  HSTMT_LOCK(stmt);
16947  ret = drvdescribecol(stmt, col, (SQLCHAR *) name,
16948  (SQLSMALLINT) (nameMax * sizeof (SQLWCHAR)),
16949  &len, type, size, digits, nullable);
16950  if (ret == SQL_SUCCESS) {
16951  if (name) {
16952  if (len > 0) {
16953  SQLWCHAR *n = NULL;
16954 
16955  n = uc_from_utf((SQLCHAR *) name, len);
16956  if (n) {
16957  uc_strncpy(name, n, nameMax);
16958  n[len] = 0;
16959  len = min(nameMax, uc_strlen(n));
16960  uc_free(n);
16961  } else {
16962  len = 0;
16963  }
16964  }
16965  if (len <= 0) {
16966  len = 0;
16967  if (nameMax > 0) {
16968  name[0] = 0;
16969  }
16970  }
16971  } else {
16972  STMT *s = (STMT *) stmt;
16973  COL *c = s->cols + col - 1;
16974 
16975  len = 0;
16976  if (c->column) {
16977  len = strlen(c->column);
16978  }
16979  }
16980  if (nameLen) {
16981  *nameLen = len;
16982  }
16983  }
16984  HSTMT_UNLOCK(stmt);
16985  return ret;
16986 }
16987 #endif
16988 
17001 static SQLRETURN
17002 drvcolattributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17003  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17004  SQLLEN *val2)
17005 {
17006  STMT *s;
17007  COL *c;
17008  SQLSMALLINT dummy;
17009  char *valc = (char *) val;
17010 
17011  if (stmt == SQL_NULL_HSTMT) {
17012  return SQL_INVALID_HANDLE;
17013  }
17014  s = (STMT *) stmt;
17015  if (!s->cols) {
17016  return SQL_ERROR;
17017  }
17018  if (!valLen) {
17019  valLen = &dummy;
17020  }
17021  if (id == SQL_COLUMN_COUNT) {
17022  if (val2) {
17023  *val2 = s->ncols;
17024  }
17025  *valLen = sizeof (int);
17026  return SQL_SUCCESS;
17027  }
17028  if (id == SQL_COLUMN_TYPE && col == 0) {
17029  if (val2) {
17030  *val2 = SQL_INTEGER;
17031  }
17032  *valLen = sizeof (int);
17033  return SQL_SUCCESS;
17034  }
17035 #ifdef SQL_DESC_OCTET_LENGTH
17036  if (id == SQL_DESC_OCTET_LENGTH && col == 0) {
17037  if (val2) {
17038  *val2 = 4;
17039  }
17040  *valLen = sizeof (int);
17041  return SQL_SUCCESS;
17042  }
17043 #endif
17044  if (col < 1 || col > s->ncols) {
17045  setstat(s, -1, "invalid column", (*s->ov3) ? "07009": "S1002");
17046  return SQL_ERROR;
17047  }
17048  c = s->cols + col - 1;
17049 
17050  switch (id) {
17051  case SQL_COLUMN_LABEL:
17052  if (c->label) {
17053  if (valc && valMax > 0) {
17054  strncpy(valc, c->label, valMax);
17055  valc[valMax - 1] = '\0';
17056  }
17057  *valLen = strlen(c->label);
17058  goto checkLen;
17059  }
17060  /* fall through */
17061  case SQL_COLUMN_NAME:
17062  case SQL_DESC_NAME:
17063  if (valc && valMax > 0) {
17064  strncpy(valc, c->column, valMax);
17065  valc[valMax - 1] = '\0';
17066  }
17067  *valLen = strlen(c->column);
17068 checkLen:
17069  if (*valLen >= valMax) {
17070  setstat(s, -1, "data right truncated", "01004");
17071  return SQL_SUCCESS_WITH_INFO;
17072  }
17073  return SQL_SUCCESS;
17074 #ifdef SQL_DESC_BASE_COLUMN_NAME
17075  case SQL_DESC_BASE_COLUMN_NAME:
17076  if (strchr(c->column, '(') || strchr(c->column, ')')) {
17077  if (valc && valMax > 0) {
17078  valc[0] = '\0';
17079  }
17080  *valLen = 0;
17081  } else if (valc && valMax > 0) {
17082  strncpy(valc, c->column, valMax);
17083  valc[valMax - 1] = '\0';
17084  *valLen = strlen(c->column);
17085  }
17086  goto checkLen;
17087 #endif
17088  case SQL_COLUMN_TYPE:
17089  case SQL_DESC_TYPE:
17090 #ifdef WINTERFACE
17091  {
17092  int type = c->type;
17093 
17094  if (s->nowchar[0] || s->nowchar[1]) {
17095  switch (type) {
17096  case SQL_WCHAR:
17097  type = SQL_CHAR;
17098  break;
17099  case SQL_WVARCHAR:
17100  type = SQL_VARCHAR;
17101  break;
17102 #ifdef SQL_LONGVARCHAR
17103  case SQL_WLONGVARCHAR:
17104  type = SQL_LONGVARCHAR;
17105  break;
17106  }
17107  }
17108  if (val2) {
17109  *val2 = type;
17110  }
17111 #endif
17112  }
17113 #else
17114  if (val2) {
17115  *val2 = c->type;
17116  }
17117 #endif
17118  *valLen = sizeof (int);
17119  return SQL_SUCCESS;
17120  case SQL_COLUMN_DISPLAY_SIZE:
17121  if (val2) {
17122  *val2 = c->size;
17123  }
17124  *valLen = sizeof (int);
17125  return SQL_SUCCESS;
17126  case SQL_COLUMN_UNSIGNED:
17127  if (val2) {
17128  *val2 = c->nosign ? SQL_TRUE : SQL_FALSE;
17129  }
17130  *valLen = sizeof (int);
17131  return SQL_SUCCESS;
17132  case SQL_COLUMN_SCALE:
17133  case SQL_DESC_SCALE:
17134  if (val2) {
17135  *val2 = c->scale;
17136  }
17137  *valLen = sizeof (int);
17138  return SQL_SUCCESS;
17139  case SQL_COLUMN_PRECISION:
17140  case SQL_DESC_PRECISION:
17141  if (val2) {
17142  switch (c->type) {
17143  case SQL_SMALLINT:
17144  *val2 = 5;
17145  break;
17146  case SQL_INTEGER:
17147  *val2 = 10;
17148  break;
17149  case SQL_FLOAT:
17150  case SQL_REAL:
17151  case SQL_DOUBLE:
17152  *val2 = 15;
17153  break;
17154  case SQL_DATE:
17155  *val2 = 0;
17156  break;
17157  case SQL_TIME:
17158  *val2 = 0;
17159  break;
17160 #ifdef SQL_TYPE_TIMESTAMP
17161  case SQL_TYPE_TIMESTAMP:
17162 #endif
17163  case SQL_TIMESTAMP:
17164  *val2 = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
17165  break;
17166  default:
17167  *val2 = c->prec;
17168  break;
17169  }
17170  }
17171  *valLen = sizeof (int);
17172  return SQL_SUCCESS;
17173  case SQL_COLUMN_MONEY:
17174  if (val2) {
17175  *val2 = SQL_FALSE;
17176  }
17177  *valLen = sizeof (int);
17178  return SQL_SUCCESS;
17179  case SQL_COLUMN_AUTO_INCREMENT:
17180  if (val2) {
17181  *val2 = c->autoinc;
17182  }
17183  *valLen = sizeof (int);
17184  return SQL_SUCCESS;
17185  case SQL_COLUMN_LENGTH:
17186  case SQL_DESC_LENGTH:
17187  if (val2) {
17188  *val2 = c->size;
17189  }
17190  *valLen = sizeof (int);
17191  return SQL_SUCCESS;
17192  case SQL_COLUMN_NULLABLE:
17193  case SQL_DESC_NULLABLE:
17194  if (val2) {
17195  *val2 = c->notnull;
17196  }
17197  *valLen = sizeof (int);
17198  return SQL_SUCCESS;
17199  case SQL_COLUMN_SEARCHABLE:
17200  if (val2) {
17201  *val2 = SQL_SEARCHABLE;
17202  }
17203  *valLen = sizeof (int);
17204  return SQL_SUCCESS;
17205  case SQL_COLUMN_CASE_SENSITIVE:
17206  if (val2) {
17207  *val2 = SQL_TRUE;
17208  }
17209  *valLen = sizeof (int);
17210  return SQL_SUCCESS;
17211  case SQL_COLUMN_UPDATABLE:
17212  if (val2) {
17213  *val2 = SQL_TRUE;
17214  }
17215  *valLen = sizeof (int);
17216  return SQL_SUCCESS;
17217  case SQL_DESC_COUNT:
17218  if (val2) {
17219  *val2 = s->ncols;
17220  }
17221  *valLen = sizeof (int);
17222  return SQL_SUCCESS;
17223  case SQL_COLUMN_TYPE_NAME: {
17224  char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17225 
17226 #ifdef WINTERFACE
17227  if (c->type == SQL_WCHAR ||
17228  c->type == SQL_WVARCHAR ||
17229  c->type == SQL_WLONGVARCHAR) {
17230  if (!(s->nowchar[0] || s->nowchar[1])) {
17231  if (strcasecmp(tn, "varchar") == 0) {
17232  tn = "wvarchar";
17233  }
17234  }
17235  }
17236 #endif
17237  if (valc && valMax > 0) {
17238  strncpy(valc, tn, valMax);
17239  valc[valMax - 1] = '\0';
17240  p = strchr(valc, '(');
17241  if (p) {
17242  *p = '\0';
17243  while (p > valc && ISSPACE(p[-1])) {
17244  --p;
17245  *p = '\0';
17246  }
17247  }
17248  *valLen = strlen(valc);
17249  } else {
17250  *valLen = strlen(tn);
17251  p = strchr(tn, '(');
17252  if (p) {
17253  *valLen = p - tn;
17254  while (p > tn && ISSPACE(p[-1])) {
17255  --p;
17256  *valLen -= 1;
17257  }
17258  }
17259  }
17260  goto checkLen;
17261  }
17262  case SQL_COLUMN_OWNER_NAME:
17263  case SQL_COLUMN_QUALIFIER_NAME: {
17264  char *z = "";
17265 
17266  if (valc && valMax > 0) {
17267  strncpy(valc, z, valMax);
17268  valc[valMax - 1] = '\0';
17269  }
17270  *valLen = strlen(z);
17271  goto checkLen;
17272  }
17273  case SQL_COLUMN_TABLE_NAME:
17274 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17275  case SQL_DESC_TABLE_NAME:
17276 #endif
17277 #ifdef SQL_DESC_BASE_TABLE_NAME
17278  case SQL_DESC_BASE_TABLE_NAME:
17279 #endif
17280  if (valc && valMax > 0) {
17281  strncpy(valc, c->table, valMax);
17282  valc[valMax - 1] = '\0';
17283  }
17284  *valLen = strlen(c->table);
17285  goto checkLen;
17286 #ifdef SQL_DESC_NUM_PREC_RADIX
17287  case SQL_DESC_NUM_PREC_RADIX:
17288  if (val2) {
17289  switch (c->type) {
17290 #ifdef WINTERFACE
17291  case SQL_WCHAR:
17292  case SQL_WVARCHAR:
17293 #ifdef SQL_LONGVARCHAR
17294  case SQL_WLONGVARCHAR:
17295 #endif
17296 #endif
17297  case SQL_CHAR:
17298  case SQL_VARCHAR:
17299 #ifdef SQL_LONGVARCHAR
17300  case SQL_LONGVARCHAR:
17301 #endif
17302  case SQL_BINARY:
17303  case SQL_VARBINARY:
17304  case SQL_LONGVARBINARY:
17305  *val2 = 0;
17306  break;
17307  default:
17308  *val2 = 2;
17309  }
17310  }
17311  *valLen = sizeof (int);
17312  return SQL_SUCCESS;
17313 #endif
17314  }
17315  setstat(s, -1, "unsupported column attributes %d", "HY091", id);
17316  return SQL_ERROR;
17317 }
17318 
17319 #ifndef WINTERFACE
17320 
17332 SQLRETURN SQL_API
17333 SQLColAttributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17334  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17335  SQLLEN *val2)
17336 {
17337 #if defined(_WIN32) || defined(_WIN64)
17338  SQLSMALLINT len = 0;
17339 #endif
17340  SQLRETURN ret;
17341 
17342  HSTMT_LOCK(stmt);
17343 #if defined(_WIN32) || defined(_WIN64)
17344  if (!((STMT *) stmt)->oemcp[0]) {
17345  ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17346  goto done;
17347  }
17348  ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17349  if (SQL_SUCCEEDED(ret)) {
17350  char *v = NULL;
17351 
17352  switch (id) {
17353  case SQL_COLUMN_LABEL:
17354  case SQL_COLUMN_NAME:
17355  case SQL_DESC_NAME:
17356  case SQL_COLUMN_TYPE_NAME:
17357  case SQL_COLUMN_OWNER_NAME:
17358  case SQL_COLUMN_QUALIFIER_NAME:
17359  case SQL_COLUMN_TABLE_NAME:
17360 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17361  case SQL_DESC_TABLE_NAME:
17362 #endif
17363 #ifdef SQL_DESC_BASE_COLUMN_NAME
17364  case SQL_DESC_BASE_COLUMN_NAME:
17365 #endif
17366 #ifdef SQL_DESC_BASE_TABLE_NAME
17367  case SQL_DESC_BASE_TABLE_NAME:
17368 #endif
17369  if (val && valMax > 0) {
17370  int vmax = valMax;
17371 
17372  v = utf_to_wmb((char *) val, SQL_NTS);
17373  if (v) {
17374  strncpy(val, v, vmax);
17375  len = min(vmax, strlen(v));
17376  uc_free(v);
17377  }
17378  if (vmax > 0) {
17379  v = (char *) val;
17380  v[vmax - 1] = '\0';
17381  }
17382  }
17383  if (len <= 0) {
17384  len = 0;
17385  }
17386  break;
17387  }
17388  if (valLen) {
17389  *valLen = len;
17390  }
17391  }
17392 done:
17393  ;
17394 #else
17395  ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17396 #endif
17397  HSTMT_UNLOCK(stmt);
17398  return ret;
17399 }
17400 #endif
17401 
17402 #ifdef WINTERFACE
17403 
17415 SQLRETURN SQL_API
17416 SQLColAttributesW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17417  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17418  SQLLEN *val2)
17419 {
17420  SQLRETURN ret;
17421  SQLSMALLINT len = 0;
17422 
17423  HSTMT_LOCK(stmt);
17424  ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17425  if (SQL_SUCCEEDED(ret)) {
17426  SQLWCHAR *v = NULL;
17427 
17428  switch (id) {
17429  case SQL_COLUMN_LABEL:
17430  case SQL_COLUMN_NAME:
17431  case SQL_DESC_NAME:
17432  case SQL_COLUMN_TYPE_NAME:
17433  case SQL_COLUMN_OWNER_NAME:
17434  case SQL_COLUMN_QUALIFIER_NAME:
17435  case SQL_COLUMN_TABLE_NAME:
17436 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17437  case SQL_DESC_TABLE_NAME:
17438 #endif
17439 #ifdef SQL_DESC_BASE_COLUMN_NAME
17440  case SQL_DESC_BASE_COLUMN_NAME:
17441 #endif
17442 #ifdef SQL_DESC_BASE_TABLE_NAME
17443  case SQL_DESC_BASE_TABLE_NAME:
17444 #endif
17445  if (val && valMax > 0) {
17446  int vmax = valMax / sizeof (SQLWCHAR);
17447 
17448  v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
17449  if (v) {
17450  uc_strncpy(val, v, vmax);
17451  len = min(vmax, uc_strlen(v));
17452  uc_free(v);
17453  len *= sizeof (SQLWCHAR);
17454  }
17455  if (vmax > 0) {
17456  v = (SQLWCHAR *) val;
17457  v[vmax - 1] = '\0';
17458  }
17459  }
17460  if (len <= 0) {
17461  len = 0;
17462  }
17463  break;
17464  }
17465  if (valLen) {
17466  *valLen = len;
17467  }
17468  }
17469  HSTMT_UNLOCK(stmt);
17470  return ret;
17471 }
17472 #endif
17473 
17486 static SQLRETURN
17487 drvcolattribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17488  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17489  SQLPOINTER val2)
17490 {
17491  STMT *s;
17492  COL *c;
17493  int v = 0;
17494  char *valc = (char *) val;
17495  SQLSMALLINT dummy;
17496 
17497  if (stmt == SQL_NULL_HSTMT) {
17498  return SQL_INVALID_HANDLE;
17499  }
17500  s = (STMT *) stmt;
17501  if (!s->cols) {
17502  return SQL_ERROR;
17503  }
17504  if (col < 1 || col > s->ncols) {
17505  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
17506  return SQL_ERROR;
17507  }
17508  if (!valLen) {
17509  valLen = &dummy;
17510  }
17511  c = s->cols + col - 1;
17512  switch (id) {
17513  case SQL_DESC_COUNT:
17514  v = s->ncols;
17515  break;
17516  case SQL_DESC_CATALOG_NAME:
17517  if (valc && valMax > 0) {
17518  strncpy(valc, c->db, valMax);
17519  valc[valMax - 1] = '\0';
17520  }
17521  *valLen = strlen(c->db);
17522 checkLen:
17523  if (*valLen >= valMax) {
17524  setstat(s, -1, "data right truncated", "01004");
17525  return SQL_SUCCESS_WITH_INFO;
17526  }
17527  break;
17528  case SQL_COLUMN_LENGTH:
17529  case SQL_DESC_LENGTH:
17530  v = c->size;
17531  break;
17532  case SQL_COLUMN_LABEL:
17533  if (c->label) {
17534  if (valc && valMax > 0) {
17535  strncpy(valc, c->label, valMax);
17536  valc[valMax - 1] = '\0';
17537  }
17538  *valLen = strlen(c->label);
17539  goto checkLen;
17540  }
17541  /* fall through */
17542  case SQL_COLUMN_NAME:
17543  case SQL_DESC_NAME:
17544  if (valc && valMax > 0) {
17545  strncpy(valc, c->column, valMax);
17546  valc[valMax - 1] = '\0';
17547  }
17548  *valLen = strlen(c->column);
17549  goto checkLen;
17550  case SQL_DESC_SCHEMA_NAME: {
17551  char *z = "";
17552 
17553  if (valc && valMax > 0) {
17554  strncpy(valc, z, valMax);
17555  valc[valMax - 1] = '\0';
17556  }
17557  *valLen = strlen(z);
17558  goto checkLen;
17559  }
17560 #ifdef SQL_DESC_BASE_COLUMN_NAME
17561  case SQL_DESC_BASE_COLUMN_NAME:
17562  if (strchr(c->column, '(') || strchr(c->column, ')')) {
17563  valc[0] = '\0';
17564  *valLen = 0;
17565  } else if (valc && valMax > 0) {
17566  strncpy(valc, c->column, valMax);
17567  valc[valMax - 1] = '\0';
17568  *valLen = strlen(c->column);
17569  }
17570  goto checkLen;
17571 #endif
17572  case SQL_DESC_TYPE_NAME: {
17573  char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17574 
17575 #ifdef WINTERFACE
17576  if (c->type == SQL_WCHAR ||
17577  c->type == SQL_WVARCHAR ||
17578  c->type == SQL_WLONGVARCHAR) {
17579  if (!(s->nowchar[0] || s->nowchar[1])) {
17580  if (strcasecmp(tn, "varchar") == 0) {
17581  tn = "wvarchar";
17582  }
17583  }
17584  }
17585 #endif
17586  if (valc && valMax > 0) {
17587  strncpy(valc, tn, valMax);
17588  valc[valMax - 1] = '\0';
17589  p = strchr(valc, '(');
17590  if (p) {
17591  *p = '\0';
17592  while (p > valc && ISSPACE(p[-1])) {
17593  --p;
17594  *p = '\0';
17595  }
17596  }
17597  *valLen = strlen(valc);
17598  } else {
17599  *valLen = strlen(tn);
17600  p = strchr(tn, '(');
17601  if (p) {
17602  *valLen = p - tn;
17603  while (p > tn && ISSPACE(p[-1])) {
17604  --p;
17605  *valLen -= 1;
17606  }
17607  }
17608  }
17609  goto checkLen;
17610  }
17611  case SQL_DESC_OCTET_LENGTH:
17612  v = c->size;
17613 #ifdef WINTERFACE
17614  if (c->type == SQL_WCHAR ||
17615  c->type == SQL_WVARCHAR ||
17616  c->type == SQL_WLONGVARCHAR) {
17617  if (!(s->nowchar[0] || s->nowchar[1])) {
17618  v *= sizeof (SQLWCHAR);
17619  }
17620  }
17621 #endif
17622  break;
17623 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17624  case SQL_COLUMN_TABLE_NAME:
17625 #endif
17626 #ifdef SQL_DESC_BASE_TABLE_NAME
17627  case SQL_DESC_BASE_TABLE_NAME:
17628 #endif
17629  case SQL_DESC_TABLE_NAME:
17630  if (valc && valMax > 0) {
17631  strncpy(valc, c->table, valMax);
17632  valc[valMax - 1] = '\0';
17633  }
17634  *valLen = strlen(c->table);
17635  goto checkLen;
17636  case SQL_DESC_TYPE:
17637  v = c->type;
17638 #ifdef WINTERFACE
17639  if (s->nowchar[0] || s->nowchar[1]) {
17640  switch (v) {
17641  case SQL_WCHAR:
17642  v = SQL_CHAR;
17643  break;
17644  case SQL_WVARCHAR:
17645  v = SQL_VARCHAR;
17646  break;
17647 #ifdef SQL_LONGVARCHAR
17648  case SQL_WLONGVARCHAR:
17649  v = SQL_LONGVARCHAR;
17650  break;
17651 #endif
17652  }
17653  }
17654 #endif
17655  break;
17656  case SQL_DESC_CONCISE_TYPE:
17657  switch (c->type) {
17658  case SQL_INTEGER:
17659  v = SQL_C_LONG;
17660  break;
17661  case SQL_TINYINT:
17662  v = SQL_C_TINYINT;
17663  break;
17664  case SQL_SMALLINT:
17665  v = SQL_C_SHORT;
17666  break;
17667  case SQL_FLOAT:
17668  v = SQL_C_FLOAT;
17669  break;
17670  case SQL_DOUBLE:
17671  v = SQL_C_DOUBLE;
17672  break;
17673  case SQL_TIMESTAMP:
17674  v = SQL_C_TIMESTAMP;
17675  break;
17676  case SQL_TIME:
17677  v = SQL_C_TIME;
17678  break;
17679  case SQL_DATE:
17680  v = SQL_C_DATE;
17681  break;
17682 #ifdef SQL_C_TYPE_TIMESTAMP
17683  case SQL_TYPE_TIMESTAMP:
17684  v = SQL_C_TYPE_TIMESTAMP;
17685  break;
17686 #endif
17687 #ifdef SQL_C_TYPE_TIME
17688  case SQL_TYPE_TIME:
17689  v = SQL_C_TYPE_TIME;
17690  break;
17691 #endif
17692 #ifdef SQL_C_TYPE_DATE
17693  case SQL_TYPE_DATE:
17694  v = SQL_C_TYPE_DATE;
17695  break;
17696 #endif
17697 #ifdef SQL_BIT
17698  case SQL_BIT:
17699  v = SQL_C_BIT;
17700  break;
17701 #endif
17702 #ifdef SQL_BIGINT
17703  case SQL_BIGINT:
17704  v = SQL_C_SBIGINT;
17705  break;
17706 #endif
17707  default:
17708 #ifdef WINTERFACE
17709  v = (s->nowchar[0] || s->nowchar[1]) ? SQL_C_CHAR : SQL_C_WCHAR;
17710 #else
17711  v = SQL_C_CHAR;
17712 #endif
17713  break;
17714  }
17715  break;
17716  case SQL_DESC_UPDATABLE:
17717  v = SQL_TRUE;
17718  break;
17719  case SQL_COLUMN_DISPLAY_SIZE:
17720  v = c->size;
17721  break;
17722  case SQL_COLUMN_UNSIGNED:
17723  v = c->nosign ? SQL_TRUE : SQL_FALSE;
17724  break;
17725  case SQL_COLUMN_SEARCHABLE:
17726  v = SQL_SEARCHABLE;
17727  break;
17728  case SQL_COLUMN_SCALE:
17729  case SQL_DESC_SCALE:
17730  v = c->scale;
17731  break;
17732  case SQL_COLUMN_PRECISION:
17733  case SQL_DESC_PRECISION:
17734  switch (c->type) {
17735  case SQL_SMALLINT:
17736  v = 5;
17737  break;
17738  case SQL_INTEGER:
17739  v = 10;
17740  break;
17741  case SQL_FLOAT:
17742  case SQL_REAL:
17743  case SQL_DOUBLE:
17744  v = 15;
17745  break;
17746  case SQL_DATE:
17747  v = 0;
17748  break;
17749  case SQL_TIME:
17750  v = 0;
17751  break;
17752 #ifdef SQL_TYPE_TIMESTAMP
17753  case SQL_TYPE_TIMESTAMP:
17754 #endif
17755  case SQL_TIMESTAMP:
17756  v = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
17757  break;
17758  default:
17759  v = c->prec;
17760  break;
17761  }
17762  break;
17763  case SQL_COLUMN_MONEY:
17764  v = SQL_FALSE;
17765  break;
17766  case SQL_COLUMN_AUTO_INCREMENT:
17767  v = c->autoinc;
17768  break;
17769  case SQL_DESC_NULLABLE:
17770  v = c->notnull;
17771  break;
17772 #ifdef SQL_DESC_NUM_PREC_RADIX
17773  case SQL_DESC_NUM_PREC_RADIX:
17774  switch (c->type) {
17775 #ifdef WINTERFACE
17776  case SQL_WCHAR:
17777  case SQL_WVARCHAR:
17778 #ifdef SQL_LONGVARCHAR
17779  case SQL_WLONGVARCHAR:
17780 #endif
17781 #endif
17782  case SQL_CHAR:
17783  case SQL_VARCHAR:
17784 #ifdef SQL_LONGVARCHAR
17785  case SQL_LONGVARCHAR:
17786 #endif
17787  case SQL_BINARY:
17788  case SQL_VARBINARY:
17789  case SQL_LONGVARBINARY:
17790  v = 0;
17791  break;
17792  default:
17793  v = 2;
17794  }
17795  break;
17796 #endif
17797  default:
17798  setstat(s, -1, "unsupported column attribute %d", "HY091", id);
17799  return SQL_ERROR;
17800  }
17801  if (val2) {
17802  *(SQLLEN *) val2 = v;
17803  }
17804  return SQL_SUCCESS;
17805 }
17806 
17807 #ifndef WINTERFACE
17808 
17820 SQLRETURN SQL_API
17821 SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17822  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17824 {
17825 #if defined(_WIN32) || defined(_WIN64)
17826  SQLSMALLINT len = 0;
17827 #endif
17828  SQLRETURN ret;
17829 
17830  HSTMT_LOCK(stmt);
17831 #if defined(_WIN32) || defined(_WIN64)
17832  if (!((STMT *) stmt)->oemcp[0]) {
17833  ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
17834  (SQLPOINTER) val2);
17835  goto done;
17836  }
17837  ret = drvcolattribute(stmt, col, id, val, valMax, &len,
17838  (SQLPOINTER) val2);
17839  if (SQL_SUCCEEDED(ret)) {
17840  char *v = NULL;
17841 
17842  switch (id) {
17843  case SQL_DESC_SCHEMA_NAME:
17844  case SQL_DESC_CATALOG_NAME:
17845  case SQL_COLUMN_LABEL:
17846  case SQL_DESC_NAME:
17847  case SQL_DESC_TABLE_NAME:
17848 #ifdef SQL_DESC_BASE_TABLE_NAME
17849  case SQL_DESC_BASE_TABLE_NAME:
17850 #endif
17851 #ifdef SQL_DESC_BASE_COLUMN_NAME
17852  case SQL_DESC_BASE_COLUMN_NAME:
17853 #endif
17854  case SQL_DESC_TYPE_NAME:
17855  if (val && valMax > 0) {
17856  int vmax = valMax;
17857 
17858  v = utf_to_wmb((char *) val, SQL_NTS);
17859  if (v) {
17860  strncpy(val, v, vmax);
17861  len = min(vmax, strlen(v));
17862  uc_free(v);
17863  }
17864  if (vmax > 0) {
17865  v = (char *) val;
17866  v[vmax - 1] = '\0';
17867  }
17868  }
17869  if (len <= 0) {
17870  len = 0;
17871  }
17872  break;
17873  }
17874  if (valLen) {
17875  *valLen = len;
17876  }
17877  }
17878 done:
17879  ;
17880 #else
17881  ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
17882  (SQLPOINTER) val2);
17883 #endif
17884  HSTMT_UNLOCK(stmt);
17885  return ret;
17886 }
17887 #endif
17888 
17889 #ifdef WINTERFACE
17890 
17902 SQLRETURN SQL_API
17903 SQLColAttributeW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17904  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17906 {
17907  SQLRETURN ret;
17908  SQLSMALLINT len = 0;
17909 
17910  HSTMT_LOCK(stmt);
17911  ret = drvcolattribute(stmt, col, id, val, valMax, &len,
17912  (SQLPOINTER) val2);
17913  if (SQL_SUCCEEDED(ret)) {
17914  SQLWCHAR *v = NULL;
17915 
17916  switch (id) {
17917  case SQL_DESC_SCHEMA_NAME:
17918  case SQL_DESC_CATALOG_NAME:
17919  case SQL_COLUMN_LABEL:
17920  case SQL_DESC_NAME:
17921  case SQL_DESC_TABLE_NAME:
17922 #ifdef SQL_DESC_BASE_TABLE_NAME
17923  case SQL_DESC_BASE_TABLE_NAME:
17924 #endif
17925 #ifdef SQL_DESC_BASE_COLUMN_NAME
17926  case SQL_DESC_BASE_COLUMN_NAME:
17927 #endif
17928  case SQL_DESC_TYPE_NAME:
17929  if (val && valMax > 0) {
17930  int vmax = valMax / sizeof (SQLWCHAR);
17931 
17932  v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
17933  if (v) {
17934  uc_strncpy(val, v, vmax);
17935  len = min(vmax, uc_strlen(v));
17936  uc_free(v);
17937  len *= sizeof (SQLWCHAR);
17938  }
17939  if (vmax > 0) {
17940  v = (SQLWCHAR *) val;
17941  v[vmax - 1] = '\0';
17942  }
17943  }
17944  if (len <= 0) {
17945  len = 0;
17946  }
17947  break;
17948  }
17949  if (valLen) {
17950  *valLen = len;
17951  }
17952  }
17953  HSTMT_UNLOCK(stmt);
17954  return ret;
17955 }
17956 #endif
17957 
17971 static SQLRETURN
17972 drverror(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
17973  SQLCHAR *sqlState, SQLINTEGER *nativeErr,
17974  SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
17975 {
17976  SQLCHAR dummy0[6];
17977  SQLINTEGER dummy1;
17978  SQLSMALLINT dummy2;
17979 
17980  if (env == SQL_NULL_HENV &&
17981  dbc == SQL_NULL_HDBC &&
17982  stmt == SQL_NULL_HSTMT) {
17983  return SQL_INVALID_HANDLE;
17984  }
17985  if (sqlState) {
17986  sqlState[0] = '\0';
17987  } else {
17988  sqlState = dummy0;
17989  }
17990  if (!nativeErr) {
17991  nativeErr = &dummy1;
17992  }
17993  *nativeErr = 0;
17994  if (!errlen) {
17995  errlen = &dummy2;
17996  }
17997  *errlen = 0;
17998  if (errmsg) {
17999  if (errmax > 0) {
18000  errmsg[0] = '\0';
18001  }
18002  } else {
18003  errmsg = dummy0;
18004  errmax = 0;
18005  }
18006  if (stmt) {
18007  STMT *s = (STMT *) stmt;
18008 
18009  HSTMT_LOCK(stmt);
18010  if (s->logmsg[0] == '\0') {
18011  HSTMT_UNLOCK(stmt);
18012  goto noerr;
18013  }
18014  *nativeErr = s->naterr;
18015  strcpy((char *) sqlState, s->sqlstate);
18016  if (errmax == SQL_NTS) {
18017  strcpy((char *) errmsg, "[SQLite]");
18018  strcat((char *) errmsg, (char *) s->logmsg);
18019  *errlen = strlen((char *) errmsg);
18020  } else {
18021  strncpy((char *) errmsg, "[SQLite]", errmax);
18022  if (errmax - 8 > 0) {
18023  strncpy((char *) errmsg + 8, (char *) s->logmsg, errmax - 8);
18024  }
18025  *errlen = min(strlen((char *) s->logmsg) + 8, errmax);
18026  }
18027  s->logmsg[0] = '\0';
18028  HSTMT_UNLOCK(stmt);
18029  return SQL_SUCCESS;
18030  }
18031  if (dbc) {
18032  DBC *d = (DBC *) dbc;
18033 
18034  HDBC_LOCK(dbc);
18035  if (d->magic != DBC_MAGIC || d->logmsg[0] == '\0') {
18036  HDBC_UNLOCK(dbc);
18037  goto noerr;
18038  }
18039  *nativeErr = d->naterr;
18040  strcpy((char *) sqlState, d->sqlstate);
18041  if (errmax == SQL_NTS) {
18042  strcpy((char *) errmsg, "[SQLite]");
18043  strcat((char *) errmsg, (char *) d->logmsg);
18044  *errlen = strlen((char *) errmsg);
18045  } else {
18046  strncpy((char *) errmsg, "[SQLite]", errmax);
18047  if (errmax - 8 > 0) {
18048  strncpy((char *) errmsg + 8, (char *) d->logmsg, errmax - 8);
18049  }
18050  *errlen = min(strlen((char *) d->logmsg) + 8, errmax);
18051  }
18052  d->logmsg[0] = '\0';
18053  HDBC_UNLOCK(dbc);
18054  return SQL_SUCCESS;
18055  }
18056 noerr:
18057  sqlState[0] = '\0';
18058  errmsg[0] = '\0';
18059  *nativeErr = 0;
18060  *errlen = 0;
18061  return SQL_NO_DATA;
18062 }
18063 
18064 #ifndef WINTERFACE
18065 
18078 SQLRETURN SQL_API
18079 SQLError(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18080  SQLCHAR *sqlState, SQLINTEGER *nativeErr,
18081  SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18082 {
18083  return drverror(env, dbc, stmt, sqlState, nativeErr,
18084  errmsg, errmax, errlen);
18085 }
18086 #endif
18087 
18088 #ifdef WINTERFACE
18089 
18102 SQLRETURN SQL_API
18103 SQLErrorW(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18104  SQLWCHAR *sqlState, SQLINTEGER *nativeErr,
18105  SQLWCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18106 {
18107  char state[16];
18108  SQLSMALLINT len = 0;
18109  SQLRETURN ret;
18110 
18111  ret = drverror(env, dbc, stmt, (SQLCHAR *) state, nativeErr,
18112  (SQLCHAR *) errmsg, errmax, &len);
18113  if (ret == SQL_SUCCESS) {
18114  if (sqlState) {
18115  uc_from_utf_buf((SQLCHAR *) state, -1, sqlState,
18116  6 * sizeof (SQLWCHAR));
18117  }
18118  if (errmsg) {
18119  if (len > 0) {
18120  SQLWCHAR *e = NULL;
18121 
18122  e = uc_from_utf((SQLCHAR *) errmsg, len);
18123  if (e) {
18124  if (errmax > 0) {
18125  uc_strncpy(errmsg, e, errmax);
18126  e[len] = 0;
18127  len = min(errmax, uc_strlen(e));
18128  } else {
18129  len = uc_strlen(e);
18130  }
18131  uc_free(e);
18132  } else {
18133  len = 0;
18134  }
18135  }
18136  if (len <= 0) {
18137  len = 0;
18138  if (errmax > 0) {
18139  errmsg[0] = 0;
18140  }
18141  }
18142  } else {
18143  len = 0;
18144  }
18145  if (errlen) {
18146  *errlen = len;
18147  }
18148  } else if (ret == SQL_NO_DATA) {
18149  if (sqlState) {
18150  sqlState[0] = 0;
18151  }
18152  if (errmsg) {
18153  if (errmax > 0) {
18154  errmsg[0] = 0;
18155  }
18156  }
18157  if (errlen) {
18158  *errlen = 0;
18159  }
18160  }
18161  return ret;
18162 }
18163 #endif
18164 
18171 SQLRETURN SQL_API
18172 SQLMoreResults(SQLHSTMT stmt)
18173 {
18174  HSTMT_LOCK(stmt);
18175  if (stmt == SQL_NULL_HSTMT) {
18176  return SQL_INVALID_HANDLE;
18177  }
18178  HSTMT_UNLOCK(stmt);
18179  return SQL_NO_DATA;
18180 }
18181 
18190 static SQLRETURN
18191 setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp)
18192 {
18193  int ncols = *ncolsp, guessed_types = 0;
18194  SQLRETURN ret = SQL_SUCCESS;
18195 
18196  if (ncols > 0) {
18197  int i;
18198  PTRDIFF_T size;
18199  char *p;
18200  COL *dyncols;
18201  DBC *d = (DBC *) s->dbc;
18202  const char *colname, *typename;
18203 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18204  char *tblname;
18205 #endif
18206 
18207  for (i = size = 0; i < ncols; i++) {
18208  colname = sqlite3_column_name(s3stmt, i);
18209  size += 3 + 3 * strlen(colname);
18210  }
18211 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18212  tblname = (char *) size;
18213  for (i = 0; i < ncols; i++) {
18214  p = (char *) sqlite3_column_table_name(s3stmt, i);
18215  size += 2 + (p ? strlen(p) : 0);
18216  }
18217 #endif
18218  dyncols = xmalloc(ncols * sizeof (COL) + size);
18219  if (!dyncols) {
18220  freedyncols(s);
18221  *ncolsp = 0;
18222  ret = SQL_ERROR;
18223  } else {
18224  p = (char *) (dyncols + ncols);
18225 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18226  tblname = p + (PTRDIFF_T) tblname;
18227 #endif
18228  for (i = 0; i < ncols; i++) {
18229  char *q;
18230 
18231  colname = sqlite3_column_name(s3stmt, i);
18232  if (d->trace) {
18233  fprintf(d->trace, "-- column %d name: '%s'\n",
18234  i + 1, colname);
18235  fflush(d->trace);
18236  }
18237 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18238  q = (char *) sqlite3_column_table_name(s3stmt, i);
18239  strcpy(tblname, q ? q : "");
18240  if (d->trace) {
18241  fprintf(d->trace, "-- table %d name: '%s'\n",
18242  i + 1, tblname);
18243  fflush(d->trace);
18244  }
18245  dyncols[i].table = tblname;
18246  tblname += strlen(tblname) + 1;
18247 #endif
18248  typename = s3stmt_coltype(s3stmt, i, d, &guessed_types);
18249  dyncols[i].db = ((DBC *) (s->dbc))->dbname;
18250  strcpy(p, colname);
18251  dyncols[i].label = p;
18252  p += strlen(p) + 1;
18253  q = strchr(colname, '.');
18254  if (q) {
18255  char *q2 = strchr(q + 1, '.');
18256 
18257  /* SQLite 3.3.4 produces view.table.column sometimes */
18258  if (q2) {
18259  q = q2;
18260  }
18261  }
18262  if (q) {
18263 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18264  dyncols[i].table = p;
18265 #endif
18266  strncpy(p, colname, q - colname);
18267  p[q - colname] = '\0';
18268  p += strlen(p) + 1;
18269  strcpy(p, q + 1);
18270  dyncols[i].column = p;
18271  p += strlen(p) + 1;
18272  } else {
18273 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18274  dyncols[i].table = "";
18275 #endif
18276  strcpy(p, colname);
18277  dyncols[i].column = p;
18278  p += strlen(p) + 1;
18279  }
18280  if (s->longnames) {
18281  dyncols[i].column = dyncols[i].label;
18282  }
18283 #ifdef SQL_LONGVARCHAR
18284  dyncols[i].type = SQL_LONGVARCHAR;
18285  dyncols[i].size = 65535;
18286 #else
18287  dyncols[i].type = SQL_VARCHAR;
18288  dyncols[i].size = 255;
18289 #endif
18290  dyncols[i].index = i;
18291  dyncols[i].scale = 0;
18292  dyncols[i].prec = 0;
18293  dyncols[i].nosign = 1;
18294 #if defined(HAVE_SQLITE3TABLECOLUMNMETADATA) && (HAVE_SQLITE3TABLECOLUMNMETADATA)
18295  s3stmt_addmeta(s3stmt, i, d, &dyncols[i]);
18296 #else
18297  dyncols[i].autoinc = SQL_FALSE;
18298  dyncols[i].notnull = SQL_NULLABLE;
18299  dyncols[i].ispk = -1;
18300  dyncols[i].isrowid = -1;
18301 #endif
18302  dyncols[i].typename = xstrdup(typename);
18303  }
18304  freedyncols(s);
18305  s->dyncols = s->cols = dyncols;
18306  s->dcols = ncols;
18307  fixupdyncols(s, d);
18308  s->guessed_types = guessed_types;
18309  }
18310  }
18311  return ret;
18312 }
18313 
18322 static SQLRETURN
18323 drvprepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18324 {
18325  STMT *s;
18326  DBC *d;
18327  char *errp = NULL;
18328  SQLRETURN sret;
18329 
18330  if (stmt == SQL_NULL_HSTMT) {
18331  return SQL_INVALID_HANDLE;
18332  }
18333  s = (STMT *) stmt;
18334  if (s->dbc == SQL_NULL_HDBC) {
18335 noconn:
18336  return noconn(s);
18337  }
18338  d = s->dbc;
18339  if (!d->sqlite) {
18340  goto noconn;
18341  }
18342  s3stmt_end(s);
18343  s3stmt_drop(s);
18344  sret = starttran(s);
18345  if (sret != SQL_SUCCESS) {
18346  return sret;
18347  }
18348  freep(&s->query);
18349  s->query = (SQLCHAR *) fixupsql((char *) query, queryLen,
18350  (d->version >= 0x030805),
18351  &s->nparams, &s->isselect, &errp);
18352  if (!s->query) {
18353  if (errp) {
18354  setstat(s, -1, "%s", (*s->ov3) ? "HY000" : "S1000", errp);
18355  return SQL_ERROR;
18356  }
18357  return nomem(s);
18358  }
18359  errp = NULL;
18360  freeresult(s, -1);
18361  if (s->isselect == 1) {
18362  int ret, ncols, nretry = 0;
18363  const char *rest;
18364  sqlite3_stmt *s3stmt = NULL;
18365 
18366 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18367  dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
18368 #else
18369  dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
18370 #endif
18371  do {
18372  s3stmt = NULL;
18373 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18374  ret = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
18375  &s3stmt, &rest);
18376 #else
18377  ret = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
18378  &s3stmt, &rest);
18379 #endif
18380  if (ret != SQLITE_OK) {
18381  if (s3stmt) {
18382  sqlite3_finalize(s3stmt);
18383  s3stmt = NULL;
18384  }
18385  }
18386  } while (ret == SQLITE_SCHEMA && (++nretry) < 2);
18387  dbtracerc(d, ret, NULL);
18388  if (ret != SQLITE_OK) {
18389  if (s3stmt) {
18390  dbtraceapi(d, "sqlite3_finalize", 0);
18391  sqlite3_finalize(s3stmt);
18392  }
18393  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18394  sqlite3_errmsg(d->sqlite), ret);
18395  return SQL_ERROR;
18396  }
18397  if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
18398  dbtraceapi(d, "sqlite3_finalize", 0);
18399  sqlite3_finalize(s3stmt);
18400  setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
18401  (*s->ov3) ? "HY000" : "S1000");
18402  return SQL_ERROR;
18403  }
18404  ncols = sqlite3_column_count(s3stmt);
18405  s->guessed_types = 0;
18406  setupdyncols(s, s3stmt, &ncols);
18407  s->ncols = ncols;
18408  s->s3stmt = s3stmt;
18409  }
18410  mkbindcols(s, s->ncols);
18411  s->paramset_count = 0;
18412  return SQL_SUCCESS;
18413 }
18414 
18422 static SQLRETURN
18423 drvexecute(SQLHSTMT stmt, int initial)
18424 {
18425  STMT *s;
18426  DBC *d;
18427  char *errp = NULL;
18428  int rc, i, ncols = 0, nrows = 0, busy_count;
18429  SQLRETURN ret;
18430 
18431  if (stmt == SQL_NULL_HSTMT) {
18432  return SQL_INVALID_HANDLE;
18433  }
18434  s = (STMT *) stmt;
18435  if (s->dbc == SQL_NULL_HDBC) {
18436 noconn:
18437  return noconn(s);
18438  }
18439  d = (DBC *) s->dbc;
18440  if (!d->sqlite) {
18441  goto noconn;
18442  }
18443  if (!s->query) {
18444  setstat(s, -1, "no query prepared", (*s->ov3) ? "HY000" : "S1000");
18445  return SQL_ERROR;
18446  }
18447  if (s->nbindparms < s->nparams) {
18448 unbound:
18449  setstat(s, -1, "unbound parameters in query",
18450  (*s->ov3) ? "HY000" : "S1000");
18451  return SQL_ERROR;
18452  }
18453  for (i = 0; i < s->nparams; i++) {
18454  BINDPARM *p = &s->bindparms[i];
18455 
18456  if (!p->bound) {
18457  goto unbound;
18458  }
18459  if (initial) {
18460  SQLLEN *lenp = p->lenp;
18461 
18462  if (lenp && *lenp < 0 && *lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18463  *lenp != SQL_NTS && *lenp != SQL_NULL_DATA &&
18464  *lenp != SQL_DATA_AT_EXEC) {
18465  setstat(s, -1, "invalid length reference", "HY009");
18466  return SQL_ERROR;
18467  }
18468  if (lenp && (*lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18469  *lenp == SQL_DATA_AT_EXEC)) {
18470  p->need = 1;
18471  p->offs = 0;
18472  p->len = 0;
18473  }
18474  }
18475  }
18476  ret = starttran(s);
18477  if (ret != SQL_SUCCESS) {
18478  goto cleanup;
18479  }
18480  busy_count = 0;
18481 again:
18482  s3stmt_end(s);
18483  if (initial) {
18484  /* fixup data-at-execution parameters and alloc'ed blobs */
18485  s->pdcount = -1;
18486  for (i = 0; i < s->nparams; i++) {
18487  BINDPARM *p = &s->bindparms[i];
18488 
18489  if (p->param == p->parbuf) {
18490  p->param = NULL;
18491  }
18492  freep(&p->parbuf);
18493  if (p->need <= 0 &&
18494  p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18495  *p->lenp == SQL_DATA_AT_EXEC)) {
18496  p->need = 1;
18497  p->offs = 0;
18498  p->len = 0;
18499  }
18500  }
18501  }
18502  if (s->nparams) {
18503  for (i = 0; i < s->nparams; i++) {
18504  ret = setupparam(s, (char *) s->query, i);
18505  if (ret != SQL_SUCCESS) {
18506  goto cleanup;
18507  }
18508  }
18509  }
18510  freeresult(s, 0);
18511  if (s->isselect == 1 && !d->intrans &&
18512  s->curtype == SQL_CURSOR_FORWARD_ONLY &&
18513  d->step_enable && s->nparams == 0 && d->cur_s3stmt == NULL) {
18514  s->nrows = -1;
18515  ret = s3stmt_start(s);
18516  if (ret == SQL_SUCCESS) {
18517  goto done2;
18518  }
18519  }
18520  rc = drvgettable(s, s->s3stmt ? NULL : (char *) s->query, &s->rows,
18521  &s->nrows, &ncols, &errp, s->nparams, s->bindparms);
18522  dbtracerc(d, rc, errp);
18523  if (rc == SQLITE_BUSY) {
18524  if (busy_handler((void *) d, ++busy_count)) {
18525  if (errp) {
18526  sqlite3_free(errp);
18527  errp = NULL;
18528  }
18529  for (i = 0; i < s->nparams; i++) {
18530  BINDPARM *p = &s->bindparms[i];
18531 
18532  if (p->param == p->parbuf) {
18533  p->param = NULL;
18534  }
18535  freep(&p->parbuf);
18536  if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18537  *p->lenp != SQL_DATA_AT_EXEC)) {
18538  p->param = p->param0;
18539  }
18540  p->lenp = p->lenp0;
18541  }
18542  s->nrows = 0;
18543  goto again;
18544  }
18545  }
18546  if (rc != SQLITE_OK) {
18547  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18548  errp ? errp : "unknown error", rc);
18549  if (errp) {
18550  sqlite3_free(errp);
18551  errp = NULL;
18552  }
18553  ret = SQL_ERROR;
18554  goto cleanup;
18555  }
18556  if (errp) {
18557  sqlite3_free(errp);
18558  errp = NULL;
18559  }
18560  s->rowfree = freerows;
18561  if (s->isselect <= 0 || s->isselect > 1) {
18562  /*
18563  * INSERT/UPDATE/DELETE or DDL results are immediately released.
18564  */
18565  freeresult(s, -1);
18566  nrows += sqlite3_changes(d->sqlite);
18567  s->nrows = nrows;
18568  goto done;
18569  }
18570  if (s->ncols != ncols) {
18571  /*
18572  * Weird result.
18573  */
18574  setstat(s, -1, "broken result set %d/%d",
18575  (*s->ov3) ? "HY000" : "S1000", s->ncols, ncols);
18576  ret = SQL_ERROR;
18577  goto cleanup;
18578  }
18579 done:
18580  mkbindcols(s, s->ncols);
18581 done2:
18582  ret = SQL_SUCCESS;
18583  s->rowp = s->rowprs = -1;
18584  s->paramset_count++;
18585  s->paramset_nrows = s->nrows;
18586  if (s->paramset_count < s->paramset_size) {
18587  for (i = 0; i < s->nparams; i++) {
18588  BINDPARM *p = &s->bindparms[i];
18589 
18590  if (p->param == p->parbuf) {
18591  p->param = NULL;
18592  }
18593  freep(&p->parbuf);
18594  if (p->lenp0 &&
18595  s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18596  p->lenp = (SQLLEN *) ((char *) p->lenp0 +
18597  s->paramset_count * s->parm_bind_type);
18598  } else if (p->lenp0 && p->inc > 0) {
18599  p->lenp = p->lenp0 + s->paramset_count;
18600  }
18601  if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18602  *p->lenp != SQL_DATA_AT_EXEC)) {
18603  if (p->param0 &&
18604  s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18605  p->param = (char *) p->param0 +
18607  } else if (p->param0 && p->inc > 0) {
18608  p->param = (char *) p->param0 +
18609  s->paramset_count * p->inc;
18610  }
18611  } else if (p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18612  *p->lenp == SQL_DATA_AT_EXEC)) {
18613  p->need = 1;
18614  p->offs = 0;
18615  p->len = 0;
18616  }
18617  }
18618  goto again;
18619  }
18620 cleanup:
18621  if (ret != SQL_NEED_DATA) {
18622  for (i = 0; i < s->nparams; i++) {
18623  BINDPARM *p = &s->bindparms[i];
18624 
18625  if (p->param == p->parbuf) {
18626  p->param = NULL;
18627  }
18628  freep(&p->parbuf);
18629  if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18630  *p->lenp != SQL_DATA_AT_EXEC)) {
18631  p->param = p->param0;
18632  }
18633  p->lenp = p->lenp0;
18634  }
18635  s->nrows = s->paramset_nrows;
18636  if (s->parm_proc) {
18637  *s->parm_proc = s->paramset_count;
18638  }
18639  s->paramset_count = 0;
18640  s->paramset_nrows = 0;
18641  }
18642  /*
18643  * For INSERT/UPDATE/DELETE statements change the return code
18644  * to SQL_NO_DATA if the number of rows affected was 0.
18645  */
18646  if (*s->ov3 && s->isselect == 0 &&
18647  ret == SQL_SUCCESS && nrows == 0) {
18648  ret = SQL_NO_DATA;
18649  }
18650  return ret;
18651 }
18652 
18653 #ifndef WINTERFACE
18654 
18662 SQLRETURN SQL_API
18663 SQLPrepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18664 {
18665  SQLRETURN ret;
18666 #if defined(_WIN32) || defined(_WIN64)
18667  char *q;
18668 #endif
18669 
18670  HSTMT_LOCK(stmt);
18671 #if defined(_WIN32) || defined(_WIN64)
18672  if (!((STMT *) stmt)->oemcp[0]) {
18673  ret = drvprepare(stmt, query, queryLen);
18674  goto done;
18675  }
18676  q = wmb_to_utf_c((char *) query, queryLen);
18677  if (!q) {
18678  ret = nomem((STMT *) stmt);
18679  goto done;
18680  }
18681  query = (SQLCHAR *) q;
18682  queryLen = SQL_NTS;
18683 #endif
18684  ret = drvprepare(stmt, query, queryLen);
18685 #if defined(_WIN32) || defined(_WIN64)
18686  uc_free(q);
18687 done:
18688  ;
18689 #endif
18690  HSTMT_UNLOCK(stmt);
18691  return ret;
18692 }
18693 #endif
18694 
18695 #ifdef WINTERFACE
18696 
18704 SQLRETURN SQL_API
18705 SQLPrepareW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
18706 {
18707  SQLRETURN ret;
18708  char *q = uc_to_utf_c(query, queryLen);
18709 
18710  HSTMT_LOCK(stmt);
18711  if (!q) {
18712  ret = nomem((STMT *) stmt);
18713  goto done;
18714  }
18715  ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
18716  uc_free(q);
18717 done:
18718  HSTMT_UNLOCK(stmt);
18719  return ret;
18720 }
18721 #endif
18722 
18729 SQLRETURN SQL_API
18730 SQLExecute(SQLHSTMT stmt)
18731 {
18732  SQLRETURN ret;
18733 
18734  HSTMT_LOCK(stmt);
18735  ret = drvexecute(stmt, 1);
18736  HSTMT_UNLOCK(stmt);
18737  return ret;
18738 }
18739 
18740 #ifndef WINTERFACE
18741 
18749 SQLRETURN SQL_API
18750 SQLExecDirect(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18751 {
18752  SQLRETURN ret;
18753 #if defined(_WIN32) || defined(_WIN64)
18754  char *q;
18755 #endif
18756 
18757  HSTMT_LOCK(stmt);
18758 #if defined(_WIN32) || defined(_WIN64)
18759  if (!((STMT *) stmt)->oemcp[0]) {
18760  ret = drvprepare(stmt, query, queryLen);
18761  if (ret == SQL_SUCCESS) {
18762  ret = drvexecute(stmt, 1);
18763  }
18764  goto done;
18765  }
18766  q = wmb_to_utf_c((char *) query, queryLen);
18767  if (!q) {
18768  ret = nomem((STMT *) stmt);
18769  goto done;
18770  }
18771  query = (SQLCHAR *) q;
18772  queryLen = SQL_NTS;
18773 #endif
18774  ret = drvprepare(stmt, query, queryLen);
18775  if (ret == SQL_SUCCESS) {
18776  ret = drvexecute(stmt, 1);
18777  }
18778 #if defined(_WIN32) || defined(_WIN64)
18779  uc_free(q);
18780 done:
18781  ;
18782 #endif
18783  HSTMT_UNLOCK(stmt);
18784  return ret;
18785 }
18786 #endif
18787 
18788 #ifdef WINTERFACE
18789 
18797 SQLRETURN SQL_API
18798 SQLExecDirectW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
18799 {
18800  SQLRETURN ret;
18801  char *q = uc_to_utf_c(query, queryLen);
18802 
18803  HSTMT_LOCK(stmt);
18804  if (!q) {
18805  ret = nomem((STMT *) stmt);
18806  goto done;
18807  }
18808  ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
18809  uc_free(q);
18810  if (ret == SQL_SUCCESS) {
18811  ret = drvexecute(stmt, 1);
18812  }
18813 done:
18814  HSTMT_UNLOCK(stmt);
18815  return ret;
18816 }
18817 #endif
18818 
18819 
18820 #if defined(_WIN32) || defined(_WIN64)
18821 #ifndef WITHOUT_DRIVERMGR
18822 
18823 /*
18824  * Windows configuration dialog stuff.
18825  */
18826 
18827 #include <windowsx.h>
18828 #include <winuser.h>
18829 
18830 #define MAXPATHLEN (259+1) /* Max path length */
18831 #define MAXKEYLEN (15+1) /* Max keyword length */
18832 #define MAXDESC (255+1) /* Max description length */
18833 #define MAXDSNAME (32+1) /* Max data source name length */
18834 #define MAXTONAME (32+1) /* Max timeout length */
18835 #define MAXDBNAME MAXPATHLEN
18836 
18837 /* Attribute key indexes into an array of Attr structs, see below */
18838 
18839 #define KEY_DSN 0
18840 #define KEY_DESC 1
18841 #define KEY_DBNAME 2
18842 #define KEY_BUSY 3
18843 #define KEY_DRIVER 4
18844 #define KEY_STEPAPI 5
18845 #define KEY_SYNCP 6
18846 #define KEY_NOTXN 7
18847 #define KEY_SHORTNAM 8
18848 #define KEY_LONGNAM 9
18849 #define KEY_NOCREAT 10
18850 #define KEY_NOWCHAR 11
18851 #define KEY_LOADEXT 12
18852 #define KEY_JMODE 13
18853 #define KEY_FKSUPPORT 14
18854 #define KEY_OEMCP 15
18855 #define KEY_BIGINT 16
18856 #define KEY_PASSWD 17
18857 #define KEY_JDCONV 18
18858 #define NUMOFKEYS 19
18859 
18860 typedef struct {
18861  BOOL supplied;
18862  char attr[MAXPATHLEN*4];
18863 } ATTR;
18864 
18865 typedef struct {
18866  SQLHWND parent;
18867  LPCSTR driver;
18868  ATTR attr[NUMOFKEYS];
18869  char DSN[MAXDSNAME];
18870  BOOL newDSN;
18871  BOOL defDSN;
18872 } SETUPDLG;
18873 
18874 static struct {
18875  char *key;
18876  int ikey;
18877 } attrLookup[] = {
18878  { "DSN", KEY_DSN },
18879  { "DESC", KEY_DESC },
18880  { "Description", KEY_DESC},
18881  { "Database", KEY_DBNAME },
18882  { "Timeout", KEY_BUSY },
18883  { "Driver", KEY_DRIVER },
18884  { "StepAPI", KEY_STEPAPI },
18885  { "SyncPragma", KEY_SYNCP },
18886  { "NoTXN", KEY_NOTXN },
18887  { "ShortNames", KEY_SHORTNAM },
18888  { "LongNames", KEY_LONGNAM },
18889  { "NoCreat", KEY_NOCREAT },
18890  { "NoWCHAR", KEY_NOWCHAR },
18891  { "LoadExt", KEY_LOADEXT },
18892  { "JournalMode", KEY_JMODE },
18893  { "FKSupport", KEY_FKSUPPORT },
18894  { "OEMCP", KEY_OEMCP },
18895  { "BigInt", KEY_BIGINT },
18896  { "PWD", KEY_PASSWD },
18897  { "JDConv", KEY_JDCONV },
18898  { NULL, 0 }
18899 };
18900 
18907 static void
18908 ParseAttributes(LPCSTR attribs, SETUPDLG *setupdlg)
18909 {
18910  char *str = (char *) attribs, *start, key[MAXKEYLEN];
18911  int elem, nkey;
18912 
18913  while (*str) {
18914  start = str;
18915  if ((str = strchr(str, '=')) == NULL) {
18916  return;
18917  }
18918  elem = -1;
18919  nkey = str - start;
18920  if (nkey < sizeof (key)) {
18921  int i;
18922 
18923  memcpy(key, start, nkey);
18924  key[nkey] = '\0';
18925  for (i = 0; attrLookup[i].key; i++) {
18926  if (strcasecmp(attrLookup[i].key, key) == 0) {
18927  elem = attrLookup[i].ikey;
18928  break;
18929  }
18930  }
18931  }
18932  start = ++str;
18933  while (*str && *str != ';') {
18934  ++str;
18935  }
18936  if (elem >= 0) {
18937  int end = min(str - start, sizeof (setupdlg->attr[elem].attr) - 1);
18938 
18939  setupdlg->attr[elem].supplied = TRUE;
18940  memcpy(setupdlg->attr[elem].attr, start, end);
18941  setupdlg->attr[elem].attr[end] = '\0';
18942  }
18943  ++str;
18944  }
18945 }
18946 
18954 static BOOL
18955 SetDSNAttributes(HWND parent, SETUPDLG *setupdlg)
18956 {
18957  char *dsn = setupdlg->attr[KEY_DSN].attr;
18958 
18959  if (setupdlg->newDSN && strlen(dsn) == 0) {
18960  return FALSE;
18961  }
18962  if (!SQLWriteDSNToIni(dsn, setupdlg->driver)) {
18963  if (parent) {
18964  char buf[MAXPATHLEN], msg[MAXPATHLEN];
18965 
18966  LoadString(hModule, IDS_BADDSN, buf, sizeof (buf));
18967  wsprintf(msg, buf, dsn);
18968  LoadString(hModule, IDS_MSGTITLE, buf, sizeof (buf));
18969  MessageBox(parent, msg, buf,
18970  MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
18971  MB_SETFOREGROUND);
18972  }
18973  return FALSE;
18974  }
18975  if (parent || setupdlg->attr[KEY_DESC].supplied) {
18976  SQLWritePrivateProfileString(dsn, "Description",
18977  setupdlg->attr[KEY_DESC].attr,
18978  ODBC_INI);
18979  }
18980  if (parent || setupdlg->attr[KEY_DBNAME].supplied) {
18981  SQLWritePrivateProfileString(dsn, "Database",
18982  setupdlg->attr[KEY_DBNAME].attr,
18983  ODBC_INI);
18984  }
18985  if (parent || setupdlg->attr[KEY_BUSY].supplied) {
18986  SQLWritePrivateProfileString(dsn, "Timeout",
18987  setupdlg->attr[KEY_BUSY].attr,
18988  ODBC_INI);
18989  }
18990  if (parent || setupdlg->attr[KEY_STEPAPI].supplied) {
18991  SQLWritePrivateProfileString(dsn, "StepAPI",
18992  setupdlg->attr[KEY_STEPAPI].attr,
18993  ODBC_INI);
18994  }
18995  if (parent || setupdlg->attr[KEY_SYNCP].supplied) {
18996  SQLWritePrivateProfileString(dsn, "SyncPragma",
18997  setupdlg->attr[KEY_SYNCP].attr,
18998  ODBC_INI);
18999  }
19000  if (parent || setupdlg->attr[KEY_NOTXN].supplied) {
19001  SQLWritePrivateProfileString(dsn, "NoTXN",
19002  setupdlg->attr[KEY_NOTXN].attr,
19003  ODBC_INI);
19004  }
19005  if (parent || setupdlg->attr[KEY_SHORTNAM].supplied) {
19006  SQLWritePrivateProfileString(dsn, "ShortNames",
19007  setupdlg->attr[KEY_SHORTNAM].attr,
19008  ODBC_INI);
19009  }
19010  if (parent || setupdlg->attr[KEY_LONGNAM].supplied) {
19011  SQLWritePrivateProfileString(dsn, "LongNames",
19012  setupdlg->attr[KEY_LONGNAM].attr,
19013  ODBC_INI);
19014  }
19015  if (parent || setupdlg->attr[KEY_NOCREAT].supplied) {
19016  SQLWritePrivateProfileString(dsn, "NoCreat",
19017  setupdlg->attr[KEY_NOCREAT].attr,
19018  ODBC_INI);
19019  }
19020  if (parent || setupdlg->attr[KEY_NOWCHAR].supplied) {
19021  SQLWritePrivateProfileString(dsn, "NoWCHAR",
19022  setupdlg->attr[KEY_NOWCHAR].attr,
19023  ODBC_INI);
19024  }
19025  if (parent || setupdlg->attr[KEY_FKSUPPORT].supplied) {
19026  SQLWritePrivateProfileString(dsn, "FKSupport",
19027  setupdlg->attr[KEY_FKSUPPORT].attr,
19028  ODBC_INI);
19029  }
19030  if (parent || setupdlg->attr[KEY_OEMCP].supplied) {
19031  SQLWritePrivateProfileString(dsn, "OEMCP",
19032  setupdlg->attr[KEY_OEMCP].attr,
19033  ODBC_INI);
19034  }
19035  if (parent || setupdlg->attr[KEY_LOADEXT].supplied) {
19036  SQLWritePrivateProfileString(dsn, "LoadExt",
19037  setupdlg->attr[KEY_LOADEXT].attr,
19038  ODBC_INI);
19039  }
19040  if (parent || setupdlg->attr[KEY_BIGINT].supplied) {
19041  SQLWritePrivateProfileString(dsn, "BigInt",
19042  setupdlg->attr[KEY_BIGINT].attr,
19043  ODBC_INI);
19044  }
19045  if (parent || setupdlg->attr[KEY_JDCONV].supplied) {
19046  SQLWritePrivateProfileString(dsn, "JDConv",
19047  setupdlg->attr[KEY_JDCONV].attr,
19048  ODBC_INI);
19049  }
19050  if (parent || setupdlg->attr[KEY_PASSWD].supplied) {
19051  SQLWritePrivateProfileString(dsn, "PWD",
19052  setupdlg->attr[KEY_PASSWD].attr,
19053  ODBC_INI);
19054  }
19055  if (setupdlg->attr[KEY_DSN].supplied &&
19056  strcasecmp(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr)) {
19057  SQLRemoveDSNFromIni(setupdlg->DSN);
19058  }
19059  return TRUE;
19060 }
19061 
19067 static void
19068 GetAttributes(SETUPDLG *setupdlg)
19069 {
19070  char *dsn = setupdlg->attr[KEY_DSN].attr;
19071 
19072  if (!setupdlg->attr[KEY_DESC].supplied) {
19073  SQLGetPrivateProfileString(dsn, "Description", "",
19074  setupdlg->attr[KEY_DESC].attr,
19075  sizeof (setupdlg->attr[KEY_DESC].attr),
19076  ODBC_INI);
19077  }
19078  if (!setupdlg->attr[KEY_DBNAME].supplied) {
19079  SQLGetPrivateProfileString(dsn, "Database", "",
19080  setupdlg->attr[KEY_DBNAME].attr,
19081  sizeof (setupdlg->attr[KEY_DBNAME].attr),
19082  ODBC_INI);
19083  }
19084  if (!setupdlg->attr[KEY_BUSY].supplied) {
19085  SQLGetPrivateProfileString(dsn, "Timeout", "100000",
19086  setupdlg->attr[KEY_BUSY].attr,
19087  sizeof (setupdlg->attr[KEY_BUSY].attr),
19088  ODBC_INI);
19089  }
19090  if (!setupdlg->attr[KEY_STEPAPI].supplied) {
19091  SQLGetPrivateProfileString(dsn, "StepAPI", "0",
19092  setupdlg->attr[KEY_STEPAPI].attr,
19093  sizeof (setupdlg->attr[KEY_STEPAPI].attr),
19094  ODBC_INI);
19095  }
19096  if (!setupdlg->attr[KEY_SYNCP].supplied) {
19097  SQLGetPrivateProfileString(dsn, "SyncPragma", "NORMAL",
19098  setupdlg->attr[KEY_SYNCP].attr,
19099  sizeof (setupdlg->attr[KEY_SYNCP].attr),
19100  ODBC_INI);
19101  }
19102  if (!setupdlg->attr[KEY_NOTXN].supplied) {
19103  SQLGetPrivateProfileString(dsn, "NoTXN", "",
19104  setupdlg->attr[KEY_NOTXN].attr,
19105  sizeof (setupdlg->attr[KEY_NOTXN].attr),
19106  ODBC_INI);
19107  }
19108  if (!setupdlg->attr[KEY_SHORTNAM].supplied) {
19109  SQLGetPrivateProfileString(dsn, "ShortNames", "",
19110  setupdlg->attr[KEY_SHORTNAM].attr,
19111  sizeof (setupdlg->attr[KEY_SHORTNAM].attr),
19112  ODBC_INI);
19113  }
19114  if (!setupdlg->attr[KEY_LONGNAM].supplied) {
19115  SQLGetPrivateProfileString(dsn, "LongNames", "",
19116  setupdlg->attr[KEY_LONGNAM].attr,
19117  sizeof (setupdlg->attr[KEY_LONGNAM].attr),
19118  ODBC_INI);
19119  }
19120  if (!setupdlg->attr[KEY_NOCREAT].supplied) {
19121  SQLGetPrivateProfileString(dsn, "NoCreat", "",
19122  setupdlg->attr[KEY_NOCREAT].attr,
19123  sizeof (setupdlg->attr[KEY_NOCREAT].attr),
19124  ODBC_INI);
19125  }
19126  if (!setupdlg->attr[KEY_NOWCHAR].supplied) {
19127  SQLGetPrivateProfileString(dsn, "NoWCHAR", "",
19128  setupdlg->attr[KEY_NOWCHAR].attr,
19129  sizeof (setupdlg->attr[KEY_NOWCHAR].attr),
19130  ODBC_INI);
19131  }
19132  if (!setupdlg->attr[KEY_FKSUPPORT].supplied) {
19133  SQLGetPrivateProfileString(dsn, "FKSupport", "",
19134  setupdlg->attr[KEY_FKSUPPORT].attr,
19135  sizeof (setupdlg->attr[KEY_FKSUPPORT].attr),
19136  ODBC_INI);
19137  }
19138  if (!setupdlg->attr[KEY_OEMCP].supplied) {
19139  SQLGetPrivateProfileString(dsn, "OEMCP", "",
19140  setupdlg->attr[KEY_OEMCP].attr,
19141  sizeof (setupdlg->attr[KEY_OEMCP].attr),
19142  ODBC_INI);
19143  }
19144  if (!setupdlg->attr[KEY_LOADEXT].supplied) {
19145  SQLGetPrivateProfileString(dsn, "LoadExt", "",
19146  setupdlg->attr[KEY_LOADEXT].attr,
19147  sizeof (setupdlg->attr[KEY_LOADEXT].attr),
19148  ODBC_INI);
19149  }
19150  if (!setupdlg->attr[KEY_JMODE].supplied) {
19151  SQLGetPrivateProfileString(dsn, "JournalMode", "",
19152  setupdlg->attr[KEY_JMODE].attr,
19153  sizeof (setupdlg->attr[KEY_JMODE].attr),
19154  ODBC_INI);
19155  }
19156  if (!setupdlg->attr[KEY_BIGINT].supplied) {
19157  SQLGetPrivateProfileString(dsn, "BigInt", "",
19158  setupdlg->attr[KEY_BIGINT].attr,
19159  sizeof (setupdlg->attr[KEY_BIGINT].attr),
19160  ODBC_INI);
19161  }
19162  if (!setupdlg->attr[KEY_PASSWD].supplied) {
19163  SQLGetPrivateProfileString(dsn, "PWD", "",
19164  setupdlg->attr[KEY_PASSWD].attr,
19165  sizeof (setupdlg->attr[KEY_PASSWD].attr),
19166  ODBC_INI);
19167  }
19168  if (!setupdlg->attr[KEY_JDCONV].supplied) {
19169  SQLGetPrivateProfileString(dsn, "JDConv", "",
19170  setupdlg->attr[KEY_JDCONV].attr,
19171  sizeof (setupdlg->attr[KEY_JDCONV].attr),
19172  ODBC_INI);
19173  }
19174 }
19175 
19181 static void
19182 GetDBFile(HWND hdlg)
19183 {
19184 #ifdef _WIN64
19185  SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19186 #else
19187  SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19188 #endif
19189  OPENFILENAME ofn;
19190 
19191  memset(&ofn, 0, sizeof (ofn));
19192  ofn.lStructSize = sizeof (ofn);
19193  ofn.hwndOwner = hdlg;
19194 #ifdef _WIN64
19195  ofn.hInstance = (HINSTANCE) GetWindowLongPtr(hdlg, GWLP_HINSTANCE);
19196 #else
19197  ofn.hInstance = (HINSTANCE) GetWindowLong(hdlg, GWL_HINSTANCE);
19198 #endif
19199  ofn.lpstrFile = (LPTSTR) setupdlg->attr[KEY_DBNAME].attr;
19200  ofn.nMaxFile = MAXPATHLEN;
19201  ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST |
19202  OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_FILEMUSTEXIST;
19203  if (GetOpenFileName(&ofn)) {
19204  SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19205  setupdlg->attr[KEY_DBNAME].supplied = TRUE;
19206  }
19207 }
19208 
19218 static BOOL CALLBACK
19219 ConfigDlgProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19220 {
19221  SETUPDLG *setupdlg = NULL;
19222  WORD index;
19223 
19224  switch (wmsg) {
19225  case WM_INITDIALOG:
19226 #ifdef _WIN64
19227  SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19228 #else
19229  SetWindowLong(hdlg, DWL_USER, lparam);
19230 #endif
19231  setupdlg = (SETUPDLG *) lparam;
19232  GetAttributes(setupdlg);
19233  SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19234  SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19235  SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19236  SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19237  SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19238  SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19239  (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19240  SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19241  (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19242  SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19243  (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19244  SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19245  (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19246  SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19247  (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19248  CheckDlgButton(hdlg, IDC_STEPAPI,
19249  getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19250  BST_CHECKED : BST_UNCHECKED);
19251  CheckDlgButton(hdlg, IDC_NOTXN,
19252  getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19253  BST_CHECKED : BST_UNCHECKED);
19254  CheckDlgButton(hdlg, IDC_SHORTNAM,
19255  getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19256  BST_CHECKED : BST_UNCHECKED);
19257  CheckDlgButton(hdlg, IDC_LONGNAM,
19258  getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19259  BST_CHECKED : BST_UNCHECKED);
19260  CheckDlgButton(hdlg, IDC_NOCREAT,
19261  getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19262  BST_CHECKED : BST_UNCHECKED);
19263  CheckDlgButton(hdlg, IDC_NOWCHAR,
19264  getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19265  BST_CHECKED : BST_UNCHECKED);
19266  CheckDlgButton(hdlg, IDC_FKSUPPORT,
19267  getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19268  BST_CHECKED : BST_UNCHECKED);
19269  CheckDlgButton(hdlg, IDC_OEMCP,
19270  getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19271  BST_CHECKED : BST_UNCHECKED);
19272  CheckDlgButton(hdlg, IDC_BIGINT,
19273  getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19274  BST_CHECKED : BST_UNCHECKED);
19275  CheckDlgButton(hdlg, IDC_JDCONV,
19276  getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19277  BST_CHECKED : BST_UNCHECKED);
19278  SendDlgItemMessage(hdlg, IDC_SYNCP,
19279  CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19280  SendDlgItemMessage(hdlg, IDC_SYNCP,
19281  CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19282  SendDlgItemMessage(hdlg, IDC_SYNCP,
19283  CB_ADDSTRING, 0, (LPARAM) "OFF");
19284  SendDlgItemMessage(hdlg, IDC_SYNCP,
19285  CB_ADDSTRING, 0, (LPARAM) "FULL");
19286  SendDlgItemMessage(hdlg, IDC_SYNCP,
19287  CB_SELECTSTRING, (WPARAM) -1,
19288  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19289  if (setupdlg->defDSN) {
19290  EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19291  EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19292  }
19293  return TRUE;
19294  case WM_COMMAND:
19295  switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19296  case IDC_DSNAME:
19297  if (GET_WM_COMMAND_CMD(wparam, lparam) == EN_CHANGE) {
19298  char item[MAXDSNAME];
19299 
19300  EnableWindow(GetDlgItem(hdlg, IDOK),
19301  GetDlgItemText(hdlg, IDC_DSNAME,
19302  item, sizeof (item)));
19303  return TRUE;
19304  }
19305  break;
19306  case IDC_BROWSE:
19307  GetDBFile(hdlg);
19308  break;
19309  case IDOK:
19310 #ifdef _WIN64
19311  setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19312 #else
19313  setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19314 #endif
19315  if (!setupdlg->defDSN) {
19316  GetDlgItemText(hdlg, IDC_DSNAME,
19317  setupdlg->attr[KEY_DSN].attr,
19318  sizeof (setupdlg->attr[KEY_DSN].attr));
19319  }
19320  GetDlgItemText(hdlg, IDC_DESC,
19321  setupdlg->attr[KEY_DESC].attr,
19322  sizeof (setupdlg->attr[KEY_DESC].attr));
19323  GetDlgItemText(hdlg, IDC_DBNAME,
19324  setupdlg->attr[KEY_DBNAME].attr,
19325  sizeof (setupdlg->attr[KEY_DBNAME].attr));
19326  GetDlgItemText(hdlg, IDC_TONAME,
19327  setupdlg->attr[KEY_BUSY].attr,
19328  sizeof (setupdlg->attr[KEY_BUSY].attr));
19329  GetDlgItemText(hdlg, IDC_LOADEXT,
19330  setupdlg->attr[KEY_LOADEXT].attr,
19331  sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19332  index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19333  CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19334  if (index != (WORD) CB_ERR) {
19335  SendDlgItemMessage(hdlg, IDC_SYNCP,
19336  CB_GETLBTEXT, index,
19337  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19338  }
19339  strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19340  (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19341  "1" : "0");
19342  strcpy(setupdlg->attr[KEY_NOTXN].attr,
19343  (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19344  "1" : "0");
19345  strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19346  (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19347  "1" : "0");
19348  strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19349  (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19350  "1" : "0");
19351  strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19352  (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19353  "1" : "0");
19354  strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19355  (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19356  "1" : "0");
19357  strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19358  (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19359  "1" : "0");
19360  strcpy(setupdlg->attr[KEY_OEMCP].attr,
19361  (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19362  "1" : "0");
19363  strcpy(setupdlg->attr[KEY_BIGINT].attr,
19364  (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19365  "1" : "0");
19366  strcpy(setupdlg->attr[KEY_JDCONV].attr,
19367  (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19368  "1" : "0");
19369  SetDSNAttributes(hdlg, setupdlg);
19370  /* FALL THROUGH */
19371  case IDCANCEL:
19372  EndDialog(hdlg, wparam);
19373  return TRUE;
19374  }
19375  break;
19376  }
19377  return FALSE;
19378 }
19379 
19389 BOOL INSTAPI
19390 ConfigDSN(HWND hwnd, WORD request, LPCSTR driver, LPCSTR attribs)
19391 {
19392  BOOL success;
19393  SETUPDLG *setupdlg;
19394 
19395  setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
19396  if (setupdlg == NULL) {
19397  return FALSE;
19398  }
19399  memset(setupdlg, 0, sizeof (SETUPDLG));
19400  if (attribs) {
19401  ParseAttributes(attribs, setupdlg);
19402  }
19403  if (setupdlg->attr[KEY_DSN].supplied) {
19404  strcpy(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr);
19405  } else {
19406  setupdlg->DSN[0] = '\0';
19407  }
19408  if (request == ODBC_REMOVE_DSN) {
19409  if (!setupdlg->attr[KEY_DSN].supplied) {
19410  success = FALSE;
19411  } else {
19412  success = SQLRemoveDSNFromIni(setupdlg->attr[KEY_DSN].attr);
19413  }
19414  } else {
19415  setupdlg->parent = hwnd;
19416  setupdlg->driver = driver;
19417  setupdlg->newDSN = request == ODBC_ADD_DSN;
19418  setupdlg->defDSN = strcasecmp(setupdlg->attr[KEY_DSN].attr,
19419  "Default") == 0;
19420  if (hwnd) {
19421  success = DialogBoxParam(hModule, MAKEINTRESOURCE(CONFIGDSN),
19422  hwnd, (DLGPROC) ConfigDlgProc,
19423  (LPARAM) setupdlg) == IDOK;
19424  } else if (setupdlg->attr[KEY_DSN].supplied) {
19425  success = SetDSNAttributes(hwnd, setupdlg);
19426  } else {
19427  success = FALSE;
19428  }
19429  }
19430  xfree(setupdlg);
19431  return success;
19432 }
19433 
19443 static BOOL CALLBACK
19444 DriverConnectProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19445 {
19446  SETUPDLG *setupdlg;
19447  WORD index;
19448 
19449  switch (wmsg) {
19450  case WM_INITDIALOG:
19451 #ifdef _WIN64
19452  SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19453 #else
19454  SetWindowLong(hdlg, DWL_USER, lparam);
19455 #endif
19456  setupdlg = (SETUPDLG *) lparam;
19457  SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19458  SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19459  SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19460  SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19461  SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19462  SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19463  (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19464  SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19465  (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19466  SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19467  (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19468  SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19469  (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19470  SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19471  (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19472  CheckDlgButton(hdlg, IDC_STEPAPI,
19473  getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19474  BST_CHECKED : BST_UNCHECKED);
19475  CheckDlgButton(hdlg, IDC_NOTXN,
19476  getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19477  BST_CHECKED : BST_UNCHECKED);
19478  CheckDlgButton(hdlg, IDC_SHORTNAM,
19479  getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19480  BST_CHECKED : BST_UNCHECKED);
19481  CheckDlgButton(hdlg, IDC_LONGNAM,
19482  getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19483  BST_CHECKED : BST_UNCHECKED);
19484  CheckDlgButton(hdlg, IDC_NOCREAT,
19485  getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19486  BST_CHECKED : BST_UNCHECKED);
19487  CheckDlgButton(hdlg, IDC_NOWCHAR,
19488  getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19489  BST_CHECKED : BST_UNCHECKED);
19490  CheckDlgButton(hdlg, IDC_FKSUPPORT,
19491  getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19492  BST_CHECKED : BST_UNCHECKED);
19493  CheckDlgButton(hdlg, IDC_OEMCP,
19494  getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19495  BST_CHECKED : BST_UNCHECKED);
19496  CheckDlgButton(hdlg, IDC_BIGINT,
19497  getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19498  BST_CHECKED : BST_UNCHECKED);
19499  CheckDlgButton(hdlg, IDC_JDCONV,
19500  getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19501  BST_CHECKED : BST_UNCHECKED);
19502  SendDlgItemMessage(hdlg, IDC_SYNCP,
19503  CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19504  SendDlgItemMessage(hdlg, IDC_SYNCP,
19505  CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19506  SendDlgItemMessage(hdlg, IDC_SYNCP,
19507  CB_ADDSTRING, 0, (LPARAM) "OFF");
19508  SendDlgItemMessage(hdlg, IDC_SYNCP,
19509  CB_ADDSTRING, 0, (LPARAM) "FULL");
19510  SendDlgItemMessage(hdlg, IDC_SYNCP,
19511  CB_SELECTSTRING, (WORD) -1,
19512  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19513  if (setupdlg->defDSN) {
19514  EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19515  EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19516  }
19517  return TRUE;
19518  case WM_COMMAND:
19519  switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19520  case IDC_BROWSE:
19521  GetDBFile(hdlg);
19522  break;
19523  case IDOK:
19524 #ifdef _WIN64
19525  setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19526 #else
19527  setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19528 #endif
19529  GetDlgItemText(hdlg, IDC_DSNAME,
19530  setupdlg->attr[KEY_DSN].attr,
19531  sizeof (setupdlg->attr[KEY_DSN].attr));
19532  GetDlgItemText(hdlg, IDC_DBNAME,
19533  setupdlg->attr[KEY_DBNAME].attr,
19534  sizeof (setupdlg->attr[KEY_DBNAME].attr));
19535  GetDlgItemText(hdlg, IDC_TONAME,
19536  setupdlg->attr[KEY_BUSY].attr,
19537  sizeof (setupdlg->attr[KEY_BUSY].attr));
19538  GetDlgItemText(hdlg, IDC_LOADEXT,
19539  setupdlg->attr[KEY_LOADEXT].attr,
19540  sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19541  index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19542  CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19543  if (index != (WORD) CB_ERR) {
19544  SendDlgItemMessage(hdlg, IDC_SYNCP,
19545  CB_GETLBTEXT, index,
19546  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19547  }
19548  strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19549  (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19550  "1" : "0");
19551  strcpy(setupdlg->attr[KEY_NOTXN].attr,
19552  (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19553  "1" : "0");
19554  strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19555  (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19556  "1" : "0");
19557  strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19558  (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19559  "1" : "0");
19560  strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19561  (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19562  "1" : "0");
19563  strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19564  (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19565  "1" : "0");
19566  strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19567  (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19568  "1" : "0");
19569  strcpy(setupdlg->attr[KEY_OEMCP].attr,
19570  (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19571  "1" : "0");
19572  strcpy(setupdlg->attr[KEY_BIGINT].attr,
19573  (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19574  "1" : "0");
19575  strcpy(setupdlg->attr[KEY_JDCONV].attr,
19576  (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19577  "1" : "0");
19578  /* FALL THROUGH */
19579  case IDCANCEL:
19580  EndDialog(hdlg, GET_WM_COMMAND_ID(wparam, lparam) == IDOK);
19581  return TRUE;
19582  }
19583  }
19584  return FALSE;
19585 }
19586 
19600 static SQLRETURN
19601 drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
19602  SQLCHAR *connIn, SQLSMALLINT connInLen,
19603  SQLCHAR *connOut, SQLSMALLINT connOutMax,
19604  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19605 {
19606  BOOL maybeprompt, prompt = FALSE, defaultdsn = FALSE;
19607  DBC *d;
19608  SETUPDLG *setupdlg;
19609  SQLRETURN ret;
19610  char *dsn = NULL, *driver = NULL, *dbname = NULL;
19611 
19612  if (dbc == SQL_NULL_HDBC) {
19613  return SQL_INVALID_HANDLE;
19614  }
19615  d = (DBC *) dbc;
19616  if (d->sqlite) {
19617  setstatd(d, -1, "connection already established", "08002");
19618  return SQL_ERROR;
19619  }
19620  setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
19621  if (setupdlg == NULL) {
19622  return SQL_ERROR;
19623  }
19624  memset(setupdlg, 0, sizeof (SETUPDLG));
19625  maybeprompt = drvcompl == SQL_DRIVER_COMPLETE ||
19626  drvcompl == SQL_DRIVER_COMPLETE_REQUIRED;
19627  if (connIn == NULL || !connInLen ||
19628  (connInLen == SQL_NTS && !connIn[0])) {
19629  prompt = TRUE;
19630  } else {
19631  ParseAttributes((LPCSTR) connIn, setupdlg);
19632  if (!setupdlg->attr[KEY_DSN].attr[0] &&
19633  drvcompl == SQL_DRIVER_COMPLETE_REQUIRED) {
19634  strcpy(setupdlg->attr[KEY_DSN].attr, "DEFAULT");
19635  defaultdsn = TRUE;
19636  }
19637  GetAttributes(setupdlg);
19638  if (drvcompl == SQL_DRIVER_PROMPT ||
19639  (maybeprompt &&
19640  !setupdlg->attr[KEY_DBNAME].attr[0])) {
19641  prompt = TRUE;
19642  }
19643  }
19644 retry:
19645  if (prompt) {
19646  short dlgret;
19647 
19648  setupdlg->defDSN = setupdlg->attr[KEY_DRIVER].attr[0] != '\0';
19649  dlgret = DialogBoxParam(hModule, MAKEINTRESOURCE(DRIVERCONNECT),
19650  hwnd, (DLGPROC) DriverConnectProc,
19651  (LPARAM) setupdlg);
19652 
19653  if (!dlgret || dlgret == -1) {
19654  xfree(setupdlg);
19655  return SQL_NO_DATA;
19656  }
19657  }
19658  dsn = setupdlg->attr[KEY_DSN].attr;
19659  driver = setupdlg->attr[KEY_DRIVER].attr;
19660  dbname = setupdlg->attr[KEY_DBNAME].attr;
19661  if (connOut || connOutLen) {
19662  char buf[SQL_MAX_MESSAGE_LENGTH * 4];
19663  int len, count;
19664  char dsn_0 = (dsn && !defaultdsn) ? dsn[0] : '\0';
19665  char drv_0 = driver ? driver[0] : '\0';
19666 
19667  buf[0] = '\0';
19668  count = snprintf(buf, sizeof (buf),
19669  "%s%s%s%s%s%sDatabase=%s;StepAPI=%s;"
19670  "SyncPragma=%s;NoTXN=%s;Timeout=%s;"
19671  "ShortNames=%s;LongNames=%s;"
19672  "NoCreat=%s;NoWCHAR=%s;"
19673  "FKSupport=%s;JournalMode=%s;OEMCP=%s;LoadExt=%s;"
19674  "BigInt=%s;JDConv=%s;PWD=%s",
19675  dsn_0 ? "DSN=" : "",
19676  dsn_0 ? dsn : "",
19677  dsn_0 ? ";" : "",
19678  drv_0 ? "Driver=" : "",
19679  drv_0 ? driver : "",
19680  drv_0 ? ";" : "",
19681  dbname ? dbname : "",
19682  setupdlg->attr[KEY_STEPAPI].attr,
19683  setupdlg->attr[KEY_SYNCP].attr,
19684  setupdlg->attr[KEY_NOTXN].attr,
19685  setupdlg->attr[KEY_BUSY].attr,
19686  setupdlg->attr[KEY_SHORTNAM].attr,
19687  setupdlg->attr[KEY_LONGNAM].attr,
19688  setupdlg->attr[KEY_NOCREAT].attr,
19689  setupdlg->attr[KEY_NOWCHAR].attr,
19690  setupdlg->attr[KEY_FKSUPPORT].attr,
19691  setupdlg->attr[KEY_JMODE].attr,
19692  setupdlg->attr[KEY_OEMCP].attr,
19693  setupdlg->attr[KEY_LOADEXT].attr,
19694  setupdlg->attr[KEY_BIGINT].attr,
19695  setupdlg->attr[KEY_JDCONV].attr,
19696  setupdlg->attr[KEY_PASSWD].attr);
19697  if (count < 0) {
19698  buf[sizeof (buf) - 1] = '\0';
19699  }
19700  len = min(connOutMax - 1, strlen(buf));
19701  if (connOut) {
19702  strncpy((char *) connOut, buf, len);
19703  connOut[len] = '\0';
19704  }
19705  if (connOutLen) {
19706  *connOutLen = len;
19707  }
19708  }
19709  if (dsn[0]) {
19710  char tracef[SQL_MAX_MESSAGE_LENGTH];
19711 
19712  tracef[0] = '\0';
19713  SQLGetPrivateProfileString(setupdlg->attr[KEY_DSN].attr,
19714  "tracefile", "", tracef,
19715  sizeof (tracef), ODBC_INI);
19716  if (tracef[0] != '\0') {
19717  d->trace = fopen(tracef, "a");
19718  }
19719  }
19720  d->nowchar = getbool(setupdlg->attr[KEY_NOWCHAR].attr);
19721  d->shortnames = getbool(setupdlg->attr[KEY_SHORTNAM].attr);
19722  d->longnames = getbool(setupdlg->attr[KEY_LONGNAM].attr);
19723  d->nocreat = getbool(setupdlg->attr[KEY_NOCREAT].attr);
19724  d->fksupport = getbool(setupdlg->attr[KEY_FKSUPPORT].attr);
19725  d->oemcp = getbool(setupdlg->attr[KEY_OEMCP].attr);
19726  d->dobigint = getbool(setupdlg->attr[KEY_BIGINT].attr);
19727  d->jdconv = getbool(setupdlg->attr[KEY_JDCONV].attr);
19728  d->pwdLen = strlen(setupdlg->attr[KEY_PASSWD].attr);
19729  d->pwd = (d->pwdLen > 0) ? setupdlg->attr[KEY_PASSWD].attr : NULL;
19730  ret = dbopen(d, dbname ? dbname : "", 0,
19731  dsn ? dsn : "",
19732  setupdlg->attr[KEY_STEPAPI].attr,
19733  setupdlg->attr[KEY_SYNCP].attr,
19734  setupdlg->attr[KEY_NOTXN].attr,
19735  setupdlg->attr[KEY_JMODE].attr,
19736  setupdlg->attr[KEY_BUSY].attr);
19737  if (ret != SQL_SUCCESS) {
19738  if (maybeprompt && !prompt) {
19739  prompt = TRUE;
19740  goto retry;
19741  }
19742  }
19743  memset(setupdlg->attr[KEY_PASSWD].attr, 0,
19744  sizeof (setupdlg->attr[KEY_PASSWD].attr));
19745  if (ret == SQL_SUCCESS) {
19746  dbloadext(d, setupdlg->attr[KEY_LOADEXT].attr);
19747  }
19748  xfree(setupdlg);
19749  return ret;
19750 }
19751 
19752 #endif /* WITHOUT_DRIVERMGR */
19753 #endif /* _WIN32 || _WIN64 */
19754 
19755 #ifndef WINTERFACE
19756 
19769 SQLRETURN SQL_API
19770 SQLDriverConnect(SQLHDBC dbc, SQLHWND hwnd,
19771  SQLCHAR *connIn, SQLSMALLINT connInLen,
19772  SQLCHAR *connOut, SQLSMALLINT connOutMax,
19773  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19774 {
19775  SQLRETURN ret;
19776 
19777  HDBC_LOCK(dbc);
19778  ret = drvdriverconnect(dbc, hwnd, connIn, connInLen,
19779  connOut, connOutMax, connOutLen, drvcompl);
19780  HDBC_UNLOCK(dbc);
19781  return ret;
19782 }
19783 #endif
19784 
19785 #ifdef WINTERFACE
19786 
19799 SQLRETURN SQL_API
19800 SQLDriverConnectW(SQLHDBC dbc, SQLHWND hwnd,
19801  SQLWCHAR *connIn, SQLSMALLINT connInLen,
19802  SQLWCHAR *connOut, SQLSMALLINT connOutMax,
19803  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19804 {
19805  SQLRETURN ret;
19806  char *ci = NULL;
19807  SQLSMALLINT len = 0;
19808 
19809  HDBC_LOCK(dbc);
19810  if (connIn) {
19811 #if defined(_WIN32) || defined(_WIN64)
19812  if (connInLen == SQL_NTS) {
19813  connInLen = -1;
19814  }
19815  ci = uc_to_wmb(connIn, connInLen);
19816 #else
19817  ci = uc_to_utf(connIn, connInLen);
19818 #endif
19819  if (!ci) {
19820  DBC *d = (DBC *) dbc;
19821 
19822  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
19823  HDBC_UNLOCK(dbc);
19824  return SQL_ERROR;
19825  }
19826  }
19827  ret = drvdriverconnect(dbc, hwnd, (SQLCHAR *) ci, SQL_NTS,
19828  (SQLCHAR *) connOut, connOutMax, &len, drvcompl);
19829  HDBC_UNLOCK(dbc);
19830  uc_free(ci);
19831  if (ret == SQL_SUCCESS) {
19832  SQLWCHAR *co = NULL;
19833 
19834  if (connOut) {
19835  if (len > 0) {
19836 #if defined(_WIN32) || defined(_WIN64)
19837  co = wmb_to_uc((char *) connOut, len);
19838 #else
19839  co = uc_from_utf((SQLCHAR *) connOut, len);
19840 #endif
19841  if (co) {
19842  uc_strncpy(connOut, co, connOutMax / sizeof (SQLWCHAR));
19843  len = min(connOutMax / sizeof (SQLWCHAR), uc_strlen(co));
19844  uc_free(co);
19845  } else {
19846  len = 0;
19847  }
19848  }
19849  if (len <= 0) {
19850  len = 0;
19851  connOut[0] = 0;
19852  }
19853  } else {
19854  len = 0;
19855  }
19856  if (connOutLen) {
19857  *connOutLen = len;
19858  }
19859  }
19860  return ret;
19861 }
19862 #endif
19863 
19864 #if defined(_WIN32) || defined(_WIN64)
19865 
19874 BOOL APIENTRY
19875 LibMain(HANDLE hinst, DWORD reason, LPVOID reserved)
19876 {
19877  static int initialized = 0;
19878 
19879  switch (reason) {
19880  case DLL_PROCESS_ATTACH:
19881  if (!initialized++) {
19882  hModule = hinst;
19883 #ifdef WINTERFACE
19884  /* MS Access hack part 1 (reserved error -7748) */
19885  statSpec2P = statSpec2;
19886  statSpec3P = statSpec3;
19887 #endif
19888 #ifdef SQLITE_DYNLOAD
19889  dls_init();
19890 #endif
19891 #ifdef SQLITE_HAS_CODEC
19892  sqlite3_activate_see(SQLITE_ACTIVATION_KEY);
19893 #endif
19894  }
19895 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
19896  nvfs_init();
19897 #endif
19898  break;
19899  case DLL_THREAD_ATTACH:
19900  break;
19901  case DLL_PROCESS_DETACH:
19902  if (--initialized <= 0) {
19903 #ifdef SQLITE_DYNLOAD
19904  dls_fini();
19905 #endif
19906  }
19907  break;
19908  case DLL_THREAD_DETACH:
19909  break;
19910  default:
19911  break;
19912  }
19913  return TRUE;
19914 }
19915 
19924 int __stdcall
19925 DllMain(HANDLE hinst, DWORD reason, LPVOID reserved)
19926 {
19927  return LibMain(hinst, reason, reserved);
19928 }
19929 
19930 #ifndef WITHOUT_INSTALLER
19931 
19938 static BOOL
19939 InUnError(char *name)
19940 {
19941  WORD err = 1;
19942  DWORD code;
19943  char errmsg[301];
19944  WORD errlen, errmax = sizeof (errmsg) - 1;
19945  int sqlret;
19946  BOOL ret = FALSE;
19947 
19948  do {
19949  errmsg[0] = '\0';
19950  sqlret = SQLInstallerError(err, &code, errmsg, errmax, &errlen);
19951  if (SQL_SUCCEEDED(sqlret)) {
19952  MessageBox(NULL, errmsg, name,
19953  MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
19954  ret = TRUE;
19955  }
19956  err++;
19957  } while (sqlret != SQL_NO_DATA);
19958  return ret;
19959 }
19960 
19967 static BOOL
19968 InUn(int remove, char *cmdline)
19969 {
19970 #ifdef SQLITE_HAS_CODEC
19971  static char *drivername = "SQLite3 ODBC Driver (SEE)";
19972  static char *dsname = "SQLite3 SEE Datasource";
19973 #else
19974  static char *drivername = "SQLite3 ODBC Driver";
19975  static char *dsname = "SQLite3 Datasource";
19976 #endif
19977  char *dllname, *p;
19978  char dllbuf[301], path[301], driver[300], attr[300], inst[400];
19979  WORD pathmax = sizeof (path) - 1, pathlen;
19980  DWORD usecnt, mincnt;
19981  int quiet = 0;
19982 
19983  dllbuf[0] = '\0';
19984  GetModuleFileName(hModule, dllbuf, sizeof (dllbuf));
19985  p = strrchr(dllbuf, '\\');
19986  dllname = p ? (p + 1) : dllbuf;
19987  quiet = cmdline && strstr(cmdline, "quiet");
19988  if (SQLInstallDriverManager(path, pathmax, &pathlen)) {
19989  sprintf(driver, "%s;Driver=%s;Setup=%s;",
19990  drivername, dllname, dllname);
19991  p = driver;
19992  while (*p) {
19993  if (*p == ';') {
19994  *p = '\0';
19995  }
19996  ++p;
19997  }
19998  usecnt = 0;
19999  path[0] = '\0';
20000  SQLInstallDriverEx(driver, NULL, path, pathmax, NULL,
20001  ODBC_INSTALL_INQUIRY, &usecnt);
20002  pathlen = strlen(path);
20003  while (pathlen > 0 && path[pathlen - 1] == '\\') {
20004  --pathlen;
20005  path[pathlen] = '\0';
20006  }
20007  sprintf(driver, "%s;Driver=%s\\%s;Setup=%s\\%s;",
20008  drivername, path, dllname, path, dllname);
20009  p = driver;
20010  while (*p) {
20011  if (*p == ';') {
20012  *p = '\0';
20013  }
20014  ++p;
20015  }
20016  sprintf(inst, "%s\\%s", path, dllname);
20017  if (!remove && usecnt > 0) {
20018  /* first install try: copy over driver dll, keeping DSNs */
20019  if (GetFileAttributesA(dllbuf) != INVALID_FILE_ATTRIBUTES &&
20020  CopyFile(dllbuf, inst, 0)) {
20021  if (!quiet) {
20022  char buf[512];
20023 
20024  sprintf(buf, "%s replaced.", drivername);
20025  MessageBox(NULL, buf, "Info",
20026  MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20027  MB_SETFOREGROUND);
20028  }
20029  return TRUE;
20030  }
20031  }
20032  mincnt = remove ? 1 : 0;
20033  while (usecnt != mincnt) {
20034  if (!SQLRemoveDriver(driver, TRUE, &usecnt)) {
20035  break;
20036  }
20037  }
20038  if (remove) {
20039  if (usecnt && !SQLRemoveDriver(driver, TRUE, &usecnt)) {
20040  InUnError("SQLRemoveDriver");
20041  return FALSE;
20042  }
20043  if (!usecnt) {
20044  char buf[512];
20045 
20046  DeleteFile(inst);
20047  if (!quiet) {
20048  sprintf(buf, "%s uninstalled.", drivername);
20049  MessageBox(NULL, buf, "Info",
20050  MB_ICONINFORMATION |MB_OK | MB_TASKMODAL |
20051  MB_SETFOREGROUND);
20052  }
20053  }
20054  sprintf(attr, "DSN=%s;Database=;", dsname);
20055  p = attr;
20056  while (*p) {
20057  if (*p == ';') {
20058  *p = '\0';
20059  }
20060  ++p;
20061  }
20062  SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20063  return TRUE;
20064  }
20065  if (GetFileAttributesA(dllbuf) == INVALID_FILE_ATTRIBUTES) {
20066  return FALSE;
20067  }
20068  if (strcasecmp(dllbuf, inst) != 0 && !CopyFile(dllbuf, inst, 0)) {
20069  char buf[512];
20070 
20071  sprintf(buf, "Copy %s to %s failed.", dllbuf, inst);
20072  MessageBox(NULL, buf, "CopyFile",
20073  MB_ICONSTOP |MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
20074  return FALSE;
20075  }
20076  if (!SQLInstallDriverEx(driver, path, path, pathmax, &pathlen,
20077  ODBC_INSTALL_COMPLETE, &usecnt)) {
20078  InUnError("SQLInstallDriverEx");
20079  return FALSE;
20080  }
20081  sprintf(attr, "DSN=%s;Database=;", dsname);
20082  p = attr;
20083  while (*p) {
20084  if (*p == ';') {
20085  *p = '\0';
20086  }
20087  ++p;
20088  }
20089  SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20090  if (!SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN, drivername, attr)) {
20091  InUnError("SQLConfigDataSource");
20092  return FALSE;
20093  }
20094  if (!quiet) {
20095  char buf[512];
20096 
20097  sprintf(buf, "%s installed.", drivername);
20098  MessageBox(NULL, buf, "Info",
20099  MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20100  MB_SETFOREGROUND);
20101  }
20102  } else {
20103  InUnError("SQLInstallDriverManager");
20104  return FALSE;
20105  }
20106  return TRUE;
20107 }
20108 
20117 void CALLBACK
20118 install(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20119 {
20120  InUn(0, lpszCmdLine);
20121 }
20122 
20131 void CALLBACK
20132 uninstall(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20133 {
20134  InUn(1, lpszCmdLine);
20135 }
20136 
20137 #endif /* WITHOUT_INSTALLER */
20138 
20139 #ifndef WITHOUT_SHELL
20140 
20149 static void
20150 setargv(int *argcp, char ***argvp, char *cmdline, char *argv0)
20151 {
20152  char *p, *arg, *argspace, **argv;
20153  int argc, size, inquote, copy, slashes;
20154 
20155  size = 2 + (argv0 ? 1 : 0);
20156  for (p = cmdline; *p != '\0'; p++) {
20157  if (ISSPACE(*p)) {
20158  size++;
20159  while (ISSPACE(*p)) {
20160  p++;
20161  }
20162  if (*p == '\0') {
20163  break;
20164  }
20165  }
20166  }
20167  argspace = malloc(size * sizeof (char *) + strlen(cmdline) + 1);
20168  argv = (char **) argspace;
20169  argspace += size * sizeof (char *);
20170  size--;
20171  argc = 0;
20172  if (argv0) {
20173  argv[argc++] = argv0;
20174  }
20175  p = cmdline;
20176  for (; argc < size; argc++) {
20177  argv[argc] = arg = argspace;
20178  while (ISSPACE(*p)) {
20179  p++;
20180  }
20181  if (*p == '\0') {
20182  break;
20183  }
20184  inquote = 0;
20185  slashes = 0;
20186  while (1) {
20187  copy = 1;
20188  while (*p == '\\') {
20189  slashes++;
20190  p++;
20191  }
20192  if (*p == '"') {
20193  if ((slashes & 1) == 0) {
20194  copy = 0;
20195  if (inquote && p[1] == '"') {
20196  p++;
20197  copy = 1;
20198  } else {
20199  inquote = !inquote;
20200  }
20201  }
20202  slashes >>= 1;
20203  }
20204  while (slashes) {
20205  *arg = '\\';
20206  arg++;
20207  slashes--;
20208  }
20209  if (*p == '\0' || (!inquote && ISSPACE(*p))) {
20210  break;
20211  }
20212  if (copy != 0) {
20213  *arg = *p;
20214  arg++;
20215  }
20216  p++;
20217  }
20218  *arg = '\0';
20219  argspace = arg + 1;
20220  }
20221  argv[argc] = 0;
20222  *argcp = argc;
20223  *argvp = argv;
20224 }
20225 
20234 void CALLBACK
20235 shell(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20236 {
20237  int argc, needcon = 0;
20238  char **argv;
20239  extern int sqlite3_main(int, char **);
20240  static const char *name = "SQLite3 Shell";
20241  DWORD ftype0, ftype1, ftype2;
20242 
20243  ftype0 = GetFileType(GetStdHandle(STD_INPUT_HANDLE));
20244  ftype1 = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
20245  ftype2 = GetFileType(GetStdHandle(STD_ERROR_HANDLE));
20246  if (ftype0 != FILE_TYPE_DISK && ftype0 != FILE_TYPE_CHAR &&
20247  ftype0 != FILE_TYPE_PIPE) {
20248  fclose(stdin);
20249  ++needcon;
20250  ftype0 = FILE_TYPE_UNKNOWN;
20251  }
20252  if (ftype1 != FILE_TYPE_DISK && ftype1 != FILE_TYPE_CHAR &&
20253  ftype1 != FILE_TYPE_PIPE) {
20254  fclose(stdout);
20255  ++needcon;
20256  ftype1 = FILE_TYPE_UNKNOWN;
20257  }
20258  if (ftype2 != FILE_TYPE_DISK && ftype2 != FILE_TYPE_CHAR &&
20259  ftype2 != FILE_TYPE_PIPE) {
20260  fclose(stderr);
20261  ++needcon;
20262  ftype2 = FILE_TYPE_UNKNOWN;
20263  }
20264  if (needcon > 0) {
20265  AllocConsole();
20266  SetConsoleTitle(name);
20267  }
20268  if (ftype0 == FILE_TYPE_UNKNOWN) {
20269  freopen("CONIN$", "r", stdin);
20270  }
20271  if (ftype1 == FILE_TYPE_UNKNOWN) {
20272  freopen("CONOUT$", "w", stdout);
20273  }
20274  if (ftype2 == FILE_TYPE_UNKNOWN) {
20275  freopen("CONOUT$", "w", stderr);
20276  }
20277  setargv(&argc, &argv, lpszCmdLine, (char *) name);
20278 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
20279  nvfs_init();
20280 #endif
20281  sqlite3_main(argc, argv);
20282 }
20283 
20284 #endif /* WITHOUT_SHELL */
20285 
20286 #endif /* _WIN32 || _WIN64 */
20287 
20288 #if defined(HAVE_ODBCINSTEXT_H) && (HAVE_ODBCINSTEXT_H)
20289 
20290 /*
20291  * unixODBC property page for this driver,
20292  * may or may not work depending on unixODBC version.
20293  */
20294 
20295 #include <odbcinstext.h>
20296 
20297 int
20298 ODBCINSTGetProperties(HODBCINSTPROPERTY prop)
20299 {
20300  static const char *instYN[] = { "No", "Yes", NULL };
20301  static const char *syncPragma[] = { "NORMAL", "OFF", "FULL", NULL };
20302  static const char *jmPragma[] = {
20303  "DELETE", "PERSIST", "OFF", "TRUNCATE", "MEMORY", "WAL", NULL
20304  };
20305 
20306  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20307  prop = prop->pNext;
20308  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20309  prop->nPromptType = ODBCINST_PROMPTTYPE_FILENAME;
20310  strncpy(prop->szName, "Database", INI_MAX_PROPERTY_NAME);
20311  strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20312  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20313  prop = prop->pNext;
20314  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20315  prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20316  strncpy(prop->szName, "Timeout", INI_MAX_PROPERTY_NAME);
20317  strncpy(prop->szValue, "100000", INI_MAX_PROPERTY_VALUE);
20318  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20319  prop = prop->pNext;
20320  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20321  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20322  prop->aPromptData = malloc(sizeof (instYN));
20323  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20324  strncpy(prop->szName, "StepAPI", INI_MAX_PROPERTY_NAME);
20325  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20326  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20327  prop = prop->pNext;
20328  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20329  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20330  prop->aPromptData = malloc(sizeof (instYN));
20331  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20332  strncpy(prop->szName, "ShortNames", INI_MAX_PROPERTY_NAME);
20333  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20334  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20335  prop = prop->pNext;
20336  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20337  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20338  prop->aPromptData = malloc(sizeof (instYN));
20339  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20340  strncpy(prop->szName, "LongNames", INI_MAX_PROPERTY_NAME);
20341  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20342  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20343  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20344  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20345  prop->aPromptData = malloc(sizeof (instYN));
20346  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20347  strncpy(prop->szName, "NoCreat", INI_MAX_PROPERTY_NAME);
20348  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20349 #ifdef WINTERFACE
20350  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20351  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20352  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20353  prop->aPromptData = malloc(sizeof (instYN));
20354  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20355  strncpy(prop->szName, "NoWCHAR", INI_MAX_PROPERTY_NAME);
20356  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20357 #endif
20358  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20359  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20360  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20361  prop->aPromptData = malloc(sizeof (instYN));
20362  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20363  strncpy(prop->szName, "FKSupport", INI_MAX_PROPERTY_NAME);
20364  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20365  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20366  prop = prop->pNext;
20367  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20368  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20369  prop->aPromptData = malloc(sizeof (syncPragma));
20370  memcpy(prop->aPromptData, syncPragma, sizeof (syncPragma));
20371  strncpy(prop->szName, "SyncPragma", INI_MAX_PROPERTY_NAME);
20372  strncpy(prop->szValue, "NORMAL", INI_MAX_PROPERTY_VALUE);
20373  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20374  prop = prop->pNext;
20375  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20376  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20377  prop->aPromptData = malloc(sizeof (jmPragma));
20378  memcpy(prop->aPromptData, jmPragma, sizeof (jmPragma));
20379  strncpy(prop->szName, "JournalMode", INI_MAX_PROPERTY_NAME);
20380  strncpy(prop->szValue, "DELETE", INI_MAX_PROPERTY_VALUE);
20381  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20382  prop = prop->pNext;
20383  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20384  prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20385  strncpy(prop->szName, "LoadExt", INI_MAX_PROPERTY_NAME);
20386  strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20387  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20388  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20389  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20390  prop->aPromptData = malloc(sizeof (instYN));
20391  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20392  strncpy(prop->szName, "BigInt", INI_MAX_PROPERTY_NAME);
20393  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20394  return 1;
20395 }
20396 
20397 #endif /* HAVE_ODBCINSTEXT_H */
20398 
20399 #ifdef SQLITE_DYNLOAD
20400 
20401 /*
20402  * SQLite3 shared library/DLL stubs.
20403  */
20404 
20405 static void
20406 dls_void(void)
20407 {
20408 }
20409 
20410 static int
20411 dls_error(void)
20412 {
20413  return SQLITE_ERROR;
20414 }
20415 
20416 static int
20417 dls_0(void)
20418 {
20419  return 0;
20420 }
20421 
20422 static sqlite_int64
20423 dls_0LL(void)
20424 {
20425  return 0;
20426 }
20427 
20428 static double
20429 dls_00(void)
20430 {
20431  return 0;
20432 }
20433 
20434 static void *
20435 dls_null(void)
20436 {
20437  return NULL;
20438 }
20439 
20440 static const char *
20441 dls_empty(void)
20442 {
20443  return "";
20444 }
20445 
20446 static int
20447 dls_snull(void)
20448 {
20449  return SQLITE_NULL;
20450 }
20451 
20452 #define DLS_ENT(name, func) \
20453  { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, name), \
20454  (void *) func }
20455 
20456 #define DLS_ENT3(name, off, func) \
20457  { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, off), \
20458  (void *) func }
20459 
20460 #define DLS_END { NULL, 0, NULL }
20461 
20462 static struct {
20463  const char *name;
20464  int offset;
20465  void *func;
20466 } dls_nametab[] = {
20467  DLS_ENT(activate_see, dls_void),
20468  DLS_ENT(bind_blob, dls_error),
20469  DLS_ENT(bind_double, dls_error),
20470  DLS_ENT(bind_int, dls_error),
20471  DLS_ENT(bind_int64, dls_error),
20472  DLS_ENT(bind_null, dls_error),
20473  DLS_ENT(bind_parameter_count, dls_0),
20474  DLS_ENT(bind_text, dls_error),
20475  DLS_ENT(busy_handler, dls_error),
20476  DLS_ENT(changes, dls_0),
20477  DLS_ENT(close, dls_error),
20478  DLS_ENT(column_blob, dls_null),
20479  DLS_ENT(column_bytes, dls_0),
20480  DLS_ENT(column_count, dls_0),
20481  DLS_ENT(column_database_name, dls_empty),
20482  DLS_ENT(column_decltype, dls_empty),
20483  DLS_ENT(column_double, dls_00),
20484  DLS_ENT(column_name, dls_empty),
20485  DLS_ENT(column_origin_name, dls_null),
20486  DLS_ENT(column_table_name, dls_null),
20487  DLS_ENT(column_text, dls_null),
20488  DLS_ENT(column_type, dls_snull),
20489  DLS_ENT(create_function, dls_error),
20490  DLS_ENT(enable_load_extension, dls_error),
20491  DLS_ENT(errcode, dls_error),
20492  DLS_ENT(errmsg, dls_empty),
20493  DLS_ENT(exec, dls_error),
20494  DLS_ENT(finalize, dls_error),
20495  DLS_ENT(free, free),
20496  DLS_ENT(free_table, dls_void),
20497  DLS_ENT(get_table, dls_error),
20498  DLS_ENT(interrupt, dls_void),
20499  DLS_ENT(key, dls_error),
20500  DLS_ENT(last_insert_rowid, dls_0LL),
20501  DLS_ENT(libversion, dls_empty),
20502  DLS_ENT(load_extension, dls_error),
20503  DLS_ENT(malloc, malloc),
20504  DLS_ENT(mprintf, dls_null),
20505  DLS_ENT(open, dls_error),
20506  DLS_ENT(open16, dls_error),
20507  DLS_ENT(open_v2, dls_error),
20508  DLS_ENT(prepare, dls_error),
20509  DLS_ENT(prepare_v2, dls_error),
20510  DLS_ENT(profile, dls_null),
20511  DLS_ENT(realloc, realloc),
20512  DLS_ENT(rekey, dls_error),
20513  DLS_ENT(reset, dls_error),
20514  DLS_ENT(result_blob, dls_void),
20515  DLS_ENT(result_error, dls_void),
20516  DLS_ENT(result_int, dls_void),
20517  DLS_ENT(result_null, dls_void),
20518  DLS_ENT(step, dls_error),
20519 #if defined(_WIN32) || defined(_WIN64)
20520  DLS_ENT3(strnicmp, xstrnicmp, _strnicmp),
20521 #else
20522  DLS_ENT3(strnicmp, xstrnicmp, strncasecmp),
20523 #endif
20524  DLS_ENT(table_column_metadata, dls_error),
20525  DLS_ENT(trace, dls_null),
20526  DLS_ENT(user_data, dls_null),
20527  DLS_ENT(value_blob, dls_null),
20528  DLS_ENT(value_bytes, dls_0),
20529  DLS_ENT(value_text, dls_empty),
20530  DLS_ENT(value_type, dls_snull),
20531  DLS_END
20532 };
20533 
20534 #if defined(_WIN32) || defined(_WIN64)
20535 
20536 static HMODULE sqlite3_dll = 0;
20537 
20538 static void
20539 dls_init(void)
20540 {
20541  int i;
20542  static const char *dll_names[] = {
20543  "System.Data.SQLite.dll",
20544  "sqlite3.dll",
20545  NULL,
20546  };
20547 
20548  i = 0;
20549  while (dll_names[i]) {
20550  sqlite3_dll = LoadLibrary(dll_names[i]);
20551  if (sqlite3_dll) {
20552  break;
20553  }
20554  ++i;
20555  }
20556  i = 0;
20557  while (dls_nametab[i].name) {
20558  void *func = 0, **loc;
20559 
20560  if (sqlite3_dll) {
20561  func = (void *) GetProcAddress(sqlite3_dll, dls_nametab[i].name);
20562  }
20563  if (!func) {
20564  func = dls_nametab[i].func;
20565  }
20566  loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
20567  *loc = func;
20568  ++i;
20569  }
20570  if (!sqlite3_dll) {
20571  char buf[MAXPATHLEN], msg[MAXPATHLEN];
20572 
20573  LoadString(hModule, IDS_DRVTITLE, buf, sizeof (buf));
20574  LoadString(hModule, IDS_DLLERR, msg, sizeof (msg));
20575  MessageBox(NULL, msg, buf,
20576  MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
20577  MB_SETFOREGROUND);
20578  }
20579 }
20580 
20581 static void
20582 dls_fini(void)
20583 {
20584  if (sqlite3_dll) {
20585  FreeLibrary(sqlite3_dll);
20586  sqlite3_dll = 0;
20587  }
20588 }
20589 
20590 #else
20591 
20592 #include <dlfcn.h>
20593 
20594 static void *libsqlite3_so = 0;
20595 
20596 void
20597 dls_init(void)
20598 {
20599  int i;
20600 
20601  libsqlite3_so = dlopen("libsqlite3.so.0", RTLD_NOW | RTLD_GLOBAL);
20602  i = 0;
20603  while (dls_nametab[i].name) {
20604  void *func = 0, **loc;
20605 
20606  if (libsqlite3_so) {
20607  func = dlsym(libsqlite3_so, dls_nametab[i].name);
20608  }
20609  if (!func) {
20610  func = dls_nametab[i].func;
20611  }
20612  loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
20613  *loc = func;
20614  ++i;
20615  }
20616  if (!libsqlite3_so) {
20617  const char errmsg[] = "SQLite3 shared library not found.\n";
20618 
20619  write(2, errmsg, sizeof (errmsg) - 1);
20620  }
20621 }
20622 
20623 void
20624 dls_fini(void)
20625 {
20626  if (libsqlite3_so) {
20627  dlclose(libsqlite3_so);
20628  libsqlite3_so = 0;
20629  }
20630 }
20631 
20632 #endif
20633 
20634 #endif
20635 
20636 /*
20637  * Local Variables:
20638  * mode: c
20639  * c-basic-offset: 4
20640  * fill-column: 78
20641  * tab-width: 8
20642  * End:
20643  */
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:5593
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:5870
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:9614
static SQLRETURN nomem(STMT *s)
Report S1000 (out of memory) SQL error given STMT.
Definition: sqlite3odbc.c:1830
static const char lower_chars[]
Definition: sqlite3odbc.c:535
static int findcol(char **cols, int ncols, char *name)
Find column given name in string array.
Definition: sqlite3odbc.c:2760
int longnames
Don't shorten column names.
Definition: sqlite3odbc.h:133
int nocreat
Don't auto create database file.
Definition: sqlite3odbc.h:134
#define xstrdup(x)
Definition: sqlite3odbc.c:394
#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:2168
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:1705
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:5008
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:7802
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:5627
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:626
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:1307
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:1408
static void blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function to import a BLOB from a file.
Definition: sqlite3odbc.c:3686
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:1316
int ispk
Flag for primary key (> 0)
Definition: sqlite3odbc.h:175
static SQLRETURN dofetchbind(STMT *s, int rsi)
Internal: fetch and bind from statement's current row.
PTRDIFF_T ndata
index into result array
Definition: sqlite3odbc.c:1398
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:3217
Internal structure for bound column (SQLBindCol).
Definition: sqlite3odbc.h:187
static COL pkeySpec2[]
Columns for result set of SQLPrimaryKeys().
Definition: sqlite3odbc.c:6397
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:250
static COL fkeySpec2[]
Columns for result set of SQLForeignKeys().
Definition: sqlite3odbc.c:7241
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:2194
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:2318
SQLRETURN SQL_API SQLAllocEnv(SQLHENV *env)
Allocate HENV.
#define ISDIGIT(c)
Definition: sqlite3odbc.c:556
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:554
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:8695
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:8128
static SQLRETURN drvallocenv(SQLHENV *env)
Internal allocate HENV.
static COL procSpec2[]
Columns for result set of SQLProcedures().
Definition: sqlite3odbc.c:8163
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:6428
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:4534
SQLRETURN SQL_API SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno, SQLSMALLINT fieldid, SQLPOINTER value, SQLINTEGER buflen)
Function not implemented.
Definition: sqlite3odbc.c:5823
#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:563
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:393
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:8367
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:9373
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:9445
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:264
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:8340
static void dbtrace(void *arg, const char *msg, sqlite_uint64 et)
SQLite trace or profile callback.
Definition: sqlite3odbc.c:3821
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:520
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:8053
static void blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function to export a BLOB to a file.
Definition: sqlite3odbc.c:3756
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:1396
static COL procColSpec3[]
Definition: sqlite3odbc.c:8269
static double ln_strtod(const char *data, char **endp)
Internal locale neutral strtod function.
Definition: sqlite3odbc.c:1859
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:4773
#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:2403
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:7294
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:251
static SQLRETURN noconn(STMT *s)
Report S1000 (not connected) SQL error given STMT.
Definition: sqlite3odbc.c:1843
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:4992
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:5544
SQLRETURN SQL_API SQLCopyDesc(SQLHDESC source, SQLHDESC target)
Function not implemented.
Definition: sqlite3odbc.c:8066
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:5891
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:8894
static int namematch(char *str, char *pat, int esc)
SQL LIKE string match with optional backslash escape handling.
Definition: sqlite3odbc.c:1963
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:806
static SQLWCHAR * uc_from_utf(unsigned char *str, int len)
Make UNICODE string from UTF8 string.
Definition: sqlite3odbc.c:938
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:8039
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:5681
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:1399
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:5933
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:5966
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:6260
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'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:9583
static void freep(void *x)
Free memory given pointer to memory pointer.
Definition: sqlite3odbc.c:1815
static void fixupdyncols(STMT *s, DBC *d)
Fixup column information for a running statement.
Definition: sqlite3odbc.c:2791
static char * uc_to_utf(SQLWCHAR *str, int len)
Make UTF8 string from UNICODE string.
Definition: sqlite3odbc.c:964
int nosign
Unsigned type.
Definition: sqlite3odbc.h:170
static int getmdays(int year, int month)
Return number of month days.
Definition: sqlite3odbc.c:3068
static COL tablePrivSpec3[]
Definition: sqlite3odbc.c:5943
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:6756
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:7194
static int str2date(int jdconv, char *str, DATE_STRUCT *ds)
Convert string to ODBC DATE_STRUCT.
Definition: sqlite3odbc.c:3102
static COL procSpec3[]
Definition: sqlite3odbc.c:8174
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:9954
static COL colPrivSpec3[]
Definition: sqlite3odbc.c:6317
#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't try to use WCHAR.
Definition: sqlite3odbc.h:130
#define HSTMT_UNLOCK(hdbc)
Definition: sqlite3odbc.c:521
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:9543
SQLRETURN SQL_API SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SETSTMTOPTION_LAST_ARG_TYPE param)
Set option on HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9564
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:1527
Internal structure for managing driver's sqlite3_get_table() implementation.
Definition: sqlite3odbc.c:1390
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:6801
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:6406
static int busy_handler(void *udata, int count)
Busy callback for SQLite.
Definition: sqlite3odbc.c:2036
static char * uc_to_utf_c(SQLWCHAR *str, int len)
Make UTF8 string from UNICODE string.
Definition: sqlite3odbc.c:1047
#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:3338
static SQLRETURN starttran(STMT *s)
Start transaction when autocommit off.
Definition: sqlite3odbc.c:7880
static int s3stmt_step(STMT *s)
Do one sqlite statement step gathering one result row.
Definition: sqlite3odbc.c:4284
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:8247
static SQLRETURN drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER buflen)
Internal set option on HSTMT.
Definition: sqlite3odbc.c:9165
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'ed size of result array
Definition: sqlite3odbc.c:1395
static void dbtraceapi(DBC *d, char *fn, const char *sql)
Trace function for SQLite API calls.
Definition: sqlite3odbc.c:3859
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:4715
int coldef
Definition: sqlite3odbc.h:204
static int getbool(char *string)
Get boolean flag from string.
Definition: sqlite3odbc.c:3670
SQLRETURN SQL_API SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Get option of HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9143
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:5854
int nowchar[2]
Don't try to use WCHAR.
Definition: sqlite3odbc.h:260
static const char upper_chars[]
Definition: sqlite3odbc.c:534
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:5033
#define stringify(s)
Definition: sqlite3odbc.c:236
int binlen
Length of blob data.
Definition: sqlite3odbc.h:288
#define SCOL_VARCHAR
Definition: sqlite3odbc.c:243
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:1778
SQLUSMALLINT * row_status0
Internal status array.
Definition: sqlite3odbc.h:266
#define SCOL_CHAR
Definition: sqlite3odbc.c:244
static void s3stmt_end_if(STMT *s)
Conditionally stop running sqlite statement.
Definition: sqlite3odbc.c:4562
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:2111
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:9425
static SQLRETURN drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
Internal set option on HSTMT.
Definition: sqlite3odbc.c:9465
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:604
FILE * trace
sqlite3_trace() file pointer or NULL
Definition: sqlite3odbc.h:143
Internal structure representing dynamic strings.
Definition: sqlite3odbc.c:260
static void freeresult(STMT *s, int clrcols)
Free statement's result.
SQLRETURN SQL_API SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER buflen)
Set option on HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9352
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:832
sqlite3_stmt * stmt
SQLite3 statement pointer.
Definition: sqlite3odbc.c:1393
static void uc_free(void *str)
Free converted UTF8 or UNICODE string.
Definition: sqlite3odbc.c:1065
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:7923
int oom
True when out of memory.
Definition: sqlite3odbc.c:263
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:4751
char * db
Database name.
Definition: sqlite3odbc.h:164
static const char * xdigits
Definition: sqlite3odbc.c:267
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:8617
char sqlstate[6]
SQL state for SQLError()
Definition: sqlite3odbc.h:128
int bound
True when SQLBindParameter() called.
Definition: sqlite3odbc.h:212
void(* rowfree)()
Free function for rows.
Definition: sqlite3odbc.h:256
static void dbloadext(DBC *d, char *exts)
Load SQLite extension modules, if any.
Definition: sqlite3odbc.c:4117
static BOOL InUn(int remove, char *drivername, char *dllname, char *dll2name, char *dsname)
Driver installer/uninstaller.
Definition: inst.c:150
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.
static int TOLOWER(int c)
Definition: sqlite3odbc.c:538
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:1394
static COL colSpec2[]
Columns for result set of SQLColumns().
int ncol
number of columns in result array
Definition: sqlite3odbc.c:1397
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:5515
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.
Definition: sqlite3odbc.c:9991
static int dserr(dstr *dsp)
Check error on dynamic string.
Definition: sqlite3odbc.c:757
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:3011
static dstr * dsappendq(dstr *dsp, const char *str)
Append string quoted to dynamic string.
Definition: sqlite3odbc.c:678
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:5746
static COL colPrivSpec2[]
Columns for result set of SQLColumnPrivileges().
Definition: sqlite3odbc.c:6307
int size
Size of column.
Definition: sqlite3odbc.h:168
static COL scolSpec3[]
Definition: sqlite3odbc.c:6813
static SQLRETURN drvunimplstmt(HSTMT stmt)
Report IM001 (not implemented) SQL error code for HSTMT.
Definition: sqlite3odbc.c:1797
struct dstr dstr
SQLRETURN SQL_API SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
Set information in HENV.
Definition: sqlite3odbc.c:8425
static char * s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
Find out column type.
Definition: sqlite3odbc.c:4191
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:4681
#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:5795
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:768
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:4601
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:565
#define drvrelgpps(d)
Definition: sqlite3odbc.c:1308
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:5567
char strbuf[64]
String buffer for scalar data.
Definition: sqlite3odbc.h:215
static COL fkeySpec3[]
Definition: sqlite3odbc.c:7258
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:7982
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:1745
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:4580
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:1392
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:8970
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:3903
static int uc_strlen(SQLWCHAR *str)
Return length of UNICODE string.
Definition: sqlite3odbc.c:784
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:519
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:1900
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:6376
static void convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
Convert julian day to hour/minute/second.
Definition: sqlite3odbc.c:3039
char ** resarr
result array
Definition: sqlite3odbc.c:1391
#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:3879
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:6841
int len
Current length.
Definition: sqlite3odbc.c:261
#define DEAD_MAGIC
Definition: sqlite3odbc.c:252
static const char * dsval(dstr *dsp)
Return dynamic string's value.
Definition: sqlite3odbc.c:742
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:5376
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:8228
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:2494
SQLRETURN SQL_API SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
Function not implemented.
Definition: sqlite3odbc.c:5765
#define xmalloc(x)
Definition: sqlite3odbc.c:391
#define ODBC_INI
Definition: sqlite3odbc.c:205
#define xrealloc(x, y)
Definition: sqlite3odbc.c:392
#define HDBC_LOCK(hdbc)
Definition: sqlite3odbc.c:518
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:8486
Header file for SQLite3 ODBC driver.
int max
Maximum length of buffer.
Definition: sqlite3odbc.c:262
static int unescpat(char *str)
Unescape search pattern for e.g.
Definition: sqlite3odbc.c:1925

Generated on Thu May 12 2016 by doxygen.
Contact: chw@ch-werner.de