xref: /sqlite-3.40.0/src/test1.c (revision 74217cc0)
1 /*
2 ** 2001 September 15
3 **
4 ** The author disclaims copyright to this source code.  In place of
5 ** a legal notice, here is a blessing:
6 **
7 **    May you do good and not evil.
8 **    May you find forgiveness for yourself and forgive others.
9 **    May you share freely, never taking more than you give.
10 **
11 *************************************************************************
12 ** Code for testing the printf() interface to SQLite.  This code
13 ** is not included in the SQLite library.  It is used for automated
14 ** testing of the SQLite library.
15 **
16 ** $Id: test1.c,v 1.162 2005/09/19 13:15:23 drh Exp $
17 */
18 #include "sqliteInt.h"
19 #include "tcl.h"
20 #include "os.h"
21 #include <stdlib.h>
22 #include <string.h>
23 
24 const char *sqlite3TestErrorName(int rc){
25   const char *zName = 0;
26   switch( rc ){
27     case SQLITE_OK:         zName = "SQLITE_OK";          break;
28     case SQLITE_ERROR:      zName = "SQLITE_ERROR";       break;
29     case SQLITE_PERM:       zName = "SQLITE_PERM";        break;
30     case SQLITE_ABORT:      zName = "SQLITE_ABORT";       break;
31     case SQLITE_BUSY:       zName = "SQLITE_BUSY";        break;
32     case SQLITE_LOCKED:     zName = "SQLITE_LOCKED";      break;
33     case SQLITE_NOMEM:      zName = "SQLITE_NOMEM";       break;
34     case SQLITE_READONLY:   zName = "SQLITE_READONLY";    break;
35     case SQLITE_INTERRUPT:  zName = "SQLITE_INTERRUPT";   break;
36     case SQLITE_IOERR:      zName = "SQLITE_IOERR";       break;
37     case SQLITE_CORRUPT:    zName = "SQLITE_CORRUPT";     break;
38     case SQLITE_FULL:       zName = "SQLITE_FULL";        break;
39     case SQLITE_CANTOPEN:   zName = "SQLITE_CANTOPEN";    break;
40     case SQLITE_PROTOCOL:   zName = "SQLITE_PROTOCOL";    break;
41     case SQLITE_EMPTY:      zName = "SQLITE_EMPTY";       break;
42     case SQLITE_SCHEMA:     zName = "SQLITE_SCHEMA";      break;
43     case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT";  break;
44     case SQLITE_MISMATCH:   zName = "SQLITE_MISMATCH";    break;
45     case SQLITE_MISUSE:     zName = "SQLITE_MISUSE";      break;
46     case SQLITE_NOLFS:      zName = "SQLITE_NOLFS";       break;
47     case SQLITE_AUTH:       zName = "SQLITE_AUTH";        break;
48     case SQLITE_FORMAT:     zName = "SQLITE_FORMAT";      break;
49     case SQLITE_RANGE:      zName = "SQLITE_RANGE";       break;
50     case SQLITE_ROW:        zName = "SQLITE_ROW";         break;
51     case SQLITE_DONE:       zName = "SQLITE_DONE";        break;
52     case SQLITE_NOTADB:     zName = "SQLITE_NOTADB";      break;
53     default:                zName = "SQLITE_Unknown";     break;
54   }
55   return zName;
56 }
57 #define errorName sqlite3TestErrorName
58 
59 /*
60 ** Convert an sqlite3_stmt* into an sqlite3*.  This depends on the
61 ** fact that the sqlite3* is the first field in the Vdbe structure.
62 */
63 #define StmtToDb(X)   sqlite3_db_handle(X)
64 
65 /*
66 ** Check a return value to make sure it agrees with the results
67 ** from sqlite3_errcode.
68 */
69 int sqlite3TestErrCode(Tcl_Interp *interp, sqlite3 *db, int rc){
70   if( rc!=SQLITE_MISUSE && rc!=SQLITE_OK && sqlite3_errcode(db)!=rc ){
71     char zBuf[200];
72     int r2 = sqlite3_errcode(db);
73     sprintf(zBuf, "error code %s (%d) does not match sqlite3_errcode %s (%d)",
74        errorName(rc), rc, errorName(r2), r2);
75     Tcl_ResetResult(interp);
76     Tcl_AppendResult(interp, zBuf, 0);
77     return 1;
78   }
79   return 0;
80 }
81 
82 /*
83 ** Decode a pointer to an sqlite3 object.
84 */
85 static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){
86   *ppDb = (sqlite3*)sqlite3TextToPtr(zA);
87   return TCL_OK;
88 }
89 
90 /*
91 ** Decode a pointer to an sqlite3_stmt object.
92 */
93 static int getStmtPointer(
94   Tcl_Interp *interp,
95   const char *zArg,
96   sqlite3_stmt **ppStmt
97 ){
98   *ppStmt = (sqlite3_stmt*)sqlite3TextToPtr(zArg);
99   return TCL_OK;
100 }
101 
102 /*
103 ** Decode a pointer to an sqlite3_stmt object.
104 */
105 static int getFilePointer(
106   Tcl_Interp *interp,
107   const char *zArg,
108   OsFile **ppFile
109 ){
110   *ppFile = (OsFile*)sqlite3TextToPtr(zArg);
111   return TCL_OK;
112 }
113 
114 /*
115 ** Generate a text representation of a pointer that can be understood
116 ** by the getDbPointer and getVmPointer routines above.
117 **
118 ** The problem is, on some machines (Solaris) if you do a printf with
119 ** "%p" you cannot turn around and do a scanf with the same "%p" and
120 ** get your pointer back.  You have to prepend a "0x" before it will
121 ** work.  Or at least that is what is reported to me (drh).  But this
122 ** behavior varies from machine to machine.  The solution used her is
123 ** to test the string right after it is generated to see if it can be
124 ** understood by scanf, and if not, try prepending an "0x" to see if
125 ** that helps.  If nothing works, a fatal error is generated.
126 */
127 static int makePointerStr(Tcl_Interp *interp, char *zPtr, void *p){
128   sqlite3_snprintf(100, zPtr, "%p", p);
129   return TCL_OK;
130 }
131 
132 /*
133 ** The callback routine for sqlite3_exec_printf().
134 */
135 static int exec_printf_cb(void *pArg, int argc, char **argv, char **name){
136   Tcl_DString *str = (Tcl_DString*)pArg;
137   int i;
138 
139   if( Tcl_DStringLength(str)==0 ){
140     for(i=0; i<argc; i++){
141       Tcl_DStringAppendElement(str, name[i] ? name[i] : "NULL");
142     }
143   }
144   for(i=0; i<argc; i++){
145     Tcl_DStringAppendElement(str, argv[i] ? argv[i] : "NULL");
146   }
147   return 0;
148 }
149 
150 /*
151 ** Usage:  sqlite3_exec_printf  DB  FORMAT  STRING
152 **
153 ** Invoke the sqlite3_exec_printf() interface using the open database
154 ** DB.  The SQL is the string FORMAT.  The format string should contain
155 ** one %s or %q.  STRING is the value inserted into %s or %q.
156 */
157 static int test_exec_printf(
158   void *NotUsed,
159   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
160   int argc,              /* Number of arguments */
161   char **argv            /* Text of each argument */
162 ){
163   sqlite3 *db;
164   Tcl_DString str;
165   int rc;
166   char *zErr = 0;
167   char *zSql;
168   char zBuf[30];
169   if( argc!=4 ){
170     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
171        " DB FORMAT STRING", 0);
172     return TCL_ERROR;
173   }
174   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
175   Tcl_DStringInit(&str);
176   zSql = sqlite3_mprintf(argv[2], argv[3]);
177   rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr);
178   sqlite3_free(zSql);
179   sprintf(zBuf, "%d", rc);
180   Tcl_AppendElement(interp, zBuf);
181   Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);
182   Tcl_DStringFree(&str);
183   if( zErr ) free(zErr);
184   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
185   return TCL_OK;
186 }
187 
188 /*
189 ** Usage:  sqlite3_mprintf_z_test  SEPARATOR  ARG0  ARG1 ...
190 **
191 ** Test the %z format of mprintf().  Use multiple mprintf() calls to
192 ** concatenate arg0 through argn using separator as the separator.
193 ** Return the result.
194 */
195 static int test_mprintf_z(
196   void *NotUsed,
197   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
198   int argc,              /* Number of arguments */
199   char **argv            /* Text of each argument */
200 ){
201   char *zResult = 0;
202   int i;
203 
204   for(i=2; i<argc; i++){
205     zResult = sqlite3MPrintf("%z%s%s", zResult, argv[1], argv[i]);
206   }
207   Tcl_AppendResult(interp, zResult, 0);
208   sqliteFree(zResult);
209   return TCL_OK;
210 }
211 
212 /*
213 ** Usage:  sqlite3_get_table_printf  DB  FORMAT  STRING
214 **
215 ** Invoke the sqlite3_get_table_printf() interface using the open database
216 ** DB.  The SQL is the string FORMAT.  The format string should contain
217 ** one %s or %q.  STRING is the value inserted into %s or %q.
218 */
219 static int test_get_table_printf(
220   void *NotUsed,
221   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
222   int argc,              /* Number of arguments */
223   char **argv            /* Text of each argument */
224 ){
225   sqlite3 *db;
226   Tcl_DString str;
227   int rc;
228   char *zErr = 0;
229   int nRow, nCol;
230   char **aResult;
231   int i;
232   char zBuf[30];
233   char *zSql;
234   if( argc!=4 ){
235     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
236        " DB FORMAT STRING", 0);
237     return TCL_ERROR;
238   }
239   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
240   Tcl_DStringInit(&str);
241   zSql = sqlite3_mprintf(argv[2],argv[3]);
242   rc = sqlite3_get_table(db, zSql, &aResult, &nRow, &nCol, &zErr);
243   sqlite3_free(zSql);
244   sprintf(zBuf, "%d", rc);
245   Tcl_AppendElement(interp, zBuf);
246   if( rc==SQLITE_OK ){
247     sprintf(zBuf, "%d", nRow);
248     Tcl_AppendElement(interp, zBuf);
249     sprintf(zBuf, "%d", nCol);
250     Tcl_AppendElement(interp, zBuf);
251     for(i=0; i<(nRow+1)*nCol; i++){
252       Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL");
253     }
254   }else{
255     Tcl_AppendElement(interp, zErr);
256   }
257   sqlite3_free_table(aResult);
258   if( zErr ) free(zErr);
259   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
260   return TCL_OK;
261 }
262 
263 
264 /*
265 ** Usage:  sqlite3_last_insert_rowid DB
266 **
267 ** Returns the integer ROWID of the most recent insert.
268 */
269 static int test_last_rowid(
270   void *NotUsed,
271   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
272   int argc,              /* Number of arguments */
273   char **argv            /* Text of each argument */
274 ){
275   sqlite3 *db;
276   char zBuf[30];
277 
278   if( argc!=2 ){
279     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0);
280     return TCL_ERROR;
281   }
282   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
283   sprintf(zBuf, "%lld", sqlite3_last_insert_rowid(db));
284   Tcl_AppendResult(interp, zBuf, 0);
285   return SQLITE_OK;
286 }
287 
288 /*
289 ** Usage:  sqlite3_key DB KEY
290 **
291 ** Set the codec key.
292 */
293 static int test_key(
294   void *NotUsed,
295   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
296   int argc,              /* Number of arguments */
297   char **argv            /* Text of each argument */
298 ){
299   sqlite3 *db;
300   const char *zKey;
301   int nKey;
302   if( argc!=3 ){
303     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
304        " FILENAME\"", 0);
305     return TCL_ERROR;
306   }
307   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
308   zKey = argv[2];
309   nKey = strlen(zKey);
310 #ifdef SQLITE_HAS_CODEC
311   sqlite3_key(db, zKey, nKey);
312 #endif
313   return TCL_OK;
314 }
315 
316 /*
317 ** Usage:  sqlite3_rekey DB KEY
318 **
319 ** Change the codec key.
320 */
321 static int test_rekey(
322   void *NotUsed,
323   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
324   int argc,              /* Number of arguments */
325   char **argv            /* Text of each argument */
326 ){
327   sqlite3 *db;
328   const char *zKey;
329   int nKey;
330   if( argc!=3 ){
331     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
332        " FILENAME\"", 0);
333     return TCL_ERROR;
334   }
335   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
336   zKey = argv[2];
337   nKey = strlen(zKey);
338 #ifdef SQLITE_HAS_CODEC
339   sqlite3_rekey(db, zKey, nKey);
340 #endif
341   return TCL_OK;
342 }
343 
344 /*
345 ** Usage:  sqlite3_close DB
346 **
347 ** Closes the database opened by sqlite3_open.
348 */
349 static int sqlite_test_close(
350   void *NotUsed,
351   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
352   int argc,              /* Number of arguments */
353   char **argv            /* Text of each argument */
354 ){
355   sqlite3 *db;
356   int rc;
357   if( argc!=2 ){
358     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
359        " FILENAME\"", 0);
360     return TCL_ERROR;
361   }
362   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
363   rc = sqlite3_close(db);
364   Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
365   return TCL_OK;
366 }
367 
368 /*
369 ** Implementation of the x_coalesce() function.
370 ** Return the first argument non-NULL argument.
371 */
372 static void ifnullFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
373   int i;
374   for(i=0; i<argc; i++){
375     if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){
376       sqlite3_result_text(context, sqlite3_value_text(argv[i]), -1,
377           SQLITE_TRANSIENT);
378       break;
379     }
380   }
381 }
382 
383 /*
384 ** A structure into which to accumulate text.
385 */
386 struct dstr {
387   int nAlloc;  /* Space allocated */
388   int nUsed;   /* Space used */
389   char *z;     /* The space */
390 };
391 
392 /*
393 ** Append text to a dstr
394 */
395 static void dstrAppend(struct dstr *p, const char *z, int divider){
396   int n = strlen(z);
397   if( p->nUsed + n + 2 > p->nAlloc ){
398     char *zNew;
399     p->nAlloc = p->nAlloc*2 + n + 200;
400     zNew = sqliteRealloc(p->z, p->nAlloc);
401     if( zNew==0 ){
402       sqliteFree(p->z);
403       memset(p, 0, sizeof(*p));
404       return;
405     }
406     p->z = zNew;
407   }
408   if( divider && p->nUsed>0 ){
409     p->z[p->nUsed++] = divider;
410   }
411   memcpy(&p->z[p->nUsed], z, n+1);
412   p->nUsed += n;
413 }
414 
415 /*
416 ** Invoked for each callback from sqlite3ExecFunc
417 */
418 static int execFuncCallback(void *pData, int argc, char **argv, char **NotUsed){
419   struct dstr *p = (struct dstr*)pData;
420   int i;
421   for(i=0; i<argc; i++){
422     if( argv[i]==0 ){
423       dstrAppend(p, "NULL", ' ');
424     }else{
425       dstrAppend(p, argv[i], ' ');
426     }
427   }
428   return 0;
429 }
430 
431 /*
432 ** Implementation of the x_sqlite_exec() function.  This function takes
433 ** a single argument and attempts to execute that argument as SQL code.
434 ** This is illegal and should set the SQLITE_MISUSE flag on the database.
435 **
436 ** 2004-Jan-07:  We have changed this to make it legal to call sqlite3_exec()
437 ** from within a function call.
438 **
439 ** This routine simulates the effect of having two threads attempt to
440 ** use the same database at the same time.
441 */
442 static void sqlite3ExecFunc(
443   sqlite3_context *context,
444   int argc,
445   sqlite3_value **argv
446 ){
447   struct dstr x;
448   memset(&x, 0, sizeof(x));
449   sqlite3_exec((sqlite3*)sqlite3_user_data(context),
450       sqlite3_value_text(argv[0]),
451       execFuncCallback, &x, 0);
452   sqlite3_result_text(context, x.z, x.nUsed, SQLITE_TRANSIENT);
453   sqliteFree(x.z);
454 }
455 
456 /*
457 ** Usage:  sqlite_test_create_function DB
458 **
459 ** Call the sqlite3_create_function API on the given database in order
460 ** to create a function named "x_coalesce".  This function does the same thing
461 ** as the "coalesce" function.  This function also registers an SQL function
462 ** named "x_sqlite_exec" that invokes sqlite3_exec().  Invoking sqlite3_exec()
463 ** in this way is illegal recursion and should raise an SQLITE_MISUSE error.
464 ** The effect is similar to trying to use the same database connection from
465 ** two threads at the same time.
466 **
467 ** The original motivation for this routine was to be able to call the
468 ** sqlite3_create_function function while a query is in progress in order
469 ** to test the SQLITE_MISUSE detection logic.
470 */
471 static int test_create_function(
472   void *NotUsed,
473   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
474   int argc,              /* Number of arguments */
475   char **argv            /* Text of each argument */
476 ){
477   int rc;
478   sqlite3 *db;
479   extern void Md5_Register(sqlite3*);
480 
481   if( argc!=2 ){
482     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
483        " DB\"", 0);
484     return TCL_ERROR;
485   }
486   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
487   rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_ANY, 0,
488         ifnullFunc, 0, 0);
489 
490 #ifndef SQLITE_OMIT_UTF16
491   /* Use the sqlite3_create_function16() API here. Mainly for fun, but also
492   ** because it is not tested anywhere else. */
493   if( rc==SQLITE_OK ){
494     sqlite3_value *pVal;
495     pVal = sqlite3ValueNew();
496     sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC);
497     rc = sqlite3_create_function16(db,
498               sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
499               1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0);
500     sqlite3ValueFree(pVal);
501   }
502 #endif
503 
504   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
505   Tcl_SetResult(interp, (char *)errorName(rc), 0);
506   return TCL_OK;
507 }
508 
509 /*
510 ** Routines to implement the x_count() aggregate function.
511 */
512 typedef struct CountCtx CountCtx;
513 struct CountCtx {
514   int n;
515 };
516 static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
517   CountCtx *p;
518   p = sqlite3_aggregate_context(context, sizeof(*p));
519   if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0]) ) && p ){
520     p->n++;
521   }
522 }
523 static void countFinalize(sqlite3_context *context){
524   CountCtx *p;
525   p = sqlite3_aggregate_context(context, sizeof(*p));
526   sqlite3_result_int(context, p ? p->n : 0);
527 }
528 
529 /*
530 ** Usage:  sqlite_test_create_aggregate DB
531 **
532 ** Call the sqlite3_create_function API on the given database in order
533 ** to create a function named "x_count".  This function does the same thing
534 ** as the "md5sum" function.
535 **
536 ** The original motivation for this routine was to be able to call the
537 ** sqlite3_create_aggregate function while a query is in progress in order
538 ** to test the SQLITE_MISUSE detection logic.
539 */
540 static int test_create_aggregate(
541   void *NotUsed,
542   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
543   int argc,              /* Number of arguments */
544   char **argv            /* Text of each argument */
545 ){
546   sqlite3 *db;
547   int rc;
548   if( argc!=2 ){
549     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
550        " FILENAME\"", 0);
551     return TCL_ERROR;
552   }
553   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
554   rc = sqlite3_create_function(db, "x_count", 0, SQLITE_UTF8, 0, 0,
555       countStep,countFinalize);
556   if( rc==SQLITE_OK ){
557     sqlite3_create_function(db, "x_count", 1, SQLITE_UTF8, 0, 0,
558         countStep,countFinalize);
559   }
560   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
561   return TCL_OK;
562 }
563 
564 
565 
566 /*
567 ** Usage:  sqlite3_mprintf_int FORMAT INTEGER INTEGER INTEGER
568 **
569 ** Call mprintf with three integer arguments
570 */
571 static int sqlite3_mprintf_int(
572   void *NotUsed,
573   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
574   int argc,              /* Number of arguments */
575   char **argv            /* Text of each argument */
576 ){
577   int a[3], i;
578   char *z;
579   if( argc!=5 ){
580     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
581        " FORMAT INT INT INT\"", 0);
582     return TCL_ERROR;
583   }
584   for(i=2; i<5; i++){
585     if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;
586   }
587   z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]);
588   Tcl_AppendResult(interp, z, 0);
589   sqlite3_free(z);
590   return TCL_OK;
591 }
592 
593 /*
594 ** If zNum represents an integer that will fit in 64-bits, then set
595 ** *pValue to that integer and return true.  Otherwise return false.
596 */
597 static int sqlite3GetInt64(const char *zNum, i64 *pValue){
598   if( sqlite3FitsIn64Bits(zNum) ){
599     sqlite3atoi64(zNum, pValue);
600     return 1;
601   }
602   return 0;
603 }
604 
605 /*
606 ** Usage:  sqlite3_mprintf_int64 FORMAT INTEGER INTEGER INTEGER
607 **
608 ** Call mprintf with three 64-bit integer arguments
609 */
610 static int sqlite3_mprintf_int64(
611   void *NotUsed,
612   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
613   int argc,              /* Number of arguments */
614   char **argv            /* Text of each argument */
615 ){
616   int i;
617   sqlite_int64 a[3];
618   char *z;
619   if( argc!=5 ){
620     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
621        " FORMAT INT INT INT\"", 0);
622     return TCL_ERROR;
623   }
624   for(i=2; i<5; i++){
625     if( !sqlite3GetInt64(argv[i], &a[i-2]) ){
626       Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0);
627       return TCL_ERROR;
628     }
629   }
630   z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]);
631   Tcl_AppendResult(interp, z, 0);
632   sqlite3_free(z);
633   return TCL_OK;
634 }
635 
636 /*
637 ** Usage:  sqlite3_mprintf_str FORMAT INTEGER INTEGER STRING
638 **
639 ** Call mprintf with two integer arguments and one string argument
640 */
641 static int sqlite3_mprintf_str(
642   void *NotUsed,
643   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
644   int argc,              /* Number of arguments */
645   char **argv            /* Text of each argument */
646 ){
647   int a[3], i;
648   char *z;
649   if( argc<4 || argc>5 ){
650     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
651        " FORMAT INT INT ?STRING?\"", 0);
652     return TCL_ERROR;
653   }
654   for(i=2; i<4; i++){
655     if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;
656   }
657   z = sqlite3_mprintf(argv[1], a[0], a[1], argc>4 ? argv[4] : NULL);
658   Tcl_AppendResult(interp, z, 0);
659   sqlite3_free(z);
660   return TCL_OK;
661 }
662 
663 /*
664 ** Usage:  sqlite3_mprintf_double FORMAT INTEGER INTEGER DOUBLE
665 **
666 ** Call mprintf with two integer arguments and one double argument
667 */
668 static int sqlite3_mprintf_double(
669   void *NotUsed,
670   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
671   int argc,              /* Number of arguments */
672   char **argv            /* Text of each argument */
673 ){
674   int a[3], i;
675   double r;
676   char *z;
677   if( argc!=5 ){
678     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
679        " FORMAT INT INT DOUBLE\"", 0);
680     return TCL_ERROR;
681   }
682   for(i=2; i<4; i++){
683     if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;
684   }
685   if( Tcl_GetDouble(interp, argv[4], &r) ) return TCL_ERROR;
686   z = sqlite3_mprintf(argv[1], a[0], a[1], r);
687   Tcl_AppendResult(interp, z, 0);
688   sqlite3_free(z);
689   return TCL_OK;
690 }
691 
692 /*
693 ** Usage:  sqlite3_mprintf_scaled FORMAT DOUBLE DOUBLE
694 **
695 ** Call mprintf with a single double argument which is the product of the
696 ** two arguments given above.  This is used to generate overflow and underflow
697 ** doubles to test that they are converted properly.
698 */
699 static int sqlite3_mprintf_scaled(
700   void *NotUsed,
701   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
702   int argc,              /* Number of arguments */
703   char **argv            /* Text of each argument */
704 ){
705   int i;
706   double r[2];
707   char *z;
708   if( argc!=4 ){
709     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
710        " FORMAT DOUBLE DOUBLE\"", 0);
711     return TCL_ERROR;
712   }
713   for(i=2; i<4; i++){
714     if( Tcl_GetDouble(interp, argv[i], &r[i-2]) ) return TCL_ERROR;
715   }
716   z = sqlite3_mprintf(argv[1], r[0]*r[1]);
717   Tcl_AppendResult(interp, z, 0);
718   sqlite3_free(z);
719   return TCL_OK;
720 }
721 
722 /*
723 ** Usage:  sqlite3_mprintf_stronly FORMAT STRING
724 **
725 ** Call mprintf with a single double argument which is the product of the
726 ** two arguments given above.  This is used to generate overflow and underflow
727 ** doubles to test that they are converted properly.
728 */
729 static int sqlite3_mprintf_stronly(
730   void *NotUsed,
731   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
732   int argc,              /* Number of arguments */
733   char **argv            /* Text of each argument */
734 ){
735   char *z;
736   if( argc!=3 ){
737     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
738        " FORMAT STRING\"", 0);
739     return TCL_ERROR;
740   }
741   z = sqlite3_mprintf(argv[1], argv[2]);
742   Tcl_AppendResult(interp, z, 0);
743   sqlite3_free(z);
744   return TCL_OK;
745 }
746 
747 /*
748 ** Usage:  sqlite3_mprintf_hexdouble FORMAT HEX
749 **
750 ** Call mprintf with a single double argument which is derived from the
751 ** hexadecimal encoding of an IEEE double.
752 */
753 static int sqlite3_mprintf_hexdouble(
754   void *NotUsed,
755   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
756   int argc,              /* Number of arguments */
757   char **argv            /* Text of each argument */
758 ){
759   char *z;
760   double r;
761   unsigned  x1, x2;
762   long long unsigned d;
763   if( argc!=3 ){
764     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
765        " FORMAT STRING\"", 0);
766     return TCL_ERROR;
767   }
768   if( sscanf(argv[2], "%08x%08x", &x2, &x1)!=2 ){
769     Tcl_AppendResult(interp, "2nd argument should be 16-characters of hex", 0);
770     return TCL_ERROR;
771   }
772   d = x2;
773   d = (d<<32) + x1;
774   memcpy(&r, &d, sizeof(r));
775   z = sqlite3_mprintf(argv[1], r);
776   Tcl_AppendResult(interp, z, 0);
777   sqlite3_free(z);
778   return TCL_OK;
779 }
780 
781 /*
782 ** Usage: sqlite_malloc_fail N  ?REPEAT-INTERVAL?
783 **
784 ** Rig sqliteMalloc() to fail on the N-th call and every REPEAT-INTERVAL call
785 ** after that.  If REPEAT-INTERVAL is 0 or is omitted, then only a single
786 ** malloc will fail.  If REPEAT-INTERVAL is 1 then all mallocs after the
787 ** first failure will continue to fail on every call.  If REPEAT-INTERVAL is
788 ** 2 then every other malloc will fail.  And so forth.
789 **
790 ** Turn off this mechanism and reset the sqlite3_malloc_failed variable is N==0.
791 */
792 #ifdef SQLITE_MEMDEBUG
793 static int sqlite_malloc_fail(
794   void *NotUsed,
795   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
796   int argc,              /* Number of arguments */
797   char **argv            /* Text of each argument */
798 ){
799   int n;
800   int rep;
801   if( argc!=2 && argc!=3 ){
802     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " N\"", 0);
803     return TCL_ERROR;
804   }
805   if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR;
806   if( argc==3 ){
807     if( Tcl_GetInt(interp, argv[2], &rep) ) return TCL_ERROR;
808   }else{
809     rep = 0;
810   }
811   sqlite3_iMallocFail = n;
812   sqlite3_iMallocReset = rep;
813   sqlite3_malloc_failed = 0;
814   return TCL_OK;
815 }
816 #endif
817 
818 /*
819 ** Usage: sqlite_malloc_stat
820 **
821 ** Return the number of prior calls to sqliteMalloc() and sqliteFree().
822 */
823 #ifdef SQLITE_MEMDEBUG
824 static int sqlite_malloc_stat(
825   void *NotUsed,
826   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
827   int argc,              /* Number of arguments */
828   char **argv            /* Text of each argument */
829 ){
830   char zBuf[200];
831   sprintf(zBuf, "%d %d %d", sqlite3_nMalloc, sqlite3_nFree, sqlite3_iMallocFail);
832   Tcl_AppendResult(interp, zBuf, 0);
833   return TCL_OK;
834 }
835 #endif
836 
837 /*
838 ** Usage:  sqlite_abort
839 **
840 ** Shutdown the process immediately.  This is not a clean shutdown.
841 ** This command is used to test the recoverability of a database in
842 ** the event of a program crash.
843 */
844 static int sqlite_abort(
845   void *NotUsed,
846   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
847   int argc,              /* Number of arguments */
848   char **argv            /* Text of each argument */
849 ){
850   assert( interp==0 );   /* This will always fail */
851   return TCL_OK;
852 }
853 
854 /*
855 ** The following routine is a user-defined SQL function whose purpose
856 ** is to test the sqlite_set_result() API.
857 */
858 static void testFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
859   while( argc>=2 ){
860     const char *zArg0 = sqlite3_value_text(argv[0]);
861     if( zArg0 ){
862       if( 0==sqlite3StrICmp(zArg0, "int") ){
863         sqlite3_result_int(context, sqlite3_value_int(argv[1]));
864       }else if( sqlite3StrICmp(zArg0,"int64")==0 ){
865         sqlite3_result_int64(context, sqlite3_value_int64(argv[1]));
866       }else if( sqlite3StrICmp(zArg0,"string")==0 ){
867         sqlite3_result_text(context, sqlite3_value_text(argv[1]), -1,
868             SQLITE_TRANSIENT);
869       }else if( sqlite3StrICmp(zArg0,"double")==0 ){
870         sqlite3_result_double(context, sqlite3_value_double(argv[1]));
871       }else if( sqlite3StrICmp(zArg0,"null")==0 ){
872         sqlite3_result_null(context);
873       }else if( sqlite3StrICmp(zArg0,"value")==0 ){
874         sqlite3_result_value(context, argv[sqlite3_value_int(argv[1])]);
875       }else{
876         goto error_out;
877       }
878     }else{
879       goto error_out;
880     }
881     argc -= 2;
882     argv += 2;
883   }
884   return;
885 
886 error_out:
887   sqlite3_result_error(context,"first argument should be one of: "
888       "int int64 string double null value", -1);
889 }
890 
891 /*
892 ** Usage:   sqlite_register_test_function  DB  NAME
893 **
894 ** Register the test SQL function on the database DB under the name NAME.
895 */
896 static int test_register_func(
897   void *NotUsed,
898   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
899   int argc,              /* Number of arguments */
900   char **argv            /* Text of each argument */
901 ){
902   sqlite3 *db;
903   int rc;
904   if( argc!=3 ){
905     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
906        " DB FUNCTION-NAME", 0);
907     return TCL_ERROR;
908   }
909   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
910   rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0,
911       testFunc, 0, 0);
912   if( rc!=0 ){
913     Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0);
914     return TCL_ERROR;
915   }
916   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
917   return TCL_OK;
918 }
919 
920 /*
921 ** Usage:  sqlite3_finalize  STMT
922 **
923 ** Finalize a statement handle.
924 */
925 static int test_finalize(
926   void * clientData,
927   Tcl_Interp *interp,
928   int objc,
929   Tcl_Obj *CONST objv[]
930 ){
931   sqlite3_stmt *pStmt;
932   int rc;
933   sqlite3 *db;
934 
935   if( objc!=2 ){
936     Tcl_AppendResult(interp, "wrong # args: should be \"",
937         Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0);
938     return TCL_ERROR;
939   }
940 
941   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
942 
943   if( pStmt ){
944     db = StmtToDb(pStmt);
945   }
946   rc = sqlite3_finalize(pStmt);
947   Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
948   if( db && sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
949   return TCL_OK;
950 }
951 
952 /*
953 ** Usage:  sqlite3_reset  STMT
954 **
955 ** Finalize a statement handle.
956 */
957 static int test_reset(
958   void * clientData,
959   Tcl_Interp *interp,
960   int objc,
961   Tcl_Obj *CONST objv[]
962 ){
963   sqlite3_stmt *pStmt;
964   int rc;
965 
966   if( objc!=2 ){
967     Tcl_AppendResult(interp, "wrong # args: should be \"",
968         Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0);
969     return TCL_ERROR;
970   }
971 
972   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
973 
974   rc = sqlite3_reset(pStmt);
975   if( pStmt &&
976       sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
977   Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
978   if( rc ){
979     return TCL_ERROR;
980   }
981   return TCL_OK;
982 }
983 
984 /*
985 ** Usage:  sqlite3_expired STMT
986 **
987 ** Return TRUE if a recompilation of the statement is recommended.
988 */
989 static int test_expired(
990   void * clientData,
991   Tcl_Interp *interp,
992   int objc,
993   Tcl_Obj *CONST objv[]
994 ){
995   sqlite3_stmt *pStmt;
996   if( objc!=2 ){
997     Tcl_AppendResult(interp, "wrong # args: should be \"",
998         Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0);
999     return TCL_ERROR;
1000   }
1001   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1002   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(sqlite3_expired(pStmt)));
1003   return TCL_OK;
1004 }
1005 
1006 /*
1007 ** Usage:  sqlite3_transfer_bindings FROMSTMT TOSTMT
1008 **
1009 ** Transfer all bindings from FROMSTMT over to TOSTMT
1010 */
1011 static int test_transfer_bind(
1012   void * clientData,
1013   Tcl_Interp *interp,
1014   int objc,
1015   Tcl_Obj *CONST objv[]
1016 ){
1017   sqlite3_stmt *pStmt1, *pStmt2;
1018   if( objc!=3 ){
1019     Tcl_AppendResult(interp, "wrong # args: should be \"",
1020         Tcl_GetStringFromObj(objv[0], 0), " FROM-STMT TO-STMT", 0);
1021     return TCL_ERROR;
1022   }
1023   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt1)) return TCL_ERROR;
1024   if( getStmtPointer(interp, Tcl_GetString(objv[2]), &pStmt2)) return TCL_ERROR;
1025   Tcl_SetObjResult(interp,
1026      Tcl_NewIntObj(sqlite3_transfer_bindings(pStmt1,pStmt2)));
1027   return TCL_OK;
1028 }
1029 
1030 /*
1031 ** Usage:  sqlite3_changes DB
1032 **
1033 ** Return the number of changes made to the database by the last SQL
1034 ** execution.
1035 */
1036 static int test_changes(
1037   void * clientData,
1038   Tcl_Interp *interp,
1039   int objc,
1040   Tcl_Obj *CONST objv[]
1041 ){
1042   sqlite3 *db;
1043   if( objc!=2 ){
1044     Tcl_AppendResult(interp, "wrong # args: should be \"",
1045        Tcl_GetString(objv[0]), " DB", 0);
1046     return TCL_ERROR;
1047   }
1048   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
1049   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_changes(db)));
1050   return TCL_OK;
1051 }
1052 
1053 /*
1054 ** This is the "static_bind_value" that variables are bound to when
1055 ** the FLAG option of sqlite3_bind is "static"
1056 */
1057 static char *sqlite_static_bind_value = 0;
1058 
1059 /*
1060 ** Usage:  sqlite3_bind  VM  IDX  VALUE  FLAGS
1061 **
1062 ** Sets the value of the IDX-th occurance of "?" in the original SQL
1063 ** string.  VALUE is the new value.  If FLAGS=="null" then VALUE is
1064 ** ignored and the value is set to NULL.  If FLAGS=="static" then
1065 ** the value is set to the value of a static variable named
1066 ** "sqlite_static_bind_value".  If FLAGS=="normal" then a copy
1067 ** of the VALUE is made.
1068 */
1069 static int test_bind(
1070   void *NotUsed,
1071   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1072   int argc,              /* Number of arguments */
1073   char **argv            /* Text of each argument */
1074 ){
1075   sqlite3_stmt *pStmt;
1076   int rc;
1077   int idx;
1078   if( argc!=5 ){
1079     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1080        " VM IDX VALUE (null|static|normal)\"", 0);
1081     return TCL_ERROR;
1082   }
1083   if( getStmtPointer(interp, argv[1], &pStmt) ) return TCL_ERROR;
1084   if( Tcl_GetInt(interp, argv[2], &idx) ) return TCL_ERROR;
1085   if( strcmp(argv[4],"null")==0 ){
1086     rc = sqlite3_bind_null(pStmt, idx);
1087   }else if( strcmp(argv[4],"static")==0 ){
1088     rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value, -1, 0);
1089   }else if( strcmp(argv[4],"normal")==0 ){
1090     rc = sqlite3_bind_text(pStmt, idx, argv[3], -1, SQLITE_TRANSIENT);
1091   }else{
1092     Tcl_AppendResult(interp, "4th argument should be "
1093         "\"null\" or \"static\" or \"normal\"", 0);
1094     return TCL_ERROR;
1095   }
1096   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
1097   if( rc ){
1098     char zBuf[50];
1099     sprintf(zBuf, "(%d) ", rc);
1100     Tcl_AppendResult(interp, zBuf, sqlite3ErrStr(rc), 0);
1101     return TCL_ERROR;
1102   }
1103   return TCL_OK;
1104 }
1105 
1106 #ifndef SQLITE_OMIT_UTF16
1107 /*
1108 ** Usage: add_test_collate <db ptr> <utf8> <utf16le> <utf16be>
1109 **
1110 ** This function is used to test that SQLite selects the correct collation
1111 ** sequence callback when multiple versions (for different text encodings)
1112 ** are available.
1113 **
1114 ** Calling this routine registers the collation sequence "test_collate"
1115 ** with database handle <db>. The second argument must be a list of three
1116 ** boolean values. If the first is true, then a version of test_collate is
1117 ** registered for UTF-8, if the second is true, a version is registered for
1118 ** UTF-16le, if the third is true, a UTF-16be version is available.
1119 ** Previous versions of test_collate are deleted.
1120 **
1121 ** The collation sequence test_collate is implemented by calling the
1122 ** following TCL script:
1123 **
1124 **   "test_collate <enc> <lhs> <rhs>"
1125 **
1126 ** The <lhs> and <rhs> are the two values being compared, encoded in UTF-8.
1127 ** The <enc> parameter is the encoding of the collation function that
1128 ** SQLite selected to call. The TCL test script implements the
1129 ** "test_collate" proc.
1130 **
1131 ** Note that this will only work with one intepreter at a time, as the
1132 ** interp pointer to use when evaluating the TCL script is stored in
1133 ** pTestCollateInterp.
1134 */
1135 static Tcl_Interp* pTestCollateInterp;
1136 static int test_collate_func(
1137   void *pCtx,
1138   int nA, const void *zA,
1139   int nB, const void *zB
1140 ){
1141   Tcl_Interp *i = pTestCollateInterp;
1142   int encin = (int)pCtx;
1143   int res;
1144   int n;
1145 
1146   sqlite3_value *pVal;
1147   Tcl_Obj *pX;
1148 
1149   pX = Tcl_NewStringObj("test_collate", -1);
1150   Tcl_IncrRefCount(pX);
1151 
1152   switch( encin ){
1153     case SQLITE_UTF8:
1154       Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-8",-1));
1155       break;
1156     case SQLITE_UTF16LE:
1157       Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16LE",-1));
1158       break;
1159     case SQLITE_UTF16BE:
1160       Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16BE",-1));
1161       break;
1162     default:
1163       assert(0);
1164   }
1165 
1166   pVal = sqlite3ValueNew();
1167   sqlite3ValueSetStr(pVal, nA, zA, encin, SQLITE_STATIC);
1168   n = sqlite3_value_bytes(pVal);
1169   Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj(sqlite3_value_text(pVal),n));
1170   sqlite3ValueSetStr(pVal, nB, zB, encin, SQLITE_STATIC);
1171   n = sqlite3_value_bytes(pVal);
1172   Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj(sqlite3_value_text(pVal),n));
1173   sqlite3ValueFree(pVal);
1174 
1175   Tcl_EvalObjEx(i, pX, 0);
1176   Tcl_DecrRefCount(pX);
1177   Tcl_GetIntFromObj(i, Tcl_GetObjResult(i), &res);
1178   return res;
1179 }
1180 static int test_collate(
1181   void * clientData,
1182   Tcl_Interp *interp,
1183   int objc,
1184   Tcl_Obj *CONST objv[]
1185 ){
1186   sqlite3 *db;
1187   int val;
1188   sqlite3_value *pVal;
1189   int rc;
1190 
1191   if( objc!=5 ) goto bad_args;
1192   pTestCollateInterp = interp;
1193   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
1194 
1195   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
1196   rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF8,
1197           (void *)SQLITE_UTF8, val?test_collate_func:0);
1198   if( rc==SQLITE_OK ){
1199     if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
1200     rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE,
1201             (void *)SQLITE_UTF16LE, val?test_collate_func:0);
1202     if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;
1203 
1204     pVal = sqlite3ValueNew();
1205     sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC);
1206     sqlite3_create_collation16(db, sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
1207           SQLITE_UTF16BE, (void *)SQLITE_UTF16BE, val?test_collate_func:0);
1208     sqlite3ValueFree(pVal);
1209   }
1210   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
1211   return TCL_OK;
1212 
1213 bad_args:
1214   Tcl_AppendResult(interp, "wrong # args: should be \"",
1215       Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0);
1216   return TCL_ERROR;
1217 }
1218 
1219 static void test_collate_needed_cb(
1220   void *pCtx,
1221   sqlite3 *db,
1222   int eTextRep,
1223   const void *notUsed
1224 ){
1225   int enc = db->enc;
1226   sqlite3_create_collation(
1227       db, "test_collate", db->enc, (void *)enc, test_collate_func);
1228 }
1229 
1230 /*
1231 ** Usage: add_test_collate_needed DB
1232 */
1233 static int test_collate_needed(
1234   void * clientData,
1235   Tcl_Interp *interp,
1236   int objc,
1237   Tcl_Obj *CONST objv[]
1238 ){
1239   sqlite3 *db;
1240   int rc;
1241 
1242   if( objc!=2 ) goto bad_args;
1243   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
1244   rc = sqlite3_collation_needed16(db, 0, test_collate_needed_cb);
1245   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
1246   return TCL_OK;
1247 
1248 bad_args:
1249   Tcl_WrongNumArgs(interp, 1, objv, "DB");
1250   return TCL_ERROR;
1251 }
1252 #endif /* SQLITE_OMIT_UTF16 */
1253 
1254 /*
1255 ** Usage: add_test_function <db ptr> <utf8> <utf16le> <utf16be>
1256 **
1257 ** This function is used to test that SQLite selects the correct user
1258 ** function callback when multiple versions (for different text encodings)
1259 ** are available.
1260 **
1261 ** Calling this routine registers up to three versions of the user function
1262 ** "test_function" with database handle <db>.  If the second argument is
1263 ** true, then a version of test_function is registered for UTF-8, if the
1264 ** third is true, a version is registered for UTF-16le, if the fourth is
1265 ** true, a UTF-16be version is available.  Previous versions of
1266 ** test_function are deleted.
1267 **
1268 ** The user function is implemented by calling the following TCL script:
1269 **
1270 **   "test_function <enc> <arg>"
1271 **
1272 ** Where <enc> is one of UTF-8, UTF-16LE or UTF16BE, and <arg> is the
1273 ** single argument passed to the SQL function. The value returned by
1274 ** the TCL script is used as the return value of the SQL function. It
1275 ** is passed to SQLite using UTF-16BE for a UTF-8 test_function(), UTF-8
1276 ** for a UTF-16LE test_function(), and UTF-16LE for an implementation that
1277 ** prefers UTF-16BE.
1278 */
1279 #ifndef SQLITE_OMIT_UTF16
1280 static void test_function_utf8(
1281   sqlite3_context *pCtx,
1282   int nArg,
1283   sqlite3_value **argv
1284 ){
1285   Tcl_Interp *interp;
1286   Tcl_Obj *pX;
1287   sqlite3_value *pVal;
1288   interp = (Tcl_Interp *)sqlite3_user_data(pCtx);
1289   pX = Tcl_NewStringObj("test_function", -1);
1290   Tcl_IncrRefCount(pX);
1291   Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-8", -1));
1292   Tcl_ListObjAppendElement(interp, pX,
1293       Tcl_NewStringObj(sqlite3_value_text(argv[0]), -1));
1294   Tcl_EvalObjEx(interp, pX, 0);
1295   Tcl_DecrRefCount(pX);
1296   sqlite3_result_text(pCtx, Tcl_GetStringResult(interp), -1, SQLITE_TRANSIENT);
1297   pVal = sqlite3ValueNew();
1298   sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp),
1299       SQLITE_UTF8, SQLITE_STATIC);
1300   sqlite3_result_text16be(pCtx, sqlite3_value_text16be(pVal),
1301       -1, SQLITE_TRANSIENT);
1302   sqlite3ValueFree(pVal);
1303 }
1304 static void test_function_utf16le(
1305   sqlite3_context *pCtx,
1306   int nArg,
1307   sqlite3_value **argv
1308 ){
1309   Tcl_Interp *interp;
1310   Tcl_Obj *pX;
1311   sqlite3_value *pVal;
1312   interp = (Tcl_Interp *)sqlite3_user_data(pCtx);
1313   pX = Tcl_NewStringObj("test_function", -1);
1314   Tcl_IncrRefCount(pX);
1315   Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16LE", -1));
1316   Tcl_ListObjAppendElement(interp, pX,
1317       Tcl_NewStringObj(sqlite3_value_text(argv[0]), -1));
1318   Tcl_EvalObjEx(interp, pX, 0);
1319   Tcl_DecrRefCount(pX);
1320   pVal = sqlite3ValueNew();
1321   sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp),
1322       SQLITE_UTF8, SQLITE_STATIC);
1323   sqlite3_result_text(pCtx,sqlite3_value_text(pVal),-1,SQLITE_TRANSIENT);
1324   sqlite3ValueFree(pVal);
1325 }
1326 static void test_function_utf16be(
1327   sqlite3_context *pCtx,
1328   int nArg,
1329   sqlite3_value **argv
1330 ){
1331   Tcl_Interp *interp;
1332   Tcl_Obj *pX;
1333   sqlite3_value *pVal;
1334   interp = (Tcl_Interp *)sqlite3_user_data(pCtx);
1335   pX = Tcl_NewStringObj("test_function", -1);
1336   Tcl_IncrRefCount(pX);
1337   Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16BE", -1));
1338   Tcl_ListObjAppendElement(interp, pX,
1339       Tcl_NewStringObj(sqlite3_value_text(argv[0]), -1));
1340   Tcl_EvalObjEx(interp, pX, 0);
1341   Tcl_DecrRefCount(pX);
1342   pVal = sqlite3ValueNew();
1343   sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp),
1344       SQLITE_UTF8, SQLITE_STATIC);
1345   sqlite3_result_text16le(pCtx, sqlite3_value_text16le(pVal),
1346       -1, SQLITE_TRANSIENT);
1347   sqlite3ValueFree(pVal);
1348 }
1349 #endif /* SQLITE_OMIT_UTF16 */
1350 static int test_function(
1351   void * clientData,
1352   Tcl_Interp *interp,
1353   int objc,
1354   Tcl_Obj *CONST objv[]
1355 ){
1356 #ifndef SQLITE_OMIT_UTF16
1357   sqlite3 *db;
1358   int val;
1359 
1360   if( objc!=5 ) goto bad_args;
1361   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
1362 
1363   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
1364   if( val ){
1365     sqlite3_create_function(db, "test_function", 1, SQLITE_UTF8,
1366         interp, test_function_utf8, 0, 0);
1367   }
1368   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
1369   if( val ){
1370     sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16LE,
1371         interp, test_function_utf16le, 0, 0);
1372   }
1373   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;
1374   if( val ){
1375     sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16BE,
1376         interp, test_function_utf16be, 0, 0);
1377   }
1378 
1379   return TCL_OK;
1380 bad_args:
1381   Tcl_AppendResult(interp, "wrong # args: should be \"",
1382       Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0);
1383 #endif /* SQLITE_OMIT_UTF16 */
1384   return TCL_ERROR;
1385 }
1386 
1387 /*
1388 ** Usage:         test_errstr <err code>
1389 **
1390 ** Test that the english language string equivalents for sqlite error codes
1391 ** are sane. The parameter is an integer representing an sqlite error code.
1392 ** The result is a list of two elements, the string representation of the
1393 ** error code and the english language explanation.
1394 */
1395 static int test_errstr(
1396   void * clientData,
1397   Tcl_Interp *interp,
1398   int objc,
1399   Tcl_Obj *CONST objv[]
1400 ){
1401   char *zCode;
1402   int i;
1403   if( objc!=1 ){
1404     Tcl_WrongNumArgs(interp, 1, objv, "<error code>");
1405   }
1406 
1407   zCode = Tcl_GetString(objv[1]);
1408   for(i=0; i<200; i++){
1409     if( 0==strcmp(errorName(i), zCode) ) break;
1410   }
1411   Tcl_SetResult(interp, (char *)sqlite3ErrStr(i), 0);
1412   return TCL_OK;
1413 }
1414 
1415 static int sqlite3_crashparams(
1416   void * clientData,
1417   Tcl_Interp *interp,
1418   int objc,
1419   Tcl_Obj *CONST objv[]
1420 ){
1421 #ifdef OS_TEST
1422   int delay;
1423   if( objc!=3 ) goto bad_args;
1424   if( Tcl_GetIntFromObj(interp, objv[1], &delay) ) return TCL_ERROR;
1425   sqlite3SetCrashParams(delay, Tcl_GetString(objv[2]));
1426 #endif
1427   return TCL_OK;
1428 
1429 #ifdef OS_TEST
1430 bad_args:
1431   Tcl_AppendResult(interp, "wrong # args: should be \"",
1432       Tcl_GetStringFromObj(objv[0], 0), "<delay> <filename>", 0);
1433   return TCL_ERROR;
1434 #endif
1435 }
1436 
1437 
1438 /*
1439 ** Usage:    breakpoint
1440 **
1441 ** This routine exists for one purpose - to provide a place to put a
1442 ** breakpoint with GDB that can be triggered using TCL code.  The use
1443 ** for this is when a particular test fails on (say) the 1485th iteration.
1444 ** In the TCL test script, we can add code like this:
1445 **
1446 **     if {$i==1485} breakpoint
1447 **
1448 ** Then run testfixture in the debugger and wait for the breakpoint to
1449 ** fire.  Then additional breakpoints can be set to trace down the bug.
1450 */
1451 static int test_breakpoint(
1452   void *NotUsed,
1453   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1454   int argc,              /* Number of arguments */
1455   char **argv            /* Text of each argument */
1456 ){
1457   return TCL_OK;         /* Do nothing */
1458 }
1459 
1460 /*
1461 ** Usage:   sqlite3_bind_int  STMT N VALUE
1462 **
1463 ** Test the sqlite3_bind_int interface.  STMT is a prepared statement.
1464 ** N is the index of a wildcard in the prepared statement.  This command
1465 ** binds a 32-bit integer VALUE to that wildcard.
1466 */
1467 static int test_bind_int(
1468   void * clientData,
1469   Tcl_Interp *interp,
1470   int objc,
1471   Tcl_Obj *CONST objv[]
1472 ){
1473   sqlite3_stmt *pStmt;
1474   int idx;
1475   int value;
1476   int rc;
1477 
1478   if( objc!=4 ){
1479     Tcl_AppendResult(interp, "wrong # args: should be \"",
1480         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0);
1481     return TCL_ERROR;
1482   }
1483 
1484   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1485   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
1486   if( Tcl_GetIntFromObj(interp, objv[3], &value) ) return TCL_ERROR;
1487 
1488   rc = sqlite3_bind_int(pStmt, idx, value);
1489   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
1490   if( rc!=SQLITE_OK ){
1491     return TCL_ERROR;
1492   }
1493 
1494   return TCL_OK;
1495 }
1496 
1497 
1498 /*
1499 ** Usage:   sqlite3_bind_int64  STMT N VALUE
1500 **
1501 ** Test the sqlite3_bind_int64 interface.  STMT is a prepared statement.
1502 ** N is the index of a wildcard in the prepared statement.  This command
1503 ** binds a 64-bit integer VALUE to that wildcard.
1504 */
1505 static int test_bind_int64(
1506   void * clientData,
1507   Tcl_Interp *interp,
1508   int objc,
1509   Tcl_Obj *CONST objv[]
1510 ){
1511   sqlite3_stmt *pStmt;
1512   int idx;
1513   i64 value;
1514   int rc;
1515 
1516   if( objc!=4 ){
1517     Tcl_AppendResult(interp, "wrong # args: should be \"",
1518         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0);
1519     return TCL_ERROR;
1520   }
1521 
1522   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1523   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
1524   if( Tcl_GetWideIntFromObj(interp, objv[3], &value) ) return TCL_ERROR;
1525 
1526   rc = sqlite3_bind_int64(pStmt, idx, value);
1527   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
1528   if( rc!=SQLITE_OK ){
1529     return TCL_ERROR;
1530   }
1531 
1532   return TCL_OK;
1533 }
1534 
1535 
1536 /*
1537 ** Usage:   sqlite3_bind_double  STMT N VALUE
1538 **
1539 ** Test the sqlite3_bind_double interface.  STMT is a prepared statement.
1540 ** N is the index of a wildcard in the prepared statement.  This command
1541 ** binds a 64-bit integer VALUE to that wildcard.
1542 */
1543 static int test_bind_double(
1544   void * clientData,
1545   Tcl_Interp *interp,
1546   int objc,
1547   Tcl_Obj *CONST objv[]
1548 ){
1549   sqlite3_stmt *pStmt;
1550   int idx;
1551   double value;
1552   int rc;
1553 
1554   if( objc!=4 ){
1555     Tcl_AppendResult(interp, "wrong # args: should be \"",
1556         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0);
1557     return TCL_ERROR;
1558   }
1559 
1560   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1561   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
1562   if( Tcl_GetDoubleFromObj(interp, objv[3], &value) ) return TCL_ERROR;
1563 
1564   rc = sqlite3_bind_double(pStmt, idx, value);
1565   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
1566   if( rc!=SQLITE_OK ){
1567     return TCL_ERROR;
1568   }
1569 
1570   return TCL_OK;
1571 }
1572 
1573 /*
1574 ** Usage:   sqlite3_bind_null  STMT N
1575 **
1576 ** Test the sqlite3_bind_null interface.  STMT is a prepared statement.
1577 ** N is the index of a wildcard in the prepared statement.  This command
1578 ** binds a NULL to the wildcard.
1579 */
1580 static int test_bind_null(
1581   void * clientData,
1582   Tcl_Interp *interp,
1583   int objc,
1584   Tcl_Obj *CONST objv[]
1585 ){
1586   sqlite3_stmt *pStmt;
1587   int idx;
1588   int rc;
1589 
1590   if( objc!=3 ){
1591     Tcl_AppendResult(interp, "wrong # args: should be \"",
1592         Tcl_GetStringFromObj(objv[0], 0), " STMT N", 0);
1593     return TCL_ERROR;
1594   }
1595 
1596   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1597   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
1598 
1599   rc = sqlite3_bind_null(pStmt, idx);
1600   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
1601   if( rc!=SQLITE_OK ){
1602     return TCL_ERROR;
1603   }
1604 
1605   return TCL_OK;
1606 }
1607 
1608 /*
1609 ** Usage:   sqlite3_bind_text  STMT N STRING BYTES
1610 **
1611 ** Test the sqlite3_bind_text interface.  STMT is a prepared statement.
1612 ** N is the index of a wildcard in the prepared statement.  This command
1613 ** binds a UTF-8 string STRING to the wildcard.  The string is BYTES bytes
1614 ** long.
1615 */
1616 static int test_bind_text(
1617   void * clientData,
1618   Tcl_Interp *interp,
1619   int objc,
1620   Tcl_Obj *CONST objv[]
1621 ){
1622   sqlite3_stmt *pStmt;
1623   int idx;
1624   int bytes;
1625   char *value;
1626   int rc;
1627 
1628   if( objc!=5 ){
1629     Tcl_AppendResult(interp, "wrong # args: should be \"",
1630         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0);
1631     return TCL_ERROR;
1632   }
1633 
1634   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1635   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
1636   value = Tcl_GetString(objv[3]);
1637   if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
1638 
1639   rc = sqlite3_bind_text(pStmt, idx, value, bytes, SQLITE_TRANSIENT);
1640   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
1641   if( rc!=SQLITE_OK ){
1642     Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
1643     return TCL_ERROR;
1644   }
1645 
1646   return TCL_OK;
1647 }
1648 
1649 /*
1650 ** Usage:   sqlite3_bind_text16  STMT N STRING BYTES
1651 **
1652 ** Test the sqlite3_bind_text16 interface.  STMT is a prepared statement.
1653 ** N is the index of a wildcard in the prepared statement.  This command
1654 ** binds a UTF-16 string STRING to the wildcard.  The string is BYTES bytes
1655 ** long.
1656 */
1657 static int test_bind_text16(
1658   void * clientData,
1659   Tcl_Interp *interp,
1660   int objc,
1661   Tcl_Obj *CONST objv[]
1662 ){
1663 #ifndef SQLITE_OMIT_UTF16
1664   sqlite3_stmt *pStmt;
1665   int idx;
1666   int bytes;
1667   char *value;
1668   int rc;
1669 
1670   if( objc!=5 ){
1671     Tcl_AppendResult(interp, "wrong # args: should be \"",
1672         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0);
1673     return TCL_ERROR;
1674   }
1675 
1676   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1677   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
1678   value = Tcl_GetByteArrayFromObj(objv[3], 0);
1679   if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
1680 
1681   rc = sqlite3_bind_text16(pStmt, idx, (void *)value, bytes, SQLITE_TRANSIENT);
1682   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
1683   if( rc!=SQLITE_OK ){
1684     return TCL_ERROR;
1685   }
1686 
1687 #endif /* SQLITE_OMIT_UTF16 */
1688   return TCL_OK;
1689 }
1690 
1691 /*
1692 ** Usage:   sqlite3_bind_blob  STMT N DATA BYTES
1693 **
1694 ** Test the sqlite3_bind_blob interface.  STMT is a prepared statement.
1695 ** N is the index of a wildcard in the prepared statement.  This command
1696 ** binds a BLOB to the wildcard.  The BLOB is BYTES bytes in size.
1697 */
1698 static int test_bind_blob(
1699   void * clientData,
1700   Tcl_Interp *interp,
1701   int objc,
1702   Tcl_Obj *CONST objv[]
1703 ){
1704   sqlite3_stmt *pStmt;
1705   int idx;
1706   int bytes;
1707   char *value;
1708   int rc;
1709 
1710   if( objc!=5 ){
1711     Tcl_AppendResult(interp, "wrong # args: should be \"",
1712         Tcl_GetStringFromObj(objv[0], 0), " STMT N DATA BYTES", 0);
1713     return TCL_ERROR;
1714   }
1715 
1716   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1717   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
1718   value = Tcl_GetString(objv[3]);
1719   if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
1720 
1721   rc = sqlite3_bind_blob(pStmt, idx, value, bytes, SQLITE_TRANSIENT);
1722   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
1723   if( rc!=SQLITE_OK ){
1724     return TCL_ERROR;
1725   }
1726 
1727   return TCL_OK;
1728 }
1729 
1730 /*
1731 ** Usage:   sqlite3_bind_parameter_count  STMT
1732 **
1733 ** Return the number of wildcards in the given statement.
1734 */
1735 static int test_bind_parameter_count(
1736   void * clientData,
1737   Tcl_Interp *interp,
1738   int objc,
1739   Tcl_Obj *CONST objv[]
1740 ){
1741   sqlite3_stmt *pStmt;
1742 
1743   if( objc!=2 ){
1744     Tcl_WrongNumArgs(interp, 1, objv, "STMT");
1745     return TCL_ERROR;
1746   }
1747   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1748   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_bind_parameter_count(pStmt)));
1749   return TCL_OK;
1750 }
1751 
1752 /*
1753 ** Usage:   sqlite3_bind_parameter_name  STMT  N
1754 **
1755 ** Return the name of the Nth wildcard.  The first wildcard is 1.
1756 ** An empty string is returned if N is out of range or if the wildcard
1757 ** is nameless.
1758 */
1759 static int test_bind_parameter_name(
1760   void * clientData,
1761   Tcl_Interp *interp,
1762   int objc,
1763   Tcl_Obj *CONST objv[]
1764 ){
1765   sqlite3_stmt *pStmt;
1766   int i;
1767 
1768   if( objc!=3 ){
1769     Tcl_WrongNumArgs(interp, 1, objv, "STMT N");
1770     return TCL_ERROR;
1771   }
1772   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1773   if( Tcl_GetIntFromObj(interp, objv[2], &i) ) return TCL_ERROR;
1774   Tcl_SetObjResult(interp,
1775      Tcl_NewStringObj(sqlite3_bind_parameter_name(pStmt,i),-1)
1776   );
1777   return TCL_OK;
1778 }
1779 
1780 /*
1781 ** Usage:   sqlite3_bind_parameter_index  STMT  NAME
1782 **
1783 ** Return the index of the wildcard called NAME.  Return 0 if there is
1784 ** no such wildcard.
1785 */
1786 static int test_bind_parameter_index(
1787   void * clientData,
1788   Tcl_Interp *interp,
1789   int objc,
1790   Tcl_Obj *CONST objv[]
1791 ){
1792   sqlite3_stmt *pStmt;
1793 
1794   if( objc!=3 ){
1795     Tcl_WrongNumArgs(interp, 1, objv, "STMT NAME");
1796     return TCL_ERROR;
1797   }
1798   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1799   Tcl_SetObjResult(interp,
1800      Tcl_NewIntObj(
1801        sqlite3_bind_parameter_index(pStmt,Tcl_GetString(objv[2]))
1802      )
1803   );
1804   return TCL_OK;
1805 }
1806 
1807 /*
1808 ** Usage:   sqlite3_clear_bindings STMT
1809 **
1810 */
1811 #if 0
1812 static int test_clear_bindings(
1813   void * clientData,
1814   Tcl_Interp *interp,
1815   int objc,
1816   Tcl_Obj *CONST objv[]
1817 ){
1818   sqlite3_stmt *pStmt;
1819 
1820   if( objc!=2 ){
1821     Tcl_WrongNumArgs(interp, 1, objv, "STMT");
1822     return TCL_ERROR;
1823   }
1824   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1825   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_clear_bindings(pStmt)));
1826   return TCL_OK;
1827 }
1828 #endif
1829 
1830 /*
1831 ** Usage: sqlite3_errcode DB
1832 **
1833 ** Return the string representation of the most recent sqlite3_* API
1834 ** error code. e.g. "SQLITE_ERROR".
1835 */
1836 static int test_errcode(
1837   void * clientData,
1838   Tcl_Interp *interp,
1839   int objc,
1840   Tcl_Obj *CONST objv[]
1841 ){
1842   sqlite3 *db;
1843 
1844   if( objc!=2 ){
1845     Tcl_AppendResult(interp, "wrong # args: should be \"",
1846        Tcl_GetString(objv[0]), " DB", 0);
1847     return TCL_ERROR;
1848   }
1849   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
1850   Tcl_SetResult(interp, (char *)errorName(sqlite3_errcode(db)), 0);
1851   return TCL_OK;
1852 }
1853 
1854 /*
1855 ** Usage:   test_errmsg DB
1856 **
1857 ** Returns the UTF-8 representation of the error message string for the
1858 ** most recent sqlite3_* API call.
1859 */
1860 static int test_errmsg(
1861   void * clientData,
1862   Tcl_Interp *interp,
1863   int objc,
1864   Tcl_Obj *CONST objv[]
1865 ){
1866   sqlite3 *db;
1867   const char *zErr;
1868 
1869   if( objc!=2 ){
1870     Tcl_AppendResult(interp, "wrong # args: should be \"",
1871        Tcl_GetString(objv[0]), " DB", 0);
1872     return TCL_ERROR;
1873   }
1874   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
1875 
1876   zErr = sqlite3_errmsg(db);
1877   Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1));
1878   return TCL_OK;
1879 }
1880 
1881 /*
1882 ** Usage:   test_errmsg16 DB
1883 **
1884 ** Returns the UTF-16 representation of the error message string for the
1885 ** most recent sqlite3_* API call. This is a byte array object at the TCL
1886 ** level, and it includes the 0x00 0x00 terminator bytes at the end of the
1887 ** UTF-16 string.
1888 */
1889 static int test_errmsg16(
1890   void * clientData,
1891   Tcl_Interp *interp,
1892   int objc,
1893   Tcl_Obj *CONST objv[]
1894 ){
1895 #ifndef SQLITE_OMIT_UTF16
1896   sqlite3 *db;
1897   const void *zErr;
1898   int bytes;
1899 
1900   if( objc!=2 ){
1901     Tcl_AppendResult(interp, "wrong # args: should be \"",
1902        Tcl_GetString(objv[0]), " DB", 0);
1903     return TCL_ERROR;
1904   }
1905   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
1906 
1907   zErr = sqlite3_errmsg16(db);
1908   bytes = sqlite3utf16ByteLen(zErr, -1);
1909   Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zErr, bytes));
1910 #endif /* SQLITE_OMIT_UTF16 */
1911   return TCL_OK;
1912 }
1913 
1914 /*
1915 ** Usage: sqlite3_prepare DB sql bytes tailvar
1916 **
1917 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
1918 ** database handle <DB>. The parameter <tailval> is the name of a global
1919 ** variable that is set to the unused portion of <sql> (if any). A
1920 ** STMT handle is returned.
1921 */
1922 static int test_prepare(
1923   void * clientData,
1924   Tcl_Interp *interp,
1925   int objc,
1926   Tcl_Obj *CONST objv[]
1927 ){
1928   sqlite3 *db;
1929   const char *zSql;
1930   int bytes;
1931   const char *zTail = 0;
1932   sqlite3_stmt *pStmt = 0;
1933   char zBuf[50];
1934   int rc;
1935 
1936   if( objc!=5 ){
1937     Tcl_AppendResult(interp, "wrong # args: should be \"",
1938        Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0);
1939     return TCL_ERROR;
1940   }
1941   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
1942   zSql = Tcl_GetString(objv[2]);
1943   if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
1944 
1945   rc = sqlite3_prepare(db, zSql, bytes, &pStmt, &zTail);
1946   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
1947   if( zTail ){
1948     if( bytes>=0 ){
1949       bytes = bytes - (zTail-zSql);
1950     }
1951     Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0);
1952   }
1953   if( rc!=SQLITE_OK ){
1954     assert( pStmt==0 );
1955     sprintf(zBuf, "(%d) ", rc);
1956     Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0);
1957     return TCL_ERROR;
1958   }
1959 
1960   if( pStmt ){
1961     if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
1962     Tcl_AppendResult(interp, zBuf, 0);
1963   }
1964   return TCL_OK;
1965 }
1966 
1967 /*
1968 ** Usage: sqlite3_prepare DB sql bytes tailvar
1969 **
1970 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
1971 ** database handle <DB>. The parameter <tailval> is the name of a global
1972 ** variable that is set to the unused portion of <sql> (if any). A
1973 ** STMT handle is returned.
1974 */
1975 static int test_prepare16(
1976   void * clientData,
1977   Tcl_Interp *interp,
1978   int objc,
1979   Tcl_Obj *CONST objv[]
1980 ){
1981 #ifndef SQLITE_OMIT_UTF16
1982   sqlite3 *db;
1983   const void *zSql;
1984   const void *zTail = 0;
1985   Tcl_Obj *pTail = 0;
1986   sqlite3_stmt *pStmt = 0;
1987   char zBuf[50];
1988   int rc;
1989   int bytes;                /* The integer specified as arg 3 */
1990   int objlen;               /* The byte-array length of arg 2 */
1991 
1992   if( objc!=5 ){
1993     Tcl_AppendResult(interp, "wrong # args: should be \"",
1994        Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0);
1995     return TCL_ERROR;
1996   }
1997   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
1998   zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen);
1999   if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
2000 
2001   rc = sqlite3_prepare16(db, zSql, bytes, &pStmt, &zTail);
2002   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
2003   if( rc ){
2004     return TCL_ERROR;
2005   }
2006 
2007   if( zTail ){
2008     objlen = objlen - ((u8 *)zTail-(u8 *)zSql);
2009   }else{
2010     objlen = 0;
2011   }
2012   pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen);
2013   Tcl_IncrRefCount(pTail);
2014   Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0);
2015   Tcl_DecrRefCount(pTail);
2016 
2017   if( pStmt ){
2018     if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
2019   }
2020   Tcl_AppendResult(interp, zBuf, 0);
2021 #endif /* SQLITE_OMIT_UTF16 */
2022   return TCL_OK;
2023 }
2024 
2025 /*
2026 ** Usage: sqlite3_open filename ?options-list?
2027 */
2028 static int test_open(
2029   void * clientData,
2030   Tcl_Interp *interp,
2031   int objc,
2032   Tcl_Obj *CONST objv[]
2033 ){
2034   const char *zFilename;
2035   sqlite3 *db;
2036   int rc;
2037   char zBuf[100];
2038 
2039   if( objc!=3 && objc!=2 ){
2040     Tcl_AppendResult(interp, "wrong # args: should be \"",
2041        Tcl_GetString(objv[0]), " filename options-list", 0);
2042     return TCL_ERROR;
2043   }
2044 
2045   zFilename = Tcl_GetString(objv[1]);
2046   rc = sqlite3_open(zFilename, &db);
2047 
2048   if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR;
2049   Tcl_AppendResult(interp, zBuf, 0);
2050   return TCL_OK;
2051 }
2052 
2053 /*
2054 ** Usage: sqlite3_open16 filename options
2055 */
2056 static int test_open16(
2057   void * clientData,
2058   Tcl_Interp *interp,
2059   int objc,
2060   Tcl_Obj *CONST objv[]
2061 ){
2062 #ifndef SQLITE_OMIT_UTF16
2063   const void *zFilename;
2064   sqlite3 *db;
2065   int rc;
2066   char zBuf[100];
2067 
2068   if( objc!=3 ){
2069     Tcl_AppendResult(interp, "wrong # args: should be \"",
2070        Tcl_GetString(objv[0]), " filename options-list", 0);
2071     return TCL_ERROR;
2072   }
2073 
2074   zFilename = Tcl_GetByteArrayFromObj(objv[1], 0);
2075   rc = sqlite3_open16(zFilename, &db);
2076 
2077   if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR;
2078   Tcl_AppendResult(interp, zBuf, 0);
2079 #endif /* SQLITE_OMIT_UTF16 */
2080   return TCL_OK;
2081 }
2082 
2083 /*
2084 ** Usage: sqlite3_complete16 <UTF-16 string>
2085 **
2086 ** Return 1 if the supplied argument is a complete SQL statement, or zero
2087 ** otherwise.
2088 */
2089 static int test_complete16(
2090   void * clientData,
2091   Tcl_Interp *interp,
2092   int objc,
2093   Tcl_Obj *CONST objv[]
2094 ){
2095 #if !defined(SQLITE_OMIT_COMPLETE) && !defined(SQLITE_OMIT_UTF16)
2096   char *zBuf;
2097 
2098   if( objc!=2 ){
2099     Tcl_WrongNumArgs(interp, 1, objv, "<utf-16 sql>");
2100     return TCL_ERROR;
2101   }
2102 
2103   zBuf = Tcl_GetByteArrayFromObj(objv[1], 0);
2104   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_complete16(zBuf)));
2105 #endif /* SQLITE_OMIT_COMPLETE && SQLITE_OMIT_UTF16 */
2106   return TCL_OK;
2107 }
2108 
2109 /*
2110 ** Usage: sqlite3_step STMT
2111 **
2112 ** Advance the statement to the next row.
2113 */
2114 static int test_step(
2115   void * clientData,
2116   Tcl_Interp *interp,
2117   int objc,
2118   Tcl_Obj *CONST objv[]
2119 ){
2120   sqlite3_stmt *pStmt;
2121   int rc;
2122 
2123   if( objc!=2 ){
2124     Tcl_AppendResult(interp, "wrong # args: should be \"",
2125        Tcl_GetString(objv[0]), " STMT", 0);
2126     return TCL_ERROR;
2127   }
2128 
2129   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2130   rc = sqlite3_step(pStmt);
2131 
2132   /* if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL_ERROR; */
2133   Tcl_SetResult(interp, (char *)errorName(rc), 0);
2134   return TCL_OK;
2135 }
2136 
2137 /*
2138 ** Usage: sqlite3_column_count STMT
2139 **
2140 ** Return the number of columns returned by the sql statement STMT.
2141 */
2142 static int test_column_count(
2143   void * clientData,
2144   Tcl_Interp *interp,
2145   int objc,
2146   Tcl_Obj *CONST objv[]
2147 ){
2148   sqlite3_stmt *pStmt;
2149 
2150   if( objc!=2 ){
2151     Tcl_AppendResult(interp, "wrong # args: should be \"",
2152        Tcl_GetString(objv[0]), " STMT column", 0);
2153     return TCL_ERROR;
2154   }
2155 
2156   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2157 
2158   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_column_count(pStmt)));
2159   return TCL_OK;
2160 }
2161 
2162 /*
2163 ** Usage: sqlite3_column_type STMT column
2164 **
2165 ** Return the type of the data in column 'column' of the current row.
2166 */
2167 static int test_column_type(
2168   void * clientData,
2169   Tcl_Interp *interp,
2170   int objc,
2171   Tcl_Obj *CONST objv[]
2172 ){
2173   sqlite3_stmt *pStmt;
2174   int col;
2175   int tp;
2176 
2177   if( objc!=3 ){
2178     Tcl_AppendResult(interp, "wrong # args: should be \"",
2179        Tcl_GetString(objv[0]), " STMT column", 0);
2180     return TCL_ERROR;
2181   }
2182 
2183   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2184   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
2185 
2186   tp = sqlite3_column_type(pStmt, col);
2187   switch( tp ){
2188     case SQLITE_INTEGER:
2189       Tcl_SetResult(interp, "INTEGER", TCL_STATIC);
2190       break;
2191     case SQLITE_NULL:
2192       Tcl_SetResult(interp, "NULL", TCL_STATIC);
2193       break;
2194     case SQLITE_FLOAT:
2195       Tcl_SetResult(interp, "FLOAT", TCL_STATIC);
2196       break;
2197     case SQLITE_TEXT:
2198       Tcl_SetResult(interp, "TEXT", TCL_STATIC);
2199       break;
2200     case SQLITE_BLOB:
2201       Tcl_SetResult(interp, "BLOB", TCL_STATIC);
2202       break;
2203     default:
2204       assert(0);
2205   }
2206 
2207   return TCL_OK;
2208 }
2209 
2210 /*
2211 ** Usage: sqlite3_column_int64 STMT column
2212 **
2213 ** Return the data in column 'column' of the current row cast as an
2214 ** wide (64-bit) integer.
2215 */
2216 static int test_column_int64(
2217   void * clientData,
2218   Tcl_Interp *interp,
2219   int objc,
2220   Tcl_Obj *CONST objv[]
2221 ){
2222   sqlite3_stmt *pStmt;
2223   int col;
2224   i64 iVal;
2225 
2226   if( objc!=3 ){
2227     Tcl_AppendResult(interp, "wrong # args: should be \"",
2228        Tcl_GetString(objv[0]), " STMT column", 0);
2229     return TCL_ERROR;
2230   }
2231 
2232   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2233   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
2234 
2235   iVal = sqlite3_column_int64(pStmt, col);
2236   Tcl_SetObjResult(interp, Tcl_NewWideIntObj(iVal));
2237   return TCL_OK;
2238 }
2239 
2240 /*
2241 ** Usage: sqlite3_column_blob STMT column
2242 */
2243 static int test_column_blob(
2244   void * clientData,
2245   Tcl_Interp *interp,
2246   int objc,
2247   Tcl_Obj *CONST objv[]
2248 ){
2249   sqlite3_stmt *pStmt;
2250   int col;
2251 
2252   int len;
2253   const void *pBlob;
2254 
2255   if( objc!=3 ){
2256     Tcl_AppendResult(interp, "wrong # args: should be \"",
2257        Tcl_GetString(objv[0]), " STMT column", 0);
2258     return TCL_ERROR;
2259   }
2260 
2261   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2262   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
2263 
2264   pBlob = sqlite3_column_blob(pStmt, col);
2265   len = sqlite3_column_bytes(pStmt, col);
2266   Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBlob, len));
2267   return TCL_OK;
2268 }
2269 
2270 /*
2271 ** Usage: sqlite3_column_double STMT column
2272 **
2273 ** Return the data in column 'column' of the current row cast as a double.
2274 */
2275 static int test_column_double(
2276   void * clientData,
2277   Tcl_Interp *interp,
2278   int objc,
2279   Tcl_Obj *CONST objv[]
2280 ){
2281   sqlite3_stmt *pStmt;
2282   int col;
2283   double rVal;
2284 
2285   if( objc!=3 ){
2286     Tcl_AppendResult(interp, "wrong # args: should be \"",
2287        Tcl_GetString(objv[0]), " STMT column", 0);
2288     return TCL_ERROR;
2289   }
2290 
2291   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2292   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
2293 
2294   rVal = sqlite3_column_double(pStmt, col);
2295   Tcl_SetObjResult(interp, Tcl_NewDoubleObj(rVal));
2296   return TCL_OK;
2297 }
2298 
2299 /*
2300 ** Usage: sqlite3_data_count STMT
2301 **
2302 ** Return the number of columns returned by the sql statement STMT.
2303 */
2304 static int test_data_count(
2305   void * clientData,
2306   Tcl_Interp *interp,
2307   int objc,
2308   Tcl_Obj *CONST objv[]
2309 ){
2310   sqlite3_stmt *pStmt;
2311 
2312   if( objc!=2 ){
2313     Tcl_AppendResult(interp, "wrong # args: should be \"",
2314        Tcl_GetString(objv[0]), " STMT column", 0);
2315     return TCL_ERROR;
2316   }
2317 
2318   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2319 
2320   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_data_count(pStmt)));
2321   return TCL_OK;
2322 }
2323 
2324 /*
2325 ** Usage: sqlite3_column_text STMT column
2326 **
2327 ** Usage: sqlite3_column_decltype STMT column
2328 **
2329 ** Usage: sqlite3_column_name STMT column
2330 */
2331 static int test_stmt_utf8(
2332   void * clientData,        /* Pointer to SQLite API function to be invoke */
2333   Tcl_Interp *interp,
2334   int objc,
2335   Tcl_Obj *CONST objv[]
2336 ){
2337   sqlite3_stmt *pStmt;
2338   int col;
2339   const char *(*xFunc)(sqlite3_stmt*, int) = clientData;
2340   const char *zRet;
2341 
2342   if( objc!=3 ){
2343     Tcl_AppendResult(interp, "wrong # args: should be \"",
2344        Tcl_GetString(objv[0]), " STMT column", 0);
2345     return TCL_ERROR;
2346   }
2347 
2348   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2349   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
2350   zRet = xFunc(pStmt, col);
2351   if( zRet ){
2352     Tcl_SetResult(interp, (char *)zRet, 0);
2353   }
2354   return TCL_OK;
2355 }
2356 
2357 static int test_global_recover(
2358   void * clientData,
2359   Tcl_Interp *interp,
2360   int objc,
2361   Tcl_Obj *CONST objv[]
2362 ){
2363 #ifndef SQLITE_OMIT_GLOBALRECOVER
2364   int rc;
2365   if( objc!=1 ){
2366     Tcl_WrongNumArgs(interp, 1, objv, "");
2367     return TCL_ERROR;
2368   }
2369   rc = sqlite3_global_recover();
2370   Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
2371 #endif
2372   return TCL_OK;
2373 }
2374 
2375 /*
2376 ** Usage: sqlite3_column_text STMT column
2377 **
2378 ** Usage: sqlite3_column_decltype STMT column
2379 **
2380 ** Usage: sqlite3_column_name STMT column
2381 */
2382 static int test_stmt_utf16(
2383   void * clientData,     /* Pointer to SQLite API function to be invoked */
2384   Tcl_Interp *interp,
2385   int objc,
2386   Tcl_Obj *CONST objv[]
2387 ){
2388 #ifndef SQLITE_OMIT_UTF16
2389   sqlite3_stmt *pStmt;
2390   int col;
2391   Tcl_Obj *pRet;
2392   const void *zName16;
2393   const void *(*xFunc)(sqlite3_stmt*, int) = clientData;
2394 
2395   if( objc!=3 ){
2396     Tcl_AppendResult(interp, "wrong # args: should be \"",
2397        Tcl_GetString(objv[0]), " STMT column", 0);
2398     return TCL_ERROR;
2399   }
2400 
2401   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2402   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
2403 
2404   zName16 = xFunc(pStmt, col);
2405   if( zName16 ){
2406     pRet = Tcl_NewByteArrayObj(zName16, sqlite3utf16ByteLen(zName16, -1)+2);
2407     Tcl_SetObjResult(interp, pRet);
2408   }
2409 #endif /* SQLITE_OMIT_UTF16 */
2410 
2411   return TCL_OK;
2412 }
2413 
2414 /*
2415 ** Usage: sqlite3_column_int STMT column
2416 **
2417 ** Usage: sqlite3_column_bytes STMT column
2418 **
2419 ** Usage: sqlite3_column_bytes16 STMT column
2420 **
2421 */
2422 static int test_stmt_int(
2423   void * clientData,    /* Pointer to SQLite API function to be invoked */
2424   Tcl_Interp *interp,
2425   int objc,
2426   Tcl_Obj *CONST objv[]
2427 ){
2428   sqlite3_stmt *pStmt;
2429   int col;
2430   int (*xFunc)(sqlite3_stmt*, int) = clientData;
2431 
2432   if( objc!=3 ){
2433     Tcl_AppendResult(interp, "wrong # args: should be \"",
2434        Tcl_GetString(objv[0]), " STMT column", 0);
2435     return TCL_ERROR;
2436   }
2437 
2438   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2439   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
2440 
2441   Tcl_SetObjResult(interp, Tcl_NewIntObj(xFunc(pStmt, col)));
2442   return TCL_OK;
2443 }
2444 
2445 #ifndef SQLITE_OMIT_DISKIO
2446 /*
2447 ** Usage:  sqlite3OsOpenReadWrite <filename>
2448 */
2449 static int test_sqlite3OsOpenReadWrite(
2450   void * clientData,
2451   Tcl_Interp *interp,
2452   int objc,
2453   Tcl_Obj *CONST objv[]
2454 ){
2455   OsFile * pFile;
2456   int rc;
2457   int dummy;
2458   char zBuf[100];
2459 
2460   if( objc!=2 ){
2461     Tcl_AppendResult(interp, "wrong # args: should be \"",
2462        Tcl_GetString(objv[0]), " filename", 0);
2463     return TCL_ERROR;
2464   }
2465 
2466   pFile = sqliteMalloc(sizeof(OsFile));
2467   rc = sqlite3OsOpenReadWrite(Tcl_GetString(objv[1]), pFile, &dummy);
2468   if( rc!=SQLITE_OK ){
2469     sqliteFree(pFile);
2470     Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
2471     return TCL_ERROR;
2472   }
2473   makePointerStr(interp, zBuf, pFile);
2474   Tcl_SetResult(interp, zBuf, 0);
2475   return TCL_ERROR;
2476 }
2477 
2478 /*
2479 ** Usage:  sqlite3OsClose <file handle>
2480 */
2481 static int test_sqlite3OsClose(
2482   void * clientData,
2483   Tcl_Interp *interp,
2484   int objc,
2485   Tcl_Obj *CONST objv[]
2486 ){
2487   OsFile * pFile;
2488   int rc;
2489 
2490   if( objc!=2 ){
2491     Tcl_AppendResult(interp, "wrong # args: should be \"",
2492        Tcl_GetString(objv[0]), " filehandle", 0);
2493     return TCL_ERROR;
2494   }
2495 
2496   if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){
2497     return TCL_ERROR;
2498   }
2499   rc = sqlite3OsClose(pFile);
2500   if( rc!=SQLITE_OK ){
2501     Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
2502     return TCL_ERROR;
2503   }
2504   sqliteFree(pFile);
2505   return TCL_OK;
2506 }
2507 
2508 /*
2509 ** Usage:  sqlite3OsLock <file handle> <locktype>
2510 */
2511 static int test_sqlite3OsLock(
2512   void * clientData,
2513   Tcl_Interp *interp,
2514   int objc,
2515   Tcl_Obj *CONST objv[]
2516 ){
2517   OsFile * pFile;
2518   int rc;
2519 
2520   if( objc!=3 ){
2521     Tcl_AppendResult(interp, "wrong # args: should be \"",
2522         Tcl_GetString(objv[0]),
2523         " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0);
2524     return TCL_ERROR;
2525   }
2526 
2527   if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){
2528     return TCL_ERROR;
2529   }
2530 
2531   if( 0==strcmp("SHARED", Tcl_GetString(objv[2])) ){
2532     rc = sqlite3OsLock(pFile, SHARED_LOCK);
2533   }
2534   else if( 0==strcmp("RESERVED", Tcl_GetString(objv[2])) ){
2535     rc = sqlite3OsLock(pFile, RESERVED_LOCK);
2536   }
2537   else if( 0==strcmp("PENDING", Tcl_GetString(objv[2])) ){
2538     rc = sqlite3OsLock(pFile, PENDING_LOCK);
2539   }
2540   else if( 0==strcmp("EXCLUSIVE", Tcl_GetString(objv[2])) ){
2541     rc = sqlite3OsLock(pFile, EXCLUSIVE_LOCK);
2542   }else{
2543     Tcl_AppendResult(interp, "wrong # args: should be \"",
2544         Tcl_GetString(objv[0]),
2545         " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0);
2546     return TCL_ERROR;
2547   }
2548 
2549   if( rc!=SQLITE_OK ){
2550     Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
2551     return TCL_ERROR;
2552   }
2553   return TCL_OK;
2554 }
2555 
2556 /*
2557 ** Usage:  sqlite3OsUnlock <file handle>
2558 */
2559 static int test_sqlite3OsUnlock(
2560   void * clientData,
2561   Tcl_Interp *interp,
2562   int objc,
2563   Tcl_Obj *CONST objv[]
2564 ){
2565   OsFile * pFile;
2566   int rc;
2567 
2568   if( objc!=2 ){
2569     Tcl_AppendResult(interp, "wrong # args: should be \"",
2570        Tcl_GetString(objv[0]), " filehandle", 0);
2571     return TCL_ERROR;
2572   }
2573 
2574   if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){
2575     return TCL_ERROR;
2576   }
2577   rc = sqlite3OsUnlock(pFile, NO_LOCK);
2578   if( rc!=SQLITE_OK ){
2579     Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
2580     return TCL_ERROR;
2581   }
2582   return TCL_OK;
2583 }
2584 
2585 /*
2586 ** Usage:  sqlite3OsTempFileName
2587 */
2588 static int test_sqlite3OsTempFileName(
2589   void * clientData,
2590   Tcl_Interp *interp,
2591   int objc,
2592   Tcl_Obj *CONST objv[]
2593 ){
2594   char zFile[SQLITE_TEMPNAME_SIZE];
2595   int rc;
2596 
2597   rc = sqlite3OsTempFileName(zFile);
2598   if( rc!=SQLITE_OK ){
2599     Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
2600     return TCL_ERROR;
2601   }
2602   Tcl_AppendResult(interp, zFile, 0);
2603   return TCL_OK;
2604 }
2605 #endif
2606 
2607 /*
2608 ** Usage:  sqlite_set_magic  DB  MAGIC-NUMBER
2609 **
2610 ** Set the db->magic value.  This is used to test error recovery logic.
2611 */
2612 static int sqlite_set_magic(
2613   void * clientData,
2614   Tcl_Interp *interp,
2615   int argc,
2616   char **argv
2617 ){
2618   sqlite3 *db;
2619   if( argc!=3 ){
2620     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
2621          " DB MAGIC", 0);
2622     return TCL_ERROR;
2623   }
2624   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
2625   if( strcmp(argv[2], "SQLITE_MAGIC_OPEN")==0 ){
2626     db->magic = SQLITE_MAGIC_OPEN;
2627   }else if( strcmp(argv[2], "SQLITE_MAGIC_CLOSED")==0 ){
2628     db->magic = SQLITE_MAGIC_CLOSED;
2629   }else if( strcmp(argv[2], "SQLITE_MAGIC_BUSY")==0 ){
2630     db->magic = SQLITE_MAGIC_BUSY;
2631   }else if( strcmp(argv[2], "SQLITE_MAGIC_ERROR")==0 ){
2632     db->magic = SQLITE_MAGIC_ERROR;
2633   }else if( Tcl_GetInt(interp, argv[2], &db->magic) ){
2634     return TCL_ERROR;
2635   }
2636   return TCL_OK;
2637 }
2638 
2639 /*
2640 ** Usage:  sqlite3_interrupt  DB
2641 **
2642 ** Trigger an interrupt on DB
2643 */
2644 static int test_interrupt(
2645   void * clientData,
2646   Tcl_Interp *interp,
2647   int argc,
2648   char **argv
2649 ){
2650   sqlite3 *db;
2651   if( argc!=2 ){
2652     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB", 0);
2653     return TCL_ERROR;
2654   }
2655   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
2656   sqlite3_interrupt(db);
2657   return TCL_OK;
2658 }
2659 
2660 static u8 *sqlite3_stack_baseline = 0;
2661 
2662 /*
2663 ** Fill the stack with a known bitpattern.
2664 */
2665 static void prepStack(void){
2666   int i;
2667   u32 bigBuf[65536];
2668   for(i=0; i<sizeof(bigBuf); i++) bigBuf[i] = 0xdeadbeef;
2669   sqlite3_stack_baseline = (u8*)&bigBuf[65536];
2670 }
2671 
2672 /*
2673 ** Get the current stack depth.  Used for debugging only.
2674 */
2675 u64 sqlite3StackDepth(void){
2676   u8 x;
2677   return (u64)(sqlite3_stack_baseline - &x);
2678 }
2679 
2680 /*
2681 ** Usage:  sqlite3_stack_used DB SQL
2682 **
2683 ** Try to measure the amount of stack space used by a call to sqlite3_exec
2684 */
2685 static int test_stack_used(
2686   void * clientData,
2687   Tcl_Interp *interp,
2688   int argc,
2689   char **argv
2690 ){
2691   sqlite3 *db;
2692   int i;
2693   if( argc!=3 ){
2694     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
2695         " DB SQL", 0);
2696     return TCL_ERROR;
2697   }
2698   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
2699   prepStack();
2700   sqlite3_exec(db, argv[2], 0, 0, 0);
2701   for(i=65535; i>=0 && ((u32*)sqlite3_stack_baseline)[-i]==0xdeadbeef; i--){}
2702   Tcl_SetObjResult(interp, Tcl_NewIntObj(i*4));
2703   return TCL_OK;
2704 }
2705 
2706 /*
2707 ** Usage: sqlite_delete_function DB function-name
2708 **
2709 ** Delete the user function 'function-name' from database handle DB. It
2710 ** is assumed that the user function was created as UTF8, any number of
2711 ** arguments (the way the TCL interface does it).
2712 */
2713 static int delete_function(
2714   void * clientData,
2715   Tcl_Interp *interp,
2716   int argc,
2717   char **argv
2718 ){
2719   int rc;
2720   sqlite3 *db;
2721   if( argc!=3 ){
2722     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
2723         " DB function-name", 0);
2724     return TCL_ERROR;
2725   }
2726   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
2727   rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 0, 0, 0);
2728   Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
2729   return TCL_OK;
2730 }
2731 
2732 /*
2733 ** Usage: sqlite_delete_collation DB collation-name
2734 **
2735 ** Delete the collation sequence 'collation-name' from database handle
2736 ** DB. It is assumed that the collation sequence was created as UTF8 (the
2737 ** way the TCL interface does it).
2738 */
2739 static int delete_collation(
2740   void * clientData,
2741   Tcl_Interp *interp,
2742   int argc,
2743   char **argv
2744 ){
2745   int rc;
2746   sqlite3 *db;
2747   if( argc!=3 ){
2748     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
2749         " DB function-name", 0);
2750     return TCL_ERROR;
2751   }
2752   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
2753   rc = sqlite3_create_collation(db, argv[2], SQLITE_UTF8, 0, 0);
2754   Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
2755   return TCL_OK;
2756 }
2757 
2758 /*
2759 ** Usage: sqlite3_get_autocommit DB
2760 **
2761 ** Return true if the database DB is currently in auto-commit mode.
2762 ** Return false if not.
2763 */
2764 static int get_autocommit(
2765   void * clientData,
2766   Tcl_Interp *interp,
2767   int argc,
2768   char **argv
2769 ){
2770   char zBuf[30];
2771   sqlite3 *db;
2772   if( argc!=2 ){
2773     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
2774         " DB", 0);
2775     return TCL_ERROR;
2776   }
2777   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
2778   sprintf(zBuf, "%d", sqlite3_get_autocommit(db));
2779   Tcl_AppendResult(interp, zBuf, 0);
2780   return TCL_OK;
2781 }
2782 
2783 /*
2784 ** Usage:  tcl_variable_type VARIABLENAME
2785 **
2786 ** Return the name of the internal representation for the
2787 ** value of the given variable.
2788 */
2789 static int tcl_variable_type(
2790   void * clientData,
2791   Tcl_Interp *interp,
2792   int objc,
2793   Tcl_Obj *CONST objv[]
2794 ){
2795   Tcl_Obj *pVar;
2796   if( objc!=2 ){
2797     Tcl_WrongNumArgs(interp, 1, objv, "VARIABLE");
2798     return TCL_ERROR;
2799   }
2800   pVar = Tcl_GetVar2Ex(interp, Tcl_GetString(objv[1]), 0, TCL_LEAVE_ERR_MSG);
2801   if( pVar==0 ) return TCL_ERROR;
2802   if( pVar->typePtr ){
2803     Tcl_SetObjResult(interp, Tcl_NewStringObj(pVar->typePtr->name, -1));
2804   }
2805   return TCL_OK;
2806 }
2807 
2808 /*
2809 ** This routine sets entries in the global ::sqlite_options() array variable
2810 ** according to the compile-time configuration of the database.  Test
2811 ** procedures use this to determine when tests should be omitted.
2812 */
2813 static void set_options(Tcl_Interp *interp){
2814 #ifdef SQLITE_32BIT_ROWID
2815   Tcl_SetVar2(interp, "sqlite_options", "rowid32", "1", TCL_GLOBAL_ONLY);
2816 #else
2817   Tcl_SetVar2(interp, "sqlite_options", "rowid32", "0", TCL_GLOBAL_ONLY);
2818 #endif
2819 
2820 #ifdef SQLITE_CASE_SENSITIVE_LIKE
2821   Tcl_SetVar2(interp, "sqlite_options","casesensitivelike","1",TCL_GLOBAL_ONLY);
2822 #else
2823   Tcl_SetVar2(interp, "sqlite_options","casesensitivelike","0",TCL_GLOBAL_ONLY);
2824 #endif
2825 
2826 #ifdef SQLITE_OMIT_ALTERTABLE
2827   Tcl_SetVar2(interp, "sqlite_options", "altertable", "0", TCL_GLOBAL_ONLY);
2828 #else
2829   Tcl_SetVar2(interp, "sqlite_options", "altertable", "1", TCL_GLOBAL_ONLY);
2830 #endif
2831 
2832 #ifdef SQLITE_OMIT_ANALYZE
2833   Tcl_SetVar2(interp, "sqlite_options", "analyze", "0", TCL_GLOBAL_ONLY);
2834 #else
2835   Tcl_SetVar2(interp, "sqlite_options", "analyze", "1", TCL_GLOBAL_ONLY);
2836 #endif
2837 
2838 #ifdef SQLITE_OMIT_AUTHORIZATION
2839   Tcl_SetVar2(interp, "sqlite_options", "auth", "0", TCL_GLOBAL_ONLY);
2840 #else
2841   Tcl_SetVar2(interp, "sqlite_options", "auth", "1", TCL_GLOBAL_ONLY);
2842 #endif
2843 
2844 #ifdef SQLITE_OMIT_AUTOINCREMENT
2845   Tcl_SetVar2(interp, "sqlite_options", "autoinc", "0", TCL_GLOBAL_ONLY);
2846 #else
2847   Tcl_SetVar2(interp, "sqlite_options", "autoinc", "1", TCL_GLOBAL_ONLY);
2848 #endif
2849 
2850 #ifdef SQLITE_OMIT_AUTOVACUUM
2851   Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "0", TCL_GLOBAL_ONLY);
2852 #else
2853   Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "1", TCL_GLOBAL_ONLY);
2854 #endif /* SQLITE_OMIT_AUTOVACUUM */
2855 #if !defined(SQLITE_DEFAULT_AUTOVACUUM) || SQLITE_DEFAULT_AUTOVACUUM==0
2856   Tcl_SetVar2(interp,"sqlite_options","default_autovacuum","0",TCL_GLOBAL_ONLY);
2857 #else
2858   Tcl_SetVar2(interp,"sqlite_options","default_autovacuum","1",TCL_GLOBAL_ONLY);
2859 #endif
2860 
2861 #ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION
2862   Tcl_SetVar2(interp, "sqlite_options", "between_opt", "0", TCL_GLOBAL_ONLY);
2863 #else
2864   Tcl_SetVar2(interp, "sqlite_options", "between_opt", "1", TCL_GLOBAL_ONLY);
2865 #endif
2866 
2867 #ifdef SQLITE_OMIT_BLOB_LITERAL
2868   Tcl_SetVar2(interp, "sqlite_options", "bloblit", "0", TCL_GLOBAL_ONLY);
2869 #else
2870   Tcl_SetVar2(interp, "sqlite_options", "bloblit", "1", TCL_GLOBAL_ONLY);
2871 #endif
2872 
2873 #ifdef SQLITE_OMIT_CAST
2874   Tcl_SetVar2(interp, "sqlite_options", "cast", "0", TCL_GLOBAL_ONLY);
2875 #else
2876   Tcl_SetVar2(interp, "sqlite_options", "cast", "1", TCL_GLOBAL_ONLY);
2877 #endif
2878 
2879 #ifdef SQLITE_OMIT_COMPLETE
2880   Tcl_SetVar2(interp, "sqlite_options", "complete", "0", TCL_GLOBAL_ONLY);
2881 #else
2882   Tcl_SetVar2(interp, "sqlite_options", "complete", "1", TCL_GLOBAL_ONLY);
2883 #endif
2884 
2885 #ifdef SQLITE_OMIT_COMPOUND_SELECT
2886   Tcl_SetVar2(interp, "sqlite_options", "compound", "0", TCL_GLOBAL_ONLY);
2887 #else
2888   Tcl_SetVar2(interp, "sqlite_options", "compound", "1", TCL_GLOBAL_ONLY);
2889 #endif
2890 
2891 #ifdef SQLITE_OMIT_CONFLICT_CLAUSE
2892   Tcl_SetVar2(interp, "sqlite_options", "conflict", "0", TCL_GLOBAL_ONLY);
2893 #else
2894   Tcl_SetVar2(interp, "sqlite_options", "conflict", "1", TCL_GLOBAL_ONLY);
2895 #endif
2896 
2897 #ifdef SQLITE_OMIT_DATETIME_FUNCS
2898   Tcl_SetVar2(interp, "sqlite_options", "datetime", "0", TCL_GLOBAL_ONLY);
2899 #else
2900   Tcl_SetVar2(interp, "sqlite_options", "datetime", "1", TCL_GLOBAL_ONLY);
2901 #endif
2902 
2903 #ifdef SQLITE_OMIT_DISKIO
2904   Tcl_SetVar2(interp, "sqlite_options", "diskio", "0", TCL_GLOBAL_ONLY);
2905 #else
2906   Tcl_SetVar2(interp, "sqlite_options", "diskio", "1", TCL_GLOBAL_ONLY);
2907 #endif
2908 
2909 #ifdef SQLITE_OMIT_EXPLAIN
2910   Tcl_SetVar2(interp, "sqlite_options", "explain", "0", TCL_GLOBAL_ONLY);
2911 #else
2912   Tcl_SetVar2(interp, "sqlite_options", "explain", "1", TCL_GLOBAL_ONLY);
2913 #endif
2914 
2915 #ifdef SQLITE_OMIT_FLOATING_POINT
2916   Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "0", TCL_GLOBAL_ONLY);
2917 #else
2918   Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "1", TCL_GLOBAL_ONLY);
2919 #endif
2920 
2921 #ifdef SQLITE_OMIT_FOREIGN_KEY
2922   Tcl_SetVar2(interp, "sqlite_options", "foreignkey", "0", TCL_GLOBAL_ONLY);
2923 #else
2924   Tcl_SetVar2(interp, "sqlite_options", "foreignkey", "1", TCL_GLOBAL_ONLY);
2925 #endif
2926 
2927 #ifdef SQLITE_OMIT_GLOBALRECOVER
2928   Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "0", TCL_GLOBAL_ONLY);
2929 #else
2930   Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "1", TCL_GLOBAL_ONLY);
2931 #endif
2932 
2933 #ifdef SQLITE_OMIT_INTEGRITY_CHECK
2934   Tcl_SetVar2(interp, "sqlite_options", "integrityck", "0", TCL_GLOBAL_ONLY);
2935 #else
2936   Tcl_SetVar2(interp, "sqlite_options", "integrityck", "1", TCL_GLOBAL_ONLY);
2937 #endif
2938 
2939 #ifdef SQLITE_OMIT_LIKE_OPTIMIZATION
2940   Tcl_SetVar2(interp, "sqlite_options", "like_opt", "0", TCL_GLOBAL_ONLY);
2941 #else
2942   Tcl_SetVar2(interp, "sqlite_options", "like_opt", "1", TCL_GLOBAL_ONLY);
2943 #endif
2944 
2945 #ifdef SQLITE_OMIT_MEMORYDB
2946   Tcl_SetVar2(interp, "sqlite_options", "memorydb", "0", TCL_GLOBAL_ONLY);
2947 #else
2948   Tcl_SetVar2(interp, "sqlite_options", "memorydb", "1", TCL_GLOBAL_ONLY);
2949 #endif
2950 
2951 #ifdef SQLITE_OMIT_OR_OPTIMIZATION
2952   Tcl_SetVar2(interp, "sqlite_options", "or_opt", "0", TCL_GLOBAL_ONLY);
2953 #else
2954   Tcl_SetVar2(interp, "sqlite_options", "or_opt", "1", TCL_GLOBAL_ONLY);
2955 #endif
2956 
2957 #ifdef SQLITE_OMIT_PAGER_PRAGMAS
2958   Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "0", TCL_GLOBAL_ONLY);
2959 #else
2960   Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "1", TCL_GLOBAL_ONLY);
2961 #endif
2962 
2963 #ifdef SQLITE_OMIT_PARSER
2964   Tcl_SetVar2(interp, "sqlite_options", "parser", "0", TCL_GLOBAL_ONLY);
2965 #else
2966   Tcl_SetVar2(interp, "sqlite_options", "parser", "1", TCL_GLOBAL_ONLY);
2967 #endif
2968 
2969 #if defined(SQLITE_OMIT_PRAGMA) || defined(SQLITE_OMIT_FLAG_PRAGMAS)
2970   Tcl_SetVar2(interp, "sqlite_options", "pragma", "0", TCL_GLOBAL_ONLY);
2971   Tcl_SetVar2(interp, "sqlite_options", "integrityck", "0", TCL_GLOBAL_ONLY);
2972 #else
2973   Tcl_SetVar2(interp, "sqlite_options", "pragma", "1", TCL_GLOBAL_ONLY);
2974 #endif
2975 
2976 #ifdef SQLITE_OMIT_PROGRESS_CALLBACK
2977   Tcl_SetVar2(interp, "sqlite_options", "progress", "0", TCL_GLOBAL_ONLY);
2978 #else
2979   Tcl_SetVar2(interp, "sqlite_options", "progress", "1", TCL_GLOBAL_ONLY);
2980 #endif
2981 
2982 #ifdef SQLITE_OMIT_REINDEX
2983   Tcl_SetVar2(interp, "sqlite_options", "reindex", "0", TCL_GLOBAL_ONLY);
2984 #else
2985   Tcl_SetVar2(interp, "sqlite_options", "reindex", "1", TCL_GLOBAL_ONLY);
2986 #endif
2987 
2988 #ifdef SQLITE_OMIT_SCHEMA_PRAGMAS
2989   Tcl_SetVar2(interp, "sqlite_options", "schema_pragmas", "0", TCL_GLOBAL_ONLY);
2990 #else
2991   Tcl_SetVar2(interp, "sqlite_options", "schema_pragmas", "1", TCL_GLOBAL_ONLY);
2992 #endif
2993 
2994 #ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
2995   Tcl_SetVar2(interp, "sqlite_options", "schema_version", "0", TCL_GLOBAL_ONLY);
2996 #else
2997   Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY);
2998 #endif
2999 
3000 #ifdef SQLITE_OMIT_SUBQUERY
3001   Tcl_SetVar2(interp, "sqlite_options", "subquery", "0", TCL_GLOBAL_ONLY);
3002 #else
3003   Tcl_SetVar2(interp, "sqlite_options", "subquery", "1", TCL_GLOBAL_ONLY);
3004 #endif
3005 
3006 #ifdef SQLITE_OMIT_TCL_VARIABLE
3007   Tcl_SetVar2(interp, "sqlite_options", "tclvar", "0", TCL_GLOBAL_ONLY);
3008 #else
3009   Tcl_SetVar2(interp, "sqlite_options", "tclvar", "1", TCL_GLOBAL_ONLY);
3010 #endif
3011 
3012 #if defined(THREADSAFE) && THREADSAFE
3013   Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "1", TCL_GLOBAL_ONLY);
3014 #else
3015   Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "0", TCL_GLOBAL_ONLY);
3016 #endif
3017 
3018 #ifdef SQLITE_OMIT_TRACE
3019   Tcl_SetVar2(interp, "sqlite_options", "trace", "0", TCL_GLOBAL_ONLY);
3020 #else
3021   Tcl_SetVar2(interp, "sqlite_options", "trace", "1", TCL_GLOBAL_ONLY);
3022 #endif
3023 
3024 #ifdef SQLITE_OMIT_TRIGGER
3025   Tcl_SetVar2(interp, "sqlite_options", "trigger", "0", TCL_GLOBAL_ONLY);
3026 #else
3027   Tcl_SetVar2(interp, "sqlite_options", "trigger", "1", TCL_GLOBAL_ONLY);
3028 #endif
3029 
3030 #ifdef SQLITE_OMIT_TEMPDB
3031   Tcl_SetVar2(interp, "sqlite_options", "tempdb", "0", TCL_GLOBAL_ONLY);
3032 #else
3033   Tcl_SetVar2(interp, "sqlite_options", "tempdb", "1", TCL_GLOBAL_ONLY);
3034 #endif
3035 
3036 #ifdef SQLITE_OMIT_UTF16
3037   Tcl_SetVar2(interp, "sqlite_options", "utf16", "0", TCL_GLOBAL_ONLY);
3038 #else
3039   Tcl_SetVar2(interp, "sqlite_options", "utf16", "1", TCL_GLOBAL_ONLY);
3040 #endif
3041 
3042 #ifdef SQLITE_OMIT_VACUUM
3043   Tcl_SetVar2(interp, "sqlite_options", "vacuum", "0", TCL_GLOBAL_ONLY);
3044 #else
3045   Tcl_SetVar2(interp, "sqlite_options", "vacuum", "1", TCL_GLOBAL_ONLY);
3046 #endif
3047 
3048 #ifdef SQLITE_OMIT_VIEW
3049   Tcl_SetVar2(interp, "sqlite_options", "view", "0", TCL_GLOBAL_ONLY);
3050 #else
3051   Tcl_SetVar2(interp, "sqlite_options", "view", "1", TCL_GLOBAL_ONLY);
3052 #endif
3053 }
3054 
3055 /*
3056 ** Register commands with the TCL interpreter.
3057 */
3058 int Sqlitetest1_Init(Tcl_Interp *interp){
3059   extern int sqlite3_search_count;
3060   extern int sqlite3_interrupt_count;
3061   extern int sqlite3_open_file_count;
3062   extern int sqlite3_sort_count;
3063   extern int sqlite3_current_time;
3064   static struct {
3065      char *zName;
3066      Tcl_CmdProc *xProc;
3067   } aCmd[] = {
3068      { "sqlite3_mprintf_int",           (Tcl_CmdProc*)sqlite3_mprintf_int    },
3069      { "sqlite3_mprintf_int64",         (Tcl_CmdProc*)sqlite3_mprintf_int64  },
3070      { "sqlite3_mprintf_str",           (Tcl_CmdProc*)sqlite3_mprintf_str    },
3071      { "sqlite3_mprintf_stronly",       (Tcl_CmdProc*)sqlite3_mprintf_stronly},
3072      { "sqlite3_mprintf_double",        (Tcl_CmdProc*)sqlite3_mprintf_double },
3073      { "sqlite3_mprintf_scaled",        (Tcl_CmdProc*)sqlite3_mprintf_scaled },
3074      { "sqlite3_mprintf_hexdouble",   (Tcl_CmdProc*)sqlite3_mprintf_hexdouble},
3075      { "sqlite3_mprintf_z_test",        (Tcl_CmdProc*)test_mprintf_z        },
3076      { "sqlite3_last_insert_rowid",     (Tcl_CmdProc*)test_last_rowid       },
3077      { "sqlite3_exec_printf",           (Tcl_CmdProc*)test_exec_printf      },
3078      { "sqlite3_get_table_printf",      (Tcl_CmdProc*)test_get_table_printf },
3079      { "sqlite3_close",                 (Tcl_CmdProc*)sqlite_test_close     },
3080      { "sqlite3_create_function",       (Tcl_CmdProc*)test_create_function  },
3081      { "sqlite3_create_aggregate",      (Tcl_CmdProc*)test_create_aggregate },
3082      { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func    },
3083      { "sqlite_abort",                  (Tcl_CmdProc*)sqlite_abort          },
3084 #ifdef SQLITE_MEMDEBUG
3085      { "sqlite_malloc_fail",            (Tcl_CmdProc*)sqlite_malloc_fail    },
3086      { "sqlite_malloc_stat",            (Tcl_CmdProc*)sqlite_malloc_stat    },
3087 #endif
3088      { "sqlite_bind",                   (Tcl_CmdProc*)test_bind             },
3089      { "breakpoint",                    (Tcl_CmdProc*)test_breakpoint       },
3090      { "sqlite3_key",                   (Tcl_CmdProc*)test_key              },
3091      { "sqlite3_rekey",                 (Tcl_CmdProc*)test_rekey            },
3092      { "sqlite_set_magic",              (Tcl_CmdProc*)sqlite_set_magic      },
3093      { "sqlite3_interrupt",             (Tcl_CmdProc*)test_interrupt        },
3094 #if 0
3095      { "sqlite3_sleep",                 (Tcl_CmdProc*)test_sleep            },
3096 #endif
3097      { "sqlite_delete_function",        (Tcl_CmdProc*)delete_function       },
3098      { "sqlite_delete_collation",       (Tcl_CmdProc*)delete_collation      },
3099      { "sqlite3_get_autocommit",        (Tcl_CmdProc*)get_autocommit        },
3100      { "sqlite3_stack_used",            (Tcl_CmdProc*)test_stack_used       },
3101   };
3102   static struct {
3103      char *zName;
3104      Tcl_ObjCmdProc *xProc;
3105      void *clientData;
3106   } aObjCmd[] = {
3107      { "sqlite3_bind_int",              test_bind_int,      0 },
3108      { "sqlite3_bind_int64",            test_bind_int64,    0 },
3109      { "sqlite3_bind_double",           test_bind_double,   0 },
3110      { "sqlite3_bind_null",             test_bind_null     ,0 },
3111      { "sqlite3_bind_text",             test_bind_text     ,0 },
3112      { "sqlite3_bind_text16",           test_bind_text16   ,0 },
3113      { "sqlite3_bind_blob",             test_bind_blob     ,0 },
3114      { "sqlite3_bind_parameter_count",  test_bind_parameter_count, 0},
3115      { "sqlite3_bind_parameter_name",   test_bind_parameter_name,  0},
3116      { "sqlite3_bind_parameter_index",  test_bind_parameter_index, 0},
3117 #if 0
3118      { "sqlite3_clear_bindings",        test_clear_bindings, 0},
3119 #endif
3120      { "sqlite3_errcode",               test_errcode       ,0 },
3121      { "sqlite3_errmsg",                test_errmsg        ,0 },
3122      { "sqlite3_errmsg16",              test_errmsg16      ,0 },
3123      { "sqlite3_open",                  test_open          ,0 },
3124      { "sqlite3_open16",                test_open16        ,0 },
3125      { "sqlite3_complete16",            test_complete16    ,0 },
3126 
3127      { "sqlite3_prepare",               test_prepare       ,0 },
3128      { "sqlite3_prepare16",             test_prepare16     ,0 },
3129      { "sqlite3_finalize",              test_finalize      ,0 },
3130      { "sqlite3_reset",                 test_reset         ,0 },
3131      { "sqlite3_expired",               test_expired       ,0 },
3132      { "sqlite3_transfer_bindings",     test_transfer_bind ,0 },
3133      { "sqlite3_changes",               test_changes       ,0 },
3134      { "sqlite3_step",                  test_step          ,0 },
3135 
3136      /* sqlite3_column_*() API */
3137      { "sqlite3_column_count",          test_column_count  ,0 },
3138      { "sqlite3_data_count",            test_data_count    ,0 },
3139      { "sqlite3_column_type",           test_column_type   ,0 },
3140      { "sqlite3_column_blob",           test_column_blob   ,0 },
3141      { "sqlite3_column_double",         test_column_double ,0 },
3142      { "sqlite3_column_int64",          test_column_int64  ,0 },
3143      { "sqlite3_column_text",       test_stmt_utf8,  sqlite3_column_text      },
3144      { "sqlite3_column_decltype",   test_stmt_utf8,  sqlite3_column_decltype  },
3145      { "sqlite3_column_name",       test_stmt_utf8,  sqlite3_column_name      },
3146      { "sqlite3_column_int",        test_stmt_int,   sqlite3_column_int       },
3147      { "sqlite3_column_bytes",      test_stmt_int,   sqlite3_column_bytes     },
3148 #ifndef SQLITE_OMIT_UTF16
3149      { "sqlite3_column_bytes16",    test_stmt_int,   sqlite3_column_bytes16   },
3150      { "sqlite3_column_text16",     test_stmt_utf16, sqlite3_column_text16    },
3151      { "sqlite3_column_decltype16", test_stmt_utf16, sqlite3_column_decltype16},
3152      { "sqlite3_column_name16",     test_stmt_utf16, sqlite3_column_name16    },
3153 #endif
3154      { "sqlite3_global_recover",    test_global_recover, 0   },
3155 
3156      /* Functions from os.h */
3157 #ifndef SQLITE_OMIT_DISKIO
3158      { "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 },
3159      { "sqlite3OsClose",        test_sqlite3OsClose, 0 },
3160      { "sqlite3OsLock",         test_sqlite3OsLock, 0 },
3161      { "sqlite3OsTempFileName", test_sqlite3OsTempFileName, 0 },
3162 
3163      /* Custom test interfaces */
3164      { "sqlite3OsUnlock",         test_sqlite3OsUnlock, 0    },
3165 #endif
3166 #ifndef SQLITE_OMIT_UTF16
3167      { "add_test_collate",        test_collate, 0            },
3168      { "add_test_collate_needed", test_collate_needed, 0     },
3169      { "add_test_function",       test_function, 0           },
3170 #endif
3171      { "sqlite3_crashparams",     sqlite3_crashparams, 0     },
3172      { "sqlite3_test_errstr",     test_errstr, 0             },
3173      { "tcl_variable_type",       tcl_variable_type, 0       },
3174   };
3175   static int bitmask_size = sizeof(Bitmask)*8;
3176   int i;
3177   extern int sqlite3_os_trace;
3178   extern int sqlite3_where_trace;
3179   extern int sqlite3_sync_count, sqlite3_fullsync_count;
3180   extern int sqlite3_opentemp_count;
3181   extern int sqlite3_memUsed;
3182   extern int sqlite3_memMax;
3183   extern int sqlite3_like_count;
3184 #if OS_WIN
3185   extern int sqlite3_os_type;
3186 #endif
3187 #ifdef SQLITE_DEBUG
3188   extern int sqlite3_vdbe_addop_trace;
3189 #endif
3190 #ifdef SQLITE_TEST
3191   extern char sqlite3_query_plan[];
3192   static char *query_plan = sqlite3_query_plan;
3193 #endif
3194 
3195   for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
3196     Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
3197   }
3198   for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
3199     Tcl_CreateObjCommand(interp, aObjCmd[i].zName,
3200         aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
3201   }
3202   Tcl_LinkVar(interp, "sqlite_search_count",
3203       (char*)&sqlite3_search_count, TCL_LINK_INT);
3204   Tcl_LinkVar(interp, "sqlite_sort_count",
3205       (char*)&sqlite3_sort_count, TCL_LINK_INT);
3206   Tcl_LinkVar(interp, "sqlite_like_count",
3207       (char*)&sqlite3_like_count, TCL_LINK_INT);
3208   Tcl_LinkVar(interp, "sqlite_interrupt_count",
3209       (char*)&sqlite3_interrupt_count, TCL_LINK_INT);
3210   Tcl_LinkVar(interp, "sqlite_open_file_count",
3211       (char*)&sqlite3_open_file_count, TCL_LINK_INT);
3212   Tcl_LinkVar(interp, "sqlite_current_time",
3213       (char*)&sqlite3_current_time, TCL_LINK_INT);
3214   Tcl_LinkVar(interp, "sqlite_os_trace",
3215       (char*)&sqlite3_os_trace, TCL_LINK_INT);
3216 #if OS_WIN
3217   Tcl_LinkVar(interp, "sqlite_os_type",
3218       (char*)&sqlite3_os_type, TCL_LINK_INT);
3219 #endif
3220 #ifdef SQLITE_TEST
3221   Tcl_LinkVar(interp, "sqlite_query_plan",
3222       (char*)&query_plan, TCL_LINK_STRING|TCL_LINK_READ_ONLY);
3223 #endif
3224 #ifdef SQLITE_DEBUG
3225   Tcl_LinkVar(interp, "sqlite_addop_trace",
3226       (char*)&sqlite3_vdbe_addop_trace, TCL_LINK_INT);
3227   Tcl_LinkVar(interp, "sqlite_where_trace",
3228       (char*)&sqlite3_where_trace, TCL_LINK_INT);
3229 #endif
3230 #ifdef SQLITE_MEMDEBUG
3231   Tcl_LinkVar(interp, "sqlite_memused",
3232       (char*)&sqlite3_memUsed, TCL_LINK_INT | TCL_LINK_READ_ONLY);
3233   Tcl_LinkVar(interp, "sqlite_memmax",
3234       (char*)&sqlite3_memMax, TCL_LINK_INT | TCL_LINK_READ_ONLY);
3235 #endif
3236 #ifndef SQLITE_OMIT_DISKIO
3237   Tcl_LinkVar(interp, "sqlite_opentemp_count",
3238       (char*)&sqlite3_opentemp_count, TCL_LINK_INT);
3239 #endif
3240   Tcl_LinkVar(interp, "sqlite_static_bind_value",
3241       (char*)&sqlite_static_bind_value, TCL_LINK_STRING);
3242   Tcl_LinkVar(interp, "sqlite_temp_directory",
3243       (char*)&sqlite3_temp_directory, TCL_LINK_STRING);
3244   Tcl_LinkVar(interp, "bitmask_size",
3245       (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY);
3246 #if OS_UNIX
3247   Tcl_LinkVar(interp, "sqlite_sync_count",
3248       (char*)&sqlite3_sync_count, TCL_LINK_INT);
3249   Tcl_LinkVar(interp, "sqlite_fullsync_count",
3250       (char*)&sqlite3_fullsync_count, TCL_LINK_INT);
3251 #endif /* OS_UNIX */
3252   set_options(interp);
3253   return TCL_OK;
3254 }
3255