sqlite3odbc.c
Go to the documentation of this file.
1 
14 #if defined(SQLITE_HAS_CODEC) && defined(SQLITE_API)
15 #undef WITH_SQLITE_DLLS
16 #undef SQLITE_DYNLOAD
17 #include "sqlite3.c"
18 #endif
19 
20 #if defined(WITH_SQLITE_DLLS) && (WITH_SQLITE_DLLS > 1)
21 #define SQLITE_DYNLOAD 1
22 #undef HAVE_SQLITE3CLOSEV2
23 #endif
24 
25 #include "sqlite3odbc.h"
26 
27 #ifdef SQLITE_DYNLOAD
28 
29 #undef MEMORY_DEBUG
30 
31 #if defined(_WIN32) || defined(_WIN64)
32 static void dls_init(void);
33 static void dls_fini(void);
34 #else
35 void dls_init(void);
36 void dls_fini(void);
37 #endif
38 
39 static struct dl_sqlite3_funcs {
40  void (*activate_see)(const char *p0);
41  int (*bind_blob)(sqlite3_stmt *p0, int p1, const void *p2, int p3,
42  void (*p4)(void *));
43  int (*bind_double)(sqlite3_stmt *p0, int p1, double p2);
44  int (*bind_int)(sqlite3_stmt *p0, int p1, int p2);
45  int (*bind_int64)(sqlite3_stmt *p0, int p1, sqlite_int64 p2);
46  int (*bind_null)(sqlite3_stmt *p0, int p1);
47  int (*bind_parameter_count)(sqlite3_stmt *p0);
48  int (*bind_text)(sqlite3_stmt *p0, int p1, const char *p2, int p3,
49  void (*p4)(void *));
50  int (*busy_handler)(sqlite3 *p0, int (*p2)(void *, int), void *p3);
51  int (*changes)(sqlite3 *p0);
52  int (*close)(sqlite3 *p0);
53  const void * (*column_blob)(sqlite3_stmt *p0, int p1);
54  int (*column_bytes)(sqlite3_stmt *p0, int p1);
55  int (*column_count)(sqlite3_stmt *p0);
56  const char * (*column_database_name)(sqlite3_stmt *p0, int p1);
57  const char * (*column_decltype)(sqlite3_stmt *p0, int p1);
58  double (*column_double)(sqlite3_stmt *p0, int p1);
59  const char * (*column_name)(sqlite3_stmt *p0, int p1);
60  const char * (*column_origin_name)(sqlite3_stmt *p0, int p1);
61  const char * (*column_table_name)(sqlite3_stmt *p0, int p1);
62  const unsigned char * (*column_text)(sqlite3_stmt *p0, int p1);
63  int (*column_type)(sqlite3_stmt *p0, int p1);
64  int (*create_function)(sqlite3 *p0, const char *p1, int p2, int p3,
65  void *p4,
66  void (*p5)(sqlite3_context *, int, sqlite3_value **),
67  void (*p6)(sqlite3_context *, int, sqlite3_value **),
68  void (*p7)(sqlite3_context *));
69  int (*enable_load_extension)(sqlite3 *p0, int p1);
70  int (*errcode)(sqlite3 *p0);
71  const char * (*errmsg)(sqlite3 *p0);
72  int (*exec)(sqlite3 *p0, const char *p1,
73  int (*p2)(void *, int, char **, char **),
74  void *p3, char **p4);
75  int (*finalize)(sqlite3_stmt *p0);
76  void (*free)(void *p0);
77  void (*free_table)(char **p0);
78  int (*get_table)(sqlite3 *p0, const char *p1, char ***p2,
79  int *p3, int *p4, char **p5);
80  void (*interrupt)(sqlite3 *p0);
81  int (*key)(sqlite3 *p0, const void *p1, int p2);
82  sqlite_int64 (*last_insert_rowid)(sqlite3 *p0);
83  const char * (*libversion)(void);
84  int (*load_extension)(sqlite3 *p0, const char *p1, const char *p2,
85  char **p3);
86  void * (*malloc)(int p0);
87  char * (*mprintf)(const char *p0, ...);
88  int (*open)(const char *p0, sqlite3 **p1);
89  int (*open16)(const void *p0, sqlite3 **p1);
90  int (*open_v2)(const char *p0, sqlite3 **p1, int p2, const char *p3);
91  int (*prepare)(sqlite3 *p0, const char *p1, int p2, sqlite3_stmt **p3,
92  const char **p4);
93  int (*prepare_v2)(sqlite3 *p0, const char *p1, int p2, sqlite3_stmt **p3,
94  const char **p4);
95  void * (*profile)(sqlite3 *p0,
96  void (*p1)(void *, const char *, sqlite3_uint64),
97  void *p2);
98  void * (*realloc)(void *p0, int p1);
99  int (*rekey)(sqlite3 *p0, const void *p1, int p2);
100  int (*reset)(sqlite3_stmt *p0);
101  void (*result_blob)(sqlite3_context *p0, const void *p1,
102  int p2, void (*p3)(void *));
103  void (*result_error)(sqlite3_context *p0, const char *p1, int p2);
104  void (*result_int)(sqlite3_context *p0, int p1);
105  void (*result_null)(sqlite3_context *p0);
106  int (*step)(sqlite3_stmt *p0);
107  int (*xstrnicmp)(const char *p0, const char *p1, int p2);
108  int (*table_column_metadata)(sqlite3 *p0, const char *p1,
109  const char *p2, const char *p3,
110  char const **p4, char const **p5,
111  int *p6, int *p7, int *p8);
112  void * (*trace)(sqlite3 *p0, void (*p1)(void *, const char *), void *p2);
113  void * (*user_data)(sqlite3_context *p0);
114  const void * (*value_blob)(sqlite3_value *p0);
115  int (*value_bytes)(sqlite3_value *p0);
116  const unsigned char * (*value_text)(sqlite3_value *p0);
117  int (*value_type)(sqlite3_value *p0);
118 } dls_funcs;
119 
120 #define sqlite3_activate_see dls_funcs.activate_see
121 #define sqlite3_bind_blob dls_funcs.bind_blob
122 #define sqlite3_bind_double dls_funcs.bind_double
123 #define sqlite3_bind_int dls_funcs.bind_int
124 #define sqlite3_bind_int64 dls_funcs.bind_int64
125 #define sqlite3_bind_null dls_funcs.bind_null
126 #define sqlite3_bind_parameter_count dls_funcs.bind_parameter_count
127 #define sqlite3_bind_text dls_funcs.bind_text
128 #define sqlite3_busy_handler dls_funcs.busy_handler
129 #define sqlite3_changes dls_funcs.changes
130 #define sqlite3_close dls_funcs.close
131 #define sqlite3_column_blob dls_funcs.column_blob
132 #define sqlite3_column_bytes dls_funcs.column_bytes
133 #define sqlite3_column_count dls_funcs.column_count
134 #define sqlite3_column_database_name dls_funcs.column_database_name
135 #define sqlite3_column_decltype dls_funcs.column_decltype
136 #define sqlite3_column_double dls_funcs.column_double
137 #define sqlite3_column_name dls_funcs.column_name
138 #define sqlite3_column_origin_name dls_funcs.column_origin_name
139 #define sqlite3_column_table_name dls_funcs.column_table_name
140 #define sqlite3_column_text dls_funcs.column_text
141 #define sqlite3_column_type dls_funcs.column_type
142 #define sqlite3_create_function dls_funcs.create_function
143 #define sqlite3_enable_load_extension dls_funcs.enable_load_extension
144 #define sqlite3_errcode dls_funcs.errcode
145 #define sqlite3_errmsg dls_funcs.errmsg
146 #define sqlite3_exec dls_funcs.exec
147 #define sqlite3_finalize dls_funcs.finalize
148 #define sqlite3_free dls_funcs.free
149 #define sqlite3_free_table dls_funcs.free_table
150 #define sqlite3_get_table dls_funcs.get_table
151 #define sqlite3_interrupt dls_funcs.interrupt
152 #define sqlite3_key dls_funcs.key
153 #define sqlite3_last_insert_rowid dls_funcs.last_insert_rowid
154 #define sqlite3_libversion dls_funcs.libversion
155 #define sqlite3_load_extension dls_funcs.load_extension
156 #define sqlite3_malloc dls_funcs.malloc
157 #define sqlite3_mprintf dls_funcs.mprintf
158 #define sqlite3_open dls_funcs.open
159 #define sqlite3_open16 dls_funcs.open16
160 #define sqlite3_open_v2 dls_funcs.open_v2
161 #define sqlite3_prepare dls_funcs.prepare
162 #define sqlite3_prepare_v2 dls_funcs.prepare_v2
163 #define sqlite3_profile dls_funcs.profile
164 #define sqlite3_realloc dls_funcs.realloc
165 #define sqlite3_rekey dls_funcs.rekey
166 #define sqlite3_reset dls_funcs.reset
167 #define sqlite3_result_blob dls_funcs.result_blob
168 #define sqlite3_result_error dls_funcs.result_error
169 #define sqlite3_result_int dls_funcs.result_int
170 #define sqlite3_result_null dls_funcs.result_null
171 #define sqlite3_step dls_funcs.step
172 #define sqlite3_strnicmp dls_funcs.xstrnicmp
173 #define sqlite3_table_column_metadata dls_funcs.table_column_metadata
174 #define sqlite3_trace dls_funcs.trace
175 #define sqlite3_user_data dls_funcs.user_data
176 #define sqlite3_value_blob dls_funcs.value_blob
177 #define sqlite3_value_bytes dls_funcs.value_bytes
178 #define sqlite3_value_text dls_funcs.value_text
179 #define sqlite3_value_type dls_funcs.value_type
180 
181 #endif
182 
183 #ifndef WITHOUT_WINTERFACE
184 #define WINTERFACE
185 #define WCHARSUPPORT
186 #endif
187 
188 #if !defined(_WIN32) && !defined(_WIN64)
189 #if !defined(WCHARSUPPORT) && defined(HAVE_SQLWCHAR) && (HAVE_SQLWCHAR)
190 #define WCHARSUPPORT
191 #endif
192 #endif
193 
194 #if defined(WINTERFACE)
195 #include <sqlucode.h>
196 #endif
197 
198 #if defined(_WIN32) || defined(_WIN64)
199 #include "resource3.h"
200 #define ODBC_INI "ODBC.INI"
201 #ifndef DRIVER_VER_INFO
202 #define DRIVER_VER_INFO VERSION
203 #endif
204 #else
205 #define ODBC_INI ".odbc.ini"
206 #endif
207 
208 #ifndef DRIVER_VER_INFO
209 #define DRIVER_VER_INFO "0.0"
210 #endif
211 
212 #ifndef COLATTRIBUTE_LAST_ARG_TYPE
213 #ifdef _WIN64
214 #define COLATTRIBUTE_LAST_ARG_TYPE SQLLEN *
215 #else
216 #define COLATTRIBUTE_LAST_ARG_TYPE SQLPOINTER
217 #endif
218 #endif
219 
220 #ifndef SETSTMTOPTION_LAST_ARG_TYPE
221 #define SETSTMTOPTION_LAST_ARG_TYPE SQLROWCOUNT
222 #endif
223 
224 #undef min
225 #define min(a, b) ((a) < (b) ? (a) : (b))
226 #undef max
227 #define max(a, b) ((a) < (b) ? (b) : (a))
228 
229 #ifndef PTRDIFF_T
230 #define PTRDIFF_T int
231 #endif
232 
233 #define array_size(x) (sizeof (x) / sizeof (x[0]))
234 
235 #define stringify1(s) #s
236 #define stringify(s) stringify1(s)
237 
238 #define verinfo(maj, min, lev) ((maj) << 16 | (min) << 8 | (lev))
239 
240 /* Column meta data from SQLite support */
241 #undef FULL_METADATA
242 #if defined(HAVE_SQLITE3TABLECOLUMNMETADATA) && (HAVE_SQLITE3TABLECOLUMNMETADATA)
243 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
244 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
245 #if defined(HAVE_SQLITE3COLUMNORIGINNAME) && (HAVE_SQLITE3COLUMNORIGINNAME)
246 #define FULL_METADATA 1
247 #endif
248 #endif
249 #endif
250 #endif
251 
252 /* Column types for static string column descriptions (SQLTables etc.) */
253 
254 #if defined(WINTERFACE) && !defined(_WIN32) && !defined(_WIN64)
255 #define SCOL_VARCHAR SQL_WVARCHAR
256 #define SCOL_CHAR SQL_WCHAR
257 #else
258 #define SCOL_VARCHAR SQL_VARCHAR
259 #define SCOL_CHAR SQL_CHAR
260 #endif
261 
262 #define ENV_MAGIC 0x53544145
263 #define DBC_MAGIC 0x53544144
264 #define DEAD_MAGIC 0xdeadbeef
265 
272 typedef struct dstr {
273  int len;
274  int max;
275  int oom;
276  char buffer[1];
277 } dstr;
278 
279 static const char *xdigits = "0123456789ABCDEFabcdef";
280 
281 #ifdef MEMORY_DEBUG
282 
283 static void *
284 xmalloc_(int n, char *file, int line)
285 {
286  int nn = n + 4 * sizeof (long);
287  long *p;
288 
289  p = malloc(nn);
290  if (!p) {
291 #if (MEMORY_DEBUG > 1)
292  fprintf(stderr, "malloc\t%d\tNULL\t%s:%d\n", n, file, line);
293 #endif
294  return NULL;
295  }
296  p[0] = 0xdead1234;
297  nn = nn / sizeof (long) - 1;
298  p[1] = n;
299  p[nn] = 0xdead5678;
300 #if (MEMORY_DEBUG > 1)
301  fprintf(stderr, "malloc\t%d\t%p\t%s:%d\n", n, &p[2], file, line);
302 #endif
303  return (void *) &p[2];
304 }
305 
306 static void *
307 xrealloc_(void *old, int n, char *file, int line)
308 {
309  int nn = n + 4 * sizeof (long), nnn;
310  long *p, *pp;
311 
312  if (n == 0 || !old) {
313  return xmalloc_(n, file, line);
314  }
315  p = &((long *) old)[-2];
316  if (p[0] != 0xdead1234) {
317  fprintf(stderr, "*** low end corruption @ %p\n", old);
318  abort();
319  }
320  nnn = p[1] + 4 * sizeof (long);
321  nnn = nnn / sizeof (long) - 1;
322  if (p[nnn] != 0xdead5678) {
323  fprintf(stderr, "*** high end corruption @ %p\n", old);
324  abort();
325  }
326  pp = realloc(p, nn);
327  if (!pp) {
328 #if (MEMORY_DEBUG > 1)
329  fprintf(stderr, "realloc\t%p,%d\tNULL\t%s:%d\n", old, n, file, line);
330 #endif
331  return NULL;
332  }
333 #if (MEMORY_DEBUG > 1)
334  fprintf(stderr, "realloc\t%p,%d\t%p\t%s:%d\n", old, n, &pp[2], file, line);
335 #endif
336  p = pp;
337  p[1] = n;
338  nn = nn / sizeof (long) - 1;
339  p[nn] = 0xdead5678;
340  return (void *) &p[2];
341 }
342 
343 static void
344 xfree_(void *x, char *file, int line)
345 {
346  long *p;
347  int n;
348 
349  if (!x) {
350  return;
351  }
352  p = &((long *) x)[-2];
353  if (p[0] != 0xdead1234) {
354  fprintf(stderr, "*** low end corruption @ %p\n", x);
355  abort();
356  }
357  n = p[1] + 4 * sizeof (long);
358  n = n / sizeof (long) - 1;
359  if (p[n] != 0xdead5678) {
360  fprintf(stderr, "*** high end corruption @ %p\n", x);
361  abort();
362  }
363 #if (MEMORY_DEBUG > 1)
364  fprintf(stderr, "free\t%p\t\t%s:%d\n", x, file, line);
365 #endif
366  free(p);
367 }
368 
369 static void
370 xfree__(void *x)
371 {
372  xfree_(x, "unknown location", 0);
373 }
374 
375 static char *
376 xstrdup_(const char *str, char *file, int line)
377 {
378  char *p;
379 
380  if (!str) {
381 #if (MEMORY_DEBUG > 1)
382  fprintf(stderr, "strdup\tNULL\tNULL\t%s:%d\n", file, line);
383 #endif
384  return NULL;
385  }
386  p = xmalloc_(strlen(str) + 1, file, line);
387  if (p) {
388  strcpy(p, str);
389  }
390 #if (MEMORY_DEBUG > 1)
391  fprintf(stderr, "strdup\t%p\t%p\t%s:%d\n", str, p, file, line);
392 #endif
393  return p;
394 }
395 
396 #define xmalloc(x) xmalloc_(x, __FILE__, __LINE__)
397 #define xrealloc(x,y) xrealloc_(x, y, __FILE__, __LINE__)
398 #define xfree(x) xfree_(x, __FILE__, __LINE__)
399 #define xstrdup(x) xstrdup_(x, __FILE__, __LINE__)
400 
401 #else
402 
403 #define xmalloc(x) sqlite3_malloc(x)
404 #define xrealloc(x,y) sqlite3_realloc(x, y)
405 #define xfree(x) sqlite3_free(x)
406 #define xstrdup(x) strdup_(x)
407 
408 #endif
409 
410 #if defined(_WIN32) || defined(_WIN64)
411 
412 #define vsnprintf _vsnprintf
413 #define snprintf _snprintf
414 #define strcasecmp _stricmp
415 #define strncasecmp _strnicmp
416 
417 #ifdef _MSC_VER
418 #define strtoll _strtoi64
419 #define strtoull _strtoui64
420 #endif
421 
422 static HINSTANCE NEAR hModule; /* Saved module handle for resources */
423 
424 #endif
425 
426 #ifdef HAVE_SQLITE3STRNICMP
427 #undef strncasecmp
428 #define strncasecmp(A,B,C) sqlite3_strnicmp(A,B,C)
429 #undef strcasecmp
430 #define strcasecmp(A,B) strcasecmp_(A,B)
431 
432 #if defined(__GNUC__) && (__GNUC__ >= 2)
433 static int strcasecmp_(const char *a, const char *b)
434  __attribute__((__unused__));
435 #endif
436 
437 static int strcasecmp_(const char *a, const char *b)
438 {
439  int c = strlen(a), d = strlen(b);
440 
441  if (c > d) {
442  return strncasecmp(a, b, c);
443  }
444  return strncasecmp(a, b, d);
445 }
446 #endif
447 
448 #if defined(_WIN32) || defined(_WIN64)
449 
450 /*
451  * SQLHENV, SQLHDBC, and SQLHSTMT synchronization
452  * is done using a critical section in ENV and DBC
453  * structures.
454  */
455 
456 #define HDBC_LOCK(hdbc) \
457 { \
458  DBC *d; \
459  \
460  if ((hdbc) == SQL_NULL_HDBC) { \
461  return SQL_INVALID_HANDLE; \
462  } \
463  d = (DBC *) (hdbc); \
464  if (d->magic != DBC_MAGIC) { \
465  return SQL_INVALID_HANDLE; \
466  } \
467  EnterCriticalSection(&d->cs); \
468  d->owner = GetCurrentThreadId(); \
469 }
470 
471 #define HDBC_UNLOCK(hdbc) \
472  if ((hdbc) != SQL_NULL_HDBC) { \
473  DBC *d; \
474  \
475  d = (DBC *) (hdbc); \
476  if (d->magic == DBC_MAGIC) { \
477  d->owner = 0; \
478  LeaveCriticalSection(&d->cs); \
479  } \
480  }
481 
482 #define HSTMT_LOCK(hstmt) \
483 { \
484  DBC *d; \
485  \
486  if ((hstmt) == SQL_NULL_HSTMT) { \
487  return SQL_INVALID_HANDLE; \
488  } \
489  d = (DBC *) ((STMT *) (hstmt))->dbc; \
490  if (d->magic != DBC_MAGIC) { \
491  return SQL_INVALID_HANDLE; \
492  } \
493  EnterCriticalSection(&d->cs); \
494  d->owner = GetCurrentThreadId(); \
495 }
496 
497 #define HSTMT_UNLOCK(hstmt) \
498  if ((hstmt) != SQL_NULL_HSTMT) { \
499  DBC *d; \
500  \
501  d = (DBC *) ((STMT *) (hstmt))->dbc; \
502  if (d->magic == DBC_MAGIC) { \
503  d->owner = 0; \
504  LeaveCriticalSection(&d->cs); \
505  } \
506  }
507 
508 #else
509 
510 /*
511  * On UN*X assume that we are single-threaded or
512  * the driver manager provides serialization for us.
513  *
514  * In iODBC (3.52.x) serialization can be turned
515  * on using the DSN property "ThreadManager=yes".
516  *
517  * In unixODBC that property is named
518  * "Threading=0-3" and takes one of these values:
519  *
520  * 0 - no protection
521  * 1 - statement level protection
522  * 2 - connection level protection
523  * 3 - environment level protection
524  *
525  * unixODBC 2.2.11 uses environment level protection
526  * by default when it has been built with pthread
527  * support.
528  */
529 
530 #define HDBC_LOCK(hdbc)
531 #define HDBC_UNLOCK(hdbc)
532 #define HSTMT_LOCK(hdbc)
533 #define HSTMT_UNLOCK(hdbc)
534 
535 #endif
536 
537 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
538 extern void nvfs_init(void);
539 extern const char *nvfs_makevfs(const char *);
540 #endif
541 
542 /*
543  * tolower() replacement w/o locale
544  */
545 
546 static const char upper_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
547 static const char lower_chars[] = "abcdefghijklmnopqrstuvwxyz";
548 
549 static int
550 TOLOWER(int c)
551 {
552  if (c) {
553  char *p = strchr(upper_chars, c);
554 
555  if (p) {
556  c = lower_chars[p - upper_chars];
557  }
558  }
559  return c;
560 }
561 
562 /*
563  * isdigit() replacement w/o ctype.h
564  */
565 
566 static const char digit_chars[] = "0123456789";
567 
568 #define ISDIGIT(c) \
569  ((c) && strchr(digit_chars, (c)) != NULL)
570 
571 /*
572  * isspace() replacement w/o ctype.h
573  */
574 
575 static const char space_chars[] = " \f\n\r\t\v";
576 
577 #define ISSPACE(c) \
578  ((c) && strchr(space_chars, (c)) != NULL)
579 
580 
581 /*
582  * Forward declarations of static functions.
583  */
584 
585 static void dbtraceapi(DBC *d, char *fn, const char *sql);
586 static void freedyncols(STMT *s);
587 static void freeresult(STMT *s, int clrcols);
588 static void freerows(char **rowp);
589 static void unbindcols(STMT *s);
590 static void s3stmt_drop(STMT *s);
591 
592 static SQLRETURN drvexecute(SQLHSTMT stmt, int initial);
593 static SQLRETURN freestmt(HSTMT stmt);
594 static SQLRETURN mkbindcols(STMT *s, int ncols);
595 static SQLRETURN setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp);
596 static SQLRETURN setupparbuf(STMT *s, BINDPARM *p);
597 static SQLRETURN starttran(STMT *s);
598 static SQLRETURN setupparam(STMT *s, char *sql, int pnum);
599 static SQLRETURN getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype,
600  SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp,
601  int partial);
602 
603 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
604 /* MS Access hack part 1 (reserved error -7748) */
605 static COL *statSpec2P, *statSpec3P;
606 #endif
607 
608 #if (MEMORY_DEBUG < 1)
609 
615 static char *
616 strdup_(const char *str)
617 {
618  char *p = NULL;
619 
620  if (str) {
621  p = xmalloc(strlen(str) + 1);
622  if (p) {
623  strcpy(p, str);
624  }
625  }
626  return p;
627 }
628 #endif
629 
637 static dstr *
638 dsappend(dstr *dsp, const char *str)
639 {
640  int len;
641 
642  if (!str) {
643  return dsp;
644  }
645  len = strlen(str);
646  if (!dsp) {
647  int max = 256;
648 
649  if (max < len) {
650  max += len;
651  }
652  dsp = xmalloc(max);
653  if (dsp) {
654  dsp->max = max;
655  dsp->len = dsp->oom = 0;
656  goto copy;
657  }
658  return dsp;
659  }
660  if (dsp->oom) {
661  return dsp;
662  }
663  if (dsp->len + len > dsp->max) {
664  int max = dsp->max + len + 256;
665  dstr *ndsp = xrealloc(dsp, max);
666 
667  if (!ndsp) {
668  strcpy(dsp->buffer, "OUT OF MEMORY");
669  dsp->max = dsp->len = 13;
670  dsp->oom = 1;
671  return dsp;
672  }
673  dsp = ndsp;
674  dsp->max = max;
675  }
676 copy:
677  strcpy(dsp->buffer + dsp->len, str);
678  dsp->len += len;
679  return dsp;
680 }
681 
689 static dstr *
690 dsappendq(dstr *dsp, const char *str)
691 {
692  int len;
693  const char *p;
694  char *q;
695 
696  if (!str) {
697  return dsp;
698  }
699  len = strlen(str);
700  for (p = str; *p; ++p) {
701  if (p[0] == '"') {
702  ++len;
703  }
704  }
705  if (!dsp) {
706  int max = 256;
707 
708  if (max < len) {
709  max += len;
710  }
711  dsp = xmalloc(max);
712  if (dsp) {
713  dsp->max = max;
714  dsp->len = dsp->oom = 0;
715  goto copy;
716  }
717  return dsp;
718  }
719  if (dsp->oom) {
720  return dsp;
721  }
722  if (dsp->len + len > dsp->max) {
723  int max = dsp->max + len + 256;
724  dstr *ndsp = xrealloc(dsp, max);
725 
726  if (!ndsp) {
727  strcpy(dsp->buffer, "OUT OF MEMORY");
728  dsp->max = dsp->len = 13;
729  dsp->oom = 1;
730  return dsp;
731  }
732  dsp = ndsp;
733  dsp->max = max;
734  }
735 copy:
736  for (p = str, q = dsp->buffer + dsp->len; *p; ++p) {
737  *q++ = *p;
738  if (p[0] == '"') {
739  *q++ = '"';
740  }
741  }
742  *q = '\0';
743  dsp->len += len;
744  return dsp;
745 }
746 
753 static const char *
754 dsval(dstr *dsp)
755 {
756  if (dsp) {
757  return (const char *) dsp->buffer;
758  }
759  return "ERROR";
760 }
761 
768 static int
769 dserr(dstr *dsp)
770 {
771  return !dsp || dsp->oom;
772 }
773 
779 static void
781 {
782  if (dsp) {
783  xfree(dsp);
784  }
785 }
786 
787 #ifdef WCHARSUPPORT
788 
795 static int
796 uc_strlen(SQLWCHAR *str)
797 {
798  int len = 0;
799 
800  if (str) {
801  while (*str) {
802  ++len;
803  ++str;
804  }
805  }
806  return len;
807 }
808 
817 static SQLWCHAR *
818 uc_strncpy(SQLWCHAR *dest, SQLWCHAR *src, int len)
819 {
820  int i = 0;
821 
822  while (i < len) {
823  if (!src[i]) {
824  break;
825  }
826  dest[i] = src[i];
827  ++i;
828  }
829  if (i < len) {
830  dest[i] = 0;
831  }
832  return dest;
833 }
834 
843 static void
844 uc_from_utf_buf(unsigned char *str, int len, SQLWCHAR *uc, int ucLen)
845 {
846  ucLen = ucLen / sizeof (SQLWCHAR);
847  if (!uc || ucLen < 0) {
848  return;
849  }
850  if (len < 0) {
851  len = ucLen * 5;
852  }
853  uc[0] = 0;
854  if (str) {
855  int i = 0;
856 
857  while (i < len && *str && i < ucLen) {
858  unsigned char c = str[0];
859 
860  if (c < 0x80) {
861  uc[i++] = c;
862  ++str;
863  } else if (c <= 0xc1 || c >= 0xf5) {
864  /* illegal, ignored */
865  ++str;
866  } else if (c < 0xe0) {
867  if ((str[1] & 0xc0) == 0x80) {
868  unsigned long t = ((c & 0x1f) << 6) | (str[1] & 0x3f);
869 
870  uc[i++] = t;
871  str += 2;
872  } else {
873  uc[i++] = c;
874  ++str;
875  }
876  } else if (c < 0xf0) {
877  if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80) {
878  unsigned long t = ((c & 0x0f) << 12) |
879  ((str[1] & 0x3f) << 6) | (str[2] & 0x3f);
880 
881  uc[i++] = t;
882  str += 3;
883  } else {
884  uc[i++] = c;
885  ++str;
886  }
887  } else if (c < 0xf8) {
888  if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 &&
889  (str[3] & 0xc0) == 0x80) {
890  unsigned long t = ((c & 0x03) << 18) |
891  ((str[1] & 0x3f) << 12) | ((str[2] & 0x3f) << 6) |
892  (str[3] & 0x3f);
893 
894  if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
895  t >= 0x10000) {
896  t -= 0x10000;
897  uc[i++] = 0xd800 | ((t >> 10) & 0x3ff);
898  if (i >= ucLen) {
899  break;
900  }
901  t = 0xdc00 | (t & 0x3ff);
902  }
903  uc[i++] = t;
904  str += 4;
905  } else {
906  uc[i++] = c;
907  ++str;
908  }
909  } else if (c < 0xfc) {
910  if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 &&
911  (str[3] & 0xc0) == 0x80 && (str[4] & 0xc0) == 0x80) {
912  unsigned long t = ((c & 0x01) << 24) |
913  ((str[1] & 0x3f) << 18) | ((str[2] & 0x3f) << 12) |
914  ((str[3] & 0x3f) << 6) | (str[4] & 0x3f);
915 
916  if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
917  t >= 0x10000) {
918  t -= 0x10000;
919  uc[i++] = 0xd800 | ((t >> 10) & 0x3ff);
920  if (i >= ucLen) {
921  break;
922  }
923  t = 0xdc00 | (t & 0x3ff);
924  }
925  uc[i++] = t;
926  str += 5;
927  } else {
928  uc[i++] = c;
929  ++str;
930  }
931  } else {
932  /* ignore */
933  ++str;
934  }
935  }
936  if (i < ucLen) {
937  uc[i] = 0;
938  }
939  }
940 }
941 
949 static SQLWCHAR *
950 uc_from_utf(unsigned char *str, int len)
951 {
952  SQLWCHAR *uc = NULL;
953  int ucLen;
954 
955  if (str) {
956  if (len == SQL_NTS) {
957  len = strlen((char *) str);
958  }
959  ucLen = sizeof (SQLWCHAR) * (len + 1);
960  uc = xmalloc(ucLen);
961  if (uc) {
962  uc_from_utf_buf(str, len, uc, ucLen);
963  }
964  }
965  return uc;
966 }
967 
975 static char *
976 uc_to_utf(SQLWCHAR *str, int len)
977 {
978  int i;
979  char *cp, *ret = NULL;
980 
981  if (!str) {
982  return ret;
983  }
984  if (len == SQL_NTS) {
985  len = uc_strlen(str);
986  } else {
987  len = len / sizeof (SQLWCHAR);
988  }
989  cp = xmalloc(len * 6 + 1);
990  if (!cp) {
991  return ret;
992  }
993  ret = cp;
994  for (i = 0; i < len; i++) {
995  unsigned long c = str[i];
996 
997  if (sizeof (SQLWCHAR) == 2 * sizeof (char)) {
998  c &= 0xffff;
999  }
1000  if (c < 0x80) {
1001  *cp++ = c;
1002  } else if (c < 0x800) {
1003  *cp++ = 0xc0 | ((c >> 6) & 0x1f);
1004  *cp++ = 0x80 | (c & 0x3f);
1005  } else if (c < 0x10000) {
1006  if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
1007  c >= 0xd800 && c <= 0xdbff && i + 1 < len) {
1008  unsigned long c2 = str[i + 1] & 0xffff;
1009 
1010  if (c2 >= 0xdc00 && c2 <= 0xdfff) {
1011  c = (((c & 0x3ff) << 10) | (c2 & 0x3ff)) + 0x10000;
1012  *cp++ = 0xf0 | ((c >> 18) & 0x07);
1013  *cp++ = 0x80 | ((c >> 12) & 0x3f);
1014  *cp++ = 0x80 | ((c >> 6) & 0x3f);
1015  *cp++ = 0x80 | (c & 0x3f);
1016  ++i;
1017  continue;
1018  }
1019  }
1020  *cp++ = 0xe0 | ((c >> 12) & 0x0f);
1021  *cp++ = 0x80 | ((c >> 6) & 0x3f);
1022  *cp++ = 0x80 | (c & 0x3f);
1023  } else if (c < 0x200000) {
1024  *cp++ = 0xf0 | ((c >> 18) & 0x07);
1025  *cp++ = 0x80 | ((c >> 12) & 0x3f);
1026  *cp++ = 0x80 | ((c >> 6) & 0x3f);
1027  *cp++ = 0x80 | (c & 0x3f);
1028  } else if (c < 0x4000000) {
1029  *cp++ = 0xf8 | ((c >> 24) & 0x03);
1030  *cp++ = 0x80 | ((c >> 18) & 0x3f);
1031  *cp++ = 0x80 | ((c >> 12) & 0x3f);
1032  *cp++ = 0x80 | ((c >> 6) & 0x3f);
1033  *cp++ = 0x80 | (c & 0x3f);
1034  } else if (c < 0x80000000) {
1035  *cp++ = 0xfc | ((c >> 31) & 0x01);
1036  *cp++ = 0x80 | ((c >> 24) & 0x3f);
1037  *cp++ = 0x80 | ((c >> 18) & 0x3f);
1038  *cp++ = 0x80 | ((c >> 12) & 0x3f);
1039  *cp++ = 0x80 | ((c >> 6) & 0x3f);
1040  *cp++ = 0x80 | (c & 0x3f);
1041  }
1042  }
1043  *cp = '\0';
1044  return ret;
1045 }
1046 
1047 #endif
1048 
1049 #ifdef WINTERFACE
1050 
1058 static char *
1059 uc_to_utf_c(SQLWCHAR *str, int len)
1060 {
1061  if (len != SQL_NTS) {
1062  len = len * sizeof (SQLWCHAR);
1063  }
1064  return uc_to_utf(str, len);
1065 }
1066 
1067 #endif
1068 
1069 #if defined(WCHARSUPPORT) || defined(_WIN32) || defined(_WIN64)
1070 
1076 static void
1077 uc_free(void *str)
1078 {
1079  if (str) {
1080  xfree(str);
1081  }
1082 }
1083 
1084 #endif
1085 
1086 #if defined(_WIN32) || defined(_WIN64)
1087 
1095 static char *
1096 wmb_to_utf(char *str, int len)
1097 {
1098  WCHAR *wstr;
1099  OSVERSIONINFO ovi;
1100  int nchar, is2k, cp = CP_OEMCP;
1101 
1102  ovi.dwOSVersionInfoSize = sizeof (ovi);
1103  GetVersionEx(&ovi);
1104  is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1105  if (AreFileApisANSI()) {
1106  cp = is2k ? CP_THREAD_ACP : CP_ACP;
1107  }
1108  nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
1109  wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
1110  if (!wstr) {
1111  return NULL;
1112  }
1113  wstr[0] = 0;
1114  nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
1115  wstr[nchar] = 0;
1116  str = xmalloc((nchar + 1) * 7);
1117  if (!str) {
1118  xfree(wstr);
1119  return NULL;
1120  }
1121  str[0] = '\0';
1122  nchar = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, nchar * 7, 0, 0);
1123  str[nchar] = '\0';
1124  xfree(wstr);
1125  return str;
1126 }
1127 
1128 #ifndef WINTERFACE
1129 
1137 static char *
1138 wmb_to_utf_c(char *str, int len)
1139 {
1140  if (len == SQL_NTS) {
1141  len = strlen(str);
1142  }
1143  return wmb_to_utf(str, len);
1144 }
1145 
1146 #endif
1147 
1155 static char *
1156 utf_to_wmb(char *str, int len)
1157 {
1158  WCHAR *wstr;
1159  OSVERSIONINFO ovi;
1160  int nchar, is2k, cp = CP_OEMCP;
1161 
1162  ovi.dwOSVersionInfoSize = sizeof (ovi);
1163  GetVersionEx(&ovi);
1164  is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1165  if (AreFileApisANSI()) {
1166  cp = is2k ? CP_THREAD_ACP : CP_ACP;
1167  }
1168  nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
1169  wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
1170  if (!wstr) {
1171  return NULL;
1172  }
1173  wstr[0] = 0;
1174  nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, wstr, nchar);
1175  wstr[nchar] = 0;
1176  str = xmalloc((nchar + 1) * 7);
1177  if (!str) {
1178  xfree(wstr);
1179  return NULL;
1180  }
1181  str[0] = '\0';
1182  nchar = WideCharToMultiByte(cp, 0, wstr, -1, str, nchar * 7, 0, 0);
1183  str[nchar] = '\0';
1184  xfree(wstr);
1185  return str;
1186 }
1187 
1188 #ifdef WINTERFACE
1189 
1197 static WCHAR *
1198 wmb_to_uc(char *str, int len)
1199 {
1200  WCHAR *wstr;
1201  OSVERSIONINFO ovi;
1202  int nchar, is2k, cp = CP_OEMCP;
1203 
1204  ovi.dwOSVersionInfoSize = sizeof (ovi);
1205  GetVersionEx(&ovi);
1206  is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1207  if (AreFileApisANSI()) {
1208  cp = is2k ? CP_THREAD_ACP : CP_ACP;
1209  }
1210  nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
1211  wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
1212  if (!wstr) {
1213  return NULL;
1214  }
1215  wstr[0] = 0;
1216  nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
1217  wstr[nchar] = 0;
1218  return wstr;
1219 }
1220 
1228 static char *
1229 uc_to_wmb(WCHAR *wstr, int len)
1230 {
1231  char *str;
1232  OSVERSIONINFO ovi;
1233  int nchar, is2k, cp = CP_OEMCP;
1234 
1235  ovi.dwOSVersionInfoSize = sizeof (ovi);
1236  GetVersionEx(&ovi);
1237  is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
1238  if (AreFileApisANSI()) {
1239  cp = is2k ? CP_THREAD_ACP : CP_ACP;
1240  }
1241  nchar = WideCharToMultiByte(cp, 0, wstr, len, NULL, 0, 0, 0);
1242  str = xmalloc((nchar + 1) * 2);
1243  if (!str) {
1244  return NULL;
1245  }
1246  str[0] = '\0';
1247  nchar = WideCharToMultiByte(cp, 0, wstr, len, str, nchar * 2, 0, 0);
1248  str[nchar] = '\0';
1249  return str;
1250 }
1251 
1252 #endif /* WINTERFACE */
1253 
1254 #endif /* _WIN32 || _WIN64 */
1255 
1256 
1257 #ifdef USE_DLOPEN_FOR_GPPS
1258 
1259 #include <dlfcn.h>
1260 
1261 #define SQLGetPrivateProfileString(A,B,C,D,E,F) drvgpps(d,A,B,C,D,E,F)
1262 
1263 /*
1264  * EXPERIMENTAL: SQLGetPrivateProfileString infrastructure using
1265  * dlopen(), in theory this makes the driver independent from the
1266  * driver manager, i.e. the same driver binary can run with iODBC
1267  * and unixODBC.
1268  */
1269 
1270 static void
1271 drvgetgpps(DBC *d)
1272 {
1273  void *lib;
1274  int (*gpps)();
1275 
1276  lib = dlopen("libodbcinst.so.2", RTLD_LAZY);
1277  if (!lib) {
1278  lib = dlopen("libodbcinst.so.1", RTLD_LAZY);
1279  }
1280  if (!lib) {
1281  lib = dlopen("libodbcinst.so", RTLD_LAZY);
1282  }
1283  if (!lib) {
1284  lib = dlopen("libiodbcinst.so.2", RTLD_LAZY);
1285  }
1286  if (!lib) {
1287  lib = dlopen("libiodbcinst.so", RTLD_LAZY);
1288  }
1289  if (lib) {
1290  gpps = (int (*)()) dlsym(lib, "SQLGetPrivateProfileString");
1291  if (!gpps) {
1292  dlclose(lib);
1293  return;
1294  }
1295  d->instlib = lib;
1296  d->gpps = gpps;
1297  }
1298 }
1299 
1300 static void
1301 drvrelgpps(DBC *d)
1302 {
1303  if (d->instlib) {
1304  dlclose(d->instlib);
1305  d->instlib = 0;
1306  }
1307 }
1308 
1309 static int
1310 drvgpps(DBC *d, char *sect, char *ent, char *def, char *buf,
1311  int bufsiz, char *fname)
1312 {
1313  if (d->gpps) {
1314  return d->gpps(sect, ent, def, buf, bufsiz, fname);
1315  }
1316  strncpy(buf, def, bufsiz);
1317  buf[bufsiz - 1] = '\0';
1318  return 1;
1319 }
1320 #else
1321 #include <odbcinst.h>
1322 #define drvgetgpps(d)
1323 #define drvrelgpps(d)
1324 #endif
1325 
1326 /*
1327  * Internal function to bind SQLite3 parameters.
1328  */
1329 
1330 static void
1331 s3bind(DBC *d, sqlite3_stmt *stmt, int nparams, BINDPARM *p)
1332 {
1333  int i;
1334 
1335  if (stmt && p && nparams > 0) {
1336  for (i = 0; i < nparams; i++, p++) {
1337  switch (p->s3type) {
1338  default:
1339  case SQLITE_NULL:
1340  sqlite3_bind_null(stmt, i + 1);
1341  if (d->trace) {
1342  fprintf(d->trace, "-- parameter %d: NULL\n", i + 1);
1343  fflush(d->trace);
1344  }
1345  break;
1346  case SQLITE_TEXT:
1347  sqlite3_bind_text(stmt, i + 1, p->s3val, p->s3size,
1348  SQLITE_STATIC);
1349  if (d->trace) {
1350  fprintf(d->trace, "-- parameter %d: '%*s'\n", i + 1,
1351  p->s3size, (char *) p->s3val);
1352  fflush(d->trace);
1353  }
1354  break;
1355  case SQLITE_BLOB:
1356  sqlite3_bind_blob(stmt, i + 1, p->s3val, p->s3size,
1357  SQLITE_STATIC);
1358  if (d->trace) {
1359  fprintf(d->trace, "-- parameter %d: [BLOB]'\n", i + 1);
1360  fflush(d->trace);
1361  }
1362  break;
1363  case SQLITE_FLOAT:
1364  sqlite3_bind_double(stmt, i + 1, p->s3dval);
1365  if (d->trace) {
1366  fprintf(d->trace, "-- parameter %d: %g\n",
1367  i + 1, p->s3dval);
1368  fflush(d->trace);
1369  }
1370  break;
1371  case SQLITE_INTEGER:
1372  if (p->s3size > sizeof (int)) {
1373  sqlite3_bind_int64(stmt, i + 1, p->s3lival);
1374  if (d->trace) {
1375  fprintf(d->trace,
1376 #ifdef _WIN32
1377  "-- parameter %d: %I64d\n",
1378 #else
1379  "-- parameter %d: %lld\n",
1380 #endif
1381  i + 1, p->s3lival);
1382  fflush(d->trace);
1383  }
1384  } else {
1385  sqlite3_bind_int(stmt, i + 1, p->s3ival);
1386  if (d->trace) {
1387  fprintf(d->trace, "-- parameter %d: %d\n",
1388  i + 1, p->s3ival);
1389  fflush(d->trace);
1390  }
1391  }
1392  break;
1393  }
1394  }
1395  }
1396 }
1397 
1405 typedef struct tblres {
1406  char **resarr;
1407  char *errmsg;
1408  sqlite3_stmt *stmt;
1409  STMT *s;
1410  int nalloc;
1411  int nrow;
1412  int ncol;
1414  int rc;
1415 } TBLRES;
1416 
1417 /*
1418  * Driver's version of sqlite3_get_table() and friends which are
1419  * capable of dealing with blobs.
1420  */
1421 
1422 static int
1423 drvgettable_row(TBLRES *t, int ncol, int rc)
1424 {
1425  int need;
1426  int i;
1427  char *p;
1428 
1429  if (t->nrow == 0 && rc == SQLITE_ROW) {
1430  need = ncol * 2;
1431  } else {
1432  need = ncol;
1433  }
1434  if (t->ndata + need >= t->nalloc) {
1435  char **resnew;
1436  int nalloc = t->nalloc * 2 + need + 1;
1437 
1438  resnew = xrealloc(t->resarr, sizeof (char *) * nalloc);
1439  if (!resnew) {
1440 nomem:
1441  t->rc = SQLITE_NOMEM;
1442  return 1;
1443  }
1444  t->nalloc = nalloc;
1445  t->resarr = resnew;
1446  }
1447  /* column names when first row */
1448  if (t->nrow == 0) {
1449  t->ncol = ncol;
1450  for (i = 0; i < ncol; i++) {
1451  p = (char *) sqlite3_column_name(t->stmt, i);
1452  if (p) {
1453  char *q = xmalloc(strlen(p) + 1);
1454 
1455  if (!q) {
1456  goto nomem;
1457  }
1458  strcpy(q, p);
1459  p = q;
1460  }
1461  t->resarr[t->ndata++] = p;
1462  }
1463  if (t->s && t->s->guessed_types) {
1464  int ncol2 = ncol;
1465 
1466  setupdyncols(t->s, t->stmt, &ncol2);
1467  t->s->guessed_types = 0;
1468  t->s->ncols = ncol;
1469  }
1470  } else if (t->ncol != ncol) {
1471  t->errmsg = sqlite3_mprintf("drvgettable() called with two or"
1472  " more incompatible queries");
1473  t->rc = SQLITE_ERROR;
1474  return 1;
1475  }
1476  /* copy row data */
1477  if (rc == SQLITE_ROW) {
1478  for (i = 0; i < ncol; i++) {
1479  int coltype = sqlite3_column_type(t->stmt, i);
1480 
1481  p = NULL;
1482  if (coltype == SQLITE_BLOB) {
1483  int k, nbytes = sqlite3_column_bytes(t->stmt, i);
1484  char *qp;
1485  unsigned const char *bp;
1486 
1487  bp = sqlite3_column_blob(t->stmt, i);
1488  qp = xmalloc(nbytes * 2 + 4);
1489  if (!qp) {
1490  goto nomem;
1491  }
1492  p = qp;
1493  *qp++ = 'X';
1494  *qp++ = '\'';
1495  for (k = 0; k < nbytes; k++) {
1496  *qp++ = xdigits[(bp[k] >> 4)];
1497  *qp++ = xdigits[(bp[k] & 0xF)];
1498  }
1499  *qp++ = '\'';
1500  *qp = '\0';
1501 #ifdef _MSC_VER
1502  } else if (coltype == SQLITE_FLOAT) {
1503  static struct lconv *lc = 0;
1504  double val = sqlite3_column_double(t->stmt, i);
1505  char buffer[128];
1506 
1507  /*
1508  * This avoids floating point rounding
1509  * and formatting problems of some SQLite
1510  * versions in conjunction with MSVC 2010.
1511  */
1512  snprintf(buffer, sizeof (buffer), "%.15g", val);
1513  if (!lc) {
1514  lc = localeconv();
1515  }
1516  if (lc && lc->decimal_point && lc->decimal_point[0] &&
1517  lc->decimal_point[0] != '.') {
1518  p = strchr(buffer, lc->decimal_point[0]);
1519  if (p) {
1520  *p = '.';
1521  }
1522  }
1523  p = xstrdup(buffer);
1524  if (!p) {
1525  goto nomem;
1526  }
1527 #endif
1528  } else if (coltype != SQLITE_NULL) {
1529  p = xstrdup((char *) sqlite3_column_text(t->stmt, i));
1530  if (!p) {
1531  goto nomem;
1532  }
1533  }
1534  t->resarr[t->ndata++] = p;
1535  }
1536  t->nrow++;
1537  }
1538  return 0;
1539 }
1540 
1541 static int
1542 drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp,
1543  int *ncolp, char **errp, int nparam, BINDPARM *p)
1544 {
1545  DBC *d = (DBC *) s->dbc;
1546  int rc = SQLITE_OK, keep = sql == NULL;
1547  TBLRES tres;
1548  const char *sqlleft = 0;
1549  int nretry = 0, haveerr = 0;
1550 
1551  if (!resp) {
1552  return SQLITE_ERROR;
1553  }
1554  *resp = NULL;
1555  if (nrowp) {
1556  *nrowp = 0;
1557  }
1558  if (ncolp) {
1559  *ncolp = 0;
1560  }
1561  tres.errmsg = NULL;
1562  tres.nrow = 0;
1563  tres.ncol = 0;
1564  tres.ndata = 1;
1565  tres.nalloc = 20;
1566  tres.rc = SQLITE_OK;
1567  tres.resarr = xmalloc(sizeof (char *) * tres.nalloc);
1568  tres.stmt = NULL;
1569  tres.s = s;
1570  if (!tres.resarr) {
1571  return SQLITE_NOMEM;
1572  }
1573  tres.resarr[0] = 0;
1574  if (sql == NULL) {
1575  tres.stmt = s->s3stmt;
1576  if (tres.stmt == NULL) {
1577  return SQLITE_NOMEM;
1578  }
1579  goto retrieve;
1580  }
1581  while (sql && *sql && (rc == SQLITE_OK ||
1582  (rc == SQLITE_SCHEMA && (++nretry) < 2))) {
1583  int ncol;
1584 
1585  tres.stmt = NULL;
1586 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
1587  dbtraceapi(d, "sqlite3_prepare_v2", sql);
1588  rc = sqlite3_prepare_v2(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
1589 #else
1590  dbtraceapi(d, "sqlite3_prepare", sql);
1591  rc = sqlite3_prepare(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
1592 #endif
1593  if (rc != SQLITE_OK) {
1594  if (tres.stmt) {
1595  dbtraceapi(d, "sqlite3_finalize", 0);
1596  sqlite3_finalize(tres.stmt);
1597  tres.stmt = NULL;
1598  }
1599  continue;
1600  }
1601  if (!tres.stmt) {
1602  /* this happens for a comment or white-space */
1603  sql = sqlleft;
1604  continue;
1605  }
1606 retrieve:
1607  if (sqlite3_bind_parameter_count(tres.stmt) != nparam) {
1608  if (errp) {
1609  *errp =
1610  sqlite3_mprintf("%s", "parameter marker count incorrect");
1611  }
1612  haveerr = 1;
1613  rc = SQLITE_ERROR;
1614  goto tbldone;
1615  }
1616  s3bind(d, tres.stmt, nparam, p);
1617  ncol = sqlite3_column_count(tres.stmt);
1618  while (1) {
1619  if (s->max_rows && tres.nrow >= s->max_rows) {
1620  rc = SQLITE_OK;
1621  break;
1622  }
1623  rc = sqlite3_step(tres.stmt);
1624  if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
1625  if (drvgettable_row(&tres, ncol, rc)) {
1626  rc = SQLITE_ABORT;
1627  goto tbldone;
1628  }
1629  }
1630  if (rc != SQLITE_ROW) {
1631  if (keep) {
1632  dbtraceapi(d, "sqlite3_reset", 0);
1633  rc = sqlite3_reset(tres.stmt);
1634  s->s3stmt_noreset = 1;
1635  } else {
1636  dbtraceapi(d, "sqlite3_finalize", 0);
1637  rc = sqlite3_finalize(tres.stmt);
1638  }
1639  tres.stmt = 0;
1640  if (rc != SQLITE_SCHEMA) {
1641  nretry = 0;
1642  sql = sqlleft;
1643  while (sql && ISSPACE(*sql)) {
1644  sql++;
1645  }
1646  }
1647  if (rc == SQLITE_DONE) {
1648  rc = SQLITE_OK;
1649  }
1650  break;
1651  }
1652  }
1653  }
1654 tbldone:
1655  if (tres.stmt) {
1656  if (keep) {
1657  if (!s->s3stmt_noreset) {
1658  dbtraceapi(d, "sqlite3_reset", 0);
1659  sqlite3_reset(tres.stmt);
1660  s->s3stmt_noreset = 1;
1661  }
1662  } else {
1663  dbtraceapi(d, "sqlite3_finalize", 0);
1664  sqlite3_finalize(tres.stmt);
1665  }
1666  }
1667  if (haveerr) {
1668  /* message already in *errp if any */
1669  } else if (rc != SQLITE_OK && rc == sqlite3_errcode(d->sqlite) && errp) {
1670  *errp = sqlite3_mprintf("%s", sqlite3_errmsg(d->sqlite));
1671  } else if (errp) {
1672  *errp = NULL;
1673  }
1674  if (tres.resarr) {
1675  tres.resarr[0] = (char *) (tres.ndata - 1);
1676  }
1677  if (rc == SQLITE_ABORT) {
1678  freerows(&tres.resarr[1]);
1679  if (tres.errmsg) {
1680  if (errp) {
1681  if (*errp) {
1682  sqlite3_free(*errp);
1683  }
1684  *errp = tres.errmsg;
1685  } else {
1686  sqlite3_free(tres.errmsg);
1687  }
1688  }
1689  return tres.rc;
1690  }
1691  sqlite3_free(tres.errmsg);
1692  if (rc != SQLITE_OK) {
1693  freerows(&tres.resarr[1]);
1694  return rc;
1695  }
1696  *resp = &tres.resarr[1];
1697  if (ncolp) {
1698  *ncolp = tres.ncol;
1699  }
1700  if (nrowp) {
1701  *nrowp = tres.nrow;
1702  }
1703  return rc;
1704 }
1705 
1714 #if defined(__GNUC__) && (__GNUC__ >= 2)
1715 static void setstatd(DBC *, int, char *, char *, ...)
1716  __attribute__((format (printf, 3, 5)));
1717 #endif
1718 
1719 static void
1720 setstatd(DBC *d, int naterr, char *msg, char *st, ...)
1721 {
1722  va_list ap;
1723 
1724  if (!d) {
1725  return;
1726  }
1727  d->naterr = naterr;
1728  d->logmsg[0] = '\0';
1729  if (msg) {
1730  int count;
1731 
1732  va_start(ap, st);
1733  count = vsnprintf((char *) d->logmsg, sizeof (d->logmsg), msg, ap);
1734  va_end(ap);
1735  if (count < 0) {
1736  d->logmsg[sizeof (d->logmsg) - 1] = '\0';
1737  }
1738  }
1739  if (!st) {
1740  st = "?????";
1741  }
1742  strncpy(d->sqlstate, st, 5);
1743  d->sqlstate[5] = '\0';
1744 }
1745 
1754 #if defined(__GNUC__) && (__GNUC__ >= 2)
1755 static void setstat(STMT *, int, char *, char *, ...)
1756  __attribute__((format (printf, 3, 5)));
1757 #endif
1758 
1759 static void
1760 setstat(STMT *s, int naterr, char *msg, char *st, ...)
1761 {
1762  va_list ap;
1763 
1764  if (!s) {
1765  return;
1766  }
1767  s->naterr = naterr;
1768  s->logmsg[0] = '\0';
1769  if (msg) {
1770  int count;
1771 
1772  va_start(ap, st);
1773  count = vsnprintf((char *) s->logmsg, sizeof (s->logmsg), msg, ap);
1774  va_end(ap);
1775  if (count < 0) {
1776  s->logmsg[sizeof (s->logmsg) - 1] = '\0';
1777  }
1778  }
1779  if (!st) {
1780  st = "?????";
1781  }
1782  strncpy(s->sqlstate, st, 5);
1783  s->sqlstate[5] = '\0';
1784 }
1785 
1792 static SQLRETURN
1794 {
1795  DBC *d;
1796 
1797  if (dbc == SQL_NULL_HDBC) {
1798  return SQL_INVALID_HANDLE;
1799  }
1800  d = (DBC *) dbc;
1801  setstatd(d, -1, "not supported", "IM001");
1802  return SQL_ERROR;
1803 }
1804 
1811 static SQLRETURN
1813 {
1814  STMT *s;
1815 
1816  if (stmt == SQL_NULL_HSTMT) {
1817  return SQL_INVALID_HANDLE;
1818  }
1819  s = (STMT *) stmt;
1820  setstat(s, -1, "not supported", "IM001");
1821  return SQL_ERROR;
1822 }
1823 
1829 static void
1830 freep(void *x)
1831 {
1832  if (x && ((char **) x)[0]) {
1833  xfree(((char **) x)[0]);
1834  ((char **) x)[0] = NULL;
1835  }
1836 }
1837 
1844 static SQLRETURN
1846 {
1847  setstat(s, -1, "out of memory", (*s->ov3) ? "HY000" : "S1000");
1848  return SQL_ERROR;
1849 }
1850 
1857 static SQLRETURN
1859 {
1860  setstat(s, -1, "not connected", (*s->ov3) ? "HY000" : "S1000");
1861  return SQL_ERROR;
1862 }
1863 
1871 #if defined(HAVE_LOCALECONV) || defined(_WIN32) || defined(_WIN64)
1872 
1873 static double
1874 ln_strtod(const char *data, char **endp)
1875 {
1876  static struct lconv *lc = 0;
1877  char buf[128], *p, *end;
1878  double value;
1879 
1880  if (!lc) {
1881  lc = localeconv();
1882  }
1883  if (lc && lc->decimal_point && lc->decimal_point[0] &&
1884  lc->decimal_point[0] != '.') {
1885  strncpy(buf, data, sizeof (buf) - 1);
1886  buf[sizeof (buf) - 1] = '\0';
1887  p = strchr(buf, '.');
1888  if (p) {
1889  *p = lc->decimal_point[0];
1890  }
1891  p = buf;
1892  } else {
1893  p = (char *) data;
1894  }
1895  value = strtod(p, &end);
1896  end = (char *) data + (end - p);
1897  if (endp) {
1898  *endp = end;
1899  }
1900  return value;
1901 }
1902 
1903 #else
1904 
1905 #define ln_strtod(A,B) strtod(A,B)
1906 
1907 #endif
1908 
1914 static char *
1915 unquote(char *str)
1916 {
1917  if (str) {
1918  int len = strlen(str);
1919 
1920  if (len > 1) {
1921  int end = len - 1;
1922 
1923  if ((str[0] == '\'' && str[end] == '\'') ||
1924  (str[0] == '"' && str[end] == '"') ||
1925  (str[0] == '[' && str[end] == ']')) {
1926  memmove(str, str + 1, end - 1);
1927  str[end - 1] = '\0';
1928  }
1929  }
1930  }
1931  return str;
1932 }
1933 
1941 static int
1942 unescpat(char *str)
1943 {
1944  char *p, *q;
1945  int count = 0;
1946 
1947  p = str;
1948  while ((q = strchr(p, '_')) != NULL) {
1949  if (q == str || q[-1] != '\\') {
1950  count++;
1951  }
1952  p = q + 1;
1953  }
1954  p = str;
1955  while ((q = strchr(p, '%')) != NULL) {
1956  if (q == str || q[-1] != '\\') {
1957  count++;
1958  }
1959  p = q + 1;
1960  }
1961  p = str;
1962  while ((q = strchr(p, '\\')) != NULL) {
1963  if (q[1] == '\\' || q[1] == '_' || q[1] == '%') {
1964  memmove(q, q + 1, strlen(q));
1965  }
1966  p = q + 1;
1967  }
1968  return count;
1969 }
1970 
1979 static int
1980 namematch(char *str, char *pat, int esc)
1981 {
1982  int cp, ch;
1983 
1984  while (1) {
1985  cp = TOLOWER(*pat);
1986  if (cp == '\0') {
1987  if (*str != '\0') {
1988  goto nomatch;
1989  }
1990  break;
1991  }
1992  if (*str == '\0' && cp != '%') {
1993  goto nomatch;
1994  }
1995  if (cp == '%') {
1996  while (*pat == '%') {
1997  ++pat;
1998  }
1999  cp = TOLOWER(*pat);
2000  if (cp == '\0') {
2001  break;
2002  }
2003  while (1) {
2004  if (cp != '_' && cp != '\\') {
2005  while (*str) {
2006  ch = TOLOWER(*str);
2007  if (ch == cp) {
2008  break;
2009  }
2010  ++str;
2011  }
2012  }
2013  if (namematch(str, pat, esc)) {
2014  goto match;
2015  }
2016  if (*str == '\0') {
2017  goto nomatch;
2018  }
2019  ch = TOLOWER(*str);
2020  ++str;
2021  }
2022  }
2023  if (cp == '_') {
2024  pat++;
2025  str++;
2026  continue;
2027  }
2028  if (esc && cp == '\\' &&
2029  (pat[1] == '\\' || pat[1] == '%' || pat[1] == '_')) {
2030  ++pat;
2031  cp = TOLOWER(*pat);
2032  }
2033  ch = TOLOWER(*str++);
2034  ++pat;
2035  if (ch != cp) {
2036  goto nomatch;
2037  }
2038  }
2039 match:
2040  return 1;
2041 nomatch:
2042  return 0;
2043 }
2044 
2052 static int
2053 busy_handler(void *udata, int count)
2054 {
2055  DBC *d = (DBC *) udata;
2056  long t1;
2057  int ret = 0;
2058 #if !defined(_WIN32) && !defined(_WIN64)
2059  struct timeval tv;
2060 #ifdef HAVE_NANOSLEEP
2061  struct timespec ts;
2062 #endif
2063 #endif
2064 
2065  if (d->busyint) {
2066  d->busyint = 0;
2067  return ret;
2068  }
2069  if (d->timeout <= 0) {
2070  return ret;
2071  }
2072  if (count <= 1) {
2073 #if defined(_WIN32) || defined(_WIN64)
2074  d->t0 = GetTickCount();
2075 #else
2076  gettimeofday(&tv, NULL);
2077  d->t0 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
2078 #endif
2079  }
2080 #if defined(_WIN32) || defined(_WIN64)
2081  t1 = GetTickCount();
2082 #else
2083  gettimeofday(&tv, NULL);
2084  t1 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
2085 #endif
2086  if (t1 - d->t0 > d->timeout) {
2087  goto done;
2088  }
2089 #if defined(_WIN32) || defined(_WIN64)
2090  Sleep(10);
2091 #else
2092 #ifdef HAVE_NANOSLEEP
2093  ts.tv_sec = 0;
2094  ts.tv_nsec = 10000000;
2095  do {
2096  ret = nanosleep(&ts, &ts);
2097  if (ret < 0 && errno != EINTR) {
2098  ret = 0;
2099  }
2100  } while (ret);
2101 #else
2102 #ifdef HAVE_USLEEP
2103  usleep(10000);
2104 #else
2105  tv.tv_sec = 0;
2106  tv.tv_usec = 10000;
2107  select(0, NULL, NULL, NULL, &tv);
2108 #endif
2109 #endif
2110 #endif
2111  ret = 1;
2112 done:
2113  return ret;
2114 }
2115 
2127 static int
2128 setsqliteopts(sqlite3 *x, DBC *d)
2129 {
2130  int count = 0, step = 0, max, rc = SQLITE_ERROR;
2131 
2132 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
2133  max = d->longnames ? 3 : 1;
2134 #else
2135  max = 3;
2136 #endif
2137  if (d->shortnames) {
2138  max = 3;
2139  }
2140  while (step < max) {
2141  if (step < 1) {
2142  rc = sqlite3_exec(x, "PRAGMA empty_result_callbacks = on;",
2143  NULL, NULL, NULL);
2144  if (rc == SQLITE_OK) {
2145  rc = sqlite3_exec(x, d->fksupport ?
2146  "PRAGMA foreign_keys = on;" :
2147  "PRAGMA foreign_keys = off;",
2148  NULL, NULL, NULL);
2149  }
2150  } else if (step < 2) {
2151  rc = sqlite3_exec(x, d->shortnames ?
2152  "PRAGMA full_column_names = off;" :
2153  "PRAGMA full_column_names = on;",
2154  NULL, NULL, NULL);
2155  } else if (step < 3) {
2156  rc = sqlite3_exec(x, d->shortnames ?
2157  "PRAGMA short_column_names = on;" :
2158  "PRAGMA short_column_names = off;",
2159  NULL, NULL, NULL);
2160  }
2161  if (rc != SQLITE_OK) {
2162  if (rc != SQLITE_BUSY ||
2163  !busy_handler((void *) d, ++count)) {
2164  return rc;
2165  }
2166  continue;
2167  }
2168  count = 0;
2169  ++step;
2170  }
2171  sqlite3_busy_handler(x, busy_handler, (void *) d);
2172  return SQLITE_OK;
2173 }
2174 
2184 static void
2185 freerows(char **rowp)
2186 {
2187  PTRDIFF_T size, i;
2188 
2189  if (!rowp) {
2190  return;
2191  }
2192  --rowp;
2193  size = (PTRDIFF_T) rowp[0];
2194  for (i = 1; i <= size; i++) {
2195  freep(&rowp[i]);
2196  }
2197  freep(&rowp);
2198 }
2199 
2210 static int
2211 mapsqltype(const char *typename, int *nosign, int ov3, int nowchar,
2212  int dobigint)
2213 {
2214  char *p, *q;
2215  int testsign = 0, result;
2216 
2217 #ifdef WINTERFACE
2218  result = nowchar ? SQL_VARCHAR : SQL_WVARCHAR;
2219 #else
2220  result = SQL_VARCHAR;
2221 #endif
2222  if (!typename) {
2223  return result;
2224  }
2225  q = p = xmalloc(strlen(typename) + 1);
2226  if (!p) {
2227  return result;
2228  }
2229  strcpy(p, typename);
2230  while (*q) {
2231  *q = TOLOWER(*q);
2232  ++q;
2233  }
2234  if (strncmp(p, "inter", 5) == 0) {
2235  } else if (strncmp(p, "int", 3) == 0 ||
2236  strncmp(p, "mediumint", 9) == 0) {
2237  testsign = 1;
2238  result = SQL_INTEGER;
2239  } else if (strncmp(p, "numeric", 7) == 0) {
2240  result = SQL_DOUBLE;
2241  } else if (strncmp(p, "tinyint", 7) == 0) {
2242  testsign = 1;
2243  result = SQL_TINYINT;
2244  } else if (strncmp(p, "smallint", 8) == 0) {
2245  testsign = 1;
2246  result = SQL_SMALLINT;
2247  } else if (strncmp(p, "float", 5) == 0) {
2248  result = SQL_DOUBLE;
2249  } else if (strncmp(p, "double", 6) == 0 ||
2250  strncmp(p, "real", 4) == 0) {
2251  result = SQL_DOUBLE;
2252  } else if (strncmp(p, "timestamp", 9) == 0) {
2253 #ifdef SQL_TYPE_TIMESTAMP
2254  result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
2255 #else
2256  result = SQL_TIMESTAMP;
2257 #endif
2258  } else if (strncmp(p, "datetime", 8) == 0) {
2259 #ifdef SQL_TYPE_TIMESTAMP
2260  result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
2261 #else
2262  result = SQL_TIMESTAMP;
2263 #endif
2264  } else if (strncmp(p, "time", 4) == 0) {
2265 #ifdef SQL_TYPE_TIME
2266  result = ov3 ? SQL_TYPE_TIME : SQL_TIME;
2267 #else
2268  result = SQL_TIME;
2269 #endif
2270  } else if (strncmp(p, "date", 4) == 0) {
2271 #ifdef SQL_TYPE_DATE
2272  result = ov3 ? SQL_TYPE_DATE : SQL_DATE;
2273 #else
2274  result = SQL_DATE;
2275 #endif
2276 #ifdef SQL_LONGVARCHAR
2277  } else if (strncmp(p, "text", 4) == 0 ||
2278  strncmp(p, "memo", 4) == 0 ||
2279  strncmp(p, "longvarchar", 11) == 0) {
2280 #ifdef WINTERFACE
2281  result = nowchar ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
2282 #else
2283  result = SQL_LONGVARCHAR;
2284 #endif
2285 #ifdef WINTERFACE
2286  } else if (strncmp(p, "wtext", 5) == 0 ||
2287  strncmp(p, "wvarchar", 8) == 0 ||
2288  strncmp(p, "longwvarchar", 12) == 0) {
2289  result = SQL_WLONGVARCHAR;
2290 #endif
2291 #endif
2292 #ifdef SQL_BIT
2293  } else if (strncmp(p, "bool", 4) == 0 ||
2294  strncmp(p, "bit", 3) == 0) {
2295  result = SQL_BIT;
2296 #endif
2297 #ifdef SQL_BIGINT
2298  } else if (strncmp(p, "bigint", 6) == 0) {
2299  testsign = 1;
2300  result = SQL_BIGINT;
2301 #endif
2302  } else if (strncmp(p, "blob", 4) == 0) {
2303  result = SQL_BINARY;
2304  } else if (strncmp(p, "varbinary", 9) == 0) {
2305  result = SQL_VARBINARY;
2306  } else if (strncmp(p, "longvarbinary", 13) == 0) {
2307  result = SQL_LONGVARBINARY;
2308  }
2309  if (nosign) {
2310  if (testsign) {
2311  *nosign = strstr(p, "unsigned") != NULL;
2312  } else {
2313  *nosign = 1;
2314  }
2315  }
2316 #ifdef SQL_BIGINT
2317  if (dobigint && result == SQL_INTEGER) {
2318  result = SQL_BIGINT;
2319  }
2320 #endif
2321  xfree(p);
2322  return result;
2323 }
2324 
2334 static void
2335 getmd(const char *typename, int sqltype, int *mp, int *dp)
2336 {
2337  int m = 0, d = 0;
2338 
2339  switch (sqltype) {
2340  case SQL_INTEGER: m = 10; d = 9; break;
2341  case SQL_TINYINT: m = 4; d = 3; break;
2342  case SQL_SMALLINT: m = 6; d = 5; break;
2343  case SQL_FLOAT: m = 25; d = 24; break;
2344  case SQL_DOUBLE: m = 54; d = 53; break;
2345  case SQL_VARCHAR: m = 255; d = 0; break;
2346 #ifdef WINTERFACE
2347 #ifdef SQL_WVARCHAR
2348  case SQL_WVARCHAR: m = 255; d = 0; break;
2349 #endif
2350 #endif
2351 #ifdef SQL_TYPE_DATE
2352  case SQL_TYPE_DATE:
2353 #endif
2354  case SQL_DATE: m = 10; d = 0; break;
2355 #ifdef SQL_TYPE_TIME
2356  case SQL_TYPE_TIME:
2357 #endif
2358  case SQL_TIME: m = 8; d = 0; break;
2359 #ifdef SQL_TYPE_TIMESTAMP
2360  case SQL_TYPE_TIMESTAMP:
2361 #endif
2362  case SQL_TIMESTAMP: m = 32; d = 3; break;
2363 #ifdef SQL_LONGVARCHAR
2364  case SQL_LONGVARCHAR : m = 65536; d = 0; break;
2365 #endif
2366 #ifdef WINTERFACE
2367 #ifdef SQL_WLONGVARCHAR
2368  case SQL_WLONGVARCHAR: m = 65536; d = 0; break;
2369 #endif
2370 #endif
2371  case SQL_BINARY:
2372  case SQL_VARBINARY: m = 255; d = 0; break;
2373  case SQL_LONGVARBINARY: m = 65536; d = 0; break;
2374 #ifdef SQL_BIGINT
2375  case SQL_BIGINT: m = 20; d = 19; break;
2376 #endif
2377 #ifdef SQL_BIT
2378  case SQL_BIT: m = 1; d = 1; break;
2379 #endif
2380  }
2381  if (m && typename) {
2382  int mm, dd;
2383  char clbr[4];
2384 
2385  if (sscanf(typename, "%*[^(](%d,%d %1[)]", &mm, &dd, clbr) == 3) {
2386  m = mm;
2387  d = dd;
2388  } else if (sscanf(typename, "%*[^(](%d %1[)]", &mm, clbr) == 2) {
2389  if (sqltype == SQL_TIMESTAMP) {
2390  d = mm;
2391  }
2392 #ifdef SQL_TYPE_TIMESTAMP
2393  else if (sqltype == SQL_TYPE_TIMESTAMP) {
2394  d = mm;
2395  }
2396 #endif
2397  else {
2398  m = d = mm;
2399  }
2400  }
2401  }
2402  if (mp) {
2403  *mp = m;
2404  }
2405  if (dp) {
2406  *dp = d;
2407  }
2408 }
2409 
2419 static int
2420 mapdeftype(int type, int stype, int nosign, int nowchar)
2421 {
2422  if (type == SQL_C_DEFAULT) {
2423  switch (stype) {
2424  case SQL_INTEGER:
2425  type = (nosign > 0) ? SQL_C_ULONG : SQL_C_LONG;
2426  break;
2427  case SQL_TINYINT:
2428  type = (nosign > 0) ? SQL_C_UTINYINT : SQL_C_TINYINT;
2429  break;
2430  case SQL_SMALLINT:
2431  type = (nosign > 0) ? SQL_C_USHORT : SQL_C_SHORT;
2432  break;
2433  case SQL_FLOAT:
2434  type = SQL_C_FLOAT;
2435  break;
2436  case SQL_DOUBLE:
2437  type = SQL_C_DOUBLE;
2438  break;
2439  case SQL_TIMESTAMP:
2440  type = SQL_C_TIMESTAMP;
2441  break;
2442  case SQL_TIME:
2443  type = SQL_C_TIME;
2444  break;
2445  case SQL_DATE:
2446  type = SQL_C_DATE;
2447  break;
2448 #ifdef SQL_C_TYPE_TIMESTAMP
2449  case SQL_TYPE_TIMESTAMP:
2450  type = SQL_C_TYPE_TIMESTAMP;
2451  break;
2452 #endif
2453 #ifdef SQL_C_TYPE_TIME
2454  case SQL_TYPE_TIME:
2455  type = SQL_C_TYPE_TIME;
2456  break;
2457 #endif
2458 #ifdef SQL_C_TYPE_DATE
2459  case SQL_TYPE_DATE:
2460  type = SQL_C_TYPE_DATE;
2461  break;
2462 #endif
2463 #ifdef WINTERFACE
2464  case SQL_WVARCHAR:
2465  case SQL_WCHAR:
2466 #ifdef SQL_WLONGVARCHAR
2467  case SQL_WLONGVARCHAR:
2468 #endif
2469  type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
2470  break;
2471 #endif
2472  case SQL_BINARY:
2473  case SQL_VARBINARY:
2474  case SQL_LONGVARBINARY:
2475  type = SQL_C_BINARY;
2476  break;
2477 #ifdef SQL_BIT
2478  case SQL_BIT:
2479  type = SQL_C_BIT;
2480  break;
2481 #endif
2482 #ifdef SQL_BIGINT
2483  case SQL_BIGINT:
2484  type = SQL_C_CHAR;
2485  break;
2486 #endif
2487  default:
2488 #ifdef WINTERFACE
2489  type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
2490 #else
2491  type = SQL_C_CHAR;
2492 #endif
2493  break;
2494  }
2495  }
2496  return type;
2497 }
2498 
2510 static char *
2511 fixupsql(char *sql, int sqlLen, int cte, int *nparam, int *isselect,
2512  char **errmsg)
2513 {
2514  char *q = sql, *qz = NULL, *p, *inq = NULL, *out;
2515  int np = 0, isddl = -1, size;
2516 
2517  if (errmsg) {
2518  *errmsg = NULL;
2519  }
2520  if (sqlLen != SQL_NTS) {
2521  qz = q = xmalloc(sqlLen + 1);
2522  if (!qz) {
2523  return NULL;
2524  }
2525  memcpy(q, sql, sqlLen);
2526  q[sqlLen] = '\0';
2527  size = sqlLen * 4;
2528  } else {
2529  size = strlen(sql) * 4;
2530  }
2531  size += sizeof (char *) - 1;
2532  size &= ~(sizeof (char *) - 1);
2533  p = xmalloc(size);
2534  if (!p) {
2535 errout:
2536  freep(&qz);
2537  return NULL;
2538  }
2539  memset(p, 0, size);
2540  out = p;
2541  while (*q) {
2542  switch (*q) {
2543  case '\'':
2544  case '\"':
2545  if (q == inq) {
2546  inq = NULL;
2547  } else if (!inq) {
2548  inq = q + 1;
2549 
2550  while (*inq) {
2551  if (*inq == *q) {
2552  if (inq[1] == *q) {
2553  inq++;
2554  } else {
2555  break;
2556  }
2557  }
2558  inq++;
2559  }
2560  }
2561  *p++ = *q;
2562  break;
2563  case '?':
2564  *p++ = *q;
2565  if (!inq) {
2566  np++;
2567  }
2568  break;
2569  case ';':
2570  if (!inq) {
2571  if (isddl < 0) {
2572  char *qq = out;
2573 
2574  while (*qq && ISSPACE(*qq)) {
2575  ++qq;
2576  }
2577  if (*qq && *qq != ';') {
2578  int i;
2579  static const struct {
2580  int len;
2581  const char *str;
2582  } ddlstr[] = {
2583  { 5, "alter" },
2584  { 7, "analyze" },
2585  { 6, "attach" },
2586  { 5, "begin" },
2587  { 6, "commit" },
2588  { 6, "create" },
2589  { 6, "detach" },
2590  { 4, "drop" },
2591  { 3, "end" },
2592  { 7, "reindex" },
2593  { 7, "release" },
2594  { 8, "rollback" },
2595  { 9, "savepoint" },
2596  { 6, "vacuum" }
2597  };
2598 
2599  size = strlen(qq);
2600  for (i = 0; i < array_size(ddlstr); i++) {
2601  if (size >= ddlstr[i].len &&
2602  strncasecmp(qq, ddlstr[i].str, ddlstr[i].len)
2603  == 0) {
2604  isddl = 1;
2605  break;
2606  }
2607  }
2608  if (isddl != 1) {
2609  isddl = 0;
2610  }
2611  }
2612  }
2613  if (isddl == 0) {
2614  char *qq = q;
2615 
2616  do {
2617  ++qq;
2618  } while (*qq && ISSPACE(*qq));
2619  if (*qq && *qq != ';') {
2620  freep(&out);
2621  if (errmsg) {
2622  *errmsg = "only one SQL statement allowed";
2623  }
2624  goto errout;
2625  }
2626  }
2627  }
2628  *p++ = *q;
2629  break;
2630  case '{':
2631  /*
2632  * Deal with escape sequences:
2633  * {d 'YYYY-MM-DD'}, {t ...}, {ts ...}
2634  * {oj ...}, {fn ...} etc.
2635  */
2636  if (!inq) {
2637  int ojfn = 0, brc = 0;
2638  char *inq2 = NULL, *end = q + 1, *start;
2639 
2640  while (*end && ISSPACE(*end)) {
2641  ++end;
2642  }
2643  if (*end != 'd' && *end != 'D' &&
2644  *end != 't' && *end != 'T') {
2645  ojfn = 1;
2646  }
2647  start = end;
2648  while (*end) {
2649  if (inq2 && *end == *inq2) {
2650  inq2 = NULL;
2651  } else if (inq2 == NULL && *end == '{') {
2652  char *nerr = 0, *nsql;
2653 
2654  nsql = fixupsql(end, SQL_NTS, cte, 0, 0, &nerr);
2655  if (nsql && !nerr) {
2656  strcpy(end, nsql);
2657  } else {
2658  brc++;
2659  }
2660  freep(&nsql);
2661  } else if (inq2 == NULL && *end == '}') {
2662  if (brc-- <= 0) {
2663  break;
2664  }
2665  } else if (inq2 == NULL && (*end == '\'' || *end == '"')) {
2666  inq2 = end;
2667  } else if (inq2 == NULL && *end == '?') {
2668  np++;
2669  }
2670  ++end;
2671  }
2672  if (*end == '}') {
2673  char *end2 = end - 1;
2674 
2675  if (ojfn) {
2676  while (start < end) {
2677  if (ISSPACE(*start)) {
2678  break;
2679  }
2680  ++start;
2681  }
2682  while (start < end) {
2683  *p++ = *start;
2684  ++start;
2685  }
2686  q = end;
2687  break;
2688  } else {
2689  while (start < end2 && *start != '\'') {
2690  ++start;
2691  }
2692  while (end2 > start && *end2 != '\'') {
2693  --end2;
2694  }
2695  if (*start == '\'' && *end2 == '\'') {
2696  while (start <= end2) {
2697  *p++ = *start;
2698  ++start;
2699  }
2700  q = end;
2701  break;
2702  }
2703  }
2704  }
2705  }
2706  /* FALL THROUGH */
2707  default:
2708  *p++ = *q;
2709  }
2710  ++q;
2711  }
2712  freep(&qz);
2713  *p = '\0';
2714  if (nparam) {
2715  *nparam = np;
2716  }
2717  if (isselect) {
2718  if (isddl > 0) {
2719  *isselect = 2;
2720  } else {
2721  int incom = 0;
2722 
2723  p = out;
2724  while (*p) {
2725  switch (*p) {
2726  case '-':
2727  if (!incom && p[1] == '-') {
2728  incom = -1;
2729  }
2730  break;
2731  case '\n':
2732  if (incom < 0) {
2733  incom = 0;
2734  }
2735  break;
2736  case '/':
2737  if (incom > 0 && p[-1] == '*') {
2738  incom = 0;
2739  p++;
2740  continue;
2741  } else if (!incom && p[1] == '*') {
2742  incom = 1;
2743  }
2744  break;
2745  }
2746  if (!incom && !ISSPACE(*p)) {
2747  break;
2748  }
2749  p++;
2750  }
2751  size = strlen(p);
2752  if (size >= 6 &&
2753  (strncasecmp(p, "select", 6) == 0 ||
2754  strncasecmp(p, "pragma", 6) == 0)) {
2755  *isselect = 1;
2756  } else if (cte && size >= 4 && strncasecmp(p, "with", 4) == 0) {
2757  *isselect = 1;
2758  } else if (size >= 7 && strncasecmp(p, "explain", 7) == 0) {
2759  *isselect = 1;
2760  } else {
2761  *isselect = 0;
2762  }
2763  }
2764  }
2765  return out;
2766 }
2767 
2776 static int
2777 findcol(char **cols, int ncols, char *name)
2778 {
2779  int i;
2780 
2781  if (cols) {
2782  for (i = 0; i < ncols; i++) {
2783  if (strcmp(cols[i], name) == 0) {
2784  return i;
2785  }
2786  }
2787  }
2788  return -1;
2789 }
2790 
2807 static void
2809 {
2810  int i, k;
2811 #ifndef FULL_METADATA
2812  int pk, nn, t, r, nrows, ncols;
2813  char **rowp, *flagp, flags[128];
2814 #endif
2815 
2816  if (!s->dyncols) {
2817  return;
2818  }
2819  /* fixup labels */
2820  if (!s->longnames) {
2821  if (s->dcols > 1) {
2822  char *table = s->dyncols[0].table;
2823 
2824  for (i = 1; table[0] && i < s->dcols; i++) {
2825  if (strcmp(s->dyncols[i].table, table)) {
2826  break;
2827  }
2828  }
2829  if (i >= s->dcols) {
2830  for (i = 0; i < s->dcols; i++) {
2831  s->dyncols[i].label = s->dyncols[i].column;
2832  }
2833  }
2834  } else if (s->dcols == 1) {
2835  s->dyncols[0].label = s->dyncols[0].column;
2836  }
2837  }
2838  for (i = 0; i < s->dcols; i++) {
2839  s->dyncols[i].type =
2840  mapsqltype(s->dyncols[i].typename, &s->dyncols[i].nosign, *s->ov3,
2841  s->nowchar[0] || s->nowchar[1], s->dobigint);
2842  getmd(s->dyncols[i].typename, s->dyncols[i].type,
2843  &s->dyncols[i].size, &s->dyncols[i].prec);
2844 #ifdef SQL_LONGVARCHAR
2845  if (s->dyncols[i].type == SQL_VARCHAR &&
2846  s->dyncols[i].size > 255) {
2847  s->dyncols[i].type = SQL_LONGVARCHAR;
2848  }
2849 #endif
2850 #ifdef WINTERFACE
2851 #ifdef SQL_WLONGVARCHAR
2852  if (s->dyncols[i].type == SQL_WVARCHAR &&
2853  s->dyncols[i].size > 255) {
2854  s->dyncols[i].type = SQL_WLONGVARCHAR;
2855  }
2856 #endif
2857 #endif
2858  if (s->dyncols[i].type == SQL_VARBINARY &&
2859  s->dyncols[i].size > 255) {
2860  s->dyncols[i].type = SQL_LONGVARBINARY;
2861  }
2862  }
2863 #ifndef FULL_METADATA
2864  if (s->dcols > array_size(flags)) {
2865  flagp = xmalloc(sizeof (flags[0]) * s->dcols);
2866  if (flagp == NULL) {
2867  return;
2868  }
2869  } else {
2870  flagp = flags;
2871  }
2872  memset(flagp, 0, sizeof (flags[0]) * s->dcols);
2873  for (i = 0; i < s->dcols; i++) {
2874  s->dyncols[i].autoinc = SQL_FALSE;
2875  s->dyncols[i].notnull = SQL_NULLABLE;
2876  }
2877  for (i = 0; i < s->dcols; i++) {
2878  int ret, lastpk = -1, autoinccount = 0;
2879  char *sql;
2880 
2881  if (!s->dyncols[i].table[0]) {
2882  continue;
2883  }
2884  if (flagp[i]) {
2885  continue;
2886  }
2887  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", s->dyncols[i].table);
2888  if (!sql) {
2889  continue;
2890  }
2891  dbtraceapi(d, "sqlite3_get_table", sql);
2892  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, NULL);
2893  sqlite3_free(sql);
2894  if (ret != SQLITE_OK) {
2895  continue;
2896  }
2897  k = findcol(rowp, ncols, "name");
2898  t = findcol(rowp, ncols, "type");
2899  pk = findcol(rowp, ncols, "pk");
2900  nn = findcol(rowp, ncols, "notnull");
2901  if (k < 0 || t < 0) {
2902  goto freet;
2903  }
2904  for (r = 1; r <= nrows; r++) {
2905  int m;
2906 
2907  for (m = i; m < s->dcols; m++) {
2908  char *colname = s->dyncols[m].column;
2909 
2910  if (s->longnames) {
2911  char *dotp = strchr(colname, '.');
2912 
2913  if (dotp) {
2914  colname = dotp + 1;
2915  }
2916  }
2917  if (!flagp[m] &&
2918  strcmp(colname, rowp[r * ncols + k]) == 0 &&
2919  strcmp(s->dyncols[m].table, s->dyncols[i].table) == 0) {
2920  char *typename = rowp[r * ncols + t];
2921 
2922  flagp[m] = i + 1;
2923  freep(&s->dyncols[m].typename);
2924  s->dyncols[m].typename = xstrdup(typename);
2925  s->dyncols[m].type =
2926  mapsqltype(typename, &s->dyncols[m].nosign, *s->ov3,
2927  s->nowchar[0] || s->nowchar[1],
2928  s->dobigint);
2929  getmd(typename, s->dyncols[m].type, &s->dyncols[m].size,
2930  &s->dyncols[m].prec);
2931 #ifdef SQL_LONGVARCHAR
2932  if (s->dyncols[m].type == SQL_VARCHAR &&
2933  s->dyncols[m].size > 255) {
2934  s->dyncols[m].type = SQL_LONGVARCHAR;
2935  }
2936 #endif
2937 #ifdef WINTERFACE
2938 #ifdef SQL_WLONGVARCHAR
2939  if (s->dyncols[i].type == SQL_WVARCHAR &&
2940  s->dyncols[i].size > 255) {
2941  s->dyncols[i].type = SQL_WLONGVARCHAR;
2942  }
2943 #endif
2944 #endif
2945  if (s->dyncols[i].type == SQL_VARBINARY &&
2946  s->dyncols[i].size > 255) {
2947  s->dyncols[i].type = SQL_LONGVARBINARY;
2948  }
2949  if (pk >= 0 && strcmp(rowp[r * ncols + pk], "1") == 0) {
2950  s->dyncols[m].ispk = 1;
2951  if (++autoinccount > 1) {
2952  if (lastpk >= 0) {
2953  s->dyncols[lastpk].autoinc = SQL_FALSE;
2954  lastpk = -1;
2955  }
2956  } else {
2957  lastpk = m;
2958  if (strlen(typename) == 7 &&
2959  strncasecmp(typename, "integer", 7) == 0) {
2960  s->dyncols[m].autoinc = SQL_TRUE;
2961  }
2962  }
2963  } else {
2964  s->dyncols[m].ispk = 0;
2965  }
2966  if (nn >= 0 && rowp[r * ncols + nn][0] != '0') {
2967  s->dyncols[m].notnull = SQL_NO_NULLS;
2968  }
2969  }
2970  }
2971  }
2972 freet:
2973  sqlite3_free_table(rowp);
2974  }
2975  for (i = k = 0; i < s->dcols; i++) {
2976  if (flagp[i] == 0) {
2977  break;
2978  }
2979  if (k == 0) {
2980  k = flagp[i];
2981  } else if (flagp[i] != k) {
2982  k = 0;
2983  break;
2984  }
2985  }
2986  s->one_tbl = k ? 1 : 0;
2987  k = 0;
2988  if (s->one_tbl) {
2989  for (i = 0; i < s->dcols; i++) {
2990  if (s->dyncols[i].ispk > 0) {
2991  ++k;
2992  }
2993  }
2994  }
2995  s->has_pk = k;
2996  if (flagp != flags) {
2997  freep(&flagp);
2998  }
2999 #else
3000  for (i = 1, k = 0; i < s->dcols; i++) {
3001  if (strcmp(s->dyncols[i].table, s->dyncols[0].table) == 0) {
3002  k++;
3003  }
3004  }
3005  s->one_tbl = (k && k + 1 == s->dcols) ? 1 : 0;
3006  k = 0;
3007  if (s->one_tbl) {
3008  for (i = 0; i < s->dcols; i++) {
3009  if (s->dyncols[i].ispk > 0) {
3010  ++k;
3011  if (s->has_rowid < 0 && s->dyncols[i].isrowid > 0) {
3012  s->has_rowid = i;
3013  }
3014  }
3015  }
3016  }
3017  s->has_pk = k;
3018 #endif
3019 }
3020 
3027 static void
3028 convJD2YMD(double jd, DATE_STRUCT *ds)
3029 {
3030  int z, a, b, c, d, e, x1;
3031  sqlite_int64 ijd;
3032 
3033  ijd = jd * 86400000.0 + 0.5;
3034  z = (int) ((ijd + 43200000) / 86400000);
3035  a = (int) ((z - 1867216.25) / 36524.25);
3036  a = z + 1 + a - (a / 4);
3037  b = a + 1524;
3038  c = (int) ((b - 122.1) / 365.25);
3039  d = (36525 * c) / 100;
3040  e = (int) ((b - d) / 30.6001);
3041  x1 = (int) (30.6001 * e);
3042  ds->day = b - d - x1;
3043  ds->month = (e < 14) ? (e - 1) : (e - 13);
3044  ds->year = (ds->month > 2) ? (c - 4716) : (c - 4715);
3045 }
3046 
3047 
3055 static void
3056 convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
3057 {
3058  int s;
3059  double ds;
3060  sqlite_int64 ijd;
3061 
3062  ijd = jd * 86400000.0 + 0.5;
3063  s = (int)((ijd + 43200000) % 86400000);
3064  ds = s / 1000.0;
3065  if (fp) {
3066  *fp = (s % 1000) * 1000000;
3067  }
3068  s = (int) ds;
3069  ds -= s;
3070  ts->hour = s / 3600;
3071  s -= ts->hour * 3600;
3072  ts->minute = s / 60;
3073  ds += s - ts->minute *60;
3074  ts->second = (int) ds;
3075 }
3076 
3084 static int
3085 getmdays(int year, int month)
3086 {
3087  static const int mdays[] = {
3088  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
3089  };
3090  int mday;
3091 
3092  if (month < 1) {
3093  return 0;
3094  }
3095  mday = mdays[(month - 1) % 12];
3096  if (mday == 28 && year % 4 == 0 &&
3097  (!(year % 100 == 0) || year % 400 == 0)) {
3098  mday++;
3099  }
3100  return mday;
3101 }
3102 
3118 static int
3119 str2date(int jdconv, char *str, DATE_STRUCT *ds)
3120 {
3121  int i, err = 0;
3122  double jd;
3123  char *p, *q, sepc = '\0';
3124 
3125  ds->year = ds->month = ds->day = 0;
3126  if (jdconv) {
3127  p = strchr(str, '.');
3128  if (p) {
3129  /* julian day format */
3130  p = 0;
3131  jd = ln_strtod(str, &p);
3132  if (p && p > str) {
3133  convJD2YMD(jd, ds);
3134  return 0;
3135  }
3136  }
3137  }
3138  p = str;
3139  while (*p && !ISDIGIT(*p)) {
3140  ++p;
3141  }
3142  q = p;
3143  i = 0;
3144  while (*q && !ISDIGIT(*q)) {
3145  ++i;
3146  ++q;
3147  }
3148  if (i >= 8) {
3149  char buf[8];
3150 
3151  strncpy(buf, p + 0, 4); buf[4] = '\0';
3152  ds->year = strtol(buf, NULL, 10);
3153  strncpy(buf, p + 4, 2); buf[2] = '\0';
3154  ds->month = strtol(buf, NULL, 10);
3155  strncpy(buf, p + 6, 2); buf[2] = '\0';
3156  ds->day = strtol(buf, NULL, 10);
3157  goto done;
3158  }
3159  i = 0;
3160  while (i < 3) {
3161  int n;
3162 
3163  q = NULL;
3164  n = strtol(p, &q, 10);
3165  if (!q || q == p) {
3166  if (*q == '\0') {
3167  if (i == 0) {
3168  err = 1;
3169  }
3170  goto done;
3171  }
3172  }
3173  if (!sepc) {
3174  sepc = *q;
3175  }
3176  if (*q == '-' || *q == '/' || *q == '\0' || i == 2) {
3177  switch (i) {
3178  case 0: ds->year = n; break;
3179  case 1: ds->month = n; break;
3180  case 2: ds->day = n; break;
3181  }
3182  ++i;
3183  if (*q) {
3184  ++q;
3185  }
3186  } else {
3187  i = 0;
3188  while (*q && !ISDIGIT(*q)) {
3189  ++q;
3190  }
3191  }
3192  p = q;
3193  }
3194 done:
3195  /* final check for overflow */
3196  if (err ||
3197  ds->month < 1 || ds->month > 12 ||
3198  ds->day < 1 || ds->day > getmdays(ds->year, ds->month)) {
3199  if (sepc == '/') {
3200  /* Try MM/DD/YYYY format */
3201  int t[3];
3202 
3203  t[0] = ds->year;
3204  t[1] = ds->month;
3205  t[2] = ds->day;
3206  ds->year = t[2];
3207  ds->day = t[1];
3208  ds->month = t[0];
3209  if (ds->month >= 1 && ds->month <= 12 &&
3210  (ds->day >= 1 || ds->day <= getmdays(ds->year, ds->month))) {
3211  return 0;
3212  }
3213  }
3214  return -1;
3215  }
3216  return 0;
3217 }
3218 
3233 static int
3234 str2time(int jdconv, char *str, TIME_STRUCT *ts)
3235 {
3236  int i, err = 0, ampm = -1;
3237  double jd;
3238  char *p, *q;
3239 
3240  ts->hour = ts->minute = ts->second = 0;
3241  if (jdconv) {
3242  p = strchr(str, '.');
3243  if (p) {
3244  /* julian day format */
3245  p = 0;
3246  jd = ln_strtod(str, &p);
3247  if (p && p > str) {
3248  convJD2HMS(jd, ts, 0);
3249  return 0;
3250  }
3251  }
3252  }
3253  p = str;
3254  while (*p && !ISDIGIT(*p)) {
3255  ++p;
3256  }
3257  q = p;
3258  i = 0;
3259  while (*q && ISDIGIT(*q)) {
3260  ++i;
3261  ++q;
3262  }
3263  if (i >= 6) {
3264  char buf[4];
3265 
3266  strncpy(buf, p + 0, 2); buf[2] = '\0';
3267  ts->hour = strtol(buf, NULL, 10);
3268  strncpy(buf, p + 2, 2); buf[2] = '\0';
3269  ts->minute = strtol(buf, NULL, 10);
3270  strncpy(buf, p + 4, 2); buf[2] = '\0';
3271  ts->second = strtol(buf, NULL, 10);
3272  goto done;
3273  }
3274  i = 0;
3275  while (i < 3) {
3276  int n;
3277 
3278  q = NULL;
3279  n = strtol(p, &q, 10);
3280  if (!q || q == p) {
3281  if (*q == '\0') {
3282  if (i == 0) {
3283  err = 1;
3284  }
3285  goto done;
3286  }
3287  }
3288  if (*q == ':' || *q == '\0' || i == 2) {
3289  switch (i) {
3290  case 0: ts->hour = n; break;
3291  case 1: ts->minute = n; break;
3292  case 2: ts->second = n; break;
3293  }
3294  ++i;
3295  if (*q) {
3296  ++q;
3297  }
3298  } else {
3299  i = 0;
3300  while (*q && !ISDIGIT(*q)) {
3301  ++q;
3302  }
3303  }
3304  p = q;
3305  }
3306  if (!err) {
3307  while (*p) {
3308  if ((p[0] == 'p' || p[0] == 'P') &&
3309  (p[1] == 'm' || p[1] == 'M')) {
3310  ampm = 1;
3311  } else if ((p[0] == 'a' || p[0] == 'A') &&
3312  (p[1] == 'm' || p[1] == 'M')) {
3313  ampm = 0;
3314  }
3315  ++p;
3316  }
3317  if (ampm > 0) {
3318  if (ts->hour < 12) {
3319  ts->hour += 12;
3320  }
3321  } else if (ampm == 0) {
3322  if (ts->hour == 12) {
3323  ts->hour = 0;
3324  }
3325  }
3326  }
3327 done:
3328  /* final check for overflow */
3329  if (err || ts->hour > 23 || ts->minute > 59 || ts->second > 59) {
3330  return -1;
3331  }
3332  return 0;
3333 }
3334 
3354 static int
3355 str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
3356 {
3357  int i, m, n, err = 0, ampm = -1;
3358  double jd;
3359  char *p, *q, in = '\0', sepc = '\0';
3360 
3361  tss->year = tss->month = tss->day = 0;
3362  tss->hour = tss->minute = tss->second = 0;
3363  tss->fraction = 0;
3364  if (jdconv) {
3365  p = strchr(str, '.');
3366  if (p) {
3367  q = strchr(str, '-');
3368  if (q == str) {
3369  q = 0;
3370  }
3371  if (!q) {
3372  q = strchr(str, '/');
3373  if (!q) {
3374  q = strchr(str, ':');
3375  }
3376  }
3377  if (!q || q > p) {
3378  /* julian day format */
3379  p = 0;
3380  jd = ln_strtod(str, &p);
3381  if (p && p > str) {
3382  DATE_STRUCT ds;
3383  TIME_STRUCT ts;
3384 
3385  convJD2YMD(jd, &ds);
3386  convJD2HMS(jd, &ts, &n);
3387  tss->year = ds.year;
3388  tss->month = ds.month;
3389  tss->day = ds.day;
3390  tss->hour = ts.hour;
3391  tss->minute = ts.minute;
3392  tss->second = ts.second;
3393  tss->fraction = n;
3394  return 0;
3395  }
3396  }
3397  }
3398  }
3399  p = str;
3400  while (*p && !ISDIGIT(*p)) {
3401  ++p;
3402  }
3403  q = p;
3404  i = 0;
3405  while (*q && ISDIGIT(*q)) {
3406  ++i;
3407  ++q;
3408  }
3409  if (i >= 14) {
3410  char buf[16];
3411 
3412  strncpy(buf, p + 0, 4); buf[4] = '\0';
3413  tss->year = strtol(buf, NULL, 10);
3414  strncpy(buf, p + 4, 2); buf[2] = '\0';
3415  tss->month = strtol(buf, NULL, 10);
3416  strncpy(buf, p + 6, 2); buf[2] = '\0';
3417  tss->day = strtol(buf, NULL, 10);
3418  strncpy(buf, p + 8, 2); buf[2] = '\0';
3419  tss->hour = strtol(buf, NULL, 10);
3420  strncpy(buf, p + 10, 2); buf[2] = '\0';
3421  tss->minute = strtol(buf, NULL, 10);
3422  strncpy(buf, p + 12, 2); buf[2] = '\0';
3423  tss->second = strtol(buf, NULL, 10);
3424  if (i > 14) {
3425  m = i - 14;
3426  strncpy(buf, p + 14, m);
3427  while (m < 9) {
3428  buf[m] = '0';
3429  ++m;
3430  }
3431  buf[m] = '\0';
3432  tss->fraction = strtol(buf, NULL, 10);
3433  }
3434  m = 7;
3435  goto done;
3436  }
3437  m = i = 0;
3438  while ((m & 7) != 7) {
3439  q = NULL;
3440  n = strtol(p, &q, 10);
3441  if (!q || q == p) {
3442  if (*q == '\0') {
3443  if (m < 1) {
3444  err = 1;
3445  }
3446  goto done;
3447  }
3448  }
3449  if (in == '\0') {
3450  switch (*q) {
3451  case '-':
3452  case '/':
3453  if ((m & 1) == 0) {
3454  in = *q;
3455  i = 0;
3456  }
3457  break;
3458  case ':':
3459  if ((m & 2) == 0) {
3460  in = *q;
3461  i = 0;
3462  }
3463  break;
3464  case ' ':
3465  case '.':
3466  break;
3467  default:
3468  in = '\0';
3469  i = 0;
3470  break;
3471  }
3472  }
3473  switch (in) {
3474  case '-':
3475  case '/':
3476  if (!sepc) {
3477  sepc = in;
3478  }
3479  switch (i) {
3480  case 0: tss->year = n; break;
3481  case 1: tss->month = n; break;
3482  case 2: tss->day = n; break;
3483  }
3484  if (++i >= 3) {
3485  i = 0;
3486  m |= 1;
3487  if (!(m & 2)) {
3488  m |= 8;
3489  }
3490  goto skip;
3491  } else {
3492  ++q;
3493  }
3494  break;
3495  case ':':
3496  switch (i) {
3497  case 0: tss->hour = n; break;
3498  case 1: tss->minute = n; break;
3499  case 2: tss->second = n; break;
3500  }
3501  if (++i >= 3) {
3502  i = 0;
3503  m |= 2;
3504  if (*q == '.') {
3505  in = '.';
3506  goto skip2;
3507  }
3508  if (*q == ' ') {
3509  if ((m & 1) == 0) {
3510  char *e = NULL;
3511 
3512  (void) strtol(q + 1, &e, 10);
3513  if (e && *e == '-') {
3514  goto skip;
3515  }
3516  }
3517  in = '.';
3518  goto skip2;
3519  }
3520  goto skip;
3521  } else {
3522  ++q;
3523  }
3524  break;
3525  case '.':
3526  if (++i >= 1) {
3527  int ndig = q - p;
3528 
3529  if (p[0] == '+' || p[0] == '-') {
3530  ndig--;
3531  }
3532  while (ndig < 9) {
3533  n = n * 10;
3534  ++ndig;
3535  }
3536  tss->fraction = n;
3537  m |= 4;
3538  i = 0;
3539  }
3540  default:
3541  skip:
3542  in = '\0';
3543  skip2:
3544  while (*q && !ISDIGIT(*q)) {
3545  if ((q[0] == 'a' || q[0] == 'A') &&
3546  (q[1] == 'm' || q[1] == 'M')) {
3547  ampm = 0;
3548  ++q;
3549  } else if ((q[0] == 'p' || q[0] == 'P') &&
3550  (q[1] == 'm' || q[1] == 'M')) {
3551  ampm = 1;
3552  ++q;
3553  }
3554  ++q;
3555  }
3556  }
3557  p = q;
3558  }
3559  if ((m & 7) > 1 && (m & 8)) {
3560  /* ISO8601 timezone */
3561  if (p > str && ISDIGIT(*p)) {
3562  int nn, sign;
3563 
3564  q = p - 1;
3565  if (*q != '+' && *q != '-') {
3566  goto done;
3567  }
3568  sign = (*q == '+') ? -1 : 1;
3569  q = NULL;
3570  n = strtol(p, &q, 10);
3571  if (!q || *q++ != ':' || !ISDIGIT(*q)) {
3572  goto done;
3573  }
3574  p = q;
3575  q = NULL;
3576  nn = strtol(p, &q, 10);
3577  tss->minute += nn * sign;
3578  if ((SQLSMALLINT) tss->minute < 0) {
3579  tss->hour -= 1;
3580  tss->minute += 60;
3581  } else if (tss->minute >= 60) {
3582  tss->hour += 1;
3583  tss->minute -= 60;
3584  }
3585  tss->hour += n * sign;
3586  if ((SQLSMALLINT) tss->hour < 0) {
3587  tss->day -= 1;
3588  tss->hour += 24;
3589  } else if (tss->hour >= 24) {
3590  tss->day += 1;
3591  tss->hour -= 24;
3592  }
3593  if ((short) tss->day < 1 || tss->day >= 28) {
3594  int mday, pday, pmon;
3595 
3596  mday = getmdays(tss->year, tss->month);
3597  pmon = tss->month - 1;
3598  if (pmon < 1) {
3599  pmon = 12;
3600  }
3601  pday = getmdays(tss->year, pmon);
3602  if ((SQLSMALLINT) tss->day < 1) {
3603  tss->month -= 1;
3604  tss->day = pday;
3605  } else if (tss->day > mday) {
3606  tss->month += 1;
3607  tss->day = 1;
3608  }
3609  if ((SQLSMALLINT) tss->month < 1) {
3610  tss->year -= 1;
3611  tss->month = 12;
3612  } else if (tss->month > 12) {
3613  tss->year += 1;
3614  tss->month = 1;
3615  }
3616  }
3617  }
3618  }
3619 done:
3620  if ((m & 1) &&
3621  (tss->month < 1 || tss->month > 12 ||
3622  tss->day < 1 || tss->day > getmdays(tss->year, tss->month))) {
3623  if (sepc == '/') {
3624  /* Try MM/DD/YYYY format */
3625  int t[3];
3626 
3627  t[0] = tss->year;
3628  t[1] = tss->month;
3629  t[2] = tss->day;
3630  tss->year = t[2];
3631  tss->day = t[1];
3632  tss->month = t[0];
3633  }
3634  }
3635  /* Replace missing year/month/day with current date */
3636  if (!err && (m & 1) == 0) {
3637 #ifdef _WIN32
3638  SYSTEMTIME t;
3639 
3640  GetLocalTime(&t);
3641  tss->year = t.wYear;
3642  tss->month = t.wMonth;
3643  tss->day = t.wDay;
3644 #else
3645  struct timeval tv;
3646  struct tm tm;
3647 
3648  gettimeofday(&tv, NULL);
3649  tm = *localtime(&tv.tv_sec);
3650  tss->year = tm.tm_year + 1900;
3651  tss->month = tm.tm_mon + 1;
3652  tss->day = tm.tm_mday;
3653 #endif
3654  }
3655  /* Normalize fraction */
3656  if (tss->fraction < 0) {
3657  tss->fraction = 0;
3658  }
3659  /* Final check for overflow */
3660  if (err ||
3661  tss->month < 1 || tss->month > 12 ||
3662  tss->day < 1 || tss->day > getmdays(tss->year, tss->month) ||
3663  tss->hour > 23 || tss->minute > 59 || tss->second > 59) {
3664  return -1;
3665  }
3666  if ((m & 7) > 1) {
3667  if (ampm > 0) {
3668  if (tss->hour < 12) {
3669  tss->hour += 12;
3670  }
3671  } else if (ampm == 0) {
3672  if (tss->hour == 12) {
3673  tss->hour = 0;
3674  }
3675  }
3676  }
3677  return ((m & 7) < 1) ? -1 : 0;
3678 }
3679 
3686 static int
3687 getbool(char *string)
3688 {
3689  if (string) {
3690  return string[0] && strchr("Yy123456789Tt", string[0]) != NULL;
3691  }
3692  return 0;
3693 }
3694 
3702 static void
3703 blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
3704 {
3705 #if 0
3706  DBC *d = (DBC *) sqlite3_user_data(ctx);
3707 #endif
3708  char *filename = 0;
3709 
3710  if (nargs > 0) {
3711  if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
3712  filename = (char *) sqlite3_value_text(args[0]);
3713  }
3714  }
3715  if (filename) {
3716 #ifdef _WIN32
3717  char *wname = utf_to_wmb(filename, -1);
3718  FILE *f;
3719 #else
3720  FILE *f = fopen(filename, "r");
3721 #endif
3722  char *p;
3723  long n, nn;
3724 
3725 #ifdef _WIN32
3726  if (wname) {
3727  f = fopen(wname, "rb");
3728  } else {
3729  sqlite3_result_error(ctx, "out of memory", -1);
3730  return;
3731  }
3732  uc_free(wname);
3733 #endif
3734  if (f) {
3735  if (fseek(f, 0, SEEK_END) == 0) {
3736  n = ftell(f);
3737  if (fseek(f, 0, SEEK_SET) == 0) {
3738  p = sqlite3_malloc(n);
3739  if (p) {
3740  nn = fread(p, 1, n, f);
3741  if (nn != n) {
3742  sqlite3_result_error(ctx, "read error", -1);
3743  sqlite3_free(p);
3744  } else {
3745  sqlite3_result_blob(ctx, p, n, sqlite3_free);
3746  }
3747  } else {
3748  sqlite3_result_error(ctx, "out of memory", -1);
3749  }
3750  } else {
3751  sqlite3_result_error(ctx, "seek error", -1);
3752  }
3753  } else {
3754  sqlite3_result_error(ctx, "seek error", -1);
3755  }
3756  fclose(f);
3757  } else {
3758  sqlite3_result_error(ctx, "cannot open file", -1);
3759  }
3760  } else {
3761  sqlite3_result_error(ctx, "no filename given", -1);
3762  }
3763 }
3764 
3772 static void
3773 blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
3774 {
3775 #if 0
3776  DBC *d = (DBC *) sqlite3_user_data(ctx);
3777 #endif
3778  char *filename = 0;
3779  char *p = 0;
3780  int n = 0;
3781 
3782  if (nargs > 0) {
3783  p = (char *) sqlite3_value_blob(args[0]);
3784  n = sqlite3_value_bytes(args[0]);
3785  }
3786  if (nargs > 1) {
3787  if (sqlite3_value_type(args[1]) != SQLITE_NULL) {
3788  filename = (char *) sqlite3_value_text(args[1]);
3789  }
3790  }
3791  if (p) {
3792  if (filename) {
3793 #ifdef _WIN32
3794  char *wname = utf_to_wmb(filename, -1);
3795  FILE *f;
3796 #else
3797  FILE *f = fopen(filename, "w");
3798 #endif
3799  int nn;
3800 
3801 #ifdef _WIN32
3802  if (wname) {
3803  f = fopen(wname, "wb");
3804  } else {
3805  sqlite3_result_error(ctx, "out of memory", -1);
3806  return;
3807  }
3808  uc_free(wname);
3809 #endif
3810  if (f) {
3811  nn = fwrite(p, 1, n, f);
3812  fclose(f);
3813  if (nn != n) {
3814  sqlite3_result_error(ctx, "write error", -1);
3815  } else {
3816  sqlite3_result_int(ctx, nn);
3817  }
3818  } else {
3819  sqlite3_result_error(ctx, "cannot open file", -1);
3820  }
3821  } else {
3822  sqlite3_result_error(ctx, "no filename given", -1);
3823  }
3824  } else {
3825  sqlite3_result_null(ctx);
3826  }
3827 }
3828 
3836 static void
3837 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3838 dbtrace(void *arg, const char *msg, sqlite_uint64 et)
3839 #else
3840 dbtrace(void *arg, const char *msg)
3841 #endif
3842 {
3843  DBC *d = (DBC *) arg;
3844 
3845  if (msg && d->trace) {
3846  int len = strlen(msg);
3847 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3848  unsigned long s, f;
3849 #endif
3850 
3851  if (len > 0) {
3852  char *end = "\n";
3853 
3854  if (msg[len - 1] != ';') {
3855  end = ";\n";
3856  }
3857  fprintf(d->trace, "%s%s", msg, end);
3858 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
3859  s = et / 1000000000LL;
3860  f = et % 1000000000LL;
3861  fprintf(d->trace, "-- took %lu.%09lu seconds\n", s, f);
3862 #endif
3863  fflush(d->trace);
3864  }
3865  }
3866 }
3867 
3875 static void
3876 dbtraceapi(DBC *d, char *fn, const char *sql)
3877 {
3878  if (fn && d->trace) {
3879  if (sql) {
3880  fprintf(d->trace, "-- %s: %s\n", fn, sql);
3881  } else {
3882  fprintf(d->trace, "-- %s\n", fn);
3883  }
3884  fflush(d->trace);
3885  }
3886 }
3887 
3895 static void
3896 dbtracerc(DBC *d, int rc, char *err)
3897 {
3898  if (rc != SQLITE_OK && d->trace) {
3899  fprintf(d->trace, "-- SQLITE ERROR CODE %d", rc);
3900  fprintf(d->trace, err ? ": %s\n" : "\n", err);
3901  fflush(d->trace);
3902  }
3903 }
3904 
3919 static SQLRETURN
3920 dbopen(DBC *d, char *name, int isu, char *dsn, char *sflag,
3921  char *spflag, char *ntflag, char *jmode, char *busy)
3922 {
3923  char *endp = NULL;
3924  int rc, tmp, busyto = 100000;
3925 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
3926  int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
3927  char *uname = name;
3928  const char *vfs_name = NULL;
3929 #endif
3930 
3931  if (d->sqlite) {
3932  if (d->trace) {
3933  fprintf(d->trace, "-- sqlite3_close (deferred): '%s'\n",
3934  d->dbname);
3935  fflush(d->trace);
3936  }
3937 #if defined(HAVE_SQLITE3CLOSEV2) && (HAVE_SQLITE3CLOSEV2)
3938  sqlite3_close_v2(d->sqlite);
3939 #else
3940  sqlite3_close(d->sqlite);
3941 #endif
3942  d->sqlite = NULL;
3943  }
3944 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
3945  if (d->nocreat) {
3946  flags &= ~ SQLITE_OPEN_CREATE;
3947  }
3948 #if defined(_WIN32) || defined(_WIN64)
3949  if (!isu) {
3950  char expname[MAX_PATH];
3951 
3952  expname[0] = '\0';
3953  rc = ExpandEnvironmentStrings(name, expname, sizeof (expname));
3954  if (rc <= sizeof (expname)) {
3955  uname = wmb_to_utf(expname, rc - 1);
3956  } else {
3957  uname = wmb_to_utf(name, -1);
3958  }
3959  if (!uname) {
3960  rc = SQLITE_NOMEM;
3961  setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
3962  return SQL_ERROR;
3963  }
3964  }
3965 #endif
3966 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
3967  vfs_name = nvfs_makevfs(uname);
3968 #endif
3969 #ifdef SQLITE_OPEN_URI
3970  flags |= SQLITE_OPEN_URI;
3971 #endif
3972  rc = sqlite3_open_v2(uname, &d->sqlite, flags, vfs_name);
3973 #if defined(WINTERFACE) || defined(_WIN32) || defined(_WIN64)
3974  if (uname != name) {
3975  uc_free(uname);
3976  }
3977 #endif
3978 #else
3979 #if defined(_WIN32) || defined(_WIN64)
3980  if (d->nocreat) {
3981  char *cname = NULL;
3982 
3983  if (isu) {
3984  cname = utf_to_wmb(name, -1);
3985  }
3986  if (GetFileAttributesA(cname ? cname : name) ==
3987  INVALID_FILE_ATTRIBUTES) {
3988  uc_free(cname);
3989  rc = SQLITE_CANTOPEN;
3990  setstatd(d, rc, "cannot open database",
3991  (*d->ov3) ? "HY000" : "S1000");
3992  return SQL_ERROR;
3993  }
3994  uc_free(cname);
3995  }
3996 #else
3997  if (d->nocreat && access(name, 004) < 0) {
3998  rc = SQLITE_CANTOPEN;
3999  setstatd(d, rc, "cannot open database", (*d->ov3) ? "HY000" : "S1000");
4000  return SQL_ERROR;
4001  }
4002 #endif
4003 #if defined(_WIN32) || defined(_WIN64)
4004  if (!isu) {
4005  WCHAR *wname = wmb_to_uc(name, -1);
4006 
4007  if (!wname) {
4008  rc = SQLITE_NOMEM;
4009  setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
4010  return SQL_ERROR;
4011  }
4012  rc = sqlite3_open16(wname, &d->sqlite);
4013  uc_free(wname);
4014  } else
4015 #endif
4016  rc = sqlite3_open(name, &d->sqlite);
4017 #endif /* !HAVE_SQLITE3VFS */
4018  if (rc != SQLITE_OK) {
4019 connfail:
4020  setstatd(d, rc, "connect failed", (*d->ov3) ? "HY000" : "S1000");
4021  if (d->sqlite) {
4022  sqlite3_close(d->sqlite);
4023  d->sqlite = NULL;
4024  }
4025  return SQL_ERROR;
4026  }
4027 #if defined(SQLITE_DYNLOAD) || defined(SQLITE_HAS_CODEC)
4028  if (d->pwd) {
4029  sqlite3_key(d->sqlite, d->pwd, d->pwdLen);
4030  }
4031 #endif
4032  d->pwd = NULL;
4033  d->pwdLen = 0;
4034  if (d->trace) {
4035 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
4036  sqlite3_profile(d->sqlite, dbtrace, d);
4037 #else
4038  sqlite3_trace(d->sqlite, dbtrace, d);
4039 #endif
4040  }
4041  d->step_enable = getbool(sflag);
4042  d->trans_disable = getbool(ntflag);
4043  d->curtype = d->step_enable ?
4044  SQL_CURSOR_FORWARD_ONLY : SQL_CURSOR_STATIC;
4045  tmp = strtol(busy, &endp, 0);
4046  if (endp && *endp == '\0' && endp != busy) {
4047  busyto = tmp;
4048  }
4049  if (busyto < 1 || busyto > 1000000) {
4050  busyto = 1000000;
4051  }
4052  d->timeout = busyto;
4053  freep(&d->dbname);
4054  d->dbname = xstrdup(name);
4055  freep(&d->dsn);
4056  d->dsn = xstrdup(dsn);
4057  if ((rc = setsqliteopts(d->sqlite, d)) != SQLITE_OK) {
4058  if (d->trace) {
4059  fprintf(d->trace, "-- sqlite3_close: '%s'\n",
4060  d->dbname);
4061  fflush(d->trace);
4062  }
4063  sqlite3_close(d->sqlite);
4064  d->sqlite = NULL;
4065  goto connfail;
4066  }
4067  if (!spflag || spflag[0] == '\0') {
4068  spflag = "NORMAL";
4069  }
4070  if (spflag[0] != '\0') {
4071  char syncp[128];
4072 
4073  sprintf(syncp, "PRAGMA synchronous = %8.8s;", spflag);
4074  sqlite3_exec(d->sqlite, syncp, NULL, NULL, NULL);
4075  }
4076  if (jmode[0] != '\0') {
4077  char jourp[128];
4078 
4079  sprintf(jourp, "PRAGMA journal_mode = %16.16s;", jmode);
4080  sqlite3_exec(d->sqlite, jourp, NULL, NULL, NULL);
4081  }
4082  if (d->trace) {
4083  fprintf(d->trace, "-- sqlite3_open: '%s'\n", d->dbname);
4084  fflush(d->trace);
4085  }
4086 #if defined(_WIN32) || defined(_WIN64)
4087  {
4088  char pname[MAX_PATH];
4089  HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
4090  FALSE, GetCurrentProcessId());
4091 
4092  pname[0] = '\0';
4093  if (h) {
4094  HMODULE m = NULL, l = LoadLibrary("psapi.dll");
4095  DWORD need;
4096  typedef BOOL (WINAPI *epmfunc)(HANDLE, HMODULE *, DWORD, LPDWORD);
4097  typedef BOOL (WINAPI *gmbfunc)(HANDLE, HMODULE, LPSTR, DWORD);
4098  epmfunc epm;
4099  gmbfunc gmb;
4100 
4101  if (l) {
4102  epm = (epmfunc) GetProcAddress(l, "EnumProcessModules");
4103  gmb = (gmbfunc) GetProcAddress(l, "GetModuleBaseNameA");
4104  if (epm && gmb && epm(h, &m, sizeof (m), &need)) {
4105  gmb(h, m, pname, sizeof (pname));
4106  }
4107  FreeLibrary(l);
4108  }
4109  CloseHandle(h);
4110  }
4111  d->xcelqrx = strncasecmp(pname, "EXCEL", 5) == 0 ||
4112  strncasecmp(pname, "MSQRY", 5) == 0;
4113  if (d->trace && d->xcelqrx) {
4114 
4115  fprintf(d->trace, "-- enabled EXCEL quirks\n");
4116  fflush(d->trace);
4117  }
4118  }
4119 #endif
4120  sqlite3_create_function(d->sqlite, "blob_import", 1, SQLITE_UTF8,
4121  d, blob_import, 0, 0);
4122  sqlite3_create_function(d->sqlite, "blob_export", 2, SQLITE_UTF8,
4123  d, blob_export, 0, 0);
4124  return SQL_SUCCESS;
4125 }
4126 
4133 static void
4134 dbloadext(DBC *d, char *exts)
4135 {
4136 #if defined(HAVE_SQLITE3LOADEXTENSION) && (HAVE_SQLITE3LOADEXTENSION)
4137  char *p;
4138  char path[SQL_MAX_MESSAGE_LENGTH];
4139  int plen = 0;
4140 
4141  if (!d->sqlite) {
4142  return;
4143  }
4144  sqlite3_enable_load_extension(d->sqlite, 1);
4145 #if defined(_WIN32) || defined(_WIN64)
4146  GetModuleFileName(hModule, path, sizeof (path));
4147  p = strrchr(path, '\\');
4148  plen = p ? ((p + 1) - path) : 0;
4149 #endif
4150  do {
4151  p = strchr(exts, ',');
4152  if (p) {
4153  strncpy(path + plen, exts, p - exts);
4154  path[plen + (p - exts)] = '\0';
4155  } else {
4156  strcpy(path + plen, exts);
4157  }
4158  if (exts[0]) {
4159  char *errmsg = NULL;
4160  int rc;
4161 #if defined(_WIN32) || defined(_WIN64)
4162  char *q;
4163 
4164  q = path + plen;
4165  if (!(q[0] &&
4166  ((q[1] == ':' && (q[2] == '\\' || q[2] == '/')) ||
4167  q[0] == '\\' || q[0] == '/' || q[0] == '.'))) {
4168  q = path;
4169  }
4170  rc = sqlite3_load_extension(d->sqlite, q, 0, &errmsg);
4171 #else
4172  rc = sqlite3_load_extension(d->sqlite, path, 0, &errmsg);
4173 #endif
4174  if (rc != SQLITE_OK) {
4175 #if defined(_WIN32) || defined(_WIN64)
4176  char buf[512], msg[512];
4177 
4178  LoadString(hModule, IDS_EXTERR, buf, sizeof (buf));
4179  wsprintf(msg, buf, q, errmsg ?
4180  errmsg : "no error info available");
4181  LoadString(hModule, IDS_EXTTITLE, buf, sizeof (buf));
4182  MessageBox(NULL, msg, buf,
4183  MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
4184  MB_SETFOREGROUND);
4185 #else
4186  fprintf(stderr, "extension '%s' did not load%s%s\n",
4187  path, errmsg ? ": " : "", errmsg ? errmsg : "");
4188 #endif
4189  }
4190  }
4191  if (p) {
4192  exts = p + 1;
4193  }
4194  } while (p);
4195 #endif /* HAVE_SQLITE3LOADEXTENSION */
4196 }
4197 
4207 static char *
4208 s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
4209 {
4210  char *typename = (char *) sqlite3_column_decltype(s3stmt, col);
4211  char guess[64];
4212 
4213  guess[0] = '\0';
4214  if (!typename) {
4215  int coltype = sqlite3_column_type(s3stmt, col);
4216 
4217  if (guessed_types) {
4218  guessed_types[0]++;
4219  }
4220  if (d->trace) {
4221  sprintf(guess, " (guessed from %d)", coltype);
4222  }
4223  switch (coltype) {
4224  case SQLITE_INTEGER: typename = "integer"; break;
4225  case SQLITE_FLOAT: typename = "double"; break;
4226  default:
4227  case SQLITE_TEXT: typename = "varchar"; break;
4228  case SQLITE_BLOB: typename = "blob"; break;
4229 #if 0
4230  case SQLITE_NULL: typename = "null"; break;
4231 #endif
4232  }
4233  }
4234  if (d->trace) {
4235  fprintf(d->trace, "-- column %d type%s: '%s'\n", col + 1,
4236  guess, typename);
4237  fflush(d->trace);
4238  }
4239  return typename;
4240 }
4241 
4242 #ifdef FULL_METADATA
4243 
4252 static void
4253 s3stmt_addmeta(sqlite3_stmt *s3stmt, int col, DBC *d, COL *ci)
4254 {
4255  int nn = 0, pk = 0, ai = 0;
4256  const char *dn = NULL, *tn = NULL, *cn = NULL, *dummy[4];
4257 
4258  dn = sqlite3_column_database_name(s3stmt, col);
4259  tn = sqlite3_column_table_name(s3stmt, col);
4260  cn = sqlite3_column_origin_name(s3stmt, col);
4261  dummy[0] = dummy[1] = 0;
4262  if (tn && cn) {
4263  sqlite3_table_column_metadata(d->sqlite, dn, tn, cn,
4264  dummy, dummy + 1,
4265  &nn, &pk, &ai);
4266  }
4267  ci->autoinc = ai ? SQL_TRUE: SQL_FALSE;
4268  ci->notnull = nn ? SQL_NO_NULLS : SQL_NULLABLE;
4269  ci->ispk = pk ? 1 : 0;
4270  if (d->trace) {
4271  fprintf(d->trace, "-- column %d %s\n",
4272  col + 1, nn ? "notnull" : "nullable");
4273  if (ai) {
4274  fprintf(d->trace, "-- column %d autoincrement\n", col + 1);
4275  }
4276  fflush(d->trace);
4277  }
4278  ci->isrowid = 0;
4279  if (ci->ispk && tn) {
4280  nn = pk = ai = 0;
4281  dummy[2] = dummy[3] = 0;
4282 
4283  sqlite3_table_column_metadata(d->sqlite, dn, tn, "rowid",
4284  dummy + 2, dummy + 3,
4285  &nn, &pk, &ai);
4286  if (pk && dummy[0] && dummy[0] == dummy[2]) {
4287  ci->isrowid = 1;
4288  }
4289  }
4290 }
4291 
4292 #endif
4293 
4300 static int
4302 {
4303  DBC *d = (DBC *) s->dbc;
4304  char **rowd = NULL;
4305  const char *errp = NULL;
4306  int i, ncols, rc;
4307 
4308  if (s != d->cur_s3stmt || !s->s3stmt) {
4309  setstat(s, -1, "stale statement", (*s->ov3) ? "HY000" : "S1000");
4310  return SQL_ERROR;
4311  }
4312  rc = sqlite3_step(s->s3stmt);
4313  if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
4314  ++s->s3stmt_rownum;
4315  ncols = sqlite3_column_count(s->s3stmt);
4316  if (d->s3stmt_needmeta && s->s3stmt_rownum == 0 && ncols > 0) {
4317  PTRDIFF_T size;
4318  char *p;
4319  COL *dyncols;
4320  const char *colname, *typename;
4321 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4322  char *tblname;
4323 #endif
4324 
4325  for (i = size = 0; i < ncols; i++) {
4326  colname = sqlite3_column_name(s->s3stmt, i);
4327  size += 3 + 3 * strlen(colname);
4328  }
4329 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4330  tblname = (char *) size;
4331  for (i = 0; i < ncols; i++) {
4332  p = (char *) sqlite3_column_table_name(s->s3stmt, i);
4333  size += 2 + (p ? strlen(p) : 0);
4334  }
4335 #endif
4336  dyncols = xmalloc(ncols * sizeof (COL) + size);
4337  if (!dyncols) {
4338  freedyncols(s);
4339  s->ncols = 0;
4340  dbtraceapi(d, "sqlite3_finalize", 0);
4341  sqlite3_finalize(s->s3stmt);
4342  s->s3stmt = NULL;
4343  d->cur_s3stmt = NULL;
4344  return nomem(s);
4345  }
4346  p = (char *) (dyncols + ncols);
4347 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4348  tblname = p + (PTRDIFF_T) tblname;
4349 #endif
4350  for (i = 0; i < ncols; i++) {
4351  char *q;
4352 
4353  colname = sqlite3_column_name(s->s3stmt, i);
4354  if (d->trace) {
4355  fprintf(d->trace, "-- column %d name: '%s'\n",
4356  i + 1, colname);
4357  fflush(d->trace);
4358  }
4359 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
4360  q = (char *) sqlite3_column_table_name(s->s3stmt, i);
4361  strcpy(tblname, q ? q : "");
4362  if (d->trace) {
4363  fprintf(d->trace, "-- table %d name: '%s'\n",
4364  i + 1, tblname);
4365  fflush(d->trace);
4366  }
4367  dyncols[i].table = tblname;
4368  tblname += strlen(tblname) + 1;
4369 #endif
4370  typename = s3stmt_coltype(s->s3stmt, i, d, 0);
4371  dyncols[i].db = ((DBC *) (s->dbc))->dbname;
4372  strcpy(p, colname);
4373  dyncols[i].label = p;
4374  p += strlen(p) + 1;
4375  q = strchr(colname, '.');
4376  if (q) {
4377  char *q2 = strchr(q + 1, '.');
4378 
4379  /* SQLite 3.3.4 produces view.table.column sometimes */
4380  if (q2) {
4381  q = q2;
4382  }
4383  }
4384  if (q) {
4385 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
4386  dyncols[i].table = p;
4387 #endif
4388  strncpy(p, colname, q - colname);
4389  p[q - colname] = '\0';
4390  p += strlen(p) + 1;
4391  strcpy(p, q + 1);
4392  dyncols[i].column = p;
4393  p += strlen(p) + 1;
4394  } else {
4395 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
4396  dyncols[i].table = "";
4397 #endif
4398  strcpy(p, colname);
4399  dyncols[i].column = p;
4400  p += strlen(p) + 1;
4401  }
4402  if (s->longnames) {
4403  dyncols[i].column = dyncols[i].label;
4404  }
4405 #ifdef SQL_LONGVARCHAR
4406  dyncols[i].type = SQL_LONGVARCHAR;
4407  dyncols[i].size = 65535;
4408 #else
4409  dyncols[i].type = SQL_VARCHAR;
4410  dyncols[i].size = 255;
4411 #endif
4412  dyncols[i].index = i;
4413  dyncols[i].scale = 0;
4414  dyncols[i].prec = 0;
4415  dyncols[i].nosign = 1;
4416  dyncols[i].autoinc = SQL_FALSE;
4417  dyncols[i].notnull = SQL_NULLABLE;
4418  dyncols[i].ispk = -1;
4419  dyncols[i].isrowid = -1;
4420 #ifdef FULL_METADATA
4421  s3stmt_addmeta(s->s3stmt, i, d, &dyncols[i]);
4422 #endif
4423  dyncols[i].typename = xstrdup(typename);
4424  }
4425  freedyncols(s);
4426  s->ncols = s->dcols = ncols;
4427  s->dyncols = s->cols = dyncols;
4428  fixupdyncols(s, d);
4429  mkbindcols(s, s->ncols);
4430  d->s3stmt_needmeta = 0;
4431  }
4432  if (ncols <= 0) {
4433  goto killstmt;
4434  }
4435  if (rc == SQLITE_DONE) {
4436  freeresult(s, 0);
4437  s->nrows = 0;
4438  dbtraceapi(d, "sqlite3_finalize", 0);
4439  sqlite3_finalize(s->s3stmt);
4440  s->s3stmt = NULL;
4441  d->cur_s3stmt = NULL;
4442  return SQL_SUCCESS;
4443  }
4444  rowd = xmalloc((1 + 2 * ncols) * sizeof (char *));
4445  if (rowd) {
4446  const unsigned char *value;
4447 
4448  rowd[0] = (char *) ((PTRDIFF_T) (ncols * 2));
4449  ++rowd;
4450  for (i = 0; i < ncols; i++) {
4451  int coltype = sqlite3_column_type(s->s3stmt, i);
4452 
4453  rowd[i] = rowd[i + ncols] = NULL;
4454  if (coltype == SQLITE_BLOB) {
4455  int k, nbytes = sqlite3_column_bytes(s->s3stmt, i);
4456  char *qp;
4457  unsigned const char *bp;
4458 
4459  bp = sqlite3_column_blob(s->s3stmt, i);
4460  qp = xmalloc(nbytes * 2 + 4);
4461  if (qp) {
4462  rowd[i + ncols] = qp;
4463  *qp++ = 'X';
4464  *qp++ = '\'';
4465  for (k = 0; k < nbytes; k++) {
4466  *qp++ = xdigits[(bp[k] >> 4)];
4467  *qp++ = xdigits[(bp[k] & 0xF)];
4468  }
4469  *qp++ = '\'';
4470  *qp = '\0';
4471  }
4472 #ifdef _MSC_VER
4473  } else if (coltype == SQLITE_FLOAT) {
4474  static struct lconv *lc = 0;
4475  double d = sqlite3_column_double(s->s3stmt, i);
4476  char *p, buffer[128];
4477 
4478  /*
4479  * This avoids floating point rounding
4480  * and formatting problems of some SQLite
4481  * versions in conjunction with MSVC 2010.
4482  */
4483  snprintf(buffer, sizeof (buffer), "%.15g", d);
4484  if (!lc) {
4485  lc = localeconv();
4486  }
4487  if (lc && lc->decimal_point && lc->decimal_point[0] &&
4488  lc->decimal_point[0] != '.') {
4489  p = strchr(buffer, lc->decimal_point[0]);
4490  if (p) {
4491  *p = '.';
4492  }
4493  }
4494  rowd[i + ncols] = xstrdup(buffer);
4495 #endif
4496  } else if (coltype != SQLITE_NULL) {
4497  value = sqlite3_column_text(s->s3stmt, i);
4498  rowd[i + ncols] = xstrdup((char *) value);
4499  }
4500  }
4501  for (i = 0; i < ncols; i++) {
4502  int coltype = sqlite3_column_type(s->s3stmt, i);
4503 
4504  value = NULL;
4505  if (coltype == SQLITE_BLOB) {
4506  value = sqlite3_column_blob(s->s3stmt, i);
4507  } else if (coltype != SQLITE_NULL) {
4508  value = sqlite3_column_text(s->s3stmt, i);
4509  }
4510  if (value && !rowd[i + ncols]) {
4511  freerows(rowd);
4512  rowd = 0;
4513  break;
4514  }
4515  }
4516  }
4517  if (rowd) {
4518  freeresult(s, 0);
4519  s->nrows = 1;
4520  s->rows = rowd;
4521  s->rowfree = freerows;
4522  if (rc == SQLITE_DONE) {
4523  dbtraceapi(d, "sqlite3_finalize", 0);
4524  sqlite3_finalize(s->s3stmt);
4525  s->s3stmt = NULL;
4526  d->cur_s3stmt = NULL;
4527  }
4528  return SQL_SUCCESS;
4529  }
4530  }
4531 killstmt:
4532  dbtraceapi(d, "sqlite3_reset", 0);
4533  rc = sqlite3_reset(s->s3stmt);
4534  s->s3stmt_noreset = 1;
4535  errp = sqlite3_errmsg(d->sqlite);
4536  if (d->cur_s3stmt == s) {
4537  d->cur_s3stmt = NULL;
4538  }
4539  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
4540  errp ? errp : "unknown error", rc);
4541  return SQL_ERROR;
4542 }
4543 
4549 static void
4551 {
4552  DBC *d;
4553 
4554  if (!s || !s->s3stmt) {
4555  return;
4556  }
4557  d = (DBC *) s->dbc;
4558  if (d) {
4559  d->busyint = 0;
4560  }
4561  if (!s->s3stmt_noreset) {
4562  dbtraceapi(d, "sqlite3_reset", 0);
4563  sqlite3_reset(s->s3stmt);
4564  s->s3stmt_noreset = 1;
4565  s->s3stmt_rownum = -1;
4566  }
4567  if (d->cur_s3stmt == s) {
4568  d->cur_s3stmt = NULL;
4569  }
4570 }
4571 
4577 static void
4579 {
4580  DBC *d = (DBC *) s->dbc;
4581 
4582  if (d) {
4583  d->busyint = 0;
4584  }
4585  if (d && d->cur_s3stmt == s) {
4586  s3stmt_end(s);
4587  }
4588 }
4589 
4595 static void
4597 {
4598  if (s->s3stmt) {
4599  DBC *d = (DBC *) s->dbc;
4600 
4601  if (d) {
4602  dbtraceapi(d, "sqlite3_finalize", 0);
4603  }
4604  sqlite3_finalize(s->s3stmt);
4605  s->s3stmt = NULL;
4606  s->s3stmt_rownum = 0;
4607  }
4608 }
4609 
4616 static SQLRETURN
4618 {
4619  DBC *d = (DBC *) s->dbc;
4620  const char *endp;
4621  sqlite3_stmt *s3stmt = NULL;
4622  int rc, nretry = 0;
4623 
4624  d->s3stmt_needmeta = 0;
4625  if (!s->s3stmt) {
4626 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
4627  dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
4628 #else
4629  dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
4630 #endif
4631  do {
4632  s3stmt = NULL;
4633 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
4634  rc = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
4635  &s3stmt, &endp);
4636 #else
4637  rc = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
4638  &s3stmt, &endp);
4639 #endif
4640  if (rc != SQLITE_OK) {
4641  if (s3stmt) {
4642  sqlite3_finalize(s3stmt);
4643  s3stmt = NULL;
4644  }
4645  }
4646  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
4647  dbtracerc(d, rc, NULL);
4648  if (rc != SQLITE_OK) {
4649  if (s3stmt) {
4650  dbtraceapi(d, "sqlite3_finalize", NULL);
4651  sqlite3_finalize(s3stmt);
4652  }
4653  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
4654  sqlite3_errmsg(d->sqlite), rc);
4655  return SQL_ERROR;
4656  }
4657  if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
4658  dbtraceapi(d, "sqlite3_finalize", 0);
4659  sqlite3_finalize(s3stmt);
4660  setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
4661  (*s->ov3) ? "HY000" : "S1000");
4662  return SQL_ERROR;
4663  }
4664  s->s3stmt = s3stmt;
4665  s->s3stmt_noreset = 1;
4666  d->s3stmt_needmeta = 1;
4667  }
4668  d->cur_s3stmt = s;
4669  s->s3stmt_rownum = -1;
4670  s3bind(d, s->s3stmt, s->nparams, s->bindparms);
4671  return SQL_SUCCESS;
4672 }
4673 
4674 #ifndef WINTERFACE
4675 
4679 SQLRETURN SQL_API
4680 SQLDataSources(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *srvname,
4681  SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
4682  SQLCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
4683 {
4684  if (env == SQL_NULL_HENV) {
4685  return SQL_INVALID_HANDLE;
4686  }
4687  return SQL_ERROR;
4688 }
4689 #endif
4690 
4691 #ifdef WINTERFACE
4692 
4696 SQLRETURN SQL_API
4697 SQLDataSourcesW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *srvname,
4698  SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
4699  SQLWCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
4700 {
4701  if (env == SQL_NULL_HENV) {
4702  return SQL_INVALID_HANDLE;
4703  }
4704  return SQL_ERROR;
4705 }
4706 #endif
4707 
4708 #ifndef WINTERFACE
4709 
4713 SQLRETURN SQL_API
4714 SQLDrivers(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *drvdesc,
4715  SQLSMALLINT descmax, SQLSMALLINT *desclenp,
4716  SQLCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
4717 {
4718  if (env == SQL_NULL_HENV) {
4719  return SQL_INVALID_HANDLE;
4720  }
4721  return SQL_ERROR;
4722 }
4723 #endif
4724 
4725 #ifdef WINTERFACE
4726 
4730 SQLRETURN SQL_API
4731 SQLDriversW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *drvdesc,
4732  SQLSMALLINT descmax, SQLSMALLINT *desclenp,
4733  SQLWCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
4734 {
4735  if (env == SQL_NULL_HENV) {
4736  return SQL_INVALID_HANDLE;
4737  }
4738  return SQL_ERROR;
4739 }
4740 #endif
4741 
4742 #ifndef WINTERFACE
4743 
4747 SQLRETURN SQL_API
4748 SQLBrowseConnect(SQLHDBC dbc, SQLCHAR *connin, SQLSMALLINT conninLen,
4749  SQLCHAR *connout, SQLSMALLINT connoutMax,
4750  SQLSMALLINT *connoutLen)
4751 {
4752  SQLRETURN ret;
4753 
4754  HDBC_LOCK(dbc);
4755  ret = drvunimpldbc(dbc);
4756  HDBC_UNLOCK(dbc);
4757  return ret;
4758 }
4759 #endif
4760 
4761 #ifdef WINTERFACE
4762 
4766 SQLRETURN SQL_API
4767 SQLBrowseConnectW(SQLHDBC dbc, SQLWCHAR *connin, SQLSMALLINT conninLen,
4768  SQLWCHAR *connout, SQLSMALLINT connoutMax,
4769  SQLSMALLINT *connoutLen)
4770 {
4771  SQLRETURN ret;
4772 
4773  HDBC_LOCK(dbc);
4774  ret = drvunimpldbc(dbc);
4775  HDBC_UNLOCK(dbc);
4776  return ret;
4777 }
4778 #endif
4779 
4788 static SQLRETURN
4789 drvputdata(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
4790 {
4791  STMT *s;
4792  int i, dlen, done = 0;
4793  BINDPARM *p;
4794 
4795  if (stmt == SQL_NULL_HSTMT) {
4796  return SQL_INVALID_HANDLE;
4797  }
4798  s = (STMT *) stmt;
4799  if (!s->query || s->nparams <= 0) {
4800 seqerr:
4801  setstat(s, -1, "sequence error", "HY010");
4802  return SQL_ERROR;
4803  }
4804  for (i = (s->pdcount < 0) ? 0 : s->pdcount; i < s->nparams; i++) {
4805  p = &s->bindparms[i];
4806  if (p->need > 0) {
4807  int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
4808 
4809  if (len == SQL_NULL_DATA) {
4810  freep(&p->parbuf);
4811  p->param = NULL;
4812  p->len = SQL_NULL_DATA;
4813  p->need = -1;
4814  } else if (type != SQL_C_CHAR
4815 #ifdef WCHARSUPPORT
4816  && type != SQL_C_WCHAR
4817 #endif
4818  && type != SQL_C_BINARY) {
4819  int size = 0;
4820 
4821  switch (type) {
4822  case SQL_C_TINYINT:
4823  case SQL_C_UTINYINT:
4824  case SQL_C_STINYINT:
4825 #ifdef SQL_BIT
4826  case SQL_C_BIT:
4827 #endif
4828  size = sizeof (SQLCHAR);
4829  break;
4830  case SQL_C_SHORT:
4831  case SQL_C_USHORT:
4832  case SQL_C_SSHORT:
4833  size = sizeof (SQLSMALLINT);
4834  break;
4835  case SQL_C_LONG:
4836  case SQL_C_ULONG:
4837  case SQL_C_SLONG:
4838  size = sizeof (SQLINTEGER);
4839  break;
4840 #ifdef SQL_BIGINT
4841  case SQL_C_UBIGINT:
4842  case SQL_C_SBIGINT:
4843  size = sizeof (SQLBIGINT);
4844  break;
4845 #endif
4846  case SQL_C_FLOAT:
4847  size = sizeof (float);
4848  break;
4849  case SQL_C_DOUBLE:
4850  size = sizeof (double);
4851  break;
4852 #ifdef SQL_C_TYPE_DATE
4853  case SQL_C_TYPE_DATE:
4854 #endif
4855  case SQL_C_DATE:
4856  size = sizeof (DATE_STRUCT);
4857  break;
4858 #ifdef SQL_C_TYPE_DATE
4859  case SQL_C_TYPE_TIME:
4860 #endif
4861  case SQL_C_TIME:
4862  size = sizeof (TIME_STRUCT);
4863  break;
4864 #ifdef SQL_C_TYPE_DATE
4865  case SQL_C_TYPE_TIMESTAMP:
4866 #endif
4867  case SQL_C_TIMESTAMP:
4868  size = sizeof (TIMESTAMP_STRUCT);
4869  break;
4870  }
4871  freep(&p->parbuf);
4872  p->parbuf = xmalloc(size);
4873  if (!p->parbuf) {
4874  return nomem(s);
4875  }
4876  p->param = p->parbuf;
4877  memcpy(p->param, data, size);
4878  p->len = size;
4879  p->need = -1;
4880  } else if (len == SQL_NTS && (
4881  type == SQL_C_CHAR
4882 #ifdef WCHARSUPPORT
4883  || type == SQL_C_WCHAR
4884 #endif
4885  )) {
4886  char *dp = data;
4887 
4888 #ifdef WCHARSUPPORT
4889  if (type == SQL_C_WCHAR) {
4890  dp = uc_to_utf(data, len);
4891  if (!dp) {
4892  return nomem(s);
4893  }
4894  }
4895 #endif
4896 #if defined(_WIN32) || defined(_WIN64)
4897  if (*s->oemcp) {
4898  dp = wmb_to_utf(data, strlen (data));
4899  if (!dp) {
4900  return nomem(s);
4901  }
4902  }
4903 #endif
4904  dlen = strlen(dp);
4905  freep(&p->parbuf);
4906  p->parbuf = xmalloc(dlen + 1);
4907  if (!p->parbuf) {
4908  if (dp != data) {
4909  uc_free(dp);
4910  }
4911  return nomem(s);
4912  }
4913  p->param = p->parbuf;
4914  strcpy(p->param, dp);
4915  if (dp != data) {
4916  uc_free(dp);
4917  }
4918  p->len = dlen;
4919  p->need = -1;
4920  } else if (len < 0) {
4921  setstat(s, -1, "invalid length", "HY090");
4922  return SQL_ERROR;
4923  } else {
4924  dlen = min(p->len - p->offs, len);
4925  if (!p->param) {
4926  setstat(s, -1, "no memory for parameter", "HY013");
4927  return SQL_ERROR;
4928  }
4929  memcpy((char *) p->param + p->offs, data, dlen);
4930  p->offs += dlen;
4931  if (p->offs >= p->len) {
4932 #ifdef WCHARSUPPORT
4933  if (type == SQL_C_WCHAR) {
4934  char *dp = uc_to_utf(p->param, p->len);
4935  char *np;
4936  int nlen;
4937 
4938  if (!dp) {
4939  return nomem(s);
4940  }
4941  nlen = strlen(dp);
4942  np = xmalloc(nlen + 1);
4943  if (!np) {
4944  uc_free(dp);
4945  return nomem(s);
4946  }
4947  strcpy(np, dp);
4948  uc_free(dp);
4949  if (p->param == p->parbuf) {
4950  freep(&p->parbuf);
4951  }
4952  p->parbuf = p->param = np;
4953  p->len = nlen;
4954  } else {
4955  *((char *) p->param + p->len) = '\0';
4956  }
4957  p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR)
4958  ? -1 : 0;
4959 #else
4960  *((char *) p->param + p->len) = '\0';
4961  p->need = (type == SQL_C_CHAR) ? -1 : 0;
4962 #endif
4963 #if defined(_WIN32) || defined(_WIN64)
4964  if (type == SQL_C_CHAR && *s->oemcp &&
4965  !(p->stype == SQL_BINARY ||
4966  p->stype == SQL_VARBINARY ||
4967  p->stype == SQL_LONGVARBINARY)) {
4968  char *dp = wmb_to_utf(p->param, p->len);
4969 
4970  if (!dp) {
4971  return nomem(s);
4972  }
4973  if (p->param == p->parbuf) {
4974  freep(&p->parbuf);
4975  }
4976  p->parbuf = p->param = dp;
4977  p->len = strlen(dp);
4978  }
4979  if (p->type == SQL_C_WCHAR &&
4980  (p->stype == SQL_VARCHAR ||
4981  p->stype == SQL_LONGVARCHAR) &&
4982  p->len == p->coldef * sizeof (SQLWCHAR)) {
4983  /* fix for MS-Access */
4984  p->len = p->coldef;
4985  }
4986 #endif
4987  }
4988  }
4989  done = 1;
4990  break;
4991  }
4992  }
4993  if (!done) {
4994  goto seqerr;
4995  }
4996  return SQL_SUCCESS;
4997 }
4998 
5007 SQLRETURN SQL_API
5008 SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
5009 {
5010  SQLRETURN ret;
5011 
5012  HSTMT_LOCK(stmt);
5013  ret = drvputdata(stmt, data, len);
5014  HSTMT_UNLOCK(stmt);
5015  return ret;
5016 }
5017 
5023 static SQLRETURN
5025 {
5026  if (s->bindparms) {
5027  int n;
5028 
5029  for (n = 0; n < s->nbindparms; n++) {
5030  freep(&s->bindparms[n].parbuf);
5031  memset(&s->bindparms[n], 0, sizeof (BINDPARM));
5032  }
5033  }
5034  return SQL_SUCCESS;
5035 }
5036 
5048 static SQLRETURN
5049 setupparam(STMT *s, char *sql, int pnum)
5050 {
5051  int type, len = 0, needalloc = 0;
5052  BINDPARM *p;
5053 
5054  if (!s->bindparms || pnum < 0 || pnum >= s->nbindparms) {
5055  goto error;
5056  }
5057  p = &s->bindparms[pnum];
5058  type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
5059 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
5060  /* MS Access hack part 4 (map SQL_C_DEFAULT to SQL_C_CHAR) */
5061  if (type == SQL_C_WCHAR && p->type == SQL_C_DEFAULT) {
5062  type = SQL_C_CHAR;
5063  }
5064 #endif
5065  if (p->need > 0) {
5066  return setupparbuf(s, p);
5067  }
5068  p->strbuf[0] = '\0';
5069  if (!p->param || (p->lenp && *p->lenp == SQL_NULL_DATA)) {
5070  p->s3type = SQLITE_NULL;
5071  p->s3size = 0;
5072  return SQL_SUCCESS;
5073  }
5074  if (type == SQL_C_CHAR &&
5075  (p->stype == SQL_BINARY ||
5076  p->stype == SQL_VARBINARY ||
5077  p->stype == SQL_LONGVARBINARY)) {
5078  type = SQL_C_BINARY;
5079  }
5080  switch (type) {
5081  case SQL_C_BINARY:
5082  p->s3type = SQLITE_BLOB;
5083  p->s3size = p->len;
5084  p->s3val = p->param;
5085  if (p->need < 0) {
5086  break;
5087  }
5088  if (!p->lenp) {
5089  len = p->len;
5090  } else if (*p->lenp == SQL_DATA_AT_EXEC) {
5091  len = p->len;
5092  } else {
5093  len = *p->lenp;
5094  if (len <= SQL_LEN_DATA_AT_EXEC_OFFSET) {
5095  len = SQL_LEN_DATA_AT_EXEC(len);
5096  }
5097  }
5098  if (len < 0) {
5099  setstat(s, -1, "invalid length", "HY009");
5100  return SQL_ERROR;
5101  }
5102  p->len = len;
5103  p->max = p->len;
5104  p->need = -1;
5105  p->s3size = len;
5106  break;
5107 #ifdef WCHARSUPPORT
5108  case SQL_C_WCHAR:
5109 #endif
5110  case SQL_C_CHAR:
5111  p->s3type = SQLITE_TEXT;
5112  p->s3size = -1;
5113  p->s3val = p->param;
5114  if (!p->parbuf) {
5115 #ifdef WCHARSUPPORT
5116  if (type == SQL_C_WCHAR) {
5117  if (!p->lenp || *p->lenp == SQL_NTS) {
5118  p->max = uc_strlen(p->param) * sizeof (SQLWCHAR);
5119  } else if (*p->lenp >= 0) {
5120  p->max = *p->lenp;
5121  }
5122  } else
5123 #endif
5124  if (type == SQL_C_CHAR) {
5125  if (!p->lenp || *p->lenp == SQL_NTS) {
5126  p->len = p->max = strlen(p->param);
5127 #if defined(_WIN32) || defined(_WIN64)
5128  needalloc = 1;
5129 #endif
5130  } else if (*p->lenp >= 0) {
5131  p->len = p->max = *p->lenp;
5132  needalloc = 1;
5133  }
5134  }
5135  }
5136  if (p->need < 0 && p->parbuf == p->param) {
5137  break;
5138  }
5139 #ifdef WCHARSUPPORT
5140  if (type == SQL_C_WCHAR) {
5141  char *dp = uc_to_utf(p->param, p->max);
5142 
5143  if (!dp) {
5144  return nomem(s);
5145  }
5146  if (p->param == p->parbuf) {
5147  freep(&p->parbuf);
5148  }
5149  p->parbuf = p->param = dp;
5150  p->need = -1;
5151  p->len = strlen(p->param);
5152  p->s3val = p->param;
5153  p->s3size = p->len;
5154  } else
5155 #endif
5156  if (type == SQL_C_CHAR) {
5157  p->s3val = p->param;
5158  if (needalloc) {
5159  char *dp;
5160 
5161 #if defined(_WIN32) || defined(_WIN64)
5162  if (*s->oemcp) {
5163  dp = wmb_to_utf(p->param, p->len);
5164  } else {
5165  dp = xmalloc(p->len + 1);
5166  }
5167 #else
5168  dp = xmalloc(p->len + 1);
5169 #endif
5170  if (!dp) {
5171  return nomem(s);
5172  }
5173 #if defined(_WIN32) || defined(_WIN64)
5174  if (*s->oemcp) {
5175  p->len = strlen(dp);
5176  } else {
5177  memcpy(dp, p->param, p->len);
5178  dp[p->len] = '\0';
5179  }
5180 #else
5181  memcpy(dp, p->param, p->len);
5182  dp[p->len] = '\0';
5183 #endif
5184  if (p->param == p->parbuf) {
5185  freep(&p->parbuf);
5186  }
5187  p->parbuf = p->param = dp;
5188  p->need = -1;
5189  p->s3val = p->param;
5190  p->s3size = p->len;
5191  }
5192  }
5193  break;
5194  case SQL_C_UTINYINT:
5195  case SQL_C_TINYINT:
5196  case SQL_C_STINYINT:
5197  p->s3type = SQLITE_INTEGER;
5198  p->s3size = sizeof (int);
5199  p->s3ival = *((SQLCHAR *) p->param);
5200  break;
5201  case SQL_C_USHORT:
5202  p->s3type = SQLITE_INTEGER;
5203  p->s3size = sizeof (int);
5204  p->s3ival = *((SQLUSMALLINT *) p->param);
5205  break;
5206  case SQL_C_SHORT:
5207  case SQL_C_SSHORT:
5208  p->s3type = SQLITE_INTEGER;
5209  p->s3size = sizeof (int);
5210  p->s3ival = *((SQLSMALLINT *) p->param);
5211  break;
5212  case SQL_C_ULONG:
5213  p->s3type = SQLITE_INTEGER;
5214  p->s3size = sizeof (int);
5215  p->s3ival = *((SQLUINTEGER *) p->param);
5216  break;
5217  case SQL_C_LONG:
5218  case SQL_C_SLONG:
5219  p->s3type = SQLITE_INTEGER;
5220  p->s3size = sizeof (int);
5221  p->s3ival = *((SQLINTEGER *) p->param);
5222  break;
5223 #ifdef SQL_BIT
5224  case SQL_C_BIT:
5225  p->s3type = SQLITE_INTEGER;
5226  p->s3size = sizeof (int);
5227  p->s3ival = (*((SQLCHAR *) p->param)) ? 1 : 0;
5228  break;
5229 #endif
5230 #ifdef SQL_BIGINT
5231  case SQL_C_SBIGINT:
5232  p->s3type = SQLITE_INTEGER;
5233  p->s3size = sizeof (sqlite_int64);
5234  p->s3lival = *((sqlite_int64 *) p->param);
5235  break;
5236  case SQL_C_UBIGINT:
5237  p->s3type = SQLITE_INTEGER;
5238  p->s3size = sizeof (sqlite_int64);
5239  p->s3lival = *((sqlite_uint64 *) p->param);
5240  break;
5241 #endif
5242  case SQL_C_FLOAT:
5243  p->s3type = SQLITE_FLOAT;
5244  p->s3size = sizeof (double);
5245  p->s3dval = *((float *) p->param);
5246  break;
5247  case SQL_C_DOUBLE:
5248  p->s3type = SQLITE_FLOAT;
5249  p->s3size = sizeof (double);
5250  p->s3dval = *((double *) p->param);
5251  break;
5252 #ifdef SQL_C_TYPE_DATE
5253  case SQL_C_TYPE_DATE:
5254 #endif
5255  case SQL_C_DATE:
5256  if (*s->jdconv) {
5257  int a, b, x1, x2, y, m, d;
5258 
5259  p->s3type = SQLITE_FLOAT;
5260  p->s3size = sizeof (double);
5261  y = ((DATE_STRUCT *) p->param)->year;
5262  m = ((DATE_STRUCT *) p->param)->month;
5263  d = ((DATE_STRUCT *) p->param)->day;
5264  if (m <= 2) {
5265  y--;
5266  m += 12;
5267  }
5268  a = y / 100;
5269  b = 2 - a + (a / 4);
5270  x1 = 36525 * (y + 4716) / 100;
5271  x2 = 306001 * (m + 1) / 10000;
5272  p->s3dval = x1 + x2 + d + b - 1524.5;
5273  break;
5274  }
5275  sprintf(p->strbuf, "%04d-%02d-%02d",
5276  ((DATE_STRUCT *) p->param)->year,
5277  ((DATE_STRUCT *) p->param)->month,
5278  ((DATE_STRUCT *) p->param)->day);
5279  p->s3type = SQLITE_TEXT;
5280  p->s3size = -1;
5281  p->s3val = p->strbuf;
5282  break;
5283 #ifdef SQL_C_TYPE_TIME
5284  case SQL_C_TYPE_TIME:
5285 #endif
5286  case SQL_C_TIME:
5287  if (*s->jdconv) {
5288  p->s3type = SQLITE_FLOAT;
5289  p->s3size = sizeof (double);
5290  p->s3dval = 2451544.5 +
5291  (((TIME_STRUCT *) p->param)->hour * 3600000.0 +
5292  ((TIME_STRUCT *) p->param)->minute * 60000.0 +
5293  ((TIME_STRUCT *) p->param)->second * 1000.0) / 86400000.0;
5294  break;
5295  }
5296  sprintf(p->strbuf, "%02d:%02d:%02d",
5297  ((TIME_STRUCT *) p->param)->hour,
5298  ((TIME_STRUCT *) p->param)->minute,
5299  ((TIME_STRUCT *) p->param)->second);
5300  p->s3type = SQLITE_TEXT;
5301  p->s3size = -1;
5302  p->s3val = p->strbuf;
5303  break;
5304 #ifdef SQL_C_TYPE_TIMESTAMP
5305  case SQL_C_TYPE_TIMESTAMP:
5306 #endif
5307  case SQL_C_TIMESTAMP:
5308  if (*s->jdconv) {
5309  int a, b, x1, x2, y, m, d;
5310 
5311  p->s3type = SQLITE_FLOAT;
5312  p->s3size = sizeof (double);
5313  y = ((TIMESTAMP_STRUCT *) p->param)->year;
5314  m = ((TIMESTAMP_STRUCT *) p->param)->month;
5315  d = ((TIMESTAMP_STRUCT *) p->param)->day;
5316  if (m <= 2) {
5317  y--;
5318  m += 12;
5319  }
5320  a = y / 100;
5321  b = 2 - a + (a / 4);
5322  x1 = 36525 * (y + 4716) / 100;
5323  x2 = 306001 * (m + 1) / 10000;
5324  p->s3dval = x1 + x2 + d + b - 1524.5 +
5325  (((TIMESTAMP_STRUCT *) p->param)->hour * 3600000.0 +
5326  ((TIMESTAMP_STRUCT *) p->param)->minute * 60000.0 +
5327  ((TIMESTAMP_STRUCT *) p->param)->second * 1000.0 +
5328  ((TIMESTAMP_STRUCT *) p->param)->fraction / 1.0E6)
5329  / 86400000.0;
5330  break;
5331  }
5332  len = (int) ((TIMESTAMP_STRUCT *) p->param)->fraction;
5333  len /= 1000000;
5334  len = len % 1000;
5335  if (len < 0) {
5336  len = 0;
5337  }
5338  if (p->coldef && p->coldef <= 16) {
5339  sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
5340  ((TIMESTAMP_STRUCT *) p->param)->year,
5341  ((TIMESTAMP_STRUCT *) p->param)->month,
5342  ((TIMESTAMP_STRUCT *) p->param)->day,
5343  ((TIMESTAMP_STRUCT *) p->param)->hour,
5344  ((TIMESTAMP_STRUCT *) p->param)->minute);
5345  } else if (p->coldef && p->coldef <= 19) {
5346  sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
5347  ((TIMESTAMP_STRUCT *) p->param)->year,
5348  ((TIMESTAMP_STRUCT *) p->param)->month,
5349  ((TIMESTAMP_STRUCT *) p->param)->day,
5350  ((TIMESTAMP_STRUCT *) p->param)->hour,
5351  ((TIMESTAMP_STRUCT *) p->param)->minute,
5352  ((TIMESTAMP_STRUCT *) p->param)->second);
5353  } else {
5354  sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
5355  ((TIMESTAMP_STRUCT *) p->param)->year,
5356  ((TIMESTAMP_STRUCT *) p->param)->month,
5357  ((TIMESTAMP_STRUCT *) p->param)->day,
5358  ((TIMESTAMP_STRUCT *) p->param)->hour,
5359  ((TIMESTAMP_STRUCT *) p->param)->minute,
5360  ((TIMESTAMP_STRUCT *) p->param)->second,
5361  len);
5362  }
5363  p->s3type = SQLITE_TEXT;
5364  p->s3size = -1;
5365  p->s3val = p->strbuf;
5366  break;
5367  default:
5368  error:
5369  setstat(s, -1, "unsupported parameter type",
5370  (*s->ov3) ? "07009" : "S1093");
5371  return SQL_ERROR;
5372  }
5373  return SQL_SUCCESS;
5374 }
5375 
5391 static SQLRETURN
5392 drvbindparam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
5393  SQLSMALLINT buftype, SQLSMALLINT ptype, SQLUINTEGER coldef,
5394  SQLSMALLINT scale,
5395  SQLPOINTER data, SQLINTEGER buflen, SQLLEN *len)
5396 {
5397  STMT *s;
5398  BINDPARM *p;
5399 
5400  if (stmt == SQL_NULL_HSTMT) {
5401  return SQL_INVALID_HANDLE;
5402  }
5403  s = (STMT *) stmt;
5404  if (pnum == 0) {
5405  setstat(s, -1, "invalid parameter", (*s->ov3) ? "07009" : "S1093");
5406  return SQL_ERROR;
5407  }
5408  if (!data && !len) {
5409  setstat(s, -1, "invalid buffer", "HY003");
5410  return SQL_ERROR;
5411  }
5412  --pnum;
5413  if (s->bindparms) {
5414  if (pnum >= s->nbindparms) {
5415  BINDPARM *newparms;
5416 
5417  newparms = xrealloc(s->bindparms,
5418  (pnum + 1) * sizeof (BINDPARM));
5419  if (!newparms) {
5420 outofmem:
5421  return nomem(s);
5422  }
5423  s->bindparms = newparms;
5424  memset(&s->bindparms[s->nbindparms], 0,
5425  (pnum + 1 - s->nbindparms) * sizeof (BINDPARM));
5426  s->nbindparms = pnum + 1;
5427  }
5428  } else {
5429  int npar = max(10, pnum + 1);
5430 
5431  s->bindparms = xmalloc(npar * sizeof (BINDPARM));
5432  if (!s->bindparms) {
5433  goto outofmem;
5434  }
5435  memset(s->bindparms, 0, npar * sizeof (BINDPARM));
5436  s->nbindparms = npar;
5437  }
5438  switch (buftype) {
5439  case SQL_C_STINYINT:
5440  case SQL_C_UTINYINT:
5441  case SQL_C_TINYINT:
5442 #ifdef SQL_C_BIT
5443  case SQL_C_BIT:
5444 #endif
5445  buflen = sizeof (SQLCHAR);
5446  break;
5447  case SQL_C_SHORT:
5448  case SQL_C_USHORT:
5449  case SQL_C_SSHORT:
5450  buflen = sizeof (SQLSMALLINT);
5451  break;
5452  case SQL_C_SLONG:
5453  case SQL_C_ULONG:
5454  case SQL_C_LONG:
5455  buflen = sizeof (SQLINTEGER);
5456  break;
5457  case SQL_C_FLOAT:
5458  buflen = sizeof (float);
5459  break;
5460  case SQL_C_DOUBLE:
5461  buflen = sizeof (double);
5462  break;
5463  case SQL_C_TIMESTAMP:
5464 #ifdef SQL_C_TYPE_TIMESTAMP
5465  case SQL_C_TYPE_TIMESTAMP:
5466 #endif
5467  buflen = sizeof (TIMESTAMP_STRUCT);
5468  break;
5469  case SQL_C_TIME:
5470 #ifdef SQL_C_TYPE_TIME
5471  case SQL_C_TYPE_TIME:
5472 #endif
5473  buflen = sizeof (TIME_STRUCT);
5474  break;
5475  case SQL_C_DATE:
5476 #ifdef SQL_C_TYPE_DATE
5477  case SQL_C_TYPE_DATE:
5478 #endif
5479  buflen = sizeof (DATE_STRUCT);
5480  break;
5481 #ifdef SQL_C_UBIGINT
5482  case SQL_C_UBIGINT:
5483  buflen = sizeof (SQLBIGINT);
5484  break;
5485 #endif
5486 #ifdef SQL_C_SBIGINT
5487  case SQL_C_SBIGINT:
5488  buflen = sizeof (SQLBIGINT);
5489  break;
5490 #endif
5491 #ifdef SQL_C_BIGINT
5492  case SQL_C_BIGINT:
5493  buflen = sizeof (SQLBIGINT);
5494  break;
5495 #endif
5496  }
5497  p = &s->bindparms[pnum];
5498  p->type = buftype;
5499  p->stype = ptype;
5500  p->coldef = coldef;
5501  p->scale = scale;
5502  p->max = buflen;
5503  p->inc = buflen;
5504  p->lenp = p->lenp0 = len;
5505  p->offs = 0;
5506  p->len = 0;
5507  p->param0 = data;
5508  freep(&p->parbuf);
5509  p->param = p->param0;
5510  p->bound = 1;
5511  p->need = 0;
5512  return SQL_SUCCESS;
5513 }
5514 
5530 SQLRETURN SQL_API
5531 SQLBindParameter(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
5532  SQLSMALLINT buftype, SQLSMALLINT ptype, SQLULEN coldef,
5533  SQLSMALLINT scale,
5534  SQLPOINTER data, SQLLEN buflen, SQLLEN *len)
5535 {
5536  SQLRETURN ret;
5537 
5538  HSTMT_LOCK(stmt);
5539  ret = drvbindparam(stmt, pnum, iotype, buftype, ptype, coldef,
5540  scale, data, buflen, len);
5541  HSTMT_UNLOCK(stmt);
5542  return ret;
5543 }
5544 
5545 #ifndef HAVE_IODBC
5546 
5559 SQLRETURN SQL_API
5560 SQLBindParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT vtype,
5561  SQLSMALLINT ptype, SQLULEN lenprec,
5562  SQLSMALLINT scale, SQLPOINTER val,
5563  SQLLEN *lenp)
5564 {
5565  SQLRETURN ret;
5566 
5567  HSTMT_LOCK(stmt);
5568  ret = drvbindparam(stmt, pnum, SQL_PARAM_INPUT, vtype, ptype,
5569  lenprec, scale, val, 0, lenp);
5570  HSTMT_UNLOCK(stmt);
5571  return ret;
5572 }
5573 #endif
5574 
5582 SQLRETURN SQL_API
5583 SQLNumParams(SQLHSTMT stmt, SQLSMALLINT *nparam)
5584 {
5585  STMT *s;
5586  SQLSMALLINT dummy;
5587 
5588  HSTMT_LOCK(stmt);
5589  if (stmt == SQL_NULL_HSTMT) {
5590  return SQL_INVALID_HANDLE;
5591  }
5592  s = (STMT *) stmt;
5593  if (!nparam) {
5594  nparam = &dummy;
5595  }
5596  *nparam = s->nparams;
5597  HSTMT_UNLOCK(stmt);
5598  return SQL_SUCCESS;
5599 }
5600 
5608 static SQLRETURN
5610 {
5611  if (!p->parbuf) {
5612  if (*p->lenp == SQL_DATA_AT_EXEC) {
5613  p->len = p->max;
5614  } else {
5615  p->len = SQL_LEN_DATA_AT_EXEC(*p->lenp);
5616  }
5617  if (p->len < 0 && p->len != SQL_NTS &&
5618  p->len != SQL_NULL_DATA) {
5619  setstat(s, -1, "invalid length", "HY009");
5620  return SQL_ERROR;
5621  }
5622  if (p->len >= 0) {
5623  p->parbuf = xmalloc(p->len + 2);
5624  if (!p->parbuf) {
5625  return nomem(s);
5626  }
5627  p->param = p->parbuf;
5628  } else {
5629  p->param = NULL;
5630  }
5631  }
5632  return SQL_NEED_DATA;
5633 }
5634 
5642 SQLRETURN SQL_API
5643 SQLParamData(SQLHSTMT stmt, SQLPOINTER *pind)
5644 {
5645  STMT *s;
5646  int i;
5647  SQLPOINTER dummy;
5648  SQLRETURN ret;
5649  BINDPARM *p;
5650 
5651  HSTMT_LOCK(stmt);
5652  if (stmt == SQL_NULL_HSTMT) {
5653  return SQL_INVALID_HANDLE;
5654  }
5655  s = (STMT *) stmt;
5656  if (!pind) {
5657  pind = &dummy;
5658  }
5659  if (s->pdcount < s->nparams) {
5660  s->pdcount++;
5661  }
5662  for (i = 0; i < s->pdcount; i++) {
5663  p = &s->bindparms[i];
5664  if (p->need > 0) {
5665  int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
5666 
5667  p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR) ? -1 : 0;
5668  }
5669  }
5670  for (; i < s->nparams; i++) {
5671  p = &s->bindparms[i];
5672  if (p->need > 0) {
5673  *pind = (SQLPOINTER) p->param0;
5674  ret = setupparbuf(s, p);
5675  s->pdcount = i;
5676  goto done;
5677  }
5678  }
5679  ret = drvexecute(stmt, 0);
5680 done:
5681  HSTMT_UNLOCK(stmt);
5682  return ret;
5683 }
5684 
5696 SQLRETURN SQL_API
5697 SQLDescribeParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT *dtype,
5698  SQLULEN *size, SQLSMALLINT *decdigits, SQLSMALLINT *nullable)
5699 {
5700  STMT *s;
5701  SQLRETURN ret = SQL_ERROR;
5702 
5703  HSTMT_LOCK(stmt);
5704  if (stmt == SQL_NULL_HSTMT) {
5705  return SQL_INVALID_HANDLE;
5706  }
5707  s = (STMT *) stmt;
5708  --pnum;
5709  if (pnum >= s->nparams) {
5710  setstat(s, -1, "invalid parameter index",
5711  (*s->ov3) ? "HY000" : "S1000");
5712  goto done;
5713  }
5714  if (dtype) {
5715 #ifdef SQL_LONGVARCHAR
5716 #ifdef WINTERFACE
5717  *dtype = s->nowchar[0] ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
5718 #else
5719  *dtype = SQL_LONGVARCHAR;
5720 #endif
5721 #else
5722 #ifdef WINTERFACE
5723  *dtype = s->nowchar[0] ? SQL_VARCHAR : SQL_WVARCHAR;
5724 #else
5725  *dtype = SQL_VARCHAR;
5726 #endif
5727 #endif
5728  }
5729  if (size) {
5730 #ifdef SQL_LONGVARCHAR
5731  *size = 65536;
5732 #else
5733  *size = 255;
5734 #endif
5735  }
5736  if (decdigits) {
5737  *decdigits = 0;
5738  }
5739  if (nullable) {
5740  *nullable = SQL_NULLABLE;
5741  }
5742  ret = SQL_SUCCESS;
5743 done:
5744  HSTMT_UNLOCK(stmt);
5745  return ret;
5746 }
5747 
5761 SQLRETURN SQL_API
5762 SQLSetParam(SQLHSTMT stmt, SQLUSMALLINT par, SQLSMALLINT type,
5763  SQLSMALLINT sqltype, SQLULEN coldef,
5764  SQLSMALLINT scale, SQLPOINTER val, SQLLEN *nval)
5765 {
5766  SQLRETURN ret;
5767 
5768  HSTMT_LOCK(stmt);
5769  ret = drvbindparam(stmt, par, SQL_PARAM_INPUT,
5770  type, sqltype, coldef, scale, val,
5771  SQL_SETPARAM_VALUE_MAX, nval);
5772  HSTMT_UNLOCK(stmt);
5773  return ret;
5774 }
5775 
5780 SQLRETURN SQL_API
5781 SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
5782 {
5783  SQLRETURN ret;
5784 
5785  HSTMT_LOCK(stmt);
5786  ret = drvunimplstmt(stmt);
5787  HSTMT_UNLOCK(stmt);
5788  return ret;
5789 }
5790 
5791 #ifndef WINTERFACE
5792 
5796 SQLRETURN SQL_API
5797 SQLGetDescField(SQLHDESC handle, SQLSMALLINT recno,
5798  SQLSMALLINT fieldid, SQLPOINTER value,
5799  SQLINTEGER buflen, SQLINTEGER *strlen)
5800 {
5801  return SQL_ERROR;
5802 }
5803 #endif
5804 
5805 #ifdef WINTERFACE
5806 
5810 SQLRETURN SQL_API
5811 SQLGetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
5812  SQLSMALLINT fieldid, SQLPOINTER value,
5813  SQLINTEGER buflen, SQLINTEGER *strlen)
5814 {
5815  return SQL_ERROR;
5816 }
5817 #endif
5818 
5819 #ifndef WINTERFACE
5820 
5824 SQLRETURN SQL_API
5825 SQLSetDescField(SQLHDESC handle, SQLSMALLINT recno,
5826  SQLSMALLINT fieldid, SQLPOINTER value,
5827  SQLINTEGER buflen)
5828 {
5829  return SQL_ERROR;
5830 }
5831 #endif
5832 
5833 #ifdef WINTERFACE
5834 
5838 SQLRETURN SQL_API
5839 SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
5840  SQLSMALLINT fieldid, SQLPOINTER value,
5841  SQLINTEGER buflen)
5842 {
5843  return SQL_ERROR;
5844 }
5845 #endif
5846 
5847 #ifndef WINTERFACE
5848 
5852 SQLRETURN SQL_API
5853 SQLGetDescRec(SQLHDESC handle, SQLSMALLINT recno,
5854  SQLCHAR *name, SQLSMALLINT buflen,
5855  SQLSMALLINT *strlen, SQLSMALLINT *type,
5856  SQLSMALLINT *subtype, SQLLEN *len,
5857  SQLSMALLINT *prec, SQLSMALLINT *scale,
5858  SQLSMALLINT *nullable)
5859 {
5860  return SQL_ERROR;
5861 }
5862 #endif
5863 
5864 #ifdef WINTERFACE
5865 
5869 SQLRETURN SQL_API
5870 SQLGetDescRecW(SQLHDESC handle, SQLSMALLINT recno,
5871  SQLWCHAR *name, SQLSMALLINT buflen,
5872  SQLSMALLINT *strlen, SQLSMALLINT *type,
5873  SQLSMALLINT *subtype, SQLLEN *len,
5874  SQLSMALLINT *prec, SQLSMALLINT *scale,
5875  SQLSMALLINT *nullable)
5876 {
5877  return SQL_ERROR;
5878 }
5879 #endif
5880 
5885 SQLRETURN SQL_API
5886 SQLSetDescRec(SQLHDESC handle, SQLSMALLINT recno,
5887  SQLSMALLINT type, SQLSMALLINT subtype,
5888  SQLLEN len, SQLSMALLINT prec,
5889  SQLSMALLINT scale, SQLPOINTER data,
5890  SQLLEN *strlen, SQLLEN *indicator)
5891 {
5892  return SQL_ERROR;
5893 }
5894 
5906 static SQLRETURN
5907 mkresultset(HSTMT stmt, COL *colspec, int ncols, COL *colspec3,
5908  int ncols3, int *nret)
5909 {
5910  STMT *s;
5911  DBC *d;
5912 
5913  if (stmt == SQL_NULL_HSTMT) {
5914  return SQL_INVALID_HANDLE;
5915  }
5916  s = (STMT *) stmt;
5917  if (s->dbc == SQL_NULL_HDBC) {
5918 noconn:
5919  return noconn(s);
5920  }
5921  d = (DBC *) s->dbc;
5922  if (!d->sqlite) {
5923  goto noconn;
5924  }
5925  s3stmt_end_if(s);
5926  freeresult(s, 0);
5927  if (colspec3 && *s->ov3) {
5928  s->ncols = ncols3;
5929  s->cols = colspec3;
5930  } else {
5931  s->ncols = ncols;
5932  s->cols = colspec;
5933  }
5934  mkbindcols(s, s->ncols);
5935  s->nowchar[1] = 1;
5936  s->nrows = 0;
5937  s->rowp = s->rowprs = -1;
5938  s->isselect = -1;
5939  if (nret) {
5940  *nret = s->ncols;
5941  }
5942  return SQL_SUCCESS;
5943 }
5944 
5949 static COL tablePrivSpec2[] = {
5950  { "SYSTEM", "TABLEPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
5951  { "SYSTEM", "TABLEPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
5952  { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
5953  { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
5954  { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
5955  { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
5956  { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
5957 };
5958 
5959 static COL tablePrivSpec3[] = {
5960  { "SYSTEM", "TABLEPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
5961  { "SYSTEM", "TABLEPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
5962  { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
5963  { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
5964  { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
5965  { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
5966  { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
5967 };
5968 
5981 static SQLRETURN
5983  SQLCHAR *cat, SQLSMALLINT catLen,
5984  SQLCHAR *schema, SQLSMALLINT schemaLen,
5985  SQLCHAR *table, SQLSMALLINT tableLen)
5986 {
5987  SQLRETURN ret;
5988  STMT *s;
5989  DBC *d;
5990  int ncols, rc, size, npatt;
5991  char *errp = NULL, *sql, tname[512];
5992 
5993  ret = mkresultset(stmt, tablePrivSpec2, array_size(tablePrivSpec2),
5994  tablePrivSpec3, array_size(tablePrivSpec3), NULL);
5995  if (ret != SQL_SUCCESS) {
5996  return ret;
5997  }
5998  s = (STMT *) stmt;
5999  d = (DBC *) s->dbc;
6000  if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
6001  table = NULL;
6002  goto doit;
6003  }
6004  if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
6005  schema[0] == '%') {
6006  if ((!cat || catLen == 0 || !cat[0]) &&
6007  (!table || tableLen == 0 || !table[0])) {
6008  table = NULL;
6009  goto doit;
6010  }
6011  }
6012 doit:
6013  if (!table) {
6014  size = 1;
6015  tname[0] = '%';
6016  } else {
6017  if (tableLen == SQL_NTS) {
6018  size = sizeof (tname) - 1;
6019  } else {
6020  size = min(sizeof (tname) - 1, tableLen);
6021  }
6022  strncpy(tname, (char *) table, size);
6023  }
6024  tname[size] = '\0';
6025  npatt = unescpat(tname);
6026 #if defined(_WIN32) || defined(_WIN64)
6027  sql = sqlite3_mprintf("select %s as 'TABLE_QUALIFIER', "
6028  "%s as 'TABLE_OWNER', "
6029  "tbl_name as 'TABLE_NAME', "
6030  "'' as 'GRANTOR', "
6031  "'' as 'GRANTEE', "
6032  "'SELECT' AS 'PRIVILEGE', "
6033  "NULL as 'IS_GRANTABLE' "
6034  "from sqlite_master where "
6035  "(type = 'table' or type = 'view') "
6036  "and tbl_name %s %Q "
6037  "UNION "
6038  "select %s as 'TABLE_QUALIFIER', "
6039  "%s as 'TABLE_OWNER', "
6040  "tbl_name as 'TABLE_NAME', "
6041  "'' as 'GRANTOR', "
6042  "'' as 'GRANTEE', "
6043  "'UPDATE' AS 'PRIVILEGE', "
6044  "NULL as 'IS_GRANTABLE' "
6045  "from sqlite_master where "
6046  "(type = 'table' or type = 'view') "
6047  "and tbl_name %s %Q "
6048  "UNION "
6049  "select %s as 'TABLE_QUALIFIER', "
6050  "%s as 'TABLE_OWNER', "
6051  "tbl_name as 'TABLE_NAME', "
6052  "'' as 'GRANTOR', "
6053  "'' as 'GRANTEE', "
6054  "'DELETE' AS 'PRIVILEGE', "
6055  "NULL as 'IS_GRANTABLE' "
6056  "from sqlite_master where "
6057  "(type = 'table' or type = 'view') "
6058  "and tbl_name %s %Q "
6059  "UNION "
6060  "select %s as 'TABLE_QUALIFIER', "
6061  "%s as 'TABLE_OWNER', "
6062  "tbl_name as 'TABLE_NAME', "
6063  "'' as 'GRANTOR', "
6064  "'' as 'GRANTEE', "
6065  "'INSERT' AS 'PRIVILEGE', "
6066  "NULL as 'IS_GRANTABLE' "
6067  "from sqlite_master where "
6068  "(type = 'table' or type = 'view') "
6069  "and tbl_name %s %Q "
6070  "UNION "
6071  "select %s as 'TABLE_QUALIFIER', "
6072  "%s as 'TABLE_OWNER', "
6073  "tbl_name as 'TABLE_NAME', "
6074  "'' as 'GRANTOR', "
6075  "'' as 'GRANTEE', "
6076  "'REFERENCES' AS 'PRIVILEGE', "
6077  "NULL as 'IS_GRANTABLE' "
6078  "from sqlite_master where "
6079  "(type = 'table' or type = 'view') "
6080  "and tbl_name %s %Q",
6081  d->xcelqrx ? "'main'" : "NULL",
6082  d->xcelqrx ? "''" : "NULL",
6083  npatt ? "like" : "=", tname,
6084  d->xcelqrx ? "'main'" : "NULL",
6085  d->xcelqrx ? "''" : "NULL",
6086  npatt ? "like" : "=", tname,
6087  d->xcelqrx ? "'main'" : "NULL",
6088  d->xcelqrx ? "''" : "NULL",
6089  npatt ? "like" : "=", tname,
6090  d->xcelqrx ? "'main'" : "NULL",
6091  d->xcelqrx ? "''" : "NULL",
6092  npatt ? "like" : "=", tname,
6093  d->xcelqrx ? "'main'" : "NULL",
6094  d->xcelqrx ? "''" : "NULL",
6095  npatt ? "like" : "=", tname);
6096 #else
6097  sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
6098  "NULL as 'TABLE_OWNER', "
6099  "tbl_name as 'TABLE_NAME', "
6100  "'' as 'GRANTOR', "
6101  "'' as 'GRANTEE', "
6102  "'SELECT' AS 'PRIVILEGE', "
6103  "NULL as 'IS_GRANTABLE' "
6104  "from sqlite_master where "
6105  "(type = 'table' or type = 'view') "
6106  "and tbl_name %s %Q "
6107  "UNION "
6108  "select NULL as 'TABLE_QUALIFIER', "
6109  "NULL as 'TABLE_OWNER', "
6110  "tbl_name as 'TABLE_NAME', "
6111  "'' as 'GRANTOR', "
6112  "'' as 'GRANTEE', "
6113  "'UPDATE' AS 'PRIVILEGE', "
6114  "NULL as 'IS_GRANTABLE' "
6115  "from sqlite_master where "
6116  "(type = 'table' or type = 'view') "
6117  "and tbl_name %s %Q "
6118  "UNION "
6119  "select NULL as 'TABLE_QUALIFIER', "
6120  "NULL as 'TABLE_OWNER', "
6121  "tbl_name as 'TABLE_NAME', "
6122  "'' as 'GRANTOR', "
6123  "'' as 'GRANTEE', "
6124  "'DELETE' AS 'PRIVILEGE', "
6125  "NULL as 'IS_GRANTABLE' "
6126  "from sqlite_master where "
6127  "(type = 'table' or type = 'view') "
6128  "and tbl_name %s %Q "
6129  "UNION "
6130  "select NULL as 'TABLE_QUALIFIER', "
6131  "NULL as 'TABLE_OWNER', "
6132  "tbl_name as 'TABLE_NAME', "
6133  "'' as 'GRANTOR', "
6134  "'' as 'GRANTEE', "
6135  "'INSERT' AS 'PRIVILEGE', "
6136  "NULL as 'IS_GRANTABLE' "
6137  "from sqlite_master where "
6138  "(type = 'table' or type = 'view') "
6139  "and tbl_name %s %Q "
6140  "UNION "
6141  "select NULL as 'TABLE_QUALIFIER', "
6142  "NULL as 'TABLE_OWNER', "
6143  "tbl_name as 'TABLE_NAME', "
6144  "'' as 'GRANTOR', "
6145  "'' as 'GRANTEE', "
6146  "'REFERENCES' AS 'PRIVILEGE', "
6147  "NULL as 'IS_GRANTABLE' "
6148  "from sqlite_master where "
6149  "(type = 'table' or type = 'view') "
6150  "and tbl_name %s %Q",
6151  npatt ? "like" : "=", tname,
6152  npatt ? "like" : "=", tname,
6153  npatt ? "like" : "=", tname,
6154  npatt ? "like" : "=", tname,
6155  npatt ? "like" : "=", tname);
6156 #endif
6157  if (!sql) {
6158  return nomem(s);
6159  }
6160  ret = starttran(s);
6161  if (ret != SQL_SUCCESS) {
6162  sqlite3_free(sql);
6163  return ret;
6164  }
6165  dbtraceapi(d, "sqlite3_get_table", sql);
6166  rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
6167  sqlite3_free(sql);
6168  if (rc == SQLITE_OK) {
6169  if (ncols != s->ncols) {
6170  freeresult(s, 0);
6171  s->nrows = 0;
6172  } else {
6173  s->rowfree = sqlite3_free_table;
6174  }
6175  } else {
6176  s->nrows = 0;
6177  s->rows = NULL;
6178  s->rowfree = NULL;
6179  }
6180  if (errp) {
6181  sqlite3_free(errp);
6182  errp = NULL;
6183  }
6184  s->rowp = s->rowprs = -1;
6185  return SQL_SUCCESS;
6186 }
6187 
6188 
6189 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
6190 
6202 SQLRETURN SQL_API
6203 SQLTablePrivileges(SQLHSTMT stmt,
6204  SQLCHAR *catalog, SQLSMALLINT catalogLen,
6205  SQLCHAR *schema, SQLSMALLINT schemaLen,
6206  SQLCHAR *table, SQLSMALLINT tableLen)
6207 {
6208 #if defined(_WIN32) || defined(_WIN64)
6209  char *c = NULL, *s = NULL, *t = NULL;
6210 #endif
6211  SQLRETURN ret;
6212 
6213  HSTMT_LOCK(stmt);
6214 #if defined(_WIN32) || defined(_WIN64)
6215  if (!((STMT *) stmt)->oemcp[0]) {
6216  ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
6217  table, tableLen);
6218  goto done2;
6219  }
6220  if (catalog) {
6221  c = wmb_to_utf_c((char *) catalog, catalogLen);
6222  if (!c) {
6223  ret = nomem((STMT *) stmt);
6224  goto done;
6225  }
6226  }
6227  if (schema) {
6228  s = wmb_to_utf_c((char *) schema, schemaLen);
6229  if (!s) {
6230  ret = nomem((STMT *) stmt);
6231  goto done;
6232  }
6233  }
6234  if (table) {
6235  t = wmb_to_utf_c((char *) table, tableLen);
6236  if (!t) {
6237  ret = nomem((STMT *) stmt);
6238  goto done;
6239  }
6240  }
6241  ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
6242  (SQLCHAR *) s, SQL_NTS,
6243  (SQLCHAR *) t, SQL_NTS);
6244 #else
6245  ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
6246  table, tableLen);
6247 #endif
6248 #if defined(_WIN32) || defined(_WIN64)
6249 done:
6250  uc_free(t);
6251  uc_free(s);
6252  uc_free(c);
6253 done2:
6254  ;
6255 #endif
6256  HSTMT_UNLOCK(stmt);
6257  return ret;
6258 }
6259 #endif
6260 
6261 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
6262 #ifdef WINTERFACE
6263 
6275 SQLRETURN SQL_API
6276 SQLTablePrivilegesW(SQLHSTMT stmt,
6277  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
6278  SQLWCHAR *schema, SQLSMALLINT schemaLen,
6279  SQLWCHAR *table, SQLSMALLINT tableLen)
6280 {
6281  char *c = NULL, *s = NULL, *t = NULL;
6282  SQLRETURN ret;
6283 
6284  HSTMT_LOCK(stmt);
6285  if (catalog) {
6286  c = uc_to_utf_c(catalog, catalogLen);
6287  if (!c) {
6288  ret = nomem((STMT *) stmt);
6289  goto done;
6290  }
6291  }
6292  if (schema) {
6293  s = uc_to_utf_c(schema, schemaLen);
6294  if (!s) {
6295  ret = nomem((STMT *) stmt);
6296  goto done;
6297  }
6298  }
6299  if (table) {
6300  t = uc_to_utf_c(table, tableLen);
6301  if (!t) {
6302  ret = nomem((STMT *) stmt);
6303  goto done;
6304  }
6305  }
6306  ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
6307  (SQLCHAR *) s, SQL_NTS,
6308  (SQLCHAR *) t, SQL_NTS);
6309 done:
6310  uc_free(t);
6311  uc_free(s);
6312  uc_free(c);
6313  HSTMT_UNLOCK(stmt);
6314  return ret;
6315 }
6316 #endif
6317 #endif
6318 
6323 static COL colPrivSpec2[] = {
6324  { "SYSTEM", "COLPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
6325  { "SYSTEM", "COLPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
6326  { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6327  { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6328  { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6329  { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6330  { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
6331 };
6332 
6333 static COL colPrivSpec3[] = {
6334  { "SYSTEM", "COLPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
6335  { "SYSTEM", "COLPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
6336  { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
6337  { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6338  { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
6339  { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
6340  { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
6341 };
6342 
6343 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
6344 
6358 SQLRETURN SQL_API
6359 SQLColumnPrivileges(SQLHSTMT stmt,
6360  SQLCHAR *catalog, SQLSMALLINT catalogLen,
6361  SQLCHAR *schema, SQLSMALLINT schemaLen,
6362  SQLCHAR *table, SQLSMALLINT tableLen,
6363  SQLCHAR *column, SQLSMALLINT columnLen)
6364 {
6365  SQLRETURN ret;
6366 
6367  HSTMT_LOCK(stmt);
6368  ret = mkresultset(stmt, colPrivSpec2, array_size(colPrivSpec2),
6369  colPrivSpec3, array_size(colPrivSpec3), NULL);
6370  HSTMT_UNLOCK(stmt);
6371  return ret;
6372 }
6373 #endif
6374 
6375 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
6376 #ifdef WINTERFACE
6377 
6391 SQLRETURN SQL_API
6392 SQLColumnPrivilegesW(SQLHSTMT stmt,
6393  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
6394  SQLWCHAR *schema, SQLSMALLINT schemaLen,
6395  SQLWCHAR *table, SQLSMALLINT tableLen,
6396  SQLWCHAR *column, SQLSMALLINT columnLen)
6397 {
6398  SQLRETURN ret;
6399 
6400  HSTMT_LOCK(stmt);
6401  ret = mkresultset(stmt, colPrivSpec2, array_size(colPrivSpec2),
6402  colPrivSpec3, array_size(colPrivSpec3), NULL);
6403  HSTMT_UNLOCK(stmt);
6404  return ret;
6405 }
6406 #endif
6407 #endif
6408 
6413 static COL pkeySpec2[] = {
6414  { "SYSTEM", "PRIMARYKEY", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
6415  { "SYSTEM", "PRIMARYKEY", "TABLE_OWNER", SCOL_VARCHAR, 50 },
6416  { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
6417  { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6418  { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
6419  { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
6420 };
6421 
6422 static COL pkeySpec3[] = {
6423  { "SYSTEM", "PRIMARYKEY", "TABLE_CAT", SCOL_VARCHAR, 50 },
6424  { "SYSTEM", "PRIMARYKEY", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
6425  { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
6426  { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6427  { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
6428  { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
6429 };
6430 
6443 static SQLRETURN
6444 drvprimarykeys(SQLHSTMT stmt,
6445  SQLCHAR *cat, SQLSMALLINT catLen,
6446  SQLCHAR *schema, SQLSMALLINT schemaLen,
6447  SQLCHAR *table, SQLSMALLINT tableLen)
6448 {
6449  STMT *s;
6450  DBC *d;
6451  SQLRETURN sret;
6452  int i, asize, ret, nrows, ncols, nrows2 = 0, ncols2 = 0;
6453  int namec = -1, uniquec = -1, namec2 = -1, uniquec2 = -1, offs, seq = 1;
6454  PTRDIFF_T size;
6455  char **rowp = NULL, **rowp2 = NULL, *errp = NULL, *sql, tname[512];
6456 
6457  sret = mkresultset(stmt, pkeySpec2, array_size(pkeySpec2),
6458  pkeySpec3, array_size(pkeySpec3), &asize);
6459  if (sret != SQL_SUCCESS) {
6460  return sret;
6461  }
6462  s = (STMT *) stmt;
6463  d = (DBC *) s->dbc;
6464  if (!table || table[0] == '\0' || table[0] == '%') {
6465  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
6466  return SQL_ERROR;
6467  }
6468  if (tableLen == SQL_NTS) {
6469  size = sizeof (tname) - 1;
6470  } else {
6471  size = min(sizeof (tname) - 1, tableLen);
6472  }
6473  strncpy(tname, (char *) table, size);
6474  tname[size] = '\0';
6475  unescpat(tname);
6476  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
6477  if (!sql) {
6478  return nomem(s);
6479  }
6480  sret = starttran(s);
6481  if (sret != SQL_SUCCESS) {
6482  sqlite3_free(sql);
6483  return sret;
6484  }
6485  dbtraceapi(d, "sqlite3_get_table", sql);
6486  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
6487  sqlite3_free(sql);
6488  if (ret != SQLITE_OK) {
6489  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6490  errp ? errp : "unknown error", ret);
6491  if (errp) {
6492  sqlite3_free(errp);
6493  errp = NULL;
6494  }
6495  return SQL_ERROR;
6496  }
6497  if (errp) {
6498  sqlite3_free(errp);
6499  errp = NULL;
6500  }
6501  size = 0;
6502  if (ncols * nrows > 0) {
6503  int typec;
6504 
6505  namec = findcol(rowp, ncols, "name");
6506  uniquec = findcol(rowp, ncols, "pk");
6507  typec = findcol(rowp, ncols, "type");
6508  if (namec >= 0 && uniquec >= 0 && typec >= 0) {
6509  for (i = 1; i <= nrows; i++) {
6510  if (*rowp[i * ncols + uniquec] != '0') {
6511  size++;
6512  }
6513  }
6514  }
6515  }
6516  if (size == 0) {
6517  sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
6518  if (!sql) {
6519  sqlite3_free_table(rowp);
6520  return nomem(s);
6521  }
6522  dbtraceapi(d, "sqlite3_get_table", sql);
6523  ret = sqlite3_get_table(d->sqlite, sql, &rowp2, &nrows2, &ncols2,
6524  &errp);
6525  sqlite3_free(sql);
6526  if (ret != SQLITE_OK) {
6527  sqlite3_free_table(rowp);
6528  sqlite3_free_table(rowp2);
6529  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6530  errp ? errp : "unknown error", ret);
6531  if (errp) {
6532  sqlite3_free(errp);
6533  errp = NULL;
6534  }
6535  return SQL_ERROR;
6536  }
6537  if (errp) {
6538  sqlite3_free(errp);
6539  errp = NULL;
6540  }
6541  }
6542  if (ncols2 * nrows2 > 0) {
6543  namec2 = findcol(rowp2, ncols2, "name");
6544  uniquec2 = findcol(rowp2, ncols2, "unique");
6545  if (namec2 >= 0 && uniquec2 >= 0) {
6546  for (i = 1; i <= nrows2; i++) {
6547  int nnrows, nncols, nlen = 0;
6548  char **rowpp;
6549 
6550  if (rowp2[i * ncols2 + namec2]) {
6551  nlen = strlen(rowp2[i * ncols2 + namec2]);
6552  }
6553  if (nlen < 17 ||
6554  strncmp(rowp2[i * ncols2 + namec2],
6555  "sqlite_autoindex_", 17)) {
6556  continue;
6557  }
6558  if (*rowp2[i * ncols2 + uniquec2] != '0') {
6559  ret = SQLITE_ERROR;
6560  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6561  rowp2[i * ncols2 + namec2]);
6562  if (sql) {
6563  dbtraceapi(d, "sqlite3_get_table", sql);
6564  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6565  &nnrows, &nncols, NULL);
6566  sqlite3_free(sql);
6567  }
6568  if (ret == SQLITE_OK) {
6569  size += nnrows;
6570  sqlite3_free_table(rowpp);
6571  }
6572  }
6573  }
6574  }
6575  }
6576  if (size == 0) {
6577  sqlite3_free_table(rowp);
6578  sqlite3_free_table(rowp2);
6579  return SQL_SUCCESS;
6580  }
6581  s->nrows = size;
6582  size = (size + 1) * asize;
6583  s->rows = xmalloc((size + 1) * sizeof (char *));
6584  if (!s->rows) {
6585  s->nrows = 0;
6586  sqlite3_free_table(rowp);
6587  sqlite3_free_table(rowp2);
6588  return nomem(s);
6589  }
6590  s->rows[0] = (char *) size;
6591  s->rows += 1;
6592  memset(s->rows, 0, sizeof (char *) * size);
6593  s->rowfree = freerows;
6594  offs = s->ncols;
6595  if (rowp) {
6596  for (i = 1; i <= nrows; i++) {
6597  if (*rowp[i * ncols + uniquec] != '0') {
6598  char buf[32];
6599 
6600 #if defined(_WIN32) || defined(_WIN64)
6601  s->rows[offs + 0] = xstrdup(d->xcelqrx ? "main" : "");
6602  s->rows[offs + 1] = xstrdup("");
6603 #else
6604  s->rows[offs + 0] = xstrdup("");
6605  s->rows[offs + 1] = xstrdup("");
6606 #endif
6607  s->rows[offs + 2] = xstrdup(tname);
6608  s->rows[offs + 3] = xstrdup(rowp[i * ncols + namec]);
6609  sprintf(buf, "%d", seq++);
6610  s->rows[offs + 4] = xstrdup(buf);
6611  offs += s->ncols;
6612  }
6613  }
6614  }
6615  if (rowp2) {
6616  for (i = 1; i <= nrows2; i++) {
6617  int nnrows, nncols, nlen = 0;
6618  char **rowpp;
6619 
6620  if (rowp2[i * ncols2 + namec2]) {
6621  nlen = strlen(rowp2[i * ncols2 + namec2]);
6622  }
6623  if (nlen < 17 ||
6624  strncmp(rowp2[i * ncols2 + namec2], "sqlite_autoindex_", 17)) {
6625  continue;
6626  }
6627  if (*rowp2[i * ncols2 + uniquec2] != '0') {
6628  int k;
6629 
6630  ret = SQLITE_ERROR;
6631  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6632  rowp2[i * ncols2 + namec2]);
6633  if (sql) {
6634  dbtraceapi(d, "sqlite3_get_table", sql);
6635  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6636  &nnrows, &nncols, NULL);
6637  sqlite3_free(sql);
6638  }
6639  if (ret != SQLITE_OK) {
6640  continue;
6641  }
6642  for (k = 0; nnrows && k < nncols; k++) {
6643  if (strcmp(rowpp[k], "name") == 0) {
6644  int m;
6645 
6646  for (m = 1; m <= nnrows; m++) {
6647  int roffs = offs + (m - 1) * s->ncols;
6648 
6649 #if defined(_WIN32) || defined(_WIN64)
6650  s->rows[roffs + 0] =
6651  xstrdup(d->xcelqrx ? "main" : "");
6652  s->rows[roffs + 1] = xstrdup("");
6653 #else
6654  s->rows[roffs + 0] = xstrdup("");
6655  s->rows[roffs + 1] = xstrdup("");
6656 #endif
6657  s->rows[roffs + 2] = xstrdup(tname);
6658  s->rows[roffs + 3] =
6659  xstrdup(rowpp[m * nncols + k]);
6660  s->rows[roffs + 5] =
6661  xstrdup(rowp2[i * ncols2 + namec2]);
6662  }
6663  } else if (strcmp(rowpp[k], "seqno") == 0) {
6664  int m;
6665 
6666  for (m = 1; m <= nnrows; m++) {
6667  int roffs = offs + (m - 1) * s->ncols;
6668  int pos = m - 1;
6669  char buf[32];
6670 
6671  sscanf(rowpp[m * nncols + k], "%d", &pos);
6672  sprintf(buf, "%d", pos + 1);
6673  s->rows[roffs + 4] = xstrdup(buf);
6674  }
6675  }
6676  }
6677  offs += nnrows * s->ncols;
6678  sqlite3_free_table(rowpp);
6679  }
6680  }
6681  }
6682  sqlite3_free_table(rowp);
6683  sqlite3_free_table(rowp2);
6684  return SQL_SUCCESS;
6685 }
6686 
6687 #ifndef WINTERFACE
6688 
6700 SQLRETURN SQL_API
6701 SQLPrimaryKeys(SQLHSTMT stmt,
6702  SQLCHAR *cat, SQLSMALLINT catLen,
6703  SQLCHAR *schema, SQLSMALLINT schemaLen,
6704  SQLCHAR *table, SQLSMALLINT tableLen)
6705 {
6706 #if defined(_WIN32) || defined(_WIN64)
6707  char *c = NULL, *s = NULL, *t = NULL;
6708 #endif
6709  SQLRETURN ret;
6710 
6711  HSTMT_LOCK(stmt);
6712 #if defined(_WIN32) || defined(_WIN64)
6713  if (!((STMT *) stmt)->oemcp[0]) {
6714  ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
6715  table, tableLen);
6716  goto done2;
6717  }
6718  if (cat) {
6719  c = wmb_to_utf_c((char *) cat, catLen);
6720  if (!c) {
6721  ret = nomem((STMT *) stmt);
6722  goto done;
6723  }
6724  }
6725  if (schema) {
6726  s = wmb_to_utf_c((char *) schema, schemaLen);
6727  if (!s) {
6728  ret = nomem((STMT *) stmt);
6729  goto done;
6730  }
6731  }
6732  if (table) {
6733  t = wmb_to_utf_c((char *) table, tableLen);
6734  if (!t) {
6735  ret = nomem((STMT *) stmt);
6736  goto done;
6737  }
6738  }
6739  ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
6740  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
6741 #else
6742  ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
6743  table, tableLen);
6744 #endif
6745 #if defined(_WIN32) || defined(_WIN64)
6746 done:
6747  uc_free(t);
6748  uc_free(s);
6749  uc_free(c);
6750 done2:
6751  ;
6752 #endif
6753  HSTMT_UNLOCK(stmt);
6754  return ret;
6755 }
6756 #endif
6757 
6758 #ifdef WINTERFACE
6759 
6771 SQLRETURN SQL_API
6772 SQLPrimaryKeysW(SQLHSTMT stmt,
6773  SQLWCHAR *cat, SQLSMALLINT catLen,
6774  SQLWCHAR *schema, SQLSMALLINT schemaLen,
6775  SQLWCHAR *table, SQLSMALLINT tableLen)
6776 {
6777  char *c = NULL, *s = NULL, *t = NULL;
6778  SQLRETURN ret;
6779 
6780  HSTMT_LOCK(stmt);
6781  if (cat) {
6782  c = uc_to_utf_c(cat, catLen);
6783  if (!c) {
6784  ret = nomem((STMT *) stmt);
6785  goto done;
6786  }
6787  }
6788  if (schema) {
6789  s = uc_to_utf_c(schema, schemaLen);
6790  if (!s) {
6791  ret = nomem((STMT *) stmt);
6792  goto done;
6793  }
6794  }
6795  if (table) {
6796  t = uc_to_utf_c(table, tableLen);
6797  if (!t) {
6798  ret = nomem((STMT *) stmt);
6799  goto done;
6800  }
6801  }
6802  ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
6803  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
6804 done:
6805  uc_free(t);
6806  uc_free(s);
6807  uc_free(c);
6808  HSTMT_UNLOCK(stmt);
6809  return ret;
6810 }
6811 #endif
6812 
6817 static COL scolSpec2[] = {
6818  { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
6819  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6820  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
6821  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
6822  { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
6823  { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
6824  { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
6825  { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
6826  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
6827 };
6828 
6829 static COL scolSpec3[] = {
6830  { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
6831  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
6832  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
6833  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
6834  { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
6835  { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
6836  { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
6837  { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
6838  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
6839 };
6840 
6856 static SQLRETURN
6857 drvspecialcolumns(SQLHSTMT stmt, SQLUSMALLINT id,
6858  SQLCHAR *cat, SQLSMALLINT catLen,
6859  SQLCHAR *schema, SQLSMALLINT schemaLen,
6860  SQLCHAR *table, SQLSMALLINT tableLen,
6861  SQLUSMALLINT scope, SQLUSMALLINT nullable)
6862 {
6863  STMT *s;
6864  DBC *d;
6865  SQLRETURN sret;
6866  int i, asize, ret, nrows, ncols, nnnrows, nnncols, offs;
6867  PTRDIFF_T size;
6868  int namec = -1, uniquec = -1, namecc = -1, typecc = -1;
6869  int notnullcc = -1, mkrowid = 0;
6870  char *errp = NULL, *sql, tname[512];
6871  char **rowp = NULL, **rowppp = NULL;
6872 
6873  sret = mkresultset(stmt, scolSpec2, array_size(scolSpec2),
6874  scolSpec3, array_size(scolSpec3), &asize);
6875  if (sret != SQL_SUCCESS) {
6876  return sret;
6877  }
6878  s = (STMT *) stmt;
6879  d = (DBC *) s->dbc;
6880  if (!table || table[0] == '\0' || table[0] == '%') {
6881  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
6882  return SQL_ERROR;
6883  }
6884  if (tableLen == SQL_NTS) {
6885  size = sizeof (tname) - 1;
6886  } else {
6887  size = min(sizeof (tname) - 1, tableLen);
6888  }
6889  strncpy(tname, (char *) table, size);
6890  tname[size] = '\0';
6891  unescpat(tname);
6892  if (id != SQL_BEST_ROWID) {
6893  return SQL_SUCCESS;
6894  }
6895  sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
6896  if (!sql) {
6897  return nomem(s);
6898  }
6899  sret = starttran(s);
6900  if (sret != SQL_SUCCESS) {
6901  sqlite3_free(sql);
6902  return sret;
6903  }
6904  dbtraceapi(d, "sqlite3_get_table", sql);
6905  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
6906  sqlite3_free(sql);
6907  if (ret != SQLITE_OK) {
6908 doerr:
6909  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
6910  errp ? errp : "unknown error", ret);
6911  if (errp) {
6912  sqlite3_free(errp);
6913  errp = NULL;
6914  }
6915  return SQL_ERROR;
6916  }
6917  if (errp) {
6918  sqlite3_free(errp);
6919  errp = NULL;
6920  }
6921  size = 0; /* number result rows */
6922  if (ncols * nrows <= 0) {
6923  goto nodata_but_rowid;
6924  }
6925  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
6926  if (!sql) {
6927  return nomem(s);
6928  }
6929  dbtraceapi(d, "sqlite3_get_table", sql);
6930  ret = sqlite3_get_table(d->sqlite, sql, &rowppp, &nnnrows, &nnncols,
6931  &errp);
6932  sqlite3_free(sql);
6933  if (ret != SQLITE_OK) {
6934  sqlite3_free_table(rowp);
6935  goto doerr;
6936  }
6937  if (errp) {
6938  sqlite3_free(errp);
6939  errp = NULL;
6940  }
6941  namec = findcol(rowp, ncols, "name");
6942  uniquec = findcol(rowp, ncols, "unique");
6943  if (namec < 0 || uniquec < 0) {
6944  goto nodata_but_rowid;
6945  }
6946  namecc = findcol(rowppp, nnncols, "name");
6947  typecc = findcol(rowppp, nnncols, "type");
6948  notnullcc = findcol(rowppp, nnncols, "notnull");
6949  for (i = 1; i <= nrows; i++) {
6950  int nnrows, nncols;
6951  char **rowpp = NULL;
6952 
6953  if (*rowp[i * ncols + uniquec] != '0') {
6954  ret = SQLITE_ERROR;
6955  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
6956  rowp[i * ncols + namec]);
6957  if (sql) {
6958  dbtraceapi(d, "sqlite3_get_table", sql);
6959  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
6960  &nnrows, &nncols, NULL);
6961  sqlite3_free(sql);
6962  }
6963  if (ret == SQLITE_OK) {
6964  size += nnrows;
6965  sqlite3_free_table(rowpp);
6966  }
6967  }
6968  }
6969 nodata_but_rowid:
6970  if (size == 0) {
6971  size = 1;
6972  mkrowid = 1;
6973  }
6974  s->nrows = size;
6975  size = (size + 1) * asize;
6976  s->rows = xmalloc((size + 1) * sizeof (char *));
6977  if (!s->rows) {
6978  s->nrows = 0;
6979  sqlite3_free_table(rowp);
6980  sqlite3_free_table(rowppp);
6981  return nomem(s);
6982  }
6983  s->rows[0] = (char *) size;
6984  s->rows += 1;
6985  memset(s->rows, 0, sizeof (char *) * size);
6986  s->rowfree = freerows;
6987  if (mkrowid) {
6988  s->nrows = 0;
6989  goto mkrowid;
6990  }
6991  offs = 0;
6992  for (i = 1; i <= nrows; i++) {
6993  int nnrows, nncols;
6994  char **rowpp = NULL;
6995 
6996  if (*rowp[i * ncols + uniquec] != '0') {
6997  int k;
6998 
6999  ret = SQLITE_ERROR;
7000  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
7001  rowp[i * ncols + namec]);
7002  if (sql) {
7003  dbtraceapi(d, "sqlite3_get_table", sql);
7004  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7005  &nnrows, &nncols, NULL);
7006  sqlite3_free(sql);
7007  }
7008  if (ret != SQLITE_OK) {
7009  continue;
7010  }
7011  for (k = 0; nnrows && k < nncols; k++) {
7012  if (strcmp(rowpp[k], "name") == 0) {
7013  int m;
7014 
7015  for (m = 1; m <= nnrows; m++) {
7016  int roffs = (offs + m) * s->ncols;
7017 
7018  s->rows[roffs + 0] =
7019  xstrdup(stringify(SQL_SCOPE_SESSION));
7020  s->rows[roffs + 1] = xstrdup(rowpp[m * nncols + k]);
7021  s->rows[roffs + 4] = xstrdup("0");
7022  s->rows[roffs + 7] =
7023  xstrdup(stringify(SQL_PC_NOT_PSEUDO));
7024  if (namecc >= 0 && typecc >= 0) {
7025  int ii;
7026 
7027  for (ii = 1; ii <= nnnrows; ii++) {
7028  if (strcmp(rowppp[ii * nnncols + namecc],
7029  rowpp[m * nncols + k]) == 0) {
7030  char *typen = rowppp[ii * nnncols + typecc];
7031  int sqltype, mm, dd, isnullable = 0;
7032  char buf[32];
7033 
7034  s->rows[roffs + 3] = xstrdup(typen);
7035  sqltype = mapsqltype(typen, NULL, *s->ov3,
7036  s->nowchar[0],
7037  s->dobigint);
7038  getmd(typen, sqltype, &mm, &dd);
7039 #ifdef SQL_LONGVARCHAR
7040  if (sqltype == SQL_VARCHAR && mm > 255) {
7041  sqltype = SQL_LONGVARCHAR;
7042  }
7043 #endif
7044 #ifdef WINTERFACE
7045 #ifdef SQL_WLONGVARCHAR
7046  if (sqltype == SQL_WVARCHAR && mm > 255) {
7047  sqltype = SQL_WLONGVARCHAR;
7048  }
7049 #endif
7050 #endif
7051  if (sqltype == SQL_VARBINARY && mm > 255) {
7052  sqltype = SQL_LONGVARBINARY;
7053  }
7054  sprintf(buf, "%d", sqltype);
7055  s->rows[roffs + 2] = xstrdup(buf);
7056  sprintf(buf, "%d", mm);
7057  s->rows[roffs + 5] = xstrdup(buf);
7058  sprintf(buf, "%d", dd);
7059  s->rows[roffs + 6] = xstrdup(buf);
7060  if (notnullcc >= 0) {
7061  char *inp =
7062  rowppp[ii * nnncols + notnullcc];
7063 
7064  isnullable = inp[0] != '0';
7065  }
7066  sprintf(buf, "%d", isnullable);
7067  s->rows[roffs + 8] = xstrdup(buf);
7068  }
7069  }
7070  }
7071  }
7072  }
7073  }
7074  offs += nnrows;
7075  sqlite3_free_table(rowpp);
7076  }
7077  }
7078  if (nullable == SQL_NO_NULLS) {
7079  for (i = 1; i < s->nrows; i++) {
7080  if (s->rows[i * s->ncols + 8][0] == '0') {
7081  int m, i1 = i + 1;
7082 
7083  for (m = 0; m < s->ncols; m++) {
7084  freep(&s->rows[i * s->ncols + m]);
7085  }
7086  size = s->ncols * sizeof (char *) * (s->nrows - i1);
7087  if (size > 0) {
7088  memmove(s->rows + i * s->ncols,
7089  s->rows + i1 * s->ncols,
7090  size);
7091  memset(s->rows + s->nrows * s->ncols, 0,
7092  s->ncols * sizeof (char *));
7093  }
7094  s->nrows--;
7095  --i;
7096  }
7097  }
7098  }
7099 mkrowid:
7100  sqlite3_free_table(rowp);
7101  sqlite3_free_table(rowppp);
7102  if (s->nrows == 0) {
7103  s->rows[s->ncols + 0] = xstrdup(stringify(SQL_SCOPE_SESSION));
7104  s->rows[s->ncols + 1] = xstrdup("_ROWID_");
7105  s->rows[s->ncols + 2] = xstrdup(stringify(SQL_INTEGER));
7106  s->rows[s->ncols + 3] = xstrdup("integer");
7107  s->rows[s->ncols + 4] = xstrdup("0");
7108  s->rows[s->ncols + 5] = xstrdup("10");
7109  s->rows[s->ncols + 6] = xstrdup("9");
7110  s->rows[s->ncols + 7] = xstrdup(stringify(SQL_PC_PSEUDO));
7111  s->rows[s->ncols + 8] = xstrdup(stringify(SQL_FALSE));
7112  s->nrows = 1;
7113  }
7114  return SQL_SUCCESS;
7115 }
7116 
7117 #ifndef WINTERFACE
7118 
7133 SQLRETURN SQL_API
7134 SQLSpecialColumns(SQLHSTMT stmt, SQLUSMALLINT id,
7135  SQLCHAR *cat, SQLSMALLINT catLen,
7136  SQLCHAR *schema, SQLSMALLINT schemaLen,
7137  SQLCHAR *table, SQLSMALLINT tableLen,
7138  SQLUSMALLINT scope, SQLUSMALLINT nullable)
7139 {
7140 #if defined(_WIN32) || defined(_WIN64)
7141  char *c = NULL, *s = NULL, *t = NULL;
7142 #endif
7143  SQLRETURN ret;
7144 
7145  HSTMT_LOCK(stmt);
7146 #if defined(_WIN32) || defined(_WIN64)
7147  if (!((STMT *) stmt)->oemcp[0]) {
7148  ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
7149  table, tableLen, scope, nullable);
7150  goto done2;
7151  }
7152  if (cat) {
7153  c = wmb_to_utf_c((char *) cat, catLen);
7154  if (!c) {
7155  ret = nomem((STMT *) stmt);
7156  goto done;
7157  }
7158  }
7159  if (schema) {
7160  s = wmb_to_utf_c((char *) schema, schemaLen);
7161  if (!s) {
7162  ret = nomem((STMT *) stmt);
7163  goto done;
7164  }
7165  }
7166  if (table) {
7167  t = wmb_to_utf_c((char *) table, tableLen);
7168  if (!t) {
7169  ret = nomem((STMT *) stmt);
7170  goto done;
7171  }
7172  }
7173  ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
7174  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
7175  scope, nullable);
7176 #else
7177  ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
7178  table, tableLen, scope, nullable);
7179 #endif
7180 #if defined(_WIN32) || defined(_WIN64)
7181 done:
7182  uc_free(t);
7183  uc_free(s);
7184  uc_free(c);
7185 done2:
7186  ;
7187 #endif
7188  HSTMT_UNLOCK(stmt);
7189  return ret;
7190 }
7191 #endif
7192 
7193 #ifdef WINTERFACE
7194 
7209 SQLRETURN SQL_API
7210 SQLSpecialColumnsW(SQLHSTMT stmt, SQLUSMALLINT id,
7211  SQLWCHAR *cat, SQLSMALLINT catLen,
7212  SQLWCHAR *schema, SQLSMALLINT schemaLen,
7213  SQLWCHAR *table, SQLSMALLINT tableLen,
7214  SQLUSMALLINT scope, SQLUSMALLINT nullable)
7215 {
7216  char *c = NULL, *s = NULL, *t = NULL;
7217  SQLRETURN ret;
7218 
7219  HSTMT_LOCK(stmt);
7220  if (cat) {
7221  c = uc_to_utf_c(cat, catLen);
7222  if (!c) {
7223  ret = nomem((STMT *) stmt);
7224  goto done;
7225  }
7226  }
7227  if (schema) {
7228  s = uc_to_utf_c(schema, schemaLen);
7229  if (!s) {
7230  ret = nomem((STMT *) stmt);
7231  goto done;
7232  }
7233  }
7234  if (table) {
7235  t = uc_to_utf_c(table, tableLen);
7236  if (!t) {
7237  ret = nomem((STMT *) stmt);
7238  goto done;
7239  }
7240  }
7241  ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
7242  (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
7243  scope, nullable);
7244 done:
7245  uc_free(t);
7246  uc_free(s);
7247  uc_free(c);
7248  HSTMT_UNLOCK(stmt);
7249  return ret;
7250 }
7251 #endif
7252 
7257 static COL fkeySpec2[] = {
7258  { "SYSTEM", "FOREIGNKEY", "PKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
7259  { "SYSTEM", "FOREIGNKEY", "PKTABLE_OWNER", SCOL_VARCHAR, 50 },
7260  { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
7261  { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7262  { "SYSTEM", "FOREIGNKEY", "FKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
7263  { "SYSTEM", "FOREIGNKEY", "FKTABLE_OWNER", SCOL_VARCHAR, 50 },
7264  { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
7265  { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7266  { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
7267  { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
7268  { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
7269  { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
7270  { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
7271  { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
7272 };
7273 
7274 static COL fkeySpec3[] = {
7275  { "SYSTEM", "FOREIGNKEY", "PKTABLE_CAT", SCOL_VARCHAR, 50 },
7276  { "SYSTEM", "FOREIGNKEY", "PKTABLE_SCHEM", SCOL_VARCHAR, 50 },
7277  { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
7278  { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7279  { "SYSTEM", "FOREIGNKEY", "FKTABLE_CAT", SCOL_VARCHAR, 50 },
7280  { "SYSTEM", "FOREIGNKEY", "FKTABLE_SCHEM", SCOL_VARCHAR, 50 },
7281  { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
7282  { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
7283  { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
7284  { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
7285  { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
7286  { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
7287  { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
7288  { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
7289 };
7290 
7309 static SQLRETURN SQL_API
7310 drvforeignkeys(SQLHSTMT stmt,
7311  SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7312  SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
7313  SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
7314  SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7315  SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
7316  SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
7317 {
7318  STMT *s;
7319  DBC *d;
7320  SQLRETURN sret;
7321  int i, asize, ret, nrows, ncols, offs, namec, seqc, fromc, toc;
7322  int onu, ond;
7323  PTRDIFF_T size;
7324  char **rowp, *errp = NULL, *sql, pname[512], fname[512];
7325 
7326  sret = mkresultset(stmt, fkeySpec2, array_size(fkeySpec2),
7327  fkeySpec3, array_size(fkeySpec3), &asize);
7328  if (sret != SQL_SUCCESS) {
7329  return sret;
7330  }
7331  s = (STMT *) stmt;
7332  sret = starttran(s);
7333  if (sret != SQL_SUCCESS) {
7334  return sret;
7335  }
7336  d = (DBC *) s->dbc;
7337  if ((!PKtable || PKtable[0] == '\0' || PKtable[0] == '%') &&
7338  (!FKtable || FKtable[0] == '\0' || FKtable[0] == '%')) {
7339  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
7340  return SQL_ERROR;
7341  }
7342  size = 0;
7343  if (PKtable) {
7344  if (PKtableLen == SQL_NTS) {
7345  size = sizeof (pname) - 1;
7346  } else {
7347  size = min(sizeof (pname) - 1, PKtableLen);
7348  }
7349  strncpy(pname, (char *) PKtable, size);
7350  }
7351  pname[size] = '\0';
7352  size = 0;
7353  if (FKtable) {
7354 
7355  if (FKtableLen == SQL_NTS) {
7356  size = sizeof (fname) - 1;
7357  } else {
7358  size = min(sizeof (fname) - 1, FKtableLen);
7359  }
7360  strncpy(fname, (char *) FKtable, size);
7361  }
7362  fname[size] = '\0';
7363  if (fname[0] != '\0') {
7364  int plen;
7365 
7366  ret = SQLITE_ERROR;
7367  sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", fname);
7368  if (sql) {
7369  dbtraceapi(d, "sqlite3_get_table", sql);
7370  ret = sqlite3_get_table(d->sqlite, sql, &rowp,
7371  &nrows, &ncols, &errp);
7372  sqlite3_free(sql);
7373  }
7374  if (ret != SQLITE_OK) {
7375  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7376  errp ? errp : "unknown error", ret);
7377  if (errp) {
7378  sqlite3_free(errp);
7379  errp = NULL;
7380  }
7381  return SQL_ERROR;
7382  }
7383  if (errp) {
7384  sqlite3_free(errp);
7385  errp = NULL;
7386  }
7387  if (ncols * nrows <= 0) {
7388 nodata:
7389  sqlite3_free_table(rowp);
7390  return SQL_SUCCESS;
7391  }
7392  size = 0;
7393  namec = findcol(rowp, ncols, "table");
7394  seqc = findcol(rowp, ncols, "seq");
7395  fromc = findcol(rowp, ncols, "from");
7396  toc = findcol(rowp, ncols, "to");
7397  onu = findcol(rowp, ncols, "on_update");
7398  ond = findcol(rowp, ncols, "on_delete");
7399  if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7400  goto nodata;
7401  }
7402  plen = strlen(pname);
7403  for (i = 1; i <= nrows; i++) {
7404  char *ptab = unquote(rowp[i * ncols + namec]);
7405 
7406  if (plen && ptab) {
7407  int len = strlen(ptab);
7408 
7409  if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
7410  continue;
7411  }
7412  }
7413  size++;
7414  }
7415  if (size == 0) {
7416  goto nodata;
7417  }
7418  s->nrows = size;
7419  size = (size + 1) * asize;
7420  s->rows = xmalloc((size + 1) * sizeof (char *));
7421  if (!s->rows) {
7422  s->nrows = 0;
7423  return nomem(s);
7424  }
7425  s->rows[0] = (char *) size;
7426  s->rows += 1;
7427  memset(s->rows, 0, sizeof (char *) * size);
7428  s->rowfree = freerows;
7429  offs = 0;
7430  for (i = 1; i <= nrows; i++) {
7431  int pos = 0, roffs = (offs + 1) * s->ncols;
7432  char *ptab = rowp[i * ncols + namec];
7433  char buf[32];
7434 
7435  if (plen && ptab) {
7436  int len = strlen(ptab);
7437 
7438  if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
7439  continue;
7440  }
7441  }
7442 #if defined(_WIN32) || defined(_WIN64)
7443  s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
7444  s->rows[roffs + 1] = xstrdup("");
7445 #else
7446  s->rows[roffs + 0] = xstrdup("");
7447  s->rows[roffs + 1] = xstrdup("");
7448 #endif
7449  s->rows[roffs + 2] = xstrdup(ptab);
7450  s->rows[roffs + 3] = xstrdup(rowp[i * ncols + toc]);
7451  s->rows[roffs + 4] = xstrdup("");
7452  s->rows[roffs + 5] = xstrdup("");
7453  s->rows[roffs + 6] = xstrdup(fname);
7454  s->rows[roffs + 7] = xstrdup(rowp[i * ncols + fromc]);
7455  sscanf(rowp[i * ncols + seqc], "%d", &pos);
7456  sprintf(buf, "%d", pos + 1);
7457  s->rows[roffs + 8] = xstrdup(buf);
7458  if (onu < 0) {
7459  s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7460  } else {
7461  if (strcmp(rowp[i * ncols + onu], "SET NULL") == 0) {
7462  s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
7463  } else if (strcmp(rowp[i * ncols + onu], "SET DEFAULT") == 0) {
7464  s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_DEFAULT));
7465  } else if (strcmp(rowp[i * ncols + onu], "CASCADE") == 0) {
7466  s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
7467  } else if (strcmp(rowp[i * ncols + onu], "RESTRICT") == 0) {
7468  s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
7469  } else {
7470  s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7471  }
7472  }
7473  if (ond < 0) {
7474  s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7475  } else {
7476  if (strcmp(rowp[i * ncols + ond], "SET NULL") == 0) {
7477  s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
7478  } else if (strcmp(rowp[i * ncols + ond], "SET DEFAULT") == 0) {
7479  s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_DEFAULT));
7480  } else if (strcmp(rowp[i * ncols + ond], "CASCADE") == 0) {
7481  s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
7482  } else if (strcmp(rowp[i * ncols + ond], "RESTRICT") == 0) {
7483  s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
7484  } else {
7485  s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7486  }
7487  }
7488  s->rows[roffs + 11] = NULL;
7489  s->rows[roffs + 12] = NULL;
7490  s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
7491  offs++;
7492  }
7493  sqlite3_free_table(rowp);
7494  } else {
7495  int nnrows, nncols, plen = strlen(pname);
7496  char **rowpp;
7497 
7498  sql = "select name from sqlite_master where type='table'";
7499  dbtraceapi(d, "sqlite3_get_table", sql);
7500  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
7501  if (ret != SQLITE_OK) {
7502  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7503  errp ? errp : "unknown error", ret);
7504  if (errp) {
7505  sqlite3_free(errp);
7506  errp = NULL;
7507  }
7508  return SQL_ERROR;
7509  }
7510  if (errp) {
7511  sqlite3_free(errp);
7512  errp = NULL;
7513  }
7514  if (ncols * nrows <= 0) {
7515  goto nodata;
7516  }
7517  size = 0;
7518  for (i = 1; i <= nrows; i++) {
7519  int k;
7520 
7521  if (!rowp[i]) {
7522  continue;
7523  }
7524  rowpp = NULL;
7525  ret = SQLITE_ERROR;
7526  sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
7527  if (sql) {
7528  dbtraceapi(d, "sqlite3_get_table", sql);
7529  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7530  &nnrows, &nncols, NULL);
7531  sqlite3_free(sql);
7532  }
7533  if (ret != SQLITE_OK || nncols * nnrows <= 0) {
7534  sqlite3_free_table(rowpp);
7535  continue;
7536  }
7537  namec = findcol(rowpp, nncols, "table");
7538  seqc = findcol(rowpp, nncols, "seq");
7539  fromc = findcol(rowpp, nncols, "from");
7540  toc = findcol(rowpp, nncols, "to");
7541  if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7542  sqlite3_free_table(rowpp);
7543  continue;
7544  }
7545  for (k = 1; k <= nnrows; k++) {
7546  char *ptab = unquote(rowpp[k * nncols + namec]);
7547 
7548  if (plen && ptab) {
7549  int len = strlen(ptab);
7550 
7551  if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
7552  continue;
7553  }
7554  }
7555  size++;
7556  }
7557  sqlite3_free_table(rowpp);
7558  }
7559  if (size == 0) {
7560  goto nodata;
7561  }
7562  s->nrows = size;
7563  size = (size + 1) * asize;
7564  s->rows = xmalloc((size + 1) * sizeof (char *));
7565  if (!s->rows) {
7566  s->nrows = 0;
7567  return nomem(s);
7568  }
7569  s->rows[0] = (char *) size;
7570  s->rows += 1;
7571  memset(s->rows, 0, sizeof (char *) * size);
7572  s->rowfree = freerows;
7573  offs = 0;
7574  for (i = 1; i <= nrows; i++) {
7575  int k;
7576 
7577  if (!rowp[i]) {
7578  continue;
7579  }
7580  rowpp = NULL;
7581  ret = SQLITE_ERROR;
7582  sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
7583  if (sql) {
7584  dbtraceapi(d, "sqlite3_get_table", sql);
7585  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
7586  &nnrows, &nncols, NULL);
7587  sqlite3_free(sql);
7588  }
7589  if (ret != SQLITE_OK || nncols * nnrows <= 0) {
7590  sqlite3_free_table(rowpp);
7591  continue;
7592  }
7593  namec = findcol(rowpp, nncols, "table");
7594  seqc = findcol(rowpp, nncols, "seq");
7595  fromc = findcol(rowpp, nncols, "from");
7596  toc = findcol(rowpp, nncols, "to");
7597  onu = findcol(rowpp, nncols, "on_update");
7598  ond = findcol(rowpp, nncols, "on_delete");
7599  if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
7600  sqlite3_free_table(rowpp);
7601  continue;
7602  }
7603  for (k = 1; k <= nnrows; k++) {
7604  int pos = 0, roffs = (offs + 1) * s->ncols;
7605  char *ptab = unquote(rowpp[k * nncols + namec]);
7606  char buf[32];
7607 
7608  if (plen && ptab) {
7609  int len = strlen(ptab);
7610 
7611  if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
7612  continue;
7613  }
7614  }
7615 #if defined(_WIN32) || defined(_WIN64)
7616  s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
7617  s->rows[roffs + 1] = xstrdup("");
7618 #else
7619  s->rows[roffs + 0] = xstrdup("");
7620  s->rows[roffs + 1] = xstrdup("");
7621 #endif
7622  s->rows[roffs + 2] = xstrdup(ptab);
7623  s->rows[roffs + 3] = xstrdup(rowpp[k * nncols + toc]);
7624  s->rows[roffs + 4] = xstrdup("");
7625  s->rows[roffs + 5] = xstrdup("");
7626  s->rows[roffs + 6] = xstrdup(rowp[i]);
7627  s->rows[roffs + 7] = xstrdup(rowpp[k * nncols + fromc]);
7628  sscanf(rowpp[k * nncols + seqc], "%d", &pos);
7629  sprintf(buf, "%d", pos + 1);
7630  s->rows[roffs + 8] = xstrdup(buf);
7631  if (onu < 0) {
7632  s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
7633  } else {
7634  if (strcmp(rowpp[k * nncols + onu], "SET NULL") == 0) {
7635  s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
7636  } else if (strcmp(rowpp[k * nncols + onu], "SET DEFAULT")
7637  == 0) {
7638  s->rows[roffs + 9] =
7639  xstrdup(stringify(SQL_SET_DEFAULT));
7640  } else if (strcmp(rowpp[k * nncols + onu], "CASCADE")
7641  == 0) {
7642  s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
7643  } else if (strcmp(rowpp[k * nncols + onu], "RESTRICT")
7644  == 0) {
7645  s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
7646  } else {
7647  s->rows[roffs + 9] =
7648  xstrdup(stringify(SQL_NO_ACTION));
7649  }
7650  }
7651  if (ond < 0) {
7652  s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
7653  } else {
7654  if (strcmp(rowpp[k * nncols + ond], "SET NULL") == 0) {
7655  s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
7656  } else if (strcmp(rowpp[k * nncols + ond], "SET DEFAULT")
7657  == 0) {
7658  s->rows[roffs + 10] =
7659  xstrdup(stringify(SQL_SET_DEFAULT));
7660  } else if (strcmp(rowpp[k * nncols + ond], "CASCADE")
7661  == 0) {
7662  s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
7663  } else if (strcmp(rowpp[k * nncols + ond], "RESTRICT")
7664  == 0) {
7665  s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
7666  } else {
7667  s->rows[roffs + 10] =
7668  xstrdup(stringify(SQL_NO_ACTION));
7669  }
7670  }
7671  s->rows[roffs + 11] = NULL;
7672  s->rows[roffs + 12] = NULL;
7673  s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
7674  offs++;
7675  }
7676  sqlite3_free_table(rowpp);
7677  }
7678  sqlite3_free_table(rowp);
7679  }
7680  return SQL_SUCCESS;
7681 }
7682 
7683 #ifndef WINTERFACE
7684 
7702 SQLRETURN SQL_API
7703 SQLForeignKeys(SQLHSTMT stmt,
7704  SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7705  SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
7706  SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
7707  SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7708  SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
7709  SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
7710 {
7711 #if defined(_WIN32) || defined(_WIN64)
7712  char *pc = NULL, *ps = NULL, *pt = NULL;
7713  char *fc = NULL, *fs = NULL, *ft = NULL;
7714 #endif
7715  SQLRETURN ret;
7716 
7717  HSTMT_LOCK(stmt);
7718 #if defined(_WIN32) || defined(_WIN64)
7719  if (!((STMT *) stmt)->oemcp[0]) {
7720  ret = drvforeignkeys(stmt,
7721  PKcatalog, PKcatalogLen,
7722  PKschema, PKschemaLen, PKtable, PKtableLen,
7723  FKcatalog, FKcatalogLen,
7724  FKschema, FKschemaLen,
7725  FKtable, FKtableLen);
7726  goto done2;
7727  }
7728  if (PKcatalog) {
7729  pc = wmb_to_utf_c((char *) PKcatalog, PKcatalogLen);
7730  if (!pc) {
7731  ret = nomem((STMT *) stmt);
7732  goto done;
7733  }
7734  }
7735  if (PKschema) {
7736  ps = wmb_to_utf_c((char *) PKschema, PKschemaLen);
7737  if (!ps) {
7738  ret = nomem((STMT *) stmt);
7739  goto done;
7740  }
7741  }
7742  if (PKtable) {
7743  pt = wmb_to_utf_c((char *) PKtable, PKtableLen);
7744  if (!pt) {
7745  ret = nomem((STMT *) stmt);
7746  goto done;
7747  }
7748  }
7749  if (FKcatalog) {
7750  fc = wmb_to_utf_c((char *) FKcatalog, FKcatalogLen);
7751  if (!fc) {
7752  ret = nomem((STMT *) stmt);
7753  goto done;
7754  }
7755  }
7756  if (FKschema) {
7757  fs = wmb_to_utf_c((char *) FKschema, FKschemaLen);
7758  if (!fs) {
7759  ret = nomem((STMT *) stmt);
7760  goto done;
7761  }
7762  }
7763  if (FKtable) {
7764  ft = wmb_to_utf_c((char *) FKtable, FKtableLen);
7765  if (!ft) {
7766  ret = nomem((STMT *) stmt);
7767  goto done;
7768  }
7769  }
7770  ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
7771  (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
7772  (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
7773  (SQLCHAR *) ft, SQL_NTS);
7774 #else
7775  ret = drvforeignkeys(stmt,
7776  PKcatalog, PKcatalogLen,
7777  PKschema, PKschemaLen, PKtable, PKtableLen,
7778  FKcatalog, FKcatalogLen,
7779  FKschema, FKschemaLen,
7780  FKtable, FKtableLen);
7781 #endif
7782 #if defined(_WIN32) || defined(_WIN64)
7783 done:
7784  uc_free(ft);
7785  uc_free(fs);
7786  uc_free(fc);
7787  uc_free(pt);
7788  uc_free(ps);
7789  uc_free(pc);
7790 done2:
7791  ;
7792 #endif
7793  HSTMT_UNLOCK(stmt);
7794  return ret;
7795 }
7796 #endif
7797 
7798 #ifdef WINTERFACE
7799 
7817 SQLRETURN SQL_API
7818 SQLForeignKeysW(SQLHSTMT stmt,
7819  SQLWCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
7820  SQLWCHAR *PKschema, SQLSMALLINT PKschemaLen,
7821  SQLWCHAR *PKtable, SQLSMALLINT PKtableLen,
7822  SQLWCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
7823  SQLWCHAR *FKschema, SQLSMALLINT FKschemaLen,
7824  SQLWCHAR *FKtable, SQLSMALLINT FKtableLen)
7825 {
7826  char *pc = NULL, *ps = NULL, *pt = NULL;
7827  char *fc = NULL, *fs = NULL, *ft = NULL;
7828  SQLRETURN ret;
7829 
7830  HSTMT_LOCK(stmt);
7831  if (PKcatalog) {
7832  pc = uc_to_utf_c(PKcatalog, PKcatalogLen);
7833  if (!pc) {
7834  ret = nomem((STMT *) stmt);
7835  goto done;
7836  }
7837  }
7838  if (PKschema) {
7839  ps = uc_to_utf_c(PKschema, PKschemaLen);
7840  if (!ps) {
7841  ret = nomem((STMT *) stmt);
7842  goto done;
7843  }
7844  }
7845  if (PKtable) {
7846  pt = uc_to_utf_c(PKtable, PKtableLen);
7847  if (!pt) {
7848  ret = nomem((STMT *) stmt);
7849  goto done;
7850  }
7851  }
7852  if (FKcatalog) {
7853  fc = uc_to_utf_c(FKcatalog, FKcatalogLen);
7854  if (!fc) {
7855  ret = nomem((STMT *) stmt);
7856  goto done;
7857  }
7858  }
7859  if (FKschema) {
7860  fs = uc_to_utf_c(FKschema, FKschemaLen);
7861  if (!fs) {
7862  ret = nomem((STMT *) stmt);
7863  goto done;
7864  }
7865  }
7866  if (FKtable) {
7867  ft = uc_to_utf_c(FKtable, FKtableLen);
7868  if (!ft) {
7869  ret = nomem((STMT *) stmt);
7870  goto done;
7871  }
7872  }
7873  ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
7874  (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
7875  (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
7876  (SQLCHAR *) ft, SQL_NTS);
7877 done:
7878  uc_free(ft);
7879  uc_free(fs);
7880  uc_free(fc);
7881  uc_free(pt);
7882  uc_free(ps);
7883  uc_free(pc);
7884  HSTMT_UNLOCK(stmt);
7885  return ret;
7886 }
7887 #endif
7888 
7895 static SQLRETURN
7897 {
7898  int ret = SQL_SUCCESS, rc, busy_count = 0;
7899  char *errp = NULL;
7900  DBC *d = (DBC *) s->dbc;
7901 
7902  if (!d->autocommit && !d->intrans && !d->trans_disable) {
7903 begin_again:
7904  rc = sqlite3_exec(d->sqlite, "BEGIN TRANSACTION", NULL, NULL, &errp);
7905  if (rc == SQLITE_BUSY) {
7906  if (busy_handler((void *) d, ++busy_count)) {
7907  if (errp) {
7908  sqlite3_free(errp);
7909  errp = NULL;
7910  }
7911  goto begin_again;
7912  }
7913  }
7914  dbtracerc(d, rc, errp);
7915  if (rc != SQLITE_OK) {
7916  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
7917  errp ? errp : "unknown error", rc);
7918  ret = SQL_ERROR;
7919  } else {
7920  d->intrans = 1;
7921  }
7922  if (errp) {
7923  sqlite3_free(errp);
7924  errp = NULL;
7925  }
7926  }
7927  return ret;
7928 }
7929 
7938 static SQLRETURN
7939 endtran(DBC *d, SQLSMALLINT comptype, int force)
7940 {
7941  int ret, busy_count = 0;
7942  char *sql, *errp = NULL;
7943 
7944  if (!d->sqlite) {
7945  setstatd(d, -1, "not connected", (*d->ov3) ? "HY000" : "S1000");
7946  return SQL_ERROR;
7947  }
7948  if ((!force && d->autocommit) || !d->intrans) {
7949  return SQL_SUCCESS;
7950  }
7951  switch (comptype) {
7952  case SQL_COMMIT:
7953  sql = "COMMIT TRANSACTION";
7954  goto doit;
7955  case SQL_ROLLBACK:
7956  sql = "ROLLBACK TRANSACTION";
7957  doit:
7958  ret = sqlite3_exec(d->sqlite, sql, NULL, NULL, &errp);
7959  dbtracerc(d, ret, errp);
7960  if (ret == SQLITE_BUSY && busy_count < 10) {
7961  if (busy_handler((void *) d, ++busy_count)) {
7962  if (errp) {
7963  sqlite3_free(errp);
7964  errp = NULL;
7965  }
7966  goto doit;
7967  }
7968  }
7969  if (ret != SQLITE_OK) {
7970  setstatd(d, ret, "%s", (*d->ov3) ? "HY000" : "S1000",
7971  errp ? errp : "transaction failed");
7972  if (errp) {
7973  sqlite3_free(errp);
7974  errp = NULL;
7975  }
7976  return SQL_ERROR;
7977  }
7978  if (errp) {
7979  sqlite3_free(errp);
7980  errp = NULL;
7981  }
7982  d->intrans = 0;
7983  return SQL_SUCCESS;
7984  }
7985  setstatd(d, -1, "invalid completion type", (*d->ov3) ? "HY000" : "S1000");
7986  return SQL_ERROR;
7987 }
7988 
7997 static SQLRETURN
7998 drvendtran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
7999 {
8000  DBC *d = NULL;
8001  int fail = 0;
8002  SQLRETURN ret;
8003 #if defined(_WIN32) || defined(_WIN64)
8004  ENV *e;
8005 #endif
8006 
8007  switch (type) {
8008  case SQL_HANDLE_DBC:
8009  HDBC_LOCK((SQLHDBC) handle);
8010  if (handle == SQL_NULL_HDBC) {
8011  return SQL_INVALID_HANDLE;
8012  }
8013  d = (DBC *) handle;
8014  ret = endtran(d, comptype, 0);
8015  HDBC_UNLOCK((SQLHDBC) handle);
8016  return ret;
8017  case SQL_HANDLE_ENV:
8018  if (handle == SQL_NULL_HENV) {
8019  return SQL_INVALID_HANDLE;
8020  }
8021 #if defined(_WIN32) || defined(_WIN64)
8022  e = (ENV *) handle;
8023  if (e->magic != ENV_MAGIC) {
8024  return SQL_INVALID_HANDLE;
8025  }
8026  EnterCriticalSection(&e->cs);
8027 #endif
8028  d = ((ENV *) handle)->dbcs;
8029  while (d) {
8030  HDBC_LOCK((SQLHDBC) d);
8031  ret = endtran(d, comptype, 0);
8032  HDBC_UNLOCK((SQLHDBC) d);
8033  if (ret != SQL_SUCCESS) {
8034  fail++;
8035  }
8036  d = d->next;
8037  }
8038 #if defined(_WIN32) || defined(_WIN64)
8039  LeaveCriticalSection(&e->cs);
8040 #endif
8041  return fail ? SQL_ERROR : SQL_SUCCESS;
8042  }
8043  return SQL_INVALID_HANDLE;
8044 }
8045 
8054 SQLRETURN SQL_API
8055 SQLEndTran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
8056 {
8057  return drvendtran(type, handle, comptype);
8058 }
8059 
8068 SQLRETURN SQL_API
8069 SQLTransact(SQLHENV env, SQLHDBC dbc, SQLUSMALLINT type)
8070 {
8071  if (dbc != SQL_NULL_HDBC) {
8072  return drvendtran(SQL_HANDLE_DBC, (SQLHANDLE) dbc, type);
8073  }
8074  return drvendtran(SQL_HANDLE_ENV, (SQLHANDLE) env, type);
8075 }
8076 
8081 SQLRETURN SQL_API
8082 SQLCopyDesc(SQLHDESC source, SQLHDESC target)
8083 {
8084  return SQL_ERROR;
8085 }
8086 
8087 #ifndef WINTERFACE
8088 
8099 SQLRETURN SQL_API
8100 SQLNativeSql(SQLHSTMT stmt, SQLCHAR *sqlin, SQLINTEGER sqlinLen,
8101  SQLCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
8102 {
8103  int outLen = 0;
8104  SQLRETURN ret = SQL_SUCCESS;
8105 
8106  HSTMT_LOCK(stmt);
8107  if (sqlinLen == SQL_NTS) {
8108  sqlinLen = strlen((char *) sqlin);
8109  }
8110  if (sql) {
8111  if (sqlMax > 0) {
8112  strncpy((char *) sql, (char *) sqlin, sqlMax - 1);
8113  sqlin[sqlMax - 1] = '\0';
8114  outLen = min(sqlMax - 1, sqlinLen);
8115  }
8116  } else {
8117  outLen = sqlinLen;
8118  }
8119  if (sqlLen) {
8120  *sqlLen = outLen;
8121  }
8122  if (sql && outLen < sqlinLen) {
8123  setstat((STMT *) stmt, -1, "data right truncated", "01004");
8124  ret = SQL_SUCCESS_WITH_INFO;
8125  }
8126  HSTMT_UNLOCK(stmt);
8127  return ret;
8128 }
8129 #endif
8130 
8131 #ifdef WINTERFACE
8132 
8143 SQLRETURN SQL_API
8144 SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen,
8145  SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
8146 {
8147  int outLen = 0;
8148  SQLRETURN ret = SQL_SUCCESS;
8149 
8150  HSTMT_LOCK(stmt);
8151  if (sqlinLen == SQL_NTS) {
8152  sqlinLen = uc_strlen(sqlin);
8153  }
8154  if (sql) {
8155  if (sqlMax > 0) {
8156  uc_strncpy(sql, sqlin, sqlMax - 1);
8157  sqlin[sqlMax - 1] = 0;
8158  outLen = min(sqlMax - 1, sqlinLen);
8159  }
8160  } else {
8161  outLen = sqlinLen;
8162  }
8163  if (sqlLen) {
8164  *sqlLen = outLen;
8165  }
8166  if (sql && outLen < sqlinLen) {
8167  setstat((STMT *) stmt, -1, "data right truncated", "01004");
8168  ret = SQL_SUCCESS_WITH_INFO;
8169  }
8170  HSTMT_UNLOCK(stmt);
8171  return ret;
8172 }
8173 #endif
8174 
8179 static COL procSpec2[] = {
8180  { "SYSTEM", "PROCEDURE", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
8181  { "SYSTEM", "PROCEDURE", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
8182  { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8183  { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
8184  { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
8185  { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
8186  { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
8187  { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
8188 };
8189 
8190 static COL procSpec3[] = {
8191  { "SYSTEM", "PROCEDURE", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
8192  { "SYSTEM", "PROCEDURE", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
8193  { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8194  { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
8195  { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
8196  { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
8197  { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
8198  { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
8199 };
8200 
8201 #ifndef WINTERFACE
8202 
8214 SQLRETURN SQL_API
8215 SQLProcedures(SQLHSTMT stmt,
8216  SQLCHAR *catalog, SQLSMALLINT catalogLen,
8217  SQLCHAR *schema, SQLSMALLINT schemaLen,
8218  SQLCHAR *proc, SQLSMALLINT procLen)
8219 {
8220  SQLRETURN ret;
8221 
8222  HSTMT_LOCK(stmt);
8223  ret = mkresultset(stmt, procSpec2, array_size(procSpec2),
8224  procSpec3, array_size(procSpec3), NULL);
8225  HSTMT_UNLOCK(stmt);
8226  return ret;
8227 }
8228 #endif
8229 
8230 #ifdef WINTERFACE
8231 
8243 SQLRETURN SQL_API
8244 SQLProceduresW(SQLHSTMT stmt,
8245  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
8246  SQLWCHAR *schema, SQLSMALLINT schemaLen,
8247  SQLWCHAR *proc, SQLSMALLINT procLen)
8248 {
8249  SQLRETURN ret;
8250 
8251  HSTMT_LOCK(stmt);
8252  ret = mkresultset(stmt, procSpec2, array_size(procSpec2),
8253  procSpec3, array_size(procSpec3), NULL);
8254  HSTMT_UNLOCK(stmt);
8255  return ret;
8256 }
8257 #endif
8258 
8263 static COL procColSpec2[] = {
8264  { "SYSTEM", "PROCCOL", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
8265  { "SYSTEM", "PROCCOL", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
8266  { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8267  { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
8268  { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
8269  { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
8270  { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
8271  { "SYSTEM", "PROCCOL", "PRECISION", SQL_INTEGER, 10 },
8272  { "SYSTEM", "PROCCOL", "LENGTH", SQL_INTEGER, 10 },
8273  { "SYSTEM", "PROCCOL", "SCALE", SQL_SMALLINT, 5 },
8274  { "SYSTEM", "PROCCOL", "RADIX", SQL_SMALLINT, 5 },
8275  { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
8276  { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
8277  { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
8278  { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
8279  { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
8280  { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
8281  { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
8282  { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
8283 };
8284 
8285 static COL procColSpec3[] = {
8286  { "SYSTEM", "PROCCOL", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
8287  { "SYSTEM", "PROCCOL", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
8288  { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
8289  { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
8290  { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
8291  { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
8292  { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
8293  { "SYSTEM", "PROCCOL", "COLUMN_SIZE", SQL_INTEGER, 10 },
8294  { "SYSTEM", "PROCCOL", "BUFFER_LENGTH", SQL_INTEGER, 10 },
8295  { "SYSTEM", "PROCCOL", "DECIMAL_DIGITS", SQL_SMALLINT, 5 },
8296  { "SYSTEM", "PROCCOL", "NUM_PREC_RADIX", SQL_SMALLINT, 5 },
8297  { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
8298  { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
8299  { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
8300  { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
8301  { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
8302  { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
8303  { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
8304  { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
8305 };
8306 
8307 #ifndef WINTERFACE
8308 
8322 SQLRETURN SQL_API
8323 SQLProcedureColumns(SQLHSTMT stmt,
8324  SQLCHAR *catalog, SQLSMALLINT catalogLen,
8325  SQLCHAR *schema, SQLSMALLINT schemaLen,
8326  SQLCHAR *proc, SQLSMALLINT procLen,
8327  SQLCHAR *column, SQLSMALLINT columnLen)
8328 {
8329  SQLRETURN ret;
8330 
8331  HSTMT_LOCK(stmt);
8332  ret = mkresultset(stmt, procColSpec2, array_size(procColSpec2),
8333  procColSpec3, array_size(procColSpec3), NULL);
8334  HSTMT_UNLOCK(stmt);
8335  return ret;
8336 }
8337 #endif
8338 
8339 #ifdef WINTERFACE
8340 
8355 SQLRETURN SQL_API
8356 SQLProcedureColumnsW(SQLHSTMT stmt,
8357  SQLWCHAR *catalog, SQLSMALLINT catalogLen,
8358  SQLWCHAR *schema, SQLSMALLINT schemaLen,
8359  SQLWCHAR *proc, SQLSMALLINT procLen,
8360  SQLWCHAR *column, SQLSMALLINT columnLen)
8361 {
8362  SQLRETURN ret;
8363 
8364  HSTMT_LOCK(stmt);
8365  ret = mkresultset(stmt, procColSpec2, array_size(procColSpec2),
8366  procColSpec3, array_size(procColSpec3), NULL);
8367  HSTMT_UNLOCK(stmt);
8368  return ret;
8369 }
8370 #endif
8371 
8382 SQLRETURN SQL_API
8383 SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val,
8384  SQLINTEGER len, SQLINTEGER *lenp)
8385 {
8386  ENV *e;
8387  SQLRETURN ret = SQL_ERROR;
8388 
8389  if (env == SQL_NULL_HENV) {
8390  return SQL_INVALID_HANDLE;
8391  }
8392  e = (ENV *) env;
8393  if (!e || e->magic != ENV_MAGIC) {
8394  return SQL_INVALID_HANDLE;
8395  }
8396 #if defined(_WIN32) || defined(_WIN64)
8397  EnterCriticalSection(&e->cs);
8398 #endif
8399  switch (attr) {
8400  case SQL_ATTR_CONNECTION_POOLING:
8401  ret = SQL_ERROR;
8402  break;
8403  case SQL_ATTR_CP_MATCH:
8404  ret = SQL_NO_DATA;
8405  break;
8406  case SQL_ATTR_OUTPUT_NTS:
8407  if (val) {
8408  *((SQLINTEGER *) val) = SQL_TRUE;
8409  }
8410  if (lenp) {
8411  *lenp = sizeof (SQLINTEGER);
8412  }
8413  ret = SQL_SUCCESS;
8414  break;
8415  case SQL_ATTR_ODBC_VERSION:
8416  if (val) {
8417  *((SQLINTEGER *) val) = e->ov3 ? SQL_OV_ODBC3 : SQL_OV_ODBC2;
8418  }
8419  if (lenp) {
8420  *lenp = sizeof (SQLINTEGER);
8421  }
8422  ret = SQL_SUCCESS;
8423  break;
8424  }
8425 #if defined(_WIN32) || defined(_WIN64)
8426  LeaveCriticalSection(&e->cs);
8427 #endif
8428  return ret;
8429 }
8430 
8440 SQLRETURN SQL_API
8441 SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
8442 {
8443  ENV *e;
8444  SQLRETURN ret = SQL_ERROR;
8445 
8446  if (env == SQL_NULL_HENV) {
8447  return SQL_INVALID_HANDLE;
8448  }
8449  e = (ENV *) env;
8450  if (!e || e->magic != ENV_MAGIC) {
8451  return SQL_INVALID_HANDLE;
8452  }
8453 #if defined(_WIN32) || defined(_WIN64)
8454  EnterCriticalSection(&e->cs);
8455 #endif
8456  switch (attr) {
8457  case SQL_ATTR_CONNECTION_POOLING:
8458  ret = SQL_SUCCESS;
8459  break;
8460  case SQL_ATTR_CP_MATCH:
8461  ret = SQL_NO_DATA;
8462  break;
8463  case SQL_ATTR_OUTPUT_NTS:
8464  if (val == (SQLPOINTER) SQL_TRUE) {
8465  ret = SQL_SUCCESS;
8466  }
8467  break;
8468  case SQL_ATTR_ODBC_VERSION:
8469  if (!val) {
8470  break;
8471  }
8472  if (val == (SQLPOINTER) SQL_OV_ODBC2) {
8473  e->ov3 = 0;
8474  ret = SQL_SUCCESS;
8475  }
8476  if (val == (SQLPOINTER) SQL_OV_ODBC3) {
8477  e->ov3 = 1;
8478  ret = SQL_SUCCESS;
8479  }
8480  break;
8481  }
8482 #if defined(_WIN32) || defined(_WIN64)
8483  LeaveCriticalSection(&e->cs);
8484 #endif
8485  return ret;
8486 }
8487 
8501 static SQLRETURN
8502 drvgetdiagrec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8503  SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
8504  SQLSMALLINT buflen, SQLSMALLINT *msglen)
8505 {
8506  DBC *d = NULL;
8507  STMT *s = NULL;
8508  int len, naterr;
8509  char *logmsg, *sqlst;
8510  SQLRETURN ret = SQL_ERROR;
8511 
8512  if (handle == SQL_NULL_HANDLE) {
8513  return SQL_INVALID_HANDLE;
8514  }
8515  if (sqlstate) {
8516  sqlstate[0] = '\0';
8517  }
8518  if (msg && buflen > 0) {
8519  msg[0] = '\0';
8520  }
8521  if (msglen) {
8522  *msglen = 0;
8523  }
8524  if (nativeerr) {
8525  *nativeerr = 0;
8526  }
8527  switch (htype) {
8528  case SQL_HANDLE_ENV:
8529  case SQL_HANDLE_DESC:
8530  return SQL_NO_DATA;
8531  case SQL_HANDLE_DBC:
8532  HDBC_LOCK((SQLHDBC) handle);
8533  d = (DBC *) handle;
8534  logmsg = (char *) d->logmsg;
8535  sqlst = d->sqlstate;
8536  naterr = d->naterr;
8537  break;
8538  case SQL_HANDLE_STMT:
8539  HSTMT_LOCK((SQLHSTMT) handle);
8540  s = (STMT *) handle;
8541  logmsg = (char *) s->logmsg;
8542  sqlst = s->sqlstate;
8543  naterr = s->naterr;
8544  break;
8545  default:
8546  return SQL_INVALID_HANDLE;
8547  }
8548  if (buflen < 0) {
8549  goto done;
8550  }
8551  if (recno > 1) {
8552  ret = SQL_NO_DATA;
8553  goto done;
8554  }
8555  len = strlen(logmsg);
8556  if (len == 0) {
8557  ret = SQL_NO_DATA;
8558  goto done;
8559  }
8560  if (nativeerr) {
8561  *nativeerr = naterr;
8562  }
8563  if (sqlstate) {
8564  strcpy((char *) sqlstate, sqlst);
8565  }
8566  if (msglen) {
8567  *msglen = len;
8568  }
8569  if (len >= buflen) {
8570  if (msg && buflen > 0) {
8571  strncpy((char *) msg, logmsg, buflen);
8572  msg[buflen - 1] = '\0';
8573  logmsg[0] = '\0';
8574  }
8575  } else if (msg) {
8576  strcpy((char *) msg, logmsg);
8577  logmsg[0] = '\0';
8578  }
8579  ret = SQL_SUCCESS;
8580 done:
8581  switch (htype) {
8582  case SQL_HANDLE_DBC:
8583  HDBC_UNLOCK((SQLHDBC) handle);
8584  break;
8585  case SQL_HANDLE_STMT:
8586  HSTMT_UNLOCK((SQLHSTMT) handle);
8587  break;
8588  }
8589  return ret;
8590 }
8591 
8592 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
8593 
8606 SQLRETURN SQL_API
8607 SQLGetDiagRec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8608  SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
8609  SQLSMALLINT buflen, SQLSMALLINT *msglen)
8610 {
8611  return drvgetdiagrec(htype, handle, recno, sqlstate,
8612  nativeerr, msg, buflen, msglen);
8613 }
8614 #endif
8615 
8616 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
8617 #ifdef WINTERFACE
8618 
8632 SQLRETURN SQL_API
8633 SQLGetDiagRecW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8634  SQLWCHAR *sqlstate, SQLINTEGER *nativeerr, SQLWCHAR *msg,
8635  SQLSMALLINT buflen, SQLSMALLINT *msglen)
8636 {
8637  char state[16];
8638  SQLSMALLINT len;
8639  SQLRETURN ret;
8640 
8641  ret = drvgetdiagrec(htype, handle, recno, (SQLCHAR *) state,
8642  nativeerr, (SQLCHAR *) msg, buflen, &len);
8643  if (ret == SQL_SUCCESS) {
8644  if (sqlstate) {
8645  uc_from_utf_buf((SQLCHAR *) state, -1, sqlstate,
8646  6 * sizeof (SQLWCHAR));
8647  }
8648  if (msg) {
8649  if (len > 0) {
8650  SQLWCHAR *m = NULL;
8651 
8652  m = uc_from_utf((unsigned char *) msg, len);
8653  if (m) {
8654  if (buflen) {
8655  buflen /= sizeof (SQLWCHAR);
8656  uc_strncpy(msg, m, buflen);
8657  m[len] = 0;
8658  len = min(buflen, uc_strlen(m));
8659  } else {
8660  len = uc_strlen(m);
8661  }
8662  uc_free(m);
8663  } else {
8664  len = 0;
8665  }
8666  }
8667  if (len <= 0) {
8668  len = 0;
8669  if (buflen > 0) {
8670  msg[0] = 0;
8671  }
8672  }
8673  } else {
8674  /* estimated length !!! */
8675  len *= sizeof (SQLWCHAR);
8676  }
8677  if (msglen) {
8678  *msglen = len;
8679  }
8680  } else if (ret == SQL_NO_DATA) {
8681  if (sqlstate) {
8682  sqlstate[0] = 0;
8683  }
8684  if (msg) {
8685  if (buflen > 0) {
8686  msg[0] = 0;
8687  }
8688  }
8689  if (msglen) {
8690  *msglen = 0;
8691  }
8692  }
8693  return ret;
8694 }
8695 #endif
8696 #endif
8697 
8710 static SQLRETURN
8711 drvgetdiagfield(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8712  SQLSMALLINT id, SQLPOINTER info,
8713  SQLSMALLINT buflen, SQLSMALLINT *stringlen)
8714 {
8715  DBC *d = NULL;
8716  STMT *s = NULL;
8717  int len, naterr, strbuf = 1;
8718  char *logmsg, *sqlst, *clrmsg = NULL;
8719  SQLRETURN ret = SQL_ERROR;
8720 
8721  if (handle == SQL_NULL_HANDLE) {
8722  return SQL_INVALID_HANDLE;
8723  }
8724  if (stringlen) {
8725  *stringlen = 0;
8726  }
8727  switch (htype) {
8728  case SQL_HANDLE_ENV:
8729  case SQL_HANDLE_DESC:
8730  return SQL_NO_DATA;
8731  case SQL_HANDLE_DBC:
8732  HDBC_LOCK((SQLHDBC) handle);
8733  d = (DBC *) handle;
8734  logmsg = (char *) d->logmsg;
8735  sqlst = d->sqlstate;
8736  naterr = d->naterr;
8737  break;
8738  case SQL_HANDLE_STMT:
8739  HSTMT_LOCK((SQLHSTMT) handle);
8740  s = (STMT *) handle;
8741  d = (DBC *) s->dbc;
8742  logmsg = (char *) s->logmsg;
8743  sqlst = s->sqlstate;
8744  naterr = s->naterr;
8745  break;
8746  default:
8747  return SQL_INVALID_HANDLE;
8748  }
8749  if (buflen < 0) {
8750  switch (buflen) {
8751  case SQL_IS_POINTER:
8752  case SQL_IS_UINTEGER:
8753  case SQL_IS_INTEGER:
8754  case SQL_IS_USMALLINT:
8755  case SQL_IS_SMALLINT:
8756  strbuf = 0;
8757  break;
8758  default:
8759  ret = SQL_ERROR;
8760  goto done;
8761  }
8762  }
8763  if (recno > 1) {
8764  ret = SQL_NO_DATA;
8765  goto done;
8766  }
8767  switch (id) {
8768  case SQL_DIAG_CLASS_ORIGIN:
8769  logmsg = "ISO 9075";
8770  if (sqlst[0] == 'I' && sqlst[1] == 'M') {
8771  logmsg = "ODBC 3.0";
8772  }
8773  break;
8774  case SQL_DIAG_SUBCLASS_ORIGIN:
8775  logmsg = "ISO 9075";
8776  if (sqlst[0] == 'I' && sqlst[1] == 'M') {
8777  logmsg = "ODBC 3.0";
8778  } else if (sqlst[0] == 'H' && sqlst[1] == 'Y') {
8779  logmsg = "ODBC 3.0";
8780  } else if (sqlst[0] == '2' || sqlst[0] == '0' || sqlst[0] == '4') {
8781  logmsg = "ODBC 3.0";
8782  }
8783  break;
8784  case SQL_DIAG_CONNECTION_NAME:
8785  case SQL_DIAG_SERVER_NAME:
8786  logmsg = d->dsn ? d->dsn : "No DSN";
8787  break;
8788  case SQL_DIAG_SQLSTATE:
8789  logmsg = sqlst;
8790  break;
8791  case SQL_DIAG_MESSAGE_TEXT:
8792  if (info) {
8793  clrmsg = logmsg;
8794  }
8795  break;
8796  case SQL_DIAG_NUMBER:
8797  naterr = 1;
8798  /* fall through */
8799  case SQL_DIAG_NATIVE:
8800  len = strlen(logmsg);
8801  if (len == 0) {
8802  ret = SQL_NO_DATA;
8803  goto done;
8804  }
8805  if (info) {
8806  *((SQLINTEGER *) info) = naterr;
8807  }
8808  ret = SQL_SUCCESS;
8809  goto done;
8810  case SQL_DIAG_DYNAMIC_FUNCTION:
8811  logmsg = "";
8812  break;
8813  case SQL_DIAG_CURSOR_ROW_COUNT:
8814  if (htype == SQL_HANDLE_STMT) {
8815  SQLULEN count;
8816 
8817  count = (s->isselect == 1 || s->isselect == -1) ? s->nrows : 0;
8818  *((SQLULEN *) info) = count;
8819  ret = SQL_SUCCESS;
8820  }
8821  goto done;
8822  case SQL_DIAG_ROW_COUNT:
8823  if (htype == SQL_HANDLE_STMT) {
8824  SQLULEN count;
8825 
8826  count = s->isselect ? 0 : s->nrows;
8827  *((SQLULEN *) info) = count;
8828  ret = SQL_SUCCESS;
8829  }
8830  goto done;
8831  default:
8832  goto done;
8833  }
8834  if (info && buflen > 0) {
8835  ((char *) info)[0] = '\0';
8836  }
8837  len = strlen(logmsg);
8838  if (len == 0) {
8839  ret = SQL_NO_DATA;
8840  goto done;
8841  }
8842  if (stringlen) {
8843  *stringlen = len;
8844  }
8845  if (strbuf) {
8846  if (len >= buflen) {
8847  if (info && buflen > 0) {
8848  if (stringlen) {
8849  *stringlen = buflen - 1;
8850  }
8851  strncpy((char *) info, logmsg, buflen);
8852  ((char *) info)[buflen - 1] = '\0';
8853  }
8854  } else if (info) {
8855  strcpy((char *) info, logmsg);
8856  }
8857  }
8858  if (clrmsg) {
8859  *clrmsg = '\0';
8860  }
8861  ret = SQL_SUCCESS;
8862 done:
8863  switch (htype) {
8864  case SQL_HANDLE_DBC:
8865  HDBC_UNLOCK((SQLHDBC) handle);
8866  break;
8867  case SQL_HANDLE_STMT:
8868  HSTMT_UNLOCK((SQLHSTMT) handle);
8869  break;
8870  }
8871  return ret;
8872 }
8873 
8874 #ifndef WINTERFACE
8875 
8887 SQLRETURN SQL_API
8888 SQLGetDiagField(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8889  SQLSMALLINT id, SQLPOINTER info,
8890  SQLSMALLINT buflen, SQLSMALLINT *stringlen)
8891 {
8892  return drvgetdiagfield(htype, handle, recno, id, info, buflen, stringlen);
8893 }
8894 #endif
8895 
8896 #ifdef WINTERFACE
8897 
8909 SQLRETURN SQL_API
8910 SQLGetDiagFieldW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
8911  SQLSMALLINT id, SQLPOINTER info,
8912  SQLSMALLINT buflen, SQLSMALLINT *stringlen)
8913 {
8914  SQLSMALLINT len;
8915  SQLRETURN ret;
8916 
8917  ret = drvgetdiagfield(htype, handle, recno, id, info, buflen, &len);
8918  if (ret == SQL_SUCCESS) {
8919  if (info) {
8920  switch (id) {
8921  case SQL_DIAG_CLASS_ORIGIN:
8922  case SQL_DIAG_SUBCLASS_ORIGIN:
8923  case SQL_DIAG_CONNECTION_NAME:
8924  case SQL_DIAG_SERVER_NAME:
8925  case SQL_DIAG_SQLSTATE:
8926  case SQL_DIAG_MESSAGE_TEXT:
8927  case SQL_DIAG_DYNAMIC_FUNCTION:
8928  if (len > 0) {
8929  SQLWCHAR *m = NULL;
8930 
8931  m = uc_from_utf((unsigned char *) info, len);
8932  if (m) {
8933  if (buflen) {
8934  buflen /= sizeof (SQLWCHAR);
8935  uc_strncpy(info, m, buflen);
8936  m[len] = 0;
8937  len = min(buflen, uc_strlen(m));
8938  } else {
8939  len = uc_strlen(m);
8940  }
8941  uc_free(m);
8942  len *= sizeof (SQLWCHAR);
8943  } else {
8944  len = 0;
8945  }
8946  }
8947  if (len <= 0) {
8948  len = 0;
8949  if (buflen > 0) {
8950  ((SQLWCHAR *) info)[0] = 0;
8951  }
8952  }
8953  }
8954  } else {
8955  switch (id) {
8956  case SQL_DIAG_CLASS_ORIGIN:
8957  case SQL_DIAG_SUBCLASS_ORIGIN:
8958  case SQL_DIAG_CONNECTION_NAME:
8959  case SQL_DIAG_SERVER_NAME:
8960  case SQL_DIAG_SQLSTATE:
8961  case SQL_DIAG_MESSAGE_TEXT:
8962  case SQL_DIAG_DYNAMIC_FUNCTION:
8963  len *= sizeof (SQLWCHAR);
8964  break;
8965  }
8966  }
8967  if (stringlen) {
8968  *stringlen = len;
8969  }
8970  }
8971  return ret;
8972 }
8973 #endif
8974 
8985 static SQLRETURN
8986 drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
8987  SQLINTEGER bufmax, SQLINTEGER *buflen)
8988 {
8989  STMT *s = (STMT *) stmt;
8990  SQLULEN *uval = (SQLULEN *) val;
8991  SQLINTEGER dummy;
8992  char dummybuf[16];
8993 
8994  if (!buflen) {
8995  buflen = &dummy;
8996  }
8997  if (!uval) {
8998  uval = (SQLPOINTER) dummybuf;
8999  }
9000  switch (attr) {
9001  case SQL_QUERY_TIMEOUT:
9002  *uval = 0;
9003  *buflen = sizeof (SQLULEN);
9004  return SQL_SUCCESS;
9005  case SQL_ATTR_CURSOR_TYPE:
9006  *uval = s->curtype;
9007  *buflen = sizeof (SQLULEN);
9008  return SQL_SUCCESS;
9009  case SQL_ATTR_CURSOR_SCROLLABLE:
9010  *uval = (s->curtype != SQL_CURSOR_FORWARD_ONLY) ?
9011  SQL_SCROLLABLE : SQL_NONSCROLLABLE;
9012  *buflen = sizeof (SQLULEN);
9013  return SQL_SUCCESS;
9014 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
9015  case SQL_ATTR_CURSOR_SENSITIVITY:
9016  *uval = SQL_UNSPECIFIED;
9017  *buflen = sizeof (SQLULEN);
9018  return SQL_SUCCESS;
9019 #endif
9020  case SQL_ATTR_ROW_NUMBER:
9021  if (s->s3stmt) {
9022  *uval = (s->s3stmt_rownum < 0) ?
9023  SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
9024  } else {
9025  *uval = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
9026  }
9027  *buflen = sizeof (SQLULEN);
9028  return SQL_SUCCESS;
9029  case SQL_ATTR_ASYNC_ENABLE:
9030  *uval = SQL_ASYNC_ENABLE_OFF;
9031  *buflen = sizeof (SQLULEN);
9032  return SQL_SUCCESS;
9033  case SQL_CONCURRENCY:
9034  *uval = SQL_CONCUR_LOCK;
9035  *buflen = sizeof (SQLULEN);
9036  return SQL_SUCCESS;
9037  case SQL_ATTR_RETRIEVE_DATA:
9038  *uval = s->retr_data;
9039  *buflen = sizeof (SQLULEN);
9040  return SQL_SUCCESS;
9041  case SQL_ROWSET_SIZE:
9042  case SQL_ATTR_ROW_ARRAY_SIZE:
9043  *uval = s->rowset_size;
9044  *buflen = sizeof (SQLULEN);
9045  return SQL_SUCCESS;
9046  /* Needed for some driver managers, but dummies for now */
9047  case SQL_ATTR_IMP_ROW_DESC:
9048  case SQL_ATTR_APP_ROW_DESC:
9049  case SQL_ATTR_IMP_PARAM_DESC:
9050  case SQL_ATTR_APP_PARAM_DESC:
9051  *((SQLHDESC *) uval) = (SQLHDESC) DEAD_MAGIC;
9052  *buflen = sizeof (SQLHDESC);
9053  return SQL_SUCCESS;
9054  case SQL_ATTR_ROW_STATUS_PTR:
9055  *((SQLUSMALLINT **) uval) = s->row_status;
9056  *buflen = sizeof (SQLUSMALLINT *);
9057  return SQL_SUCCESS;
9058  case SQL_ATTR_ROWS_FETCHED_PTR:
9059  *((SQLULEN **) uval) = s->row_count;
9060  *buflen = sizeof (SQLULEN *);
9061  return SQL_SUCCESS;
9062  case SQL_ATTR_USE_BOOKMARKS: {
9063  STMT *s = (STMT *) stmt;
9064 
9065  *(SQLUINTEGER *) uval = s->bkmrk;
9066  *buflen = sizeof (SQLUINTEGER);
9067  return SQL_SUCCESS;
9068  }
9069  case SQL_ATTR_FETCH_BOOKMARK_PTR:
9070  *(SQLPOINTER *) uval = s->bkmrkptr;
9071  *buflen = sizeof (SQLPOINTER);
9072  return SQL_SUCCESS;
9073  case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
9074  *((SQLULEN **) uval) = s->parm_bind_offs;
9075  *buflen = sizeof (SQLULEN *);
9076  return SQL_SUCCESS;
9077  case SQL_ATTR_PARAM_BIND_TYPE:
9078  *((SQLULEN *) uval) = s->parm_bind_type;
9079  *buflen = sizeof (SQLULEN);
9080  return SQL_SUCCESS;
9081  case SQL_ATTR_PARAM_OPERATION_PTR:
9082  *((SQLUSMALLINT **) uval) = s->parm_oper;
9083  *buflen = sizeof (SQLUSMALLINT *);
9084  return SQL_SUCCESS;
9085  case SQL_ATTR_PARAM_STATUS_PTR:
9086  *((SQLUSMALLINT **) uval) = s->parm_status;
9087  *buflen = sizeof (SQLUSMALLINT *);
9088  return SQL_SUCCESS;
9089  case SQL_ATTR_PARAMS_PROCESSED_PTR:
9090  *((SQLULEN **) uval) = s->parm_proc;
9091  *buflen = sizeof (SQLULEN *);
9092  return SQL_SUCCESS;
9093  case SQL_ATTR_PARAMSET_SIZE:
9094  *((SQLULEN *) uval) = s->paramset_size;
9095  *buflen = sizeof (SQLULEN);
9096  return SQL_SUCCESS;
9097  case SQL_ATTR_ROW_BIND_TYPE:
9098  *(SQLULEN *) uval = s->bind_type;
9099  *buflen = sizeof (SQLULEN);
9100  return SQL_SUCCESS;
9101  case SQL_ATTR_ROW_BIND_OFFSET_PTR:
9102  *((SQLULEN **) uval) = s->bind_offs;
9103  *buflen = sizeof (SQLULEN *);
9104  return SQL_SUCCESS;
9105  case SQL_ATTR_MAX_ROWS:
9106  *((SQLULEN *) uval) = s->max_rows;
9107  *buflen = sizeof (SQLULEN);
9108  return SQL_SUCCESS;
9109  case SQL_ATTR_MAX_LENGTH:
9110  *((SQLULEN *) uval) = 1000000000;
9111  *buflen = sizeof (SQLULEN);
9112  return SQL_SUCCESS;
9113 #ifdef SQL_ATTR_METADATA_ID
9114  case SQL_ATTR_METADATA_ID:
9115  *((SQLULEN *) uval) = SQL_FALSE;
9116  *buflen = sizeof (SQLULEN);
9117  return SQL_SUCCESS;
9118 #endif
9119  }
9120  return drvunimplstmt(stmt);
9121 }
9122 
9123 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
9124 
9134 SQLRETURN SQL_API
9135 SQLGetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9136  SQLINTEGER bufmax, SQLINTEGER *buflen)
9137 {
9138  SQLRETURN ret;
9139 
9140  HSTMT_LOCK(stmt);
9141  ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
9142  HSTMT_UNLOCK(stmt);
9143  return ret;
9144 }
9145 #endif
9146 
9147 #ifdef WINTERFACE
9148 
9158 SQLRETURN SQL_API
9159 SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9160  SQLINTEGER bufmax, SQLINTEGER *buflen)
9161 {
9162  SQLRETURN ret;
9163 
9164  HSTMT_LOCK(stmt);
9165  ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
9166  HSTMT_UNLOCK(stmt);
9167  return ret;
9168 }
9169 #endif
9170 
9180 static SQLRETURN
9181 drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9182  SQLINTEGER buflen)
9183 {
9184  STMT *s = (STMT *) stmt;
9185 #if defined(SQL_BIGINT) && defined(__WORDSIZE) && (__WORDSIZE == 64)
9186  SQLBIGINT uval;
9187 
9188  uval = (SQLBIGINT) val;
9189 #else
9190  SQLULEN uval;
9191 
9192  uval = (SQLULEN) val;
9193 #endif
9194  switch (attr) {
9195  case SQL_ATTR_CURSOR_TYPE:
9196  if (val == (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY) {
9197  s->curtype = SQL_CURSOR_FORWARD_ONLY;
9198  } else {
9199  s->curtype = SQL_CURSOR_STATIC;
9200  }
9201  if (val != (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY &&
9202  val != (SQLPOINTER) SQL_CURSOR_STATIC) {
9203  goto e01s02;
9204  }
9205  return SQL_SUCCESS;
9206  case SQL_ATTR_CURSOR_SCROLLABLE:
9207  if (val == (SQLPOINTER) SQL_NONSCROLLABLE) {
9208  s->curtype = SQL_CURSOR_FORWARD_ONLY;
9209  } else {
9210  s->curtype = SQL_CURSOR_STATIC;
9211  }
9212  return SQL_SUCCESS;
9213  case SQL_ATTR_ASYNC_ENABLE:
9214  if (val != (SQLPOINTER) SQL_ASYNC_ENABLE_OFF) {
9215  e01s02:
9216  setstat(s, -1, "option value changed", "01S02");
9217  return SQL_SUCCESS_WITH_INFO;
9218  }
9219  return SQL_SUCCESS;
9220  case SQL_CONCURRENCY:
9221  if (val != (SQLPOINTER) SQL_CONCUR_LOCK) {
9222  goto e01s02;
9223  }
9224  return SQL_SUCCESS;
9225 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
9226  case SQL_ATTR_CURSOR_SENSITIVITY:
9227  if (val != (SQLPOINTER) SQL_UNSPECIFIED) {
9228  goto e01s02;
9229  }
9230  return SQL_SUCCESS;
9231 #endif
9232  case SQL_ATTR_QUERY_TIMEOUT:
9233  return SQL_SUCCESS;
9234  case SQL_ATTR_RETRIEVE_DATA:
9235  if (val != (SQLPOINTER) SQL_RD_ON &&
9236  val != (SQLPOINTER) SQL_RD_OFF) {
9237  goto e01s02;
9238  }
9239  s->retr_data = uval;
9240  return SQL_SUCCESS;
9241  case SQL_ROWSET_SIZE:
9242  case SQL_ATTR_ROW_ARRAY_SIZE:
9243  if (uval < 1) {
9244  setstat(s, -1, "invalid rowset size", "HY000");
9245  return SQL_ERROR;
9246  } else {
9247  SQLUSMALLINT *rst = &s->row_status1;
9248 
9249  if (uval > 1) {
9250  rst = xmalloc(sizeof (SQLUSMALLINT) * uval);
9251  if (!rst) {
9252  return nomem(s);
9253  }
9254  }
9255  if (s->row_status0 != &s->row_status1) {
9256  freep(&s->row_status0);
9257  }
9258  s->row_status0 = rst;
9259  s->rowset_size = uval;
9260  }
9261  return SQL_SUCCESS;
9262  case SQL_ATTR_ROW_STATUS_PTR:
9263  s->row_status = (SQLUSMALLINT *) val;
9264  return SQL_SUCCESS;
9265  case SQL_ATTR_ROWS_FETCHED_PTR:
9266  s->row_count = (SQLULEN *) val;
9267  return SQL_SUCCESS;
9268  case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
9269  s->parm_bind_offs = (SQLULEN *) val;
9270  return SQL_SUCCESS;
9271  case SQL_ATTR_PARAM_BIND_TYPE:
9272  s->parm_bind_type = uval;
9273  return SQL_SUCCESS;
9274  case SQL_ATTR_PARAM_OPERATION_PTR:
9275  s->parm_oper = (SQLUSMALLINT *) val;
9276  return SQL_SUCCESS;
9277  case SQL_ATTR_PARAM_STATUS_PTR:
9278  s->parm_status = (SQLUSMALLINT *) val;
9279  return SQL_SUCCESS;
9280  case SQL_ATTR_PARAMS_PROCESSED_PTR:
9281  s->parm_proc = (SQLULEN *) val;
9282  return SQL_SUCCESS;
9283  case SQL_ATTR_PARAMSET_SIZE:
9284  if (uval < 1) {
9285  goto e01s02;
9286  }
9287  s->paramset_size = uval;
9288  s->paramset_count = 0;
9289  return SQL_SUCCESS;
9290  case SQL_ATTR_ROW_BIND_TYPE:
9291  s->bind_type = uval;
9292  return SQL_SUCCESS;
9293  case SQL_ATTR_ROW_BIND_OFFSET_PTR:
9294  s->bind_offs = (SQLULEN *) val;
9295  return SQL_SUCCESS;
9296  case SQL_ATTR_USE_BOOKMARKS:
9297  if (val != (SQLPOINTER) SQL_UB_OFF &&
9298  val != (SQLPOINTER) SQL_UB_ON &&
9299  val != (SQLPOINTER) SQL_UB_VARIABLE) {
9300  goto e01s02;
9301  }
9302  if (*s->ov3 && val == (SQLPOINTER) SQL_UB_VARIABLE) {
9303  s->bkmrk = SQL_UB_VARIABLE;
9304  return SQL_SUCCESS;
9305  }
9306  if (val == (SQLPOINTER) SQL_UB_VARIABLE) {
9307  s->bkmrk = SQL_UB_ON;
9308  goto e01s02;
9309  }
9310  s->bkmrk = (val == (SQLPOINTER) SQL_UB_ON) ? SQL_UB_ON : SQL_UB_OFF;
9311  return SQL_SUCCESS;
9312  case SQL_ATTR_FETCH_BOOKMARK_PTR:
9313  s->bkmrkptr = (SQLINTEGER *) val;
9314  return SQL_SUCCESS;
9315  case SQL_ATTR_MAX_ROWS:
9316  s->max_rows = uval;
9317  return SQL_SUCCESS;
9318  case SQL_ATTR_MAX_LENGTH:
9319  if (val != (SQLPOINTER) 1000000000) {
9320  goto e01s02;
9321  }
9322  return SQL_SUCCESS;
9323 #ifdef SQL_ATTR_METADATA_ID
9324  case SQL_ATTR_METADATA_ID:
9325  if (val != (SQLPOINTER) SQL_FALSE) {
9326  goto e01s02;
9327  }
9328  return SQL_SUCCESS;
9329 #endif
9330  }
9331  return drvunimplstmt(stmt);
9332 }
9333 
9334 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
9335 
9344 SQLRETURN SQL_API
9345 SQLSetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9346  SQLINTEGER buflen)
9347 {
9348  SQLRETURN ret;
9349 
9350  HSTMT_LOCK(stmt);
9351  ret = drvsetstmtattr(stmt, attr, val, buflen);
9352  HSTMT_UNLOCK(stmt);
9353  return ret;
9354 }
9355 #endif
9356 
9357 #ifdef WINTERFACE
9358 
9367 SQLRETURN SQL_API
9368 SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
9369  SQLINTEGER buflen)
9370 {
9371  SQLRETURN ret;
9372 
9373  HSTMT_LOCK(stmt);
9374  ret = drvsetstmtattr(stmt, attr, val, buflen);
9375  HSTMT_UNLOCK(stmt);
9376  return ret;
9377 }
9378 #endif
9379 
9388 static SQLRETURN
9389 drvgetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9390 {
9391  STMT *s = (STMT *) stmt;
9392  SQLUINTEGER *ret = (SQLUINTEGER *) param;
9393 
9394  switch (opt) {
9395  case SQL_QUERY_TIMEOUT:
9396  *ret = 0;
9397  return SQL_SUCCESS;
9398  case SQL_CURSOR_TYPE:
9399  *ret = s->curtype;
9400  return SQL_SUCCESS;
9401  case SQL_ROW_NUMBER:
9402  if (s->s3stmt) {
9403  *ret = (s->s3stmt_rownum < 0) ?
9404  SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
9405  } else {
9406  *ret = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
9407  }
9408  return SQL_SUCCESS;
9409  case SQL_ASYNC_ENABLE:
9410  *ret = SQL_ASYNC_ENABLE_OFF;
9411  return SQL_SUCCESS;
9412  case SQL_CONCURRENCY:
9413  *ret = SQL_CONCUR_LOCK;
9414  return SQL_SUCCESS;
9415  case SQL_ATTR_RETRIEVE_DATA:
9416  *ret = s->retr_data;
9417  return SQL_SUCCESS;
9418  case SQL_ROWSET_SIZE:
9419  case SQL_ATTR_ROW_ARRAY_SIZE:
9420  *ret = s->rowset_size;
9421  return SQL_SUCCESS;
9422  case SQL_ATTR_MAX_ROWS:
9423  *ret = s->max_rows;
9424  return SQL_SUCCESS;
9425  case SQL_ATTR_MAX_LENGTH:
9426  *ret = 1000000000;
9427  return SQL_SUCCESS;
9428  }
9429  return drvunimplstmt(stmt);
9430 }
9431 
9440 SQLRETURN SQL_API
9441 SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9442 {
9443  SQLRETURN ret;
9444 
9445  HSTMT_LOCK(stmt);
9446  ret = drvgetstmtoption(stmt, opt, param);
9447  HSTMT_UNLOCK(stmt);
9448  return ret;
9449 }
9450 
9451 #ifdef WINTERFACE
9452 
9460 SQLRETURN SQL_API
9461 SQLGetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
9462 {
9463  SQLRETURN ret;
9464 
9465  HSTMT_LOCK(stmt);
9466  ret = drvgetstmtoption(stmt, opt, param);
9467  HSTMT_UNLOCK(stmt);
9468  return ret;
9469 }
9470 #endif
9471 
9480 static SQLRETURN
9481 drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
9482 {
9483  STMT *s = (STMT *) stmt;
9484 
9485  switch (opt) {
9486  case SQL_CURSOR_TYPE:
9487  if (param == SQL_CURSOR_FORWARD_ONLY) {
9488  s->curtype = param;
9489  } else {
9490  s->curtype = SQL_CURSOR_STATIC;
9491  }
9492  if (param != SQL_CURSOR_FORWARD_ONLY &&
9493  param != SQL_CURSOR_STATIC) {
9494  goto e01s02;
9495  }
9496  return SQL_SUCCESS;
9497  case SQL_ASYNC_ENABLE:
9498  if (param != SQL_ASYNC_ENABLE_OFF) {
9499  goto e01s02;
9500  }
9501  return SQL_SUCCESS;
9502  case SQL_CONCURRENCY:
9503  if (param != SQL_CONCUR_LOCK) {
9504  goto e01s02;
9505  }
9506  return SQL_SUCCESS;
9507  case SQL_QUERY_TIMEOUT:
9508  return SQL_SUCCESS;
9509  case SQL_RETRIEVE_DATA:
9510  if (param != SQL_RD_ON && param != SQL_RD_OFF) {
9511  e01s02:
9512  setstat(s, -1, "option value changed", "01S02");
9513  return SQL_SUCCESS_WITH_INFO;
9514  }
9515  s->retr_data = (int) param;
9516  return SQL_SUCCESS;
9517  case SQL_ROWSET_SIZE:
9518  case SQL_ATTR_ROW_ARRAY_SIZE:
9519  if (param < 1) {
9520  setstat(s, -1, "invalid rowset size", "HY000");
9521  return SQL_ERROR;
9522  } else {
9523  SQLUSMALLINT *rst = &s->row_status1;
9524 
9525  if (param > 1) {
9526  rst = xmalloc(sizeof (SQLUSMALLINT) * param);
9527  if (!rst) {
9528  return nomem(s);
9529  }
9530  }
9531  if (s->row_status0 != &s->row_status1) {
9532  freep(&s->row_status0);
9533  }
9534  s->row_status0 = rst;
9535  s->rowset_size = param;
9536  }
9537  return SQL_SUCCESS;
9538  case SQL_ATTR_MAX_ROWS:
9539  s->max_rows = param;
9540  return SQL_SUCCESS;
9541  case SQL_ATTR_MAX_LENGTH:
9542  if (param != 1000000000) {
9543  goto e01s02;
9544  }
9545  return SQL_SUCCESS;
9546  }
9547  return drvunimplstmt(stmt);
9548 }
9549 
9558 SQLRETURN SQL_API
9559 SQLSetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt,
9561 {
9562  SQLRETURN ret;
9563 
9564  HSTMT_LOCK(stmt);
9565  ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
9566  HSTMT_UNLOCK(stmt);
9567  return ret;
9568 }
9569 
9570 #ifdef WINTERFACE
9571 
9579 SQLRETURN SQL_API
9580 SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt,
9582 {
9583  SQLRETURN ret;
9584 
9585  HSTMT_LOCK(stmt);
9586  ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
9587  HSTMT_UNLOCK(stmt);
9588  return ret;
9589 }
9590 #endif
9591 
9598 static SQLRETURN
9600 {
9601  int i;
9602 
9603  if (!s->bindcols || s->nbindcols < s->ncols) {
9604 unbound:
9605  setstat(s, -1, "unbound columns", (*s->ov3) ? "HY000" : "S1000");
9606  return SQL_ERROR;
9607  }
9608  for (i = 0; i < s->ncols; i++) {
9609  BINDCOL *b = &s->bindcols[i];
9610 
9611  if (b->type == SQL_UNKNOWN_TYPE || !b->valp) {
9612  goto unbound;
9613  }
9614  }
9615  return SQL_SUCCESS;
9616 }
9617 
9629 static SQLRETURN
9630 setposbind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
9631 {
9632  DBC *d = (DBC *) s->dbc;
9633  SQLPOINTER dp = 0;
9634  SQLLEN *lp = 0;
9635  BINDCOL *b = &s->bindcols[i];
9636  COL *c = &s->cols[i];
9637  char strbuf[128], *cp;
9638 
9639  if (b->valp) {
9640  if (s->bind_type != SQL_BIND_BY_COLUMN) {
9641  dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
9642  } else {
9643  dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
9644  }
9645  if (s->bind_offs) {
9646  dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
9647  }
9648  }
9649  if (b->lenp) {
9650  if (s->bind_type != SQL_BIND_BY_COLUMN) {
9651  lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
9652  } else {
9653  lp = b->lenp + rsi;
9654  }
9655  if (s->bind_offs) {
9656  lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
9657  }
9658  }
9659  if (!dp || !lp) {
9660  setstat(s, -1, "unbound column in positional update",
9661  (*s->ov3) ? "HY000" : "S1000");
9662  return SQL_ERROR;
9663  }
9664  if (*lp == SQL_NULL_DATA) {
9665  sqlite3_bind_null(stmt, si);
9666  if (d->trace) {
9667  fprintf(d->trace, "-- parameter %d: NULL\n", si);
9668  fflush(d->trace);
9669  }
9670  return SQL_SUCCESS;
9671  }
9672  switch (b->type) {
9673  case SQL_C_UTINYINT:
9674  case SQL_C_TINYINT:
9675  case SQL_C_STINYINT:
9676  sqlite3_bind_int(stmt, si, *(SQLCHAR *) dp);
9677  if (d->trace) {
9678  fprintf(d->trace, "-- parameter %d: %d\n", si, *(SQLCHAR *) dp);
9679  fflush(d->trace);
9680  }
9681  break;
9682 #ifdef SQL_BIT
9683  case SQL_C_BIT:
9684  sqlite3_bind_int(stmt, si, (*(SQLCHAR *) dp) ? 1 : 0);
9685  if (d->trace) {
9686  fprintf(d->trace, "-- parameter %d: %d\n", si,
9687  (*(SQLCHAR *) dp) ? 1 : 0);
9688  fflush(d->trace);
9689  }
9690  break;
9691 #endif
9692  case SQL_C_USHORT:
9693  sqlite3_bind_int(stmt, si, *(SQLUSMALLINT *) dp);
9694  if (d->trace) {
9695  fprintf(d->trace, "-- parameter %d: %d\n", si,
9696  *(SQLUSMALLINT *) dp);
9697  fflush(d->trace);
9698  }
9699  break;
9700  case SQL_C_SHORT:
9701  case SQL_C_SSHORT:
9702  sqlite3_bind_int(stmt, si, *(SQLSMALLINT *) dp);
9703  if (d->trace) {
9704  fprintf(d->trace, "-- parameter %d: %d\n", si,
9705  *(SQLSMALLINT *) dp);
9706  fflush(d->trace);
9707  }
9708  break;
9709  case SQL_C_ULONG:
9710  sqlite3_bind_int(stmt, si, *(SQLUINTEGER *) dp);
9711  if (d->trace) {
9712  fprintf(d->trace, "-- parameter %d: %ld\n", si,
9713  (long) *(SQLUINTEGER *) dp);
9714  fflush(d->trace);
9715  }
9716  break;
9717  case SQL_C_LONG:
9718  case SQL_C_SLONG:
9719  sqlite3_bind_int(stmt, si, *(SQLINTEGER *) dp);
9720  if (d->trace) {
9721  fprintf(d->trace, "-- parameter %d: %ld\n", si,
9722  (long) *(SQLINTEGER *) dp);
9723  fflush(d->trace);
9724  }
9725  break;
9726 #ifdef SQL_BIGINT
9727  case SQL_C_UBIGINT:
9728  case SQL_C_SBIGINT:
9729  sqlite3_bind_int64(stmt, si, *(SQLBIGINT *) dp);
9730  if (d->trace) {
9731  fprintf(d->trace,
9732 #ifdef _WIN32
9733  "-- parameter %d: %I64d\n",
9734 #else
9735  "-- parameter %d: %lld\n",
9736 #endif
9737  si, (sqlite_int64) *(SQLBIGINT *) dp);
9738  fflush(d->trace);
9739  }
9740  break;
9741 #endif
9742  case SQL_C_FLOAT:
9743  sqlite3_bind_double(stmt, si, *(float *) dp);
9744  if (d->trace) {
9745  fprintf(d->trace, "-- parameter %d: %g\n", si,
9746  *(float *) dp);
9747  fflush(d->trace);
9748  }
9749  break;
9750  case SQL_C_DOUBLE:
9751  sqlite3_bind_double(stmt, si, *(double *) dp);
9752  if (d->trace) {
9753  fprintf(d->trace, "-- parameter %d: %g\n", si,
9754  *(double *) dp);
9755  fflush(d->trace);
9756  }
9757  break;
9758  case SQL_C_BINARY:
9759  sqlite3_bind_blob(stmt, si, (char *) dp, *lp, SQLITE_STATIC);
9760  if (d->trace) {
9761  fprintf(d->trace, "-- parameter %d: [BLOB]\n", si);
9762  fflush(d->trace);
9763  }
9764  break;
9765 #ifdef WCHARSUPPORT
9766  case SQL_C_WCHAR:
9767  cp = uc_to_utf((SQLWCHAR *) dp, *lp);
9768  if (!cp) {
9769  return nomem(s);
9770  }
9771  sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
9772  if (d->trace) {
9773  fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
9774  fflush(d->trace);
9775  }
9776  uc_free(cp);
9777  break;
9778 #endif
9779  case SQL_C_CHAR:
9780 #if defined(_WIN32) || defined(_WIN64)
9781  if (*s->oemcp) {
9782  cp = wmb_to_utf((char *) dp, *lp);
9783  if (!cp) {
9784  return nomem(s);
9785  }
9786  sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
9787  if (d->trace) {
9788  fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
9789  fflush(d->trace);
9790  }
9791  uc_free(cp);
9792  } else
9793 #endif
9794  {
9795  if (*lp == SQL_NTS) {
9796  sqlite3_bind_text(stmt, si, (char *) dp, -1,
9797  SQLITE_STATIC);
9798  if (d->trace) {
9799  fprintf(d->trace, "-- parameter %d: '%s'\n", si,
9800  (char *) dp);
9801  fflush(d->trace);
9802  }
9803  } else {
9804  sqlite3_bind_text(stmt, si, (char *) dp, *lp,
9805  SQLITE_STATIC);
9806  if (d->trace) {
9807  fprintf(d->trace, "-- parameter %d: '%*s'\n", si,
9808  (int) *lp, (char *) dp);
9809  fflush(d->trace);
9810  }
9811  }
9812  }
9813  break;
9814 #ifdef SQL_C_TYPE_DATE
9815  case SQL_C_TYPE_DATE:
9816 #endif
9817  case SQL_C_DATE:
9818  if (*s->jdconv) {
9819  int a, b, x1, x2, y, m, dd;
9820  double v;
9821 
9822  y = ((DATE_STRUCT *) dp)->year;
9823  m = ((DATE_STRUCT *) dp)->month;
9824  dd = ((DATE_STRUCT *) dp)->day;
9825  if (m <= 2) {
9826  y--;
9827  m += 12;
9828  }
9829  a = y / 100;
9830  b = 2 - a + (a / 4);
9831  x1 = 36525 * (y + 4716) / 100;
9832  x2 = 306001 * (m + 1) / 10000;
9833  v = x1 + x2 + dd + b - 1524.5;
9834  sqlite3_bind_double(stmt, si, v);
9835  if (d->trace) {
9836  fprintf(d->trace, "-- parameter %d: %g\n", si, v);
9837  fflush(d->trace);
9838  }
9839  } else {
9840  sprintf(strbuf, "%04d-%02d-%02d",
9841  ((DATE_STRUCT *) dp)->year,
9842  ((DATE_STRUCT *) dp)->month,
9843  ((DATE_STRUCT *) dp)->day);
9844  sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
9845  if (d->trace) {
9846  fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
9847  fflush(d->trace);
9848  }
9849  }
9850  break;
9851 #ifdef SQL_C_TYPE_TIME
9852  case SQL_C_TYPE_TIME:
9853 #endif
9854  case SQL_C_TIME:
9855  if (*s->jdconv) {
9856  double v;
9857 
9858  v = 2451544.5 +
9859  (((TIME_STRUCT *) dp)->hour * 3600000.0 +
9860  ((TIME_STRUCT *) dp)->minute * 60000.0 +
9861  ((TIME_STRUCT *) dp)->second * 1000.0) / 86400000.0;
9862  sqlite3_bind_double(stmt, si, v);
9863  if (d->trace) {
9864  fprintf(d->trace, "-- parameter %d: %g\n", si, v);
9865  fflush(d->trace);
9866  }
9867  } else {
9868  sprintf(strbuf, "%02d:%02d:%02d",
9869  ((TIME_STRUCT *) dp)->hour,
9870  ((TIME_STRUCT *) dp)->minute,
9871  ((TIME_STRUCT *) dp)->second);
9872  sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
9873  if (d->trace) {
9874  fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
9875  fflush(d->trace);
9876  }
9877  }
9878  break;
9879 #ifdef SQL_C_TYPE_TIMESTAMP
9880  case SQL_C_TYPE_TIMESTAMP:
9881 #endif
9882  case SQL_C_TIMESTAMP:
9883  if (*s->jdconv) {
9884  int a, b, x1, x2, y, m, dd;
9885  double v;
9886 
9887  y = ((TIMESTAMP_STRUCT *) dp)->year;
9888  m = ((TIMESTAMP_STRUCT *) dp)->month;
9889  dd = ((TIMESTAMP_STRUCT *) dp)->day;
9890  if (m <= 2) {
9891  y--;
9892  m += 12;
9893  }
9894  a = y / 100;
9895  b = 2 - a + (a / 4);
9896  x1 = 36525 * (y + 4716) / 100;
9897  x2 = 306001 * (m + 1) / 10000;
9898  v = x1 + x2 + dd + b - 1524.5 +
9899  (((TIMESTAMP_STRUCT *) dp)->hour * 3600000.0 +
9900  ((TIMESTAMP_STRUCT *) dp)->minute * 60000.0 +
9901  ((TIMESTAMP_STRUCT *) dp)->second * 1000.0 +
9902  ((TIMESTAMP_STRUCT *) dp)->fraction / 1.0E6)
9903  / 86400000.0;
9904  sqlite3_bind_double(stmt, si, v);
9905  if (d->trace) {
9906  fprintf(d->trace, "-- parameter %d: %g\n", si, v);
9907  fflush(d->trace);
9908  }
9909  } else {
9910  int frac;
9911 
9912  frac = (int) ((TIMESTAMP_STRUCT *) dp)->fraction;
9913  frac /= 1000000;
9914  frac = frac % 1000;
9915  if (frac < 0) {
9916  frac = 0;
9917  }
9918  if (c->prec && c->prec <= 16) {
9919  sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
9920  ((TIMESTAMP_STRUCT *) dp)->year,
9921  ((TIMESTAMP_STRUCT *) dp)->month,
9922  ((TIMESTAMP_STRUCT *) dp)->day,
9923  ((TIMESTAMP_STRUCT *) dp)->hour,
9924  ((TIMESTAMP_STRUCT *) dp)->minute);
9925  } else if (c->prec && c->prec <= 19) {
9926  sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
9927  ((TIMESTAMP_STRUCT *) dp)->year,
9928  ((TIMESTAMP_STRUCT *) dp)->month,
9929  ((TIMESTAMP_STRUCT *) dp)->day,
9930  ((TIMESTAMP_STRUCT *) dp)->hour,
9931  ((TIMESTAMP_STRUCT *) dp)->minute,
9932  ((TIMESTAMP_STRUCT *) dp)->second);
9933  } else {
9934  sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
9935  ((TIMESTAMP_STRUCT *) dp)->year,
9936  ((TIMESTAMP_STRUCT *) dp)->month,
9937  ((TIMESTAMP_STRUCT *) dp)->day,
9938  ((TIMESTAMP_STRUCT *) dp)->hour,
9939  ((TIMESTAMP_STRUCT *) dp)->minute,
9940  ((TIMESTAMP_STRUCT *) dp)->second,
9941  frac);
9942  }
9943  sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
9944  if (d->trace) {
9945  fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
9946  fflush(d->trace);
9947  }
9948  }
9949  break;
9950  default:
9951  setstat(s, -1, "unsupported column type in positional update",
9952  (*s->ov3) ? "HY000" : "S1000");
9953  return SQL_ERROR;
9954  }
9955  return SQL_SUCCESS;
9956 }
9957 
9969 static SQLRETURN
9970 setposibind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
9971 {
9972  DBC *d = (DBC *) s->dbc;
9973  char **data;
9974  int pos;
9975 
9976  pos = s->rowprs;
9977  if (pos < 0) {
9978  setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
9979  return SQL_ERROR;
9980  }
9981  pos += rsi;
9982  data = s->rows + s->ncols + (pos * s->ncols) + i;
9983  if (*data == NULL) {
9984  sqlite3_bind_null(stmt, si);
9985  if (d->trace) {
9986  fprintf(d->trace, "-- parameter %d: NULL\n", si);
9987  fflush(d->trace);
9988  }
9989  } else {
9990  sqlite3_bind_text(stmt, si, *data, -1, SQLITE_STATIC);
9991  if (d->trace) {
9992  fprintf(d->trace, "-- parameter %d: '%s'\n", si, *data);
9993  fflush(d->trace);
9994  }
9995  }
9996  return SQL_SUCCESS;
9997 }
9998 
10006 static SQLRETURN
10007 setposrefr(STMT *s, int rsi)
10008 {
10009  int i, withinfo = 0;
10010  SQLRETURN ret = SQL_SUCCESS;
10011 
10012  for (i = 0; s->bindcols && i < s->ncols; i++) {
10013  BINDCOL *b = &s->bindcols[i];
10014  SQLPOINTER dp = 0;
10015  SQLLEN *lp = 0;
10016 
10017  b->offs = 0;
10018  if (b->valp) {
10019  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10020  dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
10021  } else {
10022  dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
10023  }
10024  if (s->bind_offs) {
10025  dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
10026  }
10027  }
10028  if (b->lenp) {
10029  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10030  lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
10031  } else {
10032  lp = b->lenp + rsi;
10033  }
10034  if (s->bind_offs) {
10035  lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
10036  }
10037  }
10038  if (dp || lp) {
10039  int rowp = s->rowp;
10040 
10041  s->rowp = s->rowprs + rsi;
10042  ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp,
10043  b->max, lp, 0);
10044  s->rowp = rowp;
10045  if (!SQL_SUCCEEDED(ret)) {
10046  s->row_status0[rsi] = SQL_ROW_ERROR;
10047  break;
10048  }
10049  if (ret != SQL_SUCCESS) {
10050  withinfo = 1;
10051 #ifdef SQL_ROW_SUCCESS_WITH_INFO
10052  s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
10053 #endif
10054  }
10055  }
10056  }
10057  if (SQL_SUCCEEDED(ret)) {
10058  ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
10059  }
10060  return ret;
10061 }
10062 
10072 static SQLRETURN
10073 drvsetpos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10074 {
10075  STMT *s = (STMT *) stmt;
10076  DBC *d = (DBC *) s->dbc;
10077  int rowp, i, k, rc, nretry = 0;
10078  dstr *sql = 0;
10079  const char *endp;
10080  sqlite3_stmt *s3stmt = NULL;
10081  SQLRETURN ret;
10082 
10083  if (lock != SQL_LOCK_NO_CHANGE) {
10084  setstat(s, -1, "unsupported locking mode",
10085  (*s->ov3) ? "HY000" : "S1000");
10086  return SQL_ERROR;
10087  }
10088  if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10089  setstat(s, -1, "incompatible statement",
10090  (*s->ov3) ? "HY000" : "S1000");
10091  return SQL_ERROR;
10092  }
10093  if (op == SQL_ADD) {
10094  if (s->one_tbl <= 0) {
10095  setstat(s, -1, "incompatible rowset",
10096  (*s->ov3) ? "HY000" : "S1000");
10097  return SQL_ERROR;
10098  }
10099  if (row == 0 || row > s->rowset_size + 1) {
10100  goto rowoor;
10101  }
10102  ret = chkunbound(s);
10103  if (ret != SQL_SUCCESS) {
10104  return ret;
10105  }
10106  sql = dsappend(sql, "INSERT INTO ");
10107  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10108  sql = dsappendq(sql, s->dyncols[0].db);
10109  sql = dsappend(sql, ".");
10110  }
10111  sql = dsappendq(sql, s->dyncols[0].table);
10112  for (i = 0; i < s->ncols; i++) {
10113  sql = dsappend(sql, (i > 0) ? "," : "(");
10114  sql = dsappendq(sql, s->dyncols[i].column);
10115  }
10116  sql = dsappend(sql, ") VALUES ");
10117  for (i = 0; i < s->ncols; i++) {
10118  sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10119  }
10120  sql = dsappend(sql, ")");
10121  if (dserr(sql)) {
10122  dsfree(sql);
10123  return nomem(s);
10124  }
10125 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10126  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10127 #else
10128  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10129 #endif
10130  do {
10131  s3stmt = NULL;
10132 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10133  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10134  &s3stmt, &endp);
10135 #else
10136  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10137  &s3stmt, &endp);
10138 #endif
10139  if (rc != SQLITE_OK) {
10140  if (s3stmt) {
10141  sqlite3_finalize(s3stmt);
10142  s3stmt = NULL;
10143  }
10144  }
10145  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10146  dbtracerc(d, rc, NULL);
10147  dsfree(sql);
10148  if (rc != SQLITE_OK) {
10149 istmterr:
10150  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10151  sqlite3_errmsg(d->sqlite), rc);
10152  if (s3stmt) {
10153  dbtraceapi(d, "sqlite3_finalize", NULL);
10154  sqlite3_finalize(s3stmt);
10155  }
10156  return SQL_ERROR;
10157  }
10158  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10159  ret = setposbind(s, s3stmt, i, k, row - 1);
10160  if (ret != SQL_SUCCESS) {
10161  dbtraceapi(d, "sqlite3_finalize", NULL);
10162  sqlite3_finalize(s3stmt);
10163  return ret;
10164  }
10165  k++;
10166  }
10167  rc = sqlite3_step(s3stmt);
10168  if (rc != SQLITE_DONE) {
10169  goto istmterr;
10170  }
10171  sqlite3_finalize(s3stmt);
10172  if (sqlite3_changes(d->sqlite) > 0 && row <= s->rowset_size) {
10173  if (s->row_status0) {
10174  s->row_status0[row - 1] = SQL_ROW_ADDED;
10175  }
10176  if (s->row_status) {
10177  s->row_status[row - 1] = SQL_ROW_ADDED;
10178  }
10179  }
10180  return SQL_SUCCESS;
10181  } else if (op == SQL_UPDATE || op == SQL_DELETE) {
10182  if (s->one_tbl <= 0 || s->has_pk <= 0) {
10183  setstat(s, -1, "incompatible rowset",
10184  (*s->ov3) ? "HY000" : "S1000");
10185  return SQL_ERROR;
10186  }
10187  if (row == 0) {
10188  ret = SQL_SUCCESS;
10189  for (i = 1; i <= s->rowset_size; i++) {
10190  ret = drvsetpos(stmt, i, op, lock);
10191  if (!SQL_SUCCEEDED(ret)) {
10192  break;
10193  }
10194  }
10195  return ret;
10196  }
10197  if (row > s->rowset_size) {
10198  goto rowoor;
10199  }
10200  }
10201  if (op != SQL_POSITION && op != SQL_REFRESH &&
10202  op != SQL_DELETE && op != SQL_UPDATE) {
10203  return drvunimplstmt(stmt);
10204  }
10205  if (op == SQL_POSITION) {
10206  rowp = s->rowp + row - 1;
10207  if (!s->rows || row == 0 || rowp < -1 || rowp >= s->nrows) {
10208 rowoor:
10209  setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
10210  return SQL_ERROR;
10211  }
10212  s->rowp = rowp;
10213  } else if (op == SQL_REFRESH) {
10214  if (row > s->rowset_size) {
10215  goto rowoor;
10216  }
10217  if (row == 0) {
10218  ret = SQL_SUCCESS;
10219  for (i = 0; i < s->rowset_size; i++) {
10220  ret = setposrefr(s, i);
10221  if (!SQL_SUCCEEDED(ret)) {
10222  break;
10223  }
10224  }
10225  return ret;
10226  }
10227  return setposrefr(s, row - 1);
10228  } else if (op == SQL_DELETE) {
10229  sql = dsappend(sql, "DELETE FROM ");
10230  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10231  sql = dsappendq(sql, s->dyncols[0].db);
10232  sql = dsappend(sql, ".");
10233  }
10234  sql = dsappendq(sql, s->dyncols[0].table);
10235  for (i = k = 0; i < s->ncols; i++) {
10236  if (s->dyncols[i].ispk <= 0) {
10237  continue;
10238  }
10239  sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10240  sql = dsappendq(sql, s->dyncols[i].column);
10241  sql = dsappend(sql, " = ?");
10242  k++;
10243  }
10244  if (dserr(sql)) {
10245  dsfree(sql);
10246  return nomem(s);
10247  }
10248 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10249  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10250 #else
10251  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10252 #endif
10253  do {
10254  s3stmt = NULL;
10255 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10256  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10257  &s3stmt, &endp);
10258 #else
10259  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10260  &s3stmt, &endp);
10261 #endif
10262  if (rc != SQLITE_OK) {
10263  if (s3stmt) {
10264  sqlite3_finalize(s3stmt);
10265  s3stmt = NULL;
10266  }
10267  }
10268  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10269  dbtracerc(d, rc, NULL);
10270  dsfree(sql);
10271  if (rc != SQLITE_OK) {
10272 dstmterr:
10273  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10274  sqlite3_errmsg(d->sqlite), rc);
10275  if (s3stmt) {
10276  dbtraceapi(d, "sqlite3_finalize", NULL);
10277  sqlite3_finalize(s3stmt);
10278  }
10279  return SQL_ERROR;
10280  }
10281  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10282  if (s->dyncols[i].ispk <= 0) {
10283  continue;
10284  }
10285  ret = setposibind(s, s3stmt, i, k, row - 1);
10286  if (ret != SQL_SUCCESS) {
10287  dbtraceapi(d, "sqlite3_finalize", NULL);
10288  sqlite3_finalize(s3stmt);
10289  return ret;
10290  }
10291  k++;
10292  }
10293  rc = sqlite3_step(s3stmt);
10294  if (rc != SQLITE_DONE) {
10295  goto dstmterr;
10296  }
10297  sqlite3_finalize(s3stmt);
10298  if (sqlite3_changes(d->sqlite) > 0) {
10299  if (s->row_status0) {
10300  s->row_status0[row - 1] = SQL_ROW_DELETED;
10301  }
10302  if (s->row_status) {
10303  s->row_status[row - 1] = SQL_ROW_DELETED;
10304  }
10305  }
10306  return SQL_SUCCESS;
10307  } else if (op == SQL_UPDATE) {
10308  ret = chkunbound(s);
10309  if (ret != SQL_SUCCESS) {
10310  return ret;
10311  }
10312  sql = dsappend(sql, "UPDATE ");
10313  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10314  sql = dsappendq(sql, s->dyncols[0].db);
10315  sql = dsappend(sql, ".");
10316  }
10317  sql = dsappendq(sql, s->dyncols[0].table);
10318  for (i = 0; i < s->ncols; i++) {
10319  sql = dsappend(sql, (i > 0) ? ", " : " SET ");
10320  sql = dsappendq(sql, s->dyncols[i].column);
10321  sql = dsappend(sql, " = ?");
10322  }
10323  for (i = k = 0; i < s->ncols; i++) {
10324  if (s->dyncols[i].ispk <= 0) {
10325  continue;
10326  }
10327  sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10328  sql = dsappendq(sql, s->dyncols[i].column);
10329  sql = dsappend(sql, " = ?");
10330  k++;
10331  }
10332  if (dserr(sql)) {
10333  dsfree(sql);
10334  return nomem(s);
10335  }
10336 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10337  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10338 #else
10339  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10340 #endif
10341  do {
10342  s3stmt = NULL;
10343 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10344  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10345  &s3stmt, &endp);
10346 #else
10347  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10348  &s3stmt, &endp);
10349 #endif
10350  if (rc != SQLITE_OK) {
10351  if (s3stmt) {
10352  sqlite3_finalize(s3stmt);
10353  s3stmt = NULL;
10354  }
10355  }
10356  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10357  dbtracerc(d, rc, NULL);
10358  dsfree(sql);
10359  if (rc != SQLITE_OK) {
10360 ustmterr:
10361  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10362  sqlite3_errmsg(d->sqlite), rc);
10363  if (s3stmt) {
10364  dbtraceapi(d, "sqlite3_finalize", NULL);
10365  sqlite3_finalize(s3stmt);
10366  }
10367  return SQL_ERROR;
10368  }
10369  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10370  ret = setposbind(s, s3stmt, i, k, row - 1);
10371  if (ret != SQL_SUCCESS) {
10372  dbtraceapi(d, "sqlite3_finalize", NULL);
10373  sqlite3_finalize(s3stmt);
10374  return ret;
10375  }
10376  k++;
10377  }
10378  for (i = 0; s->bindcols && i < s->ncols; i++) {
10379  if (s->dyncols[i].ispk <= 0) {
10380  continue;
10381  }
10382  ret = setposibind(s, s3stmt, i, k, row - 1);
10383  if (ret != SQL_SUCCESS) {
10384  dbtraceapi(d, "sqlite3_finalize", NULL);
10385  sqlite3_finalize(s3stmt);
10386  return ret;
10387  }
10388  k++;
10389  }
10390  rc = sqlite3_step(s3stmt);
10391  if (rc != SQLITE_DONE) {
10392  goto ustmterr;
10393  }
10394  sqlite3_finalize(s3stmt);
10395  if (sqlite3_changes(d->sqlite) > 0) {
10396  if (s->row_status0) {
10397  s->row_status0[row - 1] = SQL_ROW_UPDATED;
10398  }
10399  if (s->row_status) {
10400  s->row_status[row - 1] = SQL_ROW_UPDATED;
10401  }
10402  }
10403  return SQL_SUCCESS;
10404  }
10405  return SQL_SUCCESS;
10406 }
10407 
10417 SQLRETURN SQL_API
10418 SQLSetPos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10419 {
10420  SQLRETURN ret;
10421 
10422  HSTMT_LOCK(stmt);
10423  ret = drvsetpos(stmt, row, op, lock);
10424  HSTMT_UNLOCK(stmt);
10425  return ret;
10426 }
10427 
10435 static SQLRETURN
10436 drvbulkoperations(SQLHSTMT stmt, SQLSMALLINT op)
10437 {
10438  STMT *s = (STMT *) stmt;
10439  DBC *d = (DBC *) s->dbc;
10440  int row, i, k, rc, nretry = 0;
10441  dstr *sql = 0;
10442  const char *endp;
10443  sqlite3_stmt *s3stmt = NULL;
10444  SQLRETURN ret;
10445 
10446  if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10447  setstat(s, -1, "incompatible statement",
10448  (*s->ov3) ? "HY000" : "S1000");
10449  return SQL_ERROR;
10450  }
10451  if (op == SQL_ADD) {
10452  if (s->one_tbl <= 0) {
10453  setstat(s, -1, "incompatible rowset",
10454  (*s->ov3) ? "HY000" : "S1000");
10455  return SQL_ERROR;
10456  }
10457  ret = chkunbound(s);
10458  if (ret != SQL_SUCCESS) {
10459  return ret;
10460  }
10461  sql = dsappend(sql, "INSERT INTO ");
10462  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10463  sql = dsappendq(sql, s->dyncols[0].db);
10464  sql = dsappend(sql, ".");
10465  }
10466  sql = dsappendq(sql, s->dyncols[0].table);
10467  for (i = 0; i < s->ncols; i++) {
10468  sql = dsappend(sql, (i > 0) ? "," : "(");
10469  sql = dsappendq(sql, s->dyncols[i].column);
10470  }
10471  sql = dsappend(sql, ") VALUES ");
10472  for (i = 0; i < s->ncols; i++) {
10473  sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10474  }
10475  sql = dsappend(sql, ")");
10476  if (dserr(sql)) {
10477  dsfree(sql);
10478  return nomem(s);
10479  }
10480 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10481  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10482 #else
10483  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10484 #endif
10485  do {
10486  s3stmt = NULL;
10487 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10488  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10489  &s3stmt, &endp);
10490 #else
10491  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10492  &s3stmt, &endp);
10493 #endif
10494  if (rc != SQLITE_OK) {
10495  if (s3stmt) {
10496  sqlite3_finalize(s3stmt);
10497  s3stmt = NULL;
10498  }
10499  }
10500  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10501  dbtracerc(d, rc, NULL);
10502  dsfree(sql);
10503  if (rc != SQLITE_OK) {
10504  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10505  sqlite3_errmsg(d->sqlite), rc);
10506  if (s3stmt) {
10507  dbtraceapi(d, "sqlite3_finalize", NULL);
10508  sqlite3_finalize(s3stmt);
10509  }
10510  return SQL_ERROR;
10511  }
10512  for (row = 0; row < s->rowset_size; row++) {
10513  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10514  ret = setposbind(s, s3stmt, i, k, row);
10515  if (ret != SQL_SUCCESS) {
10516 istmterr:
10517  if (s->row_status0) {
10518  s->row_status0[row] = SQL_ROW_ERROR;
10519  }
10520  if (s->row_status) {
10521  s->row_status[row] = SQL_ROW_ERROR;
10522  }
10523  dbtraceapi(d, "sqlite3_finalize", NULL);
10524  sqlite3_finalize(s3stmt);
10525  return ret;
10526  }
10527  k++;
10528  }
10529  rc = sqlite3_step(s3stmt);
10530  if (rc != SQLITE_DONE) {
10531  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10532  sqlite3_errmsg(d->sqlite), rc);
10533  ret = SQL_ERROR;
10534  goto istmterr;
10535  }
10536  if (sqlite3_changes(d->sqlite) > 0) {
10537  if (s->row_status0) {
10538  s->row_status0[row] = SQL_ROW_ADDED;
10539  }
10540  if (s->row_status) {
10541  s->row_status[row] = SQL_ROW_ADDED;
10542  }
10543  }
10544  if (s->bkmrk == SQL_UB_VARIABLE &&
10545  s->bkmrkcol.type == SQL_C_VARBOOKMARK &&
10546  s->bkmrkcol.valp) {
10547  SQLPOINTER *val;
10548 
10549  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10550  val = (SQLPOINTER)
10551  ((char *) s->bkmrkcol.valp + s->bind_type * row);
10552  } else {
10553  val = (SQLPOINTER)
10554  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10555  }
10556  if (s->bind_offs) {
10557  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10558  }
10559  *(sqlite_int64 *) val = sqlite3_last_insert_rowid(d->sqlite);
10560  if (s->bkmrkcol.lenp) {
10561  SQLLEN *ival;
10562 
10563  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10564  ival = (SQLLEN *)
10565  ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10566  } else {
10567  ival = &s->bkmrkcol.lenp[row];
10568  }
10569  if (s->bind_offs) {
10570  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10571  }
10572  *ival = sizeof (sqlite_int64);
10573  }
10574  }
10575  dbtraceapi(d, "sqlite3_reset", NULL);
10576  sqlite3_reset(s3stmt);
10577  }
10578  dbtraceapi(d, "sqlite3_finalize", NULL);
10579  sqlite3_finalize(s3stmt);
10580  return SQL_SUCCESS;
10581  } else if (op == SQL_DELETE_BY_BOOKMARK) {
10582  if (s->has_rowid < 0 ||
10583  s->bkmrk != SQL_UB_VARIABLE ||
10584  s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10585  !s->bkmrkcol.valp) {
10586  setstat(s, -1, "incompatible rowset",
10587  (*s->ov3) ? "HY000" : "S1000");
10588  return SQL_ERROR;
10589  }
10590  sql = dsappend(sql, "DELETE FROM ");
10591  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10592  sql = dsappendq(sql, s->dyncols[0].db);
10593  sql = dsappend(sql, ".");
10594  }
10595  sql = dsappendq(sql, s->dyncols[0].table);
10596  sql = dsappend(sql, " WHERE ");
10597  sql = dsappendq(sql, s->dyncols[0].column);
10598  sql = dsappend(sql, " = ?");
10599  if (dserr(sql)) {
10600  dsfree(sql);
10601  return nomem(s);
10602  }
10603 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10604  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10605 #else
10606  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10607 #endif
10608  do {
10609  s3stmt = NULL;
10610 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10611  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10612  &s3stmt, &endp);
10613 #else
10614  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10615  &s3stmt, &endp);
10616 #endif
10617  if (rc != SQLITE_OK) {
10618  if (s3stmt) {
10619  sqlite3_finalize(s3stmt);
10620  s3stmt = NULL;
10621  }
10622  }
10623  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10624  dbtracerc(d, rc, NULL);
10625  dsfree(sql);
10626  if (rc != SQLITE_OK) {
10627  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10628  sqlite3_errmsg(d->sqlite), rc);
10629  if (s3stmt) {
10630  dbtraceapi(d, "sqlite3_finalize", NULL);
10631  sqlite3_finalize(s3stmt);
10632  }
10633  return SQL_ERROR;
10634  }
10635  for (row = 0; row < s->rowset_size; row++) {
10636  SQLPOINTER *val;
10637  sqlite_int64 rowid;
10638 
10639  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10640  val = (SQLPOINTER)
10641  ((char *) s->bkmrkcol.valp + s->bind_type * row);
10642  } else {
10643  val = (SQLPOINTER)
10644  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10645  }
10646  if (s->bind_offs) {
10647  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10648  }
10649  if (s->bkmrkcol.lenp) {
10650  SQLLEN *ival;
10651 
10652  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10653  ival = (SQLLEN *)
10654  ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10655  } else {
10656  ival = &s->bkmrkcol.lenp[row];
10657  }
10658  if (s->bind_offs) {
10659  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10660  }
10661  if (*ival != sizeof (sqlite_int64)) {
10662  continue;
10663  }
10664  }
10665  rowid = *(sqlite_int64 *) val;
10666  sqlite3_bind_int64(s3stmt, 1, rowid);
10667  if (d->trace) {
10668  fprintf(d->trace,
10669 #ifdef _WIN32
10670  "-- parameter 1: %I64d\n",
10671 #else
10672  "-- parameter 1: %lld\n",
10673 #endif
10674  rowid);
10675  fflush(d->trace);
10676  }
10677  rc = sqlite3_step(s3stmt);
10678  if (rc != SQLITE_DONE) {
10679  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10680  sqlite3_errmsg(d->sqlite), rc);
10681  if (s->row_status0) {
10682  s->row_status0[row] = SQL_ROW_ERROR;
10683  }
10684  if (s->row_status) {
10685  s->row_status[row] = SQL_ROW_ERROR;
10686  }
10687  dbtraceapi(d, "sqlite3_finalize", NULL);
10688  sqlite3_finalize(s3stmt);
10689  return SQL_ERROR;
10690  }
10691  if (sqlite3_changes(d->sqlite) > 0) {
10692  if (s->row_status0) {
10693  s->row_status0[row] = SQL_ROW_DELETED;
10694  }
10695  if (s->row_status) {
10696  s->row_status[row] = SQL_ROW_DELETED;
10697  }
10698  }
10699  dbtraceapi(d, "sqlite3_reset", NULL);
10700  sqlite3_reset(s3stmt);
10701  }
10702  dbtraceapi(d, "sqlite3_finalize", NULL);
10703  sqlite3_finalize(s3stmt);
10704  return SQL_SUCCESS;
10705  } else if (op == SQL_UPDATE_BY_BOOKMARK) {
10706  if (s->has_rowid < 0 ||
10707  s->bkmrk != SQL_UB_VARIABLE ||
10708  s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10709  !s->bkmrkcol.valp) {
10710  setstat(s, -1, "incompatible rowset",
10711  (*s->ov3) ? "HY000" : "S1000");
10712  return SQL_ERROR;
10713  }
10714  ret = chkunbound(s);
10715  if (ret != SQL_SUCCESS) {
10716  return ret;
10717  }
10718  sql = dsappend(sql, "UPDATE ");
10719  if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10720  sql = dsappendq(sql, s->dyncols[0].db);
10721  sql = dsappend(sql, ".");
10722  }
10723  sql = dsappendq(sql, s->dyncols[0].table);
10724  for (i = 0, k = 0; i < s->ncols; i++) {
10725  if (i == s->has_rowid) {
10726  continue;
10727  }
10728  sql = dsappend(sql, (k > 0) ? ", " : " SET ");
10729  sql = dsappendq(sql, s->dyncols[i].column);
10730  sql = dsappend(sql, " = ?");
10731  k++;
10732  }
10733  sql = dsappend(sql, " WHERE ");
10734  sql = dsappendq(sql, s->dyncols[s->has_rowid].column);
10735  sql = dsappend(sql, " = ?");
10736  if (dserr(sql)) {
10737  dsfree(sql);
10738  return nomem(s);
10739  }
10740 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10741  dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10742 #else
10743  dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10744 #endif
10745  do {
10746  s3stmt = NULL;
10747 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10748  rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10749  &s3stmt, &endp);
10750 #else
10751  rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10752  &s3stmt, &endp);
10753 #endif
10754  if (rc != SQLITE_OK) {
10755  if (s3stmt) {
10756  sqlite3_finalize(s3stmt);
10757  s3stmt = NULL;
10758  }
10759  }
10760  } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10761  dbtracerc(d, rc, NULL);
10762  dsfree(sql);
10763  if (rc != SQLITE_OK) {
10764  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10765  sqlite3_errmsg(d->sqlite), rc);
10766  if (s3stmt) {
10767  dbtraceapi(d, "sqlite3_finalize", NULL);
10768  sqlite3_finalize(s3stmt);
10769  }
10770  return SQL_ERROR;
10771  }
10772  for (row = 0; row < s->rowset_size; row++) {
10773  SQLPOINTER *val;
10774  sqlite_int64 rowid;
10775 
10776  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10777  val = (SQLPOINTER)
10778  ((char *) s->bkmrkcol.valp + s->bind_type * row);
10779  } else {
10780  val = (SQLPOINTER)
10781  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10782  }
10783  if (s->bind_offs) {
10784  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10785  }
10786  if (s->bkmrkcol.lenp) {
10787  SQLLEN *ival;
10788 
10789  if (s->bind_type != SQL_BIND_BY_COLUMN) {
10790  ival = (SQLLEN *)
10791  ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10792  } else {
10793  ival = &s->bkmrkcol.lenp[row];
10794  }
10795  if (s->bind_offs) {
10796  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10797  }
10798  if (*ival != sizeof (sqlite_int64)) {
10799  continue;
10800  }
10801  }
10802  for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10803  if (i == s->has_rowid) {
10804  continue;
10805  }
10806  ret = setposbind(s, s3stmt, i, k, row);
10807  if (ret != SQL_SUCCESS) {
10808 ustmterr:
10809  if (s->row_status0) {
10810  s->row_status0[row] = SQL_ROW_ERROR;
10811  }
10812  if (s->row_status) {
10813  s->row_status[row] = SQL_ROW_ERROR;
10814  }
10815  dbtraceapi(d, "sqlite3_finalize", NULL);
10816  sqlite3_finalize(s3stmt);
10817  return ret;
10818  }
10819  k++;
10820  }
10821  rowid = *(sqlite_int64 *) val;
10822  sqlite3_bind_int64(s3stmt, k, rowid);
10823  if (d->trace) {
10824  fprintf(d->trace,
10825 #ifdef _WIN32
10826  "-- parameter %d: %I64d\n",
10827 #else
10828  "-- parameter %d: %lld\n",
10829 #endif
10830  k, rowid);
10831  fflush(d->trace);
10832  }
10833  rc = sqlite3_step(s3stmt);
10834  if (rc != SQLITE_DONE) {
10835  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10836  sqlite3_errmsg(d->sqlite), rc);
10837  ret = SQL_ERROR;
10838  goto ustmterr;
10839  }
10840  if (sqlite3_changes(d->sqlite) > 0) {
10841  if (s->row_status0) {
10842  s->row_status0[row] = SQL_ROW_UPDATED;
10843  }
10844  if (s->row_status) {
10845  s->row_status[row] = SQL_ROW_UPDATED;
10846  }
10847  }
10848  dbtraceapi(d, "sqlite3_reset", NULL);
10849  sqlite3_reset(s3stmt);
10850  }
10851  dbtraceapi(d, "sqlite3_finalize", NULL);
10852  sqlite3_finalize(s3stmt);
10853  return SQL_SUCCESS;
10854  }
10855  setstat(s, -1, "unsupported operation", (*s->ov3) ? "HY000" : "S1000");
10856  return SQL_ERROR;
10857 }
10858 
10866 SQLRETURN SQL_API
10867 SQLBulkOperations(SQLHSTMT stmt, SQLSMALLINT oper)
10868 {
10869  SQLRETURN ret;
10870 
10871  HSTMT_LOCK(stmt);
10872  ret = drvbulkoperations(stmt, oper);
10873  HSTMT_UNLOCK(stmt);
10874  return ret;
10875 }
10876 
10877 
10882 SQLRETURN SQL_API
10883 SQLSetScrollOptions(SQLHSTMT stmt, SQLUSMALLINT concur, SQLLEN rowkeyset,
10884  SQLUSMALLINT rowset)
10885 {
10886  SQLRETURN ret;
10887 
10888  HSTMT_LOCK(stmt);
10889  ret = drvunimplstmt(stmt);
10890  HSTMT_UNLOCK(stmt);
10891  return ret;
10892 }
10893 
10894 #define strmak(dst, src, max, lenp) { \
10895  int len = strlen(src); \
10896  int cnt = min(len + 1, max); \
10897  strncpy(dst, src, cnt); \
10898  *lenp = (cnt > len) ? len : cnt; \
10899 }
10900 
10911 static SQLRETURN
10912 drvgetinfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
10913  SQLSMALLINT *valLen)
10914 {
10915  DBC *d;
10916  char dummyc[16];
10917  SQLSMALLINT dummy;
10918 #if defined(_WIN32) || defined(_WIN64)
10919  char pathbuf[301], *drvname;
10920 #else
10921  static char drvname[] = "sqlite3odbc.so";
10922 #endif
10923 
10924  if (dbc == SQL_NULL_HDBC) {
10925  return SQL_INVALID_HANDLE;
10926  }
10927  d = (DBC *) dbc;
10928  if (valMax) {
10929  valMax--;
10930  }
10931  if (!valLen) {
10932  valLen = &dummy;
10933  }
10934  if (!val) {
10935  val = dummyc;
10936  valMax = sizeof (dummyc) - 1;
10937  }
10938  switch (type) {
10939  case SQL_MAX_USER_NAME_LEN:
10940  *((SQLSMALLINT *) val) = 16;
10941  *valLen = sizeof (SQLSMALLINT);
10942  break;
10943  case SQL_USER_NAME:
10944  strmak(val, "", valMax, valLen);
10945  break;
10946  case SQL_DRIVER_ODBC_VER:
10947 #if 0
10948  strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
10949 #else
10950  strmak(val, "03.00", valMax, valLen);
10951 #endif
10952  break;
10953  case SQL_ACTIVE_CONNECTIONS:
10954  case SQL_ACTIVE_STATEMENTS:
10955  *((SQLSMALLINT *) val) = 0;
10956  *valLen = sizeof (SQLSMALLINT);
10957  break;
10958 #ifdef SQL_ASYNC_MODE
10959  case SQL_ASYNC_MODE:
10960  *((SQLUINTEGER *) val) = SQL_AM_NONE;
10961  *valLen = sizeof (SQLUINTEGER);
10962  break;
10963 #endif
10964 #ifdef SQL_CREATE_TABLE
10965  case SQL_CREATE_TABLE:
10966  *((SQLUINTEGER *) val) = SQL_CT_CREATE_TABLE |
10967  SQL_CT_COLUMN_DEFAULT |
10968  SQL_CT_COLUMN_CONSTRAINT |
10969  SQL_CT_CONSTRAINT_NON_DEFERRABLE;
10970  *valLen = sizeof (SQLUINTEGER);
10971  break;
10972 #endif
10973 #ifdef SQL_CREATE_VIEW
10974  case SQL_CREATE_VIEW:
10975  *((SQLUINTEGER *) val) = SQL_CV_CREATE_VIEW;
10976  *valLen = sizeof (SQLUINTEGER);
10977  break;
10978 #endif
10979 #ifdef SQL_DDL_INDEX
10980  case SQL_DDL_INDEX:
10981  *((SQLUINTEGER *) val) = SQL_DI_CREATE_INDEX | SQL_DI_DROP_INDEX;
10982  *valLen = sizeof (SQLUINTEGER);
10983  break;
10984 #endif
10985 #ifdef SQL_DROP_TABLE
10986  case SQL_DROP_TABLE:
10987  *((SQLUINTEGER *) val) = SQL_DT_DROP_TABLE;
10988  *valLen = sizeof (SQLUINTEGER);
10989  break;
10990 #endif
10991 #ifdef SQL_DROP_VIEW
10992  case SQL_DROP_VIEW:
10993  *((SQLUINTEGER *) val) = SQL_DV_DROP_VIEW;
10994  *valLen = sizeof (SQLUINTEGER);
10995  break;
10996 #endif
10997 #ifdef SQL_INDEX_KEYWORDS
10998  case SQL_INDEX_KEYWORDS:
10999  *((SQLUINTEGER *) val) = SQL_IK_ALL;
11000  *valLen = sizeof (SQLUINTEGER);
11001  break;
11002 #endif
11003  case SQL_DATA_SOURCE_NAME:
11004  strmak(val, d->dsn ? d->dsn : "", valMax, valLen);
11005  break;
11006  case SQL_DRIVER_NAME:
11007 #if defined(_WIN32) || defined(_WIN64)
11008  GetModuleFileName(hModule, pathbuf, sizeof (pathbuf));
11009  drvname = strrchr(pathbuf, '\\');
11010  if (drvname == NULL) {
11011  drvname = strrchr(pathbuf, '/');
11012  }
11013  if (drvname == NULL) {
11014  drvname = pathbuf;
11015  } else {
11016  drvname++;
11017  }
11018 #endif
11019  strmak(val, drvname, valMax, valLen);
11020  break;
11021  case SQL_DRIVER_VER:
11022  strmak(val, DRIVER_VER_INFO, valMax, valLen);
11023  break;
11024  case SQL_FETCH_DIRECTION:
11025  *((SQLUINTEGER *) val) = SQL_FD_FETCH_NEXT | SQL_FD_FETCH_FIRST |
11026  SQL_FD_FETCH_LAST | SQL_FD_FETCH_PRIOR | SQL_FD_FETCH_ABSOLUTE;
11027  *valLen = sizeof (SQLUINTEGER);
11028  break;
11029  case SQL_ODBC_VER:
11030  strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
11031  break;
11032  case SQL_ODBC_SAG_CLI_CONFORMANCE:
11033  *((SQLSMALLINT *) val) = SQL_OSCC_NOT_COMPLIANT;
11034  *valLen = sizeof (SQLSMALLINT);
11035  break;
11036  case SQL_STANDARD_CLI_CONFORMANCE:
11037  *((SQLUINTEGER *) val) = SQL_SCC_XOPEN_CLI_VERSION1;
11038  *valLen = sizeof (SQLUINTEGER);
11039  break;
11040  case SQL_SQL_CONFORMANCE:
11041  *((SQLUINTEGER *) val) = SQL_SC_SQL92_ENTRY;
11042  *valLen = sizeof (SQLUINTEGER);
11043  break;
11044  case SQL_SERVER_NAME:
11045  case SQL_DATABASE_NAME:
11046  strmak(val, d->dbname ? d->dbname : "", valMax, valLen);
11047  break;
11048  case SQL_SEARCH_PATTERN_ESCAPE:
11049  strmak(val, "\\", valMax, valLen);
11050  break;
11051  case SQL_ODBC_SQL_CONFORMANCE:
11052  *((SQLSMALLINT *) val) = SQL_OSC_MINIMUM;
11053  *valLen = sizeof (SQLSMALLINT);
11054  break;
11055  case SQL_ODBC_API_CONFORMANCE:
11056  *((SQLSMALLINT *) val) = SQL_OAC_LEVEL1;
11057  *valLen = sizeof (SQLSMALLINT);
11058  break;
11059  case SQL_DBMS_NAME:
11060  strmak(val, "SQLite", valMax, valLen);
11061  break;
11062  case SQL_DBMS_VER:
11063  strmak(val, SQLITE_VERSION, valMax, valLen);
11064  break;
11065  case SQL_COLUMN_ALIAS:
11066  case SQL_NEED_LONG_DATA_LEN:
11067  strmak(val, "Y", valMax, valLen);
11068  break;
11069  case SQL_ROW_UPDATES:
11070  case SQL_ACCESSIBLE_PROCEDURES:
11071  case SQL_PROCEDURES:
11072  case SQL_EXPRESSIONS_IN_ORDERBY:
11073  case SQL_ODBC_SQL_OPT_IEF:
11074  case SQL_LIKE_ESCAPE_CLAUSE:
11075  case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11076  case SQL_OUTER_JOINS:
11077  case SQL_ACCESSIBLE_TABLES:
11078  case SQL_MULT_RESULT_SETS:
11079  case SQL_MULTIPLE_ACTIVE_TXN:
11080  case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11081  strmak(val, "N", valMax, valLen);
11082  break;
11083 #ifdef SQL_CATALOG_NAME
11084  case SQL_CATALOG_NAME:
11085 #if defined(_WIN32) || defined(_WIN64)
11086  strmak(val, d->xcelqrx ? "Y" : "N", valMax, valLen);
11087 #else
11088  strmak(val, "N", valMax, valLen);
11089 #endif
11090  break;
11091 #endif
11092  case SQL_DATA_SOURCE_READ_ONLY:
11093  strmak(val, "N", valMax, valLen);
11094  break;
11095 #ifdef SQL_OJ_CAPABILITIES
11096  case SQL_OJ_CAPABILITIES:
11097  *((SQLUINTEGER *) val) = 0;
11098  *valLen = sizeof (SQLUINTEGER);
11099  break;
11100 #endif
11101 #ifdef SQL_MAX_IDENTIFIER_LEN
11102  case SQL_MAX_IDENTIFIER_LEN:
11103  *((SQLUSMALLINT *) val) = 255;
11104  *valLen = sizeof (SQLUSMALLINT);
11105  break;
11106 #endif
11107  case SQL_CONCAT_NULL_BEHAVIOR:
11108  *((SQLSMALLINT *) val) = SQL_CB_NULL;
11109  *valLen = sizeof (SQLSMALLINT);
11110  break;
11111  case SQL_CURSOR_COMMIT_BEHAVIOR:
11112  case SQL_CURSOR_ROLLBACK_BEHAVIOR:
11113  *((SQLSMALLINT *) val) = SQL_CB_PRESERVE;
11114  *valLen = sizeof (SQLSMALLINT);
11115  break;
11116 #ifdef SQL_CURSOR_SENSITIVITY
11117  case SQL_CURSOR_SENSITIVITY:
11118  *((SQLUINTEGER *) val) = SQL_UNSPECIFIED;
11119  *valLen = sizeof (SQLUINTEGER);
11120  break;
11121 #endif
11122  case SQL_DEFAULT_TXN_ISOLATION:
11123  *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11124  *valLen = sizeof (SQLUINTEGER);
11125  break;
11126 #ifdef SQL_DESCRIBE_PARAMETER
11127  case SQL_DESCRIBE_PARAMETER:
11128  strmak(val, "Y", valMax, valLen);
11129  break;
11130 #endif
11131  case SQL_TXN_ISOLATION_OPTION:
11132  *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11133  *valLen = sizeof (SQLUINTEGER);
11134  break;
11135  case SQL_IDENTIFIER_CASE:
11136  *((SQLSMALLINT *) val) = SQL_IC_SENSITIVE;
11137  *valLen = sizeof (SQLSMALLINT);
11138  break;
11139  case SQL_IDENTIFIER_QUOTE_CHAR:
11140  strmak(val, "\"", valMax, valLen);
11141  break;
11142  case SQL_MAX_TABLE_NAME_LEN:
11143  case SQL_MAX_COLUMN_NAME_LEN:
11144  *((SQLSMALLINT *) val) = 255;
11145  *valLen = sizeof (SQLSMALLINT);
11146  break;
11147  case SQL_MAX_CURSOR_NAME_LEN:
11148  *((SQLSMALLINT *) val) = 255;
11149  *valLen = sizeof (SQLSMALLINT);
11150  break;
11151  case SQL_MAX_PROCEDURE_NAME_LEN:
11152  *((SQLSMALLINT *) val) = 0;
11153  break;
11154  case SQL_MAX_QUALIFIER_NAME_LEN:
11155  case SQL_MAX_OWNER_NAME_LEN:
11156  *((SQLSMALLINT *) val) = 255;
11157  break;
11158  case SQL_OWNER_TERM:
11159  strmak(val, "", valMax, valLen);
11160  break;
11161  case SQL_PROCEDURE_TERM:
11162  strmak(val, "PROCEDURE", valMax, valLen);
11163  break;
11164  case SQL_QUALIFIER_NAME_SEPARATOR:
11165  strmak(val, ".", valMax, valLen);
11166  break;
11167  case SQL_QUALIFIER_TERM:
11168 #if defined(_WIN32) || defined(_WIN64)
11169  strmak(val, d->xcelqrx ? "catalog" : "", valMax, valLen);
11170 #else
11171  strmak(val, "", valMax, valLen);
11172 #endif
11173  break;
11174  case SQL_QUALIFIER_USAGE:
11175 #if defined(_WIN32) || defined(_WIN64)
11176  *((SQLUINTEGER *) val) = d->xcelqrx ?
11177  (SQL_CU_DML_STATEMENTS | SQL_CU_INDEX_DEFINITION |
11178  SQL_CU_TABLE_DEFINITION) : 0;
11179 #else
11180  *((SQLUINTEGER *) val) = 0;
11181 #endif
11182  *valLen = sizeof (SQLUINTEGER);
11183  break;
11184  case SQL_SCROLL_CONCURRENCY:
11185  *((SQLUINTEGER *) val) = SQL_SCCO_LOCK;
11186  *valLen = sizeof (SQLUINTEGER);
11187  break;
11188  case SQL_SCROLL_OPTIONS:
11189  *((SQLUINTEGER *) val) = SQL_SO_STATIC | SQL_SO_FORWARD_ONLY;
11190  *valLen = sizeof (SQLUINTEGER);
11191  break;
11192  case SQL_TABLE_TERM:
11193  strmak(val, "TABLE", valMax, valLen);
11194  break;
11195  case SQL_TXN_CAPABLE:
11196  *((SQLSMALLINT *) val) = SQL_TC_ALL;
11197  *valLen = sizeof (SQLSMALLINT);
11198  break;
11199  case SQL_CONVERT_FUNCTIONS:
11200  *((SQLUINTEGER *) val) = 0;
11201  *valLen = sizeof (SQLUINTEGER);
11202  break;
11203  case SQL_SYSTEM_FUNCTIONS:
11204  case SQL_NUMERIC_FUNCTIONS:
11205  case SQL_STRING_FUNCTIONS:
11206  case SQL_TIMEDATE_FUNCTIONS:
11207  *((SQLUINTEGER *) val) = 0;
11208  *valLen = sizeof (SQLUINTEGER);
11209  break;
11210  case SQL_CONVERT_BIGINT:
11211  case SQL_CONVERT_BIT:
11212  case SQL_CONVERT_CHAR:
11213  case SQL_CONVERT_DATE:
11214  case SQL_CONVERT_DECIMAL:
11215  case SQL_CONVERT_DOUBLE:
11216  case SQL_CONVERT_FLOAT:
11217  case SQL_CONVERT_INTEGER:
11218  case SQL_CONVERT_LONGVARCHAR:
11219  case SQL_CONVERT_NUMERIC:
11220  case SQL_CONVERT_REAL:
11221  case SQL_CONVERT_SMALLINT:
11222  case SQL_CONVERT_TIME:
11223  case SQL_CONVERT_TIMESTAMP:
11224  case SQL_CONVERT_TINYINT:
11225  case SQL_CONVERT_VARCHAR:
11226  *((SQLUINTEGER *) val) =
11227  SQL_CVT_CHAR | SQL_CVT_NUMERIC | SQL_CVT_DECIMAL |
11228  SQL_CVT_INTEGER | SQL_CVT_SMALLINT | SQL_CVT_FLOAT | SQL_CVT_REAL |
11229  SQL_CVT_DOUBLE | SQL_CVT_VARCHAR | SQL_CVT_LONGVARCHAR |
11230  SQL_CVT_BIT | SQL_CVT_TINYINT | SQL_CVT_BIGINT |
11231  SQL_CVT_DATE | SQL_CVT_TIME | SQL_CVT_TIMESTAMP;
11232  *valLen = sizeof (SQLUINTEGER);
11233  break;
11234  case SQL_CONVERT_BINARY:
11235  case SQL_CONVERT_VARBINARY:
11236  case SQL_CONVERT_LONGVARBINARY:
11237  *((SQLUINTEGER *) val) = 0;
11238  *valLen = sizeof (SQLUINTEGER);
11239  break;
11240  case SQL_POSITIONED_STATEMENTS:
11241  *((SQLUINTEGER *) val) = 0;
11242  *valLen = sizeof (SQLUINTEGER);
11243  break;
11244  case SQL_LOCK_TYPES:
11245  *((SQLUINTEGER *) val) = SQL_LCK_NO_CHANGE;
11246  *valLen = sizeof (SQLUINTEGER);
11247  break;
11248  case SQL_BOOKMARK_PERSISTENCE:
11249  *((SQLUINTEGER *) val) = SQL_BP_SCROLL;
11250  *valLen = sizeof (SQLUINTEGER);
11251  break;
11252  case SQL_UNION:
11253  *((SQLUINTEGER *) val) = SQL_U_UNION | SQL_U_UNION_ALL;
11254  *valLen = sizeof (SQLUINTEGER);
11255  break;
11256  case SQL_OWNER_USAGE:
11257  case SQL_SUBQUERIES:
11258  case SQL_TIMEDATE_ADD_INTERVALS:
11259  case SQL_TIMEDATE_DIFF_INTERVALS:
11260  *((SQLUINTEGER *) val) = 0;
11261  *valLen = sizeof (SQLUINTEGER);
11262  break;
11263  case SQL_QUOTED_IDENTIFIER_CASE:
11264  *((SQLUSMALLINT *) val) = SQL_IC_SENSITIVE;
11265  *valLen = sizeof (SQLUSMALLINT);
11266  break;
11267  case SQL_POS_OPERATIONS:
11268  *((SQLUINTEGER *) val) = SQL_POS_POSITION | SQL_POS_UPDATE |
11269  SQL_POS_DELETE | SQL_POS_ADD | SQL_POS_REFRESH;
11270  *valLen = sizeof (SQLUINTEGER);
11271  break;
11272  case SQL_ALTER_TABLE:
11273  *((SQLUINTEGER *) val) = 0;
11274  *valLen = sizeof (SQLUINTEGER);
11275  break;
11276  case SQL_CORRELATION_NAME:
11277  *((SQLSMALLINT *) val) = SQL_CN_DIFFERENT;
11278  *valLen = sizeof (SQLSMALLINT);
11279  break;
11280  case SQL_NON_NULLABLE_COLUMNS:
11281  *((SQLSMALLINT *) val) = SQL_NNC_NON_NULL;
11282  *valLen = sizeof (SQLSMALLINT);
11283  break;
11284  case SQL_NULL_COLLATION:
11285  *((SQLSMALLINT *) val) = SQL_NC_START;
11286  *valLen = sizeof (SQLSMALLINT);
11287  break;
11288  case SQL_MAX_COLUMNS_IN_GROUP_BY:
11289  case SQL_MAX_COLUMNS_IN_ORDER_BY:
11290  case SQL_MAX_COLUMNS_IN_SELECT:
11291  case SQL_MAX_COLUMNS_IN_TABLE:
11292  case SQL_MAX_ROW_SIZE:
11293  case SQL_MAX_TABLES_IN_SELECT:
11294  *((SQLSMALLINT *) val) = 0;
11295  *valLen = sizeof (SQLSMALLINT);
11296  break;
11297  case SQL_MAX_BINARY_LITERAL_LEN:
11298  case SQL_MAX_CHAR_LITERAL_LEN:
11299  *((SQLUINTEGER *) val) = 0;
11300  *valLen = sizeof (SQLUINTEGER);
11301  break;
11302  case SQL_MAX_COLUMNS_IN_INDEX:
11303  *((SQLSMALLINT *) val) = 0;
11304  *valLen = sizeof (SQLSMALLINT);
11305  break;
11306  case SQL_MAX_INDEX_SIZE:
11307  *((SQLUINTEGER *) val) = 0;
11308  *valLen = sizeof (SQLUINTEGER);
11309  break;
11310 #ifdef SQL_MAX_IDENTIFIER_LENGTH
11311  case SQL_MAX_IDENTIFIER_LENGTH:
11312  *((SQLUINTEGER *) val) = 255;
11313  *valLen = sizeof (SQLUINTEGER);
11314  break;
11315 #endif
11316  case SQL_MAX_STATEMENT_LEN:
11317  *((SQLUINTEGER *) val) = 16384;
11318  *valLen = sizeof (SQLUINTEGER);
11319  break;
11320  case SQL_QUALIFIER_LOCATION:
11321  *((SQLSMALLINT *) val) = SQL_QL_START;
11322  *valLen = sizeof (SQLSMALLINT);
11323  break;
11324  case SQL_GETDATA_EXTENSIONS:
11325  *((SQLUINTEGER *) val) =
11326  SQL_GD_ANY_COLUMN | SQL_GD_ANY_ORDER | SQL_GD_BOUND;
11327  *valLen = sizeof (SQLUINTEGER);
11328  break;
11329  case SQL_STATIC_SENSITIVITY:
11330  *((SQLUINTEGER *) val) = 0;
11331  *valLen = sizeof (SQLUINTEGER);
11332  break;
11333  case SQL_FILE_USAGE:
11334 #if defined(_WIN32) || defined(_WIN64)
11335  *((SQLSMALLINT *) val) =
11336  d->xcelqrx ? SQL_FILE_CATALOG : SQL_FILE_NOT_SUPPORTED;
11337 #else
11338  *((SQLSMALLINT *) val) = SQL_FILE_NOT_SUPPORTED;
11339 #endif
11340  *valLen = sizeof (SQLSMALLINT);
11341  break;
11342  case SQL_GROUP_BY:
11343  *((SQLSMALLINT *) val) = SQL_GB_GROUP_BY_EQUALS_SELECT;
11344  *valLen = sizeof (SQLSMALLINT);
11345  break;
11346  case SQL_KEYWORDS:
11347  strmak(val, "CREATE,SELECT,DROP,DELETE,UPDATE,INSERT,"
11348  "INTO,VALUES,TABLE,INDEX,FROM,SET,WHERE,AND,CURRENT,OF",
11349  valMax, valLen);
11350  break;
11351  case SQL_SPECIAL_CHARACTERS:
11352 #ifdef SQL_COLLATION_SEQ
11353  case SQL_COLLATION_SEQ:
11354 #endif
11355  strmak(val, "", valMax, valLen);
11356  break;
11357  case SQL_BATCH_SUPPORT:
11358  case SQL_BATCH_ROW_COUNT:
11359  case SQL_PARAM_ARRAY_ROW_COUNTS:
11360  *((SQLUINTEGER *) val) = 0;
11361  *valLen = sizeof (SQLUINTEGER);
11362  break;
11363  case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1:
11364  *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_BOOKMARK;
11365  *valLen = sizeof (SQLUINTEGER);
11366  break;
11367  case SQL_STATIC_CURSOR_ATTRIBUTES1:
11368  *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE |
11369  SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK | SQL_CA1_POS_POSITION |
11370  SQL_CA1_POS_DELETE | SQL_CA1_POS_UPDATE | SQL_CA1_POS_REFRESH |
11371  SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_BULK_ADD |
11372  SQL_CA1_BULK_UPDATE_BY_BOOKMARK | SQL_CA1_BULK_DELETE_BY_BOOKMARK;
11373  *valLen = sizeof (SQLUINTEGER);
11374  break;
11375  case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2:
11376  case SQL_STATIC_CURSOR_ATTRIBUTES2:
11377  *((SQLUINTEGER *) val) = SQL_CA2_READ_ONLY_CONCURRENCY |
11378  SQL_CA2_LOCK_CONCURRENCY;
11379  *valLen = sizeof (SQLUINTEGER);
11380  break;
11381  case SQL_KEYSET_CURSOR_ATTRIBUTES1:
11382  case SQL_KEYSET_CURSOR_ATTRIBUTES2:
11383  case SQL_DYNAMIC_CURSOR_ATTRIBUTES1:
11384  case SQL_DYNAMIC_CURSOR_ATTRIBUTES2:
11385  *((SQLUINTEGER *) val) = 0;
11386  *valLen = sizeof (SQLUINTEGER);
11387  break;
11388  case SQL_ODBC_INTERFACE_CONFORMANCE:
11389  *((SQLUINTEGER *) val) = SQL_OIC_CORE;
11390  *valLen = sizeof (SQLUINTEGER);
11391  break;
11392  default:
11393  setstatd(d, -1, "unsupported info option %d",
11394  (*d->ov3) ? "HYC00" : "S1C00", type);
11395  return SQL_ERROR;
11396  }
11397  return SQL_SUCCESS;
11398 }
11399 
11400 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
11401 
11411 SQLRETURN SQL_API
11412 SQLGetInfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11413  SQLSMALLINT *valLen)
11414 {
11415  SQLRETURN ret;
11416 
11417  HDBC_LOCK(dbc);
11418  ret = drvgetinfo(dbc, type, val, valMax, valLen);
11419  HDBC_UNLOCK(dbc);
11420  return ret;
11421 }
11422 #endif
11423 
11424 #ifdef WINTERFACE
11425 
11435 SQLRETURN SQL_API
11436 SQLGetInfoW(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11437  SQLSMALLINT *valLen)
11438 {
11439  SQLRETURN ret;
11440  SQLSMALLINT len = 0;
11441 
11442  HDBC_LOCK(dbc);
11443  ret = drvgetinfo(dbc, type, val, valMax, &len);
11444  HDBC_UNLOCK(dbc);
11445  if (ret == SQL_SUCCESS) {
11446  SQLWCHAR *v = NULL;
11447 
11448  switch (type) {
11449  case SQL_USER_NAME:
11450  case SQL_DRIVER_ODBC_VER:
11451  case SQL_DATA_SOURCE_NAME:
11452  case SQL_DRIVER_NAME:
11453  case SQL_DRIVER_VER:
11454  case SQL_ODBC_VER:
11455  case SQL_SERVER_NAME:
11456  case SQL_DATABASE_NAME:
11457  case SQL_SEARCH_PATTERN_ESCAPE:
11458  case SQL_DBMS_NAME:
11459  case SQL_DBMS_VER:
11460  case SQL_NEED_LONG_DATA_LEN:
11461  case SQL_ROW_UPDATES:
11462  case SQL_ACCESSIBLE_PROCEDURES:
11463  case SQL_PROCEDURES:
11464  case SQL_EXPRESSIONS_IN_ORDERBY:
11465  case SQL_ODBC_SQL_OPT_IEF:
11466  case SQL_LIKE_ESCAPE_CLAUSE:
11467  case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11468  case SQL_OUTER_JOINS:
11469  case SQL_COLUMN_ALIAS:
11470  case SQL_ACCESSIBLE_TABLES:
11471  case SQL_MULT_RESULT_SETS:
11472  case SQL_MULTIPLE_ACTIVE_TXN:
11473  case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11474  case SQL_DATA_SOURCE_READ_ONLY:
11475 #ifdef SQL_DESCRIBE_PARAMETER
11476  case SQL_DESCRIBE_PARAMETER:
11477 #endif
11478  case SQL_IDENTIFIER_QUOTE_CHAR:
11479  case SQL_OWNER_TERM:
11480  case SQL_PROCEDURE_TERM:
11481  case SQL_QUALIFIER_NAME_SEPARATOR:
11482  case SQL_QUALIFIER_TERM:
11483  case SQL_TABLE_TERM:
11484  case SQL_KEYWORDS:
11485  case SQL_SPECIAL_CHARACTERS:
11486 #ifdef SQL_CATALOG_NAME
11487  case SQL_CATALOG_NAME:
11488 #endif
11489 #ifdef SQL_COLLATION_SEQ
11490  case SQL_COLLATION_SEQ:
11491 #endif
11492  if (val) {
11493  if (len > 0) {
11494  v = uc_from_utf((SQLCHAR *) val, len);
11495  if (v) {
11496  int vmax = valMax / sizeof (SQLWCHAR);
11497 
11498  uc_strncpy(val, v, vmax);
11499  if (len < vmax) {
11500  len = min(vmax, uc_strlen(v));
11501  v[len] = 0;
11502  } else {
11503  len = vmax;
11504  }
11505  uc_free(v);
11506  len *= sizeof (SQLWCHAR);
11507  } else {
11508  len = 0;
11509  }
11510  }
11511  if (len <= 0) {
11512  len = 0;
11513  if (valMax >= sizeof (SQLWCHAR)) {
11514  *((SQLWCHAR *)val) = 0;
11515  }
11516  }
11517  } else {
11518  len *= sizeof (SQLWCHAR);
11519  }
11520  break;
11521  }
11522  if (valLen) {
11523  *valLen = len;
11524  }
11525  }
11526  return ret;
11527 }
11528 #endif
11529 
11538 SQLRETURN SQL_API
11539 SQLGetFunctions(SQLHDBC dbc, SQLUSMALLINT func,
11540  SQLUSMALLINT *flags)
11541 {
11542  int i;
11543  SQLUSMALLINT exists[100];
11544 
11545  if (dbc == SQL_NULL_HDBC) {
11546  return SQL_INVALID_HANDLE;
11547  }
11548  for (i = 0; i < array_size(exists); i++) {
11549  exists[i] = SQL_FALSE;
11550  }
11551  exists[SQL_API_SQLALLOCCONNECT] = SQL_TRUE;
11552  exists[SQL_API_SQLFETCH] = SQL_TRUE;
11553  exists[SQL_API_SQLALLOCENV] = SQL_TRUE;
11554  exists[SQL_API_SQLFREECONNECT] = SQL_TRUE;
11555  exists[SQL_API_SQLALLOCSTMT] = SQL_TRUE;
11556  exists[SQL_API_SQLFREEENV] = SQL_TRUE;
11557  exists[SQL_API_SQLBINDCOL] = SQL_TRUE;
11558  exists[SQL_API_SQLFREESTMT] = SQL_TRUE;
11559  exists[SQL_API_SQLCANCEL] = SQL_TRUE;
11560  exists[SQL_API_SQLGETCURSORNAME] = SQL_TRUE;
11561  exists[SQL_API_SQLCOLATTRIBUTES] = SQL_TRUE;
11562  exists[SQL_API_SQLNUMRESULTCOLS] = SQL_TRUE;
11563  exists[SQL_API_SQLCONNECT] = SQL_TRUE;
11564  exists[SQL_API_SQLPREPARE] = SQL_TRUE;
11565  exists[SQL_API_SQLDESCRIBECOL] = SQL_TRUE;
11566  exists[SQL_API_SQLROWCOUNT] = SQL_TRUE;
11567  exists[SQL_API_SQLDISCONNECT] = SQL_TRUE;
11568  exists[SQL_API_SQLSETCURSORNAME] = SQL_FALSE;
11569  exists[SQL_API_SQLERROR] = SQL_TRUE;
11570  exists[SQL_API_SQLSETPARAM] = SQL_TRUE;
11571  exists[SQL_API_SQLEXECDIRECT] = SQL_TRUE;
11572  exists[SQL_API_SQLTRANSACT] = SQL_TRUE;
11573  exists[SQL_API_SQLBULKOPERATIONS] = SQL_TRUE;
11574  exists[SQL_API_SQLEXECUTE] = SQL_TRUE;
11575  exists[SQL_API_SQLBINDPARAMETER] = SQL_TRUE;
11576  exists[SQL_API_SQLGETTYPEINFO] = SQL_TRUE;
11577  exists[SQL_API_SQLCOLUMNS] = SQL_TRUE;
11578  exists[SQL_API_SQLPARAMDATA] = SQL_TRUE;
11579  exists[SQL_API_SQLDRIVERCONNECT] = SQL_TRUE;
11580  exists[SQL_API_SQLPUTDATA] = SQL_TRUE;
11581  exists[SQL_API_SQLGETCONNECTOPTION] = SQL_TRUE;
11582  exists[SQL_API_SQLSETCONNECTOPTION] = SQL_TRUE;
11583  exists[SQL_API_SQLGETDATA] = SQL_TRUE;
11584  exists[SQL_API_SQLSETSTMTOPTION] = SQL_TRUE;
11585  exists[SQL_API_SQLGETFUNCTIONS] = SQL_TRUE;
11586  exists[SQL_API_SQLSPECIALCOLUMNS] = SQL_TRUE;
11587  exists[SQL_API_SQLGETINFO] = SQL_TRUE;
11588  exists[SQL_API_SQLSTATISTICS] = SQL_TRUE;
11589  exists[SQL_API_SQLGETSTMTOPTION] = SQL_TRUE;
11590  exists[SQL_API_SQLTABLES] = SQL_TRUE;
11591  exists[SQL_API_SQLBROWSECONNECT] = SQL_FALSE;
11592  exists[SQL_API_SQLNUMPARAMS] = SQL_TRUE;
11593  exists[SQL_API_SQLCOLUMNPRIVILEGES] = SQL_FALSE;
11594  exists[SQL_API_SQLPARAMOPTIONS] = SQL_FALSE;
11595  exists[SQL_API_SQLDATASOURCES] = SQL_TRUE;
11596  exists[SQL_API_SQLPRIMARYKEYS] = SQL_TRUE;
11597  exists[SQL_API_SQLDESCRIBEPARAM] = SQL_TRUE;
11598  exists[SQL_API_SQLPROCEDURECOLUMNS] = SQL_TRUE;
11599  exists[SQL_API_SQLDRIVERS] = SQL_FALSE;
11600  exists[SQL_API_SQLPROCEDURES] = SQL_TRUE;
11601  exists[SQL_API_SQLEXTENDEDFETCH] = SQL_TRUE;
11602  exists[SQL_API_SQLSETPOS] = SQL_TRUE;
11603  exists[SQL_API_SQLFOREIGNKEYS] = SQL_TRUE;
11604  exists[SQL_API_SQLSETSCROLLOPTIONS] = SQL_TRUE;
11605  exists[SQL_API_SQLMORERESULTS] = SQL_TRUE;
11606  exists[SQL_API_SQLTABLEPRIVILEGES] = SQL_TRUE;
11607  exists[SQL_API_SQLNATIVESQL] = SQL_TRUE;
11608  if (func == SQL_API_ALL_FUNCTIONS) {
11609  memcpy(flags, exists, sizeof (exists));
11610  } else if (func == SQL_API_ODBC3_ALL_FUNCTIONS) {
11611  int i;
11612 #define SET_EXISTS(x) \
11613  flags[(x) >> 4] |= (1 << ((x) & 0xF))
11614 #define CLR_EXISTS(x) \
11615  flags[(x) >> 4] &= ~(1 << ((x) & 0xF))
11616 
11617  memset(flags, 0,
11618  sizeof (SQLUSMALLINT) * SQL_API_ODBC3_ALL_FUNCTIONS_SIZE);
11619  for (i = 0; i < array_size(exists); i++) {
11620  if (exists[i]) {
11621  flags[i >> 4] |= (1 << (i & 0xF));
11622  }
11623  }
11624  SET_EXISTS(SQL_API_SQLALLOCHANDLE);
11625  SET_EXISTS(SQL_API_SQLFREEHANDLE);
11626  SET_EXISTS(SQL_API_SQLGETSTMTATTR);
11627  SET_EXISTS(SQL_API_SQLSETSTMTATTR);
11628  SET_EXISTS(SQL_API_SQLGETCONNECTATTR);
11629  SET_EXISTS(SQL_API_SQLSETCONNECTATTR);
11630  SET_EXISTS(SQL_API_SQLGETENVATTR);
11631  SET_EXISTS(SQL_API_SQLSETENVATTR);
11632  SET_EXISTS(SQL_API_SQLCLOSECURSOR);
11633  SET_EXISTS(SQL_API_SQLBINDPARAM);
11634 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11635  /*
11636  * Some unixODBC versions have problems with
11637  * SQLError() vs. SQLGetDiagRec() with loss
11638  * of error/warning messages.
11639  */
11640  SET_EXISTS(SQL_API_SQLGETDIAGREC);
11641 #endif
11642  SET_EXISTS(SQL_API_SQLGETDIAGFIELD);
11643  SET_EXISTS(SQL_API_SQLFETCHSCROLL);
11644  SET_EXISTS(SQL_API_SQLENDTRAN);
11645  } else {
11646  if (func < array_size(exists)) {
11647  *flags = exists[func];
11648  } else {
11649  switch (func) {
11650  case SQL_API_SQLALLOCHANDLE:
11651  case SQL_API_SQLFREEHANDLE:
11652  case SQL_API_SQLGETSTMTATTR:
11653  case SQL_API_SQLSETSTMTATTR:
11654  case SQL_API_SQLGETCONNECTATTR:
11655  case SQL_API_SQLSETCONNECTATTR:
11656  case SQL_API_SQLGETENVATTR:
11657  case SQL_API_SQLSETENVATTR:
11658  case SQL_API_SQLCLOSECURSOR:
11659  case SQL_API_SQLBINDPARAM:
11660 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11661  /*
11662  * Some unixODBC versions have problems with
11663  * SQLError() vs. SQLGetDiagRec() with loss
11664  * of error/warning messages.
11665  */
11666  case SQL_API_SQLGETDIAGREC:
11667 #endif
11668  case SQL_API_SQLGETDIAGFIELD:
11669  case SQL_API_SQLFETCHSCROLL:
11670  case SQL_API_SQLENDTRAN:
11671  *flags = SQL_TRUE;
11672  break;
11673  default:
11674  *flags = SQL_FALSE;
11675  }
11676  }
11677  }
11678  return SQL_SUCCESS;
11679 }
11680 
11687 static SQLRETURN
11688 drvallocenv(SQLHENV *env)
11689 {
11690  ENV *e;
11691 
11692  if (env == NULL) {
11693  return SQL_INVALID_HANDLE;
11694  }
11695  e = (ENV *) xmalloc(sizeof (ENV));
11696  if (e == NULL) {
11697  *env = SQL_NULL_HENV;
11698  return SQL_ERROR;
11699  }
11700  e->magic = ENV_MAGIC;
11701  e->ov3 = 0;
11702 #if defined(_WIN32) || defined(_WIN64)
11703  InitializeCriticalSection(&e->cs);
11704 #else
11705 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
11706  nvfs_init();
11707 #endif
11708 #endif
11709  e->dbcs = NULL;
11710  *env = (SQLHENV) e;
11711  return SQL_SUCCESS;
11712 }
11713 
11720 SQLRETURN SQL_API
11721 SQLAllocEnv(SQLHENV *env)
11722 {
11723  return drvallocenv(env);
11724 }
11725 
11732 static SQLRETURN
11733 drvfreeenv(SQLHENV env)
11734 {
11735  ENV *e;
11736 
11737  if (env == SQL_NULL_HENV) {
11738  return SQL_INVALID_HANDLE;
11739  }
11740  e = (ENV *) env;
11741  if (e->magic != ENV_MAGIC) {
11742  return SQL_SUCCESS;
11743  }
11744 #if defined(_WIN32) || defined(_WIN64)
11745  EnterCriticalSection(&e->cs);
11746 #endif
11747  if (e->dbcs) {
11748 #if defined(_WIN32) || defined(_WIN64)
11749  LeaveCriticalSection(&e->cs);
11750 #endif
11751  return SQL_ERROR;
11752  }
11753  e->magic = DEAD_MAGIC;
11754 #if defined(_WIN32) || defined(_WIN64)
11755  LeaveCriticalSection(&e->cs);
11756  DeleteCriticalSection(&e->cs);
11757 #endif
11758  xfree(e);
11759  return SQL_SUCCESS;
11760 }
11761 
11768 SQLRETURN SQL_API
11769 SQLFreeEnv(SQLHENV env)
11770 {
11771  return drvfreeenv(env);
11772 }
11773 
11781 static SQLRETURN
11782 drvallocconnect(SQLHENV env, SQLHDBC *dbc)
11783 {
11784  DBC *d;
11785  ENV *e;
11786  const char *verstr;
11787  int maj = 0, min = 0, lev = 0;
11788 
11789  if (dbc == NULL) {
11790  return SQL_ERROR;
11791  }
11792  d = (DBC *) xmalloc(sizeof (DBC));
11793  if (d == NULL) {
11794  *dbc = SQL_NULL_HDBC;
11795  return SQL_ERROR;
11796  }
11797  memset(d, 0, sizeof (DBC));
11798  d->curtype = SQL_CURSOR_STATIC;
11799  d->ov3 = &d->ov3val;
11800  verstr = sqlite3_libversion();
11801  sscanf(verstr, "%d.%d.%d", &maj, &min, &lev);
11802  d->version = verinfo(maj & 0xFF, min & 0xFF, lev & 0xFF);
11803  e = (ENV *) env;
11804 #if defined(_WIN32) || defined(_WIN64)
11805  if (e->magic == ENV_MAGIC) {
11806  EnterCriticalSection(&e->cs);
11807  }
11808 #endif
11809  if (e->magic == ENV_MAGIC) {
11810  DBC *n, *p;
11811 
11812  d->env = e;
11813  d->ov3 = &e->ov3;
11814  p = NULL;
11815  n = e->dbcs;
11816  while (n) {
11817  p = n;
11818  n = n->next;
11819  }
11820  if (p) {
11821  p->next = d;
11822  } else {
11823  e->dbcs = d;
11824  }
11825  }
11826 #if defined(_WIN32) || defined(_WIN64)
11827  InitializeCriticalSection(&d->cs);
11828  d->owner = 0;
11829  if (e->magic == ENV_MAGIC) {
11830  LeaveCriticalSection(&e->cs);
11831  }
11832  d->oemcp = 1;
11833 #endif
11834  d->autocommit = 1;
11835  d->magic = DBC_MAGIC;
11836  *dbc = (SQLHDBC) d;
11837  drvgetgpps(d);
11838  return SQL_SUCCESS;
11839 }
11840 
11848 SQLRETURN SQL_API
11849 SQLAllocConnect(SQLHENV env, SQLHDBC *dbc)
11850 {
11851  return drvallocconnect(env, dbc);
11852 }
11853 
11860 static SQLRETURN
11861 drvfreeconnect(SQLHDBC dbc)
11862 {
11863  DBC *d;
11864  ENV *e;
11865  SQLRETURN ret = SQL_ERROR;
11866 
11867  if (dbc == SQL_NULL_HDBC) {
11868  return SQL_INVALID_HANDLE;
11869  }
11870  d = (DBC *) dbc;
11871  if (d->magic != DBC_MAGIC) {
11872  return SQL_INVALID_HANDLE;
11873  }
11874  e = d->env;
11875  if (e && e->magic == ENV_MAGIC) {
11876 #if defined(_WIN32) || defined(_WIN64)
11877  EnterCriticalSection(&e->cs);
11878 #endif
11879  } else {
11880  e = NULL;
11881  }
11882  HDBC_LOCK(dbc);
11883  if (d->sqlite) {
11884  setstatd(d, -1, "not disconnected", (*d->ov3) ? "HY000" : "S1000");
11885  HDBC_UNLOCK(dbc);
11886  goto done;
11887  }
11888  while (d->stmt) {
11889  freestmt((HSTMT) d->stmt);
11890  }
11891  if (e && e->magic == ENV_MAGIC) {
11892  DBC *n, *p;
11893 
11894  p = NULL;
11895  n = e->dbcs;
11896  while (n) {
11897  if (n == d) {
11898  break;
11899  }
11900  p = n;
11901  n = n->next;
11902  }
11903  if (n) {
11904  if (p) {
11905  p->next = d->next;
11906  } else {
11907  e->dbcs = d->next;
11908  }
11909  }
11910  }
11911  drvrelgpps(d);
11912  d->magic = DEAD_MAGIC;
11913  if (d->trace) {
11914  fclose(d->trace);
11915  }
11916 #if defined(_WIN32) || defined(_WIN64)
11917  d->owner = 0;
11918  LeaveCriticalSection(&d->cs);
11919  DeleteCriticalSection(&d->cs);
11920 #endif
11921  xfree(d);
11922  ret = SQL_SUCCESS;
11923 done:
11924 #if defined(_WIN32) || defined(_WIN64)
11925  if (e) {
11926  LeaveCriticalSection(&e->cs);
11927  }
11928 #endif
11929  return ret;
11930 }
11931 
11938 SQLRETURN SQL_API
11939 SQLFreeConnect(SQLHDBC dbc)
11940 {
11941  return drvfreeconnect(dbc);
11942 }
11943 
11954 static SQLRETURN
11955 drvgetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
11956  SQLINTEGER bufmax, SQLINTEGER *buflen)
11957 {
11958  DBC *d;
11959  SQLINTEGER dummy;
11960 
11961  if (dbc == SQL_NULL_HDBC) {
11962  return SQL_INVALID_HANDLE;
11963  }
11964  d = (DBC *) dbc;
11965  if (!val) {
11966  val = (SQLPOINTER) &dummy;
11967  }
11968  if (!buflen) {
11969  buflen = &dummy;
11970  }
11971  switch (attr) {
11972  case SQL_ATTR_CONNECTION_DEAD:
11973  *((SQLINTEGER *) val) = d->sqlite ? SQL_CD_FALSE : SQL_CD_TRUE;
11974  *buflen = sizeof (SQLINTEGER);
11975  break;
11976  case SQL_ATTR_ACCESS_MODE:
11977  *((SQLINTEGER *) val) = SQL_MODE_READ_WRITE;
11978  *buflen = sizeof (SQLINTEGER);
11979  break;
11980  case SQL_ATTR_AUTOCOMMIT:
11981  *((SQLINTEGER *) val) =
11982  d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
11983  *buflen = sizeof (SQLINTEGER);
11984  break;
11985  case SQL_ATTR_LOGIN_TIMEOUT:
11986  *((SQLINTEGER *) val) = 100;
11987  *buflen = sizeof (SQLINTEGER);
11988  break;
11989  case SQL_ATTR_ODBC_CURSORS:
11990  *((SQLINTEGER *) val) = SQL_CUR_USE_DRIVER;
11991  *buflen = sizeof (SQLINTEGER);
11992  break;
11993  case SQL_ATTR_PACKET_SIZE:
11994  *((SQLINTEGER *) val) = 16384;
11995  *buflen = sizeof (SQLINTEGER);
11996  break;
11997  case SQL_ATTR_TXN_ISOLATION:
11998  *((SQLINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11999  *buflen = sizeof (SQLINTEGER);
12000  break;
12001  case SQL_ATTR_TRACEFILE:
12002  case SQL_ATTR_TRANSLATE_LIB:
12003  *((SQLCHAR *) val) = 0;
12004  *buflen = 0;
12005  break;
12006  case SQL_ATTR_CURRENT_CATALOG:
12007 #if defined(_WIN32) || defined(_WIN64)
12008  if (d->xcelqrx) {
12009  if ((bufmax > 4) && (val != (SQLPOINTER) &dummy)) {
12010  strcpy((char *) val, "main");
12011  *buflen = 4;
12012  break;
12013  }
12014  }
12015 #endif
12016  *((SQLCHAR *) val) = 0;
12017  *buflen = 0;
12018  break;
12019  case SQL_ATTR_TRACE:
12020  case SQL_ATTR_QUIET_MODE:
12021  case SQL_ATTR_TRANSLATE_OPTION:
12022  case SQL_ATTR_KEYSET_SIZE:
12023  case SQL_ATTR_QUERY_TIMEOUT:
12024  *((SQLINTEGER *) val) = 0;
12025  *buflen = sizeof (SQLINTEGER);
12026  break;
12027  case SQL_ATTR_PARAM_BIND_TYPE:
12028  *((SQLULEN *) val) = SQL_PARAM_BIND_BY_COLUMN;
12029  *buflen = sizeof (SQLUINTEGER);
12030  break;
12031  case SQL_ATTR_ROW_BIND_TYPE:
12032  *((SQLULEN *) val) = SQL_BIND_BY_COLUMN;
12033  *buflen = sizeof (SQLULEN);
12034  break;
12035  case SQL_ATTR_USE_BOOKMARKS:
12036  *((SQLINTEGER *) val) = SQL_UB_OFF;
12037  *buflen = sizeof (SQLINTEGER);
12038  break;
12039  case SQL_ATTR_ASYNC_ENABLE:
12040  *((SQLINTEGER *) val) = SQL_ASYNC_ENABLE_OFF;
12041  *buflen = sizeof (SQLINTEGER);
12042  break;
12043  case SQL_ATTR_NOSCAN:
12044  *((SQLINTEGER *) val) = SQL_NOSCAN_ON;
12045  *buflen = sizeof (SQLINTEGER);
12046  break;
12047  case SQL_ATTR_CONCURRENCY:
12048  *((SQLINTEGER *) val) = SQL_CONCUR_LOCK;
12049  *buflen = sizeof (SQLINTEGER);
12050  break;
12051 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
12052  case SQL_ATTR_CURSOR_SENSITIVITY:
12053  *((SQLINTEGER *) val) = SQL_UNSPECIFIED;
12054  *buflen = sizeof (SQLINTEGER);
12055  break;
12056 #endif
12057  case SQL_ATTR_SIMULATE_CURSOR:
12058  *((SQLINTEGER *) val) = SQL_SC_NON_UNIQUE;
12059  *buflen = sizeof (SQLINTEGER);
12060  break;
12061  case SQL_ATTR_MAX_ROWS:
12062  *((SQLINTEGER *) val) = 0;
12063  *buflen = sizeof (SQLINTEGER);
12064  case SQL_ATTR_MAX_LENGTH:
12065  *((SQLINTEGER *) val) = 1000000000;
12066  *buflen = sizeof (SQLINTEGER);
12067  break;
12068  case SQL_ATTR_CURSOR_TYPE:
12069  *((SQLINTEGER *) val) = d->curtype;
12070  *buflen = sizeof (SQLINTEGER);
12071  break;
12072  case SQL_ATTR_RETRIEVE_DATA:
12073  *((SQLINTEGER *) val) = SQL_RD_ON;
12074  *buflen = sizeof (SQLINTEGER);
12075  break;
12076 #ifdef SQL_ATTR_METADATA_ID
12077  case SQL_ATTR_METADATA_ID:
12078  *((SQLULEN *) val) = SQL_FALSE;
12079  return SQL_SUCCESS;
12080 #endif
12081  default:
12082  *((SQLINTEGER *) val) = 0;
12083  *buflen = sizeof (SQLINTEGER);
12084  setstatd(d, -1, "unsupported connect attribute %d",
12085  (*d->ov3) ? "HYC00" : "S1C00", (int) attr);
12086  return SQL_ERROR;
12087  }
12088  return SQL_SUCCESS;
12089 }
12090 
12091 #ifndef WINTERFACE
12092 
12102 SQLRETURN SQL_API
12103 SQLGetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12104  SQLINTEGER bufmax, SQLINTEGER *buflen)
12105 {
12106  SQLRETURN ret;
12107 
12108  HDBC_LOCK(dbc);
12109  ret = drvgetconnectattr(dbc, attr, val, bufmax, buflen);
12110  HDBC_UNLOCK(dbc);
12111  return ret;
12112 }
12113 #endif
12114 
12115 #ifdef WINTERFACE
12116 
12126 SQLRETURN SQL_API
12127 SQLGetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12128  SQLINTEGER bufmax, SQLINTEGER *buflen)
12129 {
12130  SQLRETURN ret;
12131  SQLINTEGER len = 0;
12132 
12133  HDBC_LOCK(dbc);
12134  ret = drvgetconnectattr(dbc, attr, val, bufmax, &len);
12135  if (ret == SQL_SUCCESS) {
12136  SQLWCHAR *v = NULL;
12137 
12138  switch (attr) {
12139  case SQL_ATTR_TRACEFILE:
12140  case SQL_ATTR_CURRENT_CATALOG:
12141  case SQL_ATTR_TRANSLATE_LIB:
12142  if (val) {
12143  if (len > 0) {
12144  v = uc_from_utf((SQLCHAR *) val, len);
12145  if (v) {
12146  int vmax = bufmax / sizeof (SQLWCHAR);
12147 
12148  uc_strncpy(val, v, vmax);
12149  if (len < vmax) {
12150  len = min(vmax, uc_strlen(v));
12151  v[len] = 0;
12152  } else {
12153  len = vmax;
12154  }
12155  uc_free(v);
12156  len *= sizeof (SQLWCHAR);
12157  } else {
12158  len = 0;
12159  }
12160  }
12161  if (len <= 0) {
12162  len = 0;
12163  if (bufmax >= sizeof (SQLWCHAR)) {
12164  *((SQLWCHAR *)val) = 0;
12165  }
12166  }
12167  } else {
12168  len *= sizeof (SQLWCHAR);
12169  }
12170  break;
12171  }
12172  if (buflen) {
12173  *buflen = len;
12174  }
12175  }
12176  HDBC_UNLOCK(dbc);
12177  return ret;
12178 }
12179 #endif
12180 
12190 static SQLRETURN
12191 drvsetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12192  SQLINTEGER len)
12193 {
12194  DBC *d;
12195 
12196  if (dbc == SQL_NULL_HDBC) {
12197  return SQL_INVALID_HANDLE;
12198  }
12199  d = (DBC *) dbc;
12200  switch (attr) {
12201  case SQL_AUTOCOMMIT:
12202  d->autocommit = val == (SQLPOINTER) SQL_AUTOCOMMIT_ON;
12203  if (d->autocommit && d->intrans) {
12204  return endtran(d, SQL_COMMIT, 1);
12205  } else if (!d->autocommit) {
12206  s3stmt_end(d->cur_s3stmt);
12207  }
12208  break;
12209  return SQL_SUCCESS;
12210 #ifdef SQL_ATTR_METADATA_ID
12211  case SQL_ATTR_METADATA_ID:
12212  if (val == (SQLPOINTER) SQL_FALSE) {
12213  break;
12214  }
12215  /* fall through */
12216 #endif
12217  default:
12218  setstatd(d, -1, "option value changed", "01S02");
12219  return SQL_SUCCESS_WITH_INFO;
12220  }
12221  return SQL_SUCCESS;
12222 }
12223 
12224 #ifndef WINTERFACE
12225 
12234 SQLRETURN SQL_API
12235 SQLSetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12236  SQLINTEGER len)
12237 {
12238  SQLRETURN ret;
12239 
12240  HDBC_LOCK(dbc);
12241  ret = drvsetconnectattr(dbc, attr, val, len);
12242  HDBC_UNLOCK(dbc);
12243  return ret;
12244 }
12245 #endif
12246 
12247 #ifdef WINTERFACE
12248 
12257 SQLRETURN SQL_API
12258 SQLSetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12259  SQLINTEGER len)
12260 {
12261  SQLRETURN ret;
12262 
12263  HDBC_LOCK(dbc);
12264  ret = drvsetconnectattr(dbc, attr, val, len);
12265  HDBC_UNLOCK(dbc);
12266  return ret;
12267 }
12268 #endif
12269 
12278 static SQLRETURN
12279 drvgetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12280 {
12281  DBC *d;
12282  SQLINTEGER dummy;
12283 
12284  if (dbc == SQL_NULL_HDBC) {
12285  return SQL_INVALID_HANDLE;
12286  }
12287  d = (DBC *) dbc;
12288  if (!param) {
12289  param = (SQLPOINTER) &dummy;
12290  }
12291  switch (opt) {
12292  case SQL_ACCESS_MODE:
12293  *((SQLINTEGER *) param) = SQL_MODE_READ_WRITE;
12294  break;
12295  case SQL_AUTOCOMMIT:
12296  *((SQLINTEGER *) param) =
12297  d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
12298  break;
12299  case SQL_LOGIN_TIMEOUT:
12300  *((SQLINTEGER *) param) = 100;
12301  break;
12302  case SQL_ODBC_CURSORS:
12303  *((SQLINTEGER *) param) = SQL_CUR_USE_DRIVER;
12304  break;
12305  case SQL_PACKET_SIZE:
12306  *((SQLINTEGER *) param) = 16384;
12307  break;
12308  case SQL_TXN_ISOLATION:
12309  *((SQLINTEGER *) param) = SQL_TXN_SERIALIZABLE;
12310  break;
12311  case SQL_OPT_TRACE:
12312  case SQL_OPT_TRACEFILE:
12313  case SQL_QUIET_MODE:
12314  case SQL_TRANSLATE_DLL:
12315  case SQL_TRANSLATE_OPTION:
12316  case SQL_KEYSET_SIZE:
12317  case SQL_QUERY_TIMEOUT:
12318  case SQL_BIND_TYPE:
12319  case SQL_CURRENT_QUALIFIER:
12320  *((SQLINTEGER *) param) = 0;
12321  break;
12322  case SQL_USE_BOOKMARKS:
12323  *((SQLINTEGER *) param) = SQL_UB_OFF;
12324  break;
12325  case SQL_ASYNC_ENABLE:
12326  *((SQLINTEGER *) param) = SQL_ASYNC_ENABLE_OFF;
12327  break;
12328  case SQL_NOSCAN:
12329  *((SQLINTEGER *) param) = SQL_NOSCAN_ON;
12330  break;
12331  case SQL_CONCURRENCY:
12332  *((SQLINTEGER *) param) = SQL_CONCUR_LOCK;
12333  break;
12334  case SQL_SIMULATE_CURSOR:
12335  *((SQLINTEGER *) param) = SQL_SC_NON_UNIQUE;
12336  break;
12337  case SQL_MAX_ROWS:
12338  *((SQLINTEGER *) param) = 0;
12339  break;
12340  case SQL_ROWSET_SIZE:
12341  case SQL_MAX_LENGTH:
12342  *((SQLINTEGER *) param) = 1000000000;
12343  break;
12344  case SQL_CURSOR_TYPE:
12345  *((SQLINTEGER *) param) = d->curtype;
12346  break;
12347  case SQL_RETRIEVE_DATA:
12348  *((SQLINTEGER *) param) = SQL_RD_ON;
12349  break;
12350  default:
12351  *((SQLINTEGER *) param) = 0;
12352  setstatd(d, -1, "unsupported connect option %d",
12353  (*d->ov3) ? "HYC00" : "S1C00", opt);
12354  return SQL_ERROR;
12355  }
12356  return SQL_SUCCESS;
12357 }
12358 
12359 #ifndef WINTERFACE
12360 
12368 SQLRETURN SQL_API
12369 SQLGetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12370 {
12371  SQLRETURN ret;
12372 
12373  HDBC_LOCK(dbc);
12374  ret = drvgetconnectoption(dbc, opt, param);
12375  HDBC_UNLOCK(dbc);
12376  return ret;
12377 }
12378 #endif
12379 
12380 #ifdef WINTERFACE
12381 
12389 SQLRETURN SQL_API
12390 SQLGetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12391 {
12392  SQLRETURN ret;
12393 
12394  HDBC_LOCK(dbc);
12395  ret = drvgetconnectoption(dbc, opt, param);
12396  if (SQL_SUCCEEDED(ret)) {
12397  switch (opt) {
12398  case SQL_OPT_TRACEFILE:
12399  case SQL_CURRENT_QUALIFIER:
12400  case SQL_TRANSLATE_DLL:
12401  if (param) {
12402  *(SQLWCHAR *) param = 0;
12403  }
12404  break;
12405  }
12406  }
12407  HDBC_UNLOCK(dbc);
12408  return ret;
12409 }
12410 #endif
12411 
12420 static SQLRETURN
12421 drvsetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
12422 {
12423  DBC *d;
12424 
12425  if (dbc == SQL_NULL_HDBC) {
12426  return SQL_INVALID_HANDLE;
12427  }
12428  d = (DBC *) dbc;
12429  switch (opt) {
12430  case SQL_AUTOCOMMIT:
12431  d->autocommit = param == SQL_AUTOCOMMIT_ON;
12432  if (d->autocommit && d->intrans) {
12433  return endtran(d, SQL_COMMIT, 1);
12434  } else if (!d->autocommit) {
12435  s3stmt_end(d->cur_s3stmt);
12436  }
12437  break;
12438  default:
12439  setstatd(d, -1, "option value changed", "01S02");
12440  return SQL_SUCCESS_WITH_INFO;
12441  }
12442  return SQL_SUCCESS;
12443 }
12444 
12445 #ifndef WINTERFACE
12446 
12454 SQLRETURN SQL_API
12455 SQLSetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12456 {
12457  SQLRETURN ret;
12458 
12459  HDBC_LOCK(dbc);
12460  ret = drvsetconnectoption(dbc, opt, param);
12461  HDBC_UNLOCK(dbc);
12462  return ret;
12463 }
12464 #endif
12465 
12466 #ifdef WINTERFACE
12467 
12475 SQLRETURN SQL_API
12476 SQLSetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12477 {
12478  SQLRETURN ret;
12479 
12480  HDBC_LOCK(dbc);
12481  ret = drvsetconnectoption(dbc, opt, param);
12482  HDBC_UNLOCK(dbc);
12483  return ret;
12484 }
12485 #endif
12486 
12487 #if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
12488 
12499 static int
12500 getdsnattr(char *dsn, char *attr, char *out, int outLen)
12501 {
12502  char *str = dsn, *start;
12503  int len = strlen(attr);
12504 
12505  while (*str) {
12506  while (*str && *str == ';') {
12507  ++str;
12508  }
12509  start = str;
12510  if ((str = strchr(str, '=')) == NULL) {
12511  return 0;
12512  }
12513  if (str - start == len && strncasecmp(start, attr, len) == 0) {
12514  start = ++str;
12515  while (*str && *str != ';') {
12516  ++str;
12517  }
12518  len = min(outLen - 1, str - start);
12519  strncpy(out, start, len);
12520  out[len] = '\0';
12521  return 1;
12522  }
12523  while (*str && *str != ';') {
12524  ++str;
12525  }
12526  }
12527  return 0;
12528 }
12529 #endif
12530 
12542 static SQLRETURN
12543 drvconnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen, char *pwd,
12544  int pwdLen, int isu)
12545 {
12546  DBC *d;
12547  int len;
12548  SQLRETURN ret;
12549  char buf[SQL_MAX_MESSAGE_LENGTH], dbname[SQL_MAX_MESSAGE_LENGTH / 4];
12550  char busy[SQL_MAX_MESSAGE_LENGTH / 4], tracef[SQL_MAX_MESSAGE_LENGTH];
12551  char loadext[SQL_MAX_MESSAGE_LENGTH];
12552  char sflag[32], spflag[32], ntflag[32], nwflag[32], biflag[32];
12553  char snflag[32], lnflag[32], ncflag[32], fkflag[32], jmode[32];
12554  char jdflag[32];
12555 #if defined(_WIN32) || defined(_WIN64)
12556  char oemcp[32];
12557 #endif
12558 
12559  if (dbc == SQL_NULL_HDBC) {
12560  return SQL_INVALID_HANDLE;
12561  }
12562  d = (DBC *) dbc;
12563  if (d->magic != DBC_MAGIC) {
12564  return SQL_INVALID_HANDLE;
12565  }
12566  if (d->sqlite != NULL) {
12567  setstatd(d, -1, "connection already established", "08002");
12568  return SQL_ERROR;
12569  }
12570  buf[0] = '\0';
12571  if (dsnLen == SQL_NTS) {
12572  len = sizeof (buf) - 1;
12573  } else {
12574  len = min(sizeof (buf) - 1, dsnLen);
12575  }
12576  if (dsn != NULL) {
12577  strncpy(buf, (char *) dsn, len);
12578  }
12579  buf[len] = '\0';
12580  if (buf[0] == '\0') {
12581  setstatd(d, -1, "invalid DSN", (*d->ov3) ? "HY090" : "S1090");
12582  return SQL_ERROR;
12583  }
12584 #if defined(_WIN32) || defined(_WIN64)
12585  /*
12586  * When DSN is in UTF it must be converted to ANSI
12587  * here for ANSI SQLGetPrivateProfileString()
12588  */
12589  if (isu) {
12590  char *cdsn = utf_to_wmb(buf, len);
12591 
12592  if (!cdsn) {
12593  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12594  return SQL_ERROR;
12595  }
12596  strcpy(buf, cdsn);
12597  uc_free(cdsn);
12598  }
12599 #endif
12600  busy[0] = '\0';
12601  dbname[0] = '\0';
12602 #ifdef WITHOUT_DRIVERMGR
12603  getdsnattr(buf, "database", dbname, sizeof (dbname));
12604  if (dbname[0] == '\0') {
12605  strncpy(dbname, buf, sizeof (dbname));
12606  dbname[sizeof (dbname) - 1] = '\0';
12607  }
12608  getdsnattr(buf, "timeout", busy, sizeof (busy));
12609  sflag[0] = '\0';
12610  getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
12611  spflag[0] = '\0';
12612  getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
12613  ntflag[0] = '\0';
12614  getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
12615  nwflag[0] = '\0';
12616  getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
12617  snflag[0] = '\0';
12618  getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
12619  lnflag[0] = '\0';
12620  getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
12621  ncflag[0] = '\0';
12622  getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
12623  fkflag[0] = '\0';
12624  getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
12625  loadext[0] = '\0';
12626  getdsnattr(buf, "loadext", loadext, sizeof (loadext));
12627  jmode[0] = '\0';
12628  getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
12629  jdflag[0] = '\0';
12630  getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
12631 #if defined(_WIN32) || defined(_WIN64)
12632  oemcp[0] = '\0';
12633  getdsnattr(buf, "oemcp", oemcp, sizeof (oemcp));
12634 #endif
12635  biflag[0] = '\0';
12636  getdsnattr(buf, "bigint", biflag, sizeof (biflag));
12637 #else
12638  SQLGetPrivateProfileString(buf, "timeout", "100000",
12639  busy, sizeof (busy), ODBC_INI);
12640  SQLGetPrivateProfileString(buf, "database", "",
12641  dbname, sizeof (dbname), ODBC_INI);
12642 #if defined(_WIN32) || defined(_WIN64)
12643  /* database name read from registry is not UTF8 !!! */
12644  isu = 0;
12645 #endif
12646  SQLGetPrivateProfileString(buf, "stepapi", "",
12647  sflag, sizeof (sflag), ODBC_INI);
12648  SQLGetPrivateProfileString(buf, "syncpragma", "NORMAL",
12649  spflag, sizeof (spflag), ODBC_INI);
12650  SQLGetPrivateProfileString(buf, "notxn", "",
12651  ntflag, sizeof (ntflag), ODBC_INI);
12652  SQLGetPrivateProfileString(buf, "nowchar", "",
12653  nwflag, sizeof (nwflag), ODBC_INI);
12654  SQLGetPrivateProfileString(buf, "shortnames", "",
12655  snflag, sizeof (snflag), ODBC_INI);
12656  SQLGetPrivateProfileString(buf, "longnames", "",
12657  lnflag, sizeof (lnflag), ODBC_INI);
12658  SQLGetPrivateProfileString(buf, "nocreat", "",
12659  ncflag, sizeof (ncflag), ODBC_INI);
12660  SQLGetPrivateProfileString(buf, "fksupport", "",
12661  fkflag, sizeof (fkflag), ODBC_INI);
12662  SQLGetPrivateProfileString(buf, "loadext", "",
12663  loadext, sizeof (loadext), ODBC_INI);
12664  SQLGetPrivateProfileString(buf, "journalmode", "",
12665  jmode, sizeof (jmode), ODBC_INI);
12666  SQLGetPrivateProfileString(buf, "jdconv", "",
12667  jdflag, sizeof (jdflag), ODBC_INI);
12668 #if defined(_WIN32) || defined(_WIN64)
12669  SQLGetPrivateProfileString(buf, "oemcp", "1",
12670  oemcp, sizeof (oemcp), ODBC_INI);
12671 #endif
12672  SQLGetPrivateProfileString(buf, "bigint", "",
12673  biflag, sizeof (biflag), ODBC_INI);
12674 #endif
12675  tracef[0] = '\0';
12676 #ifdef WITHOUT_DRIVERMGR
12677  getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
12678 #else
12679  SQLGetPrivateProfileString(buf, "tracefile", "",
12680  tracef, sizeof (tracef), ODBC_INI);
12681 #endif
12682  if (tracef[0] != '\0') {
12683  d->trace = fopen(tracef, "a");
12684  }
12685  d->nowchar = getbool(nwflag);
12686  d->shortnames = getbool(snflag);
12687  d->longnames = getbool(lnflag);
12688  d->nocreat = getbool(ncflag);
12689  d->fksupport = getbool(fkflag);
12690  d->jdconv = getbool(jdflag);
12691 #if defined(_WIN32) || defined(_WIN64)
12692  d->oemcp = getbool(oemcp);
12693 #else
12694  d->oemcp = 0;
12695 #endif
12696  d->dobigint = getbool(biflag);
12697  d->pwd = pwd;
12698  d->pwdLen = 0;
12699  if (d->pwd) {
12700  d->pwdLen = (pwdLen == SQL_NTS) ? strlen(d->pwd) : pwdLen;
12701  }
12702  ret = dbopen(d, dbname, isu, (char *) dsn, sflag, spflag, ntflag,
12703  jmode, busy);
12704  if (ret == SQL_SUCCESS) {
12705  dbloadext(d, loadext);
12706  }
12707  return ret;
12708 }
12709 
12710 #ifndef WINTERFACE
12711 
12723 SQLRETURN SQL_API
12724 SQLConnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen,
12725  SQLCHAR *uid, SQLSMALLINT uidLen,
12726  SQLCHAR *pwd, SQLSMALLINT pwdLen)
12727 {
12728  SQLRETURN ret;
12729 
12730  HDBC_LOCK(dbc);
12731  ret = drvconnect(dbc, dsn, dsnLen, (char *) pwd, pwdLen, 0);
12732  HDBC_UNLOCK(dbc);
12733  return ret;
12734 }
12735 #endif
12736 
12737 #ifdef WINTERFACE
12738 
12750 SQLRETURN SQL_API
12751 SQLConnectW(SQLHDBC dbc, SQLWCHAR *dsn, SQLSMALLINT dsnLen,
12752  SQLWCHAR *uid, SQLSMALLINT uidLen,
12753  SQLWCHAR *pwd, SQLSMALLINT pwdLen)
12754 {
12755  char *dsna = NULL;
12756  char *pwda = NULL;
12757  SQLRETURN ret;
12758 
12759  HDBC_LOCK(dbc);
12760  if (dsn) {
12761  dsna = uc_to_utf_c(dsn, dsnLen);
12762  if (!dsna) {
12763  DBC *d = (DBC *) dbc;
12764 
12765  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12766  ret = SQL_ERROR;
12767  goto done;
12768  }
12769  }
12770  if (pwd) {
12771  pwda = uc_to_utf_c(pwd, pwdLen);
12772  if (!pwda) {
12773  DBC *d = (DBC *) dbc;
12774 
12775  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12776  ret = SQL_ERROR;
12777  goto done;
12778  }
12779  }
12780  ret = drvconnect(dbc, (SQLCHAR *) dsna, SQL_NTS, pwda, SQL_NTS, 1);
12781 done:
12782  HDBC_UNLOCK(dbc);
12783  uc_free(dsna);
12784  uc_free(pwda);
12785  return ret;
12786 }
12787 #endif
12788 
12795 static SQLRETURN
12796 drvdisconnect(SQLHDBC dbc)
12797 {
12798  DBC *d;
12799  int rc;
12800 
12801  if (dbc == SQL_NULL_HDBC) {
12802  return SQL_INVALID_HANDLE;
12803  }
12804  d = (DBC *) dbc;
12805  if (d->magic != DBC_MAGIC) {
12806  return SQL_INVALID_HANDLE;
12807  }
12808  if (d->intrans) {
12809  setstatd(d, -1, "incomplete transaction", "25000");
12810  return SQL_ERROR;
12811  }
12812  if (d->cur_s3stmt) {
12813  s3stmt_end(d->cur_s3stmt);
12814  }
12815  if (d->sqlite) {
12816  if (d->trace) {
12817  fprintf(d->trace, "-- sqlite3_close: '%s'\n",
12818  d->dbname);
12819  fflush(d->trace);
12820  }
12821  rc = sqlite3_close(d->sqlite);
12822  if (rc == SQLITE_BUSY) {
12823  setstatd(d, -1, "unfinished statements", "25000");
12824  return SQL_ERROR;
12825  }
12826  d->sqlite = NULL;
12827  }
12828  freep(&d->dbname);
12829  freep(&d->dsn);
12830  return SQL_SUCCESS;
12831 }
12832 
12839 SQLRETURN SQL_API
12840 SQLDisconnect(SQLHDBC dbc)
12841 {
12842  SQLRETURN ret;
12843 
12844  HDBC_LOCK(dbc);
12845  ret = drvdisconnect(dbc);
12846  HDBC_UNLOCK(dbc);
12847  return ret;
12848 }
12849 
12850 #if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
12851 
12865 static SQLRETURN
12866 drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
12867  SQLCHAR *connIn, SQLSMALLINT connInLen,
12868  SQLCHAR *connOut, SQLSMALLINT connOutMax,
12869  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
12870 {
12871  DBC *d;
12872  int len;
12873  SQLRETURN ret;
12874  char buf[SQL_MAX_MESSAGE_LENGTH * 6], dbname[SQL_MAX_MESSAGE_LENGTH];
12875  char dsn[SQL_MAX_MESSAGE_LENGTH / 4], busy[SQL_MAX_MESSAGE_LENGTH / 4];
12876  char tracef[SQL_MAX_MESSAGE_LENGTH], loadext[SQL_MAX_MESSAGE_LENGTH];
12877  char pwd[SQL_MAX_MESSAGE_LENGTH];
12878  char sflag[32], spflag[32], ntflag[32], snflag[32], lnflag[32];
12879  char ncflag[32], nwflag[32], fkflag[32], jmode[32], biflag[32];
12880  char jdflag[32];
12881 
12882  if (dbc == SQL_NULL_HDBC) {
12883  return SQL_INVALID_HANDLE;
12884  }
12885  if (drvcompl != SQL_DRIVER_COMPLETE &&
12886  drvcompl != SQL_DRIVER_COMPLETE_REQUIRED &&
12887  drvcompl != SQL_DRIVER_PROMPT &&
12888  drvcompl != SQL_DRIVER_NOPROMPT) {
12889  return SQL_NO_DATA;
12890  }
12891  d = (DBC *) dbc;
12892  if (d->sqlite) {
12893  setstatd(d, -1, "connection already established", "08002");
12894  return SQL_ERROR;
12895  }
12896  buf[0] = '\0';
12897  if (connInLen == SQL_NTS) {
12898  len = sizeof (buf) - 1;
12899  } else {
12900  len = min(connInLen, sizeof (buf) - 1);
12901  }
12902  if (connIn != NULL) {
12903  strncpy(buf, (char *) connIn, len);
12904  }
12905  buf[len] = '\0';
12906  if (!buf[0]) {
12907  setstatd(d, -1, "invalid connect attributes",
12908  (*d->ov3) ? "HY090" : "S1090");
12909  return SQL_ERROR;
12910  }
12911  dsn[0] = '\0';
12912  getdsnattr(buf, "DSN", dsn, sizeof (dsn));
12913 
12914  /* special case: connIn is sole DSN value without keywords */
12915  if (!dsn[0] && !strchr(buf, ';') && !strchr(buf, '=')) {
12916  strncpy(dsn, buf, sizeof (dsn) - 1);
12917  dsn[sizeof (dsn) - 1] = '\0';
12918  }
12919 
12920  busy[0] = '\0';
12921  getdsnattr(buf, "timeout", busy, sizeof (busy));
12922 #ifndef WITHOUT_DRIVERMGR
12923  if (dsn[0] && !busy[0]) {
12924  SQLGetPrivateProfileString(dsn, "timeout", "100000",
12925  busy, sizeof (busy), ODBC_INI);
12926  }
12927 #endif
12928  dbname[0] = '\0';
12929  getdsnattr(buf, "database", dbname, sizeof (dbname));
12930 #ifndef WITHOUT_DRIVERMGR
12931  if (dsn[0] && !dbname[0]) {
12932  SQLGetPrivateProfileString(dsn, "database", "",
12933  dbname, sizeof (dbname), ODBC_INI);
12934  }
12935 #endif
12936  sflag[0] = '\0';
12937  getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
12938 #ifndef WITHOUT_DRIVERMGR
12939  if (dsn[0] && !sflag[0]) {
12940  SQLGetPrivateProfileString(dsn, "stepapi", "",
12941  sflag, sizeof (sflag), ODBC_INI);
12942  }
12943 #endif
12944  spflag[0] = '\0';
12945  getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
12946 #ifndef WITHOUT_DRIVERMGR
12947  if (dsn[0] && !spflag[0]) {
12948  SQLGetPrivateProfileString(dsn, "syncpragma", "NORMAL",
12949  spflag, sizeof (spflag), ODBC_INI);
12950  }
12951 #endif
12952  ntflag[0] = '\0';
12953  getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
12954 #ifndef WITHOUT_DRIVERMGR
12955  if (dsn[0] && !ntflag[0]) {
12956  SQLGetPrivateProfileString(dsn, "notxn", "",
12957  ntflag, sizeof (ntflag), ODBC_INI);
12958  }
12959 #endif
12960  snflag[0] = '\0';
12961  getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
12962 #ifndef WITHOUT_DRIVERMGR
12963  if (dsn[0] && !snflag[0]) {
12964  SQLGetPrivateProfileString(dsn, "shortnames", "",
12965  snflag, sizeof (snflag), ODBC_INI);
12966  }
12967 #endif
12968  lnflag[0] = '\0';
12969  getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
12970 #ifndef WITHOUT_DRIVERMGR
12971  if (dsn[0] && !lnflag[0]) {
12972  SQLGetPrivateProfileString(dsn, "longnames", "",
12973  lnflag, sizeof (lnflag), ODBC_INI);
12974  }
12975 #endif
12976  ncflag[0] = '\0';
12977  getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
12978 #ifndef WITHOUT_DRIVERMGR
12979  if (dsn[0] && !ncflag[0]) {
12980  SQLGetPrivateProfileString(dsn, "nocreat", "",
12981  ncflag, sizeof (ncflag), ODBC_INI);
12982  }
12983 #endif
12984  nwflag[0] = '\0';
12985  getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
12986 #ifndef WITHOUT_DRIVERMGR
12987  if (dsn[0] && !nwflag[0]) {
12988  SQLGetPrivateProfileString(dsn, "nowchar", "",
12989  nwflag, sizeof (nwflag), ODBC_INI);
12990  }
12991 #endif
12992  fkflag[0] = '\0';
12993  getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
12994 #ifndef WITHOUT_DRIVERMGR
12995  if (dsn[0] && !fkflag[0]) {
12996  SQLGetPrivateProfileString(dsn, "fksupport", "",
12997  fkflag, sizeof (fkflag), ODBC_INI);
12998  }
12999 #endif
13000  loadext[0] = '\0';
13001  getdsnattr(buf, "loadext", loadext, sizeof (loadext));
13002 #ifndef WITHOUT_DRIVERMGR
13003  if (dsn[0] && !loadext[0]) {
13004  SQLGetPrivateProfileString(dsn, "loadext", "",
13005  loadext, sizeof (loadext), ODBC_INI);
13006  }
13007 #endif
13008  jmode[0] = '\0';
13009  getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
13010 #ifndef WITHOUT_DRIVERMGR
13011  if (dsn[0] && !jmode[0]) {
13012  SQLGetPrivateProfileString(dsn, "journalmode", "",
13013  jmode, sizeof (jmode), ODBC_INI);
13014  }
13015 #endif
13016  biflag[0] = '\0';
13017  getdsnattr(buf, "bigint", biflag, sizeof (biflag));
13018 #ifndef WITHOUT_DRIVERMGR
13019  if (dsn[0] && !biflag[0]) {
13020  SQLGetPrivateProfileString(dsn, "bigint", "",
13021  biflag, sizeof (biflag), ODBC_INI);
13022  }
13023 #endif
13024  jdflag[0] = '\0';
13025  getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
13026 #ifndef WITHOUT_DRIVERMGR
13027  if (dsn[0] && !jdflag[0]) {
13028  SQLGetPrivateProfileString(dsn, "jdconv", "",
13029  jdflag, sizeof (jdflag), ODBC_INI);
13030  }
13031 #endif
13032  pwd[0] = '\0';
13033  getdsnattr(buf, "pwd", pwd, sizeof (pwd));
13034 #ifndef WITHOUT_DRIVERMGR
13035  if (dsn[0] && !pwd[0]) {
13036  SQLGetPrivateProfileString(dsn, "pwd", "",
13037  pwd, sizeof (pwd), ODBC_INI);
13038  }
13039 #endif
13040 
13041  if (!dbname[0] && !dsn[0]) {
13042  strcpy(dsn, "SQLite");
13043  strncpy(dbname, buf, sizeof (dbname));
13044  dbname[sizeof (dbname) - 1] = '\0';
13045  }
13046  tracef[0] = '\0';
13047  getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
13048 #ifndef WITHOUT_DRIVERMGR
13049  if (dsn[0] && !tracef[0]) {
13050  SQLGetPrivateProfileString(dsn, "tracefile", "",
13051  tracef, sizeof (tracef), ODBC_INI);
13052  }
13053 #endif
13054  if (connOut || connOutLen) {
13055  int count;
13056 
13057  buf[0] = '\0';
13058  count = snprintf(buf, sizeof (buf),
13059  "DSN=%s;Database=%s;StepAPI=%s;Timeout=%s;"
13060  "SyncPragma=%s;NoTXN=%s;ShortNames=%s;LongNames=%s;"
13061  "NoCreat=%s;NoWCHAR=%s;FKSupport=%s;Tracefile=%s;"
13062  "JournalMode=%s;LoadExt=%s;BigInt=%s;JDConv=%s;"
13063  "PWD=%s",
13064  dsn, dbname, sflag, busy, spflag, ntflag,
13065  snflag, lnflag, ncflag, nwflag, fkflag, tracef,
13066  jmode, loadext, biflag, jdflag, pwd);
13067  if (count < 0) {
13068  buf[sizeof (buf) - 1] = '\0';
13069  }
13070  len = min(connOutMax - 1, strlen(buf));
13071  if (connOut) {
13072  strncpy((char *) connOut, buf, len);
13073  connOut[len] = '\0';
13074  }
13075  if (connOutLen) {
13076  *connOutLen = len;
13077  }
13078  }
13079  if (tracef[0] != '\0') {
13080  d->trace = fopen(tracef, "a");
13081  }
13082  d->shortnames = getbool(snflag);
13083  d->longnames = getbool(lnflag);
13084  d->nocreat = getbool(ncflag);
13085  d->nowchar = getbool(nwflag);
13086  d->fksupport = getbool(fkflag);
13087  d->dobigint = getbool(biflag);
13088  d->jdconv = getbool(jdflag);
13089  d->oemcp = 0;
13090  d->pwdLen = strlen(pwd);
13091  d->pwd = (d->pwdLen > 0) ? pwd : NULL;
13092  ret = dbopen(d, dbname, 0, dsn, sflag, spflag, ntflag, jmode, busy);
13093  memset(pwd, 0, sizeof (pwd));
13094  if (ret == SQL_SUCCESS) {
13095  dbloadext(d, loadext);
13096  }
13097  return ret;
13098 }
13099 #endif
13100 
13107 static SQLRETURN
13108 freestmt(SQLHSTMT stmt)
13109 {
13110  STMT *s;
13111  DBC *d;
13112 
13113  if (stmt == SQL_NULL_HSTMT) {
13114  return SQL_INVALID_HANDLE;
13115  }
13116  s = (STMT *) stmt;
13117  s3stmt_drop(s);
13118  freeresult(s, 1);
13119  freep(&s->query);
13120  d = (DBC *) s->dbc;
13121  if (d && d->magic == DBC_MAGIC) {
13122  STMT *p, *n;
13123 
13124  p = NULL;
13125  n = d->stmt;
13126  while (n) {
13127  if (n == s) {
13128  break;
13129  }
13130  p = n;
13131  n = n->next;
13132  }
13133  if (n) {
13134  if (p) {
13135  p->next = s->next;
13136  } else {
13137  d->stmt = s->next;
13138  }
13139  }
13140  }
13141  freeparams(s);
13142  freep(&s->bindparms);
13143  if (s->row_status0 != &s->row_status1) {
13144  freep(&s->row_status0);
13145  s->rowset_size = 1;
13146  s->row_status0 = &s->row_status1;
13147  }
13148  xfree(s);
13149  return SQL_SUCCESS;
13150 }
13151 
13159 static SQLRETURN
13160 drvallocstmt(SQLHDBC dbc, SQLHSTMT *stmt)
13161 {
13162  DBC *d;
13163  STMT *s, *sl, *pl;
13164 
13165  if (dbc == SQL_NULL_HDBC) {
13166  return SQL_INVALID_HANDLE;
13167  }
13168  d = (DBC *) dbc;
13169  if (d->magic != DBC_MAGIC || stmt == NULL) {
13170  return SQL_INVALID_HANDLE;
13171  }
13172  s = (STMT *) xmalloc(sizeof (STMT));
13173  if (s == NULL) {
13174  *stmt = SQL_NULL_HSTMT;
13175  return SQL_ERROR;
13176  }
13177  *stmt = (SQLHSTMT) s;
13178  memset(s, 0, sizeof (STMT));
13179  s->dbc = dbc;
13180  s->ov3 = d->ov3;
13181  s->bkmrk = SQL_UB_OFF;
13182  s->bkmrkptr = 0;
13183  s->oemcp = &d->oemcp;
13184  s->jdconv = &d->jdconv;
13185  s->nowchar[0] = d->nowchar;
13186  s->nowchar[1] = 0;
13187  s->dobigint = d->dobigint;
13188  s->curtype = d->curtype;
13189  s->row_status0 = &s->row_status1;
13190  s->rowset_size = 1;
13191  s->longnames = d->longnames;
13192  s->retr_data = SQL_RD_ON;
13193  s->max_rows = 0;
13194  s->bind_type = SQL_BIND_BY_COLUMN;
13195  s->bind_offs = NULL;
13196  s->paramset_size = 1;
13197  s->parm_bind_type = SQL_PARAM_BIND_BY_COLUMN;
13198  s->one_tbl = -1;
13199  s->has_pk = -1;
13200  s->has_rowid = -1;
13201 #ifdef _WIN64
13202  sprintf((char *) s->cursorname, "CUR_%I64X", (SQLUBIGINT) *stmt);
13203 #else
13204  sprintf((char *) s->cursorname, "CUR_%016lX", (long) *stmt);
13205 #endif
13206  sl = d->stmt;
13207  pl = NULL;
13208  while (sl) {
13209  pl = sl;
13210  sl = sl->next;
13211  }
13212  if (pl) {
13213  pl->next = s;
13214  } else {
13215  d->stmt = s;
13216  }
13217  return SQL_SUCCESS;
13218 }
13219 
13227 SQLRETURN SQL_API
13228 SQLAllocStmt(SQLHDBC dbc, SQLHSTMT *stmt)
13229 {
13230  SQLRETURN ret;
13231 
13232  HDBC_LOCK(dbc);
13233  ret = drvallocstmt(dbc, stmt);
13234  HDBC_UNLOCK(dbc);
13235  return ret;
13236 }
13237 
13245 static SQLRETURN
13246 drvfreestmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13247 {
13248  STMT *s;
13249  SQLRETURN ret = SQL_SUCCESS;
13250  SQLHDBC dbc;
13251 
13252  if (stmt == SQL_NULL_HSTMT) {
13253  return SQL_INVALID_HANDLE;
13254  }
13255  HSTMT_LOCK(stmt);
13256  s = (STMT *) stmt;
13257  dbc = s->dbc;
13258  switch (opt) {
13259  case SQL_RESET_PARAMS:
13260  freeparams(s);
13261  break;
13262  case SQL_UNBIND:
13263  unbindcols(s);
13264  break;
13265  case SQL_CLOSE:
13266  s3stmt_end_if(s);
13267  freeresult(s, 0);
13268  break;
13269  case SQL_DROP:
13270  s3stmt_end_if(s);
13271  ret = freestmt(stmt);
13272  break;
13273  default:
13274  setstat(s, -1, "unsupported option", (*s->ov3) ? "HYC00" : "S1C00");
13275  ret = SQL_ERROR;
13276  break;
13277  }
13278  HDBC_UNLOCK(dbc);
13279  return ret;
13280 }
13281 
13289 SQLRETURN SQL_API
13290 SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13291 {
13292  return drvfreestmt(stmt, opt);
13293 }
13294 
13301 SQLRETURN SQL_API
13302 SQLCancel(SQLHSTMT stmt)
13303 {
13304  if (stmt != SQL_NULL_HSTMT) {
13305  DBC *d = (DBC *) ((STMT *) stmt)->dbc;
13306 #if defined(_WIN32) || defined(_WIN64)
13307  /* interrupt when other thread owns critical section */
13308  if (d->magic == DBC_MAGIC && d->owner != GetCurrentThreadId() &&
13309  d->owner != 0) {
13310  d->busyint = 1;
13311  sqlite3_interrupt(d->sqlite);
13312  return SQL_SUCCESS;
13313  }
13314 #else
13315  if (d->magic == DBC_MAGIC) {
13316  d->busyint = 1;
13317  sqlite3_interrupt(d->sqlite);
13318  }
13319 #endif
13320  }
13321  return drvfreestmt(stmt, SQL_CLOSE);
13322 }
13323 
13333 static SQLRETURN
13334 drvgetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13335  SQLSMALLINT *lenp)
13336 {
13337  STMT *s;
13338 
13339  if (stmt == SQL_NULL_HSTMT) {
13340  return SQL_INVALID_HANDLE;
13341  }
13342  s = (STMT *) stmt;
13343  if (lenp && !cursor) {
13344  *lenp = strlen((char *) s->cursorname);
13345  return SQL_SUCCESS;
13346  }
13347  if (cursor) {
13348  if (buflen > 0) {
13349  strncpy((char *) cursor, (char *) s->cursorname, buflen - 1);
13350  cursor[buflen - 1] = '\0';
13351  }
13352  if (lenp) {
13353  *lenp = min(strlen((char *) s->cursorname), buflen - 1);
13354  }
13355  }
13356  return SQL_SUCCESS;
13357 }
13358 
13359 #ifndef WINTERFACE
13360 
13369 SQLRETURN SQL_API
13370 SQLGetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13371  SQLSMALLINT *lenp)
13372 {
13373  SQLRETURN ret;
13374 #if defined(_WIN32) || defined(_WIN64)
13375  SQLSMALLINT len = 0;
13376 #endif
13377 
13378  HSTMT_LOCK(stmt);
13379 #if defined(_WIN32) || defined(_WIN64)
13380  if (!((STMT *) stmt)->oemcp[0]) {
13381  ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13382  goto done;
13383  }
13384  ret = drvgetcursorname(stmt, cursor, buflen, &len);
13385  if (ret == SQL_SUCCESS) {
13386  char *c = NULL;
13387 
13388  if (cursor) {
13389  c = utf_to_wmb((char *) cursor, len);
13390  if (!c) {
13391  ret = nomem((STMT *) stmt);
13392  goto done;
13393  }
13394  c[len] = 0;
13395  len = strlen(c);
13396  if (buflen > 0) {
13397  strncpy((char *) cursor, c, buflen - 1);
13398  cursor[buflen - 1] = 0;
13399  }
13400  uc_free(c);
13401  }
13402  if (lenp) {
13403  *lenp = min(len, buflen - 1);
13404  }
13405  }
13406 done:
13407  ;
13408 #else
13409  ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13410 #endif
13411  HSTMT_UNLOCK(stmt);
13412  return ret;
13413 }
13414 #endif
13415 
13416 #ifdef WINTERFACE
13417 
13426 SQLRETURN SQL_API
13427 SQLGetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT buflen,
13428  SQLSMALLINT *lenp)
13429 {
13430  SQLRETURN ret;
13431  SQLSMALLINT len = 0;
13432 
13433  HSTMT_LOCK(stmt);
13434  ret = drvgetcursorname(stmt, (SQLCHAR *) cursor, buflen, &len);
13435  if (ret == SQL_SUCCESS) {
13436  SQLWCHAR *c = NULL;
13437 
13438  if (cursor) {
13439  c = uc_from_utf((SQLCHAR *) cursor, len);
13440  if (!c) {
13441  ret = nomem((STMT *) stmt);
13442  goto done;
13443  }
13444  c[len] = 0;
13445  len = uc_strlen(c);
13446  if (buflen > 0) {
13447  uc_strncpy(cursor, c, buflen - 1);
13448  cursor[buflen - 1] = 0;
13449  }
13450  uc_free(c);
13451  }
13452  if (lenp) {
13453  *lenp = min(len, buflen - 1);
13454  }
13455  }
13456 done:
13457  HSTMT_UNLOCK(stmt);
13458  return ret;
13459 }
13460 #endif
13461 
13470 static SQLRETURN
13471 drvsetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13472 {
13473  STMT *s;
13474 
13475  if (stmt == SQL_NULL_HSTMT) {
13476  return SQL_INVALID_HANDLE;
13477  }
13478  s = (STMT *) stmt;
13479  if (!cursor ||
13480  !((cursor[0] >= 'A' && cursor[0] <= 'Z') ||
13481  (cursor[0] >= 'a' && cursor[0] <= 'z'))) {
13482  setstat(s, -1, "invalid cursor name", (*s->ov3) ? "HYC00" : "S1C00");
13483  return SQL_ERROR;
13484  }
13485  if (len == SQL_NTS) {
13486  len = sizeof (s->cursorname) - 1;
13487  } else {
13488  len = min(sizeof (s->cursorname) - 1, len);
13489  }
13490  strncpy((char *) s->cursorname, (char *) cursor, len);
13491  s->cursorname[len] = '\0';
13492  return SQL_SUCCESS;
13493 }
13494 
13495 #ifndef WINTERFACE
13496 
13504 SQLRETURN SQL_API
13505 SQLSetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13506 {
13507 #if defined(_WIN32) || defined(_WIN64)
13508  char *c = NULL;
13509 #endif
13510  SQLRETURN ret;
13511 
13512  HSTMT_LOCK(stmt);
13513 #if defined(_WIN32) || defined(_WIN64)
13514  if (!((STMT *) stmt)->oemcp[0]) {
13515  ret = drvsetcursorname(stmt, cursor, len);
13516  goto done2;
13517  }
13518  if (cursor) {
13519  c = wmb_to_utf_c((char *) cursor, len);
13520  if (!c) {
13521  ret = nomem((STMT *) stmt);
13522  goto done;
13523  }
13524  }
13525  ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13526 #else
13527  ret = drvsetcursorname(stmt, cursor, len);
13528 #endif
13529 #if defined(_WIN32) || defined(_WIN64)
13530 done:
13531  uc_free(c);
13532 done2:
13533  ;
13534 #endif
13535  HSTMT_UNLOCK(stmt);
13536  return ret;
13537 }
13538 #endif
13539 
13540 #ifdef WINTERFACE
13541 
13549 SQLRETURN SQL_API
13550 SQLSetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT len)
13551 {
13552  char *c = NULL;
13553  SQLRETURN ret;
13554 
13555  HSTMT_LOCK(stmt);
13556  if (cursor) {
13557  c = uc_to_utf_c(cursor, len);
13558  if (!c) {
13559  ret = nomem((STMT *) stmt);
13560  goto done;
13561  }
13562  }
13563  ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13564 done:
13565  uc_free(c);
13566  HSTMT_UNLOCK(stmt);
13567  return ret;
13568 }
13569 #endif
13570 
13577 SQLRETURN SQL_API
13578 SQLCloseCursor(SQLHSTMT stmt)
13579 {
13580  return drvfreestmt(stmt, SQL_CLOSE);
13581 }
13582 
13591 SQLRETURN SQL_API
13592 SQLAllocHandle(SQLSMALLINT type, SQLHANDLE input, SQLHANDLE *output)
13593 {
13594  SQLRETURN ret;
13595 
13596  switch (type) {
13597  case SQL_HANDLE_ENV:
13598  ret = drvallocenv((SQLHENV *) output);
13599  if (ret == SQL_SUCCESS) {
13600  ENV *e = (ENV *) *output;
13601 
13602  if (e && e->magic == ENV_MAGIC) {
13603  e->ov3 = 1;
13604  }
13605  }
13606  return ret;
13607  case SQL_HANDLE_DBC:
13608  return drvallocconnect((SQLHENV) input, (SQLHDBC *) output);
13609  case SQL_HANDLE_STMT:
13610  HDBC_LOCK((SQLHDBC) input);
13611  ret = drvallocstmt((SQLHDBC) input, (SQLHSTMT *) output);
13612  HDBC_UNLOCK((SQLHDBC) input);
13613  return ret;
13614  }
13615  return SQL_ERROR;
13616 }
13617 
13625 SQLRETURN SQL_API
13626 SQLFreeHandle(SQLSMALLINT type, SQLHANDLE h)
13627 {
13628  switch (type) {
13629  case SQL_HANDLE_ENV:
13630  return drvfreeenv((SQLHENV) h);
13631  case SQL_HANDLE_DBC:
13632  return drvfreeconnect((SQLHDBC) h);
13633  case SQL_HANDLE_STMT:
13634  return drvfreestmt((SQLHSTMT) h, SQL_DROP);
13635  }
13636  return SQL_ERROR;
13637 }
13638 
13644 static void
13646 {
13647  if (s->dyncols) {
13648  int i;
13649 
13650  for (i = 0; i < s->dcols; i++) {
13651  freep(&s->dyncols[i].typename);
13652  }
13653  if (s->cols == s->dyncols) {
13654  s->cols = NULL;
13655  s->ncols = 0;
13656  }
13657  freep(&s->dyncols);
13658  }
13659  s->dcols = 0;
13660 }
13661 
13673 static void
13674 freeresult(STMT *s, int clrcols)
13675 {
13676  freep(&s->bincache);
13677  s->bincell = NULL;
13678  s->binlen = 0;
13679  if (s->rows) {
13680  if (s->rowfree) {
13681  s->rowfree(s->rows);
13682  s->rowfree = NULL;
13683  }
13684  s->rows = NULL;
13685  }
13686  s->nrows = -1;
13687  if (clrcols > 0) {
13688  freep(&s->bindcols);
13689  s->nbindcols = 0;
13690  }
13691  if (clrcols) {
13692  freedyncols(s);
13693  s->cols = NULL;
13694  s->ncols = 0;
13695  s->nowchar[1] = 0;
13696  s->one_tbl = -1;
13697  s->has_pk = -1;
13698  s->has_rowid = -1;
13699  }
13700 }
13701 
13707 static void
13709 {
13710  int i;
13711 
13712  for (i = 0; s->bindcols && i < s->nbindcols; i++) {
13713  s->bindcols[i].type = SQL_UNKNOWN_TYPE;
13714  s->bindcols[i].max = 0;
13715  s->bindcols[i].lenp = NULL;
13716  s->bindcols[i].valp = NULL;
13717  s->bindcols[i].index = i;
13718  s->bindcols[i].offs = 0;
13719  }
13720 }
13721 
13729 static SQLRETURN
13730 mkbindcols(STMT *s, int ncols)
13731 {
13732  if (s->bindcols) {
13733  if (s->nbindcols < ncols) {
13734  int i;
13735  BINDCOL *bindcols =
13736  xrealloc(s->bindcols, ncols * sizeof (BINDCOL));
13737 
13738  if (!bindcols) {
13739  return nomem(s);
13740  }
13741  for (i = s->nbindcols; i < ncols; i++) {
13742  bindcols[i].type = SQL_UNKNOWN_TYPE;
13743  bindcols[i].max = 0;
13744  bindcols[i].lenp = NULL;
13745  bindcols[i].valp = NULL;
13746  bindcols[i].index = i;
13747  bindcols[i].offs = 0;
13748  }
13749  s->bindcols = bindcols;
13750  s->nbindcols = ncols;
13751  }
13752  } else if (ncols > 0) {
13753  s->bindcols = (BINDCOL *) xmalloc(ncols * sizeof (BINDCOL));
13754  if (!s->bindcols) {
13755  return nomem(s);
13756  }
13757  s->nbindcols = ncols;
13758  unbindcols(s);
13759  }
13760  return SQL_SUCCESS;
13761 }
13762 
13776 static SQLRETURN
13777 getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype,
13778  SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp, int partial)
13779 {
13780  char **data, valdummy[16];
13781  SQLLEN dummy;
13782  SQLINTEGER *ilenp = NULL;
13783  int valnull = 0;
13784  int type = otype;
13785  SQLRETURN sret = SQL_NO_DATA;
13786 
13787  if (!lenp) {
13788  lenp = &dummy;
13789  }
13790  /* workaround for JDK 1.7.0 on x86_64 */
13791  if (((SQLINTEGER *) lenp) + 1 == (SQLINTEGER *) val) {
13792  ilenp = (SQLINTEGER *) lenp;
13793  lenp = &dummy;
13794  }
13795  if (col >= s->ncols) {
13796  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
13797  return SQL_ERROR;
13798  }
13799  if (s->retr_data != SQL_RD_ON) {
13800  return SQL_SUCCESS;
13801  }
13802  if (!s->rows) {
13803  *lenp = SQL_NULL_DATA;
13804  goto done;
13805  }
13806  if (s->rowp < 0 || s->rowp >= s->nrows) {
13807  *lenp = SQL_NULL_DATA;
13808  goto done;
13809  }
13810  type = mapdeftype(type, s->cols[col].type, s->cols[col].nosign ? 1 : 0,
13811  s->nowchar[0]);
13812 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
13813  /* MS Access hack part 3 (map SQL_C_DEFAULT to SQL_C_CHAR) */
13814  if (type == SQL_C_WCHAR && otype == SQL_C_DEFAULT) {
13815  type = SQL_C_CHAR;
13816  }
13817 #endif
13818  data = s->rows + s->ncols + (s->rowp * s->ncols) + col;
13819  if (!val) {
13820  valnull = 1;
13821  val = (SQLPOINTER) valdummy;
13822  }
13823  if (*data == NULL) {
13824  *lenp = SQL_NULL_DATA;
13825  switch (type) {
13826  case SQL_C_UTINYINT:
13827  case SQL_C_TINYINT:
13828  case SQL_C_STINYINT:
13829 #ifdef SQL_BIT
13830  case SQL_C_BIT:
13831 #endif
13832  *((SQLCHAR *) val) = 0;
13833  break;
13834  case SQL_C_USHORT:
13835  case SQL_C_SHORT:
13836  case SQL_C_SSHORT:
13837  *((SQLSMALLINT *) val) = 0;
13838  break;
13839  case SQL_C_ULONG:
13840  case SQL_C_LONG:
13841  case SQL_C_SLONG:
13842  *((SQLINTEGER *) val) = 0;
13843  break;
13844 #ifdef SQL_BIGINT
13845  case SQL_C_SBIGINT:
13846  case SQL_C_UBIGINT:
13847  *((SQLBIGINT *) val) = 0;
13848  break;
13849 #endif
13850  case SQL_C_FLOAT:
13851  *((float *) val) = 0;
13852  break;
13853  case SQL_C_DOUBLE:
13854  *((double *) val) = 0;
13855  break;
13856  case SQL_C_BINARY:
13857  case SQL_C_CHAR:
13858  if (len > 0) {
13859  *((SQLCHAR *) val) = '\0';
13860  }
13861  break;
13862 #ifdef WCHARSUPPORT
13863  case SQL_C_WCHAR:
13864  if (len > 0) {
13865  *((SQLWCHAR *) val) = '\0';
13866  }
13867  break;
13868 #endif
13869 #ifdef SQL_C_TYPE_DATE
13870  case SQL_C_TYPE_DATE:
13871 #endif
13872  case SQL_C_DATE:
13873  memset((DATE_STRUCT *) val, 0, sizeof (DATE_STRUCT));
13874  break;
13875 #ifdef SQL_C_TYPE_TIME
13876  case SQL_C_TYPE_TIME:
13877 #endif
13878  case SQL_C_TIME:
13879  memset((TIME_STRUCT *) val, 0, sizeof (TIME_STRUCT));
13880  break;
13881 #ifdef SQL_C_TYPE_TIMESTAMP
13882  case SQL_C_TYPE_TIMESTAMP:
13883 #endif
13884  case SQL_C_TIMESTAMP:
13885  memset((TIMESTAMP_STRUCT *) val, 0, sizeof (TIMESTAMP_STRUCT));
13886  break;
13887  default:
13888  return SQL_ERROR;
13889  }
13890  } else {
13891  char *endp = NULL;
13892 #if defined(_WIN32) || defined(_WIN64)
13893 #ifdef SQL_BIGINT
13894  char endc;
13895 #endif
13896 #endif
13897 
13898  switch (type) {
13899  case SQL_C_UTINYINT:
13900  case SQL_C_TINYINT:
13901  case SQL_C_STINYINT:
13902  *((SQLCHAR *) val) = strtol(*data, &endp, 0);
13903  if (endp && endp == *data) {
13904  *lenp = SQL_NULL_DATA;
13905  } else {
13906  *lenp = sizeof (SQLCHAR);
13907  }
13908  break;
13909 #ifdef SQL_BIT
13910  case SQL_C_BIT:
13911  *((SQLCHAR *) val) = getbool(*data);
13912  *lenp = sizeof (SQLCHAR);
13913  break;
13914 #endif
13915  case SQL_C_USHORT:
13916  case SQL_C_SHORT:
13917  case SQL_C_SSHORT:
13918  *((SQLSMALLINT *) val) = strtol(*data, &endp, 0);
13919  if (endp && endp == *data) {
13920  *lenp = SQL_NULL_DATA;
13921  } else {
13922  *lenp = sizeof (SQLSMALLINT);
13923  }
13924  break;
13925  case SQL_C_ULONG:
13926  case SQL_C_LONG:
13927  case SQL_C_SLONG:
13928  *((SQLINTEGER *) val) = strtol(*data, &endp, 0);
13929  if (endp && endp == *data) {
13930  *lenp = SQL_NULL_DATA;
13931  } else {
13932  *lenp = sizeof (SQLINTEGER);
13933  }
13934  break;
13935 #ifdef SQL_BIGINT
13936  case SQL_C_UBIGINT:
13937 #if defined(_WIN32) || defined(_WIN64)
13938  if (sscanf(*data, "%I64u%c", (SQLUBIGINT *) val, &endc) != 1) {
13939  *lenp = SQL_NULL_DATA;
13940  } else {
13941  *lenp = sizeof (SQLUBIGINT);
13942  }
13943 #else
13944 #ifdef __osf__
13945  *((SQLUBIGINT *) val) = strtoul(*data, &endp, 0);
13946 #else
13947  *((SQLUBIGINT *) val) = strtoull(*data, &endp, 0);
13948 #endif
13949  if (endp && endp == *data) {
13950  *lenp = SQL_NULL_DATA;
13951  } else {
13952  *lenp = sizeof (SQLUBIGINT);
13953  }
13954 #endif
13955  break;
13956  case SQL_C_SBIGINT:
13957 #if defined(_WIN32) || defined(_WIN64)
13958  if (sscanf(*data, "%I64d%c", (SQLBIGINT *) val, &endc) != 1) {
13959  *lenp = SQL_NULL_DATA;
13960  } else {
13961  *lenp = sizeof (SQLBIGINT);
13962  }
13963 #else
13964 #ifdef __osf__
13965  *((SQLBIGINT *) val) = strtol(*data, &endp, 0);
13966 #else
13967  *((SQLBIGINT *) val) = strtoll(*data, &endp, 0);
13968 #endif
13969  if (endp && endp == *data) {
13970  *lenp = SQL_NULL_DATA;
13971  } else {
13972  *lenp = sizeof (SQLBIGINT);
13973  }
13974 #endif
13975  break;
13976 #endif
13977  case SQL_C_FLOAT:
13978  *((float *) val) = ln_strtod(*data, &endp);
13979  if (endp && endp == *data) {
13980  *lenp = SQL_NULL_DATA;
13981  } else {
13982  *lenp = sizeof (float);
13983  }
13984  break;
13985  case SQL_C_DOUBLE:
13986  *((double *) val) = ln_strtod(*data, &endp);
13987  if (endp && endp == *data) {
13988  *lenp = SQL_NULL_DATA;
13989  } else {
13990  *lenp = sizeof (double);
13991  }
13992  break;
13993  case SQL_C_BINARY: {
13994  int dlen, offs = 0;
13995  char *bin;
13996 
13997  if (valnull) {
13998  freep(&s->bincache);
13999  s->binlen = 0;
14000  goto doCHAR;
14001  }
14002  if (*data == s->bincell) {
14003  if (s->bincache) {
14004  bin = s->bincache;
14005  dlen = s->binlen;
14006  } else {
14007  goto doCHAR;
14008  }
14009  } else {
14010  char *dp;
14011  int i;
14012 
14013  freep(&s->bincache);
14014  dp = *data;
14015  dlen = strlen(dp);
14016  s->bincell = dp;
14017  s->binlen = 0;
14018  if (!(dp[0] == 'x' || dp[0] == 'X') || dp[1] != '\'' ||
14019  dp[dlen - 1] != '\'') {
14020  goto doCHAR;
14021  }
14022  dlen -= 2;
14023  dp += 2;
14024  dlen = dlen / 2;
14025  s->bincache = bin = xmalloc(dlen + 1);
14026  if (!bin) {
14027  return nomem(s);
14028  }
14029  s->binlen = dlen;
14030  memset(bin, 0, dlen);
14031  bin[dlen] = '\0'; /* terminator, just in case */
14032  for (i = 0; i < dlen; i++) {
14033  char *x;
14034  int v;
14035 
14036  if (!*dp || !(x = strchr(xdigits, *dp))) {
14037  goto converr;
14038  }
14039  v = x - xdigits;
14040  bin[i] = (v >= 16) ? ((v - 6) << 4) : (v << 4);
14041  ++dp;
14042  if (!*dp || !(x = strchr(xdigits, *dp))) {
14043 converr:
14044  freep(&s->bincache);
14045  s->binlen = 0;
14046  setstat(s, -1, "conversion error",
14047  (*s->ov3) ? "HY000" : "S1000");
14048  return SQL_ERROR;
14049  }
14050  v = x - xdigits;
14051  bin[i] |= (v >= 16) ? (v - 6) : v;
14052  ++dp;
14053  }
14054  bin = s->bincache;
14055  }
14056  if (partial && len && s->bindcols) {
14057  if (s->bindcols[col].offs >= dlen) {
14058  *lenp = 0;
14059  if (!dlen && s->bindcols[col].offs == dlen) {
14060  s->bindcols[col].offs = 1;
14061  sret = SQL_SUCCESS;
14062  goto done;
14063  }
14064  s->bindcols[col].offs = 0;
14065  sret = SQL_NO_DATA;
14066  goto done;
14067  }
14068  offs = s->bindcols[col].offs;
14069  dlen -= offs;
14070  }
14071  if (val && len) {
14072  memcpy(val, bin + offs, min(len, dlen));
14073  }
14074  if (len < 1) {
14075  *lenp = dlen;
14076  } else {
14077  *lenp = min(len, dlen);
14078  if (*lenp == len && *lenp != dlen) {
14079  *lenp = SQL_NO_TOTAL;
14080  }
14081  }
14082  if (partial && len && s->bindcols) {
14083  if (*lenp == SQL_NO_TOTAL) {
14084  *lenp = dlen;
14085  s->bindcols[col].offs += len;
14086  setstat(s, -1, "data right truncated", "01004");
14087  if (s->bindcols[col].lenp) {
14088  *s->bindcols[col].lenp = dlen;
14089  }
14090  sret = SQL_SUCCESS_WITH_INFO;
14091  goto done;
14092  }
14093  s->bindcols[col].offs += *lenp;
14094  }
14095  if (*lenp == SQL_NO_TOTAL) {
14096  *lenp = dlen;
14097  setstat(s, -1, "data right truncated", "01004");
14098  sret = SQL_SUCCESS_WITH_INFO;
14099  goto done;
14100  }
14101  break;
14102  }
14103  doCHAR:
14104 #ifdef WCHARSUPPORT
14105  case SQL_C_WCHAR:
14106 #endif
14107  case SQL_C_CHAR: {
14108  int doz, zlen = len - 1;
14109  int dlen = strlen(*data);
14110  int offs = 0;
14111 #ifdef WCHARSUPPORT
14112  SQLWCHAR *ucdata = NULL;
14113  SQLCHAR *cdata = (SQLCHAR *) *data;
14114 #endif
14115 
14116 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
14117  /* MS Access hack part 2 (reserved error -7748) */
14118  if (!valnull &&
14119  (s->cols == statSpec2P || s->cols == statSpec3P) &&
14120  type == SQL_C_WCHAR) {
14121  if (len > 0 && len <= sizeof (SQLWCHAR)) {
14122  ((char *) val)[0] = data[0][0];
14123  memset((char *) val + 1, 0, len - 1);
14124  *lenp = 1;
14125  sret = SQL_SUCCESS;
14126  goto done;
14127  }
14128  }
14129 #endif
14130 
14131 #ifdef WCHARSUPPORT
14132  switch (type) {
14133  case SQL_C_CHAR:
14134  doz = 1;
14135  break;
14136  case SQL_C_WCHAR:
14137  doz = sizeof (SQLWCHAR);
14138  break;
14139  default:
14140  doz = 0;
14141  break;
14142  }
14143  if (type == SQL_C_WCHAR) {
14144  ucdata = uc_from_utf(cdata, dlen);
14145  if (!ucdata) {
14146  return nomem(s);
14147  }
14148  dlen = uc_strlen(ucdata) * sizeof (SQLWCHAR);
14149  }
14150 #if defined(_WIN32) || defined(_WIN64)
14151  else if (*s->oemcp && type == SQL_C_CHAR) {
14152  ucdata = (SQLWCHAR *) utf_to_wmb((char *) cdata, dlen);
14153  if (!ucdata) {
14154  return nomem(s);
14155  }
14156  cdata = (SQLCHAR *) ucdata;
14157  dlen = strlen((char *) cdata);
14158  }
14159 #endif
14160 #else
14161  doz = (type == SQL_C_CHAR) ? 1 : 0;
14162 #endif
14163  if (partial && len && s->bindcols) {
14164  if (s->bindcols[col].offs >= dlen) {
14165 #ifdef WCHARSUPPORT
14166  uc_free(ucdata);
14167 #endif
14168  *lenp = 0;
14169  if (doz && val) {
14170 #ifdef WCHARSUPPORT
14171  if (type == SQL_C_WCHAR) {
14172  ((SQLWCHAR *) val)[0] = 0;
14173  } else {
14174  ((char *) val)[0] = '\0';
14175  }
14176 #else
14177  ((char *) val)[0] = '\0';
14178 #endif
14179  }
14180  if (!dlen && s->bindcols[col].offs == dlen) {
14181  s->bindcols[col].offs = 1;
14182  sret = SQL_SUCCESS;
14183  goto done;
14184  }
14185  s->bindcols[col].offs = 0;
14186  sret = SQL_NO_DATA;
14187  goto done;
14188  }
14189  offs = s->bindcols[col].offs;
14190  dlen -= offs;
14191  }
14192  if (val && !valnull && len) {
14193 #ifdef WCHARSUPPORT
14194  if (type == SQL_C_WCHAR) {
14195  uc_strncpy(val, ucdata + offs / sizeof (SQLWCHAR),
14196  (len - doz) / sizeof (SQLWCHAR));
14197  } else {
14198  strncpy(val, (char *) cdata + offs, len - doz);
14199  }
14200 #else
14201  strncpy(val, *data + offs, len - doz);
14202 #endif
14203  }
14204  if (valnull || len < 1) {
14205  *lenp = dlen;
14206  } else {
14207  *lenp = min(len - doz, dlen);
14208  if (*lenp == len - doz && *lenp != dlen) {
14209  *lenp = SQL_NO_TOTAL;
14210  } else if (*lenp < zlen) {
14211  zlen = *lenp;
14212  }
14213  }
14214  if (len && !valnull && doz) {
14215 #ifdef WCHARSUPPORT
14216  if (type == SQL_C_WCHAR) {
14217  ((SQLWCHAR *) val)[zlen / sizeof (SQLWCHAR)] = 0;
14218  } else {
14219  ((char *) val)[zlen] = '\0';
14220  }
14221 #else
14222  ((char *) val)[zlen] = '\0';
14223 #endif
14224  }
14225 #ifdef WCHARSUPPORT
14226  uc_free(ucdata);
14227 #endif
14228  if (partial && len && s->bindcols) {
14229  if (*lenp == SQL_NO_TOTAL) {
14230  *lenp = dlen;
14231  s->bindcols[col].offs += len - doz;
14232  setstat(s, -1, "data right truncated", "01004");
14233  if (s->bindcols[col].lenp) {
14234  *s->bindcols[col].lenp = dlen;
14235  }
14236  sret = SQL_SUCCESS_WITH_INFO;
14237  goto done;
14238  }
14239  s->bindcols[col].offs += *lenp;
14240  }
14241  if (*lenp == SQL_NO_TOTAL) {
14242  *lenp = dlen;
14243  setstat(s, -1, "data right truncated", "01004");
14244  sret = SQL_SUCCESS_WITH_INFO;
14245  goto done;
14246  }
14247  break;
14248  }
14249 #ifdef SQL_C_TYPE_DATE
14250  case SQL_C_TYPE_DATE:
14251 #endif
14252  case SQL_C_DATE:
14253  if (str2date(*s->jdconv, *data, (DATE_STRUCT *) val) < 0) {
14254  *lenp = SQL_NULL_DATA;
14255  } else {
14256  *lenp = sizeof (DATE_STRUCT);
14257  }
14258  break;
14259 #ifdef SQL_C_TYPE_TIME
14260  case SQL_C_TYPE_TIME:
14261 #endif
14262  case SQL_C_TIME:
14263  if (str2time(*s->jdconv, *data, (TIME_STRUCT *) val) < 0) {
14264  *lenp = SQL_NULL_DATA;
14265  } else {
14266  *lenp = sizeof (TIME_STRUCT);
14267  }
14268  break;
14269 #ifdef SQL_C_TYPE_TIMESTAMP
14270  case SQL_C_TYPE_TIMESTAMP:
14271 #endif
14272  case SQL_C_TIMESTAMP:
14273  if (str2timestamp(*s->jdconv, *data,
14274  (TIMESTAMP_STRUCT *) val) < 0) {
14275  *lenp = SQL_NULL_DATA;
14276  } else {
14277  *lenp = sizeof (TIMESTAMP_STRUCT);
14278  }
14279  switch (s->cols[col].prec) {
14280  case 0:
14281  ((TIMESTAMP_STRUCT *) val)->fraction = 0;
14282  break;
14283  case 1:
14284  ((TIMESTAMP_STRUCT *) val)->fraction /= 100000000;
14285  ((TIMESTAMP_STRUCT *) val)->fraction *= 100000000;
14286  break;
14287  case 2:
14288  ((TIMESTAMP_STRUCT *) val)->fraction /= 10000000;
14289  ((TIMESTAMP_STRUCT *) val)->fraction *= 10000000;
14290  break;
14291  }
14292  break;
14293  default:
14294  return SQL_ERROR;
14295  }
14296  }
14297  sret = SQL_SUCCESS;
14298 done:
14299  if (ilenp) {
14300  *ilenp = *lenp;
14301  }
14302  return sret;
14303 }
14304 
14316 static SQLRETURN
14317 drvbindcol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14318  SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14319 {
14320  STMT *s;
14321  int sz = 0;
14322 
14323  if (stmt == SQL_NULL_HSTMT) {
14324  return SQL_INVALID_HANDLE;
14325  }
14326  s = (STMT *) stmt;
14327  if (col < 1) {
14328  if (col == 0 && s->bkmrk == SQL_UB_ON &&
14329  type == SQL_C_BOOKMARK) {
14330  s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14331  s->bkmrkcol.max = val ? sizeof (SQLINTEGER) : 0;
14332  s->bkmrkcol.lenp = val ? lenp : 0;
14333  s->bkmrkcol.valp = val;
14334  s->bkmrkcol.offs = 0;
14335  if (val && lenp) {
14336  *lenp = 0;
14337  }
14338  return SQL_SUCCESS;
14339  } else if (col == 0 && s->bkmrk == SQL_UB_VARIABLE &&
14340  type == SQL_C_VARBOOKMARK &&
14341  max >= sizeof (sqlite_int64)) {
14342  s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14343  s->bkmrkcol.max = val ? max : 0;
14344  s->bkmrkcol.lenp = val ? lenp : 0;
14345  s->bkmrkcol.valp = val;
14346  s->bkmrkcol.offs = 0;
14347  if (val && lenp) {
14348  *lenp = 0;
14349  }
14350  return SQL_SUCCESS;
14351  }
14352  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
14353  return SQL_ERROR;
14354  }
14355  if (mkbindcols(s, col) != SQL_SUCCESS) {
14356  return SQL_ERROR;
14357  }
14358  --col;
14359  if (type == SQL_C_DEFAULT) {
14360  type = mapdeftype(type, s->cols[col].type, 0,
14361  s->nowchar[0] || s->nowchar[1]);
14362  }
14363  switch (type) {
14364  case SQL_C_LONG:
14365  case SQL_C_ULONG:
14366  case SQL_C_SLONG:
14367  sz = sizeof (SQLINTEGER);
14368  break;
14369  case SQL_C_TINYINT:
14370  case SQL_C_UTINYINT:
14371  case SQL_C_STINYINT:
14372  sz = sizeof (SQLCHAR);
14373  break;
14374  case SQL_C_SHORT:
14375  case SQL_C_USHORT:
14376  case SQL_C_SSHORT:
14377  sz = sizeof (SQLSMALLINT);
14378  break;
14379  case SQL_C_FLOAT:
14380  sz = sizeof (SQLFLOAT);
14381  break;
14382  case SQL_C_DOUBLE:
14383  sz = sizeof (SQLDOUBLE);
14384  break;
14385  case SQL_C_TIMESTAMP:
14386  sz = sizeof (SQL_TIMESTAMP_STRUCT);
14387  break;
14388  case SQL_C_TIME:
14389  sz = sizeof (SQL_TIME_STRUCT);
14390  break;
14391  case SQL_C_DATE:
14392  sz = sizeof (SQL_DATE_STRUCT);
14393  break;
14394  case SQL_C_CHAR:
14395  break;
14396 #ifdef WCHARSUPPORT
14397  case SQL_C_WCHAR:
14398  break;
14399 #endif
14400 #ifdef SQL_C_TYPE_DATE
14401  case SQL_C_TYPE_DATE:
14402  sz = sizeof (SQL_DATE_STRUCT);
14403  break;
14404 #endif
14405 #ifdef SQL_C_TYPE_TIME
14406  case SQL_C_TYPE_TIME:
14407  sz = sizeof (SQL_TIME_STRUCT);
14408  break;
14409 #endif
14410 #ifdef SQL_C_TYPE_TIMESTAMP
14411  case SQL_C_TYPE_TIMESTAMP:
14412  sz = sizeof (SQL_TIMESTAMP_STRUCT);
14413  break;
14414 #endif
14415 #ifdef SQL_BIT
14416  case SQL_C_BIT:
14417  sz = sizeof (SQLCHAR);
14418  break;
14419 #endif
14420  case SQL_C_BINARY:
14421  break;
14422 #ifdef SQL_BIGINT
14423  case SQL_C_SBIGINT:
14424  case SQL_C_UBIGINT:
14425  sz = sizeof (SQLBIGINT);
14426  break;
14427 #endif
14428  default:
14429  if (val == NULL) {
14430  /* fall through, unbinding column */
14431  break;
14432  }
14433  setstat(s, -1, "invalid type %d", "HY003", type);
14434  return SQL_ERROR;
14435  }
14436  if (val == NULL) {
14437  /* unbind column */
14438  s->bindcols[col].type = SQL_UNKNOWN_TYPE;
14439  s->bindcols[col].max = 0;
14440  s->bindcols[col].lenp = NULL;
14441  s->bindcols[col].valp = NULL;
14442  s->bindcols[col].offs = 0;
14443  } else {
14444  if (sz == 0 && max < 0) {
14445  setstat(s, -1, "invalid length", "HY090");
14446  return SQL_ERROR;
14447  }
14448  s->bindcols[col].type = type;
14449  s->bindcols[col].max = (sz == 0) ? max : sz;
14450  s->bindcols[col].lenp = lenp;
14451  s->bindcols[col].valp = val;
14452  s->bindcols[col].offs = 0;
14453  if (lenp) {
14454  *lenp = 0;
14455  }
14456  }
14457  return SQL_SUCCESS;
14458 }
14459 
14471 SQLRETURN SQL_API
14472 SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14473  SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14474 {
14475  SQLRETURN ret;
14476 
14477  HSTMT_LOCK(stmt);
14478  ret = drvbindcol(stmt, col, type, val, max, lenp);
14479  HSTMT_UNLOCK(stmt);
14480  return ret;
14481 }
14482 
14487 static COL tableSpec2[] = {
14488  { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
14489  { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
14490  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14491  { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14492  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14493 };
14494 
14495 static COL tableSpec3[] = {
14496  { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
14497  { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
14498  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14499  { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14500  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14501 };
14502 
14517 static SQLRETURN
14518 drvtables(SQLHSTMT stmt,
14519  SQLCHAR *cat, SQLSMALLINT catLen,
14520  SQLCHAR *schema, SQLSMALLINT schemaLen,
14521  SQLCHAR *table, SQLSMALLINT tableLen,
14522  SQLCHAR *type, SQLSMALLINT typeLen)
14523 {
14524  SQLRETURN ret;
14525  STMT *s;
14526  DBC *d;
14527  int ncols, asize, rc, size, npatt;
14528  char *errp = NULL, *sql, tname[512];
14529  char *where = "(type = 'table' or type = 'view')";
14530 
14531  ret = mkresultset(stmt, tableSpec2, array_size(tableSpec2),
14532  tableSpec3, array_size(tableSpec3), &asize);
14533  if (ret != SQL_SUCCESS) {
14534  return ret;
14535  }
14536  s = (STMT *) stmt;
14537  d = (DBC *) s->dbc;
14538  if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] == '%') {
14539  int size = 3 * asize;
14540 
14541  s->rows = xmalloc(size * sizeof (char *));
14542  if (!s->rows) {
14543  s->nrows = 0;
14544  return nomem(s);
14545  }
14546  memset(s->rows, 0, sizeof (char *) * size);
14547  s->ncols = asize;
14548  s->rows[s->ncols + 0] = "";
14549  s->rows[s->ncols + 1] = "";
14550  s->rows[s->ncols + 2] = "";
14551  s->rows[s->ncols + 3] = "TABLE";
14552  s->rows[s->ncols + 5] = "";
14553  s->rows[s->ncols + 6] = "";
14554  s->rows[s->ncols + 7] = "";
14555  s->rows[s->ncols + 8] = "VIEW";
14556 #ifdef MEMORY_DEBUG
14557  s->rowfree = xfree__;
14558 #else
14559  s->rowfree = sqlite3_free;
14560 #endif
14561  s->nrows = 2;
14562  s->rowp = s->rowprs = -1;
14563  return SQL_SUCCESS;
14564  }
14565  if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
14566  table = NULL;
14567  goto doit;
14568  }
14569  if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
14570  schema[0] == '%') {
14571  if ((!cat || catLen == 0 || !cat[0]) &&
14572  (!table || tableLen == 0 || !table[0])) {
14573  table = NULL;
14574  goto doit;
14575  }
14576  }
14577  if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] != '\0') {
14578  char tmp[256], *t;
14579  int with_view = 0, with_table = 0;
14580 
14581  if (typeLen == SQL_NTS) {
14582  strncpy(tmp, (char *) type, sizeof (tmp));
14583  tmp[sizeof (tmp) - 1] = '\0';
14584  } else {
14585  int len = min(sizeof (tmp) - 1, typeLen);
14586 
14587  strncpy(tmp, (char *) type, len);
14588  tmp[len] = '\0';
14589  }
14590  t = tmp;
14591  while (*t) {
14592  *t = TOLOWER(*t);
14593  t++;
14594  }
14595  t = tmp;
14596  unescpat(t);
14597  while (t) {
14598  if (t[0] == '\'') {
14599  ++t;
14600  }
14601  if (strncmp(t, "table", 5) == 0) {
14602  with_table++;
14603  } else if (strncmp(t, "view", 4) == 0) {
14604  with_view++;
14605  }
14606  t = strchr(t, ',');
14607  if (t) {
14608  ++t;
14609  }
14610  }
14611  if (with_view && with_table) {
14612  /* where is already preset */
14613  } else if (with_view && !with_table) {
14614  where = "type = 'view'";
14615  } else if (!with_view && with_table) {
14616  where = "type = 'table'";
14617  } else {
14618  return SQL_SUCCESS;
14619  }
14620  }
14621 doit:
14622  if (!table) {
14623  size = 1;
14624  tname[0] = '%';
14625  } else {
14626  if (tableLen == SQL_NTS) {
14627  size = sizeof (tname) - 1;
14628  } else {
14629  size = min(sizeof (tname) - 1, tableLen);
14630  }
14631  strncpy(tname, (char *) table, size);
14632  }
14633  tname[size] = '\0';
14634  npatt = unescpat(tname);
14635 #if defined(_WIN32) || defined(_WIN64)
14636  sql = sqlite3_mprintf("select %s as 'TABLE_CAT', "
14637  "%s as 'TABLE_SCHEM', "
14638  "tbl_name as 'TABLE_NAME', "
14639  "upper(type) as 'TABLE_TYPE', "
14640  "NULL as 'REMARKS' "
14641  "from sqlite_master where %s "
14642  "and tbl_name %s %Q",
14643  d->xcelqrx ? "'main'" : "NULL",
14644  d->xcelqrx ? "''" : "NULL",
14645  where,
14646  npatt ? "like" : "=", tname);
14647 #else
14648  sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
14649  "NULL as 'TABLE_OWNER', "
14650  "tbl_name as 'TABLE_NAME', "
14651  "upper(type) as 'TABLE_TYPE', "
14652  "NULL as 'REMARKS' "
14653  "from sqlite_master where %s "
14654  "and tbl_name %s %Q", where,
14655  npatt ? "like" : "=", tname);
14656 #endif
14657  if (!sql) {
14658  return nomem(s);
14659  }
14660  ret = starttran(s);
14661  if (ret != SQL_SUCCESS) {
14662  sqlite3_free(sql);
14663  return ret;
14664  }
14665  dbtraceapi(d, "sqlite3_get_table", sql);
14666  rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
14667  sqlite3_free(sql);
14668  if (rc == SQLITE_OK) {
14669  if (ncols != s->ncols) {
14670  freeresult(s, 0);
14671  s->nrows = 0;
14672  } else {
14673  s->rowfree = sqlite3_free_table;
14674  }
14675  } else {
14676  s->nrows = 0;
14677  s->rows = NULL;
14678  s->rowfree = NULL;
14679  }
14680  if (errp) {
14681  sqlite3_free(errp);
14682  errp = NULL;
14683  }
14684  s->rowp = s->rowprs = -1;
14685  return SQL_SUCCESS;
14686 }
14687 
14688 #ifndef WINTERFACE
14689 
14703 SQLRETURN SQL_API
14704 SQLTables(SQLHSTMT stmt,
14705  SQLCHAR *cat, SQLSMALLINT catLen,
14706  SQLCHAR *schema, SQLSMALLINT schemaLen,
14707  SQLCHAR *table, SQLSMALLINT tableLen,
14708  SQLCHAR *type, SQLSMALLINT typeLen)
14709 {
14710 #if defined(_WIN32) || defined(_WIN64)
14711  char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
14712 #endif
14713  SQLRETURN ret;
14714 
14715  HSTMT_LOCK(stmt);
14716 #if defined(_WIN32) || defined(_WIN64)
14717  if (!((STMT *) stmt)->oemcp[0]) {
14718  ret = drvtables(stmt, cat, catLen, schema, schemaLen,
14719  table, tableLen, type, typeLen);
14720  goto done2;
14721  }
14722  if (cat) {
14723  c = wmb_to_utf_c((char *) cat, catLen);
14724  if (!c) {
14725  ret = nomem((STMT *) stmt);
14726  goto done;
14727  }
14728  }
14729  if (schema) {
14730  s = wmb_to_utf_c((char *) schema, schemaLen);
14731  if (!s) {
14732  ret = nomem((STMT *) stmt);
14733  goto done;
14734  }
14735  }
14736  if (table) {
14737  t = wmb_to_utf_c((char *) table, tableLen);
14738  if (!t) {
14739  ret = nomem((STMT *) stmt);
14740  goto done;
14741  }
14742  }
14743  if (type) {
14744  y = wmb_to_utf_c((char *) type, typeLen);
14745  if (!y) {
14746  ret = nomem((STMT *) stmt);
14747  goto done;
14748  }
14749  }
14750  ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
14751  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
14752 #else
14753  ret = drvtables(stmt, cat, catLen, schema, schemaLen,
14754  table, tableLen, type, typeLen);
14755 #endif
14756 #if defined(_WIN32) || defined(_WIN64)
14757 done:
14758  uc_free(y);
14759  uc_free(t);
14760  uc_free(s);
14761  uc_free(c);
14762 done2:
14763  ;
14764 #endif
14765  HSTMT_UNLOCK(stmt);
14766  return ret;
14767 }
14768 #endif
14769 
14770 #ifdef WINTERFACE
14771 
14785 SQLRETURN SQL_API
14786 SQLTablesW(SQLHSTMT stmt,
14787  SQLWCHAR *cat, SQLSMALLINT catLen,
14788  SQLWCHAR *schema, SQLSMALLINT schemaLen,
14789  SQLWCHAR *table, SQLSMALLINT tableLen,
14790  SQLWCHAR *type, SQLSMALLINT typeLen)
14791 {
14792  char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
14793  SQLRETURN ret;
14794 
14795  HSTMT_LOCK(stmt);
14796  if (cat) {
14797  c = uc_to_utf_c(cat, catLen);
14798  if (!c) {
14799  ret = nomem((STMT *) stmt);
14800  goto done;
14801  }
14802  }
14803  if (schema) {
14804  s = uc_to_utf_c(schema, schemaLen);
14805  if (!s) {
14806  ret = nomem((STMT *) stmt);
14807  goto done;
14808  }
14809  }
14810  if (table) {
14811  t = uc_to_utf_c(table, tableLen);
14812  if (!t) {
14813  ret = nomem((STMT *) stmt);
14814  goto done;
14815  }
14816  }
14817  if (type) {
14818  y = uc_to_utf_c(type, typeLen);
14819  if (!y) {
14820  ret = nomem((STMT *) stmt);
14821  goto done;
14822  }
14823  }
14824  ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
14825  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
14826 done:
14827  uc_free(y);
14828  uc_free(t);
14829  uc_free(s);
14830  uc_free(c);
14831  HSTMT_UNLOCK(stmt);
14832  return ret;
14833 }
14834 #endif
14835 
14840 static COL colSpec2[] = {
14841  { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
14842  { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
14843  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14844  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
14845  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
14846  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
14847  { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
14848  { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
14849  { "SYSTEM", "COLUMN", "SCALE", SQL_SMALLINT, 50 },
14850  { "SYSTEM", "COLUMN", "RADIX", SQL_SMALLINT, 50 },
14851  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
14852  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
14853  { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
14854  { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
14855  { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
14856  { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
14857  { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
14858  { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
14859 };
14860 
14861 static COL colSpec3[] = {
14862  { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
14863  { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
14864  { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14865  { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
14866  { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
14867  { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
14868  { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
14869  { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
14870  { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_SMALLINT, 50 },
14871  { "SYSTEM", "COLUMN", "NUM_PREC_RADIX", SQL_SMALLINT, 50 },
14872  { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
14873  { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
14874  { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
14875  { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
14876  { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
14877  { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
14878  { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
14879  { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
14880 };
14881 
14896 static SQLRETURN
14897 drvcolumns(SQLHSTMT stmt,
14898  SQLCHAR *cat, SQLSMALLINT catLen,
14899  SQLCHAR *schema, SQLSMALLINT schemaLen,
14900  SQLCHAR *table, SQLSMALLINT tableLen,
14901  SQLCHAR *col, SQLSMALLINT colLen)
14902 {
14903  SQLRETURN sret;
14904  STMT *s;
14905  DBC *d;
14906  int ret, nrows, ncols, asize, i, k, roffs, namec;
14907  int tnrows, tncols, npatt;
14908  PTRDIFF_T size;
14909  char *errp = NULL, *sql, tname[512], cname[512], **rowp, **trows;
14910 
14911  sret = mkresultset(stmt, colSpec2, array_size(colSpec2),
14912  colSpec3, array_size(colSpec3), &asize);
14913  if (sret != SQL_SUCCESS) {
14914  return sret;
14915  }
14916  s = (STMT *) stmt;
14917  d = (DBC *) s->dbc;
14918  if (!table) {
14919  size = 1;
14920  tname[0] = '%';
14921  } else {
14922  if (tableLen == SQL_NTS) {
14923  size = sizeof (tname) - 1;
14924  } else {
14925  size = min(sizeof (tname) - 1, tableLen);
14926  }
14927  strncpy(tname, (char *) table, size);
14928  }
14929  tname[size] = '\0';
14930  npatt = unescpat(tname);
14931  size = 0;
14932  if (col) {
14933  if (colLen == SQL_NTS) {
14934  size = sizeof (cname) - 1;
14935  } else {
14936  size = min(sizeof (cname) - 1, colLen);
14937  }
14938  strncpy(cname, (char *) col, size);
14939  }
14940  cname[size] = '\0';
14941  if (!strcmp(cname, "%")) {
14942  cname[0] = '\0';
14943  }
14944  sql = sqlite3_mprintf("select tbl_name from sqlite_master where "
14945  "(type = 'table' or type = 'view') "
14946  "and tbl_name %s %Q", npatt ? "like" : "=", tname);
14947  if (!sql) {
14948  return nomem(s);
14949  }
14950  sret = starttran(s);
14951  if (sret != SQL_SUCCESS) {
14952  sqlite3_free(sql);
14953  return sret;
14954  }
14955  dbtraceapi(d, "sqlite3_get_table", sql);
14956  ret = sqlite3_get_table(d->sqlite, sql, &trows, &tnrows, &tncols, &errp);
14957  sqlite3_free(sql);
14958  if (ret != SQLITE_OK) {
14959  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
14960  errp ? errp : "unknown error", ret);
14961  if (errp) {
14962  sqlite3_free(errp);
14963  errp = NULL;
14964  }
14965  return SQL_ERROR;
14966  }
14967  if (errp) {
14968  sqlite3_free(errp);
14969  errp = NULL;
14970  }
14971  /* pass 1: compute number of rows of result set */
14972  if (tncols * tnrows <= 0) {
14973  sqlite3_free_table(trows);
14974  return SQL_SUCCESS;
14975  }
14976  size = 0;
14977  for (i = 1; i <= tnrows; i++) {
14978  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
14979  if (!sql) {
14980  sqlite3_free_table(trows);
14981  return nomem(s);
14982  }
14983  dbtraceapi(d, "sqlite3_get_table", sql);
14984  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
14985  sqlite3_free(sql);
14986  if (ret != SQLITE_OK) {
14987  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
14988  errp ? errp : "unknown error", ret);
14989  if (errp) {
14990  sqlite3_free(errp);
14991  errp = NULL;
14992  }
14993  sqlite3_free_table(trows);
14994  return SQL_ERROR;
14995  }
14996  if (errp) {
14997  sqlite3_free(errp);
14998  errp = NULL;
14999  }
15000  if (ncols * nrows > 0) {
15001  namec = -1;
15002  for (k = 0; k < ncols; k++) {
15003  if (strcmp(rowp[k], "name") == 0) {
15004  namec = k;
15005  break;
15006  }
15007  }
15008  if (cname[0]) {
15009  if (namec >= 0) {
15010  for (k = 1; k <= nrows; k++) {
15011  if (namematch(rowp[k * ncols + namec], cname, 1)) {
15012  size++;
15013  }
15014  }
15015  }
15016  } else {
15017  size += nrows;
15018  }
15019  }
15020  sqlite3_free_table(rowp);
15021  }
15022  /* pass 2: fill result set */
15023  if (size <= 0) {
15024  sqlite3_free_table(trows);
15025  return SQL_SUCCESS;
15026  }
15027  s->nrows = size;
15028  size = (size + 1) * asize;
15029  s->rows = xmalloc((size + 1) * sizeof (char *));
15030  if (!s->rows) {
15031  s->nrows = 0;
15032  sqlite3_free_table(trows);
15033  return nomem(s);
15034  }
15035  s->rows[0] = (char *) size;
15036  s->rows += 1;
15037  memset(s->rows, 0, sizeof (char *) * size);
15038  s->rowfree = freerows;
15039  roffs = 1;
15040  for (i = 1; i <= tnrows; i++) {
15041  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
15042  if (!sql) {
15043  sqlite3_free_table(trows);
15044  return nomem(s);
15045  }
15046  dbtraceapi(d, "sqlite3_get_table", sql);
15047  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15048  sqlite3_free(sql);
15049  if (ret != SQLITE_OK) {
15050  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15051  errp ? errp : "unknown error", ret);
15052  if (errp) {
15053  sqlite3_free(errp);
15054  errp = NULL;
15055  }
15056  sqlite3_free_table(trows);
15057  return SQL_ERROR;
15058  }
15059  if (errp) {
15060  sqlite3_free(errp);
15061  errp = NULL;
15062  }
15063  if (ncols * nrows > 0) {
15064  int m, mr, nr = nrows;
15065 
15066  namec = -1;
15067  for (k = 0; k < ncols; k++) {
15068  if (strcmp(rowp[k], "name") == 0) {
15069  namec = k;
15070  break;
15071  }
15072  }
15073  if (cname[0]) {
15074  nr = 0;
15075  if (namec >= 0) {
15076  for (k = 1; k <= nrows; k++) {
15077  if (namematch(rowp[k * ncols + namec], cname, 1)) {
15078  nr++;
15079  }
15080  }
15081  }
15082  }
15083  for (k = 0; k < nr; k++) {
15084  m = asize * (roffs + k);
15085 #if defined(_WIN32) || defined(_WIN64)
15086  s->rows[m + 0] = xstrdup(d->xcelqrx ? "main" : "");
15087  s->rows[m + 1] = xstrdup("");
15088 #else
15089  s->rows[m + 0] = xstrdup("");
15090  s->rows[m + 1] = xstrdup("");
15091 #endif
15092  s->rows[m + 2] = xstrdup(trows[i]);
15093  s->rows[m + 8] = xstrdup("10");
15094  s->rows[m + 9] = xstrdup("0");
15095  s->rows[m + 15] = xstrdup("16384");
15096  }
15097  for (k = 0; nr && k < ncols; k++) {
15098  if (strcmp(rowp[k], "cid") == 0) {
15099  for (mr = 0, m = 1; m <= nrows; m++) {
15100  char buf[256];
15101  int ir, coln = k;
15102 
15103  if (cname[0] &&
15104  !namematch(rowp[m * ncols + namec], cname, 1)) {
15105  continue;
15106  }
15107  ir = asize * (roffs + mr);
15108  sscanf(rowp[m * ncols + k], "%d", &coln);
15109  sprintf(buf, "%d", coln + 1);
15110  s->rows[ir + 16] = xstrdup(buf);
15111  ++mr;
15112  }
15113  } else if (k == namec) {
15114  for (mr = 0, m = 1; m <= nrows; m++) {
15115  int ir;
15116 
15117  if (cname[0] &&
15118  !namematch(rowp[m * ncols + namec], cname, 1)) {
15119  continue;
15120  }
15121  ir = asize * (roffs + mr);
15122  s->rows[ir + 3] = xstrdup(rowp[m * ncols + k]);
15123  ++mr;
15124  }
15125  } else if (strcmp(rowp[k], "notnull") == 0) {
15126  for (mr = 0, m = 1; m <= nrows; m++) {
15127  int ir;
15128 
15129  if (cname[0] &&
15130  !namematch(rowp[m * ncols + namec], cname, 1)) {
15131  continue;
15132  }
15133  ir = asize * (roffs + mr);
15134  if (*rowp[m * ncols + k] != '0') {
15135  s->rows[ir + 10] = xstrdup(stringify(SQL_FALSE));
15136  } else {
15137  s->rows[ir + 10] = xstrdup(stringify(SQL_TRUE));
15138  }
15139  s->rows[ir + 17] =
15140  xstrdup((*rowp[m * ncols + k] != '0') ?
15141  "NO" : "YES");
15142  ++mr;
15143  }
15144  } else if (strcmp(rowp[k], "dflt_value") == 0) {
15145  for (mr = 0, m = 1; m <= nrows; m++) {
15146  char *dflt = unquote(rowp[m * ncols + k]);
15147  int ir;
15148 
15149  if (cname[0] &&
15150  !namematch(rowp[m * ncols + namec], cname, 1)) {
15151  continue;
15152  }
15153  ir = asize * (roffs + mr);
15154  s->rows[ir + 12] = xstrdup(dflt ? dflt : "NULL");
15155  ++mr;
15156  }
15157  } else if (strcmp(rowp[k], "type") == 0) {
15158  for (mr = 0, m = 1; m <= nrows; m++) {
15159  char *typename = rowp[m * ncols + k];
15160  int sqltype, mm, dd, ir;
15161  char buf[256];
15162 
15163  if (cname[0] &&
15164  !namematch(rowp[m * ncols + namec], cname, 1)) {
15165  continue;
15166  }
15167  ir = asize * (roffs + mr);
15168  s->rows[ir + 5] = xstrdup(typename);
15169  sqltype = mapsqltype(typename, NULL, *s->ov3,
15170  s->nowchar[0], s->dobigint);
15171  getmd(typename, sqltype, &mm, &dd);
15172 #ifdef SQL_LONGVARCHAR
15173  if (sqltype == SQL_VARCHAR && mm > 255) {
15174  sqltype = SQL_LONGVARCHAR;
15175  }
15176 #endif
15177 #ifdef WINTERFACE
15178 #ifdef SQL_WLONGVARCHAR
15179  if (sqltype == SQL_WVARCHAR && mm > 255) {
15180  sqltype = SQL_WLONGVARCHAR;
15181  }
15182 #endif
15183 #endif
15184  if (sqltype == SQL_VARBINARY && mm > 255) {
15185  sqltype = SQL_LONGVARBINARY;
15186  }
15187  sprintf(buf, "%d", sqltype);
15188  s->rows[ir + 4] = xstrdup(buf);
15189  s->rows[ir + 13] = xstrdup(buf);
15190  sprintf(buf, "%d", mm);
15191  s->rows[ir + 7] = xstrdup(buf);
15192  sprintf(buf, "%d", dd);
15193  s->rows[ir + 6] = xstrdup(buf);
15194  ++mr;
15195  }
15196  }
15197  }
15198  roffs += nr;
15199  }
15200  sqlite3_free_table(rowp);
15201  }
15202  sqlite3_free_table(trows);
15203  return SQL_SUCCESS;
15204 }
15205 
15206 #ifndef WINTERFACE
15207 
15221 SQLRETURN SQL_API
15222 SQLColumns(SQLHSTMT stmt,
15223  SQLCHAR *cat, SQLSMALLINT catLen,
15224  SQLCHAR *schema, SQLSMALLINT schemaLen,
15225  SQLCHAR *table, SQLSMALLINT tableLen,
15226  SQLCHAR *col, SQLSMALLINT colLen)
15227 {
15228 #if defined(_WIN32) || defined(_WIN64)
15229  char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15230 #endif
15231  SQLRETURN ret;
15232 
15233  HSTMT_LOCK(stmt);
15234 #if defined(_WIN32) || defined(_WIN64)
15235  if (!((STMT *) stmt)->oemcp[0]) {
15236  ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15237  table, tableLen, col, colLen);
15238  goto done2;
15239  }
15240  if (cat) {
15241  c = wmb_to_utf_c((char *) cat, catLen);
15242  if (!c) {
15243  ret = nomem((STMT *) stmt);
15244  goto done;
15245  }
15246  }
15247  if (schema) {
15248  s = wmb_to_utf_c((char *) schema, schemaLen);
15249  if (!s) {
15250  ret = nomem((STMT *) stmt);
15251  goto done;
15252  }
15253  }
15254  if (table) {
15255  t = wmb_to_utf_c((char *) table, tableLen);
15256  if (!t) {
15257  ret = nomem((STMT *) stmt);
15258  goto done;
15259  }
15260  }
15261  if (col) {
15262  k = wmb_to_utf_c((char *) col, colLen);
15263  if (!k) {
15264  ret = nomem((STMT *) stmt);
15265  goto done;
15266  }
15267  }
15268  ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15269  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15270 #else
15271  ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15272  table, tableLen, col, colLen);
15273 #endif
15274 #if defined(_WIN32) || defined(_WIN64)
15275 done:
15276  uc_free(k);
15277  uc_free(t);
15278  uc_free(s);
15279  uc_free(c);
15280 done2:
15281  ;
15282 #endif
15283  HSTMT_UNLOCK(stmt);
15284  return ret;
15285 }
15286 #endif
15287 
15288 #ifdef WINTERFACE
15289 
15303 SQLRETURN SQL_API
15304 SQLColumnsW(SQLHSTMT stmt,
15305  SQLWCHAR *cat, SQLSMALLINT catLen,
15306  SQLWCHAR *schema, SQLSMALLINT schemaLen,
15307  SQLWCHAR *table, SQLSMALLINT tableLen,
15308  SQLWCHAR *col, SQLSMALLINT colLen)
15309 {
15310  char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15311  SQLRETURN ret;
15312 
15313  HSTMT_LOCK(stmt);
15314  if (cat) {
15315  c = uc_to_utf_c(cat, catLen);
15316  if (!c) {
15317  ret = nomem((STMT *) stmt);
15318  goto done;
15319  }
15320  }
15321  if (schema) {
15322  s = uc_to_utf_c(schema, schemaLen);
15323  if (!s) {
15324  ret = nomem((STMT *) stmt);
15325  goto done;
15326  }
15327  }
15328  if (table) {
15329  t = uc_to_utf_c(table, tableLen);
15330  if (!t) {
15331  ret = nomem((STMT *) stmt);
15332  goto done;
15333  }
15334  }
15335  if (col) {
15336  k = uc_to_utf_c(col, colLen);
15337  if (!k) {
15338  ret = nomem((STMT *) stmt);
15339  goto done;
15340  }
15341  }
15342  ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15343  (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15344 done:
15345  uc_free(k);
15346  uc_free(t);
15347  uc_free(s);
15348  uc_free(c);
15349  HSTMT_UNLOCK(stmt);
15350  return ret;
15351 
15352 }
15353 #endif
15354 
15359 static COL typeSpec2[] = {
15360  { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15361  { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15362  { "SYSTEM", "TYPE", "PRECISION", SQL_INTEGER, 9 },
15363  { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15364  { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15365  { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15366  { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15367  { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15368  { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15369  { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15370  { "SYSTEM", "TYPE", "MONEY", SQL_SMALLINT, 2 },
15371  { "SYSTEM", "TYPE", "AUTO_INCREMENT", SQL_SMALLINT, 2 },
15372  { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15373  { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15374  { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 }
15375 };
15376 
15377 static COL typeSpec3[] = {
15378  { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15379  { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15380  { "SYSTEM", "TYPE", "COLUMN_SIZE", SQL_INTEGER, 9 },
15381  { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15382  { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15383  { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15384  { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15385  { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15386  { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15387  { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15388  { "SYSTEM", "TYPE", "FIXED_PREC_SCALE", SQL_SMALLINT, 2 },
15389  { "SYSTEM", "TYPE", "AUTO_UNIQUE_VALUE", SQL_SMALLINT, 2 },
15390  { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15391  { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15392  { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 },
15393  { "SYSTEM", "TYPE", "SQL_DATA_TYPE", SQL_SMALLINT, 2 },
15394  { "SYSTEM", "TYPE", "SQL_DATETIME_SUB", SQL_SMALLINT, 2 },
15395  { "SYSTEM", "TYPE", "NUM_PREC_RADIX", SQL_INTEGER, 4 },
15396  { "SYSTEM", "TYPE", "INTERVAL_PRECISION", SQL_SMALLINT, 2 }
15397 };
15398 
15409 static void
15410 mktypeinfo(STMT *s, int row, int asize, char *typename, int type, int tind)
15411 {
15412  int offs = row * asize;
15413  char *tcode, *crpar = NULL, *quote = NULL, *sign = stringify(SQL_FALSE);
15414  static char tcodes[32 * 32];
15415 
15416  if (tind <= 0) {
15417  tind = row;
15418  }
15419  tcode = tcodes + tind * 32;
15420  sprintf(tcode, "%d", type);
15421  s->rows[offs + 0] = typename;
15422  s->rows[offs + 1] = tcode;
15423  if (asize >= 17) {
15424  s->rows[offs + 15] = tcode;
15425  s->rows[offs + 16] = "0";
15426  }
15427  switch (type) {
15428  default:
15429 #ifdef SQL_LONGVARCHAR
15430  case SQL_LONGVARCHAR:
15431 #ifdef WINTERFACE
15432  case SQL_WLONGVARCHAR:
15433 #endif
15434  crpar = "length";
15435  quote = "'";
15436  sign = NULL;
15437  s->rows[offs + 2] = "65536";
15438  break;
15439 #endif
15440 #ifdef SQL_BIT
15441  case SQL_BIT:
15442  sign = NULL;
15443  s->rows[offs + 2] = "1";
15444  break;
15445 #endif
15446  case SQL_CHAR:
15447  case SQL_VARCHAR:
15448 #ifdef WINTERFACE
15449  case SQL_WCHAR:
15450  case SQL_WVARCHAR:
15451 #endif
15452  s->rows[offs + 2] = "255";
15453  crpar = "length";
15454  quote = "'";
15455  sign = NULL;
15456  break;
15457  case SQL_TINYINT:
15458  s->rows[offs + 2] = "3";
15459  break;
15460  case SQL_SMALLINT:
15461  s->rows[offs + 2] = "5";
15462  break;
15463  case SQL_INTEGER:
15464  s->rows[offs + 2] = "9";
15465  break;
15466 #ifdef SQL_BIGINT
15467  case SQL_BIGINT:
15468  s->rows[offs + 2] = "19";
15469  break;
15470 #endif
15471  case SQL_FLOAT:
15472  s->rows[offs + 2] = "7";
15473  break;
15474  case SQL_DOUBLE:
15475  s->rows[offs + 2] = "15";
15476  break;
15477 #ifdef SQL_TYPE_DATE
15478  case SQL_TYPE_DATE:
15479 #endif
15480  case SQL_DATE:
15481  s->rows[offs + 2] = "10";
15482  quote = "'";
15483  sign = NULL;
15484  break;
15485 #ifdef SQL_TYPE_TIME
15486  case SQL_TYPE_TIME:
15487 #endif
15488  case SQL_TIME:
15489  s->rows[offs + 2] = "8";
15490  quote = "'";
15491  sign = NULL;
15492  break;
15493 #ifdef SQL_TYPE_TIMESTAMP
15494  case SQL_TYPE_TIMESTAMP:
15495 #endif
15496  case SQL_TIMESTAMP:
15497  s->rows[offs + 2] = "32";
15498  quote = "'";
15499  sign = NULL;
15500  break;
15501  case SQL_VARBINARY:
15502  sign = NULL;
15503  s->rows[offs + 2] = "255";
15504  break;
15505  case SQL_LONGVARBINARY:
15506  sign = NULL;
15507  s->rows[offs + 2] = "65536";
15508  break;
15509  }
15510  s->rows[offs + 3] = s->rows[offs + 4] = quote;
15511  s->rows[offs + 5] = crpar;
15512  s->rows[offs + 6] = stringify(SQL_NULLABLE);
15513  s->rows[offs + 7] = stringify(SQL_FALSE);
15514  s->rows[offs + 8] = stringify(SQL_SEARCHABLE);
15515  s->rows[offs + 9] = sign;
15516  s->rows[offs + 10] = stringify(SQL_FALSE);
15517  s->rows[offs + 11] = stringify(SQL_FALSE);
15518  s->rows[offs + 12] = typename;
15519  switch (type) {
15520  case SQL_DATE:
15521  case SQL_TIME:
15522  s->rows[offs + 13] = "0";
15523  s->rows[offs + 14] = "0";
15524  break;
15525 #ifdef SQL_TYPE_TIMESTAMP
15526  case SQL_TYPE_TIMESTAMP:
15527 #endif
15528  case SQL_TIMESTAMP:
15529  s->rows[offs + 13] = "0";
15530  s->rows[offs + 14] = "3";
15531  break;
15532  default:
15533  s->rows[offs + 13] = NULL;
15534  s->rows[offs + 14] = NULL;
15535  break;
15536  }
15537 }
15538 
15547 static int
15548 typeinfosort(const void *a, const void *b)
15549 {
15550  char **pa = (char **) a;
15551  char **pb = (char **) b;
15552  int na, nb;
15553 
15554  na = strtol(pa[1], NULL, 0);
15555  nb = strtol(pb[1], NULL, 0);
15556  return na - nb;
15557 }
15558 
15566 static SQLRETURN
15567 drvgettypeinfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
15568 {
15569  SQLRETURN ret;
15570  STMT *s;
15571  int asize;
15572 
15573  ret = mkresultset(stmt, typeSpec2, array_size(typeSpec2),
15574  typeSpec3, array_size(typeSpec3), &asize);
15575  if (ret != SQL_SUCCESS) {
15576  return ret;
15577  }
15578  s = (STMT *) stmt;
15579 #ifdef SQL_LONGVARCHAR
15580  s->nrows = (sqltype == SQL_ALL_TYPES) ? 13 : 1;
15581 #else
15582  s->nrows = (sqltype == SQL_ALL_TYPES) ? 12 : 1;
15583 #endif
15584  if (sqltype == SQL_ALL_TYPES) {
15585 #ifdef WINTERFACE
15586  s->nrows += 2;
15587 #ifdef SQL_WLONGVARCHAR
15588  s->nrows += 2;
15589 #endif
15590 #endif
15591  }
15592  if (sqltype == SQL_ALL_TYPES) {
15593  s->nrows += 2;
15594 #ifdef SQL_BIT
15595  s->nrows += 1;
15596 #endif
15597 #ifdef SQL_BIGINT
15598  s->nrows += 1;
15599 #endif
15600  }
15601  s->rows = (char **) xmalloc(sizeof (char *) * (s->nrows + 1) * asize);
15602  if (!s->rows) {
15603  s->nrows = 0;
15604  return nomem(s);
15605  }
15606 #ifdef MEMORY_DEBUG
15607  s->rowfree = xfree__;
15608 #else
15609  s->rowfree = sqlite3_free;
15610 #endif
15611  memset(s->rows, 0, sizeof (char *) * (s->nrows + 1) * asize);
15612  if (sqltype == SQL_ALL_TYPES) {
15613  int cc = 1;
15614 
15615  mktypeinfo(s, cc++, asize, "varchar", SQL_VARCHAR, 0);
15616  mktypeinfo(s, cc++, asize, "tinyint", SQL_TINYINT, 0);
15617  mktypeinfo(s, cc++, asize, "smallint", SQL_SMALLINT, 0);
15618  mktypeinfo(s, cc++, asize, "integer", SQL_INTEGER, 0);
15619  mktypeinfo(s, cc++, asize, "float", SQL_FLOAT, 0);
15620  mktypeinfo(s, cc++, asize, "double", SQL_DOUBLE, 0);
15621 #ifdef SQL_TYPE_DATE
15622  mktypeinfo(s, cc++, asize, "date",
15623  (*s->ov3) ? SQL_TYPE_DATE : SQL_DATE, 0);
15624 #else
15625  mktypeinfo(s, cc++, asize, "date", SQL_DATE, 0);
15626 #endif
15627 #ifdef SQL_TYPE_TIME
15628  mktypeinfo(s, cc++, asize, "time",
15629  (*s->ov3) ? SQL_TYPE_TIME : SQL_TIME, 0);
15630 #else
15631  mktypeinfo(s, cc++, asize, "time", SQL_TIME, 0);
15632 #endif
15633 #ifdef SQL_TYPE_TIMESTAMP
15634  mktypeinfo(s, cc++, asize, "timestamp",
15635  (*s->ov3) ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP, 0);
15636 #else
15637  mktypeinfo(s, cc++, asize, "timestamp", SQL_TIMESTAMP, 0);
15638 #endif
15639  mktypeinfo(s, cc++, asize, "char", SQL_CHAR, 0);
15640  mktypeinfo(s, cc++, asize, "numeric", SQL_DOUBLE, 0);
15641 #ifdef SQL_LONGVARCHAR
15642  mktypeinfo(s, cc++, asize, "text", SQL_LONGVARCHAR, 0);
15643  mktypeinfo(s, cc++, asize, "longvarchar", SQL_LONGVARCHAR, 0);
15644 #else
15645  mktypeinfo(s, cc++, asize, "text", SQL_VARCHAR, 0);
15646 #endif
15647  mktypeinfo(s, cc++, asize, "varbinary", SQL_VARBINARY, 0);
15648  mktypeinfo(s, cc++, asize, "longvarbinary", SQL_LONGVARBINARY, 0);
15649 #ifdef SQL_BIT
15650  mktypeinfo(s, cc++, asize, "bit", SQL_BIT, 0);
15651 #endif
15652 #ifdef SQL_BIGINT
15653  mktypeinfo(s, cc++, asize, "bigint", SQL_BIGINT, 0);
15654 #endif
15655 #ifdef WINTERFACE
15656  mktypeinfo(s, cc++, asize, "wvarchar", SQL_WVARCHAR, 0);
15657  mktypeinfo(s, cc++, asize, "wchar", SQL_WCHAR, 0);
15658 #ifdef SQL_WLONGVARCHAR
15659  mktypeinfo(s, cc++, asize, "wtext", SQL_WLONGVARCHAR, 0);
15660  mktypeinfo(s, cc++, asize, "longwvarchar", SQL_WLONGVARCHAR, 0);
15661 #endif
15662 #endif
15663  qsort(s->rows + asize, s->nrows, sizeof (char *) * asize,
15664  typeinfosort);
15665  } else {
15666  switch (sqltype) {
15667  case SQL_CHAR:
15668  mktypeinfo(s, 1, asize, "char", SQL_CHAR, 10);
15669  break;
15670  case SQL_VARCHAR:
15671  mktypeinfo(s, 1, asize, "varchar", SQL_VARCHAR, 1);
15672  break;
15673  case SQL_TINYINT:
15674  mktypeinfo(s, 1, asize, "tinyint", SQL_TINYINT, 2);
15675  break;
15676  case SQL_SMALLINT:
15677  mktypeinfo(s, 1, asize, "smallint", SQL_SMALLINT, 3);
15678  break;
15679  case SQL_INTEGER:
15680  mktypeinfo(s, 1, asize, "integer", SQL_INTEGER, 4);
15681  break;
15682  case SQL_FLOAT:
15683  mktypeinfo(s, 1, asize, "float", SQL_FLOAT, 5);
15684  break;
15685  case SQL_DOUBLE:
15686  mktypeinfo(s, 1, asize, "double", SQL_DOUBLE, 6);
15687  break;
15688 #ifdef SQL_TYPE_DATE
15689  case SQL_TYPE_DATE:
15690  mktypeinfo(s, 1, asize, "date", SQL_TYPE_DATE, 25);
15691  break;
15692 #endif
15693  case SQL_DATE:
15694  mktypeinfo(s, 1, asize, "date", SQL_DATE, 7);
15695  break;
15696 #ifdef SQL_TYPE_TIME
15697  case SQL_TYPE_TIME:
15698  mktypeinfo(s, 1, asize, "time", SQL_TYPE_TIME, 26);
15699  break;
15700 #endif
15701  case SQL_TIME:
15702  mktypeinfo(s, 1, asize, "time", SQL_TIME, 8);
15703  break;
15704 #ifdef SQL_TYPE_TIMESTAMP
15705  case SQL_TYPE_TIMESTAMP:
15706  mktypeinfo(s, 1, asize, "timestamp", SQL_TYPE_TIMESTAMP, 27);
15707  break;
15708 #endif
15709  case SQL_TIMESTAMP:
15710  mktypeinfo(s, 1, asize, "timestamp", SQL_TIMESTAMP, 9);
15711  break;
15712 #ifdef SQL_LONGVARCHAR
15713  case SQL_LONGVARCHAR:
15714  mktypeinfo(s, 1, asize, "longvarchar", SQL_LONGVARCHAR, 12);
15715  break;
15716 #endif
15717  case SQL_VARBINARY:
15718  mktypeinfo(s, 1, asize, "varbinary", SQL_VARBINARY, 30);
15719  break;
15720  case SQL_LONGVARBINARY:
15721  mktypeinfo(s, 1, asize, "longvarbinary", SQL_LONGVARBINARY, 31);
15722  break;
15723 #ifdef SQL_BIT
15724  case SQL_BIT:
15725  mktypeinfo(s, 1, asize, "bit", SQL_BIT, 29);
15726  break;
15727 #endif
15728 #ifdef SQL_BIGINT
15729  case SQL_BIGINT:
15730  mktypeinfo(s, 1, asize, "bigint", SQL_BIGINT, 28);
15731  break;
15732 #endif
15733 #ifdef WINTERFACE
15734 #ifdef SQL_WCHAR
15735  case SQL_WCHAR:
15736  mktypeinfo(s, 1, asize, "wchar", SQL_WCHAR, 18);
15737  break;
15738 #endif
15739 #ifdef SQL_WVARCHAR
15740  case SQL_WVARCHAR:
15741  mktypeinfo(s, 1, asize, "wvarchar", SQL_WVARCHAR, 19);
15742  break;
15743 #endif
15744 #ifdef SQL_WLONGVARCHAR
15745  case SQL_WLONGVARCHAR:
15746  mktypeinfo(s, 1, asize, "longwvarchar", SQL_WLONGVARCHAR, 20);
15747  break;
15748 #endif
15749 #endif
15750  default:
15751  s->nrows = 0;
15752  }
15753  }
15754  return SQL_SUCCESS;
15755 }
15756 
15757 #ifndef WINTERFACE
15758 
15765 SQLRETURN SQL_API
15766 SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
15767 {
15768  SQLRETURN ret;
15769 
15770  HSTMT_LOCK(stmt);
15771  ret = drvgettypeinfo(stmt, sqltype);
15772  HSTMT_UNLOCK(stmt);
15773  return ret;
15774 }
15775 #endif
15776 
15777 #ifdef WINTERFACE
15778 
15785 SQLRETURN SQL_API
15786 SQLGetTypeInfoW(SQLHSTMT stmt, SQLSMALLINT sqltype)
15787 {
15788  SQLRETURN ret;
15789 
15790  HSTMT_LOCK(stmt);
15791  ret = drvgettypeinfo(stmt, sqltype);
15792  HSTMT_UNLOCK(stmt);
15793  return ret;
15794 }
15795 #endif
15796 
15801 static COL statSpec2[] = {
15802  { "SYSTEM", "STATISTICS", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
15803  { "SYSTEM", "STATISTICS", "TABLE_OWNER", 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", "SEQ_IN_INDEX", SQL_SMALLINT, 50 },
15810  { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15811  { "SYSTEM", "STATISTICS", "COLLATION", 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 
15817 static COL statSpec3[] = {
15818  { "SYSTEM", "STATISTICS", "TABLE_CAT", SCOL_VARCHAR, 50 },
15819  { "SYSTEM", "STATISTICS", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
15820  { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
15821  { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
15822  { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
15823  { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
15824  { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
15825  { "SYSTEM", "STATISTICS", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
15826  { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15827  { "SYSTEM", "STATISTICS", "ASC_OR_DESC", SCOL_CHAR, 1 },
15828  { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
15829  { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
15830  { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
15831 };
15832 
15847 static SQLRETURN
15848 drvstatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
15849  SQLCHAR *schema, SQLSMALLINT schemaLen,
15850  SQLCHAR *table, SQLSMALLINT tableLen,
15851  SQLUSMALLINT itype, SQLUSMALLINT resv)
15852 {
15853  SQLRETURN sret;
15854  STMT *s;
15855  DBC *d;
15856  int i, asize, ret, nrows, ncols, offs, namec, uniquec, addipk = 0;
15857  PTRDIFF_T size;
15858  char **rowp, *errp = NULL, *sql, tname[512];
15859 
15860  sret = mkresultset(stmt, statSpec2, array_size(statSpec2),
15861  statSpec3, array_size(statSpec3), &asize);
15862  if (sret != SQL_SUCCESS) {
15863  return sret;
15864  }
15865  s = (STMT *) stmt;
15866  d = (DBC *) s->dbc;
15867  if (!table || table[0] == '\0' || table[0] == '%') {
15868  setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
15869  return SQL_ERROR;
15870  }
15871  if (tableLen == SQL_NTS) {
15872  size = sizeof (tname) - 1;
15873  } else {
15874  size = min(sizeof (tname) - 1, tableLen);
15875  }
15876  strncpy(tname, (char *) table, size);
15877  tname[size] = '\0';
15878  unescpat(tname);
15879  sret = starttran(s);
15880  if (sret != SQL_SUCCESS) {
15881  return sret;
15882  }
15883  /*
15884  * Try integer primary key (autoincrement) first
15885  */
15886  if (itype == SQL_INDEX_UNIQUE || itype == SQL_INDEX_ALL) {
15887  rowp = 0;
15888  ret = SQLITE_ERROR;
15889  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
15890  if (sql) {
15891  dbtraceapi(d, "sqlite3_get_table", sql);
15892  ret = sqlite3_get_table(d->sqlite, sql, &rowp,
15893  &nrows, &ncols, NULL);
15894  sqlite3_free(sql);
15895  }
15896  if (ret == SQLITE_OK) {
15897  int colid, typec, npk = 0, npkint = 0;
15898 
15899  namec = findcol(rowp, ncols, "name");
15900  uniquec = findcol(rowp, ncols, "pk");
15901  typec = findcol(rowp, ncols, "type");
15902  colid = findcol(rowp, ncols, "cid");
15903  if (namec < 0 || uniquec < 0 || typec < 0 || colid < 0) {
15904  goto noipk;
15905  }
15906  for (i = 1; i <= nrows; i++) {
15907  if (*rowp[i * ncols + uniquec] != '0') {
15908  npk++;
15909  if (strlen(rowp[i * ncols + typec]) == 7 &&
15910  strncasecmp(rowp[i * ncols + typec], "integer", 7)
15911  == 0) {
15912  npkint++;
15913  }
15914  }
15915  }
15916  if (npkint == 1 && npk == npkint) {
15917  addipk = 1;
15918  }
15919  }
15920 noipk:
15921  sqlite3_free_table(rowp);
15922  }
15923  sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
15924  if (!sql) {
15925  return nomem(s);
15926  }
15927  dbtraceapi(d, "sqlite3_get_table", sql);
15928  ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15929  sqlite3_free(sql);
15930  if (ret != SQLITE_OK) {
15931  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15932  errp ? errp : "unknown error", ret);
15933  if (errp) {
15934  sqlite3_free(errp);
15935  errp = NULL;
15936  }
15937  return SQL_ERROR;
15938  }
15939  if (errp) {
15940  sqlite3_free(errp);
15941  errp = NULL;
15942  }
15943  size = 0;
15944  namec = findcol(rowp, ncols, "name");
15945  uniquec = findcol(rowp, ncols, "unique");
15946  if (namec < 0 || uniquec < 0) {
15947  goto nodata;
15948  }
15949  for (i = 1; i <= nrows; i++) {
15950  int nnrows, nncols;
15951  char **rowpp;
15952  int isuniq;
15953 
15954  isuniq = *rowp[i * ncols + uniquec] != '0';
15955  if (isuniq || itype == SQL_INDEX_ALL) {
15956  ret = SQLITE_ERROR;
15957  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
15958  rowp[i * ncols + namec]);
15959  if (sql) {
15960  dbtraceapi(d, "sqlite3_get_table", sql);
15961  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
15962  &nnrows, &nncols, NULL);
15963  sqlite3_free(sql);
15964  }
15965  if (ret == SQLITE_OK) {
15966  size += nnrows;
15967  sqlite3_free_table(rowpp);
15968  }
15969  }
15970  }
15971 nodata:
15972  if (addipk) {
15973  size++;
15974  }
15975  if (size == 0) {
15976  sqlite3_free_table(rowp);
15977  return SQL_SUCCESS;
15978  }
15979  s->nrows = size;
15980  size = (size + 1) * asize;
15981  s->rows = xmalloc((size + 1) * sizeof (char *));
15982  if (!s->rows) {
15983  s->nrows = 0;
15984  return nomem(s);
15985  }
15986  s->rows[0] = (char *) size;
15987  s->rows += 1;
15988  memset(s->rows, 0, sizeof (char *) * size);
15989  s->rowfree = freerows;
15990  offs = 0;
15991  if (addipk) {
15992  char **rowpp = 0;
15993  int nrows2, ncols2;
15994 
15995  sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
15996  if (sql) {
15997  dbtraceapi(d, "sqlite3_get_table", sql);
15998  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
15999  &nrows2, &ncols2, NULL);
16000  sqlite3_free(sql);
16001  }
16002  if (ret == SQLITE_OK) {
16003  int colid, typec, roffs, namecc, uniquecc;
16004 
16005  namecc = findcol(rowpp, ncols2, "name");
16006  uniquecc = findcol(rowpp, ncols2, "pk");
16007  typec = findcol(rowpp, ncols2, "type");
16008  colid = findcol(rowpp, ncols2, "cid");
16009  if (namecc < 0 || uniquecc < 0 || typec < 0 || colid < 0) {
16010  addipk = 0;
16011  s->nrows--;
16012  goto nodata2;
16013  }
16014  for (i = 1; i <= nrows2; i++) {
16015  if (*rowpp[i * ncols2 + uniquecc] != '0' &&
16016  strlen(rowpp[i * ncols2 + typec]) == 7 &&
16017  strncasecmp(rowpp[i * ncols2 + typec], "integer", 7)
16018  == 0) {
16019  break;
16020  }
16021  }
16022  if (i > nrows2) {
16023  addipk = 0;
16024  s->nrows--;
16025  goto nodata2;
16026  }
16027  roffs = s->ncols;
16028 #if defined(_WIN32) || defined(_WIN64)
16029  s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
16030  s->rows[roffs + 1] = xstrdup("");
16031 #else
16032  s->rows[roffs + 0] = xstrdup("");
16033  s->rows[roffs + 1] = xstrdup("");
16034 #endif
16035  s->rows[roffs + 2] = xstrdup(tname);
16036  s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16037  s->rows[roffs + 5] = xstrdup("sqlite_autoindex_0");
16038  s->rows[roffs + 6] = xstrdup(stringify(SQL_INDEX_OTHER));
16039  s->rows[roffs + 7] = xstrdup("1");
16040  s->rows[roffs + 8] = xstrdup(rowpp[i * ncols2 + namecc]);
16041  s->rows[roffs + 9] = xstrdup("A");
16042  }
16043 nodata2:
16044  sqlite3_free_table(rowpp);
16045  }
16046  for (i = 1; i <= nrows; i++) {
16047  int nnrows, nncols;
16048  char **rowpp = 0;
16049 
16050  if (*rowp[i * ncols + uniquec] != '0' || itype == SQL_INDEX_ALL) {
16051  int k;
16052 
16053  ret = SQLITE_ERROR;
16054  sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
16055  rowp[i * ncols + namec]);
16056  if (sql) {
16057  dbtraceapi(d, "sqlite3_get_table", sql);
16058  ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16059  &nnrows, &nncols, NULL);
16060  sqlite3_free(sql);
16061  }
16062  if (ret != SQLITE_OK) {
16063  continue;
16064  }
16065  for (k = 0; nnrows && k < nncols; k++) {
16066  if (strcmp(rowpp[k], "name") == 0) {
16067  int m;
16068 
16069  for (m = 1; m <= nnrows; m++) {
16070  int roffs = (offs + addipk + m) * s->ncols;
16071  int isuniq;
16072 
16073  isuniq = *rowp[i * ncols + uniquec] != '0';
16074  s->rows[roffs + 0] = xstrdup("");
16075  s->rows[roffs + 1] = xstrdup("");
16076  s->rows[roffs + 2] = xstrdup(tname);
16077  if (isuniq) {
16078  s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16079  } else {
16080  s->rows[roffs + 3] = xstrdup(stringify(SQL_TRUE));
16081  }
16082  s->rows[roffs + 5] = xstrdup(rowp[i * ncols + namec]);
16083  s->rows[roffs + 6] =
16084  xstrdup(stringify(SQL_INDEX_OTHER));
16085  s->rows[roffs + 8] = xstrdup(rowpp[m * nncols + k]);
16086  s->rows[roffs + 9] = xstrdup("A");
16087  }
16088  } else if (strcmp(rowpp[k], "seqno") == 0) {
16089  int m;
16090 
16091  for (m = 1; m <= nnrows; m++) {
16092  int roffs = (offs + addipk + m) * s->ncols;
16093  int pos = m - 1;
16094  char buf[32];
16095 
16096  sscanf(rowpp[m * nncols + k], "%d", &pos);
16097  sprintf(buf, "%d", pos + 1);
16098  s->rows[roffs + 7] = xstrdup(buf);
16099  }
16100  }
16101  }
16102  offs += nnrows;
16103  sqlite3_free_table(rowpp);
16104  }
16105  }
16106  sqlite3_free_table(rowp);
16107  return SQL_SUCCESS;
16108 }
16109 
16110 #ifndef WINTERFACE
16111 
16125 SQLRETURN SQL_API
16126 SQLStatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
16127  SQLCHAR *schema, SQLSMALLINT schemaLen,
16128  SQLCHAR *table, SQLSMALLINT tableLen,
16129  SQLUSMALLINT itype, SQLUSMALLINT resv)
16130 {
16131 #if defined(_WIN32) || defined(_WIN64)
16132  char *c = NULL, *s = NULL, *t = NULL;
16133 #endif
16134  SQLRETURN ret;
16135 
16136  HSTMT_LOCK(stmt);
16137 #if defined(_WIN32) || defined(_WIN64)
16138  if (!((STMT *) stmt)->oemcp[0]) {
16139  ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16140  table, tableLen, itype, resv);
16141  goto done2;
16142  }
16143  if (cat) {
16144  c = wmb_to_utf_c((char *) cat, catLen);
16145  if (!c) {
16146  ret = nomem((STMT *) stmt);
16147  goto done;
16148  }
16149  }
16150  if (schema) {
16151  s = wmb_to_utf_c((char *) schema, schemaLen);
16152  if (!s) {
16153  ret = nomem((STMT *) stmt);
16154  goto done;
16155  }
16156  }
16157  if (table) {
16158  t = wmb_to_utf_c((char *) table, tableLen);
16159  if (!t) {
16160  ret = nomem((STMT *) stmt);
16161  goto done;
16162  }
16163  }
16164  ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16165  (SQLCHAR *) t, SQL_NTS, itype, resv);
16166 #else
16167  ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16168  table, tableLen, itype, resv);
16169 #endif
16170 #if defined(_WIN32) || defined(_WIN64)
16171 done:
16172  uc_free(t);
16173  uc_free(s);
16174  uc_free(c);
16175 done2:
16176  ;
16177 #endif
16178  HSTMT_UNLOCK(stmt);
16179  return ret;
16180 }
16181 #endif
16182 
16183 #ifdef WINTERFACE
16184 
16198 SQLRETURN SQL_API
16199 SQLStatisticsW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen,
16200  SQLWCHAR *schema, SQLSMALLINT schemaLen,
16201  SQLWCHAR *table, SQLSMALLINT tableLen,
16202  SQLUSMALLINT itype, SQLUSMALLINT resv)
16203 {
16204  char *c = NULL, *s = NULL, *t = NULL;
16205  SQLRETURN ret;
16206 
16207  HSTMT_LOCK(stmt);
16208  if (cat) {
16209  c = uc_to_utf_c(cat, catLen);
16210  if (!c) {
16211  ret = nomem((STMT *) stmt);
16212  goto done;
16213  }
16214  }
16215  if (schema) {
16216  s = uc_to_utf_c(schema, schemaLen);
16217  if (!s) {
16218  ret = nomem((STMT *) stmt);
16219  goto done;
16220  }
16221  }
16222  if (table) {
16223  t = uc_to_utf_c(table, tableLen);
16224  if (!t) {
16225  ret = nomem((STMT *) stmt);
16226  goto done;
16227  }
16228  }
16229  ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16230  (SQLCHAR *) t, SQL_NTS, itype, resv);
16231 done:
16232  uc_free(t);
16233  uc_free(s);
16234  uc_free(c);
16235  HSTMT_UNLOCK(stmt);
16236  return ret;
16237 }
16238 #endif
16239 
16251 SQLRETURN SQL_API
16252 SQLGetData(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
16253  SQLPOINTER val, SQLLEN len, SQLLEN *lenp)
16254 {
16255  STMT *s;
16256  SQLRETURN ret = SQL_ERROR;
16257 
16258  HSTMT_LOCK(stmt);
16259  if (stmt == SQL_NULL_HSTMT) {
16260  return SQL_INVALID_HANDLE;
16261  }
16262  s = (STMT *) stmt;
16263  if (col == 0 && s->bkmrk != SQL_UB_OFF) {
16264  if (s->bkmrk == SQL_UB_ON && type == SQL_C_BOOKMARK) {
16265  *((SQLINTEGER *) val) = s->rowp;
16266  if (lenp) {
16267  *lenp = sizeof (SQLINTEGER);
16268  }
16269  ret = SQL_SUCCESS;
16270  goto done;
16271  } else if (s->bkmrk == SQL_UB_VARIABLE && type == SQL_C_VARBOOKMARK) {
16272  if (s->has_rowid >= 0) {
16273  char **data, *endp = 0;
16274 
16275  data = s->rows + s->ncols + (s->rowp * s->ncols)
16276  + s->has_rowid;
16277 #ifdef __osf__
16278  *((sqlite_int64 *) val) = strtol(*data, &endp, 0);
16279 #else
16280  *((sqlite_int64 *) val) = strtoll(*data, &endp, 0);
16281 #endif
16282  } else {
16283  *((sqlite_int64 *) val) = s->rowp;
16284  }
16285  if (lenp) {
16286  *lenp = sizeof (sqlite_int64);
16287  }
16288  ret = SQL_SUCCESS;
16289  goto done;
16290  }
16291  }
16292  if (col < 1 || col > s->ncols) {
16293  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
16294  goto done;
16295  }
16296  --col;
16297  ret = getrowdata(s, col, type, val, len, lenp, 1);
16298 done:
16299  HSTMT_UNLOCK(stmt);
16300  return ret;
16301 }
16302 
16310 static SQLRETURN
16311 dofetchbind(STMT *s, int rsi)
16312 {
16313  int ret, i, withinfo = 0;
16314 
16315  s->row_status0[rsi] = SQL_ROW_SUCCESS;
16316  if (s->bkmrk != SQL_UB_OFF && s->bkmrkcol.valp) {
16317  int bsize = sizeof (SQLINTEGER);
16318 
16319  if (s->bkmrkcol.type == SQL_C_VARBOOKMARK) {
16320  SQLPOINTER *val;
16321 
16322  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16323  val = (SQLPOINTER)
16324  ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16325  } else {
16326  val = (SQLPOINTER)
16327  ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * rsi);
16328  }
16329  if (s->bind_offs) {
16330  val = (SQLPOINTER) ((char *) val + *s->bind_offs);
16331  }
16332  if (s->has_rowid >= 0) {
16333  char **data, *endp = 0;
16334 
16335  data = s->rows + s->ncols + (s->rowp * s->ncols)
16336  + s->has_rowid;
16337 #ifdef __osf__
16338  *(sqlite_int64 *) val = strtol(*data, &endp, 0);
16339 #else
16340  *(sqlite_int64 *) val = strtoll(*data, &endp, 0);
16341 #endif
16342  } else {
16343  *(sqlite_int64 *) val = s->rowp;
16344  }
16345  bsize = sizeof (sqlite_int64);
16346  } else {
16347  SQLINTEGER *val;
16348 
16349  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16350  val = (SQLINTEGER *)
16351  ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16352  } else {
16353  val = (SQLINTEGER *) s->bkmrkcol.valp + rsi;
16354  }
16355  if (s->bind_offs) {
16356  val = (SQLINTEGER *) ((char *) val + *s->bind_offs);
16357  }
16358  *val = s->rowp;
16359  }
16360  if (s->bkmrkcol.lenp) {
16361  SQLLEN *ival;
16362 
16363  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16364  ival = (SQLLEN *)
16365  ((char *) s->bkmrkcol.lenp + s->bind_type * rsi);
16366  } else {
16367  ival = &s->bkmrkcol.lenp[rsi];
16368  }
16369  if (s->bind_offs) {
16370  ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
16371  }
16372  *ival = bsize;
16373  }
16374  }
16375  ret = SQL_SUCCESS;
16376  for (i = 0; s->bindcols && i < s->ncols; i++) {
16377  BINDCOL *b = &s->bindcols[i];
16378  SQLPOINTER dp = 0;
16379  SQLLEN *lp = 0;
16380 
16381  b->offs = 0;
16382  if (b->valp) {
16383  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16384  dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
16385  } else {
16386  dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
16387  }
16388  if (s->bind_offs) {
16389  dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
16390  }
16391  }
16392  if (b->lenp) {
16393  if (s->bind_type != SQL_BIND_BY_COLUMN) {
16394  lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
16395  } else {
16396  lp = b->lenp + rsi;
16397  }
16398  if (s->bind_offs) {
16399  lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
16400  }
16401  }
16402  if (dp || lp) {
16403  ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp, b->max, lp, 0);
16404  if (!SQL_SUCCEEDED(ret)) {
16405  s->row_status0[rsi] = SQL_ROW_ERROR;
16406  break;
16407  }
16408  if (ret != SQL_SUCCESS) {
16409  withinfo = 1;
16410 #ifdef SQL_ROW_SUCCESS_WITH_INFO
16411  s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
16412 #endif
16413  }
16414  }
16415  }
16416  if (SQL_SUCCEEDED(ret)) {
16417  ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16418  }
16419  return ret;
16420 }
16421 
16430 static SQLRETURN
16431 drvfetchscroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLINTEGER offset)
16432 {
16433  STMT *s;
16434  int i, withinfo = 0;
16435  SQLRETURN ret;
16436 
16437  if (stmt == SQL_NULL_HSTMT) {
16438  return SQL_INVALID_HANDLE;
16439  }
16440  s = (STMT *) stmt;
16441  for (i = 0; i < s->rowset_size; i++) {
16442  s->row_status0[i] = SQL_ROW_NOROW;
16443  }
16444  if (s->row_status) {
16445  memcpy(s->row_status, s->row_status0,
16446  sizeof (SQLUSMALLINT) * s->rowset_size);
16447  }
16448  s->row_count0 = 0;
16449  if (s->row_count) {
16450  *s->row_count = s->row_count0;
16451  }
16452  if (!s->bindcols) {
16453  for (i = 0; i < s->rowset_size; i++) {
16454  s->row_status0[i] = SQL_ROW_ERROR;
16455  }
16456  ret = SQL_ERROR;
16457  i = 0;
16458  goto done2;
16459  }
16460  if (s->isselect != 1 && s->isselect != -1) {
16461  setstat(s, -1, "no result set available", "24000");
16462  ret = SQL_ERROR;
16463  i = s->nrows;
16464  goto done2;
16465  }
16466  if (s->curtype == SQL_CURSOR_FORWARD_ONLY && orient != SQL_FETCH_NEXT) {
16467  setstat(s, -1, "wrong fetch direction", "01000");
16468  ret = SQL_ERROR;
16469  i = 0;
16470  goto done2;
16471  }
16472  ret = SQL_SUCCESS;
16473  i = 0;
16474  if (((DBC *) (s->dbc))->cur_s3stmt == s && s->s3stmt) {
16475  s->rowp = s->rowprs = 0;
16476  for (; i < s->rowset_size; i++) {
16477  if (s->max_rows && s->s3stmt_rownum + 1 >= s->max_rows) {
16478  ret = (i == 0) ? SQL_NO_DATA : SQL_SUCCESS;
16479  break;
16480  }
16481  ret = s3stmt_step(s);
16482  if (ret != SQL_SUCCESS) {
16483  s->row_status0[i] = SQL_ROW_ERROR;
16484  break;
16485  }
16486  if (s->nrows < 1) {
16487  break;
16488  }
16489  ret = dofetchbind(s, i);
16490  if (!SQL_SUCCEEDED(ret)) {
16491  break;
16492  } else if (ret == SQL_SUCCESS_WITH_INFO) {
16493  withinfo = 1;
16494  }
16495  }
16496  } else if (s->rows) {
16497  switch (orient) {
16498  case SQL_FETCH_NEXT:
16499  if (s->nrows < 1) {
16500  return SQL_NO_DATA;
16501  }
16502  if (s->rowp < 0) {
16503  s->rowp = -1;
16504  }
16505  if (s->rowp >= s->nrows) {
16506  s->rowp = s->rowprs = s->nrows;
16507  return SQL_NO_DATA;
16508  }
16509  break;
16510  case SQL_FETCH_PRIOR:
16511  if (s->nrows < 1 || s->rowp <= 0) {
16512  s->rowp = s->rowprs = -1;
16513  return SQL_NO_DATA;
16514  }
16515  s->rowp -= s->rowset_size + 1;
16516  if (s->rowp < -1) {
16517  s->rowp = s->rowprs = -1;
16518  return SQL_NO_DATA;
16519  }
16520  break;
16521  case SQL_FETCH_FIRST:
16522  if (s->nrows < 1) {
16523  return SQL_NO_DATA;
16524  }
16525  s->rowp = -1;
16526  break;
16527  case SQL_FETCH_LAST:
16528  if (s->nrows < 1) {
16529  return SQL_NO_DATA;
16530  }
16531  s->rowp = s->nrows - s->rowset_size;
16532  if (--s->rowp < -1) {
16533  s->rowp = -1;
16534  }
16535  break;
16536  case SQL_FETCH_ABSOLUTE:
16537  if (offset == 0) {
16538  s->rowp = s->rowprs = -1;
16539  return SQL_NO_DATA;
16540  } else if (offset < 0) {
16541  if (0 - offset <= s->nrows) {
16542  s->rowp = s->nrows + offset - 1;
16543  break;
16544  }
16545  s->rowp = s->rowprs = -1;
16546  return SQL_NO_DATA;
16547  } else if (offset > s->nrows) {
16548  s->rowp = s->rowprs = s->nrows;
16549  return SQL_NO_DATA;
16550  }
16551  s->rowp = offset - 1 - 1;
16552  break;
16553  case SQL_FETCH_RELATIVE:
16554  if (offset >= 0) {
16555  s->rowp += offset * s->rowset_size - 1;
16556  if (s->rowp >= s->nrows) {
16557  s->rowp = s->rowprs = s->nrows;
16558  return SQL_NO_DATA;
16559  }
16560  } else {
16561  s->rowp += offset * s->rowset_size - 1;
16562  if (s->rowp < -1) {
16563  s->rowp = s->rowprs = -1;
16564  return SQL_NO_DATA;
16565  }
16566  }
16567  break;
16568  case SQL_FETCH_BOOKMARK:
16569  if (s->bkmrk == SQL_UB_ON && !s->bkmrkptr) {
16570  if (offset < 0 || offset >= s->nrows) {
16571  return SQL_NO_DATA;
16572  }
16573  s->rowp = offset - 1;
16574  break;
16575  }
16576  if (s->bkmrk != SQL_UB_OFF && s->bkmrkptr) {
16577  int rowp;
16578 
16579  if (s->bkmrk == SQL_UB_VARIABLE) {
16580  if (s->has_rowid >= 0) {
16581  sqlite_int64 bkmrk, rowid;
16582 
16583  bkmrk = *(sqlite_int64 *) s->bkmrkptr;
16584  for (rowp = 0; rowp < s->nrows; rowp++) {
16585  char **data, *endp = 0;
16586 
16587  data = s->rows + s->ncols + (rowp * s->ncols)
16588  + s->has_rowid;
16589 #ifdef __osf__
16590  rowid = strtol(*data, &endp, 0);
16591 #else
16592  rowid = strtoll(*data, &endp, 0);
16593 #endif
16594  if (rowid == bkmrk) {
16595  break;
16596  }
16597  }
16598  } else {
16599  rowp = *(sqlite_int64 *) s->bkmrkptr;
16600  }
16601  } else {
16602  rowp = *(int *) s->bkmrkptr;
16603  }
16604  if (rowp + offset < 0 || rowp + offset >= s->nrows) {
16605  return SQL_NO_DATA;
16606  }
16607  s->rowp = rowp + offset - 1;
16608  break;
16609  }
16610  /* fall through */
16611  default:
16612  s->row_status0[0] = SQL_ROW_ERROR;
16613  ret = SQL_ERROR;
16614  goto done;
16615  }
16616  s->rowprs = s->rowp + 1;
16617  for (; i < s->rowset_size; i++) {
16618  ++s->rowp;
16619  if (s->rowp < 0 || s->rowp >= s->nrows) {
16620  break;
16621  }
16622  ret = dofetchbind(s, i);
16623  if (!SQL_SUCCEEDED(ret)) {
16624  break;
16625  } else if (ret == SQL_SUCCESS_WITH_INFO) {
16626  withinfo = 1;
16627  }
16628  }
16629  }
16630 done:
16631  if (i == 0) {
16632  if (SQL_SUCCEEDED(ret)) {
16633  return SQL_NO_DATA;
16634  }
16635  return ret;
16636  }
16637  if (SQL_SUCCEEDED(ret)) {
16638  ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16639  }
16640 done2:
16641  if (s->row_status) {
16642  memcpy(s->row_status, s->row_status0,
16643  sizeof (SQLUSMALLINT) * s->rowset_size);
16644  }
16645  s->row_count0 = i;
16646  if (s->row_count) {
16647  *s->row_count = s->row_count0;
16648  }
16649  return ret;
16650 }
16651 
16658 SQLRETURN SQL_API
16659 SQLFetch(SQLHSTMT stmt)
16660 {
16661  SQLRETURN ret;
16662 
16663  HSTMT_LOCK(stmt);
16664  ret = drvfetchscroll(stmt, SQL_FETCH_NEXT, 0);
16665  HSTMT_UNLOCK(stmt);
16666  return ret;
16667 }
16668 
16677 SQLRETURN SQL_API
16678 SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLLEN offset)
16679 {
16680  SQLRETURN ret;
16681 
16682  HSTMT_LOCK(stmt);
16683  ret = drvfetchscroll(stmt, orient, offset);
16684  HSTMT_UNLOCK(stmt);
16685  return ret;
16686 }
16687 
16698 SQLRETURN SQL_API
16699 SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT orient, SQLROWOFFSET offset,
16700  SQLROWSETSIZE *rowcount, SQLUSMALLINT *rowstatus)
16701 {
16702  STMT *s;
16703  SQLRETURN ret;
16704  SQLUSMALLINT *rst;
16705  SQLINTEGER *bkmrkptr;
16706 
16707  HSTMT_LOCK(stmt);
16708  if (stmt == SQL_NULL_HSTMT) {
16709  return SQL_INVALID_HANDLE;
16710  }
16711  s = (STMT *) stmt;
16712  /* temporarily turn off SQL_ATTR_ROW_STATUS_PTR */
16713  rst = s->row_status;
16714  s->row_status = 0;
16715  bkmrkptr = s->bkmrkptr;
16716  s->bkmrkptr = 0;
16717  ret = drvfetchscroll(stmt, orient, offset);
16718  s->row_status = rst;
16719  s->bkmrkptr = bkmrkptr;
16720  if (rowstatus) {
16721  memcpy(rowstatus, s->row_status0,
16722  sizeof (SQLUSMALLINT) * s->rowset_size);
16723  }
16724  if (rowcount) {
16725  *rowcount = s->row_count0;
16726  }
16727  HSTMT_UNLOCK(stmt);
16728  return ret;
16729 }
16730 
16738 SQLRETURN SQL_API
16739 SQLRowCount(SQLHSTMT stmt, SQLLEN *nrows)
16740 {
16741  STMT *s;
16742 
16743  HSTMT_LOCK(stmt);
16744  if (stmt == SQL_NULL_HSTMT) {
16745  return SQL_INVALID_HANDLE;
16746  }
16747  s = (STMT *) stmt;
16748  if (nrows) {
16749  *nrows = s->isselect ? 0 : s->nrows;
16750  }
16751  HSTMT_UNLOCK(stmt);
16752  return SQL_SUCCESS;
16753 }
16754 
16762 SQLRETURN SQL_API
16763 SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *ncols)
16764 {
16765  STMT *s;
16766 
16767  HSTMT_LOCK(stmt);
16768  if (stmt == SQL_NULL_HSTMT) {
16769  return SQL_INVALID_HANDLE;
16770  }
16771  s = (STMT *) stmt;
16772  if (ncols) {
16773  *ncols = s->ncols;
16774  }
16775  HSTMT_UNLOCK(stmt);
16776  return SQL_SUCCESS;
16777 }
16778 
16793 static SQLRETURN
16794 drvdescribecol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
16795  SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
16796  SQLSMALLINT *type, SQLULEN *size,
16797  SQLSMALLINT *digits, SQLSMALLINT *nullable)
16798 {
16799  STMT *s;
16800  COL *c;
16801  int didname = 0;
16802 
16803  if (stmt == SQL_NULL_HSTMT) {
16804  return SQL_INVALID_HANDLE;
16805  }
16806  s = (STMT *) stmt;
16807  if (!s->cols) {
16808  setstat(s, -1, "no columns", (*s->ov3) ? "07009" : "S1002");
16809  return SQL_ERROR;
16810  }
16811  if (col < 1 || col > s->ncols) {
16812  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
16813  return SQL_ERROR;
16814  }
16815  c = s->cols + col - 1;
16816  if (name && nameMax > 0) {
16817  strncpy((char *) name, c->column, nameMax);
16818  name[nameMax - 1] = '\0';
16819  didname = 1;
16820  }
16821  if (nameLen) {
16822  if (didname) {
16823  *nameLen = strlen((char *) name);
16824  } else {
16825  *nameLen = strlen(c->column);
16826  }
16827  }
16828  if (type) {
16829  *type = c->type;
16830 #ifdef WINTERFACE
16831  if (s->nowchar[0] || s->nowchar[1]) {
16832  switch (c->type) {
16833  case SQL_WCHAR:
16834  *type = SQL_CHAR;
16835  break;
16836  case SQL_WVARCHAR:
16837  *type = SQL_VARCHAR;
16838  break;
16839 #ifdef SQL_LONGVARCHAR
16840  case SQL_WLONGVARCHAR:
16841  *type = SQL_LONGVARCHAR;
16842  break;
16843 #endif
16844  }
16845  }
16846 #endif
16847  }
16848  if (size) {
16849  *size = c->size;
16850  }
16851  if (digits) {
16852  *digits = 0;
16853  }
16854  if (nullable) {
16855  *nullable = 1;
16856  }
16857  return SQL_SUCCESS;
16858 }
16859 
16860 #ifndef WINTERFACE
16861 
16875 SQLRETURN SQL_API
16876 SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
16877  SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
16878  SQLSMALLINT *type, SQLULEN *size,
16879  SQLSMALLINT *digits, SQLSMALLINT *nullable)
16880 {
16881 #if defined(_WIN32) || defined(_WIN64)
16882  SQLSMALLINT len = 0;
16883 #endif
16884  SQLRETURN ret;
16885 
16886  HSTMT_LOCK(stmt);
16887 #if defined(_WIN32) || defined(_WIN64)
16888  if (!((STMT *) stmt)->oemcp[0]) {
16889  ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
16890  type, size, digits, nullable);
16891  goto done;
16892  }
16893  ret = drvdescribecol(stmt, col, name, nameMax,
16894  &len, type, size, digits, nullable);
16895  if (ret == SQL_SUCCESS) {
16896  if (name) {
16897  if (len > 0) {
16898  SQLCHAR *n = NULL;
16899 
16900  n = (SQLCHAR *) utf_to_wmb((char *) name, len);
16901  if (n) {
16902  strncpy((char *) name, (char *) n, nameMax);
16903  n[len] = 0;
16904  len = min(nameMax, strlen((char *) n));
16905  uc_free(n);
16906  } else {
16907  len = 0;
16908  }
16909  }
16910  if (len <= 0) {
16911  len = 0;
16912  if (nameMax > 0) {
16913  name[0] = 0;
16914  }
16915  }
16916  } else {
16917  STMT *s = (STMT *) stmt;
16918  COL *c = s->cols + col - 1;
16919 
16920  len = 0;
16921  if (c->column) {
16922  len = strlen(c->column);
16923  }
16924  }
16925  if (nameLen) {
16926  *nameLen = len;
16927  }
16928  }
16929 done:
16930  ;
16931 #else
16932  ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
16933  type, size, digits, nullable);
16934 #endif
16935  HSTMT_UNLOCK(stmt);
16936  return ret;
16937 }
16938 #endif
16939 
16940 #ifdef WINTERFACE
16941 
16955 SQLRETURN SQL_API
16956 SQLDescribeColW(SQLHSTMT stmt, SQLUSMALLINT col, SQLWCHAR *name,
16957  SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
16958  SQLSMALLINT *type, SQLULEN *size,
16959  SQLSMALLINT *digits, SQLSMALLINT *nullable)
16960 {
16961  SQLRETURN ret;
16962  SQLSMALLINT len = 0;
16963 
16964  HSTMT_LOCK(stmt);
16965  ret = drvdescribecol(stmt, col, (SQLCHAR *) name,
16966  (SQLSMALLINT) (nameMax * sizeof (SQLWCHAR)),
16967  &len, type, size, digits, nullable);
16968  if (ret == SQL_SUCCESS) {
16969  if (name) {
16970  if (len > 0) {
16971  SQLWCHAR *n = NULL;
16972 
16973  n = uc_from_utf((SQLCHAR *) name, len);
16974  if (n) {
16975  uc_strncpy(name, n, nameMax);
16976  n[len] = 0;
16977  len = min(nameMax, uc_strlen(n));
16978  uc_free(n);
16979  } else {
16980  len = 0;
16981  }
16982  }
16983  if (len <= 0) {
16984  len = 0;
16985  if (nameMax > 0) {
16986  name[0] = 0;
16987  }
16988  }
16989  } else {
16990  STMT *s = (STMT *) stmt;
16991  COL *c = s->cols + col - 1;
16992 
16993  len = 0;
16994  if (c->column) {
16995  len = strlen(c->column);
16996  }
16997  }
16998  if (nameLen) {
16999  *nameLen = len;
17000  }
17001  }
17002  HSTMT_UNLOCK(stmt);
17003  return ret;
17004 }
17005 #endif
17006 
17019 static SQLRETURN
17020 drvcolattributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17021  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17022  SQLLEN *val2)
17023 {
17024  STMT *s;
17025  COL *c;
17026  SQLSMALLINT dummy;
17027  char *valc = (char *) val;
17028 
17029  if (stmt == SQL_NULL_HSTMT) {
17030  return SQL_INVALID_HANDLE;
17031  }
17032  s = (STMT *) stmt;
17033  if (!s->cols) {
17034  return SQL_ERROR;
17035  }
17036  if (!valLen) {
17037  valLen = &dummy;
17038  }
17039  if (id == SQL_COLUMN_COUNT) {
17040  if (val2) {
17041  *val2 = s->ncols;
17042  }
17043  *valLen = sizeof (int);
17044  return SQL_SUCCESS;
17045  }
17046  if (id == SQL_COLUMN_TYPE && col == 0) {
17047  if (val2) {
17048  *val2 = SQL_INTEGER;
17049  }
17050  *valLen = sizeof (int);
17051  return SQL_SUCCESS;
17052  }
17053 #ifdef SQL_DESC_OCTET_LENGTH
17054  if (id == SQL_DESC_OCTET_LENGTH && col == 0) {
17055  if (val2) {
17056  *val2 = 4;
17057  }
17058  *valLen = sizeof (int);
17059  return SQL_SUCCESS;
17060  }
17061 #endif
17062  if (col < 1 || col > s->ncols) {
17063  setstat(s, -1, "invalid column", (*s->ov3) ? "07009": "S1002");
17064  return SQL_ERROR;
17065  }
17066  c = s->cols + col - 1;
17067 
17068  switch (id) {
17069  case SQL_COLUMN_LABEL:
17070  if (c->label) {
17071  if (valc && valMax > 0) {
17072  strncpy(valc, c->label, valMax);
17073  valc[valMax - 1] = '\0';
17074  }
17075  *valLen = strlen(c->label);
17076  goto checkLen;
17077  }
17078  /* fall through */
17079  case SQL_COLUMN_NAME:
17080  case SQL_DESC_NAME:
17081  if (valc && valMax > 0) {
17082  strncpy(valc, c->column, valMax);
17083  valc[valMax - 1] = '\0';
17084  }
17085  *valLen = strlen(c->column);
17086 checkLen:
17087  if (*valLen >= valMax) {
17088  setstat(s, -1, "data right truncated", "01004");
17089  return SQL_SUCCESS_WITH_INFO;
17090  }
17091  return SQL_SUCCESS;
17092 #ifdef SQL_DESC_BASE_COLUMN_NAME
17093  case SQL_DESC_BASE_COLUMN_NAME:
17094  if (strchr(c->column, '(') || strchr(c->column, ')')) {
17095  if (valc && valMax > 0) {
17096  valc[0] = '\0';
17097  }
17098  *valLen = 0;
17099  } else if (valc && valMax > 0) {
17100  strncpy(valc, c->column, valMax);
17101  valc[valMax - 1] = '\0';
17102  *valLen = strlen(c->column);
17103  }
17104  goto checkLen;
17105 #endif
17106  case SQL_COLUMN_TYPE:
17107  case SQL_DESC_TYPE:
17108 #ifdef WINTERFACE
17109  {
17110  int type = c->type;
17111 
17112  if (s->nowchar[0] || s->nowchar[1]) {
17113  switch (type) {
17114  case SQL_WCHAR:
17115  type = SQL_CHAR;
17116  break;
17117  case SQL_WVARCHAR:
17118  type = SQL_VARCHAR;
17119  break;
17120 #ifdef SQL_LONGVARCHAR
17121  case SQL_WLONGVARCHAR:
17122  type = SQL_LONGVARCHAR;
17123  break;
17124  }
17125  }
17126  if (val2) {
17127  *val2 = type;
17128  }
17129 #endif
17130  }
17131 #else
17132  if (val2) {
17133  *val2 = c->type;
17134  }
17135 #endif
17136  *valLen = sizeof (int);
17137  return SQL_SUCCESS;
17138  case SQL_COLUMN_DISPLAY_SIZE:
17139  if (val2) {
17140  *val2 = c->size;
17141  }
17142  *valLen = sizeof (int);
17143  return SQL_SUCCESS;
17144  case SQL_COLUMN_UNSIGNED:
17145  if (val2) {
17146  *val2 = c->nosign ? SQL_TRUE : SQL_FALSE;
17147  }
17148  *valLen = sizeof (int);
17149  return SQL_SUCCESS;
17150  case SQL_COLUMN_SCALE:
17151  case SQL_DESC_SCALE:
17152  if (val2) {
17153  *val2 = c->scale;
17154  }
17155  *valLen = sizeof (int);
17156  return SQL_SUCCESS;
17157  case SQL_COLUMN_PRECISION:
17158  case SQL_DESC_PRECISION:
17159  if (val2) {
17160  switch (c->type) {
17161  case SQL_SMALLINT:
17162  *val2 = 5;
17163  break;
17164  case SQL_INTEGER:
17165  *val2 = 10;
17166  break;
17167  case SQL_FLOAT:
17168  case SQL_REAL:
17169  case SQL_DOUBLE:
17170  *val2 = 15;
17171  break;
17172  case SQL_DATE:
17173  *val2 = 0;
17174  break;
17175  case SQL_TIME:
17176  *val2 = 0;
17177  break;
17178 #ifdef SQL_TYPE_TIMESTAMP
17179  case SQL_TYPE_TIMESTAMP:
17180 #endif
17181  case SQL_TIMESTAMP:
17182  *val2 = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
17183  break;
17184  default:
17185  *val2 = c->prec;
17186  break;
17187  }
17188  }
17189  *valLen = sizeof (int);
17190  return SQL_SUCCESS;
17191  case SQL_COLUMN_MONEY:
17192  if (val2) {
17193  *val2 = SQL_FALSE;
17194  }
17195  *valLen = sizeof (int);
17196  return SQL_SUCCESS;
17197  case SQL_COLUMN_AUTO_INCREMENT:
17198  if (val2) {
17199  *val2 = c->autoinc;
17200  }
17201  *valLen = sizeof (int);
17202  return SQL_SUCCESS;
17203  case SQL_COLUMN_LENGTH:
17204  case SQL_DESC_LENGTH:
17205  if (val2) {
17206  *val2 = c->size;
17207  }
17208  *valLen = sizeof (int);
17209  return SQL_SUCCESS;
17210  case SQL_COLUMN_NULLABLE:
17211  case SQL_DESC_NULLABLE:
17212  if (val2) {
17213  *val2 = c->notnull;
17214  }
17215  *valLen = sizeof (int);
17216  return SQL_SUCCESS;
17217  case SQL_COLUMN_SEARCHABLE:
17218  if (val2) {
17219  *val2 = SQL_SEARCHABLE;
17220  }
17221  *valLen = sizeof (int);
17222  return SQL_SUCCESS;
17223  case SQL_COLUMN_CASE_SENSITIVE:
17224  if (val2) {
17225  *val2 = SQL_TRUE;
17226  }
17227  *valLen = sizeof (int);
17228  return SQL_SUCCESS;
17229  case SQL_COLUMN_UPDATABLE:
17230  if (val2) {
17231  *val2 = SQL_TRUE;
17232  }
17233  *valLen = sizeof (int);
17234  return SQL_SUCCESS;
17235  case SQL_DESC_COUNT:
17236  if (val2) {
17237  *val2 = s->ncols;
17238  }
17239  *valLen = sizeof (int);
17240  return SQL_SUCCESS;
17241  case SQL_COLUMN_TYPE_NAME: {
17242  char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17243 
17244 #ifdef WINTERFACE
17245  if (c->type == SQL_WCHAR ||
17246  c->type == SQL_WVARCHAR ||
17247  c->type == SQL_WLONGVARCHAR) {
17248  if (!(s->nowchar[0] || s->nowchar[1])) {
17249  if (strcasecmp(tn, "varchar") == 0) {
17250  tn = "wvarchar";
17251  }
17252  }
17253  }
17254 #endif
17255  if (valc && valMax > 0) {
17256  strncpy(valc, tn, valMax);
17257  valc[valMax - 1] = '\0';
17258  p = strchr(valc, '(');
17259  if (p) {
17260  *p = '\0';
17261  while (p > valc && ISSPACE(p[-1])) {
17262  --p;
17263  *p = '\0';
17264  }
17265  }
17266  *valLen = strlen(valc);
17267  } else {
17268  *valLen = strlen(tn);
17269  p = strchr(tn, '(');
17270  if (p) {
17271  *valLen = p - tn;
17272  while (p > tn && ISSPACE(p[-1])) {
17273  --p;
17274  *valLen -= 1;
17275  }
17276  }
17277  }
17278  goto checkLen;
17279  }
17280  case SQL_COLUMN_OWNER_NAME:
17281  case SQL_COLUMN_QUALIFIER_NAME: {
17282  char *z = "";
17283 
17284  if (valc && valMax > 0) {
17285  strncpy(valc, z, valMax);
17286  valc[valMax - 1] = '\0';
17287  }
17288  *valLen = strlen(z);
17289  goto checkLen;
17290  }
17291  case SQL_COLUMN_TABLE_NAME:
17292 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17293  case SQL_DESC_TABLE_NAME:
17294 #endif
17295 #ifdef SQL_DESC_BASE_TABLE_NAME
17296  case SQL_DESC_BASE_TABLE_NAME:
17297 #endif
17298  if (valc && valMax > 0) {
17299  strncpy(valc, c->table, valMax);
17300  valc[valMax - 1] = '\0';
17301  }
17302  *valLen = strlen(c->table);
17303  goto checkLen;
17304 #ifdef SQL_DESC_NUM_PREC_RADIX
17305  case SQL_DESC_NUM_PREC_RADIX:
17306  if (val2) {
17307  switch (c->type) {
17308 #ifdef WINTERFACE
17309  case SQL_WCHAR:
17310  case SQL_WVARCHAR:
17311 #ifdef SQL_LONGVARCHAR
17312  case SQL_WLONGVARCHAR:
17313 #endif
17314 #endif
17315  case SQL_CHAR:
17316  case SQL_VARCHAR:
17317 #ifdef SQL_LONGVARCHAR
17318  case SQL_LONGVARCHAR:
17319 #endif
17320  case SQL_BINARY:
17321  case SQL_VARBINARY:
17322  case SQL_LONGVARBINARY:
17323  *val2 = 0;
17324  break;
17325  default:
17326  *val2 = 2;
17327  }
17328  }
17329  *valLen = sizeof (int);
17330  return SQL_SUCCESS;
17331 #endif
17332  }
17333  setstat(s, -1, "unsupported column attributes %d", "HY091", id);
17334  return SQL_ERROR;
17335 }
17336 
17337 #ifndef WINTERFACE
17338 
17350 SQLRETURN SQL_API
17351 SQLColAttributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17352  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17353  SQLLEN *val2)
17354 {
17355 #if defined(_WIN32) || defined(_WIN64)
17356  SQLSMALLINT len = 0;
17357 #endif
17358  SQLRETURN ret;
17359 
17360  HSTMT_LOCK(stmt);
17361 #if defined(_WIN32) || defined(_WIN64)
17362  if (!((STMT *) stmt)->oemcp[0]) {
17363  ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17364  goto done;
17365  }
17366  ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17367  if (SQL_SUCCEEDED(ret)) {
17368  char *v = NULL;
17369 
17370  switch (id) {
17371  case SQL_COLUMN_LABEL:
17372  case SQL_COLUMN_NAME:
17373  case SQL_DESC_NAME:
17374  case SQL_COLUMN_TYPE_NAME:
17375  case SQL_COLUMN_OWNER_NAME:
17376  case SQL_COLUMN_QUALIFIER_NAME:
17377  case SQL_COLUMN_TABLE_NAME:
17378 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17379  case SQL_DESC_TABLE_NAME:
17380 #endif
17381 #ifdef SQL_DESC_BASE_COLUMN_NAME
17382  case SQL_DESC_BASE_COLUMN_NAME:
17383 #endif
17384 #ifdef SQL_DESC_BASE_TABLE_NAME
17385  case SQL_DESC_BASE_TABLE_NAME:
17386 #endif
17387  if (val && valMax > 0) {
17388  int vmax = valMax;
17389 
17390  v = utf_to_wmb((char *) val, SQL_NTS);
17391  if (v) {
17392  strncpy(val, v, vmax);
17393  len = min(vmax, strlen(v));
17394  uc_free(v);
17395  }
17396  if (vmax > 0) {
17397  v = (char *) val;
17398  v[vmax - 1] = '\0';
17399  }
17400  }
17401  if (len <= 0) {
17402  len = 0;
17403  }
17404  break;
17405  }
17406  if (valLen) {
17407  *valLen = len;
17408  }
17409  }
17410 done:
17411  ;
17412 #else
17413  ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17414 #endif
17415  HSTMT_UNLOCK(stmt);
17416  return ret;
17417 }
17418 #endif
17419 
17420 #ifdef WINTERFACE
17421 
17433 SQLRETURN SQL_API
17434 SQLColAttributesW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17435  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17436  SQLLEN *val2)
17437 {
17438  SQLRETURN ret;
17439  SQLSMALLINT len = 0;
17440 
17441  HSTMT_LOCK(stmt);
17442  ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17443  if (SQL_SUCCEEDED(ret)) {
17444  SQLWCHAR *v = NULL;
17445 
17446  switch (id) {
17447  case SQL_COLUMN_LABEL:
17448  case SQL_COLUMN_NAME:
17449  case SQL_DESC_NAME:
17450  case SQL_COLUMN_TYPE_NAME:
17451  case SQL_COLUMN_OWNER_NAME:
17452  case SQL_COLUMN_QUALIFIER_NAME:
17453  case SQL_COLUMN_TABLE_NAME:
17454 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17455  case SQL_DESC_TABLE_NAME:
17456 #endif
17457 #ifdef SQL_DESC_BASE_COLUMN_NAME
17458  case SQL_DESC_BASE_COLUMN_NAME:
17459 #endif
17460 #ifdef SQL_DESC_BASE_TABLE_NAME
17461  case SQL_DESC_BASE_TABLE_NAME:
17462 #endif
17463  if (val && valMax > 0) {
17464  int vmax = valMax / sizeof (SQLWCHAR);
17465 
17466  v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
17467  if (v) {
17468  uc_strncpy(val, v, vmax);
17469  len = min(vmax, uc_strlen(v));
17470  uc_free(v);
17471  len *= sizeof (SQLWCHAR);
17472  }
17473  if (vmax > 0) {
17474  v = (SQLWCHAR *) val;
17475  v[vmax - 1] = '\0';
17476  }
17477  }
17478  if (len <= 0) {
17479  len = 0;
17480  }
17481  break;
17482  }
17483  if (valLen) {
17484  *valLen = len;
17485  }
17486  }
17487  HSTMT_UNLOCK(stmt);
17488  return ret;
17489 }
17490 #endif
17491 
17504 static SQLRETURN
17505 drvcolattribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17506  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17507  SQLPOINTER val2)
17508 {
17509  STMT *s;
17510  COL *c;
17511  int v = 0;
17512  char *valc = (char *) val;
17513  SQLSMALLINT dummy;
17514 
17515  if (stmt == SQL_NULL_HSTMT) {
17516  return SQL_INVALID_HANDLE;
17517  }
17518  s = (STMT *) stmt;
17519  if (!s->cols) {
17520  return SQL_ERROR;
17521  }
17522  if (col < 1 || col > s->ncols) {
17523  setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
17524  return SQL_ERROR;
17525  }
17526  if (!valLen) {
17527  valLen = &dummy;
17528  }
17529  c = s->cols + col - 1;
17530  switch (id) {
17531  case SQL_DESC_COUNT:
17532  v = s->ncols;
17533  break;
17534  case SQL_DESC_CATALOG_NAME:
17535  if (valc && valMax > 0) {
17536  strncpy(valc, c->db, valMax);
17537  valc[valMax - 1] = '\0';
17538  }
17539  *valLen = strlen(c->db);
17540 checkLen:
17541  if (*valLen >= valMax) {
17542  setstat(s, -1, "data right truncated", "01004");
17543  return SQL_SUCCESS_WITH_INFO;
17544  }
17545  break;
17546  case SQL_COLUMN_LENGTH:
17547  case SQL_DESC_LENGTH:
17548  v = c->size;
17549  break;
17550  case SQL_COLUMN_LABEL:
17551  if (c->label) {
17552  if (valc && valMax > 0) {
17553  strncpy(valc, c->label, valMax);
17554  valc[valMax - 1] = '\0';
17555  }
17556  *valLen = strlen(c->label);
17557  goto checkLen;
17558  }
17559  /* fall through */
17560  case SQL_COLUMN_NAME:
17561  case SQL_DESC_NAME:
17562  if (valc && valMax > 0) {
17563  strncpy(valc, c->column, valMax);
17564  valc[valMax - 1] = '\0';
17565  }
17566  *valLen = strlen(c->column);
17567  goto checkLen;
17568  case SQL_DESC_SCHEMA_NAME: {
17569  char *z = "";
17570 
17571  if (valc && valMax > 0) {
17572  strncpy(valc, z, valMax);
17573  valc[valMax - 1] = '\0';
17574  }
17575  *valLen = strlen(z);
17576  goto checkLen;
17577  }
17578 #ifdef SQL_DESC_BASE_COLUMN_NAME
17579  case SQL_DESC_BASE_COLUMN_NAME:
17580  if (strchr(c->column, '(') || strchr(c->column, ')')) {
17581  valc[0] = '\0';
17582  *valLen = 0;
17583  } else if (valc && valMax > 0) {
17584  strncpy(valc, c->column, valMax);
17585  valc[valMax - 1] = '\0';
17586  *valLen = strlen(c->column);
17587  }
17588  goto checkLen;
17589 #endif
17590  case SQL_DESC_TYPE_NAME: {
17591  char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17592 
17593 #ifdef WINTERFACE
17594  if (c->type == SQL_WCHAR ||
17595  c->type == SQL_WVARCHAR ||
17596  c->type == SQL_WLONGVARCHAR) {
17597  if (!(s->nowchar[0] || s->nowchar[1])) {
17598  if (strcasecmp(tn, "varchar") == 0) {
17599  tn = "wvarchar";
17600  }
17601  }
17602  }
17603 #endif
17604  if (valc && valMax > 0) {
17605  strncpy(valc, tn, valMax);
17606  valc[valMax - 1] = '\0';
17607  p = strchr(valc, '(');
17608  if (p) {
17609  *p = '\0';
17610  while (p > valc && ISSPACE(p[-1])) {
17611  --p;
17612  *p = '\0';
17613  }
17614  }
17615  *valLen = strlen(valc);
17616  } else {
17617  *valLen = strlen(tn);
17618  p = strchr(tn, '(');
17619  if (p) {
17620  *valLen = p - tn;
17621  while (p > tn && ISSPACE(p[-1])) {
17622  --p;
17623  *valLen -= 1;
17624  }
17625  }
17626  }
17627  goto checkLen;
17628  }
17629  case SQL_DESC_OCTET_LENGTH:
17630  v = c->size;
17631 #ifdef WINTERFACE
17632  if (c->type == SQL_WCHAR ||
17633  c->type == SQL_WVARCHAR ||
17634  c->type == SQL_WLONGVARCHAR) {
17635  if (!(s->nowchar[0] || s->nowchar[1])) {
17636  v *= sizeof (SQLWCHAR);
17637  }
17638  }
17639 #endif
17640  break;
17641 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17642  case SQL_COLUMN_TABLE_NAME:
17643 #endif
17644 #ifdef SQL_DESC_BASE_TABLE_NAME
17645  case SQL_DESC_BASE_TABLE_NAME:
17646 #endif
17647  case SQL_DESC_TABLE_NAME:
17648  if (valc && valMax > 0) {
17649  strncpy(valc, c->table, valMax);
17650  valc[valMax - 1] = '\0';
17651  }
17652  *valLen = strlen(c->table);
17653  goto checkLen;
17654  case SQL_DESC_TYPE:
17655  v = c->type;
17656 #ifdef WINTERFACE
17657  if (s->nowchar[0] || s->nowchar[1]) {
17658  switch (v) {
17659  case SQL_WCHAR:
17660  v = SQL_CHAR;
17661  break;
17662  case SQL_WVARCHAR:
17663  v = SQL_VARCHAR;
17664  break;
17665 #ifdef SQL_LONGVARCHAR
17666  case SQL_WLONGVARCHAR:
17667  v = SQL_LONGVARCHAR;
17668  break;
17669 #endif
17670  }
17671  }
17672 #endif
17673  break;
17674  case SQL_DESC_CONCISE_TYPE:
17675  switch (c->type) {
17676  case SQL_INTEGER:
17677  v = SQL_C_LONG;
17678  break;
17679  case SQL_TINYINT:
17680  v = SQL_C_TINYINT;
17681  break;
17682  case SQL_SMALLINT:
17683  v = SQL_C_SHORT;
17684  break;
17685  case SQL_FLOAT:
17686  v = SQL_C_FLOAT;
17687  break;
17688  case SQL_DOUBLE:
17689  v = SQL_C_DOUBLE;
17690  break;
17691  case SQL_TIMESTAMP:
17692  v = SQL_C_TIMESTAMP;
17693  break;
17694  case SQL_TIME:
17695  v = SQL_C_TIME;
17696  break;
17697  case SQL_DATE:
17698  v = SQL_C_DATE;
17699  break;
17700 #ifdef SQL_C_TYPE_TIMESTAMP
17701  case SQL_TYPE_TIMESTAMP:
17702  v = SQL_C_TYPE_TIMESTAMP;
17703  break;
17704 #endif
17705 #ifdef SQL_C_TYPE_TIME
17706  case SQL_TYPE_TIME:
17707  v = SQL_C_TYPE_TIME;
17708  break;
17709 #endif
17710 #ifdef SQL_C_TYPE_DATE
17711  case SQL_TYPE_DATE:
17712  v = SQL_C_TYPE_DATE;
17713  break;
17714 #endif
17715 #ifdef SQL_BIT
17716  case SQL_BIT:
17717  v = SQL_C_BIT;
17718  break;
17719 #endif
17720 #ifdef SQL_BIGINT
17721  case SQL_BIGINT:
17722  v = SQL_C_SBIGINT;
17723  break;
17724 #endif
17725  default:
17726 #ifdef WINTERFACE
17727  v = (s->nowchar[0] || s->nowchar[1]) ? SQL_C_CHAR : SQL_C_WCHAR;
17728 #else
17729  v = SQL_C_CHAR;
17730 #endif
17731  break;
17732  }
17733  break;
17734  case SQL_DESC_UPDATABLE:
17735  v = SQL_TRUE;
17736  break;
17737  case SQL_COLUMN_DISPLAY_SIZE:
17738  v = c->size;
17739  break;
17740  case SQL_COLUMN_UNSIGNED:
17741  v = c->nosign ? SQL_TRUE : SQL_FALSE;
17742  break;
17743  case SQL_COLUMN_SEARCHABLE:
17744  v = SQL_SEARCHABLE;
17745  break;
17746  case SQL_COLUMN_SCALE:
17747  case SQL_DESC_SCALE:
17748  v = c->scale;
17749  break;
17750  case SQL_COLUMN_PRECISION:
17751  case SQL_DESC_PRECISION:
17752  switch (c->type) {
17753  case SQL_SMALLINT:
17754  v = 5;
17755  break;
17756  case SQL_INTEGER:
17757  v = 10;
17758  break;
17759  case SQL_FLOAT:
17760  case SQL_REAL:
17761  case SQL_DOUBLE:
17762  v = 15;
17763  break;
17764  case SQL_DATE:
17765  v = 0;
17766  break;
17767  case SQL_TIME:
17768  v = 0;
17769  break;
17770 #ifdef SQL_TYPE_TIMESTAMP
17771  case SQL_TYPE_TIMESTAMP:
17772 #endif
17773  case SQL_TIMESTAMP:
17774  v = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
17775  break;
17776  default:
17777  v = c->prec;
17778  break;
17779  }
17780  break;
17781  case SQL_COLUMN_MONEY:
17782  v = SQL_FALSE;
17783  break;
17784  case SQL_COLUMN_AUTO_INCREMENT:
17785  v = c->autoinc;
17786  break;
17787  case SQL_DESC_NULLABLE:
17788  v = c->notnull;
17789  break;
17790 #ifdef SQL_DESC_NUM_PREC_RADIX
17791  case SQL_DESC_NUM_PREC_RADIX:
17792  switch (c->type) {
17793 #ifdef WINTERFACE
17794  case SQL_WCHAR:
17795  case SQL_WVARCHAR:
17796 #ifdef SQL_LONGVARCHAR
17797  case SQL_WLONGVARCHAR:
17798 #endif
17799 #endif
17800  case SQL_CHAR:
17801  case SQL_VARCHAR:
17802 #ifdef SQL_LONGVARCHAR
17803  case SQL_LONGVARCHAR:
17804 #endif
17805  case SQL_BINARY:
17806  case SQL_VARBINARY:
17807  case SQL_LONGVARBINARY:
17808  v = 0;
17809  break;
17810  default:
17811  v = 2;
17812  }
17813  break;
17814 #endif
17815  default:
17816  setstat(s, -1, "unsupported column attribute %d", "HY091", id);
17817  return SQL_ERROR;
17818  }
17819  if (val2) {
17820  *(SQLLEN *) val2 = v;
17821  }
17822  return SQL_SUCCESS;
17823 }
17824 
17825 #ifndef WINTERFACE
17826 
17838 SQLRETURN SQL_API
17839 SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17840  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17842 {
17843 #if defined(_WIN32) || defined(_WIN64)
17844  SQLSMALLINT len = 0;
17845 #endif
17846  SQLRETURN ret;
17847 
17848  HSTMT_LOCK(stmt);
17849 #if defined(_WIN32) || defined(_WIN64)
17850  if (!((STMT *) stmt)->oemcp[0]) {
17851  ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
17852  (SQLPOINTER) val2);
17853  goto done;
17854  }
17855  ret = drvcolattribute(stmt, col, id, val, valMax, &len,
17856  (SQLPOINTER) val2);
17857  if (SQL_SUCCEEDED(ret)) {
17858  char *v = NULL;
17859 
17860  switch (id) {
17861  case SQL_DESC_SCHEMA_NAME:
17862  case SQL_DESC_CATALOG_NAME:
17863  case SQL_COLUMN_LABEL:
17864  case SQL_DESC_NAME:
17865  case SQL_DESC_TABLE_NAME:
17866 #ifdef SQL_DESC_BASE_TABLE_NAME
17867  case SQL_DESC_BASE_TABLE_NAME:
17868 #endif
17869 #ifdef SQL_DESC_BASE_COLUMN_NAME
17870  case SQL_DESC_BASE_COLUMN_NAME:
17871 #endif
17872  case SQL_DESC_TYPE_NAME:
17873  if (val && valMax > 0) {
17874  int vmax = valMax;
17875 
17876  v = utf_to_wmb((char *) val, SQL_NTS);
17877  if (v) {
17878  strncpy(val, v, vmax);
17879  len = min(vmax, strlen(v));
17880  uc_free(v);
17881  }
17882  if (vmax > 0) {
17883  v = (char *) val;
17884  v[vmax - 1] = '\0';
17885  }
17886  }
17887  if (len <= 0) {
17888  len = 0;
17889  }
17890  break;
17891  }
17892  if (valLen) {
17893  *valLen = len;
17894  }
17895  }
17896 done:
17897  ;
17898 #else
17899  ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
17900  (SQLPOINTER) val2);
17901 #endif
17902  HSTMT_UNLOCK(stmt);
17903  return ret;
17904 }
17905 #endif
17906 
17907 #ifdef WINTERFACE
17908 
17920 SQLRETURN SQL_API
17921 SQLColAttributeW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17922  SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17924 {
17925  SQLRETURN ret;
17926  SQLSMALLINT len = 0;
17927 
17928  HSTMT_LOCK(stmt);
17929  ret = drvcolattribute(stmt, col, id, val, valMax, &len,
17930  (SQLPOINTER) val2);
17931  if (SQL_SUCCEEDED(ret)) {
17932  SQLWCHAR *v = NULL;
17933 
17934  switch (id) {
17935  case SQL_DESC_SCHEMA_NAME:
17936  case SQL_DESC_CATALOG_NAME:
17937  case SQL_COLUMN_LABEL:
17938  case SQL_DESC_NAME:
17939  case SQL_DESC_TABLE_NAME:
17940 #ifdef SQL_DESC_BASE_TABLE_NAME
17941  case SQL_DESC_BASE_TABLE_NAME:
17942 #endif
17943 #ifdef SQL_DESC_BASE_COLUMN_NAME
17944  case SQL_DESC_BASE_COLUMN_NAME:
17945 #endif
17946  case SQL_DESC_TYPE_NAME:
17947  if (val && valMax > 0) {
17948  int vmax = valMax / sizeof (SQLWCHAR);
17949 
17950  v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
17951  if (v) {
17952  uc_strncpy(val, v, vmax);
17953  len = min(vmax, uc_strlen(v));
17954  uc_free(v);
17955  len *= sizeof (SQLWCHAR);
17956  }
17957  if (vmax > 0) {
17958  v = (SQLWCHAR *) val;
17959  v[vmax - 1] = '\0';
17960  }
17961  }
17962  if (len <= 0) {
17963  len = 0;
17964  }
17965  break;
17966  }
17967  if (valLen) {
17968  *valLen = len;
17969  }
17970  }
17971  HSTMT_UNLOCK(stmt);
17972  return ret;
17973 }
17974 #endif
17975 
17989 static SQLRETURN
17990 drverror(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
17991  SQLCHAR *sqlState, SQLINTEGER *nativeErr,
17992  SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
17993 {
17994  SQLCHAR dummy0[6];
17995  SQLINTEGER dummy1;
17996  SQLSMALLINT dummy2;
17997 
17998  if (env == SQL_NULL_HENV &&
17999  dbc == SQL_NULL_HDBC &&
18000  stmt == SQL_NULL_HSTMT) {
18001  return SQL_INVALID_HANDLE;
18002  }
18003  if (sqlState) {
18004  sqlState[0] = '\0';
18005  } else {
18006  sqlState = dummy0;
18007  }
18008  if (!nativeErr) {
18009  nativeErr = &dummy1;
18010  }
18011  *nativeErr = 0;
18012  if (!errlen) {
18013  errlen = &dummy2;
18014  }
18015  *errlen = 0;
18016  if (errmsg) {
18017  if (errmax > 0) {
18018  errmsg[0] = '\0';
18019  }
18020  } else {
18021  errmsg = dummy0;
18022  errmax = 0;
18023  }
18024  if (stmt) {
18025  STMT *s = (STMT *) stmt;
18026 
18027  HSTMT_LOCK(stmt);
18028  if (s->logmsg[0] == '\0') {
18029  HSTMT_UNLOCK(stmt);
18030  goto noerr;
18031  }
18032  *nativeErr = s->naterr;
18033  strcpy((char *) sqlState, s->sqlstate);
18034  if (errmax == SQL_NTS) {
18035  strcpy((char *) errmsg, "[SQLite]");
18036  strcat((char *) errmsg, (char *) s->logmsg);
18037  *errlen = strlen((char *) errmsg);
18038  } else {
18039  strncpy((char *) errmsg, "[SQLite]", errmax);
18040  if (errmax - 8 > 0) {
18041  strncpy((char *) errmsg + 8, (char *) s->logmsg, errmax - 8);
18042  }
18043  *errlen = min(strlen((char *) s->logmsg) + 8, errmax);
18044  }
18045  s->logmsg[0] = '\0';
18046  HSTMT_UNLOCK(stmt);
18047  return SQL_SUCCESS;
18048  }
18049  if (dbc) {
18050  DBC *d = (DBC *) dbc;
18051 
18052  HDBC_LOCK(dbc);
18053  if (d->magic != DBC_MAGIC || d->logmsg[0] == '\0') {
18054  HDBC_UNLOCK(dbc);
18055  goto noerr;
18056  }
18057  *nativeErr = d->naterr;
18058  strcpy((char *) sqlState, d->sqlstate);
18059  if (errmax == SQL_NTS) {
18060  strcpy((char *) errmsg, "[SQLite]");
18061  strcat((char *) errmsg, (char *) d->logmsg);
18062  *errlen = strlen((char *) errmsg);
18063  } else {
18064  strncpy((char *) errmsg, "[SQLite]", errmax);
18065  if (errmax - 8 > 0) {
18066  strncpy((char *) errmsg + 8, (char *) d->logmsg, errmax - 8);
18067  }
18068  *errlen = min(strlen((char *) d->logmsg) + 8, errmax);
18069  }
18070  d->logmsg[0] = '\0';
18071  HDBC_UNLOCK(dbc);
18072  return SQL_SUCCESS;
18073  }
18074 noerr:
18075  sqlState[0] = '\0';
18076  errmsg[0] = '\0';
18077  *nativeErr = 0;
18078  *errlen = 0;
18079  return SQL_NO_DATA;
18080 }
18081 
18082 #ifndef WINTERFACE
18083 
18096 SQLRETURN SQL_API
18097 SQLError(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18098  SQLCHAR *sqlState, SQLINTEGER *nativeErr,
18099  SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18100 {
18101  return drverror(env, dbc, stmt, sqlState, nativeErr,
18102  errmsg, errmax, errlen);
18103 }
18104 #endif
18105 
18106 #ifdef WINTERFACE
18107 
18120 SQLRETURN SQL_API
18121 SQLErrorW(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18122  SQLWCHAR *sqlState, SQLINTEGER *nativeErr,
18123  SQLWCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18124 {
18125  char state[16];
18126  SQLSMALLINT len = 0;
18127  SQLRETURN ret;
18128 
18129  ret = drverror(env, dbc, stmt, (SQLCHAR *) state, nativeErr,
18130  (SQLCHAR *) errmsg, errmax, &len);
18131  if (ret == SQL_SUCCESS) {
18132  if (sqlState) {
18133  uc_from_utf_buf((SQLCHAR *) state, -1, sqlState,
18134  6 * sizeof (SQLWCHAR));
18135  }
18136  if (errmsg) {
18137  if (len > 0) {
18138  SQLWCHAR *e = NULL;
18139 
18140  e = uc_from_utf((SQLCHAR *) errmsg, len);
18141  if (e) {
18142  if (errmax > 0) {
18143  uc_strncpy(errmsg, e, errmax);
18144  e[len] = 0;
18145  len = min(errmax, uc_strlen(e));
18146  } else {
18147  len = uc_strlen(e);
18148  }
18149  uc_free(e);
18150  } else {
18151  len = 0;
18152  }
18153  }
18154  if (len <= 0) {
18155  len = 0;
18156  if (errmax > 0) {
18157  errmsg[0] = 0;
18158  }
18159  }
18160  } else {
18161  len = 0;
18162  }
18163  if (errlen) {
18164  *errlen = len;
18165  }
18166  } else if (ret == SQL_NO_DATA) {
18167  if (sqlState) {
18168  sqlState[0] = 0;
18169  }
18170  if (errmsg) {
18171  if (errmax > 0) {
18172  errmsg[0] = 0;
18173  }
18174  }
18175  if (errlen) {
18176  *errlen = 0;
18177  }
18178  }
18179  return ret;
18180 }
18181 #endif
18182 
18189 SQLRETURN SQL_API
18190 SQLMoreResults(SQLHSTMT stmt)
18191 {
18192  HSTMT_LOCK(stmt);
18193  if (stmt == SQL_NULL_HSTMT) {
18194  return SQL_INVALID_HANDLE;
18195  }
18196  HSTMT_UNLOCK(stmt);
18197  return SQL_NO_DATA;
18198 }
18199 
18208 static SQLRETURN
18209 setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp)
18210 {
18211  int ncols = *ncolsp, guessed_types = 0;
18212  SQLRETURN ret = SQL_SUCCESS;
18213 
18214  if (ncols > 0) {
18215  int i;
18216  PTRDIFF_T size;
18217  char *p;
18218  COL *dyncols;
18219  DBC *d = (DBC *) s->dbc;
18220  const char *colname, *typename;
18221 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18222  char *tblname;
18223 #endif
18224 
18225  for (i = size = 0; i < ncols; i++) {
18226  colname = sqlite3_column_name(s3stmt, i);
18227  size += 3 + 3 * strlen(colname);
18228  }
18229 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18230  tblname = (char *) size;
18231  for (i = 0; i < ncols; i++) {
18232  p = (char *) sqlite3_column_table_name(s3stmt, i);
18233  size += 2 + (p ? strlen(p) : 0);
18234  }
18235 #endif
18236  dyncols = xmalloc(ncols * sizeof (COL) + size);
18237  if (!dyncols) {
18238  freedyncols(s);
18239  *ncolsp = 0;
18240  ret = SQL_ERROR;
18241  } else {
18242  p = (char *) (dyncols + ncols);
18243 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18244  tblname = p + (PTRDIFF_T) tblname;
18245 #endif
18246  for (i = 0; i < ncols; i++) {
18247  char *q;
18248 
18249  colname = sqlite3_column_name(s3stmt, i);
18250  if (d->trace) {
18251  fprintf(d->trace, "-- column %d name: '%s'\n",
18252  i + 1, colname);
18253  fflush(d->trace);
18254  }
18255 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18256  q = (char *) sqlite3_column_table_name(s3stmt, i);
18257  strcpy(tblname, q ? q : "");
18258  if (d->trace) {
18259  fprintf(d->trace, "-- table %d name: '%s'\n",
18260  i + 1, tblname);
18261  fflush(d->trace);
18262  }
18263  dyncols[i].table = tblname;
18264  tblname += strlen(tblname) + 1;
18265 #endif
18266  typename = s3stmt_coltype(s3stmt, i, d, &guessed_types);
18267  dyncols[i].db = ((DBC *) (s->dbc))->dbname;
18268  strcpy(p, colname);
18269  dyncols[i].label = p;
18270  p += strlen(p) + 1;
18271  q = strchr(colname, '.');
18272  if (q) {
18273  char *q2 = strchr(q + 1, '.');
18274 
18275  /* SQLite 3.3.4 produces view.table.column sometimes */
18276  if (q2) {
18277  q = q2;
18278  }
18279  }
18280  if (q) {
18281 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18282  dyncols[i].table = p;
18283 #endif
18284  strncpy(p, colname, q - colname);
18285  p[q - colname] = '\0';
18286  p += strlen(p) + 1;
18287  strcpy(p, q + 1);
18288  dyncols[i].column = p;
18289  p += strlen(p) + 1;
18290  } else {
18291 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18292  dyncols[i].table = "";
18293 #endif
18294  strcpy(p, colname);
18295  dyncols[i].column = p;
18296  p += strlen(p) + 1;
18297  }
18298  if (s->longnames) {
18299  dyncols[i].column = dyncols[i].label;
18300  }
18301 #ifdef SQL_LONGVARCHAR
18302  dyncols[i].type = SQL_LONGVARCHAR;
18303  dyncols[i].size = 65535;
18304 #else
18305  dyncols[i].type = SQL_VARCHAR;
18306  dyncols[i].size = 255;
18307 #endif
18308  dyncols[i].index = i;
18309  dyncols[i].scale = 0;
18310  dyncols[i].prec = 0;
18311  dyncols[i].nosign = 1;
18312  dyncols[i].autoinc = SQL_FALSE;
18313  dyncols[i].notnull = SQL_NULLABLE;
18314  dyncols[i].ispk = -1;
18315  dyncols[i].isrowid = -1;
18316 #ifdef FULL_METADATA
18317  s3stmt_addmeta(s3stmt, i, d, &dyncols[i]);
18318 #endif
18319  dyncols[i].typename = xstrdup(typename);
18320  }
18321  freedyncols(s);
18322  s->dyncols = s->cols = dyncols;
18323  s->dcols = ncols;
18324  fixupdyncols(s, d);
18325  s->guessed_types = guessed_types;
18326  }
18327  }
18328  return ret;
18329 }
18330 
18339 static SQLRETURN
18340 drvprepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18341 {
18342  STMT *s;
18343  DBC *d;
18344  char *errp = NULL;
18345  SQLRETURN sret;
18346 
18347  if (stmt == SQL_NULL_HSTMT) {
18348  return SQL_INVALID_HANDLE;
18349  }
18350  s = (STMT *) stmt;
18351  if (s->dbc == SQL_NULL_HDBC) {
18352 noconn:
18353  return noconn(s);
18354  }
18355  d = s->dbc;
18356  if (!d->sqlite) {
18357  goto noconn;
18358  }
18359  s3stmt_end(s);
18360  s3stmt_drop(s);
18361  sret = starttran(s);
18362  if (sret != SQL_SUCCESS) {
18363  return sret;
18364  }
18365  freep(&s->query);
18366  s->query = (SQLCHAR *) fixupsql((char *) query, queryLen,
18367  (d->version >= 0x030805),
18368  &s->nparams, &s->isselect, &errp);
18369  if (!s->query) {
18370  if (errp) {
18371  setstat(s, -1, "%s", (*s->ov3) ? "HY000" : "S1000", errp);
18372  return SQL_ERROR;
18373  }
18374  return nomem(s);
18375  }
18376  errp = NULL;
18377  freeresult(s, -1);
18378  if (s->isselect == 1) {
18379  int ret, ncols, nretry = 0;
18380  const char *rest;
18381  sqlite3_stmt *s3stmt = NULL;
18382 
18383 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18384  dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
18385 #else
18386  dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
18387 #endif
18388  do {
18389  s3stmt = NULL;
18390 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18391  ret = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
18392  &s3stmt, &rest);
18393 #else
18394  ret = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
18395  &s3stmt, &rest);
18396 #endif
18397  if (ret != SQLITE_OK) {
18398  if (s3stmt) {
18399  sqlite3_finalize(s3stmt);
18400  s3stmt = NULL;
18401  }
18402  }
18403  } while (ret == SQLITE_SCHEMA && (++nretry) < 2);
18404  dbtracerc(d, ret, NULL);
18405  if (ret != SQLITE_OK) {
18406  if (s3stmt) {
18407  dbtraceapi(d, "sqlite3_finalize", 0);
18408  sqlite3_finalize(s3stmt);
18409  }
18410  setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18411  sqlite3_errmsg(d->sqlite), ret);
18412  return SQL_ERROR;
18413  }
18414  if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
18415  dbtraceapi(d, "sqlite3_finalize", 0);
18416  sqlite3_finalize(s3stmt);
18417  setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
18418  (*s->ov3) ? "HY000" : "S1000");
18419  return SQL_ERROR;
18420  }
18421  ncols = sqlite3_column_count(s3stmt);
18422  s->guessed_types = 0;
18423  setupdyncols(s, s3stmt, &ncols);
18424  s->ncols = ncols;
18425  s->s3stmt = s3stmt;
18426  }
18427  mkbindcols(s, s->ncols);
18428  s->paramset_count = 0;
18429  return SQL_SUCCESS;
18430 }
18431 
18439 static SQLRETURN
18440 drvexecute(SQLHSTMT stmt, int initial)
18441 {
18442  STMT *s;
18443  DBC *d;
18444  char *errp = NULL;
18445  int rc, i, ncols = 0, nrows = 0, busy_count;
18446  SQLRETURN ret;
18447 
18448  if (stmt == SQL_NULL_HSTMT) {
18449  return SQL_INVALID_HANDLE;
18450  }
18451  s = (STMT *) stmt;
18452  if (s->dbc == SQL_NULL_HDBC) {
18453 noconn:
18454  return noconn(s);
18455  }
18456  d = (DBC *) s->dbc;
18457  if (!d->sqlite) {
18458  goto noconn;
18459  }
18460  if (!s->query) {
18461  setstat(s, -1, "no query prepared", (*s->ov3) ? "HY000" : "S1000");
18462  return SQL_ERROR;
18463  }
18464  if (s->nbindparms < s->nparams) {
18465 unbound:
18466  setstat(s, -1, "unbound parameters in query",
18467  (*s->ov3) ? "HY000" : "S1000");
18468  return SQL_ERROR;
18469  }
18470  for (i = 0; i < s->nparams; i++) {
18471  BINDPARM *p = &s->bindparms[i];
18472 
18473  if (!p->bound) {
18474  goto unbound;
18475  }
18476  if (initial) {
18477  SQLLEN *lenp = p->lenp;
18478 
18479  if (lenp && *lenp < 0 && *lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18480  *lenp != SQL_NTS && *lenp != SQL_NULL_DATA &&
18481  *lenp != SQL_DATA_AT_EXEC) {
18482  setstat(s, -1, "invalid length reference", "HY009");
18483  return SQL_ERROR;
18484  }
18485  if (lenp && (*lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18486  *lenp == SQL_DATA_AT_EXEC)) {
18487  p->need = 1;
18488  p->offs = 0;
18489  p->len = 0;
18490  }
18491  }
18492  }
18493  ret = starttran(s);
18494  if (ret != SQL_SUCCESS) {
18495  goto cleanup;
18496  }
18497  busy_count = 0;
18498 again:
18499  s3stmt_end(s);
18500  if (initial) {
18501  /* fixup data-at-execution parameters and alloc'ed blobs */
18502  s->pdcount = -1;
18503  for (i = 0; i < s->nparams; i++) {
18504  BINDPARM *p = &s->bindparms[i];
18505 
18506  if (p->param == p->parbuf) {
18507  p->param = NULL;
18508  }
18509  freep(&p->parbuf);
18510  if (p->need <= 0 &&
18511  p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18512  *p->lenp == SQL_DATA_AT_EXEC)) {
18513  p->need = 1;
18514  p->offs = 0;
18515  p->len = 0;
18516  }
18517  }
18518  }
18519  if (s->nparams) {
18520  for (i = 0; i < s->nparams; i++) {
18521  ret = setupparam(s, (char *) s->query, i);
18522  if (ret != SQL_SUCCESS) {
18523  goto cleanup;
18524  }
18525  }
18526  }
18527  freeresult(s, 0);
18528  if (s->isselect == 1 && !d->intrans &&
18529  s->curtype == SQL_CURSOR_FORWARD_ONLY &&
18530  d->step_enable && s->nparams == 0 && d->cur_s3stmt == NULL) {
18531  s->nrows = -1;
18532  ret = s3stmt_start(s);
18533  if (ret == SQL_SUCCESS) {
18534  goto done2;
18535  }
18536  }
18537  rc = drvgettable(s, s->s3stmt ? NULL : (char *) s->query, &s->rows,
18538  &s->nrows, &ncols, &errp, s->nparams, s->bindparms);
18539  dbtracerc(d, rc, errp);
18540  if (rc == SQLITE_BUSY) {
18541  if (busy_handler((void *) d, ++busy_count)) {
18542  if (errp) {
18543  sqlite3_free(errp);
18544  errp = NULL;
18545  }
18546  for (i = 0; i < s->nparams; i++) {
18547  BINDPARM *p = &s->bindparms[i];
18548 
18549  if (p->param == p->parbuf) {
18550  p->param = NULL;
18551  }
18552  freep(&p->parbuf);
18553  if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18554  *p->lenp != SQL_DATA_AT_EXEC)) {
18555  p->param = p->param0;
18556  }
18557  p->lenp = p->lenp0;
18558  }
18559  s->nrows = 0;
18560  goto again;
18561  }
18562  }
18563  if (rc != SQLITE_OK) {
18564  setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18565  errp ? errp : "unknown error", rc);
18566  if (errp) {
18567  sqlite3_free(errp);
18568  errp = NULL;
18569  }
18570  ret = SQL_ERROR;
18571  goto cleanup;
18572  }
18573  if (errp) {
18574  sqlite3_free(errp);
18575  errp = NULL;
18576  }
18577  s->rowfree = freerows;
18578  if (s->isselect <= 0 || s->isselect > 1) {
18579  /*
18580  * INSERT/UPDATE/DELETE or DDL results are immediately released.
18581  */
18582  freeresult(s, -1);
18583  nrows += sqlite3_changes(d->sqlite);
18584  s->nrows = nrows;
18585  goto done;
18586  }
18587  if (s->ncols != ncols) {
18588  /*
18589  * Weird result.
18590  */
18591  setstat(s, -1, "broken result set %d/%d",
18592  (*s->ov3) ? "HY000" : "S1000", s->ncols, ncols);
18593  ret = SQL_ERROR;
18594  goto cleanup;
18595  }
18596 done:
18597  mkbindcols(s, s->ncols);
18598 done2:
18599  ret = SQL_SUCCESS;
18600  s->rowp = s->rowprs = -1;
18601  s->paramset_count++;
18602  s->paramset_nrows = s->nrows;
18603  if (s->paramset_count < s->paramset_size) {
18604  for (i = 0; i < s->nparams; i++) {
18605  BINDPARM *p = &s->bindparms[i];
18606 
18607  if (p->param == p->parbuf) {
18608  p->param = NULL;
18609  }
18610  freep(&p->parbuf);
18611  if (p->lenp0 &&
18612  s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18613  p->lenp = (SQLLEN *) ((char *) p->lenp0 +
18614  s->paramset_count * s->parm_bind_type);
18615  } else if (p->lenp0 && p->inc > 0) {
18616  p->lenp = p->lenp0 + s->paramset_count;
18617  }
18618  if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18619  *p->lenp != SQL_DATA_AT_EXEC)) {
18620  if (p->param0 &&
18621  s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18622  p->param = (char *) p->param0 +
18624  } else if (p->param0 && p->inc > 0) {
18625  p->param = (char *) p->param0 +
18626  s->paramset_count * p->inc;
18627  }
18628  } else if (p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18629  *p->lenp == SQL_DATA_AT_EXEC)) {
18630  p->need = 1;
18631  p->offs = 0;
18632  p->len = 0;
18633  }
18634  }
18635  goto again;
18636  }
18637 cleanup:
18638  if (ret != SQL_NEED_DATA) {
18639  for (i = 0; i < s->nparams; i++) {
18640  BINDPARM *p = &s->bindparms[i];
18641 
18642  if (p->param == p->parbuf) {
18643  p->param = NULL;
18644  }
18645  freep(&p->parbuf);
18646  if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18647  *p->lenp != SQL_DATA_AT_EXEC)) {
18648  p->param = p->param0;
18649  }
18650  p->lenp = p->lenp0;
18651  }
18652  s->nrows = s->paramset_nrows;
18653  if (s->parm_proc) {
18654  *s->parm_proc = s->paramset_count;
18655  }
18656  s->paramset_count = 0;
18657  s->paramset_nrows = 0;
18658  }
18659  /*
18660  * For INSERT/UPDATE/DELETE statements change the return code
18661  * to SQL_NO_DATA if the number of rows affected was 0.
18662  */
18663  if (*s->ov3 && s->isselect == 0 &&
18664  ret == SQL_SUCCESS && nrows == 0) {
18665  ret = SQL_NO_DATA;
18666  }
18667  return ret;
18668 }
18669 
18670 #ifndef WINTERFACE
18671 
18679 SQLRETURN SQL_API
18680 SQLPrepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18681 {
18682  SQLRETURN ret;
18683 #if defined(_WIN32) || defined(_WIN64)
18684  char *q;
18685 #endif
18686 
18687  HSTMT_LOCK(stmt);
18688 #if defined(_WIN32) || defined(_WIN64)
18689  if (!((STMT *) stmt)->oemcp[0]) {
18690  ret = drvprepare(stmt, query, queryLen);
18691  goto done;
18692  }
18693  q = wmb_to_utf_c((char *) query, queryLen);
18694  if (!q) {
18695  ret = nomem((STMT *) stmt);
18696  goto done;
18697  }
18698  query = (SQLCHAR *) q;
18699  queryLen = SQL_NTS;
18700 #endif
18701  ret = drvprepare(stmt, query, queryLen);
18702 #if defined(_WIN32) || defined(_WIN64)
18703  uc_free(q);
18704 done:
18705  ;
18706 #endif
18707  HSTMT_UNLOCK(stmt);
18708  return ret;
18709 }
18710 #endif
18711 
18712 #ifdef WINTERFACE
18713 
18721 SQLRETURN SQL_API
18722 SQLPrepareW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
18723 {
18724  SQLRETURN ret;
18725  char *q = uc_to_utf_c(query, queryLen);
18726 
18727  HSTMT_LOCK(stmt);
18728  if (!q) {
18729  ret = nomem((STMT *) stmt);
18730  goto done;
18731  }
18732  ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
18733  uc_free(q);
18734 done:
18735  HSTMT_UNLOCK(stmt);
18736  return ret;
18737 }
18738 #endif
18739 
18746 SQLRETURN SQL_API
18747 SQLExecute(SQLHSTMT stmt)
18748 {
18749  SQLRETURN ret;
18750 
18751  HSTMT_LOCK(stmt);
18752  ret = drvexecute(stmt, 1);
18753  HSTMT_UNLOCK(stmt);
18754  return ret;
18755 }
18756 
18757 #ifndef WINTERFACE
18758 
18766 SQLRETURN SQL_API
18767 SQLExecDirect(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18768 {
18769  SQLRETURN ret;
18770 #if defined(_WIN32) || defined(_WIN64)
18771  char *q;
18772 #endif
18773 
18774  HSTMT_LOCK(stmt);
18775 #if defined(_WIN32) || defined(_WIN64)
18776  if (!((STMT *) stmt)->oemcp[0]) {
18777  ret = drvprepare(stmt, query, queryLen);
18778  if (ret == SQL_SUCCESS) {
18779  ret = drvexecute(stmt, 1);
18780  }
18781  goto done;
18782  }
18783  q = wmb_to_utf_c((char *) query, queryLen);
18784  if (!q) {
18785  ret = nomem((STMT *) stmt);
18786  goto done;
18787  }
18788  query = (SQLCHAR *) q;
18789  queryLen = SQL_NTS;
18790 #endif
18791  ret = drvprepare(stmt, query, queryLen);
18792  if (ret == SQL_SUCCESS) {
18793  ret = drvexecute(stmt, 1);
18794  }
18795 #if defined(_WIN32) || defined(_WIN64)
18796  uc_free(q);
18797 done:
18798  ;
18799 #endif
18800  HSTMT_UNLOCK(stmt);
18801  return ret;
18802 }
18803 #endif
18804 
18805 #ifdef WINTERFACE
18806 
18814 SQLRETURN SQL_API
18815 SQLExecDirectW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
18816 {
18817  SQLRETURN ret;
18818  char *q = uc_to_utf_c(query, queryLen);
18819 
18820  HSTMT_LOCK(stmt);
18821  if (!q) {
18822  ret = nomem((STMT *) stmt);
18823  goto done;
18824  }
18825  ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
18826  uc_free(q);
18827  if (ret == SQL_SUCCESS) {
18828  ret = drvexecute(stmt, 1);
18829  }
18830 done:
18831  HSTMT_UNLOCK(stmt);
18832  return ret;
18833 }
18834 #endif
18835 
18836 
18837 #if defined(_WIN32) || defined(_WIN64)
18838 #ifndef WITHOUT_DRIVERMGR
18839 
18840 /*
18841  * Windows configuration dialog stuff.
18842  */
18843 
18844 #include <windowsx.h>
18845 #include <winuser.h>
18846 
18847 #define MAXPATHLEN (259+1) /* Max path length */
18848 #define MAXKEYLEN (15+1) /* Max keyword length */
18849 #define MAXDESC (255+1) /* Max description length */
18850 #define MAXDSNAME (255+1) /* Max data source name length */
18851 #define MAXTONAME (32+1) /* Max timeout length */
18852 #define MAXDBNAME MAXPATHLEN
18853 
18854 /* Attribute key indexes into an array of Attr structs, see below */
18855 
18856 #define KEY_DSN 0
18857 #define KEY_DESC 1
18858 #define KEY_DBNAME 2
18859 #define KEY_BUSY 3
18860 #define KEY_DRIVER 4
18861 #define KEY_STEPAPI 5
18862 #define KEY_SYNCP 6
18863 #define KEY_NOTXN 7
18864 #define KEY_SHORTNAM 8
18865 #define KEY_LONGNAM 9
18866 #define KEY_NOCREAT 10
18867 #define KEY_NOWCHAR 11
18868 #define KEY_LOADEXT 12
18869 #define KEY_JMODE 13
18870 #define KEY_FKSUPPORT 14
18871 #define KEY_OEMCP 15
18872 #define KEY_BIGINT 16
18873 #define KEY_PASSWD 17
18874 #define KEY_JDCONV 18
18875 #define NUMOFKEYS 19
18876 
18877 typedef struct {
18878  BOOL supplied;
18879  char attr[MAXPATHLEN*4];
18880 } ATTR;
18881 
18882 typedef struct {
18883  SQLHWND parent;
18884  LPCSTR driver;
18885  ATTR attr[NUMOFKEYS];
18886  char DSN[MAXDSNAME];
18887  BOOL newDSN;
18888  BOOL defDSN;
18889 } SETUPDLG;
18890 
18891 static struct {
18892  char *key;
18893  int ikey;
18894 } attrLookup[] = {
18895  { "DSN", KEY_DSN },
18896  { "DESC", KEY_DESC },
18897  { "Description", KEY_DESC},
18898  { "Database", KEY_DBNAME },
18899  { "Timeout", KEY_BUSY },
18900  { "Driver", KEY_DRIVER },
18901  { "StepAPI", KEY_STEPAPI },
18902  { "SyncPragma", KEY_SYNCP },
18903  { "NoTXN", KEY_NOTXN },
18904  { "ShortNames", KEY_SHORTNAM },
18905  { "LongNames", KEY_LONGNAM },
18906  { "NoCreat", KEY_NOCREAT },
18907  { "NoWCHAR", KEY_NOWCHAR },
18908  { "LoadExt", KEY_LOADEXT },
18909  { "JournalMode", KEY_JMODE },
18910  { "FKSupport", KEY_FKSUPPORT },
18911  { "OEMCP", KEY_OEMCP },
18912  { "BigInt", KEY_BIGINT },
18913  { "PWD", KEY_PASSWD },
18914  { "JDConv", KEY_JDCONV },
18915  { NULL, 0 }
18916 };
18917 
18924 static void
18925 ParseAttributes(LPCSTR attribs, SETUPDLG *setupdlg)
18926 {
18927  char *str = (char *) attribs, *start, key[MAXKEYLEN];
18928  int elem, nkey;
18929 
18930  while (*str) {
18931  start = str;
18932  if ((str = strchr(str, '=')) == NULL) {
18933  return;
18934  }
18935  elem = -1;
18936  nkey = str - start;
18937  if (nkey < sizeof (key)) {
18938  int i;
18939 
18940  memcpy(key, start, nkey);
18941  key[nkey] = '\0';
18942  for (i = 0; attrLookup[i].key; i++) {
18943  if (strcasecmp(attrLookup[i].key, key) == 0) {
18944  elem = attrLookup[i].ikey;
18945  break;
18946  }
18947  }
18948  }
18949  start = ++str;
18950  while (*str && *str != ';') {
18951  ++str;
18952  }
18953  if (elem >= 0) {
18954  int end = min(str - start, sizeof (setupdlg->attr[elem].attr) - 1);
18955 
18956  setupdlg->attr[elem].supplied = TRUE;
18957  memcpy(setupdlg->attr[elem].attr, start, end);
18958  setupdlg->attr[elem].attr[end] = '\0';
18959  }
18960  ++str;
18961  }
18962 }
18963 
18971 static BOOL
18972 SetDSNAttributes(HWND parent, SETUPDLG *setupdlg)
18973 {
18974  char *dsn = setupdlg->attr[KEY_DSN].attr;
18975 
18976  if (setupdlg->newDSN && strlen(dsn) == 0) {
18977  return FALSE;
18978  }
18979  if (!SQLWriteDSNToIni(dsn, setupdlg->driver)) {
18980  if (parent) {
18981  char buf[MAXPATHLEN], msg[MAXPATHLEN];
18982 
18983  LoadString(hModule, IDS_BADDSN, buf, sizeof (buf));
18984  wsprintf(msg, buf, dsn);
18985  LoadString(hModule, IDS_MSGTITLE, buf, sizeof (buf));
18986  MessageBox(parent, msg, buf,
18987  MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
18988  MB_SETFOREGROUND);
18989  }
18990  return FALSE;
18991  }
18992  if (parent || setupdlg->attr[KEY_DESC].supplied) {
18993  SQLWritePrivateProfileString(dsn, "Description",
18994  setupdlg->attr[KEY_DESC].attr,
18995  ODBC_INI);
18996  }
18997  if (parent || setupdlg->attr[KEY_DBNAME].supplied) {
18998  SQLWritePrivateProfileString(dsn, "Database",
18999  setupdlg->attr[KEY_DBNAME].attr,
19000  ODBC_INI);
19001  }
19002  if (parent || setupdlg->attr[KEY_BUSY].supplied) {
19003  SQLWritePrivateProfileString(dsn, "Timeout",
19004  setupdlg->attr[KEY_BUSY].attr,
19005  ODBC_INI);
19006  }
19007  if (parent || setupdlg->attr[KEY_STEPAPI].supplied) {
19008  SQLWritePrivateProfileString(dsn, "StepAPI",
19009  setupdlg->attr[KEY_STEPAPI].attr,
19010  ODBC_INI);
19011  }
19012  if (parent || setupdlg->attr[KEY_SYNCP].supplied) {
19013  SQLWritePrivateProfileString(dsn, "SyncPragma",
19014  setupdlg->attr[KEY_SYNCP].attr,
19015  ODBC_INI);
19016  }
19017  if (parent || setupdlg->attr[KEY_NOTXN].supplied) {
19018  SQLWritePrivateProfileString(dsn, "NoTXN",
19019  setupdlg->attr[KEY_NOTXN].attr,
19020  ODBC_INI);
19021  }
19022  if (parent || setupdlg->attr[KEY_SHORTNAM].supplied) {
19023  SQLWritePrivateProfileString(dsn, "ShortNames",
19024  setupdlg->attr[KEY_SHORTNAM].attr,
19025  ODBC_INI);
19026  }
19027  if (parent || setupdlg->attr[KEY_LONGNAM].supplied) {
19028  SQLWritePrivateProfileString(dsn, "LongNames",
19029  setupdlg->attr[KEY_LONGNAM].attr,
19030  ODBC_INI);
19031  }
19032  if (parent || setupdlg->attr[KEY_NOCREAT].supplied) {
19033  SQLWritePrivateProfileString(dsn, "NoCreat",
19034  setupdlg->attr[KEY_NOCREAT].attr,
19035  ODBC_INI);
19036  }
19037  if (parent || setupdlg->attr[KEY_NOWCHAR].supplied) {
19038  SQLWritePrivateProfileString(dsn, "NoWCHAR",
19039  setupdlg->attr[KEY_NOWCHAR].attr,
19040  ODBC_INI);
19041  }
19042  if (parent || setupdlg->attr[KEY_FKSUPPORT].supplied) {
19043  SQLWritePrivateProfileString(dsn, "FKSupport",
19044  setupdlg->attr[KEY_FKSUPPORT].attr,
19045  ODBC_INI);
19046  }
19047  if (parent || setupdlg->attr[KEY_OEMCP].supplied) {
19048  SQLWritePrivateProfileString(dsn, "OEMCP",
19049  setupdlg->attr[KEY_OEMCP].attr,
19050  ODBC_INI);
19051  }
19052  if (parent || setupdlg->attr[KEY_LOADEXT].supplied) {
19053  SQLWritePrivateProfileString(dsn, "LoadExt",
19054  setupdlg->attr[KEY_LOADEXT].attr,
19055  ODBC_INI);
19056  }
19057  if (parent || setupdlg->attr[KEY_BIGINT].supplied) {
19058  SQLWritePrivateProfileString(dsn, "BigInt",
19059  setupdlg->attr[KEY_BIGINT].attr,
19060  ODBC_INI);
19061  }
19062  if (parent || setupdlg->attr[KEY_JDCONV].supplied) {
19063  SQLWritePrivateProfileString(dsn, "JDConv",
19064  setupdlg->attr[KEY_JDCONV].attr,
19065  ODBC_INI);
19066  }
19067  if (parent || setupdlg->attr[KEY_PASSWD].supplied) {
19068  SQLWritePrivateProfileString(dsn, "PWD",
19069  setupdlg->attr[KEY_PASSWD].attr,
19070  ODBC_INI);
19071  }
19072  if (setupdlg->attr[KEY_DSN].supplied &&
19073  strcasecmp(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr)) {
19074  SQLRemoveDSNFromIni(setupdlg->DSN);
19075  }
19076  return TRUE;
19077 }
19078 
19084 static void
19085 GetAttributes(SETUPDLG *setupdlg)
19086 {
19087  char *dsn = setupdlg->attr[KEY_DSN].attr;
19088 
19089  if (!setupdlg->attr[KEY_DESC].supplied) {
19090  SQLGetPrivateProfileString(dsn, "Description", "",
19091  setupdlg->attr[KEY_DESC].attr,
19092  sizeof (setupdlg->attr[KEY_DESC].attr),
19093  ODBC_INI);
19094  }
19095  if (!setupdlg->attr[KEY_DBNAME].supplied) {
19096  SQLGetPrivateProfileString(dsn, "Database", "",
19097  setupdlg->attr[KEY_DBNAME].attr,
19098  sizeof (setupdlg->attr[KEY_DBNAME].attr),
19099  ODBC_INI);
19100  }
19101  if (!setupdlg->attr[KEY_BUSY].supplied) {
19102  SQLGetPrivateProfileString(dsn, "Timeout", "100000",
19103  setupdlg->attr[KEY_BUSY].attr,
19104  sizeof (setupdlg->attr[KEY_BUSY].attr),
19105  ODBC_INI);
19106  }
19107  if (!setupdlg->attr[KEY_STEPAPI].supplied) {
19108  SQLGetPrivateProfileString(dsn, "StepAPI", "0",
19109  setupdlg->attr[KEY_STEPAPI].attr,
19110  sizeof (setupdlg->attr[KEY_STEPAPI].attr),
19111  ODBC_INI);
19112  }
19113  if (!setupdlg->attr[KEY_SYNCP].supplied) {
19114  SQLGetPrivateProfileString(dsn, "SyncPragma", "NORMAL",
19115  setupdlg->attr[KEY_SYNCP].attr,
19116  sizeof (setupdlg->attr[KEY_SYNCP].attr),
19117  ODBC_INI);
19118  }
19119  if (!setupdlg->attr[KEY_NOTXN].supplied) {
19120  SQLGetPrivateProfileString(dsn, "NoTXN", "",
19121  setupdlg->attr[KEY_NOTXN].attr,
19122  sizeof (setupdlg->attr[KEY_NOTXN].attr),
19123  ODBC_INI);
19124  }
19125  if (!setupdlg->attr[KEY_SHORTNAM].supplied) {
19126  SQLGetPrivateProfileString(dsn, "ShortNames", "",
19127  setupdlg->attr[KEY_SHORTNAM].attr,
19128  sizeof (setupdlg->attr[KEY_SHORTNAM].attr),
19129  ODBC_INI);
19130  }
19131  if (!setupdlg->attr[KEY_LONGNAM].supplied) {
19132  SQLGetPrivateProfileString(dsn, "LongNames", "",
19133  setupdlg->attr[KEY_LONGNAM].attr,
19134  sizeof (setupdlg->attr[KEY_LONGNAM].attr),
19135  ODBC_INI);
19136  }
19137  if (!setupdlg->attr[KEY_NOCREAT].supplied) {
19138  SQLGetPrivateProfileString(dsn, "NoCreat", "",
19139  setupdlg->attr[KEY_NOCREAT].attr,
19140  sizeof (setupdlg->attr[KEY_NOCREAT].attr),
19141  ODBC_INI);
19142  }
19143  if (!setupdlg->attr[KEY_NOWCHAR].supplied) {
19144  SQLGetPrivateProfileString(dsn, "NoWCHAR", "",
19145  setupdlg->attr[KEY_NOWCHAR].attr,
19146  sizeof (setupdlg->attr[KEY_NOWCHAR].attr),
19147  ODBC_INI);
19148  }
19149  if (!setupdlg->attr[KEY_FKSUPPORT].supplied) {
19150  SQLGetPrivateProfileString(dsn, "FKSupport", "",
19151  setupdlg->attr[KEY_FKSUPPORT].attr,
19152  sizeof (setupdlg->attr[KEY_FKSUPPORT].attr),
19153  ODBC_INI);
19154  }
19155  if (!setupdlg->attr[KEY_OEMCP].supplied) {
19156  SQLGetPrivateProfileString(dsn, "OEMCP", "",
19157  setupdlg->attr[KEY_OEMCP].attr,
19158  sizeof (setupdlg->attr[KEY_OEMCP].attr),
19159  ODBC_INI);
19160  }
19161  if (!setupdlg->attr[KEY_LOADEXT].supplied) {
19162  SQLGetPrivateProfileString(dsn, "LoadExt", "",
19163  setupdlg->attr[KEY_LOADEXT].attr,
19164  sizeof (setupdlg->attr[KEY_LOADEXT].attr),
19165  ODBC_INI);
19166  }
19167  if (!setupdlg->attr[KEY_JMODE].supplied) {
19168  SQLGetPrivateProfileString(dsn, "JournalMode", "",
19169  setupdlg->attr[KEY_JMODE].attr,
19170  sizeof (setupdlg->attr[KEY_JMODE].attr),
19171  ODBC_INI);
19172  }
19173  if (!setupdlg->attr[KEY_BIGINT].supplied) {
19174  SQLGetPrivateProfileString(dsn, "BigInt", "",
19175  setupdlg->attr[KEY_BIGINT].attr,
19176  sizeof (setupdlg->attr[KEY_BIGINT].attr),
19177  ODBC_INI);
19178  }
19179  if (!setupdlg->attr[KEY_PASSWD].supplied) {
19180  SQLGetPrivateProfileString(dsn, "PWD", "",
19181  setupdlg->attr[KEY_PASSWD].attr,
19182  sizeof (setupdlg->attr[KEY_PASSWD].attr),
19183  ODBC_INI);
19184  }
19185  if (!setupdlg->attr[KEY_JDCONV].supplied) {
19186  SQLGetPrivateProfileString(dsn, "JDConv", "",
19187  setupdlg->attr[KEY_JDCONV].attr,
19188  sizeof (setupdlg->attr[KEY_JDCONV].attr),
19189  ODBC_INI);
19190  }
19191 }
19192 
19198 static void
19199 GetDBFile(HWND hdlg)
19200 {
19201 #ifdef _WIN64
19202  SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19203 #else
19204  SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19205 #endif
19206  OPENFILENAME ofn;
19207 
19208  memset(&ofn, 0, sizeof (ofn));
19209  ofn.lStructSize = sizeof (ofn);
19210  ofn.hwndOwner = hdlg;
19211 #ifdef _WIN64
19212  ofn.hInstance = (HINSTANCE) GetWindowLongPtr(hdlg, GWLP_HINSTANCE);
19213 #else
19214  ofn.hInstance = (HINSTANCE) GetWindowLong(hdlg, GWL_HINSTANCE);
19215 #endif
19216  ofn.lpstrFile = (LPTSTR) setupdlg->attr[KEY_DBNAME].attr;
19217  ofn.nMaxFile = MAXPATHLEN;
19218  ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST |
19219  OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_FILEMUSTEXIST;
19220  if (GetOpenFileName(&ofn)) {
19221  SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19222  setupdlg->attr[KEY_DBNAME].supplied = TRUE;
19223  }
19224 }
19225 
19235 static BOOL CALLBACK
19236 ConfigDlgProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19237 {
19238  SETUPDLG *setupdlg = NULL;
19239  WORD index;
19240 
19241  switch (wmsg) {
19242  case WM_INITDIALOG:
19243 #ifdef _WIN64
19244  SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19245 #else
19246  SetWindowLong(hdlg, DWL_USER, lparam);
19247 #endif
19248  setupdlg = (SETUPDLG *) lparam;
19249  GetAttributes(setupdlg);
19250  SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19251  SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19252  SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19253  SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19254  SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19255  SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19256  (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19257  SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19258  (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19259  SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19260  (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19261  SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19262  (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19263  SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19264  (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19265  CheckDlgButton(hdlg, IDC_STEPAPI,
19266  getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19267  BST_CHECKED : BST_UNCHECKED);
19268  CheckDlgButton(hdlg, IDC_NOTXN,
19269  getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19270  BST_CHECKED : BST_UNCHECKED);
19271  CheckDlgButton(hdlg, IDC_SHORTNAM,
19272  getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19273  BST_CHECKED : BST_UNCHECKED);
19274  CheckDlgButton(hdlg, IDC_LONGNAM,
19275  getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19276  BST_CHECKED : BST_UNCHECKED);
19277  CheckDlgButton(hdlg, IDC_NOCREAT,
19278  getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19279  BST_CHECKED : BST_UNCHECKED);
19280  CheckDlgButton(hdlg, IDC_NOWCHAR,
19281  getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19282  BST_CHECKED : BST_UNCHECKED);
19283  CheckDlgButton(hdlg, IDC_FKSUPPORT,
19284  getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19285  BST_CHECKED : BST_UNCHECKED);
19286  CheckDlgButton(hdlg, IDC_OEMCP,
19287  getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19288  BST_CHECKED : BST_UNCHECKED);
19289  CheckDlgButton(hdlg, IDC_BIGINT,
19290  getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19291  BST_CHECKED : BST_UNCHECKED);
19292  CheckDlgButton(hdlg, IDC_JDCONV,
19293  getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19294  BST_CHECKED : BST_UNCHECKED);
19295  SendDlgItemMessage(hdlg, IDC_SYNCP,
19296  CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19297  SendDlgItemMessage(hdlg, IDC_SYNCP,
19298  CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19299  SendDlgItemMessage(hdlg, IDC_SYNCP,
19300  CB_ADDSTRING, 0, (LPARAM) "OFF");
19301  SendDlgItemMessage(hdlg, IDC_SYNCP,
19302  CB_ADDSTRING, 0, (LPARAM) "FULL");
19303  SendDlgItemMessage(hdlg, IDC_SYNCP,
19304  CB_SELECTSTRING, (WPARAM) -1,
19305  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19306  if (setupdlg->defDSN) {
19307  EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19308  EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19309  }
19310  return TRUE;
19311  case WM_COMMAND:
19312  switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19313  case IDC_DSNAME:
19314  if (GET_WM_COMMAND_CMD(wparam, lparam) == EN_CHANGE) {
19315  char item[MAXDSNAME];
19316 
19317  EnableWindow(GetDlgItem(hdlg, IDOK),
19318  GetDlgItemText(hdlg, IDC_DSNAME,
19319  item, sizeof (item)));
19320  return TRUE;
19321  }
19322  break;
19323  case IDC_BROWSE:
19324  GetDBFile(hdlg);
19325  break;
19326  case IDOK:
19327 #ifdef _WIN64
19328  setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19329 #else
19330  setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19331 #endif
19332  if (!setupdlg->defDSN) {
19333  GetDlgItemText(hdlg, IDC_DSNAME,
19334  setupdlg->attr[KEY_DSN].attr,
19335  sizeof (setupdlg->attr[KEY_DSN].attr));
19336  }
19337  GetDlgItemText(hdlg, IDC_DESC,
19338  setupdlg->attr[KEY_DESC].attr,
19339  sizeof (setupdlg->attr[KEY_DESC].attr));
19340  GetDlgItemText(hdlg, IDC_DBNAME,
19341  setupdlg->attr[KEY_DBNAME].attr,
19342  sizeof (setupdlg->attr[KEY_DBNAME].attr));
19343  GetDlgItemText(hdlg, IDC_TONAME,
19344  setupdlg->attr[KEY_BUSY].attr,
19345  sizeof (setupdlg->attr[KEY_BUSY].attr));
19346  GetDlgItemText(hdlg, IDC_LOADEXT,
19347  setupdlg->attr[KEY_LOADEXT].attr,
19348  sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19349  index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19350  CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19351  if (index != (WORD) CB_ERR) {
19352  SendDlgItemMessage(hdlg, IDC_SYNCP,
19353  CB_GETLBTEXT, index,
19354  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19355  }
19356  strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19357  (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19358  "1" : "0");
19359  strcpy(setupdlg->attr[KEY_NOTXN].attr,
19360  (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19361  "1" : "0");
19362  strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19363  (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19364  "1" : "0");
19365  strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19366  (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19367  "1" : "0");
19368  strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19369  (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19370  "1" : "0");
19371  strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19372  (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19373  "1" : "0");
19374  strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19375  (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19376  "1" : "0");
19377  strcpy(setupdlg->attr[KEY_OEMCP].attr,
19378  (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19379  "1" : "0");
19380  strcpy(setupdlg->attr[KEY_BIGINT].attr,
19381  (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19382  "1" : "0");
19383  strcpy(setupdlg->attr[KEY_JDCONV].attr,
19384  (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19385  "1" : "0");
19386  SetDSNAttributes(hdlg, setupdlg);
19387  /* FALL THROUGH */
19388  case IDCANCEL:
19389  EndDialog(hdlg, wparam);
19390  return TRUE;
19391  }
19392  break;
19393  }
19394  return FALSE;
19395 }
19396 
19406 BOOL INSTAPI
19407 ConfigDSN(HWND hwnd, WORD request, LPCSTR driver, LPCSTR attribs)
19408 {
19409  BOOL success;
19410  SETUPDLG *setupdlg;
19411 
19412  setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
19413  if (setupdlg == NULL) {
19414  return FALSE;
19415  }
19416  memset(setupdlg, 0, sizeof (SETUPDLG));
19417  if (attribs) {
19418  ParseAttributes(attribs, setupdlg);
19419  }
19420  if (setupdlg->attr[KEY_DSN].supplied) {
19421  strcpy(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr);
19422  } else {
19423  setupdlg->DSN[0] = '\0';
19424  }
19425  if (request == ODBC_REMOVE_DSN) {
19426  if (!setupdlg->attr[KEY_DSN].supplied) {
19427  success = FALSE;
19428  } else {
19429  success = SQLRemoveDSNFromIni(setupdlg->attr[KEY_DSN].attr);
19430  }
19431  } else {
19432  setupdlg->parent = hwnd;
19433  setupdlg->driver = driver;
19434  setupdlg->newDSN = request == ODBC_ADD_DSN;
19435  setupdlg->defDSN = strcasecmp(setupdlg->attr[KEY_DSN].attr,
19436  "Default") == 0;
19437  if (hwnd) {
19438  success = DialogBoxParam(hModule, MAKEINTRESOURCE(CONFIGDSN),
19439  hwnd, (DLGPROC) ConfigDlgProc,
19440  (LPARAM) setupdlg) == IDOK;
19441  } else if (setupdlg->attr[KEY_DSN].supplied) {
19442  success = SetDSNAttributes(hwnd, setupdlg);
19443  } else {
19444  success = FALSE;
19445  }
19446  }
19447  xfree(setupdlg);
19448  return success;
19449 }
19450 
19460 static BOOL CALLBACK
19461 DriverConnectProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19462 {
19463  SETUPDLG *setupdlg;
19464  WORD index;
19465 
19466  switch (wmsg) {
19467  case WM_INITDIALOG:
19468 #ifdef _WIN64
19469  SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19470 #else
19471  SetWindowLong(hdlg, DWL_USER, lparam);
19472 #endif
19473  setupdlg = (SETUPDLG *) lparam;
19474  SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19475  SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19476  SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19477  SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19478  SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19479  SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19480  (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19481  SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19482  (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19483  SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19484  (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19485  SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19486  (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19487  SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19488  (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19489  CheckDlgButton(hdlg, IDC_STEPAPI,
19490  getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19491  BST_CHECKED : BST_UNCHECKED);
19492  CheckDlgButton(hdlg, IDC_NOTXN,
19493  getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19494  BST_CHECKED : BST_UNCHECKED);
19495  CheckDlgButton(hdlg, IDC_SHORTNAM,
19496  getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19497  BST_CHECKED : BST_UNCHECKED);
19498  CheckDlgButton(hdlg, IDC_LONGNAM,
19499  getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19500  BST_CHECKED : BST_UNCHECKED);
19501  CheckDlgButton(hdlg, IDC_NOCREAT,
19502  getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19503  BST_CHECKED : BST_UNCHECKED);
19504  CheckDlgButton(hdlg, IDC_NOWCHAR,
19505  getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19506  BST_CHECKED : BST_UNCHECKED);
19507  CheckDlgButton(hdlg, IDC_FKSUPPORT,
19508  getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19509  BST_CHECKED : BST_UNCHECKED);
19510  CheckDlgButton(hdlg, IDC_OEMCP,
19511  getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19512  BST_CHECKED : BST_UNCHECKED);
19513  CheckDlgButton(hdlg, IDC_BIGINT,
19514  getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19515  BST_CHECKED : BST_UNCHECKED);
19516  CheckDlgButton(hdlg, IDC_JDCONV,
19517  getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19518  BST_CHECKED : BST_UNCHECKED);
19519  SendDlgItemMessage(hdlg, IDC_SYNCP,
19520  CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19521  SendDlgItemMessage(hdlg, IDC_SYNCP,
19522  CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19523  SendDlgItemMessage(hdlg, IDC_SYNCP,
19524  CB_ADDSTRING, 0, (LPARAM) "OFF");
19525  SendDlgItemMessage(hdlg, IDC_SYNCP,
19526  CB_ADDSTRING, 0, (LPARAM) "FULL");
19527  SendDlgItemMessage(hdlg, IDC_SYNCP,
19528  CB_SELECTSTRING, (WORD) -1,
19529  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19530  if (setupdlg->defDSN) {
19531  EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19532  EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19533  }
19534  return TRUE;
19535  case WM_COMMAND:
19536  switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19537  case IDC_BROWSE:
19538  GetDBFile(hdlg);
19539  break;
19540  case IDOK:
19541 #ifdef _WIN64
19542  setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19543 #else
19544  setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19545 #endif
19546  GetDlgItemText(hdlg, IDC_DSNAME,
19547  setupdlg->attr[KEY_DSN].attr,
19548  sizeof (setupdlg->attr[KEY_DSN].attr));
19549  GetDlgItemText(hdlg, IDC_DBNAME,
19550  setupdlg->attr[KEY_DBNAME].attr,
19551  sizeof (setupdlg->attr[KEY_DBNAME].attr));
19552  GetDlgItemText(hdlg, IDC_TONAME,
19553  setupdlg->attr[KEY_BUSY].attr,
19554  sizeof (setupdlg->attr[KEY_BUSY].attr));
19555  GetDlgItemText(hdlg, IDC_LOADEXT,
19556  setupdlg->attr[KEY_LOADEXT].attr,
19557  sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19558  index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19559  CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19560  if (index != (WORD) CB_ERR) {
19561  SendDlgItemMessage(hdlg, IDC_SYNCP,
19562  CB_GETLBTEXT, index,
19563  (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19564  }
19565  strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19566  (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19567  "1" : "0");
19568  strcpy(setupdlg->attr[KEY_NOTXN].attr,
19569  (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19570  "1" : "0");
19571  strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19572  (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19573  "1" : "0");
19574  strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19575  (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19576  "1" : "0");
19577  strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19578  (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19579  "1" : "0");
19580  strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19581  (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19582  "1" : "0");
19583  strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19584  (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19585  "1" : "0");
19586  strcpy(setupdlg->attr[KEY_OEMCP].attr,
19587  (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19588  "1" : "0");
19589  strcpy(setupdlg->attr[KEY_BIGINT].attr,
19590  (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19591  "1" : "0");
19592  strcpy(setupdlg->attr[KEY_JDCONV].attr,
19593  (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19594  "1" : "0");
19595  /* FALL THROUGH */
19596  case IDCANCEL:
19597  EndDialog(hdlg, GET_WM_COMMAND_ID(wparam, lparam) == IDOK);
19598  return TRUE;
19599  }
19600  }
19601  return FALSE;
19602 }
19603 
19617 static SQLRETURN
19618 drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
19619  SQLCHAR *connIn, SQLSMALLINT connInLen,
19620  SQLCHAR *connOut, SQLSMALLINT connOutMax,
19621  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19622 {
19623  BOOL maybeprompt, prompt = FALSE, defaultdsn = FALSE;
19624  DBC *d;
19625  SETUPDLG *setupdlg;
19626  SQLRETURN ret;
19627  char *dsn = NULL, *driver = NULL, *dbname = NULL;
19628 
19629  if (dbc == SQL_NULL_HDBC) {
19630  return SQL_INVALID_HANDLE;
19631  }
19632  d = (DBC *) dbc;
19633  if (d->sqlite) {
19634  setstatd(d, -1, "connection already established", "08002");
19635  return SQL_ERROR;
19636  }
19637  setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
19638  if (setupdlg == NULL) {
19639  return SQL_ERROR;
19640  }
19641  memset(setupdlg, 0, sizeof (SETUPDLG));
19642  maybeprompt = drvcompl == SQL_DRIVER_COMPLETE ||
19643  drvcompl == SQL_DRIVER_COMPLETE_REQUIRED;
19644  if (connIn == NULL || !connInLen ||
19645  (connInLen == SQL_NTS && !connIn[0])) {
19646  prompt = TRUE;
19647  } else {
19648  ParseAttributes((LPCSTR) connIn, setupdlg);
19649  if (!setupdlg->attr[KEY_DSN].attr[0] &&
19650  drvcompl == SQL_DRIVER_COMPLETE_REQUIRED) {
19651  strcpy(setupdlg->attr[KEY_DSN].attr, "DEFAULT");
19652  defaultdsn = TRUE;
19653  }
19654  GetAttributes(setupdlg);
19655  if (drvcompl == SQL_DRIVER_PROMPT ||
19656  (maybeprompt &&
19657  !setupdlg->attr[KEY_DBNAME].attr[0])) {
19658  prompt = TRUE;
19659  }
19660  }
19661 retry:
19662  if (prompt) {
19663  short dlgret;
19664 
19665  setupdlg->defDSN = setupdlg->attr[KEY_DRIVER].attr[0] != '\0';
19666  dlgret = DialogBoxParam(hModule, MAKEINTRESOURCE(DRIVERCONNECT),
19667  hwnd, (DLGPROC) DriverConnectProc,
19668  (LPARAM) setupdlg);
19669 
19670  if (!dlgret || dlgret == -1) {
19671  xfree(setupdlg);
19672  return SQL_NO_DATA;
19673  }
19674  }
19675  dsn = setupdlg->attr[KEY_DSN].attr;
19676  driver = setupdlg->attr[KEY_DRIVER].attr;
19677  dbname = setupdlg->attr[KEY_DBNAME].attr;
19678  if (connOut || connOutLen) {
19679  char buf[SQL_MAX_MESSAGE_LENGTH * 4];
19680  int len, count;
19681  char dsn_0 = (dsn && !defaultdsn) ? dsn[0] : '\0';
19682  char drv_0 = driver ? driver[0] : '\0';
19683 
19684  buf[0] = '\0';
19685  count = snprintf(buf, sizeof (buf),
19686  "%s%s%s%s%s%sDatabase=%s;StepAPI=%s;"
19687  "SyncPragma=%s;NoTXN=%s;Timeout=%s;"
19688  "ShortNames=%s;LongNames=%s;"
19689  "NoCreat=%s;NoWCHAR=%s;"
19690  "FKSupport=%s;JournalMode=%s;OEMCP=%s;LoadExt=%s;"
19691  "BigInt=%s;JDConv=%s;PWD=%s",
19692  dsn_0 ? "DSN=" : "",
19693  dsn_0 ? dsn : "",
19694  dsn_0 ? ";" : "",
19695  drv_0 ? "Driver=" : "",
19696  drv_0 ? driver : "",
19697  drv_0 ? ";" : "",
19698  dbname ? dbname : "",
19699  setupdlg->attr[KEY_STEPAPI].attr,
19700  setupdlg->attr[KEY_SYNCP].attr,
19701  setupdlg->attr[KEY_NOTXN].attr,
19702  setupdlg->attr[KEY_BUSY].attr,
19703  setupdlg->attr[KEY_SHORTNAM].attr,
19704  setupdlg->attr[KEY_LONGNAM].attr,
19705  setupdlg->attr[KEY_NOCREAT].attr,
19706  setupdlg->attr[KEY_NOWCHAR].attr,
19707  setupdlg->attr[KEY_FKSUPPORT].attr,
19708  setupdlg->attr[KEY_JMODE].attr,
19709  setupdlg->attr[KEY_OEMCP].attr,
19710  setupdlg->attr[KEY_LOADEXT].attr,
19711  setupdlg->attr[KEY_BIGINT].attr,
19712  setupdlg->attr[KEY_JDCONV].attr,
19713  setupdlg->attr[KEY_PASSWD].attr);
19714  if (count < 0) {
19715  buf[sizeof (buf) - 1] = '\0';
19716  }
19717  len = min(connOutMax - 1, strlen(buf));
19718  if (connOut) {
19719  strncpy((char *) connOut, buf, len);
19720  connOut[len] = '\0';
19721  }
19722  if (connOutLen) {
19723  *connOutLen = len;
19724  }
19725  }
19726  if (dsn[0]) {
19727  char tracef[SQL_MAX_MESSAGE_LENGTH];
19728 
19729  tracef[0] = '\0';
19730  SQLGetPrivateProfileString(setupdlg->attr[KEY_DSN].attr,
19731  "tracefile", "", tracef,
19732  sizeof (tracef), ODBC_INI);
19733  if (tracef[0] != '\0') {
19734  d->trace = fopen(tracef, "a");
19735  }
19736  }
19737  d->nowchar = getbool(setupdlg->attr[KEY_NOWCHAR].attr);
19738  d->shortnames = getbool(setupdlg->attr[KEY_SHORTNAM].attr);
19739  d->longnames = getbool(setupdlg->attr[KEY_LONGNAM].attr);
19740  d->nocreat = getbool(setupdlg->attr[KEY_NOCREAT].attr);
19741  d->fksupport = getbool(setupdlg->attr[KEY_FKSUPPORT].attr);
19742  d->oemcp = getbool(setupdlg->attr[KEY_OEMCP].attr);
19743  d->dobigint = getbool(setupdlg->attr[KEY_BIGINT].attr);
19744  d->jdconv = getbool(setupdlg->attr[KEY_JDCONV].attr);
19745  d->pwdLen = strlen(setupdlg->attr[KEY_PASSWD].attr);
19746  d->pwd = (d->pwdLen > 0) ? setupdlg->attr[KEY_PASSWD].attr : NULL;
19747  ret = dbopen(d, dbname ? dbname : "", 0,
19748  dsn ? dsn : "",
19749  setupdlg->attr[KEY_STEPAPI].attr,
19750  setupdlg->attr[KEY_SYNCP].attr,
19751  setupdlg->attr[KEY_NOTXN].attr,
19752  setupdlg->attr[KEY_JMODE].attr,
19753  setupdlg->attr[KEY_BUSY].attr);
19754  if (ret != SQL_SUCCESS) {
19755  if (maybeprompt && !prompt) {
19756  prompt = TRUE;
19757  goto retry;
19758  }
19759  }
19760  memset(setupdlg->attr[KEY_PASSWD].attr, 0,
19761  sizeof (setupdlg->attr[KEY_PASSWD].attr));
19762  if (ret == SQL_SUCCESS) {
19763  dbloadext(d, setupdlg->attr[KEY_LOADEXT].attr);
19764  }
19765  xfree(setupdlg);
19766  return ret;
19767 }
19768 
19769 #endif /* WITHOUT_DRIVERMGR */
19770 #endif /* _WIN32 || _WIN64 */
19771 
19772 #ifndef WINTERFACE
19773 
19786 SQLRETURN SQL_API
19787 SQLDriverConnect(SQLHDBC dbc, SQLHWND hwnd,
19788  SQLCHAR *connIn, SQLSMALLINT connInLen,
19789  SQLCHAR *connOut, SQLSMALLINT connOutMax,
19790  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19791 {
19792  SQLRETURN ret;
19793 
19794  HDBC_LOCK(dbc);
19795  ret = drvdriverconnect(dbc, hwnd, connIn, connInLen,
19796  connOut, connOutMax, connOutLen, drvcompl);
19797  HDBC_UNLOCK(dbc);
19798  return ret;
19799 }
19800 #endif
19801 
19802 #ifdef WINTERFACE
19803 
19816 SQLRETURN SQL_API
19817 SQLDriverConnectW(SQLHDBC dbc, SQLHWND hwnd,
19818  SQLWCHAR *connIn, SQLSMALLINT connInLen,
19819  SQLWCHAR *connOut, SQLSMALLINT connOutMax,
19820  SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19821 {
19822  SQLRETURN ret;
19823  char *ci = NULL;
19824  SQLSMALLINT len = 0;
19825 
19826  HDBC_LOCK(dbc);
19827  if (connIn) {
19828 #if defined(_WIN32) || defined(_WIN64)
19829  if (connInLen == SQL_NTS) {
19830  connInLen = -1;
19831  }
19832  ci = uc_to_wmb(connIn, connInLen);
19833 #else
19834  ci = uc_to_utf(connIn, connInLen);
19835 #endif
19836  if (!ci) {
19837  DBC *d = (DBC *) dbc;
19838 
19839  setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
19840  HDBC_UNLOCK(dbc);
19841  return SQL_ERROR;
19842  }
19843  }
19844  ret = drvdriverconnect(dbc, hwnd, (SQLCHAR *) ci, SQL_NTS,
19845  (SQLCHAR *) connOut, connOutMax, &len, drvcompl);
19846  HDBC_UNLOCK(dbc);
19847  uc_free(ci);
19848  if (ret == SQL_SUCCESS) {
19849  SQLWCHAR *co = NULL;
19850 
19851  if (connOut) {
19852  if (len > 0) {
19853 #if defined(_WIN32) || defined(_WIN64)
19854  co = wmb_to_uc((char *) connOut, len);
19855 #else
19856  co = uc_from_utf((SQLCHAR *) connOut, len);
19857 #endif
19858  if (co) {
19859  uc_strncpy(connOut, co, connOutMax / sizeof (SQLWCHAR));
19860  len = min(connOutMax / sizeof (SQLWCHAR), uc_strlen(co));
19861  uc_free(co);
19862  } else {
19863  len = 0;
19864  }
19865  }
19866  if (len <= 0) {
19867  len = 0;
19868  connOut[0] = 0;
19869  }
19870  } else {
19871  len = 0;
19872  }
19873  if (connOutLen) {
19874  *connOutLen = len;
19875  }
19876  }
19877  return ret;
19878 }
19879 #endif
19880 
19881 #if defined(_WIN32) || defined(_WIN64)
19882 
19891 BOOL APIENTRY
19892 LibMain(HANDLE hinst, DWORD reason, LPVOID reserved)
19893 {
19894  static int initialized = 0;
19895 
19896  switch (reason) {
19897  case DLL_PROCESS_ATTACH:
19898  if (!initialized++) {
19899  hModule = hinst;
19900 #ifdef WINTERFACE
19901  /* MS Access hack part 1 (reserved error -7748) */
19902  statSpec2P = statSpec2;
19903  statSpec3P = statSpec3;
19904 #endif
19905 #ifdef SQLITE_DYNLOAD
19906  dls_init();
19907 #endif
19908 #ifdef SQLITE_HAS_CODEC
19909  sqlite3_activate_see(SQLITE_ACTIVATION_KEY);
19910 #endif
19911  }
19912 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
19913  nvfs_init();
19914 #endif
19915  break;
19916  case DLL_THREAD_ATTACH:
19917  break;
19918  case DLL_PROCESS_DETACH:
19919  if (--initialized <= 0) {
19920 #ifdef SQLITE_DYNLOAD
19921  dls_fini();
19922 #endif
19923  }
19924  break;
19925  case DLL_THREAD_DETACH:
19926  break;
19927  default:
19928  break;
19929  }
19930  return TRUE;
19931 }
19932 
19941 int __stdcall
19942 DllMain(HANDLE hinst, DWORD reason, LPVOID reserved)
19943 {
19944  return LibMain(hinst, reason, reserved);
19945 }
19946 
19947 #ifndef WITHOUT_INSTALLER
19948 
19955 static BOOL
19956 InUnError(char *name)
19957 {
19958  WORD err = 1;
19959  DWORD code;
19960  char errmsg[301];
19961  WORD errlen, errmax = sizeof (errmsg) - 1;
19962  int sqlret;
19963  BOOL ret = FALSE;
19964 
19965  do {
19966  errmsg[0] = '\0';
19967  sqlret = SQLInstallerError(err, &code, errmsg, errmax, &errlen);
19968  if (SQL_SUCCEEDED(sqlret)) {
19969  MessageBox(NULL, errmsg, name,
19970  MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
19971  ret = TRUE;
19972  }
19973  err++;
19974  } while (sqlret != SQL_NO_DATA);
19975  return ret;
19976 }
19977 
19984 static BOOL
19985 InUn(int remove, char *cmdline)
19986 {
19987 #ifdef SQLITE_HAS_CODEC
19988  static char *drivername = "SQLite3 ODBC Driver (SEE)";
19989  static char *dsname = "SQLite3 SEE Datasource";
19990 #else
19991  static char *drivername = "SQLite3 ODBC Driver";
19992  static char *dsname = "SQLite3 Datasource";
19993 #endif
19994  char *dllname, *p;
19995  char dllbuf[301], path[301], driver[300], attr[300], inst[400];
19996  WORD pathmax = sizeof (path) - 1, pathlen;
19997  DWORD usecnt, mincnt;
19998  int quiet = 0;
19999 
20000  dllbuf[0] = '\0';
20001  GetModuleFileName(hModule, dllbuf, sizeof (dllbuf));
20002  p = strrchr(dllbuf, '\\');
20003  dllname = p ? (p + 1) : dllbuf;
20004  quiet = cmdline && strstr(cmdline, "quiet");
20005  if (SQLInstallDriverManager(path, pathmax, &pathlen)) {
20006  sprintf(driver, "%s;Driver=%s;Setup=%s;",
20007  drivername, dllname, dllname);
20008  p = driver;
20009  while (*p) {
20010  if (*p == ';') {
20011  *p = '\0';
20012  }
20013  ++p;
20014  }
20015  usecnt = 0;
20016  path[0] = '\0';
20017  SQLInstallDriverEx(driver, NULL, path, pathmax, NULL,
20018  ODBC_INSTALL_INQUIRY, &usecnt);
20019  pathlen = strlen(path);
20020  while (pathlen > 0 && path[pathlen - 1] == '\\') {
20021  --pathlen;
20022  path[pathlen] = '\0';
20023  }
20024  sprintf(driver, "%s;Driver=%s\\%s;Setup=%s\\%s;",
20025  drivername, path, dllname, path, dllname);
20026  p = driver;
20027  while (*p) {
20028  if (*p == ';') {
20029  *p = '\0';
20030  }
20031  ++p;
20032  }
20033  sprintf(inst, "%s\\%s", path, dllname);
20034  if (!remove && usecnt > 0) {
20035  /* first install try: copy over driver dll, keeping DSNs */
20036  if (GetFileAttributesA(dllbuf) != INVALID_FILE_ATTRIBUTES &&
20037  CopyFile(dllbuf, inst, 0)) {
20038  if (!quiet) {
20039  char buf[512];
20040 
20041  sprintf(buf, "%s replaced.", drivername);
20042  MessageBox(NULL, buf, "Info",
20043  MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20044  MB_SETFOREGROUND);
20045  }
20046  return TRUE;
20047  }
20048  }
20049  mincnt = remove ? 1 : 0;
20050  while (usecnt != mincnt) {
20051  if (!SQLRemoveDriver(driver, TRUE, &usecnt)) {
20052  break;
20053  }
20054  }
20055  if (remove) {
20056  if (usecnt && !SQLRemoveDriver(driver, TRUE, &usecnt)) {
20057  InUnError("SQLRemoveDriver");
20058  return FALSE;
20059  }
20060  if (!usecnt) {
20061  char buf[512];
20062 
20063  DeleteFile(inst);
20064  if (!quiet) {
20065  sprintf(buf, "%s uninstalled.", drivername);
20066  MessageBox(NULL, buf, "Info",
20067  MB_ICONINFORMATION |MB_OK | MB_TASKMODAL |
20068  MB_SETFOREGROUND);
20069  }
20070  }
20071  sprintf(attr, "DSN=%s;Database=;", dsname);
20072  p = attr;
20073  while (*p) {
20074  if (*p == ';') {
20075  *p = '\0';
20076  }
20077  ++p;
20078  }
20079  SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20080  return TRUE;
20081  }
20082  if (GetFileAttributesA(dllbuf) == INVALID_FILE_ATTRIBUTES) {
20083  return FALSE;
20084  }
20085  if (strcasecmp(dllbuf, inst) != 0 && !CopyFile(dllbuf, inst, 0)) {
20086  char buf[512];
20087 
20088  sprintf(buf, "Copy %s to %s failed.", dllbuf, inst);
20089  MessageBox(NULL, buf, "CopyFile",
20090  MB_ICONSTOP |MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
20091  return FALSE;
20092  }
20093  if (!SQLInstallDriverEx(driver, path, path, pathmax, &pathlen,
20094  ODBC_INSTALL_COMPLETE, &usecnt)) {
20095  InUnError("SQLInstallDriverEx");
20096  return FALSE;
20097  }
20098  sprintf(attr, "DSN=%s;Database=;", dsname);
20099  p = attr;
20100  while (*p) {
20101  if (*p == ';') {
20102  *p = '\0';
20103  }
20104  ++p;
20105  }
20106  SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20107  if (!SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN, drivername, attr)) {
20108  InUnError("SQLConfigDataSource");
20109  return FALSE;
20110  }
20111  if (!quiet) {
20112  char buf[512];
20113 
20114  sprintf(buf, "%s installed.", drivername);
20115  MessageBox(NULL, buf, "Info",
20116  MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20117  MB_SETFOREGROUND);
20118  }
20119  } else {
20120  InUnError("SQLInstallDriverManager");
20121  return FALSE;
20122  }
20123  return TRUE;
20124 }
20125 
20134 void CALLBACK
20135 install(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20136 {
20137  InUn(0, lpszCmdLine);
20138 }
20139 
20148 void CALLBACK
20149 uninstall(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20150 {
20151  InUn(1, lpszCmdLine);
20152 }
20153 
20154 #endif /* WITHOUT_INSTALLER */
20155 
20156 #ifndef WITHOUT_SHELL
20157 
20166 static void
20167 setargv(int *argcp, char ***argvp, char *cmdline, char *argv0)
20168 {
20169  char *p, *arg, *argspace, **argv;
20170  int argc, size, inquote, copy, slashes;
20171 
20172  size = 2 + (argv0 ? 1 : 0);
20173  for (p = cmdline; *p != '\0'; p++) {
20174  if (ISSPACE(*p)) {
20175  size++;
20176  while (ISSPACE(*p)) {
20177  p++;
20178  }
20179  if (*p == '\0') {
20180  break;
20181  }
20182  }
20183  }
20184  argspace = malloc(size * sizeof (char *) + strlen(cmdline) + 1);
20185  argv = (char **) argspace;
20186  argspace += size * sizeof (char *);
20187  size--;
20188  argc = 0;
20189  if (argv0) {
20190  argv[argc++] = argv0;
20191  }
20192  p = cmdline;
20193  for (; argc < size; argc++) {
20194  argv[argc] = arg = argspace;
20195  while (ISSPACE(*p)) {
20196  p++;
20197  }
20198  if (*p == '\0') {
20199  break;
20200  }
20201  inquote = 0;
20202  slashes = 0;
20203  while (1) {
20204  copy = 1;
20205  while (*p == '\\') {
20206  slashes++;
20207  p++;
20208  }
20209  if (*p == '"') {
20210  if ((slashes & 1) == 0) {
20211  copy = 0;
20212  if (inquote && p[1] == '"') {
20213  p++;
20214  copy = 1;
20215  } else {
20216  inquote = !inquote;
20217  }
20218  }
20219  slashes >>= 1;
20220  }
20221  while (slashes) {
20222  *arg = '\\';
20223  arg++;
20224  slashes--;
20225  }
20226  if (*p == '\0' || (!inquote && ISSPACE(*p))) {
20227  break;
20228  }
20229  if (copy != 0) {
20230  *arg = *p;
20231  arg++;
20232  }
20233  p++;
20234  }
20235  *arg = '\0';
20236  argspace = arg + 1;
20237  }
20238  argv[argc] = 0;
20239  *argcp = argc;
20240  *argvp = argv;
20241 }
20242 
20251 void CALLBACK
20252 shell(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20253 {
20254  int argc, needcon = 0;
20255  char **argv;
20256  extern int sqlite3_main(int, char **);
20257  static const char *name = "SQLite3 Shell";
20258  DWORD ftype0, ftype1, ftype2;
20259 
20260  ftype0 = GetFileType(GetStdHandle(STD_INPUT_HANDLE));
20261  ftype1 = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
20262  ftype2 = GetFileType(GetStdHandle(STD_ERROR_HANDLE));
20263  if (ftype0 != FILE_TYPE_DISK && ftype0 != FILE_TYPE_CHAR &&
20264  ftype0 != FILE_TYPE_PIPE) {
20265  fclose(stdin);
20266  ++needcon;
20267  ftype0 = FILE_TYPE_UNKNOWN;
20268  }
20269  if (ftype1 != FILE_TYPE_DISK && ftype1 != FILE_TYPE_CHAR &&
20270  ftype1 != FILE_TYPE_PIPE) {
20271  fclose(stdout);
20272  ++needcon;
20273  ftype1 = FILE_TYPE_UNKNOWN;
20274  }
20275  if (ftype2 != FILE_TYPE_DISK && ftype2 != FILE_TYPE_CHAR &&
20276  ftype2 != FILE_TYPE_PIPE) {
20277  fclose(stderr);
20278  ++needcon;
20279  ftype2 = FILE_TYPE_UNKNOWN;
20280  }
20281  if (needcon > 0) {
20282  AllocConsole();
20283  SetConsoleTitle(name);
20284  }
20285  if (ftype0 == FILE_TYPE_UNKNOWN) {
20286  freopen("CONIN$", "r", stdin);
20287  }
20288  if (ftype1 == FILE_TYPE_UNKNOWN) {
20289  freopen("CONOUT$", "w", stdout);
20290  }
20291  if (ftype2 == FILE_TYPE_UNKNOWN) {
20292  freopen("CONOUT$", "w", stderr);
20293  }
20294  setargv(&argc, &argv, lpszCmdLine, (char *) name);
20295 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
20296  nvfs_init();
20297 #endif
20298  sqlite3_main(argc, argv);
20299 }
20300 
20301 #endif /* WITHOUT_SHELL */
20302 
20303 #endif /* _WIN32 || _WIN64 */
20304 
20305 #if defined(HAVE_ODBCINSTEXT_H) && (HAVE_ODBCINSTEXT_H)
20306 
20307 /*
20308  * unixODBC property page for this driver,
20309  * may or may not work depending on unixODBC version.
20310  */
20311 
20312 #include <odbcinstext.h>
20313 
20314 int
20315 ODBCINSTGetProperties(HODBCINSTPROPERTY prop)
20316 {
20317  static const char *instYN[] = { "No", "Yes", NULL };
20318  static const char *syncPragma[] = { "NORMAL", "OFF", "FULL", NULL };
20319  static const char *jmPragma[] = {
20320  "DELETE", "PERSIST", "OFF", "TRUNCATE", "MEMORY", "WAL", NULL
20321  };
20322 
20323  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20324  prop = prop->pNext;
20325  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20326  prop->nPromptType = ODBCINST_PROMPTTYPE_FILENAME;
20327  strncpy(prop->szName, "Database", INI_MAX_PROPERTY_NAME);
20328  strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20329  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20330  prop = prop->pNext;
20331  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20332  prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20333  strncpy(prop->szName, "Timeout", INI_MAX_PROPERTY_NAME);
20334  strncpy(prop->szValue, "100000", INI_MAX_PROPERTY_VALUE);
20335  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20336  prop = prop->pNext;
20337  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20338  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20339  prop->aPromptData = malloc(sizeof (instYN));
20340  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20341  strncpy(prop->szName, "StepAPI", INI_MAX_PROPERTY_NAME);
20342  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20343  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20344  prop = prop->pNext;
20345  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20346  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20347  prop->aPromptData = malloc(sizeof (instYN));
20348  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20349  strncpy(prop->szName, "ShortNames", INI_MAX_PROPERTY_NAME);
20350  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20351  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20352  prop = prop->pNext;
20353  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20354  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20355  prop->aPromptData = malloc(sizeof (instYN));
20356  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20357  strncpy(prop->szName, "LongNames", INI_MAX_PROPERTY_NAME);
20358  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20359  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20360  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20361  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20362  prop->aPromptData = malloc(sizeof (instYN));
20363  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20364  strncpy(prop->szName, "NoCreat", INI_MAX_PROPERTY_NAME);
20365  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20366 #ifdef WINTERFACE
20367  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20368  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20369  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20370  prop->aPromptData = malloc(sizeof (instYN));
20371  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20372  strncpy(prop->szName, "NoWCHAR", INI_MAX_PROPERTY_NAME);
20373  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20374 #endif
20375  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20376  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20377  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20378  prop->aPromptData = malloc(sizeof (instYN));
20379  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20380  strncpy(prop->szName, "FKSupport", INI_MAX_PROPERTY_NAME);
20381  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20382  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20383  prop = prop->pNext;
20384  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20385  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20386  prop->aPromptData = malloc(sizeof (syncPragma));
20387  memcpy(prop->aPromptData, syncPragma, sizeof (syncPragma));
20388  strncpy(prop->szName, "SyncPragma", INI_MAX_PROPERTY_NAME);
20389  strncpy(prop->szValue, "NORMAL", INI_MAX_PROPERTY_VALUE);
20390  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20391  prop = prop->pNext;
20392  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20393  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20394  prop->aPromptData = malloc(sizeof (jmPragma));
20395  memcpy(prop->aPromptData, jmPragma, sizeof (jmPragma));
20396  strncpy(prop->szName, "JournalMode", INI_MAX_PROPERTY_NAME);
20397  strncpy(prop->szValue, "DELETE", INI_MAX_PROPERTY_VALUE);
20398  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20399  prop = prop->pNext;
20400  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20401  prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20402  strncpy(prop->szName, "LoadExt", INI_MAX_PROPERTY_NAME);
20403  strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20404  prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20405  memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20406  prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20407  prop->aPromptData = malloc(sizeof (instYN));
20408  memcpy(prop->aPromptData, instYN, sizeof (instYN));
20409  strncpy(prop->szName, "BigInt", INI_MAX_PROPERTY_NAME);
20410  strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20411  return 1;
20412 }
20413 
20414 #endif /* HAVE_ODBCINSTEXT_H */
20415 
20416 #ifdef SQLITE_DYNLOAD
20417 
20418 /*
20419  * SQLite3 shared library/DLL stubs.
20420  */
20421 
20422 static void
20423 dls_void(void)
20424 {
20425 }
20426 
20427 static int
20428 dls_error(void)
20429 {
20430  return SQLITE_ERROR;
20431 }
20432 
20433 static int
20434 dls_0(void)
20435 {
20436  return 0;
20437 }
20438 
20439 static sqlite_int64
20440 dls_0LL(void)
20441 {
20442  return 0;
20443 }
20444 
20445 static double
20446 dls_00(void)
20447 {
20448  return 0;
20449 }
20450 
20451 static void *
20452 dls_null(void)
20453 {
20454  return NULL;
20455 }
20456 
20457 static const char *
20458 dls_empty(void)
20459 {
20460  return "";
20461 }
20462 
20463 static int
20464 dls_snull(void)
20465 {
20466  return SQLITE_NULL;
20467 }
20468 
20469 #define DLS_ENT(name, func) \
20470  { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, name), \
20471  (void *) func }
20472 
20473 #define DLS_ENT3(name, off, func) \
20474  { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, off), \
20475  (void *) func }
20476 
20477 #define DLS_END { NULL, 0, NULL }
20478 
20479 static struct {
20480  const char *name;
20481  int offset;
20482  void *func;
20483 } dls_nametab[] = {
20484  DLS_ENT(activate_see, dls_void),
20485  DLS_ENT(bind_blob, dls_error),
20486  DLS_ENT(bind_double, dls_error),
20487  DLS_ENT(bind_int, dls_error),
20488  DLS_ENT(bind_int64, dls_error),
20489  DLS_ENT(bind_null, dls_error),
20490  DLS_ENT(bind_parameter_count, dls_0),
20491  DLS_ENT(bind_text, dls_error),
20492  DLS_ENT(busy_handler, dls_error),
20493  DLS_ENT(changes, dls_0),
20494  DLS_ENT(close, dls_error),
20495  DLS_ENT(column_blob, dls_null),
20496  DLS_ENT(column_bytes, dls_0),
20497  DLS_ENT(column_count, dls_0),
20498  DLS_ENT(column_database_name, dls_empty),
20499  DLS_ENT(column_decltype, dls_empty),
20500  DLS_ENT(column_double, dls_00),
20501  DLS_ENT(column_name, dls_empty),
20502  DLS_ENT(column_origin_name, dls_null),
20503  DLS_ENT(column_table_name, dls_null),
20504  DLS_ENT(column_text, dls_null),
20505  DLS_ENT(column_type, dls_snull),
20506  DLS_ENT(create_function, dls_error),
20507  DLS_ENT(enable_load_extension, dls_error),
20508  DLS_ENT(errcode, dls_error),
20509  DLS_ENT(errmsg, dls_empty),
20510  DLS_ENT(exec, dls_error),
20511  DLS_ENT(finalize, dls_error),
20512  DLS_ENT(free, free),
20513  DLS_ENT(free_table, dls_void),
20514  DLS_ENT(get_table, dls_error),
20515  DLS_ENT(interrupt, dls_void),
20516  DLS_ENT(key, dls_error),
20517  DLS_ENT(last_insert_rowid, dls_0LL),
20518  DLS_ENT(libversion, dls_empty),
20519  DLS_ENT(load_extension, dls_error),
20520  DLS_ENT(malloc, malloc),
20521  DLS_ENT(mprintf, dls_null),
20522  DLS_ENT(open, dls_error),
20523  DLS_ENT(open16, dls_error),
20524  DLS_ENT(open_v2, dls_error),
20525  DLS_ENT(prepare, dls_error),
20526  DLS_ENT(prepare_v2, dls_error),
20527  DLS_ENT(profile, dls_null),
20528  DLS_ENT(realloc, realloc),
20529  DLS_ENT(rekey, dls_error),
20530  DLS_ENT(reset, dls_error),
20531  DLS_ENT(result_blob, dls_void),
20532  DLS_ENT(result_error, dls_void),
20533  DLS_ENT(result_int, dls_void),
20534  DLS_ENT(result_null, dls_void),
20535  DLS_ENT(step, dls_error),
20536 #if defined(_WIN32) || defined(_WIN64)
20537  DLS_ENT3(strnicmp, xstrnicmp, _strnicmp),
20538 #else
20539  DLS_ENT3(strnicmp, xstrnicmp, strncasecmp),
20540 #endif
20541  DLS_ENT(table_column_metadata, dls_error),
20542  DLS_ENT(trace, dls_null),
20543  DLS_ENT(user_data, dls_null),
20544  DLS_ENT(value_blob, dls_null),
20545  DLS_ENT(value_bytes, dls_0),
20546  DLS_ENT(value_text, dls_empty),
20547  DLS_ENT(value_type, dls_snull),
20548  DLS_END
20549 };
20550 
20551 #if defined(_WIN32) || defined(_WIN64)
20552 
20553 static HMODULE sqlite3_dll = 0;
20554 
20555 static void
20556 dls_init(void)
20557 {
20558  int i;
20559  static const char *dll_names[] = {
20560  "System.Data.SQLite.dll",
20561  "sqlite3.dll",
20562  NULL,
20563  };
20564 
20565  i = 0;
20566  while (dll_names[i]) {
20567  sqlite3_dll = LoadLibrary(dll_names[i]);
20568  if (sqlite3_dll) {
20569  break;
20570  }
20571  ++i;
20572  }
20573  i = 0;
20574  while (dls_nametab[i].name) {
20575  void *func = 0, **loc;
20576 
20577  if (sqlite3_dll) {
20578  func = (void *) GetProcAddress(sqlite3_dll, dls_nametab[i].name);
20579  }
20580  if (!func) {
20581  func = dls_nametab[i].func;
20582  }
20583  loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
20584  *loc = func;
20585  ++i;
20586  }
20587  if (!sqlite3_dll) {
20588  char buf[MAXPATHLEN], msg[MAXPATHLEN];
20589 
20590  LoadString(hModule, IDS_DRVTITLE, buf, sizeof (buf));
20591  LoadString(hModule, IDS_DLLERR, msg, sizeof (msg));
20592  MessageBox(NULL, msg, buf,
20593  MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
20594  MB_SETFOREGROUND);
20595  }
20596 }
20597 
20598 static void
20599 dls_fini(void)
20600 {
20601  if (sqlite3_dll) {
20602  FreeLibrary(sqlite3_dll);
20603  sqlite3_dll = 0;
20604  }
20605 }
20606 
20607 #else
20608 
20609 #include <dlfcn.h>
20610 
20611 static void *libsqlite3_so = 0;
20612 
20613 void
20614 dls_init(void)
20615 {
20616  int i;
20617 
20618  libsqlite3_so = dlopen("libsqlite3.so.0", RTLD_NOW | RTLD_GLOBAL);
20619  i = 0;
20620  while (dls_nametab[i].name) {
20621  void *func = 0, **loc;
20622 
20623  if (libsqlite3_so) {
20624  func = dlsym(libsqlite3_so, dls_nametab[i].name);
20625  }
20626  if (!func) {
20627  func = dls_nametab[i].func;
20628  }
20629  loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
20630  *loc = func;
20631  ++i;
20632  }
20633  if (!libsqlite3_so) {
20634  const char errmsg[] = "SQLite3 shared library not found.\n";
20635 
20636  write(2, errmsg, sizeof (errmsg) - 1);
20637  }
20638 }
20639 
20640 void
20641 dls_fini(void)
20642 {
20643  if (libsqlite3_so) {
20644  dlclose(libsqlite3_so);
20645  libsqlite3_so = 0;
20646  }
20647 }
20648 
20649 #endif
20650 
20651 #endif
20652 
20653 /*
20654  * Local Variables:
20655  * mode: c
20656  * c-basic-offset: 4
20657  * fill-column: 78
20658  * tab-width: 8
20659  * End:
20660  */
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:5609
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:5886
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:9630
static SQLRETURN nomem(STMT *s)
Report S1000 (out of memory) SQL error given STMT.
Definition: sqlite3odbc.c:1845
static const char lower_chars[]
Definition: sqlite3odbc.c:547
static int findcol(char **cols, int ncols, char *name)
Find column given name in string array.
Definition: sqlite3odbc.c:2777
int longnames
Don&#39;t shorten column names.
Definition: sqlite3odbc.h:133
int nocreat
Don&#39;t auto create database file.
Definition: sqlite3odbc.h:134
#define SQLLEN
Definition: sqlite3odbc.h:62
#define SQLULEN
Definition: sqlite3odbc.h:68
static void freerows(char **rowp)
Free counted array of char pointers.
Definition: sqlite3odbc.c:2185
SQLRETURN SQL_API SQLDisconnect(SQLHDBC dbc)
Disconnect given HDBC.
static void setstatd(DBC *d, int naterr, char *msg, char *st,...)
Set error message and SQL state on DBC.
Definition: sqlite3odbc.c:1720
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:5024
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:7818
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:5643
static SQLRETURN drvfreeconnect(SQLHDBC dbc)
Internal free connection (HDBC).
SQLCHAR logmsg[1024]
Message for SQLError()
Definition: sqlite3odbc.h:259
static dstr * dsappend(dstr *dsp, const char *str)
Append string to dynamic string.
Definition: sqlite3odbc.c:638
static SQLRETURN drvgetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen, SQLSMALLINT *lenp)
Internal function to get cursor name of STMT.
char ** rows
2-dim array, result set
Definition: sqlite3odbc.h:255
int step_enable
True for sqlite_compile/step/finalize.
Definition: sqlite3odbc.h:137
#define drvgetgpps(d)
Definition: sqlite3odbc.c:1322
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:1423
static void blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function to import a BLOB from a file.
Definition: sqlite3odbc.c:3703
SQLRETURN SQL_API SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLLEN offset)
Fetch result row with scrolling.
#define xmalloc(x)
Definition: sqlite3odbc.c:403
static void s3bind(DBC *d, sqlite3_stmt *stmt, int nparams, BINDPARM *p)
Definition: sqlite3odbc.c:1331
int ispk
Flag for primary key (> 0)
Definition: sqlite3odbc.h:175
static SQLRETURN dofetchbind(STMT *s, int rsi)
Internal: fetch and bind from statement&#39;s current row.
PTRDIFF_T ndata
index into result array
Definition: sqlite3odbc.c:1413
SQLRETURN SQL_API SQLSetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
Set option on HDBC (UNICODE version).
#define SQLROWSETSIZE
Definition: sqlite3odbc.h:84
int intrans
True when transaction started.
Definition: sqlite3odbc.h:125
int shortnames
Always use short column names.
Definition: sqlite3odbc.h:132
static SQLRETURN drvgetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
Internal get connect option of HDBC.
static SQLRETURN drvallocconnect(SQLHENV env, SQLHDBC *dbc)
Internal allocate HDBC.
SQLULEN * parm_bind_offs
SQL_ATTR_PARAM_BIND_OFFSET_PTR.
Definition: sqlite3odbc.h:277
void * s3val
SQLite3 value buffer.
Definition: sqlite3odbc.h:218
static int str2time(int jdconv, char *str, TIME_STRUCT *ts)
Convert string to ODBC TIME_STRUCT.
Definition: sqlite3odbc.c:3234
Internal structure for bound column (SQLBindCol).
Definition: sqlite3odbc.h:187
static COL pkeySpec2[]
Columns for result set of SQLPrimaryKeys().
Definition: sqlite3odbc.c:6413
SQLRETURN SQL_API SQLGetInfoW(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen)
Return information about what this ODBC driver supports.
#define ENV_MAGIC
Definition: sqlite3odbc.c:262
static COL fkeySpec2[]
Columns for result set of SQLForeignKeys().
Definition: sqlite3odbc.c:7257
static void freedyncols(STMT *s)
Free dynamically allocated column descriptions of STMT.
int nrows
Number of result rows.
Definition: sqlite3odbc.h:252
static int mapsqltype(const char *typename, int *nosign, int ov3, int nowchar, int dobigint)
Map SQL field type from string to ODBC integer type code.
Definition: sqlite3odbc.c:2211
SQLRETURN SQL_API SQLCancel(SQLHSTMT stmt)
Cancel HSTMT closing cursor.
static int quiet
Definition: inst.c:60
static void getmd(const char *typename, int sqltype, int *mp, int *dp)
Get maximum display size and number of digits after decimal point from field type specification...
Definition: sqlite3odbc.c:2335
SQLRETURN SQL_API SQLAllocEnv(SQLHENV *env)
Allocate HENV.
#define ISDIGIT(c)
Definition: sqlite3odbc.c:568
Driver internal structure for database connection (HDBC).
Definition: sqlite3odbc.h:111
SQLRETURN SQL_API SQLFreeConnect(SQLHDBC dbc)
Free connection (HDBC).
SQLRETURN SQL_API SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT orient, SQLROWOFFSET offset, SQLROWSETSIZE *rowcount, SQLUSMALLINT *rowstatus)
Fetch result row with scrolling and row status.
SQLULEN row_count0
Row count.
Definition: sqlite3odbc.h:269
int s3ival
SQLite3 integer value.
Definition: sqlite3odbc.h:219
struct stmt * cur_s3stmt
Current STMT executing sqlite statement.
Definition: sqlite3odbc.h:141
int need
True when SQL_LEN_DATA_AT_EXEC.
Definition: sqlite3odbc.h:211
static const char digit_chars[]
Definition: sqlite3odbc.c:566
static SQLRETURN drvgetdiagfield(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno, SQLSMALLINT id, SQLPOINTER info, SQLSMALLINT buflen, SQLSMALLINT *stringlen)
Get error record given handle (HDBC or HSTMT).
Definition: sqlite3odbc.c:8711
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:8144
static SQLRETURN drvallocenv(SQLHENV *env)
Internal allocate HENV.
static COL procSpec2[]
Columns for result set of SQLProcedures().
Definition: sqlite3odbc.c:8179
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:6444
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:4550
SQLRETURN SQL_API SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno, SQLSMALLINT fieldid, SQLPOINTER value, SQLINTEGER buflen)
Function not implemented.
Definition: sqlite3odbc.c:5839
#define SQL_API
Definition: sqlite3odbc.h:58
char * column
Column name.
Definition: sqlite3odbc.h:166
int version
SQLITE version number.
Definition: sqlite3odbc.h:116
char * dsn
ODBC data source name.
Definition: sqlite3odbc.h:118
HDBC dbc
Pointer to DBC.
Definition: sqlite3odbc.h:232
static const char space_chars[]
Definition: sqlite3odbc.c:575
SQLRETURN SQL_API SQLDescribeColW(SQLHSTMT stmt, SQLUSMALLINT col, SQLWCHAR *name, SQLSMALLINT nameMax, SQLSMALLINT *nameLen, SQLSMALLINT *type, SQLULEN *size, SQLSMALLINT *digits, SQLSMALLINT *nullable)
Describe column information (UNICODE version).
static SQLRETURN drvdisconnect(SQLHDBC dbc)
Internal disconnect given HDBC.
static SQLRETURN drvsetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
Internal set option on HDBC.
#define SQLROWOFFSET
Definition: sqlite3odbc.h:80
int curtype
Default cursor type.
Definition: sqlite3odbc.h:136
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:8383
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:9389
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:9461
int prec
Precision of column.
Definition: sqlite3odbc.h:172
#define xfree(x)
Definition: sqlite3odbc.c:405
int magic
Magic cookie.
Definition: sqlite3odbc.h:97
ENV * env
Pointer to environment.
Definition: sqlite3odbc.h:113
char buffer[1]
String buffer.
Definition: sqlite3odbc.c:276
SQLRETURN SQL_API SQLProcedureColumnsW(SQLHSTMT stmt, SQLWCHAR *catalog, SQLSMALLINT catalogLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *proc, SQLSMALLINT procLen, SQLWCHAR *column, SQLSMALLINT columnLen)
Retrieve information about columns in result set of stored procedures (UNICODE version).
Definition: sqlite3odbc.c:8356
static void dbtrace(void *arg, const char *msg, sqlite_uint64 et)
SQLite trace or profile callback.
Definition: sqlite3odbc.c:3838
static void mktypeinfo(STMT *s, int row, int asize, char *typename, int type, int tind)
Internal function to build up data type information as row in result set.
#define HSTMT_LOCK(hdbc)
Definition: sqlite3odbc.c:532
SQLRETURN SQL_API SQLGetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
Get connect option of HDBC (UNICODE version).
SQLRETURN SQL_API SQLTransact(SQLHENV env, SQLHDBC dbc, SQLUSMALLINT type)
Commit or rollback transaction.
Definition: sqlite3odbc.c:8069
static void blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function to export a BLOB to a file.
Definition: sqlite3odbc.c:3773
static SQLRETURN drvgetinfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen)
Internal return information about what this ODBC driver supports.
int nrow
number of rows in result array
Definition: sqlite3odbc.c:1411
static COL procColSpec3[]
Definition: sqlite3odbc.c:8285
static double ln_strtod(const char *data, char **endp)
Internal locale neutral strtod function.
Definition: sqlite3odbc.c:1874
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:4789
#define SET_EXISTS(x)
#define xstrdup(x)
Definition: sqlite3odbc.c:406
static int mapdeftype(int type, int stype, int nosign, int nowchar)
Map SQL_C_DEFAULT to proper C type.
Definition: sqlite3odbc.c:2420
static SQLRETURN SQL_API drvforeignkeys(SQLHSTMT stmt, SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen, SQLCHAR *PKschema, SQLSMALLINT PKschemaLen, SQLCHAR *PKtable, SQLSMALLINT PKtableLen, SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen, SQLCHAR *FKschema, SQLSMALLINT FKschemaLen, SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
Internal retrieve information about primary/foreign keys.
Definition: sqlite3odbc.c:7310
BINDPARM * bindparms
Array of bound parameters.
Definition: sqlite3odbc.h:249
#define SETSTMTOPTION_LAST_ARG_TYPE
Definition: sqlite3odbc.c:221
COL * cols
Result column array.
Definition: sqlite3odbc.h:240
#define DBC_MAGIC
Definition: sqlite3odbc.c:263
static SQLRETURN noconn(STMT *s)
Report S1000 (not connected) SQL error given STMT.
Definition: sqlite3odbc.c:1858
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:5008
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:5560
SQLRETURN SQL_API SQLCopyDesc(SQLHDESC source, SQLHDESC target)
Function not implemented.
Definition: sqlite3odbc.c:8082
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:5907
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:8910
static int namematch(char *str, char *pat, int esc)
SQL LIKE string match with optional backslash escape handling.
Definition: sqlite3odbc.c:1980
SQLUSMALLINT * parm_oper
SQL_ATTR_PARAM_OPERATION_PTR.
Definition: sqlite3odbc.h:278
static SQLWCHAR * uc_strncpy(SQLWCHAR *dest, SQLWCHAR *src, int len)
Copy UNICODE string like strncpy().
Definition: sqlite3odbc.c:818
static SQLWCHAR * uc_from_utf(unsigned char *str, int len)
Make UNICODE string from UTF8 string.
Definition: sqlite3odbc.c:950
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:8055
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:5697
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:1414
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:5949
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:5982
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:6276
SQLUSMALLINT row_status1
Internal status array for 1 row rowsets.
Definition: sqlite3odbc.h:267
SQLLEN * lenp
Value return, actual size of value buffer.
Definition: sqlite3odbc.h:190
SQLULEN retr_data
SQL_ATTR_RETRIEVE_DATA.
Definition: sqlite3odbc.h:263
int longnames
Don&#39;t shorten column names.
Definition: sqlite3odbc.h:262
int index
Index of column in result.
Definition: sqlite3odbc.h:192
static SQLRETURN chkunbound(STMT *s)
Check for unbound result columns.
Definition: sqlite3odbc.c:9599
static void freep(void *x)
Free memory given pointer to memory pointer.
Definition: sqlite3odbc.c:1830
static void fixupdyncols(STMT *s, DBC *d)
Fixup column information for a running statement.
Definition: sqlite3odbc.c:2808
static char * uc_to_utf(SQLWCHAR *str, int len)
Make UTF8 string from UNICODE string.
Definition: sqlite3odbc.c:976
int nosign
Unsigned type.
Definition: sqlite3odbc.h:170
static int getmdays(int year, int month)
Return number of month days.
Definition: sqlite3odbc.c:3085
static COL tablePrivSpec3[]
Definition: sqlite3odbc.c:5959
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:6772
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:7210
static int str2date(int jdconv, char *str, DATE_STRUCT *ds)
Convert string to ODBC DATE_STRUCT.
Definition: sqlite3odbc.c:3119
static COL procSpec3[]
Definition: sqlite3odbc.c:8190
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:9970
static COL colPrivSpec3[]
Definition: sqlite3odbc.c:6333
#define PTRDIFF_T
Definition: sqlite3odbc.c:230
static SQLRETURN drvtables(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen, SQLCHAR *type, SQLSMALLINT typeLen)
Retrieve information on tables and/or views.
static COL statSpec2[]
Columns for result set of SQLStatistics().
int nowchar
Don&#39;t try to use WCHAR.
Definition: sqlite3odbc.h:130
#define HSTMT_UNLOCK(hdbc)
Definition: sqlite3odbc.c:533
SQLRETURN SQL_API SQLGetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT buflen, SQLSMALLINT *lenp)
Get cursor name of STMT (UNICODE version).
SQLRETURN SQL_API SQLSetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SETSTMTOPTION_LAST_ARG_TYPE param)
Set option on HSTMT.
Definition: sqlite3odbc.c:9559
SQLRETURN SQL_API SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SETSTMTOPTION_LAST_ARG_TYPE param)
Set option on HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9580
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:1542
Internal structure for managing driver&#39;s sqlite3_get_table() implementation.
Definition: sqlite3odbc.c:1405
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:6817
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:6422
static int busy_handler(void *udata, int count)
Busy callback for SQLite.
Definition: sqlite3odbc.c:2053
static char * uc_to_utf_c(SQLWCHAR *str, int len)
Make UTF8 string from UNICODE string.
Definition: sqlite3odbc.c:1059
#define SQLSETPOSIROW
Definition: sqlite3odbc.h:76
SQLCHAR cursorname[32]
Cursor name.
Definition: sqlite3odbc.h:233
static int str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
Convert string to ODBC TIMESTAMP_STRUCT.
Definition: sqlite3odbc.c:3355
static SQLRETURN starttran(STMT *s)
Start transaction when autocommit off.
Definition: sqlite3odbc.c:7896
static int s3stmt_step(STMT *s)
Do one sqlite statement step gathering one result row.
Definition: sqlite3odbc.c:4301
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:8263
static SQLRETURN drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER buflen)
Internal set option on HSTMT.
Definition: sqlite3odbc.c:9181
SQLINTEGER * bkmrkptr
SQL_ATTR_FETCH_BOOKMARK_PTR.
Definition: sqlite3odbc.h:244
int notnull
NOT NULL constraint on column.
Definition: sqlite3odbc.h:174
int timeout
Lock timeout value.
Definition: sqlite3odbc.h:119
SQLULEN max_rows
SQL_ATTR_MAX_ROWS.
Definition: sqlite3odbc.h:273
int nalloc
alloc&#39;ed size of result array
Definition: sqlite3odbc.c:1410
static void dbtraceapi(DBC *d, char *fn, const char *sql)
Trace function for SQLite API calls.
Definition: sqlite3odbc.c:3876
SQLRETURN SQL_API SQLDriversW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *drvdesc, SQLSMALLINT descmax, SQLSMALLINT *desclenp, SQLWCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
Function not implemented.
Definition: sqlite3odbc.c:4731
int coldef
Definition: sqlite3odbc.h:204
static int getbool(char *string)
Get boolean flag from string.
Definition: sqlite3odbc.c:3687
SQLRETURN SQL_API SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Get option of HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9159
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:5870
int nowchar[2]
Don&#39;t try to use WCHAR.
Definition: sqlite3odbc.h:260
static const char upper_chars[]
Definition: sqlite3odbc.c:546
int s3size
SQLite3 size.
Definition: sqlite3odbc.h:217
static SQLRETURN setupparam(STMT *s, char *sql, int pnum)
Setup SQLite3 parameter for statement parameter.
Definition: sqlite3odbc.c:5049
#define stringify(s)
Definition: sqlite3odbc.c:236
int binlen
Length of blob data.
Definition: sqlite3odbc.h:288
#define SCOL_VARCHAR
Definition: sqlite3odbc.c:255
SQLLEN * lenp0
Actual size of parameter buffer, initial value.
Definition: sqlite3odbc.h:207
int * oemcp
True for Win32 OEM CP translation.
Definition: sqlite3odbc.h:236
static SQLRETURN drvunimpldbc(HDBC dbc)
Report IM001 (not implemented) SQL error code for HDBC.
Definition: sqlite3odbc.c:1793
SQLUSMALLINT * row_status0
Internal status array.
Definition: sqlite3odbc.h:266
#define SCOL_CHAR
Definition: sqlite3odbc.c:256
static void s3stmt_end_if(STMT *s)
Conditionally stop running sqlite statement.
Definition: sqlite3odbc.c:4578
SQLRETURN SQL_API SQLStatisticsW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen, SQLUSMALLINT itype, SQLUSMALLINT resv)
Return statistic information on table indices (UNICODE version).
SQLINTEGER max
Max.
Definition: sqlite3odbc.h:189
static int setsqliteopts(sqlite3 *x, DBC *d)
Set SQLite options (PRAGMAs) given SQLite handle.
Definition: sqlite3odbc.c:2128
int nbindcols
Number of entries in bindcols.
Definition: sqlite3odbc.h:247
int isselect
0 if query is a SELECT statement
Definition: sqlite3odbc.h:238
SQLLEN * lenp
Actual size of parameter buffer.
Definition: sqlite3odbc.h:206
SQLRETURN SQL_API SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
Get option of HSTMT.
Definition: sqlite3odbc.c:9441
static SQLRETURN drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
Internal set option on HSTMT.
Definition: sqlite3odbc.c:9481
char * pwd
Password or NULL.
Definition: sqlite3odbc.h:144
Driver internal structure for environment (HENV).
Definition: sqlite3odbc.h:96
static SQLRETURN drvfreeenv(SQLHENV env)
Internal free HENV.
static char * strdup_(const char *str)
Duplicate string using xmalloc().
Definition: sqlite3odbc.c:616
FILE * trace
sqlite3_trace() file pointer or NULL
Definition: sqlite3odbc.h:143
Internal structure representing dynamic strings.
Definition: sqlite3odbc.c:272
static void freeresult(STMT *s, int clrcols)
Free statement&#39;s result.
SQLRETURN SQL_API SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER buflen)
Set option on HSTMT (UNICODE version).
Definition: sqlite3odbc.c:9368
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:844
sqlite3_stmt * stmt
SQLite3 statement pointer.
Definition: sqlite3odbc.c:1408
static void uc_free(void *str)
Free converted UTF8 or UNICODE string.
Definition: sqlite3odbc.c:1077
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:7939
int oom
True when out of memory.
Definition: sqlite3odbc.c:275
SQLRETURN SQL_API SQLTablesW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen, SQLWCHAR *type, SQLSMALLINT typeLen)
Retrieve information on tables and/or views.
static SQLRETURN drvsetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
Internal set connect attribute of HDBC.
SQLRETURN SQL_API SQLGetFunctions(SQLHDBC dbc, SQLUSMALLINT func, SQLUSMALLINT *flags)
Return information about supported ODBC API functions.
#define min(a, b)
Definition: sqlite3odbc.c:225
SQLRETURN SQL_API SQLBrowseConnectW(SQLHDBC dbc, SQLWCHAR *connin, SQLSMALLINT conninLen, SQLWCHAR *connout, SQLSMALLINT connoutMax, SQLSMALLINT *connoutLen)
Function not implemented.
Definition: sqlite3odbc.c:4767
char * db
Database name.
Definition: sqlite3odbc.h:164
static const char * xdigits
Definition: sqlite3odbc.c:279
long t0
Start time for SQLITE busy handler.
Definition: sqlite3odbc.h:120
int naterr
Native error code.
Definition: sqlite3odbc.h:127
SQLRETURN SQL_API SQLGetDiagRecW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno, SQLWCHAR *sqlstate, SQLINTEGER *nativeerr, SQLWCHAR *msg, SQLSMALLINT buflen, SQLSMALLINT *msglen)
Get error message given handle (HENV, HDBC, or HSTMT) (UNICODE version).
Definition: sqlite3odbc.c:8633
char sqlstate[6]
SQL state for SQLError()
Definition: sqlite3odbc.h:128
int bound
True when SQLBindParameter() called.
Definition: sqlite3odbc.h:212
static void dbloadext(DBC *d, char *exts)
Load SQLite extension modules, if any.
Definition: sqlite3odbc.c:4134
static BOOL InUn(int remove, char *drivername, char *dllname, char *dll2name, char *dsname)
Driver installer/uninstaller.
Definition: inst.c: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.
void(* rowfree)()
Free function for rows.
Definition: sqlite3odbc.h:256
static int TOLOWER(int c)
Definition: sqlite3odbc.c:550
static COL tableSpec3[]
static SQLRETURN drvgetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER bufmax, SQLINTEGER *buflen)
Internal get connect attribute of HDBC.
int curtype
Cursor type.
Definition: sqlite3odbc.h:282
#define array_size(x)
Definition: sqlite3odbc.c:233
STMT * s
Driver statement pointer.
Definition: sqlite3odbc.c:1409
static COL colSpec2[]
Columns for result set of SQLColumns().
int ncol
number of columns in result array
Definition: sqlite3odbc.c:1412
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:5531
int index
Index of column in result.
Definition: sqlite3odbc.h:169
int bkmrk
True when bookmarks used.
Definition: sqlite3odbc.h:243
SQLULEN * parm_proc
SQL_ATTR_PARAMS_PROCESSED_PTR.
Definition: sqlite3odbc.h:280
SQLULEN * bind_offs
SQL_ATTR_ROW_BIND_OFFSET_PTR.
Definition: sqlite3odbc.h:275
int magic
Magic cookie.
Definition: sqlite3odbc.h:112
static SQLRETURN getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype, SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp, int partial)
Internal function to retrieve row data, used by SQLFetch() and friends and SQLGetData().
static SQLRETURN setposrefr(STMT *s, int rsi)
Internal handler to refresh user buffers from driver side result set.
static int dserr(dstr *dsp)
Check error on dynamic string.
Definition: sqlite3odbc.c:769
static SQLRETURN drvconnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen, char *pwd, int pwdLen, int isu)
Internal connect to SQLite database.
static void convJD2YMD(double jd, DATE_STRUCT *ds)
Convert julian day to year/month/day.
Definition: sqlite3odbc.c:3028
static dstr * dsappendq(dstr *dsp, const char *str)
Append string quoted to dynamic string.
Definition: sqlite3odbc.c:690
SQLRETURN SQL_API SQLSetParam(SQLHSTMT stmt, SQLUSMALLINT par, SQLSMALLINT type, SQLSMALLINT sqltype, SQLULEN coldef, SQLSMALLINT scale, SQLPOINTER val, SQLLEN *nval)
Set information on parameter.
Definition: sqlite3odbc.c:5762
static COL colPrivSpec2[]
Columns for result set of SQLColumnPrivileges().
Definition: sqlite3odbc.c:6323
int size
Size of column.
Definition: sqlite3odbc.h:168
static COL scolSpec3[]
Definition: sqlite3odbc.c:6829
static SQLRETURN drvunimplstmt(HSTMT stmt)
Report IM001 (not implemented) SQL error code for HSTMT.
Definition: sqlite3odbc.c:1812
struct dstr dstr
SQLRETURN SQL_API SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
Set information in HENV.
Definition: sqlite3odbc.c:8441
static char * s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
Find out column type.
Definition: sqlite3odbc.c:4208
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:4697
#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:5811
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:780
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:4617
int jdconv
True for julian day conversion.
Definition: sqlite3odbc.h:140
int has_rowid
Flag for ROWID (>= 0 or -1)
Definition: sqlite3odbc.h:292
BINDCOL bkmrkcol
Bookmark bound column.
Definition: sqlite3odbc.h:245
SQLULEN rowset_size
Size of rowset.
Definition: sqlite3odbc.h:264
static SQLRETURN drvstatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen, SQLUSMALLINT itype, SQLUSMALLINT resv)
Internal return statistic information on table indices.
#define ISSPACE(c)
Definition: sqlite3odbc.c:577
#define drvrelgpps(d)
Definition: sqlite3odbc.c:1323
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:5583
char strbuf[64]
String buffer for scalar data.
Definition: sqlite3odbc.h:215
static COL fkeySpec3[]
Definition: sqlite3odbc.c:7274
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:7998
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:1760
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:4596
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:1407
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:8986
static SQLRETURN dbopen(DBC *d, char *name, int isu, char *dsn, char *sflag, char *spflag, char *ntflag, char *jmode, char *busy)
Open SQLite database file given file name and flags.
Definition: sqlite3odbc.c:3920
static int uc_strlen(SQLWCHAR *str)
Return length of UNICODE string.
Definition: sqlite3odbc.c:796
int offs
Byte offset for SQLGetData()
Definition: sqlite3odbc.h:193
struct tblres TBLRES
SQLULEN paramset_count
Internal for paramset.
Definition: sqlite3odbc.h:271
int pdcount
SQLParamData() counter.
Definition: sqlite3odbc.h:251
struct stmt * stmt
STMT list of this DBC.
Definition: sqlite3odbc.h:126
#define HDBC_UNLOCK(hdbc)
Definition: sqlite3odbc.c:531
static SQLRETURN drvdescribecol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name, SQLSMALLINT nameMax, SQLSMALLINT *nameLen, SQLSMALLINT *type, SQLULEN *size, SQLSMALLINT *digits, SQLSMALLINT *nullable)
Internal describe column information.
static char * unquote(char *str)
Strip quotes from quoted string in-place.
Definition: sqlite3odbc.c:1915
static SQLRETURN drvbindcol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type, SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
Internal bind C variable to column of result set.
SQLRETURN SQL_API SQLAllocHandle(SQLSMALLINT type, SQLHANDLE input, SQLHANDLE *output)
Allocate a HENV, HDBC, or HSTMT handle.
static COL statSpec3[]
SQLRETURN SQL_API SQLColumnPrivilegesW(SQLHSTMT stmt, SQLWCHAR *catalog, SQLSMALLINT catalogLen, SQLWCHAR *schema, SQLSMALLINT schemaLen, SQLWCHAR *table, SQLSMALLINT tableLen, SQLWCHAR *column, SQLSMALLINT columnLen)
Retrieve privileges on columns (UNICODE version).
Definition: sqlite3odbc.c:6392
static void convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
Convert julian day to hour/minute/second.
Definition: sqlite3odbc.c:3056
char ** resarr
result array
Definition: sqlite3odbc.c:1406
#define verinfo(maj, min, lev)
Definition: sqlite3odbc.c:238
int s3stmt_noreset
False when sqlite3_reset() needed.
Definition: sqlite3odbc.h:284
static void dbtracerc(DBC *d, int rc, char *err)
Trace function for SQLite return codes.
Definition: sqlite3odbc.c:3896
int trans_disable
True for no transaction support.
Definition: sqlite3odbc.h:138
static SQLRETURN drvspecialcolumns(SQLHSTMT stmt, SQLUSMALLINT id, SQLCHAR *cat, SQLSMALLINT catLen, SQLCHAR *schema, SQLSMALLINT schemaLen, SQLCHAR *table, SQLSMALLINT tableLen, SQLUSMALLINT scope, SQLUSMALLINT nullable)
Internal retrieve information about indexed columns.
Definition: sqlite3odbc.c:6857
int len
Current length.
Definition: sqlite3odbc.c:273
#define DEAD_MAGIC
Definition: sqlite3odbc.c:264
static const char * dsval(dstr *dsp)
Return dynamic string&#39;s value.
Definition: sqlite3odbc.c:754
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:5392
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:8244
static char * fixupsql(char *sql, int sqlLen, int cte, int *nparam, int *isselect, char **errmsg)
Fixup query string with optional parameter markers.
Definition: sqlite3odbc.c:2511
SQLRETURN SQL_API SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
Function not implemented.
Definition: sqlite3odbc.c:5781
#define ODBC_INI
Definition: sqlite3odbc.c:205
#define xrealloc(x, y)
Definition: sqlite3odbc.c:404
#define HDBC_LOCK(hdbc)
Definition: sqlite3odbc.c:530
int naterr
Native error code.
Definition: sqlite3odbc.h:257
int len
Offset/length for SQLParamData()/SQLPutData()
Definition: sqlite3odbc.h:213
static SQLRETURN drvgetdiagrec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno, SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg, SQLSMALLINT buflen, SQLSMALLINT *msglen)
Internal get error message given handle (HENV, HDBC, or HSTMT).
Definition: sqlite3odbc.c:8502
Header file for SQLite3 ODBC driver.
int max
Maximum length of buffer.
Definition: sqlite3odbc.c:274
static int unescpat(char *str)
Unescape search pattern for e.g.
Definition: sqlite3odbc.c:1942

Generated on Tue Jul 12 2016 by doxygen.
Contact: chw@ch-werner.de