00001
00014 #if defined(SQLITE_HAS_CODEC) && defined(SQLITE_API)
00015 #undef WITH_SQLITE_DLLS
00016 #undef SQLITE_DYNLOAD
00017 #include "sqlite3.c"
00018 #endif
00019
00020 #if defined(WITH_SQLITE_DLLS) && (WITH_SQLITE_DLLS > 1)
00021 #define SQLITE_DYNLOAD 1
00022 #endif
00023
00024 #include "sqlite3odbc.h"
00025
00026 #ifdef SQLITE_DYNLOAD
00027
00028 #undef MEMORY_DEBUG
00029
00030 #if defined(_WIN32) || defined(_WIN64)
00031 static void dls_init(void);
00032 static void dls_fini(void);
00033 #else
00034 void dls_init(void);
00035 void dls_fini(void);
00036 #endif
00037
00038 static struct dl_sqlite3_funcs {
00039 void (*activate_see)(const char *p0);
00040 int (*bind_blob)(sqlite3_stmt *p0, int p1, const void *p2, int p3,
00041 void (*p4)(void *));
00042 int (*bind_double)(sqlite3_stmt *p0, int p1, double p2);
00043 int (*bind_int)(sqlite3_stmt *p0, int p1, int p2);
00044 int (*bind_int64)(sqlite3_stmt *p0, int p1, sqlite3_int64 p2);
00045 int (*bind_null)(sqlite3_stmt *p0, int p1);
00046 int (*bind_parameter_count)(sqlite3_stmt *p0);
00047 int (*bind_text)(sqlite3_stmt *p0, int p1, const char *p2, int p3,
00048 void (*p4)(void *));
00049 int (*busy_handler)(sqlite3 *p0, int (*p2)(void *, int), void *p3);
00050 int (*changes)(sqlite3 *p0);
00051 int (*close)(sqlite3 *p0);
00052 const void * (*column_blob)(sqlite3_stmt *p0, int p1);
00053 int (*column_bytes)(sqlite3_stmt *p0, int p1);
00054 int (*column_count)(sqlite3_stmt *p0);
00055 const char * (*column_database_name)(sqlite3_stmt *p0, int p1);
00056 const char * (*column_decltype)(sqlite3_stmt *p0, int p1);
00057 const char * (*column_name)(sqlite3_stmt *p0, int p1);
00058 const char * (*column_origin_name)(sqlite3_stmt *p0, int p1);
00059 const char * (*column_table_name)(sqlite3_stmt *p0, int p1);
00060 const unsigned char * (*column_text)(sqlite3_stmt *p0, int p1);
00061 int (*column_type)(sqlite3_stmt *p0, int p1);
00062 int (*create_function)(sqlite3 *p0, const char *p1, int p2, int p3,
00063 void *p4,
00064 void (*p5)(sqlite3_context *, int, sqlite3_value **),
00065 void (*p6)(sqlite3_context *, int, sqlite3_value **),
00066 void (*p7)(sqlite3_context *));
00067 int (*enable_load_extension)(sqlite3 *p0, int p1);
00068 int (*errcode)(sqlite3 *p0);
00069 const char * (*errmsg)(sqlite3 *p0);
00070 int (*exec)(sqlite3 *p0, const char *p1,
00071 int (*p2)(void *, int, char **, char **),
00072 void *p3, char **p4);
00073 int (*finalize)(sqlite3_stmt *p0);
00074 void (*free)(void *p0);
00075 void (*free_table)(char **p0);
00076 int (*get_table)(sqlite3 *p0, const char *p1, char ***p2,
00077 int *p3, int *p4, char **p5);
00078 void (*interrupt)(sqlite3 *p0);
00079 int (*key)(sqlite3 *p0, const void *p1, int p2);
00080 const char * (*libversion)(void);
00081 int (*load_extension)(sqlite3 *p0, const char *p1, const char *p2,
00082 char **p3);
00083 void * (*malloc)(int p0);
00084 char * (*mprintf)(const char *p0, ...);
00085 int (*open)(const char *p0, sqlite3 **p1);
00086 int (*open16)(const void *p0, sqlite3 **p1);
00087 int (*open_v2)(const char *p0, sqlite3 **p1, int p2, const char *p3);
00088 int (*prepare)(sqlite3 *p0, const char *p1, int p2, sqlite3_stmt **p3,
00089 const char **p4);
00090 int (*prepare_v2)(sqlite3 *p0, const char *p1, int p2, sqlite3_stmt **p3,
00091 const char **p4);
00092 void * (*profile)(sqlite3 *p0,
00093 void (*p1)(void *, const char *, sqlite3_uint64),
00094 void *p2);
00095 void * (*realloc)(void *p0, int p1);
00096 int (*rekey)(sqlite3 *p0, const void *p1, int p2);
00097 int (*reset)(sqlite3_stmt *p0);
00098 void (*result_blob)(sqlite3_context *p0, const void *p1,
00099 int p2, void (*p3)(void *));
00100 void (*result_error)(sqlite3_context *p0, const char *p1, int p2);
00101 void (*result_int)(sqlite3_context *p0, int p1);
00102 void (*result_null)(sqlite3_context *p0);
00103 int (*step)(sqlite3_stmt *p0);
00104 int (*xstrnicmp)(const char *p0, const char *p1, int p2);
00105 int (*table_column_metadata)(sqlite3 *p0, const char *p1,
00106 const char *p2, const char *p3,
00107 char const **p4, char const **p5,
00108 int *p6, int *p7, int *p8);
00109 void * (*trace)(sqlite3 *p0, void (*p1)(void *, const char *), void *p2);
00110 void * (*user_data)(sqlite3_context *p0);
00111 const void * (*value_blob)(sqlite3_value *p0);
00112 int (*value_bytes)(sqlite3_value *p0);
00113 const unsigned char * (*value_text)(sqlite3_value *p0);
00114 int (*value_type)(sqlite3_value *p0);
00115 } dls_funcs;
00116
00117 #define sqlite3_activate_see dls_funcs.activate_see
00118 #define sqlite3_bind_blob dls_funcs.bind_blob
00119 #define sqlite3_bind_double dls_funcs.bind_double
00120 #define sqlite3_bind_int dls_funcs.bind_int
00121 #define sqlite3_bind_int64 dls_funcs.bind_int64
00122 #define sqlite3_bind_null dls_funcs.bind_null
00123 #define sqlite3_bind_parameter_count dls_funcs.bind_parameter_count
00124 #define sqlite3_bind_text dls_funcs.bind_text
00125 #define sqlite3_busy_handler dls_funcs.busy_handler
00126 #define sqlite3_changes dls_funcs.changes
00127 #define sqlite3_close dls_funcs.close
00128 #define sqlite3_column_blob dls_funcs.column_blob
00129 #define sqlite3_column_bytes dls_funcs.column_bytes
00130 #define sqlite3_column_count dls_funcs.column_count
00131 #define sqlite3_column_database_name dls_funcs.column_database_name
00132 #define sqlite3_column_decltype dls_funcs.column_decltype
00133 #define sqlite3_column_name dls_funcs.column_name
00134 #define sqlite3_column_origin_name dls_funcs.column_origin_name
00135 #define sqlite3_column_table_name dls_funcs.column_table_name
00136 #define sqlite3_column_text dls_funcs.column_text
00137 #define sqlite3_column_type dls_funcs.column_type
00138 #define sqlite3_create_function dls_funcs.create_function
00139 #define sqlite3_enable_load_extension dls_funcs.enable_load_extension
00140 #define sqlite3_errcode dls_funcs.errcode
00141 #define sqlite3_errmsg dls_funcs.errmsg
00142 #define sqlite3_exec dls_funcs.exec
00143 #define sqlite3_finalize dls_funcs.finalize
00144 #define sqlite3_free dls_funcs.free
00145 #define sqlite3_free_table dls_funcs.free_table
00146 #define sqlite3_get_table dls_funcs.get_table
00147 #define sqlite3_interrupt dls_funcs.interrupt
00148 #define sqlite3_key dls_funcs.key
00149 #define sqlite3_libversion dls_funcs.libversion
00150 #define sqlite3_load_extension dls_funcs.load_extension
00151 #define sqlite3_malloc dls_funcs.malloc
00152 #define sqlite3_mprintf dls_funcs.mprintf
00153 #define sqlite3_open dls_funcs.open
00154 #define sqlite3_open16 dls_funcs.open16
00155 #define sqlite3_open_v2 dls_funcs.open_v2
00156 #define sqlite3_prepare dls_funcs.prepare
00157 #define sqlite3_prepare_v2 dls_funcs.prepare_v2
00158 #define sqlite3_profile dls_funcs.profile
00159 #define sqlite3_realloc dls_funcs.realloc
00160 #define sqlite3_rekey dls_funcs.rekey
00161 #define sqlite3_reset dls_funcs.reset
00162 #define sqlite3_result_blob dls_funcs.result_blob
00163 #define sqlite3_result_error dls_funcs.result_error
00164 #define sqlite3_result_int dls_funcs.result_int
00165 #define sqlite3_result_null dls_funcs.result_null
00166 #define sqlite3_step dls_funcs.step
00167 #define sqlite3_strnicmp dls_funcs.xstrnicmp
00168 #define sqlite3_table_column_metadata dls_funcs.table_column_metadata
00169 #define sqlite3_trace dls_funcs.trace
00170 #define sqlite3_user_data dls_funcs.user_data
00171 #define sqlite3_value_blob dls_funcs.value_blob
00172 #define sqlite3_value_bytes dls_funcs.value_bytes
00173 #define sqlite3_value_text dls_funcs.value_text
00174 #define sqlite3_value_type dls_funcs.value_type
00175
00176 #endif
00177
00178 #ifndef WITHOUT_WINTERFACE
00179 #define WINTERFACE
00180 #define WCHARSUPPORT
00181 #endif
00182
00183 #if !defined(_WIN32) && !defined(_WIN64)
00184 #if !defined(WCHARSUPPORT) && defined(HAVE_SQLWCHAR) && (HAVE_SQLWCHAR)
00185 #define WCHARSUPPORT
00186 #endif
00187 #endif
00188
00189 #if defined(WINTERFACE)
00190 #include <sqlucode.h>
00191 #endif
00192
00193 #if defined(_WIN32) || defined(_WIN64)
00194 #include "resource3.h"
00195 #define ODBC_INI "ODBC.INI"
00196 #ifndef DRIVER_VER_INFO
00197 #define DRIVER_VER_INFO VERSION
00198 #endif
00199 #else
00200 #define ODBC_INI ".odbc.ini"
00201 #endif
00202
00203 #ifndef DRIVER_VER_INFO
00204 #define DRIVER_VER_INFO "0.0"
00205 #endif
00206
00207 #ifndef COLATTRIBUTE_LAST_ARG_TYPE
00208 #ifdef _WIN64
00209 #define COLATTRIBUTE_LAST_ARG_TYPE SQLLEN *
00210 #else
00211 #define COLATTRIBUTE_LAST_ARG_TYPE SQLPOINTER
00212 #endif
00213 #endif
00214
00215 #ifndef SETSTMTOPTION_LAST_ARG_TYPE
00216 #define SETSTMTOPTION_LAST_ARG_TYPE SQLROWCOUNT
00217 #endif
00218
00219 #undef min
00220 #define min(a, b) ((a) < (b) ? (a) : (b))
00221 #undef max
00222 #define max(a, b) ((a) < (b) ? (b) : (a))
00223
00224 #ifndef PTRDIFF_T
00225 #define PTRDIFF_T int
00226 #endif
00227
00228 #define array_size(x) (sizeof (x) / sizeof (x[0]))
00229
00230 #define stringify1(s) #s
00231 #define stringify(s) stringify1(s)
00232
00233 #define verinfo(maj, min, lev) ((maj) << 16 | (min) << 8 | (lev))
00234
00235
00236
00237 #if defined(WINTERFACE) && !defined(_WIN32) && !defined(_WIN64)
00238 #define SCOL_VARCHAR SQL_WVARCHAR
00239 #define SCOL_CHAR SQL_WCHAR
00240 #else
00241 #define SCOL_VARCHAR SQL_VARCHAR
00242 #define SCOL_CHAR SQL_CHAR
00243 #endif
00244
00245 #define ENV_MAGIC 0x53544145
00246 #define DBC_MAGIC 0x53544144
00247 #define DEAD_MAGIC 0xdeadbeef
00248
00249 static const char *xdigits = "0123456789ABCDEFabcdef";
00250
00251 #ifdef MEMORY_DEBUG
00252
00253 static void *
00254 xmalloc_(int n, char *file, int line)
00255 {
00256 int nn = n + 4 * sizeof (long);
00257 long *p;
00258
00259 p = malloc(nn);
00260 if (!p) {
00261 #if (MEMORY_DEBUG > 1)
00262 fprintf(stderr, "malloc\t%d\tNULL\t%s:%d\n", n, file, line);
00263 #endif
00264 return NULL;
00265 }
00266 p[0] = 0xdead1234;
00267 nn = nn / sizeof (long) - 1;
00268 p[1] = n;
00269 p[nn] = 0xdead5678;
00270 #if (MEMORY_DEBUG > 1)
00271 fprintf(stderr, "malloc\t%d\t%p\t%s:%d\n", n, &p[2], file, line);
00272 #endif
00273 return (void *) &p[2];
00274 }
00275
00276 static void *
00277 xrealloc_(void *old, int n, char *file, int line)
00278 {
00279 int nn = n + 4 * sizeof (long), nnn;
00280 long *p, *pp;
00281
00282 if (n == 0 || !old) {
00283 return xmalloc_(n, file, line);
00284 }
00285 p = &((long *) old)[-2];
00286 if (p[0] != 0xdead1234) {
00287 fprintf(stderr, "*** low end corruption @ %p\n", old);
00288 abort();
00289 }
00290 nnn = p[1] + 4 * sizeof (long);
00291 nnn = nnn / sizeof (long) - 1;
00292 if (p[nnn] != 0xdead5678) {
00293 fprintf(stderr, "*** high end corruption @ %p\n", old);
00294 abort();
00295 }
00296 pp = realloc(p, nn);
00297 if (!pp) {
00298 #if (MEMORY_DEBUG > 1)
00299 fprintf(stderr, "realloc\t%p,%d\tNULL\t%s:%d\n", old, n, file, line);
00300 #endif
00301 return NULL;
00302 }
00303 #if (MEMORY_DEBUG > 1)
00304 fprintf(stderr, "realloc\t%p,%d\t%p\t%s:%d\n", old, n, &pp[2], file, line);
00305 #endif
00306 p = pp;
00307 p[1] = n;
00308 nn = nn / sizeof (long) - 1;
00309 p[nn] = 0xdead5678;
00310 return (void *) &p[2];
00311 }
00312
00313 static void
00314 xfree_(void *x, char *file, int line)
00315 {
00316 long *p;
00317 int n;
00318
00319 if (!x) {
00320 return;
00321 }
00322 p = &((long *) x)[-2];
00323 if (p[0] != 0xdead1234) {
00324 fprintf(stderr, "*** low end corruption @ %p\n", x);
00325 abort();
00326 }
00327 n = p[1] + 4 * sizeof (long);
00328 n = n / sizeof (long) - 1;
00329 if (p[n] != 0xdead5678) {
00330 fprintf(stderr, "*** high end corruption @ %p\n", x);
00331 abort();
00332 }
00333 #if (MEMORY_DEBUG > 1)
00334 fprintf(stderr, "free\t%p\t\t%s:%d\n", x, file, line);
00335 #endif
00336 free(p);
00337 }
00338
00339 static void
00340 xfree__(void *x)
00341 {
00342 xfree_(x, "unknown location", 0);
00343 }
00344
00345 static char *
00346 xstrdup_(const char *str, char *file, int line)
00347 {
00348 char *p;
00349
00350 if (!str) {
00351 #if (MEMORY_DEBUG > 1)
00352 fprintf(stderr, "strdup\tNULL\tNULL\t%s:%d\n", file, line);
00353 #endif
00354 return NULL;
00355 }
00356 p = xmalloc_(strlen(str) + 1, file, line);
00357 if (p) {
00358 strcpy(p, str);
00359 }
00360 #if (MEMORY_DEBUG > 1)
00361 fprintf(stderr, "strdup\t%p\t%p\t%s:%d\n", str, p, file, line);
00362 #endif
00363 return p;
00364 }
00365
00366 #define xmalloc(x) xmalloc_(x, __FILE__, __LINE__)
00367 #define xrealloc(x,y) xrealloc_(x, y, __FILE__, __LINE__)
00368 #define xfree(x) xfree_(x, __FILE__, __LINE__)
00369 #define xstrdup(x) xstrdup_(x, __FILE__, __LINE__)
00370
00371 #else
00372
00373 #define xmalloc(x) sqlite3_malloc(x)
00374 #define xrealloc(x,y) sqlite3_realloc(x, y)
00375 #define xfree(x) sqlite3_free(x)
00376 #define xstrdup(x) strdup_(x)
00377
00378 #endif
00379
00380 #if defined(_WIN32) || defined(_WIN64)
00381
00382 #define vsnprintf _vsnprintf
00383 #define snprintf _snprintf
00384 #define strcasecmp _stricmp
00385 #define strncasecmp _strnicmp
00386
00387 static HINSTANCE NEAR hModule;
00388
00389 #endif
00390
00391 #ifdef HAVE_SQLITE3STRNICMP
00392 #undef strncasecmp
00393 #define strncasecmp(A,B,C) sqlite3_strnicmp(A,B,C)
00394 #undef strcasecmp
00395 #define strcasecmp(A,B) strcasecmp_(A,B)
00396
00397 #if defined(__GNUC__) && (__GNUC__ >= 2)
00398 static int strcasecmp_(const char *a, const char *b)
00399 __attribute__((__unused__));
00400 #endif
00401
00402 static int strcasecmp_(const char *a, const char *b)
00403 {
00404 int c = strlen(a), d = strlen(b);
00405
00406 if (c > d) {
00407 return strncasecmp(a, b, c);
00408 }
00409 return strncasecmp(a, b, d);
00410 }
00411 #endif
00412
00413 #if defined(_WIN32) || defined(_WIN64)
00414
00415
00416
00417
00418
00419
00420 #define HDBC_LOCK(hdbc) \
00421 { \
00422 DBC *d; \
00423 \
00424 if ((hdbc) == SQL_NULL_HDBC) { \
00425 return SQL_INVALID_HANDLE; \
00426 } \
00427 d = (DBC *) (hdbc); \
00428 if (d->magic != DBC_MAGIC || !d->env) { \
00429 return SQL_INVALID_HANDLE; \
00430 } \
00431 if (d->env->magic != ENV_MAGIC) { \
00432 return SQL_INVALID_HANDLE; \
00433 } \
00434 EnterCriticalSection(&d->env->cs); \
00435 d->env->owner = GetCurrentThreadId(); \
00436 }
00437
00438 #define HDBC_UNLOCK(hdbc) \
00439 if ((hdbc) != SQL_NULL_HDBC) { \
00440 DBC *d; \
00441 \
00442 d = (DBC *) (hdbc); \
00443 if (d->magic == DBC_MAGIC && d->env && \
00444 d->env->magic == ENV_MAGIC) { \
00445 d->env->owner = 0; \
00446 LeaveCriticalSection(&d->env->cs); \
00447 } \
00448 }
00449
00450 #define HSTMT_LOCK(hstmt) \
00451 { \
00452 DBC *d; \
00453 \
00454 if ((hstmt) == SQL_NULL_HSTMT) { \
00455 return SQL_INVALID_HANDLE; \
00456 } \
00457 d = (DBC *) ((STMT *) (hstmt))->dbc; \
00458 if (d->magic != DBC_MAGIC || !d->env) { \
00459 return SQL_INVALID_HANDLE; \
00460 } \
00461 if (d->env->magic != ENV_MAGIC) { \
00462 return SQL_INVALID_HANDLE; \
00463 } \
00464 EnterCriticalSection(&d->env->cs); \
00465 d->env->owner = GetCurrentThreadId(); \
00466 }
00467
00468 #define HSTMT_UNLOCK(hstmt) \
00469 if ((hstmt) != SQL_NULL_HSTMT) { \
00470 DBC *d; \
00471 \
00472 d = (DBC *) ((STMT *) (hstmt))->dbc; \
00473 if (d->magic == DBC_MAGIC && d->env && \
00474 d->env->magic == ENV_MAGIC) { \
00475 d->env->owner = 0; \
00476 LeaveCriticalSection(&d->env->cs); \
00477 } \
00478 }
00479
00480 #else
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502 #define HDBC_LOCK(hdbc)
00503 #define HDBC_UNLOCK(hdbc)
00504 #define HSTMT_LOCK(hdbc)
00505 #define HSTMT_UNLOCK(hdbc)
00506
00507 #endif
00508
00509 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
00510 extern void nvfs_init(void);
00511 extern const char *nvfs_makevfs(const char *);
00512 #endif
00513
00514
00515
00516
00517
00518 static const char upper_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
00519 static const char lower_chars[] = "abcdefghijklmnopqrstuvwxyz";
00520
00521 static int
00522 TOLOWER(int c)
00523 {
00524 if (c) {
00525 char *p = strchr(upper_chars, c);
00526
00527 if (p) {
00528 c = lower_chars[p - upper_chars];
00529 }
00530 }
00531 return c;
00532 }
00533
00534
00535
00536
00537
00538 static const char digit_chars[] = "0123456789";
00539
00540 #define ISDIGIT(c) \
00541 ((c) && strchr(digit_chars, (c)) != NULL)
00542
00543
00544
00545
00546
00547 static const char space_chars[] = " \f\n\r\t\v";
00548
00549 #define ISSPACE(c) \
00550 ((c) && strchr(space_chars, (c)) != NULL)
00551
00552
00553
00554
00555
00556
00557 static void dbtraceapi(DBC *d, char *fn, const char *sql);
00558 static void freedyncols(STMT *s);
00559 static void freeresult(STMT *s, int clrcols);
00560 static void freerows(char **rowp);
00561 static void unbindcols(STMT *s);
00562 static void s3stmt_drop(STMT *s);
00563
00564 static SQLRETURN drvexecute(SQLHSTMT stmt, int initial);
00565 static SQLRETURN freestmt(HSTMT stmt);
00566 static SQLRETURN mkbindcols(STMT *s, int ncols);
00567 static SQLRETURN setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp);
00568 static SQLRETURN setupparbuf(STMT *s, BINDPARM *p);
00569 static SQLRETURN starttran(STMT *s);
00570 static SQLRETURN setupparam(STMT *s, char *sql, int pnum);
00571
00572 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
00573
00574 static COL *statSpec2P, *statSpec3P;
00575 #endif
00576
00577 #if (MEMORY_DEBUG < 1)
00578
00584 static char *
00585 strdup_(const char *str)
00586 {
00587 char *p = NULL;
00588
00589 if (str) {
00590 p = xmalloc(strlen(str) + 1);
00591 if (p) {
00592 strcpy(p, str);
00593 }
00594 }
00595 return p;
00596 }
00597 #endif
00598
00599 #ifdef WCHARSUPPORT
00600
00607 static int
00608 uc_strlen(SQLWCHAR *str)
00609 {
00610 int len = 0;
00611
00612 if (str) {
00613 while (*str) {
00614 ++len;
00615 ++str;
00616 }
00617 }
00618 return len;
00619 }
00620
00629 static SQLWCHAR *
00630 uc_strncpy(SQLWCHAR *dest, SQLWCHAR *src, int len)
00631 {
00632 int i = 0;
00633
00634 while (i < len) {
00635 if (!src[i]) {
00636 break;
00637 }
00638 dest[i] = src[i];
00639 ++i;
00640 }
00641 if (i < len) {
00642 dest[i] = 0;
00643 }
00644 return dest;
00645 }
00646
00655 static void
00656 uc_from_utf_buf(unsigned char *str, int len, SQLWCHAR *uc, int ucLen)
00657 {
00658 ucLen = ucLen / sizeof (SQLWCHAR);
00659 if (!uc || ucLen < 0) {
00660 return;
00661 }
00662 if (len < 0) {
00663 len = ucLen * 5;
00664 }
00665 uc[0] = 0;
00666 if (str) {
00667 int i = 0;
00668
00669 while (i < len && *str && i < ucLen) {
00670 unsigned char c = str[0];
00671
00672 if (c < 0x80) {
00673 uc[i++] = c;
00674 ++str;
00675 } else if (c <= 0xc1 || c >= 0xf5) {
00676
00677 ++str;
00678 } else if (c < 0xe0) {
00679 if ((str[1] & 0xc0) == 0x80) {
00680 unsigned long t = ((c & 0x1f) << 6) | (str[1] & 0x3f);
00681
00682 uc[i++] = t;
00683 str += 2;
00684 } else {
00685 uc[i++] = c;
00686 ++str;
00687 }
00688 } else if (c < 0xf0) {
00689 if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80) {
00690 unsigned long t = ((c & 0x0f) << 12) |
00691 ((str[1] & 0x3f) << 6) | (str[2] & 0x3f);
00692
00693 uc[i++] = t;
00694 str += 3;
00695 } else {
00696 uc[i++] = c;
00697 ++str;
00698 }
00699 } else if (c < 0xf8) {
00700 if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 &&
00701 (str[3] & 0xc0) == 0x80) {
00702 unsigned long t = ((c & 0x03) << 18) |
00703 ((str[1] & 0x3f) << 12) | ((str[2] & 0x3f) << 6) |
00704 (str[4] & 0x3f);
00705
00706 if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
00707 t >= 0x10000) {
00708 t -= 0x10000;
00709 uc[i++] = 0xd800 | (t & 0x3ff);
00710 if (i >= ucLen) {
00711 break;
00712 }
00713 t = 0xdc00 | ((t >> 10) & 0x3ff);
00714 }
00715 uc[i++] = t;
00716 str += 4;
00717 } else {
00718 uc[i++] = c;
00719 ++str;
00720 }
00721 } else if (c < 0xfc) {
00722 if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 &&
00723 (str[3] & 0xc0) == 0x80 && (str[4] & 0xc0) == 0x80) {
00724 unsigned long t = ((c & 0x01) << 24) |
00725 ((str[1] & 0x3f) << 18) | ((str[2] & 0x3f) << 12) |
00726 ((str[4] & 0x3f) << 6) | (str[5] & 0x3f);
00727
00728 if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
00729 t >= 0x10000) {
00730 t -= 0x10000;
00731 uc[i++] = 0xd800 | (t & 0x3ff);
00732 if (i >= ucLen) {
00733 break;
00734 }
00735 t = 0xdc00 | ((t >> 10) & 0x3ff);
00736 }
00737 uc[i++] = t;
00738 str += 5;
00739 } else {
00740 uc[i++] = c;
00741 ++str;
00742 }
00743 } else {
00744
00745 ++str;
00746 }
00747 }
00748 if (i < ucLen) {
00749 uc[i] = 0;
00750 }
00751 }
00752 }
00753
00761 static SQLWCHAR *
00762 uc_from_utf(unsigned char *str, int len)
00763 {
00764 SQLWCHAR *uc = NULL;
00765 int ucLen;
00766
00767 if (str) {
00768 if (len == SQL_NTS) {
00769 len = strlen((char *) str);
00770 }
00771 ucLen = sizeof (SQLWCHAR) * (len + 1);
00772 uc = xmalloc(ucLen);
00773 if (uc) {
00774 uc_from_utf_buf(str, len, uc, ucLen);
00775 }
00776 }
00777 return uc;
00778 }
00779
00787 static char *
00788 uc_to_utf(SQLWCHAR *str, int len)
00789 {
00790 int i;
00791 char *cp, *ret = NULL;
00792
00793 if (!str) {
00794 return ret;
00795 }
00796 if (len == SQL_NTS) {
00797 len = uc_strlen(str);
00798 } else {
00799 len = len / sizeof (SQLWCHAR);
00800 }
00801 cp = xmalloc(len * 6 + 1);
00802 if (!cp) {
00803 return ret;
00804 }
00805 ret = cp;
00806 for (i = 0; i < len; i++) {
00807 unsigned long c = str[i];
00808
00809 if (sizeof (SQLWCHAR) == 2 * sizeof (char)) {
00810 c &= 0xffff;
00811 }
00812 if (c < 0x80) {
00813 *cp++ = c;
00814 } else if (c < 0x800) {
00815 *cp++ = 0xc0 | ((c >> 6) & 0x1f);
00816 *cp++ = 0x80 | (c & 0x3f);
00817 } else if (c < 0x10000) {
00818 if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
00819 c >= 0xd800 && c <= 0xdbff && i + 1 < len) {
00820 unsigned long c2 = str[i + 1] & 0xffff;
00821
00822 if (c2 >= 0xdc00 && c <= 0xdfff) {
00823 c = ((c & 0x3ff) | ((c2 & 0x3ff) << 10)) + 0x10000;
00824 *cp++ = 0xf0 | ((c >> 18) & 0x07);
00825 *cp++ = 0x80 | ((c >> 12) & 0x3f);
00826 *cp++ = 0x80 | ((c >> 6) & 0x3f);
00827 *cp++ = 0x80 | (c & 0x3f);
00828 ++i;
00829 continue;
00830 }
00831 }
00832 *cp++ = 0xe0 | ((c >> 12) & 0x0f);
00833 *cp++ = 0x80 | ((c >> 6) & 0x3f);
00834 *cp++ = 0x80 | (c & 0x3f);
00835 } else if (c < 0x200000) {
00836 *cp++ = 0xf0 | ((c >> 18) & 0x07);
00837 *cp++ = 0x80 | ((c >> 12) & 0x3f);
00838 *cp++ = 0x80 | ((c >> 6) & 0x3f);
00839 *cp++ = 0x80 | (c & 0x3f);
00840 } else if (c < 0x4000000) {
00841 *cp++ = 0xf8 | ((c >> 24) & 0x03);
00842 *cp++ = 0x80 | ((c >> 18) & 0x3f);
00843 *cp++ = 0x80 | ((c >> 12) & 0x3f);
00844 *cp++ = 0x80 | ((c >> 6) & 0x3f);
00845 *cp++ = 0x80 | (c & 0x3f);
00846 } else if (c < 0x80000000) {
00847 *cp++ = 0xfc | ((c >> 31) & 0x01);
00848 *cp++ = 0x80 | ((c >> 24) & 0x3f);
00849 *cp++ = 0x80 | ((c >> 18) & 0x3f);
00850 *cp++ = 0x80 | ((c >> 12) & 0x3f);
00851 *cp++ = 0x80 | ((c >> 6) & 0x3f);
00852 *cp++ = 0x80 | (c & 0x3f);
00853 }
00854 }
00855 *cp = '\0';
00856 return ret;
00857 }
00858
00859 #endif
00860
00861 #ifdef WINTERFACE
00862
00870 static char *
00871 uc_to_utf_c(SQLWCHAR *str, int len)
00872 {
00873 if (len != SQL_NTS) {
00874 len = len * sizeof (SQLWCHAR);
00875 }
00876 return uc_to_utf(str, len);
00877 }
00878
00879 #endif
00880
00881 #if defined(WCHARSUPPORT) || defined(_WIN32) || defined(_WIN64)
00882
00888 static void
00889 uc_free(void *str)
00890 {
00891 if (str) {
00892 xfree(str);
00893 }
00894 }
00895
00896 #endif
00897
00898 #if defined(_WIN32) || defined(_WIN64)
00899
00907 static char *
00908 wmb_to_utf(char *str, int len)
00909 {
00910 WCHAR *wstr;
00911 OSVERSIONINFO ovi;
00912 int nchar, is2k, cp = CP_OEMCP;
00913
00914 ovi.dwOSVersionInfoSize = sizeof (ovi);
00915 GetVersionEx(&ovi);
00916 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
00917 if (AreFileApisANSI()) {
00918 cp = is2k ? CP_THREAD_ACP : CP_ACP;
00919 }
00920 nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
00921 wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
00922 if (!wstr) {
00923 return NULL;
00924 }
00925 wstr[0] = 0;
00926 nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
00927 wstr[nchar] = 0;
00928 str = xmalloc((nchar + 1) * 7);
00929 if (!str) {
00930 xfree(wstr);
00931 return NULL;
00932 }
00933 str[0] = '\0';
00934 nchar = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, nchar * 7, 0, 0);
00935 str[nchar] = '\0';
00936 xfree(wstr);
00937 return str;
00938 }
00939
00940 #ifndef WINTERFACE
00941
00949 static char *
00950 wmb_to_utf_c(char *str, int len)
00951 {
00952 if (len == SQL_NTS) {
00953 len = strlen(str);
00954 }
00955 return wmb_to_utf(str, len);
00956 }
00957
00958 #endif
00959
00967 static char *
00968 utf_to_wmb(char *str, int len)
00969 {
00970 WCHAR *wstr;
00971 OSVERSIONINFO ovi;
00972 int nchar, is2k, cp = CP_OEMCP;
00973
00974 ovi.dwOSVersionInfoSize = sizeof (ovi);
00975 GetVersionEx(&ovi);
00976 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
00977 if (AreFileApisANSI()) {
00978 cp = is2k ? CP_THREAD_ACP : CP_ACP;
00979 }
00980 nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
00981 wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
00982 if (!wstr) {
00983 return NULL;
00984 }
00985 wstr[0] = 0;
00986 nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, wstr, nchar);
00987 wstr[nchar] = 0;
00988 str = xmalloc((nchar + 1) * 7);
00989 if (!str) {
00990 xfree(wstr);
00991 return NULL;
00992 }
00993 str[0] = '\0';
00994 nchar = WideCharToMultiByte(cp, 0, wstr, -1, str, nchar * 7, 0, 0);
00995 str[nchar] = '\0';
00996 xfree(wstr);
00997 return str;
00998 }
00999
01000 #ifdef WINTERFACE
01001
01009 static WCHAR *
01010 wmb_to_uc(char *str, int len)
01011 {
01012 WCHAR *wstr;
01013 OSVERSIONINFO ovi;
01014 int nchar, is2k, cp = CP_OEMCP;
01015
01016 ovi.dwOSVersionInfoSize = sizeof (ovi);
01017 GetVersionEx(&ovi);
01018 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
01019 if (AreFileApisANSI()) {
01020 cp = is2k ? CP_THREAD_ACP : CP_ACP;
01021 }
01022 nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
01023 wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
01024 if (!wstr) {
01025 return NULL;
01026 }
01027 wstr[0] = 0;
01028 nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
01029 wstr[nchar] = 0;
01030 return wstr;
01031 }
01032
01040 static char *
01041 uc_to_wmb(WCHAR *wstr, int len)
01042 {
01043 char *str;
01044 OSVERSIONINFO ovi;
01045 int nchar, is2k, cp = CP_OEMCP;
01046
01047 ovi.dwOSVersionInfoSize = sizeof (ovi);
01048 GetVersionEx(&ovi);
01049 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
01050 if (AreFileApisANSI()) {
01051 cp = is2k ? CP_THREAD_ACP : CP_ACP;
01052 }
01053 nchar = WideCharToMultiByte(cp, 0, wstr, len, NULL, 0, 0, 0);
01054 str = xmalloc((nchar + 1) * 2);
01055 if (!str) {
01056 return NULL;
01057 }
01058 str[0] = '\0';
01059 nchar = WideCharToMultiByte(cp, 0, wstr, len, str, nchar * 2, 0, 0);
01060 str[nchar] = '\0';
01061 return str;
01062 }
01063
01064 #endif
01065
01066 #endif
01067
01068
01069 #ifdef USE_DLOPEN_FOR_GPPS
01070
01071 #include <dlfcn.h>
01072
01073 #define SQLGetPrivateProfileString(A,B,C,D,E,F) drvgpps(d,A,B,C,D,E,F)
01074
01075
01076
01077
01078
01079
01080
01081
01082 static void
01083 drvgetgpps(DBC *d)
01084 {
01085 void *lib;
01086 int (*gpps)();
01087
01088 lib = dlopen("libodbcinst.so.1", RTLD_LAZY);
01089 if (!lib) {
01090 lib = dlopen("libodbcinst.so", RTLD_LAZY);
01091 }
01092 if (!lib) {
01093 lib = dlopen("libiodbcinst.so.2", RTLD_LAZY);
01094 }
01095 if (!lib) {
01096 lib = dlopen("libiodbcinst.so", RTLD_LAZY);
01097 }
01098 if (lib) {
01099 gpps = (int (*)()) dlsym(lib, "SQLGetPrivateProfileString");
01100 if (!gpps) {
01101 dlclose(lib);
01102 return;
01103 }
01104 d->instlib = lib;
01105 d->gpps = gpps;
01106 }
01107 }
01108
01109 static void
01110 drvrelgpps(DBC *d)
01111 {
01112 if (d->instlib) {
01113 dlclose(d->instlib);
01114 d->instlib = 0;
01115 }
01116 }
01117
01118 static int
01119 drvgpps(DBC *d, char *sect, char *ent, char *def, char *buf,
01120 int bufsiz, char *fname)
01121 {
01122 if (d->gpps) {
01123 return d->gpps(sect, ent, def, buf, bufsiz, fname);
01124 }
01125 strncpy(buf, def, bufsiz);
01126 buf[bufsiz - 1] = '\0';
01127 return 1;
01128 }
01129 #else
01130 #include <odbcinst.h>
01131 #define drvgetgpps(d)
01132 #define drvrelgpps(d)
01133 #endif
01134
01135
01136
01137
01138
01139 static void
01140 s3bind(DBC *d, sqlite3_stmt *stmt, int nparams, BINDPARM *p)
01141 {
01142 int i;
01143
01144 if (stmt && p && nparams > 0) {
01145 for (i = 0; i < nparams; i++, p++) {
01146 switch (p->s3type) {
01147 default:
01148 case SQLITE_NULL:
01149 sqlite3_bind_null(stmt, i + 1);
01150 if (d->trace) {
01151 fprintf(d->trace, "-- parameter %d: NULL\n", i + 1);
01152 fflush(d->trace);
01153 }
01154 break;
01155 case SQLITE_TEXT:
01156 sqlite3_bind_text(stmt, i + 1, p->s3val, p->s3size,
01157 SQLITE_STATIC);
01158 if (d->trace) {
01159 fprintf(d->trace, "-- parameter %d: '%*s'\n", i + 1,
01160 p->s3size, (char *) p->s3val);
01161 fflush(d->trace);
01162 }
01163 break;
01164 case SQLITE_BLOB:
01165 sqlite3_bind_blob(stmt, i + 1, p->s3val, p->s3size,
01166 SQLITE_STATIC);
01167 if (d->trace) {
01168 fprintf(d->trace, "-- parameter %d: [BLOB]'\n", i + 1);
01169 fflush(d->trace);
01170 }
01171 break;
01172 case SQLITE_FLOAT:
01173 sqlite3_bind_double(stmt, i + 1, p->s3dval);
01174 if (d->trace) {
01175 fprintf(d->trace, "-- parameter %d: %g\n",
01176 i + 1, p->s3dval);
01177 fflush(d->trace);
01178 }
01179 break;
01180 case SQLITE_INTEGER:
01181 if (p->s3size > sizeof (int)) {
01182 sqlite3_bind_int64(stmt, i + 1, p->s3lival);
01183 if (d->trace) {
01184 fprintf(d->trace,
01185 #ifdef _WIN32
01186 "-- parameter %d: %I64d\n",
01187 #else
01188 "-- parameter %d: %lld\n",
01189 #endif
01190 i + 1, p->s3lival);
01191 fflush(d->trace);
01192 }
01193 } else {
01194 sqlite3_bind_int(stmt, i + 1, p->s3ival);
01195 if (d->trace) {
01196 fprintf(d->trace, "-- parameter %d: %d\n",
01197 i + 1, p->s3ival);
01198 fflush(d->trace);
01199 }
01200 }
01201 break;
01202 }
01203 }
01204 }
01205 }
01206
01207
01208
01209
01210
01211
01212 typedef struct tblres {
01213 char **resarr;
01214 char *errmsg;
01215 sqlite3_stmt *stmt;
01216 STMT *s;
01217 int nres;
01218 int nalloc;
01219 int nrow;
01220 int ncol;
01221 PTRDIFF_T ndata;
01222 int rc;
01223 } TBLRES;
01224
01225
01226
01227
01228
01229
01230 static int
01231 drvgettable_row(TBLRES *t, int ncol, int rc)
01232 {
01233 int need;
01234 int i;
01235 char *p;
01236
01237 if (t->nrow == 0 && rc == SQLITE_ROW) {
01238 need = ncol * 2;
01239 } else {
01240 need = ncol;
01241 }
01242 if (t->ndata + need >= t->nalloc) {
01243 char **resnew;
01244 int nalloc = t->nalloc * 2 + need + 1;
01245
01246 resnew = xrealloc(t->resarr, sizeof (char *) * nalloc);
01247 if (!resnew) {
01248 nomem:
01249 t->rc = SQLITE_NOMEM;
01250 return 1;
01251 }
01252 t->nalloc = nalloc;
01253 t->resarr = resnew;
01254 }
01255
01256 if (t->nrow == 0) {
01257 t->ncol = ncol;
01258 for (i = 0; i < ncol; i++) {
01259 p = (char *) sqlite3_column_name(t->stmt, i);
01260 if (p) {
01261 char *q = xmalloc(strlen(p) + 1);
01262
01263 if (!q) {
01264 goto nomem;
01265 }
01266 strcpy(q, p);
01267 p = q;
01268 }
01269 t->resarr[t->ndata++] = p;
01270 }
01271 if (t->s && t->s->guessed_types) {
01272 int ncol2 = ncol;
01273
01274 setupdyncols(t->s, t->stmt, &ncol2);
01275 t->s->guessed_types = 0;
01276 t->s->ncols = ncol;
01277 }
01278 } else if (t->ncol != ncol) {
01279 t->errmsg = sqlite3_mprintf("drvgettable() called with two or"
01280 " more incompatible queries");
01281 t->rc = SQLITE_ERROR;
01282 return 1;
01283 }
01284
01285 if (rc == SQLITE_ROW) {
01286 for (i = 0; i < ncol; i++) {
01287 int coltype = sqlite3_column_type(t->stmt, i);
01288
01289 p = NULL;
01290 if (coltype == SQLITE_BLOB) {
01291 int k, nbytes = sqlite3_column_bytes(t->stmt, i);
01292 char *qp;
01293 unsigned const char *bp;
01294
01295 bp = sqlite3_column_blob(t->stmt, i);
01296 qp = xmalloc(nbytes * 2 + 4);
01297 if (!qp) {
01298 goto nomem;
01299 }
01300 p = qp;
01301 *qp++ = 'X';
01302 *qp++ = '\'';
01303 for (k = 0; k < nbytes; k++) {
01304 *qp++ = xdigits[(bp[k] >> 4)];
01305 *qp++ = xdigits[(bp[k] & 0xF)];
01306 }
01307 *qp++ = '\'';
01308 *qp = '\0';
01309 } else if (coltype != SQLITE_NULL) {
01310 p = xstrdup((char *) sqlite3_column_text(t->stmt, i));
01311 if (!p) {
01312 goto nomem;
01313 }
01314 }
01315 t->resarr[t->ndata++] = p;
01316 }
01317 t->nrow++;
01318 }
01319 return 0;
01320 }
01321
01322 static int
01323 drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp,
01324 int *ncolp, char **errp, int nparam, BINDPARM *p)
01325 {
01326 DBC *d = (DBC *) s->dbc;
01327 int rc = SQLITE_OK, keep = sql == NULL;
01328 TBLRES tres;
01329 const char *sqlleft = 0;
01330 int nretry = 0, haveerr = 0;
01331
01332 if (!resp) {
01333 return SQLITE_ERROR;
01334 }
01335 *resp = NULL;
01336 if (nrowp) {
01337 *nrowp = 0;
01338 }
01339 if (ncolp) {
01340 *ncolp = 0;
01341 }
01342 tres.errmsg = NULL;
01343 tres.nres = 0;
01344 tres.nrow = 0;
01345 tres.ncol = 0;
01346 tres.ndata = 1;
01347 tres.nalloc = 20;
01348 tres.rc = SQLITE_OK;
01349 tres.resarr = xmalloc(sizeof (char *) * tres.nalloc);
01350 tres.stmt = NULL;
01351 tres.s = s;
01352 if (!tres.resarr) {
01353 return SQLITE_NOMEM;
01354 }
01355 tres.resarr[0] = 0;
01356 if (sql == NULL) {
01357 tres.stmt = s->s3stmt;
01358 if (tres.stmt == NULL) {
01359 return SQLITE_NOMEM;
01360 }
01361 goto retrieve;
01362 }
01363 while (sql && *sql && (rc == SQLITE_OK ||
01364 (rc == SQLITE_SCHEMA && (++nretry) < 2))) {
01365 int ncol;
01366
01367 tres.stmt = NULL;
01368 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
01369 dbtraceapi(d, "sqlite3_prepare_v2", sql);
01370 rc = sqlite3_prepare_v2(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
01371 #else
01372 dbtraceapi(d, "sqlite3_prepare", sql);
01373 rc = sqlite3_prepare(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
01374 #endif
01375 if (rc != SQLITE_OK) {
01376 if (tres.stmt) {
01377 dbtraceapi(d, "sqlite3_finalize", 0);
01378 sqlite3_finalize(tres.stmt);
01379 tres.stmt = NULL;
01380 }
01381 continue;
01382 }
01383 if (!tres.stmt) {
01384
01385 sql = sqlleft;
01386 continue;
01387 }
01388 retrieve:
01389 if (sqlite3_bind_parameter_count(tres.stmt) != nparam) {
01390 if (errp) {
01391 *errp =
01392 sqlite3_mprintf("%s", "parameter marker count incorrect");
01393 }
01394 haveerr = 1;
01395 rc = SQLITE_ERROR;
01396 goto tbldone;
01397 }
01398 s3bind(d, tres.stmt, nparam, p);
01399 ncol = sqlite3_column_count(tres.stmt);
01400 while (1) {
01401 if (s->max_rows && tres.nrow >= s->max_rows) {
01402 rc = SQLITE_OK;
01403 break;
01404 }
01405 rc = sqlite3_step(tres.stmt);
01406 if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
01407 if (drvgettable_row(&tres, ncol, rc)) {
01408 rc = SQLITE_ABORT;
01409 goto tbldone;
01410 }
01411 }
01412 if (rc != SQLITE_ROW) {
01413 if (keep) {
01414 dbtraceapi(d, "sqlite3_reset", 0);
01415 rc = sqlite3_reset(tres.stmt);
01416 s->s3stmt_noreset = 1;
01417 } else {
01418 dbtraceapi(d, "sqlite3_finalize", 0);
01419 rc = sqlite3_finalize(tres.stmt);
01420 }
01421 tres.stmt = 0;
01422 if (rc != SQLITE_SCHEMA) {
01423 nretry = 0;
01424 sql = sqlleft;
01425 while (sql && ISSPACE(*sql)) {
01426 sql++;
01427 }
01428 }
01429 if (rc == SQLITE_DONE) {
01430 rc = SQLITE_OK;
01431 }
01432 break;
01433 }
01434 }
01435 }
01436 tbldone:
01437 if (tres.stmt) {
01438 if (keep) {
01439 if (!s->s3stmt_noreset) {
01440 dbtraceapi(d, "sqlite3_reset", 0);
01441 sqlite3_reset(tres.stmt);
01442 s->s3stmt_noreset = 1;
01443 }
01444 } else {
01445 dbtraceapi(d, "sqlite3_finalize", 0);
01446 sqlite3_finalize(tres.stmt);
01447 }
01448 }
01449 if (haveerr) {
01450
01451 } else if (rc != SQLITE_OK && rc == sqlite3_errcode(d->sqlite) && errp) {
01452 *errp = sqlite3_mprintf("%s", sqlite3_errmsg(d->sqlite));
01453 } else if (errp) {
01454 *errp = NULL;
01455 }
01456 if (tres.resarr) {
01457 tres.resarr[0] = (char *) (tres.ndata - 1);
01458 }
01459 if (rc == SQLITE_ABORT) {
01460 freerows(&tres.resarr[1]);
01461 if (tres.errmsg) {
01462 if (errp) {
01463 if (*errp) {
01464 sqlite3_free(*errp);
01465 }
01466 *errp = tres.errmsg;
01467 } else {
01468 sqlite3_free(tres.errmsg);
01469 }
01470 }
01471 return tres.rc;
01472 }
01473 sqlite3_free(tres.errmsg);
01474 if (rc != SQLITE_OK) {
01475 freerows(&tres.resarr[1]);
01476 return rc;
01477 }
01478 *resp = &tres.resarr[1];
01479 if (ncolp) {
01480 *ncolp = tres.ncol;
01481 }
01482 if (nrowp) {
01483 *nrowp = tres.nrow;
01484 }
01485 return rc;
01486 }
01487
01496 #if defined(__GNUC__) && (__GNUC__ >= 2)
01497 static void setstatd(DBC *, int, char *, char *, ...)
01498 __attribute__((format (printf, 3, 5)));
01499 #endif
01500
01501 static void
01502 setstatd(DBC *d, int naterr, char *msg, char *st, ...)
01503 {
01504 va_list ap;
01505
01506 if (!d) {
01507 return;
01508 }
01509 d->naterr = naterr;
01510 d->logmsg[0] = '\0';
01511 if (msg) {
01512 int count;
01513
01514 va_start(ap, st);
01515 count = vsnprintf((char *) d->logmsg, sizeof (d->logmsg), msg, ap);
01516 va_end(ap);
01517 if (count < 0) {
01518 d->logmsg[sizeof (d->logmsg) - 1] = '\0';
01519 }
01520 }
01521 if (!st) {
01522 st = "?????";
01523 }
01524 strncpy(d->sqlstate, st, 5);
01525 d->sqlstate[5] = '\0';
01526 }
01527
01536 #if defined(__GNUC__) && (__GNUC__ >= 2)
01537 static void setstat(STMT *, int, char *, char *, ...)
01538 __attribute__((format (printf, 3, 5)));
01539 #endif
01540
01541 static void
01542 setstat(STMT *s, int naterr, char *msg, char *st, ...)
01543 {
01544 va_list ap;
01545
01546 if (!s) {
01547 return;
01548 }
01549 s->naterr = naterr;
01550 s->logmsg[0] = '\0';
01551 if (msg) {
01552 int count;
01553
01554 va_start(ap, st);
01555 count = vsnprintf((char *) s->logmsg, sizeof (s->logmsg), msg, ap);
01556 va_end(ap);
01557 if (count < 0) {
01558 s->logmsg[sizeof (s->logmsg) - 1] = '\0';
01559 }
01560 }
01561 if (!st) {
01562 st = "?????";
01563 }
01564 strncpy(s->sqlstate, st, 5);
01565 s->sqlstate[5] = '\0';
01566 }
01567
01574 static SQLRETURN
01575 drvunimpldbc(HDBC dbc)
01576 {
01577 DBC *d;
01578
01579 if (dbc == SQL_NULL_HDBC) {
01580 return SQL_INVALID_HANDLE;
01581 }
01582 d = (DBC *) dbc;
01583 setstatd(d, -1, "not supported", "IM001");
01584 return SQL_ERROR;
01585 }
01586
01593 static SQLRETURN
01594 drvunimplstmt(HSTMT stmt)
01595 {
01596 STMT *s;
01597
01598 if (stmt == SQL_NULL_HSTMT) {
01599 return SQL_INVALID_HANDLE;
01600 }
01601 s = (STMT *) stmt;
01602 setstat(s, -1, "not supported", "IM001");
01603 return SQL_ERROR;
01604 }
01605
01611 static void
01612 freep(void *x)
01613 {
01614 if (x && ((char **) x)[0]) {
01615 xfree(((char **) x)[0]);
01616 ((char **) x)[0] = NULL;
01617 }
01618 }
01619
01626 static SQLRETURN
01627 nomem(STMT *s)
01628 {
01629 setstat(s, -1, "out of memory", (*s->ov3) ? "HY000" : "S1000");
01630 return SQL_ERROR;
01631 }
01632
01639 static SQLRETURN
01640 noconn(STMT *s)
01641 {
01642 setstat(s, -1, "not connected", (*s->ov3) ? "HY000" : "S1000");
01643 return SQL_ERROR;
01644 }
01645
01653 #if defined(HAVE_LOCALECONV) || defined(_WIN32) || defined(_WIN64)
01654
01655 static double
01656 ln_strtod(const char *data, char **endp)
01657 {
01658 struct lconv *lc;
01659 char buf[128], *p, *end;
01660 double value;
01661
01662 lc = localeconv();
01663 if (lc && lc->decimal_point && lc->decimal_point[0] &&
01664 lc->decimal_point[0] != '.') {
01665 strncpy(buf, data, sizeof (buf) - 1);
01666 buf[sizeof (buf) - 1] = '\0';
01667 p = strchr(buf, '.');
01668 if (p) {
01669 *p = lc->decimal_point[0];
01670 }
01671 p = buf;
01672 } else {
01673 p = (char *) data;
01674 }
01675 value = strtod(p, &end);
01676 end = (char *) data + (end - p);
01677 if (endp) {
01678 *endp = end;
01679 }
01680 return value;
01681 }
01682
01683 #else
01684
01685 #define ln_strtod(A,B) strtod(A,B)
01686
01687 #endif
01688
01694 static char *
01695 unquote(char *str)
01696 {
01697 if (str) {
01698 int len = strlen(str);
01699
01700 if (len > 1) {
01701 if ((str[0] == '\'' && str[len - 1] == '\'') ||
01702 (str[0] == '"' && str[len - 1] == '"') ||
01703 (str[0] == '[' && str[len - 1] == ']')) {
01704 str[len - 1] = '\0';
01705 strcpy(str, str + 1);
01706 }
01707 }
01708 }
01709 return str;
01710 }
01711
01719 static int
01720 unescpat(char *str)
01721 {
01722 char *p, *q;
01723 int count = 0;
01724
01725 p = str;
01726 while ((q = strchr(p, '_')) != NULL) {
01727 if (q == str || q[-1] != '\\') {
01728 count++;
01729 }
01730 p = q + 1;
01731 }
01732 p = str;
01733 while ((q = strchr(p, '%')) != NULL) {
01734 if (q == str || q[-1] != '\\') {
01735 count++;
01736 }
01737 p = q + 1;
01738 }
01739 p = str;
01740 while ((q = strchr(p, '\\')) != NULL) {
01741 if (q[1] == '\\' || q[1] == '_' || q[1] == '%') {
01742 strcpy(q, q + 1);
01743 }
01744 p = q + 1;
01745 }
01746 return count;
01747 }
01748
01757 static int
01758 namematch(char *str, char *pat, int esc)
01759 {
01760 int cp, ch;
01761
01762 while (1) {
01763 cp = TOLOWER(*pat);
01764 if (cp == '\0') {
01765 if (*str != '\0') {
01766 goto nomatch;
01767 }
01768 break;
01769 }
01770 if (*str == '\0' && cp != '%') {
01771 goto nomatch;
01772 }
01773 if (cp == '%') {
01774 while (*pat == '%') {
01775 ++pat;
01776 }
01777 cp = TOLOWER(*pat);
01778 if (cp == '\0') {
01779 break;
01780 }
01781 while (1) {
01782 if (cp != '_' && cp != '\\') {
01783 while (*str) {
01784 ch = TOLOWER(*str);
01785 if (ch == cp) {
01786 break;
01787 }
01788 ++str;
01789 }
01790 }
01791 if (namematch(str, pat, esc)) {
01792 goto match;
01793 }
01794 if (*str == '\0') {
01795 goto nomatch;
01796 }
01797 ch = TOLOWER(*str);
01798 ++str;
01799 }
01800 }
01801 if (cp == '_') {
01802 pat++;
01803 str++;
01804 continue;
01805 }
01806 if (esc && cp == '\\' &&
01807 (pat[1] == '\\' || pat[1] == '%' || pat[1] == '_')) {
01808 ++pat;
01809 cp = TOLOWER(*pat);
01810 }
01811 ch = TOLOWER(*str++);
01812 ++pat;
01813 if (ch != cp) {
01814 goto nomatch;
01815 }
01816 }
01817 match:
01818 return 1;
01819 nomatch:
01820 return 0;
01821 }
01822
01830 static int
01831 busy_handler(void *udata, int count)
01832 {
01833 DBC *d = (DBC *) udata;
01834 long t1;
01835 int ret = 0;
01836 #if !defined(_WIN32) && !defined(_WIN64)
01837 struct timeval tv;
01838 #ifdef HAVE_NANOSLEEP
01839 struct timespec ts;
01840 #endif
01841 #endif
01842
01843 if (d->busyint) {
01844 d->busyint = 0;
01845 return ret;
01846 }
01847 if (d->timeout <= 0) {
01848 return ret;
01849 }
01850 if (count <= 1) {
01851 #if defined(_WIN32) || defined(_WIN64)
01852 d->t0 = GetTickCount();
01853 #else
01854 gettimeofday(&tv, NULL);
01855 d->t0 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
01856 #endif
01857 }
01858 #if defined(_WIN32) || defined(_WIN64)
01859 t1 = GetTickCount();
01860 #else
01861 gettimeofday(&tv, NULL);
01862 t1 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
01863 #endif
01864 if (t1 - d->t0 > d->timeout) {
01865 goto done;
01866 }
01867 #if defined(_WIN32) || defined(_WIN64)
01868 Sleep(10);
01869 #else
01870 #ifdef HAVE_NANOSLEEP
01871 ts.tv_sec = 0;
01872 ts.tv_nsec = 10000000;
01873 do {
01874 ret = nanosleep(&ts, &ts);
01875 if (ret < 0 && errno != EINTR) {
01876 ret = 0;
01877 }
01878 } while (ret);
01879 #else
01880 #ifdef HAVE_USLEEP
01881 usleep(10000);
01882 #else
01883 tv.tv_sec = 0;
01884 tv.tv_usec = 10000;
01885 select(0, NULL, NULL, NULL, &tv);
01886 #endif
01887 #endif
01888 #endif
01889 ret = 1;
01890 done:
01891 return ret;
01892 }
01893
01905 static int
01906 setsqliteopts(sqlite3 *x, DBC *d)
01907 {
01908 int count = 0, step = 0, max, rc = SQLITE_ERROR;
01909
01910 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
01911 max = d->longnames ? 3 : 1;
01912 #else
01913 max = 3;
01914 #endif
01915 if (d->shortnames) {
01916 max = 3;
01917 }
01918 while (step < max) {
01919 if (step < 1) {
01920 rc = sqlite3_exec(x, "PRAGMA empty_result_callbacks = on;",
01921 NULL, NULL, NULL);
01922 if (rc == SQLITE_OK) {
01923 rc = sqlite3_exec(x, d->fksupport ?
01924 "PRAGMA foreign_keys = on;" :
01925 "PRAGMA foreign_keys = off;",
01926 NULL, NULL, NULL);
01927 }
01928 } else if (step < 2) {
01929 rc = sqlite3_exec(x, d->shortnames ?
01930 "PRAGMA full_column_names = off;" :
01931 "PRAGMA full_column_names = on;",
01932 NULL, NULL, NULL);
01933 } else if (step < 3) {
01934 rc = sqlite3_exec(x, d->shortnames ?
01935 "PRAGMA short_column_names = on;" :
01936 "PRAGMA short_column_names = off;",
01937 NULL, NULL, NULL);
01938 }
01939 if (rc != SQLITE_OK) {
01940 if (rc != SQLITE_BUSY ||
01941 !busy_handler((void *) d, ++count)) {
01942 return rc;
01943 }
01944 continue;
01945 }
01946 count = 0;
01947 ++step;
01948 }
01949 sqlite3_busy_handler(x, busy_handler, (void *) d);
01950 return SQLITE_OK;
01951 }
01952
01962 static void
01963 freerows(char **rowp)
01964 {
01965 PTRDIFF_T size, i;
01966
01967 if (!rowp) {
01968 return;
01969 }
01970 --rowp;
01971 size = (PTRDIFF_T) rowp[0];
01972 for (i = 1; i <= size; i++) {
01973 freep(&rowp[i]);
01974 }
01975 freep(&rowp);
01976 }
01977
01988 static int
01989 mapsqltype(const char *typename, int *nosign, int ov3, int nowchar,
01990 int dobigint)
01991 {
01992 char *p, *q;
01993 int testsign = 0, result;
01994
01995 #ifdef WINTERFACE
01996 result = nowchar ? SQL_VARCHAR : SQL_WVARCHAR;
01997 #else
01998 result = SQL_VARCHAR;
01999 #endif
02000 if (!typename) {
02001 return result;
02002 }
02003 q = p = xmalloc(strlen(typename) + 1);
02004 if (!p) {
02005 return result;
02006 }
02007 strcpy(p, typename);
02008 while (*q) {
02009 *q = TOLOWER(*q);
02010 ++q;
02011 }
02012 if (strncmp(p, "inter", 5) == 0) {
02013 } else if (strncmp(p, "int", 3) == 0 ||
02014 strncmp(p, "mediumint", 9) == 0) {
02015 testsign = 1;
02016 result = SQL_INTEGER;
02017 } else if (strncmp(p, "numeric", 7) == 0) {
02018 result = SQL_DOUBLE;
02019 } else if (strncmp(p, "tinyint", 7) == 0) {
02020 testsign = 1;
02021 result = SQL_TINYINT;
02022 } else if (strncmp(p, "smallint", 8) == 0) {
02023 testsign = 1;
02024 result = SQL_SMALLINT;
02025 } else if (strncmp(p, "float", 5) == 0) {
02026 result = SQL_DOUBLE;
02027 } else if (strncmp(p, "double", 6) == 0 ||
02028 strncmp(p, "real", 4) == 0) {
02029 result = SQL_DOUBLE;
02030 } else if (strncmp(p, "timestamp", 9) == 0) {
02031 #ifdef SQL_TYPE_TIMESTAMP
02032 result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
02033 #else
02034 result = SQL_TIMESTAMP;
02035 #endif
02036 } else if (strncmp(p, "datetime", 8) == 0) {
02037 #ifdef SQL_TYPE_TIMESTAMP
02038 result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
02039 #else
02040 result = SQL_TIMESTAMP;
02041 #endif
02042 } else if (strncmp(p, "time", 4) == 0) {
02043 #ifdef SQL_TYPE_TIME
02044 result = ov3 ? SQL_TYPE_TIME : SQL_TIME;
02045 #else
02046 result = SQL_TIME;
02047 #endif
02048 } else if (strncmp(p, "date", 4) == 0) {
02049 #ifdef SQL_TYPE_DATE
02050 result = ov3 ? SQL_TYPE_DATE : SQL_DATE;
02051 #else
02052 result = SQL_DATE;
02053 #endif
02054 #ifdef SQL_LONGVARCHAR
02055 } else if (strncmp(p, "text", 4) == 0 ||
02056 strncmp(p, "memo", 4) == 0 ||
02057 strncmp(p, "longvarchar", 11) == 0) {
02058 #ifdef WINTERFACE
02059 result = nowchar ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
02060 #else
02061 result = SQL_LONGVARCHAR;
02062 #endif
02063 #ifdef WINTERFACE
02064 } else if (strncmp(p, "wtext", 5) == 0 ||
02065 strncmp(p, "wvarchar", 8) == 0 ||
02066 strncmp(p, "longwvarchar", 12) == 0) {
02067 result = SQL_WLONGVARCHAR;
02068 #endif
02069 #endif
02070 #ifdef SQL_BIT
02071 } else if (strncmp(p, "bool", 4) == 0 ||
02072 strncmp(p, "bit", 3) == 0) {
02073 result = SQL_BIT;
02074 #endif
02075 #ifdef SQL_BIGINT
02076 } else if (strncmp(p, "bigint", 6) == 0) {
02077 testsign = 1;
02078 result = SQL_BIGINT;
02079 #endif
02080 } else if (strncmp(p, "blob", 4) == 0) {
02081 result = SQL_BINARY;
02082 } else if (strncmp(p, "varbinary", 9) == 0) {
02083 result = SQL_VARBINARY;
02084 } else if (strncmp(p, "longvarbinary", 13) == 0) {
02085 result = SQL_LONGVARBINARY;
02086 }
02087 if (nosign) {
02088 if (testsign) {
02089 *nosign = strstr(p, "unsigned") != NULL;
02090 } else {
02091 *nosign = 1;
02092 }
02093 }
02094 #ifdef SQL_BIGINT
02095 if (dobigint && result == SQL_INTEGER) {
02096 result = SQL_BIGINT;
02097 }
02098 #endif
02099 xfree(p);
02100 return result;
02101 }
02102
02112 static void
02113 getmd(const char *typename, int sqltype, int *mp, int *dp)
02114 {
02115 int m = 0, d = 0;
02116
02117 switch (sqltype) {
02118 case SQL_INTEGER: m = 10; d = 9; break;
02119 case SQL_TINYINT: m = 4; d = 3; break;
02120 case SQL_SMALLINT: m = 6; d = 5; break;
02121 case SQL_FLOAT: m = 25; d = 24; break;
02122 case SQL_DOUBLE: m = 54; d = 53; break;
02123 case SQL_VARCHAR: m = 255; d = 0; break;
02124 #ifdef WINTERFACE
02125 #ifdef SQL_WVARCHAR
02126 case SQL_WVARCHAR: m = 255; d = 0; break;
02127 #endif
02128 #endif
02129 #ifdef SQL_TYPE_DATE
02130 case SQL_TYPE_DATE:
02131 #endif
02132 case SQL_DATE: m = 10; d = 0; break;
02133 #ifdef SQL_TYPE_TIME
02134 case SQL_TYPE_TIME:
02135 #endif
02136 case SQL_TIME: m = 8; d = 0; break;
02137 #ifdef SQL_TYPE_TIMESTAMP
02138 case SQL_TYPE_TIMESTAMP:
02139 #endif
02140 case SQL_TIMESTAMP: m = 32; d = 3; break;
02141 #ifdef SQL_LONGVARCHAR
02142 case SQL_LONGVARCHAR : m = 65536; d = 0; break;
02143 #endif
02144 #ifdef WINTERFACE
02145 #ifdef SQL_WLONGVARCHAR
02146 case SQL_WLONGVARCHAR: m = 65536; d = 0; break;
02147 #endif
02148 #endif
02149 case SQL_VARBINARY: m = 255; d = 0; break;
02150 case SQL_LONGVARBINARY: m = 65536; d = 0; break;
02151 #ifdef SQL_BIGINT
02152 case SQL_BIGINT: m = 20; d = 19; break;
02153 #endif
02154 #ifdef SQL_BIT
02155 case SQL_BIT: m = 1; d = 1; break;
02156 #endif
02157 }
02158 if (m && typename) {
02159 int mm, dd;
02160
02161 if (sscanf(typename, "%*[^(](%d)", &mm) == 1) {
02162 if (sqltype == SQL_TIMESTAMP) {
02163 d = mm;
02164 }
02165 #ifdef SQL_TYPE_TIMESTAMP
02166 else if (sqltype == SQL_TYPE_TIMESTAMP) {
02167 d = mm;
02168 }
02169 #endif
02170 else {
02171 m = d = mm;
02172 }
02173 } else if (sscanf(typename, "%*[^(](%d,%d)", &mm, &dd) == 2) {
02174 m = mm;
02175 d = dd;
02176 }
02177 }
02178 if (mp) {
02179 *mp = m;
02180 }
02181 if (dp) {
02182 *dp = d;
02183 }
02184 }
02185
02195 static int
02196 mapdeftype(int type, int stype, int nosign, int nowchar)
02197 {
02198 if (type == SQL_C_DEFAULT) {
02199 switch (stype) {
02200 case SQL_INTEGER:
02201 type = (nosign > 0) ? SQL_C_ULONG : SQL_C_LONG;
02202 break;
02203 case SQL_TINYINT:
02204 type = (nosign > 0) ? SQL_C_UTINYINT : SQL_C_TINYINT;
02205 break;
02206 case SQL_SMALLINT:
02207 type = (nosign > 0) ? SQL_C_USHORT : SQL_C_SHORT;
02208 break;
02209 case SQL_FLOAT:
02210 type = SQL_C_FLOAT;
02211 break;
02212 case SQL_DOUBLE:
02213 type = SQL_C_DOUBLE;
02214 break;
02215 case SQL_TIMESTAMP:
02216 type = SQL_C_TIMESTAMP;
02217 break;
02218 case SQL_TIME:
02219 type = SQL_C_TIME;
02220 break;
02221 case SQL_DATE:
02222 type = SQL_C_DATE;
02223 break;
02224 #ifdef SQL_C_TYPE_TIMESTAMP
02225 case SQL_TYPE_TIMESTAMP:
02226 type = SQL_C_TYPE_TIMESTAMP;
02227 break;
02228 #endif
02229 #ifdef SQL_C_TYPE_TIME
02230 case SQL_TYPE_TIME:
02231 type = SQL_C_TYPE_TIME;
02232 break;
02233 #endif
02234 #ifdef SQL_C_TYPE_DATE
02235 case SQL_TYPE_DATE:
02236 type = SQL_C_TYPE_DATE;
02237 break;
02238 #endif
02239 #ifdef WINTERFACE
02240 case SQL_WVARCHAR:
02241 case SQL_WCHAR:
02242 #ifdef SQL_WLONGVARCHAR
02243 case SQL_WLONGVARCHAR:
02244 #endif
02245 type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
02246 break;
02247 #endif
02248 case SQL_BINARY:
02249 case SQL_VARBINARY:
02250 case SQL_LONGVARBINARY:
02251 type = SQL_C_BINARY;
02252 break;
02253 #ifdef SQL_BIT
02254 case SQL_BIT:
02255 type = SQL_C_BIT;
02256 break;
02257 #endif
02258 #ifdef SQL_BIGINT
02259 case SQL_BIGINT:
02260 type = SQL_C_CHAR;
02261 break;
02262 #endif
02263 default:
02264 #ifdef WINTERFACE
02265 type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
02266 #else
02267 type = SQL_C_CHAR;
02268 #endif
02269 break;
02270 }
02271 }
02272 return type;
02273 }
02274
02285 static char *
02286 fixupsql(char *sql, int sqlLen, int *nparam, int *isselect, char **errmsg)
02287 {
02288 char *q = sql, *qz = NULL, *p, *inq = NULL, *out;
02289 int np = 0, isddl = -1, size;
02290
02291 *errmsg = NULL;
02292 if (sqlLen != SQL_NTS) {
02293 qz = q = xmalloc(sqlLen + 1);
02294 if (!qz) {
02295 return NULL;
02296 }
02297 memcpy(q, sql, sqlLen);
02298 q[sqlLen] = '\0';
02299 size = sqlLen * 4;
02300 } else {
02301 size = strlen(sql) * 4;
02302 }
02303 size += sizeof (char *) - 1;
02304 size &= ~(sizeof (char *) - 1);
02305 p = xmalloc(size);
02306 if (!p) {
02307 errout:
02308 freep(&qz);
02309 return NULL;
02310 }
02311 memset(p, 0, size);
02312 out = p;
02313 while (*q) {
02314 switch (*q) {
02315 case '\'':
02316 case '\"':
02317 if (q == inq) {
02318 inq = NULL;
02319 } else if (!inq) {
02320 inq = q + 1;
02321
02322 while (*inq) {
02323 if (*inq == *q) {
02324 if (inq[1] == *q) {
02325 inq++;
02326 } else {
02327 break;
02328 }
02329 }
02330 inq++;
02331 }
02332 }
02333 *p++ = *q;
02334 break;
02335 case '?':
02336 *p++ = *q;
02337 if (!inq) {
02338 np++;
02339 }
02340 break;
02341 case ';':
02342 if (!inq) {
02343 if (isddl < 0) {
02344 char *qq = out;
02345
02346 while (*qq && ISSPACE(*qq)) {
02347 ++qq;
02348 }
02349 if (*qq && *qq != ';') {
02350 size = strlen(qq);
02351 if ((size >= 5) &&
02352 (strncasecmp(qq, "create", 5) == 0)) {
02353 isddl = 1;
02354 } else if ((size >= 4) &&
02355 (strncasecmp(qq, "drop", 4) == 0)) {
02356 isddl = 1;
02357 } else {
02358 isddl = 0;
02359 }
02360 }
02361 }
02362 if (isddl == 0) {
02363 char *qq = q;
02364
02365 do {
02366 ++qq;
02367 } while (*qq && ISSPACE(*qq));
02368 if (*qq && *qq != ';') {
02369 freep(&out);
02370 *errmsg = "only one SQL statement allowed";
02371 goto errout;
02372 }
02373 }
02374 }
02375 *p++ = *q;
02376 break;
02377 case '{':
02378
02379
02380
02381
02382
02383 if (!inq) {
02384 int ojfn = 0;
02385 char *inq2 = NULL, *end = q + 1;
02386
02387 if (*end != 'd' && *end != 'D' &&
02388 *end != 't' && *end != 'T') {
02389 ojfn = 1;
02390 }
02391 while (*end) {
02392 if (inq2 && *end == *inq2) {
02393 inq2 = NULL;
02394 } else if (inq2 == NULL && *end == '}') {
02395 break;
02396 } else if (inq2 == NULL && (*end == '\'' || *end == '"')) {
02397 inq2 = end;
02398 }
02399 ++end;
02400 }
02401 if (*end == '}') {
02402 char *start = q + 1;
02403 char *end2 = end - 1;
02404
02405 if (ojfn) {
02406 while (start < end) {
02407 if (ISSPACE(*start)) {
02408 break;
02409 }
02410 ++start;
02411 }
02412 while (start < end) {
02413 *p++ = *start;
02414 ++start;
02415 }
02416 q = end;
02417 break;
02418 } else {
02419 while (start < end2 && *start != '\'') {
02420 ++start;
02421 }
02422 while (end2 > start && *end2 != '\'') {
02423 --end2;
02424 }
02425 if (*start == '\'' && *end2 == '\'') {
02426 while (start <= end2) {
02427 *p++ = *start;
02428 ++start;
02429 }
02430 q = end;
02431 break;
02432 }
02433 }
02434 }
02435 }
02436
02437 default:
02438 *p++ = *q;
02439 }
02440 ++q;
02441 }
02442 freep(&qz);
02443 *p = '\0';
02444 if (nparam) {
02445 *nparam = np;
02446 }
02447 if (isselect) {
02448 if (isddl > 0) {
02449 *isselect = 0;
02450 } else {
02451 int incom = 0;
02452
02453 p = out;
02454 while (*p) {
02455 switch (*p) {
02456 case '-':
02457 if (!incom && p[1] == '-') {
02458 incom = -1;
02459 }
02460 break;
02461 case '\n':
02462 if (incom < 0) {
02463 incom = 0;
02464 }
02465 break;
02466 case '/':
02467 if (incom > 0 && p[-1] == '*') {
02468 incom = 0;
02469 p++;
02470 continue;
02471 } else if (!incom && p[1] == '*') {
02472 incom = 1;
02473 }
02474 break;
02475 }
02476 if (!incom && !ISSPACE(*p)) {
02477 break;
02478 }
02479 p++;
02480 }
02481 size = strlen(p);
02482 *isselect = (size >= 6) && (strncasecmp(p, "select", 6) == 0);
02483 }
02484 }
02485 return out;
02486 }
02487
02496 static int
02497 findcol(char **cols, int ncols, char *name)
02498 {
02499 int i;
02500
02501 if (cols) {
02502 for (i = 0; i < ncols; i++) {
02503 if (strcmp(cols[i], name) == 0) {
02504 return i;
02505 }
02506 }
02507 }
02508 return -1;
02509 }
02510
02527 static void
02528 fixupdyncols(STMT *s, DBC *d)
02529 {
02530 int i;
02531 #if !defined(HAVE_SQLITE3TABLECOLUMNMETADATA) || !(HAVE_SQLITE3TABLECOLUMNMETADATA)
02532 int k, pk, nn, t, r, nrows, ncols;
02533 char **rowp, *flagp, flags[128];
02534 #endif
02535
02536 if (!s->dyncols) {
02537 return;
02538 }
02539
02540 if (!s->longnames) {
02541 if (s->dcols > 1) {
02542 char *table = s->dyncols[0].table;
02543
02544 for (i = 1; table[0] && i < s->dcols; i++) {
02545 if (strcmp(s->dyncols[i].table, table)) {
02546 break;
02547 }
02548 }
02549 if (i >= s->dcols) {
02550 for (i = 0; i < s->dcols; i++) {
02551 s->dyncols[i].label = s->dyncols[i].column;
02552 }
02553 }
02554 } else if (s->dcols == 1) {
02555 s->dyncols[0].label = s->dyncols[0].column;
02556 }
02557 }
02558 for (i = 0; i < s->dcols; i++) {
02559 s->dyncols[i].type =
02560 mapsqltype(s->dyncols[i].typename, &s->dyncols[i].nosign, *s->ov3,
02561 s->nowchar[0] || s->nowchar[1], s->dobigint);
02562 getmd(s->dyncols[i].typename, s->dyncols[i].type,
02563 &s->dyncols[i].size, &s->dyncols[i].prec);
02564 #ifdef SQL_LONGVARCHAR
02565 if (s->dyncols[i].type == SQL_VARCHAR &&
02566 s->dyncols[i].size > 255) {
02567 s->dyncols[i].type = SQL_LONGVARCHAR;
02568 }
02569 #endif
02570 #ifdef WINTERFACE
02571 #ifdef SQL_WLONGVARCHAR
02572 if (s->dyncols[i].type == SQL_WVARCHAR &&
02573 s->dyncols[i].size > 255) {
02574 s->dyncols[i].type = SQL_WLONGVARCHAR;
02575 }
02576 #endif
02577 #endif
02578 if (s->dyncols[i].type == SQL_VARBINARY &&
02579 s->dyncols[i].size > 255) {
02580 s->dyncols[i].type = SQL_LONGVARBINARY;
02581 }
02582 }
02583 #if !defined(HAVE_SQLITE3TABLECOLUMNMETADATA) || !(HAVE_SQLITE3TABLECOLUMNMETADATA)
02584 if (s->dcols > array_size(flags)) {
02585 flagp = xmalloc(sizeof (flags[0]) * s->dcols);
02586 if (flagp == NULL) {
02587 return;
02588 }
02589 } else {
02590 flagp = flags;
02591 }
02592 memset(flagp, 0, sizeof (flags[0]) * s->dcols);
02593 for (i = 0; i < s->dcols; i++) {
02594 s->dyncols[i].autoinc = SQL_FALSE;
02595 s->dyncols[i].notnull = SQL_NULLABLE;
02596 }
02597 for (i = 0; i < s->dcols; i++) {
02598 int ret, lastpk = -1, autoinccount = 0;
02599 char *sql;
02600
02601 if (!s->dyncols[i].table[0]) {
02602 continue;
02603 }
02604 if (flagp[i]) {
02605 continue;
02606 }
02607 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", s->dyncols[i].table);
02608 if (!sql) {
02609 continue;
02610 }
02611 dbtraceapi(d, "sqlite3_get_table", sql);
02612 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, NULL);
02613 sqlite3_free(sql);
02614 if (ret != SQLITE_OK) {
02615 continue;
02616 }
02617 k = findcol(rowp, ncols, "name");
02618 t = findcol(rowp, ncols, "type");
02619 pk = findcol(rowp, ncols, "pk");
02620 nn = findcol(rowp, ncols, "notnull");
02621 if (k < 0 || t < 0) {
02622 goto freet;
02623 }
02624 for (r = 1; r <= nrows; r++) {
02625 int m;
02626
02627 for (m = i; m < s->dcols; m++) {
02628 char *colname = s->dyncols[m].column;
02629
02630 if (s->longnames) {
02631 char *dotp = strchr(colname, '.');
02632
02633 if (dotp) {
02634 colname = dotp + 1;
02635 }
02636 }
02637 if (!flagp[m] &&
02638 strcmp(colname, rowp[r * ncols + k]) == 0 &&
02639 strcmp(s->dyncols[m].table, s->dyncols[i].table) == 0) {
02640 char *typename = rowp[r * ncols + t];
02641
02642 flagp[m] = 1;
02643 freep(&s->dyncols[m].typename);
02644 s->dyncols[m].typename = xstrdup(typename);
02645 s->dyncols[m].type =
02646 mapsqltype(typename, &s->dyncols[m].nosign, *s->ov3,
02647 s->nowchar[0] || s->nowchar[1],
02648 s->dobigint);
02649 getmd(typename, s->dyncols[m].type, &s->dyncols[m].size,
02650 &s->dyncols[m].prec);
02651 #ifdef SQL_LONGVARCHAR
02652 if (s->dyncols[m].type == SQL_VARCHAR &&
02653 s->dyncols[m].size > 255) {
02654 s->dyncols[m].type = SQL_LONGVARCHAR;
02655 }
02656 #endif
02657 #ifdef WINTERFACE
02658 #ifdef SQL_WLONGVARCHAR
02659 if (s->dyncols[i].type == SQL_WVARCHAR &&
02660 s->dyncols[i].size > 255) {
02661 s->dyncols[i].type = SQL_WLONGVARCHAR;
02662 }
02663 #endif
02664 #endif
02665 if (s->dyncols[i].type == SQL_VARBINARY &&
02666 s->dyncols[i].size > 255) {
02667 s->dyncols[i].type = SQL_LONGVARBINARY;
02668 }
02669 if (pk >= 0 && strcmp(rowp[r * ncols + pk], "1") == 0) {
02670 if (++autoinccount > 1) {
02671 if (lastpk >= 0) {
02672 s->dyncols[lastpk].autoinc = SQL_FALSE;
02673 lastpk = -1;
02674 }
02675 } else {
02676 lastpk = m;
02677 if (strlen(typename) == 7 &&
02678 strncasecmp(typename, "integer", 7) == 0) {
02679 s->dyncols[m].autoinc = SQL_TRUE;
02680 }
02681 }
02682 }
02683 if (nn >= 0 && rowp[r * ncols + nn][0] != '0') {
02684 s->dyncols[m].notnull = SQL_NO_NULLS;
02685 }
02686 }
02687 }
02688 }
02689 freet:
02690 sqlite3_free_table(rowp);
02691 }
02692 if (flagp != flags) {
02693 freep(&flagp);
02694 }
02695 #endif
02696 }
02697
02705 static int
02706 getmdays(int year, int month)
02707 {
02708 static const int mdays[] = {
02709 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
02710 };
02711 int mday;
02712
02713 if (month < 1) {
02714 return 0;
02715 }
02716 mday = mdays[(month - 1) % 12];
02717 if (mday == 28 && year % 4 == 0 &&
02718 (!(year % 100 == 0) || year % 400 == 0)) {
02719 mday++;
02720 }
02721 return mday;
02722 }
02723
02735 static int
02736 str2date(char *str, DATE_STRUCT *ds)
02737 {
02738 int i, err = 0;
02739 char *p, *q, sepc = '\0';
02740
02741 ds->year = ds->month = ds->day = 0;
02742 p = str;
02743 while (*p && !ISDIGIT(*p)) {
02744 ++p;
02745 }
02746 q = p;
02747 i = 0;
02748 while (*q && !ISDIGIT(*q)) {
02749 ++i;
02750 ++q;
02751 }
02752 if (i >= 8) {
02753 char buf[8];
02754
02755 strncpy(buf, p + 0, 4); buf[4] = '\0';
02756 ds->year = strtol(buf, NULL, 10);
02757 strncpy(buf, p + 4, 2); buf[2] = '\0';
02758 ds->month = strtol(buf, NULL, 10);
02759 strncpy(buf, p + 6, 2); buf[2] = '\0';
02760 ds->day = strtol(buf, NULL, 10);
02761 goto done;
02762 }
02763 i = 0;
02764 while (i < 3) {
02765 int n;
02766
02767 q = NULL;
02768 n = strtol(p, &q, 10);
02769 if (!q || q == p) {
02770 if (*q == '\0') {
02771 if (i == 0) {
02772 err = 1;
02773 }
02774 goto done;
02775 }
02776 }
02777 if (!sepc) {
02778 sepc = *q;
02779 }
02780 if (*q == '-' || *q == '/' || *q == '\0' || i == 2) {
02781 switch (i) {
02782 case 0: ds->year = n; break;
02783 case 1: ds->month = n; break;
02784 case 2: ds->day = n; break;
02785 }
02786 ++i;
02787 if (*q) {
02788 ++q;
02789 }
02790 } else {
02791 i = 0;
02792 while (*q && !ISDIGIT(*q)) {
02793 ++q;
02794 }
02795 }
02796 p = q;
02797 }
02798 done:
02799
02800 if (err ||
02801 ds->month < 1 || ds->month > 12 ||
02802 ds->day < 1 || ds->day > getmdays(ds->year, ds->month)) {
02803 if (sepc == '/') {
02804
02805 int t[3];
02806
02807 t[0] = ds->year;
02808 t[1] = ds->month;
02809 t[2] = ds->day;
02810 ds->year = t[2];
02811 ds->day = t[1];
02812 ds->month = t[0];
02813 if (ds->month >= 1 && ds->month <= 12 &&
02814 (ds->day >= 1 || ds->day <= getmdays(ds->year, ds->month))) {
02815 return 0;
02816 }
02817 }
02818 return -1;
02819 }
02820 return 0;
02821 }
02822
02833 static int
02834 str2time(char *str, TIME_STRUCT *ts)
02835 {
02836 int i, err = 0, ampm = -1;
02837 char *p, *q;
02838
02839 ts->hour = ts->minute = ts->second = 0;
02840 p = str;
02841 while (*p && !ISDIGIT(*p)) {
02842 ++p;
02843 }
02844 q = p;
02845 i = 0;
02846 while (*q && ISDIGIT(*q)) {
02847 ++i;
02848 ++q;
02849 }
02850 if (i >= 6) {
02851 char buf[4];
02852
02853 strncpy(buf, p + 0, 2); buf[2] = '\0';
02854 ts->hour = strtol(buf, NULL, 10);
02855 strncpy(buf, p + 2, 2); buf[2] = '\0';
02856 ts->minute = strtol(buf, NULL, 10);
02857 strncpy(buf, p + 4, 2); buf[2] = '\0';
02858 ts->second = strtol(buf, NULL, 10);
02859 goto done;
02860 }
02861 i = 0;
02862 while (i < 3) {
02863 int n;
02864
02865 q = NULL;
02866 n = strtol(p, &q, 10);
02867 if (!q || q == p) {
02868 if (*q == '\0') {
02869 if (i == 0) {
02870 err = 1;
02871 }
02872 goto done;
02873 }
02874 }
02875 if (*q == ':' || *q == '\0' || i == 2) {
02876 switch (i) {
02877 case 0: ts->hour = n; break;
02878 case 1: ts->minute = n; break;
02879 case 2: ts->second = n; break;
02880 }
02881 ++i;
02882 if (*q) {
02883 ++q;
02884 }
02885 } else {
02886 i = 0;
02887 while (*q && !ISDIGIT(*q)) {
02888 ++q;
02889 }
02890 }
02891 p = q;
02892 }
02893 if (!err) {
02894 while (*p) {
02895 if ((p[0] == 'p' || p[0] == 'P') &&
02896 (p[1] == 'm' || p[1] == 'M')) {
02897 ampm = 1;
02898 } else if ((p[0] == 'a' || p[0] == 'A') &&
02899 (p[1] == 'm' || p[1] == 'M')) {
02900 ampm = 0;
02901 }
02902 ++p;
02903 }
02904 if (ampm > 0) {
02905 if (ts->hour < 12) {
02906 ts->hour += 12;
02907 }
02908 } else if (ampm == 0) {
02909 if (ts->hour == 12) {
02910 ts->hour = 0;
02911 }
02912 }
02913 }
02914 done:
02915
02916 if (err || ts->hour > 23 || ts->minute > 59 || ts->second > 59) {
02917 return -1;
02918 }
02919 return 0;
02920 }
02921
02937 static int
02938 str2timestamp(char *str, TIMESTAMP_STRUCT *tss)
02939 {
02940 int i, m, n, err = 0, ampm = -1;
02941 char *p, *q, in = '\0', sepc = '\0';
02942
02943 tss->year = tss->month = tss->day = 0;
02944 tss->hour = tss->minute = tss->second = 0;
02945 tss->fraction = 0;
02946 p = str;
02947 while (*p && !ISDIGIT(*p)) {
02948 ++p;
02949 }
02950 q = p;
02951 i = 0;
02952 while (*q && ISDIGIT(*q)) {
02953 ++i;
02954 ++q;
02955 }
02956 if (i >= 14) {
02957 char buf[16];
02958
02959 strncpy(buf, p + 0, 4); buf[4] = '\0';
02960 tss->year = strtol(buf, NULL, 10);
02961 strncpy(buf, p + 4, 2); buf[2] = '\0';
02962 tss->month = strtol(buf, NULL, 10);
02963 strncpy(buf, p + 6, 2); buf[2] = '\0';
02964 tss->day = strtol(buf, NULL, 10);
02965 strncpy(buf, p + 8, 2); buf[2] = '\0';
02966 tss->hour = strtol(buf, NULL, 10);
02967 strncpy(buf, p + 10, 2); buf[2] = '\0';
02968 tss->minute = strtol(buf, NULL, 10);
02969 strncpy(buf, p + 12, 2); buf[2] = '\0';
02970 tss->second = strtol(buf, NULL, 10);
02971 if (i > 14) {
02972 m = i - 14;
02973 strncpy(buf, p + 14, m);
02974 while (m < 9) {
02975 buf[m] = '0';
02976 ++m;
02977 }
02978 buf[m] = '\0';
02979 tss->fraction = strtol(buf, NULL, 10);
02980 }
02981 m = 7;
02982 goto done;
02983 }
02984 m = i = 0;
02985 while ((m & 7) != 7) {
02986 q = NULL;
02987 n = strtol(p, &q, 10);
02988 if (!q || q == p) {
02989 if (*q == '\0') {
02990 if (m < 1) {
02991 err = 1;
02992 }
02993 goto done;
02994 }
02995 }
02996 if (in == '\0') {
02997 switch (*q) {
02998 case '-':
02999 case '/':
03000 if ((m & 1) == 0) {
03001 in = *q;
03002 i = 0;
03003 }
03004 break;
03005 case ':':
03006 if ((m & 2) == 0) {
03007 in = *q;
03008 i = 0;
03009 }
03010 break;
03011 case ' ':
03012 case '.':
03013 break;
03014 default:
03015 in = '\0';
03016 i = 0;
03017 break;
03018 }
03019 }
03020 switch (in) {
03021 case '-':
03022 case '/':
03023 if (!sepc) {
03024 sepc = in;
03025 }
03026 switch (i) {
03027 case 0: tss->year = n; break;
03028 case 1: tss->month = n; break;
03029 case 2: tss->day = n; break;
03030 }
03031 if (++i >= 3) {
03032 i = 0;
03033 m |= 1;
03034 if (!(m & 2)) {
03035 m |= 8;
03036 }
03037 goto skip;
03038 } else {
03039 ++q;
03040 }
03041 break;
03042 case ':':
03043 switch (i) {
03044 case 0: tss->hour = n; break;
03045 case 1: tss->minute = n; break;
03046 case 2: tss->second = n; break;
03047 }
03048 if (++i >= 3) {
03049 i = 0;
03050 m |= 2;
03051 if (*q == '.') {
03052 in = '.';
03053 goto skip2;
03054 }
03055 if (*q == ' ') {
03056 if ((m & 1) == 0) {
03057 char *e = NULL;
03058 int dummy;
03059
03060 dummy = strtol(q + 1, &e, 10);
03061 if (e && *e == '-') {
03062 goto skip;
03063 }
03064 }
03065 in = '.';
03066 goto skip2;
03067 }
03068 goto skip;
03069 } else {
03070 ++q;
03071 }
03072 break;
03073 case '.':
03074 if (++i >= 1) {
03075 int ndig = q - p;
03076
03077 if (p[0] == '+' || p[0] == '-') {
03078 ndig--;
03079 }
03080 while (ndig < 9) {
03081 n = n * 10;
03082 ++ndig;
03083 }
03084 tss->fraction = n;
03085 m |= 4;
03086 i = 0;
03087 }
03088 default:
03089 skip:
03090 in = '\0';
03091 skip2:
03092 while (*q && !ISDIGIT(*q)) {
03093 if ((q[0] == 'a' || q[0] == 'A') &&
03094 (q[1] == 'm' || q[1] == 'M')) {
03095 ampm = 0;
03096 ++q;
03097 } else if ((q[0] == 'p' || q[0] == 'P') &&
03098 (q[1] == 'm' || q[1] == 'M')) {
03099 ampm = 1;
03100 ++q;
03101 }
03102 ++q;
03103 }
03104 }
03105 p = q;
03106 }
03107 if ((m & 7) > 1 && (m & 8)) {
03108
03109 if (p > str && ISDIGIT(*p)) {
03110 int nn, sign;
03111
03112 q = p - 1;
03113 if (*q != '+' && *q != '-') {
03114 goto done;
03115 }
03116 sign = (*q == '+') ? -1 : 1;
03117 q = NULL;
03118 n = strtol(p, &q, 10);
03119 if (!q || *q++ != ':' || !ISDIGIT(*q)) {
03120 goto done;
03121 }
03122 p = q;
03123 q = NULL;
03124 nn = strtol(p, &q, 10);
03125 tss->minute += nn * sign;
03126 if ((SQLSMALLINT) tss->minute < 0) {
03127 tss->hour -= 1;
03128 tss->minute += 60;
03129 } else if (tss->minute >= 60) {
03130 tss->hour += 1;
03131 tss->minute -= 60;
03132 }
03133 tss->hour += n * sign;
03134 if ((SQLSMALLINT) tss->hour < 0) {
03135 tss->day -= 1;
03136 tss->hour += 24;
03137 } else if (tss->hour >= 24) {
03138 tss->day += 1;
03139 tss->hour -= 24;
03140 }
03141 if ((short) tss->day < 1 || tss->day >= 28) {
03142 int mday, pday, pmon;
03143
03144 mday = getmdays(tss->year, tss->month);
03145 pmon = tss->month - 1;
03146 if (pmon < 1) {
03147 pmon = 12;
03148 }
03149 pday = getmdays(tss->year, pmon);
03150 if ((SQLSMALLINT) tss->day < 1) {
03151 tss->month -= 1;
03152 tss->day = pday;
03153 } else if (tss->day > mday) {
03154 tss->month += 1;
03155 tss->day = 1;
03156 }
03157 if ((SQLSMALLINT) tss->month < 1) {
03158 tss->year -= 1;
03159 tss->month = 12;
03160 } else if (tss->month > 12) {
03161 tss->year += 1;
03162 tss->month = 1;
03163 }
03164 }
03165 }
03166 }
03167 done:
03168 if ((m & 1) &&
03169 (tss->month < 1 || tss->month > 12 ||
03170 tss->day < 1 || tss->day > getmdays(tss->year, tss->month))) {
03171 if (sepc == '/') {
03172
03173 int t[3];
03174
03175 t[0] = tss->year;
03176 t[1] = tss->month;
03177 t[2] = tss->day;
03178 tss->year = t[2];
03179 tss->day = t[1];
03180 tss->month = t[0];
03181 }
03182 }
03183
03184 if (!err && (m & 1) == 0) {
03185 #ifdef _WIN32
03186 SYSTEMTIME t;
03187
03188 GetLocalTime(&t);
03189 tss->year = t.wYear;
03190 tss->month = t.wMonth;
03191 tss->day = t.wDay;
03192 #else
03193 struct timeval tv;
03194 struct tm tm;
03195
03196 gettimeofday(&tv, NULL);
03197 tm = *localtime(&tv.tv_sec);
03198 tss->year = tm.tm_year + 1900;
03199 tss->month = tm.tm_mon + 1;
03200 tss->day = tm.tm_mday;
03201 #endif
03202 }
03203
03204 if (tss->fraction < 0) {
03205 tss->fraction = 0;
03206 }
03207
03208 if (err ||
03209 tss->month < 1 || tss->month > 12 ||
03210 tss->day < 1 || tss->day > getmdays(tss->year, tss->month) ||
03211 tss->hour > 23 || tss->minute > 59 || tss->second > 59) {
03212 return -1;
03213 }
03214 if ((m & 7) > 1) {
03215 if (ampm > 0) {
03216 if (tss->hour < 12) {
03217 tss->hour += 12;
03218 }
03219 } else if (ampm == 0) {
03220 if (tss->hour == 12) {
03221 tss->hour = 0;
03222 }
03223 }
03224 }
03225 return ((m & 7) < 1) ? -1 : 0;
03226 }
03227
03234 static int
03235 getbool(char *string)
03236 {
03237 if (string) {
03238 return string[0] && strchr("Yy123456789Tt", string[0]) != NULL;
03239 }
03240 return 0;
03241 }
03242
03250 static void
03251 blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
03252 {
03253 #if 0
03254 DBC *d = (DBC *) sqlite3_user_data(ctx);
03255 #endif
03256 char *filename = 0;
03257
03258 if (nargs > 0) {
03259 if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
03260 filename = (char *) sqlite3_value_text(args[0]);
03261 }
03262 }
03263 if (filename) {
03264 #ifdef _WIN32
03265 char *wname = utf_to_wmb(filename, -1);
03266 FILE *f;
03267 #else
03268 FILE *f = fopen(filename, "r");
03269 #endif
03270 char *p;
03271 long n, nn;
03272
03273 #ifdef _WIN32
03274 if (wname) {
03275 f = fopen(wname, "rb");
03276 } else {
03277 sqlite3_result_error(ctx, "out of memory", -1);
03278 return;
03279 }
03280 uc_free(wname);
03281 #endif
03282 if (f) {
03283 if (fseek(f, 0, SEEK_END) == 0) {
03284 n = ftell(f);
03285 if (fseek(f, 0, SEEK_SET) == 0) {
03286 p = sqlite3_malloc(n);
03287 if (p) {
03288 nn = fread(p, 1, n, f);
03289 if (nn != n) {
03290 sqlite3_result_error(ctx, "read error", -1);
03291 sqlite3_free(p);
03292 } else {
03293 sqlite3_result_blob(ctx, p, n, sqlite3_free);
03294 }
03295 } else {
03296 sqlite3_result_error(ctx, "out of memory", -1);
03297 }
03298 } else {
03299 sqlite3_result_error(ctx, "seek error", -1);
03300 }
03301 } else {
03302 sqlite3_result_error(ctx, "seek error", -1);
03303 }
03304 fclose(f);
03305 } else {
03306 sqlite3_result_error(ctx, "cannot open file", -1);
03307 }
03308 } else {
03309 sqlite3_result_error(ctx, "no filename given", -1);
03310 }
03311 }
03312
03320 static void
03321 blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
03322 {
03323 #if 0
03324 DBC *d = (DBC *) sqlite3_user_data(ctx);
03325 #endif
03326 char *filename = 0;
03327 char *p = 0;
03328 int n = 0;
03329
03330 if (nargs > 0) {
03331 p = (char *) sqlite3_value_blob(args[0]);
03332 n = sqlite3_value_bytes(args[0]);
03333 }
03334 if (nargs > 1) {
03335 if (sqlite3_value_type(args[1]) != SQLITE_NULL) {
03336 filename = (char *) sqlite3_value_text(args[1]);
03337 }
03338 }
03339 if (p) {
03340 if (filename) {
03341 #ifdef _WIN32
03342 char *wname = utf_to_wmb(filename, -1);
03343 FILE *f;
03344 #else
03345 FILE *f = fopen(filename, "w");
03346 #endif
03347 int nn;
03348
03349 #ifdef _WIN32
03350 if (wname) {
03351 f = fopen(wname, "wb");
03352 } else {
03353 sqlite3_result_error(ctx, "out of memory", -1);
03354 return;
03355 }
03356 uc_free(wname);
03357 #endif
03358 if (f) {
03359 nn = fwrite(p, 1, n, f);
03360 if (nn != n) {
03361 sqlite3_result_error(ctx, "write error", -1);
03362 } else {
03363 sqlite3_result_int(ctx, nn);
03364 }
03365 } else {
03366 sqlite3_result_error(ctx, "cannot open file", -1);
03367 }
03368 } else {
03369 sqlite3_result_error(ctx, "no filename given", -1);
03370 }
03371 } else {
03372 sqlite3_result_null(ctx);
03373 }
03374 }
03375
03383 static void
03384 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
03385 dbtrace(void *arg, const char *msg, sqlite_uint64 et)
03386 #else
03387 dbtrace(void *arg, const char *msg)
03388 #endif
03389 {
03390 DBC *d = (DBC *) arg;
03391
03392 if (msg && d->trace) {
03393 int len = strlen(msg);
03394 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
03395 unsigned long s, f;
03396 #endif
03397
03398 if (len > 0) {
03399 char *end = "\n";
03400
03401 if (msg[len - 1] != ';') {
03402 end = ";\n";
03403 }
03404 fprintf(d->trace, "%s%s", msg, end);
03405 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
03406 s = et / 1000000000LL;
03407 f = et % 1000000000LL;
03408 fprintf(d->trace, "-- took %lu.%09lu seconds\n", s, f);
03409 #endif
03410 fflush(d->trace);
03411 }
03412 }
03413 }
03414
03422 static void
03423 dbtraceapi(DBC *d, char *fn, const char *sql)
03424 {
03425 if (fn && d->trace) {
03426 if (sql) {
03427 fprintf(d->trace, "-- %s: %s\n", fn, sql);
03428 } else {
03429 fprintf(d->trace, "-- %s\n", fn);
03430 }
03431 fflush(d->trace);
03432 }
03433 }
03434
03442 static void
03443 dbtracerc(DBC *d, int rc, char *err)
03444 {
03445 if (rc != SQLITE_OK && d->trace) {
03446 fprintf(d->trace, "-- SQLITE ERROR CODE %d", rc);
03447 fprintf(d->trace, err ? ": %s\n" : "\n", err);
03448 fflush(d->trace);
03449 }
03450 }
03451
03466 static SQLRETURN
03467 dbopen(DBC *d, char *name, int isu, char *dsn, char *sflag,
03468 char *spflag, char *ntflag, char *jmode, char *busy)
03469 {
03470 char *endp = NULL;
03471 int rc, tmp, busyto = 100000;
03472 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
03473 int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
03474 char *uname = name;
03475 const char *vfs_name = NULL;
03476 #endif
03477
03478 if (d->sqlite) {
03479 if (d->trace) {
03480 fprintf(d->trace, "-- sqlite3_close (deferred): '%s'\n",
03481 d->dbname);
03482 fflush(d->trace);
03483 }
03484 sqlite3_close(d->sqlite);
03485 d->sqlite = NULL;
03486 }
03487 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
03488 if (d->nocreat) {
03489 flags &= ~ SQLITE_OPEN_CREATE;
03490 }
03491 #if defined(_WIN32) || defined(_WIN64)
03492 if (!isu) {
03493 uname = wmb_to_utf(name, -1);
03494 if (!uname) {
03495 rc = SQLITE_NOMEM;
03496 setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
03497 return SQL_ERROR;
03498 }
03499 }
03500 #endif
03501 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
03502 vfs_name = nvfs_makevfs(uname);
03503 #endif
03504 #ifdef SQLITE_OPEN_URI
03505 flags |= SQLITE_OPEN_URI;
03506 #endif
03507 rc = sqlite3_open_v2(uname, &d->sqlite, flags, vfs_name);
03508 #if defined(WINTERFACE) || defined(_WIN32) || defined(_WIN64)
03509 if (uname != name) {
03510 uc_free(uname);
03511 }
03512 #endif
03513 #else
03514 #if defined(_WIN32) || defined(_WIN64)
03515 if (d->nocreat) {
03516 char *cname = NULL;
03517
03518 if (isu) {
03519 cname = utf_to_wmb(name, -1);
03520 }
03521 if (GetFileAttributesA(cname ? cname : name) ==
03522 INVALID_FILE_ATTRIBUTES) {
03523 uc_free(cname);
03524 rc = SQLITE_CANTOPEN;
03525 setstatd(d, rc, "cannot open database",
03526 (*d->ov3) ? "HY000" : "S1000");
03527 return SQL_ERROR;
03528 }
03529 uc_free(cname);
03530 }
03531 #else
03532 if (d->nocreat && access(name, 004) < 0) {
03533 rc = SQLITE_CANTOPEN;
03534 setstatd(d, rc, "cannot open database", (*d->ov3) ? "HY000" : "S1000");
03535 return SQL_ERROR;
03536 }
03537 #endif
03538 #if defined(_WIN32) || defined(_WIN64)
03539 if (!isu) {
03540 WCHAR *wname = wmb_to_uc(name, -1);
03541
03542 if (!wname) {
03543 rc = SQLITE_NOMEM;
03544 setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
03545 return SQL_ERROR;
03546 }
03547 rc = sqlite3_open16(wname, &d->sqlite);
03548 uc_free(wname);
03549 } else
03550 #endif
03551 rc = sqlite3_open(name, &d->sqlite);
03552 #endif
03553 if (rc != SQLITE_OK) {
03554 connfail:
03555 setstatd(d, rc, "connect failed", (*d->ov3) ? "HY000" : "S1000");
03556 if (d->sqlite) {
03557 sqlite3_close(d->sqlite);
03558 d->sqlite = NULL;
03559 }
03560 return SQL_ERROR;
03561 }
03562 #if defined(SQLITE_DYNLOAD) || defined(SQLITE_HAS_CODEC)
03563 if (d->pwd) {
03564 sqlite3_key(d->sqlite, d->pwd, d->pwdLen);
03565 }
03566 #endif
03567 d->pwd = NULL;
03568 d->pwdLen = 0;
03569 if (d->trace) {
03570 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
03571 sqlite3_profile(d->sqlite, dbtrace, d);
03572 #else
03573 sqlite3_trace(d->sqlite, dbtrace, d);
03574 #endif
03575 }
03576 d->step_enable = getbool(sflag);
03577 d->trans_disable = getbool(ntflag);
03578 d->curtype = d->step_enable ?
03579 SQL_CURSOR_FORWARD_ONLY : SQL_CURSOR_STATIC;
03580 tmp = strtol(busy, &endp, 0);
03581 if (endp && *endp == '\0' && endp != busy) {
03582 busyto = tmp;
03583 }
03584 if (busyto < 1 || busyto > 1000000) {
03585 busyto = 1000000;
03586 }
03587 d->timeout = busyto;
03588 if ((rc = setsqliteopts(d->sqlite, d)) != SQLITE_OK) {
03589 if (d->trace) {
03590 fprintf(d->trace, "-- sqlite3_close: '%s'\n",
03591 d->dbname);
03592 fflush(d->trace);
03593 }
03594 sqlite3_close(d->sqlite);
03595 d->sqlite = NULL;
03596 goto connfail;
03597 }
03598 if (!spflag || spflag[0] == '\0') {
03599 spflag = "NORMAL";
03600 }
03601 if (spflag[0] != '\0') {
03602 char syncp[128];
03603
03604 sprintf(syncp, "PRAGMA synchronous = %8.8s;", spflag);
03605 sqlite3_exec(d->sqlite, syncp, NULL, NULL, NULL);
03606 }
03607 if (jmode[0] != '\0') {
03608 char jourp[128];
03609
03610 sprintf(jourp, "PRAGMA journal_mode = %16.16s;", jmode);
03611 sqlite3_exec(d->sqlite, jourp, NULL, NULL, NULL);
03612 }
03613 freep(&d->dbname);
03614 d->dbname = xstrdup(name);
03615 freep(&d->dsn);
03616 d->dsn = xstrdup(dsn);
03617 if (d->trace) {
03618 fprintf(d->trace, "-- sqlite3_open: '%s'\n", d->dbname);
03619 fflush(d->trace);
03620 }
03621 #if defined(_WIN32) || defined(_WIN64)
03622 {
03623 char pname[MAX_PATH];
03624 HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
03625 FALSE, GetCurrentProcessId());
03626
03627 pname[0] = '\0';
03628 if (h) {
03629 HMODULE m = NULL, l = LoadLibrary("psapi.dll");
03630 DWORD need;
03631 typedef BOOL (WINAPI *epmfunc)(HANDLE, HMODULE *, DWORD, LPDWORD);
03632 typedef BOOL (WINAPI *gmbfunc)(HANDLE, HMODULE, LPSTR, DWORD);
03633 epmfunc epm;
03634 gmbfunc gmb;
03635
03636 if (l) {
03637 epm = (epmfunc) GetProcAddress(l, "EnumProcessModules");
03638 gmb = (gmbfunc) GetProcAddress(l, "GetModuleBaseNameA");
03639 if (epm && gmb && epm(h, &m, sizeof (m), &need)) {
03640 gmb(h, m, pname, sizeof (pname));
03641 }
03642 FreeLibrary(l);
03643 }
03644 CloseHandle(h);
03645 }
03646 d->xcelqrx = strncasecmp(pname, "EXCEL", 5) == 0 ||
03647 strncasecmp(pname, "MSQRY", 5) == 0;
03648 if (d->trace && d->xcelqrx) {
03649 fprintf(d->trace, "-- enabled EXCEL quirks\n");
03650 fflush(d->trace);
03651 }
03652 }
03653 #endif
03654 sqlite3_create_function(d->sqlite, "blob_import", 1, SQLITE_UTF8,
03655 d, blob_import, 0, 0);
03656 sqlite3_create_function(d->sqlite, "blob_export", 2, SQLITE_UTF8,
03657 d, blob_export, 0, 0);
03658 return SQL_SUCCESS;
03659 }
03660
03667 static void
03668 dbloadext(DBC *d, char *exts)
03669 {
03670 #if defined(HAVE_SQLITE3LOADEXTENSION) && (HAVE_SQLITE3LOADEXTENSION)
03671 char *p;
03672 char path[SQL_MAX_MESSAGE_LENGTH];
03673 int plen = 0;
03674
03675 if (!d->sqlite) {
03676 return;
03677 }
03678 sqlite3_enable_load_extension(d->sqlite, 1);
03679 #if defined(_WIN32) || defined(_WIN64)
03680 GetModuleFileName(hModule, path, sizeof (path));
03681 p = strrchr(path, '\\');
03682 plen = p ? ((p + 1) - path) : 0;
03683 #endif
03684 do {
03685 p = strchr(exts, ',');
03686 if (p) {
03687 strncpy(path + plen, exts, p - exts);
03688 path[plen + (p - exts)] = '\0';
03689 } else {
03690 strcpy(path + plen, exts);
03691 }
03692 if (exts[0]) {
03693 char *errmsg = NULL;
03694 int rc;
03695 #if defined(_WIN32) || defined(_WIN64)
03696 char *q;
03697
03698 q = path + plen;
03699 if (!(q[0] &&
03700 ((q[1] == ':' && (q[2] == '\\' || q[2] == '/')) ||
03701 q[0] == '\\' || q[0] == '/' || q[0] == '.'))) {
03702 q = path;
03703 }
03704 rc = sqlite3_load_extension(d->sqlite, q, 0, &errmsg);
03705 #else
03706 rc = sqlite3_load_extension(d->sqlite, path, 0, &errmsg);
03707 #endif
03708 if (rc != SQLITE_OK) {
03709 #if defined(_WIN32) || defined(_WIN64)
03710 char buf[512], msg[512];
03711
03712 LoadString(hModule, IDS_EXTERR, buf, sizeof (buf));
03713 wsprintf(msg, buf, q, errmsg ?
03714 errmsg : "no error info available");
03715 LoadString(hModule, IDS_EXTTITLE, buf, sizeof (buf));
03716 MessageBox(NULL, msg, buf,
03717 MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
03718 MB_SETFOREGROUND);
03719 #else
03720 fprintf(stderr, "extension '%s' did not load%s%s\n",
03721 path, errmsg ? ": " : "", errmsg ? errmsg : "");
03722 #endif
03723 }
03724 }
03725 if (p) {
03726 exts = p + 1;
03727 }
03728 } while (p);
03729 #endif
03730 }
03731
03741 static char *
03742 s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
03743 {
03744 char *typename = (char *) sqlite3_column_decltype(s3stmt, col);
03745 char guess[64];
03746
03747 guess[0] = '\0';
03748 if (!typename) {
03749 int coltype = sqlite3_column_type(s3stmt, col);
03750
03751 if (guessed_types) {
03752 guessed_types[0]++;
03753 }
03754 if (d->trace) {
03755 sprintf(guess, " (guessed from %d)", coltype);
03756 }
03757 switch (coltype) {
03758 case SQLITE_INTEGER: typename = "integer"; break;
03759 case SQLITE_FLOAT: typename = "double"; break;
03760 default:
03761 case SQLITE_TEXT: typename = "varchar"; break;
03762 case SQLITE_BLOB: typename = "blob"; break;
03763 #if 0
03764 case SQLITE_NULL: typename = "null"; break;
03765 #endif
03766 }
03767 }
03768 if (d->trace) {
03769 fprintf(d->trace, "-- column %d type%s: '%s'\n", col + 1,
03770 guess, typename);
03771 fflush(d->trace);
03772 }
03773 return typename;
03774 }
03775
03776 #if defined(HAVE_SQLITE3TABLECOLUMNMETADATA) && (HAVE_SQLITE3TABLECOLUMNMETADATA)
03777
03786 static void
03787 s3stmt_addmeta(sqlite3_stmt *s3stmt, int col, DBC *d, COL *ci)
03788 {
03789 int nn = 0, pk = 0, ai = 0;
03790 const char *dn, *tn, *cn, *dummy1, *dummy2;
03791
03792 dn = sqlite3_column_database_name(s3stmt, col);
03793 tn = sqlite3_column_table_name(s3stmt, col);
03794 cn = sqlite3_column_origin_name(s3stmt, col);
03795 sqlite3_table_column_metadata(d->sqlite, dn, tn, cn,
03796 &dummy1, &dummy2,
03797 &nn, &pk, &ai);
03798 ci->autoinc = ai ? SQL_TRUE: SQL_FALSE;
03799 ci->notnull = nn ? SQL_NO_NULLS : SQL_NULLABLE;
03800 if (d->trace) {
03801 fprintf(d->trace, "-- column %d %s\n",
03802 col + 1, nn ? "notnull" : "nullable");
03803 if (ai) {
03804 fprintf(d->trace, "-- column %d autoincrement\n", col + 1);
03805 }
03806 fflush(d->trace);
03807 }
03808 }
03809
03810 #endif
03811
03818 static int
03819 s3stmt_step(STMT *s)
03820 {
03821 DBC *d = (DBC *) s->dbc;
03822 char **rowd = NULL;
03823 const char *errp = NULL;
03824 int i, ncols, rc;
03825
03826 if (s != d->cur_s3stmt || !s->s3stmt) {
03827 setstat(s, -1, "stale statement", (*s->ov3) ? "HY000" : "S1000");
03828 return SQL_ERROR;
03829 }
03830 rc = sqlite3_step(s->s3stmt);
03831 if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
03832 ++s->s3stmt_rownum;
03833 ncols = sqlite3_column_count(s->s3stmt);
03834 if (d->s3stmt_needmeta && s->s3stmt_rownum == 0 && ncols > 0) {
03835 PTRDIFF_T size;
03836 char *p;
03837 COL *dyncols;
03838 const char *colname, *typename;
03839 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
03840 char *tblname;
03841 #endif
03842
03843 for (i = size = 0; i < ncols; i++) {
03844 colname = sqlite3_column_name(s->s3stmt, i);
03845 size += 3 + 3 * strlen(colname);
03846 }
03847 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
03848 tblname = (char *) size;
03849 for (i = 0; i < ncols; i++) {
03850 p = (char *) sqlite3_column_table_name(s->s3stmt, i);
03851 size += 2 + (p ? strlen(p) : 0);
03852 }
03853 #endif
03854 dyncols = xmalloc(ncols * sizeof (COL) + size);
03855 if (!dyncols) {
03856 freedyncols(s);
03857 s->ncols = 0;
03858 dbtraceapi(d, "sqlite3_finalize", 0);
03859 sqlite3_finalize(s->s3stmt);
03860 s->s3stmt = NULL;
03861 d->cur_s3stmt = NULL;
03862 return nomem(s);
03863 }
03864 p = (char *) (dyncols + ncols);
03865 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
03866 tblname = p + (PTRDIFF_T) tblname;
03867 #endif
03868 for (i = 0; i < ncols; i++) {
03869 char *q;
03870
03871 colname = sqlite3_column_name(s->s3stmt, i);
03872 if (d->trace) {
03873 fprintf(d->trace, "-- column %d name: '%s'\n",
03874 i + 1, colname);
03875 fflush(d->trace);
03876 }
03877 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
03878 q = (char *) sqlite3_column_table_name(s->s3stmt, i);
03879 strcpy(tblname, q ? q : "");
03880 if (d->trace) {
03881 fprintf(d->trace, "-- table %d name: '%s'\n",
03882 i + 1, tblname);
03883 fflush(d->trace);
03884 }
03885 dyncols[i].table = tblname;
03886 tblname += strlen(tblname) + 1;
03887 #endif
03888 typename = s3stmt_coltype(s->s3stmt, i, d, 0);
03889 dyncols[i].db = ((DBC *) (s->dbc))->dbname;
03890 strcpy(p, colname);
03891 dyncols[i].label = p;
03892 p += strlen(p) + 1;
03893 q = strchr(colname, '.');
03894 if (q) {
03895 char *q2 = strchr(q + 1, '.');
03896
03897
03898 if (q2) {
03899 q = q2;
03900 }
03901 }
03902 if (q) {
03903 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
03904 dyncols[i].table = p;
03905 #endif
03906 strncpy(p, colname, q - colname);
03907 p[q - colname] = '\0';
03908 p += strlen(p) + 1;
03909 strcpy(p, q + 1);
03910 dyncols[i].column = p;
03911 p += strlen(p) + 1;
03912 } else {
03913 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
03914 dyncols[i].table = "";
03915 #endif
03916 strcpy(p, colname);
03917 dyncols[i].column = p;
03918 p += strlen(p) + 1;
03919 }
03920 if (s->longnames) {
03921 dyncols[i].column = dyncols[i].label;
03922 }
03923 #ifdef SQL_LONGVARCHAR
03924 dyncols[i].type = SQL_LONGVARCHAR;
03925 dyncols[i].size = 65535;
03926 #else
03927 dyncols[i].type = SQL_VARCHAR;
03928 dyncols[i].size = 255;
03929 #endif
03930 dyncols[i].index = i;
03931 dyncols[i].scale = 0;
03932 dyncols[i].prec = 0;
03933 dyncols[i].nosign = 1;
03934 #if defined(HAVE_SQLITE3TABLECOLUMNMETADATA) && (HAVE_SQLITE3TABLECOLUMNMETADATA)
03935 s3stmt_addmeta(s->s3stmt, i, d, &dyncols[i]);
03936 #else
03937 dyncols[i].autoinc = SQL_FALSE;
03938 dyncols[i].notnull = SQL_NULLABLE;
03939 #endif
03940 dyncols[i].typename = xstrdup(typename);
03941 }
03942 freedyncols(s);
03943 s->ncols = s->dcols = ncols;
03944 s->dyncols = s->cols = dyncols;
03945 fixupdyncols(s, d);
03946 mkbindcols(s, s->ncols);
03947 d->s3stmt_needmeta = 0;
03948 }
03949 if (ncols <= 0) {
03950 goto killstmt;
03951 }
03952 if (rc == SQLITE_DONE) {
03953 freeresult(s, 0);
03954 s->nrows = 0;
03955 dbtraceapi(d, "sqlite3_finalize", 0);
03956 sqlite3_finalize(s->s3stmt);
03957 s->s3stmt = NULL;
03958 d->cur_s3stmt = NULL;
03959 return SQL_SUCCESS;
03960 }
03961 rowd = xmalloc((1 + 2 * ncols) * sizeof (char *));
03962 if (rowd) {
03963 const unsigned char *value;
03964
03965 rowd[0] = (char *) ((PTRDIFF_T) (ncols * 2));
03966 ++rowd;
03967 for (i = 0; i < ncols; i++) {
03968 int coltype = sqlite3_column_type(s->s3stmt, i);
03969
03970 rowd[i] = rowd[i + ncols] = NULL;
03971 if (coltype == SQLITE_BLOB) {
03972 int k, nbytes = sqlite3_column_bytes(s->s3stmt, i);
03973 char *qp;
03974 unsigned const char *bp;
03975
03976 bp = sqlite3_column_blob(s->s3stmt, i);
03977 qp = xmalloc(nbytes * 2 + 4);
03978 if (qp) {
03979 rowd[i + ncols] = qp;
03980 *qp++ = 'X';
03981 *qp++ = '\'';
03982 for (k = 0; k < nbytes; k++) {
03983 *qp++ = xdigits[(bp[k] >> 4)];
03984 *qp++ = xdigits[(bp[k] & 0xF)];
03985 }
03986 *qp++ = '\'';
03987 *qp = '\0';
03988 }
03989 } else if (coltype != SQLITE_NULL) {
03990 value = sqlite3_column_text(s->s3stmt, i);
03991 rowd[i + ncols] = xstrdup((char *) value);
03992 }
03993 }
03994 for (i = 0; i < ncols; i++) {
03995 int coltype = sqlite3_column_type(s->s3stmt, i);
03996
03997 value = NULL;
03998 if (coltype == SQLITE_BLOB) {
03999 value = sqlite3_column_blob(s->s3stmt, i);
04000 } else if (coltype != SQLITE_NULL) {
04001 value = sqlite3_column_text(s->s3stmt, i);
04002 }
04003 if (value && !rowd[i + ncols]) {
04004 freerows(rowd);
04005 rowd = 0;
04006 break;
04007 }
04008 }
04009 }
04010 if (rowd) {
04011 freeresult(s, 0);
04012 s->nrows = 1;
04013 s->rows = rowd;
04014 s->rowfree = freerows;
04015 if (rc == SQLITE_DONE) {
04016 dbtraceapi(d, "sqlite3_finalize", 0);
04017 sqlite3_finalize(s->s3stmt);
04018 s->s3stmt = NULL;
04019 d->cur_s3stmt = NULL;
04020 }
04021 return SQL_SUCCESS;
04022 }
04023 }
04024 killstmt:
04025 dbtraceapi(d, "sqlite3_reset", 0);
04026 rc = sqlite3_reset(s->s3stmt);
04027 s->s3stmt_noreset = 1;
04028 errp = sqlite3_errmsg(d->sqlite);
04029 if (d->cur_s3stmt == s) {
04030 d->cur_s3stmt = NULL;
04031 }
04032 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
04033 errp ? errp : "unknown error", rc);
04034 return SQL_ERROR;
04035 }
04036
04042 static void
04043 s3stmt_end(STMT *s)
04044 {
04045 DBC *d;
04046
04047 if (!s || !s->s3stmt) {
04048 return;
04049 }
04050 d = (DBC *) s->dbc;
04051 if (d) {
04052 d->busyint = 0;
04053 }
04054 if (!s->s3stmt_noreset) {
04055 dbtraceapi(d, "sqlite3_reset", 0);
04056 sqlite3_reset(s->s3stmt);
04057 s->s3stmt_noreset = 1;
04058 s->s3stmt_rownum = -1;
04059 }
04060 if (d->cur_s3stmt == s) {
04061 d->cur_s3stmt = NULL;
04062 }
04063 }
04064
04070 static void
04071 s3stmt_end_if(STMT *s)
04072 {
04073 DBC *d = (DBC *) s->dbc;
04074
04075 if (d) {
04076 d->busyint = 0;
04077 }
04078 if (d && d->cur_s3stmt == s) {
04079 s3stmt_end(s);
04080 }
04081 }
04082
04088 static void
04089 s3stmt_drop(STMT *s)
04090 {
04091 if (s->s3stmt) {
04092 DBC *d = (DBC *) s->dbc;
04093
04094 if (d) {
04095 dbtraceapi(d, "sqlite3_finalize", 0);
04096 }
04097 sqlite3_finalize(s->s3stmt);
04098 s->s3stmt = NULL;
04099 s->s3stmt_rownum = 0;
04100 }
04101 }
04102
04109 static SQLRETURN
04110 s3stmt_start(STMT *s)
04111 {
04112 DBC *d = (DBC *) s->dbc;
04113 const char *endp;
04114 sqlite3_stmt *s3stmt = NULL;
04115 int rc, nretry = 0;
04116
04117 d->s3stmt_needmeta = 0;
04118 if (!s->s3stmt) {
04119 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
04120 dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
04121 #else
04122 dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
04123 #endif
04124 do {
04125 s3stmt = NULL;
04126 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
04127 rc = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
04128 &s3stmt, &endp);
04129 #else
04130 rc = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
04131 &s3stmt, &endp);
04132 #endif
04133 if (rc != SQLITE_OK) {
04134 if (s3stmt) {
04135 sqlite3_finalize(s3stmt);
04136 s3stmt = NULL;
04137 }
04138 }
04139 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
04140 dbtracerc(d, rc, NULL);
04141 if (rc != SQLITE_OK) {
04142 if (s3stmt) {
04143 dbtraceapi(d, "sqlite3_finalize", NULL);
04144 sqlite3_finalize(s3stmt);
04145 }
04146 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
04147 sqlite3_errmsg(d->sqlite), rc);
04148 return SQL_ERROR;
04149 }
04150 if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
04151 dbtraceapi(d, "sqlite3_finalize", 0);
04152 sqlite3_finalize(s3stmt);
04153 setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
04154 (*s->ov3) ? "HY000" : "S1000");
04155 return SQL_ERROR;
04156 }
04157 s->s3stmt = s3stmt;
04158 s->s3stmt_noreset = 1;
04159 d->s3stmt_needmeta = 1;
04160 }
04161 d->cur_s3stmt = s;
04162 s->s3stmt_rownum = -1;
04163 s3bind(d, s->s3stmt, s->nparams, s->bindparms);
04164 return SQL_SUCCESS;
04165 }
04166
04171 SQLRETURN SQL_API
04172 SQLBulkOperations(SQLHSTMT stmt, SQLSMALLINT oper)
04173 {
04174 SQLRETURN ret;
04175
04176 HSTMT_LOCK(stmt);
04177 ret = drvunimplstmt(stmt);
04178 HSTMT_UNLOCK(stmt);
04179 return ret;
04180 }
04181
04182 #ifndef WINTERFACE
04183
04187 SQLRETURN SQL_API
04188 SQLDataSources(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *srvname,
04189 SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
04190 SQLCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
04191 {
04192 if (env == SQL_NULL_HENV) {
04193 return SQL_INVALID_HANDLE;
04194 }
04195 return SQL_ERROR;
04196 }
04197 #endif
04198
04199 #ifdef WINTERFACE
04200
04204 SQLRETURN SQL_API
04205 SQLDataSourcesW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *srvname,
04206 SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
04207 SQLWCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
04208 {
04209 if (env == SQL_NULL_HENV) {
04210 return SQL_INVALID_HANDLE;
04211 }
04212 return SQL_ERROR;
04213 }
04214 #endif
04215
04216 #ifndef WINTERFACE
04217
04221 SQLRETURN SQL_API
04222 SQLDrivers(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *drvdesc,
04223 SQLSMALLINT descmax, SQLSMALLINT *desclenp,
04224 SQLCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
04225 {
04226 if (env == SQL_NULL_HENV) {
04227 return SQL_INVALID_HANDLE;
04228 }
04229 return SQL_ERROR;
04230 }
04231 #endif
04232
04233 #ifdef WINTERFACE
04234
04238 SQLRETURN SQL_API
04239 SQLDriversW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *drvdesc,
04240 SQLSMALLINT descmax, SQLSMALLINT *desclenp,
04241 SQLWCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
04242 {
04243 if (env == SQL_NULL_HENV) {
04244 return SQL_INVALID_HANDLE;
04245 }
04246 return SQL_ERROR;
04247 }
04248 #endif
04249
04250 #ifndef WINTERFACE
04251
04255 SQLRETURN SQL_API
04256 SQLBrowseConnect(SQLHDBC dbc, SQLCHAR *connin, SQLSMALLINT conninLen,
04257 SQLCHAR *connout, SQLSMALLINT connoutMax,
04258 SQLSMALLINT *connoutLen)
04259 {
04260 SQLRETURN ret;
04261
04262 HDBC_LOCK(dbc);
04263 ret = drvunimpldbc(dbc);
04264 HDBC_UNLOCK(dbc);
04265 return ret;
04266 }
04267 #endif
04268
04269 #ifdef WINTERFACE
04270
04274 SQLRETURN SQL_API
04275 SQLBrowseConnectW(SQLHDBC dbc, SQLWCHAR *connin, SQLSMALLINT conninLen,
04276 SQLWCHAR *connout, SQLSMALLINT connoutMax,
04277 SQLSMALLINT *connoutLen)
04278 {
04279 SQLRETURN ret;
04280
04281 HDBC_LOCK(dbc);
04282 ret = drvunimpldbc(dbc);
04283 HDBC_UNLOCK(dbc);
04284 return ret;
04285 }
04286 #endif
04287
04296 static SQLRETURN
04297 drvputdata(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
04298 {
04299 STMT *s;
04300 int i, dlen, done = 0;
04301 BINDPARM *p;
04302
04303 if (stmt == SQL_NULL_HSTMT) {
04304 return SQL_INVALID_HANDLE;
04305 }
04306 s = (STMT *) stmt;
04307 if (!s->query || s->nparams <= 0) {
04308 seqerr:
04309 setstat(s, -1, "sequence error", "HY010");
04310 return SQL_ERROR;
04311 }
04312 for (i = 0; i < s->nparams; i++) {
04313 p = &s->bindparms[i];
04314 if (p->need > 0) {
04315 int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
04316
04317 if (len == SQL_NULL_DATA) {
04318 freep(&p->parbuf);
04319 p->param = NULL;
04320 p->len = SQL_NULL_DATA;
04321 p->need = -1;
04322 } else if (type != SQL_C_CHAR
04323 #ifdef WCHARSUPPORT
04324 && type != SQL_C_WCHAR
04325 #endif
04326 && type != SQL_C_BINARY) {
04327 int size = 0;
04328
04329 switch (type) {
04330 case SQL_C_TINYINT:
04331 case SQL_C_UTINYINT:
04332 case SQL_C_STINYINT:
04333 #ifdef SQL_BIT
04334 case SQL_C_BIT:
04335 #endif
04336 size = sizeof (char);
04337 break;
04338 case SQL_C_SHORT:
04339 case SQL_C_USHORT:
04340 case SQL_C_SSHORT:
04341 size = sizeof (short);
04342 break;
04343 case SQL_C_LONG:
04344 case SQL_C_ULONG:
04345 case SQL_C_SLONG:
04346 size = sizeof (long);
04347 break;
04348 #ifdef SQL_BIGINT
04349 case SQL_C_UBIGINT:
04350 case SQL_C_SBIGINT:
04351 size = sizeof (SQLBIGINT);
04352 break;
04353 #endif
04354 case SQL_C_FLOAT:
04355 size = sizeof (float);
04356 break;
04357 case SQL_C_DOUBLE:
04358 size = sizeof (double);
04359 break;
04360 #ifdef SQL_C_TYPE_DATE
04361 case SQL_C_TYPE_DATE:
04362 #endif
04363 case SQL_C_DATE:
04364 size = sizeof (DATE_STRUCT);
04365 break;
04366 #ifdef SQL_C_TYPE_DATE
04367 case SQL_C_TYPE_TIME:
04368 #endif
04369 case SQL_C_TIME:
04370 size = sizeof (TIME_STRUCT);
04371 break;
04372 #ifdef SQL_C_TYPE_DATE
04373 case SQL_C_TYPE_TIMESTAMP:
04374 #endif
04375 case SQL_C_TIMESTAMP:
04376 size = sizeof (TIMESTAMP_STRUCT);
04377 break;
04378 }
04379 freep(&p->parbuf);
04380 p->parbuf = xmalloc(size);
04381 if (!p->parbuf) {
04382 return nomem(s);
04383 }
04384 p->param = p->parbuf;
04385 memcpy(p->param, data, size);
04386 p->len = size;
04387 p->need = -1;
04388 } else if (len == SQL_NTS && (
04389 type == SQL_C_CHAR
04390 #ifdef WCHARSUPPORT
04391 || type == SQL_C_WCHAR
04392 #endif
04393 )) {
04394 char *dp = data;
04395
04396 #ifdef WCHARSUPPORT
04397 if (type == SQL_C_WCHAR) {
04398 dp = uc_to_utf(data, len);
04399 if (!dp) {
04400 return nomem(s);
04401 }
04402 }
04403 #endif
04404 #if defined(_WIN32) || defined(_WIN64)
04405 if (*s->oemcp) {
04406 dp = wmb_to_utf(data, strlen (data));
04407 if (!dp) {
04408 return nomem(s);
04409 }
04410 }
04411 #endif
04412 dlen = strlen(dp);
04413 freep(&p->parbuf);
04414 p->parbuf = xmalloc(dlen + 1);
04415 if (!p->parbuf) {
04416 if (dp != data) {
04417 uc_free(dp);
04418 }
04419 return nomem(s);
04420 }
04421 p->param = p->parbuf;
04422 strcpy(p->param, dp);
04423 if (dp != data) {
04424 uc_free(dp);
04425 }
04426 p->len = dlen;
04427 p->need = -1;
04428 } else if (len < 0) {
04429 setstat(s, -1, "invalid length", "HY090");
04430 return SQL_ERROR;
04431 } else {
04432 dlen = min(p->len - p->offs, len);
04433 if (!p->param) {
04434 setstat(s, -1, "no memory for parameter", "HY013");
04435 return SQL_ERROR;
04436 }
04437 memcpy((char *) p->param + p->offs, data, dlen);
04438 p->offs += dlen;
04439 if (p->offs >= p->len) {
04440 #ifdef WCHARSUPPORT
04441 if (type == SQL_C_WCHAR) {
04442 char *dp = uc_to_utf(p->param, p->len);
04443 char *np;
04444 int nlen;
04445
04446 if (!dp) {
04447 return nomem(s);
04448 }
04449 nlen = strlen(dp);
04450 np = xmalloc(nlen + 1);
04451 if (!np) {
04452 uc_free(dp);
04453 return nomem(s);
04454 }
04455 strcpy(np, dp);
04456 uc_free(dp);
04457 if (p->param == p->parbuf) {
04458 freep(&p->parbuf);
04459 }
04460 p->parbuf = p->param = np;
04461 p->len = nlen;
04462 } else {
04463 *((char *) p->param + p->len) = '\0';
04464 }
04465 p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR)
04466 ? -1 : 0;
04467 #else
04468 *((char *) p->param + p->len) = '\0';
04469 p->need = (type == SQL_C_CHAR) ? -1 : 0;
04470 #endif
04471 #if defined(_WIN32) || defined(_WIN64)
04472 if (type == SQL_C_CHAR && *s->oemcp) {
04473 char *dp = wmb_to_utf(p->param, p->len);
04474
04475 if (!dp) {
04476 return nomem(s);
04477 }
04478 if (p->param == p->parbuf) {
04479 freep(&p->parbuf);
04480 }
04481 p->parbuf = p->param = dp;
04482 p->len = strlen(dp);
04483 }
04484 if (p->type == SQL_C_WCHAR &&
04485 (p->stype == SQL_VARCHAR ||
04486 p->stype == SQL_LONGVARCHAR) &&
04487 p->len == p->coldef * sizeof (SQLWCHAR)) {
04488
04489 p->len = p->coldef;
04490 }
04491 #endif
04492 }
04493 }
04494 done = 1;
04495 break;
04496 }
04497 }
04498 if (!done) {
04499 goto seqerr;
04500 }
04501 return SQL_SUCCESS;
04502 }
04503
04512 SQLRETURN SQL_API
04513 SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
04514 {
04515 SQLRETURN ret;
04516
04517 HSTMT_LOCK(stmt);
04518 ret = drvputdata(stmt, data, len);
04519 HSTMT_UNLOCK(stmt);
04520 return ret;
04521 }
04522
04528 static SQLRETURN
04529 freeparams(STMT *s)
04530 {
04531 if (s->bindparms) {
04532 int n;
04533
04534 for (n = 0; n < s->nbindparms; n++) {
04535 freep(&s->bindparms[n].parbuf);
04536 memset(&s->bindparms[n], 0, sizeof (BINDPARM));
04537 }
04538 }
04539 return SQL_SUCCESS;
04540 }
04541
04553 static SQLRETURN
04554 setupparam(STMT *s, char *sql, int pnum)
04555 {
04556 int type, len = 0, needalloc = 0;
04557 BINDPARM *p;
04558
04559 if (!s->bindparms || pnum < 0 || pnum >= s->nbindparms) {
04560 goto error;
04561 }
04562 p = &s->bindparms[pnum];
04563 type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
04564 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
04565
04566 if (type == SQL_C_WCHAR && p->type == SQL_C_DEFAULT) {
04567 type = SQL_C_CHAR;
04568 }
04569 #endif
04570 if (p->need > 0) {
04571 return setupparbuf(s, p);
04572 }
04573 p->strbuf[0] = '\0';
04574 if (!p->param || (p->lenp && *p->lenp == SQL_NULL_DATA)) {
04575 p->s3type = SQLITE_NULL;
04576 p->s3size = 0;
04577 return SQL_SUCCESS;
04578 }
04579 switch (type) {
04580 case SQL_C_BINARY:
04581 p->s3type = SQLITE_BLOB;
04582 p->s3size = p->len;
04583 p->s3val = p->param;
04584 if (p->need < 0) {
04585 break;
04586 }
04587 if (!p->lenp) {
04588 len = p->len;
04589 } else {
04590 len = *p->lenp;
04591 if (len <= SQL_LEN_DATA_AT_EXEC_OFFSET) {
04592 len = SQL_LEN_DATA_AT_EXEC(len);
04593 }
04594 }
04595 if (len < 0) {
04596 setstat(s, -1, "invalid length", "HY009");
04597 return SQL_ERROR;
04598 }
04599 p->len = len;
04600 p->max = p->len;
04601 p->need = -1;
04602 p->s3size = len;
04603 break;
04604 #ifdef WCHARSUPPORT
04605 case SQL_C_WCHAR:
04606 #endif
04607 case SQL_C_CHAR:
04608 p->s3type = SQLITE_TEXT;
04609 p->s3size = -1;
04610 p->s3val = p->param;
04611 if (!p->parbuf && p->lenp) {
04612 #ifdef WCHARSUPPORT
04613 if (type == SQL_C_WCHAR) {
04614 if (*p->lenp == SQL_NTS) {
04615 p->max = uc_strlen(p->param) * sizeof (SQLWCHAR);
04616 } else if (*p->lenp >= 0) {
04617 p->max = *p->lenp;
04618 }
04619 } else
04620 #endif
04621 if (type == SQL_C_CHAR) {
04622 if (*p->lenp == SQL_NTS) {
04623 p->len = p->max = strlen(p->param);
04624 #if defined(_WIN32) || defined(_WIN64)
04625 needalloc = 1;
04626 #endif
04627 } else if (*p->lenp >= 0) {
04628 p->len = p->max = *p->lenp;
04629 needalloc = 1;
04630 }
04631 }
04632 }
04633 if (p->need < 0 && p->parbuf == p->param) {
04634 break;
04635 }
04636 #ifdef WCHARSUPPORT
04637 if (type == SQL_C_WCHAR) {
04638 char *dp = uc_to_utf(p->param, p->max);
04639
04640 if (!dp) {
04641 return nomem(s);
04642 }
04643 if (p->param == p->parbuf) {
04644 freep(&p->parbuf);
04645 }
04646 p->parbuf = p->param = dp;
04647 p->need = -1;
04648 p->len = strlen(p->param);
04649 p->s3val = p->param;
04650 p->s3size = p->len;
04651 } else
04652 #endif
04653 if (type == SQL_C_CHAR) {
04654 p->s3val = p->param;
04655 if (needalloc) {
04656 char *dp;
04657
04658 #if defined(_WIN32) || defined(_WIN64)
04659 if (*s->oemcp) {
04660 dp = wmb_to_utf(p->param, p->len);
04661 } else {
04662 dp = xmalloc(p->len + 1);
04663 }
04664 #else
04665 dp = xmalloc(p->len + 1);
04666 #endif
04667 if (!dp) {
04668 return nomem(s);
04669 }
04670 #if defined(_WIN32) || defined(_WIN64)
04671 if (*s->oemcp) {
04672 p->len = strlen(dp);
04673 } else {
04674 memcpy(dp, p->param, p->len);
04675 dp[p->len] = '\0';
04676 }
04677 #else
04678 memcpy(dp, p->param, p->len);
04679 dp[p->len] = '\0';
04680 #endif
04681 if (p->param == p->parbuf) {
04682 freep(&p->parbuf);
04683 }
04684 p->parbuf = p->param = dp;
04685 p->need = -1;
04686 p->s3val = p->param;
04687 p->s3size = p->len;
04688 }
04689 }
04690 break;
04691 case SQL_C_UTINYINT:
04692 p->s3type = SQLITE_INTEGER;
04693 p->s3size = sizeof (int);
04694 p->s3ival = *((SQLCHAR *) p->param);
04695 break;
04696 case SQL_C_TINYINT:
04697 case SQL_C_STINYINT:
04698 p->s3type = SQLITE_INTEGER;
04699 p->s3size = sizeof (int);
04700 p->s3ival = *((SQLCHAR *) p->param);
04701 break;
04702 case SQL_C_USHORT:
04703 p->s3type = SQLITE_INTEGER;
04704 p->s3size = sizeof (int);
04705 p->s3ival = *((SQLUSMALLINT *) p->param);
04706 break;
04707 case SQL_C_SHORT:
04708 case SQL_C_SSHORT:
04709 p->s3type = SQLITE_INTEGER;
04710 p->s3size = sizeof (int);
04711 p->s3ival = *((SQLSMALLINT *) p->param);
04712 break;
04713 case SQL_C_ULONG:
04714 p->s3type = SQLITE_INTEGER;
04715 p->s3size = sizeof (int);
04716 p->s3ival = *((SQLUINTEGER *) p->param);
04717 break;
04718 case SQL_C_LONG:
04719 case SQL_C_SLONG:
04720 p->s3type = SQLITE_INTEGER;
04721 p->s3size = sizeof (int);
04722 p->s3ival = *((SQLINTEGER *) p->param);
04723 break;
04724 #ifdef SQL_BIT
04725 case SQL_C_BIT:
04726 p->s3type = SQLITE_INTEGER;
04727 p->s3size = sizeof (int);
04728 p->s3ival = (*((SQLCHAR *) p->param)) ? 1 : 0;
04729 break;
04730 #endif
04731 #ifdef SQL_BIGINT
04732 case SQL_C_SBIGINT:
04733 p->s3type = SQLITE_INTEGER;
04734 p->s3size = sizeof (sqlite_int64);
04735 p->s3lival = *((sqlite_int64 *) p->param);
04736 break;
04737 case SQL_C_UBIGINT:
04738 p->s3type = SQLITE_INTEGER;
04739 p->s3size = sizeof (sqlite_int64);
04740 p->s3lival = *((sqlite_uint64 *) p->param);
04741 break;
04742 #endif
04743 case SQL_C_FLOAT:
04744 p->s3type = SQLITE_FLOAT;
04745 p->s3size = sizeof (double);
04746 p->s3dval = *((float *) p->param);
04747 break;
04748 case SQL_C_DOUBLE:
04749 p->s3type = SQLITE_FLOAT;
04750 p->s3size = sizeof (double);
04751 p->s3dval = *((double *) p->param);
04752 break;
04753 #ifdef SQL_C_TYPE_DATE
04754 case SQL_C_TYPE_DATE:
04755 #endif
04756 case SQL_C_DATE:
04757 sprintf(p->strbuf, "%04d-%02d-%02d",
04758 ((DATE_STRUCT *) p->param)->year,
04759 ((DATE_STRUCT *) p->param)->month,
04760 ((DATE_STRUCT *) p->param)->day);
04761 p->s3type = SQLITE_TEXT;
04762 p->s3size = -1;
04763 p->s3val = p->strbuf;
04764 break;
04765 #ifdef SQL_C_TYPE_TIME
04766 case SQL_C_TYPE_TIME:
04767 #endif
04768 case SQL_C_TIME:
04769 sprintf(p->strbuf, "%02d:%02d:%02d",
04770 ((TIME_STRUCT *) p->param)->hour,
04771 ((TIME_STRUCT *) p->param)->minute,
04772 ((TIME_STRUCT *) p->param)->second);
04773 p->s3type = SQLITE_TEXT;
04774 p->s3size = -1;
04775 p->s3val = p->strbuf;
04776 break;
04777 #ifdef SQL_C_TYPE_TIMESTAMP
04778 case SQL_C_TYPE_TIMESTAMP:
04779 #endif
04780 case SQL_C_TIMESTAMP:
04781 len = (int) ((TIMESTAMP_STRUCT *) p->param)->fraction;
04782 len /= 1000000;
04783 len = len % 1000;
04784 if (len < 0) {
04785 len = 0;
04786 }
04787 if (p->coldef && p->coldef <= 16) {
04788 sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
04789 ((TIMESTAMP_STRUCT *) p->param)->year,
04790 ((TIMESTAMP_STRUCT *) p->param)->month,
04791 ((TIMESTAMP_STRUCT *) p->param)->day,
04792 ((TIMESTAMP_STRUCT *) p->param)->hour,
04793 ((TIMESTAMP_STRUCT *) p->param)->minute);
04794 } else if (p->coldef && p->coldef <= 19) {
04795 sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
04796 ((TIMESTAMP_STRUCT *) p->param)->year,
04797 ((TIMESTAMP_STRUCT *) p->param)->month,
04798 ((TIMESTAMP_STRUCT *) p->param)->day,
04799 ((TIMESTAMP_STRUCT *) p->param)->hour,
04800 ((TIMESTAMP_STRUCT *) p->param)->minute,
04801 ((TIMESTAMP_STRUCT *) p->param)->second);
04802 } else {
04803 sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
04804 ((TIMESTAMP_STRUCT *) p->param)->year,
04805 ((TIMESTAMP_STRUCT *) p->param)->month,
04806 ((TIMESTAMP_STRUCT *) p->param)->day,
04807 ((TIMESTAMP_STRUCT *) p->param)->hour,
04808 ((TIMESTAMP_STRUCT *) p->param)->minute,
04809 ((TIMESTAMP_STRUCT *) p->param)->second,
04810 len);
04811 }
04812 p->s3type = SQLITE_TEXT;
04813 p->s3size = -1;
04814 p->s3val = p->strbuf;
04815 break;
04816 default:
04817 error:
04818 setstat(s, -1, "unsupported parameter type",
04819 (*s->ov3) ? "07009" : "S1093");
04820 return SQL_ERROR;
04821 }
04822 return SQL_SUCCESS;
04823 }
04824
04840 static SQLRETURN
04841 drvbindparam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
04842 SQLSMALLINT buftype, SQLSMALLINT ptype, SQLUINTEGER coldef,
04843 SQLSMALLINT scale,
04844 SQLPOINTER data, SQLINTEGER buflen, SQLLEN *len)
04845 {
04846 STMT *s;
04847 BINDPARM *p;
04848
04849 if (stmt == SQL_NULL_HSTMT) {
04850 return SQL_INVALID_HANDLE;
04851 }
04852 s = (STMT *) stmt;
04853 if (pnum == 0) {
04854 setstat(s, -1, "invalid parameter", (*s->ov3) ? "07009" : "S1093");
04855 return SQL_ERROR;
04856 }
04857 if (!data && !len) {
04858 setstat(s, -1, "invalid buffer", "HY003");
04859 return SQL_ERROR;
04860 }
04861 --pnum;
04862 if (s->bindparms) {
04863 if (pnum >= s->nbindparms) {
04864 BINDPARM *newparms;
04865
04866 newparms = xrealloc(s->bindparms,
04867 (pnum + 1) * sizeof (BINDPARM));
04868 if (!newparms) {
04869 outofmem:
04870 return nomem(s);
04871 }
04872 s->bindparms = newparms;
04873 memset(&s->bindparms[s->nbindparms], 0,
04874 (pnum + 1 - s->nbindparms) * sizeof (BINDPARM));
04875 s->nbindparms = pnum + 1;
04876 }
04877 } else {
04878 int npar = max(10, pnum + 1);
04879
04880 s->bindparms = xmalloc(npar * sizeof (BINDPARM));
04881 if (!s->bindparms) {
04882 goto outofmem;
04883 }
04884 memset(s->bindparms, 0, npar * sizeof (BINDPARM));
04885 s->nbindparms = npar;
04886 }
04887 switch (buftype) {
04888 case SQL_C_STINYINT:
04889 case SQL_C_UTINYINT:
04890 case SQL_C_TINYINT:
04891 #ifdef SQL_C_BIT
04892 case SQL_C_BIT:
04893 #endif
04894 buflen = sizeof (SQLCHAR);
04895 break;
04896 case SQL_C_SHORT:
04897 case SQL_C_USHORT:
04898 case SQL_C_SSHORT:
04899 buflen = sizeof (SQLSMALLINT);
04900 break;
04901 case SQL_C_SLONG:
04902 case SQL_C_ULONG:
04903 case SQL_C_LONG:
04904 buflen = sizeof (SQLINTEGER);
04905 break;
04906 case SQL_C_FLOAT:
04907 buflen = sizeof (float);
04908 break;
04909 case SQL_C_DOUBLE:
04910 buflen = sizeof (double);
04911 break;
04912 case SQL_C_TIMESTAMP:
04913 #ifdef SQL_C_TYPE_TIMESTAMP
04914 case SQL_C_TYPE_TIMESTAMP:
04915 #endif
04916 buflen = sizeof (TIMESTAMP_STRUCT);
04917 break;
04918 case SQL_C_TIME:
04919 #ifdef SQL_C_TYPE_TIME
04920 case SQL_C_TYPE_TIME:
04921 #endif
04922 buflen = sizeof (TIME_STRUCT);
04923 break;
04924 case SQL_C_DATE:
04925 #ifdef SQL_C_TYPE_DATE
04926 case SQL_C_TYPE_DATE:
04927 #endif
04928 buflen = sizeof (DATE_STRUCT);
04929 break;
04930 #ifdef SQL_C_UBIGINT
04931 case SQL_C_UBIGINT:
04932 buflen = sizeof (SQLBIGINT);
04933 break;
04934 #endif
04935 #ifdef SQL_C_SBIGINT
04936 case SQL_C_SBIGINT:
04937 buflen = sizeof (SQLBIGINT);
04938 break;
04939 #endif
04940 #ifdef SQL_C_BIGINT
04941 case SQL_C_BIGINT:
04942 buflen = sizeof (SQLBIGINT);
04943 break;
04944 #endif
04945 }
04946 p = &s->bindparms[pnum];
04947 p->type = buftype;
04948 p->stype = ptype;
04949 p->coldef = coldef;
04950 p->scale = scale;
04951 p->max = buflen;
04952 p->inc = buflen;
04953 p->lenp = p->lenp0 = len;
04954 p->offs = 0;
04955 p->len = 0;
04956 p->param0 = data;
04957 freep(&p->parbuf);
04958 p->param = p->param0;
04959 p->bound = 1;
04960 p->need = 0;
04961 return SQL_SUCCESS;
04962 }
04963
04979 SQLRETURN SQL_API
04980 SQLBindParameter(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
04981 SQLSMALLINT buftype, SQLSMALLINT ptype, SQLULEN coldef,
04982 SQLSMALLINT scale,
04983 SQLPOINTER data, SQLLEN buflen, SQLLEN *len)
04984 {
04985 SQLRETURN ret;
04986
04987 HSTMT_LOCK(stmt);
04988 ret = drvbindparam(stmt, pnum, iotype, buftype, ptype, coldef,
04989 scale, data, buflen, len);
04990 HSTMT_UNLOCK(stmt);
04991 return ret;
04992 }
04993
04994 #ifndef HAVE_IODBC
04995
05008 SQLRETURN SQL_API
05009 SQLBindParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT vtype,
05010 SQLSMALLINT ptype, SQLULEN lenprec,
05011 SQLSMALLINT scale, SQLPOINTER val,
05012 SQLLEN *lenp)
05013 {
05014 SQLRETURN ret;
05015
05016 HSTMT_LOCK(stmt);
05017 ret = drvbindparam(stmt, pnum, SQL_PARAM_INPUT, vtype, ptype,
05018 lenprec, scale, val, 0, lenp);
05019 HSTMT_UNLOCK(stmt);
05020 return ret;
05021 }
05022 #endif
05023
05031 SQLRETURN SQL_API
05032 SQLNumParams(SQLHSTMT stmt, SQLSMALLINT *nparam)
05033 {
05034 STMT *s;
05035 SQLSMALLINT dummy;
05036
05037 HSTMT_LOCK(stmt);
05038 if (stmt == SQL_NULL_HSTMT) {
05039 return SQL_INVALID_HANDLE;
05040 }
05041 s = (STMT *) stmt;
05042 if (!nparam) {
05043 nparam = &dummy;
05044 }
05045 *nparam = s->nparams;
05046 HSTMT_UNLOCK(stmt);
05047 return SQL_SUCCESS;
05048 }
05049
05057 static SQLRETURN
05058 setupparbuf(STMT *s, BINDPARM *p)
05059 {
05060 if (!p->parbuf) {
05061 p->len = SQL_LEN_DATA_AT_EXEC(*p->lenp);
05062 if (p->len < 0 && p->len != SQL_NTS &&
05063 p->len != SQL_NULL_DATA) {
05064 setstat(s, -1, "invalid length", "HY009");
05065 return SQL_ERROR;
05066 }
05067 if (p->len >= 0) {
05068 p->parbuf = xmalloc(p->len + 1);
05069 if (!p->parbuf) {
05070 return nomem(s);
05071 }
05072 p->param = p->parbuf;
05073 } else {
05074 p->param = NULL;
05075 }
05076 }
05077 return SQL_NEED_DATA;
05078 }
05079
05087 SQLRETURN SQL_API
05088 SQLParamData(SQLHSTMT stmt, SQLPOINTER *pind)
05089 {
05090 STMT *s;
05091 int i;
05092 SQLPOINTER dummy;
05093 SQLRETURN ret;
05094
05095 HSTMT_LOCK(stmt);
05096 if (stmt == SQL_NULL_HSTMT) {
05097 return SQL_INVALID_HANDLE;
05098 }
05099 s = (STMT *) stmt;
05100 if (!pind) {
05101 pind = &dummy;
05102 }
05103 for (i = 0; i < s->nparams; i++) {
05104 BINDPARM *p = &s->bindparms[i];
05105
05106 if (p->need > 0) {
05107 *pind = (SQLPOINTER) p->param0;
05108 ret = setupparbuf(s, p);
05109 goto done;
05110 }
05111 }
05112 ret = drvexecute(stmt, 0);
05113 done:
05114 HSTMT_UNLOCK(stmt);
05115 return ret;
05116 }
05117
05129 SQLRETURN SQL_API
05130 SQLDescribeParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT *dtype,
05131 SQLULEN *size, SQLSMALLINT *decdigits, SQLSMALLINT *nullable)
05132 {
05133 STMT *s;
05134 SQLRETURN ret = SQL_ERROR;
05135
05136 HSTMT_LOCK(stmt);
05137 if (stmt == SQL_NULL_HSTMT) {
05138 return SQL_INVALID_HANDLE;
05139 }
05140 s = (STMT *) stmt;
05141 --pnum;
05142 if (pnum >= s->nparams) {
05143 setstat(s, -1, "invalid parameter index",
05144 (*s->ov3) ? "HY000" : "S1000");
05145 goto done;
05146 }
05147 if (dtype) {
05148 #ifdef SQL_LONGVARCHAR
05149 #ifdef WINTERFACE
05150 *dtype = s->nowchar[0] ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
05151 #else
05152 *dtype = SQL_LONGVARCHAR;
05153 #endif
05154 #else
05155 #ifdef WINTERFACE
05156 *dtype = s->nowchar[0] ? SQL_VARCHAR : SQL_WVARCHAR;
05157 #else
05158 *dtype = SQL_VARCHAR;
05159 #endif
05160 #endif
05161 }
05162 if (size) {
05163 #ifdef SQL_LONGVARCHAR
05164 *size = 65536;
05165 #else
05166 *size = 255;
05167 #endif
05168 }
05169 if (decdigits) {
05170 *decdigits = 0;
05171 }
05172 if (nullable) {
05173 *nullable = SQL_NULLABLE;
05174 }
05175 ret = SQL_SUCCESS;
05176 done:
05177 HSTMT_UNLOCK(stmt);
05178 return ret;
05179 }
05180
05194 SQLRETURN SQL_API
05195 SQLSetParam(SQLHSTMT stmt, SQLUSMALLINT par, SQLSMALLINT type,
05196 SQLSMALLINT sqltype, SQLULEN coldef,
05197 SQLSMALLINT scale, SQLPOINTER val, SQLLEN *nval)
05198 {
05199 SQLRETURN ret;
05200
05201 HSTMT_LOCK(stmt);
05202 ret = drvbindparam(stmt, par, SQL_PARAM_INPUT,
05203 type, sqltype, coldef, scale, val,
05204 SQL_SETPARAM_VALUE_MAX, nval);
05205 HSTMT_UNLOCK(stmt);
05206 return ret;
05207 }
05208
05213 SQLRETURN SQL_API
05214 SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
05215 {
05216 SQLRETURN ret;
05217
05218 HSTMT_LOCK(stmt);
05219 ret = drvunimplstmt(stmt);
05220 HSTMT_UNLOCK(stmt);
05221 return ret;
05222 }
05223
05224 #ifndef WINTERFACE
05225
05229 SQLRETURN SQL_API
05230 SQLGetDescField(SQLHDESC handle, SQLSMALLINT recno,
05231 SQLSMALLINT fieldid, SQLPOINTER value,
05232 SQLINTEGER buflen, SQLINTEGER *strlen)
05233 {
05234 return SQL_ERROR;
05235 }
05236 #endif
05237
05238 #ifdef WINTERFACE
05239
05243 SQLRETURN SQL_API
05244 SQLGetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
05245 SQLSMALLINT fieldid, SQLPOINTER value,
05246 SQLINTEGER buflen, SQLINTEGER *strlen)
05247 {
05248 return SQL_ERROR;
05249 }
05250 #endif
05251
05252 #ifndef WINTERFACE
05253
05257 SQLRETURN SQL_API
05258 SQLSetDescField(SQLHDESC handle, SQLSMALLINT recno,
05259 SQLSMALLINT fieldid, SQLPOINTER value,
05260 SQLINTEGER buflen)
05261 {
05262 return SQL_ERROR;
05263 }
05264 #endif
05265
05266 #ifdef WINTERFACE
05267
05271 SQLRETURN SQL_API
05272 SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
05273 SQLSMALLINT fieldid, SQLPOINTER value,
05274 SQLINTEGER buflen)
05275 {
05276 return SQL_ERROR;
05277 }
05278 #endif
05279
05280 #ifndef WINTERFACE
05281
05285 SQLRETURN SQL_API
05286 SQLGetDescRec(SQLHDESC handle, SQLSMALLINT recno,
05287 SQLCHAR *name, SQLSMALLINT buflen,
05288 SQLSMALLINT *strlen, SQLSMALLINT *type,
05289 SQLSMALLINT *subtype, SQLLEN *len,
05290 SQLSMALLINT *prec, SQLSMALLINT *scale,
05291 SQLSMALLINT *nullable)
05292 {
05293 return SQL_ERROR;
05294 }
05295 #endif
05296
05297 #ifdef WINTERFACE
05298
05302 SQLRETURN SQL_API
05303 SQLGetDescRecW(SQLHDESC handle, SQLSMALLINT recno,
05304 SQLWCHAR *name, SQLSMALLINT buflen,
05305 SQLSMALLINT *strlen, SQLSMALLINT *type,
05306 SQLSMALLINT *subtype, SQLLEN *len,
05307 SQLSMALLINT *prec, SQLSMALLINT *scale,
05308 SQLSMALLINT *nullable)
05309 {
05310 return SQL_ERROR;
05311 }
05312 #endif
05313
05318 SQLRETURN SQL_API
05319 SQLSetDescRec(SQLHDESC handle, SQLSMALLINT recno,
05320 SQLSMALLINT type, SQLSMALLINT subtype,
05321 SQLLEN len, SQLSMALLINT prec,
05322 SQLSMALLINT scale, SQLPOINTER data,
05323 SQLLEN *strlen, SQLLEN *indicator)
05324 {
05325 return SQL_ERROR;
05326 }
05327
05339 static SQLRETURN
05340 mkresultset(HSTMT stmt, COL *colspec, int ncols, COL *colspec3,
05341 int ncols3, int *nret)
05342 {
05343 STMT *s;
05344 DBC *d;
05345
05346 if (stmt == SQL_NULL_HSTMT) {
05347 return SQL_INVALID_HANDLE;
05348 }
05349 s = (STMT *) stmt;
05350 if (s->dbc == SQL_NULL_HDBC) {
05351 noconn:
05352 return noconn(s);
05353 }
05354 d = (DBC *) s->dbc;
05355 if (!d->sqlite) {
05356 goto noconn;
05357 }
05358 s3stmt_end_if(s);
05359 freeresult(s, 0);
05360 if (colspec3 && *s->ov3) {
05361 s->ncols = ncols3;
05362 s->cols = colspec3;
05363 } else {
05364 s->ncols = ncols;
05365 s->cols = colspec;
05366 }
05367 mkbindcols(s, s->ncols);
05368 s->nowchar[1] = 1;
05369 s->nrows = 0;
05370 s->rowp = -1;
05371 s->isselect = -1;
05372 if (nret) {
05373 *nret = s->ncols;
05374 }
05375 return SQL_SUCCESS;
05376 }
05377
05382 static COL tablePrivSpec2[] = {
05383 { "SYSTEM", "TABLEPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
05384 { "SYSTEM", "TABLEPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
05385 { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
05386 { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
05387 { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
05388 { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
05389 { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
05390 };
05391
05392 static COL tablePrivSpec3[] = {
05393 { "SYSTEM", "TABLEPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
05394 { "SYSTEM", "TABLEPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
05395 { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
05396 { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
05397 { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
05398 { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
05399 { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
05400 };
05401
05414 static SQLRETURN
05415 drvtableprivileges(SQLHSTMT stmt,
05416 SQLCHAR *cat, SQLSMALLINT catLen,
05417 SQLCHAR *schema, SQLSMALLINT schemaLen,
05418 SQLCHAR *table, SQLSMALLINT tableLen)
05419 {
05420 SQLRETURN ret;
05421 STMT *s;
05422 DBC *d;
05423 int ncols, rc, size, npatt;
05424 char *errp = NULL, *sql, tname[512];
05425
05426 ret = mkresultset(stmt, tablePrivSpec2, array_size(tablePrivSpec2),
05427 tablePrivSpec3, array_size(tablePrivSpec3), NULL);
05428 if (ret != SQL_SUCCESS) {
05429 return ret;
05430 }
05431 s = (STMT *) stmt;
05432 d = (DBC *) s->dbc;
05433 if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
05434 table = NULL;
05435 goto doit;
05436 }
05437 if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
05438 schema[0] == '%') {
05439 if ((!cat || catLen == 0 || !cat[0]) &&
05440 (!table || tableLen == 0 || !table[0])) {
05441 table = NULL;
05442 goto doit;
05443 }
05444 }
05445 doit:
05446 if (!table) {
05447 size = 1;
05448 tname[0] = '%';
05449 } else {
05450 if (tableLen == SQL_NTS) {
05451 size = sizeof (tname) - 1;
05452 } else {
05453 size = min(sizeof (tname) - 1, tableLen);
05454 }
05455 strncpy(tname, (char *) table, size);
05456 }
05457 tname[size] = '\0';
05458 npatt = unescpat(tname);
05459 #if defined(_WIN32) || defined(_WIN64)
05460 sql = sqlite3_mprintf("select %s as 'TABLE_QUALIFIER', "
05461 "%s as 'TABLE_OWNER', "
05462 "tbl_name as 'TABLE_NAME', "
05463 "'' as 'GRANTOR', "
05464 "'' as 'GRANTEE', "
05465 "'SELECT' AS 'PRIVILEGE', "
05466 "NULL as 'IS_GRANTABLE' "
05467 "from sqlite_master where "
05468 "(type = 'table' or type = 'view') "
05469 "and tbl_name %s %Q "
05470 "UNION "
05471 "select %s as 'TABLE_QUALIFIER', "
05472 "%s as 'TABLE_OWNER', "
05473 "tbl_name as 'TABLE_NAME', "
05474 "'' as 'GRANTOR', "
05475 "'' as 'GRANTEE', "
05476 "'UPDATE' AS 'PRIVILEGE', "
05477 "NULL as 'IS_GRANTABLE' "
05478 "from sqlite_master where "
05479 "(type = 'table' or type = 'view') "
05480 "and tbl_name %s %Q "
05481 "UNION "
05482 "select %s as 'TABLE_QUALIFIER', "
05483 "%s as 'TABLE_OWNER', "
05484 "tbl_name as 'TABLE_NAME', "
05485 "'' as 'GRANTOR', "
05486 "'' as 'GRANTEE', "
05487 "'DELETE' AS 'PRIVILEGE', "
05488 "NULL as 'IS_GRANTABLE' "
05489 "from sqlite_master where "
05490 "(type = 'table' or type = 'view') "
05491 "and tbl_name %s %Q "
05492 "UNION "
05493 "select %s as 'TABLE_QUALIFIER', "
05494 "%s as 'TABLE_OWNER', "
05495 "tbl_name as 'TABLE_NAME', "
05496 "'' as 'GRANTOR', "
05497 "'' as 'GRANTEE', "
05498 "'INSERT' AS 'PRIVILEGE', "
05499 "NULL as 'IS_GRANTABLE' "
05500 "from sqlite_master where "
05501 "(type = 'table' or type = 'view') "
05502 "and tbl_name %s %Q "
05503 "UNION "
05504 "select %s as 'TABLE_QUALIFIER', "
05505 "%s as 'TABLE_OWNER', "
05506 "tbl_name as 'TABLE_NAME', "
05507 "'' as 'GRANTOR', "
05508 "'' as 'GRANTEE', "
05509 "'REFERENCES' AS 'PRIVILEGE', "
05510 "NULL as 'IS_GRANTABLE' "
05511 "from sqlite_master where "
05512 "(type = 'table' or type = 'view') "
05513 "and tbl_name %s %Q",
05514 d->xcelqrx ? "''" : "NULL",
05515 d->xcelqrx ? "'main'" : "NULL",
05516 npatt ? "like" : "=", tname,
05517 d->xcelqrx ? "''" : "NULL",
05518 d->xcelqrx ? "'main'" : "NULL",
05519 npatt ? "like" : "=", tname,
05520 d->xcelqrx ? "''" : "NULL",
05521 d->xcelqrx ? "'main'" : "NULL",
05522 npatt ? "like" : "=", tname,
05523 d->xcelqrx ? "''" : "NULL",
05524 d->xcelqrx ? "'main'" : "NULL",
05525 npatt ? "like" : "=", tname,
05526 d->xcelqrx ? "''" : "NULL",
05527 d->xcelqrx ? "'main'" : "NULL",
05528 npatt ? "like" : "=", tname);
05529 #else
05530 sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
05531 "NULL as 'TABLE_OWNER', "
05532 "tbl_name as 'TABLE_NAME', "
05533 "'' as 'GRANTOR', "
05534 "'' as 'GRANTEE', "
05535 "'SELECT' AS 'PRIVILEGE', "
05536 "NULL as 'IS_GRANTABLE' "
05537 "from sqlite_master where "
05538 "(type = 'table' or type = 'view') "
05539 "and tbl_name %s %Q "
05540 "UNION "
05541 "select NULL as 'TABLE_QUALIFIER', "
05542 "NULL as 'TABLE_OWNER', "
05543 "tbl_name as 'TABLE_NAME', "
05544 "'' as 'GRANTOR', "
05545 "'' as 'GRANTEE', "
05546 "'UPDATE' AS 'PRIVILEGE', "
05547 "NULL as 'IS_GRANTABLE' "
05548 "from sqlite_master where "
05549 "(type = 'table' or type = 'view') "
05550 "and tbl_name %s %Q "
05551 "UNION "
05552 "select NULL as 'TABLE_QUALIFIER', "
05553 "NULL as 'TABLE_OWNER', "
05554 "tbl_name as 'TABLE_NAME', "
05555 "'' as 'GRANTOR', "
05556 "'' as 'GRANTEE', "
05557 "'DELETE' AS 'PRIVILEGE', "
05558 "NULL as 'IS_GRANTABLE' "
05559 "from sqlite_master where "
05560 "(type = 'table' or type = 'view') "
05561 "and tbl_name %s %Q "
05562 "UNION "
05563 "select NULL as 'TABLE_QUALIFIER', "
05564 "NULL as 'TABLE_OWNER', "
05565 "tbl_name as 'TABLE_NAME', "
05566 "'' as 'GRANTOR', "
05567 "'' as 'GRANTEE', "
05568 "'INSERT' AS 'PRIVILEGE', "
05569 "NULL as 'IS_GRANTABLE' "
05570 "from sqlite_master where "
05571 "(type = 'table' or type = 'view') "
05572 "and tbl_name %s %Q "
05573 "UNION "
05574 "select NULL as 'TABLE_QUALIFIER', "
05575 "NULL as 'TABLE_OWNER', "
05576 "tbl_name as 'TABLE_NAME', "
05577 "'' as 'GRANTOR', "
05578 "'' as 'GRANTEE', "
05579 "'REFERENCES' AS 'PRIVILEGE', "
05580 "NULL as 'IS_GRANTABLE' "
05581 "from sqlite_master where "
05582 "(type = 'table' or type = 'view') "
05583 "and tbl_name %s %Q",
05584 npatt ? "like" : "=", tname,
05585 npatt ? "like" : "=", tname,
05586 npatt ? "like" : "=", tname,
05587 npatt ? "like" : "=", tname,
05588 npatt ? "like" : "=", tname);
05589 #endif
05590 if (!sql) {
05591 return nomem(s);
05592 }
05593 ret = starttran(s);
05594 if (ret != SQL_SUCCESS) {
05595 sqlite3_free(sql);
05596 return ret;
05597 }
05598 dbtraceapi(d, "sqlite3_get_table", sql);
05599 rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
05600 sqlite3_free(sql);
05601 if (rc == SQLITE_OK) {
05602 if (ncols != s->ncols) {
05603 freeresult(s, 0);
05604 s->nrows = 0;
05605 } else {
05606 s->rowfree = sqlite3_free_table;
05607 }
05608 } else {
05609 s->nrows = 0;
05610 s->rows = NULL;
05611 s->rowfree = NULL;
05612 }
05613 if (errp) {
05614 sqlite3_free(errp);
05615 errp = NULL;
05616 }
05617 s->rowp = -1;
05618 return SQL_SUCCESS;
05619 }
05620
05621
05622 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
05623
05635 SQLRETURN SQL_API
05636 SQLTablePrivileges(SQLHSTMT stmt,
05637 SQLCHAR *catalog, SQLSMALLINT catalogLen,
05638 SQLCHAR *schema, SQLSMALLINT schemaLen,
05639 SQLCHAR *table, SQLSMALLINT tableLen)
05640 {
05641 #if defined(_WIN32) || defined(_WIN64)
05642 char *c = NULL, *s = NULL, *t = NULL;
05643 #endif
05644 SQLRETURN ret;
05645
05646 HSTMT_LOCK(stmt);
05647 #if defined(_WIN32) || defined(_WIN64)
05648 if (!((STMT *) stmt)->oemcp[0]) {
05649 ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
05650 table, tableLen);
05651 goto done2;
05652 }
05653 if (catalog) {
05654 c = wmb_to_utf_c((char *) catalog, catalogLen);
05655 if (!c) {
05656 ret = nomem((STMT *) stmt);
05657 goto done;
05658 }
05659 }
05660 if (schema) {
05661 s = wmb_to_utf_c((char *) schema, schemaLen);
05662 if (!s) {
05663 ret = nomem((STMT *) stmt);
05664 goto done;
05665 }
05666 }
05667 if (table) {
05668 t = wmb_to_utf_c((char *) table, tableLen);
05669 if (!t) {
05670 ret = nomem((STMT *) stmt);
05671 goto done;
05672 }
05673 }
05674 ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
05675 (SQLCHAR *) s, SQL_NTS,
05676 (SQLCHAR *) t, SQL_NTS);
05677 #else
05678 ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
05679 table, tableLen);
05680 #endif
05681 #if defined(_WIN32) || defined(_WIN64)
05682 done:
05683 uc_free(t);
05684 uc_free(s);
05685 uc_free(c);
05686 done2:
05687 ;
05688 #endif
05689 HSTMT_UNLOCK(stmt);
05690 return ret;
05691 }
05692 #endif
05693
05694 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
05695 #ifdef WINTERFACE
05696
05708 SQLRETURN SQL_API
05709 SQLTablePrivilegesW(SQLHSTMT stmt,
05710 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
05711 SQLWCHAR *schema, SQLSMALLINT schemaLen,
05712 SQLWCHAR *table, SQLSMALLINT tableLen)
05713 {
05714 char *c = NULL, *s = NULL, *t = NULL;
05715 SQLRETURN ret;
05716
05717 HSTMT_LOCK(stmt);
05718 if (catalog) {
05719 c = uc_to_utf_c(catalog, catalogLen);
05720 if (!c) {
05721 ret = nomem((STMT *) stmt);
05722 goto done;
05723 }
05724 }
05725 if (schema) {
05726 s = uc_to_utf_c(schema, schemaLen);
05727 if (!s) {
05728 ret = nomem((STMT *) stmt);
05729 goto done;
05730 }
05731 }
05732 if (table) {
05733 t = uc_to_utf_c(table, tableLen);
05734 if (!t) {
05735 ret = nomem((STMT *) stmt);
05736 goto done;
05737 }
05738 }
05739 ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
05740 (SQLCHAR *) s, SQL_NTS,
05741 (SQLCHAR *) t, SQL_NTS);
05742 done:
05743 uc_free(t);
05744 uc_free(s);
05745 uc_free(c);
05746 HSTMT_UNLOCK(stmt);
05747 return ret;
05748 }
05749 #endif
05750 #endif
05751
05756 static COL colPrivSpec2[] = {
05757 { "SYSTEM", "COLPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
05758 { "SYSTEM", "COLPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
05759 { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
05760 { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
05761 { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
05762 { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
05763 { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
05764 };
05765
05766 static COL colPrivSpec3[] = {
05767 { "SYSTEM", "COLPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
05768 { "SYSTEM", "COLPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
05769 { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
05770 { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
05771 { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
05772 { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
05773 { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
05774 };
05775
05776 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
05777
05791 SQLRETURN SQL_API
05792 SQLColumnPrivileges(SQLHSTMT stmt,
05793 SQLCHAR *catalog, SQLSMALLINT catalogLen,
05794 SQLCHAR *schema, SQLSMALLINT schemaLen,
05795 SQLCHAR *table, SQLSMALLINT tableLen,
05796 SQLCHAR *column, SQLSMALLINT columnLen)
05797 {
05798 SQLRETURN ret;
05799
05800 HSTMT_LOCK(stmt);
05801 ret = mkresultset(stmt, colPrivSpec2, array_size(colPrivSpec2),
05802 colPrivSpec3, array_size(colPrivSpec3), NULL);
05803 HSTMT_UNLOCK(stmt);
05804 return ret;
05805 }
05806 #endif
05807
05808 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
05809 #ifdef WINTERFACE
05810
05824 SQLRETURN SQL_API
05825 SQLColumnPrivilegesW(SQLHSTMT stmt,
05826 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
05827 SQLWCHAR *schema, SQLSMALLINT schemaLen,
05828 SQLWCHAR *table, SQLSMALLINT tableLen,
05829 SQLWCHAR *column, SQLSMALLINT columnLen)
05830 {
05831 SQLRETURN ret;
05832
05833 HSTMT_LOCK(stmt);
05834 ret = mkresultset(stmt, colPrivSpec2, array_size(colPrivSpec2),
05835 colPrivSpec3, array_size(colPrivSpec3), NULL);
05836 HSTMT_UNLOCK(stmt);
05837 return ret;
05838 }
05839 #endif
05840 #endif
05841
05846 static COL pkeySpec2[] = {
05847 { "SYSTEM", "PRIMARYKEY", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
05848 { "SYSTEM", "PRIMARYKEY", "TABLE_OWNER", SCOL_VARCHAR, 50 },
05849 { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
05850 { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
05851 { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
05852 { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
05853 };
05854
05855 static COL pkeySpec3[] = {
05856 { "SYSTEM", "PRIMARYKEY", "TABLE_CAT", SCOL_VARCHAR, 50 },
05857 { "SYSTEM", "PRIMARYKEY", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
05858 { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
05859 { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
05860 { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
05861 { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
05862 };
05863
05876 static SQLRETURN
05877 drvprimarykeys(SQLHSTMT stmt,
05878 SQLCHAR *cat, SQLSMALLINT catLen,
05879 SQLCHAR *schema, SQLSMALLINT schemaLen,
05880 SQLCHAR *table, SQLSMALLINT tableLen)
05881 {
05882 STMT *s;
05883 DBC *d;
05884 SQLRETURN sret;
05885 int i, asize, ret, nrows, ncols, nrows2 = 0, ncols2 = 0;
05886 int namec = -1, uniquec = -1, namec2 = -1, uniquec2 = -1, offs, seq = 1;
05887 PTRDIFF_T size;
05888 char **rowp = NULL, **rowp2 = NULL, *errp = NULL, *sql, tname[512];
05889
05890 sret = mkresultset(stmt, pkeySpec2, array_size(pkeySpec2),
05891 pkeySpec3, array_size(pkeySpec3), &asize);
05892 if (sret != SQL_SUCCESS) {
05893 return sret;
05894 }
05895 s = (STMT *) stmt;
05896 d = (DBC *) s->dbc;
05897 if (!table || table[0] == '\0' || table[0] == '%') {
05898 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
05899 return SQL_ERROR;
05900 }
05901 if (tableLen == SQL_NTS) {
05902 size = sizeof (tname) - 1;
05903 } else {
05904 size = min(sizeof (tname) - 1, tableLen);
05905 }
05906 strncpy(tname, (char *) table, size);
05907 tname[size] = '\0';
05908 unescpat(tname);
05909 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
05910 if (!sql) {
05911 return nomem(s);
05912 }
05913 sret = starttran(s);
05914 if (sret != SQL_SUCCESS) {
05915 sqlite3_free(sql);
05916 return sret;
05917 }
05918 dbtraceapi(d, "sqlite3_get_table", sql);
05919 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
05920 sqlite3_free(sql);
05921 if (ret != SQLITE_OK) {
05922 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
05923 errp ? errp : "unknown error", ret);
05924 if (errp) {
05925 sqlite3_free(errp);
05926 errp = NULL;
05927 }
05928 return SQL_ERROR;
05929 }
05930 if (errp) {
05931 sqlite3_free(errp);
05932 errp = NULL;
05933 }
05934 size = 0;
05935 if (ncols * nrows > 0) {
05936 int typec;
05937
05938 namec = findcol(rowp, ncols, "name");
05939 uniquec = findcol(rowp, ncols, "pk");
05940 typec = findcol(rowp, ncols, "type");
05941 if (namec >= 0 && uniquec >= 0 && typec >= 0) {
05942 for (i = 1; i <= nrows; i++) {
05943 if (*rowp[i * ncols + uniquec] != '0') {
05944 size++;
05945 }
05946 }
05947 }
05948 }
05949 if (size == 0) {
05950 sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
05951 if (!sql) {
05952 sqlite3_free_table(rowp);
05953 return nomem(s);
05954 }
05955 dbtraceapi(d, "sqlite3_get_table", sql);
05956 ret = sqlite3_get_table(d->sqlite, sql, &rowp2, &nrows2, &ncols2,
05957 &errp);
05958 sqlite3_free(sql);
05959 if (ret != SQLITE_OK) {
05960 sqlite3_free_table(rowp);
05961 sqlite3_free_table(rowp2);
05962 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
05963 errp ? errp : "unknown error", ret);
05964 if (errp) {
05965 sqlite3_free(errp);
05966 errp = NULL;
05967 }
05968 return SQL_ERROR;
05969 }
05970 if (errp) {
05971 sqlite3_free(errp);
05972 errp = NULL;
05973 }
05974 }
05975 if (ncols2 * nrows2 > 0) {
05976 namec2 = findcol(rowp2, ncols2, "name");
05977 uniquec2 = findcol(rowp2, ncols2, "unique");
05978 if (namec2 >= 0 && uniquec2 >= 0) {
05979 for (i = 1; i <= nrows2; i++) {
05980 int nnrows, nncols, nlen = 0;
05981 char **rowpp;
05982
05983 if (rowp2[i * ncols2 + namec2]) {
05984 nlen = strlen(rowp2[i * ncols2 + namec2]);
05985 }
05986 if (nlen < 17 ||
05987 strncmp(rowp2[i * ncols2 + namec2],
05988 "sqlite_autoindex_", 17)) {
05989 continue;
05990 }
05991 if (*rowp2[i * ncols2 + uniquec2] != '0') {
05992 ret = SQLITE_ERROR;
05993 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
05994 rowp2[i * ncols2 + namec2]);
05995 if (sql) {
05996 dbtraceapi(d, "sqlite3_get_table", sql);
05997 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
05998 &nnrows, &nncols, NULL);
05999 sqlite3_free(sql);
06000 }
06001 if (ret == SQLITE_OK) {
06002 size += nnrows;
06003 sqlite3_free_table(rowpp);
06004 }
06005 }
06006 }
06007 }
06008 }
06009 if (size == 0) {
06010 sqlite3_free_table(rowp);
06011 sqlite3_free_table(rowp2);
06012 return SQL_SUCCESS;
06013 }
06014 s->nrows = size;
06015 size = (size + 1) * asize;
06016 s->rows = xmalloc((size + 1) * sizeof (char *));
06017 if (!s->rows) {
06018 s->nrows = 0;
06019 sqlite3_free_table(rowp);
06020 sqlite3_free_table(rowp2);
06021 return nomem(s);
06022 }
06023 s->rows[0] = (char *) size;
06024 s->rows += 1;
06025 memset(s->rows, 0, sizeof (char *) * size);
06026 s->rowfree = freerows;
06027 offs = s->ncols;
06028 if (rowp) {
06029 for (i = 1; i <= nrows; i++) {
06030 if (*rowp[i * ncols + uniquec] != '0') {
06031 char buf[32];
06032
06033 s->rows[offs + 0] = xstrdup("");
06034 #if defined(_WIN32) || defined(_WIN64)
06035 s->rows[offs + 1] = xstrdup(d->xcelqrx ? "main" : "");
06036 #else
06037 s->rows[offs + 1] = xstrdup("");
06038 #endif
06039 s->rows[offs + 2] = xstrdup(tname);
06040 s->rows[offs + 3] = xstrdup(rowp[i * ncols + namec]);
06041 sprintf(buf, "%d", seq++);
06042 s->rows[offs + 4] = xstrdup(buf);
06043 offs += s->ncols;
06044 }
06045 }
06046 }
06047 if (rowp2) {
06048 for (i = 1; i <= nrows2; i++) {
06049 int nnrows, nncols, nlen = 0;
06050 char **rowpp;
06051
06052 if (rowp2[i * ncols2 + namec2]) {
06053 nlen = strlen(rowp2[i * ncols2 + namec2]);
06054 }
06055 if (nlen < 17 ||
06056 strncmp(rowp2[i * ncols2 + namec2], "sqlite_autoindex_", 17)) {
06057 continue;
06058 }
06059 if (*rowp2[i * ncols2 + uniquec2] != '0') {
06060 int k;
06061
06062 ret = SQLITE_ERROR;
06063 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
06064 rowp2[i * ncols2 + namec2]);
06065 if (sql) {
06066 dbtraceapi(d, "sqlite3_get_table", sql);
06067 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
06068 &nnrows, &nncols, NULL);
06069 sqlite3_free(sql);
06070 }
06071 if (ret != SQLITE_OK) {
06072 continue;
06073 }
06074 for (k = 0; nnrows && k < nncols; k++) {
06075 if (strcmp(rowpp[k], "name") == 0) {
06076 int m;
06077
06078 for (m = 1; m <= nnrows; m++) {
06079 int roffs = offs + (m - 1) * s->ncols;
06080
06081 s->rows[roffs + 0] = xstrdup("");
06082 #if defined(_WIN32) || defined(_WIN64)
06083 s->rows[roffs + 1] =
06084 xstrdup(d->xcelqrx ? "main" : "");
06085 #else
06086 s->rows[roffs + 1] = xstrdup("");
06087 #endif
06088 s->rows[roffs + 2] = xstrdup(tname);
06089 s->rows[roffs + 3] =
06090 xstrdup(rowpp[m * nncols + k]);
06091 s->rows[roffs + 5] =
06092 xstrdup(rowp2[i * ncols2 + namec2]);
06093 }
06094 } else if (strcmp(rowpp[k], "seqno") == 0) {
06095 int m;
06096
06097 for (m = 1; m <= nnrows; m++) {
06098 int roffs = offs + (m - 1) * s->ncols;
06099 int pos = m - 1;
06100 char buf[32];
06101
06102 sscanf(rowpp[m * nncols + k], "%d", &pos);
06103 sprintf(buf, "%d", pos + 1);
06104 s->rows[roffs + 4] = xstrdup(buf);
06105 }
06106 }
06107 }
06108 offs += nnrows * s->ncols;
06109 sqlite3_free_table(rowpp);
06110 }
06111 }
06112 }
06113 sqlite3_free_table(rowp);
06114 sqlite3_free_table(rowp2);
06115 return SQL_SUCCESS;
06116 }
06117
06118 #ifndef WINTERFACE
06119
06131 SQLRETURN SQL_API
06132 SQLPrimaryKeys(SQLHSTMT stmt,
06133 SQLCHAR *cat, SQLSMALLINT catLen,
06134 SQLCHAR *schema, SQLSMALLINT schemaLen,
06135 SQLCHAR *table, SQLSMALLINT tableLen)
06136 {
06137 #if defined(_WIN32) || defined(_WIN64)
06138 char *c = NULL, *s = NULL, *t = NULL;
06139 #endif
06140 SQLRETURN ret;
06141
06142 HSTMT_LOCK(stmt);
06143 #if defined(_WIN32) || defined(_WIN64)
06144 if (!((STMT *) stmt)->oemcp[0]) {
06145 ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
06146 table, tableLen);
06147 goto done2;
06148 }
06149 if (cat) {
06150 c = wmb_to_utf_c((char *) cat, catLen);
06151 if (!c) {
06152 ret = nomem((STMT *) stmt);
06153 goto done;
06154 }
06155 }
06156 if (schema) {
06157 s = wmb_to_utf_c((char *) schema, schemaLen);
06158 if (!s) {
06159 ret = nomem((STMT *) stmt);
06160 goto done;
06161 }
06162 }
06163 if (table) {
06164 t = wmb_to_utf_c((char *) table, tableLen);
06165 if (!t) {
06166 ret = nomem((STMT *) stmt);
06167 goto done;
06168 }
06169 }
06170 ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
06171 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
06172 #else
06173 ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
06174 table, tableLen);
06175 #endif
06176 #if defined(_WIN32) || defined(_WIN64)
06177 done:
06178 uc_free(t);
06179 uc_free(s);
06180 uc_free(c);
06181 done2:
06182 ;
06183 #endif
06184 HSTMT_UNLOCK(stmt);
06185 return ret;
06186 }
06187 #endif
06188
06189 #ifdef WINTERFACE
06190
06202 SQLRETURN SQL_API
06203 SQLPrimaryKeysW(SQLHSTMT stmt,
06204 SQLWCHAR *cat, SQLSMALLINT catLen,
06205 SQLWCHAR *schema, SQLSMALLINT schemaLen,
06206 SQLWCHAR *table, SQLSMALLINT tableLen)
06207 {
06208 char *c = NULL, *s = NULL, *t = NULL;
06209 SQLRETURN ret;
06210
06211 HSTMT_LOCK(stmt);
06212 if (cat) {
06213 c = uc_to_utf_c(cat, catLen);
06214 if (!c) {
06215 ret = nomem((STMT *) stmt);
06216 goto done;
06217 }
06218 }
06219 if (schema) {
06220 s = uc_to_utf_c(schema, schemaLen);
06221 if (!s) {
06222 ret = nomem((STMT *) stmt);
06223 goto done;
06224 }
06225 }
06226 if (table) {
06227 t = uc_to_utf_c(table, tableLen);
06228 if (!t) {
06229 ret = nomem((STMT *) stmt);
06230 goto done;
06231 }
06232 }
06233 ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
06234 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
06235 done:
06236 uc_free(t);
06237 uc_free(s);
06238 uc_free(c);
06239 HSTMT_UNLOCK(stmt);
06240 return ret;
06241 }
06242 #endif
06243
06248 static COL scolSpec2[] = {
06249 { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
06250 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
06251 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
06252 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
06253 { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
06254 { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
06255 { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
06256 { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
06257 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
06258 };
06259
06260 static COL scolSpec3[] = {
06261 { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
06262 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
06263 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
06264 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
06265 { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
06266 { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
06267 { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
06268 { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
06269 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
06270 };
06271
06287 static SQLRETURN
06288 drvspecialcolumns(SQLHSTMT stmt, SQLUSMALLINT id,
06289 SQLCHAR *cat, SQLSMALLINT catLen,
06290 SQLCHAR *schema, SQLSMALLINT schemaLen,
06291 SQLCHAR *table, SQLSMALLINT tableLen,
06292 SQLUSMALLINT scope, SQLUSMALLINT nullable)
06293 {
06294 STMT *s;
06295 DBC *d;
06296 SQLRETURN sret;
06297 int i, asize, ret, nrows, ncols, nnnrows, nnncols, offs;
06298 PTRDIFF_T size;
06299 int namec = -1, uniquec = -1, namecc = -1, typecc = -1;
06300 int notnullcc = -1, mkrowid = 0;
06301 char *errp = NULL, *sql, tname[512];
06302 char **rowp = NULL, **rowppp = NULL;
06303
06304 sret = mkresultset(stmt, scolSpec2, array_size(scolSpec2),
06305 scolSpec3, array_size(scolSpec3), &asize);
06306 if (sret != SQL_SUCCESS) {
06307 return sret;
06308 }
06309 s = (STMT *) stmt;
06310 d = (DBC *) s->dbc;
06311 if (!table || table[0] == '\0' || table[0] == '%') {
06312 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
06313 return SQL_ERROR;
06314 }
06315 if (tableLen == SQL_NTS) {
06316 size = sizeof (tname) - 1;
06317 } else {
06318 size = min(sizeof (tname) - 1, tableLen);
06319 }
06320 strncpy(tname, (char *) table, size);
06321 tname[size] = '\0';
06322 unescpat(tname);
06323 if (id != SQL_BEST_ROWID) {
06324 return SQL_SUCCESS;
06325 }
06326 sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
06327 if (!sql) {
06328 return nomem(s);
06329 }
06330 sret = starttran(s);
06331 if (sret != SQL_SUCCESS) {
06332 sqlite3_free(sql);
06333 return sret;
06334 }
06335 dbtraceapi(d, "sqlite3_get_table", sql);
06336 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
06337 sqlite3_free(sql);
06338 if (ret != SQLITE_OK) {
06339 doerr:
06340 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
06341 errp ? errp : "unknown error", ret);
06342 if (errp) {
06343 sqlite3_free(errp);
06344 errp = NULL;
06345 }
06346 return SQL_ERROR;
06347 }
06348 if (errp) {
06349 sqlite3_free(errp);
06350 errp = NULL;
06351 }
06352 size = 0;
06353 if (ncols * nrows <= 0) {
06354 goto nodata_but_rowid;
06355 }
06356 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
06357 if (!sql) {
06358 return nomem(s);
06359 }
06360 dbtraceapi(d, "sqlite3_get_table", sql);
06361 ret = sqlite3_get_table(d->sqlite, sql, &rowppp, &nnnrows, &nnncols,
06362 &errp);
06363 sqlite3_free(sql);
06364 if (ret != SQLITE_OK) {
06365 sqlite3_free_table(rowp);
06366 goto doerr;
06367 }
06368 if (errp) {
06369 sqlite3_free(errp);
06370 errp = NULL;
06371 }
06372 namec = findcol(rowp, ncols, "name");
06373 uniquec = findcol(rowp, ncols, "unique");
06374 if (namec < 0 || uniquec < 0) {
06375 goto nodata_but_rowid;
06376 }
06377 namecc = findcol(rowppp, nnncols, "name");
06378 typecc = findcol(rowppp, nnncols, "type");
06379 notnullcc = findcol(rowppp, nnncols, "notnull");
06380 for (i = 1; i <= nrows; i++) {
06381 int nnrows, nncols;
06382 char **rowpp = NULL;
06383
06384 if (*rowp[i * ncols + uniquec] != '0') {
06385 ret = SQLITE_ERROR;
06386 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
06387 rowp[i * ncols + namec]);
06388 if (sql) {
06389 dbtraceapi(d, "sqlite3_get_table", sql);
06390 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
06391 &nnrows, &nncols, NULL);
06392 sqlite3_free(sql);
06393 }
06394 if (ret == SQLITE_OK) {
06395 size += nnrows;
06396 sqlite3_free_table(rowpp);
06397 }
06398 }
06399 }
06400 nodata_but_rowid:
06401 if (size == 0) {
06402 size = 1;
06403 mkrowid = 1;
06404 }
06405 s->nrows = size;
06406 size = (size + 1) * asize;
06407 s->rows = xmalloc((size + 1) * sizeof (char *));
06408 if (!s->rows) {
06409 s->nrows = 0;
06410 sqlite3_free_table(rowp);
06411 sqlite3_free_table(rowppp);
06412 return nomem(s);
06413 }
06414 s->rows[0] = (char *) size;
06415 s->rows += 1;
06416 memset(s->rows, 0, sizeof (char *) * size);
06417 s->rowfree = freerows;
06418 if (mkrowid) {
06419 s->nrows = 0;
06420 goto mkrowid;
06421 }
06422 offs = 0;
06423 for (i = 1; i <= nrows; i++) {
06424 int nnrows, nncols;
06425 char **rowpp = NULL;
06426
06427 if (*rowp[i * ncols + uniquec] != '0') {
06428 int k;
06429
06430 ret = SQLITE_ERROR;
06431 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
06432 rowp[i * ncols + namec]);
06433 if (sql) {
06434 dbtraceapi(d, "sqlite3_get_table", sql);
06435 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
06436 &nnrows, &nncols, NULL);
06437 sqlite3_free(sql);
06438 }
06439 if (ret != SQLITE_OK) {
06440 continue;
06441 }
06442 for (k = 0; nnrows && k < nncols; k++) {
06443 if (strcmp(rowpp[k], "name") == 0) {
06444 int m;
06445
06446 for (m = 1; m <= nnrows; m++) {
06447 int roffs = (offs + m) * s->ncols;
06448
06449 s->rows[roffs + 0] =
06450 xstrdup(stringify(SQL_SCOPE_SESSION));
06451 s->rows[roffs + 1] = xstrdup(rowpp[m * nncols + k]);
06452 s->rows[roffs + 4] = xstrdup("0");
06453 s->rows[roffs + 7] =
06454 xstrdup(stringify(SQL_PC_NOT_PSEUDO));
06455 if (namecc >= 0 && typecc >= 0) {
06456 int ii;
06457
06458 for (ii = 1; ii <= nnnrows; ii++) {
06459 if (strcmp(rowppp[ii * nnncols + namecc],
06460 rowpp[m * nncols + k]) == 0) {
06461 char *typen = rowppp[ii * nnncols + typecc];
06462 int sqltype, mm, dd, isnullable = 0;
06463 char buf[32];
06464
06465 s->rows[roffs + 3] = xstrdup(typen);
06466 sqltype = mapsqltype(typen, NULL, *s->ov3,
06467 s->nowchar[0],
06468 s->dobigint);
06469 getmd(typen, sqltype, &mm, &dd);
06470 #ifdef SQL_LONGVARCHAR
06471 if (sqltype == SQL_VARCHAR && mm > 255) {
06472 sqltype = SQL_LONGVARCHAR;
06473 }
06474 #endif
06475 #ifdef WINTERFACE
06476 #ifdef SQL_WLONGVARCHAR
06477 if (sqltype == SQL_WVARCHAR && mm > 255) {
06478 sqltype = SQL_WLONGVARCHAR;
06479 }
06480 #endif
06481 #endif
06482 if (sqltype == SQL_VARBINARY && mm > 255) {
06483 sqltype = SQL_LONGVARBINARY;
06484 }
06485 sprintf(buf, "%d", sqltype);
06486 s->rows[roffs + 2] = xstrdup(buf);
06487 sprintf(buf, "%d", mm);
06488 s->rows[roffs + 5] = xstrdup(buf);
06489 sprintf(buf, "%d", dd);
06490 s->rows[roffs + 6] = xstrdup(buf);
06491 if (notnullcc >= 0) {
06492 char *inp =
06493 rowppp[ii * nnncols + notnullcc];
06494
06495 isnullable = inp[0] != '0';
06496 }
06497 sprintf(buf, "%d", isnullable);
06498 s->rows[roffs + 8] = xstrdup(buf);
06499 }
06500 }
06501 }
06502 }
06503 }
06504 }
06505 offs += nnrows;
06506 sqlite3_free_table(rowpp);
06507 }
06508 }
06509 if (nullable == SQL_NO_NULLS) {
06510 for (i = 1; i < s->nrows; i++) {
06511 if (s->rows[i * s->ncols + 8][0] == '0') {
06512 int m, i1 = i + 1;
06513
06514 for (m = 0; m < s->ncols; m++) {
06515 freep(&s->rows[i * s->ncols + m]);
06516 }
06517 size = s->ncols * sizeof (char *) * (s->nrows - i1);
06518 if (size > 0) {
06519 memmove(s->rows + i * s->ncols,
06520 s->rows + i1 * s->ncols,
06521 size);
06522 memset(s->rows + s->nrows * s->ncols, 0,
06523 s->ncols * sizeof (char *));
06524 }
06525 s->nrows--;
06526 --i;
06527 }
06528 }
06529 }
06530 mkrowid:
06531 sqlite3_free_table(rowp);
06532 sqlite3_free_table(rowppp);
06533 if (s->nrows == 0) {
06534 s->rows[s->ncols + 0] = xstrdup(stringify(SQL_SCOPE_SESSION));
06535 s->rows[s->ncols + 1] = xstrdup("_ROWID_");
06536 s->rows[s->ncols + 2] = xstrdup(stringify(SQL_INTEGER));
06537 s->rows[s->ncols + 3] = xstrdup("integer");
06538 s->rows[s->ncols + 4] = xstrdup("0");
06539 s->rows[s->ncols + 5] = xstrdup("10");
06540 s->rows[s->ncols + 6] = xstrdup("9");
06541 s->rows[s->ncols + 7] = xstrdup(stringify(SQL_PC_PSEUDO));
06542 s->rows[s->ncols + 8] = xstrdup(stringify(SQL_FALSE));
06543 s->nrows = 1;
06544 }
06545 return SQL_SUCCESS;
06546 }
06547
06548 #ifndef WINTERFACE
06549
06564 SQLRETURN SQL_API
06565 SQLSpecialColumns(SQLHSTMT stmt, SQLUSMALLINT id,
06566 SQLCHAR *cat, SQLSMALLINT catLen,
06567 SQLCHAR *schema, SQLSMALLINT schemaLen,
06568 SQLCHAR *table, SQLSMALLINT tableLen,
06569 SQLUSMALLINT scope, SQLUSMALLINT nullable)
06570 {
06571 #if defined(_WIN32) || defined(_WIN64)
06572 char *c = NULL, *s = NULL, *t = NULL;
06573 #endif
06574 SQLRETURN ret;
06575
06576 HSTMT_LOCK(stmt);
06577 #if defined(_WIN32) || defined(_WIN64)
06578 if (!((STMT *) stmt)->oemcp[0]) {
06579 ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
06580 table, tableLen, scope, nullable);
06581 goto done2;
06582 }
06583 if (cat) {
06584 c = wmb_to_utf_c((char *) cat, catLen);
06585 if (!c) {
06586 ret = nomem((STMT *) stmt);
06587 goto done;
06588 }
06589 }
06590 if (schema) {
06591 s = wmb_to_utf_c((char *) schema, schemaLen);
06592 if (!s) {
06593 ret = nomem((STMT *) stmt);
06594 goto done;
06595 }
06596 }
06597 if (table) {
06598 t = wmb_to_utf_c((char *) table, tableLen);
06599 if (!t) {
06600 ret = nomem((STMT *) stmt);
06601 goto done;
06602 }
06603 }
06604 ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
06605 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
06606 scope, nullable);
06607 #else
06608 ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
06609 table, tableLen, scope, nullable);
06610 #endif
06611 #if defined(_WIN32) || defined(_WIN64)
06612 done:
06613 uc_free(t);
06614 uc_free(s);
06615 uc_free(c);
06616 done2:
06617 ;
06618 #endif
06619 HSTMT_UNLOCK(stmt);
06620 return ret;
06621 }
06622 #endif
06623
06624 #ifdef WINTERFACE
06625
06640 SQLRETURN SQL_API
06641 SQLSpecialColumnsW(SQLHSTMT stmt, SQLUSMALLINT id,
06642 SQLWCHAR *cat, SQLSMALLINT catLen,
06643 SQLWCHAR *schema, SQLSMALLINT schemaLen,
06644 SQLWCHAR *table, SQLSMALLINT tableLen,
06645 SQLUSMALLINT scope, SQLUSMALLINT nullable)
06646 {
06647 char *c = NULL, *s = NULL, *t = NULL;
06648 SQLRETURN ret;
06649
06650 HSTMT_LOCK(stmt);
06651 if (cat) {
06652 c = uc_to_utf_c(cat, catLen);
06653 if (!c) {
06654 ret = nomem((STMT *) stmt);
06655 goto done;
06656 }
06657 }
06658 if (schema) {
06659 s = uc_to_utf_c(schema, schemaLen);
06660 if (!s) {
06661 ret = nomem((STMT *) stmt);
06662 goto done;
06663 }
06664 }
06665 if (table) {
06666 t = uc_to_utf_c(table, tableLen);
06667 if (!t) {
06668 ret = nomem((STMT *) stmt);
06669 goto done;
06670 }
06671 }
06672 ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
06673 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
06674 scope, nullable);
06675 done:
06676 uc_free(t);
06677 uc_free(s);
06678 uc_free(c);
06679 HSTMT_UNLOCK(stmt);
06680 return ret;
06681 }
06682 #endif
06683
06688 static COL fkeySpec2[] = {
06689 { "SYSTEM", "FOREIGNKEY", "PKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
06690 { "SYSTEM", "FOREIGNKEY", "PKTABLE_OWNER", SCOL_VARCHAR, 50 },
06691 { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
06692 { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
06693 { "SYSTEM", "FOREIGNKEY", "FKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
06694 { "SYSTEM", "FOREIGNKEY", "FKTABLE_OWNER", SCOL_VARCHAR, 50 },
06695 { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
06696 { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
06697 { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
06698 { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
06699 { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
06700 { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
06701 { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
06702 { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
06703 };
06704
06705 static COL fkeySpec3[] = {
06706 { "SYSTEM", "FOREIGNKEY", "PKTABLE_CAT", SCOL_VARCHAR, 50 },
06707 { "SYSTEM", "FOREIGNKEY", "PKTABLE_SCHEM", SCOL_VARCHAR, 50 },
06708 { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
06709 { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
06710 { "SYSTEM", "FOREIGNKEY", "FKTABLE_CAT", SCOL_VARCHAR, 50 },
06711 { "SYSTEM", "FOREIGNKEY", "FKTABLE_SCHEM", SCOL_VARCHAR, 50 },
06712 { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
06713 { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
06714 { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
06715 { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
06716 { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
06717 { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
06718 { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
06719 { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
06720 };
06721
06740 static SQLRETURN SQL_API
06741 drvforeignkeys(SQLHSTMT stmt,
06742 SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
06743 SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
06744 SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
06745 SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
06746 SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
06747 SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
06748 {
06749 STMT *s;
06750 DBC *d;
06751 SQLRETURN sret;
06752 int i, asize, ret, nrows, ncols, offs, namec, seqc, fromc, toc;
06753 int onu, ond;
06754 PTRDIFF_T size;
06755 char **rowp, *errp = NULL, *sql, pname[512], fname[512];
06756
06757 sret = mkresultset(stmt, fkeySpec2, array_size(fkeySpec2),
06758 fkeySpec3, array_size(fkeySpec3), &asize);
06759 if (sret != SQL_SUCCESS) {
06760 return sret;
06761 }
06762 s = (STMT *) stmt;
06763 sret = starttran(s);
06764 if (sret != SQL_SUCCESS) {
06765 return sret;
06766 }
06767 d = (DBC *) s->dbc;
06768 if ((!PKtable || PKtable[0] == '\0' || PKtable[0] == '%') &&
06769 (!FKtable || FKtable[0] == '\0' || FKtable[0] == '%')) {
06770 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
06771 return SQL_ERROR;
06772 }
06773 size = 0;
06774 if (PKtable) {
06775 if (PKtableLen == SQL_NTS) {
06776 size = sizeof (pname) - 1;
06777 } else {
06778 size = min(sizeof (pname) - 1, PKtableLen);
06779 }
06780 strncpy(pname, (char *) PKtable, size);
06781 }
06782 pname[size] = '\0';
06783 size = 0;
06784 if (FKtable) {
06785
06786 if (FKtableLen == SQL_NTS) {
06787 size = sizeof (fname) - 1;
06788 } else {
06789 size = min(sizeof (fname) - 1, FKtableLen);
06790 }
06791 strncpy(fname, (char *) FKtable, size);
06792 }
06793 fname[size] = '\0';
06794 if (fname[0] != '\0') {
06795 int plen;
06796
06797 ret = SQLITE_ERROR;
06798 sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", fname);
06799 if (sql) {
06800 dbtraceapi(d, "sqlite3_get_table", sql);
06801 ret = sqlite3_get_table(d->sqlite, sql, &rowp,
06802 &nrows, &ncols, &errp);
06803 sqlite3_free(sql);
06804 }
06805 if (ret != SQLITE_OK) {
06806 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
06807 errp ? errp : "unknown error", ret);
06808 if (errp) {
06809 sqlite3_free(errp);
06810 errp = NULL;
06811 }
06812 return SQL_ERROR;
06813 }
06814 if (errp) {
06815 sqlite3_free(errp);
06816 errp = NULL;
06817 }
06818 if (ncols * nrows <= 0) {
06819 nodata:
06820 sqlite3_free_table(rowp);
06821 return SQL_SUCCESS;
06822 }
06823 size = 0;
06824 namec = findcol(rowp, ncols, "table");
06825 seqc = findcol(rowp, ncols, "seq");
06826 fromc = findcol(rowp, ncols, "from");
06827 toc = findcol(rowp, ncols, "to");
06828 onu = findcol(rowp, ncols, "on_update");
06829 ond = findcol(rowp, ncols, "on_delete");
06830 if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
06831 goto nodata;
06832 }
06833 plen = strlen(pname);
06834 for (i = 1; i <= nrows; i++) {
06835 char *ptab = unquote(rowp[i * ncols + namec]);
06836
06837 if (plen && ptab) {
06838 int len = strlen(ptab);
06839
06840 if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
06841 continue;
06842 }
06843 }
06844 size++;
06845 }
06846 if (size == 0) {
06847 goto nodata;
06848 }
06849 s->nrows = size;
06850 size = (size + 1) * asize;
06851 s->rows = xmalloc((size + 1) * sizeof (char *));
06852 if (!s->rows) {
06853 s->nrows = 0;
06854 return nomem(s);
06855 }
06856 s->rows[0] = (char *) size;
06857 s->rows += 1;
06858 memset(s->rows, 0, sizeof (char *) * size);
06859 s->rowfree = freerows;
06860 offs = 0;
06861 for (i = 1; i <= nrows; i++) {
06862 int pos = 0, roffs = (offs + 1) * s->ncols;
06863 char *ptab = rowp[i * ncols + namec];
06864 char buf[32];
06865
06866 if (plen && ptab) {
06867 int len = strlen(ptab);
06868
06869 if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
06870 continue;
06871 }
06872 }
06873 s->rows[roffs + 0] = xstrdup("");
06874 #if defined(_WIN32) || defined(_WIN64)
06875 s->rows[roffs + 1] = xstrdup(d->xcelqrx ? "main" : "");
06876 #else
06877 s->rows[roffs + 1] = xstrdup("");
06878 #endif
06879 s->rows[roffs + 2] = xstrdup(ptab);
06880 s->rows[roffs + 3] = xstrdup(rowp[i * ncols + toc]);
06881 s->rows[roffs + 4] = xstrdup("");
06882 s->rows[roffs + 5] = xstrdup("");
06883 s->rows[roffs + 6] = xstrdup(fname);
06884 s->rows[roffs + 7] = xstrdup(rowp[i * ncols + fromc]);
06885 sscanf(rowp[i * ncols + seqc], "%d", &pos);
06886 sprintf(buf, "%d", pos + 1);
06887 s->rows[roffs + 8] = xstrdup(buf);
06888 if (onu < 0) {
06889 s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
06890 } else {
06891 if (strcmp(rowp[i * ncols + onu], "SET NULL") == 0) {
06892 s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
06893 } else if (strcmp(rowp[i * ncols + onu], "SET DEFAULT") == 0) {
06894 s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_DEFAULT));
06895 } else if (strcmp(rowp[i * ncols + onu], "CASCADE") == 0) {
06896 s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
06897 } else if (strcmp(rowp[i * ncols + onu], "RESTRICT") == 0) {
06898 s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
06899 } else {
06900 s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
06901 }
06902 }
06903 if (ond < 0) {
06904 s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
06905 } else {
06906 if (strcmp(rowp[i * ncols + ond], "SET NULL") == 0) {
06907 s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
06908 } else if (strcmp(rowp[i * ncols + ond], "SET DEFAULT") == 0) {
06909 s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_DEFAULT));
06910 } else if (strcmp(rowp[i * ncols + ond], "CASCADE") == 0) {
06911 s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
06912 } else if (strcmp(rowp[i * ncols + ond], "RESTRICT") == 0) {
06913 s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
06914 } else {
06915 s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
06916 }
06917 }
06918 s->rows[roffs + 11] = NULL;
06919 s->rows[roffs + 12] = NULL;
06920 s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
06921 offs++;
06922 }
06923 sqlite3_free_table(rowp);
06924 } else {
06925 int nnrows, nncols, plen = strlen(pname);
06926 char **rowpp;
06927
06928 sql = "select name from sqlite_master where type='table'";
06929 dbtraceapi(d, "sqlite3_get_table", sql);
06930 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
06931 if (ret != SQLITE_OK) {
06932 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
06933 errp ? errp : "unknown error", ret);
06934 if (errp) {
06935 sqlite3_free(errp);
06936 errp = NULL;
06937 }
06938 return SQL_ERROR;
06939 }
06940 if (errp) {
06941 sqlite3_free(errp);
06942 errp = NULL;
06943 }
06944 if (ncols * nrows <= 0) {
06945 goto nodata;
06946 }
06947 size = 0;
06948 for (i = 1; i <= nrows; i++) {
06949 int k;
06950
06951 if (!rowp[i]) {
06952 continue;
06953 }
06954 rowpp = NULL;
06955 ret = SQLITE_ERROR;
06956 sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
06957 if (sql) {
06958 dbtraceapi(d, "sqlite3_get_table", sql);
06959 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
06960 &nnrows, &nncols, NULL);
06961 sqlite3_free(sql);
06962 }
06963 if (ret != SQLITE_OK || nncols * nnrows <= 0) {
06964 sqlite3_free_table(rowpp);
06965 continue;
06966 }
06967 namec = findcol(rowpp, nncols, "table");
06968 seqc = findcol(rowpp, nncols, "seq");
06969 fromc = findcol(rowpp, nncols, "from");
06970 toc = findcol(rowpp, nncols, "to");
06971 if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
06972 sqlite3_free_table(rowpp);
06973 continue;
06974 }
06975 for (k = 1; k <= nnrows; k++) {
06976 char *ptab = unquote(rowpp[k * nncols + namec]);
06977
06978 if (plen && ptab) {
06979 int len = strlen(ptab);
06980
06981 if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
06982 continue;
06983 }
06984 }
06985 size++;
06986 }
06987 sqlite3_free_table(rowpp);
06988 }
06989 if (size == 0) {
06990 goto nodata;
06991 }
06992 s->nrows = size;
06993 size = (size + 1) * asize;
06994 s->rows = xmalloc((size + 1) * sizeof (char *));
06995 if (!s->rows) {
06996 s->nrows = 0;
06997 return nomem(s);
06998 }
06999 s->rows[0] = (char *) size;
07000 s->rows += 1;
07001 memset(s->rows, 0, sizeof (char *) * size);
07002 s->rowfree = freerows;
07003 offs = 0;
07004 for (i = 1; i <= nrows; i++) {
07005 int k;
07006
07007 if (!rowp[i]) {
07008 continue;
07009 }
07010 rowpp = NULL;
07011 ret = SQLITE_ERROR;
07012 sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
07013 if (sql) {
07014 dbtraceapi(d, "sqlite3_get_table", sql);
07015 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
07016 &nnrows, &nncols, NULL);
07017 sqlite3_free(sql);
07018 }
07019 if (ret != SQLITE_OK || nncols * nnrows <= 0) {
07020 sqlite3_free_table(rowpp);
07021 continue;
07022 }
07023 namec = findcol(rowpp, nncols, "table");
07024 seqc = findcol(rowpp, nncols, "seq");
07025 fromc = findcol(rowpp, nncols, "from");
07026 toc = findcol(rowpp, nncols, "to");
07027 onu = findcol(rowpp, nncols, "on_update");
07028 ond = findcol(rowpp, nncols, "on_delete");
07029 if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
07030 sqlite3_free_table(rowpp);
07031 continue;
07032 }
07033 for (k = 1; k <= nnrows; k++) {
07034 int pos = 0, roffs = (offs + 1) * s->ncols;
07035 char *ptab = unquote(rowpp[k * nncols + namec]);
07036 char buf[32];
07037
07038 if (plen && ptab) {
07039 int len = strlen(ptab);
07040
07041 if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
07042 continue;
07043 }
07044 }
07045 s->rows[roffs + 0] = xstrdup("");
07046 #if defined(_WIN32) || defined(_WIN64)
07047 s->rows[roffs + 1] = xstrdup(d->xcelqrx ? "main" : "");
07048 #else
07049 s->rows[roffs + 1] = xstrdup("");
07050 #endif
07051 s->rows[roffs + 2] = xstrdup(ptab);
07052 s->rows[roffs + 3] = xstrdup(rowpp[k * nncols + toc]);
07053 s->rows[roffs + 4] = xstrdup("");
07054 s->rows[roffs + 5] = xstrdup("");
07055 s->rows[roffs + 6] = xstrdup(rowp[i]);
07056 s->rows[roffs + 7] = xstrdup(rowpp[k * nncols + fromc]);
07057 sscanf(rowpp[k * nncols + seqc], "%d", &pos);
07058 sprintf(buf, "%d", pos + 1);
07059 s->rows[roffs + 8] = xstrdup(buf);
07060 if (onu < 0) {
07061 s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
07062 } else {
07063 if (strcmp(rowpp[k * nncols + onu], "SET NULL") == 0) {
07064 s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
07065 } else if (strcmp(rowpp[k * nncols + onu], "SET DEFAULT")
07066 == 0) {
07067 s->rows[roffs + 9] =
07068 xstrdup(stringify(SQL_SET_DEFAULT));
07069 } else if (strcmp(rowpp[k * nncols + onu], "CASCADE")
07070 == 0) {
07071 s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
07072 } else if (strcmp(rowpp[k * nncols + onu], "RESTRICT")
07073 == 0) {
07074 s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
07075 } else {
07076 s->rows[roffs + 9] =
07077 xstrdup(stringify(SQL_NO_ACTION));
07078 }
07079 }
07080 if (ond < 0) {
07081 s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
07082 } else {
07083 if (strcmp(rowpp[k * nncols + ond], "SET NULL") == 0) {
07084 s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
07085 } else if (strcmp(rowpp[k * nncols + ond], "SET DEFAULT")
07086 == 0) {
07087 s->rows[roffs + 10] =
07088 xstrdup(stringify(SQL_SET_DEFAULT));
07089 } else if (strcmp(rowpp[k * nncols + ond], "CASCADE")
07090 == 0) {
07091 s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
07092 } else if (strcmp(rowpp[k * nncols + ond], "RESTRICT")
07093 == 0) {
07094 s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
07095 } else {
07096 s->rows[roffs + 10] =
07097 xstrdup(stringify(SQL_NO_ACTION));
07098 }
07099 }
07100 s->rows[roffs + 11] = NULL;
07101 s->rows[roffs + 12] = NULL;
07102 s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
07103 offs++;
07104 }
07105 sqlite3_free_table(rowpp);
07106 }
07107 sqlite3_free_table(rowp);
07108 }
07109 return SQL_SUCCESS;
07110 }
07111
07112 #ifndef WINTERFACE
07113
07131 SQLRETURN SQL_API
07132 SQLForeignKeys(SQLHSTMT stmt,
07133 SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
07134 SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
07135 SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
07136 SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
07137 SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
07138 SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
07139 {
07140 #if defined(_WIN32) || defined(_WIN64)
07141 char *pc = NULL, *ps = NULL, *pt = NULL;
07142 char *fc = NULL, *fs = NULL, *ft = NULL;
07143 #endif
07144 SQLRETURN ret;
07145
07146 HSTMT_LOCK(stmt);
07147 #if defined(_WIN32) || defined(_WIN64)
07148 if (!((STMT *) stmt)->oemcp[0]) {
07149 ret = drvforeignkeys(stmt,
07150 PKcatalog, PKcatalogLen,
07151 PKschema, PKschemaLen, PKtable, PKtableLen,
07152 FKcatalog, FKcatalogLen,
07153 FKschema, FKschemaLen,
07154 FKtable, FKtableLen);
07155 goto done2;
07156 }
07157 if (PKcatalog) {
07158 pc = wmb_to_utf_c((char *) PKcatalog, PKcatalogLen);
07159 if (!pc) {
07160 ret = nomem((STMT *) stmt);
07161 goto done;
07162 }
07163 }
07164 if (PKschema) {
07165 ps = wmb_to_utf_c((char *) PKschema, PKschemaLen);
07166 if (!ps) {
07167 ret = nomem((STMT *) stmt);
07168 goto done;
07169 }
07170 }
07171 if (PKtable) {
07172 pt = wmb_to_utf_c((char *) PKtable, PKtableLen);
07173 if (!pt) {
07174 ret = nomem((STMT *) stmt);
07175 goto done;
07176 }
07177 }
07178 if (FKcatalog) {
07179 fc = wmb_to_utf_c((char *) FKcatalog, FKcatalogLen);
07180 if (!fc) {
07181 ret = nomem((STMT *) stmt);
07182 goto done;
07183 }
07184 }
07185 if (FKschema) {
07186 fs = wmb_to_utf_c((char *) FKschema, FKschemaLen);
07187 if (!fs) {
07188 ret = nomem((STMT *) stmt);
07189 goto done;
07190 }
07191 }
07192 if (FKtable) {
07193 ft = wmb_to_utf_c((char *) FKtable, FKtableLen);
07194 if (!ft) {
07195 ret = nomem((STMT *) stmt);
07196 goto done;
07197 }
07198 }
07199 ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
07200 (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
07201 (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
07202 (SQLCHAR *) ft, SQL_NTS);
07203 #else
07204 ret = drvforeignkeys(stmt,
07205 PKcatalog, PKcatalogLen,
07206 PKschema, PKschemaLen, PKtable, PKtableLen,
07207 FKcatalog, FKcatalogLen,
07208 FKschema, FKschemaLen,
07209 FKtable, FKtableLen);
07210 #endif
07211 #if defined(_WIN32) || defined(_WIN64)
07212 done:
07213 uc_free(ft);
07214 uc_free(fs);
07215 uc_free(fc);
07216 uc_free(pt);
07217 uc_free(ps);
07218 uc_free(pc);
07219 done2:
07220 ;
07221 #endif
07222 HSTMT_UNLOCK(stmt);
07223 return ret;
07224 }
07225 #endif
07226
07227 #ifdef WINTERFACE
07228
07246 SQLRETURN SQL_API
07247 SQLForeignKeysW(SQLHSTMT stmt,
07248 SQLWCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
07249 SQLWCHAR *PKschema, SQLSMALLINT PKschemaLen,
07250 SQLWCHAR *PKtable, SQLSMALLINT PKtableLen,
07251 SQLWCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
07252 SQLWCHAR *FKschema, SQLSMALLINT FKschemaLen,
07253 SQLWCHAR *FKtable, SQLSMALLINT FKtableLen)
07254 {
07255 char *pc = NULL, *ps = NULL, *pt = NULL;
07256 char *fc = NULL, *fs = NULL, *ft = NULL;
07257 SQLRETURN ret;
07258
07259 HSTMT_LOCK(stmt);
07260 if (PKcatalog) {
07261 pc = uc_to_utf_c(PKcatalog, PKcatalogLen);
07262 if (!pc) {
07263 ret = nomem((STMT *) stmt);
07264 goto done;
07265 }
07266 }
07267 if (PKschema) {
07268 ps = uc_to_utf_c(PKschema, PKschemaLen);
07269 if (!ps) {
07270 ret = nomem((STMT *) stmt);
07271 goto done;
07272 }
07273 }
07274 if (PKtable) {
07275 pt = uc_to_utf_c(PKtable, PKtableLen);
07276 if (!pt) {
07277 ret = nomem((STMT *) stmt);
07278 goto done;
07279 }
07280 }
07281 if (FKcatalog) {
07282 fc = uc_to_utf_c(FKcatalog, FKcatalogLen);
07283 if (!fc) {
07284 ret = nomem((STMT *) stmt);
07285 goto done;
07286 }
07287 }
07288 if (FKschema) {
07289 fs = uc_to_utf_c(FKschema, FKschemaLen);
07290 if (!fs) {
07291 ret = nomem((STMT *) stmt);
07292 goto done;
07293 }
07294 }
07295 if (FKtable) {
07296 ft = uc_to_utf_c(FKtable, FKtableLen);
07297 if (!ft) {
07298 ret = nomem((STMT *) stmt);
07299 goto done;
07300 }
07301 }
07302 ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
07303 (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
07304 (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
07305 (SQLCHAR *) ft, SQL_NTS);
07306 done:
07307 uc_free(ft);
07308 uc_free(fs);
07309 uc_free(fc);
07310 uc_free(pt);
07311 uc_free(ps);
07312 uc_free(pc);
07313 HSTMT_UNLOCK(stmt);
07314 return ret;
07315 }
07316 #endif
07317
07324 static SQLRETURN
07325 starttran(STMT *s)
07326 {
07327 int ret = SQL_SUCCESS, rc, busy_count = 0;
07328 char *errp = NULL;
07329 DBC *d = (DBC *) s->dbc;
07330
07331 if (!d->autocommit && !d->intrans && !d->trans_disable) {
07332 begin_again:
07333 rc = sqlite3_exec(d->sqlite, "BEGIN TRANSACTION", NULL, NULL, &errp);
07334 if (rc == SQLITE_BUSY) {
07335 if (busy_handler((void *) d, ++busy_count)) {
07336 if (errp) {
07337 sqlite3_free(errp);
07338 errp = NULL;
07339 }
07340 goto begin_again;
07341 }
07342 }
07343 dbtracerc(d, rc, errp);
07344 if (rc != SQLITE_OK) {
07345 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
07346 errp ? errp : "unknown error", rc);
07347 ret = SQL_ERROR;
07348 } else {
07349 d->intrans = 1;
07350 }
07351 if (errp) {
07352 sqlite3_free(errp);
07353 errp = NULL;
07354 }
07355 }
07356 return ret;
07357 }
07358
07367 static SQLRETURN
07368 endtran(DBC *d, SQLSMALLINT comptype, int force)
07369 {
07370 int ret, busy_count = 0;
07371 char *sql, *errp = NULL;
07372
07373 if (!d->sqlite) {
07374 setstatd(d, -1, "not connected", (*d->ov3) ? "HY000" : "S1000");
07375 return SQL_ERROR;
07376 }
07377 if ((!force && d->autocommit) || !d->intrans) {
07378 return SQL_SUCCESS;
07379 }
07380 switch (comptype) {
07381 case SQL_COMMIT:
07382 sql = "COMMIT TRANSACTION";
07383 goto doit;
07384 case SQL_ROLLBACK:
07385 sql = "ROLLBACK TRANSACTION";
07386 doit:
07387 ret = sqlite3_exec(d->sqlite, sql, NULL, NULL, &errp);
07388 dbtracerc(d, ret, errp);
07389 if (ret == SQLITE_BUSY && busy_count < 10) {
07390 if (busy_handler((void *) d, ++busy_count)) {
07391 if (errp) {
07392 sqlite3_free(errp);
07393 errp = NULL;
07394 }
07395 goto doit;
07396 }
07397 }
07398 d->intrans = 0;
07399 if (ret != SQLITE_OK) {
07400 setstatd(d, ret, "%s", (*d->ov3) ? "HY000" : "S1000",
07401 errp ? errp : "transaction failed");
07402 if (errp) {
07403 sqlite3_free(errp);
07404 errp = NULL;
07405 }
07406 return SQL_ERROR;
07407 }
07408 if (errp) {
07409 sqlite3_free(errp);
07410 errp = NULL;
07411 }
07412 return SQL_SUCCESS;
07413 }
07414 setstatd(d, -1, "invalid completion type", (*d->ov3) ? "HY000" : "S1000");
07415 return SQL_ERROR;
07416 }
07417
07426 static SQLRETURN
07427 drvendtran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
07428 {
07429 DBC *d;
07430 int fail = 0;
07431 SQLRETURN ret;
07432 #if defined(_WIN32) || defined(_WIN64)
07433 ENV *e;
07434 #endif
07435
07436 switch (type) {
07437 case SQL_HANDLE_DBC:
07438 HDBC_LOCK((SQLHDBC) handle);
07439 if (handle == SQL_NULL_HDBC) {
07440 return SQL_INVALID_HANDLE;
07441 }
07442 d = (DBC *) handle;
07443 ret = endtran(d, comptype, 0);
07444 HDBC_UNLOCK((SQLHDBC) handle);
07445 return ret;
07446 case SQL_HANDLE_ENV:
07447 if (handle == SQL_NULL_HENV) {
07448 return SQL_INVALID_HANDLE;
07449 }
07450 #if defined(_WIN32) || defined(_WIN64)
07451 e = (ENV *) handle;
07452 if (e->magic != ENV_MAGIC) {
07453 return SQL_INVALID_HANDLE;
07454 }
07455 EnterCriticalSection(&e->cs);
07456 e->owner = GetCurrentThreadId();
07457 #endif
07458 d = ((ENV *) handle)->dbcs;
07459 while (d) {
07460 ret = endtran(d, comptype, 0);
07461 if (ret != SQL_SUCCESS) {
07462 fail++;
07463 }
07464 d = d->next;
07465 }
07466 #if defined(_WIN32) || defined(_WIN64)
07467 e->owner = 0;
07468 LeaveCriticalSection(&e->cs);
07469 #endif
07470 return fail ? SQL_ERROR : SQL_SUCCESS;
07471 }
07472 return SQL_INVALID_HANDLE;
07473 }
07474
07483 SQLRETURN SQL_API
07484 SQLEndTran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
07485 {
07486 return drvendtran(type, handle, comptype);
07487 }
07488
07497 SQLRETURN SQL_API
07498 SQLTransact(SQLHENV env, SQLHDBC dbc, SQLUSMALLINT type)
07499 {
07500 if (env != SQL_NULL_HENV) {
07501 return drvendtran(SQL_HANDLE_ENV, (SQLHANDLE) env, type);
07502 }
07503 return drvendtran(SQL_HANDLE_DBC, (SQLHANDLE) dbc, type);
07504 }
07505
07510 SQLRETURN SQL_API
07511 SQLCopyDesc(SQLHDESC source, SQLHDESC target)
07512 {
07513 return SQL_ERROR;
07514 }
07515
07516 #ifndef WINTERFACE
07517
07528 SQLRETURN SQL_API
07529 SQLNativeSql(SQLHSTMT stmt, SQLCHAR *sqlin, SQLINTEGER sqlinLen,
07530 SQLCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
07531 {
07532 int outLen = 0;
07533 SQLRETURN ret = SQL_SUCCESS;
07534
07535 HSTMT_LOCK(stmt);
07536 if (sqlinLen == SQL_NTS) {
07537 sqlinLen = strlen((char *) sqlin);
07538 }
07539 if (sql) {
07540 if (sqlMax > 0) {
07541 strncpy((char *) sql, (char *) sqlin, sqlMax - 1);
07542 sqlin[sqlMax - 1] = '\0';
07543 outLen = min(sqlMax - 1, sqlinLen);
07544 }
07545 } else {
07546 outLen = sqlinLen;
07547 }
07548 if (sqlLen) {
07549 *sqlLen = outLen;
07550 }
07551 if (sql && outLen < sqlinLen) {
07552 setstat((STMT *) stmt, -1, "data right truncated", "01004");
07553 ret = SQL_SUCCESS_WITH_INFO;
07554 }
07555 HSTMT_UNLOCK(stmt);
07556 return ret;
07557 }
07558 #endif
07559
07560 #ifdef WINTERFACE
07561
07572 SQLRETURN SQL_API
07573 SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen,
07574 SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
07575 {
07576 int outLen = 0;
07577 SQLRETURN ret = SQL_SUCCESS;
07578
07579 HSTMT_LOCK(stmt);
07580 if (sqlinLen == SQL_NTS) {
07581 sqlinLen = uc_strlen(sqlin);
07582 }
07583 if (sql) {
07584 if (sqlMax > 0) {
07585 uc_strncpy(sql, sqlin, sqlMax - 1);
07586 sqlin[sqlMax - 1] = 0;
07587 outLen = min(sqlMax - 1, sqlinLen);
07588 }
07589 } else {
07590 outLen = sqlinLen;
07591 }
07592 if (sqlLen) {
07593 *sqlLen = outLen;
07594 }
07595 if (sql && outLen < sqlinLen) {
07596 setstat((STMT *) stmt, -1, "data right truncated", "01004");
07597 ret = SQL_SUCCESS_WITH_INFO;
07598 }
07599 HSTMT_UNLOCK(stmt);
07600 return ret;
07601 }
07602 #endif
07603
07608 static COL procSpec2[] = {
07609 { "SYSTEM",