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, sqlite_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 double (*column_double)(sqlite3_stmt *p0, int p1);
00058 const char * (*column_name)(sqlite3_stmt *p0, int p1);
00059 const char * (*column_origin_name)(sqlite3_stmt *p0, int p1);
00060 const char * (*column_table_name)(sqlite3_stmt *p0, int p1);
00061 const unsigned char * (*column_text)(sqlite3_stmt *p0, int p1);
00062 int (*column_type)(sqlite3_stmt *p0, int p1);
00063 int (*create_function)(sqlite3 *p0, const char *p1, int p2, int p3,
00064 void *p4,
00065 void (*p5)(sqlite3_context *, int, sqlite3_value **),
00066 void (*p6)(sqlite3_context *, int, sqlite3_value **),
00067 void (*p7)(sqlite3_context *));
00068 int (*enable_load_extension)(sqlite3 *p0, int p1);
00069 int (*errcode)(sqlite3 *p0);
00070 const char * (*errmsg)(sqlite3 *p0);
00071 int (*exec)(sqlite3 *p0, const char *p1,
00072 int (*p2)(void *, int, char **, char **),
00073 void *p3, char **p4);
00074 int (*finalize)(sqlite3_stmt *p0);
00075 void (*free)(void *p0);
00076 void (*free_table)(char **p0);
00077 int (*get_table)(sqlite3 *p0, const char *p1, char ***p2,
00078 int *p3, int *p4, char **p5);
00079 void (*interrupt)(sqlite3 *p0);
00080 int (*key)(sqlite3 *p0, const void *p1, int p2);
00081 const char * (*libversion)(void);
00082 int (*load_extension)(sqlite3 *p0, const char *p1, const char *p2,
00083 char **p3);
00084 void * (*malloc)(int p0);
00085 char * (*mprintf)(const char *p0, ...);
00086 int (*open)(const char *p0, sqlite3 **p1);
00087 int (*open16)(const void *p0, sqlite3 **p1);
00088 int (*open_v2)(const char *p0, sqlite3 **p1, int p2, const char *p3);
00089 int (*prepare)(sqlite3 *p0, const char *p1, int p2, sqlite3_stmt **p3,
00090 const char **p4);
00091 int (*prepare_v2)(sqlite3 *p0, const char *p1, int p2, sqlite3_stmt **p3,
00092 const char **p4);
00093 void * (*profile)(sqlite3 *p0,
00094 void (*p1)(void *, const char *, sqlite3_uint64),
00095 void *p2);
00096 void * (*realloc)(void *p0, int p1);
00097 int (*rekey)(sqlite3 *p0, const void *p1, int p2);
00098 int (*reset)(sqlite3_stmt *p0);
00099 void (*result_blob)(sqlite3_context *p0, const void *p1,
00100 int p2, void (*p3)(void *));
00101 void (*result_error)(sqlite3_context *p0, const char *p1, int p2);
00102 void (*result_int)(sqlite3_context *p0, int p1);
00103 void (*result_null)(sqlite3_context *p0);
00104 int (*step)(sqlite3_stmt *p0);
00105 int (*xstrnicmp)(const char *p0, const char *p1, int p2);
00106 int (*table_column_metadata)(sqlite3 *p0, const char *p1,
00107 const char *p2, const char *p3,
00108 char const **p4, char const **p5,
00109 int *p6, int *p7, int *p8);
00110 void * (*trace)(sqlite3 *p0, void (*p1)(void *, const char *), void *p2);
00111 void * (*user_data)(sqlite3_context *p0);
00112 const void * (*value_blob)(sqlite3_value *p0);
00113 int (*value_bytes)(sqlite3_value *p0);
00114 const unsigned char * (*value_text)(sqlite3_value *p0);
00115 int (*value_type)(sqlite3_value *p0);
00116 } dls_funcs;
00117
00118 #define sqlite3_activate_see dls_funcs.activate_see
00119 #define sqlite3_bind_blob dls_funcs.bind_blob
00120 #define sqlite3_bind_double dls_funcs.bind_double
00121 #define sqlite3_bind_int dls_funcs.bind_int
00122 #define sqlite3_bind_int64 dls_funcs.bind_int64
00123 #define sqlite3_bind_null dls_funcs.bind_null
00124 #define sqlite3_bind_parameter_count dls_funcs.bind_parameter_count
00125 #define sqlite3_bind_text dls_funcs.bind_text
00126 #define sqlite3_busy_handler dls_funcs.busy_handler
00127 #define sqlite3_changes dls_funcs.changes
00128 #define sqlite3_close dls_funcs.close
00129 #define sqlite3_column_blob dls_funcs.column_blob
00130 #define sqlite3_column_bytes dls_funcs.column_bytes
00131 #define sqlite3_column_count dls_funcs.column_count
00132 #define sqlite3_column_database_name dls_funcs.column_database_name
00133 #define sqlite3_column_decltype dls_funcs.column_decltype
00134 #define sqlite3_column_double dls_funcs.column_double
00135 #define sqlite3_column_name dls_funcs.column_name
00136 #define sqlite3_column_origin_name dls_funcs.column_origin_name
00137 #define sqlite3_column_table_name dls_funcs.column_table_name
00138 #define sqlite3_column_text dls_funcs.column_text
00139 #define sqlite3_column_type dls_funcs.column_type
00140 #define sqlite3_create_function dls_funcs.create_function
00141 #define sqlite3_enable_load_extension dls_funcs.enable_load_extension
00142 #define sqlite3_errcode dls_funcs.errcode
00143 #define sqlite3_errmsg dls_funcs.errmsg
00144 #define sqlite3_exec dls_funcs.exec
00145 #define sqlite3_finalize dls_funcs.finalize
00146 #define sqlite3_free dls_funcs.free
00147 #define sqlite3_free_table dls_funcs.free_table
00148 #define sqlite3_get_table dls_funcs.get_table
00149 #define sqlite3_interrupt dls_funcs.interrupt
00150 #define sqlite3_key dls_funcs.key
00151 #define sqlite3_libversion dls_funcs.libversion
00152 #define sqlite3_load_extension dls_funcs.load_extension
00153 #define sqlite3_malloc dls_funcs.malloc
00154 #define sqlite3_mprintf dls_funcs.mprintf
00155 #define sqlite3_open dls_funcs.open
00156 #define sqlite3_open16 dls_funcs.open16
00157 #define sqlite3_open_v2 dls_funcs.open_v2
00158 #define sqlite3_prepare dls_funcs.prepare
00159 #define sqlite3_prepare_v2 dls_funcs.prepare_v2
00160 #define sqlite3_profile dls_funcs.profile
00161 #define sqlite3_realloc dls_funcs.realloc
00162 #define sqlite3_rekey dls_funcs.rekey
00163 #define sqlite3_reset dls_funcs.reset
00164 #define sqlite3_result_blob dls_funcs.result_blob
00165 #define sqlite3_result_error dls_funcs.result_error
00166 #define sqlite3_result_int dls_funcs.result_int
00167 #define sqlite3_result_null dls_funcs.result_null
00168 #define sqlite3_step dls_funcs.step
00169 #define sqlite3_strnicmp dls_funcs.xstrnicmp
00170 #define sqlite3_table_column_metadata dls_funcs.table_column_metadata
00171 #define sqlite3_trace dls_funcs.trace
00172 #define sqlite3_user_data dls_funcs.user_data
00173 #define sqlite3_value_blob dls_funcs.value_blob
00174 #define sqlite3_value_bytes dls_funcs.value_bytes
00175 #define sqlite3_value_text dls_funcs.value_text
00176 #define sqlite3_value_type dls_funcs.value_type
00177
00178 #endif
00179
00180 #ifndef WITHOUT_WINTERFACE
00181 #define WINTERFACE
00182 #define WCHARSUPPORT
00183 #endif
00184
00185 #if !defined(_WIN32) && !defined(_WIN64)
00186 #if !defined(WCHARSUPPORT) && defined(HAVE_SQLWCHAR) && (HAVE_SQLWCHAR)
00187 #define WCHARSUPPORT
00188 #endif
00189 #endif
00190
00191 #if defined(WINTERFACE)
00192 #include <sqlucode.h>
00193 #endif
00194
00195 #if defined(_WIN32) || defined(_WIN64)
00196 #include "resource3.h"
00197 #define ODBC_INI "ODBC.INI"
00198 #ifndef DRIVER_VER_INFO
00199 #define DRIVER_VER_INFO VERSION
00200 #endif
00201 #else
00202 #define ODBC_INI ".odbc.ini"
00203 #endif
00204
00205 #ifndef DRIVER_VER_INFO
00206 #define DRIVER_VER_INFO "0.0"
00207 #endif
00208
00209 #ifndef COLATTRIBUTE_LAST_ARG_TYPE
00210 #ifdef _WIN64
00211 #define COLATTRIBUTE_LAST_ARG_TYPE SQLLEN *
00212 #else
00213 #define COLATTRIBUTE_LAST_ARG_TYPE SQLPOINTER
00214 #endif
00215 #endif
00216
00217 #ifndef SETSTMTOPTION_LAST_ARG_TYPE
00218 #define SETSTMTOPTION_LAST_ARG_TYPE SQLROWCOUNT
00219 #endif
00220
00221 #undef min
00222 #define min(a, b) ((a) < (b) ? (a) : (b))
00223 #undef max
00224 #define max(a, b) ((a) < (b) ? (b) : (a))
00225
00226 #ifndef PTRDIFF_T
00227 #define PTRDIFF_T int
00228 #endif
00229
00230 #define array_size(x) (sizeof (x) / sizeof (x[0]))
00231
00232 #define stringify1(s) #s
00233 #define stringify(s) stringify1(s)
00234
00235 #define verinfo(maj, min, lev) ((maj) << 16 | (min) << 8 | (lev))
00236
00237
00238
00239 #if defined(WINTERFACE) && !defined(_WIN32) && !defined(_WIN64)
00240 #define SCOL_VARCHAR SQL_WVARCHAR
00241 #define SCOL_CHAR SQL_WCHAR
00242 #else
00243 #define SCOL_VARCHAR SQL_VARCHAR
00244 #define SCOL_CHAR SQL_CHAR
00245 #endif
00246
00247 #define ENV_MAGIC 0x53544145
00248 #define DBC_MAGIC 0x53544144
00249 #define DEAD_MAGIC 0xdeadbeef
00250
00251 static const char *xdigits = "0123456789ABCDEFabcdef";
00252
00253 #ifdef MEMORY_DEBUG
00254
00255 static void *
00256 xmalloc_(int n, char *file, int line)
00257 {
00258 int nn = n + 4 * sizeof (long);
00259 long *p;
00260
00261 p = malloc(nn);
00262 if (!p) {
00263 #if (MEMORY_DEBUG > 1)
00264 fprintf(stderr, "malloc\t%d\tNULL\t%s:%d\n", n, file, line);
00265 #endif
00266 return NULL;
00267 }
00268 p[0] = 0xdead1234;
00269 nn = nn / sizeof (long) - 1;
00270 p[1] = n;
00271 p[nn] = 0xdead5678;
00272 #if (MEMORY_DEBUG > 1)
00273 fprintf(stderr, "malloc\t%d\t%p\t%s:%d\n", n, &p[2], file, line);
00274 #endif
00275 return (void *) &p[2];
00276 }
00277
00278 static void *
00279 xrealloc_(void *old, int n, char *file, int line)
00280 {
00281 int nn = n + 4 * sizeof (long), nnn;
00282 long *p, *pp;
00283
00284 if (n == 0 || !old) {
00285 return xmalloc_(n, file, line);
00286 }
00287 p = &((long *) old)[-2];
00288 if (p[0] != 0xdead1234) {
00289 fprintf(stderr, "*** low end corruption @ %p\n", old);
00290 abort();
00291 }
00292 nnn = p[1] + 4 * sizeof (long);
00293 nnn = nnn / sizeof (long) - 1;
00294 if (p[nnn] != 0xdead5678) {
00295 fprintf(stderr, "*** high end corruption @ %p\n", old);
00296 abort();
00297 }
00298 pp = realloc(p, nn);
00299 if (!pp) {
00300 #if (MEMORY_DEBUG > 1)
00301 fprintf(stderr, "realloc\t%p,%d\tNULL\t%s:%d\n", old, n, file, line);
00302 #endif
00303 return NULL;
00304 }
00305 #if (MEMORY_DEBUG > 1)
00306 fprintf(stderr, "realloc\t%p,%d\t%p\t%s:%d\n", old, n, &pp[2], file, line);
00307 #endif
00308 p = pp;
00309 p[1] = n;
00310 nn = nn / sizeof (long) - 1;
00311 p[nn] = 0xdead5678;
00312 return (void *) &p[2];
00313 }
00314
00315 static void
00316 xfree_(void *x, char *file, int line)
00317 {
00318 long *p;
00319 int n;
00320
00321 if (!x) {
00322 return;
00323 }
00324 p = &((long *) x)[-2];
00325 if (p[0] != 0xdead1234) {
00326 fprintf(stderr, "*** low end corruption @ %p\n", x);
00327 abort();
00328 }
00329 n = p[1] + 4 * sizeof (long);
00330 n = n / sizeof (long) - 1;
00331 if (p[n] != 0xdead5678) {
00332 fprintf(stderr, "*** high end corruption @ %p\n", x);
00333 abort();
00334 }
00335 #if (MEMORY_DEBUG > 1)
00336 fprintf(stderr, "free\t%p\t\t%s:%d\n", x, file, line);
00337 #endif
00338 free(p);
00339 }
00340
00341 static void
00342 xfree__(void *x)
00343 {
00344 xfree_(x, "unknown location", 0);
00345 }
00346
00347 static char *
00348 xstrdup_(const char *str, char *file, int line)
00349 {
00350 char *p;
00351
00352 if (!str) {
00353 #if (MEMORY_DEBUG > 1)
00354 fprintf(stderr, "strdup\tNULL\tNULL\t%s:%d\n", file, line);
00355 #endif
00356 return NULL;
00357 }
00358 p = xmalloc_(strlen(str) + 1, file, line);
00359 if (p) {
00360 strcpy(p, str);
00361 }
00362 #if (MEMORY_DEBUG > 1)
00363 fprintf(stderr, "strdup\t%p\t%p\t%s:%d\n", str, p, file, line);
00364 #endif
00365 return p;
00366 }
00367
00368 #define xmalloc(x) xmalloc_(x, __FILE__, __LINE__)
00369 #define xrealloc(x,y) xrealloc_(x, y, __FILE__, __LINE__)
00370 #define xfree(x) xfree_(x, __FILE__, __LINE__)
00371 #define xstrdup(x) xstrdup_(x, __FILE__, __LINE__)
00372
00373 #else
00374
00375 #define xmalloc(x) sqlite3_malloc(x)
00376 #define xrealloc(x,y) sqlite3_realloc(x, y)
00377 #define xfree(x) sqlite3_free(x)
00378 #define xstrdup(x) strdup_(x)
00379
00380 #endif
00381
00382 #if defined(_WIN32) || defined(_WIN64)
00383
00384 #define vsnprintf _vsnprintf
00385 #define snprintf _snprintf
00386 #define strcasecmp _stricmp
00387 #define strncasecmp _strnicmp
00388
00389 static HINSTANCE NEAR hModule;
00390
00391 #endif
00392
00393 #ifdef HAVE_SQLITE3STRNICMP
00394 #undef strncasecmp
00395 #define strncasecmp(A,B,C) sqlite3_strnicmp(A,B,C)
00396 #undef strcasecmp
00397 #define strcasecmp(A,B) strcasecmp_(A,B)
00398
00399 #if defined(__GNUC__) && (__GNUC__ >= 2)
00400 static int strcasecmp_(const char *a, const char *b)
00401 __attribute__((__unused__));
00402 #endif
00403
00404 static int strcasecmp_(const char *a, const char *b)
00405 {
00406 int c = strlen(a), d = strlen(b);
00407
00408 if (c > d) {
00409 return strncasecmp(a, b, c);
00410 }
00411 return strncasecmp(a, b, d);
00412 }
00413 #endif
00414
00415 #if defined(_WIN32) || defined(_WIN64)
00416
00417
00418
00419
00420
00421
00422 #define HDBC_LOCK(hdbc) \
00423 { \
00424 DBC *d; \
00425 \
00426 if ((hdbc) == SQL_NULL_HDBC) { \
00427 return SQL_INVALID_HANDLE; \
00428 } \
00429 d = (DBC *) (hdbc); \
00430 if (d->magic != DBC_MAGIC || !d->env) { \
00431 return SQL_INVALID_HANDLE; \
00432 } \
00433 if (d->env->magic != ENV_MAGIC) { \
00434 return SQL_INVALID_HANDLE; \
00435 } \
00436 EnterCriticalSection(&d->env->cs); \
00437 d->env->owner = GetCurrentThreadId(); \
00438 }
00439
00440 #define HDBC_UNLOCK(hdbc) \
00441 if ((hdbc) != SQL_NULL_HDBC) { \
00442 DBC *d; \
00443 \
00444 d = (DBC *) (hdbc); \
00445 if (d->magic == DBC_MAGIC && d->env && \
00446 d->env->magic == ENV_MAGIC) { \
00447 d->env->owner = 0; \
00448 LeaveCriticalSection(&d->env->cs); \
00449 } \
00450 }
00451
00452 #define HSTMT_LOCK(hstmt) \
00453 { \
00454 DBC *d; \
00455 \
00456 if ((hstmt) == SQL_NULL_HSTMT) { \
00457 return SQL_INVALID_HANDLE; \
00458 } \
00459 d = (DBC *) ((STMT *) (hstmt))->dbc; \
00460 if (d->magic != DBC_MAGIC || !d->env) { \
00461 return SQL_INVALID_HANDLE; \
00462 } \
00463 if (d->env->magic != ENV_MAGIC) { \
00464 return SQL_INVALID_HANDLE; \
00465 } \
00466 EnterCriticalSection(&d->env->cs); \
00467 d->env->owner = GetCurrentThreadId(); \
00468 }
00469
00470 #define HSTMT_UNLOCK(hstmt) \
00471 if ((hstmt) != SQL_NULL_HSTMT) { \
00472 DBC *d; \
00473 \
00474 d = (DBC *) ((STMT *) (hstmt))->dbc; \
00475 if (d->magic == DBC_MAGIC && d->env && \
00476 d->env->magic == ENV_MAGIC) { \
00477 d->env->owner = 0; \
00478 LeaveCriticalSection(&d->env->cs); \
00479 } \
00480 }
00481
00482 #else
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 #define HDBC_LOCK(hdbc)
00505 #define HDBC_UNLOCK(hdbc)
00506 #define HSTMT_LOCK(hdbc)
00507 #define HSTMT_UNLOCK(hdbc)
00508
00509 #endif
00510
00511 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
00512 extern void nvfs_init(void);
00513 extern const char *nvfs_makevfs(const char *);
00514 #endif
00515
00516
00517
00518
00519
00520 static const char upper_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
00521 static const char lower_chars[] = "abcdefghijklmnopqrstuvwxyz";
00522
00523 static int
00524 TOLOWER(int c)
00525 {
00526 if (c) {
00527 char *p = strchr(upper_chars, c);
00528
00529 if (p) {
00530 c = lower_chars[p - upper_chars];
00531 }
00532 }
00533 return c;
00534 }
00535
00536
00537
00538
00539
00540 static const char digit_chars[] = "0123456789";
00541
00542 #define ISDIGIT(c) \
00543 ((c) && strchr(digit_chars, (c)) != NULL)
00544
00545
00546
00547
00548
00549 static const char space_chars[] = " \f\n\r\t\v";
00550
00551 #define ISSPACE(c) \
00552 ((c) && strchr(space_chars, (c)) != NULL)
00553
00554
00555
00556
00557
00558
00559 static void dbtraceapi(DBC *d, char *fn, const char *sql);
00560 static void freedyncols(STMT *s);
00561 static void freeresult(STMT *s, int clrcols);
00562 static void freerows(char **rowp);
00563 static void unbindcols(STMT *s);
00564 static void s3stmt_drop(STMT *s);
00565
00566 static SQLRETURN drvexecute(SQLHSTMT stmt, int initial);
00567 static SQLRETURN freestmt(HSTMT stmt);
00568 static SQLRETURN mkbindcols(STMT *s, int ncols);
00569 static SQLRETURN setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp);
00570 static SQLRETURN setupparbuf(STMT *s, BINDPARM *p);
00571 static SQLRETURN starttran(STMT *s);
00572 static SQLRETURN setupparam(STMT *s, char *sql, int pnum);
00573
00574 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
00575
00576 static COL *statSpec2P, *statSpec3P;
00577 #endif
00578
00579 #if (MEMORY_DEBUG < 1)
00580
00586 static char *
00587 strdup_(const char *str)
00588 {
00589 char *p = NULL;
00590
00591 if (str) {
00592 p = xmalloc(strlen(str) + 1);
00593 if (p) {
00594 strcpy(p, str);
00595 }
00596 }
00597 return p;
00598 }
00599 #endif
00600
00601 #ifdef WCHARSUPPORT
00602
00609 static int
00610 uc_strlen(SQLWCHAR *str)
00611 {
00612 int len = 0;
00613
00614 if (str) {
00615 while (*str) {
00616 ++len;
00617 ++str;
00618 }
00619 }
00620 return len;
00621 }
00622
00631 static SQLWCHAR *
00632 uc_strncpy(SQLWCHAR *dest, SQLWCHAR *src, int len)
00633 {
00634 int i = 0;
00635
00636 while (i < len) {
00637 if (!src[i]) {
00638 break;
00639 }
00640 dest[i] = src[i];
00641 ++i;
00642 }
00643 if (i < len) {
00644 dest[i] = 0;
00645 }
00646 return dest;
00647 }
00648
00657 static void
00658 uc_from_utf_buf(unsigned char *str, int len, SQLWCHAR *uc, int ucLen)
00659 {
00660 ucLen = ucLen / sizeof (SQLWCHAR);
00661 if (!uc || ucLen < 0) {
00662 return;
00663 }
00664 if (len < 0) {
00665 len = ucLen * 5;
00666 }
00667 uc[0] = 0;
00668 if (str) {
00669 int i = 0;
00670
00671 while (i < len && *str && i < ucLen) {
00672 unsigned char c = str[0];
00673
00674 if (c < 0x80) {
00675 uc[i++] = c;
00676 ++str;
00677 } else if (c <= 0xc1 || c >= 0xf5) {
00678
00679 ++str;
00680 } else if (c < 0xe0) {
00681 if ((str[1] & 0xc0) == 0x80) {
00682 unsigned long t = ((c & 0x1f) << 6) | (str[1] & 0x3f);
00683
00684 uc[i++] = t;
00685 str += 2;
00686 } else {
00687 uc[i++] = c;
00688 ++str;
00689 }
00690 } else if (c < 0xf0) {
00691 if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80) {
00692 unsigned long t = ((c & 0x0f) << 12) |
00693 ((str[1] & 0x3f) << 6) | (str[2] & 0x3f);
00694
00695 uc[i++] = t;
00696 str += 3;
00697 } else {
00698 uc[i++] = c;
00699 ++str;
00700 }
00701 } else if (c < 0xf8) {
00702 if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 &&
00703 (str[3] & 0xc0) == 0x80) {
00704 unsigned long t = ((c & 0x03) << 18) |
00705 ((str[1] & 0x3f) << 12) | ((str[2] & 0x3f) << 6) |
00706 (str[3] & 0x3f);
00707
00708 if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
00709 t >= 0x10000) {
00710 t -= 0x10000;
00711 uc[i++] = 0xd800 | ((t >> 10) & 0x3ff);
00712 if (i >= ucLen) {
00713 break;
00714 }
00715 t = 0xdc00 | (t & 0x3ff);
00716 }
00717 uc[i++] = t;
00718 str += 4;
00719 } else {
00720 uc[i++] = c;
00721 ++str;
00722 }
00723 } else if (c < 0xfc) {
00724 if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 &&
00725 (str[3] & 0xc0) == 0x80 && (str[4] & 0xc0) == 0x80) {
00726 unsigned long t = ((c & 0x01) << 24) |
00727 ((str[1] & 0x3f) << 18) | ((str[2] & 0x3f) << 12) |
00728 ((str[3] & 0x3f) << 6) | (str[4] & 0x3f);
00729
00730 if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
00731 t >= 0x10000) {
00732 t -= 0x10000;
00733 uc[i++] = 0xd800 | ((t >> 10) & 0x3ff);
00734 if (i >= ucLen) {
00735 break;
00736 }
00737 t = 0xdc00 | (t & 0x3ff);
00738 }
00739 uc[i++] = t;
00740 str += 5;
00741 } else {
00742 uc[i++] = c;
00743 ++str;
00744 }
00745 } else {
00746
00747 ++str;
00748 }
00749 }
00750 if (i < ucLen) {
00751 uc[i] = 0;
00752 }
00753 }
00754 }
00755
00763 static SQLWCHAR *
00764 uc_from_utf(unsigned char *str, int len)
00765 {
00766 SQLWCHAR *uc = NULL;
00767 int ucLen;
00768
00769 if (str) {
00770 if (len == SQL_NTS) {
00771 len = strlen((char *) str);
00772 }
00773 ucLen = sizeof (SQLWCHAR) * (len + 1);
00774 uc = xmalloc(ucLen);
00775 if (uc) {
00776 uc_from_utf_buf(str, len, uc, ucLen);
00777 }
00778 }
00779 return uc;
00780 }
00781
00789 static char *
00790 uc_to_utf(SQLWCHAR *str, int len)
00791 {
00792 int i;
00793 char *cp, *ret = NULL;
00794
00795 if (!str) {
00796 return ret;
00797 }
00798 if (len == SQL_NTS) {
00799 len = uc_strlen(str);
00800 } else {
00801 len = len / sizeof (SQLWCHAR);
00802 }
00803 cp = xmalloc(len * 6 + 1);
00804 if (!cp) {
00805 return ret;
00806 }
00807 ret = cp;
00808 for (i = 0; i < len; i++) {
00809 unsigned long c = str[i];
00810
00811 if (sizeof (SQLWCHAR) == 2 * sizeof (char)) {
00812 c &= 0xffff;
00813 }
00814 if (c < 0x80) {
00815 *cp++ = c;
00816 } else if (c < 0x800) {
00817 *cp++ = 0xc0 | ((c >> 6) & 0x1f);
00818 *cp++ = 0x80 | (c & 0x3f);
00819 } else if (c < 0x10000) {
00820 if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
00821 c >= 0xd800 && c <= 0xdbff && i + 1 < len) {
00822 unsigned long c2 = str[i + 1] & 0xffff;
00823
00824 if (c2 >= 0xdc00 && c2 <= 0xdfff) {
00825 c = (((c & 0x3ff) << 10) | (c2 & 0x3ff)) + 0x10000;
00826 *cp++ = 0xf0 | ((c >> 18) & 0x07);
00827 *cp++ = 0x80 | ((c >> 12) & 0x3f);
00828 *cp++ = 0x80 | ((c >> 6) & 0x3f);
00829 *cp++ = 0x80 | (c & 0x3f);
00830 ++i;
00831 continue;
00832 }
00833 }
00834 *cp++ = 0xe0 | ((c >> 12) & 0x0f);
00835 *cp++ = 0x80 | ((c >> 6) & 0x3f);
00836 *cp++ = 0x80 | (c & 0x3f);
00837 } else if (c < 0x200000) {
00838 *cp++ = 0xf0 | ((c >> 18) & 0x07);
00839 *cp++ = 0x80 | ((c >> 12) & 0x3f);
00840 *cp++ = 0x80 | ((c >> 6) & 0x3f);
00841 *cp++ = 0x80 | (c & 0x3f);
00842 } else if (c < 0x4000000) {
00843 *cp++ = 0xf8 | ((c >> 24) & 0x03);
00844 *cp++ = 0x80 | ((c >> 18) & 0x3f);
00845 *cp++ = 0x80 | ((c >> 12) & 0x3f);
00846 *cp++ = 0x80 | ((c >> 6) & 0x3f);
00847 *cp++ = 0x80 | (c & 0x3f);
00848 } else if (c < 0x80000000) {
00849 *cp++ = 0xfc | ((c >> 31) & 0x01);
00850 *cp++ = 0x80 | ((c >> 24) & 0x3f);
00851 *cp++ = 0x80 | ((c >> 18) & 0x3f);
00852 *cp++ = 0x80 | ((c >> 12) & 0x3f);
00853 *cp++ = 0x80 | ((c >> 6) & 0x3f);
00854 *cp++ = 0x80 | (c & 0x3f);
00855 }
00856 }
00857 *cp = '\0';
00858 return ret;
00859 }
00860
00861 #endif
00862
00863 #ifdef WINTERFACE
00864
00872 static char *
00873 uc_to_utf_c(SQLWCHAR *str, int len)
00874 {
00875 if (len != SQL_NTS) {
00876 len = len * sizeof (SQLWCHAR);
00877 }
00878 return uc_to_utf(str, len);
00879 }
00880
00881 #endif
00882
00883 #if defined(WCHARSUPPORT) || defined(_WIN32) || defined(_WIN64)
00884
00890 static void
00891 uc_free(void *str)
00892 {
00893 if (str) {
00894 xfree(str);
00895 }
00896 }
00897
00898 #endif
00899
00900 #if defined(_WIN32) || defined(_WIN64)
00901
00909 static char *
00910 wmb_to_utf(char *str, int len)
00911 {
00912 WCHAR *wstr;
00913 OSVERSIONINFO ovi;
00914 int nchar, is2k, cp = CP_OEMCP;
00915
00916 ovi.dwOSVersionInfoSize = sizeof (ovi);
00917 GetVersionEx(&ovi);
00918 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
00919 if (AreFileApisANSI()) {
00920 cp = is2k ? CP_THREAD_ACP : CP_ACP;
00921 }
00922 nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
00923 wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
00924 if (!wstr) {
00925 return NULL;
00926 }
00927 wstr[0] = 0;
00928 nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
00929 wstr[nchar] = 0;
00930 str = xmalloc((nchar + 1) * 7);
00931 if (!str) {
00932 xfree(wstr);
00933 return NULL;
00934 }
00935 str[0] = '\0';
00936 nchar = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, nchar * 7, 0, 0);
00937 str[nchar] = '\0';
00938 xfree(wstr);
00939 return str;
00940 }
00941
00942 #ifndef WINTERFACE
00943
00951 static char *
00952 wmb_to_utf_c(char *str, int len)
00953 {
00954 if (len == SQL_NTS) {
00955 len = strlen(str);
00956 }
00957 return wmb_to_utf(str, len);
00958 }
00959
00960 #endif
00961
00969 static char *
00970 utf_to_wmb(char *str, int len)
00971 {
00972 WCHAR *wstr;
00973 OSVERSIONINFO ovi;
00974 int nchar, is2k, cp = CP_OEMCP;
00975
00976 ovi.dwOSVersionInfoSize = sizeof (ovi);
00977 GetVersionEx(&ovi);
00978 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
00979 if (AreFileApisANSI()) {
00980 cp = is2k ? CP_THREAD_ACP : CP_ACP;
00981 }
00982 nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
00983 wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
00984 if (!wstr) {
00985 return NULL;
00986 }
00987 wstr[0] = 0;
00988 nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, wstr, nchar);
00989 wstr[nchar] = 0;
00990 str = xmalloc((nchar + 1) * 7);
00991 if (!str) {
00992 xfree(wstr);
00993 return NULL;
00994 }
00995 str[0] = '\0';
00996 nchar = WideCharToMultiByte(cp, 0, wstr, -1, str, nchar * 7, 0, 0);
00997 str[nchar] = '\0';
00998 xfree(wstr);
00999 return str;
01000 }
01001
01002 #ifdef WINTERFACE
01003
01011 static WCHAR *
01012 wmb_to_uc(char *str, int len)
01013 {
01014 WCHAR *wstr;
01015 OSVERSIONINFO ovi;
01016 int nchar, is2k, cp = CP_OEMCP;
01017
01018 ovi.dwOSVersionInfoSize = sizeof (ovi);
01019 GetVersionEx(&ovi);
01020 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
01021 if (AreFileApisANSI()) {
01022 cp = is2k ? CP_THREAD_ACP : CP_ACP;
01023 }
01024 nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
01025 wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
01026 if (!wstr) {
01027 return NULL;
01028 }
01029 wstr[0] = 0;
01030 nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
01031 wstr[nchar] = 0;
01032 return wstr;
01033 }
01034
01042 static char *
01043 uc_to_wmb(WCHAR *wstr, int len)
01044 {
01045 char *str;
01046 OSVERSIONINFO ovi;
01047 int nchar, is2k, cp = CP_OEMCP;
01048
01049 ovi.dwOSVersionInfoSize = sizeof (ovi);
01050 GetVersionEx(&ovi);
01051 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
01052 if (AreFileApisANSI()) {
01053 cp = is2k ? CP_THREAD_ACP : CP_ACP;
01054 }
01055 nchar = WideCharToMultiByte(cp, 0, wstr, len, NULL, 0, 0, 0);
01056 str = xmalloc((nchar + 1) * 2);
01057 if (!str) {
01058 return NULL;
01059 }
01060 str[0] = '\0';
01061 nchar = WideCharToMultiByte(cp, 0, wstr, len, str, nchar * 2, 0, 0);
01062 str[nchar] = '\0';
01063 return str;
01064 }
01065
01066 #endif
01067
01068 #endif
01069
01070
01071 #ifdef USE_DLOPEN_FOR_GPPS
01072
01073 #include <dlfcn.h>
01074
01075 #define SQLGetPrivateProfileString(A,B,C,D,E,F) drvgpps(d,A,B,C,D,E,F)
01076
01077
01078
01079
01080
01081
01082
01083
01084 static void
01085 drvgetgpps(DBC *d)
01086 {
01087 void *lib;
01088 int (*gpps)();
01089
01090 lib = dlopen("libodbcinst.so.1", RTLD_LAZY);
01091 if (!lib) {
01092 lib = dlopen("libodbcinst.so", RTLD_LAZY);
01093 }
01094 if (!lib) {
01095 lib = dlopen("libiodbcinst.so.2", RTLD_LAZY);
01096 }
01097 if (!lib) {
01098 lib = dlopen("libiodbcinst.so", RTLD_LAZY);
01099 }
01100 if (lib) {
01101 gpps = (int (*)()) dlsym(lib, "SQLGetPrivateProfileString");
01102 if (!gpps) {
01103 dlclose(lib);
01104 return;
01105 }
01106 d->instlib = lib;
01107 d->gpps = gpps;
01108 }
01109 }
01110
01111 static void
01112 drvrelgpps(DBC *d)
01113 {
01114 if (d->instlib) {
01115 dlclose(d->instlib);
01116 d->instlib = 0;
01117 }
01118 }
01119
01120 static int
01121 drvgpps(DBC *d, char *sect, char *ent, char *def, char *buf,
01122 int bufsiz, char *fname)
01123 {
01124 if (d->gpps) {
01125 return d->gpps(sect, ent, def, buf, bufsiz, fname);
01126 }
01127 strncpy(buf, def, bufsiz);
01128 buf[bufsiz - 1] = '\0';
01129 return 1;
01130 }
01131 #else
01132 #include <odbcinst.h>
01133 #define drvgetgpps(d)
01134 #define drvrelgpps(d)
01135 #endif
01136
01137
01138
01139
01140
01141 static void
01142 s3bind(DBC *d, sqlite3_stmt *stmt, int nparams, BINDPARM *p)
01143 {
01144 int i;
01145
01146 if (stmt && p && nparams > 0) {
01147 for (i = 0; i < nparams; i++, p++) {
01148 switch (p->s3type) {
01149 default:
01150 case SQLITE_NULL:
01151 sqlite3_bind_null(stmt, i + 1);
01152 if (d->trace) {
01153 fprintf(d->trace, "-- parameter %d: NULL\n", i + 1);
01154 fflush(d->trace);
01155 }
01156 break;
01157 case SQLITE_TEXT:
01158 sqlite3_bind_text(stmt, i + 1, p->s3val, p->s3size,
01159 SQLITE_STATIC);
01160 if (d->trace) {
01161 fprintf(d->trace, "-- parameter %d: '%*s'\n", i + 1,
01162 p->s3size, (char *) p->s3val);
01163 fflush(d->trace);
01164 }
01165 break;
01166 case SQLITE_BLOB:
01167 sqlite3_bind_blob(stmt, i + 1, p->s3val, p->s3size,
01168 SQLITE_STATIC);
01169 if (d->trace) {
01170 fprintf(d->trace, "-- parameter %d: [BLOB]'\n", i + 1);
01171 fflush(d->trace);
01172 }
01173 break;
01174 case SQLITE_FLOAT:
01175 sqlite3_bind_double(stmt, i + 1, p->s3dval);
01176 if (d->trace) {
01177 fprintf(d->trace, "-- parameter %d: %g\n",
01178 i + 1, p->s3dval);
01179 fflush(d->trace);
01180 }
01181 break;
01182 case SQLITE_INTEGER:
01183 if (p->s3size > sizeof (int)) {
01184 sqlite3_bind_int64(stmt, i + 1, p->s3lival);
01185 if (d->trace) {
01186 fprintf(d->trace,
01187 #ifdef _WIN32
01188 "-- parameter %d: %I64d\n",
01189 #else
01190 "-- parameter %d: %lld\n",
01191 #endif
01192 i + 1, p->s3lival);
01193 fflush(d->trace);
01194 }
01195 } else {
01196 sqlite3_bind_int(stmt, i + 1, p->s3ival);
01197 if (d->trace) {
01198 fprintf(d->trace, "-- parameter %d: %d\n",
01199 i + 1, p->s3ival);
01200 fflush(d->trace);
01201 }
01202 }
01203 break;
01204 }
01205 }
01206 }
01207 }
01208
01216 typedef struct tblres {
01217 char **resarr;
01218 char *errmsg;
01219 sqlite3_stmt *stmt;
01220 STMT *s;
01221 int nalloc;
01222 int nrow;
01223 int ncol;
01224 PTRDIFF_T ndata;
01225 int rc;
01226 } TBLRES;
01227
01228
01229
01230
01231
01232
01233 static int
01234 drvgettable_row(TBLRES *t, int ncol, int rc)
01235 {
01236 int need;
01237 int i;
01238 char *p;
01239
01240 if (t->nrow == 0 && rc == SQLITE_ROW) {
01241 need = ncol * 2;
01242 } else {
01243 need = ncol;
01244 }
01245 if (t->ndata + need >= t->nalloc) {
01246 char **resnew;
01247 int nalloc = t->nalloc * 2 + need + 1;
01248
01249 resnew = xrealloc(t->resarr, sizeof (char *) * nalloc);
01250 if (!resnew) {
01251 nomem:
01252 t->rc = SQLITE_NOMEM;
01253 return 1;
01254 }
01255 t->nalloc = nalloc;
01256 t->resarr = resnew;
01257 }
01258
01259 if (t->nrow == 0) {
01260 t->ncol = ncol;
01261 for (i = 0; i < ncol; i++) {
01262 p = (char *) sqlite3_column_name(t->stmt, i);
01263 if (p) {
01264 char *q = xmalloc(strlen(p) + 1);
01265
01266 if (!q) {
01267 goto nomem;
01268 }
01269 strcpy(q, p);
01270 p = q;
01271 }
01272 t->resarr[t->ndata++] = p;
01273 }
01274 if (t->s && t->s->guessed_types) {
01275 int ncol2 = ncol;
01276
01277 setupdyncols(t->s, t->stmt, &ncol2);
01278 t->s->guessed_types = 0;
01279 t->s->ncols = ncol;
01280 }
01281 } else if (t->ncol != ncol) {
01282 t->errmsg = sqlite3_mprintf("drvgettable() called with two or"
01283 " more incompatible queries");
01284 t->rc = SQLITE_ERROR;
01285 return 1;
01286 }
01287
01288 if (rc == SQLITE_ROW) {
01289 for (i = 0; i < ncol; i++) {
01290 int coltype = sqlite3_column_type(t->stmt, i);
01291
01292 p = NULL;
01293 if (coltype == SQLITE_BLOB) {
01294 int k, nbytes = sqlite3_column_bytes(t->stmt, i);
01295 char *qp;
01296 unsigned const char *bp;
01297
01298 bp = sqlite3_column_blob(t->stmt, i);
01299 qp = xmalloc(nbytes * 2 + 4);
01300 if (!qp) {
01301 goto nomem;
01302 }
01303 p = qp;
01304 *qp++ = 'X';
01305 *qp++ = '\'';
01306 for (k = 0; k < nbytes; k++) {
01307 *qp++ = xdigits[(bp[k] >> 4)];
01308 *qp++ = xdigits[(bp[k] & 0xF)];
01309 }
01310 *qp++ = '\'';
01311 *qp = '\0';
01312 #ifdef _MSC_VER
01313 } else if (coltype == SQLITE_FLOAT) {
01314 static struct lconv *lc = 0;
01315 double val = sqlite3_column_double(t->stmt, i);
01316 char buffer[128];
01317
01318
01319
01320
01321
01322
01323 snprintf(buffer, sizeof (buffer), "%.15g", val);
01324 if (!lc) {
01325 lc = localeconv();
01326 }
01327 if (lc && lc->decimal_point && lc->decimal_point[0] &&
01328 lc->decimal_point[0] != '.') {
01329 p = strchr(buffer, lc->decimal_point[0]);
01330 if (p) {
01331 *p = '.';
01332 }
01333 }
01334 p = xstrdup(buffer);
01335 if (!p) {
01336 goto nomem;
01337 }
01338 #endif
01339 } else if (coltype != SQLITE_NULL) {
01340 p = xstrdup((char *) sqlite3_column_text(t->stmt, i));
01341 if (!p) {
01342 goto nomem;
01343 }
01344 }
01345 t->resarr[t->ndata++] = p;
01346 }
01347 t->nrow++;
01348 }
01349 return 0;
01350 }
01351
01352 static int
01353 drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp,
01354 int *ncolp, char **errp, int nparam, BINDPARM *p)
01355 {
01356 DBC *d = (DBC *) s->dbc;
01357 int rc = SQLITE_OK, keep = sql == NULL;
01358 TBLRES tres;
01359 const char *sqlleft = 0;
01360 int nretry = 0, haveerr = 0;
01361
01362 if (!resp) {
01363 return SQLITE_ERROR;
01364 }
01365 *resp = NULL;
01366 if (nrowp) {
01367 *nrowp = 0;
01368 }
01369 if (ncolp) {
01370 *ncolp = 0;
01371 }
01372 tres.errmsg = NULL;
01373 tres.nrow = 0;
01374 tres.ncol = 0;
01375 tres.ndata = 1;
01376 tres.nalloc = 20;
01377 tres.rc = SQLITE_OK;
01378 tres.resarr = xmalloc(sizeof (char *) * tres.nalloc);
01379 tres.stmt = NULL;
01380 tres.s = s;
01381 if (!tres.resarr) {
01382 return SQLITE_NOMEM;
01383 }
01384 tres.resarr[0] = 0;
01385 if (sql == NULL) {
01386 tres.stmt = s->s3stmt;
01387 if (tres.stmt == NULL) {
01388 return SQLITE_NOMEM;
01389 }
01390 goto retrieve;
01391 }
01392 while (sql && *sql && (rc == SQLITE_OK ||
01393 (rc == SQLITE_SCHEMA && (++nretry) < 2))) {
01394 int ncol;
01395
01396 tres.stmt = NULL;
01397 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
01398 dbtraceapi(d, "sqlite3_prepare_v2", sql);
01399 rc = sqlite3_prepare_v2(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
01400 #else
01401 dbtraceapi(d, "sqlite3_prepare", sql);
01402 rc = sqlite3_prepare(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
01403 #endif
01404 if (rc != SQLITE_OK) {
01405 if (tres.stmt) {
01406 dbtraceapi(d, "sqlite3_finalize", 0);
01407 sqlite3_finalize(tres.stmt);
01408 tres.stmt = NULL;
01409 }
01410 continue;
01411 }
01412 if (!tres.stmt) {
01413
01414 sql = sqlleft;
01415 continue;
01416 }
01417 retrieve:
01418 if (sqlite3_bind_parameter_count(tres.stmt) != nparam) {
01419 if (errp) {
01420 *errp =
01421 sqlite3_mprintf("%s", "parameter marker count incorrect");
01422 }
01423 haveerr = 1;
01424 rc = SQLITE_ERROR;
01425 goto tbldone;
01426 }
01427 s3bind(d, tres.stmt, nparam, p);
01428 ncol = sqlite3_column_count(tres.stmt);
01429 while (1) {
01430 if (s->max_rows && tres.nrow >= s->max_rows) {
01431 rc = SQLITE_OK;
01432 break;
01433 }
01434 rc = sqlite3_step(tres.stmt);
01435 if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
01436 if (drvgettable_row(&tres, ncol, rc)) {
01437 rc = SQLITE_ABORT;
01438 goto tbldone;
01439 }
01440 }
01441 if (rc != SQLITE_ROW) {
01442 if (keep) {
01443 dbtraceapi(d, "sqlite3_reset", 0);
01444 rc = sqlite3_reset(tres.stmt);
01445 s->s3stmt_noreset = 1;
01446 } else {
01447 dbtraceapi(d, "sqlite3_finalize", 0);
01448 rc = sqlite3_finalize(tres.stmt);
01449 }
01450 tres.stmt = 0;
01451 if (rc != SQLITE_SCHEMA) {
01452 nretry = 0;
01453 sql = sqlleft;
01454 while (sql && ISSPACE(*sql)) {
01455 sql++;
01456 }
01457 }
01458 if (rc == SQLITE_DONE) {
01459 rc = SQLITE_OK;
01460 }
01461 break;
01462 }
01463 }
01464 }
01465 tbldone:
01466 if (tres.stmt) {
01467 if (keep) {
01468 if (!s->s3stmt_noreset) {
01469 dbtraceapi(d, "sqlite3_reset", 0);
01470 sqlite3_reset(tres.stmt);
01471 s->s3stmt_noreset = 1;
01472 }
01473 } else {
01474 dbtraceapi(d, "sqlite3_finalize", 0);
01475 sqlite3_finalize(tres.stmt);
01476 }
01477 }
01478 if (haveerr) {
01479
01480 } else if (rc != SQLITE_OK && rc == sqlite3_errcode(d->sqlite) && errp) {
01481 *errp = sqlite3_mprintf("%s", sqlite3_errmsg(d->sqlite));
01482 } else if (errp) {
01483 *errp = NULL;
01484 }
01485 if (tres.resarr) {
01486 tres.resarr[0] = (char *) (tres.ndata - 1);
01487 }
01488 if (rc == SQLITE_ABORT) {
01489 freerows(&tres.resarr[1]);
01490 if (tres.errmsg) {
01491 if (errp) {
01492 if (*errp) {
01493 sqlite3_free(*errp);
01494 }
01495 *errp = tres.errmsg;
01496 } else {
01497 sqlite3_free(tres.errmsg);
01498 }
01499 }
01500 return tres.rc;
01501 }
01502 sqlite3_free(tres.errmsg);
01503 if (rc != SQLITE_OK) {
01504 freerows(&tres.resarr[1]);
01505 return rc;
01506 }
01507 *resp = &tres.resarr[1];
01508 if (ncolp) {
01509 *ncolp = tres.ncol;
01510 }
01511 if (nrowp) {
01512 *nrowp = tres.nrow;
01513 }
01514 return rc;
01515 }
01516
01525 #if defined(__GNUC__) && (__GNUC__ >= 2)
01526 static void setstatd(DBC *, int, char *, char *, ...)
01527 __attribute__((format (printf, 3, 5)));
01528 #endif
01529
01530 static void
01531 setstatd(DBC *d, int naterr, char *msg, char *st, ...)
01532 {
01533 va_list ap;
01534
01535 if (!d) {
01536 return;
01537 }
01538 d->naterr = naterr;
01539 d->logmsg[0] = '\0';
01540 if (msg) {
01541 int count;
01542
01543 va_start(ap, st);
01544 count = vsnprintf((char *) d->logmsg, sizeof (d->logmsg), msg, ap);
01545 va_end(ap);
01546 if (count < 0) {
01547 d->logmsg[sizeof (d->logmsg) - 1] = '\0';
01548 }
01549 }
01550 if (!st) {
01551 st = "?????";
01552 }
01553 strncpy(d->sqlstate, st, 5);
01554 d->sqlstate[5] = '\0';
01555 }
01556
01565 #if defined(__GNUC__) && (__GNUC__ >= 2)
01566 static void setstat(STMT *, int, char *, char *, ...)
01567 __attribute__((format (printf, 3, 5)));
01568 #endif
01569
01570 static void
01571 setstat(STMT *s, int naterr, char *msg, char *st, ...)
01572 {
01573 va_list ap;
01574
01575 if (!s) {
01576 return;
01577 }
01578 s->naterr = naterr;
01579 s->logmsg[0] = '\0';
01580 if (msg) {
01581 int count;
01582
01583 va_start(ap, st);
01584 count = vsnprintf((char *) s->logmsg, sizeof (s->logmsg), msg, ap);
01585 va_end(ap);
01586 if (count < 0) {
01587 s->logmsg[sizeof (s->logmsg) - 1] = '\0';
01588 }
01589 }
01590 if (!st) {
01591 st = "?????";
01592 }
01593 strncpy(s->sqlstate, st, 5);
01594 s->sqlstate[5] = '\0';
01595 }
01596
01603 static SQLRETURN
01604 drvunimpldbc(HDBC dbc)
01605 {
01606 DBC *d;
01607
01608 if (dbc == SQL_NULL_HDBC) {
01609 return SQL_INVALID_HANDLE;
01610 }
01611 d = (DBC *) dbc;
01612 setstatd(d, -1, "not supported", "IM001");
01613 return SQL_ERROR;
01614 }
01615
01622 static SQLRETURN
01623 drvunimplstmt(HSTMT stmt)
01624 {
01625 STMT *s;
01626
01627 if (stmt == SQL_NULL_HSTMT) {
01628 return SQL_INVALID_HANDLE;
01629 }
01630 s = (STMT *) stmt;
01631 setstat(s, -1, "not supported", "IM001");
01632 return SQL_ERROR;
01633 }
01634
01640 static void
01641 freep(void *x)
01642 {
01643 if (x && ((char **) x)[0]) {
01644 xfree(((char **) x)[0]);
01645 ((char **) x)[0] = NULL;
01646 }
01647 }
01648
01655 static SQLRETURN
01656 nomem(STMT *s)
01657 {
01658 setstat(s, -1, "out of memory", (*s->ov3) ? "HY000" : "S1000");
01659 return SQL_ERROR;
01660 }
01661
01668 static SQLRETURN
01669 noconn(STMT *s)
01670 {
01671 setstat(s, -1, "not connected", (*s->ov3) ? "HY000" : "S1000");
01672 return SQL_ERROR;
01673 }
01674
01682 #if defined(HAVE_LOCALECONV) || defined(_WIN32) || defined(_WIN64)
01683
01684 static double
01685 ln_strtod(const char *data, char **endp)
01686 {
01687 static struct lconv *lc = 0;
01688 char buf[128], *p, *end;
01689 double value;
01690
01691 if (!lc) {
01692 lc = localeconv();
01693 }
01694 if (lc && lc->decimal_point && lc->decimal_point[0] &&
01695 lc->decimal_point[0] != '.') {
01696 strncpy(buf, data, sizeof (buf) - 1);
01697 buf[sizeof (buf) - 1] = '\0';
01698 p = strchr(buf, '.');
01699 if (p) {
01700 *p = lc->decimal_point[0];
01701 }
01702 p = buf;
01703 } else {
01704 p = (char *) data;
01705 }
01706 value = strtod(p, &end);
01707 end = (char *) data + (end - p);
01708 if (endp) {
01709 *endp = end;
01710 }
01711 return value;
01712 }
01713
01714 #else
01715
01716 #define ln_strtod(A,B) strtod(A,B)
01717
01718 #endif
01719
01725 static char *
01726 unquote(char *str)
01727 {
01728 if (str) {
01729 int len = strlen(str);
01730
01731 if (len > 1) {
01732 if ((str[0] == '\'' && str[len - 1] == '\'') ||
01733 (str[0] == '"' && str[len - 1] == '"') ||
01734 (str[0] == '[' && str[len - 1] == ']')) {
01735 str[len - 1] = '\0';
01736 strcpy(str, str + 1);
01737 }
01738 }
01739 }
01740 return str;
01741 }
01742
01750 static int
01751 unescpat(char *str)
01752 {
01753 char *p, *q;
01754 int count = 0;
01755
01756 p = str;
01757 while ((q = strchr(p, '_')) != NULL) {
01758 if (q == str || q[-1] != '\\') {
01759 count++;
01760 }
01761 p = q + 1;
01762 }
01763 p = str;
01764 while ((q = strchr(p, '%')) != NULL) {
01765 if (q == str || q[-1] != '\\') {
01766 count++;
01767 }
01768 p = q + 1;
01769 }
01770 p = str;
01771 while ((q = strchr(p, '\\')) != NULL) {
01772 if (q[1] == '\\' || q[1] == '_' || q[1] == '%') {
01773 strcpy(q, q + 1);
01774 }
01775 p = q + 1;
01776 }
01777 return count;
01778 }
01779
01788 static int
01789 namematch(char *str, char *pat, int esc)
01790 {
01791 int cp, ch;
01792
01793 while (1) {
01794 cp = TOLOWER(*pat);
01795 if (cp == '\0') {
01796 if (*str != '\0') {
01797 goto nomatch;
01798 }
01799 break;
01800 }
01801 if (*str == '\0' && cp != '%') {
01802 goto nomatch;
01803 }
01804 if (cp == '%') {
01805 while (*pat == '%') {
01806 ++pat;
01807 }
01808 cp = TOLOWER(*pat);
01809 if (cp == '\0') {
01810 break;
01811 }
01812 while (1) {
01813 if (cp != '_' && cp != '\\') {
01814 while (*str) {
01815 ch = TOLOWER(*str);
01816 if (ch == cp) {
01817 break;
01818 }
01819 ++str;
01820 }
01821 }
01822 if (namematch(str, pat, esc)) {
01823 goto match;
01824 }
01825 if (*str == '\0') {
01826 goto nomatch;
01827 }
01828 ch = TOLOWER(*str);
01829 ++str;
01830 }
01831 }
01832 if (cp == '_') {
01833 pat++;
01834 str++;
01835 continue;
01836 }
01837 if (esc && cp == '\\' &&
01838 (pat[1] == '\\' || pat[1] == '%' || pat[1] == '_')) {
01839 ++pat;
01840 cp = TOLOWER(*pat);
01841 }
01842 ch = TOLOWER(*str++);
01843 ++pat;
01844 if (ch != cp) {
01845 goto nomatch;
01846 }
01847 }
01848 match:
01849 return 1;
01850 nomatch:
01851 return 0;
01852 }
01853
01861 static int
01862 busy_handler(void *udata, int count)
01863 {
01864 DBC *d = (DBC *) udata;
01865 long t1;
01866 int ret = 0;
01867 #if !defined(_WIN32) && !defined(_WIN64)
01868 struct timeval tv;
01869 #ifdef HAVE_NANOSLEEP
01870 struct timespec ts;
01871 #endif
01872 #endif
01873
01874 if (d->busyint) {
01875 d->busyint = 0;
01876 return ret;
01877 }
01878 if (d->timeout <= 0) {
01879 return ret;
01880 }
01881 if (count <= 1) {
01882 #if defined(_WIN32) || defined(_WIN64)
01883 d->t0 = GetTickCount();
01884 #else
01885 gettimeofday(&tv, NULL);
01886 d->t0 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
01887 #endif
01888 }
01889 #if defined(_WIN32) || defined(_WIN64)
01890 t1 = GetTickCount();
01891 #else
01892 gettimeofday(&tv, NULL);
01893 t1 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
01894 #endif
01895 if (t1 - d->t0 > d->timeout) {
01896 goto done;
01897 }
01898 #if defined(_WIN32) || defined(_WIN64)
01899 Sleep(10);
01900 #else
01901 #ifdef HAVE_NANOSLEEP
01902 ts.tv_sec = 0;
01903 ts.tv_nsec = 10000000;
01904 do {
01905 ret = nanosleep(&ts, &ts);
01906 if (ret < 0 && errno != EINTR) {
01907 ret = 0;
01908 }
01909 } while (ret);
01910 #else
01911 #ifdef HAVE_USLEEP
01912 usleep(10000);
01913 #else
01914 tv.tv_sec = 0;
01915 tv.tv_usec = 10000;
01916 select(0, NULL, NULL, NULL, &tv);
01917 #endif
01918 #endif
01919 #endif
01920 ret = 1;
01921 done:
01922 return ret;
01923 }
01924
01936 static int
01937 setsqliteopts(sqlite3 *x, DBC *d)
01938 {
01939 int count = 0, step = 0, max, rc = SQLITE_ERROR;
01940
01941 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
01942 max = d->longnames ? 3 : 1;
01943 #else
01944 max = 3;
01945 #endif
01946 if (d->shortnames) {
01947 max = 3;
01948 }
01949 while (step < max) {
01950 if (step < 1) {
01951 rc = sqlite3_exec(x, "PRAGMA empty_result_callbacks = on;",
01952 NULL, NULL, NULL);
01953 if (rc == SQLITE_OK) {
01954 rc = sqlite3_exec(x, d->fksupport ?
01955 "PRAGMA foreign_keys = on;" :
01956 "PRAGMA foreign_keys = off;",
01957 NULL, NULL, NULL);
01958 }
01959 } else if (step < 2) {
01960 rc = sqlite3_exec(x, d->shortnames ?
01961 "PRAGMA full_column_names = off;" :
01962 "PRAGMA full_column_names = on;",
01963 NULL, NULL, NULL);
01964 } else if (step < 3) {
01965 rc = sqlite3_exec(x, d->shortnames ?
01966 "PRAGMA short_column_names = on;" :
01967 "PRAGMA short_column_names = off;",
01968 NULL, NULL, NULL);
01969 }
01970 if (rc != SQLITE_OK) {
01971 if (rc != SQLITE_BUSY ||
01972 !busy_handler((void *) d, ++count)) {
01973 return rc;
01974 }
01975 continue;
01976 }
01977 count = 0;
01978 ++step;
01979 }
01980 sqlite3_busy_handler(x, busy_handler, (void *) d);
01981 return SQLITE_OK;
01982 }
01983
01993 static void
01994 freerows(char **rowp)
01995 {
01996 PTRDIFF_T size, i;
01997
01998 if (!rowp) {
01999 return;
02000 }
02001 --rowp;
02002 size = (PTRDIFF_T) rowp[0];
02003 for (i = 1; i <= size; i++) {
02004 freep(&rowp[i]);
02005 }
02006 freep(&rowp);
02007 }
02008
02019 static int
02020 mapsqltype(const char *typename, int *nosign, int ov3, int nowchar,
02021 int dobigint)
02022 {
02023 char *p, *q;
02024 int testsign = 0, result;
02025
02026 #ifdef WINTERFACE
02027 result = nowchar ? SQL_VARCHAR : SQL_WVARCHAR;
02028 #else
02029 result = SQL_VARCHAR;
02030 #endif
02031 if (!typename) {
02032 return result;
02033 }
02034 q = p = xmalloc(strlen(typename) + 1);
02035 if (!p) {
02036 return result;
02037 }
02038 strcpy(p, typename);
02039 while (*q) {
02040 *q = TOLOWER(*q);
02041 ++q;
02042 }
02043 if (strncmp(p, "inter", 5) == 0) {
02044 } else if (strncmp(p, "int", 3) == 0 ||
02045 strncmp(p, "mediumint", 9) == 0) {
02046 testsign = 1;
02047 result = SQL_INTEGER;
02048 } else if (strncmp(p, "numeric", 7) == 0) {
02049 result = SQL_DOUBLE;
02050 } else if (strncmp(p, "tinyint", 7) == 0) {
02051 testsign = 1;
02052 result = SQL_TINYINT;
02053 } else if (strncmp(p, "smallint", 8) == 0) {
02054 testsign = 1;
02055 result = SQL_SMALLINT;
02056 } else if (strncmp(p, "float", 5) == 0) {
02057 result = SQL_DOUBLE;
02058 } else if (strncmp(p, "double", 6) == 0 ||
02059 strncmp(p, "real", 4) == 0) {
02060 result = SQL_DOUBLE;
02061 } else if (strncmp(p, "timestamp", 9) == 0) {
02062 #ifdef SQL_TYPE_TIMESTAMP
02063 result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
02064 #else
02065 result = SQL_TIMESTAMP;
02066 #endif
02067 } else if (strncmp(p, "datetime", 8) == 0) {
02068 #ifdef SQL_TYPE_TIMESTAMP
02069 result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
02070 #else
02071 result = SQL_TIMESTAMP;
02072 #endif
02073 } else if (strncmp(p, "time", 4) == 0) {
02074 #ifdef SQL_TYPE_TIME
02075 result = ov3 ? SQL_TYPE_TIME : SQL_TIME;
02076 #else
02077 result = SQL_TIME;
02078 #endif
02079 } else if (strncmp(p, "date", 4) == 0) {
02080 #ifdef SQL_TYPE_DATE
02081 result = ov3 ? SQL_TYPE_DATE : SQL_DATE;
02082 #else
02083 result = SQL_DATE;
02084 #endif
02085 #ifdef SQL_LONGVARCHAR
02086 } else if (strncmp(p, "text", 4) == 0 ||
02087 strncmp(p, "memo", 4) == 0 ||
02088 strncmp(p, "longvarchar", 11) == 0) {
02089 #ifdef WINTERFACE
02090 result = nowchar ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
02091 #else
02092 result = SQL_LONGVARCHAR;
02093 #endif
02094 #ifdef WINTERFACE
02095 } else if (strncmp(p, "wtext", 5) == 0 ||
02096 strncmp(p, "wvarchar", 8) == 0 ||
02097 strncmp(p, "longwvarchar", 12) == 0) {
02098 result = SQL_WLONGVARCHAR;
02099 #endif
02100 #endif
02101 #ifdef SQL_BIT
02102 } else if (strncmp(p, "bool", 4) == 0 ||
02103 strncmp(p, "bit", 3) == 0) {
02104 result = SQL_BIT;
02105 #endif
02106 #ifdef SQL_BIGINT
02107 } else if (strncmp(p, "bigint", 6) == 0) {
02108 testsign = 1;
02109 result = SQL_BIGINT;
02110 #endif
02111 } else if (strncmp(p, "blob", 4) == 0) {
02112 result = SQL_BINARY;
02113 } else if (strncmp(p, "varbinary", 9) == 0) {
02114 result = SQL_VARBINARY;
02115 } else if (strncmp(p, "longvarbinary", 13) == 0) {
02116 result = SQL_LONGVARBINARY;
02117 }
02118 if (nosign) {
02119 if (testsign) {
02120 *nosign = strstr(p, "unsigned") != NULL;
02121 } else {
02122 *nosign = 1;
02123 }
02124 }
02125 #ifdef SQL_BIGINT
02126 if (dobigint && result == SQL_INTEGER) {
02127 result = SQL_BIGINT;
02128 }
02129 #endif
02130 xfree(p);
02131 return result;
02132 }
02133
02143 static void
02144 getmd(const char *typename, int sqltype, int *mp, int *dp)
02145 {
02146 int m = 0, d = 0;
02147
02148 switch (sqltype) {
02149 case SQL_INTEGER: m = 10; d = 9; break;
02150 case SQL_TINYINT: m = 4; d = 3; break;
02151 case SQL_SMALLINT: m = 6; d = 5; break;
02152 case SQL_FLOAT: m = 25; d = 24; break;
02153 case SQL_DOUBLE: m = 54; d = 53; break;
02154 case SQL_VARCHAR: m = 255; d = 0; break;
02155 #ifdef WINTERFACE
02156 #ifdef SQL_WVARCHAR
02157 case SQL_WVARCHAR: m = 255; d = 0; break;
02158 #endif
02159 #endif
02160 #ifdef SQL_TYPE_DATE
02161 case SQL_TYPE_DATE:
02162 #endif
02163 case SQL_DATE: m = 10; d = 0; break;
02164 #ifdef SQL_TYPE_TIME
02165 case SQL_TYPE_TIME:
02166 #endif
02167 case SQL_TIME: m = 8; d = 0; break;
02168 #ifdef SQL_TYPE_TIMESTAMP
02169 case SQL_TYPE_TIMESTAMP:
02170 #endif
02171 case SQL_TIMESTAMP: m = 32; d = 3; break;
02172 #ifdef SQL_LONGVARCHAR
02173 case SQL_LONGVARCHAR : m = 65536; d = 0; break;
02174 #endif
02175 #ifdef WINTERFACE
02176 #ifdef SQL_WLONGVARCHAR
02177 case SQL_WLONGVARCHAR: m = 65536; d = 0; break;
02178 #endif
02179 #endif
02180 case SQL_VARBINARY: m = 255; d = 0; break;
02181 case SQL_LONGVARBINARY: m = 65536; d = 0; break;
02182 #ifdef SQL_BIGINT
02183 case SQL_BIGINT: m = 20; d = 19; break;
02184 #endif
02185 #ifdef SQL_BIT
02186 case SQL_BIT: m = 1; d = 1; break;
02187 #endif
02188 }
02189 if (m && typename) {
02190 int mm, dd;
02191
02192 if (sscanf(typename, "%*[^(](%d)", &mm) == 1) {
02193 if (sqltype == SQL_TIMESTAMP) {
02194 d = mm;
02195 }
02196 #ifdef SQL_TYPE_TIMESTAMP
02197 else if (sqltype == SQL_TYPE_TIMESTAMP) {
02198 d = mm;
02199 }
02200 #endif
02201 else {
02202 m = d = mm;
02203 }
02204 } else if (sscanf(typename, "%*[^(](%d,%d)", &mm, &dd) == 2) {
02205 m = mm;
02206 d = dd;
02207 }
02208 }
02209 if (mp) {
02210 *mp = m;
02211 }
02212 if (dp) {
02213 *dp = d;
02214 }
02215 }
02216
02226 static int
02227 mapdeftype(int type, int stype, int nosign, int nowchar)
02228 {
02229 if (type == SQL_C_DEFAULT) {
02230 switch (stype) {
02231 case SQL_INTEGER:
02232 type = (nosign > 0) ? SQL_C_ULONG : SQL_C_LONG;
02233 break;
02234 case SQL_TINYINT:
02235 type = (nosign > 0) ? SQL_C_UTINYINT : SQL_C_TINYINT;
02236 break;
02237 case SQL_SMALLINT:
02238 type = (nosign > 0) ? SQL_C_USHORT : SQL_C_SHORT;
02239 break;
02240 case SQL_FLOAT:
02241 type = SQL_C_FLOAT;
02242 break;
02243 case SQL_DOUBLE:
02244 type = SQL_C_DOUBLE;
02245 break;
02246 case SQL_TIMESTAMP:
02247 type = SQL_C_TIMESTAMP;
02248 break;
02249 case SQL_TIME:
02250 type = SQL_C_TIME;
02251 break;
02252 case SQL_DATE:
02253 type = SQL_C_DATE;
02254 break;
02255 #ifdef SQL_C_TYPE_TIMESTAMP
02256 case SQL_TYPE_TIMESTAMP:
02257 type = SQL_C_TYPE_TIMESTAMP;
02258 break;
02259 #endif
02260 #ifdef SQL_C_TYPE_TIME
02261 case SQL_TYPE_TIME:
02262 type = SQL_C_TYPE_TIME;
02263 break;
02264 #endif
02265 #ifdef SQL_C_TYPE_DATE
02266 case SQL_TYPE_DATE:
02267 type = SQL_C_TYPE_DATE;
02268 break;
02269 #endif
02270 #ifdef WINTERFACE
02271 case SQL_WVARCHAR:
02272 case SQL_WCHAR:
02273 #ifdef SQL_WLONGVARCHAR
02274 case SQL_WLONGVARCHAR:
02275 #endif
02276 type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
02277 break;
02278 #endif
02279 case SQL_BINARY:
02280 case SQL_VARBINARY:
02281 case SQL_LONGVARBINARY:
02282 type = SQL_C_BINARY;
02283 break;
02284 #ifdef SQL_BIT
02285 case SQL_BIT:
02286 type = SQL_C_BIT;
02287 break;
02288 #endif
02289 #ifdef SQL_BIGINT
02290 case SQL_BIGINT:
02291 type = SQL_C_CHAR;
02292 break;
02293 #endif
02294 default:
02295 #ifdef WINTERFACE
02296 type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
02297 #else
02298 type = SQL_C_CHAR;
02299 #endif
02300 break;
02301 }
02302 }
02303 return type;
02304 }
02305
02316 static char *
02317 fixupsql(char *sql, int sqlLen, int *nparam, int *isselect, char **errmsg)
02318 {
02319 char *q = sql, *qz = NULL, *p, *inq = NULL, *out;
02320 int np = 0, isddl = -1, size;
02321
02322 *errmsg = NULL;
02323 if (sqlLen != SQL_NTS) {
02324 qz = q = xmalloc(sqlLen + 1);
02325 if (!qz) {
02326 return NULL;
02327 }
02328 memcpy(q, sql, sqlLen);
02329 q[sqlLen] = '\0';
02330 size = sqlLen * 4;
02331 } else {
02332 size = strlen(sql) * 4;
02333 }
02334 size += sizeof (char *) - 1;
02335 size &= ~(sizeof (char *) - 1);
02336 p = xmalloc(size);
02337 if (!p) {
02338 errout:
02339 freep(&qz);
02340 return NULL;
02341 }
02342 memset(p, 0, size);
02343 out = p;
02344 while (*q) {
02345 switch (*q) {
02346 case '\'':
02347 case '\"':
02348 if (q == inq) {
02349 inq = NULL;
02350 } else if (!inq) {
02351 inq = q + 1;
02352
02353 while (*inq) {
02354 if (*inq == *q) {
02355 if (inq[1] == *q) {
02356 inq++;
02357 } else {
02358 break;
02359 }
02360 }
02361 inq++;
02362 }
02363 }
02364 *p++ = *q;
02365 break;
02366 case '?':
02367 *p++ = *q;
02368 if (!inq) {
02369 np++;
02370 }
02371 break;
02372 case ';':
02373 if (!inq) {
02374 if (isddl < 0) {
02375 char *qq = out;
02376
02377 while (*qq && ISSPACE(*qq)) {
02378 ++qq;
02379 }
02380 if (*qq && *qq != ';') {
02381 int i;
02382 static const struct {
02383 int len;
02384 const char *str;
02385 } ddlstr[] = {
02386 { 5, "alter" },
02387 { 7, "analyze" },
02388 { 6, "attach" },
02389 { 5, "begin" },
02390 { 6, "commit" },
02391 { 6, "create" },
02392 { 6, "detach" },
02393 { 4, "drop" },
02394 { 3, "end" },
02395 { 7, "reindex" },
02396 { 7, "release" },
02397 { 8, "rollback" },
02398 { 9, "savepoint" },
02399 { 6, "vacuum" }
02400 };
02401
02402 size = strlen(qq);
02403 for (i = 0; i < array_size(ddlstr); i++) {
02404 if (size >= ddlstr[i].len &&
02405 strncasecmp(qq, ddlstr[i].str, ddlstr[i].len)
02406 == 0) {
02407 isddl = 1;
02408 break;
02409 }
02410 }
02411 if (isddl != 1) {
02412 isddl = 0;
02413 }
02414 }
02415 }
02416 if (isddl == 0) {
02417 char *qq = q;
02418
02419 do {
02420 ++qq;
02421 } while (*qq && ISSPACE(*qq));
02422 if (*qq && *qq != ';') {
02423 freep(&out);
02424 *errmsg = "only one SQL statement allowed";
02425 goto errout;
02426 }
02427 }
02428 }
02429 *p++ = *q;
02430 break;
02431 case '{':
02432
02433
02434
02435
02436
02437 if (!inq) {
02438 int ojfn = 0;
02439 char *inq2 = NULL, *end = q + 1;
02440
02441 while (*end && ISSPACE(*end)) {
02442 ++end;
02443 }
02444 if (*end != 'd' && *end != 'D' &&
02445 *end != 't' && *end != 'T') {
02446 ojfn = 1;
02447 }
02448 while (*end) {
02449 if (inq2 && *end == *inq2) {
02450 inq2 = NULL;
02451 } else if (inq2 == NULL && *end == '}') {
02452 break;
02453 } else if (inq2 == NULL && (*end == '\'' || *end == '"')) {
02454 inq2 = end;
02455 }
02456 ++end;
02457 }
02458 if (*end == '}') {
02459 char *start = q + 1;
02460 char *end2 = end - 1;
02461
02462 if (ojfn) {
02463 while (start < end) {
02464 if (ISSPACE(*start)) {
02465 break;
02466 }
02467 ++start;
02468 }
02469 while (start < end) {
02470 *p++ = *start;
02471 ++start;
02472 }
02473 q = end;
02474 break;
02475 } else {
02476 while (start < end2 && *start != '\'') {
02477 ++start;
02478 }
02479 while (end2 > start && *end2 != '\'') {
02480 --end2;
02481 }
02482 if (*start == '\'' && *end2 == '\'') {
02483 while (start <= end2) {
02484 *p++ = *start;
02485 ++start;
02486 }
02487 q = end;
02488 break;
02489 }
02490 }
02491 }
02492 }
02493
02494 default:
02495 *p++ = *q;
02496 }
02497 ++q;
02498 }
02499 freep(&qz);
02500 *p = '\0';
02501 if (nparam) {
02502 *nparam = np;
02503 }
02504 if (isselect) {
02505 if (isddl > 0) {
02506 *isselect = 2;
02507 } else {
02508 int incom = 0;
02509
02510 p = out;
02511 while (*p) {
02512 switch (*p) {
02513 case '-':
02514 if (!incom && p[1] == '-') {
02515 incom = -1;
02516 }
02517 break;
02518 case '\n':
02519 if (incom < 0) {
02520 incom = 0;
02521 }
02522 break;
02523 case '/':
02524 if (incom > 0 && p[-1] == '*') {
02525 incom = 0;
02526 p++;
02527 continue;
02528 } else if (!incom && p[1] == '*') {
02529 incom = 1;
02530 }
02531 break;
02532 }
02533 if (!incom && !ISSPACE(*p)) {
02534 break;
02535 }
02536 p++;
02537 }
02538 size = strlen(p);
02539 if (size >= 6 &&
02540 (strncasecmp(p, "select", 6) == 0 ||
02541 strncasecmp(p, "pragma", 6) == 0)) {
02542 *isselect = 1;
02543 } else {
02544 *isselect = 0;
02545 }
02546 }
02547 }
02548 return out;
02549 }
02550
02559 static int
02560 findcol(char **cols, int ncols, char *name)
02561 {
02562 int i;
02563
02564 if (cols) {
02565 for (i = 0; i < ncols; i++) {
02566 if (strcmp(cols[i], name) == 0) {
02567 return i;
02568 }
02569 }
02570 }
02571 return -1;
02572 }
02573
02590 static void
02591 fixupdyncols(STMT *s, DBC *d)
02592 {
02593 int i;
02594 #if !defined(HAVE_SQLITE3TABLECOLUMNMETADATA) || !(HAVE_SQLITE3TABLECOLUMNMETADATA)
02595 int k, pk, nn, t, r, nrows, ncols;
02596 char **rowp, *flagp, flags[128];
02597 #endif
02598
02599 if (!s->dyncols) {
02600 return;
02601 }
02602
02603 if (!s->longnames) {
02604 if (s->dcols > 1) {
02605 char *table = s->dyncols[0].table;
02606
02607 for (i = 1; table[0] && i < s->dcols; i++) {
02608 if (strcmp(s->dyncols[i].table, table)) {
02609 break;
02610 }
02611 }
02612 if (i >= s->dcols) {
02613 for (i = 0; i < s->dcols; i++) {
02614 s->dyncols[i].label = s->dyncols[i].column;
02615 }
02616 }
02617 } else if (s->dcols == 1) {
02618 s->dyncols[0].label = s->dyncols[0].column;
02619 }
02620 }
02621 for (i = 0; i < s->dcols; i++) {
02622 s->dyncols[i].type =
02623 mapsqltype(s->dyncols[i].typename, &s->dyncols[i].nosign, *s->ov3,
02624 s->nowchar[0] || s->nowchar[1], s->dobigint);
02625 getmd(s->dyncols[i].typename, s->dyncols[i].type,
02626 &s->dyncols[i].size, &s->dyncols[i].prec);
02627 #ifdef SQL_LONGVARCHAR
02628 if (s->dyncols[i].type == SQL_VARCHAR &&
02629 s->dyncols[i].size > 255) {
02630 s->dyncols[i].type = SQL_LONGVARCHAR;
02631 }
02632 #endif
02633 #ifdef WINTERFACE
02634 #ifdef SQL_WLONGVARCHAR
02635 if (s->dyncols[i].type == SQL_WVARCHAR &&
02636 s->dyncols[i].size > 255) {
02637 s->dyncols[i].type = SQL_WLONGVARCHAR;
02638 }
02639 #endif
02640 #endif
02641 if (s->dyncols[i].type == SQL_VARBINARY &&
02642 s->dyncols[i].size > 255) {
02643 s->dyncols[i].type = SQL_LONGVARBINARY;
02644 }
02645 }
02646 #if !defined(HAVE_SQLITE3TABLECOLUMNMETADATA) || !(HAVE_SQLITE3TABLECOLUMNMETADATA)
02647 if (s->dcols > array_size(flags)) {
02648 flagp = xmalloc(sizeof (flags[0]) * s->dcols);
02649 if (flagp == NULL) {
02650 return;
02651 }
02652 } else {
02653 flagp = flags;
02654 }
02655 memset(flagp, 0, sizeof (flags[0]) * s->dcols);
02656 for (i = 0; i < s->dcols; i++) {
02657 s->dyncols[i].autoinc = SQL_FALSE;
02658 s->dyncols[i].notnull = SQL_NULLABLE;
02659 }
02660 for (i = 0; i < s->dcols; i++) {
02661 int ret, lastpk = -1, autoinccount = 0;
02662 char *sql;
02663
02664 if (!s->dyncols[i].table[0]) {
02665 continue;
02666 }
02667 if (flagp[i]) {
02668 continue;
02669 }
02670 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", s->dyncols[i].table);
02671 if (!sql) {
02672 continue;
02673 }
02674 dbtraceapi(d, "sqlite3_get_table", sql);
02675 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, NULL);
02676 sqlite3_free(sql);
02677 if (ret != SQLITE_OK) {
02678 continue;
02679 }
02680 k = findcol(rowp, ncols, "name");
02681 t = findcol(rowp, ncols, "type");
02682 pk = findcol(rowp, ncols, "pk");
02683 nn = findcol(rowp, ncols, "notnull");
02684 if (k < 0 || t < 0) {
02685 goto freet;
02686 }
02687 for (r = 1; r <= nrows; r++) {
02688 int m;
02689
02690 for (m = i; m < s->dcols; m++) {
02691 char *colname = s->dyncols[m].column;
02692
02693 if (s->longnames) {
02694 char *dotp = strchr(colname, '.');
02695
02696 if (dotp) {
02697 colname = dotp + 1;
02698 }
02699 }
02700 if (!flagp[m] &&
02701 strcmp(colname, rowp[r * ncols + k]) == 0 &&
02702 strcmp(s->dyncols[m].table, s->dyncols[i].table) == 0) {
02703 char *typename = rowp[r * ncols + t];
02704
02705 flagp[m] = 1;
02706 freep(&s->dyncols[m].typename);
02707 s->dyncols[m].typename = xstrdup(typename);
02708 s->dyncols[m].type =
02709 mapsqltype(typename, &s->dyncols[m].nosign, *s->ov3,
02710 s->nowchar[0] || s->nowchar[1],
02711 s->dobigint);
02712 getmd(typename, s->dyncols[m].type, &s->dyncols[m].size,
02713 &s->dyncols[m].prec);
02714 #ifdef SQL_LONGVARCHAR
02715 if (s->dyncols[m].type == SQL_VARCHAR &&
02716 s->dyncols[m].size > 255) {
02717 s->dyncols[m].type = SQL_LONGVARCHAR;
02718 }
02719 #endif
02720 #ifdef WINTERFACE
02721 #ifdef SQL_WLONGVARCHAR
02722 if (s->dyncols[i].type == SQL_WVARCHAR &&
02723 s->dyncols[i].size > 255) {
02724 s->dyncols[i].type = SQL_WLONGVARCHAR;
02725 }
02726 #endif
02727 #endif
02728 if (s->dyncols[i].type == SQL_VARBINARY &&
02729 s->dyncols[i].size > 255) {
02730 s->dyncols[i].type = SQL_LONGVARBINARY;
02731 }
02732 if (pk >= 0 && strcmp(rowp[r * ncols + pk], "1") == 0) {
02733 if (++autoinccount > 1) {
02734 if (lastpk >= 0) {
02735 s->dyncols[lastpk].autoinc = SQL_FALSE;
02736 lastpk = -1;
02737 }
02738 } else {
02739 lastpk = m;
02740 if (strlen(typename) == 7 &&
02741 strncasecmp(typename, "integer", 7) == 0) {
02742 s->dyncols[m].autoinc = SQL_TRUE;
02743 }
02744 }
02745 }
02746 if (nn >= 0 && rowp[r * ncols + nn][0] != '0') {
02747 s->dyncols[m].notnull = SQL_NO_NULLS;
02748 }
02749 }
02750 }
02751 }
02752 freet:
02753 sqlite3_free_table(rowp);
02754 }
02755 if (flagp != flags) {
02756 freep(&flagp);
02757 }
02758 #endif
02759 }
02760
02767 static void
02768 convJD2YMD(double jd, DATE_STRUCT *ds)
02769 {
02770 int z, a, b, c, d, e, x1;
02771 sqlite_int64 ijd;
02772
02773 ijd = jd * 86400000.0 + 0.5;
02774 z = (int) ((ijd + 43200000) / 86400000);
02775 a = (int) ((z - 1867216.25) / 36524.25);
02776 a = z + 1 + a - (a / 4);
02777 b = a + 1524;
02778 c = (int) ((b - 122.1) / 365.25);
02779 d = (36525 * c) / 100;
02780 e = (int) ((b - d) / 30.6001);
02781 x1 = (int) (30.6001 * e);
02782 ds->day = b - d - x1;
02783 ds->month = (e < 14) ? (e - 1) : (e - 13);
02784 ds->year = (ds->month > 2) ? (c - 4716) : (c - 4715);
02785 }
02786
02787
02795 static void
02796 convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
02797 {
02798 int s;
02799 double ds;
02800 sqlite_int64 ijd;
02801
02802 ijd = jd * 86400000.0 + 0.5;
02803 s = (int)((ijd + 43200000) % 86400000);
02804 ds = s / 1000.0;
02805 if (fp) {
02806 *fp = (s % 1000) * 1000000;
02807 }
02808 s = (int) ds;
02809 ds -= s;
02810 ts->hour = s / 3600;
02811 s -= ts->hour * 3600;
02812 ts->minute = s / 60;
02813 ds += s - ts->minute *60;
02814 ts->second = (int) ds;
02815 }
02816
02824 static int
02825 getmdays(int year, int month)
02826 {
02827 static const int mdays[] = {
02828 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
02829 };
02830 int mday;
02831
02832 if (month < 1) {
02833 return 0;
02834 }
02835 mday = mdays[(month - 1) % 12];
02836 if (mday == 28 && year % 4 == 0 &&
02837 (!(year % 100 == 0) || year % 400 == 0)) {
02838 mday++;
02839 }
02840 return mday;
02841 }
02842
02858 static int
02859 str2date(int jdconv, char *str, DATE_STRUCT *ds)
02860 {
02861 int i, err = 0;
02862 double jd;
02863 char *p, *q, sepc = '\0';
02864
02865 ds->year = ds->month = ds->day = 0;
02866 if (jdconv) {
02867 p = strchr(str, '.');
02868 if (p) {
02869
02870 p = 0;
02871 jd = ln_strtod(str, &p);
02872 if (p && p > str) {
02873 convJD2YMD(jd, ds);
02874 return 0;
02875 }
02876 }
02877 }
02878 p = str;
02879 while (*p && !ISDIGIT(*p)) {
02880 ++p;
02881 }
02882 q = p;
02883 i = 0;
02884 while (*q && !ISDIGIT(*q)) {
02885 ++i;
02886 ++q;
02887 }
02888 if (i >= 8) {
02889 char buf[8];
02890
02891 strncpy(buf, p + 0, 4); buf[4] = '\0';
02892 ds->year = strtol(buf, NULL, 10);
02893 strncpy(buf, p + 4, 2); buf[2] = '\0';
02894 ds->month = strtol(buf, NULL, 10);
02895 strncpy(buf, p + 6, 2); buf[2] = '\0';
02896 ds->day = strtol(buf, NULL, 10);
02897 goto done;
02898 }
02899 i = 0;
02900 while (i < 3) {
02901 int n;
02902
02903 q = NULL;
02904 n = strtol(p, &q, 10);
02905 if (!q || q == p) {
02906 if (*q == '\0') {
02907 if (i == 0) {
02908 err = 1;
02909 }
02910 goto done;
02911 }
02912 }
02913 if (!sepc) {
02914 sepc = *q;
02915 }
02916 if (*q == '-' || *q == '/' || *q == '\0' || i == 2) {
02917 switch (i) {
02918 case 0: ds->year = n; break;
02919 case 1: ds->month = n; break;
02920 case 2: ds->day = n; break;
02921 }
02922 ++i;
02923 if (*q) {
02924 ++q;
02925 }
02926 } else {
02927 i = 0;
02928 while (*q && !ISDIGIT(*q)) {
02929 ++q;
02930 }
02931 }
02932 p = q;
02933 }
02934 done:
02935
02936 if (err ||
02937 ds->month < 1 || ds->month > 12 ||
02938 ds->day < 1 || ds->day > getmdays(ds->year, ds->month)) {
02939 if (sepc == '/') {
02940
02941 int t[3];
02942
02943 t[0] = ds->year;
02944 t[1] = ds->month;
02945 t[2] = ds->day;
02946 ds->year = t[2];
02947 ds->day = t[1];
02948 ds->month = t[0];
02949 if (ds->month >= 1 && ds->month <= 12 &&
02950 (ds->day >= 1 || ds->day <= getmdays(ds->year, ds->month))) {
02951 return 0;
02952 }
02953 }
02954 return -1;
02955 }
02956 return 0;
02957 }
02958
02973 static int
02974 str2time(int jdconv, char *str, TIME_STRUCT *ts)
02975 {
02976 int i, err = 0, ampm = -1;
02977 double jd;
02978 char *p, *q;
02979
02980 ts->hour = ts->minute = ts->second = 0;
02981 if (jdconv) {
02982 p = strchr(str, '.');
02983 if (p) {
02984
02985 p = 0;
02986 jd = ln_strtod(str, &p);
02987 if (p && p > str) {
02988 convJD2HMS(jd, ts, 0);
02989 return 0;
02990 }
02991 }
02992 }
02993 p = str;
02994 while (*p && !ISDIGIT(*p)) {
02995 ++p;
02996 }
02997 q = p;
02998 i = 0;
02999 while (*q && ISDIGIT(*q)) {
03000 ++i;
03001 ++q;
03002 }
03003 if (i >= 6) {
03004 char buf[4];
03005
03006 strncpy(buf, p + 0, 2); buf[2] = '\0';
03007 ts->hour = strtol(buf, NULL, 10);
03008 strncpy(buf, p + 2, 2); buf[2] = '\0';
03009 ts->minute = strtol(buf, NULL, 10);
03010 strncpy(buf, p + 4, 2); buf[2] = '\0';
03011 ts->second = strtol(buf, NULL, 10);
03012 goto done;
03013 }
03014 i = 0;
03015 while (i < 3) {
03016 int n;
03017
03018 q = NULL;
03019 n = strtol(p, &q, 10);
03020 if (!q || q == p) {
03021 if (*q == '\0') {
03022 if (i == 0) {
03023 err = 1;
03024 }
03025 goto done;
03026 }
03027 }
03028 if (*q == ':' || *q == '\0' || i == 2) {
03029 switch (i) {
03030 case 0: ts->hour = n; break;
03031 case 1: ts->minute = n; break;
03032 case 2: ts->second = n; break;
03033 }
03034 ++i;
03035 if (*q) {
03036 ++q;
03037 }
03038 } else {
03039 i = 0;
03040 while (*q && !ISDIGIT(*q)) {
03041 ++q;
03042 }
03043 }
03044 p = q;
03045 }
03046 if (!err) {
03047 while (*p) {
03048 if ((p[0] == 'p' || p[0] == 'P') &&
03049 (p[1] == 'm' || p[1] == 'M')) {
03050 ampm = 1;
03051 } else if ((p[0] == 'a' || p[0] == 'A') &&
03052 (p[1] == 'm' || p[1] == 'M')) {
03053 ampm = 0;
03054 }
03055 ++p;
03056 }
03057 if (ampm > 0) {
03058 if (ts->hour < 12) {
03059 ts->hour += 12;
03060 }
03061 } else if (ampm == 0) {
03062 if (ts->hour == 12) {
03063 ts->hour = 0;
03064 }
03065 }
03066 }
03067 done:
03068
03069 if (err || ts->hour > 23 || ts->minute > 59 || ts->second > 59) {
03070 return -1;
03071 }
03072 return 0;
03073 }
03074
03094 static int
03095 str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
03096 {
03097 int i, m, n, err = 0, ampm = -1;
03098 double jd;
03099 char *p, *q, in = '\0', sepc = '\0';
03100
03101 tss->year = tss->month = tss->day = 0;
03102 tss->hour = tss->minute = tss->second = 0;
03103 tss->fraction = 0;
03104 if (jdconv) {
03105 p = strchr(str, '.');
03106 if (p) {
03107 q = strchr(str, '-');
03108 if (q == str) {
03109 q = 0;
03110 }
03111 if (!q) {
03112 q = strchr(str, '/');
03113 if (!q) {
03114 q = strchr(str, ':');
03115 }
03116 }
03117 if (!q || q > p) {
03118
03119 p = 0;
03120 jd = ln_strtod(str, &p);
03121 if (p && p > str) {
03122 DATE_STRUCT ds;
03123 TIME_STRUCT ts;
03124
03125 convJD2YMD(jd, &ds);
03126 convJD2HMS(jd, &ts, &n);
03127 tss->year = ds.year;
03128 tss->month = ds.month;
03129 tss->day = ds.day;
03130 tss->hour = ts.hour;
03131 tss->minute = ts.minute;
03132 tss->second = ts.second;
03133 tss->fraction = n;
03134 return 0;
03135 }
03136 }
03137 }
03138 }
03139 p = str;
03140 while (*p && !ISDIGIT(*p)) {
03141 ++p;
03142 }
03143 q = p;
03144 i = 0;
03145 while (*q && ISDIGIT(*q)) {
03146 ++i;
03147 ++q;
03148 }
03149 if (i >= 14) {
03150 char buf[16];
03151
03152 strncpy(buf, p + 0, 4); buf[4] = '\0';
03153 tss->year = strtol(buf, NULL, 10);
03154 strncpy(buf, p + 4, 2); buf[2] = '\0';
03155 tss->month = strtol(buf, NULL, 10);
03156 strncpy(buf, p + 6, 2); buf[2] = '\0';
03157 tss->day = strtol(buf, NULL, 10);
03158 strncpy(buf, p + 8, 2); buf[2] = '\0';
03159 tss->hour = strtol(buf, NULL, 10);
03160 strncpy(buf, p + 10, 2); buf[2] = '\0';
03161 tss->minute = strtol(buf, NULL, 10);
03162 strncpy(buf, p + 12, 2); buf[2] = '\0';
03163 tss->second = strtol(buf, NULL, 10);
03164 if (i > 14) {
03165 m = i - 14;
03166 strncpy(buf, p + 14, m);
03167 while (m < 9) {
03168 buf[m] = '0';
03169 ++m;
03170 }
03171 buf[m] = '\0';
03172 tss->fraction = strtol(buf, NULL, 10);
03173 }
03174 m = 7;
03175 goto done;
03176 }
03177 m = i = 0;
03178 while ((m & 7) != 7) {
03179 q = NULL;
03180 n = strtol(p, &q, 10);
03181 if (!q || q == p) {
03182 if (*q == '\0') {
03183 if (m < 1) {
03184 err = 1;
03185 }
03186 goto done;
03187 }
03188 }
03189 if (in == '\0') {
03190 switch (*q) {
03191 case '-':
03192 case '/':
03193 if ((m & 1) == 0) {
03194 in = *q;
03195 i = 0;
03196 }
03197 break;
03198 case ':':
03199 if ((m & 2) == 0) {
03200 in = *q;
03201 i = 0;
03202 }
03203 break;
03204 case ' ':
03205 case '.':
03206 break;
03207 default:
03208 in = '\0';
03209 i = 0;
03210 break;
03211 }
03212 }
03213 switch (in) {
03214 case '-':
03215 case '/':
03216 if (!sepc) {
03217 sepc = in;
03218 }
03219 switch (i) {
03220 case 0: tss->year = n; break;
03221 case 1: tss->month = n; break;
03222 case 2: tss->day = n; break;
03223 }
03224 if (++i >= 3) {
03225 i = 0;
03226 m |= 1;
03227 if (!(m & 2)) {
03228 m |= 8;
03229 }
03230 goto skip;
03231 } else {
03232 ++q;
03233 }
03234 break;
03235 case ':':
03236 switch (i) {
03237 case 0: tss->hour = n; break;
03238 case 1: tss->minute = n; break;
03239 case 2: tss->second = n; break;
03240 }
03241 if (++i >= 3) {
03242 i = 0;
03243 m |= 2;
03244 if (*q == '.') {
03245 in = '.';
03246 goto skip2;
03247 }
03248 if (*q == ' ') {
03249 if ((m & 1) == 0) {
03250 char *e = NULL;
03251
03252 (void) strtol(q + 1, &e, 10);
03253 if (e && *e == '-') {
03254 goto skip;
03255 }
03256 }
03257 in = '.';
03258 goto skip2;
03259 }
03260 goto skip;
03261 } else {
03262 ++q;
03263 }
03264 break;
03265 case '.':
03266 if (++i >= 1) {
03267 int ndig = q - p;
03268
03269 if (p[0] == '+' || p[0] == '-') {
03270 ndig--;
03271 }
03272 while (ndig < 9) {
03273 n = n * 10;
03274 ++ndig;
03275 }
03276 tss->fraction = n;
03277 m |= 4;
03278 i = 0;
03279 }
03280 default:
03281 skip:
03282 in = '\0';
03283 skip2:
03284 while (*q && !ISDIGIT(*q)) {
03285 if ((q[0] == 'a' || q[0] == 'A') &&
03286 (q[1] == 'm' || q[1] == 'M')) {
03287 ampm = 0;
03288 ++q;
03289 } else if ((q[0] == 'p' || q[0] == 'P') &&
03290 (q[1] == 'm' || q[1] == 'M')) {
03291 ampm = 1;
03292 ++q;
03293 }
03294 ++q;
03295 }
03296 }
03297 p = q;
03298 }
03299 if ((m & 7) > 1 && (m & 8)) {
03300
03301 if (p > str && ISDIGIT(*p)) {
03302 int nn, sign;
03303
03304 q = p - 1;
03305 if (*q != '+' && *q != '-') {
03306 goto done;
03307 }
03308 sign = (*q == '+') ? -1 : 1;
03309 q = NULL;
03310 n = strtol(p, &q, 10);
03311 if (!q || *q++ != ':' || !ISDIGIT(*q)) {
03312 goto done;
03313 }
03314 p = q;
03315 q = NULL;
03316 nn = strtol(p, &q, 10);
03317 tss->minute += nn * sign;
03318 if ((SQLSMALLINT) tss->minute < 0) {
03319 tss->hour -= 1;
03320 tss->minute += 60;
03321 } else if (tss->minute >= 60) {
03322 tss->hour += 1;
03323 tss->minute -= 60;
03324 }
03325 tss->hour += n * sign;
03326 if ((SQLSMALLINT) tss->hour < 0) {
03327 tss->day -= 1;
03328 tss->hour += 24;
03329 } else if (tss->hour >= 24) {
03330 tss->day += 1;
03331 tss->hour -= 24;
03332 }
03333 if ((short) tss->day < 1 || tss->day >= 28) {
03334 int mday, pday, pmon;
03335
03336 mday = getmdays(tss->year, tss->month);
03337 pmon = tss->month - 1;
03338 if (pmon < 1) {
03339 pmon = 12;
03340 }
03341 pday = getmdays(tss->year, pmon);
03342 if ((SQLSMALLINT) tss->day < 1) {
03343 tss->month -= 1;
03344 tss->day = pday;
03345 } else if (tss->day > mday) {
03346 tss->month += 1;
03347 tss->day = 1;
03348 }
03349 if ((SQLSMALLINT) tss->month < 1) {
03350 tss->year -= 1;
03351 tss->month = 12;
03352 } else if (tss->month > 12) {
03353 tss->year += 1;
03354 tss->month = 1;
03355 }
03356 }
03357 }
03358 }
03359 done:
03360 if ((m & 1) &&
03361 (tss->month < 1 || tss->month > 12 ||
03362 tss->day < 1 || tss->day > getmdays(tss->year, tss->month))) {
03363 if (sepc == '/') {
03364
03365 int t[3];
03366
03367 t[0] = tss->year;
03368 t[1] = tss->month;
03369 t[2] = tss->day;
03370 tss->year = t[2];
03371 tss->day = t[1];
03372 tss->month = t[0];
03373 }
03374 }
03375
03376 if (!err && (m & 1) == 0) {
03377 #ifdef _WIN32
03378 SYSTEMTIME t;
03379
03380 GetLocalTime(&t);
03381 tss->year = t.wYear;
03382 tss->month = t.wMonth;
03383 tss->day = t.wDay;
03384 #else
03385 struct timeval tv;
03386 struct tm tm;
03387
03388 gettimeofday(&tv, NULL);
03389 tm = *localtime(&tv.tv_sec);
03390 tss->year = tm.tm_year + 1900;
03391 tss->month = tm.tm_mon + 1;
03392 tss->day = tm.tm_mday;
03393 #endif
03394 }
03395
03396 if (tss->fraction < 0) {
03397 tss->fraction = 0;
03398 }
03399
03400 if (err ||
03401 tss->month < 1 || tss->month > 12 ||
03402 tss->day < 1 || tss->day > getmdays(tss->year, tss->month) ||
03403 tss->hour > 23 || tss->minute > 59 || tss->second > 59) {
03404 return -1;
03405 }
03406 if ((m & 7) > 1) {
03407 if (ampm > 0) {
03408 if (tss->hour < 12) {
03409 tss->hour += 12;
03410 }
03411 } else if (ampm == 0) {
03412 if (tss->hour == 12) {
03413 tss->hour = 0;
03414 }
03415 }
03416 }
03417 return ((m & 7) < 1) ? -1 : 0;
03418 }
03419
03426 static int
03427 getbool(char *string)
03428 {
03429 if (string) {
03430 return string[0] && strchr("Yy123456789Tt", string[0]) != NULL;
03431 }
03432 return 0;
03433 }
03434
03442 static void
03443 blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
03444 {
03445 #if 0
03446 DBC *d = (DBC *) sqlite3_user_data(ctx);
03447 #endif
03448 char *filename = 0;
03449
03450 if (nargs > 0) {
03451 if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
03452 filename = (char *) sqlite3_value_text(args[0]);
03453 }
03454 }
03455 if (filename) {
03456 #ifdef _WIN32
03457 char *wname = utf_to_wmb(filename, -1);
03458 FILE *f;
03459 #else
03460 FILE *f = fopen(filename, "r");
03461 #endif
03462 char *p;
03463 long n, nn;
03464
03465 #ifdef _WIN32
03466 if (wname) {
03467 f = fopen(wname, "rb");
03468 } else {
03469 sqlite3_result_error(ctx, "out of memory", -1);
03470 return;
03471 }
03472 uc_free(wname);
03473 #endif
03474 if (f) {
03475 if (fseek(f, 0, SEEK_END) == 0) {
03476 n = ftell(f);
03477 if (fseek(f, 0, SEEK_SET) == 0) {
03478 p = sqlite3_malloc(n);
03479 if (p) {
03480 nn = fread(p, 1, n, f);
03481 if (nn != n) {
03482 sqlite3_result_error(ctx, "read error", -1);
03483 sqlite3_free(p);
03484 } else {
03485 sqlite3_result_blob(ctx, p, n, sqlite3_free);
03486 }
03487 } else {
03488 sqlite3_result_error(ctx, "out of memory", -1);
03489 }
03490 } else {
03491 sqlite3_result_error(ctx, "seek error", -1);
03492 }
03493 } else {
03494 sqlite3_result_error(ctx, "seek error", -1);
03495 }
03496 fclose(f);
03497 } else {
03498 sqlite3_result_error(ctx, "cannot open file", -1);
03499 }
03500 } else {
03501 sqlite3_result_error(ctx, "no filename given", -1);
03502 }
03503 }
03504
03512 static void
03513 blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
03514 {
03515 #if 0
03516 DBC *d = (DBC *) sqlite3_user_data(ctx);
03517 #endif
03518 char *filename = 0;
03519 char *p = 0;
03520 int n = 0;
03521
03522 if (nargs > 0) {
03523 p = (char *) sqlite3_value_blob(args[0]);
03524 n = sqlite3_value_bytes(args[0]);
03525 }
03526 if (nargs > 1) {
03527 if (sqlite3_value_type(args[1]) != SQLITE_NULL) {
03528 filename = (char *) sqlite3_value_text(args[1]);
03529 }
03530 }
03531 if (p) {
03532 if (filename) {
03533 #ifdef _WIN32
03534 char *wname = utf_to_wmb(filename, -1);
03535 FILE *f;
03536 #else
03537 FILE *f = fopen(filename, "w");
03538 #endif
03539 int nn;
03540
03541 #ifdef _WIN32
03542 if (wname) {
03543 f = fopen(wname, "wb");
03544 } else {
03545 sqlite3_result_error(ctx, "out of memory", -1);
03546 return;
03547 }
03548 uc_free(wname);
03549 #endif
03550 if (f) {
03551 nn = fwrite(p, 1, n, f);
03552 fclose(f);
03553 if (nn != n) {
03554 sqlite3_result_error(ctx, "write error", -1);
03555 } else {
03556 sqlite3_result_int(ctx, nn);
03557 }
03558 } else {
03559 sqlite3_result_error(ctx, "cannot open file", -1);
03560 }
03561 } else {
03562 sqlite3_result_error(ctx, "no filename given", -1);
03563 }
03564 } else {
03565 sqlite3_result_null(ctx);
03566 }
03567 }
03568
03576 static void
03577 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
03578 dbtrace(void *arg, const char *msg, sqlite_uint64 et)
03579 #else
03580 dbtrace(void *arg, const char *msg)
03581 #endif
03582 {
03583 DBC *d = (DBC *) arg;
03584
03585 if (msg && d->trace) {
03586 int len = strlen(msg);
03587 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
03588 unsigned long s, f;
03589 #endif
03590
03591 if (len > 0) {
03592 char *end = "\n";
03593
03594 if (msg[len - 1] != ';') {
03595 end = ";\n";
03596 }
03597 fprintf(d->trace, "%s%s", msg, end);
03598 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
03599 s = et / 1000000000LL;
03600 f = et % 1000000000LL;
03601 fprintf(d->trace, "-- took %lu.%09lu seconds\n", s, f);
03602 #endif
03603 fflush(d->trace);
03604 }
03605 }
03606 }
03607
03615 static void
03616 dbtraceapi(DBC *d, char *fn, const char *sql)
03617 {
03618 if (fn && d->trace) {
03619 if (sql) {
03620 fprintf(d->trace, "-- %s: %s\n", fn, sql);
03621 } else {
03622 fprintf(d->trace, "-- %s\n", fn);
03623 }
03624 fflush(d->trace);
03625 }
03626 }
03627
03635 static void
03636 dbtracerc(DBC *d, int rc, char *err)
03637 {
03638 if (rc != SQLITE_OK && d->trace) {
03639 fprintf(d->trace, "-- SQLITE ERROR CODE %d", rc);
03640 fprintf(d->trace, err ? ": %s\n" : "\n", err);
03641 fflush(d->trace);
03642 }
03643 }
03644
03659 static SQLRETURN
03660 dbopen(DBC *d, char *name, int isu, char *dsn, char *sflag,
03661 char *spflag, char *ntflag, char *jmode, char *busy)
03662 {
03663 char *endp = NULL;
03664 int rc, tmp, busyto = 100000;
03665 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
03666 int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
03667 char *uname = name;
03668 const char *vfs_name = NULL;
03669 #endif
03670
03671 if (d->sqlite) {
03672 if (d->trace) {
03673 fprintf(d->trace, "-- sqlite3_close (deferred): '%s'\n",
03674 d->dbname);
03675 fflush(d->trace);
03676 }
03677 sqlite3_close(d->sqlite);
03678 d->sqlite = NULL;
03679 }
03680 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
03681 if (d->nocreat) {
03682 flags &= ~ SQLITE_OPEN_CREATE;
03683 }
03684 #if defined(_WIN32) || defined(_WIN64)
03685 if (!isu) {
03686 char expname[MAX_PATH];
03687
03688 expname[0] = '\0';
03689 rc = ExpandEnvironmentStrings(name, expname, sizeof (expname));
03690 if (rc <= sizeof (expname)) {
03691 uname = wmb_to_utf(expname, rc - 1);
03692 } else {
03693 uname = wmb_to_utf(name, -1);
03694 }
03695 if (!uname) {
03696 rc = SQLITE_NOMEM;
03697 setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
03698 return SQL_ERROR;
03699 }
03700 }
03701 #endif
03702 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
03703 vfs_name = nvfs_makevfs(uname);
03704 #endif
03705 #ifdef SQLITE_OPEN_URI
03706 flags |= SQLITE_OPEN_URI;
03707 #endif
03708 rc = sqlite3_open_v2(uname, &d->sqlite, flags, vfs_name);
03709 #if defined(WINTERFACE) || defined(_WIN32) || defined(_WIN64)
03710 if (uname != name) {
03711 uc_free(uname);
03712 }
03713 #endif
03714 #else
03715 #if defined(_WIN32) || defined(_WIN64)
03716 if (d->nocreat) {
03717 char *cname = NULL;
03718
03719 if (isu) {
03720 cname = utf_to_wmb(name, -1);
03721 }
03722 if (GetFileAttributesA(cname ? cname : name) ==
03723 INVALID_FILE_ATTRIBUTES) {
03724 uc_free(cname);
03725 rc = SQLITE_CANTOPEN;
03726 setstatd(d, rc, "cannot open database",
03727 (*d->ov3) ? "HY000" : "S1000");
03728 return SQL_ERROR;
03729 }
03730 uc_free(cname);
03731 }
03732 #else
03733 if (d->nocreat && access(name, 004) < 0) {
03734 rc = SQLITE_CANTOPEN;
03735 setstatd(d, rc, "cannot open database", (*d->ov3) ? "HY000" : "S1000");
03736 return SQL_ERROR;
03737 }
03738 #endif
03739 #if defined(_WIN32) || defined(_WIN64)
03740 if (!isu) {
03741 WCHAR *wname = wmb_to_uc(name, -1);
03742
03743 if (!wname) {
03744 rc = SQLITE_NOMEM;
03745 setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
03746 return SQL_ERROR;
03747 }
03748 rc = sqlite3_open16(wname, &d->sqlite);
03749 uc_free(wname);
03750 } else
03751 #endif
03752 rc = sqlite3_open(name, &d->sqlite);
03753 #endif
03754 if (rc != SQLITE_OK) {
03755 connfail:
03756 setstatd(d, rc, "connect failed", (*d->ov3) ? "HY000" : "S1000");
03757 if (d->sqlite) {
03758 sqlite3_close(d->sqlite);
03759 d->sqlite = NULL;
03760 }
03761 return SQL_ERROR;
03762 }
03763 #if defined(SQLITE_DYNLOAD) || defined(SQLITE_HAS_CODEC)
03764 if (d->pwd) {
03765 sqlite3_key(d->sqlite, d->pwd, d->pwdLen);
03766 }
03767 #endif
03768 d->pwd = NULL;
03769 d->pwdLen = 0;
03770 if (d->trace) {
03771 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
03772 sqlite3_profile(d->sqlite, dbtrace, d);
03773 #else
03774 sqlite3_trace(d->sqlite, dbtrace, d);
03775 #endif
03776 }
03777 d->step_enable = getbool(sflag);
03778 d->trans_disable = getbool(ntflag);
03779 d->curtype = d->step_enable ?
03780 SQL_CURSOR_FORWARD_ONLY : SQL_CURSOR_STATIC;
03781 tmp = strtol(busy, &endp, 0);
03782 if (endp && *endp == '\0' && endp != busy) {
03783 busyto = tmp;
03784 }
03785 if (busyto < 1 || busyto > 1000000) {
03786 busyto = 1000000;
03787 }
03788 d->timeout = busyto;
03789 freep(&d->dbname);
03790 d->dbname = xstrdup(name);
03791 freep(&d->dsn);
03792 d->dsn = xstrdup(dsn);
03793 if ((rc = setsqliteopts(d->sqlite, d)) != SQLITE_OK) {
03794 if (d->trace) {
03795 fprintf(d->trace, "-- sqlite3_close: '%s'\n",
03796 d->dbname);
03797 fflush(d->trace);
03798 }
03799 sqlite3_close(d->sqlite);
03800 d->sqlite = NULL;
03801 goto connfail;
03802 }
03803 if (!spflag || spflag[0] == '\0') {
03804 spflag = "NORMAL";
03805 }
03806 if (spflag[0] != '\0') {
03807 char syncp[128];
03808
03809 sprintf(syncp, "PRAGMA synchronous = %8.8s;", spflag);
03810 sqlite3_exec(d->sqlite, syncp, NULL, NULL, NULL);
03811 }
03812 if (jmode[0] != '\0') {
03813 char jourp[128];
03814
03815 sprintf(jourp, "PRAGMA journal_mode = %16.16s;", jmode);
03816 sqlite3_exec(d->sqlite, jourp, NULL, NULL, NULL);
03817 }
03818 if (d->trace) {
03819 fprintf(d->trace, "-- sqlite3_open: '%s'\n", d->dbname);
03820 fflush(d->trace);
03821 }
03822 #if defined(_WIN32) || defined(_WIN64)
03823 {
03824 char pname[MAX_PATH];
03825 HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
03826 FALSE, GetCurrentProcessId());
03827
03828 pname[0] = '\0';
03829 if (h) {
03830 HMODULE m = NULL, l = LoadLibrary("psapi.dll");
03831 DWORD need;
03832 typedef BOOL (WINAPI *epmfunc)(HANDLE, HMODULE *, DWORD, LPDWORD);
03833 typedef BOOL (WINAPI *gmbfunc)(HANDLE, HMODULE, LPSTR, DWORD);
03834 epmfunc epm;
03835 gmbfunc gmb;
03836
03837 if (l) {
03838 epm = (epmfunc) GetProcAddress(l, "EnumProcessModules");
03839 gmb = (gmbfunc) GetProcAddress(l, "GetModuleBaseNameA");
03840 if (epm && gmb && epm(h, &m, sizeof (m), &need)) {
03841 gmb(h, m, pname, sizeof (pname));
03842 }
03843 FreeLibrary(l);
03844 }
03845 CloseHandle(h);
03846 }
03847 d->xcelqrx = strncasecmp(pname, "EXCEL", 5) == 0 ||
03848 strncasecmp(pname, "MSQRY", 5) == 0;
03849 if (d->trace && d->xcelqrx) {
03850 fprintf(d->trace, "-- enabled EXCEL quirks\n");
03851 fflush(d->trace);
03852 }
03853 }
03854 #endif
03855 sqlite3_create_function(d->sqlite, "blob_import", 1, SQLITE_UTF8,
03856 d, blob_import, 0, 0);
03857 sqlite3_create_function(d->sqlite, "blob_export", 2, SQLITE_UTF8,
03858 d, blob_export, 0, 0);
03859 return SQL_SUCCESS;
03860 }
03861
03868 static void
03869 dbloadext(DBC *d, char *exts)
03870 {
03871 #if defined(HAVE_SQLITE3LOADEXTENSION) && (HAVE_SQLITE3LOADEXTENSION)
03872 char *p;
03873 char path[SQL_MAX_MESSAGE_LENGTH];
03874 int plen = 0;
03875
03876 if (!d->sqlite) {
03877 return;
03878 }
03879 sqlite3_enable_load_extension(d->sqlite, 1);
03880 #if defined(_WIN32) || defined(_WIN64)
03881 GetModuleFileName(hModule, path, sizeof (path));
03882 p = strrchr(path, '\\');
03883 plen = p ? ((p + 1) - path) : 0;
03884 #endif
03885 do {
03886 p = strchr(exts, ',');
03887 if (p) {
03888 strncpy(path + plen, exts, p - exts);
03889 path[plen + (p - exts)] = '\0';
03890 } else {
03891 strcpy(path + plen, exts);
03892 }
03893 if (exts[0]) {
03894 char *errmsg = NULL;
03895 int rc;
03896 #if defined(_WIN32) || defined(_WIN64)
03897 char *q;
03898
03899 q = path + plen;
03900 if (!(q[0] &&
03901 ((q[1] == ':' && (q[2] == '\\' || q[2] == '/')) ||
03902 q[0] == '\\' || q[0] == '/' || q[0] == '.'))) {
03903 q = path;
03904 }
03905 rc = sqlite3_load_extension(d->sqlite, q, 0, &errmsg);
03906 #else
03907 rc = sqlite3_load_extension(d->sqlite, path, 0, &errmsg);
03908 #endif
03909 if (rc != SQLITE_OK) {
03910 #if defined(_WIN32) || defined(_WIN64)
03911 char buf[512], msg[512];
03912
03913 LoadString(hModule, IDS_EXTERR, buf, sizeof (buf));
03914 wsprintf(msg, buf, q, errmsg ?
03915 errmsg : "no error info available");
03916 LoadString(hModule, IDS_EXTTITLE, buf, sizeof (buf));
03917 MessageBox(NULL, msg, buf,
03918 MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
03919 MB_SETFOREGROUND);
03920 #else
03921 fprintf(stderr, "extension '%s' did not load%s%s\n",
03922 path, errmsg ? ": " : "", errmsg ? errmsg : "");
03923 #endif
03924 }
03925 }
03926 if (p) {
03927 exts = p + 1;
03928 }
03929 } while (p);
03930 #endif
03931 }
03932
03942 static char *
03943 s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
03944 {
03945 char *typename = (char *) sqlite3_column_decltype(s3stmt, col);
03946 char guess[64];
03947
03948 guess[0] = '\0';
03949 if (!typename) {
03950 int coltype = sqlite3_column_type(s3stmt, col);
03951
03952 if (guessed_types) {
03953 guessed_types[0]++;
03954 }
03955 if (d->trace) {
03956 sprintf(guess, " (guessed from %d)", coltype);
03957 }
03958 switch (coltype) {
03959 case SQLITE_INTEGER: typename = "integer"; break;
03960 case SQLITE_FLOAT: typename = "double"; break;
03961 default:
03962 case SQLITE_TEXT: typename = "varchar"; break;
03963 case SQLITE_BLOB: typename = "blob"; break;
03964 #if 0
03965 case SQLITE_NULL: typename = "null"; break;
03966 #endif
03967 }
03968 }
03969 if (d->trace) {
03970 fprintf(d->trace, "-- column %d type%s: '%s'\n", col + 1,
03971 guess, typename);
03972 fflush(d->trace);
03973 }
03974 return typename;
03975 }
03976
03977 #if defined(HAVE_SQLITE3TABLECOLUMNMETADATA) && (HAVE_SQLITE3TABLECOLUMNMETADATA)
03978
03987 static void
03988 s3stmt_addmeta(sqlite3_stmt *s3stmt, int col, DBC *d, COL *ci)
03989 {
03990 int nn = 0, pk = 0, ai = 0;
03991 const char *dn, *tn, *cn, *dummy1, *dummy2;
03992
03993 dn = sqlite3_column_database_name(s3stmt, col);
03994 tn = sqlite3_column_table_name(s3stmt, col);
03995 cn = sqlite3_column_origin_name(s3stmt, col);
03996 sqlite3_table_column_metadata(d->sqlite, dn, tn, cn,
03997 &dummy1, &dummy2,
03998 &nn, &pk, &ai);
03999 ci->autoinc = ai ? SQL_TRUE: SQL_FALSE;
04000 ci->notnull = nn ? SQL_NO_NULLS : SQL_NULLABLE;
04001 if (d->trace) {
04002 fprintf(d->trace, "-- column %d %s\n",
04003 col + 1, nn ? "notnull" : "nullable");
04004 if (ai) {
04005 fprintf(d->trace, "-- column %d autoincrement\n", col + 1);
04006 }
04007 fflush(d->trace);
04008 }
04009 }
04010
04011 #endif
04012
04019 static int
04020 s3stmt_step(STMT *s)
04021 {
04022 DBC *d = (DBC *) s->dbc;
04023 char **rowd = NULL;
04024 const char *errp = NULL;
04025 int i, ncols, rc;
04026
04027 if (s != d->cur_s3stmt || !s->s3stmt) {
04028 setstat(s, -1, "stale statement", (*s->ov3) ? "HY000" : "S1000");
04029 return SQL_ERROR;
04030 }
04031 rc = sqlite3_step(s->s3stmt);
04032 if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
04033 ++s->s3stmt_rownum;
04034 ncols = sqlite3_column_count(s->s3stmt);
04035 if (d->s3stmt_needmeta && s->s3stmt_rownum == 0 && ncols > 0) {
04036 PTRDIFF_T size;
04037 char *p;
04038 COL *dyncols;
04039 const char *colname, *typename;
04040 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
04041 char *tblname;
04042 #endif
04043
04044 for (i = size = 0; i < ncols; i++) {
04045 colname = sqlite3_column_name(s->s3stmt, i);
04046 size += 3 + 3 * strlen(colname);
04047 }
04048 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
04049 tblname = (char *) size;
04050 for (i = 0; i < ncols; i++) {
04051 p = (char *) sqlite3_column_table_name(s->s3stmt, i);
04052 size += 2 + (p ? strlen(p) : 0);
04053 }
04054 #endif
04055 dyncols = xmalloc(ncols * sizeof (COL) + size);
04056 if (!dyncols) {
04057 freedyncols(s);
04058 s->ncols = 0;
04059 dbtraceapi(d, "sqlite3_finalize", 0);
04060 sqlite3_finalize(s->s3stmt);
04061 s->s3stmt = NULL;
04062 d->cur_s3stmt = NULL;
04063 return nomem(s);
04064 }
04065 p = (char *) (dyncols + ncols);
04066 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
04067 tblname = p + (PTRDIFF_T) tblname;
04068 #endif
04069 for (i = 0; i < ncols; i++) {
04070 char *q;
04071
04072 colname = sqlite3_column_name(s->s3stmt, i);
04073 if (d->trace) {
04074 fprintf(d->trace, "-- column %d name: '%s'\n",
04075 i + 1, colname);
04076 fflush(d->trace);
04077 }
04078 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
04079 q = (char *) sqlite3_column_table_name(s->s3stmt, i);
04080 strcpy(tblname, q ? q : "");
04081 if (d->trace) {
04082 fprintf(d->trace, "-- table %d name: '%s'\n",
04083 i + 1, tblname);
04084 fflush(d->trace);
04085 }
04086 dyncols[i].table = tblname;
04087 tblname += strlen(tblname) + 1;
04088 #endif
04089 typename = s3stmt_coltype(s->s3stmt, i, d, 0);
04090 dyncols[i].db = ((DBC *) (s->dbc))->dbname;
04091 strcpy(p, colname);
04092 dyncols[i].label = p;
04093 p += strlen(p) + 1;
04094 q = strchr(colname, '.');
04095 if (q) {
04096 char *q2 = strchr(q + 1, '.');
04097
04098
04099 if (q2) {
04100 q = q2;
04101 }
04102 }
04103 if (q) {
04104 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
04105 dyncols[i].table = p;
04106 #endif
04107 strncpy(p, colname, q - colname);
04108 p[q - colname] = '\0';
04109 p += strlen(p) + 1;
04110 strcpy(p, q + 1);
04111 dyncols[i].column = p;
04112 p += strlen(p) + 1;
04113 } else {
04114 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
04115 dyncols[i].table = "";
04116 #endif
04117 strcpy(p, colname);
04118 dyncols[i].column = p;
04119 p += strlen(p) + 1;
04120 }
04121 if (s->longnames) {
04122 dyncols[i].column = dyncols[i].label;
04123 }
04124 #ifdef SQL_LONGVARCHAR
04125 dyncols[i].type = SQL_LONGVARCHAR;
04126 dyncols[i].size = 65535;
04127 #else
04128 dyncols[i].type = SQL_VARCHAR;
04129 dyncols[i].size = 255;
04130 #endif
04131 dyncols[i].index = i;
04132 dyncols[i].scale = 0;
04133 dyncols[i].prec = 0;
04134 dyncols[i].nosign = 1;
04135 #if defined(HAVE_SQLITE3TABLECOLUMNMETADATA) && (HAVE_SQLITE3TABLECOLUMNMETADATA)
04136 s3stmt_addmeta(s->s3stmt, i, d, &dyncols[i]);
04137 #else
04138 dyncols[i].autoinc = SQL_FALSE;
04139 dyncols[i].notnull = SQL_NULLABLE;
04140 #endif
04141 dyncols[i].typename = xstrdup(typename);
04142 }
04143 freedyncols(s);
04144 s->ncols = s->dcols = ncols;
04145 s->dyncols = s->cols = dyncols;
04146 fixupdyncols(s, d);
04147 mkbindcols(s, s->ncols);
04148 d->s3stmt_needmeta = 0;
04149 }
04150 if (ncols <= 0) {
04151 goto killstmt;
04152 }
04153 if (rc == SQLITE_DONE) {
04154 freeresult(s, 0);
04155 s->nrows = 0;
04156 dbtraceapi(d, "sqlite3_finalize", 0);
04157 sqlite3_finalize(s->s3stmt);
04158 s->s3stmt = NULL;
04159 d->cur_s3stmt = NULL;
04160 return SQL_SUCCESS;
04161 }
04162 rowd = xmalloc((1 + 2 * ncols) * sizeof (char *));
04163 if (rowd) {
04164 const unsigned char *value;
04165
04166 rowd[0] = (char *) ((PTRDIFF_T) (ncols * 2));
04167 ++rowd;
04168 for (i = 0; i < ncols; i++) {
04169 int coltype = sqlite3_column_type(s->s3stmt, i);
04170
04171 rowd[i] = rowd[i + ncols] = NULL;
04172 if (coltype == SQLITE_BLOB) {
04173 int k, nbytes = sqlite3_column_bytes(s->s3stmt, i);
04174 char *qp;
04175 unsigned const char *bp;
04176
04177 bp = sqlite3_column_blob(s->s3stmt, i);
04178 qp = xmalloc(nbytes * 2 + 4);
04179 if (qp) {
04180 rowd[i + ncols] = qp;
04181 *qp++ = 'X';
04182 *qp++ = '\'';
04183 for (k = 0; k < nbytes; k++) {
04184 *qp++ = xdigits[(bp[k] >> 4)];
04185 *qp++ = xdigits[(bp[k] & 0xF)];
04186 }
04187 *qp++ = '\'';
04188 *qp = '\0';
04189 }
04190 #ifdef _MSC_VER
04191 } else if (coltype == SQLITE_FLOAT) {
04192 static struct lconv *lc = 0;
04193 double d = sqlite3_column_double(s->s3stmt, i);
04194 char *p, buffer[128];
04195
04196
04197
04198
04199
04200
04201 snprintf(buffer, sizeof (buffer), "%.15g", d);
04202 if (!lc) {
04203 lc = localeconv();
04204 }
04205 if (lc && lc->decimal_point && lc->decimal_point[0] &&
04206 lc->decimal_point[0] != '.') {
04207 p = strchr(buffer, lc->decimal_point[0]);
04208 if (p) {
04209 *p = '.';
04210 }
04211 }
04212 rowd[i + ncols] = xstrdup(buffer);
04213 #endif
04214 } else if (coltype != SQLITE_NULL) {
04215 value = sqlite3_column_text(s->s3stmt, i);
04216 rowd[i + ncols] = xstrdup((char *) value);
04217 }
04218 }
04219 for (i = 0; i < ncols; i++) {
04220 int coltype = sqlite3_column_type(s->s3stmt, i);
04221
04222 value = NULL;
04223 if (coltype == SQLITE_BLOB) {
04224 value = sqlite3_column_blob(s->s3stmt, i);
04225 } else if (coltype != SQLITE_NULL) {
04226 value = sqlite3_column_text(s->s3stmt, i);
04227 }
04228 if (value && !rowd[i + ncols]) {
04229 freerows(rowd);
04230 rowd = 0;
04231 break;
04232 }
04233 }
04234 }
04235 if (rowd) {
04236 freeresult(s, 0);
04237 s->nrows = 1;
04238 s->rows = rowd;
04239 s->rowfree = freerows;
04240 if (rc == SQLITE_DONE) {
04241 dbtraceapi(d, "sqlite3_finalize", 0);
04242 sqlite3_finalize(s->s3stmt);
04243 s->s3stmt = NULL;
04244 d->cur_s3stmt = NULL;
04245 }
04246 return SQL_SUCCESS;
04247 }
04248 }
04249 killstmt:
04250 dbtraceapi(d, "sqlite3_reset", 0);
04251 rc = sqlite3_reset(s->s3stmt);
04252 s->s3stmt_noreset = 1;
04253 errp = sqlite3_errmsg(d->sqlite);
04254 if (d->cur_s3stmt == s) {
04255 d->cur_s3stmt = NULL;
04256 }
04257 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
04258 errp ? errp : "unknown error", rc);
04259 return SQL_ERROR;
04260 }
04261
04267 static void
04268 s3stmt_end(STMT *s)
04269 {
04270 DBC *d;
04271
04272 if (!s || !s->s3stmt) {
04273 return;
04274 }
04275 d = (DBC *) s->dbc;
04276 if (d) {
04277 d->busyint = 0;
04278 }
04279 if (!s->s3stmt_noreset) {
04280 dbtraceapi(d, "sqlite3_reset", 0);
04281 sqlite3_reset(s->s3stmt);
04282 s->s3stmt_noreset = 1;
04283 s->s3stmt_rownum = -1;
04284 }
04285 if (d->cur_s3stmt == s) {
04286 d->cur_s3stmt = NULL;
04287 }
04288 }
04289
04295 static void
04296 s3stmt_end_if(STMT *s)
04297 {
04298 DBC *d = (DBC *) s->dbc;
04299
04300 if (d) {
04301 d->busyint = 0;
04302 }
04303 if (d && d->cur_s3stmt == s) {
04304 s3stmt_end(s);
04305 }
04306 }
04307
04313 static void
04314 s3stmt_drop(STMT *s)
04315 {
04316 if (s->s3stmt) {
04317 DBC *d = (DBC *) s->dbc;
04318
04319 if (d) {
04320 dbtraceapi(d, "sqlite3_finalize", 0);
04321 }
04322 sqlite3_finalize(s->s3stmt);
04323 s->s3stmt = NULL;
04324 s->s3stmt_rownum = 0;
04325 }
04326 }
04327
04334 static SQLRETURN
04335 s3stmt_start(STMT *s)
04336 {
04337 DBC *d = (DBC *) s->dbc;
04338 const char *endp;
04339 sqlite3_stmt *s3stmt = NULL;
04340 int rc, nretry = 0;
04341
04342 d->s3stmt_needmeta = 0;
04343 if (!s->s3stmt) {
04344 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
04345 dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
04346 #else
04347 dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
04348 #endif
04349 do {
04350 s3stmt = NULL;
04351 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
04352 rc = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
04353 &s3stmt, &endp);
04354 #else
04355 rc = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
04356 &s3stmt, &endp);
04357 #endif
04358 if (rc != SQLITE_OK) {
04359 if (s3stmt) {
04360 sqlite3_finalize(s3stmt);
04361 s3stmt = NULL;
04362 }
04363 }
04364 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
04365 dbtracerc(d, rc, NULL);
04366 if (rc != SQLITE_OK) {
04367 if (s3stmt) {
04368 dbtraceapi(d, "sqlite3_finalize", NULL);
04369 sqlite3_finalize(s3stmt);
04370 }
04371 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
04372 sqlite3_errmsg(d->sqlite), rc);
04373 return SQL_ERROR;
04374 }
04375 if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
04376 dbtraceapi(d, "sqlite3_finalize", 0);
04377 sqlite3_finalize(s3stmt);
04378 setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
04379 (*s->ov3) ? "HY000" : "S1000");
04380 return SQL_ERROR;
04381 }
04382 s->s3stmt = s3stmt;
04383 s->s3stmt_noreset = 1;
04384 d->s3stmt_needmeta = 1;
04385 }
04386 d->cur_s3stmt = s;
04387 s->s3stmt_rownum = -1;
04388 s3bind(d, s->s3stmt, s->nparams, s->bindparms);
04389 return SQL_SUCCESS;
04390 }
04391
04396 SQLRETURN SQL_API
04397 SQLBulkOperations(SQLHSTMT stmt, SQLSMALLINT oper)
04398 {
04399 SQLRETURN ret;
04400
04401 HSTMT_LOCK(stmt);
04402 ret = drvunimplstmt(stmt);
04403 HSTMT_UNLOCK(stmt);
04404 return ret;
04405 }
04406
04407 #ifndef WINTERFACE
04408
04412 SQLRETURN SQL_API
04413 SQLDataSources(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *srvname,
04414 SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
04415 SQLCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
04416 {
04417 if (env == SQL_NULL_HENV) {
04418 return SQL_INVALID_HANDLE;
04419 }
04420 return SQL_ERROR;
04421 }
04422 #endif
04423
04424 #ifdef WINTERFACE
04425
04429 SQLRETURN SQL_API
04430 SQLDataSourcesW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *srvname,
04431 SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
04432 SQLWCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
04433 {
04434 if (env == SQL_NULL_HENV) {
04435 return SQL_INVALID_HANDLE;
04436 }
04437 return SQL_ERROR;
04438 }
04439 #endif
04440
04441 #ifndef WINTERFACE
04442
04446 SQLRETURN SQL_API
04447 SQLDrivers(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *drvdesc,
04448 SQLSMALLINT descmax, SQLSMALLINT *desclenp,
04449 SQLCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
04450 {
04451 if (env == SQL_NULL_HENV) {
04452 return SQL_INVALID_HANDLE;
04453 }
04454 return SQL_ERROR;
04455 }
04456 #endif
04457
04458 #ifdef WINTERFACE
04459
04463 SQLRETURN SQL_API
04464 SQLDriversW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *drvdesc,
04465 SQLSMALLINT descmax, SQLSMALLINT *desclenp,
04466 SQLWCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
04467 {
04468 if (env == SQL_NULL_HENV) {
04469 return SQL_INVALID_HANDLE;
04470 }
04471 return SQL_ERROR;
04472 }
04473 #endif
04474
04475 #ifndef WINTERFACE
04476
04480 SQLRETURN SQL_API
04481 SQLBrowseConnect(SQLHDBC dbc, SQLCHAR *connin, SQLSMALLINT conninLen,
04482 SQLCHAR *connout, SQLSMALLINT connoutMax,
04483 SQLSMALLINT *connoutLen)
04484 {
04485 SQLRETURN ret;
04486
04487 HDBC_LOCK(dbc);
04488 ret = drvunimpldbc(dbc);
04489 HDBC_UNLOCK(dbc);
04490 return ret;
04491 }
04492 #endif
04493
04494 #ifdef WINTERFACE
04495
04499 SQLRETURN SQL_API
04500 SQLBrowseConnectW(SQLHDBC dbc, SQLWCHAR *connin, SQLSMALLINT conninLen,
04501 SQLWCHAR *connout, SQLSMALLINT connoutMax,
04502 SQLSMALLINT *connoutLen)
04503 {
04504 SQLRETURN ret;
04505
04506 HDBC_LOCK(dbc);
04507 ret = drvunimpldbc(dbc);
04508 HDBC_UNLOCK(dbc);
04509 return ret;
04510 }
04511 #endif
04512
04521 static SQLRETURN
04522 drvputdata(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
04523 {
04524 STMT *s;
04525 int i, dlen, done = 0;
04526 BINDPARM *p;
04527
04528 if (stmt == SQL_NULL_HSTMT) {
04529 return SQL_INVALID_HANDLE;
04530 }
04531 s = (STMT *) stmt;
04532 if (!s->query || s->nparams <= 0) {
04533 seqerr:
04534 setstat(s, -1, "sequence error", "HY010");
04535 return SQL_ERROR;
04536 }
04537 for (i = (s->pdcount < 0) ? 0 : s->pdcount; i < s->nparams; i++) {
04538 p = &s->bindparms[i];
04539 if (p->need > 0) {
04540 int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
04541
04542 if (len == SQL_NULL_DATA) {
04543 freep(&p->parbuf);
04544 p->param = NULL;
04545 p->len = SQL_NULL_DATA;
04546 p->need = -1;
04547 } else if (type != SQL_C_CHAR
04548 #ifdef WCHARSUPPORT
04549 && type != SQL_C_WCHAR
04550 #endif
04551 && type != SQL_C_BINARY) {
04552 int size = 0;
04553
04554 switch (type) {
04555 case SQL_C_TINYINT:
04556 case SQL_C_UTINYINT:
04557 case SQL_C_STINYINT:
04558 #ifdef SQL_BIT
04559 case SQL_C_BIT:
04560 #endif
04561 size = sizeof (SQLCHAR);
04562 break;
04563 case SQL_C_SHORT:
04564 case SQL_C_USHORT:
04565 case SQL_C_SSHORT:
04566 size = sizeof (SQLSMALLINT);
04567 break;
04568 case SQL_C_LONG:
04569 case SQL_C_ULONG:
04570 case SQL_C_SLONG:
04571 size = sizeof (SQLINTEGER);
04572 break;
04573 #ifdef SQL_BIGINT
04574 case SQL_C_UBIGINT:
04575 case SQL_C_SBIGINT:
04576 size = sizeof (SQLBIGINT);
04577 break;
04578 #endif
04579 case SQL_C_FLOAT:
04580 size = sizeof (float);
04581 break;
04582 case SQL_C_DOUBLE:
04583 size = sizeof (double);
04584 break;
04585 #ifdef SQL_C_TYPE_DATE
04586 case SQL_C_TYPE_DATE:
04587 #endif
04588 case SQL_C_DATE:
04589 size = sizeof (DATE_STRUCT);
04590 break;
04591 #ifdef SQL_C_TYPE_DATE
04592 case SQL_C_TYPE_TIME:
04593 #endif
04594 case SQL_C_TIME:
04595 size = sizeof (TIME_STRUCT);
04596 break;
04597 #ifdef SQL_C_TYPE_DATE
04598 case SQL_C_TYPE_TIMESTAMP:
04599 #endif
04600 case SQL_C_TIMESTAMP:
04601 size = sizeof (TIMESTAMP_STRUCT);
04602 break;
04603 }
04604 freep(&p->parbuf);
04605 p->parbuf = xmalloc(size);
04606 if (!p->parbuf) {
04607 return nomem(s);
04608 }
04609 p->param = p->parbuf;
04610 memcpy(p->param, data, size);
04611 p->len = size;
04612 p->need = -1;
04613 } else if (len == SQL_NTS && (
04614 type == SQL_C_CHAR
04615 #ifdef WCHARSUPPORT
04616 || type == SQL_C_WCHAR
04617 #endif
04618 )) {
04619 char *dp = data;
04620
04621 #ifdef WCHARSUPPORT
04622 if (type == SQL_C_WCHAR) {
04623 dp = uc_to_utf(data, len);
04624 if (!dp) {
04625 return nomem(s);
04626 }
04627 }
04628 #endif
04629 #if defined(_WIN32) || defined(_WIN64)
04630 if (*s->oemcp) {
04631 dp = wmb_to_utf(data, strlen (data));
04632 if (!dp) {
04633 return nomem(s);
04634 }
04635 }
04636 #endif
04637 dlen = strlen(dp);
04638 freep(&p->parbuf);
04639 p->parbuf = xmalloc(dlen + 1);
04640 if (!p->parbuf) {
04641 if (dp != data) {
04642 uc_free(dp);
04643 }
04644 return nomem(s);
04645 }
04646 p->param = p->parbuf;
04647 strcpy(p->param, dp);
04648 if (dp != data) {
04649 uc_free(dp);
04650 }
04651 p->len = dlen;
04652 p->need = -1;
04653 } else if (len < 0) {
04654 setstat(s, -1, "invalid length", "HY090");
04655 return SQL_ERROR;
04656 } else {
04657 dlen = min(p->len - p->offs, len);
04658 if (!p->param) {
04659 setstat(s, -1, "no memory for parameter", "HY013");
04660 return SQL_ERROR;
04661 }
04662 memcpy((char *) p->param + p->offs, data, dlen);
04663 p->offs += dlen;
04664 if (p->offs >= p->len) {
04665 #ifdef WCHARSUPPORT
04666 if (type == SQL_C_WCHAR) {
04667 char *dp = uc_to_utf(p->param, p->len);
04668 char *np;
04669 int nlen;
04670
04671 if (!dp) {
04672 return nomem(s);
04673 }
04674 nlen = strlen(dp);
04675 np = xmalloc(nlen + 1);
04676 if (!np) {
04677 uc_free(dp);
04678 return nomem(s);
04679 }
04680 strcpy(np, dp);
04681 uc_free(dp);
04682 if (p->param == p->parbuf) {
04683 freep(&p->parbuf);
04684 }
04685 p->parbuf = p->param = np;
04686 p->len = nlen;
04687 } else {
04688 *((char *) p->param + p->len) = '\0';
04689 }
04690 p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR)
04691 ? -1 : 0;
04692 #else
04693 *((char *) p->param + p->len) = '\0';
04694 p->need = (type == SQL_C_CHAR) ? -1 : 0;
04695 #endif
04696 #if defined(_WIN32) || defined(_WIN64)
04697 if (type == SQL_C_CHAR && *s->oemcp &&
04698 !(p->stype == SQL_BINARY ||
04699 p->stype == SQL_VARBINARY ||
04700 p->stype == SQL_LONGVARBINARY)) {
04701 char *dp = wmb_to_utf(p->param, p->len);
04702
04703 if (!dp) {
04704 return nomem(s);
04705 }
04706 if (p->param == p->parbuf) {
04707 freep(&p->parbuf);
04708 }
04709 p->parbuf = p->param = dp;
04710 p->len = strlen(dp);
04711 }
04712 if (p->type == SQL_C_WCHAR &&
04713 (p->stype == SQL_VARCHAR ||
04714 p->stype == SQL_LONGVARCHAR) &&
04715 p->len == p->coldef * sizeof (SQLWCHAR)) {
04716
04717 p->len = p->coldef;
04718 }
04719 #endif
04720 }
04721 }
04722 done = 1;
04723 break;
04724 }
04725 }
04726 if (!done) {
04727 goto seqerr;
04728 }
04729 return SQL_SUCCESS;
04730 }
04731
04740 SQLRETURN SQL_API
04741 SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
04742 {
04743 SQLRETURN ret;
04744
04745 HSTMT_LOCK(stmt);
04746 ret = drvputdata(stmt, data, len);
04747 HSTMT_UNLOCK(stmt);
04748 return ret;
04749 }
04750
04756 static SQLRETURN
04757 freeparams(STMT *s)
04758 {
04759 if (s->bindparms) {
04760 int n;
04761
04762 for (n = 0; n < s->nbindparms; n++) {
04763 freep(&s->bindparms[n].parbuf);
04764 memset(&s->bindparms[n], 0, sizeof (BINDPARM));
04765 }
04766 }
04767 return SQL_SUCCESS;
04768 }
04769
04781 static SQLRETURN
04782 setupparam(STMT *s, char *sql, int pnum)
04783 {
04784 int type, len = 0, needalloc = 0;
04785 BINDPARM *p;
04786
04787 if (!s->bindparms || pnum < 0 || pnum >= s->nbindparms) {
04788 goto error;
04789 }
04790 p = &s->bindparms[pnum];
04791 type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
04792 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
04793
04794 if (type == SQL_C_WCHAR && p->type == SQL_C_DEFAULT) {
04795 type = SQL_C_CHAR;
04796 }
04797 #endif
04798 if (p->need > 0) {
04799 return setupparbuf(s, p);
04800 }
04801 p->strbuf[0] = '\0';
04802 if (!p->param || (p->lenp && *p->lenp == SQL_NULL_DATA)) {
04803 p->s3type = SQLITE_NULL;
04804 p->s3size = 0;
04805 return SQL_SUCCESS;
04806 }
04807 if (type == SQL_C_CHAR &&
04808 (p->stype == SQL_BINARY ||
04809 p->stype == SQL_VARBINARY ||
04810 p->stype == SQL_LONGVARBINARY)) {
04811 type = SQL_C_BINARY;
04812 }
04813 switch (type) {
04814 case SQL_C_BINARY:
04815 p->s3type = SQLITE_BLOB;
04816 p->s3size = p->len;
04817 p->s3val = p->param;
04818 if (p->need < 0) {
04819 break;
04820 }
04821 if (!p->lenp) {
04822 len = p->len;
04823 } else if (*p->lenp == SQL_DATA_AT_EXEC) {
04824 len = p->len;
04825 } else {
04826 len = *p->lenp;
04827 if (len <= SQL_LEN_DATA_AT_EXEC_OFFSET) {
04828 len = SQL_LEN_DATA_AT_EXEC(len);
04829 }
04830 }
04831 if (len < 0) {
04832 setstat(s, -1, "invalid length", "HY009");
04833 return SQL_ERROR;
04834 }
04835 p->len = len;
04836 p->max = p->len;
04837 p->need = -1;
04838 p->s3size = len;
04839 break;
04840 #ifdef WCHARSUPPORT
04841 case SQL_C_WCHAR:
04842 #endif
04843 case SQL_C_CHAR:
04844 p->s3type = SQLITE_TEXT;
04845 p->s3size = -1;
04846 p->s3val = p->param;
04847 if (!p->parbuf && p->lenp) {
04848 #ifdef WCHARSUPPORT
04849 if (type == SQL_C_WCHAR) {
04850 if (*p->lenp == SQL_NTS) {
04851 p->max = uc_strlen(p->param) * sizeof (SQLWCHAR);
04852 } else if (*p->lenp >= 0) {
04853 p->max = *p->lenp;
04854 }
04855 } else
04856 #endif
04857 if (type == SQL_C_CHAR) {
04858 if (*p->lenp == SQL_NTS) {
04859 p->len = p->max = strlen(p->param);
04860 #if defined(_WIN32) || defined(_WIN64)
04861 needalloc = 1;
04862 #endif
04863 } else if (*p->lenp >= 0) {
04864 p->len = p->max = *p->lenp;
04865 needalloc = 1;
04866 }
04867 }
04868 }
04869 if (p->need < 0 && p->parbuf == p->param) {
04870 break;
04871 }
04872 #ifdef WCHARSUPPORT
04873 if (type == SQL_C_WCHAR) {
04874 char *dp = uc_to_utf(p->param, p->max);
04875
04876 if (!dp) {
04877 return nomem(s);
04878 }
04879 if (p->param == p->parbuf) {
04880 freep(&p->parbuf);
04881 }
04882 p->parbuf = p->param = dp;
04883 p->need = -1;
04884 p->len = strlen(p->param);
04885 p->s3val = p->param;
04886 p->s3size = p->len;
04887 } else
04888 #endif
04889 if (type == SQL_C_CHAR) {
04890 p->s3val = p->param;
04891 if (needalloc) {
04892 char *dp;
04893
04894 #if defined(_WIN32) || defined(_WIN64)
04895 if (*s->oemcp) {
04896 dp = wmb_to_utf(p->param, p->len);
04897 } else {
04898 dp = xmalloc(p->len + 1);
04899 }
04900 #else
04901 dp = xmalloc(p->len + 1);
04902 #endif
04903 if (!dp) {
04904 return nomem(s);
04905 }
04906 #if defined(_WIN32) || defined(_WIN64)
04907 if (*s->oemcp) {
04908 p->len = strlen(dp);
04909 } else {
04910 memcpy(dp, p->param, p->len);
04911 dp[p->len] = '\0';
04912 }
04913 #else
04914 memcpy(dp, p->param, p->len);
04915 dp[p->len] = '\0';
04916 #endif
04917 if (p->param == p->parbuf) {
04918 freep(&p->parbuf);
04919 }
04920 p->parbuf = p->param = dp;
04921 p->need = -1;
04922 p->s3val = p->param;
04923 p->s3size = p->len;
04924 }
04925 }
04926 break;
04927 case SQL_C_UTINYINT:
04928 p->s3type = SQLITE_INTEGER;
04929 p->s3size = sizeof (int);
04930 p->s3ival = *((SQLCHAR *) p->param);
04931 break;
04932 case SQL_C_TINYINT:
04933 case SQL_C_STINYINT:
04934 p->s3type = SQLITE_INTEGER;
04935 p->s3size = sizeof (int);
04936 p->s3ival = *((SQLCHAR *) p->param);
04937 break;
04938 case SQL_C_USHORT:
04939 p->s3type = SQLITE_INTEGER;
04940 p->s3size = sizeof (int);
04941 p->s3ival = *((SQLUSMALLINT *) p->param);
04942 break;
04943 case SQL_C_SHORT:
04944 case SQL_C_SSHORT:
04945 p->s3type = SQLITE_INTEGER;
04946 p->s3size = sizeof (int);
04947 p->s3ival = *((SQLSMALLINT *) p->param);
04948 break;
04949 case SQL_C_ULONG:
04950 p->s3type = SQLITE_INTEGER;
04951 p->s3size = sizeof (int);
04952 p->s3ival = *((SQLUINTEGER *) p->param);
04953 break;
04954 case SQL_C_LONG:
04955 case SQL_C_SLONG:
04956 p->s3type = SQLITE_INTEGER;
04957 p->s3size = sizeof (int);
04958 p->s3ival = *((SQLINTEGER *) p->param);
04959 break;
04960 #ifdef SQL_BIT
04961 case SQL_C_BIT:
04962 p->s3type = SQLITE_INTEGER;
04963 p->s3size = sizeof (int);
04964 p->s3ival = (*((SQLCHAR *) p->param)) ? 1 : 0;
04965 break;
04966 #endif
04967 #ifdef SQL_BIGINT
04968 case SQL_C_SBIGINT:
04969 p->s3type = SQLITE_INTEGER;
04970 p->s3size = sizeof (sqlite_int64);
04971 p->s3lival = *((sqlite_int64 *) p->param);
04972 break;
04973 case SQL_C_UBIGINT:
04974 p->s3type = SQLITE_INTEGER;
04975 p->s3size = sizeof (sqlite_int64);
04976 p->s3lival = *((sqlite_uint64 *) p->param);
04977 break;
04978 #endif
04979 case SQL_C_FLOAT:
04980 p->s3type = SQLITE_FLOAT;
04981 p->s3size = sizeof (double);
04982 p->s3dval = *((float *) p->param);
04983 break;
04984 case SQL_C_DOUBLE:
04985 p->s3type = SQLITE_FLOAT;
04986 p->s3size = sizeof (double);
04987 p->s3dval = *((double *) p->param);
04988 break;
04989 #ifdef SQL_C_TYPE_DATE
04990 case SQL_C_TYPE_DATE:
04991 #endif
04992 case SQL_C_DATE:
04993 if (*s->jdconv) {
04994 int a, b, x1, x2, y, m, d;
04995
04996 p->s3type = SQLITE_FLOAT;
04997 p->s3size = sizeof (double);
04998 y = ((DATE_STRUCT *) p->param)->year;
04999 m = ((DATE_STRUCT *) p->param)->month;
05000 d = ((DATE_STRUCT *) p->param)->day;
05001 if (m <= 2) {
05002 y--;
05003 m += 12;
05004 }
05005 a = y / 100;
05006 b = 2 - a + (a / 4);
05007 x1 = 36525 * (y + 4716) / 100;
05008 x2 = 306001 * (m + 1) / 10000;
05009 p->s3dval = x1 + x2 + d + b - 1524.5;
05010 break;
05011 }
05012 sprintf(p->strbuf, "%04d-%02d-%02d",
05013 ((DATE_STRUCT *) p->param)->year,
05014 ((DATE_STRUCT *) p->param)->month,
05015 ((DATE_STRUCT *) p->param)->day);
05016 p->s3type = SQLITE_TEXT;
05017 p->s3size = -1;
05018 p->s3val = p->strbuf;
05019 break;
05020 #ifdef SQL_C_TYPE_TIME
05021 case SQL_C_TYPE_TIME:
05022 #endif
05023 case SQL_C_TIME:
05024 if (*s->jdconv) {
05025 p->s3type = SQLITE_FLOAT;
05026 p->s3size = sizeof (double);
05027 p->s3dval = 2451544.5 +
05028 (((TIME_STRUCT *) p->param)->hour * 3600000.0 +
05029 ((TIME_STRUCT *) p->param)->minute * 60000.0 +
05030 ((TIME_STRUCT *) p->param)->second * 1000.0) / 86400000.0;
05031 break;
05032 }
05033 sprintf(p->strbuf, "%02d:%02d:%02d",
05034 ((TIME_STRUCT *) p->param)->hour,
05035 ((TIME_STRUCT *) p->param)->minute,
05036 ((TIME_STRUCT *) p->param)->second);
05037 p->s3type = SQLITE_TEXT;
05038 p->s3size = -1;
05039 p->s3val = p->strbuf;
05040 break;
05041 #ifdef SQL_C_TYPE_TIMESTAMP
05042 case SQL_C_TYPE_TIMESTAMP:
05043 #endif
05044 case SQL_C_TIMESTAMP:
05045 if (*s->jdconv) {
05046 int a, b, x1, x2, y, m, d;
05047
05048 p->s3type = SQLITE_FLOAT;
05049 p->s3size = sizeof (double);
05050 y = ((TIMESTAMP_STRUCT *) p->param)->year;
05051 m = ((TIMESTAMP_STRUCT *) p->param)->month;
05052 d = ((TIMESTAMP_STRUCT *) p->param)->day;
05053 if (m <= 2) {
05054 y--;
05055 m += 12;
05056 }
05057 a = y / 100;
05058 b = 2 - a + (a / 4);
05059 x1 = 36525 * (y + 4716) / 100;
05060 x2 = 306001 * (m + 1) / 10000;
05061 p->s3dval = x1 + x2 + d + b - 1524.5 +
05062 (((TIMESTAMP_STRUCT *) p->param)->hour * 3600000.0 +
05063 ((TIMESTAMP_STRUCT *) p->param)->minute * 60000.0 +
05064 ((TIMESTAMP_STRUCT *) p->param)->second * 1000.0 +
05065 ((TIMESTAMP_STRUCT *) p->param)->fraction / 1.0E6)
05066 / 86400000.0;
05067 break;
05068 }
05069 len = (int) ((TIMESTAMP_STRUCT *) p->param)->fraction;
05070 len /= 1000000;
05071 len = len % 1000;
05072 if (len < 0) {
05073 len = 0;
05074 }
05075 if (p->coldef && p->coldef <= 16) {
05076 sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
05077 ((TIMESTAMP_STRUCT *) p->param)->year,
05078 ((TIMESTAMP_STRUCT *) p->param)->month,
05079 ((TIMESTAMP_STRUCT *) p->param)->day,
05080 ((TIMESTAMP_STRUCT *) p->param)->hour,
05081 ((TIMESTAMP_STRUCT *) p->param)->minute);
05082 } else if (p->coldef && p->coldef <= 19) {
05083 sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
05084 ((TIMESTAMP_STRUCT *) p->param)->year,
05085 ((TIMESTAMP_STRUCT *) p->param)->month,
05086 ((TIMESTAMP_STRUCT *) p->param)->day,
05087 ((TIMESTAMP_STRUCT *) p->param)->hour,
05088 ((TIMESTAMP_STRUCT *) p->param)->minute,
05089 ((TIMESTAMP_STRUCT *) p->param)->second);
05090 } else {
05091 sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
05092 ((TIMESTAMP_STRUCT *) p->param)->year,
05093 ((TIMESTAMP_STRUCT *) p->param)->month,
05094 ((TIMESTAMP_STRUCT *) p->param)->day,
05095 ((TIMESTAMP_STRUCT *) p->param)->hour,
05096 ((TIMESTAMP_STRUCT *) p->param)->minute,
05097 ((TIMESTAMP_STRUCT *) p->param)->second,
05098 len);
05099 }
05100 p->s3type = SQLITE_TEXT;
05101 p->s3size = -1;
05102 p->s3val = p->strbuf;
05103 break;
05104 default:
05105 error:
05106 setstat(s, -1, "unsupported parameter type",
05107 (*s->ov3) ? "07009" : "S1093");
05108 return SQL_ERROR;
05109 }
05110 return SQL_SUCCESS;
05111 }
05112
05128 static SQLRETURN
05129 drvbindparam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
05130 SQLSMALLINT buftype, SQLSMALLINT ptype, SQLUINTEGER coldef,
05131 SQLSMALLINT scale,
05132 SQLPOINTER data, SQLINTEGER buflen, SQLLEN *len)
05133 {
05134 STMT *s;
05135 BINDPARM *p;
05136
05137 if (stmt == SQL_NULL_HSTMT) {
05138 return SQL_INVALID_HANDLE;
05139 }
05140 s = (STMT *) stmt;
05141 if (pnum == 0) {
05142 setstat(s, -1, "invalid parameter", (*s->ov3) ? "07009" : "S1093");
05143 return SQL_ERROR;
05144 }
05145 if (!data && !len) {
05146 setstat(s, -1, "invalid buffer", "HY003");
05147 return SQL_ERROR;
05148 }
05149 --pnum;
05150 if (s->bindparms) {
05151 if (pnum >= s->nbindparms) {
05152 BINDPARM *newparms;
05153
05154 newparms = xrealloc(s->bindparms,
05155 (pnum + 1) * sizeof (BINDPARM));
05156 if (!newparms) {
05157 outofmem:
05158 return nomem(s);
05159 }
05160 s->bindparms = newparms;
05161 memset(&s->bindparms[s->nbindparms], 0,
05162 (pnum + 1 - s->nbindparms) * sizeof (BINDPARM));
05163 s->nbindparms = pnum + 1;
05164 }
05165 } else {
05166 int npar = max(10, pnum + 1);
05167
05168 s->bindparms = xmalloc(npar * sizeof (BINDPARM));
05169 if (!s->bindparms) {
05170 goto outofmem;
05171 }
05172 memset(s->bindparms, 0, npar * sizeof (BINDPARM));
05173 s->nbindparms = npar;
05174 }
05175 switch (buftype) {
05176 case SQL_C_STINYINT:
05177 case SQL_C_UTINYINT:
05178 case SQL_C_TINYINT:
05179 #ifdef SQL_C_BIT
05180 case SQL_C_BIT:
05181 #endif
05182 buflen = sizeof (SQLCHAR);
05183 break;
05184 case SQL_C_SHORT:
05185 case SQL_C_USHORT:
05186 case SQL_C_SSHORT:
05187 buflen = sizeof (SQLSMALLINT);
05188 break;
05189 case SQL_C_SLONG:
05190 case SQL_C_ULONG:
05191 case SQL_C_LONG:
05192 buflen = sizeof (SQLINTEGER);
05193 break;
05194 case SQL_C_FLOAT:
05195 buflen = sizeof (float);
05196 break;
05197 case SQL_C_DOUBLE:
05198 buflen = sizeof (double);
05199 break;
05200 case SQL_C_TIMESTAMP:
05201 #ifdef SQL_C_TYPE_TIMESTAMP
05202 case SQL_C_TYPE_TIMESTAMP:
05203 #endif
05204 buflen = sizeof (TIMESTAMP_STRUCT);
05205 break;
05206 case SQL_C_TIME:
05207 #ifdef SQL_C_TYPE_TIME
05208 case SQL_C_TYPE_TIME:
05209 #endif
05210 buflen = sizeof (TIME_STRUCT);
05211 break;
05212 case SQL_C_DATE:
05213 #ifdef SQL_C_TYPE_DATE
05214 case SQL_C_TYPE_DATE:
05215 #endif
05216 buflen = sizeof (DATE_STRUCT);
05217 break;
05218 #ifdef SQL_C_UBIGINT
05219 case SQL_C_UBIGINT:
05220 buflen = sizeof (SQLBIGINT);
05221 break;
05222 #endif
05223 #ifdef SQL_C_SBIGINT
05224 case SQL_C_SBIGINT:
05225 buflen = sizeof (SQLBIGINT);
05226 break;
05227 #endif
05228 #ifdef SQL_C_BIGINT
05229 case SQL_C_BIGINT:
05230 buflen = sizeof (SQLBIGINT);
05231 break;
05232 #endif
05233 }
05234 p = &s->bindparms[pnum];
05235 p->type = buftype;
05236 p->stype = ptype;
05237 p->coldef = coldef;
05238 p->scale = scale;
05239 p->max = buflen;
05240 p->inc = buflen;
05241 p->lenp = p->lenp0 = len;
05242 p->offs = 0;
05243 p->len = 0;
05244 p->param0 = data;
05245 freep(&p->parbuf);
05246 p->param = p->param0;
05247 p->bound = 1;
05248 p->need = 0;
05249 return SQL_SUCCESS;
05250 }
05251
05267 SQLRETURN SQL_API
05268 SQLBindParameter(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
05269 SQLSMALLINT buftype, SQLSMALLINT ptype, SQLULEN coldef,
05270 SQLSMALLINT scale,
05271 SQLPOINTER data, SQLLEN buflen, SQLLEN *len)
05272 {
05273 SQLRETURN ret;
05274
05275 HSTMT_LOCK(stmt);
05276 ret = drvbindparam(stmt, pnum, iotype, buftype, ptype, coldef,
05277 scale, data, buflen, len);
05278 HSTMT_UNLOCK(stmt);
05279 return ret;
05280 }
05281
05282 #ifndef HAVE_IODBC
05283
05296 SQLRETURN SQL_API
05297 SQLBindParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT vtype,
05298 SQLSMALLINT ptype, SQLULEN lenprec,
05299 SQLSMALLINT scale, SQLPOINTER val,
05300 SQLLEN *lenp)
05301 {
05302 SQLRETURN ret;
05303
05304 HSTMT_LOCK(stmt);
05305 ret = drvbindparam(stmt, pnum, SQL_PARAM_INPUT, vtype, ptype,
05306 lenprec, scale, val, 0, lenp);
05307 HSTMT_UNLOCK(stmt);
05308 return ret;
05309 }
05310 #endif
05311
05319 SQLRETURN SQL_API
05320 SQLNumParams(SQLHSTMT stmt, SQLSMALLINT *nparam)
05321 {
05322 STMT *s;
05323 SQLSMALLINT dummy;
05324
05325 HSTMT_LOCK(stmt);
05326 if (stmt == SQL_NULL_HSTMT) {
05327 return SQL_INVALID_HANDLE;
05328 }
05329 s = (STMT *) stmt;
05330 if (!nparam) {
05331 nparam = &dummy;
05332 }
05333 *nparam = s->nparams;
05334 HSTMT_UNLOCK(stmt);
05335 return SQL_SUCCESS;
05336 }
05337
05345 static SQLRETURN
05346 setupparbuf(STMT *s, BINDPARM *p)
05347 {
05348 if (!p->parbuf) {
05349 if (*p->lenp == SQL_DATA_AT_EXEC) {
05350 p->len = p->max;
05351 } else {
05352 p->len = SQL_LEN_DATA_AT_EXEC(*p->lenp);
05353 }
05354 if (p->len < 0 && p->len != SQL_NTS &&
05355 p->len != SQL_NULL_DATA) {
05356 setstat(s, -1, "invalid length", "HY009");
05357 return SQL_ERROR;
05358 }
05359 if (p->len >= 0) {
05360 p->parbuf = xmalloc(p->len + 2);
05361 if (!p->parbuf) {
05362 return nomem(s);
05363 }
05364 p->param = p->parbuf;
05365 } else {
05366 p->param = NULL;
05367 }
05368 }
05369 return SQL_NEED_DATA;
05370 }
05371
05379 SQLRETURN SQL_API
05380 SQLParamData(SQLHSTMT stmt, SQLPOINTER *pind)
05381 {
05382 STMT *s;
05383 int i;
05384 SQLPOINTER dummy;
05385 SQLRETURN ret;
05386 BINDPARM *p;
05387
05388 HSTMT_LOCK(stmt);
05389 if (stmt == SQL_NULL_HSTMT) {
05390 return SQL_INVALID_HANDLE;
05391 }
05392 s = (STMT *) stmt;
05393 if (!pind) {
05394 pind = &dummy;
05395 }
05396 if (s->pdcount < s->nparams) {
05397 s->pdcount++;
05398 }
05399 for (i = 0; i < s->pdcount; i++) {
05400 p = &s->bindparms[i];
05401 if (p->need > 0) {
05402 int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
05403
05404 p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR) ? -1 : 0;
05405 }
05406 }
05407 for (; i < s->nparams; i++) {
05408 p = &s->bindparms[i];
05409 if (p->need > 0) {
05410 *pind = (SQLPOINTER) p->param0;
05411 ret = setupparbuf(s, p);
05412 s->pdcount = i;
05413 goto done;
05414 }
05415 }
05416 ret = drvexecute(stmt, 0);
05417 done:
05418 HSTMT_UNLOCK(stmt);
05419 return ret;
05420 }
05421
05433 SQLRETURN SQL_API
05434 SQLDescribeParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT *dtype,
05435 SQLULEN *size, SQLSMALLINT *decdigits, SQLSMALLINT *nullable)
05436 {
05437 STMT *s;
05438 SQLRETURN ret = SQL_ERROR;
05439
05440 HSTMT_LOCK(stmt);
05441 if (stmt == SQL_NULL_HSTMT) {
05442 return SQL_INVALID_HANDLE;
05443 }
05444 s = (STMT *) stmt;
05445 --pnum;
05446 if (pnum >= s->nparams) {
05447 setstat(s, -1, "invalid parameter index",
05448 (*s->ov3) ? "HY000" : "S1000");
05449 goto done;
05450 }
05451 if (dtype) {
05452 #ifdef SQL_LONGVARCHAR
05453 #ifdef WINTERFACE
05454 *dtype = s->nowchar[0] ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
05455 #else
05456 *dtype = SQL_LONGVARCHAR;
05457 #endif
05458 #else
05459 #ifdef WINTERFACE
05460 *dtype = s->nowchar[0] ? SQL_VARCHAR : SQL_WVARCHAR;
05461 #else
05462 *dtype = SQL_VARCHAR;
05463 #endif
05464 #endif
05465 }
05466 if (size) {
05467 #ifdef SQL_LONGVARCHAR
05468 *size = 65536;
05469 #else
05470 *size = 255;
05471 #endif
05472 }
05473 if (decdigits) {
05474 *decdigits = 0;
05475 }
05476 if (nullable) {
05477 *nullable = SQL_NULLABLE;
05478 }
05479 ret = SQL_SUCCESS;
05480 done:
05481 HSTMT_UNLOCK(stmt);
05482 return ret;
05483 }
05484
05498 SQLRETURN SQL_API
05499 SQLSetParam(SQLHSTMT stmt, SQLUSMALLINT par, SQLSMALLINT type,
05500 SQLSMALLINT sqltype, SQLULEN coldef,
05501 SQLSMALLINT scale, SQLPOINTER val, SQLLEN *nval)
05502 {
05503 SQLRETURN ret;
05504
05505 HSTMT_LOCK(stmt);
05506 ret = drvbindparam(stmt, par, SQL_PARAM_INPUT,
05507 type, sqltype, coldef, scale, val,
05508 SQL_SETPARAM_VALUE_MAX, nval);
05509 HSTMT_UNLOCK(stmt);
05510 return ret;
05511 }
05512
05517 SQLRETURN SQL_API
05518 SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
05519 {
05520 SQLRETURN ret;
05521
05522 HSTMT_LOCK(stmt);
05523 ret = drvunimplstmt(stmt);
05524 HSTMT_UNLOCK(stmt);
05525 return ret;
05526 }
05527
05528 #ifndef WINTERFACE
05529
05533 SQLRETURN SQL_API
05534 SQLGetDescField(SQLHDESC handle, SQLSMALLINT recno,
05535 SQLSMALLINT fieldid, SQLPOINTER value,
05536 SQLINTEGER buflen, SQLINTEGER *strlen)
05537 {
05538 return SQL_ERROR;
05539 }
05540 #endif
05541
05542 #ifdef WINTERFACE
05543
05547 SQLRETURN SQL_API
05548 SQLGetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
05549 SQLSMALLINT fieldid, SQLPOINTER value,
05550 SQLINTEGER buflen, SQLINTEGER *strlen)
05551 {
05552 return SQL_ERROR;
05553 }
05554 #endif
05555
05556 #ifndef WINTERFACE
05557
05561 SQLRETURN SQL_API
05562 SQLSetDescField(SQLHDESC handle, SQLSMALLINT recno,
05563 SQLSMALLINT fieldid, SQLPOINTER value,
05564 SQLINTEGER buflen)
05565 {
05566 return SQL_ERROR;
05567 }
05568 #endif
05569
05570 #ifdef WINTERFACE
05571
05575 SQLRETURN SQL_API
05576 SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
05577 SQLSMALLINT fieldid, SQLPOINTER value,
05578 SQLINTEGER buflen)
05579 {
05580 return SQL_ERROR;
05581 }
05582 #endif
05583
05584 #ifndef WINTERFACE
05585
05589 SQLRETURN SQL_API
05590 SQLGetDescRec(SQLHDESC handle, SQLSMALLINT recno,
05591 SQLCHAR *name, SQLSMALLINT buflen,
05592 SQLSMALLINT *strlen, SQLSMALLINT *type,
05593 SQLSMALLINT *subtype, SQLLEN *len,
05594 SQLSMALLINT *prec, SQLSMALLINT *scale,
05595 SQLSMALLINT *nullable)
05596 {
05597 return SQL_ERROR;
05598 }
05599 #endif
05600
05601 #ifdef WINTERFACE
05602
05606 SQLRETURN SQL_API
05607 SQLGetDescRecW(SQLHDESC handle, SQLSMALLINT recno,
05608 SQLWCHAR *name, SQLSMALLINT buflen,
05609 SQLSMALLINT *strlen, SQLSMALLINT *type,
05610 SQLSMALLINT *subtype, SQLLEN *len,
05611 SQLSMALLINT *prec, SQLSMALLINT *scale,
05612 SQLSMALLINT *nullable)
05613 {
05614 return SQL_ERROR;
05615 }
05616 #endif
05617
05622 SQLRETURN SQL_API
05623 SQLSetDescRec(SQLHDESC handle, SQLSMALLINT recno,
05624 SQLSMALLINT type, SQLSMALLINT subtype,
05625 SQLLEN len, SQLSMALLINT prec,
05626 SQLSMALLINT scale, SQLPOINTER data,
05627 SQLLEN *strlen, SQLLEN *indicator)
05628 {
05629 return SQL_ERROR;
05630 }
05631
05643 static SQLRETURN
05644 mkresultset(HSTMT stmt, COL *colspec, int ncols, COL *colspec3,
05645 int ncols3, int *nret)
05646 {
05647 STMT *s;
05648 DBC *d;
05649
05650 if (stmt == SQL_NULL_HSTMT) {
05651 return SQL_INVALID_HANDLE;
05652 }
05653 s = (STMT *) stmt;
05654 if (s->dbc == SQL_NULL_HDBC) {
05655 noconn:
05656 return noconn(s);
05657 }
05658 d = (DBC *) s->dbc;
05659 if (!d->sqlite) {
05660 goto noconn;
05661 }
05662 s3stmt_end_if(s);
05663 freeresult(s, 0);
05664 if (colspec3 && *s->ov3) {
05665 s->ncols = ncols3;
05666 s->cols = colspec3;
05667 } else {
05668 s->ncols = ncols;
05669 s->cols = colspec;
05670 }
05671 mkbindcols(s, s->ncols);
05672 s->nowchar[1] = 1;
05673 s->nrows = 0;
05674 s->rowp = -1;
05675 s->isselect = -1;
05676 if (nret) {
05677 *nret = s->ncols;
05678 }
05679 return SQL_SUCCESS;
05680 }
05681
05686 static COL tablePrivSpec2[] = {
05687 { "SYSTEM", "TABLEPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
05688 { "SYSTEM", "TABLEPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
05689 { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
05690 { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
05691 { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
05692 { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
05693 { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
05694 };
05695
05696 static COL tablePrivSpec3[] = {
05697 { "SYSTEM", "TABLEPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
05698 { "SYSTEM", "TABLEPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
05699 { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
05700 { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
05701 { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
05702 { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
05703 { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
05704 };
05705
05718 static SQLRETURN
05719 drvtableprivileges(SQLHSTMT stmt,
05720 SQLCHAR *cat, SQLSMALLINT catLen,
05721 SQLCHAR *schema, SQLSMALLINT schemaLen,
05722 SQLCHAR *table, SQLSMALLINT tableLen)
05723 {
05724 SQLRETURN ret;
05725 STMT *s;
05726 DBC *d;
05727 int ncols, rc, size, npatt;
05728 char *errp = NULL, *sql, tname[512];
05729
05730 ret = mkresultset(stmt, tablePrivSpec2, array_size(tablePrivSpec2),
05731 tablePrivSpec3, array_size(tablePrivSpec3), NULL);
05732 if (ret != SQL_SUCCESS) {
05733 return ret;
05734 }
05735 s = (STMT *) stmt;
05736 d = (DBC *) s->dbc;
05737 if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
05738 table = NULL;
05739 goto doit;
05740 }
05741 if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
05742 schema[0] == '%') {
05743 if ((!cat || catLen == 0 || !cat[0]) &&
05744 (!table || tableLen == 0 || !table[0])) {
05745 table = NULL;
05746 goto doit;
05747 }
05748 }
05749 doit:
05750 if (!table) {
05751 size = 1;
05752 tname[0] = '%';
05753 } else {
05754 if (tableLen == SQL_NTS) {
05755 size = sizeof (tname) - 1;
05756 } else {
05757 size = min(sizeof (tname) - 1, tableLen);
05758 }
05759 strncpy(tname, (char *) table, size);
05760 }
05761 tname[size] = '\0';
05762 npatt = unescpat(tname);
05763 #if defined(_WIN32) || defined(_WIN64)
05764 sql = sqlite3_mprintf("select %s as 'TABLE_QUALIFIER', "
05765 "%s as 'TABLE_OWNER', "
05766 "tbl_name as 'TABLE_NAME', "
05767 "'' as 'GRANTOR', "
05768 "'' as 'GRANTEE', "
05769 "'SELECT' AS 'PRIVILEGE', "
05770 "NULL as 'IS_GRANTABLE' "
05771 "from sqlite_master where "
05772 "(type = 'table' or type = 'view') "
05773 "and tbl_name %s %Q "
05774 "UNION "
05775 "select %s as 'TABLE_QUALIFIER', "
05776 "%s as 'TABLE_OWNER', "
05777 "tbl_name as 'TABLE_NAME', "
05778 "'' as 'GRANTOR', "
05779 "'' as 'GRANTEE', "
05780 "'UPDATE' AS 'PRIVILEGE', "
05781 "NULL as 'IS_GRANTABLE' "
05782 "from sqlite_master where "
05783 "(type = 'table' or type = 'view') "
05784 "and tbl_name %s %Q "
05785 "UNION "
05786 "select %s as 'TABLE_QUALIFIER', "
05787 "%s as 'TABLE_OWNER', "
05788 "tbl_name as 'TABLE_NAME', "
05789 "'' as 'GRANTOR', "
05790 "'' as 'GRANTEE', "
05791 "'DELETE' AS 'PRIVILEGE', "
05792 "NULL as 'IS_GRANTABLE' "
05793 "from sqlite_master where "
05794 "(type = 'table' or type = 'view') "
05795 "and tbl_name %s %Q "
05796 "UNION "
05797 "select %s as 'TABLE_QUALIFIER', "
05798 "%s as 'TABLE_OWNER', "
05799 "tbl_name as 'TABLE_NAME', "
05800 "'' as 'GRANTOR', "
05801 "'' as 'GRANTEE', "
05802 "'INSERT' AS 'PRIVILEGE', "
05803 "NULL as 'IS_GRANTABLE' "
05804 "from sqlite_master where "
05805 "(type = 'table' or type = 'view') "
05806 "and tbl_name %s %Q "
05807 "UNION "
05808 "select %s as 'TABLE_QUALIFIER', "
05809 "%s as 'TABLE_OWNER', "
05810 "tbl_name as 'TABLE_NAME', "
05811 "'' as 'GRANTOR', "
05812 "'' as 'GRANTEE', "
05813 "'REFERENCES' AS 'PRIVILEGE', "
05814 "NULL as 'IS_GRANTABLE' "
05815 "from sqlite_master where "
05816 "(type = 'table' or type = 'view') "
05817 "and tbl_name %s %Q",
05818 d->xcelqrx ? "''" : "NULL",
05819 d->xcelqrx ? "'main'" : "NULL",
05820 npatt ? "like" : "=", tname,
05821 d->xcelqrx ? "''" : "NULL",
05822 d->xcelqrx ? "'main'" : "NULL",
05823 npatt ? "like" : "=", tname,
05824 d->xcelqrx ? "''" : "NULL",
05825 d->xcelqrx ? "'main'" : "NULL",
05826 npatt ? "like" : "=", tname,
05827 d->xcelqrx ? "''" : "NULL",
05828 d->xcelqrx ? "'main'" : "NULL",
05829 npatt ? "like" : "=", tname,
05830 d->xcelqrx ? "''" : "NULL",
05831 d->xcelqrx ? "'main'" : "NULL",
05832 npatt ? "like" : "=", tname);
05833 #else
05834 sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
05835 "NULL as 'TABLE_OWNER', "
05836 "tbl_name as 'TABLE_NAME', "
05837 "'' as 'GRANTOR', "
05838 "'' as 'GRANTEE', "
05839 "'SELECT' AS 'PRIVILEGE', "
05840 "NULL as 'IS_GRANTABLE' "
05841 "from sqlite_master where "
05842 "(type = 'table' or type = 'view') "
05843 "and tbl_name %s %Q "
05844 "UNION "
05845 "select NULL as 'TABLE_QUALIFIER', "
05846 "NULL as 'TABLE_OWNER', "
05847 "tbl_name as 'TABLE_NAME', "
05848 "'' as 'GRANTOR', "
05849 "'' as 'GRANTEE', "
05850 "'UPDATE' AS 'PRIVILEGE', "
05851 "NULL as 'IS_GRANTABLE' "
05852 "from sqlite_master where "
05853 "(type = 'table' or type = 'view') "
05854 "and tbl_name %s %Q "
05855 "UNION "
05856 "select NULL as 'TABLE_QUALIFIER', "
05857 "NULL as 'TABLE_OWNER', "
05858 "tbl_name as 'TABLE_NAME', "
05859 "'' as 'GRANTOR', "
05860 "'' as 'GRANTEE', "
05861 "'DELETE' AS 'PRIVILEGE', "
05862 "NULL as 'IS_GRANTABLE' "
05863 "from sqlite_master where "
05864 "(type = 'table' or type = 'view') "
05865 "and tbl_name %s %Q "
05866 "UNION "
05867 "select NULL as 'TABLE_QUALIFIER', "
05868 "NULL as 'TABLE_OWNER', "
05869 "tbl_name as 'TABLE_NAME', "
05870 "'' as 'GRANTOR', "
05871 "'' as 'GRANTEE', "
05872 "'INSERT' AS 'PRIVILEGE', "
05873 "NULL as 'IS_GRANTABLE' "
05874 "from sqlite_master where "
05875 "(type = 'table' or type = 'view') "
05876 "and tbl_name %s %Q "
05877 "UNION "
05878 "select NULL as 'TABLE_QUALIFIER', "
05879 "NULL as 'TABLE_OWNER', "
05880 "tbl_name as 'TABLE_NAME', "
05881 "'' as 'GRANTOR', "
05882 "'' as 'GRANTEE', "
05883 "'REFERENCES' AS 'PRIVILEGE', "
05884 "NULL as 'IS_GRANTABLE' "
05885 "from sqlite_master where "
05886 "(type = 'table' or type = 'view') "
05887 "and tbl_name %s %Q",
05888 npatt ? "like" : "=", tname,
05889 npatt ? "like" : "=", tname,
05890 npatt ? "like" : "=", tname,
05891 npatt ? "like" : "=", tname,
05892 npatt ? "like" : "=", tname);
05893 #endif
05894 if (!sql) {
05895 return nomem(s);
05896 }
05897 ret = starttran(s);
05898 if (ret != SQL_SUCCESS) {
05899 sqlite3_free(sql);
05900 return ret;
05901 }
05902 dbtraceapi(d, "sqlite3_get_table", sql);
05903 rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
05904 sqlite3_free(sql);
05905 if (rc == SQLITE_OK) {
05906 if (ncols != s->ncols) {
05907 freeresult(s, 0);
05908 s->nrows = 0;
05909 } else {
05910 s->rowfree = sqlite3_free_table;
05911 }
05912 } else {
05913 s->nrows = 0;
05914 s->rows = NULL;
05915 s->rowfree = NULL;
05916 }
05917 if (errp) {
05918 sqlite3_free(errp);
05919 errp = NULL;
05920 }
05921 s->rowp = -1;
05922 return SQL_SUCCESS;
05923 }
05924
05925
05926 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
05927
05939 SQLRETURN SQL_API
05940 SQLTablePrivileges(SQLHSTMT stmt,
05941 SQLCHAR *catalog, SQLSMALLINT catalogLen,
05942 SQLCHAR *schema, SQLSMALLINT schemaLen,
05943 SQLCHAR *table, SQLSMALLINT tableLen)
05944 {
05945 #if defined(_WIN32) || defined(_WIN64)
05946 char *c = NULL, *s = NULL, *t = NULL;
05947 #endif
05948 SQLRETURN ret;
05949
05950 HSTMT_LOCK(stmt);
05951 #if defined(_WIN32) || defined(_WIN64)
05952 if (!((STMT *) stmt)->oemcp[0]) {
05953 ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
05954 table, tableLen);
05955 goto done2;
05956 }
05957 if (catalog) {
05958 c = wmb_to_utf_c((char *) catalog, catalogLen);
05959 if (!c) {
05960 ret = nomem((STMT *) stmt);
05961 goto done;
05962 }
05963 }
05964 if (schema) {
05965 s = wmb_to_utf_c((char *) schema, schemaLen);
05966 if (!s) {
05967 ret = nomem((STMT *) stmt);
05968 goto done;
05969 }
05970 }
05971 if (table) {
05972 t = wmb_to_utf_c((char *) table, tableLen);
05973 if (!t) {
05974 ret = nomem((STMT *) stmt);
05975 goto done;
05976 }
05977 }
05978 ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
05979 (SQLCHAR *) s, SQL_NTS,
05980 (SQLCHAR *) t, SQL_NTS);
05981 #else
05982 ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
05983 table, tableLen);
05984 #endif
05985 #if defined(_WIN32) || defined(_WIN64)
05986 done:
05987 uc_free(t);
05988 uc_free(s);
05989 uc_free(c);
05990 done2:
05991 ;
05992 #endif
05993 HSTMT_UNLOCK(stmt);
05994 return ret;
05995 }
05996 #endif
05997
05998 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
05999 #ifdef WINTERFACE
06000
06012 SQLRETURN SQL_API
06013 SQLTablePrivilegesW(SQLHSTMT stmt,
06014 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
06015 SQLWCHAR *schema, SQLSMALLINT schemaLen,
06016 SQLWCHAR *table, SQLSMALLINT tableLen)
06017 {
06018 char *c = NULL, *s = NULL, *t = NULL;
06019 SQLRETURN ret;
06020
06021 HSTMT_LOCK(stmt);
06022 if (catalog) {
06023 c = uc_to_utf_c(catalog, catalogLen);
06024 if (!c) {
06025 ret = nomem((STMT *) stmt);
06026 goto done;
06027 }
06028 }
06029 if (schema) {
06030 s = uc_to_utf_c(schema, schemaLen);
06031 if (!s) {
06032 ret = nomem((STMT *) stmt);
06033 goto done;
06034 }
06035 }
06036 if (table) {
06037 t = uc_to_utf_c(table, tableLen);
06038 if (!t) {
06039 ret = nomem((STMT *) stmt);
06040 goto done;
06041 }
06042 }
06043 ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
06044 (SQLCHAR *) s, SQL_NTS,
06045 (SQLCHAR *) t, SQL_NTS);
06046 done:
06047 uc_free(t);
06048 uc_free(s);
06049 uc_free(c);
06050 HSTMT_UNLOCK(stmt);
06051 return ret;
06052 }
06053 #endif
06054 #endif
06055
06060 static COL colPrivSpec2[] = {
06061 { "SYSTEM", "COLPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
06062 { "SYSTEM", "COLPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
06063 { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
06064 { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
06065 { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
06066 { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
06067 { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
06068 };
06069
06070 static COL colPrivSpec3[] = {
06071 { "SYSTEM", "COLPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
06072 { "SYSTEM", "COLPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
06073 { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
06074 { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
06075 { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
06076 { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
06077 { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
06078 };
06079
06080 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
06081
06095 SQLRETURN SQL_API
06096 SQLColumnPrivileges(SQLHSTMT stmt,
06097 SQLCHAR *catalog, SQLSMALLINT catalogLen,
06098 SQLCHAR *schema, SQLSMALLINT schemaLen,
06099 SQLCHAR *table, SQLSMALLINT tableLen,
06100 SQLCHAR *column, SQLSMALLINT columnLen)
06101 {
06102 SQLRETURN ret;
06103
06104 HSTMT_LOCK(stmt);
06105 ret = mkresultset(stmt, colPrivSpec2, array_size(colPrivSpec2),
06106 colPrivSpec3, array_size(colPrivSpec3), NULL);
06107 HSTMT_UNLOCK(stmt);
06108 return ret;
06109 }
06110 #endif
06111
06112 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
06113 #ifdef WINTERFACE
06114
06128 SQLRETURN SQL_API
06129 SQLColumnPrivilegesW(SQLHSTMT stmt,
06130 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
06131 SQLWCHAR *schema, SQLSMALLINT schemaLen,
06132 SQLWCHAR *table, SQLSMALLINT tableLen,
06133 SQLWCHAR *column, SQLSMALLINT columnLen)
06134 {
06135 SQLRETURN ret;
06136
06137 HSTMT_LOCK(stmt);
06138 ret = mkresultset(stmt, colPrivSpec2, array_size(colPrivSpec2),
06139 colPrivSpec3, array_size(colPrivSpec3), NULL);
06140 HSTMT_UNLOCK(stmt);
06141 return ret;
06142 }
06143 #endif
06144 #endif
06145
06150 static COL pkeySpec2[] = {
06151 { "SYSTEM", "PRIMARYKEY", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
06152 { "SYSTEM", "PRIMARYKEY", "TABLE_OWNER", SCOL_VARCHAR, 50 },
06153 { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
06154 { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
06155 { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
06156 { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
06157 };
06158
06159 static COL pkeySpec3[] = {
06160 { "SYSTEM", "PRIMARYKEY", "TABLE_CAT", SCOL_VARCHAR, 50 },
06161 { "SYSTEM", "PRIMARYKEY", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
06162 { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
06163 { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
06164 { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
06165 { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
06166 };
06167
06180 static SQLRETURN
06181 drvprimarykeys(SQLHSTMT stmt,
06182 SQLCHAR *cat, SQLSMALLINT catLen,
06183 SQLCHAR *schema, SQLSMALLINT schemaLen,
06184 SQLCHAR *table, SQLSMALLINT tableLen)
06185 {
06186 STMT *s;
06187 DBC *d;
06188 SQLRETURN sret;
06189 int i, asize, ret, nrows, ncols, nrows2 = 0, ncols2 = 0;
06190 int namec = -1, uniquec = -1, namec2 = -1, uniquec2 = -1, offs, seq = 1;
06191 PTRDIFF_T size;
06192 char **rowp = NULL, **rowp2 = NULL, *errp = NULL, *sql, tname[512];
06193
06194 sret = mkresultset(stmt, pkeySpec2, array_size(pkeySpec2),
06195 pkeySpec3, array_size(pkeySpec3), &asize);
06196 if (sret != SQL_SUCCESS) {
06197 return sret;
06198 }
06199 s = (STMT *) stmt;
06200 d = (DBC *) s->dbc;
06201 if (!table || table[0] == '\0' || table[0] == '%') {
06202 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
06203 return SQL_ERROR;
06204 }
06205 if (tableLen == SQL_NTS) {
06206 size = sizeof (tname) - 1;
06207 } else {
06208 size = min(sizeof (tname) - 1, tableLen);
06209 }
06210 strncpy(tname, (char *) table, size);
06211 tname[size] = '\0';
06212 unescpat(tname);
06213 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
06214 if (!sql) {
06215 return nomem(s);
06216 }
06217 sret = starttran(s);
06218 if (sret != SQL_SUCCESS) {
06219 sqlite3_free(sql);
06220 return sret;
06221 }
06222 dbtraceapi(d, "sqlite3_get_table", sql);
06223 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
06224 sqlite3_free(sql);
06225 if (ret != SQLITE_OK) {
06226 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
06227 errp ? errp : "unknown error", ret);
06228 if (errp) {
06229 sqlite3_free(errp);
06230 errp = NULL;
06231 }
06232 return SQL_ERROR;
06233 }
06234 if (errp) {
06235 sqlite3_free(errp);
06236 errp = NULL;
06237 }
06238 size = 0;
06239 if (ncols * nrows > 0) {
06240 int typec;
06241
06242 namec = findcol(rowp, ncols, "name");
06243 uniquec = findcol(rowp, ncols, "pk");
06244 typec = findcol(rowp, ncols, "type");
06245 if (namec >= 0 && uniquec >= 0 && typec >= 0) {
06246 for (i = 1; i <= nrows; i++) {
06247 if (*rowp[i * ncols + uniquec] != '0') {
06248 size++;
06249 }
06250 }
06251 }
06252 }
06253 if (size == 0) {
06254 sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
06255 if (!sql) {
06256 sqlite3_free_table(rowp);
06257 return nomem(s);
06258 }
06259 dbtraceapi(d, "sqlite3_get_table", sql);
06260 ret = sqlite3_get_table(d->sqlite, sql, &rowp2, &nrows2, &ncols2,
06261 &errp);
06262 sqlite3_free(sql);
06263 if (ret != SQLITE_OK) {
06264 sqlite3_free_table(rowp);
06265 sqlite3_free_table(rowp2);
06266 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
06267 errp ? errp : "unknown error", ret);
06268 if (errp) {
06269 sqlite3_free(errp);
06270 errp = NULL;
06271 }
06272 return SQL_ERROR;
06273 }
06274 if (errp) {
06275 sqlite3_free(errp);
06276 errp = NULL;
06277 }
06278 }
06279 if (ncols2 * nrows2 > 0) {
06280 namec2 = findcol(rowp2, ncols2, "name");
06281 uniquec2 = findcol(rowp2, ncols2, "unique");
06282 if (namec2 >= 0 && uniquec2 >= 0) {
06283 for (i = 1; i <= nrows2; i++) {
06284 int nnrows, nncols, nlen = 0;
06285 char **rowpp;
06286
06287 if (rowp2[i * ncols2 + namec2]) {
06288 nlen = strlen(rowp2[i * ncols2 + namec2]);
06289 }
06290 if (nlen < 17 ||
06291 strncmp(rowp2[i * ncols2 + namec2],
06292 "sqlite_autoindex_", 17)) {
06293 continue;
06294 }
06295 if (*rowp2[i * ncols2 + uniquec2] != '0') {
06296 ret = SQLITE_ERROR;
06297 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
06298 rowp2[i * ncols2 + namec2]);
06299 if (sql) {
06300 dbtraceapi(d, "sqlite3_get_table", sql);
06301 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
06302 &nnrows, &nncols, NULL);
06303 sqlite3_free(sql);
06304 }
06305 if (ret == SQLITE_OK) {
06306 size += nnrows;
06307 sqlite3_free_table(rowpp);
06308 }
06309 }
06310 }
06311 }
06312 }
06313 if (size == 0) {
06314 sqlite3_free_table(rowp);
06315 sqlite3_free_table(rowp2);
06316 return SQL_SUCCESS;
06317 }
06318 s->nrows = size;
06319 size = (size + 1) * asize;
06320 s->rows = xmalloc((size + 1) * sizeof (char *));
06321 if (!s->rows) {
06322 s->nrows = 0;
06323 sqlite3_free_table(rowp);
06324 sqlite3_free_table(rowp2);
06325 return nomem(s);
06326 }
06327 s->rows[0] = (char *) size;
06328 s->rows += 1;
06329 memset(s->rows, 0, sizeof (char *) * size);
06330 s->rowfree = freerows;
06331 offs = s->ncols;
06332 if (rowp) {
06333 for (i = 1; i <= nrows; i++) {
06334 if (*rowp[i * ncols + uniquec] != '0') {
06335 char buf[32];
06336
06337 s->rows[offs + 0] = xstrdup("");
06338 #if defined(_WIN32) || defined(_WIN64)
06339 s->rows[offs + 1] = xstrdup(d->xcelqrx ? "main" : "");
06340 #else
06341 s->rows[offs + 1] = xstrdup("");
06342 #endif
06343 s->rows[offs + 2] = xstrdup(tname);
06344 s->rows[offs + 3] = xstrdup(rowp[i * ncols + namec]);
06345 sprintf(buf, "%d", seq++);
06346 s->rows[offs + 4] = xstrdup(buf);
06347 offs += s->ncols;
06348 }
06349 }
06350 }
06351 if (rowp2) {
06352 for (i = 1; i <= nrows2; i++) {
06353 int nnrows, nncols, nlen = 0;
06354 char **rowpp;
06355
06356 if (rowp2[i * ncols2 + namec2]) {
06357 nlen = strlen(rowp2[i * ncols2 + namec2]);
06358 }
06359 if (nlen < 17 ||
06360 strncmp(rowp2[i * ncols2 + namec2], "sqlite_autoindex_", 17)) {
06361 continue;
06362 }
06363 if (*rowp2[i * ncols2 + uniquec2] != '0') {
06364 int k;
06365
06366 ret = SQLITE_ERROR;
06367 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
06368 rowp2[i * ncols2 + namec2]);
06369 if (sql) {
06370 dbtraceapi(d, "sqlite3_get_table", sql);
06371 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
06372 &nnrows, &nncols, NULL);
06373 sqlite3_free(sql);
06374 }
06375 if (ret != SQLITE_OK) {
06376 continue;
06377 }
06378 for (k = 0; nnrows && k < nncols; k++) {
06379 if (strcmp(rowpp[k], "name") == 0) {
06380 int m;
06381
06382 for (m = 1; m <= nnrows; m++) {
06383 int roffs = offs + (m - 1) * s->ncols;
06384
06385 s->rows[roffs + 0] = xstrdup("");
06386 #if defined(_WIN32) || defined(_WIN64)
06387 s->rows[roffs + 1] =
06388 xstrdup(d->xcelqrx ? "main" : "");
06389 #else
06390 s->rows[roffs + 1] = xstrdup("");
06391 #endif
06392 s->rows[roffs + 2] = xstrdup(tname);
06393 s->rows[roffs + 3] =
06394 xstrdup(rowpp[m * nncols + k]);
06395 s->rows[roffs + 5] =
06396 xstrdup(rowp2[i * ncols2 + namec2]);
06397 }
06398 } else if (strcmp(rowpp[k], "seqno") == 0) {
06399 int m;
06400
06401 for (m = 1; m <= nnrows; m++) {
06402 int roffs = offs + (m - 1) * s->ncols;
06403 int pos = m - 1;
06404 char buf[32];
06405
06406 sscanf(rowpp[m * nncols + k], "%d", &pos);
06407 sprintf(buf, "%d", pos + 1);
06408 s->rows[roffs + 4] = xstrdup(buf);
06409 }
06410 }
06411 }
06412 offs += nnrows * s->ncols;
06413 sqlite3_free_table(rowpp);
06414 }
06415 }
06416 }
06417 sqlite3_free_table(rowp);
06418 sqlite3_free_table(rowp2);
06419 return SQL_SUCCESS;
06420 }
06421
06422 #ifndef WINTERFACE
06423
06435 SQLRETURN SQL_API
06436 SQLPrimaryKeys(SQLHSTMT stmt,
06437 SQLCHAR *cat, SQLSMALLINT catLen,
06438 SQLCHAR *schema, SQLSMALLINT schemaLen,
06439 SQLCHAR *table, SQLSMALLINT tableLen)
06440 {
06441 #if defined(_WIN32) || defined(_WIN64)
06442 char *c = NULL, *s = NULL, *t = NULL;
06443 #endif
06444 SQLRETURN ret;
06445
06446 HSTMT_LOCK(stmt);
06447 #if defined(_WIN32) || defined(_WIN64)
06448 if (!((STMT *) stmt)->oemcp[0]) {
06449 ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
06450 table, tableLen);
06451 goto done2;
06452 }
06453 if (cat) {
06454 c = wmb_to_utf_c((char *) cat, catLen);
06455 if (!c) {
06456 ret = nomem((STMT *) stmt);
06457 goto done;
06458 }
06459 }
06460 if (schema) {
06461 s = wmb_to_utf_c((char *) schema, schemaLen);
06462 if (!s) {
06463 ret = nomem((STMT *) stmt);
06464 goto done;
06465 }
06466 }
06467 if (table) {
06468 t = wmb_to_utf_c((char *) table, tableLen);
06469 if (!t) {
06470 ret = nomem((STMT *) stmt);
06471 goto done;
06472 }
06473 }
06474 ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
06475 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
06476 #else
06477 ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
06478 table, tableLen);
06479 #endif
06480 #if defined(_WIN32) || defined(_WIN64)
06481 done:
06482 uc_free(t);
06483 uc_free(s);
06484 uc_free(c);
06485 done2:
06486 ;
06487 #endif
06488 HSTMT_UNLOCK(stmt);
06489 return ret;
06490 }
06491 #endif
06492
06493 #ifdef WINTERFACE
06494
06506 SQLRETURN SQL_API
06507 SQLPrimaryKeysW(SQLHSTMT stmt,
06508 SQLWCHAR *cat, SQLSMALLINT catLen,
06509 SQLWCHAR *schema, SQLSMALLINT schemaLen,
06510 SQLWCHAR *table, SQLSMALLINT tableLen)
06511 {
06512 char *c = NULL, *s = NULL, *t = NULL;
06513 SQLRETURN ret;
06514
06515 HSTMT_LOCK(stmt);
06516 if (cat) {
06517 c = uc_to_utf_c(cat, catLen);
06518 if (!c) {
06519 ret = nomem((STMT *) stmt);
06520 goto done;
06521 }
06522 }
06523 if (schema) {
06524 s = uc_to_utf_c(schema, schemaLen);
06525 if (!s) {
06526 ret = nomem((STMT *) stmt);
06527 goto done;
06528 }
06529 }
06530 if (table) {
06531 t = uc_to_utf_c(table, tableLen);
06532 if (!t) {
06533 ret = nomem((STMT *) stmt);
06534 goto done;
06535 }
06536 }
06537 ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
06538 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
06539 done:
06540 uc_free(t);
06541 uc_free(s);
06542 uc_free(c);
06543 HSTMT_UNLOCK(stmt);
06544 return ret;
06545 }
06546 #endif
06547
06552 static COL scolSpec2[] = {
06553 { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
06554 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
06555 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
06556 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
06557 { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
06558 { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
06559 { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
06560 { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
06561 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
06562 };
06563
06564 static COL scolSpec3[] = {
06565 { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
06566 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
06567 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
06568 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
06569 { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
06570 { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
06571 { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
06572 { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
06573 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
06574 };
06575
06591 static SQLRETURN
06592 drvspecialcolumns(SQLHSTMT stmt, SQLUSMALLINT id,
06593 SQLCHAR *cat, SQLSMALLINT catLen,
06594 SQLCHAR *schema, SQLSMALLINT schemaLen,
06595 SQLCHAR *table, SQLSMALLINT tableLen,
06596 SQLUSMALLINT scope, SQLUSMALLINT nullable)
06597 {
06598 STMT *s;
06599 DBC *d;
06600 SQLRETURN sret;
06601 int i, asize, ret, nrows, ncols, nnnrows, nnncols, offs;
06602 PTRDIFF_T size;
06603 int namec = -1, uniquec = -1, namecc = -1, typecc = -1;
06604 int notnullcc = -1, mkrowid = 0;
06605 char *errp = NULL, *sql, tname[512];
06606 char **rowp = NULL, **rowppp = NULL;
06607
06608 sret = mkresultset(stmt, scolSpec2, array_size(scolSpec2),
06609 scolSpec3, array_size(scolSpec3), &asize);
06610 if (sret != SQL_SUCCESS) {
06611 return sret;
06612 }
06613 s = (STMT *) stmt;
06614 d = (DBC *) s->dbc;
06615 if (!table || table[0] == '\0' || table[0] == '%') {
06616 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
06617 return SQL_ERROR;
06618 }
06619 if (tableLen == SQL_NTS) {
06620 size = sizeof (tname) - 1;
06621 } else {
06622 size = min(sizeof (tname) - 1, tableLen);
06623 }
06624 strncpy(tname, (char *) table, size);
06625 tname[size] = '\0';
06626 unescpat(tname);
06627 if (id != SQL_BEST_ROWID) {
06628 return SQL_SUCCESS;
06629 }
06630 sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
06631 if (!sql) {
06632 return nomem(s);
06633 }
06634 sret = starttran(s);
06635 if (sret != SQL_SUCCESS) {
06636 sqlite3_free(sql);
06637 return sret;
06638 }
06639 dbtraceapi(d, "sqlite3_get_table", sql);
06640 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
06641 sqlite3_free(sql);
06642 if (ret != SQLITE_OK) {
06643 doerr:
06644 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
06645 errp ? errp : "unknown error", ret);
06646 if (errp) {
06647 sqlite3_free(errp);
06648 errp = NULL;
06649 }
06650 return SQL_ERROR;
06651 }
06652 if (errp) {
06653 sqlite3_free(errp);
06654 errp = NULL;
06655 }
06656 size = 0;
06657 if (ncols * nrows <= 0) {
06658 goto nodata_but_rowid;
06659 }
06660 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
06661 if (!sql) {
06662 return nomem(s);
06663 }
06664 dbtraceapi(d, "sqlite3_get_table", sql);
06665 ret = sqlite3_get_table(d->sqlite, sql, &rowppp, &nnnrows, &nnncols,
06666 &errp);
06667 sqlite3_free(sql);
06668 if (ret != SQLITE_OK) {
06669 sqlite3_free_table(rowp);
06670 goto doerr;
06671 }
06672 if (errp) {
06673 sqlite3_free(errp);
06674 errp = NULL;
06675 }
06676 namec = findcol(rowp, ncols, "name");
06677 uniquec = findcol(rowp, ncols, "unique");
06678 if (namec < 0 || uniquec < 0) {
06679 goto nodata_but_rowid;
06680 }
06681 namecc = findcol(rowppp, nnncols, "name");
06682 typecc = findcol(rowppp, nnncols, "type");
06683 notnullcc = findcol(rowppp, nnncols, "notnull");
06684 for (i = 1; i <= nrows; i++) {
06685 int nnrows, nncols;
06686 char **rowpp = NULL;
06687
06688 if (*rowp[i * ncols + uniquec] != '0') {
06689 ret = SQLITE_ERROR;
06690 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
06691 rowp[i * ncols + namec]);
06692 if (sql) {
06693 dbtraceapi(d, "sqlite3_get_table", sql);
06694 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
06695 &nnrows, &nncols, NULL);
06696 sqlite3_free(sql);
06697 }
06698 if (ret == SQLITE_OK) {
06699 size += nnrows;
06700 sqlite3_free_table(rowpp);
06701 }
06702 }
06703 }
06704 nodata_but_rowid:
06705 if (size == 0) {
06706 size = 1;
06707 mkrowid = 1;
06708 }
06709 s->nrows = size;
06710 size = (size + 1) * asize;
06711 s->rows = xmalloc((size + 1) * sizeof (char *));
06712 if (!s->rows) {
06713 s->nrows = 0;
06714 sqlite3_free_table(rowp);
06715 sqlite3_free_table(rowppp);
06716 return nomem(s);
06717 }
06718 s->rows[0] = (char *) size;
06719 s->rows += 1;
06720 memset(s->rows, 0, sizeof (char *) * size);
06721 s->rowfree = freerows;
06722 if (mkrowid) {
06723 s->nrows = 0;
06724 goto mkrowid;
06725 }
06726 offs = 0;
06727 for (i = 1; i <= nrows; i++) {
06728 int nnrows, nncols;
06729 char **rowpp = NULL;
06730
06731 if (*rowp[i * ncols + uniquec] != '0') {
06732 int k;
06733
06734 ret = SQLITE_ERROR;
06735 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
06736 rowp[i * ncols + namec]);
06737 if (sql) {
06738 dbtraceapi(d, "sqlite3_get_table", sql);
06739 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
06740 &nnrows, &nncols, NULL);
06741 sqlite3_free(sql);
06742 }
06743 if (ret != SQLITE_OK) {
06744 continue;
06745 }
06746 for (k = 0; nnrows && k < nncols; k++) {
06747 if (strcmp(rowpp[k], "name") == 0) {
06748 int m;
06749
06750 for (m = 1; m <= nnrows; m++) {
06751 int roffs = (offs + m) * s->ncols;
06752
06753 s->rows[roffs + 0] =
06754 xstrdup(stringify(SQL_SCOPE_SESSION));
06755 s->rows[roffs + 1] = xstrdup(rowpp[m * nncols + k]);
06756 s->rows[roffs + 4] = xstrdup("0");
06757 s->rows[roffs + 7] =
06758 xstrdup(stringify(SQL_PC_NOT_PSEUDO));
06759 if (namecc >= 0 && typecc >= 0) {
06760 int ii;
06761
06762 for (ii = 1; ii <= nnnrows; ii++) {
06763 if (strcmp(rowppp[ii * nnncols + namecc],
06764 rowpp[m * nncols + k]) == 0) {
06765 char *typen = rowppp[ii * nnncols + typecc];
06766 int sqltype, mm, dd, isnullable = 0;
06767 char buf[32];
06768
06769 s->rows[roffs + 3] = xstrdup(typen);
06770 sqltype = mapsqltype(typen, NULL, *s->ov3,
06771 s->nowchar[0],
06772 s->dobigint);
06773 getmd(typen, sqltype, &mm, &dd);
06774 #ifdef SQL_LONGVARCHAR
06775 if (sqltype == SQL_VARCHAR && mm > 255) {
06776 sqltype = SQL_LONGVARCHAR;
06777 }
06778 #endif
06779 #ifdef WINTERFACE
06780 #ifdef SQL_WLONGVARCHAR
06781 if (sqltype == SQL_WVARCHAR && mm > 255) {
06782 sqltype = SQL_WLONGVARCHAR;
06783 }
06784 #endif
06785 #endif
06786 if (sqltype == SQL_VARBINARY && mm > 255) {
06787 sqltype = SQL_LONGVARBINARY;
06788 }
06789 sprintf(buf, "%d", sqltype);
06790 s->rows[roffs + 2] = xstrdup(buf);
06791 sprintf(buf, "%d", mm);
06792 s->rows[roffs + 5] = xstrdup(buf);
06793 sprintf(buf, "%d", dd);
06794 s->rows[roffs + 6] = xstrdup(buf);
06795 if (notnullcc >= 0) {
06796 char *inp =
06797 rowppp[ii * nnncols + notnullcc];
06798
06799 isnullable = inp[0] != '0';
06800 }
06801 sprintf(buf, "%d", isnullable);
06802 s->rows[roffs + 8] = xstrdup(buf);
06803 }
06804 }
06805 }
06806 }
06807 }
06808 }
06809 offs += nnrows;
06810 sqlite3_free_table(rowpp);
06811 }
06812 }
06813 if (nullable == SQL_NO_NULLS) {
06814 for (i = 1; i < s->nrows; i++) {
06815 if (s->rows[i * s->ncols + 8][0] == '0') {
06816 int m, i1 = i + 1;
06817
06818 for (m = 0; m < s->ncols; m++) {
06819 freep(&s->rows[i * s->ncols + m]);
06820 }
06821 size = s->ncols * sizeof (char *) * (s->nrows - i1);
06822 if (size > 0) {
06823 memmove(s->rows + i * s->ncols,
06824 s->rows + i1 * s->ncols,
06825 size);
06826 memset(s->rows + s->nrows * s->ncols, 0,
06827 s->ncols * sizeof (char *));
06828 }
06829 s->nrows--;
06830 --i;
06831 }
06832 }
06833 }
06834 mkrowid:
06835 sqlite3_free_table(rowp);
06836 sqlite3_free_table(rowppp);
06837 if (s->nrows == 0) {
06838 s->rows[s->ncols + 0] = xstrdup(stringify(SQL_SCOPE_SESSION));
06839 s->rows[s->ncols + 1] = xstrdup("_ROWID_");
06840 s->rows[s->ncols + 2] = xstrdup(stringify(SQL_INTEGER));
06841 s->rows[s->ncols + 3] = xstrdup("integer");
06842 s->rows[s->ncols + 4] = xstrdup("0");
06843 s->rows[s->ncols + 5] = xstrdup("10");
06844 s->rows[s->ncols + 6] = xstrdup("9");
06845 s->rows[s->ncols + 7] = xstrdup(stringify(SQL_PC_PSEUDO));
06846 s->rows[s->ncols + 8] = xstrdup(stringify(SQL_FALSE));
06847 s->nrows = 1;
06848 }
06849 return SQL_SUCCESS;
06850 }
06851
06852 #ifndef WINTERFACE
06853
06868 SQLRETURN SQL_API
06869 SQLSpecialColumns(SQLHSTMT stmt, SQLUSMALLINT id,
06870 SQLCHAR *cat, SQLSMALLINT catLen,
06871 SQLCHAR *schema, SQLSMALLINT schemaLen,
06872 SQLCHAR *table, SQLSMALLINT tableLen,
06873 SQLUSMALLINT scope, SQLUSMALLINT nullable)
06874 {
06875 #if defined(_WIN32) || defined(_WIN64)
06876 char *c = NULL, *s = NULL, *t = NULL;
06877 #endif
06878 SQLRETURN ret;
06879
06880 HSTMT_LOCK(stmt);
06881 #if defined(_WIN32) || defined(_WIN64)
06882 if (!((STMT *) stmt)->oemcp[0]) {
06883 ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
06884 table, tableLen, scope, nullable);
06885 goto done2;
06886 }
06887 if (cat) {
06888 c = wmb_to_utf_c((char *) cat, catLen);
06889 if (!c) {
06890 ret = nomem((STMT *) stmt);
06891 goto done;
06892 }
06893 }
06894 if (schema) {
06895 s = wmb_to_utf_c((char *) schema, schemaLen);
06896 if (!s) {
06897 ret = nomem((STMT *) stmt);
06898 goto done;
06899 }
06900 }
06901 if (table) {
06902 t = wmb_to_utf_c((char *) table, tableLen);
06903 if (!t) {
06904 ret = nomem((STMT *) stmt);
06905 goto done;
06906 }
06907 }
06908 ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
06909 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
06910 scope, nullable);
06911 #else
06912 ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
06913 table, tableLen, scope, nullable);
06914 #endif
06915 #if defined(_WIN32) || defined(_WIN64)
06916 done:
06917 uc_free(t);
06918 uc_free(s);
06919 uc_free(c);
06920 done2:
06921 ;
06922 #endif
06923 HSTMT_UNLOCK(stmt);
06924 return ret;
06925 }
06926 #endif
06927
06928 #ifdef WINTERFACE
06929
06944 SQLRETURN SQL_API
06945 SQLSpecialColumnsW(SQLHSTMT stmt, SQLUSMALLINT id,
06946 SQLWCHAR *cat, SQLSMALLINT catLen,
06947 SQLWCHAR *schema, SQLSMALLINT schemaLen,
06948 SQLWCHAR *table, SQLSMALLINT tableLen,
06949 SQLUSMALLINT scope, SQLUSMALLINT nullable)
06950 {
06951 char *c = NULL, *s = NULL, *t = NULL;
06952 SQLRETURN ret;
06953
06954 HSTMT_LOCK(stmt);
06955 if (cat) {
06956 c = uc_to_utf_c(cat, catLen);
06957 if (!c) {
06958 ret = nomem((STMT *) stmt);
06959 goto done;
06960 }
06961 }
06962 if (schema) {
06963 s = uc_to_utf_c(schema, schemaLen);
06964 if (!s) {
06965 ret = nomem((STMT *) stmt);
06966 goto done;
06967 }
06968 }
06969 if (table) {
06970 t = uc_to_utf_c(table, tableLen);
06971 if (!t) {
06972 ret = nomem((STMT *) stmt);
06973 goto done;
06974 }
06975 }
06976 ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
06977 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
06978 scope, nullable);
06979 done:
06980 uc_free(t);
06981 uc_free(s);
06982 uc_free(c);
06983 HSTMT_UNLOCK(stmt);
06984 return ret;
06985 }
06986 #endif
06987
06992 static COL fkeySpec2[] = {
06993 { "SYSTEM", "FOREIGNKEY", "PKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
06994 { "SYSTEM", "FOREIGNKEY", "PKTABLE_OWNER", SCOL_VARCHAR, 50 },
06995 { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
06996 { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
06997 { "SYSTEM", "FOREIGNKEY", "FKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
06998 { "SYSTEM", "FOREIGNKEY", "FKTABLE_OWNER", SCOL_VARCHAR, 50 },
06999 { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
07000 { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
07001 { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
07002 { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
07003 { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
07004 { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
07005 { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
07006 { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
07007 };
07008
07009 static COL fkeySpec3[] = {
07010 { "SYSTEM", "FOREIGNKEY", "PKTABLE_CAT", SCOL_VARCHAR, 50 },
07011 { "SYSTEM", "FOREIGNKEY", "PKTABLE_SCHEM", SCOL_VARCHAR, 50 },
07012 { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
07013 { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
07014 { "SYSTEM", "FOREIGNKEY", "FKTABLE_CAT", SCOL_VARCHAR, 50 },
07015 { "SYSTEM", "FOREIGNKEY", "FKTABLE_SCHEM", SCOL_VARCHAR, 50 },
07016 { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
07017 { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
07018 { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
07019 { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
07020 { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
07021 { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
07022 { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
07023 { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
07024 };
07025
07044 static SQLRETURN SQL_API
07045 drvforeignkeys(SQLHSTMT stmt,
07046 SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
07047 SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
07048 SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
07049 SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
07050 SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
07051 SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
07052 {
07053 STMT *s;
07054 DBC *d;
07055 SQLRETURN sret;
07056 int i, asize, ret, nrows, ncols, offs, namec, seqc, fromc, toc;
07057 int onu, ond;
07058 PTRDIFF_T size;
07059 char **rowp, *errp = NULL, *sql, pname[512], fname[512];
07060
07061 sret = mkresultset(stmt, fkeySpec2, array_size(fkeySpec2),
07062 fkeySpec3, array_size(fkeySpec3), &asize);
07063 if (sret != SQL_SUCCESS) {
07064 return sret;
07065 }
07066 s = (STMT *) stmt;
07067 sret = starttran(s);
07068 if (sret != SQL_SUCCESS) {
07069 return sret;
07070 }
07071 d = (DBC *) s->dbc;
07072 if ((!PKtable || PKtable[0] == '\0' || PKtable[0] == '%') &&
07073 (!FKtable || FKtable[0] == '\0' || FKtable[0] == '%')) {
07074 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
07075 return SQL_ERROR;
07076 }
07077 size = 0;
07078 if (PKtable) {
07079 if (PKtableLen == SQL_NTS) {
07080 size = sizeof (pname) - 1;
07081 } else {
07082 size = min(sizeof (pname) - 1, PKtableLen);
07083 }
07084 strncpy(pname, (char *) PKtable, size);
07085 }
07086 pname[size] = '\0';
07087 size = 0;
07088 if (FKtable) {
07089
07090 if (FKtableLen == SQL_NTS) {
07091 size = sizeof (fname) - 1;
07092 } else {
07093 size = min(sizeof (fname) - 1, FKtableLen);
07094 }
07095 strncpy(fname, (char *) FKtable, size);
07096 }
07097 fname[size] = '\0';
07098 if (fname[0] != '\0') {
07099 int plen;
07100
07101 ret = SQLITE_ERROR;
07102 sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", fname);
07103 if (sql) {
07104 dbtraceapi(d, "sqlite3_get_table", sql);
07105 ret = sqlite3_get_table(d->sqlite, sql, &rowp,
07106 &nrows, &ncols, &errp);
07107 sqlite3_free(sql);
07108 }
07109 if (ret != SQLITE_OK) {
07110 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
07111 errp ? errp : "unknown error", ret);
07112 if (errp) {
07113 sqlite3_free(errp);
07114 errp = NULL;
07115 }
07116 return SQL_ERROR;
07117 }
07118 if (errp) {
07119 sqlite3_free(errp);
07120 errp = NULL;
07121 }
07122 if (ncols * nrows <= 0) {
07123 nodata:
07124 sqlite3_free_table(rowp);
07125 return SQL_SUCCESS;
07126 }
07127 size = 0;
07128 namec = findcol(rowp, ncols, "table");
07129 seqc = findcol(rowp, ncols, "seq");
07130 fromc = findcol(rowp, ncols, "from");
07131 toc = findcol(rowp, ncols, "to");
07132 onu = findcol(rowp, ncols, "on_update");
07133 ond = findcol(rowp, ncols, "on_delete");
07134 if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
07135 goto nodata;
07136 }
07137 plen = strlen(pname);
07138 for (i = 1; i <= nrows; i++) {
07139 char *ptab = unquote(rowp[i * ncols + namec]);
07140
07141 if (plen && ptab) {
07142 int len = strlen(ptab);
07143
07144 if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
07145 continue;
07146 }
07147 }
07148 size++;
07149 }
07150 if (size == 0) {
07151 goto nodata;
07152 }
07153 s->nrows = size;
07154 size = (size + 1) * asize;
07155 s->rows = xmalloc((size + 1) * sizeof (char *));
07156 if (!s->rows) {
07157 s->nrows = 0;
07158 return nomem(s);
07159 }
07160 s->rows[0] = (char *) size;
07161 s->rows += 1;
07162 memset(s->rows, 0, sizeof (char *) * size);
07163 s->rowfree = freerows;
07164 offs = 0;
07165 for (i = 1; i <= nrows; i++) {
07166 int pos = 0, roffs = (offs + 1) * s->ncols;
07167 char *ptab = rowp[i * ncols + namec];
07168 char buf[32];
07169
07170 if (plen && ptab) {
07171 int len = strlen(ptab);
07172
07173 if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
07174 continue;
07175 }
07176 }
07177 s->rows[roffs + 0] = xstrdup("");
07178 #if defined(_WIN32) || defined(_WIN64)
07179 s->rows[roffs + 1] = xstrdup(d->xcelqrx ? "main" : "");
07180 #else
07181 s->rows[roffs + 1] = xstrdup("");
07182 #endif
07183 s->rows[roffs + 2] = xstrdup(ptab);
07184 s->rows[roffs + 3] = xstrdup(rowp[i * ncols + toc]);
07185 s->rows[roffs + 4] = xstrdup("");
07186 s->rows[roffs + 5] = xstrdup("");
07187 s->rows[roffs + 6] = xstrdup(fname);
07188 s->rows[roffs + 7] = xstrdup(rowp[i * ncols + fromc]);
07189 sscanf(rowp[i * ncols + seqc], "%d", &pos);
07190 sprintf(buf, "%d", pos + 1);
07191 s->rows[roffs + 8] = xstrdup(buf);
07192 if (onu < 0) {
07193 s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
07194 } else {
07195 if (strcmp(rowp[i * ncols + onu], "SET NULL") == 0) {
07196 s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
07197 } else if (strcmp(rowp[i * ncols + onu], "SET DEFAULT") == 0) {
07198 s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_DEFAULT));
07199 } else if (strcmp(rowp[i * ncols + onu], "CASCADE") == 0) {
07200 s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
07201 } else if (strcmp(rowp[i * ncols + onu], "RESTRICT") == 0) {
07202 s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
07203 } else {
07204 s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
07205 }
07206 }
07207 if (ond < 0) {
07208 s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
07209 } else {
07210 if (strcmp(rowp[i * ncols + ond], "SET NULL") == 0) {
07211 s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
07212 } else if (strcmp(rowp[i * ncols + ond], "SET DEFAULT") == 0) {
07213 s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_DEFAULT));
07214 } else if (strcmp(rowp[i * ncols + ond], "CASCADE") == 0) {
07215 s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
07216 } else if (strcmp(rowp[i * ncols + ond], "RESTRICT") == 0) {
07217 s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
07218 } else {
07219 s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
07220 }
07221 }
07222 s->rows[roffs + 11] = NULL;
07223 s->rows[roffs + 12] = NULL;
07224 s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
07225 offs++;
07226 }
07227 sqlite3_free_table(rowp);
07228 } else {
07229 int nnrows, nncols, plen = strlen(pname);
07230 char **rowpp;
07231
07232 sql = "select name from sqlite_master where type='table'";
07233 dbtraceapi(d, "sqlite3_get_table", sql);
07234 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
07235 if (ret != SQLITE_OK) {
07236 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
07237 errp ? errp : "unknown error", ret);
07238 if (errp) {
07239 sqlite3_free(errp);
07240 errp = NULL;
07241 }
07242 return SQL_ERROR;
07243 }
07244 if (errp) {
07245 sqlite3_free(errp);
07246 errp = NULL;
07247 }
07248 if (ncols * nrows <= 0) {
07249 goto nodata;
07250 }
07251 size = 0;
07252 for (i = 1; i <= nrows; i++) {
07253 int k;
07254
07255 if (!rowp[i]) {
07256 continue;
07257 }
07258 rowpp = NULL;
07259 ret = SQLITE_ERROR;
07260 sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
07261 if (sql) {
07262 dbtraceapi(d, "sqlite3_get_table", sql);
07263 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
07264 &nnrows, &nncols, NULL);
07265 sqlite3_free(sql);
07266 }
07267 if (ret != SQLITE_OK || nncols * nnrows <= 0) {
07268 sqlite3_free_table(rowpp);
07269 continue;
07270 }
07271 namec = findcol(rowpp, nncols, "table");
07272 seqc = findcol(rowpp, nncols, "seq");
07273 fromc = findcol(rowpp, nncols, "from");
07274 toc = findcol(rowpp, nncols, "to");
07275 if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
07276 sqlite3_free_table(rowpp);
07277 continue;
07278 }
07279 for (k = 1; k <= nnrows; k++) {
07280 char *ptab = unquote(rowpp[k * nncols + namec]);
07281
07282 if (plen && ptab) {
07283 int len = strlen(ptab);
07284
07285 if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
07286 continue;
07287 }
07288 }
07289 size++;
07290 }
07291 sqlite3_free_table(rowpp);
07292 }
07293 if (size == 0) {
07294 goto nodata;
07295 }
07296 s->nrows = size;
07297 size = (size + 1) * asize;
07298 s->rows = xmalloc((size + 1) * sizeof (char *));
07299 if (!s->rows) {
07300 s->nrows = 0;
07301 return nomem(s);
07302 }
07303 s->rows[0] = (char *) size;
07304 s->rows += 1;
07305 memset(s->rows, 0, sizeof (char *) * size);
07306 s->rowfree = freerows;
07307 offs = 0;
07308 for (i = 1; i <= nrows; i++) {
07309 int k;
07310
07311 if (!rowp[i]) {
07312 continue;
07313 }
07314 rowpp = NULL;
07315 ret = SQLITE_ERROR;
07316 sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
07317 if (sql) {
07318 dbtraceapi(d, "sqlite3_get_table", sql);
07319 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
07320 &nnrows, &nncols, NULL);
07321 sqlite3_free(sql);
07322 }
07323 if (ret != SQLITE_OK || nncols * nnrows <= 0) {
07324 sqlite3_free_table(rowpp);
07325 continue;
07326 }
07327 namec = findcol(rowpp, nncols, "table");
07328 seqc = findcol(rowpp, nncols, "seq");
07329 fromc = findcol(rowpp, nncols, "from");
07330 toc = findcol(rowpp, nncols, "to");
07331 onu = findcol(rowpp, nncols, "on_update");
07332 ond = findcol(rowpp, nncols, "on_delete");
07333 if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
07334 sqlite3_free_table(rowpp);
07335 continue;
07336 }
07337 for (k = 1; k <= nnrows; k++) {
07338 int pos = 0, roffs = (offs + 1) * s->ncols;
07339 char *ptab = unquote(rowpp[k * nncols + namec]);
07340 char buf[32];
07341
07342 if (plen && ptab) {
07343 int len = strlen(ptab);
07344
07345 if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
07346 continue;
07347 }
07348 }
07349 s->rows[roffs + 0] = xstrdup("");
07350 #if defined(_WIN32) || defined(_WIN64)
07351 s->rows[roffs + 1] = xstrdup(d->xcelqrx ? "main" : "");
07352 #else
07353 s->rows[roffs + 1] = xstrdup("");
07354 #endif
07355 s->rows[roffs + 2] = xstrdup(ptab);
07356 s->rows[roffs + 3] = xstrdup(rowpp[k * nncols + toc]);
07357 s->rows[roffs + 4] = xstrdup("");
07358 s->rows[roffs + 5] = xstrdup("");
07359 s->rows[roffs + 6] = xstrdup(rowp[i]);
07360 s->rows[roffs + 7] = xstrdup(rowpp[k * nncols + fromc]);
07361 sscanf(rowpp[k * nncols + seqc], "%d", &pos);
07362 sprintf(buf, "%d", pos + 1);
07363 s->rows[roffs + 8] = xstrdup(buf);
07364 if (onu < 0) {
07365 s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
07366 } else {
07367 if (strcmp(rowpp[k * nncols + onu], "SET NULL") == 0) {
07368 s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
07369 } else if (strcmp(rowpp[k * nncols + onu], "SET DEFAULT")
07370 == 0) {
07371 s->rows[roffs + 9] =
07372 xstrdup(stringify(SQL_SET_DEFAULT));
07373 } else if (strcmp(rowpp[k * nncols + onu], "CASCADE")
07374 == 0) {
07375 s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
07376 } else if (strcmp(rowpp[k * nncols + onu], "RESTRICT")
07377 == 0) {
07378 s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
07379 } else {
07380 s->rows[roffs + 9] =
07381 xstrdup(stringify(SQL_NO_ACTION));
07382 }
07383 }
07384 if (ond < 0) {
07385 s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
07386 } else {
07387 if (strcmp(rowpp[k * nncols + ond], "SET NULL") == 0) {
07388 s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
07389 } else if (strcmp(rowpp[k * nncols + ond], "SET DEFAULT")
07390 == 0) {
07391 s->rows[roffs + 10] =
07392 xstrdup(stringify(SQL_SET_DEFAULT));
07393 } else if (strcmp(rowpp[k * nncols + ond], "CASCADE")
07394 == 0) {
07395 s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
07396 } else if (strcmp(rowpp[k * nncols + ond], "RESTRICT")
07397 == 0) {
07398 s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
07399 } else {
07400 s->rows[roffs + 10] =
07401 xstrdup(stringify(SQL_NO_ACTION));
07402 }
07403 }
07404 s->rows[roffs + 11] = NULL;
07405 s->rows[roffs + 12] = NULL;
07406 s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
07407 offs++;
07408 }
07409 sqlite3_free_table(rowpp);
07410 }
07411 sqlite3_free_table(rowp);
07412 }
07413 return SQL_SUCCESS;
07414 }
07415
07416 #ifndef WINTERFACE
07417
07435 SQLRETURN SQL_API
07436 SQLForeignKeys(SQLHSTMT stmt,
07437 SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
07438 SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
07439 SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
07440 SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
07441 SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
07442 SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
07443 {
07444 #if defined(_WIN32) || defined(_WIN64)
07445 char *pc = NULL, *ps = NULL, *pt = NULL;
07446 char *fc = NULL, *fs = NULL, *ft = NULL;
07447 #endif
07448 SQLRETURN ret;
07449
07450 HSTMT_LOCK(stmt);
07451 #if defined(_WIN32) || defined(_WIN64)
07452 if (!((STMT *) stmt)->oemcp[0]) {
07453 ret = drvforeignkeys(stmt,
07454 PKcatalog, PKcatalogLen,
07455 PKschema, PKschemaLen, PKtable, PKtableLen,
07456 FKcatalog, FKcatalogLen,
07457 FKschema, FKschemaLen,
07458 FKtable, FKtableLen);
07459 goto done2;
07460 }
07461 if (PKcatalog) {
07462 pc = wmb_to_utf_c((char *) PKcatalog, PKcatalogLen);
07463 if (!pc) {
07464 ret = nomem((STMT *) stmt);
07465 goto done;
07466 }
07467 }
07468 if (PKschema) {
07469 ps = wmb_to_utf_c((char *) PKschema, PKschemaLen);
07470 if (!ps) {
07471 ret = nomem((STMT *) stmt);
07472 goto done;
07473 }
07474 }
07475 if (PKtable) {
07476 pt = wmb_to_utf_c((char *) PKtable, PKtableLen);
07477 if (!pt) {
07478 ret = nomem((STMT *) stmt);
07479 goto done;
07480 }
07481 }
07482 if (FKcatalog) {
07483 fc = wmb_to_utf_c((char *) FKcatalog, FKcatalogLen);
07484 if (!fc) {
07485 ret = nomem((STMT *) stmt);
07486 goto done;
07487 }
07488 }
07489 if (FKschema) {
07490 fs = wmb_to_utf_c((char *) FKschema, FKschemaLen);
07491 if (!fs) {
07492 ret = nomem((STMT *) stmt);
07493 goto done;
07494 }
07495 }
07496 if (FKtable) {
07497 ft = wmb_to_utf_c((char *) FKtable, FKtableLen);
07498 if (!ft) {
07499 ret = nomem((STMT *) stmt);
07500 goto done;
07501 }
07502 }
07503 ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
07504 (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
07505 (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
07506 (SQLCHAR *) ft, SQL_NTS);
07507 #else
07508 ret = drvforeignkeys(stmt,
07509 PKcatalog, PKcatalogLen,
07510 PKschema, PKschemaLen, PKtable, PKtableLen,
07511 FKcatalog, FKcatalogLen,
07512 FKschema, FKschemaLen,
07513 FKtable, FKtableLen);
07514 #endif
07515 #if defined(_WIN32) || defined(_WIN64)
07516 done:
07517 uc_free(ft);
07518 uc_free(fs);
07519 uc_free(fc);
07520 uc_free(pt);
07521 uc_free(ps);
07522 uc_free(pc);
07523 done2:
07524 ;
07525 #endif
07526 HSTMT_UNLOCK(stmt);
07527 return ret;
07528 }
07529 #endif
07530
07531 #ifdef WINTERFACE
07532
07550 SQLRETURN SQL_API
07551 SQLForeignKeysW(SQLHSTMT stmt,
07552 SQLWCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
07553 SQLWCHAR *PKschema, SQLSMALLINT PKschemaLen,
07554 SQLWCHAR *PKtable, SQLSMALLINT PKtableLen,
07555 SQLWCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
07556 SQLWCHAR *FKschema, SQLSMALLINT FKschemaLen,
07557 SQLWCHAR *FKtable, SQLSMALLINT FKtableLen)
07558 {
07559 char *pc = NULL, *ps = NULL, *pt = NULL;
07560 char *fc = NULL, *fs = NULL, *ft = NULL;
07561 SQLRETURN ret;
07562
07563 HSTMT_LOCK(stmt);
07564 if (PKcatalog) {
07565 pc = uc_to_utf_c(PKcatalog, PKcatalogLen);
07566 if (!pc) {
07567 ret = nomem((STMT *) stmt);
07568 goto done;
07569 }
07570 }
07571 if (PKschema) {
07572 ps = uc_to_utf_c(PKschema, PKschemaLen);
07573 if (!ps) {
07574 ret = nomem((STMT *) stmt);
07575 goto done;
07576 }
07577 }
07578 if (PKtable) {
07579 pt = uc_to_utf_c(PKtable, PKtableLen);
07580 if (!pt) {
07581 ret = nomem((STMT *) stmt);
07582 goto done;
07583 }
07584 }
07585 if (FKcatalog) {
07586 fc = uc_to_utf_c(FKcatalog, FKcatalogLen);
07587 if (!fc) {
07588 ret = nomem((STMT *) stmt);
07589 goto done;
07590 }
07591 }
07592 if (FKschema) {
07593 fs = uc_to_utf_c(FKschema, FKschemaLen);
07594 if (!fs) {
07595 ret = nomem((STMT *) stmt);
07596 goto done;
07597 }
07598 }
07599 if (FKtable) {
07600 ft = uc_to_utf_c(FKtable, FKtableLen);
07601 if (!ft) {
07602 ret = nomem((STMT *) stmt);
07603 goto done;
07604 }
07605 }
07606 ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
07607 (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
07608 (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
07609 (SQLCHAR *) ft, SQL_NTS);
07610 done:
07611 uc_free(ft);
07612 uc_free(fs);
07613 uc_free(fc);
07614 uc_free(pt);
07615 uc_free(ps);
07616 uc_free(pc);
07617 HSTMT_UNLOCK(stmt);
07618 return ret;
07619 }
07620 #endif
07621
07628 static SQLRETURN
07629 starttran(STMT *s)
07630 {
07631 int ret = SQL_SUCCESS, rc, busy_count = 0;
07632 char *errp = NULL;
07633 DBC *d = (DBC *) s->dbc;
07634
07635 if (!d->autocommit && !d->intrans && !d->trans_disable) {
07636 begin_again:
07637 rc = sqlite3_exec(d->sqlite, "BEGIN TRANSACTION", NULL, NULL, &errp);
07638 if (rc == SQLITE_BUSY) {
07639 if (busy_handler((void *) d, ++busy_count)) {
07640 if (errp) {
07641 sqlite3_free(errp);
07642 errp = NULL;
07643 }
07644 goto begin_again;
07645 }
07646 }
07647 dbtracerc(d, rc, errp);
07648 if (rc != SQLITE_OK) {
07649 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
07650 errp ? errp : "unknown error", rc);
07651 ret = SQL_ERROR;
07652 } else {
07653 d->intrans = 1;
07654 }
07655 if (errp) {
07656 sqlite3_free(errp);
07657 errp = NULL;
07658 }
07659 }
07660 return ret;
07661 }
07662
07671 static SQLRETURN
07672 endtran(DBC *d, SQLSMALLINT comptype, int force)
07673 {
07674 int ret, busy_count = 0;
07675 char *sql, *errp = NULL;
07676
07677 if (!d->sqlite) {
07678 setstatd(d, -1, "not connected", (*d->ov3) ? "HY000" : "S1000");
07679 return SQL_ERROR;
07680 }
07681 if ((!force && d->autocommit) || !d->intrans) {
07682 return SQL_SUCCESS;
07683 }
07684 switch (comptype) {
07685 case SQL_COMMIT:
07686 sql = "COMMIT TRANSACTION";
07687 goto doit;
07688 case SQL_ROLLBACK:
07689 sql = "ROLLBACK TRANSACTION";
07690 doit:
07691 ret = sqlite3_exec(d->sqlite, sql, NULL, NULL, &errp);
07692 dbtracerc(d, ret, errp);
07693 if (ret == SQLITE_BUSY && busy_count < 10) {
07694 if (busy_handler((void *) d, ++busy_count)) {
07695 if (errp) {
07696 sqlite3_free(errp);
07697 errp = NULL;
07698 }
07699 goto doit;
07700 }
07701 }
07702 d->intrans = 0;
07703 if (ret != SQLITE_OK) {
07704 setstatd(d, ret, "%s", (*d->ov3) ? "HY000" : "S1000",
07705 errp ? errp : "transaction failed");
07706 if (errp) {
07707 sqlite3_free(errp);
07708 errp = NULL;
07709 }
07710 return SQL_ERROR;
07711 }
07712 if (errp) {
07713 sqlite3_free(errp);
07714 errp = NULL;
07715 }
07716 return SQL_SUCCESS;
07717 }
07718 setstatd(d, -1, "invalid completion type", (*d->ov3) ? "HY000" : "S1000");
07719 return SQL_ERROR;
07720 }
07721
07730 static SQLRETURN
07731 drvendtran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
07732 {
07733 DBC *d;
07734 int fail = 0;
07735 SQLRETURN ret;
07736 #if defined(_WIN32) || defined(_WIN64)
07737 ENV *e;
07738 #endif
07739
07740 switch (type) {
07741 case SQL_HANDLE_DBC:
07742 HDBC_LOCK((SQLHDBC) handle);
07743 if (handle == SQL_NULL_HDBC) {
07744 return SQL_INVALID_HANDLE;
07745 }
07746 d = (DBC *) handle;
07747 ret = endtran(d, comptype, 0);
07748 HDBC_UNLOCK((SQLHDBC) handle);
07749 return ret;
07750 case SQL_HANDLE_ENV:
07751 if (handle == SQL_NULL_HENV) {
07752 return SQL_INVALID_HANDLE;
07753 }
07754 #if defined(_WIN32) || defined(_WIN64)
07755 e = (ENV *) handle;
07756 if (e->magic != ENV_MAGIC) {
07757 return SQL_INVALID_HANDLE;
07758 }
07759 EnterCriticalSection(&e->cs);
07760 e->owner = GetCurrentThreadId();
07761 #endif
07762 d = ((ENV *) handle)->dbcs;
07763 while (d) {
07764 ret = endtran(d, comptype, 0);
07765 if (ret != SQL_SUCCESS) {
07766 fail++;
07767 }
07768 d = d->next;
07769 }
07770 #if defined(_WIN32) || defined(_WIN64)
07771 e->owner = 0;
07772 LeaveCriticalSection(&e->cs);
07773 #endif
07774 return fail ? SQL_ERROR : SQL_SUCCESS;
07775 }
07776 return SQL_INVALID_HANDLE;
07777 }
07778
07787 SQLRETURN SQL_API
07788 SQLEndTran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
07789 {
07790 return drvendtran(type, handle, comptype);
07791 }
07792
07801 SQLRETURN SQL_API
07802 SQLTransact(SQLHENV env, SQLHDBC dbc, SQLUSMALLINT type)
07803 {
07804 if (env != SQL_NULL_HENV) {
07805 return drvendtran(SQL_HANDLE_ENV, (SQLHANDLE) env, type);
07806 }
07807 return drvendtran(SQL_HANDLE_DBC, (SQLHANDLE) dbc, type);
07808 }
07809
07814 SQLRETURN SQL_API
07815 SQLCopyDesc(SQLHDESC source, SQLHDESC target)
07816 {
07817 return SQL_ERROR;
07818 }
07819
07820 #ifndef WINTERFACE
07821
07832 SQLRETURN SQL_API
07833 SQLNativeSql(SQLHSTMT stmt, SQLCHAR *sqlin, SQLINTEGER sqlinLen,
07834 SQLCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
07835 {
07836 int outLen = 0;
07837 SQLRETURN ret = SQL_SUCCESS;
07838
07839 HSTMT_LOCK(stmt);
07840 if (sqlinLen == SQL_NTS) {
07841 sqlinLen = strlen((char *) sqlin);
07842 }
07843 if (sql) {
07844 if (sqlMax > 0) {
07845 strncpy((char *) sql, (char *) sqlin, sqlMax - 1);
07846 sqlin[sqlMax - 1] = '\0';
07847 outLen = min(sqlMax - 1, sqlinLen);
07848 }
07849 } else {
07850 outLen = sqlinLen;
07851 }
07852 if (sqlLen) {
07853 *sqlLen = outLen;
07854 }
07855 if (sql && outLen < sqlinLen) {
07856 setstat((STMT *) stmt, -1, "data right truncated", "01004");
07857 ret = SQL_SUCCESS_WITH_INFO;
07858 }
07859 HSTMT_UNLOCK(stmt);
07860 return ret;
07861 }
07862 #endif
07863
07864 #ifdef WINTERFACE
07865
07876 SQLRETURN SQL_API
07877 SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen,
07878 SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
07879 {
07880 int outLen = 0;
07881 SQLRETURN ret = SQL_SUCCESS;
07882
07883 HSTMT_LOCK(stmt);
07884 if (sqlinLen == SQL_NTS) {
07885 sqlinLen = uc_strlen(sqlin);
07886 }
07887 if (sql) {
07888 if (sqlMax > 0) {
07889 uc_strncpy(sql, sqlin, sqlMax - 1);
07890 sqlin[sqlMax - 1] = 0;
07891 outLen = min(sqlMax - 1, sqlinLen);
07892 }
07893 } else {
07894 outLen = sqlinLen;
07895 }
07896 if (sqlLen) {
07897 *sqlLen = outLen;
07898 }
07899 if (sql && outLen < sqlinLen) {
07900 setstat((STMT *) stmt, -1, "data right truncated", "01004");
07901 ret = SQL_SUCCESS_WITH_INFO;
07902 }
07903 HSTMT_UNLOCK(stmt);
07904 return ret;
07905 }
07906 #endif
07907
07912 static COL procSpec2[] = {
07913 { "SYSTEM", "PROCEDURE", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
07914 { "SYSTEM", "PROCEDURE", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
07915 { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
07916 { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
07917 { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
07918 { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
07919 { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
07920 { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
07921 };
07922
07923 static COL procSpec3[] = {
07924 { "SYSTEM", "PROCEDURE", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
07925 { "SYSTEM", "PROCEDURE", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
07926 { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
07927 { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
07928 { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
07929 { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
07930 { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
07931 { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
07932 };
07933
07934 #ifndef WINTERFACE
07935
07947 SQLRETURN SQL_API
07948 SQLProcedures(SQLHSTMT stmt,
07949 SQLCHAR *catalog, SQLSMALLINT catalogLen,
07950 SQLCHAR *schema, SQLSMALLINT schemaLen,
07951 SQLCHAR *proc, SQLSMALLINT procLen)
07952 {
07953 SQLRETURN ret;
07954
07955 HSTMT_LOCK(stmt);
07956 ret = mkresultset(stmt, procSpec2, array_size(procSpec2),
07957 procSpec3, array_size(procSpec3), NULL);
07958 HSTMT_UNLOCK(stmt);
07959 return ret;
07960 }
07961 #endif
07962
07963 #ifdef WINTERFACE
07964
07976 SQLRETURN SQL_API
07977 SQLProceduresW(SQLHSTMT stmt,
07978 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
07979 SQLWCHAR *schema, SQLSMALLINT schemaLen,
07980 SQLWCHAR *proc, SQLSMALLINT procLen)
07981 {
07982 SQLRETURN ret;
07983
07984 HSTMT_LOCK(stmt);
07985 ret = mkresultset(stmt, procSpec2, array_size(procSpec2),
07986 procSpec3, array_size(procSpec3), NULL);
07987 HSTMT_UNLOCK(stmt);
07988 return ret;
07989 }
07990 #endif
07991
07996 static COL procColSpec2[] = {
07997 { "SYSTEM", "PROCCOL", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
07998 { "SYSTEM", "PROCCOL", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
07999 { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
08000 { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
08001 { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
08002 { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
08003 { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
08004 { "SYSTEM", "PROCCOL", "PRECISION", SQL_INTEGER, 10 },
08005 { "SYSTEM", "PROCCOL", "LENGTH", SQL_INTEGER, 10 },
08006 { "SYSTEM", "PROCCOL", "SCALE", SQL_SMALLINT, 5 },
08007 { "SYSTEM", "PROCCOL", "RADIX", SQL_SMALLINT, 5 },
08008 { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
08009 { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
08010 { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
08011 { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
08012 { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
08013 { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
08014 { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
08015 { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
08016 };
08017
08018 static COL procColSpec3[] = {
08019 { "SYSTEM", "PROCCOL", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
08020 { "SYSTEM", "PROCCOL", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
08021 { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
08022 { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
08023 { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
08024 { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
08025 { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
08026 { "SYSTEM", "PROCCOL", "COLUMN_SIZE", SQL_INTEGER, 10 },
08027 { "SYSTEM", "PROCCOL", "BUFFER_LENGTH", SQL_INTEGER, 10 },
08028 { "SYSTEM", "PROCCOL", "DECIMAL_DIGITS", SQL_SMALLINT, 5 },
08029 { "SYSTEM", "PROCCOL", "NUM_PREC_RADIX", SQL_SMALLINT, 5 },
08030 { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
08031 { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
08032 { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
08033 { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
08034 { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
08035 { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
08036 { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
08037 { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
08038 };
08039
08040 #ifndef WINTERFACE
08041
08055 SQLRETURN SQL_API
08056 SQLProcedureColumns(SQLHSTMT stmt,
08057 SQLCHAR *catalog, SQLSMALLINT catalogLen,
08058 SQLCHAR *schema, SQLSMALLINT schemaLen,
08059 SQLCHAR *proc, SQLSMALLINT procLen,
08060 SQLCHAR *column, SQLSMALLINT columnLen)
08061 {
08062 SQLRETURN ret;
08063
08064 HSTMT_LOCK(stmt);
08065 ret = mkresultset(stmt, procColSpec2, array_size(procColSpec2),
08066 procColSpec3, array_size(procColSpec3), NULL);
08067 HSTMT_UNLOCK(stmt);
08068 return ret;
08069 }
08070 #endif
08071
08072 #ifdef WINTERFACE
08073
08088 SQLRETURN SQL_API
08089 SQLProcedureColumnsW(SQLHSTMT stmt,
08090 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
08091 SQLWCHAR *schema, SQLSMALLINT schemaLen,
08092 SQLWCHAR *proc, SQLSMALLINT procLen,
08093 SQLWCHAR *column, SQLSMALLINT columnLen)
08094 {
08095 SQLRETURN ret;
08096
08097 HSTMT_LOCK(stmt);
08098 ret = mkresultset(stmt, procColSpec2, array_size(procColSpec2),
08099 procColSpec3, array_size(procColSpec3), NULL);
08100 HSTMT_UNLOCK(stmt);
08101 return ret;
08102 }
08103 #endif
08104
08115 SQLRETURN SQL_API
08116 SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val,
08117 SQLINTEGER len, SQLINTEGER *lenp)
08118 {
08119 ENV *e;
08120 SQLRETURN ret = SQL_ERROR;
08121
08122 if (env == SQL_NULL_HENV) {
08123 return SQL_INVALID_HANDLE;
08124 }
08125 e = (ENV *) env;
08126 if (!e || e->magic != ENV_MAGIC) {
08127 return SQL_INVALID_HANDLE;
08128 }
08129 #if defined(_WIN32) || defined(_WIN64)
08130 EnterCriticalSection(&e->cs);
08131 e->owner = GetCurrentThreadId();
08132 #endif
08133 switch (attr) {
08134 case SQL_ATTR_CONNECTION_POOLING:
08135 ret = SQL_ERROR;
08136 break;
08137 case SQL_ATTR_CP_MATCH:
08138 ret = SQL_NO_DATA;
08139 break;
08140 case SQL_ATTR_OUTPUT_NTS:
08141 if (val) {
08142 *((SQLINTEGER *) val) = SQL_TRUE;
08143 }
08144 if (lenp) {
08145 *lenp = sizeof (SQLINTEGER);
08146 }
08147 ret = SQL_SUCCESS;
08148 break;
08149 case SQL_ATTR_ODBC_VERSION:
08150 if (val) {
08151 *((SQLINTEGER *) val) = e->ov3 ? SQL_OV_ODBC3 : SQL_OV_ODBC2;
08152 }
08153 if (lenp) {
08154 *lenp = sizeof (SQLINTEGER);
08155 }
08156 ret = SQL_SUCCESS;
08157 break;
08158 }
08159 #if defined(_WIN32) || defined(_WIN64)
08160 e->owner = 0;
08161 LeaveCriticalSection(&e->cs);
08162 #endif
08163 return ret;
08164 }
08165
08175 SQLRETURN SQL_API
08176 SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
08177 {
08178 ENV *e;
08179 SQLRETURN ret = SQL_ERROR;
08180
08181 if (env == SQL_NULL_HENV) {
08182 return SQL_INVALID_HANDLE;
08183 }
08184 e = (ENV *) env;
08185 if (!e || e->magic != ENV_MAGIC) {
08186 return SQL_INVALID_HANDLE;
08187 }
08188 #if defined(_WIN32) || defined(_WIN64)
08189 EnterCriticalSection(&e->cs);
08190 e->owner = GetCurrentThreadId();
08191 #endif
08192 switch (attr) {
08193 case SQL_ATTR_CONNECTION_POOLING:
08194 ret = SQL_SUCCESS;
08195 break;
08196 case SQL_ATTR_CP_MATCH:
08197 ret = SQL_NO_DATA;
08198 break;
08199 case SQL_ATTR_OUTPUT_NTS:
08200 if (val == (SQLPOINTER) SQL_TRUE) {
08201 ret = SQL_SUCCESS;
08202 }
08203 break;
08204 case SQL_ATTR_ODBC_VERSION:
08205 if (!val) {
08206 break;
08207 }
08208 if (val == (SQLPOINTER) SQL_OV_ODBC2) {
08209 e->ov3 = 0;
08210 ret = SQL_SUCCESS;
08211 }
08212 if (val == (SQLPOINTER) SQL_OV_ODBC3) {
08213 e->ov3 = 1;
08214 ret = SQL_SUCCESS;
08215 }
08216 break;
08217 }
08218 #if defined(_WIN32) || defined(_WIN64)
08219 e->owner = 0;
08220 LeaveCriticalSection(&e->cs);
08221 #endif
08222 return ret;
08223 }
08224
08238 static SQLRETURN
08239 drvgetdiagrec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
08240 SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
08241 SQLSMALLINT buflen, SQLSMALLINT *msglen)
08242 {
08243 DBC *d = NULL;
08244 STMT *s = NULL;
08245 int len, naterr;
08246 char *logmsg, *sqlst;
08247 SQLRETURN ret = SQL_ERROR;
08248
08249 if (handle == SQL_NULL_HANDLE) {
08250 return SQL_INVALID_HANDLE;
08251 }
08252 if (sqlstate) {
08253 sqlstate[0] = '\0';
08254 }
08255 if (msg && buflen > 0) {
08256 msg[0] = '\0';
08257 }
08258 if (msglen) {
08259 *msglen = 0;
08260 }
08261 if (nativeerr) {
08262 *nativeerr = 0;
08263 }
08264 switch (htype) {
08265 case SQL_HANDLE_ENV:
08266 case SQL_HANDLE_DESC:
08267 return SQL_NO_DATA;
08268 case SQL_HANDLE_DBC:
08269 HDBC_LOCK((SQLHDBC) handle);
08270 d = (DBC *) handle;
08271 logmsg = (char *) d->logmsg;
08272 sqlst = d->sqlstate;
08273 naterr = d->naterr;
08274 break;
08275 case SQL_HANDLE_STMT:
08276 HSTMT_LOCK((SQLHSTMT) handle);
08277 s = (STMT *) handle;
08278 logmsg = (char *) s->logmsg;
08279 sqlst = s->sqlstate;
08280 naterr = s->naterr;
08281 break;
08282 default:
08283 return SQL_INVALID_HANDLE;
08284 }
08285 if (buflen < 0) {
08286 goto done;
08287 }
08288 if (recno > 1) {
08289 ret = SQL_NO_DATA;
08290 goto done;
08291 }
08292 len = strlen(logmsg);
08293 if (len == 0) {
08294 ret = SQL_NO_DATA;
08295 goto done;
08296 }
08297 if (nativeerr) {
08298 *nativeerr = naterr;
08299 }
08300 if (sqlstate) {
08301 strcpy((char *) sqlstate, sqlst);
08302 }
08303 if (msglen) {
08304 *msglen = len;
08305 }
08306 if (len >= buflen) {
08307 if (msg && buflen > 0) {
08308 strncpy((char *) msg, logmsg, buflen);
08309 msg[buflen - 1] = '\0';
08310 logmsg[0] = '\0';
08311 }
08312 } else if (msg) {
08313 strcpy((char *) msg, logmsg);
08314 logmsg[0] = '\0';
08315 }
08316 ret = SQL_SUCCESS;
08317 done:
08318 switch (htype) {
08319 case SQL_HANDLE_DBC:
08320 HDBC_UNLOCK((SQLHDBC) handle);
08321 break;
08322 case SQL_HANDLE_STMT:
08323 HSTMT_UNLOCK((SQLHSTMT) handle);
08324 break;
08325 }
08326 return ret;
08327 }
08328
08329 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
08330
08343 SQLRETURN SQL_API
08344 SQLGetDiagRec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
08345 SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
08346 SQLSMALLINT buflen, SQLSMALLINT *msglen)
08347 {
08348 return drvgetdiagrec(htype, handle, recno, sqlstate,
08349 nativeerr, msg, buflen, msglen);
08350 }
08351 #endif
08352
08353 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
08354 #ifdef WINTERFACE
08355
08369 SQLRETURN SQL_API
08370 SQLGetDiagRecW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
08371 SQLWCHAR *sqlstate, SQLINTEGER *nativeerr, SQLWCHAR *msg,
08372 SQLSMALLINT buflen, SQLSMALLINT *msglen)
08373 {
08374 char state[16];
08375 SQLSMALLINT len;
08376 SQLRETURN ret;
08377
08378 ret = drvgetdiagrec(htype, handle, recno, (SQLCHAR *) state,
08379 nativeerr, (SQLCHAR *) msg, buflen, &len);
08380 if (ret == SQL_SUCCESS) {
08381 if (sqlstate) {
08382 uc_from_utf_buf((SQLCHAR *) state, -1, sqlstate,
08383 6 * sizeof (SQLWCHAR));
08384 }
08385 if (msg) {
08386 if (len > 0) {
08387 SQLWCHAR *m = NULL;
08388
08389 m = uc_from_utf((unsigned char *) msg, len);
08390 if (m) {
08391 if (buflen) {
08392 buflen /= sizeof (SQLWCHAR);
08393 uc_strncpy(msg, m, buflen);
08394 m[len] = 0;
08395 len = min(buflen, uc_strlen(m));
08396 } else {
08397 len = uc_strlen(m);
08398 }
08399 uc_free(m);
08400 } else {
08401 len = 0;
08402 }
08403 }
08404 if (len <= 0) {
08405 len = 0;
08406 if (buflen > 0) {
08407 msg[0] = 0;
08408 }
08409 }
08410 } else {
08411
08412 len *= sizeof (SQLWCHAR);
08413 }
08414 if (msglen) {
08415 *msglen = len;
08416 }
08417 } else if (ret == SQL_NO_DATA) {
08418 if (sqlstate) {
08419 sqlstate[0] = 0;
08420 }
08421 if (msg) {
08422 if (buflen > 0) {
08423 msg[0] = 0;
08424 }
08425 }
08426 if (msglen) {
08427 *msglen = 0;
08428 }
08429 }
08430 return ret;
08431 }
08432 #endif
08433 #endif
08434
08447 static SQLRETURN
08448 drvgetdiagfield(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
08449 SQLSMALLINT id, SQLPOINTER info,
08450 SQLSMALLINT buflen, SQLSMALLINT *stringlen)
08451 {
08452 DBC *d = NULL;
08453 STMT *s = NULL;
08454 int len, naterr, strbuf = 1;
08455 char *logmsg, *sqlst, *clrmsg = NULL;
08456 SQLRETURN ret = SQL_ERROR;
08457
08458 if (handle == SQL_NULL_HANDLE) {
08459 return SQL_INVALID_HANDLE;
08460 }
08461 if (stringlen) {
08462 *stringlen = 0;
08463 }
08464 switch (htype) {
08465 case SQL_HANDLE_ENV:
08466 case SQL_HANDLE_DESC:
08467 return SQL_NO_DATA;
08468 case SQL_HANDLE_DBC:
08469 HDBC_LOCK((SQLHDBC) handle);
08470 d = (DBC *) handle;
08471 logmsg = (char *) d->logmsg;
08472 sqlst = d->sqlstate;
08473 naterr = d->naterr;
08474 break;
08475 case SQL_HANDLE_STMT:
08476 HSTMT_LOCK((SQLHSTMT) handle);
08477 s = (STMT *) handle;
08478 d = (DBC *) s->dbc;
08479 logmsg = (char *) s->logmsg;
08480 sqlst = s->sqlstate;
08481 naterr = s->naterr;
08482 break;
08483 default:
08484 return SQL_INVALID_HANDLE;
08485 }
08486 if (buflen < 0) {
08487 switch (buflen) {
08488 case SQL_IS_POINTER:
08489 case SQL_IS_UINTEGER:
08490 case SQL_IS_INTEGER:
08491 case SQL_IS_USMALLINT:
08492 case SQL_IS_SMALLINT:
08493 strbuf = 0;
08494 break;
08495 default:
08496 ret = SQL_ERROR;
08497 goto done;
08498 }
08499 }
08500 if (recno > 1) {
08501 ret = SQL_NO_DATA;
08502 goto done;
08503 }
08504 switch (id) {
08505 case SQL_DIAG_CLASS_ORIGIN:
08506 logmsg = "ISO 9075";
08507 if (sqlst[0] == 'I' && sqlst[1] == 'M') {
08508 logmsg = "ODBC 3.0";
08509 }
08510 break;
08511 case SQL_DIAG_SUBCLASS_ORIGIN:
08512 logmsg = "ISO 9075";
08513 if (sqlst[0] == 'I' && sqlst[1] == 'M') {
08514 logmsg = "ODBC 3.0";
08515 } else if (sqlst[0] == 'H' && sqlst[1] == 'Y') {
08516 logmsg = "ODBC 3.0";
08517 } else if (sqlst[0] == '2' || sqlst[0] == '0' || sqlst[0] == '4') {
08518 logmsg = "ODBC 3.0";
08519 }
08520 break;
08521 case SQL_DIAG_CONNECTION_NAME:
08522 case SQL_DIAG_SERVER_NAME:
08523 logmsg = d->dsn ? d->dsn : "No DSN";
08524 break;
08525 case SQL_DIAG_SQLSTATE:
08526 logmsg = sqlst;
08527 break;
08528 case SQL_DIAG_MESSAGE_TEXT:
08529 if (info) {
08530 clrmsg = logmsg;
08531 }
08532 break;
08533 case SQL_DIAG_NUMBER:
08534 naterr = 1;
08535
08536 case SQL_DIAG_NATIVE:
08537 len = strlen(logmsg);
08538 if (len == 0) {
08539 ret = SQL_NO_DATA;
08540 goto done;
08541 }
08542 if (info) {
08543 *((SQLINTEGER *) info) = naterr;
08544 }
08545 ret = SQL_SUCCESS;
08546 goto done;
08547 case SQL_DIAG_DYNAMIC_FUNCTION:
08548 logmsg = "";
08549 break;
08550 case SQL_DIAG_CURSOR_ROW_COUNT:
08551 if (htype == SQL_HANDLE_STMT) {
08552 SQLULEN count;
08553
08554 count = (s->isselect == 1 || s->isselect == -1) ? s->nrows : 0;
08555 *((SQLULEN *) info) = count;
08556 ret = SQL_SUCCESS;
08557 }
08558 goto done;
08559 case SQL_DIAG_ROW_COUNT:
08560 if (htype == SQL_HANDLE_STMT) {
08561 SQLULEN count;
08562
08563 count = s->isselect ? 0 : s->nrows;
08564 *((SQLULEN *) info) = count;
08565 ret = SQL_SUCCESS;
08566 }
08567 goto done;
08568 default:
08569 goto done;
08570 }
08571 if (info && buflen > 0) {
08572 ((char *) info)[0] = '\0';
08573 }
08574 len = strlen(logmsg);
08575 if (len == 0) {
08576 ret = SQL_NO_DATA;
08577 goto done;
08578 }
08579 if (stringlen) {
08580 *stringlen = len;
08581 }
08582 if (strbuf) {
08583 if (len >= buflen) {
08584 if (info && buflen > 0) {
08585 if (stringlen) {
08586 *stringlen = buflen - 1;
08587 }
08588 strncpy((char *) info, logmsg, buflen);
08589 ((char *) info)[buflen - 1] = '\0';
08590 }
08591 } else if (info) {
08592 strcpy((char *) info, logmsg);
08593 }
08594 }
08595 if (clrmsg) {
08596 *clrmsg = '\0';
08597 }
08598 ret = SQL_SUCCESS;
08599 done:
08600 switch (htype) {
08601 case SQL_HANDLE_DBC:
08602 HDBC_UNLOCK((SQLHDBC) handle);
08603 break;
08604 case SQL_HANDLE_STMT:
08605 HSTMT_UNLOCK((SQLHSTMT) handle);
08606 break;
08607 }
08608 return ret;
08609 }
08610
08611 #ifndef WINTERFACE
08612
08624 SQLRETURN SQL_API
08625 SQLGetDiagField(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
08626 SQLSMALLINT id, SQLPOINTER info,
08627 SQLSMALLINT buflen, SQLSMALLINT *stringlen)
08628 {
08629 return drvgetdiagfield(htype, handle, recno, id, info, buflen, stringlen);
08630 }
08631 #endif
08632
08633 #ifdef WINTERFACE
08634
08646 SQLRETURN SQL_API
08647 SQLGetDiagFieldW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
08648 SQLSMALLINT id, SQLPOINTER info,
08649 SQLSMALLINT buflen, SQLSMALLINT *stringlen)
08650 {
08651 SQLSMALLINT len;
08652 SQLRETURN ret;
08653
08654 ret = drvgetdiagfield(htype, handle, recno, id, info, buflen, &len);
08655 if (ret == SQL_SUCCESS) {
08656 if (info) {
08657 switch (id) {
08658 case SQL_DIAG_CLASS_ORIGIN:
08659 case SQL_DIAG_SUBCLASS_ORIGIN:
08660 case SQL_DIAG_CONNECTION_NAME:
08661 case SQL_DIAG_SERVER_NAME:
08662 case SQL_DIAG_SQLSTATE:
08663 case SQL_DIAG_MESSAGE_TEXT:
08664 case SQL_DIAG_DYNAMIC_FUNCTION:
08665 if (len > 0) {
08666 SQLWCHAR *m = NULL;
08667
08668 m = uc_from_utf((unsigned char *) info, len);
08669 if (m) {
08670 if (buflen) {
08671 buflen /= sizeof (SQLWCHAR);
08672 uc_strncpy(info, m, buflen);
08673 m[len] = 0;
08674 len = min(buflen, uc_strlen(m));
08675 } else {
08676 len = uc_strlen(m);
08677 }
08678 uc_free(m);
08679 len *= sizeof (SQLWCHAR);
08680 } else {
08681 len = 0;
08682 }
08683 }
08684 if (len <= 0) {
08685 len = 0;
08686 if (buflen > 0) {
08687 ((SQLWCHAR *) info)[0] = 0;
08688 }
08689 }
08690 }
08691 } else {
08692 switch (id) {
08693 case SQL_DIAG_CLASS_ORIGIN:
08694 case SQL_DIAG_SUBCLASS_ORIGIN:
08695 case SQL_DIAG_CONNECTION_NAME:
08696 case SQL_DIAG_SERVER_NAME:
08697 case SQL_DIAG_SQLSTATE:
08698 case SQL_DIAG_MESSAGE_TEXT:
08699 case SQL_DIAG_DYNAMIC_FUNCTION:
08700 len *= sizeof (SQLWCHAR);
08701 break;
08702 }
08703 }
08704 if (stringlen) {
08705 *stringlen = len;
08706 }
08707 }
08708 return ret;
08709 }
08710 #endif
08711
08722 static SQLRETURN
08723 drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
08724 SQLINTEGER bufmax, SQLINTEGER *buflen)
08725 {
08726 STMT *s = (STMT *) stmt;
08727 SQLULEN *uval = (SQLULEN *) val;
08728
08729 switch (attr) {
08730 case SQL_QUERY_TIMEOUT:
08731 *uval = 0;
08732 return SQL_SUCCESS;
08733 case SQL_ATTR_CURSOR_TYPE:
08734 *uval = s->curtype;
08735 return SQL_SUCCESS;
08736 case SQL_ATTR_CURSOR_SCROLLABLE:
08737 *uval = (s->curtype != SQL_CURSOR_FORWARD_ONLY) ?
08738 SQL_SCROLLABLE : SQL_NONSCROLLABLE;
08739 return SQL_SUCCESS;
08740 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
08741 case SQL_ATTR_CURSOR_SENSITIVITY:
08742 *uval = SQL_UNSPECIFIED;
08743 return SQL_SUCCESS;
08744 #endif
08745 case SQL_ATTR_ROW_NUMBER:
08746 if (s->s3stmt) {
08747 *uval = (s->s3stmt_rownum < 0) ?
08748 SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
08749 } else {
08750 *uval = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
08751 }
08752 return SQL_SUCCESS;
08753 case SQL_ATTR_ASYNC_ENABLE:
08754 *uval = SQL_ASYNC_ENABLE_OFF;
08755 return SQL_SUCCESS;
08756 case SQL_CONCURRENCY:
08757 *uval = SQL_CONCUR_LOCK;
08758 return SQL_SUCCESS;
08759 case SQL_ATTR_RETRIEVE_DATA:
08760 *uval = s->retr_data;
08761 return SQL_SUCCESS;
08762 case SQL_ROWSET_SIZE:
08763 case SQL_ATTR_ROW_ARRAY_SIZE:
08764 *uval = s->rowset_size;
08765 return SQL_SUCCESS;
08766
08767 case SQL_ATTR_IMP_ROW_DESC:
08768 case SQL_ATTR_APP_ROW_DESC:
08769 case SQL_ATTR_IMP_PARAM_DESC:
08770 case SQL_ATTR_APP_PARAM_DESC:
08771 *((SQLHDESC *) val) = (SQLHDESC) DEAD_MAGIC;
08772 return SQL_SUCCESS;
08773 case SQL_ATTR_ROW_STATUS_PTR:
08774 *((SQLUSMALLINT **) val) = s->row_status;
08775 return SQL_SUCCESS;
08776 case SQL_ATTR_ROWS_FETCHED_PTR:
08777 *((SQLULEN **) val) = s->row_count;
08778 return SQL_SUCCESS;
08779 case SQL_ATTR_USE_BOOKMARKS: {
08780 STMT *s = (STMT *) stmt;
08781
08782 *(SQLUINTEGER *) val = s->bkmrk ? SQL_UB_ON : SQL_UB_OFF;
08783 return SQL_SUCCESS;
08784 }
08785 case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
08786 *((SQLULEN **) val) = s->parm_bind_offs;
08787 return SQL_SUCCESS;
08788 case SQL_ATTR_PARAM_BIND_TYPE:
08789 *((SQLULEN *) val) = s->parm_bind_type;
08790 return SQL_SUCCESS;
08791 case SQL_ATTR_PARAM_OPERATION_PTR:
08792 *((SQLUSMALLINT **) val) = s->parm_oper;
08793 return SQL_SUCCESS;
08794 case SQL_ATTR_PARAM_STATUS_PTR:
08795 *((SQLUSMALLINT **) val) = s->parm_status;
08796 return SQL_SUCCESS;
08797 case SQL_ATTR_PARAMS_PROCESSED_PTR:
08798 *((SQLULEN **) val) = s->parm_proc;
08799 return SQL_SUCCESS;
08800 case SQL_ATTR_PARAMSET_SIZE:
08801 *((SQLULEN *) val) = s->paramset_size;
08802 return SQL_SUCCESS;
08803 case SQL_ATTR_ROW_BIND_TYPE:
08804 *(SQLULEN *) val = s->bind_type;
08805 return SQL_SUCCESS;
08806 case SQL_ATTR_ROW_BIND_OFFSET_PTR:
08807 *((SQLULEN **) val) = s->bind_offs;
08808 return SQL_SUCCESS;
08809 case SQL_ATTR_MAX_ROWS:
08810 *((SQLULEN *) val) = s->max_rows;
08811 case SQL_ATTR_MAX_LENGTH:
08812 *((SQLINTEGER *) val) = 1000000000;
08813 return SQL_SUCCESS;
08814 #ifdef SQL_ATTR_METADATA_ID
08815 case SQL_ATTR_METADATA_ID:
08816 *((SQLULEN *) val) = SQL_FALSE;
08817 return SQL_SUCCESS;
08818 #endif
08819 }
08820 return drvunimplstmt(stmt);
08821 }
08822
08823 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
08824
08834 SQLRETURN SQL_API
08835 SQLGetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
08836 SQLINTEGER bufmax, SQLINTEGER *buflen)
08837 {
08838 SQLRETURN ret;
08839
08840 HSTMT_LOCK(stmt);
08841 ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
08842 HSTMT_UNLOCK(stmt);
08843 return ret;
08844 }
08845 #endif
08846
08847 #ifdef WINTERFACE
08848
08858 SQLRETURN SQL_API
08859 SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
08860 SQLINTEGER bufmax, SQLINTEGER *buflen)
08861 {
08862 SQLRETURN ret;
08863
08864 HSTMT_LOCK(stmt);
08865 ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
08866 HSTMT_UNLOCK(stmt);
08867 return ret;
08868 }
08869 #endif
08870
08880 static SQLRETURN
08881 drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
08882 SQLINTEGER buflen)
08883 {
08884 STMT *s = (STMT *) stmt;
08885 #if defined(SQL_BIGINT) && defined(__WORDSIZE) && (__WORDSIZE == 64)
08886 SQLBIGINT uval;
08887
08888 uval = (SQLBIGINT) val;
08889 #else
08890 SQLULEN uval;
08891
08892 uval = (SQLULEN) val;
08893 #endif
08894 switch (attr) {
08895 case SQL_ATTR_CURSOR_TYPE:
08896 if (val == (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY) {
08897 s->curtype = SQL_CURSOR_FORWARD_ONLY;
08898 } else {
08899 s->curtype = SQL_CURSOR_STATIC;
08900 }
08901 if (val != (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY &&
08902 val != (SQLPOINTER) SQL_CURSOR_STATIC) {
08903 goto e01s02;
08904 }
08905 return SQL_SUCCESS;
08906 case SQL_ATTR_CURSOR_SCROLLABLE:
08907 if (val == (SQLPOINTER) SQL_NONSCROLLABLE) {
08908 s->curtype = SQL_CURSOR_FORWARD_ONLY;
08909 } else {
08910 s->curtype = SQL_CURSOR_STATIC;
08911 }
08912 return SQL_SUCCESS;
08913 case SQL_ATTR_ASYNC_ENABLE:
08914 if (val != (SQLPOINTER) SQL_ASYNC_ENABLE_OFF) {
08915 e01s02:
08916 setstat(s, -1, "option value changed", "01S02");
08917 return SQL_SUCCESS_WITH_INFO;
08918 }
08919 return SQL_SUCCESS;
08920 case SQL_CONCURRENCY:
08921 if (val != (SQLPOINTER) SQL_CONCUR_LOCK) {
08922 goto e01s02;
08923 }
08924 return SQL_SUCCESS;
08925 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
08926 case SQL_ATTR_CURSOR_SENSITIVITY:
08927 if (val != (SQLPOINTER) SQL_UNSPECIFIED) {
08928 goto e01s02;
08929 }
08930 return SQL_SUCCESS;
08931 #endif
08932 case SQL_ATTR_QUERY_TIMEOUT:
08933 return SQL_SUCCESS;
08934 case SQL_ATTR_RETRIEVE_DATA:
08935 if (val != (SQLPOINTER) SQL_RD_ON &&
08936 val != (SQLPOINTER) SQL_RD_OFF) {
08937 goto e01s02;
08938 }
08939 s->retr_data = uval;
08940 return SQL_SUCCESS;
08941 case SQL_ROWSET_SIZE:
08942 case SQL_ATTR_ROW_ARRAY_SIZE:
08943 if (uval < 1) {
08944 setstat(s, -1, "invalid rowset size", "HY000");
08945 return SQL_ERROR;
08946 } else {
08947 SQLUSMALLINT *rst = &s->row_status1;
08948
08949 if (uval > 1) {
08950 rst = xmalloc(sizeof (SQLUSMALLINT) * uval);
08951 if (!rst) {
08952 return nomem(s);
08953 }
08954 }
08955 if (s->row_status0 != &s->row_status1) {
08956 freep(&s->row_status0);
08957 }
08958 s->row_status0 = rst;
08959 s->rowset_size = uval;
08960 }
08961 return SQL_SUCCESS;
08962 case SQL_ATTR_ROW_STATUS_PTR:
08963 s->row_status = (SQLUSMALLINT *) val;
08964 return SQL_SUCCESS;
08965 case SQL_ATTR_ROWS_FETCHED_PTR:
08966 s->row_count = (SQLULEN *) val;
08967 return SQL_SUCCESS;
08968 case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
08969 s->parm_bind_offs = (SQLULEN *) val;
08970 return SQL_SUCCESS;
08971 case SQL_ATTR_PARAM_BIND_TYPE:
08972 s->parm_bind_type = uval;
08973 return SQL_SUCCESS;
08974 case SQL_ATTR_PARAM_OPERATION_PTR:
08975 s->parm_oper = (SQLUSMALLINT *) val;
08976 return SQL_SUCCESS;
08977 case SQL_ATTR_PARAM_STATUS_PTR:
08978 s->parm_status = (SQLUSMALLINT *) val;
08979 return SQL_SUCCESS;
08980 case SQL_ATTR_PARAMS_PROCESSED_PTR:
08981 s->parm_proc = (SQLULEN *) val;
08982 return SQL_SUCCESS;
08983 case SQL_ATTR_PARAMSET_SIZE:
08984 if (uval < 1) {
08985 goto e01s02;
08986 }
08987 s->paramset_size = uval;
08988 s->paramset_count = 0;
08989 return SQL_SUCCESS;
08990 case SQL_ATTR_ROW_BIND_TYPE:
08991 s->bind_type = uval;
08992 return SQL_SUCCESS;
08993 case SQL_ATTR_ROW_BIND_OFFSET_PTR:
08994 s->bind_offs = (SQLULEN *) val;
08995 return SQL_SUCCESS;
08996 case SQL_ATTR_USE_BOOKMARKS:
08997 if (val != (SQLPOINTER) SQL_UB_OFF &&
08998 val != (SQLPOINTER) SQL_UB_ON) {
08999 goto e01s02;
09000 }
09001 s->bkmrk = val == (SQLPOINTER) SQL_UB_ON;
09002 return SQL_SUCCESS;
09003 case SQL_ATTR_MAX_ROWS:
09004 s->max_rows = uval;
09005 return SQL_SUCCESS;
09006 case SQL_ATTR_MAX_LENGTH:
09007 if (val != (SQLPOINTER) 1000000000) {
09008 goto e01s02;
09009 }
09010 return SQL_SUCCESS;
09011 #ifdef SQL_ATTR_METADATA_ID
09012 case SQL_ATTR_METADATA_ID:
09013 if (val != (SQLPOINTER) SQL_FALSE) {
09014 goto e01s02;
09015 }
09016 return SQL_SUCCESS;
09017 #endif
09018 }
09019 return drvunimplstmt(stmt);
09020 }
09021
09022 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
09023
09032 SQLRETURN SQL_API
09033 SQLSetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
09034 SQLINTEGER buflen)
09035 {
09036 SQLRETURN ret;
09037
09038 HSTMT_LOCK(stmt);
09039 ret = drvsetstmtattr(stmt, attr, val, buflen);
09040 HSTMT_UNLOCK(stmt);
09041 return ret;
09042 }
09043 #endif
09044
09045 #ifdef WINTERFACE
09046
09055 SQLRETURN SQL_API
09056 SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
09057 SQLINTEGER buflen)
09058 {
09059 SQLRETURN ret;
09060
09061 HSTMT_LOCK(stmt);
09062 ret = drvsetstmtattr(stmt, attr, val, buflen);
09063 HSTMT_UNLOCK(stmt);
09064 return ret;
09065 }
09066 #endif
09067
09076 static SQLRETURN
09077 drvgetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
09078 {
09079 STMT *s = (STMT *) stmt;
09080 SQLUINTEGER *ret = (SQLUINTEGER *) param;
09081
09082 switch (opt) {
09083 case SQL_QUERY_TIMEOUT:
09084 *ret = 0;
09085 return SQL_SUCCESS;
09086 case SQL_CURSOR_TYPE:
09087 *ret = s->curtype;
09088 return SQL_SUCCESS;
09089 case SQL_ROW_NUMBER:
09090 if (s->s3stmt) {
09091 *ret = (s->s3stmt_rownum < 0) ?
09092 SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
09093 } else {
09094 *ret = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
09095 }
09096 return SQL_SUCCESS;
09097 case SQL_ASYNC_ENABLE:
09098 *ret = SQL_ASYNC_ENABLE_OFF;
09099 return SQL_SUCCESS;
09100 case SQL_CONCURRENCY:
09101 *ret = SQL_CONCUR_LOCK;
09102 return SQL_SUCCESS;
09103 case SQL_ATTR_RETRIEVE_DATA:
09104 *ret = s->retr_data;
09105 return SQL_SUCCESS;
09106 case SQL_ROWSET_SIZE:
09107 case SQL_ATTR_ROW_ARRAY_SIZE:
09108 *ret = s->rowset_size;
09109 return SQL_SUCCESS;
09110 case SQL_ATTR_MAX_ROWS:
09111 *ret = s->max_rows;
09112 return SQL_SUCCESS;
09113 case SQL_ATTR_MAX_LENGTH:
09114 *ret = 1000000000;
09115 return SQL_SUCCESS;
09116 }
09117 return drvunimplstmt(stmt);
09118 }
09119
09128 SQLRETURN SQL_API
09129 SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
09130 {
09131 SQLRETURN ret;
09132
09133 HSTMT_LOCK(stmt);
09134 ret = drvgetstmtoption(stmt, opt, param);
09135 HSTMT_UNLOCK(stmt);
09136 return ret;
09137 }
09138
09139 #ifdef WINTERFACE
09140
09148 SQLRETURN SQL_API
09149 SQLGetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
09150 {
09151 SQLRETURN ret;
09152
09153 HSTMT_LOCK(stmt);
09154 ret = drvgetstmtoption(stmt, opt, param);
09155 HSTMT_UNLOCK(stmt);
09156 return ret;
09157 }
09158 #endif
09159
09168 static SQLRETURN
09169 drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
09170 {
09171 STMT *s = (STMT *) stmt;
09172
09173 switch (opt) {
09174 case SQL_CURSOR_TYPE:
09175 if (param == SQL_CURSOR_FORWARD_ONLY) {
09176 s->curtype = param;
09177 } else {
09178 s->curtype = SQL_CURSOR_STATIC;
09179 }
09180 if (param != SQL_CURSOR_FORWARD_ONLY &&
09181 param != SQL_CURSOR_STATIC) {
09182 goto e01s02;
09183 }
09184 return SQL_SUCCESS;
09185 case SQL_ASYNC_ENABLE:
09186 if (param != SQL_ASYNC_ENABLE_OFF) {
09187 goto e01s02;
09188 }
09189 return SQL_SUCCESS;
09190 case SQL_CONCURRENCY:
09191 if (param != SQL_CONCUR_LOCK) {
09192 goto e01s02;
09193 }
09194 return SQL_SUCCESS;
09195 case SQL_QUERY_TIMEOUT:
09196 return SQL_SUCCESS;
09197 case SQL_RETRIEVE_DATA:
09198 if (param != SQL_RD_ON && param != SQL_RD_OFF) {
09199 e01s02:
09200 setstat(s, -1, "option value changed", "01S02");
09201 return SQL_SUCCESS_WITH_INFO;
09202 }
09203 s->retr_data = (int) param;
09204 return SQL_SUCCESS;
09205 case SQL_ROWSET_SIZE:
09206 case SQL_ATTR_ROW_ARRAY_SIZE:
09207 if (param < 1) {
09208 setstat(s, -1, "invalid rowset size", "HY000");
09209 return SQL_ERROR;
09210 } else {
09211 SQLUSMALLINT *rst = &s->row_status1;
09212
09213 if (param > 1) {
09214 rst = xmalloc(sizeof (SQLUSMALLINT) * param);
09215 if (!rst) {
09216 return nomem(s);
09217 }
09218 }
09219 if (s->row_status0 != &s->row_status1) {
09220 freep(&s->row_status0);
09221 }
09222 s->row_status0 = rst;
09223 s->rowset_size = param;
09224 }
09225 return SQL_SUCCESS;
09226 case SQL_ATTR_MAX_ROWS:
09227 s->max_rows = param;
09228 return SQL_SUCCESS;
09229 case SQL_ATTR_MAX_LENGTH:
09230 if (param != 1000000000) {
09231 goto e01s02;
09232 }
09233 return SQL_SUCCESS;
09234 }
09235 return drvunimplstmt(stmt);
09236 }
09237
09246 SQLRETURN SQL_API
09247 SQLSetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt,
09248 SETSTMTOPTION_LAST_ARG_TYPE param)
09249 {
09250 SQLRETURN ret;
09251
09252 HSTMT_LOCK(stmt);
09253 ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
09254 HSTMT_UNLOCK(stmt);
09255 return ret;
09256 }
09257
09258 #ifdef WINTERFACE
09259
09267 SQLRETURN SQL_API
09268 SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt,
09269 SETSTMTOPTION_LAST_ARG_TYPE param)
09270 {
09271 SQLRETURN ret;
09272
09273 HSTMT_LOCK(stmt);
09274 ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
09275 HSTMT_UNLOCK(stmt);
09276 return ret;
09277 }
09278 #endif
09279
09289 static SQLRETURN
09290 drvsetpos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
09291 {
09292 STMT *s = (STMT *) stmt;
09293 int rowp;
09294
09295 if (op != SQL_POSITION) {
09296 return drvunimplstmt(stmt);
09297 }
09298 rowp = s->rowp + row - 1;
09299 if (!s->rows || row <= 0 || rowp < -1 || rowp >= s->nrows) {
09300 setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
09301 return SQL_ERROR;
09302 }
09303 s->rowp = rowp;
09304 return SQL_SUCCESS;
09305 }
09306
09316 SQLRETURN SQL_API
09317 SQLSetPos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
09318 {
09319 SQLRETURN ret;
09320
09321 HSTMT_LOCK(stmt);
09322 ret = drvsetpos(stmt, row, op, lock);
09323 HSTMT_UNLOCK(stmt);
09324 return ret;
09325 }
09326
09331 SQLRETURN SQL_API
09332 SQLSetScrollOptions(SQLHSTMT stmt, SQLUSMALLINT concur, SQLLEN rowkeyset,
09333 SQLUSMALLINT rowset)
09334 {
09335 SQLRETURN ret;
09336
09337 HSTMT_LOCK(stmt);
09338 ret = drvunimplstmt(stmt);
09339 HSTMT_UNLOCK(stmt);
09340 return ret;
09341 }
09342
09343 #define strmak(dst, src, max, lenp) { \
09344 int len = strlen(src); \
09345 int cnt = min(len + 1, max); \
09346 strncpy(dst, src, cnt); \
09347 *lenp = (cnt > len) ? len : cnt; \
09348 }
09349
09360 static SQLRETURN
09361 drvgetinfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
09362 SQLSMALLINT *valLen)
09363 {
09364 DBC *d;
09365 char dummyc[16];
09366 SQLSMALLINT dummy;
09367 #if defined(_WIN32) || defined(_WIN64)
09368 char pathbuf[301], *drvname;
09369 #else
09370 static char drvname[] = "sqlite3odbc.so";
09371 #endif
09372
09373 if (dbc == SQL_NULL_HDBC) {
09374 return SQL_INVALID_HANDLE;
09375 }
09376 d = (DBC *) dbc;
09377 if (valMax) {
09378 valMax--;
09379 }
09380 if (!valLen) {
09381 valLen = &dummy;
09382 }
09383 if (!val) {
09384 val = dummyc;
09385 valMax = sizeof (dummyc) - 1;
09386 }
09387 switch (type) {
09388 case SQL_MAX_USER_NAME_LEN:
09389 *((SQLSMALLINT *) val) = 16;
09390 *valLen = sizeof (SQLSMALLINT);
09391 break;
09392 case SQL_USER_NAME:
09393 strmak(val, "", valMax, valLen);
09394 break;
09395 case SQL_DRIVER_ODBC_VER:
09396 #if 0
09397 strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
09398 #else
09399 strmak(val, "03.00", valMax, valLen);
09400 #endif
09401 break;
09402 case SQL_ACTIVE_CONNECTIONS:
09403 case SQL_ACTIVE_STATEMENTS:
09404 *((SQLSMALLINT *) val) = 0;
09405 *valLen = sizeof (SQLSMALLINT);
09406 break;
09407 #ifdef SQL_ASYNC_MODE
09408 case SQL_ASYNC_MODE:
09409 *((SQLUINTEGER *) val) = SQL_AM_NONE;
09410 *valLen = sizeof (SQLUINTEGER);
09411 break;
09412 #endif
09413 #ifdef SQL_CREATE_TABLE
09414 case SQL_CREATE_TABLE:
09415 *((SQLUINTEGER *) val) = SQL_CT_CREATE_TABLE |
09416 SQL_CT_COLUMN_DEFAULT |
09417 SQL_CT_COLUMN_CONSTRAINT |
09418 SQL_CT_CONSTRAINT_NON_DEFERRABLE;
09419 *valLen = sizeof (SQLUINTEGER);
09420 break;
09421 #endif
09422 #ifdef SQL_CREATE_VIEW
09423 case SQL_CREATE_VIEW:
09424 *((SQLUINTEGER *) val) = SQL_CV_CREATE_VIEW;
09425 *valLen = sizeof (SQLUINTEGER);
09426 break;
09427 #endif
09428 #ifdef SQL_DDL_INDEX
09429 case SQL_DDL_INDEX:
09430 *((SQLUINTEGER *) val) = SQL_DI_CREATE_INDEX | SQL_DI_DROP_INDEX;
09431 *valLen = sizeof (SQLUINTEGER);
09432 break;
09433 #endif
09434 #ifdef SQL_DROP_TABLE
09435 case SQL_DROP_TABLE:
09436 *((SQLUINTEGER *) val) = SQL_DT_DROP_TABLE;
09437 *valLen = sizeof (SQLUINTEGER);
09438 break;
09439 #endif
09440 #ifdef SQL_DROP_VIEW
09441 case SQL_DROP_VIEW:
09442 *((SQLUINTEGER *) val) = SQL_DV_DROP_VIEW;
09443 *valLen = sizeof (SQLUINTEGER);
09444 break;
09445 #endif
09446 #ifdef SQL_INDEX_KEYWORDS
09447 case SQL_INDEX_KEYWORDS:
09448 *((SQLUINTEGER *) val) = SQL_IK_ALL;
09449 *valLen = sizeof (SQLUINTEGER);
09450 break;
09451 #endif
09452 case SQL_DATA_SOURCE_NAME:
09453 strmak(val, d->dsn ? d->dsn : "", valMax, valLen);
09454 break;
09455 case SQL_DRIVER_NAME:
09456 #if defined(_WIN32) || defined(_WIN64)
09457 GetModuleFileName(hModule, pathbuf, sizeof (pathbuf));
09458 drvname = strrchr(pathbuf, '\\');
09459 if (drvname == NULL) {
09460 drvname = strrchr(pathbuf, '/');
09461 }
09462 if (drvname == NULL) {
09463 drvname = pathbuf;
09464 } else {
09465 drvname++;
09466 }
09467 #endif
09468 strmak(val, drvname, valMax, valLen);
09469 break;
09470 case SQL_DRIVER_VER:
09471 strmak(val, DRIVER_VER_INFO, valMax, valLen);
09472 break;
09473 case SQL_FETCH_DIRECTION:
09474 *((SQLUINTEGER *) val) = SQL_FD_FETCH_NEXT | SQL_FD_FETCH_FIRST |
09475 SQL_FD_FETCH_LAST | SQL_FD_FETCH_PRIOR | SQL_FD_FETCH_ABSOLUTE;
09476 *valLen = sizeof (SQLUINTEGER);
09477 break;
09478 case SQL_ODBC_VER:
09479 strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
09480 break;
09481 case SQL_ODBC_SAG_CLI_CONFORMANCE:
09482 *((SQLSMALLINT *) val) = SQL_OSCC_NOT_COMPLIANT;
09483 *valLen = sizeof (SQLSMALLINT);
09484 break;
09485 case SQL_STANDARD_CLI_CONFORMANCE:
09486 *((SQLUINTEGER *) val) = SQL_SCC_XOPEN_CLI_VERSION1;
09487 *valLen = sizeof (SQLUINTEGER);
09488 break;
09489 case SQL_SERVER_NAME:
09490 case SQL_DATABASE_NAME:
09491 strmak(val, d->dbname ? d->dbname : "", valMax, valLen);
09492 break;
09493 case SQL_SEARCH_PATTERN_ESCAPE:
09494 strmak(val, "\\", valMax, valLen);
09495 break;
09496 case SQL_ODBC_SQL_CONFORMANCE:
09497 *((SQLSMALLINT *) val) = SQL_OSC_MINIMUM;
09498 *valLen = sizeof (SQLSMALLINT);
09499 break;
09500 case SQL_ODBC_API_CONFORMANCE:
09501 *((SQLSMALLINT *) val) = SQL_OAC_LEVEL1;
09502 *valLen = sizeof (SQLSMALLINT);
09503 break;
09504 case SQL_DBMS_NAME:
09505 strmak(val, "SQLite", valMax, valLen);
09506 break;
09507 case SQL_DBMS_VER:
09508 strmak(val, SQLITE_VERSION, valMax, valLen);
09509 break;
09510 case SQL_COLUMN_ALIAS:
09511 case SQL_NEED_LONG_DATA_LEN:
09512 strmak(val, "Y", valMax, valLen);
09513 break;
09514 case SQL_ROW_UPDATES:
09515 case SQL_ACCESSIBLE_PROCEDURES:
09516 case SQL_PROCEDURES:
09517 case SQL_EXPRESSIONS_IN_ORDERBY:
09518 case SQL_ODBC_SQL_OPT_IEF:
09519 case SQL_LIKE_ESCAPE_CLAUSE:
09520 case SQL_ORDER_BY_COLUMNS_IN_SELECT:
09521 case SQL_OUTER_JOINS:
09522 case SQL_ACCESSIBLE_TABLES:
09523 case SQL_MULT_RESULT_SETS:
09524 case SQL_MULTIPLE_ACTIVE_TXN:
09525 case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
09526 strmak(val, "N", valMax, valLen);
09527 break;
09528 #ifdef SQL_CATALOG_NAME
09529 case SQL_CATALOG_NAME:
09530 #if defined(_WIN32) || defined(_WIN64)
09531 strmak(val, d->xcelqrx ? "Y" : "N", valMax, valLen);
09532 #else
09533 strmak(val, "N", valMax, valLen);
09534 #endif
09535 break;
09536 #endif
09537 case SQL_DATA_SOURCE_READ_ONLY:
09538 strmak(val, "N", valMax, valLen);
09539 break;
09540 #ifdef SQL_OJ_CAPABILITIES
09541 case SQL_OJ_CAPABILITIES:
09542 *((SQLUINTEGER *) val) = 0;
09543 *valLen = sizeof (SQLUINTEGER);
09544 break;
09545 #endif
09546 #ifdef SQL_MAX_IDENTIFIER_LEN
09547 case SQL_MAX_IDENTIFIER_LEN:
09548 *((SQLUSMALLINT *) val) = 255;
09549 *valLen = sizeof (SQLUSMALLINT);
09550 break;
09551 #endif
09552 case SQL_CONCAT_NULL_BEHAVIOR:
09553 *((SQLSMALLINT *) val) = SQL_CB_NULL;
09554 *valLen = sizeof (SQLSMALLINT);
09555 break;
09556 case SQL_CURSOR_COMMIT_BEHAVIOR:
09557 case SQL_CURSOR_ROLLBACK_BEHAVIOR:
09558 *((SQLSMALLINT *) val) = SQL_CB_PRESERVE;
09559 *valLen = sizeof (SQLSMALLINT);
09560 break;
09561 #ifdef SQL_CURSOR_SENSITIVITY
09562 case SQL_CURSOR_SENSITIVITY:
09563 *((SQLUINTEGER *) val) = SQL_UNSPECIFIED;
09564 *valLen = sizeof (SQLUINTEGER);
09565 break;
09566 #endif
09567 case SQL_DEFAULT_TXN_ISOLATION:
09568 *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
09569 *valLen = sizeof (SQLUINTEGER);
09570 break;
09571 #ifdef SQL_DESCRIBE_PARAMETER
09572 case SQL_DESCRIBE_PARAMETER:
09573 strmak(val, "Y", valMax, valLen);
09574 break;
09575 #endif
09576 case SQL_TXN_ISOLATION_OPTION:
09577 *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
09578 *valLen = sizeof (SQLUINTEGER);
09579 break;
09580 case SQL_IDENTIFIER_CASE:
09581 *((SQLSMALLINT *) val) = SQL_IC_SENSITIVE;
09582 *valLen = sizeof (SQLSMALLINT);
09583 break;
09584 case SQL_IDENTIFIER_QUOTE_CHAR:
09585 strmak(val, "\"", valMax, valLen);
09586 break;
09587 case SQL_MAX_TABLE_NAME_LEN:
09588 case SQL_MAX_COLUMN_NAME_LEN:
09589 *((SQLSMALLINT *) val) = 255;
09590 *valLen = sizeof (SQLSMALLINT);
09591 break;
09592 case SQL_MAX_CURSOR_NAME_LEN:
09593 *((SQLSMALLINT *) val) = 255;
09594 *valLen = sizeof (SQLSMALLINT);
09595 break;
09596 case SQL_MAX_PROCEDURE_NAME_LEN:
09597 *((SQLSMALLINT *) val) = 0;
09598 break;
09599 case SQL_MAX_QUALIFIER_NAME_LEN:
09600 case SQL_MAX_OWNER_NAME_LEN:
09601 *((SQLSMALLINT *) val) = 255;
09602 break;
09603 case SQL_OWNER_TERM:
09604 strmak(val, "", valMax, valLen);
09605 break;
09606 case SQL_PROCEDURE_TERM:
09607 strmak(val, "PROCEDURE", valMax, valLen);
09608 break;
09609 case SQL_QUALIFIER_NAME_SEPARATOR:
09610 strmak(val, ".", valMax, valLen);
09611 break;
09612 case SQL_QUALIFIER_TERM:
09613 #if defined(_WIN32) || defined(_WIN64)
09614 strmak(val, d->xcelqrx ? "catalog" : "", valMax, valLen);
09615 #else
09616 strmak(val, "", valMax, valLen);
09617 #endif
09618 break;
09619 case SQL_QUALIFIER_USAGE:
09620 #if defined(_WIN32) || defined(_WIN64)
09621 *((SQLUINTEGER *) val) = d->xcelqrx ?
09622 (SQL_CU_DML_STATEMENTS | SQL_CU_INDEX_DEFINITION |
09623 SQL_CU_TABLE_DEFINITION) : 0;
09624 #else
09625 *((SQLUINTEGER *) val) = 0;
09626 #endif
09627 *valLen = sizeof (SQLUINTEGER);
09628 break;
09629 case SQL_SCROLL_CONCURRENCY:
09630 *((SQLUINTEGER *) val) = SQL_SCCO_LOCK;
09631 *valLen = sizeof (SQLUINTEGER);
09632 break;
09633 case SQL_SCROLL_OPTIONS:
09634 *((SQLUINTEGER *) val) = SQL_SO_STATIC | SQL_SO_FORWARD_ONLY;
09635 *valLen = sizeof (SQLUINTEGER);
09636 break;
09637 case SQL_TABLE_TERM:
09638 strmak(val, "TABLE", valMax, valLen);
09639 break;
09640 case SQL_TXN_CAPABLE:
09641 *((SQLSMALLINT *) val) = SQL_TC_ALL;
09642 *valLen = sizeof (SQLSMALLINT);
09643 break;
09644 case SQL_CONVERT_FUNCTIONS:
09645 *((SQLUINTEGER *) val) = 0;
09646 *valLen = sizeof (SQLUINTEGER);
09647 break;
09648 case SQL_SYSTEM_FUNCTIONS:
09649 case SQL_NUMERIC_FUNCTIONS:
09650 case SQL_STRING_FUNCTIONS:
09651 case SQL_TIMEDATE_FUNCTIONS:
09652 *((SQLUINTEGER *) val) = 0;
09653 *valLen = sizeof (SQLUINTEGER);
09654 break;
09655 case SQL_CONVERT_BIGINT:
09656 case SQL_CONVERT_BIT:
09657 case SQL_CONVERT_CHAR:
09658 case SQL_CONVERT_DATE:
09659 case SQL_CONVERT_DECIMAL:
09660 case SQL_CONVERT_DOUBLE:
09661 case SQL_CONVERT_FLOAT:
09662 case SQL_CONVERT_INTEGER:
09663 case SQL_CONVERT_LONGVARCHAR:
09664 case SQL_CONVERT_NUMERIC:
09665 case SQL_CONVERT_REAL:
09666 case SQL_CONVERT_SMALLINT:
09667 case SQL_CONVERT_TIME:
09668 case SQL_CONVERT_TIMESTAMP:
09669 case SQL_CONVERT_TINYINT:
09670 case SQL_CONVERT_VARCHAR:
09671 *((SQLUINTEGER *) val) =
09672 SQL_CVT_CHAR | SQL_CVT_NUMERIC | SQL_CVT_DECIMAL |
09673 SQL_CVT_INTEGER | SQL_CVT_SMALLINT | SQL_CVT_FLOAT | SQL_CVT_REAL |
09674 SQL_CVT_DOUBLE | SQL_CVT_VARCHAR | SQL_CVT_LONGVARCHAR |
09675 SQL_CVT_BIT | SQL_CVT_TINYINT | SQL_CVT_BIGINT |
09676 SQL_CVT_DATE | SQL_CVT_TIME | SQL_CVT_TIMESTAMP;
09677 *valLen = sizeof (SQLUINTEGER);
09678 break;
09679 case SQL_CONVERT_BINARY:
09680 case SQL_CONVERT_VARBINARY:
09681 case SQL_CONVERT_LONGVARBINARY:
09682 *((SQLUINTEGER *) val) = 0;
09683 *valLen = sizeof (SQLUINTEGER);
09684 break;
09685 case SQL_POSITIONED_STATEMENTS:
09686 case SQL_LOCK_TYPES:
09687 *((SQLUINTEGER *) val) = 0;
09688 *valLen = sizeof (SQLUINTEGER);
09689 break;
09690 case SQL_BOOKMARK_PERSISTENCE:
09691 *((SQLUINTEGER *) val) = SQL_BP_SCROLL;
09692 *valLen = sizeof (SQLUINTEGER);
09693 break;
09694 case SQL_UNION:
09695 *((SQLUINTEGER *) val) = SQL_U_UNION | SQL_U_UNION_ALL;
09696 *valLen = sizeof (SQLUINTEGER);
09697 break;
09698 case SQL_OWNER_USAGE:
09699 case SQL_SUBQUERIES:
09700 case SQL_TIMEDATE_ADD_INTERVALS:
09701 case SQL_TIMEDATE_DIFF_INTERVALS:
09702 *((SQLUINTEGER *) val) = 0;
09703 *valLen = sizeof (SQLUINTEGER);
09704 break;
09705 case SQL_QUOTED_IDENTIFIER_CASE:
09706 *((SQLUSMALLINT *) val) = SQL_IC_SENSITIVE;
09707 *valLen = sizeof (SQLUSMALLINT);
09708 break;
09709 case SQL_POS_OPERATIONS:
09710 *((SQLUINTEGER *) val) = 0;
09711 *valLen = sizeof (SQLUINTEGER);
09712 break;
09713 case SQL_ALTER_TABLE:
09714 *((SQLUINTEGER *) val) = 0;
09715 *valLen = sizeof (SQLUINTEGER);
09716 break;
09717 case SQL_CORRELATION_NAME:
09718 *((SQLSMALLINT *) val) = SQL_CN_DIFFERENT;
09719 *valLen = sizeof (SQLSMALLINT);
09720 break;
09721 case SQL_NON_NULLABLE_COLUMNS:
09722 *((SQLSMALLINT *) val) = SQL_NNC_NON_NULL;
09723 *valLen = sizeof (SQLSMALLINT);
09724 break;
09725 case SQL_NULL_COLLATION:
09726 *((SQLSMALLINT *) val) = SQL_NC_START;
09727 *valLen = sizeof (SQLSMALLINT);
09728 break;
09729 case SQL_MAX_COLUMNS_IN_GROUP_BY:
09730 case SQL_MAX_COLUMNS_IN_ORDER_BY:
09731 case SQL_MAX_COLUMNS_IN_SELECT:
09732 case SQL_MAX_COLUMNS_IN_TABLE:
09733 case SQL_MAX_ROW_SIZE:
09734 case SQL_MAX_TABLES_IN_SELECT:
09735 *((SQLSMALLINT *) val) = 0;
09736 *valLen = sizeof (SQLSMALLINT);
09737 break;
09738 case SQL_MAX_BINARY_LITERAL_LEN:
09739 case SQL_MAX_CHAR_LITERAL_LEN:
09740 *((SQLUINTEGER *) val) = 0;
09741 *valLen = sizeof (SQLUINTEGER);
09742 break;
09743 case SQL_MAX_COLUMNS_IN_INDEX:
09744 *((SQLSMALLINT *) val) = 0;
09745 *valLen = sizeof (SQLSMALLINT);
09746 break;
09747 case SQL_MAX_INDEX_SIZE:
09748 *((SQLUINTEGER *) val) = 0;
09749 *valLen = sizeof (SQLUINTEGER);
09750 break;
09751 #ifdef SQL_MAX_IDENTIFIER_LENGTH
09752 case SQL_MAX_IDENTIFIER_LENGTH:
09753 *((SQLUINTEGER *) val) = 255;
09754 *valLen = sizeof (SQLUINTEGER);
09755 break;
09756 #endif
09757 case SQL_MAX_STATEMENT_LEN:
09758 *((SQLUINTEGER *) val) = 16384;
09759 *valLen = sizeof (SQLUINTEGER);
09760 break;
09761 case SQL_QUALIFIER_LOCATION:
09762 *((SQLSMALLINT *) val) = SQL_QL_START;
09763 *valLen = sizeof (SQLSMALLINT);
09764 break;
09765 case SQL_GETDATA_EXTENSIONS:
09766 *((SQLUINTEGER *) val) =
09767 SQL_GD_ANY_COLUMN | SQL_GD_ANY_ORDER | SQL_GD_BOUND;
09768 *valLen = sizeof (SQLUINTEGER);
09769 break;
09770 case SQL_STATIC_SENSITIVITY:
09771 *((SQLUINTEGER *) val) = 0;
09772 *valLen = sizeof (SQLUINTEGER);
09773 break;
09774 case SQL_FILE_USAGE:
09775 #if defined(_WIN32) || defined(_WIN64)
09776 *((SQLSMALLINT *) val) =
09777 d->xcelqrx ? SQL_FILE_CATALOG : SQL_FILE_NOT_SUPPORTED;
09778 #else
09779 *((SQLSMALLINT *) val) = SQL_FILE_NOT_SUPPORTED;
09780 #endif
09781 *valLen = sizeof (SQLSMALLINT);
09782 break;
09783 case SQL_GROUP_BY:
09784 *((SQLSMALLINT *) val) = 0;
09785 *valLen = sizeof (SQLSMALLINT);
09786 break;
09787 case SQL_KEYWORDS:
09788 strmak(val, "CREATE,SELECT,DROP,DELETE,UPDATE,INSERT,"
09789 "INTO,VALUES,TABLE,INDEX,FROM,SET,WHERE,AND,CURRENT,OF",
09790 valMax, valLen);
09791 break;
09792 case SQL_SPECIAL_CHARACTERS:
09793 #ifdef SQL_COLLATION_SEQ
09794 case SQL_COLLATION_SEQ:
09795 #endif
09796 strmak(val, "", valMax, valLen);
09797 break;
09798 case SQL_BATCH_SUPPORT:
09799 case SQL_BATCH_ROW_COUNT:
09800 case SQL_PARAM_ARRAY_ROW_COUNTS:
09801 *((SQLUINTEGER *) val) = 0;
09802 *valLen = sizeof (SQLUINTEGER);
09803 break;
09804 case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1:
09805 *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_BOOKMARK;
09806 *valLen = sizeof (SQLUINTEGER);
09807 break;
09808 case SQL_STATIC_CURSOR_ATTRIBUTES1:
09809 *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE |
09810 SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK;
09811 *valLen = sizeof (SQLUINTEGER);
09812 break;
09813 case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2:
09814 case SQL_STATIC_CURSOR_ATTRIBUTES2:
09815 *((SQLUINTEGER *) val) = SQL_CA2_READ_ONLY_CONCURRENCY |
09816 SQL_CA2_LOCK_CONCURRENCY;
09817 *valLen = sizeof (SQLUINTEGER);
09818 break;
09819 case SQL_KEYSET_CURSOR_ATTRIBUTES1:
09820 case SQL_KEYSET_CURSOR_ATTRIBUTES2:
09821 case SQL_DYNAMIC_CURSOR_ATTRIBUTES1:
09822 case SQL_DYNAMIC_CURSOR_ATTRIBUTES2:
09823 *((SQLUINTEGER *) val) = 0;
09824 *valLen = sizeof (SQLUINTEGER);
09825 break;
09826 case SQL_ODBC_INTERFACE_CONFORMANCE:
09827 *((SQLUINTEGER *) val) = SQL_OIC_CORE;
09828 *valLen = sizeof (SQLUINTEGER);
09829 break;
09830 default:
09831 setstatd(d, -1, "unsupported info option %d",
09832 (*d->ov3) ? "HYC00" : "S1C00", type);
09833 return SQL_ERROR;
09834 }
09835 return SQL_SUCCESS;
09836 }
09837
09838 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
09839
09849 SQLRETURN SQL_API
09850 SQLGetInfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
09851 SQLSMALLINT *valLen)
09852 {
09853 SQLRETURN ret;
09854
09855 HDBC_LOCK(dbc);
09856 ret = drvgetinfo(dbc, type, val, valMax, valLen);
09857 HDBC_UNLOCK(dbc);
09858 return ret;
09859 }
09860 #endif
09861
09862 #ifdef WINTERFACE
09863
09873 SQLRETURN SQL_API
09874 SQLGetInfoW(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
09875 SQLSMALLINT *valLen)
09876 {
09877 SQLRETURN ret;
09878 SQLSMALLINT len = 0;
09879
09880 HDBC_LOCK(dbc);
09881 ret = drvgetinfo(dbc, type, val, valMax, &len);
09882 HDBC_UNLOCK(dbc);
09883 if (ret == SQL_SUCCESS) {
09884 SQLWCHAR *v = NULL;
09885
09886 switch (type) {
09887 case SQL_USER_NAME:
09888 case SQL_DRIVER_ODBC_VER:
09889 case SQL_DATA_SOURCE_NAME:
09890 case SQL_DRIVER_NAME:
09891 case SQL_DRIVER_VER:
09892 case SQL_ODBC_VER:
09893 case SQL_SERVER_NAME:
09894 case SQL_DATABASE_NAME:
09895 case SQL_SEARCH_PATTERN_ESCAPE:
09896 case SQL_DBMS_NAME:
09897 case SQL_DBMS_VER:
09898 case SQL_NEED_LONG_DATA_LEN:
09899 case SQL_ROW_UPDATES:
09900 case SQL_ACCESSIBLE_PROCEDURES:
09901 case SQL_PROCEDURES:
09902 case SQL_EXPRESSIONS_IN_ORDERBY:
09903 case SQL_ODBC_SQL_OPT_IEF:
09904 case SQL_LIKE_ESCAPE_CLAUSE:
09905 case SQL_ORDER_BY_COLUMNS_IN_SELECT:
09906 case SQL_OUTER_JOINS:
09907 case SQL_COLUMN_ALIAS:
09908 case SQL_ACCESSIBLE_TABLES:
09909 case SQL_MULT_RESULT_SETS:
09910 case SQL_MULTIPLE_ACTIVE_TXN:
09911 case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
09912 case SQL_DATA_SOURCE_READ_ONLY:
09913 #ifdef SQL_DESCRIBE_PARAMETER
09914 case SQL_DESCRIBE_PARAMETER:
09915 #endif
09916 case SQL_IDENTIFIER_QUOTE_CHAR:
09917 case SQL_OWNER_TERM:
09918 case SQL_PROCEDURE_TERM:
09919 case SQL_QUALIFIER_NAME_SEPARATOR:
09920 case SQL_QUALIFIER_TERM:
09921 case SQL_TABLE_TERM:
09922 case SQL_KEYWORDS:
09923 case SQL_SPECIAL_CHARACTERS:
09924 #ifdef SQL_CATALOG_NAME
09925 case SQL_CATALOG_NAME:
09926 #endif
09927 #ifdef SQL_COLLATION_SEQ
09928 case SQL_COLLATION_SEQ:
09929 #endif
09930 if (val) {
09931 if (len > 0) {
09932 v = uc_from_utf((SQLCHAR *) val, len);
09933 if (v) {
09934 int vmax = valMax / sizeof (SQLWCHAR);
09935
09936 uc_strncpy(val, v, vmax);
09937 v[len] = 0;
09938 len = min(vmax, uc_strlen(v));
09939 uc_free(v);
09940 len *= sizeof (SQLWCHAR);
09941 } else {
09942 len = 0;
09943 }
09944 }
09945 if (len <= 0) {
09946 len = 0;
09947 if (valMax >= sizeof (SQLWCHAR)) {
09948 *((SQLWCHAR *)val) = 0;
09949 }
09950 }
09951 } else {
09952 len *= sizeof (SQLWCHAR);
09953 }
09954 break;
09955 }
09956 if (valLen) {
09957 *valLen = len;
09958 }
09959 }
09960 return ret;
09961 }
09962 #endif
09963
09972 SQLRETURN SQL_API
09973 SQLGetFunctions(SQLHDBC dbc, SQLUSMALLINT func,
09974 SQLUSMALLINT *flags)
09975 {
09976 int i;
09977 SQLUSMALLINT exists[100];
09978
09979 if (dbc == SQL_NULL_HDBC) {
09980 return SQL_INVALID_HANDLE;
09981 }
09982 for (i = 0; i < array_size(exists); i++) {
09983 exists[i] = SQL_FALSE;
09984 }
09985 exists[SQL_API_SQLALLOCCONNECT] = SQL_TRUE;
09986 exists[SQL_API_SQLFETCH] = SQL_TRUE;
09987 exists[SQL_API_SQLALLOCENV] = SQL_TRUE;
09988 exists[SQL_API_SQLFREECONNECT] = SQL_TRUE;
09989 exists[SQL_API_SQLALLOCSTMT] = SQL_TRUE;
09990 exists[SQL_API_SQLFREEENV] = SQL_TRUE;
09991 exists[SQL_API_SQLBINDCOL] = SQL_TRUE;
09992 exists[SQL_API_SQLFREESTMT] = SQL_TRUE;
09993 exists[SQL_API_SQLCANCEL] = SQL_TRUE;
09994 exists[SQL_API_SQLGETCURSORNAME] = SQL_TRUE;
09995 exists[SQL_API_SQLCOLATTRIBUTES] = SQL_TRUE;
09996 exists[SQL_API_SQLNUMRESULTCOLS] = SQL_TRUE;
09997 exists[SQL_API_SQLCONNECT] = SQL_TRUE;
09998 exists[SQL_API_SQLPREPARE] = SQL_TRUE;
09999 exists[SQL_API_SQLDESCRIBECOL] = SQL_TRUE;
10000 exists[SQL_API_SQLROWCOUNT] = SQL_TRUE;
10001 exists[SQL_API_SQLDISCONNECT] = SQL_TRUE;
10002 exists[SQL_API_SQLSETCURSORNAME] = SQL_FALSE;
10003 exists[SQL_API_SQLERROR] = SQL_TRUE;
10004 exists[SQL_API_SQLSETPARAM] = SQL_TRUE;
10005 exists[SQL_API_SQLEXECDIRECT] = SQL_TRUE;
10006 exists[SQL_API_SQLTRANSACT] = SQL_TRUE;
10007 exists[SQL_API_SQLEXECUTE] = SQL_TRUE;
10008 exists[SQL_API_SQLBINDPARAMETER] = SQL_TRUE;
10009 exists[SQL_API_SQLGETTYPEINFO] = SQL_TRUE;
10010 exists[SQL_API_SQLCOLUMNS] = SQL_TRUE;
10011 exists[SQL_API_SQLPARAMDATA] = SQL_TRUE;
10012 exists[SQL_API_SQLDRIVERCONNECT] = SQL_TRUE;
10013 exists[SQL_API_SQLPUTDATA] = SQL_TRUE;
10014 exists[SQL_API_SQLGETCONNECTOPTION] = SQL_TRUE;
10015 exists[SQL_API_SQLSETCONNECTOPTION] = SQL_TRUE;
10016 exists[SQL_API_SQLGETDATA] = SQL_TRUE;
10017 exists[SQL_API_SQLSETSTMTOPTION] = SQL_TRUE;
10018 exists[SQL_API_SQLGETFUNCTIONS] = SQL_TRUE;
10019 exists[SQL_API_SQLSPECIALCOLUMNS] = SQL_TRUE;
10020 exists[SQL_API_SQLGETINFO] = SQL_TRUE;
10021 exists[SQL_API_SQLSTATISTICS] = SQL_TRUE;
10022 exists[SQL_API_SQLGETSTMTOPTION] = SQL_TRUE;
10023 exists[SQL_API_SQLTABLES] = SQL_TRUE;
10024 exists[SQL_API_SQLBROWSECONNECT] = SQL_FALSE;
10025 exists[SQL_API_SQLNUMPARAMS] = SQL_TRUE;
10026 exists[SQL_API_SQLCOLUMNPRIVILEGES] = SQL_FALSE;
10027 exists[SQL_API_SQLPARAMOPTIONS] = SQL_FALSE;
10028 exists[SQL_API_SQLDATASOURCES] = SQL_TRUE;
10029 exists[SQL_API_SQLPRIMARYKEYS] = SQL_TRUE;
10030 exists[SQL_API_SQLDESCRIBEPARAM] = SQL_TRUE;
10031 exists[SQL_API_SQLPROCEDURECOLUMNS] = SQL_TRUE;
10032 exists[SQL_API_SQLDRIVERS] = SQL_FALSE;
10033 exists[SQL_API_SQLPROCEDURES] = SQL_TRUE;
10034 exists[SQL_API_SQLEXTENDEDFETCH] = SQL_TRUE;
10035 exists[SQL_API_SQLSETPOS] = SQL_TRUE;
10036 exists[SQL_API_SQLFOREIGNKEYS] = SQL_TRUE;
10037 exists[SQL_API_SQLSETSCROLLOPTIONS] = SQL_TRUE;
10038 exists[SQL_API_SQLMORERESULTS] = SQL_TRUE;
10039 exists[SQL_API_SQLTABLEPRIVILEGES] = SQL_TRUE;
10040 exists[SQL_API_SQLNATIVESQL] = SQL_TRUE;
10041 if (func == SQL_API_ALL_FUNCTIONS) {
10042 memcpy(flags, exists, sizeof (exists));
10043 } else if (func == SQL_API_ODBC3_ALL_FUNCTIONS) {
10044 int i;
10045 #define SET_EXISTS(x) \
10046 flags[(x) >> 4] |= (1 << ((x) & 0xF))
10047 #define CLR_EXISTS(x) \
10048 flags[(x) >> 4] &= ~(1 << ((x) & 0xF))
10049
10050 memset(flags, 0,
10051 sizeof (SQLUSMALLINT) * SQL_API_ODBC3_ALL_FUNCTIONS_SIZE);
10052 for (i = 0; i < array_size(exists); i++) {
10053 if (exists[i]) {
10054 flags[i >> 4] |= (1 << (i & 0xF));
10055 }
10056 }
10057 SET_EXISTS(SQL_API_SQLALLOCHANDLE);
10058 SET_EXISTS(SQL_API_SQLFREEHANDLE);
10059 SET_EXISTS(SQL_API_SQLGETSTMTATTR);
10060 SET_EXISTS(SQL_API_SQLSETSTMTATTR);
10061 SET_EXISTS(SQL_API_SQLGETCONNECTATTR);
10062 SET_EXISTS(SQL_API_SQLSETCONNECTATTR);
10063 SET_EXISTS(SQL_API_SQLGETENVATTR);
10064 SET_EXISTS(SQL_API_SQLSETENVATTR);
10065 SET_EXISTS(SQL_API_SQLCLOSECURSOR);
10066 SET_EXISTS(SQL_API_SQLBINDPARAM);
10067 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
10068
10069
10070
10071
10072
10073 SET_EXISTS(SQL_API_SQLGETDIAGREC);
10074 #endif
10075 SET_EXISTS(SQL_API_SQLGETDIAGFIELD);
10076 SET_EXISTS(SQL_API_SQLFETCHSCROLL);
10077 SET_EXISTS(SQL_API_SQLENDTRAN);
10078 } else {
10079 if (func < array_size(exists)) {
10080 *flags = exists[func];
10081 } else {
10082 switch (func) {
10083 case SQL_API_SQLALLOCHANDLE:
10084 case SQL_API_SQLFREEHANDLE:
10085 case SQL_API_SQLGETSTMTATTR:
10086 case SQL_API_SQLSETSTMTATTR:
10087 case SQL_API_SQLGETCONNECTATTR:
10088 case SQL_API_SQLSETCONNECTATTR:
10089 case SQL_API_SQLGETENVATTR:
10090 case SQL_API_SQLSETENVATTR:
10091 case SQL_API_SQLCLOSECURSOR:
10092 case SQL_API_SQLBINDPARAM:
10093 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
10094
10095
10096
10097
10098
10099 case SQL_API_SQLGETDIAGREC:
10100 #endif
10101 case SQL_API_SQLGETDIAGFIELD:
10102 case SQL_API_SQLFETCHSCROLL:
10103 case SQL_API_SQLENDTRAN:
10104 *flags = SQL_TRUE;
10105 break;
10106 default:
10107 *flags = SQL_FALSE;
10108 }
10109 }
10110 }
10111 return SQL_SUCCESS;
10112 }
10113
10120 static SQLRETURN
10121 drvallocenv(SQLHENV *env)
10122 {
10123 ENV *e;
10124
10125 if (env == NULL) {
10126 return SQL_INVALID_HANDLE;
10127 }
10128 e = (ENV *) xmalloc(sizeof (ENV));
10129 if (e == NULL) {
10130 *env = SQL_NULL_HENV;
10131 return SQL_ERROR;
10132 }
10133 e->magic = ENV_MAGIC;
10134 e->ov3 = 0;
10135 #if defined(_WIN32) || defined(_WIN64)
10136 InitializeCriticalSection(&e->cs);
10137 e->owner = 0;
10138 #else
10139 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
10140 nvfs_init();
10141 #endif
10142 #endif
10143 e->dbcs = NULL;
10144 *env = (SQLHENV) e;
10145 return SQL_SUCCESS;
10146 }
10147
10154 SQLRETURN SQL_API
10155 SQLAllocEnv(SQLHENV *env)
10156 {
10157 return drvallocenv(env);
10158 }
10159
10166 static SQLRETURN
10167 drvfreeenv(SQLHENV env)
10168 {
10169 ENV *e;
10170
10171 if (env == SQL_NULL_HENV) {
10172 return SQL_INVALID_HANDLE;
10173 }
10174 e = (ENV *) env;
10175 if (e->magic != ENV_MAGIC) {
10176 return SQL_SUCCESS;
10177 }
10178 #if defined(_WIN32) || defined(_WIN64)
10179 EnterCriticalSection(&e->cs);
10180 e->owner = GetCurrentThreadId();
10181 #endif
10182 if (e->dbcs) {
10183 #if defined(_WIN32) || defined(_WIN64)
10184 LeaveCriticalSection(&e->cs);
10185 e->owner = 0;
10186 #endif
10187 return SQL_ERROR;
10188 }
10189 e->magic = DEAD_MAGIC;
10190 #if defined(_WIN32) || defined(_WIN64)
10191 e->owner = 0;
10192 LeaveCriticalSection(&e->cs);
10193 DeleteCriticalSection(&e->cs);
10194 #endif
10195 xfree(e);
10196 return SQL_SUCCESS;
10197 }
10198
10205 SQLRETURN SQL_API
10206 SQLFreeEnv(SQLHENV env)
10207 {
10208 return drvfreeenv(env);
10209 }
10210
10218 static SQLRETURN
10219 drvallocconnect(SQLHENV env, SQLHDBC *dbc)
10220 {
10221 DBC *d;
10222 ENV *e;
10223 const char *verstr;
10224 int maj = 0, min = 0, lev = 0;
10225
10226 if (dbc == NULL) {
10227 return SQL_ERROR;
10228 }
10229 d = (DBC *) xmalloc(sizeof (DBC));
10230 if (d == NULL) {
10231 *dbc = SQL_NULL_HDBC;
10232 return SQL_ERROR;
10233 }
10234 memset(d, 0, sizeof (DBC));
10235 d->curtype = SQL_CURSOR_STATIC;
10236 d->ov3 = &d->ov3val;
10237 verstr = sqlite3_libversion();
10238 sscanf(verstr, "%d.%d.%d", &maj, &min, &lev);
10239 d->version = verinfo(maj & 0xFF, min & 0xFF, lev & 0xFF);
10240 e = (ENV *) env;
10241 #if defined(_WIN32) || defined(_WIN64)
10242 if (e->magic == ENV_MAGIC) {
10243 EnterCriticalSection(&e->cs);
10244 e->owner = GetCurrentThreadId();
10245 }
10246 #endif
10247 if (e->magic == ENV_MAGIC) {
10248 DBC *n, *p;
10249
10250 d->env = e;
10251 d->ov3 = &e->ov3;
10252 p = NULL;
10253 n = e->dbcs;
10254 while (n) {
10255 p = n;
10256 n = n->next;
10257 }
10258 if (p) {
10259 p->next = d;
10260 } else {
10261 e->dbcs = d;
10262 }
10263 }
10264 #if defined(_WIN32) || defined(_WIN64)
10265 if (e->magic == ENV_MAGIC) {
10266 e->owner = 0;
10267 LeaveCriticalSection(&e->cs);
10268 }
10269 d->oemcp = 1;
10270 #endif
10271 d->autocommit = 1;
10272 d->magic = DBC_MAGIC;
10273 *dbc = (SQLHDBC) d;
10274 drvgetgpps(d);
10275 return SQL_SUCCESS;
10276 }
10277
10285 SQLRETURN SQL_API
10286 SQLAllocConnect(SQLHENV env, SQLHDBC *dbc)
10287 {
10288 return drvallocconnect(env, dbc);
10289 }
10290
10297 static SQLRETURN
10298 drvfreeconnect(SQLHDBC dbc)
10299 {
10300 DBC *d;
10301 ENV *e;
10302 SQLRETURN ret = SQL_ERROR;
10303
10304 if (dbc == SQL_NULL_HDBC) {
10305 return SQL_INVALID_HANDLE;
10306 }
10307 d = (DBC *) dbc;
10308 if (d->magic != DBC_MAGIC) {
10309 return SQL_INVALID_HANDLE;
10310 }
10311 e = d->env;
10312 if (e && e->magic == ENV_MAGIC) {
10313 #if defined(_WIN32) || defined(_WIN64)
10314 EnterCriticalSection(&e->cs);
10315 e->owner = GetCurrentThreadId();
10316 #endif
10317 } else {
10318 e = NULL;
10319 }
10320 if (d->sqlite) {
10321 setstatd(d, -1, "not disconnected", (*d->ov3) ? "HY000" : "S1000");
10322 goto done;
10323 }
10324 while (d->stmt) {
10325 freestmt((HSTMT) d->stmt);
10326 }
10327 if (e && e->magic == ENV_MAGIC) {
10328 DBC *n, *p;
10329
10330 p = NULL;
10331 n = e->dbcs;
10332 while (n) {
10333 if (n == d) {
10334 break;
10335 }
10336 p = n;
10337 n = n->next;
10338 }
10339 if (n) {
10340 if (p) {
10341 p->next = d->next;
10342 } else {
10343 e->dbcs = d->next;
10344 }
10345 }
10346 }
10347 drvrelgpps(d);
10348 d->magic = DEAD_MAGIC;
10349 if (d->trace) {
10350 fclose(d->trace);
10351 }
10352 xfree(d);
10353 ret = SQL_SUCCESS;
10354 done:
10355 #if defined(_WIN32) || defined(_WIN64)
10356 if (e) {
10357 e->owner = 0;
10358 LeaveCriticalSection(&e->cs);
10359 }
10360 #endif
10361 return ret;
10362 }
10363
10370 SQLRETURN SQL_API
10371 SQLFreeConnect(SQLHDBC dbc)
10372 {
10373 return drvfreeconnect(dbc);
10374 }
10375
10386 static SQLRETURN
10387 drvgetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
10388 SQLINTEGER bufmax, SQLINTEGER *buflen)
10389 {
10390 DBC *d;
10391 SQLINTEGER dummy;
10392
10393 if (dbc == SQL_NULL_HDBC) {
10394 return SQL_INVALID_HANDLE;
10395 }
10396 d = (DBC *) dbc;
10397 if (!val) {
10398 val = (SQLPOINTER) &dummy;
10399 }
10400 if (!buflen) {
10401 buflen = &dummy;
10402 }
10403 switch (attr) {
10404 case SQL_ATTR_CONNECTION_DEAD:
10405 *((SQLINTEGER *) val) = d->sqlite ? SQL_CD_FALSE : SQL_CD_TRUE;
10406 *buflen = sizeof (SQLINTEGER);
10407 break;
10408 case SQL_ATTR_ACCESS_MODE:
10409 *((SQLINTEGER *) val) = SQL_MODE_READ_WRITE;
10410 *buflen = sizeof (SQLINTEGER);
10411 break;
10412 case SQL_ATTR_AUTOCOMMIT:
10413 *((SQLINTEGER *) val) =
10414 d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
10415 *buflen = sizeof (SQLINTEGER);
10416 break;
10417 case SQL_ATTR_LOGIN_TIMEOUT:
10418 *((SQLINTEGER *) val) = 100;
10419 *buflen = sizeof (SQLINTEGER);
10420 break;
10421 case SQL_ATTR_ODBC_CURSORS:
10422 *((SQLINTEGER *) val) = SQL_CUR_USE_DRIVER;
10423 *buflen = sizeof (SQLINTEGER);
10424 break;
10425 case SQL_ATTR_PACKET_SIZE:
10426 *((SQLINTEGER *) val) = 16384;
10427 *buflen = sizeof (SQLINTEGER);
10428 break;
10429 case SQL_ATTR_TXN_ISOLATION:
10430 *((SQLINTEGER *) val) = SQL_TXN_SERIALIZABLE;
10431 *buflen = sizeof (SQLINTEGER);
10432 break;
10433 case SQL_ATTR_TRACEFILE:
10434 case SQL_ATTR_TRANSLATE_LIB:
10435 case SQL_ATTR_CURRENT_CATALOG:
10436 *((SQLCHAR *) val) = 0;
10437 *buflen = 0;
10438 break;
10439 case SQL_ATTR_TRACE:
10440 case SQL_ATTR_QUIET_MODE:
10441 case SQL_ATTR_TRANSLATE_OPTION:
10442 case SQL_ATTR_KEYSET_SIZE:
10443 case SQL_ATTR_QUERY_TIMEOUT:
10444 *((SQLINTEGER *) val) = 0;
10445 *buflen = sizeof (SQLINTEGER);
10446 break;
10447 case SQL_ATTR_PARAM_BIND_TYPE:
10448 *((SQLULEN *) val) = SQL_PARAM_BIND_BY_COLUMN;
10449 *buflen = sizeof (SQLUINTEGER);
10450 break;
10451 case SQL_ATTR_ROW_BIND_TYPE:
10452 *((SQLULEN *) val) = SQL_BIND_BY_COLUMN;
10453 *buflen = sizeof (SQLULEN);
10454 break;
10455 case SQL_ATTR_USE_BOOKMARKS:
10456 *((SQLINTEGER *) val) = SQL_UB_OFF;
10457 *buflen = sizeof (SQLINTEGER);
10458 break;
10459 case SQL_ATTR_ASYNC_ENABLE:
10460 *((SQLINTEGER *) val) = SQL_ASYNC_ENABLE_OFF;
10461 *buflen = sizeof (SQLINTEGER);
10462 break;
10463 case SQL_ATTR_NOSCAN:
10464 *((SQLINTEGER *) val) = SQL_NOSCAN_ON;
10465 *buflen = sizeof (SQLINTEGER);
10466 break;
10467 case SQL_ATTR_CONCURRENCY:
10468 *((SQLINTEGER *) val) = SQL_CONCUR_LOCK;
10469 *buflen = sizeof (SQLINTEGER);
10470 break;
10471 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
10472 case SQL_ATTR_CURSOR_SENSITIVITY:
10473 *((SQLINTEGER *) val) = SQL_UNSPECIFIED;
10474 *buflen = sizeof (SQLINTEGER);
10475 break;
10476 #endif
10477 case SQL_ATTR_SIMULATE_CURSOR:
10478 *((SQLINTEGER *) val) = SQL_SC_NON_UNIQUE;
10479 *buflen = sizeof (SQLINTEGER);
10480 break;
10481 case SQL_ATTR_MAX_ROWS:
10482 *((SQLINTEGER *) val) = 0;
10483 *buflen = sizeof (SQLINTEGER);
10484 case SQL_ATTR_MAX_LENGTH:
10485 *((SQLINTEGER *) val) = 1000000000;
10486 *buflen = sizeof (SQLINTEGER);
10487 break;
10488 case SQL_ATTR_CURSOR_TYPE:
10489 *((SQLINTEGER *) val) = d->curtype;
10490 *buflen = sizeof (SQLINTEGER);
10491 break;
10492 case SQL_ATTR_RETRIEVE_DATA:
10493 *((SQLINTEGER *) val) = SQL_RD_ON;
10494 *buflen = sizeof (SQLINTEGER);
10495 break;
10496 #ifdef SQL_ATTR_METADATA_ID
10497 case SQL_ATTR_METADATA_ID:
10498 *((SQLULEN *) val) = SQL_FALSE;
10499 return SQL_SUCCESS;
10500 #endif
10501 default:
10502 *((SQLINTEGER *) val) = 0;
10503 *buflen = sizeof (SQLINTEGER);
10504 setstatd(d, -1, "unsupported connect attribute %d",
10505 (*d->ov3) ? "HYC00" : "S1C00", (int) attr);
10506 return SQL_ERROR;
10507 }
10508 return SQL_SUCCESS;
10509 }
10510
10511 #ifndef WINTERFACE
10512
10522 SQLRETURN SQL_API
10523 SQLGetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
10524 SQLINTEGER bufmax, SQLINTEGER *buflen)
10525 {
10526 SQLRETURN ret;
10527
10528 HDBC_LOCK(dbc);
10529 ret = drvgetconnectattr(dbc, attr, val, bufmax, buflen);
10530 HDBC_UNLOCK(dbc);
10531 return ret;
10532 }
10533 #endif
10534
10535 #ifdef WINTERFACE
10536
10546 SQLRETURN SQL_API
10547 SQLGetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
10548 SQLINTEGER bufmax, SQLINTEGER *buflen)
10549 {
10550 SQLRETURN ret;
10551
10552 HDBC_LOCK(dbc);
10553 ret = drvgetconnectattr(dbc, attr, val, bufmax, buflen);
10554 if (SQL_SUCCEEDED(ret)) {
10555 switch (attr) {
10556 case SQL_ATTR_TRACEFILE:
10557 case SQL_ATTR_CURRENT_CATALOG:
10558 case SQL_ATTR_TRANSLATE_LIB:
10559 if (val && bufmax >= sizeof (SQLWCHAR)) {
10560 *(SQLWCHAR *) val = 0;
10561 }
10562 break;
10563 }
10564 }
10565 HDBC_UNLOCK(dbc);
10566 return ret;
10567 }
10568 #endif
10569
10579 static SQLRETURN
10580 drvsetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
10581 SQLINTEGER len)
10582 {
10583 DBC *d;
10584
10585 if (dbc == SQL_NULL_HDBC) {
10586 return SQL_INVALID_HANDLE;
10587 }
10588 d = (DBC *) dbc;
10589 switch (attr) {
10590 case SQL_AUTOCOMMIT:
10591 d->autocommit = val == (SQLPOINTER) SQL_AUTOCOMMIT_ON;
10592 if (d->autocommit && d->intrans) {
10593 return endtran(d, SQL_COMMIT, 1);
10594 } else if (!d->autocommit) {
10595 s3stmt_end(d->cur_s3stmt);
10596 }
10597 return SQL_SUCCESS;
10598 #ifdef SQL_ATTR_METADATA_ID
10599 case SQL_ATTR_METADATA_ID:
10600 if (val == (SQLPOINTER) SQL_FALSE) {
10601 return SQL_SUCCESS;
10602 }
10603
10604 #endif
10605 default:
10606 setstatd(d, -1, "option value changed", "01S02");
10607 return SQL_SUCCESS_WITH_INFO;
10608 }
10609 return SQL_SUCCESS;
10610 }
10611
10612 #ifndef WINTERFACE
10613
10622 SQLRETURN SQL_API
10623 SQLSetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
10624 SQLINTEGER len)
10625 {
10626 SQLRETURN ret;
10627
10628 HDBC_LOCK(dbc);
10629 ret = drvsetconnectattr(dbc, attr, val, len);
10630 HDBC_UNLOCK(dbc);
10631 return ret;
10632 }
10633 #endif
10634
10635 #ifdef WINTERFACE
10636
10645 SQLRETURN SQL_API
10646 SQLSetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
10647 SQLINTEGER len)
10648 {
10649 SQLRETURN ret;
10650
10651 HDBC_LOCK(dbc);
10652 ret = drvsetconnectattr(dbc, attr, val, len);
10653 HDBC_UNLOCK(dbc);
10654 return ret;
10655 }
10656 #endif
10657
10666 static SQLRETURN
10667 drvgetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
10668 {
10669 DBC *d;
10670 SQLINTEGER dummy;
10671
10672 if (dbc == SQL_NULL_HDBC) {
10673 return SQL_INVALID_HANDLE;
10674 }
10675 d = (DBC *) dbc;
10676 if (!param) {
10677 param = (SQLPOINTER) &dummy;
10678 }
10679 switch (opt) {
10680 case SQL_ACCESS_MODE:
10681 *((SQLINTEGER *) param) = SQL_MODE_READ_WRITE;
10682 break;
10683 case SQL_AUTOCOMMIT:
10684 *((SQLINTEGER *) param) =
10685 d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
10686 break;
10687 case SQL_LOGIN_TIMEOUT:
10688 *((SQLINTEGER *) param) = 100;
10689 break;
10690 case SQL_ODBC_CURSORS:
10691 *((SQLINTEGER *) param) = SQL_CUR_USE_DRIVER;
10692 break;
10693 case SQL_PACKET_SIZE:
10694 *((SQLINTEGER *) param) = 16384;
10695 break;
10696 case SQL_TXN_ISOLATION:
10697 *((SQLINTEGER *) param) = SQL_TXN_SERIALIZABLE;
10698 break;
10699 case SQL_OPT_TRACE:
10700 case SQL_OPT_TRACEFILE:
10701 case SQL_QUIET_MODE:
10702 case SQL_TRANSLATE_DLL:
10703 case SQL_TRANSLATE_OPTION:
10704 case SQL_KEYSET_SIZE:
10705 case SQL_QUERY_TIMEOUT:
10706 case SQL_BIND_TYPE:
10707 case SQL_CURRENT_QUALIFIER:
10708 *((SQLINTEGER *) param) = 0;
10709 break;
10710 case SQL_USE_BOOKMARKS:
10711 *((SQLINTEGER *) param) = SQL_UB_OFF;
10712 break;
10713 case SQL_ASYNC_ENABLE:
10714 *((SQLINTEGER *) param) = SQL_ASYNC_ENABLE_OFF;
10715 break;
10716 case SQL_NOSCAN:
10717 *((SQLINTEGER *) param) = SQL_NOSCAN_ON;
10718 break;
10719 case SQL_CONCURRENCY:
10720 *((SQLINTEGER *) param) = SQL_CONCUR_LOCK;
10721 break;
10722 case SQL_SIMULATE_CURSOR:
10723 *((SQLINTEGER *) param) = SQL_SC_NON_UNIQUE;
10724 break;
10725 case SQL_MAX_ROWS:
10726 *((SQLINTEGER *) param) = 0;
10727 break;
10728 case SQL_ROWSET_SIZE:
10729 case SQL_MAX_LENGTH:
10730 *((SQLINTEGER *) param) = 1000000000;
10731 break;
10732 case SQL_CURSOR_TYPE:
10733 *((SQLINTEGER *) param) = d->curtype;
10734 break;
10735 case SQL_RETRIEVE_DATA:
10736 *((SQLINTEGER *) param) = SQL_RD_ON;
10737 break;
10738 default:
10739 *((SQLINTEGER *) param) = 0;
10740 setstatd(d, -1, "unsupported connect option %d",
10741 (*d->ov3) ? "HYC00" : "S1C00", opt);
10742 return SQL_ERROR;
10743 }
10744 return SQL_SUCCESS;
10745 }
10746
10747 #ifndef WINTERFACE
10748
10756 SQLRETURN SQL_API
10757 SQLGetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
10758 {
10759 SQLRETURN ret;
10760
10761 HDBC_LOCK(dbc);
10762 ret = drvgetconnectoption(dbc, opt, param);
10763 HDBC_UNLOCK(dbc);
10764 return ret;
10765 }
10766 #endif
10767
10768 #ifdef WINTERFACE
10769
10777 SQLRETURN SQL_API
10778 SQLGetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
10779 {
10780 SQLRETURN ret;
10781
10782 HDBC_LOCK(dbc);
10783 ret = drvgetconnectoption(dbc, opt, param);
10784 if (SQL_SUCCEEDED(ret)) {
10785 switch (opt) {
10786 case SQL_OPT_TRACEFILE:
10787 case SQL_CURRENT_QUALIFIER:
10788 case SQL_TRANSLATE_DLL:
10789 if (param) {
10790 *(SQLWCHAR *) param = 0;
10791 }
10792 break;
10793 }
10794 }
10795 HDBC_UNLOCK(dbc);
10796 return ret;
10797 }
10798 #endif
10799
10808 static SQLRETURN
10809 drvsetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
10810 {
10811 DBC *d;
10812
10813 if (dbc == SQL_NULL_HDBC) {
10814 return SQL_INVALID_HANDLE;
10815 }
10816 d = (DBC *) dbc;
10817 switch (opt) {
10818 case SQL_AUTOCOMMIT:
10819 d->autocommit = param == SQL_AUTOCOMMIT_ON;
10820 if (d->autocommit && d->intrans) {
10821 return endtran(d, SQL_COMMIT, 1);
10822 } else if (!d->autocommit) {
10823 s3stmt_end(d->cur_s3stmt);
10824 }
10825 break;
10826 default:
10827 setstatd(d, -1, "option value changed", "01S02");
10828 return SQL_SUCCESS_WITH_INFO;
10829 }
10830 return SQL_SUCCESS;
10831 }
10832
10833 #ifndef WINTERFACE
10834
10842 SQLRETURN SQL_API
10843 SQLSetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
10844 {
10845 SQLRETURN ret;
10846
10847 HDBC_LOCK(dbc);
10848 ret = drvsetconnectoption(dbc, opt, param);
10849 HDBC_UNLOCK(dbc);
10850 return ret;
10851 }
10852 #endif
10853
10854 #ifdef WINTERFACE
10855
10863 SQLRETURN SQL_API
10864 SQLSetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
10865 {
10866 SQLRETURN ret;
10867
10868 HDBC_LOCK(dbc);
10869 ret = drvsetconnectoption(dbc, opt, param);
10870 HDBC_UNLOCK(dbc);
10871 return ret;
10872 }
10873 #endif
10874
10875 #if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
10876
10887 static int
10888 getdsnattr(char *dsn, char *attr, char *out, int outLen)
10889 {
10890 char *str = dsn, *start;
10891 int len = strlen(attr);
10892
10893 while (*str) {
10894 while (*str && *str == ';') {
10895 ++str;
10896 }
10897 start = str;
10898 if ((str = strchr(str, '=')) == NULL) {
10899 return 0;
10900 }
10901 if (str - start == len && strncasecmp(start, attr, len) == 0) {
10902 start = ++str;
10903 while (*str && *str != ';') {
10904 ++str;
10905 }
10906 len = min(outLen - 1, str - start);
10907 strncpy(out, start, len);
10908 out[len] = '\0';
10909 return 1;
10910 }
10911 while (*str && *str != ';') {
10912 ++str;
10913 }
10914 }
10915 return 0;
10916 }
10917 #endif
10918
10930 static SQLRETURN
10931 drvconnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen, char *pwd,
10932 int pwdLen, int isu)
10933 {
10934 DBC *d;
10935 int len;
10936 SQLRETURN ret;
10937 char buf[SQL_MAX_MESSAGE_LENGTH], dbname[SQL_MAX_MESSAGE_LENGTH / 4];
10938 char busy[SQL_MAX_MESSAGE_LENGTH / 4], tracef[SQL_MAX_MESSAGE_LENGTH];
10939 char loadext[SQL_MAX_MESSAGE_LENGTH];
10940 char sflag[32], spflag[32], ntflag[32], nwflag[32], biflag[32];
10941 char snflag[32], lnflag[32], ncflag[32], fkflag[32], jmode[32];
10942 char jdflag[32];
10943 #if defined(_WIN32) || defined(_WIN64)
10944 char oemcp[32];
10945 #endif
10946
10947 if (dbc == SQL_NULL_HDBC) {
10948 return SQL_INVALID_HANDLE;
10949 }
10950 d = (DBC *) dbc;
10951 if (d->magic != DBC_MAGIC) {
10952 return SQL_INVALID_HANDLE;
10953 }
10954 if (d->sqlite != NULL) {
10955 setstatd(d, -1, "connection already established", "08002");
10956 return SQL_ERROR;
10957 }
10958 buf[0] = '\0';
10959 if (dsnLen == SQL_NTS) {
10960 len = sizeof (buf) - 1;
10961 } else {
10962 len = min(sizeof (buf) - 1, dsnLen);
10963 }
10964 if (dsn != NULL) {
10965 strncpy(buf, (char *) dsn, len);
10966 }
10967 buf[len] = '\0';
10968 if (buf[0] == '\0') {
10969 setstatd(d, -1, "invalid DSN", (*d->ov3) ? "HY090" : "S1090");
10970 return SQL_ERROR;
10971 }
10972 #if defined(_WIN32) || defined(_WIN64)
10973
10974
10975
10976
10977 if (isu) {
10978 char *cdsn = utf_to_wmb(buf, len);
10979
10980 if (!cdsn) {
10981 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
10982 return SQL_ERROR;
10983 }
10984 strcpy(buf, cdsn);
10985 uc_free(cdsn);
10986 }
10987 #endif
10988 busy[0] = '\0';
10989 dbname[0] = '\0';
10990 #ifdef WITHOUT_DRIVERMGR
10991 getdsnattr(buf, "database", dbname, sizeof (dbname));
10992 if (dbname[0] == '\0') {
10993 strncpy(dbname, buf, sizeof (dbname));
10994 dbname[sizeof (dbname) - 1] = '\0';
10995 }
10996 getdsnattr(buf, "timeout", busy, sizeof (busy));
10997 sflag[0] = '\0';
10998 getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
10999 spflag[0] = '\0';
11000 getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
11001 ntflag[0] = '\0';
11002 getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
11003 nwflag[0] = '\0';
11004 getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
11005 snflag[0] = '\0';
11006 getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
11007 lnflag[0] = '\0';
11008 getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
11009 ncflag[0] = '\0';
11010 getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
11011 fkflag[0] = '\0';
11012 getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
11013 loadext[0] = '\0';
11014 getdsnattr(buf, "loadext", loadext, sizeof (loadext));
11015 jmode[0] = '\0';
11016 getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
11017 jdflag[0] = '\0';
11018 getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
11019 #if defined(_WIN32) || defined(_WIN64)
11020 oemcp[0] = '\0';
11021 getdsnattr(buf, "oemcp", oemcp, sizeof (oemcp));
11022 #endif
11023 biflag[0] = '\0';
11024 getdsnattr(buf, "bigint", biflag, sizeof (biflag));
11025 #else
11026 SQLGetPrivateProfileString(buf, "timeout", "100000",
11027 busy, sizeof (busy), ODBC_INI);
11028 SQLGetPrivateProfileString(buf, "database", "",
11029 dbname, sizeof (dbname), ODBC_INI);
11030 #if defined(_WIN32) || defined(_WIN64)
11031
11032 isu = 0;
11033 #endif
11034 SQLGetPrivateProfileString(buf, "stepapi", "",
11035 sflag, sizeof (sflag), ODBC_INI);
11036 SQLGetPrivateProfileString(buf, "syncpragma", "NORMAL",
11037 spflag, sizeof (spflag), ODBC_INI);
11038 SQLGetPrivateProfileString(buf, "notxn", "",
11039 ntflag, sizeof (ntflag), ODBC_INI);
11040 SQLGetPrivateProfileString(buf, "nowchar", "",
11041 nwflag, sizeof (nwflag), ODBC_INI);
11042 SQLGetPrivateProfileString(buf, "shortnames", "",
11043 snflag, sizeof (snflag), ODBC_INI);
11044 SQLGetPrivateProfileString(buf, "longnames", "",
11045 lnflag, sizeof (lnflag), ODBC_INI);
11046 SQLGetPrivateProfileString(buf, "nocreat", "",
11047 ncflag, sizeof (ncflag), ODBC_INI);
11048 SQLGetPrivateProfileString(buf, "fksupport", "",
11049 fkflag, sizeof (fkflag), ODBC_INI);
11050 SQLGetPrivateProfileString(buf, "loadext", "",
11051 loadext, sizeof (loadext), ODBC_INI);
11052 SQLGetPrivateProfileString(buf, "journalmode", "",
11053 jmode, sizeof (jmode), ODBC_INI);
11054 SQLGetPrivateProfileString(buf, "jdconv", "",
11055 jdflag, sizeof (jdflag), ODBC_INI);
11056 #if defined(_WIN32) || defined(_WIN64)
11057 SQLGetPrivateProfileString(buf, "oemcp", "1",
11058 oemcp, sizeof (oemcp), ODBC_INI);
11059 #endif
11060 SQLGetPrivateProfileString(buf, "bigint", "",
11061 biflag, sizeof (biflag), ODBC_INI);
11062 #endif
11063 tracef[0] = '\0';
11064 #ifdef WITHOUT_DRIVERMGR
11065 getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
11066 #else
11067 SQLGetPrivateProfileString(buf, "tracefile", "",
11068 tracef, sizeof (tracef), ODBC_INI);
11069 #endif
11070 if (tracef[0] != '\0') {
11071 d->trace = fopen(tracef, "a");
11072 }
11073 d->nowchar = getbool(nwflag);
11074 d->shortnames = getbool(snflag);
11075 d->longnames = getbool(lnflag);
11076 d->nocreat = getbool(ncflag);
11077 d->fksupport = getbool(fkflag);
11078 d->jdconv = getbool(jdflag);
11079 #if defined(_WIN32) || defined(_WIN64)
11080 d->oemcp = getbool(oemcp);
11081 #else
11082 d->oemcp = 0;
11083 #endif
11084 d->dobigint = getbool(biflag);
11085 d->pwd = pwd;
11086 d->pwdLen = 0;
11087 if (d->pwd) {
11088 d->pwdLen = (pwdLen == SQL_NTS) ? strlen(d->pwd) : pwdLen;
11089 }
11090 ret = dbopen(d, dbname, isu, (char *) dsn, sflag, spflag, ntflag,
11091 jmode, busy);
11092 if (ret == SQL_SUCCESS) {
11093 dbloadext(d, loadext);
11094 }
11095 return ret;
11096 }
11097
11098 #ifndef WINTERFACE
11099
11111 SQLRETURN SQL_API
11112 SQLConnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen,
11113 SQLCHAR *uid, SQLSMALLINT uidLen,
11114 SQLCHAR *pwd, SQLSMALLINT pwdLen)
11115 {
11116 SQLRETURN ret;
11117
11118 HDBC_LOCK(dbc);
11119 ret = drvconnect(dbc, dsn, dsnLen, (char *) pwd, pwdLen, 0);
11120 HDBC_UNLOCK(dbc);
11121 return ret;
11122 }
11123 #endif
11124
11125 #ifdef WINTERFACE
11126
11138 SQLRETURN SQL_API
11139 SQLConnectW(SQLHDBC dbc, SQLWCHAR *dsn, SQLSMALLINT dsnLen,
11140 SQLWCHAR *uid, SQLSMALLINT uidLen,
11141 SQLWCHAR *pwd, SQLSMALLINT pwdLen)
11142 {
11143 char *dsna = NULL;
11144 char *pwda = NULL;
11145 SQLRETURN ret;
11146
11147 HDBC_LOCK(dbc);
11148 if (dsn) {
11149 dsna = uc_to_utf_c(dsn, dsnLen);
11150 if (!dsna) {
11151 DBC *d = (DBC *) dbc;
11152
11153 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
11154 ret = SQL_ERROR;
11155 goto done;
11156 }
11157 }
11158 if (pwd) {
11159 pwda = uc_to_utf_c(pwd, pwdLen);
11160 if (!pwda) {
11161 DBC *d = (DBC *) dbc;
11162
11163 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
11164 ret = SQL_ERROR;
11165 goto done;
11166 }
11167 }
11168 ret = drvconnect(dbc, (SQLCHAR *) dsna, SQL_NTS, pwda, SQL_NTS, 1);
11169 done:
11170 HDBC_UNLOCK(dbc);
11171 uc_free(dsna);
11172 uc_free(pwda);
11173 return ret;
11174 }
11175 #endif
11176
11183 static SQLRETURN
11184 drvdisconnect(SQLHDBC dbc)
11185 {
11186 DBC *d;
11187
11188 if (dbc == SQL_NULL_HDBC) {
11189 return SQL_INVALID_HANDLE;
11190 }
11191 d = (DBC *) dbc;
11192 if (d->magic != DBC_MAGIC) {
11193 return SQL_INVALID_HANDLE;
11194 }
11195 if (d->intrans) {
11196 setstatd(d, -1, "incomplete transaction", "25000");
11197 return SQL_ERROR;
11198 }
11199 if (d->cur_s3stmt) {
11200 s3stmt_end(d->cur_s3stmt);
11201 }
11202 if (d->sqlite) {
11203 if (d->trace) {
11204 fprintf(d->trace, "-- sqlite3_close: '%s'\n",
11205 d->dbname);
11206 fflush(d->trace);
11207 }
11208 sqlite3_close(d->sqlite);
11209 d->sqlite = NULL;
11210 }
11211 freep(&d->dbname);
11212 freep(&d->dsn);
11213 return SQL_SUCCESS;
11214 }
11215
11222 SQLRETURN SQL_API
11223 SQLDisconnect(SQLHDBC dbc)
11224 {
11225 SQLRETURN ret;
11226
11227 HDBC_LOCK(dbc);
11228 ret = drvdisconnect(dbc);
11229 HDBC_UNLOCK(dbc);
11230 return ret;
11231 }
11232
11233 #if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
11234
11248 static SQLRETURN
11249 drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
11250 SQLCHAR *connIn, SQLSMALLINT connInLen,
11251 SQLCHAR *connOut, SQLSMALLINT connOutMax,
11252 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
11253 {
11254 DBC *d;
11255 int len;
11256 SQLRETURN ret;
11257 char buf[SQL_MAX_MESSAGE_LENGTH * 6], dbname[SQL_MAX_MESSAGE_LENGTH];
11258 char dsn[SQL_MAX_MESSAGE_LENGTH / 4], busy[SQL_MAX_MESSAGE_LENGTH / 4];
11259 char tracef[SQL_MAX_MESSAGE_LENGTH], loadext[SQL_MAX_MESSAGE_LENGTH];
11260 char pwd[SQL_MAX_MESSAGE_LENGTH];
11261 char sflag[32], spflag[32], ntflag[32], snflag[32], lnflag[32];
11262 char ncflag[32], nwflag[32], fkflag[32], jmode[32], biflag[32];
11263 char jdflag[32];
11264
11265 if (dbc == SQL_NULL_HDBC) {
11266 return SQL_INVALID_HANDLE;
11267 }
11268 if (drvcompl != SQL_DRIVER_COMPLETE &&
11269 drvcompl != SQL_DRIVER_COMPLETE_REQUIRED &&
11270 drvcompl != SQL_DRIVER_PROMPT &&
11271 drvcompl != SQL_DRIVER_NOPROMPT) {
11272 return SQL_NO_DATA;
11273 }
11274 d = (DBC *) dbc;
11275 if (d->sqlite) {
11276 setstatd(d, -1, "connection already established", "08002");
11277 return SQL_ERROR;
11278 }
11279 buf[0] = '\0';
11280 if (connInLen == SQL_NTS) {
11281 len = sizeof (buf) - 1;
11282 } else {
11283 len = min(connInLen, sizeof (buf) - 1);
11284 }
11285 if (connIn != NULL) {
11286 strncpy(buf, (char *) connIn, len);
11287 }
11288 buf[len] = '\0';
11289 if (!buf[0]) {
11290 setstatd(d, -1, "invalid connect attributes",
11291 (*d->ov3) ? "HY090" : "S1090");
11292 return SQL_ERROR;
11293 }
11294 dsn[0] = '\0';
11295 getdsnattr(buf, "DSN", dsn, sizeof (dsn));
11296
11297
11298 if (!dsn[0] && !strchr(buf, ';') && !strchr(buf, '=')) {
11299 strncpy(dsn, buf, sizeof (dsn) - 1);
11300 dsn[sizeof (dsn) - 1] = '\0';
11301 }
11302
11303 busy[0] = '\0';
11304 getdsnattr(buf, "timeout", busy, sizeof (busy));
11305 #ifndef WITHOUT_DRIVERMGR
11306 if (dsn[0] && !busy[0]) {
11307 SQLGetPrivateProfileString(dsn, "timeout", "100000",
11308 busy, sizeof (busy), ODBC_INI);
11309 }
11310 #endif
11311 dbname[0] = '\0';
11312 getdsnattr(buf, "database", dbname, sizeof (dbname));
11313 #ifndef WITHOUT_DRIVERMGR
11314 if (dsn[0] && !dbname[0]) {
11315 SQLGetPrivateProfileString(dsn, "database", "",
11316 dbname, sizeof (dbname), ODBC_INI);
11317 }
11318 #endif
11319 sflag[0] = '\0';
11320 getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
11321 #ifndef WITHOUT_DRIVERMGR
11322 if (dsn[0] && !sflag[0]) {
11323 SQLGetPrivateProfileString(dsn, "stepapi", "",
11324 sflag, sizeof (sflag), ODBC_INI);
11325 }
11326 #endif
11327 spflag[0] = '\0';
11328 getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
11329 #ifndef WITHOUT_DRIVERMGR
11330 if (dsn[0] && !spflag[0]) {
11331 SQLGetPrivateProfileString(dsn, "syncpragma", "NORMAL",
11332 spflag, sizeof (spflag), ODBC_INI);
11333 }
11334 #endif
11335 ntflag[0] = '\0';
11336 getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
11337 #ifndef WITHOUT_DRIVERMGR
11338 if (dsn[0] && !ntflag[0]) {
11339 SQLGetPrivateProfileString(dsn, "notxn", "",
11340 ntflag, sizeof (ntflag), ODBC_INI);
11341 }
11342 #endif
11343 snflag[0] = '\0';
11344 getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
11345 #ifndef WITHOUT_DRIVERMGR
11346 if (dsn[0] && !snflag[0]) {
11347 SQLGetPrivateProfileString(dsn, "shortnames", "",
11348 snflag, sizeof (snflag), ODBC_INI);
11349 }
11350 #endif
11351 lnflag[0] = '\0';
11352 getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
11353 #ifndef WITHOUT_DRIVERMGR
11354 if (dsn[0] && !lnflag[0]) {
11355 SQLGetPrivateProfileString(dsn, "longnames", "",
11356 lnflag, sizeof (lnflag), ODBC_INI);
11357 }
11358 #endif
11359 ncflag[0] = '\0';
11360 getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
11361 #ifndef WITHOUT_DRIVERMGR
11362 if (dsn[0] && !ncflag[0]) {
11363 SQLGetPrivateProfileString(dsn, "nocreat", "",
11364 ncflag, sizeof (ncflag), ODBC_INI);
11365 }
11366 #endif
11367 nwflag[0] = '\0';
11368 getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
11369 #ifndef WITHOUT_DRIVERMGR
11370 if (dsn[0] && !nwflag[0]) {
11371 SQLGetPrivateProfileString(dsn, "nowchar", "",
11372 nwflag, sizeof (nwflag), ODBC_INI);
11373 }
11374 #endif
11375 fkflag[0] = '\0';
11376 getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
11377 #ifndef WITHOUT_DRIVERMGR
11378 if (dsn[0] && !fkflag[0]) {
11379 SQLGetPrivateProfileString(dsn, "fksupport", "",
11380 fkflag, sizeof (fkflag), ODBC_INI);
11381 }
11382 #endif
11383 loadext[0] = '\0';
11384 getdsnattr(buf, "loadext", loadext, sizeof (loadext));
11385 #ifndef WITHOUT_DRIVERMGR
11386 if (dsn[0] && !loadext[0]) {
11387 SQLGetPrivateProfileString(dsn, "loadext", "",
11388 loadext, sizeof (loadext), ODBC_INI);
11389 }
11390 #endif
11391 jmode[0] = '\0';
11392 getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
11393 #ifndef WITHOUT_DRIVERMGR
11394 if (dsn[0] && !jmode[0]) {
11395 SQLGetPrivateProfileString(dsn, "journalmode", "",
11396 jmode, sizeof (jmode), ODBC_INI);
11397 }
11398 #endif
11399 biflag[0] = '\0';
11400 getdsnattr(buf, "bigint", biflag, sizeof (biflag));
11401 #ifndef WITHOUT_DRIVERMGR
11402 if (dsn[0] && !biflag[0]) {
11403 SQLGetPrivateProfileString(dsn, "bigint", "",
11404 biflag, sizeof (biflag), ODBC_INI);
11405 }
11406 #endif
11407 jdflag[0] = '\0';
11408 getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
11409 #ifndef WITHOUT_DRIVERMGR
11410 if (dsn[0] && !jdflag[0]) {
11411 SQLGetPrivateProfileString(dsn, "jdconv", "",
11412 jdflag, sizeof (jdflag), ODBC_INI);
11413 }
11414 #endif
11415 pwd[0] = '\0';
11416 getdsnattr(buf, "pwd", pwd, sizeof (pwd));
11417 #ifndef WITHOUT_DRIVERMGR
11418 if (dsn[0] && !pwd[0]) {
11419 SQLGetPrivateProfileString(dsn, "pwd", "",
11420 pwd, sizeof (pwd), ODBC_INI);
11421 }
11422 #endif
11423
11424 if (!dbname[0] && !dsn[0]) {
11425 strcpy(dsn, "SQLite");
11426 strncpy(dbname, buf, sizeof (dbname));
11427 dbname[sizeof (dbname) - 1] = '\0';
11428 }
11429 tracef[0] = '\0';
11430 getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
11431 #ifndef WITHOUT_DRIVERMGR
11432 if (dsn[0] && !tracef[0]) {
11433 SQLGetPrivateProfileString(dsn, "tracefile", "",
11434 tracef, sizeof (tracef), ODBC_INI);
11435 }
11436 #endif
11437 if (connOut || connOutLen) {
11438 int count;
11439
11440 buf[0] = '\0';
11441 count = snprintf(buf, sizeof (buf),
11442 "DSN=%s;Database=%s;StepAPI=%s;Timeout=%s;"
11443 "SyncPragma=%s;NoTXN=%s;ShortNames=%s;LongNames=%s;"
11444 "NoCreat=%s;NoWCHAR=%s;FKSupport=%s;Tracefile=%s;"
11445 "JournalMode=%s;LoadExt=%s;BigInt=%s;JDConv=%s;"
11446 "PWD=%s",
11447 dsn, dbname, sflag, busy, spflag, ntflag,
11448 snflag, lnflag, ncflag, nwflag, fkflag, tracef,
11449 jmode, loadext, biflag, jdflag, pwd);
11450 if (count < 0) {
11451 buf[sizeof (buf) - 1] = '\0';
11452 }
11453 len = min(connOutMax - 1, strlen(buf));
11454 if (connOut) {
11455 strncpy((char *) connOut, buf, len);
11456 connOut[len] = '\0';
11457 }
11458 if (connOutLen) {
11459 *connOutLen = len;
11460 }
11461 }
11462 if (tracef[0] != '\0') {
11463 d->trace = fopen(tracef, "a");
11464 }
11465 d->shortnames = getbool(snflag);
11466 d->longnames = getbool(lnflag);
11467 d->nocreat = getbool(ncflag);
11468 d->nowchar = getbool(nwflag);
11469 d->fksupport = getbool(fkflag);
11470 d->dobigint = getbool(biflag);
11471 d->jdconv = getbool(jdflag);
11472 d->oemcp = 0;
11473 d->pwdLen = strlen(pwd);
11474 d->pwd = (d->pwdLen > 0) ? pwd : NULL;
11475 ret = dbopen(d, dbname, 0, dsn, sflag, spflag, ntflag, jmode, busy);
11476 memset(pwd, 0, sizeof (pwd));
11477 if (ret == SQL_SUCCESS) {
11478 dbloadext(d, loadext);
11479 }
11480 return ret;
11481 }
11482 #endif
11483
11490 static SQLRETURN
11491 freestmt(SQLHSTMT stmt)
11492 {
11493 STMT *s;
11494 DBC *d;
11495
11496 if (stmt == SQL_NULL_HSTMT) {
11497 return SQL_INVALID_HANDLE;
11498 }
11499 s = (STMT *) stmt;
11500 s3stmt_drop(s);
11501 freeresult(s, 1);
11502 freep(&s->query);
11503 d = (DBC *) s->dbc;
11504 if (d && d->magic == DBC_MAGIC) {
11505 STMT *p, *n;
11506
11507 p = NULL;
11508 n = d->stmt;
11509 while (n) {
11510 if (n == s) {
11511 break;
11512 }
11513 p = n;
11514 n = n->next;
11515 }
11516 if (n) {
11517 if (p) {
11518 p->next = s->next;
11519 } else {
11520 d->stmt = s->next;
11521 }
11522 }
11523 }
11524 freeparams(s);
11525 freep(&s->bindparms);
11526 if (s->row_status0 != &s->row_status1) {
11527 freep(&s->row_status0);
11528 s->rowset_size = 1;
11529 s->row_status0 = &s->row_status1;
11530 }
11531 xfree(s);
11532 return SQL_SUCCESS;
11533 }
11534
11542 static SQLRETURN
11543 drvallocstmt(SQLHDBC dbc, SQLHSTMT *stmt)
11544 {
11545 DBC *d;
11546 STMT *s, *sl, *pl;
11547
11548 if (dbc == SQL_NULL_HDBC) {
11549 return SQL_INVALID_HANDLE;
11550 }
11551 d = (DBC *) dbc;
11552 if (d->magic != DBC_MAGIC || stmt == NULL) {
11553 return SQL_INVALID_HANDLE;
11554 }
11555 s = (STMT *) xmalloc(sizeof (STMT));
11556 if (s == NULL) {
11557 *stmt = SQL_NULL_HSTMT;
11558 return SQL_ERROR;
11559 }
11560 *stmt = (SQLHSTMT) s;
11561 memset(s, 0, sizeof (STMT));
11562 s->dbc = dbc;
11563 s->ov3 = d->ov3;
11564 s->oemcp = &d->oemcp;
11565 s->jdconv = &d->jdconv;
11566 s->nowchar[0] = d->nowchar;
11567 s->nowchar[1] = 0;
11568 s->dobigint = d->dobigint;
11569 s->curtype = d->curtype;
11570 s->row_status0 = &s->row_status1;
11571 s->rowset_size = 1;
11572 s->longnames = d->longnames;
11573 s->retr_data = SQL_RD_ON;
11574 s->max_rows = 0;
11575 s->bind_type = SQL_BIND_BY_COLUMN;
11576 s->bind_offs = NULL;
11577 s->paramset_size = 1;
11578 s->parm_bind_type = SQL_PARAM_BIND_BY_COLUMN;
11579 #ifdef _WIN64
11580 sprintf((char *) s->cursorname, "CUR_%I64X", (SQLUBIGINT) *stmt);
11581 #else
11582 sprintf((char *) s->cursorname, "CUR_%016lX", (long) *stmt);
11583 #endif
11584 sl = d->stmt;
11585 pl = NULL;
11586 while (sl) {
11587 pl = sl;
11588 sl = sl->next;
11589 }
11590 if (pl) {
11591 pl->next = s;
11592 } else {
11593 d->stmt = s;
11594 }
11595 return SQL_SUCCESS;
11596 }
11597
11605 SQLRETURN SQL_API
11606 SQLAllocStmt(SQLHDBC dbc, SQLHSTMT *stmt)
11607 {
11608 SQLRETURN ret;
11609
11610 HDBC_LOCK(dbc);
11611 ret = drvallocstmt(dbc, stmt);
11612 HDBC_UNLOCK(dbc);
11613 return ret;
11614 }
11615
11623 static SQLRETURN
11624 drvfreestmt(SQLHSTMT stmt, SQLUSMALLINT opt)
11625 {
11626 STMT *s;
11627 SQLRETURN ret = SQL_SUCCESS;
11628 SQLHDBC dbc;
11629
11630 if (stmt == SQL_NULL_HSTMT) {
11631 return SQL_INVALID_HANDLE;
11632 }
11633 HSTMT_LOCK(stmt);
11634 s = (STMT *) stmt;
11635 dbc = s->dbc;
11636 switch (opt) {
11637 case SQL_RESET_PARAMS:
11638 freeparams(s);
11639 break;
11640 case SQL_UNBIND:
11641 unbindcols(s);
11642 break;
11643 case SQL_CLOSE:
11644 s3stmt_end_if(s);
11645 freeresult(s, 0);
11646 break;
11647 case SQL_DROP:
11648 s3stmt_end_if(s);
11649 ret = freestmt(stmt);
11650 break;
11651 default:
11652 setstat(s, -1, "unsupported option", (*s->ov3) ? "HYC00" : "S1C00");
11653 ret = SQL_ERROR;
11654 break;
11655 }
11656 HDBC_UNLOCK(dbc);
11657 return ret;
11658 }
11659
11667 SQLRETURN SQL_API
11668 SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT opt)
11669 {
11670 return drvfreestmt(stmt, opt);
11671 }
11672
11679 SQLRETURN SQL_API
11680 SQLCancel(SQLHSTMT stmt)
11681 {
11682 if (stmt != SQL_NULL_HSTMT) {
11683 DBC *d = (DBC *) ((STMT *) stmt)->dbc;
11684 #if defined(_WIN32) || defined(_WIN64)
11685
11686 int i;
11687
11688 for (i = 0; i < 2; i++) {
11689 if (d->magic == DBC_MAGIC && d->env &&
11690 d->env->magic == ENV_MAGIC &&
11691 d->env->owner != GetCurrentThreadId() &&
11692 d->env->owner != 0) {
11693 d->busyint = 1;
11694 sqlite3_interrupt(d->sqlite);
11695 }
11696 Sleep(1);
11697 }
11698
11699 #else
11700 if (d->magic == DBC_MAGIC) {
11701 d->busyint = 1;
11702 sqlite3_interrupt(d->sqlite);
11703 }
11704 #endif
11705 }
11706 return drvfreestmt(stmt, SQL_CLOSE);
11707 }
11708
11718 static SQLRETURN
11719 drvgetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
11720 SQLSMALLINT *lenp)
11721 {
11722 STMT *s;
11723
11724 if (stmt == SQL_NULL_HSTMT) {
11725 return SQL_INVALID_HANDLE;
11726 }
11727 s = (STMT *) stmt;
11728 if (lenp && !cursor) {
11729 *lenp = strlen((char *) s->cursorname);
11730 return SQL_SUCCESS;
11731 }
11732 if (cursor) {
11733 if (buflen > 0) {
11734 strncpy((char *) cursor, (char *) s->cursorname, buflen - 1);
11735 cursor[buflen - 1] = '\0';
11736 }
11737 if (lenp) {
11738 *lenp = min(strlen((char *) s->cursorname), buflen - 1);
11739 }
11740 }
11741 return SQL_SUCCESS;
11742 }
11743
11744 #ifndef WINTERFACE
11745
11754 SQLRETURN SQL_API
11755 SQLGetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
11756 SQLSMALLINT *lenp)
11757 {
11758 SQLRETURN ret;
11759 #if defined(_WIN32) || defined(_WIN64)
11760 SQLSMALLINT len = 0;
11761 #endif
11762
11763 HSTMT_LOCK(stmt);
11764 #if defined(_WIN32) || defined(_WIN64)
11765 if (!((STMT *) stmt)->oemcp[0]) {
11766 ret = drvgetcursorname(stmt, cursor, buflen, lenp);
11767 goto done;
11768 }
11769 ret = drvgetcursorname(stmt, cursor, buflen, &len);
11770 if (ret == SQL_SUCCESS) {
11771 char *c = NULL;
11772
11773 if (cursor) {
11774 c = utf_to_wmb((char *) cursor, len);
11775 if (!c) {
11776 ret = nomem((STMT *) stmt);
11777 goto done;
11778 }
11779 c[len] = 0;
11780 len = strlen(c);
11781 if (buflen > 0) {
11782 strncpy((char *) cursor, c, buflen - 1);
11783 cursor[buflen - 1] = 0;
11784 }
11785 uc_free(c);
11786 }
11787 if (lenp) {
11788 *lenp = min(len, buflen - 1);
11789 }
11790 }
11791 done:
11792 ;
11793 #else
11794 ret = drvgetcursorname(stmt, cursor, buflen, lenp);
11795 #endif
11796 HSTMT_UNLOCK(stmt);
11797 return ret;
11798 }
11799 #endif
11800
11801 #ifdef WINTERFACE
11802
11811 SQLRETURN SQL_API
11812 SQLGetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT buflen,
11813 SQLSMALLINT *lenp)
11814 {
11815 SQLRETURN ret;
11816 SQLSMALLINT len = 0;
11817
11818 HSTMT_LOCK(stmt);
11819 ret = drvgetcursorname(stmt, (SQLCHAR *) cursor, buflen, &len);
11820 if (ret == SQL_SUCCESS) {
11821 SQLWCHAR *c = NULL;
11822
11823 if (cursor) {
11824 c = uc_from_utf((SQLCHAR *) cursor, len);
11825 if (!c) {
11826 ret = nomem((STMT *) stmt);
11827 goto done;
11828 }
11829 c[len] = 0;
11830 len = uc_strlen(c);
11831 if (buflen > 0) {
11832 uc_strncpy(cursor, c, buflen - 1);
11833 cursor[buflen - 1] = 0;
11834 }
11835 uc_free(c);
11836 }
11837 if (lenp) {
11838 *lenp = min(len, buflen - 1);
11839 }
11840 }
11841 done:
11842 HSTMT_UNLOCK(stmt);
11843 return ret;
11844 }
11845 #endif
11846
11855 static SQLRETURN
11856 drvsetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
11857 {
11858 STMT *s;
11859
11860 if (stmt == SQL_NULL_HSTMT) {
11861 return SQL_INVALID_HANDLE;
11862 }
11863 s = (STMT *) stmt;
11864 if (!cursor ||
11865 !((cursor[0] >= 'A' && cursor[0] <= 'Z') ||
11866 (cursor[0] >= 'a' && cursor[0] <= 'z'))) {
11867 setstat(s, -1, "invalid cursor name", (*s->ov3) ? "HYC00" : "S1C00");
11868 return SQL_ERROR;
11869 }
11870 if (len == SQL_NTS) {
11871 len = sizeof (s->cursorname) - 1;
11872 } else {
11873 len = min(sizeof (s->cursorname) - 1, len);
11874 }
11875 strncpy((char *) s->cursorname, (char *) cursor, len);
11876 s->cursorname[len] = '\0';
11877 return SQL_SUCCESS;
11878 }
11879
11880 #ifndef WINTERFACE
11881
11889 SQLRETURN SQL_API
11890 SQLSetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
11891 {
11892 #if defined(_WIN32) || defined(_WIN64)
11893 char *c = NULL;
11894 #endif
11895 SQLRETURN ret;
11896
11897 HSTMT_LOCK(stmt);
11898 #if defined(_WIN32) || defined(_WIN64)
11899 if (!((STMT *) stmt)->oemcp[0]) {
11900 ret = drvsetcursorname(stmt, cursor, len);
11901 goto done2;
11902 }
11903 if (cursor) {
11904 c = wmb_to_utf_c((char *) cursor, len);
11905 if (!c) {
11906 ret = nomem((STMT *) stmt);
11907 goto done;
11908 }
11909 }
11910 ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
11911 #else
11912 ret = drvsetcursorname(stmt, cursor, len);
11913 #endif
11914 #if defined(_WIN32) || defined(_WIN64)
11915 done:
11916 uc_free(c);
11917 done2:
11918 ;
11919 #endif
11920 HSTMT_UNLOCK(stmt);
11921 return ret;
11922 }
11923 #endif
11924
11925 #ifdef WINTERFACE
11926
11934 SQLRETURN SQL_API
11935 SQLSetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT len)
11936 {
11937 char *c = NULL;
11938 SQLRETURN ret;
11939
11940 HSTMT_LOCK(stmt);
11941 if (cursor) {
11942 c = uc_to_utf_c(cursor, len);
11943 if (!c) {
11944 ret = nomem((STMT *) stmt);
11945 goto done;
11946 }
11947 }
11948 ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
11949 done:
11950 uc_free(c);
11951 HSTMT_UNLOCK(stmt);
11952 return ret;
11953 }
11954 #endif
11955
11962 SQLRETURN SQL_API
11963 SQLCloseCursor(SQLHSTMT stmt)
11964 {
11965 return drvfreestmt(stmt, SQL_CLOSE);
11966 }
11967
11976 SQLRETURN SQL_API
11977 SQLAllocHandle(SQLSMALLINT type, SQLHANDLE input, SQLHANDLE *output)
11978 {
11979 SQLRETURN ret;
11980
11981 switch (type) {
11982 case SQL_HANDLE_ENV:
11983 ret = drvallocenv((SQLHENV *) output);
11984 if (ret == SQL_SUCCESS) {
11985 ENV *e = (ENV *) *output;
11986
11987 if (e && e->magic == ENV_MAGIC) {
11988 e->ov3 = 1;
11989 }
11990 }
11991 return ret;
11992 case SQL_HANDLE_DBC:
11993 return drvallocconnect((SQLHENV) input, (SQLHDBC *) output);
11994 case SQL_HANDLE_STMT:
11995 HDBC_LOCK((SQLHDBC) input);
11996 ret = drvallocstmt((SQLHDBC) input, (SQLHSTMT *) output);
11997 HDBC_UNLOCK((SQLHDBC) input);
11998 return ret;
11999 }
12000 return SQL_ERROR;
12001 }
12002
12010 SQLRETURN SQL_API
12011 SQLFreeHandle(SQLSMALLINT type, SQLHANDLE h)
12012 {
12013 switch (type) {
12014 case SQL_HANDLE_ENV:
12015 return drvfreeenv((SQLHENV) h);
12016 case SQL_HANDLE_DBC:
12017 return drvfreeconnect((SQLHDBC) h);
12018 case SQL_HANDLE_STMT:
12019 return drvfreestmt((SQLHSTMT) h, SQL_DROP);
12020 }
12021 return SQL_ERROR;
12022 }
12023
12029 static void
12030 freedyncols(STMT *s)
12031 {
12032 if (s->dyncols) {
12033 int i;
12034
12035 for (i = 0; i < s->dcols; i++) {
12036 freep(&s->dyncols[i].typename);
12037 }
12038 if (s->cols == s->dyncols) {
12039 s->cols = NULL;
12040 s->ncols = 0;
12041 }
12042 freep(&s->dyncols);
12043 }
12044 s->dcols = 0;
12045 }
12046
12058 static void
12059 freeresult(STMT *s, int clrcols)
12060 {
12061 freep(&s->bincache);
12062 s->bincell = NULL;
12063 s->binlen = 0;
12064 if (s->rows) {
12065 if (s->rowfree) {
12066 s->rowfree(s->rows);
12067 s->rowfree = NULL;
12068 }
12069 s->rows = NULL;
12070 }
12071 s->nrows = -1;
12072 if (clrcols > 0) {
12073 freep(&s->bindcols);
12074 s->nbindcols = 0;
12075 }
12076 if (clrcols) {
12077 freedyncols(s);
12078 s->cols = NULL;
12079 s->ncols = 0;
12080 s->nowchar[1] = 0;
12081 }
12082 }
12083
12089 static void
12090 unbindcols(STMT *s)
12091 {
12092 int i;
12093
12094 s->bkmrkcol.type = -1;
12095 s->bkmrkcol.max = 0;
12096 s->bkmrkcol.lenp = NULL;
12097 s->bkmrkcol.valp = NULL;
12098 s->bkmrkcol.index = 0;
12099 s->bkmrkcol.offs = 0;
12100 for (i = 0; s->bindcols && i < s->nbindcols; i++) {
12101 s->bindcols[i].type = -1;
12102 s->bindcols[i].max = 0;
12103 s->bindcols[i].lenp = NULL;
12104 s->bindcols[i].valp = NULL;
12105 s->bindcols[i].index = i;
12106 s->bindcols[i].offs = 0;
12107 }
12108 }
12109
12117 static SQLRETURN
12118 mkbindcols(STMT *s, int ncols)
12119 {
12120 if (s->bindcols) {
12121 if (s->nbindcols < ncols) {
12122 int i;
12123 BINDCOL *bindcols =
12124 xrealloc(s->bindcols, ncols * sizeof (BINDCOL));
12125
12126 if (!bindcols) {
12127 return nomem(s);
12128 }
12129 for (i = s->nbindcols; i < ncols; i++) {
12130 bindcols[i].type = -1;
12131 bindcols[i].max = 0;
12132 bindcols[i].lenp = NULL;
12133 bindcols[i].valp = NULL;
12134 bindcols[i].index = i;
12135 bindcols[i].offs = 0;
12136 }
12137 s->bindcols = bindcols;
12138 s->nbindcols = ncols;
12139 }
12140 } else if (ncols > 0) {
12141 s->bindcols = (BINDCOL *) xmalloc(ncols * sizeof (BINDCOL));
12142 if (!s->bindcols) {
12143 return nomem(s);
12144 }
12145 s->nbindcols = ncols;
12146 unbindcols(s);
12147 }
12148 return SQL_SUCCESS;
12149 }
12150
12164 static SQLRETURN
12165 getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype,
12166 SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp, int partial)
12167 {
12168 char **data, valdummy[16];
12169 SQLLEN dummy;
12170 SQLINTEGER *ilenp = NULL;
12171 int valnull = 0;
12172 int type = otype;
12173 SQLRETURN sret = SQL_NO_DATA;
12174
12175 if (!lenp) {
12176 lenp = &dummy;
12177 }
12178
12179 if (((SQLINTEGER *) lenp) + 1 == (SQLINTEGER *) val) {
12180 ilenp = (SQLINTEGER *) lenp;
12181 lenp = &dummy;
12182 }
12183 if (col >= s->ncols) {
12184 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
12185 return SQL_ERROR;
12186 }
12187 if (!s->rows) {
12188 *lenp = SQL_NULL_DATA;
12189 goto done;
12190 }
12191 if (s->rowp < 0 || s->rowp >= s->nrows) {
12192 *lenp = SQL_NULL_DATA;
12193 goto done;
12194 }
12195 if (s->retr_data != SQL_RD_ON) {
12196 return SQL_SUCCESS;
12197 }
12198 type = mapdeftype(type, s->cols[col].type, s->cols[col].nosign ? 1 : 0,
12199 s->nowchar[0]);
12200 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
12201
12202 if (type == SQL_C_WCHAR && otype == SQL_C_DEFAULT) {
12203 type = SQL_C_CHAR;
12204 }
12205 #endif
12206 data = s->rows + s->ncols + (s->rowp * s->ncols) + col;
12207 if (!val) {
12208 valnull = 1;
12209 val = (SQLPOINTER) valdummy;
12210 }
12211 if (*data == NULL) {
12212 *lenp = SQL_NULL_DATA;
12213 switch (type) {
12214 case SQL_C_UTINYINT:
12215 case SQL_C_TINYINT:
12216 case SQL_C_STINYINT:
12217 #ifdef SQL_BIT
12218 case SQL_C_BIT:
12219 #endif
12220 *((SQLCHAR *) val) = 0;
12221 break;
12222 case SQL_C_USHORT:
12223 case SQL_C_SHORT:
12224 case SQL_C_SSHORT:
12225 *((SQLSMALLINT *) val) = 0;
12226 break;
12227 case SQL_C_ULONG:
12228 case SQL_C_LONG:
12229 case SQL_C_SLONG:
12230 *((SQLINTEGER *) val) = 0;
12231 break;
12232 #ifdef SQL_BIGINT
12233 case SQL_C_SBIGINT:
12234 case SQL_C_UBIGINT:
12235 *((SQLBIGINT *) val) = 0;
12236 break;
12237 #endif
12238 case SQL_C_FLOAT:
12239 *((float *) val) = 0;
12240 break;
12241 case SQL_C_DOUBLE:
12242 *((double *) val) = 0;
12243 break;
12244 case SQL_C_BINARY:
12245 case SQL_C_CHAR:
12246 *((SQLCHAR *) val) = '\0';
12247 break;
12248 #ifdef WCHARSUPPORT
12249 case SQL_C_WCHAR:
12250 *((SQLWCHAR *) val) = '\0';
12251 break;
12252 #endif
12253 #ifdef SQL_C_TYPE_DATE
12254 case SQL_C_TYPE_DATE:
12255 #endif
12256 case SQL_C_DATE:
12257 memset((DATE_STRUCT *) val, 0, sizeof (DATE_STRUCT));
12258 break;
12259 #ifdef SQL_C_TYPE_TIME
12260 case SQL_C_TYPE_TIME:
12261 #endif
12262 case SQL_C_TIME:
12263 memset((TIME_STRUCT *) val, 0, sizeof (TIME_STRUCT));
12264 break;
12265 #ifdef SQL_C_TYPE_TIMESTAMP
12266 case SQL_C_TYPE_TIMESTAMP:
12267 #endif
12268 case SQL_C_TIMESTAMP:
12269 memset((TIMESTAMP_STRUCT *) val, 0, sizeof (TIMESTAMP_STRUCT));
12270 break;
12271 default:
12272 return SQL_ERROR;
12273 }
12274 } else {
12275 char *endp = NULL;
12276 #if defined(_WIN32) || defined(_WIN64)
12277 #ifdef SQL_BIGINT
12278 char endc;
12279 #endif
12280 #endif
12281
12282 switch (type) {
12283 case SQL_C_UTINYINT:
12284 case SQL_C_TINYINT:
12285 case SQL_C_STINYINT:
12286 *((SQLCHAR *) val) = strtol(*data, &endp, 0);
12287 if (endp && endp == *data) {
12288 *lenp = SQL_NULL_DATA;
12289 } else {
12290 *lenp = sizeof (SQLCHAR);
12291 }
12292 break;
12293 #ifdef SQL_BIT
12294 case SQL_C_BIT:
12295 *((SQLCHAR *) val) = getbool(*data);
12296 *lenp = sizeof (SQLCHAR);
12297 break;
12298 #endif
12299 case SQL_C_USHORT:
12300 case SQL_C_SHORT:
12301 case SQL_C_SSHORT:
12302 *((SQLSMALLINT *) val) = strtol(*data, &endp, 0);
12303 if (endp && endp == *data) {
12304 *lenp = SQL_NULL_DATA;
12305 } else {
12306 *lenp = sizeof (SQLSMALLINT);
12307 }
12308 break;
12309 case SQL_C_ULONG:
12310 case SQL_C_LONG:
12311 case SQL_C_SLONG:
12312 *((SQLINTEGER *) val) = strtol(*data, &endp, 0);
12313 if (endp && endp == *data) {
12314 *lenp = SQL_NULL_DATA;
12315 } else {
12316 *lenp = sizeof (SQLINTEGER);
12317 }
12318 break;
12319 #ifdef SQL_BIGINT
12320 case SQL_C_UBIGINT:
12321 #if defined(_WIN32) || defined(_WIN64)
12322 if (sscanf(*data, "%I64u%c", (SQLUBIGINT *) val, &endc) != 1) {
12323 *lenp = SQL_NULL_DATA;
12324 } else {
12325 *lenp = sizeof (SQLUBIGINT);
12326 }
12327 #else
12328 #ifdef __osf__
12329 *((SQLUBIGINT *) val) = strtoul(*data, &endp, 0);
12330 #else
12331 *((SQLUBIGINT *) val) = strtoull(*data, &endp, 0);
12332 #endif
12333 if (endp && endp == *data) {
12334 *lenp = SQL_NULL_DATA;
12335 } else {
12336 *lenp = sizeof (SQLUBIGINT);
12337 }
12338 #endif
12339 break;
12340 case SQL_C_SBIGINT:
12341 #if defined(_WIN32) || defined(_WIN64)
12342 if (sscanf(*data, "%I64d%c", (SQLBIGINT *) val, &endc) != 1) {
12343 *lenp = SQL_NULL_DATA;
12344 } else {
12345 *lenp = sizeof (SQLBIGINT);
12346 }
12347 #else
12348 #ifdef __osf__
12349 *((SQLBIGINT *) val) = strtol(*data, &endp, 0);
12350 #else
12351 *((SQLBIGINT *) val) = strtoll(*data, &endp, 0);
12352 #endif
12353 if (endp && endp == *data) {
12354 *lenp = SQL_NULL_DATA;
12355 } else {
12356 *lenp = sizeof (SQLBIGINT);
12357 }
12358 #endif
12359 break;
12360 #endif
12361 case SQL_C_FLOAT:
12362 *((float *) val) = ln_strtod(*data, &endp);
12363 if (endp && endp == *data) {
12364 *lenp = SQL_NULL_DATA;
12365 } else {
12366 *lenp = sizeof (float);
12367 }
12368 break;
12369 case SQL_C_DOUBLE:
12370 *((double *) val) = ln_strtod(*data, &endp);
12371 if (endp && endp == *data) {
12372 *lenp = SQL_NULL_DATA;
12373 } else {
12374 *lenp = sizeof (double);
12375 }
12376 break;
12377 case SQL_C_BINARY: {
12378 int dlen, offs = 0;
12379 char *bin;
12380
12381 if (valnull) {
12382 freep(&s->bincache);
12383 s->binlen = 0;
12384 goto doCHAR;
12385 }
12386 if (*data == s->bincell) {
12387 if (s->bincache) {
12388 bin = s->bincache;
12389 dlen = s->binlen;
12390 } else {
12391 goto doCHAR;
12392 }
12393 } else {
12394 char *dp;
12395 int i;
12396
12397 freep(&s->bincache);
12398 dp = *data;
12399 dlen = strlen(dp);
12400 s->bincell = dp;
12401 s->binlen = 0;
12402 if (!(dp[0] == 'x' || dp[0] == 'X') || dp[1] != '\'' ||
12403 dp[dlen - 1] != '\'') {
12404 goto doCHAR;
12405 }
12406 dlen -= 2;
12407 dp += 2;
12408 dlen = dlen / 2;
12409 s->bincache = bin = xmalloc(dlen);
12410 if (!bin) {
12411 return nomem(s);
12412 }
12413 s->binlen = dlen;
12414 memset(s->bincache, 0, dlen);
12415 for (i = 0; i < dlen; i++) {
12416 char *x;
12417 int v;
12418
12419 if (!*dp || !(x = strchr(xdigits, *dp))) {
12420 goto converr;
12421 }
12422 v = x - xdigits;
12423 bin[i] = (v >= 16) ? ((v - 6) << 4) : (v << 4);
12424 ++dp;
12425 if (!*dp || !(x = strchr(xdigits, *dp))) {
12426 converr:
12427 freep(&s->bincache);
12428 s->binlen = 0;
12429 setstat(s, -1, "conversion error",
12430 (*s->ov3) ? "HY000" : "S1000");
12431 return SQL_ERROR;
12432 }
12433 v = x - xdigits;
12434 bin[i] |= (v >= 16) ? (v - 6) : v;
12435 ++dp;
12436 }
12437 bin = s->bincache;
12438 }
12439 if (partial && len && s->bindcols) {
12440 if (s->bindcols[col].offs >= dlen) {
12441 *lenp = 0;
12442 if (!dlen && s->bindcols[col].offs == dlen) {
12443 s->bindcols[col].offs = 1;
12444 sret = SQL_SUCCESS;
12445 goto done;
12446 }
12447 s->bindcols[col].offs = 0;
12448 sret = SQL_NO_DATA;
12449 goto done;
12450 }
12451 offs = s->bindcols[col].offs;
12452 dlen -= offs;
12453 }
12454 if (val && len) {
12455 memcpy(val, bin + offs, min(len, dlen));
12456 }
12457 if (len < 1) {
12458 *lenp = dlen;
12459 } else {
12460 *lenp = min(len, dlen);
12461 if (*lenp == len && *lenp != dlen) {
12462 *lenp = SQL_NO_TOTAL;
12463 }
12464 }
12465 if (partial && len && s->bindcols) {
12466 if (*lenp == SQL_NO_TOTAL) {
12467 *lenp = dlen;
12468 s->bindcols[col].offs += len;
12469 setstat(s, -1, "data right truncated", "01004");
12470 if (s->bindcols[col].lenp) {
12471 *s->bindcols[col].lenp = dlen;
12472 }
12473 sret = SQL_SUCCESS_WITH_INFO;
12474 goto done;
12475 }
12476 s->bindcols[col].offs += *lenp;
12477 }
12478 if (*lenp == SQL_NO_TOTAL) {
12479 *lenp = dlen;
12480 setstat(s, -1, "data right truncated", "01004");
12481 sret = SQL_SUCCESS_WITH_INFO;
12482 goto done;
12483 }
12484 break;
12485 }
12486 doCHAR:
12487 #ifdef WCHARSUPPORT
12488 case SQL_C_WCHAR:
12489 #endif
12490 case SQL_C_CHAR: {
12491 int doz, zlen = len - 1;
12492 int dlen = strlen(*data);
12493 int offs = 0;
12494 #ifdef WCHARSUPPORT
12495 SQLWCHAR *ucdata = NULL;
12496 SQLCHAR *cdata = (SQLCHAR *) *data;
12497 #endif
12498
12499 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
12500
12501 if (!valnull &&
12502 (s->cols == statSpec2P || s->cols == statSpec3P) &&
12503 type == SQL_C_WCHAR) {
12504 if (len > 0 && len <= sizeof (SQLWCHAR)) {
12505 ((char *) val)[0] = data[0][0];
12506 memset((char *) val + 1, 0, len - 1);
12507 *lenp = 1;
12508 sret = SQL_SUCCESS;
12509 goto done;
12510 }
12511 }
12512 #endif
12513
12514 #ifdef WCHARSUPPORT
12515 switch (type) {
12516 case SQL_C_CHAR:
12517 doz = 1;
12518 break;
12519 case SQL_C_WCHAR:
12520 doz = sizeof (SQLWCHAR);
12521 break;
12522 default:
12523 doz = 0;
12524 break;
12525 }
12526 if (type == SQL_C_WCHAR) {
12527 ucdata = uc_from_utf(cdata, dlen);
12528 if (!ucdata) {
12529 return nomem(s);
12530 }
12531 dlen = uc_strlen(ucdata) * sizeof (SQLWCHAR);
12532 }
12533 #if defined(_WIN32) || defined(_WIN64)
12534 else if (*s->oemcp && type == SQL_C_CHAR) {
12535 ucdata = (SQLWCHAR *) utf_to_wmb((char *) cdata, dlen);
12536 if (!ucdata) {
12537 return nomem(s);
12538 }
12539 cdata = (SQLCHAR *) ucdata;
12540 dlen = strlen((char *) cdata);
12541 }
12542 #endif
12543 #else
12544 doz = (type == SQL_C_CHAR) ? 1 : 0;
12545 #endif
12546 if (partial && len && s->bindcols) {
12547 if (s->bindcols[col].offs >= dlen) {
12548 #ifdef WCHARSUPPORT
12549 uc_free(ucdata);
12550 #endif
12551 *lenp = 0;
12552 if (doz && val) {
12553 #ifdef WCHARSUPPORT
12554 if (type == SQL_C_WCHAR) {
12555 ((SQLWCHAR *) val)[0] = 0;
12556 } else {
12557 ((char *) val)[0] = '\0';
12558 }
12559 #else
12560 ((char *) val)[0] = '\0';
12561 #endif
12562 }
12563 if (!dlen && s->bindcols[col].offs == dlen) {
12564 s->bindcols[col].offs = 1;
12565 sret = SQL_SUCCESS;
12566 goto done;
12567 }
12568 s->bindcols[col].offs = 0;
12569 sret = SQL_NO_DATA;
12570 goto done;
12571 }
12572 offs = s->bindcols[col].offs;
12573 dlen -= offs;
12574 }
12575 if (val && !valnull && len) {
12576 #ifdef WCHARSUPPORT
12577 if (type == SQL_C_WCHAR) {
12578 uc_strncpy(val, ucdata + offs / sizeof (SQLWCHAR),
12579 (len - doz) / sizeof (SQLWCHAR));
12580 } else {
12581 strncpy(val, (char *) cdata + offs, len - doz);
12582 }
12583 #else
12584 strncpy(val, *data + offs, len - doz);
12585 #endif
12586 }
12587 if (valnull || len < 1) {
12588 *lenp = dlen;
12589 } else {
12590 *lenp = min(len - doz, dlen);
12591 if (*lenp == len - doz && *lenp != dlen) {
12592 *lenp = SQL_NO_TOTAL;
12593 } else if (*lenp < zlen) {
12594 zlen = *lenp;
12595 }
12596 }
12597 if (len && !valnull && doz) {
12598 #ifdef WCHARSUPPORT
12599 if (type == SQL_C_WCHAR) {
12600 ((SQLWCHAR *) val)[zlen / sizeof (SQLWCHAR)] = 0;
12601 } else {
12602 ((char *) val)[zlen] = '\0';
12603 }
12604 #else
12605 ((char *) val)[zlen] = '\0';
12606 #endif
12607 }
12608 #ifdef WCHARSUPPORT
12609 uc_free(ucdata);
12610 #endif
12611 if (partial && len && s->bindcols) {
12612 if (*lenp == SQL_NO_TOTAL) {
12613 *lenp = dlen;
12614 s->bindcols[col].offs += len - doz;
12615 setstat(s, -1, "data right truncated", "01004");
12616 if (s->bindcols[col].lenp) {
12617 *s->bindcols[col].lenp = dlen;
12618 }
12619 sret = SQL_SUCCESS_WITH_INFO;
12620 goto done;
12621 }
12622 s->bindcols[col].offs += *lenp;
12623 }
12624 if (*lenp == SQL_NO_TOTAL) {
12625 *lenp = dlen;
12626 setstat(s, -1, "data right truncated", "01004");
12627 sret = SQL_SUCCESS_WITH_INFO;
12628 goto done;
12629 }
12630 break;
12631 }
12632 #ifdef SQL_C_TYPE_DATE
12633 case SQL_C_TYPE_DATE:
12634 #endif
12635 case SQL_C_DATE:
12636 if (str2date(*s->jdconv, *data, (DATE_STRUCT *) val) < 0) {
12637 *lenp = SQL_NULL_DATA;
12638 } else {
12639 *lenp = sizeof (DATE_STRUCT);
12640 }
12641 break;
12642 #ifdef SQL_C_TYPE_TIME
12643 case SQL_C_TYPE_TIME:
12644 #endif
12645 case SQL_C_TIME:
12646 if (str2time(*s->jdconv, *data, (TIME_STRUCT *) val) < 0) {
12647 *lenp = SQL_NULL_DATA;
12648 } else {
12649 *lenp = sizeof (TIME_STRUCT);
12650 }
12651 break;
12652 #ifdef SQL_C_TYPE_TIMESTAMP
12653 case SQL_C_TYPE_TIMESTAMP:
12654 #endif
12655 case SQL_C_TIMESTAMP:
12656 if (str2timestamp(*s->jdconv, *data,
12657 (TIMESTAMP_STRUCT *) val) < 0) {
12658 *lenp = SQL_NULL_DATA;
12659 } else {
12660 *lenp = sizeof (TIMESTAMP_STRUCT);
12661 }
12662 switch (s->cols[col].prec) {
12663 case 0:
12664 ((TIMESTAMP_STRUCT *) val)->fraction = 0;
12665 break;
12666 case 1:
12667 ((TIMESTAMP_STRUCT *) val)->fraction /= 100000000;
12668 ((TIMESTAMP_STRUCT *) val)->fraction *= 100000000;
12669 break;
12670 case 2:
12671 ((TIMESTAMP_STRUCT *) val)->fraction /= 10000000;
12672 ((TIMESTAMP_STRUCT *) val)->fraction *= 10000000;
12673 break;
12674 }
12675 break;
12676 default:
12677 return SQL_ERROR;
12678 }
12679 }
12680 sret = SQL_SUCCESS;
12681 done:
12682 if (ilenp) {
12683 *ilenp = *lenp;
12684 }
12685 return sret;
12686 }
12687
12699 static SQLRETURN
12700 drvbindcol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
12701 SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
12702 {
12703 STMT *s;
12704 int sz = 0;
12705
12706 if (stmt == SQL_NULL_HSTMT) {
12707 return SQL_INVALID_HANDLE;
12708 }
12709 s = (STMT *) stmt;
12710 if (col < 1) {
12711 if (col == 0 && s->bkmrk && type == SQL_C_BOOKMARK) {
12712 s->bkmrkcol.type = type;
12713 s->bkmrkcol.max = sizeof (SQLINTEGER);
12714 s->bkmrkcol.lenp = lenp;
12715 s->bkmrkcol.valp = val;
12716 s->bkmrkcol.offs = 0;
12717 if (lenp) {
12718 *lenp = 0;
12719 }
12720 return SQL_SUCCESS;
12721 }
12722 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
12723 return SQL_ERROR;
12724 }
12725 if (mkbindcols(s, col) != SQL_SUCCESS) {
12726 return SQL_ERROR;
12727 }
12728 --col;
12729 if (type == SQL_C_DEFAULT) {
12730 type = mapdeftype(type, s->cols[col].type, 0,
12731 s->nowchar[0] || s->nowchar[1]);
12732 }
12733 switch (type) {
12734 case SQL_C_LONG:
12735 case SQL_C_ULONG:
12736 case SQL_C_SLONG:
12737 sz = sizeof (SQLINTEGER);
12738 break;
12739 case SQL_C_TINYINT:
12740 case SQL_C_UTINYINT:
12741 case SQL_C_STINYINT:
12742 sz = sizeof (SQLCHAR);
12743 break;
12744 case SQL_C_SHORT:
12745 case SQL_C_USHORT:
12746 case SQL_C_SSHORT:
12747 sz = sizeof (SQLSMALLINT);
12748 break;
12749 case SQL_C_FLOAT:
12750 sz = sizeof (SQLFLOAT);
12751 break;
12752 case SQL_C_DOUBLE:
12753 sz = sizeof (SQLDOUBLE);
12754 break;
12755 case SQL_C_TIMESTAMP:
12756 sz = sizeof (SQL_TIMESTAMP_STRUCT);
12757 break;
12758 case SQL_C_TIME:
12759 sz = sizeof (SQL_TIME_STRUCT);
12760 break;
12761 case SQL_C_DATE:
12762 sz = sizeof (SQL_DATE_STRUCT);
12763 break;
12764 case SQL_C_CHAR:
12765 break;
12766 #ifdef WCHARSUPPORT
12767 case SQL_C_WCHAR:
12768 break;
12769 #endif
12770 #ifdef SQL_C_TYPE_DATE
12771 case SQL_C_TYPE_DATE:
12772 sz = sizeof (SQL_DATE_STRUCT);
12773 break;
12774 #endif
12775 #ifdef SQL_C_TYPE_TIME
12776 case SQL_C_TYPE_TIME:
12777 sz = sizeof (SQL_TIME_STRUCT);
12778 break;
12779 #endif
12780 #ifdef SQL_C_TYPE_TIMESTAMP
12781 case SQL_C_TYPE_TIMESTAMP:
12782 sz = sizeof (SQL_TIMESTAMP_STRUCT);
12783 break;
12784 #endif
12785 #ifdef SQL_BIT
12786 case SQL_C_BIT:
12787 sz = sizeof (SQLCHAR);
12788 break;
12789 #endif
12790 case SQL_C_BINARY:
12791 break;
12792 #ifdef SQL_BIGINT
12793 case SQL_C_SBIGINT:
12794 case SQL_C_UBIGINT:
12795 sz = sizeof (SQLBIGINT);
12796 break;
12797 #endif
12798 default:
12799 if (val == NULL) {
12800
12801 break;
12802 }
12803 setstat(s, -1, "invalid type %d", "HY003", type);
12804 return SQL_ERROR;
12805 }
12806 if (val == NULL) {
12807
12808 s->bindcols[col].type = -1;
12809 s->bindcols[col].max = 0;
12810 s->bindcols[col].lenp = NULL;
12811 s->bindcols[col].valp = NULL;
12812 s->bindcols[col].offs = 0;
12813 } else {
12814 if (sz == 0 && max < 0) {
12815 setstat(s, -1, "invalid length", "HY090");
12816 return SQL_ERROR;
12817 }
12818 s->bindcols[col].type = type;
12819 s->bindcols[col].max = (sz == 0) ? max : sz;
12820 s->bindcols[col].lenp = lenp;
12821 s->bindcols[col].valp = val;
12822 s->bindcols[col].offs = 0;
12823 if (lenp) {
12824 *lenp = 0;
12825 }
12826 }
12827 return SQL_SUCCESS;
12828 }
12829
12841 SQLRETURN SQL_API
12842 SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
12843 SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
12844 {
12845 SQLRETURN ret;
12846
12847 HSTMT_LOCK(stmt);
12848 ret = drvbindcol(stmt, col, type, val, max, lenp);
12849 HSTMT_UNLOCK(stmt);
12850 return ret;
12851 }
12852
12857 static COL tableSpec2[] = {
12858 { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
12859 { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
12860 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
12861 { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
12862 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
12863 };
12864
12865 static COL tableSpec3[] = {
12866 { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
12867 { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
12868 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
12869 { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
12870 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
12871 };
12872
12887 static SQLRETURN
12888 drvtables(SQLHSTMT stmt,
12889 SQLCHAR *cat, SQLSMALLINT catLen,
12890 SQLCHAR *schema, SQLSMALLINT schemaLen,
12891 SQLCHAR *table, SQLSMALLINT tableLen,
12892 SQLCHAR *type, SQLSMALLINT typeLen)
12893 {
12894 SQLRETURN ret;
12895 STMT *s;
12896 DBC *d;
12897 int ncols, asize, rc, size, npatt;
12898 char *errp = NULL, *sql, tname[512];
12899 char *where = "(type = 'table' or type = 'view')";
12900
12901 ret = mkresultset(stmt, tableSpec2, array_size(tableSpec2),
12902 tableSpec3, array_size(tableSpec3), &asize);
12903 if (ret != SQL_SUCCESS) {
12904 return ret;
12905 }
12906 s = (STMT *) stmt;
12907 d = (DBC *) s->dbc;
12908 if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] == '%') {
12909 int size = 3 * asize;
12910
12911 s->rows = xmalloc(size * sizeof (char *));
12912 if (!s->rows) {
12913 s->nrows = 0;
12914 return nomem(s);
12915 }
12916 memset(s->rows, 0, sizeof (char *) * size);
12917 s->ncols = asize;
12918 s->rows[s->ncols + 0] = "";
12919 s->rows[s->ncols + 1] = "";
12920 s->rows[s->ncols + 2] = "";
12921 s->rows[s->ncols + 3] = "TABLE";
12922 s->rows[s->ncols + 5] = "";
12923 s->rows[s->ncols + 6] = "";
12924 s->rows[s->ncols + 7] = "";
12925 s->rows[s->ncols + 8] = "VIEW";
12926 #ifdef MEMORY_DEBUG
12927 s->rowfree = xfree__;
12928 #else
12929 s->rowfree = sqlite3_free;
12930 #endif
12931 s->nrows = 2;
12932 s->rowp = -1;
12933 return SQL_SUCCESS;
12934 }
12935 if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
12936 table = NULL;
12937 goto doit;
12938 }
12939 if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
12940 schema[0] == '%') {
12941 if ((!cat || catLen == 0 || !cat[0]) &&
12942 (!table || tableLen == 0 || !table[0])) {
12943 table = NULL;
12944 goto doit;
12945 }
12946 }
12947 if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] != '\0') {
12948 char tmp[256], *t;
12949 int with_view = 0, with_table = 0;
12950
12951 if (typeLen == SQL_NTS) {
12952 strncpy(tmp, (char *) type, sizeof (tmp));
12953 tmp[sizeof (tmp) - 1] = '\0';
12954 } else {
12955 int len = min(sizeof (tmp) - 1, typeLen);
12956
12957 strncpy(tmp, (char *) type, len);
12958 tmp[len] = '\0';
12959 }
12960 t = tmp;
12961 while (*t) {
12962 *t = TOLOWER(*t);
12963 t++;
12964 }
12965 t = tmp;
12966 unescpat(t);
12967 while (t) {
12968 if (t[0] == '\'') {
12969 ++t;
12970 }
12971 if (strncmp(t, "table", 5) == 0) {
12972 with_table++;
12973 } else if (strncmp(t, "view", 4) == 0) {
12974 with_view++;
12975 }
12976 t = strchr(t, ',');
12977 if (t) {
12978 ++t;
12979 }
12980 }
12981 if (with_view && with_table) {
12982
12983 } else if (with_view && !with_table) {
12984 where = "type = 'view'";
12985 } else if (!with_view && with_table) {
12986 where = "type = 'table'";
12987 } else {
12988 return SQL_SUCCESS;
12989 }
12990 }
12991 doit:
12992 if (!table) {
12993 size = 1;
12994 tname[0] = '%';
12995 } else {
12996 if (tableLen == SQL_NTS) {
12997 size = sizeof (tname) - 1;
12998 } else {
12999 size = min(sizeof (tname) - 1, tableLen);
13000 }
13001 strncpy(tname, (char *) table, size);
13002 }
13003 tname[size] = '\0';
13004 npatt = unescpat(tname);
13005 #if defined(_WIN32) || defined(_WIN64)
13006 sql = sqlite3_mprintf("select %s as 'TABLE_QUALIFIER', "
13007 "%s as 'TABLE_OWNER', "
13008 "tbl_name as 'TABLE_NAME', "
13009 "upper(type) as 'TABLE_TYPE', "
13010 "NULL as 'REMARKS' "
13011 "from sqlite_master where %s "
13012 "and tbl_name %s %Q",
13013 d->xcelqrx ? "''" : "NULL",
13014 d->xcelqrx ? "'main'" : "NULL",
13015 where,
13016 npatt ? "like" : "=", tname);
13017 #else
13018 sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
13019 "NULL as 'TABLE_OWNER', "
13020 "tbl_name as 'TABLE_NAME', "
13021 "upper(type) as 'TABLE_TYPE', "
13022 "NULL as 'REMARKS' "
13023 "from sqlite_master where %s "
13024 "and tbl_name %s %Q", where,
13025 npatt ? "like" : "=", tname);
13026 #endif
13027 if (!sql) {
13028 return nomem(s);
13029 }
13030 ret = starttran(s);
13031 if (ret != SQL_SUCCESS) {
13032 sqlite3_free(sql);
13033 return ret;
13034 }
13035 dbtraceapi(d, "sqlite3_get_table", sql);
13036 rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
13037 sqlite3_free(sql);
13038 if (rc == SQLITE_OK) {
13039 if (ncols != s->ncols) {
13040 freeresult(s, 0);
13041 s->nrows = 0;
13042 } else {
13043 s->rowfree = sqlite3_free_table;
13044 }
13045 } else {
13046 s->nrows = 0;
13047 s->rows = NULL;
13048 s->rowfree = NULL;
13049 }
13050 if (errp) {
13051 sqlite3_free(errp);
13052 errp = NULL;
13053 }
13054 s->rowp = -1;
13055 return SQL_SUCCESS;
13056 }
13057
13058 #ifndef WINTERFACE
13059
13073 SQLRETURN SQL_API
13074 SQLTables(SQLHSTMT stmt,
13075 SQLCHAR *cat, SQLSMALLINT catLen,
13076 SQLCHAR *schema, SQLSMALLINT schemaLen,
13077 SQLCHAR *table, SQLSMALLINT tableLen,
13078 SQLCHAR *type, SQLSMALLINT typeLen)
13079 {
13080 #if defined(_WIN32) || defined(_WIN64)
13081 char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
13082 #endif
13083 SQLRETURN ret;
13084
13085 HSTMT_LOCK(stmt);
13086 #if defined(_WIN32) || defined(_WIN64)
13087 if (!((STMT *) stmt)->oemcp[0]) {
13088 ret = drvtables(stmt, cat, catLen, schema, schemaLen,
13089 table, tableLen, type, typeLen);
13090 goto done2;
13091 }
13092 if (cat) {
13093 c = wmb_to_utf_c((char *) cat, catLen);
13094 if (!c) {
13095 ret = nomem((STMT *) stmt);
13096 goto done;
13097 }
13098 }
13099 if (schema) {
13100 s = wmb_to_utf_c((char *) schema, schemaLen);
13101 if (!s) {
13102 ret = nomem((STMT *) stmt);
13103 goto done;
13104 }
13105 }
13106 if (table) {
13107 t = wmb_to_utf_c((char *) table, tableLen);
13108 if (!t) {
13109 ret = nomem((STMT *) stmt);
13110 goto done;
13111 }
13112 }
13113 if (type) {
13114 y = wmb_to_utf_c((char *) type, typeLen);
13115 if (!y) {
13116 ret = nomem((STMT *) stmt);
13117 goto done;
13118 }
13119 }
13120 ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
13121 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
13122 #else
13123 ret = drvtables(stmt, cat, catLen, schema, schemaLen,
13124 table, tableLen, type, typeLen);
13125 #endif
13126 #if defined(_WIN32) || defined(_WIN64)
13127 done:
13128 uc_free(y);
13129 uc_free(t);
13130 uc_free(s);
13131 uc_free(c);
13132 done2:
13133 ;
13134 #endif
13135 HSTMT_UNLOCK(stmt);
13136 return ret;
13137 }
13138 #endif
13139
13140 #ifdef WINTERFACE
13141
13155 SQLRETURN SQL_API
13156 SQLTablesW(SQLHSTMT stmt,
13157 SQLWCHAR *cat, SQLSMALLINT catLen,
13158 SQLWCHAR *schema, SQLSMALLINT schemaLen,
13159 SQLWCHAR *table, SQLSMALLINT tableLen,
13160 SQLWCHAR *type, SQLSMALLINT typeLen)
13161 {
13162 char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
13163 SQLRETURN ret;
13164
13165 HSTMT_LOCK(stmt);
13166 if (cat) {
13167 c = uc_to_utf_c(cat, catLen);
13168 if (!c) {
13169 ret = nomem((STMT *) stmt);
13170 goto done;
13171 }
13172 }
13173 if (schema) {
13174 s = uc_to_utf_c(schema, schemaLen);
13175 if (!s) {
13176 ret = nomem((STMT *) stmt);
13177 goto done;
13178 }
13179 }
13180 if (table) {
13181 t = uc_to_utf_c(table, tableLen);
13182 if (!t) {
13183 ret = nomem((STMT *) stmt);
13184 goto done;
13185 }
13186 }
13187 if (type) {
13188 y = uc_to_utf_c(type, typeLen);
13189 if (!y) {
13190 ret = nomem((STMT *) stmt);
13191 goto done;
13192 }
13193 }
13194 ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
13195 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
13196 done:
13197 uc_free(y);
13198 uc_free(t);
13199 uc_free(s);
13200 uc_free(c);
13201 HSTMT_UNLOCK(stmt);
13202 return ret;
13203 }
13204 #endif
13205
13210 static COL colSpec2[] = {
13211 { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
13212 { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
13213 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
13214 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
13215 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
13216 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
13217 { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
13218 { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
13219 { "SYSTEM", "COLUMN", "SCALE", SQL_SMALLINT, 50 },
13220 { "SYSTEM", "COLUMN", "RADIX", SQL_SMALLINT, 50 },
13221 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
13222 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
13223 { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
13224 { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
13225 { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
13226 { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
13227 { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
13228 { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
13229 };
13230
13231 static COL colSpec3[] = {
13232 { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
13233 { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
13234 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
13235 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
13236 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
13237 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
13238 { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
13239 { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
13240 { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_SMALLINT, 50 },
13241 { "SYSTEM", "COLUMN", "NUM_PREC_RADIX", SQL_SMALLINT, 50 },
13242 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
13243 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
13244 { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
13245 { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
13246 { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
13247 { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
13248 { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
13249 { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
13250 };
13251
13266 static SQLRETURN
13267 drvcolumns(SQLHSTMT stmt,
13268 SQLCHAR *cat, SQLSMALLINT catLen,
13269 SQLCHAR *schema, SQLSMALLINT schemaLen,
13270 SQLCHAR *table, SQLSMALLINT tableLen,
13271 SQLCHAR *col, SQLSMALLINT colLen)
13272 {
13273 SQLRETURN sret;
13274 STMT *s;
13275 DBC *d;
13276 int ret, nrows, ncols, asize, i, k, roffs, namec;
13277 int tnrows, tncols, npatt;
13278 PTRDIFF_T size;
13279 char *errp = NULL, *sql, tname[512], cname[512], **rowp, **trows;
13280
13281 sret = mkresultset(stmt, colSpec2, array_size(colSpec2),
13282 colSpec3, array_size(colSpec3), &asize);
13283 if (sret != SQL_SUCCESS) {
13284 return sret;
13285 }
13286 s = (STMT *) stmt;
13287 d = (DBC *) s->dbc;
13288 if (!table) {
13289 size = 1;
13290 tname[0] = '%';
13291 } else {
13292 if (tableLen == SQL_NTS) {
13293 size = sizeof (tname) - 1;
13294 } else {
13295 size = min(sizeof (tname) - 1, tableLen);
13296 }
13297 strncpy(tname, (char *) table, size);
13298 }
13299 tname[size] = '\0';
13300 npatt = unescpat(tname);
13301 size = 0;
13302 if (col) {
13303 if (colLen == SQL_NTS) {
13304 size = sizeof (cname) - 1;
13305 } else {
13306 size = min(sizeof (cname) - 1, colLen);
13307 }
13308 strncpy(cname, (char *) col, size);
13309 }
13310 cname[size] = '\0';
13311 if (!strcmp(cname, "%")) {
13312 cname[0] = '\0';
13313 }
13314 sql = sqlite3_mprintf("select tbl_name from sqlite_master where "
13315 "(type = 'table' or type = 'view') "
13316 "and tbl_name %s %Q", npatt ? "like" : "=", tname);
13317 if (!sql) {
13318 return nomem(s);
13319 }
13320 sret = starttran(s);
13321 if (sret != SQL_SUCCESS) {
13322 sqlite3_free(sql);
13323 return sret;
13324 }
13325 dbtraceapi(d, "sqlite3_get_table", sql);
13326 ret = sqlite3_get_table(d->sqlite, sql, &trows, &tnrows, &tncols, &errp);
13327 sqlite3_free(sql);
13328 if (ret != SQLITE_OK) {
13329 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
13330 errp ? errp : "unknown error", ret);
13331 if (errp) {
13332 sqlite3_free(errp);
13333 errp = NULL;
13334 }
13335 return SQL_ERROR;
13336 }
13337 if (errp) {
13338 sqlite3_free(errp);
13339 errp = NULL;
13340 }
13341
13342 if (tncols * tnrows <= 0) {
13343 sqlite3_free_table(trows);
13344 return SQL_SUCCESS;
13345 }
13346 size = 0;
13347 for (i = 1; i <= tnrows; i++) {
13348 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
13349 if (!sql) {
13350 sqlite3_free_table(trows);
13351 return nomem(s);
13352 }
13353 dbtraceapi(d, "sqlite3_get_table", sql);
13354 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
13355 sqlite3_free(sql);
13356 if (ret != SQLITE_OK) {
13357 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
13358 errp ? errp : "unknown error", ret);
13359 if (errp) {
13360 sqlite3_free(errp);
13361 errp = NULL;
13362 }
13363 sqlite3_free_table(trows);
13364 return SQL_ERROR;
13365 }
13366 if (errp) {
13367 sqlite3_free(errp);
13368 errp = NULL;
13369 }
13370 if (ncols * nrows > 0) {
13371 namec = -1;
13372 for (k = 0; k < ncols; k++) {
13373 if (strcmp(rowp[k], "name") == 0) {
13374 namec = k;
13375 break;
13376 }
13377 }
13378 if (cname[0]) {
13379 if (namec >= 0) {
13380 for (k = 1; k <= nrows; k++) {
13381 if (namematch(rowp[k * ncols + namec], cname, 1)) {
13382 size++;
13383 }
13384 }
13385 }
13386 } else {
13387 size += nrows;
13388 }
13389 }
13390 sqlite3_free_table(rowp);
13391 }
13392
13393 if (size <= 0) {
13394 sqlite3_free_table(trows);
13395 return SQL_SUCCESS;
13396 }
13397 s->nrows = size;
13398 size = (size + 1) * asize;
13399 s->rows = xmalloc((size + 1) * sizeof (char *));
13400 if (!s->rows) {
13401 s->nrows = 0;
13402 sqlite3_free_table(trows);
13403 return nomem(s);
13404 }
13405 s->rows[0] = (char *) size;
13406 s->rows += 1;
13407 memset(s->rows, 0, sizeof (char *) * size);
13408 s->rowfree = freerows;
13409 roffs = 1;
13410 for (i = 1; i <= tnrows; i++) {
13411 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
13412 if (!sql) {
13413 sqlite3_free_table(trows);
13414 return nomem(s);
13415 }
13416 dbtraceapi(d, "sqlite3_get_table", sql);
13417 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
13418 sqlite3_free(sql);
13419 if (ret != SQLITE_OK) {
13420 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
13421 errp ? errp : "unknown error", ret);
13422 if (errp) {
13423 sqlite3_free(errp);
13424 errp = NULL;
13425 }
13426 sqlite3_free_table(trows);
13427 return SQL_ERROR;
13428 }
13429 if (errp) {
13430 sqlite3_free(errp);
13431 errp = NULL;
13432 }
13433 if (ncols * nrows > 0) {
13434 int m, mr, nr = nrows;
13435
13436 namec = -1;
13437 for (k = 0; k < ncols; k++) {
13438 if (strcmp(rowp[k], "name") == 0) {
13439 namec = k;
13440 break;
13441 }
13442 }
13443 if (cname[0]) {
13444 nr = 0;
13445 if (namec >= 0) {
13446 for (k = 1; k <= nrows; k++) {
13447 if (namematch(rowp[k * ncols + namec], cname, 1)) {
13448 nr++;
13449 }
13450 }
13451 }
13452 }
13453 for (k = 0; k < nr; k++) {
13454 m = asize * (roffs + k);
13455 s->rows[m + 0] = xstrdup("");
13456 #if defined(_WIN32) || defined(_WIN64)
13457 s->rows[m + 1] = xstrdup(d->xcelqrx ? "main" : "");
13458 #else
13459 s->rows[m + 1] = xstrdup("");
13460 #endif
13461 s->rows[m + 2] = xstrdup(trows[i]);
13462 s->rows[m + 8] = xstrdup("10");
13463 s->rows[m + 9] = xstrdup("0");
13464 s->rows[m + 15] = xstrdup("16384");
13465 }
13466 for (k = 0; nr && k < ncols; k++) {
13467 if (strcmp(rowp[k], "cid") == 0) {
13468 for (mr = 0, m = 1; m <= nrows; m++) {
13469 char buf[256];
13470 int ir, coln = k;
13471
13472 if (cname[0] &&
13473 !namematch(rowp[m * ncols + namec], cname, 1)) {
13474 continue;
13475 }
13476 ir = asize * (roffs + mr);
13477 sscanf(rowp[m * ncols + k], "%d", &coln);
13478 sprintf(buf, "%d", coln + 1);
13479 s->rows[ir + 16] = xstrdup(buf);
13480 ++mr;
13481 }
13482 } else if (k == namec) {
13483 for (mr = 0, m = 1; m <= nrows; m++) {
13484 int ir;
13485
13486 if (cname[0] &&
13487 !namematch(rowp[m * ncols + namec], cname, 1)) {
13488 continue;
13489 }
13490 ir = asize * (roffs + mr);
13491 s->rows[ir + 3] = xstrdup(rowp[m * ncols + k]);
13492 ++mr;
13493 }
13494 } else if (strcmp(rowp[k], "notnull") == 0) {
13495 for (mr = 0, m = 1; m <= nrows; m++) {
13496 int ir;
13497
13498 if (cname[0] &&
13499 !namematch(rowp[m * ncols + namec], cname, 1)) {
13500 continue;
13501 }
13502 ir = asize * (roffs + mr);
13503 if (*rowp[m * ncols + k] != '0') {
13504 s->rows[ir + 10] = xstrdup(stringify(SQL_FALSE));
13505 } else {
13506 s->rows[ir + 10] = xstrdup(stringify(SQL_TRUE));
13507 }
13508 s->rows[ir + 17] =
13509 xstrdup((*rowp[m * ncols + k] != '0') ?
13510 "NO" : "YES");
13511 ++mr;
13512 }
13513 } else if (strcmp(rowp[k], "dflt_value") == 0) {
13514 for (mr = 0, m = 1; m <= nrows; m++) {
13515 char *dflt = unquote(rowp[m * ncols + k]);
13516 int ir;
13517
13518 if (cname[0] &&
13519 !namematch(rowp[m * ncols + namec], cname, 1)) {
13520 continue;
13521 }
13522 ir = asize * (roffs + mr);
13523 s->rows[ir + 12] = xstrdup(dflt ? dflt : "NULL");
13524 ++mr;
13525 }
13526 } else if (strcmp(rowp[k], "type") == 0) {
13527 for (mr = 0, m = 1; m <= nrows; m++) {
13528 char *typename = rowp[m * ncols + k];
13529 int sqltype, mm, dd, ir;
13530 char buf[256];
13531
13532 if (cname[0] &&
13533 !namematch(rowp[m * ncols + namec], cname, 1)) {
13534 continue;
13535 }
13536 ir = asize * (roffs + mr);
13537 s->rows[ir + 5] = xstrdup(typename);
13538 sqltype = mapsqltype(typename, NULL, *s->ov3,
13539 s->nowchar[0], s->dobigint);
13540 getmd(typename, sqltype, &mm, &dd);
13541 #ifdef SQL_LONGVARCHAR
13542 if (sqltype == SQL_VARCHAR && mm > 255) {
13543 sqltype = SQL_LONGVARCHAR;
13544 }
13545 #endif
13546 #ifdef WINTERFACE
13547 #ifdef SQL_WLONGVARCHAR
13548 if (sqltype == SQL_WVARCHAR && mm > 255) {
13549 sqltype = SQL_WLONGVARCHAR;
13550 }
13551 #endif
13552 #endif
13553 if (sqltype == SQL_VARBINARY && mm > 255) {
13554 sqltype = SQL_LONGVARBINARY;
13555 }
13556 sprintf(buf, "%d", sqltype);
13557 s->rows[ir + 4] = xstrdup(buf);
13558 s->rows[ir + 13] = xstrdup(buf);
13559 sprintf(buf, "%d", mm);
13560 s->rows[ir + 7] = xstrdup(buf);
13561 sprintf(buf, "%d", dd);
13562 s->rows[ir + 6] = xstrdup(buf);
13563 ++mr;
13564 }
13565 }
13566 }
13567 roffs += nr;
13568 }
13569 sqlite3_free_table(rowp);
13570 }
13571 sqlite3_free_table(trows);
13572 return SQL_SUCCESS;
13573 }
13574
13575 #ifndef WINTERFACE
13576
13590 SQLRETURN SQL_API
13591 SQLColumns(SQLHSTMT stmt,
13592 SQLCHAR *cat, SQLSMALLINT catLen,
13593 SQLCHAR *schema, SQLSMALLINT schemaLen,
13594 SQLCHAR *table, SQLSMALLINT tableLen,
13595 SQLCHAR *col, SQLSMALLINT colLen)
13596 {
13597 #if defined(_WIN32) || defined(_WIN64)
13598 char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
13599 #endif
13600 SQLRETURN ret;
13601
13602 HSTMT_LOCK(stmt);
13603 #if defined(_WIN32) || defined(_WIN64)
13604 if (!((STMT *) stmt)->oemcp[0]) {
13605 ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
13606 table, tableLen, col, colLen);
13607 goto done2;
13608 }
13609 if (cat) {
13610 c = wmb_to_utf_c((char *) cat, catLen);
13611 if (!c) {
13612 ret = nomem((STMT *) stmt);
13613 goto done;
13614 }
13615 }
13616 if (schema) {
13617 s = wmb_to_utf_c((char *) schema, schemaLen);
13618 if (!s) {
13619 ret = nomem((STMT *) stmt);
13620 goto done;
13621 }
13622 }
13623 if (table) {
13624 t = wmb_to_utf_c((char *) table, tableLen);
13625 if (!t) {
13626 ret = nomem((STMT *) stmt);
13627 goto done;
13628 }
13629 }
13630 if (col) {
13631 k = wmb_to_utf_c((char *) col, colLen);
13632 if (!k) {
13633 ret = nomem((STMT *) stmt);
13634 goto done;
13635 }
13636 }
13637 ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
13638 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
13639 #else
13640 ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
13641 table, tableLen, col, colLen);
13642 #endif
13643 #if defined(_WIN32) || defined(_WIN64)
13644 done:
13645 uc_free(k);
13646 uc_free(t);
13647 uc_free(s);
13648 uc_free(c);
13649 done2:
13650 ;
13651 #endif
13652 HSTMT_UNLOCK(stmt);
13653 return ret;
13654 }
13655 #endif
13656
13657 #ifdef WINTERFACE
13658
13672 SQLRETURN SQL_API
13673 SQLColumnsW(SQLHSTMT stmt,
13674 SQLWCHAR *cat, SQLSMALLINT catLen,
13675 SQLWCHAR *schema, SQLSMALLINT schemaLen,
13676 SQLWCHAR *table, SQLSMALLINT tableLen,
13677 SQLWCHAR *col, SQLSMALLINT colLen)
13678 {
13679 char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
13680 SQLRETURN ret;
13681
13682 HSTMT_LOCK(stmt);
13683 if (cat) {
13684 c = uc_to_utf_c(cat, catLen);
13685 if (!c) {
13686 ret = nomem((STMT *) stmt);
13687 goto done;
13688 }
13689 }
13690 if (schema) {
13691 s = uc_to_utf_c(schema, schemaLen);
13692 if (!s) {
13693 ret = nomem((STMT *) stmt);
13694 goto done;
13695 }
13696 }
13697 if (table) {
13698 t = uc_to_utf_c(table, tableLen);
13699 if (!t) {
13700 ret = nomem((STMT *) stmt);
13701 goto done;
13702 }
13703 }
13704 if (col) {
13705 k = uc_to_utf_c(col, colLen);
13706 if (!k) {
13707 ret = nomem((STMT *) stmt);
13708 goto done;
13709 }
13710 }
13711 ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
13712 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
13713 done:
13714 uc_free(k);
13715 uc_free(t);
13716 uc_free(s);
13717 uc_free(c);
13718 HSTMT_UNLOCK(stmt);
13719 return ret;
13720
13721 }
13722 #endif
13723
13728 static COL typeSpec2[] = {
13729 { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
13730 { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
13731 { "SYSTEM", "TYPE", "PRECISION", SQL_INTEGER, 9 },
13732 { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
13733 { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
13734 { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
13735 { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
13736 { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
13737 { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
13738 { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
13739 { "SYSTEM", "TYPE", "MONEY", SQL_SMALLINT, 2 },
13740 { "SYSTEM", "TYPE", "AUTO_INCREMENT", SQL_SMALLINT, 2 },
13741 { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
13742 { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
13743 { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 }
13744 };
13745
13746 static COL typeSpec3[] = {
13747 { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
13748 { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
13749 { "SYSTEM", "TYPE", "COLUMN_SIZE", SQL_INTEGER, 9 },
13750 { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
13751 { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
13752 { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
13753 { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
13754 { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
13755 { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
13756 { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
13757 { "SYSTEM", "TYPE", "FIXED_PREC_SCALE", SQL_SMALLINT, 2 },
13758 { "SYSTEM", "TYPE", "AUTO_UNIQUE_VALUE", SQL_SMALLINT, 2 },
13759 { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
13760 { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
13761 { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 },
13762 { "SYSTEM", "TYPE", "SQL_DATA_TYPE", SQL_SMALLINT, 2 },
13763 { "SYSTEM", "TYPE", "SQL_DATETIME_SUB", SQL_SMALLINT, 2 },
13764 { "SYSTEM", "TYPE", "NUM_PREC_RADIX", SQL_INTEGER, 4 },
13765 { "SYSTEM", "TYPE", "INTERVAL_PRECISION", SQL_SMALLINT, 2 }
13766 };
13767
13778 static void
13779 mktypeinfo(STMT *s, int row, int asize, char *typename, int type, int tind)
13780 {
13781 int offs = row * asize;
13782 char *tcode, *crpar = NULL, *quote = NULL, *sign = stringify(SQL_FALSE);
13783 static char tcodes[32 * 32];
13784
13785 if (tind <= 0) {
13786 tind = row;
13787 }
13788 tcode = tcodes + tind * 32;
13789 sprintf(tcode, "%d", type);
13790 s->rows[offs + 0] = typename;
13791 s->rows[offs + 1] = tcode;
13792 if (asize >= 17) {
13793 s->rows[offs + 15] = tcode;
13794 s->rows[offs + 16] = "0";
13795 }
13796 switch (type) {
13797 default:
13798 #ifdef SQL_LONGVARCHAR
13799 case SQL_LONGVARCHAR:
13800 #ifdef WINTERFACE
13801 case SQL_WLONGVARCHAR:
13802 #endif
13803 crpar = "length";
13804 quote = "'";
13805 sign = NULL;
13806 s->rows[offs + 2] = "65536";
13807 break;
13808 #endif
13809 #ifdef SQL_BIT
13810 case SQL_BIT:
13811 sign = NULL;
13812 s->rows[offs + 2] = "1";
13813 break;
13814 #endif
13815 case SQL_CHAR:
13816 case SQL_VARCHAR:
13817 #ifdef WINTERFACE
13818 case SQL_WCHAR:
13819 case SQL_WVARCHAR:
13820 #endif
13821 s->rows[offs + 2] = "255";
13822 crpar = "length";
13823 quote = "'";
13824 sign = NULL;
13825 break;
13826 case SQL_TINYINT:
13827 s->rows[offs + 2] = "3";
13828 break;
13829 case SQL_SMALLINT:
13830 s->rows[offs + 2] = "5";
13831 break;
13832 case SQL_INTEGER:
13833 s->rows[offs + 2] = "9";
13834 break;
13835 #ifdef SQL_BIGINT
13836 case SQL_BIGINT:
13837 s->rows[offs + 2] = "19";
13838 break;
13839 #endif
13840 case SQL_FLOAT:
13841 s->rows[offs + 2] = "7";
13842 break;
13843 case SQL_DOUBLE:
13844 s->rows[offs + 2] = "15";
13845 break;
13846 #ifdef SQL_TYPE_DATE
13847 case SQL_TYPE_DATE:
13848 #endif
13849 case SQL_DATE:
13850 s->rows[offs + 2] = "10";
13851 quote = "'";
13852 sign = NULL;
13853 break;
13854 #ifdef SQL_TYPE_TIME
13855 case SQL_TYPE_TIME:
13856 #endif
13857 case SQL_TIME:
13858 s->rows[offs + 2] = "8";
13859 quote = "'";
13860 sign = NULL;
13861 break;
13862 #ifdef SQL_TYPE_TIMESTAMP
13863 case SQL_TYPE_TIMESTAMP:
13864 #endif
13865 case SQL_TIMESTAMP:
13866 s->rows[offs + 2] = "32";
13867 quote = "'";
13868 sign = NULL;
13869 break;
13870 case SQL_VARBINARY:
13871 sign = NULL;
13872 s->rows[offs + 2] = "255";
13873 break;
13874 case SQL_LONGVARBINARY:
13875 sign = NULL;
13876 s->rows[offs + 2] = "65536";
13877 break;
13878 }
13879 s->rows[offs + 3] = s->rows[offs + 4] = quote;
13880 s->rows[offs + 5] = crpar;
13881 s->rows[offs + 6] = stringify(SQL_NULLABLE);
13882 s->rows[offs + 7] = stringify(SQL_FALSE);
13883 s->rows[offs + 8] = stringify(SQL_SEARCHABLE);
13884 s->rows[offs + 9] = sign;
13885 s->rows[offs + 10] = stringify(SQL_FALSE);
13886 s->rows[offs + 11] = stringify(SQL_FALSE);
13887 s->rows[offs + 12] = typename;
13888 switch (type) {
13889 case SQL_DATE:
13890 case SQL_TIME:
13891 s->rows[offs + 13] = "0";
13892 s->rows[offs + 14] = "0";
13893 break;
13894 #ifdef SQL_TYPE_TIMESTAMP
13895 case SQL_TYPE_TIMESTAMP:
13896 #endif
13897 case SQL_TIMESTAMP:
13898 s->rows[offs + 13] = "0";
13899 s->rows[offs + 14] = "3";
13900 break;
13901 default:
13902 s->rows[offs + 13] = NULL;
13903 s->rows[offs + 14] = NULL;
13904 break;
13905 }
13906 }
13907
13916 static int
13917 typeinfosort(const void *a, const void *b)
13918 {
13919 char **pa = (char **) a;
13920 char **pb = (char **) b;
13921 int na, nb;
13922
13923 na = strtol(pa[1], NULL, 0);
13924 nb = strtol(pb[1], NULL, 0);
13925 return na - nb;
13926 }
13927
13935 static SQLRETURN
13936 drvgettypeinfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
13937 {
13938 SQLRETURN ret;
13939 STMT *s;
13940 int asize;
13941
13942 ret = mkresultset(stmt, typeSpec2, array_size(typeSpec2),
13943 typeSpec3, array_size(typeSpec3), &asize);
13944 if (ret != SQL_SUCCESS) {
13945 return ret;
13946 }
13947 s = (STMT *) stmt;
13948 #ifdef SQL_LONGVARCHAR
13949 s->nrows = (sqltype == SQL_ALL_TYPES) ? 13 : 1;
13950 #else
13951 s->nrows = (sqltype == SQL_ALL_TYPES) ? 12 : 1;
13952 #endif
13953 if (sqltype == SQL_ALL_TYPES) {
13954 #ifdef WINTERFACE
13955 s->nrows += 2;
13956 #ifdef SQL_WLONGVARCHAR
13957 s->nrows += 2;
13958 #endif
13959 #endif
13960 }
13961 if (sqltype == SQL_ALL_TYPES) {
13962 s->nrows += 2;
13963 #ifdef SQL_BIT
13964 s->nrows += 1;
13965 #endif
13966 #ifdef SQL_BIGINT
13967 s->nrows += 1;
13968 #endif
13969 }
13970 s->rows = (char **) xmalloc(sizeof (char *) * (s->nrows + 1) * asize);
13971 if (!s->rows) {
13972 s->nrows = 0;
13973 return nomem(s);
13974 }
13975 #ifdef MEMORY_DEBUG
13976 s->rowfree = xfree__;
13977 #else
13978 s->rowfree = sqlite3_free;
13979 #endif
13980 memset(s->rows, 0, sizeof (char *) * (s->nrows + 1) * asize);
13981 if (sqltype == SQL_ALL_TYPES) {
13982 int cc = 1;
13983
13984 mktypeinfo(s, cc++, asize, "varchar", SQL_VARCHAR, 0);
13985 mktypeinfo(s, cc++, asize, "tinyint", SQL_TINYINT, 0);
13986 mktypeinfo(s, cc++, asize, "smallint", SQL_SMALLINT, 0);
13987 mktypeinfo(s, cc++, asize, "integer", SQL_INTEGER, 0);
13988 mktypeinfo(s, cc++, asize, "float", SQL_FLOAT, 0);
13989 mktypeinfo(s, cc++, asize, "double", SQL_DOUBLE, 0);
13990 #ifdef SQL_TYPE_DATE
13991 mktypeinfo(s, cc++, asize, "date",
13992 (*s->ov3) ? SQL_TYPE_DATE : SQL_DATE, 0);
13993 #else
13994 mktypeinfo(s, cc++, asize, "date", SQL_DATE, 0);
13995 #endif
13996 #ifdef SQL_TYPE_TIME
13997 mktypeinfo(s, cc++, asize, "time",
13998 (*s->ov3) ? SQL_TYPE_TIME : SQL_TIME, 0);
13999 #else
14000 mktypeinfo(s, cc++, asize, "time", SQL_TIME, 0);
14001 #endif
14002 #ifdef SQL_TYPE_TIMESTAMP
14003 mktypeinfo(s, cc++, asize, "timestamp",
14004 (*s->ov3) ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP, 0);
14005 #else
14006 mktypeinfo(s, cc++, asize, "timestamp", SQL_TIMESTAMP, 0);
14007 #endif
14008 mktypeinfo(s, cc++, asize, "char", SQL_CHAR, 0);
14009 mktypeinfo(s, cc++, asize, "numeric", SQL_DOUBLE, 0);
14010 #ifdef SQL_LONGVARCHAR
14011 mktypeinfo(s, cc++, asize, "text", SQL_LONGVARCHAR, 0);
14012 mktypeinfo(s, cc++, asize, "longvarchar", SQL_LONGVARCHAR, 0);
14013 #else
14014 mktypeinfo(s, cc++, asize, "text", SQL_VARCHAR, 0);
14015 #endif
14016 mktypeinfo(s, cc++, asize, "varbinary", SQL_VARBINARY, 0);
14017 mktypeinfo(s, cc++, asize, "longvarbinary", SQL_LONGVARBINARY, 0);
14018 #ifdef SQL_BIT
14019 mktypeinfo(s, cc++, asize, "bit", SQL_BIT, 0);
14020 #endif
14021 #ifdef SQL_BIGINT
14022 mktypeinfo(s, cc++, asize, "bigint", SQL_BIGINT, 0);
14023 #endif
14024 #ifdef WINTERFACE
14025 mktypeinfo(s, cc++, asize, "wvarchar", SQL_WVARCHAR, 0);
14026 mktypeinfo(s, cc++, asize, "wchar", SQL_WCHAR, 0);
14027 #ifdef SQL_WLONGVARCHAR
14028 mktypeinfo(s, cc++, asize, "wtext", SQL_WLONGVARCHAR, 0);
14029 mktypeinfo(s, cc++, asize, "longwvarchar", SQL_WLONGVARCHAR, 0);
14030 #endif
14031 #endif
14032 qsort(s->rows + asize, s->nrows, sizeof (char *) * asize,
14033 typeinfosort);
14034 } else {
14035 switch (sqltype) {
14036 case SQL_CHAR:
14037 mktypeinfo(s, 1, asize, "char", SQL_CHAR, 10);
14038 break;
14039 case SQL_VARCHAR:
14040 mktypeinfo(s, 1, asize, "varchar", SQL_VARCHAR, 1);
14041 break;
14042 case SQL_TINYINT:
14043 mktypeinfo(s, 1, asize, "tinyint", SQL_TINYINT, 2);
14044 break;
14045 case SQL_SMALLINT:
14046 mktypeinfo(s, 1, asize, "smallint", SQL_SMALLINT, 3);
14047 break;
14048 case SQL_INTEGER:
14049 mktypeinfo(s, 1, asize, "integer", SQL_INTEGER, 4);
14050 break;
14051 case SQL_FLOAT:
14052 mktypeinfo(s, 1, asize, "float", SQL_FLOAT, 5);
14053 break;
14054 case SQL_DOUBLE:
14055 mktypeinfo(s, 1, asize, "double", SQL_DOUBLE, 6);
14056 break;
14057 #ifdef SQL_TYPE_DATE
14058 case SQL_TYPE_DATE:
14059 mktypeinfo(s, 1, asize, "date", SQL_TYPE_DATE, 25);
14060 break;
14061 #endif
14062 case SQL_DATE:
14063 mktypeinfo(s, 1, asize, "date", SQL_DATE, 7);
14064 break;
14065 #ifdef SQL_TYPE_TIME
14066 case SQL_TYPE_TIME:
14067 mktypeinfo(s, 1, asize, "time", SQL_TYPE_TIME, 26);
14068 break;
14069 #endif
14070 case SQL_TIME:
14071 mktypeinfo(s, 1, asize, "time", SQL_TIME, 8);
14072 break;
14073 #ifdef SQL_TYPE_TIMESTAMP
14074 case SQL_TYPE_TIMESTAMP:
14075 mktypeinfo(s, 1, asize, "timestamp", SQL_TYPE_TIMESTAMP, 27);
14076 break;
14077 #endif
14078 case SQL_TIMESTAMP:
14079 mktypeinfo(s, 1, asize, "timestamp", SQL_TIMESTAMP, 9);
14080 break;
14081 #ifdef SQL_LONGVARCHAR
14082 case SQL_LONGVARCHAR:
14083 mktypeinfo(s, 1, asize, "longvarchar", SQL_LONGVARCHAR, 12);
14084 break;
14085 #endif
14086 case SQL_VARBINARY:
14087 mktypeinfo(s, 1, asize, "varbinary", SQL_VARBINARY, 30);
14088 break;
14089 case SQL_LONGVARBINARY:
14090 mktypeinfo(s, 1, asize, "longvarbinary", SQL_LONGVARBINARY, 31);
14091 break;
14092 #ifdef SQL_BIT
14093 case SQL_BIT:
14094 mktypeinfo(s, 1, asize, "bit", SQL_BIT, 29);
14095 break;
14096 #endif
14097 #ifdef SQL_BIGINT
14098 case SQL_BIGINT:
14099 mktypeinfo(s, 1, asize, "bigint", SQL_BIGINT, 28);
14100 break;
14101 #endif
14102 #ifdef WINTERFACE
14103 #ifdef SQL_WCHAR
14104 case SQL_WCHAR:
14105 mktypeinfo(s, 1, asize, "wchar", SQL_WCHAR, 18);
14106 break;
14107 #endif
14108 #ifdef SQL_WVARCHAR
14109 case SQL_WVARCHAR:
14110 mktypeinfo(s, 1, asize, "wvarchar", SQL_WVARCHAR, 19);
14111 break;
14112 #endif
14113 #ifdef SQL_WLONGVARCHAR
14114 case SQL_WLONGVARCHAR:
14115 mktypeinfo(s, 1, asize, "longwvarchar", SQL_WLONGVARCHAR, 20);
14116 break;
14117 #endif
14118 #endif
14119 default:
14120 s->nrows = 0;
14121 }
14122 }
14123 return SQL_SUCCESS;
14124 }
14125
14126 #ifndef WINTERFACE
14127
14134 SQLRETURN SQL_API
14135 SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
14136 {
14137 SQLRETURN ret;
14138
14139 HSTMT_LOCK(stmt);
14140 ret = drvgettypeinfo(stmt, sqltype);
14141 HSTMT_UNLOCK(stmt);
14142 return ret;
14143 }
14144 #endif
14145
14146 #ifdef WINTERFACE
14147
14154 SQLRETURN SQL_API
14155 SQLGetTypeInfoW(SQLHSTMT stmt, SQLSMALLINT sqltype)
14156 {
14157 SQLRETURN ret;
14158
14159 HSTMT_LOCK(stmt);
14160 ret = drvgettypeinfo(stmt, sqltype);
14161 HSTMT_UNLOCK(stmt);
14162 return ret;
14163 }
14164 #endif
14165
14170 static COL statSpec2[] = {
14171 { "SYSTEM", "STATISTICS", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
14172 { "SYSTEM", "STATISTICS", "TABLE_OWNER", SCOL_VARCHAR, 50 },
14173 { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
14174 { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
14175 { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
14176 { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
14177 { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
14178 { "SYSTEM", "STATISTICS", "SEQ_IN_INDEX", SQL_SMALLINT, 50 },
14179 { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
14180 { "SYSTEM", "STATISTICS", "COLLATION", SCOL_CHAR, 1 },
14181 { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
14182 { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
14183 { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
14184 };
14185
14186 static COL statSpec3[] = {
14187 { "SYSTEM", "STATISTICS", "TABLE_CAT", SCOL_VARCHAR, 50 },
14188 { "SYSTEM", "STATISTICS", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
14189 { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
14190 { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
14191 { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
14192 { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
14193 { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
14194 { "SYSTEM", "STATISTICS", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
14195 { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
14196 { "SYSTEM", "STATISTICS", "ASC_OR_DESC", SCOL_CHAR, 1 },
14197 { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
14198 { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
14199 { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
14200 };
14201
14216 static SQLRETURN
14217 drvstatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
14218 SQLCHAR *schema, SQLSMALLINT schemaLen,
14219 SQLCHAR *table, SQLSMALLINT tableLen,
14220 SQLUSMALLINT itype, SQLUSMALLINT resv)
14221 {
14222 SQLRETURN sret;
14223 STMT *s;
14224 DBC *d;
14225 int i, asize, ret, nrows, ncols, offs, namec, uniquec, addipk = 0;
14226 PTRDIFF_T size;
14227 char **rowp, *errp = NULL, *sql, tname[512];
14228
14229 sret = mkresultset(stmt, statSpec2, array_size(statSpec2),
14230 statSpec3, array_size(statSpec3), &asize);
14231 if (sret != SQL_SUCCESS) {
14232 return sret;
14233 }
14234 s = (STMT *) stmt;
14235 d = (DBC *) s->dbc;
14236 if (!table || table[0] == '\0' || table[0] == '%') {
14237 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
14238 return SQL_ERROR;
14239 }
14240 if (tableLen == SQL_NTS) {
14241 size = sizeof (tname) - 1;
14242 } else {
14243 size = min(sizeof (tname) - 1, tableLen);
14244 }
14245 strncpy(tname, (char *) table, size);
14246 tname[size] = '\0';
14247 unescpat(tname);
14248 sret = starttran(s);
14249 if (sret != SQL_SUCCESS) {
14250 return sret;
14251 }
14252
14253
14254
14255 if (itype == SQL_INDEX_UNIQUE || itype == SQL_INDEX_ALL) {
14256 rowp = 0;
14257 ret = SQLITE_ERROR;
14258 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
14259 if (sql) {
14260 dbtraceapi(d, "sqlite3_get_table", sql);
14261 ret = sqlite3_get_table(d->sqlite, sql, &rowp,
14262 &nrows, &ncols, NULL);
14263 sqlite3_free(sql);
14264 }
14265 if (ret == SQLITE_OK) {
14266 int colid, typec, npk = 0;
14267
14268 namec = findcol(rowp, ncols, "name");
14269 uniquec = findcol(rowp, ncols, "pk");
14270 typec = findcol(rowp, ncols, "type");
14271 colid = findcol(rowp, ncols, "cid");
14272 if (namec < 0 || uniquec < 0 || typec < 0 || colid < 0) {
14273 goto noipk;
14274 }
14275 for (i = 1; i <= nrows; i++) {
14276 if (*rowp[i * ncols + uniquec] != '0' &&
14277 strlen(rowp[i * ncols + typec]) == 7 &&
14278 strncasecmp(rowp[i * ncols + typec], "integer", 7)
14279 == 0) {
14280 npk++;
14281 }
14282 }
14283 if (npk == 1) {
14284 addipk = 1;
14285 }
14286 }
14287 noipk:
14288 sqlite3_free_table(rowp);
14289 }
14290 sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
14291 if (!sql) {
14292 return nomem(s);
14293 }
14294 dbtraceapi(d, "sqlite3_get_table", sql);
14295 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
14296 sqlite3_free(sql);
14297 if (ret != SQLITE_OK) {
14298 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
14299 errp ? errp : "unknown error", ret);
14300 if (errp) {
14301 sqlite3_free(errp);
14302 errp = NULL;
14303 }
14304 return SQL_ERROR;
14305 }
14306 if (errp) {
14307 sqlite3_free(errp);
14308 errp = NULL;
14309 }
14310 size = 0;
14311 namec = findcol(rowp, ncols, "name");
14312 uniquec = findcol(rowp, ncols, "unique");
14313 if (namec < 0 || uniquec < 0) {
14314 goto nodata;
14315 }
14316 for (i = 1; i <= nrows; i++) {
14317 int nnrows, nncols;
14318 char **rowpp;
14319 int isuniq;
14320
14321 isuniq = *rowp[i * ncols + uniquec] != '0';
14322 if (isuniq || itype == SQL_INDEX_ALL) {
14323 ret = SQLITE_ERROR;
14324 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
14325 rowp[i * ncols + namec]);
14326 if (sql) {
14327 dbtraceapi(d, "sqlite3_get_table", sql);
14328 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
14329 &nnrows, &nncols, NULL);
14330 sqlite3_free(sql);
14331 }
14332 if (ret == SQLITE_OK) {
14333 size += nnrows;
14334 sqlite3_free_table(rowpp);
14335 }
14336 }
14337 }
14338 nodata:
14339 if (addipk) {
14340 size++;
14341 }
14342 if (size == 0) {
14343 sqlite3_free_table(rowp);
14344 return SQL_SUCCESS;
14345 }
14346 s->nrows = size;
14347 size = (size + 1) * asize;
14348 s->rows = xmalloc((size + 1) * sizeof (char *));
14349 if (!s->rows) {
14350 s->nrows = 0;
14351 return nomem(s);
14352 }
14353 s->rows[0] = (char *) size;
14354 s->rows += 1;
14355 memset(s->rows, 0, sizeof (char *) * size);
14356 s->rowfree = freerows;
14357 offs = 0;
14358 if (addipk) {
14359 char **rowpp = 0;
14360 int nrows2, ncols2;
14361
14362 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
14363 if (sql) {
14364 dbtraceapi(d, "sqlite3_get_table", sql);
14365 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
14366 &nrows2, &ncols2, NULL);
14367 sqlite3_free(sql);
14368 }
14369 if (ret == SQLITE_OK) {
14370 int colid, typec, roffs, namecc, uniquecc;
14371
14372 namecc = findcol(rowpp, ncols2, "name");
14373 uniquecc = findcol(rowpp, ncols2, "pk");
14374 typec = findcol(rowpp, ncols2, "type");
14375 colid = findcol(rowpp, ncols2, "cid");
14376 if (namecc < 0 || uniquecc < 0 || typec < 0 || colid < 0) {
14377 addipk = 0;
14378 s->nrows--;
14379 goto nodata2;
14380 }
14381 for (i = 1; i <= nrows2; i++) {
14382 if (*rowpp[i * ncols2 + uniquecc] != '0' &&
14383 strlen(rowpp[i * ncols2 + typec]) == 7 &&
14384 strncasecmp(rowpp[i * ncols2 + typec], "integer", 7)
14385 == 0) {
14386 break;
14387 }
14388 }
14389 if (i > nrows2) {
14390 addipk = 0;
14391 s->nrows--;
14392 goto nodata2;
14393 }
14394 roffs = s->ncols;
14395 s->rows[roffs + 0] = xstrdup("");
14396 #if defined(_WIN32) || defined(_WIN64)
14397 s->rows[roffs + 1] = xstrdup(d->xcelqrx ? "main" : "");
14398 #else
14399 s->rows[roffs + 1] = xstrdup("");
14400 #endif
14401 s->rows[roffs + 2] = xstrdup(tname);
14402 s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
14403 s->rows[roffs + 5] = xstrdup("sqlite_autoindex_0");
14404 s->rows[roffs + 6] = xstrdup(stringify(SQL_INDEX_OTHER));
14405 s->rows[roffs + 7] = xstrdup("1");
14406 s->rows[roffs + 8] = xstrdup(rowpp[i * ncols2 + namecc]);
14407 s->rows[roffs + 9] = xstrdup("A");
14408 }
14409 nodata2:
14410 sqlite3_free_table(rowpp);
14411 }
14412 for (i = 1; i <= nrows; i++) {
14413 int nnrows, nncols;
14414 char **rowpp = 0;
14415
14416 if (*rowp[i * ncols + uniquec] != '0' || itype == SQL_INDEX_ALL) {
14417 int k;
14418
14419 ret = SQLITE_ERROR;
14420 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
14421 rowp[i * ncols + namec]);
14422 if (sql) {
14423 dbtraceapi(d, "sqlite3_get_table", sql);
14424 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
14425 &nnrows, &nncols, NULL);
14426 sqlite3_free(sql);
14427 }
14428 if (ret != SQLITE_OK) {
14429 continue;
14430 }
14431 for (k = 0; nnrows && k < nncols; k++) {
14432 if (strcmp(rowpp[k], "name") == 0) {
14433 int m;
14434
14435 for (m = 1; m <= nnrows; m++) {
14436 int roffs = (offs + addipk + m) * s->ncols;
14437 int isuniq;
14438
14439 isuniq = *rowp[i * ncols + uniquec] != '0';
14440 s->rows[roffs + 0] = xstrdup("");
14441 s->rows[roffs + 1] = xstrdup("");
14442 s->rows[roffs + 2] = xstrdup(tname);
14443 if (isuniq) {
14444 s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
14445 } else {
14446 s->rows[roffs + 3] = xstrdup(stringify(SQL_TRUE));
14447 }
14448 s->rows[roffs + 5] = xstrdup(rowp[i * ncols + namec]);
14449 s->rows[roffs + 6] =
14450 xstrdup(stringify(SQL_INDEX_OTHER));
14451 s->rows[roffs + 8] = xstrdup(rowpp[m * nncols + k]);
14452 s->rows[roffs + 9] = xstrdup("A");
14453 }
14454 } else if (strcmp(rowpp[k], "seqno") == 0) {
14455 int m;
14456
14457 for (m = 1; m <= nnrows; m++) {
14458 int roffs = (offs + addipk + m) * s->ncols;
14459 int pos = m - 1;
14460 char buf[32];
14461
14462 sscanf(rowpp[m * nncols + k], "%d", &pos);
14463 sprintf(buf, "%d", pos + 1);
14464 s->rows[roffs + 7] = xstrdup(buf);
14465 }
14466 }
14467 }
14468 offs += nnrows;
14469 sqlite3_free_table(rowpp);
14470 }
14471 }
14472 sqlite3_free_table(rowp);
14473 return SQL_SUCCESS;
14474 }
14475
14476 #ifndef WINTERFACE
14477
14491 SQLRETURN SQL_API
14492 SQLStatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
14493 SQLCHAR *schema, SQLSMALLINT schemaLen,
14494 SQLCHAR *table, SQLSMALLINT tableLen,
14495 SQLUSMALLINT itype, SQLUSMALLINT resv)
14496 {
14497 #if defined(_WIN32) || defined(_WIN64)
14498 char *c = NULL, *s = NULL, *t = NULL;
14499 #endif
14500 SQLRETURN ret;
14501
14502 HSTMT_LOCK(stmt);
14503 #if defined(_WIN32) || defined(_WIN64)
14504 if (!((STMT *) stmt)->oemcp[0]) {
14505 ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
14506 table, tableLen, itype, resv);
14507 goto done2;
14508 }
14509 if (cat) {
14510 c = wmb_to_utf_c((char *) cat, catLen);
14511 if (!c) {
14512 ret = nomem((STMT *) stmt);
14513 goto done;
14514 }
14515 }
14516 if (schema) {
14517 s = wmb_to_utf_c((char *) schema, schemaLen);
14518 if (!s) {
14519 ret = nomem((STMT *) stmt);
14520 goto done;
14521 }
14522 }
14523 if (table) {
14524 t = wmb_to_utf_c((char *) table, tableLen);
14525 if (!t) {
14526 ret = nomem((STMT *) stmt);
14527 goto done;
14528 }
14529 }
14530 ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
14531 (SQLCHAR *) t, SQL_NTS, itype, resv);
14532 #else
14533 ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
14534 table, tableLen, itype, resv);
14535 #endif
14536 #if defined(_WIN32) || defined(_WIN64)
14537 done:
14538 uc_free(t);
14539 uc_free(s);
14540 uc_free(c);
14541 done2:
14542 ;
14543 #endif
14544 HSTMT_UNLOCK(stmt);
14545 return ret;
14546 }
14547 #endif
14548
14549 #ifdef WINTERFACE
14550
14564 SQLRETURN SQL_API
14565 SQLStatisticsW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen,
14566 SQLWCHAR *schema, SQLSMALLINT schemaLen,
14567 SQLWCHAR *table, SQLSMALLINT tableLen,
14568 SQLUSMALLINT itype, SQLUSMALLINT resv)
14569 {
14570 char *c = NULL, *s = NULL, *t = NULL;
14571 SQLRETURN ret;
14572
14573 HSTMT_LOCK(stmt);
14574 if (cat) {
14575 c = uc_to_utf_c(cat, catLen);
14576 if (!c) {
14577 ret = nomem((STMT *) stmt);
14578 goto done;
14579 }
14580 }
14581 if (schema) {
14582 s = uc_to_utf_c(schema, schemaLen);
14583 if (!s) {
14584 ret = nomem((STMT *) stmt);
14585 goto done;
14586 }
14587 }
14588 if (table) {
14589 t = uc_to_utf_c(table, tableLen);
14590 if (!t) {
14591 ret = nomem((STMT *) stmt);
14592 goto done;
14593 }
14594 }
14595 ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
14596 (SQLCHAR *) t, SQL_NTS, itype, resv);
14597 done:
14598 uc_free(t);
14599 uc_free(s);
14600 uc_free(c);
14601 HSTMT_UNLOCK(stmt);
14602 return ret;
14603 }
14604 #endif
14605
14617 SQLRETURN SQL_API
14618 SQLGetData(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14619 SQLPOINTER val, SQLLEN len, SQLLEN *lenp)
14620 {
14621 STMT *s;
14622 SQLRETURN ret = SQL_ERROR;
14623
14624 HSTMT_LOCK(stmt);
14625 if (stmt == SQL_NULL_HSTMT) {
14626 return SQL_INVALID_HANDLE;
14627 }
14628 s = (STMT *) stmt;
14629 if (col == 0 && s->bkmrk && type == SQL_C_BOOKMARK) {
14630 *((long *) val) = s->rowp;
14631 if (lenp) {
14632 *lenp = sizeof (long);
14633 }
14634 ret = SQL_SUCCESS;
14635 goto done;
14636 }
14637 if (col < 1 || col > s->ncols) {
14638 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
14639 goto done;
14640 }
14641 --col;
14642 ret = getrowdata(s, col, type, val, len, lenp, 1);
14643 done:
14644 HSTMT_UNLOCK(stmt);
14645 return ret;
14646 }
14647
14655 static SQLRETURN
14656 dofetchbind(STMT *s, int rsi)
14657 {
14658 int ret, i, withinfo = 0;
14659
14660 s->row_status0[rsi] = SQL_ROW_SUCCESS;
14661 if (s->bkmrk && s->bkmrkcol.valp) {
14662 long *val;
14663
14664 if (s->bind_type != SQL_BIND_BY_COLUMN) {
14665 val = (long *) ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
14666 } else {
14667 val = (long *) s->bkmrkcol.valp + rsi;
14668 }
14669 if (s->bind_offs) {
14670 val = (long *) ((char *) val + *s->bind_offs);
14671 }
14672 *val = s->rowp;
14673 if (s->bkmrkcol.lenp) {
14674 SQLLEN *ival;
14675
14676 if (s->bind_type != SQL_BIND_BY_COLUMN) {
14677 ival = (SQLLEN *)
14678 ((char *) s->bkmrkcol.lenp + s->bind_type * rsi);
14679 } else {
14680 ival = &s->bkmrkcol.lenp[rsi];
14681 }
14682 if (s->bind_offs) {
14683 ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
14684 }
14685 *ival = sizeof (long);
14686 }
14687 }
14688 ret = SQL_SUCCESS;
14689 for (i = 0; s->bindcols && i < s->ncols; i++) {
14690 BINDCOL *b = &s->bindcols[i];
14691 SQLPOINTER dp = 0;
14692 SQLLEN *lp = 0;
14693
14694 b->offs = 0;
14695 if (b->valp) {
14696 if (s->bind_type != SQL_BIND_BY_COLUMN) {
14697 dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
14698 } else {
14699 dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
14700 }
14701 if (s->bind_offs) {
14702 dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
14703 }
14704 }
14705 if (b->lenp) {
14706 if (s->bind_type != SQL_BIND_BY_COLUMN) {
14707 lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
14708 } else {
14709 lp = b->lenp + rsi;
14710 }
14711 if (s->bind_offs) {
14712 lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
14713 }
14714 }
14715 if (dp || lp) {
14716 ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp, b->max, lp, 0);
14717 if (!SQL_SUCCEEDED(ret)) {
14718 s->row_status0[rsi] = SQL_ROW_ERROR;
14719 break;
14720 }
14721 if (ret != SQL_SUCCESS) {
14722 withinfo = 1;
14723 #ifdef SQL_ROW_SUCCESS_WITH_INFO
14724 s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
14725 #endif
14726 }
14727 }
14728 }
14729 if (SQL_SUCCEEDED(ret)) {
14730 ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
14731 }
14732 return ret;
14733 }
14734
14743 static SQLRETURN
14744 drvfetchscroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLINTEGER offset)
14745 {
14746 STMT *s;
14747 int i, withinfo = 0;
14748 SQLRETURN ret;
14749
14750 if (stmt == SQL_NULL_HSTMT) {
14751 return SQL_INVALID_HANDLE;
14752 }
14753 s = (STMT *) stmt;
14754 for (i = 0; i < s->rowset_size; i++) {
14755 s->row_status0[i] = SQL_ROW_NOROW;
14756 }
14757 if (s->row_status) {
14758 memcpy(s->row_status, s->row_status0,
14759 sizeof (SQLUSMALLINT) * s->rowset_size);
14760 }
14761 s->row_count0 = 0;
14762 if (s->row_count) {
14763 *s->row_count = s->row_count0;
14764 }
14765 if (!s->bindcols) {
14766 for (i = 0; i < s->rowset_size; i++) {
14767 s->row_status0[i] = SQL_ROW_ERROR;
14768 }
14769 ret = SQL_ERROR;
14770 i = 0;
14771 goto done2;
14772 }
14773 if (s->isselect != 1 && s->isselect != -1) {
14774 setstat(s, -1, "no result set available", "24000");
14775 ret = SQL_ERROR;
14776 i = s->nrows;
14777 goto done2;
14778 }
14779 if (s->curtype == SQL_CURSOR_FORWARD_ONLY && orient != SQL_FETCH_NEXT) {
14780 setstat(s, -1, "wrong fetch direction", "01000");
14781 ret = SQL_ERROR;
14782 i = 0;
14783 goto done2;
14784 }
14785 ret = SQL_SUCCESS;
14786 i = 0;
14787 if (((DBC *) (s->dbc))->cur_s3stmt == s && s->s3stmt) {
14788 s->rowp = 0;
14789 for (; i < s->rowset_size; i++) {
14790 if (s->max_rows && s->s3stmt_rownum + 1 >= s->max_rows) {
14791 ret = (i == 0) ? SQL_NO_DATA : SQL_SUCCESS;
14792 break;
14793 }
14794 ret = s3stmt_step(s);
14795 if (ret != SQL_SUCCESS) {
14796 s->row_status0[i] = SQL_ROW_ERROR;
14797 break;
14798 }
14799 if (s->nrows < 1) {
14800 break;
14801 }
14802 ret = dofetchbind(s, i);
14803 if (!SQL_SUCCEEDED(ret)) {
14804 break;
14805 } else if (ret == SQL_SUCCESS_WITH_INFO) {
14806 withinfo = 1;
14807 }
14808 }
14809 } else if (s->rows) {
14810 switch (orient) {
14811 case SQL_FETCH_NEXT:
14812 if (s->nrows < 1) {
14813 return SQL_NO_DATA;
14814 }
14815 if (s->rowp < 0) {
14816 s->rowp = -1;
14817 }
14818 if (s->rowp >= s->nrows) {
14819 s->rowp = s->nrows;
14820 return SQL_NO_DATA;
14821 }
14822 break;
14823 case SQL_FETCH_PRIOR:
14824 if (s->nrows < 1 || s->rowp <= 0) {
14825 s->rowp = -1;
14826 return SQL_NO_DATA;
14827 }
14828 s->rowp -= s->rowset_size + 1;
14829 if (s->rowp < -1) {
14830 s->rowp = -1;
14831 return SQL_NO_DATA;
14832 }
14833 break;
14834 case SQL_FETCH_FIRST:
14835 if (s->nrows < 1) {
14836 return SQL_NO_DATA;
14837 }
14838 s->rowp = -1;
14839 break;
14840 case SQL_FETCH_LAST:
14841 if (s->nrows < 1) {
14842 return SQL_NO_DATA;
14843 }
14844 s->rowp = s->nrows - s->rowset_size;
14845 if (--s->rowp < -1) {
14846 s->rowp = -1;
14847 }
14848 break;
14849 case SQL_FETCH_ABSOLUTE:
14850 if (offset == 0) {
14851 s->rowp = -1;
14852 return SQL_NO_DATA;
14853 } else if (offset < 0) {
14854 if (0 - offset <= s->nrows) {
14855 s->rowp = s->nrows + offset - 1;
14856 break;
14857 }
14858 s->rowp = -1;
14859 return SQL_NO_DATA;
14860 } else if (offset > s->nrows) {
14861 s->rowp = s->nrows;
14862 return SQL_NO_DATA;
14863 }
14864 s->rowp = offset - 1 - 1;
14865 break;
14866 case SQL_FETCH_RELATIVE:
14867 if (offset >= 0) {
14868 s->rowp += offset * s->rowset_size - 1;
14869 if (s->rowp >= s->nrows) {
14870 s->rowp = s->nrows;
14871 return SQL_NO_DATA;
14872 }
14873 } else {
14874 s->rowp += offset * s->rowset_size - 1;
14875 if (s->rowp < -1) {
14876 s->rowp = -1;
14877 return SQL_NO_DATA;
14878 }
14879 }
14880 break;
14881 case SQL_FETCH_BOOKMARK:
14882 if (s->bkmrk) {
14883 if (offset < 0 || offset >= s->nrows) {
14884 return SQL_NO_DATA;
14885 }
14886 s->rowp = offset - 1;
14887 break;
14888 }
14889
14890 default:
14891 s->row_status0[0] = SQL_ROW_ERROR;
14892 ret = SQL_ERROR;
14893 goto done;
14894 }
14895 for (; i < s->rowset_size; i++) {
14896 ++s->rowp;
14897 if (s->rowp < 0 || s->rowp >= s->nrows) {
14898 break;
14899 }
14900 ret = dofetchbind(s, i);
14901 if (!SQL_SUCCEEDED(ret)) {
14902 break;
14903 } else if (ret == SQL_SUCCESS_WITH_INFO) {
14904 withinfo = 1;
14905 }
14906 }
14907 }
14908 done:
14909 if (i == 0) {
14910 if (SQL_SUCCEEDED(ret)) {
14911 return SQL_NO_DATA;
14912 }
14913 return ret;
14914 }
14915 if (SQL_SUCCEEDED(ret)) {
14916 ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
14917 }
14918 done2:
14919 if (s->row_status) {
14920 memcpy(s->row_status, s->row_status0,
14921 sizeof (SQLUSMALLINT) * s->rowset_size);
14922 }
14923 s->row_count0 = i;
14924 if (s->row_count) {
14925 *s->row_count = s->row_count0;
14926 }
14927 return ret;
14928 }
14929
14936 SQLRETURN SQL_API
14937 SQLFetch(SQLHSTMT stmt)
14938 {
14939 SQLRETURN ret;
14940
14941 HSTMT_LOCK(stmt);
14942 ret = drvfetchscroll(stmt, SQL_FETCH_NEXT, 0);
14943 HSTMT_UNLOCK(stmt);
14944 return ret;
14945 }
14946
14955 SQLRETURN SQL_API
14956 SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLLEN offset)
14957 {
14958 SQLRETURN ret;
14959
14960 HSTMT_LOCK(stmt);
14961 ret = drvfetchscroll(stmt, orient, offset);
14962 HSTMT_UNLOCK(stmt);
14963 return ret;
14964 }
14965
14976 SQLRETURN SQL_API
14977 SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT orient, SQLROWOFFSET offset,
14978 SQLROWSETSIZE *rowcount, SQLUSMALLINT *rowstatus)
14979 {
14980 STMT *s;
14981 SQLRETURN ret;
14982 SQLUSMALLINT *rst;
14983
14984 HSTMT_LOCK(stmt);
14985 if (stmt == SQL_NULL_HSTMT) {
14986 return SQL_INVALID_HANDLE;
14987 }
14988 s = (STMT *) stmt;
14989
14990 rst = s->row_status;
14991 s->row_status = 0;
14992 ret = drvfetchscroll(stmt, orient, offset);
14993 s->row_status = rst;
14994 if (rowstatus) {
14995 memcpy(rowstatus, s->row_status0,
14996 sizeof (SQLUSMALLINT) * s->rowset_size);
14997 }
14998 if (rowcount) {
14999 *rowcount = s->row_count0;
15000 }
15001 HSTMT_UNLOCK(stmt);
15002 return ret;
15003 }
15004
15012 SQLRETURN SQL_API
15013 SQLRowCount(SQLHSTMT stmt, SQLLEN *nrows)
15014 {
15015 STMT *s;
15016
15017 HSTMT_LOCK(stmt);
15018 if (stmt == SQL_NULL_HSTMT) {
15019 return SQL_INVALID_HANDLE;
15020 }
15021 s = (STMT *) stmt;
15022 if (nrows) {
15023 *nrows = s->isselect ? 0 : s->nrows;
15024 }
15025 HSTMT_UNLOCK(stmt);
15026 return SQL_SUCCESS;
15027 }
15028
15036 SQLRETURN SQL_API
15037 SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *ncols)
15038 {
15039 STMT *s;
15040
15041 HSTMT_LOCK(stmt);
15042 if (stmt == SQL_NULL_HSTMT) {
15043 return SQL_INVALID_HANDLE;
15044 }
15045 s = (STMT *) stmt;
15046 if (ncols) {
15047 *ncols = s->ncols;
15048 }
15049 HSTMT_UNLOCK(stmt);
15050 return SQL_SUCCESS;
15051 }
15052
15067 static SQLRETURN
15068 drvdescribecol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
15069 SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
15070 SQLSMALLINT *type, SQLULEN *size,
15071 SQLSMALLINT *digits, SQLSMALLINT *nullable)
15072 {
15073 STMT *s;
15074 COL *c;
15075 int didname = 0;
15076
15077 if (stmt == SQL_NULL_HSTMT) {
15078 return SQL_INVALID_HANDLE;
15079 }
15080 s = (STMT *) stmt;
15081 if (!s->cols) {
15082 setstat(s, -1, "no columns", (*s->ov3) ? "07009" : "S1002");
15083 return SQL_ERROR;
15084 }
15085 if (col < 1 || col > s->ncols) {
15086 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
15087 return SQL_ERROR;
15088 }
15089 c = s->cols + col - 1;
15090 if (name && nameMax > 0) {
15091 strncpy((char *) name, c->column, nameMax);
15092 name[nameMax - 1] = '\0';
15093 didname = 1;
15094 }
15095 if (nameLen) {
15096 if (didname) {
15097 *nameLen = strlen((char *) name);
15098 } else {
15099 *nameLen = strlen(c->column);
15100 }
15101 }
15102 if (type) {
15103 *type = c->type;
15104 #ifdef WINTERFACE
15105 if (s->nowchar[0] || s->nowchar[1]) {
15106 switch (c->type) {
15107 case SQL_WCHAR:
15108 *type = SQL_CHAR;
15109 break;
15110 case SQL_WVARCHAR:
15111 *type = SQL_VARCHAR;
15112 break;
15113 #ifdef SQL_LONGVARCHAR
15114 case SQL_WLONGVARCHAR:
15115 *type = SQL_LONGVARCHAR;
15116 break;
15117 #endif
15118 }
15119 }
15120 #endif
15121 }
15122 if (size) {
15123 *size = c->size;
15124 }
15125 if (digits) {
15126 *digits = 0;
15127 }
15128 if (nullable) {
15129 *nullable = 1;
15130 }
15131 return SQL_SUCCESS;
15132 }
15133
15134 #ifndef WINTERFACE
15135
15149 SQLRETURN SQL_API
15150 SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
15151 SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
15152 SQLSMALLINT *type, SQLULEN *size,
15153 SQLSMALLINT *digits, SQLSMALLINT *nullable)
15154 {
15155 #if defined(_WIN32) || defined(_WIN64)
15156 SQLSMALLINT len = 0;
15157 #endif
15158 SQLRETURN ret;
15159
15160 HSTMT_LOCK(stmt);
15161 #if defined(_WIN32) || defined(_WIN64)
15162 if (!((STMT *) stmt)->oemcp[0]) {
15163 ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
15164 type, size, digits, nullable);
15165 goto done;
15166 }
15167 ret = drvdescribecol(stmt, col, name, nameMax,
15168 &len, type, size, digits, nullable);
15169 if (ret == SQL_SUCCESS) {
15170 if (name) {
15171 if (len > 0) {
15172 SQLCHAR *n = NULL;
15173
15174 n = (SQLCHAR *) utf_to_wmb((char *) name, len);
15175 if (n) {
15176 strncpy((char *) name, (char *) n, nameMax);
15177 n[len] = 0;
15178 len = min(nameMax, strlen((char *) n));
15179 uc_free(n);
15180 } else {
15181 len = 0;
15182 }
15183 }
15184 if (len <= 0) {
15185 len = 0;
15186 if (nameMax > 0) {
15187 name[0] = 0;
15188 }
15189 }
15190 } else {
15191 STMT *s = (STMT *) stmt;
15192 COL *c = s->cols + col - 1;
15193
15194 len = 0;
15195 if (c->column) {
15196 len = strlen(c->column);
15197 }
15198 }
15199 if (nameLen) {
15200 *nameLen = len;
15201 }
15202 }
15203 done:
15204 ;
15205 #else
15206 ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
15207 type, size, digits, nullable);
15208 #endif
15209 HSTMT_UNLOCK(stmt);
15210 return ret;
15211 }
15212 #endif
15213
15214 #ifdef WINTERFACE
15215
15229 SQLRETURN SQL_API
15230 SQLDescribeColW(SQLHSTMT stmt, SQLUSMALLINT col, SQLWCHAR *name,
15231 SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
15232 SQLSMALLINT *type, SQLULEN *size,
15233 SQLSMALLINT *digits, SQLSMALLINT *nullable)
15234 {
15235 SQLRETURN ret;
15236 SQLSMALLINT len = 0;
15237
15238 HSTMT_LOCK(stmt);
15239 ret = drvdescribecol(stmt, col, (SQLCHAR *) name,
15240 (SQLSMALLINT) (nameMax * sizeof (SQLWCHAR)),
15241 &len, type, size, digits, nullable);
15242 if (ret == SQL_SUCCESS) {
15243 if (name) {
15244 if (len > 0) {
15245 SQLWCHAR *n = NULL;
15246
15247 n = uc_from_utf((SQLCHAR *) name, len);
15248 if (n) {
15249 uc_strncpy(name, n, nameMax);
15250 n[len] = 0;
15251 len = min(nameMax, uc_strlen(n));
15252 uc_free(n);
15253 } else {
15254 len = 0;
15255 }
15256 }
15257 if (len <= 0) {
15258 len = 0;
15259 if (nameMax > 0) {
15260 name[0] = 0;
15261 }
15262 }
15263 } else {
15264 STMT *s = (STMT *) stmt;
15265 COL *c = s->cols + col - 1;
15266
15267 len = 0;
15268 if (c->column) {
15269 len = strlen(c->column);
15270 }
15271 }
15272 if (nameLen) {
15273 *nameLen = len;
15274 }
15275 }
15276 HSTMT_UNLOCK(stmt);
15277 return ret;
15278 }
15279 #endif
15280
15293 static SQLRETURN
15294 drvcolattributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
15295 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
15296 SQLLEN *val2)
15297 {
15298 STMT *s;
15299 COL *c;
15300 SQLSMALLINT dummy;
15301 char *valc = (char *) val;
15302
15303 if (stmt == SQL_NULL_HSTMT) {
15304 return SQL_INVALID_HANDLE;
15305 }
15306 s = (STMT *) stmt;
15307 if (!s->cols) {
15308 return SQL_ERROR;
15309 }
15310 if (!valLen) {
15311 valLen = &dummy;
15312 }
15313 if (id == SQL_COLUMN_COUNT) {
15314 if (val2) {
15315 *val2 = s->ncols;
15316 }
15317 *valLen = sizeof (int);
15318 return SQL_SUCCESS;
15319 }
15320 if (id == SQL_COLUMN_TYPE && col == 0) {
15321 if (val2) {
15322 *val2 = SQL_INTEGER;
15323 }
15324 *valLen = sizeof (int);
15325 return SQL_SUCCESS;
15326 }
15327 #ifdef SQL_DESC_OCTET_LENGTH
15328 if (id == SQL_DESC_OCTET_LENGTH && col == 0) {
15329 if (val2) {
15330 *val2 = 4;
15331 }
15332 *valLen = sizeof (int);
15333 return SQL_SUCCESS;
15334 }
15335 #endif
15336 if (col < 1 || col > s->ncols) {
15337 setstat(s, -1, "invalid column", (*s->ov3) ? "07009": "S1002");
15338 return SQL_ERROR;
15339 }
15340 c = s->cols + col - 1;
15341
15342 switch (id) {
15343 case SQL_COLUMN_LABEL:
15344 if (c->label) {
15345 if (valc && valMax > 0) {
15346 strncpy(valc, c->label, valMax);
15347 valc[valMax - 1] = '\0';
15348 }
15349 *valLen = strlen(c->label);
15350 goto checkLen;
15351 }
15352
15353 case SQL_COLUMN_NAME:
15354 case SQL_DESC_NAME:
15355 if (valc && valMax > 0) {
15356 strncpy(valc, c->column, valMax);
15357 valc[valMax - 1] = '\0';
15358 }
15359 *valLen = strlen(c->column);
15360 checkLen:
15361 if (*valLen >= valMax) {
15362 setstat(s, -1, "data right truncated", "01004");
15363 return SQL_SUCCESS_WITH_INFO;
15364 }
15365 return SQL_SUCCESS;
15366 #ifdef SQL_DESC_BASE_COLUMN_NAME
15367 if (strchr(c->column, '(') || strchr(c->column, ')')) {
15368 valc[0] = '\0';
15369 *valLen = 0;
15370 } else if (valc && valMax > 0) {
15371 strncpy(valc, c->column, valMax);
15372 valc[valMax - 1] = '\0';
15373 *valLen = strlen(c->column);
15374 }
15375 goto checkLen;
15376 #endif
15377 case SQL_COLUMN_TYPE:
15378 case SQL_DESC_TYPE:
15379 #ifdef WINTERFACE
15380 {
15381 int type = c->type;
15382
15383 if (s->nowchar[0] || s->nowchar[1]) {
15384 switch (type) {
15385 case SQL_WCHAR:
15386 type = SQL_CHAR;
15387 break;
15388 case SQL_WVARCHAR:
15389 type = SQL_VARCHAR;
15390 break;
15391 #ifdef SQL_LONGVARCHAR
15392 case SQL_WLONGVARCHAR:
15393 type = SQL_LONGVARCHAR;
15394 break;
15395 }
15396 }
15397 if (val2) {
15398 *val2 = type;
15399 }
15400 #endif
15401 }
15402 #else
15403 if (val2) {
15404 *val2 = c->type;
15405 }
15406 #endif
15407 *valLen = sizeof (int);
15408 return SQL_SUCCESS;
15409 case SQL_COLUMN_DISPLAY_SIZE:
15410 if (val2) {
15411 *val2 = c->size;
15412 }
15413 *valLen = sizeof (int);
15414 return SQL_SUCCESS;
15415 case SQL_COLUMN_UNSIGNED:
15416 if (val2) {
15417 *val2 = c->nosign ? SQL_TRUE : SQL_FALSE;
15418 }
15419 *valLen = sizeof (int);
15420 return SQL_SUCCESS;
15421 case SQL_COLUMN_SCALE:
15422 case SQL_DESC_SCALE:
15423 if (val2) {
15424 *val2 = c->scale;
15425 }
15426 *valLen = sizeof (int);
15427 return SQL_SUCCESS;
15428 case SQL_COLUMN_PRECISION:
15429 case SQL_DESC_PRECISION:
15430 if (val2) {
15431 switch (c->type) {
15432 case SQL_SMALLINT:
15433 *val2 = 5;
15434 break;
15435 case SQL_INTEGER:
15436 *val2 = 10;
15437 break;
15438 case SQL_FLOAT:
15439 case SQL_REAL:
15440 case SQL_DOUBLE:
15441 *val2 = 15;
15442 break;
15443 case SQL_DATE:
15444 *val2 = 0;
15445 break;
15446 case SQL_TIME:
15447 *val2 = 0;
15448 break;
15449 #ifdef SQL_TYPE_TIMESTAMP
15450 case SQL_TYPE_TIMESTAMP:
15451 #endif
15452 case SQL_TIMESTAMP:
15453 *val2 = (c->prec >= 0 && c->prec <= 3) ? c->